https://mooseframework.inl.gov
NestedSolve.h
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #pragma once
11 
12 #include "MooseTypes.h"
13 #include "RankTwoTensor.h"
14 #include "InputParameters.h"
15 
16 #include "libmesh/utility.h"
17 #include "libmesh/int_range.h"
18 #include "libmesh/vector_value.h"
19 
20 #include "Eigen/Core"
21 #include <Eigen/Dense>
22 #include <unsupported/Eigen/NonLinearOptimization>
23 
24 #include "EigenADReal.h"
25 
31 {
32 template <typename T>
34 }
35 
41 template <bool is_ad>
43 {
44 public:
46 
48  NestedSolveTempl(const InputParameters & params);
49 
55 
57  using DynamicVector = Eigen::Matrix<NSReal, Eigen::Dynamic, 1>;
58  using DynamicMatrix = Eigen::Matrix<NSReal, Eigen::Dynamic, Eigen::Dynamic>;
60 
62  template <typename T>
64  template <typename T>
67 
69  template <int N = 0>
70  using Value =
71  typename std::conditional<N == 1,
72  NSReal,
73  typename std::conditional<N == 0,
75  Eigen::Matrix<NSReal, N, 1>>::type>::type;
76 
78  template <int N = 0>
79  using Jacobian =
80  typename std::conditional<N == 1,
81  NSReal,
82  typename std::conditional<N == 0,
84  Eigen::Matrix<NSReal, N, N>>::type>::type;
85 
87  template <typename V, typename T>
88  void nonlinear(V & guess, T && compute);
89 
91  template <typename V, typename T, typename C>
92  void nonlinearDamped(V & guess, T && compute, C && computeCondition);
93 
96  template <typename R, typename J>
97  void nonlinear(DynamicVector & guess, R & computeResidual, J & computeJacobian);
98  template <typename R, typename J>
99  void nonlinear(NSReal & guess, R & computeResidual, J & computeJacobian);
100  template <typename R, typename J>
101  void nonlinear(NSRealVectorValue & guess, R & computeResidual, J & computeJacobian);
103 
106  template <typename R, typename J>
107  void nonlinearTight(DynamicVector & guess, R & computeResidual, J & computeJacobian);
108  template <typename R, typename J>
109  void nonlinearTight(NSReal & guess, R & computeResidual, J & computeJacobian);
110  template <typename R, typename J>
111  void nonlinearTight(NSRealVectorValue & guess, R & computeResidual, J & computeJacobian);
113 
115  template <typename R, typename J, typename B>
116  void
117  nonlinearBounded(NSReal & guess, R & computeResidual, J & computeJacobian, B & computeBounds);
120  static Real relativeToleranceDefault() { return 1e-8; }
121  static Real absoluteToleranceDefault() { return 1e-13; }
122  static Real xToleranceDefault() { return 1e-15; }
123  static unsigned int minIterationsDefault() { return 3; }
124  static unsigned int maxIterationsDefault() { return 1000; }
125  static Real acceptableMultiplierDefault() { return 10.0; }
126  static Real dampingFactorDefault() { return 0.8; }
127  static unsigned int maxDampingIterationsDefault() { return 100; }
129 
130  void setRelativeTolerance(Real rel) { _relative_tolerance_square = rel * rel; }
133 
141 
142  unsigned int _min_iterations;
143  unsigned int _max_iterations;
145 
147  enum class State
148  {
149  NONE,
155  EXACT_GUESS,
158  };
159 
161  const State & getState() const { return _state; }
163  const std::size_t & getIterations() { return _n_iterations; };
164 
166  template <typename V>
167  static Real normSquare(const V & v);
168  static Real normSquare(const NSReal & v);
169  static Real normSquare(const NSRealVectorValue & v);
171 
173  //'b' by a factor of 'c'
174  template <typename V>
175  static bool isRelSmall(const V & a, const V & b, const V & c);
176  static bool isRelSmall(const NSReal & a, const NSReal & b, const NSReal & c);
177  static bool
178  isRelSmall(const NSRealVectorValue & a, const NSRealVectorValue & b, const NSReal & c);
179  static bool isRelSmall(const DynamicVector & a, const DynamicVector & b, const NSReal & c);
181 
182 protected:
185 
187  std::size_t _n_iterations;
188 
192  NestedSolveTempl<is_ad>::DynamicMatrix & jacobian) const;
193 
195  template <typename V, typename T>
196  void sizeItems(const V &, V &, T &) const
197  {
198  }
199 
201  template <typename J, typename V>
202  void linear(const J & A, V & x, const V & b) const;
203  void linear(const NSReal & A, NSReal & x, const NSReal & b) const { x = b / A; }
204  void linear(const NSRankTwoTensor & A, NSRealVectorValue & x, const NSRealVectorValue & b) const;
206 
208  bool isConverged(Real r0_square, Real r_square, bool acceptable);
209 
210 private:
212  template <bool store_residual_norm, typename R, typename J>
213  auto make_adaptor(R & residual, J & jacobian);
214  template <bool store_residual_norm, typename R, typename J>
215  auto make_real_adaptor(R & residual, J & jacobian);
216  template <bool store_residual_norm, typename R, typename J>
217  auto make_realvector_adaptor(R & residual, J & jacobian);
219 };
220 
221 template <bool is_ad>
222 template <typename R, typename J>
223 void
225  R & computeResidual,
226  J & computeJacobian)
227 {
228  // adaptor functor to utilize the Eigen non-linear solver
229  auto functor = make_adaptor<true>(computeResidual, computeJacobian);
230  Eigen::HybridNonLinearSolver<decltype(functor), NSReal> solver(functor);
231  auto status = solver.solve(guess);
232 
233  if (status == Eigen::HybridNonLinearSolverSpace::RelativeErrorTooSmall)
234  _state = State::CONVERGED_REL;
235  else
236  _state = State::NOT_CONVERGED;
237 }
238 
239 template <bool is_ad>
240 template <typename R, typename J>
241 void
242 NestedSolveTempl<is_ad>::nonlinear(NSReal & guess, R & computeResidual, J & computeJacobian)
243 {
245 
246  // adaptor functor to utilize the Eigen non-linear solver
247  auto functor = make_real_adaptor<true>(computeResidual, computeJacobian);
248  Eigen::HybridNonLinearSolver<decltype(functor), NSReal> solver(functor);
249  V guess_eigen(1);
250  guess_eigen << guess;
251  const auto & r_square = functor.getResidualNorm();
252  solver.solveInit(guess_eigen);
253 
254  // compute first residual norm for relative convergence checks
255  auto r0_square = r_square;
256  if (r0_square == 0)
257  {
258  _state = State::EXACT_GUESS;
259  return;
260  }
261 
262  // perform non-linear iterations
263  _n_iterations = 1;
264  while (_n_iterations <= _max_iterations &&
265  solver.solveOneStep(guess_eigen) == Eigen::HybridNonLinearSolverSpace::Running)
266  {
267  // check convergence
268  if (_n_iterations >= _min_iterations && isConverged(r0_square, r_square, /*acceptable=*/false))
269  {
270  guess = guess_eigen(0);
271  return;
272  }
273  _n_iterations++;
274  }
275 
279  if (!isConverged(r0_square, r_square, /*acceptable=*/true))
280  _state = State::NOT_CONVERGED;
281 
282  guess = guess_eigen(0);
283 }
284 
285 template <bool is_ad>
286 template <typename R, typename J>
287 void
289  R & computeResidual,
290  J & computeJacobian)
291 {
293 
294  // adaptor functor to utilize the Eigen non-linear solver
295  auto functor = make_realvector_adaptor<true>(computeResidual, computeJacobian);
296  Eigen::HybridNonLinearSolver<decltype(functor), NSReal> solver(functor);
297  V guess_eigen(3);
298  guess_eigen << guess(0), guess(1), guess(2);
299  auto status = solver.solve(guess_eigen);
300  guess(0) = guess_eigen(0);
301  guess(1) = guess_eigen(1);
302  guess(2) = guess_eigen(2);
303 
304  if (status == Eigen::HybridNonLinearSolverSpace::RelativeErrorTooSmall)
305  _state = State::CONVERGED_REL;
306  else
307  _state = State::NOT_CONVERGED;
308 }
309 
310 template <bool is_ad>
311 template <typename R, typename J>
312 void
314  R & computeResidual,
315  J & computeJacobian)
316 {
317  // adaptor functor to utilize the Eigen non-linear solver
318  auto functor = make_adaptor<false>(computeResidual, computeJacobian);
319  Eigen::HybridNonLinearSolver<decltype(functor), NSReal> solver(functor);
320  auto status = solver.solve(guess);
321 
322  if (status == Eigen::HybridNonLinearSolverSpace::RelativeErrorTooSmall)
323  _state = State::CONVERGED_REL;
324  else
325  _state = State::NOT_CONVERGED;
326 }
327 
328 template <bool is_ad>
329 template <typename R, typename J>
330 void
331 NestedSolveTempl<is_ad>::nonlinearTight(NSReal & guess, R & computeResidual, J & computeJacobian)
332 {
334 
335  // adaptor functor to utilize the Eigen non-linear solver
336  auto functor = make_real_adaptor<false>(computeResidual, computeJacobian);
337  Eigen::HybridNonLinearSolver<decltype(functor), NSReal> solver(functor);
338  V guess_eigen(1);
339  guess_eigen << guess;
340  auto status = solver.solve(guess_eigen);
341  guess = guess_eigen(0);
342 
343  if (status == Eigen::HybridNonLinearSolverSpace::RelativeErrorTooSmall)
344  _state = State::CONVERGED_REL;
345  else
346  _state = State::NOT_CONVERGED;
347 }
348 
349 template <bool is_ad>
350 template <typename R, typename J>
351 void
353  R & computeResidual,
354  J & computeJacobian)
355 {
357 
358  // adaptor functor to utilize the Eigen non-linear solver
359  auto functor = make_realvector_adaptor<false>(computeResidual, computeJacobian);
360  Eigen::HybridNonLinearSolver<decltype(functor), NSReal> solver(functor);
361  V guess_eigen(3);
362  guess_eigen << guess(0), guess(1), guess(2);
363  auto status = solver.solve(guess_eigen);
364  guess(0) = guess_eigen(0);
365  guess(1) = guess_eigen(1);
366  guess(2) = guess_eigen(2);
367 
368  if (status == Eigen::HybridNonLinearSolverSpace::RelativeErrorTooSmall)
369  _state = State::CONVERGED_REL;
370  else
371  _state = State::NOT_CONVERGED;
372 }
373 
374 template <bool is_ad>
375 template <typename R, typename J, typename B>
376 void
378  R & computeResidual,
379  J & computeJacobian,
380  B & computeBounds)
381 {
382  auto functor = make_real_adaptor<false>(computeResidual, computeJacobian);
383  Eigen::HybridNonLinearSolver<decltype(functor), NSReal> solver(functor);
384 
386  guess_eigen << guess;
387 
388  auto status = solver.solveInit(guess_eigen);
389  if (status == Eigen::HybridNonLinearSolverSpace::ImproperInputParameters)
390  return;
391 
392  bool bounds_hit = false;
393  while (status == Eigen::HybridNonLinearSolverSpace::Running)
394  {
395  status = solver.solveOneStep(guess_eigen);
396  const std::pair<Real, Real> & bounds = computeBounds();
397 
398  // Snap to bounds. Terminate solve if we snap twice consecutively.
399  if (guess_eigen(0) < bounds.first || guess_eigen(0) > bounds.second)
400  {
401  if (guess_eigen(0) < bounds.first)
402  guess_eigen(0) = bounds.first;
403  else
404  guess_eigen(0) = bounds.second;
405 
406  if (bounds_hit)
407  {
408  _state = State::CONVERGED_BOUNDS;
409  return;
410  }
411 
412  bounds_hit = true;
413  }
414  }
415 
416  if (status == Eigen::HybridNonLinearSolverSpace::RelativeErrorTooSmall)
417  _state = State::CONVERGED_REL;
418  else
419  _state = State::NOT_CONVERGED;
420 
421  guess = guess_eigen(0);
422 }
423 
424 template <bool is_ad>
425 template <typename V, typename T>
426 void
427 NestedSolveTempl<is_ad>::nonlinear(V & guess, T && compute)
428 {
429  V delta;
430  V residual;
431  CorrespondingJacobian<V> jacobian;
432  sizeItems(guess, residual, jacobian);
433 
434  _n_iterations = 0;
435  compute(guess, residual, jacobian);
436 
437  // compute first residual norm for relative convergence checks
438  auto r0_square = normSquare(residual);
439  if (r0_square == 0)
440  {
441  _state = State::EXACT_GUESS;
442  return;
443  }
444  auto r_square = r0_square;
445 
446  // perform non-linear iterations
447  while (_n_iterations < _max_iterations)
448  {
449  // check convergence
450  if (_n_iterations >= _min_iterations && isConverged(r0_square, r_square, /*acceptable=*/false))
451  return;
452 
453  // solve and apply next increment
454  linear(jacobian, delta, residual);
455 
456  // Check if step size is smaller than the floating point tolerance
457  if (isRelSmall(delta, guess, _delta_thresh))
458  {
459  _state = State::CONVERGED_XTOL;
460  return;
461  }
462 
463  guess -= delta;
464  _n_iterations++;
465 
466  // compute residual and jacobian for the next iteration
467  compute(guess, residual, jacobian);
468 
469  r_square = normSquare(residual);
470  }
471 
475  if (!isConverged(r0_square, r_square, /*acceptable=*/true))
476  _state = State::NOT_CONVERGED;
477 }
478 
479 template <bool is_ad>
480 template <typename V, typename T, typename C>
481 void
482 NestedSolveTempl<is_ad>::nonlinearDamped(V & guess, T && compute, C && computeCondition)
483 {
484  V delta;
485  V residual;
486  CorrespondingJacobian<V> jacobian;
487  sizeItems(guess, residual, jacobian);
488 
489  _n_iterations = 0;
490  compute(guess, residual, jacobian);
491 
492  // compute first residual norm for relative convergence checks
493  auto r0_square = normSquare(residual);
494  if (r0_square == 0)
495  {
496  _state = State::EXACT_GUESS;
497  return;
498  }
499  auto r_square = r0_square;
500 
501  // perform non-linear iterations
502  while (_n_iterations < _max_iterations)
503  {
504  // check convergence
505  if (_n_iterations >= _min_iterations && isConverged(r0_square, r_square, /*acceptable=*/false))
506  return;
507 
508  // solve and apply next increment
509  linear(jacobian, delta, residual);
510 
511  // Check if step size is smaller than the floating point tolerance
512  if (isRelSmall(delta, guess, _delta_thresh))
513  {
514  _state = State::CONVERGED_XTOL;
515  return;
516  }
517 
518  Real alpha = 1;
519  unsigned int damping_iterations = 0;
520  auto prev_guess = guess;
521  guess -= delta;
522 
523  while (!computeCondition(guess) && (damping_iterations < _max_damping_iterations))
524  {
525  alpha *= _damping_factor;
526  guess = prev_guess - alpha * delta;
527  damping_iterations += 1;
528  }
529  _n_iterations++;
530 
531  // compute residual and jacobian for the next iteration
532  compute(guess, residual, jacobian);
533 
534  r_square = normSquare(residual);
535  }
536 
537  // if we exceed the max iterations, we could still be converged (considering the acceptable
538  // multiplier)
539  if (!isConverged(r0_square, r_square, /*acceptable=*/true))
540  _state = State::NOT_CONVERGED;
541 }
542 
543 template <bool is_ad>
544 template <typename J, typename V>
545 void
546 NestedSolveTempl<is_ad>::linear(const J & A, V & x, const V & b) const
547 {
548  // we could make the linear solve method configurable here
549  x = A.partialPivLu().solve(b);
550 }
551 
552 template <bool is_ad>
553 template <typename V>
554 Real
556 {
557  // we currently cannot get the raw_value of an AD Eigen Matrix, so we loop over components
558  Real norm_square = 0.0;
559  for (const auto i : index_range(v))
560  norm_square += Utility::pow<2>(MetaPhysicL::raw_value(v.data()[i]));
561  return norm_square;
562 }
563 
568 namespace NestedSolveInternal
569 {
570 
571 template <>
573 {
574  using type = Real;
575 };
576 
577 template <>
579 {
580  using type = ADReal;
581 };
582 
583 template <>
585 {
587 };
588 
589 template <>
591 {
593 };
594 
595 template <>
596 struct CorrespondingJacobianTempl<typename NestedSolveTempl<false>::DynamicVector>
597 {
599 };
600 
601 template <>
602 struct CorrespondingJacobianTempl<typename NestedSolveTempl<true>::DynamicVector>
603 {
605 };
606 
607 template <int N>
608 struct CorrespondingJacobianTempl<typename Eigen::Matrix<Real, N, 1>>
609 {
610  using type = Eigen::Matrix<Real, N, N>;
611 };
612 
613 template <int N>
614 struct CorrespondingJacobianTempl<typename Eigen::Matrix<ADReal, N, 1>>
615 {
616  using type = Eigen::Matrix<ADReal, N, N>;
617 };
618 
623 template <bool is_ad, typename R, typename J, bool store_residual_norm>
625 {
627 
628 public:
629  DynamicMatrixEigenAdaptorFunctor(R & residual_lambda, J & jacobian_lambda)
630  : _residual_lambda(residual_lambda), _jacobian_lambda(jacobian_lambda)
631  {
632  }
633  int operator()(V & guess, V & residual)
634  {
635  _residual_lambda(guess, residual);
636  if constexpr (store_residual_norm)
638  return 0;
639  }
640  int df(V & guess, typename NestedSolveTempl<is_ad>::template CorrespondingJacobian<V> & jacobian)
641  {
642  _jacobian_lambda(guess, jacobian);
643  return 0;
644  }
645 
647  {
648  if constexpr (store_residual_norm)
649  return _residual_norm;
650  }
651 
652 private:
655 
657 };
658 
663 template <bool is_ad, typename R, typename J, bool store_residual_norm>
665 {
667 
668 public:
669  RealEigenAdaptorFunctor(R & residual_lambda, J & jacobian_lambda)
670  : _residual_lambda(residual_lambda), _jacobian_lambda(jacobian_lambda)
671  {
672  }
673  int operator()(V & guess, V & residual)
674  {
675  _residual_lambda(guess(0), residual(0));
676  if constexpr (store_residual_norm)
678  return 0;
679  }
680  int df(V & guess, typename NestedSolveTempl<is_ad>::template CorrespondingJacobian<V> & jacobian)
681  {
682  _jacobian_lambda(guess(0), jacobian(0, 0));
683  return 0;
684  }
685 
687  {
688  if constexpr (store_residual_norm)
689  return _residual_norm;
690  }
691 
692 private:
695 
697 };
698 
703 template <bool is_ad, typename R, typename J, bool store_residual_norm>
705 {
707 
708 public:
709  RealVectorEigenAdaptorFunctor(R & residual_lambda, J & jacobian_lambda)
710  : _residual_lambda(residual_lambda), _jacobian_lambda(jacobian_lambda)
711  {
712  }
713  int operator()(V & guess, V & residual)
714  {
715  typename NestedSolveTempl<is_ad>::NSRealVectorValue guess_moose(guess(0), guess(1), guess(2));
716  typename NestedSolveTempl<is_ad>::NSRealVectorValue residual_moose;
717  _residual_lambda(guess_moose, residual_moose);
718  residual(0) = residual_moose(0);
719  residual(1) = residual_moose(1);
720  residual(2) = residual_moose(2);
721  if constexpr (store_residual_norm)
723  return 0;
724  }
725  int df(V & guess, typename NestedSolveTempl<is_ad>::template CorrespondingJacobian<V> & jacobian)
726  {
727  typename NestedSolveTempl<is_ad>::NSRealVectorValue guess_moose(guess(0), guess(1), guess(2));
728  typename NestedSolveTempl<is_ad>::NSRankTwoTensor jacobian_moose;
729  _jacobian_lambda(guess_moose, jacobian_moose);
730  jacobian =
731  Eigen::Map<typename NestedSolveTempl<is_ad>::DynamicMatrix>(&jacobian_moose(0, 0), 3, 3);
732  return 0;
733  }
734 
736  {
737  if constexpr (store_residual_norm)
738  return _residual_norm;
739  }
740 
741 private:
744 
746 };
747 
748 } // namespace NestedSolveInternal
749 
750 template <bool is_ad>
751 template <bool store_residual_norm, typename R, typename J>
752 auto
753 NestedSolveTempl<is_ad>::make_adaptor(R & residual_lambda, J & jacobian_lambda)
754 {
756  residual_lambda, jacobian_lambda);
757 }
758 template <bool is_ad>
759 template <bool store_residual_norm, typename R, typename J>
760 auto
761 NestedSolveTempl<is_ad>::make_real_adaptor(R & residual_lambda, J & jacobian_lambda)
762 {
764  residual_lambda, jacobian_lambda);
765 }
766 
767 template <bool is_ad>
768 template <bool store_residual_norm, typename R, typename J>
769 auto
770 NestedSolveTempl<is_ad>::make_realvector_adaptor(R & residual_lambda, J & jacobian_lambda)
771 {
773  residual_lambda, jacobian_lambda);
774 }
775 
776 // lambda to check for convergence and set the state accordingly
777 template <bool is_ad>
778 bool
779 NestedSolveTempl<is_ad>::isConverged(const Real r0_square, Real r_square, bool acceptable)
780 {
781  if (acceptable)
782  r_square /= _acceptable_multiplier * _acceptable_multiplier;
783  if (r_square < _absolute_tolerance_square)
784  {
785  _state = acceptable ? State::CONVERGED_ACCEPTABLE_ABS : State::CONVERGED_ABS;
786  return true;
787  }
788  if (r_square / r0_square < _relative_tolerance_square)
789  {
790  _state = acceptable ? State::CONVERGED_ACCEPTABLE_REL : State::CONVERGED_REL;
791  return true;
792  }
793  return false;
794 }
795 
void setAcceptableMultiplier(Real am)
Definition: NestedSolve.h:132
unsigned int _min_iterations
Definition: NestedSolve.h:142
MetaPhysicL::DualNumber< V, D, asd > abs(const MetaPhysicL::DualNumber< V, D, asd > &a)
Definition: EigenADReal.h:42
NestedSolveTempl< false > NestedSolve
Definition: NestedSolve.h:796
const std::size_t & getIterations()
Get the number of iterations from the last solve.
Definition: NestedSolve.h:163
Moose::GenericType< RankTwoTensor, is_ad > NSRankTwoTensor
Definition: NestedSolve.h:53
RankTwoTensorTempl< Real > RankTwoTensor
void sizeItems(const V &, V &, T &) const
Sizing is a no-op for compile time sized types (and scalars)
Definition: NestedSolve.h:196
Real _acceptable_multiplier
Definition: NestedSolve.h:144
static unsigned int maxDampingIterationsDefault()
Definition: NestedSolve.h:127
RealEigenAdaptorFunctor(R &residual_lambda, J &jacobian_lambda)
Definition: NestedSolve.h:669
RealVectorEigenAdaptorFunctor(R &residual_lambda, J &jacobian_lambda)
Definition: NestedSolve.h:709
State
possible solver states
Definition: NestedSolve.h:147
static InputParameters validParams()
Definition: NestedSolve.C:16
typename NestedSolveTempl< is_ad >::DynamicVector V
Definition: NestedSolve.h:626
State _state
current solver state
Definition: NestedSolve.h:184
DynamicMatrixEigenAdaptorFunctor(R &residual_lambda, J &jacobian_lambda)
Definition: NestedSolve.h:629
static Real dampingFactorDefault()
Definition: NestedSolve.h:126
static bool isRelSmall(const V &a, const V &b, const V &c)
Check if |a| < |b * c| for all elements in a and b. This checks if &#39;a&#39; is small relative to...
auto raw_value(const Eigen::Map< T > &in)
Definition: EigenADReal.h:73
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
static Real xToleranceDefault()
Definition: NestedSolve.h:122
Real _delta_thresh
Threshold for minimum step size of linear iterations.
Definition: NestedSolve.h:137
DualNumber< Real, DNDerivativeType, true > ADReal
Definition: ADRealForward.h:47
Adaptor functor for Eigen::Matrix based residual and Jacobian types.
Definition: NestedSolve.h:624
Eigen::Matrix< NSReal, Eigen::Dynamic, Eigen::Dynamic > DynamicMatrix
Definition: NestedSolve.h:58
typename std::conditional< is_ad, typename ADType< T >::type, T >::type GenericType
Definition: MooseTypes.h:644
typename std::conditional< N==1, NSReal, typename std::conditional< N==0, NestedSolveTempl< is_ad >::DynamicVector, Eigen::Matrix< NSReal, N, 1 > >::type >::type Value
Residual and solution type.
Definition: NestedSolve.h:75
MPI_Status status
void sizeItems(const NestedSolveTempl< is_ad >::DynamicVector &guess, NestedSolveTempl< is_ad >::DynamicVector &residual, NestedSolveTempl< is_ad >::DynamicMatrix &jacobian) const
Size a dynamic Jacobian matrix correctly.
Definition: NestedSolve.C:83
void nonlinearTight(DynamicVector &guess, R &computeResidual, J &computeJacobian)
unsigned int _max_iterations
Definition: NestedSolve.h:143
Deduce the Jacobian type from the solution type.
Definition: NestedSolve.h:63
int df(V &guess, typename NestedSolveTempl< is_ad >::template CorrespondingJacobian< V > &jacobian)
Definition: NestedSolve.h:680
RankTwoTensorTempl< ADReal > ADRankTwoTensor
void linear(const J &A, V &x, const V &b) const
Solve A*x=b for x.
Definition: NestedSolve.h:546
int operator()(V &guess, V &residual)
Definition: NestedSolve.h:673
void nonlinear(V &guess, T &&compute)
Solve the N*N nonlinear equation system using a built-in Netwon-Raphson loop.
Definition: NestedSolve.h:427
Real _absolute_tolerance_square
Definition: NestedSolve.h:135
static Real relativeToleranceDefault()
default values
Definition: NestedSolve.h:120
auto make_adaptor(R &residual, J &jacobian)
Build a suitable Eigen adaptor functors to interface between moose and Eigen types.
Definition: NestedSolve.h:753
Eigen::Matrix< NSReal, Eigen::Dynamic, 1 > DynamicVector
Eigen type shortcuts.
Definition: NestedSolve.h:57
typename std::conditional< N==1, NSReal, typename std::conditional< N==0, NestedSolveTempl< is_ad >::DynamicMatrix, Eigen::Matrix< NSReal, N, N > >::type >::type Jacobian
Jacobian matrix type.
Definition: NestedSolve.h:84
void setRelativeTolerance(Real rel)
Definition: NestedSolve.h:130
auto make_real_adaptor(R &residual, J &jacobian)
Definition: NestedSolve.h:761
bool isConverged(Real r0_square, Real r_square, bool acceptable)
Convergence check (updates _status)
Definition: NestedSolve.h:779
static Real normSquare(const V &v)
Compute squared norm of v (dropping derivatives as this is only for convergence checking) ...
Definition: NestedSolve.h:555
auto conditional(const C &, const L &, const R &)
typename NestedSolveInternal::CorrespondingJacobianTempl< T >::type CorrespondingJacobian
Definition: NestedSolve.h:65
NestedSolveTempl<is_ad> and its instantiations NestedSolve and ADNestedSolve are utility classes that...
Definition: NestedSolve.h:42
std::size_t _n_iterations
number of nested iterations
Definition: NestedSolve.h:187
Internal use namespace that contains template helpers to map each residual type to its corresponding ...
Definition: NestedSolve.h:30
void nonlinearBounded(NSReal &guess, R &computeResidual, J &computeJacobian, B &computeBounds)
Perform a bounded solve use Eigen::HybridNonLinearSolver.
Definition: NestedSolve.h:377
Adaptor functor for scalar Real valued residual and Jacobian types.
Definition: NestedSolve.h:664
Real _relative_tolerance_square
Definition: NestedSolve.h:134
auto make_realvector_adaptor(R &residual, J &jacobian)
Definition: NestedSolve.h:770
void linear(const NSReal &A, NSReal &x, const NSReal &b) const
Definition: NestedSolve.h:203
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void setAbsoluteTolerance(Real abs)
Definition: NestedSolve.h:131
static unsigned int minIterationsDefault()
Definition: NestedSolve.h:123
static unsigned int maxIterationsDefault()
Definition: NestedSolve.h:124
Moose::GenericType< Real, is_ad > NSReal
AD/non-AD switched type shortcuts.
Definition: NestedSolve.h:51
static Real absoluteToleranceDefault()
Definition: NestedSolve.h:121
static Real acceptableMultiplierDefault()
Definition: NestedSolve.h:125
typename NestedSolveTempl< is_ad >::DynamicVector V
Definition: NestedSolve.h:666
unsigned int _max_damping_iterations
Definition: NestedSolve.h:140
Adaptor functor for MOOSE RealVectorValue/RankTwoTensor residual and Jacobian types.
Definition: NestedSolve.h:704
void nonlinearDamped(V &guess, T &&compute, C &&computeCondition)
Solve the N*N nonlinear equation system using the damped Netwon-Raphson loop.
Definition: NestedSolve.h:482
int df(V &guess, typename NestedSolveTempl< is_ad >::template CorrespondingJacobian< V > &jacobian)
Definition: NestedSolve.h:640
NestedSolveTempl< true > ADNestedSolve
Definition: NestedSolve.h:797
Moose::GenericType< RealVectorValue, is_ad > NSRealVectorValue
Definition: NestedSolve.h:52
typename NestedSolveTempl< is_ad >::DynamicVector V
Definition: NestedSolve.h:706
auto index_range(const T &sizable)
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template pow< 2 >(tan(_arg))+1.0) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(sqrt
const State & getState() const
Get the solver state.
Definition: NestedSolve.h:161
int df(V &guess, typename NestedSolveTempl< is_ad >::template CorrespondingJacobian< V > &jacobian)
Definition: NestedSolve.h:725
Real _damping_factor
Damping factor.
Definition: NestedSolve.h:139