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.
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.
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.
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; 15 hr = Math.random()*(HOLE_MAX_RADIUS-HOLE_MIN_RADIUS)+HOLE_MIN_RADIUS; 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!
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
- Read about another use of model methods: generating simulation results that you can see and hear
- Check out the new features in COMSOL Multiphysics® version 5.3 on the Release Highlights page
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.