Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Propagation_3.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: Propagation_3.C,v 1.17 2008/12/06 08:45:27 mtcampbe Exp $
24 
25 #include "Propagation_3.h"
26 #include "../Rocblas/include/Rocblas.h"
27 #include "../Rocsurf/include/Generic_element_2.h"
28 
30 
31 Propagation_3::Propagation_3( Manifold *wm, COM::Window *buf)
32  : _surf(wm), _buf(buf), _cnstr_set(false), _bnd_set(0),
33  _cnstr_nodes(NULL), _cnstr_bound(NULL) {
34 
35  // Depending on whether we have pconn for ghost nodes and elements,
36  // run in either WHOLE_PANE or ACROSS_PANE mode.
37  if ( wm->pconn_nblocks() >=3)
39  else
41 
42  if ( _buf) {
43  _cnstr_nodes = _buf->new_attribute( "PROP_cnstr_nodes", 'n', COM_INT, 1, "");
44  _cnstr_faces = _buf->new_attribute( "PROP_cnstr_faces", 'e', COM_INT, 1, "");
45  _cnstr_bndry_edges = _buf->new_attribute( "PROP_cnstr_bndry_edges", 'e', COM_CHAR, 1, "");
46  _cnstr_bndry_nodes = _buf->new_attribute( "PROP_cnstr_bndry_nodes", 'n', COM_CHAR, 1, "");
47  _cnstr_bound = _buf->new_attribute( "PROP_cnstr_bound", 'p', COM_DOUBLE, BOUND_LEN, "");
48 
49  _buf->panes( _panes);
50  }
51 
52  MPI_Comm comm = _buf->get_communicator();
54  else _rank = 0;
55 }
56 
57 void Propagation_3::
58 set_bounds( const COM::Attribute *bnd) {
59  if ( _buf == NULL) return;
60 
61  if ( bnd == NULL) {
62  // Deallocate cnstr_bound if constraints are unset
63  _buf->dealloc_array( "PROP_cnstr_bound", 0);
64  _bnd_set = false;
65  }
66  else {
67  COM_assertion_msg( COM_compatible_types( bnd->data_type(), COM_DOUBLE) &&
68  bnd->size_of_components()==BOUND_LEN &&
69  bnd->is_panel() || bnd->is_windowed(),
70  "Propagation_3::set_bounds expects double-precision 3-vector");
71 
72  _buf->inherit( const_cast<COM::Attribute*>(bnd), "PROP_cnstr_bound",
73  COM::Pane::INHERIT_CLONE, true, NULL, 0);
74  _bnd_set = true;
75  }
76 
77  _buf->init_done( false);
78 }
79 
80 void Propagation_3::
81 set_constraints( const COM::Attribute *ct_in) {
82  if ( _buf == NULL) return;
83 
84  if ( ct_in == NULL) {
85  // Deallocate cnstr_types if constraints are unset
86  _buf->dealloc_array( "PROP_cnstr_nodes", 0);
87  _buf->dealloc_array( "PROP_cnstr_faces", 0);
88  _buf->dealloc_array( "PROP_cnstr_bndry_edges", 0);
89  _buf->dealloc_array( "PROP_cnstr_bndry_nodes", 0);
90  _cnstr_set = false;
91  }
92  else {
93  COM_assertion_msg( ct_in->is_panel() || ct_in->is_elemental(),
94  "Constraints must be associated with panes or faces.");
95 
96  // Copy the constraints onto the window
97  _buf->resize_array( _cnstr_faces, 0);
98  Rocblas::copy( ct_in, _cnstr_faces); // Set facal flags
99 
100  // Determine the boundary of patches with constraints
101  _buf->resize_array( _cnstr_bndry_edges, 0);
102  _buf->resize_array( _cnstr_bndry_nodes, 0);
104 
105  // Determine nodal constraints.
106  _buf->resize_array( _cnstr_nodes, 0);
107 
108  // Convert constraints from facial/panel to nodal
110  _cnstr_set = true;
111  }
112 }
113 
114 inline bool matchall( int a, int b) { return (a & b) == b; }
115 inline bool matchany( int a, int b) { return (a & b); }
116 
117 void Propagation_3::
118 convert_constraints( const COM::Attribute *ctypes_faces,
119  COM::Attribute *ctypes_nodes) {
120  int zero = 0;
121  Rocblas::copy_scalar( &zero, ctypes_nodes);
122 
123  // Loop through all the nodes to compute their displacements
124  enum { FIXED=1, XDIR = 2, YDIR = 4, ZDIR = 8,
125  NOX = 16, NOY = 32, NOZ = 64};
126 
127  std::vector< COM::Pane*>::iterator it = _panes.begin(), iend=_panes.end();
128  // Loop through the panes and its real nodes
129  for ( it=_panes.begin(); it!=iend; ++it) {
130  COM::Pane *pane = *it;
131 
132  COM_assertion( pane->attribute(COM_NC)->stride()==3);
133  const Point_3 *pnts =
134  reinterpret_cast<const Point_3*>(pane->coordinates());
135 
136  const int *val_faces=(const int*)pane->attribute(ctypes_faces->id())->pointer();
137  int *val_nodes=(int*)pane->attribute(ctypes_nodes->id())->pointer();
138 
139  // Loop through real elements of the current pane
140  Element_node_enumerator ene( pane, 1);
141  for ( int j=0, nj=pane->size_of_real_elements(); j<nj; ++j, ene.next()) {
142  int type = val_faces[j];
143 
144  int ne = ene.size_of_edges();
145  // Loop through all vertices of current face.
146  for ( int k=0; k<ne; ++k) {
147  int vindex = ene[k]-1;
148 
149  switch ( type) {
150  case 0: break;
151  case 2: val_nodes[vindex] |= FIXED; break;
152  case 'x': val_nodes[vindex] |= XDIR; break;
153  case -'x': val_nodes[vindex] |= NOX; break;
154  case 'y': val_nodes[vindex] |= YDIR; break;
155  case -'y': val_nodes[vindex] |= NOY; break;
156  case 'z': val_nodes[vindex] |= ZDIR; break;
157  case -'z': val_nodes[vindex] |= NOZ; break;
158  case 't':
159  case -'t': {
160  SURF::Generic_element_2 e(ene.size_of_edges(), ene.size_of_nodes());
161  COM::Element_node_vectors_k_const<Point_3 > ps;
162  ps.set( pnts, ene, 1);
163 
164  Vector_2 nc(0.5,0.5);
165  Vector_3 J[2], nrm;
166  e.Jacobian( ps, nc, J);
167  nrm = Vector_3::cross_product( J[0], J[1]).normalize();
168 
169  double eps = 1.e-1;
170  if ( std::abs(std::abs(nrm[0])-1) < eps) {
171  if ( type > 0) val_nodes[vindex] |= NOX;
172  else val_nodes[vindex] |= XDIR;
173  }
174  else if ( std::abs(std::abs(nrm[1])-1) < eps) {
175  if ( type > 0) val_nodes[vindex] |= NOY;
176  else val_nodes[vindex] |= YDIR;
177  }
178  else if ( std::abs(std::abs(nrm[2])-1) < eps) {
179  if ( type > 0) val_nodes[vindex] |= NOZ;
180  else val_nodes[vindex] |= ZDIR;
181  }
182  else
183  COM_assertion_msg(false, "Plane must be along axial direction");
184  break;
185  }
186  default:
187  COM_assertion_msg( false, "Unknown/unsupported type of constraint");
188  } // switch
189  } // for k
190  } // for j
191  } // for it
192 
193  _surf->reduce_on_shared_nodes( ctypes_nodes, Manifold::OP_BOR);
194 
195  // Loop through the panes and its real nodes
196  for ( it=_panes.begin(); it!=iend; ++it) {
197  COM::Pane *pane = *it;
198  int *val_nodes = (int*)pane->attribute( ctypes_nodes->id())->pointer();
199 
200  for ( int j=0, nj=pane->size_of_real_nodes(); j<nj; ++j) {
201  int &type = val_nodes[j];
202 
203  if ( type == 0) continue; // no constrained
204 
205  if ( (type & FIXED) || matchall(type, NOX|NOY|NOZ) ||
206  matchall(type, XDIR|YDIR) || matchall(type, XDIR|ZDIR) ||
207  matchall(type, YDIR|ZDIR) )
208  type = 2;
209  else if ( matchall(type, NOX|NOY)) {
210  if ( matchany(type, XDIR|YDIR)) { type = 2; }
211  else { type = 'z'; }
212  }
213  else if ( matchall(type, NOX|NOZ)) {
214  if ( matchany(type, XDIR|ZDIR)) { type = 2; }
215  else { type = 'y'; }
216  }
217  else if ( matchall(type, NOY|NOZ)) {
218  if ( matchany(type, YDIR|ZDIR)) { type = 2; }
219  else { type = 'x'; }
220  }
221  else if ( type & NOX) {
222  if ( type & XDIR) { type = 2; }
223  else if ( type & YDIR) { type = 'y'; }
224  else if ( type & ZDIR) { type = 'z'; }
225  else type = -'x';
226  }
227  else if ( type & NOY) {
228  if ( type & YDIR) { type = 2; }
229  else if ( type & XDIR) { type = 'x'; }
230  else if ( type & ZDIR) { type = 'z'; }
231  else type = -'y';
232  }
233  else if ( type & NOZ) {
234  if ( type & ZDIR) { type = 2; }
235  else if ( type & XDIR) { type = 'x'; }
236  else if ( type & YDIR) { type = 'y'; }
237  else type = -'z';
238  }
239  else if ( type & XDIR)
240  type = 'x';
241  else if ( type & YDIR)
242  type = 'y';
243  else {
244  COM_assertion( type & ZDIR);
245  type = 'z';
246  }
247  } // for j
248  } // for it
249 }
250 
252 void Propagation_3::
253 determine_constraint_boundary( const COM::Attribute *ctypes_faces,
254  COM::Attribute *ctypes_bndry_edges,
255  COM::Attribute *ctypes_bndry_nodes) {
256  _surf->update_bd_flags( ctypes_faces); // Update facal flags along boundaries
257 
258  char zero = 0;
259  Rocblas::copy_scalar( &zero, ctypes_bndry_edges);
260  Rocblas::copy_scalar( &zero, ctypes_bndry_nodes);
261 
262  Manifold::PM_iterator pm_it=_surf->pm_begin();
263  std::vector< COM::Pane*>::iterator it = _panes.begin(), iend=_panes.end();
264 
265  // Loop through the panes and its real elements
266  for ( it=_panes.begin(); it!=iend; ++it, ++pm_it) {
267  COM::Pane *pane = *it;
268 
269  const int *val_faces=(const int*)pane->attribute(ctypes_faces->id())->pointer();
270  char *val_bndry_edges=(char*)pane->attribute(ctypes_bndry_edges->id())->pointer();
271  char *val_bndry_nodes=(char*)pane->attribute(ctypes_bndry_nodes->id())->pointer();
272 
273  // Loop through real elements of the current pane
274  Element_node_enumerator ene( pane, 1);
275  for ( int j=0, nj=pane->size_of_real_elements(); j<nj; ++j, ene.next()) {
276  for ( int k=0, ne=ene.size_of_edges(); k<ne; ++k) {
277  Edge_ID eid(j+1,k), eid_opp = pm_it->get_opposite_real_edge( eid);
278 
279  if (!pm_it->is_physical_border_edge( eid_opp)) {
280  int flag_opp = (eid_opp.is_border() ?
281  pm_it->get_bd_flag( eid_opp) : val_faces[eid_opp.eid()-1]);
282  if ( val_faces[j] != flag_opp) {
283  val_bndry_edges[j] |= (1<<k);
284  val_bndry_nodes[ene[k]-1] = 1;
285  }
286  }
287  } // for k
288  } // for j
289  } // for it
290 
291  _surf->reduce_on_shared_nodes( ctypes_bndry_nodes, Manifold::OP_MAX);
292 }
293 
294 bool Propagation_3::
296  const double rad_min, const double rad_max,
297  double eps) {
298  double sqnrm = (pnt - org).squared_norm();
299 
300  return sqnrm >= square( rad_max-eps) ||
301  rad_min >=0 && sqnrm <= square( rad_min+eps);
302 }
303 
304 void Propagation_3::
306  const double rad_min, const double rad_max,
307  Vector_3 &disp, double eps) {
308  Vector_3 dir = pnt - org;
309  double sqnrm = dir.squared_norm(), sqnrm1 = (dir+disp).squared_norm(), t;
310 
311  if ( std::max( sqnrm, sqnrm1) >= square((t=rad_max)-eps) &&
312  std::min( sqnrm, sqnrm1) <= square(rad_max+eps) ||
313  (t=rad_min) >= 0 && std::min( sqnrm, sqnrm1) <= square(rad_min+eps) &&
314  std::max( sqnrm, sqnrm1) >= square(rad_min-eps)) {
315 
316  if ( dir.is_null())
317  disp[0] = disp[1] = disp[2] = 0;
318  else {
319  Vector_3 dir_unit; (dir_unit = dir).normalize();
320  disp += ( t - disp*dir_unit) * dir_unit - dir;
321  }
322  }
323  else if ( sqnrm >= square(rad_max) && sqnrm1 > sqnrm ||
324  rad_min >= 0 && sqnrm <= square(rad_min) && sqnrm1 < sqnrm) {
325  if ( dir.is_null())
326  disp[0] = disp[1] = disp[2] = 0;
327  else
328  // Only move tangentially
329  disp -= disp * dir / dir.squared_norm();
330  }
331 }
332 
333 bool Propagation_3::check_radial_bound( const double x, const double y,
334  const double bnd_min,
335  const double bnd_max,
336  double eps) {
337 
338  double sq_xy = square( x)+square( y);
339  return sq_xy >= square(bnd_max-eps) ||
340  bnd_min >=0 && sq_xy <= square(bnd_min+eps);
341 }
342 
343 void Propagation_3::bound_radial_disp( const double x, const double y,
344  const double bnd_min, const double bnd_max,
345  double &dx, double &dy, double eps) {
346 
347  double sq_xy = square( x)+square( y);
348  double sq_rad_actual=square( x+dx)+square( y+dy);
349  double t;
350 
351  if ( std::max( sq_xy, sq_rad_actual) >= square((t=bnd_max)-eps) &&
352  std::min( sq_xy, sq_rad_actual) <= square(bnd_max+eps) ||
353  std::min( sq_xy, sq_rad_actual) <= square((t=bnd_min)+eps) &&
354  std::max( sq_xy, sq_rad_actual) >= square(bnd_min-eps)) {
355 
356  if ( sq_xy == 0)
357  dx = dy = 0;
358  else {
359  // Try to propagate toward the cylinder
360  double ratio = t / std::sqrt( sq_xy);
361  dx = ratio*x - x;
362  dy = ratio*y - y;
363  }
364  }
365  else if ( sq_xy >= square(bnd_max-eps) && sq_rad_actual >= sq_xy ||
366  bnd_min>=0 && sq_xy <= square(bnd_min+eps) && sq_rad_actual<=sq_xy) {
367  dx = dy = 0; // Do not alter dx if moves inwards
368  }
369 
370 }
371 
372 bool Propagation_3::check_axial_bound( const double x, const double bnd_min,
373  const double bnd_max, double eps) {
374  return x >= bnd_max-eps || x <= bnd_min+eps;
375 }
376 
377 void Propagation_3::bound_axial_disp( const double x, const double bnd_min,
378  const double bnd_max, double &dx,
379  double eps) {
380 
381  double xnew = x+dx;
382  if ( std::max( x, xnew) >= bnd_max-eps && std::min(x, xnew) <= bnd_max+eps) {
383  dx = bnd_max - x;
384  }
385  else if ( std::min( x, xnew) <= bnd_min+eps && std::max(x, xnew) >= bnd_min-eps) {
386  dx = bnd_min - x;
387  }
388  else if ( x >= bnd_max+eps && xnew > x || x<=bnd_min-eps && xnew < x)
389  dx = 0; // Do not alter dx if moves inwards
390 }
391 
392 void Propagation_3::
393 bound_nodal_motion( const Point_3 &pnt, const double *bnd,
394  Vector_3 &du, double eps) {
395  if ( !in_bounding_box( pnt, (const Point_3&)bnd[6], (const Point_3&)bnd[9]))
396  return;
397 
398  switch ( (int)bnd[0]) {
399  case 's': bound_spherical_disp( pnt, (const Point_3&)bnd[3],
400  bnd[1], bnd[2], du, eps); break;
401 
402  case 'x': bound_axial_disp( pnt[0]-bnd[3], bnd[1], bnd[2], du[0], eps); break;
403  case 'y': bound_axial_disp( pnt[1]-bnd[4], bnd[1], bnd[2], du[1], eps); break;
404  case 'z': bound_axial_disp( pnt[2]-bnd[5], bnd[1], bnd[2], du[2], eps); break;
405 
406  case -'x': bound_radial_disp( pnt[1]-bnd[4], pnt[2]-bnd[5], bnd[1], bnd[2],
407  du[1], du[2], eps); break;
408  case -'y': bound_radial_disp( pnt[0]-bnd[3], pnt[2]-bnd[5], bnd[1], bnd[2],
409  du[0], du[2], eps); break;
410  case -'z': bound_radial_disp( pnt[0]-bnd[3], pnt[1]-bnd[4], bnd[1], bnd[2],
411  du[0], du[1], eps); break;
412 
413  default: COM_assertion_msg( false, "Unknown type of bnd");
414  }
415 }
416 
417 bool Propagation_3::
418 reached_nodal_bound( const Point_3 &pnt, const double *bnd, double eps) {
419  if ( !in_bounding_box( pnt, (const Point_3&)bnd[6], (const Point_3&)bnd[9]))
420  return false;
421 
422  switch ( (int)bnd[0]) {
423  case 's': return check_spherical_bound( pnt, (const Point_3&)bnd[3],
424  bnd[1], bnd[2], eps);
425 
426  case 'x': return check_axial_bound( pnt[0]-bnd[3], bnd[1], bnd[2], eps);
427  case 'y': return check_axial_bound( pnt[1]-bnd[4], bnd[1], bnd[2], eps);
428  case 'z': return check_axial_bound( pnt[2]-bnd[5], bnd[1], bnd[2], eps);
429 
430  case -'x': return check_radial_bound( pnt[1]-bnd[4], pnt[2]-bnd[5], bnd[1], bnd[2], eps);
431  case -'y': return check_radial_bound( pnt[0]-bnd[3], pnt[2]-bnd[5], bnd[1], bnd[2], eps);
432  case -'z': return check_radial_bound( pnt[0]-bnd[3], pnt[1]-bnd[4], bnd[1], bnd[2], eps);
433 
434  default: COM_assertion_msg( false, "Unknown type of bnd");
435  }
436 
437  return false;
438 }
439 
440 void Propagation_3::
442  switch ( type) {
443  case 0: break;
444  case 2: du = Vector_3(0.); break;
445  case 'x': du[1] = du[2] = 0.; break;
446  case -'x': du[0] = 0.; break;
447  case 'y': du[0] = du[2] = 0.; break;
448  case -'y': du[1] = 0.; break;
449  case 'z': du[0] = du[1] = 0.; break;
450  case -'z': du[2] = 0.; break;
451  default: COM_assertion_msg( false, "Unknown type of constraint");
452  }
453 }
454 
455 void Propagation_3::
456 get_constraint_directions( int type, int &ndirs, Vector_3 dirs[2]) {
457  switch ( type) {
458  case 0:
459  ndirs = 0;
460  break;
461  case 2:
462  ndirs = 3;
463  break;
464  case 'x':
465  ndirs = 1;
466  dirs[0] = Vector_3(1,0,0);
467  break;
468  case -'x':
469  ndirs = 2;
470  dirs[0] = Vector_3(0,1,0);
471  dirs[1] = Vector_3(0,0,1);
472  break;
473  case 'y':
474  ndirs = 1;
475  dirs[0] = Vector_3(0,1,0);
476  break;
477  case -'y':
478  ndirs = 2;
479  dirs[0] = Vector_3(1,0,0);
480  dirs[1] = Vector_3(0,0,1);
481  break;
482  case 'z':
483  ndirs = 1;
484  dirs[0] = Vector_3(0,0,1);
485  break;
486  case -'z':
487  ndirs = 2;
488  dirs[0] = Vector_3(1,0,0);
489  dirs[1] = Vector_3(0,1,0);
490  break;
491  default: COM_assertion_msg( false, "Unknown type of constraint");
492  }
493 }
494 
495 // Enforce nodal constraints.
496 void Propagation_3::
497 enforce_nodal_constraints( COM::Attribute *du) {
498  if ( !_cnstr_set) return;
499 
500  std::vector< COM::Pane*>::iterator it = _panes.begin(), iend=_panes.end();
501  // Loop through the panes and its real nodes
502  for ( it=_panes.begin(); it!=iend; ++it) {
503  COM::Pane *pane = *it;
504 
505  const int *types = reinterpret_cast<const int*>
506  (pane->attribute(_cnstr_nodes->id())->pointer());
507  Vector_3 *ds = reinterpret_cast<Vector_3*>
508  (pane->attribute( du->id())->pointer());
509 
510  for (int i=0, n=pane->size_of_real_nodes(); i<n; ++i) {
511  enforce_nodal_constraint( types[i], ds[i]);
512  }
513  }
514 }
515 
516 // Enforce nodal constraints.
517 void Propagation_3::
518 bound_nodal_motion( COM::Attribute *du) {
519  if ( !_bnd_set) return;
520 
521  std::vector< COM::Pane*>::iterator it = _panes.begin(), iend=_panes.end();
522  // Loop through the panes and its real nodes
523  for ( it=_panes.begin(); it!=iend; ++it) {
524  COM::Pane *pane = *it;
525 
526  Vector_3 *ds = reinterpret_cast<Vector_3*>
527  (pane->attribute( du->id())->pointer());
528 
529  const Point_3 *pnts = reinterpret_cast<const Point_3*>
530  (pane->attribute(COM_NC)->pointer());
531  const double *bnd = _bnd_set ? reinterpret_cast<const double*>
532  ( pane->attribute( _cnstr_bound->id())->pointer()) : NULL;
533  int nbnd = _bnd_set ? pane->attribute( _cnstr_bound->id())->size_of_items() : 0;
534 
535  // Bound all nodes
536  for ( int i=0; i<nbnd; ++i, bnd+=BOUND_LEN) {
537  double eps = 1.e-5 * std::min( std::min( bnd[9]-bnd[6], bnd[10]-bnd[7]),
538  bnd[11]-bnd[8]);
539  if ( eps>1 || eps <= 0) eps = 1.e-10;
540 
541  for (int i=0, n=pane->size_of_real_nodes(); i<n; ++i)
542  bound_nodal_motion( pnts[i], bnd, ds[i]);
543  }
544  }
545 }
546 
547 // Bound a face based on nodal constraints. If all the nodes are beyond
548 // the bounded, then set the value to zero.
549 void Propagation_3::
550 bound_facial_speed( COM::Attribute *fa) {
551  COM_assertion( fa->window() == _buf);
552 
553  COM_assertion_msg( _bnd_set, "Bound must be set first before calling bound_facial_speed");
554 
555  COM_assertion_msg( fa->is_elemental() && fa->size_of_components()==1 &&
556  COM_compatible_types( fa->data_type(), COM_DOUBLE),
557  "Propagation_3::bound_facial_speed expects a scalar double-precision elemental attribute.");
558 
559  std::vector< COM::Pane*>::iterator it = _panes.begin(), iend=_panes.end();
560  // Loop through the panes and its real nodes
561  for ( it=_panes.begin(); it!=iend; ++it) {
562  COM::Pane *pane = *it;
563 
564  double *val_dbl = (double*)pane->attribute(fa->id())->pointer();
565  // Skip the panes without the attribute.
566  if ( val_dbl==NULL) continue;
567 
568  COM_assertion( pane->attribute(COM_NC)->stride()==3);
569  const Point_3 *pnts = reinterpret_cast<const Point_3*>(pane->coordinates());
570  int nbnd = _bnd_set ? pane->attribute( _cnstr_bound->id())->size_of_items() : 0;
571  if ( nbnd==0) continue;
572 
573  // Loop through real elements of the current pane
574  Element_node_enumerator ene( pane, 1);
575  for ( int j=0, nj=pane->size_of_real_elements(); j<nj; ++j, ene.next()) {
576  // Skip the faces that are already initialized to 0.
577  if ( val_dbl[j]==0) continue;
578  int ne = ene.size_of_edges();
579 
580  const double *bnd = reinterpret_cast<const double*>
581  ( pane->attribute( _cnstr_bound->id())->pointer());
582  bool out[] = {false, false, false, false};
583  // Bound all nodes
584  for ( int i=0; i<nbnd; ++i, bnd+=BOUND_LEN) {
585  double eps = 1.e-5 * std::min( std::min( bnd[9]-bnd[6], bnd[10]-bnd[7]),
586  bnd[11]-bnd[8]);
587  if ( eps>1 || eps <=0 ) eps = 1.e-10;
588 
589  for ( int k=0; k<ne; ++k) {
590  out[k] |= reached_nodal_bound( pnts[ene[k]-1], bnd, eps);
591  }
592  }
593 
594  if ( out[0] && out[1] && out[2] && (ne==3 || out[3])) val_dbl[j] = 0;
595  }
596  }
597 }
598 
600 
601 
602 
603 
604 
605 
int COMMPI_Comm_rank(MPI_Comm c)
Definition: commpi.h:162
COM::Window * _buf
#define COM_assertion(EX)
Error checking utility similar to the assert macro of the C language.
An adaptor for enumerating node IDs of an element.
#define PROP_END_NAMESPACE
Definition: propbasic.h:29
static void bound_spherical_disp(const Point_3 &pnt, const Point_3 &org, const double rad_min, const double rad_max, Vector_3 &disp, double eps=0)
j indices k indices k
Definition: Indexing.h:6
COM::Attribute * _cnstr_nodes
void int int REAL REAL * y
Definition: read.cpp:74
static bool check_spherical_bound(const Point_3 &pnt, const Point_3 &org, const double rad_min, const double rad_max, double eps=0)
static bool reached_nodal_bound(const Point_3 &pnt, const double *bnd, double eps=0)
NT dx
#define PROP_BEGIN_NAMESPACE
Definition: propbasic.h:28
#define COM_assertion_msg(EX, msg)
COM::Attribute * _cnstr_faces
MAP::Facet_ID Edge_ID
Definition: Manifold_2.h:49
void determine_constraint_boundary(const COM::Attribute *ctypes_faces, COM::Attribute *ctypes_bndry_edges, COM::Attribute *ctypes_bndry_nodes)
Convert facial or panel constraints to nodal constraints.
Vector_n max(const Array_n_const &v1, const Array_n_const &v2)
Definition: Vector_n.h:354
static void enforce_nodal_constraint(int type, Vector_3 &du)
Enforce constraint for a specific vector.
bool matchall(int a, int b)
C/C++ Data types.
Definition: roccom_basic.h:129
static void bound_axial_disp(const double x, const double bnd_min, const double bnd_max, double &dx, double eps=0)
SURF::Vector_3< Real > Vector_3
Definition: rfc_basic.h:42
double sqrt(double d)
Definition: double.h:73
Vector_3 & normalize()
Definition: mapbasic.h:114
void convert_constraints(const COM::Attribute *ctypes_faces, COM::Attribute *ctypes_nodes)
Convert facial constraints to nodal constraints.
void bound_facial_speed(COM::Attribute *fa)
COM::Attribute * _cnstr_bound
void set_bounds(const COM::Attribute *bnd)
Set the bounds.
Definition: Propagation_3.C:58
std::vector< COM::Pane * > _panes
Point object that represents a single point.
Definition: datatypedef.h:68
static double square(double x)
virtual void bound_nodal_motion(COM::Attribute *disps)
static bool check_axial_bound(const double x, const double bnd_min, const double bnd_max, double eps=0)
static void bound_radial_disp(const double x, const double y, const double bnd_min, const double bnd_max, double &dx, double &dy, double eps=0)
**********************************************************************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
SURF::Window_manifold_2 Manifold
Definition: propbasic.h:46
int size_of_edges() const
Number of edges per element.
int COM_compatible_types(COM_Type type1, COM_Type type2)
Definition: roccom_c++.h:563
blockLoc i
Definition: read.cpp:79
virtual void set_constraints(const COM::Attribute *cnstr_types)
Set the types and directions of nodal constraints.
Definition: Propagation_3.C:81
void int int REAL * x
Definition: read.cpp:74
Manifold * _surf
int size_of_nodes() const
Number of nodes per element.
Type squared_norm() const
Definition: mapbasic.h:110
const NT & n
static Vector_3 cross_product(const Vector_3 &v, const Vector_3 &w)
Definition: mapbasic.h:104
static bool check_radial_bound(const double x, const double y, const double bnd_min, const double bnd_max, double eps=0)
SURF::Access_Mode _mode
Vector_n min(const Array_n_const &v1, const Array_n_const &v2)
Definition: Vector_n.h:346
COM::Attribute * _cnstr_bndry_edges
static void copy_scalar(const void *x, Attribute *y)
Operation wrapper for copy (x is a scalar pointer).
Definition: op2args.C:583
j indices j
Definition: Indexing.h:6
NT dy
COM::Attribute * _cnstr_bndry_nodes
NT abs(const NT &x)
Definition: number_utils.h:130
bool is_null() const
Definition: mapbasic.h:133
static void copy(const Attribute *x, Attribute *y)
Wrapper for copy.
Definition: op2args.C:333
static void get_constraint_directions(int type, int &ndirs, Vector_3 dirs[2])
Get orthonormals of the constraints.
void next()
Go to the next element within the connectivity tables of a pane.
void int * nj
Definition: read.cpp:74
virtual void enforce_nodal_constraints(COM::Attribute *du)
Enforces the nodal constraints by projecting motion onto given direction.
Some basic geometric data types.
Definition: mapbasic.h:54
int COMMPI_Initialized()
Definition: commpi.h:168
const int BOUND_LEN
Definition: Propagation_3.h:36
bool matchany(int a, int b)
static bool in_bounding_box(const Point_3 &pnt, const Point_3 &lb, const Point_3 &ub)