Chaste Commit::675f9facbe008c5eacb9006feaeb6423206579ea
VectorHelperFunctions.hpp
Go to the documentation of this file.
1/*
2
3Copyright (c) 2005-2025, 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#if CHASTE_SUNDIALS_VERSION >= 70000
55#define realtype sunrealtype
56#endif
57
58#if CHASTE_SUNDIALS_VERSION >= 60000
59#include "CvodeContextManager.hpp" // access to shared SUNContext object required by Sundials 6.0+
60#endif
61
62#endif
63
74template <typename VECTOR>
75inline double GetVectorComponent(const VECTOR& rVec, unsigned index);
76
87template <typename VECTOR>
88inline void SetVectorComponent(VECTOR& rVec, unsigned index, double value);
89
99template <typename VECTOR>
100inline unsigned GetVectorSize(const VECTOR& rVec);
101
110template <typename VECTOR>
111inline void InitialiseEmptyVector(VECTOR& rVec);
112
123template <typename VECTOR>
124inline void CreateVectorIfEmpty(VECTOR& rVec, unsigned size);
125
131template <typename VECTOR>
132inline VECTOR CreateEmptyVector();
133
140template <typename VECTOR>
141inline bool IsEmptyVector(VECTOR& rVec);
142
151template <typename VECTOR>
152inline void DeleteVector(VECTOR& rVec);
153
163template <typename VECTOR>
164inline VECTOR CopyVector(VECTOR& rVec);
165
175template <typename VECTOR>
176inline void CopyToStdVector(const VECTOR& rSrc, std::vector<double>& rDest);
177
187template <typename VECTOR>
188inline void CopyFromStdVector(const std::vector<double>& rSrc, VECTOR& rDest);
189
190// Specialisations for std::vector<double>
191
198template <>
199inline double GetVectorComponent(const std::vector<double>& rVec, unsigned index)
200{
201 assert(index < rVec.size());
202 return rVec[index];
203}
204
211template <>
212inline void SetVectorComponent(std::vector<double>& rVec, unsigned index, double value)
213{
214 assert(index < rVec.size());
215 rVec[index] = value;
216}
217
223template <>
224inline unsigned GetVectorSize(const std::vector<double>& rVec)
225{
226 return rVec.size();
227}
228
233template <>
234inline void InitialiseEmptyVector(std::vector<double>& rVec)
235{
236}
237
243template <>
244inline void CreateVectorIfEmpty(std::vector<double>& rVec, unsigned size)
245{
246 if (rVec.empty())
247 {
248 rVec.resize(size);
249 }
250}
251
256template <>
257inline std::vector<double> CreateEmptyVector()
258{
259 return std::vector<double>();
260}
261
267template <>
268inline bool IsEmptyVector(std::vector<double>& rVec)
269{
270 return rVec.empty();
271}
272
277template <>
278inline void DeleteVector(std::vector<double>& rVec)
279{
280}
281
287template <>
288inline std::vector<double> CopyVector(std::vector<double>& rVec)
289{
290 return rVec;
291}
292
298template <>
299inline void CopyToStdVector(const std::vector<double>& rSrc, std::vector<double>& rDest)
300{
301 rDest = rSrc;
302}
303
309template <>
310inline void CopyFromStdVector(const std::vector<double>& rSrc, std::vector<double>& rDest)
311{
312 rDest = rSrc;
313}
314
315// Specialisations for N_Vector
316
317#ifdef CHASTE_CVODE
318
325template <>
326inline double GetVectorComponent(const N_Vector& rVec, unsigned index)
327{
328 assert(rVec != nullptr);
329 return NV_Ith_S(rVec, index);
330}
331
338template <>
339inline void SetVectorComponent(N_Vector& rVec, unsigned index, double value)
340{
341 assert(rVec != nullptr);
342 NV_Ith_S(rVec, index) = value;
343}
344
350template <>
351inline unsigned GetVectorSize(const N_Vector& rVec)
352{
353 assert(rVec != nullptr);
354 return NV_LENGTH_S(rVec);
355}
356
361template <>
363{
364 rVec = nullptr;
365}
366
372template <>
373inline void CreateVectorIfEmpty(N_Vector& rVec, unsigned size)
374{
375 if (rVec == nullptr)
376 {
377#if CHASTE_SUNDIALS_VERSION >= 60000
378 rVec = N_VNew_Serial(size, CvodeContextManager::Instance()->GetSundialsContext());
379#else
380 rVec = N_VNew_Serial(size);
381#endif
382 }
383}
384
389template <>
391{
392 return nullptr;
393}
394
400template <>
401inline bool IsEmptyVector(N_Vector& rVec)
402{
403 return rVec == nullptr;
404}
405
410template <>
411inline void DeleteVector(N_Vector& rVec)
412{
413 if (rVec)
414 {
415 rVec->ops->nvdestroy(rVec);
416 rVec = nullptr;
417 }
418}
419
425template <>
427{
428 N_Vector copy = nullptr;
429 if (rVec)
430 {
431 copy = N_VClone(rVec);
432 unsigned size = NV_LENGTH_S(rVec);
433 for (unsigned i = 0; i < size; i++)
434 {
435 NV_Ith_S(copy, i) = NV_Ith_S(rVec, i);
436 }
437 }
438 return copy;
439}
440
447template <>
448inline void CopyToStdVector(const N_Vector& rSrc, std::vector<double>& rDest)
449{
450 // Check for no-op
451 realtype* p_src = NV_DATA_S(rSrc);
452 if (!rDest.empty() && p_src == &(rDest[0]))
453 return;
454 // Set dest size
455 long size = NV_LENGTH_S(rSrc);
456 rDest.resize(size);
457 // Copy data
458 for (long i = 0; i < size; i++)
459 {
460 rDest[i] = p_src[i];
461 }
462}
463
470template <>
471inline void CopyFromStdVector(const std::vector<double>& rSrc, N_Vector& rDest)
472{
473 // Check for no-op
474 realtype* p_dest = NV_DATA_S(rDest);
475 if (p_dest == &(rSrc[0])) return;
476
477 // Check dest size
478 long size = NV_LENGTH_S(rDest);
479 assert(size == (long)rSrc.size());
480
481 // Copy data
482 for (long i = 0; i < size; i++)
483 {
484 p_dest[i] = rSrc[i];
485 }
486}
487
494inline std::vector<double> MakeStdVec(N_Vector v)
495{
496 std::vector<double> sv;
497 CopyToStdVector(v, sv);
498 return sv;
499}
500
507inline N_Vector MakeNVector(const std::vector<double>& rSrc)
508{
509 N_Vector nv = nullptr;
510 CreateVectorIfEmpty(nv, rSrc.size());
511 CopyFromStdVector(rSrc, nv);
512 return nv;
513}
514
515#endif // CHASTE_CVODE
516
517// End of helper functions
518
519#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)