7 #ifndef PORTAGE_GENREMAP_DRIVER_H_ 8 #define PORTAGE_GENREMAP_DRIVER_H_ 18 #include <type_traits> 23 #include "tangram/driver/driver.h" 24 #include "tangram/intersect/split_r2d.h" 25 #include "tangram/intersect/split_r3d.h" 37 #include "wonton/mesh/flat/flat_mesh_wrapper.h" 38 #include "wonton/state/flat/flat_state_mm_wrapper.h" 39 #include "wonton/support/Point.h" 40 #include "wonton/state/state_vector_multi.h" 44 #ifdef PORTAGE_ENABLE_MPI 63 using Wonton::Flat_Mesh_Wrapper;
64 using Wonton::Flat_State_Wrapper;
93 class SourceMesh,
class SourceState,
94 class TargetMesh = SourceMesh,
class TargetState = SourceState,
95 template <
class,
int,
class,
class>
class InterfaceReconstructorType =
96 DummyInterfaceReconstructor,
97 class Matpoly_Splitter = void,
class Matpoly_Clipper = void,
98 class CoordSys = Wonton::DefaultCoordSys
107 TargetMesh, TargetState,
108 InterfaceReconstructorType,
109 Matpoly_Splitter, Matpoly_Clipper, CoordSys>;
114 Flat_State_Wrapper<Flat_Mesh_Wrapper<>>,
115 TargetMesh, TargetState,
116 InterfaceReconstructorType,
117 Matpoly_Splitter, Matpoly_Clipper, CoordSys>;
132 SourceState
const& source_state,
133 TargetMesh
const& target_mesh,
134 TargetState& target_state,
135 std::vector<std::string>
const& source_vars_to_remap,
136 Wonton::Executor_type
const *executor =
nullptr,
137 std::string *errmsg =
nullptr)
138 : source_mesh_(source_mesh),
139 target_mesh_(target_mesh),
140 source_state_(source_state),
141 target_state_(target_state),
142 dim_(source_mesh.space_dimension()),
143 source_vars_to_remap_(source_vars_to_remap),
144 executor_(executor) {
146 assert(source_mesh.space_dimension() == target_mesh.space_dimension());
151 entity_kinds_.clear();
152 for (
auto const& source_varname : source_vars_to_remap_) {
153 Entity_kind onwhat = source_state_.get_entity(source_varname);
154 if (std::find(entity_kinds_.begin(), entity_kinds_.end(), onwhat) ==
156 entity_kinds_.push_back(onwhat);
158 Field_type fieldtype = source_state_.field_type(onwhat, source_varname);
159 if (std::find(field_types_.begin(), field_types_.end(), fieldtype) ==
161 field_types_.push_back(fieldtype);
163 if (fieldtype == Field_type::MULTIMATERIAL_FIELD)
164 have_multi_material_fields_ =
true;
169 instantiate_core_drivers();
182 SourceState
const& source_state,
183 TargetMesh
const& target_mesh,
184 TargetState& target_state,
185 Wonton::Executor_type
const *executor =
nullptr,
186 std::string *errmsg =
nullptr)
187 : source_mesh_(source_mesh),
188 target_mesh_(target_mesh),
189 source_state_(source_state),
190 target_state_(target_state),
191 dim_(source_mesh.space_dimension()),
192 executor_(executor) {
194 assert(source_mesh.space_dimension() == target_mesh.space_dimension());
198 if (source_vars_to_remap_.size() == 0)
199 source_vars_to_remap_ = source_state_.names();
204 entity_kinds_.clear();
205 for (
auto const& source_varname : source_vars_to_remap_) {
206 Entity_kind onwhat = source_state_.get_entity(source_varname);
207 if (std::find(entity_kinds_.begin(), entity_kinds_.end(), onwhat) ==
209 entity_kinds_.push_back(onwhat);
211 Field_type fieldtype = source_state_.field_type(onwhat, source_varname);
212 if (std::find(field_types_.begin(), field_types_.end(), fieldtype) ==
214 field_types_.push_back(fieldtype);
216 if (fieldtype == Field_type::MULTIMATERIAL_FIELD)
217 have_multi_material_fields_ =
true;
222 instantiate_core_drivers();
241 distributed_ =
false;
243 #ifdef PORTAGE_ENABLE_MPI 244 mycomm_ = MPI_COMM_NULL;
245 auto mpiexecutor =
dynamic_cast<Wonton::MPIExecutor_type
const *
>(executor);
246 if (mpiexecutor && mpiexecutor->mpicomm != MPI_COMM_NULL) {
247 mycomm_ = mpiexecutor->mpicomm;
248 MPI_Comm_size(mycomm_, &nprocs_);
286 template <
int, Entity_kind,
class,
class>
class Search,
287 template <Entity_kind,
class,
class,
class,
288 template <
class,
int,
class,
class>
class,
295 for (Entity_kind onwhat : entity_kinds_) {
299 intersection_candidates = search<CELL, Search>();
302 source_weights_[onwhat] =
303 intersect_meshes<CELL, Intersect>(intersection_candidates);
305 if (have_multi_material_fields_) {
306 mat_intersection_completed_ =
true;
308 source_weights_by_mat_ =
309 intersect_materials<Intersect>(intersection_candidates);
315 intersection_candidates = search<NODE, Search>();
318 source_weights_[onwhat] =
319 intersect_meshes<NODE, Intersect>(intersection_candidates);
324 std::cerr <<
"Cannot remap on " <<
to_string(onwhat) <<
"\n";
343 const double min_absolute_volume) {
344 for (Entity_kind onwhat : entity_kinds_) {
347 core_driver_serial_[CELL]->template set_num_tols<CELL>(
348 min_absolute_distance, min_absolute_volume);
break;
350 core_driver_serial_[NODE]->template set_num_tols<NODE>(
351 min_absolute_distance, min_absolute_volume);
break;
353 std::cerr <<
"Cannot remap on " <<
to_string(onwhat) <<
"\n";
367 for (Entity_kind onwhat : entity_kinds_) {
370 core_driver_serial_[CELL]->template set_num_tols<CELL>(num_tols);
break;
372 core_driver_serial_[NODE]->template set_num_tols<NODE>(num_tols);
break;
374 std::cerr <<
"Cannot remap on " <<
to_string(onwhat) <<
"\n";
393 template <
int, Entity_kind,
class,
class>
class Search
398 search_completed_[ONWHAT] =
true;
400 return core_driver_serial_[ONWHAT]->template search<ONWHAT, Search>();
419 template <Entity_kind,
class,
class,
class,
420 template <
class,
int,
class,
class>
class,
423 Portage::
vector<std::vector<Portage::Weights_t>>
427 const auto& weights = core_driver_serial_[ONWHAT]->template intersect_meshes<ONWHAT, Intersect>(candidates);
432 core_driver_serial_[ONWHAT]->template check_mismatch<ONWHAT>(weights);
434 mesh_intersection_completed_[ONWHAT] =
true;
452 void set_interface_reconstructor_options(
bool all_convex,
453 const std::vector<Tangram::IterativeMethodTolerances_t> &tols =
454 std::vector<Tangram::IterativeMethodTolerances_t>()) {
455 core_driver_serial_[CELL]->set_interface_reconstructor_options(all_convex, tols);
476 template <Entity_kind,
class,
class,
class,
477 template <
class,
int,
class,
class>
class,
480 std::
vector<Portage::vector<std::vector<Portage::Weights_t>>>
483 mat_intersection_completed_ =
true;
485 return core_driver_serial_[CELL]->template intersect_materials<Intersect>(candidates);
524 template<
typename T = double,
526 template<int, Entity_kind,
class,
class,
class,
class,
class,
527 template<
class,
int,
class,
class>
class,
528 class,
class,
class>
class Interpolate
531 T lower_bound, T upper_bound,
539 interpolate<T, ONWHAT, Interpolate>(srcvarname, srcvarname,
540 lower_bound, upper_bound,
541 limiter, bnd_limiter,
542 partial_fixup_type, empty_fixup_type,
543 conservation_tol, max_fixup_iter);
578 template<
typename T = double,
580 template<int, Entity_kind,
class,
class,
class,
class,
class,
581 template<
class,
int,
class,
class>
class,
582 class,
class,
class>
class Interpolate
585 T lower_bound, T upper_bound,
593 assert(source_state_.get_entity(srcvarname) == ONWHAT);
594 assert(mesh_intersection_completed_[ONWHAT]);
596 if (std::find(source_vars_to_remap_.begin(), source_vars_to_remap_.end(),
597 srcvarname) == source_vars_to_remap_.end()) {
598 std::cerr <<
"Cannot remap source variable " << srcvarname <<
599 " - not specified in initial variable list in the constructor \n";
603 if (source_state_.field_type(ONWHAT, srcvarname) ==
604 Field_type::MULTIMATERIAL_FIELD) {
607 assert(mat_intersection_completed_);
608 assert(ONWHAT == CELL);
610 interpolate_mat_var<T, Interpolate>
611 (srcvarname, trgvarname, source_weights_by_mat_,
612 lower_bound, upper_bound, limiter, bnd_limiter, partial_fixup_type,
613 empty_fixup_type, conservation_tol, max_fixup_iter);
618 assert(mesh_intersection_completed_[ONWHAT]);
620 interpolate_mesh_var<T, ONWHAT, Interpolate>
621 (srcvarname, trgvarname, source_weights_[ONWHAT],
622 lower_bound, upper_bound, limiter, bnd_limiter, partial_fixup_type,
623 empty_fixup_type, conservation_tol, max_fixup_iter);
668 template<
typename T = double,
670 template<int, Entity_kind,
class,
class,
class,
class,
class,
671 template <
class,
int,
class,
class>
class,
672 class,
class,
class>
class Interpolate
676 T lower_bound, T upper_bound,
681 double conservation_tol,
682 int max_fixup_iter) {
684 assert(source_state_.get_entity(srcvarname) == ONWHAT);
686 if (std::find(source_vars_to_remap_.begin(), source_vars_to_remap_.end(),
687 srcvarname) == source_vars_to_remap_.end()) {
688 std::cerr <<
"Cannot remap source variable " << srcvarname <<
689 " - not specified in initial variable list in the constructor \n";
693 auto & driver = core_driver_serial_[ONWHAT];
695 using Interpolator = Interpolate<D, ONWHAT,
696 SourceMesh, TargetMesh,
697 SourceState, TargetState,
699 InterfaceReconstructorType,
700 Matpoly_Splitter, Matpoly_Clipper,
703 if (Interpolator::order == 2) {
704 auto gradients = driver->template compute_source_gradient<ONWHAT>(srcvarname,
708 driver->template interpolate_mesh_var<T, ONWHAT, Interpolate>(
709 srcvarname, trgvarname, sources_and_weights_in, &gradients
712 driver->template interpolate_mesh_var<T, ONWHAT, Interpolate>(
713 srcvarname, trgvarname, sources_and_weights_in
717 if (driver->template has_mismatch<ONWHAT>())
718 driver->template fix_mismatch<ONWHAT>(srcvarname, trgvarname, lower_bound, upper_bound, conservation_tol,
719 max_fixup_iter, partial_fixup_type, empty_fixup_type);
756 template <
typename T = double,
757 template<int, Entity_kind,
class,
class,
class,
class,
class,
758 template <
class,
int,
class,
class>
class,
759 class,
class,
class>
class Interpolate
762 std::vector<Portage::vector<std::vector<Weights_t>>> const& sources_and_weights_by_mat_in,
763 T lower_bound, T upper_bound,
768 double conservation_tol,
769 int max_fixup_iter) {
771 assert(source_state_.get_entity(srcvarname) == CELL);
773 if (std::find(source_vars_to_remap_.begin(), source_vars_to_remap_.end(),
774 srcvarname) == source_vars_to_remap_.end()) {
775 std::cerr <<
"Cannot remap source variable " << srcvarname <<
776 " - not specified in initial variable list in the constructor \n";
781 auto & driver = core_driver_serial_[CELL];
783 using Interpolator = Interpolate<D, CELL,
784 SourceMesh, TargetMesh,
785 SourceState, TargetState,
787 InterfaceReconstructorType,
788 Matpoly_Splitter, Matpoly_Clipper,
791 int const nb_mats = source_state_.num_materials();
794 if (Interpolator::order == 2) {
795 std::vector<Portage::vector<Vector<D>>> gradients(nb_mats);
796 for (
int i = 0; i < nb_mats; ++i) {
797 gradients[i] = driver->template compute_source_gradient<CELL>(srcvarname,
801 driver->template interpolate_mat_var<T, Interpolate>(
802 srcvarname, trgvarname, sources_and_weights_by_mat_in,
806 driver->template interpolate_mat_var<T, Interpolate>(
807 srcvarname, trgvarname, sources_and_weights_by_mat_in
816 SourceMesh
const& source_mesh_;
817 TargetMesh
const& target_mesh_;
818 SourceState
const& source_state_;
819 TargetState& target_state_;
823 bool distributed_ =
false;
824 Wonton::Executor_type
const *executor_;
825 #ifdef PORTAGE_ENABLE_MPI 827 MPI_Comm mycomm_ = MPI_COMM_NULL;
830 std::vector<std::string> source_vars_to_remap_ {};
831 std::vector<Entity_kind> entity_kinds_ {};
832 std::vector<Field_type> field_types_ {};
835 bool have_multi_material_fields_ =
false;
838 std::map<Entity_kind, bool> search_completed_ {};
839 std::map<Entity_kind, bool> mesh_intersection_completed_ {};
840 bool mat_intersection_completed_ =
false;
847 std::map<Entity_kind, std::unique_ptr<SerialDriverType>> core_driver_serial_ {};
862 std::map<Entity_kind, Portage::vector<std::vector<Weights_t>>> source_weights_ {};
877 std::vector<Portage::vector<std::vector<Weights_t>>> source_weights_by_mat_ {};
886 void instantiate_core_drivers(Wonton::Executor_type
const *executor =
890 for (
auto const& onwhat : entity_kinds_) {
891 search_completed_[onwhat] =
false;
892 mesh_intersection_completed_[onwhat] =
false;
898 for (Entity_kind onwhat : entity_kinds_)
899 core_driver_serial_[onwhat] =
901 TargetMesh, TargetState,
902 InterfaceReconstructorType,
903 Matpoly_Splitter, Matpoly_Clipper, CoordSys
905 source_mesh_, source_state_,
906 target_mesh_, target_state_, executor_);
915 #endif // PORTAGE_GENREMAP_DRIVER_H_ UberDriver & operator=(const UberDriver &)=delete
Assignment operator (disabled)
const NumericTolerances_t DEFAULT_NUMERIC_TOLERANCES
Definition: portage.h:186
Portage::vector< std::vector< Portage::Weights_t > > intersect_meshes(Portage::vector< std::vector< int >> const &candidates)
intersect target control volumes with source control volumes
Definition: uberdriver.h:424
Boundary_Limiter_type
Boundary limiter type.
Definition: portage.h:91
constexpr Boundary_Limiter_type DEFAULT_BND_LIMITER
Definition: portage.h:94
void set_num_tols(const double min_absolute_distance, const double min_absolute_volume)
Set numerical tolerances for small distances and volumes in core driver.
Definition: uberdriver.h:342
bool is_distributed_run(Wonton::Executor_type const *executor=nullptr)
Is this a distributed (multi-rank) run?
Definition: uberdriver.h:240
std::vector< T > vector
Definition: portage.h:238
constexpr Empty_fixup_type DEFAULT_EMPTY_FIXUP_TYPE
Definition: portage.h:138
Intersection and other tolerances to handle tiny values.
Definition: portage.h:152
void set_num_tols(const NumericTolerances_t &num_tols)
set numerical tolerances in core driver
Definition: uberdriver.h:366
void interpolate(std::string srcvarname, T lower_bound, T upper_bound, Limiter_type limiter=DEFAULT_LIMITER, Boundary_Limiter_type bnd_limiter=DEFAULT_BND_LIMITER, Partial_fixup_type partial_fixup_type=DEFAULT_PARTIAL_FIXUP_TYPE, Empty_fixup_type empty_fixup_type=DEFAULT_EMPTY_FIXUP_TYPE, double conservation_tol=DEFAULT_NUMERIC_TOLERANCES< D >.relative_conservation_eps, int max_fixup_iter=DEFAULT_NUMERIC_TOLERANCES< D >.max_num_fixup_iter)
Definition: uberdriver.h:530
Partial_fixup_type
Fixup options for partially filled cells.
Definition: portage.h:114
bool source_needs_redistribution(Wonton::Executor_type const *executor=nullptr)
Definition: uberdriver.h:263
void compute_interpolation_weights()
Compute interpolation weights in advance of actual interpolation of variables.
Definition: uberdriver.h:291
Limiter_type
Limiter type.
Definition: portage.h:85
UberDriver provides the API to mapping multi-material data from one mesh to another in a general way...
Definition: uberdriver.h:100
~UberDriver()=default
Destructor.
CoreDriverBase - Base class for core driver that is agnostic to the Entity_kind.
Definition: coredriver.h:105
std::vector< Portage::vector< std::vector< Portage::Weights_t > > > intersect_materials(Portage::vector< std::vector< int >> const &candidates)
Definition: uberdriver.h:481
UberDriver(SourceMesh const &source_mesh, SourceState const &source_state, TargetMesh const &target_mesh, TargetState &target_state, Wonton::Executor_type const *executor=nullptr, std::string *errmsg=nullptr)
Constructor for the remap driver.
Definition: uberdriver.h:181
Definition: coredriver.h:42
UberDriver(SourceMesh const &source_mesh, SourceState const &source_state, TargetMesh const &target_mesh, TargetState &target_state, std::vector< std::string > const &source_vars_to_remap, Wonton::Executor_type const *executor=nullptr, std::string *errmsg=nullptr)
Constructor for the remap driver.
Definition: uberdriver.h:131
constexpr Limiter_type DEFAULT_LIMITER
Definition: portage.h:88
Core driver for remapping.
std::unique_ptr< CoreDriverBase< D, SourceMesh, SourceState, TargetMesh, TargetState, InterfaceReconstructorType, Matpoly_Splitter, Matpoly_Clipper, CoordSys > > make_core_driver(Entity_kind onwhat, SourceMesh const &source_mesh, SourceState const &source_state, TargetMesh const &target_mesh, TargetState &target_state, Wonton::Executor_type const *executor)
Definition: coredriver.h:1524
void interpolate_mat_var(std::string srcvarname, std::string trgvarname, std::vector< Portage::vector< std::vector< Weights_t >>> const &sources_and_weights_by_mat_in, T lower_bound, T upper_bound, Limiter_type limiter, Boundary_Limiter_type bnd_limiter, Partial_fixup_type partial_fixup_type, Empty_fixup_type empty_fixup_type, double conservation_tol, int max_fixup_iter)
Definition: uberdriver.h:761
void Intersect(const IsotheticBBox< D > &box, const KDTree< D > *kdtree, std::vector< int > &pfound)
Definition: kdtree.h:439
std::string to_string(Limiter_type limiter_type)
Definition: portage.h:96
Portage::vector< std::vector< int > > search()
search for candidate source entities whose control volumes (cells, dual cells) overlap the control vo...
Definition: uberdriver.h:396
constexpr Partial_fixup_type DEFAULT_PARTIAL_FIXUP_TYPE
Definition: portage.h:118
Empty_fixup_type
Fixup options for empty cells.
Definition: portage.h:134
void interpolate_mesh_var(std::string srcvarname, std::string trgvarname, Portage::vector< std::vector< Weights_t >> const &sources_and_weights_in, T lower_bound, T upper_bound, Limiter_type limiter, Boundary_Limiter_type bnd_limiter, Partial_fixup_type partial_fixup_type, Empty_fixup_type empty_fixup_type, double conservation_tol, int max_fixup_iter)
Definition: uberdriver.h:674