Files
mfem/fem/lininteg.cpp
T
2011-04-08 15:27:24 -07:00

224 lines
5.6 KiB
C++

// Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
// the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
// reserved. See file COPYRIGHT for details.
//
// This file is part of the MFEM library. For more information and source code
// availability see http://mfem.googlecode.com.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the GNU Lesser General Public License (as published by the Free
// Software Foundation) version 2.1 dated February 1999.
#include <math.h>
#include "fem.hpp"
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;
const IntegrationRule *ir;
if (IntRule)
{
ir = IntRule;
}
else
{
// 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);
}
}
inline double sqr(double x)
{
return x * x;
}
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;
int intorder = oa * el.GetOrder() + ob; // <----------
const IntegrationRule &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 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;
int intorder = el.GetOrder() + 1;
const IntegrationRule &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 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;
int intorder = el.GetOrder() + 1;
const IntegrationRule &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 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 = IntRules.Get(el.GetGeomType(),
el.GetOrder() + 1);
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;
if (!IntRule)
ir = &IntRules.Get(el.GetGeomType(), el.GetOrder() + 1);
else
ir = IntRule;
elvect = 0.0;
for (int i = 0; i < ir->GetNPoints(); i++)
{
const IntegrationPoint &ip = ir->IntPoint(i);
Tr.SetIntPoint (&ip);
const DenseMatrix &Jac = Tr.Jacobian();
if (dim == 2)
{
nor(0) = -Jac (1,0);
nor(1) = Jac (0,0);
}
else if (dim == 3)
{
nor(0) = Jac (1,0) * Jac (2,1) - Jac (2,0) * Jac (1,1);
nor(1) = Jac (2,0) * Jac (0,1) - Jac (0,0) * Jac (2,1);
nor(2) = Jac (0,0) * Jac (1,1) - Jac (1,0) * Jac (0,1);
}
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);
}
}