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