47 std::string(equation_name),
48 "FEM for linear elasticity.")
50 "Time governor setting for the secondary equation.")
52 "Settings for computing balance.")
54 "Parameters of output stream.")
56 "Linear solver for elasticity.")
59 .make_field_descriptor_type(equation_name)),
61 "Input fields of the equation.")
63 EqData().output_fields.make_output_type(equation_name,
""),
65 "Setting of the field output.")
93 xprintf(
PrgErr,
"Unsupported polynomial order %d for finite elements in Elasticity", fe_order);
106 ds_ = std::make_shared<EqualOrderDiscreteSpace>(mesh_, fe0_, fe1_, fe2_, fe3_);
107 dh_ = std::make_shared<DOFHandlerMultiDim>(*mesh_);
109 dh_->distribute_dofs(ds_);
154 return Selection(
"Elasticity_BC_Type",
"Types of boundary conditions for heat transfer model.")
155 .
add_value(bc_type_displacement,
"displacement",
156 "Prescribed displacement.")
158 "Prescribed traction.")
168 "Type of boundary condition.")
170 .input_default(
"\"traction\"")
171 .input_selection( get_bc_type_selection() )
174 *
this+=bc_displacement
175 .name(
"bc_displacement")
176 .description(
"Prescribed displacement.")
178 .input_default(
"0.0")
183 .description(
"Prescribed traction.")
185 .input_default(
"0.0")
190 .description(
"Prescribed load.")
191 .units(
UnitSI().N().m(-3) )
192 .input_default(
"0.0")
196 .name(
"young_modulus")
197 .description(
"Young modulus.")
199 .input_default(
"0.0")
200 .flags_add(in_main_matrix);
203 .name(
"poisson_ratio")
204 .description(
"Poisson ratio.")
205 .units(
UnitSI().dimensionless() )
206 .input_default(
"0.0")
207 .flags_add(in_main_matrix);
209 *
this+=fracture_sigma
210 .name(
"fracture_sigma")
212 "Coefficient of diffusive transfer through fractures (for each substance).")
214 .input_default(
"1.0")
215 .flags_add(FieldFlag::in_main_matrix);
217 *
this += region_id.name(
"region_id")
221 *
this += subdomain.name(
"subdomain")
226 .name(
"cross_section")
227 .units(
UnitSI().m(3).md() )
228 .flags(input_copy & in_time_term & in_main_matrix);
231 .name(
"displacement")
233 .flags(equation_result);
237 output_fields += *
this;
244 allocation_done(false)
261 DebugOut().fmt(
"Mechanics: solution size {}\n",
feo->
dh()->n_global_dofs());
293 std::string petsc_default_opts;
294 petsc_default_opts =
"-ksp_type cg -pc_type hypre -pc_hypre_type boomeramg";
323 VecScatter output_scatter;
324 VecScatterCreateToZero(
ls->
get_solution(), &output_scatter, PETSC_NULL);
328 VecScatterDestroy(&(output_scatter));
339 std::stringstream ss;
356 MatSetOption(*
ls->
get_matrix(), MAT_KEEP_NONZERO_PATTERN, PETSC_TRUE);
486 assemble_volume_integrals<1>();
487 assemble_volume_integrals<2>();
488 assemble_volume_integrals<3>();
492 assemble_fluxes_boundary<1>();
493 assemble_fluxes_boundary<2>();
494 assemble_fluxes_boundary<3>();
498 assemble_fluxes_element_side<1>();
499 assemble_fluxes_element_side<2>();
500 assemble_fluxes_element_side<3>();
508 return young*0.5/(poisson+1.);
514 return young*poisson/((poisson+1.)*(1.-2.*poisson));
518 template<
unsigned int dim>
523 const unsigned int ndofs =
feo->
fe<dim>()->n_dofs(), qsize =
feo->
q<dim>()->size();
527 PetscScalar local_matrix[ndofs*ndofs];
531 for (
auto cell :
feo->
dh()->own_range())
533 if (cell.dim() != dim)
continue;
536 fe_values.
reinit(elm_acc);
537 cell.get_dof_indices(dof_indices);
544 for (
unsigned int i=0; i<ndofs; i++)
545 for (
unsigned int j=0; j<ndofs; j++)
546 local_matrix[i*ndofs+j] = 0;
548 for (
unsigned int k=0; k<qsize; k++)
550 double mu =
lame_mu(young[k], poisson[k]);
552 for (
unsigned int i=0; i<ndofs; i++)
554 for (
unsigned int j=0; j<ndofs; j++)
555 local_matrix[i*ndofs+j] += csection[k]*(
556 2*mu*arma::dot(vec.sym_grad(j,k), vec.sym_grad(i,k))
557 + lambda*vec.divergence(j,k)*vec.divergence(i,k)
579 template<
unsigned int dim>
584 const unsigned int ndofs =
feo->
fe<dim>()->n_dofs(), qsize =
feo->
q<dim>()->size();
588 PetscScalar local_rhs[ndofs];
593 for (
auto cell :
feo->
dh()->own_range())
595 if (cell.dim() != dim)
continue;
598 fe_values.
reinit(elm_acc);
599 cell.get_dof_indices(dof_indices);
602 fill_n(local_rhs, ndofs, 0);
603 local_source_balance_vector.assign(ndofs, 0);
604 local_source_balance_rhs.assign(ndofs, 0);
610 for (
unsigned int k=0; k<qsize; k++)
612 for (
unsigned int i=0; i<ndofs; i++)
613 local_rhs[i] += arma::dot(load[k], vec.value(i,k))*csection[k]*fe_values.
JxW(k);
635 template<
unsigned int dim>
640 const unsigned int ndofs =
feo->
fe<dim>()->n_dofs();
642 PetscScalar local_matrix[ndofs*ndofs];
645 for (
unsigned int iedg=0; iedg<
feo->
dh()->n_loc_edges(); iedg++)
648 if (edg->
n_sides > 1)
continue;
650 if (edg->
side(0)->
dim() != dim-1)
continue;
652 if (edg->
side(0)->
cond() == NULL)
continue;
656 feo->
dh()->cell_accessor_from_element(cell.
idx()).get_dof_indices(side_dof_indices);
676 template<
unsigned int dim>
679 if (dim == 1)
return;
686 const unsigned int ndofs_side =
feo->
fe<dim>()->n_dofs();
687 const unsigned int ndofs_sub =
feo->
fe<dim-1>()->n_dofs();
688 const unsigned int qsize =
feo->
q<dim-1>()->size();
692 vector<double> csection_lower(qsize), csection_higher(qsize), young(qsize), poisson(qsize), alpha(qsize);
693 PetscScalar local_matrix[2][2][(ndofs_side)*(ndofs_side)];
694 PetscScalar local_rhs[2][ndofs_side];
700 side_dof_indices[0].resize(ndofs_sub);
701 side_dof_indices[1].resize(ndofs_side);
702 fv_sb[0] = &fe_values_sub;
703 fv_sb[1] = &fe_values_side;
706 for (
unsigned int inb=0; inb<
feo->
dh()->n_loc_nb(); inb++)
713 feo->
dh()->cell_accessor_from_element(cell_sub.
idx()).get_dof_indices(side_dof_indices[0]);
714 fe_values_sub.
reinit(cell_sub);
717 feo->
dh()->cell_accessor_from_element(cell.
idx()).get_dof_indices(side_dof_indices[1]);
721 bool own_element_id[2];
722 own_element_id[0] =
feo->
dh()->cell_accessor_from_element(cell_sub.
idx()).is_own();
723 own_element_id[1] =
feo->
dh()->cell_accessor_from_element(cell.
idx()).is_own();
731 for (
unsigned int n=0; n<2; ++n)
733 for (
unsigned int i=0; i<ndofs_side; i++)
735 for (
unsigned int m=0; m<2; ++m)
737 for (
unsigned int j=0; j<ndofs_side; j++)
738 local_matrix[n][m][i*(ndofs_side)+j] = 0;
745 for (
unsigned int k=0; k<qsize; k++)
748 double mu =
lame_mu(young[k], poisson[k]);
751 for (
int n=0; n<2; n++)
753 if (!own_element_id[n])
continue;
755 for (
unsigned int i=0; i<n_dofs[n]; i++)
757 arma::vec3 vi = (n==0)?arma::zeros(3):vec_side.value(i,k);
758 arma::vec3 vf = (n==1)?arma::zeros(3):vec_sub.value(i,k);
759 arma::mat33 gvft = (n==0)?vec_sub.grad(i,k):arma::zeros(3,3);
761 for (
int m=0; m<2; m++)
762 for (
unsigned int j=0; j<n_dofs[m]; j++) {
763 arma::vec3 ui = (m==0)?arma::zeros(3):vec_side.value(j,k);
764 arma::vec3 uf = (m==1)?arma::zeros(3):vec_sub.value(j,k);
766 double divuit = (m==1)?arma::trace(guit):0;
768 local_matrix[n][m][i*n_dofs[m] + j] +=
770 frac_sigma[k]*arma::dot(vf-vi,
771 2/csection_lower[k]*(mu*(uf-ui)+(mu+lambda)*(arma::dot(uf-ui,nv)*nv))
772 + mu*arma::trans(guit)*nv
775 - arma::dot(gvft, mu*arma::kron(nv,ui.t()) + lambda*arma::dot(ui,nv)*arma::eye(3,3))
782 for (
unsigned int n=0; n<2; ++n)
784 for (
unsigned int m=0; m<2; ++m)
785 ls->
mat_set_values(n_dofs[n], side_dof_indices[n].
data(), n_dofs[m], side_dof_indices[m].
data(), local_matrix[n][m]);
802 set_boundary_conditions<1>();
803 set_boundary_conditions<2>();
804 set_boundary_conditions<3>();
811 template<
unsigned int dim>
816 const unsigned int ndofs =
feo->
fe<dim>()->n_dofs(), qsize =
feo->
q<dim-1>()->size();
818 unsigned int loc_b=0;
819 double local_rhs[ndofs];
821 PetscScalar local_flux_balance_rhs;
826 for (
auto cell :
feo->
dh()->own_range())
831 for (
unsigned int si=0; si<elm->
n_sides(); ++si)
834 if (edg->
n_sides > 1)
continue;
836 if (edg->
side(0)->
cond() == NULL)
continue;
838 if (edg->
side(0)->
dim() != dim-1)
840 if (edg->
side(0)->
cond() !=
nullptr) ++loc_b;
858 feo->
dh()->cell_accessor_from_element(cell.
idx()).get_dof_indices(side_dof_indices);
860 fill_n(local_rhs, ndofs, 0);
861 local_flux_balance_vector.assign(ndofs, 0);
862 local_flux_balance_rhs = 0;
869 arma::mat d_mat(ndofs,ndofs);
870 arma::vec d_vec(ndofs);
871 for (
unsigned int i=0; i<ndofs; i++)
874 for (
unsigned int k=0; k<qsize; k++)
875 d_vec(i) += arma::dot(vec.value(i,k),bc_values[k])*fe_values_side.
JxW(k);
876 for (
unsigned int j=i; j<ndofs; j++)
879 for (
unsigned int k=0; k<qsize; k++)
880 d_mat(i,j) += arma::dot(vec.value(i,k),vec.value(j,k))*fe_values_side.
JxW(k);
881 d_mat(j,i) = d_mat(i,j);
884 arma::vec d_val = pinv(d_mat)*d_vec;
886 for (
unsigned int i=0; i<ndofs; i++)
887 if (norm(d_mat.row(i)) > 0)
892 for (
unsigned int k=0; k<qsize; k++)
894 for (
unsigned int i=0; i<ndofs; i++)
895 local_rhs[i] += csection[k]*arma::dot(vec.value(i,k),bc_traction[k])*fe_values_side.
JxW(k);
BCField< 3, FieldValue< 3 >::Enum > bc_type
void output_type(OutputTime::DiscreteSpace rt)
const Edge * edge() const
BCField< 3, FieldValue< 3 >::VectorFixed > bc_displacement
Class MappingP1 implements the affine transformation of the unit cell onto the actual cell...
Field< 3, FieldValue< 3 >::Scalar > young_modulus
static const Input::Type::Record & get_input_type()
Main balance input record type.
static auto subdomain(Mesh &mesh) -> IndexField
static constexpr const char * name()
Transformed quadrature weight for cell sides.
RegionSet get_region_set(const std::string &set_name) const
unsigned int * boundary_idx_
static constexpr Mask in_main_matrix
A field is part of main "stiffness matrix" of the equation.
void reinit(ElementAccessor< 3 > &cell, unsigned int sid)
Update cell-dependent data (gradients, Jacobians etc.)
Solver based on the original PETSc solver using MPIAIJ matrix and succesive Schur complement construc...
Field< 3, FieldValue< 3 >::Scalar > region_id
unsigned int side_idx() const
static const Input::Type::Record & get_input_type()
The specification of output stream.
void set_from_input(const Input::Record in_rec) override
virtual void start_add_assembly()
void output(TimeStep step)
virtual PetscErrorCode mat_zero_entries()
VectorMPI output_vec
Vector of solution data.
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.
arma::vec3 centre() const
Centre of side.
FiniteElement< dim > * fe()
void set_boundary_conditions()
Assembles the r.h.s. components corresponding to the Dirichlet boundary conditions.
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...
LinSys * ls
Linear algebra system for the transport equation.
Fields computed from the mesh data.
virtual void start_allocation()
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.
Class FESystem for compound finite elements.
SideIter side(const unsigned int loc_index)
double lame_mu(double young, double poisson)
const RegionDB & region_db() const
std::shared_ptr< DOFHandlerMultiDim > dh()
const TimeStep & step(int index=-1) const
void add_constraint(int row, double value)
Elasticity(Mesh &init_mesh, const Input::Record in_rec)
Constructor.
void update_solution() override
Computes the solution in one time instant.
arma::mat33 mat_t(const arma::mat33 &m, const arma::vec3 &n)
Basic time management functionality for unsteady (and steady) solvers (class Equation).
ElementAccessor< 3 > element() const
virtual void value_list(const std::vector< Point > &point_list, const ElementAccessor< spacedim > &elm, std::vector< typename Value::return_type > &value_list) const
bool flux_changed
Indicator of change in advection vector field.
Input::Record input_rec
Record with input specification.
virtual void apply_constrains(double scalar)=0
Vec rhs
Vector of right hand side.
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.
ElementAccessor< 3 > element()
Transformed quadrature points.
BCField< 3, FieldValue< 3 >::VectorFixed > bc_traction
Compound finite element on dim dimensional simplex.
const Vec & get_solution()
double JxW(const unsigned int point_no) override
Return the product of Jacobian determinant and the quadrature weight at given quadrature point...
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.
unsigned int n_sides() const
static auto region_id(Mesh &mesh) -> IndexField
#define START_TIMER(tag)
Starts a timer with specified tag.
std::shared_ptr< DOFHandlerMultiDim > dh()
void set_sources()
Assembles the right hand side due to volume sources.
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm) const
void zero_time_step() override
Initialize solution in the zero time.
Vec & petsc_vec()
Getter for PETSC vector of output data (e.g. can be used by scatters).
static constexpr Mask in_rhs
A field is part of the right hand side of the equation.
Shape function gradients.
void output_data()
Postprocesses the solution and writes to output file.
Mat stiffness_matrix
The stiffness matrix.
const FEValuesViews::Vector< dim, spacedim > & vector_view(unsigned int i) const
Accessor to vector values of multicomponent FE.
virtual const Vec * get_rhs()
arma::vec::fixed< spacedim > normal_vector(unsigned int point_no) override
Returns the normal vector to a side at given quadrature point.
virtual PetscErrorCode rhs_zero_entries()
Field< 3, FieldValue< 3 >::VectorFixed > load
void set_solution(Vec sol_vec)
Field< 3, FieldValue< 3 >::Scalar > fracture_sigma
Transition parameter for diffusive transfer on fractures.
void assemble_fluxes_boundary()
Assembles the fluxes on the boundary.
void mark_input_times(const TimeGovernor &tg)
vector< Neighbour > vb_neighbours_
void set_input_list(Input::Array input_list, const TimeGovernor &tg)
Field< 3, FieldValue< 3 >::Scalar > poisson_ratio
void initialize(std::shared_ptr< OutputTime > stream, Mesh *mesh, Input::Record in_rec, const TimeGovernor &tg)
void set_components(const std::vector< string > &names)
void assemble_fluxes_element_side()
Assembles the fluxes between elements of different dimensions.
EquationOutput output_fields
static const int registrar
Registrar of class to factory.
void set_field(const RegionSet &domain, FieldBasePtr field, double time=0.0)
bool set_time(const TimeStep &time, LimitSide limit_side)
std::vector< Edge > edges
Vector of MH edges, this should not be part of the geometrical mesh.
void initialize() override
EqData data_
Field data for model parameters.
double lame_lambda(double young, double poisson)
static const Input::Type::Selection & get_bc_type_selection()
static const Input::Type::Record & get_input_type()
Definitions of particular quadrature rules on simplices.
#define WarningOut()
Macro defining 'warning' record of log.
virtual SolveInfo solve()=0
#define END_TIMER(tag)
Ends a timer with specified tag.
static string default_output_field()
vector< arma::vec::fixed< spacedim > > & point_list()
Return coordinates of all quadrature points in the actual cell system.
static const Input::Type::Record & get_input_type()
void set_mesh(const Mesh &mesh)
void assemble_stiffness_matrix()
Assembles the stiffness matrix.
virtual void mat_set_values(int nrow, int *rows, int ncol, int *cols, double *vals)=0
Class for representation SI units of Fields.
void assemble_volume_integrals()
Assembles the volume integrals into the stiffness matrix.
virtual const Mat * get_matrix()
void calculate_cumulative_balance()
MappingP1< dim, 3 > * mapping()
static UnitSI & dimensionless()
Returns dimensionless unit.
#define DebugOut()
Macro defining 'debug' record of log.
static bool print_message_table(ostream &stream, std::string equation_name)
unsigned int idx() const
Return local idx of element in boundary / bulk part of element vector.
Field< 3, FieldValue< 3 >::VectorFixed > output_field
SideIter side(const unsigned int i) const
void output_vector_gather()
Field< 3, FieldValue< 3 >::Scalar > subdomain
Definitions of Raviart-Thomas finite elements.
ElementAccessor< 3 > element_accessor()
std::shared_ptr< OutputTime > output_stream_
FEObjects(Mesh *mesh_, unsigned int fe_order)
Mechanics::FEObjects * feo
Finite element objects.
void reinit(ElementAccessor< 3 > &cell)
Update cell-dependent data (gradients, Jacobians etc.)
Transformed quadrature weights.
Calculates finite element data on a side.