COPASI API  4.16.103
CMathDependencyNode.cpp
Go to the documentation of this file.
1 // Copyright (C) 2011 - 2013 by Pedro Mendes, Virginia Tech Intellectual
2 // Properties, Inc., University of Heidelberg, and The University
3 // of Manchester.
4 // All rights reserved.
5 
6 #include "copasi.h"
7 
8 #include "CMathDependencyNode.h"
9 #include "CMathObject.h"
11 
12 #include "model/CMetab.h"
13 
15  mpObject(NULL),
16  mPrerequisites(),
17  mDependents(),
18  mChanged(false),
19  mRequested(false)
20 {}
21 
23  mpObject(pObject),
24  mPrerequisites(),
25  mDependents(),
26  mChanged(false),
27  mRequested(false)
28 {}
29 
31 {}
32 
34 {
35  return mpObject;
36 }
37 
39 {
40  mPrerequisites.push_back(pObject);
41 }
42 
43 std::vector< CMathDependencyNode * > & CMathDependencyNode::getPrerequisites()
44 {
45  return mPrerequisites;
46 }
47 
49 {
50  mDependents.push_back(pObject);
51 }
52 
53 std::vector< CMathDependencyNode * > & CMathDependencyNode::getDependents()
54 {
55  return mDependents;
56 }
57 
59  const CObjectInterface::ObjectSet & changedObjects)
60 {
63 
64  while (itNode.next())
65  {
66  // If we have a recursive dependency we need make sure that this is due to
67  // an intensive/extensive value pair
69  {
70  if (itNode->getObject()->isPrerequisiteForContext(itNode.parent()->getObject(), context, changedObjects))
71  {
72  return false;
73  }
74 
75  continue;
76  }
77 
78  // The node itself is not modified.
79  if (*itNode == this)
80  {
81  continue;
82  }
83 
84  // We are guaranteed that the current node has a parent as the only node without is this,
85  // which is handled above.
86  if (!itNode->isChanged() &&
87  itNode->getObject()->isPrerequisiteForContext(itNode.parent()->getObject(), context, changedObjects))
88  {
89  itNode->setChanged(true);
90  }
91  else
92  {
93  itNode.skipChildren();
94  }
95  }
96 
97  return itNode.state() == CMathDependencyNodeIterator::End;
98 }
99 
101  const CObjectInterface::ObjectSet & changedObjects)
102 {
105 
106  while (itNode.next())
107  {
108  // If we have a recursive dependency we need make sure that this is due to
109  // an intensive/extensive value pair
111  {
112  if (itNode.parent()->getObject()->isPrerequisiteForContext(itNode->getObject(), context, changedObjects))
113  {
114  return false;
115  }
116 
117  continue;
118  }
119 
120  // The node itself is not modified.
121  if (*itNode == this)
122  {
123  continue;
124  }
125 
126  // We are guaranteed that the current node has a parent as the only node without is this,
127  // which is handled above.
128  if (!itNode->isRequested() &&
129  itNode.parent()->getObject()->isPrerequisiteForContext(itNode->getObject(), context, changedObjects))
130  {
131  itNode->setRequested(true);
132  }
133  else
134  {
135  itNode.skipChildren();
136  }
137  }
138 
139  return itNode.state() == CMathDependencyNodeIterator::End;
140 }
141 
143  CObjectInterface::UpdateSequence & updateSequence)
144 {
145  if (!mChanged || !mRequested)
146  return true;
147 
150 
151  while (itNode.next())
152  {
153  switch (itNode.state())
154  {
156 
157  if (!itNode->isChanged() || !itNode->isRequested())
158  {
159  itNode.skipChildren();
160  }
161 
162  break;
163 
165 
166  // This check is not needed as unchanged or unrequested nodes
167  // are skipped in Before processing.
168  if (itNode->isChanged() && itNode->isRequested())
169  {
170  const CObjectInterface * pObject = itNode->getObject();
171  const CMathObject * pMathObject = NULL;
172  const CParticleReference * pParticleNumber = NULL;
173 
174  // For an extensive transient value of a dependent species we have 2
175  // possible assignments depending on the context.
176  // 1) Conversion from the intensive property
177  // 2) Dependent mass off a moiety
178  //
179  // The solution is that the moiety automatically updates the value in conjunction
180  // with the dependency graph omitting the value in the update sequence if the context
181  // is CMath::UseMoieties.
182 
183  if (!(context & CMath::UseMoieties) ||
184  ((pMathObject = dynamic_cast< const CMathObject *>(pObject)) == NULL &&
185  (pParticleNumber = dynamic_cast< const CParticleReference *>(pObject)) == NULL) ||
186  (pMathObject != NULL &&
187  (pMathObject->getSimulationType() != CMath::Dependent ||
188  pMathObject->getValueType() != CMath::Value)) ||
189  (pParticleNumber != NULL &&
190  !static_cast< const CMetab * >(pParticleNumber->getObjectParent())->isDependent()))
191  {
192  updateSequence.push_back(const_cast< CObjectInterface * >(itNode->getObject()));
193  itNode->setChanged(false);
194  }
195  }
196 
197  break;
198 
199  default:
200  break;
201  }
202  }
203 
204  mChanged = false;
205 
206  return itNode.state() == CMathDependencyNodeIterator::End;
207 }
208 
209 void CMathDependencyNode::setChanged(const bool & changed)
210 {
211  mChanged = changed;
212 }
213 
214 const bool & CMathDependencyNode::isChanged() const
215 {
216  return mChanged;
217 }
218 
219 void CMathDependencyNode::setRequested(const bool & requested)
220 {
221  mRequested = requested;
222 }
223 
225 {
226  return mRequested;
227 }
std::vector< CMathDependencyNode * > & getPrerequisites()
void addPrerequisite(CMathDependencyNode *pNode)
const bool & isChanged() const
const CObjectInterface * mpObject
const CObjectInterface * getObject() const
const CMath::SimulationType & getSimulationType() const
void addDependent(CMathDependencyNode *pNode)
void setRequested(const bool &requested)
Definition: CMetab.h:178
void setChanged(const bool &changed)
std::vector< CMathDependencyNode * > mDependents
virtual bool isPrerequisiteForContext(const CObjectInterface *pObject, const CMath::SimulationContextFlag &context, const CObjectInterface::ObjectSet &changedObjects) const =0
std::set< const CObjectInterface * > ObjectSet
bool updatePrerequisiteState(const CMath::SimulationContextFlag &context, const CObjectInterface::ObjectSet &changedObjects)
const CMath::ValueType & getValueType() const
bool updateDependentState(const CMath::SimulationContextFlag &context, const CObjectInterface::ObjectSet &changedObjects)
const CMathDependencyNode * parent()
std::vector< CMathDependencyNode * > & getDependents()
std::vector< CMathDependencyNode * > mPrerequisites
const bool & isRequested() const
bool buildUpdateSequence(const CMath::SimulationContextFlag &context, CObjectInterface::UpdateSequence &updateSequence)
CCopasiContainer * getObjectParent() const
std::vector< CObjectInterface * > UpdateSequence
void setProcessingModes(const Flag &processingModes)