Fluid structure interaction suite
projection_operator.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2022 by Luca Heltai
4 //
5 // This file is part of the FSI-suite platform, based on the deal.II library.
6 //
7 // The FSI-suite platform is free software; you can use it, redistribute it,
8 // and/or modify it under the terms of the GNU Lesser General Public License as
9 // published by the Free Software Foundation; either version 3.0 of the License,
10 // or (at your option) any later version. The full text of the license can be
11 // found in the file LICENSE at the top level of the FSI-suite platform
12 // distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef projection_operator_h
17 #define projection_operator_h
18 
19 #include <deal.II/base/config.h>
20 
23 #include <deal.II/lac/vector.h>
24 namespace dealii
25 {
72  template <
73  typename Range,
74  typename Domain,
78  const Range &range_exemplar,
79  const std::vector<std::reference_wrapper<const Domain>> &local_basis,
80  const Domain *domain_exemplar = nullptr,
81  const Payload &payload = Payload())
82  {
84  linear_operator.vmult = [range_exemplar, local_basis](Range &dst,
85  const Domain &src) {
86  static const auto id = range_exemplar.locally_owned_elements();
87  AssertDimension(local_basis.size(), id.n_elements());
88  unsigned int i = 0;
89  for (const auto j : id)
90  dst[j] = local_basis[i++].get() * src;
91  };
92 
93  linear_operator.vmult_add = [range_exemplar,
94  local_basis](Range &dst, const Domain &src) {
95  static const auto id = range_exemplar.locally_owned_elements();
96  AssertDimension(local_basis.size(), id.n_elements());
97  unsigned int i = 0;
98  for (const auto j : id)
99  dst[j] += local_basis[i++].get() * src;
100  };
101 
102  linear_operator.Tvmult = [range_exemplar, local_basis](Domain &dst,
103  const Range &src) {
104  static const auto id = range_exemplar.locally_owned_elements();
105  AssertDimension(local_basis.size(), id.n_elements());
106  dst = 0;
107  unsigned int i = 0;
108  for (const auto j : id)
109  dst.sadd(1.0, src[j], local_basis[i++]);
110  dst.compress(VectorOperation::add);
111  };
112 
113  linear_operator.Tvmult_add = [range_exemplar,
114  local_basis](Domain &dst, const Range &src) {
115  static const auto id = range_exemplar.locally_owned_elements();
116  AssertDimension(local_basis.size(), id.n_elements());
117  unsigned int i = 0;
118  for (const auto j : id)
119  dst.sadd(1.0, src[j], local_basis[i++]);
120  dst.compress(VectorOperation::add);
121  };
122 
123  linear_operator.reinit_range_vector = [range_exemplar](Range &dst,
124  bool fast) {
125  dst.reinit(range_exemplar, fast);
126  };
127 
128  if (domain_exemplar != nullptr)
129  linear_operator.reinit_domain_vector = [domain_exemplar](Domain &dst,
130  bool fast) {
131  dst.reinit(*domain_exemplar, fast);
132  };
133  else
134  {
135  Assert(local_basis.size() > 0,
136  ExcMessage("If domain_exemplar is not provided, "
137  "local_basis must contain at least one element."));
138  linear_operator.reinit_domain_vector = [local_basis](Domain &dst,
139  bool fast) {
140  dst.reinit(local_basis[0].get(), fast);
141  };
142  }
143  return linear_operator;
144  }
145 } // namespace dealii
146 #endif
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcMessage(std::string arg1)
LinearOperator< Range, Domain, TrilinosWrappers::internal::LinearOperatorImplementation::TrilinosPayload > linear_operator(const TrilinosWrappers::SparseMatrix &operator_exemplar, const Matrix &matrix)
LinearOperator< Range, Domain, Payload > projection_operator(const Range &range_exemplar, const std::vector< std::reference_wrapper< const Domain >> &local_basis, const Domain *domain_exemplar=nullptr, const Payload &payload=Payload())
Construct a LinearOperator object that projects a vector onto a basis.