feat: well_manager + well estimator#3972
Conversation
…aint class hierachy , 3) Remove all old constraint handling methods/variables, 4) it compiles ...
…lephase still needs testing
…t compositionalMultiphaseFlow/soreideWhitson/1D_100cells/1D_benchmark.xml
… to fixed and inputFiles regenerated
…d convert compositionalMultiphaseFlow/soreideWhitson/1D_100cells/1D_benchmark.xml" This reverts commit fa61ab1.
…well initialization vagaries assoiated with useSurfaceConditions=0
…for resvol constraint, compositional only
| // set the reference well element where the BHP control is applied | ||
| wellControls.setReferenceGravityCoef( refElev * gravVector[2] ); | ||
| wellControls.setReferenceGravityCoef( refElev * gravVector[2] ); // tjb remove |
| rankNegPressureIds, | ||
| rankNegDensityIds, | ||
| rankTotalNegDensityIds ); | ||
| globalCheck = MpiWrapper::min( localCheck ); |
There was a problem hiding this comment.
Should we move this MPI call outside the for loop (for performance reasons)?
| for( integer i=0; i<numNorm; i++ ) | ||
| { | ||
| localResidualNorm[i] = 0.0; | ||
| } |
There was a problem hiding this comment.
If I'm reading it correctly, there might be an issue when an open unconverged well is followed by a closed well. This branch resets the manager's accumulated maximum residual to zero, while I think closed wells should contribute nothing without clearing residuals already calculated for other wells.
| ENUM_STRINGS( WellControls_Control, | ||
| "BHP", | ||
| "phaseVolRate", | ||
| "totalVolRate", | ||
| "massRate", | ||
| "uninitialized" ); |
There was a problem hiding this comment.
The enum ConstraintTypeId has 7 values, while we are listing only five here. Should we update this list?
| // Assumes useMass is true | ||
| currentMassRate = currentTotalRate; |
There was a problem hiding this comment.
Should we add a check here on useMass instead of assuming it's true?
| } | ||
| void WellManager::initializePostSubGroups() | ||
| { | ||
| #if 0 |
There was a problem hiding this comment.
Just curious why this code block is ifdef'ed out
| // 13.4) Make sure there is at least one non-BHP constraint | ||
| bool const rate_match_found = std::any_of( constraints.begin(), constraints.end(), [&bhp_type]( const auto & constraint_tuple ) | ||
| { | ||
| return std::get< 1 >( constraint_tuple ) != bhp_type; | ||
| } ); | ||
| GEOS_THROW_IF( !rate_match_found, | ||
| GEOS_FMT( "Missing rate constraint for {} well {}", | ||
| (isProducerWell ? "producer" : "injector"), getName() ), |
There was a problem hiding this comment.
if a well has phaseVolRate while defining only a total-volume rate constraint, this check would flag things are good, but i guess initialization would hit issues later.
| string const bhp_type = isProducerWell ? MinimumBHPConstraint::catalogName() : MaximumBHPConstraint::catalogName(); | ||
| bool const no_match_found = std::none_of( constraints.begin(), constraints.end(), [&bhp_type]( const auto & constraint_tuple ) | ||
| { | ||
| return std::get< 1 >( constraint_tuple ) == bhp_type; | ||
| } ); | ||
| GEOS_THROW_IF( no_match_found, |
There was a problem hiding this comment.
When the sole BHP or rate constraint has constraintActive=0, these existence checks still accept it, while getBHPConstraint and the rate-list helpers filter it out. Subsequent selection either dereferences null or erases an end() iterator because the current constraint is absent from the active list.
| if( !hasZeroRate ) | ||
| { | ||
| for( auto const * constraint : getRateConstraints() ) | ||
| { | ||
| if( isZero( constraint->getConstraintValue( currentTime ) ) ) | ||
| { | ||
| hasZeroRate = true; | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
When one active secondary rate schedule evaluates to zero while another rate target remains positive, this loop closes the entire well on the first zero (code below). Should we close the well only when every active rate target is zero?
| well.setThermal( isThermal() ); | ||
| well.setUseMass( m_useMass ); | ||
| well.registerWellDataOnMesh( subRegion ); |
There was a problem hiding this comment.
Shouldn't this also be setting useTotalMassEquation and allowLocalCompDensityChopping?
Replaces PR #3735 and extends PR #3971
Overview
This PR introduces
An improved well schema layout and code refactor better suited for well modeling. The previous implementation primarily targeted Jacobian generation requirements for the coupled reservoir and well system.
The well estimator is used to select the active well constraint by solving the well system assuming fixed reservoir conditions and selecting the constraint with the highest or lowest well flowing pressure.
This is a breaking change, detailed migration instructions and migration script are posted at #4081