Lines 97-103
Link Here
|
97 |
} else currentStateLabelIter.next(); |
97 |
} else currentStateLabelIter.next(); |
98 |
} |
98 |
} |
99 |
} |
99 |
} |
100 |
|
100 |
|
101 |
if(jobs == null || jobs.length != num_threads) { |
101 |
if(jobs == null || jobs.length != num_threads) { |
102 |
// Initialize the jobs if not done yet or of the number of threads changes |
102 |
// Initialize the jobs if not done yet or of the number of threads changes |
103 |
jobs = new FdJob[num_threads]; |
103 |
jobs = new FdJob[num_threads]; |
Lines 107-119
Link Here
|
107 |
jobs[i] = new FdJob("Finite Difference Worker "+i, threadnum, this); |
107 |
jobs[i] = new FdJob("Finite Difference Worker "+i, threadnum, this); |
108 |
} // For each job |
108 |
} // For each job |
109 |
} // If not initialized |
109 |
} // If not initialized |
110 |
|
110 |
|
|
|
111 |
recursiveStep(time, timeDelta, cycle); |
112 |
|
113 |
return true; |
114 |
} |
115 |
|
116 |
protected void recursiveStep(STEMTime time, long timeDelta, int cycle) { |
111 |
// Initialize |
117 |
// Initialize |
112 |
|
118 |
|
113 |
for(FdJob j:jobs) { |
119 |
for(FdJob j:jobs) { |
114 |
j.cycle = cycle; |
120 |
j.cycle = cycle; |
115 |
j.time = time; |
121 |
j.time = time; |
116 |
j.timeDelta = timeDelta; |
122 |
j.timeDelta = timeDelta; |
|
|
123 |
j.step = FdJob.COMPUTE_DELTAS; |
117 |
} |
124 |
} |
118 |
|
125 |
|
119 |
// Schedule. Jobs can be rescheduled after finished |
126 |
// Schedule. Jobs can be rescheduled after finished |
Lines 129-158
Link Here
|
129 |
} |
136 |
} |
130 |
} |
137 |
} |
131 |
|
138 |
|
132 |
// Set the common time and step size here and validate everything is right |
139 |
double factor = 1.0; |
133 |
//double minStep = Double.MAX_VALUE; |
|
|
134 |
//double currentT = jobs[0].t; |
135 |
//for(SimJob j : jobs) { |
136 |
// The jobs have calculated new step sizes after they finished. Pick the |
137 |
// smallest one for the next cycle |
138 |
// if(j.h < minStep) minStep = j.h; |
139 |
// if(j.t != currentT) Activator.logError("Error, one thread was in misstep with other threads, its time was "+j.t+" versus "+currentT, new Exception()); |
140 |
//} |
141 |
|
140 |
|
142 |
//this.setCurrentX(currentT); |
141 |
for (FdJob j : jobs) { |
143 |
//this.setStepSize(minStep); // smallest one from above. |
142 |
factor = Math.min(factor, Double.parseDouble(j.getResult().getMessage())); |
144 |
return true; |
143 |
} |
|
|
144 |
|
145 |
if (factor == 1.0) { |
146 |
// Apply deltas |
147 |
|
148 |
for(FdJob j:jobs) |
149 |
j.step = FdJob.APPLY_DELTAS; |
150 |
|
151 |
for(FdJob j:jobs) |
152 |
j.schedule(); |
153 |
|
154 |
for(FdJob j : jobs) { |
155 |
try { |
156 |
j.join(); |
157 |
} catch(InterruptedException ie) { |
158 |
Activator.logError(ie.getMessage(), ie); |
159 |
} |
160 |
} |
161 |
} else { |
162 |
// Compute deltas for smaller time step |
163 |
long newTimeDelta = (long) Math.floor(factor*timeDelta); |
164 |
|
165 |
for(FdJob j:jobs) |
166 |
j.timeDelta = newTimeDelta; |
167 |
|
168 |
for(FdJob j:jobs) |
169 |
j.schedule(); |
170 |
|
171 |
for(FdJob j : jobs) { |
172 |
try { |
173 |
j.join(); |
174 |
} catch(InterruptedException ie) { |
175 |
Activator.logError(ie.getMessage(), ie); |
176 |
} |
177 |
} |
178 |
|
179 |
// Apply deltas |
180 |
|
181 |
for(FdJob j:jobs) |
182 |
j.step = FdJob.APPLY_DELTAS; |
183 |
|
184 |
for(FdJob j:jobs) |
185 |
j.schedule(); |
186 |
|
187 |
for(FdJob j : jobs) { |
188 |
try { |
189 |
j.join(); |
190 |
} catch(InterruptedException ie) { |
191 |
Activator.logError(ie.getMessage(), ie); |
192 |
} |
193 |
} |
194 |
|
195 |
// Call this method again for the rest of the time step |
196 |
|
197 |
for(Decorator decorator:this.getDecorators()) { |
198 |
EList<DynamicLabel>allLabels = decorator.getLabelsToUpdate(); |
199 |
for (final Iterator<DynamicLabel> currentStateLabelIter = allLabels |
200 |
.iterator(); currentStateLabelIter.hasNext();) { |
201 |
if(decorator instanceof IntegrationDecorator) { |
202 |
// It's a standard disease model with a standard disease model label |
203 |
final IntegrationLabel iLabel = (IntegrationLabel) currentStateLabelIter.next(); |
204 |
((IntegrationLabelValue)iLabel.getProbeValue()).set((IntegrationLabelValue)iLabel.getNextValue()); |
205 |
((IntegrationLabelValue)iLabel.getTempValue()).set((IntegrationLabelValue)iLabel.getNextValue()); |
206 |
((IntegrationLabelValue)iLabel.getTempValue()).prepareCycle(); |
207 |
((IntegrationLabelValue)iLabel.getProbeValue()).prepareCycle(); |
208 |
} else currentStateLabelIter.next(); |
209 |
} |
210 |
} |
211 |
|
212 |
recursiveStep(time, timeDelta - newTimeDelta, cycle); |
213 |
} |
145 |
} |
214 |
} |
146 |
|
215 |
|
147 |
/** |
216 |
protected double computeDeltasStep(STEMTime time, long timeDelta, int cycle, short threadnum) { |
148 |
* _step Do the step for a single thread |
|
|
149 |
* |
150 |
* @param time |
151 |
* @param timeDelta |
152 |
* @param cycle |
153 |
* @param threadnum |
154 |
*/ |
155 |
protected void _step(STEMTime time, long timeDelta, int cycle, short threadnum) { |
156 |
// Now give each decorator a chance to update its dynamic |
217 |
// Now give each decorator a chance to update its dynamic |
157 |
// labels in the canonical graph, but only if it is enabled. A |
218 |
// labels in the canonical graph, but only if it is enabled. A |
158 |
// Decorator might not be enabled if it is the action of a Trigger |
219 |
// Decorator might not be enabled if it is the action of a Trigger |
Lines 170-180
Link Here
|
170 |
for(IntegrationDecorator imodel:iDecorators) |
231 |
for(IntegrationDecorator imodel:iDecorators) |
171 |
imodel.applyExternalDeltas(time, timeDelta, partitioner.partitionDecoratorLabels((Decorator)imodel, threadnum)); |
232 |
imodel.applyExternalDeltas(time, timeDelta, partitioner.partitionDecoratorLabels((Decorator)imodel, threadnum)); |
172 |
|
233 |
|
|
|
234 |
double factor = 1.0; |
235 |
|
173 |
for(IntegrationDecorator imodel:iDecorators) |
236 |
for(IntegrationDecorator imodel:iDecorators) |
174 |
updateStandardDiseaseModelLabels((Decorator)imodel, time, timeDelta, cycle, threadnum); |
237 |
factor = Math.min(factor, getDeltaAdjustment((Decorator)imodel, threadnum)); |
175 |
|
238 |
|
|
|
239 |
return factor; |
240 |
} |
241 |
|
242 |
protected void applyDeltasStep(STEMTime time, long timeDelta, int cycle, short threadnum) { |
243 |
EList<IntegrationDecorator> iDecorators = new BasicEList<IntegrationDecorator>(); |
244 |
for (final Iterator<Decorator> decoratorIter = this |
245 |
.getDecorators().iterator(); decoratorIter.hasNext();) { |
246 |
final Decorator decorator = decoratorIter.next(); |
247 |
// Is the decorator enabled? |
248 |
if (decorator.isEnabled() && decorator instanceof IntegrationDecorator) iDecorators.add((IntegrationDecorator)decorator); |
249 |
} |
250 |
|
251 |
for(IntegrationDecorator imodel:iDecorators) |
252 |
updateStandardDiseaseModelLabels((Decorator)imodel, time, timeDelta, cycle, threadnum); |
176 |
} |
253 |
} |
177 |
|
254 |
|
|
|
255 |
protected double getDeltaAdjustment(Decorator model, short threadnum) { |
256 |
EList<DynamicLabel> myLabels = partitioner.partitionDecoratorLabels(model, threadnum); |
257 |
double factor = 1.0; |
258 |
|
259 |
for (final Iterator<DynamicLabel> currentStateLabelIter = myLabels |
260 |
.iterator(); currentStateLabelIter.hasNext();) { |
261 |
final IntegrationLabel label = (IntegrationLabel) currentStateLabelIter.next(); |
262 |
|
263 |
IntegrationLabelValue delta = (IntegrationLabelValue)label.getDeltaValue(); |
264 |
factor = Math.min(factor, delta.computeDeltaAdjustment((IntegrationLabelValue)label.getProbeValue())); |
265 |
} |
266 |
|
267 |
return factor; |
268 |
} |
178 |
|
269 |
|
179 |
protected void updateStandardDiseaseModelLabels(Decorator model, STEMTime time, long timeDelta, int cycle, short threadnum) { |
270 |
protected void updateStandardDiseaseModelLabels(Decorator model, STEMTime time, long timeDelta, int cycle, short threadnum) { |
180 |
|
271 |
|
Lines 189-201
Link Here
|
189 |
// Initialize the next value from the current value and add the delta |
280 |
// Initialize the next value from the current value and add the delta |
190 |
for (final Iterator<DynamicLabel> currentStateLabelIter = myLabels |
281 |
for (final Iterator<DynamicLabel> currentStateLabelIter = myLabels |
191 |
.iterator(); currentStateLabelIter.hasNext();) { |
282 |
.iterator(); currentStateLabelIter.hasNext();) { |
192 |
final DynamicLabel label = (DynamicLabel) currentStateLabelIter.next(); |
283 |
final IntegrationLabel label = (IntegrationLabel) currentStateLabelIter.next(); |
193 |
LabelValue nextState = label.getNextValue(); |
284 |
LabelValue nextState = label.getNextValue(); |
194 |
|
285 |
|
195 |
LabelValue delta = ((IntegrationLabel)label).getDeltaValue(); |
286 |
LabelValue delta = ((IntegrationLabel)label).getDeltaValue(); |
196 |
// For finite difference, we need to make sure we don't |
287 |
// For finite difference, we need to make sure we don't |
197 |
// move too many people from one state to another |
288 |
// move too many people from one state to another |
198 |
((IntegrationLabelValue)delta).adjustDelta((IntegrationLabelValue)label.getCurrentValue()); |
289 |
((IntegrationLabelValue)delta).avoidNegative((IntegrationLabelValue)label.getProbeValue()); |
199 |
|
290 |
|
200 |
nextState.reset(); |
291 |
nextState.reset(); |
201 |
// Add delta, this will also add the incidence |
292 |
// Add delta, this will also add the incidence |