Skip to content

Instantly share code, notes, and snippets.

@weigert
Last active June 23, 2020 01:15
Show Gist options
  • Save weigert/9a62594a300edfcf27d5ff24b41cbd50 to your computer and use it in GitHub Desktop.
Save weigert/9a62594a300edfcf27d5ff24b41cbd50 to your computer and use it in GitHub Desktop.
MATLAB function for parsing COMSOL ".txt" data export files into an easily useable struct
%{
% COMSOL-MATLAB Parser
%
% Author: Nicholas McDonald
% Tested on COMSOL 5.3 for Linux
%
% This function will parse the COMSOL standard .txt output
% into a struct that is easily used in MATLAB for data vis.
%
% It returns a struct "obj" that handles times, parametric
% studies and geometry of a COMSOL data set.
%
% Return Struct:
% obj.meta - Output file metadata
% obj.key - Variable name, unit, time point, parameters
% obj.raw - Raw data table by position, key
% obj.raw.X - Position data (row)
% obj.raw.Y - (Optional)
% obj.raw.Z - (Optional)
% obj.raw.dat - Array of entries (column), corresponding to keys
%
% Example Usage:
%
% obj = comsolread("export.txt");
% t = [obj.key.t]; %Array of Time Data
% x = [obj.raw.X]; %Array of Position Data
%
% %Slice all positions, at time = end
% raw = vertcat(obj.raw.dat); %Raw 2D Data Array
% val = raw(:, end);
%
% %Slice all times, position is X = 0
% val = obj.raw(1).dat
%
% Warning: This can be slow for large data exports
%}
function obj = comsolread(filename)
NMF = 7; %NUM META FIELDS
fileID = fopen(filename, 'r'); %Open File
obj.meta = comsolmeta(fileID, NMF); %Get Metadata Struct (7 Fields)
obj.meta.Source = filename; %Add Source file Info
obj.key = comsolkey(fileID, obj.meta); %Extract Table Key
obj.raw = comsolraw(fileID, obj.meta); %Extract Raw Data
fclose(fileID);
end
function meta = comsolmeta(fid, metacount)
key = {}; value = {};
for i = 1:metacount
data = strsplit(fgetl(fid), ' ');
key{i} = erase(data{2}, ':');
value{i} = strcat(data{3});
for j = 4:length(data);
value{i} = value{i} + " ";
value{i} = value{i} + data{j};
end
end
meta = cell2struct(value, key, 2);
meta.Dimension = str2double(meta.Dimension);
meta.Nodes = str2double(meta.Nodes);
meta.Expressions = str2double(meta.Expressions);
end
function [key val] = comsolparam(line)
if contains(line, "=")
a = strfind(line, "=");
key = line(1:a-1);
val = sscanf(line(a+1:end), "%f");
end
end
function key = comsolkey(fid, meta)
g = strsplit(fgetl(fid), " ");
initial = true;
i = 2+meta.Dimension;
while i < length(g)
keys = {}; vals = {};
keys{end+1} = 'var'; %Variable Name
vals{end+1} = g{i+0};
keys{end+1} = 'unit'; %Unit Expression
vals{end+1} = g{i+1};
a = 3;
while i + a < length(g)+1 && contains(g{i+a}, "=")
[keys{end+1} vals{end+1}] = comsolparam(g{i+a});
a = a + 1;
end
if initial
key = cell2struct(vals, keys, 2);
initial = false;
else
key(end+1) = cell2struct(vals, keys, 2);
end
i = i + a;
end
end
function raw = comsolraw(fid, meta)
initial = true;
while ~feof(fid)
tline = fgetl(fid);
A = strsplit(tline, " ");
B = struct;
a = 1;
if meta.Dimension >= 1
B.X = str2double(A{a});
a = a+1;
end
if meta.Dimension >= 2
B.Y = str2double(A{a});
a = a+1;
end
if meta.Dimension >= 3
B.Z = str2double(A{a});
a = a+1;
end
B.dat = str2double(A(a:end)); % Fill it
if initial
raw = B;
initial = false;
else
raw(end+1) = B;
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment