34 const int num_equations;
38 std::unique_ptr<HyperbolicFormIntegrator> formIntegrator;
40 std::unique_ptr<NonlinearForm> nonlinearForm;
42 std::vector<DenseMatrix> invmass;
43 std::vector<DenseMatrix> weakdiv;
45 mutable real_t max_char_speed;
50 void ComputeInvMass();
52 void ComputeWeakDivergence();
65 std::unique_ptr<HyperbolicFormIntegrator> formIntegrator_,
66 bool preassembleWeakDivergence=
true);
88 std::unique_ptr<HyperbolicFormIntegrator> formIntegrator_,
89 bool preassembleWeakDivergence)
91 num_equations(formIntegrator_->num_equations),
94 formIntegrator(std::move(formIntegrator_)),
95 z(vfes_.GetTrueVSize())
112 if (preassembleWeakDivergence)
114 ComputeWeakDivergence();
118 nonlinearForm->AddDomainIntegrator(formIntegrator.get());
120 nonlinearForm->AddInteriorFaceIntegrator(formIntegrator.get());
121 nonlinearForm->UseExternalIntegrators();
125void DGHyperbolicConservationLaws::ComputeInvMass()
129 invmass.resize(vfes.
GetNE());
130 for (
int i=0; i<vfes.
GetNE(); i++)
133 invmass[i].SetSize(dof);
134 inv_mass.AssembleElementMatrix(*vfes.
GetFE(i),
140void DGHyperbolicConservationLaws::ComputeWeakDivergence()
142 TransposeIntegrator weak_div(
new GradientIntegrator());
143 DenseMatrix weakdiv_bynodes;
145 weakdiv.resize(vfes.
GetNE());
146 for (
int i=0; i<vfes.
GetNE(); i++)
149 weakdiv_bynodes.SetSize(dof, dof*dim);
150 weak_div.AssembleElementMatrix2(*vfes.
GetFE(i), *vfes.
GetFE(i),
153 weakdiv[i].SetSize(dof, dof*dim);
156 for (
int j=0; j<dof; j++)
158 for (
int d=0; d<
dim; d++)
160 weakdiv[i].SetCol(j*dim + d, weakdiv_bynodes.GetColumn(d*dof + j));
171 formIntegrator->ResetMaxCharSpeed();
176 nonlinearForm->Mult(x, z);
177 if (!weakdiv.empty())
186 const FluxFunction &fluxFunction = formIntegrator->GetFluxFunction();
189 for (
int i=0; i<vfes.
GetNE(); i++)
197 for (
int j=0; j<dof; j++)
199 current_xmat.
GetRow(j, current_state);
202 fluxFunction.
ComputeFlux(current_state, *Tr, current_flux);
211 current_ymat.
SetSize(dof, num_equations);
212 mfem::Mult(invmass[i], current_zmat, current_ymat);
224 for (
int i=0; i<vfes.
GetNE(); i++)
230 current_ymat.
SetSize(dof, num_equations);
231 mfem::Mult(invmass[i], current_zmat, current_ymat);
235 max_char_speed = formIntegrator->GetMaxCharSpeed();
240 nonlinearForm->Update();
241 height = nonlinearForm->Height();
246 if (!weakdiv.empty()) {ComputeWeakDivergence();}
251 const real_t gas_constant,
const real_t specific_heat_ratio)
253 return [specific_heat_ratio,
256 MFEM_ASSERT(x.Size() == 2,
"");
258 const real_t xc = 0.0, yc = 0.0;
261 const real_t vel_inf = 1.;
262 const real_t den_inf = 1.;
265 const real_t pres_inf = (den_inf / specific_heat_ratio) *
266 (vel_inf / Minf) * (vel_inf / Minf);
267 const real_t temp_inf = pres_inf / (den_inf * gas_constant);
270 r2rad += (x(0) - xc) * (x(0) - xc);
271 r2rad += (x(1) - yc) * (x(1) - yc);
274 const real_t shrinv1 = 1.0 / (specific_heat_ratio - 1.);
277 vel_inf * (1 -
beta * (x(1) - yc) /
radius * std::exp(-0.5 * r2rad));
279 vel_inf *
beta * (x(0) - xc) /
radius * std::exp(-0.5 * r2rad);
280 const real_t vel2 = velX * velX + velY * velY;
282 const real_t specific_heat =
283 gas_constant * specific_heat_ratio * shrinv1;
284 const real_t temp = temp_inf - 0.5 * (vel_inf *
beta) *
285 (vel_inf *
beta) / specific_heat *
288 const real_t den = den_inf * std::pow(temp / temp_inf, shrinv1);
289 const real_t pres = den * gas_constant * temp;
290 const real_t energy = shrinv1 * pres / den + 0.5 * vel2;
306 return Mesh(
"../data/periodic-square.mesh");
309 return Mesh(
"../data/periodic-segment.mesh");
312 MFEM_ABORT(
"Problem Undefined");
318 const real_t specific_heat_ratio,
319 const real_t gas_constant)
326 specific_heat_ratio));
330 specific_heat_ratio));
334 MFEM_ASSERT(x.
Size() == 2,
"");
335 const real_t density = 1.0 + 0.2 * std::sin(M_PI*(x(0) + x(1)));
336 const real_t velocity_x = 0.7;
337 const real_t velocity_y = 0.3;
338 const real_t pressure = 1.0;
340 pressure / (1.4 - 1.0) +
341 density * 0.5 * (velocity_x * velocity_x + velocity_y * velocity_y);
344 y(1) = density * velocity_x;
345 y(2) = density * velocity_y;
351 MFEM_ASSERT(x.
Size() == 1,
"");
352 const real_t density = 1.0 + 0.2 * std::sin(M_PI * 2 * x(0));
353 const real_t velocity_x = 1.0;
354 const real_t pressure = 1.0;
356 pressure / (1.4 - 1.0) + density * 0.5 * (velocity_x * velocity_x);
359 y(1) = density * velocity_x;
363 MFEM_ABORT(
"Problem Undefined");
Time dependent DG operator for hyperbolic conservation laws.
void Mult(const Vector &x, Vector &y) const override
Apply nonlinear form to obtain M⁻¹(DIVF + JUMP HAT(F))
DGHyperbolicConservationLaws(FiniteElementSpace &vfes_, std::unique_ptr< HyperbolicFormIntegrator > formIntegrator_, bool preassembleWeakDivergence=true)
Construct a new DGHyperbolicConservationLaws object.
Data type dense matrix using column-major storage.
real_t * GetData() const
Returns the matrix data array.
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
void UseExternalData(real_t *d, int h, int w)
Change the data array and the size of the DenseMatrix.
void GetRow(int r, Vector &row) const
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
ElementTransformation * GetElementTransformation(int i) const
Returns ElementTransformation for the i-th element.
DofTransformation * GetElementVDofs(int i, Array< int > &vdofs) const
Returns indices of degrees of freedom for the i'th element. The returned indices are offsets into an ...
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
int GetNE() const
Returns number of elements in the mesh.
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Abstract class for hyperbolic flux for a system of hyperbolic conservation laws.
virtual real_t ComputeFlux(const Vector &state, ElementTransformation &Tr, DenseMatrix &flux) const =0
Compute flux F(u, x) for given state u and physical point x.
Integrator that inverts the matrix assembled by another integrator.
int width
Dimension of the input / number of columns in the matrix.
int height
Dimension of the output / number of rows in the matrix.
Abstract parallel finite element space.
Base abstract class for first order time dependent operators.
A general vector function coefficient.
void SetSubVector(const Array< int > &dofs, const real_t value)
Set the entries listed in dofs to the given value.
int Size() const
Returns the size of the vector.
void SetSize(int s)
Resize the vector to size s.
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
void AddMult_a_ABt(real_t a, const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
ABt += a * A * B^t.
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Mesh EulerMesh(const int problem)
std::function< void(const Vector &, Vector &)> GetMovingVortexInit(const real_t radius, const real_t Minf, const real_t beta, const real_t gas_constant, const real_t specific_heat_ratio)
VectorFunctionCoefficient EulerInitialCondition(const int problem, const real_t specific_heat_ratio, const real_t gas_constant)