intersect_r2d.h
Go to the documentation of this file.
1 /*
2 This file is part of the Ristra portage project.
3 Please see the license file at the root of this repository, or at:
4  https://github.com/laristra/portage/blob/master/LICENSE
5 */
6 
7 
8 #ifndef PORTAGE_INTERSECT_INTERSECT_R2D_H_
9 #define PORTAGE_INTERSECT_INTERSECT_R2D_H_
10 
11 #include <array>
12 #include <stdexcept>
13 #include <vector>
14 #include <algorithm>
15 
16 // portage includes
17 extern "C" {
18 #include "wonton/intersect/r3d/r2d.h"
19 }
23 
24 #ifdef HAVE_TANGRAM
25 #include "tangram/driver/CellMatPoly.h"
26 #include "tangram/driver/driver.h"
27 #include "tangram/support/MatPoly.h"
28 #endif
29 
30 #include "wonton/support/Point.h"
31 
32 namespace Portage {
33 
36 
37 
38 template <Entity_kind on_what, class SourceMeshType,
39  class SourceStateType, class TargetMeshType,
40  template<class, int, class, class> class InterfaceReconstructorType =
41  DummyInterfaceReconstructor,
42  class Matpoly_Splitter = void,
43  class Matpoly_Clipper = void>
44 class IntersectR2D {
45 
46 #ifdef HAVE_TANGRAM
47  using InterfaceReconstructor2D =
48  Tangram::Driver<InterfaceReconstructorType, 2, SourceMeshType,
49  Matpoly_Splitter, Matpoly_Clipper>;
50 #endif
51 
52  public:
53 
54 #ifdef HAVE_TANGRAM
55 
57  IntersectR2D(SourceMeshType const & source_mesh,
58  SourceStateType const & source_state,
59  TargetMeshType const & target_mesh,
60  NumericTolerances_t num_tols,
61  std::shared_ptr<InterfaceReconstructor2D> ir)
62  : sourceMeshWrapper(source_mesh), sourceStateWrapper(source_state),
63  targetMeshWrapper(target_mesh), interface_reconstructor(ir),
64  num_tols_(num_tols) {}
65 #endif
66 
68 
69  IntersectR2D(SourceMeshType const & source_mesh,
70  SourceStateType const & source_state,
71  TargetMeshType const & target_mesh,
72  NumericTolerances_t num_tols)
73  : sourceMeshWrapper(source_mesh), sourceStateWrapper(source_state),
74  targetMeshWrapper(target_mesh), num_tols_(num_tols) {}
75 
77 
78  void set_material(int m) {
79  matid_ = m;
80  }
81 
86 
87  std::vector<Weights_t>
88  operator() (const int tgt_entity, std::vector<int> const& src_entities) const {
89  std::cerr << "IntersectR3D not implemented for this entity type" << std::endl;
90  return std::vector<Weights_t>(0);
91  }
92 
93  IntersectR2D() = delete;
94 
96  IntersectR2D & operator = (const IntersectR2D &) = delete;
97 
98  private:
99  SourceMeshType const & sourceMeshWrapper;
100  SourceStateType const & sourceStateWrapper;
101  TargetMeshType const & targetMeshWrapper;
102  int matid_ = -1;
103 #ifdef HAVE_TANGRAM
104  std::shared_ptr<InterfaceReconstructor2D> interface_reconstructor;
105 #endif
106  NumericTolerances_t num_tols_;
107 }; // class IntersectR2D
108 
109 
110 
112 // Specialization of Intersect2D class for cells
113 
114 template <class SourceMeshType, class SourceStateType,
115  class TargetMeshType,
116  template <class, int, class, class> class InterfaceReconstructorType,
117  class Matpoly_Splitter, class Matpoly_Clipper>
118 class IntersectR2D<Entity_kind::CELL, SourceMeshType, SourceStateType, TargetMeshType,
119  InterfaceReconstructorType, Matpoly_Splitter, Matpoly_Clipper> {
120 
121 #ifdef HAVE_TANGRAM
122  using InterfaceReconstructor2D =
123  Tangram::Driver<InterfaceReconstructorType, 2, SourceMeshType,
124  Matpoly_Splitter, Matpoly_Clipper>;
125 #endif
126 
127  public:
128 
129 #ifdef HAVE_TANGRAM
130 
132  IntersectR2D(SourceMeshType const & source_mesh,
133  SourceStateType const & source_state,
134  TargetMeshType const & target_mesh,
135  NumericTolerances_t num_tols,
136  std::shared_ptr<InterfaceReconstructor2D> ir)
137  : sourceMeshWrapper(source_mesh), sourceStateWrapper(source_state),
138  targetMeshWrapper(target_mesh), interface_reconstructor(ir),
139  num_tols_(num_tols) {}
140 #endif
141 
143 
144  IntersectR2D(SourceMeshType const & source_mesh,
145  SourceStateType const & source_state,
146  TargetMeshType const & target_mesh,
147  NumericTolerances_t num_tols)
148  : sourceMeshWrapper(source_mesh), sourceStateWrapper(source_state),
149  targetMeshWrapper(target_mesh), num_tols_(num_tols) {}
150 
152 
153  void set_material(int m) {
154  matid_ = m;
155  }
156 
161 
162  std::vector<Weights_t> operator() (int tgt_cell, std::vector<int> const& src_cells) const {
163  std::vector<Wonton::Point<2>> target_poly;
164  targetMeshWrapper.cell_get_coordinates(tgt_cell, &target_poly);
165 
166  int nsrc = src_cells.size();
167  std::vector<Weights_t> sources_and_weights(nsrc);
168  int ninserted = 0;
169  for (int i = 0; i < nsrc; i++) {
170  int s = src_cells[i];
171 
172  Weights_t & this_wt = sources_and_weights[ninserted];
173  this_wt.entityID = s;
174 
175 #ifdef HAVE_TANGRAM
176  int nmats = sourceStateWrapper.cell_get_num_mats(s);
177  std::vector<int> cellmats;
178  sourceStateWrapper.cell_get_mats(s, &cellmats);
179 
180  if (!nmats || (matid_ == -1) || (nmats == 1 && cellmats[0] == matid_)) {
181  // ---------- Intersection with pure cell ---------------
182  // nmats == 0 -- no materials ==> single material
183  // matid_ == -1 -- intersect with mesh not a particular material
184  // nmats == 1 && cellmats[0] == matid -- intersection with pure cell
185  // containing matid
186 
187  std::vector<Wonton::Point<2>> source_poly;
188  sourceMeshWrapper.cell_get_coordinates(s, &source_poly);
189 
190  this_wt.weights = intersect_polys_r2d(source_poly, target_poly,
191  num_tols_);
192 
193  } else { // multi-material case
194  // How can I check that I didn't get DummyInterfaceReconstructor
195  //
196  // static_assert(InterfaceReconstructorType<SourceMeshType, 2> !=
197  // DummyInterfaceReconstructor<SourceMeshType, 2>);
198 
199  assert(interface_reconstructor != nullptr); // cannot be nullptr
200 
201  if (std::find(cellmats.begin(), cellmats.end(), matid_) !=
202  cellmats.end()) {
203  // mixed cell containing this material - intersect with
204  // polygon approximation of this material in the cell
205  // (obtained from interface reconstruction)
206 
207  Tangram::CellMatPoly<2> const& cellmatpoly =
208  interface_reconstructor->cell_matpoly_data(s);
209  std::vector<Tangram::MatPoly<2>> matpolys =
210  cellmatpoly.get_matpolys(matid_);
211 
212  this_wt.weights.resize(3, 0.0);
213  for (auto& matpoly : matpolys) {
214  std::vector<Wonton::Point<2>> tpnts = matpoly.points();
215  std::vector<Wonton::Point<2>> source_poly;
216  source_poly.reserve(tpnts.size());
217  for (auto const & p : tpnts) source_poly.push_back(p);
218 
219  std::vector<double> momvec = intersect_polys_r2d(source_poly,
220  target_poly, num_tols_);
221  for (int k = 0; k < 3; k++)
222  this_wt.weights[k] += momvec[k];
223  }
224  }
225  }
226 #else
227  std::vector<Wonton::Point<2>> source_poly;
228  sourceMeshWrapper.cell_get_coordinates(s, &source_poly);
229 
230  this_wt.weights = intersect_polys_r2d(source_poly, target_poly,
231  num_tols_);
232 #endif
233 
234  // Increment if vol of intersection > 0; otherwise, allow overwrite
235  if (!this_wt.weights.empty() && this_wt.weights[0] > 0.0)
236  ninserted++;
237  }
238 
239  sources_and_weights.resize(ninserted);
240  return sources_and_weights;
241  }
242 
243  IntersectR2D() = delete;
244 
246  IntersectR2D & operator = (const IntersectR2D &) = delete;
247 
248  private:
249  SourceMeshType const & sourceMeshWrapper;
250  SourceStateType const & sourceStateWrapper;
251  TargetMeshType const & targetMeshWrapper;
252  int matid_ = -1;
253 #ifdef HAVE_TANGRAM
254  std::shared_ptr<InterfaceReconstructor2D> interface_reconstructor;
255 #endif
256  NumericTolerances_t num_tols_;
257 }; // class IntersectR2D
258 
259 
260 
261 
263 // Specialization of Intersect2D class for nodes
264 
265 template <class SourceMeshType, class SourceStateType,
266  class TargetMeshType,
267  template <class, int, class, class> class InterfaceReconstructorType,
268  class Matpoly_Splitter, class Matpoly_Clipper>
269 class IntersectR2D<Entity_kind::NODE, SourceMeshType, SourceStateType, TargetMeshType,
270  InterfaceReconstructorType, Matpoly_Splitter, Matpoly_Clipper> {
271 
272 #ifdef HAVE_TANGRAM
273  using InterfaceReconstructor2D =
274  Tangram::Driver<InterfaceReconstructorType, 2, SourceMeshType,
275  Matpoly_Splitter, Matpoly_Clipper>;
276 #endif
277 
278  public:
279 
280 #ifdef HAVE_TANGRAM
281 
283  IntersectR2D(SourceMeshType const & source_mesh,
284  SourceStateType const & source_state,
285  TargetMeshType const & target_mesh,
286  NumericTolerances_t num_tols,
287  std::shared_ptr<InterfaceReconstructor2D> ir)
288  : sourceMeshWrapper(source_mesh), sourceStateWrapper(source_state),
289  targetMeshWrapper(target_mesh), interface_reconstructor(ir),
290  num_tols_(num_tols) {}
291 #endif
292 
293 
295 
296  IntersectR2D(SourceMeshType const & source_mesh,
297  SourceStateType const & source_state,
298  TargetMeshType const & target_mesh,
299  NumericTolerances_t num_tols)
300  : sourceMeshWrapper(source_mesh), sourceStateWrapper(source_state),
301  targetMeshWrapper(target_mesh), num_tols_(num_tols) {}
302 
304 
305  void set_material(int m) {
306  matid_ = m;
307  }
308 
314 
315  std::vector<Weights_t> operator() (int tgt_node, std::vector<int> const& src_nodes) const {
316  std::vector<Wonton::Point<2>> target_poly;
317  targetMeshWrapper.dual_cell_get_coordinates(tgt_node, &target_poly);
318 
319  int nsrc = src_nodes.size();
320  std::vector<Weights_t> sources_and_weights(nsrc);
321  int ninserted = 0;
322  for (int i = 0; i < nsrc; i++) {
323  int s = src_nodes[i];
324  std::vector<Wonton::Point<2>> source_poly;
325  sourceMeshWrapper.dual_cell_get_coordinates(s, &source_poly);
326 
327  Weights_t & this_wt = sources_and_weights[ninserted];
328  this_wt.entityID = s;
329  this_wt.weights = intersect_polys_r2d(source_poly, target_poly,
330  num_tols_);
331 
332  // Increment if vol of intersection > 0; otherwise, allow overwrite
333  if (!this_wt.weights.empty() && this_wt.weights[0] > 0.0)
334  ninserted++;
335  }
336 
337  sources_and_weights.resize(ninserted);
338  return sources_and_weights;
339  }
340 
341  IntersectR2D() = delete;
342 
344 
345  IntersectR2D & operator = (const IntersectR2D &) = delete;
346 
347  private:
348  SourceMeshType const & sourceMeshWrapper;
349  SourceStateType const & sourceStateWrapper;
350  TargetMeshType const & targetMeshWrapper;
351  int matid_ = -1;
352 #ifdef HAVE_TANGRAM
353  std::shared_ptr<InterfaceReconstructor2D> interface_reconstructor;
354 #endif
355  NumericTolerances_t num_tols_;
356 }; // class IntersectR2D
357 
358 } // namespace Portage
359 
360 #endif // PORTAGE_INTERSECT_INTERSECT_R2D_H_
IntersectR2D(SourceMeshType const &source_mesh, SourceStateType const &source_state, TargetMeshType const &target_mesh, NumericTolerances_t num_tols)
Constructor WITHOUT interface reconstructor.
Definition: intersect_r2d.h:296
IntersectR2D(SourceMeshType const &source_mesh, SourceStateType const &source_state, TargetMeshType const &target_mesh, NumericTolerances_t num_tols)
Constructor WITHOUT interface reconstructor.
Definition: intersect_r2d.h:69
void set_material(int m)
Set the source mesh material that we have to intersect against.
Definition: intersect_r2d.h:78
algorithm
Definition: intersect_r2d.h:44
Intersection and other tolerances to handle tiny values.
Definition: portage.h:152
void set_material(int m)
Set the source mesh material that we have to intersect against.
Definition: intersect_r2d.h:153
std::vector< double > intersect_polys_r2d(std::vector< Wonton::Point< 2 >> const &source_poly, std::vector< Wonton::Point< 2 >> const &target_poly, NumericTolerances_t num_tols)
Definition: intersect_polys_r2d.h:29
void set_material(int m)
Set the source mesh material that we have to intersect against.
Definition: intersect_r2d.h:305
IntersectR2D(SourceMeshType const &source_mesh, SourceStateType const &source_state, TargetMeshType const &target_mesh, NumericTolerances_t num_tols)
Constructor WITHOUT interface reconstructor.
Definition: intersect_r2d.h:144
Definition: coredriver.h:42
IntersectR2D & operator=(const IntersectR2D &)=delete
Assignment operator (disabled)
std::vector< Weights_t > operator()(const int tgt_entity, std::vector< int > const &src_entities) const
Intersect control volume of a target entity with control volumes of a set of source entities...
Definition: intersect_r2d.h:88