29 M(Mbf), K(Kbf), K_mat(NULL),
b(rhs),
30 lo_solver(NULL), lumpedM(NULL)
54 const int NE = pfes.
GetNE();
61 for (
int k = 0; k < NE; k++)
64 if (active_zones[k] ==
false)
73 MFEM_VERIFY(
adv_mode ==
HO,
"Wrong input for advection mode (-dg).");
81 Vector rhs_loc(nd), dx_loc(nd);
82 for (
int k = 0; k < NE; k++)
86 if (active_zones[k] ==
false)
95 M_loc_inv.
Mult(rhs_loc, dx_loc);
105 for (
int k = 0; k < NE; k++)
107 el_min(k) = numeric_limits<real_t>::infinity();
108 el_max(k) = -numeric_limits<real_t>::infinity();
110 for (
int i = 0; i < ndof; i++)
112 el_min(k) = min(el_min(k), gf(k*ndof + i));
113 el_max(k) = max(el_max(k), gf(k*ndof + i));
118void AdvectionOper::ComputeBounds(
const ParFiniteElementSpace &pfes,
119 const Vector &el_min,
const Vector &el_max,
120 Vector &dof_min, Vector &dof_max)
const
122 ParMesh *pmesh = pfes.GetParMesh();
123 L2_FECollection fec_bounds(0, pmesh->Dimension());
124 ParFiniteElementSpace pfes_bounds(pmesh, &fec_bounds);
125 ParGridFunction el_min_gf(&pfes_bounds), el_max_gf(&pfes_bounds);
126 const int NE = pmesh->GetNE(), ndofs = dof_min.Size() / NE;
131 el_min_gf.ExchangeFaceNbrData(); el_max_gf.ExchangeFaceNbrData();
132 const Vector &min_nbr = el_min_gf.FaceNbrData();
133 const Vector &max_nbr = el_max_gf.FaceNbrData();
134 const Table &el_to_el = pmesh->ElementToElementTable();
135 Array<int> face_nbr_el;
136 for (
int k = 0; k < NE; k++)
138 real_t k_min = el_min_gf(k), k_max = el_max_gf(k);
140 el_to_el.GetRow(k, face_nbr_el);
141 for (
int n = 0; n < face_nbr_el.Size(); n++)
143 if (face_nbr_el[n] < NE)
146 k_min = std::min(k_min, el_min_gf(face_nbr_el[n]));
147 k_max = std::max(k_max, el_max_gf(face_nbr_el[n]));
152 k_min = std::min(k_min, min_nbr(face_nbr_el[n] - NE));
153 k_max = std::max(k_max, max_nbr(face_nbr_el[n] - NE));
157 for (
int j = 0; j < ndofs; j++)
159 dof_min(k*ndofs + j) = k_min;
160 dof_max(k*ndofs + j) = k_max;
198 for (
int k = 0; k < NE; k++)
221 u.ProjectGridFunction(input);
222 for (
int k = 0; k < NE; k++)
226 {
u.SetSubVector(dofs, 0.0); }
233 "Fixed (known) u values",
wsize, 0,
236 "Element markings", 0, 2*
wsize+60,
279 real_t h_min = std::numeric_limits<real_t>::infinity();
280 for (
int k = 0; k < NE; k++)
287 real_t dt = 0.25 * h_min / order / 1.0;
288 real_t half_dt = 0.5 * dt;
299 ode_solver.
Init(adv_oper);
306 TimeLoop(
u, ode_solver, time_period, half_dt,
307 wsize,
"Extrap const u -- LO");
312 std::string mode_text =
"HO";
323 TimeLoop(n_grad_u, ode_solver, time_period, half_dt,
324 2*
wsize,
"Extrap const n.grad(u) -- Aslam -- LO");
329 lhs_bf.Mult(n_grad_u, rhs);
330 TimeLoop(
u, ode_solver, time_period, dt,
331 wsize,
"Extrap linear u -- Aslam -- " + mode_text);
339 TimeLoop(n_grad_n_grad_u, ode_solver, time_period, half_dt,
340 3*
wsize,
"Extrap const n.grad(n.grad(u)) -- Aslam -- LO");
345 lhs_bf.Mult(n_grad_n_grad_u, rhs);
346 TimeLoop(n_grad_u, ode_solver, time_period, dt,
347 2*
wsize,
"Extrap linear n.grad(u) -- Aslam -- " + mode_text);
350 lhs_bf.Mult(n_grad_u, rhs);
351 TimeLoop(
u, ode_solver, time_period, dt,
352 wsize,
"Extrap quadratic u -- Aslam -- " + mode_text);
364 grad_u_0.ProjectCoefficient(grad_u_0_coeff);
366 TimeLoop(grad_u_0, ode_solver, time_period, half_dt,
367 2*
wsize,
"Extrap const du_dx -- Bochkov -- LO");
368 TimeLoop(grad_u_1, ode_solver, time_period, half_dt,
369 3*
wsize,
"Extrap const du_dy -- Bochkov -- LO");
379 TimeLoop(
u, ode_solver, time_period, dt,
380 wsize,
"Extrap linear u -- Bochkov -- " + mode_text);
385 MFEM_ABORT(
"Quadratic Bochkov method is not implemented.");
388 else { MFEM_ABORT(
"Wrong input for extrapolation type (-et)."); }
415 Vector errors_L1(NE), errors_L2(NE), errors_LI(NE);
421 err_L1 = 0.0, err_L2 = 0.0, err_LI = 0.0;
423 for (
int k = 0; k < NE; k++)
427 err_L1 += errors_L1(k);
428 err_L2 += errors_L2(k);
429 err_LI = std::max(err_LI, errors_LI(k));
433 MPI_Comm comm = pmesh.
GetComm();
442 err_L1 /= cut_volume;
443 err_L2 /= cut_volume;
448 int vis_x_pos, std::string vis_name)
455 for (
int ti = 0; !done;)
457 real_t dt_real = min(dt, t_final -
t);
458 ode_solver.
Step(sltn,
t, dt_real);
461 done = (
t >= t_final - 1e-8*dt);
466 cout << vis_name+
" / time step: " << ti <<
", time: " <<
t << endl;
471 vis_name.c_str(), vis_x_pos,
wsize+60,
484 : pfes(
space), K(adv), D(adv), K_smap(), M_lumped(Mlump)
489 for (
int row = 0, j = 0; row < n; row++)
491 for (
int end = I[row+1]; j < end; j++)
495 for (
int _j = I[col], _end = I[col+1];
true; _j++)
497 MFEM_VERIFY(_j != _end,
"Can't find the symmetric entry!");
499 if (J[_j] == row) {
K_smap[j] = _j;
break; }
514 const int s = du.
Size();
515 for (
int i = 0; i <
s; i++)
517 du(i) = (du(i) + rhs(i)) /
M_lumped(i);
530 for (
int i = 0, k = 0; i < n; i++)
533 for (
int end = I[i+1]; k < end; k++)
538 real_t dij = fmax(fmax(0.0,-kij),-kji);
539 D_data[k] = kij + dij;
540 D_data[
K_smap[k]] = kji + dij;
541 if (i != j) { rowsum += dij; }
543 D(i,i) =
K(i,i) - rowsum;
554 u.ExchangeFaceNbrData();
555 const Vector &u_np =
u.FaceNbrData();
557 for (
int i = 0; i <
s; i++)
560 for (
int k = I[i]; k < I[i + 1]; k++)
563 real_t u_j = (j <
s) ?
u(j) : u_np[j -
s];
virtual void Mult(const Vector &x, Vector &dx) const
Perform the action of the operator: y = k = f(x, t), where k solves the algebraic equation F(x,...
enum mfem::AdvectionOper::AdvectionMode adv_mode
AdvectionOper(Array< bool > &zones, ParBilinearForm &Mbf, ParBilinearForm &Kbf, const Vector &rhs)
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Base class Coefficients that optionally depend on space and time. These are used by the BilinearFormI...
void Factor()
Factor the current DenseMatrix, *a.
void Mult(const real_t *x, real_t *y) const
Matrix vector multiplication with the inverse of dense matrix.
Data type dense matrix using column-major storage.
void CalcLOSolution(const Vector &u, const Vector &rhs, Vector &du) const
void ApplyDiscreteUpwindMatrix(ParGridFunction &u, Vector &du) const
void ComputeDiscreteUpwindMatrix() const
ParFiniteElementSpace & pfes
DiscreteUpwindLOSolver(ParFiniteElementSpace &space, const SparseMatrix &adv, const Vector &Mlump)
Class for domain integration .
int GetNE() const
Returns number of elements in the mesh.
int GetOrder(int i) const
Returns the polynomial degree of the i'th finite element.
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Coefficient defined by a GridFunction. This coefficient is mesh dependent.
virtual void ComputeElementL1Errors(Coefficient &exsol, Vector &error, const IntegrationRule *irs[]=NULL) const
virtual void ComputeElementL2Errors(Coefficient &exsol, Vector &error, const IntegrationRule *irs[]=NULL) const
virtual void ComputeElementMaxErrors(Coefficient &exsol, Vector &error, const IntegrationRule *irs[]=NULL) const
void ProjectGridFunction(const GridFunction &src)
Project the src GridFunction to this GridFunction, both of which must be on the same mesh.
Arbitrary order H1-conforming (continuous) finite elements.
HYPRE_Int Mult(HypreParVector &x, HypreParVector &y, real_t alpha=1.0, real_t beta=0.0) const
Computes y = alpha * A * x + beta * y.
Arbitrary order "L2-conforming" discontinuous finite elements.
int GetNE() const
Returns number of elements.
int Dimension() const
Dimension of the reference space used within the elements.
real_t GetElementSize(int i, int type=0)
Get the size of the i-th element relative to the perfect reference element.
real_t GetElementVolume(int i)
Abstract class for solving systems of ODEs: dx/dt = f(x,t)
virtual void Step(Vector &x, real_t &t, real_t &dt)=0
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Abstract parallel finite element space.
void GetElementDofs(int i, Array< int > &dofs, DofTransformation &doftrans) const override
The same as GetElementDofs(), but with a user-allocated DofTransformation object. doftrans must be al...
ParMesh * GetParMesh() const
const FiniteElement * GetFE(int i) const override
Class for parallel grid function.
void ExchangeFaceNbrData()
void ProjectDiscCoefficient(VectorCoefficient &coeff) override
Project a discontinuous vector coefficient as a grid function on a continuous finite element space....
ParFiniteElementSpace * ParFESpace() const
void ProjectCoefficient(Coefficient &coeff) override
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
Class for parallel meshes.
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
void MarkElements(const ParGridFunction &ls_func, Array< int > &elem_marker)
const int * HostReadJ() const
void GetDiag(Vector &d) const
Returns the Diagonal of A.
void GetSubMatrix(const Array< int > &rows, const Array< int > &cols, DenseMatrix &subm) const
const real_t * HostReadData() const
real_t * HostReadWriteData()
int * GetJ()
Return the array J.
int * GetI()
Return the array I.
const int * HostReadI() const
int Size() const
For backward compatibility, define Size() to be synonym of Height().
Base abstract class for first order time dependent operators.
Vector coefficient defined by a vector GridFunction.
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 GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
void VisualizeField(socketstream &sock, const char *vishost, int visport, GridFunction &gf, const char *title, int x, int y, int w, int h, const char *keys, bool vec)
real_t u(const Vector &xvec)
Helper struct to convert a C++ type to an MPI type.