float AssignEModulus::sampleField( const OBLelement3D* FEelement, 
								  const McDArray<McVec3f>& vertices,
								  HxUniformScalarField3* field )
{
	float sum = 0;

	if ( !FEelement ) { return 0; }

	// this parameter controls the number of samples.
	// there are *roughly* STEPS^3 samples.
	const int STEPS = 10;
	const float PARAM_STEP = 1.0/STEPS;

	HxLocation3* location = field->createLocation();
	float value;
	float volume = 0.0;
	for ( float tt = 0.0; tt <= 1.0; tt += PARAM_STEP )
	{
		for ( float ss = 0.0; ss <= 1.0-tt; ss += PARAM_STEP )
		{
			for ( float rr = 0.0; rr <= 1.0-ss-tt; rr += PARAM_STEP )
			{
				// compute the coordinates of the point corresponding to this parameter triplet.
				// this is a convex sum of the element's vertices.
				McVec3f pcoords( rr, ss, tt );
				McVec3f point = FEelement->getLocation( vertices, pcoords );

				//McMat3f J;
				//FEelement->getJacobian( vertices, pcoords, J );
				//float detJ = J.det();
				float detJ = 1.0;	// ignore scaling by volume
					
				if ( location->move(point.x, point.y, point.z) == 1 )
				{
					// field is valid for new location
					field->eval( location, &value );
					sum += value*detJ;
					volume += detJ;
				}
				// else - this point is in the tetrahedron but is outside of the scalar field.
			}
		}
	}
	delete location;

	float result = (volume > 0) ? (sum / volume) : 0;

	return result;
}
Exemplo n.º 2
0
void GLpApp::rect2DMeshGenerator(
  const int                      numProc
  ,const int                     procRank
  ,const double                  len_x
  ,const double                  len_y
  ,const int                     local_nx
  ,const int                     local_ny
  ,const int                     bndy_marker
  ,Epetra_IntSerialDenseVector   *ipindx_out
  ,Epetra_SerialDenseMatrix      *ipcoords_out
  ,Epetra_IntSerialDenseVector   *pindx_out
  ,Epetra_SerialDenseMatrix      *pcoords_out
  ,Epetra_IntSerialDenseMatrix   *t_out
  ,Epetra_IntSerialDenseMatrix   *e_out
  ,std::ostream                  *out_arg
  ,const bool                    dumpAll
  )
{
  Teuchos::RCP<Teuchos::FancyOStream>
    out = Teuchos::getFancyOStream(Teuchos::rcp(out_arg,false));
  Teuchos::OSTab tab(out);
  if(out.get())
    *out << "\nGenerating rectangular mesh with len_x="<<len_x<<", len_y="<<len_y<<", local_nx="<<local_nx<<", and local_ny="<<local_ny<<" ...\n";
  //
  // Validate input
  //
#ifdef TEUCHOS_DEBUG
  TEUCHOS_TEST_FOR_EXCEPT(len_x <= 0.0);
  TEUCHOS_TEST_FOR_EXCEPT(len_y <= 0.0);
  TEUCHOS_TEST_FOR_EXCEPT(local_nx <= 0);
  TEUCHOS_TEST_FOR_EXCEPT(local_ny <= 0);
  TEUCHOS_TEST_FOR_EXCEPT(ipindx_out==NULL);
  TEUCHOS_TEST_FOR_EXCEPT(ipcoords_out==NULL);
  TEUCHOS_TEST_FOR_EXCEPT(pindx_out==NULL);
  TEUCHOS_TEST_FOR_EXCEPT(pcoords_out==NULL);
  TEUCHOS_TEST_FOR_EXCEPT(t_out==NULL);
  TEUCHOS_TEST_FOR_EXCEPT(e_out==NULL);
#endif
  //
  // Get local references
  //
  Epetra_IntSerialDenseVector   &ipindx = *ipindx_out;
  Epetra_SerialDenseMatrix      &ipcoords = *ipcoords_out;
  Epetra_IntSerialDenseVector   &pindx = *pindx_out;
  Epetra_SerialDenseMatrix      &pcoords = *pcoords_out;
  Epetra_IntSerialDenseMatrix   &t = *t_out;
  Epetra_IntSerialDenseMatrix   &e = *e_out;
  //
  // Get dimensions
  //
  const int
    numip = ( local_nx + 1 ) * ( local_ny + ( procRank == numProc-1 ? 1 : 0 ) ),
    numcp = ( procRank == numProc-1 ? 0 : (local_nx+1) ),
    nump  = numip + numcp,
    numelems = 2*local_nx*local_ny,
    numedges = 2*local_ny + ( procRank==0 ? local_nx : 0 ) + ( procRank==numProc-1 ? local_nx : 0 );
  const double
    delta_x = len_x / local_nx,
    delta_y = (len_y/numProc) / local_ny;
  if(out.get()) {
    *out
      << "\nnumip = " << numip
      << "\nnumcp = " << numcp
      << "\nnump = " << nump
      << "\nnumelems = " << numelems
      << "\nnumedges = " << numedges
      << "\ndelta_x = " << delta_x
      << "\ndelta_y = " << delta_y
      << "\n";
  }
  //
  // Resize mesh storage
  //
  ipindx.Size(numip);
  ipcoords.Shape(numip,2);
  pindx.Size(nump);
  pcoords.Shape(nump,2);
  t.Shape(numelems,3);
  e.Shape(numedges,3);
  //
  // Get the global offsets for the local nodes IDs and y coordinates
  //
  const int     localNodeOffset   = procRank*(local_nx+1)*local_ny;
  const double  localYCoordOffset = procRank*delta_y*local_ny;
  //
  // Set the local node IDs and their cooridinates
  //
  if(out.get()) *out << "\nGenerating the node list ...\n";
  tab.incrTab();
  // Owned and shared
  int node_i  = 0;
  int global_node_id = localNodeOffset+1;
  for( int i_y = 0; i_y < local_ny + 1; ++i_y ) {
    for( int i_x = 0; i_x < local_nx + 1; ++i_x ) {
      pindx(node_i) = global_node_id;
      pcoords(node_i,0) = i_x * delta_x;
      pcoords(node_i,1) = i_y * delta_y + localYCoordOffset;
      if(out.get() && dumpAll)
        *out << "node_i="<<node_i<<",global_node_id="<<global_node_id<<",("<<pcoords(node_i,0)<<","<<pcoords(node_i,1)<<")\n";
      ++node_i;
      ++global_node_id;
    }
  }
  tab.incrTab(-1);
  TEUCHOS_TEST_FOR_EXCEPT(node_i != nump);
  // Locally owned only
  for( int i = 0; i < numip; ++i ) {
    ipindx(i) = pindx(i);
    ipcoords(i,0) = pcoords(i,0);
    ipcoords(i,1) = pcoords(i,1);
  }
  //
  // Set the elements
  //
  if(out.get()) *out << "\nGenerating the element list ...\n";
  tab.incrTab();
  int ele_k = 0;
  global_node_id = localNodeOffset+1;
  for( int i_y = 0; i_y < local_ny; ++i_y ) {
    for( int i_x = 0; i_x < local_nx; ++i_x ) {
      t(ele_k,0) = global_node_id;
      t(ele_k,1) = global_node_id + (local_nx + 1);
      t(ele_k,2) = global_node_id + 1;
      if(out.get() && dumpAll)
        *out << "ele_k="<<ele_k<<",("<<t(ele_k,0)<<","<<t(ele_k,1)<<","<<t(ele_k,2)<<")\n";
      ++ele_k;
      t(ele_k,0) = global_node_id + 1;
      t(ele_k,1) = global_node_id + (local_nx + 1);
      t(ele_k,2) = global_node_id + (local_nx + 1) + 1;
      if(out.get() && dumpAll)
        *out << "ele_k="<<ele_k<<",("<<t(ele_k,0)<<","<<t(ele_k,1)<<","<<t(ele_k,2)<<")\n";
      ++ele_k;
      ++global_node_id;
    }
    ++global_node_id;
  }
  tab.incrTab(-1);
  TEUCHOS_TEST_FOR_EXCEPT(ele_k != numelems);
  //
  // Set the edges
  //
  int edge_j = 0;
  if(procRank==0) {
    // Bottom edges
    if(out.get()) *out << "\nGenerating the bottom edges ...\n";
    tab.incrTab();
    global_node_id = localNodeOffset+1;
    for( int i_x = 0; i_x < local_nx; ++i_x ) {
      e(edge_j,0) = global_node_id;
      e(edge_j,1) = global_node_id + 1;
      e(edge_j,2) = bndy_marker;
      if(out.get() && dumpAll)
        *out << "edge_j="<<edge_j<<",("<<e(edge_j,0)<<","<<e(edge_j,1)<<"),"<<e(edge_j,2)<<"\n";
      ++edge_j;
      global_node_id += 1;
    }
    tab.incrTab(-1);
  }
  // Left edges
  if(out.get()) *out << "\nGenerating the left edges ...\n";
  tab.incrTab();
  global_node_id = localNodeOffset+1;
  for( int i_y = 0; i_y < local_ny; ++i_y ) {
    e(edge_j,0) = global_node_id;
    e(edge_j,1) = global_node_id + (local_nx + 1);
    e(edge_j,2) = bndy_marker;
    if(out.get() && dumpAll)
      *out << "edge_j="<<edge_j<<",("<<e(edge_j,0)<<","<<e(edge_j,1)<<"),"<<e(edge_j,2)<<"\n";
    ++edge_j;
    global_node_id += (local_nx + 1);
  }
  tab.incrTab(-1);
  // Right edges
  if(out.get()) *out << "\nGenerating the right edges ...\n";
  tab.incrTab();
  global_node_id = localNodeOffset + 1 + local_nx;
  for( int i_y = 0; i_y < local_ny; ++i_y ) {
    e(edge_j,0) = global_node_id;
    e(edge_j,1) = global_node_id + (local_nx + 1);
    e(edge_j,2) = bndy_marker;
    if(out.get() && dumpAll)
      *out << "edge_j="<<edge_j<<",("<<e(edge_j,0)<<","<<e(edge_j,1)<<"),"<<e(edge_j,2)<<"\n";
    ++edge_j;
    global_node_id += (local_nx + 1);
  }
  tab.incrTab(-1);
  if(procRank==numProc-1) {
    // Top edges
    if(out.get()) *out << "\nGenerating the top edges ...\n";
    tab.incrTab();
    global_node_id = localNodeOffset+1+(local_nx+1)*local_ny;
    for( int i_x = 0; i_x < local_nx; ++i_x ) {
      e(edge_j,0) = global_node_id;
      e(edge_j,1) = global_node_id + 1;
      e(edge_j,2) = bndy_marker;
      if(out.get() && dumpAll)
        *out << "edge_j="<<edge_j<<",("<<e(edge_j,0)<<","<<e(edge_j,1)<<"),"<<e(edge_j,2)<<"\n";
      ++edge_j;
      global_node_id += 1;
    }
    tab.incrTab(-1);
  }
  TEUCHOS_TEST_FOR_EXCEPT(edge_j != numedges);
}