27 #include "../Rocmap/include/Pane_connectivity.h"
28 #include "../Rocmap/include/Pane_communicator.h"
29 #include "../Rocmap/include/Rocmap.h"
30 #include "../Rocblas/include/Rocblas.h"
131 for ( std::vector<Node>::const_iterator
133 if ( it->pane_manifold()) --n;
154 for ( std::vector<Halfedge>::const_iterator
159 else if (hopp.
pane()->id()==
_pane->id()) ++branch;
162 if ( branch) n-=branch/2;
174 "Input to Window_manifold_2::init must be mesh or pmesh");
177 const COM::Window *w = pmesh->window();
180 _buf_window =
new COM::Window(w->name()+
"-buf", w->get_communicator());
181 _buf_window->inherit( const_cast<COM::Attribute*>(pmesh),
"",
182 false,
true, NULL, 0);
185 COM::Attribute *pconn_user =
188 MAP::Pane_connectivity::pconn_nblocks( pconn_user)==0);
191 COM::Attribute *pconn_n = nopconn ?
192 _buf_window->inherit( pconn_user,
"",
true,
true, NULL, 0) :
196 COM::Attribute *pconn_e =
201 std::vector<const COM::Pane*> panes;
204 std::vector<const MAP::Simple_manifold_2*> mani2(panes.size());
207 _pms.resize( panes.size());
208 for (
int i=panes.size()-1;
i>=0; --
i) {
215 int nb =
_pms[
i].size_of_real_border_edges();
216 _pms[
i]._cnt_pn.resize( nb, 0);
220 _pms[
i]._nd_prm.resize( nb+
_pms[i].size_of_isolated_nodes(),
225 if ( !mani2.empty()) {
226 MAP::Pane_connectivity pc( &mani2[0], w->get_communicator());
227 pc.compute_pconn( nopconn?pconn_n:(COM::Attribute*)NULL, pconn_e);
233 MAP::Pane_connectivity pc( pmesh, w->get_communicator());
234 pc.compute_pconn( nopconn?pconn_n:(COM::Attribute*)NULL, pconn_e);
238 _pconn_nb = MAP::Pane_connectivity::pconn_nblocks( pconn_n);
243 const int pconn_offset=MAP::Pane_connectivity::pconn_offset();
245 typedef std::map< std::pair<int,int>,
246 std::pair< const int*, const int*> > B2e_map;
256 for (
int i=0,
n=
_pms.size();
i<
n; ++
i) {
258 const COM::Attribute *pconn_l = pm.
pane()->attribute(pconn_e->id());
259 const int *b2e_l = (
const int*)pconn_l->pointer();
263 for (
int j=pconn_offset,
nj=pconn_l->size_of_real_items();
264 j<
nj;
j+=b2e_l[
j+1]+2) {
266 std::map<int,int>::iterator it=
_pi_map.find( b2e_l[
j]);
267 bool is_remote = it ==
_pi_map.end();
270 int pnid_other = b2e_l[
j];
271 if ( is_remote) pnid_other = -pnid_other;
274 for (
int k=0,
nk=b2e_l[j+1];
k<
nk; ++
k) {
280 if ( is_remote)
continue;
283 int pane_id_r = it->second;
285 if ( pane_id_l <= pane_id_r)
286 bm[ std::make_pair( pane_id_l, pane_id_r)].first = &b2e_l[j+1];
287 if ( pane_id_l >= pane_id_r)
288 bm[ std::make_pair( pane_id_r, pane_id_l)].second = &b2e_l[j+1];
295 for ( B2e_map::const_iterator it=bm.begin(); it!=bm.end(); ++it) {
298 const int *v1 = it->second.first;
299 const int *v2 = it->second.second;
301 int is_branchcut = (it->first.first == it->first.second);
303 "Branch-cut must list nodes in pairs.");
305 for (
int k=1,
nk=*v1;
k<=
nk; ++
k) {
315 if (is_branchcut) ++
k;
325 typedef std::map< std::pair<int,int>,
326 std::pair< const int*, const int*> > B2v_map;
329 const int pconn_offset=MAP::Pane_connectivity::pconn_offset();
331 for (
int i=0,
n=
_pms.size();
i<
n; ++
i) {
332 const COM::Attribute *pconn_l =
_pms[
i].pane()->attribute(pconn_n->id());
333 const int *b2v_l = (
const int*)pconn_l->pointer();
336 for (
int j=pconn_offset,
nj=pconn_l->size_of_real_items();
337 j<
nj;
j+=b2v_l[
j+1]+2) {
339 std::map<int,int>::iterator it=
_pi_map.find( b2v_l[
j]);
340 if ( it ==
_pi_map.end())
continue;
342 int pane_id_r = it->second;
344 if ( pane_id_l <= pane_id_r)
345 bm[ std::make_pair( pane_id_l, pane_id_r)].first = &b2v_l[j+1];
346 if ( pane_id_l >= pane_id_r)
347 bm[ std::make_pair( pane_id_r, pane_id_l)].second = &b2v_l[j+1];
352 for ( B2v_map::const_iterator it=bm.begin(); it!=bm.end(); ++it) {
355 const int *v1 = it->second.first, *v2=it->second.second;
357 int is_branchcut = (it->first.first == it->first.second);
359 "Branch-cut must list nodes in pairs.");
361 for (
int k=1,
nk=*v1;
k<=
nk; ++
k) {
379 if (is_branchcut) ++
k;
400 "Argument must be nodal or elemental attribute");
403 "Argument must be double-precision scalars");
405 if ( lens->is_nodal()) {
416 std::vector< COM:: Pane*> panes;
417 lens->window()-> panes( panes);
418 std::vector< COM::Pane*>::const_iterator it = panes.begin();
424 for (
int i=0, local_npanes = panes.size();
i<local_npanes; ++
i, ++it){
425 const COM::Pane &pane = **it;
428 Real *lp = (
Real *)(pane.attribute( lens->id())->pointer());
432 for (
int j=pane.size_of_elements();
j>0; --
j, ene.
next()) {
434 int uindex = ene[0]-1;
436 int vindex=ene[(
k+1)%ne]-1;
437 double sqlen = (pnts[ uindex]-pnts[ vindex]).squared_norm();
439 lp[uindex] =
std::min( lp[uindex], sqlen);
440 lp[vindex] =
std::min( lp[vindex], sqlen);
441 if ( nn>ne) lp[uindex+ne] =
std::min( lp[uindex+ne], sqlen);
442 if ( nn>ne+ne) lp[uindex+ne+ne] =
std::min( lp[uindex+ne+ne], sqlen);
458 std::vector< COM:: Pane*> panes;
459 lens->window()-> panes( panes);
460 std::vector< COM::Pane*>::const_iterator it = panes.begin();
462 for (
int i=0, local_npanes = panes.size();
i<local_npanes; ++
i, ++it){
463 const COM::Pane &pane = **it;
466 Real *lp = (
Real *)(pane.attribute( lens->id())->pointer());
470 for (
int j=pane.size_of_elements();
j>0; --
j, ene.
next(),++lp) {
471 Real sqlen = HUGE_VAL;
473 int uindex = ene[0]-1;
475 int vindex=ene[(
k+1)%ne]-1;
476 sqlen =
std::min( sqlen, (pnts[ uindex]-pnts[ vindex]).squared_norm());
487 const COM::Attribute *normals_inherited = normals;
494 ( const_cast< COM::Attribute *>(normals),
"facenormals__CNNTEMP",
495 false,
true, NULL, 0);
496 COM::Attribute *nrm=
_buf_window->new_attribute(
"normals__PMTEMP",
498 COM::Attribute *pconn_g=
_buf_window->new_attribute(
"pconn__PMTEMP",
500 COM::Attribute *pconn_e=
_buf_window->attribute(
"pconn_e");
505 COM::Pane *pn =
const_cast<COM::Pane*
>(it->pane());
507 (pn->attribute( normals_inherited->id())->pointer());
509 COM::Attribute *nrm_pn = pn->attribute( nrm->id());
510 int n = it->size_of_real_border_edges();
511 nrm_pn->set_size( n, 0);
512 it->_bd_nrms.resize( n);
515 _buf_window->set_array( nrm->name(), pn->id(), nrms_bd);
517 for (
int i=0;
i<
n; ++
i) {
520 nrms_bd[
i] = nrms_face[eid.eid()-1];
525 it->convert_pconn_edge2ghost( pn->attribute( pconn_e->id()),
526 pn->attribute( pconn_g->id()));
531 MAP::Rocmap::update_ghosts( nrm, pconn_g);
535 if ( normals_inherited != normals)
536 _buf_window->delete_attribute( normals_inherited->name());
542 const COM::Attribute *flags_inherited = flags;
549 ( const_cast< COM::Attribute *>(flags),
"faceflags__CNNTEMP",
550 false,
true, NULL, 0);
551 COM::Attribute *flg=
_buf_window->new_attribute(
"flags__PMTEMP",
553 COM::Attribute *pconn_g=
_buf_window->new_attribute(
"pconn__PMTEMP",
555 COM::Attribute *pconn_e=
_buf_window->attribute(
"pconn_e");
559 COM::Pane *pn =
const_cast<COM::Pane*
>(it->pane());
560 const int *flgs_face =
reinterpret_cast<int *
>
561 (pn->attribute( flags_inherited->id())->pointer());
563 COM::Attribute *flg_pn = pn->attribute( flg->id());
564 int n = it->size_of_real_border_edges();
565 flg_pn->set_size( n, 0);
566 it->_bd_flgs.resize( n);
568 int *flgs_bd = &it->_bd_flgs[0];
569 _buf_window->set_array( flg->name(), pn->id(), flgs_bd);
571 for (
int i=0;
i<
n; ++
i) {
574 flgs_bd[
i] = flgs_face[eid.eid()-1];
578 it->convert_pconn_edge2ghost( pn->attribute( pconn_e->id()),
579 pn->attribute( pconn_g->id()));
584 MAP::Rocmap::update_ghosts( flg, pconn_g);
588 if ( flags_inherited != flags)
589 _buf_window->delete_attribute( flags_inherited->name());
595 const COM::Attribute *bm_inherited = bitmap;
602 ( const_cast< COM::Attribute *>(bitmap),
"facebm__CNNTEMP",
603 false,
true, NULL, 0);
604 COM::Attribute *bm=
_buf_window->new_attribute(
"bm__PMTEMP",
606 COM::Attribute *pconn_g=
_buf_window->new_attribute(
"pconn__PMTEMP",
608 COM::Attribute *pconn_e=
_buf_window->attribute(
"pconn_e");
612 COM::Pane *pn =
const_cast<COM::Pane*
>(it->pane());
613 const char *bms_face =
reinterpret_cast<char *
>
614 (pn->attribute( bm_inherited->id())->pointer());
616 COM::Attribute *bm_pn = pn->attribute( bm->id());
617 int n = it->size_of_real_border_edges();
618 bm_pn->set_size( n, 0);
619 it->_bd_bm.resize( n);
621 char *bms_bd = &it->_bd_bm[0];
622 _buf_window->set_array( bm->name(), pn->id(), bms_bd);
624 for (
int i=0;
i<
n; ++
i) {
627 bms_bd[
i] = bms_face[eid.eid()-1] & (1<<eid.lid());
631 it->convert_pconn_edge2ghost( pn->attribute( pconn_e->id()),
632 pn->attribute( pconn_g->id()));
637 MAP::Rocmap::update_ghosts( bm, pconn_g);
641 if ( bm_inherited != bitmap)
642 _buf_window->delete_attribute( bm_inherited->name());
649 const COM::Attribute *vals_inherited = vals;
653 ( const_cast< COM::Attribute *>(vals),
"vals__CNNTEMP",
false,
true, NULL, 0);
654 COM::Attribute *buf=
_buf_window->new_attribute(
"buf__PMTEMP",
'p',
655 vals->data_type(), 1,
"");
656 COM::Attribute *pconn_g=
_buf_window->new_attribute(
"pconn__PMTEMP",
658 COM::Attribute *pconn_e=
_buf_window->attribute(
"pconn_e");
664 COM::Pane *pn =
const_cast<COM::Pane*
>(it->pane());
665 const char *vals_face =
reinterpret_cast<char *
>
666 (pn->attribute( vals_inherited->id())->pointer());
668 COM::Attribute *buf_pn = pn->attribute( buf->id());
669 int n = it->size_of_real_border_edges();
670 buf_pn->set_size( n, 0);
673 _buf_window->resize_array( buf->name(), pn->id(), (
void**)&val_bd);
675 for (
int i=0;
i<
n; ++
i) {
679 std::copy( &vals_face[(fid-1)*size_base_type],
680 &vals_face[fid*size_base_type], &val_bd[
i*size_base_type]);
684 it->convert_pconn_edge2ghost( pn->attribute( pconn_e->id()),
685 pn->attribute( pconn_g->id()));
690 MAP::Rocmap::update_ghosts( buf, pconn_g);
694 COM::Pane *pn =
const_cast<COM::Pane*
>(it->pane());
695 char *vals_face =
reinterpret_cast<char *
>
696 (pn->attribute( vals_inherited->id())->pointer());
698 int n = it->size_of_real_border_edges();
700 COM::Window::Pointer_descriptor ptr(NULL);
701 _buf_window->get_array( buf->name(), pn->id(), ptr);
702 char *val_bd = (
char*)ptr.ptr;
707 switch (vals->data_type()) {
708 case COM_CHAR: vals_face[eid.eid()-1] += val_bd[
i];
break;
711 (
int&)vals_face[(eid.eid()-1)*size_base_type] +=
712 (
int&)val_bd[
i*size_base_type];
break;
715 (
float&)vals_face[(eid.eid()-1)*size_base_type] +=
716 (
float&)val_bd[
i*size_base_type];
break;
719 (
double&)vals_face[(eid.eid()-1)*size_base_type] +=
720 (
double&)val_bd[
i*size_base_type];
break;
729 if ( vals_inherited != vals)
730 _buf_window->delete_attribute( vals_inherited->name());
736 COM::Attribute *pconn_g) {
737 const int *b2e_l = (
const int*)pconn_e->pointer();
739 int n=pconn_e->size_of_items();
740 pconn_g->set_size( n+n+1, n+n);
741 int *buf = (
int*)pconn_g->allocate( 1, n+n+1,
true);
747 for (
int j=1;
j<
n;
j+=b2e_l[
j+1]+2) {
749 buf[
j+2] = b2e_l[
j+1];
752 for (
int k=0,
nk=b2e_l[
j+1];
k<
nk; ++
k) {
759 std::copy( &buf[1], &buf[n+1], &buf[n+1]);
767 const COM::Attribute *weights) {
769 "Weights for elemental normals must be elemental");
773 COM::Attribute *nodal_normals;
775 nodal_normals =
_buf_window->inherit( nrms,
"nodal_normals__CNNTEMP",
776 false,
true, NULL, 0);
778 nodal_normals = nrms;
781 new_attribute(
"elem_normals__CNNTEMP",
'e',
COM_DOUBLE, 3,
"");
797 std::vector<COM::Pane*>::iterator it=
_cc->panes().begin();
798 for (
int i=0,
n=
_cc->panes().size();
i<
n; ++
i, ++it) {
799 int nnodes = (*it)->size_of_real_nodes();
802 for (
int j=0;
j<nnodes; ++
j)
808 _buf_window->delete_attribute( elem_normals->name());
810 _buf_window->delete_attribute( nodal_normals->name());
817 COM::Attribute *n_vals,
819 const COM::Attribute *e_weights,
820 COM::Attribute *n_weights,
823 "First argument must be elemental attribute");
825 "Second argument must be nodal attribute");
827 e_weights && e_weights->is_elemental(),
828 "Third argument must be elemental attribute");
831 "Output weights must be nodal with double precision");
834 COM::Attribute *nodal_vals;
836 nodal_vals =
_buf_window->inherit( n_vals,
"nodal_vals__E2NTEMP",
837 false,
true, NULL, 0);
841 const COM::Attribute *elem_vals;
844 ( const_cast<COM::Attribute*>(e_vals),
"elem_vals__E2NTEMP",
845 false,
true, NULL, 0);
850 COM::Attribute *nodal_weights;
851 if ( n_weights && n_weights->window()!=
_buf_window)
852 nodal_weights =
_buf_window->inherit( n_weights,
"nodal_weights__E2NTEMP",
853 false,
true, NULL, 0);
855 nodal_weights =
_buf_window->new_attribute(
"nodal_weights__E2NTEMP",
'n',
860 const COM::Attribute *elem_weights;
861 if ( e_weights && e_weights->window()!=
_buf_window)
863 ( const_cast<COM::Attribute*>(e_weights),
"elem_weights__E2NTEMP",
864 false,
true, NULL, 0);
866 elem_weights = e_weights;
871 int local_npanes =
_cc->panes().size();
874 std::vector< Real*> weights_ptrs(local_npanes);
875 std::vector< int> weights_strds(local_npanes);
877 int ncomp = nodal_vals->size_of_components();
879 "Numbers of components must match");
881 for (
int i=0;
i<local_npanes; ++
i) {
882 int nn=
_cc->panes()[
i]->size_of_real_nodes();
885 COM::Attribute *a =
_cc->panes()[
i]->attribute(nodal_weights->id());
886 p = weights_ptrs[
i] =
reinterpret_cast<Real*
>(a->pointer());
887 strd = weights_strds[
i] = a->stride();
890 for (
int k=0;
k<nn; ++
k, p+=strd) *p = 0.;
903 std::vector< COM::Pane*>::const_iterator it=
_cc->panes().begin();
904 for (
int i=0;
i<local_npanes; ++
i, ++it) {
905 COM::Pane &pane = **it;
908 (pane.coordinates());
909 const COM::Attribute *elem_vals_pane =
910 pane.attribute( elem_vals->id());
911 const COM::Attribute *elem_weights_pane =
912 elem_weights ? pane.attribute( elem_weights->id()) : NULL;
913 COM::Attribute *nodal_vals_pane =
914 pane.attribute( nodal_vals->id());
917 for (
int d=1;
d<=ncomp; ++
d) {
918 COM::Attribute *nvpi = ncomp==1?nodal_vals_pane:(nodal_vals_pane+
d);
919 Real *p=
reinterpret_cast<Real*
>(nvpi->pointer());
920 for (
int j=0,
s=nvpi->stride(),
n=nvpi->size_of_real_items()*
s;
j<
n;
j+=
s)
926 for (
int j=pane.size_of_real_elements();
j>0; --
j, ene.
next()) {
927 ps.
set( pnts, ene, 1);
928 elem_vals_evk.
set( elem_vals_pane, ene);
929 nodal_vals_evk.
set( nodal_vals_pane, ene);
930 nodal_weights_evk.
set( weights_ptrs[
i], ene, weights_strds[i]);
940 elem_weights_evk.
set( elem_weights_pane, ene);
941 w = elem_weights_evk[0];
953 for (
int k=0;
k<nn; ++
k)
954 nodal_weights_evk[
k] += w;
957 for (
int d=0;
d<ncomp; ++
d) {
958 Real t = w*elem_vals_evk(0,
d);
959 for (
int k=0;
k<nn; ++
k)
960 nodal_vals_evk(
k,
d) += t;
966 for (
int k=0;
k<ne; ++
k) {
967 J[0] = ps[
k==ne-1?0:k+1]-ps[
k]; J[1] = ps[k?k-1:ne-1]-ps[
k];
968 double s =
std::sqrt((J[0]*J[0])*(J[1]*J[1]));
970 double cosw = J[0]*J[1]/
s;
971 if (cosw>1) cosw=1;
else if ( cosw<-1) cosw=-1;
978 nodal_weights_evk[
k] += w;
981 for (
int d=0;
d<ncomp; ++
d)
982 nodal_vals_evk(k,
d) += w*elem_vals_evk(0,
d);
985 for (
int k=ne;
k<nn; ++
k) {
987 nodal_weights_evk[
k] += 1;
990 for (
int d=0;
d<ncomp; ++
d)
991 nodal_vals_evk(
k,
d) += elem_vals_evk(0,
d);
1005 _cc->init( &(
void*&)weights_ptrs[0],
COM_DOUBLE, 1, NULL, NULL);
1006 _cc->begin_update_shared_nodes();
1008 _cc->end_update_shared_nodes();
1012 it=
_cc->panes().begin();
1013 for (
int i=0;
i<local_npanes; ++
i, ++it) {
1014 COM::Pane &pane = **it;
1015 COM::Attribute *nodal_vals_pane = pane.attribute( nodal_vals->id());
1017 for (
int d=1;
d<=ncomp; ++
d) {
1018 COM::Attribute *nvpi = ncomp==1?nodal_vals_pane:(nodal_vals_pane+
d);
1019 Real *
v=
reinterpret_cast<Real*
>(nvpi->pointer());
1020 Real *w = weights_ptrs[
i];
1021 for (
int j=0,js=nvpi->stride(),
n=nvpi->size_of_real_items()*js,
1022 k=0, ks=weights_strds[
i];
j<
n;
j+=js, k+=ks) {
1024 std::cout <<
"***Rocsurf Error: Got zero weight for node "
1025 <<
j+1 <<
" in pane " << pane.id() << std::endl;
1027 if ( w[k] == 0) v[
j] = 0;
1035 if ( elem_weights != e_weights)
1036 _buf_window->delete_attribute( elem_weights->name());
1037 _buf_window->delete_attribute( nodal_weights->name());
1038 if ( elem_vals != e_vals)
1039 _buf_window->delete_attribute( elem_vals->name());
1040 if (nodal_vals != n_vals)
1041 _buf_window->delete_attribute( nodal_vals->name());
1047 bool to_normalize) {
1050 "Normal must have three components");
1052 "Base type of Normal must be double precision");
1054 if ( normal->is_nodal()) {
1059 "Normal must be nodal or elemental");
1060 int to_nrm = to_normalize;
1067 COM::Attribute *nrm=
_buf_window->new_attribute(
"normals__PMTEMP",
1071 COM::Attribute *rnd=
_buf_window->new_attribute(
"randoms__PMTEMP",
1075 COM::Attribute *lens=
_buf_window->new_attribute(
"lengths__PMTEMP",
1082 double dbl_range=range*2;
1108 COM::Attribute *attr_inherited = attr;
1111 attr_inherited =
_buf_window->inherit(attr,
"SuRf_ReDuCe_On_ShArEd_TeMp__",
1112 COM::Pane::INHERIT_USE,
true, NULL, 0);
1115 _cc->init( attr_inherited);
1116 _cc->begin_update_shared_nodes();
1118 _cc->reduce_maxabs_on_shared_nodes();
1120 _cc->reduce_diff_on_shared_nodes();
1122 _cc->reduce_on_shared_nodes( op);
1123 _cc->end_update_shared_nodes();
1125 if ( attr_inherited != attr) {
1126 _buf_window->delete_attribute( attr_inherited->name());
1136 for ( ; it !=
iend; ++it) {
1137 n += it->size_of_nodes( mode);
1147 for ( ; it !=
iend; ++it) {
1148 n += it->size_of_faces( mode);
1159 for ( ; it !=
iend; ++it) {
1160 n += it->size_of_triangles( mode);
1171 for ( ; it !=
iend; ++it) {
1172 n += it->size_of_quadrilaterals( mode);
1183 for ( ; it !=
iend; ++it) {
1184 n += it->size_of_edges( mode);
1195 const COM::Attribute *
attr;
1197 const COM::Pane *pn =
_pm->
pane();
1199 if ( a->pane()->id() == pid)
1202 if ( a->window() != pn->window()) {
1203 pn = &a->window()->pane( pid);
1206 attr=pn->attribute( a->id());
1210 return ((
const char*)attr->pointer()) +
1220 const COM::Attribute *
attr;
1222 const COM::Pane *pn =
_pm->
pane();
1224 if ( a->pane()->id() == pid)
1227 if ( a->window() != pn->window()) {
1228 pn = &a->window()->pane( pid);
1231 attr=pn->attribute( a->id());
1235 return ((
const char*)attr->pointer()) +
1265 const COM::Attribute *disp)
1280 }
while ( (hit=hit.
next()) != h);
1298 const double pi=3.14159265358979;
1306 double cos_a = normals[0]*normals[1]
1307 /
std::sqrt( (normals[0]*normals[0])*(normals[1]*normals[1]));
1310 if ( cos_a>1) cos_a=1;
1311 if ( cos_a<-1) cos_a=-1;
1321 std::map<int, std::vector<int>*> maps;
1323 for (
int i=0; it!=
iend; ++it, ++
i) {
1324 gids[
i].resize( it->size_of_real_nodes(), 0);
1325 maps[it->pane()->id()] = &gids[
i];
1332 for (
int i=0; it!=
iend; ++it, ++
i) {
1333 for (
int v=0, nv=it->size_of_real_nodes();
v<nv; ++
v) {
1334 if ( it->is_primary(
v+1, mode))
1342 for (
int i=0; it!=
iend; ++it, ++
i) {
1343 for (
int v=0, nv=it->size_of_real_nodes();
v<nv; ++
v) {
1344 if (gids[
i][
v]==0) {
1347 gids[
i][
v] = (*maps[nd.
pane()->id()])[nd.
id()-1];
1355 outwin->delete_pane(0);
1358 std::vector<std::vector<int> > nodes_gids;
1364 outwin->set_size(
"nc", 1, nnodes);
1367 outwin->resize_array(
"nc",1,(
void**)&coors);
1373 for ( ; it!=
iend; ++it) {
1374 const COM::Pane &pn = *it->pane();
1375 const double *p = pn.coordinates();
1377 for (
int i=0, nn=pn.size_of_real_nodes();
i<nn; ++
i) {
1378 if ( it->is_primary(
i+1, mode)) {
1379 std::copy( &p[3*
i], &p[3*i+3], &coors[3*gid]);
1389 outwin->resize_array(
":t3:", 1, (
void**)&tris);
1393 int fn=it->size_of_faces(
REAL_PANE);
if ( fn==0)
continue;
1397 for (
int f=0; f<fn; ++f, ++
k, ene.next()) {
1398 for (
int j=0;
j<3; ++
j) {
1399 tris[3*k+
j] = nodes_gids[
i][ene[
j]-1];
1404 outwin->init_done();
int size_of_panes() const
Obtain the number of panes.
void update_bd_normals(const COM::Attribute *normals, bool to_normalize=false)
Update the normals for border faces.
#define COM_assertion(EX)
Error checking utility similar to the assert macro of the C language.
Pane_manifold_2()
Default constructors.
PM_iterator pm_begin()
Obtain an iterator to the first pane manifold of the window.
An adaptor for enumerating node IDs of an element.
int size_of_edges() const
Number of edges of the pane.
bool is_real_border_edge(const Edge_ID &eID) const
Determine whether a given edge is a border edge of real part of the pane (either on physical border o...
This class encapsulate a node over a window manifold.
int size_of_faces(Access_Mode mode) const
Obtain the number of faces.
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
int size_of_triangles(Access_Mode mode) const
Obtain the number of triangles.
MAP::Pane_communicator * _cc
COM::Window * _buf_window
Vector_3< Real > deformed_normal(const COM::Attribute *disp) const
Get the normal of the deformed shape (coordinates plus given displacements) of the incident facet of ...
#define COM_assertion_msg(EX, msg)
std::vector< int > _cnt_pn
void elements_to_nodes(const COM::Attribute *evals, COM::Attribute *nvals, const int scheme=E2N_ONE, const COM::Attribute *ews=NULL, COM::Attribute *nws=NULL, const int tosum=false)
Convert element values to nodal values using weighted averaging.
#define SURF_END_NAMESPACE
const COM::Pane * pane() const
Obtain a const pointer to the pane.
int id() const
Obtain the node ID within its Pane_manifold_2.
void convert_pconn_edge2ghost(const COM::Attribute *pconn_e, COM::Attribute *pconn_g)
Convert from edge-based pconn to a ghost-node-style pconn for a pane attribute.
Halfedge get_prev_edge(Edge_ID, Access_Mode mode) const
Obtain the previous edge in a given access mode.
Halfedge opposite() const
Get the ID of the opposite edge of a given edge.
Halfedge get_next_edge(Edge_ID, Access_Mode mode) const
Obtain the next edge in a given access mode.
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
bool is_physical_border() const
Is the edge on the physical boundary?
Encapsulation of the element-wise computations for two-dimensional elements.
Halfedge prev() const
Get the previous halfedge of its owner element.
int size_of_real_nodes() const
Number of real nodes of the pane.
This class encapsulate a halfedge over a window manifold.
Edge_ID id() const
Obtain the ID of the edge.
std::vector< Pane_manifold_2 >::const_iterator PM_const_iterator
int size_of_edges(Access_Mode mode) const
Obtain the number of edges.
void init(const COM::Attribute *pmesh)
Initialize the manifold by inheriting the given mesh.
Halfedge next() const
Get the next halfedge of its owner element.
const void * addr(const COM::Attribute *attr) const
Obtain the address of an attribute associated with its bounded element.
int get_border_edgeID(Edge_ID eID) const
Get the border edge index. Return -1 if not a border edge.
void set(Value *p, Element_node_enumerator &ene, int strd)
int eid() const
Element ID of the halfedge.
const COM::Attribute * attr(const COM::Attribute *a) const
Obtain the attribute on the parent pane of the node.
std::map< int, int > _pi_map
Node get_primary() const
Get the primary copy of the node.
~Pane_manifold_2()
Destructor.
Edge_ID get_opposite_real_edge(const Edge_ID &eID) const
Get the ID of the opposite real edge of a given real or border edge.
*********************************************************************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 and or **sell copies of the and to permit persons to whom the **Software is furnished to do subject to the following this list of conditions and the following disclaimers ****Redistributions in binary form must reproduce the above **copyright this list of conditions and the following **disclaimers in the documentation and or other materials **provided with the distribution ****Neither the names of the Center for Simulation of Advanced the University of nor the names of its **contributors may be used to endorse or promote products derived **from this Software without specific prior written permission ****THE SOFTWARE IS PROVIDED AS 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 v
std::vector< Pane_manifold_2 >::iterator PM_iterator
Vector_3< Real > get_normal(const Halfedge &h, const Vector_2< Real > &nc)
Get the face normal of a point in the element incident on h.
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_BAND INTEGER MPI_BOR
#define SURF_BEGIN_NAMESPACE
Vector_3< Real > normal() const
Get the normal of the incident facet.
This is a helper class for accessing nodal data.
*********************************************************************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
bool is_isolated() const
Is the node isolated?
static void add(const Attribute *x, const Attribute *y, Attribute *z)
Operation wrapper for addition.
void reduce_on_shared_nodes(COM::Attribute *attr, MPI_Op op)
Perform reduction over a given nodal attributes.
static void compute_shortest_edgelen_elements(COM::Attribute *lens)
Obtain shortest edge length of incident edges of each element.
const Pane_manifold_2 * _pm
**********************************************************************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
int size_of_quadrilaterals(Access_Mode mode) const
Obtain the number of quadrilaterals.
void determine_primaries(const COM::Attribute *pconn_n)
Determine the primary nodes for across-pane access.
void assign_global_nodeIDs(std::vector< std::vector< int > > &gids) const
void update_bdedge_bitmap(const COM::Attribute *bitmap)
Update bitmap for border edges.
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_LAND
int size_of_edges() const
Number of edges per element.
int COM_compatible_types(COM_Type type1, COM_Type type2)
void set(const Value *p, Element_node_enumerator &ene, int strd)
initialize the accessor with a pointer and a specific stride.
void accumulate_bd_values(const COM::Attribute *vals)
Accumulate the values for border faces.
Vector_3< Real > get_deformed_normal(const Halfedge &h, const Vector_2< Real > &nc, const COM::Attribute *disp)
Get the normal of the deformed shape (coordinates plus given displacements) of the incident facet of ...
void update_bd_flags(const COM::Attribute *flags)
Update the flags for border faces.
void shortest_edge_length(COM::Attribute *lens)
Obtain shortest edge length of incident edges of each node or element.
This is a helper class for accessing elemental data.
int size_of_nodes() const
Number of nodes per element.
Type squared_norm() const
Provides a data structure accessing nodes, elements, and edges in a pane, in a manner similar to the ...
const COM::Attribute * attr(const COM::Attribute *a) const
Obtain the attribute on the parent pane of the node.
static Vector_3 cross_product(const Vector_3 &v, const Vector_3 &w)
int COM_get_sizeof(const COM_Type type, int c)
Edge_ID get_next_real_edge(const Edge_ID &eID) const
Get the ID of the next real edge of the element or along the boundary.
std::vector< Node > _nd_prm
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_BAND INTEGER MPI_LOR
const void * addr(const COM::Attribute *attr) const
Obtain the address of an attribute associated with the node.
Edge_ID get_prev_edge(const Edge_ID &eID) const
Get the ID of the previous edge of the element or along the boundary.
Vector_n min(const Array_n_const &v1, const Array_n_const &v2)
static void compute_element_normals(COM::Attribute *nrm, const int *to_normalize=NULL, const COM::Attribute *pnts=NULL)
Computes elemental normals of a given window.
void determine_counterparts(const COM::Attribute *pconn_e)
Determine the counterparts of pane-border edges for across-pane access.
bool is_border() const
Is the edge a border edge?
static void copy_scalar(const void *x, Attribute *y)
Operation wrapper for copy (x is a scalar pointer).
int size_of_nodes() const
Number of nodes of the pane.
void compute_normals(COM::Attribute *normals, int scheme=E2N_ANGLE, bool to_normalize=true)
Compute the normals at nodes or faces, depending on the type of the attribute normals.
Halfedge get_opposite_edge(Edge_ID, Access_Mode mode) const
Obtain the opposite edge in a given access mode.
void init_communicator()
Initialize a pane communicator.
void serialize_window(COM::Window *outwin) const
Create a serial window (with single pane) from the current window.
std::vector< Halfedge > _bd_cnt
static void rand_scalar(const void *a, Attribute *z)
Generate a random number between 0 and $a$ for each entry in z.
const Point_3< Real > & point() const
Obtain the coordinates of a node.
const Pane_manifold_2 * pane_manifold() const
Obtain the pane manifold that owns the edge.
void set(const Value *p, Element_node_enumerator &ene, int strd)
initialize the accessor with a pointer and a specific stride.
int size_of_real_edges() const
Number of real edges of the pane.
The ID of a facet (edge in 2D and face in 3D) encodes an element ID and the local facet's ID internal...
const COM::Pane * pane() const
Obtain the owner Pane_manifold_2 of the node.
int size_of_real_border_edges() const
Number of border edges of the real part of the pane.
void Jacobian(const Field &f, const Nat_coor &nc, Vector_3 J[2]) const
Evaluates the Jacobian at a given point.
CImg< _cimg_Tfloat > acos(const CImg< T > &instance)
void next()
Go to the next element within the connectivity tables of a pane.
double dihedral_angle() const
Return the dihedral angle at the edge.
Edge_ID get_prev_real_edge(const Edge_ID &eID) const
Get the ID of the previous real edge of the element or along the boundary.
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_PROD
This class implements a data structure for 2-manifold on each pane.
PM_iterator pm_end()
Obtain an iterator to the past-the-last pane manifold of the window.
Node origin() const
Obtain the (primary copy of the) origin of the edge.
static void sqrt(const Attribute *x, Attribute *y)
Wrapper for sqrt (y=sqrt(x)).
const Vector_3< Real > & get_bd_normal(Edge_ID) const
Obtain normal of incident face of border edge.
const Pane_manifold_2 * _pm
void compute_nodal_normals(COM::Attribute *nrm, int scheme=E2N_ANGLE, bool to_normalize=true, const COM::Attribute *weights=NULL)
Compute nodal normals using one of the following weighting schemes: E2N_ONE, E2N_AREA, and E2N_ANGLE, and E2N_USER.
void compute_shortest_edgelen_nodes(COM::Attribute *lens)
Obtain shortest edge length of incident edges of each nodes.
std::vector< Pane_manifold_2 > _pms
bool is_border() const
Determines whether the facet is on border.
int size_of_nodes(Access_Mode mode) const
Obtain the number of nodes (shared nodes are counted only once.
int get_bnode_index(int vID) const
Obtain the border node index (equal to ID of incident border edge).
Edge_ID get_next_edge(const Edge_ID &eID) const
Get the ID of the next edge of the element or along the boundary.
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_SUM
Halfedge halfedge() const
Get an incident halfedge originated from the node.
void perturb_mesh(double range)
Perturb the given mesh along its normal direction by length equal to a random number between -range a...
const COM::Pane * pane() const
Obtain the owner Pane_manifold_2 of the node.
static void mul(const Attribute *x, const Attribute *y, Attribute *z)
Operation wrapper for multiplication.
static void sub_scalar(const Attribute *x, const void *y, Attribute *z, int swap=0)
Operation wrapper for subtraction with y as a scalar pointer.