How to Create a Randomized Geometry Using Model Methods

Walter Frei June 5, 2017
Share this on Facebook Share this on Twitter Share this on Google+ Share this on LinkedIn

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 model 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 Model Method functionality. Let’s find out how…

Introducing Model 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 model method in the Application Builder.
The Application Builder showing code for a model method used to create a geometry.

When we’re working with the Model Builder, we can call this model 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 model 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 model 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 model 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 model 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 model 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 Model Methods

We’ve looked at a simple example of how to use model 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 model 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.

Post Tags

Technical Content


  1. Thales Fernandes June 6, 2017   1:15 am

    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.

  2. Tommaso Santagata June 6, 2017   6:36 am

    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!

  3. Walter Frei June 8, 2017   8:48 am

    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,

  4. Walter Frei June 8, 2017   8:52 am

    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,

  5. thouaiba htira November 23, 2017   7:57 am

    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,

  6. Walter Frei December 1, 2017   1:10 pm

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

  7. H. Richter December 8, 2017   12:00 pm

    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.

  8. Walter Frei December 8, 2017   1:35 pm

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

  9. Mojtaba Dargahi February 20, 2018   11:31 am

    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,

  10. Caty Fairclough March 1, 2018   4:06 pm

    Hi Mojtaba,

    Thanks for your comment!

    For your question, please contact our Support team.

    Online Support Center:

Loading Comments...