7 #ifndef PORTAGE_INTERPOLATE_QUADFIT_H_ 8 #define PORTAGE_INTERPOLATE_QUADFIT_H_ 21 #include "wonton/support/lsfits.h" 22 #include "wonton/support/Point.h" 23 #include "wonton/support/Vector.h" 42 template<
int D, Entity_kind on_what,
typename MeshType,
typename StateType>
57 std::string
const var_name,
63 limtype_(limiter_type),
64 bnd_limtype_(Boundary_Limiter_type) {
68 state.mesh_get_data(on_what, var_name, &vals_);
88 Vector<D*(D+3)/2>
operator()(
int entity_id) {
89 std::cerr <<
"Limited quadfit not implemented for this entity kind\n";
93 MeshType
const & mesh_;
94 StateType
const & state_;
95 std::string var_name_;
110 template<
int D,
typename MeshType,
typename StateType>
124 std::string
const var_name,
130 limtype_(limiter_type),
131 bnd_limtype_(Boundary_Limiter_type) {
134 state.mesh_get_data(Entity_kind::CELL, var_name, &vals_);
140 int ncells = mesh_.num_entities(Entity_kind::CELL);
141 cell_neighbors_.resize(ncells);
144 [
this](
int c) { mesh_.cell_get_node_adj_cells(
145 c, Entity_type::ALL, &(cell_neighbors_[c])); } );
164 Vector<D*(D+3)/2>
operator()(
int cellid);
167 MeshType
const & mesh_;
168 StateType
const & state_;
169 std::string var_name_;
173 std::vector<std::vector<int>> cell_neighbors_;
184 template<
int D,
typename MeshType,
typename StateType>
188 assert(D == mesh_.space_dimension());
189 assert(D == 2 || D == 3);
191 Vector<D*(D+3)/2> qfit;
192 Vector<D*(D+3)/2> dvec;
194 bool boundary_cell = mesh_.on_exterior_boundary(Entity_kind::CELL, cellid);
201 std::vector<int>
const & nbrids = cell_neighbors_[cellid];
203 std::vector<Point<D>> cellcenters(nbrids.size()+1);
204 std::vector<double> cellvalues(nbrids.size()+1);
207 mesh_.cell_centroid(cellid, &(cellcenters[0]));
209 cellvalues[0] = vals_[cellid];
212 for (
auto nbrcell : nbrids) {
213 mesh_.cell_centroid(nbrcell, &(cellcenters[i]));
214 cellvalues[i] = vals_[nbrcell];
218 qfit = Wonton::ls_quadfit(cellcenters, cellvalues, boundary_cell);
227 double minval = vals_[cellid];
228 double maxval = vals_[cellid];
230 int nnbr = nbrids.size();
231 for (
int ic = 0; ic < nnbr; ++ic) {
232 minval = std::min(cellvalues[ic], minval);
233 maxval = std::max(cellvalues[ic], maxval);
241 double cellcenval = vals_[cellid];
242 std::vector<Point<D>> cellcoords;
243 mesh_.cell_get_coordinates(cellid, &cellcoords);
245 for (
auto coord : cellcoords) {
246 Vector<D> vec = coord-cellcenters[0];
248 for (
int j = 0; j < D; ++j) {
251 for (
int k = 0; k < j; ++k) {
252 dvec[j+k+D-1] = dvec[k]*dvec[j];
256 double diff = dot(qfit, dvec);
257 double extremeval = (diff > 0.0) ? maxval : minval;
258 double phi_new = (diff == 0.0) ? 1 : (extremeval-cellcenval)/diff;
259 phi = std::min(phi_new, phi);
278 template<
int D,
typename MeshType,
typename StateType>
293 std::string
const var_name,
299 limtype_(limiter_type),
300 bnd_limtype_(Boundary_Limiter_type) {
303 state.mesh_get_data(Entity_kind::NODE, var_name, &vals_);
309 int nnodes = mesh_.num_entities(Entity_kind::NODE);
310 node_neighbors_.resize(nnodes);
313 [
this](
int n) { mesh_.dual_cell_get_node_adj_cells(
314 n, Entity_type::ALL, &(node_neighbors_[n])); } );
333 Vector<D*(D+3)/2>
operator()(
int nodeid);
336 MeshType
const & mesh_;
337 StateType
const & state_;
338 std::string var_name_;
342 std::vector<std::vector<int>> node_neighbors_;
354 template<
int D,
typename MeshType,
typename StateType>
358 assert(D == mesh_.space_dimension());
359 assert(D == 2 || D == 3);
361 Vector<D*(D+3)/2> qfit;
362 Vector<D*(D+3)/2> dvec;
364 bool boundary_node = mesh_.on_exterior_boundary(Entity_kind::NODE, nodeid);
370 std::vector<int>
const & nbrids = node_neighbors_[nodeid];
371 std::vector<Point<D>> nodecoords(nbrids.size()+1);
372 std::vector<double> nodevalues(nbrids.size()+1);
376 mesh_.node_get_coordinates(nodeid, &(nodecoords[0]));
377 nodevalues[0] = vals_[nodeid];
380 for (
auto const & nbrnode : nbrids) {
381 mesh_.node_get_coordinates(nbrnode, &nodecoords[i]);
382 nodevalues[i] = vals_[nbrnode];
386 qfit = Wonton::ls_quadfit(nodecoords, nodevalues, boundary_node);
393 double minval = vals_[nodeid];
394 double maxval = vals_[nodeid];
396 for (
auto const & val : nodevalues) {
397 minval = std::min(val, minval);
398 maxval = std::max(val, maxval);
406 double nodeval = vals_[nodeid];
408 std::vector<Point<D>> dualcellcoords;
409 mesh_.dual_cell_get_coordinates(nodeid, &dualcellcoords);
411 for (
auto const & coord : dualcellcoords) {
412 Vector<D> vec = coord-nodecoords[0];
414 for (
int j = 0; j < D; ++j) {
417 for (
int k = 0; k < j; ++k) {
418 dvec[j+k+D-1] = dvec[k]*dvec[j];
422 double diff = dot(qfit, dvec);
423 double extremeval = (diff > 0.0) ? maxval : minval;
424 double phi_new = (diff == 0.0) ? 1 : (extremeval-nodeval)/diff;
425 phi = std::min(phi_new, phi);
436 #endif // PORTAGE_INTERPOLATE_QUADFIT_H_
Boundary_Limiter_type
Boundary limiter type.
Definition: portage.h:91
void for_each(InputIterator first, InputIterator last, UnaryFunction f)
Definition: portage.h:264
Limited_Quadfit & operator=(const Limited_Quadfit &)=delete
Assignment operator (disabled)
Limited_Quadfit(MeshType const &mesh, StateType const &state, std::string const var_name, Limiter_type limiter_type, Boundary_Limiter_type Boundary_Limiter_type)
Constructor.
Definition: quadfit.h:56
~Limited_Quadfit()=default
Destructor.
Limited_Quadfit(MeshType const &mesh, StateType const &state, std::string const var_name, Limiter_type limiter_type, Boundary_Limiter_type Boundary_Limiter_type)
Constructor.
Definition: quadfit.h:123
Limiter_type
Limiter type.
Definition: portage.h:85
Definition: coredriver.h:42
Limited_Quadfit(MeshType const &mesh, StateType const &state, std::string const var_name, Limiter_type limiter_type, Boundary_Limiter_type Boundary_Limiter_type)
Constructor.
Definition: quadfit.h:292
Compute limited quadfit of a field or components of a field.
Definition: quadfit.h:43