dune-fem 2.12-git
Loading...
Searching...
No Matches
cginverseoperator.hh
Go to the documentation of this file.
1#ifndef DUNE_FEM_CGINVERSEOPERATOR_HH
2#define DUNE_FEM_CGINVERSEOPERATOR_HH
3
4#include <limits>
5#include <memory>
6#include <type_traits>
7
13
14namespace Dune
15{
16
17 namespace Fem
18 {
19
20 // ConjugateGradientSolver
21 // -----------------------
22
29 template< class Operator>
31 {
33
34 public:
37
43
48
51
52
53 private:
55 "DomainFunctionType must equal RangeFunctionType." );
56
57 public:
66 unsigned int maxIterations,
67 int errorMeasure,
68 bool verbose )
69 : epsilon_( epsilon ),
70 maxIterations_( maxIterations ),
71 errorMeasure_( errorMeasure ),
72 verbose_( verbose && Fem::Parameter::verbose() ),
73 averageCommTime_( 0.0 ),
74 realCount_( 0 )
75 {}
77 unsigned int maxIterations,
78 bool verbose,
79 const ParameterReader &parameter = Parameter::container() )
80 : epsilon_( epsilon ),
81 maxIterations_( maxIterations ),
82 errorMeasure_( 1 ),
83 verbose_( verbose && Fem::Parameter::verbose() ),
84 averageCommTime_( 0.0 ),
85 realCount_( 0 )
86 {}
87
94 unsigned int maxIterations,
95 const ParameterReader &parameter = Parameter::container() )
96 : epsilon_( epsilon ),
97 maxIterations_( maxIterations ),
98 errorMeasure_( 1 ),
99 verbose_( parameter.getValue< bool >( "fem.solver.verbose", false ) ),
100 averageCommTime_( 0.0 ),
101 realCount_( 0 )
102 {}
103
104 // ConjugateGradientSolver ( const ThisType & )=delete;
105
117 void solve ( const OperatorType &op, const RangeFunctionType &b, DomainFunctionType &x ) const;
118
131 void solve ( const OperatorType &op, const PreconditionerType &p,
132 const RangeFunctionType &b, DomainFunctionType &x ) const;
133
135 unsigned int iterations () const
136 {
137 return realCount_;
138 }
139
140 void setMaxIterations ( unsigned int maxIterations ) { maxIterations_ = maxIterations; }
141
142
144 double averageCommTime() const
145 {
146 return averageCommTime_;
147 }
148
149 protected:
151 unsigned int maxIterations_;
153 const bool verbose_;
154 mutable double averageCommTime_;
155 mutable unsigned int realCount_;
156 };
157
158
159 namespace Solver
160 {
161 // CGInverseOperator
162 // -----------------
163
169 template< class DiscreteFunction >
171 : public Fem::Operator< DiscreteFunction, DiscreteFunction >
172 {
175
176 public:
179
182
185
186 // non-const version
187 using BaseType::finalize;
188
189 private:
191
192 public:
201 unsigned int maxIter, bool verbose,
203 : solver_( absLimit, maxIter, verbose, parameter ),
205 {}
206
208 : solver_( param.tolerance(),
209 param.maxIterations(),
210 param.errorMeasure(),
211 param.verbose() ),
212 parameter_( param )
213 {
214 }
215
216
224 unsigned int maxIter,
226 : solver_( absLimit, maxIter, parameter ),
228 {}
229
232 : CGInverseOperator( redEps, absLimit, std::numeric_limits< unsigned int >::max(), parameter )
233 {}
234
244 RealType redEps, RealType absLimit,
245 unsigned int maxIter, bool verbose,
247 : CGInverseOperator( redEps, absLimit, maxIter, verbose, parameter )
248 {
249 bind( op );
250 }
251
252
261 RealType redEps, RealType absLimit,
262 unsigned int maxIter,
264 : CGInverseOperator( redEps, absLimit, maxIter, parameter )
265 {
266 bind( op );
267 }
268
270 RealType redEps, RealType absLimit,
272 : CGInverseOperator( redEps, absLimit, parameter )
273 {
274 bind( op );
275 }
276
287 const PreconditionerType &precond,
288 RealType redEps, RealType absLimit,
289 unsigned int maxIter, bool verbose,
291 : CGInverseOperator( redEps, absLimit, maxIter, verbose )
292 {
293 bind( op, precond );
294 }
295
305 const PreconditionerType &precond,
306 RealType redEps, RealType absLimit,
308 : CGInverseOperator( redEps, absLimit, parameter )
309 {
310 bind( op, precond );
311 }
312
314 const PreconditionerType &precond,
315 RealType redEps, RealType absLimit,
316 unsigned int maxIter,
318 : CGInverseOperator( redEps, absLimit, maxIter, parameter )
319 {
320 bind( op, precond );
321 }
322
323 void bind ( const OperatorType &op ) { operator_ = &op; preconditioner_ = nullptr; }
324 void bind ( const OperatorType &op, const PreconditionerType &precond )
325 {
326 operator_ = &op;
327 preconditioner_ = &precond;
328 }
329 void unbind () { operator_ = nullptr; preconditioner_ = nullptr; }
330
339 virtual void operator()( const DomainFunctionType &arg, RangeFunctionType &dest ) const
340 {
341 prepare();
342 apply(arg,dest);
343 const_cast< ThisType& > (*this).finalize();
344 }
345
346 template<typename... A>
347 inline void prepare(A... ) const
348 {}
349
358 virtual void apply( const DomainFunctionType &arg, RangeFunctionType &dest ) const
359 {
360 assert(operator_);
362 solver_.solve( *operator_, *preconditioner_, arg, dest );
363 else
364 solver_.solve( *operator_, arg, dest );
365 }
366
368 unsigned int iterations () const
369 {
370 return solver_.iterations();
371 }
372
373 void setMaxIterations ( unsigned int maxIter ) { solver_.setMaxIterations( maxIter ); }
374
376 double averageCommTime() const
377 {
378 return solver_.averageCommTime();
379 }
380
382 {
383 return parameter_;
384 }
385
386 protected:
387 const OperatorType *operator_ = nullptr;
391 };
392 }
393
394 // CGInverseOperator
395 // -----------------
396
404 template< class DiscreteFunction,
407 : public Fem::Solver::CGInverseOperator< DiscreteFunction >
408 {
410
411 public:
412 using BaseType::bind;
413
417
419
421 typedef Op OperatorType;
422
423 typedef typename OperatorType::RangeFieldType RangeFieldType;
425
426 // Preconditioner is to approximate op^-1 !
428
432
433
442 unsigned int maxIter, bool verbose,
444 : BaseType( redEps, absLimit, maxIter, verbose, parameter )
445 {}
446
454 unsigned int maxIter,
456 : BaseType( redEps, absLimit, maxIter, parameter )
457 {}
458
461 : BaseType( redEps, absLimit, parameter )
462 {}
463
472 template< class LinearOperator, std::enable_if_t< std::is_base_of< OperatorType, LinearOperator >::value, int > = 0 >
474 RealType redEps, RealType absLimit,
475 unsigned int maxIter, bool verbose,
477 : BaseType( redEps, absLimit, maxIter, verbose, parameter )
478 {
479 bind( op );
480 }
481
489 template< class LinearOperator, std::enable_if_t< std::is_base_of< OperatorType, LinearOperator >::value, int > = 0 >
491 RealType redEps, RealType absLimit,
492 unsigned int maxIter,
494 : BaseType( redEps, absLimit, maxIter, parameter )
495 {
496 bind( op );
497 }
498
499 template< class LinearOperator, std::enable_if_t< std::is_base_of< OperatorType, LinearOperator >::value, int > = 0 >
501 RealType redEps, RealType absLimit,
503 : BaseType( redEps, absLimit, parameter )
504 {
505 bind( op );
506 }
507
517 const PreconditioningType &precond,
518 RealType redEps, RealType absLimit,
519 unsigned int maxIter, bool verbose,
521 : BaseType( op, precond, redEps, absLimit, maxIter, verbose, parameter )
522 {}
523
533 const PreconditioningType &precond,
534 RealType redEps, RealType absLimit,
535 unsigned int maxIter,
537 : BaseType( op, precond, redEps, absLimit, maxIter, parameter )
538 {}
539
541 const PreconditioningType &precond,
542 RealType redEps, RealType absLimit,
544 : BaseType( op, precond, redEps, absLimit, parameter )
545 {}
546
547
548 template< class LinearOperator, std::enable_if_t< std::is_base_of< OperatorType, LinearOperator >::value, int > = 0 >
549 void bind ( const LinearOperator &op )
550 {
551 BaseType::bind( op );
553 }
554
555 void unbind ()
556 {
558 precondObj_.reset();
559 }
560
561 protected:
562 template< class LinearOperator >
563 void checkPreconditioning( const LinearOperator &linearOp )
564 {
565 bool preconditioning = false;
566 if (!parameter_.parameter().exists(parameter_.keyPrefix()+"preconditioning.method") &&
567 parameter_.parameter().exists("fem.preconditioning"))
568 {
569 preconditioning = parameter_.parameter().template getValue< bool >( "fem.preconditioning", false );
570 std::cout << "WARNING: using deprecated parameter `fem.preconditioning` use "
571 << parameter_.keyPrefix() << "preconditioning.method instead\n";
572 }
573 else
574 preconditioning = parameter_.preconditionMethod(
575 {
576 SolverParameter::none, // no preconditioning
577 SolverParameter::jacobi // Jacobi preconditioning
578 });
580 {
581 // create diagonal preconditioner
584 }
585 }
586
590 };
591
592 // Implementation of ConjugateGradientSolver
593 // -----------------------------------------
594
595 template< class Operator >
598 {
599
600 RealType tolerance = (epsilon_ * epsilon_);
601 if (errorMeasure_ == 1)
602 tolerance *= b.normSquaredDofs( );
603
604 averageCommTime_ = 0.0;
605
606 RangeFunctionType h( b );
607 op( x, h );
608
609 RangeFunctionType r( h );
610 r -= b;
611
612 RangeFunctionType p( b );
613 p -= h;
614
615 RealType prevResiduum = 0;
616 RealType residuum = r.normSquaredDofs( );
617
618 for( realCount_ = 0; (residuum > tolerance) && (realCount_ < maxIterations_); ++realCount_ )
619 {
620 if( realCount_ > 0 )
621 {
622 assert( residuum/prevResiduum == residuum/prevResiduum );
623 p *= (residuum / prevResiduum);
624 p -= r;
625 }
626
627 op( p, h );
628
629 RangeFieldType pdoth = p.scalarProductDofs( h );
630 const RangeFieldType alpha = residuum / pdoth;
631 assert( alpha == alpha );
632 x.axpy( alpha, p );
633 r.axpy( alpha, h );
634
635 prevResiduum = residuum;
636 residuum = r.normSquaredDofs( );
637
638 double exchangeTime = h.space().communicator().exchangeTime();
639 if( verbose_ )
640 {
641 std::cout << "CG-Iteration: " << realCount_ << ", Residuum: " << std::sqrt(residuum)
642 << ", Tolerance: " << std::sqrt(tolerance) << std::endl;
643 // only for parallel apps
644 if( b.space().gridPart().comm().size() > 1 )
645 std::cout << "Communication needed: " << exchangeTime << " s" << std::endl;
646 }
647
648 averageCommTime_ += exchangeTime;
649 }
650 }
651
652
653 template< class Operator >
655 ::solve ( const OperatorType &op, const PreconditionerType &precond, const RangeFunctionType &b, DomainFunctionType &x ) const
656 {
657 RealType tolerance = (epsilon_ * epsilon_);
658 if (errorMeasure_ == 1)
659 tolerance *= b.normSquaredDofs( );
660
661 averageCommTime_ = 0.0;
662
663 RangeFunctionType h( b );
664 //h=Ax
665 op( x, h );
666
667 //r=Ax-b
668 RangeFunctionType r( h );
669 r -= b;
670
671 //p=b-A*x <= r_0 Deufelhard
672 RangeFunctionType p( b );
673 p -= h;
674
675 //q=B*p <=q Deuf
676 RangeFunctionType q ( b );
677 precond(p,q);
678
679 RangeFunctionType s (q);
680
681 RangeFieldType prevResiduum = 0; // note that these will be real_type but require scalar product evaluation
682 RangeFieldType residuum = p.scalarProductDofs( q );//<p,Bp>
683
684 for( realCount_ = 0; (std::real(residuum) > tolerance) && (realCount_ < maxIterations_); ++realCount_ )
685 {
686 if( realCount_ > 0 )
687 {
688 assert( residuum/prevResiduum == residuum/prevResiduum );
689 const RangeFieldType beta=residuum/prevResiduum;
690 q*=beta;
691 q+=(s);
692 }
693
694 op( q, h );
695
696 RangeFieldType qdoth = q.scalarProductDofs( h );
697 const RangeFieldType alpha = residuum / qdoth;//<p,Bp>/<q,Aq>
698 assert( alpha == alpha );
699 x.axpy( alpha, q );
700
701 p.axpy( -alpha, h );//r_k
702
703 precond(p,s); //B*r_k
704
705 prevResiduum = residuum;//<rk-1,B*rk-1>
706
707 residuum = p.scalarProductDofs( s );//<rk,B*rk>
708
709 double exchangeTime = h.space().communicator().exchangeTime();
710 if( verbose_ )
711 {
712 std::cout << "CG-Iteration: " << realCount_ << ", Residuum: " << std::sqrt(residuum)
713 << ", Tolerance: " << std::sqrt(tolerance) << std::endl;
714 // only for parallel apps
715 if( b.space().gridPart().comm().size() > 1 )
716 std::cout << "Communication needed: " << exchangeTime << " s" << std::endl;
717 }
718
719 averageCommTime_ += exchangeTime;
720 }
721 }
722
723 } // namespace Fem
724
725} // namespace Dune
726
727#endif // #ifndef DUNE_FEM_CGINVERSEOPERATOR_HH
double alpha() const
double beta() const
STL namespace.
double real(const complex< Dune::Fem::Double > &x)
Definition double.hh:983
static double max(const Double &v, const double p)
Definition double.hh:398
Container for User Specified Parameters.
Definition io/parameter.hh:191
static ParameterContainer & container()
Definition io/parameter.hh:199
bool exists(const std::string &key) const
check, whether a parameter is defined
Definition reader.hh:46
abstract operator
Definition operator.hh:34
virtual void finalize()
finalization of operator
Definition operator.hh:61
DomainFunction DomainFunctionType
type of discrete function in the operator's domain
Definition operator.hh:36
RangeFunction::RangeFieldType RangeFieldType
field type of the operator's range
Definition operator.hh:43
DomainFunction::RangeFieldType DomainFieldType
field type of the operator's domain
Definition operator.hh:41
RangeFunction RangeFunctionType
type of discrete function in the operator's range
Definition operator.hh:38
abstract affine-linear operator
Definition operator.hh:90
abstract matrix operator
Definition operator.hh:133
linear solver using the CG algorithm
Definition cginverseoperator.hh:31
ConjugateGradientSolver(const RealType &epsilon, unsigned int maxIterations, bool verbose, const ParameterReader &parameter=Parameter::container())
Definition cginverseoperator.hh:76
OperatorType::RangeFunctionType RangeFunctionType
type of the operator's range vectors
Definition cginverseoperator.hh:47
ConjugateGradientSolver(RealType epsilon, unsigned int maxIterations, const ParameterReader &parameter=Parameter::container())
constructor
Definition cginverseoperator.hh:93
unsigned int iterations() const
number of iterations needed for last solve
Definition cginverseoperator.hh:135
void solve(const OperatorType &op, const RangeFunctionType &b, DomainFunctionType &x) const
solve
Definition cginverseoperator.hh:597
Dune::FieldTraits< RangeFieldType >::real_type RealType
Definition cginverseoperator.hh:42
double averageCommTime() const
return average communication time during last solve
Definition cginverseoperator.hh:144
void setMaxIterations(unsigned int maxIterations)
Definition cginverseoperator.hh:140
void solve(const OperatorType &op, const PreconditionerType &p, const RangeFunctionType &b, DomainFunctionType &x) const
solve
Definition cginverseoperator.hh:655
Fem::Operator< RangeFunctionType, DomainFunctionType > PreconditionerType
type of the preconditioner, maps from the range of the operator (the dual space) in it's domain
Definition cginverseoperator.hh:50
const bool verbose_
Definition cginverseoperator.hh:153
OperatorType::RangeFieldType RangeFieldType
field type of the operator's range vectors
Definition cginverseoperator.hh:41
OperatorType::DomainFieldType DomainFieldType
field type of the operator's domain vectors
Definition cginverseoperator.hh:39
double averageCommTime_
Definition cginverseoperator.hh:154
OperatorType::DomainFunctionType DomainFunctionType
type of the operator's domain vectors
Definition cginverseoperator.hh:45
const RealType epsilon_
Definition cginverseoperator.hh:150
Operator OperatorType
type of the operators to invert
Definition cginverseoperator.hh:36
ConjugateGradientSolver(const RealType &epsilon, unsigned int maxIterations, int errorMeasure, bool verbose)
constructor
Definition cginverseoperator.hh:65
unsigned int realCount_
Definition cginverseoperator.hh:155
int errorMeasure_
Definition cginverseoperator.hh:152
unsigned int maxIterations_
Definition cginverseoperator.hh:151
Inverse operator base on CG method. This is the base class for the cg solver and does not imvolve any...
Definition cginverseoperator.hh:172
CGInverseOperator(const OperatorType &op, RealType redEps, RealType absLimit, unsigned int maxIter, const ParameterReader &parameter=Parameter::container())
constructor of CGInverseOperator
Definition cginverseoperator.hh:260
const PreconditionerType * preconditioner_
Definition cginverseoperator.hh:388
void prepare(A...) const
Definition cginverseoperator.hh:347
void unbind()
Definition cginverseoperator.hh:329
CGInverseOperator(RealType redEps, RealType absLimit, unsigned int maxIter, bool verbose, const ParameterReader &parameter=Parameter::container())
constructor of CGInverseOperator
Definition cginverseoperator.hh:200
virtual void operator()(const DomainFunctionType &arg, RangeFunctionType &dest) const
application operator
Definition cginverseoperator.hh:339
const OperatorType * operator_
Definition cginverseoperator.hh:387
CGInverseOperator(const OperatorType &op, const PreconditionerType &precond, RealType redEps, RealType absLimit, const ParameterReader &parameter=Parameter::container())
constructor of CGInverseOperator
Definition cginverseoperator.hh:304
Dune::FieldTraits< RangeFieldType >::real_type RealType
Definition cginverseoperator.hh:184
CGInverseOperator(const OperatorType &op, RealType redEps, RealType absLimit, const ParameterReader &parameter=Parameter::container())
Definition cginverseoperator.hh:269
CGInverseOperator(RealType redEps, RealType absLimit, unsigned int maxIter, const ParameterReader &parameter=Parameter::container())
constructor of CGInverseOperator
Definition cginverseoperator.hh:223
Fem::Operator< DomainFunctionType, RangeFunctionType > OperatorType
Definition cginverseoperator.hh:180
unsigned int iterations() const
number of iterations needed for last solve
Definition cginverseoperator.hh:368
SolverParameter parameter_
Definition cginverseoperator.hh:390
virtual void apply(const DomainFunctionType &arg, RangeFunctionType &dest) const
application operator
Definition cginverseoperator.hh:358
void bind(const OperatorType &op, const PreconditionerType &precond)
Definition cginverseoperator.hh:324
CGInverseOperator(const OperatorType &op, const PreconditionerType &precond, RealType redEps, RealType absLimit, unsigned int maxIter, const ParameterReader &parameter=Parameter::container())
Definition cginverseoperator.hh:313
CGInverseOperator(RealType redEps, RealType absLimit, const ParameterReader &parameter=Parameter::container())
Definition cginverseoperator.hh:230
OperatorType::RangeFieldType RangeFieldType
Definition cginverseoperator.hh:183
BaseType::DomainFunctionType DomainFunctionType
Definition cginverseoperator.hh:177
CGInverseOperator(const OperatorType &op, const PreconditionerType &precond, RealType redEps, RealType absLimit, unsigned int maxIter, bool verbose, const ParameterReader &parameter=Parameter::container())
constructor of CGInverseOperator
Definition cginverseoperator.hh:286
double averageCommTime() const
return average communication time during last solve
Definition cginverseoperator.hh:376
SolverParameter & parameter() const
Definition cginverseoperator.hh:381
Fem::Operator< RangeFunctionType, DomainFunctionType > PreconditionerType
Definition cginverseoperator.hh:181
BaseType::RangeFunctionType RangeFunctionType
Definition cginverseoperator.hh:178
CGInverseOperator(const SolverParameter &param=SolverParameter(Parameter::container()))
Definition cginverseoperator.hh:207
SolverType solver_
Definition cginverseoperator.hh:389
void setMaxIterations(unsigned int maxIter)
Definition cginverseoperator.hh:373
void bind(const OperatorType &op)
Definition cginverseoperator.hh:323
CGInverseOperator(const OperatorType &op, RealType redEps, RealType absLimit, unsigned int maxIter, bool verbose, const ParameterReader &parameter=Parameter::container())
constructor of CGInverseOperator
Definition cginverseoperator.hh:243
Inverse operator base on CG method. Uses a runtime parameter fem.preconditioning which enables diagon...
Definition cginverseoperator.hh:408
CGInverseOperator(RealType redEps, RealType absLimit, unsigned int maxIter, bool verbose, const ParameterReader &parameter=Parameter::container())
constructor of CGInverseOperator
Definition cginverseoperator.hh:441
const PreconditionerType * preconditioner_
Definition cginverseoperator.hh:388
CGInverseOperator(const OperatorType &op, const PreconditioningType &precond, RealType redEps, RealType absLimit, const ParameterReader &parameter=Parameter::container())
Definition cginverseoperator.hh:540
Op OperatorType
type of operator
Definition cginverseoperator.hh:421
CGInverseOperator(RealType redEps, RealType absLimit, const ParameterReader &parameter=Parameter::container())
Definition cginverseoperator.hh:459
CGInverseOperator(const LinearOperator &op, RealType redEps, RealType absLimit, unsigned int maxIter, const ParameterReader &parameter=Parameter::container())
constructor of CGInverseOperator
Definition cginverseoperator.hh:490
SolverParameter SolverParameterType
Definition cginverseoperator.hh:414
void bind(const LinearOperator &op)
Definition cginverseoperator.hh:549
CGInverseOperator(RealType redEps, RealType absLimit, unsigned int maxIter, const ParameterReader &parameter=Parameter::container())
constructor of CGInverseOperator
Definition cginverseoperator.hh:453
CGInverseOperator(const LinearOperator &op, RealType redEps, RealType absLimit, const ParameterReader &parameter=Parameter::container())
Definition cginverseoperator.hh:500
SolverParameter parameter_
Definition cginverseoperator.hh:390
Dune::FieldTraits< RangeFieldType >::real_type RealType
Definition cginverseoperator.hh:424
OperatorType::RangeFieldType RangeFieldType
Definition cginverseoperator.hh:423
CGInverseOperator(const OperatorType &op, const PreconditioningType &precond, RealType redEps, RealType absLimit, unsigned int maxIter, bool verbose, const ParameterReader &parameter=Parameter::container())
constructor of CGInverseOperator
Definition cginverseoperator.hh:516
Fem::Operator< RangeFunctionType, DomainFunctionType > PreconditioningType
Definition cginverseoperator.hh:427
CGInverseOperator(const LinearOperator &op, RealType redEps, RealType absLimit, unsigned int maxIter, bool verbose, const ParameterReader &parameter=Parameter::container())
constructor of CGInverseOperator
Definition cginverseoperator.hh:473
CGInverseOperator(const SolverParameter &param=SolverParameter(Parameter::container()))
Definition cginverseoperator.hh:429
BaseType::RangeFunctionType RangeFunctionType
Definition cginverseoperator.hh:416
CGInverseOperator(const OperatorType &op, const PreconditioningType &precond, RealType redEps, RealType absLimit, unsigned int maxIter, const ParameterReader &parameter=Parameter::container())
constructor of CGInverseOperator
Definition cginverseoperator.hh:532
DomainFunctionType DestinationType
Definition cginverseoperator.hh:418
void checkPreconditioning(const LinearOperator &linearOp)
Definition cginverseoperator.hh:563
BaseType::DomainFunctionType DomainFunctionType
Definition cginverseoperator.hh:415
std::unique_ptr< PreconditioningType > precondObj_
Definition cginverseoperator.hh:589
void unbind()
Definition cginverseoperator.hh:555
Precondtioner, multiplies with inverse of the diagonal works with.
Definition diagonalpreconditioner.hh:162
Definition solver/parameter.hh:25
virtual int preconditionMethod(const std::vector< int > standardMethods, const std::vector< std::string > &additionalMethods={}, int defaultMethod=0) const
Definition solver/parameter.hh:203
const ParameterReader & parameter() const
Definition solver/parameter.hh:81
const std::string & keyPrefix() const
Definition solver/parameter.hh:79
T endl(T... args)
T sqrt(T... args)