/** * @brief AsyncServer框架要求实现的接口之一。 * */ int init_service(int isparent) { if (!isparent) { setup_timer(); init_communicator(); init_funcs(); } return 0; }
// Evaluate nodal normals void Window_manifold_2:: compute_nodal_normals( COM::DataItem *nrms, int scheme, bool to_normalize, const COM::DataItem *weights) { COM_assertion_msg( weights==NULL || weights->is_elemental(), "Weights for elemental normals must be elemental"); if ( _cc==NULL) init_communicator(); // Inherit normals onto the window COM::DataItem *nodal_normals; if ( nrms->window() != _buf_window) nodal_normals = _buf_window->inherit( nrms, "nodal_normals__CNNTEMP", false, true, NULL, 0); else nodal_normals = nrms; COM::DataItem *elem_normals = _buf_window-> new_dataitem( "elem_normals__CNNTEMP", 'e', COM_DOUBLE, 3, ""); _buf_window->resize_array( elem_normals, NULL); _buf_window->init_done(); if ( scheme == E2N_AREA) { int normalize=false; Rocsurf::compute_element_normals( elem_normals, &normalize); elements_to_nodes( elem_normals, nodal_normals, E2N_ONE, NULL, NULL, true); } else { Rocsurf::compute_element_normals( elem_normals); elements_to_nodes( elem_normals, nodal_normals, scheme, weights); } // Normalize the vectors if ( to_normalize) { std::vector<COM::Pane*>::iterator it=_cc->panes().begin(); for (int i=0, n=_cc->panes().size(); i<n; ++i, ++it) { int nnodes = (*it)->size_of_real_nodes(); Vector_3<double>* ptrs = (Vector_3<double>*)(*it)->dataitem(nodal_normals->id())->pointer(); for ( int j=0; j<nnodes; ++j) ptrs[j].normalize(); } } // Deallocate buffer in reverse order _buf_window->delete_dataitem( elem_normals->name()); if ( nrms->window() != _buf_window) _buf_window->delete_dataitem( nodal_normals->name()); _buf_window->init_done( false); }
// Convert elemental values to nodal values. void Window_manifold_2:: elements_to_nodes( const COM::DataItem *e_vals, COM::DataItem *n_vals, const int scheme, const COM::DataItem *e_weights, COM::DataItem *n_weights, const int tosum) { COM_assertion_msg( e_vals && e_vals->is_elemental(), "First argument must be elemental dataitem"); COM_assertion_msg( n_vals && n_vals->is_nodal(), "Second argument must be nodal dataitem"); COM_assertion_msg( scheme!=E2N_USER || e_weights && e_weights->is_elemental(), "Third argument must be elemental dataitem"); COM_assertion_msg( !n_weights || n_weights->is_nodal() && COM_compatible_types(COM_DOUBLE, n_weights->data_type()), "Output weights must be nodal with double precision"); // Inherit nodal and elemental values onto the window COM::DataItem *nodal_vals; if ( n_vals->window() != _buf_window) nodal_vals = _buf_window->inherit( n_vals, "nodal_vals__E2NTEMP", false, true, NULL, 0); else nodal_vals = n_vals; const COM::DataItem *elem_vals; if ( e_vals->window() != _buf_window) elem_vals = _buf_window->inherit ( const_cast<COM::DataItem*>(e_vals), "elem_vals__E2NTEMP", false, true, NULL, 0); else elem_vals = e_vals; // Inherit nodal and elemental weights onto the window COM::DataItem *nodal_weights; if ( n_weights && n_weights->window()!=_buf_window) nodal_weights = _buf_window->inherit( n_weights, "nodal_weights__E2NTEMP", false, true, NULL, 0); else { nodal_weights = _buf_window->new_dataitem( "nodal_weights__E2NTEMP", 'n', COM_DOUBLE, 1, ""); _buf_window->resize_array( nodal_weights, NULL); } const COM::DataItem *elem_weights; if ( e_weights && e_weights->window()!=_buf_window) elem_weights = _buf_window->inherit ( const_cast<COM::DataItem*>(e_weights), "elem_weights__E2NTEMP", false, true, NULL, 0); else elem_weights = e_weights; _buf_window->init_done( false); // Initialize communicator if ( _cc==NULL) init_communicator(); int local_npanes = _cc->panes().size(); // Initialize buffer spaces for nodal weights. std::vector< Real*> weights_ptrs(local_npanes); std::vector< int> weights_strds(local_npanes); int ncomp = nodal_vals->size_of_components(); COM_assertion_msg( elem_vals->size_of_components()==ncomp, "Numbers of components must match"); for (int i=0; i<local_npanes; ++i) { int nn=_cc->panes()[i]->size_of_real_nodes(); Real *p; int strd; COM::DataItem *a = _cc->panes()[i]->dataitem(nodal_weights->id()); p = weights_ptrs[i] = reinterpret_cast<Real*>(a->pointer()); strd = weights_strds[i] = a->stride(); // Initialize values to 0. for ( int k=0; k<nn; ++k, p+=strd) *p = 0.; } Vector_3<Real> J[2]; Vector_2<Real> nc(0.5,0.5); Element_node_vectors_k_const<Point_3<Real> > ps; Element_vectors_k_const<Real> elem_vals_evk; Element_node_vectors_k<Real> nodal_vals_evk; Element_vectors_k_const<Real> elem_weights_evk; Element_node_vectors_k<Real> nodal_weights_evk; // Compute nodal sums and weights on each processor std::vector< COM::Pane*>::const_iterator it=_cc->panes().begin(); for (int i=0; i<local_npanes; ++i, ++it) { // Loop through the panes COM::Pane &pane = **it; const Point_3<Real> *pnts = reinterpret_cast<const Point_3<Real>*> (pane.coordinates()); const COM::DataItem *elem_vals_pane = pane.dataitem( elem_vals->id()); const COM::DataItem *elem_weights_pane = elem_weights ? pane.dataitem( elem_weights->id()) : NULL; COM::DataItem *nodal_vals_pane = pane.dataitem( nodal_vals->id()); // Initialize values of nodal_vals_pane to 0. for ( int d=1; d<=ncomp; ++d) { COM::DataItem *nvpi = ncomp==1?nodal_vals_pane:(nodal_vals_pane+d); Real *p=reinterpret_cast<Real*>(nvpi->pointer()); for ( int j=0,s=nvpi->stride(),n=nvpi->size_of_real_items()*s; j<n; j+=s) p[j] = 0.; } // Loop through the elements of the pane Element_node_enumerator ene( &pane, 1); for ( int j=pane.size_of_real_elements(); j>0; --j, ene.next()) { ps.set( pnts, ene, 1); elem_vals_evk.set( elem_vals_pane, ene); nodal_vals_evk.set( nodal_vals_pane, ene); nodal_weights_evk.set( weights_ptrs[i], ene, weights_strds[i]); int ne=ene.size_of_edges(); int nn=ene.size_of_nodes(); Real w = 1.; switch ( scheme) { case E2N_USER: case E2N_AREA: if ( scheme == E2N_USER) { // Use user specified weights. elem_weights_evk.set( elem_weights_pane, ene); w = elem_weights_evk[0]; } // Continue to the case of E2N_ONE else { Generic_element_2 e(ne, nn); e.Jacobian( ps, nc, J); const Vector_3<Real> v = Vector_3<Real>::cross_product( J[0], J[1]); w = std::sqrt(v.squared_norm()); if ( ne==3) w*=0.5; } // Continue to the case of E2N_ONE case E2N_ONE: { // Update nodal weights for ( int k=0; k<nn; ++k) nodal_weights_evk[k] += w; // Update nodal sums for ( int d=0; d<ncomp; ++d) { Real t = w*elem_vals_evk(0,d); for ( int k=0; k<nn; ++k) nodal_vals_evk(k,d) += t; } break; } case E2N_ANGLE: case E2N_SPHERE: { for ( int k=0; k<ne; ++k) { J[0] = ps[k==ne-1?0:k+1]-ps[k]; J[1] = ps[k?k-1:ne-1]-ps[k]; double s = std::sqrt((J[0]*J[0])*(J[1]*J[1])); if ( s>0) { double cosw = J[0]*J[1]/s; if (cosw>1) cosw=1; else if ( cosw<-1) cosw=-1; w = std::acos( cosw); if ( scheme==SURF::E2N_SPHERE) w = std::sin(w)/s; // Update nodal weights nodal_weights_evk[k] += w; // Update nodal sums for ( int d=0; d<ncomp; ++d) nodal_vals_evk(k,d) += w*elem_vals_evk(0,d); } } for ( int k=ne; k<nn; ++k) { // Update nodal weights nodal_weights_evk[k] += 1; // Update nodal sums for ( int d=0; d<ncomp; ++d) nodal_vals_evk(k,d) += elem_vals_evk(0,d); } break; } default: COM_assertion_msg(false, "Should never reach here"); } } } // Performan reductions on shared nodes for nodal sums reduce_on_shared_nodes( nodal_vals, OP_SUM); // Performan reductions on shared nodes for nodal weights _cc->init( &(void*&)weights_ptrs[0], COM_DOUBLE, 1, NULL, NULL); _cc->begin_update_shared_nodes(); _cc->reduce_on_shared_nodes( MPI_SUM); _cc->end_update_shared_nodes(); if ( !tosum) { // Divide nodal sums by weights on each processor it=_cc->panes().begin(); for (int i=0; i<local_npanes; ++i, ++it) { // Loop through the panes COM::Pane &pane = **it; COM::DataItem *nodal_vals_pane = pane.dataitem( nodal_vals->id()); for ( int d=1; d<=ncomp; ++d) { COM::DataItem *nvpi = ncomp==1?nodal_vals_pane:(nodal_vals_pane+d); Real *v=reinterpret_cast<Real*>(nvpi->pointer()); Real *w = weights_ptrs[i]; for ( int j=0,js=nvpi->stride(),n=nvpi->size_of_real_items()*js, k=0, ks=weights_strds[i]; j<n; j+=js, k+=ks) { if ( w[k]==0) { std::cout << "***Rocsurf Error: Got zero weight for node " << j+1 << " in pane " << pane.id() << std::endl; } if ( w[k] == 0) v[j] = 0; else v[j] /= w[k]; } } } } // Delete the temporary dataitems in reverse order. if ( elem_weights != e_weights) _buf_window->delete_dataitem( elem_weights->name()); _buf_window->delete_dataitem( nodal_weights->name()); if ( elem_vals != e_vals) _buf_window->delete_dataitem( elem_vals->name()); if (nodal_vals != n_vals) _buf_window->delete_dataitem( nodal_vals->name()); _buf_window->init_done( false); }