diff --git a/README.md b/README.md index f7c00b0aeffef80681d11caf4bdafacce3b395ab..0e8f478f2b23fff53d5c32be3b8ca0b6fd485627 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Advantages: To get started, run `setup.m` in the root folder. This adds everything to the path and compiles .mex files if necessary. -Note that, at least, Matlab version R2022a is required. +Note that, at least, Matlab version R2022b is required. ## First steps diff --git a/lib/storage/@LevelData/LevelData.m b/lib/storage/@LevelData/LevelData.m index 8275605965d9e2977c04d81ee36f247915ef747b..7018f7f4acf77081e7af37a1a9c24a24e607f0bc 100644 --- a/lib/storage/@LevelData/LevelData.m +++ b/lib/storage/@LevelData/LevelData.m @@ -18,14 +18,7 @@ classdef LevelData < handle % properties - % Name of problem - problem = 'problem' - % Name of domain - domain = 'domain' - % Name of method - method = 'method' - % Identifier for computation - identifier = 'main' + metaData % Root folder for file storage root = 'results' % Structure array storing string representations of variables @@ -94,35 +87,30 @@ classdef LevelData < handle if nargin >= 1 obj.root = rootpath; end - ensureFolderExists(obj.root); - % Set hostname - obj.hostname = getHostname(); + + % TODO: set output of hostname to string and remove cast + obj.metaData = dictionary(... + "problem", "problem", ... + "domain", "domain", ... + "method", "method", ... + "identifier", "main", ... + "hostname", string(getHostname())); + % Save time of creation if isOctave() - obj.timestamp = datestr(now, 'yyyy-MM-dd_HH:mm:ss'); %#ok<TNOW1,DATST> + obj.metaData("timestamp") = datestr(now, 'yyyy-MM-dd_HH:mm:ss'); %#ok<TNOW1,DATST> else - obj.timestamp = char(datetime('now', 'Format', 'yyyy-MM-dd_HH:mm:ss')); + obj.metaData("timestamp") = char(datetime('now', 'Format', 'yyyy-MM-dd_HH:mm:ss')); end + + ensureFolderExists(obj.root); + % Set hostname + obj.hostname = getHostname(); % Initialise dictionary with some default values obj.dictionary = getDefaultDictionary(); end %% SET GLOBAL VARIABLES - function set.problem(obj, name) - assert(ischar(name), 'Insert character array as problem name.'); - obj.problem = name; - end - - function set.domain(obj, name) - assert(ischar(name), 'Insert character array as domain name.'); - obj.domain = name; - end - - function set.method(obj, name) - assert(ischar(name), 'Insert character array as method name.'); - obj.method = name; - end - function set.root(obj, path) assert(ischar(path), 'Insert character array as path name.'); obj.root = path; @@ -152,12 +140,12 @@ classdef LevelData < handle if numel(rootpath) > 0 && ~strcmp(rootpath(end), '/') rootpath = [rootpath, '/']; end - path = [rootpath, obj.problem, '_', obj.domain, '_', obj.method]; + path = rootpath + strjoin([obj.metaData("problem"), obj.metaData("domain"), obj.metaData("method")], '_'); end function file = get.filename(obj) % Name of file for file storage - file = [obj.identifier]; + file = [obj.metaData("identifier")]; end function bool = get.isScalar(obj) diff --git a/lib/storage/@LevelData/plotToFile.m b/lib/storage/@LevelData/plotToFile.m index 2efe1f12c844a1dab43d720fb4c7b236c588d6b6..23ffcee950fcaa105d850c200e1fd8c0091b6411 100644 --- a/lib/storage/@LevelData/plotToFile.m +++ b/lib/storage/@LevelData/plotToFile.m @@ -37,7 +37,7 @@ function plotToFile(obj, xVariable, varargin) end % Export plot - print(h, '-dpng', '-r600', [obj.foldername, '/', obj.filename, '.png']); + print(h, '-dpng', '-r600', obj.foldername + '/' + obj.filename + '.png'); % Close figure close(h); diff --git a/lib/storage/@LevelData/saveToFile.m b/lib/storage/@LevelData/saveToFile.m index b6af1ceeed229a4ea9edcdb4d3250fa1b9ea5b1d..b46a2b80a0abbadc9ea1d4323d629d351cdfd0e3 100644 --- a/lib/storage/@LevelData/saveToFile.m +++ b/lib/storage/@LevelData/saveToFile.m @@ -32,9 +32,10 @@ function saveToFile(obj, folder, file) % Create problem- and method-specific folder ensureFolderExists(folder); % Save this object to file + pathToMat = folder + '/' + file + '.mat'; if isOctave() - save([folder, '/', file, '.mat'], 'obj', '-v7'); + save(pathToMat, 'obj', '-v7'); else - save([folder, '/', file, '.mat'], 'obj', '-v7.3'); + save(pathToMat, 'obj', '-v7.3'); end end diff --git a/lib/storage/@LevelData/saveToTable.m b/lib/storage/@LevelData/saveToTable.m index 9ee04bffe8acc578f4803acf7575ed92eb6f9a48..8ac9fc83221caf761d5720c68a3d91949d01ab9a 100644 --- a/lib/storage/@LevelData/saveToTable.m +++ b/lib/storage/@LevelData/saveToTable.m @@ -33,7 +33,7 @@ function saveToTable(obj, separator) ensureFolderExists(obj.foldername); % Open file - fid = fopen([obj.foldername, '/', obj.filename, '.csv'], 'w'); + fid = fopen(obj.foldername + '/' + obj.filename + '.csv', 'w'); % Save header to file fprintf(fid, obj.headerSpecifier, obj.scalarVariable{:}); diff --git a/lib/storage/@LevelDataCollection/LevelDataCollection.m b/lib/storage/@LevelDataCollection/LevelDataCollection.m index 69c5efe49e8283b0bd58d6f1fefa0d3fdf35e471..90fd021aea50343f35027abaec5fc2ac542ee7ca 100644 --- a/lib/storage/@LevelDataCollection/LevelDataCollection.m +++ b/lib/storage/@LevelDataCollection/LevelDataCollection.m @@ -19,8 +19,7 @@ classdef LevelDataCollection < handle properties - % Identifier for computation - identifier = '' + metaData % Root folder for file storage root = 'results' % Cell array of LevelData objects @@ -28,12 +27,6 @@ classdef LevelDataCollection < handle end properties (Dependent) - % Name of problem - problem (1,:) char - % Name of domain - domain (1,:) char - % Name of method - method (1,:) char % Path to folder for file storage foldername (1,:) char % Name of file for storage @@ -73,9 +66,25 @@ classdef LevelDataCollection < handle end ensureFolderExists(obj.root); + % TODO: set output of hostname to string and remove cast + % TODO: does it make sense to store this here? -> see e.g. get.problem before + obj.metaData = dictionary(... + "problem", "problem", ... + "domain", "domain", ... + "method", "method", ... + "identifier", "main", ... + "hostname", string(getHostname())); + + % Save time of creation + if isOctave() + obj.metaData("timestamp") = datestr(now, 'yyyy-MM-dd_HH:mm:ss'); %#ok<TNOW1,DATST> + else + obj.metaData("timestamp") = char(datetime('now', 'Format', 'yyyy-MM-dd_HH:mm:ss')); + end + % Set identifier if nargin >= 2 - obj.identifier = identifier; + obj.metaData("identifier") = identifier; end end @@ -100,40 +109,16 @@ classdef LevelDataCollection < handle bool = (obj.nItem <= 1); end - function name = get.problem(obj) - if isempty(obj.item) - name = ''; - else - name = [obj.item{1}.problem]; - end - end - - function name = get.domain(obj) - if isempty(obj.item) - name = ''; - else - name = [obj.item{1}.domain]; - end - end - - function name = get.method(obj) - if isempty(obj.item) - name = ''; - else - name = [obj.item{1}.method]; - end - end - function path = get.foldername(obj) rootpath = obj.root; if numel(rootpath) > 0 && ~strcmp(rootpath(end), '/') rootpath = [rootpath, '/']; end - path = [rootpath, obj.problem, '_', obj.domain, '_', obj.method]; + path = rootpath + strjoin([obj.metaData("problem"), obj.metaData("domain"), obj.metaData("method")], '_'); end function file = get.filename(obj) - file = [obj.identifier, '_collection']; + file = obj.metaData("identifier") + '_collection'; end function spec = get.headerSpecifier(obj) diff --git a/lib/storage/@LevelDataCollection/saveToFile.m b/lib/storage/@LevelDataCollection/saveToFile.m index 81d502c4a2705cee5c846e9592f3028578d15040..b43d1e777ceb3e66ec4f7f5bb9a855eb4ce22b9e 100644 --- a/lib/storage/@LevelDataCollection/saveToFile.m +++ b/lib/storage/@LevelDataCollection/saveToFile.m @@ -38,6 +38,6 @@ function saveToFile(obj, folder, file) warning(['LevelData not stored. Octave cannot save classdef objects. ', ... 'See GNU Octave Bug: #45833']); else - save([folder, '/', file, '.mat'], 'obj', '-v7.3'); + save(folder + '/' + file + '.mat', 'obj', '-v7.3'); end end diff --git a/lib/storage/@LevelDataCollection/saveToTable.m b/lib/storage/@LevelDataCollection/saveToTable.m index 1fe0f076096cd3ca413c6db0302eb956ca04a102..6f748df078982acd9ffd213e1be30ba903fc0f63 100644 --- a/lib/storage/@LevelDataCollection/saveToTable.m +++ b/lib/storage/@LevelDataCollection/saveToTable.m @@ -35,8 +35,8 @@ function saveToTable(obj, separator) % Save data for each variable to a separate file data = obj.get(':', obj.timeVariable{:}); for j = 1:obj.nTimeVariable - fid = fopen([obj.foldername, '/', obj.filename, '_', ... - obj.timeVariable{j},'.csv'], 'w'); + fid = fopen(obj.foldername + '/' + obj.filename + '_' + ... + obj.timeVariable{j} + '.csv', 'w'); obj.printTable(fid, obj.timeVariable{j}, data{j}); fclose(fid); end diff --git a/lib/storage/TimeIt.m b/lib/storage/TimeIt.m index d84698b81431e16648021ebb54e5f22d1d25aa01..c8b533494d47518a527f3242fcb7e4bd36d2c819 100644 --- a/lib/storage/TimeIt.m +++ b/lib/storage/TimeIt.m @@ -25,13 +25,13 @@ function leveldatacollection = TimeIt(identifier, nRun, functionName, varargin) end % Welcome statement - fprintf('\n#\n# OCTAFEM - TIME MEASUREMENT\n'); + fprintf('\n#\n# MooAFEM - TIME MEASUREMENT\n'); fprintf('# Current Time: %s\n#\n\n', datestr(now)); fprintf('This is TimeIt wrapper for function "%s"\n\n', functionName); % Initialisation of collection for LevelData objects leveldatacollection = LevelDataCollection(); - leveldatacollection.identifier = identifier; + leveldatacollection.metaData("identifier") = identifier; % Run experiments for j = 1:nRun @@ -39,7 +39,7 @@ function leveldatacollection = TimeIt(identifier, nRun, functionName, varargin) temporaryIdentifier = sprintf('timingRun%04d', j); outputList = fevalc(functionName, varargin{:}); leveldata = outputList{1}; - leveldata.identifier = temporaryIdentifier; + leveldata.metaData("identifier") = temporaryIdentifier; % Remove unused information leveldata.removeNonscalar(); % Store information