57 int main(
int argc,
char *argv[])
60 Mpi::Init(argc, argv);
61 int num_procs = Mpi::WorldSize();
62 int myid = Mpi::WorldRank();
66 const char *mesh_file =
"../data/fichera-mixed.mesh";
73 int ser_ref_levels = 1;
74 int par_ref_levels = 1;
76 double delta_const = 1e-6;
78 bool static_cond =
false;
80 const char *device_config =
"cpu";
81 bool visualization =
true;
87 args.
AddOption(&ser_ref_levels,
"-rs",
"--refine-serial",
88 "Number of times to refine the mesh uniformly in serial.");
89 args.
AddOption(&par_ref_levels,
"-rp",
"--refine-parallel",
90 "Number of times to refine the mesh uniformly in parallel.");
92 "Finite element order (polynomial degree).");
93 args.
AddOption(&delta_const,
"-mc",
"--magnetic-cond",
94 "Magnetic Conductivity");
95 args.
AddOption(&static_cond,
"-sc",
"--static-condensation",
"-no-sc",
96 "--no-static-condensation",
"Enable static condensation.");
97 args.
AddOption(&mixed,
"-mixed",
"--mixed-mesh",
"-hex",
98 "--hex-mesh",
"Mixed mesh of hexahedral mesh.");
99 args.
AddOption(&pa,
"-pa",
"--partial-assembly",
"-no-pa",
100 "--no-partial-assembly",
"Enable Partial Assembly.");
101 args.
AddOption(&device_config,
"-d",
"--device",
102 "Device configuration string, see Device::Configure().");
103 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
104 "--no-visualization",
105 "Enable or disable GLVis visualization.");
107 args.
AddOption(&useAmgX,
"-amgx",
"--useAmgX",
"-no-amgx",
109 "Enable or disable AmgX in MatrixFreeAMS.");
128 mesh_file =
"../data/fichera.mesh";
131 if (submesh_elems.
Size() == 0)
133 if (strcmp(mesh_file,
"../data/fichera-mixed.mesh") == 0)
136 submesh_elems[0] = 0;
137 submesh_elems[1] = 2;
138 submesh_elems[2] = 3;
139 submesh_elems[3] = 4;
140 submesh_elems[4] = 9;
142 else if (strcmp(mesh_file,
"../data/fichera.mesh") == 0)
145 submesh_elems[0] = 10;
146 submesh_elems[1] = 14;
147 submesh_elems[2] = 34;
148 submesh_elems[3] = 36;
149 submesh_elems[4] = 37;
150 submesh_elems[5] = 38;
151 submesh_elems[6] = 39;
154 if (sym_plane_attr.
Size() == 0)
156 if (strcmp(mesh_file,
"../data/fichera-mixed.mesh") == 0 ||
157 strcmp(mesh_file,
"../data/fichera.mesh") == 0)
160 sym_plane_attr[0] = 9;
161 sym_plane_attr[1] = 10;
162 sym_plane_attr[2] = 11;
163 sym_plane_attr[3] = 12;
164 sym_plane_attr[4] = 13;
165 sym_plane_attr[5] = 14;
166 sym_plane_attr[6] = 15;
167 sym_plane_attr[7] = 16;
170 if (phi0_attr.
Size() == 0)
172 if (strcmp(mesh_file,
"../data/fichera-mixed.mesh") == 0 ||
173 strcmp(mesh_file,
"../data/fichera.mesh") == 0)
178 if (phi1_attr.
Size() == 0)
180 if (strcmp(mesh_file,
"../data/fichera-mixed.mesh") == 0 ||
181 strcmp(mesh_file,
"../data/fichera.mesh") == 0)
186 if (jn_zero_attr.
Size() == 0)
188 if (strcmp(mesh_file,
"../data/fichera-mixed.mesh") == 0 ||
189 strcmp(mesh_file,
"../data/fichera.mesh") == 0)
193 for (
int i=0; i<sym_plane_attr.
Size(); i++)
195 jn_zero_attr.
Append(sym_plane_attr[i]);
201 Device device(device_config);
202 if (myid == 0) { device.
Print(); }
207 Mesh *mesh =
new Mesh(mesh_file, 1, 1);
214 if (ser_ref_levels > 0)
224 int submesh_attr = -1;
225 if (cond_attr.
Size() == 0 && submesh_elems.
Size() > 0)
228 submesh_attr = max_attr + 1;
230 for (
int i=0; i<submesh_elems.
Size(); i++)
236 if (cond_attr.
Size() == 0)
238 cond_attr.
Append(submesh_attr);
245 int ref_levels = ser_ref_levels;
246 for (
int l = 0; l < ref_levels; l++)
255 ParMesh pmesh(MPI_COMM_WORLD, *mesh);
258 for (
int l = 0; l < par_ref_levels; l++)
265 ParSubMesh pmesh_cond(ParSubMesh::CreateFromDomain(pmesh, cond_attr));
280 ostringstream mesh_name, cond_name;
281 mesh_name <<
"cond_mesh." << setfill(
'0') << setw(6) << myid;
282 cond_name <<
"cond_j." << setfill(
'0') << setw(6) << myid;
284 ofstream mesh_ofs(mesh_name.str().c_str());
285 mesh_ofs.precision(8);
286 pmesh_cond.
Print(mesh_ofs);
288 ofstream cond_ofs(cond_name.str().c_str());
289 cond_ofs.precision(8);
290 j_cond.
Save(cond_ofs);
298 port_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n";
299 port_sock.precision(8);
300 port_sock <<
"solution\n" << pmesh_cond << j_cond
301 <<
"window_title 'Conductor J'" 302 <<
"window_geometry 400 0 400 350" << flush;
315 pmesh_cond.
Transfer(j_cond, j_full);
323 sol_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n";
324 sol_sock.precision(8);
325 sol_sock <<
"solution\n" << pmesh << j_full
326 <<
"window_title 'J Full'" 327 <<
"window_geometry 400 430 400 350" << flush;
341 for (
int i=0; i<sym_plane_attr.
Size(); i++)
343 ess_bdr[sym_plane_attr[i]-1] = 0;
373 if (pa) {
a.SetAssemblyLevel(AssemblyLevel::PARTIAL); }
381 if (static_cond) {
a.EnableStaticCondensation(); }
386 a.FormLinearSystem(ess_tdof_list, x,
b, A, X, B);
390 cout <<
"\nSolving for magnetic vector potential " 391 <<
"using CG with AMS" << endl;
415 cout <<
"Size of linear system: " 420 (
a.StaticCondensationIsEnabled() ?
a.SCParFESpace() : &fespace_nd);
432 a.RecoverFEMSolution(X,
b, x);
437 ostringstream mesh_name, sol_name;
438 mesh_name <<
"mesh." << setfill(
'0') << setw(6) << myid;
439 sol_name <<
"sol." << setfill(
'0') << setw(6) << myid;
441 ofstream mesh_ofs(mesh_name.str().c_str());
442 mesh_ofs.precision(8);
443 pmesh.
Print(mesh_ofs);
445 ofstream sol_ofs(sol_name.str().c_str());
446 sol_ofs.precision(8);
456 sol_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n";
457 sol_sock.precision(8);
458 sol_sock <<
"solution\n" << pmesh << x
459 <<
"window_title 'Vector Potential'" 460 <<
"window_geometry 800 0 400 350" << flush;
475 ostringstream dsol_name;
476 dsol_name <<
"dsol." << setfill(
'0') << setw(6) << myid;
478 ofstream dsol_ofs(dsol_name.str().c_str());
479 dsol_ofs.precision(8);
489 sol_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n";
490 sol_sock.precision(8);
491 sol_sock <<
"solution\n" << pmesh << dx
492 <<
"window_title 'Magnetic Flux'" 493 <<
"window_geometry 1200 0 400 350" << flush;
525 for (
int i=0; i<phi0_attr.
Size(); i++)
527 ess_bdr_phi[phi0_attr[i]-1] = 1;
529 for (
int i=0; i<phi1_attr.
Size(); i++)
531 ess_bdr_phi[phi1_attr[i]-1] = 1;
533 for (
int i=0; i<jn_zero_attr.
Size(); i++)
535 ess_bdr_j[jn_zero_attr[i]-1] = 1;
555 for (
int i=0; i<phi0_attr.
Size(); i++)
557 bdr0[phi0_attr[i]-1] = 1;
562 for (
int i=0; i<phi1_attr.
Size(); i++)
564 bdr1[phi1_attr[i]-1] = 1;
572 cout <<
"\nSolving for electric potential " 573 <<
"using CG with AMG" << endl;
594 port_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n";
595 port_sock.precision(8);
596 port_sock <<
"solution\n" << pmesh_cond << phi_h1
597 <<
"window_title 'Conductor Potential'" 598 <<
"window_geometry 0 0 400 350" << flush;
617 d_h1.
Mult(phi_h1, b_rt);
624 cout <<
"\nSolving for current density in H(Div) " 625 <<
"using diagonally scaled CG" << endl;
626 cout <<
"Size of linear system: " 627 << glb_size_rt << endl;
virtual void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1)
Conjugate gradient method.
The Auxiliary-space Maxwell Solver in hypre.
A coefficient that is constant across space and time.
void PrintOptions(std::ostream &out) const
Print the options.
int Dimension() const
Dimension of the reference space used within the elements.
void PrintUsage(std::ostream &out) const
Print the usage message.
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve Ax=b with hypre's PCG.
Integrator for (curl u, curl v) for Nedelec elements.
Pointer to an Operator of a specified type.
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
int main(int argc, char *argv[])
void Print(std::ostream &out=mfem::out)
Print the configuration of the MFEM virtual device object.
bool Good() const
Return true if the command line options were parsed successfully.
Abstract parallel finite element space.
void ComputeCurrentDensityOnSubMesh(int order, const Array< int > &phi0_attr, const Array< int > &phi1_attr, const Array< int > &jn_zero_attr, ParGridFunction &j_cond)
void SetPrintLevel(int print_lvl)
Subdomain representation of a topological parent in another ParMesh.
void AddDomainInterpolator(DiscreteInterpolator *di)
Adds a domain interpolator. Assumes ownership of di.
The BoomerAMG solver in hypre.
An auxiliary Maxwell solver for a high-order curl-curl system without high-order assembly.
virtual void SetPrintLevel(int print_lvl)
Legacy method to set the level of verbosity of the solver output.
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
virtual void SetAttributes()
Determine the sets of unique attribute values in domain and boundary elements.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
Jacobi preconditioner in hypre.
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
ParMesh * GetParMesh() const
void SetMaxIter(int max_it)
HYPRE_BigInt GlobalTrueVSize() const
void SetMaxIter(int max_iter)
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
void SetRelTol(double rtol)
void ProjectBdrCoefficient(Coefficient *coeff[], VectorCoefficient *vcoeff, Array< int > &attr)
ParFiniteElementSpace * ParFESpace() const
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...
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
virtual void Save(std::ostream &out) const
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get()...
void SetPreconditioner(HypreSolver &precond)
Set the hypre solver to be used as a preconditioner.
int Size() const
Return the logical size of the array.
for VectorFiniteElements (Nedelec, Raviart-Thomas)
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
void SetAttribute(int i, int attr)
Set the attribute of element i.
Arbitrary order H(curl)-conforming Nedelec finite elements.
Vector coefficient defined by a vector GridFunction.
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
Arbitrary order H1-conforming (continuous) finite elements.
void Print(std::ostream &out=mfem::out) const override
Class for parallel grid function.
static void Transfer(const ParGridFunction &src, ParGridFunction &dst)
Transfer the dofs of a ParGridFunction.
The MFEM Device class abstracts hardware devices such as GPUs, as well as programming models such as ...
Wrapper for hypre's ParCSR matrix class.
virtual void Assemble(int skip_zeros=1)
Construct the internal matrix representation of the discrete linear operator.
Class for parallel meshes.
Array< int > attributes
A list of all unique element attributes used by the Mesh.