Tutorials
This section proposes the following tutorials
Topology optimization of a cantilever beam using structured level sets
Topology optimization of a cantilever beam using unstructured conformal level sets
Topology optimization of a 2D cantilever beam using conformal level sets
The configuration files created using these tutorials are also available in the module OpenPisco.Demos()
of the OpenPisco Python library 1 .
Topology optimization of a cantilever beam using structured level sets
The goal of this tutorial is to run a topology optimization of a cantilever beam using structured level sets.
Test case
Consider the following specifications
domain of size \(12\) m \(x 4\) m \(x 3\) m
elastic material with Young modulus equal to \(1\) Pa and Poisson ratio equal to \(0.3\)
beam clamped on the plane \(x = 0\) m and submitted to a vertical load g = \((0, 0, -1000)\) N on the point \((12, 0, 1.5)\)
minimization of the elastic compliance under a volume constraint
Data setting : header
At first, we start by editing a Liu_Tovar_2014_Cantilever_T4_C1.xml file.
The data file starts with the following header
<data dim="3">
Data setting : implicit zones
Define implicit zones
<Zones>
<Gyroid id="100" scale="0.031831" desc="Init" />
<Symmetric id="101" z="100" center="12 0 1.5"/>
<Intersection id="1" z="10 101"/>
<Plane id="2" point="0.1 0. 0." normal="1. 0. 0." desc="Block"/>
<Cylinder id="3" center1="12 0 1.47" center2="12 0 1.53" radius="0.03" desc="Force"/>
<Union id="4" z="2 3"/>
<Union id="5" z="1 4 "/>
</Zones>
Data setting : grids
Define the background mesh which is a uniform grid
<Grids>
<Grid id="1" n="61 41 31" origin="0. 0. 0." length="12 4 3"/>
</Grids>
Data setting : levelsets
Define the level set together with a set of options. By default the level set is structured.
<LevelSets>
<LevelSet id="1" support="1"/>
</LevelSets>
Data setting : physical problems
Define the physical problem, which is a linear elastic static FEA problem.
We define one dirichlet condition and one neumann condition.
By default we use linear elements.
The option eVoid=”0.001” means that the density of the Ersatz material equals 0.001.
<PhysicalProblems>
<StructuredFEA id="1" grid="1" type="disp" eVoid="0.001" narrow=".2">
<Dirichlet zone="2" dofs="0 1 2" val="0.0"/>
<Neumann zone="3" dofs="1" val="-1000"/>
</StructuredFEA>
</PhysicalProblems>
Data setting : outputs
Define the desired output
<Outputs>
<Output id="2" name="Liu_Tovar_2014_Cantilever_T4_C1.xdmf"/>
<Output id="3" name="Liu_Tovar_2014_Cantilever_T4_C1.csv" nTag="NT3" />
<Output id="1" name="PROXY" outputs="2 3"/>
</Outputs>
Data setting : optimization problems
Then, we define the optimization problem by entering the objective, the constraints, the initial levelset, the implicit zones, the output and a set of options.
Note that we have to define an upper bound value for the constraint.
Note that, since the objective is a physical criterion, we precise which physical problem should be used with the keyword useProblem=”1”.
<OptimProblems>
<OptimProblem type="TopoGeneric" id="1"
OnZone="4" Dirichlet="2" Neumann="3"
useLevelset="1"
e2="0.001"
output="1"
>
<Objective type="Compliance" name="Compliance" useProblem="1" />
<Constraint type="Volume" name="Volume" upperBound="21.6" desc="0.15*voltotal= 0.15*12*4*3=21.6"/>
</OptimProblem>
</OptimProblems>
Data setting : optimization algorithms
Then, we define the optimization algorithm which is linked to the optimization problem
<TopologicalOptimizations>
<OptimAlgoNullSpace id="1"
useOptimProblem="1"/>
numberOfDesignStepsMax="100"
</TopologicalOptimizations>
Actions setting
Here we declare actions which must be runned. At first, we create a nodal tag labeled “NT3” from the implicit zone “3” of the level set “1”
<Actions>
<Action type="CreateTagsFromZones" ls="1" nodalTags="3" />
Then, the level set “1” is initialized with the implicit zone “5” and redistanciated to generate a signed distance function
<Action type="InitLevelset" ls="1" zone="5"/>
<Action type="UpdateDistance" ls="1" />
Then, we run the topology optimization
<Action type="RunTopoOp" TopoOp="1"/>
Eventually the optimal shape is exported in stl format
<Action type="SaveShapeToFile" ls="1" filename="Liu_Tovar_2014_Cantilever_T4_C1.stl"/>
</Actions>
</data>
Run
To run the script using the command line application execute in a terminal
OpenPiscoCL Liu_Tovar_2014_Cantilever_T4_C1.xml
To run the script using the GUI application execute in a terminal
OpenPisco Liu_Tovar_2014_Cantilever_T4_C1.xml
Output
After running the tutorial script the following output files have been created in the working directory
Liu_Tovar_2014_Cantilever_T4_C1.xml.log : run summary
Liu_Tovar_2014_Cantilever_T4_C1.stl : optimal shape in stl format
Liu_Tovar_2014_Cantilever_T4_C1.xdmf : (heavy) file containing the mesh and fields at each iteration in xdmf format
Liu_Tovar_2014_Cantilever_T4_C1.csv : convergence history in csv format
Topology optimization of a cantilever beam using unstructured conformal level sets
The goal of this tutorial is to run a topology optimization of a cantilever beam using unstructured conformal level sets.
Test case
Consider the following specifications
domain of size \(2\) m \(x 0.5\) m \(x 1\) m
elastic material with Young modulus equal to \(210.e9\) Pa and Poisson ratio equal to \(0.3\)
beam clamped on the plane \(x = 0\) m and submitted to a vertical load g = \((0, 0, -10000)\) N on the point \((2, 0.25, 0.5)\)
minimization of the volume under a compliance constraint
Data setting : header
At first, we start by editing a Cantilever.xml file.
The data file starts with the following header
<data dim="3">
Data setting : implicit zones
Define implicit zones
<Zones>
<Plane id="1" point="0.0001 0.25 0.5" normal="1. 0. 0." desc="x0 plane"/>
<Plane id="2" point="0.05 0.25 0.5" normal="1. 0. 0." desc="dirichlet"/>
<Plane id="3" point="1. 0.24999 0.5" normal="0. -1. 0." desc="symetry plane"/>
<Sphere id="4" center="2. 0.25 0.5" radius="0.0009" desc="nodal force"/>
<Cylinder id="5" center1="1.9999 0.25 0.5" center2="2.1 0.25 0.5" radius="0.01" desc="force"/>
<Cylinder id="6" center1="-0.1 0.25 0.5" center2="2.1 0.25 0.5" radius="0.249"/>
<Union id="7" z="2 4 6" desc="initialization"/>
<Union id="8" z="2 5" desc="onzone"/>
</Zones>
Data setting : grids
Define the background mesh which is a uniform grid
<Grids>
<Grid id="1" n="41 41 41" origin="0. 0. 0." length="2.0 0.25 1.0" ofTetras ="True"/>
</Grids>
Data setting : levelsets
Define the level set together with a set of options. The option conform=”True” means that the level set is conformal. When the body-fitted option is activated a set of meshing options are defined to drive the remeshing process.
<LevelSets>
<LevelSet id="1" support="1" conform="True" gradientMethod="gradPhi">
<MesherInfo hmax=".5" hmin="0.01" iso="0.0" rmc="True"
nr="True" computeDistanceWith="meshdist"/>
</LevelSet>
</LevelSets>
Data setting : physical problems
Define the physical problem, which is a linear elastic static problem.
We define material properties, two dirichlet conditions -clamped part and symetry plane- and one neumann condition.
By default we use linear elements.
<PhysicalProblems>
<GeneralAster type="static_elastic" id="1" >
<Material E="210.e9" Nu="0.3" />
<Dirichlet eTag="eTag1" dofs="0 1 2" value="0.0"/>
<Dirichlet eTag="eTag3" dofs="1" value="0.0"/>
<Force nTag="nTag4" value="0. 0. -10000" />
</GeneralAster>
</PhysicalProblems>
Data setting : outputs
Define the desired output
<Outputs>
<Output id="2" name="Cantilever.xdmf"/>
<Output id="3" name="Cantilever.csv" nTag="nTag4" />
<Output id="1" name="PROXY" outputs="2 3"/>
</Outputs>
Data setting : optimization problems
Then, we define the optimization problem by entering the objective, the constraints, the initial levelset, the implicit zones, the output and a set of options.
Note that we have to define an upper bound value for the constraint.
Note that, since the objective is a physical criterion, we precise which physical problem should be used with the keyword useProblem=”1”.
<OptimProblems>
<OptimProblem type="TopoGeneric" id="1"
OnZone="8" Dirichlet="2" Neumann="5"
useLevelset="1"
printMeshQualityInfo = "True"
output="3"
outputEveryLevelsetUpdate = "False">
<Objective type="Volume" name="Volume"/>
<Constraint type="Compliance" name="Compliance" UpperBound="2.5*4.69434000e-01" useProblem="1" />
</OptimProblem>
</OptimProblems>
Data setting : optimization algorithms
Then, we define the optimization algorithm which is linked to the optimization problem
<TopologicalOptimizations>
<OptimAlgoNullSpace id="1"
useOptimProblem="1"/>
</TopologicalOptimizations>
Actions setting
Here we declare actions which must be runned. At first the level set “1” is initialized with the implicit zone “7”
<Actions>
<Action type="InitLevelset" ls="1" zone="7"/>
Then, we add the bounding box edges and the skin to the initial grid. Moreover, we create tags on elements of dimension 2 starting from the implicit zones “1”,”3”. Tags “eTag1”,”eTag3” are created.
<Action type="AddEdges" ls="1" ar="45" />
<Action type="AddSkin" ls="1"/>
<Action type="CreateTagsFromZones" ls="1" elementTags="1 3" dim="2" elemenprefix="eTag"/>
We create a nodal tag “nTag4” from implicit zone “4” for the nodal force and we set it as required to preserve it during the remeshing
<Action type="CreateTagsFromZones" ls="1" nodalTags="4" nodalprefix="nTag"/>
<Action type= "SetAsRequired" ls="1" nTags="nTag4" />
We perform a remeshing to generate a conformal mesh
<Action type="Remesh" ls="1" hmax=".5" hmin="0.01" iso="0.0" rmc="True"
nr="True" computeDistanceWith="meshdist" />
Then, we run the topology optimization
<Action type="RunTopoOp" TopoOp="1"/>
Eventually the optimal shape is exported in stl format
<Action type="SaveShapeToFile" ls="1" filename="Cantilever.stl"/>
</Actions>
</data>
Run
To run the script using the command line application execute in a terminal
OpenPiscoCL Cantilever.xml
To run the script using the GUI application execute in a terminal
OpenPisco Cantilever.xml
Output
After running the tutorial script the following output files have been created in the working directory
Cantilever.xml.log : run summary
Cantilever.stl : optimal shape in stl format
Cantilever.xdmf : (heavy) file containing the mesh and fields at each iteration in xdmf format
Cantilever.csv : convergence history in csv format
Topology optimization of a 2D cantilever beam using conformal level sets
The goal of this tutorial is to run a topology optimization of a bidimensional cantilever beam using unstructured conformal level sets.
Note
For running this tutorial Code_Aster 2 needs to be installed and available from the command line.
Test case
Consider the following specifications
domain of size \(2\) m \(x 1\) m
elastic material with Young modulus equal to \(210.e9\) Pa and Poisson ratio equal to \(0.3\)
beam clamped on the plane \(x = 0\) m and submitted to a vertical load g = \((0, -10000)\) N on the point \((2, 0.5)\)
minimization of the volume under a compliance constraint
Data setting : header
We start by editing a Cantilever2D.xml file.
The data file starts with the following header
<data dim="2" >
Data setting : implicit zones
Define implicit zones
<Zones>
<Plane id="1" point="0.0001 0.25 0.5" normal="1. 0. 0." desc="x0 plane "/>
<Plane id="2" point="0.05 0.25 0.5" normal="1. 0. 0." desc="dirichlet"/>
<Sphere id="4" center="2. 0.5 0.0" radius="0.0009" desc="nodal force"/>
<Cylinder id="5" center1="1.9999 0.5 0." center2="2.1 0.5 0." radius="0.01" desc="force"/>
<Holes id="6" n="6 4 2" r="0.2" boundingMin="0. 0. 0." boundingMax="2.0 1.0 1.0" type="Original" desc="Holes"/>
<Union id="7" z="2 4 6" desc="initialization"/>
<Union id="8" z="2 5" desc="onzone" />
</Zones>
Data setting : grids
Define the background mesh which is a uniform grid
<Grids>
<Grid id="1" n="61 41" origin="0. 0." length="2.0 1.0" ofSimplex="True"/>
</Grids>
Data setting : levelsets
Define the level set together with a set of options. The option conform=”True” means that the level set is conformal. A set of meshing options are defined to drive the remeshing process.
<LevelSets>
<LevelSet id="1" support="1" conform="True" gradientMethod="gradPhi">
<MesherInfo hmax=".03" hmin="0.008" iso="0.0" rmc="True"
nr="True" computeDistanceWith="meshdist"/>
</LevelSet>
</LevelSets>
Data setting : physical problems
Define the physical problem, which is a linear elastic static problem.
We define material properties, one dirichlet condition and one neumann condition.
By default we use linear elements.
<PhysicalProblems>
<GeneralAster type="static_elastic" id="1" >
<Material E="210.e9" Nu="0.3" />
<Dirichlet eTag="eTag1" dofs="0 1" value="0.0"/>
<Force nTag="nTag4" value="0. -1000" />
</GeneralAster>
</PhysicalProblems>
Data setting : outputs
Define the desired output
<Outputs>
<Output id="1" name="Cantilever2DHistory.xdmf" inTempDirectory="True" />
<Output id="2" name="Cantilever2DHistory.csv" inTempDirectory="True" />
<Output id="3" name="PROXY" outputs="1 2" />
</Outputs>
Data setting : optimization problems
Then, we define the optimization problem by entering the objective, the constraints, the initial levelset, the implicit zones, the output and a set of options.
Note that we have to define an upper bound value for the constraint.
Note that, since the constraint is a physical criterion, we precise which physical problem should be used with the keyword useProblem=”1”.
<OptimProblems>
<OptimProblem type="TopoGeneric" id="1"
OnZone="8" Dirichlet="2" Neumann="5"
useLevelset="1"
printMeshQualityInfo = "True"
output="3"
outputEveryLevelsetUpdate = "False">
<Objective type="Volume" name="Volume"/>
<Constraint type="Compliance" name="Compliance" UpperBound="2*1.90489800e-04" useProblem="1" />
</OptimProblem>
</OptimProblems>
Data setting : optimization algorithms
Then, we define the optimization algorithm which is linked to the optimization problem
<TopologicalOptimizations>
<OptimAlgoNullSpace id="1"
useOptimProblem="1"/>
</TopologicalOptimizations>
Actions setting
Here we declare actions which must be runned. At first the level set “1” is initialized with the implicit zone “7”
<Actions>
<Action type="InitLevelset" ls="1" zone="7"/>
We create a nodal tag “nTag4” from implicit zone “4” for the nodal force and we set it as required to preserve it during the remeshing
<Action type="CreateTagsFromZones" ls="1" nodalTags="4" nodalprefix="nTag"/>
<Action type= "SetAsRequired" ls="1" nTags="nTag4" />
We perform a remeshing to generate a conformal mesh
<Action type="Remesh" ls="1" hmax=".03" hmin="0.008" iso="0.0" rmc="True"
nr="False" computeDistanceWith="meshdist" />
We create an element tag to support the Dirichlet boundary condition
<Action type="CreateTagsFromZones" ls="1" elementTags="1" dim="1" elemenprefix="eTag"/>
Then, we run the topology optimization
<Action type="RunTopoOp" TopoOp="1"/>
Eventually mesh quality indicators are printed
<Action type="LsQualityInfo" ls="1" />
</Actions>
</data>
Run
To run the script using the command line application execute in a terminal
OpenPiscoCL Cantilever2D.xml
To run the script using the GUI application execute in a terminal
OpenPisco Cantilever2D.xml
Output
After running the tutorial script the following output files have been created in the working directory
Cantilever2D.xml.log : run summary
Cantilever2DHistory.xdmf : (heavy) file containing the mesh and fields at each iteration in xdmf format
Cantilever2DHistory.csv : convergence history in csv format
Conformal remeshing using implicit geometries and mmg3d
The goal of this tutorial is to create body-fitted meshes using implicit geometries and the remeshing software mmg3d. In order to do so, we start by editing a HoneyComb.xml file
<data dim="3">
We define the honeycomb implicit geometry
<Zones>
<Honeycomb id="1" lx="0.3" w="0.05" desc="honeycomb implicit zone "/>
</Zones>
We define the initial grid and the conformal level set
<Grids>
<Grid id="1" n="201 51 101" origin="0. 0. 0." length="2.0 0.5 1.0" ofTetras ="True"/>
</Grids>
<LevelSets>
<LevelSet id="1" support="1" conform="True"></LevelSet>
</LevelSets>
We define the actions to run
<Actions>
<Action type="InitLevelset" ls="1" zone="1"/>
<Action type="AddEdges" ls="1" ar="45" />
<Action type="Remesh" ls="1" hmax=".4" hmin="0.004" hausd="0.004" iso="0.0" rmc="True" nr="True"/>
<Action type="WriteToFile" ls="1" filename="{INPUTFILE}.xdmf" />
</Actions>
We close the xml file
</data>
Run
To run the script using the command line application execute in a terminal
OpenPiscoCL HoneyComb.xml
To run the script using the GUI application execute in a terminal
OpenPisco HoneyComb.xml
Output
After running the following output files have been created in the working directory
HoneyComb.xml.log : run summary
HoneyComb.xdmf : file containing the body-fitted mesh created
Overhanged surfaces detection for additive manufacturing
The goal of this tutorial is to detect and export overhanged surfaces for additive manufacturing. At first we start by editing an OverHangDetection.xml file, reading the input mesh model and instanciating a level set
<data dim="3" debug="False" >
<Grids>
<Mesh id="1" filename="{PISCO_TEST_DATA}TubeMesh.msh" />
</Grids>
<LevelSets>
<LevelSet id="1" support="1" conform="True">
</LevelSet>
</LevelSets>
We detect the overhanged surfaces for an input angle of 45 degrees in the direction \((0, 0, 1)\). The keyword surfaceTags is optional and allows to run the overhang detection on specific mesh tags. Read the docstring of OpenPisco.Actions.AdditiveManufacturingActions.OverHangDetectionAction
for the complete list of options. The routine computes the triangle normals to check if the overhang condition is fulfilled. Doing so a tag named”overhangSurface” is filled with the overhanged triangles and added to the mesh tags.
<Actions>
<Action type="OverHangDetection" ls="1" angleDetection="45" surfaceTags="OutsideTube InsideTube" direction="0 0 1"/>
Eventually we export the overhanged surfaces and close the input file
<Action type="WriteSurfaceToStl" eTag="overhangSurface" ls="1"/>
</Actions>
</data>