39class ReducedSystemOperator;
66 ReducedSystemOperator *reduced_oper;
83 void Mult(
const Vector &vx,
Vector &dvx_dt)
const override;
94 ~HyperelasticOperator()
override;
101class ReducedSystemOperator :
public Operator
123 ~ReducedSystemOperator()
override;
138 : model(m), x(x_) { }
140 ~ElasticEnergyCoefficient()
override { }
149 bool init_vis =
false);
152int main(
int argc,
char *argv[])
155 const char *mesh_file =
"../../data/beam-quad-nurbs.mesh";
158 int ode_solver_type = 23;
164 int proj_type_int = 0;
165 bool visualization =
true;
169 args.
AddOption(&mesh_file,
"-m",
"--mesh",
170 "Mesh file to use.");
171 args.
AddOption(&ref_levels,
"-r",
"--refine",
172 "Number of times to refine the mesh uniformly.");
174 "Order (degree) of the finite elements.");
175 args.
AddOption(&ode_solver_type,
"-s",
"--ode-solver",
177 args.
AddOption(&t_final,
"-tf",
"--t-final",
178 "Final time; start time is 0.");
179 args.
AddOption(&dt,
"-dt",
"--time-step",
181 args.
AddOption(&visc,
"-v",
"--viscosity",
182 "Viscosity coefficient.");
184 "Shear modulus in the Neo-Hookean hyperelastic model.");
185 args.
AddOption(&K,
"-K",
"--bulk-modulus",
186 "Bulk modulus in the Neo-Hookean hyperelastic model.");
187 args.
AddOption(&proj_type_int,
"-proj",
"--projection",
188 "Projection type:\n."
189 " 0 = DEFAULT: ELEMENTL2 for NURBS elements, ELEMENT else.\n"
190 " 1 = ELEMENT: As defined in the respective element.\n"
191 " 2 = GLOBALL2: Global L2 projection.\n"
192 " 3 = ELEMENTL2: Element L2 projection.");
193 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
194 "--no-visualization",
195 "Enable or disable GLVis visualization.");
196 args.
AddOption(&vis_steps,
"-vs",
"--visualization-steps",
197 "Visualize every n-th timestep.");
210 Mesh *mesh =
new Mesh(mesh_file, 1, 1);
221 for (
int lev = 0; lev < ref_levels; lev++)
238 cout <<
"Using NURBS FEs: " << fec->
Name() << endl;
243 cout <<
"Using H1 FEs: " << fec->
Name() << endl;
249 cout <<
"Number of velocity/deformation unknowns: " << fe_size << endl;
252 fe_offset[1] = fe_size;
253 fe_offset[2] = 2*fe_size;
284 HyperelasticOperator oper(fespace, ess_bdr, visc,
mu, K);
294 visualize(vis_v, mesh, &x, &v,
"Velocity",
true);
298 oper.GetElasticEnergyDensity(x, w, proj_type);
300 visualize(vis_w, mesh, &x, &w,
"Elastic energy density",
true);
302 cout <<
"GLVis visualization paused."
303 <<
" Press space (in the GLVis window) to resume it.\n";
308 cout <<
"initial elastic energy (EE) = " << ee0 << endl;
309 cout <<
"initial kinetic energy (KE) = " << ke0 << endl;
310 cout <<
"initial total energy (TE) = " << (ee0 + ke0) << endl;
314 ode_solver->Init(oper);
318 bool last_step =
false;
319 for (
int ti = 1; !last_step; ti++)
321 real_t dt_real = min(dt, t_final - t);
323 ode_solver->Step(vx, t, dt_real);
325 last_step = (t >= t_final - 1e-8*dt);
327 if (last_step || (ti % vis_steps) == 0)
332 cout <<
"step " << ti <<
", t = " << t <<
", EE = " << ee <<
", KE = "
333 << ke <<
", ΔTE = " << (ee+ke)-(ee0+ke0) << endl;
341 oper.GetElasticEnergyDensity(x, w, proj_type);
354 ofstream mesh_ofs(
"deformed.mesh");
355 mesh_ofs.precision(8);
356 mesh->
Print(mesh_ofs);
358 ofstream velo_ofs(
"velocity.sol");
359 velo_ofs.precision(8);
361 ofstream ee_ofs(
"elastic_energy.sol");
363 oper.GetElasticEnergyDensity(x, w, proj_type);
376 GridFunction *field,
const char *field_name,
bool init_vis)
388 os <<
"solution\n" << *mesh << *field;
394 os <<
"window_size 800 800\n";
395 os <<
"window_title '" << field_name <<
"'\n";
403 os <<
"autoscale value\n";
410ReducedSystemOperator::ReducedSystemOperator(
412 :
Operator(M_->Height()), M(M_), S(S_), H(H_), Jacobian(NULL),
413 dt(0.0), v(NULL), x(NULL), w(height), z(height)
416void ReducedSystemOperator::SetParameters(
real_t dt_,
const Vector *v_,
419 dt = dt_; v = v_; x = x_;
422void ReducedSystemOperator::Mult(
const Vector &k,
Vector &y)
const
432Operator &ReducedSystemOperator::GetGradient(
const Vector &k)
const
439 Jacobian->
Add(dt*dt, *grad_H);
443ReducedSystemOperator::~ReducedSystemOperator()
453 M(&fespace), S(&fespace), H(&fespace),
454 viscosity(visc), z(height/2)
456#if defined(MFEM_USE_DOUBLE)
457 const real_t rel_tol = 1e-8;
458 const real_t newton_abs_tol = 0.0;
459#elif defined(MFEM_USE_SINGLE)
460 const real_t rel_tol = 1e-3;
461 const real_t newton_abs_tol = 1e-4;
463#error "Only single and double precision are supported!"
467 const int skip_zero_entries = 0;
469 const real_t ref_density = 1.0;
472 M.Assemble(skip_zero_entries);
478 M_solver.iterative_mode =
false;
479 M_solver.SetRelTol(rel_tol);
480 M_solver.SetAbsTol(0.0);
481 M_solver.SetMaxIter(30);
482 M_solver.SetPrintLevel(0);
483 M_solver.SetPreconditioner(M_prec);
484 M_solver.SetOperator(M.SpMat());
492 S.Assemble(skip_zero_entries);
495 reduced_oper =
new ReducedSystemOperator(&M, &S, &H);
497#ifndef MFEM_USE_SUITESPARSE
512 newton_solver.SetSolver(*J_solver);
513 newton_solver.SetOperator(*reduced_oper);
514 newton_solver.SetPrintLevel(1);
515 newton_solver.SetRelTol(rel_tol);
516 newton_solver.SetAbsTol(newton_abs_tol);
517 newton_solver.SetMaxIter(10);
520void HyperelasticOperator::Mult(
const Vector &vx,
Vector &dvx_dt)
const
530 if (viscosity != 0.0)
535 M_solver.
Mult(z, dv_dt);
540void HyperelasticOperator::ImplicitSolve(
const real_t dt,
555 reduced_oper->SetParameters(dt, &v, &x);
557 newton_solver.
Mult(zero, dv_dt);
558 MFEM_VERIFY(newton_solver.
GetConverged(),
"Newton solver did not converge.");
559 add(v, dt, dv_dt, dx_dt);
562real_t HyperelasticOperator::ElasticEnergy(
const Vector &x)
const
567real_t HyperelasticOperator::KineticEnergy(
const Vector &v)
const
572void HyperelasticOperator::GetElasticEnergyDensity(
575 ElasticEnergyCoefficient w_coeff(*model, x);
579HyperelasticOperator::~HyperelasticOperator()
611 v(
dim-1) = s*x(0)*x(0)*(8.0-x(0));
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
A class to handle Vectors in a block fashion.
Vector & GetBlock(int i)
Get the i-th vector in the block.
Conjugate gradient method.
void Mult(const Vector &b, Vector &x) const override
Iterative solution of the linear system using the Conjugate Gradient method.
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.
Jacobi-type diagonal smoother of a sparse matrix.
Data type dense matrix using column-major storage.
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
virtual const char * Name() const
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
Mesh * GetMesh() const
Returns the mesh.
Class for grid function - Vector with associated FE space.
void GetVectorGradient(ElementTransformation &tr, DenseMatrix &grad) const
Compute the vector gradient with respect to the physical element variable.
void SetTrueVector()
Shortcut for calling GetTrueDofs() with GetTrueVector() as argument.
virtual void Save(std::ostream &out) const
Save the GridFunction to an output stream.
void MakeTRef(FiniteElementSpace *f, real_t *tv)
Associate a new FiniteElementSpace and new true-dof data with the GridFunction.
void SetFromTrueVector()
Shortcut for calling SetFromTrueDofs() with GetTrueVector() as argument.
const Vector & GetTrueVector() const
Read only access to the (optional) internal true-dof Vector.
virtual void ProjectCoefficient(Coefficient &coeff, ProjectType type=ProjectType::DEFAULT)
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
Arbitrary order H1-conforming (continuous) finite elements.
Abstract class for hyperelastic models.
virtual real_t EvalW(const DenseMatrix &Jpt) const =0
Evaluate the strain energy density function, W = W(Jpt).
void SetTransformation(ElementTransformation &Ttr_)
Class for integration point with weight.
void SetRelTol(real_t rtol)
virtual void SetPrintLevel(int print_lvl)
Legacy method to set the level of verbosity of the solver output.
void SetMaxIter(int max_it)
bool GetConverged() const
Returns true if the last call to Mult() converged successfully.
void SetAbsTol(real_t atol)
Arbitrary order "L2-conforming" discontinuous finite elements.
void SetPreconditioner(Solver &pr) override
This should be called before SetOperator.
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
NURBSExtension * NURBSext
Optional NURBS mesh extension.
virtual void Print(std::ostream &os=mfem::out, const std::string &comments="") const
Print the mesh to the given stream using the default MFEM mesh format.
int Dimension() const
Dimension of the reference space used within the elements.
int SpaceDimension() const
Dimension of the physical space containing the mesh.
void GetNodes(Vector &node_coord) const
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
void SwapNodes(GridFunction *&nodes, int &own_nodes_)
Swap the internal node GridFunction pointer and ownership flag members with the given ones.
NURBSExtension generally contains multiple NURBSPatch objects spanning an entire Mesh....
Arbitrary order non-uniform rational B-splines (NURBS) finite elements.
Newton's method for solving F(x)=b for a given operator F.
void Mult(const Vector &b, Vector &x) const override
Solve the nonlinear system with right-hand side b.
static MFEM_EXPORT std::string Types
static MFEM_EXPORT std::unique_ptr< ODESolver > Select(const int ode_solver_type)
int height
Dimension of the output / number of rows in the matrix.
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
void PrintUsage(std::ostream &out) const
Print the usage message.
void PrintOptions(std::ostream &out) const
Print the options.
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...
bool Good() const
Return true if the command line options were parsed successfully.
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
void Add(const int i, const int j, const real_t val)
Base abstract class for first order time dependent operators.
virtual void SetTime(const real_t t_)
Set the current time.
Direct sparse solver using UMFPACK.
A general vector function coefficient.
void Neg()
(*this) = -(*this)
int Size() const
Returns the size of the vector.
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
int open(const char hostname[], int port)
Open the socket stream on 'port' at 'hostname'.
const int * ess_tdof_list
int GetTrueVSize(const FieldDescriptor &f)
Get the true dof size of a field descriptor.
ProjectType
This enumerated type describes the main projection types used by GridFunction::ProjectCoefficient():
void add(const Vector &v1, const Vector &v2, Vector &v)
std::function< real_t(const Vector &)> f(real_t mass_coeff)
void Add(const DenseMatrix &A, const DenseMatrix &B, real_t alpha, DenseMatrix &C)
C = A + alpha*B.
void visualize(ostream &os, Mesh *mesh, GridFunction *deformed_nodes, GridFunction *field, const char *field_name=NULL, bool init_vis=false)
void InitialDeformation(const Vector &x, Vector &y)
void InitialVelocity(const Vector &x, Vector &v)
std::array< int, NCMesh::MaxFaceNodes > nodes