7 #ifndef PORTAGE_INTERPOLATE_GRADIENT_H_ 8 #define PORTAGE_INTERPOLATE_GRADIENT_H_ 21 #include "wonton/support/lsfits.h" 22 #include "wonton/support/Point.h" 23 #include "wonton/support/Vector.h" 26 #include "tangram/driver/driver.h" 27 #include "tangram/driver/CellMatPoly.h" 28 #include "tangram/support/MatPoly.h" 44 int D, Entity_kind on_what,
45 typename Mesh,
typename State,
46 template<
class,
int,
class,
class>
47 class InterfaceReconstructorType = DummyInterfaceReconstructor,
48 class Matpoly_Splitter = void,
49 class Matpoly_Clipper = void,
50 class CoordSys = Wonton::DefaultCoordSys
56 using InterfaceReconstructor =
58 InterfaceReconstructorType, D, Mesh,
59 Matpoly_Splitter, Matpoly_Clipper
77 std::string
const var_name,
84 variable_name_(var_name),
85 limiter_type_(limiter_type),
86 boundary_limiter_type_(boundary_limiter_type) {}
90 std::string
const var_name,
93 std::shared_ptr<InterfaceReconstructor> ir,
98 variable_name_(var_name),
99 limiter_type_(limiter_type),
100 boundary_limiter_type_(boundary_limiter_type) {}
112 std::cerr <<
"Limited gradient not implemented for this entity kind";
113 std::cerr << std::endl;
119 double const* values_;
120 std::string variable_name_ =
"";
123 Field_type field_type_ = Field_type::UNKNOWN_TYPE_FIELD;
124 int material_id_ = 0;
140 template<
class,
int,
class,
class>
141 class InterfaceReconstructorType,
142 class Matpoly_Splitter,
class Matpoly_Clipper,
class CoordSys
145 D, Entity_kind::CELL,
147 InterfaceReconstructorType,
148 Matpoly_Splitter, Matpoly_Clipper, CoordSys
153 using InterfaceReconstructor =
155 InterfaceReconstructorType, D, Mesh,
156 Matpoly_Splitter, Matpoly_Clipper
164 std::string var_name,
171 variable_name_(var_name),
172 limiter_type_(limiter_type),
173 boundary_limiter_type_(boundary_limiter_type),
183 int const nb_cells = mesh_.num_entities(Entity_kind::CELL,
184 Entity_type::PARALLEL_OWNED);
185 cell_neighbors_.resize(nb_cells);
187 if (part_ ==
nullptr) {
188 auto collect_neighbors = [
this](
int c) {
189 mesh_.cell_get_node_adj_cells(c, Entity_type::ALL,
190 &(cell_neighbors_[c]));
194 Entity_type::PARALLEL_OWNED),
195 mesh_.end(Entity_kind::CELL,
196 Entity_type::PARALLEL_OWNED),
199 auto filter_neighbors = [
this](
int c) {
200 cell_neighbors_[c] = part_->get_neighbors(c);
203 auto const& part_cells = part_->cells();
207 set_interpolation_variable(var_name, limiter_type, boundary_limiter_type);
214 std::string
const& var_name,
217 std::shared_ptr<InterfaceReconstructor> ir,
222 variable_name_(var_name),
223 limiter_type_(limiter_type),
224 boundary_limiter_type_(boundary_limiter_type),
225 interface_reconstructor_(ir),
235 int const nb_cells = mesh_.num_entities(Entity_kind::CELL,
236 Entity_type::PARALLEL_OWNED);
237 cell_neighbors_.resize(nb_cells);
239 if (part_ ==
nullptr) {
240 auto collect_neighbors = [
this](
int c) {
241 mesh_.cell_get_node_adj_cells(c, Entity_type::ALL, &(cell_neighbors_[c]));
245 Entity_type::PARALLEL_OWNED),
246 mesh_.end(Entity_kind::CELL,
247 Entity_type::PARALLEL_OWNED),
251 auto filter_neighbors = [
this](
int c) {
252 cell_neighbors_[c] = part_->get_neighbors(c);
255 auto const& part_cells = part_->cells();
263 set_interpolation_variable(var_name, limiter_type, boundary_limiter_type);
272 material_id_ = matid;
274 if (field_type_ != Field_type::MESH_FIELD) {
275 state_.mat_get_celldata(variable_name_, material_id_, &values_);
283 variable_name_ = variable_name;
284 limiter_type_ = limiter_type;
285 boundary_limiter_type_ = boundary_limiter_type;
288 field_type_ = state_.field_type(Entity_kind::CELL, variable_name_);
289 if (field_type_ == Field_type::MESH_FIELD) {
290 state_.mesh_get_data(Entity_kind::CELL, variable_name_, &values_);
298 assert(mesh_.cell_get_type(cellid) == Entity_type::PARALLEL_OWNED);
304 if (part_ !=
nullptr && !part_->contains(cellid)) {
310 bool is_boundary_cell = mesh_.on_exterior_boundary(Entity_kind::CELL, cellid);
321 std::vector<int> neighbors{cellid};
323 if (!cell_neighbors_.empty()) {
324 neighbors.insert(std::end(neighbors),
325 std::begin(cell_neighbors_[cellid]),
326 std::end(cell_neighbors_[cellid]));
329 std::vector<Point<D>> list_coords;
330 std::vector<double> list_values;
333 for (
auto&& neigh_global : neighbors) {
338 int const neigh_local = (field_type_ == Field_type::MESH_FIELD)
340 : state_.cell_index_in_material(neigh_global, material_id_);
347 if (neigh_local >= 0) {
348 std::vector<int> cell_mats;
349 state_.cell_get_mats(neigh_global, &cell_mats);
350 int const nb_mats = cell_mats.size();
352 if (nb_mats > 1 && interface_reconstructor_) {
354 auto cell_matpoly = interface_reconstructor_->cell_matpoly_data(neigh_global);
357 auto matpolys = cell_matpoly.get_matpolys(material_id_);
363 for (
auto&& poly : matpolys) {
364 auto moments = poly.moments();
366 for (
int k = 0; k < D; k++)
367 centroid[k] += moments[k + 1];
373 if (mvol==0.)
continue;
375 for (
int k = 0; k < D; k++)
378 list_coords.push_back(centroid);
382 list_values.push_back(values_[neigh_local]);
383 }
else if (nb_mats == 1) {
386 if (cell_mats[0] == material_id_) {
389 mesh_.cell_centroid(neigh_global, ¢roid);
390 list_coords.push_back(centroid);
391 list_values.push_back(values_[neigh_local]);
398 if (field_type_ == Field_type::MESH_FIELD) {
400 mesh_.cell_centroid(neigh_global, ¢roid);
401 list_coords.push_back(centroid);
402 list_values.push_back(values_[neigh_global]);
406 grad = Wonton::ls_gradient<D, CoordSys>(list_coords, list_values);
416 double minval = list_values[0];
417 double maxval = list_values[0];
418 double cellcenval = list_values[0];
422 int const nb_values = list_values.size();
423 for (
int i = 1; i < nb_values; ++i) {
424 minval = std::min(list_values[i], minval);
425 maxval = std::max(list_values[i], maxval);
448 std::vector<Point<D>> cellcoords;
449 mesh_.cell_get_coordinates(cellid, &cellcoords);
451 for (
auto&& coord : cellcoords) {
452 auto vec = coord - list_coords[0];
453 double diff = dot(grad, vec);
454 double extremeval = (diff > 0.) ? maxval : minval;
455 double phi_new = (diff == 0. ? 1. : (extremeval - cellcenval) / diff);
456 phi = std::min(phi_new, phi);
467 double const* values_;
468 std::string variable_name_ =
"";
471 Field_type field_type_ = Field_type::UNKNOWN_TYPE_FIELD;
473 int material_id_ = 0;
474 std::vector<int> cell_ids_;
475 std::vector<std::vector<int>> cell_neighbors_;
477 std::shared_ptr<InterfaceReconstructor> interface_reconstructor_;
494 template<
class,
int,
class,
class>
495 class InterfaceReconstructorType,
496 class Matpoly_Splitter,
class Matpoly_Clipper,
class CoordSys
499 D, Entity_kind::NODE,
501 InterfaceReconstructorType,
502 Matpoly_Splitter, Matpoly_Clipper, CoordSys
506 using InterfaceReconstructor =
508 InterfaceReconstructorType, D, Mesh,
509 Matpoly_Splitter, Matpoly_Clipper
525 std::string var_name,
532 variable_name_(var_name),
533 limiter_type_(limiter_type),
534 boundary_limiter_type_(boundary_limiter_type) {
536 auto collect_node_neighbors = [
this](
int n) {
537 this->mesh_.dual_cell_get_node_adj_cells(
538 n, Entity_type::ALL, &(node_neighbors_[n])
579 int const nnodes = mesh_.num_entities(Entity_kind::NODE,
581 node_neighbors_.resize(nnodes);
584 mesh_.end(Entity_kind::NODE,
586 collect_node_neighbors);
588 set_interpolation_variable(var_name, limiter_type, boundary_limiter_type);
604 std::string
const& var_name,
607 std::shared_ptr<InterfaceReconstructor> ir,
609 :
Limited_Gradient(mesh, state, var_name, limiter_type, boundary_limiter_type) {
611 if (part !=
nullptr) {
612 std::cerr <<
"Sorry, part-by-part remap is only defined ";
613 std::cerr <<
"for cell-centered field, will be ignored." << std::endl;
624 variable_name_ = variable_name;
625 limiter_type_ = limiter_type;
626 boundary_limiter_type_ = boundary_limiter_type;
627 state_.mesh_get_data(Entity_kind::NODE, variable_name_, &values_);
638 bool is_boundary_node = mesh_.on_exterior_boundary(Entity_kind::NODE, nodeid);
648 auto const& neighbors = node_neighbors_[nodeid];
649 std::vector<Point<D>> node_coords(neighbors.size() + 1);
650 std::vector<double> node_values(neighbors.size() + 1);
651 mesh_.node_get_coordinates(nodeid, &(node_coords[0]));
652 node_values[0] = values_[nodeid];
655 for (
auto&& current : neighbors) {
656 mesh_.node_get_coordinates(current, &node_coords[i]);
657 node_values[i] = values_[current];
661 grad = Wonton::ls_gradient<D, CoordSys>(node_coords, node_values);
665 double minval = values_[nodeid];
666 double maxval = values_[nodeid];
668 for (
auto const& val : node_values) {
669 minval = std::min(val, minval);
670 maxval = std::max(val, maxval);
677 double nodeval = values_[nodeid];
679 std::vector<Point<D>> dual_cell_coords;
680 mesh_.dual_cell_get_coordinates(nodeid, &dual_cell_coords);
682 for (
auto&& coord : dual_cell_coords) {
683 auto vec = coord - node_coords[0];
684 double diff = dot(grad, vec);
685 double extremeval = (diff > 0.0) ? maxval : minval;
686 double phi_new = (diff == 0.0) ? 1 : (extremeval - nodeval) / diff;
687 phi = std::min(phi_new, phi);
698 double const* values_;
699 std::string variable_name_ =
"";
702 Field_type field_type_ = Field_type::UNKNOWN_TYPE_FIELD;
704 int material_id_ = 0;
705 std::vector<int> cell_ids_;
706 std::vector<std::vector<int>> node_neighbors_;
710 #endif // PORTAGE_INTERPOLATE_GRADIENT_H_ void set_interpolation_variable(std::string const &variable_name, Limiter_type limiter_type, Boundary_Limiter_type boundary_limiter_type)
Definition: gradient.h:620
Boundary_Limiter_type
Boundary limiter type.
Definition: portage.h:91
void set_material(int matid)
Definition: gradient.h:271
constexpr Boundary_Limiter_type DEFAULT_BND_LIMITER
Definition: portage.h:94
Vector< D > operator()(int nodeid)
Definition: gradient.h:631
Wonton::Point< OP::dim > centroid(const typename OP::points_t &apts)
Definition: operator.h:616
void for_each(InputIterator first, InputIterator last, UnaryFunction f)
Definition: portage.h:264
~Limited_Gradient()=default
Vector< D > operator()(int cellid)
Definition: gradient.h:295
Compute limited gradient of a field or components of a field.
Definition: gradient.h:52
Manages source and target sub-meshes for part-by-part remap.
Limited_Gradient & operator=(const Limited_Gradient &)=delete
Limited_Gradient(Mesh const &mesh, State const &state, std::string var_name, Limiter_type limiter_type, Boundary_Limiter_type boundary_limiter_type, const Part< Mesh, State > *part=nullptr)
Constructor.
Definition: gradient.h:523
Limiter_type
Limiter type.
Definition: portage.h:85
Limited_Gradient(Mesh const &mesh, State const &state, std::string const var_name, Limiter_type limiter_type, Boundary_Limiter_type boundary_limiter_type, const Part< Mesh, State > *part=nullptr)
Constructor.
Definition: gradient.h:76
Limited_Gradient(Mesh const &mesh, State const &state, std::string var_name, Limiter_type limiter_type, Boundary_Limiter_type boundary_limiter_type, const Part< Mesh, State > *part=nullptr)
Definition: gradient.h:162
Definition: coredriver.h:42
void set_material(int material_id)
Definition: gradient.h:618
Vector< D > operator()(int entity_id)
Definition: gradient.h:111
constexpr Limiter_type DEFAULT_LIMITER
Definition: portage.h:88
void set_interpolation_variable(std::string variable_name, Limiter_type limiter_type, Boundary_Limiter_type boundary_limiter_type)
Definition: gradient.h:279