Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RFC_Window_base.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: RFC_Window_base.C,v 1.27 2008/12/06 08:43:28 mtcampbe Exp $
24 
25 // Base implementation of the windows for Rocface.
26 
27 #include <set>
28 #include "RFC_Window_base.h"
29 #include "../Rocmap/include/Pane_connectivity.h"
30 #include "../Rocmap/include/Pane_boundary.h"
31 #include "../Rocsurf/include/Generic_element_2.h"
32 
34 
40  : _base(b), _is_master(true), _quadratic(false),
41  _n_border(0), _n_isolated(0), _color(color) {}
42 
43 void
45 
46  // Determine whether the pane has quadratic elements
47  if ( !_base->is_structured()) {
48  _base->elements( _elem_conns);
49  _elem_offsets.reserve( _elem_conns.size());
50 
51  for ( std::vector<const COM::Connectivity*>::const_iterator
52  it = _elem_conns.begin(); it != _elem_conns.end(); ++it) {
53  _elem_offsets.push_back( (*it)->index_offset());
54  const int ne = (*it)->size_of_edges_pe();
55  const int nn = (*it)->size_of_nodes_pe();
56  if ( nn > ne) _quadratic = true;
57  }
58  }
59 
60  MAP::Pane_boundary pb( _base);
61  pb.determine_border_nodes( _is_border, _is_isolated);
62 
63  for ( int i=0, n=_is_border.size(); i<n; ++i)
65 }
66 
67 // Note: This is not a general routine for detecting whether two nodes are
68 // coincident. It assumes that the two nodes belong to the same pane and
69 // the primary copy of the nodes also belongs to the same pane.
70 bool
71 RFC_Pane_base::coincident( int v1, int v2) const {
72  if ( v1==v2) return true;
73  V2b_table::const_iterator it1 = _v2b_table.find( v1);
74  V2b_table::const_iterator it2 = _v2b_table.find( v2);
75 
76  if ( it1 == _v2b_table.end() && it2 != _v2b_table.end())
77  return it2->second.first == id() &&
78  _b2v_table.find( id())->second[it2->second.second] == v1;
79  else if ( it1 != _v2b_table.end() && it2 == _v2b_table.end())
80  return it1->second.first == id() &&
81  _b2v_table.find( id())->second[it1->second.second] == v2;
82  else if ( it1 != _v2b_table.end() && it2 != _v2b_table.end()) {
83  RFC_assertion( it1->second.first==id() && it2->second.first==id());
84  B2v_table::const_iterator bit=_b2v_table.find( id());
85  return bit->second[it1->second.second]==bit->second[it2->second.second];
86  }
87  else
88  return false;
89 }
90 
91 void RFC_Pane_base::
92 get_nat_coor_in_element( const int sn_id,
93  Element_node_enumerator &ene, Point_2 &nc) const {
94  RFC_assertion( sn_id >= 1 && sn_id <= int(_subnode_parents.size()));
95 
96  const Point_2S &p = _subnode_nat_coors[ sn_id-1];
97  const Edge_ID &eid = _subnode_parents[ sn_id-1];
98 
99  if ( eid.face_id == ene.id()) {
100  nc[0]=p[0]; nc[1]=p[1];
101  normalize_nat_coor( eid.edge_id, ene.size_of_edges(), nc);
102  }
103  else {
104  nc[0] = 1.-p[0]; nc[1]=0;
105  int vid = Element_node_enumerator(_base,eid.face_id)[eid.edge_id];
106 
107  int i = get_lvid(ene, vid)-1;
108 
109  int num_edges = ene.size_of_edges();
110  if ( i<0) i=num_edges-1;
111  normalize_nat_coor( i, num_edges, nc);
112  }
113 }
114 
117 int
119  const Point_2S &nc = _subnode_nat_coors[ id-1];
120  if ( nc[0]==0 && nc[1]==0)
121  return PARENT_VERTEX;
122  if ( nc[1]==0)
123  return PARENT_EDGE;
124  return PARENT_FACE;
125 }
126 
129 int
131  const Edge_ID &eid=_subnode_parents[ id-1];
133 
134  return ene[eid.edge_id];
135 }
136 
137 Point_3
139  const int fid = _subnode_parents[i-1].face_id;
140  Element_node_enumerator ene( _base, fid);
141  Point_2 nc; get_nat_coor_in_element( i, ene, nc);
142 
143  Nodal_coor_const coors;
145  ps( coors, coordinates(), ene);
146 
147  return SURF::Generic_element_2( ene.size_of_edges(),
148  ene.size_of_nodes()).interpolate(ps, nc);
149 }
150 
151 Bbox_3
153  Bbox_3 b;
154  for ( int i=1, size=size_of_nodes(); i<=size; ++i)
155  b += Bbox_3(get_point( i));
156  return b;
157 }
158 
160 RFC_Pane_base::get_edge_id( const int face_lid, const int vertex_lid) const {
161  if ( _base->is_structured()) {
162  Element_node_enumerator ene( _base, face_lid, (COM::Connectivity *)NULL);
163  for ( int k=0; k<4; ++k)
164  if ( ene[k] == vertex_lid) return Edge_ID( face_lid, k);
165  RFC_assertion(false); abort();
166  }
167  else {
168  for ( std::vector<const COM::Connectivity*>::const_iterator
169  it = _elem_conns.begin(); it != _elem_conns.end(); ++it) {
170  const int ne = (*it)->size_of_edges_pe();
171  if ( face_lid > int((*it)->index_offset()) &&
172  face_lid <= int((*it)->index_offset()+(*it)->size_of_elements())) {
173  Element_node_enumerator ene(_base, face_lid-(*it)->index_offset(), *it);
174 
175  for ( int k=0; k<ne; ++k)
176  if ( ene[k] == vertex_lid) return Edge_ID(face_lid,k);
177  RFC_assertion(false); abort();
178  }
179  }
180  }
181  return Edge_ID(face_lid,-1);
182 }
183 
184 int
186  const int vid) const {
187  int i = ene.vertex( vid);
188  if ( i<0) {
189  // Resort to a more expensive method.
190  for ( int j=ene.size_of_nodes()-1; j>=0; --j) {
191  if ( coincident(vid, ene[j])) { i = j; }
192  }
193  RFC_assertion( i>=0);
194  }
195  return i;
196 }
197 
198 // If a node is a border node, it can have instances in multiple
199 // panes. The primary copy is the one with the smallest (pane_id, node_id)
200 // pair lexicalgraphically.
201 bool
202 RFC_Pane_base::is_primary_node( const int vid) const {
203  if ( !is_border_node(vid) && !is_isolated_node(vid)) return true;
204  V2b_table::const_iterator it = _v2b_table.find( vid);
205  RFC_assertion( it != _v2b_table.end() || !is_isolated_node( vid));
206  return ( it == _v2b_table.end());
207 }
208 
209 int
211  int n = size_of_nodes();
212  for ( V2b_table::const_iterator it=_v2b_table.begin(), iend=_v2b_table.end();
213  it != iend; ++it) {
214  if ( !is_primary_node( it->first)) --n;
215  }
216  return n;
217 }
218 
219 void
221  //`Loop through the B2v_table
222  for ( B2v_table::iterator
223  it=_b2v_table.begin(), iend=_b2v_table.end(); it != iend; ++it) {
224  for ( int i=0, size=it->second.size(); i<size; ++i) {
225  if ( it->first > id() && !is_isolated_node(it->second[i])) continue;
226 
227  std::pair<int,int> p(it->first, i);
228  if ( it->first==id()) {
229  RFC_assertion( (i&1)==1 && it->second[i-1] < it->second[i] ||
230  (i&1)==0 && it->second[i] < it->second[i+1]);
231  if ( (i&1)==0 || is_isolated_node( it->second[i-1]))
232  continue;
233  --p.second;
234  }
235  else {
236  const RFC_Pane_base &pane = w->pane( it->first);
237  if ( pane.is_isolated_node( pane._b2v_table.find(id())->second[i]))
238  continue;
239  }
240 
241  if ( _v2b_table.find( it->second[i]) == _v2b_table.end())
242  _v2b_table[it->second[i]] = p;
243  }
244  }
245 }
246 
247 RFC_Window_base::RFC_Window_base( Base *b, int c, MPI_Comm comm)
248  : _base(b), _verbose(1), _color(c), _map_comm( b, comm) {}
250  while ( !_pane_set.empty()) {
251  delete _pane_set.begin()->second;
252  _pane_set.erase( _pane_set.begin());
253  }
254 }
255 
256 int
258  int n = 0;
259  // Loop through panes
260  Pane_set::const_iterator pit=_pane_set.begin(), piend=_pane_set.end();
261  for ( ; pit != piend; ++pit) {
262  n += pit->second->size_of_primary_nodes();
263  }
264 
265  return n;
266 }
267 
268 int
270  int n = 0;
271  // Loop through panes
272  Pane_set::const_iterator pit=_pane_set.begin(), piend=_pane_set.end();
273  for ( ; pit != piend; ++pit) {
274  n += pit->second->size_of_faces();
275  }
276 
277  return n;
278 }
279 
280 Bbox_3
282  Bbox_3 b;
283  Pane_set::const_iterator it=_pane_set.begin(), iend=_pane_set.end();
284  for ( ; it != iend; ++it)
285  b += it->second->get_bounding_box();
286  return b;
287 }
288 
289 void
291  MAP::Pane_connectivity pc( _base->attribute(COM::COM_MESH),
292  _map_comm.mpi_comm());
293  pc.compute_pconn( _base->attribute(COM::COM_PCONN));
294 
295  // Now copy from b2v into the tables of each pane
296  Pane_set::iterator pane_it, pane_iend=_pane_set.end();
297 
298  for ( pane_it=_pane_set.begin(); pane_it != pane_iend; ++pane_it) {
299  const COM::Attribute *pconn =
300  pane_it->second->_base->attribute(COM::COM_PCONN);
301 
302  int count=pc.pconn_offset(), s = pconn->size_of_real_items();
303  const int *buf= ((const int*)pconn->pointer())+count;
304 
305  while ( count < s) {
306  const int r_pid = *buf;
307  const int r_size = *(buf+1);
308  count += 2; buf += 2;
309 
310  Pane::B2v &b2 = pane_it->second->_b2v_table[ r_pid];
311  b2.clear();
312  b2.insert( b2.end(), buf, buf+r_size);
313 
314  count += r_size;
315  buf += r_size;
316  }
317  }
318 
319  // Construct v2b
320  for ( pane_it=_pane_set.begin(); pane_it != pane_iend; ++pane_it) {
321  Pane &pane = *pane_it->second;
322  pane.build_v2b_from_b2v( this);
323  }
324 }
325 
326 void
328  int nsn=size_of_subnodes();
329  _subnode_normalized_nc.resize( nsn);
330  _subnode_subID.resize( size_of_nodes());
331 
332  // Initialize _subnode_normalized_nc.
333  for ( int i=0; i<nsn; ++i) {
334  int f=_subnode_parents[i].face_id;
336 
337  Point_2 p; get_nat_coor_in_element( i+1, ene, p);
338  _subnode_normalized_nc[i] = Point_2S(p[0], p[1]);
339 
340  // Assign sub-node ID for each vertex in input mesh
342  int vid = ene[_subnode_parents[i].edge_id];
343  _subnode_subID[ vid-1] = i+1;
344  }
345  }
346 
347  int nsf=size_of_subfaces();
348  _subface_nat_coors.resize( nsf);
349  // Initialize _subface_nat_coors.
350  Element_node_enumerator ene( base(), 1);
351  for ( int i=0; i<nsf; ++i) {
352  if ( ene.id() != _subface_parents[i]) {
353  ene.next();
354  if ( ene.pane()==NULL || ene.id() != _subface_parents[i])
356  }
357  Point_2 p;
358  for ( int j=0; j<3; ++j) {
359  get_nat_coor_in_element( _subfaces[i][j], ene, p);
360  _subface_nat_coors[i][j] = Point_2S(p[0], p[1]);
361  }
362  }
363 }
364 
365 void
367 
368  Pane_set::const_iterator pane_it, pane_iend=_pane_set.end();
369 
370  for ( pane_it=_pane_set.begin(); pane_it != pane_iend; ++pane_it) {
371  Pane &pane = *pane_it->second;
372  Pane &to_pane = *w->_pane_set.find( pane.id())->second;
373 
374  // Copy over the nodes information
375  to_pane._subnode_parents = pane._subnode_parents;
377  to_pane._subnode_nat_coors = pane._subnode_nat_coors;
378 
379  // Copy over the face information
380  to_pane._subface_offsets = pane._subface_offsets;
382  to_pane._subface_parents = pane._subface_parents;
383  to_pane._subfaces = pane._subfaces;
384 
385  // Copy over the pane connectivity of the vertices
386  to_pane._b2v_table = pane._b2v_table;
387  to_pane._v2b_table = pane._v2b_table;
388 
389  to_pane.comp_nat_coors();
390  }
391 }
392 
394 
395 
396 
397 
398 
399 
int face_id
local face id.
MAP::Pane_communicator _map_comm
An adaptor for enumerating node IDs of an element.
void build_pc_tables()
Build the pane connectivity table.
j indices k indices k
Definition: Indexing.h:6
int vertex(int lvid, bool level=false) const
Get the vertex index of an vertex within the element.
void comp_nat_coors()
Compute the natural coordinates.
std::vector< const COM::Connectivity * > _elem_conns
double s
Definition: blastest.C:80
void normalize_nat_coor(int idx, int e, Point &nc) const
Base * base()
The id of its base COM::Pane object.
MAP::Facet_ID Edge_ID
Definition: Manifold_2.h:49
Adpator for element-wise data container.
SURF::Point_2< float > Point_2S
Definition: rfc_basic.h:45
const Point_3 & get_point(int id) const
Get the physical coordinates of the node with given local id.
Base * _base
Reference to its base object.
bool coincident(int i, int j) const
Report whether the two given nodes are coincident.
const RFC_Pane_base & pane(const int pid) const
int parent_type_of_subnode(int) const
Determine the parent type of a subnode of given tyep.
std::vector< Three_tuple< int > > _subfaces
int get_lvid(const Element_node_enumerator &ene, const int v) const
bool _quadratic
Does it contain quadratic elements?
int id() const
Get the local id of the element within the pane.
int size_of_subnodes() const
The total number of nodes in the subdivision of the pane.
std::vector< Edge_ID > _subnode_parents
Edge ids of parents.
Base * _base
A reference to its base COM::Window object.
void build_v2b_from_b2v(const RFC_Window_base *w)
Build pane connectivity.
std::vector< int > _elem_offsets
The base implementation of RFC_Pane.
std::vector< int > _subnode_subID
Sub-node ID of nodes in the pane.
#define RFC_END_NAME_SPACE
Definition: rfc_basic.h:29
int get_parent_node(int) const
Get the local parent node id of a given subnode.
**********************************************************************Rocstar Simulation Suite Illinois Rocstar LLC All rights reserved ****Illinois Rocstar LLC IL **www illinoisrocstar com **sales illinoisrocstar com WITHOUT WARRANTY OF ANY **EXPRESS OR INCLUDING BUT NOT LIMITED TO THE WARRANTIES **OF FITNESS FOR A PARTICULAR PURPOSE AND **NONINFRINGEMENT IN NO EVENT SHALL THE CONTRIBUTORS OR **COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES OR OTHER WHETHER IN AN ACTION OF TORT OR **Arising OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE **USE OR OTHER DEALINGS WITH THE SOFTWARE **********************************************************************INTERFACE SUBROUTINE knode iend
std::vector< bool > _is_isolated
Is a node isolated?
int size_of_faces() const
Get the total number of faces contained the window.
std::vector< Point_2S > _subnode_normalized_nc
Natual coordinates in the parent face.
int size_of_nodes() const
The total number of nodes in the pane.
A window is a collection of panes.
int size_of_edges() const
Number of edges per element.
A local ID of an edge.
Bbox_3 get_bounding_box() const
Get the bounding box of the pane.
int edge_id
edge id within the face.
blockLoc i
Definition: read.cpp:79
#define RFC_BEGIN_NAME_SPACE
Definition: rfc_basic.h:28
Point_3 get_point_of_subnode(int id) const
std::vector< bool > _is_border
Is a node on border?
void get_nat_coor_in_element(const int eid, const int lid, Point_2 &nc) const
Take a subface id and a local subnode id, return the natual coordinates of the subnode within the par...
int size_of_nodes() const
Number of nodes per element.
const NT & n
B2v_table _b2v_table
int size_of_subfaces() const
The total number of faces in the subdivision of the pane.
Edge_ID get_edge_id(const int face_lid, const int vertex_lid) const
Get the edge id within a given face.
std::vector< Node_ID > _subnode_counterparts
Ids of counterparts of subnodes.
std::vector< Three_tuple< Point_2S > > _subface_nat_coors
Element connectivity of the subfaces.
int size_of_nodes() const
Get the total number of nodes contained the window.
COM::Window Base
Pane_set _pane_set
The set of panes contained in the window.
j indices j
Definition: Indexing.h:6
const Real * coordinates() const
void get_host_element_of_subface(int i, Element_node_enumerator &ene) const
bool is_border_node(int i) const
Is a give node on the boundary of the pane?
std::vector< int > _subface_parents
Face ids of the parents of the subfaces.
std::vector< int > _subface_offsets
Offsets of first subfaces contained in a face.
V2b_table _v2b_table
An const adaptor for accessing nodal coordinates of a pane.
void next()
Go to the next element within the connectivity tables of a pane.
bool is_isolated_node(int i) const
Is a give node an isolated node not belong to any element?
void export_window(RFC_Window_base *) const
int size_of_primary_nodes() const
Get total number of primary nodes contained in the pane.
Bbox_3 get_bounding_box() const
Get the bounding box of the window.
std::vector< Point_2S > _subnode_nat_coors
Natual coordinates in the parent face.
int id() const
std::vector< int > B2v
From local boundary ids to node ids.
#define RFC_assertion
Definition: rfc_basic.h:65
std::vector< Face_ID > _subface_counterparts
Ids of counterparts of faces.
const Pane * pane() const
virtual ~RFC_Window_base()
Default destructor.
bool is_primary_node(const int vid) const
Is the node with given local id a primary one?