GEOS
CoupledSolver.hpp
Go to the documentation of this file.
1 /*
2  * ------------------------------------------------------------------------------------------------------------
3  * SPDX-License-Identifier: LGPL-2.1-only
4  *
5  * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC
6  * Copyright (c) 2018-2024 TotalEnergies
7  * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University
8  * Copyright (c) 2023-2024 Chevron
9  * Copyright (c) 2019- GEOS/GEOSX Contributors
10  * All rights reserved
11  *
12  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
13  * ------------------------------------------------------------------------------------------------------------
14  */
15 
21 #ifndef GEOS_PHYSICSSOLVERS_MULTIPHYSICS_COUPLEDSOLVER_HPP_
22 #define GEOS_PHYSICSSOLVERS_MULTIPHYSICS_COUPLEDSOLVER_HPP_
23 
26 
27 #include <tuple>
28 
29 namespace geos
30 {
31 
32 template< typename ... SOLVERS >
34 {
35 
36 public:
37 
43  CoupledSolver( const string & name,
44  Group * const parent )
45  : PhysicsSolverBase( name, parent )
46  {
47  forEachArgInTuple( m_solvers, [&]( auto solver, auto idx )
48  {
49  using SolverType = TYPEOFPTR( solver );
50  string const key = SolverType::coupledSolverAttributePrefix() + "SolverName";
51  registerWrapper( key, &m_names[idx()] ).
52  setRTTypeName( rtTypes::CustomTypes::groupNameRef ).
54  setDescription( "Name of the " + SolverType::coupledSolverAttributePrefix() + " solver used by the coupled solver" );
55  } );
56 
57  this->getWrapper< string >( PhysicsSolverBase::viewKeyStruct::discretizationString() ).
58  setInputFlag( dataRepository::InputFlags::FALSE );
59 
60  addLogLevel< logInfo::Coupling >();
61  }
62 
64  CoupledSolver( CoupledSolver const & ) = delete;
65 
67  CoupledSolver( CoupledSolver && ) = default;
68 
70  CoupledSolver & operator=( CoupledSolver const & ) = delete;
71 
74 
75 
79  void
81  {
82  forEachArgInTuple( m_solvers, [&]( auto & solver, auto idx )
83  {
84  using SolverPtr = TYPEOFREF( solver );
85  using SolverType = TYPEOFPTR( SolverPtr {} );
86  auto const & solverName = m_names[idx()];
87  auto const & solverType = LvArray::system::demangleType< SolverType >();
88  solver = this->getParent().template getGroupPointer< SolverType >( solverName );
89  GEOS_THROW_IF( solver == nullptr,
90  GEOS_FMT( "{}: Could not find solver '{}' of type {}",
92  solverName, solverType ),
93  InputError );
94  GEOS_LOG_LEVEL_RANK_0( logInfo::Coupling,
95  GEOS_FMT( "{}: found {} solver named {}",
96  getName(), solver->getCatalogName(), solverName ) );
97  } );
98  }
99 
100 
106  virtual void
108  DofManager & dofManager ) const
109  { GEOS_UNUSED_VAR( domain, dofManager ); }
110 
120  virtual void
122  real64 const dt,
123  DomainPartition const & domain,
124  DofManager const & dofManager,
125  CRSMatrixView< real64, globalIndex const > const & localMatrix,
126  arrayView1d< real64 > const & localRhs )
127  { GEOS_UNUSED_VAR( time_n, dt, domain, dofManager, localMatrix, localRhs ); }
128 
136  void
137  setupDofs( DomainPartition const & domain,
138  DofManager & dofManager ) const override
139  {
140  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
141  {
142  solver->setupDofs( domain, dofManager );
143  } );
144 
145  setupCoupling( domain, dofManager );
146  }
147 
148  virtual void
149  implicitStepSetup( real64 const & time_n,
150  real64 const & dt,
151  DomainPartition & domain ) override
152  {
153  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
154  {
155  solver->implicitStepSetup( time_n, dt, domain );
156  } );
157  }
158 
159  virtual void
160  implicitStepComplete( real64 const & time_n,
161  real64 const & dt,
162  DomainPartition & domain ) override
163  {
164  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
165  {
166  solver->implicitStepComplete( time_n, dt, domain );
167  } );
168  }
169 
170  // general version of assembleSystem function, keep in mind many solvers will override it
171  virtual void
172  assembleSystem( real64 const time_n,
173  real64 const dt,
174  DomainPartition & domain,
175  DofManager const & dofManager,
176  CRSMatrixView< real64, globalIndex const > const & localMatrix,
177  arrayView1d< real64 > const & localRhs ) override
178  {
180 
181  // 1. Assemble matrix blocks of each individual solver
182  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
183  {
184  solver->assembleSystem( time_n, dt, domain, dofManager, localMatrix, localRhs );
185  } );
186 
187  // 2. Assemble coupling blocks
188  assembleCouplingTerms( time_n, dt, domain, dofManager, localMatrix, localRhs );
189  }
190 
191  virtual void
192  applySystemSolution( DofManager const & dofManager,
193  arrayView1d< real64 const > const & localSolution,
194  real64 const scalingFactor,
195  real64 const dt,
196  DomainPartition & domain ) override
197  {
198  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
199  {
200  solver->applySystemSolution( dofManager, localSolution, scalingFactor, dt, domain );
201  } );
202  }
203 
204  virtual void
205  updateState( DomainPartition & domain ) override
206  {
207  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
208  {
209  solver->updateState( domain );
210  } );
211  }
212 
213  virtual void
215  {
216  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
217  {
218  solver->resetStateToBeginningOfStep( domain );
219  } );
220  }
221 
224  real64
225  solverStep( real64 const & time_n,
226  real64 const & dt,
227  int const cycleNumber,
228  DomainPartition & domain ) override final
229  {
231 
233  {
234  return fullyCoupledSolverStep( time_n, dt, cycleNumber, domain );
235  }
237  {
238  return sequentiallyCoupledSolverStep( time_n, dt, cycleNumber, domain );
239  }
240  else
241  {
242  GEOS_ERROR( getDataContext() << ": Invalid coupling type option." );
243  return 0;
244  }
245 
246  }
247 
248 
249  virtual void
250  updateAndWriteConvergenceStep( real64 const & time_n, real64 const & dt,
251  integer const cycleNumber, integer const iteration ) override
252  {
253  PhysicsSolverBase::updateAndWriteConvergenceStep( time_n, dt, cycleNumber, iteration );
254  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
255  {
256  solver->updateAndWriteConvergenceStep( time_n, dt, cycleNumber, iteration );
257  } );
258  }
259 
260  virtual real64
261  calculateResidualNorm( real64 const & time_n,
262  real64 const & dt,
263  DomainPartition const & domain,
264  DofManager const & dofManager,
265  arrayView1d< real64 const > const & localRhs ) override
266  {
267  real64 norm = 0.0;
268  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
269  {
270  real64 const singlePhysicsNorm = solver->calculateResidualNorm( time_n, dt, domain, dofManager, localRhs );
271  norm += singlePhysicsNorm * singlePhysicsNorm;
272  } );
273 
274  return sqrt( norm );
275  }
276 
277  virtual void
279  real64 const dt,
280  DomainPartition & domain,
281  DofManager const & dofManager,
282  CRSMatrixView< real64, globalIndex const > const & localMatrix,
283  arrayView1d< real64 > const & localRhs ) override
284  {
285  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
286  {
287  solver->applyBoundaryConditions( time_n, dt, domain, dofManager, localMatrix, localRhs );
288  } );
289  }
290 
291  virtual bool
293  DofManager const & dofManager,
294  arrayView1d< real64 const > const & localSolution,
295  real64 const scalingFactor ) override
296  {
297  bool validSolution = true;
298  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
299  {
300  bool const validSinglePhysicsSolution = solver->checkSystemSolution( domain, dofManager, localSolution, scalingFactor );
301  if( !validSinglePhysicsSolution )
302  {
303  GEOS_LOG_RANK_0( GEOS_FMT( " {}/{}: Solution check failed. Newton loop terminated.", getName(), solver->getName()) );
304  }
305  validSolution = validSolution && validSinglePhysicsSolution;
306  } );
307  return validSolution;
308  }
309 
310  virtual real64
312  DofManager const & dofManager,
313  arrayView1d< real64 const > const & localSolution ) override
314  {
315  real64 scalingFactor = PhysicsSolverBase::scalingForSystemSolution( domain, dofManager, localSolution );
316  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
317  {
318  real64 const singlePhysicsScalingFactor = solver->scalingForSystemSolution( domain, dofManager, localSolution );
319  scalingFactor = LvArray::math::min( scalingFactor, singlePhysicsScalingFactor );
320  } );
321  return scalingFactor;
322  }
323 
324  virtual real64
325  setNextDt( real64 const & currentTime,
326  real64 const & currentDt,
327  DomainPartition & domain ) override
328  {
329  real64 nextDt = PhysicsSolverBase::setNextDt( currentTime, currentDt, domain );
330  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
331  {
332  real64 const singlePhysicsNextDt =
333  solver->setNextDt( currentTime, currentDt, domain );
334  nextDt = LvArray::math::min( singlePhysicsNextDt, nextDt );
335  } );
336  return nextDt;
337  }
338 
339  virtual void cleanup( real64 const time_n,
340  integer const cycleNumber,
341  integer const eventCounter,
342  real64 const eventProgress,
343  DomainPartition & domain ) override
344  {
345  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
346  {
347  solver->cleanup( time_n, cycleNumber, eventCounter, eventProgress, domain );
348  } );
349  PhysicsSolverBase::cleanup( time_n, cycleNumber, eventCounter, eventProgress, domain );
350  }
351 
354  virtual bool checkSequentialSolutionIncrements( DomainPartition & domain ) const override
355  {
356  bool isConverged = true;
357  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
358  {
359  isConverged &= solver->checkSequentialSolutionIncrements( domain );
360  } );
361  return isConverged;
362  }
363 
364  virtual bool updateConfiguration( DomainPartition & domain,
365  integer const configurationLoopIter ) override
366  {
367  bool result = true;
368  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
369  {
370  result &= solver->updateConfiguration( domain, configurationLoopIter );
371  } );
372  return result;
373  }
374 
375  virtual void outputConfigurationStatistics( DomainPartition const & domain ) const override
376  {
377  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
378  {
379  solver->outputConfigurationStatistics( domain );
380  } );
381  }
382 
383  virtual void resetConfigurationToBeginningOfStep( DomainPartition & domain ) override
384  {
385  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
386  {
387  solver->resetConfigurationToBeginningOfStep( domain );
388  } );
389  }
390 
391  virtual bool resetConfigurationToDefault( DomainPartition & domain ) const override
392  {
393  bool result = true;
394  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
395  {
396  result &= solver->resetConfigurationToDefault( domain );
397  } );
398  return result;
399  }
400 
401  virtual void
403  {
404  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
405  {
406  solver->getNonlinearSolverParameters() = getNonlinearSolverParameters();
407  solver->synchronizeNonlinearSolverParameters();
408  } );
409  }
410 
411 protected:
412 
422  virtual real64 fullyCoupledSolverStep( real64 const & time_n,
423  real64 const & dt,
424  int const cycleNumber,
425  DomainPartition & domain )
426  {
427  return PhysicsSolverBase::solverStep( time_n, dt, cycleNumber, domain );
428  }
429 
440  virtual real64 sequentiallyCoupledSolverStep( real64 const & time_n,
441  real64 const & dt,
442  integer const cycleNumber,
443  DomainPartition & domain )
444  {
446 
447  // Only build the sparsity pattern if the mesh has changed
448  Timestamp const meshModificationTimestamp = getMeshModificationTimestamp( domain );
449  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
450  {
451  if( meshModificationTimestamp > solver->getSystemSetupTimestamp() )
452  {
453  solver->setupSystem( domain,
454  solver->getDofManager(),
455  solver->getLocalMatrix(),
456  solver->getSystemRhs(),
457  solver->getSystemSolution() );
458  solver->setSystemSetupTimestamp( meshModificationTimestamp );
459  }
460  } );
461 
462  implicitStepSetup( time_n, dt, domain );
463 
465  integer const maxNumberDtCuts = solverParams.m_maxTimeStepCuts;
466  real64 const dtCutFactor = solverParams.m_timeStepCutFactor;
467  integer & dtAttempt = solverParams.m_numTimeStepAttempts;
468 
469  bool isConverged = false;
470  // dt may be cut during the course of this step, so we are keeping a local
471  // value to track the achieved dt for this step.
472  real64 stepDt = dt;
473 
474  // outer loop attempts to apply full timestep, and managed the cutting of the timestep if
475  // required.
476  for( dtAttempt = 0; dtAttempt < maxNumberDtCuts; ++dtAttempt )
477  {
478  // TODO configuration loop
479 
480  // Reset the states of all solvers if any of them had to restart
481  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
482  {
483  solver->resetStateToBeginningOfStep( domain );
484  solver->getIterationStats().resetCurrentTimeStepStatistics(); // initialize counters for subsolvers
485  } );
486  resetStateToBeginningOfStep( domain );
487 
488  integer & iter = solverParams.m_numNewtonIterations;
489 
491  for( iter = 0; iter < solverParams.m_maxIterNewton; iter++ )
492  {
493  // Increment the solver statistics for reporting purposes
495 
496  startSequentialIteration( iter, domain );
497 
498  // Solve the subproblems nonlinearly
499  forEachArgInTuple( m_solvers, [&]( auto & solver, auto idx )
500  {
501  GEOS_LOG_LEVEL_RANK_0( logInfo::NonlinearSolver,
502  GEOS_FMT( " Iteration {:2}: {}", iter + 1, solver->getName() ) );
503  real64 solverDt = solver->nonlinearImplicitStep( time_n,
504  stepDt,
505  cycleNumber,
506  domain );
507 
508  // save fields (e.g. pressure and temperature) after inner solve
509  if( solver->getNonlinearSolverParameters().couplingType() == NonlinearSolverParameters::CouplingType::Sequential )
510  {
511  solver->saveSequentialIterationState( domain );
512  }
513 
514  mapSolutionBetweenSolvers( domain, idx() );
515 
516  if( solverDt < stepDt ) // subsolver had to cut the time step
517  {
518  iter = 0; // restart outer loop
519  stepDt = solverDt; // sync time step
521  }
522  } );
523  // Check convergence of the outer loop
524  isConverged = checkSequentialConvergence( cycleNumber,
525  iter,
526  time_n,
527  stepDt,
528  domain );
529 
530  if( isConverged )
531  {
532  // we still want to count current iteration
533  ++iter;
534  // exit outer loop
535  break;
536  }
537  else
538  {
539  finishSequentialIteration( iter, domain );
540  }
541  }
542 
543  if( isConverged )
544  {
545  // Save time step statistics for the subsolvers
546  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
547  {
548  solver->getIterationStats().iterateTimeStepStatistics();
549  } );
550  // get out of the time loop
551  break;
552  }
553  else
554  {
555  // cut timestep, go back to beginning of step and restart the Newton loop
556  stepDt *= dtCutFactor;
558  GEOS_LOG_LEVEL_RANK_0( logInfo::TimeStep, GEOS_FMT( "New dt = {}", stepDt ) );
559 
560  // notify the solver statistics counter that this is a time step cut
562  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
563  {
564  solver->getIterationStats().updateTimeStepCut();
565  } );
566  }
567  }
568 
569  if( !isConverged )
570  {
571  GEOS_LOG_RANK_0( "Convergence not achieved." );
572 
574  {
575  GEOS_LOG_RANK_0( "The accepted solution may be inaccurate." );
576  }
577  else
578  {
579  GEOS_ERROR( "Nonconverged solutions not allowed. Terminating..." );
580  }
581  }
582 
583  implicitStepComplete( time_n, stepDt, domain );
584 
585  return stepDt;
586  }
587 
595  integer const solverType )
596  {
597  GEOS_UNUSED_VAR( domain, solverType );
598  }
599 
600  virtual bool checkSequentialConvergence( integer const cycleNumber,
601  integer const iter,
602  real64 const & time_n,
603  real64 const & dt,
604  DomainPartition & domain )
605  {
607  bool isConverged = true;
608 
609  if( params.m_subcyclingOption == 0 )
610  {
611  GEOS_LOG_LEVEL_RANK_0( logInfo::Convergence, "***** Single Pass solver, no subcycling *****" );
612  }
613  else
614  {
615  GEOS_LOG_LEVEL_RANK_0( logInfo::Convergence, GEOS_FMT( " Iteration {:2}: outer-loop convergence check", iter + 1 ) );
616 
618  {
619  real64 residualNorm = 0;
620 
621  // loop over all the single-physics solvers
622  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
623  {
624 
625  solver->getLocalMatrix().toViewConstSizes().zero();
626  solver->getSystemRhs().zero();
627  arrayView1d< real64 > const localRhs = solver->getSystemRhs().open();
628 
629  // for each solver, we have to recompute the residual (and Jacobian, although not necessary)
630  solver->assembleSystem( time_n,
631  dt,
632  domain,
633  solver->getDofManager(),
634  solver->getLocalMatrix().toViewConstSizes(),
635  localRhs );
636  solver->applyBoundaryConditions( time_n,
637  dt,
638  domain,
639  solver->getDofManager(),
640  solver->getLocalMatrix().toViewConstSizes(),
641  localRhs );
642  solver->getSystemRhs().close();
643 
644  // once this is done, we recompute the single-physics residual
645  real64 const singlePhysicsNorm =
646  solver->calculateResidualNorm( time_n,
647  dt,
648  domain,
649  solver->getDofManager(),
650  solver->getSystemRhs().values() );
651  residualNorm += singlePhysicsNorm * singlePhysicsNorm;
652  } );
653 
654  // finally, we perform the convergence check on the multiphysics residual
655  residualNorm = sqrt( residualNorm );
656  GEOS_LOG_LEVEL_RANK_0( logInfo::ResidualNorm,
657  GEOS_FMT( " ( R ) = ( {:4.2e} )", residualNorm ) );
658  getConvergenceStats().setResidualValue( "R", residualNorm );
659  updateAndWriteConvergenceStep( time_n, dt, cycleNumber, iter );
660 
661  isConverged = ( residualNorm < params.m_newtonTol );
662 
663  }
665  {
666  // TODO also make recursive?
667  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
668  {
669  NonlinearSolverParameters const & singlePhysicsParams = solver->getNonlinearSolverParameters();
670  if( singlePhysicsParams.m_numNewtonIterations > singlePhysicsParams.m_minIterNewton )
671  {
672  isConverged = false;
673  }
674  } );
675  }
677  {
678  isConverged = checkSequentialSolutionIncrements( domain );
679  }
680  else
681  {
682  GEOS_ERROR( getDataContext() << ": Invalid sequential convergence criterion." );
683  }
684 
685  if( isConverged )
686  {
687  GEOS_LOG_LEVEL_RANK_0( logInfo::Convergence,
688  GEOS_FMT( "***** The iterative coupling has converged in {} iteration(s) *****", iter + 1 ) );
689  }
690  }
691  return isConverged;
692  }
693 
694  virtual void
696  {
697  setSubSolvers();
698 
700 
703  GEOS_THROW_IF( isSequential && usesLineSearch,
704  GEOS_FMT( "{}: line search is not supported by the coupled solver when {} is set to `{}`. Please set {} to `{}` to remove this error",
705  getNonlinearSolverParameters().getWrapperDataContext( NonlinearSolverParameters::viewKeysStruct::couplingTypeString() ),
706  NonlinearSolverParameters::viewKeysStruct::couplingTypeString(),
708  NonlinearSolverParameters::viewKeysStruct::lineSearchActionString(),
710  InputError );
711 
713  {
714  validateNonlinearAcceleration();
715  }
716  }
717 
718  virtual void validateNonlinearAcceleration()
719  {
720  GEOS_THROW ( GEOS_FMT( "{}: Nonlinear acceleration {} is not supported by {} solver '{}'",
721  getWrapperDataContext( NonlinearSolverParameters::viewKeysStruct::nonlinearAccelerationTypeString() ),
723  getCatalogName(), getName()),
724  InputError );
725  }
726 
727  virtual void initializePreSubGroups() override
728  {
730 
732  if( !isSequential )
733  {
735  }
736  }
737 
738  virtual void startSequentialIteration( integer const & iter,
739  DomainPartition & domain )
740  {
741  GEOS_UNUSED_VAR( iter, domain );
742  }
743 
744  virtual void finishSequentialIteration( integer const & iter,
745  DomainPartition & domain )
746  {
747  GEOS_UNUSED_VAR( iter, domain );
748  }
749 
750 protected:
751 
753  std::tuple< SOLVERS *... > m_solvers;
754 
756  std::array< string, sizeof...( SOLVERS ) > m_names;
757 };
758 
759 } /* namespace geos */
760 
761 #endif /* GEOS_PHYSICSSOLVERS_MULTIPHYSICS_COUPLEDSOLVER_HPP_ */
#define GEOS_UNUSED_VAR(...)
Mark an unused variable and silence compiler warnings.
Definition: GeosxMacros.hpp:84
#define GEOS_THROW(msg, TYPE)
Throw an exception.
Definition: Logger.hpp:164
#define GEOS_ERROR(msg)
Raise a hard error and terminate the program.
Definition: Logger.hpp:157
#define GEOS_LOG_RANK_0(msg)
Log a message on screen on rank 0.
Definition: Logger.hpp:101
#define GEOS_THROW_IF(EXP, msg, TYPE)
Conditionally throw an exception.
Definition: Logger.hpp:151
#define GEOS_MARK_FUNCTION
Mark function with both Caliper and NVTX if enabled.
virtual void assembleCouplingTerms(real64 const time_n, real64 const dt, DomainPartition const &domain, DofManager const &dofManager, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs)
Utility function to compute coupling terms.
CoupledSolver & operator=(CoupledSolver const &)=delete
deleted assignment operator
virtual real64 fullyCoupledSolverStep(real64 const &time_n, real64 const &dt, int const cycleNumber, DomainPartition &domain)
Fully coupled solution approach solution step.
virtual bool resetConfigurationToDefault(DomainPartition &domain) const override
resets the configuration to the default value.
CoupledSolver(const string &name, Group *const parent)
main constructor for CoupledSolver Objects
virtual void outputConfigurationStatistics(DomainPartition const &domain) const override
CoupledSolver(CoupledSolver &&)=default
default move constructor
virtual void resetConfigurationToBeginningOfStep(DomainPartition &domain) override
resets the configuration to the beginning of the time-step.
virtual void initializePreSubGroups() override
Called by Initialize() prior to initializing sub-Groups.
virtual real64 sequentiallyCoupledSolverStep(real64 const &time_n, real64 const &dt, integer const cycleNumber, DomainPartition &domain)
Sequentially coupled solver step. It solves a nonlinear system of equations using a sequential approa...
CoupledSolver(CoupledSolver const &)=delete
deleted copy constructor
virtual void synchronizeNonlinearSolverParameters() override
synchronize the nonlinear solver parameters.
virtual void setupCoupling(DomainPartition const &domain, DofManager &dofManager) const
Utility function to set the coupling between degrees of freedom.
virtual bool checkSequentialSolutionIncrements(DomainPartition &domain) const override
Check if the solution increments are ok to use.
virtual bool updateConfiguration(DomainPartition &domain, integer const configurationLoopIter) override
updates the configuration (if needed) based on the state after a converged Newton loop.
virtual void postInputInitialization() override
std::array< string, sizeof...(SOLVERS) > m_names
Names of the single-physics solvers.
std::tuple< SOLVERS *... > m_solvers
Pointers of the single-physics solvers.
CoupledSolver & operator=(CoupledSolver &&)=delete
deleted move operator
void setSubSolvers()
Utility function to set the subsolvers pointers using the names provided by the user.
virtual void mapSolutionBetweenSolvers(DomainPartition &domain, integer const solverType)
Maps the solution obtained from one solver to the fields used by the other solver(s)
The DoFManager is responsible for allocating global dofs, constructing sparsity patterns,...
Definition: DofManager.hpp:45
Partition of the decomposed physical domain. It also manages the connexion information to its neighbo...
void updateNonlinearIteration(integer const numLinearIterations)
Tell the solverStatistics that we have done a newton iteration.
void updateTimeStepCut()
Tell the solverStatistics that we cut the time step and we increment the cumulative counters for disc...
SequentialConvergenceCriterion sequentialConvergenceCriterion() const
Getter for the sequential convergence criterion.
integer m_allowNonConverged
Flag to allow for a non-converged nonlinear solution and continue with the problem.
real64 m_newtonTol
The tolerance for the nonlinear convergence check.
NonlinearAccelerationType m_nonlinearAccelerationType
Type of nonlinear acceleration for sequential solver.
integer m_maxIterNewton
The maximum number of nonlinear iterations that are allowed.
real64 m_timeStepCutFactor
Factor by which the time step will be cut if a timestep cut is required.
integer m_numNewtonIterations
The number of nonlinear iterations that have been exectued.
integer m_numTimeStepAttempts
Number of times that the time-step had to be cut.
integer m_maxTimeStepCuts
Max number of time step cuts.
CouplingType couplingType() const
Getter for the coupling type.
LineSearchAction m_lineSearchAction
Flag to apply a line search.
@ ResidualNorm
convergence achieved when the residual drops below a given norm
@ NumberOfNonlinearIterations
convergence achieved when the subproblems convergence is achieved in less than minNewtonIteration
@ SolutionIncrements
convergence achieved when the solution increments are small enough
integer m_subcyclingOption
Flag to specify whether subcycling is allowed or not in sequential schemes.
Base class for all physics solvers.
virtual string getCatalogName() const =0
IterationsStatistics & getIterationStats()
integer m_numTimestepsSinceLastDtCut
Number of cycles since last timestep cut.
virtual void cleanup(real64 const time_n, integer const cycleNumber, integer const eventCounter, real64 const eventProgress, DomainPartition &domain) override
Called as the code exits the main run loop.
Timestamp getMeshModificationTimestamp(DomainPartition &domain) const
getter for the timestamp of the mesh modification on the mesh levels
virtual void postInputInitialization() override
ConvergenceStatistics & getConvergenceStats()
NonlinearSolverParameters & getNonlinearSolverParameters()
accessor for the nonlinear solver parameters.
NonlinearSolverParameters m_nonlinearSolverParameters
Nonlinear solver parameters.
virtual void initializePreSubGroups()
Called by Initialize() prior to initializing sub-Groups.
Definition: Group.hpp:1542
Wrapper< TBASE > & registerWrapper(string const &name, wrapperMap::KeyIndex::index_type *const rkey=nullptr)
Create and register a Wrapper around a new object.
DataContext const & getDataContext() const
Definition: Group.hpp:1345
string const & getName() const
Get group name.
Definition: Group.hpp:1331
Group & getParent()
Access the group's parent.
Definition: Group.hpp:1364
DataContext const & getWrapperDataContext(KEY key) const
Definition: Group.hpp:1356
#define GEOS_LOG_LEVEL_RANK_0(logInfoStruct, msg)
Output messages (only on rank 0) based on current Group's log level.
virtual void implicitStepSetup(real64 const &time_n, real64 const &dt, DomainPartition &domain) override
function to perform setup for implicit timestep
virtual void cleanup(real64 const time_n, integer const cycleNumber, integer const eventCounter, real64 const eventProgress, DomainPartition &domain) override
Called as the code exits the main run loop.
virtual real64 scalingForSystemSolution(DomainPartition &domain, DofManager const &dofManager, arrayView1d< real64 const > const &localSolution) override
Function to determine if the solution vector should be scaled back in order to maintain a known const...
virtual void updateAndWriteConvergenceStep(real64 const &time_n, real64 const &dt, integer const cycleNumber, integer const iteration) override
Update the convergence information and write then into a CSV file.
virtual void updateState(DomainPartition &domain) override
Recompute all dependent quantities from primary variables (including constitutive models)
virtual void implicitStepComplete(real64 const &time_n, real64 const &dt, DomainPartition &domain) override
perform cleanup for implicit timestep
virtual void applyBoundaryConditions(real64 const time_n, real64 const dt, DomainPartition &domain, DofManager const &dofManager, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs) override
apply boundary condition to system
virtual real64 scalingForSystemSolution(DomainPartition &domain, DofManager const &dofManager, arrayView1d< real64 const > const &localSolution)
Function to determine if the solution vector should be scaled back in order to maintain a known const...
virtual real64 calculateResidualNorm(real64 const &time_n, real64 const &dt, DomainPartition const &domain, DofManager const &dofManager, arrayView1d< real64 const > const &localRhs) override
calculate the norm of the global system residual
real64 solverStep(real64 const &time_n, real64 const &dt, int const cycleNumber, DomainPartition &domain) override final
virtual real64 setNextDt(real64 const &currentTime, real64 const &currentDt, DomainPartition &domain) override
function to set the next time step size
virtual real64 solverStep(real64 const &time_n, real64 const &dt, integer const cycleNumber, DomainPartition &domain)
entry function to perform a solver step
void setupDofs(DomainPartition const &domain, DofManager &dofManager) const override
Populate degree-of-freedom manager with fields relevant to this solver.
virtual void applySystemSolution(DofManager const &dofManager, arrayView1d< real64 const > const &localSolution, real64 const scalingFactor, real64 const dt, DomainPartition &domain) override
Function to apply the solution vector to the state.
virtual real64 setNextDt(real64 const &currentTime, real64 const &currentDt, DomainPartition &domain)
function to set the next time step size
virtual void updateAndWriteConvergenceStep(real64 const &time_n, real64 const &dt, integer const cycleNumber, integer const iteration)
Update the convergence information and write then into a CSV file.
virtual void assembleSystem(real64 const time_n, real64 const dt, DomainPartition &domain, DofManager const &dofManager, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs) override
function to assemble the linear system matrix and rhs
virtual bool checkSystemSolution(DomainPartition &domain, DofManager const &dofManager, arrayView1d< real64 const > const &localSolution, real64 const scalingFactor) override
Function to check system solution for physical consistency and constraint violation.
virtual void resetStateToBeginningOfStep(DomainPartition &domain) override
reset state of physics back to the beginning of the step.
@ FALSE
Not read from input.
@ REQUIRED
Required in input.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:179
unsigned long long int Timestamp
Timestamp type (used to perform actions such a sparsity pattern computation after mesh modifications)
Definition: DataTypes.hpp:126
std::string string
String type.
Definition: DataTypes.hpp:90
double real64
64-bit floating point type.
Definition: DataTypes.hpp:98
LvArray::CRSMatrixView< T, COL_INDEX, INDEX_TYPE const, LvArray::ChaiBuffer > CRSMatrixView
Alias for CRS Matrix View.
Definition: DataTypes.hpp:309
int integer
Signed integer type.
Definition: DataTypes.hpp:81
Provides enum <-> string conversion facilities.
Exception class used to report errors in user input.
Definition: Logger.hpp:464
static constexpr char const * discretizationString()