Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
smooth_mesquite_ng.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 #ifdef MESQUITE
24 #define USE_STD_INCLUDES 1
25 #define USE_C_PREFIX_INCLUDES 1
26 #include "Mesquite.hpp"
27 #include "MeshImpl.hpp"
28 #include "MesquiteError.hpp"
29 #include "InstructionQueue.hpp"
30 #include "MeshSet.hpp"
31 #include "TerminationCriterion.hpp"
32 #include "QualityAssessor.hpp"
33 #include "PlanarDomain.hpp"
34 #include "ShapeImprovementWrapper.hpp"
35 
36 // algorithms
37 #include "MeanRatioQualityMetric.hpp"
38 #include "EdgeLengthQualityMetric.hpp"
39 #include "LPtoPTemplate.hpp"
40 #include "FeasibleNewton.hpp"
41 #include "ConjugateGradient.hpp"
42 #include "MsqMessage.hpp"
43 #include "MesqPane.h"
44 
45 using namespace Mesquite;
46 #endif
47 
48 #include "Rocmop.h"
49 #include "roccom.h"
50 #include "Pane.h"
51 #include "Rocblas.h"
52 #include "Rocmap.h"
53 #include "Geometric_Metrics_3.h"
54 #include "Pane_connectivity.h"
55 #include "Pane_boundary.h"
56 #include "Pane_communicator.h"
57 
59 
60 using MAP::Rocmap;
61 
62 //FIXME, much of the information gathering can be moved to
63 // the smoother specific initialization routine.
64 void Rocmop::smooth_vol_mesq_ng(double initial_quality){
65  if(_verb)
66  std::cout << " Entering Rocmop::smooth_mesquite_ng" << std::endl;
67 
68  const std::string surf_attr("is_surface");
69  COM::Attribute* w_is_surface = _wrk_window->attribute(surf_attr);
70  COM_assertion_msg( w_is_surface, "Unexpected NULL pointer");
71 
72  // First Perform Element-based Laplacian smoothing on pane boundary volume nodes
73  // implemented as follows:
74 
75  // * this part should go into smoother_specific_init
76  // 0 Declare and resize variables and buffers
77  // 1 Loop through panes
78  // a. Find the set of shared nodes.
79  // b. Remove surface nodes from above set, "leaving submerged boundary nodes"
80  // c. Loop through all elements
81  // if(element contains submersed boundary nodes)
82  // increment submersed_boundary nodes' adj. element count
83  // add element center to each submersed_boundary nodes' new position
84 
85 
86  // 2 Sum reduction on nodal positions and adj. element counts
87  // 3 Divide new nodal positions by element counts
88 
89  // 0 Declare and resize data structures.
90  if(_verb > 2) std::cout << " Declaring Variables\n";
91 
92  // Allocate buffer space for new nodal positions
93  COM::Attribute *w_new_coords =
94  _wrk_window->new_attribute("new_coords", 'n', COM_DOUBLE, 3, "");
95  _wrk_window->resize_array(w_new_coords, 0);
96 
97  // Allocate buffer space for adjacent element counts
98  COM::Attribute *w_adj_elem_cnts =
99  _wrk_window->new_attribute("adj_elem_cnts", 'n', COM_DOUBLE, 1, "");
100  _wrk_window->resize_array(w_adj_elem_cnts, 0);
101  _wrk_window->init_done();
102 
103  // Allocate buffer space for safe distance
104  COM::Attribute *w_safe_dist =
105  _wrk_window->new_attribute("safe_dist", 'n', COM_DOUBLE, 1, "");
106  _wrk_window->resize_array(w_safe_dist, 0);
107  _wrk_window->init_done();
108 
109  // Allocate buffer space for backup coords
110  COM::Attribute *w_backup =
111  _wrk_window->new_attribute("backup", 'n', COM_DOUBLE, 3, "");
112  _wrk_window->resize_array(w_backup, 0);
113  _wrk_window->init_done();
114 
115  // Allocate buffer space for reset flags
116  COM::Attribute *w_reset =
117  _wrk_window->new_attribute("reset", 'n', COM_INT, 1, "");
118  _wrk_window->resize_array(w_reset, 0);
119  _wrk_window->init_done();
120 
121  // Initialize buffer spaces to zeroes.
122  double dzero = 0.;
123  double dlarge =99999999;
124  int izero = 0;
125  Rocblas::copy_scalar( &dzero, w_new_coords);
126  Rocblas::copy_scalar( &dzero, w_adj_elem_cnts);
127  Rocblas::copy_scalar( &dlarge, w_safe_dist);
128  Rocblas::copy_scalar( &izero, w_reset);
129 
130  //backup nodal coords.
131  Rocblas::copy( _wrk_window->attribute(COM::COM_NC), w_backup);
132 
133  // Get worst qualities, pre smoothing.
134 
135  // Get a list of local panes
136  std::vector<COM::Pane*> allpanes;
137  _wrk_window->panes(allpanes);
138  int total_npanes = (int)allpanes.size();
139 
140  // Allocate space for the set of submerged_boundary.
141  std::vector<std::vector<bool> > is_sub_bnd; // Is submerged boundary node?
142  std::vector<std::vector<bool> > is_pan_bnd; // Is pane boundary node?
143  is_sub_bnd.resize(total_npanes);
144  is_pan_bnd.resize(total_npanes);
145 
146  // Get attribute ids
147  int new_coords_id = w_new_coords->id();
148  int adj_elem_cnts_id = w_adj_elem_cnts->id();
149  int is_surface_id = w_is_surface->id();
150  int safe_dist_id = w_safe_dist->id();
151  int reset_id = w_reset->id();
152  int backup_id = w_backup->id();
153 
154  // get the pconn offset
155  int pconn_offset = MAP::Pane_connectivity::pconn_offset();
156 
157  // 1 Loop through panes
158 
159  if(_verb > 2) std::cout << " Step 1\n";
160  for(int i=0; i < total_npanes; ++i){
161  int size_of_real_nodes = allpanes[i]->size_of_real_nodes();
162  int size_of_real_elems = allpanes[i]->size_of_real_elements();
163  is_sub_bnd[i].resize(size_of_real_nodes,0);
164  is_pan_bnd[i].resize(size_of_real_nodes,0);
165 
166  std::vector<bool> is_isolated; // is a node isolated?
167  MAP::Pane_boundary pb (allpanes[i]);
168  pb.determine_border_nodes(is_pan_bnd[i], is_isolated);
169 
170  // a. Find the set of shared nodes.
171 
172  // get pane level pointers
173  COM::Attribute *p_is_surface = allpanes[i]->attribute(is_surface_id);
174  int *is_surface_ptr = (int*)p_is_surface->pointer();
175 
176  double * adj_elem_cnts_ptr = reinterpret_cast<double*>
177  (allpanes[i]->attribute(adj_elem_cnts_id)->pointer());
178 
179  double * safe_dist_ptr =
180  (double*)(allpanes[i]->attribute(safe_dist_id)->pointer());
181 
182  const Vector_3<double> *pnts = reinterpret_cast<Vector_3<double>*>
183  (allpanes[i]->attribute(COM_NC)->pointer());
184 
185  Vector_3<double> *new_coords_ptr = reinterpret_cast<Vector_3<double>*>
186  (allpanes[i]->attribute(new_coords_id)->pointer());
187 
188  // Obtain the pane connectivity of the local pane
189  const COM::Attribute *pconn = allpanes[i]->attribute(COM::COM_PCONN);
190  const int *vs = (const int*)pconn->pointer() + pconn_offset;
191  int vs_size = pconn->size_of_real_items() - pconn_offset;
192 
193  // Determine the number of communicating panes for shared nodes.
194  int count=0;
195  for (int j=0, nj=vs_size; j<nj; j+=vs[j+1]+2) {
196  if (_wrk_window->owner_rank( vs[j]) >=0) ++count;
197  }
198 
199  int index = 0;
200  // Loop through communicating panes for shared nodes.
201  for ( int j=0; j<count; ++j, index+=vs[index+1]+2) {
202  // We skip the panes that are not in the current window
203  while ( _wrk_window->owner_rank(vs[index])<0) {
204  index+=vs[index+1]+2;
205  COM_assertion_msg( index<=vs_size, "Invalid communication map");
206  }
207  // Mark node as shared
208  for(int k=0; k<vs[index+1]; ++k){
209  is_sub_bnd[i][vs[index+2+k]-1]=1;
210  }
211  }
212 
213  // b. Remove surface nodes from above set, leaving submerged boundary nodes
214  for (int j =0; j < size_of_real_nodes; ++j){
215  if(is_surface_ptr[j])
216  is_sub_bnd[i][j] = 0;
217  }
218 
219  // c. Loop through all elements
220  // if(element contains submersed boundary nodes)
221  // increment submersed_boundary nodes' adj. element count
222  // add element center to each submersed_boundary nodes' new position
223  Element_node_enumerator ene(allpanes[i],1);
224  for(int j =0; j < size_of_real_elems; ++j, ene.next()){
225  // Collect element indices of submerged boundary nodes.
226  int nn = ene.size_of_nodes(), flag = 0;
227  for(int k =0; k < nn; ++k){
228  if(is_sub_bnd[i][ene[k]-1]){
229  flag = 1;
230  adj_elem_cnts_ptr[ene[k]-1] += 1.0;
231  }
232  }
233  // If the element contains submerged boundary nodes
234  if(flag!=0){
235  // Calculate the element's center
236  Vector_3<double> elem_cntr_pos(0.0,0.0,0.0);
237  for(int k =0; k < nn; ++k){
238  elem_cntr_pos += pnts[ene[k]-1];
239  }
240  elem_cntr_pos /= (double)nn;
241  // Add the center position to the accumulating new positions
242  // of the constituent submerged boundary nodes.
243  // And update safe distance if needed
244  for(int k =0; k < nn; ++k){
245  if(is_sub_bnd[i][ene[k]-1]){
246  // initialize safe distance with distance to center
247  double local_safe_dist = (pnts[ene[k]-1] - elem_cntr_pos).norm();
248  int long_src = -1;
249  double long_dist = -1.0;
250  // replace safe distance with .5 shortest adj. edge length
251  // if less than distance to center.
252  int safe_source = -1;
253  for(int ii=1; ii<nn; ++ii){
254  double cur_edge_dist =
255  .5*(pnts[ene[k]-1] - pnts[ene[(k+ii)%nn]-1]).norm();
256  if(cur_edge_dist < local_safe_dist){
257  safe_source = ii;
258  local_safe_dist = cur_edge_dist;
259  }
260  if(cur_edge_dist > long_dist){
261  long_dist = cur_edge_dist;
262  long_src = ii;
263  }
264  }
265  new_coords_ptr[ene[k]-1] += elem_cntr_pos;
266 #if 0
267  if(safe_source == -1)
268  new_coords_ptr[ene[k]-1] += elem_cntr_pos;
269  else {
270  Vector_3<double> direction =
271  (pnts[ene[(k+long_src)%nn]-1] - pnts[ene[k]-1]);
272  direction.normalize();
273  new_coords_ptr[ene[k]-1] += pnts[ene[k]-1];
274  new_coords_ptr[ene[k]-1] += direction*local_safe_dist;
275  //new_coords_ptr[ene[k]-1] -= pnts[ene[(k+safe_source)%nn]-1];
276  }
277 #endif
278  if(local_safe_dist < safe_dist_ptr[ene[k]-1])
279  safe_dist_ptr[ene[k]-1] = local_safe_dist;
280  }
281  }
282  }
283  }
284  }
285 
286  // 2 Sum reduction on nodal positions and adj. element counts
287  if(_verb > 1) std::cout << " Step 2\n";
288  reduce_sum_on_shared_nodes(w_new_coords);
289  reduce_sum_on_shared_nodes(w_adj_elem_cnts);
290  if(COMMPI_Initialized()){
291  MAP::Pane_communicator pc(_wrk_window, _wrk_window->get_communicator());
292  pc.init(w_safe_dist);
293  pc.begin_update_shared_nodes();
294  pc.reduce_on_shared_nodes(MPI_MIN);
295  pc.end_update_shared_nodes();
296  }
297 
298  // 3 Divide new nodal positions by element counts
299  if(_verb > 1) std::cout << " Step 3\n";
300  Rocblas::div(w_new_coords, w_adj_elem_cnts, w_new_coords);
301 
302  //std::string msg("\n I submerged quality = ");
303  //print_mquality(msg, is_sub_bnd);
304  //msg = " I pane boundary quality = ";
305  //print_mquality(msg, is_pan_bnd);
306 
307  std::vector<std::vector<bool> > elem_to_check;
308  mark_elems_from_nodes(is_sub_bnd, elem_to_check);
309 
310  // get min,max angles for later use
311  double max_angle = 0.0;
312  double min_angle = 180.0;
313  double angles[] = {0.0, 0.0};
314  for(int i=0,ni = allpanes.size(); i<ni; ++i){
315  for(int k =0,nk = elem_to_check[i].size(); k<nk; ++k){
316  if(elem_to_check[i][k]){
317  Element_node_enumerator ene(allpanes[i],k+1);
318  Angle_Metric_3 am;
319  am.initialize(ene);
320  am.compute(angles);
321  if(angles[1]>max_angle)
322  max_angle = angles[1];
323  if(angles[0]<min_angle)
324  min_angle = angles[0];
325  }
326  }
327  }
328  int rank =0;
329  double temp = min_angle;
330  if(COMMPI_Initialized()){
331  agree_double(max_angle,MPI_MAX);
332  agree_double(min_angle,MPI_MIN);
333  int ierr = MPI_Comm_rank( _wrk_window->get_communicator()
334  , &rank);
335  assert( ierr == 0);
336  }
337 
338  if(_verb > 1) std::cout << " Step 4\n";
339  // 4 Copy new nodal coords into mesh for submerged boundary nodes
340 
341  for(int i=0; i < total_npanes; ++i){
342 
343  // get pane level attributes
344  Vector_3<double>* new_coords_ptr =
345  reinterpret_cast<Vector_3<double>* >(allpanes[i]->
346  attribute(new_coords_id)->
347  pointer());
348  Vector_3<double>* coords_ptr =
349  reinterpret_cast<Vector_3<double>* >(allpanes[i]->
350  attribute(COM::COM_NC)
351  ->pointer());
352 
353  double* safe_dist_ptr =
354  (double*)(allpanes[i]->attribute(safe_dist_id)->pointer());
355 
356  for (int j = 0, nj = allpanes[i]->size_of_real_nodes(); j<nj; ++j){
357  if(is_sub_bnd[i][j]){
358  Vector_3<double> direction =
359  new_coords_ptr[j] - coords_ptr[j];
360  double dist = direction.norm();
361  if (dist > safe_dist_ptr[j]){
362  double alpha = .9*safe_dist_ptr[j]/dist;
363  coords_ptr[j] =
364  alpha*new_coords_ptr[j] +(1.0-alpha)*coords_ptr[j];
365  }
366  else{
367  coords_ptr[j] = .5*new_coords_ptr[j] +.5*coords_ptr[j];
368  }
369  }
370  }
371  }
372  //msg = ("\n L submerged quality = ");
373  //print_mquality(msg, is_sub_bnd);
374  //msg = " L pane boundary quality = ";
375  //print_mquality(msg, is_pan_bnd);
376  //msg = " L overall quality = ";
377  //print_quality(msg);
378 
379  // Decide which positions to reset
380  for(int i=0; i < total_npanes; ++i){
381 
382  int* reset_ptr =
383  (int*)(allpanes[i]->attribute(reset_id)->pointer());
384 
385  for(int k =0,nk = elem_to_check[i].size(); k<nk; ++k){
386  if(elem_to_check[i][k]){
387  double angles[] = {0.0, 0.0};
388 
389  Element_node_enumerator ene(allpanes[i],k+1);
390  Angle_Metric_3 am;
391  am.initialize(ene);
392  am.compute(angles);
393  if(angles[1]>max_angle ||
394  angles[0]<min_angle){
395  std::vector<int> nodes;
396  ene.get_nodes(nodes);
397  for(int j =0, nj=nodes.size(); j<nj; ++j){
398  if (is_sub_bnd[i][nodes[j]-1])
399  reset_ptr[nodes[j]-1] = 1;
400  }
401  }
402  }
403  }
404  }
405 
406  // All nodes being moved are shared, so this should be valid
408 
409  for(int i=0; i < total_npanes; ++i){
410 
411  // get pane level attributes
412  Vector_3<double>* backup_ptr =
413  reinterpret_cast<Vector_3<double>* >(allpanes[i]->
414  attribute(backup_id)->
415  pointer());
416  Vector_3<double>* coords_ptr =
417  reinterpret_cast<Vector_3<double>* >(allpanes[i]->
418  attribute(COM::COM_NC)
419  ->pointer());
420 
421  int* reset_ptr =
422  (int*)(allpanes[i]->attribute(reset_id)->pointer());
423 
424  for(int j=0, nj = allpanes[i]->size_of_real_nodes(); j<nj; ++j){
425  if(reset_ptr[j])
426  coords_ptr[j] = backup_ptr[j];
427  }
428  }
429 
430  //msg = ("\n R submerged quality = ");
431  //print_mquality(msg, is_sub_bnd);
432  //msg = " R pane boundary quality = ";
433  //print_mquality(msg, is_pan_bnd);
434  //msg = " R overall quality = ";
435  //print_quality(msg);
436 
437  // Smooth using mesquite.
438  smooth_mesquite(allpanes,0);
439 
440  //msg = "\n M submerged quality = ";
441  //print_mquality(msg, is_sub_bnd);
442  // msg = " M pane boundary quality = ";
443  //print_mquality(msg, is_pan_bnd);
444  //msg = " M overall quality = ";
445  //print_quality(msg);
446 
447  //Deallocate buffer space
448  _wrk_window->delete_attribute( w_adj_elem_cnts->name());
449  _wrk_window->delete_attribute( w_new_coords->name());
450  _wrk_window->init_done();
451 
452  if(_verb > 1)
453  std::cout << " Exiting Rocmop::smooth_mesquite_ng" << std::endl;
454 }
455 
457 struct Four_tuple {
458  Four_tuple( int a, int b, int c, int d)
459  : _a(a), _b(b), _c(c), _d(d) {}
460  int &operator[](int i) { return (&_a)[i]; }
461  const int &operator[](int i) const { return (&_a)[i]; }
462  bool operator<( const Four_tuple &x) const {
463  return _a<x._a || (_a==x._a && (_b<x._b || _b==x._b &&
464  (_c<x._c || _c==x._c && _d<x._d)));
465  }
466 private:
467  int _a, _b, _c, _d;
468 };
469 
470 typedef std::map< Four_tuple, MAP::Facet_ID> Corners2Face_Map;
471 typedef std::map< int, int> Id_Map;
472 
473 void Rocmop::determine_physical_border(COM::Attribute* w_is_surface){
474  COM_assertion_msg( w_is_surface, "Unexpected NULL pointer");
475  COM_assertion_msg( COM_compatible_types( w_is_surface->data_type(), COM_INT),
476  "Surface-list must have integer type");
477  COM_assertion_msg( w_is_surface->is_nodal() == 1,
478  "Surface-list must be nodal");
479  COM_assertion_msg( w_is_surface->size_of_components() == 1,
480  "Surface-list must have a single component");
481  int w_is_surface_id = w_is_surface->id();
482 
483  // This function is implemented as follows:
484  // 0 Declare and resize data structures.
485  //
486  // Loop through panes
487  // 1 Get the pane boundary nodes and faces using Rocmap::Pane_boundary
488  // 2 Identify adjacent panes, and shared nodes. Also, create an id mappings
489  // from a node's id to its index in the shared node array and vice versa.
490  // 3 Identify "possibly shared faces", those faces whose nodes are all
491  // shared with the same adjacent pane. Make a list of these faces.
492  // 4 Communicate the size of the local face list to send to / recieve from
493  // adjacent panes.
494  // 5 Create buffers for the incoming face list and communicate faces lists.
495  // 6 For every face received, remove any matching faces in the list of
496  // boundary faces.
497  // 7 Mark all nodes still contained in boundary faces as physical boundary
498  // nodes.
499 
500 
501  // 0 Declare and resize data structures.
502 
503  // vector corresponds to adjacent panes (reused amongst local panes)
504  std::vector<bool> is_border; // is a node a border node?
505  std::vector<bool> is_shared; // is a node a shared node?
506  std::vector<bool> is_isolated; // is a node isolated?
507  std::vector<MAP::Facet_ID> border_facet_list;
508 
509  // Space in which false pconns are built. (reused amongs local panes)
510  // outside vectors correspond to adjacent panes
511  // inside vectors correspond to connectivity information
512  //std::vector<std::vector<int> > false_pconn;
513 
514  // Per-local-pane data structures
515  // outside vectors correspond to the local panes
516  // inside vectors correspond to adjacent panes
517  std::vector<std::set<MAP::Facet_ID> > border_facets; // List of all border faces.
518  std::vector<std::vector<Corners2Face_Map> > maybe_shared; // Possibly shared facets
519  std::vector<std::vector<Id_Map > > lid2ind; // map from local id to pconn index
520  std::vector<std::vector<Id_Map > > ind2lid; // map from pconn index to local id
521  std::vector<std::vector<std::set<int> > > adj_pane_set; // nodes shared with adjacent panes
522  std::vector<std::vector<int> > adj_pane_id; // ids of adjacent panes
523  std::vector<std::vector<int> > adj_pane_recv; // amount of data coming from adjacent panes.
524 
525  // The amount of data to be sent by each pane
526  std::vector<int> send_sizes;
527 
528  std::set<MAP::Facet_ID>::iterator bf_it, bf_it2;
529  Id_Map::iterator idm_it,idm_it2; // iterator for lid2ind or ind2lid
530  Corners2Face_Map::iterator ms_it,ms_it2;
531  std::set<int >::iterator aps_it, aps_it2; //iterator for adj_pane_map
532 
533  // get the pconn offset
534  int pconn_offset = MAP::Pane_connectivity::pconn_offset();
535 
536  // Resize per-local-pane data structures
537  std::vector<COM::Pane*> allpanes;
538  COM::Window * wrk_window = w_is_surface->window();
539  wrk_window->panes(allpanes);
540  int total_npanes = (int)allpanes.size();
541  border_facets.resize(total_npanes);
542  maybe_shared.resize(total_npanes);
543  lid2ind.resize(total_npanes);
544  ind2lid.resize(total_npanes);
545  adj_pane_set.resize(total_npanes);
546  adj_pane_id.resize(total_npanes);
547  adj_pane_recv.resize(total_npanes);
548  send_sizes.resize(total_npanes);
549 
550  // Register an attribute for our fake pconn.
551  COM::Attribute * false_pconn = wrk_window->new_attribute("false_pconn", 'p', COM_INT, 1, "");
552 
553  // Register an attribute for sending and receiving sizes
554  // also used for sending buffer
555  COM::Attribute *com_buff = wrk_window->new_attribute("com_buff", 'p', COM_INT, 1,"");
556  int w_com_buff_id = com_buff->id();
557 
558  // Loop through panes
559  for(int i=0; i<total_npanes; ++i){
560  int size_of_real_nodes = allpanes[i]->size_of_real_nodes();
561  is_border.clear();
562  is_shared.clear();
563  is_isolated.clear();
564  is_border.resize(size_of_real_nodes,0);
565  is_shared.resize(size_of_real_nodes,0);
566  is_isolated.resize(size_of_real_nodes,0);
567  send_sizes[i] = 0;
568 
569  // 1 Get the pane boundary nodes and faces using Rocmap::Pane_boundary
570  // Determine the border nodes.
571  MAP::Pane_boundary pb(allpanes[i]);
572  pb.determine_border_nodes(is_border, is_isolated, &border_facet_list);
573 
574  // put the list of border facets into a set for faster searching
575  for(int j =0, nj=border_facet_list.size(); j<nj; ++j)
576  border_facets[i].insert(border_facet_list[j]);
577 
578  // 2 Identify adjacent panes, and shared nodes. Also, create an id mappings
579  // from a node's id to its index in the shared node array and vice versa.
580 
581  // Obtain the pane connectivity of the local pane
582  const COM::Attribute *pconn = allpanes[i]->attribute(COM::COM_PCONN);
583  const int *vs = (const int*)pconn->pointer() + pconn_offset;
584  int vs_size = pconn->size_of_real_items() - pconn_offset;
585 
586  // Determine the number of communicating panes for shared nodes.
587  int count=0;
588  for (int j=0, nj=vs_size; j<nj; j+=vs[j+1]+2) {
589  if (wrk_window->owner_rank( vs[j]) >=0) ++count;
590  }
591 
592  // Resize per-adjacent-pane data structures
593  //false_pconn.resize(count);
594  maybe_shared[i].resize(count);
595  lid2ind[i].resize(count);
596  ind2lid[i].resize(count);
597  adj_pane_set[i].resize(count);
598  adj_pane_id[i].resize(count);
599  adj_pane_recv[i].resize(count);
600 
601  int index = 0;
602  // Loop through communicating panes for shared nodes.
603  for ( int j=0; j<count; ++j, index+=vs[index+1]+2) {
604  // We skip the panes that are not in the current window
605  while ( wrk_window->owner_rank(vs[index])<0) {
606  index+=vs[index+1]+2;
607  COM_assertion_msg( index<=vs_size, "Invalid communication map");
608  }
609  adj_pane_id[i][j] = vs[index];
610  // Add this pane to current shared node's list, mark node as shared and
611  // keep track of the mapping between array index and local node id
612  for(int k=0; k<vs[index+1]; ++k){
613  is_shared[vs[index+2+k]-1]=1;
614  adj_pane_set[i][j].insert(vs[index+2+k]);
615  lid2ind[i][j].insert(std::make_pair(vs[index+2+k],k));
616  ind2lid[i][j].insert(std::make_pair(k,vs[index+2+k]));
617  }
618  }
619 #if 0
620 
621  std::cout << "Pane " << allpanes[i]->id() << " lid2ind = \n";
622  for(int j=0; j < count; ++j){
623  std::cout << " to Pane " << adj_pane_id[i][j] << " =\n";
624  for(int k =0; k < ind2lid[i][j].size();++k){
625  std::cout << "(" << k << "," << ind2lid[i][j][k] << ") ";
626  }
627  std::cout << "\n";
628  }
629  std::cout << "Pane " << i << "\n"
630  << " shared nodes = \n";
631 
632  for(int j=0; j<is_shared.size(); ++j){
633  if(is_shared[j])
634  std::cout << j+1 << " ";
635  }
636  std::cout << "\n\n nodes shared with othe panes";
637 
638  aps_it = adj_pane_set[i][0].begin();
639  for(; aps_it != adj_pane_set[i][0].end(); ++aps_it){
640  std::cout << *aps_it << " ";
641  }
642 
643 #endif
644 
645  // 3 Identify "possibly shared faces", those faces whose nodes are all
646  // shared with the same adjacent pane. Make a list of these faces.
647 
648  bf_it2 = border_facets[i].end();
649  bf_it = border_facets[i].begin();
650  //for(int j=0, nj=border_facets[i].size(); j<nj; ++j){
651  for(; bf_it != bf_it2; ++bf_it){
652  Element_node_enumerator ene(allpanes[i], (*bf_it).eid());
653  Facet_node_enumerator fne (&ene, (*bf_it).lid());
654  //if all the nodes are shared
655  if( is_shared[fne[0]-1] &&
656  is_shared[fne[1]-1] &&
657  is_shared[fne[2]-1] &&
658  fne.size_of_edges()>3?is_shared[fne[3]-1]:1
659  ){
660  // then see if they are all shared by the same panes
661  Four_tuple ns( fne[0], fne[1], fne[2], fne.size_of_edges()>3?fne[3]:-1);
662  for(int k=0; k<count; ++k){
663  aps_it2 = adj_pane_set[i][k].end();
664  if(aps_it2 != adj_pane_set[i][k].find(fne[0]) &&
665  aps_it2 != adj_pane_set[i][k].find(fne[1]) &&
666  aps_it2 != adj_pane_set[i][k].find(fne[2]) &&
667  (fne.size_of_edges()>3?(adj_pane_set[i][k].find(fne[3]) != aps_it2):1)){
668  // and if they are
669  // then this facet is possibly shared with the adjacent node
670  Four_tuple ns( fne[0], fne[1], fne[2], fne.size_of_edges()>3?fne[3]:-1);
671  std::sort(&ns[0],&ns[4]);
672  maybe_shared[i][k].insert(std::make_pair(ns,(*bf_it)));
673  }
674  }
675  }
676  }
677 
678 #if 0
679  // print out the list of possibly shared nodes:
680  std::cout << "Pane " << allpanes[i]->id() << " possibly shared panes\n";
681  for(int j = 0; j<count; ++j){
682  std::cout << " faces possibly shared with Pane " << adj_pane_id[i][j] << "\n";
683  ms_it2 = maybe_shared[i][j].end();
684  for(ms_it = maybe_shared[i][j].begin(); ms_it != ms_it2; ++ms_it){
685  std::cout << "(" << (ms_it->first)[0] << " "
686  << (ms_it->first)[1] << " "
687  << (ms_it->first)[2] << " "
688  << (ms_it->first)[3] << ") ";
689  }
690  std::cout << "\n";
691  }
692 #endif
693 
694  wrk_window->set_size("com_buff", allpanes[i]->id(), count, 0);
695  int* my_buff;
696  wrk_window->resize_array("com_buff", (const int)allpanes[i]->id(),
697  reinterpret_cast<void**>(&my_buff));
698 
699  // find the size of the pconn to create
700  // 3*(pconn_offset) // number of communicating blocks
701  // + 3 // shared node block
702  // + 6*count // (pane id,node count,array-id for each adj. pane)*2blocks
703 
704  int my_size = 3*pconn_offset + 3 + 6*count;
705  int* my_pconn;
706  wrk_window->set_size("false_pconn", allpanes[i]->id(), my_size,
707  my_size-(3+pconn_offset));
708  wrk_window->resize_array("false_pconn", (const int)allpanes[i]->id(),
709  reinterpret_cast<void**>(&my_pconn));
710  // Add shared node data
711  if(pconn_offset){my_pconn[0]=1;++my_pconn;}
712  my_pconn[0]=1; my_pconn[1]=1; my_pconn[2]=1;
713  my_pconn += 3;
714 
715  // filling in send buffer and real nodes to send info.
716  if(pconn_offset){my_pconn[0]=count;++my_pconn;}
717  for(int j=0; j<count; ++j){
718  // print communicating pane id
719  my_pconn[0] = adj_pane_id[i][j];
720  // print number of ints to communicate
721  my_pconn[1] = 1;
722  // print index-id of information
723  my_pconn[2] = j+1;
724  my_pconn+=3;
725  // store size of information to send
726  my_buff[j] = 4*maybe_shared[i][j].size();
727  send_sizes[i] += my_buff[j];
728  }
729 
730  // add ghost nodes to receive info.
731  if(pconn_offset){my_pconn[0]=count;++my_pconn;}
732  for(int j=0; j<count; ++j){
733  my_pconn[0] = adj_pane_id[i][j];
734  my_pconn[1] = 1;
735  my_pconn[2] = j+1;
736  my_pconn+=3;
737  }
738 
739 #if 0
740  for ( int j=0; j<count; ++j, index+=vs[index+1]+2) {
741  // We skip the panes that are not in the current window
742  while ( wrk_window->owner_rank(vs[index])<0)
743  index+=vs[index+1]+2;
744  // List the communicating pane, 1 item to send, and the index of that item in a
745  // local panel array
746  my_pconn[3*j] = vs[index];
747  my_pconn[3*j+1] = 1;
748  my_pconn[3*j+2] = j+1;
749 
750  my_pconn[3*(count+j)+pconn_offset] = vs[index];
751  my_pconn[3*(count+j)+1+pconn_offset] = 1;
752  my_pconn[3*(count+j)+2+pconn_offset] = j+1;
753 
754  my_pconn[3*(2*count+j)+2*pconn_offset] = vs[index];
755  my_pconn[3*(2*count+j)+1+2*pconn_offset] = 1;
756  my_pconn[3*(2*count+j)+2+2*pconn_offset] = j+1;
757 
758 
759  // store the size of the buffer to send across
760  my_buff[j] = 4*maybe_shared[i][j].size();
761  send_sizes[i] += my_buff[j];
762  }
763 #endif
764 #if 0
765  std::cout << "pconn_offset = " << pconn_offset << "\n";
766  std::cout << "total size = " << my_size << "\n";
767  std::cout << "ghost sized = " << my_size - pconn_offset << "\n\n";
768 #endif
769  }
770  wrk_window->init_done();
771 
772 #if 0
773  //print out pconn, for debugging.
774  for(int i=0; i<total_npanes; ++i){
775  std::cout << "FALSE pconn for pane " << allpanes[i]->id() << std::endl;
776  COM::Attribute *my_pconn = allpanes[i]->attribute(w_false_pconn_id);
777  int* ptr = (int*)my_pconn->pointer();
778  for(int k=0,nk=my_pconn->size_of_items();k<nk;++k){
779  std::cout << ptr[k] << " ";
780  }
781  std::cout << "\n\n";
782 
783  // print out size of buffer being sent across
784  std::cout << "size of face list\n";
785  COM::Attribute *my_bsize = allpanes[i]->attribute(w_com_buff_id);
786  ptr = (int*)my_bsize->pointer();
787  for(int j =0; j<my_bsize->size_of_items(); ++j)
788  std::cout << ptr[j] << " ";
789  std::cout << "\n\n";
790  }
791 #endif
792 
793  // 4 Communicate the size of the local face list to send to / recieve from
794  // adjacent panes.Pane_connectivity::
795  Rocmap::update_ghosts(com_buff,
796  false_pconn);
797 
798  //print out pconn, for debugging.
799 #if 0
800  for(int i=0; i<total_npanes; ++i){
801  COM::Attribute *my_pconn = allpanes[i]->attribute(w_false_pconn_id);
802  int* ptr = (int*)my_pconn->pointer();
803  for(int k=0,nk=my_pconn->size_of_items();k<nk;++k){
804  std::cout << ptr[k] << " ";
805  }
806  std::cout << "\n\n";
807  // print out possibly shared faces
808  std::cout << "possibly shared faces\n";
809  for(ms_it = maybe_shared[i][0].begin(), ms_it2 = maybe_shared[i][0].end();
810  ms_it != ms_it2; ++ms_it){
811  std::cout << "("
812  << (ms_it->first)[0] << " "
813  << (ms_it->first)[1] << " "
814  << (ms_it->first)[2] << " "
815  << (ms_it->first)[3] << ") ";
816  }
817  std::cout << "\n\n";
818  // print out size of buffer being sent across
819  std::cout << "size of communicated face list\n";
820  COM::Attribute *my_bsize = allpanes[i]->attribute(w_com_buff_id);
821  ptr = (int*)my_bsize->pointer();
822  for(int j =0; j <adj_pane_id[i].size(); ++j)
823  std::cout << ptr[j] << " ";
824  std::cout << "\n\n";
825  }
826 #endif
827 
828  // 5 Create buffers for the incoming face list and communicate faces lists.
829  // loop through panes
830  for(int i=0; i<total_npanes; ++i){
831 
832  // get pane level attributes and pointers
833  COM::Attribute *p_com_buff = allpanes[i]->attribute(w_com_buff_id);
834  int *com_buff_ptr = (int*)p_com_buff->pointer();
835 
836  // find the number of adjacent panes
837  int count = adj_pane_id[i].size();
838 
839  // find the size of data to be received and sent.
840  int recv_size = 0;
841  // add up the sizes of all the buffers being sent
842  for(int j=0; j< count; ++j){
843  recv_size += com_buff_ptr[j];
844  adj_pane_recv[i][j] = com_buff_ptr[j];
845  }
846  int send_size = send_sizes[i];
847 
848  // find the size of the pconn to create
849  // 3*(pconn_offset) // number of communicating blocks
850  // + 3 // shared node block
851  // + 4*count // (pane id and node count for each adj. pane)*2blocks
852  // + recv_size+send_size // number of nodes in facet lists
853  int pconn_size = 3*(pconn_offset)+3+4*count+recv_size+send_size;
854 
855 #if 0
856 
857  std::cout << " SIZES\nrecv_size = " << recv_size << " send_size = " << send_size
858  << " pconn size = " << pconn_size << "\n"
859  << " 3*pconn_offset = " << 3*pconn_offset
860  << " 4*count = " << 4*count << "\n\n";
861 
862 #endif
863 
864  wrk_window->set_size("com_buff", allpanes[i]->id(),std::max(send_size,recv_size),0);
865  wrk_window->resize_array("com_buff", (const int)allpanes[i]->id(),
866  reinterpret_cast<void**>(&com_buff_ptr));
867  int* pconn_ptr;
868  wrk_window->set_size("false_pconn", allpanes[i]->id(), pconn_size,
869  pconn_size - (3+pconn_offset));
870  wrk_window->resize_array("false_pconn", (const int)allpanes[i]->id(),
871  reinterpret_cast<void**>(&pconn_ptr));
872 
873  // add shared node data
874  if(pconn_offset){pconn_ptr[0]=1;++pconn_ptr;}
875  pconn_ptr[0]=1; pconn_ptr[1]=1; pconn_ptr[2]=1;
876  pconn_ptr += 3;
877 
878  // now fill in the send buffer and real nodes to send info. in the pconn
879  if(pconn_offset){pconn_ptr[0]=count;++pconn_ptr;}
880  int com_ind = 0; // index of next place in com_buff
881  for(int j =0; j<count; ++j){
882  pconn_ptr[0]=adj_pane_id[i][j];
883  pconn_ptr[1]=4*maybe_shared[i][j].size();
884  pconn_ptr+=2;
885  ms_it2 = maybe_shared[i][j].end();
886  for(ms_it = maybe_shared[i][j].begin(); ms_it != ms_it2;
887  ++ms_it, com_ind+=4, pconn_ptr+=4){
888  // Convert nodal id's to pconn based index id's and place in the comm buffer
889  const Four_tuple* ft = &(ms_it->first);
890  if ((*ft)[0]==-1)
891  com_buff_ptr[com_ind] = -1;
892  else
893  idm_it = lid2ind[i][j].find((*ft)[0]);
894  idm_it = lid2ind[i][j].find((*ft)[1]);
895  com_buff_ptr[com_ind+1] = idm_it->second;
896  idm_it = lid2ind[i][j].find((*ft)[2]);
897  com_buff_ptr[com_ind+2] = idm_it->second;
898  idm_it = lid2ind[i][j].find((*ft)[3]);
899  com_buff_ptr[com_ind+3] = idm_it->second;
900  std::sort(&com_buff_ptr[com_ind],&com_buff_ptr[com_ind+4]);
901  // Also fill in the pconn
902  pconn_ptr[0] = com_ind+1;
903  pconn_ptr[1] = com_ind+2;
904  pconn_ptr[2] = com_ind+3;
905  pconn_ptr[3] = com_ind+4;
906  }
907  }
908 
909  // now fill in the ghost nodes to receive info. in the pconn
910  if(pconn_offset){pconn_ptr[0]=count;++pconn_ptr;}
911  com_ind = 1;
912  for(int j=0; j<count; ++j){
913  pconn_ptr[0]=adj_pane_id[i][j];
914  pconn_ptr[1]=adj_pane_recv[i][j];
915  for(int k=0; k<adj_pane_recv[i][j]; ++k){
916  pconn_ptr[k+2] = k+com_ind;
917  }
918  com_ind += adj_pane_recv[i][j];
919  pconn_ptr += 2+adj_pane_recv[i][j];
920  }
921  }
922 
923 #if 0
924  //print out pconn, for debugging.
925  for(int i=0; i<total_npanes; ++i){
926  std::cout << "Facet list FALSE pconn for pane " << allpanes[i]->id() << std::endl;
927  COM::Attribute *my_pconn = allpanes[i]->attribute(w_false_pconn_id);
928  int* ptr = (int*)my_pconn->pointer();
929  for(int k=0,nk=my_pconn->size_of_items();k<nk;++k){
930  std::cout << ptr[k] << " ";
931  }
932  std::cout << "\n\n";
933 
934  std::cout << "Facet list buffer for pane " << allpanes[i]->id() << std::endl;
935  COM::Attribute *my_buff = allpanes[i]->attribute(w_com_buff_id);
936  ptr = (int*)my_buff->pointer();
937  for(int k=0,nk=my_buff->size_of_items();k<nk;++k){
938  std::cout << ptr[k] << " ";
939  }
940  std::cout << "\n\n";
941  }
942 #endif
943 
944  // update
945  Rocmap::update_ghosts(com_buff,
946  false_pconn);
947 
948 #if 0
949  //print out pconn, for debugging.
950  for(int i=0; i<total_npanes; ++i){
951  std::cout << "Updated Facet list buffer for pane " << allpanes[i]->id() << std::endl;
952  COM::Attribute *my_buff = allpanes[i]->attribute(w_com_buff_id);
953  int* ptr = (int*)my_buff->pointer();
954  for(int k=0,nk=my_buff->size_of_items();k<nk;++k){
955  std::cout << ptr[k] << " ";
956  }
957  std::cout << "\n\n";
958  }
959 #endif
960  // 6 For every face received, remove any matching faces in the list of
961  // boundary faces.
962  // loop through all panes
963  for(int i =0; i<total_npanes; ++i){
964  COM::Attribute *my_buff = allpanes[i]->attribute(w_com_buff_id);
965  int* buff_ptr = (int*)my_buff->pointer();
966 
967  int count = adj_pane_recv[i].size();
968  // loop through adjacent panes
969  //std::cout << "Pane " << allpanes[i]->id() << "\n";
970  for(int j=0;j<count; buff_ptr += adj_pane_recv[i][j], ++j){
971 
972  //std::cout << "Converting node array\n";
973  // convert all node array indices to local id
974  //std::cout << adj_pane_recv[i][j] << " items being converted\n";
975  for(int k=0, nk =adj_pane_recv[i][j]; k<nk; ++k){
976  if(buff_ptr[k]!=-1){
977  buff_ptr[k] = ind2lid[i][j][buff_ptr[k]];
978  }
979  }
980  // std::cout << "Checking for matching facets with pane" << adj_pane_id[i][j] << "\n";
981  // check for matching facets
982  ms_it2 = maybe_shared[i][j].end();
983  bf_it2 = border_facets[i].end();
984  for(int k=0, nk=adj_pane_recv[i][j]; k<nk; k+=4){
985  Four_tuple ns(buff_ptr[k],buff_ptr[k+1],buff_ptr[k+2],buff_ptr[k+3]);
986  std::sort(&ns[0],&ns[4]);
987  //std::cout << " (" << ns[0] << " " << ns[1] << " " << ns[2] << " " << ns[3] << ") ";
988  ms_it = maybe_shared[i][j].find(ns);
989  if(ms_it != ms_it2){
990  //std::cout << "found ";
991  Element_node_enumerator ene(allpanes[i], (ms_it->second).eid());
992  Facet_node_enumerator fne (&ene, (ms_it->second).lid());
993  //std::cout << "(" << fne[0] << " " << fne[1]
994  // << " " << fne[2];
995  // if(fne.size_of_edges()>3)
996  // std::cout << " " << fne[3];
997  //std::cout << ")\n";
998  MAP::Facet_ID fid = ms_it->second;
999  bf_it = border_facets[i].find(fid);
1000  if(bf_it != bf_it2)
1001  border_facets[i].erase(fid);
1002  }
1003  else
1004  ;
1005  //std::cout << "not found\n";
1006  }
1007  }
1008  }
1009 
1010  // std::cout << "On to step 7 \n";
1011 
1012  // 7 Mark all nodes still contained in boundary faces as physical boundary
1013  // nodes.
1014  for(int i =0; i < total_npanes; ++i){
1015  // std::cout << "Pane " << i << " detected surface faces\n";
1016  bf_it2 = border_facets[i].end();
1017  for(bf_it = border_facets[i].begin(); bf_it!= bf_it2; ++bf_it){
1018  Element_node_enumerator ene(allpanes[i], (*bf_it).eid());
1019  Facet_node_enumerator fne (&ene, (*bf_it).lid());
1020 
1021  //std::cout << "(" << fne[0] << " " << fne[1]
1022  // << " " << fne[2];
1023  // if(fne.size_of_edges()>3)
1024  // std::cout << " " << fne[3];
1025  //std::cout << ")";
1026  }
1027  //std::cout << "\n\n";
1028  }
1029 
1030  for(int i = 0; i < total_npanes; ++i){
1031  COM::Attribute *p_is_surface = allpanes[i]->attribute(w_is_surface_id);
1032  int* surf_ptr = (int*)p_is_surface->pointer();
1033  // initialize surface to 0s
1034  for(int j=0, nj= p_is_surface->size_of_items();j<nj; ++j){
1035  surf_ptr[j] = 0;
1036  }
1037  bf_it2 = border_facets[i].end();
1038  //std::cout << "Pane " << allpanes[i]->id() << " marking surface nodes\n";
1039  for(bf_it = border_facets[i].begin(); bf_it!= bf_it2; ++bf_it){
1040  Element_node_enumerator ene(allpanes[i], (*bf_it).eid());
1041  Facet_node_enumerator fne (&ene, (*bf_it).lid());
1042  surf_ptr[fne[0]-1] = 1;
1043  surf_ptr[fne[1]-1] = 1;
1044  surf_ptr[fne[2]-1] = 1;
1045  //std::cout << fne[0] << " " << fne[1] << " " << fne[2] << "\n";
1046  if(fne.size_of_edges()>3)
1047  surf_ptr[fne[3]-1] = 1;
1048  }
1049  // std::cout << "\n\n";
1050  }
1051 
1052 #if 0
1053  for(int i = 0; i < total_npanes; ++i){
1054  COM::Attribute *p_pconn = allpanes[i]->attribute(COM::COM_PCONN);
1055  // std::cout << "PANE " << allpanes[i]->id() << "'s real pconn size = "
1056  // << p_pconn->size_of_real_items() << " and ghost size = "
1057  // << p_pconn->size_of_items()-p_pconn->size_of_real_items() << "\n\n";
1058 
1059  //int* ptr = (int*)p_pconn->pointer();
1060  //for(int j=0, nj=p_pconn->size_of_items(); j<nj; ++j){
1061  // std::cout << ptr[j] << " ";
1062  //}
1063  // std::cout << "\n\n";
1064  }
1065 #endif
1066 
1067  // update
1069  Rocmap::update_ghosts(w_is_surface);
1070 
1071  // delete buffer and false pconn attributes
1072  wrk_window->delete_attribute(com_buff->name());
1073  wrk_window->delete_attribute(false_pconn->name());
1074 
1075 }
1076 
1078 
1079 
1080 
1081 
1082 
1083 
bool operator<(const Four_tuple &x) const
void determine_physical_border()
Determine which nodes and elements are on the physical border.
Definition: Rocmop.C:677
A structure used to represent element faces.
Definition: Pane_boundary.C:60
Utility for constructing pane connectivities in parallel.
std::map< int, int > Id_Map
virtual void compute(double atts[]) const
Calculate the metric value on this element.
const NT & d
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_GROUP_EMPTY INTEGER MPI_MAX
Contains the prototypes for the Pane object.
j indices k indices k
Definition: Indexing.h:6
#define COM_assertion_msg(EX, msg)
Vector_n max(const Array_n_const &v1, const Array_n_const &v2)
Definition: Vector_n.h:354
This file contains the prototypes for Roccom API.
3D geometric quality Metric declarations.
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_GROUP_EMPTY INTEGER MPI_MIN
const int & operator[](int i) const
Vector_3 & normalize()
Definition: mapbasic.h:114
Handles communication of shared nodes, ghost nodes or ghost cells across panes.
const int total_npanes
Definition: ex1.C:94
std::map< Four_tuple, Facet_ID > Corners2Face_Map
Definition: Pane_boundary.C:73
T norm(const NVec< DIM, T > &v)
static void reduce_maxabs_on_shared_nodes(COM::Attribute *att, COM::Attribute *pconn=NULL)
Perform a maxabs-reduction on the shared nodes for the given attribute.
Definition: Rocmap.C:77
void smooth_vol_mesq_ng()
Smooths a volume using Mesquite with only shared node information.
Definition: Rocmop_1.h:276
int COM_compatible_types(COM_Type type1, COM_Type type2)
Definition: roccom_c++.h:563
blockLoc i
Definition: read.cpp:79
void int int REAL * x
Definition: read.cpp:74
static void div(const Attribute *x, const Attribute *y, Attribute *z)
Operation wrapper for division.
Definition: op3args.C:269
Four_tuple(int a, int b, int c, int d)
int & operator[](int i)
#define MOP_END_NAMESPACE
Definition: mopbasic.h:29
virtual void initialize(Vector_3< double > n[], int type)
Initialize a 3D Geometric Metric by nodal coords and element type.
Definition for Rocblas API.
void int int * nk
Definition: read.cpp:74
static void copy_scalar(const void *x, Attribute *y)
Operation wrapper for copy (x is a scalar pointer).
Definition: op2args.C:583
static void update_ghosts(COM::Attribute *att, const COM::Attribute *pconn=NULL)
Update ghost nodal or elemental values for the given attribute.
Definition: Rocmap.C:87
MesqPane.h.
j indices j
Definition: Indexing.h:6
#define MOP_BEGIN_NAMESPACE
Definition: mopbasic.h:28
3D Max and Min Angle Metric Class
static void copy(const Attribute *x, Attribute *y)
Wrapper for copy.
Definition: op2args.C:333
void int int REAL REAL REAL *z blockDim dim * ni
Definition: read.cpp:77
void int * nj
Definition: read.cpp:74
static int rank
Definition: advectest.C:66
long double dist(long double *coord1, long double *coord2, int size)
int COMMPI_Initialized()
Definition: commpi.h:168
Type norm() const
Definition: mapbasic.h:112
Utility for detecting boundaries of a pane.