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