[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
meshmover_linear_elasticity.cpp
1 #include <deal.II/lac/constrained_linear_operator.h>
2 
3 #include <deal.II/dofs/dof_tools.h>
4 
5 //#include <deal.II/lac/solver_cg.h>
6 #include <deal.II/lac/solver_gmres.h>
7 #include <deal.II/lac/solver_bicgstab.h>
8 //#include <deal.II/lac/precondition.h>
9 //#include <deal.II/lac/precondition_block.h>
10 
11 #include <deal.II/lac/dynamic_sparsity_pattern.h>
12 #include <deal.II/lac/sparsity_tools.h>
13 #include <deal.II/lac/affine_constraints.h>
14 #include <deal.II/lac/trilinos_precondition.h>
15 #include <deal.II/lac/trilinos_solver.h>
16 
17 #include <deal.II/lac/trilinos_sparse_matrix.h>
18 
19 #include "meshmover_linear_elasticity.hpp"
20 
21 namespace PHiLiP {
22 namespace MeshMover {
23 
24  // template <int dim, typename real>
25  // LinearElasticity<dim,real>::LinearElasticity(
26  // const HighOrderGrid<dim,real> &high_order_grid,
27  // const dealii::LinearAlgebra::distributed::Vector<double> &boundary_displacements_vector)
28  // : triangulation(*(high_order_grid.triangulation))
29  // , mapping_fe_field(high_order_grid.mapping_fe_field)
30  // , dof_handler(high_order_grid.dof_handler_grid)
31  // , quadrature_formula(dof_handler.get_fe().degree + 1)
32  // , mpi_communicator(MPI_COMM_WORLD)
33  // , n_mpi_processes(dealii::Utilities::MPI::n_mpi_processes(mpi_communicator))
34  // , this_mpi_process(dealii::Utilities::MPI::this_mpi_process(mpi_communicator))
35  // , pcout(std::cout, this_mpi_process == 0)
36  // , boundary_ids_vector(high_order_grid.surface_to_volume_indices)
37  // , boundary_displacements_vector(boundary_displacements_vector)
38  // {
39  // AssertDimension(boundary_displacements_vector.size(), boundary_ids_vector.size());
40  // }
41 
42  template <int dim, typename real>
44  const HighOrderGrid<dim,real> &high_order_grid,
45  const dealii::LinearAlgebra::distributed::Vector<double> &boundary_displacements_vector)
46  : LinearElasticity<dim,real> (
47  *(high_order_grid.triangulation),
48  high_order_grid.mapping_fe_field,
49  high_order_grid.dof_handler_grid,
50  high_order_grid.surface_to_volume_indices,
51  boundary_displacements_vector)
52  { }
53 
54  template <int dim, typename real>
56  const Triangulation &_triangulation,
57  const std::shared_ptr<dealii::MappingFEField<dim,dim,VectorType,DoFHandlerType>> mapping_fe_field,
58  const DoFHandlerType &_dof_handler,
59  const dealii::LinearAlgebra::distributed::Vector<int> &_boundary_ids_vector,
60  const dealii::LinearAlgebra::distributed::Vector<double> &_boundary_displacements_vector)
61  : triangulation(_triangulation)
63  , dof_handler(_dof_handler)
64  , quadrature_formula(dof_handler.get_fe().degree + 1)
65  , mpi_communicator(MPI_COMM_WORLD)
66  , n_mpi_processes(dealii::Utilities::MPI::n_mpi_processes(mpi_communicator))
67  , this_mpi_process(dealii::Utilities::MPI::this_mpi_process(mpi_communicator))
68  , pcout(std::cout, this_mpi_process == 0)
69  , boundary_ids_vector(_boundary_ids_vector)
70  , boundary_displacements_vector(_boundary_displacements_vector)
71  {
72  AssertDimension(boundary_displacements_vector.size(), boundary_ids_vector.size());
73 
74  boundary_displacements_vector.update_ghost_values();
75  setup_system();
76  }
77 
78  // template <int dim, typename real>
79  // LinearElasticity<dim,real>::LinearElasticity(
80  // const HighOrderGrid<dim,real> &high_order_grid,
81  // const std::vector<dealii::Tensor<1,dim,real>> &boundary_displacements_tensors)
82  // : LinearElasticity(high_order_grid, boundary_displacements_vector(tensor_to_vector(boundary_displacements_tensors))
83  // { }
84 
85  template <int dim, typename real>
86  dealii::LinearAlgebra::distributed::Vector<double> LinearElasticity<dim,real>::
87  tensor_to_vector(const std::vector<dealii::Tensor<1,dim,real>> &boundary_displacements_tensors) const
88  {
89  (void) boundary_displacements_tensors;
90  dealii::LinearAlgebra::distributed::Vector<double> boundary_displacements_vector;
92  }
93 
94  //template <int dim, typename real>
95  //LinearElasticity<dim,real>::~LinearElasticity() { dof_handler.clear(); }
96 
97  template <int dim, typename real>
98  dealii::LinearAlgebra::distributed::Vector<real>
100  {
101  pcout << "Solving linear elasticity problem for volume displacements..." << std::endl;
102  solve_timestep();
103  // displacement_solution = 0;
104  // all_constraints.distribute(displacement_solution);
105  displacement_solution.update_ghost_values();
106  return displacement_solution;
107  }
108  template <int dim, typename real>
110  {
111  //dof_handler.distribute_dofs(fe_system);
112  //dealii::DoFRenumbering::Cuthill_McKee(dof_handler);
113 
114  locally_owned_dofs = dof_handler.locally_owned_dofs();
115  dealii::DoFTools::extract_locally_relevant_dofs(dof_handler, locally_relevant_dofs);
116  dealii::IndexSet ghost_dofs = locally_relevant_dofs;
117  ghost_dofs.subtract_set(locally_owned_dofs);
118  //ghost_dofs.print(std::cout);
119 
120  system_rhs.reinit(locally_owned_dofs, ghost_dofs, mpi_communicator);
123 
124  // Set the hanging node constraints
125  all_constraints.clear();
127  dealii::DoFTools::make_hanging_node_constraints(dof_handler, all_constraints);
128 
129  hanging_node_constraints.clear();
131  dealii::DoFTools::make_hanging_node_constraints(dof_handler, hanging_node_constraints);
132  hanging_node_constraints.close();
133 
134  // Set the Dirichlet BC constraint
135  // Only add Dirichlet BC when there is currently no constraint.
136  // Note that we set ALL surfaces to be an inhomogeneous BC.
137  // In a way, it allows us to detect surface DoFs in the matrix by checking whether there is an inhomogeneous constraight.
138  // If there is another constraint, it's because it's a hanging node.
139  // In that case, we choose to satisfy the regularity properties of the element and ignoring the Dirichlet BC.
140  const auto &partitionner = boundary_ids_vector.get_partitioner();
141  for (unsigned int isurf = 0; isurf < boundary_ids_vector.size(); ++isurf) {
142  const bool is_accessible = partitionner->in_local_range(isurf) || partitionner->is_ghost_entry(isurf);
143  if (is_accessible) {
144  const unsigned int iglobal_row = boundary_ids_vector[isurf];
145  const double dirichlet_value = boundary_displacements_vector[isurf];
146  Assert(all_constraints.can_store_line(iglobal_row), dealii::ExcInternalError());
147  all_constraints.add_line(iglobal_row);
148  all_constraints.set_inhomogeneity(iglobal_row, dirichlet_value+1e-15);
149  }
150  }
151  all_constraints.close();
152  dealii::IndexSet temp_locally_active_dofs;
153  dealii::DoFTools::extract_locally_active_dofs(dof_handler, temp_locally_active_dofs);
154  const std::vector<dealii::IndexSet> local_dofs_per_process = dealii::Utilities::MPI::all_gather(mpi_communicator, dof_handler.locally_owned_dofs());
155  AssertThrow(all_constraints.is_consistent_in_parallel(local_dofs_per_process,
156  temp_locally_active_dofs,
158  /*verbose*/ true),
159  dealii::ExcInternalError());
160 
161 
162  dealii::DynamicSparsityPattern sparsity_pattern(locally_relevant_dofs);
163  dealii::DoFTools::make_sparsity_pattern(dof_handler,
164  sparsity_pattern,
166  //all_constraints,
167  /*keep constrained dofs*/ true);
168  dealii::SparsityTools::distribute_sparsity_pattern(sparsity_pattern,
169  dof_handler.locally_owned_dofs(),
174  sparsity_pattern,
178  sparsity_pattern,
180 
181  // pcout << " Number of active cells: " << triangulation.n_active_cells() << std::endl;
182  // pcout << " Number of degrees of freedom: " << dof_handler.n_dofs() << std::endl;
183  }
184  template <int dim, typename real>
186  {
187  pcout << " Assembling MeshMover::LinearElasticity system..." << std::endl;
188 
189  setup_system();
190 
191  system_rhs = 0;
192  system_matrix = 0;
195  const dealii::FESystem<dim> &fe_system = dof_handler.get_fe(0);
196  dealii::FEValues<dim> fe_values(
198  fe_system,
200  dealii::update_values | dealii::update_gradients |
201  dealii::update_quadrature_points | dealii::update_JxW_values);
202  const unsigned int dofs_per_cell = fe_system.dofs_per_cell;
203  const unsigned int n_q_points = quadrature_formula.size();
204  std::vector<dealii::types::global_dof_index> local_dof_indices(dofs_per_cell);
205  dealii::FullMatrix<double> cell_matrix(dofs_per_cell, dofs_per_cell);
206  dealii::Vector<double> cell_rhs(dofs_per_cell);
207 
208  //std::vector<double> youngs_modulus(n_q_points, 1.0);
209  //std::vector<double> poissons_ratio(n_q_points, 0.4);
210 
211  std::vector<double> youngs_modulus(n_q_points, 1.0);
212  std::vector<double> poissons_ratio(n_q_points, 0.1);
213 
214  std::vector<double> lame_lambda_values(n_q_points);
215  std::vector<double> lame_mu_values(n_q_points);
216  for (unsigned int iquad = 0; iquad < n_q_points; ++iquad) {
217  const double E = youngs_modulus[iquad];
218  const double nu = poissons_ratio[iquad];
219  lame_lambda_values[iquad] = E*nu/((1.0+nu)*(1-2.0*nu));
220  lame_mu_values[iquad] = 0.5*E/(1.0+nu);
221  }
222 
223  dealii::Functions::ZeroFunction<dim> body_force(dim);
224  std::vector<dealii::Vector<double>> body_force_values(n_q_points,dealii::Vector<double>(dim));
225 
226  for (const auto &cell : dof_handler.active_cell_iterators()) {
227  if (!cell->is_locally_owned()) continue;
228 
229  cell_matrix = 0;
230  cell_rhs = 0;
231  fe_values.reinit(cell);
232 
233  double volume = 0.0;
234  for (unsigned int q_point = 0; q_point < n_q_points; ++q_point) {
235  volume += fe_values.JxW(q_point);
236  }
237 
238  //lame_lambda.value_list(fe_values.get_quadrature_points(), lame_lambda_values);
239  //lame_mu.value_list(fe_values.get_quadrature_points(), lame_mu_values);
240 
241  for (unsigned int itest = 0; itest < dofs_per_cell; ++itest) {
242 
243  const unsigned int component_test = fe_system.system_to_component_index(itest).first;
244 
245  for (unsigned int itrial = 0; itrial < dofs_per_cell; ++itrial) {
246 
247  const unsigned int component_trial = fe_system.system_to_component_index(itrial).first;
248 
249  for (unsigned int q_point = 0; q_point < n_q_points; ++q_point) {
250 
251  const double E = youngs_modulus[q_point] / volume;
252  const double nu = poissons_ratio[q_point];
253  lame_lambda_values[q_point] = E*nu/((1.0+nu)*(1-2.0*nu));
254  lame_mu_values[q_point] = 0.5*E/(1.0+nu);
255  //const SymmetricTensor<2, dim> grad_basis_i_grad_u
256  //cell_matrix(itest, itrial) +=
257  double value = lame_lambda_values[q_point]
258  * fe_values.shape_grad_component(itest, q_point, component_test)
259  * fe_values.shape_grad_component(itrial, q_point, component_trial);
260  value += lame_mu_values[q_point]
261  * fe_values.shape_grad_component(itest, q_point, component_trial)
262  * fe_values.shape_grad_component(itrial, q_point, component_test);
263  if (component_test == component_trial) {
264  value += lame_mu_values[q_point]
265  * fe_values.shape_grad_component(itest, q_point, component_test)
266  * fe_values.shape_grad_component(itrial, q_point, component_trial);
267  }
268  value *= fe_values.JxW(q_point);
269 
270  cell_matrix(itest, itrial) += value;
271  }
272  }
273  }
274  body_force.vector_value_list(fe_values.get_quadrature_points(), body_force_values);
275  for (unsigned int itest = 0; itest < dofs_per_cell; ++itest) {
276  const unsigned int component_test = fe_system.system_to_component_index(itest).first;
277  for (unsigned int q_point = 0; q_point < n_q_points; ++q_point) {
278  cell_rhs(itest) += body_force_values[q_point][component_test] * fe_values.shape_value(itest, q_point);
279  cell_rhs(itest) *= fe_values.JxW(q_point);
280  }
281  }
282  cell->get_dof_indices(local_dof_indices);
283  //all_constraints.distribute_local_to_global(cell_matrix, cell_rhs, local_dof_indices, system_matrix, system_rhs);
284  const bool use_inhomogeneities_for_rhs = false;
285  //all_constraints.distribute_local_to_global(cell_matrix, cell_rhs, local_dof_indices, system_matrix, system_rhs, use_inhomogeneities_for_rhs);
286  hanging_node_constraints.distribute_local_to_global(cell_matrix, cell_rhs, local_dof_indices, system_matrix, system_rhs, use_inhomogeneities_for_rhs);
287  // Unconstrained system matrix and right-hand side
288  // std::cout << std::endl;
289  // for (auto const &value: local_dof_indices) {
290  // std::cout << value << std::endl;
291  // }
292  // system_matrix.print(std::cout);
293  // system_matrix_unconstrained.print(std::cout);
294  // cell_matrix.print(std::cout);
295  // system_matrix_unconstrained.add(local_dof_indices, cell_matrix);
296  // //system_matrix_unconstrained.add(local_dof_indices, local_dof_indices, cell_matrix);
297  // system_rhs_unconstrained.add(local_dof_indices, cell_rhs);
298  // // for (unsigned int itest = 0; itest < dofs_per_cell; ++itest) {
299  // // std::vector<double> row_values(dofs_per_cell);
300  // // for (unsigned int itrial = 0; itrial < dofs_per_cell; ++itrial) {
301  // // row_values[itrial] = cell_matrix[itest][itrial];
302  // // }
303  // // system_rhs_unconstrained.add(local_dof_indices[itest], cell_rhs);
304  // // }
305  // // for (unsigned int itest = 0; itest < dofs_per_cell; ++itest) {
306  // // for (unsigned int itrial = 0; itrial < dofs_per_cell; ++itrial) {
307  // // system_matrix_unconstrained.add(local_dof_indices, local_dof_indices, cell_matrix);
308  // // }
309  // // system_rhs_unconstrained.add(local_dof_indices, cell_rhs);
310  // // }
311  for (unsigned int itest = 0; itest < dofs_per_cell; ++itest) {
312  for (unsigned int itrial = 0; itrial < dofs_per_cell; ++itrial) {
313  system_matrix_unconstrained.add(local_dof_indices[itest], local_dof_indices[itrial], cell_matrix(itest,itrial));
314  }
315  }
316  system_rhs_unconstrained.add(local_dof_indices, cell_rhs);
317 
318  } // active cell loop
319  system_matrix.compress(dealii::VectorOperation::add);
320  system_rhs.compress(dealii::VectorOperation::add);
321  system_matrix_unconstrained.compress(dealii::VectorOperation::add);
322  system_rhs_unconstrained.compress(dealii::VectorOperation::add);
323  const auto &partitionner = boundary_ids_vector.get_partitioner();
324  MPI_Barrier(MPI_COMM_WORLD);
325  for (unsigned int isurf = 0; isurf < boundary_ids_vector.size(); ++isurf) {
326  const bool is_accessible = partitionner->in_local_range(isurf) || partitionner->is_ghost_entry(isurf);
327  if (is_accessible) {
328  const unsigned int iglobal_row = boundary_ids_vector[isurf];
329  const double dirichlet_value = boundary_displacements_vector[isurf];
330 
331  system_matrix.clear_row(iglobal_row,1.0);
332  system_rhs[iglobal_row] = dirichlet_value;
333  }
334  }
335  // Until deal.II accepts the pull request to fix TrilinosWrappers::SparseMatrix::clear_row(row,new_diag_value)
336  // Manually set the value of the diagonal to 1.0 here.
337  for (unsigned int isurf = 0; isurf < boundary_ids_vector.size(); ++isurf) {
338  const bool is_accessible = partitionner->in_local_range(isurf) || partitionner->is_ghost_entry(isurf);
339  if (is_accessible) {
340  const unsigned int iglobal_row = boundary_ids_vector[isurf];
341  system_matrix.set(iglobal_row,iglobal_row,1.0);
342  }
343  }
344  system_matrix.compress(dealii::VectorOperation::insert);
345  system_rhs.compress(dealii::VectorOperation::insert);
346  system_matrix_unconstrained.compress(dealii::VectorOperation::insert);
347  system_rhs_unconstrained.compress(dealii::VectorOperation::insert);
348  }
349  template <int dim, typename real>
351  {
352  assemble_system();
354  //const unsigned int n_iterations = solve_linear_problem();
355  //pcout << " Solver converged in " << n_iterations << " iterations." << std::endl;
356  }
357 
358  template <int dim, typename real>
359  void
362  const dealii::LinearAlgebra::distributed::Vector<double> &input_vector,
363  dealii::LinearAlgebra::distributed::Vector<double> &output_vector)
364  {
365  pcout << "Applying [dXvdXs] onto a vector..." << std::endl;
366  assert(input_vector.size() == output_vector.size());
367 
368  double input_vector_norm = input_vector.l2_norm();
369  if (input_vector_norm == 0.0) {
370  pcout << "Zero input vector. Zero output vector." << std::endl;
371  output_vector = 0.0;
372  return;
373  }
374 
375  assemble_system();
376 
377  const bool log_history = (this_mpi_process == 0);
378  dealii::SolverControl solver_control(20000, 1e-14 * input_vector_norm, log_history);
379  //dealii::SolverControl solver_control(20000, 1e-14, log_history);
380  solver_control.log_frequency(100);
381  const int max_n_tmp_vectors=200;
382  const bool right_preconditioning=true;
383  const bool use_default_residual=true;
384  const bool force_re_orthogonalization=false;
385  dealii::SolverGMRES<dealii::LinearAlgebra::distributed::Vector<double>>::AdditionalData gmres_settings(max_n_tmp_vectors, right_preconditioning, use_default_residual, force_re_orthogonalization);
386  dealii::SolverGMRES<dealii::LinearAlgebra::distributed::Vector<double>> solver(solver_control, gmres_settings);
387 
388  //dealii::TrilinosWrappers::PreconditionJacobi precondition;
389  //precondition.initialize(system_matrix);
390 
391  //dealii::TrilinosWrappers::PreconditionILU precondition;
392  //const int ilu_fill = 2;
393  //dealii::TrilinosWrappers::PreconditionILU::AdditionalData precond_settings(ilu_fill, 0., 1.0, 1);
394  //precondition.initialize(system_matrix, precond_settings);
395 
396  dealii::TrilinosWrappers::PreconditionILUT precondition;
397  const unsigned int ilut_fill=50;
398  const double ilut_drop=1e-15;
399  const double ilut_atol=1e-6;
400  const double ilut_rtol=1.00001;
401  const unsigned int overlap=1;
402  dealii::TrilinosWrappers::PreconditionILUT::AdditionalData precond_settings(ilut_drop, ilut_fill, ilut_atol, ilut_rtol, overlap);
403  precondition.initialize(system_matrix, precond_settings);
404 
405 
406  //const double omega = 1;
407  //const double min_diagonal = 1e-8;
408  //const unsigned int overlap = 1;
409  //const unsigned int n_sweeps = 1;
410  //dealii::TrilinosWrappers::PreconditionSSOR::AdditionalData precond_settings(omega, min_diagonal, overlap, n_sweeps);
411  //dealii::TrilinosWrappers::PreconditionSSOR precondition;
412  //precondition.initialize(system_matrix, precond_settings);
413 
414  using trilinos_vector_type = dealii::LinearAlgebra::distributed::Vector<double>;
415  using payload_type = dealii::TrilinosWrappers::internal::LinearOperatorImplementation::TrilinosPayload;
416  const auto op_a = dealii::linear_operator<trilinos_vector_type,trilinos_vector_type,payload_type>(system_matrix);
417 
418  const auto &rhs_vector = input_vector;
419  output_vector = input_vector;
420  //output_vector = 0.0;//input_vector;
421 
422  // Solve modified system.
423  dealii::deallog.depth_console(2);
424  solver.solve(op_a, output_vector, rhs_vector, precondition);
425 
426  pcout << "dXvdXvs Solver took " << solver_control.last_step() << " steps. "
427  << "Residual: " << solver_control.last_value() << ". "
428  << std::endl;
429 
430  solver.solve(op_a, output_vector, rhs_vector, precondition);
431 
432  pcout << "dXvdXvs Solver took " << solver_control.last_step() << " steps. "
433  << "Residual: " << solver_control.last_value() << ". "
434  << std::endl;
435 
436  if (solver_control.last_check() != dealii::SolverControl::State::success) {
437  pcout << "Failed to converge." << std::endl;
438  std::abort();
439  }
440  }
441 
442  template <int dim, typename real>
443  void
446  std::vector<dealii::LinearAlgebra::distributed::Vector<double>> &list_of_vectors,
447  dealii::TrilinosWrappers::SparseMatrix &output_matrix)
448  {
449  assemble_system();
450 
451  const unsigned int n_rows = dof_handler.n_dofs();
452  const unsigned int n_cols = list_of_vectors.size();
453  //const unsigned int max_per_row = n_cols;
454 
455  const dealii::IndexSet &row_part = dof_handler.locally_owned_dofs();
456  dealii::DoFTools::extract_locally_relevant_dofs(dof_handler, locally_relevant_dofs);
457 
458  dealii::DynamicSparsityPattern full_dsp(n_rows, n_cols, row_part);
459  for (const auto &i_row: row_part) {
460  for (unsigned int i_col = 0; i_col < n_cols; ++i_col) {
461  full_dsp.add(i_row, i_col);
462  }
463  }
464  dealii::SparsityTools::distribute_sparsity_pattern(full_dsp, dof_handler.locally_owned_dofs(), mpi_communicator, locally_relevant_dofs);
465 
466  dealii::SparsityPattern full_sp;
467  full_sp.copy_from(full_dsp);
468 
469  const dealii::IndexSet col_part = dealii::Utilities::MPI::create_evenly_distributed_partitioning(MPI_COMM_WORLD,n_cols);
470 
471  output_matrix.reinit(row_part, col_part, full_sp, mpi_communicator);
472 
473  //dealii::TrilinosWrappers::PreconditionJacobi precondition;
474  //precondition.initialize(system_matrix);
475 
476  //dealii::TrilinosWrappers::PreconditionILU precondition;
477  //const int ilu_fill = 2;
478  //dealii::TrilinosWrappers::PreconditionILU::AdditionalData precond_settings(ilu_fill, 0., 1.0, 1);
479  //precondition.initialize(system_matrix, precond_settings);
480 
481  dealii::TrilinosWrappers::PreconditionILUT precondition;
482  const unsigned int ilut_fill=50;
483  const double ilut_drop=0.0;//1e-15;
484  const double ilut_atol=0.0;//1e-6;
485  const double ilut_rtol=1.0;//1.00001;
486  const unsigned int overlap=1;
487  dealii::TrilinosWrappers::PreconditionILUT::AdditionalData precond_settings(ilut_drop, ilut_fill, ilut_atol, ilut_rtol, overlap);
488  precondition.initialize(system_matrix, precond_settings);
489 
490 
491  //const double omega = 1;
492  //const double min_diagonal = 1e-8;
493  //const unsigned int overlap = 1;
494  //const unsigned int n_sweeps = 1;
495  //dealii::TrilinosWrappers::PreconditionSSOR::AdditionalData precond_settings(omega, min_diagonal, overlap, n_sweeps);
496  //dealii::TrilinosWrappers::PreconditionSSOR precondition;
497  //precondition.initialize(system_matrix, precond_settings);
498 
499  using trilinos_vector_type = dealii::LinearAlgebra::distributed::Vector<double>;
500  using payload_type = dealii::TrilinosWrappers::internal::LinearOperatorImplementation::TrilinosPayload;
501  const auto op_a = dealii::linear_operator<trilinos_vector_type,trilinos_vector_type,payload_type>(system_matrix);
502 
503  dXvdXs.clear();
504  pcout << "Applying for [dXvdXs] onto " << list_of_vectors.size() << " vectors..." << std::endl;
505 
506  unsigned int col = 0;
507  dealii::LinearAlgebra::distributed::Vector<double> output_vector;
508  output_vector.reinit(list_of_vectors[0]);
509  for (auto &input_vector: list_of_vectors) {
510 
511  pcout << " Vector " << col << " out of " << list_of_vectors.size() << std::endl;
512 
513  dealii::deallog.depth_console(0);
514 
515  double input_vector_norm = input_vector.l2_norm();
516  if (input_vector_norm == 0.0) {
517  pcout << "Zero input vector. Zero output vector." << std::endl;
518  output_vector = 0.0;
519  } else {
520  const bool log_history = (this_mpi_process == 0);
521  dealii::SolverControl solver_control(20000, 1e-14 * input_vector_norm, log_history);
522  //dealii::SolverControl solver_control(20000, 1e-14, log_history);
523  solver_control.log_frequency(100);
524  const int max_n_tmp_vectors=200;
525  const bool right_preconditioning=true;
526  const bool use_default_residual=true;
527  const bool force_re_orthogonalization=false;
528  dealii::SolverGMRES<dealii::LinearAlgebra::distributed::Vector<double>>::AdditionalData gmres_settings(max_n_tmp_vectors, right_preconditioning, use_default_residual, force_re_orthogonalization);
529  dealii::SolverGMRES<dealii::LinearAlgebra::distributed::Vector<double>> solver(solver_control, gmres_settings);
530 
531  //dealii::SolverBicgstab<dealii::LinearAlgebra::distributed::Vector<double>> solver(solver_control);
532 
533  dealii::deallog.depth_console(2);
534  solver.solve(op_a, output_vector, input_vector, precondition);
535  pcout << "dXvdXvs Solver took " << solver_control.last_step() << " steps. "
536  << "Residual: " << solver_control.last_value() << ". "
537  << std::endl;
538 
539  solver.solve(op_a, output_vector, input_vector, precondition);
540  pcout << "dXvdXvs Solver took " << solver_control.last_step() << " steps. "
541  << "Residual: " << solver_control.last_value() << ". "
542  << std::endl;
543  }
544 
545  dXvdXs.push_back(output_vector);
546 
547  for (const auto &row: dof_handler.locally_owned_dofs()) {
548  output_matrix.set(row, col, dXvdXs[col][row]);
549  }
550  col++;
551  }
552  output_matrix.compress(dealii::VectorOperation::insert);
553 
554  }
555 
556  template <int dim, typename real>
557  void
560  const dealii::LinearAlgebra::distributed::Vector<double> &input_vector,
561  dealii::LinearAlgebra::distributed::Vector<double> &output_vector)
562  {
563  pcout << "Applying [transpose(dXvdXvs)] onto a vector..." << std::endl;
564 
565  double input_vector_norm = input_vector.l2_norm();
566  if (input_vector_norm == 0.0) {
567  pcout << "Zero input vector. Zero output vector." << std::endl;
568  output_vector = 0.0;
569  return;
570  }
571 
572  assemble_system();
573 
574  const bool log_history = (this_mpi_process == 0);
575  dealii::SolverControl solver_control(20000, 1e-14 * input_vector_norm, log_history);
576  //dealii::SolverControl solver_control(20000, 1e-14, log_history);
577  solver_control.log_frequency(100);
578  const int max_n_tmp_vectors=200;
579  const bool right_preconditioning=true;
580  const bool use_default_residual=true;
581  const bool force_re_orthogonalization=false;
582  dealii::SolverGMRES<dealii::LinearAlgebra::distributed::Vector<double>>::AdditionalData gmres_settings(max_n_tmp_vectors, right_preconditioning, use_default_residual, force_re_orthogonalization);
583  dealii::SolverGMRES<dealii::LinearAlgebra::distributed::Vector<double>> solver(solver_control, gmres_settings);
584 
585  //dealii::TrilinosWrappers::PreconditionJacobi precondition;
586  //precondition.initialize(system_matrix);
587 
588  // dealii::TrilinosWrappers::PreconditionILU precondition;
589  // const int ilu_fill = 2;
590  // dealii::TrilinosWrappers::PreconditionILU::AdditionalData precond_settings(ilu_fill, 0., 1.0, 1);
591  // precondition.initialize(system_matrix, precond_settings);
592 
593  dealii::TrilinosWrappers::PreconditionILUT precondition;
594  const unsigned int ilut_fill=50;
595  const double ilut_drop=1e-15;
596  const double ilut_atol=1e-6;
597  const double ilut_rtol=1.00001;
598  const unsigned int overlap=1;
599  dealii::TrilinosWrappers::PreconditionILUT::AdditionalData precond_settings(ilut_drop, ilut_fill, ilut_atol, ilut_rtol, overlap);
600  precondition.initialize(system_matrix, precond_settings);
601 
602  //const double omega = 1;
603  //const double min_diagonal = 1e-8;
604  //const unsigned int overlap = 1;
605  //const unsigned int n_sweeps = 1;
606  //dealii::TrilinosWrappers::PreconditionSSOR::AdditionalData precond_settings(omega, min_diagonal, overlap, n_sweeps);
607  //dealii::TrilinosWrappers::PreconditionSSOR precondition;
608  //precondition.initialize(system_matrix, precond_settings);
609 
610  using trilinos_vector_type = VectorType;
611  using payload_type = dealii::TrilinosWrappers::internal::LinearOperatorImplementation::TrilinosPayload;
612  const auto op_a = dealii::linear_operator<trilinos_vector_type,trilinos_vector_type,payload_type>(system_matrix);
613  const auto op_at = dealii::transpose_operator(op_a);
614 
615  // Solve system.
616  dealii::deallog.depth_console(2);
617  output_vector = input_vector;
618  solver.solve(op_at, output_vector, input_vector, precondition);
619  pcout << "dXvdXvs_Transpose Solver took " << solver_control.last_step() << " steps. "
620  << "Residual: " << solver_control.last_value() << ". "
621  << std::endl;
622  solver.solve(op_at, output_vector, input_vector, precondition);
623  pcout << "dXvdXvs_Transpose Solver took " << solver_control.last_step() << " steps. "
624  << "Residual: " << solver_control.last_value() << ". "
625  << std::endl;
626  if (solver_control.last_check() != dealii::SolverControl::State::success) {
627  pcout << "Failed to converge." << std::endl;
628  std::abort();
629  }
630 
631 
632  }
633 
634  // template <int dim, typename real>
635  // unsigned int LinearElasticity<dim,real>::solve_linear_problem()
636  // {
637  // displacement_solution.reinit(system_rhs);
638 
639  // dealii::SolverControl solver_control(20000, 1e-14 * system_rhs.l2_norm());
640  // dealii::SolverGMRES<VectorType> solver(solver_control);
641  // dealii::TrilinosWrappers::PreconditionJacobi precondition;
642  // precondition.initialize(system_matrix);
643 
644  // using trilinos_vector_type = VectorType;
645  // using payload_type = dealii::TrilinosWrappers::internal::LinearOperatorImplementation::TrilinosPayload;
646  // const auto op_a = dealii::linear_operator<trilinos_vector_type,trilinos_vector_type,payload_type>(system_matrix);
647 
648  // solver.solve(op_a, displacement_solution, system_rhs, precondition);
649 
650  // return solver_control.last_step();
651  // }
652 
653  // template <int dim, typename real>
654  // void
655  // LinearElasticity<dim,real>
656  // ::apply_dXvdXvs(
657  // const dealii::LinearAlgebra::distributed::Vector<double> &input_vector,
658  // dealii::LinearAlgebra::distributed::Vector<double> &output_vector)
659  // {
660  // pcout << "Applying [dXvdXs] onto a vector..." << std::endl;
661  // assert(input_vector.size() == output_vector.size());
662 
663  // assemble_system();
664 
665  // dealii::SolverControl solver_control(20000, 1e-14 * system_rhs.l2_norm());
666  // dealii::SolverGMRES<dealii::LinearAlgebra::distributed::Vector<double>> solver(solver_control);
667  // dealii::TrilinosWrappers::PreconditionJacobi precondition;
668  // precondition.initialize(system_matrix_unconstrained);
669 
670  // /// The use of the constrained linear operator is heavily discussed in:
671  // /// https://www.dealii.org/current/doxygen/deal.II/group__constraints.html
672  // /// Given affine constraints such that x = C y + k
673  // /// where C describes the homogeneous part of the linear constraints stored in an AffineConstraints object
674  // /// and the vector k is the vector of corresponding inhomogeneities
675  // ///
676  // /// Eg. Dirichlet BC's would have zero-rows in C and non-zero rows in k
677  // /// and hanging-nodes would be linearly constrained through non-zero rows within C.
678  // ///
679  // /// 1. (Ct A_unconstrained C + Id_c) y = Ct (b - Ak)
680  // /// 2. x = C y + k
681  // ///
682  // /// b are the forces, which == 0
683  // /// k are the inhomogeneous
684  // /// Id_c Identity on the subspace of constrained degrees of freedom.
685  // ///
686  // /// The above steps 1. and 2. solve the real constrained system A_constrained x = b_constrained
687  // /// Although possible to assemble and solve, we will be interested in the derivative with respect
688  // /// to the inhomogeneity vector k, which is more easily recoverable through formulation 1. and 2.,
689  // /// than the assembly of the constrained system.
690  // ///
691  // /// y = - inverse(Ct A_unconstrained C + Id_c) Ct A k
692  // /// x = - C inverse(Ct A_unconstrained C + Id_c) Ct A k + k
693  // /// dx/dk = - C inverse(Ct A_unconstrained C + Id_c) Ct A + I
694  // using trilinos_vector_type = dealii::LinearAlgebra::distributed::Vector<double>;
695  // using payload_type = dealii::TrilinosWrappers::internal::LinearOperatorImplementation::TrilinosPayload;
696  // const auto op_a = dealii::linear_operator<trilinos_vector_type,trilinos_vector_type,payload_type>(system_matrix_unconstrained);
697  // const auto op_amod = dealii::constrained_linear_operator(all_constraints, op_a);
698  // const auto C = distribute_constraints_linear_operator(all_constraints, op_a);
699  // const auto Ct = transpose_operator(C);
700  // const auto Id_c = project_to_constrained_linear_operator(all_constraints, op_a);
701 
702  // const auto &rhs_vector = input_vector;
703 
704  // // Build RHS.
705  // dealii::LinearAlgebra::distributed::Vector<double> CtArhs;
706  // CtArhs.reinit(rhs_vector);
707  // CtArhs = Ct*op_a*rhs_vector;
708 
709  // // Solution.
710  // dealii::LinearAlgebra::distributed::Vector<double> op_inv_CtArhs(rhs_vector);
711  // all_constraints.set_zero(op_inv_CtArhs);
712 
713  // // Solve modified system.
714  // dealii::deallog.depth_console(0);
715  // solver.solve(op_amod, op_inv_CtArhs, CtArhs, precondition);
716 
717  // // Apply boundary condition
718  // output_vector = C*op_inv_CtArhs;
719  // output_vector *= -1.0;
720  // output_vector += rhs_vector;
721  // }
722 
723  // template <int dim, typename real>
724  // void
725  // LinearElasticity<dim,real>
726  // ::apply_dXvdXvs(
727  // std::vector<dealii::LinearAlgebra::distributed::Vector<double>> &list_of_vectors,
728  // dealii::TrilinosWrappers::SparseMatrix &output_matrix)
729  // {
730  // assemble_system();
731 
732  // const unsigned int n_rows = dof_handler.n_dofs();
733  // const unsigned int n_cols = list_of_vectors.size();
734  // //const unsigned int max_per_row = n_cols;
735 
736  // const dealii::IndexSet &row_part = dof_handler.locally_owned_dofs();
737  // dealii::DoFTools::extract_locally_relevant_dofs(dof_handler, locally_relevant_dofs);
738 
739  // dealii::DynamicSparsityPattern full_dsp(n_rows, n_cols, row_part);
740  // for (const auto &i_row: row_part) {
741  // for (unsigned int i_col = 0; i_col < n_cols; ++i_col) {
742  // full_dsp.add(i_row, i_col);
743  // }
744  // }
745  // dealii::SparsityTools::distribute_sparsity_pattern(full_dsp, dof_handler.locally_owned_dofs(), mpi_communicator, locally_relevant_dofs);
746 
747  // dealii::SparsityPattern full_sp;
748  // full_sp.copy_from(full_dsp);
749 
750  // const dealii::IndexSet col_part = dealii::Utilities::MPI::create_evenly_distributed_partitioning(MPI_COMM_WORLD,n_cols);
751 
752  // output_matrix.reinit(row_part, col_part, full_sp, mpi_communicator);
753 
754  // dealii::SolverControl solver_control(20000, 1e-14 * system_rhs.l2_norm());
755  // dealii::SolverGMRES<dealii::LinearAlgebra::distributed::Vector<double>> solver(solver_control);
756  // dealii::TrilinosWrappers::PreconditionJacobi precondition;
757  // precondition.initialize(system_matrix_unconstrained);
758 
759  // /// The use of the constrained linear operator is heavily discussed in:
760  // /// https://www.dealii.org/current/doxygen/deal.II/group__constraints.html
761  // /// Given affine constraints such that x = C y + k
762  // /// where C describes the homogeneous part of the linear constraints stored in an AffineConstraints object
763  // /// and the vector k is the vector of corresponding inhomogeneities
764  // ///
765  // /// Eg. Dirichlet BC's would have zero-rows in C and non-zero rows in k
766  // /// and hanging-nodes would be linearly constrained through non-zero rows within C.
767  // ///
768  // /// 1. (Ct A_unconstrained C + Id_c) y = Ct (b - Ak)
769  // /// 2. x = C y + k
770  // ///
771  // /// b are the forces, which == 0
772  // /// k are the inhomogeneous
773  // /// Id_c Identity on the subspace of constrained degrees of freedom.
774  // ///
775  // /// The above steps 1. and 2. solve the real constrained system A_constrained x = b_constrained
776  // /// Although possible to assemble and solve, we will be interested in the derivative with respect
777  // /// to the inhomogeneity vector k, which is more easily recoverable through formulation 1. and 2.,
778  // /// than the assembly of the constrained system.
779  // ///
780  // /// y = - inverse(Ct A_unconstrained C + Id_c) Ct A k
781  // /// x = - C inverse(Ct A_unconstrained C + Id_c) Ct A k + k
782  // /// dx/dk = - C inverse(Ct A_unconstrained C + Id_c) Ct A + I
783  // using trilinos_vector_type = dealii::LinearAlgebra::distributed::Vector<double>;
784  // using payload_type = dealii::TrilinosWrappers::internal::LinearOperatorImplementation::TrilinosPayload;
785  // const auto op_a = dealii::linear_operator<trilinos_vector_type,trilinos_vector_type,payload_type>(system_matrix_unconstrained);
786  // const auto op_amod = dealii::constrained_linear_operator(all_constraints, op_a);
787  // const auto C = distribute_constraints_linear_operator(all_constraints, op_a);
788  // const auto Ct = transpose_operator(C);
789  // const auto Id_c = project_to_constrained_linear_operator(all_constraints, op_a);
790 
791  // dXvdXs.clear();
792  // pcout << "Applying for [dXvdXs] onto " << list_of_vectors.size() << " vectors..." << std::endl;
793 
794  // unsigned int col = 0;
795  // for (auto &rhs_vector: list_of_vectors) {
796 
797  // // Build RHS.
798  // dealii::LinearAlgebra::distributed::Vector<double> CtArhs;
799  // CtArhs.reinit(rhs_vector);
800  // CtArhs = Ct*op_a*rhs_vector;
801 
802  // // Solution.
803  // dealii::LinearAlgebra::distributed::Vector<double> op_inv_CtArhs(rhs_vector);
804  // all_constraints.set_zero(op_inv_CtArhs);
805 
806  // // Solve modified system.
807  // dealii::deallog.depth_console(0);
808  // solver.solve(op_amod, op_inv_CtArhs, CtArhs, precondition);
809 
810  // // Apply boundary condition
811  // dealii::LinearAlgebra::distributed::Vector<double> dXvdXs_i_trilinos;
812  // dXvdXs_i_trilinos.reinit(CtArhs);
813  // dXvdXs_i_trilinos = C*op_inv_CtArhs;
814  // dXvdXs_i_trilinos *= -1.0;
815  // dXvdXs_i_trilinos += rhs_vector;
816 
817  // dXvdXs.push_back(dXvdXs_i_trilinos);
818 
819  // for (const auto &row: dof_handler.locally_owned_dofs()) {
820  // output_matrix.set(row, col, dXvdXs[col][row]);
821  // }
822  // col++;
823  // }
824  // output_matrix.compress(dealii::VectorOperation::insert);
825 
826  // }
827 
828  // template <int dim, typename real>
829  // void
830  // LinearElasticity<dim,real>
831  // ::apply_dXvdXvs_transpose(
832  // const dealii::LinearAlgebra::distributed::Vector<double> &input_vector,
833  // dealii::LinearAlgebra::distributed::Vector<double> &output_vector)
834  // {
835  // pcout << "Applying [transpose(dXvdXvs)] onto a vector..." << std::endl;
836  // assemble_system();
837 
838  // dealii::SolverControl solver_control(20000, 1e-14 * system_rhs.l2_norm());
839  // dealii::SolverGMRES<dealii::LinearAlgebra::distributed::Vector<double>> solver(solver_control);
840  // dealii::TrilinosWrappers::PreconditionJacobi precondition;
841  // precondition.initialize(system_matrix_unconstrained);
842 
843  // /// The use of the constrained linear operator is heavily discussed in:
844  // /// https://www.dealii.org/current/doxygen/deal.II/group__constraints.html
845  // /// x = - C inverse(Ct A_unconstrained C + Id_c) Ct A k + k
846  // /// dx/dk = - C inverse(Ct A_unconstrained C + Id_c) Ct A + I
847  // /// transpose(dx/dk) = - transpose(A) C transpose(inverse(Ct A_unconstrained C + Id_c)) Ct + I
848  // using trilinos_vector_type = dealii::LinearAlgebra::distributed::Vector<double>;
849  // using payload_type = dealii::TrilinosWrappers::internal::LinearOperatorImplementation::TrilinosPayload;
850  // const auto op_a = dealii::linear_operator<trilinos_vector_type,trilinos_vector_type,payload_type>(system_matrix_unconstrained);
851  // const auto op_at = transpose_operator(op_a);
852  // const auto op_amod_trans = transpose_operator(dealii::constrained_linear_operator(all_constraints, op_a));
853  // const auto C = distribute_constraints_linear_operator(all_constraints, op_a);
854  // const auto Ct = transpose_operator(C);
855  // const auto Id_c = project_to_constrained_linear_operator(all_constraints, op_a);
856 
857  // // Build RHS.
858  // dealii::LinearAlgebra::distributed::Vector<double> Ctrhs;
859  // Ctrhs.reinit(input_vector);
860  // Ctrhs = Ct*input_vector;
861 
862  // // Solution.
863  // dealii::LinearAlgebra::distributed::Vector<double> op_inv_Ctrhs(input_vector);
864  // all_constraints.set_zero(op_inv_Ctrhs);
865 
866  // // Solve modified system.
867  // dealii::deallog.depth_console(0);
868  // solver.solve(op_amod_trans, op_inv_Ctrhs, Ctrhs, precondition);
869 
870  // // Apply boundary condition
871  // output_vector.reinit(Ctrhs);
872  // output_vector = op_at*C*op_inv_Ctrhs;
873  // output_vector *= -1.0;
874  // output_vector += input_vector;
875 
876  // //output_vector.compress(dealii::VectorOperation::insert);
877 
878  // }
879 
880  template <int dim, typename real>
882  {
883  std::vector<dealii::LinearAlgebra::distributed::Vector<double>> unit_rhs_vector;
884  const unsigned int n_dirichlet_constraints = boundary_displacements_vector.size();
885  dXvdXs.clear();
886  pcout << "Solving for dXvdXs with " << n_dirichlet_constraints << " surface nodes..." << std::endl;
887  pcout << "*******************************************************" << std::endl;
888  pcout << "Are you sure that you need to for the dXvdXs matrix...?" << std::endl;
889  pcout << "Ideally, you would apply dXvdXs onto a vector such that" << std::endl;
890  pcout << "only 1 linear system needs to be solved. " << std::endl;
891  pcout << "*******************************************************" << std::endl;
892  for (unsigned int iconstraint = 0; iconstraint < n_dirichlet_constraints; iconstraint++) {
893 
894  dealii::LinearAlgebra::distributed::Vector<double> unit_rhs;
895  unit_rhs.reinit(system_rhs);
896 
897  if (boundary_ids_vector.locally_owned_elements().is_element(iconstraint)) {
898  const unsigned int constrained_row = boundary_ids_vector[iconstraint];
899  unit_rhs[constrained_row] = 1.0;
900  }
901  unit_rhs.update_ghost_values();
902 
903  unit_rhs_vector.push_back(unit_rhs);
904  }
905  dealii::TrilinosWrappers::SparseMatrix dXvdXs_matrix;
906  apply_dXvdXvs(unit_rhs_vector, dXvdXs_matrix);
907  }
908 
909  // template <int dim, typename real>
910  // void LinearElasticity<dim,real>::evaluate_dXvdXs()
911  // {
912  // VectorType trilinos_solution(system_rhs);
913 
914  // all_constraints.set_zero(trilinos_solution);
915 
916  // dealii::SolverControl solver_control(20000, 1e-14 * system_rhs.l2_norm());
917  // dealii::SolverGMRES<VectorType> solver(solver_control);
918  // dealii::TrilinosWrappers::PreconditionJacobi precondition;
919  // precondition.initialize(system_matrix_unconstrained);
920  // //precondition.initialize(system_matrix);
921  // //solver.solve(system_matrix, trilinos_solution, system_rhs, precondition);
922 
923  // //all_constraints.distribute(trilinos_solution);
924 
925  // /// The use of the constrained linear operator is heavily discussed in:
926  // /// https://www.dealii.org/current/doxygen/deal.II/group__constraints.html
927  // using trilinos_vector_type = VectorType;
928  // using payload_type = dealii::TrilinosWrappers::internal::LinearOperatorImplementation::TrilinosPayload;
929  // const auto op_a = dealii::linear_operator<trilinos_vector_type,trilinos_vector_type,payload_type>(system_matrix_unconstrained);
930  // const auto op_amod = dealii::constrained_linear_operator(all_constraints, op_a);
931  // const auto C = distribute_constraints_linear_operator(all_constraints, op_a);
932  // const auto Ct = transpose_operator(C);
933  // // const auto Id_c = project_to_constrained_linear_operator(all_constraints, op_a);
934 
935  // const unsigned int n_dirichlet_constraints = boundary_displacements_vector.size();
936  // dXvdXs.clear();
937  // pcout << "Solving for dXvdXs with " << n_dirichlet_constraints << "surface nodes..." << std::endl;
938  // for (unsigned int iconstraint = 0; iconstraint < n_dirichlet_constraints; iconstraint++) {
939 
940  // VectorType unit_rhs, CtArhs, dXvdXs_i_trilinos, op_inv_CtArhs;
941  // unit_rhs.reinit(trilinos_solution);
942  // CtArhs.reinit(trilinos_solution);
943 
944  // if (boundary_ids_vector.locally_owned_elements().is_element(iconstraint)) {
945  // const unsigned int constrained_row = boundary_ids_vector[iconstraint];
946  // unit_rhs[constrained_row] = 1.0;
947  // }
948  // CtArhs = Ct*op_a*unit_rhs;
949 
950  // op_inv_CtArhs.reinit(CtArhs);
951 
952  // dealii::deallog.depth_console(0);
953  // solver.solve(op_amod, op_inv_CtArhs, CtArhs, precondition);
954 
955  // //pcout << "Surface Dirichlet constraint " << iconstraint+1 << " out of " << n_dirichlet_constraints
956  // // << " DoF constrained: " << iconstraint
957  // // << " Solver converged in " << solver_control.last_step() << " iterations." << std::endl;
958 
959  // // dXvdXs_i_trilinos.reinit(CtArhs);
960  // // dXvdXs_i_trilinos = C*op_inv_CtArhs;
961  // // dXvdXs_i_trilinos *= -1.0;
962  // // dXvdXs_i_trilinos.add(unit_rhs);
963 
964  // // //dXvdXs.push_back(dXvdXs_i_trilinos);
965  // // dealii::LinearAlgebra::ReadWriteVector<double> rw_vector;
966  // // rw_vector.reinit(dXvdXs_i_trilinos);
967 
968  // // dealii::LinearAlgebra::distributed::Vector<double> dXvdXs_i;
969  // // dXvdXs_i.reinit(displacement_solution);
970  // // dXvdXs_i.import(rw_vector, dealii::VectorOperation::insert);
971  // // dXvdXs.push_back(dXvdXs_i);
972 
973  // dXvdXs_i_trilinos.reinit(CtArhs);
974  // dXvdXs_i_trilinos = C*op_inv_CtArhs;
975  // dXvdXs_i_trilinos *= -1.0;
976  // dXvdXs_i_trilinos.add(1.0,unit_rhs);
977  // dXvdXs.push_back(dXvdXs_i_trilinos);
978  // }
979  // // for (unsigned int row = 0; row < dof_handler.n_dofs(); row++) {
980  // // bool is_locally_inhomogeneously_constrained = false;
981  // // bool is_inhomogeneously_constrained = false;
982  // // if (all_constraints.can_store_line(row)) {
983  // // if (all_constraints.is_inhomogeneously_constrained(row)) {
984  // // is_locally_inhomogeneously_constrained = true;
985  // // }
986  // // }
987  // // MPI_Allreduce(&is_locally_inhomogeneously_constrained, &is_inhomogeneously_constrained, 1, MPI::BOOL, MPI_LOR, MPI_COMM_WORLD);
988  // // if (is_inhomogeneously_constrained) {
989  // // n_inhomogeneous_constraints++;
990  // // }
991  // // }
992  // // dXvdXs.clear();
993  // // int i_inhomogeneous_constraints = 0;
994  // // for (unsigned int row = 0; row < dof_handler.n_dofs(); row++) {
995  // // bool is_locally_inhomogeneously_constrained = false;
996  // // bool is_inhomogeneously_constrained = false;
997  // // if (all_constraints.can_store_line(row)) {
998  // // if (all_constraints.is_inhomogeneously_constrained(row)) {
999  // // is_locally_inhomogeneously_constrained = true;
1000  // // }
1001  // // }
1002  // // MPI_Allreduce(&is_locally_inhomogeneously_constrained, &is_inhomogeneously_constrained, 1, MPI::BOOL, MPI_LOR, MPI_COMM_WORLD);
1003  // // if (is_inhomogeneously_constrained) {
1004  // // precondition.initialize(system_matrix_unconstrained);
1005  // // VectorType unit_rhs, CtArhs, dXvdXs_i_trilinos, op_inv_CtArhs;
1006  // // unit_rhs.reinit(trilinos_solution);
1007  // // CtArhs.reinit(trilinos_solution);
1008  // // if (locally_owned_dofs.is_element(row)) {
1009  // // unit_rhs[row] = 1.0;
1010  // // }
1011  // // CtArhs = Ct*op_a*unit_rhs;
1012 
1013  // // op_inv_CtArhs.reinit(CtArhs);
1014  // // solver.solve(op_amod, op_inv_CtArhs, CtArhs, precondition);
1015 
1016  // // dXvdXs_i_trilinos.reinit(CtArhs);
1017  // // dXvdXs_i_trilinos = C*op_inv_CtArhs;
1018  // // dXvdXs_i_trilinos *= -1.0;
1019  // // dXvdXs_i_trilinos.add(unit_rhs);
1020 
1021  // // pcout << "Inhomogeneous constraint " << ++i_inhomogeneous_constraints << " out of " << n_inhomogeneous_constraints
1022  // // << " DoF constrained: " << row
1023  // // << " Solver converged in " << solver_control.last_step() << " iterations." << std::endl;
1024 
1025  // // dealii::LinearAlgebra::ReadWriteVector<double> rw_vector;
1026  // // rw_vector.reinit(dXvdXs_i_trilinos);
1027 
1028  // // dealii::LinearAlgebra::distributed::Vector<double> dXvdXs_i;
1029  // // dXvdXs_i.reinit(displacement_solution);
1030  // // dXvdXs_i.import(rw_vector, dealii::VectorOperation::insert);
1031  // // dXvdXs.push_back(dXvdXs_i);
1032  // // }
1033  // // }
1034  // }
1035  // template <int dim, typename real>
1036  // unsigned int LinearElasticity<dim,real>::solve_linear_problem()
1037  // {
1038  // VectorType trilinos_solution(system_rhs);
1039 
1040  // all_constraints.set_zero(trilinos_solution);
1041 
1042  // // dealii::FullMatrix<double> fullA(system_matrix.m());
1043  // // fullA.copy_from(system_matrix);
1044  // // pcout<<"Dense matrix:"<<std::endl;
1045  // // if (pcout.is_active()) fullA.print_formatted(pcout.get_stream(), 3, true, 10, "0", 1., 0.);
1046  // // //trilinos_solution.print(std::cout, 4);
1047  // // system_rhs.print(std::cout, 4);
1048 
1049  // dealii::SolverControl solver_control(20000, 1e-14 * system_rhs.l2_norm());
1050  // dealii::SolverGMRES<VectorType> solver(solver_control);
1051  // dealii::TrilinosWrappers::PreconditionJacobi precondition;
1052  // //precondition.initialize(system_matrix);
1053  // //solver.solve(system_matrix, trilinos_solution, system_rhs, precondition);
1054 
1055  // //all_constraints.distribute(trilinos_solution);
1056 
1057  // using trilinos_vector_type = VectorType;
1058  // using payload_type = dealii::TrilinosWrappers::internal::LinearOperatorImplementation::TrilinosPayload;
1059  // const auto op_a = dealii::linear_operator<trilinos_vector_type,trilinos_vector_type,payload_type>(system_matrix_unconstrained);
1060  // //const auto op_a = dealii::linear_operator(system_matrix_unconstrained);
1061  // const auto op_amod = dealii::constrained_linear_operator(all_constraints, op_a);
1062  // VectorType rhs_mod
1063  // = dealii::constrained_right_hand_side(all_constraints, op_a, system_rhs_unconstrained);
1064  // precondition.initialize(system_matrix_unconstrained);
1065  // solver.solve(op_amod, trilinos_solution, rhs_mod, precondition);
1066 
1067  //
1068  // // Should be the same as distribute
1069  // // {
1070  // // VectorType trilinos_solution2(trilinos_solution);
1071 
1072  // // const auto C = distribute_constraints_linear_operator(all_constraints, op_a);
1073  // // VectorType inhomogeneity_vector(trilinos_solution);
1074  // // for (unsigned int i=0; i<dof_handler.n_dofs(); i++) {
1075  // // if (inhomogeneity_vector.in_local_range(i)) {
1076  // // inhomogeneity_vector[i] = all_constraints.get_inhomogeneity(i);
1077  // // }
1078  // // }
1079 
1080  // // trilinos_solution2 = C*trilinos_solution + inhomogeneity_vector;
1081  // // trilinos_solution = trilinos_solution2;
1082  // // }
1083 
1084  // all_constraints.distribute(trilinos_solution);
1085 
1086  // // dealii::LinearAlgebra::ReadWriteVector<double> rw_vector;
1087  // // rw_vector.reinit(trilinos_solution);
1088  // // displacement_solution.import(rw_vector, dealii::VectorOperation::insert);
1089  // displacement_solution = trilinos_solution;
1090  // return solver_control.last_step();
1091  // }
1092 
1094 } // namespace MeshMover
1095 
1096 } // namespace PHiLiP
dealii::LinearAlgebra::distributed::Vector< double > system_rhs_unconstrained
const dealii::LinearAlgebra::distributed::Vector< int > & boundary_ids_vector
dealii::TrilinosWrappers::SparseMatrix system_matrix
System matrix corresponding to linearized elasticity problem.
dealii::ConditionalOStream pcout
ConditionalOStream for output.
dealii::IndexSet locally_owned_dofs
Locally owned DoFs.
const std::shared_ptr< dealii::MappingFEField< dim, dim, VectorType, DoFHandlerType > > mapping_fe_field
MappingFEField corresponding to curved mesh.
Files for the baseline physics.
Definition: ADTypes.hpp:10
dealii::IndexSet locally_relevant_dofs
Locally relevant DoFs.
void apply_dXvdXvs_transpose(const dealii::LinearAlgebra::distributed::Vector< double > &input_vector, dealii::LinearAlgebra::distributed::Vector< double > &output_vector)
dealii::LinearAlgebra::distributed::Vector< double > tensor_to_vector(const std::vector< dealii::Tensor< 1, dim, real >> &boundary_displacements_tensors) const
void apply_dXvdXvs(std::vector< dealii::LinearAlgebra::distributed::Vector< double >> &list_of_vectors, dealii::TrilinosWrappers::SparseMatrix &output_matrix)
dealii::parallel::distributed::Triangulation< dim > Triangulation
dealii::TrilinosWrappers::SparseMatrix system_matrix_unconstrained
std::vector< dealii::types::global_dof_index > local_dofs_per_process
List of number of DoFs per process.
dealii::LinearAlgebra::distributed::Vector< double > system_rhs
LinearElasticity(const Triangulation &_triangulation, const std::shared_ptr< dealii::MappingFEField< dim, dim, VectorType, DoFHandlerType >> mapping_fe_field, const DoFHandlerType &_dof_handler, const dealii::LinearAlgebra::distributed::Vector< int > &_boundary_ids_vector, const dealii::LinearAlgebra::distributed::Vector< double > &_boundary_displacements_vector)
Constructor.
dealii::DoFHandler< dim > DoFHandlerType
DoFHandler.
void setup_system()
Allocation and boundary condition setup.
void assemble_system()
Assemble the system and its right-hand side.
const DoFHandlerType & dof_handler
Same DoFHandler as the HighOrderGrid.
dealii::AffineConstraints< double > hanging_node_constraints
dealii::LinearAlgebra::distributed::Vector< real > VectorType
Distributed vector of double.
dealii::AffineConstraints< double > all_constraints
const dealii::QGauss< dim > quadrature_formula
Integration strength of the mesh order plus one.
std::vector< dealii::LinearAlgebra::distributed::Vector< double > > dXvdXs
const unsigned int n_mpi_processes
Number of MPI processes.
const dealii::LinearAlgebra::distributed::Vector< double > & boundary_displacements_vector