Scripted CAD pre-processing with build123d

This example demonstrates how to use a separate CAD tool to generate the geometry used in M-Star Pre. While M-Star Pre has an abundence of built-in CAD geometries, including relevant parametric CAD models, it is not uncommon that you will need to create geomtry in a separate CAD tool such as Solidworks or other tool. In this example, we are using a Python package called build123d as our external CAD tool. This package allows us to generate custom CAD geometry outside of M-Star Pre.

Prerequisites:

  • Python installation

  • Python virtual environment setup as follows

    • M-Star Pre Python module setup in environment, see - Installation

    • build123d installed pip install build123d

The final case setup looks like this:

  • The stir bar is generated from build123d

  • Stir bar spins at 60 RPM

  • Dye is injected at 10s

  • Relative standard deviation of the dye scalar is tracked

../../../../_images/stirbar-ex.PNG
  • Copy or download the script into your project directory. Run the script using your environment.

  • Open the msb file in M-Star Pre and examine the case setup

  • Click Run and review results

  • Try making a change to the script such as:

    • Change the rotation RPM

    • Change stir bar size or aspect ratio

    • Implement a parameter sweep to loop over an array of rotation RPMs

mstar-b123-stirbar-rounded.py


from build123d import *
import mstar

def create_stir_bar(bar_length=0.1):

    bar_radius = bar_length * 0.1
    bar_end_cap_r = bar_radius * 0.75

    with BuildPart() as stirbar:
        with BuildSketch() as part_profile:
            with BuildLine() as profile:
                l0 = bar_length * 0.5
                l1 = l0 - bar_end_cap_r

                EllipticalCenterArc(center=[-l1, 0, 0], 
                                    x_radius=bar_end_cap_r, 
                                    y_radius=bar_radius,
                                    start_angle=90.0,
                                    end_angle=180.0)
                
                Line([ (-l1, bar_radius, 0), (l1, bar_radius, 0) ])

                EllipticalCenterArc(center=[l1, 0, 0], 
                                    x_radius=bar_end_cap_r, 
                                    y_radius=bar_radius,
                                    start_angle=0.0,
                                    end_angle=90.0)
                
                Line([ (-l1, 0, 0), (l1, 0, 0) ])

            make_face()
        revolve(axis=Axis.X)
    return stirbar    


mstar.Initialize()
model = mstar.Load()

tank_height = 0.3
tank_diameter = tank_height

staticBody = model.AddComponent("Static")
tankGeo = staticBody.AddGeometry("Cylindrical Tank")
tankGeo.Get("Diameter").Value = tank_diameter
tankGeo.Get("Length").Value = tank_height
tankGeo.Get("End1").Value = "Flat"
tankGeo.Get("Baffle Width").Value = 0

simParams = model.GetSimParams()
movingBody = model.AddComponent("Moving")
globalVar = model.AddComponent("GlobalVariable")
miscScalar = model.AddComponent("MiscibleScalar")

stirbar = create_stir_bar(bar_length=tank_height * 0.5)
stirbarfn = "stirbar-rounded.brep"
export_brep(stirbar.part, stirbarfn)
impellerGeo = movingBody.AddGeometryFromFile(stirbarfn)

miscScalarGeo = miscScalar.AddGeometry("Cylinder")

simParams.Get("Run Time").Value = 60.0

miscScalar.SetName("dye")
miscScalar.Get("Injection Time Span").Value = "Impulse"
miscScalar.Get("Injection Impulse Time").Value = 10.0
miscScalar.Get("Child Geometry Value").Value = "1.0"

miscScalarGeo.Get("Diameter").Value = 0.01
miscScalarGeo.Get("Length").Value = 0.01
miscScalarGeo.SetLocation(tank_diameter * 0.4, tank_height * .95, 0.0)

movingBodyHeight = tank_height * 0.05
movingBody.Translate(0, movingBodyHeight, 0)
movingBody.Get("Rotation Speed UDF").Value = "60.0"

globalVar.SetName("blendTime")
globalVar.Get("Data Source").Value = "Fluid"
globalVar.Get("Reduction").Value = "RelStdDev"
globalVar.Get("Code").Value = "value=dye;"

plane1 = model.AddComponent("OutputPlane")
plane1.Get("Axis Direction").Value = "Y"
plane1.Get("Value").Value = movingBodyHeight

plane2 = model.AddComponent("OutputPlane")
plane2.Get("Axis Direction").Value = "X"
plane2.Get("Value").Value = 0.0

model.Save("stirbar-example.msb")
model.Close()