34 template <
int dim,
int spacedim,
typename LacType>
39 , embedded(
"w",
"Embedded")
41 , coupling(
"/Coupling")
42 , mass_solver(
"/Mass solver")
47 template <
int dim,
int spacedim,
typename LacType>
52 space.grid_generator.generate(space.triangulation);
53 embedded.grid_generator.generate(embedded.triangulation);
54 coupling.initialize(space_cache,
59 embedded.constraints);
60 coupling.adjust_grid_refinements(space.triangulation,
61 embedded.triangulation,
67 template <
int dim,
int spacedim,
typename LacType>
72 embedded.setup_system();
74 const auto row_indices = space.dof_handler.locally_owned_dofs();
75 const auto col_indices = embedded.dof_handler.locally_owned_dofs();
79 space.mpi_communicator,
83 embedded.dof_handler.n_dofs(),
86 coupling.assemble_sparsity(dsp);
90 space.mpi_communicator,
91 space.locally_relevant_dofs[0]);
93 coupling_matrix.reinit(row_indices,
96 space.mpi_communicator);
101 template <
int dim,
int spacedim,
typename LacType>
107 "Assemble stiffness system");
111 space.finite_element(),
112 space.cell_quadrature,
117 space.finite_element().n_dofs_per_cell());
119 for (
const auto &cell : space.dof_handler.active_cell_iterators())
120 if (cell->is_locally_owned())
122 auto &cell_matrix = copy.matrices[0];
123 auto &cell_rhs = copy.vectors[0];
126 const auto &fe_values = scratch.
reinit(cell);
127 cell->get_dof_indices(copy.local_dof_indices[0]);
129 for (
const unsigned int q_index :
130 fe_values.quadrature_point_indices())
132 for (
const unsigned int i : fe_values.dof_indices())
134 for (
const unsigned int j : fe_values.dof_indices())
136 (fe_values.shape_grad(i, q_index) *
137 fe_values.shape_grad(j, q_index) *
138 fe_values.JxW(q_index));
140 (fe_values.shape_value(i, q_index) *
141 space.forcing_term.value(
142 fe_values.quadrature_point(q_index)) *
143 fe_values.JxW(q_index));
147 space.constraints.distribute_local_to_global(
150 copy.local_dof_indices[0],
160 coupling_matrix = 0.0;
161 coupling.assemble_matrix(coupling_matrix);
168 embedded.finite_element(),
169 embedded.cell_quadrature,
174 embedded.finite_element().n_dofs_per_cell());
176 for (
const auto &cell : embedded.dof_handler.active_cell_iterators())
177 if (cell->is_locally_owned())
179 auto &cell_matrix = copy.matrices[0];
180 auto &cell_rhs = copy.vectors[0];
183 const auto &fe_values = scratch.
reinit(cell);
184 cell->get_dof_indices(copy.local_dof_indices[0]);
186 for (
const unsigned int q_index :
187 fe_values.quadrature_point_indices())
189 for (
const unsigned int i : fe_values.dof_indices())
191 for (
const unsigned int j : fe_values.dof_indices())
193 (fe_values.shape_value(i, q_index) *
194 fe_values.shape_value(j, q_index) *
195 fe_values.JxW(q_index));
197 (fe_values.shape_value(i, q_index) *
198 embedded.forcing_term.value(
199 fe_values.quadrature_point(q_index)) *
200 fe_values.JxW(q_index));
204 embedded.constraints.distribute_local_to_global(
207 copy.local_dof_indices[0],
216 embedded.forcing_term,
224 template <
int dim,
int spacedim,
typename LacType>
230 using BVec =
typename LacType::BlockVector;
231 using Vec =
typename BVec::BlockType;
235 auto A = linear_operator<Vec>(space.matrix.block(0, 0));
236 auto Bt = linear_operator<Vec>(coupling_matrix);
239 auto M = linear_operator<Vec>(embedded.matrix.block(0, 0));
242 space.preconditioner.initialize(space.matrix.block(0, 0));
243 A_inv = space.inverse_operator(A, space.preconditioner);
245 embedded.preconditioner.initialize(embedded.matrix.block(0, 0));
246 auto M_prec = linear_operator<Vec>(M, embedded.preconditioner);
247 M_inv = mass_solver(M, M_prec);
249 auto &lambda = embedded.solution.block(0);
250 auto &embedded_rhs = embedded.rhs.block(0);
251 auto &solution = space.solution.block(0);
252 auto &rhs = space.rhs.block(0);
254 auto S = B * A_inv * Bt;
256 auto S_inv = embedded.inverse_operator(S, M_inv);
258 lambda = S_inv * (B * A_inv * rhs - embedded_rhs);
259 solution = A_inv * (rhs - Bt * lambda);
262 embedded.constraints.distribute(lambda);
263 embedded.locally_relevant_solution = embedded.solution;
264 space.constraints.distribute(solution);
265 space.locally_relevant_solution = space.solution;
270 template <
int dim,
int spacedim,
typename LacType>
273 const unsigned int cycle)
275 space.output_results(cycle);
276 embedded.output_results(cycle);
281 template <
int dim,
int spacedim,
typename LacType>
287 for (
const auto &cycle : space.grid_refinement.get_refinement_cycles())
293 space.estimate(space.error_per_cell);
294 embedded.estimate(embedded.error_per_cell);
295 output_results(cycle);
296 if (cycle < space.grid_refinement.get_n_refinement_cycles() - 1)
298 space.mark(space.error_per_cell);
300 embedded.triangulation.refine_global(1);
301 coupling.adjust_grid_refinements(space.triangulation,
302 embedded.triangulation,
307 if (space.mpi_rank == 0)
309 space.error_table.output_table(std::cout);
310 embedded.error_table.output_table(std::cout);
void push(const std::string &text)
unsigned int depth_console(const unsigned int n)
const FEValues< dim, spacedim > & reinit(const typename DoFHandler< dim, spacedim >::active_cell_iterator &cell)
General class, used to initialize different types of block vectors, block atrices and block sparsity ...
void output_results(const unsigned int cycle)
LinearOperator< Range, Range, Payload > identity_operator(const std::function< void(Range &, bool)> &reinit_vector)
LinearOperator< Domain, Range, Payload > transpose_operator(const LinearOperator< Range, Domain, Payload > &op)
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
PDEs::DistributedLagrange< dim, spacedim, LAC::LATrilinos > DistributedLagrange
We collect in this namespace all PDEs that are relevant to Fluid Structure Interaction Problems.
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation