Chaste Release::3.1
|
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