/* SPDX-FileCopyrightText: Copyright (c) 2016 - 2026, the adamantine authors. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception */ #include "MaterialStates.hh" #define BOOST_TEST_MODULE Integration_Data_Assimilation #include "../applications/adamantine.hh" #include #include #include #include "main.cc" namespace tt = boost::test_tools; double integration_da(MPI_Comm communicator, bool l2_norm) { std::vector timers; initialize_timers(communicator, timers); // Read the input. std::string const filename = "bare_plate_L_da.info"; adamantine::ASSERT_THROW(std::filesystem::exists(filename) == true, "The file " + filename + " does not exist."); boost::property_tree::ptree database; boost::property_tree::info_parser::read_info(filename, database); // Run the simulation auto result = run_ensemble<3, 1, 1, adamantine::SolidLiquidPowder, dealii::MemorySpace::Host>(communicator, database, timers); if (l2_norm) { double norm = -1.; for (auto const &r : result) { norm = std::max(r.l2_norm(), norm); } return dealii::Utilities::MPI::max(norm, communicator); } // Three ensemble members expected unsigned int local_result_size = result.size(); unsigned int global_result_size = dealii::Utilities::MPI::sum(local_result_size, communicator); BOOST_TEST(global_result_size == 3); // Get the average minimum value for each ensemble member, which is very close // to the initial temperature double sum = 0.0; for (unsigned int member = 0; member < local_result_size; ++member) { double min_val = std::numeric_limits::max(); for (unsigned int i = 0; i < result.at(member).block(0).locally_owned_size(); ++i) { if (result.at(member).block(0).local_element(i) < min_val) min_val = result.at(member).block(0).local_element(i); } sum += min_val; } double partial_average_minimum_value = sum / global_result_size; double average_minimum_value = dealii::Utilities::MPI::sum(partial_average_minimum_value, communicator); // Based on the experimental data, the expected temperature is ~200.0 BOOST_TEST(average_minimum_value >= 200.0); BOOST_TEST(average_minimum_value < 300.0); MPI_Barrier(communicator); return average_minimum_value; } BOOST_AUTO_TEST_CASE(integration_data_assimilation) { bool l2_norm = dealii::Utilities::MPI::n_mpi_processes(MPI_COMM_WORLD) > 3 ? true : false; double result_world = integration_da(MPI_COMM_WORLD, l2_norm); double result_self = integration_da(MPI_COMM_SELF, l2_norm); BOOST_TEST(result_world == result_self, tt::tolerance(1e-12)); } double integration_da_point_cloud_add_mat(MPI_Comm communicator, bool l2_norm) { std::vector timers; initialize_timers(communicator, timers); // Read the input. std::string const filename = "integration_da_add_material.info"; adamantine::ASSERT_THROW(std::filesystem::exists(filename) == true, "The file " + filename + " does not exist."); boost::property_tree::ptree database; boost::property_tree::info_parser::read_info(filename, database); // Run the simulation auto result = run_ensemble<3, 1, 1, adamantine::SolidLiquidPowder, dealii::MemorySpace::Host>(communicator, database, timers); if (l2_norm) { double norm = -1.; for (auto const &r : result) { norm = std::max(r.l2_norm(), norm); } return dealii::Utilities::MPI::max(norm, communicator); } // Three ensemble members expected unsigned int local_result_size = result.size(); unsigned int global_result_size = dealii::Utilities::MPI::sum(local_result_size, communicator); BOOST_TEST(global_result_size == 3); // Get the average minimum value for each ensemble member, which is very close // to the initial temperature double sum = 0.0; for (unsigned int member = 0; member < local_result_size; ++member) { double min_val = std::numeric_limits::max(); for (unsigned int i = 0; i < result.at(member).block(0).locally_owned_size(); ++i) { if (result.at(member).block(0).local_element(i) < min_val) min_val = result.at(member).block(0).local_element(i); } sum += min_val; } double partial_average_minimum_value = sum / global_result_size; double average_minimum_value = dealii::Utilities::MPI::sum(partial_average_minimum_value, communicator); // Based on the experimental data, the expected temperature is ~200.0 BOOST_CHECK(average_minimum_value >= 200.0); BOOST_CHECK(average_minimum_value < 300.0); MPI_Barrier(communicator); return average_minimum_value; } BOOST_AUTO_TEST_CASE(integration_3D_da_point_cloud_add_material) { /* * This integration test checks that the data assimilation using point cloud * data works while adding material. */ bool l2_norm = dealii::Utilities::MPI::n_mpi_processes(MPI_COMM_WORLD) > 3 ? true : false; double result_world = integration_da_point_cloud_add_mat(MPI_COMM_WORLD, l2_norm); double result_self = integration_da_point_cloud_add_mat(MPI_COMM_SELF, l2_norm); BOOST_TEST(result_world == result_self, tt::tolerance(1e-12)); } double integration_da_ray_add_mat(MPI_Comm communicator, bool l2_norm) { std::vector timers; initialize_timers(communicator, timers); // Read the input. std::string const filename = "integration_da_add_material.info"; adamantine::ASSERT_THROW(std::filesystem::exists(filename) == true, "The file " + filename + " does not exist."); boost::property_tree::ptree database; boost::property_tree::info_parser::read_info(filename, database); // Change experiment file name database.put("experiment.file", "integration_da_add_material_expt_ray_#camera_#frame.csv"); // Change experiment data format to ray database.put("experiment.format", "ray"); // Run the simulation auto result = run_ensemble<3, -1, 1, adamantine::SolidLiquidPowder, dealii::MemorySpace::Host>(communicator, database, timers); if (l2_norm) { double norm = -1.; for (auto const &r : result) { norm = std::max(r.l2_norm(), norm); } return dealii::Utilities::MPI::max(norm, communicator); } // Three ensemble members expected unsigned int local_result_size = result.size(); unsigned int global_result_size = dealii::Utilities::MPI::sum(local_result_size, communicator); BOOST_TEST(global_result_size == 3); // Get the average minimum value for each ensemble member, which is very close // to the initial temperature double sum = 0.0; for (unsigned int member = 0; member < result.size(); ++member) { double min_val = std::numeric_limits::max(); for (unsigned int i = 0; i < result.at(member).block(0).locally_owned_size(); ++i) { if (result.at(member).block(0).local_element(i) < min_val) min_val = result.at(member).block(0).local_element(i); } sum += min_val; } double partial_average_minimum_value = sum / global_result_size; double average_minimum_value = dealii::Utilities::MPI::sum(partial_average_minimum_value, communicator); // Based on the experimental data, the expected temperature is ~200.0 BOOST_CHECK(average_minimum_value >= 200.0); BOOST_CHECK(average_minimum_value < 300.0); MPI_Barrier(communicator); return average_minimum_value; } BOOST_AUTO_TEST_CASE(integration_3D_da_ray_add_material) { /* * This integration test checks that the data assimilation using point cloud * data works while adding material. */ bool l2_norm = dealii::Utilities::MPI::n_mpi_processes(MPI_COMM_WORLD) > 3 ? true : false; double result_world = integration_da_ray_add_mat(MPI_COMM_WORLD, l2_norm); double result_self = integration_da_ray_add_mat(MPI_COMM_SELF, l2_norm); BOOST_TEST(result_world == result_self, tt::tolerance(1e-12)); }