/* SPDX-FileCopyrightText: Copyright (c) 2021 - 2024, the adamantine authors. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception */ #include "MaterialStates.hh" #include #include #include #include #include #include #include #include namespace tt = boost::test_tools; template void material_property() { MPI_Comm communicator = MPI_COMM_WORLD; // Create the Geometry boost::property_tree::ptree geometry_database; geometry_database.put("import_mesh", false); geometry_database.put("length", 12); geometry_database.put("length_divisions", 4); geometry_database.put("height", 6); geometry_database.put("height_divisions", 5); boost::optional units_optional_database; adamantine::Geometry<2> geometry(communicator, geometry_database, units_optional_database); auto const &triangulation = geometry.get_triangulation(); for (auto cell : triangulation.cell_iterators()) { cell->set_material_id(0); cell->set_user_index( static_cast(adamantine::SolidLiquidPowder::State::solid)); } // Create the MaterialProperty boost::property_tree::ptree database; database.put("property_format", "polynomial"); database.put("n_materials", 1); database.put("material_0.solid.density", 1.); database.put("material_0.solid.thermal_conductivity_x", 10.); database.put("material_0.solid.thermal_conductivity_z", 10.); database.put("material_0.powder.thermal_conductivity_x", 10.); database.put("material_0.powder.thermal_conductivity_z", 10.); database.put("material_0.liquid", ""); database.put("material_0.liquidus", "100"); database.put("material_0.solid.lame_first_parameter", 2.); database.put("material_0.solid.lame_second_parameter", 3.); adamantine::MaterialProperty<2, 1, 2, adamantine::SolidLiquidPowder, MemorySpaceType> mat_prop(communicator, triangulation, database); // Evaluate the material property at the given temperature dealii::FE_Q<2> fe(4); dealii::DoFHandler<2> dof_handler(triangulation); dof_handler.distribute_dofs(fe); dealii::LinearAlgebra::distributed::Vector temperature(dof_handler.locally_owned_dofs(), communicator); mat_prop.update(dof_handler, temperature); // This checks only one cell for (auto cell : triangulation.active_cell_iterators()) { double const density = mat_prop.get_cell_value(cell, adamantine::StateProperty::density); BOOST_TEST(density == 1.); double const th_conduc_x = mat_prop.get_cell_value( cell, adamantine::StateProperty::thermal_conductivity_x); BOOST_TEST(th_conduc_x == 10.); double const th_conduc_z = mat_prop.get_cell_value( cell, adamantine::StateProperty::thermal_conductivity_z); BOOST_TEST(th_conduc_z == 10.); double const liquidus = mat_prop.get_cell_value(cell, adamantine::Property::liquidus); BOOST_TEST(liquidus == 100.); double const lambda = mat_prop.get_mechanical_property( cell, adamantine::StateProperty::lame_first_parameter); BOOST_TEST(lambda == 2.); double const mu = mat_prop.get_mechanical_property( cell, adamantine::StateProperty::lame_second_parameter); BOOST_TEST(mu == 3.); } } template void ratios() { MPI_Comm communicator = MPI_COMM_WORLD; // Create the Geometry boost::property_tree::ptree geometry_database; geometry_database.put("import_mesh", false); geometry_database.put("length", 12); geometry_database.put("length_divisions", 4); geometry_database.put("height", 6); geometry_database.put("height_divisions", 5); boost::optional units_optional_database; adamantine::Geometry<2> geometry(communicator, geometry_database, units_optional_database); auto const &triangulation = geometry.get_triangulation(); for (auto cell : triangulation.active_cell_iterators()) { cell->set_material_id(0); cell->set_user_index( static_cast(adamantine::SolidLiquidPowder::State::powder)); } dealii::FE_Q<2> fe(1); dealii::DoFHandler<2> dof_handler(triangulation); dof_handler.distribute_dofs(fe); // Create the MaterialProperty boost::property_tree::ptree database; database.put("property_format", "polynomial"); database.put("n_materials", 1); database.put("material_0.solid.density", 10.); database.put("material_0.solid.thermal_conductivity_x", 10.); database.put("material_0.solid.thermal_conductivity_z", 10.); database.put("material_0.solid.specific_heat", 10.); database.put("material_0.powder.density", 1.); database.put("material_0.powder.thermal_conductivity_x", 1.); database.put("material_0.powder.thermal_conductivity_z", 1.); database.put("material_0.powder.specific_heat", 1.); database.put("material_0.liquid.density", 1.); database.put("material_0.liquid.thermal_conductivity_x", 20.); database.put("material_0.liquid.thermal_conductivity_z", 20.); database.put("material_0.liquid.specific_heat", 20.); database.put("material_0.solidus", "50"); database.put("material_0.liquidus", "100"); database.put("material_0.latent_heat", "1000"); adamantine::MaterialProperty<2, 1, 0, adamantine::SolidLiquidPowder, MemorySpaceType> mat_prop(communicator, triangulation, database); dealii::LinearAlgebra::distributed::Vector temperature(dof_handler.locally_owned_dofs(), communicator); mat_prop.update(dof_handler, temperature); // Check the material properties of the powder for (auto cell : triangulation.active_cell_iterators()) { double powder_ratio = mat_prop.get_state_ratio( cell, adamantine::SolidLiquidPowder::State::powder); BOOST_TEST(powder_ratio == 1.); double solid_ratio = mat_prop.get_state_ratio( cell, adamantine::SolidLiquidPowder::State::solid); BOOST_TEST(solid_ratio == 0.); double liquid_ratio = mat_prop.get_state_ratio( cell, adamantine::SolidLiquidPowder::State::liquid); BOOST_TEST(liquid_ratio == 0.); double const density = mat_prop.get_cell_value(cell, adamantine::StateProperty::density); BOOST_TEST(density == 1.); double const th_conduc_x = mat_prop.get_cell_value( cell, adamantine::StateProperty::thermal_conductivity_x); BOOST_TEST(th_conduc_x == 1.); double const th_conduc_z = mat_prop.get_cell_value( cell, adamantine::StateProperty::thermal_conductivity_z); BOOST_TEST(th_conduc_z == 1.); double const liquidus = mat_prop.get_cell_value(cell, adamantine::Property::liquidus); BOOST_TEST(liquidus == 100.); double const solidus = mat_prop.get_cell_value(cell, adamantine::Property::solidus); BOOST_TEST(solidus == 50.); double const latent_heat = mat_prop.get_cell_value(cell, adamantine::Property::latent_heat); BOOST_TEST(latent_heat == 1000.); double const specific_heat = mat_prop.get_cell_value(cell, adamantine::StateProperty::specific_heat); BOOST_TEST(specific_heat == 1.); } // Check the material properties of the liquid dealii::types::global_dof_index const n_dofs = dof_handler.n_dofs(); dealii::LA::distributed::Vector avg_temperature( n_dofs); dealii::LA::ReadWriteVector rw_vector(n_dofs); for (unsigned int i = 0; i < n_dofs; ++i) rw_vector[i] = 100000.; avg_temperature.import_elements(rw_vector, dealii::VectorOperation::insert); mat_prop.update(dof_handler, avg_temperature); for (auto cell : triangulation.active_cell_iterators()) { double powder_ratio = mat_prop.get_state_ratio( cell, adamantine::SolidLiquidPowder::State::powder); BOOST_TEST(powder_ratio == 0.); double solid_ratio = mat_prop.get_state_ratio( cell, adamantine::SolidLiquidPowder::State::solid); BOOST_TEST(solid_ratio == 0.); double liquid_ratio = mat_prop.get_state_ratio( cell, adamantine::SolidLiquidPowder::State::liquid); BOOST_TEST(liquid_ratio == 1.); double const density = mat_prop.get_cell_value(cell, adamantine::StateProperty::density); BOOST_TEST(density == 1.); double const th_conduc_x = mat_prop.get_cell_value( cell, adamantine::StateProperty::thermal_conductivity_x); BOOST_TEST(th_conduc_x == 20.); double const th_conduc_z = mat_prop.get_cell_value( cell, adamantine::StateProperty::thermal_conductivity_z); BOOST_TEST(th_conduc_z == 20.); double const liquidus = mat_prop.get_cell_value(cell, adamantine::Property::liquidus); BOOST_TEST(liquidus == 100.); double const solidus = mat_prop.get_cell_value(cell, adamantine::Property::solidus); BOOST_TEST(solidus == 50.); double const latent_heat = mat_prop.get_cell_value(cell, adamantine::Property::latent_heat); BOOST_TEST(latent_heat == 1000.); double const specific_heat = mat_prop.get_cell_value(cell, adamantine::StateProperty::specific_heat); BOOST_TEST(specific_heat == 20.); } // Check the material properties of the solid avg_temperature = 0.; mat_prop.update(dof_handler, avg_temperature); for (auto cell : triangulation.active_cell_iterators()) { double powder_ratio = mat_prop.get_state_ratio( cell, adamantine::SolidLiquidPowder::State::powder); BOOST_TEST(powder_ratio == 0.); double solid_ratio = mat_prop.get_state_ratio( cell, adamantine::SolidLiquidPowder::State::solid); BOOST_TEST(solid_ratio == 1.); double liquid_ratio = mat_prop.get_state_ratio( cell, adamantine::SolidLiquidPowder::State::liquid); BOOST_TEST(liquid_ratio == 0.); double const density = mat_prop.get_cell_value(cell, adamantine::StateProperty::density); BOOST_TEST(density == 10.); double const th_conduc_x = mat_prop.get_cell_value( cell, adamantine::StateProperty::thermal_conductivity_x); BOOST_TEST(th_conduc_x == 10.); double const th_conduc_z = mat_prop.get_cell_value( cell, adamantine::StateProperty::thermal_conductivity_z); BOOST_TEST(th_conduc_z == 10.); double const liquidus = mat_prop.get_cell_value(cell, adamantine::Property::liquidus); BOOST_TEST(liquidus == 100.); double const solidus = mat_prop.get_cell_value(cell, adamantine::Property::solidus); BOOST_TEST(solidus == 50.); double const latent_heat = mat_prop.get_cell_value(cell, adamantine::Property::latent_heat); BOOST_TEST(latent_heat == 1000.); double const specific_heat = mat_prop.get_cell_value(cell, adamantine::StateProperty::specific_heat); BOOST_TEST(specific_heat == 10.); } } template void material_property_table() { MPI_Comm communicator = MPI_COMM_WORLD; boost::property_tree::ptree database; boost::property_tree::read_info("material_property_table.info", database); // Create the Geometry boost::property_tree::ptree geometry_database = database.get_child("geometry"); boost::optional units_optional_database; adamantine::Geometry<2> geometry(communicator, geometry_database, units_optional_database); auto const &triangulation = geometry.get_triangulation(); unsigned int n = 0; for (auto cell : triangulation.active_cell_iterators()) { if (n < 10) cell->set_material_id(0); else cell->set_material_id(1); if (n < 15) cell->set_user_index( static_cast(adamantine::SolidLiquidPowder::State::solid)); else cell->set_user_index( static_cast(adamantine::SolidLiquidPowder::State::powder)); ++n; } // Create the MaterialProperty boost::property_tree::ptree material_database = database.get_child("materials"); adamantine::MaterialProperty<2, -1, 0, adamantine::SolidLiquidPowder, MemorySpaceType> mat_prop(communicator, triangulation, material_database); // Evaluate the material property at the given temperature dealii::FE_Q<2> fe(4); dealii::DoFHandler<2> dof_handler(triangulation); dof_handler.distribute_dofs(fe); dealii::LinearAlgebra::distributed::Vector temperature(dof_handler.locally_owned_dofs(), communicator); dealii::LA::ReadWriteVector rw_vector( dof_handler.locally_owned_dofs()); for (unsigned int i = 0; i < rw_vector.locally_owned_size(); ++i) rw_vector.local_element(i) = 15; temperature.import_elements(rw_vector, dealii::VectorOperation::insert); mat_prop.update(dof_handler, temperature); n = 0; double constexpr tolerance = 1e-10; for (auto cell : triangulation.active_cell_iterators()) { if (n < 10) { BOOST_TEST(mat_prop.get_cell_value( cell, adamantine::StateProperty::density) == 1., tt::tolerance(tolerance)); BOOST_TEST(mat_prop.get_cell_value( cell, adamantine::StateProperty::thermal_conductivity_x) == 100., tt::tolerance(tolerance)); BOOST_TEST(mat_prop.get_cell_value( cell, adamantine::StateProperty::thermal_conductivity_z) == 100., tt::tolerance(tolerance)); } else if (n < 15) { BOOST_TEST(mat_prop.get_cell_value( cell, adamantine::StateProperty::density) == 1.75, tt::tolerance(tolerance)); BOOST_TEST(mat_prop.get_cell_value( cell, adamantine::StateProperty::thermal_conductivity_x) == 150., tt::tolerance(tolerance)); BOOST_TEST(mat_prop.get_cell_value( cell, adamantine::StateProperty::thermal_conductivity_z) == 150., tt::tolerance(tolerance)); } else { BOOST_TEST(mat_prop.get_cell_value( cell, adamantine::StateProperty::density) == 2., tt::tolerance(tolerance)); BOOST_TEST(mat_prop.get_cell_value( cell, adamantine::StateProperty::thermal_conductivity_x) == 162.5, tt::tolerance(tolerance)); BOOST_TEST(mat_prop.get_cell_value( cell, adamantine::StateProperty::thermal_conductivity_z) == 162.5, tt::tolerance(tolerance)); } ++n; } } template void material_property_polynomials() { MPI_Comm communicator = MPI_COMM_WORLD; boost::property_tree::ptree database; boost::property_tree::read_info("material_property_polynomial.info", database); // Create the Geometry boost::property_tree::ptree geometry_database = database.get_child("geometry"); boost::optional units_optional_database; adamantine::Geometry<2> geometry(communicator, geometry_database, units_optional_database); auto const &triangulation = geometry.get_triangulation(); unsigned int n = 0; for (auto cell : triangulation.active_cell_iterators()) { if (n < 10) cell->set_material_id(0); else cell->set_material_id(1); if (n < 15) cell->set_user_index( static_cast(adamantine::SolidLiquidPowder::State::solid)); else cell->set_user_index( static_cast(adamantine::SolidLiquidPowder::State::powder)); ++n; } // Create the MaterialProperty boost::property_tree::ptree material_database = database.get_child("materials"); adamantine::MaterialProperty<2, -1, 4, adamantine::SolidLiquidPowder, MemorySpaceType> mat_prop(communicator, triangulation, material_database); // Evaluate the material property at the given temperature dealii::FE_Q<2> fe(4); dealii::DoFHandler<2> dof_handler(triangulation); dof_handler.distribute_dofs(fe); dealii::LinearAlgebra::distributed::Vector temperature(dof_handler.locally_owned_dofs(), communicator); dealii::LA::ReadWriteVector rw_vector( dof_handler.locally_owned_dofs()); for (unsigned int i = 0; i < temperature.locally_owned_size(); ++i) rw_vector.local_element(i) = 15; temperature.import_elements(rw_vector, dealii::VectorOperation::insert); mat_prop.update(dof_handler, temperature); n = 0; double constexpr tolerance = 1e-10; for (auto cell : triangulation.active_cell_iterators()) { if (n < 10) { BOOST_TEST(mat_prop.get_cell_value( cell, adamantine::StateProperty::density) == 15., tt::tolerance(tolerance)); BOOST_TEST(mat_prop.get_cell_value( cell, adamantine::StateProperty::thermal_conductivity_x) == 465., tt::tolerance(tolerance)); BOOST_TEST(mat_prop.get_cell_value( cell, adamantine::StateProperty::thermal_conductivity_z) == 465., tt::tolerance(tolerance)); } else if (n < 15) { BOOST_TEST(mat_prop.get_cell_value( cell, adamantine::StateProperty::density) == 706., tt::tolerance(tolerance)); BOOST_TEST(mat_prop.get_cell_value( cell, adamantine::StateProperty::thermal_conductivity_x) == 681001., tt::tolerance(tolerance)); BOOST_TEST(mat_prop.get_cell_value( cell, adamantine::StateProperty::thermal_conductivity_z) == 681001., tt::tolerance(tolerance)); } else { BOOST_TEST(mat_prop.get_cell_value( cell, adamantine::StateProperty::density) == 720., tt::tolerance(tolerance)); BOOST_TEST(mat_prop.get_cell_value( cell, adamantine::StateProperty::thermal_conductivity_x) == 45280., tt::tolerance(tolerance)); BOOST_TEST(mat_prop.get_cell_value( cell, adamantine::StateProperty::thermal_conductivity_z) == 45280., tt::tolerance(tolerance)); } ++n; } }