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.