Chaste Commit::1fd4e48e3990e67db148bc1bc4cf6991a0049d0c
VectorHelperFunctions.hpp
Go to the documentation of this file.
1/*
2
3Copyright (c) 2005-2024, University of Oxford.
4All rights reserved.
5
6University of Oxford means the Chancellor, Masters and Scholars of the
7University of Oxford, having an administrative office at Wellington
8Square, Oxford OX1 2JD, UK.
9
10This file is part of Chaste.
11
12Redistribution and use in source and binary forms, with or without
13modification, 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
23THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32OF 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#if CHASTE_SUNDIALS_VERSION >= 60000
55#include "CvodeContextManager.hpp" // access to shared SUNContext object required by Sundials 6.0+
56#endif
57
58#endif
59
70template <typename VECTOR>
71inline double GetVectorComponent(const VECTOR& rVec, unsigned index);
72
83template <typename VECTOR>
84inline void SetVectorComponent(VECTOR& rVec, unsigned index, double value);
85
95template <typename VECTOR>
96inline unsigned GetVectorSize(const VECTOR& rVec);
97
106template <typename VECTOR>
107inline void InitialiseEmptyVector(VECTOR& rVec);
108
119template <typename VECTOR>
120inline void CreateVectorIfEmpty(VECTOR& rVec, unsigned size);
121
127template <typename VECTOR>
128inline VECTOR CreateEmptyVector();
129
136template <typename VECTOR>
137inline bool IsEmptyVector(VECTOR& rVec);
138
147template <typename VECTOR>
148inline void DeleteVector(VECTOR& rVec);
149
159template <typename VECTOR>
160inline VECTOR CopyVector(VECTOR& rVec);
161
171template <typename VECTOR>
172inline void CopyToStdVector(const VECTOR& rSrc, std::vector<double>& rDest);
173
183template <typename VECTOR>
184inline void CopyFromStdVector(const std::vector<double>& rSrc, VECTOR& rDest);
185
186// Specialisations for std::vector<double>
187
194template <>
195inline double GetVectorComponent(const std::vector<double>& rVec, unsigned index)
196{
197 assert(index < rVec.size());
198 return rVec[index];
199}
200
207template <>
208inline void SetVectorComponent(std::vector<double>& rVec, unsigned index, double value)
209{
210 assert(index < rVec.size());
211 rVec[index] = value;
212}
213
219template <>
220inline unsigned GetVectorSize(const std::vector<double>& rVec)
221{
222 return rVec.size();
223}
224
229template <>
230inline void InitialiseEmptyVector(std::vector<double>& rVec)
231{
232}
233
239template <>
240inline void CreateVectorIfEmpty(std::vector<double>& rVec, unsigned size)
241{
242 if (rVec.empty())
243 {
244 rVec.resize(size);
245 }
246}
247
252template <>
253inline std::vector<double> CreateEmptyVector()
254{
255 return std::vector<double>();
256}
257
263template <>
264inline bool IsEmptyVector(std::vector<double>& rVec)
265{
266 return rVec.empty();
267}
268
273template <>
274inline void DeleteVector(std::vector<double>& rVec)
275{
276}
277
283template <>
284inline std::vector<double> CopyVector(std::vector<double>& rVec)
285{
286 return rVec;
287}
288
294template <>
295inline void CopyToStdVector(const std::vector<double>& rSrc, std::vector<double>& rDest)
296{
297 rDest = rSrc;
298}
299
305template <>
306inline void CopyFromStdVector(const std::vector<double>& rSrc, std::vector<double>& rDest)
307{
308 rDest = rSrc;
309}
310
311// Specialisations for N_Vector
312
313#ifdef CHASTE_CVODE
314
321template <>
322inline double GetVectorComponent(const N_Vector& rVec, unsigned index)
323{
324 assert(rVec != nullptr);
325 return NV_Ith_S(rVec, index);
326}
327
334template <>
335inline void SetVectorComponent(N_Vector& rVec, unsigned index, double value)
336{
337 assert(rVec != nullptr);
338 NV_Ith_S(rVec, index) = value;
339}
340
346template <>
347inline unsigned GetVectorSize(const N_Vector& rVec)
348{
349 assert(rVec != nullptr);
350 return NV_LENGTH_S(rVec);
351}
352
357template <>
359{
360 rVec = nullptr;
361}
362
368template <>
369inline void CreateVectorIfEmpty(N_Vector& rVec, unsigned size)
370{
371 if (rVec == nullptr)
372 {
373#if CHASTE_SUNDIALS_VERSION >= 60000
374 rVec = N_VNew_Serial(size, CvodeContextManager::Instance()->GetSundialsContext());
375#else
376 rVec = N_VNew_Serial(size);
377#endif
378 }
379}
380
385template <>
387{
388 return nullptr;
389}
390
396template <>
397inline bool IsEmptyVector(N_Vector& rVec)
398{
399 return rVec == nullptr;
400}
401
406template <>
407inline void DeleteVector(N_Vector& rVec)
408{
409 if (rVec)
410 {
411 rVec->ops->nvdestroy(rVec);
412 rVec = nullptr;
413 }
414}
415
421template <>
423{
424 N_Vector copy = nullptr;
425 if (rVec)
426 {
427 copy = N_VClone(rVec);
428 unsigned size = NV_LENGTH_S(rVec);
429 for (unsigned i = 0; i < size; i++)
430 {
431 NV_Ith_S(copy, i) = NV_Ith_S(rVec, i);
432 }
433 }
434 return copy;
435}
436
443template <>
444inline void CopyToStdVector(const N_Vector& rSrc, std::vector<double>& rDest)
445{
446 // Check for no-op
447 realtype* p_src = NV_DATA_S(rSrc);
448 if (!rDest.empty() && p_src == &(rDest[0]))
449 return;
450 // Set dest size
451 long size = NV_LENGTH_S(rSrc);
452 rDest.resize(size);
453 // Copy data
454 for (long i = 0; i < size; i++)
455 {
456 rDest[i] = p_src[i];
457 }
458}
459
466template <>
467inline void CopyFromStdVector(const std::vector<double>& rSrc, N_Vector& rDest)
468{
469 // Check for no-op
470 realtype* p_dest = NV_DATA_S(rDest);
471 if (p_dest == &(rSrc[0])) return;
472
473 // Check dest size
474 long size = NV_LENGTH_S(rDest);
475 assert(size == (long)rSrc.size());
476
477 // Copy data
478 for (long i = 0; i < size; i++)
479 {
480 p_dest[i] = rSrc[i];
481 }
482}
483
490inline std::vector<double> MakeStdVec(N_Vector v)
491{
492 std::vector<double> sv;
493 CopyToStdVector(v, sv);
494 return sv;
495}
496
503inline N_Vector MakeNVector(const std::vector<double>& rSrc)
504{
505 N_Vector nv = nullptr;
506 CreateVectorIfEmpty(nv, rSrc.size());
507 CopyFromStdVector(rSrc, nv);
508 return nv;
509}
510
511#endif // CHASTE_CVODE
512
513// End of helper functions
514
515#endif /*VECTORHELPERFUNCTIONS_HPP_*/
void DeleteVector(VECTOR &rVec)
void CreateVectorIfEmpty(VECTOR &rVec, unsigned size)
void SetVectorComponent(VECTOR &rVec, unsigned index, double value)
double GetVectorComponent(const VECTOR &rVec, unsigned index)
VECTOR CreateEmptyVector()
std::vector< double > MakeStdVec(N_Vector v)
unsigned GetVectorSize(const VECTOR &rVec)
N_Vector MakeNVector(const std::vector< double > &rSrc)
bool IsEmptyVector(VECTOR &rVec)
VECTOR CopyVector(VECTOR &rVec)
void InitialiseEmptyVector(VECTOR &rVec)
void CopyFromStdVector(const std::vector< double > &rSrc, VECTOR &rDest)
void CopyToStdVector(const VECTOR &rSrc, std::vector< double > &rDest)