26 #include "../Rocblas/include/Rocblas.h" 
   27 #include "../Rocsurf/include/Generic_element_2.h" 
   32   : _surf(wm), _buf(buf), _cnstr_set(false), _bnd_set(0), 
 
   33     _cnstr_nodes(NULL), _cnstr_bound(NULL) {
 
   37   if ( wm->pconn_nblocks() >=3)
 
   52   MPI_Comm comm = 
_buf->get_communicator();
 
   59   if ( 
_buf == NULL) 
return;
 
   63     _buf->dealloc_array( 
"PROP_cnstr_bound", 0);
 
   69                        bnd->is_panel() || bnd->is_windowed(),
 
   70                        "Propagation_3::set_bounds expects double-precision 3-vector");
 
   72     _buf->inherit( const_cast<COM::Attribute*>(bnd), 
"PROP_cnstr_bound",
 
   73                    COM::Pane::INHERIT_CLONE, 
true, NULL, 0);
 
   77   _buf->init_done( 
false);
 
   82   if ( 
_buf == NULL) 
return;
 
   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);
 
   94                        "Constraints must be associated with panes or faces.");
 
  114 inline bool matchall( 
int a, 
int b) { 
return (a & b) == b; }
 
  115 inline bool matchany( 
int a, 
int b) { 
return (a & b); }
 
  119                      COM::Attribute *ctypes_nodes) {
 
  124   enum { FIXED=1, XDIR = 2, YDIR = 4, ZDIR = 8, 
 
  125          NOX = 16, NOY = 32, NOZ = 64};
 
  130     COM::Pane *pane = *it;
 
  134       reinterpret_cast<const Point_3*
>(pane->coordinates()); 
 
  136     const int *val_faces=(
const int*)pane->attribute(ctypes_faces->id())->pointer();
 
  137     int *val_nodes=(
int*)pane->attribute(ctypes_nodes->id())->pointer();
 
  141     for ( 
int j=0, 
nj=pane->size_of_real_elements(); 
j<
nj; ++
j, ene.
next()) {
 
  142       int type = val_faces[
j];
 
  146       for ( 
int k=0; 
k<ne; ++
k) {
 
  147         int vindex = ene[
k]-1;
 
  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;
 
  161           COM::Element_node_vectors_k_const<Point_3 > ps;
 
  162           ps.set( pnts, ene, 1);
 
  166           e.Jacobian( ps, nc, J);
 
  171             if ( type > 0) val_nodes[vindex] |= NOX;
 
  172             else val_nodes[vindex] |= XDIR;
 
  175             if ( type > 0) val_nodes[vindex] |= NOY;
 
  176             else val_nodes[vindex] |= YDIR;
 
  179             if ( type > 0) val_nodes[vindex] |= NOZ;
 
  180             else val_nodes[vindex] |= ZDIR;
 
  193   _surf->reduce_on_shared_nodes( ctypes_nodes, Manifold::OP_BOR);
 
  197     COM::Pane *pane = *it;
 
  198     int *val_nodes = (
int*)pane->attribute( ctypes_nodes->id())->pointer();
 
  200     for ( 
int j=0, 
nj=pane->size_of_real_nodes(); 
j<
nj; ++
j) {
 
  201       int &type = val_nodes[
j];
 
  203       if ( type == 0) 
continue; 
 
  205       if ( (type & FIXED) || 
matchall(type, NOX|NOY|NOZ) ||
 
  209       else if ( 
matchall(type, NOX|NOY)) {
 
  210         if ( 
matchany(type, XDIR|YDIR)) { type = 2; }
 
  213       else if ( 
matchall(type, NOX|NOZ)) {
 
  214         if ( 
matchany(type, XDIR|ZDIR)) { type = 2; }
 
  217       else if ( 
matchall(type, NOY|NOZ)) {
 
  218         if ( 
matchany(type, YDIR|ZDIR)) { type = 2; }
 
  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'; }
 
  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'; }
 
  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'; }
 
  239       else if ( type & XDIR)
 
  241       else if ( type & YDIR)
 
  254                                COM::Attribute *ctypes_bndry_edges,
 
  255                                COM::Attribute *ctypes_bndry_nodes) {
 
  256   _surf->update_bd_flags( ctypes_faces); 
 
  262   Manifold::PM_iterator pm_it=
_surf->pm_begin();
 
  266   for ( it=
_panes.begin(); it!=
iend; ++it, ++pm_it) {
 
  267     COM::Pane *pane = *it;
 
  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();
 
  275     for ( 
int j=0, 
nj=pane->size_of_real_elements(); 
j<
nj; ++
j, ene.
next()) {
 
  277         Edge_ID eid(
j+1,
k), eid_opp = pm_it->get_opposite_real_edge( eid);
 
  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;
 
  291   _surf->reduce_on_shared_nodes( ctypes_bndry_nodes, Manifold::OP_MAX);
 
  296                        const double rad_min, 
const double rad_max, 
 
  298   double sqnrm = (pnt - org).squared_norm();
 
  300   return sqnrm >= 
square( rad_max-eps) || 
 
  301     rad_min >=0 && sqnrm <= 
square( rad_min+eps);
 
  306                       const double rad_min, 
const double rad_max, 
 
  309   double sqnrm = dir.
squared_norm(), sqnrm1 = (dir+disp).squared_norm(), t;
 
  313        (t=rad_min) >= 0 && 
std::min( sqnrm, sqnrm1) <= 
square(rad_min+eps) && 
 
  317       disp[0] = disp[1] = disp[2] = 0;
 
  319       Vector_3 dir_unit; (dir_unit = dir).normalize();
 
  320       disp += ( t - disp*dir_unit) * dir_unit - dir;
 
  323   else if ( sqnrm >= 
square(rad_max) && sqnrm1 > sqnrm || 
 
  324             rad_min >= 0 && sqnrm <= 
square(rad_min) && sqnrm1 < sqnrm) {
 
  326       disp[0] = disp[1] = disp[2] = 0;
 
  334                                         const double bnd_min, 
 
  335                                         const double bnd_max,
 
  339   return  sq_xy >= 
square(bnd_max-eps) || 
 
  340     bnd_min >=0 && sq_xy <= 
square(bnd_min+eps);
 
  344                                        const double bnd_min, 
const double bnd_max,
 
  345                                        double &
dx, 
double &
dy, 
double eps) {
 
  351   if ( 
std::max( sq_xy, sq_rad_actual) >= 
square((t=bnd_max)-eps) && 
 
  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) {
 
  373                                        const double bnd_max, 
double eps) {
 
  374   return x >= bnd_max-eps || x <= bnd_min+eps;
 
  378                                       const double bnd_max, 
double &
dx, 
 
  382   if ( 
std::max( x, xnew) >= bnd_max-eps && 
std::min(x, xnew) <= bnd_max+eps) {
 
  385   else if ( 
std::min( x, xnew) <= bnd_min+eps && 
std::max(x, xnew) >= bnd_min-eps) {
 
  388   else if ( x >= bnd_max+eps && xnew > x || x<=bnd_min-eps && xnew < x)
 
  398   switch ( (
int)bnd[0]) {
 
  400                                    bnd[1], bnd[2], du, eps); 
break;
 
  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;
 
  407                                  du[1], du[2], eps); 
break;
 
  409                                  du[0], du[2], eps); 
break;
 
  411                                  du[0], du[1], eps); 
break;
 
  422   switch ( (
int)bnd[0]) {
 
  424                                            bnd[1], bnd[2], eps);
 
  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); 
 
  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;
 
  503     COM::Pane *pane = *it;
 
  505     const int *types = 
reinterpret_cast<const int*
> 
  508       (pane->attribute( du->id())->pointer());
 
  510     for (
int i=0, 
n=pane->size_of_real_nodes(); 
i<
n; ++
i) {
 
  524     COM::Pane *pane = *it;
 
  527       (pane->attribute( du->id())->pointer());
 
  530       (pane->attribute(
COM_NC)->pointer());
 
  531     const double *bnd = 
_bnd_set ? 
reinterpret_cast<const double*
> 
  532       ( pane->attribute( 
_cnstr_bound->id())->pointer()) : NULL;
 
  539       if ( eps>1 || eps <= 0) eps = 1.e-10;
 
  541       for (
int i=0, 
n=pane->size_of_real_nodes(); 
i<
n; ++
i)
 
  557                      "Propagation_3::bound_facial_speed expects a scalar double-precision elemental attribute.");
 
  562     COM::Pane *pane = *it;
 
  564     double *val_dbl = (
double*)pane->attribute(fa->id())->pointer();
 
  566     if ( val_dbl==NULL) 
continue;
 
  569     const Point_3 *pnts = 
reinterpret_cast<const Point_3*
>(pane->coordinates()); 
 
  571     if ( nbnd==0) 
continue;
 
  575     for ( 
int j=0, 
nj=pane->size_of_real_elements(); 
j<
nj; ++
j, ene.
next()) {
 
  577       if ( val_dbl[
j]==0) 
continue;
 
  580       const double *bnd = 
reinterpret_cast<const double*
> 
  582       bool out[] = {
false, 
false, 
false, 
false};
 
  587         if ( eps>1 || eps <=0 ) eps = 1.e-10;
 
  589         for ( 
int k=0; 
k<ne; ++
k) {
 
  594       if ( out[0] && out[1] && out[2] && (ne==3 || out[3])) val_dbl[
j] = 0;
 
int COMMPI_Comm_rank(MPI_Comm c)
#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
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)
COM::Attribute * _cnstr_nodes
void int int REAL REAL * y
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)
#define PROP_BEGIN_NAMESPACE
#define COM_assertion_msg(EX, msg)
COM::Attribute * _cnstr_faces
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)
static void enforce_nodal_constraint(int type, Vector_3 &du)
Enforce constraint for a specific vector. 
bool matchall(int a, int b)
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
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. 
std::vector< COM::Pane * > _panes
Point object that represents a single point. 
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
int size_of_edges() const 
Number of edges per element. 
int COM_compatible_types(COM_Type type1, COM_Type type2)
virtual void set_constraints(const COM::Attribute *cnstr_types)
Set the types and directions of nodal constraints. 
int size_of_nodes() const 
Number of nodes per element. 
Type squared_norm() const 
static Vector_3 cross_product(const Vector_3 &v, const Vector_3 &w)
static bool check_radial_bound(const double x, const double y, const double bnd_min, const double bnd_max, double eps=0)
Vector_n min(const Array_n_const &v1, const Array_n_const &v2)
COM::Attribute * _cnstr_bndry_edges
static void copy_scalar(const void *x, Attribute *y)
Operation wrapper for copy (x is a scalar pointer). 
COM::Attribute * _cnstr_bndry_nodes
static void copy(const Attribute *x, Attribute *y)
Wrapper for copy. 
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. 
virtual void enforce_nodal_constraints(COM::Attribute *du)
Enforces the nodal constraints by projecting motion onto given direction. 
Some basic geometric data types. 
bool matchany(int a, int b)
static bool in_bounding_box(const Point_3 &pnt, const Point_3 &lb, const Point_3 &ub)