adamantine
is a thermomechanical code for additive manufacturing. It is based
on deal.II,
ArborX,
Trilinos, and Kokkos.
adamantine
can simulate the thermomechanical evolution an object undergoes
during the manufacturing process. It can handle materials in three distinct
phases (solid, liquid, and powder) to accurately reflect the physical state
during manufacturing. Experimental data can be used to improve the simulation
through the use of Ensemble Kalman
filter.
Installing adamantine
requires:
- MPI
- A compiler that support C++17
- CMake: 3.15 or later
- Boost: 1.70.0 or later
- ArborX: 1.4.1 or later
- Trilinos: 14.4.0 or later. If you want to adamantine to read an Exodus mesh, you need to enable SEACAS support.
- deal.II: 9.5 or later. You need to compile deal.II with MPI, p4est, and ArborX support.
- Caliper: 2.10 or later. Optional dependency to profile
adamantine
.
An example on how to install all the dependencies can be found in
ci/Dockerfile
.
To configure adamantine
use:
cmake \
-D CMAKE_BUILD_TYPE=Release \
-D DEAL_II_DIR=/path/to/dealii \
-DBOOST_DIR=/path/to/boost \
/path/to/source/dir
Then simply use make
. This will compile adamantine
and create an executable
in a newly created bin
subdirectory. You will find in this subdirectory the
executable and an example of input files.
The list of configuration options is:
- ADAMANTINE_ENABLE_ADIAK=ON/OFF
- ADAMANTINE_ENABLE_CALIPER=ON/OFF
- ADAMANTINE_ENABLE_COVERAGE=ON/OFF
- ADAMANTINE_ENABLE_TESTS=ON/OFF
- BOOST_DIR=/path/to/boost
- CMAKE_BUILD_TYPE=Debug/Release
- CALIPER_DIR=/path/to/caliper (optional)
- DEAL_II_DIR=/path/to/dealii
The Docker image containing the latest version of adamantine
can be pulled
using
docker pull rombur/adamantine:latest
The 1.0 release version is available using
docker pull rombur/adamantine:1.0
To start an interactive container use
docker run --rm -it rombur/adamantine:1.0 bash
You will find adamantine
in /home/adamantine/bin
. You can mount a folder
into a Docker image using
docker run --rm -it -v /path/to/compute/folder:/path/to/image/folder rombur/adamantine:1.0 bash
The instructions to install adamantine
using NIX can be found here.
After compiling adamantine
, you can run a simulation using
mpirun -n 2 ./adamantine --input-file=input.info
Note that the name of the input file is totally arbitrary, my_input_file
is as
valid as input.info
.
There is a known bug when using multithreading. To deactivate multithreading use
export DEAL_II_NUM_THREADS=1
If you use our Docker image, the variable is already set.
adamantine
supports Boost INFO format and json. The input file is assumed to use
the INFO format unless the file extension is .json
. An example of an input
file can be found
here.
The following options are available:
- boundary (required):
- type: type of boundary: adiabatic, radiative, or convective. Multiple types can be chosen simultaneously by separating them by comma (required)
- physics (required):
- thermal: thermal simulation: true or false (required)
- mechanical: mechanical simulation; if both thermal and mechanical parameters are true, solve a coupled thermo-mechanics problem : true or false (required)
- discretization (required):
- thermal:
- fe_degree: degree of the finite element used (required if physics.thermal is true)
- quadrature: quadrature used: gauss or lobatto (default value: gauss)
- mechanical:
- fe_degree: degree of the finite element used (required if physics.mechanical is true)
- thermal:
- geometry (required):
- dim: the dimension of the problem (2 or 3, required)
- material_height: below this height the domain contains material. Above this height the domain is empty. The height is in meters (default value: 1e9)
- use_powder: the additive manufacturing process use powder: true or false (default value: false)
- if use_powder is true:
- powder_layer: thickness of the initial layer of powder in meters (required)
- material_deposition: material is deposed during the simulation: true or false (default value: false)
- if material_deposition is true:
- material_deposition_method: file, scan_paths
- if material_deposition_method is file:
- material_deposition_file: material deposition filename
- if material_deposition_method is scan_paths:
- deposition_length: length of material deposition boxes along the scan direction in meters
- deposition_width: width of material deposition boxes in meters (in the plane of the material, normal to the scan direction, 3D only)
- deposition_height: height of material deposition boxes in meters (out of the plane of the material)
- deposition_lead_time: amount of time before the scan path reaches a point that the material is added in seconds
- deposition_time: using this option, the material is added in bigger lumps in seconds (optional)
- import_mesh: true or false (required)
- if import_mesh is true:
- mesh_file: The filename for the mesh file (required)
- mesh_format: abaqus, assimp, unv, ucd, dbmesh, gmsh, tecplot, xda, vtk, vtu, exodus, or default, i.e., use the file suffix to try to determine the mesh format (required)
- mesh_scale_factor: Apply a uniform scaling factor to the mesh (e.g. if the mesh is defined in mm or inches instead of m), (default value: 1) [removed in 1.1, use units.mesh instead]
- reset_material_id: Clear the material IDs defined in the mesh and set them all to zero so all material properties are given by the
material\_0
input block: true or false (default value: false)
- if import_mesh is false:
- length: the length of the domain in meters (required)
- height: the height of the domain in meters (required)
- width: the width of the domain in meters (only in 3D)
- length_origin: the reference location in the length direction (default value: 0)
- height_origin: the reference location in the height direction (default value: 0)
- width_origin: the reference location in the width direction (only in 3D) (default value: 0)
- length_divisions: number of cell layers in length (default value: 10)
- height_divisions: number of cell layers in the height (default value: 10)
- width_divisions: number of cell layers in width (only in 3D) (default value: 10)
- materials (required):
- n_materials: number of materials (required)
- property_format: format of the material property: table or polynomial (required)
- initial_temperature: initial temperature of all the materials in kelvins (default value: 300)
- new_material_temperature: temperature of all the material that is being added during the process in kelvins (default value: 300)
- material_X: property tree for the material with number X
- material_X.Y: property tree where Y is either liquid, powder, or solid (one is required)
- material_X.Y.Z: Z is either density in kg/m^3, specific_heat in J/(K*kg), thermal_conductivity_x, resp. y or z, in the direction x, resp. y or z (in 2D only x and z are used), in W/(m*K), emissivity, or convection_heat_transfer_coef in W/(m^2*K) (optional)
- material_X.A: A is either solidus in kelvins, liquidus in kelvins, latent_heat in J/kg, radiation_temperature_infty in kelvins, or convection_temperature_infty in kelvins (optional)
- memory_space (optional): device (use GPU if Kokkos compiled with GPU support) or host (use CPU) (default value: host)
- post_processor (required):
- filename_prefix: prefix of output files (required)
- time_steps_between_output: number of time steps between the fields being written to the output files (default value: 1)
- additional_output_refinement: additional levels of refinement for the output (default: 0)
- refinement (required):
- n_refinements: number of times the cells on the paths of the beams are refined (default value: 2)
- beam_cutoff: the cutoff value of the heat source terms above which beam-based refinement occurs (default value: 1e-15)
- coarsen_after_beam: whether to coarsen cells where the beam has already passed (default value: false)
- time_steps_between_refinement: number of time steps after which the refinement process is performed (default value: 2)
- sources (required):
- n_beams: number of heat source beams (required)
- beam_X: property tree for the beam with number X
- beam_X.type: type of heat source: goldak, electron_beam, or cube (required)
- beam_X.scan_path_file: scan path filename (required)
- beam_X.scan_path_file_format: format of the scan path: segment or event_series (required)
- beam_X.max_power: maximum power of the beam in watts (required)
- beam_X.depth: maximum depth reached by the electron beam in meters (required)
- beam_X.absorption_efficiency: absorption efficiency of the beam equivalent to energy_conversion_efficiency * control_efficiency for electon beam. Number between 0 and 1 (required).
- beam_X.diameter: diameter of the beam in meters (default value: 2e-3)
- time_stepping (required):
- method: name of the method to use for the time integration: forward_euler, rk_third_order, rk_fourth_order, backward_euler, implicit_midpoint, crank_nicolson, or sdirk2 (required)
- scan_path_for_duration: if the flag is true, the duration of the simulation is determined by the duration of the scan path. In this case the scan path file needs to contain SCAN_PATH_END to terminate the simulation. If the flag is false, the duration of the simulation is determined by the duration input (default value: false) [since 1.1]
- duration: duration of the simulation in seconds (required if scan_path_for_duration is false) [required for 1.0]
- time_step: length of the time steps used for the simulation in seconds (required)
- for implicit method:
- max_iteration: mamximum number of the iterations of the linear solver (default value: 1000)
- tolerance: tolerance of the linear solver (default value: 1e-12)
- n_tmp_vectors: maximum number of vectors used by GMRES (default value: 30)
- right_preconditioner: use left or right preconditioning for the linear solver (default value: false)
- newton_max_iteration: maximum number of iterations of Newton solver (default value: 100)
- newton_tolerance: tolerance of the Newton solver (default value: 1e-6)
- jfnk: use Jacobian-Free Newton Krylov method (default value: false)
- experiment (optional):
- read_in_experimental_data: whether to read in experimental data (default: false)
- if reading in experimental data:
- file: format of the file names. The format is pretty arbitrary, the keywords #frame and #camera are replaced by the frame and the camera number. The format of the file itself should be csv with a header line. (required)
- format: The format of the experimental data, either
point_cloud
, with (x,y,z,value) per line, orray
, with (pt0_x,pt0_y,pt0_z,pt1_x,pt1_y,pt1_z,value) per line, where the ray starts at pt0 and passes through pt1. (required) - first_frame: number associated to the first frame (default value: 0)
- last_frame: number associated to the last frame (required)
- first_camera_id: number associated to the first camera (required)
- last_camera_id: number associated to the last camera (required)
- log_filename: The (full) filename of the log file that lists the timestamp for each frame
from each camera. Note that the timestamps are not assumed to match the simulation time frame. The
first_frame_temporal_offset
parameter (below) controls the simulation time corresponding to the first camera frame. (required) - first_frame_temporal_offset: A uniform shift to the timestamps from all cameras to match the simulation time (default value: 0.0)
- estimated_uncertainty: The estimate of the uncertainty in the experimental data points as given by a standard deviation (under the simplifying assumption that the error is normally distributed and independent for each data point) (default value: 0.0).
- output_experiment_on_mesh: Whether to output the experimental data projected onto the simulation mesh at each experiment time stamp (default: true).
- ensemble (optional):
- ensemble_simulation: whether to perform an ensemble of simulations (default value: false)
- ensemble_size: the number of ensemble members for the ensemble Kalman filter (EnKF) (default value: 5)
- initial_temperature_stddev: the standard deviation for the initial temperature of the material (default value: 0.0)
- new_material_temperature_stddev: the standard deviation for the temperature of material added during the process (default value: 0.0)
- beam_0_max_power_stddev: the standard deviation for the max power for beam 0 (if it exists) (default value: 0.0)
- beam_0_absorption_efficiency_stddev: the standard deviation for the absorption efficiency for beam 0 (if it exists) (default value: 0.0)
- data_assimilation (optional):
- assimilate_data: whether to perform data assimilation (default value: false)
- localization_cutoff_function: the function used to decrease the sample covariance as the relevant points become farther away: gaspari_cohn, step_function, none (default: none)
- localization_cutoff_distance: the distance at which sample covariance entries are set to zero (default: infinity)
- augment_with_beam_0_absorption: whether to augment the state vector with the beam 0 absorption efficiency (default: false)
- augment_with_beam_0_max_power: whether to augment the state vector with the beam 0 max power (default: false)
- solver:
- max_number_of_temp_vectors: maximum number of temporary vectors for the GMRES solve (optional)
- max_iterations: maximum number of iterations for the GMRES solve (optional)
- convergence_tolerance: convergence tolerance for the GMRES solve (optional)
- profiling (optional):
- timer: output timing information (default value: false)
- caliper: configuration string for Caliper (optional)
- checkpoint (optional):
- time_steps_between_checkpoint: number of time steps after which checkpointing is performed (required)
- filename_prefix: prefix of the checkpoint files (required)
- overwrite_files: if true the checkpoint files are overwritten by newer ones. If false, the time steps is added to the filename prefix (required)
- restart (optional):
- filename_prefix: prefix of the restart files (required)
- units (optional): change the unit of some inputs [since 1.1]
- mesh: unit used for the mesh. Either millimeter, centimeter, inch, or meter (default value: meter)
- heat_source (optional):
- power: unit used for the power of the heat sources. Either milliwatt or watt (default value: watt)
- velocity: unit used for the velocity of the heat sources. Either millimeter/second, centimeter/second, or meter/second (default value: meter/second)
- dimension: unit used for the dimension of the heat sources. Either millimeter, centimeter, inch, or meter (default value: meter)
- scan_path: unit used for the scan path of the heat sources. Either millimeter, centimeter, inch, or meter (default value: meter)
- verbose_output: true or false (default value: false)
adamantine
supports two kinds of scan path input: the segment
format and the
event
format.
After the self-explainatory tree-line header, the column descriptions are:
- Column 1: mode 0 for line mode, mode 1 for spot mode
- Columns 2 to 4: (x,y,z) coordinates in units of m. For line mode, this is the ending position of the the line.
- Column 5: the coefficient for the nominal power. Usually this is either 0 or 1, but sometimes intermediate values are used when turning a corner.
- Column 6: in spot mode, this is the dwell time in seconds, in line mode this is the velocity in m/s.
The first entry must be a spot. If it was a line, there would be no way to know where the line starts (since the coordinates are the ending coordinates). By convention, we avoid using a zero second dwell time for the first spot and instead choose some small positive number.
A scan file example can be found here.
For an event series the first segment is a point, then the rest are lines. The column descriptions are:
- Column 1: segment endtime
- Columns 2 to 4: (x,y,z) coordinates in units of m. This is the ending position of the line.
- Column 5: the coefficient for the nominal power. Usually this is either 0 or 1, but sometimes intermediate values are used when turning a corner.
A scan file example can be found here.
adamantine
supports two ways to deposit material: based on the scan path and based on a separate material deposition file.
If the material deposition is based on the scan path, then material is added according to the deposition_length
, deposition_width
, deposition_height
, deposition_lead_time
, and deposition_time
input parameters in the geometry
input block. Cells are activated if they are crossed by a rectangular prism (rectangle in 2D) traveling along the scan path. In 3D the rectangular prism is centered with the (x,y) values of the scan path and the top of the rectangular prism is at the z value of the scan path (i.e. the scan path height gives the new height of the material after deposition). Near the end of segments, the length of the rectangular prism is truncated so as to not deposit material past the edge of the segment. Material can be deposited with a lead time ahead of the heat source (controlled by deposition_lead_time
). Depositing material requires modifying the simulation mesh, which can be computationally intensive. To reduce the cost, material can be added in "lumps", with the time between lumps set by deposition_time
.
The material deposition can also be set by boxes defined in a separate file. The format of this file is as follows.
The first entry of the file is the dimension the problem: 2 or 3.
- For 2D problems, the column descriptions are:
- Column 1 to 2: (x,y) coordinates of the center of the deposition box in m.
- Column 3 to 4: (x,y) length of deposition box in m.
- Column 5: deposition time in s.
- Column 6: angle of material deposition.
- For 3D problems, the column descriptions are:
- Column 1 to 3: (x,y,z) coordinates of the center of the deposition box in m.
- Column 4 to 6: (x,y,z) length of deposition box in m.
- Column 7: deposition time in s.
- Column 6: angle of material deposition.
An example of material deposition file can be found here.
Examples that showcase adamantine
capabilities can be found
here.
adamantine
is distributed under the 3-Clause BSD License.
If you have any question, find a bug, or have feature request please open an issue.
We encourage you to contribute to adamantine! Please check out the guidelines about how to proceed.