Note: This discussion is about an older version of the COMSOL Multiphysics® software. The information provided may be out of date.

Discussion Closed This discussion was created more than 6 months ago and has been closed. To start a new discussion with a link back to this one, click here.

Creating spatially-dependent material properties from file via LiveLink for Matlab

Please login with a confirmed email address before reporting spam


Hi All,

I'm using the RF module and LiveLink for Matlab to perform 2D mode solving of nanoscale optical waveguides. I would like one of my domains to have a material property (refractive index) that is a dependent on position, but that can not be expressed as a function of position - rather, I need to import this material property from Matlab.

The good news is that the index profile is a function of a previous COMSOL calculation on the same grid (the goal is to iteratively solve for the modes of a waveguide with nonlinear index). It's trivial to create a structure in Matlab that contains all of the required data. My problem is, I can't figure out how to send this information back to COMSOL to set a material property with spatial dependence. I'm guessing that I need the model.material() function, but I can't get my head around the syntax..

Any suggestions?


5 Replies Last Post Jun 7, 2012, 5:19 p.m. EDT

Please login with a confirmed email address before reporting spam

Posted: 1 decade ago Jun 7, 2012, 4:26 a.m. EDT
Hi,


It is possible. I have not tried to read in a grid from a matlab array directly. But I have tried to read in a grid from a text file which is re-written at each time step as part of MATLAB calculation and essentially contains: x, y, f(x,y).

Based on livelink manual, for example, I just show you the creation of a text file called ksoft.txt


%%
% Open the file ksoft.txt for writting and enter the
% evaluated data with the format '%%x y ksoft'. Exclude in the file the NaN
% value that result of evaluating the ksoft outside the domain.
fid = fopen(filename1,'w');
fprintf(fid,'%%x y ksoft\n');
for j = 1:nog
if ~isnan(x1(j))||~isnan(y1(j))
fprintf(fid,'%10.10f %10.10f %10.10f\n',x1(j),y1(j),ksoft1(j));
end
end
fclose(fid);

I then have the following two lines:

model.func('int1').setIndex('funcs', 'int2', 0, 0);
model.study('std1').run;

To know what the int2 is doing, I attach a screenshot.

I guess that implementing directly from MATLAB array should also be simple but I have not had time to do it.

Sorry I cannot be of more help.


Suresh


Hi, It is possible. I have not tried to read in a grid from a matlab array directly. But I have tried to read in a grid from a text file which is re-written at each time step as part of MATLAB calculation and essentially contains: x, y, f(x,y). Based on livelink manual, for example, I just show you the creation of a text file called ksoft.txt %% % Open the file ksoft.txt for writting and enter the % evaluated data with the format '%%x y ksoft'. Exclude in the file the NaN % value that result of evaluating the ksoft outside the domain. fid = fopen(filename1,'w'); fprintf(fid,'%%x y ksoft\n'); for j = 1:nog if ~isnan(x1(j))||~isnan(y1(j)) fprintf(fid,'%10.10f %10.10f %10.10f\n',x1(j),y1(j),ksoft1(j)); end end fclose(fid); I then have the following two lines: model.func('int1').setIndex('funcs', 'int2', 0, 0); model.study('std1').run; To know what the int2 is doing, I attach a screenshot. I guess that implementing directly from MATLAB array should also be simple but I have not had time to do it. Sorry I cannot be of more help. Suresh


Please login with a confirmed email address before reporting spam

Posted: 1 decade ago Jun 7, 2012, 2:36 p.m. EDT

Hi Suresh,

Thanks for your suggestion, I'll give it a try. I don't have any problem with going from Matlab to COMSOL via a .txt file.

Would I complete the task simply by setting my material parameter to 'ksoft', using your example?

Cheers,
Brian
Hi Suresh, Thanks for your suggestion, I'll give it a try. I don't have any problem with going from Matlab to COMSOL via a .txt file. Would I complete the task simply by setting my material parameter to 'ksoft', using your example? Cheers, Brian

Please login with a confirmed email address before reporting spam

Posted: 1 decade ago Jun 7, 2012, 3:47 p.m. EDT

Suresh,

I'm not quite sure what your last 2 lines accomplish. I managed to get COMSOL to read and interpolate the .txt file by setting up int1 and the variable by hand in COMSOL, but I need to be able to set these through MATLAB (since it's going to iterate in a MATLAB loop). Any thoughts?

Thanks,
Brian
Suresh, I'm not quite sure what your last 2 lines accomplish. I managed to get COMSOL to read and interpolate the .txt file by setting up int1 and the variable by hand in COMSOL, but I need to be able to set these through MATLAB (since it's going to iterate in a MATLAB loop). Any thoughts? Thanks, Brian

Please login with a confirmed email address before reporting spam

Posted: 1 decade ago Jun 7, 2012, 3:59 p.m. EDT
I'd suggest to avoid using interpolation function in this case. It's rather slow/inaccurate. Instead, call Matlab function directly from COMSOL (Global def.-Functions-Matlab).

Input to the function should be xyz coordinates (vectors) and output is the function value (vector of the same size). I define electric fields in such a way and it's so much faster and accurate than doing through text files.
I'd suggest to avoid using interpolation function in this case. It's rather slow/inaccurate. Instead, call Matlab function directly from COMSOL (Global def.-Functions-Matlab). Input to the function should be xyz coordinates (vectors) and output is the function value (vector of the same size). I define electric fields in such a way and it's so much faster and accurate than doing through text files.

Please login with a confirmed email address before reporting spam

Posted: 1 decade ago Jun 7, 2012, 5:19 p.m. EDT
Hi Brian,


I am not sure of your question.

All the lines I gave you are to be written into a program file that you create in matlab.

If you are loading filename.m file then the interpolation command would already be in the m file itself so you probably don't need it. This script and many more would be necessary if you are writing out the entire script yourself without calling the m file.

The next line "model.study('std1').run;" is necessary because I have to run the model. What I showed you was just an extract from a much larger matlab input file. I have a lot more scripting to effect changes at every time step within a loop and therefore I run the model after changing them. I am not sure if I understood your question correctly here. So I attach here again a partial code that may help you a bit more.

Alexander is right that it is better to call matlab array directly, because in this approach, as you have guessed you have to keep writing data into a text file at each step of the loop. I think this could be slow. I had no problems with accuracy at least for the problem I was solving, it also depends on how many data points you have.



Suresh

------------------------------------------------
clear

%%
% have to load mph here
model = mphload('modelname'); % no need to put .mph extension to the modelname

% allocate arrays and initialise ksoft
filename1='D:\My_research\ksoft.txt';
pd1=mpheval(model,'u','pattern','gauss');
nog=length(pd1.p(1,:));
ksoft1=zeros(nog,1);
ksoft1(:)=1e-4;
x1=pd1.p(1,:);
y1=pd1.p(2,:);

%%
% Open the file ksoft.txt for writting and enter the
% evaluated data with the format '%%x y ksoft'. Exclude in the file the NaN
% value that result of evaluating the ksoft outside the domain.
fid = fopen(filename1,'w');
fprintf(fid,'%%x y ksoft\n');
for j = 1:nog
if ~isnan(x1(j))||~isnan(y1(j))
fprintf(fid,'%10.10f %10.10f %10.10f\n',x1(j),y1(j),ksoft1(j));
end
end
fclose(fid);

%%
% Run a loop
for i = 1:50
%%
% set parameter values

model.param.set('bound_disp', i*1e-6);

for iter = 1:2
% Run the study.
if (iter>1)
model.param.set('param1',1);
model.param.set('param2',1);
else
model.param.set('param1',0);
model.param.set('param2',0);
end
model.func('int1').setIndex('funcs', 'int2', 0, 0);
model.study('std1').run;


% re-evaluate ksoft
script deleted

% re-write ksoft.txt
script deleted


%%
% Set the new solution vector back into comsol, reset only the last time
% % step value
model.sol('sol1').setU(Ulast);
model.sol('sol1').createSolution;
model.sol('sol1').feature('v1').set('initmethod', 'sol');
model.sol('sol1').feature('v1').set('initsol', 'sol1');

disp(sprintf(' Completed iteration no. - %d',iter));
end
disp(sprintf('Completed load step. - %d',i));
end


end

disp(sprintf('Problem completed. %d'));



Hi Brian, I am not sure of your question. All the lines I gave you are to be written into a program file that you create in matlab. If you are loading filename.m file then the interpolation command would already be in the m file itself so you probably don't need it. This script and many more would be necessary if you are writing out the entire script yourself without calling the m file. The next line "model.study('std1').run;" is necessary because I have to run the model. What I showed you was just an extract from a much larger matlab input file. I have a lot more scripting to effect changes at every time step within a loop and therefore I run the model after changing them. I am not sure if I understood your question correctly here. So I attach here again a partial code that may help you a bit more. Alexander is right that it is better to call matlab array directly, because in this approach, as you have guessed you have to keep writing data into a text file at each step of the loop. I think this could be slow. I had no problems with accuracy at least for the problem I was solving, it also depends on how many data points you have. Suresh ------------------------------------------------ clear %% % have to load mph here model = mphload('modelname'); % no need to put .mph extension to the modelname % allocate arrays and initialise ksoft filename1='D:\My_research\ksoft.txt'; pd1=mpheval(model,'u','pattern','gauss'); nog=length(pd1.p(1,:)); ksoft1=zeros(nog,1); ksoft1(:)=1e-4; x1=pd1.p(1,:); y1=pd1.p(2,:); %% % Open the file ksoft.txt for writting and enter the % evaluated data with the format '%%x y ksoft'. Exclude in the file the NaN % value that result of evaluating the ksoft outside the domain. fid = fopen(filename1,'w'); fprintf(fid,'%%x y ksoft\n'); for j = 1:nog if ~isnan(x1(j))||~isnan(y1(j)) fprintf(fid,'%10.10f %10.10f %10.10f\n',x1(j),y1(j),ksoft1(j)); end end fclose(fid); %% % Run a loop for i = 1:50 %% % set parameter values model.param.set('bound_disp', i*1e-6); for iter = 1:2 % Run the study. if (iter>1) model.param.set('param1',1); model.param.set('param2',1); else model.param.set('param1',0); model.param.set('param2',0); end model.func('int1').setIndex('funcs', 'int2', 0, 0); model.study('std1').run; % re-evaluate ksoft script deleted % re-write ksoft.txt script deleted %% % Set the new solution vector back into comsol, reset only the last time % % step value model.sol('sol1').setU(Ulast); model.sol('sol1').createSolution; model.sol('sol1').feature('v1').set('initmethod', 'sol'); model.sol('sol1').feature('v1').set('initsol', 'sol1'); disp(sprintf(' Completed iteration no. - %d',iter)); end disp(sprintf('Completed load step. - %d',i)); end end disp(sprintf('Problem completed. %d'));

Note that while COMSOL employees may participate in the discussion forum, COMSOL® software users who are on-subscription should submit their questions via the Support Center for a more comprehensive response from the Technical Support team.