OGS 6.2.0-97-g4a610c866
SimpleMatrixVectorProvider.cpp
Go to the documentation of this file.
1 
11 
12 #include <cassert>
13 #include <logog/include/logog.hpp>
14 
15 #include "BaseLib/Error.h"
16 #include "MathLib/LinAlg/LinAlg.h"
18 
19 namespace LinAlg = MathLib::LinAlg;
20 
21 namespace detail
22 {
23 
24 template<typename MatVec>
25 MatVec*
26 transfer(std::map<std::size_t, MatVec*>& from_unused,
27  std::map<MatVec*, std::size_t>& to_used,
28  typename std::map<std::size_t, MatVec*>::iterator it)
29 {
30  auto const id = it->first;
31  auto& ptr = it->second;
32 
33  auto res = to_used.emplace(ptr, id);
34  assert(res.second && "Emplacement failed.");
35  from_unused.erase(it);
36  return res.first->first;
37 }
38 
39 template<typename MatVec>
40 void
41 transfer(std::map<MatVec*, std::size_t>& from_used,
42  std::map<std::size_t, MatVec*>& to_unused,
43  typename std::map<MatVec*, std::size_t>::iterator it)
44 {
45  auto& ptr = it->first;
46  auto const id = it->second;
47 
48  auto res = to_unused.emplace(id, ptr);
49  assert(res.second && "Emplacement failed.");
50  (void) res; // res unused if NDEBUG
51  from_used.erase(it);
52 }
53 
54 } // namespace detail
55 
56 namespace NumLib
57 {
58 
59 template<bool do_search, typename MatVec, typename... Args>
60 std::pair<MatVec*, bool>
61 SimpleMatrixVectorProvider::
62 get_(std::size_t& id,
63  std::map<std::size_t, MatVec*>& unused_map,
64  std::map<MatVec*, std::size_t>& used_map,
65  Args&&... args)
66 {
67  if (id >= _next_id) {
68  OGS_FATAL("An obviously uninitialized id argument has been passed."
69  " This might not be a serious error for the current implementation,"
70  " but it might become one in the future."
71  " Hence, I will abort now.");
72  }
73 
74  if (do_search)
75  {
76  auto it = unused_map.find(id);
77  if (it != unused_map.end())
78  { // unused matrix/vector found
79  return {::detail::transfer(unused_map, used_map, it), false};
80  }
81  }
82 
83  // not searched or not found, so create a new one
84  id = _next_id++;
85  auto res = used_map.emplace(
86  MathLib::MatrixVectorTraits<MatVec>::newInstance(std::forward<Args>(args)...).release(),
87  id);
88  assert(res.second && "Emplacement failed.");
89  return { res.first->first, true };
90 }
91 
92 template<bool do_search, typename... Args>
93 std::pair<GlobalMatrix*, bool>
94 SimpleMatrixVectorProvider::
95 getMatrix_(std::size_t& id, Args&&... args)
96 {
97  return get_<do_search>(id, _unused_matrices, _used_matrices, std::forward<Args>(args)...);
98 }
99 
100 
101 GlobalMatrix&
102 SimpleMatrixVectorProvider::
103 getMatrix()
104 {
105  std::size_t id = 0u;
106  return *getMatrix_<false>(id).first;
107 }
108 
109 GlobalMatrix&
110 SimpleMatrixVectorProvider::
111 getMatrix(std::size_t& id)
112 {
113  return *getMatrix_<true>(id).first;
114 }
115 
116 GlobalMatrix&
117 SimpleMatrixVectorProvider::
118 getMatrix(MathLib::MatrixSpecifications const& ms)
119 {
120  std::size_t id = 0u;
121  return *getMatrix_<false>(id, ms).first;
122  // TODO assert that the returned object always is of the right size
123 }
124 
125 GlobalMatrix&
126 SimpleMatrixVectorProvider::
127 getMatrix(MathLib::MatrixSpecifications const& ms, std::size_t& id)
128 {
129  return *getMatrix_<true>(id, ms).first;
130  // TODO assert that the returned object always is of the right size
131 }
132 
133 GlobalMatrix&
134 SimpleMatrixVectorProvider::
135 getMatrix(GlobalMatrix const& A)
136 {
137  std::size_t id = 0u;
138  auto const& res = getMatrix_<false>(id, A);
139  if (!res.second)
140  { // no new object has been created
141  LinAlg::copy(A, *res.first);
142  }
143  return *res.first;
144 }
145 
146 GlobalMatrix&
147 SimpleMatrixVectorProvider::
148 getMatrix(GlobalMatrix const& A, std::size_t& id)
149 {
150  auto const& res = getMatrix_<true>(id, A);
151  if (!res.second)
152  { // no new object has been created
153  LinAlg::copy(A, *res.first);
154  }
155  return *res.first;
156 }
157 
158 void
159 SimpleMatrixVectorProvider::
160 releaseMatrix(GlobalMatrix const& A)
161 {
162  auto it = _used_matrices.find(const_cast<GlobalMatrix*>(&A));
163  if (it == _used_matrices.end()) {
164  OGS_FATAL("The given matrix has not been found. Cannot release it. Aborting.");
165  } else {
166  ::detail::transfer(_used_matrices, _unused_matrices, it);
167  }
168 }
169 
170 template<bool do_search, typename... Args>
171 std::pair<GlobalVector*, bool>
172 SimpleMatrixVectorProvider::
173 getVector_(std::size_t& id, Args&&... args)
174 {
175  return get_<do_search>(id, _unused_vectors, _used_vectors, std::forward<Args>(args)...);
176 }
177 
178 
179 GlobalVector&
180 SimpleMatrixVectorProvider::
181 getVector()
182 {
183  std::size_t id = 0u;
184  return *getVector_<false>(id).first;
185 }
186 
187 GlobalVector&
188 SimpleMatrixVectorProvider::
189 getVector(std::size_t& id)
190 {
191  return *getVector_<true>(id).first;
192 }
193 
194 GlobalVector&
195 SimpleMatrixVectorProvider::
196 getVector(MathLib::MatrixSpecifications const& ms)
197 {
198  std::size_t id = 0u;
199  return *getVector_<false>(id, ms).first;
200  // TODO assert that the returned object always is of the right size
201 }
202 
203 GlobalVector&
204 SimpleMatrixVectorProvider::
205 getVector(MathLib::MatrixSpecifications const& ms, std::size_t& id)
206 {
207  return *getVector_<true>(id, ms).first;
208  // TODO assert that the returned object always is of the right size
209 }
210 
211 GlobalVector&
212 SimpleMatrixVectorProvider::
213 getVector(GlobalVector const& x)
214 {
215  std::size_t id = 0u;
216  auto const& res = getVector_<false>(id, x);
217  if (!res.second)
218  { // no new object has been created
219  LinAlg::copy(x, *res.first);
220  }
221  return *res.first;
222 }
223 
224 GlobalVector&
225 SimpleMatrixVectorProvider::
226 getVector(GlobalVector const& x, std::size_t& id)
227 {
228  auto const& res = getVector_<true>(id, x);
229  if (!res.second)
230  { // no new object has been created
231  LinAlg::copy(x, *res.first);
232  }
233  return *res.first;
234 }
235 
236 void
237 SimpleMatrixVectorProvider::
238 releaseVector(GlobalVector const& x)
239 {
240  auto it = _used_vectors.find(const_cast<GlobalVector*>(&x));
241  if (it == _used_vectors.end()) {
242  OGS_FATAL("The given vector has not been found. Cannot release it. Aborting.");
243  } else {
244  ::detail::transfer(_used_vectors, _unused_vectors, it);
245  }
246 }
247 
248 SimpleMatrixVectorProvider::
249 ~SimpleMatrixVectorProvider()
250 {
251  if ((!_used_matrices.empty()) || (!_used_vectors.empty())) {
252  WARN("There are still some matrices and vectors in use."
253  " This might be an indicator of a possible waste of memory.");
254  }
255 
256  for (auto& id_ptr : _unused_matrices)
257  {
258  delete id_ptr.second;
259  }
260 
261  for (auto& ptr_id : _used_matrices)
262  {
263  delete ptr_id.first;
264  }
265 
266  for (auto& id_ptr : _unused_vectors)
267  {
268  delete id_ptr.second;
269  }
270 
271  for (auto& ptr_id : _used_vectors)
272  {
273  delete ptr_id.first;
274  }
275 }
276 
277 } // namespace NumLib
MatVec * transfer(std::map< std::size_t, MatVec *> &from_unused, std::map< MatVec *, std::size_t > &to_used, typename std::map< std::size_t, MatVec *>::iterator it)
void transfer(std::map< MatVec *, std::size_t > &from_used, std::map< std::size_t, MatVec *> &to_unused, typename std::map< MatVec *, std::size_t >::iterator it)
#define OGS_FATAL(fmt,...)
Definition: Error.h:63
void copy(MatrixOrVector const &x, MatrixOrVector &y)
Copies x to y.
Definition: LinAlg.h:36