How to Create a Randomized Geometry Using Model Methods

June 5, 2017

Have you ever wanted to include a randomly created geometry in your model? Perhaps you want to simulate a natural material or an arrangement of parts that has some known statistical distribution of dimensional variations. In such cases, we may want to create a random geometry in the COMSOL Multiphysics® software. With the release of version 5.3, we can now create random geometries using a method. Let’s take a look at how to do so with a tasty example.

Building a Model of Swiss Cheese

Determining the best cheese in the world is a hotly contested task, but I’ll go ahead and add my opinion: a good Emmentaler cheese is hard to beat. A master cheesemaker might joke that it’s really the holes that add the flavor, so if we’re going to build a good COMSOL Multiphysics model of a wheel of cheese, we need to include the holes.

An image showing a model of cheese with randomized holes.
A model of Emmentaler cheese, with randomly positioned and sized holes.

It turns out that the reasons for the holes in Swiss cheese are quite complicated, so we aren’t going to try to model the hole formation itself. Instead, we will simply set up a model of the cheese, as shown in the image above. We want to include a randomly distributed set of holes within the cheese, with a random hole radius between some upper and lower limit on the radius. We can build this randomized geometry in COMSOL Multiphysics version 5.3 using the new method functionality. Let’s find out how…

Introducing Methods in COMSOL Multiphysics®

When you’re running COMSOL Multiphysics® version 5.3 on the Windows® platform and working with the Model Builder, you will now see a Developer tab in the ribbon, as shown in the screenshot below. One of the options is Record Method. When clicked, this option prompts you to enter a new method Name and Method type. You can enter any string for the method name, while the method type can either be application method or model method.

An application method can be used within a COMSOL app — a process introduced in this tutorial video. A model method can be used within the underlying COMSOL Multiphysics model and can operate on (and add information to) the existing model data.

A screenshot showing the new Developer tab in COMSOL Multiphysics® version 5.3.
The Developer tab, showing the Record Method and Run Model Method buttons.

After you click the OK button in the Record Method dialog box, you can see a red highlight around the entire graphical user interface. All operations performed are recorded in this method until you click the Stop Recording button. You can then switch to the Application Builder and view your recorded method. The screenshot below shows the Application Builder and the method after we record the creation of a single geometry object. The object is a cylinder with the tag cyl1, a radius of 40 cm, and a height of 20 cm — a good starting approximation for a wheel of cheese.

A screenshot of the code for a method in the Application Builder.
The Application Builder showing code for a method used to create a geometry.

When we’re working with the Model Builder, we can call this method within any other model file (as long as it doesn’t already have an existing object with tag cyl1 within the geometry sequence) via the Run Model Method button in the Developer tab. Of course, this simple method just creates a cylinder. If we want to model the holes, we need to introduce a bit of randomness into our method. Let’s look at that next.

Creating a Random Set of Geometry Features

Within a method, you can call standard Java® classes, such as the Math.random class, which returns a double-precision number greater than or equal to 0.0 and less than 1.0. We want to use this class, along with a little bit of extra code, to set up a specified number of randomly positioned and sized holes within the model of the wheel of cheese.

Let’s say that we want 1000 holes randomly distributed throughout the cheese that each have a random radius between 0.1 cm and 1 cm. We also need to keep in mind that Emmentaler cheese has a natural rind within which no holes form. So, we need to add a bit of logic to make sure that our 1000 holes are actually inside the cheese. The complete method below (with line numbers added and text strings in red) shows how to do this.

1  int NUMBER_OF_HOLES = 1000;
2  int ind = 0;
3  double hx, hy, hz, hr = 0.0;
4  double CHEESE_HEIGHT = 20.0;
5  double CHEESE_RADIUS = 40.0;
6  double RIND_THICKNESS = 0.2;
7  double HOLE_MIN_RADIUS = 0.1;
8  double HOLE_MAX_RADIUS = 1.0;
9  model.component("comp1").geom("geom1").lengthUnit("cm");
10 model.component("comp1").geom("geom1").selection().create("csel1", "CumulativeSelection");
11 while (ind < NUMBER_OF_HOLES) {
12   hx = (2.0*Math.random()-1.0)*CHEESE_RADIUS;
13   hy = (2.0*Math.random()-1.0)*CHEESE_RADIUS;
14   hz = Math.random()*CHEESE_HEIGHT;
16   if ((Math.sqrt(hx*hx+hy*hy)+hr) > CHEESE_RADIUS-RIND_THICKNESS) {continue; }
17   if (((hz-hr) < RIND_THICKNESS) || ((hz+hr) > CHEESE_HEIGHT-RIND_THICKNESS)) {continue; }
18   model.component("comp1").geom("geom1").create("sph"+ind, "Sphere");
19   model.component("comp1").geom("geom1").feature("sph"+ind).set("r", hr);
20   model.component("comp1").geom("geom1").feature("sph"+ind).set("pos", new double[]{hx, hy, hz});
21   model.component("comp1").geom("geom1").feature("sph"+ind).set("contributeto", "csel1");
22   ind++;
23 }
24 model.component("comp1").geom("geom1").create("cyl1", "Cylinder");
25 model.component("comp1").geom("geom1").feature("cyl1").set("r", CHEESE_RADIUS);
26 model.component("comp1").geom("geom1").feature("cyl1").set("h", CHEESE_HEIGHT);
27 model.component("comp1").geom("geom1").create("dif1", "Difference");
28 model.component("comp1").geom("geom1").feature("dif1").selection("input").set("cyl1");
29 model.component("comp1").geom("geom1").feature("dif1").selection("input2").named("csel1");
30 model.component("comp1").geom("geom1").run();

Let’s go through this method line by line:

1. Initialize and define the total number of holes that we want to put in the cheese.
2. Initialize and define an index counter to use later.
3. Initialize a set of double-precision numbers that holds the xyz-position and radius of each hole.
4–8. Initialize and define a set of numbers that defines the cheese height, radius, ring thickness, and maximum and minimum possible hole radius in centimeters.
9. Set the length unit of the geometry to centimeters.
10. Create a new selection set, with tag csel and name CumulativeSelection. Note that if such a selection set already exists, the method fails at this point. You could also modify the method to account for this, if you want to run the method repeatedly in the same file.
11. Initialize a while loop to create the specified number of holes.
12–14. Define the xyz-position of the holes by calling the random method and scaling the output such that the xyz-position of the holes lies within the outer Cartesian bounds of the cheese.
15. Define the hole radius to lie between the specified limits.
16–17. Check if the hole position and size are such that the hole is actually outside of the cheese. If so, continue to the next iteration of the while loop without executing any of the remaining code in the loop. This check can be done in a single line or split into three lines, depending on your preference of programming style.
18. Create a sphere with a name based on the current index value.
19–20. Set the radius and position of the newly created sphere. Although the radius can be passed in directly as a double, the position must be specified as an array of doubles.
21. Specify that this sphere feature is part of (contributes to) the selection set named csel1.
22–23. Iterate the index, indicating that a sphere has been created, and close the while loop.
24–26. Create a cylinder primitive that represents the wheel of cheese.
27–29. Set up a Boolean difference operation. The object to add is the cylinder primitive, while the object to subtract is the selection of all of the spheres.
30. Run the entire geometry sequence, which cuts all of the spheres out of the cylinder, forming the wheel of cheese.

We can run this method in a new (and empty) model file to create a model of a wheel of cheese. Each time we rerun the method, we will get a different model. The geometry sequence in the model file contains all of the spheres and the cylinder primitives as well as the Boolean operation.

If we want to, we could also add some additional code to our method to write out a geometry file of just the final geometry: the cheese. This geometry file can be written in the COMSOL Multiphysics native or STL file format. We could also write out to Parasolid® software or ACIS® software file formats with any of the optional modules that include the Parasolid® software kernel. Working with just the final geometry after it has been exported and reimported is faster than working with the complete geometry sequence.

We can see the final results of our efforts below. Delicious!

An image showing a model of a wheel of Emmentaler cheese, an example of a randomized geometry.
A model of a wheel of Emmentaler cheese, ready to be eaten.

Closing Remarks on Creating a Randomized Geometry via Methods

We’ve looked at a simple example of how to use methods to create a geometry with randomly placed and sized features. There are some questions that we haven’t addressed here, such as how to ensure that the holes are not overlapping and how to come up with a close-packed arrangement, but these turn out to be difficult mathematical questions that are fields in their own right.

Of course, there is a lot more that you can do with methods, which we will save for another day. There are also other ways to create a random geometry, such as by parametrically defining a surface.

Related Resources

ACIS is a registered trademark of Spatial Corporation. Oracle and Java are registered trademarks of Oracle and/or its affiliates. Parasolid is a trademark or registered trademark of Siemens Product Lifecycle Management Software Inc. or its subsidiaries in the United States and in other countries. Microsoft and Windows are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries.

Comments (29)

Leave a Comment
Log In | Registration
Thales Fernandes
Thales Fernandes
June 6, 2017

With Model Methods is it possible to modify the solution itself? Even defining new variables?

For example, renormalizing the solution (instead of creating new variables) or changing eigenvalue positions?
In EM simulations Comsol sort solutions by neff (and sometimes not even that!). I find it better to sort by TE/TM fraction since this preserves modes orthogonality in a sweep.
Lumerical offers this possibility with “overlap” function but Comsol just sorts the modes in whatever random order that makes sweep discontinuous.

BTW, thanks for the post, post like these really teach us some tricks.

Tommaso Santagata
Tommaso Santagata
June 6, 2017

Very nice post, thank you!

Is it possible to use two shapes for the holes and give specific boundary conditions for each shape? e.g. for a fluid dynamics model, cylinders with no slip condition and spheres with a surface reaction term. What do you think about it?

Thank you for this very interesting post!

Walter Frei
Walter Frei
June 8, 2017

Hello Thales,
For the types of solution manipulation that you’re asking about, we would recommend that you look to the LiveLink for MATLAB product ( which lets you evaluate and manipulate your solutions.
Best Regards,

Walter Frei
Walter Frei
June 8, 2017

Hello Tommaso,
What you’re asking about could be achieved with the Selections capability. Not only can you use Geometry selections to perform further geometry operations (As we do in this example) but you can also use the Selections in your physics assignments. An example of the usage of these is in the 5.3 version of the heat sink example:
Best Regards,

thouaiba htira
thouaiba htira
November 23, 2017

thank you for this helpfull example. i have some questions :
is it possible to do this with comsol 5.2a?
the code is similar ?
after created the geometry how we can go back to the model builder and plot the geometry to continue adding physics etc… ?
Thank you for help!
Best regards,

Walter Frei
Walter Frei
December 1, 2017

Hello Thouaiba,
This functionality described here is new in 5.3.

H. Richter
H. Richter
December 8, 2017

Very informative post, thank you!

Regarding the generation of non-overlapping, random sphere packings, there exist several software tools that address this issue (an open-source one is available at Such tools could be easily used in conjunction with java scripting to create advanced microstructure models.

Walter Frei
Walter Frei
December 8, 2017

Thank you for the comment, I was not aware of this tool!

Mojtaba Dargahi
Mojtaba Dargahi
February 20, 2018

Hello Walter,
thank you for this helpful example. Just some questions :
How can we call it in my model? I mean, after writing down the sequences and creating the geometry in the way you explained how we can go back to the model builder and plot the geometry to continue adding physics etc… ?
Thank you for help!

Best regards,

Caty Fairclough
Caty Fairclough
March 1, 2018

Hi Mojtaba,

Thanks for your comment!

For your question, please contact our Support team.

Online Support Center:

Sarra Zid
Sarra Zid
October 23, 2018

Hello, thank you for this helpful example,
I would like to ask how to generate a Gaussian distribution of numbers, I know that we must use nextGaussian() but i have some errors in my application builder interface.


July 28, 2022

model.func().create(“rn1”, “Random”); // create random function
model.func(“rn1”).set(“type”, “normal”); // set as normal distribution
model.func(“rn1”).set(“mean”, “0.45/2”); // set mean
model.func(“rn1”).set(“normalsigma”, “0.025/2”); // set standard deviation

For example, set the random value for a radius in a while loop:
model.component(“comp1”).geom(“geom1”).feature(“circ”+ind).set(“r”, “rn1(“+ind+”)”);

Viki Temesvary
Viki Temesvary
January 8, 2019

Looks like lines 12-16 in the code snippet magically disappeared?!

Viki Temesvary
Viki Temesvary
January 11, 2019

it’s there in the model file of course!

while (ind CHEESE_RADIUS-RIND_THICKNESS) {continue; }

Said Bouta
Said Bouta
December 25, 2019

How to add this line in the script?

Jeff Hiller
Jeff Hiller
April 25, 2019

Thank you, Viki, for reporting the missing lines of code. This has now be corrected.

Flavio Moraes
Flavio Moraes
June 25, 2020

Is it possible to use Nd4j library in my methods? How do I do that?

Mikhail Kukharevich
Mikhail Kukharevich
September 12, 2020

Hello friend) Can I use this example in the optimization process ?) I want to investigate how a certain pore distribution will affect the strength of the cheese) I also have a problem with the fact that with a certain distribution, some of the pores go beyond the cheese) Can I update the form with the removal of pores that go beyond the cheese boundaries during the optimization process ?)

Sumit Choudhary
Sumit Choudhary
December 20, 2020

Dear Walter,

Thank you for nice blog.

Math.random() generates the random number between zero to one. I want to generate the random numbers whose elements are normally distributed with mean zero and standard deviation one. Can I generate using Model method in application programming interface of comsol?

Shuveksha sapkota
Shuveksha sapkota
June 11, 2021

i need the same answer.

Shuveksha sapkota
Shuveksha sapkota
June 11, 2021

Hey there. I am using Comsol to study about the effects on roughness on heat transfer chractersistics of a circular microchannel. These are the details.
Standard deviation = 1.00 micrometers
Surface roughness mean= 1.40 micrometers
Inner diameter= 123 micrometres
Outer diameter= 282 micrometers
Please provide me a suitable way on how this geomtry can be created and analysis be done.

You have similar file as i ned. Please provide details on how you created this.
random_tube_geometry_4_patches_hollowed_with_cylinder.mph – 6.42MB

Bojan Jokanovic
Bojan Jokanovic
July 1, 2021

Thanks. It is a very useful method for creating a geometry.

Kausik Bal
Kausik Bal
August 4, 2021

Thanks for the blog. While trying to replicate this, an error message may come as you have mentioned here:
“10. Create a new selection set, with tag csel and name CumulativeSelection. Note that if such a selection set already exists, the method fails at this point. You could also modify the method to account for this, if you want to run the method repeatedly in the same file.” I do not think the solution to this scenario was clear to me from reading your blog. Can you be a little more explicit and explain exactly what to do if such situation appears (i.e., the method fails to run due to the already existing selection set)? Thanks in advance.

Tanzila Nurjahan
Tanzila Nurjahan
March 23, 2022

Hello Mr. Walter Frei,
I am a new COMSOL user and currently using COMSOL 6.0.
I would like to extract the model of this (Swiss) cheese structure from the .mph file, however, it did not work. Could you please assist in extracting the mph file into modeling the structure? Thanks in advance.

Walter Frei
Walter Frei
March 23, 2022 COMSOL Employee

Hello Tanzila,
If you download the model file and run the method you will then have a sample geometry in the Geometry branch. If you want, toy can then export (right-click Geometry > Export… ) to the file type of your choice.

Tanzila Nurjahan
Tanzila Nurjahan
March 23, 2022

Dear Mr. Walter Frei,
I tried, however, it is not working. Is it possible to arrange an online discussion session, would be really helpful, thanks in advance.

Uthpala Ekanayake
Uthpala Ekanayake
December 19, 2022


I am trying to place random cubes, How do you set properties of the block.
e.g : model.componnet(“comp1”).geom(“”geom1).features(“blk”).set(“??”,hr)

What should come at “??” In the above code, for a sphere this is given as “r”

Pablo Ramos
Pablo Ramos
May 9, 2023

It is possible to avoid the overlapping of the spheres. And how is it done?

Walter Frei
Walter Frei
May 9, 2023 COMSOL Employee

Hello Pablo,
There is an interesting earlier comment, from H. Richter, that addresses this.
Happy Modeling!