38 using std::endl;
using std::cout;
using std::cerr;
39 using std::ends;
using std::cin;
44 using bgeot::base_vector;
45 using bgeot::scalar_type;
47 using bgeot::dim_type;
48 using bgeot::base_matrix;
54 typedef getfem::modeling_standard_sparse_matrix sparse_matrix;
55 typedef getfem::modeling_standard_plain_vector plain_vector;
60 struct elastostatic_problem {
62 enum { DIRICHLET_BOUNDARY_NUM = 0, NEUMANN_BOUNDARY_NUM = 1};
69 scalar_type p1, p2, p3;
73 std::string datafilename;
74 bgeot::md_param PARAM;
76 bool solve(plain_vector &U);
78 elastostatic_problem(
void) : mim(mesh), mf_u(mesh), mf_p(mesh), mf_rhs(mesh),
88 void elastostatic_problem::init(
void) {
89 std::string MESH_TYPE = PARAM.string_value(
"MESH_TYPE",
"Mesh type ");
90 std::string FEM_TYPE = PARAM.string_value(
"FEM_TYPE",
"FEM name");
91 std::string FEM_TYPE_P= PARAM.string_value(
"FEM_TYPE_P",
92 "FEM name for the pressure");
93 std::string INTEGRATION = PARAM.string_value(
"INTEGRATION",
94 "Name of integration method");
95 cout <<
"MESH_TYPE=" << MESH_TYPE <<
"\n";
96 cout <<
"FEM_TYPE=" << FEM_TYPE <<
"\n";
97 cout <<
"INTEGRATION=" << INTEGRATION <<
"\n";
103 std::vector<size_type> nsubdiv(N);
104 std::fill(nsubdiv.begin(),nsubdiv.end(),
105 PARAM.int_value(
"NX",
"Nomber of space steps "));
106 nsubdiv[1] = PARAM.int_value(
"NY") ? PARAM.int_value(
"NY") : nsubdiv[0];
108 nsubdiv[2] = PARAM.int_value(
"NZ") ? PARAM.int_value(
"NZ") : nsubdiv[0];
110 PARAM.int_value(
"MESH_NOISED") != 0);
112 bgeot::base_matrix M(N,N);
114 static const char *t[] = {
"LX",
"LY",
"LZ"};
115 M(i,i) = (i<3) ? PARAM.real_value(t[i],t[i]) : 1.0;
117 if (N>1) { M(0,1) = PARAM.real_value(
"INCLINE") * PARAM.real_value(
"LY"); }
120 mesh.transformation(M);
122 datafilename = PARAM.string_value(
"ROOTFILENAME",
"Base name of data files.");
123 residual = PARAM.real_value(
"RESIDUAL");
if (residual == 0.) residual = 1e-10;
125 p1 = PARAM.real_value(
"P1",
"First Elastic coefficient");
126 p2 = PARAM.real_value(
"P2",
"Second Elastic coefficient");
127 p3 = PARAM.real_value(
"P3",
"Third Elastic coefficient");
129 mf_u.set_qdim(dim_type(N));
134 getfem::pintegration_method ppi =
137 mim.set_integration_method(ppi);
138 mf_u.set_finite_element(pf_u);
144 std::string data_fem_name = PARAM.string_value(
"DATA_FEM_TYPE");
145 if (data_fem_name.size() == 0) {
146 GMM_ASSERT1(pf_u->is_lagrange(),
"You are using a non-lagrange FEM"
147 ". In that case you need to set "
148 <<
"DATA_FEM_TYPE in the .param file");
149 mf_rhs.set_finite_element(mesh.convex_index(), pf_u);
151 mf_rhs.set_finite_element(mesh.convex_index(),
158 mf_coef.set_finite_element(mesh.convex_index(),
163 cout <<
"Selecting Neumann and Dirichlet boundaries\n";
167 assert(it.is_face());
168 base_node un = mesh.normal_of_face_of_convex(it.cv(), it.f());
170 if (gmm::abs(un[N-1] - 1.0) < 1.0E-7) {
171 mesh.region(DIRICHLET_BOUNDARY_NUM).add(it.cv(),it.f());
172 }
else if (gmm::abs(un[N-1] + 1.0) < 1.0E-7) {
173 mesh.region(DIRICHLET_BOUNDARY_NUM).add(it.cv(),it.f());
182 bool elastostatic_problem::solve(plain_vector &U) {
185 size_type law_num = PARAM.int_value(
"LAW");
187 base_vector p(3); p[0] = p1; p[1] = p2; p[2] = p3;
193 case 1: lawname =
"Saint_Venant_Kirchhoff"; p.resize(2);
break;
194 case 2: lawname =
"Ciarlet_Geymonat"; p.resize(3);
break;
195 case 3: lawname =
"Incompressible_Mooney_Rivlin"; p.resize(2);
break;
196 default: GMM_ASSERT1(
false,
"no such law");
200 cout <<
"2D plane strain hyper-elasticity\n";
201 lawname =
"Plane_Strain_"+lawname;
214 if (law_num == 1 || law_num == 3) {
221 f[0] = PARAM.real_value(
"FORCEX",
"Amplitude of the gravity");
222 f[1] = PARAM.real_value(
"FORCEY",
"Amplitude of the gravity");
224 f[2] = PARAM.real_value(
"FORCEZ",
"Amplitude of the gravity");
225 plain_vector F(nb_dof_rhs * N);
226 for (
size_type i = 0; i < nb_dof_rhs; ++i) {
227 gmm::copy(f, gmm::sub_vector(F, gmm::sub_interval(i*N, N)));
234 plain_vector F2(nb_dof_rhs * N);
236 if (PARAM.int_value(
"DIRICHLET_VERSION") == 0)
238 (model, mim,
"u", mf_u, DIRICHLET_BOUNDARY_NUM,
"DirichletData");
241 (model, mim,
"u", 1E15, DIRICHLET_BOUNDARY_NUM,
"DirichletData");
245 gmm::set_traces_level(1);
252 PARAM.int_value(
"VTK_EXPORT")==1);
255 exp.exporting(sl,
true); exp.exporting_mesh_edges();
257 exp.write_point_data(mf_u, U,
"stepinit");
258 exp.serie_add_object(
"deformationsteps");
260 GMM_ASSERT1(!mf_rhs.is_reduced(),
"To be adapted for reduced mesh_fems");
262 int nb_step = int(PARAM.int_value(
"NBSTEP"));
263 size_type maxit = PARAM.int_value(
"MAXITER");
265 for (
int step = 0; step < nb_step; ++step) {
268 gmm::copy(gmm::scaled(F, (step+1.)/(scalar_type)nb_step), DF);
273 scalar_type torsion = PARAM.real_value(
"TORSION",
274 "Amplitude of the torsion");
275 torsion *= (step+1)/scalar_type(nb_step);
276 scalar_type extension = PARAM.real_value(
"EXTENSION",
277 "Amplitude of the extension");
278 extension *= (step+1)/scalar_type(nb_step);
279 base_node G(N); G[0] = G[1] = 0.5;
280 for (
size_type i = 0; i < nb_dof_rhs; ++i) {
281 const base_node P = mf_rhs.point_of_basic_dof(i) - G;
282 scalar_type r = sqrt(P[0]*P[0]+P[1]*P[1]),
283 theta = atan2(P[1],P[0]);
284 F2[i*N+0] = r*cos(theta + (torsion*P[2])) - P[0];
285 F2[i*N+1] = r*sin(theta + (torsion*P[2])) - P[1];
286 F2[i*N+2] = extension * P[2];
292 cout <<
"step " << step <<
", number of variables : "
293 << model.
nb_dof() << endl;
295 maxit ? maxit : 40000);
304 exp.write_point_data(mf_u, U);
305 exp.serie_add_object(
"deformationsteps");
311 return (iter.converged());
318 int main(
int argc,
char *argv[]) {
320 GETFEM_MPI_INIT(argc, argv);
321 GMM_SET_EXCEPTION_DEBUG;
325 elastostatic_problem p;
326 p.PARAM.read_command_line(argc, argv);
328 p.mesh.write_to_file(p.datafilename +
".mesh");
329 p.mf_u.write_to_file(p.datafilename +
".mf",
true);
330 p.mf_rhs.write_to_file(p.datafilename +
".mfd",
true);
331 plain_vector U(p.mf_u.nb_dof());
332 GMM_ASSERT1(p.solve(U),
"Solve has failed");
333 if (p.PARAM.int_value(
"VTK_EXPORT")) {
334 gmm::vecsave(p.datafilename +
".U", U);
335 cout <<
"export to " << p.datafilename +
".vtk" <<
"..\n";
337 p.PARAM.int_value(
"VTK_EXPORT")==1);
338 exp.exporting(p.mf_u);
339 exp.write_point_data(p.mf_u, U,
"elastostatic_displacement");
340 cout <<
"export done, you can view the data file with (for example)\n"
341 "mayavi2 -d " << p.datafilename <<
".vtk -f ExtractVectorNorm -f "
342 "WarpVector -m Surface -m Outline\n";
345 GMM_STANDARD_CATCH_ERROR;
A (quite large) class for exportation of data to IBM OpenDX.
Describe a finite element method linked to a mesh.
Describe an integration method linked to a mesh.
"iterator" class for regions.
structure used to hold a set of convexes and/or convex faces.
Describe a mesh (collection of convexes (elements) and points).
`‘Model’' variables store the variables, the data and the description of a model.
size_type nb_dof(bool with_internal=false) const
Total number of degrees of freedom in the model.
void add_fem_variable(const std::string &name, const mesh_fem &mf, size_type niter=1)
Add a variable being the dofs of a finite element method to the model.
void add_initialized_fixed_size_data(const std::string &name, const VECT &v)
Add a fixed size data (assumed to be a vector) to the model and initialized with v.
void add_initialized_fem_data(const std::string &name, const mesh_fem &mf, const VECT &v)
Add an initialized fixed size data to the model, assumed to be a vector field if the size of the vect...
model_real_plain_vector & set_real_variable(const std::string &name, size_type niter) const
Gives the write access to the vector value of a variable.
const model_real_plain_vector & real_variable(const std::string &name, size_type niter) const
Gives the access to the vector value of a variable.
Extraction of the boundary of a slice.
The output of a getfem::mesh_slicer which has been recorded.
void build(const getfem::mesh &m, const slicer_action &a, size_type nrefine=1)
Build the slice, by applying a slicer_action operation.
The Iteration object calculates whether the solution has reached the desired accuracy,...
sparse vector built upon std::vector.
Export solutions to various formats.
Standard solvers for model bricks.
Non-linear elasticty and incompressibility bricks.
Include common gmm files.
void copy(const L1 &l1, L2 &l2)
*/
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm2(const V &v)
Euclidean norm of a vector.
void APIDECL outer_faces_of_mesh(const mesh &m, const dal::bit_vector &cvlst, convex_face_ct &flist)
returns a list of "exterior" faces of a mesh (i.e.
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
pfem fem_descriptor(const std::string &name)
get a fem descriptor from its string name.
pfem classical_fem(bgeot::pgeometric_trans pgt, short_type k, bool complete=false)
Give a pointer on the structures describing the classical polynomial fem of degree k on a given conve...
pgeometric_trans geometric_trans_descriptor(std::string name)
Get the geometric transformation from its string name.
size_t size_type
used as the common size type in the library
std::shared_ptr< const bgeot::geometric_trans > pgeometric_trans
pointer type for a geometric transformation
size_type APIDECL add_Dirichlet_condition_with_multipliers(model &md, const mesh_im &mim, const std::string &varname, const std::string &multname, size_type region, const std::string &dataname=std::string())
Add a Dirichlet condition on the variable varname and the mesh region region.
size_type add_finite_strain_elasticity_brick(model &md, const mesh_im &mim, const std::string &lawname, const std::string &varname, const std::string ¶ms, size_type region=size_type(-1))
Add a finite strain elasticity brick to the model with respect to the variable varname (the displacem...
size_type add_finite_strain_incompressibility_brick(model &md, const mesh_im &mim, const std::string &varname, const std::string &multname, size_type region=size_type(-1))
Add a finite strain incompressibility term (for large strain elasticity) to the model with respect to...
void regular_unit_mesh(mesh &m, std::vector< size_type > nsubdiv, bgeot::pgeometric_trans pgt, bool noised=false)
Build a regular mesh of the unit square/cube/, etc.
pintegration_method int_method_descriptor(std::string name, bool throw_if_not_found=true)
Get an integration method from its name .
size_type APIDECL add_Dirichlet_condition_with_penalization(model &md, const mesh_im &mim, const std::string &varname, scalar_type penalization_coeff, size_type region, const std::string &dataname=std::string(), const mesh_fem *mf_mult=0)
Add a Dirichlet condition on the variable varname and the mesh region region.
size_type APIDECL add_source_term_brick(model &md, const mesh_im &mim, const std::string &varname, const std::string &dataexpr, size_type region=size_type(-1), const std::string &directdataname=std::string())
Add a source term on the variable varname.
void standard_solve(model &md, gmm::iteration &iter, rmodel_plsolver_type lsolver, abstract_newton_line_search &ls)
A default solver for the model brick system.