pi-DoMUS: Parallel Deal.II MUltiphysics Solver
neo_hookean_two_fields.h
Go to the documentation of this file.
1 
5 #ifndef _neo_hookean_two_fields_interface_h_
6 #define _neo_hookean_two_fields_interface_h_
7 
8 #include "pde_system_interface.h"
9 #include <deal2lkit/parsed_function.h>
10 
11 
12 #include <deal.II/fe/fe_values.h>
17 
21 
22 #include <deal.II/lac/solver_cg.h>
24 
25 
26 template <int dim, int spacedim, typename LAC>
27 class NeoHookeanTwoFieldsInterface : public PDESystemInterface<dim,spacedim, NeoHookeanTwoFieldsInterface<dim,spacedim,LAC>, LAC>
28 {
29 public:
30 
31  /* specific and useful functions for this very problem */
33 
34  virtual void declare_parameters (ParameterHandler &prm);
35 
36  void set_matrix_couplings(std::vector<std::string> &couplings) const;
37 
38 
39  template <typename EnergyType, typename ResidualType>
41  FEValuesCache<dim,spacedim> &scratch,
42  std::vector<EnergyType> &energies,
43  std::vector<std::vector<ResidualType> > &local_residuals,
44  bool compute_only_system_terms) const;
45 
46 
48  const std::vector<shared_ptr<LATrilinos::BlockMatrix> >,
51 
52 
53 private:
54  double mu;
55 
56  mutable shared_ptr<TrilinosWrappers::PreconditionAMG> Amg_preconditioner;
57  mutable shared_ptr<TrilinosWrappers::PreconditionJacobi> P_preconditioner;
58 
59 };
60 
61 template <int dim, int spacedim, typename LAC>
63  PDESystemInterface<dim,spacedim,NeoHookeanTwoFieldsInterface<dim,spacedim,LAC>, LAC >("NeoHookean Parameters",
64  dim+1,2,
65  "FESystem[FE_Q(2)^d-FE_Q(1)]",
66  "u,u,u,p",
67  "1,0")
68 {}
69 
70 
71 template <int dim, int spacedim,typename LAC>
72 template<typename EnergyType,typename ResidualType>
74  FEValuesCache<dim,spacedim> &fe_cache,
75  std::vector<EnergyType> &energies,
76  std::vector<std::vector<ResidualType> > &,
77  bool compute_only_system_terms) const
78 {
79  EnergyType alpha = this->alpha;
80  this->reinit(alpha, cell, fe_cache);
81 
82  const FEValuesExtractors::Vector displacement(0);
83 
84  auto &grad_us = fe_cache.get_gradients("solution", "u", displacement, alpha);
85  auto &Fs = fe_cache.get_deformation_gradients("solution", "Fu", displacement, alpha);
86 
87  const FEValuesExtractors::Scalar pressure(dim);
88  auto &ps = fe_cache.get_values("solution","p", pressure, alpha);
89 
90  auto &JxW = fe_cache.get_JxW_values();
91 
92  const unsigned int n_q_points = ps.size();
93 
94  energies[0] = 0;
95  for (unsigned int q=0; q<n_q_points; ++q)
96  {
98 
99  const EnergyType &p = ps[q];
100  const Tensor <2, dim, EnergyType> &F = Fs[q];
101  const Tensor<2, dim, EnergyType> C = transpose(F)*F;
102  auto &grad_u = grad_us[q];
103 
104  EnergyType Ic = trace(C);
105  EnergyType J = determinant(F);
106 
107  EnergyType psi = (mu/2.)*(Ic-dim)-p*(J-1.);
108  energies[0] += (psi)*JxW[q];
109  if (!compute_only_system_terms)
110  energies[1] += (scalar_product(grad_u,grad_u) + 0.5*p*p)*JxW[q];
111  }
112 }
113 
114 
115 template <int dim, int spacedim, typename LAC>
117 {
119  this->add_parameter(prm, &mu, "Shear modulus", "10.0", Patterns::Double(0.0));
120 }
121 
122 template <int dim, int spacedim, typename LAC>
123 void NeoHookeanTwoFieldsInterface<dim,spacedim,LAC>::set_matrix_couplings(std::vector<std::string> &couplings) const
124 {
125  couplings[0]="1,1;1,0";
126  couplings[1]="1,0;0,1";
127 }
128 
129 template <int dim, int spacedim, typename LAC>
130 void
132  const std::vector<shared_ptr<LATrilinos::BlockMatrix> > matrices,
135 {
136 
137  std::vector<std::vector<bool> > constant_modes;
138  FEValuesExtractors::Vector displacement(0);
139  DoFTools::extract_constant_modes (dh, dh.get_fe().component_mask(displacement),
140  constant_modes);
141 
142  P_preconditioner.reset (new TrilinosWrappers::PreconditionJacobi());
143  Amg_preconditioner.reset (new TrilinosWrappers::PreconditionAMG());
144 
146  Amg_data.constant_modes = constant_modes;
147  Amg_data.elliptic = true;
148  Amg_data.higher_order_elements = true;
149  Amg_data.smoother_sweeps = 2;
150  Amg_data.aggregation_threshold = 0.02;
151 
152  P_preconditioner->initialize (matrices[1]->block(1,1));
153  Amg_preconditioner->initialize (matrices[1]->block(0,0),Amg_data);
154 
155 
156  // SYSTEM MATRIX:
157  auto A = linear_operator< TrilinosWrappers::MPI::Vector >( matrices[0]->block(0,0) );
158  auto Bt = linear_operator< TrilinosWrappers::MPI::Vector >( matrices[0]->block(0,1) );
159  // auto B = transpose_operator(Bt);
160  auto B = linear_operator< TrilinosWrappers::MPI::Vector >( matrices[0]->block(1,0) );
161  auto ZeroP = 0*linear_operator< TrilinosWrappers::MPI::Vector >( matrices[0]->block(1,1) );
162 
163  auto Mp = linear_operator< TrilinosWrappers::MPI::Vector >( matrices[1]->block(1,1) );
164 
165  static ReductionControl solver_control_pre(5000, 1e-8);
166  static SolverCG<TrilinosWrappers::MPI::Vector> solver_CG(solver_control_pre);
167  auto A_inv = inverse_operator( A, solver_CG, *Amg_preconditioner);
168  auto Schur_inv = inverse_operator( Mp, solver_CG, *P_preconditioner);
169 
170  auto P00 = A_inv;
171  auto P01 = null_operator(Bt);
172  auto P10 = Schur_inv * B * A_inv;
173  auto P11 = -1 * Schur_inv;
174 
175  // ASSEMBLE THE PROBLEM:
176  system_op = block_operator<2, 2, LATrilinos::VectorType >({{
177  {{ A, Bt }} ,
178  {{ B, ZeroP }}
179  }
180  });
181 
182 
183  //const auto S = linear_operator<VEC>(matrix);
184 
185  prec_op = block_operator<2, 2, LATrilinos::VectorType >({{
186  {{ P00, P01 }} ,
187  {{ P10, P11 }}
188  }
189  });
190 }
191 
192 #endif
193 
Definition: lac_type.h:33
std::vector< std::vector< bool > > constant_modes
void set_matrix_couplings(std::vector< std::string > &couplings) const
Definition: neo_hookean_two_fields.h:123
ActiveSelector::active_cell_iterator active_cell_iterator
This is the class that users should derive from.
Definition: pde_system_interface.h:46
NeoHookeanTwoFieldsInterface()
Definition: neo_hookean_two_fields.h:62
virtual void declare_parameters(ParameterHandler &prm)
Definition: neo_hookean_two_fields.h:116
LinearOperator< Range, Domain > null_operator(const LinearOperator< Range, Domain > &op)
void compute_system_operators(const DoFHandler< dim, spacedim > &, const std::vector< shared_ptr< LATrilinos::BlockMatrix > >, LinearOperator< LATrilinos::VectorType > &, LinearOperator< LATrilinos::VectorType > &) const
Definition: neo_hookean_two_fields.h:131
LinearOperator< typename Solver::vector_type, typename Solver::vector_type > inverse_operator(const LinearOperator< typename Solver::vector_type, typename Solver::vector_type > &op, Solver &solver, const Preconditioner &preconditioner)
Definition: neo_hookean_two_fields.h:27
void energies_and_residuals(const typename DoFHandler< dim, spacedim >::active_cell_iterator &cell, FEValuesCache< dim, spacedim > &scratch, std::vector< EnergyType > &energies, std::vector< std::vector< ResidualType > > &local_residuals, bool compute_only_system_terms) const
Definition: neo_hookean_two_fields.h:73
void extract_constant_modes(const DoFHandlerType &dof_handler, const ComponentMask &component_mask, std::vector< std::vector< bool > > &constant_modes)
const FiniteElement< dim, spacedim > & get_fe() const