Esempio n. 1
0
/**
  * @brief AsyncServer框架要求实现的接口之一。 
  *
  */
int  init_service(int isparent)
{
	if (!isparent) {
		setup_timer();
		init_communicator();
		init_funcs();
	}

	return 0;
}
Esempio n. 2
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);
}
Esempio n. 3
0
// 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);
}