2 Highly Optimized Object-oriented Many-particle Dynamics -- Blue Edition
3 (HOOMD-blue) Open Source Software License Copyright 2009-2014 The Regents of
4 the University of Michigan All rights reserved.
6 HOOMD-blue may contain modifications ("Contributions") provided, and to which
7 copyright is held, by various Contributors who have granted The Regents of the
8 University of Michigan the right to modify and/or distribute such Contributions.
10 You may redistribute, use, and create derivate works of HOOMD-blue, in source
11 and binary forms, provided you abide by the following conditions:
13 * Redistributions of source code must retain the above copyright notice, this
14 list of conditions, and the following disclaimer both in the code and
15 prominently in any materials provided with the distribution.
17 * Redistributions in binary form must reproduce the above copyright notice, this
18 list of conditions, and the following disclaimer in the documentation and/or
19 other materials provided with the distribution.
21 * All publications and presentations based on HOOMD-blue, including any reports
22 or published results obtained, in whole or in part, with HOOMD-blue, will
23 acknowledge its use according to the terms posted at the time of submission on:
24 http://codeblue.umich.edu/hoomd-blue/citations.html
26 * Any electronic documents citing HOOMD-Blue will link to the HOOMD-Blue website:
27 http://codeblue.umich.edu/hoomd-blue/
29 * Apart from the above required attributions, neither the name of the copyright
30 holder nor the names of HOOMD-blue's contributors may be used to endorse or
31 promote products derived from this software without specific prior written
36 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND
37 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
38 WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND/OR ANY
39 WARRANTIES THAT THIS SOFTWARE IS FREE OF INFRINGEMENT ARE DISCLAIMED.
41 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
42 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
43 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
45 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
46 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
47 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 // Maintainer: joaander
53 \brief Defines the System class
57 #pragma warning( push )
58 #pragma warning( disable : 4103 4244 )
62 #include "SignalHandler.h"
64 #include <boost/python.hpp>
65 using namespace boost::python
;
70 #include "Communicator.h"
75 /*! \param sysdef SystemDefinition for the system to be simulated
76 \param initial_tstep Initial time step of the simulation
78 \post The System is constructed with no attached computes, updaters,
79 analyzers or integrators. Profiling defaults to disabled and
80 statistics are printed every 10 seconds.
82 System::System(boost::shared_ptr
<SystemDefinition
> sysdef
, unsigned int initial_tstep
)
83 : m_sysdef(sysdef
), m_start_tstep(initial_tstep
), m_end_tstep(0), m_cur_tstep(initial_tstep
),
84 m_last_status_time(0), m_last_status_tstep(initial_tstep
), m_quiet_run(false),
85 m_profile(false), m_stats_period(10)
89 m_exec_conf
= m_sysdef
->getParticleData()->getExecConf();
92 // the initial time step is defined on the root processor
93 if (m_sysdef
->getParticleData()->getDomainDecomposition())
95 bcast(m_start_tstep
, 0, m_exec_conf
->getMPICommunicator());
96 bcast(m_cur_tstep
, 0, m_exec_conf
->getMPICommunicator());
97 bcast(m_last_status_tstep
, 0, m_exec_conf
->getMPICommunicator());
102 /*! \param analyzer Shared pointer to the Analyzer to add
103 \param name A unique name to identify the Analyzer by
104 \param period Analyzer::analyze() will be called for every time step that is a multiple
107 All Analyzers will be called, in the order that they are added, and with the specified
108 \a period during time step calculations performed when run() is called. An analyzer
109 can be prevented from running in future runs by removing it (removeAnalyzer()) before
112 void System::addAnalyzer(boost::shared_ptr
<Analyzer
> analyzer
, const std::string
& name
, unsigned int period
)
118 // first check that the name is unique
119 vector
<analyzer_item
>::iterator i
;
120 for (i
= m_analyzers
.begin(); i
!= m_analyzers
.end(); ++i
)
122 if (i
->m_name
== name
)
124 m_exec_conf
->msg
->error() << "Analyzer " << name
<< " already exists" << endl
;
125 throw runtime_error("System: cannot add Analyzer");
129 // if we get here, we can add it
130 m_analyzers
.push_back(analyzer_item(analyzer
, name
, period
, m_cur_tstep
));
133 /*! \param name Name of the Analyzer to find in m_analyzers
134 \returns An iterator into m_analyzers of the found Analyzer
136 std::vector
<System::analyzer_item
>::iterator
System::findAnalyzerItem(const std::string
&name
)
138 // search for the analyzer
139 vector
<analyzer_item
>::iterator i
;
140 for (i
= m_analyzers
.begin(); i
!= m_analyzers
.end(); ++i
)
142 if (i
->m_name
== name
)
148 m_exec_conf
->msg
->error() << "Analyzer " << name
<< " not found" << endl
;
149 throw runtime_error("System: cannot find Analyzer");
151 return m_analyzers
.begin();
154 /*! \param name Name of the Analyzer to be removed
157 void System::removeAnalyzer(const std::string
& name
)
159 vector
<analyzer_item
>::iterator i
= findAnalyzerItem(name
);
160 m_analyzers
.erase(i
);
163 /*! \param name Name of the Analyzer to retrieve
164 \returns A shared pointer to the requested Analyzer
166 boost::shared_ptr
<Analyzer
> System::getAnalyzer(const std::string
& name
)
168 vector
<System::analyzer_item
>::iterator i
= findAnalyzerItem(name
);
169 return i
->m_analyzer
;
172 /*! \param name Name of the Analyzer to modify
173 \param period New period to set
175 void System::setAnalyzerPeriod(const std::string
& name
, unsigned int period
)
180 vector
<System::analyzer_item
>::iterator i
= findAnalyzerItem(name
);
181 i
->setPeriod(period
, m_cur_tstep
);
184 /*! \param name Name of the Updater to modify
185 \param update_func A python callable function taking one argument that returns an integer value of the next time step to analyze at
187 void System::setAnalyzerPeriodVariable(const std::string
& name
, boost::python::object update_func
)
189 vector
<System::analyzer_item
>::iterator i
= findAnalyzerItem(name
);
190 i
->setVariablePeriod(update_func
, m_cur_tstep
);
194 /*! \param name Name of the Analyzer to get the period of
195 \returns Period of the Analyzer
197 unsigned int System::getAnalyzerPeriod(const std::string
& name
)
199 vector
<System::analyzer_item
>::iterator i
= findAnalyzerItem(name
);
204 // -------------- Updater get/set methods
205 /*! \param name Name of the Updater to find in m_updaters
206 \returns An iterator into m_updaters of the found Updater
208 std::vector
<System::updater_item
>::iterator
System::findUpdaterItem(const std::string
&name
)
210 // search for the analyzer
211 vector
<System::updater_item
>::iterator i
;
212 for (i
= m_updaters
.begin(); i
!= m_updaters
.end(); ++i
)
214 if (i
->m_name
== name
)
220 m_exec_conf
->msg
->error() << "Updater " << name
<< " not found" << endl
;
221 throw runtime_error("System: cannot find Updater");
223 return m_updaters
.begin();
227 /*! \param updater Shared pointer to the Updater to add
228 \param name A unique name to identify the Updater by
229 \param period Updater::update() will be called for every time step that is a multiple
232 All Updaters will be called, in the order that they are added, and with the specified
233 \a period during time step calculations performed when run() is called. An updater
234 can be prevented from running in future runs by removing it (removeUpdater()) before
237 void System::addUpdater(boost::shared_ptr
<Updater
> updater
, const std::string
& name
, unsigned int period
)
243 // first check that the name is unique
244 vector
<updater_item
>::iterator i
;
245 for (i
= m_updaters
.begin(); i
!= m_updaters
.end(); ++i
)
247 if (i
->m_name
== name
)
249 m_exec_conf
->msg
->error() << "Updater " << name
<< " already exists" << endl
;
250 throw runtime_error("System: cannot add Updater");
254 // if we get here, we can add it
255 m_updaters
.push_back(updater_item(updater
, name
, period
, m_cur_tstep
));
258 /*! \param name Name of the Updater to be removed
261 void System::removeUpdater(const std::string
& name
)
263 vector
<updater_item
>::iterator i
= findUpdaterItem(name
);
267 /*! \param name Name of the Updater to retrieve
268 \returns A shared pointer to the requested Updater
270 boost::shared_ptr
<Updater
> System::getUpdater(const std::string
& name
)
272 vector
<System::updater_item
>::iterator i
= findUpdaterItem(name
);
276 /*! \param name Name of the Updater to modify
277 \param period New period to set
279 void System::setUpdaterPeriod(const std::string
& name
, unsigned int period
)
284 vector
<System::updater_item
>::iterator i
= findUpdaterItem(name
);
285 i
->setPeriod(period
, m_cur_tstep
);
288 /*! \param name Name of the Updater to modify
289 \param update_func A python callable function taking one argument that returns an integer value of the next time step to update at
291 void System::setUpdaterPeriodVariable(const std::string
& name
, boost::python::object update_func
)
293 vector
<System::updater_item
>::iterator i
= findUpdaterItem(name
);
294 i
->setVariablePeriod(update_func
, m_cur_tstep
);
297 /*! \param name Name of the Updater to get the period of
298 \returns Period of the Updater
300 unsigned int System::getUpdaterPeriod(const std::string
& name
)
302 vector
<System::updater_item
>::iterator i
= findUpdaterItem(name
);
307 // -------------- Compute get/set methods
309 /*! \param compute Shared pointer to the Compute to add
310 \param name Unique name to assign to this Compute
312 Computes are added to the System only as a convenience for naming,
313 saving to restart files, and to activate profiling. They are never
314 directly called by the system.
316 void System::addCompute(boost::shared_ptr
<Compute
> compute
, const std::string
& name
)
321 // check if the name is unique
322 map
< string
, boost::shared_ptr
<Compute
> >::iterator i
= m_computes
.find(name
);
323 if (i
== m_computes
.end())
324 m_computes
[name
] = compute
;
327 m_exec_conf
->msg
->error() << "Compute " << name
<< " already exists" << endl
;
328 throw runtime_error("System: cannot add compute");
333 /*! \param name Name of the Compute to remove
335 void System::removeCompute(const std::string
& name
)
337 // see if the compute exists to be removed
338 map
< string
, boost::shared_ptr
<Compute
> >::iterator i
= m_computes
.find(name
);
339 if (i
== m_computes
.end())
341 m_exec_conf
->msg
->error() << "Compute " << name
<< " not found" << endl
;
342 throw runtime_error("System: cannot remove compute");
348 /*! \param name Name of the compute to access
349 \returns A shared pointer to the Compute as provided previosly by addCompute()
351 boost::shared_ptr
<Compute
> System::getCompute(const std::string
& name
)
353 // see if the compute even exists first
354 map
< string
, boost::shared_ptr
<Compute
> >::iterator i
= m_computes
.find(name
);
355 if (i
== m_computes
.end())
357 m_exec_conf
->msg
->error() << "Compute " << name
<< " not found" << endl
;
358 throw runtime_error("System: cannot retrieve compute");
359 return boost::shared_ptr
<Compute
>();
362 return m_computes
[name
];
365 // -------------- Integrator methods
367 /*! \param integrator Updater to set as the Integrator for this System
369 void System::setIntegrator(boost::shared_ptr
<Integrator
> integrator
)
371 m_integrator
= integrator
;
374 /*! \returns A shared pointer to the Integrator for this System
376 boost::shared_ptr
<Integrator
> System::getIntegrator()
382 // -------------- Methods for communication
383 void System::setCommunicator(boost::shared_ptr
<Communicator
> comm
)
389 // -------------- Methods for running the simulation
391 /*! \param nsteps Number of simulation steps to run
392 \param limit_hours Number of hours to run for (0.0 => infinity)
393 \param cb_frequency Modulus of timestep number when to call the callback (0 = at end)
394 \param callback Python function to be called periodically during run.
395 \param limit_multiple Only allow \a limit_hours to break the simulation at steps that are a multiple of
398 During each simulation step, all added Analyzers and
399 Updaters are called, then the Integrator to move the system
400 forward one step in time. This is repeated \a nsteps times,
401 or until a \a limit_hours hours have passed.
403 run() can be called as many times as the user wishes:
404 each time, it will continue at the time step where it left off.
407 void System::run(unsigned int nsteps
, unsigned int cb_frequency
,
408 boost::python::object callback
, double limit_hours
,
409 unsigned int limit_multiple
)
412 m_start_tstep
= m_cur_tstep
;
413 m_end_tstep
= m_cur_tstep
+ nsteps
;
415 // initialize the last status time
416 int64_t initial_time
= m_clk
.getTime();
417 m_last_status_time
= initial_time
;
420 // preset the flags before the run loop so that any analyzers/updaters run on step 0 have the info they need
421 // but set the flags before prepRun, as prepRun may remove some flags that it cannot generate on the first step
422 m_sysdef
->getParticleData()->setFlags(determineFlags(m_cur_tstep
));
427 //! Set communicator in all Updaters
428 vector
<updater_item
>::iterator updater
;
429 for (updater
= m_updaters
.begin(); updater
!= m_updaters
.end(); ++updater
)
430 updater
->m_updater
->setCommunicator(m_comm
);
432 // Set communicator in all Computes
433 map
< string
, boost::shared_ptr
<Compute
> >::iterator compute
;
434 for (compute
= m_computes
.begin(); compute
!= m_computes
.end(); ++compute
)
435 compute
->second
->setCommunicator(m_comm
);
437 // Set communicator in all Analyzers
438 vector
<analyzer_item
>::iterator analyzer
;
439 for (analyzer
= m_analyzers
.begin(); analyzer
!= m_analyzers
.end(); ++analyzer
)
440 analyzer
->m_analyzer
->setCommunicator(m_comm
);
442 // Set communicator in Integrator
444 m_integrator
->setCommunicator(m_comm
);
452 m_exec_conf
->msg
->warning() << "You are running without an integrator" << endl
;
454 m_integrator
->prepRun(m_cur_tstep
);
459 // make sure we start off with a migration substep, so that
460 // any old ghost particles are invalidated
461 m_comm
->forceMigrate();
465 // catch exceptions during simulation
469 for ( ; m_cur_tstep
< m_end_tstep
; m_cur_tstep
++)
471 // check the clock and output a status line if needed
472 uint64_t cur_time
= m_clk
.getTime();
474 // check if the time limit has exceeded
475 if (limit_hours
!= 0.0f
)
477 if (m_cur_tstep
% limit_multiple
== 0)
479 unsigned int end_run
= 0;
480 int64_t time_limit
= int64_t(limit_hours
* 3600.0 * 1e9
);
481 if (int64_t(cur_time
) - initial_time
> time_limit
)
485 // if any processor wants to end the run, end it on all processors
487 MPI_Allreduce(MPI_IN_PLACE
, &end_run
, 1, MPI_INT
, MPI_SUM
, m_exec_conf
->getMPICommunicator());
492 m_exec_conf
->msg
->notice(2) << "Ending run at time step " << m_cur_tstep
<< " as " << limit_hours
<< " hours have passed" << endl
;
497 // execute python callback, if present and needed
498 // a negative return value indicates immediate end of run.
499 if (callback
&& (cb_frequency
> 0) && (m_cur_tstep
% cb_frequency
== 0))
501 boost::python::object rv
= callback(m_cur_tstep
);
502 extract
<int> extracted_rv(rv
);
503 if (extracted_rv
.check() && extracted_rv() < 0)
505 m_exec_conf
->msg
->notice(2) << "End of run requested by python callback at step "
506 << m_cur_tstep
<< " / " << m_end_tstep
<< endl
;
511 if (cur_time
- m_last_status_time
>= uint64_t(m_stats_period
)*uint64_t(1000000000))
514 generateStatusLine();
515 m_last_status_time
= cur_time
;
516 m_last_status_tstep
= m_cur_tstep
;
518 // check for any CUDA errors
520 if (m_exec_conf
->isCUDAEnabled())
528 vector
<analyzer_item
>::iterator analyzer
;
529 for (analyzer
= m_analyzers
.begin(); analyzer
!= m_analyzers
.end(); ++analyzer
)
531 if (analyzer
->shouldExecute(m_cur_tstep
))
532 analyzer
->m_analyzer
->analyze(m_cur_tstep
);
536 vector
<updater_item
>::iterator updater
;
537 for (updater
= m_updaters
.begin(); updater
!= m_updaters
.end(); ++updater
)
539 if (updater
->shouldExecute(m_cur_tstep
))
540 updater
->m_updater
->update(m_cur_tstep
);
543 // look ahead to the next time step and see which analyzers and updaters will be executed
544 // or together all of their requested PDataFlags to determine the flags to set for this time step
545 m_sysdef
->getParticleData()->setFlags(determineFlags(m_cur_tstep
+1));
547 // execute the integrator
549 m_integrator
->update(m_cur_tstep
);
551 // quit if cntrl-C was pressed
559 catch (std::exception
const & ex
)
562 if (m_sysdef
->getParticleData()->getDomainDecomposition() && m_exec_conf
->msg
->isLocked())
564 // tear down other ranks in a controlled way, but only if we are the rank that displayed an error
565 // so that eventual error messages are flushed correctly
566 if (m_exec_conf
->msg
->hasLock())
567 MPI_Abort(m_exec_conf
->getMPICommunicator(), MPI_ERR_OTHER
);
569 // otherwise just wait
570 MPI_Barrier(m_exec_conf
->getMPICommunicator());
575 // re-throw original exception
583 // migrate particles back into domains and remove all ghost atoms
584 m_comm
->migrateParticles();
588 // generate a final status line
590 generateStatusLine();
591 m_last_status_tstep
= m_cur_tstep
;
593 // execute python callback, if present and needed
594 if (callback
&& (cb_frequency
== 0))
596 callback(m_cur_tstep
);
599 // calculate averate TPS
600 Scalar TPS
= Scalar(m_cur_tstep
- m_start_tstep
) / Scalar(m_clk
.getTime() - initial_time
) * Scalar(1e9
);
605 // make sure all ranks return the same TPS
607 bcast(m_last_TPS
, 0, m_exec_conf
->getMPICommunicator());
611 m_exec_conf
->msg
->notice(1) << "Average TPS: " << m_last_TPS
<< endl
;
613 // write out the profile data
615 m_exec_conf
->msg
->notice(1) << *m_profiler
;
622 /*! \param enable Set to true to enable profiling during calls to run()
624 void System::enableProfiler(bool enable
)
629 /*! \param logger Logger to register computes and updaters with
630 All computes and updaters registered with the system are also registerd with the logger.
632 void System::registerLogger(boost::shared_ptr
<Logger
> logger
)
634 // set the profiler on everything
636 logger
->registerUpdater(m_integrator
);
639 vector
<updater_item
>::iterator updater
;
640 for (updater
= m_updaters
.begin(); updater
!= m_updaters
.end(); ++updater
)
641 logger
->registerUpdater(updater
->m_updater
);
644 map
< string
, boost::shared_ptr
<Compute
> >::iterator compute
;
645 for (compute
= m_computes
.begin(); compute
!= m_computes
.end(); ++compute
)
646 logger
->registerCompute(compute
->second
);
649 /*! \param seconds Period between statistics ouptut in seconds
651 void System::setStatsPeriod(unsigned int seconds
)
653 m_stats_period
= seconds
;
656 /*! \param enable Enable/disable autotuning
657 \param period period (approximate) in time steps when returning occurs
659 void System::setAutotunerParams(bool enabled
, unsigned int period
)
661 // set the autotuner parameters on everything
663 m_integrator
->setAutotunerParams(enabled
, period
);
666 vector
<analyzer_item
>::iterator analyzer
;
667 for (analyzer
= m_analyzers
.begin(); analyzer
!= m_analyzers
.end(); ++analyzer
)
668 analyzer
->m_analyzer
->setAutotunerParams(enabled
, period
);
671 vector
<updater_item
>::iterator updater
;
672 for (updater
= m_updaters
.begin(); updater
!= m_updaters
.end(); ++updater
)
673 updater
->m_updater
->setAutotunerParams(enabled
, period
);
676 map
< string
, boost::shared_ptr
<Compute
> >::iterator compute
;
677 for (compute
= m_computes
.begin(); compute
!= m_computes
.end(); ++compute
)
678 compute
->second
->setAutotunerParams(enabled
, period
);
682 m_comm
->setAutotunerParams(enabled
, period
);
686 // --------- Steps in the simulation run implemented in helper functions
688 void System::setupProfiling()
691 m_profiler
= boost::shared_ptr
<Profiler
>(new Profiler("Simulation"));
693 m_profiler
= boost::shared_ptr
<Profiler
>();
695 // set the profiler on everything
697 m_integrator
->setProfiler(m_profiler
);
698 m_sysdef
->getParticleData()->setProfiler(m_profiler
);
699 m_sysdef
->getBondData()->setProfiler(m_profiler
);
702 vector
<analyzer_item
>::iterator analyzer
;
703 for (analyzer
= m_analyzers
.begin(); analyzer
!= m_analyzers
.end(); ++analyzer
)
704 analyzer
->m_analyzer
->setProfiler(m_profiler
);
707 vector
<updater_item
>::iterator updater
;
708 for (updater
= m_updaters
.begin(); updater
!= m_updaters
.end(); ++updater
)
709 updater
->m_updater
->setProfiler(m_profiler
);
712 map
< string
, boost::shared_ptr
<Compute
> >::iterator compute
;
713 for (compute
= m_computes
.begin(); compute
!= m_computes
.end(); ++compute
)
714 compute
->second
->setProfiler(m_profiler
);
719 m_comm
->setProfiler(m_profiler
);
723 void System::printStats()
725 m_exec_conf
->msg
->notice(1) << "---------" << endl
;
726 // print the stats for everything
728 m_integrator
->printStats();
731 vector
<analyzer_item
>::iterator analyzer
;
732 for (analyzer
= m_analyzers
.begin(); analyzer
!= m_analyzers
.end(); ++analyzer
)
733 analyzer
->m_analyzer
->printStats();
736 vector
<updater_item
>::iterator updater
;
737 for (updater
= m_updaters
.begin(); updater
!= m_updaters
.end(); ++updater
)
738 updater
->m_updater
->printStats();
741 map
< string
, boost::shared_ptr
<Compute
> >::iterator compute
;
742 for (compute
= m_computes
.begin(); compute
!= m_computes
.end(); ++compute
)
743 compute
->second
->printStats();
746 void System::resetStats()
749 m_integrator
->resetStats();
752 vector
<analyzer_item
>::iterator analyzer
;
753 for (analyzer
= m_analyzers
.begin(); analyzer
!= m_analyzers
.end(); ++analyzer
)
754 analyzer
->m_analyzer
->resetStats();
757 vector
<updater_item
>::iterator updater
;
758 for (updater
= m_updaters
.begin(); updater
!= m_updaters
.end(); ++updater
)
759 updater
->m_updater
->resetStats();
762 map
< string
, boost::shared_ptr
<Compute
> >::iterator compute
;
763 for (compute
= m_computes
.begin(); compute
!= m_computes
.end(); ++compute
)
764 compute
->second
->resetStats();
767 void System::generateStatusLine()
769 // a status line consists of
771 // current timestep / end time step
772 // time steps per second
776 int64_t cur_time
= m_clk
.getTime();
777 string t_elap
= ClockSource::formatHMS(cur_time
);
779 // time steps per second
780 Scalar TPS
= Scalar(m_cur_tstep
- m_last_status_tstep
) / Scalar(cur_time
- m_last_status_time
) * Scalar(1e9
);
782 // estimated time to go (base on current TPS)
783 string ETA
= ClockSource::formatHMS(int64_t((m_end_tstep
- m_cur_tstep
) / TPS
* Scalar(1e9
)));
786 m_exec_conf
->msg
->notice(1) << "Time " << t_elap
<< " | Step " << m_cur_tstep
<< " / " << m_end_tstep
<< " | TPS " << TPS
<< " | ETA " << ETA
<< endl
;
789 /*! \param tstep Time step for which to determine the flags
791 The flags needed are determiend by peeking to \a tstep and then using bitwise or to combine all of the flags from the
792 analyzers and updaters that are to be executed on that step.
794 PDataFlags
System::determineFlags(unsigned int tstep
)
798 flags
= m_integrator
->getRequestedPDataFlags();
800 vector
<analyzer_item
>::iterator analyzer
;
801 for (analyzer
= m_analyzers
.begin(); analyzer
!= m_analyzers
.end(); ++analyzer
)
803 if (analyzer
->peekExecute(tstep
))
804 flags
|= analyzer
->m_analyzer
->getRequestedPDataFlags();
807 vector
<updater_item
>::iterator updater
;
808 for (updater
= m_updaters
.begin(); updater
!= m_updaters
.end(); ++updater
)
810 if (updater
->peekExecute(tstep
))
811 flags
|= updater
->m_updater
->getRequestedPDataFlags();
819 class_
< System
, boost::shared_ptr
<System
>, boost::noncopyable
> ("System", init
< boost::shared_ptr
<SystemDefinition
>, unsigned int >())
820 .def("addAnalyzer", &System::addAnalyzer
)
821 .def("removeAnalyzer", &System::removeAnalyzer
)
822 .def("getAnalyzer", &System::getAnalyzer
)
823 .def("setAnalyzerPeriod", &System::setAnalyzerPeriod
)
824 .def("setAnalyzerPeriodVariable", &System::setAnalyzerPeriodVariable
)
825 .def("getAnalyzerPeriod", &System::getAnalyzerPeriod
)
827 .def("addUpdater", &System::addUpdater
)
828 .def("removeUpdater", &System::removeUpdater
)
829 .def("getUpdater", &System::getUpdater
)
830 .def("setUpdaterPeriod", &System::setUpdaterPeriod
)
831 .def("setUpdaterPeriodVariable", &System::setUpdaterPeriodVariable
)
832 .def("getUpdaterPeriod", &System::getUpdaterPeriod
)
834 .def("addCompute", &System::addCompute
)
835 .def("removeCompute", &System::removeCompute
)
836 .def("getCompute", &System::getCompute
)
838 .def("setIntegrator", &System::setIntegrator
)
839 .def("getIntegrator", &System::getIntegrator
)
841 .def("registerLogger", &System::registerLogger
)
842 .def("setStatsPeriod", &System::setStatsPeriod
)
843 .def("setAutotunerParams", &System::setAutotunerParams
)
844 .def("enableProfiler", &System::enableProfiler
)
845 .def("enableQuietRun", &System::enableQuietRun
)
846 .def("run", &System::run
)
848 .def("getLastTPS", &System::getLastTPS
)
849 .def("getCurrentTimeStep", &System::getCurrentTimeStep
)
851 .def("setCommunicator", &System::setCommunicator
)
852 .def("getCommunicator", &System::getCommunicator
)
858 #pragma warning( pop )