Files
mfem/fem/lininteg.cpp
T
2020-05-22 19:50:45 -07:00

829 lines
21 KiB
C++

// Copyright (c) 2010-2020, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.
#include <cmath>
#include "fem.hpp"
namespace mfem
{
void LinearFormIntegrator::AssembleRHSElementVect(
const FiniteElement &el, FaceElementTransformations &Tr, Vector &elvect)
{
mfem_error("LinearFormIntegrator::AssembleRHSElementVect(...)");
}
void DomainLFIntegrator::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)
{
// ir = &IntRules.Get(el.GetGeomType(),
// oa * el.GetOrder() + ob + Tr.OrderW());
ir = &IntRules.Get(el.GetGeomType(), oa * el.GetOrder() + ob);
}
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 DomainLFIntegrator::AssembleDeltaElementVect(
const FiniteElement &fe, ElementTransformation &Trans, Vector &elvect)
{
MFEM_ASSERT(delta != NULL, "coefficient must be DeltaCoefficient");
elvect.SetSize(fe.GetDof());
fe.CalcPhysShape(Trans, elvect);
elvect *= delta->EvalDelta(Trans, Trans.GetIntPoint());
}
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 BoundaryLFIntegrator::AssembleRHSElementVect(
const FiniteElement &el, FaceElementTransformations &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; // <------ user control
ir = &IntRules.Get(Tr.FaceGeom, intorder); // of integration order
}
for (int i = 0; i < ir->GetNPoints(); i++)
{
const IntegrationPoint &ip = ir->IntPoint(i);
IntegrationPoint eip;
Tr.Loc1.Transform(ip, eip);
Tr.Face->SetIntPoint (&ip);
double val = Tr.Face->Weight() * ip.weight * Q.Eval(*Tr.Face, ip);
el.CalcShape(eip, shape);
add(elvect, val, shape, elvect);
}
}
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 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);
}
}
void VectorDomainLFIntegrator::AssembleRHSElementVect(
const FiniteElement &el, ElementTransformation &Tr, Vector &elvect)
{
int vdim = Q.GetVDim();
int dof = el.GetDof();
double val,cf;
shape.SetSize(dof); // vector of size dof
elvect.SetSize(dof * vdim);
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);
val = Tr.Weight();
el.CalcShape(ip, shape);
Q.Eval (Qvec, Tr, ip);
for (int k = 0; k < vdim; k++)
{
cf = val * Qvec(k);
for (int s = 0; s < dof; s++)
{
elvect(dof*k+s) += ip.weight * cf * shape(s);
}
}
}
}
void VectorDomainLFIntegrator::AssembleDeltaElementVect(
const FiniteElement &fe, ElementTransformation &Trans, Vector &elvect)
{
MFEM_ASSERT(vec_delta != NULL, "coefficient must be VectorDeltaCoefficient");
int vdim = Q.GetVDim();
int dof = fe.GetDof();
shape.SetSize(dof);
fe.CalcPhysShape(Trans, shape);
vec_delta->EvalDelta(Qvec, Trans, Trans.GetIntPoint());
elvect.SetSize(dof*vdim);
DenseMatrix elvec_as_mat(elvect.GetData(), dof, vdim);
MultVWt(shape, Qvec, elvec_as_mat);
}
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 = 2*el.GetOrder();
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 VectorBoundaryLFIntegrator::AssembleRHSElementVect(
const FiniteElement &el, FaceElementTransformations &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 = 2*el.GetOrder();
ir = &IntRules.Get(Tr.GetGeometryType(), intorder);
}
for (int i = 0; i < ir->GetNPoints(); i++)
{
const IntegrationPoint &ip = ir->IntPoint(i);
IntegrationPoint eip;
Tr.Loc1.Transform(ip, eip);
Tr.SetIntPoint(&ip);
// Use Tr transformation in case Q depends on boundary attribute
Q.Eval(vec, Tr, ip);
vec *= Tr.Weight() * ip.weight;
el.CalcShape(eip, shape);
for (int k = 0; k < vdim; k++)
{
for (int s = 0; s < dof; s++)
{
elvect(dof*k+s) += vec(k) * shape(s);
}
}
}
}
void VectorFEDomainLFIntegrator::AssembleRHSElementVect(
const FiniteElement &el, ElementTransformation &Tr, Vector &elvect)
{
int dof = el.GetDof();
int spaceDim = Tr.GetSpaceDim();
vshape.SetSize(dof,spaceDim);
vec.SetSize(spaceDim);
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 VectorFEDomainLFIntegrator::AssembleDeltaElementVect(
const FiniteElement &fe, ElementTransformation &Trans, Vector &elvect)
{
MFEM_ASSERT(vec_delta != NULL, "coefficient must be VectorDeltaCoefficient");
int dof = fe.GetDof();
int spaceDim = Trans.GetSpaceDim();
vshape.SetSize(dof, spaceDim);
fe.CalcPhysVShape(Trans, vshape);
vec_delta->EvalDelta(vec, Trans, Trans.GetIntPoint());
elvect.SetSize(dof);
vshape.Mult(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 VectorFEBoundaryFluxLFIntegrator::AssembleRHSElementVect(
const FiniteElement &el, ElementTransformation &Tr, Vector &elvect)
{
int dof = el.GetDof();
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);
el.CalcShape(ip, shape);
double val = ip.weight;
if (F)
{
Tr.SetIntPoint (&ip);
val *= F->Eval(Tr, ip);
}
elvect.Add(val, shape);
}
}
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 = 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);
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 BoundaryFlowIntegrator::AssembleRHSElementVect(
const FiniteElement &el, ElementTransformation &Tr, Vector &elvect)
{
mfem_error("BoundaryFlowIntegrator::AssembleRHSElementVect\n"
" is not implemented as boundary integrator!\n"
" Use LinearForm::AddBdrFaceIntegrator instead of\n"
" LinearForm::AddBoundaryIntegrator.");
}
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.GetGeometryType(), 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.SetIntPoint(&ip);
// Use Tr.Elem1 transformation for u so that it matches the coefficient
// used with the ConvectionIntegrator and/or the DGTraceIntegrator.
u->Eval(vu, *Tr.Elem1, eip);
if (dim == 1)
{
nor(0) = 2*eip.x - 1.0;
}
else
{
CalcOrtho(Tr.Jacobian(), nor);
}
un = vu * nor;
w = 0.5*alpha*un - beta*fabs(un);
w *= ip.weight*f->Eval(Tr, ip);
elvect.Add(w, shape);
}
}
void DGDirichletLFIntegrator::AssembleRHSElementVect(
const FiniteElement &el, ElementTransformation &Tr, Vector &elvect)
{
mfem_error("DGDirichletLFIntegrator::AssembleRHSElementVect");
}
void DGDirichletLFIntegrator::AssembleRHSElementVect(
const FiniteElement &el, FaceElementTransformations &Tr, Vector &elvect)
{
int dim, ndof;
bool kappa_is_nonzero = (kappa != 0.);
double w;
dim = el.GetDim();
ndof = el.GetDof();
nor.SetSize(dim);
nh.SetSize(dim);
ni.SetSize(dim);
adjJ.SetSize(dim);
if (MQ)
{
mq.SetSize(dim);
}
shape.SetSize(ndof);
dshape.SetSize(ndof, dim);
dshape_dn.SetSize(ndof);
elvect.SetSize(ndof);
elvect = 0.0;
const IntegrationRule *ir = IntRule;
if (ir == NULL)
{
// a simple choice for the integration order; is this OK?
int order = 2*el.GetOrder();
ir = &IntRules.Get(Tr.GetGeometryType(), order);
}
for (int p = 0; p < ir->GetNPoints(); p++)
{
const IntegrationPoint &ip = ir->IntPoint(p);
IntegrationPoint eip;
Tr.Loc1.Transform(ip, eip);
Tr.SetIntPoint(&ip);
if (dim == 1)
{
nor(0) = 2*eip.x - 1.0;
}
else
{
CalcOrtho(Tr.Jacobian(), nor);
}
el.CalcShape(eip, shape);
el.CalcDShape(eip, dshape);
// compute uD through the face transformation
w = ip.weight * uD->Eval(Tr, ip) / Tr.Elem1->Weight();
if (!MQ)
{
if (Q)
{
w *= Q->Eval(Tr, ip);
}
ni.Set(w, nor);
}
else
{
nh.Set(w, nor);
MQ->Eval(mq, Tr, ip);
mq.MultTranspose(nh, ni);
}
CalcAdjugate(Tr.Elem1->Jacobian(), adjJ);
adjJ.Mult(ni, nh);
dshape.Mult(nh, dshape_dn);
elvect.Add(sigma, dshape_dn);
if (kappa_is_nonzero)
{
elvect.Add(kappa*(ni*nor), shape);
}
}
}
void DGElasticityDirichletLFIntegrator::AssembleRHSElementVect(
const FiniteElement &el, ElementTransformation &Tr, Vector &elvect)
{
mfem_error("DGElasticityDirichletLFIntegrator::AssembleRHSElementVect");
}
void DGElasticityDirichletLFIntegrator::AssembleRHSElementVect(
const FiniteElement &el, FaceElementTransformations &Tr, Vector &elvect)
{
MFEM_ASSERT(Tr.Elem2No < 0, "interior boundary is not supported");
#ifdef MFEM_THREAD_SAFE
Vector shape;
DenseMatrix dshape;
DenseMatrix adjJ;
DenseMatrix dshape_ps;
Vector nor;
Vector dshape_dn;
Vector dshape_du;
Vector u_dir;
#endif
const int dim = el.GetDim();
const int ndofs = el.GetDof();
const int nvdofs = dim*ndofs;
elvect.SetSize(nvdofs);
elvect = 0.0;
adjJ.SetSize(dim);
shape.SetSize(ndofs);
dshape.SetSize(ndofs, dim);
dshape_ps.SetSize(ndofs, dim);
nor.SetSize(dim);
dshape_dn.SetSize(ndofs);
dshape_du.SetSize(ndofs);
u_dir.SetSize(dim);
const IntegrationRule *ir = IntRule;
if (ir == NULL)
{
const int order = 2*el.GetOrder(); // <-----
ir = &IntRules.Get(Tr.GetGeometryType(), order);
}
for (int pi = 0; pi < ir->GetNPoints(); ++pi)
{
const IntegrationPoint &ip = ir->IntPoint(pi);
IntegrationPoint eip;
Tr.Loc1.Transform(ip, eip);
Tr.SetIntPoint(&ip);
// Evaluate the Dirichlet b.c. using the face transformation.
uD.Eval(u_dir, Tr, ip);
el.CalcShape(eip, shape);
el.CalcDShape(eip, dshape);
CalcAdjugate(Tr.Elem1->Jacobian(), adjJ);
Mult(dshape, adjJ, dshape_ps);
if (dim == 1)
{
nor(0) = 2*eip.x - 1.0;
}
else
{
CalcOrtho(Tr.Jacobian(), nor);
}
double wL, wM, jcoef;
{
const double w = ip.weight / Tr.Elem1->Weight();
wL = w * lambda->Eval(*Tr.Elem1, eip);
wM = w * mu->Eval(*Tr.Elem1, eip);
jcoef = kappa * (wL + 2.0*wM) * (nor*nor);
dshape_ps.Mult(nor, dshape_dn);
dshape_ps.Mult(u_dir, dshape_du);
}
// alpha < uD, (lambda div(v) I + mu (grad(v) + grad(v)^T)) . n > +
// + kappa < h^{-1} (lambda + 2 mu) uD, v >
// i = idof + ndofs * im
// v_phi(i,d) = delta(im,d) phi(idof)
// div(v_phi(i)) = dphi(idof,im)
// (grad(v_phi(i)))(k,l) = delta(im,k) dphi(idof,l)
//
// term 1:
// alpha < uD, lambda div(v_phi(i)) n >
// alpha lambda div(v_phi(i)) (uD.n) =
// alpha lambda dphi(idof,im) (uD.n) --> quadrature -->
// ip.weight/det(J1) alpha lambda (uD.nor) dshape_ps(idof,im) =
// alpha * wL * (u_dir*nor) * dshape_ps(idof,im)
// term 2:
// < alpha uD, mu grad(v_phi(i)).n > =
// alpha mu uD^T grad(v_phi(i)) n =
// alpha mu uD(k) delta(im,k) dphi(idof,l) n(l) =
// alpha mu uD(im) dphi(idof,l) n(l) --> quadrature -->
// ip.weight/det(J1) alpha mu uD(im) dshape_ps(idof,l) nor(l) =
// alpha * wM * u_dir(im) * dshape_dn(idof)
// term 3:
// < alpha uD, mu (grad(v_phi(i)))^T n > =
// alpha mu n^T grad(v_phi(i)) uD =
// alpha mu n(k) delta(im,k) dphi(idof,l) uD(l) =
// alpha mu n(im) dphi(idof,l) uD(l) --> quadrature -->
// ip.weight/det(J1) alpha mu nor(im) dshape_ps(idof,l) uD(l) =
// alpha * wM * nor(im) * dshape_du(idof)
// term j:
// < kappa h^{-1} (lambda + 2 mu) uD, v_phi(i) > =
// kappa/h (lambda + 2 mu) uD(k) v_phi(i,k) =
// kappa/h (lambda + 2 mu) uD(k) delta(im,k) phi(idof) =
// kappa/h (lambda + 2 mu) uD(im) phi(idof) --> quadrature -->
// [ 1/h = |nor|/det(J1) ]
// ip.weight/det(J1) |nor|^2 kappa (lambda + 2 mu) uD(im) phi(idof) =
// jcoef * u_dir(im) * shape(idof)
wM *= alpha;
const double t1 = alpha * wL * (u_dir*nor);
for (int im = 0, i = 0; im < dim; ++im)
{
const double t2 = wM * u_dir(im);
const double t3 = wM * nor(im);
const double tj = jcoef * u_dir(im);
for (int idof = 0; idof < ndofs; ++idof, ++i)
{
elvect(i) += (t1*dshape_ps(idof,im) + t2*dshape_dn(idof) +
t3*dshape_du(idof) + tj*shape(idof));
}
}
}
}
void VectorQuadratureLFIntegrator::AssembleRHSElementVect(
const FiniteElement &fe, ElementTransformation &Tr, Vector &elvect)
{
const IntegrationRule *ir =
&vqfc.GetQuadFunction().GetSpace()->GetElementIntRule(Tr.ElementNo);
const int nqp = ir->GetNPoints();
const int vdim = vqfc.GetVDim();
const int ndofs = fe.GetDof();
Vector shape(ndofs);
Vector temp(vdim);
elvect.SetSize(vdim * ndofs);
elvect = 0.0;
for (int q = 0; q < nqp; q++)
{
const IntegrationPoint &ip = ir->IntPoint(q);
Tr.SetIntPoint(&ip);
const double w = Tr.Weight() * ip.weight;
vqfc.Eval(temp, Tr, ip);
fe.CalcShape(ip, shape);
for (int ind = 0; ind < vdim; ind++)
{
for (int nd = 0; nd < ndofs; nd++)
{
elvect(nd + ind * ndofs) += w * shape(nd) * temp(ind);
}
}
}
}
void QuadratureLFIntegrator::AssembleRHSElementVect(const FiniteElement &fe,
ElementTransformation &Tr,
Vector &elvect)
{
const IntegrationRule *ir =
&qfc.GetQuadFunction().GetSpace()->GetElementIntRule(Tr.ElementNo);
const int nqp = ir->GetNPoints();
const int ndofs = fe.GetDof();
Vector shape(ndofs);
elvect.SetSize(ndofs);
elvect = 0.0;
for (int q = 0; q < nqp; q++)
{
const IntegrationPoint &ip = ir->IntPoint(q);
Tr.SetIntPoint (&ip);
const double w = Tr.Weight() * ip.weight;
double temp = qfc.Eval(Tr, ip);
fe.CalcShape(ip, shape);
shape *= (w * temp);
elvect += shape;
}
}
}