The model bricks
Although it is possible to use assembly procedures on their own to make your finite element programs, it is now possible to use predefined bricks to build up very quickly a certain number of models. Most of the bricks are defined in getfem/getfem_modeling.h.
A model brick is basically an object which modifies a global
tangent matrix and its associated right hand side. Typical
modifications are insertion of the stiffness matrix for the problem
considered (linear elasticity, laplacian, ...), handling of a set
of contraints, Dirichlet condition, addition of a source term to
the right hand side etc. The global tangent matrix and its right
hand side are stored in a model_state structure.
The model state variable
The getfem::model_state object is an object which stores the state of the system and the tangent system with eventual constraints. There are two predefined model_state types:
getfem::standard_model_state getfem::standard_complex_model_state
The second one is for models with complex degrees of freedom like Helmholtz problem. These two predefined model_state type are built with the following predefined sparse matrices and plain vectors:
getfem::modeling_standard_sparse_matrix (gmm::col_matrix<gmm::rsvector<double> >) getfem::modeling_standard_plain_vector (std::vector<double>) getfem::modeling_standard_complex_sparse_matrix (gmm::col_matrix<gmm::rsvector<std::complex<double> > >) getfem::modeling_standard_complex_plain_vector (std::vector<std::complex<double> >)
But you can define your own model state type with arbitrary types of sparse matrices and plain vectors (see the file getfem/getfem_modeling.h)
Basic properties of a brick
A brick represents a basic problem (elasticity, Helmholtz,
Poisson problems ...) or a modifier of such problems (addition of a
Dirichlet or Neumann condition, source term, incompressibility term
...). Each brick will participate on the global linear system to be
solved (the tangent system for non linear problem). A brick is an
object which derives from getfem::mdbrick_abstract
<MODEL_STATE> (which itself
derive from the non-template class
getfem::mdbrick_abstract_common_base) with the following
virtual methods to be defined:
| brick.proper_update() | called each time the brick should update itself. In particular, this function is expected to assign the correct values to proper_nb_dof (the nb of new dof introduced by this brick), proper_nb_constraints and proper_mixed_variables. It may also precompute certain components (like stiffness matrices for linear problems). |
| brick.do_compute_tangent_matrix(MS, i0, j0) | the brick has to compute its own part of the tangent and constraint matrices (i0 and j0 are optional arguments representing the shifts in the matrices defined in MS). |
| brick.do_compute_residual(MS, i0, j0) | the brick has to compute its own part of the residual of the linear system and of the constraint system (i0 and j0 are the shifts in the residual vectors defined in MS). |
Of course, each specific brick may have additional methods to build the brick, define some parameters and extract the solution from the model state variable. The brick may also do some extra efforts in order to avoid unecessary recomputations (see for example the K_uptodate flag of the getfem::mdbrick_abstract_linear_pde brick).
Brick parameters
Many bricks depend on one or more parameter fields. For example, the linear elasticity brick uses the two Lamé coefficients λ and µ. These Lamé coefficients are described as a field (i.e. and mesh_fem and a vector of dof values), in a template structure getfem::mdbrick_parameter <VECTOR_TYPE>.
Some problems require a matrix or a tensor field, instead of a scalar field. For example, the brick responsible for the Dirichlet condition is used to impose h(x)u(x) = r(x) on a region of the mesh. When the mesh_fem is a vector one (Q >= 1), h(x) is a Q × Q matrix field, and r(x) is a vector field of dimension Q. That case is also handled by the getfem::mdbrick_parameter structure.
Basically, this structure contains
- a getfem::mesh_fem (whose Qdim is always equal to one!).
- a description of the field dimensions (scalar, matrix, ..)
- a vector, whose length is the field number of elements times the nb_dof() of the mesh_fem. For a matrix field h(x), the order is the fortran one, with the dof number as the slowest varying index: [h_11^1, h_21^1, h_12^1, h_22^1, h_11^2, ..., h_11^n, h_21^n, h_12^n, h_22^n]
This structure provides these methods:
| field.mf() | return the mesh_fem on which the field is defined. |
| field.get() | return the current dof data of the field. |
| field.fsizes() | return the field size, as a vector. For a scalar field, this is an empty vector, for a n× p matrix field, this is the vector [n,p], etc. |
| field.fsize() | return the product of the elements of the vector fsizes(). |
| field.set([mf, ] V) | change the field value. The value V can be a scalar value (constant field), a vector of length fsize() to set a constant non-scalar field, or a large vector of length fsize()*mf().nb_dof() to set a non-constant field. The mesh_fem mf is an optional paramater, hence it is possible to change the mesh_fem associated to the parameter (typically it is a polynomial mesh_fem of degree 0). |
| set_diagonal(V) | can be used with matrix fields, to set only the diagonal elements (V length should be fsize()[0] or fsize()[0]*mf().nb_dof()). |
generic elliptic brick
The generic elliptic brick is a basic brick representing a term
such as
-div(k∇u) = ... where u is a scalar field and the
coefficient k is a positive scalar or a symmetric positive
definite order two tensor field, or a symmetric positive definite
order four tensor (and u a vector field). The constructor
initializes the brick for a scalar constant coefficient
k:
getfem::mdbrick_generic_elliptic <MODEL_STATE> brick(mim, mf_u, k = 1.0);
where mim is a variable of type getfem::mesh_im defining the integration method used, and mf_u is a getfem::mesh_fem on the same mesh. mf_u describes the finite element method used for the unknown.
A local copy of the stiffness matrix K is stored in the
brick, this obviously has a memory cost but allows not to recompute
it each time when compute_tangent_matrix(...) is called.
In fact this bricks cover several situations. When k is a scalar coefficient, the brick represent
a laplace operator which is componentwise if the mf_u represent a vector field (mf_u.get_qdim()>1). When k is an order two tensor coefficient, the
brick represent a scalar generic elliptic operator which is
componentwise if mf_u is a vector
field. And finally, When k is an
order four tensor coefficient, the brick represents a vectorial
generic elliptic operator (for example linear elasticity with a
generic Hooke tensor).
A general tensor field k can be set thanks to the two functions: brick.set_coeff_dimension(d) (with d = 0, 2 or 4) sets the tensor dimension, and brick.coeff().set(mf_data, new_k) sets the value of the tensor field (mf_data could be ommited, it is an order 0 element by default).
The following additional methods are available on this brick:
| brick.coeff() | gives the access to the parameter k (see section on bricks parameters). |
| brick.set_coeff_dimension(d) | Set the tensor dimension of k. d=1 for laplacian operator, d=2 for generic scalar elliptic operator and d=4 for generic vectorial elliptic operator. |
| brick.get_solution(MS, V) | After a solve, extract the solution of the model state variable MS and put it in the vector V. |
Source term brick
The brick getfem::mdbrick_source_term represents either a volumic source term or a Neumann condition, i.e. a term ∫Ω f.v dx or ∫Γ f.v dx in the weak formulation , with Γ a part of∂Ω. This brick works for both real or complex terms in scalar or vectorial problems. The constructor of this brick is:
getfem::mdbrick_source_term <MODEL_STATE> brick(problem, mf_data, F, bound=-1, num_fem=0); getfem::mdbrick_source_term <MODEL_STATE> brick(problem, bound=-1, num_fem=0);
where problem is the problem on which the source term will be added (a scalar elliptic brick for instance), mf_data is the finite element description for the source term f, F is a vector of type MODEL_STATE::vector_type which contains the values of the source term on each degree of freedom of mf_data, bound is an optional parameter specifying on which boundary of the main mesh fem of problem the Neumann condition is applied. If this parameter is omitted, a volumic source term will be taken into account. num_fem is an optional parameter allowing to choose a fem is the problem has several fems (for example, in a mixed problem the num_fem 0 may correspond to the mesh_fem used for the velocity, and the num_fem 1 may correspond to the mesh_fem used for the pressure).
The following additional methods are available on this brick:
| brick.source_term() | give the access to the parameter F defining the source term (see section on bricks parameters for how to change the value of the parameter) |
Constraint brick
The constraint brick getfem::mdbrick_constraint adds constraints on the degrees of freedom of a mesh_fem. This brick is a base class for the Dirichlet condition bricks for instance. It can also be used on its own to add constraints on an unknow when this unknow is not fully determinated (for instance, when only a Neumann condition is present on the boundary of the domain). This brick deals directly with the vectorial format of the unknow, i.e. with a system representing the constraints BU=R, where B is a nc × nd matrix, U is the vector of unkown corresponding to a finite element method mf_u having nd dofs and R is a vector of size nc corresponding to the right hand side of the constraints. This correspond to add nc constraints to the system. These constraints have to be independant, which means that the matrix B has to be of maximal rank.
The brick offers three different manners to take the constraints into account. This is representied by an enum in getfem/getfem_modeling.h:
- getfem::AUGMENTED_CONSTRAINTS
consists in the addition of Lagrange multipliers (one multiplier
for each constraint) so that the final linear system is augmented
with the corresponding number of multipliers.
The inconvenient of this approach is that the final linear system looses is larger, and is not positive definite. - getfem::PENALIZED_CONSTRAINTS : add a penalization (1)/(ε) (BTB U - BTR) to the linear system. The penalization parameter ε has a default value equal to 10-9. This method is simple and robust, and does not increase the linear system. However the condition number of the final system is worse.
- getfem::ELIMINATED_CONSTRAINTS consists in collecting all the constraints on the system in a global constraint system (in the getfem::model_state variable) and to "eliminate" the dofs concerned by the constraints before solving the linear system. This is done computing the kernel of the constraints and projecting the linear system on this kernel. This method is efficient on "simple cases", but it may it is not very robust with respect to high degree FEMs, it is not parallelisable, and the computation of the kernel takes a non-negligible amount of time.
The constructor of this brick is
getfem::mdbrick_constraint <MODEL_STATE> brick(problem, num_fem);
where problem is the problem on which the constraints will be added (a generic elliptic brick for instance) and num_fem is an optional parameter allowing to choose a fem is the problem has several fems (0 is the default).
The specification of the constraints is done using the method
brick.set_constraints(B, R);
The following additional methods are available on this brick:
| brick.set_constraints_rhs(R) | changes only the right hand side of the constraints. |
| brick.set_constraints_type(c) | set the method to take into account the constraints. The parameter c is either getfem::AUGMENTED_CONSTRAINTS, getfem::PENALIZED_CONSTRAINTS, or getfem::ELIMINATED_CONSTRAINTS. |
| brick.set_penalization_parameter(eps) | set the penalization parameter for the method getfem::PENALIZED_CONSTRAINTS. |
Dirichlet condition brick
The getfem::mdbrick_Dirichlet
brick allows to define a Dirichlet condition on a part
Γ of the boundary of the domain (i.e. set the value of
the unknown on this part of the boundary u = r). This brick
is derived from the constraint brick and automatically set the
constraints system BU=R. As a consequence, the methods of
the constraint brick are available (brick.set_constraints_type(c) and brick.set_penalization_parameter(eps)).
In order to be able to treat arbitraries finite element methods,
the Dirichlet condition is considered in the weak form
∫Γ u(x)v(x)
dΓ= ∫Γ r(x)v(x)
dΓ for all v taken in a space of convenient
multipliers. This allows to describe the data r(x) on a
different fem than the unknown u(x) and allows also to have
a more stable condition when the unknow u(x) is describe on
a complex fem like an Xfem using a standard lagrangian fem for the
multipliers.
getfem::mdbrick_Dirichlet <MODEL_STATE> brick(problem, bound, mf_mult, num_fem);
where problem is the problem on which the Dirichlet condition will be added, bound specifies on which boundary of the main mesh of problem the Dirichlet condition is applied, mf_mult is an optional parameter representing the fem for the multipliers (the default value is to take the same fem as the unknow) and num_fem is an optional parameter allowing to choose a fem is the problem has several fems (0 is the default).
The fem mf_mult has to be chosen in order to satify the Babuska-Brezzi inf-sup condition (i.e. the fact that the matrix B, which represent here a mass matrix on the boundary Γ, is of maximal rank). It is satisfied when mf_mult is the same fem as the one for the unkown and generally when mf_mult is "less rich" than this fem.
By default, the prescribed value is zero. For non-homogenous Dirichlet condition u = r, the parameter rhs of the brick has to be set by the command:
brick.rhs().set(mf_data, R);
where mf_data is the finite element description for the data and F is a vector of type MODEL_STATE::vector_type which contains the values of the data on each degree of freedom of mf_data.
The following additional methods are available on this brick:
| brick.rhs() | gives the access to the parameter representing the value of the Dirichlet condition. |
| brick.set_constraints_type(c) | set the method to take into account the constraints. The parameter c is either getfem::AUGMENTED_CONSTRAINTS, getfem::PENALIZED_CONSTRAINTS, or getfem::ELIMINATED_CONSTRAINTS. |
| brick.set_penalization_parameter(eps) | set the penalization parameter for the method getfem::PENALIZED_CONSTRAINTS. |
Remark: except for the getfem::AUGMENTED_CONSTRAINTS option, an algorithm of simplification tries when it is possible to have a matrix B with only one element per line. This is possible when the mass matrix on Γ of mf_u the fem for the unknown and mf_mult is invertible.
Example of a complete Poisson problem
If mf_u and mf_data are valid finite element description on a mesh representing the domain on which the problem is defined, the following sequence will define a Poisson (laplacian) problem with a Dirichlet condition on boundary 5 of mf_u and a Neumann condition on boundary 7 of mf_u:
typedef getfem::modeling_standard_plain_vector plain_vector; plain_vector U(mf_u.nb_dof()), F(mf_data.nb_dof()); getfem::mdbrick_generic_elliptic <> laplacian(mim, mf_u); plain_vector F(mf_data.nb_dof()); for (int i = 0; i < mf_data.nb_dof(); ++i) F(i) = ...; getfem::mdbrick_source_term <> volumic_source_term(laplacian, mf_data, F); for (int i = 0; i < mf_data.nb_dof(); ++i) F(i) = ...; getfem::mdbrick_source_term <> neumann_condition(volumic_source_term, mf_data, F, 7); for (int i = 0; i < mf_data.nb_dof(); ++i) F(i) = ...; getfem::mdbrick_Dirichlet <> final_model(neumann_condition, 5); final_model.rhs().set(mf_data, F); getfem::standard_model_state MS(final_model); gmm::iteration iter(residual, 1, 40000); getfem::standard_solve(MS, final_model, iter); laplacian.get_solution(MS, U);
Remark how the bricks are linked, each condition is applied to the brick defined with the previous condition. The order of the conditions is of course arbitrary, you can define the Dirichlet condition before the source term for instance.
Predefined solvers
Of course, for many problems, it will be more convenient to make a specific solver. Even so, one generic solver is at the moment available to test your models quickly. It can also be taken as a model to build your own solvers. It is defined in getfem/getfem_model_solvers.h and the call is
getfem::standard_solve(MS, problem, iter);
where MS is a model state
variable, problem is the brick that
represent your global problem and iter is an iteration object from Gmm++. See
also the previous section for an example of use.
Note that SuperLu is used by default on "small" problems. You can
also link MUMPS with Getfem (see section *) and used the parallele version.
Isotropic linearized elasticity brick
The
getfem::mdbrick_isotropic_linearized_elasticity is a basic
brick representing a term such as
-div(σ) = ...;
with
σ= λtr(ε(u))I + 2µε(u);
ε(u) = (∇u + ∇u^T)/2.
The constructors build the brick for constant Lamé coefficients:
getfem::mdbrick_isotropic_linearized_elasticity <MODEL_STATE> brick(mim, mf_u);
where mim is a variable of type getfem::mesh_im defining the integration method used, mf_u is a valid fem descriptor. mf_u describe the finite element method used for the unknown.
The brick has two parameters, lambda() and mu() for the usual Lamé coefficients. As they are getfem::mdbrick_parameter, it is possible to use either a constant value (with for example brick.lambda().set(100.), or a non constant value (for example brick.lambda().set(mf_lambda, lambdav) with lambdav of type MODEL_STATE::vector_type).
The stiffness matrix is "cached" in the brick (and available
with brick.get_K()), it has a memory
cost but avoids unnecessary recomputations each time compute_tangent_matrix(...) is called.
The following additional methods are available on this brick:
| brick.lambda() | gives access to the brick parameter lambda. |
| brick.mu() | gives access to the brick parameter mu. |
| brick.get_solution(MS, V) | After a solve, extract the solution of the model state variable MS and put it in the vector V. |
| brick.compute_Von_Mises_or_Tresca(MS, mf_vm, VM, tresca_flag) | Compute the Von Mises criterion (or Tresca is tresca_flag is set to true) on the displacement field stored in MS. The stress is evaluated on the mesh_fem mf_vm and stored in the vector VM. |
The program elastostatic.cc in the tests directory of Getfem++ distribution can be taken as a model of use of this brick.
Qu term brick
The getfem::mdbrick_QU_term
brick can be used to add boundary conditions of Fourier-Robin type
like
(∂u)/(∂n) = Qu
for scalar problems, or
σn = Qu
for linearized elasticity problems. Q is a scalar field in the scalar case or a matrix field in the vectorial case. This brick works for both real or complex terms in scalar or vectorial problems.
The constructor is the following :
getfem::mdbrick_QU_term <MODEL_STATE> brick(problem, Q_diag=0.0, bound=-1, numfem=0);
where problem is the problem on which the condition will be added. Q_diag is a real for the homogeneous and diagonal case (Q = Qdia * I). bound is the number of the boundary of main_mesh_fem() on which the condition will be applied. num_fem is an optional parameter allowing to choose a fem is the problem has several fems.
The following additional methods are available on this brick:
| brick.Q() | gives access to the brick parameter Q. |
Helmholtz brick
This brick represent the complex or real Helmholtz problem
Δu + k^2 u = ... where k the wave number is a real or
complex value. For a complex version, a complex model state
variable has to be used (for example getfem::standard_complex_model_state, see
helmholtz.cc in the tests
directory)
The constructor is
getfem::mdbrick_Helmholtz<MODEL_STATE> brick(mim, mf_u, k);
where mim is a variable of type getfem::mesh_im defining the integration method used, mf_u describe the finite element method used for the unknown. k is the (homogeneous) wave_number. It can be changed to a non-homogeneous wave number afterwards, with brick.wave_number().set(mf_k, k) etc.
The following additional methods are available on this brick:
| brick.wave_number() | gives access to the brick parameter k. |
| brick.get_solution(MS, V) | After a solve, extract the solution of the model state variable MS and put it in the vector V. |
linear incompressibility (or nearly incompressibility) brick
The getfem::mdbrick_linear_incomp
brick adds a linear incompressibility condition (or a nearly
incompressible condition) in a problem of type
div(u) = 0, (or div(u) = εp)
This constraint is enforced with Lagrange multipliers representing the pressure, introduced in a mixed formulation.
The constructor for the incompressibility condition is:
getfem::mdbrick_linear_incomp <MODEL_STATE> brick(problem, mf_p, numfem);
where problem is the problem on which the incompressibility condition is applied, mf_p is the finite element description for the pressure (be aware that the LBB inf-sup condition has to be satisfied between the main_mesh_fem() and mf_p. num_fem is an optional parameter allowing to choose a fem is the problem has several fems.
The nearly incompressibility condition is used when it is
switched on with brick.set_penalized(true). The penalization
parameter ε is accessed with brick.penalization_coeff().
In nearly incompressible homogeneous linearized elasticity, one has
ε= 1 / λ where λ is one of the
Lamé coefficient.
For instance, the following program defines a Stokes problem with a
source term and an homogeneous Dirichlet condition on boundary 0.
mf_u, mf_data and mf_p have to be valid finite element
description on the same mesh.
typedef getfem::modeling_standard_plain_vector plain_vector; plain_vector U(mf_u.nb_dof()), F(mf_data.nb_dof()); double mu = 1.0; getfem::mdbrick_isotropic_linearized_elasticity<> stokes(mim, mf_u, 0.0, mu); getfem::mdbrick_linear_incomp<> incomp(stokes, mf_p); plain_vector F(mf_data.nb_dof()); for (int i = 0; i < mf_data.nb_dof(); ++i) F(i) = ...; getfem::mdbrick_source_term<> volumic_source_term(incomp, mf_data, F); gmm::clear(F); getfem::mdbrick_Dirichlet<> final_model(volumic_source_term, 0); final_model.rhs().set(mf_data, F); getfem::standard_model_state MS(final_model); gmm::iteration iter(residual, 1, 40000); getfem::standard_solve(MS, final_model, iter); stokes.get_solution(MS, U);
A example for a nearly incompressibility condition can be found in the program tests/elastostatic.cc.
Small displacement plasticity brick
The getfem::mdbrick_plasticity brick modelizes small-displacement quasi-static plasticity problems. It is defined in getfem/getfem_plasticity.h Plasticity happens when you stress an object too much, so that even when you remove the charge, constraints remain 'trapped' into the object. When a stress is applied to an object, if the stress is small enough, the displacements stays elastic. If that stress gets greater than a constant value called stress threshold (intrinsic to the object), then the displacements becomes plastic.
Quasi-static means that we do not take inertia into account, however the algorithm used needs some kind of a time representation. It is not possible to put the charge on the model at once, as it will render false results. Instead, we have to put the charge only a bit at a time, and calculate the deformation each time, hence the 'quasi-static' name. For instance, if you wish to put a 100N/m charge on your object, you should put it by small steps (20,40,60,80,100 is ok). We have to use that method to keep the consistency of the problem.
The constructor is
getfem::mdbrick_plasticity (mesh_im &mim_, mesh_fem &mf_u_, value_type lambdai, value_type mui, value_type stress_threshold, const abstract_constraints_project &t_proj_);
The stress_threshold is the 'elasticity limit' : if constraints are below that limit, the problem is an elasticity problem. Else, it is a plasticity one. t_proj_ is an instance of a constraints projection objects, such as getfem::VM_projection.
Using that constructor, you can build the problem like with any other bricks, adding the Volumic, Neumann and Dirichlet bricks as usual (look at elastostatic.cc and plasticity.cc in tests directory for examples), and call the solver with getfem::standard_solve(MS, final_model, iter);.
Once it's done, you need to know what the results are. You can know the displacement using brick.get_solution(MS, U); where MS is defined by getfem::standard_model_state MS(final_model);, and U the displacement vector.
The Von Mises constraints can be obtained with brick.compute_Von_Mises_or_Tresca(mf_vm,VM,tresca_flag) (see the description in the linearized isotropic elasticity brick).
Contact and friction conditions brick
(to be documented, see the test program tests/dynamic_friction.cc, and the source file getfem/getfem_Coulomb_friction.h)
Linearized plate brick
(to be documented, see the test program tests/plate.cc)
- ut is the membrane displacement.
- u3 is the transverse displacement.
- theta is the rotation of the normal (section rotation).
Many specialized bricks are defined in getfem/getfem_linearized_plates.h:
- getfem::mdbrick_isotropic_linearized_plate: linear plate model brick (for moderately thick plates, using the Reissner-Mindlin model).
- getfem::mdbrick_mixed_isotropic_linearized_plate: mixed linear plate model brick (for thin plates, using Kirchhoff-Love model). The getfem::mdbrick_plate_closing has to be used in conjonction with this one.
- getfem::mdbrick_plate_source_term: apply a classical source term on the ut, u3, and theta fields.
- getfem::mdbrick_plate_simple_support: Dirichlet condition on ut and u3, free rotation.
- getfem::mdbrick_plate_clamped_support: Dirichlet condition on the displacement and the rotation.
- getfem::mdbrick_plate_closing: free edges condition for mixed plate model brick. This brick has to be added for the mixed linearized plate brick after all other boundary conditions.
Large strain elasticity brick
The getfem::mdbrick_nonlinear_elasticity brick represents a large strain elasticity problem. It is defined in getfem/getfem_nonlinear_elasticity.h The constructor is:
getfem::mdbrick_nonlinear_elasticity <MODEL_STATE> brick (Hyperelastic_Law, mim, mf_u, lawparams);
where Hyperelastic_Law is an object of type getfem::abstract_hyperelastic_law representing the considered hyperelastic law. It has to be chosen between:
getfem::SaintVenant_Kirchhoff_hyperelastic_law Hyperelastic_Law; getfem::Ciarlet_Geymonat_hyperelastic_law Hyperelastic_Law; getfem::Mooney_Rivlin_hyperelastic_law Hyperelastic_Law;
The Saint-Venant Kirchhoff law is a linearized law defined with
the two Lamé coefficients, Ciarlet Geymonat law is defined
with the two Lamé coefficients and an additional coefficient
and the Mooney-Rivlin law is defined with two coefficients and is
to be used with the large strain incompressibility condition.
mf_u describe the finite element
method used for the unknown and mf_data the finite element method used for the
parameters of the selected hyperelastic law. The parameters of the
hyperelastic law are supplied in the vector lawparams (by default they are constant over
the mesh, but of you can change that later with brick.params().set(mf, V)).
The program nonlinear_elastostatic.cc in tests directory is an example of use of this brick with or without an incompressibility condition.
Large strain incompressibility brick
The
getfem::mdbrick_nonlinear_incomp brick adds an
incompressibility condition in a large strain problem of type
det(I+∇u) = 1,
For this, Lagrange multipliers representing the pressure are introduced in a mixed formulation.
The constructor is:
getfem::mdbrick_nonlinear_incomp <MODEL_STATE> brick(problem, mf_p, numfem);
where problem is the problem on which the incompressibility condition is applied, mf_p is the finite element description for the pressure (be aware that the LBB (Ladyzhenskaja-Babuska-Brezzi) inf-sup condition has to be satisfied between the main_mesh_fem() and mf_p. num_fem is an optional parameter allowing to choose a fem is the problem has several fems.
The program nonlinear_elastostatic.cc in tests directory is an example of use of this brick.
