Plugins
Loading...
Searching...
No Matches
limex_integrator.hpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014 - 2020: G-CSC, Goethe University Frankfurt
3 * Author: Arne Naegel
4 *
5 * This file is part of UG4.
6 *
7 * UG4 is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License version 3 (as published by the
9 * Free Software Foundation) with the following additional attribution
10 * requirements (according to LGPL/GPL v3 §7):
11 *
12 * (1) The following notice must be displayed in the Appropriate Legal Notices
13 * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 *
15 * (2) The following notice must be displayed at a prominent place in the
16 * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 *
18 * (3) The following bibliography is recommended for citation and must be
19 * preserved in all covered files:
20 * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 * parallel geometric multigrid solver on hierarchically distributed grids.
22 * Computing and visualization in science 16, 4 (2013), 151-164"
23 * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 * flexible software system for simulating pde based models on high performance
25 * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 *
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU Lesser General Public License for more details.
31 */
32
33#ifndef LIMEX_INTEGRATOR_HPP_
34#define LIMEX_INTEGRATOR_HPP_
35/*
36#define XMTHREAD_BOOST
37#ifdef XMTHREAD_BOOST
38#include <boost/thread/thread.hpp>
39#endif
40*/
41#include <string>
42
43#include "common/stopwatch.h"
44
49
51#include "lib_disc/assemble_interface.h" // TODO: missing IAssemble in following file:
58#include "lib_disc/function_spaces/grid_function_util.h" // SaveVectorForConnectionViewer
61
63
64
65// own headers
66#include "time_extrapolation.h"
67#include "time_integrator.hpp"
68#include "../limex_tools.h"
69//#include "../multi_thread_tools.h"
70
71
72#ifdef UG_JSON
73#include <nlohmann/json.hpp>
74#endif
75
76#undef LIMEX_MULTI_THREAD
77
78namespace ug {
79
80
81/*
82template<class TI>
83class TimeIntegratorThread : public TI
84{
85 TimeIntegratorThread(SmartPtr<grid_function_type> u1, number t1, ConstSmartPtr<grid_function_type> u0, number t0)
86 {
87
88 }
89
90 // thre
91 void apply()
92 {
93 TI::apply(u1, t1, u0, t0);
94 }
95
96
97};*/
98
99static void MyPrintError(UGError &err)
100{
101 for(size_t i=0;i<err.num_msg();++i)
102 {
103 UG_LOG("MYERROR "<<i<<":"<<err.get_msg(i)<<std::endl);
104 UG_LOG(" [at "<<err.get_file(i)<<
105 ", line "<<err.get_line(i)<<"]\n");
106 }
107}
108
110{
111 virtual ~ILimexRefiner(){};
112
113protected:
115};
116
118
120{
121public:
124
126 virtual void update_cost(std::vector<number> &costA, const std::vector<size_t> &vSteps, const size_t nstages) = 0;
127};
128
129
132{
133public:
135 void update_cost(std::vector<number> &m_costA, const std::vector<size_t> &m_vSteps, const size_t nstages)
136 {
137 UG_ASSERT(m_costA.size() >= nstages, "Huhh: Vectors match in size:" << m_costA.size() << "vs." << nstages);
138
139 UG_LOG("A_0="<< m_vSteps[0] << std::endl);
140 m_costA[0] = (1.0)*m_vSteps[0];
141 for (size_t i=1; i<nstages; ++i)
142 {
143 m_costA[i] = m_costA[i-1] + (1.0)*m_vSteps[i];
144 UG_LOG("A_i="<< m_vSteps[i] << std::endl);
145 }
146 }
147};
148
151{
152public:
154 m_cAssemble (1.0), m_cMatAdd(0.0), m_cSolution(1.0), m_useGamma(1)
155 {}
156
157 void update_cost(std::vector<number> &m_costA, const std::vector<size_t> &nSteps, const size_t nstages)
158 {
159 UG_ASSERT(m_costA.size() >= nstages, "Huhh: Vectors match in size:" << m_costA.size() << "vs." << nstages);
160
161 // 3 assemblies (M0, J0, Gamma0)
162 m_costA[0] = (2.0+m_useGamma)*m_cAssemble + nSteps[0]*((1.0+m_useGamma)*m_cMatAdd + m_cSolution);
163 for (size_t i=1; i<=nstages; ++i)
164 {
165 // n-1 assemblies for Mk, 2n MatAdds, n solutions
166 m_costA[i] = m_costA[i-1] + (nSteps[i]-1) * m_cAssemble + nSteps[i]*((1.0+m_useGamma)*m_cMatAdd + m_cSolution);
167 }
168 }
169
170protected:
171 double m_cAssemble;
172 double m_cMatAdd;
173 double m_cSolution;
174
176
177};
178
179
181
182{
183public:
185 : m_nstages(2),
186 m_tol(0.01),
187 m_rhoSafety(0.8),
188 m_sigmaReduction(0.5),
191 m_asymptotic_order(1000),
192 m_useCachedMatrices(false),
194 {}
195
196 LimexTimeIntegratorConfig(unsigned int nstages)
197 : m_nstages(nstages),
198 m_tol(0.01),
199 m_rhoSafety(0.8),
200 m_sigmaReduction(0.5),
203 m_asymptotic_order(1000),
204 m_useCachedMatrices(false),
206 {}
207
208
209protected:
210 unsigned int m_nstages;
211 double m_tol;
214
216
219
221 unsigned int m_conservative; // stepping back?
222
223#ifdef UG_JSON
224 NLOHMANN_DEFINE_TYPE_INTRUSIVE(LimexTimeIntegratorConfig,
228#endif
229public:
230 std::string config_string() const {
231 #ifdef UG_JSON
232 try{
233 nlohmann::json j(*this);
234 // to_json(j, *this);
235 return j.dump();
236 } catch (...) {
237 return std::string("EXCEPTION!!!");
238 }
239 #else
240 return std::string("LimexTimeIntegratorConfig::config_string()");
241 #endif
242 }
243
244};
245
247template<class TDomain, class TAlgebra>
249: public INonlinearTimeIntegrator<TDomain, TAlgebra>,
250 public VectorDebugWritingObject<typename TAlgebra::vector_type>,
251 public LimexTimeIntegratorConfig // TODO: should become a 'has a'.
252{
253
254
255public:
256 typedef TAlgebra algebra_type;
257 typedef typename algebra_type::matrix_type matrix_type;
258 typedef typename algebra_type::vector_type vector_type;
262
269
272 {
273 //typedef boost::thread thread_type;
274 public:
275
277 : m_stepper(spTimeStep)
278 {}
279
283
284
286 { m_solver = solver;}
287
290
291 void set_error(int e)
292 { m_error=e; }
293
294
296 { /*return m_error;*/ }
297
298
301
304
307
310
311 protected:
312 // includes time step series
315
319 };
320
321 typedef std::vector<SmartPtr<ThreadData> > thread_vector_type;
322
323public:
324
327 {
328 for(size_t i=0; i<m_vThreadData.size(); ++i)
329 {
330 m_vThreadData[i].get_time_stepper()->set_debug(spDebugWriter);
331 }
332 UG_LOG("set_debug:" << m_vThreadData.size());
333 }
334
336protected:
338
339
340
341public:
346 m_monitor(((m_nstages)*(m_nstages))), // TODO: wasting memory here!
352 m_spBanachSpace(new AlgebraicSpace<grid_function_type>()), // default algebraic space
353 m_bInterrupt(false),
354 m_limex_step(1)
355 {
356 m_vThreadData.reserve(m_nstages);
357 m_vSteps.reserve(m_nstages);
358 init_gamma(); // init exponents (i.e. k+1, k, 2k+1, ...)
359 }
360
361
362
364 void set_tolerance(double tol) { m_tol = tol;}
365 void set_stepsize_safety_factor(double rho) { m_rhoSafety = rho;}
366 void set_stepsize_reduction_factor(double sigma) { m_sigmaReduction = sigma;}
368
369 void set_max_reductions(size_t nred) { m_max_reductions = nred;}
371
374 { m_spErrorEstimator = spErrorEstim; }
375
378 {
379 UG_ASSERT(m_vThreadData.size() == m_vSteps.size(), "ERROR: m_vThreadData and m_vSteps differ in size!");
380
381 UG_ASSERT(m_vThreadData.empty() || m_vSteps.back()<nsteps, "ERROR: Sequence of steps must be increasing." );
382
383 // all entries have been set
384 if (m_vThreadData.size() == m_nstages)
385 { return; }
386
387
388 // a) set number of steps
389 m_vSteps.push_back(nsteps);
390
391 // b) set time-stepper
392 SmartPtr<timestep_type> limexStepSingleton;
393#ifndef LIMEX_MULTI_THREAD
394
395 if(m_vThreadData.size()>0) {
396 // re-use time-stepper (if applicable)
397 limexStepSingleton = m_vThreadData.back().get_time_stepper();
398 }
399 else
400 {
401 // create time-stepper
402#endif
403 // for mult-threading, each info object has own time-stepper
404 if (spGamma.invalid()) {
405 limexStepSingleton = make_sp(new timestep_type(spDD));
406 } else {
407 limexStepSingleton = make_sp(new timestep_type(spDD, spDD, spGamma));
408 }
409 UG_ASSERT(limexStepSingleton.valid(), "Huhh: Invalid pointer")
410#ifndef LIMEX_MULTI_THREAD
411 }
412#endif
413 // propagate debug info
414 limexStepSingleton->set_debug(VectorDebugWritingObject<vector_type>::vector_debug_writer());
415 m_vThreadData.push_back(ThreadData(limexStepSingleton));
416
417 // c) set solver
418 UG_ASSERT(solver.valid(), "Huhh: Need to supply solver!");
419 m_vThreadData.back().set_solver(solver);
420 UG_ASSERT(m_vThreadData.back().get_solver().valid(), "Huhh: Need to supply solver!");
421 }
422
424 { add_stage_base(nsteps, solver, spDD); }
425
427 { add_stage_base(nsteps, solver, spDD, spGamma); }
428
430 void add_stage(size_t i, size_t nsteps, SmartPtr<domain_discretization_type> spDD, SmartPtr<solver_type> solver)
431 {
432 UG_LOG("WARNING: add_stage(i, nsteps ,...) is deprecated. Please use 'add_stage(nsteps ,...) instead!'");
433 add_stage(nsteps, solver, spDD);
434 }
435
438 {
439 UG_ASSERT(i<m_vThreadData.size(), "Huhh: Invalid entry");
440 return m_vThreadData[i].get_time_stepper();
441 }
442
443
444
445
446protected:
449
452
455
458
461
462public:
465
466 number get_cost(size_t i) { return m_costA[i]; }
467 number get_gamma(size_t i) { return m_gamma[i]; }
468 number get_workload(size_t i) { return m_workload[i]; }
469
470
471protected:
472 number& monitor(size_t k, size_t q) {
473 UG_ASSERT(k<m_nstages, "Huhh: k mismatch");
474 UG_ASSERT(q<m_nstages, "Huhh: q mismatch");
475 return m_monitor[k+(m_nstages)*q];
476 }
477
480 {
481 for (size_t k=0; k<=m_nstages; ++k)
482 {
483 m_gamma[k] = 2.0+k;
484 }
485 }
486
488 // (depends on m_vSteps, which must have been initialized!)
490 {
492 }
493
495 // (depends on cost, which must have been initialized!)
497 {
498 UG_ASSERT(m_costA.size()>= m_nstages, "Cost vector too small!")
499 for (size_t k=0; k<m_nstages-1; ++k)
500 {
501 UG_LOG("k= "<< k<< ", A[k]=" << m_costA[k] << ", gamma[k]=" << m_gamma[k] << "\t");
502 for (size_t q=0; q<m_nstages-1; ++q)
503 {
504 // Deuflhard: Order and stepsize, ... eq. (3.7)
505 double gamma = (m_costA[k+1] - m_costA[0] + 1.0)/(m_costA[q+1] - m_costA[0] + 1.0);
506 double alpha = pow(m_tol, gamma);
507
508 // for fixed order q, the monitor indicates the performance penalty compared to a strategy using k stages only
509 // cf. eq. (4.6)
510 monitor(k,q) = pow(alpha/(m_tol * m_rhoSafety), 1.0/m_gamma[k]);
511 UG_LOG(monitor(k,q) << "[" << pow(alpha/(m_tol), 1.0/m_gamma[k]) <<"," << gamma<< ","<< m_costA[k+1] << "," << m_costA[q+1]<< ","<< alpha << "]" << "\t");
512 // UG_LOG( << "\t");
513
514 }
515 UG_LOG(std::endl);
516 }
517
518 }
519
520 // Find row k=1, ..., ntest-1 minimizing (estimated) error eps[kmin]
521 // Also: predict column q with minimal workload W_{k+1,k} = A_{k+1} * lambda_{k+1}
522 size_t find_optimal_solution(const std::vector<number>& eps, size_t ntest, /*size_t &kf,*/ size_t &qpred);
523
524public:
527
530
533
534
537
540
541
544 {
545 m_spBanachSpace = spSpace;
546 UG_LOG("set_space:" << m_spBanachSpace->config_string());
547 }
548
550 void interrupt() {m_bInterrupt = true;}
551
552 void set_conservative(bool c)
553 { m_conservative = (c) ? 1 : 0; }
554
555 std::string config_string() const
557
558protected:
559
560 SmartPtr<error_estim_type> m_spErrorEstimator; // (smart ptr for) error estimator
561
562 std::vector<size_t> m_vSteps;
563 std::vector<ThreadData> m_vThreadData;
564
565 std::vector<number> m_gamma;
566
567 std::vector<number> m_costA;
568 std::vector<number> m_monitor;
569
570 std::vector<number> m_workload;
571 std::vector<number> m_lambda;
572
573 std::vector<size_t> m_num_reductions;
574
575 std::vector<number> m_consistency_error;
576
578
580
583
586
587
588};
589
590
592template<class TDomain, class TAlgebra>
594{
595 PROFILE_FUNC_GROUP("limex");
596 const int nstages = m_vThreadData.size()-1;
597 for (int i=nstages; i>=0; --i)
598 {
599 m_vThreadData[i].set_solution(u->clone());
600 m_vThreadData[i].set_derivative(u->clone());
601 m_vThreadData[i].get_time_stepper()->set_matrix_cache(m_useCachedMatrices);
602 }
603}
604
606template<class TDomain, class TAlgebra>
608{
609 PROFILE_FUNC_GROUP("limex");
610 const int nstages = m_vThreadData.size()-1;
611 for (int i=nstages; i>=0; --i)
612 {
613 m_vThreadData[i].set_solution(SPNULL);
614 m_vThreadData[i].set_derivative(SPNULL);
615 // m_vThreadData[i].get_time_stepper()->set_matrix_cache(m_useCachedMatrices);
616 }
617}
618
619
620// create (& execute) threads
621/*boost::thread_group g;
622 typename thread_vector_type::reverse_iterator rit=m_vThreadData.rbegin();
623 for (rit++; rit!= m_vThreadData.rend(); ++rit)
624 {
625
626 boost::thread *t =new boost::thread(boost::bind(&ThreadSafeTimeIntegrator::apply, *rit));
627 //g.add_thread(t);
628
629 g.create_thread(boost::bind(&ThreadSafeTimeIntegrator::apply, *rit));
630
631 }*/
632
633
634/* TODO: PARALLEL execution?*/
635template<class TDomain, class TAlgebra>
637{
638 PROFILE_FUNC_GROUP("limex");
639 update_cost(); // compute cost A_i (alternative: measure times?)
640 update_monitor(); // convergence monitor
641
642 /*
643 int tn = omp_get_thread_num();
644 int nt = omp_get_num_threads();
645 omp_set_num_threads(nstages);
646 */
647 int error = 0;
648 //const int nstages = m_vThreadData.size()-1;
649 // #pragma omp for private(i) // shared (nstages, u1) schedule(static)
650 for (int i=0; i<=(int)nstages; ++i)
651 {
652 /*
653 std::cerr << "I am " << tn << " of " << nt << " ("<< i<< "/" << nstages<<")!" << std::endl;
654 UGMultiThreadEnvironment mt_env;
655 */
656
657 // copy data to private structure (one-to-many)
658 //m_vThreadData[i].set_solution(u1->clone());
659
660 // switch to "child" comm
661 // mt_env.begin();
662
663 // integrate (t0, t0+dtcurr)
664 time_integrator_type integrator(m_vThreadData[i].get_time_stepper());
665 integrator.set_time_step(dtcurr/m_vSteps[i]);
666 integrator.set_dt_min(dtcurr/m_vSteps[i]);
667 integrator.set_dt_max(dtcurr/m_vSteps[i]);
668 integrator.set_reduction_factor(0.0); // quit immediately, if step fails
669 integrator.set_solver(m_vThreadData[i].get_solver());
670 integrator.set_derivative(m_vThreadData[i].get_derivative());
671
672 UG_ASSERT(m_spBanachSpace.valid(), "Huhh: Need valid (default) banach space");
673 integrator.set_banach_space(m_spBanachSpace);
674 UG_LOG("Set space:" << m_spBanachSpace->config_string());
675
676 bool exec = true;
677 try
678 {
679 exec = integrator.apply(m_vThreadData[i].get_solution(), t0+dtcurr, u0, t0);
680 m_consistency_error[i] = integrator.get_consistency_error();
681 }
682 catch(ug::UGError& err)
683 {
684
685 exec = false;
686 error += (1 << i);
687 UG_LOGN("Step "<< i<< " failed on stage " << i << ": " << err.get_msg());
688 MyPrintError(err);
689
690 }
691
692 if (!exec)
693 {
694 // Additional actions at failure
695 }
696
697 // switch to "parent" comm
698 //mt_env.end();
699 } /*for all stages loop*/
700
701
702
703 return error;
704}
705
706
707template<class TDomain, class TAlgebra>
709{
710 // join all threads
711 // g.join_all();
712 const int nstages = m_vThreadData.size()-1;
713 for (int i=nstages; i>=0; --i)
714 {
715 m_vThreadData[i].get_time_stepper()->invalidate();
716 }
717}
718
719
720template<class TDomain, class TAlgebra>
722{
723 const int nstages = m_vThreadData.size()-1;
724 for (int i=nstages; i>=0; --i)
725 {
726 UG_ASSERT(m_vThreadData[i].get_solution()->size()==ucommon->size(), "LIMEX: Vectors must match in size!")
727 *m_vThreadData[i].get_solution() = *ucommon;
728 }
729}
730
731template<class TDomain, class TAlgebra>
733find_optimal_solution(const std::vector<number>& eps, size_t ntest, /*size_t &kf,*/ size_t &qpred)
734{
735
736 const size_t qold=qpred;
737
738 size_t jbest = 1;
739 qpred = 1;
740
741 size_t j=1;
742 size_t k=j-1;
743
744 m_lambda[k] = pow(m_rhoSafety*m_tol/eps[j], 1.0/m_gamma[k]); // 1/epsilon(k)
745 m_workload[k] = m_costA[j]/m_lambda[k];
746 UG_LOG("j=" << j << ": eps=" << eps[j] << ", lambda(j)=" <<m_lambda[k] << ", epsilon(j)=" <<1.0/m_lambda[k] << "<= alpha(k, qcurr)=" << monitor(k,qold-1) << "< alpha(k, qcurr+1)=" << monitor(k,qold) <<", A="<< m_costA[j] << ", W="<< m_workload[k] <<std::endl);
747
748 for (j=2; j<ntest; ++j)
749 {
750 k = j-1;
751 m_lambda[k] = pow(m_rhoSafety*m_tol/eps[j], 1.0/m_gamma[k]);
752 m_workload[k] = m_costA[j]/m_lambda[k];
753 UG_LOG("j=" << j << ": eps=" << eps[j] << ", lambda(j)=" <<m_lambda[k] << ", epsilon(j)=" <<1.0/m_lambda[k] << "<= alpha(k, qcurr)=" << monitor(k,qold-1) << "< alpha(k, qcurr+1)=" << monitor(k,qold) <<", A="<< m_costA[j] << ", W="<< m_workload[k] <<std::endl);
754
755
756 // TODO: Convergence monitor
757
758 qpred = (m_workload[qpred-1] > m_workload[k]) ? j : qpred;
759 jbest = (eps[jbest] > eps [j]) ? j : jbest;
760 }
761
762 return jbest;
763}
764
765template<class TDomain, class TAlgebra>
768{
769 PROFILE_FUNC_GROUP("limex");
770#ifdef UG_OPENMP
771 // create multi-threading environment
772 //int nt = std::min(omp_get_max_threads(), m_nstages);
773
774#endif
775
776 // NOTE: we use u as common storage for future (and intermediate) solution(s)
777 if (u.get() != u0.get()) // only copy if not already identical, otherwise: PST_UNDEFINED!
778 *u = *u0;
779
780 // initialize integrator threads
781 // (w/ solutions)
782 init_integrator_threads(u0);
783
784
785 // write_debug
786 for (unsigned int i=0; i<m_vThreadData.size(); ++i)
787 {
788 std::ostringstream ossName;
789 ossName << std::setfill('0') << std::setw(4);
790 ossName << "Limex_Init_iter" << 0 << "_stage" << i;
791 write_debug(*m_vThreadData[i].get_solution(), ossName.str().c_str());
792 }
793
794 number t = t0;
796
797 size_t kmax = m_vThreadData.size(); // maximum number of stages
798 size_t qpred = kmax-1; // predicted optimal order
799 size_t qcurr = qpred; // current order
800
801 // for Gustafsson/lundh/Soederlind type PID controller
802 /*size_t qlast = 0;
803 double dtlast = 0.0;
804 std::vector<double> epslast(kmax, m_rhoSafety*m_tol);
805*/
806
807 // time integration loop
809 size_t limex_total = 1;
810 size_t limex_success = 0;
811 size_t ntest;
812 size_t jbest;
813
814 m_bInterrupt = false;
815 //bool bProbation = false;
816 bool bAsymptoticReduction = false;
817
818 const size_t nSwitchHistory=16;
819 const size_t nSwitchLookBack=5;
820 int vSwitchHistory[nSwitchHistory] ={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
821
822 timex_type timex(m_vSteps);
823 while ((t < t1) && ((t1-t) > base_type::m_precisionBound))
824 {
825 int err = 0;
826
827 //UG_DLOG(LIB_LIMEX, 5, "+++ LimexTimestep +++" << limex_step << "\n");
828 UG_LOG("+++ LimexTimestep +++" << m_limex_step << "\n");
829
830
831 // save time stamp for limex step start
832 Stopwatch stopwatch;
833 stopwatch.start();
834
835
836 // determine step size
837 number dt = std::min(dtcurr, t1-t);
838 UG_COND_THROW(dt < base_type::get_dt_min(), "Time step size below minimum. ABORTING! dt=" << dt << "; dt_min=" << base_type::get_dt_min() << "\n");
839
840
841 // Notify init observers. (NOTE: u = u(t))¸
842 itime_integrator_type::notify_init_step(u, m_limex_step, t, dt);
843
844
845 // determine number of stages to investigate
846 qcurr = qpred;
847 ntest = std::min(kmax, qcurr+1);
848 UG_LOG("ntest="<< ntest << std::endl);
849
850 // checks
851 UG_ASSERT(m_vSteps.size() >= ntest, "Huhh: sizes do not match: " << m_vSteps.size() << "<"<<ntest);
852 UG_ASSERT(m_vThreadData.size() >= ntest, "Huhh: sizes do not match: " << m_vThreadData.size() << "< "<< ntest);
853
855 // PARALLEL EXECUTION: BEGIN
856
857 // write_debug
858 for (size_t i=0; i<ntest; ++i)
859 {
860 std::ostringstream ossName;
861 ossName << std::setfill('0') << std::setw(4);
862 ossName << "Limex_BeforeSerial_iter" << m_limex_step << "_stage" << i << "_total" << limex_total;
863 write_debug(*m_vThreadData[i].get_solution(), ossName.str().c_str());
864 }
865
866 // integrate: t -> t+dt
867 err = apply_integrator_threads(dt, u, t, ntest-1);
868
869 // write_debug
870 for (size_t i=0; i<ntest; ++i)
871 {
872 std::ostringstream ossName;
873 ossName << std::setfill('0') << std::setw(4);
874 ossName << "Limex_AfterSerial_iter" << m_limex_step << "_stage" << i << "_total" << limex_total;
875 write_debug(*m_vThreadData[i].get_solution(), ossName.str().c_str());
876 }
877
878 join_integrator_threads();
879 // PARALLEL EXECUTION: END
881
882
884 // SERIAL EXECUTION: BEGIN
885
886 // sanity checks
887 UG_ASSERT(m_spErrorEstimator.valid(), "Huhh: Invalid Error estimator?");
888
889 double epsmin = 0.0;
890
891 bool limexConverged = false;
892 if (err==0)
893 { // Compute extrapolation at t+dtcurr (SERIAL)
894 // Consistency check.
895 for (unsigned int i=1; i<ntest; ++i)
896 {
897 UG_LOG("Checking consistency:" <<m_consistency_error[i] <<"/" << m_consistency_error[i-1] << "="<< m_consistency_error[i]/m_consistency_error[i-1] << std::endl);
898 }
899
900 // Extrapolation.
901 timex.set_error_estimate(m_spErrorEstimator);
902 for (unsigned int i=0; i<ntest; ++i)
903 {
904 UG_ASSERT(m_vThreadData[i].get_solution().valid(), "Huhh: no valid solution?");
905 timex.set_solution(m_vThreadData[i].get_solution(), i);
906 }
907 timex.apply(ntest);
908
909 // write_debug
910 for (size_t i=0; i<ntest; ++i)
911 {
912 std::ostringstream ossName;
913 ossName << std::setfill('0') << std::setw(4);
914 ossName << "Limex_Extrapolates_iter" << m_limex_step << "_stage" << i << "_total" << limex_total;
915 write_debug(*m_vThreadData[i].get_solution(), ossName.str().c_str());
916 }
917 limex_total++;
918
919 // Obtain sub-diagonal error estimates.
920 const std::vector<number>& eps = timex.get_error_estimates();
921 UG_ASSERT(ntest<=eps.size(), "Huhh: Not enough solutions?");
922
923 // select optimal solution (w.r.t error) AND
924 // predict optimal order (w.r.t. workload) for next step
925 jbest = find_optimal_solution(eps, ntest, qpred);
926 UG_ASSERT(jbest < ntest, "Huhh: Not enough solutions?");
927
928 // best solution
929 ubest = timex.get_solution(jbest-m_conservative).template cast_dynamic<grid_function_type>();
930 epsmin = eps[jbest];
931
932 // check for convergence
933 limexConverged = (epsmin <= m_tol) ;
934
935
936 if (limex_success>3)
937 {
938
939 vSwitchHistory[m_limex_step%nSwitchHistory] = (qpred - qcurr);
940 UG_DLOG(LIB_LIMEX, 5, "LIMEX-ASYMPTOTIC-ORDER switch: = " << (qpred - qcurr)<< std::endl);
941
942 size_t nSwitches=0;
943 for (int s=nSwitchLookBack-1; s>=0; s--)
944 {
945 nSwitches += std::abs(vSwitchHistory[(m_limex_step-s)%nSwitchHistory]);
946 UG_DLOG(LIB_LIMEX, 6, "LIMEX-ASYMPTOTIC-ORDER: s[" << s<< "] = " << vSwitchHistory[(m_limex_step-s)%nSwitchHistory] << std::endl);
947 }
948 UG_DLOG(LIB_LIMEX, 5,"LIMEX-ASYMPTOTIC-ORDER: nSwitches = " << nSwitches << std::endl);
949
950
951 /*
952 if (bProbation)
953 {
954
955 if ((qpred < qcurr) || (!limexConverged)) // consecutive (follow-up) order decrease
956 {
957 bProbation = true;
958 m_num_reductions[0]++;
959 UG_LOG("LIMEX-ASYMPTOTIC-ORDER: Decrease on parole detected: "<< qcurr << " -> " << qpred << "("<< m_num_reductions[0]<<")"<<std::endl);
960
961 }
962 else
963 {
964 // reset all counters
965 bProbation = false;
966 UG_LOG("LIMEX-ASYMPTOTIC-ORDER: Probation off!"<<std::endl);
967
968 }
969 }
970 else
971 {
972 if ((qpred < qcurr) || (!limexConverged))// 1st order decrease
973 {
974 bProbation = true;
975 m_num_reductions[0]++;
976 UG_LOG("LIMEX-ASYMPTOTIC-ORDER: Decrease detected: "<< qcurr << " -> " << qpred << "("<< m_num_reductions[0]<<")"<<std::endl);
977 }
978 else
979 {
980 m_num_reductions[0] = 0;
981 UG_LOG("LIMEX-ASYMPTOTIC-ORDER: I am totally free!"<<std::endl);
982 }
983
984
985 }
986*/
987
988 // bAsymptoticReduction = (m_num_reductions[0] >= m_max_reductions) || bAsymptoticReduction;
989
990 // bAsymptoticReduction = (nSwitches >= m_max_reductions) || bAsymptoticReduction;
991
992 if (nSwitches >= m_max_reductions) {
993
994
995 m_asymptotic_order = std::min<size_t>(m_asymptotic_order-1, 2);
996 bAsymptoticReduction = true;
997
998 for (int s=nSwitchLookBack-1; s>=0; s--)
999 { vSwitchHistory[(m_limex_step-s)%nSwitchHistory]=0; }
1000
1001
1002 }
1003
1004
1005
1006 // asymptotic order reduction
1007 //if (m_num_reductions[0] >= m_max_reductions)
1008 if (bAsymptoticReduction)
1009 {
1010 kmax = (kmax >= m_asymptotic_order ) ? m_asymptotic_order : kmax;
1011 qpred = kmax - 1;
1012 UG_DLOG(LIB_LIMEX, 5, "LIMEX-ASYMPTOTIC-ORDER: Reduction: "<< qpred );
1013 UG_DLOG(LIB_LIMEX, 5, "(kmax=" << kmax << ", asymptotic"<< m_asymptotic_order <<") after "<<m_max_reductions<< std::endl);
1014 }
1015
1016 } // (limex_success>3)
1017
1018 /*
1019 // adjust for order bound history
1020 if ((m_num_reductions[qpred] > m_max_reductions) && (qpred > 1))
1021 {
1022 UG_LOG("prohibited q:"<< qpred << "(" << m_num_reductions[qpred] << ")"<<std::endl);
1023 //qpred--;
1024 qpred = kmax = 2;
1025 } else
1026 {
1027 UG_LOG("keeping q:"<< qpred << "(" << m_num_reductions[qpred] << ")"<<std::endl);
1028 }
1029 */
1030
1031 //double pid = 1.0;
1032
1033 // constant order?
1034 /*if (qcurr == qlast)
1035 {
1036 double dtRatio =dtcurr/dtlast;
1037 // Dd, Band 3 (DE), p. 360
1038 int k = ntest-1;
1039 while (k--) {
1040 double epsRatio =eps[k+1]/epslast[k+1];
1041
1042 double qopt = log(epsRatio) / log(dtRatio); // take dtcurr here, as dt may be smaller
1043
1044 UG_LOG("effective p["<< k << "]="<< qopt-1.0 <<","<< eps[k+1] <<","<< epslast[k+1] <<"," << epsRatio << "("<< log(epsRatio) << ","<< pow(epsRatio, 1.0/m_gamma[k]) <<")"<< dtcurr <<","<< dtlast << "," << dtRatio << "," <<log(dtRatio) << std::endl);
1045 }
1046
1047
1048 double epsRatio = eps[qcurr]/epslast[qcurr];
1049 pid = dtRatio/pow(epsRatio, 1.0/m_gamma[qcurr-1]);
1050
1051 UG_LOG("pid=" << pid << std::endl);
1052
1053 }*/
1054
1055
1056 // select (predicted) order for next step
1057 double dtpred = dtcurr*std::min(m_lambda[qpred-1], itime_integrator_type::get_increase_factor());
1058 //double dtpred = dtcurr*m_lambda[qpred-1];
1059 UG_LOG("+++++\nget_increase_factor() gives "<<itime_integrator_type::get_increase_factor()<<" \n+++++++")
1060 UG_LOG("koptim=\t" << jbest << ",\t eps(k)=" << epsmin << ",\t q=\t" << qpred<< "("<< ntest << "), lambda(q)=" << m_lambda[qpred-1] << ", alpha(q-1,q)=" << monitor(qpred-1, qpred) << "dt(q)=" << dtpred<< std::endl);
1061
1062 // EXTENSIONS: convergence model
1063 if (limexConverged)
1064 {
1065 limex_success++;
1066
1067 // a) aim for order increase in next step
1068 if ((qpred+1==ntest) /* increase by one possible? */
1069 // && (m_lambda[qpred-1]>1.0)
1070 // && (m_num_reductions[qpred+1] <= m_max_reductions)
1071 && (kmax>ntest)) /* still below max? */
1072 {
1073 const double alpha = monitor(qpred-1, qpred);
1074 UG_LOG("CHECKING for order increase: "<< m_costA[qpred] << "*" << alpha << ">" << m_costA[qpred+1]);
1075 // check, whether further increase could still be efficient
1076 if (m_costA[qpred] * alpha > m_costA[qpred+1])
1077 {
1078 qpred++; // go for higher order
1079 if (m_greedyOrderIncrease >0.0) {
1080 dtpred *= (1.0-m_greedyOrderIncrease) + m_greedyOrderIncrease*alpha; // & adapt time step // TODO: check required!
1081 }
1082 UG_LOG("... yes.\n")
1083
1084 // update history
1085 vSwitchHistory[m_limex_step%nSwitchHistory] = (qpred - qcurr);
1086 UG_LOG("LIMEX-ASYMPTOTIC-ORDER switch update: = " << (qpred - qcurr)<< std::endl);
1087
1088 } else {
1089 UG_LOG("... nope.\n")
1090 }
1091
1092 }
1093
1094
1095 // b) monitor convergence (a-priori check!)
1096
1097 }
1098
1099 // parameters for subsequent step
1100 dtcurr = std::min(dtpred, itime_integrator_type::get_dt_max());
1101
1102
1103 }
1104 else
1105 {
1106 // solver failed -> cut time step
1107 dtcurr *= m_sigmaReduction;
1108 }
1109
1110 // output compute time for Limex step
1111 number watchTime = stopwatch.ms()/1000.0;
1112 UG_LOGN("Time: " << std::setprecision(3) << watchTime << "s");
1113
1114 if ((err==0) && limexConverged)
1115 {
1116 // ACCEPT time step
1117 UG_LOG("+++ LimexTimestep +++" << m_limex_step << " ACCEPTED"<< std::endl);
1118 UG_LOG(" :\t time \t dt (success) \t dt (pred) \tq=\t order (curr)" << qcurr+1 << std::endl);
1119 UG_LOG("LIMEX-ACCEPTING:\t" << t <<"\t"<< dt << "\t" << dtcurr << "\tq=\t" << qcurr+1 << std::endl);
1120
1121
1122 // update PID controller
1123 /*qlast = qcurr;
1124 epslast = timex.get_error_estimates(); // double check ???
1125 dtlast = dt;
1126*/
1127 // Compute time derivatives (by extrapolation)
1128 if (this->has_time_derivative())
1129 {
1130 UG_LOG("Computing derivative" << std::endl);
1131 grid_function_type &udot = *get_time_derivative();
1132
1133 for (size_t i=0; i<=jbest; ++i)
1134 {
1135 timex.set_solution(m_vThreadData[i].get_derivative(), i);
1136 }
1137 timex.apply(jbest+1, false); // do not compute error
1138
1139 udot = *timex.get_solution(jbest).template cast_dynamic<grid_function_type>();
1140
1141 std::ostringstream ossName;
1142 ossName << std::setfill('0');
1143 ossName << "Limex_Derivative_iter" << m_limex_step << "_total" << limex_total;
1144 write_debug(udot, ossName.str().c_str());
1145 }
1146
1147
1148 // Copy best solution.
1149 UG_ASSERT(ubest.valid(), "Huhh: Invalid error estimate?");
1150 *u = *ubest;
1151 t += dt;
1152
1153 // Initiate post process.
1154 itime_integrator_type::notify_finalize_step(u, m_limex_step++, t, dt);
1155
1156 // make sure that all threads continue
1157 // with identical initial value u(t)
1158 // update_integrator_threads(ubest, t);
1159
1160
1161 // working on last row => increase order
1162 //if (ntest == q+1) ntest++;
1163 }
1164 else
1165 {
1166 // DISCARD time step
1167 UG_LOG("+++ LimexTimestep +++" << m_limex_step << " FAILED" << std::endl);
1168 UG_LOG("LIMEX-REJECTING:\t" << t <<"\t"<< dt << "\t" << dtcurr << std::endl);
1169
1170 itime_integrator_type::notify_rewind_step(ubest, m_limex_step, t+dt, dt);
1171
1172 }
1173
1174 // interrupt if interruption flag set
1175 if (m_bInterrupt)
1176 {
1177 UG_LOGN("Limex interrupted by external command.");
1178 break;
1179 }
1180
1181 // SERIAL EXECUTION: END
1183 update_integrator_threads(u, t);
1184
1185
1186 // SOLVE
1187
1188 // ESTIMATE
1189
1190 // MARK
1191
1192 // REFINE
1193
1194
1195 } // time integration loop
1196
1197 dispose_integrator_threads();
1198
1199 return true;
1200} // apply
1201
1202
1203} // namespace ug
1204
1205#endif /* TIME_INTEGRATOR_HPP_ */
parameterString s
Definition Biogas.lua:2
const T * get() const
T * get()
bool valid() const
Definition time_extrapolation.h:984
SmartPtr< vector_type > get_solution(size_t i)
get solution (on stage i)
Definition time_extrapolation.h:1018
void set_error_estimate(SmartPtr< ISubDiagErrorEst< vector_type > > subdiag)
set error estimator
Definition time_extrapolation.h:1022
const std::vector< number > & get_error_estimates() const
Definition time_extrapolation.h:1028
void apply(size_t nstages, bool with_error=true)
best error estimate
Definition time_extrapolation.h:1063
void set_solution(SmartPtr< vector_type > soli, int i)
set solution (for stage i)
Definition time_extrapolation.h:1014
Abstract class for the cost of a limex stage.
Definition limex_integrator.hpp:120
virtual ~ILimexCostStrategy()
destructor
Definition limex_integrator.hpp:123
virtual void update_cost(std::vector< number > &costA, const std::vector< size_t > &vSteps, const size_t nstages)=0
provides the cost for all 0...nstages stages.
Definition limex_integrator.hpp:110
SmartPtr< IRefiner > m_spRefiner
Definition limex_integrator.hpp:114
virtual ~ILimexRefiner()
Definition limex_integrator.hpp:111
integration of non-linear systems (with bounds on dt)
Definition time_integrator.hpp:1097
void set_dt_min(double min)
Definition time_integrator.hpp:1116
void set_solver(SmartPtr< solver_type > solver)
Definition time_integrator.hpp:1107
void set_reduction_factor(double dec)
Definition time_integrator.hpp:1122
void set_dt_max(double max)
Definition time_integrator.hpp:1119
Interface for sub-diagonal error estimator (w.r.t time in Aitken-Neville scheme)
Definition time_extrapolation.h:142
void set_time_step(double dt)
Set initial time step.
Definition time_integrator.hpp:570
double get_time_step()
Definition time_integrator.hpp:573
Cost is identical to (summation over) number of steps.
Definition limex_integrator.hpp:132
LimexDefaultCost()
Definition limex_integrator.hpp:134
void update_cost(std::vector< number > &m_costA, const std::vector< size_t > &m_vSteps, const size_t nstages)
provides the cost for all 0...nstages stages.
Definition limex_integrator.hpp:135
For.
Definition limex_integrator.hpp:151
double m_cMatAdd
! Cost for matrix assembly
Definition limex_integrator.hpp:172
double m_cAssemble
Definition limex_integrator.hpp:171
void update_cost(std::vector< number > &m_costA, const std::vector< size_t > &nSteps, const size_t nstages)
provides the cost for all 0...nstages stages.
Definition limex_integrator.hpp:157
int m_useGamma
! Cost for solving Jx=b
Definition limex_integrator.hpp:175
double m_cSolution
! Cost for J=A+B
Definition limex_integrator.hpp:173
LimexNonlinearCost()
Definition limex_integrator.hpp:153
Contains all data for parallel execution of time steps.
Definition limex_integrator.hpp:272
void get_error()
Definition limex_integrator.hpp:295
SmartPtr< timestep_type > get_time_stepper()
Definition limex_integrator.hpp:281
ThreadData(SmartPtr< timestep_type > spTimeStep)
Definition limex_integrator.hpp:276
SmartPtr< grid_function_type > m_dot
Definition limex_integrator.hpp:317
SmartPtr< solver_type > m_solver
Definition limex_integrator.hpp:314
void set_derivative(SmartPtr< grid_function_type > sol)
Definition limex_integrator.hpp:305
SmartPtr< grid_function_type > get_derivative()
Definition limex_integrator.hpp:308
void set_error(int e)
Definition limex_integrator.hpp:291
ThreadData()
Definition limex_integrator.hpp:280
SmartPtr< timestep_type > m_stepper
Definition limex_integrator.hpp:313
int m_error
Definition limex_integrator.hpp:318
void set_solution(SmartPtr< grid_function_type > sol)
Definition limex_integrator.hpp:299
void set_solver(SmartPtr< solver_type > solver)
Definition limex_integrator.hpp:285
SmartPtr< grid_function_type > m_sol
Definition limex_integrator.hpp:316
SmartPtr< solver_type > get_solver()
Definition limex_integrator.hpp:288
SmartPtr< grid_function_type > get_solution()
Definition limex_integrator.hpp:302
Definition limex_integrator.hpp:182
unsigned int m_nstages
Number of Aitken-Neville stages.
Definition limex_integrator.hpp:210
size_t m_asymptotic_order
For PDEs, we may apply an symptotic order reduction.
Definition limex_integrator.hpp:218
LimexTimeIntegratorConfig(unsigned int nstages)
Definition limex_integrator.hpp:196
double m_greedyOrderIncrease
Definition limex_integrator.hpp:215
std::string config_string() const
Definition limex_integrator.hpp:230
double m_tol
Definition limex_integrator.hpp:211
double m_rhoSafety
Definition limex_integrator.hpp:212
bool m_useCachedMatrices
Definition limex_integrator.hpp:220
unsigned int m_conservative
Definition limex_integrator.hpp:221
size_t m_max_reductions
Definition limex_integrator.hpp:217
LimexTimeIntegratorConfig()
Definition limex_integrator.hpp:184
double m_sigmaReduction
Definition limex_integrator.hpp:213
Base class for LIMEX time integrator.
Definition limex_integrator.hpp:252
void add_stage(size_t nsteps, SmartPtr< solver_type > solver, SmartPtr< domain_discretization_type > spDD)
Definition limex_integrator.hpp:423
INonlinearTimeIntegrator< TDomain, TAlgebra > itime_integrator_type
Definition limex_integrator.hpp:266
GridFunction< TDomain, TAlgebra > grid_function_type
Definition limex_integrator.hpp:259
void add_stage_ext(size_t nsteps, SmartPtr< solver_type > solver, SmartPtr< domain_discretization_type > spDD, SmartPtr< domain_discretization_type > spGamma)
Definition limex_integrator.hpp:426
bool apply(SmartPtr< grid_function_type > u, number t1, ConstSmartPtr< grid_function_type > u0, number t0)
Integrating from t0 -> t1.
Definition limex_integrator.hpp:767
void set_debug_for_timestepper(SmartPtr< IDebugWriter< algebra_type > > spDebugWriter)
forward debug info to time integrators
Definition limex_integrator.hpp:326
SmartPtr< grid_function_type > m_spDtSol
Time derivative.
Definition limex_integrator.hpp:577
SmartPtr< error_estim_type > m_spErrorEstimator
Definition limex_integrator.hpp:560
void set_stepsize_greedy_order_factor(double sigma)
Definition limex_integrator.hpp:367
void init_gamma()
aux: compute exponents gamma_k (for roots)
Definition limex_integrator.hpp:479
std::vector< number > m_costA
Cost A_i (for completing stage i)
Definition limex_integrator.hpp:567
TAlgebra algebra_type
Definition limex_integrator.hpp:256
std::vector< number > m_gamma
gamma_i: exponent
Definition limex_integrator.hpp:565
SmartPtr< IGridFunctionSpace< grid_function_type > > m_spBanachSpace
metric space
Definition limex_integrator.hpp:582
void add_error_estimator(SmartPtr< error_estim_type > spErrorEstim)
add an error estimator
Definition limex_integrator.hpp:373
base_type::solver_type solver_type
Definition limex_integrator.hpp:261
void set_tolerance(double tol)
tolerance
Definition limex_integrator.hpp:364
std::vector< ThreadData > m_vThreadData
vector with thread information
Definition limex_integrator.hpp:563
number & monitor(size_t k, size_t q)
Definition limex_integrator.hpp:472
void select_cost_strategy(SmartPtr< ILimexCostStrategy > cost)
Definition limex_integrator.hpp:538
ISubDiagErrorEst< vector_type > error_estim_type
Definition limex_integrator.hpp:268
SmartPtr< ILimexCostStrategy > m_spCostStrategy
Definition limex_integrator.hpp:579
size_t find_optimal_solution(const std::vector< number > &eps, size_t ntest, size_t &qpred)
Definition limex_integrator.hpp:733
std::vector< size_t > m_num_reductions
history of reductions
Definition limex_integrator.hpp:573
int m_limex_step
Current counter.
Definition limex_integrator.hpp:585
std::vector< number > m_monitor
Convergence monitor \alpha.
Definition limex_integrator.hpp:568
AitkenNevilleTimex< vector_type > timex_type
Definition limex_integrator.hpp:265
SimpleTimeIntegrator< TDomain, TAlgebra > time_integrator_type
Definition limex_integrator.hpp:267
std::vector< SmartPtr< ThreadData > > thread_vector_type
Definition limex_integrator.hpp:321
number get_workload(size_t i)
Definition limex_integrator.hpp:468
void set_time_derivative(SmartPtr< grid_function_type > udot)
setter for time derivative info (optional for setting $\Gamma$)
Definition limex_integrator.hpp:526
void add_stage(size_t i, size_t nsteps, SmartPtr< domain_discretization_type > spDD, SmartPtr< solver_type > solver)
! TODO: remove this function!
Definition limex_integrator.hpp:430
std::vector< number > m_consistency_error
Consistency error.
Definition limex_integrator.hpp:575
void dispose_integrator_threads()
Dispose integrator threads (w/ solutions)
Definition limex_integrator.hpp:607
void disable_matrix_cache()
Select approximate Newton (default)
Definition limex_integrator.hpp:536
void set_max_reductions(size_t nred)
Definition limex_integrator.hpp:369
IDomainDiscretization< algebra_type > domain_discretization_type
Definition limex_integrator.hpp:263
algebra_type::matrix_type matrix_type
Definition limex_integrator.hpp:257
std::vector< size_t > m_vSteps
generating sequence for extrapolation
Definition limex_integrator.hpp:562
std::vector< number > m_lambda
Definition limex_integrator.hpp:571
void set_space(SmartPtr< IGridFunctionSpace< grid_function_type > > spSpace)
set banach space (e.g. for computing consistency error)
Definition limex_integrator.hpp:543
bool has_time_derivative()
status for time derivative info (optional for setting $\Gamma$)
Definition limex_integrator.hpp:532
SmartPtr< grid_function_type > get_time_derivative()
getter for time derivative info (optional for setting $\Gamma$)
Definition limex_integrator.hpp:529
LimexTimeIntegrator(int nstages)
Definition limex_integrator.hpp:342
void update_integrator_threads(ConstSmartPtr< grid_function_type > ucommon, number t)
Override thread-wise solutions with common solution.
Definition limex_integrator.hpp:721
LinearImplicitEuler< algebra_type > timestep_type
Definition limex_integrator.hpp:264
void enable_matrix_cache()
Select classic LIMEX.
Definition limex_integrator.hpp:535
void interrupt()
interrupt execution of apply() by external call via observer
Definition limex_integrator.hpp:550
SmartPtr< timestep_type > get_time_stepper(size_t i)
Definition limex_integrator.hpp:437
void set_stepsize_safety_factor(double rho)
Definition limex_integrator.hpp:365
number get_cost(size_t i)
Definition limex_integrator.hpp:466
void update_monitor()
convergence monitor
Definition limex_integrator.hpp:496
std::string config_string() const
Definition limex_integrator.hpp:555
void set_conservative(bool c)
Definition limex_integrator.hpp:552
number get_gamma(size_t i)
Definition limex_integrator.hpp:467
algebra_type::vector_type vector_type
Definition limex_integrator.hpp:258
void init_integrator_threads(ConstSmartPtr< grid_function_type > u)
Initialize integrator threads (w/ solutions)
Definition limex_integrator.hpp:593
void update_cost()
Updating workloads A_i for computing T_ii.
Definition limex_integrator.hpp:489
void add_stage_base(size_t nsteps, SmartPtr< solver_type > solver, SmartPtr< domain_discretization_type > spDD, SmartPtr< domain_discretization_type > spGamma=SPNULL)
add a new stage (at end of list)
Definition limex_integrator.hpp:377
bool m_bInterrupt
Definition limex_integrator.hpp:584
INonlinearTimeIntegrator< TDomain, TAlgebra > base_type
Definition limex_integrator.hpp:260
std::vector< number > m_workload
Definition limex_integrator.hpp:570
int apply_integrator_threads(number dtcurr, ConstSmartPtr< grid_function_type > u0, number t0, size_t nstages)
(Tentatively) apply integrators
Definition limex_integrator.hpp:636
void join_integrator_threads()
e.g. wait for all threads to complete
Definition limex_integrator.hpp:708
void set_asymptotic_order(size_t q)
Definition limex_integrator.hpp:370
void set_stepsize_reduction_factor(double sigma)
Definition limex_integrator.hpp:366
Definition linear_implicit_timestep.h:74
Integrate (a non-linear problem) over a given time interval.
Definition simple_integrator.hpp:11
number get_consistency_error() const
Definition simple_integrator.hpp:53
void set_banach_space(SmartPtr< IGridFunctionSpace< grid_function_type > > spSpace)
Definition simple_integrator.hpp:56
void set_derivative(SmartPtr< grid_function_type > udot)
Definition simple_integrator.hpp:47
bool apply(SmartPtr< grid_function_type > u1, number t1, ConstSmartPtr< grid_function_type > u0, number t0)
Definition simple_integrator.hpp:38
const std::string & get_file(size_t i) const
unsigned long get_line(size_t i) const
const std::string & get_msg() const
size_t num_msg() const
virtual void set_debug(SmartPtr< IVectorDebugWriter< vector_type > > spDebugWriter)
void write_debug(const vector_type &vec, const char *filename)
const NullSmartPtr SPNULL
#define UG_ASSERT(expr, msg)
#define UG_DLOG(__debugID__, level, msg)
#define UG_LOG(msg)
#define UG_LOGN(msg)
#define UG_COND_THROW(cond, msg)
double number
static void MyPrintError(UGError &err)
Definition limex_integrator.hpp:99
DebugID LIB_LIMEX("LIB_LIMEX")
Definition limex_tools.h:51
#define PROFILE_FUNC_GROUP(groups)
SmartPtr< T, FreePolicy > make_sp(T *inst)
function ProblemDisc new(problemDesc, dom)