Basics 01#

Nothing is better than a few good examples for quick start. A few super quick examples will show you how to kick start.

Fill a box#

Assuming we would like to fill a box geometry with Cubic lattice, the input JSON shall be like this:

{"Setup":{  "Type" : "Sample",
            "Sample": {"Domain" : [[0.0,4.0],[0.0,4.0],[0.0,4.0]], "Shape": "Box"},
            "Geomfile": "",
            "Rot" : [0.0,0.0,0.0],
            "res":[0.05,0.05,0.05],
            "Padding": 1,
            "onGPU": false,
            "memorylimit": 1073741824000
            },
  "WorkFlow":{
      "1":{"Add_Lattice":{
                "la_name": "BCCubic", "size": [1.0,1.0,1.0], "thk":0.1, "Rot":[0.0, 0.0, 0.0], "Trans":[0.0, 0.0, 0.0],
                "Inv": false, "Fill": true, "Cube_Request": {}
                }},
       "2":{"Export": {"outfile": ".//Test_results/Test_Sample_Strut_Infill.stl"}}
       },
   "PostProcess":{"CombineMeshes": true,
            "RemovePartitionMeshFile": false,
            "RemoveIsolatedParts": false,
            "ExportLazPts": false}
}
The JSON contains three sections,
  • Setup, setup the general computational domain (an 3D block that computes everything) and other essential required computing quantities such as resolution (keywords res). The domain was defined in a block from (0.0,0.0,0.0) to (4.0, 4.0, 4.0) - a solid cube with length of 4 mm.

  • WorkFlow defines the how the resultant lattices built, e.g. connection between two different lattice fields etc.. The single step of lattice operation is defined by numeric index keywords, such as "1", "2" etc.. In the step "1", we added a BCCubic lattice with 1 mm in x, y and z direction, and the radius of the beam was 0.1 mm. In the step "2", the results saved in the file ".//Test_results/Test_Sample_Strut_Infill.stl".

  • PostProcess implements simple post processes on the resultant geometries. In this example, we would only combine the meshes if the automatic partitions were made.

Save the JSON as Sample_box.txt, and type

python ArtisanMain.pt -f .//Test_json//Sample_box.txt

You should see the results stl file at the folder Test_results, and launch the paraview, loads the file, you should be able to see the following.

../_images/Fill_box_results.png

A few output files were also generated. Under the folder which contains the input JSON file, you should find the following:

  • “Sample_box.log”, a log file containing inputs and execution information.

  • “Sample_box.prg”, this is a file regularly updated during the computing procedure, it informs the current progress of percentage of job completion.

In the destination folder, you will see:

  • the results file, e.g. “Test_Sample_Strut_Infill.stl”, and

  • the partitioned mesh file “Test_Sample_Strut_Infill_000000.stl”. In this case, the partition was not triggered and only one mesh file was produced.

Two Lattices#

We certainly can add two lattice together. Artisan provides two simple connections, the hard connection - no transition between two lattice, the linear connection - a linearly changing behavior applied on two lattices.

The JSON setup below builds a cube filled with two distinct lattices, BCCubic and

{"Setup":{  "Type" : "Sample",
            "Sample": {"Domain" : [[0.0,4.0],[0.0,4.0],[0.0,4.0]], "Shape": "Box"},
            "Geomfile": "",
            "Rot" : [0.0,0.0,0.0],
            "res":[0.01,0.01,0.01],
            "Padding": 1,
            "onGPU": false,
            "memorylimit": 1073741824000
            },
 "WorkFlow":{
      "1":{"Add_Lattice":{
                "la_name": "BCCubic", "size": [1.0,1.0,1.0], "thk":0.1, "Rot":[0.0, 0.0, 0.0], "Trans":[0.0, 0.0, 0.0],
                "Inv": false, "Fill": false, "Cube_Request": {}
                }},
      "2" :{"HS_Interpolate" : {
                "la_name": "SchwarzPrimitive",
                "size": [1.0,1.0,1.0],
                "thk": 0.05, "pt":[2.0, 0.0, 0.0], "Rot":[0.0, 0.0, 0.0], "Trans":[0.0, 0.0, 0.0],
                "n_vec":[1.0, 0.0, 0.0], "Fill": true, "Cube_Request": {}
                }},
      "3":{"Export": {"outfile": ".//Test_results/Test_Sample_Strut_Infill_2lattices.stl"}}
       },
 "PostProcess":{"CombineMeshes": true,
            "RemovePartitionMeshFile": false,
            "RemoveIsolatedParts": false,
            "ExportLazPts": false}
}

You will notice it took some time to compute the results as a finer resolution was set, i.e. "res":[0.01,0.01,0.01]. The results should looks more smoother.

../_images/Fill_box_2Lattices.png

The keywords in "2" introduced the heaviside connection between BCCubic and the Schwarz Primitive lattice. The boundary plane is defined through the plane equation that at "pt":[2.0, 0.0, 0.0] with the normal "n_vec":[1.0, 0.0, 0.0]. The normal can be varying according to the required scenarios, it does not has to be align with axis. You could change the normal vector direction to check how it affect the combination of two lattices.

The linear varying relationship normally applied to the same lattice topological and size, but varying thickness across the regions. Let’s try the JSON below.

{"Setup":{  "Type" : "Sample",
            "Sample": {"Domain" : [[0.0,4.0],[0.0,4.0],[0.0,4.0]], "Shape": "Box"},
            "Geomfile": "",
            "Rot" : [0.0,0.0,0.0],
            "res":[0.01,0.01,0.01],
            "Padding": 1,
            "onGPU": false,
            "memorylimit": 1073741824000
            },
 "WorkFlow":{
      "1":{"Add_Lattice":{
                "la_name": "BCCubic", "size": [1.0,1.0,1.0], "thk":0.1, "Rot":[0.0, 0.0, 0.0], "Trans":[0.0, 0.0, 0.0],
                "Inv": false, "Fill": false, "Cube_Request": {}
                }},
      "2":{"Lin_Interpolate" : {
                "la_name": "BCCubic", "size": [1.0,1.0,1.0], "thk": 0.3, "Rot":[0.0, 0.0, 0.0], "Trans":[0.0, 0.0, 0.0],
                "pt_01":[0.0,0.0,0.0], "n_vec_01":[0.0,0.0,1.0],
                "pt_02":[0.0,0.0,4.0], "n_vec_02":[0.0,0.0,-1.0],
                "Inv": false, "Fill": true,
                "Cube_Request": {}
                }},
      "3":{"Export": {"outfile": ".//Test_results/Test_Sample_Strut_Infill_2lattices.stl"}}
       },
 "PostProcess":{"CombineMeshes": true,
            "RemovePartitionMeshFile": false,
            "RemoveIsolatedParts": false,
            "ExportLazPts": false}
}

The varying thickness was therefore generated from z=0.0 plane to z=4.0 plane. There is no restrictions on the plane definition. User may try change the definition and check the results.

../_images/Fill_box_2Lattices_Lin.png

There is a trick that the size can be varying as well, as long as the interface topology is kept. For example, the JSON below demonstrates the varying thickness and varying size of unit lattice.

{"Setup":{  "Type" : "Sample",
            "Sample": {"Domain" : [[0.0,4.0],[0.0,4.0],[0.0,8.0]], "Shape": "Box"},
            "Geomfile": "",
            "Rot" : [0.0,0.0,0.0],
            "res":[0.02,0.02,0.02],
            "Padding": 1,
            "onGPU": false,
            "memorylimit": 1073741824000
            },
 "WorkFlow":{
      "1":{"Add_Lattice":{
                "la_name": "BCCubic",
                "size": [1.0,1.0,1.0], "thk":0.1,
                "Inv": false, "Fill": false, "Rot":[0.0, 0.0, 0.0], "Trans":[0.0, 0.0, 0.0],
                "Cube_Request": {}
                }},
      "2":{"Lin_Interpolate" : {
                "la_name": "BCCubic", "size": [1.0,1.0,2.0], "thk": 0.2, "Rot":[0.0, 0.0, 0.0], "Trans":[0.0, 0.0, 0.0],
                "pt_01":[0.0,0.0,0.0], "n_vec_01":[0.0,0.0,1.0],
                "pt_02":[0.0,0.0,8.0], "n_vec_02":[0.0,0.0,-1.0],
                "Inv": false, "Fill": true,
                "Cube_Request": {}
                }},
      "3":{"Export": {"outfile": ".//Test_results/Test_Sample_Strut_Infill_2lattices.stl"}}
       },
 "PostProcess":{"CombineMeshes": true,
            "RemovePartitionMeshFile": false,
            "RemoveIsolatedParts": false,
            "ExportLazPts": false}
}

The transition cells may not be well preserved, but generally connected and is printable. In the design, user may try to keep the transition region longer, or has less dramatic change, in order to keep the shape integrity of the lattice.

../_images/Fill_box_2Lattices_Lin_VarSize.png

Attractor#

The regional thickness variation can be introduced by adding attractor operation. Attractor creates a spherical shape linearly varying field, and naturally merges this field with surrounding lattice structure. Here is an example JSON.

{"Setup":{  "Type" : "Sample",
            "Sample": {"Domain" : [[0.0,4.0],[0.0,4.0],[0.0,4.0]], "Shape": "Box"},
            "Geomfile": "",
            "Rot" : [0.0,0.0,0.0],
            "res":[0.02,0.02,0.02],
            "Padding": 1,
            "onGPU": false,
            "memorylimit": 1073741824000
            },
 "WorkFlow":{
      "1":{"Add_Lattice":{
                "la_name": "BCCubic",
                "size": [1.0,1.0,1.0], "thk":0.1, "Rot":[0.0, 0.0, 0.0], "Trans":[0.0, 0.0, 0.0],
                "Inv": false, "Fill": false,
                "Cube_Request": {}
                }},
      "2":{
      "Add_Attractor": {
                "la_name": "BCCubic",
                "size": [1.0,1.0,1.0], "thk": 0.5, "Rot":[0.0, 0.0, 0.0], "Trans":[0.0, 0.0, 0.0],
                "pt":[0.0, 0.0, 4.0], "r":3.5,
                "Inv": false, "Fill": true,
                "Cube_Request": {}
                }},
      "3":{"Export": {"outfile": ".//Test_results/Test_Sample_Strut_Infill_2lattices.stl"}}
       },
 "PostProcess":{"CombineMeshes": true,
            "RemovePartitionMeshFile": false,
            "RemoveIsolatedParts": false,
            "ExportLazPts": false}
}

In above, "pt":[0.0, 0.0, 4.0] defined the center and "r":3.5 defined the radius of the sphere. A corner of the cube has chunky material which caused by very thick beam definition, and the thickness was gradually changed and merged to the surrounding.

../_images/Fill_box_2Lattices_Attractor.png

Rotation and Translation#

To fit a design purpose, users can apply rotation and translation on the lattice unit orientation. It is important to note that only periodic lattices can be rotated and translated with respect to the global origin and axes. Currently, the following keywords support these two operations: Add_Lattice, Subtract_Lattice, HS_Interpolate, Lin_Interpolate, Add_Attractor, and OP_FieldMerge.

In the example JSON below, the lattice is rotated with respect to the x-axis by \(\frac{\pi}{4}\) radians.

{"Setup":{      "Type" : "Sample",
            "Sample": {"Domain" : [[0.0,4.0],[0.0,4.0],[0.0,4.0]], "Shape": "Box"},
            "Geomfile": "",
            "Rot" : [0.0,0.0,0.0],
            "res":[0.025,0.025,0.025],
            "Padding": 1,
            "onGPU": false,
            "memorylimit": 1073741824000
            },
"WorkFlow":{
      "1":{"Add_Lattice":{
                "la_name": "Cubic", "size": [1.0,1.0,1.0], "thk":0.05,
                "Rot":[0.7853981633974483, 0.0, 0.0], "Trans":[0.0,0.0,0.0], "Inv": false, "Fill": true,
                "Cube_Request": {}
                }},
      "2":{"Export": {"outfile": ".//Test_results/Test_Sample_Strut_Infill.stl"}}
       },
"PostProcess":{"CombineMeshes": true,
            "RemovePartitionMeshFile": false,
            "RemoveIsolatedParts": false,
            "ExportLazPts": false}
}

The parameter Rot in the keywords Add_Lattice becomes [0.7853981633974483, 0.0, 0.0]. The first element represents the rotation around x-axis in radius unit, and the second and third element defines the y- and z-axis rotation. Same setup applies to the Trans that defines the translation movement. It has to note that, Artisan rotates the lattice before translating it.

../_images/Rotation_Cubic.png

User may define the parameter Trans to get after rotation translation, for instance, move the structure by 0.5 in x direction "Trans":[0.5, 0.0, 0.0].

../_images/Translation_Cubic.png