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; }
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); } }
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); } }
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); } }
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); } }
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); } }
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;; }
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); } }
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; }
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; }
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; }
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; } }
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; } }
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); }
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; } }
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; }
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); } }
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; }
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; }
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; }
//----------------------------------------------------------------------------- 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); }
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;; }
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); } }
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); }
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 }
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); }
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 }
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 }
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; }
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; }