KASKADE 7 development version
limexWithoutJensHierarchicEst.hh
Go to the documentation of this file.
1#ifndef LIMEX_HH
2#define LIMEX_HH
3
4#include <fstream>
5#include <iostream>
6
7#include <boost/timer/timer.hpp>
8
9#include "dune/istl/solvers.hh"
10
12#include "fem/iterate_grid.hh"
15#include "fem/istlinterface.hh"
16
17#include "dune/istl/solvers.hh"
18#include "dune/istl/preconditioners.hh"
19
22
25// #include "linalg/mumps_solve.hh"
26// #include "linalg/superlu_solve.hh"
27
29#include "linalg/direct.hh"
30#include "linalg/triplet.hh"
31#include "linalg/iluprecond.hh"
32// #include "linalg/hyprecond.hh"
34
35#include "utilities/enums.hh"
36
37#include "io/vtk.hh"
38
39bool fabscompare( double a, double b ) { return fabs( a ) < fabs( b ) ; }
40
42
43namespace Kaskade
44{
45
46
47 template <class Functional>
48 struct CardioD2
49 {
50 template <int row, int col>
51 class D2: public Functional::template D2<row,col>
52 {
53 typedef typename Functional::template D2<row,col> d2;
54
55 public:
56 static bool const present = d2::present && (row==0) && (col==0);
57 static bool const lumped = true;
58 };
59 };
60
69template <class Eq>
70class Limex
71{
72public:
74 typedef typename EvolutionEquation::AnsatzVars::VariableSet State;
75
76private:
79
80 // for hierarchic error estimator
82 typedef boost::fusion::vector< typename SpaceType<typename Eq::AnsatzVars::Spaces,0>::type const*, SpaceEx const*> ExSpaces;
83
84// two components, 1 space -- how to generalize?
85// typedef boost::fusion::vector<VariableDescription<1,1,0>, VariableDescription<1,1,1> > ExVariableDescriptions;
86
87 // 1 component, 1 space -- how to generalize?
88 typedef boost::fusion::vector<VariableDescription<1,1,0> > ExVariableDescriptions;
89
93
94// typedef typename EstimatorAssembler::template AnsatzVariableRepresentation<> Ansatz;
95// typedef typename EstimatorAssembler::template TestVariableRepresentation<> Test;
96/* typedef typename ExVariableSet::template CoefficientVectorRepresentation<0,1>::type ExCoefficientVectors;*/
97
98 typedef typename Eq::AnsatzVars::Grid::Traits::LeafIndexSet IS ;
99
100
101public:
107 EvolutionEquation& eq_, typename EvolutionEquation::AnsatzVars const& ansatzVars_, DirectType st=DirectType::UMFPACK):
108 gridManager(gridManager_), ansatzVars(ansatzVars_), eq(&eq_,0),
109 assembler(ansatzVars.spaces),
110 iteSteps(10000), iteEps(1e-6), extrap(0),
112 solverType(st)
113 {}
114
115
122 State const& step(State const& x, double dt, int order,
123 std::vector<std::pair<double,double> > const& tolX)
124 {
125 std::vector<std::vector<bool> > tmp ;
126 return step(x,dt,order,tolX,tmp);
127 }
128
146 State const& step(State const& x, double dt, int order,
147 std::vector<std::pair<double,double> > const& tolX,
148
149 std::vector< std::vector<bool> > &refinements )
150 {
151 boost::timer::cpu_timer timer;
152
153 std::vector<double> stepFractions(order+1);
154 for (int i=0; i<=order; ++i) stepFractions[i] = 1.0/(i+1); // harmonic sequence
155 extrap.clear();
156
157 typedef typename EvolutionEquation::AnsatzVars::Grid Grid;
158
159 int const dim = EvolutionEquation::AnsatzVars::Grid::dimension;
160 int const nvars = EvolutionEquation::AnsatzVars::noOfVariables;
161 int const neq = EvolutionEquation::TestVars::noOfVariables;
162 size_t nnz = assembler.nnz(0,neq,0,nvars,false);
163 size_t size = ansatzVars.degreesOfFreedom(0,nvars);
164
165 std::vector<double> rhs(size), sol(size);
166
167 State dx(x), dxsum(x), tmp(x);
168 double const t = eq.time();
169
170 double estTime = 0 ;
171
172 eq.temporalEvaluationRange(t,t+dt);
173
175
176 bool iterative = true ;
177 int fill_lev = /*0*/ /*1*/2;
178
179 typedef typename EvolutionEquation::AnsatzVars::template CoefficientVectorRepresentation<0,neq>::type
180 CoefficientVectors;
181 typedef typename EvolutionEquation::TestVars::template CoefficientVectorRepresentation<0,neq>::type
182 LinearSpaceX;
183
184 for (int i=0; i<=order; ++i) {
185 double const tau = stepFractions[i]*dt;
186 eq.setTau(tau);
187 eq.time(t);
188
189 // mesh adaptation loop. Just once if i>0.
190 bool accurate = true;
191 int refinement_count = 0 ;
192
193
194 do {
195 // Evaluate and factorize matrix B(t)-tau*J
196 dx/* * */= 0;
197 timer.start();
198
199// assembler.assemble(Linearization(eq,x,x,dx)/*,(Assembler::VALUE|Assembler::RHS|Assembler::MATRIX),4*/);
200
201// #ifndef KASKADE_SEQUENTIAL
202// gridManager.enforceConcurrentReads(std::is_same<Grid,Dune::UGGrid<dim> >::value);
203// assembler.setNSimultaneousBlocks(40);
204// assembler.setRowBlockFactor(2.0);
205// #endif
206// std::cout << "assemble linear system ..." ; std::cout.flush();
207 assembler.assemble(Linearization(eq,x,x,dx)/*,(Assembler::VALUE|Assembler::RHS|Assembler::MATRIX),4*/);
208// std::cout << " done\n"; std::cout.flush();
209
210 matrixAssemblyTime += (double)(timer.elapsed().user)/1e9;
211
212 Op A(assembler);
213// std::cout << "solve linear system\n"; std::cout.flush();
214
215 if (iterative)
216 {
217 timer.start();
218
219 CoefficientVectors solution(EvolutionEquation::AnsatzVars::template CoefficientVectorRepresentation<0,neq>::init(ansatzVars.spaces)
220 );
221 solution = 0;
222 CoefficientVectors rhs(assembler.rhs());
223
224 ILUKPreconditioner<Op> p(A,fill_lev,0);
225// ILUTPreconditioner<Op> p(A,240,1e-2,0);
226// JacobiPreconditioner<Op> p(A,1.0);
227
228 Dune::BiCGSTABSolver<LinearSpaceX> cg(A,p,1e-7,2000,0); //verbosity: 0-1-2 (nothing-start/final-every it.)
229 Dune::InverseOperatorResult res;
230 cg.apply(solution,rhs,res);
231 if ( !(res.converged) || (res.iterations == 2001) ) {
232 std::cout << " no of iterations in cg = " << res.iterations << std::endl;
233 std::cout << " convergence status of cg = " << res.converged << std::endl;
234 assert(0);
235 }
236 dx.data = solution.data;
237 solutionTime += (double)(timer.elapsed().user)/1e9;
238 }
239 else
240 {
241 // direct solution
242 timer.start();
243// assembler.toTriplet(0,neq,0,nvars,ridx.begin(),cidx.begin(),data.begin(),false);
244 MatrixAsTriplet<double> triplet = A.template get<MatrixAsTriplet<double> >();
245
246 Factorization<double> *matrix = 0;
247 switch (solverType) {
249 matrix = new UMFFactorization<double>(size,triplet.ridx,triplet.cidx,triplet.data);
250 break;
252 matrix = new UMFFactorization<double>(size,triplet.ridx,triplet.cidx,triplet.data);
253 break;
254// case MUMPS:
255// matrix = new MUMPSFactorization<double>(size,triplet.ridx,triplet.cidx,triplet.data);
256// break;
257// case SUPERLU:
258// matrix = new SUPERLUFactorization<double>(size,triplet.ridx,triplet.cidx,triplet.data);
259// break;
260 default:
261 throw -321;
262 break;
263 }
264 factorizationTime += (double)(timer.elapsed().user)/1e9;
265
266 // First right hand side (j=0) has been assembled together with matrix.
267 timer.start();
268 A.getAssembler().toSequence(0,neq,rhs.begin());
269 for (int k=0; k<rhs.size(); ++k) assert(std::isfinite(rhs[k]));
270 matrix->solve(rhs,sol);
271 delete matrix;
272 for (int k=0; k<sol.size(); ++k) assert(std::isfinite(sol[k]));
273 dx.read(sol.begin());
274 solutionTime += (double)(timer.elapsed().user)/1e9;
275
276
277// Factorization<double> *matrix = 0;
278// switch (solverType)
279// {
280// case UMFPACK:
281// matrix = new UMFFactorization<double>(size,ridx,cidx,data);
282// break;
283// case UMFPACK3264:
284// matrix = new UMFFactorization<double>(size,ridx,cidx,data);
285// break;
286// case MUMPS:
287// matrix = new MUMPSFactorization<double>(size,ridx,cidx,data);
288// break;
289// case SUPERLU:
290// matrix = new SUPERLUFactorization<double>(size,ridx,cidx,data);
291// break;
292// default:
293// throw -321;
294// break;
295// }
296// factorizationTime += (double)(timer.elapsed().user)/1e9;
297//
298// // First right hand side (j=0) has been assembled together with matrix.
299// timer.start();
300// assembler.toSequence(0,neq,rhs.begin());
301// for (size_t k=0; k<rhs.size(); ++k) assert(finite(rhs[k]));
302// matrix->solve(rhs,sol);
303// delete matrix;
304// for (size_t k=0; k<sol.size(); ++k) assert(finite(sol[k]));
305// dx.read(sol.begin());
306// solutionTime += (double)(timer.elapsed().user)/1e9;
307 //end: direct solution
308 }
309
310 // Mesh adaptation only if requested and only for the full
311 // implicit Euler step (first stage).
312
313 typedef typename EvolutionEquation::AnsatzVars::GridView::template Codim<0>::Iterator CellIterator ;
314
315 accurate = true ;
316 timer.start();
317 IS const& is = gridManager.grid().leafIndexSet();
318 std::vector<double> errorDistribution(is.size(0),0.0);
319 double maxErr = 0.0, errNorm = 0.0 ;
320
321 if (!tolX.empty() && i==0) {
322
323 // embeddedErrorEstimator can not be used for linear finite elements
324 // use HierarchicErrorEstimator instead
325 // preparation for HierarchicErrorEstimator
326 if(true) // to avoid mesh adaptation for exVariables
327 {
328 //TODO: this should be using the gridviews/index sets of the original space, not the leaf!
329 SpaceEx spaceEx(gridManager,gridManager.grid().leafGridView(), boost::fusion::at_c<0>(ansatzVars.spaces)->mapper().maxOrder()+1);
330 typename SpaceType<typename Eq::AnsatzVars::Spaces,0>::type spaceH1 = *(boost::fusion::at_c<0>(ansatzVars.spaces)) ;
331 ExSpaces exSpaces(&spaceH1,&spaceEx);
332 std::string exVarNames[2] = { "ev", "ew" };
333 ExVariableSet exVariableSet(exSpaces, exVarNames);
334 EstimatorAssembler estAssembler(gridManager,exSpaces);
335
336 tmp/* * */= 0 ;
337// estAssembler.assemble(ErrorEstimator(Linearization(eq,x,x,tmp/*dx*/),dx));
338 estAssembler.assemble(ErrorEstimator(semiLinearization(eq,x,x,/*dx*/tmp),dx));
339
340
341 int const estNvars = ErrorEstimator::AnsatzVars::noOfVariables;
342// std::cout << "estimator: nvars = " << estNvars << "\n";
343 int const estNeq = ErrorEstimator::TestVars::noOfVariables;
344// std::cout << "estimator: neq = " << estNeq << "\n";
345 size_t estNnz = estAssembler.nnz(0,estNeq,0,estNvars,false);
346 size_t estSize = exVariableSet.degreesOfFreedom(0,estNvars);
347
348 std::vector<int> estRidx(estNnz), estCidx(estNnz);
349 std::vector<double> estData(estNnz), estRhs(estSize), estSolVec(estSize);
350
351 estAssembler.toSequence(0,estNeq,estRhs.begin());
352
353 typedef typename ExVariableSet::template CoefficientVectorRepresentation<0,estNeq>::type ExCoefficientVectors;
354
355 // iterative solution of error estimator
356// timer.start();
357// AssembledGalerkinOperator<EstimatorAssembler> E(estAssembler);
358// typename Dune::InverseOperatorResult estRes;
359// typename Test::type estRhside( Test::rhs(estAssembler) ) ;
360// typename Ansatz::type estSol( Ansatz::init(estAssembler) ) ;
361// estSol = 1.0 ;
362// JacobiPreconditioner<EstimatorAssembler> jprec(estAssembler, 1.0);
363// jprec.apply(estSol,estRhside); //single Jacobi iteration
364// estTime += (double)(timer.elapsed().user)/1e9;
365// estSol.write(estSolVec.begin());
366
368 AssEstOperator agro(estAssembler);
369 Dune::InverseOperatorResult estRes;
370 ExCoefficientVectors estRhside(estAssembler.rhs());
371 ExCoefficientVectors estSol(ExVariableSet::template CoefficientVectorRepresentation<0,estNeq>::init(exVariableSet.spaces));
372 estSol = 1.0 ;
374 jprec.apply(estSol,estRhside); //single Jacobi iteration
375// estTime += (double)(timer.elapsed().user)/1e9;
376 estSol.write(estSolVec.begin());
377
378 //--
379
380 // Transfer error indicators to cells.
381 CellIterator ciEnd = ansatzVars.gridView.template end<0>() ;
382 for (CellIterator ci=ansatzVars.gridView.template begin<0>(); ci!=ciEnd; ++ci) {
383 typedef typename SpaceEx::Mapper::GlobalIndexRange GIR;
384 double err = 0.0;
385 GIR gix = spaceEx.mapper().globalIndices(*ci);
386 for (typename GIR::iterator j=gix.begin(); j!=gix.end(); ++j)
387 err += fabs(boost::fusion::at_c<0>(estSol.data)[*j]);
388 // only for 1st component -- second in monodomain is ODE
389 errorDistribution[is.index(*ci)] = err;
390 if (fabs(err)>maxErr) maxErr = fabs(err);
391 }
392// std::cout << "maxErr: " << maxErr << "\n";
393
394// for( size_t cno = 0 ; cno < is.size(0); cno++ )
395// std::cout << cno << "\t\t" << errorDistribution[cno] << "\n";
396// std::cout.flush();
397
398 //TODO: estimate only error in PDE, not ODE!
399 // what about relative accuracy?
400 for (size_t k = 0; k < estRhs.size() ; k++ ) errNorm += fabs( estRhs[k] * estSolVec[k] );
401 // this is for all variables?!
402// errNorm = tau/*dt*/*sqrt(errNorm);
403 std::cout << "errNorm = " << errNorm << std::endl ;
404 std::cout.flush();
405
406 }
407
408 double overallTol = tolX[0].first ;
409
410
411// for( int i = 0 ; i < 1 /*nvars*/ ; i++ )
412// overallTol += tolX[i].first*tolX[i].first ;
413// overallTol = sqrt(overallTol);
414
415// std::cout << "overallTol = " << overallTol << std::endl ;
416
417
418// alpha = 0 ; // for uniform refinement
419
420 int nRefMax = /*10*/7 ;/*7*//*5*//*3*//*15*/ /*4*/ /*5*/ /*10*/
421 double fractionOfCells = 0.05; /*0.1,0.2*/
422 unsigned long noToRefine = 0, noToCoarsen = 0;
423 double alpha = 1.0; /*0.5; //test april 13*/
424
425 double errLevel = 0.5*maxErr ; //0.75
426// double minRefine = 0.05;
427
428// if (minRefine>0.0)
429// {
430// std::vector<double> eSort(errorDistribution);
431// std::sort(eSort.begin(),eSort.end(),fabscompare);
432// int minRefineIndex = minRefine*(eSort.size()-1);
433// double minErrLevel = fabs(eSort[minRefineIndex])+1.0e-15;
434// if (minErrLevel<errLevel)
435// errLevel = minErrLevel;
436// }
437
438// double minRefine = fractionOfCells; //* gridManager.grid().size(0);
439// if (minRefine >0.0)
440// {
441// std::vector<double> eSort(errorDistribution);
442// std::sort(eSort.begin(),eSort.end(),fabscompare);
443// int minRefineIndex = minRefine*(eSort.size()-1);
444// double minErrLevel = fabs(eSort[minRefineIndex])+1.0e-15;
445// if (minErrLevel<errLevel)
446// errLevel = minErrLevel;
447// }
448
449 size_t maxNoOfVertices =/* 500000*/ /*2000000*//*12000*/30000;
450 size_t maxNoOfElements = 2000000;
451 int maxLevel = /*20*/6 /*25*/ /*18*/; // additional refinement levels
452
453 if( errNorm > overallTol && refinement_count < nRefMax
454 && gridManager.grid().size(/*dim*/0) < /*maxNoOfVertices*/maxNoOfElements )
455 //current setup: for 2D BFGS; for 3D fibrillation: use maxNoOfElements
456 {
457// accurate = false;
458// std::vector<bool> toRefine( is.size(0), false ) ;
459// size_t noCells = gridManager.grid().size(0);
460// // std::cout << is.size(0) << " " << noCells << "\n"; std::cout.flush();
461// for( size_t cno = 0 ; cno < noCells ; cno++ )
462// {
463// if (fabs(errorDistribution[cno]) >= alpha*errLevel)
464// {
465// noToRefine++;
466// toRefine[cno] = true ;
467// }
468// }
469 std::vector<bool> toRefine( is.size(0), false ) ; //for adaptivity in compression
470
471 accurate = false ;
472 size_t noCells = gridManager.grid().size(0);
473
474// // Nagaiah paper:
475// unsigned minLevel = 10 ; // do not coarsen below that level
476// CellIterator ciEnd = ansatzVars.gridView.template end<0>() ;
477// for (CellIterator ci=ansatzVars.gridView.template begin<0>(); ci!=ciEnd; ++ci)
478// {
479// double vol = sqrt( ci->geometry().volume() );
480// if (fabs(errorDistribution[is.index(*ci)])/vol >= 0.2 /*0.1*/ )
481// {
482// if( ci->level() < maxLevel && gridManager.grid().size(dim) < maxNoOfVertices )
483// {
484// gridManager.mark(1,*ci);
485// noToRefine++;
486// }
487// }
488// else if (fabs(errorDistribution[is.index(*ci)])/vol < 0.1 /* /2 */ && ci->level() > minLevel )
489// {
490// gridManager.mark(-1,*ci);
491// noToCoarsen++;
492// }
493// }
494// std::cout << "refine: " << noToRefine << " coarsen: " << noToCoarsen << "\n";
495// gridManager.countMarked();
496
497// last implementation was the following:
498 unsigned long noToRefineOld = 0;
499 do{
500 noToRefineOld = noToRefine;
501 for( size_t cno = 0 ; cno < noCells ; cno++ )
502 {
503 if (fabs(errorDistribution[cno]) >= alpha*errLevel)
504 { // TODO: check and bugfix this!
505 if( !toRefine[cno] ) noToRefine++;
506 toRefine[cno] = true ;
507 }
508 }
509// std::cout << "alpha: " << alpha << "\trefine: " << noToRefine << "\n";
510// std::cout.flush();
511 alpha *= 0.75; // refine more aggressively: reduce alpha by larger amount
512 } while ( noToRefine < fractionOfCells * noCells && (!noToRefineOld == noToRefine) ) ;
513// std::cout << "to refine: " << noToRefine << "\n";
514 std::cout.flush();
515
516
517// alpha = 0.5; //50
518// do {
519// for( size_t cno = 0 ; cno < noCells ; cno++ )
520// if (fabs(errorDistribution[cno]) > alpha*maxErr/*overallTol/noCells*/) {
521// /*if( !toRefine[cno] )*/ noToRefine++;
522// toRefine[cno] = true;
523// }
524//
525// alpha *=0.9;
526// } while (noToRefine < fractionOfCells * noCells);
527
528// long int nRefined = (long int) std::count( toRefine.begin(), toRefine.end(), true );
529// std::cout << " noToRefine = " << nRefined << std::endl;
530// refinements.push_back(toRefine);
531
532 for (CellIterator ci=ansatzVars.gridView.template begin<0>(); ci!=ansatzVars.gridView.template end<0>(); ++ci)
533 if( toRefine[is.index(*ci)] && ci->level() < maxLevel ) gridManager.mark(1,*ci);
534
535 bool refok = gridManager.adaptAtOnce(); // something has been refined?
536 if( !refok )
537 {
538 // nothing has been refined
539 std::cout << "nothing has been refined (probably due to maxLevel constraint), stopping\n";
540 accurate = true ;
541 }
542
543 if (!accurate) {
544 refinement_count++ ;
545 nnz = assembler.nnz(0,neq,0,nvars,false);
546 size = ansatzVars.degreesOfFreedom(0,nvars);
547 rhs.resize(size);
548 sol.resize(size);
549 }
550 }
551 else
552 {
553 if( errNorm > overallTol && refinement_count > nRefMax )
554 std::cout << "max no of refinements exceeded\n";
555// if( errNorm > overallTol && gridManager.grid().size(2) > maxNoOfVertices )
556// std::cout << "max no of nodes exceeded\n";
557
558 accurate = true ;
559 }
560 }
561 } while (!accurate);
562 adaptivityTime += (double)(timer.elapsed().user)/1e9;
563
564// std::cout << gridManager.grid().size(dim) << " nodes on " << gridManager.grid().maxLevel() << "levels\n";
565
566 dxsum = dx;
567
568 // propagate by linearly implicit Euler
569 for (int j=1; j<=i; ++j) {
570 // Assemble new right hand side tau*f(x_j)
571 eq.time(eq.time()+tau);
572 tmp = x; tmp += dxsum;
573 State zero(x); zero /* * */= 0;
574 timer.start();
575// gridManager.enforceConcurrentReads(true);
576// assembler.setNSimultaneousBlocks(40);
577// assembler.setRowBlockFactor(2.0);
578 assembler.assemble(Linearization(eq,tmp,x,zero),Assembler::RHS|Assembler::MATRIX,4);
579 rhsAssemblyTime += (double)(timer.elapsed().user)/1e9;
580
581 Op A(assembler);
582
583 if( !iterative )
584 {
585 timer.start();
586 //direct solution
587 A.getAssembler().toSequence(0,neq,rhs.begin());
588 MatrixAsTriplet<double> triplet = A.template get<MatrixAsTriplet<double> >();
589 Factorization<double> *matrix = 0;
590 switch (solverType) {
592 matrix = new UMFFactorization<double>(size,triplet.ridx,triplet.cidx,triplet.data);
593 break;
595 matrix = new UMFFactorization<double>(size,triplet.ridx,triplet.cidx,triplet.data);
596 break;
597// case MUMPS:
598// matrix = new MUMPSFactorization<double>(size,triplet.ridx,triplet.cidx,triplet.data);
599// break;
600// case SUPERLU:
601// matrix = new SUPERLUFactorization<double>(size,triplet.ridx,triplet.cidx,triplet.data);
602// break;
603 default:
604 throw -321;
605 break;
606 }
607 factorizationTime += (double)(timer.elapsed().user)/1e9;
608 timer.start();
609 matrix->solve(rhs,sol);
610 delete matrix;
611 for (int k=0; k<rhs.size(); ++k) assert(std::isfinite(rhs[k]));
612 for (int k=0; k<sol.size(); ++k) assert(std::isfinite(sol[k]));
613 dx.read(sol.begin());
614 solutionTime += (double)(timer.elapsed().user)/1e9;
615 }
616 else
617 {
618 timer.start();
619 CoefficientVectors solution(EvolutionEquation::AnsatzVars::template
620 CoefficientVectorRepresentation<0,neq>::init(ansatzVars.spaces) );
621 solution = 0;
622 // assembler.assemble(linearization(F,x));
623 CoefficientVectors rhs(assembler.rhs());
624
625 ILUKPreconditioner<Op> p(A,fill_lev,0);
626// ILUTPreconditioner<Op> p(A,240,1e-2,0);
627// JacobiPreconditioner<Op> p(A,1.0);
628
629
630 Dune::BiCGSTABSolver<LinearSpaceX> cg(A,p,1e-7,2000,0); //verbosity: 0-1-2 (nothing-start/final-every it.)
631 Dune::InverseOperatorResult res;
632 cg.apply(solution,rhs,res);
633 if ( !(res.converged) || (res.iterations == 2001) ) {
634 std::cout << " no of iterations in cg = " << res.iterations << std::endl;
635 std::cout << " convergence status of cg = " << res.converged << std::endl;
636 assert(0);
637 }
638 dx.data = solution.data;
639// // iterative solution
640// timer.start();
641// typedef typename Assembler::template TestVariableRepresentation<>::type Rhs;
642// typedef typename Assembler::template AnsatzVariableRepresentation<>::type Sol;
643// Sol solution(Assembler::template AnsatzVariableRepresentation<>::init(assembler));
644// Rhs rhside(Assembler::template TestVariableRepresentation<>::rhs(assembler));
645// AssembledGalerkinOperator<Assembler,0,1,0,1> A(assembler, false);
646// typename AssembledGalerkinOperator<Assembler,0,1,0,1>::matrix_type tri(A.getmat());
647//
648//
649// typedef typename Assembler::template TestVariableRepresentation<>::type LinearSpace;
650// Dune::InverseOperatorResult res;
651// solution = 1.0;
652// JacobiPreconditioner<Assembler,0,1,0> p(assembler,1.0);
653// // TrivialPreconditioner<LinearSpace> trivial;
654// Dune::CGSolver<LinearSpace> cg(A,/*trivial*/p,iteEps,iteSteps,0);
655// cg.apply(solution,rhside,res);
656// A.applyscaleadd(-1.0,rhside,solution);
657// double slntime = (double)(timer.elapsed().user)/1e9;
658// solutionTime += slntime ;
659// dx.data = solution.data ;
660// // end: iterative solution
661 }
662
663 dxsum += dx;
664 solutionTime += (double)(timer.elapsed().user)/1e9;
665 }
666
667 // insert into extrapolation tableau
668 extrap.push_back(dxsum,stepFractions[i]);
669
670 // restore initial time
671 eq.time(t);
672 }
673
674 return extrap.back();
675 }
676
683 std::vector<std::pair<double,double> > estimateError(State const& x,int i, int j) const
684 {
685 assert(extrap.size()>1);
686
687 std::vector<std::pair<double,double> > e(ansatzVars.noOfVariables);
688
689 relativeError(typename EvolutionEquation::AnsatzVars::Variables(),extrap[i].data,
690 extrap[j].data,x.data,
691 ansatzVars.spaces,eq.scaling(),e.begin());
692
693 return e;
694 }
695
696 template <class OutStream>
697 void reportTime(OutStream& out) const {
698 out << "Limex time: " << matrixAssemblyTime << "s matrix assembly\n"
699 << " " << rhsAssemblyTime << "s rhs assembly\n"
700 << " " << factorizationTime << "s factorization\n"
701 << " " << solutionTime << "s solution\n"
702 << " " << adaptivityTime << "s adaptivity\n";
703 }
704
705 void advanceTime(double dt) { eq.time(eq.time()+dt); }
706
707
708private:
710 typename EvolutionEquation::AnsatzVars const& ansatzVars;
712 Assembler assembler;
713 int iteSteps ;
714 double iteEps ;
715
716public:
720};
721
722} //namespace Kaskade
723#endif
An adaptor presenting a Dune::LinearOperator <domain_type,range_type> interface to a contiguous sub-b...
void push_back(T t, double hnew)
A representation of a finite element function space defined over a domain covered by a grid.
LocalToGlobalMapper const & mapper() const
Provides read access to the node manager.
Abstract base class for matrix factorizations.
Grid const & grid() const
Returns a const reference on the owned grid.
Definition: gridmanager.hh:292
bool adaptAtOnce()
DEPRECATED Performs grid refinement without prolongating registered FE functions.
Definition: gridmanager.hh:390
bool mark(int refCount, typename Grid::template Codim< 0 >::Entity const &cell)
Marks the given cell for refinement or coarsening.
Definition: gridmanager.hh:330
Defines assembly of hierarchically extended problems for defining DLY style error estimators.
virtual void apply(domain_type &x, range_type const &b)
Extrapolated linearly implicit Euler method.
Definition: limex.hh:33
EvolutionEquation::AnsatzVars::VariableSet State
double rhsAssemblyTime
Definition: limex.hh:172
State const & step(State const &x, double dt, int order)
Definition: limex.hh:66
double matrixAssemblyTime
Definition: limex.hh:172
State const & step(State const &x, double dt, int order, std::vector< std::pair< double, double > > const &tolX)
double solutionTime
Definition: limex.hh:172
std::vector< std::pair< double, double > > estimateError(State const &x, int i, int j) const
State const & step(State const &x, double dt, int order, std::vector< std::pair< double, double > > const &tolX, std::vector< std::vector< bool > > &refinements)
ExtrapolationTableau< State > extrap
Definition: limex.hh:171
Limex(GridManager< typename EvolutionEquation::AnsatzVars::Grid > &gridManager_, EvolutionEquation &eq_, typename EvolutionEquation::AnsatzVars const &ansatzVars_, DirectType st=DirectType::UMFPACK)
void reportTime(OutStream &out) const
double factorizationTime
Definition: limex.hh:172
std::vector< SparseIndexInt > ridx
row indices
Definition: triplet.hh:669
std::vector< SparseIndexInt > cidx
column indices
Definition: triplet.hh:671
std::vector< Scalar > data
data
Definition: triplet.hh:673
Self & setTau(Scalar dt)
Sets the time step size.
Definition: semieuler.hh:428
Proxy class for the linearization of semi-linear time stepping schemes.
Factorization of sparse linear systems with UMFPack.
A class that stores information about a set of variables.
Definition: variables.hh:537
size_t degreesOfFreedom(int first=0, int last=noOfVariables) const
Computes the total number of scalar degrees of freedom collected in the variables [first,...
Definition: variables.hh:661
Spaces spaces
A heterogeneous sequence of pointers to (const) spaces involved.
Definition: variables.hh:807
void toSequence(int rbegin, int rend, DataOutIter xi) const
Writes the subvector defined by the half-open block range [rbegin,rend) to the output iterator xi.
TestVariableSetDescription::template CoefficientVectorRepresentation< first, last >::type rhs() const
Returns a contiguous subrange of the rhs coefficient vectors.
size_t nnz(size_t rbegin=0, size_t rend=TestVariableSetDescription::noOfVariables, size_t cbegin=0, size_t cend=AnsatzVariableSetDescription::noOfVariables, bool extractOnlyLowerTriangle=false) const
Returns the number of structurally nonzero entries in the submatrix defined by the half-open block ra...
void assemble(F const &f, unsigned int flags=Assembler::EVERYTHING, int nThreads=0, bool verbose=false)
Assembly without block filter or cell filter.
Error estimation via hierachic FEM.
DirectType
Available direct solvers for linear equation systems.
Definition: enums.hh:35
@ UMFPACK3264
NO LONGER SUPPORTED.
@ UMFPACK
UMFPack from SuiteSparse, using 32 bit integer indices.
Hierarchic Finite Elements.
bool fabscompare(double a, double b)
DirectType xyz
void relativeError(Variables const &varDesc, Functions const &f1, Functions const &f2, Functions const &f3, Spaces const &spaces, Scaling const &scaling, OutIter out)
std::remove_pointer_t< typename boost::fusion::result_of::value_at_c< Spaces, Idx >::type > type
Output of mesh and solution for visualization software.