예제 #1
0
void CompatibleOperators::Weak::Gradient(Vectors& EV, const FiniteElement& fe,
                                         double scale)
{
  for (size_t n = 1; n <= fe.grad(n).cols(); ++n)
    for (size_t i = 1; i <= fe.basis(n).size(); ++i)
      EV[n](i) += scale*fe.grad(n)(i,n)*fe.detJxW;
}
예제 #2
0
파일: lininteg.cpp 프로젝트: lyq105/mfem
void VectorFEDomainLFIntegrator::AssembleRHSElementVect(
    const FiniteElement &el, ElementTransformation &Tr, Vector &elvect)
{
    int dof = el.GetDof();
    int dim = el.GetDim();

    vshape.SetSize(dof,dim);
    vec.SetSize(dim);

    elvect.SetSize(dof);
    elvect = 0.0;

    const IntegrationRule *ir = IntRule;
    if (ir == NULL)
    {
        // int intorder = 2*el.GetOrder() - 1; // ok for O(h^{k+1}) conv. in L2
        int intorder = 2*el.GetOrder();
        ir = &IntRules.Get(el.GetGeomType(), intorder);
    }

    for (int i = 0; i < ir->GetNPoints(); i++)
    {
        const IntegrationPoint &ip = ir->IntPoint(i);

        Tr.SetIntPoint (&ip);
        el.CalcVShape(Tr, vshape);

        QF.Eval (vec, Tr, ip);
        vec *= ip.weight * Tr.Weight();

        vshape.AddMult (vec, elvect);
    }
}
예제 #3
0
파일: lininteg.cpp 프로젝트: lyq105/mfem
void VectorBoundaryFluxLFIntegrator::AssembleRHSElementVect(
    const FiniteElement &el, ElementTransformation &Tr, Vector &elvect)
{
    int dim = el.GetDim()+1;
    int dof = el.GetDof();

    shape.SetSize (dof);
    nor.SetSize (dim);
    elvect.SetSize (dim*dof);

    const IntegrationRule *ir = IntRule;
    if (ir == NULL)
        ir = &IntRules.Get(el.GetGeomType(), el.GetOrder() + 1);

    elvect = 0.0;
    for (int i = 0; i < ir->GetNPoints(); i++)
    {
        const IntegrationPoint &ip = ir->IntPoint(i);
        Tr.SetIntPoint (&ip);
        CalcOrtho(Tr.Jacobian(), nor);
        el.CalcShape (ip, shape);
        nor *= Sign * ip.weight * F -> Eval (Tr, ip);
        for (int j = 0; j < dof; j++)
            for (int k = 0; k < dim; k++)
                elvect(dof*k+j) += nor(k) * shape(j);
    }
}
예제 #4
0
파일: lininteg.cpp 프로젝트: lyq105/mfem
void VectorFEBoundaryTangentLFIntegrator::AssembleRHSElementVect(
    const FiniteElement &el, ElementTransformation &Tr, Vector &elvect)
{
    int dof = el.GetDof();
    DenseMatrix vshape(dof, 2);
    Vector f_loc(3);
    Vector f_hat(2);

    elvect.SetSize(dof);
    elvect = 0.0;

    const IntegrationRule *ir = IntRule;
    if (ir == NULL)
    {
        int intorder = 2*el.GetOrder();  // <----------
        ir = &IntRules.Get(el.GetGeomType(), intorder);
    }

    for (int i = 0; i < ir->GetNPoints(); i++)
    {
        const IntegrationPoint &ip = ir->IntPoint(i);

        Tr.SetIntPoint(&ip);
        f.Eval(f_loc, Tr, ip);
        Tr.Jacobian().MultTranspose(f_loc, f_hat);
        el.CalcVShape(ip, vshape);

        Swap<double>(f_hat(0), f_hat(1));
        f_hat(0) = -f_hat(0);
        f_hat *= ip.weight;
        vshape.AddMult(f_hat, elvect);
    }
}
예제 #5
0
파일: lininteg.cpp 프로젝트: lyq105/mfem
void VectorBoundaryLFIntegrator::AssembleRHSElementVect(
    const FiniteElement &el, ElementTransformation &Tr, Vector &elvect)
{
    int vdim = Q.GetVDim();
    int dof  = el.GetDof();

    shape.SetSize(dof);
    vec.SetSize(vdim);

    elvect.SetSize(dof * vdim);
    elvect = 0.0;

    const IntegrationRule *ir = IntRule;
    if (ir == NULL)
    {
        int intorder = el.GetOrder() + 1;
        ir = &IntRules.Get(el.GetGeomType(), intorder);
    }

    for (int i = 0; i < ir->GetNPoints(); i++)
    {
        const IntegrationPoint &ip = ir->IntPoint(i);

        Q.Eval(vec, Tr, ip);
        Tr.SetIntPoint (&ip);
        vec *= Tr.Weight() * ip.weight;
        el.CalcShape(ip, shape);
        for (int k = 0; k < vdim; k++)
            for (int s = 0; s < dof; s++)
                elvect(dof*k+s) += vec(k) * shape(s);
    }
}
예제 #6
0
파일: lininteg.cpp 프로젝트: lyq105/mfem
void BoundaryLFIntegrator::AssembleRHSElementVect(
    const FiniteElement &el, ElementTransformation &Tr, Vector &elvect)
{
    int dof = el.GetDof();

    shape.SetSize(dof);        // vector of size dof
    elvect.SetSize(dof);
    elvect = 0.0;

    const IntegrationRule *ir = IntRule;
    if (ir == NULL)
    {
        int intorder = oa * el.GetOrder() + ob;  // <----------
        ir = &IntRules.Get(el.GetGeomType(), intorder);
    }

    for (int i = 0; i < ir->GetNPoints(); i++)
    {
        const IntegrationPoint &ip = ir->IntPoint(i);

        Tr.SetIntPoint (&ip);
        double val = Tr.Weight() * Q.Eval(Tr, ip);

        el.CalcShape(ip, shape);

        add(elvect, ip.weight * val, shape, elvect);
    }
}
예제 #7
0
void Assembler::forcingTerm(const MeshHandler<ORDER>& mesh,
	                     FiniteElement<Integrator, ORDER>& fe, const ForcingTerm& u, VectorXr& forcingTerm)
{

	forcingTerm = VectorXr::Zero(mesh.num_nodes());

  	for(auto t=0; t<mesh.num_triangles(); t++)
  	{
		fe.updateElement(mesh.getTriangle(t));

		// Vector of vertices indices (link local to global indexing system)
		std::vector<UInt> identifiers;
				identifiers.resize(ORDER*3);

		for( auto q=0; q<ORDER*3; q++)
			identifiers[q]=mesh.getTriangle(t)[q].id();


		//localM=localMassMatrix(currentelem);
		for(int i = 0; i < 3*ORDER; i++)
		{
			Real s=0;

			for(int iq = 0;iq < Integrator::NNODES; iq++)
			{
				UInt globalIndex = fe.getGlobalIndex(iq);
				s +=  fe.phiMaster(i,iq)* u(globalIndex) * fe.getDet() * fe.getAreaReference()* Integrator::WEIGHTS[iq];//(*)
			}
			forcingTerm[identifiers[i]] += s;
		}

	}
	//cout<<"done!"<<endl;;
}
예제 #8
0
파일: lininteg.cpp 프로젝트: lyq105/mfem
void BoundaryNormalLFIntegrator::AssembleRHSElementVect(
    const FiniteElement &el, ElementTransformation &Tr, Vector &elvect)
{
    int dim = el.GetDim()+1;
    int dof = el.GetDof();
    Vector nor(dim), Qvec;

    shape.SetSize(dof);
    elvect.SetSize(dof);
    elvect = 0.0;

    const IntegrationRule *ir = IntRule;
    if (ir == NULL)
    {
        int intorder = oa * el.GetOrder() + ob;  // <----------
        ir = &IntRules.Get(el.GetGeomType(), intorder);
    }

    for (int i = 0; i < ir->GetNPoints(); i++)
    {
        const IntegrationPoint &ip = ir->IntPoint(i);

        Tr.SetIntPoint(&ip);
        CalcOrtho(Tr.Jacobian(), nor);
        Q.Eval(Qvec, Tr, ip);

        el.CalcShape(ip, shape);

        elvect.Add(ip.weight*(Qvec*nor), shape);
    }
}
예제 #9
0
void CompatibleOperators::Weak::Gradient(std::vector<Matrix>& EM,
                                        const FiniteElement& fe,
                                        double scale)
{
  size_t nsd = fe.grad(1).cols();
  for (size_t n = 1; n <= nsd; ++n)
    for (size_t i=1; i <= fe.basis(n).size(); ++i)
      for (size_t j=1; j <= fe.basis(nsd+1).size(); ++j)
        EM[8+4*(n-1)](i,j) += -scale*fe.grad(n)(i,n)*fe.basis(nsd+1)(j)*fe.detJxW;
}
예제 #10
0
void CompatibleOperators::Weak::Advection(std::vector<Matrix>& EM,
                                          const FiniteElement& fe,
                                          const Vec3& AC, double scale)
{
  size_t nsd = fe.grad(1).cols();
  for (size_t n = 1; n <= nsd; ++n)
    for (size_t i = 1; i <= fe.basis(n).size(); ++i)
      for (size_t j = 1; j <= fe.basis(n).size(); ++j)
        for (size_t k = 1; k <= nsd; ++k)
          EM[n](i,j) += scale*AC[k]*fe.grad(n)(j,k)*fe.basis(n)(i)*fe.detJxW;
}
예제 #11
0
bool PoroElasticity::evalBou (LocalIntegral& elmInt,
                              const FiniteElement& fe,
                              const TimeDomain& time, const Vec3& X,
                              const Vec3& normal) const
{
  if (!tracFld && !fluxFld)
  {
    std::cerr << " *** PoroElasticity::evalBouMx: No fluxes/tractions." << std::endl;
    return false;
  }

  const PoroMaterial* pmat = dynamic_cast<const PoroMaterial*>(material);
  if (!pmat) {
    std::cerr << __FUNCTION__ << ": No material data." << std::endl;
    return false;
  }

  // Evaluate the surface traction
  Vec4 Xt = static_cast<const Vec4&>(X);
  Xt.t = time.t;
  Vec3 tr2 = this->getTraction(Xt,normal);
  Xt.t -= time.dt;
  Vec3 tr1 = this->getTraction(Xt,normal);
  Vec3 dtr;
  dtr = tr2 - tr1;

  Vec3 permeability = pmat->getPermeability(X);

  Vec3 bf = this->getBodyforce(X);

  double scl(sc);
  if (scl == 0.0)
    scl = sqrt(pmat->getStiffness(X)*pmat->getFluidDensity(X)*gacc/(permeability[0]*time.dt));

  // Integrate the force vector fu
  ElmMats& elMat = static_cast<ElmMats&>(elmInt);
  for (size_t i = 1; i <= fe.basis(1).size(); i++)
    for (unsigned short int j = 1; j <= nsd; j++)
      elMat.b[Fu](nsd*(i-1)+j) += (-1.0)*(dtr[j-1]*fe.basis(1)(i)*fe.detJxW +
                                  bf[j-1]*fe.basis(1)(i)*fe.detJxW);

  // First term of fp vector in RHS, remember to add water flux term
  for (size_t i = 1; i <= fe.basis(2).size(); i++)
  {
    double fpvec = 0.0;
    for (size_t k = 1; k <= nsd; k++)
      fpvec += scl*fe.grad(2)(i,k)*(permeability[k-1]/gacc)*gravity[k-1];
    elMat.b[Fp](i) = fpvec*time.dt*fe.detJxW;
  }

  return true;
}
예제 #12
0
void CompatibleOperators::Residual::Convection(Vectors& EV, const FiniteElement& fe,
                                               const Vec3& U, const Tensor& dUdX,
                                               const Vec3& UC, double scale,
                                               bool conservative)
{
  size_t nsd = fe.grad(1).cols();
  for (size_t n=1; n <= nsd; ++n) {
    double conv = 0.0;
    for (size_t k = 1; k<= nsd; ++k)
      conv += U[k-1]*dUdX(n, k);
    for (size_t i=1; i <= fe.basis(n).size(); ++i)
      EV[n](i) -= scale * conv * fe.basis(n)(i) * fe.detJxW;
  }
}
예제 #13
0
void CompatibleOperators::Residual::Laplacian(Vectors& EV,
                                              const FiniteElement& fe,
                                              const Tensor& dUdX,
                                              double scale, bool stress)
{
  size_t nsd = fe.grad(1).cols();
  for (size_t k = 1; k <= nsd; ++k)
    for (size_t i = 1; i <= fe.basis(k).size(); ++i) {
      double diff = 0.0;
      for (size_t m = 1; m <= nsd; ++m)
        diff += fe.grad(k)(i,m)*dUdX(k,m);
      EV[k](i) += scale*diff*fe.detJxW;
    }
}
예제 #14
0
void CompatibleOperators::Weak::Source(Vectors& EV,
                                       const FiniteElement& fe,
                                       double scale)
{
  for (size_t k = 1; k <= fe.grad(1).cols(); ++k)
    EqualOrderOperators::Weak::Source(EV[k], fe, scale, 1, k);
}
예제 #15
0
void CompatibleOperators::Weak::Laplacian(std::vector<Matrix>& EM,
                                          const FiniteElement& fe,
                                          double scale, bool stress)
{
  size_t nsd = fe.grad(1).cols();
  for (size_t n = 1; n <= nsd; ++n)
    EqualOrderOperators::Weak::Laplacian(EM[n], fe, scale, false, n);

  for (size_t m = 1; m <= nsd && stress; m++)
    for (size_t i = 1; i <= fe.basis(m).size(); ++i)
      for (size_t n = m; n <= nsd; n++)
        for (size_t j = 1; j <= fe.basis(n).size(); ++j) {
          int idx = m == n ? m : (m == 1 ? 5+n-m : 10+n-m);
          EM[idx](i,j) += scale* fe.grad(n)(j,m) * fe.grad(m)(i,n) * fe.detJxW;
        }
}
예제 #16
0
bool PoroNorm::evalInt (LocalIntegral& elmInt, const FiniteElement& fe,
                        const TimeDomain& time, const Vec3& X) const
{
  ElmNorm& norms = static_cast<ElmNorm&>(elmInt);
  size_t nsd = fe.grad(1).cols();

  // Numerical displacement and pressure
  Vec3   disp_h;
  double press_h;
  if (fe.getNoBasis() == 1)
  {
    for (size_t i = 0; i < nsd; i++)
      disp_h[i] = norms.vec[PoroElasticity::Vu].dot(fe.N,i,nsd+1);
    press_h = norms.vec[PoroElasticity::Vp].dot(fe.N,nsd,nsd+1);
  }
  else
  {
    for (size_t i = 0; i < nsd; i++)
      disp_h[i] = norms.vec[PoroElasticity::Vu].dot(fe.basis(1),i,nsd);
    press_h = norms.vec[PoroElasticity::Vp].dot(fe.basis(2));
  }

  // Norm index counter
  size_t np = 0;

  // Displacement L2-norm
  norms[np++] += disp_h * disp_h * fe.detJxW;

  // Pressure L2-norm
  norms[np++] += press_h * press_h * fe.detJxW;

  // Displacement error L2-norm
  if (displacement)
  {
    Vec3 disp_a = (*displacement)(Vec4(X,time.t));
    norms[np++] += (disp_a - disp_h) * (disp_a - disp_h) * fe.detJxW;
  }

  // Pressure error L2-norm
  if (pressure)
  {
    double press_a = (*pressure)(Vec4(X,time.t));
    norms[np++] += (press_a - press_h) * (press_a - press_h) * fe.detJxW;
  }

  return true;
}
예제 #17
0
파일: lininteg.cpp 프로젝트: lyq105/mfem
void BoundaryFlowIntegrator::AssembleRHSElementVect(
    const FiniteElement &el, FaceElementTransformations &Tr, Vector &elvect)
{
    int dim, ndof, order;
    double un, w, vu_data[3], nor_data[3];

    dim  = el.GetDim();
    ndof = el.GetDof();
    Vector vu(vu_data, dim), nor(nor_data, dim);

    const IntegrationRule *ir = IntRule;
    if (ir == NULL)
    {
        // Assuming order(u)==order(mesh)
        order = Tr.Elem1->OrderW() + 2*el.GetOrder();
        if (el.Space() == FunctionSpace::Pk)
            order++;
        ir = &IntRules.Get(Tr.FaceGeom, order);
    }

    shape.SetSize(ndof);
    elvect.SetSize(ndof);
    elvect = 0.0;

    for (int p = 0; p < ir->GetNPoints(); p++)
    {
        const IntegrationPoint &ip = ir->IntPoint(p);
        IntegrationPoint eip;
        Tr.Loc1.Transform(ip, eip);
        el.CalcShape(eip, shape);

        Tr.Face->SetIntPoint(&ip);

        u->Eval(vu, *Tr.Elem1, eip);

        if (dim == 1)
            nor(0) = 2*eip.x - 1.0;
        else
            CalcOrtho(Tr.Face->Jacobian(), nor);

        un = vu * nor;
        w = 0.5*alpha*un - beta*fabs(un);
        w *= ip.weight*f->Eval(*Tr.Elem1, eip);
        elvect.Add(w, shape);
    }
}
예제 #18
0
bool CahnHilliard4::evalInt (LocalIntegral& elmInt, const FiniteElement& fe,
                             const Vec3& X) const
{
  if (!this->CahnHilliard::evalInt(elmInt,fe,X))
    return false;

  Matrix& A = static_cast<ElmMats&>(elmInt).A.front();
  double s4JxW = pow(smearing,4.0)*fe.detJxW;

  for (size_t i = 1; i <= fe.N.size(); i++)
    for (size_t j = 1; j <= fe.N.size(); j++)
    {
      double grad = 0.0;
      for (unsigned short int k = 1; k <= nsd; k++)
        grad += fe.d2NdX2(i,k,k)*fe.d2NdX2(j,k,k);
      A(i,j) += grad*s4JxW;
    }

  return true;
}
예제 #19
0
bool PoroElasticity::evalInt (LocalIntegral& elmInt,
                              const FiniteElement& fe,
                              const TimeDomain& time, const Vec3& X) const
{
  const PoroMaterial* pmat = dynamic_cast<const PoroMaterial*>(material);
  if (!pmat)
  {
    std::cerr <<" *** PoroElasticity::evalInt: No material data."<< std::endl;
    return false;
  }

  Matrix Bmat;
  if (!this->formBmatrix(Bmat,fe.dNdX))
    return false;

  SymmTensor Kperm(nsd); // Evaluate the permeability tensor
  if (!this->formPermeabilityTensor(Kperm,elmInt.vec,fe,X))
    return false;

  // Evaluate other material parameters
  double visc  = pmat->getViscosity(X);
  double poro  = pmat->getPorosity(X);
  double alpha = pmat->getBiotCoeff(X);
  double Minv  = pmat->getBiotModulus(X,alpha,poro);

  // Integrate the element matrices, depending on solution mode
  ElmMats& elMat = static_cast<ElmMats&>(elmInt);

  if (!elMat.A[uu_M].empty())
    this->formMassMatrix(elMat.A[uu_M], fe.basis(1), X, fe.detJxW);

  if (!elMat.A[up_D].empty())
    this->evalDynCouplingMatrix(elMat.A[up_D], fe.basis(1), fe.grad(2),
                                Kperm, 1.0 / visc * fe.detJxW);

  this->evalPermeabilityMatrix(elMat.A[pp_P], fe.grad(2),
                               Kperm, 1.0 / visc * fe.detJxW);

  if (!this->evalElasticityMatrices(elMat, Bmat, fe, X))
    return false;

  if (!this->evalCouplingMatrix(elMat.A[up_Q], Bmat, fe.basis(2),
                                alpha * fe.detJxW))
    return false;

  // In the fully static formulation, we don't need the S-matrix
  if (m_mode == SIM::DYNAMIC || !staticFlow)
    if (!this->evalCompressibilityMatrix(elMat.A[pp_S], fe.basis(2),
                                         Minv * fe.detJxW))
        return false;

  if (volumeFlux)
    elMat.b[Fp].add(fe.basis(2),(*volumeFlux)(X)*fe.detJxW);

  return true;
}
예제 #20
0
bool ElasticityForce::evalForce (ElmMats& elmat, const Vec3& th,
                                 const FiniteElement& fe) const
{
  // Integrate the nodal force vector
  Vector& ES = elmat.b.front();
  size_t nsd = fe.dNdX.cols();
  for (size_t a = 1; a <= fe.N.size(); a++)
    for (size_t d = 1; d <= nsd; d++)
      ES(nsd*(a-1)+d) += th[d-1]*fe.N(a)*fe.detJxW;

  return true;
}
예제 #21
0
//-----------------------------------------------------------------------------
void GenericFunction::restrict_as_ufc_function(double* w,
                                               const FiniteElement& element,
                                               const Cell& dolfin_cell,
                                               const double* coordinate_dofs,
                                               const ufc::cell& ufc_cell) const
{
  dolfin_assert(w);

  // Evaluate dofs to get the expansion coefficients
  element.evaluate_dofs(w, *this, coordinate_dofs, ufc_cell.orientation,
                        ufc_cell);
}
예제 #22
0
void Assembler::operKernel(EOExpr<A> oper,const MeshHandler<ORDER>& mesh,
	                     FiniteElement<Integrator, ORDER>& fe, SpMat& OpMat)
{
	std::vector<coeff> triplets;


  	for(auto t=0; t<mesh.num_triangles(); t++)
  	{
		fe.updateElement(mesh.getTriangle(t));

		// Vector of vertices indices (link local to global indexing system)
		std::vector<UInt> identifiers;
		identifiers.resize(ORDER*3);
		for( auto q=0; q<ORDER*3; q++)
			identifiers[q]=mesh.getTriangle(t)[q].id();


		//localM=localMassMatrix(currentelem);
		for(int i = 0; i < 3*ORDER; i++)
		{
			for(int j = 0; j < 3*ORDER; j++)
			{
				Real s=0;

				for(int l = 0;l < Integrator::NNODES; l++)
				{
					s += oper(fe,i,j,l) * fe.getDet() * fe.getAreaReference()* Integrator::WEIGHTS[l];//(*)
				}
			  triplets.push_back(coeff(identifiers[i],identifiers[j],s));
			}
		}

	}

  	UInt nnodes = mesh.num_nodes();
  	OpMat.resize(nnodes, nnodes);
	OpMat.setFromTriplets(triplets.begin(),triplets.end());
	//cout<<"done!"<<endl;;
}
예제 #23
0
파일: lininteg.cpp 프로젝트: lyq105/mfem
void BoundaryTangentialLFIntegrator::AssembleRHSElementVect(
    const FiniteElement &el, ElementTransformation &Tr, Vector &elvect)
{
    int dim = el.GetDim()+1;
    int dof = el.GetDof();
    Vector tangent(dim), Qvec;

    shape.SetSize(dof);
    elvect.SetSize(dof);
    elvect = 0.0;

    if (dim != 2)
        mfem_error("These methods make sense only in 2D problems.");

    const IntegrationRule *ir = IntRule;
    if (ir == NULL)
    {
        int intorder = oa * el.GetOrder() + ob;  // <----------
        ir = &IntRules.Get(el.GetGeomType(), intorder);
    }

    for (int i = 0; i < ir->GetNPoints(); i++)
    {
        const IntegrationPoint &ip = ir->IntPoint(i);

        Tr.SetIntPoint(&ip);
        const DenseMatrix &Jac = Tr.Jacobian();
        tangent(0) =  Jac(0,0);
        tangent(1) = Jac(1,0);

        Q.Eval(Qvec, Tr, ip);

        el.CalcShape(ip, shape);

        add(elvect, ip.weight*(Qvec*tangent), shape, elvect);
    }
}
예제 #24
0
bool PoroElasticity::evalBou (LocalIntegral& elmInt,
                              const FiniteElement& fe,
                              const TimeDomain&, const Vec3& X,
                              const Vec3& normal) const
{
  if (fluxFld)
  {
    double hbar = -(*fluxFld)(X);
    static_cast<ElmMats&>(elmInt).b[Fp].add(fe.basis(2),hbar*fe.detJxW);
    return true;
  }

  // Using the inherited standard method from Elasticity for tractions
  return this->Elasticity::evalBou(elmInt,fe,X,normal);
}
예제 #25
0
   static void apply_trans(const FiniteElement&     fe, 
                           const IntegrationPoint&  ip,
                           Vector1&                 vec_B,
                           Vector2&                 vec_D) 
   {

      gsse::matrix mx_s    = fe.get_shape( gsse::fem::get_coord( ip ) );  // [TODO] matrix;
      vec_B =  mx_s * vec_D;     

#ifdef GSSE_DEBUG_FULLOUTPUT
      std::cout << "DIFFOP:: idboundary " << std::endl;
      std::cout  << "vec_B: " << vec_B << std::endl;
      std::cout  << "vec_D: " << vec_D << std::endl;
      std::cout  << "mx_s: " << mx_s << std::endl;
#endif
   }
예제 #26
0
파일: fdaPDE.cpp 프로젝트: 10376920/fdaPDE
SEXP get_integration_points(SEXP Rmesh, SEXP Rorder)
{
	//Declare pointer to access data from C++

	int order;

	// Cast all computation parameters
    order 		= INTEGER(Rorder)[0];

	//std::cout<<"Computing Locations for Numeric Integration"<<std::endl;

    SEXP result;

    if(order == 1)
    {
    	MeshHandler<1> mesh(Rmesh);
    	PROTECT(result=Rf_allocVector(REALSXP, 2*IntegratorTriangleP2::NNODES*mesh.num_triangles()));

    	FiniteElement<IntegratorTriangleP2,1> fe;
    	for(UInt i=0; i<mesh.num_triangles(); i++)
    	{
    		fe.updateElement(mesh.getTriangle(i));
    		for(UInt l = 0;l < IntegratorTriangleP2::NNODES; l++)
    		{
    			Point p = fe.coorQuadPt(l);
    			REAL(result)[i*IntegratorTriangleP2::NNODES + l] = p[0];
    			REAL(result)[mesh.num_triangles()*IntegratorTriangleP2::NNODES + i*IntegratorTriangleP2::NNODES + l] = p[1];
    		}

    	}
    }
    else if(order == 2)
    {
    	MeshHandler<2> mesh(Rmesh);
    	PROTECT(result=Rf_allocVector(REALSXP, 2*IntegratorTriangleP4::NNODES*mesh.num_triangles()));

    	FiniteElement<IntegratorTriangleP4,2> fe;
    	for(UInt i=0; i<mesh.num_triangles(); i++)
    	{
    		fe.updateElement(mesh.getTriangle(i));
    		for(UInt l = 0;l < IntegratorTriangleP4::NNODES; l++)
    		{
    			Point p = fe.coorQuadPt(l);
    			REAL(result)[i*IntegratorTriangleP4::NNODES + l] = p[0];
    			REAL(result)[mesh.num_triangles()*IntegratorTriangleP4::NNODES + i*IntegratorTriangleP4::NNODES + l] = p[1];
    		}

    	}
    }


	UNPROTECT(1);
    // result list
    return(result);
}
예제 #27
0
   static void generate_matrix(const FiniteElement&     fe, 
                               const IntegrationPoint&  ip,
                               Matrix&                  mx_B) 
   {
      gsse::set_to_zero(mx_B);

      Matrix mx_Ds    = fe.get_shape( gsse::fem::get_coord( ip ) );
      for (long mi = 0; mi < gsse::num_rows(mx_Ds); ++mi)
      {
         mx_B(0,mi) = mx_Ds(mi,0);
      }

#ifdef GSSE_DEBUG_FULLOUTPUT
      std::cout << "DIFFOP:: idboundary " << std::endl;
      std::cout << "ip coord ref:" << gsse::fem::get_coord( ip ) << std::endl;
      std::cout << " diffop::mx Ds    : " << mx_Ds << std::endl;
      std::cout << " diffop::mx B     : " << mx_B << std::endl;
#endif
   }
예제 #28
0
   static void generate_matrix(const FiniteElement&     fe, 
                               const IntegrationPoint&  ip,
                               Matrix&                  mx_B) 
   {
#ifdef GSSE_DEBUG_FULLOUTPUT
      std::cout << "DIFFOP:: gradient " << std::endl;
#endif

      Matrix mx_Jac_i = gsse::math::matrix_op::inverse<DIM>( gsse::fem::get_jacobian (ip) );
      Matrix mx_Ds    = fe.get_Dshape( gsse::fem::get_coord( ip ) );

      mx_B = gsse::math::matrix_op::transpose( mx_Jac_i ) * gsse::math::matrix_op::transpose(mx_Ds);


#ifdef GSSE_DEBUG_FULLOUTPUT
      std::cout << "mx Ds    : " << mx_Ds << std::endl;
      std::cout << "mx Jac in: " << mx_Jac_i << std::endl;
      std::cout << "mx B     : " << mx_B << std::endl;
#endif
   
   }
예제 #29
0
bool Elasticity::evalBou (LocalIntegral& elmInt, const FiniteElement& fe,
                          const Vec3& X, const Vec3& normal) const
{
  if (!tracFld && !fluxFld)
  {
    std::cerr <<" *** Elasticity::evalBou: No tractions."<< std::endl;
    return false;
  }
  else if (!eS)
  {
    std::cerr <<" *** Elasticity::evalBou: No load vector."<< std::endl;
    return false;
  }

  // Axi-symmetric integration point volume; 2*pi*r*|J|*w
  const double detJW = axiSymmetry ? 2.0*M_PI*X.x*fe.detJxW : fe.detJxW;

  // Evaluate the surface traction
  Vec3 T = this->getTraction(X,normal);

  // Store traction value for visualization
  if (fe.iGP < tracVal.size() && !T.isZero())
  {
    tracVal[fe.iGP].first = X;
    tracVal[fe.iGP].second += T;
  }

  // Pull-back traction to reference configuration
  if (!this->pullBackTraction(T))
    return false;

  // Integrate the force vector
  Vector& ES = static_cast<ElmMats&>(elmInt).b[eS-1];
  for (size_t a = 1; a <= fe.N.size(); a++)
    for (unsigned short int i = 1; i <= nsd; i++)
      ES(nsd*(a-1)+i) += T[i-1]*fe.N(a)*detJW;

  return true;
}
예제 #30
0
bool ElasticBase::evalPoint (LocalIntegral& elmInt, const FiniteElement& fe,
                             const Vec3& pval)
{
  if (!eS)
  {
    std::cerr <<" *** ElasticBase::evalPoint: No load vector."<< std::endl;
    return false;
  }

  Vector& ES = static_cast<ElmMats&>(elmInt).b[eS-1];
  for (size_t a = 1; a <= fe.N.size(); a++)
    for (unsigned short int i = 1; i <= npv && i <= 3; i++)
      ES(npv*(a-1)+i) += pval(i)*fe.N(a)*fe.detJxW;

  if (eS == 1)
  {
    RealArray& sumLoad = static_cast<ElmMats&>(elmInt).c;
    for (size_t i = 0; i < sumLoad.size() && i < 3; i++)
      sumLoad[i] += pval[i]*fe.detJxW;
  }

  return true;
}