Chaste Commit::29c3c4ab2bee00ddd311a035a1e522c03cbe928a
VectorHelperFunctions.hpp
Go to the documentation of this file.
1/*
2
3Copyright (c) 2005-2026, 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// CVODE headers
51#include <nvector/nvector_serial.h>
52#if CHASTE_SUNDIALS_VERSION >= 70000
54#define realtype sunrealtype
55#endif
56
57#if CHASTE_SUNDIALS_VERSION >= 60000
58#include "CvodeContextManager.hpp" // access to shared SUNContext object required by Sundials 6.0+
59#endif
60
71template <typename VECTOR>
72inline double GetVectorComponent(const VECTOR& rVec, unsigned index);
73
84template <typename VECTOR>
85inline void SetVectorComponent(VECTOR& rVec, unsigned index, double value);
86
96template <typename VECTOR>
97inline unsigned GetVectorSize(const VECTOR& rVec);
98
107template <typename VECTOR>
108inline void InitialiseEmptyVector(VECTOR& rVec);
109
120template <typename VECTOR>
121inline void CreateVectorIfEmpty(VECTOR& rVec, unsigned size);
122
128template <typename VECTOR>
129inline VECTOR CreateEmptyVector();
130
137template <typename VECTOR>
138inline bool IsEmptyVector(VECTOR& rVec);
139
148template <typename VECTOR>
149inline void DeleteVector(VECTOR& rVec);
150
160template <typename VECTOR>
161inline VECTOR CopyVector(VECTOR& rVec);
162
172template <typename VECTOR>
173inline void CopyToStdVector(const VECTOR& rSrc, std::vector<double>& rDest);
174
184template <typename VECTOR>
185inline void CopyFromStdVector(const std::vector<double>& rSrc, VECTOR& rDest);
186
187// Specialisations for std::vector<double>
188
195template <>
196inline double GetVectorComponent(const std::vector<double>& rVec, unsigned index)
197{
198 assert(index < rVec.size());
199 return rVec[index];
200}
201
208template <>
209inline void SetVectorComponent(std::vector<double>& rVec, unsigned index, double value)
210{
211 assert(index < rVec.size());
212 rVec[index] = value;
213}
214
220template <>
221inline unsigned GetVectorSize(const std::vector<double>& rVec)
222{
223 return rVec.size();
224}
225
230template <>
231inline void InitialiseEmptyVector(std::vector<double>& rVec)
232{
233}
234
240template <>
241inline void CreateVectorIfEmpty(std::vector<double>& rVec, unsigned size)
242{
243 if (rVec.empty())
244 {
245 rVec.resize(size);
246 }
247}
248
253template <>
254inline std::vector<double> CreateEmptyVector()
255{
256 return std::vector<double>();
257}
258
264template <>
265inline bool IsEmptyVector(std::vector<double>& rVec)
266{
267 return rVec.empty();
268}
269
274template <>
275inline void DeleteVector(std::vector<double>& rVec)
276{
277}
278
284template <>
285inline std::vector<double> CopyVector(std::vector<double>& rVec)
286{
287 return rVec;
288}
289
295template <>
296inline void CopyToStdVector(const std::vector<double>& rSrc, std::vector<double>& rDest)
297{
298 rDest = rSrc;
299}
300
306template <>
307inline void CopyFromStdVector(const std::vector<double>& rSrc, std::vector<double>& rDest)
308{
309 rDest = rSrc;
310}
311
312// Specialisations for N_Vector
313
320template <>
321inline double GetVectorComponent(const N_Vector& rVec, unsigned index)
322{
323 assert(rVec != nullptr);
324 return NV_Ith_S(rVec, index);
325}
326
333template <>
334inline void SetVectorComponent(N_Vector& rVec, unsigned index, double value)
335{
336 assert(rVec != nullptr);
337 NV_Ith_S(rVec, index) = value;
338}
339
345template <>
346inline unsigned GetVectorSize(const N_Vector& rVec)
347{
348 assert(rVec != nullptr);
349 return NV_LENGTH_S(rVec);
350}
351
356template <>
358{
359 rVec = nullptr;
360}
361
367template <>
368inline void CreateVectorIfEmpty(N_Vector& rVec, unsigned size)
369{
370 if (rVec == nullptr)
371 {
372#if CHASTE_SUNDIALS_VERSION >= 60000
373 rVec = N_VNew_Serial(size, CvodeContextManager::Instance()->GetSundialsContext());
374#else
375 rVec = N_VNew_Serial(size);
376#endif
377 }
378}
379
384template <>
386{
387 return nullptr;
388}
389
395template <>
396inline bool IsEmptyVector(N_Vector& rVec)
397{
398 return rVec == nullptr;
399}
400
405template <>
406inline void DeleteVector(N_Vector& rVec)
407{
408 if (rVec)
409 {
410 rVec->ops->nvdestroy(rVec);
411 rVec = nullptr;
412 }
413}
414
420template <>
422{
423 N_Vector copy = nullptr;
424 if (rVec)
425 {
426 copy = N_VClone(rVec);
427 unsigned size = NV_LENGTH_S(rVec);
428 for (unsigned i = 0; i < size; i++)
429 {
430 NV_Ith_S(copy, i) = NV_Ith_S(rVec, i);
431 }
432 }
433 return copy;
434}
435
442template <>
443inline void CopyToStdVector(const N_Vector& rSrc, std::vector<double>& rDest)
444{
445 // Check for no-op
446 realtype* p_src = NV_DATA_S(rSrc);
447 if (p_src == rDest.data())
448 return;
449 // Set dest size
450 long size = NV_LENGTH_S(rSrc);
451 rDest.resize(size);
452 // Copy data
453 for (long i = 0; i < size; i++)
454 {
455 rDest[i] = p_src[i];
456 }
457}
458
465template <>
466inline void CopyFromStdVector(const std::vector<double>& rSrc, N_Vector& rDest)
467{
468 // Check for no-op
469 realtype* p_dest = NV_DATA_S(rDest);
470 if (p_dest == rSrc.data()) return;
471
472 // Check dest size
473 long size = NV_LENGTH_S(rDest);
474 assert(size == (long)rSrc.size());
475
476 // Copy data
477 for (long i = 0; i < size; i++)
478 {
479 p_dest[i] = rSrc[i];
480 }
481}
482
489inline std::vector<double> MakeStdVec(N_Vector v)
490{
491 std::vector<double> sv;
492 CopyToStdVector(v, sv);
493 return sv;
494}
495
502inline N_Vector MakeNVector(const std::vector<double>& rSrc)
503{
504 N_Vector nv = nullptr;
505 CreateVectorIfEmpty(nv, rSrc.size());
506 CopyFromStdVector(rSrc, nv);
507 return nv;
508}
509
510// End of helper functions
511
512#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)