DUNE PDELab (git)

newton.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_PDELAB_SOLVER_NEWTON_HH
4#define DUNE_PDELAB_SOLVER_NEWTON_HH
5
8
9#include <dune/pdelab/constraints/common/constraints.hh>
10#include <dune/pdelab/solver/newtonerrors.hh>
11#include <dune/pdelab/solver/linesearch.hh>
12#include <dune/pdelab/solver/terminate.hh>
13#include <dune/pdelab/solver/utility.hh>
14
15namespace Dune::PDELab
16{
17 namespace Impl
18 {
19 // Some SFinae magic to execute setReuse(bool) on a backend
20 template<typename T1, typename = void>
21 struct HasSetReuse
22 : std::false_type
23 {};
24
25 template<typename T>
26 struct HasSetReuse<T, decltype(std::declval<T>().setReuse(true), void())>
27 : std::true_type
28 {};
29
30 template<typename T>
31 inline void setLinearSystemReuse(T& solver_backend, bool reuse, std::true_type)
32 {
33 if (!solver_backend.getReuse() && reuse)
34 dwarn << "WARNING: Newton needed to override your choice to reuse the linear system in order to work!" << std::endl;
35 solver_backend.setReuse(reuse);
36 }
37
38 template<typename T>
39 inline void setLinearSystemReuse(T&, bool, std::false_type)
40 {}
41
42 template<typename T>
43 inline void setLinearSystemReuse(T& solver_backend, bool reuse)
44 {
45 setLinearSystemReuse(solver_backend, reuse, HasSetReuse<T>());
46 }
47 }
48
49
62 template <typename GridOperator_, typename LinearSolver_>
64 {
65 public:
67 using GridOperator = GridOperator_;
68
70 using LinearSolver = LinearSolver_;
71
74
77
80
82 using Real = typename Dune::FieldTraits<typename Domain::ElementType>::real_type;
83
85 using Result = PDESolverResult<Real>;
86
89
92 {
93 if (not _resultValid)
94 DUNE_THROW(NewtonError, "NewtonMethod::result() called before NewtonMethod::solve()");
95 return _result;
96 }
97
98 virtual void prepareStep(Domain& solution)
99 {
100 _reassembled = false;
101 if (_result.defect/_previousDefect > _reassembleThreshold){
102 if (_hangingNodeModifications){
103 auto dirichletValues = solution;
104 // Set all non dirichlet values to zero
105 Dune::PDELab::set_shifted_dofs(_gridOperator.localAssembler().trialConstraints(), 0.0, dirichletValues);
106 // Set all constrained DOFs to zero in solution
107 Dune::PDELab::set_constrained_dofs(_gridOperator.localAssembler().trialConstraints(), 0.0, solution);
108 // Copy correct Dirichlet values back into solution vector
109 Dune::PDELab::copy_constrained_dofs(_gridOperator.localAssembler().trialConstraints(), dirichletValues, solution);
110 // Interpolate periodic constraints / hanging nodes
111 _gridOperator.localAssembler().backtransform(solution);
112 }
113 if constexpr (!linearSolverIsMatrixFree<LinearSolver>()){
114 if (_verbosity>=3)
115 std::cout << " Reassembling matrix..." << std::endl;
116 *_jacobian = Real(0.0);
117 _gridOperator.jacobian(solution, *_jacobian);
118 _reassembled = true;
119 }
120 }
121
122 _linearReduction = _minLinearReduction;
123 // corner case: ForceIteration==true. Use _minLinearReduction when initial defect is less than AbsoluteLimit.
124 if (not _fixedLinearReduction && !(_result.iterations==0 && _result.first_defect<_absoluteLimit)){
125 // Determine maximum defect, where Newton is converged.
126 using std::min;
127 using std::max;
128 auto stop_defect = max(_result.first_defect*_reduction, _absoluteLimit);
129
130 // To achieve second order convergence of newton we need a linear
131 // reduction of at least current_defect^2/prev_defect^2. For the
132 // last newton step a linear reduction of
133 // 1/10*end_defect/current_defect is sufficient for convergence.
134 _linearReduction =
135 max( stop_defect/(10*_result.defect),
136 min(_minLinearReduction, _result.defect*_result.defect/(_previousDefect*_previousDefect)) );
137 }
138
139 if (_verbosity >= 3)
140 std::cout << " requested linear reduction: "
141 << std::setw(12) << std::setprecision(4) << std::scientific
142 << _linearReduction << std::endl;
143 }
144
145 virtual void linearSolve()
146 {
147 if (_verbosity >= 4)
148 std::cout << " Solving linear system..." << std::endl;
149
150 if constexpr (!linearSolverIsMatrixFree<LinearSolver>()){
151 // If the jacobian was not reassembled we might save some work in the solver backend
152 Impl::setLinearSystemReuse(_linearSolver, not _reassembled);
153 }
154
155 // Solve the linear system
156 _correction = 0.0;
157 if constexpr (linearSolverIsMatrixFree<LinearSolver>()){
158 _linearSolver.apply(_correction, _residual, _linearReduction);
159 }
160 else{
161 _linearSolver.apply(*_jacobian, _correction, _residual, _linearReduction);
162 }
163
164 if (not _linearSolver.result().converged)
165 DUNE_THROW(NewtonLinearSolverError,
166 "NewtonMethod::linearSolve(): Linear solver did not converge "
167 "in " << _linearSolver.result().iterations << " iterations");
168 if (_verbosity >= 4)
169 std::cout << " linear solver iterations: "
170 << std::setw(12) << _linearSolver.result().iterations << std::endl
171 << " linear defect reduction: "
172 << std::setw(12) << std::setprecision(4) << std::scientific
173 << _linearSolver.result().reduction << std::endl;
174 }
175
177 virtual void apply(Domain& solution)
178 {
179 // Reset solver statistics
180 _result.clear();
181 _resultValid = true;
182
183 // Store old ios flags (will be reset when this goes out of scope)
184 ios_base_all_saver restorer(std::cout);
185
186 // Prepare time measuring
187 using Clock = std::chrono::steady_clock;
188 using Duration = Clock::duration;
189 auto assembler_time = Duration::zero();
190 auto linear_solver_time = Duration::zero();
191 auto line_search_time = Duration::zero();
192 auto to_seconds =
193 [](Duration duration){
194 return std::chrono::duration<double>(duration).count();
195 };
196 auto start_solve = Clock::now();
197
198 //=========================
199 // Calculate initial defect
200 //=========================
201 updateDefect(solution);
202 _result.first_defect = _result.defect;
203 _previousDefect = _result.defect;
204
205 if (_verbosity >= 2)
206 std::cout << " Initial defect: "
207 << std::setw(12) << std::setprecision(4) << std::scientific
208 << _result.defect << std::endl;
209
210 //==========================
211 // Calculate Jacobian matrix
212 //==========================
213 if constexpr (!linearSolverIsMatrixFree<LinearSolver>()){
214 if (not _jacobian)
215 _jacobian = std::make_shared<Jacobian>(_gridOperator);
216 }
217
218 //=========================
219 // Nonlinear iteration loop
220 //=========================
221 while (not _terminate->terminate()){
222 if(_verbosity >= 3)
223 std::cout << " Newton iteration " << _result.iterations
224 << " --------------------------------" << std::endl;
225
226 //=============
227 // Prepare step
228 //=============
229 auto start = Clock::now();
230 try{
231 prepareStep(solution);
232 }
233 catch (...)
234 {
235 // Keep track of statistics when the method fails. We record
236 // independently the time spent in non-converging attempts.
237 // Check OneStepMethod to see how these data are propagated.
238 auto end = Clock::now();
239 assembler_time += end-start;
240 _result.assembler_time = to_seconds(assembler_time);
241 throw;
242 }
243 auto end = Clock::now();
244 assembler_time += end -start;
245 _result.assembler_time = to_seconds(assembler_time);
246
247 // Store defect
248 _previousDefect = _result.defect;
249
250 //====================
251 // Solve linear system
252 //====================
253 start = Clock::now();
254
255 // Important: In the matrix-free case we need to set the current linearization point!
256 if constexpr (linearSolverIsMatrixFree<LinearSolver>()){
257 _linearSolver.setLinearizationPoint(solution);
258 }
259 try{
260 linearSolve();
261 }
262 catch (...)
263 {
264 // Separately catch statistics for linear solver failures.
265 end = Clock::now();
266 linear_solver_time += end-start;
267 _result.linear_solver_time = to_seconds(linear_solver_time);
268 _result.linear_solver_iterations += _linearSolver.result().iterations;
269 throw;
270 }
271 end = Clock::now();
272 linear_solver_time += end -start;
273 _result.linear_solver_time = to_seconds(linear_solver_time);
274 _result.linear_solver_iterations += _linearSolver.result().iterations;
275
276 //===================================
277 // Do line search and update solution
278 //===================================
279 start = Clock::now();
280 _lineSearch->lineSearch(solution, _correction);
281 // lineSearch(solution);
282 end = Clock::now();
283 line_search_time += end -start;
284
285 //========================================
286 // Store statistics and create some output
287 //========================================
288 _result.reduction = _result.defect/_result.first_defect;
289 _result.iterations++;
290 _result.conv_rate = std::pow(_result.reduction, 1.0/_result.iterations);
291
292 if (_verbosity >= 3)
293 std::cout << " linear solver time: "
294 << std::setw(12) << std::setprecision(4) << std::scientific
295 << to_seconds(linear_solver_time) << std::endl
296 << " defect reduction (this iteration):"
297 << std::setw(12) << std::setprecision(4) << std::scientific
298 << _result.defect/_previousDefect << std::endl
299 << " defect reduction (total): "
300 << std::setw(12) << std::setprecision(4) << std::scientific
301 << _result.reduction << std::endl
302 << " new defect: "
303 << std::setw(12) << std::setprecision(4) << std::scientific
304 << _result.defect << std::endl;
305 if (_verbosity == 2)
306 std::cout << " Newton iteration "
307 << std::setw(2)
308 << _result.iterations
309 << ". New defect: "
310 << std::setw(12) << std::setprecision(4) << std::scientific
311 << _result.defect
312 << ". Reduction (this): "
313 << std::setw(12) << std::setprecision(4) << std::scientific
314 << _result.defect/_previousDefect
315 << ". Reduction (total): "
316 << std::setw(12) << std::setprecision(4) << std::scientific
317 << _result.reduction
318 << std::endl;
319 } // end while loop of nonlinear iterations
320
321 auto end_solve = Clock::now();
322 auto solve_time = end_solve - start_solve;
323 _result.elapsed = to_seconds(solve_time);
324
325 if (_verbosity == 1)
326 std::cout << " Newton converged after "
327 << std::setw(2)
328 << _result.iterations
329 << " iterations. Reduction: "
330 << std::setw(12) << std::setprecision(4) << std::scientific
331 << _result.reduction
332 << " (" << std::setprecision(4) << _result.elapsed << "s)"
333 << std::endl;
334
335 if constexpr (!linearSolverIsMatrixFree<LinearSolver>()){
336 if (not _keepMatrix)
337 _jacobian.reset();
338 }
339 }
340
342 virtual void updateDefect(Domain& solution)
343 {
344 if (_hangingNodeModifications){
345 auto dirichletValues = solution;
346 // Set all non dirichlet values to zero
347 Dune::PDELab::set_shifted_dofs(_gridOperator.localAssembler().trialConstraints(), 0.0, dirichletValues);
348 // Set all constrained DOFs to zero in solution
349 Dune::PDELab::set_constrained_dofs(_gridOperator.localAssembler().trialConstraints(), 0.0, solution);
350 // Copy correct Dirichlet values back into solution vector
351 Dune::PDELab::copy_constrained_dofs(_gridOperator.localAssembler().trialConstraints(), dirichletValues, solution);
352 // Interpolate periodic constraints / hanging nodes
353 _gridOperator.localAssembler().backtransform(solution);
354 }
355
356 _residual = 0.0;
357 _gridOperator.residual(solution, _residual);
358
359 // Use the maximum norm as a stopping criterion. This helps loosen the tolerance
360 // when solving for stationary solutions of nonlinear time-dependent problems.
361 // The default is to use the Euclidean norm (in the else-block) as before
362 if (_useMaxNorm){
363 auto rankMax = Backend::native(_residual).infinity_norm();
364 _result.defect = _gridOperator.testGridFunctionSpace().gridView().comm().max(rankMax);
365 }
366 else
367 _result.defect = _linearSolver.norm(_residual);
368 }
369
371 void setVerbosityLevel(unsigned int verbosity)
372 {
373 if (_gridOperator.trialGridFunctionSpace().gridView().comm().rank()>0)
374 _verbosity = 0;
375 else
376 _verbosity = verbosity;
377 }
378
380 unsigned int getVerbosityLevel() const
381 {
382 return _verbosity;
383 }
384
386 void setReduction(Real reduction)
387 {
388 _reduction = reduction;
389 }
390
393 {
394 return _reduction;
395 }
396
398 void setAbsoluteLimit(Real absoluteLimit)
399 {
400 _absoluteLimit = absoluteLimit;
401 }
402
403 Real getAbsoluteLimit() const
404 {
405 return _absoluteLimit;
406 }
407
409 void setKeepMatrix(bool b)
410 {
411 _keepMatrix = b;
412 }
413
415 void setUseMaxNorm(bool b)
416 {
417 _useMaxNorm = b;
418 }
419
422 {
423 _hangingNodeModifications = b;
424 }
425
426
428 bool keepMatrix() const
429 {
430 return _keepMatrix;
431 }
432
435 {
436 if(_jacobian)
437 _jacobian.reset();
438 }
439
447 void setMinLinearReduction(Real minLinearReduction)
448 {
449 _minLinearReduction = minLinearReduction;
450 }
451
457 void setFixedLinearReduction(bool fixedLinearReduction)
458 {
459 _fixedLinearReduction = fixedLinearReduction;
460 }
461
468 void setReassembleThreshold(Real reassembleThreshold)
469 {
470 _reassembleThreshold = reassembleThreshold;
471 }
472
502 void setParameters(const ParameterTree& parameterTree){
503 _verbosity = parameterTree.get("VerbosityLevel", _verbosity);
504 _reduction = parameterTree.get("Reduction", _reduction);
505 _absoluteLimit = parameterTree.get("AbsoluteLimit", _absoluteLimit);
506 _keepMatrix = parameterTree.get("KeepMatrix", _keepMatrix);
507 _useMaxNorm = parameterTree.get("UseMaxNorm", _useMaxNorm);
508 _hangingNodeModifications = parameterTree.get("HangingNodeModifications", _hangingNodeModifications);
509 _minLinearReduction = parameterTree.get("MinLinearReduction", _minLinearReduction);
510 _fixedLinearReduction = parameterTree.get("FixedLinearReduction", _fixedLinearReduction);
511 _reassembleThreshold = parameterTree.get("ReassembleThreshold", _reassembleThreshold);
512
513 // first create the linesearch, depending on the parameter
514 std::string lineSearchStrategy = parameterTree.get("LineSearchStrategy","hackbuschReusken");
515 auto strategy = lineSearchStrategyFromString(lineSearchStrategy);
516 _lineSearch = createLineSearch(*this, strategy);
517
518 // now set parameters
519 if (parameterTree.hasSub("Terminate")){
520 _terminate->setParameters(parameterTree.sub("Terminate"));
521 }
522 else{
523 ParameterTree terminateTree;
524 terminateTree["MaxIterations"] = std::to_string(parameterTree.get("MaxIterations", 40));
525 terminateTree["ForceIteration"] = std::to_string(parameterTree.get("ForceIteration", false));
526 _terminate->setParameters(terminateTree);
527 }
528 if (parameterTree.hasSub("LineSearch")){
529 _lineSearch->setParameters(parameterTree.sub("LineSearch"));
530 }
531 else{
532 ParameterTree lineSearchTree;
533 lineSearchTree["MaxIterations"] = std::to_string(parameterTree.get("LineSearchMaxIterations", 10));
534 lineSearchTree["DampingFactor"] = std::to_string(parameterTree.get("LineSearchDampingFactor", 0.5));
535 lineSearchTree["AcceptBest"] = std::to_string(parameterTree.get("LineSearchAcceptBest", false));
536 _lineSearch->setParameters(lineSearchTree);
537 }
538 }
539
541 void setTerminate(std::shared_ptr<TerminateInterface> terminate)
542 {
543 _terminate = terminate;
544 }
545
547 std::shared_ptr<TerminateInterface> getTerminate() const
548 {
549 return _terminate;
550 }
551
556 void setLineSearch(std::shared_ptr<LineSearch> lineSearch)
557 {
558 _lineSearch = lineSearch;
559 }
560
562 std::shared_ptr<LineSearch> getLineSearch() const
563 {
564 return _lineSearch;
565 }
566
572 void printParameters(const std::string& _name = "NewtonMethod") const
573 {
574 // Change boolalpha flag to output true/false in full, not 0/1.
575 // Restoring to previous setting is guaranteed.
576 auto ioflags = std::cout.flags();
577 std::cout.setf(std::ios_base::boolalpha);
578 std::cout << _name << " parameters:\n";
579 std::cout << "Verbosity............... " << _verbosity << std::endl;
580 std::cout << "Reduction............... " << _reduction << std::endl;
581 std::cout << "AbsoluteLimit........... " << _absoluteLimit << std::endl;
582 std::cout << "KeepMatrix.............. " << _keepMatrix << std::endl;
583 std::cout << "UseMaxNorm.............. " << _useMaxNorm << std::endl;
584 std::cout << "MinLinearReduction...... " << _minLinearReduction << std::endl;
585 std::cout << "FixedLinearReduction.... " << _fixedLinearReduction << std::endl;
586 std::cout << "ReassembleThreshold..... " << _reassembleThreshold << std::endl;
587 std::cout << "HangingNodeModifications " << _hangingNodeModifications << std::endl;
588 try
589 {
590 _terminate->printParameters();
591 _lineSearch->printParameters();
592 }
593 catch (...)
594 {
595 // guarantee restoring previous std::cout flags
596 std::cout.flags(ioflags);
597 throw;
598 }
599 std::cout.flags(ioflags);
600 }
601
603
607 const GridOperator& gridOperator,
608 LinearSolver& linearSolver)
609 : _gridOperator(gridOperator)
610 , _linearSolver(linearSolver)
611 , _residual(gridOperator.testGridFunctionSpace())
612 , _correction(gridOperator.trialGridFunctionSpace())
613 {
614 _terminate = std::make_shared<DefaultTerminate<NewtonMethod>> (*this);
615 _lineSearch = createLineSearch(*this, LineSearchStrategy::hackbuschReusken);
616 }
617
620 const GridOperator& gridOperator,
621 LinearSolver& linearSolver,
622 const ParameterTree& parameterTree)
623 : _gridOperator(gridOperator)
624 , _linearSolver(linearSolver)
625 , _residual(gridOperator.testGridFunctionSpace())
626 , _correction(gridOperator.trialGridFunctionSpace())
627
628 {
629 _terminate = std::make_shared<DefaultTerminate<NewtonMethod>> (*this);
630 setParameters(parameterTree);
631 }
632
633 virtual ~NewtonMethod() {}
634
635 private:
636 const GridOperator& _gridOperator;
637 LinearSolver& _linearSolver;
638
639 // Vectors and Jacobi matrix we set up only once
640 Range _residual;
641 Domain _correction;
642 std::shared_ptr<Jacobian> _jacobian;
643
644 std::shared_ptr<TerminateInterface> _terminate;
645 std::shared_ptr<LineSearch> _lineSearch;
646
647 // Class for storing results
648 Result _result;
649 bool _resultValid = false; // result class only valid after calling apply
650 Real _previousDefect = 0.0;
651
652 // Remember if jacobian was reassembled in prepareStep
653 bool _reassembled = true; // will be set in prepare step
654 Real _linearReduction = 0.0; // will be set in prepare step
655
656 // User parameters
657 unsigned int _verbosity = 0;
658 Real _reduction = 1e-8;
659 Real _absoluteLimit = 1e-12;
660 bool _keepMatrix = true;
661 bool _useMaxNorm = false;
662
663 // Special treatment if we have hanging nodes
664 bool _hangingNodeModifications = false;
665
666 // User parameters for prepareStep()
667 Real _minLinearReduction = 1e-3;
668 bool _fixedLinearReduction = false;
669 Real _reassembleThreshold = 0.0;
670 };
671
672} // namespace Dune::PDELab
673
674#endif
Abstract base class describing the line search interface.
Definition: linesearch.hh:15
Newton solver for solving non-linear problems.
Definition: newton.hh:64
typename GridOperator::Traits::Jacobian Jacobian
Type of the Jacobian matrix.
Definition: newton.hh:79
NewtonMethod(const GridOperator &gridOperator, LinearSolver &linearSolver, const ParameterTree &parameterTree)
Construct Newton passing a parameter tree.
Definition: newton.hh:619
void setMinLinearReduction(Real minLinearReduction)
Set the minimal reduction in the linear solver.
Definition: newton.hh:447
void setTerminate(std::shared_ptr< TerminateInterface > terminate)
Set the termination criterion.
Definition: newton.hh:541
bool keepMatrix() const
Return whether the jacobian matrix is kept across calls to apply().
Definition: newton.hh:428
unsigned int getVerbosityLevel() const
Get verbosity level.
Definition: newton.hh:380
std::shared_ptr< TerminateInterface > getTerminate() const
Return a pointer to the stored termination criterion.
Definition: newton.hh:547
typename GridOperator::Traits::Domain Domain
Type of the domain (solution)
Definition: newton.hh:73
void setParameters(const ParameterTree &parameterTree)
Interpret a parameter tree as a set of options for the newton solver.
Definition: newton.hh:502
void setHangingNodeModifications(bool b)
Does the problem have hanging nodes.
Definition: newton.hh:421
void setFixedLinearReduction(bool fixedLinearReduction)
Set wether to use a fixed reduction in the linear solver.
Definition: newton.hh:457
std::shared_ptr< LineSearch > getLineSearch() const
Return a pointer to the stored line search.
Definition: newton.hh:562
void discardMatrix()
Discard the stored Jacobian matrix.
Definition: newton.hh:434
GridOperator_ GridOperator
Type of the grid operator.
Definition: newton.hh:67
void setLineSearch(std::shared_ptr< LineSearch > lineSearch)
Set the line search.
Definition: newton.hh:556
void setReduction(Real reduction)
Set reduction Newton needs to achieve.
Definition: newton.hh:386
typename Dune::FieldTraits< typename Domain::ElementType >::real_type Real
Number type.
Definition: newton.hh:82
void setKeepMatrix(bool b)
Set whether the jacobian matrix should be kept across calls to apply().
Definition: newton.hh:409
LinearSolver_ LinearSolver
Type of the linear solver.
Definition: newton.hh:70
void setUseMaxNorm(bool b)
Set whether to use the maximum norm for stopping criteria.
Definition: newton.hh:415
typename GridOperator::Traits::Range Range
Type of the range (residual)
Definition: newton.hh:76
void setAbsoluteLimit(Real absoluteLimit)
Set absolute convergence limit.
Definition: newton.hh:398
virtual void updateDefect(Domain &solution)
Update _residual and defect in _result.
Definition: newton.hh:342
void printParameters(const std::string &_name="NewtonMethod") const
Output NewtonMethod parameters.
Definition: newton.hh:572
virtual void apply(Domain &solution)
Solve the nonlinear problem using solution as initial guess and for storing the result.
Definition: newton.hh:177
PDESolverResult< Real > Result
Type of results.
Definition: newton.hh:85
NewtonMethod(const GridOperator &gridOperator, LinearSolver &linearSolver)
Construct Newton using default parameters with default parameters.
Definition: newton.hh:606
Result & result()
Return results.
Definition: newton.hh:91
void setReassembleThreshold(Real reassembleThreshold)
Set a threshold, when the linear operator is reassembled.
Definition: newton.hh:468
void setVerbosityLevel(unsigned int verbosity)
Set how much output you get.
Definition: newton.hh:371
Real getReduction() const
Get reduction.
Definition: newton.hh:392
Hierarchical structure of string parameters.
Definition: parametertree.hh:37
std::string get(const std::string &key, const std::string &defaultValue) const
get value as string
Definition: parametertree.cc:188
ParameterTree & sub(const std::string &sub)
get substructure by name
Definition: parametertree.cc:106
bool hasSub(const std::string &sub) const
test for substructure
Definition: parametertree.cc:79
Utility class for storing and resetting stream attributes.
Definition: ios_state.hh:34
A few common exception classes.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
void set_constrained_dofs(const CG &cg, typename XG::ElementType x, XG &xg)
construct constraints from given boundary condition function
Definition: constraints.hh:796
void set_shifted_dofs(const CG &cg, typename XG::ElementType x, XG &xg)
Definition: constraints.hh:1014
void copy_constrained_dofs(const CG &cg, const XG &xgin, XG &xgout)
Definition: constraints.hh:936
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:484
constexpr auto min
Function object that returns the smaller of the given values.
Definition: hybridutilities.hh:506
DWarnType dwarn(std::cerr)
Stream for warnings indicating problems.
Definition: stdstreams.hh:162
Utility class for storing and resetting stream attributes.
STL namespace.
Dune::PDELab::Backend::Matrix< MB, Domain, Range, JF > Jacobian
The type of the jacobian.
Definition: gridoperatorutilities.hh:72
Dune::PDELab::Backend::Vector< GFSV, RF > Range
The type of the range (residual).
Definition: gridoperatorutilities.hh:65
Dune::PDELab::Backend::Vector< GFSU, DF > Domain
The type of the domain (solution).
Definition: gridoperatorutilities.hh:58
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 23, 23:29, 2024)