Skip to content

Commit

Permalink
Merge pull request OpenSEMBA#5 from lmdiazangulo/main
Browse files Browse the repository at this point in the history
Refactors FE_Evolution
  • Loading branch information
AlejandroMunozManterola authored Apr 19, 2022
2 parents aa834fa + 5074a0a commit 969bca2
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 220 deletions.
270 changes: 106 additions & 164 deletions src/maxwell1D/FE_Evolution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,168 +2,128 @@

namespace Maxwell1D {

FE_Evolution::FE_Evolution(FiniteElementSpace* fes) :
FE_Evolution::FE_Evolution(FiniteElementSpace* fes, Options options) :
TimeDependentOperator(numberOfFieldComponents* fes->GetNDofs()),
opts_(options),
fes_(fes),
MInv_(buildInverseMassMatrix())
MInv_(buildInverseMassMatrix()),
K_(buildDerivativeOperator()),
FE_(buildFluxOperators(Field::Electric)),
FH_(buildFluxOperators(Field::Magnetic))
{
initializeBilinearForms();
}

std::unique_ptr<BilinearForm> FE_Evolution::buildInverseMassMatrix() const
{
auto MInv = std::make_unique<BilinearForm>(fes_);
MInv->AddDomainIntegrator(new InverseIntegrator(new MassIntegrator));

MInv->Assemble();
MInv->Finalize();

return MInv;
}

void FE_Evolution::addDerivativeOperator(
std::unique_ptr<BilinearForm>& form,
const Direction& d, ConstantCoefficient& coeff) const
std::unique_ptr<BilinearForm> FE_Evolution::buildDerivativeOperator() const
{
assert(d == X, "Incorrect argument for direction.");

switch (fluxType) {
case Upwind:
form->AddDomainIntegrator(
new DerivativeIntegrator(coeff, d));
break;
case Centered:
form->AddDomainIntegrator(
new TransposeIntegrator(
new DerivativeIntegrator(coeff, d)));
break;
std::size_t d = 0;
ConstantCoefficient coeff(1.0);

auto K = std::make_unique<BilinearForm>(fes_);
K->AddDomainIntegrator(new TransposeIntegrator(new DerivativeIntegrator(coeff, d)));

K->Assemble();
K->Finalize();

return K;
}

FE_Evolution::FluxOperators FE_Evolution::buildFluxOperators(const Field& f) const
{
FluxOperators res = std::make_pair(
std::make_unique<BilinearForm>(fes_),
std::make_unique<BilinearForm>(fes_)
);

VectorConstantCoefficient n(Vector({ 1.0 }));
{
FluxCoefficient c = interiorFluxCoefficient();
res.first->AddInteriorFaceIntegrator(new MaxwellDGTraceIntegrator(n, c.alpha, c.beta));
}
{
FluxCoefficient c = boundaryFluxCoefficient(f);
res.first->AddInteriorFaceIntegrator(new MaxwellDGTraceIntegrator(n, c.alpha, c.beta));
}
{
FluxCoefficient c = interiorAltFluxCoefficient();
res.second->AddInteriorFaceIntegrator(new MaxwellDGTraceIntegrator(n, c.alpha, c.beta));
}
{
FluxCoefficient c = boundaryAltFluxCoefficient(f);
res.second->AddInteriorFaceIntegrator(new MaxwellDGTraceIntegrator(n, c.alpha, c.beta));
}

res.first->Assemble();
res.first->Finalize();
res.second->Assemble();
res.second->Finalize();

return res;
}

void FE_Evolution::addFluxOperator(
std::unique_ptr<BilinearForm>& form,
const Direction& d, const Vector& abgFace, const Vector& abgBdr) const
FE_Evolution::FluxCoefficient FE_Evolution::interiorFluxCoefficient() const
{
assert(d == X, "Incorrect argument for direction.");

std::vector<VectorConstantCoefficient> n = {
VectorConstantCoefficient(Vector({1.0})),
};

switch (fluxType) {
case Upwind:
form->AddInteriorFaceIntegrator(
new MaxwellDGTraceIntegrator(n[d], abgFace[Alpha], abgFace[Beta]));
form->AddBdrFaceIntegrator(
new MaxwellDGTraceIntegrator(n[d], abgBdr[Alpha], abgBdr[Beta]));
break;

case Centered:
form->AddInteriorFaceIntegrator(
new DGTraceIntegrator(n[d], abgFace[Alpha], abgFace[Beta]));
form->AddBdrFaceIntegrator(
new DGTraceIntegrator(n[d], abgBdr[Alpha], abgBdr[Beta]));
break;
return FluxCoefficient{-1.0, 0.0};
}

FE_Evolution::FluxCoefficient FE_Evolution::interiorAltFluxCoefficient() const
{
switch (opts_.fluxType) {
case FluxType::Centered:
return FluxCoefficient{0.0, 0.0};
case FluxType::Upwind:
return FluxCoefficient{0.0, 0.5}; // TODO??
}
form->Assemble(0);
form->Finalize(0);
}

void FE_Evolution::initializeBilinearForms()
FE_Evolution::FluxCoefficient FE_Evolution::boundaryFluxCoefficient(const Field& f) const
{
double alpha = 0.0;
double beta = 0.0;
ConstantCoefficient coeff;
Vector abIntFaceE({alpha, beta});
Vector abBdrFaceE({alpha, beta});
Vector abIntFaceH({alpha, beta});
Vector abBdrFaceH({alpha, beta});

KEE_ = std::make_unique<BilinearForm>(fes_);
KEH_ = std::make_unique<BilinearForm>(fes_);
KHE_ = std::make_unique<BilinearForm>(fes_);
KHH_ = std::make_unique<BilinearForm>(fes_);

switch (fluxType) {
case Upwind:

switch (bdrCond) {
case PEC:
abIntFaceE[Alpha] = 0.0;
abIntFaceH[Alpha] = 1.0;
abBdrFaceE[Alpha] = 0.0;
abBdrFaceH[Alpha] = 1.0;
abIntFaceE[Beta] = 0.0;
abIntFaceH[Beta] = 0.0;
abBdrFaceE[Beta] = 0.5;
abBdrFaceH[Beta] = 0.0;
break;
default:
throw std::exception("Input a valid Boundary Condition.");
break;
}

coeff = ConstantCoefficient(-1.0);

addFluxOperator(KEE_, X, abIntFaceE, abBdrFaceE);

addDerivativeOperator(KEH_, X, coeff);
addFluxOperator(KEH_, X, abIntFaceE, abBdrFaceE);

switch (bdrCond) {
case PEC:
abIntFaceE[Alpha] = 1.0;
abIntFaceH[Alpha] = 0.0;
abBdrFaceE[Alpha] = 1.0;
abBdrFaceH[Alpha] = 0.0;
abIntFaceE[Beta] = 0.0;
abIntFaceH[Beta] = 0.0;
abBdrFaceE[Beta] = 0.0;
abBdrFaceH[Beta] = 0.5;
break;
default:
throw std::exception("Input a valid Boundary Condition.");
break;
switch (opts_.bdrCond) {
case BdrCond::PEC:
switch (f) {
case Field::Electric:
return FluxCoefficient{ -2.0, 0.0 };
case Field::Magnetic:
return FluxCoefficient{ 0.0, 0.0 };
}
}
}

addFluxOperator(KHH_, X, abIntFaceH, abBdrFaceH);

addDerivativeOperator(KHE_, X, coeff);
addFluxOperator(KHE_, X, abIntFaceH, abBdrFaceH);

break;

case Centered:

switch (bdrCond) {
case PEC:
abIntFaceE[Alpha] = -1.0;
abIntFaceH[Alpha] = -1.0;
abBdrFaceE[Alpha] = 0.0;
abBdrFaceH[Alpha] = -2.0;
break;
case PMC:
abIntFaceE[Alpha] = -1.0;
abIntFaceH[Alpha] = -1.0;
abBdrFaceE[Alpha] = -2.0;
abBdrFaceH[Alpha] = 0.0;
break;
case SMA:
throw std::exception("SMA not available for Centered Flux.");
default:
throw std::exception("Input a valid Boundary Condition.");
break;
FE_Evolution::FluxCoefficient FE_Evolution::boundaryAltFluxCoefficient(const Field& f) const
{
switch (opts_.fluxType) {
case FluxType::Centered:
return FluxCoefficient{ 0.0,0.0 };
case FluxType::Upwind:
switch (opts_.bdrCond) {
case BdrCond::PEC:
switch (f) {
case Field::Electric:
return FluxCoefficient{ 0.0, 0.0 }; // TODO
case Field::Magnetic:
return FluxCoefficient{ 0.0, 0.0 }; // TODO
}
}
}
}

coeff = ConstantCoefficient(1.0);

addDerivativeOperator(KEH_, X, coeff);
addFluxOperator(KEH_, X, abIntFaceE, abBdrFaceE);

addDerivativeOperator(KHE_, X, coeff);
addFluxOperator(KHE_, X, abIntFaceH, abBdrFaceH);

break;
}
void FE_Evolution::constructBilinearForms()
{
MInv_ = buildInverseMassMatrix();
K_ = buildDerivativeOperator();
FE_ = buildFluxOperators(Field::Electric);
FH_ = buildFluxOperators(Field::Magnetic);
}

void FE_Evolution::Mult(const Vector& x, Vector& y) const
Expand All @@ -174,39 +134,21 @@ void FE_Evolution::Mult(const Vector& x, Vector& y) const
GridFunction eNew(fes_, &y[0]);
GridFunction hNew(fes_, &y[fes_->GetNDofs()]);

Vector auxFluxdE(MInv_->Height());
Vector auxFluxdH(MInv_->Height());
Vector auxRHS(MInv_->Height());

switch (fluxType) {
case Upwind:

// Update E. dE/dt = M^{-1} * (-S * H + nx * {H} + 0.5 * [E])).
KEH_->Mult(hOld, auxRHS);
KEE_->Mult(eOld, auxFluxdE);
auxRHS.Add(1.0, auxFluxdE);
MInv_->Mult(auxRHS, eNew);

// Update H. dH/dt = M^{-1} * (-S * E + nx * {E} + 0.5 * [H])).
KHE_->Mult(eOld, auxRHS);
KHH_->Mult(hOld, auxFluxdH);
auxRHS.Add(1.0, auxFluxdH);
MInv_->Mult(auxRHS, hNew);

break;

case Centered:

// Update E. dE/dt = M^{-1} * (S * H - {H}).
KEH_->Mult(hOld, auxRHS);
MInv_->Mult(auxRHS, eNew);

// Update H. dH/dt = M^{-1} * (S * E - {E}).
KHE_->Mult(eOld, auxRHS);
MInv_->Mult(auxRHS, hNew);

break;
}
// Update E. dE/dt = M^{-1} * (-K * H + FE * {H} + altFE * [E])).
auxRHS = 0.0;
K_->AddMult(hOld, auxRHS, -1.0);
FE_.first->AddMult(hOld, auxRHS);
FE_.second->AddMult(eOld, auxRHS);
MInv_->Mult(auxRHS, eNew);

// Update H. dH/dt = M^{-1} * (-K * E + FH * {E} + altFH * [H])).
auxRHS = 0.0;
K_->AddMult(eOld, auxRHS, -1.0);
FH_.first->AddMult(eOld, auxRHS);
FH_.second->AddMult(hOld, auxRHS);
MInv_->Mult(auxRHS, hNew);

}

Expand Down
Loading

0 comments on commit 969bca2

Please sign in to comment.