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  template< typename T >
76  void throwSolversNotFound( std::ostringstream & errorMessage,
77  string const & solverWrapperKey,
78  string const & solverType )
79  {
80  GEOS_UNUSED_VAR( solverWrapperKey );
81  string_array availableSolvers;
82 
83  this->getParent().template forSubGroups< T >( [&]( T & group )
84  {
85 
86  availableSolvers.emplace_back( group.getName());
87 
88  } );
89 
90  if( availableSolvers.empty() )
91  {
92  errorMessage << GEOS_FMT( "No {} solver has been found.", solverType );
93  }
94  else
95  {
96  errorMessage << GEOS_FMT( "Available {} solvers are: {}. ", solverType,
97  stringutilities::join( availableSolvers, ", " ) );
98  }
99 
100  GEOS_THROW( errorMessage.str(),
101  InputError, getWrapperDataContext( solverWrapperKey ) );
102  }
106  void
108  {
109  forEachArgInTuple( m_solvers, [&]( auto & solver, auto idx )
110  {
111  using SolverPtr = TYPEOFREF( solver );
112  using SolverType = TYPEOFPTR( SolverPtr {} );
113  auto const & solverName = m_names[idx()];
114  solver = this->getParent().template getGroupPointer< SolverType >( solverName );
115  if( solver== nullptr )
116  {
117  string const solverWrapperKey = SolverType::coupledSolverAttributePrefix() + "SolverName";
118  std::ostringstream errorMessage;
119  errorMessage << GEOS_FMT( "Could not find solver named '{}'.\n", solverName );
120  throwSolversNotFound< SolverType >( errorMessage, solverWrapperKey, SolverType::coupledSolverAttributePrefix() );
121  }
122 
123 
124  GEOS_LOG_LEVEL_RANK_0( logInfo::Coupling,
125  GEOS_FMT( "{}: found {} solver named {}",
126  getName(), solver->getCatalogName(), solverName ) );
127  } );
128  }
129 
130 
136  virtual void
138  DofManager & dofManager ) const
139  { GEOS_UNUSED_VAR( domain, dofManager ); }
140 
150  virtual void
152  real64 const dt,
153  DomainPartition const & domain,
154  DofManager const & dofManager,
155  CRSMatrixView< real64, globalIndex const > const & localMatrix,
156  arrayView1d< real64 > const & localRhs )
157  { GEOS_UNUSED_VAR( time_n, dt, domain, dofManager, localMatrix, localRhs ); }
158 
166  void
167  setupDofs( DomainPartition const & domain,
168  DofManager & dofManager ) const override
169  {
170  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
171  {
172  solver->setupDofs( domain, dofManager );
173  } );
174 
175  setupCoupling( domain, dofManager );
176  }
177 
178  virtual void
179  implicitStepSetup( real64 const & time_n,
180  real64 const & dt,
181  DomainPartition & domain ) override
182  {
183  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
184  {
185  solver->implicitStepSetup( time_n, dt, domain );
186  } );
187  }
188 
189  virtual void
190  implicitStepComplete( real64 const & time_n,
191  real64 const & dt,
192  DomainPartition & domain ) override
193  {
194  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
195  {
196  solver->implicitStepComplete( time_n, dt, domain );
197  } );
198  }
199 
200  // general version of assembleSystem function, keep in mind many solvers will override it
201  virtual void
202  assembleSystem( real64 const time_n,
203  real64 const dt,
204  DomainPartition & domain,
205  DofManager const & dofManager,
206  CRSMatrixView< real64, globalIndex const > const & localMatrix,
207  arrayView1d< real64 > const & localRhs ) override
208  {
210 
211  // 1. Assemble matrix blocks of each individual solver
212  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
213  {
214  solver->assembleSystem( time_n, dt, domain, dofManager, localMatrix, localRhs );
215  } );
216 
217  // 2. Assemble coupling blocks
218  assembleCouplingTerms( time_n, dt, domain, dofManager, localMatrix, localRhs );
219  }
220 
221  virtual void
222  applySystemSolution( DofManager const & dofManager,
223  arrayView1d< real64 const > const & localSolution,
224  real64 const scalingFactor,
225  real64 const dt,
226  DomainPartition & domain ) override
227  {
228  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
229  {
230  solver->applySystemSolution( dofManager, localSolution, scalingFactor, dt, domain );
231  } );
232  }
233 
234  virtual void
235  updateState( DomainPartition & domain ) override
236  {
237  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
238  {
239  solver->updateState( domain );
240  } );
241  }
242 
243  virtual void
245  {
246  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
247  {
248  solver->resetStateToBeginningOfStep( domain );
249  } );
250  }
251 
254  real64
255  solverStep( real64 const & time_n,
256  real64 const & dt,
257  int const cycleNumber,
258  DomainPartition & domain ) override final
259  {
261 
263  {
264  return fullyCoupledSolverStep( time_n, dt, cycleNumber, domain );
265  }
267  {
268  return sequentiallyCoupledSolverStep( time_n, dt, cycleNumber, domain );
269  }
270  else
271  {
272  GEOS_ERROR( "Invalid coupling type option.", getDataContext() );
273  return 0;
274  }
275 
276  }
277 
278 
279  virtual void
280  updateAndWriteConvergenceStep( real64 const & time_n, real64 const & dt,
281  integer const cycleNumber, integer const iteration ) override
282  {
283  PhysicsSolverBase::updateAndWriteConvergenceStep( time_n, dt, cycleNumber, iteration );
284  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
285  {
286  solver->updateAndWriteConvergenceStep( time_n, dt, cycleNumber, iteration );
287  } );
288  }
289 
290  virtual real64
291  calculateResidualNorm( real64 const & time_n,
292  real64 const & dt,
293  DomainPartition const & domain,
294  DofManager const & dofManager,
295  arrayView1d< real64 const > const & localRhs ) override
296  {
297  real64 norm = 0.0;
298  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
299  {
300  real64 const singlePhysicsNorm = solver->calculateResidualNorm( time_n, dt, domain, dofManager, localRhs );
301  norm += singlePhysicsNorm * singlePhysicsNorm;
302  } );
303 
304  return sqrt( norm );
305  }
306 
307  virtual void
309  real64 const dt,
310  DomainPartition & domain,
311  DofManager const & dofManager,
312  CRSMatrixView< real64, globalIndex const > const & localMatrix,
313  arrayView1d< real64 > const & localRhs ) override
314  {
315  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
316  {
317  solver->applyBoundaryConditions( time_n, dt, domain, dofManager, localMatrix, localRhs );
318  } );
319  }
320 
321  virtual bool
323  DofManager const & dofManager,
324  arrayView1d< real64 const > const & localSolution,
325  real64 const scalingFactor ) override
326  {
327  bool validSolution = true;
328  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
329  {
330  bool const validSinglePhysicsSolution = solver->checkSystemSolution( domain, dofManager, localSolution, scalingFactor );
331  if( !validSinglePhysicsSolution )
332  {
333  GEOS_LOG_RANK_0( GEOS_FMT( " {}/{}: Solution check failed. Newton loop terminated.", getName(), solver->getName()) );
334  }
335  validSolution = validSolution && validSinglePhysicsSolution;
336  } );
337  return validSolution;
338  }
339 
340  virtual real64
342  DofManager const & dofManager,
343  arrayView1d< real64 const > const & localSolution ) override
344  {
345  real64 scalingFactor = PhysicsSolverBase::scalingForSystemSolution( domain, dofManager, localSolution );
346  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
347  {
348  real64 const singlePhysicsScalingFactor = solver->scalingForSystemSolution( domain, dofManager, localSolution );
349  scalingFactor = LvArray::math::min( scalingFactor, singlePhysicsScalingFactor );
350  } );
351  return scalingFactor;
352  }
353 
354  virtual real64
355  setNextDt( real64 const & currentTime,
356  real64 const & currentDt,
357  DomainPartition & domain ) override
358  {
359  real64 nextDt = PhysicsSolverBase::setNextDt( currentTime, currentDt, domain );
360  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
361  {
362  real64 const singlePhysicsNextDt =
363  solver->setNextDt( currentTime, currentDt, domain );
364  nextDt = LvArray::math::min( singlePhysicsNextDt, nextDt );
365  } );
366  return nextDt;
367  }
368 
369  virtual void cleanup( real64 const time_n,
370  integer const cycleNumber,
371  integer const eventCounter,
372  real64 const eventProgress,
373  DomainPartition & domain ) override
374  {
375  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
376  {
377  solver->cleanup( time_n, cycleNumber, eventCounter, eventProgress, domain );
378  } );
379  PhysicsSolverBase::cleanup( time_n, cycleNumber, eventCounter, eventProgress, domain );
380  }
381 
384  virtual bool checkSequentialSolutionIncrements( DomainPartition & domain ) const override
385  {
386  bool isConverged = true;
387  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
388  {
389  isConverged &= solver->checkSequentialSolutionIncrements( domain );
390  } );
391  return isConverged;
392  }
393 
394  virtual bool updateConfiguration( DomainPartition & domain,
395  integer const configurationLoopIter ) override
396  {
397  bool result = true;
398  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
399  {
400  result &= solver->updateConfiguration( domain, configurationLoopIter );
401  } );
402  return result;
403  }
404 
405  virtual void outputConfigurationStatistics( DomainPartition const & domain ) const override
406  {
407  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
408  {
409  solver->outputConfigurationStatistics( domain );
410  } );
411  }
412 
413  virtual void resetConfigurationToBeginningOfStep( DomainPartition & domain ) override
414  {
415  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
416  {
417  solver->resetConfigurationToBeginningOfStep( domain );
418  } );
419  }
420 
421  virtual bool resetConfigurationToDefault( DomainPartition & domain ) const override
422  {
423  bool result = true;
424  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
425  {
426  result &= solver->resetConfigurationToDefault( domain );
427  } );
428  return result;
429  }
430 
431  virtual void
433  {
434  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
435  {
436  solver->getNonlinearSolverParameters() = getNonlinearSolverParameters();
437  solver->synchronizeNonlinearSolverParameters();
438  } );
439  }
440 
441 protected:
442 
452  virtual real64 fullyCoupledSolverStep( real64 const & time_n,
453  real64 const & dt,
454  int const cycleNumber,
455  DomainPartition & domain )
456  {
457  return PhysicsSolverBase::solverStep( time_n, dt, cycleNumber, domain );
458  }
459 
470  virtual real64 sequentiallyCoupledSolverStep( real64 const & time_n,
471  real64 const & dt,
472  integer const cycleNumber,
473  DomainPartition & domain )
474  {
476 
477  // Only build the sparsity pattern if the mesh has changed
478  Timestamp const meshModificationTimestamp = getMeshModificationTimestamp( domain );
479  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
480  {
481  if( meshModificationTimestamp > solver->getSystemSetupTimestamp() )
482  {
483  solver->setupSystem( domain,
484  solver->getDofManager(),
485  solver->getLocalMatrix(),
486  solver->getSystemRhs(),
487  solver->getSystemSolution() );
488  solver->setSystemSetupTimestamp( meshModificationTimestamp );
489  }
490  } );
491 
492  implicitStepSetup( time_n, dt, domain );
493 
495  integer const maxNumberDtCuts = solverParams.m_maxTimeStepCuts;
496  real64 const dtCutFactor = solverParams.m_timeStepCutFactor;
497  integer & dtAttempt = solverParams.m_numTimeStepAttempts;
498 
499  bool isConverged = false;
500  // dt may be cut during the course of this step, so we are keeping a local
501  // value to track the achieved dt for this step.
502  real64 stepDt = dt;
503 
504  // outer loop attempts to apply full timestep, and managed the cutting of the timestep if
505  // required.
506  for( dtAttempt = 0; dtAttempt < maxNumberDtCuts; ++dtAttempt )
507  {
508  // TODO configuration loop
509 
510  // Reset the states of all solvers if any of them had to restart
511  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
512  {
513  solver->resetStateToBeginningOfStep( domain );
514  solver->getIterationStats().resetCurrentTimeStepStatistics(); // initialize counters for subsolvers
515  } );
516  resetStateToBeginningOfStep( domain );
517 
518  integer & iter = solverParams.m_numNewtonIterations;
519 
521  for( iter = 0; iter < solverParams.m_maxIterNewton; iter++ )
522  {
523  // Increment the solver statistics for reporting purposes
525 
526  startSequentialIteration( iter, domain );
527 
528  // Solve the subproblems nonlinearly
529  forEachArgInTuple( m_solvers, [&]( auto & solver, auto idx )
530  {
531  GEOS_LOG_LEVEL_RANK_0( logInfo::NonlinearSolver,
532  GEOS_FMT( " Iteration {:2}: {}", iter + 1, solver->getName() ) );
533  real64 solverDt = solver->nonlinearImplicitStep( time_n,
534  stepDt,
535  cycleNumber,
536  domain );
537 
538  // save fields (e.g. pressure and temperature) after inner solve
539  if( solver->getNonlinearSolverParameters().couplingType() == NonlinearSolverParameters::CouplingType::Sequential )
540  {
541  solver->saveSequentialIterationState( domain );
542  }
543 
544  mapSolutionBetweenSolvers( domain, idx() );
545 
546  if( solverDt < stepDt ) // subsolver had to cut the time step
547  {
548  iter = 0; // restart outer loop
549  stepDt = solverDt; // sync time step
551  }
552  } );
553  // Check convergence of the outer loop
554  isConverged = checkSequentialConvergence( cycleNumber,
555  iter,
556  time_n,
557  stepDt,
558  domain );
559 
560  if( isConverged )
561  {
562  // we still want to count current iteration
563  ++iter;
564  // exit outer loop
565  break;
566  }
567  else
568  {
569  finishSequentialIteration( iter, domain );
570  }
571  }
572 
573  if( isConverged )
574  {
575  // Save time step statistics for the subsolvers
576  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
577  {
578  solver->getIterationStats().iterateTimeStepStatistics();
579  } );
580  // get out of the time loop
581  break;
582  }
583  else
584  {
585  // cut timestep, go back to beginning of step and restart the Newton loop
586  stepDt *= dtCutFactor;
588  GEOS_LOG_LEVEL_RANK_0( logInfo::TimeStep, GEOS_FMT( "New dt = {}", stepDt ) );
589 
590  // notify the solver statistics counter that this is a time step cut
592  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
593  {
594  solver->getIterationStats().updateTimeStepCut();
595  } );
596  }
597  }
598 
599  if( !isConverged )
600  {
601  GEOS_LOG_RANK_0( "Convergence not achieved." );
602 
604  {
605  GEOS_LOG_RANK_0( "The accepted solution may be inaccurate." );
606  }
607  else
608  {
609  GEOS_ERROR( "Nonconverged solutions not allowed. Terminating...", getDataContext() );
610  }
611  }
612 
613  implicitStepComplete( time_n, stepDt, domain );
614 
615  return stepDt;
616  }
617 
625  integer const solverType )
626  {
627  GEOS_UNUSED_VAR( domain, solverType );
628  }
629 
630  virtual bool checkSequentialConvergence( integer const cycleNumber,
631  integer const iter,
632  real64 const & time_n,
633  real64 const & dt,
634  DomainPartition & domain )
635  {
637  bool isConverged = true;
638 
639  if( params.m_subcyclingOption == 0 )
640  {
641  GEOS_LOG_LEVEL_RANK_0( logInfo::Convergence, "***** Single Pass solver, no subcycling *****" );
642  }
643  else
644  {
645  GEOS_LOG_LEVEL_RANK_0( logInfo::Convergence, GEOS_FMT( " Iteration {:2}: outer-loop convergence check", iter + 1 ) );
646 
648  {
649  real64 residualNorm = 0;
650 
651  // loop over all the single-physics solvers
652  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
653  {
654 
655  solver->getLocalMatrix().toViewConstSizes().zero();
656  solver->getSystemRhs().zero();
657  arrayView1d< real64 > const localRhs = solver->getSystemRhs().open();
658 
659  // for each solver, we have to recompute the residual (and Jacobian, although not necessary)
660  solver->assembleSystem( time_n,
661  dt,
662  domain,
663  solver->getDofManager(),
664  solver->getLocalMatrix().toViewConstSizes(),
665  localRhs );
666  solver->applyBoundaryConditions( time_n,
667  dt,
668  domain,
669  solver->getDofManager(),
670  solver->getLocalMatrix().toViewConstSizes(),
671  localRhs );
672  solver->getSystemRhs().close();
673 
674  // once this is done, we recompute the single-physics residual
675  real64 const singlePhysicsNorm =
676  solver->calculateResidualNorm( time_n,
677  dt,
678  domain,
679  solver->getDofManager(),
680  solver->getSystemRhs().values() );
681  residualNorm += singlePhysicsNorm * singlePhysicsNorm;
682  } );
683 
684  // finally, we perform the convergence check on the multiphysics residual
685  residualNorm = sqrt( residualNorm );
686  GEOS_LOG_LEVEL_RANK_0( logInfo::ResidualNorm,
687  GEOS_FMT( " ( R ) = ( {:4.2e} )", residualNorm ) );
688  getConvergenceStats().setResidualValue( "R", residualNorm );
689  updateAndWriteConvergenceStep( time_n, dt, cycleNumber, iter );
690 
691  isConverged = ( residualNorm < params.m_newtonTol );
692 
693  }
695  {
696  // TODO also make recursive?
697  forEachArgInTuple( m_solvers, [&]( auto & solver, auto )
698  {
699  NonlinearSolverParameters const & singlePhysicsParams = solver->getNonlinearSolverParameters();
700  if( singlePhysicsParams.m_numNewtonIterations > singlePhysicsParams.m_minIterNewton )
701  {
702  isConverged = false;
703  }
704  } );
705  }
707  {
708  isConverged = checkSequentialSolutionIncrements( domain );
709  }
710  else
711  {
712  GEOS_ERROR( "Invalid sequential convergence criterion.", getDataContext() );
713  }
714 
715  if( isConverged )
716  {
717  GEOS_LOG_LEVEL_RANK_0( logInfo::Convergence,
718  GEOS_FMT( "***** The iterative coupling has converged in {} iteration(s) *****", iter + 1 ) );
719  }
720  }
721  return isConverged;
722  }
723 
724  virtual void
726  {
727  setSubSolvers();
728 
730 
733  GEOS_THROW_IF( isSequential && usesLineSearch,
734  GEOS_FMT( "{}: line search is not supported by the coupled solver when {} is set to `{}`. Please set {} to `{}` to remove this error",
735  getNonlinearSolverParameters().getWrapperDataContext( NonlinearSolverParameters::viewKeysStruct::couplingTypeString() ),
736  NonlinearSolverParameters::viewKeysStruct::couplingTypeString(),
738  NonlinearSolverParameters::viewKeysStruct::lineSearchActionString(),
740  InputError, getNonlinearSolverParameters().getWrapperDataContext( NonlinearSolverParameters::viewKeysStruct::couplingTypeString() ) );
741 
743  {
744  validateNonlinearAcceleration();
745  }
746  }
747 
748  virtual void validateNonlinearAcceleration()
749  {
750  GEOS_THROW ( GEOS_FMT( "{}: Nonlinear acceleration {} is not supported by {} solver '{}'",
751  getWrapperDataContext( NonlinearSolverParameters::viewKeysStruct::nonlinearAccelerationTypeString() ),
753  getCatalogName(), getName()),
754  InputError );
755  }
756 
757  virtual void initializePreSubGroups() override
758  {
760 
762  if( !isSequential )
763  {
765  }
766  }
767 
768  virtual void startSequentialIteration( integer const & iter,
769  DomainPartition & domain )
770  {
771  GEOS_UNUSED_VAR( iter, domain );
772  }
773 
774  virtual void finishSequentialIteration( integer const & iter,
775  DomainPartition & domain )
776  {
777  GEOS_UNUSED_VAR( iter, domain );
778  }
779 
780 protected:
781 
783  std::tuple< SOLVERS *... > m_solvers;
784 
786  std::array< string, sizeof...( SOLVERS ) > m_names;
787 };
788 
789 } /* namespace geos */
790 
791 #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,...)
Conditionally raise a hard error and terminate the program.
Definition: Logger.hpp:318
#define GEOS_ERROR(...)
Raise a hard error and terminate the program.
Definition: Logger.hpp:226
#define GEOS_LOG_RANK_0(msg)
Log a message on screen on rank 0.
Definition: Logger.hpp:99
#define GEOS_THROW_IF(COND, MSG,...)
Conditionally raise a hard error and terminate the program.
Definition: Logger.hpp:308
#define GEOS_MARK_FUNCTION
Mark function with both Caliper and NVTX if enabled.
void setResidualValue(string const &key, real64 const value)
Set a residual value given a key ( column in the CSV )
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:1544
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:1343
string const & getName() const
Get group name.
Definition: Group.hpp:1329
Group & getParent()
Access the group's parent.
Definition: Group.hpp:1362
DataContext const & getWrapperDataContext(KEY key) const
Definition: Group.hpp:1354
#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
stdVector< string > string_array
A 1-dimensional array of geos::string types.
Definition: DataTypes.hpp:361
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.
static constexpr char const * discretizationString()