I am trying to model deformations caused by identical, solid half-ball bearings on a thin, solid cylindrical plate in Ansys. But drawing the geometries is much easier in Mathematica, especially if I add boundary conditions or other preprocessing functions for the placement of the half-ball bearings.

I think there are probably a lot of ways to do this so I get accurate results, but I am not sure how to proceed. And if I get the file into IGES, STP, or whichever, I do not feel certain that it was done properly with want data dictated the file.

Here is a photo of 9 examples of geometries when looking above the plate:

This an aerial view of half-ball bearings on a cylindrical plate. It looks like non-overlapping darkly colored circles in a lighter color circle.

And here is the code to generate 1 random example:

HalfBallBearingCreation[radius_, bottomCenterCoordinate_] :=
  ParametricPlot3D[radius*{Cos[u] Sin[v], Sin[u] Sin[v], Cos[v]} + bottomCenterCoordinate, 
    {u, -Pi/2, Pi/2}, {v, -Pi/2, Pi/2}, 
    Mesh -> None, 
    Boxed -> False, 
    Axes -> None, 
    PlotStyle -> Directive[RGBColor[0.4, 0.4, 0.4], Opacity[1]]

    {radius* Cos[theta], radius* Sin[theta], z}, 
    {theta, 0, 2 Pi}, {z, -height, 0},
    Mesh -> None, 
    Boxed -> False, 
    Axes -> False

generateCirclesSameRadius[numCircles_Integer, boundaryRadius_, circleRadius_, maxAttempts_Integer] :=
 Module[{circles = {}, attempt = 0, newCircle, canPlace},
  While[Length[circles] < numCircles && attempt < maxAttempts,
   newCircle = RandomPoint[Disk[{0, 0}, boundaryRadius - circleRadius]];
   canPlace = True;
    If[Norm[newCircle - circle] < 2 circleRadius, canPlace = False; Break[];],
    {circle, circles[[All, 2]]}
   If[canPlace, AppendTo[circles, {circleRadius, newCircle}]];
circles = generateCirclesSameRadius[numCircles, cylinderRadius, fixedRadius, maxAttempts];
base3DCircles=Map[{#[[1]], Append[#[[2]], 0]} &, circles];
Graphics3D[Append[Table[HalfBallBearingCreation[base3DCircles[[i]][[1]],base3DCircles[[i]][[2]]],{i,1,Length[base3DCircles]}],{RGBColor[.8,.8,.8],Cylinder[{{0, 0, -cylinderHeight}, {0, 0, 0}}, cylinderRadius]}
], Boxed -> False,ViewPoint->Above]

Which can be called like:


UPDATE: I just wanted to show a physical explanation with an aluminum disk and half-ball bearings on it.

Aluminum disk with half-ball bearings on it.

The same aluminum dish with half-ball bearings on it, but located in different spots.

I am not the greatest at finding the boundary conditions that only allow for elastic deformations and appropriate overlap of deformations.

  • 3
    $\begingroup$ What is your question specifically? $\endgroup$
    – MarcoB
    Commented Feb 4 at 2:27
  • $\begingroup$ @MarcoB What are best practices for exporting geometries made in Mathematica to be used in Ansys, specifically for the situation with half-ball bearings on a cylindrical plate? I am interested in the static structural situation. I don't know if that is relevant. $\endgroup$
    – Teg Louis
    Commented Feb 4 at 2:29
  • 2
    $\begingroup$ Would you be able to import STL files? If not, what is your preferred file type for importing geometries? $\endgroup$
    – Syed
    Commented Feb 4 at 5:05
  • 1
    $\begingroup$ You could use OpenCascadeLink for this. I assume ANSYS can import step files? $\endgroup$
    – user21
    Commented Feb 4 at 20:27
  • 1
    $\begingroup$ community.wolfram.com/groups/-/m/t/1258473 $\endgroup$
    – Syed
    Commented Feb 5 at 8:21

2 Answers 2


I am not sure I can follow all of your thinking in your code, but I'll show a version that you can export to STEP. We are going to use the OpenCascadeLink for this.

We start by generating a cylinder:


cheight = 2;
cradius = 10;
c = Cylinder[{{0, 0, 0}, {0, 0, cheight}}, cradius];

Next, we create some random Ball objects; these should not intersect with the cylinder boundary:

(* generate balls *)
bradius = 1;
numTestBalls = 8;
balls = Ball[#, 
     bradius] & /@ (RandomPoint[
      Cylinder[{{0, 0, 0}, {0, 0, cheight}}, cradius - bradius], 
      numTestBalls] /. {x_, y_, z_} :> {x, y, cheight});

Now, we remove intersecting Ball objects, should there be any:

(* remove intersecting balls *)
subsets = Subsets[balls, {2}];
pos = Position[RegionIntersection /@ subsets, 
   Except[EmptyRegion[3]], {1}, Heads -> False];
nonIntersectingBalls = 
   Flatten[Extract[subsets, pos]]];

You will know what exactly you need here. This is to provide some code to work with. Visualize the scene

Graphics3D[{c, nonIntersectingBalls}]

enter image description here

Now, we create an OpenCascade shape from this:

ocCyliner = OpenCascadeShape[c];
ocBalls = OpenCascadeShape /@ nonIntersectingBalls;
shape = OpenCascadeShapeUnion[Flatten[{ocCyliner, ocBalls}]]

You can export this to STEP:

(* export step file *)
OpenCascadeShapeExport["test.step", shape]

We can inspect a discretzed version of this

bmesh = OpenCascadeShapeSurfaceMeshToBoundaryMesh[shape]


enter image description here

If you want this with multiple material regions (i.e. with different material for the ball objects and the cylinder) then you could use:

ocCyliner = OpenCascadeShape[c];
ocBalls = OpenCascadeShape /@ nonIntersectingBalls;
temp = OpenCascadeShapeFaces /@ Flatten[{ocCyliner, ocBalls}];
shape = OpenCascadeShapeSewing[Flatten[temp]]

You can again export this to STEP and/or look at it's boundary element mesh discretization:

bmesh2 = OpenCascadeShapeSurfaceMeshToBoundaryMesh[shape]

enter image description here

Depends a bit what you want to do.

But WAIT: what are we missing here??? Ah, yes, this is Mathematica.... Let's move on and generate the mesh:

mesh = ToElementMesh[bmesh]

And Let's also do the finite element analysis here. Start with creating the PDE model:

vars = {{u[x, y, z], v[x, y, z], w[x, y, z]}, {x, y, z}};
pars = <|"Material" -> Entity["Element", "Titanium"]|>;
model = {SolidMechanicsPDEComponent[vars, pars] == 
    SolidBoundaryLoadValue[z >= (cheight + bradius/2), vars, 
     pars, <|"Pressure" -> {0, 0, -10^5}|>], 
   SolidFixedCondition[x^2 + y^2 >= (cradius - 1/10)^2, vars, pars]};

Compute the displacements:

displacement = 
  model, {u[x, y, z], v[x, y, z], w[x, y, z]}, {x, y, z} \[Element] 

And visualize them:

VectorDisplacementPlot3D[displacement, {x, y, z} \[Element] 
  MeshRegion[MeshOrderAlteration[mesh, 1]]]

enter image description here

Strain and stress are the some post processing steps. Have a look in the documentation, there are plenty of examples...

I hope this gets you started.

  • $\begingroup$ The half ball bearings will be made out of bismuth. The cylindrical plate material has not been decided, I just know that it is metal. Not that it is important to your answer. Just saying. $\endgroup$
    – Teg Louis
    Commented Feb 5 at 19:00

This is perhaps more of an extended comment than an answer.

The comments mention both STEP and STL interchange formats. I have for many years used STEP format to transfer lens system geometries to mechanical engineers using solids modeling tools like Solidworks. It is common practice. STL is not suitable for many purposes, including optics, because the triangulated mesh does not describe a locally smooth surface with sufficient accuracy. STEP uses NURBS, which can accurately describe smooth surfaces.

I was quite excited to see that in Mathematica Version 14 "Import and Export fully support the STEP file format." I was hoping to use Mathematica to mathematically generate lenses for export to Ansys Zemax OpticStudio.

In testing, Mathematica fell well short of the claim. I cannot get it to work for even rudimentary import/export.

Importing: I used Zemax OpticStudio (a professional lens design code) to export STEP format solids. I can import them into COMSOL Multiphysics (an FEA tool) successfully. When I import the same files to Mathematica I get garbage.

Exporting: I can export a simple native object like a cylinder and import it into COMSOL successfully. But anything truly useful, like a solid described by ImplicitRegion, is not supported. (ImplicitRegion would be a good way to describe a mathematically defined solid.)

I reported this to tech support. (CASE:5107654) The response I received is that these limitations exist probably because STEP support is "experimental." (It is so marked in the documentation.) I was sent a "workaround" but that workaround turned everything into triangulated meshes, like STL.

I would appreciate it if those interested in making use of the STEP format in Mathematica would express their interest to tech support.

  • $\begingroup$ You have seen OpenCascadeLink? $\endgroup$
    – user21
    Commented Feb 4 at 20:13
  • 1
    $\begingroup$ Yes. That is the workaround I was offered by tech support. They provided a notebook that imported my STEP file. It had been exported by OpticStudio, and was 65KB and smooth. Clearly based on NURBS. It came in as a wireframe. It was exported by OpenCascadeLink as a 10MB STEP file. I think not NURBS. It was then imported by OpenCascadeLink. It came in as a tessellated wire frame. Which is unusable for my purposes. When I tried to import it into COMSOL, COMSOL threw an internal error I've never seen before. Mathematica STEP support needs to use NURBS to describe solids. $\endgroup$ Commented Feb 4 at 23:25
  • 1
    $\begingroup$ @DavidKeith, I am the developer of OpenCascadeLink. If you like we can look at this together such that I better understand what it is you want to do. Having said that, when you import a NURBS into M- with OpenCascadeLink it will remain a NURBS. It's just the discretization/visualization that creates the wireframe but the shape itself is a NURBS shape. Now, in the second part you seem to want to export an implicit region. It's correct that this needs to be discretized in order to export it. However, you can express your surface as a BSplineCurve and export that. What is missing is, perhaps,.... $\endgroup$
    – user21
    Commented Feb 5 at 13:18
  • 1
    $\begingroup$ ... a ImplicitRegion to BSplineCurve or BSplineSurface conversion. Is that what you are requesting? $\endgroup$
    – user21
    Commented Feb 5 at 13:19
  • 1
    $\begingroup$ @user21, thank you. I’ll email you. $\endgroup$ Commented Feb 5 at 17:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.