MFEM v4.10.0
Finite element discretization library
Loading...
Searching...
No Matches
plor-transfer.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2026, 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// -----------------------------------------------------------------------
13// Parallel LOR Transfer Miniapp: Map functions between HO and LOR spaces
14// -----------------------------------------------------------------------
15//
16// This miniapp visualizes the maps between a high-order (HO) finite element
17// space, typically using high-order functions on a high-order mesh, and a
18// low-order refined (LOR) finite element space, typically defined by 0th or 1st
19// order functions on a low-order refinement of the HO mesh.
20//
21// The grid transfer operators are represented using either
22// InterpolationGridTransfer or L2ProjectionGridTransfer (depending on the
23// options requested by the user). The two transfer operators are then:
24//
25// 1. R: HO -> LOR, defined by GridTransfer::ForwardOperator
26// 2. P: LOR -> HO, defined by GridTransfer::BackwardOperator
27//
28// While defined generally, these operators have some nice properties for
29// particular finite element spaces. For example they satisfy PR=I, plus mass
30// conservation in both directions for L2 fields.
31//
32// Compile with: make plor-transfer
33//
34// Sample runs: plor-transfer
35// plor-transfer -h1
36// plor-transfer -ea -w
37// plor-transfer -t
38// plor-transfer -m ../../data/star-q2.mesh -lref 5 -p 4
39// plor-transfer -m ../../data/star-mixed.mesh -lref 3 -p 2
40// plor-transfer -lref 4 -o 4 -lo 0 -p 1
41// plor-transfer -lref 4 -o 4 -lo 0 -p 1
42// plor-transfer -lref 4 -o 4 -lo 2 -p 2
43// plor-transfer -lref 4 -o 4 -lo 0 -p 3
44
45#include "mfem.hpp"
46#include <fstream>
47#include <iostream>
48
49using namespace std;
50using namespace mfem;
51
52int problem = 1; // problem type
53
54int Wx = 0, Wy = 0; // window position
55int Ww = 350, Wh = 350; // window size
56int offx = Ww+5, offy = Wh+25; // window offsets
57
58string space;
59string direction;
60
61// Exact functions to project
62real_t RHO_exact(const Vector &x);
63real_t W_exact(const Vector &x);
64real_t weight(const Vector &x);
65
66// Helper functions
67void visualize(VisItDataCollection &, string, int, int, int /* visport */);
69
70int main(int argc, char *argv[])
71{
72 // Initialize MPI and HYPRE.
73 Mpi::Init(argc, argv);
75
76 // Parse command-line options.
77 const char *mesh_file = "../../data/star.mesh";
78 int order = 2;
79 int lref = order+1;
80 int lorder = 0;
81 bool vis = true;
82 bool useH1 = false;
83 int visport = 19916;
84 bool use_pointwise_transfer = false;
85 bool use_weighted_transfer = false;
86 const char *device_config = "cpu";
87 bool use_ea = false;
88
89 OptionsParser args(argc, argv);
90 args.AddOption(&mesh_file, "-m", "--mesh",
91 "Mesh file to use.");
92 args.AddOption(&problem, "-p", "--problem",
93 "Problem type (see the RHO_exact function).");
94 args.AddOption(&order, "-o", "--order",
95 "Finite element order (polynomial degree) or -1 for"
96 " isoparametric space.");
97 args.AddOption(&lref, "-lref", "--lor-ref-level", "LOR refinement level.");
98 args.AddOption(&lorder, "-lo", "--lor-order",
99 "LOR space order (polynomial degree, zero by default).");
100 args.AddOption(&vis, "-vis", "--visualization", "-no-vis",
101 "--no-visualization",
102 "Enable or disable GLVis visualization.");
103 args.AddOption(&useH1, "-h1", "--use-h1", "-l2", "--use-l2",
104 "Use H1 spaces instead of L2.");
105 args.AddOption(&use_pointwise_transfer, "-t", "--use-pointwise-transfer",
106 "-no-t", "--dont-use-pointwise-transfer",
107 "Use pointwise transfer operators instead of L2 projection.");
108 args.AddOption(&use_weighted_transfer, "-w", "--use-weighted-transfer",
109 "-no-w", "--dont-use-weighted-transfer",
110 "Use coefficient-weighted L2 projection.");
111 args.AddOption(&device_config, "-d", "--device",
112 "Device configuration string, see Device::Configure().");
113 args.AddOption(&use_ea, "-ea", "--ea-version", "-no-ea",
114 "--no-ea-version", "Use element assembly version.");
115 args.ParseCheck();
116
117 // Configure device
118 Device device(device_config);
119 if (Mpi::Root()) { device.Print(); }
120
121 if (use_weighted_transfer && !use_pointwise_transfer)
122 {
123 if (problem != 5 && Mpi::Root())
124 {
125 cout << "Switching to positive problem = 5 for weighted transfer.\n";
126 }
127 problem = 5;
128 }
129
130 // Read the mesh from the given mesh file.
131 Mesh serial_mesh(mesh_file, 1, 1);
132 ParMesh mesh(MPI_COMM_WORLD, serial_mesh);
133 serial_mesh.Clear();
134 int dim = mesh.Dimension();
135
136 // Make initial refinement on serial mesh.
137 for (int l = 0; l < 4; l++)
138 {
139 mesh.UniformRefinement();
140 }
141
142 // Create the low-order refined mesh
143 int basis_lor = BasisType::GaussLobatto; // BasisType::ClosedUniform;
144 ParMesh mesh_lor = ParMesh::MakeRefined(mesh, lref, basis_lor);
145
146 // Create spaces
147 FiniteElementCollection *fec, *fec_lor;
148 if (useH1)
149 {
150 space = "H1";
151 if (lorder == 0)
152 {
153 lorder = 1;
154 if (Mpi::Root())
155 {
156 cerr << "Switching the H1 LOR space order from 0 to 1\n";
157 }
158 }
159 fec = new H1_FECollection(order, dim);
160 fec_lor = new H1_FECollection(lorder, dim);
161 }
162 else
163 {
164 space = "L2";
165 fec = new L2_FECollection(order, dim);
166 fec_lor = new L2_FECollection(lorder, dim);
167 }
168
169 ParFiniteElementSpace fespace(&mesh, fec);
170 ParFiniteElementSpace fespace_lor(&mesh_lor, fec_lor);
171
172 FunctionCoefficient weight_fn_coeff(weight);
173 CoefficientWithOrder weight_coeff;
174 if (use_weighted_transfer)
175 {
176 weight_coeff.coeff = &weight_fn_coeff;
177 weight_coeff.order = 2;
178 }
179
180 ParGridFunction rho(&fespace);
181 ParGridFunction rho_lor(&fespace_lor);
182
183 // Data collections for vis/analysis
184 VisItDataCollection HO_dc(MPI_COMM_WORLD, "HO", &mesh);
185 HO_dc.RegisterField("density", &rho);
186 VisItDataCollection LOR_dc(MPI_COMM_WORLD, "LOR", &mesh_lor);
187 LOR_dc.RegisterField("density", &rho_lor);
188
189 ParBilinearForm M_ho(&fespace);
191 M_ho.Assemble();
192 M_ho.Finalize();
193 HypreParMatrix* M_ho_tdof = M_ho.ParallelAssemble();
194
195 ParBilinearForm M_lor(&fespace_lor);
197 M_lor.Assemble();
198 M_lor.Finalize();
199 HypreParMatrix* M_lor_tdof = M_lor.ParallelAssemble();
200
201 // HO projections
202 direction = "HO -> LOR @ HO";
204 rho.ProjectCoefficient(RHO);
205 // Make sure AMR constraints are satisfied
206 rho.SetTrueVector();
207 rho.SetFromTrueVector();
208
209 real_t ho_mass = compute_mass(rho, -1.0, "HO ", weight_coeff);
210 if (vis) { visualize(HO_dc, "HO", Wx, Wy, visport); Wx += offx; }
211
212 GridTransfer *gt;
213 if (use_pointwise_transfer)
214 {
215 gt = new InterpolationGridTransfer(fespace, fespace_lor);
216 }
217 else
218 {
219 gt = new L2ProjectionGridTransfer(fespace, fespace_lor, weight_coeff,
220 weight_coeff);
221 }
222
223 // Configure element assembly for device acceleration
224 gt->UseEA(use_ea);
225
226 const Operator &R = gt->ForwardOperator();
227
228 // HO->LOR restriction
229 direction = "HO -> LOR @ LOR";
230 R.Mult(rho, rho_lor);
231 compute_mass(rho_lor, ho_mass, "R(HO) ", weight_coeff);
232 if (vis) { visualize(LOR_dc, "R(HO)", Wx, Wy, visport); Wx += offx; }
233 auto global_max = [](const Vector& v)
234 {
235 real_t max = v.Normlinf();
236 MPI_Allreduce(MPI_IN_PLACE, &max, 1, MPITypeMap<real_t>::mpi_type,
237 MPI_MAX, MPI_COMM_WORLD);
238 return max;
239 };
240
241 if (use_weighted_transfer && !use_pointwise_transfer)
242 {
243 // Transfer velocity while conserving rho-weighted momentum.
244 GridFunctionCoefficient rho_coeff(&rho);
245 GridFunctionCoefficient rho_lor_coeff(&rho_lor);
246 ProductCoefficient prod_coeff(weight_fn_coeff, rho_coeff);
247 ProductCoefficient prod_lor_coeff(weight_fn_coeff, rho_lor_coeff);
248 CoefficientWithOrder prod_weight(prod_coeff, order + 2);
249 CoefficientWithOrder prod_lor_weight(prod_lor_coeff, lorder + 2);
250
251 ParGridFunction w(&fespace), w_lor(&fespace_lor);
253 w.ProjectCoefficient(W);
254
255 if (Mpi::Root()) { cout << '\n'; }
256 const real_t ho_momentum = compute_mass(w, -1.0, "rho w HO ", prod_weight);
257
258 L2ProjectionGridTransfer vel_gt(fespace, fespace_lor, prod_weight,
259 prod_lor_weight);
260 vel_gt.UseEA(use_ea);
261 vel_gt.ForwardOperator().Mult(w, w_lor);
262 compute_mass(w_lor, ho_momentum, "rho w LOR", prod_lor_weight);
263
264 if (vel_gt.SupportsBackwardsOperator())
265 {
266 ParGridFunction w_prev = w;
267 vel_gt.BackwardOperator().Mult(w_lor, w);
268 compute_mass(w, ho_momentum, "P(rho w) ", prod_weight);
269
270 w_prev -= w;
271 Vector w_prev_true(fespace.GetTrueVSize());
272 w_prev.GetTrueDofs(w_prev_true);
273 const real_t l_inf = global_max(w_prev_true);
274 if (Mpi::Root())
275 {
276 cout.precision(12);
277 cout << "|w - P(R(w))|_∞ = " << l_inf << "\n\n";
278 }
279 }
280 }
281
283 {
284 const Operator &P = gt->BackwardOperator();
285 // LOR->HO prolongation
286 direction = "HO -> LOR @ HO";
287 ParGridFunction rho_prev = rho;
288 P.Mult(rho_lor, rho);
289 compute_mass(rho, ho_mass, "P(R(HO)) ", weight_coeff);
290 if (vis) { visualize(HO_dc, "P(R(HO))", Wx, Wy, visport); Wx = 0; Wy += offy; }
291
292 rho_prev -= rho;
293 Vector rho_prev_true(fespace.GetTrueVSize());
294 rho_prev.GetTrueDofs(rho_prev_true);
295 real_t l_inf = global_max(rho_prev_true);
296 if (Mpi::Root())
297 {
298 cout.precision(12);
299 cout << "|HO - P(R(HO))|_∞ = " << l_inf << endl;
300 }
301 }
302
303 // HO* to LOR* dual fields
304 ParLinearForm M_rho(&fespace), M_rho_lor(&fespace_lor);
305 auto global_sum = [](const Vector& v)
306 {
307 real_t sum = v.Sum();
308 MPI_Allreduce(MPI_IN_PLACE, &sum, 1, MPITypeMap<real_t>::mpi_type,
309 MPI_SUM, MPI_COMM_WORLD);
310 return sum;
311 };
312 if (!use_pointwise_transfer && gt->SupportsBackwardsOperator())
313 {
314 Vector M_rho_true(fespace.GetTrueVSize());
315 M_ho_tdof->Mult(rho.GetTrueVector(), M_rho_true);
316 fespace.GetRestrictionOperator()->MultTranspose(M_rho_true, M_rho);
317 const Operator &P = gt->BackwardOperator();
318 P.MultTranspose(M_rho, M_rho_lor);
319 real_t ho_dual_mass = global_sum(M_rho);
320 real_t lor_dual_mass = global_sum(M_rho_lor);
321 if (Mpi::Root())
322 {
323 cout << "HO -> LOR dual field: " << abs(ho_dual_mass - lor_dual_mass) << "\n\n";
324 }
325 }
326
327 // LOR projections
328 direction = "LOR -> HO @ LOR";
329 rho_lor.ProjectCoefficient(RHO);
330 ParGridFunction rho_lor_prev = rho_lor;
331 real_t lor_mass = compute_mass(rho_lor, -1.0, "LOR ", weight_coeff);
332 if (vis) { visualize(LOR_dc, "LOR", Wx, Wy, visport); Wx += offx; }
333
335 {
336 const Operator &P = gt->BackwardOperator();
337 // Prolongate to HO space
338 direction = "LOR -> HO @ HO";
339 P.Mult(rho_lor, rho);
340 compute_mass(rho, lor_mass, "P(LOR) ", weight_coeff);
341 if (vis) { visualize(HO_dc, "P(LOR)", Wx, Wy, visport); Wx += offx; }
342
343 // Restrict back to LOR space. This won't give the original function because
344 // the rho_lor doesn't necessarily live in the range of R.
345 direction = "LOR -> HO @ LOR";
346 R.Mult(rho, rho_lor);
347 compute_mass(rho_lor, lor_mass, "R(P(LOR))", weight_coeff);
348 if (vis) { visualize(LOR_dc, "R(P(LOR))", Wx, Wy, visport); }
349
350 rho_lor_prev -= rho_lor;
351 Vector rho_lor_prev_true(fespace_lor.GetTrueVSize());
352 rho_lor_prev.GetTrueDofs(rho_lor_prev_true);
353 real_t l_inf = global_max(rho_lor_prev_true);
354 if (Mpi::Root())
355 {
356 cout.precision(12);
357 cout << "|LOR - R(P(LOR))|_∞ = " << l_inf << endl;
358 }
359 }
360
361 // LOR* to HO* dual fields
362 if (!use_pointwise_transfer)
363 {
364 Vector M_rho_lor_true(fespace_lor.GetTrueVSize());
365 M_lor_tdof->Mult(rho_lor.GetTrueVector(), M_rho_lor_true);
366 fespace_lor.GetRestrictionOperator()->MultTranspose(M_rho_lor_true,
367 M_rho_lor);
368 R.MultTranspose(M_rho_lor, M_rho);
369 real_t ho_dual_mass = global_sum(M_rho);
370 real_t lor_dual_mass = global_sum(M_rho_lor);
371
372 if (Mpi::Root())
373 {
374 cout << "lor dual mass = " << lor_dual_mass << '\n';
375 cout << "ho dual mass = " << ho_dual_mass << '\n';
376 cout << "LOR -> HO dual field: " << abs(ho_dual_mass - lor_dual_mass) << '\n';
377 }
378 }
379
380 delete fec;
381 delete fec_lor;
382 delete M_ho_tdof;
383 delete M_lor_tdof;
384 delete gt;
385
386 return 0;
387}
388
389
391{
392 switch (problem)
393 {
394 case 1: // smooth field
395 return x(1)+0.25*cos(2*M_PI*x.Norml2());
396 case 2: // cubic function
397 return x(1)*x(1)*x(1) + 2*x(0)*x(1) + x(0);
398 case 3: // sharp gradient
399 return M_PI/2-atan(5*(2*x.Norml2()-1));
400 case 4: // basis function
401 return (x.Norml2() < 0.1) ? 1 : 0;
402 case 5: // positive function
403 return 2.0 + 2*x(0)*x(0) + 3*x(1)*x(1) - x(0)*x(1) + 0.1*sin(x.Norml2());
404 default:
405 return 1.0;
406 }
407}
408
409
411{
412 return x(1) + 0.25*cos(2*M_PI*x.Norml2());
413}
414
415
417{
418 return x(0)*x(0) + x(1)*x(1) + 1.0;
419}
420
421
422void visualize(VisItDataCollection &dc, string prefix, int x, int y,
423 int visport)
424{
425 int w = Ww, h = Wh;
426
427 char vishost[] = "localhost";
428
429 socketstream sol_sockL2(vishost, visport);
430 sol_sockL2 << "parallel " << Mpi::WorldSize() << " " << Mpi::WorldRank() <<
431 "\n";
432 sol_sockL2.precision(8);
433 sol_sockL2 << "solution\n" << *dc.GetMesh() << *dc.GetField("density")
434 << "window_geometry " << x << " " << y << " " << w << " " << h
435 << "plot_caption '" << space << " " << prefix << " Density'"
436 << "window_title '" << direction << "'" << flush;
437}
438
439
440real_t compute_mass(ParGridFunction &gf, real_t oldmass, string prefix,
441 CoefficientWithOrder mass_coeff)
442{
444 Mesh &mesh = *fes.GetMesh();
445
446 // Integration order is a * (element order) + b.
447 const int a = 2;
448 const int b = mesh.GetTypicalElementTransformation()->OrderW() +
449 mass_coeff.order;
450
451 ConstantCoefficient one(1.0);
452 Coefficient &coeff = mass_coeff ? *mass_coeff.coeff : one;
453 DomainLFIntegrator *integ = new DomainLFIntegrator(coeff, a, b);
454
455 ParLinearForm lf(&fes);
456 lf.AddDomainIntegrator(integ);
457 lf.Assemble();
458
459 const real_t newmass = lf(gf);
460 if (Mpi::Root())
461 {
462 cout.precision(18);
463 cout << space << " " << prefix << " mass = " << newmass;
464 if (oldmass >= 0)
465 {
466 cout.precision(4);
467 cout << " (" << fabs(newmass-oldmass)*100/oldmass << "%)";
468 }
469 cout << endl;
470 }
471 return newmass;
472}
@ GaussLobatto
Closed type.
Definition fe_base.hpp:36
void AddDomainIntegrator(BilinearFormIntegrator *bfi)
Adds new Domain Integrator. Assumes ownership of bfi.
void Finalize(int skip_zeros=1) override
Finalizes the matrix initialization if the AssemblyLevel is AssemblyLevel::LEGACY....
Base class Coefficients that optionally depend on space and time. These are used by the BilinearFormI...
A coefficient that is constant across space and time.
GridFunction * GetField(const std::string &field_name)
Get a pointer to a grid function in the collection.
Mesh * GetMesh()
Get a pointer to the mesh in the collection.
The MFEM Device class abstracts hardware devices such as GPUs, as well as programming models such as ...
Definition device.hpp:129
void Print(std::ostream &os=mfem::out)
Print the configuration of the MFEM virtual device object.
Definition device.cpp:319
Class for domain integration .
Definition lininteg.hpp:108
virtual int OrderW() const =0
Return the order of the determinant of the Jacobian (weight) of the transformation.
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
Definition fe_coll.hpp:27
Mesh * GetMesh() const
Returns the mesh.
Definition fespace.hpp:639
A general function coefficient.
Coefficient defined by a GridFunction. This coefficient is mesh dependent.
void SetTrueVector()
Shortcut for calling GetTrueDofs() with GetTrueVector() as argument.
Definition gridfunc.hpp:187
void SetFromTrueVector()
Shortcut for calling SetFromTrueDofs() with GetTrueVector() as argument.
Definition gridfunc.hpp:193
const Vector & GetTrueVector() const
Read only access to the (optional) internal true-dof Vector.
Definition gridfunc.hpp:173
Base class for transfer algorithms that construct transfer Operators between two finite element (FE) ...
Definition transfer.hpp:32
void UseEA(bool use_ea_)
Definition transfer.hpp:78
virtual bool SupportsBackwardsOperator() const
Definition transfer.hpp:117
virtual const Operator & ForwardOperator()=0
Return an Operator that transfers GridFunctions from the domain FE space to GridFunctions in the rang...
virtual const Operator & BackwardOperator()=0
Return an Operator that transfers GridFunctions from the range FE space back to GridFunctions in the ...
Arbitrary order H1-conforming (continuous) finite elements.
Definition fe_coll.hpp:291
Wrapper for hypre's ParCSR matrix class.
Definition hypre.hpp:419
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.
Definition hypre.cpp:1873
static void Init()
Initialize hypre by calling HYPRE_Init() and set default options. After calling Hypre::Init(),...
Definition hypre.cpp:33
Transfer data between a coarse mesh and an embedded refined mesh using interpolation.
Definition transfer.hpp:139
Transfer data in L2 and H1 finite element spaces between a coarse mesh and an embedded refined mesh u...
Definition transfer.hpp:198
const Operator & BackwardOperator() override
Return an Operator that transfers GridFunctions from the range FE space back to GridFunctions in the ...
bool SupportsBackwardsOperator() const override
const Operator & ForwardOperator() override
Return an Operator that transfers GridFunctions from the domain FE space to GridFunctions in the rang...
Arbitrary order "L2-conforming" discontinuous finite elements.
Definition fe_coll.hpp:369
void AddDomainIntegrator(LinearFormIntegrator *lfi)
Adds new Domain Integrator. Assumes ownership of lfi.
Mesh data type.
Definition mesh.hpp:67
void Clear()
Clear the contents of the Mesh.
Definition mesh.hpp:835
int Dimension() const
Dimension of the reference space used within the elements.
Definition mesh.hpp:1314
ElementTransformation * GetTypicalElementTransformation()
If the local mesh is not empty return GetElementTransformation(0); otherwise, return the identity tra...
Definition mesh.cpp:394
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
Definition mesh.cpp:12125
static bool Root()
Return true if the rank in MPI_COMM_WORLD is zero.
static int WorldRank()
Return the MPI rank in MPI_COMM_WORLD.
static int WorldSize()
Return the size of MPI_COMM_WORLD.
static void Init(int &argc, char **&argv, int required=default_thread_required, int *provided=nullptr)
Singleton creation with Mpi::Init(argc, argv).
Abstract operator.
Definition operator.hpp:27
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
virtual void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
Definition operator.hpp:102
void ParseCheck(std::ostream &out=mfem::out)
void AddOption(bool *var, const char *enable_short_name, const char *enable_long_name, const char *disable_short_name, const char *disable_long_name, const char *description, bool required=false)
Add a boolean option and set 'var' to receive the value. Enable/disable tags are used to set the bool...
Definition optparser.hpp:82
Class for parallel bilinear form.
HypreParMatrix * ParallelAssemble()
Returns the matrix assembled on the true dofs, i.e. P^t A P.
void Assemble(int skip_zeros=1)
Assemble the local matrix.
Abstract parallel finite element space.
Definition pfespace.hpp:31
const Operator * GetRestrictionOperator() const override
int GetTrueVSize() const override
Return the number of local vector true dofs.
Definition pfespace.hpp:365
Class for parallel grid function.
Definition pgridfunc.hpp:50
void ProjectCoefficient(Coefficient &coeff, ProjectType type=ProjectType::DEFAULT) override
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
HypreParVector * GetTrueDofs() const
Returns the true dofs in a new HypreParVector.
ParFiniteElementSpace * ParFESpace() const
Class for parallel linear form.
void Assemble()
Assembles the ParLinearForm i.e. sums over all domain/bdr integrators.
Class for parallel meshes.
Definition pmesh.hpp:35
static ParMesh MakeRefined(ParMesh &orig_mesh, int ref_factor, int ref_type)
Create a uniformly refined (by any factor) version of orig_mesh.
Definition pmesh.cpp:1374
Scalar coefficient defined as the product of two scalar coefficients or a scalar and a scalar coeffic...
Vector data type.
Definition vector.hpp:82
real_t Norml2() const
Returns the l2 norm of the vector.
Definition vector.cpp:968
Data collection with VisIt I/O routines.
void RegisterField(const std::string &field_name, GridFunction *gf) override
Add a grid function to the collection and update the root file.
int dim
Definition ex24.cpp:53
int main()
real_t b
Definition lissajous.cpp:42
real_t a
Definition lissajous.cpp:41
float real_t
Definition config.hpp:46
const char vishost[]
STL namespace.
real_t weight(const Vector &x)
int Ww
int Wy
int Wx
int problem
int offx
real_t compute_mass(ParGridFunction &, real_t, string, CoefficientWithOrder)
real_t W_exact(const Vector &x)
int Wh
string direction
void visualize(VisItDataCollection &, string, int, int, int)
real_t RHO_exact(const Vector &x)
string space
int offy
MFEM_HOST_DEVICE real_t abs(const Complex &z)
Helper struct to convert a C++ type to an MPI type.