Run Comsol Simulations from Matlab

March 1st, 2007 by

Note: This post is slightly outdated. Since I wrote this post back in 2004, Comsol integrated parameter looping to their solver (it was called Femlab back then). Many use cases that would have previously required Matlab integration can be handled entirely within Comsol now. The particular case that is shown could not (because the permittivity is calculated from a helper function). Unfortunately I do not have the time to answer specific questions or basic FEA issues, but hope that this post gets you pointed in the right direction for simulation automation.

Comsol is extremely powerful because it's well integrated with Matlab. However, the ability to build and run simulations in Matlab isn't well documented.

Here are a few cases where you would want to build a simulation in Matlab:

  • You want to simulate a variety of geometries to optimize a system
  • You are generating tons of data and you would like to save the results for later analysis and plot generation
  • Your simulation is so complicated that the file is becoming tens or hundreds of megabytes in size

Instructions

Create a new simulation in Comsol or open an existing one. Now, choose Save As... from the File menu. Before you do anything else, look at the options that you have for saving it. One of them is to save it as a .m file. Do that and then open up the existing file in a text editor. You'll see something like this:

flclear fem
clear vrsn
vrsn.name = 'FEMLAB 3.1';
vrsn.ext = '';
vrsn.major = 0;
vrsn.build = 157;
vrsn.rcs = '$Name: $';
vrsn.date = '$Date: 2004/11/12 07:39:54 $';
fem.version = vrsn;
...

Take a few minutes to dig through the file and guess what it's doing. It's important to realize that this is a normal .m file so you have access to all of Matlab's libraries and commands.

So how do you run these things? The next time that you start up Comsol be sure to use the Comsol with Matlab option and then just open the file in Matlab like you would any other script. This last step gave me plenty of grief and it's surprising that Comsol doesn't more clearly communicate the massive power that you gain by working directly with the text file (edit: at least in 2004 when I was working on this, I've heard rumors that things are a lot better documented now).

My usual procedure for using this feature is create a new simulation in Comsol using the GUI with the exact options, geometry, boundary conditions, etc. that I want. Once it is done, run the simulation and then save it as a .m file. This approach is useful because Comsol will generate all of the hard part for you and you can just go back and add your for loops, etc.

Here's an example file that I used for simulating the local electromagnetic field enhancement for a gold nanocrescent at UC Berkeley.

% Joseph Doll
% OpticalOneLayer.m
% FEMLAB 3.1 simulation to calculate the maximum local electric field
% enhancement for a gold or silver nanocrescent of arbitrary ID, OD,
% and opening width immersed in a low absorption dielectric medium of
% arbitrary dielectric constant.
function [simResults, lambda] = NanocrescentSim(OD, IDRatio, ...
  DRatio, lambda, eps_o)

flclear fem
clear vrsn
vrsn.name = 'FEMLAB 3.1';
vrsn.ext = '';
vrsn.major = 0;
vrsn.build = 157;
vrsn.rcs = '$Name: $';
vrsn.date = '$Date: 2004/11/12 07:39:54 $';
fem.version = vrsn;

% -------------------------------------------------------------
% -------------- Start Geometry Initialization ----------------
% -------------------------------------------------------------

% Fix outside diameter
% Specify inside diameter as a proportion of OD
% Specify delta as a proportion of ID

indexCounter = 1;
theta = 0;

for outsideRadius = OD/2
  for insideRadius = outsideRadius.*IDRatio
    for delta = (insideRadius*2).*DRatio

    sprintf('OD = %d, ID = %d, OW = %d', ...
      2*outsideRadius, 2*insideRadius, delta)

    % Calculate the horizontal displacement of each ellipse based
    % upon the dimensions noted above (radii and opening widths)
    outerCircleDx = 0;
    outerCircleDy = 0;

    innerCircleDx = -((outsideRadius - insideRadius) + ...
      (insideRadius*(1-cos(asin(delta/(2*insideRadius))))) - ...
      (outsideRadius*(1-cos(asin(delta/(2*outsideRadius))))));
    innerCircleDy = 0;

    % Define the ellipses based upon the calculated dimensions
    g1=ellip2(outsideRadius,outsideRadius,'base','center','pos', ...
      [outerCircleDx,outerCircleDy],'rot','0');
    g5=ellip2(insideRadius,insideRadius,'base','center','pos', ...
      [innerCircleDx,innerCircleDy],'rot','0');

    % Define the environment bound rectangle
    bound_rect = rect2('4e-6','2e-6','base','center', ...
      'pos',{'0','0'},'rot','0');

    % Boolean operations to create the "sharp structures"
    sharp_nc = geomcomp({g1,g5},'ns',{'g1','g5'},'sf', ...
      'g1-g5','edge','none');

    % Fillets
    round_nc = fillet(sharp_nc,'radii',2E-9,'point',[1 2]);

    % Rotate the finished nanocresent
    nanocrescent = rotate(round_nc, theta ,[0,0]);

    clear s
    s.objs = {nanocrescent, bound_rect};
    s.name={'NC','BR'};
    s.tags={'nanocrescent','boundrect'};

    fem.draw=struct('s',s);
    fem.geom=geomcsg(fem);

    % ---------------------------------------------------------
    % ---------------- Start Simulation Loop ------------------
    % ---------------------------------------------------------

    % Vector of the max electric field at each wavelength
    emax = [];

    % Calculate the dielectric constant values
    % Requires helper function OpticalData.m
    eps_i = OpticalData( lambda(1), ...
      lambda(length(lambda)),length(lambda),1);

    for ii = 1:length(lambda)
      fem.const={'eps_i',eps_i(ii),'eps_o',eps_o};

      clear appl
      appl.mode.class = 'InPlaneWaves';
      appl.module = 'CEM';
      appl.assignsuffix = '_wh';

      % Solve via input wavelength
      clear prop
      prop.field='TM';
      prop.inputvar='lambda';
      appl.prop = prop;

      % Set the boundary conditions
      clear bnd
      bnd.H0 = {{0;0;1},{0;0;0},{0;0;0}};
      bnd.type = {'NR','cont','NR'};
      bnd.ind = [1,3,3,3,2,2,2,2,2,2,2,2,2,2];
      appl.bnd = bnd;

      % Set the domain variables
      clear equ
      equ.epsilonr = {'eps_o','eps_i'};
      equ.ind = [1,2];
      appl.equ = equ;

      % Set the current wavelength
      appl.var = {'nu','1e9','lambda0',lambda(ii)};
      fem.appl{1} = appl;
      fem.border = 1;

      fem=multiphysics(fem);

      % Mesh initialize parameters, smaller = finer
      fem.mesh=meshinit(fem, ...
        'hmaxfact',1, ...
        'hcurve',0.1, ...
        'hgrad',1.2, ...
        'hcutoff',0.001);

      fem.xmesh=meshextend(fem);

      fem.sol=femlin(fem, ...
        'solcomp',{'Hz'}, ...
        'outcomp',{'Hz'});

      % posteval returns the electric field at each point
      eii_struct = posteval(fem,'normE_wh','dl',[1]);

      % Take the maximum field value and add it to emax
      eii_max = max(eii_struct.d);
      emax = [emax eii_max];
    end

    simResults{indexCounter} = emax;
    indexCounter = indexCounter + 1;
  end
end
end

Using this approach I was able to automate process of finding the peak electric field intensity as a function of design parameters. Combined with another script I was able to run a simulation for about 3 days on end that tested 300+ different geometry combinations. And all I had to do was set it up, click a button, and put a note on the computer to not disturb it. Like I said, pretty awesome.

34 Responses to “Run Comsol Simulations from Matlab”

  1. madteckhead Says:

    interesting thanks, keep the posts coming!

  2. carlosvinicius Says:

    Great post ! Keep writing!
    Thanks

  3. Ryan Westafer Says:

    Excellent write-up, and with an example script! Not only did you solve the problem for your own research, but now you've enabled others like me to get a jumpstart on COMSOL scripting. That extra effort to document your solution is much appreciated. Thanks!

  4. marco Says:

    Hi Joey, Marco here. I sent you a private email, but I guess this comment box is even better. Congrats on the website and the article.
    I have two simple questions. By the way, I am using the RF module (lelectromagnetic simulations).
    In Comsol, I see that after clicking “Solve”, there are predefined variables that I can plot.
    1) How can I plot user-defined variables, like phase? Which commands/box in the GUI can I use?
    2) I am trying to draw 1 turn of a helicoid (solid linear spiral ramp). I tried to revolve a 2D rectangle around a line, hoping to find a way to make it also move along the line while rotating. Do you have any suggestion on how to draw it?
    thanks
    marco

  5. jcdoll Says:

    I replied to your email, but for posterity and others:

    I'm glad the post has been helpful. Re: your questions, its been a few years since I dusted off Comsol but here's a shot…

    1) For plotting phase, perhaps Comsol already returns it as part of the solution. Otherwise, you can plot it as long as you define it on every domain within the solution. I've never done that, but I've heard from others that Comsol has recently improved the quality of the scripting documentation and you might be able to find something about it in the docs.

    2) No idea about drawing the helicoid. Comsol's 3d drawing capabilities leave a lot to be desired. You could always draw it in another program (solidworks, blender, etc) and export it to Comsol.

  6. JohnFerd Says:

    Hello, thank you very much for this article, it really shed some light on how to utilize matlab and femlab together! One question about something i have been trying to find out with this procedure, but to no avail yet:

    In the post processing menu of femlab, there is a 'Geometric parameters' option, which opens up a new window with very useful information such as the inertia tensor for a subdomain, center of mass coordinates etc. Unfortunately, saving afterwards as an *.m file does not include the code for calculating these.

    Any ideas on how could someone calculate or call from the code these parameters? Thank you in advance for any replies.

  7. caroline Says:

    useful,thank you

  8. samira Says:

    Thanks it was great,

    just I have more question, may I have your email?

  9. Alderson Says:

    Hi Joey: Thanks for the article. I wonder if you have some info regarding saving partial solutions in Comsol. In my case I am running a thermnal transient problem and my heat source is changing location in a very short time so I have to solve the whole system for an specific location and then update the location being the previous solution the initial conditions for the next one. At the end I only get the final result but I need to be able to save an individual result for further analysis. I hope I was clear. Thanks in advance for your help

  10. UAgirl Says:

    This is a great write-up. I am also trying to automate a process to solve for the max electric field around a geometry. Was the other script written to automate the process in Matlab or COMSOL?

  11. enri Says:

    great! thanks

  12. ram Says:

    I dont find comsol with matlab on my machine and when i try to run the matlab code i get an error and the system dosent work ,,can you tell me the solution if i have to use matlab to run comsol ..

  13. jcdoll Says:

    Install Comsol after installing Matlab, and be sure to check the box for Matlab integration during the Comsol install.

  14. jcdoll Says:

    Install Comsol after installing Matlab, and be sure to check the box for Matlab integration during the Comsol install.

  15. fmhood Says:

    Thanks for a great post!
    I have no experience with comsol-matlab interface, so bear with me. I can see that the simulation section is looped. So I suppose that the m-file above is loaded into comsol, to run/solve it? Or is everything done in matlab?

  16. jcdoll Says:

    You first open “Comsol with Matlab”, which will start instances of both applications. Then in the Matlab window you run the code above. This method allows you to access the data that the simulation spits out. Alternatively, you can open .m files directly in Comsol, which will run them but won't give you direct data access.

    A useful approach to generating a .m file for a new problem is to generate your model in Comsol and then use the “save as” option to save the model as a .m file, which can then be tweaked and run in Matlab.

  17. fmhood Says:

    Thanks alot.
    I think I understand how the m-file is generated and accessed using matlab.
    I need one small clarification though: When matlab reads the 'simulation loop' in the script above, it make calls to comsol in order to start the simulations and afterwards access the data to postprocess it in the matlab environment?

  18. jcdoll Says:

    Yup, when femlin() is called, Matlab waits for Comsol to return the data. Once the simulation is done, the solution is stored in fem.sol and can be treated like any old struct.

  19. fmhood Says:

    Wow this is really powerfull then! thanks alot!

  20. Sharifi Fatemeh Says:

    Hi
    i copied your m file and run it in my matlab2008b but it shows errors for example:
    ??? Input argument “OD” is undefined.

    Error in ==> NanocrescentSim at 29
    for outsideRadius = OD/2

    when i get a specific number to OD, it then start asking another parameter
    i dont know how to do
    i think comsol should some how defined this parameters in matalb

    please tell me how to remove this errorrs
    my email is: sharifi.fatemeh@gmail.com

  21. jcdoll Says:

    That's because this is a *function* not a script. You need to pass in several arguments, i.e. the check out the first line…

    function [simResults, lambda] = NanocrescentSim(OD, IDRatio, DRatio, lambda, eps_o)

  22. Marco Says:

    Thanks man.. i've started today to use comsol with matlab script.. you show me that's possible..!!
    Bye

  23. sara Says:

    i want help witj Comsol Multiphysics 4.1 . i want to simulate and model electric field as a function of time varying voltage. i dont know how to do this, because i never used this software before. any help will be very appreciable. thanks
    Regards Sara borge

  24. jcdoll Says:

    Hi Sara –
    The post that you commented on is about using a poorly documented feature that might be helpful for advanced users.

    If you need basic help on using their products, you should RTFM or contact Comsol. That's why they get paid the big bucks.

    – joey

  25. Alain Says:

    Hello, i need help with Comsol – matlab.
    I just started using comsol and it is painful.
    I have a geometry which i can solve with comsol.
    I have want to use matlab to change an input (which is a constant) in comsol and then solve the problem again via matlab. Is there a way to avoid going to comsol, changing manually the input, solve, go back to matlab and process the output ? In other words, is there a command in matlab to Solve the FEM model in comsol ?
    Regards Alain

  26. jcdoll Says:

    Hi Alain –
    Yup, that’s exactly what the code in this post does. You’ll need to adapt it to your specific problem. From what I hear, the current MATLAB-Comsol integration is significantly better than it used to be and there are probably more detailed and up-to-date docs that shipped with your version of Comsol.

    – Joey

  27. Rupeshrpkoirala Says:

    hi, i have used COMSOL to solve a non linear partial differential equation. then i saved the file as .m . while running the model i wanted to extract data or tried to display the data in the variables but i could not. will you please tell me how the matlab model of the COMSOL used?

  28. ali Says:

    Hi, I have saved a comsol simulation as a mfile. I can run this mfile in MATLAB. I do not know how to access the results. Is it possible to have comsol results in MATLAb workspace?
    Thank you

  29. jcdoll Says:

    See the tail end of the script on this page. most importantly…

    fem.sol=femlin(…);
    eii_struct = posteval(fem,’normE_wh’,…);

    You use posteval in order to pull data out of the results structure. At least, this was how it worked back in 2004. Beyond that I can’t provide any advice.

    Cheers,
     Joey

  30. jcdoll Says:

    Hi Ali –
    See the reply I just posted to Rupeshrpkoirala. But note, I haven’t used Comsol/Femlab for its Matlab integration since 2004. So while I’m keeping this page up for posterity, I’d wager that there are better ways to do it now.

    – joey

  31. Deepakghanta Says:

    excellent…helped a lot at the right time…thank you very much…

    -deepak

  32. Foad Says:

    Thanks a lot Joey.

  33. subha Says:

    plz tel me how to read and understand this comsol mfile in the editor. i wan to understand this code. code talks about how it is taking values, how meshing, how doing geometry, how to get curves for each time level.
    ?

  34. jcdoll Says:

    Hi Subha –
    Unfortunately I can’t solve your problem for you. But hopefully the comments in the code above (and the Comsol documentation!) will get you started.

    It’s important to note that the Comsol-Matlab example on this page is from Comsol/Femlab 3.1 so is 6+ years old. Comsol reworked their Matlab interface in version 4. So if you’re using a modern version of Comsol then it will probably look very different than what I posted. Also, parameterization of your geometry is well supported in Comsol 4.x and doesn’t require fussing with any .m files.

    Best of luck,
    Joey


fetishroom