8 template<
typename time>
11 auto sweeper = this->get_level(level);
12 for (
size_t s = 0; s < this->nsweeps[level]; s++) {
14 sweeper->predict(predict);
15 sweeper->post_predict();
19 sweeper->post_sweep();
29 template<
typename time>
39 template<
typename time>
42 if (this->comm->size() == 1) {
47 int nblocks = int(this->get_end_time() / this->get_step_size()) / comm->size();
50 ML_CLOG(INFO,
"Controller",
"invalid duration: there are more time processors than time steps");
51 throw ValueError(
"invalid duration: there are more time processors than time steps");
54 if (nblocks * comm->size() * this->get_step_size() < this->get_end_time()) {
55 ML_CLOG(INFO,
"Controller",
"invalid duration: mismatch between number of time processors and time steps");
56 throw ValueError(
"invalid duration: mismatch between number of time processors and time steps");
59 for (
int nblock = 0; nblock < nblocks; nblock++) {
60 this->set_step(nblock * comm->size() + comm->rank());
64 ML_CLOG(DEBUG,
"Controller",
"iterating on step " << this->get_step()
65 <<
" (0/" << this->get_max_iterations() <<
")");
66 for (this->set_iteration(0);
67 this->get_iteration() < this->get_max_iterations() && this->comm->status->keep_iterating();
68 this->advance_iteration()) {
70 if (this->comm->status->previous_is_iterating()) {
73 cycle_v(this->finest());
75 ML_CLOG(DEBUG,
"Controller",
"done iterating on step " << this->get_step()
76 <<
" (" << this->get_iteration() <<
"/"
77 << this->get_max_iterations() <<
")");
79 for (
auto l = this->finest(); l >= this->coarsest(); --l) {
80 l.current()->post_step();
83 if (nblock < nblocks - 1) {
87 this->comm->status->clear();
91 template<
typename time>
98 perform_sweeps(l.
level);
100 if (l == this->finest() && fine->converged()) {
101 this->comm->status->set_converged(
true);
104 fine->send(comm, tag(l),
false);
105 trns->restrict(crse, fine,
true);
106 trns->fas(this->get_step_size(), crse, fine);
112 template<
typename time>
115 auto fine = level_iter.
current();
116 auto crse = level_iter.
coarse();
119 trns->interpolate(fine, crse,
true);
120 fine->recv(comm, tag(level_iter),
false);
121 trns->interpolate_initial(fine, crse);
123 if (level_iter < this->finest()) {
124 perform_sweeps(level_iter.
level);
127 return level_iter + 1;
130 template<
typename time>
133 auto crse = level_iter.
current();
135 if (this->comm->status->previous_is_iterating()) {
136 crse->recv(comm, tag(level_iter),
true);
138 this->comm->status->recv(stag(level_iter));
139 this->perform_sweeps(level_iter.
level);
140 crse->send(comm, tag(level_iter),
true);
141 this->comm->status->set_converged(!this->comm->status->keep_iterating());
142 this->comm->status->send(stag(level_iter));
143 return level_iter + 1;
146 template<
typename time>
149 if (level_iter.
level == 0) {
150 level_iter = cycle_bottom(level_iter);
152 level_iter = cycle_down(level_iter);
153 level_iter = cycle_v(level_iter);
154 level_iter = cycle_up(level_iter);
159 template<
typename time>
162 this->get_finest()->spread();
165 for (
auto l = this->finest() - 1; l >= this->coarsest(); --l) {
166 auto crse = l.current();
167 auto fine = l.fine();
168 auto trns = l.transfer();
169 trns->restrict_initial(crse, fine);
176 auto crse = this->coarsest().current();
177 for (
int nstep = 0; nstep < comm->rank() + 1; nstep++) {
180 if (nstep < comm->rank()) {
186 for (
auto l = this->coarsest() + 1; l <= this->finest(); ++l) {
187 auto crse = l.coarse();
188 auto fine = l.current();
189 auto trns = l.transfer();
191 trns->interpolate(fine, crse,
true);
192 if (l < this->finest()) {
193 perform_sweeps(l.level);
198 template<
typename time>
201 this->get_finest()->broadcast(this->comm);
211 template<
typename time>
214 return (level_iter.
level+1) * 10000 + this->get_iteration();
217 template<
typename time>
220 return level_iter.
level * 1000 + this->get_iteration();
227 template<
typename time>
230 if (this->comm->status->previous_is_iterating()) {
231 this->comm->status->post(0);
232 for (
auto l = this->coarsest() + 1; l <= this->finest(); ++l) {
233 l.current()->post(comm, tag(l));
virtual void run()
Solve ODE using MLSDC.
virtual void broadcast()
Broadcast finest level to all processes of PFASST::comm.
LevelIter cycle_v(LevelIter level_iter)
Perform an MLSDC V-cycle.
shared_ptr< R > coarse()
Get the next coarser level based on LevelIter::current()
void perform_sweeps(size_t level)
Level (MLSDC/PFASST) iterator.
#define ML_CLOG(level, logger_id, x)
same as CLOG(level, logger, x) from easylogging++
LevelIter cycle_up(LevelIter level_iter)
Interpolate coarse correction to fine, sweep on current (fine).
virtual void predictor()
Predictor: restrict initial down, preform coarse sweeps, return to finest.
virtual void post()
Post current status and values to next processor.
shared_ptr< R > transfer()
Get transfer operator for current level.
LevelIter cycle_down(LevelIter level_iter)
Sweep on current (fine), restrict to coarse.
virtual int stag(LevelIter level_iter)
virtual void set_comm(ICommunicator *comm)
Set communicator.
virtual int tag(LevelIter level_iter)
Generate a unique tag for level iterator.
shared_ptr< R > current()
Get level this iterator is currently pointing at.
Abstract interface for communicators.
LevelIter cycle_bottom(LevelIter level_iter)
Sweep on the current (coarsest) level.
virtual void run() override
Solve ODE using PFASST.