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)