AbstractParameterisedSystem.cpp

00001 /*
00002 
00003 Copyright (c) 2005-2015, 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>::DumpState(const std::string& message,
00068                                                            VECTOR Y,
00069                                                            double time)
00070 {
00071     std::stringstream extra_message;
00072     extra_message << std::endl << "At independent variable (usually time) = " << time;
00073     std::string new_message = message + extra_message.str();
00074     return GetStateMessage(new_message, Y);
00075 }
00076 
00077 template<typename VECTOR>
00078 std::string AbstractParameterisedSystem<VECTOR>::GetStateMessage(const std::string& message, VECTOR Y)
00079 {
00080     std::stringstream res;
00081     res << message << std::endl << "State:" << std::endl;
00082     assert(rGetStateVariableNames().size()==GetVectorSize(Y));
00083     const std::vector<std::string>& r_units = rGetStateVariableUnits();
00084     for (unsigned i=0; i<GetVectorSize(Y); i++)
00085     {
00086         res << "\t" << rGetStateVariableNames()[i] << ":" << GetVectorComponent(Y, i);
00087         if (!r_units.empty())
00088         {
00089             res << " " << r_units[i];
00090         }
00091         res << std::endl;
00092     }
00093     return res.str();
00094 }
00095 
00096 template<typename VECTOR>
00097 void AbstractParameterisedSystem<VECTOR>::CheckParametersOnLoad(const std::vector<double>& rParameters, const std::vector<std::string>& rParameterNames)
00098 {
00099     if (GetVectorSize(mParameters) != rGetParameterNames().size())
00100     {
00101         // Subclass constructor didn't give default values, so we need the archive to provide them all
00102         if (rParameterNames.size() != rGetParameterNames().size())
00103         {
00104             EXCEPTION("Number of ODE parameters in archive does not match number in class.");
00105         }
00106         CreateVectorIfEmpty(mParameters,rGetParameterNames().size());
00107     }
00108 
00109     // Check whether the archive specifies parameters that don't appear in this class,
00110     // and create a map from archive index to local index
00111     std::vector<unsigned> index_map(rParameterNames.size());
00112     for (unsigned i=0; i<rParameterNames.size(); ++i)
00113     {
00114         index_map[i] = find(rGetParameterNames().begin(), rGetParameterNames().end(), rParameterNames[i])
00115                        - rGetParameterNames().begin();
00116         if (index_map[i] == rGetParameterNames().size())
00117         {
00118             EXCEPTION("Archive specifies a parameter '" + rParameterNames[i] + "' which does not appear in this class.");
00119         }
00120     }
00121 
00122     for (unsigned i=0; i<rParameterNames.size(); ++i)
00123     {
00124         SetVectorComponent(mParameters,index_map[i],rParameters[i]);
00125     }
00126 
00127     // Paranoia check
00128     assert(GetVectorSize(mParameters) == rGetParameterNames().size());
00129 }
00130 
00131 //
00132 // State variable methods
00133 //
00134 
00135 template<typename VECTOR>
00136 VECTOR& AbstractParameterisedSystem<VECTOR>::rGetStateVariables()
00137 {
00138     return mStateVariables;
00139 }
00140 
00141 template<typename VECTOR>
00142 VECTOR AbstractParameterisedSystem<VECTOR>::GetStateVariables()
00143 {
00144     return CopyVector(mStateVariables);
00145 }
00146 
00147 template<typename VECTOR>
00148 void AbstractParameterisedSystem<VECTOR>::SetStateVariables(const VECTOR& rStateVariables)
00149 {
00150     if ( mNumberOfStateVariables != GetVectorSize(rStateVariables) )
00151     {
00152         EXCEPTION("The size of the passed in vector must be that of the number of state variables.");
00153     }
00154     CreateVectorIfEmpty(mStateVariables, mNumberOfStateVariables);
00155     for (unsigned i=0; i<mNumberOfStateVariables; i++)
00156     {
00157         SetVectorComponent(mStateVariables, i, GetVectorComponent(rStateVariables, i));
00158     }
00159 }
00160 
00161 template<typename VECTOR>
00162 double AbstractParameterisedSystem<VECTOR>::GetStateVariable(unsigned index) const
00163 {
00164     if (index >= mNumberOfStateVariables)
00165     {
00166         EXCEPTION("The index passed in must be less than the number of state variables.");
00167     }
00168     return GetVectorComponent(mStateVariables, index);
00169 }
00170 
00171 template<typename VECTOR>
00172 double AbstractParameterisedSystem<VECTOR>::GetStateVariable(const std::string& rName) const
00173 {
00174     return GetStateVariable(GetStateVariableIndex(rName));
00175 }
00176 
00177 template<typename VECTOR>
00178 void AbstractParameterisedSystem<VECTOR>::SetStateVariable(unsigned index, double newValue)
00179 {
00180     if ( mNumberOfStateVariables <= index )
00181     {
00182         EXCEPTION("The index passed in must be less than the number of state variables.");
00183     }
00184     SetVectorComponent(mStateVariables, index, newValue);
00185 }
00186 
00187 template<typename VECTOR>
00188 void AbstractParameterisedSystem<VECTOR>::SetStateVariable(const std::string& rName, double newValue)
00189 {
00190     SetStateVariable(GetStateVariableIndex(rName), newValue);
00191 }
00192 
00193 
00194 //
00195 // Initial condition methods
00196 //
00197 
00198 template<typename VECTOR>
00199 void AbstractParameterisedSystem<VECTOR>::SetDefaultInitialConditions(const VECTOR& rInitialConditions)
00200 {
00201     if (GetVectorSize(rInitialConditions) != mNumberOfStateVariables)
00202     {
00203         EXCEPTION("The number of initial conditions must be that of the number of state variables.");
00204     }
00205     assert(mpSystemInfo);
00206     std::vector<double> inits;
00207     CopyToStdVector(rInitialConditions, inits);
00208     mpSystemInfo->SetDefaultInitialConditions(inits);
00209 }
00210 
00211 template<typename VECTOR>
00212 void AbstractParameterisedSystem<VECTOR>::SetDefaultInitialCondition(unsigned index, double initialCondition)
00213 {
00214     if (index >= mNumberOfStateVariables)
00215     {
00216         EXCEPTION("Index is greater than the number of state variables.");
00217     }
00218     assert(mpSystemInfo);
00219     mpSystemInfo->SetDefaultInitialCondition(index, initialCondition);
00220 }
00221 
00222 template<typename VECTOR>
00223 VECTOR AbstractParameterisedSystem<VECTOR>::GetInitialConditions() const
00224 {
00225     assert(mpSystemInfo);
00226     VECTOR v;
00227     InitialiseEmptyVector(v);
00228     CreateVectorIfEmpty(v, mNumberOfStateVariables);
00229     CopyFromStdVector(mpSystemInfo->GetInitialConditions(), v);
00230     return v;
00231 }
00232 
00233 template<typename VECTOR>
00234 void AbstractParameterisedSystem<VECTOR>::ResetToInitialConditions()
00235 {
00236     VECTOR inits = GetInitialConditions();
00237     SetStateVariables(inits);
00238     DeleteVector(inits);
00239 }
00240 
00241 //
00242 // Parameter methods
00243 //
00244 
00245 template<typename VECTOR>
00246 double AbstractParameterisedSystem<VECTOR>::GetParameter(unsigned index) const
00247 {
00248     if (index >= GetVectorSize(mParameters))
00249     {
00250         EXCEPTION("The index passed in must be less than the number of parameters.");
00251     }
00252     return GetVectorComponent(mParameters, index);
00253 }
00254 
00255 template<typename VECTOR>
00256 void AbstractParameterisedSystem<VECTOR>::SetParameter(unsigned index, double value)
00257 {
00258     if (index >= GetVectorSize(mParameters))
00259     {
00260         EXCEPTION("The index passed in must be less than the number of parameters.");
00261     }
00262     SetVectorComponent(mParameters, index, value);
00263 }
00264 
00265 template<typename VECTOR>
00266 void AbstractParameterisedSystem<VECTOR>::SetParameter(const std::string& rName, double value)
00267 {
00268     SetVectorComponent(mParameters, GetParameterIndex(rName), value);
00269 }
00270 
00271 template<typename VECTOR>
00272 double AbstractParameterisedSystem<VECTOR>::GetParameter(const std::string& rName) const
00273 {
00274     return GetParameter(GetParameterIndex(rName));
00275 }
00276 
00277 //
00278 // "Any variable" methods
00279 //
00280 
00281 template<typename VECTOR>
00282 double AbstractParameterisedSystem<VECTOR>::GetAnyVariable(unsigned index, double time,
00283                                                            VECTOR* pDerivedQuantities)
00284 {
00285     if (index < mNumberOfStateVariables)
00286     {
00287         return GetVectorComponent(mStateVariables, index);
00288     }
00289     else if (index - mNumberOfStateVariables < GetVectorSize(mParameters))
00290     {
00291         return GetVectorComponent(mParameters, index - mNumberOfStateVariables);
00292     }
00293     else
00294     {
00295         unsigned offset = mNumberOfStateVariables + GetVectorSize(mParameters);
00296         if (index - offset < GetNumberOfDerivedQuantities())
00297         {
00298             VECTOR dqs;
00299             if (pDerivedQuantities == NULL)
00300             {
00301                 dqs = ComputeDerivedQuantitiesFromCurrentState(time);
00302                 pDerivedQuantities = &dqs;
00303             }
00304             double value = GetVectorComponent(*pDerivedQuantities, index - offset);
00305             if (pDerivedQuantities == &dqs)
00306             {
00307                 DeleteVector(dqs);
00308             }
00309             return value;
00310         }
00311         else
00312         {
00313             EXCEPTION("Invalid index passed to GetAnyVariable.");
00314         }
00315     }
00316 }
00317 
00318 template<typename VECTOR>
00319 double AbstractParameterisedSystem<VECTOR>::GetAnyVariable(const std::string& rName,
00320                                                            double time,
00321                                                            VECTOR* pDerivedQuantities)
00322 {
00323     return GetAnyVariable(GetAnyVariableIndex(rName), time, pDerivedQuantities);
00324 }
00325 
00326 template<typename VECTOR>
00327 void AbstractParameterisedSystem<VECTOR>::SetAnyVariable(unsigned index, double value)
00328 {
00329     if (index < mNumberOfStateVariables)
00330     {
00331         SetVectorComponent(mStateVariables, index, value);
00332     }
00333     else if (index - mNumberOfStateVariables < GetVectorSize(mParameters))
00334     {
00335         SetVectorComponent(mParameters, index - mNumberOfStateVariables, value);
00336     }
00337     else
00338     {
00339         EXCEPTION("Cannot set the value of a derived quantity, or invalid index.");
00340     }
00341 }
00342 
00343 template<typename VECTOR>
00344 void AbstractParameterisedSystem<VECTOR>::SetAnyVariable(const std::string& rName, double value)
00345 {
00346     SetAnyVariable(GetAnyVariableIndex(rName), value);
00347 }
00348 
00349 //
00350 // "Derived quantities" methods
00351 //
00352 
00353 template<typename VECTOR>
00354 VECTOR AbstractParameterisedSystem<VECTOR>::ComputeDerivedQuantities(double time,
00355                                                                      const VECTOR& rState)
00356 {
00357     EXCEPTION("This ODE system does not define derived quantities.");
00358 }
00359 
00360 template<typename VECTOR>
00361 VECTOR AbstractParameterisedSystem<VECTOR>::ComputeDerivedQuantitiesFromCurrentState(double time)
00362 {
00363     return this->ComputeDerivedQuantities(time, mStateVariables);
00364 }
00365 
00366 
00368 // Explicit instantiation
00370 
00371 template class AbstractParameterisedSystem<std::vector<double> >;
00372 #ifdef CHASTE_CVODE
00373 template class AbstractParameterisedSystem<N_Vector>;
00374 #endif

Generated by  doxygen 1.6.2