GEOS
WellControls.hpp
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 
16 /*
17  * @file WellControls.hpp
18  */
19 
20 
21 #ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_WELLS_WELLCONTROLS_HPP
22 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_WELLS_WELLCONTROLS_HPP
23 
25 #include "dataRepository/Group.hpp"
27 #include "constitutive/fluid/multifluid/MultiFluidBase.hpp"
28 
29 #include "physicsSolvers/fluidFlow/wells/WellInjectionConstraint.hpp"
30 #include "physicsSolvers/fluidFlow/wells/WellProductionConstraint.hpp"
31 #include "physicsSolvers/fluidFlow/wells/WellBHPConstraints.hpp"
32 #include "physicsSolvers/fluidFlow/wells/WellVolumeRateConstraint.hpp"
33 #include "physicsSolvers/fluidFlow/wells/WellPhaseVolumeRateConstraint.hpp"
34 #include "physicsSolvers/fluidFlow/wells/WellMassRateConstraint.hpp"
35 #include "physicsSolvers/fluidFlow/wells/WellLiquidRateConstraint.hpp"
36 #include "constitutive/fluid/multifluid/MultiFluidBase.hpp"
37 #include "constitutive/fluid/singlefluid/SingleFluidBase.hpp"
38 namespace geos
39 {
40 namespace dataRepository
41 {
42 namespace keys
43 {
44 static constexpr auto wellControls = "WellControls";
45 }
46 }
47 
48 
54 {
55 public:
56 
60  enum class Type : integer
61  {
62  PRODUCER,
63  INJECTOR
64  };
65 
69  enum class Status : integer
70  {
71  OPEN,
72  CLOSED
73  };
74 
78  enum class Control : integer
79  {
80  BHP,
81  PHASEVOLRATE,
82  TOTALVOLRATE,
83  MASSRATE,
85  };
86 
87 
92 
98  explicit WellControls( string const & name, dataRepository::Group * const parent );
99 
100 
104  ~WellControls() override;
105 
109  WellControls() = delete;
110 
114  WellControls( WellControls const & ) = delete;
115 
119  WellControls( WellControls && ) = delete;
120 
125  WellControls & operator=( WellControls const & ) = delete;
126 
132 
134 
141  virtual Group * createChild( string const & childKey, string const & childName ) override;
143 
144  virtual void expandObjectCatalogs() override;
145 
157  template< typename T0, typename T1, typename ... CASTTYPES, typename CONTAINERTYPE, typename LAMBDA >
158  static bool applyLambdaToContainer( CONTAINERTYPE container, LAMBDA && lambda )
159  {
160  using Pointee = std::remove_pointer_t< std::remove_reference_t< CONTAINERTYPE > >;
161  using T = std::conditional_t< std::is_const< Pointee >::value, T0 const, T0 >;
162  T * const castedContainer = dynamic_cast< T * >( container );
163 
164  if( castedContainer != nullptr )
165  {
166  lambda( *castedContainer );
167  return true;
168  }
169 
170  return applyLambdaToContainer< T1, CASTTYPES... >( container, std::forward< LAMBDA >( lambda ) );
171  }
172 
173  // Base case: no more types to try
174  template< typename CONTAINERTYPE, typename LAMBDA >
175  static bool applyLambdaToContainer( CONTAINERTYPE /*container*/, LAMBDA && /*lambda*/ )
176  {
177  return false;
178  }
179 
180  // Single-type overload: try only T0 and stop
181  template< typename T0, typename CONTAINERTYPE, typename LAMBDA >
182  static bool applyLambdaToContainer( CONTAINERTYPE container, LAMBDA && lambda )
183  {
184  using Pointee = std::remove_pointer_t< std::remove_reference_t< CONTAINERTYPE > >;
185  using T = std::conditional_t< std::is_const< Pointee >::value, T0 const, T0 >;
186  T * const castedContainer = dynamic_cast< T * >( container );
187 
188  if( castedContainer != nullptr )
189  {
190  lambda( *castedContainer );
191  return true;
192  }
193 
194  return false;
195  }
196 
197 
201  template< typename GROUPTYPE = Group, typename ... GROUPTYPES, typename LAMBDA >
202  void forInjectionConstraints( LAMBDA && lambda ) const
203  {
204  for( auto const * constraintIter : m_injectionRateConstraintList )
205  {
206  applyLambdaToContainer< GROUPTYPE, GROUPTYPES... >( constraintIter, [&]( auto const & castedSubGroup )
207  {
208  lambda( castedSubGroup );
209  } );
210  }
211  }
212 
213  // non-const overload
214  template< typename GROUPTYPE = Group, typename ... GROUPTYPES, typename LAMBDA >
215  void forInjectionConstraints( LAMBDA && lambda )
216  {
217  for( auto * constraintIter : m_injectionRateConstraintList )
218  {
219  applyLambdaToContainer< GROUPTYPE, GROUPTYPES... >( constraintIter, [&]( auto & castedSubGroup )
220  {
221  lambda( castedSubGroup );
222  } );
223  }
224  }
228  template< typename GROUPTYPE = Group, typename ... GROUPTYPES, typename LAMBDA >
229  void forProductionConstraints( LAMBDA && lambda ) const
230  {
231  for( auto const * constraintIter : m_productionRateConstraintList )
232  {
233  applyLambdaToContainer< GROUPTYPE, GROUPTYPES... >( constraintIter, [&]( auto const & castedSubGroup )
234  {
235  lambda( castedSubGroup );
236  } );
237  }
238  }
239 
240  // non-const overload
241  template< typename GROUPTYPE = Group, typename ... GROUPTYPES, typename LAMBDA >
242  void forProductionConstraints( LAMBDA && lambda )
243  {
244  for( auto * constraintIter : m_productionRateConstraintList )
245  {
246  applyLambdaToContainer< GROUPTYPE, GROUPTYPES... >( constraintIter, [&]( auto & castedSubGroup )
247  {
248  lambda( castedSubGroup );
249  } );
250  }
251  }
256 
257 
262  Control getControl() const { return m_currentControl; }
263 
268  void setControl( Control const & newControl ) { m_currentControl = newControl; }
269 
274  integer estimateSolution() const { return m_estimateSolution; }
275 
280  real64 getReferenceGravityCoef() const { return m_refGravCoef; }
281 
285  void setReferenceGravityCoef( real64 const & refGravCoef ) { m_refGravCoef = refGravCoef; }
286 
287 
293  real64 getTargetBHP( real64 const & targetTime ) const;
294 
295 
301 
307 
308 
314 
320 
321 
326  integer useSurfaceConditions() const { return m_useSurfaceConditions; }
327 
332  string referenceReservoirRegion() const { return m_referenceReservoirRegion; }
333 
338  const real64 & getSurfacePressure() const { return m_surfacePres; }
339 
344  const real64 & getSurfaceTemperature() const { return m_surfaceTemp; }
345 
350  bool isInjector() const { return ( m_type == Type::INJECTOR ); }
351 
356  bool isProducer() const { return ( m_type == Type::PRODUCER ); }
357 
362  bool isWellOpen() const;
363 
364  void setWellState( bool open );
365  bool getWellState() const;
366 
367 
368  void setConstraintSwitch( bool constraintSwitch );
369  bool getConstraintSwitch() const;
370 
371  void setCurrentConstraint( WellConstraintBase * currentConstraint ) { m_currentConstraint = currentConstraint;}
372  WellConstraintBase * getCurrentConstraint() { return m_currentConstraint; }
373  WellConstraintBase const * getCurrentConstraint() const { return m_currentConstraint; }
374 
375 
380  bool isCrossflowEnabled() const { return m_isCrossflowEnabled; }
381 
386  real64 getInitialPressureCoefficient() const { return m_initialPressureCoefficient; }
387 
393  void setNextDtFromTables( real64 const & currentTime, real64 & nextDt );
394 
395 
400  void setFluidSeparator( std::unique_ptr< constitutive::ConstitutiveBase > fluidSeparatorPtr ) { m_fluidSeparatorPtr = std::move( fluidSeparatorPtr );}
405  constitutive::MultiFluidBase & getMultiFluidSeparator() { return dynamicCast< constitutive::MultiFluidBase & >( *m_fluidSeparatorPtr ); }
406 
411  constitutive::SingleFluidBase & getSingleFluidSeparator() { return dynamicCast< constitutive::SingleFluidBase & >( *m_fluidSeparatorPtr ); }
412 
413 
418  real64 getRegionAveragePressure() const { return m_regionAveragePressure; }
419 
424  void setRegionAveragePressure( real64 regionAveragePressure ) { m_regionAveragePressure = regionAveragePressure; }
425 
430  real64 getRegionAverageTemperature() const { return m_regionAverageTemperature; }
431 
436  void setRegionAverageTemperature( real64 regionAverageTemperature ) { m_regionAverageTemperature = regionAverageTemperature; }
437 
443  void setWellStatus ( real64 const & currentTime, WellControls::Status status );
444 
449  WellControls::Status getWellStatus () const { return m_wellStatus; }
451 
457  {
459  static constexpr char const * refElevString() { return "referenceElevation"; }
461  static constexpr char const * typeString() { return "type"; }
462 
464  static constexpr char const * currentControlString() { return "currentControl"; }
465 
467  static constexpr char const * useSurfaceConditionsString() { return "useSurfaceConditions"; }
469  static constexpr char const * referenceReservoirRegionString() { return "referenceReservoirRegion"; }
471  static constexpr char const * surfacePressureString() { return "surfacePressure"; }
473  static constexpr char const * surfaceTemperatureString() { return "surfaceTemperature"; }
474 
476  static constexpr char const * statusTableNameString() { return "statusTableName"; }
478  static constexpr char const * perfStatusTableNameString() { return "perfStatusTableName"; }
480  static constexpr char const * enableCrossflowString() { return "enableCrossflow"; }
482  static constexpr char const * initialPressureCoefficientString() { return "initialPressureCoefficient"; }
484  static constexpr char const * estimateWellSolutionString() { return "estimateWellSolution"; }
485 
487  static constexpr char const * minimumBHPConstraintString() { return "MinimumBHPConstraint"; }
489  static constexpr char const * maximumBHPConstraintString() { return "MaximumBHPConstraint"; }
491  static constexpr char const * phaseProductionConstraintString() { return "PhaseProductionConstraint"; }
493  static constexpr char const * phaseInjectionConstraintString() { return "PhaseInjectionConstraint"; }
495  static constexpr char const * totalVolProductionConstraintString() { return "TotalVolProductionConstraint"; }
497  static constexpr char const * totalVolInjectionConstraintString() { return "TotalVolInjectionConstraint"; }
499  static constexpr char const * massProductionConstraintString() { return "massProductionConstraint"; }
501  static constexpr char const * massInjectionConstraintString() { return "massInjectionConstraint"; }
503  static constexpr char const * liquidProductionConstraintString() { return "liquidProductionConstraint"; }
504  }
507 
508  static void setNextDtFromTable( TableFunction const * table, real64 const currentTime, real64 & nextDt );
509 
515  template< typename ConstraintType > void createConstraint ( string const & constraintName );
516 
517 
521  MinimumBHPConstraint * getMinBHPConstraint() { return m_minBHPConstraint; };
522  MinimumBHPConstraint * getMinBHPConstraint() const { return m_minBHPConstraint; };
523  MaximumBHPConstraint * getMaxBHPConstraint() { return m_maxBHPConstraint; };
524  MaximumBHPConstraint * getMaxBHPConstraint() const { return m_maxBHPConstraint; };
525  // Lists of rate constraints
526  std::vector< WellConstraintBase * > getProdRateConstraints() { return m_productionRateConstraintList; };
527  std::vector< WellConstraintBase * > getProdRateConstraints() const { return m_productionRateConstraintList; };
528  std::vector< WellConstraintBase * > getInjRateConstraints() { return m_injectionRateConstraintList; }
529  std::vector< WellConstraintBase * > getInjRateConstraints() const { return m_injectionRateConstraintList; }
530 protected:
531 
532  virtual void postInputInitialization() override;
533 
534 
535 
536 private:
537 
539  Type m_type;
540 
542  real64 m_refElevation;
543 
545  real64 m_refGravCoef;
546 
548  Control m_currentControl;
549 
551  integer m_useSurfaceConditions;
552 
553  // Fuild model to compute properties for constraint equation user specified conditions
554  std::unique_ptr< constitutive::ConstitutiveBase > m_fluidSeparatorPtr;
555 
557  string m_referenceReservoirRegion;
558 
560  real64 m_surfacePres;
561 
563  real64 m_surfaceTemp;
564 
565 
567  string m_statusTableName;
568 
570  string m_perfStatusTableName;
571 
573  integer m_isCrossflowEnabled;
574 
576  real64 m_initialPressureCoefficient;
577 
579  real64 m_rateSign;
580 
581 
583  TableFunction const * m_statusTable;
584 
585  bool m_wellOpen;
586 
588  integer m_estimateSolution;
589 
591  //constraint_array m_ConstraintList;
592  // Bool to trigger old/new constraint switch logic
593  bool m_constraintSwitch;
594 
595  // Current constraint
596  WellConstraintBase * m_currentConstraint;
597  // Minimum and maximum BHP and WHP constraints
598  MinimumBHPConstraint * m_minBHPConstraint;
599  MaximumBHPConstraint * m_maxBHPConstraint;
600 
601 
602  // Lists of rate constraints
603  std::vector< WellConstraintBase * > m_productionRateConstraintList;
604  std::vector< WellConstraintBase * > m_injectionRateConstraintList;
605 
606 
608  WellControls::Status m_wellStatus;
609 
610 
612  real64 m_regionAveragePressure;
613 
615  real64 m_regionAverageTemperature;
616 
617 };
618 
619 
620 // Use local aliases to avoid accidental macro expansion of the tokens 'Type' or 'Control'
623  "producer",
624  "injector" );
625 
628  "BHP",
629  "phaseVolRate",
630  "totalVolRate",
631  "massRate",
632  "uninitialized" );
633 
634 
635 } //namespace geos
636 
637 #endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_WELLS_WELLCONTROLS_HPP
This class describes a minimum pressure constraint used to control a injection well.
This class describes the controls used to operate a well.
~WellControls() override
Default destructor.
integer estimateSolution() const
getter for esitmator switch
void setWellStatus(real64 const &currentTime, WellControls::Status status)
Set well status from time and internal action, eg. all perfs closed.
bool isProducer() const
Is the well a producer?
virtual void postInputInitialization() override
WellControls & operator=(WellControls &&)=delete
Deleted move operator.
real64 getRegionAverageTemperature() const
Getter for the reservoir average temperature when m_useSurfaceConditions == 0.
void createConstraint(string const &constraintName)
Create a constraint.
string referenceReservoirRegion() const
Getter for the reservoir region associated with reservoir volume constraint.
Control getControl() const
Get the control type for the well.
void setNextDtFromTables(real64 const &currentTime, real64 &nextDt)
set next time step based on tables intervals
struct geos::WellControls::viewKeyStruct viewKeysWellControls
ViewKey struct for the WellControls class.
bool isInjector() const
Is the well an injector?
real64 getReferenceElevation() const
Return the reference elvation where pressure constraint is measured.
WellControls::Status getWellStatus() const
Is the well open (or shut) based on internal action.
WellControls(WellControls &&)=delete
Deleted move constructor.
real64 getRegionAveragePressure() const
Getter for the reservoir average pressure when m_useSurfaceConditions == 0.
integer useSurfaceConditions() const
Getter for the flag specifying whether we check rates at surface or reservoir conditions.
void setReferenceGravityCoef(real64 const &refGravCoef)
Setter for the reference gravity.
void setFluidSeparator(std::unique_ptr< constitutive::ConstitutiveBase > fluidSeparatorPtr)
setter for multi fluid separator
WellControls(string const &name, dataRepository::Group *const parent)
Constructor for WellControls Objects.
void setRegionAverageTemperature(real64 regionAverageTemperature)
Set the reservoir average temperature when m_useSurfaceConditions == 0.
void setControl(Control const &newControl)
Set the control type for the well.
WellControls(WellControls const &)=delete
Deleted copy constructor.
WellControls & operator=(WellControls const &)=delete
Deleted assignment operator.
void forInjectionConstraints(LAMBDA &&lambda) const
constitutive::SingleFluidBase & getSingleFluidSeparator()
Getter for single fluid separator.
virtual void expandObjectCatalogs() override
Expand catalog for schema generation.
virtual Group * createChild(string const &childKey, string const &childName) override
Create a new geometric object (box, plane, etc) as a child of this group.
void forProductionConstraints(LAMBDA &&lambda) const
real64 getTargetBHP(real64 const &targetTime) const
Returns the target bottom hole pressure value.
bool isCrossflowEnabled() const
Getter for the flag to enable crossflow.
integer getConstraintPhaseIndex() const
Const accessor for the phase constraint index.
WellControls()=delete
Deleted default constructor.
MinimumBHPConstraint * getMinBHPConstraint()
Getters for constraints.
bool isWellOpen() const
Is the well open (or shut) at currentTime, status initalized in WellSolverBase::implicitStepSetup.
const real64 & getSurfaceTemperature() const
Getter for the surface temperature when m_useSurfaceConditions == 1.
arrayView1d< real64 const > getInjectionStream() const
Const accessor for the injection stream.
real64 getReferenceGravityCoef() const
Getter for the reference gravity coefficient.
static bool applyLambdaToContainer(CONTAINERTYPE container, LAMBDA &&lambda)
Apply a given functor to a container if the container can be cast to one of the specified types.
real64 getInitialPressureCoefficient() const
Getter for the initial pressure coefficient.
const real64 & getSurfacePressure() const
Getter for the surface pressure when m_useSurfaceConditions == 1.
constitutive::MultiFluidBase & getMultiFluidSeparator()
Getter for multi fluid separator.
real64 getInjectionTemperature() const
Const accessor for the temperature of the injection stream.
void setRegionAveragePressure(real64 regionAveragePressure)
Set the reservoir average pressure when m_useSurfaceConditions == 0.
Group()=delete
Deleted default constructor.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:179
double real64
64-bit floating point type.
Definition: DataTypes.hpp:98
int integer
Signed integer type.
Definition: DataTypes.hpp:81
ENUM_STRINGS(LinearSolverParameters::SolverType, "direct", "cg", "gmres", "fgmres", "bicgstab", "richardson", "preconditioner")
Declare strings associated with enumeration values.
Struct to serve as a container for variable strings and keys.
static constexpr char const * initialPressureCoefficientString()
string key for the initial pressure coefficient
static constexpr char const * phaseProductionConstraintString()
string key for the maximum phase rate for a producer
static constexpr char const * totalVolInjectionConstraintString()
string key for the maximum volume rate for a injector
static constexpr char const * useSurfaceConditionsString()
String key for checking the rates at surface conditions.
static constexpr char const * perfStatusTableNameString()
string key for perforation status table name
static constexpr char const * maximumBHPConstraintString()
string key for the maximum BHP presssure for a injection
static constexpr char const * refElevString()
String key for the well reference elevation (for BHP control)
static constexpr char const * minimumBHPConstraintString()
string key for the minimum BHP presssure for a producer
static constexpr char const * enableCrossflowString()
string key for the crossflow flag
static constexpr char const * totalVolProductionConstraintString()
string key for the maximum volume rate for a producer
static constexpr char const * referenceReservoirRegionString()
String key for reference reservoir region.
static constexpr char const * phaseInjectionConstraintString()
string key for the maximum phase rate for a injection
static constexpr char const * surfaceTemperatureString()
String key for the surface temperature.
static constexpr char const * statusTableNameString()
string key for status table name
static constexpr char const * massProductionConstraintString()
string key for the maximum mass rate for a producer
static constexpr char const * surfacePressureString()
String key for the surface pressure.
static constexpr char const * estimateWellSolutionString()
string key for the esitmate well solution flag
static constexpr char const * typeString()
String key for the well type.
static constexpr char const * massInjectionConstraintString()
string key for the maximum mass rate for a injector
static constexpr char const * liquidProductionConstraintString()
string key for the liquid rate for a producer
static constexpr char const * currentControlString()
String key for the well current control.