Chaste  Release::2018.1
VectorHelperFunctions.hpp
Go to the documentation of this file.
1 /*
2 
3 Copyright (c) 2005-2018, University of Oxford.
4 All rights reserved.
5 
6 University of Oxford means the Chancellor, Masters and Scholars of the
7 University of Oxford, having an administrative office at Wellington
8 Square, Oxford OX1 2JD, UK.
9 
10 This file is part of Chaste.
11 
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
14  * Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright notice,
17  this list of conditions and the following disclaimer in the documentation
18  and/or other materials provided with the distribution.
19  * Neither the name of the University of Oxford nor the names of its
20  contributors may be used to endorse or promote products derived from this
21  software without specific prior written permission.
22 
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 
34 */
35 
36 #ifndef VECTORHELPERFUNCTIONS_HPP_
37 #define VECTORHELPERFUNCTIONS_HPP_
38 
47 #include <cassert>
48 #include <vector>
49 
50 #ifdef CHASTE_CVODE
51 // CVODE headers
52 #include <nvector/nvector_serial.h>
53 
54 #endif
55 
66 template <typename VECTOR>
67 inline double GetVectorComponent(const VECTOR& rVec, unsigned index);
68 
79 template <typename VECTOR>
80 inline void SetVectorComponent(VECTOR& rVec, unsigned index, double value);
81 
91 template <typename VECTOR>
92 inline unsigned GetVectorSize(const VECTOR& rVec);
93 
102 template <typename VECTOR>
103 inline void InitialiseEmptyVector(VECTOR& rVec);
104 
115 template <typename VECTOR>
116 inline void CreateVectorIfEmpty(VECTOR& rVec, unsigned size);
117 
123 template <typename VECTOR>
124 inline VECTOR CreateEmptyVector();
125 
132 template <typename VECTOR>
133 inline bool IsEmptyVector(VECTOR& rVec);
134 
143 template <typename VECTOR>
144 inline void DeleteVector(VECTOR& rVec);
145 
155 template <typename VECTOR>
156 inline VECTOR CopyVector(VECTOR& rVec);
157 
167 template <typename VECTOR>
168 inline void CopyToStdVector(const VECTOR& rSrc, std::vector<double>& rDest);
169 
179 template <typename VECTOR>
180 inline void CopyFromStdVector(const std::vector<double>& rSrc, VECTOR& rDest);
181 
182 // Specialisations for std::vector<double>
183 
190 template <>
191 inline double GetVectorComponent(const std::vector<double>& rVec, unsigned index)
192 {
193  assert(index < rVec.size());
194  return rVec[index];
195 }
196 
203 template <>
204 inline void SetVectorComponent(std::vector<double>& rVec, unsigned index, double value)
205 {
206  assert(index < rVec.size());
207  rVec[index] = value;
208 }
209 
215 template <>
216 inline unsigned GetVectorSize(const std::vector<double>& rVec)
217 {
218  return rVec.size();
219 }
220 
225 template <>
226 inline void InitialiseEmptyVector(std::vector<double>& rVec)
227 {
228 }
229 
235 template <>
236 inline void CreateVectorIfEmpty(std::vector<double>& rVec, unsigned size)
237 {
238  if (rVec.empty())
239  {
240  rVec.resize(size);
241  }
242 }
243 
248 template <>
249 inline std::vector<double> CreateEmptyVector()
250 {
251  return std::vector<double>();
252 }
253 
259 template <>
260 inline bool IsEmptyVector(std::vector<double>& rVec)
261 {
262  return rVec.empty();
263 }
264 
269 template <>
270 inline void DeleteVector(std::vector<double>& rVec)
271 {
272 }
273 
279 template <>
280 inline std::vector<double> CopyVector(std::vector<double>& rVec)
281 {
282  return rVec;
283 }
284 
290 template <>
291 inline void CopyToStdVector(const std::vector<double>& rSrc, std::vector<double>& rDest)
292 {
293  rDest = rSrc;
294 }
295 
301 template <>
302 inline void CopyFromStdVector(const std::vector<double>& rSrc, std::vector<double>& rDest)
303 {
304  rDest = rSrc;
305 }
306 
307 // Specialisations for N_Vector
308 
309 #ifdef CHASTE_CVODE
310 
317 template <>
318 inline double GetVectorComponent(const N_Vector& rVec, unsigned index)
319 {
320  assert(rVec != nullptr);
321  return NV_Ith_S(rVec, index);
322 }
323 
330 template <>
331 inline void SetVectorComponent(N_Vector& rVec, unsigned index, double value)
332 {
333  assert(rVec != nullptr);
334  NV_Ith_S(rVec, index) = value;
335 }
336 
342 template <>
343 inline unsigned GetVectorSize(const N_Vector& rVec)
344 {
345  assert(rVec != nullptr);
346  return NV_LENGTH_S(rVec);
347 }
348 
353 template <>
354 inline void InitialiseEmptyVector(N_Vector& rVec)
355 {
356  rVec = nullptr;
357 }
358 
364 template <>
365 inline void CreateVectorIfEmpty(N_Vector& rVec, unsigned size)
366 {
367  if (rVec == nullptr)
368  {
369  rVec = N_VNew_Serial(size);
370  }
371 }
372 
377 template <>
379 {
380  return nullptr;
381 }
382 
388 template <>
389 inline bool IsEmptyVector(N_Vector& rVec)
390 {
391  return rVec == nullptr;
392 }
393 
398 template <>
399 inline void DeleteVector(N_Vector& rVec)
400 {
401  if (rVec)
402  {
403  rVec->ops->nvdestroy(rVec);
404  rVec = nullptr;
405  }
406 }
407 
413 template <>
415 {
416  N_Vector copy = nullptr;
417  if (rVec)
418  {
419  copy = N_VClone(rVec);
420  unsigned size = NV_LENGTH_S(rVec);
421  for (unsigned i = 0; i < size; i++)
422  {
423  NV_Ith_S(copy, i) = NV_Ith_S(rVec, i);
424  }
425  }
426  return copy;
427 }
428 
435 template <>
436 inline void CopyToStdVector(const N_Vector& rSrc, std::vector<double>& rDest)
437 {
438  // Check for no-op
439  realtype* p_src = NV_DATA_S(rSrc);
440  if (!rDest.empty() && p_src == &(rDest[0]))
441  return;
442  // Set dest size
443  long size = NV_LENGTH_S(rSrc);
444  rDest.resize(size);
445  // Copy data
446  for (long i = 0; i < size; i++)
447  {
448  rDest[i] = p_src[i];
449  }
450 }
451 
458 template <>
459 inline void CopyFromStdVector(const std::vector<double>& rSrc, N_Vector& rDest)
460 {
461  // Check for no-op
462  realtype* p_dest = NV_DATA_S(rDest);
463  if (p_dest == &(rSrc[0])) return;
464 
465  // Check dest size
466  long size = NV_LENGTH_S(rDest);
467  assert(size == (long)rSrc.size());
468 
469  // Copy data
470  for (long i = 0; i < size; i++)
471  {
472  p_dest[i] = rSrc[i];
473  }
474 }
475 
482 inline std::vector<double> MakeStdVec(N_Vector v)
483 {
484  std::vector<double> sv;
485  CopyToStdVector(v, sv);
486  return sv;
487 }
488 
495 inline N_Vector MakeNVector(const std::vector<double>& rSrc)
496 {
497  N_Vector nv = nullptr;
498  CreateVectorIfEmpty(nv, rSrc.size());
499  CopyFromStdVector(rSrc, nv);
500  return nv;
501 }
502 
503 #endif // CHASTE_CVODE
504 
505 // End of helper functions
506 
507 #endif /*VECTORHELPERFUNCTIONS_HPP_*/
std::vector< double > MakeStdVec(N_Vector v)
VECTOR CreateEmptyVector()
VECTOR CopyVector(VECTOR &rVec)
N_Vector MakeNVector(const std::vector< double > &rSrc)
void InitialiseEmptyVector(VECTOR &rVec)
void CreateVectorIfEmpty(VECTOR &rVec, unsigned size)
void SetVectorComponent(VECTOR &rVec, unsigned index, double value)
void CopyFromStdVector(const std::vector< double > &rSrc, VECTOR &rDest)
void CopyToStdVector(const VECTOR &rSrc, std::vector< double > &rDest)
double GetVectorComponent(const VECTOR &rVec, unsigned index)
void DeleteVector(VECTOR &rVec)
unsigned GetVectorSize(const VECTOR &rVec)
bool IsEmptyVector(VECTOR &rVec)