Attempt to program parameter sweep on model in COMSOL, using OOP in MATLAB

40 vues (au cours des 30 derniers jours)
Oliver Bond
Oliver Bond le 9 Nov 2022
Commenté : chrisw23 le 11 Nov 2022
Using COMSOL LiveLink and object-orientated programming (which I am new to) I am trying to develop a convenient way of passing vectorised parameters into a COMSOL model and running a parameter sweep efficiently without using the GUI on COMSOL.
I am aware that this code assumes that a is a 10-by-1 array, and that b, c and d are scalars.
After declaring this class, I try running:
Test = SimpleModel;
Test.a = 1:10; Test.b = 2; Test.c = 3; Test.d = 4;
Test.solveAll
However, I keep getting Java errors, along the lines of "com.comsol.util.exceptions.FlException: Variable refers to an object which is no longer in the model"
classdef SimpleModel
properties
a {mustBeNumeric}
b {mustBeNumeric}
c {mustBeNumeric}
d {mustBeNumeric}
model = mphopen('simpleModel')
end
methods
function obj = paramSet(obj)
obj.model.param.set("a",obj.a);
obj.model.param.set("b",obj.b);
obj.model.param.set("c",obj.c);
obj.model.param.set("d",obj.d);
end
function obj = solve(obj)
obj.model.study("std1").run()
obj.model.result.dataset("dset1");
end
function Solution = solution(obj)
Solution = obj.model.result.dataset("dset1");
end
function Vertices = meshPoints(obj,show)
[~ , data] = mphmeshstats(obj.model);
Vertices = data.vertex';
if show == true
plot(Vertices(1,:),Vertices(2,:),'.')
end
end
function Values = solValues(obj)
Values = mpheval(obj.model,"u").d1';
end
function Value = meanValue(obj)
Value = mphglobal(obj.model,"aveop1(u)");
end
% for parameter sweeps
function Strings = paramNames(obj)
Strings = ["a","b","c","d"];
end
function Values = paramValues(obj)
Names = obj.paramNames;
Values = cell(1,length(Names));
for n = 1:length(Names)
Values{n} = getfield(obj,Names(n));
end
end
function Int = howManyParametersAreBeingSwept(obj)
Int = 0;
Values = obj.paramValues();
for n = 1:length(Values)
if length(Values{n}) > 1
Int = Int + 1;
end
end
end
function Strings = whichParametersAreBeingSwept(obj)
Names = obj.paramNames;
Values = obj.paramValues;
Strings = [];
for n = 1:length(Values)
if length(Values{n}) > 1
Strings = [Names(n) Strings];
end
end
end
function Cell = paramIndices(obj)
Cell = {1:10};
end
function Cell = storageSpace(obj)
Names = obj.paramNames;
Values = obj.paramValues;
Cell = cell(1,10);
for idx = 1:10
Cell{idx} = obj;
Cell{idx}.a = obj.a(idx);
end
end
function Solutions = solveAll(obj)
Solutions = obj.storageSpace;
for idx = 1:10
% keyboard
Temp = Solutions{idx};
Temp.model = mphopen('simpleModel');
ParamValues = Temp.paramValues;
Temp.model.param.set("a",Temp.a);
Temp.model.param.set("b",Temp.b);
Temp.model.param.set("c",Temp.c);
Temp.model.param.set("d",Temp.d);
Temp.solve()
Solutions{idx} = Temp;
end
clear Temp
end
end
end
As I am new to object-orientated programming, I am aware that the code above might have quite a few shortcomings. If anybody could provide guidance on these I would be very grateful.

Réponses (1)

chrisw23
chrisw23 le 10 Nov 2022
I suggest to use the constructor to load the model like.
...
methods
function obj = SimpleModel(modelFilePath)
obj.model = mphopen(modelFilePath)
end
...
  2 commentaires
Oliver Bond
Oliver Bond le 10 Nov 2022
Thanks for this. I have implemented some similar code with a different model.
However, I don't really want to need to load the .mph file every single time a SimpleModel object is declared. This makes the code particularly slow when one of the parameters is vectorised (a in this case). I only need to open the .mph file once, and then cycle through each parameter and get a solution.
(Strictly speaking, it is only really the parameters that need to be part of the SimpleModel class - the Model part is probably better as a method than an attribute).
How can I modify the code to take this into account?
chrisw23
chrisw23 le 11 Nov 2022
This suggestion was more in terms of having multiple objects (models) of the same class type. On the other hand you have path dependencies loading the model by file name and I would use the constructor to handle this by an argument or other options. I would also suggest to use the destructor (delete method) of your class to unload the model when the object lifetime ends. This could be importend for your comsol environment when a new model is to be loaded.

Connectez-vous pour commenter.

Catégories

En savoir plus sur Argument Definitions dans Help Center et File Exchange

Tags

Produits

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by