26 #include "../Rocblas/include/Rocblas.h"
27 #include "../Rocsurf/include/Rocsurf.h"
35 COM::Attribute *bo_attr, COM::Attribute *predicted) {
38 "If no speed function, then time step must be zero.");
40 const double zero = 0., eps = 1.e-100;
42 if ( dt==0) bo_attr = NULL;
46 COM::Attribute *A_attr =
_As;
55 COM::Attribute *sa_attr =
57 _buf->resize_array( sa_attr, 0);
63 std::vector< COM::Pane*>::iterator it =
_panes.begin();
64 Manifold::PM_iterator pm_it=
_surf->pm_begin();
65 for (
int i=0, local_npanes =
_panes.size();
66 i<local_npanes; ++
i, ++it, ++pm_it) {
67 COM::Pane *pane = *it;
71 (pane->attribute(
COM_NC)->pointer());
77 double *ws =
reinterpret_cast<double*
>
78 ( pane->attribute(w_attr->id())->pointer());
80 ( pane->attribute(
_vcenters->id())->pointer());
83 const double *spds_ptr = spds?
reinterpret_cast<const double*
>
84 (pane->attribute( spds->id())->pointer()):NULL;
88 ( pane->attribute(A_attr->id())->pointer());
90 ( pane->attribute(bm_attr->id())->pointer());
92 ( pane->attribute(bo_attr->id())->pointer()) : NULL;
94 ( pane->attribute(predicted->id())->pointer()) : NULL;
95 double *sa =
reinterpret_cast<double*
>
96 ( pane->attribute(sa_attr->id())->pointer());
97 double *areas =
reinterpret_cast<double*
>
98 ( pane->attribute(
_faceareas->id())->pointer());
102 for (
int j=0,
nj=pane->size_of_real_elements();
j<
nj; ++
j, ene.
next()) {
108 int uindex=ene[ne-1]-1, vindex=ene[0]-1, windex=0;
114 ene, fnrms[
j], cnt, disps, nrms);
118 for (
int k=0;
k<ne; ++
k, uindex=vindex, vindex=windex) {
119 windex = ene[(
k+1==ne)?0:k+1]-1;
122 Vector_3 ts[2] = { pnts[uindex]-pnts[vindex],
123 pnts[windex]-pnts[vindex]};
127 delta = -disps[
k]*ns_nz;
136 double s =
std::sqrt((ts[0]*ts[0])*(ts[1]*ts[1]));
154 A_v[0] += ns_nz[0]*nrm;
155 A_v[1] += ns_nz[1]*nrm;
156 A_v[2] += ns_nz[2]*nrm;
158 if ( delta!=0) bs_o[vindex] += delta*nrm;
165 vcnts[vindex] += diff;
172 _surf->reduce_on_shared_nodes( A_attr, Manifold::OP_SUM);
173 _surf->reduce_on_shared_nodes( bm_attr, Manifold::OP_SUM);
174 if ( bo_attr)
_surf->reduce_on_shared_nodes( bo_attr, Manifold::OP_SUM);
175 _surf->reduce_on_shared_nodes( sa_attr, Manifold::OP_SUM);
182 _surf->reduce_on_shared_nodes( A_attr, Manifold::OP_MAXABS);
183 _surf->reduce_on_shared_nodes( sa_attr, Manifold::OP_MAXABS);
186 _surf->reduce_on_shared_nodes( w_attr, Manifold::OP_SUM);
194 for (
int i=0, local_npanes =
_panes.size();
i<local_npanes; ++
i, ++it) {
195 COM::Pane *pane = *it;
199 ( pane->attribute(A_attr->id())->pointer());
201 ( pane->attribute(
_eigvecs->id())->pointer());
203 ( pane->attribute(bm_attr->id())->pointer());
204 double *sa =
reinterpret_cast<double*
>
205 ( pane->attribute(sa_attr->id())->pointer());
208 char *tranks =
reinterpret_cast<char*
>
209 ( pane->attribute(
_tangranks->id())->pointer());
212 for (
int j=0, jn=pane->size_of_real_nodes();
j<jn; ++
j) {
215 if ( bs_m[
j].is_null())
continue;
231 _buf->delete_attribute( sa_attr->name());
232 _buf->init_done(
false);
241 double angle_defect) {
268 COM::Attribute *vcenters_buf =
270 COM::Attribute *vecdiff_buf =
272 _buf->resize_array( vcenters_buf, 0);
273 _buf->resize_array( vecdiff_buf, 0);
276 std::vector< COM::Pane*>::iterator it =
_panes.begin();
277 Manifold::PM_iterator pm_it=
_surf->pm_begin();
279 for (
int i=0, local_npanes =
_panes.size();
i<local_npanes;
280 ++
i, ++it, ++pm_it) {
281 COM::Pane *pane = *it;
282 const std::set< Edge_ID> &eset_pn =
_edges[
i];
285 (pane->attribute(
COM_NC)->pointer());
287 (pane->attribute(vcenters_buf->id())->pointer());
289 (pane->attribute(vecdiff_buf->id())->pointer());
291 for ( std::set< Edge_ID>::const_iterator eit=eset_pn.begin(),
292 eend=eset_pn.end(); eit!=eend; ++eit) {
294 Edge_ID eid = *eit, eid_opp = pm_it->get_opposite_real_edge( eid);
295 bool is_border_edge = pm_it->is_physical_border_edge( eid_opp);
299 int vindex = ene[lid]-1, windex = ene[neighbor]-1;
302 Vector_3 diff = pnts[ windex] - pnts[vindex];
304 if ( vdiff[vindex].is_null()) vdiff[vindex] = diff;
305 else vdiff[vindex] -= diff;
307 if ( is_border_edge) {
309 if ( vdiff[windex].is_null()) vdiff[windex] = -diff;
310 else vdiff[windex] += diff;
315 _surf->reduce_on_shared_nodes( vcenters_buf, Manifold::OP_SUM);
316 _surf->reduce_on_shared_nodes( vecdiff_buf, Manifold::OP_DIFF);
321 for (
int i=0, local_npanes =
_panes.size();
322 i<local_npanes; ++
i, ++it) {
323 COM::Pane *pane = *it;
326 (pane->attribute(vcenters_buf->id())->pointer());
328 (pane->attribute(
_vcenters->id())->pointer());
330 (pane->attribute(vecdiff_buf->id())->pointer());
331 const char *tranks =
reinterpret_cast<const char*
>
332 ( pane->attribute(
_tangranks->id())->pointer());
333 const char *cranks =
reinterpret_cast<const char*
>
335 const char *val_bndry_nodes =
reinterpret_cast<const char*
>
338 for (
int j=0, jn=pane->size_of_real_nodes();
j<jn; ++
j)
if (cranks[
j]!=2) {
341 else if ( val_bndry_nodes && val_bndry_nodes[
j] && !vdiff[
j].is_null()) {
342 vcs_buf[
j] = (vcs_buf[
j]*vdiff[
j]*vdiff[
j])/vdiff[
j].squared_norm();
344 vcs[
j] = (1./4.)*vcs_buf[
j];
349 _buf->delete_attribute( vecdiff_buf->name());
350 _buf->delete_attribute( vcenters_buf->name());
351 _buf->init_done(
false);
360 std::vector< COM::Pane*>::iterator it =
_panes.begin();
361 Manifold::PM_iterator pm_it=
_surf->pm_begin();
362 for (
int i=0, local_npanes =
_panes.size();
363 i<local_npanes; ++
i, ++it, ++pm_it) {
364 COM::Pane *pane = *it;
365 char *tranks =
reinterpret_cast<char*
>
366 ( pane->attribute(
_tangranks->id())->pointer());
367 char *weak =
reinterpret_cast<char*
>
368 ( pane->attribute(
_weak->id())->pointer());
370 ( pane->attribute(
_eigvalues->id())->pointer());
372 for (
int j=0,
nj=pane->size_of_real_nodes();
j<
nj; ++
j) {
373 weak[
j] = tranks[
j]==2 &&
380 _surf->reduce_on_shared_nodes(
_weak, Manifold::OP_MIN);
383 inline double SQR(
double x) {
return (x*x); }
386 void dsytrd3(
double A[3][3],
double Q[3][3],
double d[3],
double e[2])
404 for (
int i=0;
i < 3;
i++)
407 for (
int j=0;
j <
i;
j++)
408 Q[i][
j] = Q[
j][i] = 0.0;
412 h =
SQR(A[0][1]) +
SQR(A[0][2]);
427 for (
int i=1;
i < 3;
i++)
429 f = A[1][
i] * u[1] + A[
i][2] * u[2];
433 K *= 0.5 *
SQR(omega);
435 for (
int i=1;
i < 3;
i++)
436 q[
i] = q[
i] - K * u[
i];
439 d[1] = A[1][1] - 2.0*q[1]*u[1];
440 d[2] = A[2][2] - 2.0*q[2]*u[2];
443 for (
int j=1;
j < 3;
j++)
446 for (
int i=1;
i < 3;
i++)
447 Q[
i][
j] = Q[
i][
j] - f*u[
i];
451 e[1] = A[1][2] - q[1]*u[2] - u[1]*q[2];
455 for (
int i=0;
i < 3;
i++)
462 int dsyevq3(
double A[3][3],
double Q[3][3],
double w[3])
486 double g, r, p, f, b,
s, c, t;
497 for (
int l=0; l < 2; l++)
504 for (m=l; m < 2; m++)
506 g = fabs(w[m])+fabs(w[m+1]);
507 if (fabs(e[m]) + g == g)
517 g = (w[l+1] - w[l]) / (e[l] + e[l]);
520 g = w[m] - w[l] + e[l]/(g + r);
522 g = w[m] - w[l] + e[l]/(g - r);
526 for (
int i=m-1;
i >= l;
i--)
530 if (fabs(f) > fabs(g))
546 r = (w[
i] - g)*s + 2.0*c*b;
552 for (
int k=0;
k < 3;
k++)
555 Q[
k][
i+1] = s*Q[
k][
i] + c*t;
556 Q[
k][
i] = c*Q[
k][
i] - s*t;
574 double abuf[3][3] = { {A[0][0], A[0][1], A[0][2]},
575 {A[1][0], A[1][1], A[1][2]},
576 {A[2][0], A[2][1], A[2][2]}};
588 if ( lambdas[0]<lambdas[1]) {
589 if ( lambdas[1]<lambdas[2]) {
591 A[0] = buf[2]; A[1] = buf[1]; A[2] = buf[0];
594 double t = lambdas[0];
595 lambdas[0] = lambdas[1];
599 lambdas[1] = lambdas[2]; lambdas[2] = t;
600 A[1] = buf[2]; A[2] = buf[0];
604 A[1] = buf[0]; A[2] = buf[2];
608 else if ( lambdas[0]<lambdas[2]) {
609 double t = lambdas[0];
610 lambdas[0] = lambdas[2]; lambdas[2] = lambdas[1]; lambdas[1] = t;
611 A[0] = buf[2]; A[1] = buf[0]; A[2] = buf[1];
615 if ( lambdas[1]<lambdas[2]) {
617 A[1] = buf[2]; A[2] = buf[1];
620 A[1] = buf[1]; A[2] = buf[2];
static void compute_eigenvectors(Vector_3 A[3], Vector_3 &lambdas)
void swap(int &a, int &b)
COM::Attribute * _eigvalues
An adaptor for enumerating node IDs of an element.
#define PROP_END_NAMESPACE
void obtain_face_offset(const Point_3 *pnts, const double *spd_ptr, const COM::Attribute *spd, double dt, const Vector_3 *dirs, COM::Element_node_enumerator &ene, Vector_3 &ns_nz, Point_3 &cnt, Vector_3 *disps, Vector_3 *ns)
#define PROP_BEGIN_NAMESPACE
#define COM_assertion_msg(EX, msg)
COM::Attribute * _vcenters
COM::Attribute * _faceareas
void update_vertex_centers()
COM::Attribute * _tangranks
std::vector< COM::Pane * > _panes
COM::Attribute * _eigvecs
*********************************************************************Illinois Open Source License ****University of Illinois NCSA **Open Source License University of Illinois All rights reserved ****Developed free of to any person **obtaining a copy of this software and associated documentation to deal with the Software without including without limitation the rights to ** copy
COM::Attribute * _facecenters
int size_of_edges() const
Number of edges per element.
void compute_quadrics(double dt, const COM::Attribute *spds, COM::Attribute *rhs, COM::Attribute *predicted)
Compute quadrics for every vertex.
double angle(Vector_3< double > v1, Vector_3< double > v2)
Compute the angle between two vectors.
COM::Attribute * _bmedial
COM::Attribute * _weights
static void div(const Attribute *x, const Attribute *y, Attribute *z)
Operation wrapper for division.
static double eval_angle(const Vector_3 &v1, const Vector_3 &v2)
static void copy_scalar(const void *x, Attribute *y)
Operation wrapper for copy (x is a scalar pointer).
void mark_weak_vertices()
Mark vertices that are weak.
COM::Attribute * _cnstr_bndry_nodes
std::vector< std::set< Edge_ID > > _edges
static void copy(const Attribute *x, Attribute *y)
Wrapper for copy.
COM::Attribute * _vnormals
void next()
Go to the next element within the connectivity tables of a pane.
Some basic geometric data types.
void info()
Print informations about CImg environement variables.
COM::Attribute * _facenormals
COM::Attribute * _ctangranks
int eigen_analyze_vertex(Vector_3 A_io[3], Vector_3 &b_io, double angle_defect=0)