56 class JacobianPreconditioner :
public Solver
83 virtual void SetOperator(
const Operator &op);
85 virtual ~JacobianPreconditioner();
92 class RubberOperator :
public Operator
121 Array<int> &block_trueOffsets,
double rel_tol,
double abs_tol,
129 void Solve(
Vector &xp)
const;
131 virtual ~RubberOperator();
137 bool init_vis =
false);
144 int main(
int argc,
char *argv[])
147 const char *mesh_file =
"../data/beam-tet.mesh";
150 bool visualization =
true;
151 double newton_rel_tol = 1e-4;
152 double newton_abs_tol = 1e-6;
153 int newton_iter = 500;
157 args.
AddOption(&mesh_file,
"-m",
"--mesh",
158 "Mesh file to use.");
159 args.
AddOption(&ref_levels,
"-r",
"--refine",
160 "Number of times to refine the mesh uniformly.");
162 "Order (degree) of the finite elements.");
163 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
164 "--no-visualization",
165 "Enable or disable GLVis visualization.");
166 args.
AddOption(&newton_rel_tol,
"-rel",
"--relative-tolerance",
167 "Relative tolerance for the Newton solve.");
168 args.
AddOption(&newton_abs_tol,
"-abs",
"--absolute-tolerance",
169 "Absolute tolerance for the Newton solve.");
170 args.
AddOption(&newton_iter,
"-it",
"--newton-iterations",
171 "Maximum iterations for the Newton solve.");
172 args.
AddOption(&mu,
"-mu",
"--shear-modulus",
173 "Shear modulus for the neo-Hookean material.");
184 Mesh *mesh =
new Mesh(mesh_file, 1, 1);
190 for (
int lev = 0; lev < ref_levels; lev++)
208 spaces[0] = &R_space;
209 spaces[1] = &W_space;
225 ess_bdr[0] = &ess_bdr_u;
226 ess_bdr[1] = &ess_bdr_p;
229 std::cout <<
"***********************************************************\n";
230 std::cout <<
"dim(u) = " << R_size <<
"\n";
231 std::cout <<
"dim(p) = " << W_size <<
"\n";
232 std::cout <<
"dim(u+p) = " << R_size + W_size <<
"\n";
233 std::cout <<
"***********************************************************\n";
237 block_offsets[0] = 0;
238 block_offsets[1] = R_space.
GetVSize();
239 block_offsets[2] = W_space.
GetVSize();
262 RubberOperator oper(spaces, ess_bdr, block_offsets,
263 newton_rel_tol, newton_abs_tol, newton_iter, c_mu);
275 char vishost[] =
"localhost";
277 vis_u.
open(vishost, visport);
279 visualize(vis_u, mesh, &x_gf, &x_def,
"Deformation",
true);
280 vis_p.
open(vishost, visport);
282 visualize(vis_p, mesh, &x_gf, &p_gf,
"Pressure",
true);
291 ofstream mesh_ofs(
"deformed.mesh");
292 mesh_ofs.precision(8);
293 mesh->
Print(mesh_ofs);
295 ofstream pressure_ofs(
"pressure.sol");
296 pressure_ofs.precision(8);
297 p_gf.
Save(pressure_ofs);
299 ofstream deformation_ofs(
"deformation.sol");
300 deformation_ofs.precision(8);
301 x_def.
Save(deformation_ofs);
314 :
Solver(offsets[2]), block_offsets(offsets), pressure_mass(&mass)
324 mass_prec = mass_prec_gs;
335 mass_pcg = mass_pcg_iter;
347 block_offsets[1]-block_offsets[0]);
349 block_offsets[2]-block_offsets[1]);
352 block_offsets[1]-block_offsets[0]);
354 block_offsets[2]-block_offsets[1]);
356 Vector temp(block_offsets[1]-block_offsets[0]);
357 Vector temp2(block_offsets[1]-block_offsets[0]);
360 mass_pcg->Mult(pres_in, pres_out);
363 jacobian->GetBlock(0,1).Mult(pres_out, temp);
366 stiff_pcg->Mult(temp2, disp_out);
369 void JacobianPreconditioner::SetOperator(
const Operator &op)
374 if (stiff_prec == NULL)
378 stiff_prec = stiff_prec_gs;
388 stiff_pcg = stiff_pcg_iter;
396 JacobianPreconditioner::~JacobianPreconditioner()
412 :
Operator(fes[0]->GetVSize() + fes[1]->GetVSize()),
413 newton_solver(), mu(c_mu), block_offsets(offsets)
427 Hform->SetEssentialBC(ess_bdr, rhs);
439 JacobianPreconditioner *jac_prec =
440 new JacobianPreconditioner(fes, *pressure_mass, block_offsets);
455 newton_solver.SetSolver(*j_solver);
456 newton_solver.SetOperator(*
this);
457 newton_solver.SetPrintLevel(1);
458 newton_solver.SetRelTol(rel_tol);
459 newton_solver.SetAbsTol(abs_tol);
460 newton_solver.SetMaxIter(iter);
464 void RubberOperator::Solve(
Vector &xp)
const
467 newton_solver.Mult(zero, xp);
468 MFEM_VERIFY(newton_solver.GetConverged(),
469 "Newton Solver did not converge.");
484 RubberOperator::~RubberOperator()
487 delete pressure_mass;
495 GridFunction *field,
const char *field_name,
bool init_vis)
507 out <<
"solution\n" << *mesh << *field;
513 out <<
"window_size 800 800\n";
514 out <<
"window_title '" << field_name <<
"'\n";
521 out <<
"autoscale value\n";
537 y[1] = x[1] + 0.25*x[0];
void visualize(ostream &out, Mesh *mesh, GridFunction *deformed_nodes, GridFunction *field, const char *field_name=NULL, bool init_vis=false)
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
void InitialDeformation(const Vector &x, Vector &y)
virtual void Print(std::ostream &out=mfem::out) const
Conjugate gradient method.
void ReferenceConfiguration(const Vector &x, Vector &y)
Class for grid function - Vector with associated FE space.
A class to handle Vectors in a block fashion.
Subclass constant coefficient.
virtual Operator & GetGradient(const Vector &x) const
Evaluate the gradient operator at the point x. The default behavior in class Operator is to generate ...
void SwapNodes(GridFunction *&nodes, int &own_nodes_)
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
void Copy(Array ©) const
Create a copy of the current array.
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
int main(int argc, char *argv[])
double * GetData() const
Return a pointer to the beginning of the Vector data.
Data type for Gauss-Seidel smoother of sparse matrix.
virtual void Save(std::ostream &out) const
Save the GridFunction to an output stream.
void SetPrintLevel(int print_lvl)
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
Mesh * GetMesh() const
Returns the mesh.
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
void SetMaxIter(int max_it)
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
Newton's method for solving F(x)=b for a given operator F.
virtual void MakeRef(FiniteElementSpace *f, double *v)
Make the GridFunction reference external data on a new FiniteElementSpace.
void PrintUsage(std::ostream &out) const
int SpaceDimension() const
void SetAbsTol(double atol)
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
void SetRelTol(double rtol)
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Base class Coefficient that may optionally depend on time.
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)
void PartialSum()
Partial Sum.
void PrintOptions(std::ostream &out) const
virtual void ProjectCoefficient(Coefficient &coeff)
int open(const char hostname[], int port)
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
Arbitrary order H1-conforming (continuous) finite elements.
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
A class to handle Block systems in a matrix-free implementation.
Vector & GetBlock(int i)
Get the i-th vector in the block.