From 8728e741b89a49249eed05533ef5fca6724326e0 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Fri, 3 May 2024 10:15:33 -0400 Subject: [PATCH 01/30] Introduce HeatSources --- application/adamantine.hh | 49 ++--- source/ElectronBeamHeatSource.cc | 7 +- source/ElectronBeamHeatSource.hh | 1 - source/GoldakHeatSource.cc | 3 + source/GoldakHeatSource.hh | 1 - source/HeatSources.hh | 266 ++++++++++++++++++++++++++ source/ThermalOperator.hh | 16 +- source/ThermalOperator.templates.hh | 13 +- source/ThermalPhysics.hh | 8 +- source/ThermalPhysics.templates.hh | 74 +------ source/ThermalPhysicsInterface.hh | 2 +- source/material_deposition.cc | 12 +- source/material_deposition.hh | 4 +- tests/test_heat_source.cc | 2 +- tests/test_implicit_operator.cc | 11 +- tests/test_post_processor.cc | 11 +- tests/test_thermal_operator.cc | 57 ++++-- tests/test_thermal_operator_device.cc | 11 +- 18 files changed, 390 insertions(+), 158 deletions(-) create mode 100644 source/HeatSources.hh diff --git a/application/adamantine.hh b/application/adamantine.hh index f2b382d6..ebdc0fd8 100644 --- a/application/adamantine.hh +++ b/application/adamantine.hh @@ -520,7 +520,7 @@ compute_cells_to_refine( dealii::parallel::distributed::Triangulation &triangulation, double const time, double const next_refinement_time, unsigned int const n_time_steps, - std::vector>> &heat_sources, + adamantine::HeatSources &heat_sources, double const current_source_height, double const refinement_beam_cutoff) { @@ -537,25 +537,22 @@ compute_cells_to_refine( double const current_time = time + static_cast(i) / static_cast(n_time_steps) * (next_refinement_time - time); - for (auto &beam : heat_sources) + heat_sources.update_time(current_time); + for (auto cell : + dealii::filter_iterators(triangulation.active_cell_iterators(), + dealii::IteratorFilters::LocallyOwnedCell())) { - beam->update_time(current_time); - for (auto cell : dealii::filter_iterators( - triangulation.active_cell_iterators(), - dealii::IteratorFilters::LocallyOwnedCell())) + // Check the value at the center of the cell faces. For most cases this + // should be sufficient, but if the beam is small compared to the + // coarsest mesh we may need to add other points to check (e.g. + // quadrature points, vertices). + for (unsigned int f = 0; f < cell->reference_cell().n_faces(); ++f) { - // Check the value at the center of the cell faces. For most cases this - // should be sufficient, but if the beam is small compared to the - // coarsest mesh we may need to add other points to check (e.g. - // quadrature points, vertices). - for (unsigned int f = 0; f < cell->reference_cell().n_faces(); ++f) + if (heat_sources.max_value(cell->face(f)->center(), current_source_height) > + refinement_beam_cutoff) { - if (beam->value(cell->face(f)->center(), current_source_height) > - refinement_beam_cutoff) - { - cells_to_refine.push_back(cell); - break; - } + cells_to_refine.push_back(cell); + break; } } } @@ -572,7 +569,7 @@ void refine_mesh( adamantine::MaterialProperty &material_properties, dealii::LA::distributed::Vector &solution, - std::vector>> &heat_sources, + adamantine::HeatSources const &heat_sources, double const time, double const next_refinement_time, unsigned int const time_steps_refinement, boost::property_tree::ptree const &refinement_database) @@ -609,6 +606,8 @@ void refine_mesh( const double refinement_beam_cutoff = refinement_database.get("beam_cutoff", 1.0e-15); + adamantine::HeatSources host_heat_sources = heat_sources.copy_to_host(); + for (unsigned int i = 0; i < n_refinements; ++i) { // Compute the cells to be refined. @@ -616,7 +615,7 @@ void refine_mesh( dim>::active_cell_iterator> cells_to_refine = compute_cells_to_refine( triangulation, time, next_refinement_time, time_steps_refinement, - heat_sources, current_source_height, refinement_beam_cutoff); + host_heat_sources, current_source_height, refinement_beam_cutoff); // PropertyTreeInput refinement.coarsen_after_beam const bool coarsen_after_beam = @@ -661,7 +660,7 @@ void refine_mesh( adamantine::MaterialProperty &material_properties, dealii::LA::distributed::Vector &solution, - std::vector>> &heat_sources, + adamantine::HeatSources const &heat_sources, double const time, double const next_refinement_time, unsigned int const time_steps_refinement, boost::property_tree::ptree const &refinement_database) @@ -759,7 +758,7 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database, // Create ThermalPhysics if necessary std::unique_ptr> thermal_physics; - std::vector>> heat_sources; + adamantine::HeatSources heat_sources; if (use_thermal_physics) { // PropertyTreeInput discretization.thermal.fe_degree @@ -936,11 +935,13 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database, mechanical_physics, displacement, material_properties, timers); ++n_time_step; + adamantine::HeatSources host_heat_sources = heat_sources.copy_to_host(); + // Create the bounding boxes used for material deposition auto [material_deposition_boxes, deposition_times, deposition_cos, deposition_sin] = adamantine::create_material_deposition_boxes(geometry_database, - heat_sources); + host_heat_sources); // Extract the time-stepping database boost::property_tree::ptree time_stepping_database = database.get_child("time_stepping"); @@ -1364,7 +1365,7 @@ run_ensemble(MPI_Comm const &global_communicator, adamantine::ThermalPhysicsInterface>> thermal_physics_ensemble(local_ensemble_size); - std::vector>>> + std::vector> heat_sources_ensemble(local_ensemble_size); std::vector>> geometry_ensemble; @@ -1718,7 +1719,7 @@ run_ensemble(MPI_Comm const &global_communicator, refine_mesh(thermal_physics_ensemble[member], *material_properties_ensemble[member], solution_augmented_ensemble[member].block(base_state), - heat_sources_ensemble[member], time, next_refinement_time, + heat_sources_ensemble[member].copy_to_host(), time, next_refinement_time, time_steps_refinement, refinement_database); solution_augmented_ensemble[member].collect_sizes(); } diff --git a/source/ElectronBeamHeatSource.cc b/source/ElectronBeamHeatSource.cc index 260ae6b6..8f7114a6 100644 --- a/source/ElectronBeamHeatSource.cc +++ b/source/ElectronBeamHeatSource.cc @@ -22,11 +22,12 @@ ElectronBeamHeatSource::ElectronBeamHeatSource( template void ElectronBeamHeatSource::update_time(double time) { + static const double log_01 = std::log(0.1); _beam_center = this->_scan_path.value(time); double segment_power_modifier = this->_scan_path.get_power_modifier(time); _alpha = -this->_beam.absorption_efficiency * this->_beam.max_power * - segment_power_modifier * _log_01 / + segment_power_modifier * log_01 / (dealii::numbers::PI * this->_beam.radius_squared * this->_beam.depth); } @@ -52,9 +53,11 @@ double ElectronBeamHeatSource::value(dealii::Point const &point, std::pow(point[axis::y] - _beam_center[axis::y], 2); } + static const double log_01 = std::log(0.1); + // Electron beam heat source equation double heat_source = - _alpha * std::exp(_log_01 * xpy_squared / this->_beam.radius_squared) * + _alpha * std::exp(log_01 * xpy_squared / this->_beam.radius_squared) * distribution_z; return heat_source; diff --git a/source/ElectronBeamHeatSource.hh b/source/ElectronBeamHeatSource.hh index e3673dbf..70892a3e 100644 --- a/source/ElectronBeamHeatSource.hh +++ b/source/ElectronBeamHeatSource.hh @@ -48,7 +48,6 @@ public: private: dealii::Point<3> _beam_center; double _alpha; - double const _log_01 = std::log(0.1); }; } // namespace adamantine diff --git a/source/GoldakHeatSource.cc b/source/GoldakHeatSource.cc index 56789898..e1faae65 100644 --- a/source/GoldakHeatSource.cc +++ b/source/GoldakHeatSource.cc @@ -22,6 +22,9 @@ GoldakHeatSource::GoldakHeatSource( template void GoldakHeatSource::update_time(double time) { + static const double _pi_over_3_to_1p5 = + std::pow(dealii::numbers::PI / 3.0, 1.5); + _beam_center = this->_scan_path.value(time); double segment_power_modifier = this->_scan_path.get_power_modifier(time); _alpha = 2.0 * this->_beam.absorption_efficiency * this->_beam.max_power * diff --git a/source/GoldakHeatSource.hh b/source/GoldakHeatSource.hh index b145ee1e..90a94928 100644 --- a/source/GoldakHeatSource.hh +++ b/source/GoldakHeatSource.hh @@ -48,7 +48,6 @@ public: private: dealii::Point<3> _beam_center; double _alpha; - double const _pi_over_3_to_1p5 = std::pow(dealii::numbers::PI / 3.0, 1.5); }; } // namespace adamantine diff --git a/source/HeatSources.hh b/source/HeatSources.hh new file mode 100644 index 00000000..5c820b1e --- /dev/null +++ b/source/HeatSources.hh @@ -0,0 +1,266 @@ +/* Copyright (c) 2020 - 2021, the adamantine authors. + * + * This file is subject to the Modified BSD License and may not be distributed + * without copyright and license information. Please refer to the file LICENSE + * for the text and further information on this license. + */ + +#ifndef HEAT_SOURCES_HH +#define HEAT_SOURCES_HH + +#include +#include +#include +#include + +#include + +namespace adamantine +{ +template +class HeatSources +{ +public: + /** + * Default constructor creating empty object. + */ + HeatSources() = default; + + /** + * Constructor. + */ + HeatSources(boost::property_tree::ptree const &source_database); + + HeatSources( + Kokkos::View *, + typename MemorySpace::kokkos_space> + electron_beam_heat_sources, + Kokkos::View *, typename MemorySpace::kokkos_space> + cube_heat_sources, + Kokkos::View *, typename MemorySpace::kokkos_space> + goldak_heat_sources) + : _electron_beam_heat_sources(electron_beam_heat_sources), + _cube_heat_sources(cube_heat_sources), + _goldak_heat_sources(goldak_heat_sources) + { + } + + HeatSources copy_to_host() const + { + return {Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, + _electron_beam_heat_sources), + Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, + _cube_heat_sources), + Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, + _goldak_heat_sources)}; + } + + /** + * Set the time variable. + */ + KOKKOS_FUNCTION void update_time(double time); + + /** + * Compute the cumulative heat source at a given point at a given time given + * the current height of the object being manufactured. + */ + KOKKOS_FUNCTION double value(dealii::Point const &point, + double const height) const; + + /** + * Compute the maxiumum heat source at a given point at a given time given the + * current height of the object being manufactured. + */ + KOKKOS_FUNCTION double max_value(dealii::Point const &point, + double const height) const; + + /** + * Return the scan paths for the heat source. + */ + std::vector get_scan_paths() const; + + /** + * (Re)sets the BeamHeatSourceProperties member variable, necessary if the + * beam parameters vary in time (e.g. due to data assimilation). + */ + void + set_beam_properties(boost::property_tree::ptree const &heat_source_database); + + /** + * Compute the current height of the where the heat source meets the material + * (i.e. the current scan path height). + */ + double get_current_height(double time) const; + +private: + Kokkos::View *, + typename MemorySpace::kokkos_space> + _electron_beam_heat_sources; + Kokkos::View *, typename MemorySpace::kokkos_space> + _cube_heat_sources; + Kokkos::View *, typename MemorySpace::kokkos_space> + _goldak_heat_sources; +}; + +template +HeatSources::HeatSources( + boost::property_tree::ptree const &source_database) +{ + unsigned int const n_beams = source_database.get("n_beams"); + std::vector> electron_beam_heat_sources; + std::vector> cube_heat_sources; + std::vector> goldak_heat_sources; + for (unsigned int i = 0; i < n_beams; ++i) + { + boost::property_tree::ptree const &beam_database = + source_database.get_child("beam_" + std::to_string(i)); + std::string type = beam_database.get("type"); + if (type == "goldak") + { + goldak_heat_sources.emplace_back(beam_database); + } + else if (type == "electron_beam") + { + electron_beam_heat_sources.emplace_back(beam_database); + } + else if (type == "cube") + { + cube_heat_sources.emplace_back(beam_database); + } + else + { + ASSERT_THROW(false, "Error: Beam type '" + + beam_database.get("type") + + "' not recognized."); + } + } + _goldak_heat_sources = decltype(_goldak_heat_sources)( + Kokkos::view_alloc(Kokkos::WithoutInitializing, "goldak_heat_sources"), + goldak_heat_sources.size()); + _electron_beam_heat_sources = decltype(_electron_beam_heat_sources)( + Kokkos::view_alloc(Kokkos::WithoutInitializing, + "electron_beam_heat_sources"), + electron_beam_heat_sources.size()); + _cube_heat_sources = decltype(_cube_heat_sources)( + Kokkos::view_alloc(Kokkos::WithoutInitializing, "cube_heat_sources"), + cube_heat_sources.size()); + Kokkos::deep_copy( + _goldak_heat_sources, + Kokkos::View *, Kokkos::HostSpace>( + goldak_heat_sources.data(), goldak_heat_sources.size())); + Kokkos::deep_copy( + _electron_beam_heat_sources, + Kokkos::View *, Kokkos::HostSpace>( + electron_beam_heat_sources.data(), + electron_beam_heat_sources.size())); + Kokkos::deep_copy(_cube_heat_sources, + Kokkos::View *, Kokkos::HostSpace>( + cube_heat_sources.data(), cube_heat_sources.size())); +} + +template +KOKKOS_FUNCTION void HeatSources::update_time(double time) +{ + for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) + _electron_beam_heat_sources(i).update_time(time); + for (unsigned int i = 0; i < _cube_heat_sources.size(); ++i) + _cube_heat_sources(i).update_time(time); + for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) + _goldak_heat_sources(i).update_time(time); +} + +template +KOKKOS_FUNCTION double +HeatSources::value(dealii::Point const &point, + double const height) const +{ + double value = 0; + for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) + value += _electron_beam_heat_sources(i).value(point, height); + for (unsigned int i = 0; i < _cube_heat_sources.size(); ++i) + value += _cube_heat_sources(i).value(point, height); + for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) + value += _goldak_heat_sources(i).value(point, height); + return value; +} + +template +KOKKOS_FUNCTION double +HeatSources::max_value(dealii::Point const &point, + double const height) const +{ + double value = 0; + for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) + value = + std::max(value, _electron_beam_heat_sources(i).value(point, height)); + for (unsigned int i = 0; i < _cube_heat_sources.size(); ++i) + value = std::max(value, _cube_heat_sources(i).value(point, height)); + for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) + value = std::max(value, _goldak_heat_sources(i).value(point, height)); + return value; +} + +template +std::vector HeatSources::get_scan_paths() const +{ + std::vector scan_paths; + for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) + scan_paths.push_back(_electron_beam_heat_sources(i).get_scan_path()); + for (unsigned int i = 0; i < _cube_heat_sources.size(); ++i) + scan_paths.push_back(_cube_heat_sources(i).get_scan_path()); + for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) + scan_paths.push_back(_goldak_heat_sources(i).get_scan_path()); + return scan_paths; +} + +template +double HeatSources::get_current_height(double time) const +{ + // Right now this is just the maximum heat source height, which can lead to + // unexpected behavior for + // different sources with different heights. + double temp_height = std::numeric_limits::lowest(); + for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) + temp_height = std::max( + temp_height, _electron_beam_heat_sources(i).get_current_height(time)); + for (unsigned int i = 0; i < _cube_heat_sources.size(); ++i) + temp_height = + std::max(temp_height, _cube_heat_sources(i).get_current_height(time)); + for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) + temp_height = + std::max(temp_height, _goldak_heat_sources(i).get_current_height(time)); + return temp_height; +} + +template +void HeatSources::set_beam_properties( + boost::property_tree::ptree const &heat_source_database) +{ + unsigned int source_index = 0; + + auto set_properties = [&](auto &source) + { + // PropertyTreeInput sources.beam_X + boost::property_tree::ptree const &beam_database = + heat_source_database.get_child("beam_" + std::to_string(source_index)); + + // PropertyTreeInput sources.beam_X.type + std::string type = beam_database.get("type"); + + if (type == "goldak" || type == "electron_beam") + source.set_beam_properties(beam_database); + + source_index++; + }; + + for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) + set_properties(_electron_beam_heat_sources[i]); + for (unsigned int i = 0; i < _cube_heat_sources.size(); ++i) + set_properties(_cube_heat_sources[i]); + for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) + set_properties(_goldak_heat_sources[i]); +} + +} // namespace adamantine + +#endif diff --git a/source/ThermalOperator.hh b/source/ThermalOperator.hh index 5b2bda72..ea769243 100644 --- a/source/ThermalOperator.hh +++ b/source/ThermalOperator.hh @@ -8,7 +8,7 @@ #ifndef THERMAL_OPERATOR_HH #define THERMAL_OPERATOR_HH -#include +#include #include #include #include @@ -28,11 +28,10 @@ template { public: - ThermalOperator( - MPI_Comm const &communicator, BoundaryType boundary_type, - MaterialProperty - &material_properties, - std::vector>> const &heat_sources); + ThermalOperator(MPI_Comm const &communicator, BoundaryType boundary_type, + MaterialProperty &material_properties, + HeatSources const &heat_sources); /** * Associate the AffineConstraints and the MatrixFree objects to the @@ -196,7 +195,7 @@ private: /** * Vector of heat sources. */ - std::vector>> _heat_sources; + HeatSources _heat_sources; /** * Underlying MatrixFree object. */ @@ -323,8 +322,7 @@ ThermalOperatorupdate_time(t); + _heat_sources.update_time(t); } } // namespace adamantine diff --git a/source/ThermalOperator.templates.hh b/source/ThermalOperator.templates.hh index 49a28c86..39933f32 100644 --- a/source/ThermalOperator.templates.hh +++ b/source/ThermalOperator.templates.hh @@ -30,11 +30,10 @@ template ThermalOperator:: - ThermalOperator( - MPI_Comm const &communicator, BoundaryType boundary_type, - MaterialProperty - &material_properties, - std::vector>> const &heat_sources) + ThermalOperator(MPI_Comm const &communicator, BoundaryType boundary_type, + MaterialProperty &material_properties, + HeatSources const &heat_sources) : _communicator(communicator), _boundary_type(boundary_type), _material_properties(material_properties), _heat_sources(heat_sources), _inverse_mass_matrix( @@ -625,8 +624,8 @@ void ThermalOperatorvalue(q_point_loc, _current_source_height); + quad_pt_source[i] += + _heat_sources.value(q_point_loc, _current_source_height); } quad_pt_source *= inv_rho_cp; diff --git a/source/ThermalPhysics.hh b/source/ThermalPhysics.hh index f0adc4e7..625ad05e 100644 --- a/source/ThermalPhysics.hh +++ b/source/ThermalPhysics.hh @@ -9,7 +9,7 @@ #define THERMAL_PHYSICS_HH #include -#include +#include #include #include #include @@ -112,7 +112,7 @@ public: dealii::AffineConstraints &get_affine_constraints() override; - std::vector>> &get_heat_sources() override; + HeatSources &get_heat_sources() override; unsigned int get_fe_degree() const override; @@ -220,7 +220,7 @@ private: /** * Vector of heat sources. */ - std::vector>> _heat_sources; + mutable HeatSources _heat_sources; /** * Shared pointer to the underlying ThermalOperator. */ @@ -324,7 +324,7 @@ ThermalPhysics -inline std::vector>> & +inline HeatSources & ThermalPhysics::get_heat_sources() { diff --git a/source/ThermalPhysics.templates.hh b/source/ThermalPhysics.templates.hh index a751bf8c..e443436d 100644 --- a/source/ThermalPhysics.templates.hh +++ b/source/ThermalPhysics.templates.hh @@ -95,7 +95,7 @@ evaluate_thermal_physics_impl( &thermal_operator, dealii::hp::FECollection const &fe_collection, double const t, dealii::DoFHandler const &dof_handler, - std::vector>> const &heat_sources, + HeatSources &heat_sources, double current_source_height, BoundaryType boundary_type, MaterialProperty &material_properties, @@ -120,8 +120,7 @@ evaluate_thermal_physics_impl( // Compute the source term. // TODO do this on the GPU - for (auto &beam : heat_sources) - beam->update_time(t); + heat_sources.update_time(t); dealii::LA::distributed::Vector source( y.get_partitioner()); source = 0.; @@ -166,8 +165,7 @@ evaluate_thermal_physics_impl( double const inv_rho_cp = thermal_operator_dev->get_inv_rho_cp(cell, q); double quad_pt_source = 0.; dealii::Point const &q_point = fe_values.quadrature_point(q); - for (auto &beam : heat_sources) - quad_pt_source += beam->value(q_point, current_source_height); + quad_pt_source += heat_sources.value(q_point, current_source_height); cell_source[i] += inv_rho_cp * quad_pt_source * fe_values.shape_value(i, q) * fe_values.JxW(q); @@ -289,35 +287,7 @@ ThermalPhysics("n_beams"); - _heat_sources.resize(n_beams); - for (unsigned int i = 0; i < n_beams; ++i) - { - // PropertyTreeInput sources.beam_X.type - boost::property_tree::ptree const &beam_database = - source_database.get_child("beam_" + std::to_string(i)); - std::string type = beam_database.get("type"); - if (type == "goldak") - { - _heat_sources[i] = std::make_shared>(beam_database); - } - else if (type == "electron_beam") - { - _heat_sources[i] = - std::make_shared>(beam_database); - } - else if (type == "cube") - { - _heat_sources[i] = std::make_shared>(beam_database); - } - else - { - ASSERT_THROW(false, "Error: Beam type '" + - beam_database.get("type") + - "' not recognized."); - } - } + _heat_sources = HeatSources(source_database); // Create the boundary condition type // PropertyTreeInput boundary.type @@ -494,15 +464,7 @@ ThermalPhysicsset_active_fe_index(1); } - // Set the initial height of the heat source. Right now this is just the - // maximum heat source height, which can lead to unexpected behavior for - // different sources with different heights. - double temp_height = std::numeric_limits::lowest(); - for (auto const &source : _heat_sources) - { - temp_height = std::max(temp_height, source->get_current_height(0.0)); - } - _current_source_height = temp_height; + _current_source_height = _heat_sources.get_current_height(0.0); } template ("type"); - - if (type == "goldak" || type == "electron_beam") - source->set_beam_properties(beam_database); - - source_index++; - } + _heat_sources.set_beam_properties(heat_source_database); } template &solution, std::vector &timers) { - // Update the height of the heat source. Right now this is just the - // maximum heat source height, which can lead to unexpected behavior for - // different sources with different heights. - double temp_height = std::numeric_limits::lowest(); - for (auto const &source : _heat_sources) - { - temp_height = std::max(temp_height, source->get_current_height(t)); - } - _current_source_height = temp_height; + _current_source_height = _heat_sources.get_current_height(t); auto eval = [&](double const t, LA_Vector const &y) { return evaluate_thermal_physics(t, y, timers); }; diff --git a/source/ThermalPhysicsInterface.hh b/source/ThermalPhysicsInterface.hh index b4b4a845..4662f206 100644 --- a/source/ThermalPhysicsInterface.hh +++ b/source/ThermalPhysicsInterface.hh @@ -175,7 +175,7 @@ public: /** * Return the heat sources. */ - virtual std::vector>> &get_heat_sources() = 0; + virtual HeatSources &get_heat_sources() = 0; /** * Return the degree of the finite element. diff --git a/source/material_deposition.cc b/source/material_deposition.cc index 419772ac..e128c490 100644 --- a/source/material_deposition.cc +++ b/source/material_deposition.cc @@ -24,7 +24,7 @@ std::tuple>, std::vector, std::vector, std::vector> create_material_deposition_boxes( boost::property_tree::ptree const &geometry_database, - std::vector>> &heat_sources) + HeatSources &heat_sources) { // PropertyTreeInput geometry.material_deposition bool material_deposition = @@ -46,10 +46,10 @@ create_material_deposition_boxes( std::tuple>, std::vector, std::vector, std::vector>> deposition_paths; - for (auto const &source : heat_sources) + for (auto const &scan_path : heat_sources.get_scan_paths()) { - deposition_paths.emplace_back(deposition_along_scan_path( - geometry_database, source->get_scan_path())); + deposition_paths.emplace_back( + deposition_along_scan_path(geometry_database, scan_path)); } return merge_deposition_paths(deposition_paths); @@ -358,12 +358,12 @@ template std::tuple>, std::vector, std::vector, std::vector> create_material_deposition_boxes( boost::property_tree::ptree const &geometry_database, - std::vector>> &heat_sources); + HeatSources &heat_sources); template std::tuple>, std::vector, std::vector, std::vector> create_material_deposition_boxes( boost::property_tree::ptree const &geometry_database, - std::vector>> &heat_sources); + HeatSources &heat_sources); template std::tuple>, std::vector, std::vector, std::vector> diff --git a/source/material_deposition.hh b/source/material_deposition.hh index c43435df..6e0a71fa 100644 --- a/source/material_deposition.hh +++ b/source/material_deposition.hh @@ -8,7 +8,7 @@ #ifndef MATERIAL_DEPOSITION_HH #define MATERIAL_DEPOSITION_HH -#include +#include #include #include @@ -26,7 +26,7 @@ std::tuple>, std::vector, std::vector, std::vector> create_material_deposition_boxes( boost::property_tree::ptree const &geometry_database, - std::vector>> &heat_sources); + HeatSources &heat_sources); /** * Read the material deposition file and return the bounding boxes, the * deposition times, the cosine of the deposition angles, and the sine of the diff --git a/tests/test_heat_source.cc b/tests/test_heat_source.cc index 594f96b3..a6d6a70e 100644 --- a/tests/test_heat_source.cc +++ b/tests/test_heat_source.cc @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include "main.cc" diff --git a/tests/test_implicit_operator.cc b/tests/test_implicit_operator.cc index 1eba9765..8a9eb33c 100644 --- a/tests/test_implicit_operator.cc +++ b/tests/test_implicit_operator.cc @@ -80,10 +80,13 @@ BOOST_AUTO_TEST_CASE(implicit_operator) beam_database.put("max_power", 10.); beam_database.put("scan_path_file", "scan_path.txt"); beam_database.put("scan_path_file_format", "segment"); - std::vector>> heat_sources; - heat_sources.resize(1); - heat_sources[0] = - std::make_shared>(beam_database); + Kokkos::View *, Kokkos::HostSpace> + goldak_heat_sources(Kokkos::view_alloc(Kokkos::WithoutInitializing, + "goldak_heat_sources"), + 1); + goldak_heat_sources(0) = adamantine::GoldakHeatSource<2>(beam_database); + adamantine::HeatSources heat_sources( + {}, {}, goldak_heat_sources); // Initialize the ThermalOperator auto thermal_operator = std::make_shared< diff --git a/tests/test_post_processor.cc b/tests/test_post_processor.cc index 91c1f9d0..15a570fd 100644 --- a/tests/test_post_processor.cc +++ b/tests/test_post_processor.cc @@ -79,10 +79,13 @@ BOOST_AUTO_TEST_CASE(thermal_post_processor) beam_database.put("max_power", 10.); beam_database.put("scan_path_file", "scan_path.txt"); beam_database.put("scan_path_file_format", "segment"); - std::vector>> heat_sources; - heat_sources.resize(1); - heat_sources[0] = - std::make_shared>(beam_database); + Kokkos::View *, Kokkos::HostSpace> + goldak_heat_sources(Kokkos::view_alloc(Kokkos::WithoutInitializing, + "goldak_heat_sources"), + 1); + goldak_heat_sources(0) = adamantine::GoldakHeatSource<2>(beam_database); + adamantine::HeatSources heat_sources( + {}, {}, goldak_heat_sources); // Initialize the ThermalOperator adamantine::ThermalOperator<2, false, 0, 2, adamantine::SolidLiquidPowder, diff --git a/tests/test_thermal_operator.cc b/tests/test_thermal_operator.cc index 51330c72..4e8448f6 100644 --- a/tests/test_thermal_operator.cc +++ b/tests/test_thermal_operator.cc @@ -94,10 +94,13 @@ BOOST_AUTO_TEST_CASE(thermal_operator, *utf::tolerance(1e-15)) beam_database.put("max_power", 10.); beam_database.put("scan_path_file", "scan_path.txt"); beam_database.put("scan_path_file_format", "segment"); - std::vector>> heat_sources; - heat_sources.resize(1); - heat_sources[0] = - std::make_shared>(beam_database); + Kokkos::View *, Kokkos::HostSpace> + goldak_heat_sources(Kokkos::view_alloc(Kokkos::WithoutInitializing, + "goldak_heat_sources"), + 1); + goldak_heat_sources(0) = adamantine::GoldakHeatSource<2>(beam_database); + adamantine::HeatSources heat_sources( + {}, {}, goldak_heat_sources); // Initialize the ThermalOperator adamantine::ThermalOperator<2, false, 1, 2, adamantine::SolidLiquidPowder, @@ -199,10 +202,13 @@ BOOST_AUTO_TEST_CASE(spmv, *utf::tolerance(1e-12)) beam_database.put("max_power", 10.); beam_database.put("scan_path_file", "scan_path.txt"); beam_database.put("scan_path_file_format", "segment"); - std::vector>> heat_sources; - heat_sources.resize(1); - heat_sources[0] = - std::make_shared>(beam_database); + Kokkos::View *, Kokkos::HostSpace> + goldak_heat_sources(Kokkos::view_alloc(Kokkos::WithoutInitializing, + "goldak_heat_sources"), + 1); + goldak_heat_sources(0) = adamantine::GoldakHeatSource<2>(beam_database); + adamantine::HeatSources heat_sources( + {}, {}, goldak_heat_sources); // Initialize the ThermalOperator adamantine::ThermalOperator<2, false, 2, 2, adamantine::SolidLiquidPowder, @@ -308,10 +314,13 @@ BOOST_AUTO_TEST_CASE(spmv_anisotropic, *utf::tolerance(1e-12)) beam_database.put("max_power", 10.); beam_database.put("scan_path_file", "scan_path.txt"); beam_database.put("scan_path_file_format", "segment"); - std::vector>> heat_sources; - heat_sources.resize(1); - heat_sources[0] = - std::make_shared>(beam_database); + Kokkos::View *, Kokkos::HostSpace> + goldak_heat_sources(Kokkos::view_alloc(Kokkos::WithoutInitializing, + "goldak_heat_sources"), + 1); + goldak_heat_sources(0) = adamantine::GoldakHeatSource<2>(beam_database); + adamantine::HeatSources heat_sources( + {}, {}, goldak_heat_sources); // Initialize the ThermalOperator adamantine::ThermalOperator<2, false, 2, 2, adamantine::SolidLiquidPowder, @@ -450,7 +459,7 @@ BOOST_AUTO_TEST_CASE(spmv_anisotropic_angle, *utf::tolerance(1e-10)) mat_prop_database); // Create the heat sources - std::vector>> heat_sources; + adamantine::HeatSources heat_sources; // Initialize the ThermalOperator adamantine::ThermalOperator<3, false, 1, 2, adamantine::SolidLiquidPowder, @@ -615,10 +624,13 @@ BOOST_AUTO_TEST_CASE(spmv_rad, *utf::tolerance(1e-12)) beam_database.put("max_power", 10.); beam_database.put("scan_path_file", "scan_path.txt"); beam_database.put("scan_path_file_format", "segment"); - std::vector>> heat_sources; - heat_sources.resize(1); - heat_sources[0] = - std::make_shared>(beam_database); + Kokkos::View *, Kokkos::HostSpace> + goldak_heat_sources(Kokkos::view_alloc(Kokkos::WithoutInitializing, + "goldak_heat_sources"), + 1); + goldak_heat_sources(0) = adamantine::GoldakHeatSource<2>(beam_database); + adamantine::HeatSources heat_sources( + {}, {}, goldak_heat_sources); // Initialize the ThermalOperator adamantine::ThermalOperator<2, false, 1, 2, adamantine::SolidLiquidPowder, @@ -799,10 +811,13 @@ BOOST_AUTO_TEST_CASE(spmv_conv, *utf::tolerance(1e-12)) beam_database.put("max_power", 10.); beam_database.put("scan_path_file", "scan_path.txt"); beam_database.put("scan_path_file_format", "segment"); - std::vector>> heat_sources; - heat_sources.resize(1); - heat_sources[0] = - std::make_shared>(beam_database); + Kokkos::View *, Kokkos::HostSpace> + goldak_heat_sources(Kokkos::view_alloc(Kokkos::WithoutInitializing, + "goldak_heat_sources"), + 1); + goldak_heat_sources(0) = adamantine::GoldakHeatSource<2>(beam_database); + adamantine::HeatSources heat_sources( + {}, {}, goldak_heat_sources); // Initialize the ThermalOperator adamantine::ThermalOperator<2, false, 1, 2, adamantine::SolidLiquidPowder, diff --git a/tests/test_thermal_operator_device.cc b/tests/test_thermal_operator_device.cc index 29b6fa75..36901f80 100644 --- a/tests/test_thermal_operator_device.cc +++ b/tests/test_thermal_operator_device.cc @@ -285,10 +285,13 @@ BOOST_AUTO_TEST_CASE(mf_spmv, *utf::tolerance(1.5e-12)) beam_database.put("max_power", 10.); beam_database.put("scan_path_file", "scan_path.txt"); beam_database.put("scan_path_file_format", "segment"); - std::vector>> heat_sources; - heat_sources.resize(1); - heat_sources[0] = - std::make_shared>(beam_database); + Kokkos::View *, Kokkos::HostSpace> + goldak_heat_sources(Kokkos::view_alloc(Kokkos::WithoutInitializing, + "goldak_heat_sources"), + 1); + goldak_heat_sources(0) = adamantine::GoldakHeatSource<2>(beam_database); + adamantine::HeatSources heat_sources( + {}, {}, goldak_heat_sources); // Initialize the ThermalOperator adamantine::ThermalOperatorDevice<2, false, 4, 2, From 7db8d9ad1deec7dfff7ceb77fbea7ec0234f3fbf Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Mon, 6 May 2024 14:27:03 -0400 Subject: [PATCH 02/30] Update ScanPath implementation --- source/HeatSources.hh | 3 +-- source/ScanPath.cc | 30 +++++++++++++++++------------- source/ScanPath.hh | 6 +++++- tests/test_scan_path.cc | 4 ++-- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/source/HeatSources.hh b/source/HeatSources.hh index 5c820b1e..182cefe4 100644 --- a/source/HeatSources.hh +++ b/source/HeatSources.hh @@ -217,8 +217,7 @@ template double HeatSources::get_current_height(double time) const { // Right now this is just the maximum heat source height, which can lead to - // unexpected behavior for - // different sources with different heights. + // unexpected behavior for different sources with different heights. double temp_height = std::numeric_limits::lowest(); for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) temp_height = std::max( diff --git a/source/ScanPath.cc b/source/ScanPath.cc index 2f9bd328..fffe22fb 100644 --- a/source/ScanPath.cc +++ b/source/ScanPath.cc @@ -60,7 +60,7 @@ void ScanPath::load_segment_scan_path(std::string scan_path_file) { // Check to make sure the segment isn't the first, if it is, throw an // exception (the first segment must be a point in the spec). - ASSERT_THROW(_segment_list.size() > 0, + ASSERT_THROW(_segment_list_length > 0, "Error: Scan paths must begin with a 'point' segment."); } else if (split_line[0] == "1") @@ -85,10 +85,10 @@ void ScanPath::load_segment_scan_path(std::string scan_path_file) // Set the velocity and end time if (segment_type == ScanPathSegmentType::point) { - if (_segment_list.size() > 0) + if (_segment_list_length > 0) { - segment.end_time = - _segment_list.back().end_time + std::stod(split_line[5]); + segment.end_time = _segment_list[_segment_list_length - 1].end_time + + std::stod(split_line[5]); } else { @@ -98,12 +98,14 @@ void ScanPath::load_segment_scan_path(std::string scan_path_file) else { double velocity = std::stod(split_line[5]); - double line_length = - segment.end_point.distance(_segment_list.back().end_point); - segment.end_time = - _segment_list.back().end_time + std::abs(line_length / velocity); + double line_length = segment.end_point.distance( + _segment_list[_segment_list_length - 1].end_point); + segment.end_time = _segment_list[_segment_list_length - 1].end_time + + std::abs(line_length / velocity); } - _segment_list.push_back(segment); + if (_segment_list_length == MAX_NUMBER_OF_SEGMENTS) + Kokkos::abort("too many segmnets"); + _segment_list[_segment_list_length++] = segment; data_index++; } file.close(); @@ -138,7 +140,9 @@ void ScanPath::load_event_series_scan_path(std::string scan_path_file) segment.power_modifier = last_power; last_power = std::stod(split_line[4]); - _segment_list.push_back(segment); + if (_segment_list_length == MAX_NUMBER_OF_SEGMENTS) + Kokkos::abort("too many segmnets"); + _segment_list[_segment_list_length++] = segment; } } @@ -169,7 +173,7 @@ dealii::Point<3> ScanPath::value(double const &time) const { // If the current time is after the scan path data is over, return a point // that is (presumably) out of the domain. - if (time > _segment_list.back().end_time) + if (time > _segment_list[_segment_list_length - 1].end_time) { dealii::Point<3> out_of_domain_point(std::numeric_limits::lowest(), std::numeric_limits::lowest(), @@ -196,7 +200,7 @@ double ScanPath::get_power_modifier(double const &time) const { // If the current time is after the scan path data is over, set the power to // zero. - if (time > _segment_list.back().end_time) + if (time > _segment_list[_segment_list_length - 1].end_time) return 0.0; // Get to the correct segment @@ -209,7 +213,7 @@ double ScanPath::get_power_modifier(double const &time) const std::vector ScanPath::get_segment_list() const { - return _segment_list; + return {&_segment_list[0], &_segment_list[0] + _segment_list_length}; } } // namespace adamantine diff --git a/source/ScanPath.hh b/source/ScanPath.hh index 3b14e232..d270a85f 100644 --- a/source/ScanPath.hh +++ b/source/ScanPath.hh @@ -19,6 +19,8 @@ #include #include +#define MAX_NUMBER_OF_SEGMENTS 100 + namespace adamantine { /** @@ -94,7 +96,9 @@ private: /** * The list of information about each segment in the scan path. */ - std::vector _segment_list; + ScanPathSegment _segment_list[MAX_NUMBER_OF_SEGMENTS]; + + int _segment_list_length = 0; /** * The index of the current segment in the scan path. diff --git a/tests/test_scan_path.cc b/tests/test_scan_path.cc index b9226180..fb3144f7 100644 --- a/tests/test_scan_path.cc +++ b/tests/test_scan_path.cc @@ -22,12 +22,12 @@ class ScanPathTester std::vector get_segment_format_list() { ScanPath scan_path("scan_path.txt", "segment"); - return scan_path._segment_list; + return scan_path.get_segment_list(); }; std::vector get_event_series_format_list() { ScanPath scan_path("scan_path_event_series.inp", "event_series"); - return scan_path._segment_list; + return scan_path.get_segment_list(); }; }; From 9e31ea3a04e4d1800ebec6bcdde52be74adbc7e0 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Tue, 7 May 2024 15:53:34 -0400 Subject: [PATCH 03/30] Store ScanPathSegments outside of ScanPath --- source/CubeHeatSource.cc | 28 +++--- source/CubeHeatSource.hh | 4 +- source/DataAssimilator.hh | 2 +- source/ElectronBeamHeatSource.cc | 24 +++-- source/ElectronBeamHeatSource.hh | 7 +- source/GoldakHeatSource.cc | 25 +++-- source/GoldakHeatSource.hh | 7 +- source/HeatSource.hh | 29 +++--- source/HeatSources.hh | 126 +++++++++++++++++++------- source/MaterialProperty.hh | 2 +- source/ScanPath.cc | 73 +++++++++------ source/ScanPath.hh | 32 ++++--- source/ThermalPhysicsInterface.hh | 2 +- source/material_deposition.cc | 2 +- source/material_deposition.hh | 5 +- tests/test_heat_source.cc | 42 +++++++-- tests/test_implicit_operator.cc | 7 +- tests/test_material_deposition.cc | 36 +++++++- tests/test_post_processor.cc | 7 +- tests/test_scan_path.cc | 15 ++- tests/test_thermal_operator.cc | 47 +++------- tests/test_thermal_operator_device.cc | 7 +- 22 files changed, 327 insertions(+), 202 deletions(-) diff --git a/source/CubeHeatSource.cc b/source/CubeHeatSource.cc index 35614add..d74689dd 100644 --- a/source/CubeHeatSource.cc +++ b/source/CubeHeatSource.cc @@ -9,11 +9,14 @@ #include #include +#include + namespace adamantine { -template -CubeHeatSource::CubeHeatSource(boost::property_tree::ptree const &database) - : HeatSource() +template +CubeHeatSource::CubeHeatSource( + boost::property_tree::ptree const &database) + : HeatSource() { _start_time = database.get("start_time"); _end_time = database.get("end_time"); @@ -29,15 +32,16 @@ CubeHeatSource::CubeHeatSource(boost::property_tree::ptree const &database) } } -template -void CubeHeatSource::update_time(double time) +template +void CubeHeatSource::update_time(double time) { _source_on = ((time > _start_time) && (time < _end_time)); } -template -double CubeHeatSource::value(dealii::Point const &point, - double const /*height*/) const +template +double +CubeHeatSource::value(dealii::Point const &point, + double const /*height*/) const { if (_source_on) { @@ -58,12 +62,14 @@ double CubeHeatSource::value(dealii::Point const &point, return 0.; } -template -double CubeHeatSource::get_current_height(double const /*time*/) const +template +double CubeHeatSource::get_current_height( + double const /*time*/) const { return _max_point[axis::z]; } } // namespace adamantine -INSTANTIATE_DIM(CubeHeatSource) +INSTANTIATE_DIM_DEVICE(CubeHeatSource) +INSTANTIATE_DIM_HOST(CubeHeatSource) diff --git a/source/CubeHeatSource.hh b/source/CubeHeatSource.hh index e6191d81..a496b405 100644 --- a/source/CubeHeatSource.hh +++ b/source/CubeHeatSource.hh @@ -16,8 +16,8 @@ namespace adamantine * Cube heat source. This source does not represent a physical source, it is * used for verification purpose. */ -template -class CubeHeatSource final : public HeatSource +template +class CubeHeatSource final : public HeatSource { public: /** diff --git a/source/DataAssimilator.hh b/source/DataAssimilator.hh index b2b9a746..9fcb494f 100644 --- a/source/DataAssimilator.hh +++ b/source/DataAssimilator.hh @@ -14,7 +14,7 @@ #include #include #include -#include +// #include #include #include #include diff --git a/source/ElectronBeamHeatSource.cc b/source/ElectronBeamHeatSource.cc index 8f7114a6..6236bbdc 100644 --- a/source/ElectronBeamHeatSource.cc +++ b/source/ElectronBeamHeatSource.cc @@ -9,18 +9,21 @@ #include #include +#include + namespace adamantine { -template -ElectronBeamHeatSource::ElectronBeamHeatSource( - boost::property_tree::ptree const &database) - : HeatSource(database) +template +ElectronBeamHeatSource::ElectronBeamHeatSource( + BeamHeatSourceProperties const &beam, + ScanPath const &scan_path) + : HeatSource(beam, scan_path) { } -template -void ElectronBeamHeatSource::update_time(double time) +template +void ElectronBeamHeatSource::update_time(double time) { static const double log_01 = std::log(0.1); _beam_center = this->_scan_path.value(time); @@ -31,9 +34,9 @@ void ElectronBeamHeatSource::update_time(double time) (dealii::numbers::PI * this->_beam.radius_squared * this->_beam.depth); } -template -double ElectronBeamHeatSource::value(dealii::Point const &point, - double const height) const +template +double ElectronBeamHeatSource::value( + dealii::Point const &point, double const height) const { double const z = point[axis::z] - height; if ((z + this->_beam.depth) < 0.) @@ -65,4 +68,5 @@ double ElectronBeamHeatSource::value(dealii::Point const &point, } } // namespace adamantine -INSTANTIATE_DIM(ElectronBeamHeatSource) +INSTANTIATE_DIM_DEVICE(ElectronBeamHeatSource) +INSTANTIATE_DIM_HOST(ElectronBeamHeatSource) diff --git a/source/ElectronBeamHeatSource.hh b/source/ElectronBeamHeatSource.hh index 70892a3e..351f4432 100644 --- a/source/ElectronBeamHeatSource.hh +++ b/source/ElectronBeamHeatSource.hh @@ -17,8 +17,8 @@ namespace adamantine * The form of the heat source model is taken from the following reference: * Raghavan et al, Acta Materilia, 112, 2016, pp 303-314. */ -template -class ElectronBeamHeatSource final : public HeatSource +template +class ElectronBeamHeatSource final : public HeatSource { public: /** @@ -31,7 +31,8 @@ public: * - input_file: name of the file that contains the scan path * segments */ - ElectronBeamHeatSource(boost::property_tree::ptree const &database); + ElectronBeamHeatSource(BeamHeatSourceProperties const &beam, + ScanPath const &scan_path); /** * Set the time variable. diff --git a/source/GoldakHeatSource.cc b/source/GoldakHeatSource.cc index e1faae65..acb5fc1b 100644 --- a/source/GoldakHeatSource.cc +++ b/source/GoldakHeatSource.cc @@ -9,18 +9,21 @@ #include #include +#include + namespace adamantine { -template -GoldakHeatSource::GoldakHeatSource( - boost::property_tree::ptree const &database) - : HeatSource(database) +template +GoldakHeatSource::GoldakHeatSource( + BeamHeatSourceProperties const &beam, + ScanPath const &scan_path) + : HeatSource(beam, scan_path) { } -template -void GoldakHeatSource::update_time(double time) +template +void GoldakHeatSource::update_time(double time) { static const double _pi_over_3_to_1p5 = std::pow(dealii::numbers::PI / 3.0, 1.5); @@ -32,9 +35,10 @@ void GoldakHeatSource::update_time(double time) (this->_beam.radius_squared * this->_beam.depth * _pi_over_3_to_1p5); } -template -double GoldakHeatSource::value(dealii::Point const &point, - double const height) const +template +double +GoldakHeatSource::value(dealii::Point const &point, + double const height) const { double const z = point[axis::z] - height; if ((z + this->_beam.depth) < 0.) @@ -61,4 +65,5 @@ double GoldakHeatSource::value(dealii::Point const &point, } } // namespace adamantine -INSTANTIATE_DIM(GoldakHeatSource) +INSTANTIATE_DIM_DEVICE(GoldakHeatSource) +INSTANTIATE_DIM_HOST(GoldakHeatSource) diff --git a/source/GoldakHeatSource.hh b/source/GoldakHeatSource.hh index 90a94928..76f48543 100644 --- a/source/GoldakHeatSource.hh +++ b/source/GoldakHeatSource.hh @@ -17,8 +17,8 @@ namespace adamantine * The form of the heat source model is taken from the following reference: * Coleman et al, Journal of Heat Transfer, (in press, 2020). */ -template -class GoldakHeatSource final : public HeatSource +template +class GoldakHeatSource final : public HeatSource { public: /** @@ -31,7 +31,8 @@ public: * - input_file: name of the file that contains the scan path * segments */ - GoldakHeatSource(boost::property_tree::ptree const &database); + GoldakHeatSource(BeamHeatSourceProperties const &beam, + ScanPath const &scan_path); /** * Set the time variable. diff --git a/source/HeatSource.hh b/source/HeatSource.hh index 715d73f4..4abe4f39 100644 --- a/source/HeatSource.hh +++ b/source/HeatSource.hh @@ -29,7 +29,7 @@ namespace adamantine * of the part, and the second component is the thickness. That is, the last two * components are swapped between the two coordinate systems. */ -template +template class HeatSource { public: @@ -49,12 +49,9 @@ public: * - input_file: name of the file that contains the scan path * segments */ - HeatSource(boost::property_tree::ptree const &database) - : _beam(database), - // PropertyTreeInput sources.beam_X.scan_path_file - // PropertyTreeInput sources.beam_X.scan_path_format - _scan_path(database.get("scan_path_file"), - database.get("scan_path_file_format")) + HeatSource(BeamHeatSourceProperties const &beam, + ScanPath const &scan_path) + : _beam(beam), _scan_path(scan_path) { } @@ -77,7 +74,7 @@ public: /** * Return the scan path for the heat source. */ - virtual ScanPath const &get_scan_path() const; + virtual ScanPath const &get_scan_path() const; /** * Compute the current height of the where the heat source meets the material @@ -100,23 +97,25 @@ protected: /** * The scan path for the heat source. */ - ScanPath _scan_path; + ScanPath _scan_path; }; -template -inline ScanPath const &HeatSource::get_scan_path() const +template +inline ScanPath const & +HeatSource::get_scan_path() const { return _scan_path; } -template -inline double HeatSource::get_current_height(double const time) const +template +inline double +HeatSource::get_current_height(double const time) const { return _scan_path.value(time)[2]; } -template -inline void HeatSource::set_beam_properties( +template +inline void HeatSource::set_beam_properties( boost::property_tree::ptree const &database) { _beam.set_from_database(database); diff --git a/source/HeatSources.hh b/source/HeatSources.hh index 182cefe4..344bcae4 100644 --- a/source/HeatSources.hh +++ b/source/HeatSources.hh @@ -31,20 +31,6 @@ public: */ HeatSources(boost::property_tree::ptree const &source_database); - HeatSources( - Kokkos::View *, - typename MemorySpace::kokkos_space> - electron_beam_heat_sources, - Kokkos::View *, typename MemorySpace::kokkos_space> - cube_heat_sources, - Kokkos::View *, typename MemorySpace::kokkos_space> - goldak_heat_sources) - : _electron_beam_heat_sources(electron_beam_heat_sources), - _cube_heat_sources(cube_heat_sources), - _goldak_heat_sources(goldak_heat_sources) - { - } - HeatSources copy_to_host() const { return {Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, @@ -77,7 +63,7 @@ public: /** * Return the scan paths for the heat source. */ - std::vector get_scan_paths() const; + std::vector> get_scan_paths() const; /** * (Re)sets the BeamHeatSourceProperties member variable, necessary if the @@ -93,13 +79,19 @@ public: double get_current_height(double time) const; private: - Kokkos::View *, + Kokkos::View *, typename MemorySpace::kokkos_space> _electron_beam_heat_sources; - Kokkos::View *, typename MemorySpace::kokkos_space> + Kokkos::View *, + typename MemorySpace::kokkos_space> _cube_heat_sources; - Kokkos::View *, typename MemorySpace::kokkos_space> + Kokkos::View *, + typename MemorySpace::kokkos_space> _goldak_heat_sources; + Kokkos::View + _electron_beam_scan_path_segments; + Kokkos::View + _goldak_scan_path_segments; }; template @@ -107,21 +99,30 @@ HeatSources::HeatSources( boost::property_tree::ptree const &source_database) { unsigned int const n_beams = source_database.get("n_beams"); - std::vector> electron_beam_heat_sources; - std::vector> cube_heat_sources; - std::vector> goldak_heat_sources; + std::vector goldak_beams; + std::vector electron_beam_beams; + std::vector> goldak_scan_path_segments; + std::vector> electron_beam_scan_path_segments; + std::vector> cube_heat_sources; + for (unsigned int i = 0; i < n_beams; ++i) { boost::property_tree::ptree const &beam_database = source_database.get_child("beam_" + std::to_string(i)); std::string type = beam_database.get("type"); + std::vector scan_path_segments = + ScanPath::extract_scan_paths( + beam_database.get("scan_path_file"), + beam_database.get("scan_path_file_format")); if (type == "goldak") { - goldak_heat_sources.emplace_back(beam_database); + goldak_beams.emplace_back(beam_database); + goldak_scan_path_segments.push_back(scan_path_segments); } else if (type == "electron_beam") { - electron_beam_heat_sources.emplace_back(beam_database); + electron_beam_beams.emplace_back(beam_database); + electron_beam_scan_path_segments.push_back(scan_path_segments); } else if (type == "cube") { @@ -134,6 +135,65 @@ HeatSources::HeatSources( "' not recognized."); } } + + std::vector> goldak_heat_sources; + { + std::vector goldak_scan_path_segment_start( + goldak_scan_path_segments.size() + 1); + for (unsigned int i = 1; i < goldak_scan_path_segments.size() + 1; ++i) + goldak_scan_path_segment_start[i] = + goldak_scan_path_segment_start[i - 1] + + goldak_scan_path_segments[i - 1].size(); + _goldak_scan_path_segments = decltype(_goldak_scan_path_segments)( + Kokkos::view_alloc(Kokkos::WithoutInitializing, + "goldak_scan_path_segments"), + goldak_scan_path_segment_start.back()); + for (unsigned int i = 0; i < goldak_scan_path_segments.size(); ++i) + { + auto goldak_scan_path_segment = + Kokkos::subview(_goldak_scan_path_segments, + Kokkos::pair(goldak_scan_path_segment_start[i], + goldak_scan_path_segment_start[i + 1])); + Kokkos::deep_copy(goldak_scan_path_segment, + Kokkos::View( + goldak_scan_path_segments[i].data(), + goldak_scan_path_segments[i].size())); + goldak_heat_sources.emplace_back( + goldak_beams[i], ScanPath(goldak_scan_path_segment)); + } + } + + std::vector> + electron_beam_heat_sources; + { + std::vector electron_beam_scan_path_segment_start( + electron_beam_scan_path_segments.size() + 1); + for (unsigned int i = 1; i < electron_beam_scan_path_segments.size() + 1; + ++i) + electron_beam_scan_path_segment_start[i] = + electron_beam_scan_path_segment_start[i - 1] + + electron_beam_scan_path_segments[i - 1].size(); + _electron_beam_scan_path_segments = + decltype(_electron_beam_scan_path_segments)( + Kokkos::view_alloc(Kokkos::WithoutInitializing, + "electron_beam_scan_path_segments"), + electron_beam_scan_path_segment_start.back()); + for (unsigned int i = 0; i < electron_beam_scan_path_segments.size(); ++i) + { + auto electron_beam_scan_path_segment = Kokkos::subview( + _electron_beam_scan_path_segments, + Kokkos::pair(electron_beam_scan_path_segment_start[i], + electron_beam_scan_path_segment_start[i + 1])); + Kokkos::deep_copy(electron_beam_scan_path_segment, + Kokkos::View( + electron_beam_scan_path_segments[i].data(), + electron_beam_scan_path_segments[i].size())); + electron_beam_heat_sources.emplace_back( + electron_beam_beams[i], + ScanPath(electron_beam_scan_path_segment)); + } + } + _goldak_heat_sources = decltype(_goldak_heat_sources)( Kokkos::view_alloc(Kokkos::WithoutInitializing, "goldak_heat_sources"), goldak_heat_sources.size()); @@ -146,16 +206,17 @@ HeatSources::HeatSources( cube_heat_sources.size()); Kokkos::deep_copy( _goldak_heat_sources, - Kokkos::View *, Kokkos::HostSpace>( + Kokkos::View *, Kokkos::HostSpace>( goldak_heat_sources.data(), goldak_heat_sources.size())); Kokkos::deep_copy( _electron_beam_heat_sources, - Kokkos::View *, Kokkos::HostSpace>( - electron_beam_heat_sources.data(), - electron_beam_heat_sources.size())); - Kokkos::deep_copy(_cube_heat_sources, - Kokkos::View *, Kokkos::HostSpace>( - cube_heat_sources.data(), cube_heat_sources.size())); + Kokkos::View *, + Kokkos::HostSpace>(electron_beam_heat_sources.data(), + electron_beam_heat_sources.size())); + Kokkos::deep_copy( + _cube_heat_sources, + Kokkos::View *, Kokkos::HostSpace>( + cube_heat_sources.data(), cube_heat_sources.size())); } template @@ -201,9 +262,10 @@ HeatSources::max_value(dealii::Point const &point, } template -std::vector HeatSources::get_scan_paths() const +std::vector> +HeatSources::get_scan_paths() const { - std::vector scan_paths; + std::vector> scan_paths; for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) scan_paths.push_back(_electron_beam_heat_sources(i).get_scan_path()); for (unsigned int i = 0; i < _cube_heat_sources.size(); ++i) diff --git a/source/MaterialProperty.hh b/source/MaterialProperty.hh index 525fdedd..153a4c9c 100644 --- a/source/MaterialProperty.hh +++ b/source/MaterialProperty.hh @@ -22,7 +22,7 @@ #include #include #include -#include +// #include #include diff --git a/source/ScanPath.cc b/source/ScanPath.cc index fffe22fb..274063b6 100644 --- a/source/ScanPath.cc +++ b/source/ScanPath.cc @@ -8,11 +8,17 @@ #include #include +#include + #include namespace adamantine { -ScanPath::ScanPath(std::string scan_path_file, std::string file_format) + +template +std::vector +ScanPath::extract_scan_paths(std::string scan_path_file, + std::string file_format) { // Parse the scan path wait_for_file(scan_path_file, @@ -20,20 +26,26 @@ ScanPath::ScanPath(std::string scan_path_file, std::string file_format) if (file_format == "segment") { - load_segment_scan_path(scan_path_file); + return load_segment_scan_path(scan_path_file); } else if (file_format == "event_series") { - load_event_series_scan_path(scan_path_file); + return load_event_series_scan_path(scan_path_file); } else { ASSERT_THROW(false, "Error: Format of scan path file not recognized."); } + + return {}; } -void ScanPath::load_segment_scan_path(std::string scan_path_file) +template +std::vector +ScanPath::load_segment_scan_path(std::string scan_path_file) { + std::vector segment_list; + std::ifstream file; file.open(scan_path_file); std::string line; @@ -60,7 +72,7 @@ void ScanPath::load_segment_scan_path(std::string scan_path_file) { // Check to make sure the segment isn't the first, if it is, throw an // exception (the first segment must be a point in the spec). - ASSERT_THROW(_segment_list_length > 0, + ASSERT_THROW(segment_list.size() > 0, "Error: Scan paths must begin with a 'point' segment."); } else if (split_line[0] == "1") @@ -85,10 +97,10 @@ void ScanPath::load_segment_scan_path(std::string scan_path_file) // Set the velocity and end time if (segment_type == ScanPathSegmentType::point) { - if (_segment_list_length > 0) + if (segment_list.size() > 0) { - segment.end_time = _segment_list[_segment_list_length - 1].end_time + - std::stod(split_line[5]); + segment.end_time = + segment_list.back().end_time + std::stod(split_line[5]); } else { @@ -98,21 +110,24 @@ void ScanPath::load_segment_scan_path(std::string scan_path_file) else { double velocity = std::stod(split_line[5]); - double line_length = segment.end_point.distance( - _segment_list[_segment_list_length - 1].end_point); - segment.end_time = _segment_list[_segment_list_length - 1].end_time + - std::abs(line_length / velocity); + double line_length = + segment.end_point.distance(segment_list.back().end_point); + segment.end_time = + segment_list.back().end_time + std::abs(line_length / velocity); } - if (_segment_list_length == MAX_NUMBER_OF_SEGMENTS) - Kokkos::abort("too many segmnets"); - _segment_list[_segment_list_length++] = segment; + segment_list.push_back(segment); data_index++; } file.close(); + return segment_list; } -void ScanPath::load_event_series_scan_path(std::string scan_path_file) +template +std::vector +ScanPath::load_event_series_scan_path(std::string scan_path_file) { + std::vector segment_list; + std::ifstream file; file.open(scan_path_file); std::string line; @@ -140,13 +155,13 @@ void ScanPath::load_event_series_scan_path(std::string scan_path_file) segment.power_modifier = last_power; last_power = std::stod(split_line[4]); - if (_segment_list_length == MAX_NUMBER_OF_SEGMENTS) - Kokkos::abort("too many segmnets"); - _segment_list[_segment_list_length++] = segment; + segment_list.push_back(segment); } + return segment_list; } -void ScanPath::update_current_segment_info( +template +void ScanPath::update_current_segment_info( double time, dealii::Point<3> &segment_start_point, double &segment_start_time) const { @@ -169,11 +184,12 @@ void ScanPath::update_current_segment_info( } } -dealii::Point<3> ScanPath::value(double const &time) const +template +dealii::Point<3> ScanPath::value(double const &time) const { // If the current time is after the scan path data is over, return a point // that is (presumably) out of the domain. - if (time > _segment_list[_segment_list_length - 1].end_time) + if (time > _segment_list[_segment_list.size() - 1].end_time) { dealii::Point<3> out_of_domain_point(std::numeric_limits::lowest(), std::numeric_limits::lowest(), @@ -196,11 +212,12 @@ dealii::Point<3> ScanPath::value(double const &time) const return position; } -double ScanPath::get_power_modifier(double const &time) const +template +double ScanPath::get_power_modifier(double const &time) const { // If the current time is after the scan path data is over, set the power to // zero. - if (time > _segment_list[_segment_list_length - 1].end_time) + if (time > _segment_list[_segment_list.size() - 1].end_time) return 0.0; // Get to the correct segment @@ -211,9 +228,13 @@ double ScanPath::get_power_modifier(double const &time) const return _segment_list[_current_segment].power_modifier; } -std::vector ScanPath::get_segment_list() const +template +std::vector ScanPath::get_segment_list() const { - return {&_segment_list[0], &_segment_list[0] + _segment_list_length}; + return {&_segment_list[0], &_segment_list[0] + _segment_list.size()}; } } // namespace adamantine + +template class adamantine::ScanPath; +template class adamantine::ScanPath; diff --git a/source/ScanPath.hh b/source/ScanPath.hh index d270a85f..9c4ab903 100644 --- a/source/ScanPath.hh +++ b/source/ScanPath.hh @@ -19,8 +19,6 @@ #include #include -#define MAX_NUMBER_OF_SEGMENTS 100 - namespace adamantine { /** @@ -58,6 +56,7 @@ class ScanPathTester; * gives the power modifier for the current segment. It reads in the scan path * from a text file. */ +template class ScanPath { friend class ScanPathTester; @@ -68,13 +67,16 @@ public: */ ScanPath() = default; - /** - * Construtor. - * \param[in] scan_path_file is the name of the text file containing the scan - * path - * \param[in] file_format is the format of the scan path file - */ - ScanPath(std::string scan_path_file, std::string file_format); + ScanPath( + Kokkos::View> + scan_path_segments) + : _segment_list(scan_path_segments) + { + } + + static std::vector + extract_scan_paths(std::string scan_path_file, std::string file_format); /** * Calculates the location of the scan path at a given time for a single @@ -96,9 +98,9 @@ private: /** * The list of information about each segment in the scan path. */ - ScanPathSegment _segment_list[MAX_NUMBER_OF_SEGMENTS]; - - int _segment_list_length = 0; + Kokkos::View> + _segment_list; /** * The index of the current segment in the scan path. @@ -108,12 +110,14 @@ private: /** * Method to load a "segment" scan path file */ - void load_segment_scan_path(std::string scan_path_file); + static std::vector + load_segment_scan_path(std::string scan_path_file); /** * Method to load an "event series" scan path file */ - void load_event_series_scan_path(std::string scan_path_file); + static std::vector + load_event_series_scan_path(std::string scan_path_file); /** * Method to determine the current segment, its start point, and start time. diff --git a/source/ThermalPhysicsInterface.hh b/source/ThermalPhysicsInterface.hh index 4662f206..915a7b02 100644 --- a/source/ThermalPhysicsInterface.hh +++ b/source/ThermalPhysicsInterface.hh @@ -19,7 +19,7 @@ namespace adamantine // Forward declarations class Timer; -template +template class HeatSource; /** diff --git a/source/material_deposition.cc b/source/material_deposition.cc index e128c490..51622214 100644 --- a/source/material_deposition.cc +++ b/source/material_deposition.cc @@ -133,7 +133,7 @@ template std::tuple>, std::vector, std::vector, std::vector> deposition_along_scan_path(boost::property_tree::ptree const &geometry_database, - ScanPath const &scan_path) + ScanPath const &scan_path) { std::tuple>, std::vector, std::vector, std::vector> diff --git a/source/material_deposition.hh b/source/material_deposition.hh index 6e0a71fa..fb37dd40 100644 --- a/source/material_deposition.hh +++ b/source/material_deposition.hh @@ -43,8 +43,9 @@ read_material_deposition(boost::property_tree::ptree const &geometry_database); template std::tuple>, std::vector, std::vector, std::vector> -deposition_along_scan_path(boost::property_tree::ptree const &geometry_database, - ScanPath const &scan_path); +deposition_along_scan_path( + boost::property_tree::ptree const &geometry_database, + ScanPath const &scan_path); /** * Merge a vector of tuple of bounding boxes, deposition times, cosine of * deposition angles, and sine of deposition angles into a diff --git a/tests/test_heat_source.cc b/tests/test_heat_source.cc index a6d6a70e..2ad267cf 100644 --- a/tests/test_heat_source.cc +++ b/tests/test_heat_source.cc @@ -29,8 +29,17 @@ BOOST_AUTO_TEST_CASE(heat_source_value_2d, *utf::tolerance(1e-12)) database.put("max_power", 10.); database.put("scan_path_file", "scan_path.txt"); database.put("scan_path_file_format", "segment"); - GoldakHeatSource<2> goldak_heat_source(database); - ElectronBeamHeatSource<2> eb_heat_source(database); + std::vector scan_path_segments = + ScanPath::extract_scan_paths( + database.get("scan_path_file"), + database.get("scan_path_file_format")); + Kokkos::View scan_paths_segments_view( + scan_path_segments.data(), scan_path_segments.size()); + BeamHeatSourceProperties beam(database); + GoldakHeatSource<2, dealii::MemorySpace::Host> goldak_heat_source( + beam, ScanPath(scan_paths_segments_view)); + ElectronBeamHeatSource<2, dealii::MemorySpace::Host> eb_heat_source( + database, ScanPath(scan_paths_segments_view)); double g_value = 0.0; double eb_value = 0.0; @@ -109,9 +118,18 @@ BOOST_AUTO_TEST_CASE(heat_source_value_3d, *utf::tolerance(1e-12)) database.put("max_power", 10.); database.put("scan_path_file", "scan_path.txt"); database.put("scan_path_file_format", "segment"); - - GoldakHeatSource<3> goldak_heat_source(database); - ElectronBeamHeatSource<3> eb_heat_source(database); + std::vector scan_path_segments = + ScanPath::extract_scan_paths( + database.get("scan_path_file"), + database.get("scan_path_file_format")); + Kokkos::View scan_paths_segments_view( + scan_path_segments.data(), scan_path_segments.size()); + BeamHeatSourceProperties beam(database); + + GoldakHeatSource<3, dealii::MemorySpace::Host> goldak_heat_source( + beam, ScanPath(scan_paths_segments_view)); + ElectronBeamHeatSource<3, dealii::MemorySpace::Host> eb_heat_source( + beam, ScanPath(scan_paths_segments_view)); double g_value = 0.0; double eb_value = 0.0; @@ -178,8 +196,18 @@ BOOST_AUTO_TEST_CASE(heat_source_height, *utf::tolerance(1e-12)) database.put("max_power", 10.); database.put("scan_path_file", "scan_path_layers.txt"); database.put("scan_path_file_format", "segment"); - GoldakHeatSource<2> goldak_heat_source(database); - ElectronBeamHeatSource<2> eb_heat_source(database); + std::vector scan_path_segments = + ScanPath::extract_scan_paths( + database.get("scan_path_file"), + database.get("scan_path_file_format")); + Kokkos::View scan_paths_segments_view( + scan_path_segments.data(), scan_path_segments.size()); + BeamHeatSourceProperties beam(database); + + GoldakHeatSource<2, dealii::MemorySpace::Host> goldak_heat_source( + beam, ScanPath(scan_paths_segments_view)); + ElectronBeamHeatSource<2, dealii::MemorySpace::Host> eb_heat_source( + beam, ScanPath(scan_paths_segments_view)); double g_height = 0.0; double eb_height = 0.0; diff --git a/tests/test_implicit_operator.cc b/tests/test_implicit_operator.cc index 8a9eb33c..6507facd 100644 --- a/tests/test_implicit_operator.cc +++ b/tests/test_implicit_operator.cc @@ -80,13 +80,8 @@ BOOST_AUTO_TEST_CASE(implicit_operator) beam_database.put("max_power", 10.); beam_database.put("scan_path_file", "scan_path.txt"); beam_database.put("scan_path_file_format", "segment"); - Kokkos::View *, Kokkos::HostSpace> - goldak_heat_sources(Kokkos::view_alloc(Kokkos::WithoutInitializing, - "goldak_heat_sources"), - 1); - goldak_heat_sources(0) = adamantine::GoldakHeatSource<2>(beam_database); adamantine::HeatSources heat_sources( - {}, {}, goldak_heat_sources); + beam_database); // Initialize the ThermalOperator auto thermal_operator = std::make_shared< diff --git a/tests/test_material_deposition.cc b/tests/test_material_deposition.cc index c33a69f8..e14f2c69 100644 --- a/tests/test_material_deposition.cc +++ b/tests/test_material_deposition.cc @@ -353,7 +353,14 @@ BOOST_AUTO_TEST_CASE(material_deposition) BOOST_AUTO_TEST_CASE(deposition_from_scan_path_2d, *utf::tolerance(1e-13)) { - adamantine::ScanPath scan_path("scan_path.txt", "segment"); + std::vector scan_path_segments = + adamantine::ScanPath::extract_scan_paths( + "scan_path.txt", "segment"); + Kokkos::View + scan_paths_segments_view(scan_path_segments.data(), + scan_path_segments.size()); + adamantine::ScanPath scan_path( + scan_paths_segments_view); boost::property_tree::ptree database; database.put("deposition_length", 0.0005); @@ -401,7 +408,14 @@ BOOST_AUTO_TEST_CASE(deposition_from_scan_path_2d, *utf::tolerance(1e-13)) BOOST_AUTO_TEST_CASE(deposition_from_scan_path_3d, *utf::tolerance(1e-13)) { - adamantine::ScanPath scan_path("scan_path.txt", "segment"); + std::vector scan_path_segments = + adamantine::ScanPath::extract_scan_paths( + "scan_path.txt", "segment"); + Kokkos::View + scan_paths_segments_view(scan_path_segments.data(), + scan_path_segments.size()); + adamantine::ScanPath scan_path( + scan_paths_segments_view); boost::property_tree::ptree database; database.put("deposition_length", 0.0005); @@ -453,7 +467,14 @@ BOOST_AUTO_TEST_CASE(deposition_from_scan_path_3d, *utf::tolerance(1e-13)) BOOST_AUTO_TEST_CASE(deposition_from_L_scan_path_3d, *utf::tolerance(1e-13)) { - adamantine::ScanPath scan_path("scan_path_L.txt", "segment"); + std::vector scan_path_segments = + adamantine::ScanPath::extract_scan_paths( + "scan_path_L.txt", "segment"); + Kokkos::View + scan_paths_segments_view(scan_path_segments.data(), + scan_path_segments.size()); + adamantine::ScanPath scan_path( + scan_paths_segments_view); boost::property_tree::ptree database; database.put("deposition_length", 0.0005); @@ -539,7 +560,14 @@ BOOST_AUTO_TEST_CASE(deposition_from_L_scan_path_3d, *utf::tolerance(1e-13)) BOOST_AUTO_TEST_CASE(deposition_from_diagonal_scan_path_3d, *utf::tolerance(1e-10)) { - adamantine::ScanPath scan_path("scan_path_diagonal.txt", "segment"); + std::vector scan_path_segments = + adamantine::ScanPath::extract_scan_paths( + "scan_path_diagonal.txt", "segment"); + Kokkos::View + scan_paths_segments_view(scan_path_segments.data(), + scan_path_segments.size()); + adamantine::ScanPath scan_path( + scan_paths_segments_view); boost::property_tree::ptree database; database.put("deposition_length", 0.0005); diff --git a/tests/test_post_processor.cc b/tests/test_post_processor.cc index 15a570fd..a7bbb7f5 100644 --- a/tests/test_post_processor.cc +++ b/tests/test_post_processor.cc @@ -79,13 +79,8 @@ BOOST_AUTO_TEST_CASE(thermal_post_processor) beam_database.put("max_power", 10.); beam_database.put("scan_path_file", "scan_path.txt"); beam_database.put("scan_path_file_format", "segment"); - Kokkos::View *, Kokkos::HostSpace> - goldak_heat_sources(Kokkos::view_alloc(Kokkos::WithoutInitializing, - "goldak_heat_sources"), - 1); - goldak_heat_sources(0) = adamantine::GoldakHeatSource<2>(beam_database); adamantine::HeatSources heat_sources( - {}, {}, goldak_heat_sources); + beam_database); // Initialize the ThermalOperator adamantine::ThermalOperator<2, false, 0, 2, adamantine::SolidLiquidPowder, diff --git a/tests/test_scan_path.cc b/tests/test_scan_path.cc index fb3144f7..31076c06 100644 --- a/tests/test_scan_path.cc +++ b/tests/test_scan_path.cc @@ -21,13 +21,13 @@ class ScanPathTester public: std::vector get_segment_format_list() { - ScanPath scan_path("scan_path.txt", "segment"); - return scan_path.get_segment_list(); + return ScanPath::extract_scan_paths( + "scan_path.txt", "segment"); }; std::vector get_event_series_format_list() { - ScanPath scan_path("scan_path_event_series.inp", "event_series"); - return scan_path.get_segment_list(); + return ScanPath::extract_scan_paths( + "scan_path_event_series.inp", "event_series"); }; }; @@ -75,7 +75,12 @@ BOOST_AUTO_TEST_CASE(scan_path, *utf::tolerance(1e-12)) BOOST_AUTO_TEST_CASE(scan_path_location, *utf::tolerance(1e-10)) { - ScanPath scan_path("scan_path.txt", "segment"); + std::vector scan_path_segments = + ScanPath::extract_scan_paths("scan_path.txt", + "segment"); + Kokkos::View scan_paths_segments_view( + scan_path_segments.data(), scan_path_segments.size()); + ScanPath scan_path(scan_paths_segments_view); double time = 1.0e-7; dealii::Point<3> p1 = scan_path.value(time); diff --git a/tests/test_thermal_operator.cc b/tests/test_thermal_operator.cc index 4e8448f6..0fe85bc2 100644 --- a/tests/test_thermal_operator.cc +++ b/tests/test_thermal_operator.cc @@ -94,13 +94,8 @@ BOOST_AUTO_TEST_CASE(thermal_operator, *utf::tolerance(1e-15)) beam_database.put("max_power", 10.); beam_database.put("scan_path_file", "scan_path.txt"); beam_database.put("scan_path_file_format", "segment"); - Kokkos::View *, Kokkos::HostSpace> - goldak_heat_sources(Kokkos::view_alloc(Kokkos::WithoutInitializing, - "goldak_heat_sources"), - 1); - goldak_heat_sources(0) = adamantine::GoldakHeatSource<2>(beam_database); adamantine::HeatSources heat_sources( - {}, {}, goldak_heat_sources); + beam_database); // Initialize the ThermalOperator adamantine::ThermalOperator<2, false, 1, 2, adamantine::SolidLiquidPowder, @@ -196,19 +191,14 @@ BOOST_AUTO_TEST_CASE(spmv, *utf::tolerance(1e-12)) // Create the heat sources boost::property_tree::ptree beam_database; - beam_database.put("depth", 0.1); - beam_database.put("absorption_efficiency", 0.1); - beam_database.put("diameter", 1.0); - beam_database.put("max_power", 10.); - beam_database.put("scan_path_file", "scan_path.txt"); - beam_database.put("scan_path_file_format", "segment"); - Kokkos::View *, Kokkos::HostSpace> - goldak_heat_sources(Kokkos::view_alloc(Kokkos::WithoutInitializing, - "goldak_heat_sources"), - 1); - goldak_heat_sources(0) = adamantine::GoldakHeatSource<2>(beam_database); + beam_database.put("sources.beam_0.depth", 0.1); + beam_database.put("sources.beam_0.absorption_efficiency", 0.1); + beam_database.put("sources.beam_0.diameter", 1.0); + beam_database.put("sources.beam_0.max_power", 10.); + beam_database.put("sources.beam_0.scan_path_file", "scan_path.txt"); + beam_database.put("sources.beam_0.scan_path_file_format", "segment"); adamantine::HeatSources heat_sources( - {}, {}, goldak_heat_sources); + beam_database); // Initialize the ThermalOperator adamantine::ThermalOperator<2, false, 2, 2, adamantine::SolidLiquidPowder, @@ -314,13 +304,8 @@ BOOST_AUTO_TEST_CASE(spmv_anisotropic, *utf::tolerance(1e-12)) beam_database.put("max_power", 10.); beam_database.put("scan_path_file", "scan_path.txt"); beam_database.put("scan_path_file_format", "segment"); - Kokkos::View *, Kokkos::HostSpace> - goldak_heat_sources(Kokkos::view_alloc(Kokkos::WithoutInitializing, - "goldak_heat_sources"), - 1); - goldak_heat_sources(0) = adamantine::GoldakHeatSource<2>(beam_database); adamantine::HeatSources heat_sources( - {}, {}, goldak_heat_sources); + beam_database); // Initialize the ThermalOperator adamantine::ThermalOperator<2, false, 2, 2, adamantine::SolidLiquidPowder, @@ -624,13 +609,8 @@ BOOST_AUTO_TEST_CASE(spmv_rad, *utf::tolerance(1e-12)) beam_database.put("max_power", 10.); beam_database.put("scan_path_file", "scan_path.txt"); beam_database.put("scan_path_file_format", "segment"); - Kokkos::View *, Kokkos::HostSpace> - goldak_heat_sources(Kokkos::view_alloc(Kokkos::WithoutInitializing, - "goldak_heat_sources"), - 1); - goldak_heat_sources(0) = adamantine::GoldakHeatSource<2>(beam_database); adamantine::HeatSources heat_sources( - {}, {}, goldak_heat_sources); + beam_database); // Initialize the ThermalOperator adamantine::ThermalOperator<2, false, 1, 2, adamantine::SolidLiquidPowder, @@ -811,13 +791,8 @@ BOOST_AUTO_TEST_CASE(spmv_conv, *utf::tolerance(1e-12)) beam_database.put("max_power", 10.); beam_database.put("scan_path_file", "scan_path.txt"); beam_database.put("scan_path_file_format", "segment"); - Kokkos::View *, Kokkos::HostSpace> - goldak_heat_sources(Kokkos::view_alloc(Kokkos::WithoutInitializing, - "goldak_heat_sources"), - 1); - goldak_heat_sources(0) = adamantine::GoldakHeatSource<2>(beam_database); adamantine::HeatSources heat_sources( - {}, {}, goldak_heat_sources); + beam_database); // Initialize the ThermalOperator adamantine::ThermalOperator<2, false, 1, 2, adamantine::SolidLiquidPowder, diff --git a/tests/test_thermal_operator_device.cc b/tests/test_thermal_operator_device.cc index 36901f80..0093d83d 100644 --- a/tests/test_thermal_operator_device.cc +++ b/tests/test_thermal_operator_device.cc @@ -285,13 +285,8 @@ BOOST_AUTO_TEST_CASE(mf_spmv, *utf::tolerance(1.5e-12)) beam_database.put("max_power", 10.); beam_database.put("scan_path_file", "scan_path.txt"); beam_database.put("scan_path_file_format", "segment"); - Kokkos::View *, Kokkos::HostSpace> - goldak_heat_sources(Kokkos::view_alloc(Kokkos::WithoutInitializing, - "goldak_heat_sources"), - 1); - goldak_heat_sources(0) = adamantine::GoldakHeatSource<2>(beam_database); adamantine::HeatSources heat_sources( - {}, {}, goldak_heat_sources); + beam_database); // Initialize the ThermalOperator adamantine::ThermalOperatorDevice<2, false, 4, 2, From 5fdff90fe54299d4222dde3dbb790d938d2d8bf0 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Wed, 8 May 2024 11:18:28 -0400 Subject: [PATCH 04/30] Refactor HeatSources to store std::vectors of ScanPathSegments --- source/CubeHeatSource.cc | 26 ++- source/CubeHeatSource.hh | 7 +- source/HeatSource.hh | 2 + source/HeatSources.hh | 219 +++++++++++++++++--------- tests/test_implicit_operator.cc | 14 +- tests/test_post_processor.cc | 14 +- tests/test_thermal_operator.cc | 70 ++++---- tests/test_thermal_operator_device.cc | 14 +- 8 files changed, 230 insertions(+), 136 deletions(-) diff --git a/source/CubeHeatSource.cc b/source/CubeHeatSource.cc index d74689dd..469b98f3 100644 --- a/source/CubeHeatSource.cc +++ b/source/CubeHeatSource.cc @@ -13,10 +13,9 @@ namespace adamantine { -template -CubeHeatSource::CubeHeatSource( - boost::property_tree::ptree const &database) - : HeatSource() +template +CubeHeatSource::CubeHeatSource(boost::property_tree::ptree const &database) + : HeatSource() { _start_time = database.get("start_time"); _end_time = database.get("end_time"); @@ -32,16 +31,15 @@ CubeHeatSource::CubeHeatSource( } } -template -void CubeHeatSource::update_time(double time) +template +void CubeHeatSource::update_time(double time) { _source_on = ((time > _start_time) && (time < _end_time)); } -template -double -CubeHeatSource::value(dealii::Point const &point, - double const /*height*/) const +template +double CubeHeatSource::value(dealii::Point const &point, + double const /*height*/) const { if (_source_on) { @@ -62,14 +60,12 @@ CubeHeatSource::value(dealii::Point const &point, return 0.; } -template -double CubeHeatSource::get_current_height( - double const /*time*/) const +template +double CubeHeatSource::get_current_height(double const /*time*/) const { return _max_point[axis::z]; } } // namespace adamantine -INSTANTIATE_DIM_DEVICE(CubeHeatSource) -INSTANTIATE_DIM_HOST(CubeHeatSource) +INSTANTIATE_DIM(CubeHeatSource) diff --git a/source/CubeHeatSource.hh b/source/CubeHeatSource.hh index a496b405..67f0b84f 100644 --- a/source/CubeHeatSource.hh +++ b/source/CubeHeatSource.hh @@ -10,14 +10,17 @@ #include +#include + namespace adamantine { /** * Cube heat source. This source does not represent a physical source, it is * used for verification purpose. */ -template -class CubeHeatSource final : public HeatSource +template +class CubeHeatSource final + : public HeatSource { public: /** diff --git a/source/HeatSource.hh b/source/HeatSource.hh index 4abe4f39..e69bd5d8 100644 --- a/source/HeatSource.hh +++ b/source/HeatSource.hh @@ -88,6 +88,8 @@ public: */ virtual void set_beam_properties(boost::property_tree::ptree const &database); + BeamHeatSourceProperties get_beam_properties() const { return _beam; } + protected: /** * Structure of the physical properties of the beam heat source. diff --git a/source/HeatSources.hh b/source/HeatSources.hh index 344bcae4..56ee12a3 100644 --- a/source/HeatSources.hh +++ b/source/HeatSources.hh @@ -31,14 +31,115 @@ public: */ HeatSources(boost::property_tree::ptree const &source_database); + HeatSources( + Kokkos::View *, + typename MemorySpace::kokkos_space> + electron_beam_heat_sources, + Kokkos::View *, typename MemorySpace::kokkos_space> + cube_heat_sources, + Kokkos::View *, + typename MemorySpace::kokkos_space> + goldak_heat_sources, + std::vector< + Kokkos::View> + electron_beam_scan_path_segments, + std::vector< + Kokkos::View> + goldak_scan_path_segments) + : _electron_beam_heat_sources(electron_beam_heat_sources), + _cube_heat_sources(cube_heat_sources), + _goldak_heat_sources(goldak_heat_sources), + _electron_beam_scan_path_segments(electron_beam_scan_path_segments), + _goldak_scan_path_segments(goldak_scan_path_segments) + { + } + HeatSources copy_to_host() const { - return {Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, - _electron_beam_heat_sources), - Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, - _cube_heat_sources), - Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, - _goldak_heat_sources)}; + if constexpr (std::is_same_v) + return *this; + else + { + std::vector> + host_electron_beam_scan_path_segments( + _electron_beam_scan_path_segments.size()); + std::vector> + host_goldak_scan_path_segments(_goldak_scan_path_segments.size()); + + for (unsigned int i = 0; i < _electron_beam_scan_path_segments.size(); + ++i) + host_electron_beam_scan_path_segments[i] = + Kokkos::create_mirror_view_and_copy( + Kokkos::HostSpace{}, _electron_beam_scan_path_segments[i]); + + for (unsigned int i = 0; i < _goldak_scan_path_segments.size(); ++i) + host_goldak_scan_path_segments[i] = Kokkos::create_mirror_view_and_copy( + Kokkos::HostSpace{}, _goldak_scan_path_segments[i]); + + auto host_copy_electron_beam_heat_sources = + Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, + _electron_beam_heat_sources); + auto host_copy_goldak_heat_sources = Kokkos::create_mirror_view_and_copy( + Kokkos::HostSpace{}, _goldak_heat_sources); + + std::vector goldak_beams( + _goldak_heat_sources.size()); + std::vector electron_beam_beams( + _electron_beam_heat_sources.size()); + + for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) + goldak_beams.push_back( + host_copy_goldak_heat_sources(i).get_beam_properties()); + for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) + electron_beam_beams.push_back( + host_copy_electron_beam_heat_sources(i).get_beam_properties()); + + Kokkos::View *, + Kokkos::HostSpace> + host_electron_beam_heat_sources( + Kokkos::view_alloc(Kokkos::WithoutInitializing, + "electron_beam_heat_sources"), + _electron_beam_heat_sources.size()); + Kokkos::View *, + Kokkos::HostSpace> + host_goldak_heat_sources( + Kokkos::view_alloc(Kokkos::WithoutInitializing, + "goldak_heat_sources"), + _goldak_heat_sources.size()); + + std::vector> + goldak_heat_source_vector; + for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) + goldak_heat_source_vector.emplace_back( + goldak_beams[i], ScanPath( + host_goldak_scan_path_segments[i])); + Kokkos::deep_copy( + host_goldak_heat_sources, + Kokkos::View *, + Kokkos::HostSpace>(goldak_heat_source_vector.data(), + goldak_heat_source_vector.size())); + + std::vector> + electron_beam_heat_source_vector; + for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) + electron_beam_heat_source_vector.emplace_back( + electron_beam_beams[i], + ScanPath( + host_electron_beam_scan_path_segments[i])); + Kokkos::deep_copy( + host_electron_beam_heat_sources, + Kokkos::View *, + Kokkos::HostSpace>( + electron_beam_heat_source_vector.data(), + electron_beam_heat_source_vector.size())); + + auto host_cube_heat_sources = Kokkos::create_mirror_view_and_copy( + Kokkos::HostSpace{}, _cube_heat_sources); + + return {host_electron_beam_heat_sources, host_cube_heat_sources, + host_goldak_heat_sources, host_electron_beam_scan_path_segments, + host_goldak_scan_path_segments}; + } } /** @@ -82,15 +183,16 @@ private: Kokkos::View *, typename MemorySpace::kokkos_space> _electron_beam_heat_sources; - Kokkos::View *, - typename MemorySpace::kokkos_space> + Kokkos::View *, typename MemorySpace::kokkos_space> _cube_heat_sources; Kokkos::View *, typename MemorySpace::kokkos_space> _goldak_heat_sources; - Kokkos::View + std::vector< + Kokkos::View> _electron_beam_scan_path_segments; - Kokkos::View + std::vector< + Kokkos::View> _goldak_scan_path_segments; }; @@ -103,26 +205,28 @@ HeatSources::HeatSources( std::vector electron_beam_beams; std::vector> goldak_scan_path_segments; std::vector> electron_beam_scan_path_segments; - std::vector> cube_heat_sources; + std::vector> cube_heat_sources; for (unsigned int i = 0; i < n_beams; ++i) { boost::property_tree::ptree const &beam_database = source_database.get_child("beam_" + std::to_string(i)); std::string type = beam_database.get("type"); - std::vector scan_path_segments = - ScanPath::extract_scan_paths( - beam_database.get("scan_path_file"), - beam_database.get("scan_path_file_format")); if (type == "goldak") { goldak_beams.emplace_back(beam_database); - goldak_scan_path_segments.push_back(scan_path_segments); + goldak_scan_path_segments.push_back( + ScanPath::extract_scan_paths( + beam_database.get("scan_path_file"), + beam_database.get("scan_path_file_format"))); } else if (type == "electron_beam") { electron_beam_beams.emplace_back(beam_database); - electron_beam_scan_path_segments.push_back(scan_path_segments); + electron_beam_scan_path_segments.push_back( + ScanPath::extract_scan_paths( + beam_database.get("scan_path_file"), + beam_database.get("scan_path_file_format"))); } else if (type == "cube") { @@ -137,61 +241,37 @@ HeatSources::HeatSources( } std::vector> goldak_heat_sources; + for (unsigned int i = 0; i < goldak_scan_path_segments.size(); ++i) { - std::vector goldak_scan_path_segment_start( - goldak_scan_path_segments.size() + 1); - for (unsigned int i = 1; i < goldak_scan_path_segments.size() + 1; ++i) - goldak_scan_path_segment_start[i] = - goldak_scan_path_segment_start[i - 1] + - goldak_scan_path_segments[i - 1].size(); - _goldak_scan_path_segments = decltype(_goldak_scan_path_segments)( + _goldak_scan_path_segments.emplace_back( Kokkos::view_alloc(Kokkos::WithoutInitializing, - "goldak_scan_path_segments"), - goldak_scan_path_segment_start.back()); - for (unsigned int i = 0; i < goldak_scan_path_segments.size(); ++i) - { - auto goldak_scan_path_segment = - Kokkos::subview(_goldak_scan_path_segments, - Kokkos::pair(goldak_scan_path_segment_start[i], - goldak_scan_path_segment_start[i + 1])); - Kokkos::deep_copy(goldak_scan_path_segment, - Kokkos::View( - goldak_scan_path_segments[i].data(), - goldak_scan_path_segments[i].size())); - goldak_heat_sources.emplace_back( - goldak_beams[i], ScanPath(goldak_scan_path_segment)); - } + "goldak_scan_path_segments_" + std::to_string(i)), + goldak_scan_path_segments[i].size()); + Kokkos::deep_copy(_goldak_scan_path_segments.back(), + Kokkos::View( + goldak_scan_path_segments[i].data(), + goldak_scan_path_segments[i].size())); + goldak_heat_sources.emplace_back( + goldak_beams[i], + ScanPath(_goldak_scan_path_segments.back())); } std::vector> electron_beam_heat_sources; + for (unsigned int i = 0; i < electron_beam_scan_path_segments.size(); ++i) { - std::vector electron_beam_scan_path_segment_start( - electron_beam_scan_path_segments.size() + 1); - for (unsigned int i = 1; i < electron_beam_scan_path_segments.size() + 1; - ++i) - electron_beam_scan_path_segment_start[i] = - electron_beam_scan_path_segment_start[i - 1] + - electron_beam_scan_path_segments[i - 1].size(); - _electron_beam_scan_path_segments = - decltype(_electron_beam_scan_path_segments)( - Kokkos::view_alloc(Kokkos::WithoutInitializing, - "electron_beam_scan_path_segments"), - electron_beam_scan_path_segment_start.back()); - for (unsigned int i = 0; i < electron_beam_scan_path_segments.size(); ++i) - { - auto electron_beam_scan_path_segment = Kokkos::subview( - _electron_beam_scan_path_segments, - Kokkos::pair(electron_beam_scan_path_segment_start[i], - electron_beam_scan_path_segment_start[i + 1])); - Kokkos::deep_copy(electron_beam_scan_path_segment, - Kokkos::View( - electron_beam_scan_path_segments[i].data(), - electron_beam_scan_path_segments[i].size())); - electron_beam_heat_sources.emplace_back( - electron_beam_beams[i], - ScanPath(electron_beam_scan_path_segment)); - } + _electron_beam_scan_path_segments.emplace_back( + Kokkos::view_alloc(Kokkos::WithoutInitializing, + "electron_beam_scan_path_segments_" + + std::to_string(i)), + electron_beam_scan_path_segments[i].size()); + Kokkos::deep_copy(_electron_beam_scan_path_segments.back(), + Kokkos::View( + electron_beam_scan_path_segments[i].data(), + electron_beam_scan_path_segments[i].size())); + electron_beam_heat_sources.emplace_back( + electron_beam_beams[i], + ScanPath(_electron_beam_scan_path_segments.back())); } _goldak_heat_sources = decltype(_goldak_heat_sources)( @@ -213,10 +293,9 @@ HeatSources::HeatSources( Kokkos::View *, Kokkos::HostSpace>(electron_beam_heat_sources.data(), electron_beam_heat_sources.size())); - Kokkos::deep_copy( - _cube_heat_sources, - Kokkos::View *, Kokkos::HostSpace>( - cube_heat_sources.data(), cube_heat_sources.size())); + Kokkos::deep_copy(_cube_heat_sources, + Kokkos::View *, Kokkos::HostSpace>( + cube_heat_sources.data(), cube_heat_sources.size())); } template @@ -268,8 +347,6 @@ HeatSources::get_scan_paths() const std::vector> scan_paths; for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) scan_paths.push_back(_electron_beam_heat_sources(i).get_scan_path()); - for (unsigned int i = 0; i < _cube_heat_sources.size(); ++i) - scan_paths.push_back(_cube_heat_sources(i).get_scan_path()); for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) scan_paths.push_back(_goldak_heat_sources(i).get_scan_path()); return scan_paths; diff --git a/tests/test_implicit_operator.cc b/tests/test_implicit_operator.cc index 6507facd..48080281 100644 --- a/tests/test_implicit_operator.cc +++ b/tests/test_implicit_operator.cc @@ -74,12 +74,14 @@ BOOST_AUTO_TEST_CASE(implicit_operator) mat_prop_database); boost::property_tree::ptree beam_database; - beam_database.put("depth", 0.1); - beam_database.put("absorption_efficiency", 0.1); - beam_database.put("diameter", 1.0); - beam_database.put("max_power", 10.); - beam_database.put("scan_path_file", "scan_path.txt"); - beam_database.put("scan_path_file_format", "segment"); + beam_database.put("n_beams", 1); + beam_database.put("beam_0.type", "goldak"); + beam_database.put("beam_0.depth", 0.1); + beam_database.put("beam_0.absorption_efficiency", 0.1); + beam_database.put("beam_0.diameter", 1.0); + beam_database.put("beam_0.max_power", 10.); + beam_database.put("beam_0.scan_path_file", "scan_path.txt"); + beam_database.put("beam_0.scan_path_file_format", "segment"); adamantine::HeatSources heat_sources( beam_database); diff --git a/tests/test_post_processor.cc b/tests/test_post_processor.cc index a7bbb7f5..5fec1038 100644 --- a/tests/test_post_processor.cc +++ b/tests/test_post_processor.cc @@ -73,12 +73,14 @@ BOOST_AUTO_TEST_CASE(thermal_post_processor) mat_prop_database); boost::property_tree::ptree beam_database; - beam_database.put("depth", 0.1); - beam_database.put("absorption_efficiency", 0.1); - beam_database.put("diameter", 1.0); - beam_database.put("max_power", 10.); - beam_database.put("scan_path_file", "scan_path.txt"); - beam_database.put("scan_path_file_format", "segment"); + beam_database.put("n_beams", 1); + beam_database.put("beam_0.type", "goldak"); + beam_database.put("beam_0.depth", 0.1); + beam_database.put("beam_0.absorption_efficiency", 0.1); + beam_database.put("beam_0.diameter", 1.0); + beam_database.put("beam_0.max_power", 10.); + beam_database.put("beam_0.scan_path_file", "scan_path.txt"); + beam_database.put("beam_0.scan_path_file_format", "segment"); adamantine::HeatSources heat_sources( beam_database); diff --git a/tests/test_thermal_operator.cc b/tests/test_thermal_operator.cc index 0fe85bc2..617b5581 100644 --- a/tests/test_thermal_operator.cc +++ b/tests/test_thermal_operator.cc @@ -88,12 +88,14 @@ BOOST_AUTO_TEST_CASE(thermal_operator, *utf::tolerance(1e-15)) // Create the heat sources boost::property_tree::ptree beam_database; - beam_database.put("depth", 0.1); - beam_database.put("absorption_efficiency", 0.1); - beam_database.put("diameter", 1.0); - beam_database.put("max_power", 10.); - beam_database.put("scan_path_file", "scan_path.txt"); - beam_database.put("scan_path_file_format", "segment"); + beam_database.put("n_beams", 1); + beam_database.put("beam_0.type", "goldak"); + beam_database.put("beam_0.depth", 0.1); + beam_database.put("beam_0.absorption_efficiency", 0.1); + beam_database.put("beam_0.diameter", 1.0); + beam_database.put("beam_0.max_power", 10.); + beam_database.put("beam_0.scan_path_file", "scan_path.txt"); + beam_database.put("beam_0.scan_path_file_format", "segment"); adamantine::HeatSources heat_sources( beam_database); @@ -191,12 +193,14 @@ BOOST_AUTO_TEST_CASE(spmv, *utf::tolerance(1e-12)) // Create the heat sources boost::property_tree::ptree beam_database; - beam_database.put("sources.beam_0.depth", 0.1); - beam_database.put("sources.beam_0.absorption_efficiency", 0.1); - beam_database.put("sources.beam_0.diameter", 1.0); - beam_database.put("sources.beam_0.max_power", 10.); - beam_database.put("sources.beam_0.scan_path_file", "scan_path.txt"); - beam_database.put("sources.beam_0.scan_path_file_format", "segment"); + beam_database.put("n_beams", 1); + beam_database.put("beam_0.type", "goldak"); + beam_database.put("beam_0.depth", 0.1); + beam_database.put("beam_0.absorption_efficiency", 0.1); + beam_database.put("beam_0.diameter", 1.0); + beam_database.put("beam_0.max_power", 10.); + beam_database.put("beam_0.scan_path_file", "scan_path.txt"); + beam_database.put("beam_0.scan_path_file_format", "segment"); adamantine::HeatSources heat_sources( beam_database); @@ -298,12 +302,14 @@ BOOST_AUTO_TEST_CASE(spmv_anisotropic, *utf::tolerance(1e-12)) // Create the heat sources boost::property_tree::ptree beam_database; - beam_database.put("depth", 0.1); - beam_database.put("absorption_efficiency", 0.1); - beam_database.put("diameter", 1.0); - beam_database.put("max_power", 10.); - beam_database.put("scan_path_file", "scan_path.txt"); - beam_database.put("scan_path_file_format", "segment"); + beam_database.put("n_beams", 1); + beam_database.put("beam_0.type", "goldak"); + beam_database.put("beam_0.depth", 0.1); + beam_database.put("beam_0.absorption_efficiency", 0.1); + beam_database.put("beam_0.diameter", 1.0); + beam_database.put("beam_0.max_power", 10.); + beam_database.put("beam_0.scan_path_file", "scan_path.txt"); + beam_database.put("beam_0.scan_path_file_format", "segment"); adamantine::HeatSources heat_sources( beam_database); @@ -603,12 +609,14 @@ BOOST_AUTO_TEST_CASE(spmv_rad, *utf::tolerance(1e-12)) // Create the heat sources boost::property_tree::ptree beam_database; - beam_database.put("depth", 0.1); - beam_database.put("absorption_efficiency", 0.1); - beam_database.put("diameter", 1.0); - beam_database.put("max_power", 10.); - beam_database.put("scan_path_file", "scan_path.txt"); - beam_database.put("scan_path_file_format", "segment"); + beam_database.put("n_beams", 1); + beam_database.put("beam_0.type", "goldak"); + beam_database.put("beam_0.depth", 0.1); + beam_database.put("beam_0.absorption_efficiency", 0.1); + beam_database.put("beam_0.diameter", 1.0); + beam_database.put("beam_0.max_power", 10.); + beam_database.put("beam_0.scan_path_file", "scan_path.txt"); + beam_database.put("beam_0.scan_path_file_format", "segment"); adamantine::HeatSources heat_sources( beam_database); @@ -785,12 +793,14 @@ BOOST_AUTO_TEST_CASE(spmv_conv, *utf::tolerance(1e-12)) // Create the heat sources boost::property_tree::ptree beam_database; - beam_database.put("depth", 0.1); - beam_database.put("absorption_efficiency", 0.1); - beam_database.put("diameter", 1.0); - beam_database.put("max_power", 10.); - beam_database.put("scan_path_file", "scan_path.txt"); - beam_database.put("scan_path_file_format", "segment"); + beam_database.put("n_beams", 1); + beam_database.put("beam_0.type", "goldak"); + beam_database.put("beam_0.depth", 0.1); + beam_database.put("beam_0.absorption_efficiency", 0.1); + beam_database.put("beam_0.diameter", 1.0); + beam_database.put("beam_0.max_power", 10.); + beam_database.put("beam_0.scan_path_file", "scan_path.txt"); + beam_database.put("beam_0.scan_path_file_format", "segment"); adamantine::HeatSources heat_sources( beam_database); diff --git a/tests/test_thermal_operator_device.cc b/tests/test_thermal_operator_device.cc index 0093d83d..697ca3cb 100644 --- a/tests/test_thermal_operator_device.cc +++ b/tests/test_thermal_operator_device.cc @@ -279,12 +279,14 @@ BOOST_AUTO_TEST_CASE(mf_spmv, *utf::tolerance(1.5e-12)) // Create the heat sources boost::property_tree::ptree beam_database; - beam_database.put("depth", 0.1); - beam_database.put("absorption_efficiency", 0.1); - beam_database.put("diameter", 1.0); - beam_database.put("max_power", 10.); - beam_database.put("scan_path_file", "scan_path.txt"); - beam_database.put("scan_path_file_format", "segment"); + beam_database.put("n_beams", 1); + beam_database.put("beam_0.type", "goldak"); + beam_database.put("beam_0.depth", 0.1); + beam_database.put("beam_0.absorption_efficiency", 0.1); + beam_database.put("beam_0.diameter", 1.0); + beam_database.put("beam_0.max_power", 10.); + beam_database.put("beam_0.scan_path_file", "scan_path.txt"); + beam_database.put("beam_0.scan_path_file_format", "segment"); adamantine::HeatSources heat_sources( beam_database); From cf6263fee4f1858fa7d039a90e879797be8cf98f Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Fri, 10 May 2024 16:35:58 +0000 Subject: [PATCH 05/30] Remove HeatSource.hh --- source/CMakeLists.txt | 2 +- source/CubeHeatSource.cc | 1 - source/CubeHeatSource.hh | 24 ++++-- source/ElectronBeamHeatSource.cc | 2 +- source/ElectronBeamHeatSource.hh | 35 ++++++-- source/GoldakHeatSource.cc | 2 +- source/GoldakHeatSource.hh | 35 ++++++-- source/HeatSource.hh | 128 ------------------------------ source/ScanPath.hh | 2 + source/ThermalPhysicsInterface.hh | 3 - source/material_deposition.cc | 11 ++- 11 files changed, 87 insertions(+), 158 deletions(-) delete mode 100644 source/HeatSource.hh diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index a6e65140..84d04193 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -7,7 +7,7 @@ set(Adamantine_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/ExperimentalData.hh ${CMAKE_CURRENT_SOURCE_DIR}/Geometry.hh ${CMAKE_CURRENT_SOURCE_DIR}/GoldakHeatSource.hh - ${CMAKE_CURRENT_SOURCE_DIR}/HeatSource.hh + ${CMAKE_CURRENT_SOURCE_DIR}/HeatSources.hh ${CMAKE_CURRENT_SOURCE_DIR}/ImplicitOperator.hh ${CMAKE_CURRENT_SOURCE_DIR}/MaterialProperty.hh ${CMAKE_CURRENT_SOURCE_DIR}/MaterialProperty.templates.hh diff --git a/source/CubeHeatSource.cc b/source/CubeHeatSource.cc index 469b98f3..4a9a7a5f 100644 --- a/source/CubeHeatSource.cc +++ b/source/CubeHeatSource.cc @@ -15,7 +15,6 @@ namespace adamantine { template CubeHeatSource::CubeHeatSource(boost::property_tree::ptree const &database) - : HeatSource() { _start_time = database.get("start_time"); _end_time = database.get("end_time"); diff --git a/source/CubeHeatSource.hh b/source/CubeHeatSource.hh index 67f0b84f..2b561b19 100644 --- a/source/CubeHeatSource.hh +++ b/source/CubeHeatSource.hh @@ -8,9 +8,9 @@ #ifndef CUBE_HEAT_SOURCE_HH #define CUBE_HEAT_SOURCE_HH -#include +#include -#include +#include namespace adamantine { @@ -20,7 +20,6 @@ namespace adamantine */ template class CubeHeatSource final - : public HeatSource { public: /** @@ -41,18 +40,24 @@ public: /** * Set the time variable. */ - void update_time(double time) final; + void update_time(double time); /** * Return the value of the source for a given point and time. */ - double value(dealii::Point const &point, - double const /*height*/) const final; + double value(dealii::Point const &point, double const /*height*/) const; /** * Compute the current height of the where the heat source meets the material * (i.e. the current scan path height). */ - double get_current_height(double const time) const final; + double get_current_height(double const time) const; + + void set_beam_properties(boost::property_tree::ptree const &database) + { + _beam.set_from_database(database); + } + + BeamHeatSourceProperties get_beam_properties() const { return _beam; } private: bool _source_on = false; @@ -61,6 +66,11 @@ private: double _value; dealii::Point _min_point; dealii::Point _max_point; + double _alpha; + /** + * Structure of the physical properties of the beam heat source. + */ + BeamHeatSourceProperties _beam; }; } // namespace adamantine diff --git a/source/ElectronBeamHeatSource.cc b/source/ElectronBeamHeatSource.cc index 6236bbdc..a149d18b 100644 --- a/source/ElectronBeamHeatSource.cc +++ b/source/ElectronBeamHeatSource.cc @@ -18,7 +18,7 @@ template ElectronBeamHeatSource::ElectronBeamHeatSource( BeamHeatSourceProperties const &beam, ScanPath const &scan_path) - : HeatSource(beam, scan_path) + : _beam(beam), _scan_path(scan_path) { } diff --git a/source/ElectronBeamHeatSource.hh b/source/ElectronBeamHeatSource.hh index 351f4432..160eaeac 100644 --- a/source/ElectronBeamHeatSource.hh +++ b/source/ElectronBeamHeatSource.hh @@ -8,17 +8,18 @@ #ifndef ELECTRON_BEAM_HEAT_SOURCE_HH #define ELECTRON_BEAM_HEAT_SOURCE_HH -#include +#include +#include namespace adamantine { /** - * A derived class from HeatSource for a model of an electron beam heat source. + * A model of an electron beam heat source. * The form of the heat source model is taken from the following reference: * Raghavan et al, Acta Materilia, 112, 2016, pp 303-314. */ template -class ElectronBeamHeatSource final : public HeatSource +class ElectronBeamHeatSource { public: /** @@ -37,18 +38,40 @@ public: /** * Set the time variable. */ - void update_time(double time) final; + void update_time(double time); /** * Returns the value of an electron beam heat source at a specified point and * time. */ - double value(dealii::Point const &point, - double const height) const final; + double value(dealii::Point const &point, double const height) const; + + ScanPath const &get_scan_path() const { return _scan_path; } + + double get_current_height(double const time) const + { + return _scan_path.value(time)[2]; + } + + void set_beam_properties(boost::property_tree::ptree const &database) + { + _beam.set_from_database(database); + } + + BeamHeatSourceProperties get_beam_properties() const { return _beam; } private: dealii::Point<3> _beam_center; double _alpha; + /** + * Structure of the physical properties of the beam heat source. + */ + BeamHeatSourceProperties _beam; + + /** + * The scan path for the heat source. + */ + ScanPath _scan_path; }; } // namespace adamantine diff --git a/source/GoldakHeatSource.cc b/source/GoldakHeatSource.cc index acb5fc1b..a4a0cba4 100644 --- a/source/GoldakHeatSource.cc +++ b/source/GoldakHeatSource.cc @@ -18,7 +18,7 @@ template GoldakHeatSource::GoldakHeatSource( BeamHeatSourceProperties const &beam, ScanPath const &scan_path) - : HeatSource(beam, scan_path) + : _beam(beam), _scan_path(scan_path) { } diff --git a/source/GoldakHeatSource.hh b/source/GoldakHeatSource.hh index 76f48543..4652c92e 100644 --- a/source/GoldakHeatSource.hh +++ b/source/GoldakHeatSource.hh @@ -8,17 +8,18 @@ #ifndef GOLDAK_HEAT_SOURCE_HH #define GOLDAK_HEAT_SOURCE_HH -#include +#include +#include namespace adamantine { /** - * A derived class from HeatSource for the Goldak model of a laser heat source. + * Goldak model of a laser heat source. * The form of the heat source model is taken from the following reference: * Coleman et al, Journal of Heat Transfer, (in press, 2020). */ template -class GoldakHeatSource final : public HeatSource +class GoldakHeatSource { public: /** @@ -37,18 +38,40 @@ public: /** * Set the time variable. */ - void update_time(double time) final; + void update_time(double time); /** * Returns the value of a Goldak heat source at a specified point and * time. */ - double value(dealii::Point const &point, - double const height) const final; + double value(dealii::Point const &point, double const height) const; + + ScanPath const &get_scan_path() const { return _scan_path; } + + double get_current_height(double const time) const + { + return _scan_path.value(time)[2]; + } + + void set_beam_properties(boost::property_tree::ptree const &database) + { + _beam.set_from_database(database); + } + + BeamHeatSourceProperties get_beam_properties() const { return _beam; } private: dealii::Point<3> _beam_center; double _alpha; + /** + * Structure of the physical properties of the beam heat source. + */ + BeamHeatSourceProperties _beam; + + /** + * The scan path for the heat source. + */ + ScanPath _scan_path; }; } // namespace adamantine diff --git a/source/HeatSource.hh b/source/HeatSource.hh deleted file mode 100644 index e69bd5d8..00000000 --- a/source/HeatSource.hh +++ /dev/null @@ -1,128 +0,0 @@ -/* Copyright (c) 2020 - 2021, the adamantine authors. - * - * This file is subject to the Modified BSD License and may not be distributed - * without copyright and license information. Please refer to the file LICENSE - * for the text and further information on this license. - */ - -#ifndef HEAT_SOURCE_HH -#define HEAT_SOURCE_HH - -#include -#include -#include - -#include - -namespace adamantine -{ -/** - * This is the base class for describing the functional form of a heat - * source. It has a pure virtual "value" method that needs to be implemented in - * a derived class. - * NOTE: The coordinate system in this class is different than - * for the finite element mesh. In this class, the first two components of a - * dealii::Point<3> describe the position along the surface of the part. The - * last component is the height through the thickness of the part from the base - * plate. This is in opposition to the finite element mesh where the first and - * last components of a dealii::Point<3> describe the position along the surface - * of the part, and the second component is the thickness. That is, the last two - * components are swapped between the two coordinate systems. - */ -template -class HeatSource -{ -public: - /** - * Default constructor. This constructor should only be used for non-beam heat - * source. - */ - HeatSource() = default; - - /** - * Constructor. - * \param[in] database requires the following entries: - * - absorption_efficiency: double in \f$[0,1]\f$ - * - depth: double in \f$[0,\infty)\f$ - * - diameter: double in \f$[0,\infty)\f$ - * - max_power: double in \f$[0, \infty)\f$ - * - input_file: name of the file that contains the scan path - * segments - */ - HeatSource(BeamHeatSourceProperties const &beam, - ScanPath const &scan_path) - : _beam(beam), _scan_path(scan_path) - { - } - - /** - * Destructor. - */ - virtual ~HeatSource() = default; - - /** - * Set the time variable. - */ - virtual void update_time(double time) = 0; - - /** - * Compute the heat source at a given point at a given time given the current - * height of the object being manufactured. - */ - virtual double value(dealii::Point const &point, - double const height) const = 0; - /** - * Return the scan path for the heat source. - */ - virtual ScanPath const &get_scan_path() const; - - /** - * Compute the current height of the where the heat source meets the material - * (i.e. the current scan path height). - */ - virtual double get_current_height(double const time) const; - - /** - * (Re)sets the BeamHeatSourceProperties member variable, necessary if the - * beam parameters vary in time (e.g. due to data assimilation). - */ - virtual void set_beam_properties(boost::property_tree::ptree const &database); - - BeamHeatSourceProperties get_beam_properties() const { return _beam; } - -protected: - /** - * Structure of the physical properties of the beam heat source. - */ - BeamHeatSourceProperties _beam; - - /** - * The scan path for the heat source. - */ - ScanPath _scan_path; -}; - -template -inline ScanPath const & -HeatSource::get_scan_path() const -{ - return _scan_path; -} - -template -inline double -HeatSource::get_current_height(double const time) const -{ - return _scan_path.value(time)[2]; -} - -template -inline void HeatSource::set_beam_properties( - boost::property_tree::ptree const &database) -{ - _beam.set_from_database(database); -} - -} // namespace adamantine - -#endif diff --git a/source/ScanPath.hh b/source/ScanPath.hh index 9c4ab903..0ecea77f 100644 --- a/source/ScanPath.hh +++ b/source/ScanPath.hh @@ -15,6 +15,8 @@ #include #include +#include + #include #include #include diff --git a/source/ThermalPhysicsInterface.hh b/source/ThermalPhysicsInterface.hh index 915a7b02..6582fc97 100644 --- a/source/ThermalPhysicsInterface.hh +++ b/source/ThermalPhysicsInterface.hh @@ -19,9 +19,6 @@ namespace adamantine // Forward declarations class Timer; -template -class HeatSource; - /** * This class defines the interface for ThermalPhysics used in run(). The * objective of this class is to simplify code in run() by reducing the number diff --git a/source/material_deposition.cc b/source/material_deposition.cc index 51622214..cc4b3472 100644 --- a/source/material_deposition.cc +++ b/source/material_deposition.cc @@ -6,6 +6,7 @@ */ #include +#include #include #include @@ -400,10 +401,12 @@ merge_deposition_paths( template std::tuple>, std::vector, std::vector, std::vector> -deposition_along_scan_path(boost::property_tree::ptree const &geometry_database, - ScanPath const &scan_path); +deposition_along_scan_path( + boost::property_tree::ptree const &geometry_database, + ScanPath const &scan_path); template std::tuple>, std::vector, std::vector, std::vector> -deposition_along_scan_path(boost::property_tree::ptree const &geometry_database, - ScanPath const &scan_path); +deposition_along_scan_path( + boost::property_tree::ptree const &geometry_database, + ScanPath const &scan_path); } // namespace adamantine From 4ec8fd0488c17fc3f033a9e28387b94a4d597f34 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Fri, 10 May 2024 22:57:08 +0000 Subject: [PATCH 06/30] Copy to host where necessary and fix copy_to_host --- source/HeatSources.hh | 8 ++++---- source/ThermalPhysics.templates.hh | 11 +++++++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/source/HeatSources.hh b/source/HeatSources.hh index 56ee12a3..b3c9ba12 100644 --- a/source/HeatSources.hh +++ b/source/HeatSources.hh @@ -88,11 +88,11 @@ public: _electron_beam_heat_sources.size()); for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) - goldak_beams.push_back( - host_copy_goldak_heat_sources(i).get_beam_properties()); + goldak_beams[i] = + host_copy_goldak_heat_sources(i).get_beam_properties(); for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) - electron_beam_beams.push_back( - host_copy_electron_beam_heat_sources(i).get_beam_properties()); + electron_beam_beams[i] = + host_copy_electron_beam_heat_sources(i).get_beam_properties(); Kokkos::View *, Kokkos::HostSpace> diff --git a/source/ThermalPhysics.templates.hh b/source/ThermalPhysics.templates.hh index e443436d..ef10c9a6 100644 --- a/source/ThermalPhysics.templates.hh +++ b/source/ThermalPhysics.templates.hh @@ -120,7 +120,8 @@ evaluate_thermal_physics_impl( // Compute the source term. // TODO do this on the GPU - heat_sources.update_time(t); + auto host_heat_sources = heat_sources.copy_to_host(); + host_heat_sources.update_time(t); dealii::LA::distributed::Vector source( y.get_partitioner()); source = 0.; @@ -165,7 +166,8 @@ evaluate_thermal_physics_impl( double const inv_rho_cp = thermal_operator_dev->get_inv_rho_cp(cell, q); double quad_pt_source = 0.; dealii::Point const &q_point = fe_values.quadrature_point(q); - quad_pt_source += heat_sources.value(q_point, current_source_height); + quad_pt_source += + host_heat_sources.value(q_point, current_source_height); cell_source[i] += inv_rho_cp * quad_pt_source * fe_values.shape_value(i, q) * fe_values.JxW(q); @@ -464,7 +466,8 @@ ThermalPhysicsset_active_fe_index(1); } - _current_source_height = _heat_sources.get_current_height(0.0); + auto host_heat_sources = _heat_sources.copy_to_host(); + _current_source_height = host_heat_sources.get_current_height(0.0); } template &solution, std::vector &timers) { - _current_source_height = _heat_sources.get_current_height(t); + _current_source_height = _heat_sources.copy_to_host().get_current_height(t); auto eval = [&](double const t, LA_Vector const &y) { return evaluate_thermal_physics(t, y, timers); }; From 432c229d28f64a6d93dc517e3b64a00f8c1e47fa Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Mon, 13 May 2024 13:06:33 -0400 Subject: [PATCH 07/30] Restructure HeatSources --- source/CubeHeatSource.hh | 31 +++- source/ElectronBeamHeatSource.hh | 63 +++++--- source/GoldakHeatSource.hh | 63 ++++++-- source/HeatSources.hh | 245 +++++++++++++++++-------------- 4 files changed, 251 insertions(+), 151 deletions(-) diff --git a/source/CubeHeatSource.hh b/source/CubeHeatSource.hh index 2b561b19..73d51208 100644 --- a/source/CubeHeatSource.hh +++ b/source/CubeHeatSource.hh @@ -52,12 +52,16 @@ public: */ double get_current_height(double const time) const; - void set_beam_properties(boost::property_tree::ptree const &database) - { - _beam.set_from_database(database); - } + /** + * (Re)sets the BeamHeatSourceProperties member variable, necessary if the + * beam parameters vary in time (e.g. due to data assimilation). + */ + void set_beam_properties(boost::property_tree::ptree const &database); - BeamHeatSourceProperties get_beam_properties() const { return _beam; } + /** + * Return the beam properties. + */ + BeamHeatSourceProperties get_beam_properties() const; private: bool _source_on = false; @@ -67,11 +71,22 @@ private: dealii::Point _min_point; dealii::Point _max_point; double _alpha; - /** - * Structure of the physical properties of the beam heat source. - */ BeamHeatSourceProperties _beam; }; + +template +void CubeHeatSource::set_beam_properties( + boost::property_tree::ptree const &database) +{ + _beam.set_from_database(database); +} + +template +BeamHeatSourceProperties CubeHeatSource::get_beam_properties() const +{ + return _beam; +} + } // namespace adamantine #endif diff --git a/source/ElectronBeamHeatSource.hh b/source/ElectronBeamHeatSource.hh index 160eaeac..b2696805 100644 --- a/source/ElectronBeamHeatSource.hh +++ b/source/ElectronBeamHeatSource.hh @@ -46,33 +46,62 @@ public: */ double value(dealii::Point const &point, double const height) const; - ScanPath const &get_scan_path() const { return _scan_path; } + /** + * Return the scan path. + */ + ScanPath const &get_scan_path() const; - double get_current_height(double const time) const - { - return _scan_path.value(time)[2]; - } + /** + * Compute the current height of the where the heat source meets the material + * (i.e. the current scan path height). + */ + double get_current_height(double const time) const; - void set_beam_properties(boost::property_tree::ptree const &database) - { - _beam.set_from_database(database); - } + /** + * (Re)sets the BeamHeatSourceProperties member variable, necessary if the + * beam parameters vary in time (e.g. due to data assimilation). + */ + void set_beam_properties(boost::property_tree::ptree const &database); - BeamHeatSourceProperties get_beam_properties() const { return _beam; } + /** + * Return the beam properties. + */ + BeamHeatSourceProperties get_beam_properties() const; private: dealii::Point<3> _beam_center; double _alpha; - /** - * Structure of the physical properties of the beam heat source. - */ BeamHeatSourceProperties _beam; - - /** - * The scan path for the heat source. - */ ScanPath _scan_path; }; + +template +ScanPath const & +ElectronBeamHeatSource::get_scan_path() const +{ + return _scan_path; +} + +template +double ElectronBeamHeatSource::get_current_height( + double const time) const +{ + return _scan_path.value(time)[2]; +} + +template +void ElectronBeamHeatSource::set_beam_properties( + boost::property_tree::ptree const &database) +{ + _beam.set_from_database(database); +} +template +BeamHeatSourceProperties +ElectronBeamHeatSource::get_beam_properties() const +{ + return _beam; +} + } // namespace adamantine #endif diff --git a/source/GoldakHeatSource.hh b/source/GoldakHeatSource.hh index 4652c92e..8ea7db29 100644 --- a/source/GoldakHeatSource.hh +++ b/source/GoldakHeatSource.hh @@ -46,33 +46,64 @@ public: */ double value(dealii::Point const &point, double const height) const; - ScanPath const &get_scan_path() const { return _scan_path; } + /** + * Return the scan path. + */ + ScanPath const &get_scan_path() const; - double get_current_height(double const time) const - { - return _scan_path.value(time)[2]; - } + /** + * Compute the current height of the where the heat source meets the material + * (i.e. the current scan path height). + */ + double get_current_height(double const time) const; - void set_beam_properties(boost::property_tree::ptree const &database) - { - _beam.set_from_database(database); - } + /** + * (Re)sets the BeamHeatSourceProperties member variable, necessary if the + * beam parameters vary in time (e.g. due to data assimilation). + */ + void set_beam_properties(boost::property_tree::ptree const &database); - BeamHeatSourceProperties get_beam_properties() const { return _beam; } + /** + * Return the beam properties. + */ + BeamHeatSourceProperties get_beam_properties() const; private: dealii::Point<3> _beam_center; double _alpha; - /** - * Structure of the physical properties of the beam heat source. - */ BeamHeatSourceProperties _beam; - /** - * The scan path for the heat source. - */ ScanPath _scan_path; }; + +template +ScanPath const & +GoldakHeatSource::get_scan_path() const +{ + return _scan_path; +} + +template +double GoldakHeatSource::get_current_height( + double const time) const +{ + return _scan_path.value(time)[2]; +} + +template +void GoldakHeatSource::set_beam_properties( + boost::property_tree::ptree const &database) +{ + _beam.set_from_database(database); +} + +template +BeamHeatSourceProperties +GoldakHeatSource::get_beam_properties() const +{ + return _beam; +} + } // namespace adamantine #endif diff --git a/source/HeatSources.hh b/source/HeatSources.hh index b3c9ba12..c9c19a3f 100644 --- a/source/HeatSources.hh +++ b/source/HeatSources.hh @@ -31,116 +31,10 @@ public: */ HeatSources(boost::property_tree::ptree const &source_database); - HeatSources( - Kokkos::View *, - typename MemorySpace::kokkos_space> - electron_beam_heat_sources, - Kokkos::View *, typename MemorySpace::kokkos_space> - cube_heat_sources, - Kokkos::View *, - typename MemorySpace::kokkos_space> - goldak_heat_sources, - std::vector< - Kokkos::View> - electron_beam_scan_path_segments, - std::vector< - Kokkos::View> - goldak_scan_path_segments) - : _electron_beam_heat_sources(electron_beam_heat_sources), - _cube_heat_sources(cube_heat_sources), - _goldak_heat_sources(goldak_heat_sources), - _electron_beam_scan_path_segments(electron_beam_scan_path_segments), - _goldak_scan_path_segments(goldak_scan_path_segments) - { - } - - HeatSources copy_to_host() const - { - if constexpr (std::is_same_v) - return *this; - else - { - std::vector> - host_electron_beam_scan_path_segments( - _electron_beam_scan_path_segments.size()); - std::vector> - host_goldak_scan_path_segments(_goldak_scan_path_segments.size()); - - for (unsigned int i = 0; i < _electron_beam_scan_path_segments.size(); - ++i) - host_electron_beam_scan_path_segments[i] = - Kokkos::create_mirror_view_and_copy( - Kokkos::HostSpace{}, _electron_beam_scan_path_segments[i]); - - for (unsigned int i = 0; i < _goldak_scan_path_segments.size(); ++i) - host_goldak_scan_path_segments[i] = Kokkos::create_mirror_view_and_copy( - Kokkos::HostSpace{}, _goldak_scan_path_segments[i]); - - auto host_copy_electron_beam_heat_sources = - Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, - _electron_beam_heat_sources); - auto host_copy_goldak_heat_sources = Kokkos::create_mirror_view_and_copy( - Kokkos::HostSpace{}, _goldak_heat_sources); - - std::vector goldak_beams( - _goldak_heat_sources.size()); - std::vector electron_beam_beams( - _electron_beam_heat_sources.size()); - - for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) - goldak_beams[i] = - host_copy_goldak_heat_sources(i).get_beam_properties(); - for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) - electron_beam_beams[i] = - host_copy_electron_beam_heat_sources(i).get_beam_properties(); - - Kokkos::View *, - Kokkos::HostSpace> - host_electron_beam_heat_sources( - Kokkos::view_alloc(Kokkos::WithoutInitializing, - "electron_beam_heat_sources"), - _electron_beam_heat_sources.size()); - Kokkos::View *, - Kokkos::HostSpace> - host_goldak_heat_sources( - Kokkos::view_alloc(Kokkos::WithoutInitializing, - "goldak_heat_sources"), - _goldak_heat_sources.size()); - - std::vector> - goldak_heat_source_vector; - for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) - goldak_heat_source_vector.emplace_back( - goldak_beams[i], ScanPath( - host_goldak_scan_path_segments[i])); - Kokkos::deep_copy( - host_goldak_heat_sources, - Kokkos::View *, - Kokkos::HostSpace>(goldak_heat_source_vector.data(), - goldak_heat_source_vector.size())); - - std::vector> - electron_beam_heat_source_vector; - for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) - electron_beam_heat_source_vector.emplace_back( - electron_beam_beams[i], - ScanPath( - host_electron_beam_scan_path_segments[i])); - Kokkos::deep_copy( - host_electron_beam_heat_sources, - Kokkos::View *, - Kokkos::HostSpace>( - electron_beam_heat_source_vector.data(), - electron_beam_heat_source_vector.size())); - - auto host_cube_heat_sources = Kokkos::create_mirror_view_and_copy( - Kokkos::HostSpace{}, _cube_heat_sources); - - return {host_electron_beam_heat_sources, host_cube_heat_sources, - host_goldak_heat_sources, host_electron_beam_scan_path_segments, - host_goldak_scan_path_segments}; - } - } + /** + * Return a copy of this instance in host memory space. + */ + HeatSources copy_to_host() const; /** * Set the time variable. @@ -180,6 +74,27 @@ public: double get_current_height(double time) const; private: + friend class HeatSources; + + /** + * Private constructor used by copy_to_host. + */ + HeatSources( + Kokkos::View *, + typename MemorySpace::kokkos_space> + electron_beam_heat_sources, + Kokkos::View *, typename MemorySpace::kokkos_space> + cube_heat_sources, + Kokkos::View *, + typename MemorySpace::kokkos_space> + goldak_heat_sources, + std::vector< + Kokkos::View> + electron_beam_scan_path_segments, + std::vector< + Kokkos::View> + goldak_scan_path_segments); + Kokkos::View *, typename MemorySpace::kokkos_space> _electron_beam_heat_sources; @@ -298,6 +213,30 @@ HeatSources::HeatSources( cube_heat_sources.data(), cube_heat_sources.size())); } +template +HeatSources::HeatSources( + Kokkos::View *, + typename MemorySpace::kokkos_space> + electron_beam_heat_sources, + Kokkos::View *, typename MemorySpace::kokkos_space> + cube_heat_sources, + Kokkos::View *, + typename MemorySpace::kokkos_space> + goldak_heat_sources, + std::vector< + Kokkos::View> + electron_beam_scan_path_segments, + std::vector< + Kokkos::View> + goldak_scan_path_segments) + : _electron_beam_heat_sources(electron_beam_heat_sources), + _cube_heat_sources(cube_heat_sources), + _goldak_heat_sources(goldak_heat_sources), + _electron_beam_scan_path_segments(electron_beam_scan_path_segments), + _goldak_scan_path_segments(goldak_scan_path_segments) +{ +} + template KOKKOS_FUNCTION void HeatSources::update_time(double time) { @@ -399,6 +338,92 @@ void HeatSources::set_beam_properties( set_properties(_goldak_heat_sources[i]); } +template +HeatSources +HeatSources::copy_to_host() const +{ + if constexpr (std::is_same_v) + return *this; + else + { + Kokkos::View *, + Kokkos::HostSpace> + host_electron_beam_heat_sources( + Kokkos::view_alloc(Kokkos::WithoutInitializing, + "electron_beam_heat_sources"), + _electron_beam_heat_sources.size()); + std::vector> + host_electron_beam_scan_path_segments( + _electron_beam_scan_path_segments.size()); + { + for (unsigned int i = 0; i < _electron_beam_scan_path_segments.size(); + ++i) + host_electron_beam_scan_path_segments[i] = + Kokkos::create_mirror_view_and_copy( + Kokkos::HostSpace{}, _electron_beam_scan_path_segments[i]); + auto host_copy_electron_beam_heat_sources = + Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, + _electron_beam_heat_sources); + std::vector electron_beam_beams( + _electron_beam_heat_sources.size()); + for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) + electron_beam_beams[i] = + host_copy_electron_beam_heat_sources(i).get_beam_properties(); + std::vector> + electron_beam_heat_source_vector; + for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) + electron_beam_heat_source_vector.emplace_back( + electron_beam_beams[i], + ScanPath( + host_electron_beam_scan_path_segments[i])); + Kokkos::deep_copy( + host_electron_beam_heat_sources, + Kokkos::View *, + Kokkos::HostSpace>( + electron_beam_heat_source_vector.data(), + electron_beam_heat_source_vector.size())); + } + + Kokkos::View *, + Kokkos::HostSpace> + host_goldak_heat_sources(Kokkos::view_alloc(Kokkos::WithoutInitializing, + "goldak_heat_sources"), + _goldak_heat_sources.size()); + std::vector> + host_goldak_scan_path_segments(_goldak_scan_path_segments.size()); + { + for (unsigned int i = 0; i < _goldak_scan_path_segments.size(); ++i) + host_goldak_scan_path_segments[i] = Kokkos::create_mirror_view_and_copy( + Kokkos::HostSpace{}, _goldak_scan_path_segments[i]); + auto host_copy_goldak_heat_sources = Kokkos::create_mirror_view_and_copy( + Kokkos::HostSpace{}, _goldak_heat_sources); + std::vector goldak_beams( + _goldak_heat_sources.size()); + for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) + goldak_beams[i] = + host_copy_goldak_heat_sources(i).get_beam_properties(); + std::vector> + goldak_heat_source_vector; + for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) + goldak_heat_source_vector.emplace_back( + goldak_beams[i], ScanPath( + host_goldak_scan_path_segments[i])); + Kokkos::deep_copy( + host_goldak_heat_sources, + Kokkos::View *, + Kokkos::HostSpace>(goldak_heat_source_vector.data(), + goldak_heat_source_vector.size())); + } + + auto host_cube_heat_sources = Kokkos::create_mirror_view_and_copy( + Kokkos::HostSpace{}, _cube_heat_sources); + + return {host_electron_beam_heat_sources, host_cube_heat_sources, + host_goldak_heat_sources, host_electron_beam_scan_path_segments, + host_goldak_scan_path_segments}; + } +} + } // namespace adamantine #endif From 9e520b71bedee1373f27f75473e157c1154d1a21 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Mon, 13 May 2024 16:51:50 -0400 Subject: [PATCH 08/30] Add copy_to_device --- application/adamantine.hh | 6 +- source/HeatSources.hh | 90 +++++++++++++++++------------- source/ThermalPhysics.templates.hh | 11 ++-- 3 files changed, 60 insertions(+), 47 deletions(-) diff --git a/application/adamantine.hh b/application/adamantine.hh index ebdc0fd8..08901622 100644 --- a/application/adamantine.hh +++ b/application/adamantine.hh @@ -606,7 +606,7 @@ void refine_mesh( const double refinement_beam_cutoff = refinement_database.get("beam_cutoff", 1.0e-15); - adamantine::HeatSources host_heat_sources = heat_sources.copy_to_host(); + adamantine::HeatSources host_heat_sources = heat_sources.copy_to(dealii::MemorySpace::Host{}); for (unsigned int i = 0; i < n_refinements; ++i) { @@ -935,7 +935,7 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database, mechanical_physics, displacement, material_properties, timers); ++n_time_step; - adamantine::HeatSources host_heat_sources = heat_sources.copy_to_host(); + adamantine::HeatSources host_heat_sources = heat_sources.copy_to(dealii::MemorySpace::Host{}); // Create the bounding boxes used for material deposition auto [material_deposition_boxes, deposition_times, deposition_cos, @@ -1719,7 +1719,7 @@ run_ensemble(MPI_Comm const &global_communicator, refine_mesh(thermal_physics_ensemble[member], *material_properties_ensemble[member], solution_augmented_ensemble[member].block(base_state), - heat_sources_ensemble[member].copy_to_host(), time, next_refinement_time, + heat_sources_ensemble[member].copy_to(dealii::MemorySpace::Host{}), time, next_refinement_time, time_steps_refinement, refinement_database); solution_augmented_ensemble[member].collect_sizes(); } diff --git a/source/HeatSources.hh b/source/HeatSources.hh index c9c19a3f..704c94cf 100644 --- a/source/HeatSources.hh +++ b/source/HeatSources.hh @@ -32,9 +32,11 @@ public: HeatSources(boost::property_tree::ptree const &source_database); /** - * Return a copy of this instance in host memory space. + * Return a copy of this instance in the target memory space. */ - HeatSources copy_to_host() const; + template + HeatSources + copy_to(TargetMemorySpace target_memory_space) const; /** * Set the time variable. @@ -75,6 +77,7 @@ public: private: friend class HeatSources; + friend class HeatSources; /** * Private constructor used by copy_to_host. @@ -339,88 +342,95 @@ void HeatSources::set_beam_properties( } template -HeatSources -HeatSources::copy_to_host() const +template +HeatSources HeatSources::copy_to( + TargetMemorySpace /*target_memory_space*/) const { - if constexpr (std::is_same_v) + if constexpr (std::is_same_v) return *this; else { - Kokkos::View *, - Kokkos::HostSpace> - host_electron_beam_heat_sources( + Kokkos::View *, + typename TargetMemorySpace::kokkos_space> + target_electron_beam_heat_sources( Kokkos::view_alloc(Kokkos::WithoutInitializing, "electron_beam_heat_sources"), _electron_beam_heat_sources.size()); - std::vector> - host_electron_beam_scan_path_segments( + std::vector> + target_electron_beam_scan_path_segments( _electron_beam_scan_path_segments.size()); { for (unsigned int i = 0; i < _electron_beam_scan_path_segments.size(); ++i) - host_electron_beam_scan_path_segments[i] = + target_electron_beam_scan_path_segments[i] = Kokkos::create_mirror_view_and_copy( Kokkos::HostSpace{}, _electron_beam_scan_path_segments[i]); - auto host_copy_electron_beam_heat_sources = + auto target_copy_electron_beam_heat_sources = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, _electron_beam_heat_sources); std::vector electron_beam_beams( _electron_beam_heat_sources.size()); for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) electron_beam_beams[i] = - host_copy_electron_beam_heat_sources(i).get_beam_properties(); - std::vector> + target_copy_electron_beam_heat_sources(i).get_beam_properties(); + std::vector> electron_beam_heat_source_vector; for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) electron_beam_heat_source_vector.emplace_back( electron_beam_beams[i], - ScanPath( - host_electron_beam_scan_path_segments[i])); + ScanPath( + target_electron_beam_scan_path_segments[i])); Kokkos::deep_copy( - host_electron_beam_heat_sources, - Kokkos::View *, + target_electron_beam_heat_sources, + Kokkos::View *, Kokkos::HostSpace>( electron_beam_heat_source_vector.data(), electron_beam_heat_source_vector.size())); } - Kokkos::View *, - Kokkos::HostSpace> - host_goldak_heat_sources(Kokkos::view_alloc(Kokkos::WithoutInitializing, - "goldak_heat_sources"), - _goldak_heat_sources.size()); - std::vector> - host_goldak_scan_path_segments(_goldak_scan_path_segments.size()); + Kokkos::View *, + typename TargetMemorySpace::kokkos_space> + target_goldak_heat_sources( + Kokkos::view_alloc(Kokkos::WithoutInitializing, + "goldak_heat_sources"), + _goldak_heat_sources.size()); + std::vector> + target_goldak_scan_path_segments(_goldak_scan_path_segments.size()); { for (unsigned int i = 0; i < _goldak_scan_path_segments.size(); ++i) - host_goldak_scan_path_segments[i] = Kokkos::create_mirror_view_and_copy( - Kokkos::HostSpace{}, _goldak_scan_path_segments[i]); - auto host_copy_goldak_heat_sources = Kokkos::create_mirror_view_and_copy( - Kokkos::HostSpace{}, _goldak_heat_sources); + target_goldak_scan_path_segments[i] = + Kokkos::create_mirror_view_and_copy( + typename TargetMemorySpace::kokkos_space{}, + _goldak_scan_path_segments[i]); + auto target_copy_goldak_heat_sources = + Kokkos::create_mirror_view_and_copy( + typename TargetMemorySpace::kokkos_space{}, _goldak_heat_sources); std::vector goldak_beams( _goldak_heat_sources.size()); for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) goldak_beams[i] = - host_copy_goldak_heat_sources(i).get_beam_properties(); - std::vector> + target_copy_goldak_heat_sources(i).get_beam_properties(); + std::vector> goldak_heat_source_vector; for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) goldak_heat_source_vector.emplace_back( - goldak_beams[i], ScanPath( - host_goldak_scan_path_segments[i])); + goldak_beams[i], + ScanPath(target_goldak_scan_path_segments[i])); Kokkos::deep_copy( - host_goldak_heat_sources, - Kokkos::View *, + target_goldak_heat_sources, + Kokkos::View *, Kokkos::HostSpace>(goldak_heat_source_vector.data(), goldak_heat_source_vector.size())); } - auto host_cube_heat_sources = Kokkos::create_mirror_view_and_copy( - Kokkos::HostSpace{}, _cube_heat_sources); + auto target_cube_heat_sources = Kokkos::create_mirror_view_and_copy( + typename TargetMemorySpace::kokkos_space{}, _cube_heat_sources); - return {host_electron_beam_heat_sources, host_cube_heat_sources, - host_goldak_heat_sources, host_electron_beam_scan_path_segments, - host_goldak_scan_path_segments}; + return {target_electron_beam_heat_sources, target_cube_heat_sources, + target_goldak_heat_sources, target_electron_beam_scan_path_segments, + target_goldak_scan_path_segments}; } } diff --git a/source/ThermalPhysics.templates.hh b/source/ThermalPhysics.templates.hh index ef10c9a6..d345aef6 100644 --- a/source/ThermalPhysics.templates.hh +++ b/source/ThermalPhysics.templates.hh @@ -120,7 +120,7 @@ evaluate_thermal_physics_impl( // Compute the source term. // TODO do this on the GPU - auto host_heat_sources = heat_sources.copy_to_host(); + auto host_heat_sources = heat_sources.copy_to(dealii::MemorySpace::Host{}); host_heat_sources.update_time(t); dealii::LA::distributed::Vector source( y.get_partitioner()); @@ -466,7 +466,7 @@ ThermalPhysicsset_active_fe_index(1); } - auto host_heat_sources = _heat_sources.copy_to_host(); + auto host_heat_sources = _heat_sources.copy_to(dealii::MemorySpace::Host{}); _current_source_height = host_heat_sources.get_current_height(0.0); } @@ -809,7 +809,9 @@ void ThermalPhysics< { // Update the heat source from heat_source_database to reflect changes during // the simulation (i.e. due to data assimilation) - _heat_sources.set_beam_properties(heat_source_database); + auto host_heat_sources = _heat_sources.copy_to(dealii::MemorySpace::Host{}); + host_heat_sources.set_beam_properties(heat_source_database); + _heat_sources = host_heat_sources.copy_to(MemorySpaceType{}); } template &solution, std::vector &timers) { - _current_source_height = _heat_sources.copy_to_host().get_current_height(t); + _current_source_height = + _heat_sources.copy_to(dealii::MemorySpace::Host{}).get_current_height(t); auto eval = [&](double const t, LA_Vector const &y) { return evaluate_thermal_physics(t, y, timers); }; From fce7f5cb28822972c5c90b6f3688ed4fc0b86ad1 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Tue, 14 May 2024 12:56:26 -0400 Subject: [PATCH 09/30] Use correct heat source order in set_beam_properties --- source/HeatSources.hh | 63 ++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/source/HeatSources.hh b/source/HeatSources.hh index 704c94cf..fb736061 100644 --- a/source/HeatSources.hh +++ b/source/HeatSources.hh @@ -91,12 +91,15 @@ private: Kokkos::View *, typename MemorySpace::kokkos_space> goldak_heat_sources, - std::vector< - Kokkos::View> - electron_beam_scan_path_segments, - std::vector< - Kokkos::View> - goldak_scan_path_segments); + std::vector> const + &electron_beam_scan_path_segments, + std::vector> const + &goldak_scan_path_segments, + std::vector const &electron_beam_indices, + std::vector const &cube_indices, + std::vector const &goldak_indices); Kokkos::View *, typename MemorySpace::kokkos_space> @@ -112,6 +115,9 @@ private: std::vector< Kokkos::View> _goldak_scan_path_segments; + std::vector _electron_beam_indices; + std::vector _cube_indices; + std::vector _goldak_indices; }; template @@ -137,6 +143,7 @@ HeatSources::HeatSources( ScanPath::extract_scan_paths( beam_database.get("scan_path_file"), beam_database.get("scan_path_file_format"))); + _goldak_indices.push_back(i); } else if (type == "electron_beam") { @@ -145,10 +152,12 @@ HeatSources::HeatSources( ScanPath::extract_scan_paths( beam_database.get("scan_path_file"), beam_database.get("scan_path_file_format"))); + _electron_beam_indices.push_back(i); } else if (type == "cube") { cube_heat_sources.emplace_back(beam_database); + _cube_indices.push_back(i); } else { @@ -226,17 +235,22 @@ HeatSources::HeatSources( Kokkos::View *, typename MemorySpace::kokkos_space> goldak_heat_sources, - std::vector< - Kokkos::View> - electron_beam_scan_path_segments, - std::vector< - Kokkos::View> - goldak_scan_path_segments) + std::vector> const + &electron_beam_scan_path_segments, + std::vector> const + &goldak_scan_path_segments, + std::vector const &electron_beam_indices, + std::vector const &cube_indices, + std::vector const &goldak_indices) : _electron_beam_heat_sources(electron_beam_heat_sources), _cube_heat_sources(cube_heat_sources), _goldak_heat_sources(goldak_heat_sources), _electron_beam_scan_path_segments(electron_beam_scan_path_segments), - _goldak_scan_path_segments(goldak_scan_path_segments) + _goldak_scan_path_segments(goldak_scan_path_segments), + _electron_beam_indices(electron_beam_indices), + _cube_indices(cube_indices), _goldak_indices(goldak_indices) { } @@ -316,9 +330,7 @@ template void HeatSources::set_beam_properties( boost::property_tree::ptree const &heat_source_database) { - unsigned int source_index = 0; - - auto set_properties = [&](auto &source) + auto set_properties = [&](auto &source, int const source_index) { // PropertyTreeInput sources.beam_X boost::property_tree::ptree const &beam_database = @@ -329,16 +341,14 @@ void HeatSources::set_beam_properties( if (type == "goldak" || type == "electron_beam") source.set_beam_properties(beam_database); - - source_index++; }; for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) - set_properties(_electron_beam_heat_sources[i]); + set_properties(_electron_beam_heat_sources[i], _electron_beam_indices[i]); for (unsigned int i = 0; i < _cube_heat_sources.size(); ++i) - set_properties(_cube_heat_sources[i]); + set_properties(_cube_heat_sources[i], _cube_indices[i]); for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) - set_properties(_goldak_heat_sources[i]); + set_properties(_goldak_heat_sources[i], _goldak_indices[i]); } template @@ -428,9 +438,14 @@ HeatSources HeatSources::copy_to( auto target_cube_heat_sources = Kokkos::create_mirror_view_and_copy( typename TargetMemorySpace::kokkos_space{}, _cube_heat_sources); - return {target_electron_beam_heat_sources, target_cube_heat_sources, - target_goldak_heat_sources, target_electron_beam_scan_path_segments, - target_goldak_scan_path_segments}; + return {target_electron_beam_heat_sources, + target_cube_heat_sources, + target_goldak_heat_sources, + target_electron_beam_scan_path_segments, + target_goldak_scan_path_segments, + _cube_indices, + _electron_beam_indices, + _goldak_indices}; } } From 91938625e63719a6911b109c89baf3c71aaabb5b Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Tue, 14 May 2024 14:53:26 -0400 Subject: [PATCH 10/30] Fix order of template parameters --- application/adamantine.hh | 14 +-- source/HeatSources.hh | 157 +++++++++++++------------- source/ScanPath.cc | 31 ++--- source/ThermalOperator.hh | 4 +- source/ThermalOperator.templates.hh | 2 +- source/ThermalPhysics.hh | 6 +- source/ThermalPhysics.templates.hh | 4 +- source/ThermalPhysicsInterface.hh | 2 +- source/material_deposition.cc | 6 +- source/material_deposition.hh | 2 +- tests/test_implicit_operator.cc | 2 +- tests/test_post_processor.cc | 2 +- tests/test_thermal_operator.cc | 12 +- tests/test_thermal_operator_device.cc | 2 +- 14 files changed, 125 insertions(+), 121 deletions(-) diff --git a/application/adamantine.hh b/application/adamantine.hh index 08901622..6ba159cf 100644 --- a/application/adamantine.hh +++ b/application/adamantine.hh @@ -520,7 +520,7 @@ compute_cells_to_refine( dealii::parallel::distributed::Triangulation &triangulation, double const time, double const next_refinement_time, unsigned int const n_time_steps, - adamantine::HeatSources &heat_sources, + adamantine::HeatSources &heat_sources, double const current_source_height, double const refinement_beam_cutoff) { @@ -569,7 +569,7 @@ void refine_mesh( adamantine::MaterialProperty &material_properties, dealii::LA::distributed::Vector &solution, - adamantine::HeatSources const &heat_sources, + adamantine::HeatSources const &heat_sources, double const time, double const next_refinement_time, unsigned int const time_steps_refinement, boost::property_tree::ptree const &refinement_database) @@ -606,7 +606,7 @@ void refine_mesh( const double refinement_beam_cutoff = refinement_database.get("beam_cutoff", 1.0e-15); - adamantine::HeatSources host_heat_sources = heat_sources.copy_to(dealii::MemorySpace::Host{}); + adamantine::HeatSources host_heat_sources = heat_sources.copy_to(dealii::MemorySpace::Host{}); for (unsigned int i = 0; i < n_refinements; ++i) { @@ -660,7 +660,7 @@ void refine_mesh( adamantine::MaterialProperty &material_properties, dealii::LA::distributed::Vector &solution, - adamantine::HeatSources const &heat_sources, + adamantine::HeatSources const &heat_sources, double const time, double const next_refinement_time, unsigned int const time_steps_refinement, boost::property_tree::ptree const &refinement_database) @@ -758,7 +758,7 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database, // Create ThermalPhysics if necessary std::unique_ptr> thermal_physics; - adamantine::HeatSources heat_sources; + adamantine::HeatSources heat_sources; if (use_thermal_physics) { // PropertyTreeInput discretization.thermal.fe_degree @@ -935,7 +935,7 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database, mechanical_physics, displacement, material_properties, timers); ++n_time_step; - adamantine::HeatSources host_heat_sources = heat_sources.copy_to(dealii::MemorySpace::Host{}); + adamantine::HeatSources host_heat_sources = heat_sources.copy_to(dealii::MemorySpace::Host{}); // Create the bounding boxes used for material deposition auto [material_deposition_boxes, deposition_times, deposition_cos, @@ -1365,7 +1365,7 @@ run_ensemble(MPI_Comm const &global_communicator, adamantine::ThermalPhysicsInterface>> thermal_physics_ensemble(local_ensemble_size); - std::vector> + std::vector> heat_sources_ensemble(local_ensemble_size); std::vector>> geometry_ensemble; diff --git a/source/HeatSources.hh b/source/HeatSources.hh index fb736061..3aa98414 100644 --- a/source/HeatSources.hh +++ b/source/HeatSources.hh @@ -17,7 +17,7 @@ namespace adamantine { -template +template class HeatSources { public: @@ -34,9 +34,9 @@ public: /** * Return a copy of this instance in the target memory space. */ - template - HeatSources - copy_to(TargetMemorySpace target_memory_space) const; + template + HeatSources + copy_to(TargetMemorySpaceType target_memory_space) const; /** * Set the time variable. @@ -60,7 +60,7 @@ public: /** * Return the scan paths for the heat source. */ - std::vector> get_scan_paths() const; + std::vector> get_scan_paths() const; /** * (Re)sets the BeamHeatSourceProperties member variable, necessary if the @@ -76,52 +76,53 @@ public: double get_current_height(double time) const; private: - friend class HeatSources; - friend class HeatSources; + friend class HeatSources; + friend class HeatSources; /** * Private constructor used by copy_to_host. */ HeatSources( - Kokkos::View *, - typename MemorySpace::kokkos_space> + Kokkos::View *, + typename MemorySpaceType::kokkos_space> electron_beam_heat_sources, - Kokkos::View *, typename MemorySpace::kokkos_space> + Kokkos::View *, + typename MemorySpaceType::kokkos_space> cube_heat_sources, - Kokkos::View *, - typename MemorySpace::kokkos_space> + Kokkos::View *, + typename MemorySpaceType::kokkos_space> goldak_heat_sources, std::vector> const + typename MemorySpaceType::kokkos_space>> const &electron_beam_scan_path_segments, std::vector> const + typename MemorySpaceType::kokkos_space>> const &goldak_scan_path_segments, std::vector const &electron_beam_indices, std::vector const &cube_indices, std::vector const &goldak_indices); - Kokkos::View *, - typename MemorySpace::kokkos_space> + Kokkos::View *, + typename MemorySpaceType::kokkos_space> _electron_beam_heat_sources; - Kokkos::View *, typename MemorySpace::kokkos_space> + Kokkos::View *, typename MemorySpaceType::kokkos_space> _cube_heat_sources; - Kokkos::View *, - typename MemorySpace::kokkos_space> + Kokkos::View *, + typename MemorySpaceType::kokkos_space> _goldak_heat_sources; std::vector< - Kokkos::View> + Kokkos::View> _electron_beam_scan_path_segments; std::vector< - Kokkos::View> + Kokkos::View> _goldak_scan_path_segments; std::vector _electron_beam_indices; std::vector _cube_indices; std::vector _goldak_indices; }; -template -HeatSources::HeatSources( +template +HeatSources::HeatSources( boost::property_tree::ptree const &source_database) { unsigned int const n_beams = source_database.get("n_beams"); @@ -140,7 +141,7 @@ HeatSources::HeatSources( { goldak_beams.emplace_back(beam_database); goldak_scan_path_segments.push_back( - ScanPath::extract_scan_paths( + ScanPath::extract_scan_paths( beam_database.get("scan_path_file"), beam_database.get("scan_path_file_format"))); _goldak_indices.push_back(i); @@ -149,7 +150,7 @@ HeatSources::HeatSources( { electron_beam_beams.emplace_back(beam_database); electron_beam_scan_path_segments.push_back( - ScanPath::extract_scan_paths( + ScanPath::extract_scan_paths( beam_database.get("scan_path_file"), beam_database.get("scan_path_file_format"))); _electron_beam_indices.push_back(i); @@ -167,7 +168,7 @@ HeatSources::HeatSources( } } - std::vector> goldak_heat_sources; + std::vector> goldak_heat_sources; for (unsigned int i = 0; i < goldak_scan_path_segments.size(); ++i) { _goldak_scan_path_segments.emplace_back( @@ -180,10 +181,10 @@ HeatSources::HeatSources( goldak_scan_path_segments[i].size())); goldak_heat_sources.emplace_back( goldak_beams[i], - ScanPath(_goldak_scan_path_segments.back())); + ScanPath(_goldak_scan_path_segments.back())); } - std::vector> + std::vector> electron_beam_heat_sources; for (unsigned int i = 0; i < electron_beam_scan_path_segments.size(); ++i) { @@ -198,7 +199,7 @@ HeatSources::HeatSources( electron_beam_scan_path_segments[i].size())); electron_beam_heat_sources.emplace_back( electron_beam_beams[i], - ScanPath(_electron_beam_scan_path_segments.back())); + ScanPath(_electron_beam_scan_path_segments.back())); } _goldak_heat_sources = decltype(_goldak_heat_sources)( @@ -213,11 +214,11 @@ HeatSources::HeatSources( cube_heat_sources.size()); Kokkos::deep_copy( _goldak_heat_sources, - Kokkos::View *, Kokkos::HostSpace>( + Kokkos::View *, Kokkos::HostSpace>( goldak_heat_sources.data(), goldak_heat_sources.size())); Kokkos::deep_copy( _electron_beam_heat_sources, - Kokkos::View *, + Kokkos::View *, Kokkos::HostSpace>(electron_beam_heat_sources.data(), electron_beam_heat_sources.size())); Kokkos::deep_copy(_cube_heat_sources, @@ -225,21 +226,21 @@ HeatSources::HeatSources( cube_heat_sources.data(), cube_heat_sources.size())); } -template -HeatSources::HeatSources( - Kokkos::View *, - typename MemorySpace::kokkos_space> +template +HeatSources::HeatSources( + Kokkos::View *, + typename MemorySpaceType::kokkos_space> electron_beam_heat_sources, - Kokkos::View *, typename MemorySpace::kokkos_space> + Kokkos::View *, typename MemorySpaceType::kokkos_space> cube_heat_sources, - Kokkos::View *, - typename MemorySpace::kokkos_space> + Kokkos::View *, + typename MemorySpaceType::kokkos_space> goldak_heat_sources, std::vector> const + typename MemorySpaceType::kokkos_space>> const &electron_beam_scan_path_segments, std::vector> const + typename MemorySpaceType::kokkos_space>> const &goldak_scan_path_segments, std::vector const &electron_beam_indices, std::vector const &cube_indices, @@ -254,8 +255,8 @@ HeatSources::HeatSources( { } -template -KOKKOS_FUNCTION void HeatSources::update_time(double time) +template +KOKKOS_FUNCTION void HeatSources::update_time(double time) { for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) _electron_beam_heat_sources(i).update_time(time); @@ -265,10 +266,10 @@ KOKKOS_FUNCTION void HeatSources::update_time(double time) _goldak_heat_sources(i).update_time(time); } -template +template KOKKOS_FUNCTION double -HeatSources::value(dealii::Point const &point, - double const height) const +HeatSources::value(dealii::Point const &point, + double const height) const { double value = 0; for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) @@ -280,10 +281,10 @@ HeatSources::value(dealii::Point const &point, return value; } -template +template KOKKOS_FUNCTION double -HeatSources::max_value(dealii::Point const &point, - double const height) const +HeatSources::max_value(dealii::Point const &point, + double const height) const { double value = 0; for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) @@ -296,11 +297,11 @@ HeatSources::max_value(dealii::Point const &point, return value; } -template -std::vector> -HeatSources::get_scan_paths() const +template +std::vector> +HeatSources::get_scan_paths() const { - std::vector> scan_paths; + std::vector> scan_paths; for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) scan_paths.push_back(_electron_beam_heat_sources(i).get_scan_path()); for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) @@ -308,8 +309,8 @@ HeatSources::get_scan_paths() const return scan_paths; } -template -double HeatSources::get_current_height(double time) const +template +double HeatSources::get_current_height(double time) const { // Right now this is just the maximum heat source height, which can lead to // unexpected behavior for different sources with different heights. @@ -326,8 +327,8 @@ double HeatSources::get_current_height(double time) const return temp_height; } -template -void HeatSources::set_beam_properties( +template +void HeatSources::set_beam_properties( boost::property_tree::ptree const &heat_source_database) { auto set_properties = [&](auto &source, int const source_index) @@ -351,23 +352,24 @@ void HeatSources::set_beam_properties( set_properties(_goldak_heat_sources[i], _goldak_indices[i]); } -template -template -HeatSources HeatSources::copy_to( - TargetMemorySpace /*target_memory_space*/) const +template +template +HeatSources +HeatSources::copy_to( + TargetMemorySpaceType /*target_memory_space*/) const { - if constexpr (std::is_same_v) + if constexpr (std::is_same_v) return *this; else { - Kokkos::View *, - typename TargetMemorySpace::kokkos_space> + Kokkos::View *, + typename TargetMemorySpaceType::kokkos_space> target_electron_beam_heat_sources( Kokkos::view_alloc(Kokkos::WithoutInitializing, "electron_beam_heat_sources"), _electron_beam_heat_sources.size()); std::vector> + typename TargetMemorySpaceType::kokkos_space>> target_electron_beam_scan_path_segments( _electron_beam_scan_path_segments.size()); { @@ -384,59 +386,60 @@ HeatSources HeatSources::copy_to( for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) electron_beam_beams[i] = target_copy_electron_beam_heat_sources(i).get_beam_properties(); - std::vector> + std::vector> electron_beam_heat_source_vector; for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) electron_beam_heat_source_vector.emplace_back( electron_beam_beams[i], - ScanPath( + ScanPath( target_electron_beam_scan_path_segments[i])); Kokkos::deep_copy( target_electron_beam_heat_sources, - Kokkos::View *, + Kokkos::View *, Kokkos::HostSpace>( electron_beam_heat_source_vector.data(), electron_beam_heat_source_vector.size())); } - Kokkos::View *, - typename TargetMemorySpace::kokkos_space> + Kokkos::View *, + typename TargetMemorySpaceType::kokkos_space> target_goldak_heat_sources( Kokkos::view_alloc(Kokkos::WithoutInitializing, "goldak_heat_sources"), _goldak_heat_sources.size()); std::vector> + typename TargetMemorySpaceType::kokkos_space>> target_goldak_scan_path_segments(_goldak_scan_path_segments.size()); { for (unsigned int i = 0; i < _goldak_scan_path_segments.size(); ++i) target_goldak_scan_path_segments[i] = Kokkos::create_mirror_view_and_copy( - typename TargetMemorySpace::kokkos_space{}, + typename TargetMemorySpaceType::kokkos_space{}, _goldak_scan_path_segments[i]); auto target_copy_goldak_heat_sources = Kokkos::create_mirror_view_and_copy( - typename TargetMemorySpace::kokkos_space{}, _goldak_heat_sources); + typename TargetMemorySpaceType::kokkos_space{}, + _goldak_heat_sources); std::vector goldak_beams( _goldak_heat_sources.size()); for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) goldak_beams[i] = target_copy_goldak_heat_sources(i).get_beam_properties(); - std::vector> + std::vector> goldak_heat_source_vector; for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) goldak_heat_source_vector.emplace_back( - goldak_beams[i], - ScanPath(target_goldak_scan_path_segments[i])); + goldak_beams[i], ScanPath( + target_goldak_scan_path_segments[i])); Kokkos::deep_copy( target_goldak_heat_sources, - Kokkos::View *, + Kokkos::View *, Kokkos::HostSpace>(goldak_heat_source_vector.data(), goldak_heat_source_vector.size())); } auto target_cube_heat_sources = Kokkos::create_mirror_view_and_copy( - typename TargetMemorySpace::kokkos_space{}, _cube_heat_sources); + typename TargetMemorySpaceType::kokkos_space{}, _cube_heat_sources); return {target_electron_beam_heat_sources, target_cube_heat_sources, diff --git a/source/ScanPath.cc b/source/ScanPath.cc index 274063b6..85a97f84 100644 --- a/source/ScanPath.cc +++ b/source/ScanPath.cc @@ -15,10 +15,10 @@ namespace adamantine { -template +template std::vector -ScanPath::extract_scan_paths(std::string scan_path_file, - std::string file_format) +ScanPath::extract_scan_paths(std::string scan_path_file, + std::string file_format) { // Parse the scan path wait_for_file(scan_path_file, @@ -40,9 +40,9 @@ ScanPath::extract_scan_paths(std::string scan_path_file, return {}; } -template +template std::vector -ScanPath::load_segment_scan_path(std::string scan_path_file) +ScanPath::load_segment_scan_path(std::string scan_path_file) { std::vector segment_list; @@ -122,9 +122,10 @@ ScanPath::load_segment_scan_path(std::string scan_path_file) return segment_list; } -template +template std::vector -ScanPath::load_event_series_scan_path(std::string scan_path_file) +ScanPath::load_event_series_scan_path( + std::string scan_path_file) { std::vector segment_list; @@ -160,8 +161,8 @@ ScanPath::load_event_series_scan_path(std::string scan_path_file) return segment_list; } -template -void ScanPath::update_current_segment_info( +template +void ScanPath::update_current_segment_info( double time, dealii::Point<3> &segment_start_point, double &segment_start_time) const { @@ -184,8 +185,8 @@ void ScanPath::update_current_segment_info( } } -template -dealii::Point<3> ScanPath::value(double const &time) const +template +dealii::Point<3> ScanPath::value(double const &time) const { // If the current time is after the scan path data is over, return a point // that is (presumably) out of the domain. @@ -212,8 +213,8 @@ dealii::Point<3> ScanPath::value(double const &time) const return position; } -template -double ScanPath::get_power_modifier(double const &time) const +template +double ScanPath::get_power_modifier(double const &time) const { // If the current time is after the scan path data is over, set the power to // zero. @@ -228,8 +229,8 @@ double ScanPath::get_power_modifier(double const &time) const return _segment_list[_current_segment].power_modifier; } -template -std::vector ScanPath::get_segment_list() const +template +std::vector ScanPath::get_segment_list() const { return {&_segment_list[0], &_segment_list[0] + _segment_list.size()}; } diff --git a/source/ThermalOperator.hh b/source/ThermalOperator.hh index ea769243..15a3afec 100644 --- a/source/ThermalOperator.hh +++ b/source/ThermalOperator.hh @@ -31,7 +31,7 @@ public: ThermalOperator(MPI_Comm const &communicator, BoundaryType boundary_type, MaterialProperty &material_properties, - HeatSources const &heat_sources); + HeatSources const &heat_sources); /** * Associate the AffineConstraints and the MatrixFree objects to the @@ -195,7 +195,7 @@ private: /** * Vector of heat sources. */ - HeatSources _heat_sources; + HeatSources _heat_sources; /** * Underlying MatrixFree object. */ diff --git a/source/ThermalOperator.templates.hh b/source/ThermalOperator.templates.hh index 39933f32..82c71b3b 100644 --- a/source/ThermalOperator.templates.hh +++ b/source/ThermalOperator.templates.hh @@ -33,7 +33,7 @@ ThermalOperator &material_properties, - HeatSources const &heat_sources) + HeatSources const &heat_sources) : _communicator(communicator), _boundary_type(boundary_type), _material_properties(material_properties), _heat_sources(heat_sources), _inverse_mass_matrix( diff --git a/source/ThermalPhysics.hh b/source/ThermalPhysics.hh index 625ad05e..da27ac5f 100644 --- a/source/ThermalPhysics.hh +++ b/source/ThermalPhysics.hh @@ -112,7 +112,7 @@ public: dealii::AffineConstraints &get_affine_constraints() override; - HeatSources &get_heat_sources() override; + HeatSources &get_heat_sources() override; unsigned int get_fe_degree() const override; @@ -220,7 +220,7 @@ private: /** * Vector of heat sources. */ - mutable HeatSources _heat_sources; + mutable HeatSources _heat_sources; /** * Shared pointer to the underlying ThermalOperator. */ @@ -324,7 +324,7 @@ ThermalPhysics -inline HeatSources & +inline HeatSources & ThermalPhysics::get_heat_sources() { diff --git a/source/ThermalPhysics.templates.hh b/source/ThermalPhysics.templates.hh index d345aef6..067f54bd 100644 --- a/source/ThermalPhysics.templates.hh +++ b/source/ThermalPhysics.templates.hh @@ -95,7 +95,7 @@ evaluate_thermal_physics_impl( &thermal_operator, dealii::hp::FECollection const &fe_collection, double const t, dealii::DoFHandler const &dof_handler, - HeatSources &heat_sources, + HeatSources &heat_sources, double current_source_height, BoundaryType boundary_type, MaterialProperty &material_properties, @@ -289,7 +289,7 @@ ThermalPhysics(source_database); + _heat_sources = HeatSources(source_database); // Create the boundary condition type // PropertyTreeInput boundary.type diff --git a/source/ThermalPhysicsInterface.hh b/source/ThermalPhysicsInterface.hh index 6582fc97..778973a2 100644 --- a/source/ThermalPhysicsInterface.hh +++ b/source/ThermalPhysicsInterface.hh @@ -172,7 +172,7 @@ public: /** * Return the heat sources. */ - virtual HeatSources &get_heat_sources() = 0; + virtual HeatSources &get_heat_sources() = 0; /** * Return the degree of the finite element. diff --git a/source/material_deposition.cc b/source/material_deposition.cc index cc4b3472..5b633f34 100644 --- a/source/material_deposition.cc +++ b/source/material_deposition.cc @@ -25,7 +25,7 @@ std::tuple>, std::vector, std::vector, std::vector> create_material_deposition_boxes( boost::property_tree::ptree const &geometry_database, - HeatSources &heat_sources) + HeatSources &heat_sources) { // PropertyTreeInput geometry.material_deposition bool material_deposition = @@ -359,12 +359,12 @@ template std::tuple>, std::vector, std::vector, std::vector> create_material_deposition_boxes( boost::property_tree::ptree const &geometry_database, - HeatSources &heat_sources); + HeatSources<2, dealii::MemorySpace::Host> &heat_sources); template std::tuple>, std::vector, std::vector, std::vector> create_material_deposition_boxes( boost::property_tree::ptree const &geometry_database, - HeatSources &heat_sources); + HeatSources<3, dealii::MemorySpace::Host> &heat_sources); template std::tuple>, std::vector, std::vector, std::vector> diff --git a/source/material_deposition.hh b/source/material_deposition.hh index fb37dd40..370b8f06 100644 --- a/source/material_deposition.hh +++ b/source/material_deposition.hh @@ -26,7 +26,7 @@ std::tuple>, std::vector, std::vector, std::vector> create_material_deposition_boxes( boost::property_tree::ptree const &geometry_database, - HeatSources &heat_sources); + HeatSources &heat_sources); /** * Read the material deposition file and return the bounding boxes, the * deposition times, the cosine of the deposition angles, and the sine of the diff --git a/tests/test_implicit_operator.cc b/tests/test_implicit_operator.cc index 48080281..dbb41b3c 100644 --- a/tests/test_implicit_operator.cc +++ b/tests/test_implicit_operator.cc @@ -82,7 +82,7 @@ BOOST_AUTO_TEST_CASE(implicit_operator) beam_database.put("beam_0.max_power", 10.); beam_database.put("beam_0.scan_path_file", "scan_path.txt"); beam_database.put("beam_0.scan_path_file_format", "segment"); - adamantine::HeatSources heat_sources( + adamantine::HeatSources<2, dealii::MemorySpace::Host> heat_sources( beam_database); // Initialize the ThermalOperator diff --git a/tests/test_post_processor.cc b/tests/test_post_processor.cc index 5fec1038..fb048b9a 100644 --- a/tests/test_post_processor.cc +++ b/tests/test_post_processor.cc @@ -81,7 +81,7 @@ BOOST_AUTO_TEST_CASE(thermal_post_processor) beam_database.put("beam_0.max_power", 10.); beam_database.put("beam_0.scan_path_file", "scan_path.txt"); beam_database.put("beam_0.scan_path_file_format", "segment"); - adamantine::HeatSources heat_sources( + adamantine::HeatSources<2, dealii::MemorySpace::Host> heat_sources( beam_database); // Initialize the ThermalOperator diff --git a/tests/test_thermal_operator.cc b/tests/test_thermal_operator.cc index 617b5581..a0e7b67a 100644 --- a/tests/test_thermal_operator.cc +++ b/tests/test_thermal_operator.cc @@ -96,7 +96,7 @@ BOOST_AUTO_TEST_CASE(thermal_operator, *utf::tolerance(1e-15)) beam_database.put("beam_0.max_power", 10.); beam_database.put("beam_0.scan_path_file", "scan_path.txt"); beam_database.put("beam_0.scan_path_file_format", "segment"); - adamantine::HeatSources heat_sources( + adamantine::HeatSources<2, dealii::MemorySpace::Host> heat_sources( beam_database); // Initialize the ThermalOperator @@ -201,7 +201,7 @@ BOOST_AUTO_TEST_CASE(spmv, *utf::tolerance(1e-12)) beam_database.put("beam_0.max_power", 10.); beam_database.put("beam_0.scan_path_file", "scan_path.txt"); beam_database.put("beam_0.scan_path_file_format", "segment"); - adamantine::HeatSources heat_sources( + adamantine::HeatSources<2, dealii::MemorySpace::Host> heat_sources( beam_database); // Initialize the ThermalOperator @@ -310,7 +310,7 @@ BOOST_AUTO_TEST_CASE(spmv_anisotropic, *utf::tolerance(1e-12)) beam_database.put("beam_0.max_power", 10.); beam_database.put("beam_0.scan_path_file", "scan_path.txt"); beam_database.put("beam_0.scan_path_file_format", "segment"); - adamantine::HeatSources heat_sources( + adamantine::HeatSources<2, dealii::MemorySpace::Host> heat_sources( beam_database); // Initialize the ThermalOperator @@ -450,7 +450,7 @@ BOOST_AUTO_TEST_CASE(spmv_anisotropic_angle, *utf::tolerance(1e-10)) mat_prop_database); // Create the heat sources - adamantine::HeatSources heat_sources; + adamantine::HeatSources<3, dealii::MemorySpace::Host> heat_sources; // Initialize the ThermalOperator adamantine::ThermalOperator<3, false, 1, 2, adamantine::SolidLiquidPowder, @@ -617,7 +617,7 @@ BOOST_AUTO_TEST_CASE(spmv_rad, *utf::tolerance(1e-12)) beam_database.put("beam_0.max_power", 10.); beam_database.put("beam_0.scan_path_file", "scan_path.txt"); beam_database.put("beam_0.scan_path_file_format", "segment"); - adamantine::HeatSources heat_sources( + adamantine::HeatSources<2, dealii::MemorySpace::Host> heat_sources( beam_database); // Initialize the ThermalOperator @@ -801,7 +801,7 @@ BOOST_AUTO_TEST_CASE(spmv_conv, *utf::tolerance(1e-12)) beam_database.put("beam_0.max_power", 10.); beam_database.put("beam_0.scan_path_file", "scan_path.txt"); beam_database.put("beam_0.scan_path_file_format", "segment"); - adamantine::HeatSources heat_sources( + adamantine::HeatSources<2, dealii::MemorySpace::Host> heat_sources( beam_database); // Initialize the ThermalOperator diff --git a/tests/test_thermal_operator_device.cc b/tests/test_thermal_operator_device.cc index 697ca3cb..a015c633 100644 --- a/tests/test_thermal_operator_device.cc +++ b/tests/test_thermal_operator_device.cc @@ -287,7 +287,7 @@ BOOST_AUTO_TEST_CASE(mf_spmv, *utf::tolerance(1.5e-12)) beam_database.put("beam_0.max_power", 10.); beam_database.put("beam_0.scan_path_file", "scan_path.txt"); beam_database.put("beam_0.scan_path_file_format", "segment"); - adamantine::HeatSources heat_sources( + adamantine::HeatSources<2, dealii::MemorySpace::Host> heat_sources( beam_database); // Initialize the ThermalOperator From 7b888246d5b844a2475919b61fb25d55eda89269 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Fri, 17 May 2024 11:27:52 -0400 Subject: [PATCH 11/30] Fix copy_to when targeting GPUs --- source/HeatSources.hh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/HeatSources.hh b/source/HeatSources.hh index 3aa98414..e5d4704d 100644 --- a/source/HeatSources.hh +++ b/source/HeatSources.hh @@ -377,7 +377,8 @@ HeatSources::copy_to( ++i) target_electron_beam_scan_path_segments[i] = Kokkos::create_mirror_view_and_copy( - Kokkos::HostSpace{}, _electron_beam_scan_path_segments[i]); + typename TargetMemorySpaceType::kokkos_space{}, + _electron_beam_scan_path_segments[i]); auto target_copy_electron_beam_heat_sources = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, _electron_beam_heat_sources); From ac350837e381c2001aa075301679c0c62149e3fa Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Mon, 20 May 2024 17:08:58 -0400 Subject: [PATCH 12/30] Remove KOKKOS_FUNCTION from HeatSources.hh --- source/HeatSources.hh | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/source/HeatSources.hh b/source/HeatSources.hh index e5d4704d..500d8cf2 100644 --- a/source/HeatSources.hh +++ b/source/HeatSources.hh @@ -41,21 +41,19 @@ public: /** * Set the time variable. */ - KOKKOS_FUNCTION void update_time(double time); + void update_time(double time); /** * Compute the cumulative heat source at a given point at a given time given * the current height of the object being manufactured. */ - KOKKOS_FUNCTION double value(dealii::Point const &point, - double const height) const; + double value(dealii::Point const &point, double const height) const; /** * Compute the maxiumum heat source at a given point at a given time given the * current height of the object being manufactured. */ - KOKKOS_FUNCTION double max_value(dealii::Point const &point, - double const height) const; + double max_value(dealii::Point const &point, double const height) const; /** * Return the scan paths for the heat source. @@ -256,7 +254,7 @@ HeatSources::HeatSources( } template -KOKKOS_FUNCTION void HeatSources::update_time(double time) +void HeatSources::update_time(double time) { for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) _electron_beam_heat_sources(i).update_time(time); @@ -267,9 +265,8 @@ KOKKOS_FUNCTION void HeatSources::update_time(double time) } template -KOKKOS_FUNCTION double -HeatSources::value(dealii::Point const &point, - double const height) const +double HeatSources::value(dealii::Point const &point, + double const height) const { double value = 0; for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) @@ -282,7 +279,7 @@ HeatSources::value(dealii::Point const &point, } template -KOKKOS_FUNCTION double +double HeatSources::max_value(dealii::Point const &point, double const height) const { From 69394d1fb0ff37d7d9cf5a8fbda2d42ed74a630a Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Mon, 20 May 2024 17:27:47 -0400 Subject: [PATCH 13/30] Restore lac/la_vector.h --- source/DataAssimilator.hh | 2 +- source/MaterialProperty.hh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/DataAssimilator.hh b/source/DataAssimilator.hh index 9fcb494f..b2b9a746 100644 --- a/source/DataAssimilator.hh +++ b/source/DataAssimilator.hh @@ -14,7 +14,7 @@ #include #include #include -// #include +#include #include #include #include diff --git a/source/MaterialProperty.hh b/source/MaterialProperty.hh index 153a4c9c..525fdedd 100644 --- a/source/MaterialProperty.hh +++ b/source/MaterialProperty.hh @@ -22,7 +22,7 @@ #include #include #include -// #include +#include #include From b467051dab76c1f91fe39b4b6ebe087001d02003 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Thu, 6 Jun 2024 11:56:07 -0400 Subject: [PATCH 14/30] Introduce update_scan_paths --- application/adamantine.hh | 19 +++--- source/DataAssimilator.hh | 1 - source/ElectronBeamHeatSource.hh | 5 ++ source/GoldakHeatSource.hh | 5 ++ source/HeatSources.hh | 109 +++++++++++++++++++++++-------- source/MaterialProperty.hh | 1 - source/ScanPath.cc | 31 ++++----- source/ScanPath.hh | 31 ++------- 8 files changed, 121 insertions(+), 81 deletions(-) diff --git a/application/adamantine.hh b/application/adamantine.hh index b2cd84cf..c4a692d6 100644 --- a/application/adamantine.hh +++ b/application/adamantine.hh @@ -775,10 +775,10 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database, heat_sources = thermal_physics->get_heat_sources(); // Store the current end time of each heat source and set a flag that the // scan path has changed - for (auto const &source : heat_sources) + auto const& scan_paths = heat_sources.get_scan_paths(); + for (auto const &scan_path : scan_paths) { - scan_path_end.emplace_back( - source->get_scan_path().get_segment_list().back().end_time, true); + scan_path_end.emplace_back(scan_path.get_segment_list().back().end_time, true); } post_processor_database.put("thermal_output", true); } @@ -1026,14 +1026,15 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database, } if (scan_path_updated) { + adamantine::HeatSources host_heat_sources = heat_sources.copy_to(dealii::MemorySpace::Host{}); + host_heat_sources.update_scan_paths(); + heat_sources = host_heat_sources.copy_to(MemorySpaceType{}); + + auto const& scan_paths = heat_sources.get_scan_paths(); for (unsigned int s = 0; s < scan_path_end.size(); ++s) { - // Read the scan path file - heat_sources[s]->get_scan_path().read_file(); - // Update scan_path_end - double new_end_time = heat_sources[s] - ->get_scan_path() + double new_end_time = scan_paths[s] .get_segment_list() .back() .end_time; @@ -1044,7 +1045,7 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database, std::tie(material_deposition_boxes, deposition_times, deposition_cos, deposition_sin) = adamantine::create_material_deposition_boxes(geometry_database, - heat_sources); + host_heat_sources); } auto activation_start = diff --git a/source/DataAssimilator.hh b/source/DataAssimilator.hh index b2b9a746..27355dbb 100644 --- a/source/DataAssimilator.hh +++ b/source/DataAssimilator.hh @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/source/ElectronBeamHeatSource.hh b/source/ElectronBeamHeatSource.hh index 17a859ba..d698d253 100644 --- a/source/ElectronBeamHeatSource.hh +++ b/source/ElectronBeamHeatSource.hh @@ -53,6 +53,11 @@ public: */ ScanPath const &get_scan_path() const; + void set_scan_path(ScanPath const scan_path) + { + _scan_path = scan_path; + } + /** * Compute the current height of the where the heat source meets the material * (i.e. the current scan path height). diff --git a/source/GoldakHeatSource.hh b/source/GoldakHeatSource.hh index 51f5b9ed..acbf17e9 100644 --- a/source/GoldakHeatSource.hh +++ b/source/GoldakHeatSource.hh @@ -53,6 +53,11 @@ public: */ ScanPath const &get_scan_path() const; + void set_scan_path(ScanPath const scan_path) + { + _scan_path = scan_path; + } + /** * Compute the current height of the where the heat source meets the material * (i.e. the current scan path height). diff --git a/source/HeatSources.hh b/source/HeatSources.hh index 500d8cf2..66a80f51 100644 --- a/source/HeatSources.hh +++ b/source/HeatSources.hh @@ -43,6 +43,14 @@ public: */ void update_time(double time); + /** + * Update the scan paths for all heat sources reading again from the + * respective files. + */ + template + std::enable_if_t> + update_scan_paths(); + /** * Compute the cumulative heat source at a given point at a given time given * the current height of the object being manufactured. @@ -77,6 +85,11 @@ private: friend class HeatSources; friend class HeatSources; + /** + * Private helper for update_scan_paths + */ + void internal_update_scan_paths(); + /** * Private constructor used by copy_to_host. */ @@ -117,8 +130,63 @@ private: std::vector _electron_beam_indices; std::vector _cube_indices; std::vector _goldak_indices; + + std::vector _goldak_scan_files; + std::vector _electron_beam_scan_files; + std::vector _goldak_scan_formats; + std::vector _electron_beam_scan_formats; }; +template +void HeatSources::internal_update_scan_paths() +{ + std::vector scan_path_segments; + _goldak_scan_path_segments.clear(); + for (unsigned int i = 0; i < _goldak_indices.size(); ++i) + { + scan_path_segments = ScanPath::extract_scan_paths( + _goldak_scan_files[i], _goldak_scan_formats[i]); + _goldak_scan_path_segments.emplace_back( + Kokkos::view_alloc(Kokkos::WithoutInitializing, + "goldak_scan_path_segments_" + std::to_string(i)), + scan_path_segments.size()); + Kokkos::deep_copy( + _goldak_scan_path_segments.back(), + Kokkos::View( + scan_path_segments.data(), scan_path_segments.size())); + } + _electron_beam_scan_path_segments.clear(); + for (unsigned int i = 0; i < _electron_beam_indices.size(); ++i) + { + scan_path_segments = ScanPath::extract_scan_paths( + _electron_beam_scan_files[i], _electron_beam_scan_formats[i]); + _electron_beam_scan_path_segments.emplace_back( + Kokkos::view_alloc(Kokkos::WithoutInitializing, + "electron_beam_scan_path_segments_" + + std::to_string(i)), + scan_path_segments.size()); + Kokkos::deep_copy( + _electron_beam_scan_path_segments.back(), + Kokkos::View( + scan_path_segments.data(), scan_path_segments.size())); + } +} + +template +template +std::enable_if_t> +HeatSources::update_scan_paths() +{ + internal_update_scan_paths(); + + for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) + _goldak_heat_sources(i).set_scan_path( + ScanPath{_goldak_scan_path_segments[i]}); + for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) + _electron_beam_heat_sources(i).set_scan_path( + ScanPath{_electron_beam_scan_path_segments[i]}); +} + template HeatSources::HeatSources( boost::property_tree::ptree const &source_database) @@ -126,8 +194,6 @@ HeatSources::HeatSources( unsigned int const n_beams = source_database.get("n_beams"); std::vector goldak_beams; std::vector electron_beam_beams; - std::vector> goldak_scan_path_segments; - std::vector> electron_beam_scan_path_segments; std::vector> cube_heat_sources; for (unsigned int i = 0; i < n_beams; ++i) @@ -138,20 +204,20 @@ HeatSources::HeatSources( if (type == "goldak") { goldak_beams.emplace_back(beam_database); - goldak_scan_path_segments.push_back( - ScanPath::extract_scan_paths( - beam_database.get("scan_path_file"), - beam_database.get("scan_path_file_format"))); _goldak_indices.push_back(i); + _goldak_scan_files.push_back( + beam_database.get("scan_path_file")); + _goldak_scan_formats.push_back( + beam_database.get("scan_path_file_format")); } else if (type == "electron_beam") { electron_beam_beams.emplace_back(beam_database); - electron_beam_scan_path_segments.push_back( - ScanPath::extract_scan_paths( - beam_database.get("scan_path_file"), - beam_database.get("scan_path_file_format"))); _electron_beam_indices.push_back(i); + _electron_beam_scan_files.push_back( + beam_database.get("scan_path_file")); + _electron_beam_scan_formats.push_back( + beam_database.get("scan_path_file_format")); } else if (type == "cube") { @@ -166,17 +232,11 @@ HeatSources::HeatSources( } } + internal_update_scan_paths(); + std::vector> goldak_heat_sources; - for (unsigned int i = 0; i < goldak_scan_path_segments.size(); ++i) + for (unsigned int i = 0; i < goldak_beams.size(); ++i) { - _goldak_scan_path_segments.emplace_back( - Kokkos::view_alloc(Kokkos::WithoutInitializing, - "goldak_scan_path_segments_" + std::to_string(i)), - goldak_scan_path_segments[i].size()); - Kokkos::deep_copy(_goldak_scan_path_segments.back(), - Kokkos::View( - goldak_scan_path_segments[i].data(), - goldak_scan_path_segments[i].size())); goldak_heat_sources.emplace_back( goldak_beams[i], ScanPath(_goldak_scan_path_segments.back())); @@ -184,17 +244,8 @@ HeatSources::HeatSources( std::vector> electron_beam_heat_sources; - for (unsigned int i = 0; i < electron_beam_scan_path_segments.size(); ++i) + for (unsigned int i = 0; i < electron_beam_beams.size(); ++i) { - _electron_beam_scan_path_segments.emplace_back( - Kokkos::view_alloc(Kokkos::WithoutInitializing, - "electron_beam_scan_path_segments_" + - std::to_string(i)), - electron_beam_scan_path_segments[i].size()); - Kokkos::deep_copy(_electron_beam_scan_path_segments.back(), - Kokkos::View( - electron_beam_scan_path_segments[i].data(), - electron_beam_scan_path_segments[i].size())); electron_beam_heat_sources.emplace_back( electron_beam_beams[i], ScanPath(_electron_beam_scan_path_segments.back())); diff --git a/source/MaterialProperty.hh b/source/MaterialProperty.hh index 8878713d..275ec536 100644 --- a/source/MaterialProperty.hh +++ b/source/MaterialProperty.hh @@ -22,7 +22,6 @@ #include #include #include -#include #include diff --git a/source/ScanPath.cc b/source/ScanPath.cc index da6fe56e..18a16b2f 100644 --- a/source/ScanPath.cc +++ b/source/ScanPath.cc @@ -9,6 +9,7 @@ #include #include + #include #include @@ -21,24 +22,19 @@ std::vector ScanPath::extract_scan_paths(std::string scan_path_file, std::string file_format) { - ASSERT_THROW((_file_format == "segment") || (_file_format == "event_series"), + ASSERT_THROW((file_format == "segment") || (file_format == "event_series"), "Error: Format of scan path file not recognized."); - wait_for_file(_scan_path_file, - "Waiting for scan path file: " + _scan_path_file); - - read_file(); -} + wait_for_file(scan_path_file, + "Waiting for scan path file: " + scan_path_file); -void ScanPath::read_file() -{ - if (_file_format == "segment") + if (file_format == "segment") { - load_segment_scan_path(scan_path_file); + return load_segment_scan_path(scan_path_file); } else { - load_event_series_scan_path(); + return load_event_series_scan_path(scan_path_file); } return {}; @@ -46,11 +42,11 @@ void ScanPath::read_file() template std::vector -ScanPath::load_segment_scan_path() +ScanPath::load_segment_scan_path(std::string scan_path_file) { - _segment_list.clear(); + std::vector segment_list; std::ifstream file; - file.open(_scan_path_file); + file.open(scan_path_file); std::string line; unsigned int data_index = 0; // Skip first line @@ -127,11 +123,12 @@ ScanPath::load_segment_scan_path() template std::vector -ScanPath::load_event_series_scan_path() +ScanPath::load_event_series_scan_path( + std::string scan_path_file) { - _segment_list.clear(); + std::vector segment_list; std::ifstream file; - file.open(_scan_path_file); + file.open(scan_path_file); std::string line; double last_power = 0.0; diff --git a/source/ScanPath.hh b/source/ScanPath.hh index 7161a4bd..ae43d58a 100644 --- a/source/ScanPath.hh +++ b/source/ScanPath.hh @@ -1,5 +1,5 @@ /* Copyright (c) 2016 - 2024, the adamantine authors. -* + * * This file is subject to the Modified BSD License and may not be distributed * without copyright and license information. Please refer to the file LICENSE * for the text and further information on this license. @@ -65,11 +65,11 @@ public: */ ScanPath() = default; - ScanPath( + KOKKOS_FUNCTION ScanPath( Kokkos::View> scan_path_segments) - : _segment_list(scan_path_segments) + : _segment_list(scan_path_segments.data(), scan_path_segments.size()) { } @@ -98,18 +98,6 @@ public: void read_file(); private: - /** - * The list of information about each segment in the scan path. - */ - Kokkos::View> - _segment_list; - - /** - * The index of the current segment in the scan path. - */ - mutable unsigned int _current_segment = 0; - /** * Method to load a "segment" scan path file */ @@ -129,18 +117,13 @@ private: dealii::Point<3> &segment_start_point, double &segment_start_time) const; - /** - * File name of the scan path - */ - std::string _scan_path_file; - /** - * Format of the scan path file, either segment of event_series. - */ - std::string _file_format; /** * The list of information about each segment in the scan path. */ - std::vector _segment_list; + Kokkos::View> + _segment_list; + /** * The index of the current segment in the scan path. */ From 583ab35a8b6ba4e316462232b0c0bbbcc148d6bf Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Mon, 10 Jun 2024 16:07:51 -0400 Subject: [PATCH 15/30] Remove max_value --- application/adamantine.hh | 2 +- source/HeatSources.hh | 22 ---------------------- 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/application/adamantine.hh b/application/adamantine.hh index c4a692d6..4fc9d734 100644 --- a/application/adamantine.hh +++ b/application/adamantine.hh @@ -549,7 +549,7 @@ compute_cells_to_refine( // quadrature points, vertices). for (unsigned int f = 0; f < cell->reference_cell().n_faces(); ++f) { - if (heat_sources.max_value(cell->face(f)->center(), current_source_height) > + if (heat_sources.value(cell->face(f)->center(), current_source_height) > refinement_beam_cutoff) { cells_to_refine.push_back(cell); diff --git a/source/HeatSources.hh b/source/HeatSources.hh index 66a80f51..5415df86 100644 --- a/source/HeatSources.hh +++ b/source/HeatSources.hh @@ -57,12 +57,6 @@ public: */ double value(dealii::Point const &point, double const height) const; - /** - * Compute the maxiumum heat source at a given point at a given time given the - * current height of the object being manufactured. - */ - double max_value(dealii::Point const &point, double const height) const; - /** * Return the scan paths for the heat source. */ @@ -329,22 +323,6 @@ double HeatSources::value(dealii::Point const &point, return value; } -template -double -HeatSources::max_value(dealii::Point const &point, - double const height) const -{ - double value = 0; - for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) - value = - std::max(value, _electron_beam_heat_sources(i).value(point, height)); - for (unsigned int i = 0; i < _cube_heat_sources.size(); ++i) - value = std::max(value, _cube_heat_sources(i).value(point, height)); - for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) - value = std::max(value, _goldak_heat_sources(i).value(point, height)); - return value; -} - template std::vector> HeatSources::get_scan_paths() const From aef60511e2ee5dc8c2e0ad8b9d5f322412502fde Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Mon, 10 Jun 2024 16:13:46 -0400 Subject: [PATCH 16/30] host_heat_sources -> heat_sources_host --- application/adamantine.hh | 26 +++++++++++++++----------- source/ThermalPhysics.templates.hh | 16 ++++++++-------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/application/adamantine.hh b/application/adamantine.hh index 4fc9d734..1c3eccd0 100644 --- a/application/adamantine.hh +++ b/application/adamantine.hh @@ -607,7 +607,8 @@ void refine_mesh( const double refinement_beam_cutoff = refinement_database.get("beam_cutoff", 1.0e-15); - adamantine::HeatSources host_heat_sources = heat_sources.copy_to(dealii::MemorySpace::Host{}); + adamantine::HeatSources heat_sources_host = + heat_sources.copy_to(dealii::MemorySpace::Host{}); for (unsigned int i = 0; i < n_refinements; ++i) { @@ -616,7 +617,7 @@ void refine_mesh( dim>::active_cell_iterator> cells_to_refine = compute_cells_to_refine( triangulation, time, next_refinement_time, time_steps_refinement, - host_heat_sources, current_source_height, refinement_beam_cutoff); + heat_sources_host, current_source_height, refinement_beam_cutoff); // PropertyTreeInput refinement.coarsen_after_beam const bool coarsen_after_beam = @@ -944,13 +945,14 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database, mechanical_physics, displacement, material_properties, timers); ++n_time_step; - adamantine::HeatSources host_heat_sources = heat_sources.copy_to(dealii::MemorySpace::Host{}); + adamantine::HeatSources heat_sources_host = + heat_sources.copy_to(dealii::MemorySpace::Host{}); // Create the bounding boxes used for material deposition auto [material_deposition_boxes, deposition_times, deposition_cos, deposition_sin] = adamantine::create_material_deposition_boxes(geometry_database, - host_heat_sources); + heat_sources_host); // Extract the time-stepping database boost::property_tree::ptree time_stepping_database = database.get_child("time_stepping"); @@ -1026,11 +1028,13 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database, } if (scan_path_updated) { - adamantine::HeatSources host_heat_sources = heat_sources.copy_to(dealii::MemorySpace::Host{}); - host_heat_sources.update_scan_paths(); - heat_sources = host_heat_sources.copy_to(MemorySpaceType{}); - - auto const& scan_paths = heat_sources.get_scan_paths(); + adamantine::HeatSources + heat_sources_host = + heat_sources.copy_to(dealii::MemorySpace::Host{}); + heat_sources_host.update_scan_paths(); + heat_sources = heat_sources_host.copy_to(MemorySpaceType{}); + + auto const &scan_paths = heat_sources.get_scan_paths(); for (unsigned int s = 0; s < scan_path_end.size(); ++s) { // Update scan_path_end @@ -1044,8 +1048,8 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database, std::tie(material_deposition_boxes, deposition_times, deposition_cos, deposition_sin) = - adamantine::create_material_deposition_boxes(geometry_database, - host_heat_sources); + adamantine::create_material_deposition_boxes( + geometry_database, heat_sources_host); } auto activation_start = diff --git a/source/ThermalPhysics.templates.hh b/source/ThermalPhysics.templates.hh index 067f54bd..79b0ca8b 100644 --- a/source/ThermalPhysics.templates.hh +++ b/source/ThermalPhysics.templates.hh @@ -120,8 +120,8 @@ evaluate_thermal_physics_impl( // Compute the source term. // TODO do this on the GPU - auto host_heat_sources = heat_sources.copy_to(dealii::MemorySpace::Host{}); - host_heat_sources.update_time(t); + auto heat_sources_host = heat_sources.copy_to(dealii::MemorySpace::Host{}); + heat_sources_host.update_time(t); dealii::LA::distributed::Vector source( y.get_partitioner()); source = 0.; @@ -167,7 +167,7 @@ evaluate_thermal_physics_impl( double quad_pt_source = 0.; dealii::Point const &q_point = fe_values.quadrature_point(q); quad_pt_source += - host_heat_sources.value(q_point, current_source_height); + heat_sources_host.value(q_point, current_source_height); cell_source[i] += inv_rho_cp * quad_pt_source * fe_values.shape_value(i, q) * fe_values.JxW(q); @@ -466,8 +466,8 @@ ThermalPhysicsset_active_fe_index(1); } - auto host_heat_sources = _heat_sources.copy_to(dealii::MemorySpace::Host{}); - _current_source_height = host_heat_sources.get_current_height(0.0); + auto heat_sources_host = _heat_sources.copy_to(dealii::MemorySpace::Host{}); + _current_source_height = heat_sources_host.get_current_height(0.0); } template Date: Mon, 10 Jun 2024 16:14:05 -0400 Subject: [PATCH 17/30] Indent more filles --- application/adamantine.hh | 23 ++++++++++++----------- indent | 1 + 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/application/adamantine.hh b/application/adamantine.hh index 1c3eccd0..33c0c720 100644 --- a/application/adamantine.hh +++ b/application/adamantine.hh @@ -776,10 +776,11 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database, heat_sources = thermal_physics->get_heat_sources(); // Store the current end time of each heat source and set a flag that the // scan path has changed - auto const& scan_paths = heat_sources.get_scan_paths(); + auto const &scan_paths = heat_sources.get_scan_paths(); for (auto const &scan_path : scan_paths) { - scan_path_end.emplace_back(scan_path.get_segment_list().back().end_time, true); + scan_path_end.emplace_back(scan_path.get_segment_list().back().end_time, + true); } post_processor_database.put("thermal_output", true); } @@ -1038,10 +1039,8 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database, for (unsigned int s = 0; s < scan_path_end.size(); ++s) { // Update scan_path_end - double new_end_time = scan_paths[s] - .get_segment_list() - .back() - .end_time; + double new_end_time = + scan_paths[s].get_segment_list().back().end_time; scan_path_end[s].second = scan_path_end[s].first != new_end_time; scan_path_end[s].first = new_end_time; } @@ -1767,11 +1766,13 @@ run_ensemble(MPI_Comm const &global_communicator, for (unsigned int member = 0; member < local_ensemble_size; ++member) { - refine_mesh(thermal_physics_ensemble[member], - *material_properties_ensemble[member], - solution_augmented_ensemble[member].block(base_state), - heat_sources_ensemble[member].copy_to(dealii::MemorySpace::Host{}), time, next_refinement_time, - time_steps_refinement, refinement_database); + refine_mesh( + thermal_physics_ensemble[member], + *material_properties_ensemble[member], + solution_augmented_ensemble[member].block(base_state), + heat_sources_ensemble[member].copy_to(dealii::MemorySpace::Host{}), + time, next_refinement_time, time_steps_refinement, + refinement_database); solution_augmented_ensemble[member].collect_sizes(); } diff --git a/indent b/indent index 83bfac5f..780a0542 100755 --- a/indent +++ b/indent @@ -2,3 +2,4 @@ clang-format -style=file -i source/*.cc clang-format -style=file -i source/*.hh clang-format -style=file -i tests/*.cc clang-format -style=file -i application/*.cc +clang-format -style=file -i application/*.hh From 647ee6ffc574c8bd3a48bbde32a10dac093f4ed0 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Mon, 10 Jun 2024 16:15:05 -0400 Subject: [PATCH 18/30] Remove redundant include --- source/CubeHeatSource.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/CubeHeatSource.cc b/source/CubeHeatSource.cc index 4a9a7a5f..4c686ac3 100644 --- a/source/CubeHeatSource.cc +++ b/source/CubeHeatSource.cc @@ -9,8 +9,6 @@ #include #include -#include - namespace adamantine { template From 76ff0bf8741310e7003e00f70f8124dd52521afe Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Mon, 10 Jun 2024 16:17:02 -0400 Subject: [PATCH 19/30] Remove beam from cube heat source --- source/CubeHeatSource.hh | 25 ------------------------- source/HeatSources.hh | 2 -- 2 files changed, 27 deletions(-) diff --git a/source/CubeHeatSource.hh b/source/CubeHeatSource.hh index 73d51208..ea151207 100644 --- a/source/CubeHeatSource.hh +++ b/source/CubeHeatSource.hh @@ -52,17 +52,6 @@ public: */ double get_current_height(double const time) const; - /** - * (Re)sets the BeamHeatSourceProperties member variable, necessary if the - * beam parameters vary in time (e.g. due to data assimilation). - */ - void set_beam_properties(boost::property_tree::ptree const &database); - - /** - * Return the beam properties. - */ - BeamHeatSourceProperties get_beam_properties() const; - private: bool _source_on = false; double _start_time; @@ -71,22 +60,8 @@ private: dealii::Point _min_point; dealii::Point _max_point; double _alpha; - BeamHeatSourceProperties _beam; }; -template -void CubeHeatSource::set_beam_properties( - boost::property_tree::ptree const &database) -{ - _beam.set_from_database(database); -} - -template -BeamHeatSourceProperties CubeHeatSource::get_beam_properties() const -{ - return _beam; -} - } // namespace adamantine #endif diff --git a/source/HeatSources.hh b/source/HeatSources.hh index 5415df86..112de8eb 100644 --- a/source/HeatSources.hh +++ b/source/HeatSources.hh @@ -372,8 +372,6 @@ void HeatSources::set_beam_properties( for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) set_properties(_electron_beam_heat_sources[i], _electron_beam_indices[i]); - for (unsigned int i = 0; i < _cube_heat_sources.size(); ++i) - set_properties(_cube_heat_sources[i], _cube_indices[i]); for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) set_properties(_goldak_heat_sources[i], _goldak_indices[i]); } From a78818601d88b08e44d7069b3190a2cc28e77b45 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Mon, 10 Jun 2024 16:25:34 -0400 Subject: [PATCH 20/30] Remove redundant final --- source/CubeHeatSource.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/CubeHeatSource.hh b/source/CubeHeatSource.hh index ea151207..9cebbbf4 100644 --- a/source/CubeHeatSource.hh +++ b/source/CubeHeatSource.hh @@ -19,7 +19,7 @@ namespace adamantine * used for verification purpose. */ template -class CubeHeatSource final +class CubeHeatSource { public: /** From 87efdf7849490a29665660a8d450001d8c8c6574 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Mon, 10 Jun 2024 16:28:45 -0400 Subject: [PATCH 21/30] Resets -> Reset --- source/ElectronBeamHeatSource.hh | 2 +- source/GoldakHeatSource.hh | 2 +- source/HeatSources.hh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/ElectronBeamHeatSource.hh b/source/ElectronBeamHeatSource.hh index d698d253..967238f6 100644 --- a/source/ElectronBeamHeatSource.hh +++ b/source/ElectronBeamHeatSource.hh @@ -65,7 +65,7 @@ public: double get_current_height(double const time) const; /** - * (Re)sets the BeamHeatSourceProperties member variable, necessary if the + * (Re)set the BeamHeatSourceProperties member variable, necessary if the * beam parameters vary in time (e.g. due to data assimilation). */ void set_beam_properties(boost::property_tree::ptree const &database); diff --git a/source/GoldakHeatSource.hh b/source/GoldakHeatSource.hh index acbf17e9..1028e7de 100644 --- a/source/GoldakHeatSource.hh +++ b/source/GoldakHeatSource.hh @@ -65,7 +65,7 @@ public: double get_current_height(double const time) const; /** - * (Re)sets the BeamHeatSourceProperties member variable, necessary if the + * (Re)set the BeamHeatSourceProperties member variable, necessary if the * beam parameters vary in time (e.g. due to data assimilation). */ void set_beam_properties(boost::property_tree::ptree const &database); diff --git a/source/HeatSources.hh b/source/HeatSources.hh index 112de8eb..ef9cd5c8 100644 --- a/source/HeatSources.hh +++ b/source/HeatSources.hh @@ -63,7 +63,7 @@ public: std::vector> get_scan_paths() const; /** - * (Re)sets the BeamHeatSourceProperties member variable, necessary if the + * (Re)set the BeamHeatSourceProperties member variable, necessary if the * beam parameters vary in time (e.g. due to data assimilation). */ void From dea04e497ff2db7c9544c81dd12de0e81a3ad721 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Mon, 10 Jun 2024 16:36:31 -0400 Subject: [PATCH 22/30] Return BeamHeatSourceProperties by const& --- source/ElectronBeamHeatSource.hh | 4 ++-- source/GoldakHeatSource.hh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/ElectronBeamHeatSource.hh b/source/ElectronBeamHeatSource.hh index 967238f6..af89a5db 100644 --- a/source/ElectronBeamHeatSource.hh +++ b/source/ElectronBeamHeatSource.hh @@ -73,7 +73,7 @@ public: /** * Return the beam properties. */ - BeamHeatSourceProperties get_beam_properties() const; + BeamHeatSourceProperties const &get_beam_properties() const; private: dealii::Point<3> _beam_center; @@ -103,7 +103,7 @@ void ElectronBeamHeatSource::set_beam_properties( _beam.set_from_database(database); } template -BeamHeatSourceProperties +BeamHeatSourceProperties const & ElectronBeamHeatSource::get_beam_properties() const { return _beam; diff --git a/source/GoldakHeatSource.hh b/source/GoldakHeatSource.hh index 1028e7de..1ea8a24a 100644 --- a/source/GoldakHeatSource.hh +++ b/source/GoldakHeatSource.hh @@ -73,7 +73,7 @@ public: /** * Return the beam properties. */ - BeamHeatSourceProperties get_beam_properties() const; + BeamHeatSourceProperties const &get_beam_properties() const; private: dealii::Point<3> _beam_center; @@ -105,7 +105,7 @@ void GoldakHeatSource::set_beam_properties( } template -BeamHeatSourceProperties +BeamHeatSourceProperties const & GoldakHeatSource::get_beam_properties() const { return _beam; From af4f18161da0535507c45572a35bc3fdd9958a92 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Mon, 10 Jun 2024 16:37:22 -0400 Subject: [PATCH 23/30] Fix formatting --- source/ElectronBeamHeatSource.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/source/ElectronBeamHeatSource.hh b/source/ElectronBeamHeatSource.hh index af89a5db..3e0b45a4 100644 --- a/source/ElectronBeamHeatSource.hh +++ b/source/ElectronBeamHeatSource.hh @@ -102,6 +102,7 @@ void ElectronBeamHeatSource::set_beam_properties( { _beam.set_from_database(database); } + template BeamHeatSourceProperties const & ElectronBeamHeatSource::get_beam_properties() const From a95bcb324c830ce164eec3167207ac536ee44110 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Mon, 10 Jun 2024 16:39:06 -0400 Subject: [PATCH 24/30] _pi_over_3_to_1p5 -> pi_over_3_to_1p5 --- source/GoldakHeatSource.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/GoldakHeatSource.cc b/source/GoldakHeatSource.cc index a4a0cba4..784493f3 100644 --- a/source/GoldakHeatSource.cc +++ b/source/GoldakHeatSource.cc @@ -25,14 +25,14 @@ GoldakHeatSource::GoldakHeatSource( template void GoldakHeatSource::update_time(double time) { - static const double _pi_over_3_to_1p5 = + static const double pi_over_3_to_1p5 = std::pow(dealii::numbers::PI / 3.0, 1.5); _beam_center = this->_scan_path.value(time); double segment_power_modifier = this->_scan_path.get_power_modifier(time); _alpha = 2.0 * this->_beam.absorption_efficiency * this->_beam.max_power * segment_power_modifier / - (this->_beam.radius_squared * this->_beam.depth * _pi_over_3_to_1p5); + (this->_beam.radius_squared * this->_beam.depth * pi_over_3_to_1p5); } template From 02a7600d0cf9ac68f8d1e05e434da4657c8a5ac7 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Mon, 10 Jun 2024 16:39:39 -0400 Subject: [PATCH 25/30] Formatting --- source/GoldakHeatSource.hh | 1 - 1 file changed, 1 deletion(-) diff --git a/source/GoldakHeatSource.hh b/source/GoldakHeatSource.hh index 1ea8a24a..1d4cf0a0 100644 --- a/source/GoldakHeatSource.hh +++ b/source/GoldakHeatSource.hh @@ -79,7 +79,6 @@ private: dealii::Point<3> _beam_center; double _alpha = std::numeric_limits::signaling_NaN(); BeamHeatSourceProperties _beam; - ScanPath _scan_path; }; From ab3a2d5edf2986bf1d657b12d30b4480237a2cce Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Tue, 11 Jun 2024 11:18:20 -0400 Subject: [PATCH 26/30] Avoid duplications in tests --- tests/test_heat_source.cc | 76 ++++++++++++------------------- tests/test_material_deposition.cc | 49 ++++++++------------ 2 files changed, 47 insertions(+), 78 deletions(-) diff --git a/tests/test_heat_source.cc b/tests/test_heat_source.cc index 2ad267cf..a6a84e92 100644 --- a/tests/test_heat_source.cc +++ b/tests/test_heat_source.cc @@ -19,7 +19,11 @@ namespace utf = boost::unit_test; namespace adamantine { -BOOST_AUTO_TEST_CASE(heat_source_value_2d, *utf::tolerance(1e-12)) +template +std::tuple, + ElectronBeamHeatSource, + GoldakHeatSource> +create_heat_sources(std::string scan_path_file) { boost::property_tree::ptree database; @@ -27,19 +31,31 @@ BOOST_AUTO_TEST_CASE(heat_source_value_2d, *utf::tolerance(1e-12)) database.put("absorption_efficiency", 0.1); database.put("diameter", 1.0); database.put("max_power", 10.); - database.put("scan_path_file", "scan_path.txt"); + database.put("scan_path_file", scan_path_file); database.put("scan_path_file_format", "segment"); std::vector scan_path_segments = ScanPath::extract_scan_paths( database.get("scan_path_file"), database.get("scan_path_file_format")); - Kokkos::View scan_paths_segments_view( - scan_path_segments.data(), scan_path_segments.size()); + Kokkos::View scan_path_segments_view( + "scan_path_segments", scan_path_segments.size()); + Kokkos::deep_copy(scan_path_segments_view, + Kokkos::View{ + scan_path_segments.data(), scan_path_segments.size()}); BeamHeatSourceProperties beam(database); - GoldakHeatSource<2, dealii::MemorySpace::Host> goldak_heat_source( - beam, ScanPath(scan_paths_segments_view)); - ElectronBeamHeatSource<2, dealii::MemorySpace::Host> eb_heat_source( - database, ScanPath(scan_paths_segments_view)); + return std::tuple( + scan_path_segments_view, + ElectronBeamHeatSource{ + database, + ScanPath(scan_path_segments_view)}, + GoldakHeatSource{ + beam, ScanPath(scan_path_segments_view)}); +} + +BOOST_AUTO_TEST_CASE(heat_source_value_2d, *utf::tolerance(1e-12)) +{ + auto [scan_paths_segments, eb_heat_source, goldak_heat_source] = + create_heat_sources<2>("scan_path.txt"); double g_value = 0.0; double eb_value = 0.0; @@ -110,26 +126,8 @@ BOOST_AUTO_TEST_CASE(heat_source_value_2d, *utf::tolerance(1e-12)) BOOST_AUTO_TEST_CASE(heat_source_value_3d, *utf::tolerance(1e-12)) { - boost::property_tree::ptree database; - - database.put("depth", 0.1); - database.put("absorption_efficiency", 0.1); - database.put("diameter", 1.0); - database.put("max_power", 10.); - database.put("scan_path_file", "scan_path.txt"); - database.put("scan_path_file_format", "segment"); - std::vector scan_path_segments = - ScanPath::extract_scan_paths( - database.get("scan_path_file"), - database.get("scan_path_file_format")); - Kokkos::View scan_paths_segments_view( - scan_path_segments.data(), scan_path_segments.size()); - BeamHeatSourceProperties beam(database); - - GoldakHeatSource<3, dealii::MemorySpace::Host> goldak_heat_source( - beam, ScanPath(scan_paths_segments_view)); - ElectronBeamHeatSource<3, dealii::MemorySpace::Host> eb_heat_source( - beam, ScanPath(scan_paths_segments_view)); + auto [scan_paths_segments, eb_heat_source, goldak_heat_source] = + create_heat_sources<3>("scan_path.txt"); double g_value = 0.0; double eb_value = 0.0; @@ -188,26 +186,8 @@ BOOST_AUTO_TEST_CASE(heat_source_value_3d, *utf::tolerance(1e-12)) BOOST_AUTO_TEST_CASE(heat_source_height, *utf::tolerance(1e-12)) { - boost::property_tree::ptree database; - - database.put("depth", 0.1); - database.put("absorption_efficiency", 0.1); - database.put("diameter", 1.0); - database.put("max_power", 10.); - database.put("scan_path_file", "scan_path_layers.txt"); - database.put("scan_path_file_format", "segment"); - std::vector scan_path_segments = - ScanPath::extract_scan_paths( - database.get("scan_path_file"), - database.get("scan_path_file_format")); - Kokkos::View scan_paths_segments_view( - scan_path_segments.data(), scan_path_segments.size()); - BeamHeatSourceProperties beam(database); - - GoldakHeatSource<2, dealii::MemorySpace::Host> goldak_heat_source( - beam, ScanPath(scan_paths_segments_view)); - ElectronBeamHeatSource<2, dealii::MemorySpace::Host> eb_heat_source( - beam, ScanPath(scan_paths_segments_view)); + auto [scan_paths_segments, eb_heat_source, goldak_heat_source] = + create_heat_sources<2>("scan_path_layers.txt"); double g_height = 0.0; double eb_height = 0.0; diff --git a/tests/test_material_deposition.cc b/tests/test_material_deposition.cc index e14f2c69..35fd70f4 100644 --- a/tests/test_material_deposition.cc +++ b/tests/test_material_deposition.cc @@ -351,16 +351,25 @@ BOOST_AUTO_TEST_CASE(material_deposition) } } -BOOST_AUTO_TEST_CASE(deposition_from_scan_path_2d, *utf::tolerance(1e-13)) +std::pair, + adamantine::ScanPath> +create_scan_path(std::string file_name) { std::vector scan_path_segments = adamantine::ScanPath::extract_scan_paths( - "scan_path.txt", "segment"); + file_name, "segment"); Kokkos::View - scan_paths_segments_view(scan_path_segments.data(), - scan_path_segments.size()); - adamantine::ScanPath scan_path( - scan_paths_segments_view); + scan_path_segments_view("scan_path_segments", scan_path_segments.size()); + Kokkos::deep_copy( + scan_path_segments_view, + Kokkos::View{ + scan_path_segments.data(), scan_path_segments.size()}); + return {scan_path_segments_view, {scan_path_segments_view}}; +} + +BOOST_AUTO_TEST_CASE(deposition_from_scan_path_2d, *utf::tolerance(1e-13)) +{ + auto [scan_path_segments, scan_path] = create_scan_path("scan_path.txt"); boost::property_tree::ptree database; database.put("deposition_length", 0.0005); @@ -408,14 +417,7 @@ BOOST_AUTO_TEST_CASE(deposition_from_scan_path_2d, *utf::tolerance(1e-13)) BOOST_AUTO_TEST_CASE(deposition_from_scan_path_3d, *utf::tolerance(1e-13)) { - std::vector scan_path_segments = - adamantine::ScanPath::extract_scan_paths( - "scan_path.txt", "segment"); - Kokkos::View - scan_paths_segments_view(scan_path_segments.data(), - scan_path_segments.size()); - adamantine::ScanPath scan_path( - scan_paths_segments_view); + auto [scan_path_segments, scan_path] = create_scan_path("scan_path.txt"); boost::property_tree::ptree database; database.put("deposition_length", 0.0005); @@ -467,14 +469,7 @@ BOOST_AUTO_TEST_CASE(deposition_from_scan_path_3d, *utf::tolerance(1e-13)) BOOST_AUTO_TEST_CASE(deposition_from_L_scan_path_3d, *utf::tolerance(1e-13)) { - std::vector scan_path_segments = - adamantine::ScanPath::extract_scan_paths( - "scan_path_L.txt", "segment"); - Kokkos::View - scan_paths_segments_view(scan_path_segments.data(), - scan_path_segments.size()); - adamantine::ScanPath scan_path( - scan_paths_segments_view); + auto [scan_path_segments, scan_path] = create_scan_path("scan_path_L.txt"); boost::property_tree::ptree database; database.put("deposition_length", 0.0005); @@ -560,14 +555,8 @@ BOOST_AUTO_TEST_CASE(deposition_from_L_scan_path_3d, *utf::tolerance(1e-13)) BOOST_AUTO_TEST_CASE(deposition_from_diagonal_scan_path_3d, *utf::tolerance(1e-10)) { - std::vector scan_path_segments = - adamantine::ScanPath::extract_scan_paths( - "scan_path_diagonal.txt", "segment"); - Kokkos::View - scan_paths_segments_view(scan_path_segments.data(), - scan_path_segments.size()); - adamantine::ScanPath scan_path( - scan_paths_segments_view); + auto [scan_path_segments, scan_path] = + create_scan_path("scan_path_diagonal.txt"); boost::property_tree::ptree database; database.put("deposition_length", 0.0005); From 24601c679b39fbe2b7794c5caaef3e68d2bde8a7 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Tue, 11 Jun 2024 20:13:21 +0000 Subject: [PATCH 27/30] Fix running on GPUs --- application/adamantine.hh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/application/adamantine.hh b/application/adamantine.hh index 33c0c720..3ea25d0e 100644 --- a/application/adamantine.hh +++ b/application/adamantine.hh @@ -774,9 +774,12 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database, fe_degree, quadrature_type, communicator, database, geometry, material_properties); heat_sources = thermal_physics->get_heat_sources(); + adamantine::HeatSources heat_sources_host = + heat_sources.copy_to(dealii::MemorySpace::Host{}); + // Store the current end time of each heat source and set a flag that the // scan path has changed - auto const &scan_paths = heat_sources.get_scan_paths(); + auto const &scan_paths = heat_sources_host.get_scan_paths(); for (auto const &scan_path : scan_paths) { scan_path_end.emplace_back(scan_path.get_segment_list().back().end_time, From 044ad9fae4f39fced4ad71a36e98eb7be479c257 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Tue, 25 Jun 2024 14:45:54 -0400 Subject: [PATCH 28/30] extract_scan_paths->read_file --- application/adamantine.cc | 3 ++- source/HeatSources.hh | 4 ++-- source/ScanPath.cc | 4 ++-- source/ScanPath.hh | 4 ++-- tests/test_heat_source.cc | 2 +- tests/test_material_deposition.cc | 4 ++-- tests/test_scan_path.cc | 10 +++++----- 7 files changed, 16 insertions(+), 15 deletions(-) diff --git a/application/adamantine.cc b/application/adamantine.cc index bd819b7d..2fed26a7 100644 --- a/application/adamantine.cc +++ b/application/adamantine.cc @@ -164,7 +164,8 @@ int main(int argc, char *argv[]) // Read the input. std::string const filename = map["input-file"].as(); - adamantine::wait_for_file(filename, "Waiting for input file: " + filename); + // adamantine::wait_for_file(filename, "Waiting for input file: " + + // filename); boost::property_tree::ptree database; if (std::filesystem::path(filename).extension().native() == ".json") { diff --git a/source/HeatSources.hh b/source/HeatSources.hh index ef9cd5c8..f6af5c4b 100644 --- a/source/HeatSources.hh +++ b/source/HeatSources.hh @@ -138,7 +138,7 @@ void HeatSources::internal_update_scan_paths() _goldak_scan_path_segments.clear(); for (unsigned int i = 0; i < _goldak_indices.size(); ++i) { - scan_path_segments = ScanPath::extract_scan_paths( + scan_path_segments = ScanPath::read_file( _goldak_scan_files[i], _goldak_scan_formats[i]); _goldak_scan_path_segments.emplace_back( Kokkos::view_alloc(Kokkos::WithoutInitializing, @@ -152,7 +152,7 @@ void HeatSources::internal_update_scan_paths() _electron_beam_scan_path_segments.clear(); for (unsigned int i = 0; i < _electron_beam_indices.size(); ++i) { - scan_path_segments = ScanPath::extract_scan_paths( + scan_path_segments = ScanPath::read_file( _electron_beam_scan_files[i], _electron_beam_scan_formats[i]); _electron_beam_scan_path_segments.emplace_back( Kokkos::view_alloc(Kokkos::WithoutInitializing, diff --git a/source/ScanPath.cc b/source/ScanPath.cc index 18a16b2f..6fa8c255 100644 --- a/source/ScanPath.cc +++ b/source/ScanPath.cc @@ -19,8 +19,8 @@ namespace adamantine template std::vector -ScanPath::extract_scan_paths(std::string scan_path_file, - std::string file_format) +ScanPath::read_file(std::string scan_path_file, + std::string file_format) { ASSERT_THROW((file_format == "segment") || (file_format == "event_series"), "Error: Format of scan path file not recognized."); diff --git a/source/ScanPath.hh b/source/ScanPath.hh index ae43d58a..76de5973 100644 --- a/source/ScanPath.hh +++ b/source/ScanPath.hh @@ -73,8 +73,8 @@ public: { } - static std::vector - extract_scan_paths(std::string scan_path_file, std::string file_format); + static std::vector read_file(std::string scan_path_file, + std::string file_format); /** * Calculate the location of the scan path at a given time for a single diff --git a/tests/test_heat_source.cc b/tests/test_heat_source.cc index a6a84e92..2cdad877 100644 --- a/tests/test_heat_source.cc +++ b/tests/test_heat_source.cc @@ -34,7 +34,7 @@ create_heat_sources(std::string scan_path_file) database.put("scan_path_file", scan_path_file); database.put("scan_path_file_format", "segment"); std::vector scan_path_segments = - ScanPath::extract_scan_paths( + ScanPath::read_file( database.get("scan_path_file"), database.get("scan_path_file_format")); Kokkos::View scan_path_segments_view( diff --git a/tests/test_material_deposition.cc b/tests/test_material_deposition.cc index 35fd70f4..6a42b431 100644 --- a/tests/test_material_deposition.cc +++ b/tests/test_material_deposition.cc @@ -356,8 +356,8 @@ std::pair, create_scan_path(std::string file_name) { std::vector scan_path_segments = - adamantine::ScanPath::extract_scan_paths( - file_name, "segment"); + adamantine::ScanPath::read_file(file_name, + "segment"); Kokkos::View scan_path_segments_view("scan_path_segments", scan_path_segments.size()); Kokkos::deep_copy( diff --git a/tests/test_scan_path.cc b/tests/test_scan_path.cc index 31076c06..ad927a01 100644 --- a/tests/test_scan_path.cc +++ b/tests/test_scan_path.cc @@ -21,12 +21,12 @@ class ScanPathTester public: std::vector get_segment_format_list() { - return ScanPath::extract_scan_paths( - "scan_path.txt", "segment"); + return ScanPath::read_file("scan_path.txt", + "segment"); }; std::vector get_event_series_format_list() { - return ScanPath::extract_scan_paths( + return ScanPath::read_file( "scan_path_event_series.inp", "event_series"); }; }; @@ -76,8 +76,8 @@ BOOST_AUTO_TEST_CASE(scan_path, *utf::tolerance(1e-12)) BOOST_AUTO_TEST_CASE(scan_path_location, *utf::tolerance(1e-10)) { std::vector scan_path_segments = - ScanPath::extract_scan_paths("scan_path.txt", - "segment"); + ScanPath::read_file("scan_path.txt", + "segment"); Kokkos::View scan_paths_segments_view( scan_path_segments.data(), scan_path_segments.size()); ScanPath scan_path(scan_paths_segments_view); From a01cbc569ffef294e8b0e91389cd0c7166c4ea83 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Thu, 11 Jul 2024 14:47:12 -0400 Subject: [PATCH 29/30] Store ScanPath on host --- application/adamantine.hh | 2 +- source/ElectronBeamHeatSource.cc | 20 ++--- source/ElectronBeamHeatSource.hh | 31 +++---- source/GoldakHeatSource.cc | 21 ++--- source/GoldakHeatSource.hh | 31 +++---- source/HeatSources.hh | 144 +++++++++++++----------------- source/ScanPath.cc | 30 ++----- source/ScanPath.hh | 10 +-- source/experimental_data_utils.cc | 7 +- source/material_deposition.cc | 12 ++- source/material_deposition.hh | 5 +- tests/test_heat_source.cc | 15 ++-- tests/test_material_deposition.cc | 5 +- tests/test_scan_path.cc | 11 +-- 14 files changed, 143 insertions(+), 201 deletions(-) diff --git a/application/adamantine.hh b/application/adamantine.hh index 3ea25d0e..b4d4fa5f 100644 --- a/application/adamantine.hh +++ b/application/adamantine.hh @@ -775,7 +775,7 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database, material_properties); heat_sources = thermal_physics->get_heat_sources(); adamantine::HeatSources heat_sources_host = - heat_sources.copy_to(dealii::MemorySpace::Host{}); + heat_sources.copy_to(dealii::MemorySpace::Host{}); // Store the current end time of each heat source and set a flag that the // scan path has changed diff --git a/source/ElectronBeamHeatSource.cc b/source/ElectronBeamHeatSource.cc index a149d18b..9b636e5c 100644 --- a/source/ElectronBeamHeatSource.cc +++ b/source/ElectronBeamHeatSource.cc @@ -14,16 +14,15 @@ namespace adamantine { -template -ElectronBeamHeatSource::ElectronBeamHeatSource( - BeamHeatSourceProperties const &beam, - ScanPath const &scan_path) +template +ElectronBeamHeatSource::ElectronBeamHeatSource( + BeamHeatSourceProperties const &beam, ScanPath const &scan_path) : _beam(beam), _scan_path(scan_path) { } -template -void ElectronBeamHeatSource::update_time(double time) +template +void ElectronBeamHeatSource::update_time(double time) { static const double log_01 = std::log(0.1); _beam_center = this->_scan_path.value(time); @@ -34,9 +33,9 @@ void ElectronBeamHeatSource::update_time(double time) (dealii::numbers::PI * this->_beam.radius_squared * this->_beam.depth); } -template -double ElectronBeamHeatSource::value( - dealii::Point const &point, double const height) const +template +double ElectronBeamHeatSource::value(dealii::Point const &point, + double const height) const { double const z = point[axis::z] - height; if ((z + this->_beam.depth) < 0.) @@ -68,5 +67,4 @@ double ElectronBeamHeatSource::value( } } // namespace adamantine -INSTANTIATE_DIM_DEVICE(ElectronBeamHeatSource) -INSTANTIATE_DIM_HOST(ElectronBeamHeatSource) +INSTANTIATE_DIM(ElectronBeamHeatSource) diff --git a/source/ElectronBeamHeatSource.hh b/source/ElectronBeamHeatSource.hh index 3e0b45a4..5782e19c 100644 --- a/source/ElectronBeamHeatSource.hh +++ b/source/ElectronBeamHeatSource.hh @@ -20,7 +20,7 @@ namespace adamantine * The form of the heat source model is taken from the following reference: * Raghavan et al, Acta Materilia, 112, 2016, pp 303-314. */ -template +template class ElectronBeamHeatSource { public: @@ -35,7 +35,7 @@ public: * segments */ ElectronBeamHeatSource(BeamHeatSourceProperties const &beam, - ScanPath const &scan_path); + ScanPath const &scan_path); /** * Set the time variable. @@ -51,12 +51,9 @@ public: /** * Return the scan path. */ - ScanPath const &get_scan_path() const; + ScanPath const &get_scan_path() const; - void set_scan_path(ScanPath const scan_path) - { - _scan_path = scan_path; - } + void set_scan_path(ScanPath const scan_path) { _scan_path = scan_path; } /** * Compute the current height of the where the heat source meets the material @@ -79,33 +76,31 @@ private: dealii::Point<3> _beam_center; double _alpha = std::numeric_limits::signaling_NaN(); BeamHeatSourceProperties _beam; - ScanPath _scan_path; + ScanPath _scan_path; }; -template -ScanPath const & -ElectronBeamHeatSource::get_scan_path() const +template +ScanPath const &ElectronBeamHeatSource::get_scan_path() const { return _scan_path; } -template -double ElectronBeamHeatSource::get_current_height( - double const time) const +template +double ElectronBeamHeatSource::get_current_height(double const time) const { return _scan_path.value(time)[2]; } -template -void ElectronBeamHeatSource::set_beam_properties( +template +void ElectronBeamHeatSource::set_beam_properties( boost::property_tree::ptree const &database) { _beam.set_from_database(database); } -template +template BeamHeatSourceProperties const & -ElectronBeamHeatSource::get_beam_properties() const +ElectronBeamHeatSource::get_beam_properties() const { return _beam; } diff --git a/source/GoldakHeatSource.cc b/source/GoldakHeatSource.cc index 784493f3..d61c0e6d 100644 --- a/source/GoldakHeatSource.cc +++ b/source/GoldakHeatSource.cc @@ -14,16 +14,15 @@ namespace adamantine { -template -GoldakHeatSource::GoldakHeatSource( - BeamHeatSourceProperties const &beam, - ScanPath const &scan_path) +template +GoldakHeatSource::GoldakHeatSource(BeamHeatSourceProperties const &beam, + ScanPath const &scan_path) : _beam(beam), _scan_path(scan_path) { } -template -void GoldakHeatSource::update_time(double time) +template +void GoldakHeatSource::update_time(double time) { static const double pi_over_3_to_1p5 = std::pow(dealii::numbers::PI / 3.0, 1.5); @@ -35,10 +34,9 @@ void GoldakHeatSource::update_time(double time) (this->_beam.radius_squared * this->_beam.depth * pi_over_3_to_1p5); } -template -double -GoldakHeatSource::value(dealii::Point const &point, - double const height) const +template +double GoldakHeatSource::value(dealii::Point const &point, + double const height) const { double const z = point[axis::z] - height; if ((z + this->_beam.depth) < 0.) @@ -65,5 +63,4 @@ GoldakHeatSource::value(dealii::Point const &point, } } // namespace adamantine -INSTANTIATE_DIM_DEVICE(GoldakHeatSource) -INSTANTIATE_DIM_HOST(GoldakHeatSource) +INSTANTIATE_DIM(GoldakHeatSource) diff --git a/source/GoldakHeatSource.hh b/source/GoldakHeatSource.hh index 1d4cf0a0..b502aff6 100644 --- a/source/GoldakHeatSource.hh +++ b/source/GoldakHeatSource.hh @@ -20,7 +20,7 @@ namespace adamantine * The form of the heat source model is taken from the following reference: * Coleman et al, Journal of Heat Transfer, (in press, 2020). */ -template +template class GoldakHeatSource { public: @@ -35,7 +35,7 @@ public: * segments */ GoldakHeatSource(BeamHeatSourceProperties const &beam, - ScanPath const &scan_path); + ScanPath const &scan_path); /** * Set the time variable. @@ -51,12 +51,9 @@ public: /** * Return the scan path. */ - ScanPath const &get_scan_path() const; + ScanPath const &get_scan_path() const; - void set_scan_path(ScanPath const scan_path) - { - _scan_path = scan_path; - } + void set_scan_path(ScanPath const scan_path) { _scan_path = scan_path; } /** * Compute the current height of the where the heat source meets the material @@ -79,33 +76,31 @@ private: dealii::Point<3> _beam_center; double _alpha = std::numeric_limits::signaling_NaN(); BeamHeatSourceProperties _beam; - ScanPath _scan_path; + ScanPath _scan_path; }; -template -ScanPath const & -GoldakHeatSource::get_scan_path() const +template +ScanPath const &GoldakHeatSource::get_scan_path() const { return _scan_path; } -template -double GoldakHeatSource::get_current_height( - double const time) const +template +double GoldakHeatSource::get_current_height(double const time) const { return _scan_path.value(time)[2]; } -template -void GoldakHeatSource::set_beam_properties( +template +void GoldakHeatSource::set_beam_properties( boost::property_tree::ptree const &database) { _beam.set_from_database(database); } -template +template BeamHeatSourceProperties const & -GoldakHeatSource::get_beam_properties() const +GoldakHeatSource::get_beam_properties() const { return _beam; } diff --git a/source/HeatSources.hh b/source/HeatSources.hh index f6af5c4b..f1f1f045 100644 --- a/source/HeatSources.hh +++ b/source/HeatSources.hh @@ -60,7 +60,7 @@ public: /** * Return the scan paths for the heat source. */ - std::vector> get_scan_paths() const; + std::vector get_scan_paths() const; /** * (Re)set the BeamHeatSourceProperties member variable, necessary if the @@ -85,41 +85,40 @@ private: void internal_update_scan_paths(); /** - * Private constructor used by copy_to_host. + * Private constructor used by copy_to. */ HeatSources( - Kokkos::View *, + Kokkos::View *, typename MemorySpaceType::kokkos_space> electron_beam_heat_sources, Kokkos::View *, typename MemorySpaceType::kokkos_space> cube_heat_sources, - Kokkos::View *, + Kokkos::View *, typename MemorySpaceType::kokkos_space> goldak_heat_sources, - std::vector> const + std::vector> const &electron_beam_scan_path_segments, - std::vector> const + std::vector> const &goldak_scan_path_segments, std::vector const &electron_beam_indices, std::vector const &cube_indices, - std::vector const &goldak_indices); + std::vector const &goldak_indices, + std::vector const &goldak_scan_files, + std::vector const &electron_beam_scan_files, + std::vector const &goldak_scan_formats, + std::vector const &electron_beam_scan_formats); - Kokkos::View *, + Kokkos::View *, typename MemorySpaceType::kokkos_space> _electron_beam_heat_sources; Kokkos::View *, typename MemorySpaceType::kokkos_space> _cube_heat_sources; - Kokkos::View *, - typename MemorySpaceType::kokkos_space> + Kokkos::View *, typename MemorySpaceType::kokkos_space> _goldak_heat_sources; - std::vector< - Kokkos::View> + std::vector> _electron_beam_scan_path_segments; - std::vector< - Kokkos::View> + std::vector> _goldak_scan_path_segments; std::vector _electron_beam_indices; std::vector _cube_indices; @@ -138,8 +137,8 @@ void HeatSources::internal_update_scan_paths() _goldak_scan_path_segments.clear(); for (unsigned int i = 0; i < _goldak_indices.size(); ++i) { - scan_path_segments = ScanPath::read_file( - _goldak_scan_files[i], _goldak_scan_formats[i]); + scan_path_segments = + ScanPath::read_file(_goldak_scan_files[i], _goldak_scan_formats[i]); _goldak_scan_path_segments.emplace_back( Kokkos::view_alloc(Kokkos::WithoutInitializing, "goldak_scan_path_segments_" + std::to_string(i)), @@ -152,8 +151,8 @@ void HeatSources::internal_update_scan_paths() _electron_beam_scan_path_segments.clear(); for (unsigned int i = 0; i < _electron_beam_indices.size(); ++i) { - scan_path_segments = ScanPath::read_file( - _electron_beam_scan_files[i], _electron_beam_scan_formats[i]); + scan_path_segments = ScanPath::read_file(_electron_beam_scan_files[i], + _electron_beam_scan_formats[i]); _electron_beam_scan_path_segments.emplace_back( Kokkos::view_alloc(Kokkos::WithoutInitializing, "electron_beam_scan_path_segments_" + @@ -175,10 +174,10 @@ HeatSources::update_scan_paths() for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) _goldak_heat_sources(i).set_scan_path( - ScanPath{_goldak_scan_path_segments[i]}); + ScanPath{_goldak_scan_path_segments[i]}); for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) _electron_beam_heat_sources(i).set_scan_path( - ScanPath{_electron_beam_scan_path_segments[i]}); + ScanPath{_electron_beam_scan_path_segments[i]}); } template @@ -228,21 +227,19 @@ HeatSources::HeatSources( internal_update_scan_paths(); - std::vector> goldak_heat_sources; + std::vector> goldak_heat_sources; for (unsigned int i = 0; i < goldak_beams.size(); ++i) { goldak_heat_sources.emplace_back( - goldak_beams[i], - ScanPath(_goldak_scan_path_segments.back())); + goldak_beams[i], ScanPath(_goldak_scan_path_segments.back())); } - std::vector> - electron_beam_heat_sources; + std::vector> electron_beam_heat_sources; for (unsigned int i = 0; i < electron_beam_beams.size(); ++i) { electron_beam_heat_sources.emplace_back( electron_beam_beams[i], - ScanPath(_electron_beam_scan_path_segments.back())); + ScanPath(_electron_beam_scan_path_segments.back())); } _goldak_heat_sources = decltype(_goldak_heat_sources)( @@ -257,44 +254,51 @@ HeatSources::HeatSources( cube_heat_sources.size()); Kokkos::deep_copy( _goldak_heat_sources, - Kokkos::View *, Kokkos::HostSpace>( + Kokkos::View *, Kokkos::HostSpace>( goldak_heat_sources.data(), goldak_heat_sources.size())); Kokkos::deep_copy( _electron_beam_heat_sources, - Kokkos::View *, - Kokkos::HostSpace>(electron_beam_heat_sources.data(), - electron_beam_heat_sources.size())); + Kokkos::View *, Kokkos::HostSpace>( + electron_beam_heat_sources.data(), + electron_beam_heat_sources.size())); Kokkos::deep_copy(_cube_heat_sources, - Kokkos::View *, Kokkos::HostSpace>( + Kokkos::View *, + typename MemorySpaceType::kokkos_space>( cube_heat_sources.data(), cube_heat_sources.size())); } template HeatSources::HeatSources( - Kokkos::View *, + Kokkos::View *, typename MemorySpaceType::kokkos_space> electron_beam_heat_sources, Kokkos::View *, typename MemorySpaceType::kokkos_space> cube_heat_sources, - Kokkos::View *, + Kokkos::View *, typename MemorySpaceType::kokkos_space> goldak_heat_sources, - std::vector> const + std::vector> const &electron_beam_scan_path_segments, - std::vector> const + std::vector> const &goldak_scan_path_segments, std::vector const &electron_beam_indices, std::vector const &cube_indices, - std::vector const &goldak_indices) + std::vector const &goldak_indices, + std::vector const &goldak_scan_files, + std::vector const &electron_beam_scan_files, + std::vector const &goldak_scan_formats, + std::vector const &electron_beam_scan_formats) : _electron_beam_heat_sources(electron_beam_heat_sources), _cube_heat_sources(cube_heat_sources), _goldak_heat_sources(goldak_heat_sources), _electron_beam_scan_path_segments(electron_beam_scan_path_segments), _goldak_scan_path_segments(goldak_scan_path_segments), _electron_beam_indices(electron_beam_indices), - _cube_indices(cube_indices), _goldak_indices(goldak_indices) + _cube_indices(cube_indices), _goldak_indices(goldak_indices), + _goldak_scan_files(goldak_scan_files), + _electron_beam_scan_files(electron_beam_scan_files), + _goldak_scan_formats(goldak_scan_formats), + _electron_beam_scan_formats(electron_beam_scan_formats) { } @@ -324,10 +328,9 @@ double HeatSources::value(dealii::Point const &point, } template -std::vector> -HeatSources::get_scan_paths() const +std::vector HeatSources::get_scan_paths() const { - std::vector> scan_paths; + std::vector scan_paths; for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) scan_paths.push_back(_electron_beam_heat_sources(i).get_scan_path()); for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) @@ -386,23 +389,13 @@ HeatSources::copy_to( return *this; else { - Kokkos::View *, + Kokkos::View *, typename TargetMemorySpaceType::kokkos_space> target_electron_beam_heat_sources( Kokkos::view_alloc(Kokkos::WithoutInitializing, "electron_beam_heat_sources"), _electron_beam_heat_sources.size()); - std::vector> - target_electron_beam_scan_path_segments( - _electron_beam_scan_path_segments.size()); { - for (unsigned int i = 0; i < _electron_beam_scan_path_segments.size(); - ++i) - target_electron_beam_scan_path_segments[i] = - Kokkos::create_mirror_view_and_copy( - typename TargetMemorySpaceType::kokkos_space{}, - _electron_beam_scan_path_segments[i]); auto target_copy_electron_beam_heat_sources = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, _electron_beam_heat_sources); @@ -411,36 +404,25 @@ HeatSources::copy_to( for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) electron_beam_beams[i] = target_copy_electron_beam_heat_sources(i).get_beam_properties(); - std::vector> - electron_beam_heat_source_vector; + std::vector> electron_beam_heat_source_vector; for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) electron_beam_heat_source_vector.emplace_back( electron_beam_beams[i], - ScanPath( - target_electron_beam_scan_path_segments[i])); + ScanPath(_electron_beam_scan_path_segments[i])); Kokkos::deep_copy( target_electron_beam_heat_sources, - Kokkos::View *, - Kokkos::HostSpace>( + Kokkos::View *, Kokkos::HostSpace>( electron_beam_heat_source_vector.data(), electron_beam_heat_source_vector.size())); } - Kokkos::View *, + Kokkos::View *, typename TargetMemorySpaceType::kokkos_space> target_goldak_heat_sources( Kokkos::view_alloc(Kokkos::WithoutInitializing, "goldak_heat_sources"), _goldak_heat_sources.size()); - std::vector> - target_goldak_scan_path_segments(_goldak_scan_path_segments.size()); { - for (unsigned int i = 0; i < _goldak_scan_path_segments.size(); ++i) - target_goldak_scan_path_segments[i] = - Kokkos::create_mirror_view_and_copy( - typename TargetMemorySpaceType::kokkos_space{}, - _goldak_scan_path_segments[i]); auto target_copy_goldak_heat_sources = Kokkos::create_mirror_view_and_copy( typename TargetMemorySpaceType::kokkos_space{}, @@ -450,17 +432,15 @@ HeatSources::copy_to( for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) goldak_beams[i] = target_copy_goldak_heat_sources(i).get_beam_properties(); - std::vector> - goldak_heat_source_vector; + std::vector> goldak_heat_source_vector; for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) goldak_heat_source_vector.emplace_back( - goldak_beams[i], ScanPath( - target_goldak_scan_path_segments[i])); + goldak_beams[i], ScanPath(_goldak_scan_path_segments[i])); Kokkos::deep_copy( target_goldak_heat_sources, - Kokkos::View *, - Kokkos::HostSpace>(goldak_heat_source_vector.data(), - goldak_heat_source_vector.size())); + Kokkos::View *, Kokkos::HostSpace>( + goldak_heat_source_vector.data(), + goldak_heat_source_vector.size())); } auto target_cube_heat_sources = Kokkos::create_mirror_view_and_copy( @@ -469,11 +449,15 @@ HeatSources::copy_to( return {target_electron_beam_heat_sources, target_cube_heat_sources, target_goldak_heat_sources, - target_electron_beam_scan_path_segments, - target_goldak_scan_path_segments, + _electron_beam_scan_path_segments, + _goldak_scan_path_segments, _cube_indices, _electron_beam_indices, - _goldak_indices}; + _goldak_indices, + _goldak_scan_files, + _electron_beam_scan_files, + _goldak_scan_formats, + _electron_beam_scan_formats}; } } diff --git a/source/ScanPath.cc b/source/ScanPath.cc index 6fa8c255..269363a9 100644 --- a/source/ScanPath.cc +++ b/source/ScanPath.cc @@ -8,8 +8,6 @@ #include #include -#include - #include #include @@ -17,10 +15,8 @@ namespace adamantine { -template -std::vector -ScanPath::read_file(std::string scan_path_file, - std::string file_format) +std::vector ScanPath::read_file(std::string scan_path_file, + std::string file_format) { ASSERT_THROW((file_format == "segment") || (file_format == "event_series"), "Error: Format of scan path file not recognized."); @@ -40,9 +36,8 @@ ScanPath::read_file(std::string scan_path_file, return {}; } -template std::vector -ScanPath::load_segment_scan_path(std::string scan_path_file) +ScanPath::load_segment_scan_path(std::string scan_path_file) { std::vector segment_list; std::ifstream file; @@ -121,10 +116,8 @@ ScanPath::load_segment_scan_path(std::string scan_path_file) return segment_list; } -template std::vector -ScanPath::load_event_series_scan_path( - std::string scan_path_file) +ScanPath::load_event_series_scan_path(std::string scan_path_file) { std::vector segment_list; std::ifstream file; @@ -159,8 +152,7 @@ ScanPath::load_event_series_scan_path( return segment_list; } -template -void ScanPath::update_current_segment_info( +void ScanPath::update_current_segment_info( double time, dealii::Point<3> &segment_start_point, double &segment_start_time) const { @@ -183,8 +175,7 @@ void ScanPath::update_current_segment_info( } } -template -dealii::Point<3> ScanPath::value(double const &time) const +dealii::Point<3> ScanPath::value(double const &time) const { // If the current time is after the scan path data is over, return a point // that is (presumably) out of the domain. @@ -211,8 +202,7 @@ dealii::Point<3> ScanPath::value(double const &time) const return position; } -template -double ScanPath::get_power_modifier(double const &time) const +double ScanPath::get_power_modifier(double const &time) const { // If the current time is after the scan path data is over, set the power to // zero. @@ -227,13 +217,9 @@ double ScanPath::get_power_modifier(double const &time) const return _segment_list[_current_segment].power_modifier; } -template -std::vector ScanPath::get_segment_list() const +std::vector ScanPath::get_segment_list() const { return {&_segment_list[0], &_segment_list[0] + _segment_list.size()}; } } // namespace adamantine - -template class adamantine::ScanPath; -template class adamantine::ScanPath; diff --git a/source/ScanPath.hh b/source/ScanPath.hh index 76de5973..14636a70 100644 --- a/source/ScanPath.hh +++ b/source/ScanPath.hh @@ -54,7 +54,6 @@ class ScanPathTester; * gives the power modifier for the current segment. It reads in the scan path * from a text file. */ -template class ScanPath { friend class ScanPathTester; @@ -65,10 +64,9 @@ public: */ ScanPath() = default; - KOKKOS_FUNCTION ScanPath( - Kokkos::View> - scan_path_segments) + KOKKOS_FUNCTION ScanPath(Kokkos::View> + scan_path_segments) : _segment_list(scan_path_segments.data(), scan_path_segments.size()) { } @@ -120,7 +118,7 @@ private: /** * The list of information about each segment in the scan path. */ - Kokkos::View> _segment_list; diff --git a/source/experimental_data_utils.cc b/source/experimental_data_utils.cc index 16dce1ae..d6c7f396 100644 --- a/source/experimental_data_utils.cc +++ b/source/experimental_data_utils.cc @@ -95,9 +95,10 @@ get_expt_to_dof_mapping(PointsValues const &points_values, for (int j = offset[i]; j < offset[i + 1]; ++j) { obs_indices[j] = i; - global_indices[j] = indices_ranks[j].second == my_rank - ? dof_indices[indices_ranks[j].first] - : -1; + global_indices[j] = + indices_ranks[j].second == my_rank + ? static_cast(dof_indices[indices_ranks[j].first]) + : -1; } } diff --git a/source/material_deposition.cc b/source/material_deposition.cc index 5b633f34..c1bf4a0e 100644 --- a/source/material_deposition.cc +++ b/source/material_deposition.cc @@ -134,7 +134,7 @@ template std::tuple>, std::vector, std::vector, std::vector> deposition_along_scan_path(boost::property_tree::ptree const &geometry_database, - ScanPath const &scan_path) + ScanPath const &scan_path) { std::tuple>, std::vector, std::vector, std::vector> @@ -401,12 +401,10 @@ merge_deposition_paths( template std::tuple>, std::vector, std::vector, std::vector> -deposition_along_scan_path( - boost::property_tree::ptree const &geometry_database, - ScanPath const &scan_path); +deposition_along_scan_path(boost::property_tree::ptree const &geometry_database, + ScanPath const &scan_path); template std::tuple>, std::vector, std::vector, std::vector> -deposition_along_scan_path( - boost::property_tree::ptree const &geometry_database, - ScanPath const &scan_path); +deposition_along_scan_path(boost::property_tree::ptree const &geometry_database, + ScanPath const &scan_path); } // namespace adamantine diff --git a/source/material_deposition.hh b/source/material_deposition.hh index 370b8f06..708d8583 100644 --- a/source/material_deposition.hh +++ b/source/material_deposition.hh @@ -43,9 +43,8 @@ read_material_deposition(boost::property_tree::ptree const &geometry_database); template std::tuple>, std::vector, std::vector, std::vector> -deposition_along_scan_path( - boost::property_tree::ptree const &geometry_database, - ScanPath const &scan_path); +deposition_along_scan_path(boost::property_tree::ptree const &geometry_database, + ScanPath const &scan_path); /** * Merge a vector of tuple of bounding boxes, deposition times, cosine of * deposition angles, and sine of deposition angles into a diff --git a/tests/test_heat_source.cc b/tests/test_heat_source.cc index 2cdad877..4e5a53c0 100644 --- a/tests/test_heat_source.cc +++ b/tests/test_heat_source.cc @@ -21,8 +21,7 @@ namespace adamantine template std::tuple, - ElectronBeamHeatSource, - GoldakHeatSource> + ElectronBeamHeatSource, GoldakHeatSource> create_heat_sources(std::string scan_path_file) { boost::property_tree::ptree database; @@ -34,9 +33,8 @@ create_heat_sources(std::string scan_path_file) database.put("scan_path_file", scan_path_file); database.put("scan_path_file_format", "segment"); std::vector scan_path_segments = - ScanPath::read_file( - database.get("scan_path_file"), - database.get("scan_path_file_format")); + ScanPath::read_file(database.get("scan_path_file"), + database.get("scan_path_file_format")); Kokkos::View scan_path_segments_view( "scan_path_segments", scan_path_segments.size()); Kokkos::deep_copy(scan_path_segments_view, @@ -45,11 +43,8 @@ create_heat_sources(std::string scan_path_file) BeamHeatSourceProperties beam(database); return std::tuple( scan_path_segments_view, - ElectronBeamHeatSource{ - database, - ScanPath(scan_path_segments_view)}, - GoldakHeatSource{ - beam, ScanPath(scan_path_segments_view)}); + ElectronBeamHeatSource{database, ScanPath(scan_path_segments_view)}, + GoldakHeatSource{beam, ScanPath(scan_path_segments_view)}); } BOOST_AUTO_TEST_CASE(heat_source_value_2d, *utf::tolerance(1e-12)) diff --git a/tests/test_material_deposition.cc b/tests/test_material_deposition.cc index 6a42b431..f0964989 100644 --- a/tests/test_material_deposition.cc +++ b/tests/test_material_deposition.cc @@ -352,12 +352,11 @@ BOOST_AUTO_TEST_CASE(material_deposition) } std::pair, - adamantine::ScanPath> + adamantine::ScanPath> create_scan_path(std::string file_name) { std::vector scan_path_segments = - adamantine::ScanPath::read_file(file_name, - "segment"); + adamantine::ScanPath::read_file(file_name, "segment"); Kokkos::View scan_path_segments_view("scan_path_segments", scan_path_segments.size()); Kokkos::deep_copy( diff --git a/tests/test_scan_path.cc b/tests/test_scan_path.cc index ad927a01..f50d0482 100644 --- a/tests/test_scan_path.cc +++ b/tests/test_scan_path.cc @@ -21,13 +21,11 @@ class ScanPathTester public: std::vector get_segment_format_list() { - return ScanPath::read_file("scan_path.txt", - "segment"); + return ScanPath::read_file("scan_path.txt", "segment"); }; std::vector get_event_series_format_list() { - return ScanPath::read_file( - "scan_path_event_series.inp", "event_series"); + return ScanPath::read_file("scan_path_event_series.inp", "event_series"); }; }; @@ -76,11 +74,10 @@ BOOST_AUTO_TEST_CASE(scan_path, *utf::tolerance(1e-12)) BOOST_AUTO_TEST_CASE(scan_path_location, *utf::tolerance(1e-10)) { std::vector scan_path_segments = - ScanPath::read_file("scan_path.txt", - "segment"); + ScanPath::read_file("scan_path.txt", "segment"); Kokkos::View scan_paths_segments_view( scan_path_segments.data(), scan_path_segments.size()); - ScanPath scan_path(scan_paths_segments_view); + ScanPath scan_path(scan_paths_segments_view); double time = 1.0e-7; dealii::Point<3> p1 = scan_path.value(time); From 6f13c9574e83eaae6e7ef686fc8f1231d6db34ce Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Tue, 16 Jul 2024 14:44:03 -0400 Subject: [PATCH 30/30] Minimize changes --- application/adamantine.hh | 42 ++--- source/ElectronBeamHeatSource.cc | 6 +- source/ElectronBeamHeatSource.hh | 7 +- source/GoldakHeatSource.cc | 8 +- source/GoldakHeatSource.hh | 7 +- source/HeatSources.hh | 258 +++++----------------------- source/ScanPath.cc | 79 +++++---- source/ScanPath.hh | 49 ++++-- source/ThermalOperator.hh | 11 +- source/ThermalOperator.templates.hh | 9 +- source/ThermalPhysics.hh | 6 +- source/ThermalPhysics.templates.hh | 20 +-- source/ThermalPhysicsInterface.hh | 2 +- source/utils.hh | 30 ++++ tests/CMakeLists.txt | 6 +- tests/test_heat_source.cc | 53 +++--- tests/test_material_deposition.cc | 24 +-- tests/test_scan_path.cc | 12 +- 18 files changed, 243 insertions(+), 386 deletions(-) diff --git a/application/adamantine.hh b/application/adamantine.hh index b4d4fa5f..e0b56976 100644 --- a/application/adamantine.hh +++ b/application/adamantine.hh @@ -570,7 +570,7 @@ void refine_mesh( adamantine::MaterialProperty &material_properties, dealii::LA::distributed::Vector &solution, - adamantine::HeatSources const &heat_sources, + adamantine::HeatSources &heat_sources, double const time, double const next_refinement_time, unsigned int const time_steps_refinement, boost::property_tree::ptree const &refinement_database) @@ -607,9 +607,6 @@ void refine_mesh( const double refinement_beam_cutoff = refinement_database.get("beam_cutoff", 1.0e-15); - adamantine::HeatSources heat_sources_host = - heat_sources.copy_to(dealii::MemorySpace::Host{}); - for (unsigned int i = 0; i < n_refinements; ++i) { // Compute the cells to be refined. @@ -617,7 +614,7 @@ void refine_mesh( dim>::active_cell_iterator> cells_to_refine = compute_cells_to_refine( triangulation, time, next_refinement_time, time_steps_refinement, - heat_sources_host, current_source_height, refinement_beam_cutoff); + heat_sources, current_source_height, refinement_beam_cutoff); // PropertyTreeInput refinement.coarsen_after_beam const bool coarsen_after_beam = @@ -662,7 +659,7 @@ void refine_mesh( adamantine::MaterialProperty &material_properties, dealii::LA::distributed::Vector &solution, - adamantine::HeatSources const &heat_sources, + adamantine::HeatSources &heat_sources, double const time, double const next_refinement_time, unsigned int const time_steps_refinement, boost::property_tree::ptree const &refinement_database) @@ -760,7 +757,7 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database, // Create ThermalPhysics if necessary std::unique_ptr> thermal_physics; - adamantine::HeatSources heat_sources; + adamantine::HeatSources heat_sources; std::vector> scan_path_end; if (use_thermal_physics) { @@ -774,12 +771,10 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database, fe_degree, quadrature_type, communicator, database, geometry, material_properties); heat_sources = thermal_physics->get_heat_sources(); - adamantine::HeatSources heat_sources_host = - heat_sources.copy_to(dealii::MemorySpace::Host{}); // Store the current end time of each heat source and set a flag that the // scan path has changed - auto const &scan_paths = heat_sources_host.get_scan_paths(); + auto const &scan_paths = heat_sources.get_scan_paths(); for (auto const &scan_path : scan_paths) { scan_path_end.emplace_back(scan_path.get_segment_list().back().end_time, @@ -949,14 +944,11 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database, mechanical_physics, displacement, material_properties, timers); ++n_time_step; - adamantine::HeatSources heat_sources_host = - heat_sources.copy_to(dealii::MemorySpace::Host{}); - // Create the bounding boxes used for material deposition auto [material_deposition_boxes, deposition_times, deposition_cos, deposition_sin] = adamantine::create_material_deposition_boxes(geometry_database, - heat_sources_host); + heat_sources); // Extract the time-stepping database boost::property_tree::ptree time_stepping_database = database.get_child("time_stepping"); @@ -1032,11 +1024,7 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database, } if (scan_path_updated) { - adamantine::HeatSources - heat_sources_host = - heat_sources.copy_to(dealii::MemorySpace::Host{}); - heat_sources_host.update_scan_paths(); - heat_sources = heat_sources_host.copy_to(MemorySpaceType{}); + heat_sources.update_scan_paths(); auto const &scan_paths = heat_sources.get_scan_paths(); for (unsigned int s = 0; s < scan_path_end.size(); ++s) @@ -1050,8 +1038,8 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database, std::tie(material_deposition_boxes, deposition_times, deposition_cos, deposition_sin) = - adamantine::create_material_deposition_boxes( - geometry_database, heat_sources_host); + adamantine::create_material_deposition_boxes(geometry_database, + heat_sources); } auto activation_start = @@ -1769,13 +1757,11 @@ run_ensemble(MPI_Comm const &global_communicator, for (unsigned int member = 0; member < local_ensemble_size; ++member) { - refine_mesh( - thermal_physics_ensemble[member], - *material_properties_ensemble[member], - solution_augmented_ensemble[member].block(base_state), - heat_sources_ensemble[member].copy_to(dealii::MemorySpace::Host{}), - time, next_refinement_time, time_steps_refinement, - refinement_database); + refine_mesh(thermal_physics_ensemble[member], + *material_properties_ensemble[member], + solution_augmented_ensemble[member].block(base_state), + heat_sources_ensemble[member], time, next_refinement_time, + time_steps_refinement, refinement_database); solution_augmented_ensemble[member].collect_sizes(); } diff --git a/source/ElectronBeamHeatSource.cc b/source/ElectronBeamHeatSource.cc index 9b636e5c..775b416e 100644 --- a/source/ElectronBeamHeatSource.cc +++ b/source/ElectronBeamHeatSource.cc @@ -16,8 +16,10 @@ namespace adamantine template ElectronBeamHeatSource::ElectronBeamHeatSource( - BeamHeatSourceProperties const &beam, ScanPath const &scan_path) - : _beam(beam), _scan_path(scan_path) + boost::property_tree::ptree const &database) + : _beam(database), + _scan_path(database.get("scan_path_file"), + database.get("scan_path_file_format")) { } diff --git a/source/ElectronBeamHeatSource.hh b/source/ElectronBeamHeatSource.hh index 5782e19c..197cf1f7 100644 --- a/source/ElectronBeamHeatSource.hh +++ b/source/ElectronBeamHeatSource.hh @@ -34,8 +34,7 @@ public: * - input_file: name of the file that contains the scan path * segments */ - ElectronBeamHeatSource(BeamHeatSourceProperties const &beam, - ScanPath const &scan_path); + ElectronBeamHeatSource(boost::property_tree::ptree const &database); /** * Set the time variable. @@ -51,7 +50,7 @@ public: /** * Return the scan path. */ - ScanPath const &get_scan_path() const; + ScanPath &get_scan_path(); void set_scan_path(ScanPath const scan_path) { _scan_path = scan_path; } @@ -80,7 +79,7 @@ private: }; template -ScanPath const &ElectronBeamHeatSource::get_scan_path() const +ScanPath &ElectronBeamHeatSource::get_scan_path() { return _scan_path; } diff --git a/source/GoldakHeatSource.cc b/source/GoldakHeatSource.cc index d61c0e6d..430df25b 100644 --- a/source/GoldakHeatSource.cc +++ b/source/GoldakHeatSource.cc @@ -15,9 +15,11 @@ namespace adamantine { template -GoldakHeatSource::GoldakHeatSource(BeamHeatSourceProperties const &beam, - ScanPath const &scan_path) - : _beam(beam), _scan_path(scan_path) +GoldakHeatSource::GoldakHeatSource( + boost::property_tree::ptree const &database) + : _beam(database), + _scan_path(database.get("scan_path_file"), + database.get("scan_path_file_format")) { } diff --git a/source/GoldakHeatSource.hh b/source/GoldakHeatSource.hh index b502aff6..1edb024d 100644 --- a/source/GoldakHeatSource.hh +++ b/source/GoldakHeatSource.hh @@ -34,8 +34,7 @@ public: * - input_file: name of the file that contains the scan path * segments */ - GoldakHeatSource(BeamHeatSourceProperties const &beam, - ScanPath const &scan_path); + GoldakHeatSource(boost::property_tree::ptree const &database); /** * Set the time variable. @@ -51,7 +50,7 @@ public: /** * Return the scan path. */ - ScanPath const &get_scan_path() const; + ScanPath &get_scan_path(); void set_scan_path(ScanPath const scan_path) { _scan_path = scan_path; } @@ -80,7 +79,7 @@ private: }; template -ScanPath const &GoldakHeatSource::get_scan_path() const +ScanPath &GoldakHeatSource::get_scan_path() { return _scan_path; } diff --git a/source/HeatSources.hh b/source/HeatSources.hh index f1f1f045..d2b26f52 100644 --- a/source/HeatSources.hh +++ b/source/HeatSources.hh @@ -29,14 +29,17 @@ public: /** * Constructor. */ + template >> HeatSources(boost::property_tree::ptree const &source_database); /** * Return a copy of this instance in the target memory space. */ - template - HeatSources - copy_to(TargetMemorySpaceType target_memory_space) const; + // template + // HeatSources + // copy_to(TargetMemorySpaceType target_memory_space) const; /** * Set the time variable. @@ -79,35 +82,21 @@ private: friend class HeatSources; friend class HeatSources; - /** - * Private helper for update_scan_paths - */ - void internal_update_scan_paths(); - /** * Private constructor used by copy_to. */ - HeatSources( - Kokkos::View *, - typename MemorySpaceType::kokkos_space> - electron_beam_heat_sources, - Kokkos::View *, - typename MemorySpaceType::kokkos_space> - cube_heat_sources, - Kokkos::View *, - typename MemorySpaceType::kokkos_space> - goldak_heat_sources, - std::vector> const - &electron_beam_scan_path_segments, - std::vector> const - &goldak_scan_path_segments, - std::vector const &electron_beam_indices, - std::vector const &cube_indices, - std::vector const &goldak_indices, - std::vector const &goldak_scan_files, - std::vector const &electron_beam_scan_files, - std::vector const &goldak_scan_formats, - std::vector const &electron_beam_scan_formats); + HeatSources(Kokkos::View *, + typename MemorySpaceType::kokkos_space> + electron_beam_heat_sources, + Kokkos::View *, + typename MemorySpaceType::kokkos_space> + cube_heat_sources, + Kokkos::View *, + typename MemorySpaceType::kokkos_space> + goldak_heat_sources, + std::vector const &electron_beam_indices, + std::vector const &cube_indices, + std::vector const &goldak_indices); Kokkos::View *, typename MemorySpaceType::kokkos_space> @@ -116,77 +105,30 @@ private: _cube_heat_sources; Kokkos::View *, typename MemorySpaceType::kokkos_space> _goldak_heat_sources; - std::vector> - _electron_beam_scan_path_segments; - std::vector> - _goldak_scan_path_segments; std::vector _electron_beam_indices; std::vector _cube_indices; std::vector _goldak_indices; - - std::vector _goldak_scan_files; - std::vector _electron_beam_scan_files; - std::vector _goldak_scan_formats; - std::vector _electron_beam_scan_formats; }; -template -void HeatSources::internal_update_scan_paths() -{ - std::vector scan_path_segments; - _goldak_scan_path_segments.clear(); - for (unsigned int i = 0; i < _goldak_indices.size(); ++i) - { - scan_path_segments = - ScanPath::read_file(_goldak_scan_files[i], _goldak_scan_formats[i]); - _goldak_scan_path_segments.emplace_back( - Kokkos::view_alloc(Kokkos::WithoutInitializing, - "goldak_scan_path_segments_" + std::to_string(i)), - scan_path_segments.size()); - Kokkos::deep_copy( - _goldak_scan_path_segments.back(), - Kokkos::View( - scan_path_segments.data(), scan_path_segments.size())); - } - _electron_beam_scan_path_segments.clear(); - for (unsigned int i = 0; i < _electron_beam_indices.size(); ++i) - { - scan_path_segments = ScanPath::read_file(_electron_beam_scan_files[i], - _electron_beam_scan_formats[i]); - _electron_beam_scan_path_segments.emplace_back( - Kokkos::view_alloc(Kokkos::WithoutInitializing, - "electron_beam_scan_path_segments_" + - std::to_string(i)), - scan_path_segments.size()); - Kokkos::deep_copy( - _electron_beam_scan_path_segments.back(), - Kokkos::View( - scan_path_segments.data(), scan_path_segments.size())); - } -} - template template std::enable_if_t> HeatSources::update_scan_paths() { - internal_update_scan_paths(); - for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) - _goldak_heat_sources(i).set_scan_path( - ScanPath{_goldak_scan_path_segments[i]}); + _goldak_heat_sources(i).get_scan_path().read_file(); for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) - _electron_beam_heat_sources(i).set_scan_path( - ScanPath{_electron_beam_scan_path_segments[i]}); + _electron_beam_heat_sources(i).get_scan_path().read_file(); } template +template HeatSources::HeatSources( boost::property_tree::ptree const &source_database) { unsigned int const n_beams = source_database.get("n_beams"); - std::vector goldak_beams; - std::vector electron_beam_beams; + std::vector> goldak_heat_sources; + std::vector> electron_beam_heat_sources; std::vector> cube_heat_sources; for (unsigned int i = 0; i < n_beams; ++i) @@ -196,21 +138,13 @@ HeatSources::HeatSources( std::string type = beam_database.get("type"); if (type == "goldak") { - goldak_beams.emplace_back(beam_database); + goldak_heat_sources.emplace_back(beam_database); _goldak_indices.push_back(i); - _goldak_scan_files.push_back( - beam_database.get("scan_path_file")); - _goldak_scan_formats.push_back( - beam_database.get("scan_path_file_format")); } else if (type == "electron_beam") { - electron_beam_beams.emplace_back(beam_database); + electron_beam_heat_sources.emplace_back(beam_database); _electron_beam_indices.push_back(i); - _electron_beam_scan_files.push_back( - beam_database.get("scan_path_file")); - _electron_beam_scan_formats.push_back( - beam_database.get("scan_path_file_format")); } else if (type == "cube") { @@ -224,46 +158,31 @@ HeatSources::HeatSources( "' not recognized."); } } - - internal_update_scan_paths(); - - std::vector> goldak_heat_sources; - for (unsigned int i = 0; i < goldak_beams.size(); ++i) - { - goldak_heat_sources.emplace_back( - goldak_beams[i], ScanPath(_goldak_scan_path_segments.back())); - } - - std::vector> electron_beam_heat_sources; - for (unsigned int i = 0; i < electron_beam_beams.size(); ++i) - { - electron_beam_heat_sources.emplace_back( - electron_beam_beams[i], - ScanPath(_electron_beam_scan_path_segments.back())); - } - - _goldak_heat_sources = decltype(_goldak_heat_sources)( - Kokkos::view_alloc(Kokkos::WithoutInitializing, "goldak_heat_sources"), + _goldak_heat_sources = Kokkos::View *, + typename MemorySpaceType::kokkos_space>( + Kokkos::view_alloc(Kokkos::WithoutInitializing, "KokkosGoldakHeatSourcs"), goldak_heat_sources.size()); - _electron_beam_heat_sources = decltype(_electron_beam_heat_sources)( - Kokkos::view_alloc(Kokkos::WithoutInitializing, - "electron_beam_heat_sources"), - electron_beam_heat_sources.size()); - _cube_heat_sources = decltype(_cube_heat_sources)( - Kokkos::view_alloc(Kokkos::WithoutInitializing, "cube_heat_sources"), - cube_heat_sources.size()); Kokkos::deep_copy( _goldak_heat_sources, Kokkos::View *, Kokkos::HostSpace>( goldak_heat_sources.data(), goldak_heat_sources.size())); + _electron_beam_heat_sources = + Kokkos::View *, + typename MemorySpaceType::kokkos_space>( + Kokkos::view_alloc(Kokkos::WithoutInitializing, + "ElectronBeamHeatSources"), + electron_beam_heat_sources.size()); Kokkos::deep_copy( _electron_beam_heat_sources, Kokkos::View *, Kokkos::HostSpace>( electron_beam_heat_sources.data(), electron_beam_heat_sources.size())); + _cube_heat_sources = Kokkos::View *, + typename MemorySpaceType::kokkos_space>( + Kokkos::view_alloc(Kokkos::WithoutInitializing, "CubeHeatSources"), + cube_heat_sources.size()); Kokkos::deep_copy(_cube_heat_sources, - Kokkos::View *, - typename MemorySpaceType::kokkos_space>( + Kokkos::View *, Kokkos::HostSpace>( cube_heat_sources.data(), cube_heat_sources.size())); } @@ -277,28 +196,14 @@ HeatSources::HeatSources( Kokkos::View *, typename MemorySpaceType::kokkos_space> goldak_heat_sources, - std::vector> const - &electron_beam_scan_path_segments, - std::vector> const - &goldak_scan_path_segments, std::vector const &electron_beam_indices, std::vector const &cube_indices, - std::vector const &goldak_indices, - std::vector const &goldak_scan_files, - std::vector const &electron_beam_scan_files, - std::vector const &goldak_scan_formats, - std::vector const &electron_beam_scan_formats) + std::vector const &goldak_indices) : _electron_beam_heat_sources(electron_beam_heat_sources), _cube_heat_sources(cube_heat_sources), _goldak_heat_sources(goldak_heat_sources), - _electron_beam_scan_path_segments(electron_beam_scan_path_segments), - _goldak_scan_path_segments(goldak_scan_path_segments), _electron_beam_indices(electron_beam_indices), - _cube_indices(cube_indices), _goldak_indices(goldak_indices), - _goldak_scan_files(goldak_scan_files), - _electron_beam_scan_files(electron_beam_scan_files), - _goldak_scan_formats(goldak_scan_formats), - _electron_beam_scan_formats(electron_beam_scan_formats) + _cube_indices(cube_indices), _goldak_indices(goldak_indices) { } @@ -378,88 +283,15 @@ void HeatSources::set_beam_properties( for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) set_properties(_goldak_heat_sources[i], _goldak_indices[i]); } - +/* template template HeatSources HeatSources::copy_to( - TargetMemorySpaceType /*target_memory_space*/) const + TargetMemorySpaceType target_memory_space) const { - if constexpr (std::is_same_v) - return *this; - else - { - Kokkos::View *, - typename TargetMemorySpaceType::kokkos_space> - target_electron_beam_heat_sources( - Kokkos::view_alloc(Kokkos::WithoutInitializing, - "electron_beam_heat_sources"), - _electron_beam_heat_sources.size()); - { - auto target_copy_electron_beam_heat_sources = - Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, - _electron_beam_heat_sources); - std::vector electron_beam_beams( - _electron_beam_heat_sources.size()); - for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) - electron_beam_beams[i] = - target_copy_electron_beam_heat_sources(i).get_beam_properties(); - std::vector> electron_beam_heat_source_vector; - for (unsigned int i = 0; i < _electron_beam_heat_sources.size(); ++i) - electron_beam_heat_source_vector.emplace_back( - electron_beam_beams[i], - ScanPath(_electron_beam_scan_path_segments[i])); - Kokkos::deep_copy( - target_electron_beam_heat_sources, - Kokkos::View *, Kokkos::HostSpace>( - electron_beam_heat_source_vector.data(), - electron_beam_heat_source_vector.size())); - } - - Kokkos::View *, - typename TargetMemorySpaceType::kokkos_space> - target_goldak_heat_sources( - Kokkos::view_alloc(Kokkos::WithoutInitializing, - "goldak_heat_sources"), - _goldak_heat_sources.size()); - { - auto target_copy_goldak_heat_sources = - Kokkos::create_mirror_view_and_copy( - typename TargetMemorySpaceType::kokkos_space{}, - _goldak_heat_sources); - std::vector goldak_beams( - _goldak_heat_sources.size()); - for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) - goldak_beams[i] = - target_copy_goldak_heat_sources(i).get_beam_properties(); - std::vector> goldak_heat_source_vector; - for (unsigned int i = 0; i < _goldak_heat_sources.size(); ++i) - goldak_heat_source_vector.emplace_back( - goldak_beams[i], ScanPath(_goldak_scan_path_segments[i])); - Kokkos::deep_copy( - target_goldak_heat_sources, - Kokkos::View *, Kokkos::HostSpace>( - goldak_heat_source_vector.data(), - goldak_heat_source_vector.size())); - } - - auto target_cube_heat_sources = Kokkos::create_mirror_view_and_copy( - typename TargetMemorySpaceType::kokkos_space{}, _cube_heat_sources); - - return {target_electron_beam_heat_sources, - target_cube_heat_sources, - target_goldak_heat_sources, - _electron_beam_scan_path_segments, - _goldak_scan_path_segments, - _cube_indices, - _electron_beam_indices, - _goldak_indices, - _goldak_scan_files, - _electron_beam_scan_files, - _goldak_scan_formats, - _electron_beam_scan_formats}; - } -} + return {}; +}*/ } // namespace adamantine diff --git a/source/ScanPath.cc b/source/ScanPath.cc index 269363a9..8370f66c 100644 --- a/source/ScanPath.cc +++ b/source/ScanPath.cc @@ -14,34 +14,38 @@ namespace adamantine { - -std::vector ScanPath::read_file(std::string scan_path_file, - std::string file_format) +ScanPath::ScanPath(std::string scan_path_file, std::string file_format) + : _scan_path_file(scan_path_file), _file_format(file_format) { - ASSERT_THROW((file_format == "segment") || (file_format == "event_series"), + ASSERT_THROW((_file_format == "segment") || (_file_format == "event_series"), "Error: Format of scan path file not recognized."); - wait_for_file(scan_path_file, - "Waiting for scan path file: " + scan_path_file); + wait_for_file(_scan_path_file, + "Waiting for scan path file: " + _scan_path_file); + + read_file(); +} - if (file_format == "segment") +void ScanPath::read_file() +{ + wait_for_file_to_update(_scan_path_file, "Waiting for " + _scan_path_file, + _last_write_time); + + if (_file_format == "segment") { - return load_segment_scan_path(scan_path_file); + load_segment_scan_path(); } else { - return load_event_series_scan_path(scan_path_file); + load_event_series_scan_path(); } - - return {}; } -std::vector -ScanPath::load_segment_scan_path(std::string scan_path_file) +void ScanPath::load_segment_scan_path() { - std::vector segment_list; + _segment_list.clear(); std::ifstream file; - file.open(scan_path_file); + file.open(_scan_path_file); std::string line; unsigned int data_index = 0; // Skip first line @@ -55,6 +59,13 @@ ScanPath::load_segment_scan_path(std::string scan_path_file) // segments to read, whichever comes first while ((data_index < n_segments) && (getline(file, line))) { + // If we reach the end of the scan path, we stop reading the file. + if (line.find("SCAN_PATH_END") != std::string::npos) + { + _scan_path_end = true; + break; + } + std::vector split_line; boost::split(split_line, line, boost::is_any_of(" "), boost::token_compress_on); @@ -66,7 +77,7 @@ ScanPath::load_segment_scan_path(std::string scan_path_file) { // Check to make sure the segment isn't the first, if it is, throw an // exception (the first segment must be a point in the spec). - ASSERT_THROW(segment_list.size() > 0, + ASSERT_THROW(_segment_list.size() > 0, "Error: Scan paths must begin with a 'point' segment."); } else if (split_line[0] == "1") @@ -91,10 +102,10 @@ ScanPath::load_segment_scan_path(std::string scan_path_file) // Set the velocity and end time if (segment_type == ScanPathSegmentType::point) { - if (segment_list.size() > 0) + if (_segment_list.size() > 0) { segment.end_time = - segment_list.back().end_time + std::stod(split_line[5]); + _segment_list.back().end_time + std::stod(split_line[5]); } else { @@ -105,28 +116,33 @@ ScanPath::load_segment_scan_path(std::string scan_path_file) { double velocity = std::stod(split_line[5]); double line_length = - segment.end_point.distance(segment_list.back().end_point); + segment.end_point.distance(_segment_list.back().end_point); segment.end_time = - segment_list.back().end_time + std::abs(line_length / velocity); + _segment_list.back().end_time + std::abs(line_length / velocity); } - segment_list.push_back(segment); + _segment_list.push_back(segment); data_index++; } file.close(); - return segment_list; } -std::vector -ScanPath::load_event_series_scan_path(std::string scan_path_file) +void ScanPath::load_event_series_scan_path() { - std::vector segment_list; + _segment_list.clear(); std::ifstream file; - file.open(scan_path_file); + file.open(_scan_path_file); std::string line; double last_power = 0.0; while (getline(file, line)) { + // If we reach the end of the scan path, we stop reading the file. + if (line.find("SCAN_PATH_END") != std::string::npos) + { + _scan_path_end = true; + break; + } + // For an event series the first segment is a ScanPathSegment point, then // the rest are ScanPathSegment lines ScanPathSegment segment; @@ -147,9 +163,8 @@ ScanPath::load_event_series_scan_path(std::string scan_path_file) segment.power_modifier = last_power; last_power = std::stod(split_line[4]); - segment_list.push_back(segment); + _segment_list.push_back(segment); } - return segment_list; } void ScanPath::update_current_segment_info( @@ -179,7 +194,7 @@ dealii::Point<3> ScanPath::value(double const &time) const { // If the current time is after the scan path data is over, return a point // that is (presumably) out of the domain. - if (time > _segment_list[_segment_list.size() - 1].end_time) + if (time > _segment_list.back().end_time) { dealii::Point<3> out_of_domain_point(std::numeric_limits::lowest(), std::numeric_limits::lowest(), @@ -206,7 +221,7 @@ double ScanPath::get_power_modifier(double const &time) const { // If the current time is after the scan path data is over, set the power to // zero. - if (time > _segment_list[_segment_list.size() - 1].end_time) + if (time > _segment_list.back().end_time) return 0.0; // Get to the correct segment @@ -219,7 +234,9 @@ double ScanPath::get_power_modifier(double const &time) const std::vector ScanPath::get_segment_list() const { - return {&_segment_list[0], &_segment_list[0] + _segment_list.size()}; + return _segment_list; } +bool ScanPath::is_finished() const { return _scan_path_end; } + } // namespace adamantine diff --git a/source/ScanPath.hh b/source/ScanPath.hh index 14636a70..b7354e4c 100644 --- a/source/ScanPath.hh +++ b/source/ScanPath.hh @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -64,15 +65,13 @@ public: */ ScanPath() = default; - KOKKOS_FUNCTION ScanPath(Kokkos::View> - scan_path_segments) - : _segment_list(scan_path_segments.data(), scan_path_segments.size()) - { - } - - static std::vector read_file(std::string scan_path_file, - std::string file_format); + /** + * Construtor. + * \param[in] scan_path_file is the name of the text file containing the scan + * path + * \param[in] file_format is the format of the scan path file + */ + ScanPath(std::string scan_path_file, std::string file_format); /** * Calculate the location of the scan path at a given time for a single @@ -95,18 +94,21 @@ public: */ void read_file(); + /** + * Return true if we reach the end of the scan path. + */ + bool is_finished() const; + private: /** * Method to load a "segment" scan path file */ - static std::vector - load_segment_scan_path(std::string scan_path_file); + void load_segment_scan_path(); /** * Method to load an "event series" scan path file */ - static std::vector - load_event_series_scan_path(std::string scan_path_file); + void load_event_series_scan_path(); /** * Method to determine the current segment, its start point, and start time. @@ -115,13 +117,26 @@ private: dealii::Point<3> &segment_start_point, double &segment_start_time) const; + /** + * Flag is true if we have reached the end of _scan_path_file. + */ + bool _scan_path_end = false; + /** + * File name of the scan path + */ + std::string _scan_path_file; + /** + * Format of the scan path file, either segment of event_series. + */ + std::string _file_format; + /** + * Time the last time _scan_path_file was updated. + */ + std::filesystem::file_time_type _last_write_time; /** * The list of information about each segment in the scan path. */ - Kokkos::View> - _segment_list; - + std::vector _segment_list; /** * The index of the current segment in the scan path. */ diff --git a/source/ThermalOperator.hh b/source/ThermalOperator.hh index 15a3afec..5caf4e4e 100644 --- a/source/ThermalOperator.hh +++ b/source/ThermalOperator.hh @@ -28,10 +28,11 @@ template { public: - ThermalOperator(MPI_Comm const &communicator, BoundaryType boundary_type, - MaterialProperty &material_properties, - HeatSources const &heat_sources); + ThermalOperator( + MPI_Comm const &communicator, BoundaryType boundary_type, + MaterialProperty + &material_properties, + HeatSources const &heat_sources); /** * Associate the AffineConstraints and the MatrixFree objects to the @@ -195,7 +196,7 @@ private: /** * Vector of heat sources. */ - HeatSources _heat_sources; + HeatSources _heat_sources; /** * Underlying MatrixFree object. */ diff --git a/source/ThermalOperator.templates.hh b/source/ThermalOperator.templates.hh index 82c71b3b..a74092a2 100644 --- a/source/ThermalOperator.templates.hh +++ b/source/ThermalOperator.templates.hh @@ -30,10 +30,11 @@ template ThermalOperator:: - ThermalOperator(MPI_Comm const &communicator, BoundaryType boundary_type, - MaterialProperty &material_properties, - HeatSources const &heat_sources) + ThermalOperator( + MPI_Comm const &communicator, BoundaryType boundary_type, + MaterialProperty + &material_properties, + HeatSources const &heat_sources) : _communicator(communicator), _boundary_type(boundary_type), _material_properties(material_properties), _heat_sources(heat_sources), _inverse_mass_matrix( diff --git a/source/ThermalPhysics.hh b/source/ThermalPhysics.hh index da27ac5f..8d6d03a6 100644 --- a/source/ThermalPhysics.hh +++ b/source/ThermalPhysics.hh @@ -112,7 +112,7 @@ public: dealii::AffineConstraints &get_affine_constraints() override; - HeatSources &get_heat_sources() override; + HeatSources &get_heat_sources() override; unsigned int get_fe_degree() const override; @@ -220,7 +220,7 @@ private: /** * Vector of heat sources. */ - mutable HeatSources _heat_sources; + mutable HeatSources _heat_sources; /** * Shared pointer to the underlying ThermalOperator. */ @@ -324,7 +324,7 @@ ThermalPhysics -inline HeatSources & +inline HeatSources & ThermalPhysics::get_heat_sources() { diff --git a/source/ThermalPhysics.templates.hh b/source/ThermalPhysics.templates.hh index 79b0ca8b..97b92d5c 100644 --- a/source/ThermalPhysics.templates.hh +++ b/source/ThermalPhysics.templates.hh @@ -95,7 +95,7 @@ evaluate_thermal_physics_impl( &thermal_operator, dealii::hp::FECollection const &fe_collection, double const t, dealii::DoFHandler const &dof_handler, - HeatSources &heat_sources, + HeatSources &heat_sources, double current_source_height, BoundaryType boundary_type, MaterialProperty &material_properties, @@ -120,8 +120,7 @@ evaluate_thermal_physics_impl( // Compute the source term. // TODO do this on the GPU - auto heat_sources_host = heat_sources.copy_to(dealii::MemorySpace::Host{}); - heat_sources_host.update_time(t); + heat_sources.update_time(t); dealii::LA::distributed::Vector source( y.get_partitioner()); source = 0.; @@ -166,8 +165,7 @@ evaluate_thermal_physics_impl( double const inv_rho_cp = thermal_operator_dev->get_inv_rho_cp(cell, q); double quad_pt_source = 0.; dealii::Point const &q_point = fe_values.quadrature_point(q); - quad_pt_source += - heat_sources_host.value(q_point, current_source_height); + quad_pt_source += heat_sources.value(q_point, current_source_height); cell_source[i] += inv_rho_cp * quad_pt_source * fe_values.shape_value(i, q) * fe_values.JxW(q); @@ -289,7 +287,7 @@ ThermalPhysics(source_database); + _heat_sources = HeatSources(source_database); // Create the boundary condition type // PropertyTreeInput boundary.type @@ -466,8 +464,7 @@ ThermalPhysicsset_active_fe_index(1); } - auto heat_sources_host = _heat_sources.copy_to(dealii::MemorySpace::Host{}); - _current_source_height = heat_sources_host.get_current_height(0.0); + _current_source_height = _heat_sources.get_current_height(0.0); } template &solution, std::vector &timers) { - _current_source_height = - _heat_sources.copy_to(dealii::MemorySpace::Host{}).get_current_height(t); + _current_source_height = _heat_sources.get_current_height(t); auto eval = [&](double const t, LA_Vector const &y) { return evaluate_thermal_physics(t, y, timers); }; diff --git a/source/ThermalPhysicsInterface.hh b/source/ThermalPhysicsInterface.hh index 778973a2..28bc6aae 100644 --- a/source/ThermalPhysicsInterface.hh +++ b/source/ThermalPhysicsInterface.hh @@ -172,7 +172,7 @@ public: /** * Return the heat sources. */ - virtual HeatSources &get_heat_sources() = 0; + virtual HeatSources &get_heat_sources() = 0; /** * Return the degree of the finite element. diff --git a/source/utils.hh b/source/utils.hh index 197c994c..9f04ed7f 100644 --- a/source/utils.hh +++ b/source/utils.hh @@ -38,6 +38,36 @@ inline void wait_for_file(std::string const &filename, } } +/** + * Wait for the file to be updated. + */ +inline void +wait_for_file_to_update(std::string const &filename, std::string const &message, + std::filesystem::file_time_type &last_write_time) +{ + unsigned int counter = 1; + // We check when the file was last written to know if he file was updated. + // When the file is being overwritten, the last_write_time() function throws + // an error. Since it's an "expected" behavior, we just catch the error keep + // working. + try + { + while (std::filesystem::last_write_time(filename) == last_write_time) + { + // Spin loop waiting for the file to be updated (message printed if + // counter overflows) + if (counter == 0) + std::cout << message << std::endl; + ++counter; + } + } + catch (std::filesystem::filesystem_error) + { + // No-op + } + last_write_time = std::filesystem::last_write_time(filename); +} + #define ASSERT(condition, message) assert((condition) && (message)) inline void ASSERT_THROW(bool cond, std::string const &message) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e9290c69..e71ee4d4 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -15,8 +15,6 @@ list(APPEND test_integration_thermoelastic test_material_property test_material_property_device - test_mechanical_operator - test_mechanical_physics test_newton_solver test_post_processor test_scan_path @@ -39,7 +37,9 @@ list(APPEND test_integration_3d_amr_device test_integration_da_augmented test_material_deposition - test_thermal_physics + test_mechanical_operator + test_mechanical_physics +test_thermal_physics test_ensemble_management ) diff --git a/tests/test_heat_source.cc b/tests/test_heat_source.cc index 4e5a53c0..a6d6a70e 100644 --- a/tests/test_heat_source.cc +++ b/tests/test_heat_source.cc @@ -19,10 +19,7 @@ namespace utf = boost::unit_test; namespace adamantine { -template -std::tuple, - ElectronBeamHeatSource, GoldakHeatSource> -create_heat_sources(std::string scan_path_file) +BOOST_AUTO_TEST_CASE(heat_source_value_2d, *utf::tolerance(1e-12)) { boost::property_tree::ptree database; @@ -30,27 +27,10 @@ create_heat_sources(std::string scan_path_file) database.put("absorption_efficiency", 0.1); database.put("diameter", 1.0); database.put("max_power", 10.); - database.put("scan_path_file", scan_path_file); + database.put("scan_path_file", "scan_path.txt"); database.put("scan_path_file_format", "segment"); - std::vector scan_path_segments = - ScanPath::read_file(database.get("scan_path_file"), - database.get("scan_path_file_format")); - Kokkos::View scan_path_segments_view( - "scan_path_segments", scan_path_segments.size()); - Kokkos::deep_copy(scan_path_segments_view, - Kokkos::View{ - scan_path_segments.data(), scan_path_segments.size()}); - BeamHeatSourceProperties beam(database); - return std::tuple( - scan_path_segments_view, - ElectronBeamHeatSource{database, ScanPath(scan_path_segments_view)}, - GoldakHeatSource{beam, ScanPath(scan_path_segments_view)}); -} - -BOOST_AUTO_TEST_CASE(heat_source_value_2d, *utf::tolerance(1e-12)) -{ - auto [scan_paths_segments, eb_heat_source, goldak_heat_source] = - create_heat_sources<2>("scan_path.txt"); + GoldakHeatSource<2> goldak_heat_source(database); + ElectronBeamHeatSource<2> eb_heat_source(database); double g_value = 0.0; double eb_value = 0.0; @@ -121,8 +101,17 @@ BOOST_AUTO_TEST_CASE(heat_source_value_2d, *utf::tolerance(1e-12)) BOOST_AUTO_TEST_CASE(heat_source_value_3d, *utf::tolerance(1e-12)) { - auto [scan_paths_segments, eb_heat_source, goldak_heat_source] = - create_heat_sources<3>("scan_path.txt"); + boost::property_tree::ptree database; + + database.put("depth", 0.1); + database.put("absorption_efficiency", 0.1); + database.put("diameter", 1.0); + database.put("max_power", 10.); + database.put("scan_path_file", "scan_path.txt"); + database.put("scan_path_file_format", "segment"); + + GoldakHeatSource<3> goldak_heat_source(database); + ElectronBeamHeatSource<3> eb_heat_source(database); double g_value = 0.0; double eb_value = 0.0; @@ -181,8 +170,16 @@ BOOST_AUTO_TEST_CASE(heat_source_value_3d, *utf::tolerance(1e-12)) BOOST_AUTO_TEST_CASE(heat_source_height, *utf::tolerance(1e-12)) { - auto [scan_paths_segments, eb_heat_source, goldak_heat_source] = - create_heat_sources<2>("scan_path_layers.txt"); + boost::property_tree::ptree database; + + database.put("depth", 0.1); + database.put("absorption_efficiency", 0.1); + database.put("diameter", 1.0); + database.put("max_power", 10.); + database.put("scan_path_file", "scan_path_layers.txt"); + database.put("scan_path_file_format", "segment"); + GoldakHeatSource<2> goldak_heat_source(database); + ElectronBeamHeatSource<2> eb_heat_source(database); double g_height = 0.0; double eb_height = 0.0; diff --git a/tests/test_material_deposition.cc b/tests/test_material_deposition.cc index f0964989..c33a69f8 100644 --- a/tests/test_material_deposition.cc +++ b/tests/test_material_deposition.cc @@ -351,24 +351,9 @@ BOOST_AUTO_TEST_CASE(material_deposition) } } -std::pair, - adamantine::ScanPath> -create_scan_path(std::string file_name) -{ - std::vector scan_path_segments = - adamantine::ScanPath::read_file(file_name, "segment"); - Kokkos::View - scan_path_segments_view("scan_path_segments", scan_path_segments.size()); - Kokkos::deep_copy( - scan_path_segments_view, - Kokkos::View{ - scan_path_segments.data(), scan_path_segments.size()}); - return {scan_path_segments_view, {scan_path_segments_view}}; -} - BOOST_AUTO_TEST_CASE(deposition_from_scan_path_2d, *utf::tolerance(1e-13)) { - auto [scan_path_segments, scan_path] = create_scan_path("scan_path.txt"); + adamantine::ScanPath scan_path("scan_path.txt", "segment"); boost::property_tree::ptree database; database.put("deposition_length", 0.0005); @@ -416,7 +401,7 @@ BOOST_AUTO_TEST_CASE(deposition_from_scan_path_2d, *utf::tolerance(1e-13)) BOOST_AUTO_TEST_CASE(deposition_from_scan_path_3d, *utf::tolerance(1e-13)) { - auto [scan_path_segments, scan_path] = create_scan_path("scan_path.txt"); + adamantine::ScanPath scan_path("scan_path.txt", "segment"); boost::property_tree::ptree database; database.put("deposition_length", 0.0005); @@ -468,7 +453,7 @@ BOOST_AUTO_TEST_CASE(deposition_from_scan_path_3d, *utf::tolerance(1e-13)) BOOST_AUTO_TEST_CASE(deposition_from_L_scan_path_3d, *utf::tolerance(1e-13)) { - auto [scan_path_segments, scan_path] = create_scan_path("scan_path_L.txt"); + adamantine::ScanPath scan_path("scan_path_L.txt", "segment"); boost::property_tree::ptree database; database.put("deposition_length", 0.0005); @@ -554,8 +539,7 @@ BOOST_AUTO_TEST_CASE(deposition_from_L_scan_path_3d, *utf::tolerance(1e-13)) BOOST_AUTO_TEST_CASE(deposition_from_diagonal_scan_path_3d, *utf::tolerance(1e-10)) { - auto [scan_path_segments, scan_path] = - create_scan_path("scan_path_diagonal.txt"); + adamantine::ScanPath scan_path("scan_path_diagonal.txt", "segment"); boost::property_tree::ptree database; database.put("deposition_length", 0.0005); diff --git a/tests/test_scan_path.cc b/tests/test_scan_path.cc index f50d0482..b9226180 100644 --- a/tests/test_scan_path.cc +++ b/tests/test_scan_path.cc @@ -21,11 +21,13 @@ class ScanPathTester public: std::vector get_segment_format_list() { - return ScanPath::read_file("scan_path.txt", "segment"); + ScanPath scan_path("scan_path.txt", "segment"); + return scan_path._segment_list; }; std::vector get_event_series_format_list() { - return ScanPath::read_file("scan_path_event_series.inp", "event_series"); + ScanPath scan_path("scan_path_event_series.inp", "event_series"); + return scan_path._segment_list; }; }; @@ -73,11 +75,7 @@ BOOST_AUTO_TEST_CASE(scan_path, *utf::tolerance(1e-12)) BOOST_AUTO_TEST_CASE(scan_path_location, *utf::tolerance(1e-10)) { - std::vector scan_path_segments = - ScanPath::read_file("scan_path.txt", "segment"); - Kokkos::View scan_paths_segments_view( - scan_path_segments.data(), scan_path_segments.size()); - ScanPath scan_path(scan_paths_segments_view); + ScanPath scan_path("scan_path.txt", "segment"); double time = 1.0e-7; dealii::Point<3> p1 = scan_path.value(time);