nvector_SimTK.h

Go to the documentation of this file.
00001 #ifndef SimTK_CPODES_NVECTOR_SimTK_H_
00002 #define SimTK_CPODES_NVECTOR_SimTK_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                      SimTK Core: SimTK CPodes                              *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK Core biosimulation toolkit originating from      *
00008  * Simbios, the NIH National Center for Physics-Based Simulation of           *
00009  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
00010  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
00011  *                                                                            *
00012  * Portions copyright (c) 2006-7 Stanford University and the Authors.         *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Permission is hereby granted, free of charge, to any person obtaining a    *
00017  * copy of this software and associated documentation files (the "Software"), *
00018  * to deal in the Software without restriction, including without limitation  *
00019  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
00020  * and/or sell copies of the Software, and to permit persons to whom the      *
00021  * Software is furnished to do so, subject to the following conditions:       *
00022  *                                                                            *
00023  * The above copyright notice and this permission notice shall be included in *
00024  * all copies or substantial portions of the Software.                        *
00025  *                                                                            *
00026  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
00027  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
00028  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
00029  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
00030  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
00031  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
00032  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
00033  * -------------------------------------------------------------------------- */
00034 
00040 #include "SimTKcommon.h"
00041 
00042 #include "sundials/sundials_nvector.h"
00043 
00044 #include <cassert>
00045 
00046 namespace SimTK {
00047 
00048 // This is the object to which the generic N_Vector struct's "content"
00049 // entry points.
00050 class N_VectorContent_SimTK {
00051 public:
00052     N_VectorContent_SimTK()
00053       : treatAsConst(false), ownVector(true), data(new Vector()) { 
00054     }
00055 
00056     N_VectorContent_SimTK(const Vector& v) 
00057       : treatAsConst(true), ownVector(false),
00058         data(const_cast<Vector*>(&v)) {
00059     }
00060 
00061     N_VectorContent_SimTK(Vector& v) 
00062       : treatAsConst(false), ownVector(false), data(&v) {
00063     }
00064 
00065     // Copy constructor makes a deep (new) copy.
00066     N_VectorContent_SimTK(const N_VectorContent_SimTK& nv) 
00067       : treatAsConst(false), ownVector(true), data(new Vector(*nv.data)) {
00068     }
00069 
00070     // Assignment fails if target is const, otherwise reallocates as needed.
00071     N_VectorContent_SimTK& operator=(const N_VectorContent_SimTK& nv) {
00072         if (&nv != this) {
00073             assert(!treatAsConst);
00074             *data = *nv.data;
00075         }
00076         return *this;
00077     }
00078 
00079     ~N_VectorContent_SimTK() {
00080         if (ownVector) delete data;
00081         data = 0;
00082     }
00083 
00084     const Vector& getVector() const {
00085         assert(data);
00086         return *data;
00087     }
00088 
00089     Vector& updVector() {
00090         assert(data);
00091         assert(!treatAsConst);
00092         return *data;
00093     }
00094 
00095 private:
00096     bool treatAsConst;  // is this logically const?
00097     bool ownVector;     // if true, destruct Vector along with this
00098     Vector* data;
00099 
00100 };
00101 
00102 // This singleton class defines the operations needed by the abstract
00103 // N_Vector in terms of operations performed on SimTK Vectors.
00104 // The "virtual function table" is filled in once and used
00105 // in *all* N_Vector_SimTK objects.
00106 class N_Vector_Ops_SimTK : public _generic_N_Vector_Ops {
00107 public:
00108     // Return a reference to the singleton object. You can use
00109     // the address of this reference to check whether a given N_Vector
00110     // is really an N_Vector_SimTK.
00111     static const _generic_N_Vector_Ops& getOps() {
00112         return Ops;
00113     }
00114 
00115     // Sundials isn't const correct so it is going to want a
00116     // non-const pointer to the Ops class here, which is const.
00117     // We'll just have to trust it.
00118     static _generic_N_Vector_Ops* getSundialsOpsPtr() {
00119         return const_cast<N_Vector_Ops_SimTK*>(&Ops);
00120     }
00121 
00122 private:
00123     N_Vector_Ops_SimTK(); // initialize
00124     SUNDIALS_EXPORT static const N_Vector_Ops_SimTK Ops;
00125 };
00126 
00127 // This is the object to which an N_Vector points when we are using
00128 // SimTK's N_Vector implementation.
00129 class N_Vector_SimTK : public _generic_N_Vector {
00130 public:
00131     // Default constructor creates an owned, empty, resizable vector.
00132     N_Vector_SimTK() {
00133         content = (void*)new N_VectorContent_SimTK();
00134         ops = N_Vector_Ops_SimTK::getSundialsOpsPtr();
00135     }
00136 
00137     // This constructor produces a read-only *reference* to an existing Vector.
00138     // Destruction of the N_Vector_SimTK leaves the original Vector as it was.
00139     N_Vector_SimTK(const Vector& v) {
00140        content = (void*)new N_VectorContent_SimTK(v);
00141        ops = N_Vector_Ops_SimTK::getSundialsOpsPtr();
00142     }
00143 
00144     // This constructor produces a writable *reference* to an existing
00145     // Vector. Destruction of the N_Vector_SimTK leaves the original
00146     // Vector in existence, although its value may have changed.
00147     N_Vector_SimTK(Vector& v) {
00148        content = (void*)new N_VectorContent_SimTK(v);
00149        ops = N_Vector_Ops_SimTK::getSundialsOpsPtr();
00150     }
00151 
00152     // Copy constructor makes a deep copy. The result will be an owned,
00153     // resizable vector that will evaporate upon destruction of the
00154     // N_Vector_SimTK object.
00155     N_Vector_SimTK(const N_Vector_SimTK& nv) {
00156         assert(nv.ops == &N_Vector_Ops_SimTK::getOps());
00157         content = (void*)new N_VectorContent_SimTK(nv.getContent());
00158         ops = N_Vector_Ops_SimTK::getSundialsOpsPtr();
00159     }
00160 
00161     // Assignment will fail if this isn't writable.
00162     N_Vector_SimTK& operator=(const N_Vector_SimTK& nv) {
00163         assert(   ops    == &N_Vector_Ops_SimTK::getOps() 
00164                && nv.ops == &N_Vector_Ops_SimTK::getOps());
00165         if (&nv != this)
00166             updContent() = nv.getContent();
00167         return *this;
00168     }
00169 
00170     ~N_Vector_SimTK() {
00171         assert(ops == &N_Vector_Ops_SimTK::getOps());
00172         delete reinterpret_cast<N_VectorContent_SimTK*>(content);
00173         content = 0;
00174         ops = 0;
00175     }
00176 
00177     static bool isA(const N_Vector nv) {
00178         return nv && (nv->ops == &N_Vector_Ops_SimTK::getOps());
00179     }
00180 
00181     static const N_Vector_SimTK* downcast(const N_Vector nv) {
00182         assert(isA(nv));
00183         return reinterpret_cast<const N_Vector_SimTK*>(nv);
00184     }
00185 
00186     static N_Vector_SimTK* updDowncast(N_Vector nv) {
00187         assert(isA(nv));
00188         return reinterpret_cast<N_Vector_SimTK*>(nv);
00189     }
00190 
00191     static N_Vector_SimTK* nvclone(const N_Vector nv) {
00192         assert(isA(nv));
00193         const N_Vector_SimTK& nvs = *reinterpret_cast<const N_Vector_SimTK*>(nv);
00194         return new N_Vector_SimTK(nvs);
00195     }
00196 
00197     static const Vector& getVector(const N_Vector nv) {
00198         assert(isA(nv));
00199         const N_Vector_SimTK& nvs = *reinterpret_cast<const N_Vector_SimTK*>(nv);
00200         return nvs.getContent().getVector();
00201     }
00202 
00203     static Vector& updVector(N_Vector nv) {
00204         assert(isA(nv));
00205         N_Vector_SimTK& nvs = *reinterpret_cast<N_Vector_SimTK*>(nv);
00206         return nvs.updContent().updVector();
00207     }
00208 
00209 private:
00210     const N_VectorContent_SimTK& getContent() const {
00211         return *reinterpret_cast<const N_VectorContent_SimTK*>(content);
00212     }
00213     N_VectorContent_SimTK& updContent() {
00214         return *reinterpret_cast<N_VectorContent_SimTK*>(content);
00215     }
00216 
00217 };
00218 
00219 } // namespace SimTK
00220 
00221 #endif // SimTK_NVECTOR_SimTK_H_

Generated on Fri Sep 26 07:44:15 2008 for SimTKcore by  doxygen 1.5.6