49 std::string equation_name = std::string(name_) +
"_FE";
51 std::string(equation_name),
52 "FEM for linear elasticity.")
55 "Settings for computing balance.")
57 "Parameters of output stream.")
59 "Linear solver for elasticity.")
62 .make_field_descriptor_type(equation_name)),
64 "Input fields of the equation.")
66 EqFields().output_fields.make_output_type(equation_name,
""),
67 IT::Default(
"{ \"fields\": [ \"displacement\" ] }"),
68 "Setting of the field output.")
74 Input::register_class< Elasticity, Mesh &, const Input::Record>(std::string(name_) +
"_FE") +
79 double lame_mu(
double young,
double poisson)
81 return young*0.5/(poisson+1.);
87 return young*poisson/((poisson+1.)*(1.-2.*poisson));
92 inline double operator() (
double young,
double poisson) {
93 return young * 0.5 / (poisson+1.);
99 inline double operator() (
double young,
double poisson) {
100 return young * poisson / ((poisson+1.)*(1.-2.*poisson));
117 return Selection(
"Elasticity_BC_Type",
"Types of boundary conditions for mechanics.")
118 .
add_value(bc_type_displacement,
"displacement",
119 "Prescribed displacement.")
120 .
add_value(bc_type_displacement_normal,
"displacement_n",
121 "Prescribed displacement in the normal direction to the boundary.")
123 "Prescribed traction.")
125 "Prescribed stress tensor.")
135 "Type of boundary condition.")
137 .input_default(
"\"traction\"")
138 .input_selection( get_bc_type_selection() )
141 *
this+=bc_displacement
142 .name(
"bc_displacement")
143 .description(
"Prescribed displacement on boundary.")
145 .input_default(
"0.0")
150 .description(
"Prescribed traction on boundary.")
152 .input_default(
"0.0")
157 .description(
"Prescribed stress on boundary.")
159 .input_default(
"0.0")
164 .description(
"Prescribed bulk load.")
165 .units(
UnitSI().N().m(-3) )
166 .input_default(
"0.0")
170 .name(
"young_modulus")
171 .description(
"Young's modulus.")
173 .input_default(
"0.0")
174 .flags_add(in_main_matrix & in_rhs);
177 .name(
"poisson_ratio")
178 .description(
"Poisson's ratio.")
179 .units(
UnitSI().dimensionless() )
180 .input_default(
"0.0")
181 .flags_add(in_main_matrix & in_rhs);
183 *
this+=fracture_sigma
184 .name(
"fracture_sigma")
186 "Coefficient of transfer of forces through fractures.")
188 .input_default(
"1.0")
189 .flags_add(in_main_matrix & in_rhs);
191 *
this+=initial_stress
192 .name(
"initial_stress")
193 .description(
"Initial stress tensor.")
195 .input_default(
"0.0")
198 *
this += region_id.name(
"region_id")
202 *
this += subdomain.name(
"subdomain")
207 .name(
"cross_section")
208 .units(
UnitSI().m(3).md() )
209 .flags(input_copy & in_time_term & in_main_matrix & in_rhs);
211 *
this+=cross_section_min
212 .name(
"cross_section_min")
213 .description(
"Minimal cross-section of fractures.")
214 .units(
UnitSI().m(3).md() )
215 .input_default(
"0.0");
217 *
this+=potential_load
218 .name(
"potential_load")
220 .flags(input_copy & in_rhs);
223 .name(
"displacement")
224 .description(
"Displacement vector field output.")
226 .flags(equation_result);
228 *
this += output_stress
230 .description(
"Stress tensor output.")
232 .flags(equation_result);
234 *
this += output_von_mises_stress
235 .name(
"von_mises_stress")
236 .description(
"von Mises stress output.")
238 .flags(equation_result);
240 *
this += output_mean_stress
242 .description(
"mean stress output.")
244 .flags(equation_result);
246 *
this += output_cross_section
247 .name(
"cross_section_updated")
248 .description(
"Cross-section after deformation - output.")
250 .flags(equation_result);
252 *
this += output_divergence
253 .name(
"displacement_divergence")
254 .description(
"Displacement divergence output.")
255 .units(
UnitSI().dimensionless() )
256 .flags(equation_result);
258 *
this +=
lame_mu.name(
"lame_mu")
259 .description(
"Field lame_mu.")
260 .input_default(
"0.0")
264 .description(
"Field lame_lambda.")
265 .input_default(
"0.0")
268 *
this += dirichlet_penalty.name(
"dirichlet_penalty")
269 .description(
"Field dirichlet_penalty.")
270 .input_default(
"0.0")
274 output_fields += *
this;
280 ASSERT_EQ(fe_order, 1)(fe_order).error(
"Unsupported polynomial order for finite elements in Elasticity");
284 std::shared_ptr<DiscreteSpace> ds = std::make_shared<EqualOrderDiscreteSpace>(mesh, fe);
285 dh_ = std::make_shared<DOFHandlerMultiDim>(*mesh);
287 dh_->distribute_dofs(ds);
291 dh_scalar_ = make_shared<DOFHandlerMultiDim>(*mesh);
292 std::shared_ptr<DiscreteSpace> ds_scalar = std::make_shared<EqualOrderDiscreteSpace>( mesh, fe_p_disc);
293 dh_scalar_->distribute_dofs(ds_scalar);
297 dh_tensor_ = make_shared<DOFHandlerMultiDim>(*mesh);
298 std::shared_ptr<DiscreteSpace> dst = std::make_shared<EqualOrderDiscreteSpace>( mesh, fe_t);
299 dh_tensor_->distribute_dofs(dst);
306 stiffness_assembly_(nullptr),
307 rhs_assembly_(nullptr),
308 constraint_assembly_(nullptr),
309 output_fields_assembly_(nullptr)
315 eq_data_ = std::make_shared<EqData>();
328 ASSERT( time_from_rec.
is_default() ).error(
"Duplicate key 'time', time in elasticity is already initialized from parent class!");
341 DebugOut().fmt(
"Mechanics: solution size {}\n",
eq_data_->dh_->n_global_dofs());
364 eq_fields_->output_field_ptr = create_field_fe<3, FieldValue<3>::VectorFixed>(
eq_data_->dh_);
368 eq_fields_->output_stress_ptr = create_field_fe<3, FieldValue<3>::TensorFixed>(
eq_data_->dh_tensor_);
372 eq_fields_->output_von_mises_stress_ptr = create_field_fe<3, FieldValue<3>::Scalar>(
eq_data_->dh_scalar_);
376 eq_fields_->output_mean_stress_ptr = create_field_fe<3, FieldValue<3>::Scalar>(
eq_data_->dh_scalar_);
380 eq_fields_->output_cross_section_ptr = create_field_fe<3, FieldValue<3>::Scalar>(
eq_data_->dh_scalar_);
384 eq_fields_->output_div_ptr = create_field_fe<3, FieldValue<3>::Scalar>(
eq_data_->dh_scalar_);
399 std::string petsc_default_opts;
400 petsc_default_opts =
"-ksp_type cg -pc_type hypre -pc_hypre_type boomeramg";
406 #ifndef FLOW123D_HAVE_PERMON
407 ASSERT(
false).error(
"Flow123d was not built with PERMON library, therefore contact conditions are unsupported.");
408 #endif //FLOW123D_HAVE_PERMON
412 unsigned int n_own_constraints = 0;
413 for (
auto cell :
eq_data_->dh_->own_range())
414 if (cell.elm()->n_neighs_vb() > 0)
416 unsigned int n_constraints = 0;
418 if (elm->n_neighs_vb() > 0)
419 eq_data_->constraint_idx[elm.idx()] = n_constraints++;
423 MatCreateAIJ(PETSC_COMM_WORLD, n_own_constraints,
eq_data_->dh_->lsize(), PETSC_DECIDE, PETSC_DECIDE, nnz, 0, nnz, 0, &
eq_data_->constraint_matrix);
424 VecCreateMPI(PETSC_COMM_WORLD, n_own_constraints, PETSC_DECIDE, &
eq_data_->constraint_vec);
467 eq_fields_->output_field_ptr->vec().local_to_ghost_begin();
468 eq_fields_->output_stress_ptr->vec().zero_entries();
469 eq_fields_->output_cross_section_ptr->vec().zero_entries();
470 eq_fields_->output_div_ptr->vec().zero_entries();
471 eq_fields_->output_field_ptr->vec().local_to_ghost_end();
477 eq_fields_->output_stress_ptr->vec().local_to_ghost_begin();
478 eq_fields_->output_von_mises_stress_ptr->vec().local_to_ghost_begin();
479 eq_fields_->output_mean_stress_ptr->vec().local_to_ghost_begin();
480 eq_fields_->output_cross_section_ptr->vec().local_to_ghost_begin();
481 eq_fields_->output_div_ptr->vec().local_to_ghost_begin();
482 eq_fields_->output_stress_ptr->vec().local_to_ghost_end();
483 eq_fields_->output_von_mises_stress_ptr->vec().local_to_ghost_end();
484 eq_fields_->output_mean_stress_ptr->vec().local_to_ghost_end();
485 eq_fields_->output_cross_section_ptr->vec().local_to_ghost_end();
486 eq_fields_->output_div_ptr->vec().local_to_ghost_end();
497 std::stringstream ss;
511 MatSetOption(*
eq_data_->ls->get_matrix(), MAT_KEEP_NONZERO_PATTERN, PETSC_TRUE);
518 MessageOut().fmt(
"[mech solver] lin. it: {}, reason: {}, residual: {}\n",
569 if (
eq_data_->ls->get_matrix() == NULL
572 DebugOut() <<
"Mechanics: Assembling matrix.\n";
583 DebugOut() <<
"Mechanics: Assembling right hand side.\n";
592 MessageOut().fmt(
"[mech solver] lin. it: {}, reason: {}, residual: {}\n",
634 MatZeroEntries(
eq_data_->constraint_matrix);
635 VecZeroEntries(
eq_data_->constraint_vec);
637 MatAssemblyBegin(
eq_data_->constraint_matrix, MAT_FINAL_ASSEMBLY);
638 MatAssemblyEnd(
eq_data_->constraint_matrix, MAT_FINAL_ASSEMBLY);
639 VecAssemblyBegin(
eq_data_->constraint_vec);
640 VecAssemblyEnd(
eq_data_->constraint_vec);