Last active
June 23, 2020 01:15
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%{ | |
% 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