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 GETFEM_MPI_INIT(argc, argv);
322 GMM_SET_EXCEPTION_DEBUG;
326 elastostatic_problem p;
327 p.PARAM.read_command_line(argc, argv);
329 p.mesh.write_to_file(p.datafilename +
".mesh");
330 p.mf_u.write_to_file(p.datafilename +
".mf",
true);
331 p.mf_rhs.write_to_file(p.datafilename +
".mfd",
true);
332 plain_vector U(p.mf_u.nb_dof());
333 GMM_ASSERT1(p.solve(U),
"Solve has failed");
334 if (p.PARAM.int_value(
"VTK_EXPORT")) {
335 gmm::vecsave(p.datafilename +
".U", U);
336 cout <<
"export to " << p.datafilename +
".vtk" <<
"..\n";
338 p.PARAM.int_value(
"VTK_EXPORT")==1);
339 exp.exporting(p.mf_u);
340 exp.write_point_data(p.mf_u, U,
"elastostatic_displacement");
341 cout <<
"export done, you can view the data file with (for example)\n"
342 "mayavi2 -d " << p.datafilename <<
".vtk -f ExtractVectorNorm -f "
343 "WarpVector -m Surface -m Outline\n";
346 GMM_STANDARD_CATCH_ERROR;