37 using std::endl;
using std::cout;
using std::cerr;
38 using std::ends;
using std::cin;
43 using bgeot::base_vector;
44 using bgeot::scalar_type;
46 using bgeot::dim_type;
47 using bgeot::base_matrix;
53 typedef getfem::modeling_standard_sparse_matrix sparse_matrix;
54 typedef getfem::modeling_standard_plain_vector plain_vector;
59 struct elastostatic_problem {
61 enum { DIRICHLET_BOUNDARY_NUM = 0, NEUMANN_BOUNDARY_NUM = 1};
68 scalar_type p1, p2, p3;
72 std::string datafilename;
73 bgeot::md_param PARAM;
75 bool solve(plain_vector &U);
77 elastostatic_problem(
void) : mim(mesh), mf_u(mesh), mf_p(mesh), mf_rhs(mesh),
87 void elastostatic_problem::init(
void) {
88 std::string MESH_TYPE = PARAM.string_value(
"MESH_TYPE",
"Mesh type ");
89 std::string FEM_TYPE = PARAM.string_value(
"FEM_TYPE",
"FEM name");
90 std::string FEM_TYPE_P= PARAM.string_value(
"FEM_TYPE_P",
91 "FEM name for the pressure");
92 std::string INTEGRATION = PARAM.string_value(
"INTEGRATION",
93 "Name of integration method");
94 cout <<
"MESH_TYPE=" << MESH_TYPE <<
"\n";
95 cout <<
"FEM_TYPE=" << FEM_TYPE <<
"\n";
96 cout <<
"INTEGRATION=" << INTEGRATION <<
"\n";
102 std::vector<size_type> nsubdiv(N);
103 std::fill(nsubdiv.begin(),nsubdiv.end(),
104 PARAM.int_value(
"NX",
"Nomber of space steps "));
105 nsubdiv[1] = PARAM.int_value(
"NY") ? PARAM.int_value(
"NY") : nsubdiv[0];
107 nsubdiv[2] = PARAM.int_value(
"NZ") ? PARAM.int_value(
"NZ") : nsubdiv[0];
109 PARAM.int_value(
"MESH_NOISED") != 0);
111 bgeot::base_matrix M(N,N);
113 static const char *t[] = {
"LX",
"LY",
"LZ"};
114 M(i,i) = (i<3) ? PARAM.real_value(t[i],t[i]) : 1.0;
116 if (N>1) { M(0,1) = PARAM.real_value(
"INCLINE") * PARAM.real_value(
"LY"); }
119 mesh.transformation(M);
121 datafilename = PARAM.string_value(
"ROOTFILENAME",
"Base name of data files.");
122 residual = PARAM.real_value(
"RESIDUAL");
if (residual == 0.) residual = 1e-10;
124 p1 = PARAM.real_value(
"P1",
"First Elastic coefficient");
125 p2 = PARAM.real_value(
"P2",
"Second Elastic coefficient");
126 p3 = PARAM.real_value(
"P3",
"Third Elastic coefficient");
128 mf_u.set_qdim(dim_type(N));
133 getfem::pintegration_method ppi =
136 mim.set_integration_method(ppi);
137 mf_u.set_finite_element(pf_u);
143 std::string data_fem_name = PARAM.string_value(
"DATA_FEM_TYPE");
144 if (data_fem_name.size() == 0) {
145 GMM_ASSERT1(pf_u->is_lagrange(),
"You are using a non-lagrange FEM"
146 ". In that case you need to set "
147 <<
"DATA_FEM_TYPE in the .param file");
148 mf_rhs.set_finite_element(mesh.convex_index(), pf_u);
150 mf_rhs.set_finite_element(mesh.convex_index(),
157 mf_coef.set_finite_element(mesh.convex_index(),
162 cout <<
"Selecting Neumann and Dirichlet boundaries\n";
166 assert(it.is_face());
167 base_node un = mesh.normal_of_face_of_convex(it.cv(), it.f());
169 if (gmm::abs(un[N-1] - 1.0) < 1.0E-7) {
170 mesh.region(DIRICHLET_BOUNDARY_NUM).add(it.cv(),it.f());
171 }
else if (gmm::abs(un[N-1] + 1.0) < 1.0E-7) {
172 mesh.region(DIRICHLET_BOUNDARY_NUM).add(it.cv(),it.f());
181 bool elastostatic_problem::solve(plain_vector &U) {
184 size_type law_num = PARAM.int_value(
"LAW");
186 base_vector p(3); p[0] = p1; p[1] = p2; p[2] = p3;
192 case 1: lawname =
"Saint_Venant_Kirchhoff"; p.resize(2);
break;
193 case 2: lawname =
"Ciarlet_Geymonat"; p.resize(3);
break;
194 case 3: lawname =
"Incompressible_Mooney_Rivlin"; p.resize(2);
break;
195 default: GMM_ASSERT1(
false,
"no such law");
199 cout <<
"2D plane strain hyper-elasticity\n";
200 lawname =
"Plane_Strain_"+lawname;
213 if (law_num == 1 || law_num == 3) {
220 f[0] = PARAM.real_value(
"FORCEX",
"Amplitude of the gravity");
221 f[1] = PARAM.real_value(
"FORCEY",
"Amplitude of the gravity");
223 f[2] = PARAM.real_value(
"FORCEZ",
"Amplitude of the gravity");
224 plain_vector F(nb_dof_rhs * N);
225 for (
size_type i = 0; i < nb_dof_rhs; ++i) {
226 gmm::copy(f, gmm::sub_vector(F, gmm::sub_interval(i*N, N)));
233 plain_vector F2(nb_dof_rhs * N);
235 if (PARAM.int_value(
"DIRICHLET_VERSION") == 0)
237 (model, mim,
"u", mf_u, DIRICHLET_BOUNDARY_NUM,
"DirichletData");
240 (model, mim,
"u", 1E15, DIRICHLET_BOUNDARY_NUM,
"DirichletData");
244 gmm::set_traces_level(1);
251 PARAM.int_value(
"VTK_EXPORT")==1);
254 exp.exporting(sl,
true); exp.exporting_mesh_edges();
256 exp.write_point_data(mf_u, U,
"stepinit");
257 exp.serie_add_object(
"deformationsteps");
259 GMM_ASSERT1(!mf_rhs.is_reduced(),
"To be adapted for reduced mesh_fems");
261 int nb_step = int(PARAM.int_value(
"NBSTEP"));
262 size_type maxit = PARAM.int_value(
"MAXITER");
264 for (
int step = 0; step < nb_step; ++step) {
267 gmm::copy(gmm::scaled(F, (step+1.)/(scalar_type)nb_step), DF);
272 scalar_type torsion = PARAM.real_value(
"TORSION",
273 "Amplitude of the torsion");
274 torsion *= (step+1)/scalar_type(nb_step);
275 scalar_type extension = PARAM.real_value(
"EXTENSION",
276 "Amplitude of the extension");
277 extension *= (step+1)/scalar_type(nb_step);
278 base_node G(N); G[0] = G[1] = 0.5;
279 for (
size_type i = 0; i < nb_dof_rhs; ++i) {
280 const base_node P = mf_rhs.point_of_basic_dof(i) - G;
281 scalar_type r = sqrt(P[0]*P[0]+P[1]*P[1]),
282 theta = atan2(P[1],P[0]);
283 F2[i*N+0] = r*cos(theta + (torsion*P[2])) - P[0];
284 F2[i*N+1] = r*sin(theta + (torsion*P[2])) - P[1];
285 F2[i*N+2] = extension * P[2];
291 cout <<
"step " << step <<
", number of variables : "
292 << model.
nb_dof() << endl;
294 maxit ? maxit : 40000);
303 exp.write_point_data(mf_u, U);
304 exp.serie_add_object(
"deformationsteps");
310 return (iter.converged());
317 int main(
int argc,
char *argv[]) {
319 GETFEM_MPI_INIT(argc, argv);
320 GMM_SET_EXCEPTION_DEBUG;
324 elastostatic_problem p;
325 p.PARAM.read_command_line(argc, argv);
327 p.mesh.write_to_file(p.datafilename +
".mesh");
328 p.mf_u.write_to_file(p.datafilename +
".mf",
true);
329 p.mf_rhs.write_to_file(p.datafilename +
".mfd",
true);
330 plain_vector U(p.mf_u.nb_dof());
331 GMM_ASSERT1(p.solve(U),
"Solve has failed");
332 if (p.PARAM.int_value(
"VTK_EXPORT")) {
333 gmm::vecsave(p.datafilename +
".U", U);
334 cout <<
"export to " << p.datafilename +
".vtk" <<
"..\n";
336 p.PARAM.int_value(
"VTK_EXPORT")==1);
337 exp.exporting(p.mf_u);
338 exp.write_point_data(p.mf_u, U,
"elastostatic_displacement");
339 cout <<
"export done, you can view the data file with (for example)\n"
340 "mayavi2 -d " << p.datafilename <<
".vtk -f ExtractVectorNorm -f "
341 "WarpVector -m Surface -m Outline\n";
344 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.