45 GeneralResidualMonitor(MPI_Comm comm,
const std::string& prefix_,
50 print_level = print_lvl;
53 MPI_Comm_rank(comm, &rank);
56 print_level = print_lvl;
65 virtual void MonitorResidual(
int it,
double norm,
const Vector &r,
bool final);
68 const std::string prefix;
73 void GeneralResidualMonitor::MonitorResidual(
int it,
double norm,
74 const Vector &r,
bool final)
76 if (print_level == 1 || (print_level == 3 && (
final || it == 0)))
78 mfem::out << prefix <<
" iteration " << setw(2) << it
79 <<
" : ||r|| = " << norm;
82 mfem::out <<
", ||r||/||r_0|| = " << norm/norm0;
107 class JacobianPreconditioner :
public Solver 134 virtual void SetOperator(
const Operator &op);
136 virtual ~JacobianPreconditioner();
143 class RubberOperator :
public Operator 157 GeneralResidualMonitor newton_monitor;
161 GeneralResidualMonitor j_monitor;
174 Array<int> &block_trueOffsets,
double rel_tol,
double abs_tol,
182 void Solve(
Vector &xp)
const;
184 virtual ~RubberOperator();
191 bool init_vis =
false);
198 int main(
int argc,
char *argv[])
200 #ifdef HYPRE_USING_GPU 201 cout <<
"\nAs of mfem-4.3 and hypre-2.22.0 (July 2021) this example\n" 202 <<
"is NOT supported with the GPU version of hypre.\n\n";
208 const int myid = Mpi::WorldRank();
212 const char *mesh_file =
"../data/beam-tet.mesh";
213 int ser_ref_levels = 0;
214 int par_ref_levels = 0;
216 bool visualization =
true;
217 double newton_rel_tol = 1e-4;
218 double newton_abs_tol = 1e-6;
219 int newton_iter = 500;
223 args.
AddOption(&mesh_file,
"-m",
"--mesh",
224 "Mesh file to use.");
225 args.
AddOption(&ser_ref_levels,
"-rs",
"--refine-serial",
226 "Number of times to refine the mesh uniformly in serial.");
227 args.
AddOption(&par_ref_levels,
"-rp",
"--refine-parallel",
228 "Number of times to refine the mesh uniformly in parallel.");
230 "Order (degree) of the finite elements.");
231 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
232 "--no-visualization",
233 "Enable or disable GLVis visualization.");
234 args.
AddOption(&newton_rel_tol,
"-rel",
"--relative-tolerance",
235 "Relative tolerance for the Newton solve.");
236 args.
AddOption(&newton_abs_tol,
"-abs",
"--absolute-tolerance",
237 "Absolute tolerance for the Newton solve.");
238 args.
AddOption(&newton_iter,
"-it",
"--newton-iterations",
239 "Maximum iterations for the Newton solve.");
241 "Shear modulus for the neo-Hookean material.");
259 Mesh *mesh =
new Mesh(mesh_file, 1, 1);
265 for (
int lev = 0; lev < ser_ref_levels; lev++)
275 for (
int lev = 0; lev < par_ref_levels; lev++)
293 spaces[0] = &R_space;
294 spaces[1] = &W_space;
310 ess_bdr[0] = &ess_bdr_u;
311 ess_bdr[1] = &ess_bdr_p;
316 std::cout <<
"***********************************************************\n";
317 std::cout <<
"dim(u) = " << glob_R_size <<
"\n";
318 std::cout <<
"dim(p) = " << glob_W_size <<
"\n";
319 std::cout <<
"dim(u+p) = " << glob_R_size + glob_W_size <<
"\n";
320 std::cout <<
"***********************************************************\n";
325 block_trueOffsets[0] = 0;
326 block_trueOffsets[1] = R_space.
TrueVSize();
327 block_trueOffsets[2] = W_space.
TrueVSize();
351 RubberOperator oper(spaces, ess_bdr, block_trueOffsets,
352 newton_rel_tol, newton_abs_tol, newton_iter, c_mu);
372 visualize(vis_u, pmesh, &x_gf, &x_def,
"Deformation",
true);
378 visualize(vis_p, pmesh, &x_gf, &p_gf,
"Pressure",
true);
387 ostringstream mesh_name, pressure_name, deformation_name;
388 mesh_name <<
"mesh." << setfill(
'0') << setw(6) << myid;
389 pressure_name <<
"pressure." << setfill(
'0') << setw(6) << myid;
390 deformation_name <<
"deformation." << setfill(
'0') << setw(6) << myid;
392 ofstream mesh_ofs(mesh_name.str().c_str());
393 mesh_ofs.precision(8);
394 pmesh->
Print(mesh_ofs);
396 ofstream pressure_ofs(pressure_name.str().c_str());
397 pressure_ofs.precision(8);
398 p_gf.
Save(pressure_ofs);
400 ofstream deformation_ofs(deformation_name.str().c_str());
401 deformation_ofs.precision(8);
402 x_def.
Save(deformation_ofs);
416 :
Solver(offsets[2]), block_trueOffsets(offsets), pressure_mass(&mass)
427 mass_prec = mass_prec_amg;
438 mass_pcg = mass_pcg_iter;
450 disp_in.
MakeRef(const_cast<Vector&>(k), block_trueOffsets[0],
451 block_trueOffsets[1]-block_trueOffsets[0]);
453 pres_in.
MakeRef(const_cast<Vector&>(k), block_trueOffsets[1],
454 block_trueOffsets[2]-block_trueOffsets[1]);
457 disp_out.
MakeRef(y, block_trueOffsets[0],
458 block_trueOffsets[1]-block_trueOffsets[0]);
460 pres_out.
MakeRef(y, block_trueOffsets[1],
461 block_trueOffsets[2]-block_trueOffsets[1]);
463 Vector temp(block_trueOffsets[1]-block_trueOffsets[0]);
464 Vector temp2(block_trueOffsets[1]-block_trueOffsets[0]);
467 mass_pcg->Mult(pres_in, pres_out);
470 jacobian->GetBlock(0,1).Mult(pres_out, temp);
473 stiff_pcg->Mult(temp2, disp_out);
479 void JacobianPreconditioner::SetOperator(
const Operator &op)
484 if (stiff_prec == NULL)
489 if (!spaces[0]->GetParMesh()->Nonconforming())
491 #if !defined(HYPRE_USING_GPU) 497 stiff_prec = stiff_prec_amg;
507 stiff_pcg = stiff_pcg_iter;
515 JacobianPreconditioner::~JacobianPreconditioner()
531 :
Operator(fes[0]->TrueVSize() + fes[1]->TrueVSize()),
532 newton_solver(fes[0]->GetComm()),
533 newton_monitor(fes[0]->GetComm(),
"Newton", 1),
534 j_monitor(fes[0]->GetComm(),
" GMRES", 3),
535 mu(c_mu), block_trueOffsets(trueOffsets)
549 Hform->SetEssentialBC(ess_bdr, rhs);
558 a->ParallelAssemble(mass);
561 mass.SetOperatorOwner(
false);
562 pressure_mass = mass.Ptr();
565 JacobianPreconditioner *jac_prec =
566 new JacobianPreconditioner(fes, *pressure_mass, block_trueOffsets);
582 newton_solver.SetSolver(*j_solver);
583 newton_solver.SetOperator(*
this);
584 newton_solver.SetPrintLevel(-1);
585 newton_solver.SetMonitor(newton_monitor);
586 newton_solver.SetRelTol(rel_tol);
587 newton_solver.SetAbsTol(abs_tol);
588 newton_solver.SetMaxIter(iter);
592 void RubberOperator::Solve(
Vector &xp)
const 595 newton_solver.Mult(zero, xp);
596 MFEM_VERIFY(newton_solver.GetConverged(),
597 "Newton Solver did not converge.");
612 RubberOperator::~RubberOperator()
615 delete pressure_mass;
638 os <<
"solution\n" << *mesh << *field;
644 os <<
"window_size 800 800\n";
645 os <<
"window_title '" << field_name <<
"'\n";
654 os <<
"autoscale value\n";
670 y[1] = x[1] + 0.25*x[0];
Conjugate gradient method.
Class for grid function - Vector with associated FE space.
virtual Operator & GetGradient(const Vector &x) const
Evaluate the gradient operator at the point x. The default behavior in class Operator is to generate ...
A class to handle Vectors in a block fashion.
A coefficient that is constant across space and time.
void PrintOptions(std::ostream &out) const
Print the options.
int TrueVSize() const
Obsolete, kept for backward compatibility.
void PrintUsage(std::ostream &out) const
Print the usage message.
void SwapNodes(GridFunction *&nodes, int &own_nodes_)
Swap the internal node GridFunction pointer and ownership flag members with the given ones...
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Pointer to an Operator of a specified type.
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
bool Good() const
Return true if the command line options were parsed successfully.
Abstract parallel finite element space.
virtual void ProjectCoefficient(Coefficient &coeff)
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
virtual void SetOperator(const Operator &op) override
Also calls SetOperator for the preconditioner if there is one.
int main(int argc, char *argv[])
The BoomerAMG solver in hypre.
virtual void SetPrintLevel(int print_lvl)
Legacy method to set the level of verbosity of the solver output.
void InitialDeformation(const Vector &x, Vector &y)
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
void SetPrintLevel(int print_level)
void SetMaxIter(int max_it)
Newton's method for solving F(x)=b for a given operator F.
void SetElasticityOptions(ParFiniteElementSpace *fespace)
void ReferenceConfiguration(const Vector &x, Vector &y)
HYPRE_BigInt GlobalTrueVSize() const
A general vector function coefficient.
Abstract base class for an iterative solver monitor.
Mesh * GetMesh() const
Returns the mesh.
void SetAbsTol(double atol)
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
void SetRelTol(double rtol)
void visualize(ostream &os, ParMesh *mesh, ParGridFunction *deformed_nodes, ParGridFunction *field, const char *field_name=NULL, bool init_vis=false)
Base class Coefficients that optionally depend on space and time. These are used by the BilinearFormI...
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
void subtract(const Vector &x, const Vector &y, Vector &z)
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 PartialSum()
Fill the entries of the array with the cumulative sum of the entries.
void Distribute(const Vector *tv)
int SpaceDimension() const
virtual void Save(std::ostream &out) const
void SetMonitor(IterativeSolverMonitor &m)
Set the iterative solver monitor.
void SyncAliasMemory(const Vector &v) const
Update the alias memory location of the vector to match v.
void Copy(Array ©) const
Create a copy of the internal array to the provided copy.
int open(const char hostname[], int port)
Open the socket stream on 'port' at 'hostname'.
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
HypreParVector * GetTrueDofs() const
Returns the true dofs in a new HypreParVector.
void MakeRef(Vector &base, int offset, int size)
Reset the Vector to be a reference to a sub-vector of base.
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.
A class to handle Block systems in a matrix-free implementation.
Class for parallel meshes.
Vector & GetBlock(int i)
Get the i-th vector in the block.