Flow123d  JS_before_hm-1013-g06f2edc
elasticity.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file transport_dg.cc
15  * @brief Discontinuous Galerkin method for equation of transport with dispersion.
16  * @author Jan Stebel
17  */
18 
19 #include "system/sys_profiler.hh"
20 #include "mechanics/elasticity.hh"
21 
22 #include "io/output_time.hh"
24 #include "fem/fe_values.hh"
25 #include "fem/fe_p.hh"
26 #include "fem/fe_rt.hh"
27 #include "fem/fe_system.hh"
28 #include "fields/field_fe.hh"
29 #include "la/linsys_PETSC.hh"
30 #include "coupling/balance.hh"
31 #include "mesh/neighbours.h"
32 
33 #include "fields/multi_field.hh"
34 #include "fields/generic_field.hh"
35 #include "input/factory.hh"
36 
37 
38 
39 
40 using namespace Input::Type;
41 
42 
44  std::string equation_name = std::string(Elasticity::EqData::name()) + "_FE";
45  return IT::Record(
46  std::string(equation_name),
47  "FEM for linear elasticity.")
49  .declare_key("balance", Balance::get_input_type(), Default("{}"),
50  "Settings for computing balance.")
52  "Parameters of output stream.")
54  "Linear solver for elasticity.")
55  .declare_key("input_fields", Array(
57  .make_field_descriptor_type(equation_name)),
59  "Input fields of the equation.")
60  .declare_key("output",
61  EqData().output_fields.make_output_type(equation_name, ""),
62  IT::Default("{ \"fields\": [ "+Elasticity::EqData::default_output_field()+" ] }"),
63  "Setting of the field output.")
64  .close();
65 }
66 
67 const int Elasticity::registrar =
68  Input::register_class< Elasticity, Mesh &, const Input::Record>(std::string(Elasticity::EqData::name()) + "_FE") +
70 
71 
72 
73 namespace Mechanics {
74 
75 FEObjects::FEObjects(Mesh *mesh_, unsigned int fe_order)
76 : q_(QGauss::make_array(2))
77 {
78  switch (fe_order)
79  {
80  case 1: {
81  MixedPtr<FE_P> fe_p(1);
82  fe_ = mixed_fe_system(fe_p, FEVector, 3);
83  break;
84  }
85  default:
86  xprintf(PrgErr, "Unsupported polynomial order %d for finite elements in Elasticity", fe_order);
87  break;
88  }
89 
90 
91  ds_ = std::make_shared<EqualOrderDiscreteSpace>(mesh_, fe_);
92  dh_ = std::make_shared<DOFHandlerMultiDim>(*mesh_);
93 
94  dh_->distribute_dofs(ds_);
95 
96 
97  MixedPtr<FE_P_disc> fe_p(0);
98  dh_scalar_ = make_shared<DOFHandlerMultiDim>(*mesh_);
99  std::shared_ptr<DiscreteSpace> ds = std::make_shared<EqualOrderDiscreteSpace>( mesh_, fe_p);
100  dh_scalar_->distribute_dofs(ds);
101 
102 
104  dh_tensor_ = make_shared<DOFHandlerMultiDim>(*mesh_);
105  std::shared_ptr<DiscreteSpace> dst = std::make_shared<EqualOrderDiscreteSpace>( mesh_, fe_t);
106  dh_tensor_->distribute_dofs(dst);
107 }
108 
109 
111 {
112 }
113 
114 template<> std::shared_ptr<FiniteElement<0>> FEObjects::fe<0>() { return fe_[0_d]; }
115 template<> std::shared_ptr<FiniteElement<1>> FEObjects::fe<1>() { return fe_[1_d]; }
116 template<> std::shared_ptr<FiniteElement<2>> FEObjects::fe<2>() { return fe_[2_d]; }
117 template<> std::shared_ptr<FiniteElement<3>> FEObjects::fe<3>() { return fe_[3_d]; }
118 
119 std::shared_ptr<DOFHandlerMultiDim> FEObjects::dh() { return dh_; }
120 std::shared_ptr<DOFHandlerMultiDim> FEObjects::dh_scalar() { return dh_scalar_; }
121 std::shared_ptr<DOFHandlerMultiDim> FEObjects::dh_tensor() { return dh_tensor_; }
122 
123 
124 
125 } // namespace Mechanics
126 
127 
128 double lame_mu(double young, double poisson)
129 {
130  return young*0.5/(poisson+1.);
131 }
132 
133 
134 double lame_lambda(double young, double poisson)
135 {
136  return young*poisson/((poisson+1.)*(1.-2.*poisson));
137 }
138 
139 
140 
141 
142 
143 
145  return Selection("Elasticity_BC_Type", "Types of boundary conditions for mechanics.")
146  .add_value(bc_type_displacement, "displacement",
147  "Prescribed displacement.")
148  .add_value(bc_type_displacement_normal, "displacement_n",
149  "Prescribed displacement in the normal direction to the boundary.")
150  .add_value(bc_type_traction, "traction",
151  "Prescribed traction.")
152  .add_value(bc_type_stress, "stress",
153  "Prescribed stress tensor.")
154  .close();
155 }
156 
157 
159 {
160  *this+=bc_type
161  .name("bc_type")
162  .description(
163  "Type of boundary condition.")
164  .units( UnitSI::dimensionless() )
165  .input_default("\"traction\"")
166  .input_selection( get_bc_type_selection() )
168 
169  *this+=bc_displacement
170  .name("bc_displacement")
171  .description("Prescribed displacement on boundary.")
172  .units( UnitSI().m() )
173  .input_default("0.0")
174  .flags_add(in_rhs);
175 
176  *this+=bc_traction
177  .name("bc_traction")
178  .description("Prescribed traction on boundary.")
179  .units( UnitSI().Pa() )
180  .input_default("0.0")
181  .flags_add(in_rhs);
182 
183  *this+=bc_stress
184  .name("bc_stress")
185  .description("Prescribed stress on boundary.")
186  .units( UnitSI().Pa() )
187  .input_default("0.0")
188  .flags_add(in_rhs);
189 
190  *this+=load
191  .name("load")
192  .description("Prescribed bulk load.")
193  .units( UnitSI().N().m(-3) )
194  .input_default("0.0")
195  .flags_add(in_rhs);
196 
197  *this+=young_modulus
198  .name("young_modulus")
199  .description("Young's modulus.")
200  .units( UnitSI().Pa() )
201  .input_default("0.0")
202  .flags_add(in_main_matrix & in_rhs);
203 
204  *this+=poisson_ratio
205  .name("poisson_ratio")
206  .description("Poisson's ratio.")
207  .units( UnitSI().dimensionless() )
208  .input_default("0.0")
209  .flags_add(in_main_matrix & in_rhs);
210 
211  *this+=fracture_sigma
212  .name("fracture_sigma")
213  .description(
214  "Coefficient of transfer of forces through fractures.")
215  .units( UnitSI::dimensionless() )
216  .input_default("1.0")
217  .flags_add(in_main_matrix & in_rhs);
218 
219  *this += region_id.name("region_id")
220  .units( UnitSI::dimensionless())
222 
223  *this += subdomain.name("subdomain")
224  .units( UnitSI::dimensionless() )
226 
227  *this+=cross_section
228  .name("cross_section")
229  .units( UnitSI().m(3).md() )
230  .flags(input_copy & in_time_term & in_main_matrix & in_rhs);
231 
232  *this+=potential_load
233  .name("potential_load")
234  .units( UnitSI().m() )
235  .flags(input_copy & in_rhs);
236 
237  *this+=output_field
238  .name("displacement")
239  .description("Displacement vector field output.")
240  .units( UnitSI().m() )
241  .flags(equation_result);
242 
243  *this += output_stress
244  .name("stress")
245  .description("Stress tensor output.")
246  .units( UnitSI().Pa() )
247  .flags(equation_result);
248 
249  *this += output_von_mises_stress
250  .name("von_mises_stress")
251  .description("von Mises stress output.")
252  .units( UnitSI().Pa() )
253  .flags(equation_result);
254 
255  *this += output_cross_section
256  .name("cross_section_updated")
257  .description("Cross-section after deformation - output.")
258  .units( UnitSI().m() )
259  .flags(equation_result);
260 
261  *this += output_divergence
262  .name("displacement_divergence")
263  .description("Displacement divergence output.")
264  .units( UnitSI().dimensionless() )
265  .flags(equation_result);
266 
267  // add all input fields to the output list
268  output_fields += *this;
269 
270 }
271 
272 Elasticity::Elasticity(Mesh & init_mesh, const Input::Record in_rec, TimeGovernor *tm)
273  : EquationBase(init_mesh, in_rec),
274  input_rec(in_rec),
275  allocation_done(false)
276 {
277  // Can not use name() + "constructor" here, since START_TIMER only accepts const char *
278  // due to constexpr optimization.
280 
281  this->eq_data_ = &data_;
282 
283  auto time_rec = in_rec.val<Input::Record>("time");
284  if (tm == nullptr)
285  {
286  time_ = new TimeGovernor(time_rec);
287  }
288  else
289  {
290  TimeGovernor time_from_rec(time_rec);
291  ASSERT( time_from_rec.is_default() ).error("Duplicate key 'time', time in elasticity is already initialized from parent class!");
292  time_ = tm;
293  }
294 
295 
296  // Set up physical parameters.
297  data_.set_mesh(init_mesh);
300 
301  // create finite element structures and distribute DOFs
302  feo = new Mechanics::FEObjects(mesh_, 1);
303  DebugOut().fmt("Mechanics: solution size {}\n", feo->dh()->n_global_dofs());
304 
305 }
306 
307 
309 {
310  output_stream_ = OutputTime::create_output_stream("mechanics", input_rec.val<Input::Record>("output_stream"), time().get_unit_string());
311 
312  data_.set_components({"displacement"});
313  data_.set_input_list( input_rec.val<Input::Array>("input_fields"), time() );
314 
315 // balance_ = std::make_shared<Balance>("mechanics", mesh_);
316 // balance_->init_from_input(input_rec.val<Input::Record>("balance"), *time_);
317  // initialization of balance object
318 // data_.balance_idx_ = {
319 // balance_->add_quantity("force_x"),
320 // balance_->add_quantity("force_y"),
321 // balance_->add_quantity("force_z")
322 // };
323 // balance_->units(UnitSI().kg().m().s(-2));
324 
325  // create shared pointer to a FieldFE, pass FE data and push this FieldFE to output_field on all regions
326  data_.output_field_ptr = create_field_fe<3, FieldValue<3>::VectorFixed>(feo->dh());
328 
329  // setup output stress
330  data_.output_stress_ptr = create_field_fe<3, FieldValue<3>::TensorFixed>(feo->dh_tensor());
332 
333  // setup output von Mises stress
334  data_.output_von_mises_stress_ptr = create_field_fe<3, FieldValue<3>::Scalar>(feo->dh_scalar());
336 
337  // setup output cross-section
338  data_.output_cross_section_ptr = create_field_fe<3, FieldValue<3>::Scalar>(feo->dh_scalar());
340 
341  // setup output divergence
342  data_.output_div_ptr = create_field_fe<3, FieldValue<3>::Scalar>(feo->dh_scalar());
344 
346 
347  // set time marks for writing the output
349 
350  // equation default PETSc solver options
351  std::string petsc_default_opts;
352  petsc_default_opts = "-ksp_type cg -pc_type hypre -pc_hypre_type boomeramg";
353 
354  // allocate matrix and vector structures
355  ls = new LinSys_PETSC(feo->dh()->distr().get(), petsc_default_opts);
357  ls->set_solution(data_.output_field_ptr->vec().petsc_vec());
358 
359  // initialization of balance object
360 // balance_->allocate(feo->dh()->distr()->lsize(),
361 // max(feo->fe<1>()->n_dofs(), max(feo->fe<2>()->n_dofs(), feo->fe<3>()->n_dofs())));
362 
363 }
364 
365 
367 {
368 // delete time_;
369 
370  MatDestroy(&stiffness_matrix);
371  VecDestroy(&rhs);
372  delete ls;
373  delete feo;
374 
375 }
376 
377 
378 
380 {
381  // update ghost values of solution vector
382  data_.output_field_ptr->vec().local_to_ghost_begin();
383  data_.output_field_ptr->vec().local_to_ghost_end();
384 
385  // compute new output fields depending on solution (stress, divergence etc.)
386  data_.output_stress_ptr->vec().zero_entries();
387  data_.output_cross_section_ptr->vec().zero_entries();
388  data_.output_div_ptr->vec().zero_entries();
389  compute_output_fields<1>();
390  compute_output_fields<2>();
391  compute_output_fields<3>();
392 
393  // update ghost values of computed fields
394  data_.output_stress_ptr->vec().local_to_ghost_begin();
395  data_.output_stress_ptr->vec().local_to_ghost_end();
396  data_.output_von_mises_stress_ptr->vec().local_to_ghost_begin();
397  data_.output_von_mises_stress_ptr->vec().local_to_ghost_end();
398  data_.output_cross_section_ptr->vec().local_to_ghost_begin();
399  data_.output_cross_section_ptr->vec().local_to_ghost_end();
400  data_.output_div_ptr->vec().local_to_ghost_begin();
401  data_.output_div_ptr->vec().local_to_ghost_end();
402 }
403 
404 
405 
406 
408 {
412  std::stringstream ss; // print warning message with table of uninitialized fields
413  if ( FieldCommon::print_message_table(ss, "mechanics") ) {
414  WarningOut() << ss.str();
415  }
416 
417  ( (LinSys_PETSC *)ls )->set_initial_guess_nonzero();
418 
419  // check first time assembly - needs preallocation
421 
422 
423  // after preallocation we assemble the matrices and vectors required for balance of forces
424 // for (auto subst_idx : data_.balance_idx_)
425 // balance_->calculate_instant(subst_idx, ls->get_solution());
426 
427 // update_solution();
429  MatSetOption(*ls->get_matrix(), MAT_KEEP_NONZERO_PATTERN, PETSC_TRUE);
430  ls->mat_zero_entries();
431  ls->rhs_zero_entries();
433  assemble_rhs();
434  ls->finish_assembly();
435  LinSys::SolveInfo si = ls->solve();
436  MessageOut().fmt("[mech solver] lin. it: {}, reason: {}, residual: {}\n",
438  output_data();
439 }
440 
441 
442 
444 {
445  // preallocate system matrix
446  ls->start_allocation();
447  stiffness_matrix = NULL;
448  rhs = NULL;
449 
451  assemble_rhs();
452 
453  allocation_done = true;
454 }
455 
456 
457 
458 
460 {
461  START_TIMER("DG-ONE STEP");
462 
463  next_time();
465 
467 
468  output_data();
469 
470  END_TIMER("DG-ONE STEP");
471 }
472 
474 {
475  time_->next_time();
476  time_->view("MECH");
477 
478 }
479 
480 
481 
483 {
484  START_TIMER("data reinit");
486  END_TIMER("data reinit");
487 
488  // assemble stiffness matrix
489  if (stiffness_matrix == NULL
491  {
492  DebugOut() << "Mechanics: Assembling matrix.\n";
494  ls->mat_zero_entries();
496  ls->finish_assembly();
497 
498  if (stiffness_matrix == NULL)
499  MatConvert(*( ls->get_matrix() ), MATSAME, MAT_INITIAL_MATRIX, &stiffness_matrix);
500  else
501  MatCopy(*( ls->get_matrix() ), stiffness_matrix, DIFFERENT_NONZERO_PATTERN);
502  }
503 
504  // assemble right hand side (due to sources and boundary conditions)
505  if (rhs == NULL
506  || data_.subset(FieldFlag::in_rhs).changed())
507  {
508  DebugOut() << "Mechanics: Assembling right hand side.\n";
510  ls->rhs_zero_entries();
511  assemble_rhs();
512  ls->finish_assembly();
513 
514  if (rhs == nullptr) VecDuplicate(*( ls->get_rhs() ), &rhs);
515  VecCopy(*( ls->get_rhs() ), rhs);
516  }
517 
518  START_TIMER("solve");
519  LinSys::SolveInfo si = ls->solve();
520  MessageOut().fmt("[mech solver] lin. it: {}, reason: {}, residual: {}\n",
522  END_TIMER("solve");
523 }
524 
525 
526 
527 
528 
529 
531 {
532  START_TIMER("MECH-OUTPUT");
533 
534  // gather the solution from all processors
535  data_.output_fields.set_time( this->time().step(), LimitSide::left);
536  //if (data_.output_fields.is_field_output_time(data_.output_field, this->time().step()) )
538  data_.output_fields.output(this->time().step());
539  output_stream_->write_time_frame();
540 
541 // START_TIMER("MECH-balance");
542 // balance_->calculate_instant(subst_idx, ls->get_solution());
543 // balance_->output();
544 // END_TIMER("MECH-balance");
545 
546  END_TIMER("MECH-OUTPUT");
547 }
548 
549 
550 template<unsigned int dim>
552 {
553  QGauss q(dim, 0), q_sub(dim-1, 0);
554  FEValues<3> fv(q, *feo->fe<dim>(),
556  FEValues<3> fsv(q_sub, *feo->fe<dim>(),
558  const unsigned int ndofs = feo->fe<dim>()->n_dofs();
559  auto vec = fv.vector_view(0);
560  auto vec_side = fsv.vector_view(0);
561  VectorMPI output_vec = data_.output_field_ptr->vec();
562  VectorMPI output_stress_vec = data_.output_stress_ptr->vec();
563  VectorMPI output_von_mises_stress_vec = data_.output_von_mises_stress_ptr->vec();
564  VectorMPI output_cross_sec_vec = data_.output_cross_section_ptr->vec();
565  VectorMPI output_div_vec = data_.output_div_ptr->vec();
566 
567  DHCellAccessor cell_tensor = *feo->dh_tensor()->own_range().begin();
568  DHCellAccessor cell_scalar = *feo->dh_scalar()->own_range().begin();
569  for (auto cell : feo->dh()->own_range())
570  {
571  if (cell.dim() == dim)
572  {
573  auto elm = cell.elm();
574 
575  double poisson = data_.poisson_ratio.value(elm.centre(), elm);
576  double young = data_.young_modulus.value(elm.centre(), elm);
577  double mu = lame_mu(young, poisson);
578  double lambda = lame_lambda(young, poisson);
579 
580  fv.reinit(elm);
581  LocDofVec dof_indices = cell.get_loc_dof_indices();
582  LocDofVec dof_indices_scalar = cell_scalar.get_loc_dof_indices();
583  LocDofVec dof_indices_tensor = cell_tensor.get_loc_dof_indices();
584 
585  arma::mat33 stress = arma::zeros(3,3);
586  double div = 0;
587  for (unsigned int i=0; i<ndofs; i++)
588  {
589  stress += (2*mu*vec.sym_grad(i,0) + lambda*vec.divergence(i,0)*arma::eye(3,3))*output_vec[dof_indices[i]];
590  div += vec.divergence(i,0)*output_vec[dof_indices[i]];
591  }
592 
593  arma::mat33 stress_dev = stress - arma::trace(stress)/3*arma::eye(3,3);
594  double von_mises_stress = sqrt(1.5*arma::dot(stress_dev, stress_dev));
595  output_div_vec[dof_indices_scalar[0]] += div;
596 
597  for (unsigned int i=0; i<3; i++)
598  for (unsigned int j=0; j<3; j++)
599  output_stress_vec[dof_indices_tensor[i*3+j]] += stress(i,j);
600  output_von_mises_stress_vec[dof_indices_scalar[0]] = von_mises_stress;
601 
602  output_cross_sec_vec[dof_indices_scalar[0]] += data_.cross_section.value(fv.point(0), elm);
603  }
604  else if (cell.dim() == dim-1)
605  {
606  auto elm = cell.elm();
607  double normal_displacement = 0;
608  double csection = data_.cross_section.value(fsv.point(0), elm);
609  arma::mat33 normal_stress = arma::zeros(3,3);
610 
611  double poisson = data_.poisson_ratio.value(elm.centre(), elm);
612  double young = data_.young_modulus.value(elm.centre(), elm);
613  double mu = lame_mu(young, poisson);
614  double lambda = lame_lambda(young, poisson);
615 
616  for (unsigned int inb=0; inb<elm->n_neighs_vb(); inb++)
617  {
618  auto side = elm->neigh_vb[inb]->side();
619  auto cell_side = side->element();
620  fsv.reinit(*side);
621  LocDofVec side_dof_indices =
622  feo->dh()->cell_accessor_from_element(cell_side.idx()).get_loc_dof_indices();
623 
624  for (unsigned int i=0; i<ndofs; i++)
625  {
626  normal_displacement -= arma::dot(vec_side.value(i,0)*output_vec[side_dof_indices[i]], fsv.normal_vector(0));
627  arma::mat33 grad = -arma::kron(vec_side.value(i,0)*output_vec[side_dof_indices[i]], fsv.normal_vector(0).t()) / csection;
628  normal_stress += mu*(grad+grad.t()) + lambda*arma::trace(grad)*arma::eye(3,3);
629  }
630  }
631  LocDofVec dof_indices_scalar = cell_scalar.get_loc_dof_indices();
632  LocDofVec dof_indices_tensor = cell_tensor.get_loc_dof_indices();
633  for (unsigned int i=0; i<3; i++)
634  for (unsigned int j=0; j<3; j++)
635  output_stress_vec[dof_indices_tensor[i*3+j]] += normal_stress(i,j);
636  output_cross_sec_vec[dof_indices_scalar[0]] += normal_displacement;
637  output_div_vec[dof_indices_scalar[0]] += normal_displacement / csection;
638  }
639  cell_scalar.inc();
640  cell_tensor.inc();
641  }
642 }
643 
644 
645 
646 
647 
649 {
650 // if (balance_->cumulative())
651 // {
652 // balance_->calculate_cumulative(subst_idx, ls->get_solution());
653 // }
654 }
655 
656 
657 
658 
659 
660 
661 
662 
664 {
665  START_TIMER("assemble_stiffness");
666  START_TIMER("assemble_volume_integrals");
667  assemble_volume_integrals<1>();
668  assemble_volume_integrals<2>();
669  assemble_volume_integrals<3>();
670  END_TIMER("assemble_volume_integrals");
671 
672  START_TIMER("assemble_fluxes_boundary");
673  assemble_fluxes_boundary<1>();
674  assemble_fluxes_boundary<2>();
675  assemble_fluxes_boundary<3>();
676  END_TIMER("assemble_fluxes_boundary");
677 
678  START_TIMER("assemble_matrix_elem_side");
679  assemble_matrix_element_side<1>();
680  assemble_matrix_element_side<2>();
681  assemble_matrix_element_side<3>();
682  END_TIMER("assemble_matrix_elem_side");
683  END_TIMER("assemble_stiffness");
684 }
685 
686 
687 
688 template<unsigned int dim>
690 {
691  FEValues<3> fe_values(*feo->q<dim>(), *feo->fe<dim>(),
693  const unsigned int ndofs = feo->fe<dim>()->n_dofs(), qsize = feo->q<dim>()->size();
694  vector<int> dof_indices(ndofs);
695  vector<arma::vec3> velocity(qsize);
696  vector<double> young(qsize), poisson(qsize), csection(qsize);
697  PetscScalar local_matrix[ndofs*ndofs];
698  auto vec = fe_values.vector_view(0);
699 
700  // assemble integral over elements
701  for (auto cell : feo->dh()->own_range())
702  {
703  if (cell.dim() != dim) continue;
704  ElementAccessor<3> elm_acc = cell.elm();
705 
706  fe_values.reinit(elm_acc);
707  cell.get_dof_indices(dof_indices);
708 
709  data_.cross_section.value_list(fe_values.point_list(), elm_acc, csection);
710  data_.young_modulus.value_list(fe_values.point_list(), elm_acc, young);
711  data_.poisson_ratio.value_list(fe_values.point_list(), elm_acc, poisson);
712 
713  // assemble the local stiffness matrix
714  for (unsigned int i=0; i<ndofs; i++)
715  for (unsigned int j=0; j<ndofs; j++)
716  local_matrix[i*ndofs+j] = 0;
717 
718  for (unsigned int k=0; k<qsize; k++)
719  {
720  double mu = lame_mu(young[k], poisson[k]);
721  double lambda = lame_lambda(young[k], poisson[k]);
722  for (unsigned int i=0; i<ndofs; i++)
723  {
724  for (unsigned int j=0; j<ndofs; j++)
725  local_matrix[i*ndofs+j] += csection[k]*(
726  2*mu*arma::dot(vec.sym_grad(j,k), vec.sym_grad(i,k))
727  + lambda*vec.divergence(j,k)*vec.divergence(i,k)
728  )*fe_values.JxW(k);
729  }
730  }
731  ls->mat_set_values(ndofs, dof_indices.data(), ndofs, dof_indices.data(), local_matrix);
732  }
733 }
734 
735 
736 
738 {
739  START_TIMER("assemble_rhs");
740 // balance_->start_source_assembly(subst_idx);
741 // balance_->start_flux_assembly(subst_idx);
742  assemble_sources<1>();
743  assemble_sources<2>();
744  assemble_sources<3>();
745  assemble_rhs_element_side<1>();
746  assemble_rhs_element_side<2>();
747  assemble_rhs_element_side<3>();
748  assemble_boundary_conditions<1>();
749  assemble_boundary_conditions<2>();
750  assemble_boundary_conditions<3>();
751 // balance_->finish_flux_assembly(subst_idx);
752 // balance_->finish_source_assembly(subst_idx);
753  END_TIMER("assemble_rhs");
754 }
755 
756 
757 template<unsigned int dim>
759 {
760  FEValues<3> fe_values(*feo->q<dim>(), *feo->fe<dim>(),
762  const unsigned int ndofs = feo->fe<dim>()->n_dofs(), qsize = feo->q<dim>()->size();
763  vector<arma::vec3> load(qsize);
764  vector<double> csection(qsize), potential(qsize);
765  vector<int> dof_indices(ndofs);
766  PetscScalar local_rhs[ndofs];
767  vector<PetscScalar> local_source_balance_vector(ndofs), local_source_balance_rhs(ndofs);
768  auto vec = fe_values.vector_view(0);
769 
770  // assemble integral over elements
771  for (auto cell : feo->dh()->own_range())
772  {
773  if (cell.dim() != dim) continue;
774  ElementAccessor<3> elm_acc = cell.elm();
775 
776  fe_values.reinit(elm_acc);
777  cell.get_dof_indices(dof_indices);
778 
779  // assemble the local stiffness matrix
780  fill_n(local_rhs, ndofs, 0);
781  local_source_balance_vector.assign(ndofs, 0);
782  local_source_balance_rhs.assign(ndofs, 0);
783 
784  data_.cross_section.value_list(fe_values.point_list(), elm_acc, csection);
785  data_.load.value_list(fe_values.point_list(), elm_acc, load);
786  data_.potential_load.value_list(fe_values.point_list(), elm_acc, potential);
787 
788  // compute sources
789  for (unsigned int k=0; k<qsize; k++)
790  {
791  for (unsigned int i=0; i<ndofs; i++)
792  local_rhs[i] += (
793  arma::dot(load[k], vec.value(i,k))
794  -potential[k]*vec.divergence(i,k)
795  )*csection[k]*fe_values.JxW(k);
796  }
797  ls->rhs_set_values(ndofs, dof_indices.data(), local_rhs);
798 
799 // for (unsigned int i=0; i<ndofs; i++)
800 // {
801 // for (unsigned int k=0; k<qsize; k++)
802 // local_source_balance_vector[i] -= 0;//sources_sigma[k]*fe_values[vec].value(i,k)*fe_values.JxW(k);
803 //
804 // local_source_balance_rhs[i] += local_rhs[i];
805 // }
806 // balance_->add_source_matrix_values(subst_idx, elm_acc.region().bulk_idx(), dof_indices, local_source_balance_vector);
807 // balance_->add_source_vec_values(subst_idx, elm_acc.region().bulk_idx(), dof_indices, local_source_balance_rhs);
808  }
809 }
810 
811 
812 
814 {
815  double young = data_.young_modulus.value(side->centre(), side->element());
816  double poisson = data_.poisson_ratio.value(side->centre(), side->element());
817  return 1e3*(2*lame_mu(young, poisson) + lame_lambda(young, poisson)) / side->measure();
818 }
819 
820 
821 
822 template<unsigned int dim>
824 {
825  FEValues<3> fe_values_side(*feo->q<dim-1>(), *feo->fe<dim>(),
827  const unsigned int ndofs = feo->fe<dim>()->n_dofs(), qsize = feo->q<dim-1>()->size();
828  vector<int> side_dof_indices(ndofs);
829  PetscScalar local_matrix[ndofs*ndofs];
830  auto vec = fe_values_side.vector_view(0);
831 
832  // assemble boundary integral
833  for (unsigned int iedg=0; iedg<feo->dh()->n_loc_edges(); iedg++)
834  {
835  Edge edg = mesh_->edge(feo->dh()->edge_index(iedg));
836  if (edg.n_sides() > 1) continue;
837  // check spatial dimension
838  if (edg.side(0)->dim() != dim-1) continue;
839  // skip edges lying not on the boundary
840  if (! edg.side(0)->is_boundary()) continue;
841 
842  SideIter side = edg.side(0);
843  ElementAccessor<3> cell = side->element();
844  DHCellAccessor dh_cell = feo->dh()->cell_accessor_from_element(cell.idx());
845  DHCellSide dh_side(dh_cell, side->side_idx());
846  dh_cell.get_dof_indices(side_dof_indices);
847  unsigned int bc_type = data_.bc_type.value(side->centre(), side->cond().element_accessor());
848  fe_values_side.reinit(*side);
849 
850  for (unsigned int i=0; i<ndofs; i++)
851  for (unsigned int j=0; j<ndofs; j++)
852  local_matrix[i*ndofs+j] = 0;
853 
854  if (bc_type == EqData::bc_type_displacement)
855  {
856  for (unsigned int k=0; k<qsize; k++)
857  for (unsigned int i=0; i<ndofs; i++)
858  for (unsigned int j=0; j<ndofs; j++)
859  local_matrix[i*ndofs+j] += dirichlet_penalty(side)*arma::dot(vec.value(i,k),vec.value(j,k))*fe_values_side.JxW(k);
860  }
861  else if (bc_type == EqData::bc_type_displacement_normal)
862  {
863  for (unsigned int k=0; k<qsize; k++)
864  for (unsigned int i=0; i<ndofs; i++)
865  for (unsigned int j=0; j<ndofs; j++)
866  local_matrix[i*ndofs+j] += dirichlet_penalty(side)*arma::dot(vec.value(i,k),fe_values_side.normal_vector(k))*arma::dot(vec.value(j,k),fe_values_side.normal_vector(k))*fe_values_side.JxW(k);
867  }
868 
869  ls->mat_set_values(ndofs, side_dof_indices.data(), ndofs, side_dof_indices.data(), local_matrix);
870  }
871 }
872 
873 
875 {
876  arma::mat33 mt = m - m*arma::kron(n,n.t());
877  return mt;
878 }
879 
880 
881 template<unsigned int dim>
883 {
884  if (dim == 1) return;
885  FEValues<3> fe_values_sub(*feo->q<dim-1>(), *feo->fe<dim-1>(),
887  FEValues<3> fe_values_side(*feo->q<dim-1>(), *feo->fe<dim>(),
889 
890  const unsigned int ndofs_side = feo->fe<dim>()->n_dofs(); // number of local dofs
891  const unsigned int ndofs_sub = feo->fe<dim-1>()->n_dofs();
892  const unsigned int qsize = feo->q<dim-1>()->size(); // number of quadrature points
893  vector<vector<int> > side_dof_indices(2);
894  vector<unsigned int> n_dofs = { ndofs_sub, ndofs_side };
895  vector<double> frac_sigma(qsize);
896  vector<double> csection_lower(qsize), csection_higher(qsize), young(qsize), poisson(qsize), alpha(qsize);
897  PetscScalar local_matrix[2][2][(ndofs_side)*(ndofs_side)];
898  auto vec_side = fe_values_side.vector_view(0);
899  auto vec_sub = fe_values_sub.vector_view(0);
900 
901  // index 0 = element with lower dimension,
902  // index 1 = side of element with higher dimension
903  side_dof_indices[0].resize(ndofs_sub);
904  side_dof_indices[1].resize(ndofs_side);
905 
906  // assemble integral over sides
907  for (unsigned int inb=0; inb<feo->dh()->n_loc_nb(); inb++)
908  {
909  Neighbour *nb = &mesh_->vb_neighbours_[feo->dh()->nb_index(inb)];
910  // skip neighbours of different dimension
911  if (nb->element()->dim() != dim-1) continue;
912 
913  ElementAccessor<3> cell_sub = nb->element();
914  DHCellAccessor dh_cell_sub = feo->dh()->cell_accessor_from_element(cell_sub.idx());
915  dh_cell_sub.get_dof_indices(side_dof_indices[0]);
916  fe_values_sub.reinit(cell_sub);
917 
918  ElementAccessor<3> cell = nb->side()->element();
919  DHCellAccessor dh_cell = feo->dh()->cell_accessor_from_element(cell.idx());
920  DHCellSide dh_side(dh_cell, nb->side()->side_idx());
921  dh_cell.get_dof_indices(side_dof_indices[1]);
922  fe_values_side.reinit(dh_side.side());
923 
924  // Element id's for testing if they belong to local partition.
925  bool own_element_id[2];
926  own_element_id[0] = feo->dh()->cell_accessor_from_element(cell_sub.idx()).is_own();
927  own_element_id[1] = feo->dh()->cell_accessor_from_element(cell.idx()).is_own();
928 
929  data_.cross_section.value_list(fe_values_sub.point_list(), cell_sub, csection_lower);
930  data_.cross_section.value_list(fe_values_sub.point_list(), cell, csection_higher);
931  data_.fracture_sigma.value_list(fe_values_sub.point_list(), cell_sub, frac_sigma);
932  data_.young_modulus.value_list(fe_values_sub.point_list(), cell_sub, young);
933  data_.poisson_ratio.value_list(fe_values_sub.point_list(), cell_sub, poisson);
934 
935  for (unsigned int n=0; n<2; ++n)
936  for (unsigned int i=0; i<ndofs_side; i++)
937  for (unsigned int m=0; m<2; ++m)
938  for (unsigned int j=0; j<ndofs_side; j++)
939  local_matrix[n][m][i*(ndofs_side)+j] = 0;
940 
941  // set transmission conditions
942  for (unsigned int k=0; k<qsize; k++)
943  {
944  arma::vec3 nv = fe_values_side.normal_vector(k);
945  double mu = lame_mu(young[k], poisson[k]);
946  double lambda = lame_lambda(young[k], poisson[k]);
947 
948  for (int n=0; n<2; n++)
949  {
950  if (!own_element_id[n]) continue;
951 
952  for (unsigned int i=0; i<n_dofs[n]; i++)
953  {
954  arma::vec3 vi = (n==0)?arma::zeros(3):vec_side.value(i,k);
955  arma::vec3 vf = (n==1)?arma::zeros(3):vec_sub.value(i,k);
956  arma::mat33 gvft = (n==0)?vec_sub.grad(i,k):arma::zeros(3,3);
957 
958  for (int m=0; m<2; m++)
959  for (unsigned int j=0; j<n_dofs[m]; j++) {
960  arma::vec3 ui = (m==0)?arma::zeros(3):vec_side.value(j,k);
961  arma::vec3 uf = (m==1)?arma::zeros(3):vec_sub.value(j,k);
962  arma::mat33 guit = (m==1)?mat_t(vec_side.grad(j,k),nv):arma::zeros(3,3);
963  double divuit = (m==1)?arma::trace(guit):0;
964 
965  local_matrix[n][m][i*n_dofs[m] + j] +=
966  frac_sigma[k]*csection_higher[k]*(
967  arma::dot(vf-vi,
968  2*csection_higher[k]/csection_lower[k]*(mu*(uf-ui)+(mu+lambda)*(arma::dot(uf-ui,nv)*nv))
969  + mu*arma::trans(guit)*nv
970  + lambda*divuit*nv
971  )
972  - arma::dot(gvft, mu*arma::kron(nv,ui.t()) + lambda*arma::dot(ui,nv)*arma::eye(3,3))
973  )*fe_values_sub.JxW(k);
974  }
975 
976  }
977  }
978  }
979 
980  for (unsigned int n=0; n<2; ++n)
981  for (unsigned int m=0; m<2; ++m)
982  ls->mat_set_values(n_dofs[n], side_dof_indices[n].data(), n_dofs[m], side_dof_indices[m].data(), local_matrix[n][m]);
983  }
984 }
985 
986 
987 
988 template<unsigned int dim>
990 {
991  if (dim == 1) return;
992  FEValues<3> fe_values_sub(*feo->q<dim-1>(), *feo->fe<dim-1>(),
994  FEValues<3> fe_values_side(*feo->q<dim-1>(), *feo->fe<dim>(),
996 
997  const unsigned int ndofs_side = feo->fe<dim>()->n_dofs(); // number of local dofs
998  const unsigned int ndofs_sub = feo->fe<dim-1>()->n_dofs();
999  const unsigned int qsize = feo->q<dim-1>()->size(); // number of quadrature points
1000  vector<vector<int> > side_dof_indices(2);
1001  vector<unsigned int> n_dofs = { ndofs_sub, ndofs_side };
1002  vector<double> frac_sigma(qsize), potential(qsize), csection_higher(qsize);
1003  PetscScalar local_rhs[2][ndofs_side];
1004  auto vec_side = fe_values_side.vector_view(0);
1005  auto vec_sub = fe_values_sub.vector_view(0);
1006 
1007  // index 0 = element with lower dimension,
1008  // index 1 = side of element with higher dimension
1009  side_dof_indices[0].resize(ndofs_sub);
1010  side_dof_indices[1].resize(ndofs_side);
1011 
1012  // assemble integral over sides
1013  for (unsigned int inb=0; inb<feo->dh()->n_loc_nb(); inb++)
1014  {
1015  Neighbour *nb = &mesh_->vb_neighbours_[feo->dh()->nb_index(inb)];
1016  // skip neighbours of different dimension
1017  if (nb->element()->dim() != dim-1) continue;
1018 
1019  ElementAccessor<3> cell_sub = nb->element();
1020  feo->dh()->cell_accessor_from_element(cell_sub.idx()).get_dof_indices(side_dof_indices[0]);
1021  fe_values_sub.reinit(cell_sub);
1022 
1023  ElementAccessor<3> cell = nb->side()->element();
1024  feo->dh()->cell_accessor_from_element(cell.idx()).get_dof_indices(side_dof_indices[1]);
1025  fe_values_side.reinit(*nb->side());
1026 
1027  // Element id's for testing if they belong to local partition.
1028  bool own_element_id[2];
1029  own_element_id[0] = feo->dh()->cell_accessor_from_element(cell_sub.idx()).is_own();
1030  own_element_id[1] = feo->dh()->cell_accessor_from_element(cell.idx()).is_own();
1031 
1032  data_.fracture_sigma.value_list(fe_values_sub.point_list(), cell_sub, frac_sigma);
1033  data_.potential_load.value_list(fe_values_sub.point_list(), cell, potential);
1034  data_.cross_section.value_list(fe_values_sub.point_list(), cell, csection_higher);
1035 
1036  for (unsigned int n=0; n<2; ++n)
1037  for (unsigned int i=0; i<ndofs_side; i++)
1038  local_rhs[n][i] = 0;
1039 
1040  // set transmission conditions
1041  for (unsigned int k=0; k<qsize; k++)
1042  {
1043  arma::vec3 nv = fe_values_side.normal_vector(k);
1044 
1045  for (int n=0; n<2; n++)
1046  {
1047  if (!own_element_id[n]) continue;
1048 
1049  for (unsigned int i=0; i<n_dofs[n]; i++)
1050  {
1051  arma::vec3 vi = (n==0)?arma::zeros(3):vec_side.value(i,k);
1052  arma::vec3 vf = (n==1)?arma::zeros(3):vec_sub.value(i,k);
1053 
1054  local_rhs[n][i] -= frac_sigma[k]*csection_higher[k]*arma::dot(vf-vi,potential[k]*nv)*fe_values_sub.JxW(k);
1055  }
1056  }
1057  }
1058 
1059  for (unsigned int n=0; n<2; ++n)
1060  ls->rhs_set_values(n_dofs[n], side_dof_indices[n].data(), local_rhs[n]);
1061  }
1062 }
1063 
1064 
1065 
1066 
1067 
1068 template<unsigned int dim>
1070 {
1071  FEValues<3> fe_values_side(*feo->q<dim-1>(), *feo->fe<dim>(),
1073  const unsigned int ndofs = feo->fe<dim>()->n_dofs(), qsize = feo->q<dim-1>()->size();
1074  vector<int> side_dof_indices(ndofs);
1075  // unsigned int loc_b=0;
1076  double local_rhs[ndofs];
1077  vector<PetscScalar> local_flux_balance_vector(ndofs);
1078  // PetscScalar local_flux_balance_rhs;
1079  vector<arma::vec3> bc_values(qsize), bc_traction(qsize);
1080  vector<arma::mat33> bc_stress(qsize);
1081  vector<double> csection(qsize), bc_potential(qsize);
1082  auto vec = fe_values_side.vector_view(0);
1083 
1084  for (DHCellAccessor cell : feo->dh()->own_range())
1085  {
1086  ElementAccessor<3> elm = cell.elm();
1087  if (elm->boundary_idx_ == nullptr) continue;
1088 
1089  for (unsigned int si=0; si<elm->n_sides(); ++si)
1090  {
1091  Edge edg = elm.side(si)->edge();
1092  Side side = *cell.elm().side(si);
1093 
1094  if (edg.n_sides() > 1) continue;
1095  // skip edges lying not on the boundary
1096  if ( ! side.is_boundary()) continue;
1097 
1098  if (side.dim() != dim-1)
1099  {
1100  // if (edg.side(0)->cond() != nullptr) ++loc_b;
1101  continue;
1102  }
1103 
1104  ElementAccessor<3> bc_cell = side.cond().element_accessor();
1105  unsigned int bc_type = data_.bc_type.value(side.centre(), bc_cell);
1106 
1107  fe_values_side.reinit(side);
1108 
1109  data_.cross_section.value_list(fe_values_side.point_list(), elm, csection);
1110  // The b.c. data are fetched for all possible b.c. types since we allow
1111  // different bc_type for each substance.
1112  data_.bc_displacement.value_list(fe_values_side.point_list(), bc_cell, bc_values);
1113  data_.bc_traction.value_list(fe_values_side.point_list(), bc_cell, bc_traction);
1114  data_.bc_stress.value_list(fe_values_side.point_list(), bc_cell, bc_stress);
1115  data_.potential_load.value_list(fe_values_side.point_list(), elm, bc_potential);
1116 
1117  cell.get_dof_indices(side_dof_indices);
1118 
1119  fill_n(local_rhs, ndofs, 0);
1120  local_flux_balance_vector.assign(ndofs, 0);
1121  // local_flux_balance_rhs = 0;
1122 
1123  if (bc_type == EqData::bc_type_displacement)
1124  {
1125  for (unsigned int k=0; k<qsize; k++)
1126  for (unsigned int i=0; i<ndofs; i++)
1127  local_rhs[i] += dirichlet_penalty(side)*arma::dot(bc_values[k],vec.value(i,k))*fe_values_side.JxW(k);
1128  }
1129  else if (bc_type == EqData::bc_type_displacement_normal)
1130  {
1131  for (unsigned int k=0; k<qsize; k++)
1132  for (unsigned int i=0; i<ndofs; i++)
1133  local_rhs[i] += dirichlet_penalty(side)*arma::dot(bc_values[k],fe_values_side.normal_vector(k))*arma::dot(vec.value(i,k),fe_values_side.normal_vector(k))*fe_values_side.JxW(k);
1134  }
1135  else if (bc_type == EqData::bc_type_traction)
1136  {
1137  for (unsigned int k=0; k<qsize; k++)
1138  {
1139  for (unsigned int i=0; i<ndofs; i++)
1140  local_rhs[i] += csection[k]*arma::dot(vec.value(i,k),bc_traction[k] + bc_potential[k]*fe_values_side.normal_vector(k))*fe_values_side.JxW(k);
1141  }
1142  }
1143  else if (bc_type == EqData::bc_type_stress)
1144  {
1145  for (unsigned int k=0; k<qsize; k++)
1146  {
1147  for (unsigned int i=0; i<ndofs; i++)
1148  // stress is multiplied by inward normal to obtain traction
1149  local_rhs[i] += csection[k]*arma::dot(vec.value(i,k),-bc_stress[k]*fe_values_side.normal_vector(k) + bc_potential[k]*fe_values_side.normal_vector(k))*fe_values_side.JxW(k);
1150  }
1151  }
1152  ls->rhs_set_values(ndofs, side_dof_indices.data(), local_rhs);
1153 
1154 
1155 
1156 // balance_->add_flux_matrix_values(subst_idx, loc_b, side_dof_indices, local_flux_balance_vector);
1157 // balance_->add_flux_vec_value(subst_idx, loc_b, local_flux_balance_rhs);
1158  // ++loc_b;
1159  }
1160  }
1161 }
1162 
1163 
1164 
1165 
TimeGovernor & time()
Definition: equation.hh:149
BCField< 3, FieldValue< 3 >::Enum > bc_type
Definition: elasticity.hh:112
std::shared_ptr< DiscreteSpace > ds_
Definition: elasticity.hh:72
BCField< 3, FieldValue< 3 >::VectorFixed > bc_displacement
Definition: elasticity.hh:113
Field< 3, FieldValue< 3 >::TensorFixed > output_stress
Definition: elasticity.hh:128
Shape function values.
Definition: update_flags.hh:87
unsigned int n_sides() const
Returns number of sides aligned with the edge.
Definition: accessors.hh:300
Field< 3, FieldValue< 3 >::Scalar > young_modulus
Definition: elasticity.hh:117
FieldSet * eq_data_
Definition: equation.hh:227
static const Input::Type::Record & get_input_type()
Main balance input record type.
Definition: balance.cc:50
static auto subdomain(Mesh &mesh) -> IndexField
static constexpr const char * name()
Definition: elasticity.hh:103
std::shared_ptr< FieldFE< 3, FieldValue< 3 >::Scalar > > output_von_mises_stress_ptr
Definition: elasticity.hh:135
Field< 3, FieldValue< 3 >::Scalar > output_von_mises_stress
Definition: elasticity.hh:129
Transformed quadrature weight for cell sides.
RegionSet get_region_set(const std::string &set_name) const
Definition: region.cc:328
const FEValuesViews::Vector< spacedim > & vector_view(unsigned int i) const
Accessor to vector values of multicomponent FE.
Definition: fe_values.hh:254
Accessor to input data conforming to declared Array.
Definition: accessors.hh:566
arma::Col< IntIdx > LocDofVec
Definition: index_types.hh:28
ArmaVec< double, N > vec
Definition: armor.hh:861
unsigned int * boundary_idx_
Definition: elements.h:80
void assemble_matrix_element_side()
Assembles the fluxes between elements of different dimensions depending on displacement.
Definition: elasticity.cc:882
unsigned int size() const
Returns number of keys in the Record.
Definition: type_record.hh:602
static constexpr Mask in_main_matrix
A field is part of main "stiffness matrix" of the equation.
Definition: field_flag.hh:49
Solver based on the original PETSc solver using MPIAIJ matrix and succesive Schur complement construc...
void preallocate()
Definition: elasticity.cc:443
void inc()
Iterates to next local element.
Field< 3, FieldValue< 3 >::Scalar > region_id
Definition: elasticity.hh:124
unsigned int side_idx() const
Returns local index of the side on the element.
Definition: accessors.hh:415
Field< 3, FieldValue< 3 >::Scalar > output_cross_section
Definition: elasticity.hh:130
static const Input::Type::Record & get_input_type()
The specification of output stream.
Definition: output_time.cc:37
unsigned int get_dof_indices(std::vector< LongIdx > &indices) const
Fill vector of the global indices of dofs associated to the cell.
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:61
Edge edge() const
Returns pointer to the edge connected to the side.
void set_from_input(const Input::Record in_rec) override
#define MessageOut()
Macro defining &#39;message&#39; record of log.
Definition: logger.hh:255
virtual void start_add_assembly()
Definition: linsys.hh:341
void output(TimeStep step)
virtual PetscErrorCode mat_zero_entries()
Definition: linsys.hh:264
virtual void rhs_set_values(int nrow, int *rows, double *vals)=0
void next_time()
Proceed to the next time according to current estimated time step.
static const Input::Type::Record & get_input_type()
Declare input record type for the equation TransportDG.
Definition: elasticity.cc:43
void assemble_rhs()
Assembles the right hand side (forces, boundary conditions, tractions).
Definition: elasticity.cc:737
arma::vec3 centre() const
Centre of side.
Definition: accessors.cc:116
static Default obligatory()
The factory function to make an empty default value which is obligatory.
Definition: type_record.hh:110
static std::shared_ptr< OutputTime > create_output_stream(const std::string &equation_name, const Input::Record &in_rec, std::string unit_str)
This method delete all object instances of class OutputTime stored in output_streams vector...
Definition: output_time.cc:184
LinSys * ls
Linear algebra system for the transport equation.
Definition: elasticity.hh:302
Definition: mesh.h:78
Fields computed from the mesh data.
virtual void start_allocation()
Definition: linsys.hh:333
std::shared_ptr< FieldFE< 3, FieldValue< 3 >::TensorFixed > > output_stress_ptr
Definition: elasticity.hh:134
Cell accessor allow iterate over DOF handler cells.
Class FEValues calculates finite element data on the actual cells such as shape function values...
virtual void finish_assembly()=0
Field< 3, FieldValue< 3 >::Scalar > cross_section
Pointer to DarcyFlow field cross_section.
Definition: elasticity.hh:122
Class FESystem for compound finite elements.
LocDofVec get_loc_dof_indices() const
Returns the local indices of dofs associated to the cell on the local process.
~Elasticity()
Destructor.
Definition: elasticity.cc:366
SideIter side(const unsigned int loc_index)
double lame_mu(double young, double poisson)
Definition: elasticity.cc:128
const RegionDB & region_db() const
Definition: mesh.h:143
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:347
const Armor::array & point_list() const
Return coordinates of all quadrature points in the actual cell system.
Definition: fe_values.hh:223
const TimeStep & step(int index=-1) const
void update_solution() override
Computes the solution in one time instant.
Definition: elasticity.cc:459
std::shared_ptr< DOFHandlerMultiDim > dh()
Definition: elasticity.cc:119
arma::mat33 mat_t(const arma::mat33 &m, const arma::vec3 &n)
Definition: elasticity.cc:874
Basic time management functionality for unsteady (and steady) solvers (class Equation).
void assemble_rhs_element_side()
Assemble fluxes between different dimensions that are independent of displacement.
Definition: elasticity.cc:989
ElementAccessor< 3 > element() const
Returns iterator to the element of the side.
void reinit(const ElementAccessor< spacedim > &cell)
Update cell-dependent data (gradients, Jacobians etc.)
Definition: fe_values.cc:548
void compute_output_fields()
Definition: elasticity.cc:551
Input::Record input_rec
Record with input specification.
Definition: elasticity.hh:313
Field< 3, FieldValue< 3 >::Scalar > potential_load
Potential of an additional (external) load.
Definition: elasticity.hh:123
Class for declaration of inputs sequences.
Definition: type_base.hh:339
Vec rhs
Vector of right hand side.
Definition: elasticity.hh:296
void view(const char *name="") const
Symmetric Gauss-Legendre quadrature formulae on simplices.
static Input::Type::Record & record_template()
Template Record with common keys for derived equations.
Definition: equation.cc:35
FEM for linear elasticity.
bool allocation_done
Indicates whether matrices have been preallocated.
Definition: elasticity.hh:325
unsigned int dim() const
Definition: elements.h:121
ElementAccessor< 3 > element()
Definition: neighbours.h:161
Transformed quadrature points.
unsigned int dim() const
Returns dimension of the side, that is dimension of the element minus one.
BCField< 3, FieldValue< 3 >::VectorFixed > bc_traction
Definition: elasticity.hh:114
bool is_boundary() const
Returns true for side on the boundary.
void solve_linear_system()
Solve without updating time step and without output.
Definition: elasticity.cc:482
void assemble_sources()
Assembles the right hand side vector due to volume sources.
Definition: elasticity.cc:758
Definitions of basic Lagrangean finite elements with polynomial shape functions.
static constexpr Mask equation_external_output
Match an output field, that can be also copy of other field.
Definition: field_flag.hh:58
SideIter side()
Definition: neighbours.h:145
void update_output_fields()
Definition: elasticity.cc:379
Accessor to the data with type Type::Record.
Definition: accessors.hh:291
const Ret val(const string &key) const
unsigned int n_sides() const
Definition: elements.h:132
MixedPtr< FiniteElement > fe_
Finite elements for the solution of the mechanics equation.
Definition: elasticity.hh:68
static auto region_id(Mesh &mesh) -> IndexField
#define xprintf(...)
Definition: system.hh:93
#define START_TIMER(tag)
Starts a timer with specified tag.
int converged_reason
Definition: linsys.hh:109
Mesh * mesh_
Definition: equation.hh:218
Selection & add_value(const int value, const std::string &key, const std::string &description="", TypeBase::attribute_map attributes=TypeBase::attribute_map())
Adds one new value with name given by key to the Selection.
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm) const
Definition: field.hh:434
Field< 3, FieldValue< 3 >::Scalar > output_divergence
Definition: elasticity.hh:131
Record & declare_key(const string &key, std::shared_ptr< TypeBase > type, const Default &default_value, const string &description, TypeBase::attribute_map key_attributes=TypeBase::attribute_map())
Declares a new key of the Record.
Definition: type_record.cc:503
void zero_time_step() override
Initialize solution in the zero time.
Definition: elasticity.cc:407
static constexpr Mask in_rhs
A field is part of the right hand side of the equation.
Definition: field_flag.hh:51
Shape function gradients.
Definition: update_flags.hh:95
void output_data()
Postprocesses the solution and writes to output file.
Definition: elasticity.cc:530
Mat stiffness_matrix
The stiffness matrix.
Definition: elasticity.hh:299
std::shared_ptr< FiniteElement< dim > > fe()
Quadrature * q()
Definition: elasticity.hh:58
virtual void value_list(const Armor::array &point_list, const ElementAccessor< spacedim > &elm, std::vector< typename Value::return_type > &value_list) const
Definition: field.hh:448
double measure() const
Calculate metrics of the side.
Definition: accessors.cc:27
virtual const Vec * get_rhs()
Definition: linsys.hh:203
Normal vectors.
virtual PetscErrorCode rhs_zero_entries()
Definition: linsys.hh:273
Field< 3, FieldValue< 3 >::VectorFixed > load
Definition: elasticity.hh:116
void set_solution(Vec sol_vec)
Definition: linsys.hh:290
Field< 3, FieldValue< 3 >::Scalar > fracture_sigma
Transition parameter for diffusive transfer on fractures.
Definition: elasticity.hh:119
void assemble_fluxes_boundary()
Assembles the fluxes on the boundary.
Definition: elasticity.cc:823
Record & copy_keys(const Record &other)
Copy keys from other record.
Definition: type_record.cc:216
void mark_input_times(const TimeGovernor &tg)
Definition: field_set.hh:221
vector< Neighbour > vb_neighbours_
Definition: mesh.h:267
void assemble_boundary_conditions()
Assembles the r.h.s. components corresponding to the Dirichlet boundary conditions for a given space ...
Definition: elasticity.cc:1069
void set_input_list(Input::Array input_list, const TimeGovernor &tg)
Definition: field_set.hh:193
Field< 3, FieldValue< 3 >::Scalar > poisson_ratio
Definition: elasticity.hh:118
void initialize(std::shared_ptr< OutputTime > stream, Mesh *mesh, Input::Record in_rec, const TimeGovernor &tg)
const Selection & close() const
Close the Selection, no more values can be added.
std::shared_ptr< DOFHandlerMultiDim > dh_tensor_
Definition: elasticity.hh:77
void set_components(const std::vector< string > &names)
Definition: field_set.hh:180
BCField< 3, FieldValue< 3 >::TensorFixed > bc_stress
Definition: elasticity.hh:115
EquationOutput output_fields
Definition: elasticity.hh:139
Definition: system.hh:65
static const int registrar
Registrar of class to factory.
Definition: elasticity.hh:210
void set_field(const RegionSet &domain, FieldBasePtr field, double time=0.0)
Definition: field.impl.hh:227
void next_time()
Pass to next time and update equation data.
Definition: elasticity.cc:473
bool set_time(const TimeStep &time, LimitSide limit_side)
Definition: field_set.cc:157
void initialize() override
Definition: elasticity.cc:308
EqData data_
Field data for model parameters.
Definition: elasticity.hh:277
double lame_lambda(double young, double poisson)
Definition: elasticity.cc:134
static const Input::Type::Selection & get_bc_type_selection()
Definition: elasticity.cc:144
MixedPtr< FESystem > mixed_fe_system(MixedPtr< FiniteElement > fe, Args &&...args)
Definition: fe_system.hh:171
Definitions of particular quadrature rules on simplices.
#define WarningOut()
Macro defining &#39;warning&#39; record of log.
Definition: logger.hh:258
virtual SolveInfo solve()=0
#define END_TIMER(tag)
Ends a timer with specified tag.
static string default_output_field()
Definition: elasticity.hh:105
std::shared_ptr< FieldFE< 3, FieldValue< 3 >::VectorFixed > > output_field_ptr
Definition: elasticity.hh:133
static const Input::Type::Record & get_input_type()
Definition: linsys_PETSC.cc:32
Edge edge(uint edge_idx) const
Definition: mesh.cc:254
std::shared_ptr< DOFHandlerMultiDim > dh_
Object for distribution of dofs.
Definition: elasticity.hh:75
void set_mesh(const Mesh &mesh)
Definition: field_set.hh:186
void assemble_stiffness_matrix()
Assembles the stiffness matrix.
Definition: elasticity.cc:663
std::shared_ptr< DOFHandlerMultiDim > dh_scalar()
Definition: elasticity.cc:120
Record type proxy class.
Definition: type_record.hh:182
virtual void mat_set_values(int nrow, int *rows, int ncol, int *cols, double *vals)=0
double JxW(const unsigned int point_no)
Return the product of Jacobian determinant and the quadrature weight at given quadrature point...
Definition: fe_values.hh:200
Class for representation SI units of Fields.
Definition: unit_si.hh:40
std::shared_ptr< FieldFE< 3, FieldValue< 3 >::Scalar > > output_div_ptr
Definition: elasticity.hh:137
Boundary cond() const
std::shared_ptr< DOFHandlerMultiDim > dh_tensor()
Definition: elasticity.cc:121
void assemble_volume_integrals()
Assembles the volume integrals into the stiffness matrix.
Definition: elasticity.cc:689
virtual const Mat * get_matrix()
Definition: linsys.hh:187
void calculate_cumulative_balance()
Definition: elasticity.cc:648
Elasticity(Mesh &init_mesh, const Input::Record in_rec, TimeGovernor *tm=nullptr)
Constructor.
Definition: elasticity.cc:272
std::shared_ptr< FieldFE< 3, FieldValue< 3 >::Scalar > > output_cross_section_ptr
Definition: elasticity.hh:136
arma::vec::fixed< spacedim > point(const unsigned int point_no)
Return coordinates of the quadrature point in the actual cell system.
Definition: fe_values.hh:213
static UnitSI & dimensionless()
Returns dimensionless unit.
Definition: unit_si.cc:55
#define DebugOut()
Macro defining &#39;debug&#39; record of log.
Definition: logger.hh:264
static bool print_message_table(ostream &stream, std::string equation_name)
Definition: field_common.cc:96
unsigned int idx() const
Return local idx of element in boundary / bulk part of element vector.
Definition: accessors.hh:181
virtual double compute_residual()=0
Field< 3, FieldValue< 3 >::VectorFixed > output_field
Definition: elasticity.hh:127
std::shared_ptr< DOFHandlerMultiDim > dh_scalar_
Definition: elasticity.hh:76
SideIter side(const unsigned int i) const
Gets side iterator of the i -th side.
bool changed() const
Definition: field_set.cc:165
Template for classes storing finite set of named values.
Field< 3, FieldValue< 3 >::Scalar > subdomain
Definition: elasticity.hh:125
Definitions of Raviart-Thomas finite elements.
Side accessor allows to iterate over sides of DOF handler cell.
FieldCommon & output_type(OutputTime::DiscreteSpace rt)
ElementAccessor< 3 > element_accessor()
std::shared_ptr< OutputTime > output_stream_
Definition: elasticity.hh:310
TimeGovernor * time_
Definition: equation.hh:219
Mechanics::FEObjects * feo
Finite element objects.
Definition: elasticity.hh:286
double dirichlet_penalty(SideIter side)
Penalty to enforce boundary value in weak sense.
Definition: elasticity.cc:813
Transformed quadrature weights.
arma::vec::fixed< spacedim > normal_vector(unsigned int point_no)
Returns the normal vector to a side at given quadrature point.
Definition: fe_values.hh:234