2015-08-06 04:38:12 -05:00
/*
Copyright 2015 IRIS
This file is part of the Open Porous Media project ( OPM ) .
OPM is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
OPM is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with OPM . If not , see < http : //www.gnu.org/licenses/>.
*/
# include <config.h>
2015-08-14 04:58:12 -05:00
# include <opm/autodiff/SolventPropsAdFromDeck.hpp>
2015-08-06 04:38:12 -05:00
# include <opm/autodiff/AutoDiffHelpers.hpp>
2016-02-17 05:24:13 -06:00
# include <opm/core/utility/extractPvtTableIndex.hpp>
2016-02-26 04:56:44 -06:00
# include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
2016-01-20 08:11:30 -06:00
# include <opm/parser/eclipse/EclipseState/Tables/PvdsTable.hpp>
# include <opm/parser/eclipse/EclipseState/Tables/SsfnTable.hpp>
2016-01-27 07:00:40 -06:00
# include <opm/parser/eclipse/EclipseState/Tables/Sof2Table.hpp>
2016-03-09 05:29:18 -06:00
# include <opm/parser/eclipse/EclipseState/Tables/TlpmixpaTable.hpp>
2016-01-20 08:11:30 -06:00
2015-08-06 04:38:12 -05:00
namespace Opm
{
// Making these typedef to make the code more readable.
typedef SolventPropsAdFromDeck : : ADB ADB ;
2015-08-27 06:54:16 -05:00
typedef Eigen : : SparseMatrix < double > S ;
typedef Eigen : : DiagonalMatrix < double , Eigen : : Dynamic > D ;
2015-08-06 04:38:12 -05:00
typedef SolventPropsAdFromDeck : : V V ;
typedef Eigen : : Array < double , Eigen : : Dynamic , Eigen : : Dynamic , Eigen : : RowMajor > Block ;
2016-10-14 02:23:26 -05:00
SolventPropsAdFromDeck : : SolventPropsAdFromDeck ( const Deck & deck ,
const EclipseState & eclState ,
2015-08-06 04:38:12 -05:00
const int number_of_cells ,
const int * global_cell )
{
2016-10-14 02:23:26 -05:00
if ( deck . hasKeyword ( " SOLVENT " ) ) {
2015-09-17 08:46:56 -05:00
// retrieve the cell specific PVT table index from the deck
// and using the grid...
2016-01-08 07:47:41 -06:00
extractPvtTableIndex ( cellPvtRegionIdx_ , eclState , number_of_cells , global_cell ) ;
2016-02-17 03:43:01 -06:00
extractTableIndex ( " SATNUM " , eclState , number_of_cells , global_cell , cellSatNumRegionIdx_ ) ;
2015-08-06 04:38:12 -05:00
2015-10-06 03:51:20 -05:00
// surface densities
2016-10-14 02:23:26 -05:00
if ( deck . hasKeyword ( " SDENSITY " ) ) {
const auto & densityKeyword = deck . getKeyword ( " SDENSITY " ) ;
2016-02-09 09:05:00 -06:00
int numRegions = densityKeyword . size ( ) ;
2015-10-06 03:51:20 -05:00
solvent_surface_densities_ . resize ( numRegions ) ;
for ( int regionIdx = 0 ; regionIdx < numRegions ; + + regionIdx ) {
solvent_surface_densities_ [ regionIdx ]
2016-02-09 09:05:00 -06:00
= densityKeyword . getRecord ( regionIdx ) . getItem ( " SOLVENT_DENSITY " ) . getSIDouble ( 0 ) ;
2015-08-06 04:38:12 -05:00
}
2015-10-06 03:51:20 -05:00
} else {
OPM_THROW ( std : : runtime_error , " SDENSITY must be specified in SOLVENT runs \n " ) ;
}
2015-08-06 04:38:12 -05:00
2016-10-14 02:23:26 -05:00
const auto & tables = eclState . getTableManager ( ) ;
2015-10-06 03:51:20 -05:00
// pvt
2016-04-11 02:15:06 -05:00
const TableContainer & pvdsTables = tables . getPvdsTables ( ) ;
2015-10-06 03:51:20 -05:00
if ( ! pvdsTables . empty ( ) ) {
int numRegions = pvdsTables . size ( ) ;
// resize the attributes of the object
b_ . resize ( numRegions ) ;
viscosity_ . resize ( numRegions ) ;
inverseBmu_ . resize ( numRegions ) ;
for ( int regionIdx = 0 ; regionIdx < numRegions ; + + regionIdx ) {
const Opm : : PvdsTable & pvdsTable = pvdsTables . getTable < PvdsTable > ( regionIdx ) ;
2016-01-06 07:53:53 -06:00
const auto & press = pvdsTable . getPressureColumn ( ) ;
const auto & b = pvdsTable . getFormationFactorColumn ( ) ;
const auto & visc = pvdsTable . getViscosityColumn ( ) ;
2015-10-06 03:51:20 -05:00
const int sz = b . size ( ) ;
2016-01-06 07:53:53 -06:00
std : : vector < double > inverseBmu ( sz ) ;
2015-10-06 03:51:20 -05:00
std : : vector < double > inverseB ( sz ) ;
for ( int i = 0 ; i < sz ; + + i ) {
inverseB [ i ] = 1.0 / b [ i ] ;
inverseBmu [ i ] = 1.0 / ( b [ i ] * visc [ i ] ) ;
}
b_ [ regionIdx ] = NonuniformTableLinear < double > ( press , inverseB ) ;
viscosity_ [ regionIdx ] = NonuniformTableLinear < double > ( press , visc ) ;
inverseBmu_ [ regionIdx ] = NonuniformTableLinear < double > ( press , inverseBmu ) ;
2015-08-06 04:38:12 -05:00
}
2015-10-06 03:51:20 -05:00
} else {
OPM_THROW ( std : : runtime_error , " PVDS must be specified in SOLVENT runs \n " ) ;
2015-08-06 04:38:12 -05:00
}
2015-08-10 03:28:24 -05:00
2016-04-11 02:15:06 -05:00
const TableContainer & ssfnTables = tables . getSsfnTables ( ) ;
2015-10-06 03:51:20 -05:00
// relative permeabilty multiplier
if ( ! ssfnTables . empty ( ) ) {
2015-08-10 03:28:24 -05:00
2015-12-02 05:32:08 -06:00
int numRegions = ssfnTables . size ( ) ;
2015-08-10 03:28:24 -05:00
2015-10-06 03:51:20 -05:00
// resize the attributes of the object
krg_ . resize ( numRegions ) ;
krs_ . resize ( numRegions ) ;
for ( int regionIdx = 0 ; regionIdx < numRegions ; + + regionIdx ) {
const Opm : : SsfnTable & ssfnTable = ssfnTables . getTable < SsfnTable > ( regionIdx ) ;
// Copy data
2016-01-06 07:53:53 -06:00
const auto & solventFraction = ssfnTable . getSolventFractionColumn ( ) ;
const auto & krg = ssfnTable . getGasRelPermMultiplierColumn ( ) ;
const auto & krs = ssfnTable . getSolventRelPermMultiplierColumn ( ) ;
2015-10-06 03:51:20 -05:00
krg_ [ regionIdx ] = NonuniformTableLinear < double > ( solventFraction , krg ) ;
krs_ [ regionIdx ] = NonuniformTableLinear < double > ( solventFraction , krs ) ;
}
2015-08-10 03:28:24 -05:00
2015-10-06 03:51:20 -05:00
} else {
OPM_THROW ( std : : runtime_error , " SSFN must be specified in SOLVENT runs \n " ) ;
}
2015-12-02 05:32:08 -06:00
2016-10-14 02:23:26 -05:00
if ( deck . hasKeyword ( " MISCIBLE " ) ) {
2016-02-15 03:07:47 -06:00
// retrieve the cell specific Misc table index from the deck
// and using the grid...
2016-02-17 03:43:01 -06:00
extractTableIndex ( " MISCNUM " , eclState , number_of_cells , global_cell , cellMiscRegionIdx_ ) ;
2016-02-15 03:07:47 -06:00
2015-12-02 05:32:08 -06:00
// misicible hydrocabon relative permeability wrt water
2016-04-11 02:15:06 -05:00
const TableContainer & sof2Tables = tables . getSof2Tables ( ) ;
2015-12-02 05:32:08 -06:00
if ( ! sof2Tables . empty ( ) ) {
int numRegions = sof2Tables . size ( ) ;
// resize the attributes of the object
krn_ . resize ( numRegions ) ;
for ( int regionIdx = 0 ; regionIdx < numRegions ; + + regionIdx ) {
const Opm : : Sof2Table & sof2Table = sof2Tables . getTable < Sof2Table > ( regionIdx ) ;
// Copy data
// Sn = So + Sg + Ss;
2016-01-27 07:00:40 -06:00
const auto & sn = sof2Table . getSoColumn ( ) ;
const auto & krn = sof2Table . getKroColumn ( ) ;
2015-12-02 05:32:08 -06:00
krn_ [ regionIdx ] = NonuniformTableLinear < double > ( sn , krn ) ;
}
} else {
OPM_THROW ( std : : runtime_error , " SOF2 must be specified in MISCIBLE (SOLVENT) runs \n " ) ;
}
2016-04-11 02:15:06 -05:00
const TableContainer & miscTables = tables . getMiscTables ( ) ;
2015-12-09 04:30:16 -06:00
if ( ! miscTables . empty ( ) ) {
int numRegions = miscTables . size ( ) ;
// resize the attributes of the object
misc_ . resize ( numRegions ) ;
for ( int regionIdx = 0 ; regionIdx < numRegions ; + + regionIdx ) {
const Opm : : MiscTable & miscTable = miscTables . getTable < MiscTable > ( regionIdx ) ;
// Copy data
// solventFraction = Ss / (Ss + Sg);
2016-01-27 07:00:40 -06:00
const auto & solventFraction = miscTable . getSolventFractionColumn ( ) ;
const auto & misc = miscTable . getMiscibilityColumn ( ) ;
2015-12-09 04:30:16 -06:00
misc_ [ regionIdx ] = NonuniformTableLinear < double > ( solventFraction , misc ) ;
}
} else {
OPM_THROW ( std : : runtime_error , " MISC must be specified in MISCIBLE (SOLVENT) runs \n " ) ;
}
2016-04-11 02:15:06 -05:00
const TableContainer & pmiscTables = tables . getPmiscTables ( ) ;
2016-03-04 04:15:46 -06:00
if ( ! pmiscTables . empty ( ) ) {
int numRegions = pmiscTables . size ( ) ;
// resize the attributes of the object
pmisc_ . resize ( numRegions ) ;
for ( int regionIdx = 0 ; regionIdx < numRegions ; + + regionIdx ) {
const Opm : : PmiscTable & pmiscTable = pmiscTables . getTable < PmiscTable > ( regionIdx ) ;
// Copy data
const auto & po = pmiscTable . getOilPhasePressureColumn ( ) ;
const auto & pmisc = pmiscTable . getMiscibilityColumn ( ) ;
pmisc_ [ regionIdx ] = NonuniformTableLinear < double > ( po , pmisc ) ;
}
}
2015-12-02 05:32:08 -06:00
// miscible relative permeability multipleiers
2016-04-11 02:15:06 -05:00
const TableContainer & msfnTables = tables . getMsfnTables ( ) ;
2015-12-02 05:32:08 -06:00
if ( ! msfnTables . empty ( ) ) {
int numRegions = msfnTables . size ( ) ;
// resize the attributes of the object
mkrsg_ . resize ( numRegions ) ;
mkro_ . resize ( numRegions ) ;
for ( int regionIdx = 0 ; regionIdx < numRegions ; + + regionIdx ) {
const Opm : : MsfnTable & msfnTable = msfnTables . getTable < MsfnTable > ( regionIdx ) ;
// Copy data
// Ssg = Ss + Sg;
2016-01-27 07:00:40 -06:00
const auto & Ssg = msfnTable . getGasPhaseFractionColumn ( ) ;
const auto & krsg = msfnTable . getGasSolventRelpermMultiplierColumn ( ) ;
const auto & kro = msfnTable . getOilRelpermMultiplierColumn ( ) ;
2015-12-02 05:32:08 -06:00
mkrsg_ [ regionIdx ] = NonuniformTableLinear < double > ( Ssg , krsg ) ;
mkro_ [ regionIdx ] = NonuniformTableLinear < double > ( Ssg , kro ) ;
}
}
2015-12-02 07:38:49 -06:00
2016-04-11 02:15:06 -05:00
const TableContainer & sorwmisTables = tables . getSorwmisTables ( ) ;
2015-12-09 04:30:16 -06:00
if ( ! sorwmisTables . empty ( ) ) {
2015-12-02 07:38:49 -06:00
2015-12-09 04:30:16 -06:00
int numRegions = sorwmisTables . size ( ) ;
2015-12-02 07:38:49 -06:00
// resize the attributes of the object
2015-12-09 04:30:16 -06:00
sorwmis_ . resize ( numRegions ) ;
2015-12-02 07:38:49 -06:00
for ( int regionIdx = 0 ; regionIdx < numRegions ; + + regionIdx ) {
2015-12-09 04:30:16 -06:00
const Opm : : SorwmisTable & sorwmisTable = sorwmisTables . getTable < SorwmisTable > ( regionIdx ) ;
2015-12-02 07:38:49 -06:00
// Copy data
2016-01-27 07:00:40 -06:00
const auto & sw = sorwmisTable . getWaterSaturationColumn ( ) ;
const auto & sorwmis = sorwmisTable . getMiscibleResidualOilColumn ( ) ;
2015-12-02 07:38:49 -06:00
2015-12-09 04:30:16 -06:00
sorwmis_ [ regionIdx ] = NonuniformTableLinear < double > ( sw , sorwmis ) ;
}
}
2016-04-11 02:15:06 -05:00
const TableContainer & sgcwmisTables = tables . getSgcwmisTables ( ) ;
2015-12-09 04:30:16 -06:00
if ( ! sgcwmisTables . empty ( ) ) {
2015-12-02 07:38:49 -06:00
2015-12-09 04:30:16 -06:00
int numRegions = sgcwmisTables . size ( ) ;
// resize the attributes of the object
sgcwmis_ . resize ( numRegions ) ;
for ( int regionIdx = 0 ; regionIdx < numRegions ; + + regionIdx ) {
const Opm : : SgcwmisTable & sgcwmisTable = sgcwmisTables . getTable < SgcwmisTable > ( regionIdx ) ;
2015-12-02 07:38:49 -06:00
2015-12-09 04:30:16 -06:00
// Copy data
2016-01-27 07:00:40 -06:00
const auto & sw = sgcwmisTable . getWaterSaturationColumn ( ) ;
const auto & sgcwmis = sgcwmisTable . getMiscibleResidualGasColumn ( ) ;
2015-12-02 07:38:49 -06:00
2015-12-09 04:30:16 -06:00
sgcwmis_ [ regionIdx ] = NonuniformTableLinear < double > ( sw , sgcwmis ) ;
}
}
2015-12-02 07:38:49 -06:00
2016-10-14 02:23:26 -05:00
if ( deck . hasKeyword ( " TLMIXPAR " ) ) {
const int numRegions = deck . getKeyword ( " TLMIXPAR " ) . size ( ) ;
2016-02-15 06:28:54 -06:00
// resize the attributes of the object
mix_param_viscosity_ . resize ( numRegions ) ;
mix_param_density_ . resize ( numRegions ) ;
for ( int regionIdx = 0 ; regionIdx < numRegions ; + + regionIdx ) {
2016-10-14 02:23:26 -05:00
const auto & tlmixparRecord = deck . getKeyword ( " TLMIXPAR " ) . getRecord ( regionIdx ) ;
2016-02-09 09:05:00 -06:00
const auto & mix_params_viscosity = tlmixparRecord . getItem ( " TL_VISCOSITY_PARAMETER " ) . getSIDoubleData ( ) ;
2016-02-15 06:28:54 -06:00
mix_param_viscosity_ [ regionIdx ] = mix_params_viscosity [ 0 ] ;
2016-02-09 09:05:00 -06:00
const auto & mix_params_density = tlmixparRecord . getItem ( " TL_DENSITY_PARAMETER " ) . getSIDoubleData ( ) ;
2016-02-15 06:28:54 -06:00
const int numDensityItems = mix_params_density . size ( ) ;
if ( numDensityItems = = 0 ) {
mix_param_density_ [ regionIdx ] = mix_param_viscosity_ [ regionIdx ] ;
} else if ( numDensityItems = = 1 ) {
mix_param_density_ [ regionIdx ] = mix_params_density [ 0 ] ;
} else {
OPM_THROW ( std : : runtime_error , " Only one value can be entered for the TL parameter pr MISC region. " ) ;
}
2015-12-10 05:53:09 -06:00
}
}
2016-10-14 02:23:26 -05:00
if ( deck . hasKeyword ( " TLPMIXPA " ) ) {
2016-04-11 08:15:27 -05:00
const TableContainer & tlpmixparTables = tables . getTlpmixpaTables ( ) ;
2016-03-09 05:29:18 -06:00
if ( ! tlpmixparTables . empty ( ) ) {
int numRegions = tlpmixparTables . size ( ) ;
// resize the attributes of the object
tlpmix_param_ . resize ( numRegions ) ;
for ( int regionIdx = 0 ; regionIdx < numRegions ; + + regionIdx ) {
const Opm : : TlpmixpaTable & tlpmixparTable = tlpmixparTables . getTable < TlpmixpaTable > ( regionIdx ) ;
// Copy data
const auto & po = tlpmixparTable . getOilPhasePressureColumn ( ) ;
const auto & tlpmixpa = tlpmixparTable . getMiscibilityColumn ( ) ;
tlpmix_param_ [ regionIdx ] = NonuniformTableLinear < double > ( po , tlpmixpa ) ;
}
} else {
// if empty keyword. Try to use the pmisc table as default.
if ( pmisc_ . size ( ) > 0 ) {
tlpmix_param_ = pmisc_ ;
} else {
OPM_THROW ( std : : invalid_argument , " If the pressure dependent TL values in TLPMIXPA is defaulted (no entries), then the PMISC tables must be specified. " ) ;
}
}
}
2015-12-02 05:32:08 -06:00
}
2015-08-10 03:28:24 -05:00
}
2015-12-02 05:32:08 -06:00
2015-08-06 04:38:12 -05:00
}
ADB SolventPropsAdFromDeck : : muSolvent ( const ADB & pg ,
const Cells & cells ) const
{
const int n = cells . size ( ) ;
assert ( pg . value ( ) . size ( ) = = n ) ;
V mu ( n ) ;
V dmudp ( n ) ;
for ( int i = 0 ; i < n ; + + i ) {
const double & pg_i = pg . value ( ) [ i ] ;
2016-02-15 03:07:47 -06:00
int regionIdx = cellPvtRegionIdx_ [ cells [ i ] ] ;
2015-08-06 04:38:12 -05:00
double tempInvB = b_ [ regionIdx ] ( pg_i ) ;
double tempInvBmu = inverseBmu_ [ regionIdx ] ( pg_i ) ;
mu [ i ] = tempInvB / tempInvBmu ;
dmudp [ i ] = ( tempInvBmu * b_ [ regionIdx ] . derivative ( pg_i )
- tempInvB * inverseBmu_ [ regionIdx ] . derivative ( pg_i ) ) / ( tempInvBmu * tempInvBmu ) ;
}
2015-08-27 06:54:16 -05:00
ADB : : M dmudp_diag ( dmudp . matrix ( ) . asDiagonal ( ) ) ;
2015-08-06 04:38:12 -05:00
const int num_blocks = pg . numBlocks ( ) ;
std : : vector < ADB : : M > jacs ( num_blocks ) ;
for ( int block = 0 ; block < num_blocks ; + + block ) {
2015-08-27 06:54:16 -05:00
jacs [ block ] = dmudp_diag * pg . derivative ( ) [ block ] ;
2015-08-06 04:38:12 -05:00
}
return ADB : : function ( std : : move ( mu ) , std : : move ( jacs ) ) ;
}
ADB SolventPropsAdFromDeck : : bSolvent ( const ADB & pg ,
2016-02-12 04:02:03 -06:00
const Cells & cells ) const
2015-08-06 04:38:12 -05:00
{
2016-02-15 03:07:47 -06:00
return SolventPropsAdFromDeck : : makeADBfromTables ( pg , cells , cellPvtRegionIdx_ , b_ ) ;
2015-08-06 04:38:12 -05:00
}
2015-08-10 03:28:24 -05:00
ADB SolventPropsAdFromDeck : : gasRelPermMultiplier ( const ADB & solventFraction ,
2016-02-12 04:02:03 -06:00
const Cells & cells ) const
2015-08-10 03:28:24 -05:00
{
2016-02-15 03:07:47 -06:00
return SolventPropsAdFromDeck : : makeADBfromTables ( solventFraction , cells , cellSatNumRegionIdx_ , krg_ ) ;
2015-08-10 03:28:24 -05:00
}
ADB SolventPropsAdFromDeck : : solventRelPermMultiplier ( const ADB & solventFraction ,
2016-02-12 04:02:03 -06:00
const Cells & cells ) const
2015-08-10 03:28:24 -05:00
{
2016-02-15 03:07:47 -06:00
return SolventPropsAdFromDeck : : makeADBfromTables ( solventFraction , cells , cellSatNumRegionIdx_ , krs_ ) ;
2015-12-02 05:32:08 -06:00
}
ADB SolventPropsAdFromDeck : : misicibleHydrocarbonWaterRelPerm ( const ADB & Sn ,
2016-02-12 04:02:03 -06:00
const Cells & cells ) const
2015-12-02 05:32:08 -06:00
{
2016-02-15 03:07:47 -06:00
return SolventPropsAdFromDeck : : makeADBfromTables ( Sn , cells , cellSatNumRegionIdx_ , krn_ ) ;
2015-12-02 05:32:08 -06:00
}
ADB SolventPropsAdFromDeck : : miscibleSolventGasRelPermMultiplier ( const ADB & Ssg ,
2016-02-12 04:02:03 -06:00
const Cells & cells ) const
2015-12-02 05:32:08 -06:00
{
2015-12-09 04:30:16 -06:00
if ( mkrsg_ . size ( ) > 0 ) {
2016-02-15 03:07:47 -06:00
return SolventPropsAdFromDeck : : makeADBfromTables ( Ssg , cells , cellSatNumRegionIdx_ , mkrsg_ ) ;
2015-12-09 04:30:16 -06:00
}
// trivial function if not specified
return Ssg ;
2015-12-02 05:32:08 -06:00
}
ADB SolventPropsAdFromDeck : : miscibleOilRelPermMultiplier ( const ADB & So ,
2016-02-12 04:02:03 -06:00
const Cells & cells ) const
2015-12-02 05:32:08 -06:00
{
2015-12-09 04:30:16 -06:00
if ( mkro_ . size ( ) > 0 ) {
2016-02-15 03:07:47 -06:00
return SolventPropsAdFromDeck : : makeADBfromTables ( So , cells , cellSatNumRegionIdx_ , mkro_ ) ;
2015-12-09 04:30:16 -06:00
}
// trivial function if not specified
return So ;
2015-12-02 05:32:08 -06:00
}
2015-12-02 07:38:49 -06:00
ADB SolventPropsAdFromDeck : : miscibilityFunction ( const ADB & solventFraction ,
2016-02-12 04:02:03 -06:00
const Cells & cells ) const
2015-12-02 07:38:49 -06:00
{
2015-12-09 04:30:16 -06:00
2016-02-15 03:07:47 -06:00
return SolventPropsAdFromDeck : : makeADBfromTables ( solventFraction , cells , cellMiscRegionIdx_ , misc_ ) ;
2015-12-02 07:38:49 -06:00
}
2016-03-04 04:15:46 -06:00
ADB SolventPropsAdFromDeck : : pressureMiscibilityFunction ( const ADB & po ,
const Cells & cells ) const
{
if ( pmisc_ . size ( ) > 0 ) {
return SolventPropsAdFromDeck : : makeADBfromTables ( po , cells , cellMiscRegionIdx_ , pmisc_ ) ;
}
// return ones if not specified i.e. no effect.
return ADB : : constant ( V : : Constant ( po . size ( ) , 1.0 ) ) ;
}
2015-12-09 04:30:16 -06:00
ADB SolventPropsAdFromDeck : : miscibleCriticalGasSaturationFunction ( const ADB & Sw ,
2016-02-12 04:02:03 -06:00
const Cells & cells ) const {
2015-12-09 04:30:16 -06:00
if ( sgcwmis_ . size ( ) > 0 ) {
2016-02-15 03:07:47 -06:00
return SolventPropsAdFromDeck : : makeADBfromTables ( Sw , cells , cellMiscRegionIdx_ , sgcwmis_ ) ;
2015-12-09 04:30:16 -06:00
}
// return zeros if not specified
return ADB : : constant ( V : : Zero ( Sw . size ( ) ) ) ;
}
ADB SolventPropsAdFromDeck : : miscibleResidualOilSaturationFunction ( const ADB & Sw ,
2016-02-12 04:02:03 -06:00
const Cells & cells ) const {
2015-12-09 04:30:16 -06:00
if ( sorwmis_ . size ( ) > 0 ) {
2016-02-15 03:07:47 -06:00
return SolventPropsAdFromDeck : : makeADBfromTables ( Sw , cells , cellMiscRegionIdx_ , sorwmis_ ) ;
2015-12-09 04:30:16 -06:00
}
// return zeros if not specified
return ADB : : constant ( V : : Zero ( Sw . size ( ) ) ) ;
}
2016-02-12 04:02:03 -06:00
ADB SolventPropsAdFromDeck : : makeADBfromTables ( const ADB & X_AD ,
const Cells & cells ,
2016-02-15 03:07:47 -06:00
const std : : vector < int > & regionIdx ,
2016-02-12 04:02:03 -06:00
const std : : vector < NonuniformTableLinear < double > > & tables ) const {
2015-08-10 03:28:24 -05:00
const int n = cells . size ( ) ;
2016-02-03 05:21:47 -06:00
assert ( X_AD . value ( ) . size ( ) = = n ) ;
2015-12-02 05:32:08 -06:00
V x ( n ) ;
V dx ( n ) ;
2015-08-10 03:28:24 -05:00
for ( int i = 0 ; i < n ; + + i ) {
2015-12-02 05:32:08 -06:00
const double & X_i = X_AD . value ( ) [ i ] ;
2016-02-15 03:07:47 -06:00
x [ i ] = tables [ regionIdx [ cells [ i ] ] ] ( X_i ) ;
dx [ i ] = tables [ regionIdx [ cells [ i ] ] ] . derivative ( X_i ) ;
2015-08-10 03:28:24 -05:00
}
2015-12-02 05:32:08 -06:00
ADB : : M dx_diag ( dx . matrix ( ) . asDiagonal ( ) ) ;
const int num_blocks = X_AD . numBlocks ( ) ;
2015-08-10 03:28:24 -05:00
std : : vector < ADB : : M > jacs ( num_blocks ) ;
for ( int block = 0 ; block < num_blocks ; + + block ) {
2015-12-02 05:32:08 -06:00
fastSparseProduct ( dx_diag , X_AD . derivative ( ) [ block ] , jacs [ block ] ) ;
2015-08-10 03:28:24 -05:00
}
2015-12-02 05:32:08 -06:00
return ADB : : function ( std : : move ( x ) , std : : move ( jacs ) ) ;
2015-08-10 03:28:24 -05:00
}
2015-12-02 05:32:08 -06:00
2015-08-06 04:38:12 -05:00
V SolventPropsAdFromDeck : : solventSurfaceDensity ( const Cells & cells ) const {
const int n = cells . size ( ) ;
V density ( n ) ;
for ( int i = 0 ; i < n ; + + i ) {
2016-02-15 03:07:47 -06:00
int regionIdx = cellPvtRegionIdx_ [ cells [ i ] ] ;
2015-08-06 04:38:12 -05:00
density [ i ] = solvent_surface_densities_ [ regionIdx ] ;
}
return density ;
}
2016-02-15 06:28:54 -06:00
V SolventPropsAdFromDeck : : mixingParameterViscosity ( const Cells & cells ) const {
const int n = cells . size ( ) ;
if ( mix_param_viscosity_ . size ( ) > 0 ) {
V mix_param ( n ) ;
for ( int i = 0 ; i < n ; + + i ) {
int regionIdx = cellMiscRegionIdx_ [ cells [ i ] ] ;
mix_param [ i ] = mix_param_viscosity_ [ regionIdx ] ;
}
return mix_param ;
}
// return zeros if not specified
return V : : Zero ( n ) ;
2015-12-10 05:53:09 -06:00
}
2016-02-15 06:28:54 -06:00
V SolventPropsAdFromDeck : : mixingParameterDensity ( const Cells & cells ) const {
const int n = cells . size ( ) ;
if ( mix_param_viscosity_ . size ( ) > 0 ) {
V mix_param ( n ) ;
for ( int i = 0 ; i < n ; + + i ) {
int regionIdx = cellMiscRegionIdx_ [ cells [ i ] ] ;
mix_param [ i ] = mix_param_density_ [ regionIdx ] ;
}
return mix_param ;
}
// return zeros if not specified
return V : : Zero ( n ) ;
2015-12-10 05:53:09 -06:00
}
2016-03-09 05:29:18 -06:00
ADB SolventPropsAdFromDeck : : pressureMixingParameter ( const ADB & po ,
const Cells & cells ) const {
if ( tlpmix_param_ . size ( ) > 0 ) {
return SolventPropsAdFromDeck : : makeADBfromTables ( po , cells , cellMiscRegionIdx_ , tlpmix_param_ ) ;
}
// return ones if not specified i.e. no pressure effects.
return ADB : : constant ( V : : Constant ( po . size ( ) , 1.0 ) ) ;
}
2016-02-15 03:07:47 -06:00
void SolventPropsAdFromDeck : : extractTableIndex ( const std : : string & keyword ,
2016-10-14 02:23:26 -05:00
const Opm : : EclipseState & eclState ,
2016-02-17 03:43:01 -06:00
size_t numCompressed ,
const int * compressedToCartesianCellIdx ,
std : : vector < int > & tableIdx ) const {
2016-02-15 03:07:47 -06:00
//Get the Region data
2016-10-14 02:23:26 -05:00
const auto & regionData = eclState . get3DProperties ( ) . getIntGridProperty ( keyword ) . getData ( ) ;
2016-02-15 03:07:47 -06:00
// Convert this into an array of compressed cells
// Eclipse uses Fortran-style indices which start at 1
// instead of 0, we subtract 1.
tableIdx . resize ( numCompressed ) ;
for ( size_t cellIdx = 0 ; cellIdx < numCompressed ; + + cellIdx ) {
size_t cartesianCellIdx = compressedToCartesianCellIdx ? compressedToCartesianCellIdx [ cellIdx ] : cellIdx ;
assert ( cartesianCellIdx < regionData . size ( ) ) ;
tableIdx [ cellIdx ] = regionData [ cartesianCellIdx ] - 1 ;
}
}
2015-12-10 05:53:09 -06:00
2015-08-06 04:38:12 -05:00
} //namespace OPM