///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2017- Statoil ASA // // ResInsight 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. // // ResInsight 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 at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RigFractureTransmissibilityEquations.h" #include "cvfMath.h" #include "cvfVector2.h" #include const double RigFractureTransmissibilityEquations::EPSILON = 1.0e-9; //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- double RigFractureTransmissibilityEquations::centerToCenterFractureCellTrans( double conductivityCell1, double sideLengthParallellTransCell1, double sideLengthNormalTransCell1, double conductivityCell2, double sideLengthParallellTransCell2, double sideLengthNormalTransCell2, double cDarcyForRelevantUnit ) { double transCell1 = centerToEdgeFractureCellTrans( conductivityCell1, sideLengthParallellTransCell1, sideLengthNormalTransCell1, cDarcyForRelevantUnit ); double transCell2 = centerToEdgeFractureCellTrans( conductivityCell2, sideLengthParallellTransCell2, sideLengthNormalTransCell2, cDarcyForRelevantUnit ); double totalTrans = 1 / ( ( 1 / transCell1 ) + ( 1 / transCell2 ) ); return totalTrans; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- double RigFractureTransmissibilityEquations::fractureCellToWellRadialTrans( double fractureCellConductivity, double fractureCellSizeX, double fractureCellSizeZ, double wellRadius, double skinFactor, double cDarcyForRelevantUnit ) { double ro = 0.14 * cvf::Math::sqrt( pow( fractureCellSizeX, 2.0 ) + pow( fractureCellSizeZ, 2 ) ); if ( ro < ( wellRadius * 1.01 ) ) { ro = wellRadius * 1.01; } double Tc = 2 * cvf::PI_D * cDarcyForRelevantUnit * fractureCellConductivity / ( log( ro / wellRadius ) + skinFactor ); CVF_TIGHT_ASSERT( Tc > 0 ); return Tc; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- double RigFractureTransmissibilityEquations::fractureCellToWellLinearTrans( double fractureConductivity, double fractureCellSizeX, double fractureCellSizeZ, double perforationLengthVertical, double perforationLengthHorizontal, double perforationEfficiency, double skinfactor, double cDarcyForRelevantUnit, double wellRadius ) { const double invalidTrans = 1.0e9; const double epsilon = 1.0e-8; double TcPrefix = 8 * cDarcyForRelevantUnit * fractureConductivity; cvf::Vec2d wellOrientation = cvf::Vec2d( perforationLengthHorizontal, perforationLengthVertical ).getNormalized(); cvf::Vec2d wellRadialVector = wellOrientation.perpendicularVector() * wellRadius; double DzPerf = perforationLengthVertical * perforationEfficiency; double DxPerf = perforationLengthHorizontal * perforationEfficiency; double TcZ = 0.0; if ( DzPerf > epsilon ) { double effectiveFlowLengthHorizontal = fractureCellSizeX - 4.0 * std::abs( wellRadialVector.x() ); double denominatorZ = effectiveFlowLengthHorizontal + skinfactor * DzPerf / cvf::PI_D; if ( denominatorZ < epsilon ) { return invalidTrans; } TcZ = TcPrefix * DzPerf / denominatorZ; } double TcX = 0.0; if ( DxPerf > epsilon ) { double effectiveFlowLengthVertical = fractureCellSizeZ - 4.0 * std::abs( wellRadialVector.y() ); double denominatorX = effectiveFlowLengthVertical + skinfactor * DxPerf / cvf::PI_D; if ( denominatorX < epsilon ) { return invalidTrans; } TcX = TcPrefix * DxPerf / denominatorX; } double Tc = cvf::Math::sqrt( pow( TcX, 2 ) + pow( TcZ, 2 ) ); return Tc; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- double RigFractureTransmissibilityEquations::matrixToFractureTrans( double perm, double NTG, double A, double cellSizeLength, double skinfactor, double fractureAreaWeightedlength, double cDarcy ) { double transmissibility; double slDivPi = 0.0; if ( cvf::Math::abs( skinfactor ) > EPSILON ) { slDivPi = ( skinfactor * fractureAreaWeightedlength ) / cvf::PI_D; } transmissibility = 8 * cDarcy * ( perm * NTG ) * A / ( cellSizeLength + slDivPi ); CVF_ASSERT( transmissibility == transmissibility ); return transmissibility; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- double RigFractureTransmissibilityEquations::effectiveInternalFractureToWellTransPDDHC( double sumScaledMatrixToFractureTrans, double scaledMatrixToWellTrans ) { double divisor = sumScaledMatrixToFractureTrans - scaledMatrixToWellTrans; if ( cvf::Math::abs( divisor ) > EPSILON ) { return ( sumScaledMatrixToFractureTrans * scaledMatrixToWellTrans ) / divisor; } return 0.0; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- double RigFractureTransmissibilityEquations::effectiveMatrixToWellTransPDDHC( double sumOriginalMatrixToFractureTrans, double effectiveInternalFractureToWellTrans ) { double divisor = sumOriginalMatrixToFractureTrans + effectiveInternalFractureToWellTrans; if ( cvf::Math::abs( divisor ) > EPSILON ) { return ( sumOriginalMatrixToFractureTrans * effectiveInternalFractureToWellTrans ) / divisor; } return 0.0; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- double RigFractureTransmissibilityEquations::matrixPermeability( double permx, double permy, double NTG ) { double permxy = cvf::Math::sqrt( permx * permy ); return permxy * NTG; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- double RigFractureTransmissibilityEquations::centerToEdgeFractureCellTrans( double conductivity, double sideLengthParallellTrans, double sideLengthNormalTrans, double cDarcyForRelevantUnit ) { double transmissibility = cDarcyForRelevantUnit * conductivity * sideLengthNormalTrans / ( sideLengthParallellTrans / 2 ); return transmissibility; }