├── .clang-format ├── .envrc ├── .github └── workflows │ ├── Dockerfile │ ├── docker.yml │ └── nix.yml ├── .vscode ├── launch.json └── tasks.json ├── CHANGELOG.md ├── CITATION.cff ├── CMakeLists.txt ├── CMakePresets.json ├── CONTRIBUTING.md ├── LICENSE ├── NIX.md ├── README.md ├── application ├── CMakeLists.txt ├── adamantine.cc ├── adamantine.hh ├── input.info └── input_scan_path.txt ├── ci ├── Dockerfile ├── address_blacklist.txt └── jenkins_config ├── cmake ├── CodeCoverage.cmake ├── SetupAdamantine.cmake ├── SetupDealII.cmake ├── SetupTPLs.cmake └── Testing.cmake ├── doc ├── CMakeLists.txt ├── Doxyfile.in ├── README.md └── logo │ ├── adamantine_logo.png │ ├── adamantine_logo.svg │ ├── adamantine_logo_with_bg.png │ ├── adamantine_wordmark.png │ ├── adamantine_wordmark.svg │ └── adamantine_wordmark_with_bg.png ├── flake.lock ├── flake.nix ├── indent ├── nix ├── adamantine │ ├── common.nix │ └── v1.0.0.nix ├── dependencies │ ├── adiak │ │ └── default.nix │ ├── arborx │ │ └── default.nix │ ├── caliper │ │ └── default.nix │ └── dealii │ │ ├── common.nix │ │ ├── v9.5.2.nix │ │ └── v9.6.2.nix └── nixpkgs │ └── config.nix ├── source ├── BeamHeatSourceProperties.hh ├── BodyForce.cc ├── BodyForce.hh ├── CMakeLists.txt ├── CubeHeatSource.cc ├── CubeHeatSource.hh ├── DataAssimilator.cc ├── DataAssimilator.hh ├── ElectronBeamHeatSource.cc ├── ElectronBeamHeatSource.hh ├── ExperimentalData.hh ├── Geometry.cc ├── Geometry.hh ├── GoldakHeatSource.cc ├── GoldakHeatSource.hh ├── HeatSource.hh ├── ImplicitOperator.cc ├── ImplicitOperator.hh ├── MaterialProperty.hh ├── MaterialProperty.templates.hh ├── MaterialPropertyInstDev.cc ├── MaterialPropertyInstHost.cc ├── MaterialStates.hh ├── MechanicalOperator.cc ├── MechanicalOperator.hh ├── MechanicalPhysics.cc ├── MechanicalPhysics.hh ├── Microstructure.cc ├── Microstructure.hh ├── NewtonSolver.cc ├── NewtonSolver.hh ├── Operator.hh ├── PointCloud.cc ├── PointCloud.hh ├── PostProcessor.cc ├── PostProcessor.hh ├── RayTracing.cc ├── RayTracing.hh ├── ScanPath.cc ├── ScanPath.hh ├── ThermalOperator.hh ├── ThermalOperator.templates.hh ├── ThermalOperatorBase.hh ├── ThermalOperatorDevice.hh ├── ThermalOperatorDevice.templates.hh ├── ThermalOperatorDeviceInstSDev.cc ├── ThermalOperatorDeviceInstSLDev.cc ├── ThermalOperatorDeviceInstSLPDev.cc ├── ThermalOperatorInstSHost.cc ├── ThermalOperatorInstSLHost.cc ├── ThermalOperatorInstSLPHost.cc ├── ThermalPhysics.hh ├── ThermalPhysics.templates.hh ├── ThermalPhysicsInstSDev.cc ├── ThermalPhysicsInstSHost.cc ├── ThermalPhysicsInstSLDev.cc ├── ThermalPhysicsInstSLHost.cc ├── ThermalPhysicsInstSLPDev.cc ├── ThermalPhysicsInstSLPHost.cc ├── ThermalPhysicsInterface.hh ├── Timer.cc ├── Timer.hh ├── ensemble_management.cc ├── ensemble_management.hh ├── experimental_data_utils.cc ├── experimental_data_utils.hh ├── instantiation.hh ├── material_deposition.cc ├── material_deposition.hh ├── types.hh ├── utils.hh ├── validate_input_database.cc └── validate_input_database.hh └── tests ├── CMakeLists.txt ├── data ├── HourGlass_AOP.info ├── HourGlass_AOP.vtk ├── HourGlass_AOP_scan_path.txt ├── amr_test.info ├── bare_plate_L_da.info ├── bare_plate_L_da_aug_ref_data_0_0.csv ├── bare_plate_L_da_aug_ref_data_0_1.csv ├── bare_plate_L_da_aug_ref_log.txt ├── bare_plate_L_da_augmented.info ├── bare_plate_L_ensemble.info ├── bare_plate_L_expt_data_0_0.csv ├── bare_plate_L_expt_data_0_1.csv ├── bare_plate_L_expt_log.txt ├── bare_plate_L_scan_path.txt ├── bare_plate_L_scan_path_fast.txt ├── demo_316_short.info ├── demo_316_short_amr.info ├── demo_316_short_anisotropic.info ├── demo_316_short_scan_path.txt ├── demo_316_short_scan_path_amr.txt ├── experiment_log_test.txt ├── experimental_data_0_0.csv ├── extruded_cube.msh ├── hexahedra.geo ├── hexahedra.msh ├── integration_2d.info ├── integration_2d_ensemble.info ├── integration_2d_gold.txt ├── integration_2d_units.info ├── integration_3d_gold.txt ├── integration_3d_gold_0.txt ├── integration_3d_gold_1.txt ├── integration_3d_gold_short.txt ├── integration_3d_gold_short_0.txt ├── integration_3d_gold_short_1.txt ├── integration_da_add_material.info ├── integration_da_add_material_expt_log.txt ├── integration_da_add_material_expt_pc_0_0.csv ├── integration_da_add_material_expt_ray_0_0.csv ├── integration_da_add_material_sp.txt ├── material_deposition_2d.txt ├── material_deposition_3d.txt ├── material_path_test_material_deposition.txt ├── material_property_polynomial.info ├── material_property_table.info ├── microstructure_G_R_gold_1.txt ├── microstructure_G_R_gold_2.txt ├── rays_cam-0-0_test_full.csv ├── raytracing_experimental_data_0_0.csv ├── raytracing_non_AA_cells-0-0.csv ├── scan_path.txt ├── scan_path_L.txt ├── scan_path_diagonal.txt ├── scan_path_event_series.inp ├── scan_path_layers.txt ├── scan_path_test_thermal_physics.txt ├── scan_path_units.txt ├── thermoelastic_bare_plate.info ├── thermoelastic_bare_plate_add_material_scan_path.txt └── thermoelastic_bare_plate_scan_path.txt ├── main.cc ├── test_data_assimilator.cc ├── test_ensemble_management.cc ├── test_experimental_data.cc ├── test_geometry.cc ├── test_heat_source.cc ├── test_implicit_operator.cc ├── test_integration_2d.cc ├── test_integration_2d_device.cc ├── test_integration_3d.cc ├── test_integration_3d_amr.cc ├── test_integration_3d_amr_device.cc ├── test_integration_3d_device.cc ├── test_integration_da.cc ├── test_integration_da_augmented.cc ├── test_integration_thermoelastic.cc ├── test_material_deposition.cc ├── test_material_property.cc ├── test_material_property.hh ├── test_material_property_device.cc ├── test_mechanical_operator.cc ├── test_mechanical_physics.cc ├── test_microstructure.cc ├── test_newton_solver.cc ├── test_post_processor.cc ├── test_scan_path.cc ├── test_thermal_operator.cc ├── test_thermal_operator_device.cc ├── test_thermal_physics.cc ├── test_thermal_physics.hh ├── test_thermal_physics_device.cc ├── test_timer.cc ├── test_utils.cc └── test_validate_input_database.cc /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM 2 | --- 3 | Language: Cpp 4 | AlwaysBreakTemplateDeclarations: true 5 | BreakBeforeBraces: Allman 6 | IncludeBlocks: Regroup 7 | IncludeCategories: 8 | - Regex: "[a-z]*.hh" 9 | Priority: 100 10 | - Regex: "deal.II*" 11 | Priority: 200 12 | - Regex: "boost*" 13 | Priority: 300 14 | - Regex: "adiak*" 15 | Priority: 400 16 | - Regex: "caliper*" 17 | Priority: 500 18 | - Regex: "Kokkos*" 19 | Priority: 600 20 | - Regex: "<[a-z_]+>" 21 | Priority: 1000 22 | ... 23 | -------------------------------------------------------------------------------- /.envrc: -------------------------------------------------------------------------------- 1 | use flake -L 2 | -------------------------------------------------------------------------------- /.github/workflows/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rombur/adamantine-stack:no_gpu-latest 2 | 3 | ENV DEBIAN_FRONTEND=noninteractive 4 | RUN apt-get update && apt-get upgrade -y && apt-get install -y \ 5 | wget \ 6 | curl \ 7 | bison \ 8 | bash-completion \ 9 | gdb \ 10 | zlib1g-dev \ 11 | python3-dev \ 12 | python3-setuptools \ 13 | vim-nox \ 14 | ninja-build \ 15 | && \ 16 | apt-get clean && rm -rf /var/lib/apt/lists/ 17 | 18 | RUN cd /home && git clone https://github.com/adamantine-sim/adamantine && \ 19 | cd adamantine && \ 20 | mkdir build && cd build && \ 21 | cmake \ 22 | -DDEAL_II_DIR=${DEAL_II_DIR} \ 23 | -DCMAKE_BUILD_TYPE=Release\ 24 | -DADAMANTINE_ENABLE_ADIAK=ON \ 25 | -DADAMANTINE_ENABLE_CALIPER=ON \ 26 | ../ && \ 27 | make && mv bin ../ && cd ../ && rm -r build 28 | 29 | # Make adamantine available as executable anywhere in container 30 | RUN ln -s /home/adamantine/bin/adamantine /bin/adamantine 31 | -------------------------------------------------------------------------------- /.github/workflows/docker.yml: -------------------------------------------------------------------------------- 1 | name: github-docker 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | 7 | jobs: 8 | build-master-docker: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout code 12 | uses: actions/checkout@v2 13 | 14 | - name: Login do DockerHub 15 | uses: docker/login-action@v1 16 | with: 17 | username: ${{ secrets.DOCKER_USERNAME }} 18 | password: ${{ secrets.DOCKER_PASSWORD }} 19 | 20 | - name: Build and push Docker image of master 21 | uses: docker/build-push-action@v2 22 | with: 23 | context: ./.github/workflows/ 24 | file: ./.github/workflows/Dockerfile 25 | push: true 26 | tags: rombur/adamantine:latest 27 | -------------------------------------------------------------------------------- /.github/workflows/nix.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Nix 3 | on: [push, pull_request] 4 | jobs: 5 | test: 6 | strategy: 7 | matrix: 8 | os: [ubuntu-latest, macos-latest] 9 | runs-on: ${{ matrix.os }} 10 | defaults: 11 | run: 12 | working-directory: ./ 13 | steps: 14 | - uses: actions/checkout@v4 15 | - uses: cachix/install-nix-action@v27 16 | with: 17 | nix_path: nixpkgs=channel:nixos-unstable 18 | extra_nix_config: | 19 | trusted-public-keys = mdfbaam.cachix.org-1:WCQinXaMJP7Ny4sMlKdisNUyhcO2MHnPoobUef5aTmQ= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= 20 | substituters = https://mdfbaam.cachix.org https://cache.nixos.org 21 | - run: nix flake check 22 | - run: nix build 23 | 24 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "cppdbg", 6 | "request": "launch", 7 | "name": "Launch Adamantine (GDB)", 8 | "cwd": "${workspaceFolder}", 9 | "program": "${command:cmake.launchTargetPath}", 10 | "args": [ 11 | "-i", 12 | "${input:pickInputFile}", 13 | "-o", 14 | "${input:pickInputFile}.${input:shortDate}.output" 15 | ] 16 | } 17 | ], 18 | "inputs": [ 19 | { 20 | "id": "pickInputFile", 21 | "type": "command", 22 | "command": "extension.commandvariable.pickStringRemember", 23 | "args": { 24 | "description": "Pick a info file to pass to adamantine", 25 | "key": "debugInfoFile", 26 | "rememberTransformed": "true", 27 | "options": [ 28 | { 29 | "label": "Use previous input", 30 | "description": "${remember:debugInfoFile}", 31 | "value": "${remember:debugInfoFile}" 32 | }, 33 | { 34 | "label": "Pick new input", 35 | "value": "${pickFile:newDebugFile}" 36 | } 37 | ], 38 | "pickFile": { 39 | "newDebugFile": { 40 | "description": "Pick new info file for adamantine", 41 | "include": "**/*.info", 42 | "exclude": "**/build/**", 43 | "keyRemember": "newDebugFile" 44 | } 45 | }, 46 | "remember": { 47 | "debugInfoFile": { 48 | "key": "debugInfoFile", 49 | "default": "Undefined - select an input first" 50 | } 51 | } 52 | } 53 | }, 54 | { 55 | "id": "shortDate", 56 | "type": "command", 57 | "command": "extension.commandvariable.dateTime", 58 | "args": { 59 | "locale": "en-US", 60 | "options": { 61 | "weekday": "long", 62 | "year": "numeric", 63 | "month": "2-digit", 64 | "day": "2-digit", 65 | "hour12": false, 66 | "hour": "2-digit", 67 | "minute": "2-digit", 68 | "second": "2-digit" 69 | }, 70 | "template": "${year}${month}${day}T${hour}${minute}${second}" 71 | } 72 | } 73 | ] 74 | } 75 | 76 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "Launch Adamantine (mpirun)", 6 | "type": "shell", 7 | "command": "mpirun", 8 | "args": [ 9 | "${command:cmake.launchTargetPath}", 10 | "-i", 11 | "${input:pickInputFile}", 12 | "-o", 13 | "${input:pickInputFile}.${input:shortDate}.output" 14 | ], 15 | "presentation": { 16 | "reveal": "always", 17 | "focus": false, 18 | "panel": "dedicated", 19 | "showReuseMessage": true, 20 | "clear": false 21 | }, 22 | "problemMatcher": [] 23 | }, 24 | { 25 | "label": "Launch Adamantine (direct)", 26 | "type": "shell", 27 | "command": "${command:cmake.launchTargetPath}", 28 | "args": [ 29 | "-i", 30 | "${input:pickInputFile}", 31 | "-o", 32 | "${input:pickInputFile}.${input:shortDate}.output" 33 | ], 34 | "presentation": { 35 | "reveal": "always", 36 | "focus": false, 37 | "panel": "dedicated", 38 | "showReuseMessage": true, 39 | "clear": false 40 | }, 41 | "problemMatcher": [] 42 | } 43 | ], 44 | "inputs": [ 45 | { 46 | "id": "pickInputFile", 47 | "type": "command", 48 | "command": "extension.commandvariable.pickStringRemember", 49 | "args": { 50 | "description": "Pick a info file to pass to adamantine", 51 | "key": "debugInfoFile", 52 | "rememberTransformed": "true", 53 | "options": [ 54 | { 55 | "label": "Use previous input", 56 | "description": "${remember:debugInfoFile}", 57 | "value": "${remember:debugInfoFile}" 58 | }, 59 | { 60 | "label": "Pick new input", 61 | "value": "${pickFile:newDebugFile}" 62 | } 63 | ], 64 | "pickFile": { 65 | "newDebugFile": { 66 | "description": "Pick new info file for adamantine", 67 | "include": "**/*.info", 68 | "exclude": "**/build/**", 69 | "keyRemember": "newDebugFile" 70 | } 71 | }, 72 | "remember": { 73 | "debugInfoFile": { 74 | "key": "debugInfoFile", 75 | "default": "Undefined - select an input first" 76 | } 77 | } 78 | } 79 | }, 80 | { 81 | "id": "shortDate", 82 | "type": "command", 83 | "command": "extension.commandvariable.dateTime", 84 | "args": { 85 | "locale": "en-US", 86 | "options": { 87 | "weekday": "long", 88 | "year": "numeric", 89 | "month": "2-digit", 90 | "day": "2-digit", 91 | "hour12": false, 92 | "hour": "2-digit", 93 | "minute": "2-digit", 94 | "second": "2-digit" 95 | }, 96 | "template": "${year}${month}${day}T${hour}${minute}${second}" 97 | } 98 | } 99 | ] 100 | } 101 | 102 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [1.0](https://github.com/adamantine-sim/adamantine/tree/release/1.0) (2024-10-01) 4 | 5 | Initial release. 6 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | message: "If you use this software, please cite it as below." 3 | repository-code: "https://github.com/admantine-sim/adamantine" 4 | url: "https://adamantine-sim.github.io/adamantine" 5 | license: "BSD-3-Clause" 6 | authors: 7 | - family-names: "Turcksin" 8 | given-names: "Bruno" 9 | orcid: "https://orcid.org/0000-0001-5954-6313" 10 | - family-names: "DeWitt" 11 | given-names: "Stephen" 12 | orcid: "https://orcid.org/0000-0002-9550-293X" 13 | title: "Adamantine 1.0: A Thermomechanical Simulator for Additive Manufacturing" 14 | doi: 10.21105/joss.07017 15 | journal: "Journal of Open Source Software" 16 | volume: "9" 17 | number: "102" 18 | year: "2024" 19 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | 3 | if(POLICY CMP0167) 4 | # Policy introduced in CMake 3.30. Use the Boost CMake Config installed with Boost instead of 5 | # the FindBoost.cmake module installed with CMake. 6 | cmake_policy(SET CMP0167 NEW) 7 | endif() 8 | 9 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) 10 | 11 | set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) 12 | 13 | # This needs to be called before project is called and before we setup the other 14 | # TPL and adamantine 15 | include(SetupDealII) 16 | 17 | project(Adamantine LANGUAGES CXX VERSION 1.0.9) 18 | 19 | include(SetupTPLs) 20 | include(SetupAdamantine) 21 | 22 | add_subdirectory(application) 23 | add_subdirectory(source) 24 | 25 | option(ADAMANTINE_ENABLE_COVERAGE "Measure coverage" OFF) 26 | if (ADAMANTINE_ENABLE_COVERAGE) 27 | include(CodeCoverage) 28 | endif() 29 | 30 | option(ADAMANTINE_ENABLE_TESTS "Build tests" OFF) 31 | if (ADAMANTINE_ENABLE_TESTS) 32 | include(Testing) 33 | enable_testing() 34 | include(CTest) 35 | add_subdirectory(tests) 36 | add_test(NAME indent_code 37 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} 38 | COMMAND ./indent 39 | ) 40 | endif() 41 | 42 | # Provide "indent" target for indenting all the header and the source files. 43 | add_custom_target(indent 44 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} 45 | COMMAND ./indent 46 | ) 47 | 48 | if (ADAMANTINE_ENABLE_DOCUMENTATION) 49 | add_subdirectory(doc) 50 | endif() 51 | -------------------------------------------------------------------------------- /CMakePresets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 6, 3 | "configurePresets": [ 4 | { 5 | "name": "generic-gcc-ninja", 6 | "displayName": "Generic (gcc-ninja)", 7 | "description": "Basic configuration with the GCC toolchain using Ninja generator.", 8 | "generator": "Ninja Multi-Config", 9 | "binaryDir": "${sourceDir}/build/${presetName}", 10 | "cacheVariables": { 11 | "CMAKE_CXX_COMPILER": "g++" 12 | } 13 | } 14 | ], 15 | "buildPresets": [ 16 | { 17 | "name": "build-debug-gcc-ninja", 18 | "displayName": "Debug (gcc-ninja)", 19 | "description": "Compile a debug build using GCC.", 20 | "configurePreset": "generic-gcc-ninja", 21 | "configuration": "Debug" 22 | }, 23 | { 24 | "name": "build-release-gcc-ninja", 25 | "displayName": "Release (gcc-ninja)", 26 | "description": "Compile a release build using GCC.", 27 | "configurePreset": "generic-gcc-ninja", 28 | "configuration": "Release" 29 | } 30 | ] 31 | } 32 | 33 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributing to adamantine is easy. Just send us a [pullrequest](https://help.github.com/articles/using-pull-requests/). 4 | When you send your request, make `master` the destination branch on the [adamantine repository](https://github.com/adamantine-sim/adamantine). 5 | 6 | Your pull request must pass adamantine's tests before being merged into the `master` branch. These tests are (usually) performed automatically through the continuous integration (CI) testing integrated into adamantine's GitHub repository. 7 | -------------------------------------------------------------------------------- /NIX.md: -------------------------------------------------------------------------------- 1 | ## Nix 2 | 3 | First install the [Nix package manager][NIX] and then enable [Flakes][Flakes]. 4 | Alternatively, check out the [Determinate Systems Installer][Determinate] for 5 | an out of the box experience. See [nix.dev][nix.dev] for more help with Nix. 6 | 7 | To get a shell with adamantine temporarily installed, run: 8 | 9 | $ nix shell github:adamantine-sim/adamantine 10 | # Adamantine now available 11 | $ adamantine --help 12 | 13 | To install this permanently, run: 14 | 15 | $ nix profile install github:adamantine-sim/adamantine 16 | 17 | To get the latest stable release, use: 18 | 19 | $ nix shell github:adamantine-sim/adamantine#adamantine.versions.stable 20 | 21 | To build from a working copy use `nix develop` and run CMake manually: 22 | 23 | $ nix develop 24 | $ cmake -B build -GNinja 25 | $ cmake --build build 26 | 27 | ## Cache 28 | 29 | To avoid unnecessary builds, you can use the cache as configured in 30 | `flake.nix`. The only requirement is that your user is a "trusted user" by the 31 | nix dameon. 32 | 33 | If you are not a trusted user, you may make yourself one by editing 34 | `/etc/nix/nix.conf` and add the following line: 35 | 36 | ... 37 | trusted-users = [YOUR USERNAME HERE] 38 | ... 39 | 40 | Then, when running a nix operation with the Adamantine flake, you should be 41 | prompted if you want to add the cache to your configuration. Say yes to all 42 | queries to enable the cache permanently. 43 | 44 | For more info, see the docs for this option [here][Trusted]. 45 | 46 | ## direnv 47 | 48 | This repository also supports `direnv` for integration with both your shell and 49 | tools like VSCode. 50 | 51 | First install direnv from either your distro or via Nix: 52 | 53 | # Via apt... 54 | $ sudo apt install direnv 55 | # ... or nix. 56 | $ nix profile install direnv 57 | 58 | Setup direnv for your shell. Tutorials for various shells can be found 59 | [here][DirenvHook]. For bash: 60 | 61 | $ echo "eval \"\$(direnv hook bash)\"" >> ~/.bashrc 62 | 63 | Restart your shell and then allow direnv: 64 | 65 | $ cd path/to/my/adamantine 66 | $ direnv allow 67 | 68 | This will automatically enter the nix development shell whenever you enter the 69 | adamantine directory. 70 | 71 | If you use VSCode, a great extension that adds direnv support can be found 72 | [here][DirenvVSCode]. 73 | 74 | 75 | [NIX]: https://nixos.org/download.html 76 | [Flakes]: https://nixos.wiki/wiki/Flakes 77 | [nix.dev]: https://nix.dev 78 | [Determinate]: https://github.com/DeterminateSystems/nix-installer 79 | [DirenvHook]: https://direnv.net/docs/hook.html 80 | [DirenvVSCode]: https://marketplace.visualstudio.com/items?itemName=mkhl.direnv 81 | [Trusted]: https://nix.dev/manual/nix/2.24/command-ref/conf-file#conf-trusted-users 82 | -------------------------------------------------------------------------------- /application/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Create adamantine executable and link against the static library. 2 | set(Adamantine_app_HEADERS 3 | ${CMAKE_CURRENT_SOURCE_DIR}/adamantine.hh 4 | ) 5 | set(Adamantine_app_SOURCES 6 | ${CMAKE_CURRENT_SOURCE_DIR}/adamantine.cc 7 | ) 8 | add_executable(adamantine ${Adamantine_app_SOURCES} ${Adamantine_app_HEADERS}) 9 | 10 | set_target_properties(adamantine PROPERTIES 11 | CXX_STANDARD 17 12 | CXX_STANDARD_REQUIRED ON 13 | CXX_EXTENSIONS OFF 14 | ) 15 | 16 | DEAL_II_SETUP_TARGET(adamantine) 17 | target_link_libraries(adamantine Adamantine) 18 | if (ADAMANTINE_ENABLE_ADIAK) 19 | target_link_libraries(adamantine adiak::adiak) 20 | endif() 21 | 22 | file(COPY input.info DESTINATION ${CMAKE_BINARY_DIR}/bin) 23 | file(COPY input_scan_path.txt DESTINATION ${CMAKE_BINARY_DIR}/bin) 24 | 25 | install(TARGETS adamantine) 26 | -------------------------------------------------------------------------------- /application/input.info: -------------------------------------------------------------------------------- 1 | geometry 2 | { 3 | import_mesh false ; Use built-in mesh generator 4 | dim 2 ; dimension of the domain 5 | length 2e-2 ; [m] 6 | height 1e-2 ; [m] In 3D, the third parameters is width 7 | length_divisions 20 ; Number of cell layers in the length direction 8 | height_divisions 10 ; Number of cell layers in the height direction 9 | } 10 | 11 | physics 12 | { 13 | thermal true ; Thermal simulation 14 | mechanical false ; Mechanical simulation. If both thermal and mechanical are 15 | ; true, solve a coupled thermo-mechanical problem 16 | } 17 | 18 | boundary 19 | { 20 | type adiabatic 21 | } 22 | 23 | refinement 24 | { 25 | n_refinements 2 ; Number of time the cells on the paths of the beams are 26 | ; refined 27 | } 28 | 29 | materials 30 | { 31 | n_materials 1 32 | 33 | property_format polynomial 34 | 35 | material_0 36 | { 37 | solid 38 | { 39 | density 7541 ; [kg/m^3] For now all the states needs to have the same 40 | ; density. 41 | specific_heat 600 ; [J/kg K] 42 | thermal_conductivity_x 26.6 ; [W/m K] 43 | thermal_conductivity_z 26.6 ; [W/m K] 44 | } 45 | 46 | powder 47 | { 48 | specific_heat 600 ; [J/kg K] 49 | density 7541 ; [kg/m^3] 50 | thermal_conductivity_x 0.266 ; [W/m K] 51 | thermal_conductivity_z 0.266 ; [W/m K] 52 | } 53 | 54 | liquid 55 | { 56 | specific_heat 775 ; [J/kg K] 57 | density 7541 ; [kg/m^3] 58 | thermal_conductivity_x 29.0 ; [W/m k] 59 | thermal_conductivity_z 29.0 ; [W/m k] 60 | ; Not all three states need to define the same properties or to exist 61 | } 62 | 63 | solidus 1528 ; [K] 64 | liquidus 1610 ; [K] 65 | latent_heat 227000 ; [J/kg] 66 | } 67 | } 68 | 69 | sources 70 | { 71 | n_beams 1 72 | 73 | beam_0 74 | { 75 | type goldak ; goldak (laser) or electron_beam 76 | depth 1e-3 ; [m] maximum depth reached by the laser 77 | diameter 1e-3 ; [m] 78 | scan_path_file input_scan_path.txt 79 | scan_path_file_format segment 80 | absorption_efficiency 0.3 ; number between 0 and 1 equivalent to 81 | ; energy_conversion_efficiency * control_efficiency 82 | ; for an electron beam 83 | max_power 1200.0 ; [W], current * voltage for an electron beam 84 | } 85 | } 86 | 87 | time_stepping 88 | { 89 | method forward_euler ; Possibilities: backward_euler, implicit_midpoint, 90 | ; crank_nicolson, sdirk2, forward_euler, rk_third_order, 91 | ; rk_fourth_order 92 | duration 1e-9 ; [s] 93 | time_step 5e-11 ; [s] 94 | } 95 | 96 | post_processor 97 | { 98 | filename_prefix output 99 | } 100 | 101 | discretization 102 | { 103 | thermal 104 | { 105 | fe_degree 3 106 | quadrature gauss ; Optional parameter. Possibilities: gauss or lobatto 107 | } 108 | } 109 | 110 | memory_space device ; If Kokkos was compiled with GPU support, run on the device 111 | -------------------------------------------------------------------------------- /application/input_scan_path.txt: -------------------------------------------------------------------------------- 1 | Number of path segments 2 | 2 3 | Mode x y z pmod param 4 | 1 0.000 0.000 0 0 1e-6 5 | 0 0.002 0.000 0 1 0.8 6 | -------------------------------------------------------------------------------- /ci/address_blacklist.txt: -------------------------------------------------------------------------------- 1 | leak:libmpi.so 2 | leak:libopen-pal.so 3 | -------------------------------------------------------------------------------- /ci/jenkins_config: -------------------------------------------------------------------------------- 1 | pipeline { 2 | agent none 3 | 4 | options { 5 | disableConcurrentBuilds(abortPrevious: true) 6 | timeout(time: 6, unit: 'HOURS') 7 | } 8 | 9 | triggers { 10 | issueCommentTrigger('.*test this please.*') 11 | } 12 | 13 | environment { 14 | OMP_NUM_THREADS = 2 15 | } 16 | 17 | stages { 18 | stage('Test') { 19 | parallel { 20 | stage('CPU') { 21 | agent { 22 | docker { 23 | image "rombur/adamantine-stack:no_gpu-latest" 24 | alwaysPull true 25 | label 'nvidia-docker || rocm-docker' 26 | } 27 | } 28 | environment { 29 | BOOST_TEST_LOG_LEVEL = 'test_suite' 30 | } 31 | steps { 32 | sh 'rm -rf build && mkdir -p build' 33 | dir('build') { 34 | sh '''#!/bin/bash 35 | cmake \ 36 | -D CMAKE_BUILD_TYPE=Debug \ 37 | -D ADAMANTINE_ENABLE_TESTS=ON \ 38 | -DADAMANTINE_ENABLE_ADIAK=ON \ 39 | -DADAMANTINE_ENABLE_CALIPER=ON \ 40 | -D CMAKE_CXX_FLAGS="-Wall -Wextra -pedantic -Werror" \ 41 | -D DEAL_II_DIR=${DEAL_II_DIR} \ 42 | .. 43 | ''' 44 | sh 'make -j8' 45 | sh 'ctest -V --timeout 3600 --no-compress-output -R test_ -T Test' 46 | } 47 | } 48 | post { 49 | always { 50 | xunit([CTest(deleteOutputFiles: true, failIfNotNew: true, pattern: 'build/Testing/**/Test.xml', skipNoTestFiles: false, stopProcessingIfError: true)]) 51 | } 52 | } 53 | } 54 | 55 | stage('CUDA') { 56 | agent { 57 | docker { 58 | image "rombur/adamantine-stack:latest" 59 | alwaysPull true 60 | label 'nvidia-docker && ampere' 61 | } 62 | } 63 | environment { 64 | BOOST_TEST_LOG_LEVEL = 'test_suite' 65 | } 66 | steps { 67 | sh 'rm -rf build && mkdir -p build' 68 | dir('build') { 69 | sh '''#!/bin/bash 70 | cmake \ 71 | -D CMAKE_BUILD_TYPE=Debug \ 72 | -D ADAMANTINE_ENABLE_TESTS=ON \ 73 | -D ADAMANTINE_ENABLE_COVERAGE=OFF \ 74 | -D CMAKE_CXX_FLAGS="-Wall -Wextra" \ 75 | -D DEAL_II_DIR=${DEAL_II_DIR} \ 76 | .. 77 | ''' 78 | sh 'make -j8' 79 | sh 'ctest -V --timeout 3600 --no-compress-output -R test_ -T Test' 80 | } 81 | } 82 | post { 83 | always { 84 | xunit([CTest(deleteOutputFiles: true, failIfNotNew: true, pattern: 'build/Testing/**/Test.xml', skipNoTestFiles: false, stopProcessingIfError: true)]) 85 | } 86 | } 87 | } 88 | } 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /cmake/CodeCoverage.cmake: -------------------------------------------------------------------------------- 1 | find_program(LCOV_EXECUTABLE lcov) 2 | if(LCOV_EXECUTABLE) 3 | message(STATUS "Found lcov: ${LCOV_EXECUTABLE}") 4 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") 5 | message(STATUS "CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}") 6 | else() 7 | message(SEND_ERROR "lcov not found") 8 | endif() 9 | 10 | find_program(GENHTML_EXECUTABLE genhtml) 11 | if(GENHTML_EXECUTABLE) 12 | message(STATUS "Found genhtml: ${GENHTML_EXECUTABLE}") 13 | else() 14 | message(SEND_ERROR "genhtml not found") 15 | endif() 16 | 17 | set(CPP_COVERAGE_FILE ${CMAKE_BINARY_DIR}/lcov.info) 18 | set(CPP_COVERAGE_OUTPUT_DIRECTORY 19 | ${CMAKE_BINARY_DIR}/htmlcov-cpp) 20 | 21 | add_custom_target(coverage 22 | COMMAND ${LCOV_EXECUTABLE} 23 | --capture 24 | --directory ${CMAKE_BINARY_DIR} 25 | --output-file=${CPP_COVERAGE_FILE} 26 | COMMAND ${GENHTML_EXECUTABLE} 27 | ${CPP_COVERAGE_FILE} 28 | --output-directory 29 | ${CPP_COVERAGE_OUTPUT_DIRECTORY} 30 | ) 31 | -------------------------------------------------------------------------------- /cmake/SetupAdamantine.cmake: -------------------------------------------------------------------------------- 1 | message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") 2 | if(CMAKE_BUILD_TYPE MATCHES "Debug") 3 | add_compile_definitions(ADAMANTINE_DEBUG) 4 | endif() 5 | 6 | # deal.II flags override any other flags so we need to trick deal.II by 7 | # appending user's flag to deal.II's flags 8 | string(APPEND DEAL_II_CXX_FLAGS " $ENV{CXXFLAGS} ${CMAKE_CXX_FLAGS}") 9 | string(APPEND DEAL_II_CXX_FLAGS_DEBUG " ${CMAKE_CXX_FLAGS_DEBUG}") 10 | string(APPEND DEAL_II_CXX_FLAGS_RELEASE " ${CMAKE_CXX_FLAGS_RELEASE}") 11 | string(APPEND DEAL_II_LINKER_FLAGS " $ENV{LDFLAGS} ${CMAKE_EXE_LINKER_FLAGS}") 12 | set(CMAKE_CXX_FLAGS "") 13 | set(CMAKE_CXX_FLAGS_RELEASE "") 14 | set(CMAKE_CXX_FLAGS_DEBUG "") 15 | set(CMAKE_EXE_LINKER_FLAGS "") 16 | -------------------------------------------------------------------------------- /cmake/SetupDealII.cmake: -------------------------------------------------------------------------------- 1 | #### deal.II ################################################################# 2 | find_package(deal.II 9.6 REQUIRED PATHS ${DEAL_II_DIR}) 3 | 4 | deal_ii_initialize_cached_variables() 5 | 6 | set(DEAL_II_REQUIRED_FEATURES ARBORX CXX17 MPI P4EST TRILINOS) 7 | 8 | foreach(FEATURE ${DEAL_II_REQUIRED_FEATURES}) 9 | if(NOT DEAL_II_WITH_${FEATURE}) 10 | list(APPEND DEAL_II_MISSING_FEATURES ${FEATURE}) 11 | endif() 12 | endforeach() 13 | 14 | if(DEAL_II_MISSING_FEATURES) 15 | string(REPLACE ";" ", " DEAL_II_MISSING_FEATURES "${DEAL_II_MISSING_FEATURES}") 16 | message(FATAL_ERROR "deal.II wasn't configured with all required dependencies. The missing dependencies are ${DEAL_II_MISSING_FEATURES}.") 17 | endif() 18 | 19 | if(NOT DEAL_II_ARBORX_WITH_MPI) 20 | message(FATAL_ERROR "ArborX needs to be configured with MPI support.") 21 | endif() 22 | -------------------------------------------------------------------------------- /cmake/SetupTPLs.cmake: -------------------------------------------------------------------------------- 1 | #### Message Passing Interface (MPI) ######################################### 2 | find_package(MPI REQUIRED) 3 | 4 | #### Boost ################################################################### 5 | if (DEFINED BOOST_DIR) 6 | set(BOOST_ROOT ${BOOST_DIR}) 7 | endif() 8 | set(Boost_COMPONENTS 9 | chrono 10 | program_options 11 | timer 12 | unit_test_framework 13 | ) 14 | find_package(Boost 1.70.0 REQUIRED COMPONENTS ${Boost_COMPONENTS}) 15 | 16 | #### Adiak ################################################################### 17 | if (ADAMANTINE_ENABLE_ADIAK) 18 | find_package(adiak REQUIRED PATHS ${ADIAK_DIR}) 19 | add_compile_definitions(ADAMANTINE_WITH_ADIAK) 20 | message(STATUS "Found Adiak: ${adiak_DIR}") 21 | endif() 22 | 23 | #### Caliper ################################################################# 24 | if (ADAMANTINE_ENABLE_CALIPER) 25 | find_package(caliper REQUIRED PATHS ${CALIPER_DIR}) 26 | add_compile_definitions(ADAMANTINE_WITH_CALIPER) 27 | message(STATUS "Found Caliper: ${caliper_DIR}") 28 | endif() 29 | -------------------------------------------------------------------------------- /cmake/Testing.cmake: -------------------------------------------------------------------------------- 1 | function(adamantine_ADD_BOOST_TEST TEST_NAME) 2 | add_executable(${TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/${TEST_NAME}.cc ${tests_SOURCES}) 3 | target_link_libraries(${TEST_NAME} Boost::boost) 4 | target_link_libraries(${TEST_NAME} Boost::chrono) 5 | target_link_libraries(${TEST_NAME} Boost::program_options) 6 | target_link_libraries(${TEST_NAME} Boost::timer) 7 | target_link_libraries(${TEST_NAME} Boost::unit_test_framework) 8 | target_link_libraries(${TEST_NAME} MPI::MPI_CXX) 9 | target_link_libraries(${TEST_NAME} Adamantine) 10 | set_target_properties(${TEST_NAME} PROPERTIES 11 | CXX_STANDARD 17 12 | CXX_STANDARD_REQUIRED ON 13 | CXX_EXTENSIONS OFF 14 | ) 15 | DEAL_II_SETUP_TARGET(${TEST_NAME}) 16 | if(ARGN) 17 | set(NUMBER_OF_PROCESSES_TO_EXECUTE ${ARGN}) 18 | else() 19 | set(NUMBER_OF_PROCESSES_TO_EXECUTE 1) 20 | endif() 21 | foreach(NPROC ${NUMBER_OF_PROCESSES_TO_EXECUTE}) 22 | add_test( 23 | NAME ${TEST_NAME}_${NPROC} 24 | COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${NPROC} ${CMAKE_BINARY_DIR}/bin/${TEST_NAME} 25 | ) 26 | set_tests_properties(${TEST_NAME}_${NPROC} PROPERTIES 27 | PROCESSORS ${NPROC} 28 | ) 29 | endforeach() 30 | endfunction() 31 | 32 | function(adamantine_COPY_INPUT_FILE INPUT_FILE PATH_TO_FILE) 33 | add_custom_command( 34 | OUTPUT ${CMAKE_BINARY_DIR}/bin/${INPUT_FILE} 35 | DEPENDS ${CMAKE_SOURCE_DIR}/${PATH_TO_FILE}/${INPUT_FILE} 36 | COMMAND ${CMAKE_COMMAND} 37 | ARGS -E copy ${CMAKE_SOURCE_DIR}/${PATH_TO_FILE}/${INPUT_FILE} ${CMAKE_BINARY_DIR}/bin/${INPUT_FILE} 38 | COMMAND ${CMAKE_COMMAND} 39 | ARGS -E copy ${CMAKE_SOURCE_DIR}/${PATH_TO_FILE}/${INPUT_FILE} ${CMAKE_CURRENT_BINARY_DIR}/${INPUT_FILE} 40 | COMMENT "Copying ${INPUT_FILE}" 41 | ) 42 | string(REGEX REPLACE "[/@]" "_" DUMMY ${CMAKE_BINARY_DIR}/bin/${INPUT_FILE}) 43 | add_custom_target( 44 | ${DUMMY} ALL 45 | DEPENDS ${CMAKE_BINARY_DIR}/bin/${INPUT_FILE} 46 | ) 47 | endfunction() 48 | -------------------------------------------------------------------------------- /doc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Generate Doxygen documentation 2 | FIND_PACKAGE(Doxygen) 3 | 4 | CONFIGURE_FILE( 5 | ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in 6 | ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 7 | @ONLY 8 | ) 9 | 10 | ADD_CUSTOM_TARGET(documentation 11 | ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 12 | COMMENT "Generating API documentation with Doxygen" 13 | ) 14 | -------------------------------------------------------------------------------- /doc/README.md: -------------------------------------------------------------------------------- 1 | This is the documentation for adamantine developers. The user documentation can 2 | be found at https://adamantine-sim.github.io/adamantine 3 | -------------------------------------------------------------------------------- /doc/logo/adamantine_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamantine-sim/adamantine/8b60f735f459c8c977e2c81dc9fc2d29fba837c2/doc/logo/adamantine_logo.png -------------------------------------------------------------------------------- /doc/logo/adamantine_logo_with_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamantine-sim/adamantine/8b60f735f459c8c977e2c81dc9fc2d29fba837c2/doc/logo/adamantine_logo_with_bg.png -------------------------------------------------------------------------------- /doc/logo/adamantine_wordmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamantine-sim/adamantine/8b60f735f459c8c977e2c81dc9fc2d29fba837c2/doc/logo/adamantine_wordmark.png -------------------------------------------------------------------------------- /doc/logo/adamantine_wordmark_with_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamantine-sim/adamantine/8b60f735f459c8c977e2c81dc9fc2d29fba837c2/doc/logo/adamantine_wordmark_with_bg.png -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "nixpkgs": { 4 | "locked": { 5 | "lastModified": 1739758141, 6 | "narHash": "sha256-uq6A2L7o1/tR6VfmYhZWoVAwb3gTy7j4Jx30MIrH0rE=", 7 | "owner": "nixos", 8 | "repo": "nixpkgs", 9 | "rev": "c618e28f70257593de75a7044438efc1c1fc0791", 10 | "type": "github" 11 | }, 12 | "original": { 13 | "owner": "nixos", 14 | "ref": "nixos-24.11", 15 | "repo": "nixpkgs", 16 | "type": "github" 17 | } 18 | }, 19 | "root": { 20 | "inputs": { 21 | "nixpkgs": "nixpkgs", 22 | "utils": "utils" 23 | } 24 | }, 25 | "systems": { 26 | "locked": { 27 | "lastModified": 1681028828, 28 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 29 | "owner": "nix-systems", 30 | "repo": "default", 31 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 32 | "type": "github" 33 | }, 34 | "original": { 35 | "owner": "nix-systems", 36 | "repo": "default", 37 | "type": "github" 38 | } 39 | }, 40 | "utils": { 41 | "inputs": { 42 | "systems": "systems" 43 | }, 44 | "locked": { 45 | "lastModified": 1731533236, 46 | "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 47 | "owner": "numtide", 48 | "repo": "flake-utils", 49 | "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 50 | "type": "github" 51 | }, 52 | "original": { 53 | "owner": "numtide", 54 | "repo": "flake-utils", 55 | "type": "github" 56 | } 57 | } 58 | }, 59 | "root": "root", 60 | "version": 7 61 | } 62 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | ## See NIX.md for help getting started with Nix 2 | 3 | { 4 | description = "Software to simulate heat transfer for additive manufacturing"; 5 | 6 | inputs = { 7 | nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11"; 8 | utils.url = "github:numtide/flake-utils"; 9 | }; 10 | 11 | outputs = inputs @ { self, utils, ... }: utils.lib.eachDefaultSystem (system: rec { 12 | config = rec { 13 | pkgs = import inputs.nixpkgs { 14 | inherit system; 15 | inherit (import ./nix/nixpkgs/config.nix {}) overlays config; 16 | }; 17 | }; 18 | 19 | lib = with config; { 20 | callPackage = set: pkgs.lib.callPackageWith (pkgs // set); 21 | }; 22 | 23 | derivations = with config; rec { 24 | callPackage = lib.callPackage libs; 25 | 26 | libs = { 27 | adiak = callPackage ./nix/dependencies/adiak {}; 28 | caliper = callPackage ./nix/dependencies/caliper {}; 29 | arborx = callPackage ./nix/dependencies/arborx {}; 30 | 31 | dealii = let 32 | versions = rec { 33 | latest = v962; 34 | v962 = callPackage ./nix/dependencies/dealii/v9.6.2.nix { inherit callPackage; }; 35 | v952 = callPackage ./nix/dependencies/dealii/v9.5.2.nix { inherit callPackage; }; 36 | }; 37 | in (versions.latest) // { 38 | inherit versions; 39 | }; 40 | }; 41 | 42 | adamantine = let 43 | versions = rec { 44 | devel = callPackage ./nix/adamantine/common.nix { 45 | version = self.shortRev or self.dirtyShortRev; 46 | src = self; 47 | }; 48 | 49 | stable = v100; 50 | 51 | v100 = callPackage ./nix/adamantine/v1.0.0.nix { 52 | inherit callPackage; 53 | dealii = libs.dealii.versions.v952; 54 | }; 55 | }; 56 | in (versions.devel) // { 57 | inherit versions; 58 | }; 59 | }; 60 | 61 | packages = rec { 62 | default = adamantine.versions.devel; 63 | 64 | inherit (derivations) adamantine; 65 | }; 66 | 67 | devShells = with config; rec { 68 | default = adamantineDev; 69 | 70 | adamantineDev = pkgs.mkShell rec { 71 | name = "adamantine-dev"; 72 | 73 | packages = with pkgs; [ 74 | git 75 | clang-tools 76 | ninja 77 | ] ++ pkgs.lib.optionals (pkgs.stdenv.hostPlatform.isLinux) [ 78 | gdb 79 | cntr 80 | ] ++ self.outputs.packages.${system}.default.buildInputs 81 | ++ self.outputs.packages.${system}.default.nativeBuildInputs 82 | ++ self.outputs.packages.${system}.default.propagatedBuildInputs; 83 | 84 | # For dev, we want to disable hardening. 85 | hardeningDisable = [ 86 | "bindnow" 87 | "format" 88 | "fortify" 89 | "fortify3" 90 | "pic" 91 | "relro" 92 | "stackprotector" 93 | "strictoverflow" 94 | ]; 95 | 96 | # Ensure the locales point at the correct archive location. 97 | LOCALE_ARCHIVE = pkgs.lib.optional (pkgs.stdenv.hostPlatform.isLinux) ( 98 | "${pkgs.glibcLocales}/lib/locale/locale-archive" 99 | ); 100 | }; 101 | }; 102 | }); 103 | 104 | nixConfig = { 105 | extra-substituters = [ "https://mdfbaam.cachix.org" ]; 106 | extra-trusted-public-keys = [ "mdfbaam.cachix.org-1:WCQinXaMJP7Ny4sMlKdisNUyhcO2MHnPoobUef5aTmQ=" ]; 107 | }; 108 | } 109 | -------------------------------------------------------------------------------- /indent: -------------------------------------------------------------------------------- 1 | clang-format -style=file -i source/*.cc 2 | clang-format -style=file -i source/*.hh 3 | clang-format -style=file -i tests/*.cc 4 | clang-format -style=file -i application/*.cc 5 | clang-format -style=file -i application/*.hh 6 | -------------------------------------------------------------------------------- /nix/adamantine/common.nix: -------------------------------------------------------------------------------- 1 | { 2 | src, version, 3 | 4 | lib, stdenv, 5 | 6 | cmake, 7 | 8 | arborx, adiak, caliper, p4est, trilinos-mpi, boost, openmpi, dealii, 9 | 10 | doCheck ? true, 11 | 12 | # Allow extra args as needed for callPackage chaining - not ideal. 13 | ... 14 | }: 15 | 16 | stdenv.mkDerivation rec { 17 | pname = "adamantine"; 18 | inherit version; 19 | 20 | inherit src; 21 | 22 | nativeBuildInputs = [ 23 | cmake 24 | ]; 25 | 26 | buildInputs = [ 27 | arborx 28 | adiak 29 | caliper 30 | p4est 31 | trilinos-mpi 32 | boost 33 | dealii 34 | ]; 35 | 36 | propagatedBuildInputs = [ 37 | openmpi 38 | ]; 39 | 40 | cmakeFlags = [ 41 | "-DADAMANTINE_ENABLE_ADIAK=ON" 42 | "-DADAMANTINE_ENABLE_CALIPER=ON" 43 | ] ++ lib.optionals (doCheck) [ 44 | "-DADAMANTINE_ENABLE_TESTS=ON" 45 | ]; 46 | 47 | # Manual install if using versions 1.0 since adamantine was lacking CMake installs. 48 | installPhase = lib.optional (version == "1.0") '' 49 | mkdir -p $out/bin 50 | cp bin/adamantine $out/bin 51 | ''; 52 | 53 | inherit doCheck; 54 | checkPhase = '' 55 | ctest -R integration_2d 56 | ''; 57 | } 58 | 59 | -------------------------------------------------------------------------------- /nix/adamantine/v1.0.0.nix: -------------------------------------------------------------------------------- 1 | attrs @ { callPackage, fetchFromGitHub, ... }: 2 | 3 | callPackage ./common.nix ( 4 | rec { 5 | version = "1.0"; 6 | src = fetchFromGitHub { 7 | owner = "adamantine-sim"; 8 | repo = "adamantine"; 9 | rev = "v${version}"; 10 | hash = "sha256-pwwGgk4uIEOkyNLN26nRYvkzQZR53TJW14R9P99E3Ts="; 11 | }; 12 | } // attrs 13 | ) 14 | -------------------------------------------------------------------------------- /nix/dependencies/adiak/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | stdenv, fetchFromGitHub, 3 | 4 | cmake 5 | }: 6 | 7 | stdenv.mkDerivation rec { 8 | pname = "adiak"; 9 | version = "0.4.0"; 10 | 11 | src = fetchFromGitHub { 12 | owner = "LLNL"; 13 | repo = "Adiak"; 14 | rev = "v${version}"; 15 | hash = "sha256-S4ZLU6f/njdZXyoQdCJIDzpQTSmfapZiRe4zIex5f0Q="; 16 | 17 | fetchSubmodules = true; 18 | }; 19 | 20 | nativeBuildInputs = [ 21 | cmake 22 | ]; 23 | 24 | cmakeFlags = [ 25 | "-DBUILD_SHARED_LIBS=ON" 26 | "-DCMAKE_BUILD_TYPE=Release" 27 | ]; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /nix/dependencies/arborx/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | stdenv, fetchFromGitHub, 3 | 4 | cmake, 5 | 6 | openmpi, trilinos-mpi 7 | }: 8 | 9 | stdenv.mkDerivation rec { 10 | pname = "arborx"; 11 | version = "1.5"; 12 | 13 | src = fetchFromGitHub { 14 | owner = "arborx"; 15 | repo = "ArborX"; 16 | rev = "v${version}"; 17 | hash = "sha256-XhvWKex7sKACY90emvV9uGw/ACI00dLq1HoeG2nWthk="; 18 | }; 19 | 20 | nativeBuildInputs = [ 21 | cmake 22 | ]; 23 | 24 | buildInputs = [ 25 | openmpi 26 | trilinos-mpi 27 | ]; 28 | 29 | cmakeFlags = [ 30 | "-DCMAKE_BUILD_TYPE=Release" 31 | "-DBUILD_SHARED_LIBS=ON" 32 | "-DCMAKE_CXX_EXTENSIONS=OFF" 33 | "-DARBORX_ENABLE_MPI=ON" 34 | ]; 35 | } 36 | 37 | -------------------------------------------------------------------------------- /nix/dependencies/caliper/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | stdenv, fetchFromGitHub, 3 | 4 | cmake, python3, 5 | 6 | adiak, openmpi 7 | }: 8 | 9 | stdenv.mkDerivation rec { 10 | pname = "caliper"; 11 | version = "2.10.0"; 12 | 13 | src = fetchFromGitHub { 14 | owner = "LLNL"; 15 | repo = "caliper"; 16 | rev = "v${version}"; 17 | hash = "sha256-4rnPbRYtciohLnThtonTrUBO+d8vyWvJsCgoqbJI5Rg="; 18 | 19 | fetchSubmodules = true; 20 | }; 21 | 22 | nativeBuildInputs = [ 23 | cmake 24 | python3 25 | ]; 26 | 27 | buildInputs = [ 28 | adiak 29 | openmpi 30 | ]; 31 | 32 | cmakeFlags = [ 33 | "-DCMAKE_BUILD_TYPE=Release" 34 | "-DBUILD_SHARED_LIBS=ON" 35 | "-DWITH_ADIAK=ON" 36 | "-DWITH_LIBDW=ON" 37 | "-DWITH_LIBPFM=ON" 38 | "-DWITH_LIBUNWIND=ON" 39 | "-DWITH_MPI=ON" 40 | "-DWITH_SAMPLER=ON" 41 | ]; 42 | } 43 | -------------------------------------------------------------------------------- /nix/dependencies/dealii/common.nix: -------------------------------------------------------------------------------- 1 | { 2 | src, version, 3 | 4 | stdenv, 5 | 6 | cmake, 7 | 8 | openmpi, trilinos-mpi, arborx, p4est, boost, 9 | 10 | # Allow extra args as needed for callPackage chaining - not ideal. 11 | ... 12 | }: 13 | 14 | stdenv.mkDerivation rec { 15 | pname = "dealii"; 16 | inherit version; 17 | 18 | inherit src; 19 | 20 | nativeBuildInputs = [ 21 | cmake 22 | ]; 23 | 24 | buildInputs = [ 25 | openmpi 26 | trilinos-mpi 27 | arborx 28 | p4est 29 | boost 30 | ]; 31 | 32 | hardeningDisable = [ 33 | "fortify" 34 | "fortify3" 35 | ]; 36 | 37 | cmakeFlags = [ 38 | "-DCMAKE_BUILD_TYPE=DebugRelease" 39 | "-DCMAKE_CXX_STANDARD=17" 40 | "-DCMAKE_CXX_EXTENSIONS=OFF" 41 | "-DDEAL_II_WITH_TBB=OFF" 42 | "-DDEAL_II_WITH_64BIT_INDICES=ON" 43 | "-DDEAL_II_WITH_COMPLEX_VALUES=OFF" 44 | "-DDEAL_II_WITH_MPI=ON" 45 | "-DDEAL_II_WITH_P4EST=ON" 46 | "-DDEAL_II_WITH_ARBORX=ON" 47 | "-DDEAL_II_WITH_TRILINOS=ON" 48 | "-DDEAL_II_TRILINOS_WITH_SEACAS=OFF" 49 | "-DDEAL_II_COMPONENT_EXAMPLES=OFF" 50 | "-DDEAL_II_WITH_ADOLC=OFF" 51 | "-DDEAL_II_ALLOW_BUNDLED=OFF" 52 | ]; 53 | } 54 | -------------------------------------------------------------------------------- /nix/dependencies/dealii/v9.5.2.nix: -------------------------------------------------------------------------------- 1 | attrs @ { callPackage, fetchFromGitHub, ... }: 2 | 3 | callPackage ./common.nix ( 4 | rec { 5 | version = "9.5.2"; 6 | src = fetchFromGitHub { 7 | owner = "dealii"; 8 | repo = "dealii"; 9 | rev = "v${version}"; 10 | hash = "sha256-m2+1HCAkfY6w3QBT4fuz5dm7E3qurvukRf9nI6xyfpY="; 11 | }; 12 | } // attrs 13 | ) 14 | -------------------------------------------------------------------------------- /nix/dependencies/dealii/v9.6.2.nix: -------------------------------------------------------------------------------- 1 | attrs @ { callPackage, fetchFromGitHub, ... }: 2 | 3 | callPackage ./common.nix ( 4 | rec { 5 | version = "9.6.2"; 6 | src = fetchFromGitHub { 7 | owner = "dealii"; 8 | repo = "dealii"; 9 | rev = "v${version}"; 10 | hash = "sha256-sIyGSEmGc2JMKwvFRkJJLROUNdLKVhPgfUx1IfjT3dI="; 11 | }; 12 | } // attrs 13 | ) 14 | -------------------------------------------------------------------------------- /nix/nixpkgs/config.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | 3 | { 4 | overlays = [( 5 | finalPkgs: prevPkgs: { 6 | trilinos-mpi = prevPkgs.trilinos-mpi.overrideAttrs (final: prev: rec { 7 | version = "14.4.0"; 8 | 9 | preConfigure = prev.preConfigure + '' 10 | cmakeFlagsArray+=(-DTrilinos_ENABLE_ML=ON); 11 | ''; 12 | 13 | src = prev.src.override { 14 | rev = "${prev.pname}-release-${prevPkgs.lib.replaceStrings [ "." ] [ "-" ] version}"; 15 | sha256 = "sha256-jbXQYEyf/p9F2I/I7jP+0/6OOcH5ArFlUk6LHn453qY="; 16 | }; 17 | }); 18 | } 19 | )]; 20 | 21 | config = { 22 | allowUnfree = true; 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /source/BeamHeatSourceProperties.hh: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2016 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #ifndef BEAM_HEAT_SOURCE_PROPERTIES_HH 6 | #define BEAM_HEAT_SOURCE_PROPERTIES_HH 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | 14 | namespace adamantine 15 | { 16 | /** 17 | * This class stores all the physical properties necessary to define an 18 | * beam heat source. 19 | */ 20 | class BeamHeatSourceProperties 21 | { 22 | public: 23 | BeamHeatSourceProperties() = default; 24 | 25 | /** 26 | * Constructor. 27 | * \param[in] beam_database requires the following entries: 28 | * - absorption_efficiency: double in \f$[0,1]\f$ 29 | * - depth: double in \f$[0,\infty)\f$ 30 | * - diameter: double in \f$[0,\infty)\f$ 31 | * - max_power: double in \f$[0, \infty)\f$ 32 | * \param[in] units_optional_database can have the following entries: 33 | * - heat_source.dimension 34 | * - heat_source.power 35 | */ 36 | BeamHeatSourceProperties( 37 | boost::property_tree::ptree const &beam_database, 38 | boost::optional const 39 | &units_optional_database) 40 | { 41 | if (units_optional_database) 42 | { 43 | auto unit_database = units_optional_database.get(); 44 | // PropertyTreeInput units.heat_source.dimension 45 | std::string unit = unit_database.get("heat_source.dimension", "meter"); 46 | _dimension_scaling = g_unit_scaling_factor[unit]; 47 | // PropertyTreeInput units.heat_source.power 48 | unit = unit_database.get("heat_source.power", "watt"); 49 | _power_scaling = g_unit_scaling_factor[unit]; 50 | } 51 | 52 | set_from_database(beam_database); 53 | } 54 | 55 | void set_from_database(boost::property_tree::ptree const &database) 56 | { 57 | // PropertyTreeInput sources.beam_X.depth 58 | depth = database.get("depth") * _dimension_scaling; 59 | // PropertyTreeInput sources.beam_X.absorption_efficiency 60 | absorption_efficiency = database.get("absorption_efficiency"); 61 | // PropertyTreeInput sources.beam_X.diameter 62 | radius = database.get("diameter") * _dimension_scaling / 2.0; 63 | radius_squared = std::pow(radius, 2); 64 | // PropertyTreeInput sources.beam_X.max_power 65 | max_power = database.get("max_power") * _power_scaling; 66 | } 67 | 68 | /** 69 | * A metric of the depth of the heat source into the material. The specific 70 | * definition of the depth may differ across heat source types. 71 | */ 72 | double depth = 0.; 73 | /** 74 | * Energy conversion efficiency on the surface. 75 | */ 76 | double absorption_efficiency = 0.; 77 | /** 78 | * Beam radius. 79 | */ 80 | double radius = 0.; 81 | /** 82 | * Square of the beam radius. 83 | */ 84 | double radius_squared = 0.; 85 | /** 86 | * Maximum power of the beam. 87 | */ 88 | double max_power = 0.; 89 | 90 | private: 91 | /** 92 | * Scaling factor for the dimension of the heat source. 93 | */ 94 | double _dimension_scaling = 1.; 95 | /** 96 | * Scaling factor for the power of the heat source. 97 | */ 98 | double _power_scaling = 1.; 99 | }; 100 | } // namespace adamantine 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /source/BodyForce.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2023 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | namespace adamantine 10 | { 11 | template 13 | GravityForce::GravityForce( 14 | MaterialProperty 15 | &material_properties) 16 | : _material_properties(material_properties) 17 | { 18 | } 19 | 20 | template 22 | dealii::Tensor<1, dim, double> 23 | GravityForce::eval( 24 | typename dealii::Triangulation::active_cell_iterator const &cell) 25 | { 26 | // Note that the density is independent of the temperature 27 | double density = _material_properties.get_mechanical_property( 28 | cell, StateProperty::density_s); 29 | dealii::Tensor<1, dim, double> body_force; 30 | body_force[axis::z] = -density * g; 31 | 32 | return body_force; 33 | } 34 | } // namespace adamantine 35 | 36 | INSTANTIATE_DIM_PORDER_MATERIALSTATES_HOST(TUPLE(GravityForce)) 37 | INSTANTIATE_DIM_PORDER_MATERIALSTATES_DEVICE(TUPLE(GravityForce)) 38 | -------------------------------------------------------------------------------- /source/BodyForce.hh: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2023 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #ifndef BODY_FORCE_HH 6 | #define BODY_FORCE_HH 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace adamantine 13 | { 14 | /** 15 | * Base class that describes the interface that body forces need to implement. 16 | */ 17 | template 18 | struct BodyForce 19 | { 20 | /** 21 | * Evaluate the body force given a cell. 22 | */ 23 | virtual dealii::Tensor<1, dim, double> 24 | eval(typename dealii::Triangulation::active_cell_iterator const 25 | &cell) = 0; 26 | }; 27 | 28 | // Forward declaration 29 | template 31 | class MaterialProperty; 32 | 33 | /** 34 | * Gravity's body force. 35 | */ 36 | template 38 | class GravityForce final : public BodyForce 39 | { 40 | public: 41 | GravityForce(MaterialProperty 42 | &material_properties); 43 | 44 | dealii::Tensor<1, dim, double> 45 | eval(typename dealii::Triangulation::active_cell_iterator const &cell) 46 | final; 47 | 48 | private: 49 | /** 50 | * Gravity in \f$m/s^2\f$ 51 | */ 52 | static double constexpr g = 9.80665; 53 | MaterialProperty 54 | &_material_properties; 55 | }; 56 | } // namespace adamantine 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /source/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(Adamantine_HEADERS 2 | ${CMAKE_CURRENT_SOURCE_DIR}/BeamHeatSourceProperties.hh 3 | ${CMAKE_CURRENT_SOURCE_DIR}/BodyForce.hh 4 | ${CMAKE_CURRENT_SOURCE_DIR}/CubeHeatSource.hh 5 | ${CMAKE_CURRENT_SOURCE_DIR}/DataAssimilator.hh 6 | ${CMAKE_CURRENT_SOURCE_DIR}/ElectronBeamHeatSource.hh 7 | ${CMAKE_CURRENT_SOURCE_DIR}/ExperimentalData.hh 8 | ${CMAKE_CURRENT_SOURCE_DIR}/Geometry.hh 9 | ${CMAKE_CURRENT_SOURCE_DIR}/GoldakHeatSource.hh 10 | ${CMAKE_CURRENT_SOURCE_DIR}/HeatSource.hh 11 | ${CMAKE_CURRENT_SOURCE_DIR}/ImplicitOperator.hh 12 | ${CMAKE_CURRENT_SOURCE_DIR}/MaterialProperty.hh 13 | ${CMAKE_CURRENT_SOURCE_DIR}/MaterialProperty.templates.hh 14 | ${CMAKE_CURRENT_SOURCE_DIR}/MaterialStates.hh 15 | ${CMAKE_CURRENT_SOURCE_DIR}/MechanicalOperator.hh 16 | ${CMAKE_CURRENT_SOURCE_DIR}/MechanicalPhysics.hh 17 | ${CMAKE_CURRENT_SOURCE_DIR}/Microstructure.hh 18 | ${CMAKE_CURRENT_SOURCE_DIR}/NewtonSolver.hh 19 | ${CMAKE_CURRENT_SOURCE_DIR}/Operator.hh 20 | ${CMAKE_CURRENT_SOURCE_DIR}/PointCloud.hh 21 | ${CMAKE_CURRENT_SOURCE_DIR}/PostProcessor.hh 22 | ${CMAKE_CURRENT_SOURCE_DIR}/RayTracing.hh 23 | ${CMAKE_CURRENT_SOURCE_DIR}/ScanPath.hh 24 | ${CMAKE_CURRENT_SOURCE_DIR}/ThermalOperatorBase.hh 25 | ${CMAKE_CURRENT_SOURCE_DIR}/ThermalOperator.hh 26 | ${CMAKE_CURRENT_SOURCE_DIR}/ThermalOperator.templates.hh 27 | ${CMAKE_CURRENT_SOURCE_DIR}/ThermalOperatorDevice.hh 28 | ${CMAKE_CURRENT_SOURCE_DIR}/ThermalOperatorDevice.templates.hh 29 | ${CMAKE_CURRENT_SOURCE_DIR}/ThermalPhysicsInterface.hh 30 | ${CMAKE_CURRENT_SOURCE_DIR}/ThermalPhysics.hh 31 | ${CMAKE_CURRENT_SOURCE_DIR}/ThermalPhysics.templates.hh 32 | ${CMAKE_CURRENT_SOURCE_DIR}/Timer.hh 33 | ${CMAKE_CURRENT_SOURCE_DIR}/ensemble_management.hh 34 | ${CMAKE_CURRENT_SOURCE_DIR}/experimental_data_utils.hh 35 | ${CMAKE_CURRENT_SOURCE_DIR}/material_deposition.hh 36 | ${CMAKE_CURRENT_SOURCE_DIR}/utils.hh 37 | ${CMAKE_CURRENT_SOURCE_DIR}/types.hh 38 | ${CMAKE_CURRENT_SOURCE_DIR}/validate_input_database.hh 39 | ) 40 | set(Adamantine_SOURCES 41 | ${CMAKE_CURRENT_SOURCE_DIR}/BodyForce.cc 42 | ${CMAKE_CURRENT_SOURCE_DIR}/CubeHeatSource.cc 43 | ${CMAKE_CURRENT_SOURCE_DIR}/DataAssimilator.cc 44 | ${CMAKE_CURRENT_SOURCE_DIR}/ElectronBeamHeatSource.cc 45 | ${CMAKE_CURRENT_SOURCE_DIR}/Geometry.cc 46 | ${CMAKE_CURRENT_SOURCE_DIR}/GoldakHeatSource.cc 47 | ${CMAKE_CURRENT_SOURCE_DIR}/ImplicitOperator.cc 48 | ${CMAKE_CURRENT_SOURCE_DIR}/MaterialPropertyInstDev.cc 49 | ${CMAKE_CURRENT_SOURCE_DIR}/MaterialPropertyInstHost.cc 50 | ${CMAKE_CURRENT_SOURCE_DIR}/MechanicalOperator.cc 51 | ${CMAKE_CURRENT_SOURCE_DIR}/MechanicalPhysics.cc 52 | ${CMAKE_CURRENT_SOURCE_DIR}/Microstructure.cc 53 | ${CMAKE_CURRENT_SOURCE_DIR}/NewtonSolver.cc 54 | ${CMAKE_CURRENT_SOURCE_DIR}/PointCloud.cc 55 | ${CMAKE_CURRENT_SOURCE_DIR}/PostProcessor.cc 56 | ${CMAKE_CURRENT_SOURCE_DIR}/RayTracing.cc 57 | ${CMAKE_CURRENT_SOURCE_DIR}/ScanPath.cc 58 | ${CMAKE_CURRENT_SOURCE_DIR}/ThermalOperatorInstSHost.cc 59 | ${CMAKE_CURRENT_SOURCE_DIR}/ThermalOperatorInstSLHost.cc 60 | ${CMAKE_CURRENT_SOURCE_DIR}/ThermalOperatorInstSLPHost.cc 61 | ${CMAKE_CURRENT_SOURCE_DIR}/ThermalOperatorDeviceInstSDev.cc 62 | ${CMAKE_CURRENT_SOURCE_DIR}/ThermalOperatorDeviceInstSLDev.cc 63 | ${CMAKE_CURRENT_SOURCE_DIR}/ThermalOperatorDeviceInstSLPDev.cc 64 | ${CMAKE_CURRENT_SOURCE_DIR}/ThermalPhysicsInstSDev.cc 65 | ${CMAKE_CURRENT_SOURCE_DIR}/ThermalPhysicsInstSLDev.cc 66 | ${CMAKE_CURRENT_SOURCE_DIR}/ThermalPhysicsInstSLPDev.cc 67 | ${CMAKE_CURRENT_SOURCE_DIR}/ThermalPhysicsInstSHost.cc 68 | ${CMAKE_CURRENT_SOURCE_DIR}/ThermalPhysicsInstSLHost.cc 69 | ${CMAKE_CURRENT_SOURCE_DIR}/ThermalPhysicsInstSLPHost.cc 70 | ${CMAKE_CURRENT_SOURCE_DIR}/Timer.cc 71 | ${CMAKE_CURRENT_SOURCE_DIR}/ensemble_management.cc 72 | ${CMAKE_CURRENT_SOURCE_DIR}/experimental_data_utils.cc 73 | ${CMAKE_CURRENT_SOURCE_DIR}/material_deposition.cc 74 | ${CMAKE_CURRENT_SOURCE_DIR}/validate_input_database.cc 75 | ) 76 | 77 | add_library(${PROJECT_NAME} OBJECT) 78 | target_sources(${PROJECT_NAME} PRIVATE ${Adamantine_SOURCES}) 79 | target_sources(${PROJECT_NAME} PUBLIC FILE_SET HEADERS FILES ${Adamantine_HEADERS}) 80 | 81 | DEAL_II_SETUP_TARGET(${PROJECT_NAME}) 82 | 83 | set_target_properties(${PROJECT_NAME} PROPERTIES 84 | CXX_STANDARD 17 85 | CXX_STANDARD_REQUIRED ON 86 | CXX_EXTENSIONS OFF 87 | ) 88 | 89 | target_link_libraries(${PROJECT_NAME} Boost::boost) 90 | target_link_libraries(${PROJECT_NAME} Boost::chrono) 91 | target_link_libraries(${PROJECT_NAME} Boost::program_options) 92 | target_link_libraries(${PROJECT_NAME} MPI::MPI_CXX) 93 | if (ADAMANTINE_ENABLE_CALIPER) 94 | target_link_libraries(${PROJECT_NAME} caliper) 95 | endif() 96 | 97 | 98 | -------------------------------------------------------------------------------- /source/CubeHeatSource.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2020 - 2025, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | namespace adamantine 10 | { 11 | template 12 | CubeHeatSource::CubeHeatSource( 13 | boost::property_tree::ptree const &source_database, 14 | boost::optional const 15 | &units_optional_database) 16 | : HeatSource() 17 | { 18 | double dimension_scaling = 1.; 19 | double power_scaling = 1.; 20 | if (units_optional_database) 21 | { 22 | auto const &database = units_optional_database.get(); 23 | // PropertyTreeInput units.scan_path_distance 24 | std::string unit = database.get("heat_source.dimension", "meter"); 25 | dimension_scaling = g_unit_scaling_factor[unit]; 26 | // PropertyTreeInput units.heat_source.power 27 | unit = database.get("heat_source.power", "watt"); 28 | power_scaling = g_unit_scaling_factor[unit]; 29 | } 30 | 31 | _start_time = source_database.get("start_time"); 32 | _end_time = source_database.get("end_time"); 33 | _value = source_database.get("value") * power_scaling; 34 | _min_point[0] = source_database.get("min_x") * dimension_scaling; 35 | _max_point[0] = source_database.get("max_x") * dimension_scaling; 36 | _min_point[1] = source_database.get("min_y") * dimension_scaling; 37 | _max_point[1] = source_database.get("max_y") * dimension_scaling; 38 | if constexpr (dim == 3) 39 | { 40 | _min_point[2] = source_database.get("min_z") * dimension_scaling; 41 | _max_point[2] = source_database.get("max_z") * dimension_scaling; 42 | } 43 | } 44 | 45 | template 46 | void CubeHeatSource::update_time(double time) 47 | { 48 | _source_on = ((time > _start_time) && (time < _end_time)); 49 | } 50 | 51 | template 52 | double CubeHeatSource::value(dealii::Point const &point, 53 | double const /*height*/) const 54 | { 55 | if (_source_on) 56 | { 57 | bool in_source = true; 58 | for (int i = 0; i < dim; ++i) 59 | { 60 | if ((point[i] < _min_point[i]) || (point[i] > _max_point[i])) 61 | { 62 | in_source = false; 63 | break; 64 | } 65 | } 66 | 67 | if (in_source) 68 | return _value; 69 | } 70 | 71 | return 0.; 72 | } 73 | 74 | template 75 | dealii::VectorizedArray CubeHeatSource::value( 76 | dealii::Point> const &points, 77 | dealii::VectorizedArray const & /*height*/) const 78 | { 79 | dealii::VectorizedArray mask = 0.; 80 | 81 | if (_source_on) 82 | { 83 | for (unsigned int j = 0; j < points[0].size(); ++j) 84 | { 85 | if constexpr (dim == 2) 86 | { 87 | if ((points[0][j] >= _min_point[0]) && 88 | (points[0][j] <= _max_point[0]) && 89 | (points[1][j] >= _min_point[1]) && (points[1][j] <= _max_point[1])) 90 | { 91 | mask[j] = 1.; 92 | } 93 | } 94 | if constexpr (dim == 3) 95 | { 96 | if ((points[0][j] >= _min_point[0]) && 97 | (points[0][j] <= _max_point[0]) && 98 | (points[1][j] >= _min_point[1]) && 99 | (points[1][j] <= _max_point[1]) && 100 | (points[2][j] >= _min_point[2]) && (points[2][j] <= _max_point[2])) 101 | { 102 | mask[j] = 1.; 103 | } 104 | } 105 | } 106 | } 107 | 108 | return mask * _value; 109 | } 110 | 111 | template 112 | double CubeHeatSource::get_current_height(double const /*time*/) const 113 | { 114 | return _max_point[axis::z]; 115 | } 116 | 117 | template 118 | dealii::BoundingBox 119 | CubeHeatSource::get_bounding_box(double const /*scaling_factor*/) const 120 | { 121 | if constexpr (dim == 2) 122 | { 123 | return {{{_min_point[0], _min_point[1]}, {_max_point[0], _max_point[1]}}}; 124 | } 125 | else 126 | { 127 | return {{{_min_point[0], _min_point[1], _min_point[2]}, 128 | {_max_point[0], _max_point[1], _max_point[2]}}}; 129 | } 130 | } 131 | 132 | } // namespace adamantine 133 | 134 | INSTANTIATE_DIM(CubeHeatSource) 135 | -------------------------------------------------------------------------------- /source/CubeHeatSource.hh: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2020 - 2025, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #ifndef CUBE_HEAT_SOURCE_HH 6 | #define CUBE_HEAT_SOURCE_HH 7 | 8 | #include 9 | 10 | namespace adamantine 11 | { 12 | /** 13 | * Cube heat source. This source does not represent a physical source, it is 14 | * used for verification purpose. 15 | */ 16 | template 17 | class CubeHeatSource final : public HeatSource 18 | { 19 | public: 20 | /** 21 | * Constructor. 22 | * \param[in] source_database requires the following entries: 23 | * - start_time: double (when the source is turned on) 24 | * - end_time: double (when the source is turned off) 25 | * - value: double (value of the soruce) 26 | * - min_x: double (minimum x coordinate of the cube) 27 | * - max_x: double (maximum x coordinate of the cube) 28 | * - min_y: double (minimum y coordinate of the cube) 29 | * - max_y: double (maximum y coordinate of the cube) 30 | * - min_z: double (3D only, minimum z coordinate of the cube) 31 | * - max_z: double (3D only, maximum z coordinate of the cube) 32 | * \param[in] units_optional_database may have the following entries: 33 | * - heat_source.dimension 34 | * - heat_source.power 35 | */ 36 | CubeHeatSource(boost::property_tree::ptree const &source_database, 37 | boost::optional const 38 | &units_optional_database); 39 | 40 | /** 41 | * Set the time variable. 42 | */ 43 | void update_time(double time) final; 44 | 45 | /** 46 | * Return the value of the source for a given point and time. 47 | */ 48 | double value(dealii::Point const &point, 49 | double const /*height*/) const final; 50 | 51 | /** 52 | * Same function as above but it uses vectorized data. 53 | */ 54 | dealii::VectorizedArray 55 | value(dealii::Point> const &points, 56 | dealii::VectorizedArray const & /*height*/) const final; 57 | 58 | /** 59 | * Compute the current height of the where the heat source meets the material 60 | * (i.e. the current scan path height). 61 | */ 62 | double get_current_height(double const time) const final; 63 | 64 | dealii::BoundingBox 65 | get_bounding_box(double const scaling_factor) const final; 66 | 67 | private: 68 | bool _source_on = false; 69 | double _start_time; 70 | double _end_time; 71 | double _value; 72 | dealii::Point _min_point; 73 | dealii::Point _max_point; 74 | }; 75 | } // namespace adamantine 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /source/ElectronBeamHeatSource.hh: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2020 - 2025, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #ifndef ELECTRON_BEAM_HEAT_SOURCE_HH 6 | #define ELECTRON_BEAM_HEAT_SOURCE_HH 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace adamantine 13 | { 14 | /** 15 | * A derived class from HeatSource for a model of an electron beam heat source. 16 | * The form of the heat source model is taken from the following reference: 17 | * Raghavan et al, Acta Materilia, 112, 2016, pp 303-314. 18 | */ 19 | template 20 | class ElectronBeamHeatSource final : public HeatSource 21 | { 22 | public: 23 | /** 24 | * Constructor. 25 | * \param[in] beam_database requires the following entries: 26 | * - absorption_efficiency: double in \f$[0,1]\f$ 27 | * - depth: double in \f$[0,\infty)\f$ 28 | * - diameter: double in \f$[0,\infty)\f$ 29 | * - max_power: double in \f$[0, \infty)\f$ 30 | * - input_file: name of the file that contains the scan path 31 | * segments 32 | * \param[in] units_optional_database may have the following entries: 33 | * - heat_source.dimension 34 | * - heat_source.power 35 | */ 36 | ElectronBeamHeatSource( 37 | boost::property_tree::ptree const &beam_database, 38 | boost::optional const 39 | &units_optional_database); 40 | 41 | /** 42 | * Set the time variable. 43 | */ 44 | void update_time(double time) final; 45 | 46 | /** 47 | * Returns the value of an electron beam heat source at a specified point and 48 | * time. 49 | */ 50 | double value(dealii::Point const &point, 51 | double const height) const final; 52 | 53 | /** 54 | * Same function as above but it uses vectorized data. 55 | */ 56 | dealii::VectorizedArray 57 | value(dealii::Point> const &points, 58 | dealii::VectorizedArray const &height) const final; 59 | 60 | dealii::BoundingBox 61 | get_bounding_box(double const scaling_factor) const final; 62 | 63 | private: 64 | dealii::Point<3, dealii::VectorizedArray> _beam_center; 65 | dealii::VectorizedArray _alpha = 66 | std::numeric_limits::signaling_NaN(); 67 | dealii::VectorizedArray _depth = 68 | std::numeric_limits::signaling_NaN(); 69 | dealii::VectorizedArray _radius_squared = 70 | std::numeric_limits::signaling_NaN(); 71 | double const _log_01 = std::log(0.1); 72 | }; 73 | } // namespace adamantine 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /source/ExperimentalData.hh: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2023 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #ifndef EXPERIMENTAL_DATA_HH 6 | #define EXPERIMENTAL_DATA_HH 7 | 8 | #include 9 | 10 | namespace adamantine 11 | { 12 | /** 13 | * Base class that describes the interfaces of classes that manipulate 14 | * experimental data. 15 | */ 16 | template 17 | class ExperimentalData 18 | { 19 | public: 20 | virtual ~ExperimentalData() = default; 21 | 22 | /** 23 | * Read data from the next frame and return the frame ID. 24 | */ 25 | virtual unsigned int read_next_frame() = 0; 26 | 27 | /** 28 | * Return the Points and their associated value (temperature). 29 | */ 30 | virtual PointsValues get_points_values() = 0; 31 | }; 32 | 33 | } // namespace adamantine 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /source/Geometry.hh: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2016 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #ifndef GEOMETRY_HH 6 | #define GEOMETRY_HH 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace adamantine 13 | { 14 | /** 15 | * This class generates and stores a Triangulation given a database. 16 | */ 17 | template 18 | class Geometry 19 | { 20 | public: 21 | /** 22 | * Constructor. 23 | */ 24 | Geometry(MPI_Comm const &communicator, 25 | boost::property_tree::ptree const &database, 26 | boost::optional const 27 | &units_optional_database); 28 | 29 | /** 30 | * Return the underlying Triangulation. 31 | */ 32 | dealii::parallel::distributed::Triangulation &get_triangulation(); 33 | 34 | private: 35 | /** 36 | * Triangulation of the domain. 37 | */ 38 | dealii::parallel::distributed::Triangulation _triangulation; 39 | 40 | /** 41 | * Assign the material state to the mesh. 42 | */ 43 | void assign_material_state(boost::property_tree::ptree const &database); 44 | }; 45 | 46 | template 47 | inline dealii::parallel::distributed::Triangulation & 48 | Geometry::get_triangulation() 49 | { 50 | return _triangulation; 51 | } 52 | } // namespace adamantine 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /source/GoldakHeatSource.hh: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2020 - 2025, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #ifndef GOLDAK_HEAT_SOURCE_HH 6 | #define GOLDAK_HEAT_SOURCE_HH 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace adamantine 13 | { 14 | /** 15 | * A derived class from HeatSource for the Goldak model of a laser heat source. 16 | * The form of the heat source model is taken from the following reference: 17 | * Coleman et al, Journal of Heat Transfer, (in press, 2020). 18 | */ 19 | template 20 | class GoldakHeatSource final : public HeatSource 21 | { 22 | public: 23 | /** 24 | * Constructor. 25 | * \param[in] beam_database requires the following entries: 26 | * - absorption_efficiency: double in \f$[0,1]\f$ 27 | * - depth: double in \f$[0,\infty)\f$ 28 | * - diameter: double in \f$[0,\infty)\f$ 29 | * - max_power: double in \f$[0, \infty)\f$ 30 | * - input_file: name of the file that contains the scan path 31 | * segments 32 | * \param[in] units_optional_database may contain the following entries: 33 | * - heat_source.dimension 34 | * - heat_source.power 35 | */ 36 | GoldakHeatSource(boost::property_tree::ptree const &beam_database, 37 | boost::optional const 38 | &units_optional_database); 39 | 40 | /** 41 | * Set the time variable. 42 | */ 43 | void update_time(double time) final; 44 | 45 | /** 46 | * Returns the value of a Goldak heat source at a specified point and 47 | * time. 48 | */ 49 | double value(dealii::Point const &point, 50 | double const height) const final; 51 | 52 | /** 53 | * Same function as above but it uses vectorized data. 54 | */ 55 | dealii::VectorizedArray 56 | value(dealii::Point> const &points, 57 | dealii::VectorizedArray const &height) const final; 58 | 59 | dealii::BoundingBox 60 | get_bounding_box(double const scaling_factor) const final; 61 | 62 | private: 63 | dealii::Point<3, dealii::VectorizedArray> _beam_center; 64 | dealii::VectorizedArray _alpha = 65 | std::numeric_limits::signaling_NaN(); 66 | dealii::VectorizedArray _depth = 67 | std::numeric_limits::signaling_NaN(); 68 | dealii::VectorizedArray _radius_squared = 69 | std::numeric_limits::signaling_NaN(); 70 | double const _pi_over_3_to_1p5 = std::pow(dealii::numbers::PI / 3.0, 1.5); 71 | }; 72 | } // namespace adamantine 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /source/HeatSource.hh: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2020 - 2025, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #ifndef HEAT_SOURCE_HH 6 | #define HEAT_SOURCE_HH 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | namespace adamantine 17 | { 18 | /** 19 | * This is the base class for describing the functional form of a heat 20 | * source. It has a pure virtual "value" method that needs to be implemented in 21 | * a derived class. 22 | * NOTE: The coordinate system in this class is different than 23 | * for the finite element mesh. In this class, the first two components of a 24 | * dealii::Point<3> describe the position along the surface of the part. The 25 | * last component is the height through the thickness of the part from the base 26 | * plate. This is in opposition to the finite element mesh where the first and 27 | * last components of a dealii::Point<3> describe the position along the surface 28 | * of the part, and the second component is the thickness. That is, the last two 29 | * components are swapped between the two coordinate systems. 30 | */ 31 | template 32 | class HeatSource 33 | { 34 | public: 35 | /** 36 | * Default constructor. This constructor should only be used for non-beam heat 37 | * source. 38 | */ 39 | HeatSource() = default; 40 | 41 | /** 42 | * Constructor. 43 | * \param[in] beam_database requires the following entries: 44 | * - absorption_efficiency: double in \f$[0,1]\f$ 45 | * - depth: double in \f$[0,\infty)\f$ 46 | * - diameter: double in \f$[0,\infty)\f$ 47 | * - max_power: double in \f$[0, \infty)\f$ 48 | * - input_file: name of the file that contains the scan path 49 | * segments 50 | * \param[in] units_optional_database may contain the following entries: 51 | * - heat_source.dimension 52 | * - heat_source.power 53 | */ 54 | HeatSource(boost::property_tree::ptree const &beam_database, 55 | boost::optional const 56 | &units_optional_database) 57 | : _beam(beam_database, units_optional_database), 58 | // PropertyTreeInput sources.beam_X.scan_path_file 59 | // PropertyTreeInput sources.beam_X.scan_path_format 60 | _scan_path(beam_database.get("scan_path_file"), 61 | beam_database.get("scan_path_file_format"), 62 | units_optional_database) 63 | { 64 | } 65 | 66 | /** 67 | * Destructor. 68 | */ 69 | virtual ~HeatSource() = default; 70 | 71 | /** 72 | * Set the time variable. 73 | */ 74 | virtual void update_time(double time) = 0; 75 | 76 | /** 77 | * Compute the heat source at a given point at a given time given the current 78 | * height of the object being manufactured. 79 | */ 80 | virtual double value(dealii::Point const &points, 81 | double const height) const = 0; 82 | 83 | /** 84 | * Same function as above but it uses vectorized data. 85 | */ 86 | virtual dealii::VectorizedArray 87 | value(dealii::Point> const &points, 88 | dealii::VectorizedArray const &height) const = 0; 89 | /** 90 | * Return the scan path for the heat source. 91 | */ 92 | virtual ScanPath &get_scan_path(); 93 | 94 | /** 95 | * Compute the current height of the where the heat source meets the material 96 | * (i.e. the current scan path height). 97 | */ 98 | virtual double get_current_height(double const time) const; 99 | 100 | /** 101 | * (Re)sets the BeamHeatSourceProperties member variable, necessary if the 102 | * beam parameters vary in time (e.g. due to data assimilation). 103 | */ 104 | virtual void set_beam_properties(boost::property_tree::ptree const &database); 105 | 106 | /** 107 | * Return a scaled bounding box of the heat source. 108 | */ 109 | virtual dealii::BoundingBox 110 | get_bounding_box(double const scaling_factor) const = 0; 111 | 112 | protected: 113 | /** 114 | * Structure of the physical properties of the beam heat source. 115 | */ 116 | BeamHeatSourceProperties _beam; 117 | 118 | /** 119 | * The scan path for the heat source. 120 | */ 121 | ScanPath _scan_path; 122 | }; 123 | 124 | template 125 | inline ScanPath &HeatSource::get_scan_path() 126 | { 127 | return _scan_path; 128 | } 129 | 130 | template 131 | inline double HeatSource::get_current_height(double const time) const 132 | { 133 | return _scan_path.value(time)[2]; 134 | } 135 | 136 | template 137 | inline void HeatSource::set_beam_properties( 138 | boost::property_tree::ptree const &database) 139 | { 140 | _beam.set_from_database(database); 141 | } 142 | 143 | } // namespace adamantine 144 | 145 | #endif 146 | -------------------------------------------------------------------------------- /source/ImplicitOperator.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2016 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | namespace adamantine 10 | { 11 | template 12 | ImplicitOperator::ImplicitOperator( 13 | std::shared_ptr> explicit_operator, bool jfnk) 14 | : _jfnk(jfnk), _explicit_operator(explicit_operator) 15 | { 16 | } 17 | 18 | template 19 | void ImplicitOperator::vmult( 20 | dealii::LA::distributed::Vector &dst, 21 | dealii::LA::distributed::Vector const &src) const 22 | { 23 | if (_jfnk == true) 24 | { 25 | dealii::LA::distributed::Vector tmp_dst( 26 | dst.get_partitioner()); 27 | dealii::LA::distributed::Vector tmp_src(src); 28 | tmp_src *= (1. + 1e-10); 29 | _explicit_operator->vmult(dst, tmp_src); 30 | _explicit_operator->vmult(tmp_dst, src); 31 | dst -= tmp_dst; 32 | dst /= 1e-10; 33 | } 34 | else 35 | _explicit_operator->jacobian_vmult(dst, src); 36 | 37 | dst.scale(*_inverse_mass_matrix); 38 | dst *= -_tau; 39 | dst += src; 40 | } 41 | 42 | template 43 | void ImplicitOperator::Tvmult( 44 | dealii::LA::distributed::Vector & /*dst*/, 45 | dealii::LA::distributed::Vector const & /*src*/) 46 | const 47 | { 48 | ASSERT_THROW_NOT_IMPLEMENTED(); 49 | } 50 | 51 | template 52 | void ImplicitOperator::vmult_add( 53 | dealii::LA::distributed::Vector & /*dst*/, 54 | dealii::LA::distributed::Vector const & /*src*/) 55 | const 56 | { 57 | ASSERT_THROW_NOT_IMPLEMENTED(); 58 | } 59 | 60 | template 61 | void ImplicitOperator::Tvmult_add( 62 | dealii::LA::distributed::Vector & /*dst*/, 63 | dealii::LA::distributed::Vector const & /*src*/) 64 | const 65 | { 66 | ASSERT_THROW_NOT_IMPLEMENTED(); 67 | } 68 | 69 | // Instantiation 70 | template class ImplicitOperator; 71 | template class ImplicitOperator; 72 | } // namespace adamantine 73 | -------------------------------------------------------------------------------- /source/ImplicitOperator.hh: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2016 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #ifndef IMPLICIT_OPERATOR_HH 6 | #define IMPLICIT_OPERATOR_HH 7 | 8 | #include "Operator.hh" 9 | 10 | namespace adamantine 11 | { 12 | /** 13 | * This class uses an operator \f$F\f$ and creates an operator 14 | * \f$I-\tau M^{-1} \frac{F}{dy}\f$. This operator is then inverted when using 15 | * an implicit time stepping scheme. 16 | */ 17 | template 18 | class ImplicitOperator : public Operator 19 | { 20 | public: 21 | ImplicitOperator(std::shared_ptr> explicit_operator, 22 | bool jfnk); 23 | 24 | dealii::types::global_dof_index m() const override; 25 | 26 | dealii::types::global_dof_index n() const override; 27 | 28 | void vmult(dealii::LA::distributed::Vector &dst, 29 | dealii::LA::distributed::Vector const 30 | &src) const override; 31 | 32 | void Tvmult(dealii::LA::distributed::Vector &dst, 33 | dealii::LA::distributed::Vector const 34 | &src) const override; 35 | 36 | void vmult_add(dealii::LA::distributed::Vector &dst, 37 | dealii::LA::distributed::Vector const 38 | &src) const override; 39 | 40 | void Tvmult_add(dealii::LA::distributed::Vector &dst, 41 | dealii::LA::distributed::Vector const 42 | &src) const override; 43 | 44 | /** 45 | * Set the parameter \f$\tau\f$ defined by the Runge-Kutta method. 46 | */ 47 | void set_tau(double tau); 48 | 49 | /** 50 | * Set the shared pointer of the inverse of the mass matrix. 51 | */ 52 | void set_inverse_mass_matrix( 53 | std::shared_ptr> 54 | inverse_mass_matrix); 55 | 56 | private: 57 | /** 58 | * Flag to switch between Jacobian-Free Newton Krylov method and exact 59 | * Jacobian method. 60 | */ 61 | bool _jfnk; 62 | /** 63 | * Parameter of the Runge-Kutta method used. 64 | */ 65 | double _tau; 66 | /** 67 | * Shared pointer of the inverse of the mass matrix. 68 | */ 69 | std::shared_ptr> 70 | _inverse_mass_matrix; 71 | /** 72 | * Shared pointer of the operator \f$F\f$. 73 | */ 74 | std::shared_ptr> _explicit_operator; 75 | }; 76 | 77 | template 78 | inline dealii::types::global_dof_index 79 | ImplicitOperator::m() const 80 | { 81 | return _explicit_operator->m(); 82 | } 83 | 84 | template 85 | inline dealii::types::global_dof_index 86 | ImplicitOperator::n() const 87 | { 88 | return _explicit_operator->n(); 89 | } 90 | 91 | template 92 | inline void ImplicitOperator::set_tau(double tau) 93 | { 94 | _tau = tau; 95 | } 96 | 97 | template 98 | inline void ImplicitOperator::set_inverse_mass_matrix( 99 | std::shared_ptr> 100 | inverse_mass_matrix) 101 | { 102 | _inverse_mass_matrix = inverse_mass_matrix; 103 | } 104 | } // namespace adamantine 105 | 106 | #endif 107 | -------------------------------------------------------------------------------- /source/MaterialPropertyInstDev.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | INSTANTIATE_DIM_PORDER_MATERIALSTATES_DEVICE(TUPLE(MaterialProperty)) 9 | -------------------------------------------------------------------------------- /source/MaterialPropertyInstHost.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | INSTANTIATE_DIM_PORDER_MATERIALSTATES_HOST(TUPLE(MaterialProperty)) 9 | -------------------------------------------------------------------------------- /source/MaterialStates.hh: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #ifndef MATERIAL_STATES_HH 6 | #define MATERIAL_STATES_HH 7 | 8 | namespace adamantine 9 | { 10 | /** 11 | * This struct describes a material that can be found in three states: solid, 12 | * liquid, and powder as it is the case in PBF. 13 | */ 14 | struct SolidLiquidPowder 15 | { 16 | /** 17 | * Enum on the possible material states. 18 | */ 19 | enum class State 20 | { 21 | solid, 22 | liquid, 23 | powder, 24 | SIZE 25 | }; 26 | 27 | /** 28 | * Maximum different number of states a given material can be. 29 | */ 30 | static unsigned int constexpr n_material_states = 31 | static_cast(State::SIZE); 32 | }; 33 | 34 | /** 35 | * This struct describes a material that can be found in two states: solid and 36 | * liquid as it is the case in DED. 37 | */ 38 | struct SolidLiquid 39 | { 40 | /** 41 | * Enum on the possible material states. 42 | */ 43 | enum class State 44 | { 45 | solid, 46 | liquid, 47 | SIZE 48 | }; 49 | 50 | /** 51 | * Maximum different number of states a given material can be. 52 | */ 53 | static unsigned int constexpr n_material_states = 54 | static_cast(State::SIZE); 55 | }; 56 | 57 | /** 58 | * This struct describes a material that can be found in one state: solid as it 59 | * is the case in FDM. 60 | */ 61 | struct Solid 62 | { 63 | /** 64 | * Enum on the possible material states. 65 | */ 66 | enum class State 67 | { 68 | solid, 69 | SIZE 70 | }; 71 | 72 | /** 73 | * Maximum different number of states a given material can be. 74 | */ 75 | static unsigned int constexpr n_material_states = 76 | static_cast(State::SIZE); 77 | }; 78 | 79 | } // namespace adamantine 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /source/Microstructure.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2025, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | namespace adamantine 12 | { 13 | template 14 | Microstructure::Microstructure(MPI_Comm communicator, 15 | std::string const &filename_prefix) 16 | : _communicator(communicator), _filename_prefix(filename_prefix) 17 | { 18 | auto rank = dealii::Utilities::MPI::this_mpi_process(_communicator); 19 | _file.open(_filename_prefix + "_" + std::to_string(rank) + ".txt"); 20 | // Set the precision to 9 digits 21 | _file << std::setprecision(9); 22 | } 23 | 24 | template 25 | Microstructure::~Microstructure() 26 | { 27 | // Concatenate all the temporary files written by each processor. 28 | // This is good enough for now but it won't scale. We probably want to use 29 | // ADIOS in the future. 30 | _file.close(); 31 | MPI_Barrier(_communicator); 32 | if (dealii::Utilities::MPI::this_mpi_process(_communicator) == 0) 33 | { 34 | std::string global_filename = _filename_prefix + ".txt"; 35 | // Remove the global file if it already exist. If it doesn't exist, remove 36 | // returns an error code that we ignore. 37 | std::filesystem::remove(global_filename); 38 | unsigned int const n_procs = 39 | dealii::Utilities::MPI::n_mpi_processes(_communicator); 40 | for (unsigned int rank = 0; rank < n_procs; ++rank) 41 | { 42 | // This needs to be inside the loop. I don't understand why but if 43 | // global_file is defined outside the loop the file is not written 44 | // correctly. 45 | std::ofstream global_file(global_filename, std::ios::app); 46 | std::string local_filename = 47 | _filename_prefix + "_" + std::to_string(rank) + ".txt"; 48 | std::ifstream local_file(local_filename); 49 | global_file << local_file.rdbuf(); 50 | 51 | std::filesystem::remove(local_filename); 52 | } 53 | } 54 | } 55 | 56 | template 57 | void Microstructure::set_old_temperature( 58 | dealii::LA::distributed::Vector 59 | &old_temperature) 60 | { 61 | _old_temperature = old_temperature; 62 | } 63 | } // namespace adamantine 64 | 65 | //-------------------- Explicit Instantiations --------------------// 66 | INSTANTIATE_DIM(Microstructure) 67 | -------------------------------------------------------------------------------- /source/NewtonSolver.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2016 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include 6 | 7 | namespace adamantine 8 | { 9 | NewtonSolver::NewtonSolver(unsigned int max_it, double tolerance) 10 | : _max_it(max_it), _tolerance(tolerance) 11 | { 12 | } 13 | 14 | void NewtonSolver::solve( 15 | std::function( 16 | dealii::LA::distributed::Vector const &)> const 17 | &compute_residual, 18 | std::function( 19 | dealii::LA::distributed::Vector const &)> const 20 | &compute_inv_jacobian, 21 | dealii::LA::distributed::Vector &y) 22 | { 23 | 24 | dealii::LA::distributed::Vector y_old = y; 25 | dealii::LA::distributed::Vector residual = compute_residual(y); 26 | unsigned int i = 0; 27 | double residual_norm_old = residual.l2_norm(); 28 | double residual_norm = residual_norm_old; 29 | while (i < _max_it) 30 | { 31 | dealii::LA::distributed::Vector newton_step = 32 | compute_inv_jacobian(y); 33 | newton_step.scale(residual); 34 | // alpha is used for line search. 35 | double alpha = 1.0; 36 | while (residual_norm >= residual_norm_old) 37 | { 38 | y.sadd(1.0, -alpha, newton_step); 39 | residual = compute_residual(y); 40 | residual_norm = residual.l2_norm(); 41 | alpha /= 2.; 42 | // Break if the line search is falling to improve the solution. 43 | if (alpha < 1e-6) 44 | break; 45 | } 46 | if (residual_norm < _tolerance) 47 | break; 48 | 49 | y_old = y; 50 | residual_norm_old = residual_norm; 51 | 52 | ++i; 53 | } 54 | } 55 | } // namespace adamantine 56 | -------------------------------------------------------------------------------- /source/NewtonSolver.hh: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2016 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #ifndef NEWTON_SOLVER_HH 6 | #define NEWTON_SOLVER_HH 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | 14 | namespace adamantine 15 | { 16 | 17 | class NewtonSolver 18 | { 19 | /** 20 | * This class implements a Newton solver with basic line search capabilities. 21 | */ 22 | public: 23 | /** 24 | * Constructor. \p max_it is the maximal number of Newton iteration and \p 25 | * tolerance 26 | * is the tolerance on the solution. 27 | */ 28 | NewtonSolver(unsigned int max_it, double tolerance); 29 | 30 | /** 31 | * Solve non-linear problem. 32 | * \param[in] compute_residual: this function must return the residual for a 33 | * given vector. 34 | * \param[in] compute_inv_jacobian: this function must return the inverse of 35 | * the Jacobian for a given vector. 36 | * \param[in] y is the initial guess and the solution of the problem. 37 | */ 38 | void solve(std::function( 39 | dealii::LA::distributed::Vector const &)> const 40 | &compute_residual, 41 | std::function( 42 | dealii::LA::distributed::Vector const &)> const 43 | &compute_inv_jacobian, 44 | dealii::LA::distributed::Vector &y); 45 | 46 | private: 47 | /** 48 | * Maximum number of iteration. 49 | */ 50 | unsigned int _max_it; 51 | /** 52 | * Tolerance. 53 | */ 54 | double _tolerance; 55 | }; 56 | } // namespace adamantine 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /source/Operator.hh: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2016 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #ifndef OPERATOR_HH 6 | #define OPERATOR_HH 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | namespace adamantine 15 | { 16 | /** 17 | * This class defines the interface that every operator needs to implement. 18 | */ 19 | template 20 | class Operator : public dealii::Subscriptor 21 | { 22 | public: 23 | Operator() = default; 24 | 25 | virtual ~Operator() = default; 26 | 27 | /** 28 | * Return the dimension of the codomain (or range) space. To remember: the 29 | * matrix is of dimension m×n. 30 | */ 31 | virtual dealii::types::global_dof_index m() const = 0; 32 | 33 | /** 34 | * Return the dimension of the domain space. To remember: the matrix is of 35 | * dimension m×n. 36 | */ 37 | virtual dealii::types::global_dof_index n() const = 0; 38 | 39 | /** 40 | * Matrix-vector multiplication. This function applies the operator to the 41 | * vector src. 42 | * \param[in] src 43 | * \param[out] dst 44 | */ 45 | virtual void 46 | vmult(dealii::LA::distributed::Vector &dst, 47 | dealii::LA::distributed::Vector const &src) 48 | const = 0; 49 | 50 | /** 51 | * Matrix-vector multiplication with the transposed matrix. This function 52 | * applies the transpose of the operator to the vector src. 53 | * \param[in] src 54 | * \param[out] dst 55 | */ 56 | virtual void 57 | Tvmult(dealii::LA::distributed::Vector &dst, 58 | dealii::LA::distributed::Vector const &src) 59 | const = 0; 60 | 61 | /** 62 | * Matrix-vector multiplication and addition of the result to dst. This 63 | * function applies the operator to the vector src and add the result to the 64 | * vector dst. 65 | * \param[in] src 66 | * \param[inout] dst 67 | */ 68 | virtual void 69 | vmult_add(dealii::LA::distributed::Vector &dst, 70 | dealii::LA::distributed::Vector const &src) 71 | const = 0; 72 | 73 | /** 74 | * Matrix-vector multiplication with the transposed matrix and addition of 75 | * the result to dst. This function applies the transpose of the operator to 76 | * the vector src and add the result to the vector dst. 77 | * \param[in] src 78 | * \param[inout] dst 79 | */ 80 | virtual void 81 | Tvmult_add(dealii::LA::distributed::Vector &dst, 82 | dealii::LA::distributed::Vector const 83 | &src) const = 0; 84 | 85 | /** 86 | * Matrix-vector multiplication with the Jacobian. This function applies the 87 | * Jacobian of the operator to the vector src. 88 | * \param[in] src 89 | * \param[inout] dst 90 | */ 91 | virtual void jacobian_vmult( 92 | [[maybe_unused]] dealii::LA::distributed::Vector 93 | &dst, 94 | [[maybe_unused]] dealii::LA::distributed::Vector< 95 | double, MemorySpaceType> const &src) const 96 | { 97 | ASSERT_THROW_NOT_IMPLEMENTED(); 98 | } 99 | }; 100 | } // namespace adamantine 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /source/PointCloud.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2023 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace adamantine 13 | { 14 | template 15 | PointCloud::PointCloud( 16 | boost::property_tree::ptree const &experiment_database) 17 | { 18 | // Format of the file names: the format is pretty arbitrary, #frame and 19 | // #camera are replaced by the frame and the camera number. 20 | // PropertyTreeInput experiment.file 21 | _data_filename = experiment_database.get("file"); 22 | // PropertyTreeInput experiment.first_frame 23 | _next_frame = experiment_database.get("first_frame", 0); 24 | // PropertyTreeInput experiment.first_camera_id 25 | _first_camera_id = experiment_database.get("first_camera_id"); 26 | // PropertyTreeInput experiment.last_camera_id 27 | _last_camera_id = experiment_database.get("last_camera_id"); 28 | } 29 | 30 | template 31 | unsigned int PointCloud::read_next_frame() 32 | { 33 | _points_values_current_frame.points.clear(); 34 | _points_values_current_frame.values.clear(); 35 | for (unsigned int camera_id = _first_camera_id; 36 | camera_id < _last_camera_id + 1; ++camera_id) 37 | { 38 | // Use regex to get the next file to read 39 | std::regex camera_regex("#camera"); 40 | std::regex frame_regex("#frame"); 41 | auto filename = 42 | std::regex_replace((std::regex_replace(_data_filename, camera_regex, 43 | std::to_string(camera_id))), 44 | frame_regex, std::to_string(_next_frame)); 45 | wait_for_file(filename, "Waiting for the next frame: " + filename); 46 | 47 | // Read and parse the file 48 | std::ifstream file; 49 | file.open(filename); 50 | std::string line; 51 | std::getline(file, line); 52 | while (std::getline(file, line)) 53 | { 54 | std::size_t pos = 0; 55 | std::size_t last_pos = 0; 56 | std::size_t line_length = line.length(); 57 | unsigned int i = 0; 58 | dealii::Point point; 59 | double value = 0.; 60 | while (last_pos < line_length + 1) 61 | { 62 | pos = line.find_first_of(',', last_pos); 63 | // If no comma was found that we read until the end of the file 64 | if (pos == std::string::npos) 65 | { 66 | pos = line_length; 67 | } 68 | 69 | if (pos != last_pos) 70 | { 71 | char *end = line.data() + pos; 72 | if (i < dim) 73 | { 74 | point[i] = std::strtod(line.data() + last_pos, &end); 75 | } 76 | else 77 | { 78 | value = std::strtod(line.data() + last_pos, &end); 79 | } 80 | 81 | ++i; 82 | } 83 | 84 | last_pos = pos + 1; 85 | } 86 | 87 | _points_values_current_frame.points.push_back(point); 88 | _points_values_current_frame.values.push_back(value); 89 | } 90 | } 91 | 92 | return _next_frame++; 93 | } 94 | 95 | template 96 | PointsValues PointCloud::get_points_values() 97 | { 98 | return _points_values_current_frame; 99 | } 100 | 101 | } // namespace adamantine 102 | 103 | INSTANTIATE_DIM(PointCloud); 104 | -------------------------------------------------------------------------------- /source/PointCloud.hh: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2023 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #ifndef POINT_CLOUD_HH 6 | #define POINT_CLOUD_HH 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace adamantine 13 | { 14 | /** 15 | * Point cloud with the associated temperature. 16 | */ 17 | template 18 | class PointCloud final : public ExperimentalData 19 | { 20 | public: 21 | /** 22 | * Constructor. 23 | */ 24 | PointCloud(boost::property_tree::ptree const &experiment_database); 25 | 26 | unsigned int read_next_frame() override; 27 | 28 | PointsValues get_points_values() override; 29 | 30 | private: 31 | /** 32 | * Next frame that should be read. 33 | */ 34 | unsigned int _next_frame; 35 | /** 36 | * ID of the first camera. 37 | */ 38 | unsigned int _first_camera_id; 39 | /** 40 | * ID of the last camera. 41 | */ 42 | unsigned int _last_camera_id; 43 | /** 44 | * Generic file name of the frames. 45 | */ 46 | std::string _data_filename; 47 | /** 48 | * Values and associated points of the current frame. 49 | */ 50 | PointsValues _points_values_current_frame; 51 | }; 52 | 53 | } // namespace adamantine 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /source/RayTracing.hh: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2023 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #ifndef RAY_TRACING_HH 6 | #define RAY_TRACING_HH 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace adamantine 13 | { 14 | /** 15 | * Data structure representing a ray. 16 | */ 17 | template 18 | struct Ray 19 | { 20 | /** 21 | * Origin of the ray. 22 | */ 23 | dealii::Point origin; 24 | /** 25 | * Direction of propagation of the ray. 26 | */ 27 | dealii::Tensor<1, dim> direction; 28 | }; 29 | 30 | /** 31 | * This class performs ray tracing 32 | */ 33 | class RayTracing final : public ExperimentalData<3> 34 | { 35 | public: 36 | static int constexpr dim = 3; 37 | 38 | /** 39 | * Constructor. 40 | */ 41 | RayTracing(boost::property_tree::ptree const &experiment_database, 42 | dealii::DoFHandler const &dof_handler); 43 | 44 | unsigned int read_next_frame() override; 45 | 46 | PointsValues get_points_values() override; 47 | 48 | private: 49 | /** 50 | * Next frame that should be read. 51 | */ 52 | unsigned int _next_frame; 53 | /** 54 | * ID of the first camera. 55 | */ 56 | unsigned int _first_camera_id; 57 | /** 58 | * ID of the last camera. 59 | */ 60 | unsigned int _last_camera_id; 61 | /** 62 | * Generic file name of the frames. 63 | */ 64 | std::string _data_filename; 65 | /** 66 | * DoFHandler of the mesh we want to perform the ray tracing on. 67 | */ 68 | dealii::DoFHandler const &_dof_handler; 69 | /** 70 | * Rays associated to the current frame. 71 | */ 72 | std::vector> _rays_current_frame; 73 | /** 74 | * Values associated to the rays of the current frame. 75 | */ 76 | std::vector _values_current_frame; 77 | }; 78 | 79 | } // namespace adamantine 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /source/ScanPath.hh: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2016 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #ifndef SCAN_PATH_HH 6 | #define SCAN_PATH_HH 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | namespace adamantine 19 | { 20 | /** 21 | * This enum distinguishes between the two types of scan path segments. 22 | */ 23 | enum class ScanPathSegmentType 24 | { 25 | line, 26 | point 27 | }; 28 | 29 | /** 30 | * This structure stores the relevant information for a single segment. The scan 31 | * path input file distingishes between spots and lines, but when we know the 32 | * end time and end location, spots become lines with a start point equal to its 33 | * end point. Everything one needs can be determined from these three quantities 34 | * (and the segment info from the preceding segment) but in the future it might 35 | * be worth adding in some redundant information like start time/point and 36 | * velocity. 37 | */ 38 | struct ScanPathSegment 39 | { 40 | double end_time = 41 | std::numeric_limits::signaling_NaN(); // Unit: seconds 42 | double power_modifier = 43 | std::numeric_limits::signaling_NaN(); // Dimensionless 44 | dealii::Point<3> end_point; // Unit: m 45 | }; 46 | 47 | /** 48 | * Forward declaration of the tester friend class to ScanPath. 49 | */ 50 | class ScanPathTester; 51 | 52 | /** 53 | * This class calculates the position of the center of a heat source. It also 54 | * gives the power modifier for the current segment. It reads in the scan path 55 | * from a text file. 56 | */ 57 | class ScanPath 58 | { 59 | friend class ScanPathTester; 60 | 61 | public: 62 | /** 63 | * Default constructor. This creates an empty scan path with no segment. 64 | */ 65 | ScanPath() = default; 66 | 67 | /** 68 | * Construtor. 69 | * \param[in] scan_path_file is the name of the text file containing the scan 70 | * path 71 | * \param[in] file_format is the format of the scan path file 72 | * \param[in] units_optional_database is the units property tree 73 | */ 74 | ScanPath(std::string const &scan_path_file, std::string const &file_format, 75 | boost::optional const 76 | &units_optional_database); 77 | 78 | /** 79 | * Calculate the location of the scan path at a given time for a single 80 | * coordinate. 81 | */ 82 | dealii::Point<3> value(double const &time) const; 83 | 84 | /** 85 | * Return the power coefficient for the current segment 86 | */ 87 | double get_power_modifier(double const &time) const; 88 | 89 | /** 90 | * Return the scan path's list of segments 91 | */ 92 | std::vector get_segment_list() const; 93 | 94 | /** 95 | * Read the scan path file and update the list of segments. 96 | */ 97 | void read_file(); 98 | 99 | /** 100 | * Return true if we reach the end of the scan path. 101 | */ 102 | bool is_finished() const; 103 | 104 | private: 105 | /** 106 | * Method to load a "segment" scan path file 107 | */ 108 | void load_segment_scan_path(); 109 | 110 | /** 111 | * Method to load an "event series" scan path file 112 | */ 113 | void load_event_series_scan_path(); 114 | 115 | /** 116 | * Method to determine the current segment, its start point, and start time. 117 | */ 118 | void update_current_segment_info(double time, 119 | dealii::Point<3> &segment_start_point, 120 | double &segment_start_time) const; 121 | 122 | /** 123 | * Flag is true if we have reached the end of _scan_path_file. 124 | */ 125 | bool _scan_path_end = false; 126 | /** 127 | * Scaling factor for the distance. 128 | */ 129 | double _distance_scaling = 1.; 130 | /** 131 | * Scaling factor for the velocity. 132 | */ 133 | double _velocity_scaling = 1.; 134 | /** 135 | * File name of the scan path 136 | */ 137 | std::string _scan_path_file; 138 | /** 139 | * Format of the scan path file, either segment of event_series. 140 | */ 141 | std::string _file_format; 142 | /** 143 | * Time the last time _scan_path_file was updated. 144 | */ 145 | std::filesystem::file_time_type _last_write_time; 146 | /** 147 | * The list of information about each segment in the scan path. 148 | */ 149 | std::vector _segment_list; 150 | /** 151 | * The index of the current segment in the scan path. 152 | */ 153 | mutable unsigned int _current_segment = 0; 154 | }; 155 | } // namespace adamantine 156 | 157 | #endif 158 | -------------------------------------------------------------------------------- /source/ThermalOperatorBase.hh: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2016 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #ifndef THERMAL_OPERATOR_BASE_HH 6 | #define THERMAL_OPERATOR_BASE_HH 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace adamantine 15 | { 16 | template 17 | class ThermalOperatorBase : public Operator 18 | { 19 | public: 20 | ThermalOperatorBase() = default; 21 | 22 | virtual ~ThermalOperatorBase() = default; 23 | 24 | virtual void 25 | reinit(dealii::DoFHandler const &dof_handler, 26 | dealii::AffineConstraints const &affine_constraints, 27 | dealii::hp::QCollection<1> const &q_collection) = 0; 28 | 29 | virtual void compute_inverse_mass_matrix( 30 | dealii::DoFHandler const &dof_handler, 31 | dealii::AffineConstraints const &affine_constraints) = 0; 32 | 33 | virtual std::shared_ptr< 34 | dealii::LA::distributed::Vector> 35 | get_inverse_mass_matrix() const = 0; 36 | 37 | virtual void initialize_dof_vector( 38 | dealii::LA::distributed::Vector &vector) 39 | const = 0; 40 | 41 | virtual void clear() = 0; 42 | 43 | virtual void get_state_from_material_properties() = 0; 44 | 45 | virtual void set_state_to_material_properties() = 0; 46 | 47 | virtual void set_material_deposition_orientation( 48 | std::vector const &deposition_cos, 49 | std::vector const &deposition_sin) = 0; 50 | 51 | virtual void set_time_and_source_height(double, double) = 0; 52 | }; 53 | } // namespace adamantine 54 | #endif 55 | -------------------------------------------------------------------------------- /source/ThermalOperatorDeviceInstSDev.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | INSTANTIATE_DIM_USETABLE_PORDER_FEDEGREE_S_DEVICE(TUPLE(ThermalOperatorDevice)) 9 | -------------------------------------------------------------------------------- /source/ThermalOperatorDeviceInstSLDev.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | INSTANTIATE_DIM_USETABLE_PORDER_FEDEGREE_SL_DEVICE(TUPLE(ThermalOperatorDevice)) 9 | -------------------------------------------------------------------------------- /source/ThermalOperatorDeviceInstSLPDev.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | INSTANTIATE_DIM_USETABLE_PORDER_FEDEGREE_SLP_DEVICE( 9 | TUPLE(ThermalOperatorDevice)) 10 | -------------------------------------------------------------------------------- /source/ThermalOperatorInstSHost.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | INSTANTIATE_DIM_USETABLE_PORDER_FEDEGREE_S_HOST(TUPLE(ThermalOperator)) 9 | -------------------------------------------------------------------------------- /source/ThermalOperatorInstSLHost.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | INSTANTIATE_DIM_USETABLE_PORDER_FEDEGREE_SL_HOST(TUPLE(ThermalOperator)) 9 | -------------------------------------------------------------------------------- /source/ThermalOperatorInstSLPHost.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | INSTANTIATE_DIM_USETABLE_PORDER_FEDEGREE_SLP_HOST(TUPLE(ThermalOperator)) 9 | -------------------------------------------------------------------------------- /source/ThermalPhysicsInstSDev.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | INSTANTIATE_DIM_PORDER_FEDEGREE_S_QUAD_DEVICE(TUPLE(ThermalPhysics)) 9 | -------------------------------------------------------------------------------- /source/ThermalPhysicsInstSHost.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | INSTANTIATE_DIM_PORDER_FEDEGREE_S_QUAD_HOST(TUPLE(ThermalPhysics)) 9 | -------------------------------------------------------------------------------- /source/ThermalPhysicsInstSLDev.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | INSTANTIATE_DIM_PORDER_FEDEGREE_SL_QUAD_DEVICE(TUPLE(ThermalPhysics)) 9 | -------------------------------------------------------------------------------- /source/ThermalPhysicsInstSLHost.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | INSTANTIATE_DIM_PORDER_FEDEGREE_SL_QUAD_HOST(TUPLE(ThermalPhysics)) 9 | -------------------------------------------------------------------------------- /source/ThermalPhysicsInstSLPDev.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | INSTANTIATE_DIM_PORDER_FEDEGREE_SLP_QUAD_DEVICE(TUPLE(ThermalPhysics)) 9 | -------------------------------------------------------------------------------- /source/ThermalPhysicsInstSLPHost.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | INSTANTIATE_DIM_PORDER_FEDEGREE_SLP_QUAD_HOST(TUPLE(ThermalPhysics)) 9 | -------------------------------------------------------------------------------- /source/Timer.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2017 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include 6 | 7 | #include 8 | 9 | namespace adamantine 10 | { 11 | Timer::Timer(MPI_Comm communicator, std::string const §ion) 12 | : _communicator(communicator), _section(section), _clock(), _t_start(), 13 | _elapsed_time(boost::chrono::milliseconds(0)) 14 | { 15 | } 16 | 17 | void Timer::start() { _t_start = _clock.now(); } 18 | 19 | void Timer::stop() { _elapsed_time += _clock.now() - _t_start; } 20 | 21 | void Timer::reset() { _elapsed_time = boost::chrono::milliseconds(0); } 22 | 23 | void Timer::print() 24 | { 25 | int rank = -1; 26 | MPI_Comm_rank(_communicator, &rank); 27 | if (rank == 0) 28 | { 29 | boost::chrono::milliseconds ms = 30 | boost::chrono::duration_cast( 31 | _elapsed_time); 32 | std::cout << "Time elapsed in " + _section + ": " << ms << std::endl; 33 | } 34 | } 35 | 36 | boost::chrono::process_real_cpu_clock::duration Timer::get_elapsed_time() 37 | { 38 | return _elapsed_time; 39 | } 40 | } // namespace adamantine 41 | -------------------------------------------------------------------------------- /source/Timer.hh: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2017 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #ifndef TIMER_H 6 | #define TIMER_H 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | 14 | namespace adamantine 15 | { 16 | /** 17 | * This class measures the time spend in a given section by the rank 0 process. 18 | * This class does not use any MPI_Barrier to synchronize the timer among all 19 | * the processors. 20 | */ 21 | class Timer 22 | { 23 | public: 24 | /** 25 | * Default constructor. 26 | */ 27 | Timer() = default; 28 | 29 | /** 30 | * Constructor. The string @p section is used when the timing is output. 31 | */ 32 | Timer(MPI_Comm communicator, std::string const §ion); 33 | 34 | /** 35 | * Start the clock. 36 | */ 37 | void start(); 38 | 39 | /** 40 | * Stop the clock. If the clock has already been started and stopped before 41 | * the new duration will be added to the previous one. 42 | */ 43 | void stop(); 44 | 45 | /** 46 | * Reset to zero the store duration. 47 | */ 48 | void reset(); 49 | 50 | /** 51 | * Print the name of the section and the elapsed time. 52 | */ 53 | void print(); 54 | 55 | /** 56 | * Return the current elapsed time. 57 | */ 58 | boost::chrono::process_real_cpu_clock::duration get_elapsed_time(); 59 | 60 | private: 61 | MPI_Comm _communicator; 62 | std::string _section; 63 | boost::chrono::process_cpu_clock _clock; 64 | boost::chrono::process_cpu_clock::time_point _t_start; 65 | /** 66 | * Store the elapsed time in milliseconds nds 67 | */ 68 | boost::chrono::process_cpu_clock::duration _elapsed_time; 69 | }; 70 | } // namespace adamantine 71 | #endif 72 | -------------------------------------------------------------------------------- /source/ensemble_management.hh: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2021-2025, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #ifndef ENSEMBLE_MANAGEMENT_HH 6 | #define ENSEMBLE_MANAGEMENT_HH 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | namespace adamantine 18 | { 19 | /** 20 | * Return the sources encompassing all the sources of the different ensemble 21 | * members. 22 | */ 23 | template 24 | std::vector>> get_bounding_heat_sources( 25 | std::vector const &property_trees, 26 | MPI_Comm global_communicator); 27 | 28 | /** 29 | * Given an input property tree @p database, return @p local_ensemble_size 30 | * databases each one modified to respect the standard deviation of each 31 | * quantity (if provided). 32 | */ 33 | std::vector create_database_ensemble( 34 | boost::property_tree::ptree const &database, MPI_Comm local_communicator, 35 | unsigned int first_local_member, unsigned int local_ensemble_size, 36 | unsigned int global_ensemble_size); 37 | } // namespace adamantine 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /source/experimental_data_utils.hh: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2021-2023, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #ifndef EXPERIMENTAL_DATA_UTILS_HH 6 | #define EXPERIMENTAL_DATA_UTILS_HH 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | namespace adamantine 15 | { 16 | /** 17 | * Structure to encapsulate a point cloud and the values associated to each 18 | * point. 19 | */ 20 | template 21 | struct PointsValues 22 | { 23 | std::vector> points; 24 | std::vector values; 25 | }; 26 | 27 | /** 28 | * Read the experimental data (IR point cloud) and return a vector of 29 | * PointsValues. The size of the vector is equal to the number of frames. 30 | */ 31 | template 32 | std::vector> read_experimental_data_point_cloud( 33 | MPI_Comm const &communicator, 34 | boost::property_tree::ptree const &experiment_database); 35 | 36 | /** 37 | * Get the pair of vectors that map the DOF indices to the 38 | * support points. 39 | */ 40 | template 41 | std::pair, 42 | std::vector>> 43 | get_dof_to_support_mapping(dealii::DoFHandler const &dof_handler); 44 | 45 | /** 46 | * Get the pair of vectors that map the experimental observation indices to the 47 | * dof indices. 48 | */ 49 | template 50 | std::pair, std::vector> 51 | get_expt_to_dof_mapping(PointsValues const &points_values, 52 | dealii::DoFHandler const &dof_handler); 53 | 54 | /** 55 | * Fill the @p temperature Vector given @p points_values. 56 | */ 57 | template 58 | void set_with_experimental_data( 59 | MPI_Comm const &communicator, PointsValues const &points_values, 60 | std::pair, std::vector> &expt_to_dof_mapping, 61 | dealii::LinearAlgebra::distributed::Vector &temperature, 62 | bool verbose_output); 63 | 64 | /** 65 | * Parse the log file that maps experimental frames to their times. 66 | * The log file has a headerless CSV format with the frame index (int) as the 67 | * first entry per line followed by the timestamp for each camera. For now we 68 | * assume that the first frame for each camera is synced so that we can 69 | * re-reference the times to a fixed offset from the first frame time. The 70 | * function returns a vector containing the frame timings for each camera, i.e. 71 | * the first index is the camera index and the second is the frame index. The 72 | * frame indices in the output are such that the 'first frame' listed in the 73 | * input file is index 0. 74 | */ 75 | std::vector> 76 | read_frame_timestamps(boost::property_tree::ptree const &experiment_database); 77 | 78 | } // namespace adamantine 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /source/material_deposition.hh: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2021 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #ifndef MATERIAL_DEPOSITION_HH 6 | #define MATERIAL_DEPOSITION_HH 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace adamantine 16 | { 17 | /** 18 | * Return the bounding boxes, the deposition times, the cosine of the deposition 19 | * angles, and the sine of the deposition angles. 20 | */ 21 | template 22 | std::tuple>, std::vector, 23 | std::vector, std::vector> 24 | create_material_deposition_boxes( 25 | boost::property_tree::ptree const &geometry_database, 26 | std::vector>> &heat_sources); 27 | /** 28 | * Read the material deposition file and return the bounding boxes, the 29 | * deposition times, the cosine of the deposition angles, and the sine of the 30 | * deposition angles. 31 | */ 32 | template 33 | std::tuple>, std::vector, 34 | std::vector, std::vector> 35 | read_material_deposition(boost::property_tree::ptree const &geometry_database); 36 | /** 37 | * Return the bounding boxes, the deposition times, the cosine of the deposition 38 | * angles, and the sine of deposition angles based on the scan path. 39 | */ 40 | template 41 | std::tuple>, std::vector, 42 | std::vector, std::vector> 43 | deposition_along_scan_path(boost::property_tree::ptree const &geometry_database, 44 | ScanPath const &scan_path); 45 | /** 46 | * Merge a vector of tuple of bounding boxes, deposition times, cosine of 47 | * deposition angles, and sine of deposition angles into a 48 | * single tuple of vectors, sorted by deposition time. 49 | */ 50 | template 51 | std::tuple>, std::vector, 52 | std::vector, std::vector> 53 | merge_deposition_paths( 54 | std::vector>, 55 | std::vector, std::vector, 56 | std::vector>> const &bounding_box_lists); 57 | /** 58 | * Return a vector of cells to activate for each time deposition. 59 | */ 60 | template 61 | std::vector::active_cell_iterator>> 62 | get_elements_to_activate( 63 | dealii::DoFHandler const &dof_handler, 64 | std::vector> const &material_deposition_boxes); 65 | } // namespace adamantine 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /source/utils.hh: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2016 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #ifndef UTILS_HH 6 | #define UTILS_HH 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | namespace adamantine 20 | { 21 | /** 22 | * Wait for the file to appear. 23 | */ 24 | inline void wait_for_file(std::string const &filename, 25 | std::string const &message) 26 | { 27 | unsigned int counter = 1; 28 | while (!std::filesystem::exists(filename)) 29 | { 30 | // Spin loop waiting for the file to appear (message printed if counter 31 | // overflows) 32 | if (counter == 0) 33 | std::cout << message << std::endl; 34 | ++counter; 35 | } 36 | } 37 | 38 | /** 39 | * Wait for the file to be updated. 40 | */ 41 | inline void 42 | wait_for_file_to_update(std::string const &filename, std::string const &message, 43 | std::filesystem::file_time_type &last_write_time) 44 | { 45 | unsigned int counter = 1; 46 | // We check when the file was last written to know if he file was updated. 47 | // When the file is being overwritten, the last_write_time() function throws 48 | // an error. Since it's an "expected" behavior, we just catch the error keep 49 | // working. 50 | try 51 | { 52 | while (std::filesystem::last_write_time(filename) == last_write_time) 53 | { 54 | // Spin loop waiting for the file to be updated (message printed if 55 | // counter overflows) 56 | if (counter == 0) 57 | std::cout << message << std::endl; 58 | ++counter; 59 | } 60 | } 61 | catch (std::filesystem::filesystem_error const &) 62 | { 63 | // No-op 64 | } 65 | last_write_time = std::filesystem::last_write_time(filename); 66 | } 67 | 68 | #define ASSERT(condition, message) assert((condition) && (message)) 69 | 70 | inline void ASSERT_THROW(bool cond, std::string const &message) 71 | { 72 | if (cond == false) 73 | throw std::runtime_error(message); 74 | } 75 | 76 | // ----------- Custom Exceptions --------------// 77 | class NotImplementedExc : public std::exception 78 | { 79 | virtual const char *what() const throw() override 80 | { 81 | return "The function is not implemented"; 82 | } 83 | }; 84 | 85 | inline void ASSERT_THROW_NOT_IMPLEMENTED() 86 | { 87 | NotImplementedExc exception; 88 | throw exception; 89 | } 90 | 91 | } // namespace adamantine 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /source/validate_input_database.hh: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2021 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #ifndef VALIDATE_INPUT_DATABASE_HH 6 | #define VALIDATE_INPUT_DATABASE_HH 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace adamantine 13 | { 14 | void validate_input_database(boost::property_tree::ptree &database); 15 | } // namespace adamantine 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /tests/data/HourGlass_AOP.info: -------------------------------------------------------------------------------- 1 | geometry 2 | { 3 | import_mesh true 4 | mesh_format vtk 5 | mesh_file HourGlass_AOP.vtk 6 | mesh_scale_factor 1 7 | reset_material_id true 8 | dim 3 ; dimension of the domain 9 | material_deposition true 10 | material_deposition_method scan_paths 11 | deposition_length 3.5e-3 12 | deposition_height 0.759e-3 13 | deposition_width 3.5e-3 14 | deposition_lead_time 0 15 | material_height 0.0015; 16 | } 17 | physics 18 | { 19 | thermal true 20 | mechanical false 21 | } 22 | 23 | boundary 24 | { 25 | type convective ; adiabatic,radiative ; 26 | } 27 | 28 | refinement 29 | { 30 | n_refinements 0 ; Number of coarsening/refinement executed (uses Kelly's 31 | ; error estimator) 32 | time_steps_between_refinement 200000 ; number of time steps after which 33 | ; the refinement process is performed 34 | } 35 | 36 | materials 37 | { 38 | ; switching to new material 39 | n_materials 1 40 | 41 | property_format polynomial 42 | material_0 43 | { 44 | initial_temperature 300 ; [K] 45 | solid 46 | { 47 | specific_heat 650; [J/kg K] 48 | density 7990; [kg/m^3] 49 | thermal_conductivity_x 38.0 ; [W/m k] 50 | thermal_conductivity_y 38.0 ; [W/m k] 51 | thermal_conductivity_z 38.0 ; [W/m k] 52 | emissivity 0.05 53 | convection_heat_transfer_coef 0.1 ; [W/m^2 K] 54 | } 55 | 56 | liquid 57 | { 58 | specific_heat 650; [J/kg K] 59 | density 7990; [kg/m^3] 60 | thermal_conductivity_x 0.38 ; [W/m k] 61 | thermal_conductivity_y 0.38 ; [W/m k] 62 | thermal_conductivity_z 0.38 ; [W/m k] 63 | emissivity 0.05 64 | convection_heat_transfer_coef 0.01 ; [W/m^2 K] 65 | } 66 | 67 | powder 68 | { 69 | specific_heat 650; [J/kg K] 70 | density 7990; [kg/m^3] 71 | thermal_conductivity_x 38.0 ; [W/m k] 72 | thermal_conductivity_y 38.0 ; [W/m k] 73 | thermal_conductivity_z 38.0 ; [W/m k] 74 | emissivity 0.05 75 | convection_heat_transfer_coef 0.1 ; [W/m^2 K] 76 | } 77 | 78 | solidus 1713; [K] 79 | liquidus 1803; [K] 80 | latent_heat 272000 ; [J/kg] 81 | radiation_temperature_infty 300 ; [K] 82 | convection_temperature_infty 300 ; [K] 83 | } 84 | } 85 | 86 | sources 87 | { 88 | n_beams 1 89 | 90 | beam_0 91 | { 92 | type goldak ; goldak (laser) or electron_beam 93 | depth 3.5e-3 [m] maximum depth reached by the laser - MIGHT NEED TWEAKED 94 | diameter 3.5e-3 ; [m] 95 | scan_path_file HourGlass_AOP_scan_path.txt 96 | scan_path_file_format segment 97 | absorption_efficiency 0.7 ; number between 0 and 1 equivalent to 98 | ; energy_conversion_efficiency * control_efficiency 99 | ; for an electron beam 100 | max_power 2000.0 ; [W], current * voltage for an electron beam 101 | } 102 | } 103 | 104 | time_stepping 105 | { 106 | method forward_euler ; Possibilities: backward_euler, implicit_midpoint, 107 | ; crank_nicolson, sdirk2, forward_euler, rk_third_order, 108 | ; rk_fourth_order, bogacki_shampine, dopri, 109 | ; fehlberg, cash_karp 110 | duration 10; [s] 111 | time_step 1e-2 ; [s] 112 | } 113 | 114 | post_processor 115 | { 116 | filename_prefix AdamantineDemo_output 117 | time_steps_between_output 10 118 | additional_output_refinement 0 119 | } 120 | 121 | discretization 122 | { 123 | thermal 124 | { 125 | fe_degree 1 126 | quadrature gauss ; Optional parameter. Possibilities: gauss or lobatto 127 | } 128 | mechanical 129 | { 130 | fe_degree 1 131 | quadrature gauss ; Optional parameter. Possibilities: gauss or lobatto 132 | } 133 | } 134 | 135 | profiling 136 | { 137 | timer false 138 | caliper "runtime-report,calc.inclusive" 139 | } 140 | 141 | memory_space host ; Always run on the host 142 | verbose_output true 143 | -------------------------------------------------------------------------------- /tests/data/amr_test.info: -------------------------------------------------------------------------------- 1 | geometry 2 | { 3 | import_mesh false ; Use built-in mesh generator 4 | dim 3 ; dimension of the domain 5 | length 5.0e-3 ; [m] 6 | height 0.5e-3 ; [m] In 3D, the third parameters is width 7 | width 5.0e-3 8 | length_divisions 4 ; Number of cell layers in the length direction 9 | height_divisions 1 ; Number of cell layers in the height direction 10 | width_divisions 4 11 | } 12 | 13 | physics 14 | { 15 | thermal true 16 | mechanical false 17 | } 18 | 19 | boundary 20 | { 21 | type adiabatic ; convective,radiative 22 | } 23 | 24 | refinement 25 | { 26 | n_refinements 1 ; Number of time the cells on the paths of the beams are 27 | ; refined 28 | time_steps_between_refinement 200 ; number of time steps after which 29 | ; the refinement process is performed 30 | } 31 | 32 | materials 33 | { 34 | n_materials 1 35 | 36 | property_format polynomial 37 | material_0 38 | { 39 | solid 40 | { 41 | density 7904; [kg/m^3] For now all the states needs to have the same 42 | ; density. 43 | specific_heat 714; [J/kg K] 44 | thermal_conductivity_x 31.4 ; [W/m K] 45 | thermal_conductivity_y 31.4 ; [W/m K] 46 | thermal_conductivity_z 31.4 ; [W/m K] 47 | } 48 | 49 | powder 50 | { 51 | specific_heat 714; [J/kg K] 52 | density 7904; [kg/m^3] 53 | thermal_conductivity_x 0.314 ; [W/m K] 54 | thermal_conductivity_y 0.314 ; [W/m K] 55 | thermal_conductivity_z 0.314 ; [W/m K] 56 | } 57 | 58 | liquid 59 | { 60 | specific_heat 847; [J/kg K] 61 | density 7904; [kg/m^3] 62 | thermal_conductivity_x 37.3 ; [W/m k] 63 | thermal_conductivity_y 37.3 ; [W/m k] 64 | thermal_conductivity_z 37.3 ; [W/m k] 65 | ; Not all three states need to define the same properties or to exist 66 | } 67 | 68 | solidus 1675; [K] 69 | liquidus 1708; [K] 70 | latent_heat 290000 ; [J/kg] 71 | } 72 | } 73 | 74 | sources 75 | { 76 | n_beams 1 77 | 78 | beam_0 79 | { 80 | type goldak ; goldak (laser) or electron_beam 81 | depth 0.25e-3 ; [m] maximum depth reached by the laser 82 | diameter 0.6e-3 ; [m] 83 | scan_path_file bare_plate_L_scan_path_fast.txt 84 | scan_path_file_format segment 85 | absorption_efficiency 0.3 ; number between 0 and 1 equivalent to 86 | ; energy_conversion_efficiency * control_efficiency 87 | ; for an electron beam 88 | max_power 400.0 ; [W], current * voltage for an electron beam 89 | } 90 | } 91 | 92 | time_stepping 93 | { 94 | method forward_euler ; Possibilities: backward_euler, implicit_midpoint, 95 | ; crank_nicolson, sdirk2, forward_euler, rk_third_order, 96 | ; rk_fourth_order 97 | duration 25.0e-5 ; [s] 98 | time_step 1.0e-6 ; [s] 99 | } 100 | 101 | post_processor 102 | { 103 | filename_prefix output 104 | time_steps_between_output 50 105 | } 106 | 107 | discretization 108 | { 109 | thermal 110 | { 111 | fe_degree 3 112 | quadrature gauss ; Optional parameter. Possibilities: gauss or lobatto 113 | } 114 | } 115 | 116 | profiling 117 | { 118 | timer false 119 | caliper "spot(profile.mpi),loop-report,runtime-report" 120 | } 121 | 122 | memory_space host ; Always run on the host 123 | -------------------------------------------------------------------------------- /tests/data/bare_plate_L_da.info: -------------------------------------------------------------------------------- 1 | ensemble 2 | { 3 | ensemble_simulation true 4 | ensemble_size 3 5 | materials 6 | { 7 | initial_temperature_stddev 50.0 8 | } 9 | } 10 | experiment 11 | { 12 | read_in_experimental_data true 13 | log_filename bare_plate_L_expt_log.txt 14 | file bare_plate_L_expt_data_#camera_#frame.csv 15 | format point_cloud 16 | first_frame 0 17 | last_frame 1 18 | first_camera_id 0 19 | last_camera_id 0 20 | first_frame_temporal_offset 0.0105 21 | estimated_uncertainty 5.0 22 | } 23 | data_assimilation 24 | { 25 | assimilate_data true 26 | localization_cutoff_function gaspari_cohn 27 | localization_cutoff_distance 1.0e-3 28 | solver 29 | { 30 | max_number_of_temp_vectors 10 31 | convergence_tolerance 1.0e-8 32 | } 33 | } 34 | physics 35 | { 36 | thermal true 37 | mechanical false 38 | } 39 | geometry 40 | { 41 | import_mesh false ; Use built-in mesh generator 42 | dim 3 ; dimension of the domain 43 | length 5.0e-3 ; [m] 44 | height 0.5e-3 ; [m] In 3D, the third parameters is width 45 | width 5.0e-3 46 | length_divisions 4 ; Number of cell layers in the length direction 47 | height_divisions 1 ; Number of cell layers in the height direction 48 | width_divisions 4 49 | } 50 | 51 | boundary 52 | { 53 | type adiabatic ; convective,radiative 54 | } 55 | 56 | refinement 57 | { 58 | n_refinements 1 ; Number of time the cells on the paths of the beams are 59 | ; refined 60 | time_steps_between_refinement 250 ; number of time steps after which 61 | ; the refinement process is performed 62 | } 63 | 64 | materials 65 | { 66 | n_materials 1 67 | 68 | property_format polynomial 69 | initial_temperature 300 70 | 71 | material_0 72 | { 73 | solid 74 | { 75 | density 7904; [kg/m^3] For now all the states needs to have the same 76 | ; density. 77 | specific_heat 714; [J/kg K] 78 | thermal_conductivity_x 31.4 ; [W/m K] 79 | thermal_conductivity_y 31.4 ; [W/m K] 80 | thermal_conductivity_z 31.4 ; [W/m K] 81 | } 82 | 83 | powder 84 | { 85 | specific_heat 714; [J/kg K] 86 | density 7904; [kg/m^3] 87 | thermal_conductivity_x 0.314 ; [W/m K] 88 | thermal_conductivity_y 0.314 ; [W/m K] 89 | thermal_conductivity_z 0.314 ; [W/m K] 90 | } 91 | 92 | liquid 93 | { 94 | specific_heat 847; [J/kg K] 95 | density 7904; [kg/m^3] 96 | thermal_conductivity_x 37.3 ; [W/m k] 97 | thermal_conductivity_y 37.3 ; [W/m k] 98 | thermal_conductivity_z 37.3 ; [W/m k] 99 | ; Not all three states need to define the same properties or to exist 100 | } 101 | 102 | solidus 1675; [K] 103 | liquidus 1708; [K] 104 | latent_heat 290000 ; [J/kg] 105 | } 106 | } 107 | 108 | sources 109 | { 110 | n_beams 1 111 | 112 | beam_0 113 | { 114 | type goldak ; goldak (laser) or electron_beam 115 | depth 0.5e-3 ; [m] maximum depth reached by the laser 116 | diameter 0.6e-3 ; [m] 117 | scan_path_file bare_plate_L_scan_path.txt 118 | scan_path_file_format segment 119 | absorption_efficiency 0.3 ; number between 0 and 1 equivalent to 120 | ; energy_conversion_efficiency * control_efficiency 121 | ; for an electron beam 122 | max_power 400.0 ; [W], current * voltage for an electron beam 123 | } 124 | } 125 | 126 | time_stepping 127 | { 128 | method forward_euler ; Possibilities: backward_euler, implicit_midpoint, 129 | ; crank_nicolson, sdirk2, forward_euler, rk_third_order, 130 | ; rk_fourth_order 131 | duration 5.0e-2 ; [s] 132 | time_step 1.0e-4 ; [s] 133 | } 134 | 135 | post_processor 136 | { 137 | filename_prefix output 138 | time_steps_between_output 20 139 | } 140 | 141 | discretization 142 | { 143 | thermal 144 | { 145 | fe_degree 3 146 | quadrature gauss ; Optional parameter. Possibilities: gauss or lobatto 147 | } 148 | } 149 | 150 | profiling 151 | { 152 | timer false 153 | caliper "spot(profile.mpi),loop-report,runtime-report" 154 | } 155 | 156 | memory_space host ; Always run on the host 157 | -------------------------------------------------------------------------------- /tests/data/bare_plate_L_da_aug_ref_data_0_0.csv: -------------------------------------------------------------------------------- 1 | "x", "y", "z", "T" 2 | 0.00125, 0.003125, 0.0005, 331.274 3 | 0.0025, 0.003125, 0.0005, 563.587 4 | -------------------------------------------------------------------------------- /tests/data/bare_plate_L_da_aug_ref_data_0_1.csv: -------------------------------------------------------------------------------- 1 | "x", "y", "z", "T" 2 | 0.00125, 0.003125, 0.0005, 392.267 3 | 0.0025, 0.003125, 0.0005, 526.117 4 | -------------------------------------------------------------------------------- /tests/data/bare_plate_L_da_aug_ref_log.txt: -------------------------------------------------------------------------------- 1 | 0, 0.02, 2 | 1, 0.04, 3 | -------------------------------------------------------------------------------- /tests/data/bare_plate_L_da_augmented.info: -------------------------------------------------------------------------------- 1 | ensemble 2 | { 3 | ensemble_simulation true 4 | ensemble_size 3 5 | sources 6 | { 7 | beam_0 8 | { 9 | absorption_efficiency_stddev 0.1 10 | } 11 | } 12 | } 13 | experiment 14 | { 15 | read_in_experimental_data true 16 | log_filename bare_plate_L_da_aug_ref_log.txt 17 | file bare_plate_L_da_aug_ref_data_#camera_#frame.csv 18 | format point_cloud 19 | first_frame 0 20 | last_frame 1 21 | first_camera_id 0 22 | last_camera_id 0 23 | first_frame_temporal_offset 0.02 24 | estimated_uncertainty 5.0 25 | } 26 | data_assimilation 27 | { 28 | assimilate_data true 29 | localization_cutoff_function gaspari_cohn 30 | localization_cutoff_distance 1.0e-3 31 | augment_with_beam_0_absorption true 32 | solver 33 | { 34 | max_number_of_temp_vectors 10 35 | convergence_tolerance 1.0e-8 36 | } 37 | } 38 | physics 39 | { 40 | thermal true 41 | mechanical false 42 | } 43 | geometry 44 | { 45 | import_mesh false ; Use built-in mesh generator 46 | dim 3 ; dimension of the domain 47 | length 5.0e-3 ; [m] 48 | height 0.5e-3 ; [m] In 3D, the third parameters is width 49 | width 5.0e-3 50 | length_divisions 8 ; Number of cell layers in the length direction 51 | height_divisions 1 ; Number of cell layers in the height direction 52 | width_divisions 8 53 | } 54 | 55 | boundary 56 | { 57 | type adiabatic ; convective,radiative 58 | } 59 | 60 | refinement 61 | { 62 | n_refinements 0 ; Number of time the cells on the paths of the beams are 63 | ; refined 64 | time_steps_between_refinement 2000000000 ; number of time steps after which 65 | ; the refinement process is performed 66 | } 67 | 68 | materials 69 | { 70 | n_materials 1 71 | 72 | property_format polynomial 73 | material_0 74 | { 75 | solid 76 | { 77 | density 7904; [kg/m^3] For now all the states needs to have the same 78 | ; density. 79 | specific_heat 714; [J/kg K] 80 | thermal_conductivity_x 31.4 ; [W/m K] 81 | thermal_conductivity_y 31.4 ; [W/m K] 82 | thermal_conductivity_z 31.4 ; [W/m K] 83 | } 84 | 85 | powder 86 | { 87 | specific_heat 714; [J/kg K] 88 | density 7904; [kg/m^3] 89 | thermal_conductivity_x 0.314 ; [W/m K] 90 | thermal_conductivity_y 0.314 ; [W/m K] 91 | thermal_conductivity_z 0.314 ; [W/m K] 92 | } 93 | 94 | liquid 95 | { 96 | specific_heat 847; [J/kg K] 97 | density 7904; [kg/m^3] 98 | thermal_conductivity_x 37.3 ; [W/m k] 99 | thermal_conductivity_y 37.3 ; [W/m k] 100 | thermal_conductivity_z 37.3 ; [W/m k] 101 | ; Not all three states need to define the same properties or to exist 102 | } 103 | 104 | solidus 1675; [K] 105 | liquidus 1708; [K] 106 | latent_heat 290000 ; [J/kg] 107 | } 108 | } 109 | 110 | sources 111 | { 112 | n_beams 1 113 | 114 | beam_0 115 | { 116 | type goldak ; goldak (laser) or electron_beam 117 | depth 0.5e-3 ; [m] maximum depth reached by the laser 118 | diameter 0.6e-3 ; [m] 119 | scan_path_file bare_plate_L_scan_path.txt 120 | scan_path_file_format segment 121 | absorption_efficiency 0.4 ; number between 0 and 1 equivalent to 122 | ; energy_conversion_efficiency * control_efficiency 123 | ; for an electron beam 124 | max_power 400.0 ; [W], current * voltage for an electron beam 125 | } 126 | } 127 | 128 | time_stepping 129 | { 130 | method forward_euler ; Possibilities: backward_euler, implicit_midpoint, 131 | ; crank_nicolson, sdirk2, forward_euler, rk_third_order, 132 | ; rk_fourth_order 133 | duration 5.0e-2 ; [s] 134 | time_step 1.0e-4 ; [s] 135 | } 136 | 137 | post_processor 138 | { 139 | filename_prefix output 140 | time_steps_between_output 20 141 | } 142 | 143 | discretization 144 | { 145 | thermal 146 | { 147 | fe_degree 3 148 | quadrature gauss ; Optional parameter. Possibilities: gauss or lobatto 149 | } 150 | } 151 | 152 | profiling 153 | { 154 | timer false 155 | caliper "spot(profile.mpi),loop-report,runtime-report" 156 | } 157 | 158 | memory_space host ; Always run on the host 159 | -------------------------------------------------------------------------------- /tests/data/bare_plate_L_ensemble.info: -------------------------------------------------------------------------------- 1 | ensemble 2 | { 3 | ensemble_simulation true 4 | ensemble_size 3 5 | materials 6 | { 7 | initial_temperature_stddev 10.0 8 | } 9 | } 10 | 11 | physics 12 | { 13 | thermal true 14 | mechanical false 15 | } 16 | 17 | geometry 18 | { 19 | import_mesh false ; Use built-in mesh generator 20 | dim 3 ; dimension of the domain 21 | length 5.0e-3 ; [m] 22 | height 0.5e-3 ; [m] In 3D, the third parameters is width 23 | width 5.0e-3 24 | length_divisions 25 ; Number of cell layers in the length direction 25 | height_divisions 2 ; Number of cell layers in the height direction 26 | width_divisions 25 27 | } 28 | 29 | boundary 30 | { 31 | type adiabatic ; convective,radiative 32 | } 33 | 34 | refinement 35 | { 36 | n_refinements 0 ; Number of time the cells on the paths of the beams are 37 | ; refined 38 | time_steps_between_refinement 2000000000 ; number of time steps after which 39 | ; the refinement process is performed 40 | } 41 | 42 | materials 43 | { 44 | n_materials 1 45 | 46 | property_format polynomial 47 | initial_temperature 300 48 | 49 | material_0 50 | { 51 | solid 52 | { 53 | density 7904; [kg/m^3] For now all the states needs to have the same 54 | ; density. 55 | specific_heat 714; [J/kg K] 56 | thermal_conductivity_x 31.4 ; [W/m K] 57 | thermal_conductivity_y 31.4 ; [W/m K] 58 | thermal_conductivity_z 31.4 ; [W/m K] 59 | } 60 | 61 | powder 62 | { 63 | specific_heat 714; [J/kg K] 64 | density 7904; [kg/m^3] 65 | thermal_conductivity_x 0.314 ; [W/m K] 66 | thermal_conductivity_y 0.314 ; [W/m K] 67 | thermal_conductivity_z 0.314 ; [W/m K] 68 | } 69 | 70 | liquid 71 | { 72 | specific_heat 847; [J/kg K] 73 | density 7904; [kg/m^3] 74 | thermal_conductivity_x 37.3 ; [W/m k] 75 | thermal_conductivity_y 37.3 ; [W/m k] 76 | thermal_conductivity_z 37.3 ; [W/m k] 77 | ; Not all three states need to define the same properties or to exist 78 | } 79 | 80 | solidus 1675; [K] 81 | liquidus 1708; [K] 82 | latent_heat 290000 ; [J/kg] 83 | } 84 | } 85 | 86 | sources 87 | { 88 | n_beams 1 89 | 90 | beam_0 91 | { 92 | type goldak ; goldak (laser) or electron_beam 93 | depth 0.5e-3 ; [m] maximum depth reached by the laser 94 | diameter 0.6e-3 ; [m] 95 | scan_path_file bare_plate_L_scan_path.txt 96 | scan_path_file_format segment 97 | absorption_efficiency 0.3 ; number between 0 and 1 equivalent to 98 | ; energy_conversion_efficiency * control_efficiency 99 | ; for an electron beam 100 | max_power 400.0 ; [W], current * voltage for an electron beam 101 | } 102 | } 103 | 104 | time_stepping 105 | { 106 | method forward_euler ; Possibilities: backward_euler, implicit_midpoint, 107 | ; crank_nicolson, sdirk2, forward_euler, rk_third_order, 108 | ; rk_fourth_order 109 | duration 5.0e-2 ; [s] 110 | time_step 5.0e-5 ; [s] 111 | } 112 | 113 | post_processor 114 | { 115 | filename_prefix output 116 | time_steps_between_output 10 117 | } 118 | 119 | discretization 120 | { 121 | thermal 122 | { 123 | fe_degree 3 124 | quadrature gauss ; Optional parameter. Possibilities: gauss or lobatto 125 | } 126 | } 127 | 128 | profiling 129 | { 130 | timer false 131 | caliper "spot(profile.mpi),loop-report,runtime-report" 132 | } 133 | 134 | memory_space host ; Always run on the host 135 | -------------------------------------------------------------------------------- /tests/data/bare_plate_L_expt_data_0_0.csv: -------------------------------------------------------------------------------- 1 | "x", "y", "z", "T" 2 | 0.001, 0.001, 0.005, 200.0 3 | -------------------------------------------------------------------------------- /tests/data/bare_plate_L_expt_data_0_1.csv: -------------------------------------------------------------------------------- 1 | "x", "y", "z", "T" 2 | 0.0045, 0.0005, 0.0005, 250.0 3 | -------------------------------------------------------------------------------- /tests/data/bare_plate_L_expt_log.txt: -------------------------------------------------------------------------------- 1 | 0, 0.0105, 2 | 1, 0.021, 3 | -------------------------------------------------------------------------------- /tests/data/bare_plate_L_scan_path.txt: -------------------------------------------------------------------------------- 1 | Number of path segments 2 | 3 3 | Mode x y z pmod param 4 | 1 2.1e-3 2.1e-3 0.5e-3 0 1e-6 5 | 0 2.1e-3 4.1e-3 0.5e-3 1 0.1 6 | 0 4.1e-3 4.1e-3 0.5e-3 1 0.1 7 | -------------------------------------------------------------------------------- /tests/data/bare_plate_L_scan_path_fast.txt: -------------------------------------------------------------------------------- 1 | Number of path segments 2 | 3 3 | Mode x y z pmod param 4 | 1 2.1e-3 2.1e-3 0.5e-3 0 1e-6 5 | 0 2.1e-3 4.1e-3 0.5e-3 1 16.0 6 | 0 4.1e-3 4.1e-3 0.5e-3 1 16.0 7 | -------------------------------------------------------------------------------- /tests/data/demo_316_short.info: -------------------------------------------------------------------------------- 1 | geometry 2 | { 3 | import_mesh false ; Use built-in mesh generator 4 | dim 3 ; dimension of the domain 5 | length 10e-3 ; [m] 6 | height 2.0e-3 ; [m] In 3D, the third parameters is width 7 | width 10e-3 8 | length_divisions 50 ; Number of cell layers in the length direction 9 | height_divisions 8 ; Number of cell layers in the height direction 10 | width_divisions 50 11 | material_deposition true 12 | material_deposition_method scan_paths 13 | deposition_length 0.0003 14 | deposition_height 0.0002 15 | deposition_width 0.0003 16 | deposition_lead_time 0.0005 17 | material_height 0.75e-3 18 | } 19 | 20 | boundary 21 | { 22 | type convective,radiative 23 | } 24 | 25 | physics 26 | { 27 | thermal true 28 | mechanical false 29 | } 30 | 31 | refinement 32 | { 33 | n_refinements 0 ; Number of time the cells on the paths of the beams are 34 | ; refined 35 | time_steps_between_refinement 2000000000 ; number of time steps after which 36 | ; the refinement process is performed 37 | } 38 | 39 | materials 40 | { 41 | n_materials 1 42 | 43 | property_format polynomial 44 | material_0 45 | { 46 | solid 47 | { 48 | density 7904; [kg/m^3] For now all the states needs to have the same 49 | ; density. 50 | specific_heat 714; [J/kg K] 51 | thermal_conductivity_x 31.4 ; [W/m K] 52 | thermal_conductivity_y 31.4 ; [W/m K] 53 | thermal_conductivity_z 31.4 ; [W/m K] 54 | convection_heat_transfer_coef 100 ; [W/(m^2*K)] 55 | emissivity 0.15 56 | } 57 | 58 | powder 59 | { 60 | specific_heat 714; [J/kg K] 61 | density 7904; [kg/m^3] 62 | thermal_conductivity_x 0.314 ; [W/m K] 63 | thermal_conductivity_y 0.314 ; [W/m K] 64 | thermal_conductivity_z 0.314 ; [W/m K] 65 | convection_heat_transfer_coef 100 ; [W/(m^2*K)] 66 | emissivity 0.15 67 | } 68 | 69 | liquid 70 | { 71 | specific_heat 847; [J/kg K] 72 | density 7904; [kg/m^3] 73 | thermal_conductivity_x 37.3 ; [W/m k] 74 | thermal_conductivity_y 37.3 ; [W/m k] 75 | thermal_conductivity_z 37.3 ; [W/m k] 76 | convection_heat_transfer_coef 100 ; [W/(m^2*K)] 77 | emissivity 0.15 78 | ; Not all three states need to define the same properties or to exist 79 | } 80 | 81 | solidus 1675; [K] 82 | liquidus 1708; [K] 83 | latent_heat 290000 ; [J/kg] 84 | radiation_temperature_infty 300 ; [K] 85 | convection_temperature_infty 300 ; [K] 86 | } 87 | } 88 | 89 | sources 90 | { 91 | n_beams 1 92 | 93 | beam_0 94 | { 95 | type goldak ; goldak (laser) or electron_beam 96 | depth 0.5e-3 ; [m] maximum depth reached by the laser 97 | diameter 0.6e-3 ; [m] 98 | scan_path_file demo_316_short_scan_path.txt 99 | scan_path_file_format segment 100 | absorption_efficiency 0.3 ; number between 0 and 1 equivalent to 101 | ; energy_conversion_efficiency * control_efficiency 102 | ; for an electron beam 103 | max_power 400.0 ; [W], current * voltage for an electron beam 104 | } 105 | } 106 | 107 | time_stepping 108 | { 109 | method forward_euler ; Possibilities: backward_euler, implicit_midpoint, 110 | ; crank_nicolson, sdirk2, forward_euler, rk_third_order, 111 | ; rk_fourth_order 112 | duration 0.004 ; [s] 113 | time_step 0.6e-4 ; [s] 114 | } 115 | 116 | post_processor 117 | { 118 | filename_prefix output 119 | time_steps_between_output 10 120 | } 121 | 122 | discretization 123 | { 124 | thermal 125 | { 126 | fe_degree 3 127 | quadrature gauss ; Optional parameter. Possibilities: gauss or lobatto 128 | } 129 | } 130 | 131 | profiling 132 | { 133 | timer false 134 | caliper "spot(profile.mpi),loop-report,runtime-report" 135 | } 136 | 137 | memory_space host ; Always run on the host 138 | -------------------------------------------------------------------------------- /tests/data/demo_316_short_amr.info: -------------------------------------------------------------------------------- 1 | geometry 2 | { 3 | import_mesh false ; Use built-in mesh generator 4 | dim 3 ; dimension of the domain 5 | length 5e-3 ; [m] 6 | height 5e-4 ; [m] In 3D, the third parameters is width 7 | width 5e-3 8 | length_divisions 25 ; Number of cell layers in the length direction 9 | height_divisions 2 ; Number of cell layers in the height direction 10 | width_divisions 25 11 | material_deposition true 12 | material_deposition_method scan_paths 13 | deposition_length 0.0003 14 | deposition_height 0.0002 15 | deposition_width 0.0003 16 | deposition_lead_time 0.0005 17 | material_height 0.75e-3 18 | } 19 | 20 | boundary 21 | { 22 | type convective,radiative 23 | } 24 | 25 | physics 26 | { 27 | thermal true 28 | mechanical false 29 | } 30 | 31 | refinement 32 | { 33 | n_refinements 1 ; Number of time the cells on the paths of the beams are 34 | ; refined 35 | time_steps_between_refinement 5 ; number of time steps after which 36 | ; the refinement process is performed 37 | coarsen_after_beam true 38 | } 39 | 40 | materials 41 | { 42 | n_materials 1 43 | 44 | property_format polynomial 45 | material_0 46 | { 47 | solid 48 | { 49 | density 7904; [kg/m^3] For now all the states needs to have the same 50 | ; density. 51 | specific_heat 714; [J/kg K] 52 | thermal_conductivity_x 31.4 ; [W/m K] 53 | thermal_conductivity_y 31.4 ; [W/m K] 54 | thermal_conductivity_z 31.4 ; [W/m K] 55 | convection_heat_transfer_coef 100 ; [W/(m^2*K)] 56 | emissivity 0.15 57 | } 58 | 59 | powder 60 | { 61 | specific_heat 714; [J/kg K] 62 | density 7904; [kg/m^3] 63 | thermal_conductivity_x 0.314 ; [W/m K] 64 | thermal_conductivity_y 0.314 ; [W/m K] 65 | thermal_conductivity_z 0.314 ; [W/m K] 66 | convection_heat_transfer_coef 100 ; [W/(m^2*K)] 67 | emissivity 0.15 68 | } 69 | 70 | liquid 71 | { 72 | specific_heat 847; [J/kg K] 73 | density 7904; [kg/m^3] 74 | thermal_conductivity_x 37.3 ; [W/m k] 75 | thermal_conductivity_y 37.3 ; [W/m k] 76 | thermal_conductivity_z 37.3 ; [W/m k] 77 | convection_heat_transfer_coef 100 ; [W/(m^2*K)] 78 | emissivity 0.15 79 | ; Not all three states need to define the same properties or to exist 80 | } 81 | 82 | solidus 1675; [K] 83 | liquidus 1708; [K] 84 | latent_heat 290000 ; [J/kg] 85 | radiation_temperature_infty 300 ; [K] 86 | convection_temperature_infty 300 ; [K] 87 | } 88 | } 89 | 90 | sources 91 | { 92 | n_beams 1 93 | 94 | beam_0 95 | { 96 | type goldak ; goldak (laser) or electron_beam 97 | depth 0.5e-3 ; [m] maximum depth reached by the laser 98 | diameter 0.6e-3 ; [m] 99 | scan_path_file demo_316_short_scan_path_amr.txt 100 | scan_path_file_format segment 101 | absorption_efficiency 0.3 ; number between 0 and 1 equivalent to 102 | ; energy_conversion_efficiency * control_efficiency 103 | ; for an electron beam 104 | max_power 400.0 ; [W], current * voltage for an electron beam 105 | } 106 | } 107 | 108 | time_stepping 109 | { 110 | method forward_euler ; Possibilities: backward_euler, implicit_midpoint, 111 | ; crank_nicolson, sdirk2, forward_euler, rk_third_order, 112 | ; rk_fourth_order 113 | duration 0.004 ; [s] 114 | time_step 1.0e-4 ; [s] 115 | } 116 | 117 | post_processor 118 | { 119 | filename_prefix output 120 | time_steps_between_output 10 121 | } 122 | 123 | discretization 124 | { 125 | thermal 126 | { 127 | fe_degree 2 128 | quadrature gauss ; Optional parameter. Possibilities: gauss or lobatto 129 | } 130 | } 131 | 132 | profiling 133 | { 134 | timer false 135 | caliper "spot(profile.mpi),loop-report,runtime-report" 136 | } 137 | 138 | memory_space host ; Always run on the host 139 | -------------------------------------------------------------------------------- /tests/data/demo_316_short_anisotropic.info: -------------------------------------------------------------------------------- 1 | geometry 2 | { 3 | import_mesh false ; Use built-in mesh generator 4 | dim 3 ; dimension of the domain 5 | length 10e-3 ; [m] 6 | height 2.0e-3 ; [m] In 3D, the third parameters is width 7 | width 10e-3 8 | length_divisions 30 ; Number of cell layers in the length direction 9 | height_divisions 8 ; Number of cell layers in the height direction 10 | width_divisions 30 11 | material_deposition true 12 | material_deposition_method scan_paths 13 | deposition_length 0.0003 14 | deposition_height 0.0002 15 | deposition_width 0.0003 16 | deposition_lead_time 0.0005 17 | material_height 0.75e-3 18 | } 19 | 20 | boundary 21 | { 22 | type adiabatic 23 | } 24 | 25 | physics 26 | { 27 | thermal true 28 | mechanical false 29 | } 30 | 31 | refinement 32 | { 33 | n_refinements 0 ; Number of time the cells on the paths of the beams are 34 | ; refined 35 | time_steps_between_refinement 2000000000 ; number of time steps after which 36 | ; the refinement process is performed 37 | } 38 | 39 | materials 40 | { 41 | n_materials 1 42 | 43 | property_format polynomial 44 | material_0 45 | { 46 | solid 47 | { 48 | density 7904; [kg/m^3] For now all the states needs to have the same 49 | ; density. 50 | specific_heat 714; [J/kg K] 51 | thermal_conductivity_x 47.1 ; [W/m K] 52 | thermal_conductivity_y 31.4 ; [W/m K] 53 | thermal_conductivity_z 31.4 ; [W/m K] 54 | 55 | } 56 | 57 | powder 58 | { 59 | specific_heat 714; [J/kg K] 60 | density 7904; [kg/m^3] 61 | thermal_conductivity_x 0.471 ; [W/m K] 62 | thermal_conductivity_y 0.314 ; [W/m K] 63 | thermal_conductivity_z 0.314 ; [W/m K] 64 | } 65 | 66 | liquid 67 | { 68 | specific_heat 847; [J/kg K] 69 | density 7904; [kg/m^3] 70 | thermal_conductivity_x 55.95 ; [W/m k] 71 | thermal_conductivity_y 37.3 ; [W/m k] 72 | thermal_conductivity_z 37.3 ; [W/m k] 73 | ; Not all three states need to define the same properties or to exist 74 | } 75 | 76 | solidus 1675; [K] 77 | liquidus 1708; [K] 78 | latent_heat 290000 ; [J/kg] 79 | } 80 | } 81 | 82 | sources 83 | { 84 | n_beams 1 85 | 86 | beam_0 87 | { 88 | type goldak ; goldak (laser) or electron_beam 89 | depth 0.5e-3 ; [m] maximum depth reached by the laser 90 | diameter 0.6e-3 ; [m] 91 | scan_path_file demo_316_short_scan_path.txt 92 | scan_path_file_format segment 93 | absorption_efficiency 0.3 ; number between 0 and 1 equivalent to 94 | ; energy_conversion_efficiency * control_efficiency 95 | ; for an electron beam 96 | max_power 400.0 ; [W], current * voltage for an electron beam 97 | } 98 | } 99 | 100 | time_stepping 101 | { 102 | method forward_euler ; Possibilities: backward_euler, implicit_midpoint, 103 | ; crank_nicolson, sdirk2, forward_euler, rk_third_order, 104 | ; rk_fourth_order 105 | duration 0.001 ; [s] 106 | time_step 1e-5 ; [s] 107 | } 108 | 109 | post_processor 110 | { 111 | filename_prefix output 112 | time_steps_between_output 1000 113 | } 114 | 115 | discretization 116 | { 117 | thermal 118 | { 119 | fe_degree 2 120 | quadrature gauss ; Optional parameter. Possibilities: gauss or lobatto 121 | } 122 | } 123 | 124 | profiling 125 | { 126 | timer false 127 | } 128 | 129 | memory_space host ; Always run on the host 130 | -------------------------------------------------------------------------------- /tests/data/demo_316_short_scan_path.txt: -------------------------------------------------------------------------------- 1 | Number of path segments 2 | 3 3 | Mode x y z pmod param 4 | 1 2.1e-3 2.1e-3 0.75e-3 0 1e-6 5 | 0 2.1e-3 4.1e-3 0.75e-3 1 1.0 6 | 0 3.1e-3 4.1e-3 0.75e-3 1 1.0 7 | -------------------------------------------------------------------------------- /tests/data/demo_316_short_scan_path_amr.txt: -------------------------------------------------------------------------------- 1 | Number of path segments 2 | 3 3 | Mode x y z pmod param 4 | 1 2.2e-3 2.2e-3 0.95e-3 0 1e-6 5 | 0 2.2e-3 4.0e-3 0.95e-3 1 1.0 6 | 0 3.2e-3 4.0e-3 0.95e-3 1 1.0 7 | -------------------------------------------------------------------------------- /tests/data/experiment_log_test.txt: -------------------------------------------------------------------------------- 1 | 0, 0.0005, 0.0006, 2 | 1, 0.0105, 0.0106, 3 | 2, 0.0240, 0.0242, 4 | 3, 0.0450, 0.0454, 5 | 4, 0.0480, 0.0481, 6 | -------------------------------------------------------------------------------- /tests/data/experimental_data_0_0.csv: -------------------------------------------------------------------------------- 1 | "x", "y", "z", "T" 2 | 0,0,1,1.2 3 | 0,0.5,1,1.3 4 | 0,1,1,1.4 5 | 0.5,0,1,1.5 6 | 0.5,0.5,1,1.6 7 | 0.5,1,1,1.7 8 | 1,0,1,1.8 9 | 1,0.5,1,1.9 10 | 1,1,1,2. 11 | -------------------------------------------------------------------------------- /tests/data/hexahedra.geo: -------------------------------------------------------------------------------- 1 | // 8 vertices of the domain 2 | Point(1) = {0, 0, 0, 1e-2}; 3 | Point(2) = {0.1, 0.5, 0, 1e-2}; 4 | Point(3) = {1.3, 0.8, 0, 1e-2}; 5 | Point(4) = {0.9, 0.2, 0, 1e-2}; 6 | Point(5) = {0, 0, 1, 1e-2}; 7 | Point(6) = {0.1, 0.5, 1.6, 1e-2}; 8 | Point(7) = {1.3, 0.8, 3.1, 1e-2}; 9 | Point(8) = {0.9, 0.2, 2.1, 1e-2}; 10 | 11 | // Bottom face 12 | Line(1) = {1, 2}; 13 | Line(2) = {2, 3}; 14 | Line(3) = {3, 4}; 15 | Line(4) = {4, 1}; 16 | Curve Loop(1) = {1, 2, 3, 4}; 17 | Plane Surface(1) = {1}; 18 | 19 | // Top face 20 | Line(5) = {5, 6}; 21 | Line(6) = {6, 7}; 22 | Line(7) = {7, 8}; 23 | Line(8) = {8, 5}; 24 | Curve Loop(2) = {5, 6, 7, 8}; 25 | Plane Surface(2) = {2}; 26 | 27 | // Front face 28 | Line(9) = {2, 6}; 29 | Line(10) = {5, 1}; 30 | Curve Loop(3) = {1, 9, -5, 10}; 31 | Plane Surface(3) = {3}; 32 | 33 | // Back face 34 | Line(11) = {3, 7}; 35 | Line(12) = {8, 4}; 36 | Curve Loop(4) = {-3, 11, 7, 12}; 37 | Plane Surface(4) = {4}; 38 | 39 | // Left face 40 | Curve Loop(5) = {4, -10, -8, 12}; 41 | Plane Surface(5) = {5}; 42 | 43 | // Right face 44 | Curve Loop(6) = {2, 11, -6, -9}; 45 | Plane Surface(6) = {6}; 46 | 47 | // Volume 48 | Surface Loop(1) = {1, 2, 3, 4, 5, 6}; 49 | Volume(1) = {1}; 50 | -------------------------------------------------------------------------------- /tests/data/integration_2d.info: -------------------------------------------------------------------------------- 1 | geometry 2 | { 3 | import_mesh false ; Use builtin mesh generator 4 | dim 2 ; dimension of the domain 5 | length 2e-2 ; [m] 6 | height 1e-2 ; [m] In 3D, the third parameters is width 7 | length_divisions 20 ; Number of cell layers in the length direction 8 | height_divisions 10 ; Number of cell layers in the height direction 9 | } 10 | 11 | physics 12 | { 13 | thermal true 14 | mechanical false 15 | } 16 | 17 | refinement 18 | { 19 | n_refinements 2 ; Number of time the cells on the paths of the beams are 20 | ; refined 21 | } 22 | 23 | materials 24 | { 25 | property_format polynomial 26 | 27 | n_materials 1 28 | 29 | material_0 30 | { 31 | solid 32 | { 33 | density 7541 ; [kg/m^3] For now all the states needs to have the same 34 | ; density. The value can be constant or an equation 35 | specific_heat 600 ; [J/kg K] The value can be constant or an equation 36 | thermal_conductivity_x 26.6 ; [W/m K] 37 | thermal_conductivity_z 26.6 ; [W/m K] 38 | ; The value can be constant or an equation like 10*exp(T)*sin(2.*T) 39 | } 40 | 41 | powder 42 | { 43 | specific_heat 600 ; [J/kg K] 44 | density 7541 ; [kg/m^3] 45 | thermal_conductivity_x 0.266 ; [W/m K] 46 | thermal_conductivity_z 0.266 ; [W/m K] 47 | } 48 | 49 | liquid 50 | { 51 | specific_heat 775 ; [J/kg K] 52 | density 7541 ; [kg/m^3] 53 | thermal_conductivity_x 29.0 ; [W/m k] 54 | thermal_conductivity_z 29.0 ; [W/m k] 55 | ; Not all three states need to define the same properties or to exist 56 | } 57 | 58 | solidus 1528 ; [K] 59 | liquidus 1610 ; [K] 60 | latent_heat 227000 ; [J/kg] 61 | } 62 | } 63 | 64 | sources 65 | { 66 | n_beams 1 67 | 68 | beam_0 69 | { 70 | depth 1e-3 ; [m] maximum depth reached by the laser 71 | diameter 1e-3 ; [m] 72 | scan_path_file scan_path.txt 73 | scan_path_file_format segment 74 | absorption_efficiency 0.3 75 | max_power 1200.0 76 | type electron_beam 77 | } 78 | } 79 | 80 | time_stepping 81 | { 82 | method backward_euler ; Possibilities: backward_euler, implicit_midpoint, 83 | ; crank_nicolson, sdirk2, forward_euler, rk_third_order, 84 | ; rk_fourth_order 85 | duration 1e-9 ; [s] 86 | time_step 5e-11 ; [s] 87 | } 88 | 89 | post_processor 90 | { 91 | filename_prefix output 92 | } 93 | 94 | discretization 95 | { 96 | thermal 97 | { 98 | fe_degree 3 99 | quadrature gauss ; Optional parameter. Possibilities: gauss or lobatto 100 | } 101 | } 102 | 103 | boundary 104 | { 105 | type adiabatic 106 | } 107 | -------------------------------------------------------------------------------- /tests/data/integration_2d_ensemble.info: -------------------------------------------------------------------------------- 1 | ensemble 2 | { 3 | ensemble_simulation true ; Whether to use data assimilation 4 | ensemble_size 3 ; Size of the ensemble for data assimilation 5 | } 6 | 7 | geometry 8 | { 9 | import_mesh false ; Use builtin mesh generator 10 | dim 2 ; dimension of the domain 11 | length 2e-2 ; [m] 12 | height 1e-2 ; [m] In 3D, the third parameters is width 13 | length_divisions 20 ; Number of cell layers in the length direction 14 | height_divisions 10 ; Number of cell layers in the height direction 15 | } 16 | 17 | physics 18 | { 19 | thermal true 20 | mechanical false 21 | } 22 | 23 | refinement 24 | { 25 | n_refinements 2 ; Number of time the cells on the paths of the beams are 26 | ; refined 27 | } 28 | 29 | materials 30 | { 31 | property_format polynomial 32 | 33 | n_materials 1 34 | 35 | material_0 36 | { 37 | solid 38 | { 39 | density 7541 ; [kg/m^3] For now all the states needs to have the same 40 | ; density. The value can be constant or an equation 41 | specific_heat 600 ; [J/kg K] The value can be constant or an equation 42 | thermal_conductivity_x 26.6 ; [W/m K] 43 | thermal_conductivity_z 26.6 ; [W/m K] 44 | ; The value can be constant or an equation like 10*exp(T)*sin(2.*T) 45 | } 46 | 47 | powder 48 | { 49 | specific_heat 600 ; [J/kg K] 50 | density 7541 ; [kg/m^3] 51 | thermal_conductivity_x 0.266 ; [W/m K] 52 | thermal_conductivity_z 0.266 ; [W/m K] 53 | } 54 | 55 | liquid 56 | { 57 | specific_heat 775 ; [J/kg K] 58 | density 7541 ; [kg/m^3] 59 | thermal_conductivity_x 29.0 ; [W/m k] 60 | thermal_conductivity_z 29.0 ; [W/m k] 61 | ; Not all three states need to define the same properties or to exist 62 | } 63 | 64 | solidus 1528 ; [K] 65 | liquidus 1610 ; [K] 66 | latent_heat 227000 ; [J/kg] 67 | } 68 | } 69 | 70 | sources 71 | { 72 | n_beams 1 73 | 74 | beam_0 75 | { 76 | depth 1e-3 ; [m] maximum depth reached by the laser 77 | diameter 1e-3 ; [m] 78 | scan_path_file scan_path.txt 79 | scan_path_file_format segment 80 | absorption_efficiency 0.3 81 | max_power 1200.0 82 | type electron_beam 83 | } 84 | } 85 | 86 | time_stepping 87 | { 88 | method backward_euler ; Possibilities: backward_euler, implicit_midpoint, 89 | ; crank_nicolson, sdirk2, forward_euler, rk_third_order, 90 | ; rk_fourth_order 91 | duration 1e-9 ; [s] 92 | time_step 5e-11 ; [s] 93 | } 94 | 95 | post_processor 96 | { 97 | filename_prefix output 98 | } 99 | 100 | discretization 101 | { 102 | thermal 103 | { 104 | fe_degree 3 105 | quadrature gauss ; Optional parameter. Possibilities: gauss or lobatto 106 | } 107 | } 108 | 109 | boundary 110 | { 111 | type adiabatic 112 | } 113 | -------------------------------------------------------------------------------- /tests/data/integration_2d_units.info: -------------------------------------------------------------------------------- 1 | units 2 | { 3 | mesh millimeter 4 | heat_source 5 | { 6 | scan_path millimeter 7 | dimension millimeter 8 | power milliwatt 9 | velocity millimeter/second 10 | } 11 | } 12 | 13 | 14 | geometry 15 | { 16 | import_mesh false ; Use builtin mesh generator 17 | dim 2 ; dimension of the domain 18 | length 2e1 ; 19 | height 1e1 ; In 3D, the third parameters is width 20 | length_divisions 20 ; Number of cell layers in the length direction 21 | height_divisions 10 ; Number of cell layers in the height direction 22 | } 23 | 24 | physics 25 | { 26 | thermal true 27 | mechanical false 28 | } 29 | 30 | refinement 31 | { 32 | n_refinements 2 ; Number of time the cells on the paths of the beams are 33 | ; refined 34 | } 35 | 36 | materials 37 | { 38 | property_format polynomial 39 | 40 | n_materials 1 41 | 42 | material_0 43 | { 44 | solid 45 | { 46 | density 7541 ; [kg/m^3] For now all the states needs to have the same 47 | ; density. The value can be constant or an equation 48 | specific_heat 600 ; [J/kg K] The value can be constant or an equation 49 | thermal_conductivity_x 26.6 ; [W/m K] 50 | thermal_conductivity_z 26.6 ; [W/m K] 51 | ; The value can be constant or an equation like 10*exp(T)*sin(2.*T) 52 | } 53 | 54 | powder 55 | { 56 | specific_heat 600 ; [J/kg K] 57 | density 7541 ; [kg/m^3] 58 | thermal_conductivity_x 0.266 ; [W/m K] 59 | thermal_conductivity_z 0.266 ; [W/m K] 60 | } 61 | 62 | liquid 63 | { 64 | specific_heat 775 ; [J/kg K] 65 | density 7541 ; [kg/m^3] 66 | thermal_conductivity_x 29.0 ; [W/m k] 67 | thermal_conductivity_z 29.0 ; [W/m k] 68 | ; Not all three states need to define the same properties or to exist 69 | } 70 | 71 | solidus 1528 ; [K] 72 | liquidus 1610 ; [K] 73 | latent_heat 227000 ; [J/kg] 74 | } 75 | } 76 | 77 | sources 78 | { 79 | n_beams 1 80 | 81 | beam_0 82 | { 83 | depth 1 ; maximum depth reached by the laser 84 | diameter 1 ; 85 | scan_path_file scan_path_units.txt 86 | scan_path_file_format segment 87 | absorption_efficiency 0.3 88 | max_power 1200000.0 89 | type electron_beam 90 | } 91 | } 92 | 93 | time_stepping 94 | { 95 | method backward_euler ; Possibilities: backward_euler, implicit_midpoint, 96 | ; crank_nicolson, sdirk2, forward_euler, rk_third_order, 97 | ; rk_fourth_order 98 | duration 1e-9 ; [s] 99 | time_step 5e-11 ; [s] 100 | } 101 | 102 | post_processor 103 | { 104 | filename_prefix output 105 | } 106 | 107 | discretization 108 | { 109 | thermal 110 | { 111 | fe_degree 3 112 | quadrature gauss ; Optional parameter. Possibilities: gauss or lobatto 113 | } 114 | } 115 | 116 | boundary 117 | { 118 | type adiabatic 119 | } 120 | -------------------------------------------------------------------------------- /tests/data/integration_da_add_material.info: -------------------------------------------------------------------------------- 1 | ensemble 2 | { 3 | ensemble_simulation true 4 | ensemble_size 3 5 | materials 6 | { 7 | initial_temperature_stddev 5.0 8 | } 9 | sources 10 | { 11 | beam_0 12 | { 13 | absorption_efficiency_stddev 0.05 14 | } 15 | } 16 | } 17 | experiment 18 | { 19 | read_in_experimental_data true 20 | log_filename integration_da_add_material_expt_log.txt 21 | file integration_da_add_material_expt_pc_#camera_#frame.csv 22 | format point_cloud 23 | first_frame 0 24 | last_frame 0 25 | first_camera_id 0 26 | last_camera_id 0 27 | first_frame_temporal_offset 0.06 28 | estimated_uncertainty 1.0 29 | } 30 | data_assimilation 31 | { 32 | assimilate_data true 33 | localization_cutoff_function gaspari_cohn 34 | localization_cutoff_distance 5.0e-1 35 | solver 36 | { 37 | max_number_of_temp_vectors 10 38 | convergence_tolerance 1.0e-8 39 | } 40 | } 41 | 42 | geometry 43 | { 44 | import_mesh false ; Use built-in mesh generator 45 | dim 3 ; dimension of the domain 46 | length 100.0e-3 ; [m] 47 | height 20.0e-3 ; [m] In 3D, the third parameters is width 48 | width 100.0e-3 49 | length_divisions 3 ; Number of cell layers in the length direction 50 | height_divisions 3 ; Number of cell layers in the height direction 51 | width_divisions 3 52 | material_deposition true 53 | material_deposition_method scan_paths 54 | deposition_length 2.0e-3 55 | deposition_height 2.0e-3 56 | deposition_width 2.0e-3 57 | deposition_lead_time 1.0e0 58 | material_height 14.0e-3 59 | } 60 | 61 | physics 62 | { 63 | thermal true 64 | mechanical false 65 | } 66 | 67 | boundary 68 | { 69 | type adiabatic ; convective,radiative 70 | } 71 | 72 | refinement 73 | { 74 | n_refinements 0 ; Number of time the cells on the paths of the beams are 75 | ; refined 76 | time_steps_between_refinement 200000 ; number of time steps after which 77 | ; the refinement process is performed 78 | } 79 | 80 | materials 81 | { 82 | n_materials 1 83 | 84 | property_format polynomial 85 | initial_temperature 285 86 | 87 | material_0 88 | { 89 | solid 90 | { 91 | density 7904; [kg/m^3] For now all the states needs to have the same 92 | ; density. 93 | specific_heat 714; [J/kg K] 94 | thermal_conductivity_x 31.4 ; [W/m K] 95 | thermal_conductivity_y 31.4 ; [W/m K] 96 | thermal_conductivity_z 31.4 ; [W/m K] 97 | } 98 | 99 | powder 100 | { 101 | specific_heat 714; [J/kg K] 102 | density 7904; [kg/m^3] 103 | thermal_conductivity_x 0.314 ; [W/m K] 104 | thermal_conductivity_y 0.314 ; [W/m K] 105 | thermal_conductivity_z 0.314 ; [W/m K] 106 | } 107 | 108 | liquid 109 | { 110 | specific_heat 847; [J/kg K] 111 | density 7904; [kg/m^3] 112 | thermal_conductivity_x 37.3 ; [W/m k] 113 | thermal_conductivity_y 37.3 ; [W/m k] 114 | thermal_conductivity_z 37.3 ; [W/m k] 115 | ; Not all three states need to define the same properties or to exist 116 | } 117 | 118 | solidus 1675; [K] 119 | liquidus 1708; [K] 120 | latent_heat 290000 ; [J/kg] 121 | } 122 | } 123 | 124 | sources 125 | { 126 | n_beams 1 127 | 128 | beam_0 129 | { 130 | type goldak ; goldak (laser) or electron_beam 131 | depth 3.0e-3 ; [m] maximum depth reached by the laser 132 | diameter 3.0e-3 ; [m] 133 | scan_path_file integration_da_add_material_sp.txt 134 | scan_path_file_format segment 135 | absorption_efficiency 0.6 ; number between 0 and 1 equivalent to 136 | ; energy_conversion_efficiency * control_efficiency 137 | ; for an electron beam 138 | max_power 900.0 ; [W], current * voltage for an electron beam 139 | } 140 | } 141 | 142 | time_stepping 143 | { 144 | method forward_euler ; Possibilities: backward_euler, implicit_midpoint, 145 | ; crank_nicolson, sdirk2, forward_euler, rk_third_order, 146 | ; rk_fourth_order 147 | duration 2.0e-1 ; [s] 148 | time_step 2.0e-2 ; [s] 149 | } 150 | 151 | post_processor 152 | { 153 | filename_prefix output 154 | time_steps_between_output 1 155 | } 156 | 157 | discretization 158 | { 159 | thermal 160 | { 161 | fe_degree 2 162 | quadrature gauss ; Optional parameter. Possibilities: gauss or lobatto 163 | } 164 | mechanical 165 | { 166 | fe_degree 1 167 | quadrature gauss ; Optional parameter. Possibilities: gauss or lobatto 168 | } 169 | } 170 | 171 | profiling 172 | { 173 | timer true 174 | caliper "spot(profile.mpi),loop-report,runtime-report" 175 | } 176 | 177 | memory_space host ; Always run on the host 178 | -------------------------------------------------------------------------------- /tests/data/integration_da_add_material_expt_log.txt: -------------------------------------------------------------------------------- 1 | 0, 0.06, 2 | -------------------------------------------------------------------------------- /tests/data/integration_da_add_material_expt_pc_0_0.csv: -------------------------------------------------------------------------------- 1 | x, y, z, T 2 | 0.05, 0.1, 0.14, 200.0 3 | -------------------------------------------------------------------------------- /tests/data/integration_da_add_material_expt_ray_0_0.csv: -------------------------------------------------------------------------------- 1 | x0, y0, z0, x1, y1, z1, T 2 | 0.08, 0.08, 0.02, 0, 0.5, -1, 200.0 3 | -------------------------------------------------------------------------------- /tests/data/integration_da_add_material_sp.txt: -------------------------------------------------------------------------------- 1 | Number of path segments 2 | 13 3 | Mode x y z pmod param 4 | 1 19.35e-3 46.71e-3 14.0e-3 0 1e-6 5 | 0 79.83e-3 46.71e-3 14.0e-3 1 0.001667 6 | 0 79.83e-3 49.59e-3 14.0e-3 1 0.001667 7 | 0 19.35e-3 49.59e-3 14.0e-3 1 0.001667 8 | 0 19.35e-3 52.47e-3 14.0e-3 1 0.001667 9 | 0 79.83e-3 52.47e-3 14.0e-3 1 0.001667 10 | 1 79.83e-3 52.47e-3 14.0e-3 0 9.0 11 | 1 79.83e-3 52.47e-3 17.5e-3 0 1.0 12 | 0 19.35e-3 52.47e-3 17.5e-3 1 0.001667 13 | 0 19.35e-3 49.59e-3 17.5e-3 1 0.001667 14 | 0 79.83e-3 49.59e-3 17.5e-3 1 0.001667 15 | 0 79.83e-3 46.71e-3 17.5e-3 1 0.001667 16 | 0 19.35e-3 46.71e-3 17.5e-3 1 0.001667 17 | -------------------------------------------------------------------------------- /tests/data/material_deposition_2d.txt: -------------------------------------------------------------------------------- 1 | 2 2 | 0.5 0.5 1. 1. 1. 0. 3 | 5. 6.2 4. 7.6 2. 3.14 4 | 5.5 5.7 3. 6.6 3.4 1.57 5 | 5. 6.2 2 5.6 4.98 -1.57 6 | -------------------------------------------------------------------------------- /tests/data/material_deposition_3d.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 0.5 0.5 0.5 1. 1. 1. 1. 0. 3 | 5. 6.2 1.5 4. 7.6 1. 2. -3.14 4 | 5.5 5.7 3. 3. 6.6 2. 3.4 1.57 5 | 5. 6.2 5.5 2 5.6 5. 4.98 -1.57 6 | -------------------------------------------------------------------------------- /tests/data/material_path_test_material_deposition.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 1. 2.5 6.5 1.9 4.9 0.9 0.1 0. 3 | 3. 2.5 6.5 1.9 4.9 0.9 0.2 -0. 4 | 5. 2.5 6.5 1.9 4.9 0.9 0.3 0.1 5 | 7. 2.5 6.5 1.9 4.9 0.9 0.4 -0.1 6 | 9. 2.5 6.5 1.9 4.9 0.9 0.45 0.2 7 | 1. 7.5 6.5 1.9 4.9 0.9 0.6 -0.2 8 | 3. 7.5 6.5 1.9 4.9 0.9 0.7 0.3 9 | 5. 7.5 6.5 1.9 4.9 0.9 0.8 -0.3 10 | 7. 7.5 6.5 1.9 4.9 0.9 0.9 0.4 11 | 9. 7.5 6.5 1.9 4.9 0.9 0.91 -0.4 12 | 1. 2.5 7.5 1.9 4.9 0.9 0.92 0.5 13 | 3. 2.5 7.5 1.9 4.9 0.9 0.93 -0.5 14 | -------------------------------------------------------------------------------- /tests/data/material_property_polynomial.info: -------------------------------------------------------------------------------- 1 | geometry 2 | { 3 | import_mesh false 4 | length 12 5 | length_divisions 4 6 | height 6 7 | height_divisions 5 8 | } 9 | 10 | materials 11 | { 12 | property_format polynomial 13 | n_materials 2 14 | 15 | material_0 16 | { 17 | solid 18 | { 19 | density 0.,1. 20 | thermal_conductivity_x 0.,1.,2. 21 | thermal_conductivity_z 0.,1.,2. 22 | } 23 | } 24 | material_1 25 | { 26 | solid 27 | { 28 | density 1.,2.,3. 29 | thermal_conductivity_x 1.,100.,20.,200. 30 | thermal_conductivity_z 1.,100.,20.,200. 31 | } 32 | powder 33 | { 34 | density 15.,2.,3. 35 | thermal_conductivity_x 10.,18.,200. 36 | thermal_conductivity_z 10.,18.,200. 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tests/data/material_property_table.info: -------------------------------------------------------------------------------- 1 | geometry 2 | { 3 | import_mesh false 4 | length 12 5 | length_divisions 4 6 | height 6 7 | height_divisions 5 8 | } 9 | 10 | materials 11 | { 12 | property_format table 13 | n_materials 2 14 | 15 | material_0 16 | { 17 | solid 18 | { 19 | density 0.,1. 20 | thermal_conductivity_x 0.,10.|10.,100. 21 | thermal_conductivity_z 0.,10.|10.,100. 22 | density 0.,1.|20.,2.|30.,3. 23 | } 24 | } 25 | 26 | material_1 27 | { 28 | solid 29 | { 30 | density 0.,1.|20.,2.|30.,3. 31 | thermal_conductivity_x 0.,10.|10.,100.|20.,200. 32 | thermal_conductivity_z 0.,10.|10.,100.|20.,200. 33 | } 34 | powder 35 | { 36 | density 0.,1.|15.,2.|30.,3. 37 | thermal_conductivity_x 0.,10.|10.,100.|18.,200. 38 | thermal_conductivity_z 0.,10.|10.,100.|18.,200. 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/data/microstructure_G_R_gold_1.txt: -------------------------------------------------------------------------------- 1 | 0 0 0 954.545455 inf 2 | 0.005 0 0 954.545455 inf 3 | 0.01 0 0 954.545455 inf 4 | 0 0.005 0 954.545455 inf 5 | 0.005 0.005 0 954.545455 inf 6 | 0.01 0.005 0 954.545455 inf 7 | 0 0.01 0 954.545455 inf 8 | 0.005 0.01 0 954.545455 inf 9 | 0.01 0.01 0 954.545455 inf 10 | -------------------------------------------------------------------------------- /tests/data/microstructure_G_R_gold_2.txt: -------------------------------------------------------------------------------- 1 | 0 0 2 954.636364 477.318182 2 | 0.005 0 1.99 954.635457 479.71631 3 | 0.01 0 1.98 954.634555 482.138664 4 | 0 0.005 2.000025 954.636366 477.312217 5 | 0.005 0.005 1.99002513 954.635459 479.710254 6 | 0.01 0.005 1.98002525 954.634557 482.132516 7 | 0 0.01 2.0001 954.636373 477.294322 8 | 0.005 0.01 1.9901005 954.635466 479.692089 9 | 0.01 0.01 1.98010101 954.634564 482.114074 10 | -------------------------------------------------------------------------------- /tests/data/raytracing_experimental_data_0_0.csv: -------------------------------------------------------------------------------- 1 | x0,y0,z0,x1,y1,z1,T K 2 | -10,0.1,0.2,1,0.1,0.2,1 3 | 10,0.1,0.001,-1,0.1,0.001,2 4 | 2.0,0,0.1,1.5,0.5,0.1,3 5 | 20,20,21,20,20,20,4 6 | 3.0,1.0,0.5,2.0,0.5,0.5,5 -------------------------------------------------------------------------------- /tests/data/raytracing_non_AA_cells-0-0.csv: -------------------------------------------------------------------------------- 1 | x0,y0,z0,x1,y1,z1,T K 2 | 0.5,-1.,2.5,0.5,-0.5,2.5,10 3 | 0.5,-1.,0.5,0.5,-0.5,0.5,4 4 | 1.0,-1.,0.5,1.0,-0.5,0.5,5 5 | 0.5,0.5,10.0,0.5,0.5,9.0,6 6 | -------------------------------------------------------------------------------- /tests/data/scan_path.txt: -------------------------------------------------------------------------------- 1 | Number of path segments 2 | 2 3 | Mode x y z pmod param 4 | 1 0.000 0.1 0.1 0 1e-6 5 | 0 0.002 0.1 0.1 1 0.8 6 | -------------------------------------------------------------------------------- /tests/data/scan_path_L.txt: -------------------------------------------------------------------------------- 1 | Number of path segments 2 | 3 3 | Mode x y z pmod param 4 | 1 0.000 0.000 0.1 0 1e-6 5 | 0 0.002 0.000 0.1 1 0.8 6 | 0 0.002 0.0018 0.1 1 0.8 7 | -------------------------------------------------------------------------------- /tests/data/scan_path_diagonal.txt: -------------------------------------------------------------------------------- 1 | Number of path segments 2 | 2 3 | Mode x y z pmod param 4 | 1 0.000 0.000 0.1 0 1e-6 5 | 0 0.002 0.001 0.1 1 0.8 6 | -------------------------------------------------------------------------------- /tests/data/scan_path_event_series.inp: -------------------------------------------------------------------------------- 1 | 0.1, 0.0, 0.0, 0.0, 1.0 2 | 1.0, 0.5, 0.0, 0.0, 0.5 3 | 2.0, 0.5, 0.5, 0.0, 1.0 4 | -------------------------------------------------------------------------------- /tests/data/scan_path_layers.txt: -------------------------------------------------------------------------------- 1 | Number of path segments 2 | 4 3 | Mode x y z pmod param 4 | 1 0.000 0.000 0 0 1e-6 5 | 0 0.002 0.000 0 1 0.8 6 | 1 0.000 0.000 0.001 0 1e-6 7 | 0 0.002 0.000 0.001 1 0.8 8 | -------------------------------------------------------------------------------- /tests/data/scan_path_test_thermal_physics.txt: -------------------------------------------------------------------------------- 1 | Number of path segments 2 | 2 3 | Mode x y z pmod param 4 | 1 0.000 0.000 0 1.0 1e-15 5 | 0 1.0 0.000 0 1.0 1.0 6 | -------------------------------------------------------------------------------- /tests/data/scan_path_units.txt: -------------------------------------------------------------------------------- 1 | Number of path segments 2 | 2 3 | Mode x y z pmod param 4 | 1 0 100 100 0 1e-6 5 | 0 2 100 100 1 0.8 6 | 7 | -------------------------------------------------------------------------------- /tests/data/thermoelastic_bare_plate.info: -------------------------------------------------------------------------------- 1 | geometry 2 | { 3 | import_mesh false ; Use built-in mesh generator 4 | dim 3 ; dimension of the domain 5 | length 36.0e-3 ; [m] 6 | height 6.0e-3 ; [m] In 3D, the third parameters is width 7 | width 6.0e-3 8 | length_divisions 24 ; Number of cell layers in the length direction 9 | height_divisions 3 ; Number of cell layers in the height direction 10 | width_divisions 3 11 | material_deposition true 12 | material_deposition_method scan_paths 13 | deposition_length 2.0e-3 14 | deposition_height 2.0e-3 15 | deposition_width 2.0e-3 16 | deposition_lead_time 1.0e0 17 | material_height 6.0e-3 18 | } 19 | 20 | physics 21 | { 22 | thermal true 23 | mechanical true 24 | } 25 | 26 | discretization 27 | { 28 | thermal 29 | { 30 | fe_degree 3 31 | quadrature gauss ; Optional parameter. Possibilities: gauss or lobatto 32 | } 33 | mechanical 34 | { 35 | fe_degree 1 36 | } 37 | } 38 | 39 | boundary 40 | { 41 | type adiabatic ; convective,radiative 42 | } 43 | 44 | refinement 45 | { 46 | n_refinements 0 ; Number of time the cells on the paths of the beams are 47 | ; refined 48 | time_steps_between_refinement 100 ; number of time steps after which 49 | ; the refinement process is performed 50 | } 51 | 52 | materials 53 | { 54 | n_materials 1 55 | 56 | property_format polynomial 57 | material_0 58 | { 59 | solid 60 | { 61 | density 7904; [kg/m^3] For now all the states needs to have the same 62 | ; density. 63 | specific_heat 714; [J/kg K] 64 | thermal_conductivity_x 31.4 ; [W/m K] 65 | thermal_conductivity_y 31.4 ; [W/m K] 66 | thermal_conductivity_z 31.4 ; [W/m K] 67 | lame_first_parameter 92.0e9 ; [Pa] 68 | lame_second_parameter 79.0e9 ; [Pa] 69 | thermal_expansion_coef 17.2e-6 ; [1/K] 70 | } 71 | 72 | powder 73 | { 74 | specific_heat 714; [J/kg K] 75 | density 7904; [kg/m^3] 76 | thermal_conductivity_x 0.314 ; [W/m K] 77 | thermal_conductivity_y 0.314 ; [W/m K] 78 | thermal_conductivity_z 0.314 ; [W/m K] 79 | } 80 | 81 | liquid 82 | { 83 | specific_heat 847; [J/kg K] 84 | density 7904; [kg/m^3] 85 | thermal_conductivity_x 37.3 ; [W/m k] 86 | thermal_conductivity_y 37.3 ; [W/m k] 87 | thermal_conductivity_z 37.3 ; [W/m k] 88 | 89 | ; Not all three states need to define the same properties or to exist 90 | } 91 | 92 | solidus 1675; [K] 93 | liquidus 1708; [K] 94 | latent_heat 290000 ; [J/kg] 95 | 96 | } 97 | } 98 | 99 | sources 100 | { 101 | n_beams 1 102 | 103 | beam_0 104 | { 105 | type goldak ; goldak (laser) or electron_beam 106 | depth 3.0e-3 ; [m] maximum depth reached by the laser 107 | diameter 3.0e-3 ; [m] 108 | scan_path_file thermoelastic_bare_plate_scan_path.txt 109 | scan_path_file_format segment 110 | absorption_efficiency 0.6 ; number between 0 and 1 equivalent to 111 | ; energy_conversion_efficiency * control_efficiency 112 | ; for an electron beam 113 | max_power 9000.0 ; [W], current * voltage for an electron beam 114 | } 115 | } 116 | 117 | time_stepping 118 | { 119 | method forward_euler ; Possibilities: backward_euler, implicit_midpoint, 120 | ; crank_nicolson, sdirk2, forward_euler, rk_third_order, 121 | ; rk_fourth_order 122 | duration 4.0e0 ; [s] 123 | time_step 4.0e-3 ; [s] 124 | } 125 | 126 | post_processor 127 | { 128 | filename_prefix output 129 | time_steps_between_output 500 130 | } 131 | 132 | discretization 133 | { 134 | fe_degree 2 135 | quadrature gauss ; Optional parameter. Possibilities: gauss or lobatto 136 | } 137 | 138 | profiling 139 | { 140 | timer false 141 | caliper "spot(profile.mpi),loop-report,runtime-report" 142 | } 143 | 144 | memory_space host ; Always run on the host 145 | -------------------------------------------------------------------------------- /tests/data/thermoelastic_bare_plate_add_material_scan_path.txt: -------------------------------------------------------------------------------- 1 | Number of path segments 2 | 2 3 | Mode x y z pmod param 4 | 1 16.0e-3 3.0e-3 8.0e-3 0 1e-6 5 | 0 16.2e-3 3.0e-3 8.0e-3 1 0.001667 6 | -------------------------------------------------------------------------------- /tests/data/thermoelastic_bare_plate_scan_path.txt: -------------------------------------------------------------------------------- 1 | Number of path segments 2 | 2 3 | Mode x y z pmod param 4 | 1 16.0e-3 3.0e-3 6.0e-3 0 1e-6 5 | 0 16.2e-3 3.0e-3 6.0e-3 1 0.001667 6 | -------------------------------------------------------------------------------- /tests/main.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2016 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #define BOOST_TEST_NO_MAIN 6 | #include 7 | 8 | #include 9 | 10 | #include 11 | 12 | bool init_function() { return true; } 13 | 14 | int main(int argc, char *argv[]) 15 | { 16 | #ifndef __APPLE__ 17 | feenableexcept(FE_INVALID); 18 | #endif 19 | dealii::Utilities::MPI::MPI_InitFinalize mpi_initialization( 20 | argc, argv, dealii::numbers::invalid_unsigned_int); 21 | 22 | return boost::unit_test::unit_test_main(&init_function, argc, argv); 23 | } 24 | -------------------------------------------------------------------------------- /tests/test_integration_2d.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2016 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include "MaterialStates.hh" 6 | #define BOOST_TEST_MODULE Integration_2D 7 | 8 | #include "../application/adamantine.hh" 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include "main.cc" 16 | 17 | namespace utf = boost::unit_test; 18 | 19 | BOOST_AUTO_TEST_CASE(integration_2D, *utf::tolerance(0.1)) 20 | { 21 | MPI_Comm communicator = MPI_COMM_WORLD; 22 | 23 | std::vector timers; 24 | initialize_timers(communicator, timers); 25 | 26 | // Read the input. 27 | std::string const filename = "integration_2d.info"; 28 | adamantine::ASSERT_THROW(std::filesystem::exists(filename) == true, 29 | "The file " + filename + " does not exist."); 30 | boost::property_tree::ptree database; 31 | boost::property_tree::info_parser::read_info(filename, database); 32 | 33 | auto [temperature, displacement] = 34 | run<2, 4, adamantine::SolidLiquidPowder, dealii::MemorySpace::Host>( 35 | communicator, database, timers); 36 | 37 | std::ifstream gold_file("integration_2d_gold.txt"); 38 | for (unsigned int i = 0; i < temperature.locally_owned_size(); ++i) 39 | { 40 | double gold_value = -1.; 41 | gold_file >> gold_value; 42 | BOOST_TEST(temperature.local_element(i) == gold_value); 43 | } 44 | } 45 | 46 | BOOST_AUTO_TEST_CASE(integration_2D_ensemble, *utf::tolerance(0.1)) 47 | { 48 | MPI_Comm communicator = MPI_COMM_WORLD; 49 | 50 | std::vector timers; 51 | initialize_timers(communicator, timers); 52 | 53 | // Read the input. 54 | std::string const filename = "integration_2d_ensemble.info"; 55 | adamantine::ASSERT_THROW(std::filesystem::exists(filename) == true, 56 | "The file " + filename + " does not exist."); 57 | boost::property_tree::ptree database; 58 | boost::property_tree::info_parser::read_info(filename, database); 59 | 60 | auto result_ensemble = 61 | run_ensemble<2, 3, adamantine::SolidLiquidPowder, 62 | dealii::MemorySpace::Host>(communicator, database, timers); 63 | 64 | for (auto &result_member : result_ensemble) 65 | { 66 | std::ifstream gold_file("integration_2d_gold.txt"); 67 | for (unsigned int i = 0; i < result_member.block(0).locally_owned_size(); 68 | ++i) 69 | { 70 | double gold_value = -1.; 71 | gold_file >> gold_value; 72 | BOOST_TEST(result_member.block(0).local_element(i) == gold_value); 73 | } 74 | } 75 | } 76 | 77 | // This is the same test as integration_2D but using different units 78 | BOOST_AUTO_TEST_CASE(integration_2D_units, *utf::tolerance(0.1)) 79 | { 80 | MPI_Comm communicator = MPI_COMM_WORLD; 81 | 82 | std::vector timers; 83 | initialize_timers(communicator, timers); 84 | 85 | // Read the input. 86 | std::string const filename = "integration_2d_units.info"; 87 | adamantine::ASSERT_THROW(std::filesystem::exists(filename) == true, 88 | "The file " + filename + " does not exist."); 89 | boost::property_tree::ptree database; 90 | boost::property_tree::info_parser::read_info(filename, database); 91 | 92 | auto [temperature, displacement] = 93 | run<2, 4, adamantine::SolidLiquidPowder, dealii::MemorySpace::Host>( 94 | communicator, database, timers); 95 | 96 | std::ifstream gold_file("integration_2d_gold.txt"); 97 | for (unsigned int i = 0; i < temperature.locally_owned_size(); ++i) 98 | { 99 | double gold_value = -1.; 100 | gold_file >> gold_value; 101 | BOOST_TEST(temperature.local_element(i) == gold_value); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /tests/test_integration_2d_device.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2016 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include "MaterialStates.hh" 6 | #define BOOST_TEST_MODULE Integration_2D_Device 7 | 8 | #include "../application/adamantine.hh" 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include "main.cc" 16 | 17 | namespace utf = boost::unit_test; 18 | 19 | BOOST_AUTO_TEST_CASE(intregation_2D_device, *utf::tolerance(0.1)) 20 | { 21 | MPI_Comm communicator = MPI_COMM_WORLD; 22 | 23 | std::vector timers; 24 | initialize_timers(communicator, timers); 25 | 26 | // Read the input. 27 | std::string const filename = "integration_2d.info"; 28 | adamantine::ASSERT_THROW(std::filesystem::exists(filename) == true, 29 | "The file " + filename + " does not exist."); 30 | boost::property_tree::ptree database; 31 | boost::property_tree::info_parser::read_info(filename, database); 32 | 33 | auto [temperature, displacement] = 34 | run<2, 4, adamantine::SolidLiquidPowder, dealii::MemorySpace::Default>( 35 | communicator, database, timers); 36 | 37 | std::ifstream gold_file("integration_2d_gold.txt"); 38 | for (unsigned int i = 0; i < temperature.locally_owned_size(); ++i) 39 | { 40 | double gold_value = -1.; 41 | gold_file >> gold_value; 42 | BOOST_TEST(temperature.local_element(i) == gold_value); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/test_integration_3d_amr.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2016 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include "MaterialStates.hh" 6 | #define BOOST_TEST_MODULE Integration_3D_AMR 7 | 8 | #include "../application/adamantine.hh" 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include "main.cc" 16 | 17 | namespace utf = boost::unit_test; 18 | 19 | BOOST_AUTO_TEST_CASE(integration_3D_amr, *utf::tolerance(0.1)) 20 | { 21 | MPI_Comm communicator = MPI_COMM_WORLD; 22 | 23 | std::vector timers; 24 | initialize_timers(communicator, timers); 25 | 26 | // Read the input. 27 | std::string const filename = "amr_test.info"; 28 | adamantine::ASSERT_THROW(std::filesystem::exists(filename) == true, 29 | "The file " + filename + " does not exist."); 30 | boost::property_tree::ptree database; 31 | boost::property_tree::info_parser::read_info(filename, database); 32 | 33 | auto [temperature, displacement] = 34 | run<3, 4, adamantine::SolidLiquidPowder, dealii::MemorySpace::Host>( 35 | communicator, database, timers); 36 | 37 | double min_val = std::numeric_limits::max(); 38 | double max_val = std::numeric_limits::min(); 39 | for (unsigned int i = 0; i < temperature.locally_owned_size(); ++i) 40 | { 41 | if (temperature.local_element(i) < min_val) 42 | min_val = temperature.local_element(i); 43 | 44 | if (temperature.local_element(i) > max_val) 45 | max_val = temperature.local_element(i); 46 | } 47 | 48 | double global_max = 49 | dealii::Utilities::MPI::max(max_val, temperature.get_mpi_communicator()); 50 | double global_min = 51 | dealii::Utilities::MPI::min(min_val, temperature.get_mpi_communicator()); 52 | 53 | double expected_max = 329.5; 54 | double expected_min = 296.1; 55 | 56 | BOOST_TEST(expected_max == global_max); 57 | BOOST_TEST(expected_min == global_min); 58 | } 59 | 60 | BOOST_AUTO_TEST_CASE(integration_3D_amr_refine_coarsen, *utf::tolerance(0.1)) 61 | { 62 | MPI_Comm communicator = MPI_COMM_WORLD; 63 | 64 | std::vector timers; 65 | initialize_timers(communicator, timers); 66 | 67 | // Read the input. 68 | std::string const filename = "demo_316_short_amr.info"; 69 | adamantine::ASSERT_THROW(std::filesystem::exists(filename) == true, 70 | "The file " + filename + " does not exist."); 71 | boost::property_tree::ptree database; 72 | boost::property_tree::info_parser::read_info(filename, database); 73 | 74 | auto [temperature, displacement] = 75 | run<3, 4, adamantine::SolidLiquidPowder, dealii::MemorySpace::Host>( 76 | communicator, database, timers); 77 | 78 | auto global_size = temperature.size(); 79 | double l1_norm = temperature.l1_norm(); 80 | 81 | // Check for the expected number of degrees of freedom 82 | BOOST_TEST(global_size == 13005); 83 | 84 | // Check that AMR hasn't caused any NaNs 85 | // NOTE: This check is only relevant in some cases. In debug mode the test 86 | // should fail earlier through an assert. In release model with --ffast-math 87 | // all NaN checks (including isnan and isfinite) are skipped. 88 | BOOST_TEST(std::isfinite(l1_norm)); 89 | } 90 | -------------------------------------------------------------------------------- /tests/test_integration_3d_amr_device.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2023 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include "MaterialStates.hh" 6 | #define BOOST_TEST_MODULE Integration_3D_AMR 7 | 8 | #include "../application/adamantine.hh" 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include "main.cc" 16 | 17 | namespace utf = boost::unit_test; 18 | 19 | BOOST_AUTO_TEST_CASE(integration_3D_amr_device, *utf::tolerance(0.1)) 20 | { 21 | MPI_Comm communicator = MPI_COMM_WORLD; 22 | 23 | std::vector timers; 24 | initialize_timers(communicator, timers); 25 | 26 | // Read the input. 27 | std::string const filename = "amr_test.info"; 28 | adamantine::ASSERT_THROW(std::filesystem::exists(filename) == true, 29 | "The file " + filename + " does not exist."); 30 | boost::property_tree::ptree database; 31 | boost::property_tree::info_parser::read_info(filename, database); 32 | 33 | auto [temperature, displacement] = 34 | run<3, 4, adamantine::SolidLiquidPowder, dealii::MemorySpace::Default>( 35 | communicator, database, timers); 36 | 37 | double min_val = std::numeric_limits::max(); 38 | double max_val = std::numeric_limits::min(); 39 | for (unsigned int i = 0; i < temperature.locally_owned_size(); ++i) 40 | { 41 | if (temperature.local_element(i) < min_val) 42 | min_val = temperature.local_element(i); 43 | 44 | if (temperature.local_element(i) > max_val) 45 | max_val = temperature.local_element(i); 46 | } 47 | 48 | double global_max = 49 | dealii::Utilities::MPI::max(max_val, temperature.get_mpi_communicator()); 50 | double global_min = 51 | dealii::Utilities::MPI::min(min_val, temperature.get_mpi_communicator()); 52 | 53 | double expected_max = 329.5; 54 | double expected_min = 296.1; 55 | 56 | BOOST_TEST(expected_max == global_max); 57 | BOOST_TEST(expected_min == global_min); 58 | } 59 | -------------------------------------------------------------------------------- /tests/test_integration_3d_device.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2022 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include "MaterialStates.hh" 6 | #define BOOST_TEST_MODULE Integration_3D_Device 7 | 8 | #include "../application/adamantine.hh" 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include "main.cc" 16 | 17 | namespace utf = boost::unit_test; 18 | 19 | BOOST_AUTO_TEST_CASE(integration_3D_device, *utf::tolerance(0.1)) 20 | { 21 | MPI_Comm communicator = MPI_COMM_WORLD; 22 | 23 | std::vector timers; 24 | initialize_timers(communicator, timers); 25 | 26 | // Read the input. 27 | std::string const filename = "demo_316_short_anisotropic.info"; 28 | adamantine::ASSERT_THROW(std::filesystem::exists(filename) == true, 29 | "The file " + filename + " does not exist."); 30 | boost::property_tree::ptree database; 31 | boost::property_tree::info_parser::read_info(filename, database); 32 | 33 | auto [temperature, displacement] = 34 | run<3, 3, adamantine::SolidLiquidPowder, dealii::MemorySpace::Default>( 35 | communicator, database, timers); 36 | 37 | std::ifstream gold_file("integration_3d_gold.txt"); 38 | for (unsigned int i = 0; i < temperature.locally_owned_size(); ++i) 39 | { 40 | double gold_value = -1.; 41 | gold_file >> gold_value; 42 | BOOST_TEST(temperature.local_element(i) == gold_value); 43 | } 44 | } 45 | 46 | BOOST_AUTO_TEST_CASE(integration_3D_checkpoint_restart_device) 47 | { 48 | MPI_Comm communicator = MPI_COMM_WORLD; 49 | 50 | std::vector timers; 51 | initialize_timers(communicator, timers); 52 | 53 | // Read the input. 54 | std::string const input_filename = "demo_316_short_anisotropic.info"; 55 | adamantine::ASSERT_THROW(std::filesystem::exists(input_filename) == true, 56 | "The file " + input_filename + " does not exist."); 57 | boost::property_tree::ptree database; 58 | boost::property_tree::info_parser::read_info(input_filename, database); 59 | std::string const checkpoint_filename = "test_checkpoint"; 60 | 61 | // First run with checkpoint of the solution halfway through the solution 62 | database.put("checkpoint.filename_prefix", checkpoint_filename); 63 | database.put("checkpoint.overwrite_files", true); 64 | database.put("checkpoint.time_steps_between_checkpoint", 80); 65 | auto [temperature_1, displacement_1] = 66 | run<3, 3, adamantine::SolidLiquidPowder, dealii::MemorySpace::Host>( 67 | communicator, database, timers); 68 | // Restart of the simulation 69 | database.put("restart.filename_prefix", checkpoint_filename); 70 | auto [temperature_2, displacement_2] = 71 | run<3, 3, adamantine::SolidLiquidPowder, dealii::MemorySpace::Host>( 72 | communicator, database, timers); 73 | 74 | // Compare the temperatures. When using more than one processor, the 75 | // partitioning is different and so the distribution of the dofs are 76 | // different. This makes it very difficult to compare the temperatures, so 77 | // when using more than one processor we only compare the L2 norm. 78 | if (dealii::Utilities::MPI::n_mpi_processes(communicator) == 1) 79 | { 80 | for (unsigned int i = 0; i < temperature_1.size(); ++i) 81 | BOOST_TEST(temperature_1[i] == temperature_2[i]); 82 | } 83 | else 84 | { 85 | BOOST_TEST(temperature_1.l2_norm() == temperature_2.l2_norm()); 86 | } 87 | 88 | // Remove the files created during the test 89 | std::filesystem::remove(checkpoint_filename); 90 | std::filesystem::remove(checkpoint_filename + "_fixed.data"); 91 | std::filesystem::remove(checkpoint_filename + ".info"); 92 | std::filesystem::remove(checkpoint_filename + "_variable.data"); 93 | std::filesystem::remove(checkpoint_filename + "_time.txt"); 94 | } 95 | -------------------------------------------------------------------------------- /tests/test_integration_da_augmented.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2016 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include "MaterialStates.hh" 6 | #define BOOST_TEST_MODULE Integration_Data_Assimilation_Augmented 7 | 8 | #include "../application/adamantine.hh" 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include "main.cc" 16 | 17 | namespace utf = boost::unit_test; 18 | 19 | BOOST_AUTO_TEST_CASE(integration_3D_data_assimilation_augmented, 20 | *utf::tolerance(5.)) 21 | { 22 | 23 | MPI_Comm communicator = MPI_COMM_WORLD; 24 | 25 | std::vector timers; 26 | initialize_timers(communicator, timers); 27 | 28 | // Read the input. 29 | std::string const filename = "bare_plate_L_da_augmented.info"; 30 | adamantine::ASSERT_THROW(std::filesystem::exists(filename) == true, 31 | "The file " + filename + " does not exist."); 32 | boost::property_tree::ptree database; 33 | boost::property_tree::info_parser::read_info(filename, database); 34 | 35 | // Run the simulation 36 | auto result = 37 | run_ensemble<3, 3, adamantine::SolidLiquidPowder, 38 | dealii::MemorySpace::Host>(communicator, database, timers); 39 | 40 | // Three ensemble members expected 41 | unsigned int local_result_size = result.size(); 42 | unsigned int global_result_size = 43 | dealii::Utilities::MPI::sum(local_result_size, communicator); 44 | BOOST_TEST(global_result_size == 3); 45 | 46 | // Get the average absorption value for each ensemble member 47 | double sum = 0.0; 48 | for (unsigned int member = 0; member < result.size(); ++member) 49 | { 50 | sum += result.at(member).block(1).local_element(0); 51 | } 52 | double partial_average_value = sum / global_result_size; 53 | double average_value = 54 | dealii::Utilities::MPI::sum(partial_average_value, communicator); 55 | 56 | // Based on the reference solution, the expected absorption efficiency is 0.3 57 | double gold_solution = 0.3; 58 | BOOST_TEST(average_value == gold_solution); 59 | } 60 | -------------------------------------------------------------------------------- /tests/test_integration_thermoelastic.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2016 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #include "MaterialStates.hh" 6 | #define BOOST_TEST_MODULE Integration_Thermoelastic 7 | 8 | #include "../application/adamantine.hh" 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include "main.cc" 16 | 17 | namespace utf = boost::unit_test; 18 | 19 | BOOST_AUTO_TEST_CASE(integration_thermoelastic, *utf::tolerance(1.0e-5)) 20 | { 21 | MPI_Comm communicator = MPI_COMM_WORLD; 22 | 23 | std::vector timers; 24 | initialize_timers(communicator, timers); 25 | 26 | // Read the input. 27 | std::string const filename = "thermoelastic_bare_plate.info"; 28 | adamantine::ASSERT_THROW(std::filesystem::exists(filename) == true, 29 | "The file " + filename + " does not exist."); 30 | boost::property_tree::ptree database; 31 | boost::property_tree::info_parser::read_info(filename, database); 32 | database.put("materials.material_0.solid.thermal_expansion_coef", 17.2e-3); 33 | 34 | auto [temperature, displacement] = 35 | run<3, 3, adamantine::SolidLiquidPowder, dealii::MemorySpace::Host>( 36 | communicator, database, timers); 37 | 38 | // For now doing a simple regression test. Without a dof handler, it's hard to 39 | // do something more meaningful with the vector. 40 | 41 | // To generate a new gold solution 42 | // std::cout << "dis l2:" << displacement.l2_norm() << std::endl; 43 | 44 | BOOST_TEST(displacement.l2_norm() == 0.21537566016824577); 45 | } 46 | 47 | BOOST_AUTO_TEST_CASE(integration_thermoelastic_add_material, 48 | *utf::tolerance(1.0e-5)) 49 | { 50 | MPI_Comm communicator = MPI_COMM_WORLD; 51 | 52 | std::vector timers; 53 | initialize_timers(communicator, timers); 54 | 55 | // Read the input. 56 | std::string const filename = "thermoelastic_bare_plate.info"; 57 | adamantine::ASSERT_THROW(std::filesystem::exists(filename) == true, 58 | "The file " + filename + " does not exist."); 59 | boost::property_tree::ptree database; 60 | boost::property_tree::info_parser::read_info(filename, database); 61 | database.put("geometry.height", 8.0e-3); 62 | database.put("geometry.height_division", 4); 63 | database.put("sources.beam_0.scan_path_file", 64 | "thermoelastic_bare_plate_add_material_scan_path.txt"); 65 | database.put("materials.material_0.solid.thermal_expansion_coef", 17.2e-3); 66 | 67 | auto [temperature, displacement] = 68 | run<3, 2, adamantine::SolidLiquidPowder, dealii::MemorySpace::Host>( 69 | communicator, database, timers); 70 | 71 | // For now doing a simple regression test. Without a dof handler, it's hard to 72 | // do something more meaningful with the vector. 73 | 74 | BOOST_TEST(displacement.l2_norm() == 0.355534971638); 75 | } 76 | -------------------------------------------------------------------------------- /tests/test_material_property.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2016 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #define BOOST_TEST_MODULE MaterialProperty 6 | 7 | // clang-format off 8 | #include "main.cc" 9 | 10 | #include "test_material_property.hh" 11 | // clang-format on 12 | 13 | BOOST_AUTO_TEST_CASE(material_property_host) 14 | { 15 | material_property(); 16 | } 17 | 18 | BOOST_AUTO_TEST_CASE(ratios_host) { ratios(); } 19 | 20 | BOOST_AUTO_TEST_CASE(material_property_table_host) 21 | { 22 | material_property_table(); 23 | } 24 | 25 | BOOST_AUTO_TEST_CASE(material_property_polynomials_host) 26 | { 27 | material_property_polynomials(); 28 | } 29 | -------------------------------------------------------------------------------- /tests/test_material_property_device.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2021 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #define BOOST_TEST_MODULE MaterialPropertyDevice 6 | 7 | // clang-format off 8 | #include "main.cc" 9 | 10 | #include "test_material_property.hh" 11 | // clang-format on 12 | 13 | BOOST_AUTO_TEST_CASE(material_property_device) 14 | { 15 | material_property(); 16 | } 17 | 18 | BOOST_AUTO_TEST_CASE(ratios_device) { ratios(); } 19 | 20 | BOOST_AUTO_TEST_CASE(material_property_table_device) 21 | { 22 | material_property_table(); 23 | } 24 | 25 | BOOST_AUTO_TEST_CASE(material_property_polynomials_device) 26 | { 27 | material_property_polynomials(); 28 | } 29 | -------------------------------------------------------------------------------- /tests/test_newton_solver.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2016 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #define BOOST_TEST_MODULE Newton_Solver 6 | 7 | #include 8 | 9 | #include "main.cc" 10 | 11 | namespace utf = boost::unit_test; 12 | 13 | dealii::LA::distributed::Vector 14 | compute_residual(dealii::LA::distributed::Vector const &x) 15 | { 16 | dealii::LA::distributed::Vector res(2); 17 | res[0] = std::pow(x[0], 4) - 1.; 18 | res[1] = std::pow(x[1], 6) - 1.; 19 | 20 | return res; 21 | } 22 | 23 | dealii::LA::distributed::Vector 24 | compute_inv_jacobian(dealii::LA::distributed::Vector const &x) 25 | { 26 | dealii::LA::distributed::Vector inv_jacobian(2); 27 | inv_jacobian[0] = 1. / (4. * std::pow(x[0], 3)); 28 | inv_jacobian[1] = 1. / (6. * std::pow(x[1], 5)); 29 | 30 | return inv_jacobian; 31 | } 32 | 33 | BOOST_AUTO_TEST_CASE(newton_solver, *utf::tolerance(1e-5)) 34 | { 35 | dealii::LA::distributed::Vector src(2); 36 | src[0] = 2.; 37 | src[1] = 2.; 38 | 39 | adamantine::NewtonSolver newton_solver(10, 1e-7); 40 | newton_solver.solve(&compute_residual, &compute_inv_jacobian, src); 41 | 42 | BOOST_TEST(1. == src[0]); 43 | BOOST_TEST(1. == src[1]); 44 | } 45 | -------------------------------------------------------------------------------- /tests/test_scan_path.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2016 - 2021, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #define BOOST_TEST_MODULE ScanPath 6 | 7 | #include 8 | 9 | #include "main.cc" 10 | 11 | namespace utf = boost::unit_test; 12 | 13 | namespace adamantine 14 | { 15 | 16 | class ScanPathTester 17 | { 18 | public: 19 | std::vector get_segment_format_list() 20 | { 21 | boost::optional 22 | units_optional_database; 23 | ScanPath scan_path("scan_path.txt", "segment", units_optional_database); 24 | return scan_path._segment_list; 25 | }; 26 | std::vector get_event_series_format_list() 27 | { 28 | boost::optional 29 | units_optional_database; 30 | ScanPath scan_path("scan_path_event_series.inp", "event_series", 31 | units_optional_database); 32 | return scan_path._segment_list; 33 | }; 34 | }; 35 | 36 | BOOST_AUTO_TEST_CASE(scan_path, *utf::tolerance(1e-12)) 37 | { 38 | ScanPathTester tester; 39 | 40 | // Test the segments from a ScanPathFileFormat::segment file 41 | std::vector segment_format_list = 42 | tester.get_segment_format_list(); 43 | 44 | BOOST_TEST(segment_format_list.size() == 2); 45 | 46 | BOOST_TEST(segment_format_list[0].end_time == 1.0e-6); 47 | BOOST_TEST(segment_format_list[0].end_point[0] == 0.0); 48 | BOOST_TEST(segment_format_list[0].end_point[1] == 0.1); 49 | BOOST_TEST(segment_format_list[0].power_modifier == 0.0); 50 | 51 | BOOST_TEST(segment_format_list[1].end_time == (1.0e-6 + 0.002 / 0.8)); 52 | BOOST_TEST(segment_format_list[1].end_point[0] == 0.002); 53 | BOOST_TEST(segment_format_list[1].end_point[1] == 0.1); 54 | BOOST_TEST(segment_format_list[1].power_modifier == 1.0); 55 | 56 | // Test the segments from a ScanPathFileFormat::event_series file 57 | std::vector segment_event_series_list = 58 | tester.get_event_series_format_list(); 59 | 60 | BOOST_TEST(segment_event_series_list.size() == 3); 61 | 62 | BOOST_TEST(segment_event_series_list[0].end_time == 0.1); 63 | BOOST_TEST(segment_event_series_list[0].end_point[0] == 0.0); 64 | BOOST_TEST(segment_event_series_list[0].end_point[1] == 0.0); 65 | BOOST_TEST(segment_event_series_list[0].power_modifier == 0.0); 66 | 67 | BOOST_TEST(segment_event_series_list[1].end_time == 1.0); 68 | BOOST_TEST(segment_event_series_list[1].end_point[0] == 0.5); 69 | BOOST_TEST(segment_event_series_list[1].end_point[1] == 0.0); 70 | BOOST_TEST(segment_event_series_list[1].power_modifier == 1.0); 71 | 72 | BOOST_TEST(segment_event_series_list[2].end_time == 2.0); 73 | BOOST_TEST(segment_event_series_list[2].end_point[0] == 0.5); 74 | BOOST_TEST(segment_event_series_list[2].end_point[1] == 0.5); 75 | BOOST_TEST(segment_event_series_list[2].power_modifier == 0.5); 76 | } 77 | 78 | BOOST_AUTO_TEST_CASE(scan_path_location, *utf::tolerance(1e-10)) 79 | { 80 | boost::optional units_optional_database; 81 | ScanPath scan_path("scan_path.txt", "segment", units_optional_database); 82 | double time = 1.0e-7; 83 | dealii::Point<3> p1 = scan_path.value(time); 84 | 85 | BOOST_TEST(p1[0] == 0.0); 86 | BOOST_TEST(p1[1] == 0.1); 87 | BOOST_TEST(p1[2] == 0.1); 88 | 89 | time = 0.001001; 90 | 91 | dealii::Point<3> p2 = scan_path.value(time); 92 | 93 | BOOST_TEST(p2[0] == 8.0e-4); 94 | BOOST_TEST(p2[1] == 0.1); 95 | BOOST_TEST(p2[2] == 0.1); 96 | 97 | time = 100.0; 98 | dealii::Point<3> p3 = scan_path.value(time); 99 | BOOST_TEST(p3[0] == std::numeric_limits::lowest()); 100 | BOOST_TEST(p3[1] == std::numeric_limits::lowest()); 101 | BOOST_TEST(p3[2] == std::numeric_limits::lowest()); 102 | double power = scan_path.get_power_modifier(time); 103 | BOOST_TEST(power == 0.0); 104 | } 105 | 106 | } // namespace adamantine 107 | -------------------------------------------------------------------------------- /tests/test_thermal_physics.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2016 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #define BOOST_TEST_MODULE ThermalPhysics 6 | 7 | // clang-format off 8 | #include "main.cc" 9 | 10 | #include "test_thermal_physics.hh" 11 | // clang-format on 12 | 13 | BOOST_AUTO_TEST_CASE(thermal_2d_explicit_host) 14 | { 15 | boost::property_tree::ptree database; 16 | // Time-stepping database 17 | database.put("time_stepping.method", "forward_euler"); 18 | database.put("sources.beam_0.scan_path_file", 19 | "scan_path_test_thermal_physics.txt"); 20 | database.put("sources.beam_0.type", "electron_beam"); 21 | database.put("sources.beam_0.scan_path_file_format", "segment"); 22 | 23 | thermal_2d(database, 0.05); 24 | } 25 | 26 | BOOST_AUTO_TEST_CASE(thermal_2d_implicit_host) 27 | { 28 | boost::property_tree::ptree database; 29 | // Time-stepping database 30 | database.put("time_stepping.method", "backward_euler"); 31 | database.put("time_stepping.max_iteration", 100); 32 | database.put("time_stepping.tolerance", 1e-6); 33 | database.put("time_stepping.n_tmp_vectors", 100); 34 | database.put("sources.beam_0.scan_path_file", 35 | "scan_path_test_thermal_physics.txt"); 36 | database.put("sources.beam_0.type", "electron_beam"); 37 | database.put("sources.beam_0.scan_path_file_format", "segment"); 38 | 39 | thermal_2d(database, 0.025); 40 | } 41 | 42 | BOOST_AUTO_TEST_CASE(thermal_2d_manufactured_solution_host) 43 | { 44 | thermal_2d_manufactured_solution(); 45 | } 46 | 47 | BOOST_AUTO_TEST_CASE(initial_temperature_host) 48 | { 49 | initial_temperature(); 50 | } 51 | 52 | BOOST_AUTO_TEST_CASE(energy_conservation_host) 53 | { 54 | energy_conservation(); 55 | } 56 | 57 | BOOST_AUTO_TEST_CASE(radiation_bcs_host) 58 | { 59 | radiation_bcs(); 60 | } 61 | 62 | BOOST_AUTO_TEST_CASE(convection_bcs_host) 63 | { 64 | convection_bcs(); 65 | } 66 | 67 | BOOST_AUTO_TEST_CASE(reference_temperature_host) 68 | { 69 | reference_temperature(); 70 | } 71 | -------------------------------------------------------------------------------- /tests/test_thermal_physics_device.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2016 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #define BOOST_TEST_MODULE ThermalPhysicsDevice 6 | 7 | // clang-format off 8 | #include "main.cc" 9 | 10 | #include "test_thermal_physics.hh" 11 | // clang-format on 12 | 13 | BOOST_AUTO_TEST_CASE(thermal_2d_explicit_device) 14 | { 15 | boost::property_tree::ptree database; 16 | // Time-stepping database 17 | database.put("time_stepping.method", "forward_euler"); 18 | database.put("sources.beam_0.scan_path_file", 19 | "scan_path_test_thermal_physics.txt"); 20 | database.put("sources.beam_0.type", "electron_beam"); 21 | database.put("sources.beam_0.scan_path_file_format", "segment"); 22 | 23 | thermal_2d(database, 0.05); 24 | } 25 | 26 | BOOST_AUTO_TEST_CASE(thermal_2d_implicit_device) 27 | { 28 | boost::property_tree::ptree database; 29 | // Time-stepping database 30 | database.put("time_stepping.method", "backward_euler"); 31 | database.put("time_stepping.max_iteration", 100); 32 | database.put("time_stepping.tolerance", 1e-6); 33 | database.put("time_stepping.n_tmp_vectors", 100); 34 | database.put("sources.beam_0.scan_path_file", 35 | "scan_path_test_thermal_physics.txt"); 36 | database.put("sources.beam_0.type", "electron_beam"); 37 | database.put("sources.beam_0.scan_path_file_format", "segment"); 38 | 39 | thermal_2d(database, 0.025); 40 | } 41 | 42 | BOOST_AUTO_TEST_CASE(thermal_2d_manufactured_solution_device) 43 | { 44 | thermal_2d_manufactured_solution(); 45 | } 46 | 47 | BOOST_AUTO_TEST_CASE(initial_temperature_device) 48 | { 49 | initial_temperature(); 50 | } 51 | 52 | BOOST_AUTO_TEST_CASE(energy_conservation_device) 53 | { 54 | energy_conservation(); 55 | } 56 | -------------------------------------------------------------------------------- /tests/test_timer.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2017 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #define BOOST_TEST_MODULE Timer 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "main.cc" 14 | 15 | BOOST_AUTO_TEST_CASE(test_timer) 16 | { 17 | unsigned int const tolerance = 15; 18 | adamantine::Timer timer(MPI_COMM_WORLD, "test"); 19 | 20 | timer.start(); 21 | std::this_thread::sleep_for(std::chrono::milliseconds(200)); 22 | timer.stop(); 23 | boost::chrono::process_cpu_clock::duration duration = 24 | timer.get_elapsed_time(); 25 | boost::chrono::milliseconds ms = 26 | boost::chrono::duration_cast(duration); 27 | BOOST_TEST(std::abs(ms.count() - 200) < tolerance); 28 | 29 | timer.start(); 30 | std::this_thread::sleep_for(std::chrono::milliseconds(200)); 31 | timer.stop(); 32 | duration = timer.get_elapsed_time(); 33 | ms = boost::chrono::duration_cast(duration); 34 | BOOST_TEST(std::abs(ms.count() - 400) < 2 * tolerance); 35 | 36 | timer.reset(); 37 | timer.start(); 38 | std::this_thread::sleep_for(std::chrono::milliseconds(200)); 39 | timer.stop(); 40 | duration = timer.get_elapsed_time(); 41 | ms = boost::chrono::duration_cast(duration); 42 | BOOST_TEST(std::abs(ms.count() - 200) < tolerance); 43 | } 44 | -------------------------------------------------------------------------------- /tests/test_utils.cc: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (c) 2017 - 2024, the adamantine authors. 2 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 3 | */ 4 | 5 | #define BOOST_TEST_MODULE utils 6 | 7 | #include 8 | 9 | #include "main.cc" 10 | 11 | BOOST_AUTO_TEST_CASE(utils) 12 | { 13 | // Do not check ASSERT because it is not checked in release mode 14 | 15 | BOOST_CHECK_THROW(adamantine::ASSERT_THROW(false, "test"), 16 | std::runtime_error); 17 | 18 | BOOST_CHECK_THROW(adamantine::ASSERT_THROW_NOT_IMPLEMENTED(), 19 | adamantine::NotImplementedExc); 20 | } 21 | --------------------------------------------------------------------------------