Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Overlay_IO.C
Go to the documentation of this file.
1 /* *******************************************************************
2  * Rocstar Simulation Suite *
3  * Copyright@2015, Illinois Rocstar LLC. All rights reserved. *
4  * *
5  * Illinois Rocstar LLC *
6  * Champaign, IL *
7  * www.illinoisrocstar.com *
8  * sales@illinoisrocstar.com *
9  * *
10  * License: See LICENSE file in top level of distribution package or *
11  * http://opensource.org/licenses/NCSA *
12  *********************************************************************/
13 /* *******************************************************************
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
15  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES *
16  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *
17  * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR *
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
21  * USE OR OTHER DEALINGS WITH THE SOFTWARE. *
22  *********************************************************************/
23 // $Id: Overlay_IO.C,v 1.19 2008/12/06 08:43:28 mtcampbe Exp $
24 
25 //===============================================================
26 // This file contains the implementation of routines for exporting the
27 // common subdivision into RFC_Window_base to be used for data transfer.
28 // Author: Xiangmin Jiao
29 // Date: 06/14/2001
30 //===============================================================
31 
32 #include "Overlay.h"
33 #include "Triangulation.h"
34 
36 
44 void Overlay::
45 set_subnode_id( INode *i, int color, int pane_id, int l_id) {
46  if ( color==BLUE) {
47  int global_id = i->id();
48  Node_ID &vid = _subnode_ids_b[ global_id];
49  if ( vid.node_id < 0) { // Uninitialized
50  vid = Node_ID( pane_id, l_id);
51  _subnode_copies_b[global_id] = 1;
52  }
53  else {
54  _subnode_imap_b[global_id][ vid.pane_id] = vid.node_id;
55  std::map<int,int> &imap=_subnode_imap_b[global_id];
56  RFC_assertion( imap.find(pane_id) == imap.end());
57  imap[ pane_id] = l_id;
58  ++_subnode_copies_b[global_id];
59  }
60  }
61  else {
62  RFC_assertion( color==GREEN);
63  int global_id = i->id();
64  Node_ID &vid = _subnode_ids_g[ global_id];
65  if ( vid.node_id < 0) { // Uninitialized
66  vid = Node_ID( pane_id, l_id);
67  _subnode_copies_g[global_id] = 1;
68  }
69  else {
70  _subnode_imap_g[global_id][ vid.pane_id] = vid.node_id;
71  std::map<int,int> &imap=_subnode_imap_g[global_id];
72  RFC_assertion( imap.find(pane_id) == imap.end());
73  imap[ pane_id] = l_id;
74  ++_subnode_copies_g[global_id];
75  }
76  }
77 }
78 
82 int Overlay::
83 get_subnode_id( const INode *i, int color, int pane_id) const {
84  if ( color==BLUE) {
85  int global_id = i->id();
86  const Node_ID &vid = _subnode_ids_b[ global_id];
87 
88  if ( vid.pane_id == pane_id)
89  return vid.node_id;
90  else
91  return _subnode_imap_b.find( global_id)->second.find( pane_id)->second;
92  }
93  else { RFC_assertion( color == GREEN);
94  int global_id = i->id();
95  const Node_ID &vid = _subnode_ids_g[ global_id];
96 
97  if ( vid.pane_id == pane_id)
98  return vid.node_id;
99  else
100  return _subnode_imap_g.find( global_id)->second.find( pane_id)->second;
101  }
102 }
103 
106 int Overlay::
107 get_subnode_copies( const INode *i, int color) const {
108  if ( color==BLUE) {
109  int global_id = i->id();
110  return _subnode_copies_b[ global_id];
111  }
112  else {
113  RFC_assertion( color == GREEN);
114  int global_id = i->id();
115  return _subnode_copies_g[ global_id];
116  }
117 }
118 
122 void
124  int pane_id, int &lid,
126  Point_2 &nc) const {
127  lid = get_subnode_id( i, color, pane_id);
128  i->nat_coor( color, nc);
129 
130  // ==== Determine eid
131  RFC_Pane_overlay &pane = *acc.get_pane(h);
132  eid.face_id = pane.get_lid( h->facet());
133 
134  // Determine eid.edge_id
135  Element_node_enumerator ene( pane.base(), eid.face_id);
136  Halfedge *b = i->halfedge( color);
137 
138  if ( b->facet() != h->facet()) {
139  RFC_assertion( i->parent_type(color) != PARENT_FACE);
140  RFC_Window_overlay &win = color==BLUE? *B : *G;
141  RFC_assertion_code( int count=0);
142  // Find the local node id of b->origin() in the host pane of h
143  while ( !win.is_same_node( b->origin(), h->destination())) {
144  h = h->next(); RFC_assertion( ++count <= 4);
145  }
146  if ( i->parent_type(color) == PARENT_VERTEX)
147  eid.edge_id = pane.get_lvid( ene, pane.get_lid( h->destination()));
148  else {
149  eid.edge_id = pane.get_lvid( ene, pane.get_lid( h->origin()));
150  nc = Point_2( 1-nc[0], 0);
151  }
152  }
153  else {
154  eid.edge_id = pane.get_lvid( ene, pane.get_lid( b->origin()));
155 
156  if ( i->parent_type(color) == PARENT_FACE) {
157  pane.normalize_nat_coor( eid.edge_id, ene.size_of_edges(), nc);
158  eid.edge_id = 0;
159  }
160  }
161 }
162 
163 // Assign numbers to an S-vertex within all its host panes
164 void Overlay::
165 number_a_subnode( INode *i, int color,
166  std::map<int,std::pair<int,int> > &cnts) {
167  Parent_type t = i->parent_type( color);
168  Halfedge *h = i->halfedge( color);
169 
170  switch ( t) {
171  case PARENT_FACE: {
172  int pane_id = acc.get_pane(h)->id();
173  set_subnode_id( i, color, pane_id, ++(cnts[ pane_id].second));
174  break;
175  }
176  case PARENT_EDGE: {
177  Halfedge *h0 = h;
178  int last_id = -1;
179  do {
180  int pane_id = acc.get_pane(h)->id();
181  if ( pane_id == last_id) continue;
182  set_subnode_id( i, color, pane_id, ++(cnts[ pane_id].second));
183  last_id = pane_id;
184  } while ( (h=acc.get_opposite(h)) != h0);
185  break;
186  }
187  default: {
189 
190  Halfedge *h0 = h;
191  int last_id = -1;
192  std::set<int> panes;
193  bool first_iter = true;
194  do {
195  int pane_id = acc.get_pane(h)->id();
196  if ( !first_iter && (pane_id==last_id||panes.find(pane_id)!=panes.end()))
197  continue;
198  set_subnode_id( i, color, pane_id, ++(cnts[ pane_id].first));
199  panes.insert(last_id=pane_id);
200 
201  // Optimization assuming the halfedge structure is normalized
202  if ( first_iter && !h->origin()->halfedge()->is_border()) break;
203  first_iter = false;
204  } while ( (h=acc.get_next_around_origin(h)) != h0);
205  break;
206  }
207  }
208 }
209 
210 // Count the number of S-vertices whose parents are vertices
211 void Overlay::
212 count_subnodes( INode *i, int color,
213  std::map<int,std::pair<int,int> > &cnts) {
214  if ( i->parent_type( color) == PARENT_VERTEX) {
215  Halfedge *h = i->halfedge( color);
216  Halfedge *h0 = h;
217  int last_id = -1;
218  std::set<int> panes;
219  bool first_iter = true;
220  do {
221  int pane_id = acc.get_pane(h)->id();
222  if ( !first_iter && (pane_id==last_id||panes.find(pane_id)!=panes.end()))
223  continue;
224  ++(cnts[ pane_id].second);
225  panes.insert(last_id=pane_id);
226 
227  // Optimization assuming the halfedge structure is normalized
228  if ( first_iter && !h->origin()->halfedge()->is_border()) break;
229  first_iter = false;
230  } while ( (h=acc.get_next_around_origin(h)) != h0);
231  }
232 }
233 
234 // Determine the numbering system for the S-vertices within panes.
235 void Overlay::
237  std::vector<RFC_Pane_overlay*> b_ps, g_ps;
238  B->panes( b_ps); G->panes( g_ps);
239 
240  // Maps from pane ids to the number of S-vertices processed
241  std::map< int, std::pair<int,int> > b_vertex_counts;
242  std::map< int, std::pair<int,int> > g_vertex_counts;
243 
244  std::vector<RFC_Pane_overlay*>::iterator pi;
245  for ( pi=b_ps.begin(); pi!=b_ps.end(); ++pi)
246  b_vertex_counts[(*pi)->id()] = std::make_pair(0,0);
247  for ( pi=g_ps.begin(); pi!=g_ps.end(); ++pi)
248  g_vertex_counts[(*pi)->id()] = std::make_pair(0,0);
249 
250  // Loop through the S-vertices
251  // First, count the number of subvertices host at vertices
252  for ( std::list< INode*>::const_iterator
253  it=inodes.begin(); it!=inodes.end(); ++it) {
254  count_subnodes( *it, BLUE, b_vertex_counts);
255  count_subnodes( *it, GREEN, g_vertex_counts);
256  }
257 
258  // Second, assign IDs for subnodes
259  int n=inodes.size();
260  _subnode_ids_b.resize( n, Node_ID( 0,-1));
261  _subnode_ids_g.resize( n, Node_ID( 0,-1));
262  _subnode_copies_b.resize( n, 0);
263  _subnode_copies_g.resize( n, 0);
264  int i=0;
265  for ( std::list< INode*>::const_iterator
266  it=inodes.begin(); it!=inodes.end(); ++it,++i) {
267  (*it)->set_id( i);
268  number_a_subnode( *it, BLUE, b_vertex_counts);
269  number_a_subnode( *it, GREEN, g_vertex_counts);
270  }
271 
272  // Allocate space for subnodes.
273  for ( pi=b_ps.begin(); pi!=b_ps.end(); ++pi)
274  (*pi)->allocate_subnodes( b_vertex_counts[(*pi)->id()].second);
275  for ( pi=g_ps.begin(); pi!=g_ps.end(); ++pi)
276  (*pi)->allocate_subnodes( g_vertex_counts[(*pi)->id()].second);
277 }
278 
279 // Determine the number system for the S-faces within panes
280 void Overlay::
282  std::vector<RFC_Pane_overlay*> b_ps, g_ps;
283  B->panes( b_ps); G->panes( g_ps);
284 
285  typedef std::map< int, std::vector< int> > Subface_counts;
286  Subface_counts cnts_b, cnts_g;
287 
288  std::vector<RFC_Pane_overlay*>::iterator pi;
289  for ( pi=b_ps.begin(); pi!=b_ps.end(); ++pi)
290  cnts_b[(*pi)->id()].resize( (*pi)->size_of_faces(), 0);
291  for ( pi=g_ps.begin(); pi!=g_ps.end(); ++pi)
292  cnts_g[(*pi)->id()].resize( (*pi)->size_of_faces(), 0);
293 
294  // First, count the number of S-faces by looping through all the blue faces
295  for ( pi=b_ps.begin(); pi!=b_ps.end(); ++pi) {
296  RFC_Pane_overlay *pane_b = *pi;
297  Subface_counts::iterator cnts_it_b = cnts_b.find(pane_b->id());
298  Subface_counts::iterator cnts_it_g = cnts_g.begin();
299 
300  for ( HDS::Facet_iterator fi=pane_b->hds().facets_begin();
301  fi!=pane_b->hds().facets_end(); ++fi) {
302  // Construct a list of nodes for the blue face
303  INode_const_list nodes;
304  get_inodes_of_face( &*fi, nodes);
305  RFC_assertion( nodes.size() > 2);
306 
307  Subface_list sub_faces;
308  // subdivide the face
309  bool ret = subdivide( nodes, ++nodes.begin(), sub_faces, BLUE);
310  if ( ret) {
311  std::cerr << "ERROR: Got error code " << ret
312  << " when subdividing face "
313  << fi - pane_b->hds().facets_begin() + 1
314  << " with node "
315  << pane_b->get_index( fi->halfedge()->origin())+1
316  << " in pane " << pane_b->id() << std::endl;
317 
318  sub_faces.clear();
319  subdivide( nodes, ++nodes.begin(), sub_faces, BLUE);
320  RFC_assertion(!ret); abort();
321  }
322  if (sub_faces.empty()) {
323  std::cerr << "ERROR: Error in enumerating subface in face "
324  << fi - pane_b->hds().facets_begin() + 1
325  << " in pane " << pane_b->id() << std::endl;
326  RFC_assertion(!sub_faces.empty()); abort();
327  }
328 
329  // Count the subfaces in the blue face
330  for (Subface_list::iterator
331  si=sub_faces.begin(), send=sub_faces.end(); si != send; ++si) {
332  int num_tris = si->size()-2;
333  Halfedge *s = get_parent_face( *si, GREEN);
334  RFC_Pane_overlay *pane_g = acc.get_pane(s);
335  if ( cnts_it_g->first != pane_g->id())
336  cnts_it_g=cnts_g.find(pane_g->id());
337 
338  cnts_it_b->second[pane_b->get_index(&*fi)] += num_tris;
339  cnts_it_g->second[pane_g->get_index(s->facet())] += num_tris;
340  }
341  }
342  }
343 
344  // Allocate space for subfaces and convert counts into offsets.
345  for ( pi=b_ps.begin(); pi!=b_ps.end(); ++pi) {
346  std::vector< int> &cnts = cnts_b[ (*pi)->id()];
347  (*pi)->allocate_subfaces( cnts);
348  if ( cnts.empty()) continue;
349  // Convert counts into offsets
350  int t1=cnts[0];
351  cnts[0] = 0;
352  for ( int i=1, n=cnts.size(); i<n; ++i) {
353  int t2 = cnts[i];
354  cnts[i] = cnts[i-1] + t1;
355  t1 = t2;
356  }
357  }
358 
359  for ( pi=g_ps.begin(); pi!=g_ps.end(); ++pi) {
360  std::vector< int> &cnts = cnts_g[ (*pi)->id()];
361  (*pi)->allocate_subfaces( cnts);
362  if ( cnts.empty()) continue;
363  // Convert counts into offsets
364  int t1=cnts[0];
365  cnts[0] = 0;
366  for ( int i=1, n=cnts.size(); i<n; ++i) {
367  int t2 = cnts[i];
368  cnts[i] = cnts[i-1] + t1;
369  t1 = t2;
370  }
371  }
372 
373  Subface_counts &offsets_b=cnts_b, &offsets_g=cnts_g;
374 
375  // Third, we fill up the arrays for face-list and etc.
376  for ( pi=b_ps.begin(); pi!=b_ps.end(); ++pi) {
377  RFC_Pane_overlay *pane_b = *pi;
378  const int pane_id_b = pane_b->id();
379 
380  Subface_counts::iterator offsets_it_b = offsets_b.find(pane_b->id());
381  Subface_counts::iterator offsets_it_g = offsets_g.begin();
382 
383  for ( HDS::Facet_iterator fi=(*pi)->hds().facets_begin();
384  fi!=(*pi)->hds().facets_end(); ++fi) {
385 
386  // Construct a list of nodes for the blue face
387  INode_const_list nodes;
388  get_inodes_of_face( &*fi, nodes);
389  RFC_assertion( nodes.size() > 2);
390 
391  Subface_list sub_faces;
392  // subdivide the face
393  RFC_assertion_code( bool ret = )
394  subdivide( nodes, ++nodes.begin(), sub_faces, BLUE);
395  RFC_assertion( !ret);
396 
397  Halfedge *b = fi->halfedge();
398  Generic_element e_b( count_edges(b));
399 
400  // output the subfaces of the blue face
401  for (Subface_list::iterator
402  si=sub_faces.begin(), send=sub_faces.end(); si != send; ++si) {
403  int n = si->size(), num_tris = n-2;
404 
405  Halfedge *g = get_parent_face( *si, GREEN);
406  Generic_element e_g( count_edges(g));
407 
408  std::vector< Point_2> pnts_b( n), pnts_g( n);
409  for ( int k=0; k<n; ++k) {
410  pnts_b[k] = get_nat_coor( *(*si)[k], e_b, b, BLUE);
411  pnts_g[k] = get_nat_coor( *(*si)[k], e_g, g, GREEN);
412  }
413 
414  std::vector< Three_tuple<int> > tris( num_tris);
415  Triangulation triangulation;
416  // Triangulate the sub-face in both B and G.
417  triangulation.triangulate( &pnts_b[0], n, &tris);
418 
419  RFC_Pane_overlay *pane_g = acc.get_pane(g);
420  const int pane_id_g = pane_g->id();
421  // Insert the triangles into the blue and green panes
422  for ( int k=0; k<num_tris; ++k) {
423  int lids_b[3], lids_g[3];
424  RFC_Pane_overlay::Edge_ID eids_b[3], eids_g[3];
425  Point_2 ncs_b[3], ncs_g[3];
426 
427  for ( int i=0; i<3; ++i) {
428  COM_assertion_msg( (*si)[tris[k][i]], "Empty intersection.");
429 
430  convert_nat_coordinates( (*si)[tris[k][i]], b, BLUE, pane_id_b,
431  lids_b[i], eids_b[i], ncs_b[i]);
432  convert_nat_coordinates( (*si)[tris[k][i]], g, GREEN, pane_id_g,
433  lids_g[i], eids_g[i], ncs_g[i]);
434  }
435 
436  if ( offsets_it_g->first != pane_g->id())
437  offsets_it_g=offsets_g.find(pane_g->id());
438 
439  int idx_b = offsets_it_b->second[pane_b->get_index(&*fi)]++;
440  int idx_g = offsets_it_g->second[pane_g->get_index(g->facet())]++;
441 
442  pane_b->insert_subface(idx_b, pane_b->get_lid( b->facet()),
443  lids_b, eids_b, ncs_b,
444  pane_id_g, idx_g+1, lids_g);
445  pane_g->insert_subface(idx_g, pane_g->get_lid( g->facet()),
446  lids_g, eids_g, ncs_g,
447  pane_id_b, idx_b+1, lids_b);
448  }
449  }
450  }
451  }
452 }
453 
454 void Overlay::
456  // Copy data from RFC_Window_overlay into RFC_Window_base.
457  B->export_window( bw);
458  G->export_window( gw);
459 }
460 
462 
463 
464 
465 
466 
467 
std::pair< int, int > Node_ID
int face_id
local face id.
void number_subnodes()
Definition: Overlay_IO.C:236
std::vector< Node_ID > _subnode_ids_b
Definition: Overlay.h:247
int node_id
the local id within the pane starting from 1.
std::list< const INode * > INode_const_list
Definition: Overlay.h:63
Parent_type parent_type(const int color) const
Definition: HDS_overlay.h:350
void set_subnode_id(INode *i, int color, int pane_id, int l_id)
Definition: Overlay_IO.C:45
void insert_subface(int idx, int plid, const int *lids, const Edge_ID *eids, const Point_2 *nc, int rp_id, int cnt, const int *rids)
Insert all the infomation related to a subface into the database.
Halfedge_overlay * halfedge()
Definition: HDS_overlay.h:73
An adaptor for enumerating node IDs of an element.
int id() const
Definition: HDS_overlay.h:347
void number_subfaces()
Definition: Overlay_IO.C:281
Halfedge * get_opposite(Halfedge *h) const
Definition: HDS_accessor.h:99
j indices k indices k
Definition: Indexing.h:6
Vertex_overlay * destination()
Definition: HDS_overlay.h:137
#define COM_assertion_msg(EX, msg)
double s
Definition: blastest.C:80
RFC_Pane_overlay * get_pane(Vertex *v) const
Definition: HDS_accessor.h:128
void normalize_nat_coor(int idx, int e, Point &nc) const
Base * base()
The id of its base COM::Pane object.
std::map< int, std::map< int, int > > _subnode_imap_g
Definition: Overlay.h:253
Halfedge * get_parent_face(const Subface &sf, int color)
Definition: Overlay.C:1841
void triangulate(const Point_2 *ps, int n, Connectivity *tri)
Main entry for triangulation.
Definition: Triangulation.h:87
SURF::Generic_element_2 Generic_element
Definition: rfc_basic.h:46
bool is_border() const
Definition: HDS_overlay.h:131
const Color GREEN
Definition: Color.C:59
int get_lid(const Vertex *v) const
int get_lvid(const Element_node_enumerator &ene, const int v) const
void panes(std::vector< Pane * > &ps)
Get a vector of local panes contained in the window.
std::vector< char > _subnode_copies_g
Definition: Overlay.h:250
void number_a_subnode(INode *i, int color, std::map< int, std::pair< int, int > > &cnts)
Definition: Overlay_IO.C:165
A window is a collection of panes.
Vertex_overlay * origin()
Definition: HDS_overlay.h:135
void get_inodes_of_face(const Facet *f, INode_const_list &nodes)
Definition: Overlay.C:1922
#define RFC_END_NAME_SPACE
Definition: rfc_basic.h:29
int pane_id
the id of the owner pane.
void convert_nat_coordinates(const INode *i, Halfedge *h, int color, int pane_id, int &lid, RFC_Pane_overlay::Edge_ID &eid, Point_2 &nc) const
Definition: Overlay_IO.C:123
Parent_type
Definition: rfc_basic.h:49
const Point_2S & nat_coor(const int color) const
Definition: HDS_overlay.h:327
RFC_Window_overlay * G
Definition: Overlay.h:281
void export_windows(RFC_Window_base *, RFC_Window_base *)
Export the subdivisions to the two given windows.
Definition: Overlay_IO.C:455
A window is a collection of panes.
A local ID of an edge.
std::vector< Node_ID > _subnode_ids_g
Definition: Overlay.h:248
int edge_id
edge id within the face.
blockLoc i
Definition: read.cpp:79
#define RFC_BEGIN_NAME_SPACE
Definition: rfc_basic.h:28
Triangulating a convex polygon by ear-removal.
Definition: Triangulation.h:50
int get_subnode_id(const INode *i, int color, int pane_id) const
Definition: Overlay_IO.C:83
std::map< int, std::map< int, int > > _subnode_imap_b
Definition: Overlay.h:252
const NT & n
int count_edges(const Halfedge *e) const
Definition: Overlay.h:224
const Color BLUE
Definition: Color.C:62
Halfedge * halfedge(const int color) const
Definition: HDS_overlay.h:357
HDS_accessor< Tag_true > acc
Definition: Overlay.h:284
Halfedge_overlay * next()
Definition: HDS_overlay.h:120
bool subdivide(const INode_const_list &face, INode_const_list::const_iterator last_checked, Subface_list &sub_faces, int color, int depth=0) const
Definition: Overlay.C:1759
std::list< Subface > Subface_list
Definition: Overlay.h:65
#define RFC_assertion_code
Definition: rfc_basic.h:68
int get_index(const Vertex *v) const
Halfedge * get_next_around_origin(Halfedge *h) const
Definition: HDS_accessor.h:136
const double pi
std::vector< char > _subnode_copies_b
Definition: Overlay.h:249
Point_2 get_nat_coor(const INode &i, const Generic_element &e, const Halfedge *h, int color) const
Definition: Overlay.C:1854
void export_window(RFC_Window_base *) const
A global ID of a node.
RFC_Window_overlay * B
Definition: Overlay.h:280
int id() const
int get_subnode_copies(const INode *i, int color) const
Definition: Overlay_IO.C:107
void allocate_subfaces(const std::vector< int > &cnts)
Allocate memory space for the arrays for storing the subdivision.
#define RFC_assertion
Definition: rfc_basic.h:65
std::list< INode * > inodes
Definition: Overlay.h:282
void count_subnodes(INode *i, int color, std::map< int, std::pair< int, int > > &cnts)
Definition: Overlay_IO.C:212
Facet_overlay * facet()
Definition: HDS_overlay.h:129
SURF::Vector_2< Real > Point_2
Definition: rfc_basic.h:43