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