39 using std::endl;
using std::cout;
using std::cerr;
40 using std::ends;
using std::cin;
45 using bgeot::base_vector;
46 using bgeot::scalar_type;
48 using bgeot::dim_type;
49 using bgeot::base_matrix;
55 typedef getfem::modeling_standard_sparse_matrix sparse_matrix;
56 typedef getfem::modeling_standard_plain_vector plain_vector;
61 struct elastostatic_problem {
63 enum { DIRICHLET_BOUNDARY_NUM = 0, NEUMANN_BOUNDARY_NUM = 1};
70 scalar_type p1, p2, p3;
74 std::string datafilename;
75 bgeot::md_param PARAM;
77 bool solve(plain_vector &U);
79 elastostatic_problem(
void) : mim(mesh), mf_u(mesh), mf_p(mesh), mf_rhs(mesh),
89 void elastostatic_problem::init(
void) {
90 std::string MESH_TYPE = PARAM.string_value(
"MESH_TYPE",
"Mesh type ");
91 std::string FEM_TYPE = PARAM.string_value(
"FEM_TYPE",
"FEM name");
92 std::string FEM_TYPE_P= PARAM.string_value(
"FEM_TYPE_P",
93 "FEM name for the pressure");
94 std::string INTEGRATION = PARAM.string_value(
"INTEGRATION",
95 "Name of integration method");
96 cout <<
"MESH_TYPE=" << MESH_TYPE <<
"\n";
97 cout <<
"FEM_TYPE=" << FEM_TYPE <<
"\n";
98 cout <<
"INTEGRATION=" << INTEGRATION <<
"\n";
104 std::vector<size_type> nsubdiv(N);
105 std::fill(nsubdiv.begin(),nsubdiv.end(),
106 PARAM.int_value(
"NX",
"Nomber of space steps "));
107 nsubdiv[1] = PARAM.int_value(
"NY") ? PARAM.int_value(
"NY") : nsubdiv[0];
109 nsubdiv[2] = PARAM.int_value(
"NZ") ? PARAM.int_value(
"NZ") : nsubdiv[0];
111 PARAM.int_value(
"MESH_NOISED") != 0);
113 bgeot::base_matrix M(N,N);
115 static const char *t[] = {
"LX",
"LY",
"LZ"};
116 M(i,i) = (i<3) ? PARAM.real_value(t[i],t[i]) : 1.0;
118 if (N>1) { M(0,1) = PARAM.real_value(
"INCLINE") * PARAM.real_value(
"LY"); }
121 mesh.transformation(M);
123 datafilename = PARAM.string_value(
"ROOTFILENAME",
"Base name of data files.");
124 residual = PARAM.real_value(
"RESIDUAL");
if (residual == 0.) residual = 1e-10;
126 p1 = PARAM.real_value(
"P1",
"First Elastic coefficient");
127 p2 = PARAM.real_value(
"P2",
"Second Elastic coefficient");
128 p3 = PARAM.real_value(
"P3",
"Third Elastic coefficient");
130 mf_u.set_qdim(dim_type(N));
135 getfem::pintegration_method ppi =
138 mim.set_integration_method(ppi);
139 mf_u.set_finite_element(pf_u);
145 std::string data_fem_name = PARAM.string_value(
"DATA_FEM_TYPE");
146 if (data_fem_name.size() == 0) {
147 GMM_ASSERT1(pf_u->is_lagrange(),
"You are using a non-lagrange FEM" 148 ". In that case you need to set " 149 <<
"DATA_FEM_TYPE in the .param file");
150 mf_rhs.set_finite_element(mesh.convex_index(), pf_u);
152 mf_rhs.set_finite_element(mesh.convex_index(),
159 mf_coef.set_finite_element(mesh.convex_index(),
164 cout <<
"Selecting Neumann and Dirichlet boundaries\n";
168 assert(it.is_face());
169 base_node un = mesh.normal_of_face_of_convex(it.cv(), it.f());
171 if (gmm::abs(un[N-1] - 1.0) < 1.0E-7) {
172 mesh.region(DIRICHLET_BOUNDARY_NUM).add(it.cv(),it.f());
173 }
else if (gmm::abs(un[N-1] + 1.0) < 1.0E-7) {
174 mesh.region(DIRICHLET_BOUNDARY_NUM).add(it.cv(),it.f());
183 bool elastostatic_problem::solve(plain_vector &U) {
186 size_type law_num = PARAM.int_value(
"LAW");
188 base_vector p(3); p[0] = p1; p[1] = p2; p[2] = p3;
194 case 1: lawname =
"Saint_Venant_Kirchhoff"; p.resize(2);
break;
195 case 2: lawname =
"Ciarlet_Geymonat"; p.resize(3);
break;
196 case 3: lawname =
"Incompressible_Mooney_Rivlin"; p.resize(2);
break;
197 default: GMM_ASSERT1(
false,
"no such law");
201 cout <<
"2D plane strain hyper-elasticity\n";
202 lawname =
"Plane_Strain_"+lawname;
215 if (law_num == 1 || law_num == 3) {
222 f[0] = PARAM.real_value(
"FORCEX",
"Amplitude of the gravity");
223 f[1] = PARAM.real_value(
"FORCEY",
"Amplitude of the gravity");
225 f[2] = PARAM.real_value(
"FORCEZ",
"Amplitude of the gravity");
226 plain_vector F(nb_dof_rhs * N);
227 for (
size_type i = 0; i < nb_dof_rhs; ++i) {
228 gmm::copy(f, gmm::sub_vector(F, gmm::sub_interval(i*N, N)));
235 plain_vector F2(nb_dof_rhs * N);
237 if (PARAM.int_value(
"DIRICHLET_VERSION") == 0)
239 (model, mim,
"u", mf_u, DIRICHLET_BOUNDARY_NUM,
"DirichletData");
242 (model, mim,
"u", 1E15, DIRICHLET_BOUNDARY_NUM,
"DirichletData");
246 gmm::set_traces_level(1);
253 PARAM.int_value(
"VTK_EXPORT")==1);
256 exp.exporting(sl,
true); exp.exporting_mesh_edges();
258 exp.write_point_data(mf_u, U,
"stepinit");
259 exp.serie_add_object(
"deformationsteps");
261 GMM_ASSERT1(!mf_rhs.is_reduced(),
"To be adapted for reduced mesh_fems");
263 int nb_step = int(PARAM.int_value(
"NBSTEP"));
264 size_type maxit = PARAM.int_value(
"MAXITER");
266 for (
int step = 0; step < nb_step; ++step) {
269 gmm::copy(gmm::scaled(F, (step+1.)/(scalar_type)nb_step), DF);
274 scalar_type torsion = PARAM.real_value(
"TORSION",
275 "Amplitude of the torsion");
276 torsion *= (step+1)/scalar_type(nb_step);
277 scalar_type extension = PARAM.real_value(
"EXTENSION",
278 "Amplitude of the extension");
279 extension *= (step+1)/scalar_type(nb_step);
280 base_node G(N); G[0] = G[1] = 0.5;
281 for (
size_type i = 0; i < nb_dof_rhs; ++i) {
282 const base_node P = mf_rhs.point_of_basic_dof(i) - G;
283 scalar_type r = sqrt(P[0]*P[0]+P[1]*P[1]),
284 theta = atan2(P[1],P[0]);
285 F2[i*N+0] = r*cos(theta + (torsion*P[2])) - P[0];
286 F2[i*N+1] = r*sin(theta + (torsion*P[2])) - P[1];
287 F2[i*N+2] = extension * P[2];
293 cout <<
"step " << step <<
", number of variables : " 294 << model.
nb_dof() << endl;
296 maxit ? maxit : 40000);
305 exp.write_point_data(mf_u, U);
306 exp.serie_add_object(
"deformationsteps");
312 return (iter.converged());
319 int main(
int argc,
char *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);
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;
structure used to hold a set of convexes and/or convex faces.
size_type nb_dof() const
Total number of degrees of freedom in the model.
Export solutions to various formats.
pfem fem_descriptor(const std::string &name)
get a fem descriptor from its string name.
The Iteration object calculates whether the solution has reached the desired accuracy, or whether the maximum number of iterations has been reached.
Non-linear elasticty and incompressibility bricks.
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 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.
Extraction of the boundary of a slice.
Describe a mesh (collection of convexes (elements) and points).
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.
pintegration_method int_method_descriptor(std::string name, bool throw_if_not_found=true)
Get an integration method from its name .
Describe an integration method linked to a mesh.
void exporting(const mesh &m)
should be called before write_*_data
pgeometric_trans geometric_trans_descriptor(std::string name)
Get the geometric transformation from its string name.
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...
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm2(const V &v)
Euclidean norm of a vector.
``Model'' variables store the variables, the data and the description of a model. ...
size_t size_type
used as the common size type in the library
Standard solvers for model bricks.
"iterator" class for regions.
The output of a getfem::mesh_slicer which has been recorded.
A (quite large) class for exportation of data to IBM OpenDX.
sparse vector built upon std::vector.
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
Describe a finite element method linked to a mesh.
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.
void build(const getfem::mesh &m, const slicer_action &a, size_type nrefine=1)
Build the slice, by applying a slicer_action operation.
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...
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...
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.
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.
Include common gmm files.
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.
SuperLU interface for getfem.
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.
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_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 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.