Chaste  Release::3.4
AbstractParameterisedSystem.cpp
1 /*
2 
3 Copyright (c) 2005-2016, University of Oxford.
4 All rights reserved.
5 
6 University of Oxford means the Chancellor, Masters and Scholars of the
7 University of Oxford, having an administrative office at Wellington
8 Square, Oxford OX1 2JD, UK.
9 
10 This file is part of Chaste.
11 
12 Redistribution and use in source and binary forms, with or without
13 modification, 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 
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 
34 */
35 
36 #include <sstream>
37 #include <cassert>
38 
39 #include "AbstractParameterisedSystem.hpp"
40 
41 #include "Exception.hpp"
43 
44 
45 template<typename VECTOR>
47  : AbstractUntemplatedParameterisedSystem(numberOfStateVariables)
48 {
51 }
52 
53 template<typename VECTOR>
54 std::string AbstractParameterisedSystem<VECTOR>::DumpState(const std::string& rMessage)
55 {
56  return GetStateMessage(rMessage, mStateVariables);
57 }
58 
59 template<typename VECTOR>
60 std::string AbstractParameterisedSystem<VECTOR>::DumpState(const std::string& rMessage,
61  VECTOR Y)
62 {
63  return GetStateMessage(rMessage, Y);
64 }
65 
66 template<typename VECTOR>
67 std::string AbstractParameterisedSystem<VECTOR>::DumpState(const std::string& rMessage,
68  VECTOR Y,
69  double time)
70 {
71  std::stringstream extra_message;
72  extra_message << std::endl << "At independent variable (usually time) = " << time;
73  std::string new_message = rMessage + extra_message.str();
74  return GetStateMessage(new_message, Y);
75 }
76 
77 template<typename VECTOR>
78 std::string AbstractParameterisedSystem<VECTOR>::GetStateMessage(const std::string& rMessage, VECTOR Y)
79 {
80  std::stringstream res;
81  res << rMessage << std::endl << "State:" << std::endl;
82  assert(rGetStateVariableNames().size()==GetVectorSize(Y));
83  const std::vector<std::string>& r_units = rGetStateVariableUnits();
84  for (unsigned i=0; i<GetVectorSize(Y); i++)
85  {
86  res << "\t" << rGetStateVariableNames()[i] << ":" << GetVectorComponent(Y, i);
87  if (!r_units.empty())
88  {
89  res << " " << r_units[i];
90  }
91  res << std::endl;
92  }
93  return res.str();
94 }
95 
96 template<typename VECTOR>
97 void AbstractParameterisedSystem<VECTOR>::CheckParametersOnLoad(const std::vector<double>& rParameters, const std::vector<std::string>& rParameterNames)
98 {
99  if (GetVectorSize(mParameters) != rGetParameterNames().size())
100  {
101  // Subclass constructor didn't give default values, so we need the archive to provide them all
102  if (rParameterNames.size() != rGetParameterNames().size())
103  {
104  EXCEPTION("Number of ODE parameters in archive does not match number in class.");
105  }
106  CreateVectorIfEmpty(mParameters,rGetParameterNames().size());
107  }
108 
109  // Check whether the archive specifies parameters that don't appear in this class,
110  // and create a map from archive index to local index
111  std::vector<unsigned> index_map(rParameterNames.size());
112  for (unsigned i=0; i<rParameterNames.size(); ++i)
113  {
114  index_map[i] = find(rGetParameterNames().begin(), rGetParameterNames().end(), rParameterNames[i])
115  - rGetParameterNames().begin();
116  if (index_map[i] == rGetParameterNames().size())
117  {
118  EXCEPTION("Archive specifies a parameter '" + rParameterNames[i] + "' which does not appear in this class.");
119  }
120  }
121 
122  for (unsigned i=0; i<rParameterNames.size(); ++i)
123  {
124  SetVectorComponent(mParameters,index_map[i],rParameters[i]);
125  }
126 
127  // Paranoia check
128  assert(GetVectorSize(mParameters) == rGetParameterNames().size());
129 }
130 
131 //
132 // State variable methods
133 //
134 
135 template<typename VECTOR>
137 {
138  return mStateVariables;
139 }
140 
141 template<typename VECTOR>
143 {
144  return CopyVector(mStateVariables);
145 }
146 
147 template<typename VECTOR>
149 {
150 
151  if ( mNumberOfStateVariables != GetVectorSize(rStateVariables) )
152  {
153  EXCEPTION("The size of the passed in vector must be that of the number of state variables.");
154  }
155 
156  CreateVectorIfEmpty(mStateVariables, mNumberOfStateVariables);
157  for (unsigned i=0; i<mNumberOfStateVariables; i++)
158  {
159  SetVectorComponent(mStateVariables, i, GetVectorComponent(rStateVariables, i));
160  }
161 }
162 
163 template<typename VECTOR>
165 {
166  if (index >= mNumberOfStateVariables)
167  {
168  EXCEPTION("The index passed in must be less than the number of state variables.");
169  }
170  return GetVectorComponent(mStateVariables, index);
171 }
172 
173 template<typename VECTOR>
174 double AbstractParameterisedSystem<VECTOR>::GetStateVariable(const std::string& rName) const
175 {
176  return GetStateVariable(GetStateVariableIndex(rName));
177 }
178 
179 template<typename VECTOR>
180 void AbstractParameterisedSystem<VECTOR>::SetStateVariable(unsigned index, double newValue)
181 {
182  if ( mNumberOfStateVariables <= index )
183  {
184  EXCEPTION("The index passed in must be less than the number of state variables.");
185  }
186  SetVectorComponent(mStateVariables, index, newValue);
187 }
188 
189 template<typename VECTOR>
190 void AbstractParameterisedSystem<VECTOR>::SetStateVariable(const std::string& rName, double newValue)
191 {
192  SetStateVariable(GetStateVariableIndex(rName), newValue);
193 }
194 
195 
196 //
197 // Initial condition methods
198 //
199 
200 template<typename VECTOR>
202 {
203  if (GetVectorSize(rInitialConditions) != mNumberOfStateVariables)
204  {
205  EXCEPTION("The number of initial conditions must be that of the number of state variables.");
206  }
207  assert(mpSystemInfo);
208  std::vector<double> inits;
209  CopyToStdVector(rInitialConditions, inits);
210  mpSystemInfo->SetDefaultInitialConditions(inits);
211 }
212 
213 template<typename VECTOR>
214 void AbstractParameterisedSystem<VECTOR>::SetDefaultInitialCondition(unsigned index, double initialCondition)
215 {
216  if (index >= mNumberOfStateVariables)
217  {
218  EXCEPTION("Index is greater than the number of state variables.");
219  }
220  assert(mpSystemInfo);
221  mpSystemInfo->SetDefaultInitialCondition(index, initialCondition);
222 }
223 
224 template<typename VECTOR>
226 {
227  assert(mpSystemInfo);
228  VECTOR v;
230  CreateVectorIfEmpty(v, mNumberOfStateVariables);
231  CopyFromStdVector(mpSystemInfo->GetInitialConditions(), v);
232  return v;
233 }
234 
235 template<typename VECTOR>
237 {
238  VECTOR inits = GetInitialConditions();
239  SetStateVariables(inits);
240  DeleteVector(inits);
241 }
242 
243 //
244 // Parameter methods
245 //
246 
247 template<typename VECTOR>
249 {
250  if (index >= GetVectorSize(mParameters))
251  {
252  EXCEPTION("The index passed in must be less than the number of parameters.");
253  }
254  return GetVectorComponent(mParameters, index);
255 }
256 
257 template<typename VECTOR>
258 void AbstractParameterisedSystem<VECTOR>::SetParameter(unsigned index, double value)
259 {
260  if (index >= GetVectorSize(mParameters))
261  {
262  EXCEPTION("The index passed in must be less than the number of parameters.");
263  }
264  SetVectorComponent(mParameters, index, value);
265 }
266 
267 template<typename VECTOR>
268 void AbstractParameterisedSystem<VECTOR>::SetParameter(const std::string& rName, double value)
269 {
270  SetVectorComponent(mParameters, GetParameterIndex(rName), value);
271 }
272 
273 template<typename VECTOR>
274 double AbstractParameterisedSystem<VECTOR>::GetParameter(const std::string& rName) const
275 {
276  return GetParameter(GetParameterIndex(rName));
277 }
278 
279 //
280 // "Any variable" methods
281 //
282 
283 template<typename VECTOR>
284 double AbstractParameterisedSystem<VECTOR>::GetAnyVariable(unsigned index, double time,
285  VECTOR* pDerivedQuantities)
286 {
287  if (index < mNumberOfStateVariables)
288  {
289  return GetVectorComponent(mStateVariables, index);
290  }
291  else if (index - mNumberOfStateVariables < GetVectorSize(mParameters))
292  {
293  return GetVectorComponent(mParameters, index - mNumberOfStateVariables);
294  }
295  else
296  {
297  unsigned offset = mNumberOfStateVariables + GetVectorSize(mParameters);
298  if (index - offset < GetNumberOfDerivedQuantities())
299  {
300  VECTOR dqs;
301  if (pDerivedQuantities == NULL)
302  {
303  dqs = ComputeDerivedQuantitiesFromCurrentState(time);
304  pDerivedQuantities = &dqs;
305  }
306  double value = GetVectorComponent(*pDerivedQuantities, index - offset);
307  if (pDerivedQuantities == &dqs)
308  {
309  DeleteVector(dqs);
310  }
311  return value;
312  }
313  else
314  {
315  EXCEPTION("Invalid index passed to GetAnyVariable.");
316  }
317  }
318 }
319 
320 template<typename VECTOR>
322  double time,
323  VECTOR* pDerivedQuantities)
324 {
325  return GetAnyVariable(GetAnyVariableIndex(rName), time, pDerivedQuantities);
326 }
327 
328 template<typename VECTOR>
329 void AbstractParameterisedSystem<VECTOR>::SetAnyVariable(unsigned index, double value)
330 {
331  if (index < mNumberOfStateVariables)
332  {
333  SetVectorComponent(mStateVariables, index, value);
334  }
335  else if (index - mNumberOfStateVariables < GetVectorSize(mParameters))
336  {
337  SetVectorComponent(mParameters, index - mNumberOfStateVariables, value);
338  }
339  else
340  {
341  EXCEPTION("Cannot set the value of a derived quantity, or invalid index.");
342  }
343 }
344 
345 template<typename VECTOR>
346 void AbstractParameterisedSystem<VECTOR>::SetAnyVariable(const std::string& rName, double value)
347 {
348  SetAnyVariable(GetAnyVariableIndex(rName), value);
349 }
350 
351 //
352 // "Derived quantities" methods
353 //
354 
355 template<typename VECTOR>
357  const VECTOR& rState)
358 {
359  EXCEPTION("This ODE system does not define derived quantities.");
360 }
361 
362 template<typename VECTOR>
364 {
365  return this->ComputeDerivedQuantities(time, mStateVariables);
366 }
367 
368 
370 // Explicit instantiation
372 
374 #ifdef CHASTE_CVODE
376 #endif
void SetDefaultInitialCondition(unsigned index, double initialCondition)
void SetDefaultInitialConditions(const VECTOR &rInitialConditions)
#define EXCEPTION(message)
Definition: Exception.hpp:143
VECTOR CopyVector(VECTOR &rVec)
std::string DumpState(const std::string &rMessage)
void InitialiseEmptyVector(VECTOR &rVec)
void SetStateVariables(const VECTOR &rStateVariables)
double GetStateVariable(unsigned index) const
double GetParameter(unsigned index) const
void CreateVectorIfEmpty(VECTOR &rVec, unsigned size)
void SetVectorComponent(VECTOR &rVec, unsigned index, double value)
void SetAnyVariable(unsigned index, double value)
void SetParameter(const std::string &rName, double value)
virtual VECTOR ComputeDerivedQuantities(double time, const VECTOR &rState)
void SetStateVariable(unsigned index, double newValue)
void CopyFromStdVector(const std::vector< double > &rSrc, VECTOR &rDest)
void CheckParametersOnLoad(const std::vector< double > &rParameters, const std::vector< std::string > &rParameterNames)
void CopyToStdVector(const VECTOR &rSrc, std::vector< double > &rDest)
double GetVectorComponent(const VECTOR &rVec, unsigned index)
VECTOR ComputeDerivedQuantitiesFromCurrentState(double time)
std::string GetStateMessage(const std::string &rMessage, VECTOR Y)
void DeleteVector(VECTOR &rVec)
double GetAnyVariable(unsigned index, double time=0.0, VECTOR *pDerivedQuantities=NULL)
unsigned GetVectorSize(const VECTOR &rVec)
AbstractParameterisedSystem(unsigned numberOfStateVariables)