MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
hyperbolic.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
12// Implementation of hyperbolic conservation laws
13
14#include "hyperbolic.hpp"
15#include "nonlinearform.hpp"
16#include "pnonlinearform.hpp"
17
18namespace mfem
19{
20
22 const NumericalFlux &numFlux,
23 const int IntOrderOffset,
24 real_t sign)
26 numFlux(numFlux),
27 fluxFunction(numFlux.GetFluxFunction()),
28 IntOrderOffset(IntOrderOffset),
29 sign(sign),
30 num_equations(fluxFunction.num_equations)
31{
32#ifndef MFEM_THREAD_SAFE
34 flux.SetSize(num_equations, fluxFunction.dim);
35 state1.SetSize(num_equations);
36 state2.SetSize(num_equations);
39 nor.SetSize(fluxFunction.dim);
40#endif
42}
43
46 const Vector &elfun,
47 Vector &elvect)
48{
49 // current element's the number of degrees of freedom
50 // does not consider the number of equations
51 const int dof = el.GetDof();
52
53#ifdef MFEM_THREAD_SAFE
54 // Local storage for element integration
55
56 // shape function value at an integration point
57 Vector shape(dof);
58 // derivative of shape function at an integration point
59 DenseMatrix dshape(dof, Tr.GetSpaceDim());
60 // state value at an integration point
61 Vector state(num_equations);
62 // flux value at an integration point
64#else
65 // resize shape and gradient shape storage
66 shape.SetSize(dof);
67 dshape.SetSize(dof, Tr.GetSpaceDim());
68#endif
69
70 // setDegree-up output vector
71 elvect.SetSize(dof * num_equations);
72 elvect = 0.0;
73
74 // make state variable and output dual vector matrix form.
75 const DenseMatrix elfun_mat(elfun.GetData(), dof, num_equations);
76 DenseMatrix elvect_mat(elvect.GetData(), dof, num_equations);
77
78 // obtain integration rule. If integration is rule is given, then use it.
79 // Otherwise, get (2*p + IntOrderOffset) order integration rule
80 const IntegrationRule *ir = IntRule;
81 if (!ir)
82 {
83 const int order = el.GetOrder()*2 + IntOrderOffset;
84 ir = &IntRules.Get(Tr.GetGeometryType(), order);
85 }
86
87 // loop over integration points
88 for (int i = 0; i < ir->GetNPoints(); i++)
89 {
90 const IntegrationPoint &ip = ir->IntPoint(i);
91 Tr.SetIntPoint(&ip);
92
93 el.CalcShape(ip, shape);
94 el.CalcPhysDShape(Tr, dshape);
95 // compute current state value with given shape function values
96 elfun_mat.MultTranspose(shape, state);
97 // compute F(u,x) and point maximum characteristic speed
98
99 const real_t mcs = fluxFunction.ComputeFlux(state, Tr, flux);
100 // update maximum characteristic speed
101 max_char_speed = std::max(mcs, max_char_speed);
102 // integrate (F(u,x), grad v)
103 AddMult_a_ABt(ip.weight * Tr.Weight() * sign, dshape, flux, elvect_mat);
104 }
105}
106
108 const FiniteElement &el, ElementTransformation &Tr, const Vector &elfun,
109 DenseMatrix &grad)
110{
111 // current element's the number of degrees of freedom
112 // does not consider the number of equations
113 const int dof = el.GetDof();
114
115#ifdef MFEM_THREAD_SAFE
116 // Local storage for element integration
117
118 // shape function value at an integration point
119 Vector shape(dof);
120 // derivative of shape function at an integration point
121 DenseMatrix dshape(dof, Tr.GetSpaceDim());
122 // state value at an integration point
123 Vector state(num_equations);
124 // Jacobian value at an integration point
125 DenseTensor J(num_equations, num_equations, fluxFunction.dim);
126#else
127 // resize shape, gradient shape and Jacobian storage
128 shape.SetSize(dof);
129 dshape.SetSize(dof, Tr.GetSpaceDim());
130 J.SetSize(num_equations, num_equations, fluxFunction.dim);
131#endif
132
133 // setup output gradient matrix
134 grad.SetSize(dof * num_equations);
135 grad = 0.0;
136
137 // make state variable and output dual vector matrix form.
138 const DenseMatrix elfun_mat(elfun.GetData(), dof, num_equations);
139 //DenseMatrix elvect_mat(elvect.GetData(), dof, num_equations);
140
141 // obtain integration rule. If integration is rule is given, then use it.
142 // Otherwise, get (2*p + IntOrderOffset) order integration rule
143 const IntegrationRule *ir = IntRule;
144 if (!ir)
145 {
146 const int order = el.GetOrder()*2 + IntOrderOffset;
147 ir = &IntRules.Get(Tr.GetGeometryType(), order);
148 }
149
150 // loop over integration points
151 for (int q = 0; q < ir->GetNPoints(); q++)
152 {
153 const IntegrationPoint &ip = ir->IntPoint(q);
154 Tr.SetIntPoint(&ip);
155
156 el.CalcShape(ip, shape);
157 el.CalcPhysDShape(Tr, dshape);
158 // compute current state value with given shape function values
159 elfun_mat.MultTranspose(shape, state);
160
161 // compute J(u,x)
162 fluxFunction.ComputeFluxJacobian(state, Tr, J);
163
164 // integrate (J(u,x), grad v)
165 const real_t w = ip.weight * Tr.Weight() * sign;
166 for (int di = 0; di < num_equations; di++)
167 for (int dj = 0; dj < num_equations; dj++)
168 for (int i = 0; i < dof; i++)
169 for (int j = 0; j < dof; j++)
170 for (int d = 0; d < fluxFunction.dim; d++)
171 {
172 grad(di*dof+i, dj*dof+j) += w * dshape(i,d) * shape(j) * J(di,dj,d);
173 }
174 }
175}
176
178 const FiniteElement &el1, const FiniteElement &el2,
179 FaceElementTransformations &Tr, const Vector &elfun, Vector &elvect)
180{
181 // current elements' the number of degrees of freedom
182 // does not consider the number of equations
183 const int dof1 = el1.GetDof();
184 const int dof2 = (Tr.Elem2No >= 0)?(el2.GetDof()):(0);
185
186#ifdef MFEM_THREAD_SAFE
187 // Local storage for element integration
188
189 // shape function value at an integration point - first elem
190 Vector shape1(dof1);
191 // shape function value at an integration point - second elem
192 Vector shape2(dof2);
193 // normal vector (usually not a unit vector)
194 Vector nor(Tr.GetSpaceDim());
195 // state value at an integration point - first elem
196 Vector state1(num_equations);
197 // state value at an integration point - second elem
198 Vector state2(num_equations);
199 // hat(F)(u,x)
200 Vector fluxN(num_equations);
201#else
202 shape1.SetSize(dof1);
203 shape2.SetSize(dof2);
204#endif
205
206 elvect.SetSize((dof1 + dof2) * num_equations);
207 elvect = 0.0;
208
209 const DenseMatrix elfun1_mat(elfun.GetData(), dof1, num_equations);
210 const DenseMatrix elfun2_mat(elfun.GetData() + dof1 * num_equations, dof2,
212
213 DenseMatrix elvect1_mat(elvect.GetData(), dof1, num_equations);
214 DenseMatrix elvect2_mat(elvect.GetData() + dof1 * num_equations, dof2,
216
217 // Obtain integration rule. If integration is rule is given, then use it.
218 // Otherwise, get (2*p + IntOrderOffset) order integration rule
219 const IntegrationRule *ir = IntRule;
220 if (!ir)
221 {
222 const int max_el_order = dof2 ? std::max(el1.GetOrder(),
223 el2.GetOrder()) : el1.GetOrder();
224 const int order = 2*max_el_order + IntOrderOffset;
225 ir = &IntRules.Get(Tr.GetGeometryType(), order);
226 }
227 // loop over integration points
228 for (int i = 0; i < ir->GetNPoints(); i++)
229 {
230 const IntegrationPoint &ip = ir->IntPoint(i);
231
232 Tr.SetAllIntPoints(&ip); // set face and element int. points
233
234 // Calculate basis functions on both elements at the face
235 el1.CalcShape(Tr.GetElement1IntPoint(), shape1);
236
237 // Interpolate elfun at the point
238 elfun1_mat.MultTranspose(shape1, state1);
239
240 if (dof2)
241 {
242 // Calculate basis functions on both elements at the face
243 el2.CalcShape(Tr.GetElement2IntPoint(), shape2);
244 // Interpolate elfun at the point
245 elfun2_mat.MultTranspose(shape2, state2);
246 }
247
248 // Get the normal vector and the flux on the face
249 if (nor.Size() == 1) // if 1D, use 1 or -1.
250 {
251 nor(0) = 2*Tr.GetElement1IntPoint().x - 1.;
252 }
253 else
254 {
255 CalcOrtho(Tr.Jacobian(), nor);
256 }
257 // Compute F(u+, x) and F(u-, x) with maximum characteristic speed
258 // Compute hat(F) using evaluated quantities
259 const real_t speed = (dof2) ? numFlux.Eval(state1, state2, nor, Tr, fluxN):
260 fluxFunction.ComputeFluxDotN(state1, nor, Tr, fluxN);
261
262 // Update the global max char speed
263 max_char_speed = std::max(speed, max_char_speed);
264
265 // pre-multiply integration weight to flux
266 AddMult_a_VWt(-ip.weight*sign, shape1, fluxN, elvect1_mat);
267 if (dof2)
268 {
269 AddMult_a_VWt(+ip.weight*sign, shape2, fluxN, elvect2_mat);
270 }
271 }
272}
273
275 const FiniteElement &el1, const FiniteElement &el2,
276 FaceElementTransformations &Tr, const Vector &elfun, DenseMatrix &elmat)
277{
278 // current elements' the number of degrees of freedom
279 // does not consider the number of equations
280 const int dof1 = el1.GetDof();
281 const int dof2 = (Tr.Elem2No >= 0)?(el2.GetDof()):(0);
282
283#ifdef MFEM_THREAD_SAFE
284 // Local storage for element integration
285
286 // shape function value at an integration point - first elem
287 Vector shape1(dof1);
288 // shape function value at an integration point - second elem
289 Vector shape2(dof2);
290 // normal vector (usually not a unit vector)
291 Vector nor(Tr.GetSpaceDim());
292 // state value at an integration point - first elem
293 Vector state1(num_equations);
294 // state value at an integration point - second elem
295 Vector state2(num_equations);
296 // hat(J)(u,x)
298#else
299 shape1.SetSize(dof1);
300 shape2.SetSize(dof2);
301#endif
302
303 elmat.SetSize((dof1 + dof2) * num_equations);
304 elmat = 0.0;
305
306 const DenseMatrix elfun1_mat(elfun.GetData(), dof1, num_equations);
307 const DenseMatrix elfun2_mat(elfun.GetData() + dof1 * num_equations, dof2,
309
310 // Obtain integration rule. If integration is rule is given, then use it.
311 // Otherwise, get (2*p + IntOrderOffset) order integration rule
312 const IntegrationRule *ir = IntRule;
313 if (!ir)
314 {
315 const int max_el_order = dof2 ? std::max(el1.GetOrder(),
316 el2.GetOrder()) : el1.GetOrder();
317 const int order = 2*max_el_order + IntOrderOffset;
318 ir = &IntRules.Get(Tr.GetGeometryType(), order);
319 }
320 // loop over integration points
321 for (int q = 0; q < ir->GetNPoints(); q++)
322 {
323 const IntegrationPoint &ip = ir->IntPoint(q);
324
325 Tr.SetAllIntPoints(&ip); // set face and element int. points
326
327 // Calculate basis functions of the first element at the face
328 el1.CalcShape(Tr.GetElement1IntPoint(), shape1);
329
330 // Interpolate elfun at the point
331 elfun1_mat.MultTranspose(shape1, state1);
332
333 if (dof2)
334 {
335 // Calculate basis function of the second element at the face
336 el2.CalcShape(Tr.GetElement2IntPoint(), shape2);
337
338 // Interpolate elfun at the point
339 elfun2_mat.MultTranspose(shape2, state2);
340 }
341
342 // Get the normal vector and the flux on the face
343 if (nor.Size() == 1) // if 1D, use 1 or -1.
344 {
345 nor(0) = 2*Tr.GetElement1IntPoint().x - 1.;
346 }
347 else
348 {
349 CalcOrtho(Tr.Jacobian(), nor);
350 }
351
352 // Trial side 1
353
354 // Compute hat(J) using evaluated quantities
355 if (dof2)
356 {
357 numFlux.Grad(1, state1, state2, nor, Tr, JDotN);
358 }
359 else
360 {
361 fluxFunction.ComputeFluxJacobianDotN(state1, nor, Tr, JDotN);
362 }
363
364 const int ioff = fluxFunction.num_equations * dof1;
365
366 for (int di = 0; di < fluxFunction.num_equations; di++)
367 for (int dj = 0; dj < fluxFunction.num_equations; dj++)
368 {
369 // pre-multiply integration weight to Jacobian
370 const real_t w = -ip.weight * sign * JDotN(di,dj);
371 for (int j = 0; j < dof1; j++)
372 {
373 // Test side 1
374 for (int i = 0; i < dof1; i++)
375 {
376 elmat(i+dof1*di, j+dof1*dj) += w * shape1(i) * shape1(j);
377 }
378
379 // Test side 2
380 for (int i = 0; i < dof2; i++)
381 {
382 elmat(ioff+i+dof2*di, j+dof1*dj) -= w * shape2(i) * shape1(j);
383 }
384 }
385 }
386
387 if (dof2)
388 {
389 // Trial side 2
390
391 // Compute hat(J) using evaluated quantities
392 numFlux.Grad(2, state1, state2, nor, Tr, JDotN);
393
394 const int joff = ioff;
395
396 for (int di = 0; di < fluxFunction.num_equations; di++)
397 for (int dj = 0; dj < fluxFunction.num_equations; dj++)
398 {
399 // pre-multiply integration weight to Jacobian
400 const real_t w = +ip.weight * sign * JDotN(di,dj);
401 for (int j = 0; j < dof2; j++)
402 {
403 // Test side 1
404 for (int i = 0; i < dof1; i++)
405 {
406 elmat(i+dof1*di, joff+j+dof2*dj) += w * shape1(i) * shape2(j);
407 }
408
409 // Test side 2
410 for (int i = 0; i < dof2; i++)
411 {
412 elmat(ioff+i+dof2*di, joff+j+dof2*dj) -= w * shape2(i) * shape2(j);
413 }
414 }
415 }
416 }
417 }
418}
419
421 const NumericalFlux &numFlux,
422 VectorCoefficient &bdrState,
423 const int IntOrderOffset,
424 real_t sign)
426 numFlux(numFlux),
427 fluxFunction(numFlux.GetFluxFunction()),
428 u_vcoeff(bdrState),
429 IntOrderOffset(IntOrderOffset),
430 sign(sign),
431 num_equations(fluxFunction.num_equations)
432{
433 MFEM_VERIFY(fluxFunction.num_equations == bdrState.GetVDim(),
434 "Flux function does not match the vector dimension of the coefficient!");
435#ifndef MFEM_THREAD_SAFE
436 state_in.SetSize(num_equations);
437 state_out.SetSize(num_equations);
438 fluxN.SetSize(num_equations);
439 JDotN.SetSize(num_equations);
440 nor.SetSize(fluxFunction.dim);
441#endif
443}
444
446 const FiniteElement &el, const FiniteElement &,
447 FaceElementTransformations &Tr, const Vector &elfun, Vector &elvect)
448{
449 MFEM_ASSERT(Tr.Elem2No < 0, "Not a boundary face!");
450
451 // current elements' the number of degrees of freedom
452 // does not consider the number of equations
453 const int dof = el.GetDof();
454
455#ifdef MFEM_THREAD_SAFE
456 // Local storage for element integration
457
458 // shape function value at an integration point
459 Vector shape(dof);
460 // normal vector (usually not a unit vector)
461 Vector nor(Tr.GetSpaceDim());
462 // state value at an integration point - interior
463 Vector state_in(num_equations);
464 // state value at an integration point - boundary
465 Vector state_out(num_equations);
466 // hat(F)(u,x)
467 Vector fluxN(num_equations);
468#else
469 shape.SetSize(dof);
470#endif
471
472 elvect.SetSize(dof * num_equations);
473 elvect = 0.0;
474
475 const DenseMatrix elfun_mat(elfun.GetData(), dof, num_equations);
476
477 DenseMatrix elvect_mat(elvect.GetData(), dof, num_equations);
478
479 // Obtain integration rule. If integration is rule is given, then use it.
480 // Otherwise, get (2*p + IntOrderOffset) order integration rule
481 const IntegrationRule *ir = IntRule;
482 if (!ir)
483 {
484 const int order = 2*el.GetOrder() + IntOrderOffset;
485 ir = &IntRules.Get(Tr.GetGeometryType(), order);
486 }
487 // loop over integration points
488 for (int i = 0; i < ir->GetNPoints(); i++)
489 {
490 const IntegrationPoint &ip = ir->IntPoint(i);
491
492 Tr.SetAllIntPoints(&ip); // set face and element int. points
493
494 // Calculate basis functions at the face
495 el.CalcShape(Tr.GetElement1IntPoint(), shape);
496
497 // Interpolate elfun at the point
498 elfun_mat.MultTranspose(shape, state_in);
499
500 // Evaluate boundary state at the point
501 u_vcoeff.Eval(state_out, Tr, ip);
502
503 // Get the normal vector and the flux on the face
504 if (nor.Size() == 1) // if 1D, use 1 or -1.
505 {
506 nor(0) = 2*Tr.GetElement1IntPoint().x - 1.;
507 }
508 else
509 {
510 CalcOrtho(Tr.Jacobian(), nor);
511 }
512 // Compute F(u+, x) and F(u_b, x) with maximum characteristic speed
513 // Compute hat(F) using evaluated quantities
514 const real_t speed = numFlux.Eval(state_in, state_out, nor, Tr, fluxN);
515
516 // Update the global max char speed
517 max_char_speed = std::max(speed, max_char_speed);
518
519 // pre-multiply integration weight to flux
520 AddMult_a_VWt(-ip.weight*sign, shape, fluxN, elvect_mat);
521 }
522}
523
525 const FiniteElement &el, const FiniteElement &,
526 FaceElementTransformations &Tr, const Vector &elfun, DenseMatrix &elmat)
527{
528 // current elements' the number of degrees of freedom
529 // does not consider the number of equations
530 const int dof = el.GetDof();
531
532#ifdef MFEM_THREAD_SAFE
533 // Local storage for element integration
534
535 // shape function value at an integration point
536 Vector shape(dof);
537 // normal vector (usually not a unit vector)
538 Vector nor(Tr.GetSpaceDim());
539 // state value at an integration point - interior
540 Vector state_in(num_equations);
541 // state value at an integration point - boundary
542 Vector state_out(num_equations);
543 // hat(J)(u,x)
545#else
546 shape.SetSize(dof);
547#endif
548
549 elmat.SetSize(dof * num_equations);
550 elmat = 0.0;
551
552 const DenseMatrix elfun_mat(elfun.GetData(), dof, num_equations);
553
554 // Obtain integration rule. If integration is rule is given, then use it.
555 // Otherwise, get (2*p + IntOrderOffset) order integration rule
556 const IntegrationRule *ir = IntRule;
557 if (!ir)
558 {
559 const int order = 2*el.GetOrder() + IntOrderOffset;
560 ir = &IntRules.Get(Tr.GetGeometryType(), order);
561 }
562 // loop over integration points
563 for (int q = 0; q < ir->GetNPoints(); q++)
564 {
565 const IntegrationPoint &ip = ir->IntPoint(q);
566
567 Tr.SetAllIntPoints(&ip); // set face and element int. points
568
569 // Calculate basis functions at the face
570 el.CalcShape(Tr.GetElement1IntPoint(), shape);
571
572 // Interpolate elfun at the point
573 elfun_mat.MultTranspose(shape, state_in);
574
575 // Evaluate boundary state at the point
576 u_vcoeff.Eval(state_out, Tr, ip);
577
578 // Get the normal vector and the flux on the face
579 if (nor.Size() == 1) // if 1D, use 1 or -1.
580 {
581 nor(0) = 2*Tr.GetElement1IntPoint().x - 1.;
582 }
583 else
584 {
585 CalcOrtho(Tr.Jacobian(), nor);
586 }
587
588 // Compute hat(J) using evaluated quantities
589 numFlux.Grad(1, state_in, state_out, nor, Tr, JDotN);
590
591 for (int di = 0; di < fluxFunction.num_equations; di++)
592 for (int dj = 0; dj < fluxFunction.num_equations; dj++)
593 {
594 // pre-multiply integration weight to Jacobian
595 const real_t w = -ip.weight * sign * JDotN(di,dj);
596 for (int j = 0; j < dof; j++)
597 for (int i = 0; i < dof; i++)
598 {
599 elmat(i+dof*di, j+dof*dj) += w * shape(i) * shape(j);
600 }
601 }
602 }
603}
604
606 const FluxFunction &flux, VectorCoefficient &u, real_t alpha_, real_t beta_,
607 const int IntOrderOffset_)
608 : fluxFunction(flux), u_vcoeff(u), alpha(alpha_), beta(beta_),
609 IntOrderOffset(IntOrderOffset_)
610{
611 MFEM_VERIFY(fluxFunction.num_equations == u_vcoeff.GetVDim(),
612 "Flux function does not match the vector dimension of the coefficient!");
613#ifndef MFEM_THREAD_SAFE
614 state.SetSize(fluxFunction.num_equations);
615 nor.SetSize(fluxFunction.dim);
616 fluxN.SetSize(fluxFunction.num_equations);
617#endif
619}
620
622 const FiniteElement &el, ElementTransformation &Tr, Vector &elvect)
623{
624 mfem_error("BoundaryHyperbolicFlowIntegrator::AssembleRHSElementVect\n"
625 " is not implemented as boundary integrator!\n"
626 " Use LinearForm::AddBdrFaceIntegrator instead of\n"
627 " LinearForm::AddBoundaryIntegrator.");
628}
629
631 const FiniteElement &el, FaceElementTransformations &Tr, Vector &elvect)
632{
633 // current elements' the number of degrees of freedom
634 // does not consider the number of equations
635 const int dof = el.GetDof();
636
637#ifdef MFEM_THREAD_SAFE
638 // Local storage for element integration
639
640 // shape function value at an integration point
641 Vector shape(dof);
642 // state value at an integration point
643 Vector state(fluxFunction.num_equations);
644 // normal vector (usually not a unit vector)
645 Vector nor(Tr.GetSpaceDim());
646 // hat(F)(u,x)
647 Vector fluxN(fluxFunction.num_equations);
648#else
649 shape.SetSize(dof);
650#endif
651
652 elvect.SetSize(dof * fluxFunction.num_equations);
653 elvect = 0.0;
654
655 DenseMatrix elvect_mat(elvect.GetData(), dof, fluxFunction.num_equations);
656
657 // Obtain integration rule. If integration is rule is given, then use it.
658 // Otherwise, get (2*p + IntOrderOffset) order integration rule
659 const IntegrationRule *ir = IntRule;
660 if (!ir)
661 {
662 const int order = 2*el.GetOrder() + IntOrderOffset;
663 ir = &IntRules.Get(Tr.GetGeometryType(), order);
664 }
665 // loop over integration points
666 for (int i = 0; i < ir->GetNPoints(); i++)
667 {
668 const IntegrationPoint &ip = ir->IntPoint(i);
669
670 Tr.SetAllIntPoints(&ip); // set face and element int. points
671
672 // Calculate basis functions on both elements at the face
673 el.CalcShape(Tr.GetElement1IntPoint(), shape);
674
675 // Evaluate the coefficient at the point
676 u_vcoeff.Eval(state, Tr, ip);
677
678 // Get the normal vector and the flux on the face
679 if (nor.Size() == 1) // if 1D, use 1 or -1.
680 {
681 nor(0) = 2*Tr.GetElement1IntPoint().x - 1.;
682 }
683 else
684 {
685 CalcOrtho(Tr.Jacobian(), nor);
686 }
687 // Compute F(u, x) with maximum characteristic speed
688 const real_t speed = fluxFunction.ComputeFluxDotN(state, nor, Tr, fluxN);
689
690 // Update the global max char speed
691 max_char_speed = std::max(speed, max_char_speed);
692
693 // pre-multiply integration weight to flux
694 const real_t a = 0.5 * alpha * ip.weight;
695 const real_t b = beta * ip.weight;
696
697 for (int n = 0; n < fluxFunction.num_equations; n++)
698 {
699 fluxN(n) = a * fluxN(n) - b * fabs(fluxN(n));
700 }
701
702 AddMultVWt(shape, fluxN, elvect_mat);
703 }
704}
705
707 const Vector &normal,
709 Vector &FUdotN) const
710{
711#ifdef MFEM_THREAD_SAFE
713#else
715#endif
716 real_t val = ComputeFlux(U, Tr, flux);
717 flux.Mult(normal, FUdotN);
718 return val;
719}
720
722 const Vector &normal,
724 Vector &fluxDotN) const
725{
726#ifdef MFEM_THREAD_SAFE
728#else
730#endif
731 real_t val = ComputeAvgFlux(U1, U2, Tr, flux);
732 flux.Mult(normal, fluxDotN);
733 return val;
734}
735
737 const Vector &normal,
739 DenseMatrix &JDotN) const
740{
741#ifdef MFEM_THREAD_SAFE
743#else
745#endif
746 ComputeFluxJacobian(U, Tr, J);
747 JDotN.Set(normal(0), J(0));
748 for (int d = 1; d < dim; d++)
749 {
750 JDotN.AddMatrix(normal(d), J(d), 0, 0);
751 }
752}
753
755 : NumericalFlux(fluxFunction)
756{
757#ifndef MFEM_THREAD_SAFE
760#endif
761}
762
763real_t RusanovFlux::Eval(const Vector &state1, const Vector &state2,
764 const Vector &nor, FaceElementTransformations &Tr,
765 Vector &flux) const
766{
767#ifdef MFEM_THREAD_SAFE
769#endif
770 const real_t speed1 = fluxFunction.ComputeFluxDotN(state1, nor, Tr, fluxN1);
771 const real_t speed2 = fluxFunction.ComputeFluxDotN(state2, nor, Tr, fluxN2);
772 // NOTE: nor in general is not a unit normal
773 const real_t maxE = std::max(speed1, speed2);
774 // here, nor.Norml2() is multiplied to match the scale with fluxN
775 const real_t scaledMaxE = maxE * nor.Norml2();
776 for (int i = 0; i < fluxFunction.num_equations; i++)
777 {
778 flux(i) = 0.5*(scaledMaxE*(state1(i) - state2(i)) + (fluxN1(i) + fluxN2(i)));
779 }
780 return maxE;
781}
782
783void RusanovFlux::Grad(int side, const Vector &state1, const Vector &state2,
784 const Vector &nor, FaceElementTransformations &Tr,
785 DenseMatrix &grad) const
786{
787#ifdef MFEM_THREAD_SAFE
789#endif
790
791 const real_t speed1 = fluxFunction.ComputeFluxDotN(state1, nor, Tr, fluxN1);
792 const real_t speed2 = fluxFunction.ComputeFluxDotN(state2, nor, Tr, fluxN2);
793
794 // NOTE: nor in general is not a unit normal
795 const real_t maxE = std::max(speed1, speed2);
796 // here, nor.Norml2() is multiplied to match the scale with fluxN
797 const real_t scaledMaxE = maxE * nor.Norml2();
798
799 if (side == 1)
800 {
801 fluxFunction.ComputeFluxJacobianDotN(state1, nor, Tr, grad);
802
803 for (int i = 0; i < fluxFunction.num_equations; i++)
804 {
805 grad(i,i) += 0.5 * scaledMaxE;
806 }
807 }
808 else
809 {
810 fluxFunction.ComputeFluxJacobianDotN(state2, nor, Tr, grad);
811
812 for (int i = 0; i < fluxFunction.num_equations; i++)
813 {
814 grad(i,i) -= 0.5 * scaledMaxE;
815 }
816 }
817}
818
819real_t RusanovFlux::Average(const Vector &state1, const Vector &state2,
820 const Vector &nor, FaceElementTransformations &Tr,
821 Vector &flux) const
822{
823#ifdef MFEM_THREAD_SAFE
825#endif
826 const real_t speed1 = fluxFunction.ComputeFluxDotN(state1, nor, Tr, fluxN1);
827 const real_t speed2 = fluxFunction.ComputeAvgFluxDotN(state1, state2, nor, Tr,
828 fluxN2);
829 // NOTE: nor in general is not a unit normal
830 const real_t maxE = std::max(speed1, speed2);
831 // here, nor.Norml2() is multiplied to match the scale with fluxN
832 const real_t scaledMaxE = maxE * nor.Norml2() * 0.5;
833 for (int i = 0; i < fluxFunction.num_equations; i++)
834 {
835 flux(i) = 0.5*(scaledMaxE*(state1(i) - state2(i)) + (fluxN1(i) + fluxN2(i)));
836 }
837 return maxE;
838}
839
840void RusanovFlux::AverageGrad(int side, const Vector &state1,
841 const Vector &state2,
842 const Vector &nor, FaceElementTransformations &Tr,
843 DenseMatrix &grad) const
844{
845#ifdef MFEM_THREAD_SAFE
847#endif
848
849#if defined(MFEM_USE_DOUBLE)
850 constexpr real_t tol = 1e-12;
851#elif defined(MFEM_USE_SINGLE)
852 constexpr real_t tol = 4e-6;
853#else
854#error "Only single and double precision are supported!"
855 constexpr real_t tol = 1.;
856#endif
857
858 auto equal_check = [=](real_t a, real_t b) -> bool { return std::abs(a - b) <= tol * std::abs(a + b); };
859
860 if (side == 1)
861 {
862#ifdef MFEM_THREAD_SAFE
864#else
866#endif
867 const real_t speed1 = fluxFunction.ComputeFluxDotN(state1, nor, Tr, fluxN1);
868 const real_t speed2 = fluxFunction.ComputeAvgFluxDotN(state1, state2, nor, Tr,
869 fluxN2);
871
872 // NOTE: nor in general is not a unit normal
873 const real_t maxE = std::max(speed1, speed2);
874 // here, nor.Norml2() is multiplied to match the scale with fluxN
875 const real_t scaledMaxE = maxE * nor.Norml2() * 0.5;
876
877 grad = 0.;
878
879 for (int i = 0; i < fluxFunction.num_equations; i++)
880 {
881 // Only diagonal terms of J are considered
882 // lim_{u → u⁻} (F̄(u⁻,u)n - F(u⁻)n) / (u - u⁻) = ½λ
883 if (equal_check(state1(i), state2(i))) { continue; }
884 grad(i,i) = 0.5 * ((fluxN2(i) - fluxN1(i)) / (state2(i) - state1(i))
885 - JDotN(i,i) + scaledMaxE);
886 }
887 }
888 else
889 {
890 const real_t speed1 = fluxFunction.ComputeAvgFluxDotN(state1, state2, nor, Tr,
891 fluxN1);
892 const real_t speed2 = fluxFunction.ComputeFluxDotN(state2, nor, Tr, fluxN2);
893
894 // NOTE: nor in general is not a unit normal
895 const real_t maxE = std::max(speed1, speed2);
896 // here, nor.Norml2() is multiplied to match the scale with fluxN
897 const real_t scaledMaxE = maxE * nor.Norml2() * 0.5;
898
899 grad = 0.;
900
901 for (int i = 0; i < fluxFunction.num_equations; i++)
902 {
903 // lim_{u → u⁻} (F(u)n - F̄(u⁻,u)n) / (u - u⁻) = ½λ
904 if (equal_check(state1(i), state2(i))) { continue; }
905 grad(i,i) = 0.5 * ((fluxN2(i) - fluxN1(i)) / (state2(i) - state1(i))
906 - scaledMaxE);
907 }
908 }
909}
910
912 const FluxFunction &fluxFunction)
913 : NumericalFlux(fluxFunction)
914{
915#ifndef MFEM_THREAD_SAFE
918#endif
919 if (fluxFunction.dim > 1)
920 MFEM_WARNING("Upwinded flux is implemented only component-wise.")
921 }
922
924 const Vector &nor, FaceElementTransformations &Tr,
925 Vector &flux) const
926{
927#ifdef MFEM_THREAD_SAFE
929#endif
930 const real_t speed1 = fluxFunction.ComputeFluxDotN(state1, nor, Tr, fluxN1);
931 const real_t speed2 = fluxFunction.ComputeFluxDotN(state2, nor, Tr, fluxN2);
932
933 for (int i = 0; i < fluxFunction.num_equations; i++)
934 {
935 if (state1(i) <= state2(i))
936 {
937 flux(i) = std::min(fluxN1(i), fluxN2(i));
938 }
939 else
940 {
941 flux(i) = std::max(fluxN1(i), fluxN2(i));
942 }
943 }
944
945 return std::max(speed1, speed2);
946}
947
948void ComponentwiseUpwindFlux::Grad(int side, const Vector &state1,
949 const Vector &state2,
950 const Vector &nor, FaceElementTransformations &Tr,
951 DenseMatrix &grad) const
952{
953#ifdef MFEM_THREAD_SAFE
955#else
957#endif
958
959 grad = 0.;
960
961 if (side == 1)
962 {
964
965 for (int i = 0; i < fluxFunction.num_equations; i++)
966 {
967 // Only diagonal terms of J are considered
968 grad(i,i) = std::max(JDotN(i,i), 0_r);
969 }
970 }
971 else
972 {
974
975 for (int i = 0; i < fluxFunction.num_equations; i++)
976 {
977 // Only diagonal terms of J are considered
978 grad(i,i) = std::min(JDotN(i,i), 0_r);
979 }
980 }
981}
982
984 const Vector &state2,
985 const Vector &nor, FaceElementTransformations &Tr,
986 Vector &flux) const
987{
988#ifdef MFEM_THREAD_SAFE
990#endif
991 const real_t speed1 = fluxFunction.ComputeFluxDotN(state1, nor, Tr, fluxN1);
992 const real_t speed2 = fluxFunction.ComputeAvgFluxDotN(state1, state2, nor, Tr,
993 fluxN2);
994
995 for (int i = 0; i < fluxFunction.num_equations; i++)
996 {
997 if (state1(i) <= state2(i))
998 {
999 flux(i) = std::min(fluxN1(i), fluxN2(i));
1000 }
1001 else
1002 {
1003 flux(i) = std::max(fluxN1(i), fluxN2(i));
1004 }
1005 }
1006
1007 return std::max(speed1, speed2);
1008}
1009
1011 const Vector &state2,
1012 const Vector &nor, FaceElementTransformations &Tr,
1013 DenseMatrix &grad) const
1014{
1015#ifdef MFEM_THREAD_SAFE
1017#endif
1018
1019#if defined(MFEM_USE_DOUBLE)
1020 constexpr real_t tol = 1e-12;
1021#elif defined(MFEM_USE_SINGLE)
1022 constexpr real_t tol = 4e-6;
1023#else
1024#error "Only single and double precision are supported!"
1025 constexpr real_t tol = 1.;
1026#endif
1027
1028 auto equal_check = [=](real_t a, real_t b) -> bool { return std::abs(a - b) <= tol * std::abs(a + b); };
1029
1030 if (side == 1)
1031 {
1032#ifdef MFEM_THREAD_SAFE
1034#else
1036#endif
1037 fluxFunction.ComputeFluxDotN(state1, nor, Tr, fluxN1);
1038 fluxFunction.ComputeAvgFluxDotN(state1, state2, nor, Tr, fluxN2);
1039 fluxFunction.ComputeFluxJacobianDotN(state1, nor, Tr, JDotN);
1040
1041 grad = 0.;
1042
1043 for (int i = 0; i < fluxFunction.num_equations; i++)
1044 {
1045 // Only diagonal terms of J are considered
1046 // lim_{u → u⁻} (F̄(u⁻,u)n - F(u⁻)n) / (u - u⁻) = ½J(u⁻)n
1047 const real_t gr12 = (!equal_check(state1(i), state2(i)))?
1048 (fluxN2(i) - fluxN1(i)) / (state2(i) - state1(i))
1049 :(0.5 * JDotN(i,i));
1050 grad(i,i) = (gr12 >= 0.)?(JDotN(i,i)):(gr12);
1051 }
1052 }
1053 else
1054 {
1055#ifdef MFEM_THREAD_SAFE
1057#endif
1058 fluxFunction.ComputeAvgFluxDotN(state1, state2, nor, Tr, fluxN1);
1059 fluxFunction.ComputeFluxDotN(state2, nor, Tr, fluxN2);
1060
1061 // Jacobian is not needed except the limit case when u⁺=u⁻
1062 bool J_needed = false;
1063 for (int i = 0; i < fluxFunction.num_equations; i++)
1064 if (equal_check(state1(i), state2(i)))
1065 {
1066 J_needed = true;
1067 break;
1068 }
1069
1070 if (J_needed)
1071 {
1073 fluxFunction.ComputeFluxJacobianDotN(state1, nor, Tr, JDotN);
1074 }
1075
1076 grad = 0.;
1077
1078 for (int i = 0; i < fluxFunction.num_equations; i++)
1079 {
1080 // Only diagonal terms of J are considered
1081 // lim_{u → u⁻} (F(u)n - F̄(u⁻,u)n) / (u - u⁻) = ½J(u⁻)n
1082 const real_t gr12 = (!equal_check(state1(i), state2(i)))?
1083 (fluxN2(i) - fluxN1(i)) / (state2(i) - state1(i))
1084 :(0.5 * JDotN(i,i));
1085 grad(i,i) = std::min(gr12, 0_r);
1086 }
1087 }
1088}
1089
1092 DenseMatrix &FU) const
1093{
1094#ifdef MFEM_THREAD_SAFE
1095 Vector bval(b.GetVDim());
1096#endif
1097 b.Eval(bval, Tr, Tr.GetIntPoint());
1098 MultVWt(U, bval, FU);
1099 return bval.Norml2();
1100}
1101
1103 const Vector &normal,
1105 Vector &FDotN) const
1106{
1107#ifdef MFEM_THREAD_SAFE
1108 Vector bval(b.GetVDim());
1109#endif
1110 b.Eval(bval, Tr, Tr.GetIntPoint());
1111 FDotN(0) = U(0) * (bval * normal);
1112 return bval.Norml2();
1113}
1114
1117 DenseMatrix &FU) const
1118{
1119#ifdef MFEM_THREAD_SAFE
1120 Vector bval(b.GetVDim());
1121#endif
1122 b.Eval(bval, Tr, Tr.GetIntPoint());
1123 Vector Uavg(1);
1124 Uavg(0) = (U1(0) + U2(0)) * 0.5;
1125 MultVWt(Uavg, bval, FU);
1126 return bval.Norml2();
1127}
1128
1130 const Vector &normal,
1132 Vector &FDotN) const
1133{
1134#ifdef MFEM_THREAD_SAFE
1135 Vector bval(b.GetVDim());
1136#endif
1137 b.Eval(bval, Tr, Tr.GetIntPoint());
1138 FDotN(0) = (U1(0) + U2(0)) * 0.5 * (bval * normal);
1139 return bval.Norml2();
1140}
1141
1144 DenseTensor &J) const
1145{
1146#ifdef MFEM_THREAD_SAFE
1147 Vector bval(b.GetVDim());
1148#endif
1149 b.Eval(bval, Tr, Tr.GetIntPoint());
1150 J = 0.;
1151 for (int d = 0; d < dim; d++)
1152 {
1153 J(0,0,d) = bval(d);
1154 }
1155}
1156
1158 const Vector &normal,
1160 DenseMatrix &JDotN) const
1161{
1162#ifdef MFEM_THREAD_SAFE
1163 Vector bval(b.GetVDim());
1164#endif
1165 b.Eval(bval, Tr, Tr.GetIntPoint());
1166 JDotN(0,0) = bval * normal;
1167}
1168
1171 DenseMatrix &FU) const
1172{
1173 FU = U(0) * U(0) * 0.5;
1174 return std::fabs(U(0));
1175}
1176
1178 const Vector &normal,
1180 Vector &FDotN) const
1181{
1182 FDotN(0) = U(0) * U(0) * 0.5 * normal.Sum();
1183 return std::fabs(U(0));
1184}
1185
1187 const Vector &U2,
1189 DenseMatrix &FU) const
1190{
1191 FU = (U1(0)*U1(0) + U1(0)*U2(0) + U2(0)*U2(0)) / 6.;
1192 return std::max(std::fabs(U1(0)), std::fabs(U2(0)));
1193}
1194
1196 const Vector &U2,
1197 const Vector &normal,
1199 Vector &FDotN) const
1200{
1201 FDotN(0) = (U1(0)*U1(0) + U1(0)*U2(0) + U2(0)*U2(0)) / 6. * normal.Sum();
1202 return std::max(std::fabs(U1(0)), std::fabs(U2(0)));
1203}
1204
1207 DenseTensor &J) const
1208{
1209 J = 0.;
1210 for (int d = 0; d < dim; d++)
1211 {
1212 J(0,0,d) = U(0);
1213 }
1214}
1215
1217 const Vector &normal,
1219 DenseMatrix &JDotN) const
1220{
1221 JDotN(0,0) = U(0) * normal.Sum();
1222}
1223
1226 DenseMatrix &FU) const
1227{
1228 const real_t height = U(0);
1229 const Vector h_vel(U.GetData() + 1, dim);
1230
1231 const real_t energy = 0.5 * g * (height * height);
1232
1233 MFEM_ASSERT(height >= 0, "Negative Height");
1234
1235 for (int d = 0; d < dim; d++)
1236 {
1237 FU(0, d) = h_vel(d);
1238 for (int i = 0; i < dim; i++)
1239 {
1240 FU(1 + i, d) = h_vel(i) * h_vel(d) / height;
1241 }
1242 FU(1 + d, d) += energy;
1243 }
1244
1245 const real_t sound = std::sqrt(g * height);
1246 const real_t vel = std::sqrt(h_vel * h_vel) / height;
1247
1248 return vel + sound;
1249}
1250
1251
1253 const Vector &normal,
1255 Vector &FUdotN) const
1256{
1257 const real_t height = U(0);
1258 const Vector h_vel(U.GetData() + 1, dim);
1259
1260 const real_t energy = 0.5 * g * (height * height);
1261
1262 MFEM_ASSERT(height >= 0, "Negative Height");
1263 FUdotN(0) = h_vel * normal;
1264 const real_t normal_vel = FUdotN(0) / height;
1265 for (int i = 0; i < dim; i++)
1266 {
1267 FUdotN(1 + i) = normal_vel * h_vel(i) + energy * normal(i);
1268 }
1269
1270 const real_t sound = std::sqrt(g * height);
1271 const real_t vel = std::fabs(normal_vel) / std::sqrt(normal*normal);
1272
1273 return vel + sound;
1274}
1275
1276
1279 DenseMatrix &FU) const
1280{
1281 // 1. Get states
1282 const real_t density = U(0); // ρ
1283 const Vector momentum(U.GetData() + 1, dim); // ρu
1284 const real_t energy = U(1 + dim); // E, internal energy ρe
1285 const real_t kinetic_energy = 0.5 * (momentum*momentum) / density;
1286 // pressure, p = (γ-1)*(E - ½ρ|u|^2)
1287 const real_t pressure = (specific_heat_ratio - 1.0) *
1288 (energy - kinetic_energy);
1289
1290 // Check whether the solution is physical only in debug mode
1291 MFEM_ASSERT(density >= 0, "Negative Density");
1292 MFEM_ASSERT(pressure >= 0, "Negative Pressure");
1293 MFEM_ASSERT(energy >= 0, "Negative Energy");
1294
1295 // 2. Compute Flux
1296 for (int d = 0; d < dim; d++)
1297 {
1298 FU(0, d) = momentum(d); // ρu
1299 for (int i = 0; i < dim; i++)
1300 {
1301 // ρuuᵀ
1302 FU(1 + i, d) = momentum(i) * momentum(d) / density;
1303 }
1304 // (ρuuᵀ) + p
1305 FU(1 + d, d) += pressure;
1306 }
1307 // enthalpy H = e + p/ρ = (E + p)/ρ
1308 const real_t H = (energy + pressure) / density;
1309 for (int d = 0; d < dim; d++)
1310 {
1311 // u(E+p) = ρu*(E + p)/ρ = ρu*H
1312 FU(1 + dim, d) = momentum(d) * H;
1313 }
1314
1315 // 3. Compute maximum characteristic speed
1316
1317 // sound speed, √(γ p / ρ)
1318 const real_t sound = std::sqrt(specific_heat_ratio * pressure / density);
1319 // fluid speed |u|
1320 const real_t speed = std::sqrt(2.0 * kinetic_energy / density);
1321 // max characteristic speed = fluid speed + sound speed
1322 return speed + sound;
1323}
1324
1325
1327 const Vector &normal,
1329 Vector &FUdotN) const
1330{
1331 // 1. Get states
1332 const real_t density = x(0); // ρ
1333 const Vector momentum(x.GetData() + 1, dim); // ρu
1334 const real_t energy = x(1 + dim); // E, internal energy ρe
1335 const real_t kinetic_energy = 0.5 * (momentum*momentum) / density;
1336 // pressure, p = (γ-1)*(E - ½ρ|u|^2)
1337 const real_t pressure = (specific_heat_ratio - 1.0) *
1338 (energy - kinetic_energy);
1339
1340 // Check whether the solution is physical only in debug mode
1341 MFEM_ASSERT(density >= 0, "Negative Density");
1342 MFEM_ASSERT(pressure >= 0, "Negative Pressure");
1343 MFEM_ASSERT(energy >= 0, "Negative Energy");
1344
1345 // 2. Compute normal flux
1346
1347 FUdotN(0) = momentum * normal; // ρu⋅n
1348 // u⋅n
1349 const real_t normal_velocity = FUdotN(0) / density;
1350 for (int d = 0; d < dim; d++)
1351 {
1352 // (ρuuᵀ + pI)n = ρu*(u⋅n) + pn
1353 FUdotN(1 + d) = normal_velocity * momentum(d) + pressure * normal(d);
1354 }
1355 // (u⋅n)(E + p)
1356 FUdotN(1 + dim) = normal_velocity * (energy + pressure);
1357
1358 // 3. Compute maximum characteristic speed
1359
1360 // sound speed, √(γ p / ρ)
1361 const real_t sound = std::sqrt(specific_heat_ratio * pressure / density);
1362 // fluid speed |u|
1363 const real_t speed = std::fabs(normal_velocity) / std::sqrt(normal*normal);
1364 // max characteristic speed = fluid speed + sound speed
1365 return speed + sound;
1366}
1367
1368} // namespace mfem
void ComputeFluxJacobian(const Vector &state, ElementTransformation &Tr, DenseTensor &J) const override
Compute J(u)
real_t ComputeFlux(const Vector &state, ElementTransformation &Tr, DenseMatrix &flux) const override
Compute F(u)
void ComputeFluxJacobianDotN(const Vector &state, const Vector &normal, ElementTransformation &Tr, DenseMatrix &JDotN) const override
Compute J(u) n.
real_t ComputeFluxDotN(const Vector &state, const Vector &normal, FaceElementTransformations &Tr, Vector &fluxDotN) const override
Compute F(u) n.
real_t ComputeAvgFlux(const Vector &state1, const Vector &state2, ElementTransformation &Tr, DenseMatrix &flux) const override
Compute average flux F̄(u)
real_t ComputeAvgFluxDotN(const Vector &state1, const Vector &state2, const Vector &normal, FaceElementTransformations &Tr, Vector &fluxDotN) const override
Compute average flux F̄(u) n.
void AssembleFaceGrad(const FiniteElement &el1, const FiniteElement &el2, FaceElementTransformations &Tr, const Vector &elfun, DenseMatrix &elmat) override
Implements <-Ĵ(u⁻,u_b,x) n, [v]> with abstract Ĵ computed by NumericalFlux::Grad() of the numerical...
void ResetMaxCharSpeed()
Reset the maximum characteristic speed to zero.
void AssembleFaceVector(const FiniteElement &el1, const FiniteElement &el2, FaceElementTransformations &Tr, const Vector &elfun, Vector &elvect) override
Implements <-F̂(u⁻,u_b,x) n, [v]> with abstract F̂ computed by NumericalFlux::Eval() of the numerical...
BdrHyperbolicDirichletIntegrator(const NumericalFlux &numFlux, VectorCoefficient &bdrState, const int IntOrderOffset=0, const real_t sign=1.)
Construct a new BdrHyperbolicDirichletIntegrator object.
BoundaryHyperbolicFlowIntegrator(const FluxFunction &flux, VectorCoefficient &u, real_t alpha=-1., int IntOrderOffset=0)
Construct a new BoundaryHyperbolicFlowIntegrator object.
void ResetMaxCharSpeed()
Reset the maximum characteristic speed to zero.
void AssembleRHSElementVect(const FiniteElement &el, ElementTransformation &Tr, Vector &elvect) override
real_t ComputeAvgFluxDotN(const Vector &state1, const Vector &state2, const Vector &normal, FaceElementTransformations &Tr, Vector &fluxDotN) const override
Compute average flux F̄(u) n.
void ComputeFluxJacobianDotN(const Vector &state, const Vector &normal, ElementTransformation &Tr, DenseMatrix &JDotN) const override
Compute J(u) n.
real_t ComputeAvgFlux(const Vector &state1, const Vector &state2, ElementTransformation &Tr, DenseMatrix &flux) const override
Compute average flux F̄(u)
real_t ComputeFluxDotN(const Vector &state, const Vector &normal, FaceElementTransformations &Tr, Vector &fluxDotN) const override
Compute F(u) n.
real_t ComputeFlux(const Vector &state, ElementTransformation &Tr, DenseMatrix &flux) const override
Compute F(u)
void ComputeFluxJacobian(const Vector &state, ElementTransformation &Tr, DenseTensor &J) const override
Compute J(u)
ComponentwiseUpwindFlux(const FluxFunction &fluxFunction)
Constructor for a flux function.
void AverageGrad(int side, const Vector &state1, const Vector &state2, const Vector &nor, FaceElementTransformations &Tr, DenseMatrix &grad) const override
Jacobian of average normal numerical flux over the interval [u⁻, u⁺] in the second argument of the fl...
real_t Average(const Vector &state1, const Vector &state2, const Vector &nor, FaceElementTransformations &Tr, Vector &flux) const override
Average normal numerical flux over the interval [u⁻, u⁺] in the second argument of the flux F̂(u⁻,...
void Grad(int side, const Vector &state1, const Vector &state2, const Vector &nor, FaceElementTransformations &Tr, DenseMatrix &grad) const override
Jacobian of normal numerical flux F̂(u⁻,u⁺,x) n.
real_t Eval(const Vector &state1, const Vector &state2, const Vector &nor, FaceElementTransformations &Tr, Vector &flux) const override
Normal numerical flux F̂(u⁻,u⁺,x) n.
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
void Mult(const real_t *x, real_t *y) const
Matrix vector multiplication.
Definition densemat.cpp:108
void Set(real_t alpha, const real_t *A)
Set the matrix to alpha * A, assuming that A has the same dimensions as the matrix and uses column-ma...
Definition densemat.cpp:580
void MultTranspose(const real_t *x, real_t *y) const
Multiply a vector with the transpose matrix.
Definition densemat.cpp:158
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Definition densemat.hpp:116
void AddMatrix(DenseMatrix &A, int ro, int co)
Perform (ro+i,co+j)+=A(i,j) for 0<=i.
Rank 3 tensor (array of matrices)
void SetSize(int i, int j, int k, MemoryType mt_=MemoryType::PRESERVE)
Geometry::Type GetGeometryType() const
Return the Geometry::Type of the reference element.
Definition eltrans.hpp:175
const IntegrationPoint & GetIntPoint()
Get a const reference to the currently set integration point. This will return NULL if no integration...
Definition eltrans.hpp:111
virtual int GetSpaceDim() const =0
Get the dimension of the target (physical) space.
real_t Weight()
Return the weight of the Jacobian matrix of the transformation at the currently set IntegrationPoint....
Definition eltrans.hpp:144
const DenseMatrix & Jacobian()
Return the Jacobian matrix of the transformation at the currently set IntegrationPoint,...
Definition eltrans.hpp:132
void SetIntPoint(const IntegrationPoint *ip)
Set the integration point ip that weights and Jacobians will be evaluated at.
Definition eltrans.hpp:106
real_t ComputeFlux(const Vector &state, ElementTransformation &Tr, DenseMatrix &flux) const override
Compute F(ρ, ρu, E)
real_t ComputeFluxDotN(const Vector &x, const Vector &normal, FaceElementTransformations &Tr, Vector &fluxN) const override
Compute normal flux, F(ρ, ρu, E)n.
A specialized ElementTransformation class representing a face and its two neighboring elements.
Definition eltrans.hpp:750
const IntegrationPoint & GetElement1IntPoint()
Get a const reference to the integration point in neighboring element 1 corresponding to the currentl...
Definition eltrans.hpp:846
const IntegrationPoint & GetElement2IntPoint()
Get a const reference to the integration point in neighboring element 2 corresponding to the currentl...
Definition eltrans.hpp:856
void SetAllIntPoints(const IntegrationPoint *face_ip)
Set the integration point in the Face and the two neighboring elements, if present.
Definition eltrans.hpp:835
Abstract class for all finite elements.
Definition fe_base.hpp:247
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
Definition fe_base.hpp:341
void CalcPhysDShape(ElementTransformation &Trans, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in physical space at the poi...
Definition fe_base.cpp:202
int GetDim() const
Returns the reference space dimension for the finite element.
Definition fe_base.hpp:324
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const =0
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Definition fe_base.hpp:337
Abstract class for hyperbolic flux for a system of hyperbolic conservation laws.
virtual real_t ComputeAvgFlux(const Vector &state1, const Vector &state2, ElementTransformation &Tr, DenseMatrix &flux_) const
Compute average flux over the given interval of states. Optionally overloaded in a derived class.
virtual real_t ComputeAvgFluxDotN(const Vector &state1, const Vector &state2, const Vector &normal, FaceElementTransformations &Tr, Vector &fluxDotN) const
Compute average normal flux over the given interval of states. Optionally overloaded in a derived cla...
const int num_equations
virtual real_t ComputeFlux(const Vector &state, ElementTransformation &Tr, DenseMatrix &flux) const =0
Compute flux F(u, x). Must be implemented in a derived class.
virtual void ComputeFluxJacobian(const Vector &state, ElementTransformation &Tr, DenseTensor &J_) const
Compute flux Jacobian J(u, x). Optionally overloaded in a derived class when Jacobian is necessary (e...
virtual real_t ComputeFluxDotN(const Vector &state, const Vector &normal, FaceElementTransformations &Tr, Vector &fluxDotN) const
Compute normal flux F(u, x)⋅n. Optionally overloaded in a derived class to avoid creating a full dens...
virtual void ComputeFluxJacobianDotN(const Vector &state, const Vector &normal, ElementTransformation &Tr, DenseMatrix &JDotN) const
Compute normal flux Jacobian J(u, x)⋅n. Optionally overloaded in a derived class to avoid creating a ...
HyperbolicFormIntegrator(const NumericalFlux &numFlux, const int IntOrderOffset=0, const real_t sign=1.)
Construct a new HyperbolicFormIntegrator object.
void AssembleFaceGrad(const FiniteElement &el1, const FiniteElement &el2, FaceElementTransformations &Tr, const Vector &elfun, DenseMatrix &elmat) override
Implements <-Ĵ(u⁻,u⁺,x) n, [v]> with abstract Ĵ computed by NumericalFlux::Grad() of the numerical ...
void AssembleFaceVector(const FiniteElement &el1, const FiniteElement &el2, FaceElementTransformations &Tr, const Vector &elfun, Vector &elvect) override
Implements <-F̂(u⁻,u⁺,x) n, [v]> with abstract F̂ computed by NumericalFlux::Eval() of the numerical ...
void ResetMaxCharSpeed()
Reset the maximum characteristic speed to zero.
void AssembleElementGrad(const FiniteElement &el, ElementTransformation &Tr, const Vector &elfun, DenseMatrix &grad) override
Implements (J(u), ∇v) with abstract J computed by FluxFunction::ComputeFluxJacobian()
void AssembleElementVector(const FiniteElement &el, ElementTransformation &Tr, const Vector &elfun, Vector &elvect) override
Implements (F(u), ∇v) with abstract F computed by FluxFunction::ComputeFlux()
Class for integration point with weight.
Definition intrules.hpp:35
Class for an integration rule - an Array of IntegrationPoint.
Definition intrules.hpp:100
int GetNPoints() const
Returns the number of the points in the integration rule.
Definition intrules.hpp:256
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
Definition intrules.hpp:259
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
const IntegrationRule * IntRule
int GetSpaceDim() const override
Get the dimension of the target (physical) space.
Definition eltrans.hpp:709
This class is used to express the local action of a general nonlinear finite element operator....
Abstract class for numerical flux for a system of hyperbolic conservation laws on a face with states,...
const FluxFunction & fluxFunction
virtual real_t Eval(const Vector &state1, const Vector &state2, const Vector &nor, FaceElementTransformations &Tr, Vector &flux) const =0
Evaluates normal numerical flux for the given states and normal. Must be implemented in a derived cla...
virtual void Grad(int side, const Vector &state1, const Vector &state2, const Vector &nor, FaceElementTransformations &Tr, DenseMatrix &grad) const
Evaluates Jacobian of the normal numerical flux for the given states and normal. Optionally overloade...
RusanovFlux(const FluxFunction &fluxFunction)
Constructor for a flux function.
DenseMatrix JDotN
real_t Average(const Vector &state1, const Vector &state2, const Vector &nor, FaceElementTransformations &Tr, Vector &flux) const override
Average normal numerical flux over the interval [u⁻, u⁺] in the second argument of the flux F̂(u⁻,...
void Grad(int side, const Vector &state1, const Vector &state2, const Vector &nor, FaceElementTransformations &Tr, DenseMatrix &grad) const override
Jacobian of normal numerical flux F̂(u⁻,u⁺,x) n.
void AverageGrad(int side, const Vector &state1, const Vector &state2, const Vector &nor, FaceElementTransformations &Tr, DenseMatrix &grad) const override
Jacobian of average normal numerical flux over the interval [u⁻, u⁺] in the second argument of the fl...
real_t Eval(const Vector &state1, const Vector &state2, const Vector &nor, FaceElementTransformations &Tr, Vector &flux) const override
Normal numerical flux F̂(u⁻,u⁺,x) n.
real_t ComputeFluxDotN(const Vector &state, const Vector &normal, FaceElementTransformations &Tr, Vector &fluxN) const override
Compute normal flux, F(h, hu)
real_t ComputeFlux(const Vector &state, ElementTransformation &Tr, DenseMatrix &flux) const override
Compute F(h, hu)
Base class for vector Coefficients that optionally depend on time and space.
int GetVDim()
Returns dimension of the vector.
virtual void Eval(Vector &V, ElementTransformation &T, const IntegrationPoint &ip)=0
Evaluate the vector coefficient in the element described by T at the point ip, storing the result in ...
Vector data type.
Definition vector.hpp:82
real_t Norml2() const
Returns the l2 norm of the vector.
Definition vector.cpp:968
int Size() const
Returns the size of the vector.
Definition vector.hpp:234
real_t Sum() const
Return the sum of the vector entries.
Definition vector.cpp:1246
void SetSize(int s)
Resize the vector to size s.
Definition vector.hpp:584
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
Definition vector.hpp:243
Vector beta_
const real_t alpha
Definition ex15.cpp:369
real_t b
Definition lissajous.cpp:42
real_t a
Definition lissajous.cpp:41
void CalcOrtho(const DenseMatrix &J, Vector &n)
void AddMult_a_ABt(real_t a, const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
ABt += a * A * B^t.
real_t u(const Vector &xvec)
Definition lor_mms.hpp:22
void mfem_error(const char *msg)
Definition error.cpp:154
void MultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt)
void AddMult_a_VWt(const real_t a, const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += a * v w^t.
void AddMultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += v w^t.
float real_t
Definition config.hpp:46
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Definition intrules.hpp:492
void vel(const Vector &x, real_t t, Vector &u)