Table of Contents
Commit of the latest developments I made for additive manufacturing. In commit 20/09/2018, the “PointAdditiveManager” class only handled the activation of volume elements based on the position of a single point, the boundary conditions were not considered. In this commit, the following features have been added:
- Activation/deactivation of the boundary conditions.
- Activation/deactivation of the heat flux modeling the laser, including a possibility to only activate the flux elements along a certain direction.
- Allowing the use of multiple “point activators”, a PointActivator class has also been created, this class stores a point and remembers which element the point activated last.
- Generalization to 2D simulations.
Use of the additive manager
Example of use of the additive manager:
AM=PointAdditiveManager() #Adds the activator points: AM.addActivator(Pointset(1)) AM.addActivator(Pointset(2)) AM.addActivator(Pointset(3)) #sets the FieldApplicator linked to the volume we want to activate AM.setTargetField(FieldApplicator(1)) #Adds the related boundary conditions AM.addBoundaryCondition(LoadingInteraction(1)) AM.addBoundaryCondition(LoadingInteraction(2)) #Adds the heat flux (will be activated only while the point is inside the related element) #If no direction for the flux is specified: AM.setHeatFlux(LoadingInteraction(3)) #If a direction for the flux is specified(only the elements that initially have a normal in a certain direction will be activated): fluxNormal=Vect3(0.0,1.0,0.0) AM.setHeatFlux(LoadingInteraction(3),fluxNormal) #Link the created Additivemanager to Metafor: metafor.setAdditiveManager(AM)
- To create boundary condition elements on each volume element's surfaces inside a given geometrical volume one can push the volume in the LoadingInteraction instead of a surface, e.g.:
prpConvection = ElementProperties(TmConvection3DElement) prpConvection.put(CONV_COEF,ConvectionCoef) prpConvection.put(TEMP_FLUIDE,TFluid) Convection=LoadingInteraction(1) Convection.push(volumeset(1)) Convection.addProperty(prpConvection ) interactionset.add(Convection)
- For now, only one targetField can be set, this will change in the future.
Algorithm for the activation
The algorithm for the activation of elements(AdditiveManager::enableElements()) is called at every Metafor::endstep() and is as followed:
- For each PointActivator, we find the closest point from the FieldApplicator (those points are stored in PointAdditivemanager.meshPointStdSet).
- We check if the point activator is inside a volume connected to this closestPoint, if it is inside a different volume than on the previous timestep, we save this new volume in PointActivator.lastActivated, otherwise we do nothing.
- We repeat for each PointActivator and if at least one modification has been made we set the flag “hasChanged” to true.
- If hasChanged is true, we deactivate all heat flux elements (we will reactivate only the flux elements related to the current activation).
- For each PointActivator, we enable the elements corresponding to the “lastActivated” Volume.
- For each volume we get the corresponding sides.
- For each side we get the corresponding boundary condition elements, if the side is a boundary (i.e. connected to 1 and only 1 active volume element) we enable all elements. If the side is not a boundary (connected to 0 elements or within a structure) we dis-enable all elements. Before activation the elements are also compared to a “doNotActivate” elementHashSet filled with elements not to activate (for now only used if a specific orientation has been specified for the heat flux, in the initialisation of additiveManager the elementHashSet is then filled with all the elements not in the right direction).
If a modification was done in the algorithm (flag hasChanged==true), we set metafor.RebuildConnexionFlagRupt to true. This will trigger a RebuildConnexion and a CheckFreeNodes at the beginning of the next iteration as for the rupture.
- I plan on moving the call to the algorithm from Metafor::endStep() to TimeIntegration::stepInitialisation() in the future, now the simulation is constantly 1 timeStep behind.
Those modifications allowed me to recreate the results from Chiumenti (Numerical simulation and experimental calibration of Additive Manufacturing by blown powder technology. Part I: thermal analysis, Rapid Prototyping Journal 23 (2017) 448–463.) That I had already recreated using the “stageManager” method (cf. commit 20/09/2018).
Here are the results (temperature at 3 thermocouples named “CH1”, “CH2” and “CH3”):
Temperature at CH1 over time (left) and zoom (right):
Temperature at CH2 over time (left) and zoom (right):
Temperature at CH3 over time (left) and zoom (right):
As one can see, the results are good. The creation of a test case is easier using Additive Manager. The preprocessing is a lot faster (>15mins for big simulations using Stage manager vs <1min for Additive Manager)). The computation time is also better in parallel for big computations. An example of computation times on fabulous is given here after where Nx8, Nx16, Nx32 are simulations with respectively 8, 16 and 32 elements in the x direction of the deposited piece.
One can see that for big simulations some computation time can be saved because the activation with the new additive manager is better in parallel. Note: The simulation could be made faster by improving the method to allow bigger minimum time steps, for now the minimum time step has to be fixed to (deposit Speed)/(smallest element size) otherwise some elements might be “skipped” during the activation.
I also tried to recreate 2D results from the PhD thesis of N.Hashemi (Study of High Speed Steel deposits produced by Laser cladding,2017, ULiège) with moderate success (I still need to investigate the differences):
A first try of reproduction of thermomechanical results from the literature has also been done (the test is from Lu et al. “Finite element analysis and experimental validation of the thermomechanical behavior in laser solid forming of Ti-6Al-4V”, Additive Manufacturing, 21 (2018), 30-40.)
Comparison of distorsion at a point:
Residual stress and displacement (Metafor):
Residual stress (Lu et al.):
The difference in results is significant and highlights the fact that although TM simulations seem to work an annealing temperature needs to be implemented in Metafor to correctly model AM processes.This implemetantion will be the next step.
I added new python functions in meshedGeometry2D.py and meshedGeometry3D.py that generates connected quadragles/hexaedres and use a XYZ numerotation for the points/edges/sides. Example:
More details in:
Added [a] / deleted [d ] / modified [m] files
[a]mtElements/PointActivator.cpp [a]mtElements/PointActivator.h [m]mtElements/_src/mtElements.i [m]mtElements/PointAdditiveManager.cpp [m]mtElements/PointAdditiveManager.h [m]mtFEM/_src/mtFEM.i [m]mtFEM/AdditiveManager.cpp [m]mtFEM/AdditiveManager.h [m]mtFEM/algos/TimeIntegration.cpp [m]mtFEM/Metafor.cpp
with Stage Manager: [d]additiveM/withStageManager/battery/Chiumenti1.py [d]additiveM/withStageManager/tests/Chiumenti1.py [d]additiveM/withStageManager/tests/Chiumenti1Coarse.py [d]additiveM/withStageManager/tests/Chiumenti1MWE.py [m]additiveM/withStageManager/tools/activationWithStages.py [m]additiveM/withStageManager/tools/chiumenti.py [m]additiveM/withStageManager/tools/chiumentiParallel.py [a]additiveM/withStageManager/battery/ChiumentiMWE.py [a]additiveM/withStageManager/battery/ChiumentiMWELobatto.py [a]additiveM/withStageManager/battery/testSimpleLineWithStages.py [a]additiveM/withStageManager/tests/Chiumenti/ChiumentiCoarse.py [a]additiveM/withStageManager/tests/Chiumenti/ChiumentiNx16.py [a]additiveM/withStageManager/tests/Chiumenti/ChiumentiNx16Lobatto.py [a]additiveM/withStageManager/tests/Chiumenti/ChiumentiNx32.py [a]additiveM/withStageManager/tests/Chiumenti/ChiumentiNx8.py With Additive Manager: [d]additiveM/withAdditiveManager/tests/activationWithAdditiveManager.py [d]additiveM/withAdditiveManager/tests/testAdditiveManagerDiag.py [d]additiveM/withAdditiveManager/tests/testAdditiveManagerSin.py [m]additiveM/withAdditiveManager/battery/activationWithAdditiveManager.py [m]additiveM/withAdditiveManager/battery/testAdditiveManagerSin.py [a]additiveM/withAdditiveManager/battery/activate1LineWithBC.py [a]additiveM/withAdditiveManager/battery/ChiumentiMWE.py [a]additiveM/withAdditiveManager/battery/ChiumentiMWELobatto.py [a]additiveM/withAdditiveManager/battery/HashemiMWE.py [a]additiveM/withAdditiveManager/battery/TmChiumentiMWE.py [a]additiveM/withAdditiveManager/tests/Chiumenti/chiumentiGauss8.py [a]additiveM/withAdditiveManager/tests/Chiumenti/chiumentiLobattoNx16.py [a]additiveM/withAdditiveManager/tests/Chiumenti/chiumentiLobattoNx32.py [a]additiveM/withAdditiveManager/tests/Chiumenti/chiumentiLobattoNx8.py [a]additiveM/withAdditiveManager/tests/Chiumenti/chiumentiLobattoNx8Nip4.py [a]additiveM/withAdditiveManager/tests/Chiumenti/chiumentiNx16.py [a]additiveM/withAdditiveManager/tests/Chiumenti/chiumentiNx32.py [a]additiveM/withAdditiveManager/tests/Chiumenti/chiumentiNx8.py [a]additiveM/withAdditiveManager/tests/Chiumenti/chiumentiNx8Nip4.py [a]additiveM/withAdditiveManager/tests/HashemiAndJardin/hashemi.py [a]additiveM/withAdditiveManager/tests/HashemiAndJardin/hashemiFixPlate.py [a]additiveM/withAdditiveManager/tests/HashemiAndJardin/jardin.py [a]additiveM/withAdditiveManager/tests/TmChiumenti/TmChiumentiNx16.py [a]additiveM/withAdditiveManager/tests/TmChiumenti/TmChiumentiNx32.py [a]additiveM/withAdditiveManager/tests/TmChiumenti/TmChiumentiNx64.py [a]additiveM/withAdditiveManager/tests/TmChiumenti/TmChiumentiNx8.py [a]additiveM/withAdditiveManager/tests/TmChiumenti/TmChiumentiNx80.py [a]additiveM/withAdditiveManager/tools/chiumentiAM.py [a]additiveM/withAdditiveManager/tools/chiumentiAmOldParam.py [a]additiveM/withAdditiveManager/tools/hashemiAM.py [a]additiveM/withAdditiveManager/tools/Matlab [a]additiveM/withAdditiveManager/tools/TmChiumentiAM.py
— Cédric Laruelle 2019/05/07