Chaste Release::3.1
AbstractParameterisedSystem.cpp
00001 /*
00002 
00003 Copyright (c) 2005-2012, University of Oxford.
00004 All rights reserved.
00005 
00006 University of Oxford means the Chancellor, Masters and Scholars of the
00007 University of Oxford, having an administrative office at Wellington
00008 Square, Oxford OX1 2JD, UK.
00009 
00010 This file is part of Chaste.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014  * Redistributions of source code must retain the above copyright notice,
00015    this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright notice,
00017    this list of conditions and the following disclaimer in the documentation
00018    and/or other materials provided with the distribution.
00019  * Neither the name of the University of Oxford nor the names of its
00020    contributors may be used to endorse or promote products derived from this
00021    software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 
00034 */
00035 
00036 #include <sstream>
00037 #include <cassert>
00038 
00039 #include "AbstractParameterisedSystem.hpp"
00040 
00041 #include "Exception.hpp"
00042 #include "VectorHelperFunctions.hpp"
00043 
00044 
00045 template<typename VECTOR>
00046 AbstractParameterisedSystem<VECTOR>::AbstractParameterisedSystem(unsigned numberOfStateVariables)
00047     : AbstractUntemplatedParameterisedSystem(numberOfStateVariables)
00048 {
00049     InitialiseEmptyVector(mParameters);
00050     InitialiseEmptyVector(mStateVariables);
00051 }
00052 
00053 template<typename VECTOR>
00054 std::string AbstractParameterisedSystem<VECTOR>::DumpState(const std::string& message)
00055 {
00056     return GetStateMessage(message, mStateVariables);
00057 }
00058 
00059 template<typename VECTOR>
00060 std::string AbstractParameterisedSystem<VECTOR>::DumpState(const std::string& message,
00061                                                            VECTOR Y)
00062 {
00063     return GetStateMessage(message, Y);
00064 }
00065 
00066 template<typename VECTOR>
00067 std::string AbstractParameterisedSystem<VECTOR>::GetStateMessage(const std::string& message, VECTOR Y)
00068 {
00069     std::stringstream res;
00070     res << message << "\nState:\n";
00071     assert(rGetStateVariableNames().size()==GetVectorSize(Y));
00072     for (unsigned i=0; i<GetVectorSize(Y); i++)
00073     {
00074         res << "\t" << rGetStateVariableNames()[i] << ":" << GetVectorComponent(Y, i) << "\n";
00075     }
00076     return res.str();
00077 }
00078 
00079 template<typename VECTOR>
00080 void AbstractParameterisedSystem<VECTOR>::CheckParametersOnLoad(const std::vector<double>& rParameters, const std::vector<std::string>& rParameterNames)
00081 {
00082     if (GetVectorSize(mParameters) != rGetParameterNames().size())
00083     {
00084         // Subclass constructor didn't give default values, so we need the archive to provide them all
00085         if (rParameterNames.size() != rGetParameterNames().size())
00086         {
00087             EXCEPTION("Number of ODE parameters in archive does not match number in class.");
00088         }
00089         CreateVectorIfEmpty(mParameters,rGetParameterNames().size());
00090     }
00091 
00092     // Check whether the archive specifies parameters that don't appear in this class,
00093     // and create a map from archive index to local index
00094     std::vector<unsigned> index_map(rParameterNames.size());
00095     for (unsigned i=0; i<rParameterNames.size(); ++i)
00096     {
00097         index_map[i] = find(rGetParameterNames().begin(), rGetParameterNames().end(), rParameterNames[i])
00098                        - rGetParameterNames().begin();
00099         if (index_map[i] == rGetParameterNames().size())
00100         {
00101             EXCEPTION("Archive specifies a parameter '" + rParameterNames[i] + "' which does not appear in this class.");
00102         }
00103     }
00104 
00105     for (unsigned i=0; i<rParameterNames.size(); ++i)
00106     {
00107         SetVectorComponent(mParameters,index_map[i],rParameters[i]);
00108     }
00109 
00110     // Paranoia check
00111     assert(GetVectorSize(mParameters) == rGetParameterNames().size());
00112 }
00113 
00114 //
00115 // State variable methods
00116 //
00117 
00118 template<typename VECTOR>
00119 VECTOR& AbstractParameterisedSystem<VECTOR>::rGetStateVariables()
00120 {
00121     return mStateVariables;
00122 }
00123 
00124 template<typename VECTOR>
00125 VECTOR AbstractParameterisedSystem<VECTOR>::GetStateVariables()
00126 {
00127     return CopyVector(mStateVariables);
00128 }
00129 
00130 template<typename VECTOR>
00131 void AbstractParameterisedSystem<VECTOR>::SetStateVariables(const VECTOR& rStateVariables)
00132 {
00133     if ( mNumberOfStateVariables != GetVectorSize(rStateVariables) )
00134     {
00135         EXCEPTION("The size of the passed in vector must be that of the number of state variables.");
00136     }
00137     CreateVectorIfEmpty(mStateVariables, mNumberOfStateVariables);
00138     for (unsigned i=0; i<mNumberOfStateVariables; i++)
00139     {
00140         SetVectorComponent(mStateVariables, i, GetVectorComponent(rStateVariables, i));
00141     }
00142 }
00143 
00144 template<typename VECTOR>
00145 double AbstractParameterisedSystem<VECTOR>::GetStateVariable(unsigned index) const
00146 {
00147     if (index >= mNumberOfStateVariables)
00148     {
00149         EXCEPTION("The index passed in must be less than the number of state variables.");
00150     }
00151     return GetVectorComponent(mStateVariables, index);
00152 }
00153 
00154 template<typename VECTOR>
00155 double AbstractParameterisedSystem<VECTOR>::GetStateVariable(const std::string& rName) const
00156 {
00157     return GetStateVariable(GetStateVariableIndex(rName));
00158 }
00159 
00160 template<typename VECTOR>
00161 void AbstractParameterisedSystem<VECTOR>::SetStateVariable(unsigned index, double newValue)
00162 {
00163     if ( mNumberOfStateVariables <= index )
00164     {
00165         EXCEPTION("The index passed in must be less than the number of state variables.");
00166     }
00167     SetVectorComponent(mStateVariables, index, newValue);
00168 }
00169 
00170 template<typename VECTOR>
00171 void AbstractParameterisedSystem<VECTOR>::SetStateVariable(const std::string& rName, double newValue)
00172 {
00173     SetStateVariable(GetStateVariableIndex(rName), newValue);
00174 }
00175 
00176 
00177 //
00178 // Initial condition methods
00179 //
00180 
00181 template<typename VECTOR>
00182 void AbstractParameterisedSystem<VECTOR>::SetDefaultInitialConditions(const VECTOR& rInitialConditions)
00183 {
00184     if (GetVectorSize(rInitialConditions) != mNumberOfStateVariables)
00185     {
00186         EXCEPTION("The number of initial conditions must be that of the number of state variables.");
00187     }
00188     assert(mpSystemInfo);
00189     std::vector<double> inits;
00190     CopyToStdVector(rInitialConditions, inits);
00191     mpSystemInfo->SetDefaultInitialConditions(inits);
00192 }
00193 
00194 template<typename VECTOR>
00195 void AbstractParameterisedSystem<VECTOR>::SetDefaultInitialCondition(unsigned index, double initialCondition)
00196 {
00197     if (index >= mNumberOfStateVariables)
00198     {
00199         EXCEPTION("Index is greater than the number of state variables.");
00200     }
00201     assert(mpSystemInfo);
00202     mpSystemInfo->SetDefaultInitialCondition(index, initialCondition);
00203 }
00204 
00205 template<typename VECTOR>
00206 VECTOR AbstractParameterisedSystem<VECTOR>::GetInitialConditions() const
00207 {
00208     assert(mpSystemInfo);
00209     VECTOR v;
00210     InitialiseEmptyVector(v);
00211     CreateVectorIfEmpty(v, mNumberOfStateVariables);
00212     CopyFromStdVector(mpSystemInfo->GetInitialConditions(), v);
00213     return v;
00214 }
00215 
00216 template<typename VECTOR>
00217 void AbstractParameterisedSystem<VECTOR>::ResetToInitialConditions()
00218 {
00219     VECTOR inits = GetInitialConditions();
00220     SetStateVariables(inits);
00221     DeleteVector(inits);
00222 }
00223 
00224 //
00225 // Parameter methods
00226 //
00227 
00228 template<typename VECTOR>
00229 double AbstractParameterisedSystem<VECTOR>::GetParameter(unsigned index) const
00230 {
00231     if (index >= GetVectorSize(mParameters))
00232     {
00233         EXCEPTION("The index passed in must be less than the number of parameters.");
00234     }
00235     return GetVectorComponent(mParameters, index);
00236 }
00237 
00238 template<typename VECTOR>
00239 void AbstractParameterisedSystem<VECTOR>::SetParameter(unsigned index, double value)
00240 {
00241     if (index >= GetVectorSize(mParameters))
00242     {
00243         EXCEPTION("The index passed in must be less than the number of parameters.");
00244     }
00245     SetVectorComponent(mParameters, index, value);
00246 }
00247 
00248 template<typename VECTOR>
00249 void AbstractParameterisedSystem<VECTOR>::SetParameter(const std::string& rName, double value)
00250 {
00251     SetVectorComponent(mParameters, GetParameterIndex(rName), value);
00252 }
00253 
00254 template<typename VECTOR>
00255 double AbstractParameterisedSystem<VECTOR>::GetParameter(const std::string& rName) const
00256 {
00257     return GetParameter(GetParameterIndex(rName));
00258 }
00259 
00260 //
00261 // "Any variable" methods
00262 //
00263 
00264 template<typename VECTOR>
00265 double AbstractParameterisedSystem<VECTOR>::GetAnyVariable(unsigned index, double time,
00266                                                            VECTOR* pDerivedQuantities)
00267 {
00268     if (index < mNumberOfStateVariables)
00269     {
00270         return GetVectorComponent(mStateVariables, index);
00271     }
00272     else if (index - mNumberOfStateVariables < GetVectorSize(mParameters))
00273     {
00274         return GetVectorComponent(mParameters, index - mNumberOfStateVariables);
00275     }
00276     else
00277     {
00278         unsigned offset = mNumberOfStateVariables + GetVectorSize(mParameters);
00279         if (index - offset < GetNumberOfDerivedQuantities())
00280         {
00281             VECTOR dqs;
00282             if (pDerivedQuantities == NULL)
00283             {
00284                 dqs = ComputeDerivedQuantitiesFromCurrentState(time);
00285                 pDerivedQuantities = &dqs;
00286             }
00287             double value = GetVectorComponent(*pDerivedQuantities, index - offset);
00288             if (pDerivedQuantities == &dqs)
00289             {
00290                 DeleteVector(dqs);
00291             }
00292             return value;
00293         }
00294         else
00295         {
00296             EXCEPTION("Invalid index passed to GetAnyVariable.");
00297         }
00298     }
00299 }
00300 
00301 template<typename VECTOR>
00302 double AbstractParameterisedSystem<VECTOR>::GetAnyVariable(const std::string& rName,
00303                                                            double time,
00304                                                            VECTOR* pDerivedQuantities)
00305 {
00306     return GetAnyVariable(GetAnyVariableIndex(rName), time, pDerivedQuantities);
00307 }
00308 
00309 template<typename VECTOR>
00310 void AbstractParameterisedSystem<VECTOR>::SetAnyVariable(unsigned index, double value)
00311 {
00312     if (index < mNumberOfStateVariables)
00313     {
00314         SetVectorComponent(mStateVariables, index, value);
00315     }
00316     else if (index - mNumberOfStateVariables < GetVectorSize(mParameters))
00317     {
00318         SetVectorComponent(mParameters, index - mNumberOfStateVariables, value);
00319     }
00320     else
00321     {
00322         EXCEPTION("Cannot set the value of a derived quantity, or invalid index.");
00323     }
00324 }
00325 
00326 template<typename VECTOR>
00327 void AbstractParameterisedSystem<VECTOR>::SetAnyVariable(const std::string& rName, double value)
00328 {
00329     SetAnyVariable(GetAnyVariableIndex(rName), value);
00330 }
00331 
00332 //
00333 // "Derived quantities" methods
00334 //
00335 
00336 template<typename VECTOR>
00337 VECTOR AbstractParameterisedSystem<VECTOR>::ComputeDerivedQuantities(double time,
00338                                                                      const VECTOR& rState)
00339 {
00340     EXCEPTION("This ODE system does not define derived quantities.");
00341 }
00342 
00343 template<typename VECTOR>
00344 VECTOR AbstractParameterisedSystem<VECTOR>::ComputeDerivedQuantitiesFromCurrentState(double time)
00345 {
00346     return this->ComputeDerivedQuantities(time, mStateVariables);
00347 }
00348 
00349 
00351 // Explicit instantiation
00353 
00354 template class AbstractParameterisedSystem<std::vector<double> >;
00355 #ifdef CHASTE_CVODE
00356 template class AbstractParameterisedSystem<N_Vector>;
00357 #endif