示例#1
0
/*----------------------------------------------------------------------*
 |                                                           mwgee 08/05|
 | 2D case:                                                             |
 | this method evaluates the function                                   |
 | F(eta) = ( Ni * xis - xm ) dot g(xi)                                 |
 | with Ni shape functions of slave segment                             |
 |      xm  nodal coords of master node                                 |
 |      xs  nodal coords of slave nodes on segment                      |
 |      njs nodal outward normal of nodes xs (slave side)               |
 *----------------------------------------------------------------------*/
double MOERTEL::Projector::evaluate_F_2D_SegmentOrthogonal(MOERTEL::Node& node,
                                                        MOERTEL::Segment& seg, 
                                                        double eta,
														double &gap)
{
  // check the type of function on the segment
  // Here, we need 1D functions set as function id 0
  MOERTEL::Function::FunctionType type = seg.FunctionType(0);
  if (type != MOERTEL::Function::func_Linear1D)
  {
	  std::stringstream oss;
    oss << "***ERR*** MOERTEL::Projector::evaluate_F_2D_SegmentOrthogonal:\n"
    	 << "***ERR*** function is of wrong type\n"
    	 << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
	throw ReportError(oss);
  }
  
  // evaluate the first function set on segment at eta
  int nsnode = seg.Nnode();
  double val[100];
  seg.EvaluateFunction(0,&eta,val,nsnode,NULL);
  
  // get nodal coords and normals of slave nodes and interpolate them
  double Nx[2]; 
  Nx[0] = Nx[1] = 0.0;
  MOERTEL::Node** snodes = seg.Nodes();
  if (!snodes)
  {
	  std::stringstream oss;
    oss << "***ERR*** MOERTEL::Projector::evaluate_F_2D_SegmentOrthogonal:\n"
    	 << "***ERR*** segment " << seg.Id() << " ptr to it's nodes is zero\n"
    	 << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
	throw ReportError(oss);
  }
  for (int i=0; i<nsnode; ++i)
  {
    const double* X = snodes[i]->X();
    Nx[0] += val[i]*X[0];
    Nx[1] += val[i]*X[1];
  }
  
  // subtract xm from interpolated coords Nx
  const double* X = node.X();
  Nx[0] -= X[0];
  Nx[1] -= X[1];
  
  // evaluate the metric of the segment in point xi
  double g[2];
  seg.Metric(&eta,g,NULL);

  // calculate F
  double F = Nx[0]*g[0] + Nx[1]*g[1];

  gap = (Nx[0] * g[0] + Nx[1] * g[1]);
		  
//  gap = ((Nx[0] - X[0]) * g[0] + (Nx[1] - X[1]) * g[1])
//		  / sqrt(g[0] * g[0] + g[1] * g[1]);  // ||gap|| cos theta

  return F;
}
示例#2
0
/*----------------------------------------------------------------------*
 |                                                           mwgee 08/05|
 *----------------------------------------------------------------------*/
bool MOERTEL::Projector::ProjectNodetoSegment_Orthogonal_to_Slave(
                                                             MOERTEL::Node& snode,
                                                             MOERTEL::Segment& seg, 
                                                             double xi[],
															 double &gap,
                                                             MOERTEL::Segment& sseg)
{
#if 0
  std::cout << "----- Projector: Node " << snode.Id() << " Segment " << seg.Id() << std::endl;
  std::cout << "      orthogonal to Slave Segment " << sseg.Id() << std::endl;
#endif

  if (IsTwoDimensional())
  {
    // get the local node id of snode on sseg
    int lid = sseg.GetLocalNodeId(snode.Id());
    if (lid<0)
    {
	  std::stringstream oss;
      oss << "***ERR*** MOERTEL::Projector::ProjectNodetoSegment_Orthogonal_to_Slave:\n"
    	   << "***ERR*** local node id could not be found\n"
      	   << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
		throw ReportError(oss);
    }
    // get coordinate of local node lid
    double lidxi;
    sseg.LocalCoordinatesOfNode(lid,&lidxi);
    
    // build tangent vector in xi
    double g[2];
    sseg.Metric(&lidxi,g,NULL);
    
    // we do a newton iteration for the projection coordinates xi
    // set starting value to the middle of the segment
    double eta = 0.0;
    int    i = 0;
    double F=0.0,dF=0.0,deta=0.0;
    for (i=0; i<10; ++i)
    {
      F = evaluate_F_2D_SegmentOrthogonal_to_g(snode,seg,eta,gap,g);
      if (abs(F) < 1.0e-10) break;
      dF   = evaluate_gradF_2D_SegmentOrthogonal_to_g(snode,seg,eta,g);
      deta = (-F)/dF;
      eta += deta;
    }
    if (abs(F)>1.0e-10)
    {
      if (OutLevel()>3)
      std::cout << "MOERTEL: ***WRN*** MOERTEL::Projector::ProjectNodetoSegment_Orthogonal_to_Slave:\n"
      	   << "MOERTEL: ***WRN*** Newton iteration failed to converge\n"
      	   << "MOERTEL: ***WRN*** #iterations = " << i << std::endl
      	   << "MOERTEL: ***WRN*** F(eta) = " << F << " gradF(eta) = " << dF << " eta = " << eta << " delta(eta) = " << deta << "\n"
           << "MOERTEL: ***WRN*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
    }
#if 0
    std::cout << "#iterations = " << i << " F = " << F << " eta = " << eta << std::endl;
#endif
    xi[0] = eta;
    return true;
  }
  else
  {
	  std::stringstream oss;
    oss << "***ERR*** MOERTEL::Projector::ProjectNodetoSegment_Orthogonal_to_Slave:\n"
    	 << "***ERR*** 3D projection not impl.\n"
    	 << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
	throw ReportError(oss);
  }
  return true;
}