Doxygen API reference documentation for ideal.II
vector_tools.hh
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2022 - 2023 by the ideal.II authors
4 //
5 // This file is part of the ideal.II library.
6 //
7 // The ideal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 3.0 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of ideal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef INCLUDE_IDEAL_II_NUMERICS_VECTOR_TOOLS_HH_
17 #define INCLUDE_IDEAL_II_NUMERICS_VECTOR_TOOLS_HH_
18 
19 #include <deal.II/base/config.h>
20 
21 #include <ideal.II/base/quadrature_lib.hh>
22 
23 #include <ideal.II/dofs/slab_dof_handler.hh>
24 
25 #include <deal.II/fe/fe_values.h>
26 
27 #include <deal.II/lac/affine_constraints.h>
28 #include <deal.II/lac/trilinos_vector.h>
29 #include <deal.II/lac/vector.h>
30 
31 #include <deal.II/numerics/vector_tools.h>
32 
33 #include <memory>
34 
36 {
37 
54  template <int dim, typename Number>
55  void
57  idealii::slab::DoFHandler<dim> &dof_handler,
58  const dealii::types::boundary_id boundary_component,
59  dealii::Function<dim, Number> &boundary_function,
60  std::shared_ptr<dealii::AffineConstraints<Number>> spacetime_constraints,
61  const dealii::ComponentMask &component_mask = dealii::ComponentMask());
62 
80  template <int dim, typename Number = double>
81  void
83  dealii::IndexSet space_relevant_dofs,
84  idealii::slab::DoFHandler<dim> &dof_handler,
85  const dealii::types::boundary_id boundary_component,
86  dealii::Function<dim, Number> &boundary_function,
87  std::shared_ptr<dealii::AffineConstraints<Number>> spacetime_constraints,
88  const dealii::ComponentMask &component_mask = dealii::ComponentMask())
89  {
90  auto space_constraints =
91  std::make_shared<dealii::AffineConstraints<Number>>();
92  space_constraints->reinit(space_relevant_dofs);
93  dealii::Quadrature<1> quad_time(
94  dof_handler.temporal()->get_fe(0).get_unit_support_points());
95  dealii::FEValues<1> fev(dof_handler.temporal()->get_fe(0),
96  quad_time,
97  dealii::update_quadrature_points);
98 
99  unsigned int n_space_dofs = dof_handler.n_dofs_space();
100  unsigned int time_dof = 0;
101  std::vector<dealii::types::global_dof_index> local_indices(
102  dof_handler.dofs_per_cell_time());
103  // loop over time cells instead
104  for (const auto &cell_time :
105  dof_handler.temporal()->active_cell_iterators())
106  {
107  fev.reinit(cell_time);
108 
109  cell_time->get_dof_indices(local_indices);
110  for (unsigned int q = 0; q < quad_time.size(); q++)
111  {
112  space_constraints->clear();
113  time_dof = local_indices[q];
114  boundary_function.set_time(fev.quadrature_point(q)[0]);
115  dealii::VectorTools::interpolate_boundary_values(
116  *dof_handler.spatial(),
117  boundary_component,
118  boundary_function,
119  *space_constraints,
120  component_mask);
121 
122  for (auto id = space_relevant_dofs.begin();
123  id != space_relevant_dofs.end();
124  id++)
125  {
126  // check if this is a constrained dof
127  if (space_constraints->is_constrained(*id))
128  {
129  const std::vector<std::pair<dealii::types::global_dof_index,
130  double>> *entries =
131  space_constraints->get_constraint_entries(*id);
132  spacetime_constraints->add_line(*id +
133  time_dof * n_space_dofs);
134  // non Dirichlet constraint
135  if (entries->size() > 0)
136  {
137  for (auto entry : *entries)
138  {
139  std::cout << entry.first << "," << entry.second
140  << std::endl;
141  spacetime_constraints->add_entry(
142  *id + time_dof * n_space_dofs,
143  entry.first + time_dof * n_space_dofs,
144  entry.second);
145  }
146  }
147  else
148  {
149  spacetime_constraints->set_inhomogeneity(
150  *id + time_dof * n_space_dofs,
151  space_constraints->get_inhomogeneity(*id));
152  }
153  }
154  }
155  }
156  }
157  }
158 
175  template <int dim, typename Number>
176  void
178  idealii::slab::DoFHandler<dim> &dof_handler,
179  unsigned int first_vector_component,
180  dealii::Function<dim, Number> &boundary_function,
181  const dealii::types::boundary_id boundary_component,
182  std::shared_ptr<dealii::AffineConstraints<Number>> spacetime_constraints);
183 
191  void
192  extract_subvector_at_time_dof(const dealii::Vector<double> &spacetime_vector,
193  dealii::Vector<double> &space_vector,
194  unsigned int dof_index)
195  {
196  unsigned int n_dofs_space = space_vector.size();
197  for (unsigned int i = 0; i < n_dofs_space; i++)
198  {
199  space_vector[i] = spacetime_vector[i + dof_index * n_dofs_space];
200  }
201  }
202 
203 #ifdef DEAL_II_WITH_MPI
211  void
213  const dealii::TrilinosWrappers::MPI::Vector &spacetime_vector,
214  dealii::TrilinosWrappers::MPI::Vector &space_vector,
215  unsigned int dof_index)
216  {
217  dealii::IndexSet space_owned = space_vector.locally_owned_elements();
218  unsigned int n_dofs_space = space_vector.size();
219  dealii::TrilinosWrappers::MPI::Vector tmp;
220  tmp.reinit(space_owned, space_vector.get_mpi_communicator());
221  for (auto id = space_owned.begin(); id != space_owned.end(); id++)
222  {
223  tmp[*id] = spacetime_vector[*id + dof_index * n_dofs_space];
224  }
225  space_vector = tmp;
226  }
227 #endif
238  template <int dim>
239  void
241  slab::DoFHandler<dim> &dof_handler,
242  const dealii::Vector<double> &spacetime_vector,
243  dealii::Vector<double> &space_vector,
244  const double t)
245  {
246  space_vector = 0;
247  unsigned int n_dofs_space = space_vector.size();
248  double left = 0;
249  double right = 0;
250  for (auto cell : dof_handler.temporal()->active_cell_iterators())
251  {
252  left = cell->face(0)->center()(0);
253  right = cell->face(1)->center()(0);
254  if (t < left || t > right)
255  {
256  continue;
257  }
258  double _t = (t - left) / (right - left);
259  dealii::Point<1> qpoint(_t);
260  const dealii::Quadrature<1> time_qf(qpoint);
261  dealii::FEValues<1> time_values(dof_handler.temporal()->get_fe(),
262  time_qf,
263  dealii::update_values);
264  time_values.reinit(cell);
265  unsigned int offset =
266  cell->index() * dof_handler.dofs_per_cell_time() * n_dofs_space;
267  for (unsigned int ii = 0; ii < dof_handler.dofs_per_cell_time(); ii++)
268  {
269  double factor = time_values.shape_value(ii, 0);
270  for (unsigned int i = 0; i < n_dofs_space; i++)
271  {
272  space_vector[i] +=
273  spacetime_vector[i + ii * n_dofs_space + offset] * factor;
274  }
275  }
276  }
277  }
278 
279 #ifdef DEAL_II_WITH_MPI
290  template <int dim>
291  void
293  slab::DoFHandler<dim> &dof_handler,
294  const dealii::TrilinosWrappers::MPI::Vector &spacetime_vector,
295  dealii::TrilinosWrappers::MPI::Vector &space_vector,
296  const double t)
297  {
298  space_vector = 0;
299  unsigned int n_dofs_space = space_vector.size();
300  double left = 0;
301  double right = 0;
302  for (auto cell : dof_handler.temporal()->active_cell_iterators())
303  {
304  left = cell->face(0)->center()(0);
305  right = cell->face(1)->center()(0);
306  if (t < left || t > right)
307  {
308  continue;
309  }
310  double _t = (t - left) / (right - left);
311  dealii::Point<1> qpoint(_t);
312  const dealii::Quadrature<1> time_qf(qpoint);
313  dealii::FEValues<1> time_values(dof_handler.temporal()->get_fe(),
314  time_qf,
315  dealii::update_values);
316  time_values.reinit(cell);
317  dealii::IndexSet space_owned = space_vector.locally_owned_elements();
318  unsigned int n_dofs_space = space_vector.size();
319  dealii::TrilinosWrappers::MPI::Vector tmp;
320  tmp.reinit(space_owned, space_vector.get_mpi_communicator());
321 
322  for (unsigned int ii = 0; ii < dof_handler.dofs_per_cell_time(); ii++)
323  {
324  double factor = time_values.shape_value(ii, 0);
325  for (auto id = space_owned.begin(); id != space_owned.end(); id++)
326  {
327  tmp[*id] += spacetime_vector[*id + ii * n_dofs_space] * factor;
328  }
329  space_vector = tmp;
330  }
331  }
332  }
333 #endif
334 
345  template <int dim>
346  double
348  slab::DoFHandler<dim> &dof_handler,
349  dealii::Vector<double> &spacetime_vector,
350  dealii::Function<dim, double> &exact_solution,
352 
353  // #ifdef DEAL_II_WITH_MPI
364  template <int dim>
365  double
367  slab::DoFHandler<dim> &dof_handler,
368  dealii::TrilinosWrappers::MPI::Vector &spacetime_vector,
369  dealii::Function<dim, double> &exact_solution,
371 
372  // #endif
373 
374 } // namespace idealii::slab::VectorTools
375 
376 #endif /* INCLUDE_IDEAL_II_VECTOR_TOOLS_HH_ */
Actual DoFHandler for a specific slab.
Definition: slab_dof_handler.hh:43
std::shared_ptr< dealii::DoFHandler< 1 > > temporal()
The underlying temporal dof handler.
std::shared_ptr< dealii::DoFHandler< dim > > spatial()
The underlying spatial dof handler.
unsigned int n_dofs_space()
Number of spatial degrees of fredom on this slab.
unsigned int dofs_per_cell_time()
Number of temporal dofs in a single element/interval.
The base class for quadrature formulae in space and time.
Definition: spacetime_quadrature.hh:35
Collection of functions working on space-time slab Vectors.
Definition: idealii.hh:72
void extract_subvector_at_time_point(slab::DoFHandler< dim > &dof_handler, const dealii::Vector< double > &spacetime_vector, dealii::Vector< double > &space_vector, const double t)
Get the spatial subvector at a specific time point of the corresponding slab. The result is calculate...
Definition: vector_tools.hh:240
void project_boundary_values_curl_conforming_l2(idealii::slab::DoFHandler< dim > &dof_handler, unsigned int first_vector_component, dealii::Function< dim, Number > &boundary_function, const dealii::types::boundary_id boundary_component, std::shared_ptr< dealii::AffineConstraints< Number >> spacetime_constraints)
Compute space-time constraints on the solution corresponding to Hcurl Dirichlet conditions....
void interpolate_boundary_values(idealii::slab::DoFHandler< dim > &dof_handler, const dealii::types::boundary_id boundary_component, dealii::Function< dim, Number > &boundary_function, std::shared_ptr< dealii::AffineConstraints< Number >> spacetime_constraints, const dealii::ComponentMask &component_mask=dealii::ComponentMask())
Compute space-time constraints on the solution corresponding to Dirichlet conditions....
double calculate_L2L2_squared_error_on_slab(slab::DoFHandler< dim > &dof_handler, dealii::Vector< double > &spacetime_vector, dealii::Function< dim, double > &exact_solution, spacetime::Quadrature< dim > &quad)
calculate the L2 inner product of (u-u_{kh}) with itself.
void extract_subvector_at_time_dof(const dealii::Vector< double > &spacetime_vector, dealii::Vector< double > &space_vector, unsigned int dof_index)
Get the spatial subvector of a specific temporal dof of the corresponding slab.
Definition: vector_tools.hh:192