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 
15 namespace 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
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
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
Result & result()
Return results.
Definition: newton.hh:91
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
void setReassembleThreshold(Real reassembleThreshold)
Set a threshold, when the linear operator is reassembled.
Definition: newton.hh:468
std::shared_ptr< LineSearch > getLineSearch() const
Return a pointer to the stored line search.
Definition: newton.hh:562
std::shared_ptr< TerminateInterface > getTerminate() const
Return a pointer to the stored termination criterion.
Definition: newton.hh:547
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:185
ParameterTree & sub(const std::string &sub)
get substructure by name
Definition: parametertree.cc:103
bool hasSub(const std::string &sub) const
test for substructure
Definition: parametertree.cc:76
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:161
Utility class for storing and resetting stream attributes.
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.80.0 (May 16, 22:29, 2024)