diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..479ea17 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,7 @@ + + + + + + + diff --git a/docs/lib.html b/docs/lib.html new file mode 100644 index 0000000..90d4529 --- /dev/null +++ b/docs/lib.html @@ -0,0 +1,265 @@ + + + + + + + lib API documentation + + + + + + + + + +
+
+

+lib

+ + + + + + +
1from . import enumerations, simulation, polymer, grid, surfactant
+2
+3name = "lib"
+
+ + +
+
+
+ name = +'lib' + + +
+ + + + +
+
+ + \ No newline at end of file diff --git a/docs/lib/Exceptions.html b/docs/lib/Exceptions.html new file mode 100644 index 0000000..23b520e --- /dev/null +++ b/docs/lib/Exceptions.html @@ -0,0 +1,567 @@ + + + + + + + lib.Exceptions API documentation + + + + + + + + + +
+
+

+lib.Exceptions

+ + + + + + +
 1class OutOfRangeError(Exception):
+ 2    """Exception raised for errors in the input if it is out of range."""
+ 3
+ 4    def __init__(self, value, message="Value is out of the allowed range."):
+ 5        """
+ 6        Args:
+ 7        -----
+ 8            value (float): value that the user provided in GUI
+ 9            message (str): Error message
+10        """
+11        self._value = value
+12        self._message = message
+13        super().__init__(self.message)
+14
+15    def __str__(self):
+16        """
+17        Returns: (str)
+18        --------------
+19            Returns the error message
+20        """
+21        return f"{self._value} -> {self._message}"
+22
+23
+24class SimulationCalcInputException(Exception):
+25    """
+26    Exception Handling for required inputs within various stages of the simulation
+27    """
+28
+29    def __init__(self, message):
+30        """
+31        constructor exception object
+32        
+33        Args:
+34        -----
+35            message (str): takes in the error message
+36        """
+37        self._message = message
+38
+39    def __str__(self):
+40        """
+41        Returns: (str)
+42        --------------
+43            Returns the error message
+44        """
+45        return self._message
+46
+47
+48
+49
+50class UserInputException(Exception):
+51    """
+52    Exception raised for invalid user inputs from the GUI.
+53    """
+54
+55    def __init__(self, message: str, inputs: dict | None = None):
+56        """
+57        Initialize the exception with a message and optional input dictionary.
+58
+59        Args:
+60        -----
+61            message (str): Description of the validation error.
+62            inputs (dict, None): Dictionary of user inputs (optional).
+63        """
+64        super().__init__(message)
+65        self._message = message
+66        self._user_inputs = inputs or {}
+67
+68    def __str__(self):
+69        """
+70        Returns: (str)
+71        --------------
+72            Returns the error message
+73        """
+74        return f"UserInputException: {self._message}"
+
+ + +
+
+ +
+ + class + OutOfRangeError(builtins.Exception): + + + +
+ +
 2class OutOfRangeError(Exception):
+ 3    """Exception raised for errors in the input if it is out of range."""
+ 4
+ 5    def __init__(self, value, message="Value is out of the allowed range."):
+ 6        """
+ 7        Args:
+ 8        -----
+ 9            value (float): value that the user provided in GUI
+10            message (str): Error message
+11        """
+12        self._value = value
+13        self._message = message
+14        super().__init__(self.message)
+15
+16    def __str__(self):
+17        """
+18        Returns: (str)
+19        --------------
+20            Returns the error message
+21        """
+22        return f"{self._value} -> {self._message}"
+
+ + +

Exception raised for errors in the input if it is out of range.

+
+ + +
+ +
+ + OutOfRangeError(value, message='Value is out of the allowed range.') + + + +
+ +
 5    def __init__(self, value, message="Value is out of the allowed range."):
+ 6        """
+ 7        Args:
+ 8        -----
+ 9            value (float): value that the user provided in GUI
+10            message (str): Error message
+11        """
+12        self._value = value
+13        self._message = message
+14        super().__init__(self.message)
+
+ + +

Args:

+ +
value (float): value that the user provided in GUI
+message (str): Error message
+
+
+ + +
+
+
+ +
+ + class + SimulationCalcInputException(builtins.Exception): + + + +
+ +
25class SimulationCalcInputException(Exception):
+26    """
+27    Exception Handling for required inputs within various stages of the simulation
+28    """
+29
+30    def __init__(self, message):
+31        """
+32        constructor exception object
+33        
+34        Args:
+35        -----
+36            message (str): takes in the error message
+37        """
+38        self._message = message
+39
+40    def __str__(self):
+41        """
+42        Returns: (str)
+43        --------------
+44            Returns the error message
+45        """
+46        return self._message
+
+ + +

Exception Handling for required inputs within various stages of the simulation

+
+ + +
+ +
+ + SimulationCalcInputException(message) + + + +
+ +
30    def __init__(self, message):
+31        """
+32        constructor exception object
+33        
+34        Args:
+35        -----
+36            message (str): takes in the error message
+37        """
+38        self._message = message
+
+ + +

constructor exception object

+ +

Args:

+ +
message (str): takes in the error message
+
+
+ + +
+
+
+ +
+ + class + UserInputException(builtins.Exception): + + + +
+ +
51class UserInputException(Exception):
+52    """
+53    Exception raised for invalid user inputs from the GUI.
+54    """
+55
+56    def __init__(self, message: str, inputs: dict | None = None):
+57        """
+58        Initialize the exception with a message and optional input dictionary.
+59
+60        Args:
+61        -----
+62            message (str): Description of the validation error.
+63            inputs (dict, None): Dictionary of user inputs (optional).
+64        """
+65        super().__init__(message)
+66        self._message = message
+67        self._user_inputs = inputs or {}
+68
+69    def __str__(self):
+70        """
+71        Returns: (str)
+72        --------------
+73            Returns the error message
+74        """
+75        return f"UserInputException: {self._message}"
+
+ + +

Exception raised for invalid user inputs from the GUI.

+
+ + +
+ +
+ + UserInputException(message: str, inputs: dict | None = None) + + + +
+ +
56    def __init__(self, message: str, inputs: dict | None = None):
+57        """
+58        Initialize the exception with a message and optional input dictionary.
+59
+60        Args:
+61        -----
+62            message (str): Description of the validation error.
+63            inputs (dict, None): Dictionary of user inputs (optional).
+64        """
+65        super().__init__(message)
+66        self._message = message
+67        self._user_inputs = inputs or {}
+
+ + +

Initialize the exception with a message and optional input dictionary.

+ +

Args:

+ +
message (str): Description of the validation error.
+inputs (dict, None): Dictionary of user inputs (optional).
+
+
+ + +
+
+
+ + \ No newline at end of file diff --git a/docs/lib/enumerations.html b/docs/lib/enumerations.html new file mode 100644 index 0000000..9b648f5 --- /dev/null +++ b/docs/lib/enumerations.html @@ -0,0 +1,1533 @@ + + + + + + + lib.enumerations API documentation + + + + + + + + + +
+
+

+lib.enumerations

+ +

This python script contains the class definitions for the enumerations that are used within the simulation runs

+ +

The methods of this class were derived from the MATLAB Surfactant-Polymer Flooding Code developed by +Sourav Dutta and Rohit Mishra.

+ +

@author: Bhargav Akula Ramesh Kumar, Carlos Acosta Caripo

+
+ + + + + +
  1"""
+  2This python script contains the class definitions for the enumerations that are used within the simulation runs
+  3
+  4The methods of this class were derived from the MATLAB Surfactant-Polymer Flooding Code developed by
+  5Sourav Dutta and Rohit Mishra.
+  6
+  7@author: Bhargav Akula Ramesh Kumar, Carlos Acosta Caripo
+  8"""
+  9
+ 10from enum import Enum
+ 11import numpy as np
+ 12
+ 13
+ 14class SimulationConstants(Enum):
+ 15    """
+ 16    Simulation constants
+ 17    (Taken from 2017 paper "Modeling and simulation of surfactant–polymer flooding using a new hybrid method")
+ 18    """
+ 19
+ 20    Water_Viscosity = 1.26
+ 21    Water_Density = 1000  # kg/m^3
+ 22    Oil_Viscosity = 10
+ 23
+ 24    Initial_Residual_Water_Saturation = 0.79
+ 25    Resid_Aqueous_Phase_Saturation_Initial = 0.1  # wetting phase
+ 26    Resid_Oleic_Phase_Saturation_Initial = 0.3  # non-wetting phase
+ 27
+ 28    Aqueous_Phase_Critical_Capillary_Num = 10 ** (-5)
+ 29    Oleic_Phase_Critical_Capillary_Num = 10 ** (-5)
+ 30
+ 31    Capillary_Pressure_Param_1 = 0.1  # omega_1
+ 32    Capillary_Pressure_Param_2 = 0.4  # omega_2
+ 33
+ 34    Injection_Rate = 200
+ 35    Time_Step = 1 / 50
+ 36    Grid_Size = 29
+ 37    Source_Flow_Magnitude = (
+ 38        120000  # FIXME: Update in v2.0 to allow for multiple Injection Rates!
+ 39    )
+ 40
+ 41    beta1 = 15000
+ 42
+ 43
+ 44class PolymerList(Enum):
+ 45    """
+ 46    List of Polymers that can be selected for the simulation runs
+ 47    """
+ 48
+ 49    Xanthane = (
+ 50        1,
+ 51        1500,
+ 52        np.array([[3.05428284], [-0.27294817]]),
+ 53        np.array([[1.15410398e-04], [2.04937780e00]]),
+ 54    )
+ 55    Schizophyllan = (
+ 56        2,
+ 57        1300,
+ 58        np.array([[4.86265534], [-0.41570227]]),
+ 59        np.array([[0.03647214], [1.32175949]]),
+ 60    )
+ 61    No_Polymer = (3, 0, [0, 0], [0, 0])
+ 62
+ 63    @property
+ 64    def Id(self):
+ 65        """
+ 66        Id (int): Index for Polymer
+ 67        """
+ 68        return self.value[0]
+ 69
+ 70    @property
+ 71    def Density(self):  # kg/m^3
+ 72        """
+ 73        Density (float): density of the Polymer
+ 74        """
+ 75        return self.value[1]
+ 76
+ 77    @property
+ 78    def n_coeff(self):  # dimensionless
+ 79        """
+ 80        n_coeff (list[float]): 'n' coeffient for the empirical power law equation
+ 81        """
+ 82        return self.value[2]
+ 83
+ 84    @property
+ 85    def e_coeff(self):  # dimensionless
+ 86        """
+ 87        e_coeff (list[float]): 'ε' coeffient for the empirical power law equation
+ 88        """
+ 89        return self.value[3]
+ 90
+ 91    @classmethod
+ 92    def get_by_value(cls, value):
+ 93        """
+ 94        retrieves Polymer from enumeration based on value
+ 95        """
+ 96        member = next((member for member in cls if member.value[0] == value), None)
+ 97        return member
+ 98
+ 99
+100class SurfactantList(Enum):
+101    """
+102    List of Surfactants that can be selected for the simulation runs
+103
+104    FIXME: need to adjust when implementing 'autodiff'
+105    """
+106
+107    Alkyl_Ether_Sulfate = (
+108        1,
+109        lambda GG: 10.001 / (GG + 1),
+110        lambda GG: (-10.001) / ((GG + 1) ** 2),
+111    )
+112    No_Surfactant = (2, lambda GG: 0, lambda GG: 0)
+113
+114    @property
+115    def Id(self):
+116        """
+117        Id (int): Index for Polymer
+118        """
+119        return self.value[0]
+120
+121    @property
+122    def IFT_equation(self):
+123        """
+124        IFT_equation (lambda): the relationship between surfactant concentration and interfacial tension
+125        """
+126        return self.value[1]
+127
+128    @property
+129    def derivative_IFT_equation(self):
+130        """
+131        derivative_IFT_equation (lambda): the derivative of the IFT_equation
+132        """
+133        return self.value[2]
+134
+135    @classmethod
+136    def get_by_value(cls, value):
+137        """
+138        retrieves Surfactant from enumeration based on value
+139        """
+140        member = next((member for member in cls if member.value[0] == value), None)
+141        return member
+142
+143
+144class ModelType(Enum):
+145    """
+146    The simulation model types that can be selected
+147    """
+148
+149    No_Shear_Thinning = 1
+150    Sourav_Implementation = 2
+151    Shear_Thinning_On = 3
+152
+153
+154class PlotType(Enum):
+155    """
+156    Selection of types of plots that can be created for the user
+157    """
+158
+159    Saturation_Plot = 1
+160    Polymer_Concentration_Plot = 2
+161    Surfactant_Concentration_Plot = 3
+162
+163
+164class ResevoirGeometry(Enum):
+165    """
+166    Selection of the geometry of the resevoir for the simulation
+167    """
+168
+169    Rectilinear = 1
+170    Quarter_Five_Spot = 2
+171
+172
+173class PermeabilityType(Enum):
+174    """
+175    Selection of the permeability profile for each of the simulation runs
+176    """
+177
+178    Homogenous = 1
+179    Heterogenous = 2
+180
+181
+182class RelativePermeabilityFormula(Enum):
+183    """
+184    Selection of the relative permeability formuala
+185    (krw, Kro)
+186    """
+187
+188    AmaefuleHandEquation = 1
+189    CoreyTypeEquation = 2
+
+ + +
+
+ +
+ + class + SimulationConstants(enum.Enum): + + + +
+ +
15class SimulationConstants(Enum):
+16    """
+17    Simulation constants
+18    (Taken from 2017 paper "Modeling and simulation of surfactant–polymer flooding using a new hybrid method")
+19    """
+20
+21    Water_Viscosity = 1.26
+22    Water_Density = 1000  # kg/m^3
+23    Oil_Viscosity = 10
+24
+25    Initial_Residual_Water_Saturation = 0.79
+26    Resid_Aqueous_Phase_Saturation_Initial = 0.1  # wetting phase
+27    Resid_Oleic_Phase_Saturation_Initial = 0.3  # non-wetting phase
+28
+29    Aqueous_Phase_Critical_Capillary_Num = 10 ** (-5)
+30    Oleic_Phase_Critical_Capillary_Num = 10 ** (-5)
+31
+32    Capillary_Pressure_Param_1 = 0.1  # omega_1
+33    Capillary_Pressure_Param_2 = 0.4  # omega_2
+34
+35    Injection_Rate = 200
+36    Time_Step = 1 / 50
+37    Grid_Size = 29
+38    Source_Flow_Magnitude = (
+39        120000  # FIXME: Update in v2.0 to allow for multiple Injection Rates!
+40    )
+41
+42    beta1 = 15000
+
+ + +

Simulation constants +(Taken from 2017 paper "Modeling and simulation of surfactant–polymer flooding using a new hybrid method")

+
+ + +
+
+ Water_Viscosity = +<SimulationConstants.Water_Viscosity: 1.26> + + +
+ + + + +
+
+
+ Water_Density = +<SimulationConstants.Water_Density: 1000> + + +
+ + + + +
+
+
+ Oil_Viscosity = +<SimulationConstants.Oil_Viscosity: 10> + + +
+ + + + +
+
+
+ Initial_Residual_Water_Saturation = +<SimulationConstants.Initial_Residual_Water_Saturation: 0.79> + + +
+ + + + +
+
+
+ Resid_Aqueous_Phase_Saturation_Initial = +<SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial: 0.1> + + +
+ + + + +
+
+
+ Resid_Oleic_Phase_Saturation_Initial = +<SimulationConstants.Resid_Oleic_Phase_Saturation_Initial: 0.3> + + +
+ + + + +
+
+
+ Aqueous_Phase_Critical_Capillary_Num = +<SimulationConstants.Aqueous_Phase_Critical_Capillary_Num: 1e-05> + + +
+ + + + +
+
+
+ Oleic_Phase_Critical_Capillary_Num = +<SimulationConstants.Aqueous_Phase_Critical_Capillary_Num: 1e-05> + + +
+ + + + +
+
+
+ Capillary_Pressure_Param_1 = +<SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial: 0.1> + + +
+ + + + +
+
+
+ Capillary_Pressure_Param_2 = +<SimulationConstants.Capillary_Pressure_Param_2: 0.4> + + +
+ + + + +
+
+
+ Injection_Rate = +<SimulationConstants.Injection_Rate: 200> + + +
+ + + + +
+
+
+ Time_Step = +<SimulationConstants.Time_Step: 0.02> + + +
+ + + + +
+
+
+ Grid_Size = +<SimulationConstants.Grid_Size: 29> + + +
+ + + + +
+
+
+ Source_Flow_Magnitude = +<SimulationConstants.Source_Flow_Magnitude: 120000> + + +
+ + + + +
+
+
+ beta1 = +<SimulationConstants.beta1: 15000> + + +
+ + + + +
+
+
+ +
+ + class + PolymerList(enum.Enum): + + + +
+ +
45class PolymerList(Enum):
+46    """
+47    List of Polymers that can be selected for the simulation runs
+48    """
+49
+50    Xanthane = (
+51        1,
+52        1500,
+53        np.array([[3.05428284], [-0.27294817]]),
+54        np.array([[1.15410398e-04], [2.04937780e00]]),
+55    )
+56    Schizophyllan = (
+57        2,
+58        1300,
+59        np.array([[4.86265534], [-0.41570227]]),
+60        np.array([[0.03647214], [1.32175949]]),
+61    )
+62    No_Polymer = (3, 0, [0, 0], [0, 0])
+63
+64    @property
+65    def Id(self):
+66        """
+67        Id (int): Index for Polymer
+68        """
+69        return self.value[0]
+70
+71    @property
+72    def Density(self):  # kg/m^3
+73        """
+74        Density (float): density of the Polymer
+75        """
+76        return self.value[1]
+77
+78    @property
+79    def n_coeff(self):  # dimensionless
+80        """
+81        n_coeff (list[float]): 'n' coeffient for the empirical power law equation
+82        """
+83        return self.value[2]
+84
+85    @property
+86    def e_coeff(self):  # dimensionless
+87        """
+88        e_coeff (list[float]): 'ε' coeffient for the empirical power law equation
+89        """
+90        return self.value[3]
+91
+92    @classmethod
+93    def get_by_value(cls, value):
+94        """
+95        retrieves Polymer from enumeration based on value
+96        """
+97        member = next((member for member in cls if member.value[0] == value), None)
+98        return member
+
+ + +

List of Polymers that can be selected for the simulation runs

+
+ + +
+
+ Xanthane = + + <PolymerList.Xanthane: (1, 1500, array([[ 3.05428284], + [-0.27294817]]), array([[1.15410398e-04], + [2.04937780e+00]]))> + + +
+ + + + +
+
+
+ Schizophyllan = + + <PolymerList.Schizophyllan: (2, 1300, array([[ 4.86265534], + [-0.41570227]]), array([[0.03647214], + [1.32175949]]))> + + +
+ + + + +
+
+
+ No_Polymer = +<PolymerList.No_Polymer: (3, 0, [0, 0], [0, 0])> + + +
+ + + + +
+
+ +
+ Id + + + +
+ +
64    @property
+65    def Id(self):
+66        """
+67        Id (int): Index for Polymer
+68        """
+69        return self.value[0]
+
+ + +

Id (int): Index for Polymer

+
+ + +
+
+ +
+ Density + + + +
+ +
71    @property
+72    def Density(self):  # kg/m^3
+73        """
+74        Density (float): density of the Polymer
+75        """
+76        return self.value[1]
+
+ + +

Density (float): density of the Polymer

+
+ + +
+
+ +
+ n_coeff + + + +
+ +
78    @property
+79    def n_coeff(self):  # dimensionless
+80        """
+81        n_coeff (list[float]): 'n' coeffient for the empirical power law equation
+82        """
+83        return self.value[2]
+
+ + +

n_coeff (list[float]): 'n' coeffient for the empirical power law equation

+
+ + +
+
+ +
+ e_coeff + + + +
+ +
85    @property
+86    def e_coeff(self):  # dimensionless
+87        """
+88        e_coeff (list[float]): 'ε' coeffient for the empirical power law equation
+89        """
+90        return self.value[3]
+
+ + +

e_coeff (list[float]): 'ε' coeffient for the empirical power law equation

+
+ + +
+
+ +
+
@classmethod
+ + def + get_by_value(cls, value): + + + +
+ +
92    @classmethod
+93    def get_by_value(cls, value):
+94        """
+95        retrieves Polymer from enumeration based on value
+96        """
+97        member = next((member for member in cls if member.value[0] == value), None)
+98        return member
+
+ + +

retrieves Polymer from enumeration based on value

+
+ + +
+
+
+ +
+ + class + SurfactantList(enum.Enum): + + + +
+ +
101class SurfactantList(Enum):
+102    """
+103    List of Surfactants that can be selected for the simulation runs
+104
+105    FIXME: need to adjust when implementing 'autodiff'
+106    """
+107
+108    Alkyl_Ether_Sulfate = (
+109        1,
+110        lambda GG: 10.001 / (GG + 1),
+111        lambda GG: (-10.001) / ((GG + 1) ** 2),
+112    )
+113    No_Surfactant = (2, lambda GG: 0, lambda GG: 0)
+114
+115    @property
+116    def Id(self):
+117        """
+118        Id (int): Index for Polymer
+119        """
+120        return self.value[0]
+121
+122    @property
+123    def IFT_equation(self):
+124        """
+125        IFT_equation (lambda): the relationship between surfactant concentration and interfacial tension
+126        """
+127        return self.value[1]
+128
+129    @property
+130    def derivative_IFT_equation(self):
+131        """
+132        derivative_IFT_equation (lambda): the derivative of the IFT_equation
+133        """
+134        return self.value[2]
+135
+136    @classmethod
+137    def get_by_value(cls, value):
+138        """
+139        retrieves Surfactant from enumeration based on value
+140        """
+141        member = next((member for member in cls if member.value[0] == value), None)
+142        return member
+
+ + +

List of Surfactants that can be selected for the simulation runs

+ +

FIXME: need to adjust when implementing 'autodiff'

+
+ + +
+
+ Alkyl_Ether_Sulfate = + + <SurfactantList.Alkyl_Ether_Sulfate: (1, <function SurfactantList.<lambda>>, <function SurfactantList.<lambda>>)> + + +
+ + + + +
+
+
+ No_Surfactant = + + <SurfactantList.No_Surfactant: (2, <function SurfactantList.<lambda>>, <function SurfactantList.<lambda>>)> + + +
+ + + + +
+
+ +
+ Id + + + +
+ +
115    @property
+116    def Id(self):
+117        """
+118        Id (int): Index for Polymer
+119        """
+120        return self.value[0]
+
+ + +

Id (int): Index for Polymer

+
+ + +
+
+ +
+ IFT_equation + + + +
+ +
122    @property
+123    def IFT_equation(self):
+124        """
+125        IFT_equation (lambda): the relationship between surfactant concentration and interfacial tension
+126        """
+127        return self.value[1]
+
+ + +

IFT_equation (lambda): the relationship between surfactant concentration and interfacial tension

+
+ + +
+
+ +
+ derivative_IFT_equation + + + +
+ +
129    @property
+130    def derivative_IFT_equation(self):
+131        """
+132        derivative_IFT_equation (lambda): the derivative of the IFT_equation
+133        """
+134        return self.value[2]
+
+ + +

derivative_IFT_equation (lambda): the derivative of the IFT_equation

+
+ + +
+
+ +
+
@classmethod
+ + def + get_by_value(cls, value): + + + +
+ +
136    @classmethod
+137    def get_by_value(cls, value):
+138        """
+139        retrieves Surfactant from enumeration based on value
+140        """
+141        member = next((member for member in cls if member.value[0] == value), None)
+142        return member
+
+ + +

retrieves Surfactant from enumeration based on value

+
+ + +
+
+
+ +
+ + class + ModelType(enum.Enum): + + + +
+ +
145class ModelType(Enum):
+146    """
+147    The simulation model types that can be selected
+148    """
+149
+150    No_Shear_Thinning = 1
+151    Sourav_Implementation = 2
+152    Shear_Thinning_On = 3
+
+ + +

The simulation model types that can be selected

+
+ + +
+
+ No_Shear_Thinning = +<ModelType.No_Shear_Thinning: 1> + + +
+ + + + +
+
+
+ Sourav_Implementation = +<ModelType.Sourav_Implementation: 2> + + +
+ + + + +
+
+
+ Shear_Thinning_On = +<ModelType.Shear_Thinning_On: 3> + + +
+ + + + +
+
+
+ +
+ + class + PlotType(enum.Enum): + + + +
+ +
155class PlotType(Enum):
+156    """
+157    Selection of types of plots that can be created for the user
+158    """
+159
+160    Saturation_Plot = 1
+161    Polymer_Concentration_Plot = 2
+162    Surfactant_Concentration_Plot = 3
+
+ + +

Selection of types of plots that can be created for the user

+
+ + +
+
+ Saturation_Plot = +<PlotType.Saturation_Plot: 1> + + +
+ + + + +
+
+
+ Polymer_Concentration_Plot = +<PlotType.Polymer_Concentration_Plot: 2> + + +
+ + + + +
+
+
+ Surfactant_Concentration_Plot = +<PlotType.Surfactant_Concentration_Plot: 3> + + +
+ + + + +
+
+
+ +
+ + class + ResevoirGeometry(enum.Enum): + + + +
+ +
165class ResevoirGeometry(Enum):
+166    """
+167    Selection of the geometry of the resevoir for the simulation
+168    """
+169
+170    Rectilinear = 1
+171    Quarter_Five_Spot = 2
+
+ + +

Selection of the geometry of the resevoir for the simulation

+
+ + +
+
+ Rectilinear = +<ResevoirGeometry.Rectilinear: 1> + + +
+ + + + +
+
+
+ Quarter_Five_Spot = +<ResevoirGeometry.Quarter_Five_Spot: 2> + + +
+ + + + +
+
+
+ +
+ + class + PermeabilityType(enum.Enum): + + + +
+ +
174class PermeabilityType(Enum):
+175    """
+176    Selection of the permeability profile for each of the simulation runs
+177    """
+178
+179    Homogenous = 1
+180    Heterogenous = 2
+
+ + +

Selection of the permeability profile for each of the simulation runs

+
+ + +
+
+ Homogenous = +<PermeabilityType.Homogenous: 1> + + +
+ + + + +
+
+
+ Heterogenous = +<PermeabilityType.Heterogenous: 2> + + +
+ + + + +
+
+
+ +
+ + class + RelativePermeabilityFormula(enum.Enum): + + + +
+ +
183class RelativePermeabilityFormula(Enum):
+184    """
+185    Selection of the relative permeability formuala
+186    (krw, Kro)
+187    """
+188
+189    AmaefuleHandEquation = 1
+190    CoreyTypeEquation = 2
+
+ + +

Selection of the relative permeability formuala +(krw, Kro)

+
+ + +
+
+ AmaefuleHandEquation = +<RelativePermeabilityFormula.AmaefuleHandEquation: 1> + + +
+ + + + +
+
+
+ CoreyTypeEquation = +<RelativePermeabilityFormula.CoreyTypeEquation: 2> + + +
+ + + + +
+
+
+ + \ No newline at end of file diff --git a/docs/lib/grid.html b/docs/lib/grid.html new file mode 100644 index 0000000..4af42f3 --- /dev/null +++ b/docs/lib/grid.html @@ -0,0 +1,2862 @@ + + + + + + + lib.grid API documentation + + + + + + + + + +
+
+

+lib.grid

+ +

This python script contains the class definition for running simulations

+ +

This Python code has been derived from the MATLAB Surfactant-Polymer Flooding Simulation +developed by Sourav Dutta and Rohit Mishra.

+ +

@author: Bhargav Akula Ramesh Kumar and Carlos Acosta Caripo

+
+ + + + + +
  1"""
+  2This python script contains the class definition for running simulations
+  3
+  4This Python code has been derived from the MATLAB Surfactant-Polymer Flooding Simulation 
+  5developed by Sourav Dutta and Rohit Mishra.
+  6
+  7@author: Bhargav Akula Ramesh Kumar and Carlos Acosta Caripo
+  8
+  9"""
+ 10
+ 11import numpy as np
+ 12from scipy.sparse import coo_matrix
+ 13from matplotlib.tri import Triangulation
+ 14
+ 15
+ 16class Grid:
+ 17    """
+ 18    Encapsulates mesh generation, triangulation, FEM matrix assembly, and source vector setup.
+ 19
+ 20    FIXME: Need to refactor this class to make it more understandable
+ 21    """
+ 22
+ 23    def __init__(
+ 24        self,
+ 25        m: int,
+ 26        n: int,
+ 27        left: float = 0.0,
+ 28        right: float = 1.0,
+ 29        bottom: float = 0.0,
+ 30        top: float = 1.0,
+ 31    ):
+ 32        self.m = m
+ 33        self.n = n
+ 34        self.left = left
+ 35        self.right = right
+ 36        self.bottom = bottom
+ 37        self.top = top
+ 38
+ 39        self.A = None
+ 40        self.B = None
+ 41
+ 42    _m = None
+ 43    @property
+ 44    def m(self):
+ 45        """
+ 46        The number of columns
+ 47        """
+ 48        return self._m
+ 49    @m.setter
+ 50    def m(self, value):
+ 51        self._m = value
+ 52    
+ 53    _n = None
+ 54    @property
+ 55    def n(self):
+ 56        """
+ 57        The number of rows
+ 58        """
+ 59        return self._n
+ 60    @n.setter
+ 61    def n(self, value):
+ 62        self._n = value
+ 63
+ 64    _left = None
+ 65    @property
+ 66    def left(self):
+ 67        """
+ 68        left most value on grid. Used to compute ``dx``. Has a default value of 0
+ 69        """
+ 70        return self._left
+ 71    @left.setter
+ 72    def left(self, value):
+ 73        self._left = value
+ 74
+ 75    _right = None
+ 76    @property
+ 77    def right(self):
+ 78        """
+ 79        right most value on grid. Used to compute ``dx``. Has a default value of 1.
+ 80        """
+ 81        return self._right
+ 82    @right.setter
+ 83    def right(self, value):
+ 84        self._right = value
+ 85
+ 86    _top = None
+ 87    @property
+ 88    def top(self):
+ 89        """
+ 90        Top most value on grid. Used to compute ``dy``. Has a default value of 1.
+ 91        """
+ 92        return self._top
+ 93    @top.setter
+ 94    def top(self, value):
+ 95        self._top = value
+ 96
+ 97    _bottom = None
+ 98    @property
+ 99    def bottom(self):
+100        """
+101        Bottom most value on grid. Used to compute ``dy``. Has a default value of 0.
+102        """
+103        return self._bottom
+104    @bottom.setter
+105    def bottom(self, value):
+106        self._bottom = value
+107
+108    _A = None
+109    @property
+110    def A(self):
+111        """
+112        A matrix for solving Ax = b
+113        """
+114        return self._A
+115    @A.setter
+116    def A(self, value):
+117        self._A = value
+118    
+119    _B = None
+120    @property
+121    def B(self):
+122        """
+123        b matrix for solving Ax = b
+124        """
+125        return self._B
+126    @B.setter
+127    def B(self, value):
+128        self._B = value
+129
+130    @property
+131    def get_spacing(self):
+132        """
+133        Provides dx and dy
+134        """
+135        return self.dx, self.dy
+136
+137    @property
+138    def get_meshgrid(self):
+139        """
+140        Generates the x and y coordinates for the FD Mesh
+141        """
+142        self.x, self.y = self.set_FD_meshgrid()
+143        return self.x, self.y
+144
+145    @property
+146    def dx(self):
+147        """
+148        Computes ``dx``
+149        """
+150        return (self.right - self.left) / self.m
+151
+152    @property
+153    def dy(self):
+154        """
+155        Computes ``dy`` 
+156        """
+157        return (self.top - self.bottom) / self.n
+158
+159    def set_FD_meshgrid(self):
+160        """
+161        Generates FD coordinate grid for SP-flooding.
+162        Used for the transport equations.
+163
+164        Returns:
+165            (x, y) meshgrid arrays
+166        """
+167        x = np.linspace(self.left, self.right, self.m + 1)
+168        y = np.linspace(self.bottom, self.top, self.n + 1)
+169        self.x, self.y = np.meshgrid(x, y)
+170        return self.x, self.y
+171
+172    def get_flat_index_matrix(self) -> np.ndarray:
+173        """
+174        Returns a matrix of shape (n+1, m+1) with flat indices at each grid point.
+175        """
+176        return np.arange((self.m + 1) * (self.n + 1)).reshape((self.n + 1, self.m + 1))
+177
+178
+179class FEMesh(Grid):
+180    def __init__(self, m: int, n: int):
+181        """
+182        Constructor for the ``FEMesh`` class (subclass of the ``Grid`` class)
+183
+184        Args:
+185            m (int): num columns
+186            n (int): num rows
+187        """
+188        super().__init__(m, n)
+189        self.U = None
+190        self.L = None
+191        self.grid_size = None
+192        self.right_hand = None
+193        self.A = None
+194        self.B = None
+195        self.sparsed_A = None
+196
+197    _sparsed_A = None
+198    @property
+199    def sparsed_A(self):
+200        """
+201        sparsed matrix version of matrix ``A``
+202        """
+203        return self._sparsed_A
+204    @sparsed_A.setter
+205    def sparsed_A(self, value):
+206        self._sparsed_A = value
+207
+208    _grid_size = None
+209    @property
+210    def grid_size(self):
+211        """
+212        row size of square grid (# rows = # cols)
+213        """
+214        return self._grid_size
+215    @grid_size.setter
+216    def grid_size(self, value):
+217        self._grid_size = value
+218
+219    _right_hand = None
+220    @property
+221    def right_hand(self):
+222        """
+223        Matrix representation of the rhs of the global pressure and velocity equations that will subsequently be used
+224        to solve for the global pressure and velocity matrices.
+225        """
+226        return self._right_hand
+227    @right_hand.setter
+228    def right_hand(self, value):
+229        self._right_hand = value
+230
+231    _U = None
+232    @property
+233    def U(self):
+234        """
+235        U = cell array with each element = array of vertices of Upper Triangle of
+236        the rectangular cell
+237        """
+238        return self._U
+239    @U.setter
+240    def U(self, value):
+241        self._U = value
+242
+243    _L = None
+244    @property
+245    def L(self):
+246        """
+247        L = cell array with each element = array of vertices of Lower Triangle of
+248        the rectangular cell
+249        """
+250        return self._L
+251    @L.setter
+252    def L(self, value):
+253        self._L = value
+254
+255    def set_triangulation(self):
+256        """
+257            Setting up triangulations for the FEM grid
+258            
+259            At every point (i,j), U{i,j} & L{i,j} are cells with coordinates of vertices
+260            of the two triangles obtained by bisecting the rectangle starting at
+261            (i,j). The bisection line goes from NW to SE.
+262        """
+263        self.U = np.empty((self.m, self.n), dtype=object)
+264        self.L = np.empty((self.m, self.n), dtype=object)
+265
+266        for j in range(self.m):
+267            for k in range(self.n):
+268                x1 = self.left + j * self.dx
+269                y1 = self.bottom + k * self.dy
+270                x2 = self.left + (j + 1) * self.dx
+271                y2 = y1
+272                x3 = x1
+273                y3 = self.bottom + (k + 1) * self.dy
+274                x4 = x2
+275                y4 = y3
+276
+277                # lower triangle vertices
+278                l = {"x": np.array([x1, x2, x3]), "y": np.array([y1, y2, y3])}
+279
+280                # upper triangle vertices
+281                u = {"x": np.array([x4, x3, x2]), "y": np.array([y4, y3, y2])}
+282
+283                self.U[j, k] = u
+284                self.L[j, k] = l
+285
+286    def _polyarea(self, x, y):
+287        """
+288        Calculate the area of a polygon using the Shoelace formula.
+289        The vertices are defined by the x and y coordinates.
+290
+291        Args:
+292            x (list or array): x-coordinates of the polygon vertices
+293            y (list or array): y-coordinates of the polygon vertices
+294
+295        Returns: (float)
+296            Area of the polygon
+297        """
+298        return 0.5 * abs(
+299            sum(x[i] * y[i + 1] - y[i] * x[i + 1] for i in range(-1, len(x) - 1))
+300        )
+301
+302    def _beta_func(self, x, y, beta):
+303        """
+304        Evaluates the coefficient beta at each grid point
+305        $$ \beta = K \lambda $$
+306        x and y are the coordinates of the grid point
+307        The corresponding index locations in the matrix for beta
+308        are determined in mm and nn respectively.
+309
+310        Analogous to beta_func.m in the MATLAB code
+311        """
+312        mm = round((x - self.left) / self.dx)
+313        nn = round((y - self.bottom) / self.dy)
+314
+315        return beta[
+316            int(nn), int(mm)
+317        ]  # nn and mm are casted to integers for indexing purposes
+318
+319    def _set_FE_meshgrid_helper(self, T, beta, V):
+320        """
+321        Evaluates beta at the vertices of the element triangle
+322
+323        Information from MATLAB:
+324            % T is a structure array with fields x & y where
+325            %   T.x contains x coordinates of vertices of an element triangle
+326            %   T.y contains y coordinates of vertices of an element triangle
+327            % beta is the average of the value at the vertices of the
+328            %   coefficient $$\beta = K(x) \lambda(s,c,\Gamma)$$
+329
+330            Analogous to the weak.m function in the MATLAB code
+331
+332        Args:
+333            T: T is a structure array with fields x & y where
+334            beta: beta is the average of the value at the vertices of the coefficient $$\beta = K(x) \lambda(s,c,\Gamma)$$
+335            V: FIXME: Need to add parameter definition here
+336
+337        Returns:
+338            FIXME: need to add definition here
+339        """
+340        beta_1 = self._beta_func(T["x"][0], T["y"][0], beta)
+341        beta_2 = self._beta_func(T["x"][1], T["y"][1], beta)
+342        beta_3 = self._beta_func(T["x"][2], T["y"][2], beta)
+343
+344        # computing average of the beta values at the vertices
+345        beta_avg = (beta_1 + beta_2 + beta_3) / 3
+346
+347        s = self._polyarea(T["x"], T["y"])
+348
+349        # Create and manipulate matrix M
+350        M = np.vstack((T["x"], T["y"], [1, 1, 1])).T
+351        M_inv = np.linalg.inv(M)
+352        M = M_inv[:2, :]  # Extract the first two rows of M_inv
+353
+354        # Calculate vdiff and inte
+355        vdiff = np.dot(M, V)
+356        inte = np.dot(vdiff.T, beta_avg * np.dot(M, s))
+357
+358        # Output result
+359        inte = np.append(inte, [0])
+360
+361        return inte
+362
+363    def set_FE_meshgrid(self, beta):
+364        """
+365        Generate FE coordinate grid for elliptic pressure calculations
+366        Analogous to the setGrid.m function in the MATLAB code
+367        """
+368        self.grid_size = np.empty((self.m + 1, self.n + 1), dtype=object)
+369
+370        for j in range(self.m + 1):
+371            for l in range(self.n + 1):
+372
+373                if j == 0 and l != 0 and l != self.n:
+374                    t1 = self._set_FE_meshgrid_helper(
+375                        self.L[j, l], beta, np.array([1, 0, 0])
+376                    )
+377                    t2 = np.array([0, 0, 0, 0])
+378                    t3 = np.array([0, 0, 0, 0])
+379                    t4 = np.array([0, 0, 0, 0])
+380                    t5 = self._set_FE_meshgrid_helper(
+381                        self.L[j, l - 1], beta, np.array([0, 0, 1])
+382                    )
+383                    t6 = self._set_FE_meshgrid_helper(
+384                        self.U[j, l - 1], beta, np.array([0, 1, 0])
+385                    )
+386
+387                if j == self.m and l != 0 and l != self.n:
+388                    t1 = np.array([0, 0, 0, 0])
+389                    t2 = self._set_FE_meshgrid_helper(
+390                        self.U[j - 1, l], beta, np.array([0, 0, 1])
+391                    )
+392                    t3 = self._set_FE_meshgrid_helper(
+393                        self.L[j - 1, l], beta, np.array([0, 1, 0])
+394                    )
+395                    t4 = self._set_FE_meshgrid_helper(
+396                        self.U[j - 1, l - 1], beta, np.array([1, 0, 0])
+397                    )
+398                    t5 = np.array([0, 0, 0, 0])
+399                    t6 = np.array([0, 0, 0, 0])
+400
+401                if j != 0 and j != self.m and l == 0:
+402                    t1 = self._set_FE_meshgrid_helper(
+403                        self.L[j, l], beta, np.array([1, 0, 0])
+404                    )
+405                    t2 = self._set_FE_meshgrid_helper(
+406                        self.U[j - 1, l], beta, np.array([0, 0, 1])
+407                    )
+408                    t3 = self._set_FE_meshgrid_helper(
+409                        self.L[j - 1, l], beta, np.array([0, 1, 0])
+410                    )
+411                    t4 = np.array([0, 0, 0, 0])
+412                    t5 = np.array([0, 0, 0, 0])
+413                    t6 = np.array([0, 0, 0, 0])
+414
+415                if j != 0 and j != self.m and l == self.n:
+416                    t1 = np.array([0, 0, 0, 0])
+417                    t2 = np.array([0, 0, 0, 0])
+418                    t3 = np.array([0, 0, 0, 0])
+419                    t4 = self._set_FE_meshgrid_helper(
+420                        self.U[j - 1, l - 1], beta, np.array([1, 0, 0])
+421                    )
+422                    t5 = self._set_FE_meshgrid_helper(
+423                        self.L[j, l - 1], beta, np.array([0, 0, 1])
+424                    )
+425                    t6 = self._set_FE_meshgrid_helper(
+426                        self.U[j, l - 1], beta, np.array([0, 1, 0])
+427                    )
+428
+429                if j == 0 and l == 0:
+430                    t1 = self._set_FE_meshgrid_helper(
+431                        self.L[j, l], beta, np.array([1, 0, 0])
+432                    )
+433                    t2 = np.array([0, 0, 0, 0])
+434                    t3 = np.array([0, 0, 0, 0])
+435                    t4 = np.array([0, 0, 0, 0])
+436                    t5 = np.array([0, 0, 0, 0])
+437                    t6 = np.array([0, 0, 0, 0])
+438
+439                if j == 0 and l == self.n:
+440                    t1 = np.array([0, 0, 0, 0])
+441                    t2 = np.array([0, 0, 0, 0])
+442                    t3 = np.array([0, 0, 0, 0])
+443                    t4 = np.array([0, 0, 0, 0])
+444                    t5 = self._set_FE_meshgrid_helper(
+445                        self.L[j, l - 1], beta, np.array([0, 0, 1])
+446                    )
+447                    t6 = self._set_FE_meshgrid_helper(
+448                        self.U[j, l - 1], beta, np.array([0, 1, 0])
+449                    )
+450
+451                if j == self.m and l == 0:
+452                    t1 = np.array([0, 0, 0, 0])
+453                    t2 = self._set_FE_meshgrid_helper(
+454                        self.U[j - 1, l], beta, np.array([0, 0, 1])
+455                    )
+456                    t3 = self._set_FE_meshgrid_helper(
+457                        self.L[j - 1, l], beta, np.array([0, 1, 0])
+458                    )
+459                    t4 = np.array([0, 0, 0, 0])
+460                    t5 = np.array([0, 0, 0, 0])
+461                    t6 = np.array([0, 0, 0, 0])
+462
+463                if j == self.m and l == self.n:
+464                    t1 = np.array([0, 0, 0, 0])
+465                    t2 = np.array([0, 0, 0, 0])
+466                    t3 = np.array([0, 0, 0, 0])
+467                    t4 = self._set_FE_meshgrid_helper(
+468                        self.U[j - 1, l - 1], beta, np.array([1, 0, 0])
+469                    )
+470                    t5 = np.array([0, 0, 0, 0])
+471                    t6 = np.array([0, 0, 0, 0])
+472
+473                if j != 0 and j != self.m and l != 0 and l != self.n:
+474                    t1 = self._set_FE_meshgrid_helper(
+475                        self.L[j, l], beta, np.array([1, 0, 0])
+476                    )
+477                    t2 = self._set_FE_meshgrid_helper(
+478                        self.U[j - 1, l], beta, np.array([0, 0, 1])
+479                    )
+480                    t3 = self._set_FE_meshgrid_helper(
+481                        self.L[j - 1, l], beta, np.array([0, 1, 0])
+482                    )
+483                    t4 = self._set_FE_meshgrid_helper(
+484                        self.U[j - 1, l - 1], beta, np.array([1, 0, 0])
+485                    )
+486                    t5 = self._set_FE_meshgrid_helper(
+487                        self.L[j, l - 1], beta, np.array([0, 0, 1])
+488                    )
+489                    t6 = self._set_FE_meshgrid_helper(
+490                        self.U[j, l - 1], beta, np.array([0, 1, 0])
+491                    )
+492
+493                # formulating grid
+494                grid = {
+495                    "c": t1[0] + t2[2] + t3[1] + t4[0] + t5[2] + t6[1],
+496                    "w": t3[0] + t4[1],
+497                    "s": t4[2] + t5[0],
+498                    "n": t1[2] + t2[0],
+499                    "e": t1[1] + t6[0],
+500                    "nw": t2[1] + t3[2],
+501                    "se": t5[1] + t6[2],
+502                    "const": t1[3] + t2[3] + t3[3] + t4[3] + t5[3] + t6[3],
+503                }
+504
+505                self.grid_size[j, l] = grid
+506
+507    def set_right_hand(self, source_prod_matrix):
+508        """
+509        Sets the right hand side of the equation being solved to update the global pressure and velocity matrices
+510        """
+511        self.right_hand = np.zeros(((self.m + 1) * (self.n + 1), 1))
+512
+513        for j in range(self.m + 1):
+514            for l in range(self.n + 1):
+515
+516                # finding corresponding index
+517                idx = j + l * (self.m + 1)
+518
+519                if j == 0 and l != 0 and l != self.n:
+520                    t1 = self._FInt(
+521                        self.L[j, l], source_prod_matrix, np.array([1, 0, 0])
+522                    )
+523                    t2 = 0
+524                    t3 = 0
+525                    t4 = 0
+526                    t5 = self._FInt(
+527                        self.L[j, l - 1], source_prod_matrix, np.array([0, 0, 1])
+528                    )
+529                    t6 = self._FInt(
+530                        self.U[j, l - 1], source_prod_matrix, np.array([0, 1, 0])
+531                    )
+532
+533                if j == self.m and l != 0 and l != self.n:
+534                    t1 = 0
+535                    t2 = self._FInt(
+536                        self.U[j - 1, l], source_prod_matrix, np.array([0, 0, 1])
+537                    )
+538                    t3 = self._FInt(
+539                        self.L[j - 1, l], source_prod_matrix, np.array([0, 1, 0])
+540                    )
+541                    t4 = self._FInt(
+542                        self.U[j - 1, l - 1], source_prod_matrix, np.array([1, 0, 0])
+543                    )
+544                    t5 = 0
+545                    t6 = 0
+546
+547                if j != 0 and j != self.m and l == 0:
+548                    t1 = self._FInt(
+549                        self.L[j, l], source_prod_matrix, np.array([1, 0, 0])
+550                    )
+551                    t2 = self._FInt(
+552                        self.U[j - 1, l], source_prod_matrix, np.array([0, 0, 1])
+553                    )
+554                    t3 = self._FInt(
+555                        self.L[j - 1, l], source_prod_matrix, np.array([0, 1, 0])
+556                    )
+557                    t4 = 0
+558                    t5 = 0
+559                    t6 = 0
+560
+561                if j != 0 and j != self.m and l == self.n:
+562                    t1 = 0
+563                    t2 = 0
+564                    t3 = 0
+565                    t4 = self._FInt(
+566                        self.U[j - 1, l - 1], source_prod_matrix, np.array([1, 0, 0])
+567                    )
+568                    t5 = self._FInt(
+569                        self.L[j, l - 1], source_prod_matrix, np.array([0, 0, 1])
+570                    )
+571                    t6 = self._FInt(
+572                        self.U[j, l - 1], source_prod_matrix, np.array([0, 1, 0])
+573                    )
+574
+575                if j == 0 and l == 0:
+576                    t1 = self._FInt(
+577                        self.L[j, l], source_prod_matrix, np.array([1, 0, 0])
+578                    )
+579                    t2 = 0
+580                    t3 = 0
+581                    t4 = 0
+582                    t5 = 0
+583                    t6 = 0
+584
+585                if j == 0 and l == self.n:
+586                    t1 = 0
+587                    t2 = 0
+588                    t3 = 0
+589                    t4 = 0
+590                    t5 = self._FInt(
+591                        self.L[j, l - 1], source_prod_matrix, np.array([0, 0, 1])
+592                    )
+593                    t6 = self._FInt(
+594                        self.U[j, l - 1], source_prod_matrix, np.array([0, 1, 0])
+595                    )
+596
+597                if j == self.m and l == 0:
+598                    t1 = 0
+599                    t2 = self._FInt(
+600                        self.U[j - 1, l], source_prod_matrix, np.array([0, 0, 1])
+601                    )
+602                    t3 = self._FInt(
+603                        self.L[j - 1, l], source_prod_matrix, np.array([0, 1, 0])
+604                    )
+605                    t4 = 0
+606                    t5 = 0
+607                    t6 = 0
+608
+609                if j == self.m and l == self.n:
+610                    t1 = 0
+611                    t2 = 0
+612                    t3 = 0
+613                    t4 = self._FInt(
+614                        self.U[j - 1, l - 1], source_prod_matrix, np.array([1, 0, 0])
+615                    )
+616                    t5 = 0
+617                    t6 = 0
+618
+619                if j != 0 and j != self.m and l != 0 and l != self.n:
+620                    t1 = self._FInt(
+621                        self.L[j, l], source_prod_matrix, np.array([1, 0, 0])
+622                    )
+623                    t2 = self._FInt(
+624                        self.U[j - 1, l], source_prod_matrix, np.array([0, 0, 1])
+625                    )
+626                    t3 = self._FInt(
+627                        self.L[j - 1, l], source_prod_matrix, np.array([0, 1, 0])
+628                    )
+629                    t4 = self._FInt(
+630                        self.U[j - 1, l - 1], source_prod_matrix, np.array([1, 0, 0])
+631                    )
+632                    t5 = self._FInt(
+633                        self.L[j, l - 1], source_prod_matrix, np.array([0, 0, 1])
+634                    )
+635                    t6 = self._FInt(
+636                        self.U[j, l - 1], source_prod_matrix, np.array([0, 1, 0])
+637                    )
+638
+639                # computing rh
+640                self.right_hand[idx] = t1 + t2 + t3 + t4 + t5 + t6
+641
+642    def _FInt(self, T, fmatrix, v):
+643        # evaluating source term at f at the vertices of the element triangle
+644        f_11 = self._f_func(T["x"][0], T["y"][0], fmatrix)
+645        f_12 = self._f_func(T["x"][1], T["y"][1], fmatrix)
+646        f_13 = self._f_func(T["x"][2], T["y"][2], fmatrix)
+647
+648        return self._trmatrix(T, f_11, f_12, f_13, v)
+649
+650    def _f_func(self, x, y, f):
+651        """
+652        Evaluates the source term 'f' at each grid point
+653            % f is non-zero only at injection and production wells
+654            % x and y are the coordinates of the grid point
+655            % The corresponding index locations in the matrix for f
+656            % are determined in mm and nn respectively.
+657        """
+658        mm = int(round((x - self.left) / self.dx))
+659        nn = int(round((y - self.bottom) / self.dy))
+660
+661        return f[nn, mm]
+662
+663    def _trmatrix(self, T, f_1, f_2, f_3, v):
+664        s = self._polyarea(T["x"], T["y"])
+665        f_c = (f_1 + f_2 + f_3) / 3
+666        v_c = (v[0] + v[1] + v[2]) / 3
+667        f_4 = (f_2 + f_3) / 2
+668        f_5 = (f_1 + f_3) / 2
+669        f_6 = (f_1 + f_2) / 2
+670
+671        v_4 = (v[1] + v[2]) / 2
+672        v_5 = (v[2] + v[0]) / 2
+673        v_6 = (v[0] + v[1]) / 2
+674
+675        return (f_4 * v_4 + f_5 * v_5 + f_6 * v_6 + f_c * v_c) * s / 4
+676
+677    def _set_A(self):
+678        """
+679        Assembles FEM stiffness matrix A
+680        Returns A as a sparse matrix
+681
+682        Corresponds to the SetA.m function in matlab
+683        """
+684        self.A = np.zeros(((self.m + 1) * (self.n + 1) * 7, 3))
+685        list_idx = 0
+686
+687        for j in range(self.m + 1):
+688            for l in range(self.n + 1):
+689
+690                a = self.grid_size[j, l]
+691                idx = j + l * (self.m + 1)
+692
+693                # center
+694                self.A[list_idx, :] = np.array([idx, idx, a["c"]])
+695                list_idx += 1
+696
+697                # west
+698                if j > 0:
+699                    self.A[list_idx, :] = np.array([idx, idx - 1, a["w"]])
+700                    list_idx += 1
+701
+702                # northwest
+703                if j > 0 and l < self.n:
+704                    self.A[list_idx, :] = np.array([idx, idx + self.m, a["nw"]])
+705                    list_idx += 1
+706
+707                # north
+708                if l < self.n:
+709                    self.A[list_idx, :] = np.array([idx, idx + (self.m + 1), a["n"]])
+710                    list_idx += 1
+711
+712                # east
+713                if j < self.m:
+714                    self.A[list_idx, :] = np.array([idx, idx + 1, a["e"]])
+715                    list_idx += 1
+716
+717                # south
+718                if l > 0:
+719                    self.A[list_idx, :] = np.array([idx, idx - (self.m + 1), a["s"]])
+720                    list_idx += 1
+721
+722                # southeast
+723                if j < self.m and l > 0:
+724                    self.A[list_idx, :] = np.array([idx, idx - self.m, a["se"]])
+725                    list_idx += 1
+726
+727        self.A = self.A[:list_idx, :]
+728
+729    def _set_B(self):
+730        self.B = np.zeros(((self.m + 1) * (self.n + 1), 1))
+731
+732        for j in range(self.m + 1):
+733            for l in range(self.n + 1):
+734
+735                a = self.grid_size[j, l]
+736                idx = j + l * (self.m + 1)
+737
+738                self.B[idx] = a["const"]
+739
+740        self.B = self.right_hand - self.B
+741
+742    def get_A_B_matrices(self):
+743        self._set_A()
+744        self._set_B()
+745
+746        # creating the sparsed matrix for A
+747        rows = np.ravel(self.A[:, 0].reshape(1, -1))
+748        cols = np.ravel(self.A[:, 1].reshape(1, -1))
+749        values = np.ravel(self.A[:, 2].reshape(1, -1))
+750        self.sparsed_A = coo_matrix(
+751            (values, (rows, cols)), shape=(np.shape(self.B)[0], np.shape(self.B)[0])
+752        )  # TODO: Verify correctedness of salf.sparsed_A
+
+ + +
+
+ +
+ + class + Grid: + + + +
+ +
 17class Grid:
+ 18    """
+ 19    Encapsulates mesh generation, triangulation, FEM matrix assembly, and source vector setup.
+ 20
+ 21    FIXME: Need to refactor this class to make it more understandable
+ 22    """
+ 23
+ 24    def __init__(
+ 25        self,
+ 26        m: int,
+ 27        n: int,
+ 28        left: float = 0.0,
+ 29        right: float = 1.0,
+ 30        bottom: float = 0.0,
+ 31        top: float = 1.0,
+ 32    ):
+ 33        self.m = m
+ 34        self.n = n
+ 35        self.left = left
+ 36        self.right = right
+ 37        self.bottom = bottom
+ 38        self.top = top
+ 39
+ 40        self.A = None
+ 41        self.B = None
+ 42
+ 43    _m = None
+ 44    @property
+ 45    def m(self):
+ 46        """
+ 47        The number of columns
+ 48        """
+ 49        return self._m
+ 50    @m.setter
+ 51    def m(self, value):
+ 52        self._m = value
+ 53    
+ 54    _n = None
+ 55    @property
+ 56    def n(self):
+ 57        """
+ 58        The number of rows
+ 59        """
+ 60        return self._n
+ 61    @n.setter
+ 62    def n(self, value):
+ 63        self._n = value
+ 64
+ 65    _left = None
+ 66    @property
+ 67    def left(self):
+ 68        """
+ 69        left most value on grid. Used to compute ``dx``. Has a default value of 0
+ 70        """
+ 71        return self._left
+ 72    @left.setter
+ 73    def left(self, value):
+ 74        self._left = value
+ 75
+ 76    _right = None
+ 77    @property
+ 78    def right(self):
+ 79        """
+ 80        right most value on grid. Used to compute ``dx``. Has a default value of 1.
+ 81        """
+ 82        return self._right
+ 83    @right.setter
+ 84    def right(self, value):
+ 85        self._right = value
+ 86
+ 87    _top = None
+ 88    @property
+ 89    def top(self):
+ 90        """
+ 91        Top most value on grid. Used to compute ``dy``. Has a default value of 1.
+ 92        """
+ 93        return self._top
+ 94    @top.setter
+ 95    def top(self, value):
+ 96        self._top = value
+ 97
+ 98    _bottom = None
+ 99    @property
+100    def bottom(self):
+101        """
+102        Bottom most value on grid. Used to compute ``dy``. Has a default value of 0.
+103        """
+104        return self._bottom
+105    @bottom.setter
+106    def bottom(self, value):
+107        self._bottom = value
+108
+109    _A = None
+110    @property
+111    def A(self):
+112        """
+113        A matrix for solving Ax = b
+114        """
+115        return self._A
+116    @A.setter
+117    def A(self, value):
+118        self._A = value
+119    
+120    _B = None
+121    @property
+122    def B(self):
+123        """
+124        b matrix for solving Ax = b
+125        """
+126        return self._B
+127    @B.setter
+128    def B(self, value):
+129        self._B = value
+130
+131    @property
+132    def get_spacing(self):
+133        """
+134        Provides dx and dy
+135        """
+136        return self.dx, self.dy
+137
+138    @property
+139    def get_meshgrid(self):
+140        """
+141        Generates the x and y coordinates for the FD Mesh
+142        """
+143        self.x, self.y = self.set_FD_meshgrid()
+144        return self.x, self.y
+145
+146    @property
+147    def dx(self):
+148        """
+149        Computes ``dx``
+150        """
+151        return (self.right - self.left) / self.m
+152
+153    @property
+154    def dy(self):
+155        """
+156        Computes ``dy`` 
+157        """
+158        return (self.top - self.bottom) / self.n
+159
+160    def set_FD_meshgrid(self):
+161        """
+162        Generates FD coordinate grid for SP-flooding.
+163        Used for the transport equations.
+164
+165        Returns:
+166            (x, y) meshgrid arrays
+167        """
+168        x = np.linspace(self.left, self.right, self.m + 1)
+169        y = np.linspace(self.bottom, self.top, self.n + 1)
+170        self.x, self.y = np.meshgrid(x, y)
+171        return self.x, self.y
+172
+173    def get_flat_index_matrix(self) -> np.ndarray:
+174        """
+175        Returns a matrix of shape (n+1, m+1) with flat indices at each grid point.
+176        """
+177        return np.arange((self.m + 1) * (self.n + 1)).reshape((self.n + 1, self.m + 1))
+
+ + +

Encapsulates mesh generation, triangulation, FEM matrix assembly, and source vector setup.

+ +

FIXME: Need to refactor this class to make it more understandable

+
+ + +
+ +
+ + Grid( m: int, n: int, left: float = 0.0, right: float = 1.0, bottom: float = 0.0, top: float = 1.0) + + + +
+ +
24    def __init__(
+25        self,
+26        m: int,
+27        n: int,
+28        left: float = 0.0,
+29        right: float = 1.0,
+30        bottom: float = 0.0,
+31        top: float = 1.0,
+32    ):
+33        self.m = m
+34        self.n = n
+35        self.left = left
+36        self.right = right
+37        self.bottom = bottom
+38        self.top = top
+39
+40        self.A = None
+41        self.B = None
+
+ + + + +
+
+ +
+ m + + + +
+ +
44    @property
+45    def m(self):
+46        """
+47        The number of columns
+48        """
+49        return self._m
+
+ + +

The number of columns

+
+ + +
+
+ +
+ n + + + +
+ +
55    @property
+56    def n(self):
+57        """
+58        The number of rows
+59        """
+60        return self._n
+
+ + +

The number of rows

+
+ + +
+
+ +
+ left + + + +
+ +
66    @property
+67    def left(self):
+68        """
+69        left most value on grid. Used to compute ``dx``. Has a default value of 0
+70        """
+71        return self._left
+
+ + +

left most value on grid. Used to compute dx. Has a default value of 0

+
+ + +
+
+ +
+ right + + + +
+ +
77    @property
+78    def right(self):
+79        """
+80        right most value on grid. Used to compute ``dx``. Has a default value of 1.
+81        """
+82        return self._right
+
+ + +

right most value on grid. Used to compute dx. Has a default value of 1.

+
+ + +
+
+ +
+ bottom + + + +
+ +
 99    @property
+100    def bottom(self):
+101        """
+102        Bottom most value on grid. Used to compute ``dy``. Has a default value of 0.
+103        """
+104        return self._bottom
+
+ + +

Bottom most value on grid. Used to compute dy. Has a default value of 0.

+
+ + +
+
+ +
+ top + + + +
+ +
88    @property
+89    def top(self):
+90        """
+91        Top most value on grid. Used to compute ``dy``. Has a default value of 1.
+92        """
+93        return self._top
+
+ + +

Top most value on grid. Used to compute dy. Has a default value of 1.

+
+ + +
+
+ +
+ A + + + +
+ +
110    @property
+111    def A(self):
+112        """
+113        A matrix for solving Ax = b
+114        """
+115        return self._A
+
+ + +

A matrix for solving Ax = b

+
+ + +
+
+ +
+ B + + + +
+ +
121    @property
+122    def B(self):
+123        """
+124        b matrix for solving Ax = b
+125        """
+126        return self._B
+
+ + +

b matrix for solving Ax = b

+
+ + +
+
+ +
+ get_spacing + + + +
+ +
131    @property
+132    def get_spacing(self):
+133        """
+134        Provides dx and dy
+135        """
+136        return self.dx, self.dy
+
+ + +

Provides dx and dy

+
+ + +
+
+ +
+ get_meshgrid + + + +
+ +
138    @property
+139    def get_meshgrid(self):
+140        """
+141        Generates the x and y coordinates for the FD Mesh
+142        """
+143        self.x, self.y = self.set_FD_meshgrid()
+144        return self.x, self.y
+
+ + +

Generates the x and y coordinates for the FD Mesh

+
+ + +
+
+ +
+ dx + + + +
+ +
146    @property
+147    def dx(self):
+148        """
+149        Computes ``dx``
+150        """
+151        return (self.right - self.left) / self.m
+
+ + +

Computes dx

+
+ + +
+
+ +
+ dy + + + +
+ +
153    @property
+154    def dy(self):
+155        """
+156        Computes ``dy`` 
+157        """
+158        return (self.top - self.bottom) / self.n
+
+ + +

Computes dy

+
+ + +
+
+ +
+ + def + set_FD_meshgrid(self): + + + +
+ +
160    def set_FD_meshgrid(self):
+161        """
+162        Generates FD coordinate grid for SP-flooding.
+163        Used for the transport equations.
+164
+165        Returns:
+166            (x, y) meshgrid arrays
+167        """
+168        x = np.linspace(self.left, self.right, self.m + 1)
+169        y = np.linspace(self.bottom, self.top, self.n + 1)
+170        self.x, self.y = np.meshgrid(x, y)
+171        return self.x, self.y
+
+ + +

Generates FD coordinate grid for SP-flooding. +Used for the transport equations.

+ +

Returns: + (x, y) meshgrid arrays

+
+ + +
+
+ +
+ + def + get_flat_index_matrix(self) -> numpy.ndarray: + + + +
+ +
173    def get_flat_index_matrix(self) -> np.ndarray:
+174        """
+175        Returns a matrix of shape (n+1, m+1) with flat indices at each grid point.
+176        """
+177        return np.arange((self.m + 1) * (self.n + 1)).reshape((self.n + 1, self.m + 1))
+
+ + +

Returns a matrix of shape (n+1, m+1) with flat indices at each grid point.

+
+ + +
+
+
+ +
+ + class + FEMesh(Grid): + + + +
+ +
180class FEMesh(Grid):
+181    def __init__(self, m: int, n: int):
+182        """
+183        Constructor for the ``FEMesh`` class (subclass of the ``Grid`` class)
+184
+185        Args:
+186            m (int): num columns
+187            n (int): num rows
+188        """
+189        super().__init__(m, n)
+190        self.U = None
+191        self.L = None
+192        self.grid_size = None
+193        self.right_hand = None
+194        self.A = None
+195        self.B = None
+196        self.sparsed_A = None
+197
+198    _sparsed_A = None
+199    @property
+200    def sparsed_A(self):
+201        """
+202        sparsed matrix version of matrix ``A``
+203        """
+204        return self._sparsed_A
+205    @sparsed_A.setter
+206    def sparsed_A(self, value):
+207        self._sparsed_A = value
+208
+209    _grid_size = None
+210    @property
+211    def grid_size(self):
+212        """
+213        row size of square grid (# rows = # cols)
+214        """
+215        return self._grid_size
+216    @grid_size.setter
+217    def grid_size(self, value):
+218        self._grid_size = value
+219
+220    _right_hand = None
+221    @property
+222    def right_hand(self):
+223        """
+224        Matrix representation of the rhs of the global pressure and velocity equations that will subsequently be used
+225        to solve for the global pressure and velocity matrices.
+226        """
+227        return self._right_hand
+228    @right_hand.setter
+229    def right_hand(self, value):
+230        self._right_hand = value
+231
+232    _U = None
+233    @property
+234    def U(self):
+235        """
+236        U = cell array with each element = array of vertices of Upper Triangle of
+237        the rectangular cell
+238        """
+239        return self._U
+240    @U.setter
+241    def U(self, value):
+242        self._U = value
+243
+244    _L = None
+245    @property
+246    def L(self):
+247        """
+248        L = cell array with each element = array of vertices of Lower Triangle of
+249        the rectangular cell
+250        """
+251        return self._L
+252    @L.setter
+253    def L(self, value):
+254        self._L = value
+255
+256    def set_triangulation(self):
+257        """
+258            Setting up triangulations for the FEM grid
+259            
+260            At every point (i,j), U{i,j} & L{i,j} are cells with coordinates of vertices
+261            of the two triangles obtained by bisecting the rectangle starting at
+262            (i,j). The bisection line goes from NW to SE.
+263        """
+264        self.U = np.empty((self.m, self.n), dtype=object)
+265        self.L = np.empty((self.m, self.n), dtype=object)
+266
+267        for j in range(self.m):
+268            for k in range(self.n):
+269                x1 = self.left + j * self.dx
+270                y1 = self.bottom + k * self.dy
+271                x2 = self.left + (j + 1) * self.dx
+272                y2 = y1
+273                x3 = x1
+274                y3 = self.bottom + (k + 1) * self.dy
+275                x4 = x2
+276                y4 = y3
+277
+278                # lower triangle vertices
+279                l = {"x": np.array([x1, x2, x3]), "y": np.array([y1, y2, y3])}
+280
+281                # upper triangle vertices
+282                u = {"x": np.array([x4, x3, x2]), "y": np.array([y4, y3, y2])}
+283
+284                self.U[j, k] = u
+285                self.L[j, k] = l
+286
+287    def _polyarea(self, x, y):
+288        """
+289        Calculate the area of a polygon using the Shoelace formula.
+290        The vertices are defined by the x and y coordinates.
+291
+292        Args:
+293            x (list or array): x-coordinates of the polygon vertices
+294            y (list or array): y-coordinates of the polygon vertices
+295
+296        Returns: (float)
+297            Area of the polygon
+298        """
+299        return 0.5 * abs(
+300            sum(x[i] * y[i + 1] - y[i] * x[i + 1] for i in range(-1, len(x) - 1))
+301        )
+302
+303    def _beta_func(self, x, y, beta):
+304        """
+305        Evaluates the coefficient beta at each grid point
+306        $$ \beta = K \lambda $$
+307        x and y are the coordinates of the grid point
+308        The corresponding index locations in the matrix for beta
+309        are determined in mm and nn respectively.
+310
+311        Analogous to beta_func.m in the MATLAB code
+312        """
+313        mm = round((x - self.left) / self.dx)
+314        nn = round((y - self.bottom) / self.dy)
+315
+316        return beta[
+317            int(nn), int(mm)
+318        ]  # nn and mm are casted to integers for indexing purposes
+319
+320    def _set_FE_meshgrid_helper(self, T, beta, V):
+321        """
+322        Evaluates beta at the vertices of the element triangle
+323
+324        Information from MATLAB:
+325            % T is a structure array with fields x & y where
+326            %   T.x contains x coordinates of vertices of an element triangle
+327            %   T.y contains y coordinates of vertices of an element triangle
+328            % beta is the average of the value at the vertices of the
+329            %   coefficient $$\beta = K(x) \lambda(s,c,\Gamma)$$
+330
+331            Analogous to the weak.m function in the MATLAB code
+332
+333        Args:
+334            T: T is a structure array with fields x & y where
+335            beta: beta is the average of the value at the vertices of the coefficient $$\beta = K(x) \lambda(s,c,\Gamma)$$
+336            V: FIXME: Need to add parameter definition here
+337
+338        Returns:
+339            FIXME: need to add definition here
+340        """
+341        beta_1 = self._beta_func(T["x"][0], T["y"][0], beta)
+342        beta_2 = self._beta_func(T["x"][1], T["y"][1], beta)
+343        beta_3 = self._beta_func(T["x"][2], T["y"][2], beta)
+344
+345        # computing average of the beta values at the vertices
+346        beta_avg = (beta_1 + beta_2 + beta_3) / 3
+347
+348        s = self._polyarea(T["x"], T["y"])
+349
+350        # Create and manipulate matrix M
+351        M = np.vstack((T["x"], T["y"], [1, 1, 1])).T
+352        M_inv = np.linalg.inv(M)
+353        M = M_inv[:2, :]  # Extract the first two rows of M_inv
+354
+355        # Calculate vdiff and inte
+356        vdiff = np.dot(M, V)
+357        inte = np.dot(vdiff.T, beta_avg * np.dot(M, s))
+358
+359        # Output result
+360        inte = np.append(inte, [0])
+361
+362        return inte
+363
+364    def set_FE_meshgrid(self, beta):
+365        """
+366        Generate FE coordinate grid for elliptic pressure calculations
+367        Analogous to the setGrid.m function in the MATLAB code
+368        """
+369        self.grid_size = np.empty((self.m + 1, self.n + 1), dtype=object)
+370
+371        for j in range(self.m + 1):
+372            for l in range(self.n + 1):
+373
+374                if j == 0 and l != 0 and l != self.n:
+375                    t1 = self._set_FE_meshgrid_helper(
+376                        self.L[j, l], beta, np.array([1, 0, 0])
+377                    )
+378                    t2 = np.array([0, 0, 0, 0])
+379                    t3 = np.array([0, 0, 0, 0])
+380                    t4 = np.array([0, 0, 0, 0])
+381                    t5 = self._set_FE_meshgrid_helper(
+382                        self.L[j, l - 1], beta, np.array([0, 0, 1])
+383                    )
+384                    t6 = self._set_FE_meshgrid_helper(
+385                        self.U[j, l - 1], beta, np.array([0, 1, 0])
+386                    )
+387
+388                if j == self.m and l != 0 and l != self.n:
+389                    t1 = np.array([0, 0, 0, 0])
+390                    t2 = self._set_FE_meshgrid_helper(
+391                        self.U[j - 1, l], beta, np.array([0, 0, 1])
+392                    )
+393                    t3 = self._set_FE_meshgrid_helper(
+394                        self.L[j - 1, l], beta, np.array([0, 1, 0])
+395                    )
+396                    t4 = self._set_FE_meshgrid_helper(
+397                        self.U[j - 1, l - 1], beta, np.array([1, 0, 0])
+398                    )
+399                    t5 = np.array([0, 0, 0, 0])
+400                    t6 = np.array([0, 0, 0, 0])
+401
+402                if j != 0 and j != self.m and l == 0:
+403                    t1 = self._set_FE_meshgrid_helper(
+404                        self.L[j, l], beta, np.array([1, 0, 0])
+405                    )
+406                    t2 = self._set_FE_meshgrid_helper(
+407                        self.U[j - 1, l], beta, np.array([0, 0, 1])
+408                    )
+409                    t3 = self._set_FE_meshgrid_helper(
+410                        self.L[j - 1, l], beta, np.array([0, 1, 0])
+411                    )
+412                    t4 = np.array([0, 0, 0, 0])
+413                    t5 = np.array([0, 0, 0, 0])
+414                    t6 = np.array([0, 0, 0, 0])
+415
+416                if j != 0 and j != self.m and l == self.n:
+417                    t1 = np.array([0, 0, 0, 0])
+418                    t2 = np.array([0, 0, 0, 0])
+419                    t3 = np.array([0, 0, 0, 0])
+420                    t4 = self._set_FE_meshgrid_helper(
+421                        self.U[j - 1, l - 1], beta, np.array([1, 0, 0])
+422                    )
+423                    t5 = self._set_FE_meshgrid_helper(
+424                        self.L[j, l - 1], beta, np.array([0, 0, 1])
+425                    )
+426                    t6 = self._set_FE_meshgrid_helper(
+427                        self.U[j, l - 1], beta, np.array([0, 1, 0])
+428                    )
+429
+430                if j == 0 and l == 0:
+431                    t1 = self._set_FE_meshgrid_helper(
+432                        self.L[j, l], beta, np.array([1, 0, 0])
+433                    )
+434                    t2 = np.array([0, 0, 0, 0])
+435                    t3 = np.array([0, 0, 0, 0])
+436                    t4 = np.array([0, 0, 0, 0])
+437                    t5 = np.array([0, 0, 0, 0])
+438                    t6 = np.array([0, 0, 0, 0])
+439
+440                if j == 0 and l == self.n:
+441                    t1 = np.array([0, 0, 0, 0])
+442                    t2 = np.array([0, 0, 0, 0])
+443                    t3 = np.array([0, 0, 0, 0])
+444                    t4 = np.array([0, 0, 0, 0])
+445                    t5 = self._set_FE_meshgrid_helper(
+446                        self.L[j, l - 1], beta, np.array([0, 0, 1])
+447                    )
+448                    t6 = self._set_FE_meshgrid_helper(
+449                        self.U[j, l - 1], beta, np.array([0, 1, 0])
+450                    )
+451
+452                if j == self.m and l == 0:
+453                    t1 = np.array([0, 0, 0, 0])
+454                    t2 = self._set_FE_meshgrid_helper(
+455                        self.U[j - 1, l], beta, np.array([0, 0, 1])
+456                    )
+457                    t3 = self._set_FE_meshgrid_helper(
+458                        self.L[j - 1, l], beta, np.array([0, 1, 0])
+459                    )
+460                    t4 = np.array([0, 0, 0, 0])
+461                    t5 = np.array([0, 0, 0, 0])
+462                    t6 = np.array([0, 0, 0, 0])
+463
+464                if j == self.m and l == self.n:
+465                    t1 = np.array([0, 0, 0, 0])
+466                    t2 = np.array([0, 0, 0, 0])
+467                    t3 = np.array([0, 0, 0, 0])
+468                    t4 = self._set_FE_meshgrid_helper(
+469                        self.U[j - 1, l - 1], beta, np.array([1, 0, 0])
+470                    )
+471                    t5 = np.array([0, 0, 0, 0])
+472                    t6 = np.array([0, 0, 0, 0])
+473
+474                if j != 0 and j != self.m and l != 0 and l != self.n:
+475                    t1 = self._set_FE_meshgrid_helper(
+476                        self.L[j, l], beta, np.array([1, 0, 0])
+477                    )
+478                    t2 = self._set_FE_meshgrid_helper(
+479                        self.U[j - 1, l], beta, np.array([0, 0, 1])
+480                    )
+481                    t3 = self._set_FE_meshgrid_helper(
+482                        self.L[j - 1, l], beta, np.array([0, 1, 0])
+483                    )
+484                    t4 = self._set_FE_meshgrid_helper(
+485                        self.U[j - 1, l - 1], beta, np.array([1, 0, 0])
+486                    )
+487                    t5 = self._set_FE_meshgrid_helper(
+488                        self.L[j, l - 1], beta, np.array([0, 0, 1])
+489                    )
+490                    t6 = self._set_FE_meshgrid_helper(
+491                        self.U[j, l - 1], beta, np.array([0, 1, 0])
+492                    )
+493
+494                # formulating grid
+495                grid = {
+496                    "c": t1[0] + t2[2] + t3[1] + t4[0] + t5[2] + t6[1],
+497                    "w": t3[0] + t4[1],
+498                    "s": t4[2] + t5[0],
+499                    "n": t1[2] + t2[0],
+500                    "e": t1[1] + t6[0],
+501                    "nw": t2[1] + t3[2],
+502                    "se": t5[1] + t6[2],
+503                    "const": t1[3] + t2[3] + t3[3] + t4[3] + t5[3] + t6[3],
+504                }
+505
+506                self.grid_size[j, l] = grid
+507
+508    def set_right_hand(self, source_prod_matrix):
+509        """
+510        Sets the right hand side of the equation being solved to update the global pressure and velocity matrices
+511        """
+512        self.right_hand = np.zeros(((self.m + 1) * (self.n + 1), 1))
+513
+514        for j in range(self.m + 1):
+515            for l in range(self.n + 1):
+516
+517                # finding corresponding index
+518                idx = j + l * (self.m + 1)
+519
+520                if j == 0 and l != 0 and l != self.n:
+521                    t1 = self._FInt(
+522                        self.L[j, l], source_prod_matrix, np.array([1, 0, 0])
+523                    )
+524                    t2 = 0
+525                    t3 = 0
+526                    t4 = 0
+527                    t5 = self._FInt(
+528                        self.L[j, l - 1], source_prod_matrix, np.array([0, 0, 1])
+529                    )
+530                    t6 = self._FInt(
+531                        self.U[j, l - 1], source_prod_matrix, np.array([0, 1, 0])
+532                    )
+533
+534                if j == self.m and l != 0 and l != self.n:
+535                    t1 = 0
+536                    t2 = self._FInt(
+537                        self.U[j - 1, l], source_prod_matrix, np.array([0, 0, 1])
+538                    )
+539                    t3 = self._FInt(
+540                        self.L[j - 1, l], source_prod_matrix, np.array([0, 1, 0])
+541                    )
+542                    t4 = self._FInt(
+543                        self.U[j - 1, l - 1], source_prod_matrix, np.array([1, 0, 0])
+544                    )
+545                    t5 = 0
+546                    t6 = 0
+547
+548                if j != 0 and j != self.m and l == 0:
+549                    t1 = self._FInt(
+550                        self.L[j, l], source_prod_matrix, np.array([1, 0, 0])
+551                    )
+552                    t2 = self._FInt(
+553                        self.U[j - 1, l], source_prod_matrix, np.array([0, 0, 1])
+554                    )
+555                    t3 = self._FInt(
+556                        self.L[j - 1, l], source_prod_matrix, np.array([0, 1, 0])
+557                    )
+558                    t4 = 0
+559                    t5 = 0
+560                    t6 = 0
+561
+562                if j != 0 and j != self.m and l == self.n:
+563                    t1 = 0
+564                    t2 = 0
+565                    t3 = 0
+566                    t4 = self._FInt(
+567                        self.U[j - 1, l - 1], source_prod_matrix, np.array([1, 0, 0])
+568                    )
+569                    t5 = self._FInt(
+570                        self.L[j, l - 1], source_prod_matrix, np.array([0, 0, 1])
+571                    )
+572                    t6 = self._FInt(
+573                        self.U[j, l - 1], source_prod_matrix, np.array([0, 1, 0])
+574                    )
+575
+576                if j == 0 and l == 0:
+577                    t1 = self._FInt(
+578                        self.L[j, l], source_prod_matrix, np.array([1, 0, 0])
+579                    )
+580                    t2 = 0
+581                    t3 = 0
+582                    t4 = 0
+583                    t5 = 0
+584                    t6 = 0
+585
+586                if j == 0 and l == self.n:
+587                    t1 = 0
+588                    t2 = 0
+589                    t3 = 0
+590                    t4 = 0
+591                    t5 = self._FInt(
+592                        self.L[j, l - 1], source_prod_matrix, np.array([0, 0, 1])
+593                    )
+594                    t6 = self._FInt(
+595                        self.U[j, l - 1], source_prod_matrix, np.array([0, 1, 0])
+596                    )
+597
+598                if j == self.m and l == 0:
+599                    t1 = 0
+600                    t2 = self._FInt(
+601                        self.U[j - 1, l], source_prod_matrix, np.array([0, 0, 1])
+602                    )
+603                    t3 = self._FInt(
+604                        self.L[j - 1, l], source_prod_matrix, np.array([0, 1, 0])
+605                    )
+606                    t4 = 0
+607                    t5 = 0
+608                    t6 = 0
+609
+610                if j == self.m and l == self.n:
+611                    t1 = 0
+612                    t2 = 0
+613                    t3 = 0
+614                    t4 = self._FInt(
+615                        self.U[j - 1, l - 1], source_prod_matrix, np.array([1, 0, 0])
+616                    )
+617                    t5 = 0
+618                    t6 = 0
+619
+620                if j != 0 and j != self.m and l != 0 and l != self.n:
+621                    t1 = self._FInt(
+622                        self.L[j, l], source_prod_matrix, np.array([1, 0, 0])
+623                    )
+624                    t2 = self._FInt(
+625                        self.U[j - 1, l], source_prod_matrix, np.array([0, 0, 1])
+626                    )
+627                    t3 = self._FInt(
+628                        self.L[j - 1, l], source_prod_matrix, np.array([0, 1, 0])
+629                    )
+630                    t4 = self._FInt(
+631                        self.U[j - 1, l - 1], source_prod_matrix, np.array([1, 0, 0])
+632                    )
+633                    t5 = self._FInt(
+634                        self.L[j, l - 1], source_prod_matrix, np.array([0, 0, 1])
+635                    )
+636                    t6 = self._FInt(
+637                        self.U[j, l - 1], source_prod_matrix, np.array([0, 1, 0])
+638                    )
+639
+640                # computing rh
+641                self.right_hand[idx] = t1 + t2 + t3 + t4 + t5 + t6
+642
+643    def _FInt(self, T, fmatrix, v):
+644        # evaluating source term at f at the vertices of the element triangle
+645        f_11 = self._f_func(T["x"][0], T["y"][0], fmatrix)
+646        f_12 = self._f_func(T["x"][1], T["y"][1], fmatrix)
+647        f_13 = self._f_func(T["x"][2], T["y"][2], fmatrix)
+648
+649        return self._trmatrix(T, f_11, f_12, f_13, v)
+650
+651    def _f_func(self, x, y, f):
+652        """
+653        Evaluates the source term 'f' at each grid point
+654            % f is non-zero only at injection and production wells
+655            % x and y are the coordinates of the grid point
+656            % The corresponding index locations in the matrix for f
+657            % are determined in mm and nn respectively.
+658        """
+659        mm = int(round((x - self.left) / self.dx))
+660        nn = int(round((y - self.bottom) / self.dy))
+661
+662        return f[nn, mm]
+663
+664    def _trmatrix(self, T, f_1, f_2, f_3, v):
+665        s = self._polyarea(T["x"], T["y"])
+666        f_c = (f_1 + f_2 + f_3) / 3
+667        v_c = (v[0] + v[1] + v[2]) / 3
+668        f_4 = (f_2 + f_3) / 2
+669        f_5 = (f_1 + f_3) / 2
+670        f_6 = (f_1 + f_2) / 2
+671
+672        v_4 = (v[1] + v[2]) / 2
+673        v_5 = (v[2] + v[0]) / 2
+674        v_6 = (v[0] + v[1]) / 2
+675
+676        return (f_4 * v_4 + f_5 * v_5 + f_6 * v_6 + f_c * v_c) * s / 4
+677
+678    def _set_A(self):
+679        """
+680        Assembles FEM stiffness matrix A
+681        Returns A as a sparse matrix
+682
+683        Corresponds to the SetA.m function in matlab
+684        """
+685        self.A = np.zeros(((self.m + 1) * (self.n + 1) * 7, 3))
+686        list_idx = 0
+687
+688        for j in range(self.m + 1):
+689            for l in range(self.n + 1):
+690
+691                a = self.grid_size[j, l]
+692                idx = j + l * (self.m + 1)
+693
+694                # center
+695                self.A[list_idx, :] = np.array([idx, idx, a["c"]])
+696                list_idx += 1
+697
+698                # west
+699                if j > 0:
+700                    self.A[list_idx, :] = np.array([idx, idx - 1, a["w"]])
+701                    list_idx += 1
+702
+703                # northwest
+704                if j > 0 and l < self.n:
+705                    self.A[list_idx, :] = np.array([idx, idx + self.m, a["nw"]])
+706                    list_idx += 1
+707
+708                # north
+709                if l < self.n:
+710                    self.A[list_idx, :] = np.array([idx, idx + (self.m + 1), a["n"]])
+711                    list_idx += 1
+712
+713                # east
+714                if j < self.m:
+715                    self.A[list_idx, :] = np.array([idx, idx + 1, a["e"]])
+716                    list_idx += 1
+717
+718                # south
+719                if l > 0:
+720                    self.A[list_idx, :] = np.array([idx, idx - (self.m + 1), a["s"]])
+721                    list_idx += 1
+722
+723                # southeast
+724                if j < self.m and l > 0:
+725                    self.A[list_idx, :] = np.array([idx, idx - self.m, a["se"]])
+726                    list_idx += 1
+727
+728        self.A = self.A[:list_idx, :]
+729
+730    def _set_B(self):
+731        self.B = np.zeros(((self.m + 1) * (self.n + 1), 1))
+732
+733        for j in range(self.m + 1):
+734            for l in range(self.n + 1):
+735
+736                a = self.grid_size[j, l]
+737                idx = j + l * (self.m + 1)
+738
+739                self.B[idx] = a["const"]
+740
+741        self.B = self.right_hand - self.B
+742
+743    def get_A_B_matrices(self):
+744        self._set_A()
+745        self._set_B()
+746
+747        # creating the sparsed matrix for A
+748        rows = np.ravel(self.A[:, 0].reshape(1, -1))
+749        cols = np.ravel(self.A[:, 1].reshape(1, -1))
+750        values = np.ravel(self.A[:, 2].reshape(1, -1))
+751        self.sparsed_A = coo_matrix(
+752            (values, (rows, cols)), shape=(np.shape(self.B)[0], np.shape(self.B)[0])
+753        )  # TODO: Verify correctedness of salf.sparsed_A
+
+ + +

Encapsulates mesh generation, triangulation, FEM matrix assembly, and source vector setup.

+ +

FIXME: Need to refactor this class to make it more understandable

+
+ + +
+ +
+ + FEMesh(m: int, n: int) + + + +
+ +
181    def __init__(self, m: int, n: int):
+182        """
+183        Constructor for the ``FEMesh`` class (subclass of the ``Grid`` class)
+184
+185        Args:
+186            m (int): num columns
+187            n (int): num rows
+188        """
+189        super().__init__(m, n)
+190        self.U = None
+191        self.L = None
+192        self.grid_size = None
+193        self.right_hand = None
+194        self.A = None
+195        self.B = None
+196        self.sparsed_A = None
+
+ + +

Constructor for the FEMesh class (subclass of the Grid class)

+ +

Args: + m (int): num columns + n (int): num rows

+
+ + +
+
+ +
+ U + + + +
+ +
233    @property
+234    def U(self):
+235        """
+236        U = cell array with each element = array of vertices of Upper Triangle of
+237        the rectangular cell
+238        """
+239        return self._U
+
+ + +

U = cell array with each element = array of vertices of Upper Triangle of +the rectangular cell

+
+ + +
+
+ +
+ L + + + +
+ +
245    @property
+246    def L(self):
+247        """
+248        L = cell array with each element = array of vertices of Lower Triangle of
+249        the rectangular cell
+250        """
+251        return self._L
+
+ + +

L = cell array with each element = array of vertices of Lower Triangle of +the rectangular cell

+
+ + +
+
+ +
+ grid_size + + + +
+ +
210    @property
+211    def grid_size(self):
+212        """
+213        row size of square grid (# rows = # cols)
+214        """
+215        return self._grid_size
+
+ + +

row size of square grid (# rows = # cols)

+
+ + +
+
+ +
+ right_hand + + + +
+ +
221    @property
+222    def right_hand(self):
+223        """
+224        Matrix representation of the rhs of the global pressure and velocity equations that will subsequently be used
+225        to solve for the global pressure and velocity matrices.
+226        """
+227        return self._right_hand
+
+ + +

Matrix representation of the rhs of the global pressure and velocity equations that will subsequently be used +to solve for the global pressure and velocity matrices.

+
+ + +
+
+ +
+ A + + + +
+ +
110    @property
+111    def A(self):
+112        """
+113        A matrix for solving Ax = b
+114        """
+115        return self._A
+
+ + +

A matrix for solving Ax = b

+
+ + +
+
+ +
+ B + + + +
+ +
121    @property
+122    def B(self):
+123        """
+124        b matrix for solving Ax = b
+125        """
+126        return self._B
+
+ + +

b matrix for solving Ax = b

+
+ + +
+
+ +
+ sparsed_A + + + +
+ +
199    @property
+200    def sparsed_A(self):
+201        """
+202        sparsed matrix version of matrix ``A``
+203        """
+204        return self._sparsed_A
+
+ + +

sparsed matrix version of matrix A

+
+ + +
+
+ +
+ + def + set_triangulation(self): + + + +
+ +
256    def set_triangulation(self):
+257        """
+258            Setting up triangulations for the FEM grid
+259            
+260            At every point (i,j), U{i,j} & L{i,j} are cells with coordinates of vertices
+261            of the two triangles obtained by bisecting the rectangle starting at
+262            (i,j). The bisection line goes from NW to SE.
+263        """
+264        self.U = np.empty((self.m, self.n), dtype=object)
+265        self.L = np.empty((self.m, self.n), dtype=object)
+266
+267        for j in range(self.m):
+268            for k in range(self.n):
+269                x1 = self.left + j * self.dx
+270                y1 = self.bottom + k * self.dy
+271                x2 = self.left + (j + 1) * self.dx
+272                y2 = y1
+273                x3 = x1
+274                y3 = self.bottom + (k + 1) * self.dy
+275                x4 = x2
+276                y4 = y3
+277
+278                # lower triangle vertices
+279                l = {"x": np.array([x1, x2, x3]), "y": np.array([y1, y2, y3])}
+280
+281                # upper triangle vertices
+282                u = {"x": np.array([x4, x3, x2]), "y": np.array([y4, y3, y2])}
+283
+284                self.U[j, k] = u
+285                self.L[j, k] = l
+
+ + +

Setting up triangulations for the FEM grid

+ +

At every point (i,j), U{i,j} & L{i,j} are cells with coordinates of vertices +of the two triangles obtained by bisecting the rectangle starting at +(i,j). The bisection line goes from NW to SE.

+
+ + +
+
+ +
+ + def + set_FE_meshgrid(self, beta): + + + +
+ +
364    def set_FE_meshgrid(self, beta):
+365        """
+366        Generate FE coordinate grid for elliptic pressure calculations
+367        Analogous to the setGrid.m function in the MATLAB code
+368        """
+369        self.grid_size = np.empty((self.m + 1, self.n + 1), dtype=object)
+370
+371        for j in range(self.m + 1):
+372            for l in range(self.n + 1):
+373
+374                if j == 0 and l != 0 and l != self.n:
+375                    t1 = self._set_FE_meshgrid_helper(
+376                        self.L[j, l], beta, np.array([1, 0, 0])
+377                    )
+378                    t2 = np.array([0, 0, 0, 0])
+379                    t3 = np.array([0, 0, 0, 0])
+380                    t4 = np.array([0, 0, 0, 0])
+381                    t5 = self._set_FE_meshgrid_helper(
+382                        self.L[j, l - 1], beta, np.array([0, 0, 1])
+383                    )
+384                    t6 = self._set_FE_meshgrid_helper(
+385                        self.U[j, l - 1], beta, np.array([0, 1, 0])
+386                    )
+387
+388                if j == self.m and l != 0 and l != self.n:
+389                    t1 = np.array([0, 0, 0, 0])
+390                    t2 = self._set_FE_meshgrid_helper(
+391                        self.U[j - 1, l], beta, np.array([0, 0, 1])
+392                    )
+393                    t3 = self._set_FE_meshgrid_helper(
+394                        self.L[j - 1, l], beta, np.array([0, 1, 0])
+395                    )
+396                    t4 = self._set_FE_meshgrid_helper(
+397                        self.U[j - 1, l - 1], beta, np.array([1, 0, 0])
+398                    )
+399                    t5 = np.array([0, 0, 0, 0])
+400                    t6 = np.array([0, 0, 0, 0])
+401
+402                if j != 0 and j != self.m and l == 0:
+403                    t1 = self._set_FE_meshgrid_helper(
+404                        self.L[j, l], beta, np.array([1, 0, 0])
+405                    )
+406                    t2 = self._set_FE_meshgrid_helper(
+407                        self.U[j - 1, l], beta, np.array([0, 0, 1])
+408                    )
+409                    t3 = self._set_FE_meshgrid_helper(
+410                        self.L[j - 1, l], beta, np.array([0, 1, 0])
+411                    )
+412                    t4 = np.array([0, 0, 0, 0])
+413                    t5 = np.array([0, 0, 0, 0])
+414                    t6 = np.array([0, 0, 0, 0])
+415
+416                if j != 0 and j != self.m and l == self.n:
+417                    t1 = np.array([0, 0, 0, 0])
+418                    t2 = np.array([0, 0, 0, 0])
+419                    t3 = np.array([0, 0, 0, 0])
+420                    t4 = self._set_FE_meshgrid_helper(
+421                        self.U[j - 1, l - 1], beta, np.array([1, 0, 0])
+422                    )
+423                    t5 = self._set_FE_meshgrid_helper(
+424                        self.L[j, l - 1], beta, np.array([0, 0, 1])
+425                    )
+426                    t6 = self._set_FE_meshgrid_helper(
+427                        self.U[j, l - 1], beta, np.array([0, 1, 0])
+428                    )
+429
+430                if j == 0 and l == 0:
+431                    t1 = self._set_FE_meshgrid_helper(
+432                        self.L[j, l], beta, np.array([1, 0, 0])
+433                    )
+434                    t2 = np.array([0, 0, 0, 0])
+435                    t3 = np.array([0, 0, 0, 0])
+436                    t4 = np.array([0, 0, 0, 0])
+437                    t5 = np.array([0, 0, 0, 0])
+438                    t6 = np.array([0, 0, 0, 0])
+439
+440                if j == 0 and l == self.n:
+441                    t1 = np.array([0, 0, 0, 0])
+442                    t2 = np.array([0, 0, 0, 0])
+443                    t3 = np.array([0, 0, 0, 0])
+444                    t4 = np.array([0, 0, 0, 0])
+445                    t5 = self._set_FE_meshgrid_helper(
+446                        self.L[j, l - 1], beta, np.array([0, 0, 1])
+447                    )
+448                    t6 = self._set_FE_meshgrid_helper(
+449                        self.U[j, l - 1], beta, np.array([0, 1, 0])
+450                    )
+451
+452                if j == self.m and l == 0:
+453                    t1 = np.array([0, 0, 0, 0])
+454                    t2 = self._set_FE_meshgrid_helper(
+455                        self.U[j - 1, l], beta, np.array([0, 0, 1])
+456                    )
+457                    t3 = self._set_FE_meshgrid_helper(
+458                        self.L[j - 1, l], beta, np.array([0, 1, 0])
+459                    )
+460                    t4 = np.array([0, 0, 0, 0])
+461                    t5 = np.array([0, 0, 0, 0])
+462                    t6 = np.array([0, 0, 0, 0])
+463
+464                if j == self.m and l == self.n:
+465                    t1 = np.array([0, 0, 0, 0])
+466                    t2 = np.array([0, 0, 0, 0])
+467                    t3 = np.array([0, 0, 0, 0])
+468                    t4 = self._set_FE_meshgrid_helper(
+469                        self.U[j - 1, l - 1], beta, np.array([1, 0, 0])
+470                    )
+471                    t5 = np.array([0, 0, 0, 0])
+472                    t6 = np.array([0, 0, 0, 0])
+473
+474                if j != 0 and j != self.m and l != 0 and l != self.n:
+475                    t1 = self._set_FE_meshgrid_helper(
+476                        self.L[j, l], beta, np.array([1, 0, 0])
+477                    )
+478                    t2 = self._set_FE_meshgrid_helper(
+479                        self.U[j - 1, l], beta, np.array([0, 0, 1])
+480                    )
+481                    t3 = self._set_FE_meshgrid_helper(
+482                        self.L[j - 1, l], beta, np.array([0, 1, 0])
+483                    )
+484                    t4 = self._set_FE_meshgrid_helper(
+485                        self.U[j - 1, l - 1], beta, np.array([1, 0, 0])
+486                    )
+487                    t5 = self._set_FE_meshgrid_helper(
+488                        self.L[j, l - 1], beta, np.array([0, 0, 1])
+489                    )
+490                    t6 = self._set_FE_meshgrid_helper(
+491                        self.U[j, l - 1], beta, np.array([0, 1, 0])
+492                    )
+493
+494                # formulating grid
+495                grid = {
+496                    "c": t1[0] + t2[2] + t3[1] + t4[0] + t5[2] + t6[1],
+497                    "w": t3[0] + t4[1],
+498                    "s": t4[2] + t5[0],
+499                    "n": t1[2] + t2[0],
+500                    "e": t1[1] + t6[0],
+501                    "nw": t2[1] + t3[2],
+502                    "se": t5[1] + t6[2],
+503                    "const": t1[3] + t2[3] + t3[3] + t4[3] + t5[3] + t6[3],
+504                }
+505
+506                self.grid_size[j, l] = grid
+
+ + +

Generate FE coordinate grid for elliptic pressure calculations +Analogous to the setGrid.m function in the MATLAB code

+
+ + +
+
+ +
+ + def + set_right_hand(self, source_prod_matrix): + + + +
+ +
508    def set_right_hand(self, source_prod_matrix):
+509        """
+510        Sets the right hand side of the equation being solved to update the global pressure and velocity matrices
+511        """
+512        self.right_hand = np.zeros(((self.m + 1) * (self.n + 1), 1))
+513
+514        for j in range(self.m + 1):
+515            for l in range(self.n + 1):
+516
+517                # finding corresponding index
+518                idx = j + l * (self.m + 1)
+519
+520                if j == 0 and l != 0 and l != self.n:
+521                    t1 = self._FInt(
+522                        self.L[j, l], source_prod_matrix, np.array([1, 0, 0])
+523                    )
+524                    t2 = 0
+525                    t3 = 0
+526                    t4 = 0
+527                    t5 = self._FInt(
+528                        self.L[j, l - 1], source_prod_matrix, np.array([0, 0, 1])
+529                    )
+530                    t6 = self._FInt(
+531                        self.U[j, l - 1], source_prod_matrix, np.array([0, 1, 0])
+532                    )
+533
+534                if j == self.m and l != 0 and l != self.n:
+535                    t1 = 0
+536                    t2 = self._FInt(
+537                        self.U[j - 1, l], source_prod_matrix, np.array([0, 0, 1])
+538                    )
+539                    t3 = self._FInt(
+540                        self.L[j - 1, l], source_prod_matrix, np.array([0, 1, 0])
+541                    )
+542                    t4 = self._FInt(
+543                        self.U[j - 1, l - 1], source_prod_matrix, np.array([1, 0, 0])
+544                    )
+545                    t5 = 0
+546                    t6 = 0
+547
+548                if j != 0 and j != self.m and l == 0:
+549                    t1 = self._FInt(
+550                        self.L[j, l], source_prod_matrix, np.array([1, 0, 0])
+551                    )
+552                    t2 = self._FInt(
+553                        self.U[j - 1, l], source_prod_matrix, np.array([0, 0, 1])
+554                    )
+555                    t3 = self._FInt(
+556                        self.L[j - 1, l], source_prod_matrix, np.array([0, 1, 0])
+557                    )
+558                    t4 = 0
+559                    t5 = 0
+560                    t6 = 0
+561
+562                if j != 0 and j != self.m and l == self.n:
+563                    t1 = 0
+564                    t2 = 0
+565                    t3 = 0
+566                    t4 = self._FInt(
+567                        self.U[j - 1, l - 1], source_prod_matrix, np.array([1, 0, 0])
+568                    )
+569                    t5 = self._FInt(
+570                        self.L[j, l - 1], source_prod_matrix, np.array([0, 0, 1])
+571                    )
+572                    t6 = self._FInt(
+573                        self.U[j, l - 1], source_prod_matrix, np.array([0, 1, 0])
+574                    )
+575
+576                if j == 0 and l == 0:
+577                    t1 = self._FInt(
+578                        self.L[j, l], source_prod_matrix, np.array([1, 0, 0])
+579                    )
+580                    t2 = 0
+581                    t3 = 0
+582                    t4 = 0
+583                    t5 = 0
+584                    t6 = 0
+585
+586                if j == 0 and l == self.n:
+587                    t1 = 0
+588                    t2 = 0
+589                    t3 = 0
+590                    t4 = 0
+591                    t5 = self._FInt(
+592                        self.L[j, l - 1], source_prod_matrix, np.array([0, 0, 1])
+593                    )
+594                    t6 = self._FInt(
+595                        self.U[j, l - 1], source_prod_matrix, np.array([0, 1, 0])
+596                    )
+597
+598                if j == self.m and l == 0:
+599                    t1 = 0
+600                    t2 = self._FInt(
+601                        self.U[j - 1, l], source_prod_matrix, np.array([0, 0, 1])
+602                    )
+603                    t3 = self._FInt(
+604                        self.L[j - 1, l], source_prod_matrix, np.array([0, 1, 0])
+605                    )
+606                    t4 = 0
+607                    t5 = 0
+608                    t6 = 0
+609
+610                if j == self.m and l == self.n:
+611                    t1 = 0
+612                    t2 = 0
+613                    t3 = 0
+614                    t4 = self._FInt(
+615                        self.U[j - 1, l - 1], source_prod_matrix, np.array([1, 0, 0])
+616                    )
+617                    t5 = 0
+618                    t6 = 0
+619
+620                if j != 0 and j != self.m and l != 0 and l != self.n:
+621                    t1 = self._FInt(
+622                        self.L[j, l], source_prod_matrix, np.array([1, 0, 0])
+623                    )
+624                    t2 = self._FInt(
+625                        self.U[j - 1, l], source_prod_matrix, np.array([0, 0, 1])
+626                    )
+627                    t3 = self._FInt(
+628                        self.L[j - 1, l], source_prod_matrix, np.array([0, 1, 0])
+629                    )
+630                    t4 = self._FInt(
+631                        self.U[j - 1, l - 1], source_prod_matrix, np.array([1, 0, 0])
+632                    )
+633                    t5 = self._FInt(
+634                        self.L[j, l - 1], source_prod_matrix, np.array([0, 0, 1])
+635                    )
+636                    t6 = self._FInt(
+637                        self.U[j, l - 1], source_prod_matrix, np.array([0, 1, 0])
+638                    )
+639
+640                # computing rh
+641                self.right_hand[idx] = t1 + t2 + t3 + t4 + t5 + t6
+
+ + +

Sets the right hand side of the equation being solved to update the global pressure and velocity matrices

+
+ + +
+
+ +
+ + def + get_A_B_matrices(self): + + + +
+ +
743    def get_A_B_matrices(self):
+744        self._set_A()
+745        self._set_B()
+746
+747        # creating the sparsed matrix for A
+748        rows = np.ravel(self.A[:, 0].reshape(1, -1))
+749        cols = np.ravel(self.A[:, 1].reshape(1, -1))
+750        values = np.ravel(self.A[:, 2].reshape(1, -1))
+751        self.sparsed_A = coo_matrix(
+752            (values, (rows, cols)), shape=(np.shape(self.B)[0], np.shape(self.B)[0])
+753        )  # TODO: Verify correctedness of salf.sparsed_A
+
+ + + + +
+
+
Inherited Members
+
+
Grid
+
m
+
n
+
left
+
right
+
bottom
+
top
+
get_spacing
+
get_meshgrid
+
dx
+
dy
+
set_FD_meshgrid
+
get_flat_index_matrix
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/lib/polymer.html b/docs/lib/polymer.html new file mode 100644 index 0000000..3aa8e49 --- /dev/null +++ b/docs/lib/polymer.html @@ -0,0 +1,2189 @@ + + + + + + + lib.polymer API documentation + + + + + + + + + +
+
+

+lib.polymer

+ +

This python script contains the class definition for polymers for the surfactant-flooding model

+ +

The methods of this class were derived from the MATLAB Surfactant-Polymer Flooding Code developed by +Sourav Dutta and Rohit Mishra.

+ +

@author: Bhargav Akula Ramesh Kumar, Carlos Acosta Caripo

+
+ + + + + +
  1"""
+  2This python script contains the class definition for polymers for the surfactant-flooding model
+  3
+  4The methods of this class were derived from the MATLAB Surfactant-Polymer Flooding Code developed by
+  5Sourav Dutta and Rohit Mishra.
+  6
+  7@author: Bhargav Akula Ramesh Kumar, Carlos Acosta Caripo
+  8"""
+  9
+ 10import numpy as np
+ 11import scipy as sp
+ 12from scipy.sparse.linalg import bicgstab
+ 13from .enumerations import ModelType, PolymerList, SimulationConstants
+ 14from .Exceptions import SimulationCalcInputException
+ 15from .grid import Grid
+ 16
+ 17
+ 18class Polymer:
+ 19    """
+ 20    Class definition for the polymer objects and their calculations
+ 21    """
+ 22
+ 23    def __init__(
+ 24        self,
+ 25        name: PolymerList,
+ 26        e_coeff: np.ndarray,
+ 27        n_coeff: np.ndarray,
+ 28        rho: float,
+ 29        concentration_scalar: float,
+ 30        phi: np.ndarray,
+ 31        viscosity_scalar: float | None = None,
+ 32        viscosity_matrix: np.ndarray | None = None,
+ 33        concentration_matrix: np.ndarray | None = None,
+ 34        shear_rate: np.ndarray | None = None,
+ 35    ):
+ 36        """
+ 37        Initializes a instance of the polymer class
+ 38        """
+ 39
+ 40        # PolymerList object
+ 41        self.name = name
+ 42
+ 43        # properties related to the concentration (scalar concentration, matrix version of initial concentration, and current concentration matrix)
+ 44        self.concetration_scalar = concentration_scalar
+ 45        self.init_concentration_matrix = concentration_matrix
+ 46        self.concentration_matrix = concentration_matrix
+ 47
+ 48        # Properties related to the viscosity
+ 49        self.viscosity_matrix = viscosity_matrix
+ 50        self.viscosity_scalar = viscosity_scalar
+ 51
+ 52        # Values required to formulate the numerical powerlaw function for viscosity calculations
+ 53        self.e_coeff = e_coeff
+ 54        self.n_coeff = n_coeff
+ 55
+ 56        # Polymer Density
+ 57        self.rho = rho
+ 58
+ 59        # shear rate matrix (needed when running 'shear thinning' model version)
+ 60        self.shear_rate = shear_rate
+ 61
+ 62        # util param for initialization
+ 63        self.phi = phi  # Will need to be created in the simulation class
+ 64 
+ 65    _name = None
+ 66    @property
+ 67    def name(self):
+ 68        """
+ 69        name (enum 'PolymerList'): Name of the polymer
+ 70        """
+ 71        return self._name
+ 72    @name.setter
+ 73    def name(self, value):
+ 74        self._name = value
+ 75
+ 76    _concetration_scalar = None
+ 77    @property
+ 78    def concetration_scalar(self):
+ 79        """
+ 80        concentration_scalar (float): Scalar quantity of concentration. When initializing, this param will equal the initial polymer concentration.
+ 81        """
+ 82        return self._concetration_scalar
+ 83    @concetration_scalar.setter
+ 84    def concetration_scalar(self, value):
+ 85        self._concetration_scalar = value
+ 86
+ 87    _init_concentration_matrix = None
+ 88    @property
+ 89    def init_concentration_matrix(self):
+ 90        """
+ 91        Initial matrix (at time t = 0) representation of polymer concentration within resevoir
+ 92        """
+ 93        return self._init_concentration_matrix
+ 94    @init_concentration_matrix.setter
+ 95    def init_concentration_matrix(self, value):
+ 96        self._init_concentration_matrix = value
+ 97
+ 98    _concentration_matrix = None
+ 99    @property
+100    def concentration_matrix(self):
+101        """
+102        concentration_matrix (np.ndarray, None): matrix representation of polymer concentration within resevoir over time
+103        """
+104        return self._concentration_matrix
+105    @concentration_matrix.setter
+106    def concentration_matrix(self, value):
+107        self._concentration_matrix = value
+108
+109    _viscosity_matrix = None
+110    @property
+111    def viscosity_matrix(self):
+112        """
+113        viscosity_matrix (np.ndarray, None): viscosity matrix of the polymer
+114        """
+115        return self._viscosity_matrix
+116    @viscosity_matrix.setter
+117    def viscosity_matrix(self, value):
+118        self._viscosity_matrix = value
+119
+120    _viscosity_scalar = None
+121    @property
+122    def viscosity_scalar(self):
+123        """
+124        viscosity_scalar (float, None): scalar quantity of the polymer viscosity
+125        """
+126        return self._viscosity_scalar
+127    @viscosity_scalar.setter
+128    def viscosity_scalar(self, value):
+129        self._viscosity_scalar = value
+130
+131    _e_coeff = None
+132    @property
+133    def e_coeff(self):
+134        """
+135        e_coeff (list[float]): The coefficients used to determine epsilon for the empirical power law expression used to determine the viscosity of the aqueous phase
+136        """
+137        return self._e_coeff
+138    @e_coeff.setter
+139    def e_coeff(self, value):
+140        self._e_coeff = value
+141
+142    _n_coeff = None
+143    @property
+144    def n_coeff(self):
+145        """
+146        n_coeff (list[float]):  The coefficients used to determine epsilon for the empirical power law expression used to determine the viscosity of the aqueous phase
+147        """
+148        return self._n_coeff
+149    @n_coeff.setter
+150    def n_coeff(self, value):
+151        self._n_coeff = value
+152
+153    _rho = None
+154    @property
+155    def rho(self):
+156        """
+157        rho (float): Density of polymer
+158        """
+159        return self._rho
+160    @rho.setter
+161    def rho(self, value):
+162        self._rho = value
+163
+164    _phi = None
+165    @property
+166    def phi(self):
+167        """
+168        phi (np.ndarray): arrray used to initialize the concentration matrix (represents porosity of the resevoir)
+169        """
+170        return self._phi
+171    @phi.setter
+172    def phi(self, value):
+173        self._phi = value
+174
+175    _shear_rate = None
+176    @property
+177    def shear_rate(self):
+178        """
+179        shear_rate (np.ndarray, None): Matrix that will hold the shear rate (the change in velocity normal to the direction of flow)
+180        """
+181        return self._shear_rate
+182    @shear_rate.setter
+183    def shear_rate(self, value):
+184        self._shear_rate = value
+185
+186
+187
+188
+189    def initialize(self, grid_shape: tuple):
+190        """
+191        Will initialize the viscosity, shear_rate, and concentration matrices
+192        
+193        Args:
+194        -----
+195            grid_shape (tuple): contain the shape of the grid
+196        
+197        Returns: (Polymer)
+198        -----------------
+199            Initalized Polymer Object
+200        """
+201        n = grid_shape[0]
+202        m = grid_shape[1]
+203        D = (self.phi > 1e-10) + (np.abs(self.phi) < 1e-10)
+204        if self.concentration_matrix is None:
+205            self.concentration_matrix = (~D) * self.concetration_scalar
+206
+207        if self.init_concentration_matrix is None:
+208            self.init_concentration_matrix = self.concetration_scalar * np.ones(
+209                (n + 1, m + 1)
+210            )
+211
+212        if self.shear_rate is None:
+213            self.shear_rate = np.zeros((n + 1, m + 1))
+214
+215        if self.viscosity_scalar is None:
+216            beta1 = 15000  # constant that came from the MATLAB code
+217            self.viscosity_scalar = SimulationConstants.Water_Viscosity.value * (
+218                1 + beta1 * self.concetration_scalar
+219            )
+220
+221        if self.viscosity_matrix is None:
+222            self.viscosity_matrix = self.viscosity_scalar * np.ones((n + 1, m + 1))
+223
+224        return self
+225
+226    def compute_viscosity(
+227        self,
+228        grid: Grid,
+229        u: np.ndarray,
+230        v: np.ndarray,
+231        model_type: ModelType,
+232        aqueous_viscosity: np.ndarray | None = None,
+233    ):
+234        """
+235        Compute polymer viscosity.
+236        This function is derived from 'compvis()' in the original MATLAB code (in file compvis.m).
+237        
+238        Args:
+239        -----
+240            grid (Tuple[NDArray[Any], ...]): The FEM grid used for simulation calculations (x and y variables from the MATLAB code)
+241
+242            u (np.ndarray): Matrix related to the global pressure
+243
+244            v (np.ndarray): Matrix related to the velocity matrix
+245
+246            model_type (enum 'ModelType'): Will state whether the model will include polymer shear thinning or not
+247
+248            aqueous_viscosity (np.ndarray, None): Aqueous viscosity matrix (will come from the ``Water`` class). Only needed when shear thinning OFF
+249        
+250        Returns: (list)
+251        ---------------
+252            the viscosity_matrix (index 0) & shear_rate matrix (index 1) for the polymer within the grid
+253        """
+254        # x and y components from meshgrid
+255        x = grid.x
+256        y = grid.y
+257
+258        if (
+259            self.concentration_matrix is None
+260            or self.init_concentration_matrix is None
+261            or self.concetration_scalar is None
+262        ):
+263            raise SimulationCalcInputException(
+264                "SimulationInputException: Polymer concentration matrix and/or scalar concentration value not initialized..."
+265            )
+266
+267        # if model_type is NO SHEAR THINNING:
+268        if model_type.value == ModelType.No_Shear_Thinning.value:
+269            if aqueous_viscosity is None:
+270                raise SimulationCalcInputException(
+271                    "SimulationInputException: Aqueous viscosity matrix required but not provided. Please try again."
+272                )
+273            ## the scalar viscosity is equal to the max within the aqueous viscosity matrix
+274            self.viscosity_scalar = np.max(aqueous_viscosity[0, :])
+275            self.viscosity_matrix = self.viscosity_scalar * np.ones(
+276                (
+277                    SimulationConstants.Grid_Size.value,
+278                    SimulationConstants.Grid_Size.value,
+279                )
+280            )
+281        # Model Type is 'Sourav Implementation':
+282        elif model_type.value == ModelType.Sourav_Implementation.value:
+283            # TODO: Will keep empty until properly understood how to implement
+284            pass
+285        # if polymer shear thinning is ON:
+286        elif model_type.value == ModelType.Shear_Thinning_On.value:
+287            if aqueous_viscosity is not None:
+288                raise SimulationCalcInputException(
+289                    "SimulationInputException: Aqueous viscosity reliant on changing polymer viscosity. Update will be done within 'Water' Class"
+290                )
+291            if self.shear_rate is None or self.viscosity_matrix is None:
+292                raise SimulationCalcInputException(
+293                    "SimulationInputException: Either shear_matrix or viscosity_matrix are not initialized"
+294                )
+295            # Getting water density and viscosity (Note: polymer density a property of class)
+296            rho_water = SimulationConstants.Water_Density.value
+297            viscosity_water = SimulationConstants.Water_Viscosity.value
+298
+299            # Formulating the numerically derived power law equation
+300            w1_0 = (
+301                self.rho * self.init_concentration_matrix
+302            )  # from the variable w10 in MATLAB code
+303            w2_0 = rho_water * (
+304                1 - self.init_concentration_matrix
+305            )  # from the variable w20 in MATLAB code
+306            wppm_0 = (w1_0 / (w1_0 + w2_0)) * (
+307                10**6
+308            )  # from the wppm0 variable in MATLAB code
+309            print(f"type w1_0: {np.shape(w1_0)}")
+310            print(f"type w2_0: {np.shape(w2_0)}")
+311
+312            ## Determining the epsilon and n coefficients for the power law equation
+313            epsilon_0 = np.zeros(
+314                (
+315                    np.size(self.concentration_matrix, 0),
+316                    np.size(self.concentration_matrix, 1),
+317                )
+318            )
+319            n_0 = np.zeros(
+320                (
+321                    np.size(self.concentration_matrix, 0),
+322                    np.size(self.concentration_matrix, 1),
+323                )
+324            )
+325            print(f"type epsilon_0: {np.shape(n_0)}")
+326            print(f"type n_0: {np.shape(n_0)}")
+327            for r in range(np.size(self.concentration_matrix, 0)):
+328                for c in range(np.size(self.concentration_matrix, 1)):
+329                    epsilon_0[r, c] = self.e_coeff[0] * wppm_0[r, c] ** self.e_coeff[1]
+330                    n_0[r, c] = min(
+331                        self.n_coeff[0] * wppm_0[r, c] ** self.n_coeff[1], 1
+332                    )
+333
+334            row = np.size(self.concentration_matrix, 0)
+335            col = np.size(self.concentration_matrix, 1)
+336
+337            # Compute divergence terms
+338            a1 = self.divergence(x, v)
+339            a2 = self.divergence(y, u)
+340            a3 = self.divergence(x, u)
+341            a4 = self.divergence(y, v)
+342
+343            pi_D = np.abs(-0.25 * ((a1 + a2) ** 2) + a3 * a4)
+344            for i in range(row):
+345                for j in range(col):
+346                    if self.concentration_matrix[i, j] > 0:
+347                        self.shear_rate[i, j] = 2 * np.sqrt(pi_D[i, j])
+348                        if not (self.shear_rate[i, j] == 0):
+349                            self.viscosity_matrix[i, j] = epsilon_0[i, j] * (
+350                                self.shear_rate[i, j] ** (n_0[i, j] - 1)
+351                            )
+352                            print(f"epsilon_0:{epsilon_0[i,j]}")
+353                            print(f"n_0:{n_0[i,j]}")
+354                            print(f"shear_rate:{self.shear_rate[i,j]}")
+355                            print(f"pi_D: {pi_D[i,j]}")
+356                            print("")
+357                            if self.viscosity_matrix[i, j] < viscosity_water:
+358                                self.viscosity_matrix[i, j] = viscosity_water
+359                            if self.viscosity_matrix[i, j] > 100:
+360                                self.viscosity_matrix[i, j] = 100
+361
+362        return [self.viscosity_matrix, self.shear_rate]
+363
+364    def compute_concentration(
+365        self,
+366        grid: Grid,
+367        water_sat: np.ndarray,
+368        u: np.ndarray,
+369        v: np.ndarray,
+370        xmod: np.ndarray,
+371        ymod: np.ndarray,
+372        const_parameters: dict,
+373        varying_parameters: dict,
+374    ):
+375        """
+376        Computes the polymer concentration
+377
+378        Raises:
+379        -------
+380            SimulationCalcInputException: Not all required parameters were provided
+381
+382        Args:
+383        -----
+384            grid (Grid): the FDMesh
+385
+386            water_sat (np.ndarray): the water saturation matrix
+387
+388            u (np.ndarray): Matrix related to the global pressure
+389
+390            v (np.ndarray): Matrix related to the velocity matrix
+391
+392            xmod (np.ndarray): x-dim characteristic coordinates based on Neumann boundary conditions
+393
+394            ymod (np.ndarray): y-dim characteristic coordinates based on Neumann boundary conditions
+395
+396            const_parameters (dict): constant parameters to help with calculations
+397
+398            varying_parameters (dict): parameters that vary but assist with calculations for water saturation, polymer concentration, and surfactant concentration
+399        
+400        Returns: (dict)
+401        ---------------
+402            The varying parameters that were changed in this method
+403
+404        """
+405        # initializing variables:
+406        # Assert statements to ensure that all parameters are property initialized:
+407        assert self.concentration_matrix is not None, SimulationCalcInputException(
+408            "SimuationInputException: polymer concentration matrix not initialized. Please try again"
+409        )
+410        # Required constants:
+411        dx = const_parameters["FD_grid_constants"]["dx"]
+412        dy = const_parameters["FD_grid_constants"]["dy"]
+413        x = const_parameters["FD_grid_constants"]["x"]
+414        y = const_parameters["FD_grid_constants"]["y"]
+415        m = const_parameters["FD_grid_constants"]["m"]
+416        n = const_parameters["FD_grid_constants"]["n"]
+417        phi = self.phi
+418        omega1 = const_parameters["Pc_constants"]["omega1"]
+419        omega2 = const_parameters["Pc_constants"]["omega2"]
+420        Qnew = water_sat
+421        C = np.copy(self.concentration_matrix)
+422        g1 = const_parameters["inlet_total_flow"]
+423        g2 = const_parameters["inlet_polymer_flow"]
+424        KK = const_parameters["KK"]
+425        relative_permeability_formula = const_parameters[
+426            "relative_permeability_formula"
+427        ]
+428
+429        # retrieving relevant parameters for updating the water saturation
+430        ## Time Step:
+431        dt = const_parameters["FD_grid_constants"]["dt"]
+432        dt_array = const_parameters["FD_grid_constants"]["dt_matrix"]
+433
+434        # retrieving fractional flow variable
+435        f = varying_parameters["fractional_flow_parameters"]["f"]
+436
+437        # Determining 'Cmod'
+438        x1d = x[0, :]
+439        y1d = y[:, 0]
+440        x_sorted = np.all(np.diff(x1d) > 0)
+441        y_sorted = np.all(np.diff(y1d) > 0)
+442
+443        # reorder vec_concentration if a dimension isn't sorted
+444        if not x_sorted:
+445            x_sort_idx = np.argsort(x1d)
+446            x1d = x1d[x_sort_idx]
+447            C = C[:, x_sort_idx]  # Sort columns of vec_concentration
+448        if not y_sorted:
+449            y_sort_idx = np.argsort(y1d)
+450            y1d = y1d[y_sort_idx]
+451            C = C[y_sort_idx, :]  # Sort rows of vec_concentration
+452
+453        interp = sp.interpolate.RegularGridInterpolator(
+454            (y1d, x1d),
+455            self.concentration_matrix,
+456            method="linear",
+457            bounds_error=False,
+458            fill_value=None,
+459        )
+460        query_points = np.stack([ymod.ravel(), xmod.ravel()], axis=-1)
+461        Cmod = interp(query_points).reshape(xmod.shape)
+462
+463        # Using 'Cmod' and 'Qnew' to update the polymer concentration matrix
+464        idx = 1
+465        AAA = np.zeros((n * m, n * m))
+466        DDD = np.zeros((n * m, 1))
+467
+468        while idx <= (m) * (n - 1) + 1:
+469            cnt = (idx - 1) // m  # cnt = 0, 1, 2, ... for idx = 1, m+1, 2m+1, 3m+1, ...
+470            BB = np.zeros((n, m))
+471            AA = np.copy(BB)
+472            CC = np.copy(BB)
+473            DD = np.zeros((m, 1))
+474            for i in range(m):
+475                for j in range(n):
+476                    if j == i:
+477                        if idx == 1:  # lowermost row of grid
+478                            if i == 1:  # leftmost point (source)
+479                                DD[i] = (
+480                                    g2 / Qnew[cnt][i] + Cmod[cnt][i] / dt_array[cnt][i]
+481                                )
+482                                BB[j][i] = 1 / dt_array[cnt][i] + g1 / Qnew[cnt][i]
+483                            else:
+484                                DD[i] = Cmod[cnt][i] / dt_array[cnt][i]
+485                                BB[j][i] = 1 / dt_array[cnt][i]
+486                        elif idx == (m) * (n - 1) + 1:
+487                            if i == m - 1:
+488                                DD[i] = Cmod[cnt][i] / dt_array[cnt][i]
+489                                BB[j][i] = (
+490                                    1 / dt_array[cnt][i] - g1 * f[cnt][i] / Qnew[cnt][i]
+491                                )
+492                            else:
+493                                DD[i] = Cmod[cnt][i] / dt_array[cnt][i]
+494                                BB[j][i] = 1 / dt_array[cnt][i]
+495                        else:
+496                            DD[i] = Cmod[cnt][i] / dt_array[cnt][i]
+497                            BB[j][i] = 1 / dt_array[cnt][i]
+498
+499            if cnt == 0:
+500                AAA[0:n, 0 : 2 * m] = np.hstack([BB, CC])
+501            elif cnt == n - 1:
+502                AAA[(m - 1) * n : m * n, (n - 2) * m : n * m] = np.hstack([AA, BB])
+503            else:
+504                AAA[cnt * n : (cnt + 1) * n, (cnt - 1) * m : (cnt + 2) * m] = np.hstack(
+505                    [AA, BB, CC]
+506                )
+507
+508            DDD[cnt * m : (cnt + 1) * m] = DD
+509
+510            idx += m
+511
+512        Cnew_flat, info = bicgstab(AAA, DDD, rtol=10 ** (-10), maxiter=600)
+513        Cnew = Cnew_flat.reshape(m, n)
+514        self.concentration_matrix = Cnew
+515
+516        return varying_parameters
+517
+518    def divergence(self, Fx, Fy, dx=1.0, dy=1.0):
+519        """
+520        Calculates Divergence
+521
+522        Args:
+523        -----
+524            Fx (np.ndarray): Function #1
+525            
+526            Fy (np.ndarray): Function #2
+527
+528            dx (float): change in the x-dimension
+529
+530            dy (float): change in the y-dimension
+531
+532        Raises: (np.ndarray)
+533        --------------------
+534            Div F = (δfx/δx) + (δfy/δy)
+535        """
+536        dFx_dx = np.gradient(Fx, dx, axis=1)
+537        dFy_dy = np.gradient(Fy, dy, axis=0)
+538        return dFx_dx + dFy_dy
+
+ + +
+
+ +
+ + class + Polymer: + + + +
+ +
 19class Polymer:
+ 20    """
+ 21    Class definition for the polymer objects and their calculations
+ 22    """
+ 23
+ 24    def __init__(
+ 25        self,
+ 26        name: PolymerList,
+ 27        e_coeff: np.ndarray,
+ 28        n_coeff: np.ndarray,
+ 29        rho: float,
+ 30        concentration_scalar: float,
+ 31        phi: np.ndarray,
+ 32        viscosity_scalar: float | None = None,
+ 33        viscosity_matrix: np.ndarray | None = None,
+ 34        concentration_matrix: np.ndarray | None = None,
+ 35        shear_rate: np.ndarray | None = None,
+ 36    ):
+ 37        """
+ 38        Initializes a instance of the polymer class
+ 39        """
+ 40
+ 41        # PolymerList object
+ 42        self.name = name
+ 43
+ 44        # properties related to the concentration (scalar concentration, matrix version of initial concentration, and current concentration matrix)
+ 45        self.concetration_scalar = concentration_scalar
+ 46        self.init_concentration_matrix = concentration_matrix
+ 47        self.concentration_matrix = concentration_matrix
+ 48
+ 49        # Properties related to the viscosity
+ 50        self.viscosity_matrix = viscosity_matrix
+ 51        self.viscosity_scalar = viscosity_scalar
+ 52
+ 53        # Values required to formulate the numerical powerlaw function for viscosity calculations
+ 54        self.e_coeff = e_coeff
+ 55        self.n_coeff = n_coeff
+ 56
+ 57        # Polymer Density
+ 58        self.rho = rho
+ 59
+ 60        # shear rate matrix (needed when running 'shear thinning' model version)
+ 61        self.shear_rate = shear_rate
+ 62
+ 63        # util param for initialization
+ 64        self.phi = phi  # Will need to be created in the simulation class
+ 65 
+ 66    _name = None
+ 67    @property
+ 68    def name(self):
+ 69        """
+ 70        name (enum 'PolymerList'): Name of the polymer
+ 71        """
+ 72        return self._name
+ 73    @name.setter
+ 74    def name(self, value):
+ 75        self._name = value
+ 76
+ 77    _concetration_scalar = None
+ 78    @property
+ 79    def concetration_scalar(self):
+ 80        """
+ 81        concentration_scalar (float): Scalar quantity of concentration. When initializing, this param will equal the initial polymer concentration.
+ 82        """
+ 83        return self._concetration_scalar
+ 84    @concetration_scalar.setter
+ 85    def concetration_scalar(self, value):
+ 86        self._concetration_scalar = value
+ 87
+ 88    _init_concentration_matrix = None
+ 89    @property
+ 90    def init_concentration_matrix(self):
+ 91        """
+ 92        Initial matrix (at time t = 0) representation of polymer concentration within resevoir
+ 93        """
+ 94        return self._init_concentration_matrix
+ 95    @init_concentration_matrix.setter
+ 96    def init_concentration_matrix(self, value):
+ 97        self._init_concentration_matrix = value
+ 98
+ 99    _concentration_matrix = None
+100    @property
+101    def concentration_matrix(self):
+102        """
+103        concentration_matrix (np.ndarray, None): matrix representation of polymer concentration within resevoir over time
+104        """
+105        return self._concentration_matrix
+106    @concentration_matrix.setter
+107    def concentration_matrix(self, value):
+108        self._concentration_matrix = value
+109
+110    _viscosity_matrix = None
+111    @property
+112    def viscosity_matrix(self):
+113        """
+114        viscosity_matrix (np.ndarray, None): viscosity matrix of the polymer
+115        """
+116        return self._viscosity_matrix
+117    @viscosity_matrix.setter
+118    def viscosity_matrix(self, value):
+119        self._viscosity_matrix = value
+120
+121    _viscosity_scalar = None
+122    @property
+123    def viscosity_scalar(self):
+124        """
+125        viscosity_scalar (float, None): scalar quantity of the polymer viscosity
+126        """
+127        return self._viscosity_scalar
+128    @viscosity_scalar.setter
+129    def viscosity_scalar(self, value):
+130        self._viscosity_scalar = value
+131
+132    _e_coeff = None
+133    @property
+134    def e_coeff(self):
+135        """
+136        e_coeff (list[float]): The coefficients used to determine epsilon for the empirical power law expression used to determine the viscosity of the aqueous phase
+137        """
+138        return self._e_coeff
+139    @e_coeff.setter
+140    def e_coeff(self, value):
+141        self._e_coeff = value
+142
+143    _n_coeff = None
+144    @property
+145    def n_coeff(self):
+146        """
+147        n_coeff (list[float]):  The coefficients used to determine epsilon for the empirical power law expression used to determine the viscosity of the aqueous phase
+148        """
+149        return self._n_coeff
+150    @n_coeff.setter
+151    def n_coeff(self, value):
+152        self._n_coeff = value
+153
+154    _rho = None
+155    @property
+156    def rho(self):
+157        """
+158        rho (float): Density of polymer
+159        """
+160        return self._rho
+161    @rho.setter
+162    def rho(self, value):
+163        self._rho = value
+164
+165    _phi = None
+166    @property
+167    def phi(self):
+168        """
+169        phi (np.ndarray): arrray used to initialize the concentration matrix (represents porosity of the resevoir)
+170        """
+171        return self._phi
+172    @phi.setter
+173    def phi(self, value):
+174        self._phi = value
+175
+176    _shear_rate = None
+177    @property
+178    def shear_rate(self):
+179        """
+180        shear_rate (np.ndarray, None): Matrix that will hold the shear rate (the change in velocity normal to the direction of flow)
+181        """
+182        return self._shear_rate
+183    @shear_rate.setter
+184    def shear_rate(self, value):
+185        self._shear_rate = value
+186
+187
+188
+189
+190    def initialize(self, grid_shape: tuple):
+191        """
+192        Will initialize the viscosity, shear_rate, and concentration matrices
+193        
+194        Args:
+195        -----
+196            grid_shape (tuple): contain the shape of the grid
+197        
+198        Returns: (Polymer)
+199        -----------------
+200            Initalized Polymer Object
+201        """
+202        n = grid_shape[0]
+203        m = grid_shape[1]
+204        D = (self.phi > 1e-10) + (np.abs(self.phi) < 1e-10)
+205        if self.concentration_matrix is None:
+206            self.concentration_matrix = (~D) * self.concetration_scalar
+207
+208        if self.init_concentration_matrix is None:
+209            self.init_concentration_matrix = self.concetration_scalar * np.ones(
+210                (n + 1, m + 1)
+211            )
+212
+213        if self.shear_rate is None:
+214            self.shear_rate = np.zeros((n + 1, m + 1))
+215
+216        if self.viscosity_scalar is None:
+217            beta1 = 15000  # constant that came from the MATLAB code
+218            self.viscosity_scalar = SimulationConstants.Water_Viscosity.value * (
+219                1 + beta1 * self.concetration_scalar
+220            )
+221
+222        if self.viscosity_matrix is None:
+223            self.viscosity_matrix = self.viscosity_scalar * np.ones((n + 1, m + 1))
+224
+225        return self
+226
+227    def compute_viscosity(
+228        self,
+229        grid: Grid,
+230        u: np.ndarray,
+231        v: np.ndarray,
+232        model_type: ModelType,
+233        aqueous_viscosity: np.ndarray | None = None,
+234    ):
+235        """
+236        Compute polymer viscosity.
+237        This function is derived from 'compvis()' in the original MATLAB code (in file compvis.m).
+238        
+239        Args:
+240        -----
+241            grid (Tuple[NDArray[Any], ...]): The FEM grid used for simulation calculations (x and y variables from the MATLAB code)
+242
+243            u (np.ndarray): Matrix related to the global pressure
+244
+245            v (np.ndarray): Matrix related to the velocity matrix
+246
+247            model_type (enum 'ModelType'): Will state whether the model will include polymer shear thinning or not
+248
+249            aqueous_viscosity (np.ndarray, None): Aqueous viscosity matrix (will come from the ``Water`` class). Only needed when shear thinning OFF
+250        
+251        Returns: (list)
+252        ---------------
+253            the viscosity_matrix (index 0) & shear_rate matrix (index 1) for the polymer within the grid
+254        """
+255        # x and y components from meshgrid
+256        x = grid.x
+257        y = grid.y
+258
+259        if (
+260            self.concentration_matrix is None
+261            or self.init_concentration_matrix is None
+262            or self.concetration_scalar is None
+263        ):
+264            raise SimulationCalcInputException(
+265                "SimulationInputException: Polymer concentration matrix and/or scalar concentration value not initialized..."
+266            )
+267
+268        # if model_type is NO SHEAR THINNING:
+269        if model_type.value == ModelType.No_Shear_Thinning.value:
+270            if aqueous_viscosity is None:
+271                raise SimulationCalcInputException(
+272                    "SimulationInputException: Aqueous viscosity matrix required but not provided. Please try again."
+273                )
+274            ## the scalar viscosity is equal to the max within the aqueous viscosity matrix
+275            self.viscosity_scalar = np.max(aqueous_viscosity[0, :])
+276            self.viscosity_matrix = self.viscosity_scalar * np.ones(
+277                (
+278                    SimulationConstants.Grid_Size.value,
+279                    SimulationConstants.Grid_Size.value,
+280                )
+281            )
+282        # Model Type is 'Sourav Implementation':
+283        elif model_type.value == ModelType.Sourav_Implementation.value:
+284            # TODO: Will keep empty until properly understood how to implement
+285            pass
+286        # if polymer shear thinning is ON:
+287        elif model_type.value == ModelType.Shear_Thinning_On.value:
+288            if aqueous_viscosity is not None:
+289                raise SimulationCalcInputException(
+290                    "SimulationInputException: Aqueous viscosity reliant on changing polymer viscosity. Update will be done within 'Water' Class"
+291                )
+292            if self.shear_rate is None or self.viscosity_matrix is None:
+293                raise SimulationCalcInputException(
+294                    "SimulationInputException: Either shear_matrix or viscosity_matrix are not initialized"
+295                )
+296            # Getting water density and viscosity (Note: polymer density a property of class)
+297            rho_water = SimulationConstants.Water_Density.value
+298            viscosity_water = SimulationConstants.Water_Viscosity.value
+299
+300            # Formulating the numerically derived power law equation
+301            w1_0 = (
+302                self.rho * self.init_concentration_matrix
+303            )  # from the variable w10 in MATLAB code
+304            w2_0 = rho_water * (
+305                1 - self.init_concentration_matrix
+306            )  # from the variable w20 in MATLAB code
+307            wppm_0 = (w1_0 / (w1_0 + w2_0)) * (
+308                10**6
+309            )  # from the wppm0 variable in MATLAB code
+310            print(f"type w1_0: {np.shape(w1_0)}")
+311            print(f"type w2_0: {np.shape(w2_0)}")
+312
+313            ## Determining the epsilon and n coefficients for the power law equation
+314            epsilon_0 = np.zeros(
+315                (
+316                    np.size(self.concentration_matrix, 0),
+317                    np.size(self.concentration_matrix, 1),
+318                )
+319            )
+320            n_0 = np.zeros(
+321                (
+322                    np.size(self.concentration_matrix, 0),
+323                    np.size(self.concentration_matrix, 1),
+324                )
+325            )
+326            print(f"type epsilon_0: {np.shape(n_0)}")
+327            print(f"type n_0: {np.shape(n_0)}")
+328            for r in range(np.size(self.concentration_matrix, 0)):
+329                for c in range(np.size(self.concentration_matrix, 1)):
+330                    epsilon_0[r, c] = self.e_coeff[0] * wppm_0[r, c] ** self.e_coeff[1]
+331                    n_0[r, c] = min(
+332                        self.n_coeff[0] * wppm_0[r, c] ** self.n_coeff[1], 1
+333                    )
+334
+335            row = np.size(self.concentration_matrix, 0)
+336            col = np.size(self.concentration_matrix, 1)
+337
+338            # Compute divergence terms
+339            a1 = self.divergence(x, v)
+340            a2 = self.divergence(y, u)
+341            a3 = self.divergence(x, u)
+342            a4 = self.divergence(y, v)
+343
+344            pi_D = np.abs(-0.25 * ((a1 + a2) ** 2) + a3 * a4)
+345            for i in range(row):
+346                for j in range(col):
+347                    if self.concentration_matrix[i, j] > 0:
+348                        self.shear_rate[i, j] = 2 * np.sqrt(pi_D[i, j])
+349                        if not (self.shear_rate[i, j] == 0):
+350                            self.viscosity_matrix[i, j] = epsilon_0[i, j] * (
+351                                self.shear_rate[i, j] ** (n_0[i, j] - 1)
+352                            )
+353                            print(f"epsilon_0:{epsilon_0[i,j]}")
+354                            print(f"n_0:{n_0[i,j]}")
+355                            print(f"shear_rate:{self.shear_rate[i,j]}")
+356                            print(f"pi_D: {pi_D[i,j]}")
+357                            print("")
+358                            if self.viscosity_matrix[i, j] < viscosity_water:
+359                                self.viscosity_matrix[i, j] = viscosity_water
+360                            if self.viscosity_matrix[i, j] > 100:
+361                                self.viscosity_matrix[i, j] = 100
+362
+363        return [self.viscosity_matrix, self.shear_rate]
+364
+365    def compute_concentration(
+366        self,
+367        grid: Grid,
+368        water_sat: np.ndarray,
+369        u: np.ndarray,
+370        v: np.ndarray,
+371        xmod: np.ndarray,
+372        ymod: np.ndarray,
+373        const_parameters: dict,
+374        varying_parameters: dict,
+375    ):
+376        """
+377        Computes the polymer concentration
+378
+379        Raises:
+380        -------
+381            SimulationCalcInputException: Not all required parameters were provided
+382
+383        Args:
+384        -----
+385            grid (Grid): the FDMesh
+386
+387            water_sat (np.ndarray): the water saturation matrix
+388
+389            u (np.ndarray): Matrix related to the global pressure
+390
+391            v (np.ndarray): Matrix related to the velocity matrix
+392
+393            xmod (np.ndarray): x-dim characteristic coordinates based on Neumann boundary conditions
+394
+395            ymod (np.ndarray): y-dim characteristic coordinates based on Neumann boundary conditions
+396
+397            const_parameters (dict): constant parameters to help with calculations
+398
+399            varying_parameters (dict): parameters that vary but assist with calculations for water saturation, polymer concentration, and surfactant concentration
+400        
+401        Returns: (dict)
+402        ---------------
+403            The varying parameters that were changed in this method
+404
+405        """
+406        # initializing variables:
+407        # Assert statements to ensure that all parameters are property initialized:
+408        assert self.concentration_matrix is not None, SimulationCalcInputException(
+409            "SimuationInputException: polymer concentration matrix not initialized. Please try again"
+410        )
+411        # Required constants:
+412        dx = const_parameters["FD_grid_constants"]["dx"]
+413        dy = const_parameters["FD_grid_constants"]["dy"]
+414        x = const_parameters["FD_grid_constants"]["x"]
+415        y = const_parameters["FD_grid_constants"]["y"]
+416        m = const_parameters["FD_grid_constants"]["m"]
+417        n = const_parameters["FD_grid_constants"]["n"]
+418        phi = self.phi
+419        omega1 = const_parameters["Pc_constants"]["omega1"]
+420        omega2 = const_parameters["Pc_constants"]["omega2"]
+421        Qnew = water_sat
+422        C = np.copy(self.concentration_matrix)
+423        g1 = const_parameters["inlet_total_flow"]
+424        g2 = const_parameters["inlet_polymer_flow"]
+425        KK = const_parameters["KK"]
+426        relative_permeability_formula = const_parameters[
+427            "relative_permeability_formula"
+428        ]
+429
+430        # retrieving relevant parameters for updating the water saturation
+431        ## Time Step:
+432        dt = const_parameters["FD_grid_constants"]["dt"]
+433        dt_array = const_parameters["FD_grid_constants"]["dt_matrix"]
+434
+435        # retrieving fractional flow variable
+436        f = varying_parameters["fractional_flow_parameters"]["f"]
+437
+438        # Determining 'Cmod'
+439        x1d = x[0, :]
+440        y1d = y[:, 0]
+441        x_sorted = np.all(np.diff(x1d) > 0)
+442        y_sorted = np.all(np.diff(y1d) > 0)
+443
+444        # reorder vec_concentration if a dimension isn't sorted
+445        if not x_sorted:
+446            x_sort_idx = np.argsort(x1d)
+447            x1d = x1d[x_sort_idx]
+448            C = C[:, x_sort_idx]  # Sort columns of vec_concentration
+449        if not y_sorted:
+450            y_sort_idx = np.argsort(y1d)
+451            y1d = y1d[y_sort_idx]
+452            C = C[y_sort_idx, :]  # Sort rows of vec_concentration
+453
+454        interp = sp.interpolate.RegularGridInterpolator(
+455            (y1d, x1d),
+456            self.concentration_matrix,
+457            method="linear",
+458            bounds_error=False,
+459            fill_value=None,
+460        )
+461        query_points = np.stack([ymod.ravel(), xmod.ravel()], axis=-1)
+462        Cmod = interp(query_points).reshape(xmod.shape)
+463
+464        # Using 'Cmod' and 'Qnew' to update the polymer concentration matrix
+465        idx = 1
+466        AAA = np.zeros((n * m, n * m))
+467        DDD = np.zeros((n * m, 1))
+468
+469        while idx <= (m) * (n - 1) + 1:
+470            cnt = (idx - 1) // m  # cnt = 0, 1, 2, ... for idx = 1, m+1, 2m+1, 3m+1, ...
+471            BB = np.zeros((n, m))
+472            AA = np.copy(BB)
+473            CC = np.copy(BB)
+474            DD = np.zeros((m, 1))
+475            for i in range(m):
+476                for j in range(n):
+477                    if j == i:
+478                        if idx == 1:  # lowermost row of grid
+479                            if i == 1:  # leftmost point (source)
+480                                DD[i] = (
+481                                    g2 / Qnew[cnt][i] + Cmod[cnt][i] / dt_array[cnt][i]
+482                                )
+483                                BB[j][i] = 1 / dt_array[cnt][i] + g1 / Qnew[cnt][i]
+484                            else:
+485                                DD[i] = Cmod[cnt][i] / dt_array[cnt][i]
+486                                BB[j][i] = 1 / dt_array[cnt][i]
+487                        elif idx == (m) * (n - 1) + 1:
+488                            if i == m - 1:
+489                                DD[i] = Cmod[cnt][i] / dt_array[cnt][i]
+490                                BB[j][i] = (
+491                                    1 / dt_array[cnt][i] - g1 * f[cnt][i] / Qnew[cnt][i]
+492                                )
+493                            else:
+494                                DD[i] = Cmod[cnt][i] / dt_array[cnt][i]
+495                                BB[j][i] = 1 / dt_array[cnt][i]
+496                        else:
+497                            DD[i] = Cmod[cnt][i] / dt_array[cnt][i]
+498                            BB[j][i] = 1 / dt_array[cnt][i]
+499
+500            if cnt == 0:
+501                AAA[0:n, 0 : 2 * m] = np.hstack([BB, CC])
+502            elif cnt == n - 1:
+503                AAA[(m - 1) * n : m * n, (n - 2) * m : n * m] = np.hstack([AA, BB])
+504            else:
+505                AAA[cnt * n : (cnt + 1) * n, (cnt - 1) * m : (cnt + 2) * m] = np.hstack(
+506                    [AA, BB, CC]
+507                )
+508
+509            DDD[cnt * m : (cnt + 1) * m] = DD
+510
+511            idx += m
+512
+513        Cnew_flat, info = bicgstab(AAA, DDD, rtol=10 ** (-10), maxiter=600)
+514        Cnew = Cnew_flat.reshape(m, n)
+515        self.concentration_matrix = Cnew
+516
+517        return varying_parameters
+518
+519    def divergence(self, Fx, Fy, dx=1.0, dy=1.0):
+520        """
+521        Calculates Divergence
+522
+523        Args:
+524        -----
+525            Fx (np.ndarray): Function #1
+526            
+527            Fy (np.ndarray): Function #2
+528
+529            dx (float): change in the x-dimension
+530
+531            dy (float): change in the y-dimension
+532
+533        Raises: (np.ndarray)
+534        --------------------
+535            Div F = (δfx/δx) + (δfy/δy)
+536        """
+537        dFx_dx = np.gradient(Fx, dx, axis=1)
+538        dFy_dy = np.gradient(Fy, dy, axis=0)
+539        return dFx_dx + dFy_dy
+
+ + +

Class definition for the polymer objects and their calculations

+
+ + +
+ +
+ + Polymer( name: lib.enumerations.PolymerList, e_coeff: numpy.ndarray, n_coeff: numpy.ndarray, rho: float, concentration_scalar: float, phi: numpy.ndarray, viscosity_scalar: float | None = None, viscosity_matrix: numpy.ndarray | None = None, concentration_matrix: numpy.ndarray | None = None, shear_rate: numpy.ndarray | None = None) + + + +
+ +
24    def __init__(
+25        self,
+26        name: PolymerList,
+27        e_coeff: np.ndarray,
+28        n_coeff: np.ndarray,
+29        rho: float,
+30        concentration_scalar: float,
+31        phi: np.ndarray,
+32        viscosity_scalar: float | None = None,
+33        viscosity_matrix: np.ndarray | None = None,
+34        concentration_matrix: np.ndarray | None = None,
+35        shear_rate: np.ndarray | None = None,
+36    ):
+37        """
+38        Initializes a instance of the polymer class
+39        """
+40
+41        # PolymerList object
+42        self.name = name
+43
+44        # properties related to the concentration (scalar concentration, matrix version of initial concentration, and current concentration matrix)
+45        self.concetration_scalar = concentration_scalar
+46        self.init_concentration_matrix = concentration_matrix
+47        self.concentration_matrix = concentration_matrix
+48
+49        # Properties related to the viscosity
+50        self.viscosity_matrix = viscosity_matrix
+51        self.viscosity_scalar = viscosity_scalar
+52
+53        # Values required to formulate the numerical powerlaw function for viscosity calculations
+54        self.e_coeff = e_coeff
+55        self.n_coeff = n_coeff
+56
+57        # Polymer Density
+58        self.rho = rho
+59
+60        # shear rate matrix (needed when running 'shear thinning' model version)
+61        self.shear_rate = shear_rate
+62
+63        # util param for initialization
+64        self.phi = phi  # Will need to be created in the simulation class
+
+ + +

Initializes a instance of the polymer class

+
+ + +
+
+ +
+ name + + + +
+ +
67    @property
+68    def name(self):
+69        """
+70        name (enum 'PolymerList'): Name of the polymer
+71        """
+72        return self._name
+
+ + +

name (enum 'PolymerList'): Name of the polymer

+
+ + +
+
+ +
+ concetration_scalar + + + +
+ +
78    @property
+79    def concetration_scalar(self):
+80        """
+81        concentration_scalar (float): Scalar quantity of concentration. When initializing, this param will equal the initial polymer concentration.
+82        """
+83        return self._concetration_scalar
+
+ + +

concentration_scalar (float): Scalar quantity of concentration. When initializing, this param will equal the initial polymer concentration.

+
+ + +
+
+ +
+ init_concentration_matrix + + + +
+ +
89    @property
+90    def init_concentration_matrix(self):
+91        """
+92        Initial matrix (at time t = 0) representation of polymer concentration within resevoir
+93        """
+94        return self._init_concentration_matrix
+
+ + +

Initial matrix (at time t = 0) representation of polymer concentration within resevoir

+
+ + +
+
+ +
+ concentration_matrix + + + +
+ +
100    @property
+101    def concentration_matrix(self):
+102        """
+103        concentration_matrix (np.ndarray, None): matrix representation of polymer concentration within resevoir over time
+104        """
+105        return self._concentration_matrix
+
+ + +

concentration_matrix (np.ndarray, None): matrix representation of polymer concentration within resevoir over time

+
+ + +
+
+ +
+ viscosity_matrix + + + +
+ +
111    @property
+112    def viscosity_matrix(self):
+113        """
+114        viscosity_matrix (np.ndarray, None): viscosity matrix of the polymer
+115        """
+116        return self._viscosity_matrix
+
+ + +

viscosity_matrix (np.ndarray, None): viscosity matrix of the polymer

+
+ + +
+
+ +
+ viscosity_scalar + + + +
+ +
122    @property
+123    def viscosity_scalar(self):
+124        """
+125        viscosity_scalar (float, None): scalar quantity of the polymer viscosity
+126        """
+127        return self._viscosity_scalar
+
+ + +

viscosity_scalar (float, None): scalar quantity of the polymer viscosity

+
+ + +
+
+ +
+ e_coeff + + + +
+ +
133    @property
+134    def e_coeff(self):
+135        """
+136        e_coeff (list[float]): The coefficients used to determine epsilon for the empirical power law expression used to determine the viscosity of the aqueous phase
+137        """
+138        return self._e_coeff
+
+ + +

e_coeff (list[float]): The coefficients used to determine epsilon for the empirical power law expression used to determine the viscosity of the aqueous phase

+
+ + +
+
+ +
+ n_coeff + + + +
+ +
144    @property
+145    def n_coeff(self):
+146        """
+147        n_coeff (list[float]):  The coefficients used to determine epsilon for the empirical power law expression used to determine the viscosity of the aqueous phase
+148        """
+149        return self._n_coeff
+
+ + +

n_coeff (list[float]): The coefficients used to determine epsilon for the empirical power law expression used to determine the viscosity of the aqueous phase

+
+ + +
+
+ +
+ rho + + + +
+ +
155    @property
+156    def rho(self):
+157        """
+158        rho (float): Density of polymer
+159        """
+160        return self._rho
+
+ + +

rho (float): Density of polymer

+
+ + +
+
+ +
+ shear_rate + + + +
+ +
177    @property
+178    def shear_rate(self):
+179        """
+180        shear_rate (np.ndarray, None): Matrix that will hold the shear rate (the change in velocity normal to the direction of flow)
+181        """
+182        return self._shear_rate
+
+ + +

shear_rate (np.ndarray, None): Matrix that will hold the shear rate (the change in velocity normal to the direction of flow)

+
+ + +
+
+ +
+ phi + + + +
+ +
166    @property
+167    def phi(self):
+168        """
+169        phi (np.ndarray): arrray used to initialize the concentration matrix (represents porosity of the resevoir)
+170        """
+171        return self._phi
+
+ + +

phi (np.ndarray): arrray used to initialize the concentration matrix (represents porosity of the resevoir)

+
+ + +
+
+ +
+ + def + initialize(self, grid_shape: tuple): + + + +
+ +
190    def initialize(self, grid_shape: tuple):
+191        """
+192        Will initialize the viscosity, shear_rate, and concentration matrices
+193        
+194        Args:
+195        -----
+196            grid_shape (tuple): contain the shape of the grid
+197        
+198        Returns: (Polymer)
+199        -----------------
+200            Initalized Polymer Object
+201        """
+202        n = grid_shape[0]
+203        m = grid_shape[1]
+204        D = (self.phi > 1e-10) + (np.abs(self.phi) < 1e-10)
+205        if self.concentration_matrix is None:
+206            self.concentration_matrix = (~D) * self.concetration_scalar
+207
+208        if self.init_concentration_matrix is None:
+209            self.init_concentration_matrix = self.concetration_scalar * np.ones(
+210                (n + 1, m + 1)
+211            )
+212
+213        if self.shear_rate is None:
+214            self.shear_rate = np.zeros((n + 1, m + 1))
+215
+216        if self.viscosity_scalar is None:
+217            beta1 = 15000  # constant that came from the MATLAB code
+218            self.viscosity_scalar = SimulationConstants.Water_Viscosity.value * (
+219                1 + beta1 * self.concetration_scalar
+220            )
+221
+222        if self.viscosity_matrix is None:
+223            self.viscosity_matrix = self.viscosity_scalar * np.ones((n + 1, m + 1))
+224
+225        return self
+
+ + +

Will initialize the viscosity, shear_rate, and concentration matrices

+ +

Args:

+ +
grid_shape (tuple): contain the shape of the grid
+
+ +

Returns: (Polymer)

+ +
Initalized Polymer Object
+
+
+ + +
+
+ +
+ + def + compute_viscosity( self, grid: lib.grid.Grid, u: numpy.ndarray, v: numpy.ndarray, model_type: lib.enumerations.ModelType, aqueous_viscosity: numpy.ndarray | None = None): + + + +
+ +
227    def compute_viscosity(
+228        self,
+229        grid: Grid,
+230        u: np.ndarray,
+231        v: np.ndarray,
+232        model_type: ModelType,
+233        aqueous_viscosity: np.ndarray | None = None,
+234    ):
+235        """
+236        Compute polymer viscosity.
+237        This function is derived from 'compvis()' in the original MATLAB code (in file compvis.m).
+238        
+239        Args:
+240        -----
+241            grid (Tuple[NDArray[Any], ...]): The FEM grid used for simulation calculations (x and y variables from the MATLAB code)
+242
+243            u (np.ndarray): Matrix related to the global pressure
+244
+245            v (np.ndarray): Matrix related to the velocity matrix
+246
+247            model_type (enum 'ModelType'): Will state whether the model will include polymer shear thinning or not
+248
+249            aqueous_viscosity (np.ndarray, None): Aqueous viscosity matrix (will come from the ``Water`` class). Only needed when shear thinning OFF
+250        
+251        Returns: (list)
+252        ---------------
+253            the viscosity_matrix (index 0) & shear_rate matrix (index 1) for the polymer within the grid
+254        """
+255        # x and y components from meshgrid
+256        x = grid.x
+257        y = grid.y
+258
+259        if (
+260            self.concentration_matrix is None
+261            or self.init_concentration_matrix is None
+262            or self.concetration_scalar is None
+263        ):
+264            raise SimulationCalcInputException(
+265                "SimulationInputException: Polymer concentration matrix and/or scalar concentration value not initialized..."
+266            )
+267
+268        # if model_type is NO SHEAR THINNING:
+269        if model_type.value == ModelType.No_Shear_Thinning.value:
+270            if aqueous_viscosity is None:
+271                raise SimulationCalcInputException(
+272                    "SimulationInputException: Aqueous viscosity matrix required but not provided. Please try again."
+273                )
+274            ## the scalar viscosity is equal to the max within the aqueous viscosity matrix
+275            self.viscosity_scalar = np.max(aqueous_viscosity[0, :])
+276            self.viscosity_matrix = self.viscosity_scalar * np.ones(
+277                (
+278                    SimulationConstants.Grid_Size.value,
+279                    SimulationConstants.Grid_Size.value,
+280                )
+281            )
+282        # Model Type is 'Sourav Implementation':
+283        elif model_type.value == ModelType.Sourav_Implementation.value:
+284            # TODO: Will keep empty until properly understood how to implement
+285            pass
+286        # if polymer shear thinning is ON:
+287        elif model_type.value == ModelType.Shear_Thinning_On.value:
+288            if aqueous_viscosity is not None:
+289                raise SimulationCalcInputException(
+290                    "SimulationInputException: Aqueous viscosity reliant on changing polymer viscosity. Update will be done within 'Water' Class"
+291                )
+292            if self.shear_rate is None or self.viscosity_matrix is None:
+293                raise SimulationCalcInputException(
+294                    "SimulationInputException: Either shear_matrix or viscosity_matrix are not initialized"
+295                )
+296            # Getting water density and viscosity (Note: polymer density a property of class)
+297            rho_water = SimulationConstants.Water_Density.value
+298            viscosity_water = SimulationConstants.Water_Viscosity.value
+299
+300            # Formulating the numerically derived power law equation
+301            w1_0 = (
+302                self.rho * self.init_concentration_matrix
+303            )  # from the variable w10 in MATLAB code
+304            w2_0 = rho_water * (
+305                1 - self.init_concentration_matrix
+306            )  # from the variable w20 in MATLAB code
+307            wppm_0 = (w1_0 / (w1_0 + w2_0)) * (
+308                10**6
+309            )  # from the wppm0 variable in MATLAB code
+310            print(f"type w1_0: {np.shape(w1_0)}")
+311            print(f"type w2_0: {np.shape(w2_0)}")
+312
+313            ## Determining the epsilon and n coefficients for the power law equation
+314            epsilon_0 = np.zeros(
+315                (
+316                    np.size(self.concentration_matrix, 0),
+317                    np.size(self.concentration_matrix, 1),
+318                )
+319            )
+320            n_0 = np.zeros(
+321                (
+322                    np.size(self.concentration_matrix, 0),
+323                    np.size(self.concentration_matrix, 1),
+324                )
+325            )
+326            print(f"type epsilon_0: {np.shape(n_0)}")
+327            print(f"type n_0: {np.shape(n_0)}")
+328            for r in range(np.size(self.concentration_matrix, 0)):
+329                for c in range(np.size(self.concentration_matrix, 1)):
+330                    epsilon_0[r, c] = self.e_coeff[0] * wppm_0[r, c] ** self.e_coeff[1]
+331                    n_0[r, c] = min(
+332                        self.n_coeff[0] * wppm_0[r, c] ** self.n_coeff[1], 1
+333                    )
+334
+335            row = np.size(self.concentration_matrix, 0)
+336            col = np.size(self.concentration_matrix, 1)
+337
+338            # Compute divergence terms
+339            a1 = self.divergence(x, v)
+340            a2 = self.divergence(y, u)
+341            a3 = self.divergence(x, u)
+342            a4 = self.divergence(y, v)
+343
+344            pi_D = np.abs(-0.25 * ((a1 + a2) ** 2) + a3 * a4)
+345            for i in range(row):
+346                for j in range(col):
+347                    if self.concentration_matrix[i, j] > 0:
+348                        self.shear_rate[i, j] = 2 * np.sqrt(pi_D[i, j])
+349                        if not (self.shear_rate[i, j] == 0):
+350                            self.viscosity_matrix[i, j] = epsilon_0[i, j] * (
+351                                self.shear_rate[i, j] ** (n_0[i, j] - 1)
+352                            )
+353                            print(f"epsilon_0:{epsilon_0[i,j]}")
+354                            print(f"n_0:{n_0[i,j]}")
+355                            print(f"shear_rate:{self.shear_rate[i,j]}")
+356                            print(f"pi_D: {pi_D[i,j]}")
+357                            print("")
+358                            if self.viscosity_matrix[i, j] < viscosity_water:
+359                                self.viscosity_matrix[i, j] = viscosity_water
+360                            if self.viscosity_matrix[i, j] > 100:
+361                                self.viscosity_matrix[i, j] = 100
+362
+363        return [self.viscosity_matrix, self.shear_rate]
+
+ + +

Compute polymer viscosity. +This function is derived from 'compvis()' in the original MATLAB code (in file compvis.m).

+ +

Args:

+ +
grid (Tuple[NDArray[Any], ...]): The FEM grid used for simulation calculations (x and y variables from the MATLAB code)
+
+u (np.ndarray): Matrix related to the global pressure
+
+v (np.ndarray): Matrix related to the velocity matrix
+
+model_type (enum 'ModelType'): Will state whether the model will include polymer shear thinning or not
+
+aqueous_viscosity (np.ndarray, None): Aqueous viscosity matrix (will come from the ``Water`` class). Only needed when shear thinning OFF
+
+ +

Returns: (list)

+ +
the viscosity_matrix (index 0) & shear_rate matrix (index 1) for the polymer within the grid
+
+
+ + +
+
+ +
+ + def + compute_concentration( self, grid: lib.grid.Grid, water_sat: numpy.ndarray, u: numpy.ndarray, v: numpy.ndarray, xmod: numpy.ndarray, ymod: numpy.ndarray, const_parameters: dict, varying_parameters: dict): + + + +
+ +
365    def compute_concentration(
+366        self,
+367        grid: Grid,
+368        water_sat: np.ndarray,
+369        u: np.ndarray,
+370        v: np.ndarray,
+371        xmod: np.ndarray,
+372        ymod: np.ndarray,
+373        const_parameters: dict,
+374        varying_parameters: dict,
+375    ):
+376        """
+377        Computes the polymer concentration
+378
+379        Raises:
+380        -------
+381            SimulationCalcInputException: Not all required parameters were provided
+382
+383        Args:
+384        -----
+385            grid (Grid): the FDMesh
+386
+387            water_sat (np.ndarray): the water saturation matrix
+388
+389            u (np.ndarray): Matrix related to the global pressure
+390
+391            v (np.ndarray): Matrix related to the velocity matrix
+392
+393            xmod (np.ndarray): x-dim characteristic coordinates based on Neumann boundary conditions
+394
+395            ymod (np.ndarray): y-dim characteristic coordinates based on Neumann boundary conditions
+396
+397            const_parameters (dict): constant parameters to help with calculations
+398
+399            varying_parameters (dict): parameters that vary but assist with calculations for water saturation, polymer concentration, and surfactant concentration
+400        
+401        Returns: (dict)
+402        ---------------
+403            The varying parameters that were changed in this method
+404
+405        """
+406        # initializing variables:
+407        # Assert statements to ensure that all parameters are property initialized:
+408        assert self.concentration_matrix is not None, SimulationCalcInputException(
+409            "SimuationInputException: polymer concentration matrix not initialized. Please try again"
+410        )
+411        # Required constants:
+412        dx = const_parameters["FD_grid_constants"]["dx"]
+413        dy = const_parameters["FD_grid_constants"]["dy"]
+414        x = const_parameters["FD_grid_constants"]["x"]
+415        y = const_parameters["FD_grid_constants"]["y"]
+416        m = const_parameters["FD_grid_constants"]["m"]
+417        n = const_parameters["FD_grid_constants"]["n"]
+418        phi = self.phi
+419        omega1 = const_parameters["Pc_constants"]["omega1"]
+420        omega2 = const_parameters["Pc_constants"]["omega2"]
+421        Qnew = water_sat
+422        C = np.copy(self.concentration_matrix)
+423        g1 = const_parameters["inlet_total_flow"]
+424        g2 = const_parameters["inlet_polymer_flow"]
+425        KK = const_parameters["KK"]
+426        relative_permeability_formula = const_parameters[
+427            "relative_permeability_formula"
+428        ]
+429
+430        # retrieving relevant parameters for updating the water saturation
+431        ## Time Step:
+432        dt = const_parameters["FD_grid_constants"]["dt"]
+433        dt_array = const_parameters["FD_grid_constants"]["dt_matrix"]
+434
+435        # retrieving fractional flow variable
+436        f = varying_parameters["fractional_flow_parameters"]["f"]
+437
+438        # Determining 'Cmod'
+439        x1d = x[0, :]
+440        y1d = y[:, 0]
+441        x_sorted = np.all(np.diff(x1d) > 0)
+442        y_sorted = np.all(np.diff(y1d) > 0)
+443
+444        # reorder vec_concentration if a dimension isn't sorted
+445        if not x_sorted:
+446            x_sort_idx = np.argsort(x1d)
+447            x1d = x1d[x_sort_idx]
+448            C = C[:, x_sort_idx]  # Sort columns of vec_concentration
+449        if not y_sorted:
+450            y_sort_idx = np.argsort(y1d)
+451            y1d = y1d[y_sort_idx]
+452            C = C[y_sort_idx, :]  # Sort rows of vec_concentration
+453
+454        interp = sp.interpolate.RegularGridInterpolator(
+455            (y1d, x1d),
+456            self.concentration_matrix,
+457            method="linear",
+458            bounds_error=False,
+459            fill_value=None,
+460        )
+461        query_points = np.stack([ymod.ravel(), xmod.ravel()], axis=-1)
+462        Cmod = interp(query_points).reshape(xmod.shape)
+463
+464        # Using 'Cmod' and 'Qnew' to update the polymer concentration matrix
+465        idx = 1
+466        AAA = np.zeros((n * m, n * m))
+467        DDD = np.zeros((n * m, 1))
+468
+469        while idx <= (m) * (n - 1) + 1:
+470            cnt = (idx - 1) // m  # cnt = 0, 1, 2, ... for idx = 1, m+1, 2m+1, 3m+1, ...
+471            BB = np.zeros((n, m))
+472            AA = np.copy(BB)
+473            CC = np.copy(BB)
+474            DD = np.zeros((m, 1))
+475            for i in range(m):
+476                for j in range(n):
+477                    if j == i:
+478                        if idx == 1:  # lowermost row of grid
+479                            if i == 1:  # leftmost point (source)
+480                                DD[i] = (
+481                                    g2 / Qnew[cnt][i] + Cmod[cnt][i] / dt_array[cnt][i]
+482                                )
+483                                BB[j][i] = 1 / dt_array[cnt][i] + g1 / Qnew[cnt][i]
+484                            else:
+485                                DD[i] = Cmod[cnt][i] / dt_array[cnt][i]
+486                                BB[j][i] = 1 / dt_array[cnt][i]
+487                        elif idx == (m) * (n - 1) + 1:
+488                            if i == m - 1:
+489                                DD[i] = Cmod[cnt][i] / dt_array[cnt][i]
+490                                BB[j][i] = (
+491                                    1 / dt_array[cnt][i] - g1 * f[cnt][i] / Qnew[cnt][i]
+492                                )
+493                            else:
+494                                DD[i] = Cmod[cnt][i] / dt_array[cnt][i]
+495                                BB[j][i] = 1 / dt_array[cnt][i]
+496                        else:
+497                            DD[i] = Cmod[cnt][i] / dt_array[cnt][i]
+498                            BB[j][i] = 1 / dt_array[cnt][i]
+499
+500            if cnt == 0:
+501                AAA[0:n, 0 : 2 * m] = np.hstack([BB, CC])
+502            elif cnt == n - 1:
+503                AAA[(m - 1) * n : m * n, (n - 2) * m : n * m] = np.hstack([AA, BB])
+504            else:
+505                AAA[cnt * n : (cnt + 1) * n, (cnt - 1) * m : (cnt + 2) * m] = np.hstack(
+506                    [AA, BB, CC]
+507                )
+508
+509            DDD[cnt * m : (cnt + 1) * m] = DD
+510
+511            idx += m
+512
+513        Cnew_flat, info = bicgstab(AAA, DDD, rtol=10 ** (-10), maxiter=600)
+514        Cnew = Cnew_flat.reshape(m, n)
+515        self.concentration_matrix = Cnew
+516
+517        return varying_parameters
+
+ + +

Computes the polymer concentration

+ +

Raises:

+ +
SimulationCalcInputException: Not all required parameters were provided
+
+ +

Args:

+ +
grid (Grid): the FDMesh
+
+water_sat (np.ndarray): the water saturation matrix
+
+u (np.ndarray): Matrix related to the global pressure
+
+v (np.ndarray): Matrix related to the velocity matrix
+
+xmod (np.ndarray): x-dim characteristic coordinates based on Neumann boundary conditions
+
+ymod (np.ndarray): y-dim characteristic coordinates based on Neumann boundary conditions
+
+const_parameters (dict): constant parameters to help with calculations
+
+varying_parameters (dict): parameters that vary but assist with calculations for water saturation, polymer concentration, and surfactant concentration
+
+ +

Returns: (dict)

+ +
The varying parameters that were changed in this method
+
+
+ + +
+
+ +
+ + def + divergence(self, Fx, Fy, dx=1.0, dy=1.0): + + + +
+ +
519    def divergence(self, Fx, Fy, dx=1.0, dy=1.0):
+520        """
+521        Calculates Divergence
+522
+523        Args:
+524        -----
+525            Fx (np.ndarray): Function #1
+526            
+527            Fy (np.ndarray): Function #2
+528
+529            dx (float): change in the x-dimension
+530
+531            dy (float): change in the y-dimension
+532
+533        Raises: (np.ndarray)
+534        --------------------
+535            Div F = (δfx/δx) + (δfy/δy)
+536        """
+537        dFx_dx = np.gradient(Fx, dx, axis=1)
+538        dFy_dy = np.gradient(Fy, dy, axis=0)
+539        return dFx_dx + dFy_dy
+
+ + +

Calculates Divergence

+ +

Args:

+ +
Fx (np.ndarray): Function #1
+
+Fy (np.ndarray): Function #2
+
+dx (float): change in the x-dimension
+
+dy (float): change in the y-dimension
+
+ +

Raises: (np.ndarray)

+ +
Div F = (δfx/δx) + (δfy/δy)
+
+
+ + +
+
+
+ + \ No newline at end of file diff --git a/docs/lib/simulation.html b/docs/lib/simulation.html new file mode 100644 index 0000000..8c2776c --- /dev/null +++ b/docs/lib/simulation.html @@ -0,0 +1,4132 @@ + + + + + + + lib.simulation API documentation + + + + + + + + + +
+
+

+lib.simulation

+ +

This python script contains the class definition for running simulations

+ +

This Python code has been derived from the MATLAB Surfactant-Polymer Flooding Simulation +developed by Sourav Dutta and Rohit Mishra.

+ +

@author: Bhargav Akula Ramesh Kumar and Carlos Acosta Caripo

+
+ + + + + +
   1"""
+   2This python script contains the class definition for running simulations
+   3
+   4This Python code has been derived from the MATLAB Surfactant-Polymer Flooding Simulation 
+   5developed by Sourav Dutta and Rohit Mishra.
+   6
+   7@author: Bhargav Akula Ramesh Kumar and Carlos Acosta Caripo
+   8
+   9"""
+  10
+  11import os
+  12
+  13from .grid import Grid, FEMesh
+  14from .enumerations import (
+  15    ModelType,
+  16    PolymerList,
+  17    RelativePermeabilityFormula,
+  18    SurfactantList,
+  19    PermeabilityType,
+  20    ResevoirGeometry,
+  21    SimulationConstants,
+  22)
+  23from .Exceptions import SimulationCalcInputException, UserInputException
+  24from .polymer import Polymer
+  25from .surfactant import Surfactant
+  26import numpy as np
+  27import scipy as sp
+  28from .water import Water
+  29from scipy.io import loadmat
+  30from scipy.sparse.linalg import bicgstab
+  31from scipy.linalg import fractional_matrix_power
+  32from scipy.interpolate import RegularGridInterpolator
+  33
+  34os.makedirs(
+  35    "memmaps", exist_ok=True
+  36)  # ensures that the program works on computers with RAM constraints
+  37
+  38
+  39class Simulation:
+  40    """
+  41    Simulation class to run SP-flooding simulations based on MATLAB translation.
+  42    """
+  43
+  44    def __init__(self, user_input_dict: dict):
+  45        """
+  46        This method will check the ``user_input_dict`` and initialize the simulation
+  47        
+  48        Raises:
+  49        ------
+  50            UserInputException: If there is a issue with the user inputs in ``user_input_dict``
+  51            SimulationCalcInputException: If there is an issue with the execution of a calculation during runtime
+  52        
+  53        Args:
+  54        -----
+  55            user_input_dict (dict): dictionary containing the information from the GUI
+  56        """
+  57        ## Performs checks on the user input dictionary passed in:
+  58        try:
+  59            model_type = ModelType(user_input_dict["model_type"])
+  60            if model_type is None:
+  61                raise ValueError
+  62        except (KeyError, ValueError, TypeError):
+  63            raise UserInputException(
+  64                "UserInputError:BadModelTypeAssignment", user_input_dict
+  65            )
+  66
+  67        try:
+  68            reservoir_geometry = ResevoirGeometry(user_input_dict["reservoir_geometry"])
+  69            if reservoir_geometry is None:
+  70                raise ValueError
+  71        except (KeyError, ValueError, TypeError):
+  72            raise UserInputException(
+  73                "UserInputError:BadReservoirGeometryAssignment", user_input_dict
+  74            )
+  75
+  76        try:
+  77            permeability_flag = PermeabilityType(user_input_dict["permeability"])
+  78            if permeability_flag is None:
+  79                raise ValueError
+  80        except (KeyError, ValueError, TypeError):
+  81            raise UserInputException(
+  82                "UserInputError:BadPermeabilityAssignment", user_input_dict
+  83            )
+  84
+  85        try:
+  86            polymer_type = PolymerList.get_by_value(user_input_dict["polymer_type"])
+  87            if polymer_type is None:
+  88                raise ValueError
+  89        except (KeyError, ValueError, TypeError):
+  90            raise UserInputException(
+  91                "UserInputError:BadPolymerTypeAssignment", user_input_dict
+  92            )
+  93
+  94        try:
+  95            polymer_concentration = user_input_dict["polymer_concentration"]
+  96            if polymer_concentration is None:
+  97                raise ValueError
+  98        except (KeyError, ValueError, TypeError):
+  99            raise UserInputException(
+ 100                "UserInputError:BadPolymerConcentrationAssignment", user_input_dict
+ 101            )
+ 102
+ 103        try:
+ 104            surfactant_type = SurfactantList.get_by_value(
+ 105                user_input_dict["surfactant_type"]
+ 106            )
+ 107            if surfactant_type is None:
+ 108                raise ValueError
+ 109        except (KeyError, ValueError, TypeError):
+ 110            raise UserInputException(
+ 111                "UserInputError:BadSurfactantTypeAssignment", user_input_dict
+ 112            )
+ 113
+ 114        try:
+ 115            surfactant_concentration = user_input_dict["surfactant_concentration"]
+ 116            if surfactant_concentration is None:
+ 117                raise ValueError
+ 118        except (KeyError, ValueError, TypeError):
+ 119            raise UserInputException(
+ 120                "UserInputError:BadSurfactantConcentrationAssignment", user_input_dict
+ 121            )
+ 122
+ 123        ## Instantiates the required simulation properties:
+ 124
+ 125        # initializing properties that hold simulation constants
+ 126        self.grid_size = SimulationConstants.Grid_Size.value
+ 127        self.source_flow_magnitude = SimulationConstants.Source_Flow_Magnitude.value
+ 128
+ 129        # Initializing Simulation Flags:
+ 130        self.permeability_flag = permeability_flag
+ 131        self.reservoir_geometry = reservoir_geometry
+ 132        self.model_type = model_type
+ 133        self.relative_permeability_formula = (
+ 134            RelativePermeabilityFormula.AmaefuleHandEquation
+ 135        )  # WILL NEED TO UPDATE TO INCLUDE IN GUI
+ 136
+ 137        # Initializing sim properties
+ 138        self.mesh, self.FE_mesh = self._create_mesh()
+ 139        grid_shape = (self.mesh.n, self.mesh.m)
+ 140        self.x, self.y = self.mesh.get_meshgrid
+ 141        self.phi = None  # FIXME: Should check if this functionality code
+ 142        self.KK = None  # Permeability tensor
+ 143        self.time_step = None
+ 144        self.u, self.v = self._initialize_pressure_and_velocity()
+ 145        self._initialize_simulation()  # will initialize phi, KK, and time_step
+ 146        if (
+ 147            self.phi is None or self.KK is None or self.time_step is None
+ 148        ):  # Raise Exception if not properly initialized...
+ 149            raise SimulationCalcInputException(
+ 150                "SimulationCalcInputError:BadInitialSimulationPropertiesCalculation"
+ 151            )
+ 152
+ 153        # Initalizing Polymer Object
+ 154        self.polymer = Polymer(
+ 155            name=polymer_type,
+ 156            e_coeff=polymer_type.e_coeff,
+ 157            n_coeff=polymer_type.n_coeff,
+ 158            rho=polymer_type.Density,
+ 159            concentration_scalar=polymer_concentration,
+ 160            phi=self.phi,
+ 161        )
+ 162        self.polymer.initialize(grid_shape=grid_shape)
+ 163
+ 164        # Initializing Surfactant Object
+ 165        self.surfactant = Surfactant(
+ 166            name=surfactant_type,
+ 167            initial_concentration=surfactant_concentration,
+ 168            IFT_equation=surfactant_type.IFT_equation,
+ 169            derivative_IFT_equation=surfactant_type.derivative_IFT_equation,
+ 170            phi=self.phi,
+ 171        )
+ 172        self.surfactant.initialize()
+ 173
+ 174        # Initializing Water Object
+ 175        self.water = Water(
+ 176            init_water_saturation=SimulationConstants.Initial_Residual_Water_Saturation.value,
+ 177            init_aqueous_saturation=SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial.value,
+ 178            init_oleic_saturation=SimulationConstants.Resid_Oleic_Phase_Saturation_Initial.value,
+ 179            miuw=SimulationConstants.Water_Viscosity.value,
+ 180            miuo=SimulationConstants.Oil_Viscosity.value,
+ 181            phi=self.phi,
+ 182        )
+ 183        self.water.initialize(grid_shape=grid_shape)
+ 184
+ 185        # Properties for Exporting Simulation Results
+ 186        self.COC = np.zeros((1, 2000))  # Cumulative Oil Recovered
+ 187        self.miuaTcal = np.zeros((1, 2000))  # Total Aqueous Viscosity
+ 188        self.lambdaTcal = np.zeros((1, 2000))  # Total Mobility (λ_o + λ_a)
+ 189
+ 190        ##The following properties require memmaps:
+ 191        self.ProdRate, self.CROIP = (
+ 192            self._initialize_memmap_properties()
+ 193        )  # ProdRate (Production Rate) / CROIP (Cummulative Remaining Oil In Place)
+ 194        self.MFW = []
+ 195        self.integrated_inlet_flow = 0  # "src_total" in the MATLAB version of the code
+ 196
+ 197    # Property of Simulation Class
+ 198    _grid_size = None
+ 199    @property
+ 200    def grid_size(self):
+ 201        """
+ 202        grid_size (float): the dimensions of the square grid
+ 203        """
+ 204        return self._grid_size
+ 205    @grid_size.setter
+ 206    def grid_size(self, value):
+ 207        self._grid_size = value
+ 208
+ 209    _source_flow_magnitude = None
+ 210    @property
+ 211    def source_flow_magnitude(self):
+ 212        """
+ 213        source_flow_magnitude (float): flow rate at injection site
+ 214        """
+ 215        return self._source_flow_magnitude
+ 216    @source_flow_magnitude.setter
+ 217    def source_flow_magnitude(self, value):
+ 218        self._source_flow_magnitude = value
+ 219
+ 220    _permeability_flag = None
+ 221    @property
+ 222    def permeability_flag(self):
+ 223        """
+ 224        permeability_flag (enum 'PermeabilityType'): sets the permeability field based on enum ``PermeabilityType``
+ 225        """
+ 226        return self._permeability_flag
+ 227    @permeability_flag.setter
+ 228    def permeability_flag(self, value):
+ 229        self._permeability_flag = value
+ 230
+ 231    _reservoir_geometry = None
+ 232    @property
+ 233    def reservoir_geometry(self):
+ 234        """
+ 235        reservoir_geometry (enum 'ResevoirGeometry'): sets the reservoir geometry based on the enum ``ResevoirGeometry``
+ 236        """
+ 237        return self._reservoir_geometry
+ 238    @reservoir_geometry.setter
+ 239    def reservoir_geometry(self, value):
+ 240        self._reservoir_geometry = value
+ 241
+ 242    _model_type = None
+ 243    @property
+ 244    def model_type(self):
+ 245        """
+ 246        model_type (enum 'ModelType'): sets the type of simulation being run based on the enum ``ModelType``
+ 247        """
+ 248        return self._model_type
+ 249    @model_type.setter
+ 250    def model_type(self, value):
+ 251        self._model_type = value
+ 252
+ 253    _relative_permeability_formula = None
+ 254    @property
+ 255    def relative_permeability_formula(self):
+ 256        """
+ 257        relative_permeability_formula (enum 'RelativePermeabilityFormula'): sets the type of permeability formula being used in the simulation, based on the enum ``RelativePermeabilityFormula``
+ 258        """
+ 259        return self._relative_permeability_formula
+ 260    @relative_permeability_formula.setter
+ 261    def relative_permeability_formula(self, value):
+ 262        self._relative_permeability_formula = value
+ 263
+ 264    _phi = None
+ 265    @property
+ 266    def phi(self):
+ 267        """
+ 268        phi (np.ndarray): porosity matrix
+ 269        """
+ 270        return self._phi
+ 271    @phi.setter
+ 272    def phi(self, value):
+ 273        self._phi = value
+ 274
+ 275    _KK = None
+ 276    @property
+ 277    def KK(self):
+ 278       """
+ 279       KK (np.ndarray): the permeability matrix
+ 280       """
+ 281       return self._KK
+ 282    @KK.setter
+ 283    def KK(self, value):
+ 284       self._KK = value
+ 285
+ 286    _time_step = None
+ 287    @property
+ 288    def time_step(self):
+ 289        """
+ 290        time_step (float): The Δt
+ 291        """
+ 292        return self._time_step
+ 293    @time_step.setter
+ 294    def time_step(self, value):
+ 295        self._time_step = value
+ 296
+ 297    _polymer = None
+ 298    @property
+ 299    def polymer(self):
+ 300        """
+ 301        polymer (Polymer): Holds the ``Polymer`` object
+ 302        """
+ 303        return self._polymer
+ 304    @polymer.setter
+ 305    def polymer(self, value):
+ 306        self._polymer = value
+ 307
+ 308    _surfactant = None
+ 309    @property
+ 310    def surfactant(self):
+ 311        """
+ 312        surfactant (Surfactant): Holds the ``Surfactant`` object
+ 313        """
+ 314        return self._surfactant
+ 315    @surfactant.setter
+ 316    def surfactant(self, value):
+ 317        self._surfactant = value
+ 318
+ 319    _water = None
+ 320    @property
+ 321    def water(self):
+ 322        """
+ 323        water (Water): Holds the ``Water`` object
+ 324        """
+ 325        return self._water
+ 326    @water.setter
+ 327    def water(self, value):
+ 328        self._water = value
+ 329
+ 330    _COC = None
+ 331    @property
+ 332    def COC(self):
+ 333        """
+ 334        COC (np.ndarray): An array that holds the cummulative oil captured
+ 335        """
+ 336        return self._COC
+ 337    @COC.setter
+ 338    def COC(self, value):
+ 339        self._COC = value
+ 340
+ 341    _miuaTcal = None
+ 342    @property
+ 343    def miuaTcal(self):
+ 344        """
+ 345        miuTcal (np.ndarray): An array that caputres the change in the total aqueous viscosity over time
+ 346        """
+ 347        return self._miuaTcal
+ 348    @miuaTcal.setter
+ 349    def miuaTcal(self, value):
+ 350        self._miuaTcal = value
+ 351
+ 352    _lambdaTcal = None
+ 353    @property
+ 354    def lambdaTcal(self):
+ 355        """
+ 356        lambdaTcal (np.ndarray): Array that holds the change in the total mobility (λ_T = λ_a + λ_o)
+ 357        """
+ 358        return self._lambdaTcal
+ 359    @lambdaTcal.setter
+ 360    def lambdaTcal(self, value):
+ 361        self._lambdaTcal = value
+ 362
+ 363    _MFW = None
+ 364    @property
+ 365    def MFW(self):
+ 366        """
+ 367        MFW (np.ndarray): Array that holds change in the MFW (mean finger width)
+ 368        """
+ 369        return self._MFW
+ 370    @MFW.setter
+ 371    def MFW(self, value):
+ 372        self._MFW = value
+ 373
+ 374    _integrated_inlet_flow = None
+ 375    @property
+ 376    def integrated_inlet_flow(self):
+ 377        """
+ 378        integrated_inlet_flow (float): Basically the integrating the source flow rate over time
+ 379        """
+ 380        return self._integrated_inlet_flow
+ 381    @integrated_inlet_flow.setter
+ 382    def integrated_inlet_flow(self, value):
+ 383        self._integrated_inlet_flow = value
+ 384
+ 385    _source_prod_flow = None
+ 386    @property
+ 387    def source_prod_flow(self):
+ 388        """
+ 389        source_prod_flow (np.ndarray): The matrix with the source & and production well flow rates
+ 390
+ 391        assuming that the source flow = production well flow (flow magnitudes are the same!)
+ 392        """
+ 393        # setting permeability state
+ 394        if self._source_prod_flow is None:
+ 395            self._source_prod_flow = np.zeros((self.mesh.n + 1, self.mesh.m + 1))
+ 396            bool_Homogenous_and_Rectilinear = (
+ 397                self.permeability_flag.value == PermeabilityType.Homogenous.value
+ 398            ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+ 399            bool_Heterogenous_and_Rectilinear = (
+ 400                self.permeability_flag.value == PermeabilityType.Heterogenous.value
+ 401            ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+ 402            bool_Heterogenous_and_Quarter_Five_Spot = (
+ 403                self.permeability_flag.value == PermeabilityType.Heterogenous.value
+ 404            ) and (
+ 405                self.reservoir_geometry.value
+ 406                == ResevoirGeometry.Quarter_Five_Spot.value
+ 407            )
+ 408            if bool_Homogenous_and_Rectilinear or bool_Heterogenous_and_Rectilinear:
+ 409                self._source_prod_flow[:, 0] = (
+ 410                    self.source_flow_magnitude
+ 411                )  # intensity of injection well = src
+ 412                self._source_prod_flow[:, -1] = (
+ 413                    -1 * self.source_flow_magnitude
+ 414                )  # intensity of production well = -src
+ 415            elif bool_Heterogenous_and_Quarter_Five_Spot:  # Quarter-Five Spot
+ 416                self._source_prod_flow[0, 0] = (
+ 417                    self.source_flow_magnitude
+ 418                )  # Intensity of injection well = src
+ 419                self._source_prod_flow[-1, -1] = (
+ 420                    -1 * self.source_flow_magnitude
+ 421                )  # Intensity of production well = -src
+ 422
+ 423        return self._source_prod_flow
+ 424
+ 425    _scenario_flag = None
+ 426    @property
+ 427    def scenario_flag(self):
+ 428        """
+ 429        Determines the scenario based on the chosen reservoir geometry and permeability.
+ 430        Returns the integer value that represents a type of scenario run
+ 431        """
+ 432        if self._scenario_flag is None:
+ 433            bool_Homogenous_and_Rectilinear = (
+ 434                self.permeability_flag.value == PermeabilityType.Homogenous.value
+ 435            ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+ 436            bool_Heterogenous_and_Rectilinear = (
+ 437                self.permeability_flag.value == PermeabilityType.Heterogenous.value
+ 438            ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+ 439            bool_Heterogenous_and_Quarter_Five_Spot = (
+ 440                self.permeability_flag.value == PermeabilityType.Heterogenous.value
+ 441            ) and (
+ 442                self.reservoir_geometry.value
+ 443                == ResevoirGeometry.Quarter_Five_Spot.value
+ 444            )
+ 445
+ 446            if bool_Homogenous_and_Rectilinear:
+ 447                self._scenario_flag = 1
+ 448            elif bool_Heterogenous_and_Rectilinear:
+ 449                self._scenario_flag = 2
+ 450            elif bool_Heterogenous_and_Quarter_Five_Spot:
+ 451                self._scenario_flag = 3
+ 452            else:
+ 453                raise SimulationCalcInputException(
+ 454                    "SimulationCalcInputError:InvalidSimulationCase"
+ 455                )
+ 456
+ 457        return self._scenario_flag
+ 458
+ 459    # Private Methods of the Simulation Class
+ 460    def _initialize_pressure_and_velocity(self):
+ 461        """
+ 462        (private method)
+ 463
+ 464        Initializing global pressure ('u') and velocity matrices ('v')
+ 465        Will use the ``n`` and ``m`` properties from ``Grid`` Class for initialization
+ 466
+ 467        Returns: (tuple[np.ndarray, np.ndarray])
+ 468        ----------------------------------------
+ 469            The global pressure matrix (index 0) and velocity matrix (index 1)
+ 470        """
+ 471        u = np.zeros((self.mesh.n + 1, self.mesh.m + 1), dtype=np.complex128)
+ 472        v = np.zeros((self.mesh.n + 1, self.mesh.m + 1), dtype=np.complex128)
+ 473
+ 474        return u, v
+ 475
+ 476    def _compute_pressure_and_velocity_matrices(self, sparsed_A, B, beta):
+ 477        """
+ 478        (private method)
+ 479
+ 480        dependent property to calculate the pressure matrix (``u``)
+ 481        and velocity matrix (``v``). Will rely on functions in the ``FEMesh`` class.
+ 482        
+ 483        Returns: (list[np.ndarray])
+ 484        ---------------------------
+ 485            List of update pressure matrix and velocity matrix => [u,v]
+ 486        """
+ 487        max_iterations = 1000
+ 488        new_u, convergence_flag = bicgstab(
+ 489            sparsed_A, B, rtol=1e-10, atol=0, maxiter=max_iterations
+ 490        )  # new_u is of shape (900, )
+ 491        if convergence_flag != 0:
+ 492            import warnings
+ 493            warnings.warn(f"BiCGSTAB: convergence issue (info={convergence_flag}) in pressure solver")
+ 494
+ 495        new_v = np.zeros((self.FE_mesh.n + 1, self.FE_mesh.m + 1), dtype=object)
+ 496        for i in range(self.FE_mesh.m + 1):
+ 497            for j in range(self.FE_mesh.n + 1):
+ 498                new_v[j, i] = new_u[j * (self.FE_mesh.m + 1) + i]
+ 499
+ 500        px, py = self._get_gradient(new_v)
+ 501        new_u = (-1 * beta) * px
+ 502        new_v = (-1 * beta) * py
+ 503
+ 504        return new_u, new_v
+ 505
+ 506    def _get_gradient(self, vn):
+ 507        """
+ 508        (private method)
+ 509
+ 510        Helper function to determine the gradients with respect to x and y dimensions
+ 511        
+ 512        Returns: (tuple[_Array[tuple[int, int], float64], NDArray[float64]])
+ 513        --------------------------------------------------------------------
+ 514            Tuple with px py which are numpy matrices that hold the gradient wrt to x and y dimensions
+ 515        """
+ 516        m = self.mesh.m
+ 517        n = self.mesh.n
+ 518
+ 519        dx = self.mesh.dx
+ 520        dy = self.mesh.dy
+ 521
+ 522        px = np.zeros((n + 1, m + 1))
+ 523        py = np.copy(px)
+ 524
+ 525        for i in range(m + 1):
+ 526            for j in range(n + 1):
+ 527                if i != 0:
+ 528                    px[j, i] = (vn[j, i] - vn[j, i - 1]) / dx
+ 529                if i != m:
+ 530                    px[j, i] = (vn[j, i + 1] - vn[j, i]) / dx
+ 531                if i != 0 and i != m:
+ 532                    px[j, i] = (vn[j, i + 1] - vn[j, i - 1]) / (2 * dx)
+ 533                if j != 0:
+ 534                    py[j, i] = (vn[j, i] - vn[j - 1, i]) / dy
+ 535                if j != n:
+ 536                    py[j, i] = (vn[j + 1, i] - vn[j, i]) / dy
+ 537                if j != 0 and j != n:
+ 538                    py[j, i] = (vn[j + 1, i] - vn[j - 1, i]) / (2 * dy)
+ 539
+ 540        return px, py
+ 541
+ 542    def _initialize_memmap_properties(self):
+ 543        """
+ 544        (private method)
+ 545
+ 546        Will initialize the ``ProdRate`` and ``CROIP`` properties.
+ 547        Using memmaps to allow window's users to run program.
+ 548        
+ 549        Returns: (tuple[np.ndarray, np.ndarray])
+ 550        ----------------------------------------
+ 551            Initialized ``ProdRate`` and ``CROIP`` properties
+ 552        """
+ 553        os.makedirs("memmaps", exist_ok=True)
+ 554        tf = 500
+ 555        dt = self.mesh.dx / self.source_flow_magnitude
+ 556        timestamps = int(np.floor(tf / dt))
+ 557        CROIP = np.memmap(
+ 558            "memmaps/CROIP.dat", dtype="float64", mode="w+", shape=(1, timestamps)
+ 559        )
+ 560        ProdRate = np.memmap(
+ 561            "memmaps/ProdRate.dat", dtype="float64", mode="w+", shape=(1, timestamps)
+ 562        )
+ 563
+ 564        return ProdRate, CROIP
+ 565
+ 566    def _create_mesh(self):
+ 567        """
+ 568        (private method)
+ 569
+ 570        Returns: (Tuple[Grid, FEMesh])
+ 571        -----------------------------
+ 572            Initialized FD and FE mesh
+ 573        """
+ 574        FD_mesh = Grid(self.grid_size, self.grid_size)
+ 575
+ 576        FE_mesh = FEMesh(self.grid_size, self.grid_size)
+ 577
+ 578        return FD_mesh, FE_mesh
+ 579
+ 580    def _initialize_simulation(self):
+ 581        """
+ 582        (private method)
+ 583
+ 584        Sets up initial reservoir fields, permeability, and time step.
+ 585
+ 586        Returns: (None)
+ 587        ---------------
+ 588            Initialized properties of simulation. Required in ``__init__`` function
+ 589        """
+ 590        self.phi = self._compute_phi()
+ 591
+ 592        # Initialize permeability matrix
+ 593        self.KK = self._compute_permeability()
+ 594
+ 595        # Calculate time step
+ 596        self.time_step = self.mesh.dx / self.source_flow_magnitude
+ 597        if (
+ 598            self.permeability_flag == PermeabilityType.Heterogenous
+ 599            and self.reservoir_geometry == ResevoirGeometry.Quarter_Five_Spot
+ 600        ):
+ 601            self.time_step *= 100
+ 602
+ 603    def _compute_phi(self):
+ 604        """
+ 605        (private method)
+ 606
+ 607        Returns: (np.ndarray)
+ 608        ---------------------
+ 609            Computes and returns the level set function phi at each grid point. 
+ 610            (Equivalent to MATLAB get_phi_test function.)
+ 611        """
+ 612        m = self.mesh.m
+ 613        n = self.mesh.n
+ 614        dx = self.mesh.dx
+ 615        dy = self.mesh.dy
+ 616        left = self.mesh.left
+ 617        bottom = self.mesh.bottom
+ 618
+ 619        jj, ii = np.meshgrid(np.arange(1, n + 2), np.arange(1, m + 2))
+ 620        x_coords = left + (ii - 1) * dx
+ 621        y_coords = bottom + (jj - 1) * dy
+ 622
+ 623        phi = self._z_func_test(x_coords, y_coords)
+ 624        return phi
+ 625
+ 626    def _z_func_test(self, x, y):
+ 627        """
+ 628        (private method)
+ 629
+ 630        Args:
+ 631        -----
+ 632            x (np.ndarry): x-dimension coordinates 
+ 633
+ 634            y (np.ndarray): y-dimension coordinate points
+ 635        
+ 636        Returns: 
+ 637        --------
+ 638            Compute and returns the initial position of the water front.
+ 639            (Equivalent to MATLAB z_func_test.)
+ 640
+ 641        """
+ 642        init_front_hs = 0.1
+ 643        bool_Homogenous_and_Rectilinear = (
+ 644            self.permeability_flag.value == PermeabilityType.Homogenous.value
+ 645        ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+ 646        bool_Heterogenous_and_Rectilinear = (
+ 647            self.permeability_flag.value == PermeabilityType.Heterogenous.value
+ 648        ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+ 649        bool_Heterogenous_and_Quarter_Five_Spot = (
+ 650            self.permeability_flag.value == PermeabilityType.Heterogenous.value
+ 651        ) and (
+ 652            self.reservoir_geometry.value == ResevoirGeometry.Quarter_Five_Spot.value
+ 653        )
+ 654        if bool_Homogenous_and_Rectilinear:
+ 655            # Homogeneous
+ 656            out = y - init_front_hs + 0.01 * np.cos(80 * np.pi * x)
+ 657        elif bool_Heterogenous_and_Rectilinear:
+ 658            # Rectilinear Heterogeneous
+ 659            out = y - init_front_hs
+ 660        elif bool_Heterogenous_and_Quarter_Five_Spot:
+ 661            # Quarter five spot
+ 662            out = np.square(x) + np.square(y) - 0.015
+ 663        else:
+ 664            out = np.zeros_like(x)
+ 665
+ 666        return out
+ 667
+ 668    def _compute_permeability(self):
+ 669        """
+ 670        (private method)
+ 671        
+ 672        Returns:
+ 673        -------
+ 674            Compute and returns the permeability matrix KK based on the ``scenario_flag``.
+ 675            (Equivalent to MATLAB KKdef function.)
+ 676        """
+ 677        bool_Homogenous_and_Rectilinear = (
+ 678            self.permeability_flag.value == PermeabilityType.Homogenous.value
+ 679        ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+ 680        bool_Heterogenous_and_Rectilinear = (
+ 681            self.permeability_flag.value == PermeabilityType.Heterogenous.value
+ 682        ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+ 683        bool_Heterogenous_and_Quarter_Five_Spot = (
+ 684            self.permeability_flag.value == PermeabilityType.Heterogenous.value
+ 685        ) and (
+ 686            self.reservoir_geometry.value == ResevoirGeometry.Quarter_Five_Spot.value
+ 687        )
+ 688        m = self.mesh.m
+ 689        KK = None
+ 690        if bool_Homogenous_and_Rectilinear:
+ 691            # Homogeneous
+ 692            Kmax = 100
+ 693            KK = Kmax * np.ones((m + 1, m + 1))
+ 694        elif bool_Heterogenous_and_Rectilinear:
+ 695            # Heterogeneous
+ 696            Kmax = 100
+ 697            KK = Kmax * (
+ 698                0.5
+ 699                * (1 - 10 ** (-7))
+ 700                * (
+ 701                    np.sin(6 * np.pi * np.cos(self.x))
+ 702                    * np.cos(4 * np.pi * np.sin(3 * self.y))
+ 703                    - 1
+ 704                )
+ 705                + 1
+ 706            )
+ 707        elif bool_Heterogenous_and_Quarter_Five_Spot:
+ 708            # Load Upper Ness formation (SPE10)
+ 709            mat_data = loadmat(
+ 710                "./lib/Resources/KK30Ness.mat"
+ 711            )  # FIXME: when using master_surf_grid need to change this path
+ 712            if "KK" not in mat_data:
+ 713                raise SimulationCalcInputException(
+ 714                    "SimulationInputException: KK matrix not found in KK30Ness.mat file."
+ 715                )
+ 716            KK = mat_data["KK"]
+ 717        return KK
+ 718
+ 719    def _transport_equation_solver(self, dt):
+ 720        """
+ 721        (Private method)
+ 722
+ 723        This method of the ``Simulation`` class will solve the transport equations
+ 724        for the surfactant concentration, polymer concentration, and water saturation
+ 725
+ 726        Based on the 'nmmoc_surf_mod_neumann.m' function within the MATLAB version
+ 727
+ 728        Note:
+ 729            dg - derivative with respect to surfactant concentration
+ 730            ds - derivative with respect to water saturation
+ 731            dc - derivative with respect to polymer concentration
+ 732
+ 733        Returns: (tuple[float, float, float])
+ 734        ----------------------------------------------------
+ 735            tuple[ocut, wcut, ROIP]
+ 736            ocut - volume of oil in the production well
+ 737            wcut - volume of water in the production well
+ 738            ROIP - residual oil in place (as a volume fraction)
+ 739        """
+ 740        # Initialize constant parameters
+ 741        const_parameters = {}
+ 742        const_parameters["inlet_total_flow"] = self.source_flow_magnitude  # G1
+ 743        const_parameters["inlet_polymer_flow"] = (
+ 744            self.polymer.concetration_scalar * self.source_flow_magnitude
+ 745        )  # G2
+ 746        const_parameters["inlet_surfactant_flow"] = (
+ 747            self.surfactant.concentration * self.source_flow_magnitude
+ 748        )  # G3
+ 749        assert self.water.water_saturation is not None, SimulationCalcInputException(
+ 750            "SimulationCalcInputError:UndefinedWaterSaturationMatrix"
+ 751        )
+ 752        n = np.shape(self.water.water_saturation)[0]
+ 753        m = np.shape(self.water.water_saturation)[1]
+ 754        const_parameters["FD_grid_constants"] = {
+ 755            "n": n,
+ 756            "m": m,
+ 757            "dx": self.mesh.dx,
+ 758            "dy": self.mesh.dy,
+ 759            "dt": dt,
+ 760            "dt_matrix": dt * np.ones((n, m)),
+ 761            "x": self.mesh.x,
+ 762            "y": self.mesh.y,
+ 763        }
+ 764        ## parameters around Pc calculations
+ 765        const_parameters["Pc_constants"] = {
+ 766            "omega1": SimulationConstants.Capillary_Pressure_Param_1.value,
+ 767            "omega2": SimulationConstants.Capillary_Pressure_Param_2.value,
+ 768        }
+ 769        ## parameters around capillary number for residual saturation calcs
+ 770        const_parameters["resid_saturation_constants"] = {
+ 771            "Nco0": 10 ** (-5),
+ 772            "Nca0": 10 ** (-5),
+ 773        }
+ 774        ## porosity parameter
+ 775        const_parameters["porosity"] = 1
+ 776
+ 777        ## Permeability
+ 778        const_parameters["KK"] = self.KK
+ 779        const_parameters["relative_permeability_formula"] = (
+ 780            self.relative_permeability_formula
+ 781        )
+ 782
+ 783        # Initialize variable parameters
+ 784        varying_parameters = {}
+ 785        ## residual water and oil saturations
+ 786        [swr, sor] = self.water.compute_residual_saturations(
+ 787            sigma=self.surfactant.eval_IFT, u=self.u, v=self.v
+ 788        )
+ 789        varying_parameters["swr"] = swr
+ 790        varying_parameters["sor"] = sor
+ 791        nsw = (self.water.water_saturation - swr) / (1 - swr)
+ 792        nso = (self.water.water_saturation - swr) / (1 - swr - sor)
+ 793        varying_parameters["nsw"] = nsw
+ 794        varying_parameters["nso"] = nso
+ 795        ## recomputing mobilities
+ 796        assert (
+ 797            self.polymer.concentration_matrix is not None
+ 798        ), SimulationCalcInputException(
+ 799            "SimulationCalcInputError:UnknownPolymerConcentrationMatrix"
+ 800        )
+ 801        lambda_a = self.water.compute_mobility(
+ 802            c=self.polymer.concentration_matrix,
+ 803            sor=float(sor),
+ 804            swr=float(swr),
+ 805            aqueous=True,
+ 806            rel_permeability_formula=self.relative_permeability_formula,
+ 807        )
+ 808        lambda_o = self.water.compute_mobility(
+ 809            c=self.polymer.concentration_matrix,
+ 810            sor=float(sor),
+ 811            swr=float(swr),
+ 812            aqueous=False,
+ 813            rel_permeability_formula=self.relative_permeability_formula,
+ 814        )
+ 815        lambda_total = lambda_a + lambda_o
+ 816        varying_parameters["mobility_parameters"] = {
+ 817            "lambda_a": lambda_a,
+ 818            "lambda_o": lambda_o,
+ 819            "lambda_total": lambda_total,
+ 820        }
+ 821        ## fractional flow calculations
+ 822        f = lambda_a / lambda_total
+ 823        assert self.KK is not None, SimulationCalcInputException(
+ 824            "SimulationCalcInputError:UnknownPermeabilityTensor"
+ 825        )
+ 826        D = self.KK * lambda_o * f
+ 827        varying_parameters["fractional_flow_parameters"] = {"f": f, "D": D}
+ 828        ## calculating dσ/dΓ
+ 829        varying_parameters["IFT_and_derivative"] = {
+ 830            "IFT": self.surfactant.eval_IFT,
+ 831            "dIFT_dg": self.surfactant.eval_dIFT_dGamma,
+ 832        }
+ 833        ## compute capillary number
+ 834        assert self.water.viscosity_array is not None, SimulationCalcInputException(
+ 835            "SimulationCalcInputError:UnknownAqueousViscosityMatrix"
+ 836        )
+ 837        nca = (
+ 838            np.sqrt(np.matmul(self.u, self.u) + np.matmul(self.v, self.v), dtype=np.complex128)
+ 839            * self.water.viscosity_array.astype(np.complex128)
+ 840            / self.surfactant.eval_IFT.astype(np.complex128)
+ 841        )
+ 842        nco = (
+ 843            np.sqrt(np.matmul(self.u, self.u) + np.matmul(self.v, self.v), dtype=np.complex128)
+ 844            * SimulationConstants.Oil_Viscosity.value
+ 845            / self.surfactant.eval_IFT
+ 846        )
+ 847        norm_nca = np.linalg.norm(nca)  # 2-norm of nca
+ 848        norm_nco = np.linalg.norm(nco)  # 2-norm of nco
+ 849        ## compute derivatives of residual saturations with respect to surfactant concentration (FIXME: Need to update when inplementing autodiff!)
+ 850        dswr_dg = np.zeros((n, m))
+ 851        dsor_dg = np.zeros((n, m))
+ 852        swr_0 = SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial.value
+ 853        sor_0 = SimulationConstants.Resid_Oleic_Phase_Saturation_Initial.value
+ 854        assert (
+ 855            self.surfactant.concentration_matrix is not None
+ 856        ), SimulationCalcInputException(
+ 857            "SimulationCalcInputError:UnknownSurfactantConcentrationMatrix"
+ 858        )
+ 859        for j in range(n):
+ 860            for i in range(m):
+ 861                if norm_nca >= const_parameters["resid_saturation_constants"]["Nca0"]:
+ 862                    dswr_dg[j, i] = -(
+ 863                        swr_0
+ 864                        * 0.1534
+ 865                        * 10.001
+ 866                        * (
+ 867                            const_parameters["resid_saturation_constants"]["Nca0"]
+ 868                            ** 0.1534
+ 869                        )
+ 870                    ) / (
+ 871                        (
+ 872                            np.sqrt((self.u[j, i] ** 2) + (self.v[j, i] ** 2))
+ 873                            * self.water.viscosity_array[j, i]
+ 874                        )
+ 875                        ** (0.1534)
+ 876                        * self.surfactant.eval_IFT[j, i] ** (0.8466)
+ 877                        * (self.surfactant.concentration_matrix[j, i] + 1) ** 2
+ 878                    )
+ 879                if norm_nco >= const_parameters["resid_saturation_constants"]["Nco0"]:
+ 880                    dsor_dg[j, i] = -(
+ 881                        sor_0
+ 882                        * 0.5213
+ 883                        * 10.001
+ 884                        * (
+ 885                            const_parameters["resid_saturation_constants"]["Nca0"]
+ 886                            ** 0.5213
+ 887                        )
+ 888                    ) / (
+ 889                        (
+ 890                            np.sqrt((self.u[j, i] ** 2) + (self.v[j, i] ** 2))
+ 891                            * self.water.viscosity_array[j, i]
+ 892                        )
+ 893                        ** (0.5213)
+ 894                        * self.surfactant.eval_IFT[j, i] ** (0.4787)
+ 895                        * (self.surfactant.concentration_matrix[j, i] + 1) ** 2
+ 896                    )
+ 897        varying_parameters["resid_saturation_derivatives"] = {
+ 898            "dswr_dg": dswr_dg,
+ 899            "dsor_dg": dsor_dg,
+ 900        }
+ 901        ## compute derivatives of normalized saturation with respect to surfactant concentration (FIXME: Need to update when inplementing autodiff!)
+ 902        varying_parameters["normalized_saturation_derivatives"] = {
+ 903            "dnsw_dg": dswr_dg * (self.water.water_saturation - 1) / (1 - swr) ** 2,
+ 904            "dnso_dg": (
+ 905                dswr_dg * (self.water.water_saturation + sor - 1)
+ 906                + dsor_dg * (self.water.water_saturation - swr)
+ 907            )
+ 908            / (1 - swr - sor) ** 2,
+ 909        }
+ 910        ## computing relative permeability with respect to surfactant concentration (FIXME: Need to update when inplementing autodiff!)
+ 911        varying_parameters["relative_permeability_derivatives"] = {
+ 912            "dkra_dg": 2.5 * dswr_dg * (nsw**3 - nsw)
+ 913            + (self.water.water_saturation - 1)
+ 914            * (2.5 * swr * (3 * nsw**2 - 1) + 1)
+ 915            * varying_parameters["normalized_saturation_derivatives"]["dnsw_dg"]
+ 916            / (1 - swr) ** 2,
+ 917            "dkro_dg": 1
+ 918            - 5 * sor * nso
+ 919            + (1 - nso) * (1 - 5 * nso * dsor_dg)
+ 920            - (1 + 5 * sor - 10 * sor * nso)
+ 921            * varying_parameters["normalized_saturation_derivatives"]["dnso_dg"],
+ 922            "dkra_ds": 2.5 * swr * (3 * (nsw) ** 2 - 1) + 1,
+ 923            "dkro_ds": 10 * sor * nso - 5 * sor - 1,
+ 924        }
+ 925        ## computing capillary pressure derivatives with respect to concentrations and saturations (FIXME: Need to update when inplementing autodiff!)
+ 926        pc = (
+ 927            self.surfactant.eval_IFT
+ 928            * const_parameters["Pc_constants"]["omega2"]
+ 929            * np.sqrt(const_parameters["porosity"])
+ 930        ) / (
+ 931            np.matmul(
+ 932                self.KK ** (0.5),
+ 933                fractional_matrix_power(
+ 934                    1 - nso, 1 / const_parameters["Pc_constants"]["omega1"]
+ 935                ),
+ 936            )
+ 937        )
+ 938        dpc_ds = pc / (const_parameters["Pc_constants"]["omega1"] * (1 - nso))
+ 939        dpc_dg = (
+ 940            pc / self.surfactant.eval_IFT
+ 941        ) * self.surfactant.eval_dIFT_dGamma + dpc_ds
+ 942        varying_parameters["capillary_pressure_and_derivatives"] = {
+ 943            "pc": pc,
+ 944            "dpc_ds": dpc_ds,
+ 945            "dpc_dg": dpc_dg,
+ 946        }
+ 947        ## computing fractional flow derivatives with respect to concentrations and saturations (FIXME: Need to update when inplementing autodiff!)
+ 948        varying_parameters["fractional_flow_derivatives"] = {
+ 949            "df_ds": varying_parameters["relative_permeability_derivatives"]["dkra_ds"]
+ 950            * lambda_o
+ 951            / (lambda_total**2 * self.water.viscosity_array)
+ 952            - varying_parameters["relative_permeability_derivatives"]["dkro_ds"]
+ 953            * lambda_a
+ 954            / (lambda_total**2 * self.water.miuo),
+ 955            "df_dc": (-1 * (lambda_o * lambda_a * self.water.miuo))
+ 956            / ((lambda_total**2) * self.water.viscosity_array),
+ 957            "df_dg": (
+ 958                (
+ 959                    varying_parameters["relative_permeability_derivatives"]["dkra_dg"]
+ 960                    * lambda_o
+ 961                )
+ 962                / ((lambda_total**2) * self.water.viscosity_array)
+ 963            )
+ 964            - (
+ 965                (
+ 966                    varying_parameters["relative_permeability_derivatives"]["dkro_dg"]
+ 967                    * lambda_a
+ 968                )
+ 969                / ((lambda_total**2) * self.water.viscosity_array)
+ 970            ),
+ 971            "dD_dg": D
+ 972            * varying_parameters["capillary_pressure_and_derivatives"]["dpc_dg"],
+ 973            "dD_ds": D
+ 974            * varying_parameters["capillary_pressure_and_derivatives"]["dpc_ds"],
+ 975        }
+ 976        # Update Water Saturation Matrix
+ 977        ## Calculate ``xmod`` and ``ymod``
+ 978        [xmod, ymod] = self._characteristic_coordinates(
+ 979            1,
+ 980            self.water.water_saturation,
+ 981            self.water.water_saturation,
+ 982            const_parameters,
+ 983            varying_parameters,
+ 984        )
+ 985
+ 986        ## Pass in parameters into ``compute_water_saturation`` method of the ``Water`` class
+ 987        Q_old = np.copy(self.water.water_saturation)
+ 988        Qmod, varying_parameters = self.water.compute_water_saturation(
+ 989            grid=self.mesh,
+ 990            surfactant=self.surfactant,
+ 991            polymer=self.polymer,
+ 992            u=self.u,
+ 993            v=self.v,
+ 994            xmod=xmod,
+ 995            ymod=ymod,
+ 996            const_parameters=const_parameters,
+ 997            varying_parameters=varying_parameters,
+ 998        )
+ 999
+1000        # Update the Polymer Concentration Matrix
+1001        [xmod, ymod] = self._characteristic_coordinates(
+1002            2, Q_old, self.water.water_saturation, const_parameters, varying_parameters
+1003        )
+1004        C_old = np.copy(self.polymer.concentration_matrix)
+1005        varying_parameters = self.polymer.compute_concentration(
+1006            grid=self.mesh,
+1007            water_sat=self.water.water_saturation,
+1008            u=self.u,
+1009            v=self.v,
+1010            xmod=xmod,
+1011            ymod=ymod,
+1012            const_parameters=const_parameters,
+1013            varying_parameters=varying_parameters,
+1014        )
+1015
+1016        # Update the Surfactant Concentration matrix
+1017        [xmod, ymod] = self._characteristic_coordinates(
+1018            3, Q_old, self.water.water_saturation, const_parameters, varying_parameters
+1019        )
+1020        G_old = np.copy(self.surfactant.concentration_matrix)
+1021        G = np.copy(self.surfactant.concentration_matrix)
+1022        x1d = self.mesh.x[0, :]
+1023        y1d = self.mesh.y[:, 0]
+1024        x_sorted = np.all(np.diff(x1d) > 0)
+1025        y_sorted = np.all(np.diff(y1d) > 0)
+1026
+1027        # reorder surfactant.concentration_matrix if a dimension isn't sorted
+1028        if not x_sorted:
+1029            x_sort_idx = np.argsort(x1d)
+1030            x1d = x1d[x_sort_idx]
+1031            G = G[:, x_sort_idx]  # Sort columns of surfactant.concentration_matrix
+1032        if not y_sorted:
+1033            y_sort_idx = np.argsort(y1d)
+1034            y1d = y1d[y_sort_idx]
+1035            G = G[y_sort_idx, :]  # Sort rows of surfactant.concentration_matrix
+1036
+1037        interp = sp.interpolate.RegularGridInterpolator(
+1038            (y1d, x1d),
+1039            G,
+1040            method="linear",
+1041            bounds_error=False,
+1042            fill_value=None,
+1043        )
+1044        query_points = np.stack([ymod.ravel(), xmod.ravel()], axis=-1)
+1045        Gmod = interp(query_points).reshape(xmod.shape)
+1046
+1047        # Updating coefficients using interpolated surfactant concentration
+1048        assert self.surfactant.IFT_conc_equ is not None, SimulationCalcInputException(
+1049            "SimulationCalcInputError:UnknownIFTEquation"
+1050        )
+1051        assert (
+1052            self.surfactant.derivative_IFT_conc_equ is not None
+1053        ), SimulationCalcInputException(
+1054            "SimulationCalcInputError:UnknownDerivativeIFTEquation"
+1055        )
+1056        sigma_mod = self.surfactant.IFT_conc_equ(Gmod)
+1057        sigma_g_mod = self.surfactant.derivative_IFT_conc_equ(Gmod)
+1058        [swr, sor] = self.water.compute_residual_saturations(
+1059            sigma=sigma_mod, u=self.u, v=self.v
+1060        )
+1061        lambda_a = self.water.compute_mobility(
+1062            c=C_old,
+1063            sor=float(sor),
+1064            swr=float(swr),
+1065            aqueous=True,
+1066            rel_permeability_formula=self.relative_permeability_formula,
+1067            modified_water_saturation=Qmod,
+1068        )
+1069        lambda_o = self.water.compute_mobility(
+1070            c=C_old,
+1071            sor=float(sor),
+1072            swr=float(swr),
+1073            aqueous=False,
+1074            rel_permeability_formula=self.relative_permeability_formula,
+1075            modified_water_saturation=Qmod,
+1076        )
+1077        lambda_total = lambda_a + lambda_o
+1078        varying_parameters["mobility_parameters"] = {
+1079            "lambda_a": lambda_a,
+1080            "lambda_o": lambda_o,
+1081            "lambda_total": lambda_total,
+1082        }
+1083        f = lambda_a / lambda_total
+1084        assert self.KK is not None, SimulationCalcInputException(
+1085            "SimulationCalcInputError:UnknownPermeabilityTensor"
+1086        )
+1087        D = self.KK * lambda_o * f
+1088        varying_parameters["fractional_flow_parameters"] = {"f": f, "D": D}
+1089        dpc_ds = pc / (const_parameters["Pc_constants"]["omega1"] * (1 - nso))
+1090        dpc_dg = (pc / sigma_mod) * sigma_g_mod + dpc_ds
+1091        varying_parameters["capillary_pressure_and_derivatives"] = {
+1092            "pc": pc,
+1093            "dpc_ds": dpc_ds,
+1094            "dpc_dg": dpc_dg,
+1095        }
+1096        F = D * dpc_dg / self.water.water_saturation
+1097        varying_parameters = self.surfactant.compute_concentration(
+1098            grid=self.mesh,
+1099            water_sat=self.water.water_saturation,
+1100            const_parameters=const_parameters,
+1101            varying_parameters=varying_parameters,
+1102            F=F,
+1103            Gmod=Gmod,
+1104        )
+1105
+1106        # calculate the Oil capture, water captured, and residual oil in place
+1107        ocut = lambda_o[n, m] * self.source_flow_magnitude / lambda_total[n,m]
+1108        wcut = lambda_a[n, m] * self.source_flow_magnitude / lambda_total[n,m]
+1109        ROIP = 100*(np.sum(np.sum(1 - self.water.water_saturation)))/sum(np.ones((n*m,1)))
+1110        return ocut, wcut, ROIP
+1111
+1112    def _characteristic_coordinates(
+1113        self,
+1114        flag,
+1115        old_water_saturation_matrix,
+1116        new_water_saturation_matrix,
+1117        const_parameters,
+1118        varying_parameters,
+1119    ):
+1120        """
+1121        (private method)
+1122
+1123        Compute redefined characteristic coordinates (xmod, ymod) according to Neumann boundary conditions.
+1124
+1125        will be a helper function to the ``self._transport_equation_solver()`` method.
+1126
+1127        Args:
+1128        ------
+1129            flag (int): scenario flag for the simulation the user wants to run
+1130
+1131            old_water_saturation_matrix (np.ndarray): water saturation matrix from previous iteration
+1132
+1133            new_water_saturation_matrix (np.ndarray): water saturation from current iteration
+1134
+1135            const_parameters (dict): constant parameters to help with calculations
+1136
+1137            varying_parameters (dict): parameters that vary but assist with calculations for water saturation, polymer concentration, and surfactant concentration
+1138
+1139        Returns: (tuple[np.ndarray, np.ndarray])
+1140        ---------------------------------------
+1141            This method returns ``xmod`` and ``ymod``, which are the modified characteristic coordinates according to the Neumann boundary conditions
+1142        """
+1143        assert self.water.water_saturation is not None, SimulationCalcInputException(
+1144            "SimulationCalcInputError:UnknownWaterSaturationMatrix"
+1145        )
+1146        assert (
+1147            self.surfactant.concentration_matrix is not None
+1148        ), SimulationCalcInputException(
+1149            "SimulationCalcInputError:UnknownSurfactantConcentrationMatrix"
+1150        )
+1151        x, y = (
+1152            const_parameters["FD_grid_constants"]["x"],
+1153            const_parameters["FD_grid_constants"]["y"],
+1154        )
+1155        dt_matrix = const_parameters["FD_grid_constants"]["dt_matrix"]
+1156        xjump = None
+1157        yjump = None
+1158        f = varying_parameters["fractional_flow_parameters"]["f"]
+1159        f_s = varying_parameters["fractional_flow_derivatives"]["df_ds"]
+1160        D = varying_parameters["fractional_flow_parameters"]["D"]
+1161        pc_s = varying_parameters["capillary_pressure_and_derivatives"]["dpc_ds"]
+1162        pc_g = varying_parameters["capillary_pressure_and_derivatives"]["dpc_dg"]
+1163        sold = old_water_saturation_matrix
+1164        snew = new_water_saturation_matrix
+1165
+1166        if flag == 1:
+1167            xjump = x - f_s * self.u * dt_matrix
+1168            yjump = y - f_s * self.v * dt_matrix
+1169        elif flag == 2:
+1170            # Calculate gradients
+1171            sx, sy = self._get_gradient(sold)
+1172            gx, gy = self._get_gradient(self.surfactant.concentration_matrix)
+1173
+1174            xjump = (
+1175                x
+1176                - (
+1177                    (f / snew) * self.u
+1178                    + (D * pc_s / snew) * sx
+1179                    + (D * pc_g / snew) * gx
+1180                )
+1181                * dt_matrix
+1182            )
+1183            yjump = (
+1184                y
+1185                - (
+1186                    (f / snew) * self.v
+1187                    + (D * pc_s / snew) * sy
+1188                    + (D * pc_g / snew) * gy
+1189                )
+1190                * dt_matrix
+1191            )
+1192        elif flag == 3:
+1193            sx, sy = self._get_gradient(sold)
+1194
+1195            xjump = x - ((f / snew) * self.u + (D * pc_s / snew) * sx) * dt_matrix
+1196            yjump = y - ((f / snew) * self.v + (D * pc_s / snew) * sy) * dt_matrix
+1197
+1198        # Apply Neumann reflection conditions
+1199        if xjump is None or yjump is None:
+1200            raise SimulationCalcInputException(
+1201                "SimulationInputException:UnknownXJumpYJumpMatrices"
+1202            )
+1203
+1204        xmod = np.copy(x)
+1205        ymod = np.copy(y)
+1206
+1207        for j in range(np.shape(y)[0]):
+1208            for i in range(np.shape(x)[1]):
+1209                if xjump[j, i] <= 1 and yjump[j, i] <= 1:
+1210                    xmod[j, i] = np.abs(xjump[j, i])
+1211                    ymod[j, i] = np.abs(yjump[j, i])
+1212                elif xjump[j, i] > 1 and yjump[j, i] <= 1:
+1213                    xmod[j, i] = 2 - xjump[j, i]
+1214                    ymod[j, i] = np.abs(yjump[j, i])
+1215                elif xjump[j, i] <= 1 and yjump[j, i] > 1:
+1216                    xmod[j, i] = np.abs(xjump[j, i])
+1217                    ymod[j, i] = 2 - yjump[j, i]
+1218                elif xjump[j, i] > 1 and yjump[j, i] > 1:
+1219                    xmod[j, i] = 2 - xjump[j, i]
+1220                    ymod[j, i] = 2 - yjump[j, i]
+1221
+1222        return xmod, ymod
+1223
+1224    def _export_results(self):
+1225        """
+1226        (private method)
+1227
+1228        Saves simulation sim_results to CSV files.
+1229        """
+1230        import os
+1231
+1232        os.makedirs("sim_results", exist_ok=True)
+1233
+1234        np.savetxt(f"sim_results/COC_scenario_{self.scenario_flag}.csv", self.COC, delimiter=",")
+1235        np.savetxt(f"sim_results/MFW_scenario_{self.scenario_flag}.csv", self.MFW, delimiter=",")
+1236        np.savetxt(f"sim_results/CROIP_scenario_{self.scenario_flag}.csv", self.CROIP, delimiter=",")
+1237        np.savetxt(f"sim_results/ProdRate_scenario_{self.scenario_flag}.csv", self.ProdRate, delimiter=",")
+1238        # if hasattr(self, "lambdaTcal"):
+1239        #     np.savetxt(
+1240        #         "sim_results/lambdaTcal.csv", np.array(self.lambdaTcal), delimiter=","
+1241        #     )
+1242        # if hasattr(self, "miuaTcal"):
+1243        #     np.savetxt(
+1244        #         "sim_results/miuaTcal.csv", np.array(self.miuaTcal), delimiter=","
+1245        #     )
+1246
+1247        print("Simulation sim_results exported to /sim_results/ folder.")
+1248        
+1249    def _compute_MFW(self, UU):
+1250        """
+1251        (private function)
+1252
+1253        Args:
+1254        -----
+1255            UU (np.ndarray): water saturation matrix
+1256
+1257        Returns: (np.array)
+1258        -------
+1259            list of values which are the mean finger width during each iteration.
+1260            Note: Only will run under the Rectilinear Homogenous and Rectilinear Heterogeneous simulation scenarios
+1261        """
+1262        # post processing of finger width 
+1263        interface = np.zeros((29, 1))
+1264        mean_UU_save = np.zeros((29, 29))
+1265        store_UU = 0
+1266        
+1267        # find average concentration for each Y level
+1268        iter_x = 0
+1269        iter_y = 0
+1270        iter_counter = 0
+1271        
+1272        while iter_y < 29:
+1273            while iter_x < 29:
+1274                
+1275                if UU[iter_y, iter_x] > 0.21 and UU[iter_y, iter_x] < 0.99:
+1276                    iter_counter += 1
+1277                    store_UU += UU[iter_y, iter_x]
+1278                    
+1279                iter_x += 1
+1280                
+1281            mean_UU_save.T.flat[iter_y] = store_UU / iter_counter
+1282            iter_counter = 0
+1283            store_UU = 0
+1284            iter_y += 1
+1285            iter_x = 0
+1286        
+1287        iter_y = 0
+1288        iter_x = 0
+1289        while iter_y < 29:
+1290            while iter_x < 29:
+1291                if UU[iter_y, iter_x] < mean_UU_save.T.flat[iter_y]:
+1292                    interface[iter_y, 0] = iter_x
+1293                    break
+1294                iter_x += 1
+1295                
+1296            iter_x = 0
+1297            iter_y += 1
+1298        
+1299        # find location of interface front
+1300        iter_x = 0
+1301        iter_y = 0
+1302        while iter_x < 29:
+1303            if np.mean(UU[:, iter_x]) < np.mean(mean_UU_save[:, 0]):
+1304                break
+1305            iter_x += 1
+1306        
+1307        # find presence of saturation along the mixing layer
+1308        rows = UU.shape[0]
+1309        cols = UU.shape[1]
+1310        check_concentration = np.zeros((rows, cols))
+1311        for ii in range(rows):
+1312            for jj in range(cols):
+1313                if UU[ii, jj] < mean_UU_save[0, iter_y]:
+1314                    check_concentration[ii, jj] = 1
+1315                else:
+1316                    check_concentration[ii, jj] = 0
+1317        
+1318        last = 0
+1319        counter = 0
+1320        mean_finger_width = 0
+1321        total_concentration = 0
+1322        jj = iter_x - 1
+1323        for i in range(1):
+1324            for ii in range(cols):
+1325                if check_concentration[ii, jj] == 1:
+1326                    new_last = 1
+1327                    total_concentration += 1
+1328                else:
+1329                    new_last = 0
+1330                
+1331                if (new_last == 1 and last == 0) or (new_last == 0 and last == 1):
+1332                    counter += 1
+1333                last = new_last
+1334        
+1335            old_MFW = mean_finger_width
+1336            mean_finger_width = 2 * total_concentration / (counter + 1)
+1337            mean_finger_width = np.max(mean_finger_width, old_MFW)
+1338            jj += 1
+1339            
+1340        return interface, mean_finger_width, iter_x
+1341
+1342    # Public Method of Simulation Class
+1343    def run(self):
+1344        """
+1345        Executes simulation loop.
+1346        
+1347        Raises:
+1348        ------
+1349            SimulationCalcInputException: If there is an issue with the execution of a calculation during runtime
+1350        """
+1351        assert self.water.water_saturation is not None, SimulationCalcInputException(
+1352            "SimulationCalcInputError:WaterSaturationMatrixUnavailable"
+1353        )
+1354        bool_Homogenous_and_Rectilinear = (
+1355            self.permeability_flag.value == PermeabilityType.Homogenous.value
+1356        ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+1357        bool_Heterogenous_and_Rectilinear = (
+1358            self.permeability_flag.value == PermeabilityType.Heterogenous.value
+1359        ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+1360        bool_Heterogenous_and_Quarter_Five_Spot = (
+1361            self.permeability_flag.value == PermeabilityType.Heterogenous.value
+1362        ) and (
+1363            self.reservoir_geometry.value == ResevoirGeometry.Quarter_Five_Spot.value
+1364        )
+1365        try:
+1366            ## STEP 1: initializing start time, end time, and time step
+1367            t = 0
+1368            t_cal = 0
+1369            t_stop = 500
+1370            dt = self.mesh.dx / self.source_flow_magnitude
+1371            # dt value if running under Quarter Five Spot & Heterogeneous scenario:
+1372            if bool_Heterogenous_and_Quarter_Five_Spot:
+1373                dt *= 100
+1374
+1375            ## STEP 2: Initiating the primary 'while' loop that will keep running until water shows up in production well
+1376            while(t < t_stop and self.water.water_saturation[self.mesh.n, self.mesh.m] <= 0.70):
+1377                print(f'{t},{self.water.water_saturation[self.mesh.n, self.mesh.m]}')
+1378                # while t < 1:
+1379                ## STEP 2.1: Increment time and amount of feed used:
+1380                self.integrated_inlet_flow += self.source_flow_magnitude
+1381                t += dt
+1382                ## STEP 2.2: Compute viscosities:
+1383                if (
+1384                    self.model_type.value == ModelType.No_Shear_Thinning.value
+1385                ):  # if No Polymer Shear Thinning
+1386                    self.water.compute_viscosity(
+1387                        grid=self.mesh,
+1388                        model_type=self.model_type,
+1389                        polymer=self.polymer,
+1390                        u=self.u,
+1391                        v=self.v,
+1392                    )
+1393                    self.polymer.compute_viscosity(
+1394                        grid=self.mesh,
+1395                        u=self.u,
+1396                        v=self.v,
+1397                        model_type=self.model_type,
+1398                        aqueous_viscosity=self.water.viscosity_array,
+1399                    )
+1400                elif self.model_type.value == ModelType.Shear_Thinning_On.value:
+1401                    self.polymer.compute_viscosity(
+1402                        grid=self.mesh,
+1403                        u=self.u,
+1404                        v=self.v,
+1405                        model_type=self.model_type,
+1406                        aqueous_viscosity=None,
+1407                    )
+1408                    self.water.compute_viscosity(
+1409                        grid=self.mesh,
+1410                        model_type=self.model_type,
+1411                        polymer=self.polymer,
+1412                        u=self.u,
+1413                        v=self.v,
+1414                    )
+1415                ## STEP 2.2: Computing Residual Saturation:
+1416                assert (
+1417                    self.surfactant.IFT_conc_equ is not None
+1418                ), SimulationCalcInputException(
+1419                    "SimulationCalcInputError:SurfactantIFTEquationUnavailable"
+1420                )
+1421                interfacial_tension_matrix = self.surfactant.IFT_conc_equ(
+1422                    self.surfactant.concentration_matrix
+1423                )
+1424                [resid_water_saturation, resid_oleic_saturation] = (
+1425                    self.water.compute_residual_saturations(
+1426                        sigma=interfacial_tension_matrix, u=self.u, v=self.v
+1427                    )
+1428                )
+1429                ## STEP 2.3: Compute mobilities:
+1430                assert (
+1431                    self.polymer.concentration_matrix is not None
+1432                ), SimulationCalcInputException(
+1433                    "SimulationCalcInputError:PolymerConcentrationMatrixUnavailable"
+1434                )
+1435                aqueous_mobility = self.water.compute_mobility(
+1436                    c=self.polymer.concentration_matrix,
+1437                    sor=float(resid_oleic_saturation),
+1438                    swr=float(resid_water_saturation),
+1439                    aqueous=True,
+1440                    rel_permeability_formula=self.relative_permeability_formula,
+1441                )
+1442                oleic_mobility = self.water.compute_mobility(
+1443                    c=self.polymer.concentration_matrix,
+1444                    sor=float(resid_oleic_saturation),
+1445                    swr=float(resid_water_saturation),
+1446                    aqueous=False,
+1447                    rel_permeability_formula=self.relative_permeability_formula,
+1448                )
+1449                total_mobility = aqueous_mobility + oleic_mobility
+1450                assert self.KK is not None, SimulationCalcInputException(
+1451                    "SimulationCalcInputError:PermeabilityTensorUnavailable"
+1452                )
+1453                beta = self.KK * total_mobility
+1454
+1455                ## STEP 2.4: Calculating Global Pressure and velocity
+1456                ### STEP 2.4.1: setting FEM Mesh
+1457                self.FE_mesh.set_triangulation()
+1458                self.FE_mesh.set_FE_meshgrid(beta)
+1459                self.FE_mesh.set_right_hand(self.source_prod_flow)
+1460                self.FE_mesh.get_A_B_matrices()
+1461                ### STEP 2.4.2: updating the pressure & velocity matrices
+1462                u_old = self.u  # storing old pressure matrix
+1463                v_old = self.v  # storing old velocity matrix
+1464                self.u, self.v = self._compute_pressure_and_velocity_matrices(
+1465                    self.FE_mesh.sparsed_A, self.FE_mesh.B, beta
+1466                )
+1467
+1468                ## STEP 2.5: Solving Transport Equations
+1469                ocut, wcut, ROIP = self._transport_equation_solver(dt)
+1470
+1471                ## Step 2.6: MFW post processing (excluding QFS)
+1472                if (self.scenario_flag != 3): # FIXME: compute_MFW currently operates for rectilinear geometries. Implement MFW computation for QFS
+1473                    interface, MFW_val, _ = self._compute_MFW(self.water.water_saturation)
+1474                    self.MFW.append(MFW_val)
+1475
+1476                ## STEP 2.7: Updating the cummulative oil captured, Production rate, and the residual oil in place 
+1477                # arrays for exporting to CSV files
+1478                if (t_cal == 0):
+1479                    self.COC[t_cal] = ocut
+1480                else:
+1481                    self.COC[t_cal] = self.COC[t_cal - 1] + ocut
+1482
+1483                self.ProdRate[t_cal] = ocut/dt
+1484                self.CROIP[t_cal] = ROIP
+1485
+1486                t_cal += 1
+1487
+1488            self._export_results()
+1489
+1490        except Exception as e:
+1491            print(e)
+
+ + +
+
+ +
+ + class + Simulation: + + + +
+ +
  40class Simulation:
+  41    """
+  42    Simulation class to run SP-flooding simulations based on MATLAB translation.
+  43    """
+  44
+  45    def __init__(self, user_input_dict: dict):
+  46        """
+  47        This method will check the ``user_input_dict`` and initialize the simulation
+  48        
+  49        Raises:
+  50        ------
+  51            UserInputException: If there is a issue with the user inputs in ``user_input_dict``
+  52            SimulationCalcInputException: If there is an issue with the execution of a calculation during runtime
+  53        
+  54        Args:
+  55        -----
+  56            user_input_dict (dict): dictionary containing the information from the GUI
+  57        """
+  58        ## Performs checks on the user input dictionary passed in:
+  59        try:
+  60            model_type = ModelType(user_input_dict["model_type"])
+  61            if model_type is None:
+  62                raise ValueError
+  63        except (KeyError, ValueError, TypeError):
+  64            raise UserInputException(
+  65                "UserInputError:BadModelTypeAssignment", user_input_dict
+  66            )
+  67
+  68        try:
+  69            reservoir_geometry = ResevoirGeometry(user_input_dict["reservoir_geometry"])
+  70            if reservoir_geometry is None:
+  71                raise ValueError
+  72        except (KeyError, ValueError, TypeError):
+  73            raise UserInputException(
+  74                "UserInputError:BadReservoirGeometryAssignment", user_input_dict
+  75            )
+  76
+  77        try:
+  78            permeability_flag = PermeabilityType(user_input_dict["permeability"])
+  79            if permeability_flag is None:
+  80                raise ValueError
+  81        except (KeyError, ValueError, TypeError):
+  82            raise UserInputException(
+  83                "UserInputError:BadPermeabilityAssignment", user_input_dict
+  84            )
+  85
+  86        try:
+  87            polymer_type = PolymerList.get_by_value(user_input_dict["polymer_type"])
+  88            if polymer_type is None:
+  89                raise ValueError
+  90        except (KeyError, ValueError, TypeError):
+  91            raise UserInputException(
+  92                "UserInputError:BadPolymerTypeAssignment", user_input_dict
+  93            )
+  94
+  95        try:
+  96            polymer_concentration = user_input_dict["polymer_concentration"]
+  97            if polymer_concentration is None:
+  98                raise ValueError
+  99        except (KeyError, ValueError, TypeError):
+ 100            raise UserInputException(
+ 101                "UserInputError:BadPolymerConcentrationAssignment", user_input_dict
+ 102            )
+ 103
+ 104        try:
+ 105            surfactant_type = SurfactantList.get_by_value(
+ 106                user_input_dict["surfactant_type"]
+ 107            )
+ 108            if surfactant_type is None:
+ 109                raise ValueError
+ 110        except (KeyError, ValueError, TypeError):
+ 111            raise UserInputException(
+ 112                "UserInputError:BadSurfactantTypeAssignment", user_input_dict
+ 113            )
+ 114
+ 115        try:
+ 116            surfactant_concentration = user_input_dict["surfactant_concentration"]
+ 117            if surfactant_concentration is None:
+ 118                raise ValueError
+ 119        except (KeyError, ValueError, TypeError):
+ 120            raise UserInputException(
+ 121                "UserInputError:BadSurfactantConcentrationAssignment", user_input_dict
+ 122            )
+ 123
+ 124        ## Instantiates the required simulation properties:
+ 125
+ 126        # initializing properties that hold simulation constants
+ 127        self.grid_size = SimulationConstants.Grid_Size.value
+ 128        self.source_flow_magnitude = SimulationConstants.Source_Flow_Magnitude.value
+ 129
+ 130        # Initializing Simulation Flags:
+ 131        self.permeability_flag = permeability_flag
+ 132        self.reservoir_geometry = reservoir_geometry
+ 133        self.model_type = model_type
+ 134        self.relative_permeability_formula = (
+ 135            RelativePermeabilityFormula.AmaefuleHandEquation
+ 136        )  # WILL NEED TO UPDATE TO INCLUDE IN GUI
+ 137
+ 138        # Initializing sim properties
+ 139        self.mesh, self.FE_mesh = self._create_mesh()
+ 140        grid_shape = (self.mesh.n, self.mesh.m)
+ 141        self.x, self.y = self.mesh.get_meshgrid
+ 142        self.phi = None  # FIXME: Should check if this functionality code
+ 143        self.KK = None  # Permeability tensor
+ 144        self.time_step = None
+ 145        self.u, self.v = self._initialize_pressure_and_velocity()
+ 146        self._initialize_simulation()  # will initialize phi, KK, and time_step
+ 147        if (
+ 148            self.phi is None or self.KK is None or self.time_step is None
+ 149        ):  # Raise Exception if not properly initialized...
+ 150            raise SimulationCalcInputException(
+ 151                "SimulationCalcInputError:BadInitialSimulationPropertiesCalculation"
+ 152            )
+ 153
+ 154        # Initalizing Polymer Object
+ 155        self.polymer = Polymer(
+ 156            name=polymer_type,
+ 157            e_coeff=polymer_type.e_coeff,
+ 158            n_coeff=polymer_type.n_coeff,
+ 159            rho=polymer_type.Density,
+ 160            concentration_scalar=polymer_concentration,
+ 161            phi=self.phi,
+ 162        )
+ 163        self.polymer.initialize(grid_shape=grid_shape)
+ 164
+ 165        # Initializing Surfactant Object
+ 166        self.surfactant = Surfactant(
+ 167            name=surfactant_type,
+ 168            initial_concentration=surfactant_concentration,
+ 169            IFT_equation=surfactant_type.IFT_equation,
+ 170            derivative_IFT_equation=surfactant_type.derivative_IFT_equation,
+ 171            phi=self.phi,
+ 172        )
+ 173        self.surfactant.initialize()
+ 174
+ 175        # Initializing Water Object
+ 176        self.water = Water(
+ 177            init_water_saturation=SimulationConstants.Initial_Residual_Water_Saturation.value,
+ 178            init_aqueous_saturation=SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial.value,
+ 179            init_oleic_saturation=SimulationConstants.Resid_Oleic_Phase_Saturation_Initial.value,
+ 180            miuw=SimulationConstants.Water_Viscosity.value,
+ 181            miuo=SimulationConstants.Oil_Viscosity.value,
+ 182            phi=self.phi,
+ 183        )
+ 184        self.water.initialize(grid_shape=grid_shape)
+ 185
+ 186        # Properties for Exporting Simulation Results
+ 187        self.COC = np.zeros((1, 2000))  # Cumulative Oil Recovered
+ 188        self.miuaTcal = np.zeros((1, 2000))  # Total Aqueous Viscosity
+ 189        self.lambdaTcal = np.zeros((1, 2000))  # Total Mobility (λ_o + λ_a)
+ 190
+ 191        ##The following properties require memmaps:
+ 192        self.ProdRate, self.CROIP = (
+ 193            self._initialize_memmap_properties()
+ 194        )  # ProdRate (Production Rate) / CROIP (Cummulative Remaining Oil In Place)
+ 195        self.MFW = []
+ 196        self.integrated_inlet_flow = 0  # "src_total" in the MATLAB version of the code
+ 197
+ 198    # Property of Simulation Class
+ 199    _grid_size = None
+ 200    @property
+ 201    def grid_size(self):
+ 202        """
+ 203        grid_size (float): the dimensions of the square grid
+ 204        """
+ 205        return self._grid_size
+ 206    @grid_size.setter
+ 207    def grid_size(self, value):
+ 208        self._grid_size = value
+ 209
+ 210    _source_flow_magnitude = None
+ 211    @property
+ 212    def source_flow_magnitude(self):
+ 213        """
+ 214        source_flow_magnitude (float): flow rate at injection site
+ 215        """
+ 216        return self._source_flow_magnitude
+ 217    @source_flow_magnitude.setter
+ 218    def source_flow_magnitude(self, value):
+ 219        self._source_flow_magnitude = value
+ 220
+ 221    _permeability_flag = None
+ 222    @property
+ 223    def permeability_flag(self):
+ 224        """
+ 225        permeability_flag (enum 'PermeabilityType'): sets the permeability field based on enum ``PermeabilityType``
+ 226        """
+ 227        return self._permeability_flag
+ 228    @permeability_flag.setter
+ 229    def permeability_flag(self, value):
+ 230        self._permeability_flag = value
+ 231
+ 232    _reservoir_geometry = None
+ 233    @property
+ 234    def reservoir_geometry(self):
+ 235        """
+ 236        reservoir_geometry (enum 'ResevoirGeometry'): sets the reservoir geometry based on the enum ``ResevoirGeometry``
+ 237        """
+ 238        return self._reservoir_geometry
+ 239    @reservoir_geometry.setter
+ 240    def reservoir_geometry(self, value):
+ 241        self._reservoir_geometry = value
+ 242
+ 243    _model_type = None
+ 244    @property
+ 245    def model_type(self):
+ 246        """
+ 247        model_type (enum 'ModelType'): sets the type of simulation being run based on the enum ``ModelType``
+ 248        """
+ 249        return self._model_type
+ 250    @model_type.setter
+ 251    def model_type(self, value):
+ 252        self._model_type = value
+ 253
+ 254    _relative_permeability_formula = None
+ 255    @property
+ 256    def relative_permeability_formula(self):
+ 257        """
+ 258        relative_permeability_formula (enum 'RelativePermeabilityFormula'): sets the type of permeability formula being used in the simulation, based on the enum ``RelativePermeabilityFormula``
+ 259        """
+ 260        return self._relative_permeability_formula
+ 261    @relative_permeability_formula.setter
+ 262    def relative_permeability_formula(self, value):
+ 263        self._relative_permeability_formula = value
+ 264
+ 265    _phi = None
+ 266    @property
+ 267    def phi(self):
+ 268        """
+ 269        phi (np.ndarray): porosity matrix
+ 270        """
+ 271        return self._phi
+ 272    @phi.setter
+ 273    def phi(self, value):
+ 274        self._phi = value
+ 275
+ 276    _KK = None
+ 277    @property
+ 278    def KK(self):
+ 279       """
+ 280       KK (np.ndarray): the permeability matrix
+ 281       """
+ 282       return self._KK
+ 283    @KK.setter
+ 284    def KK(self, value):
+ 285       self._KK = value
+ 286
+ 287    _time_step = None
+ 288    @property
+ 289    def time_step(self):
+ 290        """
+ 291        time_step (float): The Δt
+ 292        """
+ 293        return self._time_step
+ 294    @time_step.setter
+ 295    def time_step(self, value):
+ 296        self._time_step = value
+ 297
+ 298    _polymer = None
+ 299    @property
+ 300    def polymer(self):
+ 301        """
+ 302        polymer (Polymer): Holds the ``Polymer`` object
+ 303        """
+ 304        return self._polymer
+ 305    @polymer.setter
+ 306    def polymer(self, value):
+ 307        self._polymer = value
+ 308
+ 309    _surfactant = None
+ 310    @property
+ 311    def surfactant(self):
+ 312        """
+ 313        surfactant (Surfactant): Holds the ``Surfactant`` object
+ 314        """
+ 315        return self._surfactant
+ 316    @surfactant.setter
+ 317    def surfactant(self, value):
+ 318        self._surfactant = value
+ 319
+ 320    _water = None
+ 321    @property
+ 322    def water(self):
+ 323        """
+ 324        water (Water): Holds the ``Water`` object
+ 325        """
+ 326        return self._water
+ 327    @water.setter
+ 328    def water(self, value):
+ 329        self._water = value
+ 330
+ 331    _COC = None
+ 332    @property
+ 333    def COC(self):
+ 334        """
+ 335        COC (np.ndarray): An array that holds the cummulative oil captured
+ 336        """
+ 337        return self._COC
+ 338    @COC.setter
+ 339    def COC(self, value):
+ 340        self._COC = value
+ 341
+ 342    _miuaTcal = None
+ 343    @property
+ 344    def miuaTcal(self):
+ 345        """
+ 346        miuTcal (np.ndarray): An array that caputres the change in the total aqueous viscosity over time
+ 347        """
+ 348        return self._miuaTcal
+ 349    @miuaTcal.setter
+ 350    def miuaTcal(self, value):
+ 351        self._miuaTcal = value
+ 352
+ 353    _lambdaTcal = None
+ 354    @property
+ 355    def lambdaTcal(self):
+ 356        """
+ 357        lambdaTcal (np.ndarray): Array that holds the change in the total mobility (λ_T = λ_a + λ_o)
+ 358        """
+ 359        return self._lambdaTcal
+ 360    @lambdaTcal.setter
+ 361    def lambdaTcal(self, value):
+ 362        self._lambdaTcal = value
+ 363
+ 364    _MFW = None
+ 365    @property
+ 366    def MFW(self):
+ 367        """
+ 368        MFW (np.ndarray): Array that holds change in the MFW (mean finger width)
+ 369        """
+ 370        return self._MFW
+ 371    @MFW.setter
+ 372    def MFW(self, value):
+ 373        self._MFW = value
+ 374
+ 375    _integrated_inlet_flow = None
+ 376    @property
+ 377    def integrated_inlet_flow(self):
+ 378        """
+ 379        integrated_inlet_flow (float): Basically the integrating the source flow rate over time
+ 380        """
+ 381        return self._integrated_inlet_flow
+ 382    @integrated_inlet_flow.setter
+ 383    def integrated_inlet_flow(self, value):
+ 384        self._integrated_inlet_flow = value
+ 385
+ 386    _source_prod_flow = None
+ 387    @property
+ 388    def source_prod_flow(self):
+ 389        """
+ 390        source_prod_flow (np.ndarray): The matrix with the source & and production well flow rates
+ 391
+ 392        assuming that the source flow = production well flow (flow magnitudes are the same!)
+ 393        """
+ 394        # setting permeability state
+ 395        if self._source_prod_flow is None:
+ 396            self._source_prod_flow = np.zeros((self.mesh.n + 1, self.mesh.m + 1))
+ 397            bool_Homogenous_and_Rectilinear = (
+ 398                self.permeability_flag.value == PermeabilityType.Homogenous.value
+ 399            ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+ 400            bool_Heterogenous_and_Rectilinear = (
+ 401                self.permeability_flag.value == PermeabilityType.Heterogenous.value
+ 402            ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+ 403            bool_Heterogenous_and_Quarter_Five_Spot = (
+ 404                self.permeability_flag.value == PermeabilityType.Heterogenous.value
+ 405            ) and (
+ 406                self.reservoir_geometry.value
+ 407                == ResevoirGeometry.Quarter_Five_Spot.value
+ 408            )
+ 409            if bool_Homogenous_and_Rectilinear or bool_Heterogenous_and_Rectilinear:
+ 410                self._source_prod_flow[:, 0] = (
+ 411                    self.source_flow_magnitude
+ 412                )  # intensity of injection well = src
+ 413                self._source_prod_flow[:, -1] = (
+ 414                    -1 * self.source_flow_magnitude
+ 415                )  # intensity of production well = -src
+ 416            elif bool_Heterogenous_and_Quarter_Five_Spot:  # Quarter-Five Spot
+ 417                self._source_prod_flow[0, 0] = (
+ 418                    self.source_flow_magnitude
+ 419                )  # Intensity of injection well = src
+ 420                self._source_prod_flow[-1, -1] = (
+ 421                    -1 * self.source_flow_magnitude
+ 422                )  # Intensity of production well = -src
+ 423
+ 424        return self._source_prod_flow
+ 425
+ 426    _scenario_flag = None
+ 427    @property
+ 428    def scenario_flag(self):
+ 429        """
+ 430        Determines the scenario based on the chosen reservoir geometry and permeability.
+ 431        Returns the integer value that represents a type of scenario run
+ 432        """
+ 433        if self._scenario_flag is None:
+ 434            bool_Homogenous_and_Rectilinear = (
+ 435                self.permeability_flag.value == PermeabilityType.Homogenous.value
+ 436            ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+ 437            bool_Heterogenous_and_Rectilinear = (
+ 438                self.permeability_flag.value == PermeabilityType.Heterogenous.value
+ 439            ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+ 440            bool_Heterogenous_and_Quarter_Five_Spot = (
+ 441                self.permeability_flag.value == PermeabilityType.Heterogenous.value
+ 442            ) and (
+ 443                self.reservoir_geometry.value
+ 444                == ResevoirGeometry.Quarter_Five_Spot.value
+ 445            )
+ 446
+ 447            if bool_Homogenous_and_Rectilinear:
+ 448                self._scenario_flag = 1
+ 449            elif bool_Heterogenous_and_Rectilinear:
+ 450                self._scenario_flag = 2
+ 451            elif bool_Heterogenous_and_Quarter_Five_Spot:
+ 452                self._scenario_flag = 3
+ 453            else:
+ 454                raise SimulationCalcInputException(
+ 455                    "SimulationCalcInputError:InvalidSimulationCase"
+ 456                )
+ 457
+ 458        return self._scenario_flag
+ 459
+ 460    # Private Methods of the Simulation Class
+ 461    def _initialize_pressure_and_velocity(self):
+ 462        """
+ 463        (private method)
+ 464
+ 465        Initializing global pressure ('u') and velocity matrices ('v')
+ 466        Will use the ``n`` and ``m`` properties from ``Grid`` Class for initialization
+ 467
+ 468        Returns: (tuple[np.ndarray, np.ndarray])
+ 469        ----------------------------------------
+ 470            The global pressure matrix (index 0) and velocity matrix (index 1)
+ 471        """
+ 472        u = np.zeros((self.mesh.n + 1, self.mesh.m + 1), dtype=np.complex128)
+ 473        v = np.zeros((self.mesh.n + 1, self.mesh.m + 1), dtype=np.complex128)
+ 474
+ 475        return u, v
+ 476
+ 477    def _compute_pressure_and_velocity_matrices(self, sparsed_A, B, beta):
+ 478        """
+ 479        (private method)
+ 480
+ 481        dependent property to calculate the pressure matrix (``u``)
+ 482        and velocity matrix (``v``). Will rely on functions in the ``FEMesh`` class.
+ 483        
+ 484        Returns: (list[np.ndarray])
+ 485        ---------------------------
+ 486            List of update pressure matrix and velocity matrix => [u,v]
+ 487        """
+ 488        max_iterations = 1000
+ 489        new_u, convergence_flag = bicgstab(
+ 490            sparsed_A, B, rtol=1e-10, atol=0, maxiter=max_iterations
+ 491        )  # new_u is of shape (900, )
+ 492        if convergence_flag != 0:
+ 493            import warnings
+ 494            warnings.warn(f"BiCGSTAB: convergence issue (info={convergence_flag}) in pressure solver")
+ 495
+ 496        new_v = np.zeros((self.FE_mesh.n + 1, self.FE_mesh.m + 1), dtype=object)
+ 497        for i in range(self.FE_mesh.m + 1):
+ 498            for j in range(self.FE_mesh.n + 1):
+ 499                new_v[j, i] = new_u[j * (self.FE_mesh.m + 1) + i]
+ 500
+ 501        px, py = self._get_gradient(new_v)
+ 502        new_u = (-1 * beta) * px
+ 503        new_v = (-1 * beta) * py
+ 504
+ 505        return new_u, new_v
+ 506
+ 507    def _get_gradient(self, vn):
+ 508        """
+ 509        (private method)
+ 510
+ 511        Helper function to determine the gradients with respect to x and y dimensions
+ 512        
+ 513        Returns: (tuple[_Array[tuple[int, int], float64], NDArray[float64]])
+ 514        --------------------------------------------------------------------
+ 515            Tuple with px py which are numpy matrices that hold the gradient wrt to x and y dimensions
+ 516        """
+ 517        m = self.mesh.m
+ 518        n = self.mesh.n
+ 519
+ 520        dx = self.mesh.dx
+ 521        dy = self.mesh.dy
+ 522
+ 523        px = np.zeros((n + 1, m + 1))
+ 524        py = np.copy(px)
+ 525
+ 526        for i in range(m + 1):
+ 527            for j in range(n + 1):
+ 528                if i != 0:
+ 529                    px[j, i] = (vn[j, i] - vn[j, i - 1]) / dx
+ 530                if i != m:
+ 531                    px[j, i] = (vn[j, i + 1] - vn[j, i]) / dx
+ 532                if i != 0 and i != m:
+ 533                    px[j, i] = (vn[j, i + 1] - vn[j, i - 1]) / (2 * dx)
+ 534                if j != 0:
+ 535                    py[j, i] = (vn[j, i] - vn[j - 1, i]) / dy
+ 536                if j != n:
+ 537                    py[j, i] = (vn[j + 1, i] - vn[j, i]) / dy
+ 538                if j != 0 and j != n:
+ 539                    py[j, i] = (vn[j + 1, i] - vn[j - 1, i]) / (2 * dy)
+ 540
+ 541        return px, py
+ 542
+ 543    def _initialize_memmap_properties(self):
+ 544        """
+ 545        (private method)
+ 546
+ 547        Will initialize the ``ProdRate`` and ``CROIP`` properties.
+ 548        Using memmaps to allow window's users to run program.
+ 549        
+ 550        Returns: (tuple[np.ndarray, np.ndarray])
+ 551        ----------------------------------------
+ 552            Initialized ``ProdRate`` and ``CROIP`` properties
+ 553        """
+ 554        os.makedirs("memmaps", exist_ok=True)
+ 555        tf = 500
+ 556        dt = self.mesh.dx / self.source_flow_magnitude
+ 557        timestamps = int(np.floor(tf / dt))
+ 558        CROIP = np.memmap(
+ 559            "memmaps/CROIP.dat", dtype="float64", mode="w+", shape=(1, timestamps)
+ 560        )
+ 561        ProdRate = np.memmap(
+ 562            "memmaps/ProdRate.dat", dtype="float64", mode="w+", shape=(1, timestamps)
+ 563        )
+ 564
+ 565        return ProdRate, CROIP
+ 566
+ 567    def _create_mesh(self):
+ 568        """
+ 569        (private method)
+ 570
+ 571        Returns: (Tuple[Grid, FEMesh])
+ 572        -----------------------------
+ 573            Initialized FD and FE mesh
+ 574        """
+ 575        FD_mesh = Grid(self.grid_size, self.grid_size)
+ 576
+ 577        FE_mesh = FEMesh(self.grid_size, self.grid_size)
+ 578
+ 579        return FD_mesh, FE_mesh
+ 580
+ 581    def _initialize_simulation(self):
+ 582        """
+ 583        (private method)
+ 584
+ 585        Sets up initial reservoir fields, permeability, and time step.
+ 586
+ 587        Returns: (None)
+ 588        ---------------
+ 589            Initialized properties of simulation. Required in ``__init__`` function
+ 590        """
+ 591        self.phi = self._compute_phi()
+ 592
+ 593        # Initialize permeability matrix
+ 594        self.KK = self._compute_permeability()
+ 595
+ 596        # Calculate time step
+ 597        self.time_step = self.mesh.dx / self.source_flow_magnitude
+ 598        if (
+ 599            self.permeability_flag == PermeabilityType.Heterogenous
+ 600            and self.reservoir_geometry == ResevoirGeometry.Quarter_Five_Spot
+ 601        ):
+ 602            self.time_step *= 100
+ 603
+ 604    def _compute_phi(self):
+ 605        """
+ 606        (private method)
+ 607
+ 608        Returns: (np.ndarray)
+ 609        ---------------------
+ 610            Computes and returns the level set function phi at each grid point. 
+ 611            (Equivalent to MATLAB get_phi_test function.)
+ 612        """
+ 613        m = self.mesh.m
+ 614        n = self.mesh.n
+ 615        dx = self.mesh.dx
+ 616        dy = self.mesh.dy
+ 617        left = self.mesh.left
+ 618        bottom = self.mesh.bottom
+ 619
+ 620        jj, ii = np.meshgrid(np.arange(1, n + 2), np.arange(1, m + 2))
+ 621        x_coords = left + (ii - 1) * dx
+ 622        y_coords = bottom + (jj - 1) * dy
+ 623
+ 624        phi = self._z_func_test(x_coords, y_coords)
+ 625        return phi
+ 626
+ 627    def _z_func_test(self, x, y):
+ 628        """
+ 629        (private method)
+ 630
+ 631        Args:
+ 632        -----
+ 633            x (np.ndarry): x-dimension coordinates 
+ 634
+ 635            y (np.ndarray): y-dimension coordinate points
+ 636        
+ 637        Returns: 
+ 638        --------
+ 639            Compute and returns the initial position of the water front.
+ 640            (Equivalent to MATLAB z_func_test.)
+ 641
+ 642        """
+ 643        init_front_hs = 0.1
+ 644        bool_Homogenous_and_Rectilinear = (
+ 645            self.permeability_flag.value == PermeabilityType.Homogenous.value
+ 646        ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+ 647        bool_Heterogenous_and_Rectilinear = (
+ 648            self.permeability_flag.value == PermeabilityType.Heterogenous.value
+ 649        ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+ 650        bool_Heterogenous_and_Quarter_Five_Spot = (
+ 651            self.permeability_flag.value == PermeabilityType.Heterogenous.value
+ 652        ) and (
+ 653            self.reservoir_geometry.value == ResevoirGeometry.Quarter_Five_Spot.value
+ 654        )
+ 655        if bool_Homogenous_and_Rectilinear:
+ 656            # Homogeneous
+ 657            out = y - init_front_hs + 0.01 * np.cos(80 * np.pi * x)
+ 658        elif bool_Heterogenous_and_Rectilinear:
+ 659            # Rectilinear Heterogeneous
+ 660            out = y - init_front_hs
+ 661        elif bool_Heterogenous_and_Quarter_Five_Spot:
+ 662            # Quarter five spot
+ 663            out = np.square(x) + np.square(y) - 0.015
+ 664        else:
+ 665            out = np.zeros_like(x)
+ 666
+ 667        return out
+ 668
+ 669    def _compute_permeability(self):
+ 670        """
+ 671        (private method)
+ 672        
+ 673        Returns:
+ 674        -------
+ 675            Compute and returns the permeability matrix KK based on the ``scenario_flag``.
+ 676            (Equivalent to MATLAB KKdef function.)
+ 677        """
+ 678        bool_Homogenous_and_Rectilinear = (
+ 679            self.permeability_flag.value == PermeabilityType.Homogenous.value
+ 680        ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+ 681        bool_Heterogenous_and_Rectilinear = (
+ 682            self.permeability_flag.value == PermeabilityType.Heterogenous.value
+ 683        ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+ 684        bool_Heterogenous_and_Quarter_Five_Spot = (
+ 685            self.permeability_flag.value == PermeabilityType.Heterogenous.value
+ 686        ) and (
+ 687            self.reservoir_geometry.value == ResevoirGeometry.Quarter_Five_Spot.value
+ 688        )
+ 689        m = self.mesh.m
+ 690        KK = None
+ 691        if bool_Homogenous_and_Rectilinear:
+ 692            # Homogeneous
+ 693            Kmax = 100
+ 694            KK = Kmax * np.ones((m + 1, m + 1))
+ 695        elif bool_Heterogenous_and_Rectilinear:
+ 696            # Heterogeneous
+ 697            Kmax = 100
+ 698            KK = Kmax * (
+ 699                0.5
+ 700                * (1 - 10 ** (-7))
+ 701                * (
+ 702                    np.sin(6 * np.pi * np.cos(self.x))
+ 703                    * np.cos(4 * np.pi * np.sin(3 * self.y))
+ 704                    - 1
+ 705                )
+ 706                + 1
+ 707            )
+ 708        elif bool_Heterogenous_and_Quarter_Five_Spot:
+ 709            # Load Upper Ness formation (SPE10)
+ 710            mat_data = loadmat(
+ 711                "./lib/Resources/KK30Ness.mat"
+ 712            )  # FIXME: when using master_surf_grid need to change this path
+ 713            if "KK" not in mat_data:
+ 714                raise SimulationCalcInputException(
+ 715                    "SimulationInputException: KK matrix not found in KK30Ness.mat file."
+ 716                )
+ 717            KK = mat_data["KK"]
+ 718        return KK
+ 719
+ 720    def _transport_equation_solver(self, dt):
+ 721        """
+ 722        (Private method)
+ 723
+ 724        This method of the ``Simulation`` class will solve the transport equations
+ 725        for the surfactant concentration, polymer concentration, and water saturation
+ 726
+ 727        Based on the 'nmmoc_surf_mod_neumann.m' function within the MATLAB version
+ 728
+ 729        Note:
+ 730            dg - derivative with respect to surfactant concentration
+ 731            ds - derivative with respect to water saturation
+ 732            dc - derivative with respect to polymer concentration
+ 733
+ 734        Returns: (tuple[float, float, float])
+ 735        ----------------------------------------------------
+ 736            tuple[ocut, wcut, ROIP]
+ 737            ocut - volume of oil in the production well
+ 738            wcut - volume of water in the production well
+ 739            ROIP - residual oil in place (as a volume fraction)
+ 740        """
+ 741        # Initialize constant parameters
+ 742        const_parameters = {}
+ 743        const_parameters["inlet_total_flow"] = self.source_flow_magnitude  # G1
+ 744        const_parameters["inlet_polymer_flow"] = (
+ 745            self.polymer.concetration_scalar * self.source_flow_magnitude
+ 746        )  # G2
+ 747        const_parameters["inlet_surfactant_flow"] = (
+ 748            self.surfactant.concentration * self.source_flow_magnitude
+ 749        )  # G3
+ 750        assert self.water.water_saturation is not None, SimulationCalcInputException(
+ 751            "SimulationCalcInputError:UndefinedWaterSaturationMatrix"
+ 752        )
+ 753        n = np.shape(self.water.water_saturation)[0]
+ 754        m = np.shape(self.water.water_saturation)[1]
+ 755        const_parameters["FD_grid_constants"] = {
+ 756            "n": n,
+ 757            "m": m,
+ 758            "dx": self.mesh.dx,
+ 759            "dy": self.mesh.dy,
+ 760            "dt": dt,
+ 761            "dt_matrix": dt * np.ones((n, m)),
+ 762            "x": self.mesh.x,
+ 763            "y": self.mesh.y,
+ 764        }
+ 765        ## parameters around Pc calculations
+ 766        const_parameters["Pc_constants"] = {
+ 767            "omega1": SimulationConstants.Capillary_Pressure_Param_1.value,
+ 768            "omega2": SimulationConstants.Capillary_Pressure_Param_2.value,
+ 769        }
+ 770        ## parameters around capillary number for residual saturation calcs
+ 771        const_parameters["resid_saturation_constants"] = {
+ 772            "Nco0": 10 ** (-5),
+ 773            "Nca0": 10 ** (-5),
+ 774        }
+ 775        ## porosity parameter
+ 776        const_parameters["porosity"] = 1
+ 777
+ 778        ## Permeability
+ 779        const_parameters["KK"] = self.KK
+ 780        const_parameters["relative_permeability_formula"] = (
+ 781            self.relative_permeability_formula
+ 782        )
+ 783
+ 784        # Initialize variable parameters
+ 785        varying_parameters = {}
+ 786        ## residual water and oil saturations
+ 787        [swr, sor] = self.water.compute_residual_saturations(
+ 788            sigma=self.surfactant.eval_IFT, u=self.u, v=self.v
+ 789        )
+ 790        varying_parameters["swr"] = swr
+ 791        varying_parameters["sor"] = sor
+ 792        nsw = (self.water.water_saturation - swr) / (1 - swr)
+ 793        nso = (self.water.water_saturation - swr) / (1 - swr - sor)
+ 794        varying_parameters["nsw"] = nsw
+ 795        varying_parameters["nso"] = nso
+ 796        ## recomputing mobilities
+ 797        assert (
+ 798            self.polymer.concentration_matrix is not None
+ 799        ), SimulationCalcInputException(
+ 800            "SimulationCalcInputError:UnknownPolymerConcentrationMatrix"
+ 801        )
+ 802        lambda_a = self.water.compute_mobility(
+ 803            c=self.polymer.concentration_matrix,
+ 804            sor=float(sor),
+ 805            swr=float(swr),
+ 806            aqueous=True,
+ 807            rel_permeability_formula=self.relative_permeability_formula,
+ 808        )
+ 809        lambda_o = self.water.compute_mobility(
+ 810            c=self.polymer.concentration_matrix,
+ 811            sor=float(sor),
+ 812            swr=float(swr),
+ 813            aqueous=False,
+ 814            rel_permeability_formula=self.relative_permeability_formula,
+ 815        )
+ 816        lambda_total = lambda_a + lambda_o
+ 817        varying_parameters["mobility_parameters"] = {
+ 818            "lambda_a": lambda_a,
+ 819            "lambda_o": lambda_o,
+ 820            "lambda_total": lambda_total,
+ 821        }
+ 822        ## fractional flow calculations
+ 823        f = lambda_a / lambda_total
+ 824        assert self.KK is not None, SimulationCalcInputException(
+ 825            "SimulationCalcInputError:UnknownPermeabilityTensor"
+ 826        )
+ 827        D = self.KK * lambda_o * f
+ 828        varying_parameters["fractional_flow_parameters"] = {"f": f, "D": D}
+ 829        ## calculating dσ/dΓ
+ 830        varying_parameters["IFT_and_derivative"] = {
+ 831            "IFT": self.surfactant.eval_IFT,
+ 832            "dIFT_dg": self.surfactant.eval_dIFT_dGamma,
+ 833        }
+ 834        ## compute capillary number
+ 835        assert self.water.viscosity_array is not None, SimulationCalcInputException(
+ 836            "SimulationCalcInputError:UnknownAqueousViscosityMatrix"
+ 837        )
+ 838        nca = (
+ 839            np.sqrt(np.matmul(self.u, self.u) + np.matmul(self.v, self.v), dtype=np.complex128)
+ 840            * self.water.viscosity_array.astype(np.complex128)
+ 841            / self.surfactant.eval_IFT.astype(np.complex128)
+ 842        )
+ 843        nco = (
+ 844            np.sqrt(np.matmul(self.u, self.u) + np.matmul(self.v, self.v), dtype=np.complex128)
+ 845            * SimulationConstants.Oil_Viscosity.value
+ 846            / self.surfactant.eval_IFT
+ 847        )
+ 848        norm_nca = np.linalg.norm(nca)  # 2-norm of nca
+ 849        norm_nco = np.linalg.norm(nco)  # 2-norm of nco
+ 850        ## compute derivatives of residual saturations with respect to surfactant concentration (FIXME: Need to update when inplementing autodiff!)
+ 851        dswr_dg = np.zeros((n, m))
+ 852        dsor_dg = np.zeros((n, m))
+ 853        swr_0 = SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial.value
+ 854        sor_0 = SimulationConstants.Resid_Oleic_Phase_Saturation_Initial.value
+ 855        assert (
+ 856            self.surfactant.concentration_matrix is not None
+ 857        ), SimulationCalcInputException(
+ 858            "SimulationCalcInputError:UnknownSurfactantConcentrationMatrix"
+ 859        )
+ 860        for j in range(n):
+ 861            for i in range(m):
+ 862                if norm_nca >= const_parameters["resid_saturation_constants"]["Nca0"]:
+ 863                    dswr_dg[j, i] = -(
+ 864                        swr_0
+ 865                        * 0.1534
+ 866                        * 10.001
+ 867                        * (
+ 868                            const_parameters["resid_saturation_constants"]["Nca0"]
+ 869                            ** 0.1534
+ 870                        )
+ 871                    ) / (
+ 872                        (
+ 873                            np.sqrt((self.u[j, i] ** 2) + (self.v[j, i] ** 2))
+ 874                            * self.water.viscosity_array[j, i]
+ 875                        )
+ 876                        ** (0.1534)
+ 877                        * self.surfactant.eval_IFT[j, i] ** (0.8466)
+ 878                        * (self.surfactant.concentration_matrix[j, i] + 1) ** 2
+ 879                    )
+ 880                if norm_nco >= const_parameters["resid_saturation_constants"]["Nco0"]:
+ 881                    dsor_dg[j, i] = -(
+ 882                        sor_0
+ 883                        * 0.5213
+ 884                        * 10.001
+ 885                        * (
+ 886                            const_parameters["resid_saturation_constants"]["Nca0"]
+ 887                            ** 0.5213
+ 888                        )
+ 889                    ) / (
+ 890                        (
+ 891                            np.sqrt((self.u[j, i] ** 2) + (self.v[j, i] ** 2))
+ 892                            * self.water.viscosity_array[j, i]
+ 893                        )
+ 894                        ** (0.5213)
+ 895                        * self.surfactant.eval_IFT[j, i] ** (0.4787)
+ 896                        * (self.surfactant.concentration_matrix[j, i] + 1) ** 2
+ 897                    )
+ 898        varying_parameters["resid_saturation_derivatives"] = {
+ 899            "dswr_dg": dswr_dg,
+ 900            "dsor_dg": dsor_dg,
+ 901        }
+ 902        ## compute derivatives of normalized saturation with respect to surfactant concentration (FIXME: Need to update when inplementing autodiff!)
+ 903        varying_parameters["normalized_saturation_derivatives"] = {
+ 904            "dnsw_dg": dswr_dg * (self.water.water_saturation - 1) / (1 - swr) ** 2,
+ 905            "dnso_dg": (
+ 906                dswr_dg * (self.water.water_saturation + sor - 1)
+ 907                + dsor_dg * (self.water.water_saturation - swr)
+ 908            )
+ 909            / (1 - swr - sor) ** 2,
+ 910        }
+ 911        ## computing relative permeability with respect to surfactant concentration (FIXME: Need to update when inplementing autodiff!)
+ 912        varying_parameters["relative_permeability_derivatives"] = {
+ 913            "dkra_dg": 2.5 * dswr_dg * (nsw**3 - nsw)
+ 914            + (self.water.water_saturation - 1)
+ 915            * (2.5 * swr * (3 * nsw**2 - 1) + 1)
+ 916            * varying_parameters["normalized_saturation_derivatives"]["dnsw_dg"]
+ 917            / (1 - swr) ** 2,
+ 918            "dkro_dg": 1
+ 919            - 5 * sor * nso
+ 920            + (1 - nso) * (1 - 5 * nso * dsor_dg)
+ 921            - (1 + 5 * sor - 10 * sor * nso)
+ 922            * varying_parameters["normalized_saturation_derivatives"]["dnso_dg"],
+ 923            "dkra_ds": 2.5 * swr * (3 * (nsw) ** 2 - 1) + 1,
+ 924            "dkro_ds": 10 * sor * nso - 5 * sor - 1,
+ 925        }
+ 926        ## computing capillary pressure derivatives with respect to concentrations and saturations (FIXME: Need to update when inplementing autodiff!)
+ 927        pc = (
+ 928            self.surfactant.eval_IFT
+ 929            * const_parameters["Pc_constants"]["omega2"]
+ 930            * np.sqrt(const_parameters["porosity"])
+ 931        ) / (
+ 932            np.matmul(
+ 933                self.KK ** (0.5),
+ 934                fractional_matrix_power(
+ 935                    1 - nso, 1 / const_parameters["Pc_constants"]["omega1"]
+ 936                ),
+ 937            )
+ 938        )
+ 939        dpc_ds = pc / (const_parameters["Pc_constants"]["omega1"] * (1 - nso))
+ 940        dpc_dg = (
+ 941            pc / self.surfactant.eval_IFT
+ 942        ) * self.surfactant.eval_dIFT_dGamma + dpc_ds
+ 943        varying_parameters["capillary_pressure_and_derivatives"] = {
+ 944            "pc": pc,
+ 945            "dpc_ds": dpc_ds,
+ 946            "dpc_dg": dpc_dg,
+ 947        }
+ 948        ## computing fractional flow derivatives with respect to concentrations and saturations (FIXME: Need to update when inplementing autodiff!)
+ 949        varying_parameters["fractional_flow_derivatives"] = {
+ 950            "df_ds": varying_parameters["relative_permeability_derivatives"]["dkra_ds"]
+ 951            * lambda_o
+ 952            / (lambda_total**2 * self.water.viscosity_array)
+ 953            - varying_parameters["relative_permeability_derivatives"]["dkro_ds"]
+ 954            * lambda_a
+ 955            / (lambda_total**2 * self.water.miuo),
+ 956            "df_dc": (-1 * (lambda_o * lambda_a * self.water.miuo))
+ 957            / ((lambda_total**2) * self.water.viscosity_array),
+ 958            "df_dg": (
+ 959                (
+ 960                    varying_parameters["relative_permeability_derivatives"]["dkra_dg"]
+ 961                    * lambda_o
+ 962                )
+ 963                / ((lambda_total**2) * self.water.viscosity_array)
+ 964            )
+ 965            - (
+ 966                (
+ 967                    varying_parameters["relative_permeability_derivatives"]["dkro_dg"]
+ 968                    * lambda_a
+ 969                )
+ 970                / ((lambda_total**2) * self.water.viscosity_array)
+ 971            ),
+ 972            "dD_dg": D
+ 973            * varying_parameters["capillary_pressure_and_derivatives"]["dpc_dg"],
+ 974            "dD_ds": D
+ 975            * varying_parameters["capillary_pressure_and_derivatives"]["dpc_ds"],
+ 976        }
+ 977        # Update Water Saturation Matrix
+ 978        ## Calculate ``xmod`` and ``ymod``
+ 979        [xmod, ymod] = self._characteristic_coordinates(
+ 980            1,
+ 981            self.water.water_saturation,
+ 982            self.water.water_saturation,
+ 983            const_parameters,
+ 984            varying_parameters,
+ 985        )
+ 986
+ 987        ## Pass in parameters into ``compute_water_saturation`` method of the ``Water`` class
+ 988        Q_old = np.copy(self.water.water_saturation)
+ 989        Qmod, varying_parameters = self.water.compute_water_saturation(
+ 990            grid=self.mesh,
+ 991            surfactant=self.surfactant,
+ 992            polymer=self.polymer,
+ 993            u=self.u,
+ 994            v=self.v,
+ 995            xmod=xmod,
+ 996            ymod=ymod,
+ 997            const_parameters=const_parameters,
+ 998            varying_parameters=varying_parameters,
+ 999        )
+1000
+1001        # Update the Polymer Concentration Matrix
+1002        [xmod, ymod] = self._characteristic_coordinates(
+1003            2, Q_old, self.water.water_saturation, const_parameters, varying_parameters
+1004        )
+1005        C_old = np.copy(self.polymer.concentration_matrix)
+1006        varying_parameters = self.polymer.compute_concentration(
+1007            grid=self.mesh,
+1008            water_sat=self.water.water_saturation,
+1009            u=self.u,
+1010            v=self.v,
+1011            xmod=xmod,
+1012            ymod=ymod,
+1013            const_parameters=const_parameters,
+1014            varying_parameters=varying_parameters,
+1015        )
+1016
+1017        # Update the Surfactant Concentration matrix
+1018        [xmod, ymod] = self._characteristic_coordinates(
+1019            3, Q_old, self.water.water_saturation, const_parameters, varying_parameters
+1020        )
+1021        G_old = np.copy(self.surfactant.concentration_matrix)
+1022        G = np.copy(self.surfactant.concentration_matrix)
+1023        x1d = self.mesh.x[0, :]
+1024        y1d = self.mesh.y[:, 0]
+1025        x_sorted = np.all(np.diff(x1d) > 0)
+1026        y_sorted = np.all(np.diff(y1d) > 0)
+1027
+1028        # reorder surfactant.concentration_matrix if a dimension isn't sorted
+1029        if not x_sorted:
+1030            x_sort_idx = np.argsort(x1d)
+1031            x1d = x1d[x_sort_idx]
+1032            G = G[:, x_sort_idx]  # Sort columns of surfactant.concentration_matrix
+1033        if not y_sorted:
+1034            y_sort_idx = np.argsort(y1d)
+1035            y1d = y1d[y_sort_idx]
+1036            G = G[y_sort_idx, :]  # Sort rows of surfactant.concentration_matrix
+1037
+1038        interp = sp.interpolate.RegularGridInterpolator(
+1039            (y1d, x1d),
+1040            G,
+1041            method="linear",
+1042            bounds_error=False,
+1043            fill_value=None,
+1044        )
+1045        query_points = np.stack([ymod.ravel(), xmod.ravel()], axis=-1)
+1046        Gmod = interp(query_points).reshape(xmod.shape)
+1047
+1048        # Updating coefficients using interpolated surfactant concentration
+1049        assert self.surfactant.IFT_conc_equ is not None, SimulationCalcInputException(
+1050            "SimulationCalcInputError:UnknownIFTEquation"
+1051        )
+1052        assert (
+1053            self.surfactant.derivative_IFT_conc_equ is not None
+1054        ), SimulationCalcInputException(
+1055            "SimulationCalcInputError:UnknownDerivativeIFTEquation"
+1056        )
+1057        sigma_mod = self.surfactant.IFT_conc_equ(Gmod)
+1058        sigma_g_mod = self.surfactant.derivative_IFT_conc_equ(Gmod)
+1059        [swr, sor] = self.water.compute_residual_saturations(
+1060            sigma=sigma_mod, u=self.u, v=self.v
+1061        )
+1062        lambda_a = self.water.compute_mobility(
+1063            c=C_old,
+1064            sor=float(sor),
+1065            swr=float(swr),
+1066            aqueous=True,
+1067            rel_permeability_formula=self.relative_permeability_formula,
+1068            modified_water_saturation=Qmod,
+1069        )
+1070        lambda_o = self.water.compute_mobility(
+1071            c=C_old,
+1072            sor=float(sor),
+1073            swr=float(swr),
+1074            aqueous=False,
+1075            rel_permeability_formula=self.relative_permeability_formula,
+1076            modified_water_saturation=Qmod,
+1077        )
+1078        lambda_total = lambda_a + lambda_o
+1079        varying_parameters["mobility_parameters"] = {
+1080            "lambda_a": lambda_a,
+1081            "lambda_o": lambda_o,
+1082            "lambda_total": lambda_total,
+1083        }
+1084        f = lambda_a / lambda_total
+1085        assert self.KK is not None, SimulationCalcInputException(
+1086            "SimulationCalcInputError:UnknownPermeabilityTensor"
+1087        )
+1088        D = self.KK * lambda_o * f
+1089        varying_parameters["fractional_flow_parameters"] = {"f": f, "D": D}
+1090        dpc_ds = pc / (const_parameters["Pc_constants"]["omega1"] * (1 - nso))
+1091        dpc_dg = (pc / sigma_mod) * sigma_g_mod + dpc_ds
+1092        varying_parameters["capillary_pressure_and_derivatives"] = {
+1093            "pc": pc,
+1094            "dpc_ds": dpc_ds,
+1095            "dpc_dg": dpc_dg,
+1096        }
+1097        F = D * dpc_dg / self.water.water_saturation
+1098        varying_parameters = self.surfactant.compute_concentration(
+1099            grid=self.mesh,
+1100            water_sat=self.water.water_saturation,
+1101            const_parameters=const_parameters,
+1102            varying_parameters=varying_parameters,
+1103            F=F,
+1104            Gmod=Gmod,
+1105        )
+1106
+1107        # calculate the Oil capture, water captured, and residual oil in place
+1108        ocut = lambda_o[n, m] * self.source_flow_magnitude / lambda_total[n,m]
+1109        wcut = lambda_a[n, m] * self.source_flow_magnitude / lambda_total[n,m]
+1110        ROIP = 100*(np.sum(np.sum(1 - self.water.water_saturation)))/sum(np.ones((n*m,1)))
+1111        return ocut, wcut, ROIP
+1112
+1113    def _characteristic_coordinates(
+1114        self,
+1115        flag,
+1116        old_water_saturation_matrix,
+1117        new_water_saturation_matrix,
+1118        const_parameters,
+1119        varying_parameters,
+1120    ):
+1121        """
+1122        (private method)
+1123
+1124        Compute redefined characteristic coordinates (xmod, ymod) according to Neumann boundary conditions.
+1125
+1126        will be a helper function to the ``self._transport_equation_solver()`` method.
+1127
+1128        Args:
+1129        ------
+1130            flag (int): scenario flag for the simulation the user wants to run
+1131
+1132            old_water_saturation_matrix (np.ndarray): water saturation matrix from previous iteration
+1133
+1134            new_water_saturation_matrix (np.ndarray): water saturation from current iteration
+1135
+1136            const_parameters (dict): constant parameters to help with calculations
+1137
+1138            varying_parameters (dict): parameters that vary but assist with calculations for water saturation, polymer concentration, and surfactant concentration
+1139
+1140        Returns: (tuple[np.ndarray, np.ndarray])
+1141        ---------------------------------------
+1142            This method returns ``xmod`` and ``ymod``, which are the modified characteristic coordinates according to the Neumann boundary conditions
+1143        """
+1144        assert self.water.water_saturation is not None, SimulationCalcInputException(
+1145            "SimulationCalcInputError:UnknownWaterSaturationMatrix"
+1146        )
+1147        assert (
+1148            self.surfactant.concentration_matrix is not None
+1149        ), SimulationCalcInputException(
+1150            "SimulationCalcInputError:UnknownSurfactantConcentrationMatrix"
+1151        )
+1152        x, y = (
+1153            const_parameters["FD_grid_constants"]["x"],
+1154            const_parameters["FD_grid_constants"]["y"],
+1155        )
+1156        dt_matrix = const_parameters["FD_grid_constants"]["dt_matrix"]
+1157        xjump = None
+1158        yjump = None
+1159        f = varying_parameters["fractional_flow_parameters"]["f"]
+1160        f_s = varying_parameters["fractional_flow_derivatives"]["df_ds"]
+1161        D = varying_parameters["fractional_flow_parameters"]["D"]
+1162        pc_s = varying_parameters["capillary_pressure_and_derivatives"]["dpc_ds"]
+1163        pc_g = varying_parameters["capillary_pressure_and_derivatives"]["dpc_dg"]
+1164        sold = old_water_saturation_matrix
+1165        snew = new_water_saturation_matrix
+1166
+1167        if flag == 1:
+1168            xjump = x - f_s * self.u * dt_matrix
+1169            yjump = y - f_s * self.v * dt_matrix
+1170        elif flag == 2:
+1171            # Calculate gradients
+1172            sx, sy = self._get_gradient(sold)
+1173            gx, gy = self._get_gradient(self.surfactant.concentration_matrix)
+1174
+1175            xjump = (
+1176                x
+1177                - (
+1178                    (f / snew) * self.u
+1179                    + (D * pc_s / snew) * sx
+1180                    + (D * pc_g / snew) * gx
+1181                )
+1182                * dt_matrix
+1183            )
+1184            yjump = (
+1185                y
+1186                - (
+1187                    (f / snew) * self.v
+1188                    + (D * pc_s / snew) * sy
+1189                    + (D * pc_g / snew) * gy
+1190                )
+1191                * dt_matrix
+1192            )
+1193        elif flag == 3:
+1194            sx, sy = self._get_gradient(sold)
+1195
+1196            xjump = x - ((f / snew) * self.u + (D * pc_s / snew) * sx) * dt_matrix
+1197            yjump = y - ((f / snew) * self.v + (D * pc_s / snew) * sy) * dt_matrix
+1198
+1199        # Apply Neumann reflection conditions
+1200        if xjump is None or yjump is None:
+1201            raise SimulationCalcInputException(
+1202                "SimulationInputException:UnknownXJumpYJumpMatrices"
+1203            )
+1204
+1205        xmod = np.copy(x)
+1206        ymod = np.copy(y)
+1207
+1208        for j in range(np.shape(y)[0]):
+1209            for i in range(np.shape(x)[1]):
+1210                if xjump[j, i] <= 1 and yjump[j, i] <= 1:
+1211                    xmod[j, i] = np.abs(xjump[j, i])
+1212                    ymod[j, i] = np.abs(yjump[j, i])
+1213                elif xjump[j, i] > 1 and yjump[j, i] <= 1:
+1214                    xmod[j, i] = 2 - xjump[j, i]
+1215                    ymod[j, i] = np.abs(yjump[j, i])
+1216                elif xjump[j, i] <= 1 and yjump[j, i] > 1:
+1217                    xmod[j, i] = np.abs(xjump[j, i])
+1218                    ymod[j, i] = 2 - yjump[j, i]
+1219                elif xjump[j, i] > 1 and yjump[j, i] > 1:
+1220                    xmod[j, i] = 2 - xjump[j, i]
+1221                    ymod[j, i] = 2 - yjump[j, i]
+1222
+1223        return xmod, ymod
+1224
+1225    def _export_results(self):
+1226        """
+1227        (private method)
+1228
+1229        Saves simulation sim_results to CSV files.
+1230        """
+1231        import os
+1232
+1233        os.makedirs("sim_results", exist_ok=True)
+1234
+1235        np.savetxt(f"sim_results/COC_scenario_{self.scenario_flag}.csv", self.COC, delimiter=",")
+1236        np.savetxt(f"sim_results/MFW_scenario_{self.scenario_flag}.csv", self.MFW, delimiter=",")
+1237        np.savetxt(f"sim_results/CROIP_scenario_{self.scenario_flag}.csv", self.CROIP, delimiter=",")
+1238        np.savetxt(f"sim_results/ProdRate_scenario_{self.scenario_flag}.csv", self.ProdRate, delimiter=",")
+1239        # if hasattr(self, "lambdaTcal"):
+1240        #     np.savetxt(
+1241        #         "sim_results/lambdaTcal.csv", np.array(self.lambdaTcal), delimiter=","
+1242        #     )
+1243        # if hasattr(self, "miuaTcal"):
+1244        #     np.savetxt(
+1245        #         "sim_results/miuaTcal.csv", np.array(self.miuaTcal), delimiter=","
+1246        #     )
+1247
+1248        print("Simulation sim_results exported to /sim_results/ folder.")
+1249        
+1250    def _compute_MFW(self, UU):
+1251        """
+1252        (private function)
+1253
+1254        Args:
+1255        -----
+1256            UU (np.ndarray): water saturation matrix
+1257
+1258        Returns: (np.array)
+1259        -------
+1260            list of values which are the mean finger width during each iteration.
+1261            Note: Only will run under the Rectilinear Homogenous and Rectilinear Heterogeneous simulation scenarios
+1262        """
+1263        # post processing of finger width 
+1264        interface = np.zeros((29, 1))
+1265        mean_UU_save = np.zeros((29, 29))
+1266        store_UU = 0
+1267        
+1268        # find average concentration for each Y level
+1269        iter_x = 0
+1270        iter_y = 0
+1271        iter_counter = 0
+1272        
+1273        while iter_y < 29:
+1274            while iter_x < 29:
+1275                
+1276                if UU[iter_y, iter_x] > 0.21 and UU[iter_y, iter_x] < 0.99:
+1277                    iter_counter += 1
+1278                    store_UU += UU[iter_y, iter_x]
+1279                    
+1280                iter_x += 1
+1281                
+1282            mean_UU_save.T.flat[iter_y] = store_UU / iter_counter
+1283            iter_counter = 0
+1284            store_UU = 0
+1285            iter_y += 1
+1286            iter_x = 0
+1287        
+1288        iter_y = 0
+1289        iter_x = 0
+1290        while iter_y < 29:
+1291            while iter_x < 29:
+1292                if UU[iter_y, iter_x] < mean_UU_save.T.flat[iter_y]:
+1293                    interface[iter_y, 0] = iter_x
+1294                    break
+1295                iter_x += 1
+1296                
+1297            iter_x = 0
+1298            iter_y += 1
+1299        
+1300        # find location of interface front
+1301        iter_x = 0
+1302        iter_y = 0
+1303        while iter_x < 29:
+1304            if np.mean(UU[:, iter_x]) < np.mean(mean_UU_save[:, 0]):
+1305                break
+1306            iter_x += 1
+1307        
+1308        # find presence of saturation along the mixing layer
+1309        rows = UU.shape[0]
+1310        cols = UU.shape[1]
+1311        check_concentration = np.zeros((rows, cols))
+1312        for ii in range(rows):
+1313            for jj in range(cols):
+1314                if UU[ii, jj] < mean_UU_save[0, iter_y]:
+1315                    check_concentration[ii, jj] = 1
+1316                else:
+1317                    check_concentration[ii, jj] = 0
+1318        
+1319        last = 0
+1320        counter = 0
+1321        mean_finger_width = 0
+1322        total_concentration = 0
+1323        jj = iter_x - 1
+1324        for i in range(1):
+1325            for ii in range(cols):
+1326                if check_concentration[ii, jj] == 1:
+1327                    new_last = 1
+1328                    total_concentration += 1
+1329                else:
+1330                    new_last = 0
+1331                
+1332                if (new_last == 1 and last == 0) or (new_last == 0 and last == 1):
+1333                    counter += 1
+1334                last = new_last
+1335        
+1336            old_MFW = mean_finger_width
+1337            mean_finger_width = 2 * total_concentration / (counter + 1)
+1338            mean_finger_width = np.max(mean_finger_width, old_MFW)
+1339            jj += 1
+1340            
+1341        return interface, mean_finger_width, iter_x
+1342
+1343    # Public Method of Simulation Class
+1344    def run(self):
+1345        """
+1346        Executes simulation loop.
+1347        
+1348        Raises:
+1349        ------
+1350            SimulationCalcInputException: If there is an issue with the execution of a calculation during runtime
+1351        """
+1352        assert self.water.water_saturation is not None, SimulationCalcInputException(
+1353            "SimulationCalcInputError:WaterSaturationMatrixUnavailable"
+1354        )
+1355        bool_Homogenous_and_Rectilinear = (
+1356            self.permeability_flag.value == PermeabilityType.Homogenous.value
+1357        ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+1358        bool_Heterogenous_and_Rectilinear = (
+1359            self.permeability_flag.value == PermeabilityType.Heterogenous.value
+1360        ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+1361        bool_Heterogenous_and_Quarter_Five_Spot = (
+1362            self.permeability_flag.value == PermeabilityType.Heterogenous.value
+1363        ) and (
+1364            self.reservoir_geometry.value == ResevoirGeometry.Quarter_Five_Spot.value
+1365        )
+1366        try:
+1367            ## STEP 1: initializing start time, end time, and time step
+1368            t = 0
+1369            t_cal = 0
+1370            t_stop = 500
+1371            dt = self.mesh.dx / self.source_flow_magnitude
+1372            # dt value if running under Quarter Five Spot & Heterogeneous scenario:
+1373            if bool_Heterogenous_and_Quarter_Five_Spot:
+1374                dt *= 100
+1375
+1376            ## STEP 2: Initiating the primary 'while' loop that will keep running until water shows up in production well
+1377            while(t < t_stop and self.water.water_saturation[self.mesh.n, self.mesh.m] <= 0.70):
+1378                print(f'{t},{self.water.water_saturation[self.mesh.n, self.mesh.m]}')
+1379                # while t < 1:
+1380                ## STEP 2.1: Increment time and amount of feed used:
+1381                self.integrated_inlet_flow += self.source_flow_magnitude
+1382                t += dt
+1383                ## STEP 2.2: Compute viscosities:
+1384                if (
+1385                    self.model_type.value == ModelType.No_Shear_Thinning.value
+1386                ):  # if No Polymer Shear Thinning
+1387                    self.water.compute_viscosity(
+1388                        grid=self.mesh,
+1389                        model_type=self.model_type,
+1390                        polymer=self.polymer,
+1391                        u=self.u,
+1392                        v=self.v,
+1393                    )
+1394                    self.polymer.compute_viscosity(
+1395                        grid=self.mesh,
+1396                        u=self.u,
+1397                        v=self.v,
+1398                        model_type=self.model_type,
+1399                        aqueous_viscosity=self.water.viscosity_array,
+1400                    )
+1401                elif self.model_type.value == ModelType.Shear_Thinning_On.value:
+1402                    self.polymer.compute_viscosity(
+1403                        grid=self.mesh,
+1404                        u=self.u,
+1405                        v=self.v,
+1406                        model_type=self.model_type,
+1407                        aqueous_viscosity=None,
+1408                    )
+1409                    self.water.compute_viscosity(
+1410                        grid=self.mesh,
+1411                        model_type=self.model_type,
+1412                        polymer=self.polymer,
+1413                        u=self.u,
+1414                        v=self.v,
+1415                    )
+1416                ## STEP 2.2: Computing Residual Saturation:
+1417                assert (
+1418                    self.surfactant.IFT_conc_equ is not None
+1419                ), SimulationCalcInputException(
+1420                    "SimulationCalcInputError:SurfactantIFTEquationUnavailable"
+1421                )
+1422                interfacial_tension_matrix = self.surfactant.IFT_conc_equ(
+1423                    self.surfactant.concentration_matrix
+1424                )
+1425                [resid_water_saturation, resid_oleic_saturation] = (
+1426                    self.water.compute_residual_saturations(
+1427                        sigma=interfacial_tension_matrix, u=self.u, v=self.v
+1428                    )
+1429                )
+1430                ## STEP 2.3: Compute mobilities:
+1431                assert (
+1432                    self.polymer.concentration_matrix is not None
+1433                ), SimulationCalcInputException(
+1434                    "SimulationCalcInputError:PolymerConcentrationMatrixUnavailable"
+1435                )
+1436                aqueous_mobility = self.water.compute_mobility(
+1437                    c=self.polymer.concentration_matrix,
+1438                    sor=float(resid_oleic_saturation),
+1439                    swr=float(resid_water_saturation),
+1440                    aqueous=True,
+1441                    rel_permeability_formula=self.relative_permeability_formula,
+1442                )
+1443                oleic_mobility = self.water.compute_mobility(
+1444                    c=self.polymer.concentration_matrix,
+1445                    sor=float(resid_oleic_saturation),
+1446                    swr=float(resid_water_saturation),
+1447                    aqueous=False,
+1448                    rel_permeability_formula=self.relative_permeability_formula,
+1449                )
+1450                total_mobility = aqueous_mobility + oleic_mobility
+1451                assert self.KK is not None, SimulationCalcInputException(
+1452                    "SimulationCalcInputError:PermeabilityTensorUnavailable"
+1453                )
+1454                beta = self.KK * total_mobility
+1455
+1456                ## STEP 2.4: Calculating Global Pressure and velocity
+1457                ### STEP 2.4.1: setting FEM Mesh
+1458                self.FE_mesh.set_triangulation()
+1459                self.FE_mesh.set_FE_meshgrid(beta)
+1460                self.FE_mesh.set_right_hand(self.source_prod_flow)
+1461                self.FE_mesh.get_A_B_matrices()
+1462                ### STEP 2.4.2: updating the pressure & velocity matrices
+1463                u_old = self.u  # storing old pressure matrix
+1464                v_old = self.v  # storing old velocity matrix
+1465                self.u, self.v = self._compute_pressure_and_velocity_matrices(
+1466                    self.FE_mesh.sparsed_A, self.FE_mesh.B, beta
+1467                )
+1468
+1469                ## STEP 2.5: Solving Transport Equations
+1470                ocut, wcut, ROIP = self._transport_equation_solver(dt)
+1471
+1472                ## Step 2.6: MFW post processing (excluding QFS)
+1473                if (self.scenario_flag != 3): # FIXME: compute_MFW currently operates for rectilinear geometries. Implement MFW computation for QFS
+1474                    interface, MFW_val, _ = self._compute_MFW(self.water.water_saturation)
+1475                    self.MFW.append(MFW_val)
+1476
+1477                ## STEP 2.7: Updating the cummulative oil captured, Production rate, and the residual oil in place 
+1478                # arrays for exporting to CSV files
+1479                if (t_cal == 0):
+1480                    self.COC[t_cal] = ocut
+1481                else:
+1482                    self.COC[t_cal] = self.COC[t_cal - 1] + ocut
+1483
+1484                self.ProdRate[t_cal] = ocut/dt
+1485                self.CROIP[t_cal] = ROIP
+1486
+1487                t_cal += 1
+1488
+1489            self._export_results()
+1490
+1491        except Exception as e:
+1492            print(e)
+
+ + +

Simulation class to run SP-flooding simulations based on MATLAB translation.

+
+ + +
+ +
+ + Simulation(user_input_dict: dict) + + + +
+ +
 45    def __init__(self, user_input_dict: dict):
+ 46        """
+ 47        This method will check the ``user_input_dict`` and initialize the simulation
+ 48        
+ 49        Raises:
+ 50        ------
+ 51            UserInputException: If there is a issue with the user inputs in ``user_input_dict``
+ 52            SimulationCalcInputException: If there is an issue with the execution of a calculation during runtime
+ 53        
+ 54        Args:
+ 55        -----
+ 56            user_input_dict (dict): dictionary containing the information from the GUI
+ 57        """
+ 58        ## Performs checks on the user input dictionary passed in:
+ 59        try:
+ 60            model_type = ModelType(user_input_dict["model_type"])
+ 61            if model_type is None:
+ 62                raise ValueError
+ 63        except (KeyError, ValueError, TypeError):
+ 64            raise UserInputException(
+ 65                "UserInputError:BadModelTypeAssignment", user_input_dict
+ 66            )
+ 67
+ 68        try:
+ 69            reservoir_geometry = ResevoirGeometry(user_input_dict["reservoir_geometry"])
+ 70            if reservoir_geometry is None:
+ 71                raise ValueError
+ 72        except (KeyError, ValueError, TypeError):
+ 73            raise UserInputException(
+ 74                "UserInputError:BadReservoirGeometryAssignment", user_input_dict
+ 75            )
+ 76
+ 77        try:
+ 78            permeability_flag = PermeabilityType(user_input_dict["permeability"])
+ 79            if permeability_flag is None:
+ 80                raise ValueError
+ 81        except (KeyError, ValueError, TypeError):
+ 82            raise UserInputException(
+ 83                "UserInputError:BadPermeabilityAssignment", user_input_dict
+ 84            )
+ 85
+ 86        try:
+ 87            polymer_type = PolymerList.get_by_value(user_input_dict["polymer_type"])
+ 88            if polymer_type is None:
+ 89                raise ValueError
+ 90        except (KeyError, ValueError, TypeError):
+ 91            raise UserInputException(
+ 92                "UserInputError:BadPolymerTypeAssignment", user_input_dict
+ 93            )
+ 94
+ 95        try:
+ 96            polymer_concentration = user_input_dict["polymer_concentration"]
+ 97            if polymer_concentration is None:
+ 98                raise ValueError
+ 99        except (KeyError, ValueError, TypeError):
+100            raise UserInputException(
+101                "UserInputError:BadPolymerConcentrationAssignment", user_input_dict
+102            )
+103
+104        try:
+105            surfactant_type = SurfactantList.get_by_value(
+106                user_input_dict["surfactant_type"]
+107            )
+108            if surfactant_type is None:
+109                raise ValueError
+110        except (KeyError, ValueError, TypeError):
+111            raise UserInputException(
+112                "UserInputError:BadSurfactantTypeAssignment", user_input_dict
+113            )
+114
+115        try:
+116            surfactant_concentration = user_input_dict["surfactant_concentration"]
+117            if surfactant_concentration is None:
+118                raise ValueError
+119        except (KeyError, ValueError, TypeError):
+120            raise UserInputException(
+121                "UserInputError:BadSurfactantConcentrationAssignment", user_input_dict
+122            )
+123
+124        ## Instantiates the required simulation properties:
+125
+126        # initializing properties that hold simulation constants
+127        self.grid_size = SimulationConstants.Grid_Size.value
+128        self.source_flow_magnitude = SimulationConstants.Source_Flow_Magnitude.value
+129
+130        # Initializing Simulation Flags:
+131        self.permeability_flag = permeability_flag
+132        self.reservoir_geometry = reservoir_geometry
+133        self.model_type = model_type
+134        self.relative_permeability_formula = (
+135            RelativePermeabilityFormula.AmaefuleHandEquation
+136        )  # WILL NEED TO UPDATE TO INCLUDE IN GUI
+137
+138        # Initializing sim properties
+139        self.mesh, self.FE_mesh = self._create_mesh()
+140        grid_shape = (self.mesh.n, self.mesh.m)
+141        self.x, self.y = self.mesh.get_meshgrid
+142        self.phi = None  # FIXME: Should check if this functionality code
+143        self.KK = None  # Permeability tensor
+144        self.time_step = None
+145        self.u, self.v = self._initialize_pressure_and_velocity()
+146        self._initialize_simulation()  # will initialize phi, KK, and time_step
+147        if (
+148            self.phi is None or self.KK is None or self.time_step is None
+149        ):  # Raise Exception if not properly initialized...
+150            raise SimulationCalcInputException(
+151                "SimulationCalcInputError:BadInitialSimulationPropertiesCalculation"
+152            )
+153
+154        # Initalizing Polymer Object
+155        self.polymer = Polymer(
+156            name=polymer_type,
+157            e_coeff=polymer_type.e_coeff,
+158            n_coeff=polymer_type.n_coeff,
+159            rho=polymer_type.Density,
+160            concentration_scalar=polymer_concentration,
+161            phi=self.phi,
+162        )
+163        self.polymer.initialize(grid_shape=grid_shape)
+164
+165        # Initializing Surfactant Object
+166        self.surfactant = Surfactant(
+167            name=surfactant_type,
+168            initial_concentration=surfactant_concentration,
+169            IFT_equation=surfactant_type.IFT_equation,
+170            derivative_IFT_equation=surfactant_type.derivative_IFT_equation,
+171            phi=self.phi,
+172        )
+173        self.surfactant.initialize()
+174
+175        # Initializing Water Object
+176        self.water = Water(
+177            init_water_saturation=SimulationConstants.Initial_Residual_Water_Saturation.value,
+178            init_aqueous_saturation=SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial.value,
+179            init_oleic_saturation=SimulationConstants.Resid_Oleic_Phase_Saturation_Initial.value,
+180            miuw=SimulationConstants.Water_Viscosity.value,
+181            miuo=SimulationConstants.Oil_Viscosity.value,
+182            phi=self.phi,
+183        )
+184        self.water.initialize(grid_shape=grid_shape)
+185
+186        # Properties for Exporting Simulation Results
+187        self.COC = np.zeros((1, 2000))  # Cumulative Oil Recovered
+188        self.miuaTcal = np.zeros((1, 2000))  # Total Aqueous Viscosity
+189        self.lambdaTcal = np.zeros((1, 2000))  # Total Mobility (λ_o + λ_a)
+190
+191        ##The following properties require memmaps:
+192        self.ProdRate, self.CROIP = (
+193            self._initialize_memmap_properties()
+194        )  # ProdRate (Production Rate) / CROIP (Cummulative Remaining Oil In Place)
+195        self.MFW = []
+196        self.integrated_inlet_flow = 0  # "src_total" in the MATLAB version of the code
+
+ + +

This method will check the user_input_dict and initialize the simulation

+ +

Raises:

+ +
UserInputException: If there is a issue with the user inputs in ``user_input_dict``
+SimulationCalcInputException: If there is an issue with the execution of a calculation during runtime
+
+ +

Args:

+ +
user_input_dict (dict): dictionary containing the information from the GUI
+
+
+ + +
+
+ +
+ grid_size + + + +
+ +
200    @property
+201    def grid_size(self):
+202        """
+203        grid_size (float): the dimensions of the square grid
+204        """
+205        return self._grid_size
+
+ + +

grid_size (float): the dimensions of the square grid

+
+ + +
+
+ +
+ source_flow_magnitude + + + +
+ +
211    @property
+212    def source_flow_magnitude(self):
+213        """
+214        source_flow_magnitude (float): flow rate at injection site
+215        """
+216        return self._source_flow_magnitude
+
+ + +

source_flow_magnitude (float): flow rate at injection site

+
+ + +
+
+ +
+ permeability_flag + + + +
+ +
222    @property
+223    def permeability_flag(self):
+224        """
+225        permeability_flag (enum 'PermeabilityType'): sets the permeability field based on enum ``PermeabilityType``
+226        """
+227        return self._permeability_flag
+
+ + +

permeability_flag (enum 'PermeabilityType'): sets the permeability field based on enum PermeabilityType

+
+ + +
+
+ +
+ reservoir_geometry + + + +
+ +
233    @property
+234    def reservoir_geometry(self):
+235        """
+236        reservoir_geometry (enum 'ResevoirGeometry'): sets the reservoir geometry based on the enum ``ResevoirGeometry``
+237        """
+238        return self._reservoir_geometry
+
+ + +

reservoir_geometry (enum 'ResevoirGeometry'): sets the reservoir geometry based on the enum ResevoirGeometry

+
+ + +
+
+ +
+ model_type + + + +
+ +
244    @property
+245    def model_type(self):
+246        """
+247        model_type (enum 'ModelType'): sets the type of simulation being run based on the enum ``ModelType``
+248        """
+249        return self._model_type
+
+ + +

model_type (enum 'ModelType'): sets the type of simulation being run based on the enum ModelType

+
+ + +
+
+ +
+ relative_permeability_formula + + + +
+ +
255    @property
+256    def relative_permeability_formula(self):
+257        """
+258        relative_permeability_formula (enum 'RelativePermeabilityFormula'): sets the type of permeability formula being used in the simulation, based on the enum ``RelativePermeabilityFormula``
+259        """
+260        return self._relative_permeability_formula
+
+ + +

relative_permeability_formula (enum 'RelativePermeabilityFormula'): sets the type of permeability formula being used in the simulation, based on the enum RelativePermeabilityFormula

+
+ + +
+
+ +
+ phi + + + +
+ +
266    @property
+267    def phi(self):
+268        """
+269        phi (np.ndarray): porosity matrix
+270        """
+271        return self._phi
+
+ + +

phi (np.ndarray): porosity matrix

+
+ + +
+
+ +
+ KK + + + +
+ +
277    @property
+278    def KK(self):
+279       """
+280       KK (np.ndarray): the permeability matrix
+281       """
+282       return self._KK
+
+ + +

KK (np.ndarray): the permeability matrix

+
+ + +
+
+ +
+ time_step + + + +
+ +
288    @property
+289    def time_step(self):
+290        """
+291        time_step (float): The Δt
+292        """
+293        return self._time_step
+
+ + +

time_step (float): The Δt

+
+ + +
+
+ +
+ polymer + + + +
+ +
299    @property
+300    def polymer(self):
+301        """
+302        polymer (Polymer): Holds the ``Polymer`` object
+303        """
+304        return self._polymer
+
+ + +

polymer (Polymer): Holds the Polymer object

+
+ + +
+
+ +
+ surfactant + + + +
+ +
310    @property
+311    def surfactant(self):
+312        """
+313        surfactant (Surfactant): Holds the ``Surfactant`` object
+314        """
+315        return self._surfactant
+
+ + +

surfactant (Surfactant): Holds the Surfactant object

+
+ + +
+
+ +
+ water + + + +
+ +
321    @property
+322    def water(self):
+323        """
+324        water (Water): Holds the ``Water`` object
+325        """
+326        return self._water
+
+ + +

water (Water): Holds the Water object

+
+ + +
+
+ +
+ COC + + + +
+ +
332    @property
+333    def COC(self):
+334        """
+335        COC (np.ndarray): An array that holds the cummulative oil captured
+336        """
+337        return self._COC
+
+ + +

COC (np.ndarray): An array that holds the cummulative oil captured

+
+ + +
+
+ +
+ miuaTcal + + + +
+ +
343    @property
+344    def miuaTcal(self):
+345        """
+346        miuTcal (np.ndarray): An array that caputres the change in the total aqueous viscosity over time
+347        """
+348        return self._miuaTcal
+
+ + +

miuTcal (np.ndarray): An array that caputres the change in the total aqueous viscosity over time

+
+ + +
+
+ +
+ lambdaTcal + + + +
+ +
354    @property
+355    def lambdaTcal(self):
+356        """
+357        lambdaTcal (np.ndarray): Array that holds the change in the total mobility (λ_T = λ_a + λ_o)
+358        """
+359        return self._lambdaTcal
+
+ + +

lambdaTcal (np.ndarray): Array that holds the change in the total mobility (λ_T = λ_a + λ_o)

+
+ + +
+
+ +
+ MFW + + + +
+ +
365    @property
+366    def MFW(self):
+367        """
+368        MFW (np.ndarray): Array that holds change in the MFW (mean finger width)
+369        """
+370        return self._MFW
+
+ + +

MFW (np.ndarray): Array that holds change in the MFW (mean finger width)

+
+ + +
+
+ +
+ integrated_inlet_flow + + + +
+ +
376    @property
+377    def integrated_inlet_flow(self):
+378        """
+379        integrated_inlet_flow (float): Basically the integrating the source flow rate over time
+380        """
+381        return self._integrated_inlet_flow
+
+ + +

integrated_inlet_flow (float): Basically the integrating the source flow rate over time

+
+ + +
+
+ +
+ source_prod_flow + + + +
+ +
387    @property
+388    def source_prod_flow(self):
+389        """
+390        source_prod_flow (np.ndarray): The matrix with the source & and production well flow rates
+391
+392        assuming that the source flow = production well flow (flow magnitudes are the same!)
+393        """
+394        # setting permeability state
+395        if self._source_prod_flow is None:
+396            self._source_prod_flow = np.zeros((self.mesh.n + 1, self.mesh.m + 1))
+397            bool_Homogenous_and_Rectilinear = (
+398                self.permeability_flag.value == PermeabilityType.Homogenous.value
+399            ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+400            bool_Heterogenous_and_Rectilinear = (
+401                self.permeability_flag.value == PermeabilityType.Heterogenous.value
+402            ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+403            bool_Heterogenous_and_Quarter_Five_Spot = (
+404                self.permeability_flag.value == PermeabilityType.Heterogenous.value
+405            ) and (
+406                self.reservoir_geometry.value
+407                == ResevoirGeometry.Quarter_Five_Spot.value
+408            )
+409            if bool_Homogenous_and_Rectilinear or bool_Heterogenous_and_Rectilinear:
+410                self._source_prod_flow[:, 0] = (
+411                    self.source_flow_magnitude
+412                )  # intensity of injection well = src
+413                self._source_prod_flow[:, -1] = (
+414                    -1 * self.source_flow_magnitude
+415                )  # intensity of production well = -src
+416            elif bool_Heterogenous_and_Quarter_Five_Spot:  # Quarter-Five Spot
+417                self._source_prod_flow[0, 0] = (
+418                    self.source_flow_magnitude
+419                )  # Intensity of injection well = src
+420                self._source_prod_flow[-1, -1] = (
+421                    -1 * self.source_flow_magnitude
+422                )  # Intensity of production well = -src
+423
+424        return self._source_prod_flow
+
+ + +

source_prod_flow (np.ndarray): The matrix with the source & and production well flow rates

+ +

assuming that the source flow = production well flow (flow magnitudes are the same!)

+
+ + +
+
+ +
+ scenario_flag + + + +
+ +
427    @property
+428    def scenario_flag(self):
+429        """
+430        Determines the scenario based on the chosen reservoir geometry and permeability.
+431        Returns the integer value that represents a type of scenario run
+432        """
+433        if self._scenario_flag is None:
+434            bool_Homogenous_and_Rectilinear = (
+435                self.permeability_flag.value == PermeabilityType.Homogenous.value
+436            ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+437            bool_Heterogenous_and_Rectilinear = (
+438                self.permeability_flag.value == PermeabilityType.Heterogenous.value
+439            ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+440            bool_Heterogenous_and_Quarter_Five_Spot = (
+441                self.permeability_flag.value == PermeabilityType.Heterogenous.value
+442            ) and (
+443                self.reservoir_geometry.value
+444                == ResevoirGeometry.Quarter_Five_Spot.value
+445            )
+446
+447            if bool_Homogenous_and_Rectilinear:
+448                self._scenario_flag = 1
+449            elif bool_Heterogenous_and_Rectilinear:
+450                self._scenario_flag = 2
+451            elif bool_Heterogenous_and_Quarter_Five_Spot:
+452                self._scenario_flag = 3
+453            else:
+454                raise SimulationCalcInputException(
+455                    "SimulationCalcInputError:InvalidSimulationCase"
+456                )
+457
+458        return self._scenario_flag
+
+ + +

Determines the scenario based on the chosen reservoir geometry and permeability. +Returns the integer value that represents a type of scenario run

+
+ + +
+
+ +
+ + def + run(self): + + + +
+ +
1344    def run(self):
+1345        """
+1346        Executes simulation loop.
+1347        
+1348        Raises:
+1349        ------
+1350            SimulationCalcInputException: If there is an issue with the execution of a calculation during runtime
+1351        """
+1352        assert self.water.water_saturation is not None, SimulationCalcInputException(
+1353            "SimulationCalcInputError:WaterSaturationMatrixUnavailable"
+1354        )
+1355        bool_Homogenous_and_Rectilinear = (
+1356            self.permeability_flag.value == PermeabilityType.Homogenous.value
+1357        ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+1358        bool_Heterogenous_and_Rectilinear = (
+1359            self.permeability_flag.value == PermeabilityType.Heterogenous.value
+1360        ) and (self.reservoir_geometry.value == ResevoirGeometry.Rectilinear.value)
+1361        bool_Heterogenous_and_Quarter_Five_Spot = (
+1362            self.permeability_flag.value == PermeabilityType.Heterogenous.value
+1363        ) and (
+1364            self.reservoir_geometry.value == ResevoirGeometry.Quarter_Five_Spot.value
+1365        )
+1366        try:
+1367            ## STEP 1: initializing start time, end time, and time step
+1368            t = 0
+1369            t_cal = 0
+1370            t_stop = 500
+1371            dt = self.mesh.dx / self.source_flow_magnitude
+1372            # dt value if running under Quarter Five Spot & Heterogeneous scenario:
+1373            if bool_Heterogenous_and_Quarter_Five_Spot:
+1374                dt *= 100
+1375
+1376            ## STEP 2: Initiating the primary 'while' loop that will keep running until water shows up in production well
+1377            while(t < t_stop and self.water.water_saturation[self.mesh.n, self.mesh.m] <= 0.70):
+1378                print(f'{t},{self.water.water_saturation[self.mesh.n, self.mesh.m]}')
+1379                # while t < 1:
+1380                ## STEP 2.1: Increment time and amount of feed used:
+1381                self.integrated_inlet_flow += self.source_flow_magnitude
+1382                t += dt
+1383                ## STEP 2.2: Compute viscosities:
+1384                if (
+1385                    self.model_type.value == ModelType.No_Shear_Thinning.value
+1386                ):  # if No Polymer Shear Thinning
+1387                    self.water.compute_viscosity(
+1388                        grid=self.mesh,
+1389                        model_type=self.model_type,
+1390                        polymer=self.polymer,
+1391                        u=self.u,
+1392                        v=self.v,
+1393                    )
+1394                    self.polymer.compute_viscosity(
+1395                        grid=self.mesh,
+1396                        u=self.u,
+1397                        v=self.v,
+1398                        model_type=self.model_type,
+1399                        aqueous_viscosity=self.water.viscosity_array,
+1400                    )
+1401                elif self.model_type.value == ModelType.Shear_Thinning_On.value:
+1402                    self.polymer.compute_viscosity(
+1403                        grid=self.mesh,
+1404                        u=self.u,
+1405                        v=self.v,
+1406                        model_type=self.model_type,
+1407                        aqueous_viscosity=None,
+1408                    )
+1409                    self.water.compute_viscosity(
+1410                        grid=self.mesh,
+1411                        model_type=self.model_type,
+1412                        polymer=self.polymer,
+1413                        u=self.u,
+1414                        v=self.v,
+1415                    )
+1416                ## STEP 2.2: Computing Residual Saturation:
+1417                assert (
+1418                    self.surfactant.IFT_conc_equ is not None
+1419                ), SimulationCalcInputException(
+1420                    "SimulationCalcInputError:SurfactantIFTEquationUnavailable"
+1421                )
+1422                interfacial_tension_matrix = self.surfactant.IFT_conc_equ(
+1423                    self.surfactant.concentration_matrix
+1424                )
+1425                [resid_water_saturation, resid_oleic_saturation] = (
+1426                    self.water.compute_residual_saturations(
+1427                        sigma=interfacial_tension_matrix, u=self.u, v=self.v
+1428                    )
+1429                )
+1430                ## STEP 2.3: Compute mobilities:
+1431                assert (
+1432                    self.polymer.concentration_matrix is not None
+1433                ), SimulationCalcInputException(
+1434                    "SimulationCalcInputError:PolymerConcentrationMatrixUnavailable"
+1435                )
+1436                aqueous_mobility = self.water.compute_mobility(
+1437                    c=self.polymer.concentration_matrix,
+1438                    sor=float(resid_oleic_saturation),
+1439                    swr=float(resid_water_saturation),
+1440                    aqueous=True,
+1441                    rel_permeability_formula=self.relative_permeability_formula,
+1442                )
+1443                oleic_mobility = self.water.compute_mobility(
+1444                    c=self.polymer.concentration_matrix,
+1445                    sor=float(resid_oleic_saturation),
+1446                    swr=float(resid_water_saturation),
+1447                    aqueous=False,
+1448                    rel_permeability_formula=self.relative_permeability_formula,
+1449                )
+1450                total_mobility = aqueous_mobility + oleic_mobility
+1451                assert self.KK is not None, SimulationCalcInputException(
+1452                    "SimulationCalcInputError:PermeabilityTensorUnavailable"
+1453                )
+1454                beta = self.KK * total_mobility
+1455
+1456                ## STEP 2.4: Calculating Global Pressure and velocity
+1457                ### STEP 2.4.1: setting FEM Mesh
+1458                self.FE_mesh.set_triangulation()
+1459                self.FE_mesh.set_FE_meshgrid(beta)
+1460                self.FE_mesh.set_right_hand(self.source_prod_flow)
+1461                self.FE_mesh.get_A_B_matrices()
+1462                ### STEP 2.4.2: updating the pressure & velocity matrices
+1463                u_old = self.u  # storing old pressure matrix
+1464                v_old = self.v  # storing old velocity matrix
+1465                self.u, self.v = self._compute_pressure_and_velocity_matrices(
+1466                    self.FE_mesh.sparsed_A, self.FE_mesh.B, beta
+1467                )
+1468
+1469                ## STEP 2.5: Solving Transport Equations
+1470                ocut, wcut, ROIP = self._transport_equation_solver(dt)
+1471
+1472                ## Step 2.6: MFW post processing (excluding QFS)
+1473                if (self.scenario_flag != 3): # FIXME: compute_MFW currently operates for rectilinear geometries. Implement MFW computation for QFS
+1474                    interface, MFW_val, _ = self._compute_MFW(self.water.water_saturation)
+1475                    self.MFW.append(MFW_val)
+1476
+1477                ## STEP 2.7: Updating the cummulative oil captured, Production rate, and the residual oil in place 
+1478                # arrays for exporting to CSV files
+1479                if (t_cal == 0):
+1480                    self.COC[t_cal] = ocut
+1481                else:
+1482                    self.COC[t_cal] = self.COC[t_cal - 1] + ocut
+1483
+1484                self.ProdRate[t_cal] = ocut/dt
+1485                self.CROIP[t_cal] = ROIP
+1486
+1487                t_cal += 1
+1488
+1489            self._export_results()
+1490
+1491        except Exception as e:
+1492            print(e)
+
+ + +

Executes simulation loop.

+ +

Raises:

+ +
SimulationCalcInputException: If there is an issue with the execution of a calculation during runtime
+
+
+ + +
+
+
+ + \ No newline at end of file diff --git a/docs/lib/surfactant.html b/docs/lib/surfactant.html new file mode 100644 index 0000000..48ba42c --- /dev/null +++ b/docs/lib/surfactant.html @@ -0,0 +1,1491 @@ + + + + + + + lib.surfactant API documentation + + + + + + + + + +
+
+

+lib.surfactant

+ +

This python script contains the class definition for surfactants for the surfactant-flooding model

+ +

The methods of this class were derived from the MATLAB Surfactant-Polymer Flooding Code developed by +Sourav Dutta and Rohit Mishra.

+ +

@author: Bhargav Akula Ramesh Kumar, Carlos Acosta Caripo

+
+ + + + + +
  1"""
+  2This python script contains the class definition for surfactants for the surfactant-flooding model
+  3
+  4The methods of this class were derived from the MATLAB Surfactant-Polymer Flooding Code developed by
+  5Sourav Dutta and Rohit Mishra.
+  6
+  7@author: Bhargav Akula Ramesh Kumar, Carlos Acosta Caripo
+  8"""
+  9
+ 10from types import LambdaType
+ 11import numpy as np
+ 12from scipy.sparse.linalg import bicgstab
+ 13from .enumerations import  SurfactantList
+ 14from .grid import Grid
+ 15from .Exceptions import SimulationCalcInputException
+ 16
+ 17
+ 18class Surfactant:
+ 19    """
+ 20    Contains property and calculations related to the surfactant object
+ 21    """
+ 22
+ 23    def __init__(
+ 24        self,
+ 25        name: SurfactantList,
+ 26        initial_concentration: float,
+ 27        phi: np.ndarray,
+ 28        IFT_equation: LambdaType | None = None,
+ 29        derivative_IFT_equation: (
+ 30            LambdaType | None
+ 31        ) = None,  # FIXME: can remove once implemented `autodiff` capabilities
+ 32        concentration_matrix: np.ndarray | None = None,
+ 33    ):
+ 34        """
+ 35        Creates instance of Surfactant class
+ 36        """
+ 37        self.name = name
+ 38        self.concentration = initial_concentration
+ 39        self.concentration_matrix = concentration_matrix
+ 40        self.IFT_conc_equ = IFT_equation
+ 41        self.derivative_IFT_conc_equ = derivative_IFT_equation  # FIXME: need to adjust when implementing 'autodiff'
+ 42        self.is_surfactant = True if (initial_concentration > 0) else False
+ 43        self.phi = phi
+ 44
+ 45    #CLASS PROPERTIES
+ 46    @property
+ 47    def eval_IFT(self):
+ 48        """
+ 49        evaluate IFT at a given surfactant concentration_matrix
+ 50        """
+ 51        assert self.IFT_conc_equ is not None, SimulationCalcInputException(
+ 52            "SimulationCalcInputError:UnknownIFTEquation"
+ 53        )
+ 54        return self.IFT_conc_equ(self.concentration_matrix)
+ 55
+ 56    @property
+ 57    def eval_dIFT_dGamma(self):  # FIXME: Need to adjust when implementing 'autodiff'
+ 58        """
+ 59        evaluate the dσ/dΓ at a particular surfactant concentration matrix
+ 60        """
+ 61        assert self.derivative_IFT_conc_equ is not None, SimulationCalcInputException(
+ 62            "SimulationCalcInputError:UnknownDerivativeIFTEquation"
+ 63        )
+ 64        return self.derivative_IFT_conc_equ(self.concentration_matrix)
+ 65
+ 66    _name = None
+ 67    @property
+ 68    def name(self):
+ 69        """
+ 70        name (enum 'SurfactantList'): Name of the surfactant
+ 71        """
+ 72        return self._name
+ 73    @name.setter
+ 74    def name(self, value):
+ 75        self._name = value
+ 76    
+ 77    _concentration = None
+ 78    @property
+ 79    def concentration(self):
+ 80        """
+ 81        concentration (float): Initial concentration of surfactant (scalar quantity)
+ 82        """
+ 83        return self._concentration
+ 84    @concentration.setter
+ 85    def concentration(self, value):
+ 86        self._concentration = value
+ 87
+ 88    _concentration_matrix = None
+ 89    @property
+ 90    def concentration_matrix(self):
+ 91        """
+ 92        concentration_matrix (np.ndarray, None): vector representation of surfactant concentration in resevoir
+ 93        """
+ 94        return self._concentration_matrix
+ 95    @concentration_matrix.setter
+ 96    def concentration_matrix(self, value):
+ 97        self._concentration_matrix = value
+ 98
+ 99    _IFT_conc_equ = None
+100    @property
+101    def IFT_conc_equ(self):
+102        """
+103        IFT_conc_equ (lambda, None): expression that relates surfactant concentration to interfacial tension b/t oil and water
+104        """
+105        return self._IFT_conc_equ
+106    @IFT_conc_equ.setter
+107    def IFT_conc_equ(self, value):
+108        self._IFT_conc_equ = value
+109
+110    _derivative_IFT_conc_equ = None
+111    @property
+112    def derivative_IFT_conc_equ(self):
+113        """
+114        derivative_IFT_conc_equ (lambda, None): Deriviative of the equation relating IFT to surfactant concentration
+115        """
+116        return self._derivative_IFT_conc_equ
+117    @derivative_IFT_conc_equ.setter
+118    def derivative_IFT_conc_equ(self, value):
+119        self._derivative_IFT_conc_equ = value
+120
+121    _is_surfactant = None
+122    @property
+123    def is_surfactant(self):
+124        """
+125        flag for whether or not surfactant is in the simulation
+126        """
+127        return self._is_surfactant
+128    @is_surfactant.setter
+129    def is_surfactant(self, value):
+130        self._is_surfactant = value
+131
+132    _phi = None
+133    @property
+134    def phi(self):
+135        """
+136        phi (np.ndarray): arrray used to initialize the concentration matrix (represents porosity of the resevoir)
+137        """
+138        return self._phi
+139    @phi.setter
+140    def phi(self, value):
+141        self._phi = value
+142
+143    def initialize(
+144        self,
+145    ):
+146        """
+147        This function will initialize the surfactant object
+148        
+149        Returns: (Surfactant)
+150            Surfactant object
+151        """
+152        if self.concentration_matrix is None:
+153            if self.phi is None:
+154                raise SimulationCalcInputException(
+155                    "SimulationInputException: phi value not initalized..."
+156                )
+157            D = (self.phi > 1e-10) + (np.abs(self.phi) < 1e-10)
+158            self.concentration_matrix = (~D) * self.concentration
+159        return self
+160
+161    def compute_concentration(
+162        self,
+163        grid: Grid,
+164        water_sat: np.ndarray,
+165        const_parameters: dict,
+166        varying_parameters: dict,
+167        F: np.ndarray,
+168        Gmod: np.ndarray,
+169    ):
+170        """
+171        Computing the surfactant concentration matrix
+172
+173        Raises:
+174            SimulationCalcInputException: Not all required inputs were provided
+175
+176        Args:
+177            grid (Grid): FD mesh
+178
+179            water_sat (np.ndarray): water saturation matrix
+180
+181            const_parameters (dict): dictionary object with constant parameters used in calculation
+182
+183            varying_parameters (dict): dictionary object with varying parameters used in calculation
+184
+185            F (np.ndarray): intermediate matrix used in calcs
+186
+187            Gmod (np.ndarray): bilinear interpolant for sur conc on redefined coordinates
+188
+189        Returns: (dict)
+190            Returns the ``varying_parameters`` dict
+191        """
+192        # initializing constants
+193        assert self.concentration_matrix is not None, SimulationCalcInputException(
+194            "SimuationInputException: polymer concentration matrix not initialized. Please try again"
+195        )
+196        # Required constants:
+197        dx = const_parameters["FD_grid_constants"]["dx"]
+198        dy = const_parameters["FD_grid_constants"]["dy"]
+199        x = const_parameters["FD_grid_constants"]["x"]
+200        y = const_parameters["FD_grid_constants"]["y"]
+201        m = const_parameters["FD_grid_constants"]["m"]
+202        n = const_parameters["FD_grid_constants"]["n"]
+203        phi = self.phi
+204        omega1 = const_parameters["Pc_constants"]["omega1"]
+205        omega2 = const_parameters["Pc_constants"]["omega2"]
+206        Qnew = water_sat
+207        g1 = const_parameters["inlet_total_flow"]
+208        g3 = const_parameters["inlet_surfactant_flow"]
+209        KK = const_parameters["KK"]
+210        relative_permeability_formula = const_parameters[
+211            "relative_permeability_formula"
+212        ]
+213
+214        # retrieving relevant parameters for updating the water saturation
+215        ## Time Step:
+216        dt = const_parameters["FD_grid_constants"]["dt"]
+217        dt_array = const_parameters["FD_grid_constants"]["dt_matrix"]
+218
+219        pc_g = varying_parameters["capillary_pressure_and_derivatives"]["dpc_dg"]
+220        lambda_a = varying_parameters["mobility_parameters"]["lambda_a"]
+221        lambda_total = varying_parameters["mobility_parameters"]["lambda_total"]
+222
+223        # intermediate parameters for code:
+224        idx = 1
+225        AAA = np.zeros((n * m, n * m))
+226        DDD = np.zeros((n * m, 1))
+227
+228        while idx <= (m) * (n - 1) + 1:
+229            cnt = (idx - 1) // m  # cnt = 0, 1, 2, ... for idx = 1, m+1, 2m+1, 3m+1, ...
+230            BB = np.zeros((n, m))
+231            AA = np.copy(BB)
+232            CC = np.copy(BB)
+233            DD = np.zeros((m, 1))
+234            for i in range(m):
+235                for j in range(n):
+236                    if j == i:
+237                        if idx == 1:
+238                            if i == 0:
+239                                DD[i] = (
+240                                    g3 / Qnew[cnt][i] + Gmod[cnt][i] / dt_array[cnt][i]
+241                                )
+242                                CC[j][i] = 2 * F[cnt][i] / (dy**2)
+243                                BB[j][i] = (
+244                                    1 / dt_array[cnt][i]
+245                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+246                                    + g1 / Qnew[cnt][i]
+247                                )
+248                                BB[j][i + 1] = 2 * F[cnt][i] / (dx**2)
+249                            elif i == m - 1:  # Bottom right point
+250                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+251                                CC[j][i] = 2 * F[cnt][i] / (dy**2)
+252                                BB[j][i] = (
+253                                    1 / dt_array[cnt][i]
+254                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+255                                )
+256                                BB[j][i - 1] = 2 * F[cnt][i] / (dx**2)
+257                            else:
+258                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+259                                CC[j][i] = 2 * F[cnt][i] / (dy**2)
+260                                BB[j][i] = (
+261                                    1 / dt_array[cnt][i]
+262                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+263                                )
+264                                BB[j][i - 1] = F[cnt][i] / (dx**2)
+265                                BB[j][i + 1] = F[cnt][i] / (dx**2)
+266                        elif idx == (m) * (n - 1) + 1:
+267                            if i == 0:
+268                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+269                                AA[j][i] = 2 * F[cnt][i] / (dy**2)
+270                                BB[j][i] = (
+271                                    1 / dt_array[cnt][i]
+272                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+273                                    + g1 / Qnew[cnt][i]
+274                                )
+275                                BB[j][i + 1] = 2 * F[cnt][i] / (dx**2)
+276                            elif i == m - 1:
+277                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+278                                AA[j][i] = 2 * F[cnt][i] / (dy**2)
+279                                BB[j][i] = (
+280                                    1 / dt_array[cnt][i]
+281                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+282                                    - ((g1 * lambda_a[cnt][i]) / (lambda_total[cnt][i]))
+283                                    / Qnew[cnt][i]
+284                                    + ((g3 * lambda_a[cnt][i]) / (lambda_total[cnt][i]))
+285                                    / (Qnew[cnt][i] * self.concentration)
+286                                )
+287                                BB[j][i - 1] = 2 * F[cnt][i] / (dx**2)
+288                            else:
+289                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+290                                AA[j][i] = 2 * F[cnt][i] / (dy**2)
+291                                BB[j][i + 1] = F[cnt][i] / (dx**2)
+292                                BB[j][i] = (
+293                                    1 / dt_array[cnt][i]
+294                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+295                                )
+296                                BB[j][i - 1] = F[cnt][i] / (dx**2)
+297                        else:
+298                            if i == 0:
+299                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+300                                AA[j][i] = F[cnt][i] / (dy**2)
+301                                BB[j][i] = (
+302                                    1 / dt_array[cnt][i]
+303                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+304                                )
+305                                BB[j][i + 1] = 2 * F[cnt][i] / (dx**2)
+306                                CC[j][i] = F[cnt][i] / (dy**2)
+307                            elif i == m - 1:
+308                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+309                                AA[j][i] = F[cnt][i] / (dy**2)
+310                                BB[j][i] = (
+311                                    1 / dt_array[cnt][i]
+312                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+313                                )
+314                                BB[j][i - 1] = 2 * F[cnt][i] / (dx**2)
+315                                CC[j][i] = F[cnt][i] / (dy**2)
+316                            else:
+317                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+318                                AA[j][i] = F[cnt][i] / (dy**2)
+319                                BB[j][i] = (
+320                                    1 / dt_array[cnt][i]
+321                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+322                                )
+323                                BB[j][i - 1] = F[cnt][i] / (dx**2)
+324                                BB[j][i + 1] = F[cnt][i] / (dx**2)
+325                                CC[j][i] = F[cnt][i] / (dy**2)
+326            if cnt == 0:
+327                AAA[:n, : 2 * m] = np.hstack([BB, CC])
+328            elif cnt == n - 1:
+329                AAA[(m - 1) * n : m * n, (n - 2) * m : n * m] = np.hstack([AA, BB])
+330            else:
+331                AAA[cnt * n : (cnt + 1) * n, (cnt - 1) * m : (cnt + 2) * m] = np.hstack(
+332                    [AA, BB, CC]
+333                )
+334
+335            DDD[cnt * m : (cnt + 1) * m] = DD
+336            idx += m
+337
+338        Gnew_flat, info = bicgstab(AAA, DDD, rtol=10 ** (-10), maxiter=600)
+339        Gnew = Gnew_flat.reshape(m, n)
+340
+341        self.concentration_matrix = Gnew
+342
+343        return varying_parameters
+
+ + +
+
+ +
+ + class + Surfactant: + + + +
+ +
 19class Surfactant:
+ 20    """
+ 21    Contains property and calculations related to the surfactant object
+ 22    """
+ 23
+ 24    def __init__(
+ 25        self,
+ 26        name: SurfactantList,
+ 27        initial_concentration: float,
+ 28        phi: np.ndarray,
+ 29        IFT_equation: LambdaType | None = None,
+ 30        derivative_IFT_equation: (
+ 31            LambdaType | None
+ 32        ) = None,  # FIXME: can remove once implemented `autodiff` capabilities
+ 33        concentration_matrix: np.ndarray | None = None,
+ 34    ):
+ 35        """
+ 36        Creates instance of Surfactant class
+ 37        """
+ 38        self.name = name
+ 39        self.concentration = initial_concentration
+ 40        self.concentration_matrix = concentration_matrix
+ 41        self.IFT_conc_equ = IFT_equation
+ 42        self.derivative_IFT_conc_equ = derivative_IFT_equation  # FIXME: need to adjust when implementing 'autodiff'
+ 43        self.is_surfactant = True if (initial_concentration > 0) else False
+ 44        self.phi = phi
+ 45
+ 46    #CLASS PROPERTIES
+ 47    @property
+ 48    def eval_IFT(self):
+ 49        """
+ 50        evaluate IFT at a given surfactant concentration_matrix
+ 51        """
+ 52        assert self.IFT_conc_equ is not None, SimulationCalcInputException(
+ 53            "SimulationCalcInputError:UnknownIFTEquation"
+ 54        )
+ 55        return self.IFT_conc_equ(self.concentration_matrix)
+ 56
+ 57    @property
+ 58    def eval_dIFT_dGamma(self):  # FIXME: Need to adjust when implementing 'autodiff'
+ 59        """
+ 60        evaluate the dσ/dΓ at a particular surfactant concentration matrix
+ 61        """
+ 62        assert self.derivative_IFT_conc_equ is not None, SimulationCalcInputException(
+ 63            "SimulationCalcInputError:UnknownDerivativeIFTEquation"
+ 64        )
+ 65        return self.derivative_IFT_conc_equ(self.concentration_matrix)
+ 66
+ 67    _name = None
+ 68    @property
+ 69    def name(self):
+ 70        """
+ 71        name (enum 'SurfactantList'): Name of the surfactant
+ 72        """
+ 73        return self._name
+ 74    @name.setter
+ 75    def name(self, value):
+ 76        self._name = value
+ 77    
+ 78    _concentration = None
+ 79    @property
+ 80    def concentration(self):
+ 81        """
+ 82        concentration (float): Initial concentration of surfactant (scalar quantity)
+ 83        """
+ 84        return self._concentration
+ 85    @concentration.setter
+ 86    def concentration(self, value):
+ 87        self._concentration = value
+ 88
+ 89    _concentration_matrix = None
+ 90    @property
+ 91    def concentration_matrix(self):
+ 92        """
+ 93        concentration_matrix (np.ndarray, None): vector representation of surfactant concentration in resevoir
+ 94        """
+ 95        return self._concentration_matrix
+ 96    @concentration_matrix.setter
+ 97    def concentration_matrix(self, value):
+ 98        self._concentration_matrix = value
+ 99
+100    _IFT_conc_equ = None
+101    @property
+102    def IFT_conc_equ(self):
+103        """
+104        IFT_conc_equ (lambda, None): expression that relates surfactant concentration to interfacial tension b/t oil and water
+105        """
+106        return self._IFT_conc_equ
+107    @IFT_conc_equ.setter
+108    def IFT_conc_equ(self, value):
+109        self._IFT_conc_equ = value
+110
+111    _derivative_IFT_conc_equ = None
+112    @property
+113    def derivative_IFT_conc_equ(self):
+114        """
+115        derivative_IFT_conc_equ (lambda, None): Deriviative of the equation relating IFT to surfactant concentration
+116        """
+117        return self._derivative_IFT_conc_equ
+118    @derivative_IFT_conc_equ.setter
+119    def derivative_IFT_conc_equ(self, value):
+120        self._derivative_IFT_conc_equ = value
+121
+122    _is_surfactant = None
+123    @property
+124    def is_surfactant(self):
+125        """
+126        flag for whether or not surfactant is in the simulation
+127        """
+128        return self._is_surfactant
+129    @is_surfactant.setter
+130    def is_surfactant(self, value):
+131        self._is_surfactant = value
+132
+133    _phi = None
+134    @property
+135    def phi(self):
+136        """
+137        phi (np.ndarray): arrray used to initialize the concentration matrix (represents porosity of the resevoir)
+138        """
+139        return self._phi
+140    @phi.setter
+141    def phi(self, value):
+142        self._phi = value
+143
+144    def initialize(
+145        self,
+146    ):
+147        """
+148        This function will initialize the surfactant object
+149        
+150        Returns: (Surfactant)
+151            Surfactant object
+152        """
+153        if self.concentration_matrix is None:
+154            if self.phi is None:
+155                raise SimulationCalcInputException(
+156                    "SimulationInputException: phi value not initalized..."
+157                )
+158            D = (self.phi > 1e-10) + (np.abs(self.phi) < 1e-10)
+159            self.concentration_matrix = (~D) * self.concentration
+160        return self
+161
+162    def compute_concentration(
+163        self,
+164        grid: Grid,
+165        water_sat: np.ndarray,
+166        const_parameters: dict,
+167        varying_parameters: dict,
+168        F: np.ndarray,
+169        Gmod: np.ndarray,
+170    ):
+171        """
+172        Computing the surfactant concentration matrix
+173
+174        Raises:
+175            SimulationCalcInputException: Not all required inputs were provided
+176
+177        Args:
+178            grid (Grid): FD mesh
+179
+180            water_sat (np.ndarray): water saturation matrix
+181
+182            const_parameters (dict): dictionary object with constant parameters used in calculation
+183
+184            varying_parameters (dict): dictionary object with varying parameters used in calculation
+185
+186            F (np.ndarray): intermediate matrix used in calcs
+187
+188            Gmod (np.ndarray): bilinear interpolant for sur conc on redefined coordinates
+189
+190        Returns: (dict)
+191            Returns the ``varying_parameters`` dict
+192        """
+193        # initializing constants
+194        assert self.concentration_matrix is not None, SimulationCalcInputException(
+195            "SimuationInputException: polymer concentration matrix not initialized. Please try again"
+196        )
+197        # Required constants:
+198        dx = const_parameters["FD_grid_constants"]["dx"]
+199        dy = const_parameters["FD_grid_constants"]["dy"]
+200        x = const_parameters["FD_grid_constants"]["x"]
+201        y = const_parameters["FD_grid_constants"]["y"]
+202        m = const_parameters["FD_grid_constants"]["m"]
+203        n = const_parameters["FD_grid_constants"]["n"]
+204        phi = self.phi
+205        omega1 = const_parameters["Pc_constants"]["omega1"]
+206        omega2 = const_parameters["Pc_constants"]["omega2"]
+207        Qnew = water_sat
+208        g1 = const_parameters["inlet_total_flow"]
+209        g3 = const_parameters["inlet_surfactant_flow"]
+210        KK = const_parameters["KK"]
+211        relative_permeability_formula = const_parameters[
+212            "relative_permeability_formula"
+213        ]
+214
+215        # retrieving relevant parameters for updating the water saturation
+216        ## Time Step:
+217        dt = const_parameters["FD_grid_constants"]["dt"]
+218        dt_array = const_parameters["FD_grid_constants"]["dt_matrix"]
+219
+220        pc_g = varying_parameters["capillary_pressure_and_derivatives"]["dpc_dg"]
+221        lambda_a = varying_parameters["mobility_parameters"]["lambda_a"]
+222        lambda_total = varying_parameters["mobility_parameters"]["lambda_total"]
+223
+224        # intermediate parameters for code:
+225        idx = 1
+226        AAA = np.zeros((n * m, n * m))
+227        DDD = np.zeros((n * m, 1))
+228
+229        while idx <= (m) * (n - 1) + 1:
+230            cnt = (idx - 1) // m  # cnt = 0, 1, 2, ... for idx = 1, m+1, 2m+1, 3m+1, ...
+231            BB = np.zeros((n, m))
+232            AA = np.copy(BB)
+233            CC = np.copy(BB)
+234            DD = np.zeros((m, 1))
+235            for i in range(m):
+236                for j in range(n):
+237                    if j == i:
+238                        if idx == 1:
+239                            if i == 0:
+240                                DD[i] = (
+241                                    g3 / Qnew[cnt][i] + Gmod[cnt][i] / dt_array[cnt][i]
+242                                )
+243                                CC[j][i] = 2 * F[cnt][i] / (dy**2)
+244                                BB[j][i] = (
+245                                    1 / dt_array[cnt][i]
+246                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+247                                    + g1 / Qnew[cnt][i]
+248                                )
+249                                BB[j][i + 1] = 2 * F[cnt][i] / (dx**2)
+250                            elif i == m - 1:  # Bottom right point
+251                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+252                                CC[j][i] = 2 * F[cnt][i] / (dy**2)
+253                                BB[j][i] = (
+254                                    1 / dt_array[cnt][i]
+255                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+256                                )
+257                                BB[j][i - 1] = 2 * F[cnt][i] / (dx**2)
+258                            else:
+259                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+260                                CC[j][i] = 2 * F[cnt][i] / (dy**2)
+261                                BB[j][i] = (
+262                                    1 / dt_array[cnt][i]
+263                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+264                                )
+265                                BB[j][i - 1] = F[cnt][i] / (dx**2)
+266                                BB[j][i + 1] = F[cnt][i] / (dx**2)
+267                        elif idx == (m) * (n - 1) + 1:
+268                            if i == 0:
+269                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+270                                AA[j][i] = 2 * F[cnt][i] / (dy**2)
+271                                BB[j][i] = (
+272                                    1 / dt_array[cnt][i]
+273                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+274                                    + g1 / Qnew[cnt][i]
+275                                )
+276                                BB[j][i + 1] = 2 * F[cnt][i] / (dx**2)
+277                            elif i == m - 1:
+278                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+279                                AA[j][i] = 2 * F[cnt][i] / (dy**2)
+280                                BB[j][i] = (
+281                                    1 / dt_array[cnt][i]
+282                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+283                                    - ((g1 * lambda_a[cnt][i]) / (lambda_total[cnt][i]))
+284                                    / Qnew[cnt][i]
+285                                    + ((g3 * lambda_a[cnt][i]) / (lambda_total[cnt][i]))
+286                                    / (Qnew[cnt][i] * self.concentration)
+287                                )
+288                                BB[j][i - 1] = 2 * F[cnt][i] / (dx**2)
+289                            else:
+290                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+291                                AA[j][i] = 2 * F[cnt][i] / (dy**2)
+292                                BB[j][i + 1] = F[cnt][i] / (dx**2)
+293                                BB[j][i] = (
+294                                    1 / dt_array[cnt][i]
+295                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+296                                )
+297                                BB[j][i - 1] = F[cnt][i] / (dx**2)
+298                        else:
+299                            if i == 0:
+300                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+301                                AA[j][i] = F[cnt][i] / (dy**2)
+302                                BB[j][i] = (
+303                                    1 / dt_array[cnt][i]
+304                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+305                                )
+306                                BB[j][i + 1] = 2 * F[cnt][i] / (dx**2)
+307                                CC[j][i] = F[cnt][i] / (dy**2)
+308                            elif i == m - 1:
+309                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+310                                AA[j][i] = F[cnt][i] / (dy**2)
+311                                BB[j][i] = (
+312                                    1 / dt_array[cnt][i]
+313                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+314                                )
+315                                BB[j][i - 1] = 2 * F[cnt][i] / (dx**2)
+316                                CC[j][i] = F[cnt][i] / (dy**2)
+317                            else:
+318                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+319                                AA[j][i] = F[cnt][i] / (dy**2)
+320                                BB[j][i] = (
+321                                    1 / dt_array[cnt][i]
+322                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+323                                )
+324                                BB[j][i - 1] = F[cnt][i] / (dx**2)
+325                                BB[j][i + 1] = F[cnt][i] / (dx**2)
+326                                CC[j][i] = F[cnt][i] / (dy**2)
+327            if cnt == 0:
+328                AAA[:n, : 2 * m] = np.hstack([BB, CC])
+329            elif cnt == n - 1:
+330                AAA[(m - 1) * n : m * n, (n - 2) * m : n * m] = np.hstack([AA, BB])
+331            else:
+332                AAA[cnt * n : (cnt + 1) * n, (cnt - 1) * m : (cnt + 2) * m] = np.hstack(
+333                    [AA, BB, CC]
+334                )
+335
+336            DDD[cnt * m : (cnt + 1) * m] = DD
+337            idx += m
+338
+339        Gnew_flat, info = bicgstab(AAA, DDD, rtol=10 ** (-10), maxiter=600)
+340        Gnew = Gnew_flat.reshape(m, n)
+341
+342        self.concentration_matrix = Gnew
+343
+344        return varying_parameters
+
+ + +

Contains property and calculations related to the surfactant object

+
+ + +
+ +
+ + Surfactant( name: lib.enumerations.SurfactantList, initial_concentration: float, phi: numpy.ndarray, IFT_equation: function | None = None, derivative_IFT_equation: function | None = None, concentration_matrix: numpy.ndarray | None = None) + + + +
+ +
24    def __init__(
+25        self,
+26        name: SurfactantList,
+27        initial_concentration: float,
+28        phi: np.ndarray,
+29        IFT_equation: LambdaType | None = None,
+30        derivative_IFT_equation: (
+31            LambdaType | None
+32        ) = None,  # FIXME: can remove once implemented `autodiff` capabilities
+33        concentration_matrix: np.ndarray | None = None,
+34    ):
+35        """
+36        Creates instance of Surfactant class
+37        """
+38        self.name = name
+39        self.concentration = initial_concentration
+40        self.concentration_matrix = concentration_matrix
+41        self.IFT_conc_equ = IFT_equation
+42        self.derivative_IFT_conc_equ = derivative_IFT_equation  # FIXME: need to adjust when implementing 'autodiff'
+43        self.is_surfactant = True if (initial_concentration > 0) else False
+44        self.phi = phi
+
+ + +

Creates instance of Surfactant class

+
+ + +
+
+ +
+ name + + + +
+ +
68    @property
+69    def name(self):
+70        """
+71        name (enum 'SurfactantList'): Name of the surfactant
+72        """
+73        return self._name
+
+ + +

name (enum 'SurfactantList'): Name of the surfactant

+
+ + +
+
+ +
+ concentration + + + +
+ +
79    @property
+80    def concentration(self):
+81        """
+82        concentration (float): Initial concentration of surfactant (scalar quantity)
+83        """
+84        return self._concentration
+
+ + +

concentration (float): Initial concentration of surfactant (scalar quantity)

+
+ + +
+
+ +
+ concentration_matrix + + + +
+ +
90    @property
+91    def concentration_matrix(self):
+92        """
+93        concentration_matrix (np.ndarray, None): vector representation of surfactant concentration in resevoir
+94        """
+95        return self._concentration_matrix
+
+ + +

concentration_matrix (np.ndarray, None): vector representation of surfactant concentration in resevoir

+
+ + +
+
+ +
+ IFT_conc_equ + + + +
+ +
101    @property
+102    def IFT_conc_equ(self):
+103        """
+104        IFT_conc_equ (lambda, None): expression that relates surfactant concentration to interfacial tension b/t oil and water
+105        """
+106        return self._IFT_conc_equ
+
+ + +

IFT_conc_equ (lambda, None): expression that relates surfactant concentration to interfacial tension b/t oil and water

+
+ + +
+
+ +
+ derivative_IFT_conc_equ + + + +
+ +
112    @property
+113    def derivative_IFT_conc_equ(self):
+114        """
+115        derivative_IFT_conc_equ (lambda, None): Deriviative of the equation relating IFT to surfactant concentration
+116        """
+117        return self._derivative_IFT_conc_equ
+
+ + +

derivative_IFT_conc_equ (lambda, None): Deriviative of the equation relating IFT to surfactant concentration

+
+ + +
+
+ +
+ is_surfactant + + + +
+ +
123    @property
+124    def is_surfactant(self):
+125        """
+126        flag for whether or not surfactant is in the simulation
+127        """
+128        return self._is_surfactant
+
+ + +

flag for whether or not surfactant is in the simulation

+
+ + +
+
+ +
+ phi + + + +
+ +
134    @property
+135    def phi(self):
+136        """
+137        phi (np.ndarray): arrray used to initialize the concentration matrix (represents porosity of the resevoir)
+138        """
+139        return self._phi
+
+ + +

phi (np.ndarray): arrray used to initialize the concentration matrix (represents porosity of the resevoir)

+
+ + +
+
+ +
+ eval_IFT + + + +
+ +
47    @property
+48    def eval_IFT(self):
+49        """
+50        evaluate IFT at a given surfactant concentration_matrix
+51        """
+52        assert self.IFT_conc_equ is not None, SimulationCalcInputException(
+53            "SimulationCalcInputError:UnknownIFTEquation"
+54        )
+55        return self.IFT_conc_equ(self.concentration_matrix)
+
+ + +

evaluate IFT at a given surfactant concentration_matrix

+
+ + +
+
+ +
+ eval_dIFT_dGamma + + + +
+ +
57    @property
+58    def eval_dIFT_dGamma(self):  # FIXME: Need to adjust when implementing 'autodiff'
+59        """
+60        evaluate the dσ/dΓ at a particular surfactant concentration matrix
+61        """
+62        assert self.derivative_IFT_conc_equ is not None, SimulationCalcInputException(
+63            "SimulationCalcInputError:UnknownDerivativeIFTEquation"
+64        )
+65        return self.derivative_IFT_conc_equ(self.concentration_matrix)
+
+ + +

evaluate the dσ/dΓ at a particular surfactant concentration matrix

+
+ + +
+
+ +
+ + def + initialize(self): + + + +
+ +
144    def initialize(
+145        self,
+146    ):
+147        """
+148        This function will initialize the surfactant object
+149        
+150        Returns: (Surfactant)
+151            Surfactant object
+152        """
+153        if self.concentration_matrix is None:
+154            if self.phi is None:
+155                raise SimulationCalcInputException(
+156                    "SimulationInputException: phi value not initalized..."
+157                )
+158            D = (self.phi > 1e-10) + (np.abs(self.phi) < 1e-10)
+159            self.concentration_matrix = (~D) * self.concentration
+160        return self
+
+ + +

This function will initialize the surfactant object

+ +

Returns: (Surfactant) + Surfactant object

+
+ + +
+
+ +
+ + def + compute_concentration( self, grid: lib.grid.Grid, water_sat: numpy.ndarray, const_parameters: dict, varying_parameters: dict, F: numpy.ndarray, Gmod: numpy.ndarray): + + + +
+ +
162    def compute_concentration(
+163        self,
+164        grid: Grid,
+165        water_sat: np.ndarray,
+166        const_parameters: dict,
+167        varying_parameters: dict,
+168        F: np.ndarray,
+169        Gmod: np.ndarray,
+170    ):
+171        """
+172        Computing the surfactant concentration matrix
+173
+174        Raises:
+175            SimulationCalcInputException: Not all required inputs were provided
+176
+177        Args:
+178            grid (Grid): FD mesh
+179
+180            water_sat (np.ndarray): water saturation matrix
+181
+182            const_parameters (dict): dictionary object with constant parameters used in calculation
+183
+184            varying_parameters (dict): dictionary object with varying parameters used in calculation
+185
+186            F (np.ndarray): intermediate matrix used in calcs
+187
+188            Gmod (np.ndarray): bilinear interpolant for sur conc on redefined coordinates
+189
+190        Returns: (dict)
+191            Returns the ``varying_parameters`` dict
+192        """
+193        # initializing constants
+194        assert self.concentration_matrix is not None, SimulationCalcInputException(
+195            "SimuationInputException: polymer concentration matrix not initialized. Please try again"
+196        )
+197        # Required constants:
+198        dx = const_parameters["FD_grid_constants"]["dx"]
+199        dy = const_parameters["FD_grid_constants"]["dy"]
+200        x = const_parameters["FD_grid_constants"]["x"]
+201        y = const_parameters["FD_grid_constants"]["y"]
+202        m = const_parameters["FD_grid_constants"]["m"]
+203        n = const_parameters["FD_grid_constants"]["n"]
+204        phi = self.phi
+205        omega1 = const_parameters["Pc_constants"]["omega1"]
+206        omega2 = const_parameters["Pc_constants"]["omega2"]
+207        Qnew = water_sat
+208        g1 = const_parameters["inlet_total_flow"]
+209        g3 = const_parameters["inlet_surfactant_flow"]
+210        KK = const_parameters["KK"]
+211        relative_permeability_formula = const_parameters[
+212            "relative_permeability_formula"
+213        ]
+214
+215        # retrieving relevant parameters for updating the water saturation
+216        ## Time Step:
+217        dt = const_parameters["FD_grid_constants"]["dt"]
+218        dt_array = const_parameters["FD_grid_constants"]["dt_matrix"]
+219
+220        pc_g = varying_parameters["capillary_pressure_and_derivatives"]["dpc_dg"]
+221        lambda_a = varying_parameters["mobility_parameters"]["lambda_a"]
+222        lambda_total = varying_parameters["mobility_parameters"]["lambda_total"]
+223
+224        # intermediate parameters for code:
+225        idx = 1
+226        AAA = np.zeros((n * m, n * m))
+227        DDD = np.zeros((n * m, 1))
+228
+229        while idx <= (m) * (n - 1) + 1:
+230            cnt = (idx - 1) // m  # cnt = 0, 1, 2, ... for idx = 1, m+1, 2m+1, 3m+1, ...
+231            BB = np.zeros((n, m))
+232            AA = np.copy(BB)
+233            CC = np.copy(BB)
+234            DD = np.zeros((m, 1))
+235            for i in range(m):
+236                for j in range(n):
+237                    if j == i:
+238                        if idx == 1:
+239                            if i == 0:
+240                                DD[i] = (
+241                                    g3 / Qnew[cnt][i] + Gmod[cnt][i] / dt_array[cnt][i]
+242                                )
+243                                CC[j][i] = 2 * F[cnt][i] / (dy**2)
+244                                BB[j][i] = (
+245                                    1 / dt_array[cnt][i]
+246                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+247                                    + g1 / Qnew[cnt][i]
+248                                )
+249                                BB[j][i + 1] = 2 * F[cnt][i] / (dx**2)
+250                            elif i == m - 1:  # Bottom right point
+251                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+252                                CC[j][i] = 2 * F[cnt][i] / (dy**2)
+253                                BB[j][i] = (
+254                                    1 / dt_array[cnt][i]
+255                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+256                                )
+257                                BB[j][i - 1] = 2 * F[cnt][i] / (dx**2)
+258                            else:
+259                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+260                                CC[j][i] = 2 * F[cnt][i] / (dy**2)
+261                                BB[j][i] = (
+262                                    1 / dt_array[cnt][i]
+263                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+264                                )
+265                                BB[j][i - 1] = F[cnt][i] / (dx**2)
+266                                BB[j][i + 1] = F[cnt][i] / (dx**2)
+267                        elif idx == (m) * (n - 1) + 1:
+268                            if i == 0:
+269                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+270                                AA[j][i] = 2 * F[cnt][i] / (dy**2)
+271                                BB[j][i] = (
+272                                    1 / dt_array[cnt][i]
+273                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+274                                    + g1 / Qnew[cnt][i]
+275                                )
+276                                BB[j][i + 1] = 2 * F[cnt][i] / (dx**2)
+277                            elif i == m - 1:
+278                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+279                                AA[j][i] = 2 * F[cnt][i] / (dy**2)
+280                                BB[j][i] = (
+281                                    1 / dt_array[cnt][i]
+282                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+283                                    - ((g1 * lambda_a[cnt][i]) / (lambda_total[cnt][i]))
+284                                    / Qnew[cnt][i]
+285                                    + ((g3 * lambda_a[cnt][i]) / (lambda_total[cnt][i]))
+286                                    / (Qnew[cnt][i] * self.concentration)
+287                                )
+288                                BB[j][i - 1] = 2 * F[cnt][i] / (dx**2)
+289                            else:
+290                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+291                                AA[j][i] = 2 * F[cnt][i] / (dy**2)
+292                                BB[j][i + 1] = F[cnt][i] / (dx**2)
+293                                BB[j][i] = (
+294                                    1 / dt_array[cnt][i]
+295                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+296                                )
+297                                BB[j][i - 1] = F[cnt][i] / (dx**2)
+298                        else:
+299                            if i == 0:
+300                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+301                                AA[j][i] = F[cnt][i] / (dy**2)
+302                                BB[j][i] = (
+303                                    1 / dt_array[cnt][i]
+304                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+305                                )
+306                                BB[j][i + 1] = 2 * F[cnt][i] / (dx**2)
+307                                CC[j][i] = F[cnt][i] / (dy**2)
+308                            elif i == m - 1:
+309                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+310                                AA[j][i] = F[cnt][i] / (dy**2)
+311                                BB[j][i] = (
+312                                    1 / dt_array[cnt][i]
+313                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+314                                )
+315                                BB[j][i - 1] = 2 * F[cnt][i] / (dx**2)
+316                                CC[j][i] = F[cnt][i] / (dy**2)
+317                            else:
+318                                DD[i] = Gmod[cnt][i] / dt_array[cnt][i]
+319                                AA[j][i] = F[cnt][i] / (dy**2)
+320                                BB[j][i] = (
+321                                    1 / dt_array[cnt][i]
+322                                    - ((2 / (dx**2)) + (2 / (dy**2))) * F[cnt][i]
+323                                )
+324                                BB[j][i - 1] = F[cnt][i] / (dx**2)
+325                                BB[j][i + 1] = F[cnt][i] / (dx**2)
+326                                CC[j][i] = F[cnt][i] / (dy**2)
+327            if cnt == 0:
+328                AAA[:n, : 2 * m] = np.hstack([BB, CC])
+329            elif cnt == n - 1:
+330                AAA[(m - 1) * n : m * n, (n - 2) * m : n * m] = np.hstack([AA, BB])
+331            else:
+332                AAA[cnt * n : (cnt + 1) * n, (cnt - 1) * m : (cnt + 2) * m] = np.hstack(
+333                    [AA, BB, CC]
+334                )
+335
+336            DDD[cnt * m : (cnt + 1) * m] = DD
+337            idx += m
+338
+339        Gnew_flat, info = bicgstab(AAA, DDD, rtol=10 ** (-10), maxiter=600)
+340        Gnew = Gnew_flat.reshape(m, n)
+341
+342        self.concentration_matrix = Gnew
+343
+344        return varying_parameters
+
+ + +

Computing the surfactant concentration matrix

+ +

Raises: + SimulationCalcInputException: Not all required inputs were provided

+ +

Args: + grid (Grid): FD mesh

+ +
water_sat (np.ndarray): water saturation matrix
+
+const_parameters (dict): dictionary object with constant parameters used in calculation
+
+varying_parameters (dict): dictionary object with varying parameters used in calculation
+
+F (np.ndarray): intermediate matrix used in calcs
+
+Gmod (np.ndarray): bilinear interpolant for sur conc on redefined coordinates
+
+ +

Returns: (dict) + Returns the varying_parameters dict

+
+ + +
+
+
+ + \ No newline at end of file diff --git a/docs/lib/test.html b/docs/lib/test.html new file mode 100644 index 0000000..442bd3b --- /dev/null +++ b/docs/lib/test.html @@ -0,0 +1,301 @@ + + + + + + + lib.test API documentation + + + + + + + + + +
+
+

+lib.test

+ + + + + + +
 1# """
+ 2# Sandbox script for developer testing
+ 3#
+ 4# Use this python script when implementing new features
+ 5# """
+ 6#
+ 7# import os
+ 8#
+ 9# import numpy as np
+10# from .grid import Grid
+11# from .enumerations import (
+12#     ModelType,
+13#     PolymerList,
+14#     SurfactantList,
+15#     PermeabilityType,
+16#     ResevoirGeometry,
+17#     SimulationConstants,
+18# )
+19# from .Exceptions import SimulationCalcInputException, UserInputException
+20# import simulation
+21#
+22# MODEL = {
+23#     "No_Shear_Thinning": 1,
+24#     "Sourav_Implementation": 2,
+25#     "Shear_Thinning": 3,
+26# }
+27#
+28# GEOMETRY = {
+29#     "Rectilinear": 1,
+30#     "Quarter Five Spot": 2,
+31# }
+32#
+33# PERMEABILITY = {
+34#     "Homogeneous": 1,
+35#     "Heterogeneous": 2,
+36# }
+37#
+38# POLYMER = {
+39#     "Xanthane": 1,
+40#     "Schizophyllan": 2,
+41#     "No Polymer": 3,
+42# }
+43#
+44# SURFACTANT = {
+45#     "Alkyl_Ether_Sulfate": 1,
+46#     "No_Surfactant": 2,
+47# }
+48#
+49# # Making the simulation object:
+50# user_dict = {
+51#     "simulation_id": 1,
+52#     "model_type": MODEL["No_Shear_Thinning"],
+53#     "reservoir_geometry": GEOMETRY["Rectilinear"],
+54#     "permeability": PERMEABILITY["Homogeneous"],
+55#     "polymer_type": POLYMER["Xanthane"],
+56#     "polymer_concentration": 0.001,
+57#     "surfactant_type": SURFACTANT["Alkyl_Ether_Sulfate"],
+58#     "surfactant_concentration": 0,
+59# }
+60# # FIXME: discrepancy in polymer viscosity matrix. Checked the u, v, x, and y (x and y from 'Grid' class)
+61# sim1 = simulation.Simulation(user_input_dict=user_dict)
+62# sim1.run()
+63# # print(f'polymer viscosity matrix{sim1.polymer.viscosity_matrix}')
+64# # print(f'aqueous viscosity matrix{sim1.water.viscosity_array}')
+
+ + +
+
+ + \ No newline at end of file diff --git a/docs/lib/water.html b/docs/lib/water.html new file mode 100644 index 0000000..ec357d5 --- /dev/null +++ b/docs/lib/water.html @@ -0,0 +1,3708 @@ + + + + + + + lib.water API documentation + + + + + + + + + +
+
+

+lib.water

+ +

This python script contains the class definition for the water in the surfactant-flooding model

+ +

The methods of this class were derived from the MATLAB Surfactant-Polymer Flooding Code developed by +Sourav Dutta and Rohit Mishra.

+ +

@author: Bhargav Akula Ramesh Kumar, Carlos Acosta Caripo

+
+ + + + + +
   1"""
+   2This python script contains the class definition for the water in the surfactant-flooding model
+   3
+   4The methods of this class were derived from the MATLAB Surfactant-Polymer Flooding Code developed by
+   5Sourav Dutta and Rohit Mishra.
+   6
+   7@author: Bhargav Akula Ramesh Kumar, Carlos Acosta Caripo
+   8"""
+   9
+  10##EXTERNAL IMPORTS
+  11import numpy as np
+  12import scipy as sp
+  13from scipy.linalg import fractional_matrix_power
+  14from scipy.sparse.linalg import bicgstab
+  15
+  16##INTERNAL IMPORTS
+  17from .enumerations import ModelType, RelativePermeabilityFormula, SimulationConstants
+  18from .Exceptions import SimulationCalcInputException
+  19from .grid import Grid
+  20from .polymer import Polymer
+  21from .surfactant import Surfactant
+  22
+  23
+  24class Water:
+  25    """
+  26    Contains the properties and methods for water in the SP-Flooding system
+  27    """
+  28
+  29    def __init__(
+  30        self,
+  31        init_water_saturation: float,
+  32        init_aqueous_saturation: float,
+  33        init_oleic_saturation: float,
+  34        miuw: float,
+  35        miuo: float,
+  36        phi: np.ndarray,
+  37    ):
+  38        """
+  39        Constructor for the ``Water`` class
+  40        """
+  41        self.init_water_saturation = init_water_saturation
+  42        self.init_aqueous_saturation = init_aqueous_saturation
+  43        self.init_oleic_saturation = init_oleic_saturation
+  44        self.miuw = miuw
+  45        self.miuo = miuo
+  46        self.water_saturation = None  # water saturation matrix
+  47        self.viscosity_array = None  # aqueous viscosity matrix
+  48        self.phi = phi
+  49
+  50    _init_water_saturation = None
+  51    @property
+  52    def init_water_saturation(self):
+  53        """
+  54        init_water_saturation (float): initial residual water saturation
+  55        """
+  56        return self._init_water_saturation
+  57    @init_water_saturation.setter
+  58    def init_water_saturation(self, value):
+  59        self._init_water_saturation = value
+  60
+  61    _init_aqueous_saturation = None
+  62    @property
+  63    def init_aqueous_saturation(self):
+  64        """
+  65        init_aqueous_saturation (float): initial residual aqueous phase saturation below critical capillary number (when σ = 0)
+  66        """
+  67        return self._init_aqueous_saturation
+  68    @init_aqueous_saturation.setter
+  69    def init_aqueous_saturation(self, value):
+  70        self._init_aqueous_saturation = value
+  71
+  72    _init_oleic_saturation = None
+  73    @property
+  74    def init_oleic_saturation(self):
+  75        """
+  76        init_oleic_saturation (float): initial residual oil phase saturation below the critical capillary number (when σ = 0)
+  77        """
+  78        return self._init_oleic_saturation
+  79    @init_oleic_saturation.setter
+  80    def init_oleic_saturation(self, value):
+  81        self._init_oleic_saturation = value
+  82
+  83    _miuw = None
+  84    @property
+  85    def miuw(self):
+  86        """
+  87        miuw (float): water viscosity
+  88        """
+  89        return self._miuw
+  90    @miuw.setter
+  91    def miuw(self, value):
+  92        self._miuw = value 
+  93
+  94    _miuo = None
+  95    @property
+  96    def miuo(self):
+  97        """
+  98        miuo (float): oil viscosity
+  99        """
+ 100        return self._miuo
+ 101    @miuo.setter
+ 102    def miuo(self, value):
+ 103        self._miuo = value 
+ 104
+ 105    _phi = None
+ 106    @property
+ 107    def phi(self):
+ 108        """
+ 109        phi (np.ndarray): porosity matrix
+ 110        """
+ 111        return self._phi
+ 112    @phi.setter
+ 113    def phi(self, value):
+ 114        self._phi = value
+ 115
+ 116    _water_saturation = None
+ 117    @property
+ 118    def water_saturation(self):
+ 119        """
+ 120        water_saturation (np.ndarray): The water saturation matrix being updated using the transport equations
+ 121        """
+ 122        return self._water_saturation
+ 123    @water_saturation.setter
+ 124    def water_saturation(self, value):
+ 125        self._water_saturation = value
+ 126
+ 127    _viscosity_array = None
+ 128    @property
+ 129    def viscosity_array(self):
+ 130        """
+ 131        viscosity_array (np.ndarray): The water viscosity matrix
+ 132        """
+ 133        return self._viscosity_array
+ 134    @viscosity_array.setter
+ 135    def viscosity_array(self, value):
+ 136        self._viscosity_array = value
+ 137
+ 138
+ 139    def initialize(self, grid_shape: tuple):
+ 140        """
+ 141        Initializing 'Water' object properties
+ 142
+ 143        Raises:
+ 144        -------
+ 145            SimuationInputException: Either Intial water saturation and/or porosity matrix not provided for initializing Water object
+ 146
+ 147        Args:
+ 148        -----
+ 149            grid_shape (tuple): the n and m parameters from the 'Grid' class
+ 150        
+ 151        Returns: (Water)
+ 152        ---------------
+ 153            Initializes the Water object
+ 154        """
+ 155        assert self.init_water_saturation is not None, SimulationCalcInputException(
+ 156            "SimuationInputException: Initial water saturation not initialized. Please try again"
+ 157        )
+ 158        assert self.phi is not None, SimulationCalcInputException(
+ 159            "SimuationInputException: porosity matrix not initialized. Please try again"
+ 160        )
+ 161        # getting values for n and m from grid:
+ 162        n, m = grid_shape
+ 163
+ 164        # initializing the water saturation matrix
+ 165        s0 = np.zeros((n + 1, m + 1))
+ 166        D = (self.phi > 1e-10) | (np.abs(self.phi) < 1e-10)
+ 167        s0 = np.logical_not(D).astype(float) + D.astype(float) * (
+ 168            1 - self.init_water_saturation
+ 169        )
+ 170        self.water_saturation = s0
+ 171
+ 172        # initialize the aqueous viscosity matrix:
+ 173        self.viscosity_array = self.miuw * np.ones((n + 1, m + 1))
+ 174
+ 175        return self
+ 176
+ 177    def compute_viscosity(
+ 178        self,
+ 179        grid: Grid,
+ 180        model_type: ModelType,
+ 181        polymer: Polymer,
+ 182        u: np.ndarray | None = None,
+ 183        v: np.ndarray | None = None,
+ 184    ):
+ 185        """
+ 186        Compute aqueous viscosity.
+ 187
+ 188        Raises:
+ 189        -------
+ 190            SimulationCalcInputException: Not all required parameters provided
+ 191        
+ 192        Args:
+ 193        -----
+ 194            grid (Grid): Grid object for deterrmining matrix size
+ 195
+ 196            model_type (enum 'ModelType'): Type of model we are running (Polymer shear thinning ON or OFF)
+ 197
+ 198            polymer (Polymer): holds the information about the polymer in the sim
+ 199
+ 200            u (np.ndarray, None): global pressure matrix. Only needed when shear thinning ON.
+ 201
+ 202            v (np.ndarray, None): velocity matrix. Only needed when shear thinning ON.
+ 203        
+ 204        Returns: (np.ndarray)
+ 205        --------------------
+ 206            Updated aqueous viscosity matrix
+ 207        """
+ 208
+ 209        assert self.viscosity_array is not None, SimulationCalcInputException(
+ 210            "SimuationInputException: aqueous viscosity matrix not initialized. Please try again"
+ 211        )
+ 212        assert polymer is not None and isinstance(
+ 213            polymer, Polymer
+ 214        ), SimulationCalcInputException(
+ 215            "SimuationInputException: polymer object not initialized. \
+ 216                The polymer object must be initialized before updating aqueous viscosity. Please try again."
+ 217        )
+ 218        assert polymer.concentration_matrix is not None, SimulationCalcInputException(
+ 219            "SimuationInputException: Polymer Concentration matrix must be initialized. Please try again..."
+ 220        )
+ 221        assert polymer.shear_rate is not None, SimulationCalcInputException(
+ 222            "SimuationInputException: Polymer Shear Rate matrix must be initialized. Please try again..."
+ 223        )
+ 224        n = np.size(polymer.concentration_matrix, 0)
+ 225        m = np.size(polymer.concentration_matrix, 1)
+ 226        initial_polymer_concentration_scalar = polymer.concetration_scalar
+ 227        if (
+ 228            model_type.value == ModelType.No_Shear_Thinning.value
+ 229        ):  # no shear thinning polymer
+ 230            miuw = SimulationConstants.Water_Viscosity.value
+ 231            if initial_polymer_concentration_scalar == 0:
+ 232                self.viscosity_array = miuw * np.ones((n, m))
+ 233            else:
+ 234                beta1 = SimulationConstants.beta1.value
+ 235                self.viscosity_array = miuw * (1 + beta1 * polymer.concentration_matrix)
+ 236        elif (
+ 237            model_type.value == ModelType.Shear_Thinning_On.value
+ 238        ):  # shear thinning polymer
+ 239            # using the shear rate and polymer coefficients to understand how its viscosity changes
+ 240            assert u is not None, SimulationCalcInputException(
+ 241                "SimuationInputException: variables 'u' not initialized for shear-thinning-on model. Please try again"
+ 242            )
+ 243            assert v is not None, SimulationCalcInputException(
+ 244                "SimuationInputException: variables 'v' not initialized for shear-thinning-on model. Please try again"
+ 245            )
+ 246
+ 247            # constants:
+ 248            rho_water = SimulationConstants.Water_Density.value
+ 249            viscosity_water = SimulationConstants.Water_Viscosity.value
+ 250
+ 251            # relevant parameters for power law equation:
+ 252            w1 = polymer.rho * polymer.concentration_matrix
+ 253            w2 = rho_water * (1 - polymer.concentration_matrix)
+ 254            wppm = (w1 / (w1 + w2)) * (10**6)
+ 255
+ 256            eps = 1e-12
+ 257            wppm_safe = np.maximum(wppm, eps)
+ 258
+ 259            epsilon_val = polymer.e_coeff[0] * wppm_safe ** polymer.e_coeff[1]
+ 260            n_val = np.minimum(polymer.n_coeff[0] * wppm_safe ** polymer.n_coeff[1], 1)
+ 261
+ 262            row = np.size(polymer.concentration_matrix, 0)
+ 263            col = np.size(polymer.concentration_matrix, 1)
+ 264
+ 265            # Compute divergence terms
+ 266            a1 = np.gradient(v, axis=0)
+ 267            a2 = np.gradient(u, axis=1)
+ 268            a3 = np.gradient(u, axis=0)
+ 269            a4 = np.gradient(v, axis=1)
+ 270
+ 271            pi_D = np.abs(-0.25 * (a1 + a2) ** 2 + a3 * a4)
+ 272
+ 273            for ii in range(row):
+ 274                for jj in range(col):
+ 275                    # Applying constraints
+ 276                    self.viscosity_array[ii, jj] = epsilon_val[ii, jj] * (
+ 277                        polymer.shear_rate[ii, jj] ** (n_val[ii, jj] - 1)
+ 278                    )
+ 279                    if self.viscosity_array[ii, jj] < viscosity_water:
+ 280                        self.viscosity_array[ii, jj] = viscosity_water
+ 281                    if self.viscosity_array[ii, jj] > 100:
+ 282                        self.viscosity_array[ii, jj] = 100
+ 283        return self.viscosity_array
+ 284
+ 285    def compute_residual_saturations(
+ 286        self, sigma: np.ndarray, u: np.ndarray, v: np.ndarray
+ 287    ):
+ 288        """
+ 289        Compute swr, sor based on capillary numbers (came from compres.m MATLAB file)
+ 290
+ 291        Args:
+ 292        -----
+ 293            sigma (np.ndarray): interfacial tension (IFT)
+ 294
+ 295            u (np.ndarray): global pressure matrix.
+ 296
+ 297            v (np.ndarray): velocity matrix.
+ 298        
+ 299        Returns: (list)
+ 300        ---------------
+ 301            residual saturation for oil (index 1) and water (index 0) phases
+ 302        """
+ 303        swr0 = self.init_aqueous_saturation
+ 304        sor0 = self.init_oleic_saturation
+ 305
+ 306        Nco0 = 1.44e-4
+ 307        Nca0 = 1.44e-4
+ 308
+ 309        vel_mag = np.sqrt(np.matmul(u, u) + np.matmul(v, v), dtype=np.complex128)
+ 310        nca = (vel_mag * self.viscosity_array) / sigma
+ 311        nco = (vel_mag * self.miuo) / sigma
+ 312
+ 313        Nca = np.linalg.norm(nca)
+ 314        Nco = np.linalg.norm(nco)
+ 315
+ 316        sor = sor0 * (Nco0 / Nco) ** 0.5213 if Nco >= Nco0 else sor0
+ 317        swr = swr0 * (Nca0 / Nca) ** 0.1534 if Nca >= Nca0 else swr0
+ 318
+ 319        return [swr, sor]  # [residual aqueous saturation, residual oil saturation]
+ 320
+ 321    def compute_mobility(
+ 322        self,
+ 323        c: np.ndarray,
+ 324        sor: float,
+ 325        swr: float,
+ 326        aqueous: bool,
+ 327        rel_permeability_formula: RelativePermeabilityFormula,
+ 328        modified_water_saturation: np.ndarray | None = None,
+ 329    ):
+ 330        """
+ 331        Computing mobility (made using the compmob.m MATLAB file)
+ 332        
+ 333        Raise:
+ 334        ------
+ 335            SimulationCalcInputException: Not all required arguments are not provided
+ 336
+ 337        Args:
+ 338        -----
+ 339            c (np.ndarray): polymer concentration matrix
+ 340
+ 341            sor (float): residual saturation oil phase
+ 342
+ 343            swr (float): residual saturation water phase
+ 344
+ 345            aqueous (bool): boolean for whether we are solving for aqoeous or oleic mobility
+ 346
+ 347            rel_permeability_formula (enum 'RelativePermeabilityFormula'): Select the type of relative Permeability formula from the ``RelativePermeabilityFormula`` Enum
+ 348
+ 349            surfactant_conc (float): scalar quantity of the initial surfactant concentration
+ 350        
+ 351        Returns: (np.ndarray)
+ 352        ---------------------
+ 353            aqueous or oleic mobility (depending on the 'aqueous' parameter)
+ 354        """
+ 355        assert self.water_saturation is not None, SimulationCalcInputException(
+ 356            "SimuationInputException: water saturation matrix not initialized. Please try again"
+ 357        )
+ 358        assert self.viscosity_array is not None, SimulationCalcInputException(
+ 359            "SimuationInputException: viscosity matrix not initialized. Please try again"
+ 360        )
+ 361        s = (
+ 362            self.water_saturation
+ 363            if (modified_water_saturation is None)
+ 364            else modified_water_saturation
+ 365        )
+ 366        miua = self.viscosity_array
+ 367        if (
+ 368            rel_permeability_formula.value
+ 369            == RelativePermeabilityFormula.CoreyTypeEquation.value
+ 370        ):
+ 371            nsw0 = (s - self.init_aqueous_saturation) / (
+ 372                1 - self.init_aqueous_saturation
+ 373            )
+ 374            nso0 = (s - self.init_aqueous_saturation) / (
+ 375                1 - self.init_aqueous_saturation - self.init_oleic_saturation
+ 376            )
+ 377            krw0 = nsw0**3.5
+ 378            kro0 = ((1 - nso0) ** 2) * (1 - nso0**1.5)
+ 379        else:
+ 380            nsw = (s - swr) / (1 - swr)
+ 381            nso = (s - swr) / (1 - swr - sor)
+ 382            krw0 = nsw * (2.5 * swr * (nsw**2 - 1) + 1)
+ 383            kro0 = (1 - nso) * (1 - 5 * sor * nso)
+ 384
+ 385        return krw0 / miua if aqueous else kro0 / self.miuo
+ 386
+ 387    def compute_water_saturation(
+ 388        self,
+ 389        grid: Grid,
+ 390        surfactant: Surfactant,
+ 391        polymer: Polymer,
+ 392        u: np.ndarray,
+ 393        v: np.ndarray,
+ 394        xmod: np.ndarray,
+ 395        ymod: np.ndarray,
+ 396        const_parameters: dict,
+ 397        varying_parameters: dict,
+ 398    ):
+ 399        """
+ 400        Solving saturation equation (comes from part of the nmmoc_surf_mod_neumann.m file that
+ 401        is for calculating the water saturation)
+ 402        
+ 403        Raises:
+ 404        -------
+ 405            SimulationCalcInputException: If water saturation matrix is None
+ 406
+ 407        Args:
+ 408        -----
+ 409            grid (Grid): the 'Grid' object
+ 410
+ 411            surfactant (Surfactant): The surfactant object
+ 412
+ 413            polymer (Polymer): The polymer object
+ 414
+ 415            u (np.ndarray): global pressure matrix
+ 416
+ 417            v (np.ndarray): velocity matrix
+ 418
+ 419            xmod (np.ndarray): x-dimension coordinate points for formulating the 'Qmod' matrix
+ 420
+ 421            ymod (np.ndarray): y-dimension coordinate points for formulating the 'Qmod' matrix
+ 422
+ 423            const_parameters (dict): constant parameters used in the method
+ 424
+ 425            varying_parameters (dict): parameters whose values can change
+ 426        
+ 427        Returns: (np.ndarray, dict)
+ 428        -----------------------------
+ 429            Updates the ``water_saturation`` matrix and ``varying_parameters`` dict
+ 430        """
+ 431        # Assert statements to ensure that all parameters are property initialized:
+ 432        assert self.water_saturation is not None, SimulationCalcInputException(
+ 433            "SimuationInputException: water saturation matrix not initialized. Please try again"
+ 434        )
+ 435        # Required constants:
+ 436        dx = const_parameters["FD_grid_constants"]["dx"]
+ 437        dy = const_parameters["FD_grid_constants"]["dy"]
+ 438        x = const_parameters["FD_grid_constants"]["x"]
+ 439        y = const_parameters["FD_grid_constants"]["y"]
+ 440        m = const_parameters["FD_grid_constants"]["m"]
+ 441        n = const_parameters["FD_grid_constants"]["n"]
+ 442        phi = self.phi
+ 443        omega1 = const_parameters["Pc_constants"]["omega1"]
+ 444        omega2 = const_parameters["Pc_constants"]["omega2"]
+ 445        Q = np.copy(self.water_saturation)
+ 446        g1 = const_parameters["inlet_total_flow"]
+ 447        KK = const_parameters["KK"]
+ 448        relative_permeability_formula = const_parameters[
+ 449            "relative_permeability_formula"
+ 450        ]
+ 451
+ 452        # retrieving relevant parameters for updating the water saturation
+ 453        ## Time Step:
+ 454        dt = const_parameters["FD_grid_constants"]["dt"]
+ 455        dt_array = const_parameters["FD_grid_constants"]["dt_matrix"]
+ 456
+ 457        # Determining Qmod matrix
+ 458        x1d = x[0, :]
+ 459        y1d = y[:, 0]
+ 460        x_sorted = np.all(np.diff(x1d) > 0)
+ 461        y_sorted = np.all(np.diff(y1d) > 0)
+ 462
+ 463        # reorder Q if a dimension isn't sorted
+ 464        if not x_sorted:
+ 465            x_sort_idx = np.argsort(x1d)
+ 466            x1d = x1d[x_sort_idx]
+ 467            Q = Q[:, x_sort_idx]  # Sort columns of S
+ 468        if not y_sorted:
+ 469            y_sort_idx = np.argsort(y1d)
+ 470            y1d = y1d[y_sort_idx]
+ 471            Q = Q[y_sort_idx, :]  # Sort rows of Q
+ 472
+ 473        interp_func = sp.interpolate.RegularGridInterpolator(
+ 474            (y1d, x1d), Q, method="linear", bounds_error=False, fill_value=None
+ 475        )
+ 476
+ 477        query_points = np.stack([ymod.ravel(), xmod.ravel()], axis=-1)
+ 478        Qmod = interp_func(query_points).reshape(xmod.shape)
+ 479
+ 480        swr = varying_parameters["swr"]
+ 481        sor = varying_parameters["sor"]
+ 482        nsw = (Qmod - swr) / (1 - swr)
+ 483        nso = (Qmod - swr) / (1 - swr - sor)
+ 484        varying_parameters["nsw"] = nsw
+ 485        varying_parameters["nso"] = nso
+ 486
+ 487        ## fractional flow and derivatives
+ 488        assert polymer.concentration_matrix is not None, SimulationCalcInputException(
+ 489            "SimulationCalcInputError:UnknownPolymerConcentrationMatrix"
+ 490        )
+ 491        lambda_a = self.compute_mobility(
+ 492            c=polymer.concentration_matrix,
+ 493            sor=float(sor),
+ 494            swr=float(swr),
+ 495            aqueous=True,
+ 496            rel_permeability_formula=relative_permeability_formula,
+ 497            modified_water_saturation=Qmod,
+ 498        )
+ 499        lambda_o = self.compute_mobility(
+ 500            c=polymer.concentration_matrix,
+ 501            sor=float(sor),
+ 502            swr=float(swr),
+ 503            aqueous=False,
+ 504            rel_permeability_formula=relative_permeability_formula,
+ 505            modified_water_saturation=Qmod,
+ 506        )
+ 507        lambda_total = lambda_a + lambda_o
+ 508        varying_parameters["mobility_parameters"] = {
+ 509            "lambda_a": lambda_a,
+ 510            "lambda_o": lambda_o,
+ 511            "lambda_total": lambda_total,
+ 512        }
+ 513        ## fractional flow calculations
+ 514        f = lambda_a / lambda_total
+ 515        assert KK is not None, SimulationCalcInputException(
+ 516            "SimulationCalcInputError:UnknownPermeabilityTensor"
+ 517        )
+ 518        D = KK * lambda_o * f
+ 519        assert self.viscosity_array is not None, SimulationCalcInputException(
+ 520            "SimulationCalcInputError:UnkownWaterViscosityMatrix"
+ 521        )
+ 522        varying_parameters["fractional_flow_parameters"] = {"f": f, "D": D}
+ 523        pc = (
+ 524            surfactant.eval_IFT
+ 525            * const_parameters["Pc_constants"]["omega2"]
+ 526            * np.sqrt(const_parameters["porosity"])
+ 527        ) / (
+ 528            np.matmul(
+ 529                KK ** (0.5),
+ 530                fractional_matrix_power(
+ 531                    1 - nso, 1 / const_parameters["Pc_constants"]["omega1"]
+ 532                ),
+ 533            )
+ 534        )
+ 535        pc_s = pc / (const_parameters["Pc_constants"]["omega1"] * (1 - nso))
+ 536        pc_g = (pc / surfactant.eval_IFT) * surfactant.eval_dIFT_dGamma + pc_s
+ 537        varying_parameters["capillary_pressure_and_derivatives"] = {
+ 538            "pc": pc,
+ 539            "dpc_ds": pc_s,
+ 540            "dpc_dg": pc_g,
+ 541        }
+ 542        f_c = (-1 * (lambda_o * lambda_a * self.miuo)) / (
+ 543            (lambda_total**2) * self.viscosity_array
+ 544        )
+ 545        f_g = (
+ 546            varying_parameters["relative_permeability_derivatives"]["dkra_dg"]
+ 547            * lambda_o
+ 548        ) / ((lambda_total**2) * self.viscosity_array)
+ 549        varying_parameters["fractional_flow_derivatives"]["df_dc"] = f_c
+ 550        varying_parameters["fractional_flow_derivatives"]["df_dg"] = f_g
+ 551        D_g = D * pc_g
+ 552        D_s = D * pc_s
+ 553        varying_parameters["fractional_flow_derivatives"]["dD_dg"] = D_g
+ 554        varying_parameters["fractional_flow_derivatives"]["dD_ds"] = D_s
+ 555
+ 556        # Updating coefficients with interpolated saturations
+ 557        idx = 1
+ 558        AAA = np.zeros((n * m, n * m))
+ 559        DDD = np.zeros((n * m, 1))
+ 560
+ 561        while (
+ 562            idx <= m * (n - 1) + 1
+ 563            and surfactant.concentration_matrix is not None
+ 564            and polymer.concentration_matrix is not None
+ 565        ):
+ 566            cnt = (idx - 1) // m  # cnt = 0, 1, 2, ... for idx = 1, m+1, 2m+1, 3m+1, ...
+ 567            BB = np.zeros((n, m))
+ 568            AA = np.copy(BB)
+ 569            CC = np.copy(BB)
+ 570            DD = np.zeros((m, 1))
+ 571
+ 572            #'cnt+1' in matlab is 'cnt' in python as matlab indexes from 1 but python indexes from 0
+ 573            for i in range(m):
+ 574                for j in range(n):
+ 575                    if j == i:
+ 576                        if idx == 1:
+ 577                            if i == 0:  # first/left column
+ 578                                DD[i] = (
+ 579                                    (Qmod[cnt][i] / dt_array[cnt][i])
+ 580                                    + g1 * (1 - f[cnt][i])
+ 581                                    + (
+ 582                                        (D_g[cnt][i] + D_g[cnt][i + 1]) / (dx**2)
+ 583                                        + (D_g[cnt + 1][i] + D_g[cnt][i]) / (dy**2)
+ 584                                    )
+ 585                                    * surfactant.concentration_matrix[cnt][i]
+ 586                                    - (D_g[cnt][i] + D_g[cnt][i + 1])
+ 587                                    / (dx**2)
+ 588                                    * surfactant.concentration_matrix[cnt][i + 1]
+ 589                                    - (D_g[cnt][i] + D_g[cnt + 2][i])
+ 590                                    / (dy**2)
+ 591                                    * surfactant.concentration_matrix[cnt + 1][i]
+ 592                                )
+ 593
+ 594                                CC[j][i] = (D_s[cnt][i] + D_s[cnt + 1][i]) / (dy**2)
+ 595
+ 596                                BB[j][i] = (
+ 597                                    1 / dt_array[cnt][i]
+ 598                                    - (D_s[cnt][i] + D_s[cnt][i + 1]) / (dx**2)
+ 599                                    - (D_s[cnt + 1][i] + D_s[cnt][i]) / (dy**2)
+ 600                                )
+ 601
+ 602                                BB[j][i + 1] = (D_s[cnt][i] + D_s[cnt][i + 1]) / (dx**2)
+ 603                            elif i == m - 1:  # last/rightmost column
+ 604                                DD[i] = (
+ 605                                    Qmod[cnt][i] / dt_array[cnt][i]
+ 606                                    + (
+ 607                                        (D_g[cnt][i] + D_g[cnt][i - 1]) / (dx**2)
+ 608                                        + (D_g[cnt + 1][i] + D_g[cnt][i]) / (dy**2)
+ 609                                    )
+ 610                                    * surfactant.concentration_matrix[cnt][i]
+ 611                                    - (D_g[cnt][i] + D_g[cnt][i - 1])
+ 612                                    / (dx**2)
+ 613                                    * surfactant.concentration_matrix[cnt][i - 1]
+ 614                                    - (D_g[cnt][i] + D_g[cnt + 1][i])
+ 615                                    / (dy**2)
+ 616                                    * surfactant.concentration_matrix[cnt + 1][i]
+ 617                                )
+ 618
+ 619                                BB[j][i - 1] = (D_s[cnt][i] + D_s[cnt][i - 1]) / (dx**2)
+ 620
+ 621                                BB[j][i] = (
+ 622                                    1 / dt_array[cnt][i]
+ 623                                    - (D_s[cnt][i] + D_s[cnt][i - 1]) / (dx**2)
+ 624                                    - (D_s[cnt + 1][i] + D_s[cnt][i]) / (dy**2)
+ 625                                )
+ 626
+ 627                                CC[j][i] = (D_s[cnt][i] + D_s[cnt + 1][i]) / (dy**2)
+ 628                            else: # FIXME: stopped here!
+ 629                                DD[i] = (
+ 630                                    Qmod[cnt][i] / dt_array[cnt][i]
+ 631                                    - f_c[cnt][i]
+ 632                                    * (
+ 633                                        u[cnt][i]
+ 634                                        * (
+ 635                                            polymer.concentration_matrix[cnt][i + 1]
+ 636                                            - polymer.concentration_matrix[cnt][i - 1]
+ 637                                        )
+ 638                                        / (2 * dx)
+ 639                                    )
+ 640                                    - f_g[cnt][i]
+ 641                                    * (
+ 642                                        u[cnt][i]
+ 643                                        * (
+ 644                                            surfactant.concentration_matrix[cnt][i + 1]
+ 645                                            - surfactant.concentration_matrix[cnt][
+ 646                                                i - 1
+ 647                                            ]
+ 648                                        )
+ 649                                        / (2 * dx)
+ 650                                    )
+ 651                                    + (
+ 652                                        (
+ 653                                            D_g[cnt][i + 1]
+ 654                                            + D_g[cnt][i - 1]
+ 655                                            + 2 * D_g[cnt][i]
+ 656                                        )
+ 657                                        / (2 * dx**2)
+ 658                                        + (D_g[cnt][i + 1] + D_g[cnt][i]) / (dy**2)
+ 659                                    )
+ 660                                    * surfactant.concentration_matrix[cnt][i]
+ 661                                    - (D_g[cnt][i + 1] + D_g[cnt][i])
+ 662                                    / (2 * dx**2)
+ 663                                    * surfactant.concentration_matrix[cnt][i + 1]
+ 664                                    - (D_g[cnt][i - 1] + D_g[cnt][i])
+ 665                                    / (2 * dx**2)
+ 666                                    * surfactant.concentration_matrix[cnt][i - 1]
+ 667                                    - (D_g[cnt][i] + D_g[cnt + 1][i])
+ 668                                    / (dy**2)
+ 669                                    * surfactant.concentration_matrix[cnt + 1][i]
+ 670                                )
+ 671
+ 672                                BB[j][i] = (
+ 673                                    1 / dt_array[cnt][i]
+ 674                                    - (
+ 675                                        D_s[cnt][i + 1]
+ 676                                        + D_s[cnt][i - 1]
+ 677                                        + 2 * D_s[cnt][i]
+ 678                                    )
+ 679                                    / (2 * dx**2)
+ 680                                    - (D_s[cnt + 1][i] + D_s[cnt][i]) / (dy**2)
+ 681                                )
+ 682                                BB[j][i - 1] = (D_s[cnt][i - 1] + D_s[cnt][i]) / (
+ 683                                    2 * dx**2
+ 684                                )
+ 685                                BB[j][i + 1] = (D_s[cnt][i + 1] + D_s[cnt][i]) / (
+ 686                                    2 * dx**2
+ 687                                )
+ 688
+ 689                                CC[j][i] = (D_s[cnt][i] + D_s[cnt + 1][i]) / (dy**2)
+ 690
+ 691                        elif idx == (m) * (n - 1) + 1:  # topmost row of grid
+ 692                            if i == 0:  # leftmost column
+ 693                                DD[i] = (
+ 694                                    (Qmod[cnt][i] / dt_array[cnt][i])
+ 695                                    + (
+ 696                                        (D_g[cnt][i] + D_g[cnt][i + 1]) / (dx**2)
+ 697                                        + (D_g[cnt - 1][i] + D_g[cnt][i]) / (dy**2)
+ 698                                    )
+ 699                                    * surfactant.concentration_matrix[cnt][i]
+ 700                                    - (D_g[cnt][i] + D_g[cnt][i + 1])
+ 701                                    / (dx**2)
+ 702                                    * surfactant.concentration_matrix[cnt][i + 1]
+ 703                                    - (D_g[cnt][i] + D_g[cnt - 1][i])
+ 704                                    / (dy**2)
+ 705                                    * surfactant.concentration_matrix[cnt - 1][i]
+ 706                                )
+ 707
+ 708                                AA[j][i] = (D_s[cnt][i] + D_s[cnt - 1][i]) / (dy**2)
+ 709
+ 710                                BB[j][i] = (
+ 711                                    1 / dt_array[cnt][i]
+ 712                                    - (D_s[cnt][i] + D_s[cnt][i + 1]) / (dx**2)
+ 713                                    - (D_s[cnt - 1][i] + D_s[cnt][i]) / (dy**2)
+ 714                                )
+ 715
+ 716                                BB[j][i + 1] = (D_s[cnt][i] + D_s[cnt][i + 1]) / (dx**2)
+ 717                            elif i == m - 1:  # rightmost column
+ 718                                DD[i] = (
+ 719                                    (Qmod[cnt][i] / dt_array[cnt][i])
+ 720                                    + (
+ 721                                        (D_g[cnt][i] + D_g[cnt][i - 1]) / (dx**2)
+ 722                                        + (D_g[cnt - 1][i] + D_g[cnt][i]) / (dy**2)
+ 723                                    )
+ 724                                    * surfactant.concentration_matrix[cnt][i]
+ 725                                    - (D_g[cnt][i] + D_g[cnt][i - 1])
+ 726                                    / (dx**2)
+ 727                                    * surfactant.concentration_matrix[cnt][i - 1]
+ 728                                    - (D_g[cnt][i] + D_g[cnt - 1][i])
+ 729                                    / (dy**2)
+ 730                                    * surfactant.concentration_matrix[cnt - 1][i]
+ 731                                )
+ 732
+ 733                                BB[j][i - 1] = (D_s[cnt][i] + D_s[cnt][i - 1]) / (dx**2)
+ 734
+ 735                                BB[j][i] = (
+ 736                                    1 / dt_array[cnt][i]
+ 737                                    - (D_s[cnt][i] + D_s[cnt][i - 1]) / (dx**2)
+ 738                                    - (D_s[cnt - 1][i] + D_s[cnt][i]) / (dy**2)
+ 739                                )
+ 740
+ 741                                AA[j][i] = (D_s[cnt][i] + D_s[cnt - 1][i]) / (dy**2)
+ 742                            else:
+ 743                                DD[i] = (
+ 744                                    Qmod[cnt][i] / dt_array[cnt][i]
+ 745                                    - f_c[cnt][i]
+ 746                                    * (
+ 747                                        u[cnt][i]
+ 748                                        * (
+ 749                                            polymer.concentration_matrix[cnt][i + 1]
+ 750                                            - polymer.concentration_matrix[cnt][i - 1]
+ 751                                        )
+ 752                                        / (2 * dx)
+ 753                                    )
+ 754                                    - f_g[cnt][i]
+ 755                                    * (
+ 756                                        u[cnt][i]
+ 757                                        * (
+ 758                                            surfactant.concentration_matrix[cnt][i + 1]
+ 759                                            - surfactant.concentration_matrix[cnt][
+ 760                                                i - 1
+ 761                                            ]
+ 762                                        )
+ 763                                        / (2 * dx)
+ 764                                    )
+ 765                                    + (
+ 766                                        (
+ 767                                            D_g[cnt][i + 1]
+ 768                                            + D_g[cnt][i - 1]
+ 769                                            + 2 * D_g[cnt][i]
+ 770                                        )
+ 771                                        / (2 * dx**2)
+ 772                                        + (D_g[cnt][i + 1] + D_g[cnt][i]) / (dy**2)
+ 773                                    )
+ 774                                    * surfactant.concentration_matrix[cnt][i]
+ 775                                    - (D_g[cnt][i + 1] + D_g[cnt][i])
+ 776                                    / (2 * dx**2)
+ 777                                    * surfactant.concentration_matrix[cnt][i + 1]
+ 778                                    - (D_g[cnt][i - 1] + D_g[cnt][i])
+ 779                                    / (2 * dx**2)
+ 780                                    * surfactant.concentration_matrix[cnt][i - 1]
+ 781                                    - (D_g[cnt][i] + D_g[cnt - 1][i])
+ 782                                    / (dy**2)
+ 783                                    * surfactant.concentration_matrix[cnt - 1][i]
+ 784                                )
+ 785
+ 786                                BB[j][i] = (
+ 787                                    1 / dt_array[cnt][i]
+ 788                                    - (
+ 789                                        D_s[cnt][i + 1]
+ 790                                        + D_s[cnt][i - 1]
+ 791                                        + 2 * D_s[cnt][i]
+ 792                                    )
+ 793                                    / (2 * dx**2)
+ 794                                    - (D_s[cnt - 1][i] + D_s[cnt][i]) / (dy**2)
+ 795                                )
+ 796                                BB[j][i - 1] = (D_s[cnt][i - 1] + D_s[cnt][i]) / (
+ 797                                    2 * dx**2
+ 798                                )
+ 799                                BB[j][i + 1] = (D_s[cnt][i + 1] + D_s[cnt][i]) / (
+ 800                                    2 * dx**2
+ 801                                )
+ 802
+ 803                                AA[j][i] = (D_s[cnt][i] + D_s[cnt - 1][i]) / (dy**2)
+ 804
+ 805                        else:
+ 806                            if i == 0:
+ 807                                DD[i] = (
+ 808                                    Qmod[cnt][i] / dt_array[cnt][i]
+ 809                                    - f_c[cnt][i]
+ 810                                    * (
+ 811                                        v[cnt][i]
+ 812                                        * (
+ 813                                            polymer.concentration_matrix[cnt + 1][i]
+ 814                                            - polymer.concentration_matrix[cnt][i]
+ 815                                        )
+ 816                                        / (2 * dy)
+ 817                                    )
+ 818                                    - f_g[cnt][i]
+ 819                                    * (
+ 820                                        v[cnt][i]
+ 821                                        * (
+ 822                                            surfactant.concentration_matrix[cnt + 1][i]
+ 823                                            - surfactant.concentration_matrix[cnt][i]
+ 824                                        )
+ 825                                        / (2 * dy)
+ 826                                    )
+ 827                                    + (
+ 828                                        (D_g[cnt][i] + D_g[cnt][i + 1]) / (dx**2)
+ 829                                        + (
+ 830                                            D_g[cnt - 1][i]
+ 831                                            + 2 * D_g[cnt][i]
+ 832                                            + D_g[cnt + 1][i]
+ 833                                        )
+ 834                                        / (2 * dy**2)
+ 835                                    )
+ 836                                    * surfactant.concentration_matrix[cnt][i]
+ 837                                    - (D_g[cnt][i] + D_g[cnt][i + 1])
+ 838                                    / (dx**2)
+ 839                                    * surfactant.concentration_matrix[cnt][i + 1]
+ 840                                    - (D_g[cnt][i] + D_g[cnt + 1][i])
+ 841                                    / (2 * dy**2)
+ 842                                    * surfactant.concentration_matrix[cnt + 1][i]
+ 843                                    - (D_g[cnt][i] + D_g[cnt - 1][i])
+ 844                                    / (2 * dy**2)
+ 845                                    * surfactant.concentration_matrix[cnt - 1][i]
+ 846                                )
+ 847
+ 848                                AA[j][i] = (D_s[cnt][i] + D_s[cnt - 1][i]) / (2 * dy**2)
+ 849
+ 850                                BB[j][i] = (
+ 851                                    1 / dt_array[cnt][i]
+ 852                                    - (D_s[cnt][i] + D_s[cnt][i + 1]) / (dx**2)
+ 853                                    - (
+ 854                                        D_s[cnt - 1][i]
+ 855                                        + 2 * D_s[cnt][i]
+ 856                                        + D_s[cnt + 1][i]
+ 857                                    )
+ 858                                    / (2 * dy**2)
+ 859                                )
+ 860                                BB[j][i + 1] = (D_s[cnt][i] + D_s[cnt][i + 1]) / (dx**2)
+ 861
+ 862                                CC[j][i] = (D_s[cnt][i] + D_s[cnt + 1][i]) / (2 * dy**2)
+ 863                            elif i == m - 1:
+ 864                                DD[i] = (
+ 865                                    Qmod[cnt][i] / dt_array[cnt][i]
+ 866                                    - f_c[cnt][i]
+ 867                                    * (
+ 868                                        v[cnt][i]
+ 869                                        * (
+ 870                                            polymer.concentration_matrix[cnt + 1][i]
+ 871                                            - polymer.concentration_matrix[cnt][i]
+ 872                                        )
+ 873                                        / (2 * dy)
+ 874                                    )
+ 875                                    - f_g[cnt][i]
+ 876                                    * (
+ 877                                        v[cnt][i]
+ 878                                        * (
+ 879                                            surfactant.concentration_matrix[cnt + 1][i]
+ 880                                            - surfactant.concentration_matrix[cnt][i]
+ 881                                        )
+ 882                                        / (2 * dy)
+ 883                                    )
+ 884                                    + (
+ 885                                        (D_g[cnt][i] + D_g[cnt][i - 1]) / (dx**2)
+ 886                                        + (
+ 887                                            D_g[cnt - 1][i]
+ 888                                            + 2 * D_g[cnt][i]
+ 889                                            + D_g[cnt + 1][i]
+ 890                                        )
+ 891                                        / (2 * dy**2)
+ 892                                    )
+ 893                                    * surfactant.concentration_matrix[cnt][i]
+ 894                                    - (D_g[cnt][i] + D_g[cnt][i - 1])
+ 895                                    / (dx**2)
+ 896                                    * surfactant.concentration_matrix[cnt][i - 1]
+ 897                                    - (D_g[cnt][i] + D_g[cnt + 1][i])
+ 898                                    / (2 * dy**2)
+ 899                                    * surfactant.concentration_matrix[cnt + 1][i]
+ 900                                    - (D_g[cnt][i] + D_g[cnt - 1][i])
+ 901                                    / (2 * dy**2)
+ 902                                    * surfactant.concentration_matrix[cnt - 1][i]
+ 903                                )
+ 904
+ 905                                AA[j][i] = (D_s[cnt][i] + D_s[cnt - 1][i]) / (2 * dy**2)
+ 906
+ 907                                BB[j][i] = (
+ 908                                    1 / dt_array[cnt][i]
+ 909                                    - (D_s[cnt][i] + D_s[cnt][i - 1]) / (dx**2)
+ 910                                    - (
+ 911                                        D_s[cnt - 1][i]
+ 912                                        + 2 * D_s[cnt][i]
+ 913                                        + D_s[cnt + 1][i]
+ 914                                    )
+ 915                                    / (2 * dy**2)
+ 916                                )
+ 917                                BB[j][i - 1] = (D_s[cnt][i] + D_s[cnt][i - 1]) / (dx**2)
+ 918
+ 919                                CC[j][i] = (D_s[cnt][i] + D_s[cnt + 1][i]) / (2 * dy**2)
+ 920                            else:
+ 921                                DD[i] = (
+ 922                                    (Qmod[cnt][i] / dt_array[cnt][i])
+ 923                                    - f_c[cnt][i]
+ 924                                    * (
+ 925                                        u[cnt][i]
+ 926                                        * (
+ 927                                            polymer.concentration_matrix[cnt][i + 1]
+ 928                                            - polymer.concentration_matrix[cnt][i - 1]
+ 929                                        )
+ 930                                        / (2 * dx)
+ 931                                        + v[cnt][i]
+ 932                                        * (
+ 933                                            polymer.concentration_matrix[cnt + 1][i]
+ 934                                            - polymer.concentration_matrix[cnt - 1][i]
+ 935                                        )
+ 936                                        / (2 * dy)
+ 937                                    )
+ 938                                    - f_g[cnt][i]
+ 939                                    * (
+ 940                                        u[cnt][i]
+ 941                                        * (
+ 942                                            surfactant.concentration_matrix[cnt][i + 1]
+ 943                                            - surfactant.concentration_matrix[cnt][
+ 944                                                i - 1
+ 945                                            ]
+ 946                                        )
+ 947                                        / (2 * dx)
+ 948                                        + v[cnt][i]
+ 949                                        * (
+ 950                                            surfactant.concentration_matrix[cnt + 1][i]
+ 951                                            - surfactant.concentration_matrix[cnt - 1][
+ 952                                                i
+ 953                                            ]
+ 954                                        )
+ 955                                        / (2 * dy)
+ 956                                    )
+ 957                                    - (
+ 958                                        D_g[cnt][i + 1]
+ 959                                        / (2 * dx**2)
+ 960                                        * (
+ 961                                            surfactant.concentration_matrix[cnt][i + 1]
+ 962                                            - surfactant.concentration_matrix[cnt][i]
+ 963                                        )
+ 964                                        - D_g[cnt][i - 1]
+ 965                                        / (2 * dx**2)
+ 966                                        * (
+ 967                                            surfactant.concentration_matrix[cnt][i - 1]
+ 968                                            - surfactant.concentration_matrix[cnt][i]
+ 969                                        )
+ 970                                        + D_g[cnt][i - 1]
+ 971                                        / (2 * dx**2)
+ 972                                        * (
+ 973                                            surfactant.concentration_matrix[cnt][i - 1]
+ 974                                            - surfactant.concentration_matrix[cnt][
+ 975                                                i + 1
+ 976                                            ]
+ 977                                        )
+ 978                                        + D_g[cnt + 1][i]
+ 979                                        / (2 * dx**2)
+ 980                                        * (
+ 981                                            surfactant.concentration_matrix[cnt + 1][i]
+ 982                                            - surfactant.concentration_matrix[cnt][i]
+ 983                                        )
+ 984                                        + D_g[cnt - 1][i]
+ 985                                        / (2 * dx**2)
+ 986                                        * (
+ 987                                            surfactant.concentration_matrix[cnt - 1][i]
+ 988                                            - surfactant.concentration_matrix[cnt][i]
+ 989                                        )
+ 990                                        + D_g[cnt][i]
+ 991                                        / (2 * dx**2)
+ 992                                        * (
+ 993                                            surfactant.concentration_matrix[cnt + 1][i]
+ 994                                            - surfactant.concentration_matrix[cnt][i]
+ 995                                        )
+ 996                                    )
+ 997                                )
+ 998                                AA[j][i] = (D_s[cnt - 1][i] + D_s[cnt][i]) / (2 * dy**2)
+ 999
+1000                                CC[j][i] = (D_s[cnt][i] + D_s[cnt + 1][i]) / (2 * dy**2)
+1001
+1002                                BB[j][i] = 1 / dt_array[cnt][i] - (
+1003                                    (1 / (2 * dx**2))
+1004                                    * (D_s[cnt][i - 1] + 2 * D_s[cnt][i] + D_s[cnt][i + 1])
+1005                                    + (1 / (2 * dy**2))
+1006                                    * (
+1007                                        D_s[cnt - 1][i]
+1008                                        + 2 * D_s[cnt][i]
+1009                                        + D_s[cnt + 1][i]
+1010                                    )
+1011                                )
+1012                                BB[j][i + 1] = (D_s[cnt][i] + D_s[cnt][i + 1]) / (
+1013                                    2 * dx**2
+1014                                )
+1015                                BB[j][i - 1] = (D_s[cnt][i - 1] + D_s[cnt][i]) / (
+1016                                    2 * dx**2
+1017                                )
+1018
+1019            if cnt == 0:
+1020                AAA[:n, : 2 * m] = np.hstack([BB, CC])
+1021            elif cnt == n - 1:
+1022                AAA[(m - 1) * n : m * n, (n - 2) * m : n * m] = np.hstack([AA, BB])
+1023            else:
+1024                AAA[cnt * n : (cnt + 1) * n, (cnt - 1) * m : (cnt + 2) * m] = np.hstack(
+1025                    [AA, BB, CC]
+1026                )
+1027
+1028            DDD[cnt * m : (cnt + 1) * m] = DD
+1029            idx += m
+1030
+1031        # Entering the bicgstab for the saturation calculations
+1032        # bicgstab (Biconjugate Gradient Stabilized) - Iterative algorithm to solve large, sparse, and non-symmetric linear systems of the form Ax = b
+1033
+1034        Qnew_flat, info = bicgstab(AAA, DDD, rtol=10 ** (-10), maxiter=600)
+1035        if info != 0:
+1036            import warnings
+1037            warnings.warn(f"BiCGSTAB: convergence issue (info={info}) in water saturation solver")
+1038        Qnew = Qnew_flat = Qnew_flat.reshape(m, n)
+1039
+1040        Qnew[Qnew < 0] = 0
+1041
+1042        self.water_saturation = Qnew
+1043
+1044        return Qmod, varying_parameters
+
+ + +
+
+ +
+ + class + Water: + + + +
+ +
  25class Water:
+  26    """
+  27    Contains the properties and methods for water in the SP-Flooding system
+  28    """
+  29
+  30    def __init__(
+  31        self,
+  32        init_water_saturation: float,
+  33        init_aqueous_saturation: float,
+  34        init_oleic_saturation: float,
+  35        miuw: float,
+  36        miuo: float,
+  37        phi: np.ndarray,
+  38    ):
+  39        """
+  40        Constructor for the ``Water`` class
+  41        """
+  42        self.init_water_saturation = init_water_saturation
+  43        self.init_aqueous_saturation = init_aqueous_saturation
+  44        self.init_oleic_saturation = init_oleic_saturation
+  45        self.miuw = miuw
+  46        self.miuo = miuo
+  47        self.water_saturation = None  # water saturation matrix
+  48        self.viscosity_array = None  # aqueous viscosity matrix
+  49        self.phi = phi
+  50
+  51    _init_water_saturation = None
+  52    @property
+  53    def init_water_saturation(self):
+  54        """
+  55        init_water_saturation (float): initial residual water saturation
+  56        """
+  57        return self._init_water_saturation
+  58    @init_water_saturation.setter
+  59    def init_water_saturation(self, value):
+  60        self._init_water_saturation = value
+  61
+  62    _init_aqueous_saturation = None
+  63    @property
+  64    def init_aqueous_saturation(self):
+  65        """
+  66        init_aqueous_saturation (float): initial residual aqueous phase saturation below critical capillary number (when σ = 0)
+  67        """
+  68        return self._init_aqueous_saturation
+  69    @init_aqueous_saturation.setter
+  70    def init_aqueous_saturation(self, value):
+  71        self._init_aqueous_saturation = value
+  72
+  73    _init_oleic_saturation = None
+  74    @property
+  75    def init_oleic_saturation(self):
+  76        """
+  77        init_oleic_saturation (float): initial residual oil phase saturation below the critical capillary number (when σ = 0)
+  78        """
+  79        return self._init_oleic_saturation
+  80    @init_oleic_saturation.setter
+  81    def init_oleic_saturation(self, value):
+  82        self._init_oleic_saturation = value
+  83
+  84    _miuw = None
+  85    @property
+  86    def miuw(self):
+  87        """
+  88        miuw (float): water viscosity
+  89        """
+  90        return self._miuw
+  91    @miuw.setter
+  92    def miuw(self, value):
+  93        self._miuw = value 
+  94
+  95    _miuo = None
+  96    @property
+  97    def miuo(self):
+  98        """
+  99        miuo (float): oil viscosity
+ 100        """
+ 101        return self._miuo
+ 102    @miuo.setter
+ 103    def miuo(self, value):
+ 104        self._miuo = value 
+ 105
+ 106    _phi = None
+ 107    @property
+ 108    def phi(self):
+ 109        """
+ 110        phi (np.ndarray): porosity matrix
+ 111        """
+ 112        return self._phi
+ 113    @phi.setter
+ 114    def phi(self, value):
+ 115        self._phi = value
+ 116
+ 117    _water_saturation = None
+ 118    @property
+ 119    def water_saturation(self):
+ 120        """
+ 121        water_saturation (np.ndarray): The water saturation matrix being updated using the transport equations
+ 122        """
+ 123        return self._water_saturation
+ 124    @water_saturation.setter
+ 125    def water_saturation(self, value):
+ 126        self._water_saturation = value
+ 127
+ 128    _viscosity_array = None
+ 129    @property
+ 130    def viscosity_array(self):
+ 131        """
+ 132        viscosity_array (np.ndarray): The water viscosity matrix
+ 133        """
+ 134        return self._viscosity_array
+ 135    @viscosity_array.setter
+ 136    def viscosity_array(self, value):
+ 137        self._viscosity_array = value
+ 138
+ 139
+ 140    def initialize(self, grid_shape: tuple):
+ 141        """
+ 142        Initializing 'Water' object properties
+ 143
+ 144        Raises:
+ 145        -------
+ 146            SimuationInputException: Either Intial water saturation and/or porosity matrix not provided for initializing Water object
+ 147
+ 148        Args:
+ 149        -----
+ 150            grid_shape (tuple): the n and m parameters from the 'Grid' class
+ 151        
+ 152        Returns: (Water)
+ 153        ---------------
+ 154            Initializes the Water object
+ 155        """
+ 156        assert self.init_water_saturation is not None, SimulationCalcInputException(
+ 157            "SimuationInputException: Initial water saturation not initialized. Please try again"
+ 158        )
+ 159        assert self.phi is not None, SimulationCalcInputException(
+ 160            "SimuationInputException: porosity matrix not initialized. Please try again"
+ 161        )
+ 162        # getting values for n and m from grid:
+ 163        n, m = grid_shape
+ 164
+ 165        # initializing the water saturation matrix
+ 166        s0 = np.zeros((n + 1, m + 1))
+ 167        D = (self.phi > 1e-10) | (np.abs(self.phi) < 1e-10)
+ 168        s0 = np.logical_not(D).astype(float) + D.astype(float) * (
+ 169            1 - self.init_water_saturation
+ 170        )
+ 171        self.water_saturation = s0
+ 172
+ 173        # initialize the aqueous viscosity matrix:
+ 174        self.viscosity_array = self.miuw * np.ones((n + 1, m + 1))
+ 175
+ 176        return self
+ 177
+ 178    def compute_viscosity(
+ 179        self,
+ 180        grid: Grid,
+ 181        model_type: ModelType,
+ 182        polymer: Polymer,
+ 183        u: np.ndarray | None = None,
+ 184        v: np.ndarray | None = None,
+ 185    ):
+ 186        """
+ 187        Compute aqueous viscosity.
+ 188
+ 189        Raises:
+ 190        -------
+ 191            SimulationCalcInputException: Not all required parameters provided
+ 192        
+ 193        Args:
+ 194        -----
+ 195            grid (Grid): Grid object for deterrmining matrix size
+ 196
+ 197            model_type (enum 'ModelType'): Type of model we are running (Polymer shear thinning ON or OFF)
+ 198
+ 199            polymer (Polymer): holds the information about the polymer in the sim
+ 200
+ 201            u (np.ndarray, None): global pressure matrix. Only needed when shear thinning ON.
+ 202
+ 203            v (np.ndarray, None): velocity matrix. Only needed when shear thinning ON.
+ 204        
+ 205        Returns: (np.ndarray)
+ 206        --------------------
+ 207            Updated aqueous viscosity matrix
+ 208        """
+ 209
+ 210        assert self.viscosity_array is not None, SimulationCalcInputException(
+ 211            "SimuationInputException: aqueous viscosity matrix not initialized. Please try again"
+ 212        )
+ 213        assert polymer is not None and isinstance(
+ 214            polymer, Polymer
+ 215        ), SimulationCalcInputException(
+ 216            "SimuationInputException: polymer object not initialized. \
+ 217                The polymer object must be initialized before updating aqueous viscosity. Please try again."
+ 218        )
+ 219        assert polymer.concentration_matrix is not None, SimulationCalcInputException(
+ 220            "SimuationInputException: Polymer Concentration matrix must be initialized. Please try again..."
+ 221        )
+ 222        assert polymer.shear_rate is not None, SimulationCalcInputException(
+ 223            "SimuationInputException: Polymer Shear Rate matrix must be initialized. Please try again..."
+ 224        )
+ 225        n = np.size(polymer.concentration_matrix, 0)
+ 226        m = np.size(polymer.concentration_matrix, 1)
+ 227        initial_polymer_concentration_scalar = polymer.concetration_scalar
+ 228        if (
+ 229            model_type.value == ModelType.No_Shear_Thinning.value
+ 230        ):  # no shear thinning polymer
+ 231            miuw = SimulationConstants.Water_Viscosity.value
+ 232            if initial_polymer_concentration_scalar == 0:
+ 233                self.viscosity_array = miuw * np.ones((n, m))
+ 234            else:
+ 235                beta1 = SimulationConstants.beta1.value
+ 236                self.viscosity_array = miuw * (1 + beta1 * polymer.concentration_matrix)
+ 237        elif (
+ 238            model_type.value == ModelType.Shear_Thinning_On.value
+ 239        ):  # shear thinning polymer
+ 240            # using the shear rate and polymer coefficients to understand how its viscosity changes
+ 241            assert u is not None, SimulationCalcInputException(
+ 242                "SimuationInputException: variables 'u' not initialized for shear-thinning-on model. Please try again"
+ 243            )
+ 244            assert v is not None, SimulationCalcInputException(
+ 245                "SimuationInputException: variables 'v' not initialized for shear-thinning-on model. Please try again"
+ 246            )
+ 247
+ 248            # constants:
+ 249            rho_water = SimulationConstants.Water_Density.value
+ 250            viscosity_water = SimulationConstants.Water_Viscosity.value
+ 251
+ 252            # relevant parameters for power law equation:
+ 253            w1 = polymer.rho * polymer.concentration_matrix
+ 254            w2 = rho_water * (1 - polymer.concentration_matrix)
+ 255            wppm = (w1 / (w1 + w2)) * (10**6)
+ 256
+ 257            eps = 1e-12
+ 258            wppm_safe = np.maximum(wppm, eps)
+ 259
+ 260            epsilon_val = polymer.e_coeff[0] * wppm_safe ** polymer.e_coeff[1]
+ 261            n_val = np.minimum(polymer.n_coeff[0] * wppm_safe ** polymer.n_coeff[1], 1)
+ 262
+ 263            row = np.size(polymer.concentration_matrix, 0)
+ 264            col = np.size(polymer.concentration_matrix, 1)
+ 265
+ 266            # Compute divergence terms
+ 267            a1 = np.gradient(v, axis=0)
+ 268            a2 = np.gradient(u, axis=1)
+ 269            a3 = np.gradient(u, axis=0)
+ 270            a4 = np.gradient(v, axis=1)
+ 271
+ 272            pi_D = np.abs(-0.25 * (a1 + a2) ** 2 + a3 * a4)
+ 273
+ 274            for ii in range(row):
+ 275                for jj in range(col):
+ 276                    # Applying constraints
+ 277                    self.viscosity_array[ii, jj] = epsilon_val[ii, jj] * (
+ 278                        polymer.shear_rate[ii, jj] ** (n_val[ii, jj] - 1)
+ 279                    )
+ 280                    if self.viscosity_array[ii, jj] < viscosity_water:
+ 281                        self.viscosity_array[ii, jj] = viscosity_water
+ 282                    if self.viscosity_array[ii, jj] > 100:
+ 283                        self.viscosity_array[ii, jj] = 100
+ 284        return self.viscosity_array
+ 285
+ 286    def compute_residual_saturations(
+ 287        self, sigma: np.ndarray, u: np.ndarray, v: np.ndarray
+ 288    ):
+ 289        """
+ 290        Compute swr, sor based on capillary numbers (came from compres.m MATLAB file)
+ 291
+ 292        Args:
+ 293        -----
+ 294            sigma (np.ndarray): interfacial tension (IFT)
+ 295
+ 296            u (np.ndarray): global pressure matrix.
+ 297
+ 298            v (np.ndarray): velocity matrix.
+ 299        
+ 300        Returns: (list)
+ 301        ---------------
+ 302            residual saturation for oil (index 1) and water (index 0) phases
+ 303        """
+ 304        swr0 = self.init_aqueous_saturation
+ 305        sor0 = self.init_oleic_saturation
+ 306
+ 307        Nco0 = 1.44e-4
+ 308        Nca0 = 1.44e-4
+ 309
+ 310        vel_mag = np.sqrt(np.matmul(u, u) + np.matmul(v, v), dtype=np.complex128)
+ 311        nca = (vel_mag * self.viscosity_array) / sigma
+ 312        nco = (vel_mag * self.miuo) / sigma
+ 313
+ 314        Nca = np.linalg.norm(nca)
+ 315        Nco = np.linalg.norm(nco)
+ 316
+ 317        sor = sor0 * (Nco0 / Nco) ** 0.5213 if Nco >= Nco0 else sor0
+ 318        swr = swr0 * (Nca0 / Nca) ** 0.1534 if Nca >= Nca0 else swr0
+ 319
+ 320        return [swr, sor]  # [residual aqueous saturation, residual oil saturation]
+ 321
+ 322    def compute_mobility(
+ 323        self,
+ 324        c: np.ndarray,
+ 325        sor: float,
+ 326        swr: float,
+ 327        aqueous: bool,
+ 328        rel_permeability_formula: RelativePermeabilityFormula,
+ 329        modified_water_saturation: np.ndarray | None = None,
+ 330    ):
+ 331        """
+ 332        Computing mobility (made using the compmob.m MATLAB file)
+ 333        
+ 334        Raise:
+ 335        ------
+ 336            SimulationCalcInputException: Not all required arguments are not provided
+ 337
+ 338        Args:
+ 339        -----
+ 340            c (np.ndarray): polymer concentration matrix
+ 341
+ 342            sor (float): residual saturation oil phase
+ 343
+ 344            swr (float): residual saturation water phase
+ 345
+ 346            aqueous (bool): boolean for whether we are solving for aqoeous or oleic mobility
+ 347
+ 348            rel_permeability_formula (enum 'RelativePermeabilityFormula'): Select the type of relative Permeability formula from the ``RelativePermeabilityFormula`` Enum
+ 349
+ 350            surfactant_conc (float): scalar quantity of the initial surfactant concentration
+ 351        
+ 352        Returns: (np.ndarray)
+ 353        ---------------------
+ 354            aqueous or oleic mobility (depending on the 'aqueous' parameter)
+ 355        """
+ 356        assert self.water_saturation is not None, SimulationCalcInputException(
+ 357            "SimuationInputException: water saturation matrix not initialized. Please try again"
+ 358        )
+ 359        assert self.viscosity_array is not None, SimulationCalcInputException(
+ 360            "SimuationInputException: viscosity matrix not initialized. Please try again"
+ 361        )
+ 362        s = (
+ 363            self.water_saturation
+ 364            if (modified_water_saturation is None)
+ 365            else modified_water_saturation
+ 366        )
+ 367        miua = self.viscosity_array
+ 368        if (
+ 369            rel_permeability_formula.value
+ 370            == RelativePermeabilityFormula.CoreyTypeEquation.value
+ 371        ):
+ 372            nsw0 = (s - self.init_aqueous_saturation) / (
+ 373                1 - self.init_aqueous_saturation
+ 374            )
+ 375            nso0 = (s - self.init_aqueous_saturation) / (
+ 376                1 - self.init_aqueous_saturation - self.init_oleic_saturation
+ 377            )
+ 378            krw0 = nsw0**3.5
+ 379            kro0 = ((1 - nso0) ** 2) * (1 - nso0**1.5)
+ 380        else:
+ 381            nsw = (s - swr) / (1 - swr)
+ 382            nso = (s - swr) / (1 - swr - sor)
+ 383            krw0 = nsw * (2.5 * swr * (nsw**2 - 1) + 1)
+ 384            kro0 = (1 - nso) * (1 - 5 * sor * nso)
+ 385
+ 386        return krw0 / miua if aqueous else kro0 / self.miuo
+ 387
+ 388    def compute_water_saturation(
+ 389        self,
+ 390        grid: Grid,
+ 391        surfactant: Surfactant,
+ 392        polymer: Polymer,
+ 393        u: np.ndarray,
+ 394        v: np.ndarray,
+ 395        xmod: np.ndarray,
+ 396        ymod: np.ndarray,
+ 397        const_parameters: dict,
+ 398        varying_parameters: dict,
+ 399    ):
+ 400        """
+ 401        Solving saturation equation (comes from part of the nmmoc_surf_mod_neumann.m file that
+ 402        is for calculating the water saturation)
+ 403        
+ 404        Raises:
+ 405        -------
+ 406            SimulationCalcInputException: If water saturation matrix is None
+ 407
+ 408        Args:
+ 409        -----
+ 410            grid (Grid): the 'Grid' object
+ 411
+ 412            surfactant (Surfactant): The surfactant object
+ 413
+ 414            polymer (Polymer): The polymer object
+ 415
+ 416            u (np.ndarray): global pressure matrix
+ 417
+ 418            v (np.ndarray): velocity matrix
+ 419
+ 420            xmod (np.ndarray): x-dimension coordinate points for formulating the 'Qmod' matrix
+ 421
+ 422            ymod (np.ndarray): y-dimension coordinate points for formulating the 'Qmod' matrix
+ 423
+ 424            const_parameters (dict): constant parameters used in the method
+ 425
+ 426            varying_parameters (dict): parameters whose values can change
+ 427        
+ 428        Returns: (np.ndarray, dict)
+ 429        -----------------------------
+ 430            Updates the ``water_saturation`` matrix and ``varying_parameters`` dict
+ 431        """
+ 432        # Assert statements to ensure that all parameters are property initialized:
+ 433        assert self.water_saturation is not None, SimulationCalcInputException(
+ 434            "SimuationInputException: water saturation matrix not initialized. Please try again"
+ 435        )
+ 436        # Required constants:
+ 437        dx = const_parameters["FD_grid_constants"]["dx"]
+ 438        dy = const_parameters["FD_grid_constants"]["dy"]
+ 439        x = const_parameters["FD_grid_constants"]["x"]
+ 440        y = const_parameters["FD_grid_constants"]["y"]
+ 441        m = const_parameters["FD_grid_constants"]["m"]
+ 442        n = const_parameters["FD_grid_constants"]["n"]
+ 443        phi = self.phi
+ 444        omega1 = const_parameters["Pc_constants"]["omega1"]
+ 445        omega2 = const_parameters["Pc_constants"]["omega2"]
+ 446        Q = np.copy(self.water_saturation)
+ 447        g1 = const_parameters["inlet_total_flow"]
+ 448        KK = const_parameters["KK"]
+ 449        relative_permeability_formula = const_parameters[
+ 450            "relative_permeability_formula"
+ 451        ]
+ 452
+ 453        # retrieving relevant parameters for updating the water saturation
+ 454        ## Time Step:
+ 455        dt = const_parameters["FD_grid_constants"]["dt"]
+ 456        dt_array = const_parameters["FD_grid_constants"]["dt_matrix"]
+ 457
+ 458        # Determining Qmod matrix
+ 459        x1d = x[0, :]
+ 460        y1d = y[:, 0]
+ 461        x_sorted = np.all(np.diff(x1d) > 0)
+ 462        y_sorted = np.all(np.diff(y1d) > 0)
+ 463
+ 464        # reorder Q if a dimension isn't sorted
+ 465        if not x_sorted:
+ 466            x_sort_idx = np.argsort(x1d)
+ 467            x1d = x1d[x_sort_idx]
+ 468            Q = Q[:, x_sort_idx]  # Sort columns of S
+ 469        if not y_sorted:
+ 470            y_sort_idx = np.argsort(y1d)
+ 471            y1d = y1d[y_sort_idx]
+ 472            Q = Q[y_sort_idx, :]  # Sort rows of Q
+ 473
+ 474        interp_func = sp.interpolate.RegularGridInterpolator(
+ 475            (y1d, x1d), Q, method="linear", bounds_error=False, fill_value=None
+ 476        )
+ 477
+ 478        query_points = np.stack([ymod.ravel(), xmod.ravel()], axis=-1)
+ 479        Qmod = interp_func(query_points).reshape(xmod.shape)
+ 480
+ 481        swr = varying_parameters["swr"]
+ 482        sor = varying_parameters["sor"]
+ 483        nsw = (Qmod - swr) / (1 - swr)
+ 484        nso = (Qmod - swr) / (1 - swr - sor)
+ 485        varying_parameters["nsw"] = nsw
+ 486        varying_parameters["nso"] = nso
+ 487
+ 488        ## fractional flow and derivatives
+ 489        assert polymer.concentration_matrix is not None, SimulationCalcInputException(
+ 490            "SimulationCalcInputError:UnknownPolymerConcentrationMatrix"
+ 491        )
+ 492        lambda_a = self.compute_mobility(
+ 493            c=polymer.concentration_matrix,
+ 494            sor=float(sor),
+ 495            swr=float(swr),
+ 496            aqueous=True,
+ 497            rel_permeability_formula=relative_permeability_formula,
+ 498            modified_water_saturation=Qmod,
+ 499        )
+ 500        lambda_o = self.compute_mobility(
+ 501            c=polymer.concentration_matrix,
+ 502            sor=float(sor),
+ 503            swr=float(swr),
+ 504            aqueous=False,
+ 505            rel_permeability_formula=relative_permeability_formula,
+ 506            modified_water_saturation=Qmod,
+ 507        )
+ 508        lambda_total = lambda_a + lambda_o
+ 509        varying_parameters["mobility_parameters"] = {
+ 510            "lambda_a": lambda_a,
+ 511            "lambda_o": lambda_o,
+ 512            "lambda_total": lambda_total,
+ 513        }
+ 514        ## fractional flow calculations
+ 515        f = lambda_a / lambda_total
+ 516        assert KK is not None, SimulationCalcInputException(
+ 517            "SimulationCalcInputError:UnknownPermeabilityTensor"
+ 518        )
+ 519        D = KK * lambda_o * f
+ 520        assert self.viscosity_array is not None, SimulationCalcInputException(
+ 521            "SimulationCalcInputError:UnkownWaterViscosityMatrix"
+ 522        )
+ 523        varying_parameters["fractional_flow_parameters"] = {"f": f, "D": D}
+ 524        pc = (
+ 525            surfactant.eval_IFT
+ 526            * const_parameters["Pc_constants"]["omega2"]
+ 527            * np.sqrt(const_parameters["porosity"])
+ 528        ) / (
+ 529            np.matmul(
+ 530                KK ** (0.5),
+ 531                fractional_matrix_power(
+ 532                    1 - nso, 1 / const_parameters["Pc_constants"]["omega1"]
+ 533                ),
+ 534            )
+ 535        )
+ 536        pc_s = pc / (const_parameters["Pc_constants"]["omega1"] * (1 - nso))
+ 537        pc_g = (pc / surfactant.eval_IFT) * surfactant.eval_dIFT_dGamma + pc_s
+ 538        varying_parameters["capillary_pressure_and_derivatives"] = {
+ 539            "pc": pc,
+ 540            "dpc_ds": pc_s,
+ 541            "dpc_dg": pc_g,
+ 542        }
+ 543        f_c = (-1 * (lambda_o * lambda_a * self.miuo)) / (
+ 544            (lambda_total**2) * self.viscosity_array
+ 545        )
+ 546        f_g = (
+ 547            varying_parameters["relative_permeability_derivatives"]["dkra_dg"]
+ 548            * lambda_o
+ 549        ) / ((lambda_total**2) * self.viscosity_array)
+ 550        varying_parameters["fractional_flow_derivatives"]["df_dc"] = f_c
+ 551        varying_parameters["fractional_flow_derivatives"]["df_dg"] = f_g
+ 552        D_g = D * pc_g
+ 553        D_s = D * pc_s
+ 554        varying_parameters["fractional_flow_derivatives"]["dD_dg"] = D_g
+ 555        varying_parameters["fractional_flow_derivatives"]["dD_ds"] = D_s
+ 556
+ 557        # Updating coefficients with interpolated saturations
+ 558        idx = 1
+ 559        AAA = np.zeros((n * m, n * m))
+ 560        DDD = np.zeros((n * m, 1))
+ 561
+ 562        while (
+ 563            idx <= m * (n - 1) + 1
+ 564            and surfactant.concentration_matrix is not None
+ 565            and polymer.concentration_matrix is not None
+ 566        ):
+ 567            cnt = (idx - 1) // m  # cnt = 0, 1, 2, ... for idx = 1, m+1, 2m+1, 3m+1, ...
+ 568            BB = np.zeros((n, m))
+ 569            AA = np.copy(BB)
+ 570            CC = np.copy(BB)
+ 571            DD = np.zeros((m, 1))
+ 572
+ 573            #'cnt+1' in matlab is 'cnt' in python as matlab indexes from 1 but python indexes from 0
+ 574            for i in range(m):
+ 575                for j in range(n):
+ 576                    if j == i:
+ 577                        if idx == 1:
+ 578                            if i == 0:  # first/left column
+ 579                                DD[i] = (
+ 580                                    (Qmod[cnt][i] / dt_array[cnt][i])
+ 581                                    + g1 * (1 - f[cnt][i])
+ 582                                    + (
+ 583                                        (D_g[cnt][i] + D_g[cnt][i + 1]) / (dx**2)
+ 584                                        + (D_g[cnt + 1][i] + D_g[cnt][i]) / (dy**2)
+ 585                                    )
+ 586                                    * surfactant.concentration_matrix[cnt][i]
+ 587                                    - (D_g[cnt][i] + D_g[cnt][i + 1])
+ 588                                    / (dx**2)
+ 589                                    * surfactant.concentration_matrix[cnt][i + 1]
+ 590                                    - (D_g[cnt][i] + D_g[cnt + 2][i])
+ 591                                    / (dy**2)
+ 592                                    * surfactant.concentration_matrix[cnt + 1][i]
+ 593                                )
+ 594
+ 595                                CC[j][i] = (D_s[cnt][i] + D_s[cnt + 1][i]) / (dy**2)
+ 596
+ 597                                BB[j][i] = (
+ 598                                    1 / dt_array[cnt][i]
+ 599                                    - (D_s[cnt][i] + D_s[cnt][i + 1]) / (dx**2)
+ 600                                    - (D_s[cnt + 1][i] + D_s[cnt][i]) / (dy**2)
+ 601                                )
+ 602
+ 603                                BB[j][i + 1] = (D_s[cnt][i] + D_s[cnt][i + 1]) / (dx**2)
+ 604                            elif i == m - 1:  # last/rightmost column
+ 605                                DD[i] = (
+ 606                                    Qmod[cnt][i] / dt_array[cnt][i]
+ 607                                    + (
+ 608                                        (D_g[cnt][i] + D_g[cnt][i - 1]) / (dx**2)
+ 609                                        + (D_g[cnt + 1][i] + D_g[cnt][i]) / (dy**2)
+ 610                                    )
+ 611                                    * surfactant.concentration_matrix[cnt][i]
+ 612                                    - (D_g[cnt][i] + D_g[cnt][i - 1])
+ 613                                    / (dx**2)
+ 614                                    * surfactant.concentration_matrix[cnt][i - 1]
+ 615                                    - (D_g[cnt][i] + D_g[cnt + 1][i])
+ 616                                    / (dy**2)
+ 617                                    * surfactant.concentration_matrix[cnt + 1][i]
+ 618                                )
+ 619
+ 620                                BB[j][i - 1] = (D_s[cnt][i] + D_s[cnt][i - 1]) / (dx**2)
+ 621
+ 622                                BB[j][i] = (
+ 623                                    1 / dt_array[cnt][i]
+ 624                                    - (D_s[cnt][i] + D_s[cnt][i - 1]) / (dx**2)
+ 625                                    - (D_s[cnt + 1][i] + D_s[cnt][i]) / (dy**2)
+ 626                                )
+ 627
+ 628                                CC[j][i] = (D_s[cnt][i] + D_s[cnt + 1][i]) / (dy**2)
+ 629                            else: # FIXME: stopped here!
+ 630                                DD[i] = (
+ 631                                    Qmod[cnt][i] / dt_array[cnt][i]
+ 632                                    - f_c[cnt][i]
+ 633                                    * (
+ 634                                        u[cnt][i]
+ 635                                        * (
+ 636                                            polymer.concentration_matrix[cnt][i + 1]
+ 637                                            - polymer.concentration_matrix[cnt][i - 1]
+ 638                                        )
+ 639                                        / (2 * dx)
+ 640                                    )
+ 641                                    - f_g[cnt][i]
+ 642                                    * (
+ 643                                        u[cnt][i]
+ 644                                        * (
+ 645                                            surfactant.concentration_matrix[cnt][i + 1]
+ 646                                            - surfactant.concentration_matrix[cnt][
+ 647                                                i - 1
+ 648                                            ]
+ 649                                        )
+ 650                                        / (2 * dx)
+ 651                                    )
+ 652                                    + (
+ 653                                        (
+ 654                                            D_g[cnt][i + 1]
+ 655                                            + D_g[cnt][i - 1]
+ 656                                            + 2 * D_g[cnt][i]
+ 657                                        )
+ 658                                        / (2 * dx**2)
+ 659                                        + (D_g[cnt][i + 1] + D_g[cnt][i]) / (dy**2)
+ 660                                    )
+ 661                                    * surfactant.concentration_matrix[cnt][i]
+ 662                                    - (D_g[cnt][i + 1] + D_g[cnt][i])
+ 663                                    / (2 * dx**2)
+ 664                                    * surfactant.concentration_matrix[cnt][i + 1]
+ 665                                    - (D_g[cnt][i - 1] + D_g[cnt][i])
+ 666                                    / (2 * dx**2)
+ 667                                    * surfactant.concentration_matrix[cnt][i - 1]
+ 668                                    - (D_g[cnt][i] + D_g[cnt + 1][i])
+ 669                                    / (dy**2)
+ 670                                    * surfactant.concentration_matrix[cnt + 1][i]
+ 671                                )
+ 672
+ 673                                BB[j][i] = (
+ 674                                    1 / dt_array[cnt][i]
+ 675                                    - (
+ 676                                        D_s[cnt][i + 1]
+ 677                                        + D_s[cnt][i - 1]
+ 678                                        + 2 * D_s[cnt][i]
+ 679                                    )
+ 680                                    / (2 * dx**2)
+ 681                                    - (D_s[cnt + 1][i] + D_s[cnt][i]) / (dy**2)
+ 682                                )
+ 683                                BB[j][i - 1] = (D_s[cnt][i - 1] + D_s[cnt][i]) / (
+ 684                                    2 * dx**2
+ 685                                )
+ 686                                BB[j][i + 1] = (D_s[cnt][i + 1] + D_s[cnt][i]) / (
+ 687                                    2 * dx**2
+ 688                                )
+ 689
+ 690                                CC[j][i] = (D_s[cnt][i] + D_s[cnt + 1][i]) / (dy**2)
+ 691
+ 692                        elif idx == (m) * (n - 1) + 1:  # topmost row of grid
+ 693                            if i == 0:  # leftmost column
+ 694                                DD[i] = (
+ 695                                    (Qmod[cnt][i] / dt_array[cnt][i])
+ 696                                    + (
+ 697                                        (D_g[cnt][i] + D_g[cnt][i + 1]) / (dx**2)
+ 698                                        + (D_g[cnt - 1][i] + D_g[cnt][i]) / (dy**2)
+ 699                                    )
+ 700                                    * surfactant.concentration_matrix[cnt][i]
+ 701                                    - (D_g[cnt][i] + D_g[cnt][i + 1])
+ 702                                    / (dx**2)
+ 703                                    * surfactant.concentration_matrix[cnt][i + 1]
+ 704                                    - (D_g[cnt][i] + D_g[cnt - 1][i])
+ 705                                    / (dy**2)
+ 706                                    * surfactant.concentration_matrix[cnt - 1][i]
+ 707                                )
+ 708
+ 709                                AA[j][i] = (D_s[cnt][i] + D_s[cnt - 1][i]) / (dy**2)
+ 710
+ 711                                BB[j][i] = (
+ 712                                    1 / dt_array[cnt][i]
+ 713                                    - (D_s[cnt][i] + D_s[cnt][i + 1]) / (dx**2)
+ 714                                    - (D_s[cnt - 1][i] + D_s[cnt][i]) / (dy**2)
+ 715                                )
+ 716
+ 717                                BB[j][i + 1] = (D_s[cnt][i] + D_s[cnt][i + 1]) / (dx**2)
+ 718                            elif i == m - 1:  # rightmost column
+ 719                                DD[i] = (
+ 720                                    (Qmod[cnt][i] / dt_array[cnt][i])
+ 721                                    + (
+ 722                                        (D_g[cnt][i] + D_g[cnt][i - 1]) / (dx**2)
+ 723                                        + (D_g[cnt - 1][i] + D_g[cnt][i]) / (dy**2)
+ 724                                    )
+ 725                                    * surfactant.concentration_matrix[cnt][i]
+ 726                                    - (D_g[cnt][i] + D_g[cnt][i - 1])
+ 727                                    / (dx**2)
+ 728                                    * surfactant.concentration_matrix[cnt][i - 1]
+ 729                                    - (D_g[cnt][i] + D_g[cnt - 1][i])
+ 730                                    / (dy**2)
+ 731                                    * surfactant.concentration_matrix[cnt - 1][i]
+ 732                                )
+ 733
+ 734                                BB[j][i - 1] = (D_s[cnt][i] + D_s[cnt][i - 1]) / (dx**2)
+ 735
+ 736                                BB[j][i] = (
+ 737                                    1 / dt_array[cnt][i]
+ 738                                    - (D_s[cnt][i] + D_s[cnt][i - 1]) / (dx**2)
+ 739                                    - (D_s[cnt - 1][i] + D_s[cnt][i]) / (dy**2)
+ 740                                )
+ 741
+ 742                                AA[j][i] = (D_s[cnt][i] + D_s[cnt - 1][i]) / (dy**2)
+ 743                            else:
+ 744                                DD[i] = (
+ 745                                    Qmod[cnt][i] / dt_array[cnt][i]
+ 746                                    - f_c[cnt][i]
+ 747                                    * (
+ 748                                        u[cnt][i]
+ 749                                        * (
+ 750                                            polymer.concentration_matrix[cnt][i + 1]
+ 751                                            - polymer.concentration_matrix[cnt][i - 1]
+ 752                                        )
+ 753                                        / (2 * dx)
+ 754                                    )
+ 755                                    - f_g[cnt][i]
+ 756                                    * (
+ 757                                        u[cnt][i]
+ 758                                        * (
+ 759                                            surfactant.concentration_matrix[cnt][i + 1]
+ 760                                            - surfactant.concentration_matrix[cnt][
+ 761                                                i - 1
+ 762                                            ]
+ 763                                        )
+ 764                                        / (2 * dx)
+ 765                                    )
+ 766                                    + (
+ 767                                        (
+ 768                                            D_g[cnt][i + 1]
+ 769                                            + D_g[cnt][i - 1]
+ 770                                            + 2 * D_g[cnt][i]
+ 771                                        )
+ 772                                        / (2 * dx**2)
+ 773                                        + (D_g[cnt][i + 1] + D_g[cnt][i]) / (dy**2)
+ 774                                    )
+ 775                                    * surfactant.concentration_matrix[cnt][i]
+ 776                                    - (D_g[cnt][i + 1] + D_g[cnt][i])
+ 777                                    / (2 * dx**2)
+ 778                                    * surfactant.concentration_matrix[cnt][i + 1]
+ 779                                    - (D_g[cnt][i - 1] + D_g[cnt][i])
+ 780                                    / (2 * dx**2)
+ 781                                    * surfactant.concentration_matrix[cnt][i - 1]
+ 782                                    - (D_g[cnt][i] + D_g[cnt - 1][i])
+ 783                                    / (dy**2)
+ 784                                    * surfactant.concentration_matrix[cnt - 1][i]
+ 785                                )
+ 786
+ 787                                BB[j][i] = (
+ 788                                    1 / dt_array[cnt][i]
+ 789                                    - (
+ 790                                        D_s[cnt][i + 1]
+ 791                                        + D_s[cnt][i - 1]
+ 792                                        + 2 * D_s[cnt][i]
+ 793                                    )
+ 794                                    / (2 * dx**2)
+ 795                                    - (D_s[cnt - 1][i] + D_s[cnt][i]) / (dy**2)
+ 796                                )
+ 797                                BB[j][i - 1] = (D_s[cnt][i - 1] + D_s[cnt][i]) / (
+ 798                                    2 * dx**2
+ 799                                )
+ 800                                BB[j][i + 1] = (D_s[cnt][i + 1] + D_s[cnt][i]) / (
+ 801                                    2 * dx**2
+ 802                                )
+ 803
+ 804                                AA[j][i] = (D_s[cnt][i] + D_s[cnt - 1][i]) / (dy**2)
+ 805
+ 806                        else:
+ 807                            if i == 0:
+ 808                                DD[i] = (
+ 809                                    Qmod[cnt][i] / dt_array[cnt][i]
+ 810                                    - f_c[cnt][i]
+ 811                                    * (
+ 812                                        v[cnt][i]
+ 813                                        * (
+ 814                                            polymer.concentration_matrix[cnt + 1][i]
+ 815                                            - polymer.concentration_matrix[cnt][i]
+ 816                                        )
+ 817                                        / (2 * dy)
+ 818                                    )
+ 819                                    - f_g[cnt][i]
+ 820                                    * (
+ 821                                        v[cnt][i]
+ 822                                        * (
+ 823                                            surfactant.concentration_matrix[cnt + 1][i]
+ 824                                            - surfactant.concentration_matrix[cnt][i]
+ 825                                        )
+ 826                                        / (2 * dy)
+ 827                                    )
+ 828                                    + (
+ 829                                        (D_g[cnt][i] + D_g[cnt][i + 1]) / (dx**2)
+ 830                                        + (
+ 831                                            D_g[cnt - 1][i]
+ 832                                            + 2 * D_g[cnt][i]
+ 833                                            + D_g[cnt + 1][i]
+ 834                                        )
+ 835                                        / (2 * dy**2)
+ 836                                    )
+ 837                                    * surfactant.concentration_matrix[cnt][i]
+ 838                                    - (D_g[cnt][i] + D_g[cnt][i + 1])
+ 839                                    / (dx**2)
+ 840                                    * surfactant.concentration_matrix[cnt][i + 1]
+ 841                                    - (D_g[cnt][i] + D_g[cnt + 1][i])
+ 842                                    / (2 * dy**2)
+ 843                                    * surfactant.concentration_matrix[cnt + 1][i]
+ 844                                    - (D_g[cnt][i] + D_g[cnt - 1][i])
+ 845                                    / (2 * dy**2)
+ 846                                    * surfactant.concentration_matrix[cnt - 1][i]
+ 847                                )
+ 848
+ 849                                AA[j][i] = (D_s[cnt][i] + D_s[cnt - 1][i]) / (2 * dy**2)
+ 850
+ 851                                BB[j][i] = (
+ 852                                    1 / dt_array[cnt][i]
+ 853                                    - (D_s[cnt][i] + D_s[cnt][i + 1]) / (dx**2)
+ 854                                    - (
+ 855                                        D_s[cnt - 1][i]
+ 856                                        + 2 * D_s[cnt][i]
+ 857                                        + D_s[cnt + 1][i]
+ 858                                    )
+ 859                                    / (2 * dy**2)
+ 860                                )
+ 861                                BB[j][i + 1] = (D_s[cnt][i] + D_s[cnt][i + 1]) / (dx**2)
+ 862
+ 863                                CC[j][i] = (D_s[cnt][i] + D_s[cnt + 1][i]) / (2 * dy**2)
+ 864                            elif i == m - 1:
+ 865                                DD[i] = (
+ 866                                    Qmod[cnt][i] / dt_array[cnt][i]
+ 867                                    - f_c[cnt][i]
+ 868                                    * (
+ 869                                        v[cnt][i]
+ 870                                        * (
+ 871                                            polymer.concentration_matrix[cnt + 1][i]
+ 872                                            - polymer.concentration_matrix[cnt][i]
+ 873                                        )
+ 874                                        / (2 * dy)
+ 875                                    )
+ 876                                    - f_g[cnt][i]
+ 877                                    * (
+ 878                                        v[cnt][i]
+ 879                                        * (
+ 880                                            surfactant.concentration_matrix[cnt + 1][i]
+ 881                                            - surfactant.concentration_matrix[cnt][i]
+ 882                                        )
+ 883                                        / (2 * dy)
+ 884                                    )
+ 885                                    + (
+ 886                                        (D_g[cnt][i] + D_g[cnt][i - 1]) / (dx**2)
+ 887                                        + (
+ 888                                            D_g[cnt - 1][i]
+ 889                                            + 2 * D_g[cnt][i]
+ 890                                            + D_g[cnt + 1][i]
+ 891                                        )
+ 892                                        / (2 * dy**2)
+ 893                                    )
+ 894                                    * surfactant.concentration_matrix[cnt][i]
+ 895                                    - (D_g[cnt][i] + D_g[cnt][i - 1])
+ 896                                    / (dx**2)
+ 897                                    * surfactant.concentration_matrix[cnt][i - 1]
+ 898                                    - (D_g[cnt][i] + D_g[cnt + 1][i])
+ 899                                    / (2 * dy**2)
+ 900                                    * surfactant.concentration_matrix[cnt + 1][i]
+ 901                                    - (D_g[cnt][i] + D_g[cnt - 1][i])
+ 902                                    / (2 * dy**2)
+ 903                                    * surfactant.concentration_matrix[cnt - 1][i]
+ 904                                )
+ 905
+ 906                                AA[j][i] = (D_s[cnt][i] + D_s[cnt - 1][i]) / (2 * dy**2)
+ 907
+ 908                                BB[j][i] = (
+ 909                                    1 / dt_array[cnt][i]
+ 910                                    - (D_s[cnt][i] + D_s[cnt][i - 1]) / (dx**2)
+ 911                                    - (
+ 912                                        D_s[cnt - 1][i]
+ 913                                        + 2 * D_s[cnt][i]
+ 914                                        + D_s[cnt + 1][i]
+ 915                                    )
+ 916                                    / (2 * dy**2)
+ 917                                )
+ 918                                BB[j][i - 1] = (D_s[cnt][i] + D_s[cnt][i - 1]) / (dx**2)
+ 919
+ 920                                CC[j][i] = (D_s[cnt][i] + D_s[cnt + 1][i]) / (2 * dy**2)
+ 921                            else:
+ 922                                DD[i] = (
+ 923                                    (Qmod[cnt][i] / dt_array[cnt][i])
+ 924                                    - f_c[cnt][i]
+ 925                                    * (
+ 926                                        u[cnt][i]
+ 927                                        * (
+ 928                                            polymer.concentration_matrix[cnt][i + 1]
+ 929                                            - polymer.concentration_matrix[cnt][i - 1]
+ 930                                        )
+ 931                                        / (2 * dx)
+ 932                                        + v[cnt][i]
+ 933                                        * (
+ 934                                            polymer.concentration_matrix[cnt + 1][i]
+ 935                                            - polymer.concentration_matrix[cnt - 1][i]
+ 936                                        )
+ 937                                        / (2 * dy)
+ 938                                    )
+ 939                                    - f_g[cnt][i]
+ 940                                    * (
+ 941                                        u[cnt][i]
+ 942                                        * (
+ 943                                            surfactant.concentration_matrix[cnt][i + 1]
+ 944                                            - surfactant.concentration_matrix[cnt][
+ 945                                                i - 1
+ 946                                            ]
+ 947                                        )
+ 948                                        / (2 * dx)
+ 949                                        + v[cnt][i]
+ 950                                        * (
+ 951                                            surfactant.concentration_matrix[cnt + 1][i]
+ 952                                            - surfactant.concentration_matrix[cnt - 1][
+ 953                                                i
+ 954                                            ]
+ 955                                        )
+ 956                                        / (2 * dy)
+ 957                                    )
+ 958                                    - (
+ 959                                        D_g[cnt][i + 1]
+ 960                                        / (2 * dx**2)
+ 961                                        * (
+ 962                                            surfactant.concentration_matrix[cnt][i + 1]
+ 963                                            - surfactant.concentration_matrix[cnt][i]
+ 964                                        )
+ 965                                        - D_g[cnt][i - 1]
+ 966                                        / (2 * dx**2)
+ 967                                        * (
+ 968                                            surfactant.concentration_matrix[cnt][i - 1]
+ 969                                            - surfactant.concentration_matrix[cnt][i]
+ 970                                        )
+ 971                                        + D_g[cnt][i - 1]
+ 972                                        / (2 * dx**2)
+ 973                                        * (
+ 974                                            surfactant.concentration_matrix[cnt][i - 1]
+ 975                                            - surfactant.concentration_matrix[cnt][
+ 976                                                i + 1
+ 977                                            ]
+ 978                                        )
+ 979                                        + D_g[cnt + 1][i]
+ 980                                        / (2 * dx**2)
+ 981                                        * (
+ 982                                            surfactant.concentration_matrix[cnt + 1][i]
+ 983                                            - surfactant.concentration_matrix[cnt][i]
+ 984                                        )
+ 985                                        + D_g[cnt - 1][i]
+ 986                                        / (2 * dx**2)
+ 987                                        * (
+ 988                                            surfactant.concentration_matrix[cnt - 1][i]
+ 989                                            - surfactant.concentration_matrix[cnt][i]
+ 990                                        )
+ 991                                        + D_g[cnt][i]
+ 992                                        / (2 * dx**2)
+ 993                                        * (
+ 994                                            surfactant.concentration_matrix[cnt + 1][i]
+ 995                                            - surfactant.concentration_matrix[cnt][i]
+ 996                                        )
+ 997                                    )
+ 998                                )
+ 999                                AA[j][i] = (D_s[cnt - 1][i] + D_s[cnt][i]) / (2 * dy**2)
+1000
+1001                                CC[j][i] = (D_s[cnt][i] + D_s[cnt + 1][i]) / (2 * dy**2)
+1002
+1003                                BB[j][i] = 1 / dt_array[cnt][i] - (
+1004                                    (1 / (2 * dx**2))
+1005                                    * (D_s[cnt][i - 1] + 2 * D_s[cnt][i] + D_s[cnt][i + 1])
+1006                                    + (1 / (2 * dy**2))
+1007                                    * (
+1008                                        D_s[cnt - 1][i]
+1009                                        + 2 * D_s[cnt][i]
+1010                                        + D_s[cnt + 1][i]
+1011                                    )
+1012                                )
+1013                                BB[j][i + 1] = (D_s[cnt][i] + D_s[cnt][i + 1]) / (
+1014                                    2 * dx**2
+1015                                )
+1016                                BB[j][i - 1] = (D_s[cnt][i - 1] + D_s[cnt][i]) / (
+1017                                    2 * dx**2
+1018                                )
+1019
+1020            if cnt == 0:
+1021                AAA[:n, : 2 * m] = np.hstack([BB, CC])
+1022            elif cnt == n - 1:
+1023                AAA[(m - 1) * n : m * n, (n - 2) * m : n * m] = np.hstack([AA, BB])
+1024            else:
+1025                AAA[cnt * n : (cnt + 1) * n, (cnt - 1) * m : (cnt + 2) * m] = np.hstack(
+1026                    [AA, BB, CC]
+1027                )
+1028
+1029            DDD[cnt * m : (cnt + 1) * m] = DD
+1030            idx += m
+1031
+1032        # Entering the bicgstab for the saturation calculations
+1033        # bicgstab (Biconjugate Gradient Stabilized) - Iterative algorithm to solve large, sparse, and non-symmetric linear systems of the form Ax = b
+1034
+1035        Qnew_flat, info = bicgstab(AAA, DDD, rtol=10 ** (-10), maxiter=600)
+1036        if info != 0:
+1037            import warnings
+1038            warnings.warn(f"BiCGSTAB: convergence issue (info={info}) in water saturation solver")
+1039        Qnew = Qnew_flat = Qnew_flat.reshape(m, n)
+1040
+1041        Qnew[Qnew < 0] = 0
+1042
+1043        self.water_saturation = Qnew
+1044
+1045        return Qmod, varying_parameters
+
+ + +

Contains the properties and methods for water in the SP-Flooding system

+
+ + +
+ +
+ + Water( init_water_saturation: float, init_aqueous_saturation: float, init_oleic_saturation: float, miuw: float, miuo: float, phi: numpy.ndarray) + + + +
+ +
30    def __init__(
+31        self,
+32        init_water_saturation: float,
+33        init_aqueous_saturation: float,
+34        init_oleic_saturation: float,
+35        miuw: float,
+36        miuo: float,
+37        phi: np.ndarray,
+38    ):
+39        """
+40        Constructor for the ``Water`` class
+41        """
+42        self.init_water_saturation = init_water_saturation
+43        self.init_aqueous_saturation = init_aqueous_saturation
+44        self.init_oleic_saturation = init_oleic_saturation
+45        self.miuw = miuw
+46        self.miuo = miuo
+47        self.water_saturation = None  # water saturation matrix
+48        self.viscosity_array = None  # aqueous viscosity matrix
+49        self.phi = phi
+
+ + +

Constructor for the Water class

+
+ + +
+
+ +
+ init_water_saturation + + + +
+ +
52    @property
+53    def init_water_saturation(self):
+54        """
+55        init_water_saturation (float): initial residual water saturation
+56        """
+57        return self._init_water_saturation
+
+ + +

init_water_saturation (float): initial residual water saturation

+
+ + +
+
+ +
+ init_aqueous_saturation + + + +
+ +
63    @property
+64    def init_aqueous_saturation(self):
+65        """
+66        init_aqueous_saturation (float): initial residual aqueous phase saturation below critical capillary number (when σ = 0)
+67        """
+68        return self._init_aqueous_saturation
+
+ + +

init_aqueous_saturation (float): initial residual aqueous phase saturation below critical capillary number (when σ = 0)

+
+ + +
+
+ +
+ init_oleic_saturation + + + +
+ +
74    @property
+75    def init_oleic_saturation(self):
+76        """
+77        init_oleic_saturation (float): initial residual oil phase saturation below the critical capillary number (when σ = 0)
+78        """
+79        return self._init_oleic_saturation
+
+ + +

init_oleic_saturation (float): initial residual oil phase saturation below the critical capillary number (when σ = 0)

+
+ + +
+
+ +
+ miuw + + + +
+ +
85    @property
+86    def miuw(self):
+87        """
+88        miuw (float): water viscosity
+89        """
+90        return self._miuw
+
+ + +

miuw (float): water viscosity

+
+ + +
+
+ +
+ miuo + + + +
+ +
 96    @property
+ 97    def miuo(self):
+ 98        """
+ 99        miuo (float): oil viscosity
+100        """
+101        return self._miuo
+
+ + +

miuo (float): oil viscosity

+
+ + +
+
+ +
+ water_saturation + + + +
+ +
118    @property
+119    def water_saturation(self):
+120        """
+121        water_saturation (np.ndarray): The water saturation matrix being updated using the transport equations
+122        """
+123        return self._water_saturation
+
+ + +

water_saturation (np.ndarray): The water saturation matrix being updated using the transport equations

+
+ + +
+
+ +
+ viscosity_array + + + +
+ +
129    @property
+130    def viscosity_array(self):
+131        """
+132        viscosity_array (np.ndarray): The water viscosity matrix
+133        """
+134        return self._viscosity_array
+
+ + +

viscosity_array (np.ndarray): The water viscosity matrix

+
+ + +
+
+ +
+ phi + + + +
+ +
107    @property
+108    def phi(self):
+109        """
+110        phi (np.ndarray): porosity matrix
+111        """
+112        return self._phi
+
+ + +

phi (np.ndarray): porosity matrix

+
+ + +
+
+ +
+ + def + initialize(self, grid_shape: tuple): + + + +
+ +
140    def initialize(self, grid_shape: tuple):
+141        """
+142        Initializing 'Water' object properties
+143
+144        Raises:
+145        -------
+146            SimuationInputException: Either Intial water saturation and/or porosity matrix not provided for initializing Water object
+147
+148        Args:
+149        -----
+150            grid_shape (tuple): the n and m parameters from the 'Grid' class
+151        
+152        Returns: (Water)
+153        ---------------
+154            Initializes the Water object
+155        """
+156        assert self.init_water_saturation is not None, SimulationCalcInputException(
+157            "SimuationInputException: Initial water saturation not initialized. Please try again"
+158        )
+159        assert self.phi is not None, SimulationCalcInputException(
+160            "SimuationInputException: porosity matrix not initialized. Please try again"
+161        )
+162        # getting values for n and m from grid:
+163        n, m = grid_shape
+164
+165        # initializing the water saturation matrix
+166        s0 = np.zeros((n + 1, m + 1))
+167        D = (self.phi > 1e-10) | (np.abs(self.phi) < 1e-10)
+168        s0 = np.logical_not(D).astype(float) + D.astype(float) * (
+169            1 - self.init_water_saturation
+170        )
+171        self.water_saturation = s0
+172
+173        # initialize the aqueous viscosity matrix:
+174        self.viscosity_array = self.miuw * np.ones((n + 1, m + 1))
+175
+176        return self
+
+ + +

Initializing 'Water' object properties

+ +

Raises:

+ +
SimuationInputException: Either Intial water saturation and/or porosity matrix not provided for initializing Water object
+
+ +

Args:

+ +
grid_shape (tuple): the n and m parameters from the 'Grid' class
+
+ +

Returns: (Water)

+ +
Initializes the Water object
+
+
+ + +
+
+ +
+ + def + compute_viscosity( self, grid: lib.grid.Grid, model_type: lib.enumerations.ModelType, polymer: lib.polymer.Polymer, u: numpy.ndarray | None = None, v: numpy.ndarray | None = None): + + + +
+ +
178    def compute_viscosity(
+179        self,
+180        grid: Grid,
+181        model_type: ModelType,
+182        polymer: Polymer,
+183        u: np.ndarray | None = None,
+184        v: np.ndarray | None = None,
+185    ):
+186        """
+187        Compute aqueous viscosity.
+188
+189        Raises:
+190        -------
+191            SimulationCalcInputException: Not all required parameters provided
+192        
+193        Args:
+194        -----
+195            grid (Grid): Grid object for deterrmining matrix size
+196
+197            model_type (enum 'ModelType'): Type of model we are running (Polymer shear thinning ON or OFF)
+198
+199            polymer (Polymer): holds the information about the polymer in the sim
+200
+201            u (np.ndarray, None): global pressure matrix. Only needed when shear thinning ON.
+202
+203            v (np.ndarray, None): velocity matrix. Only needed when shear thinning ON.
+204        
+205        Returns: (np.ndarray)
+206        --------------------
+207            Updated aqueous viscosity matrix
+208        """
+209
+210        assert self.viscosity_array is not None, SimulationCalcInputException(
+211            "SimuationInputException: aqueous viscosity matrix not initialized. Please try again"
+212        )
+213        assert polymer is not None and isinstance(
+214            polymer, Polymer
+215        ), SimulationCalcInputException(
+216            "SimuationInputException: polymer object not initialized. \
+217                The polymer object must be initialized before updating aqueous viscosity. Please try again."
+218        )
+219        assert polymer.concentration_matrix is not None, SimulationCalcInputException(
+220            "SimuationInputException: Polymer Concentration matrix must be initialized. Please try again..."
+221        )
+222        assert polymer.shear_rate is not None, SimulationCalcInputException(
+223            "SimuationInputException: Polymer Shear Rate matrix must be initialized. Please try again..."
+224        )
+225        n = np.size(polymer.concentration_matrix, 0)
+226        m = np.size(polymer.concentration_matrix, 1)
+227        initial_polymer_concentration_scalar = polymer.concetration_scalar
+228        if (
+229            model_type.value == ModelType.No_Shear_Thinning.value
+230        ):  # no shear thinning polymer
+231            miuw = SimulationConstants.Water_Viscosity.value
+232            if initial_polymer_concentration_scalar == 0:
+233                self.viscosity_array = miuw * np.ones((n, m))
+234            else:
+235                beta1 = SimulationConstants.beta1.value
+236                self.viscosity_array = miuw * (1 + beta1 * polymer.concentration_matrix)
+237        elif (
+238            model_type.value == ModelType.Shear_Thinning_On.value
+239        ):  # shear thinning polymer
+240            # using the shear rate and polymer coefficients to understand how its viscosity changes
+241            assert u is not None, SimulationCalcInputException(
+242                "SimuationInputException: variables 'u' not initialized for shear-thinning-on model. Please try again"
+243            )
+244            assert v is not None, SimulationCalcInputException(
+245                "SimuationInputException: variables 'v' not initialized for shear-thinning-on model. Please try again"
+246            )
+247
+248            # constants:
+249            rho_water = SimulationConstants.Water_Density.value
+250            viscosity_water = SimulationConstants.Water_Viscosity.value
+251
+252            # relevant parameters for power law equation:
+253            w1 = polymer.rho * polymer.concentration_matrix
+254            w2 = rho_water * (1 - polymer.concentration_matrix)
+255            wppm = (w1 / (w1 + w2)) * (10**6)
+256
+257            eps = 1e-12
+258            wppm_safe = np.maximum(wppm, eps)
+259
+260            epsilon_val = polymer.e_coeff[0] * wppm_safe ** polymer.e_coeff[1]
+261            n_val = np.minimum(polymer.n_coeff[0] * wppm_safe ** polymer.n_coeff[1], 1)
+262
+263            row = np.size(polymer.concentration_matrix, 0)
+264            col = np.size(polymer.concentration_matrix, 1)
+265
+266            # Compute divergence terms
+267            a1 = np.gradient(v, axis=0)
+268            a2 = np.gradient(u, axis=1)
+269            a3 = np.gradient(u, axis=0)
+270            a4 = np.gradient(v, axis=1)
+271
+272            pi_D = np.abs(-0.25 * (a1 + a2) ** 2 + a3 * a4)
+273
+274            for ii in range(row):
+275                for jj in range(col):
+276                    # Applying constraints
+277                    self.viscosity_array[ii, jj] = epsilon_val[ii, jj] * (
+278                        polymer.shear_rate[ii, jj] ** (n_val[ii, jj] - 1)
+279                    )
+280                    if self.viscosity_array[ii, jj] < viscosity_water:
+281                        self.viscosity_array[ii, jj] = viscosity_water
+282                    if self.viscosity_array[ii, jj] > 100:
+283                        self.viscosity_array[ii, jj] = 100
+284        return self.viscosity_array
+
+ + +

Compute aqueous viscosity.

+ +

Raises:

+ +
SimulationCalcInputException: Not all required parameters provided
+
+ +

Args:

+ +
grid (Grid): Grid object for deterrmining matrix size
+
+model_type (enum 'ModelType'): Type of model we are running (Polymer shear thinning ON or OFF)
+
+polymer (Polymer): holds the information about the polymer in the sim
+
+u (np.ndarray, None): global pressure matrix. Only needed when shear thinning ON.
+
+v (np.ndarray, None): velocity matrix. Only needed when shear thinning ON.
+
+ +

Returns: (np.ndarray)

+ +
Updated aqueous viscosity matrix
+
+
+ + +
+
+ +
+ + def + compute_residual_saturations(self, sigma: numpy.ndarray, u: numpy.ndarray, v: numpy.ndarray): + + + +
+ +
286    def compute_residual_saturations(
+287        self, sigma: np.ndarray, u: np.ndarray, v: np.ndarray
+288    ):
+289        """
+290        Compute swr, sor based on capillary numbers (came from compres.m MATLAB file)
+291
+292        Args:
+293        -----
+294            sigma (np.ndarray): interfacial tension (IFT)
+295
+296            u (np.ndarray): global pressure matrix.
+297
+298            v (np.ndarray): velocity matrix.
+299        
+300        Returns: (list)
+301        ---------------
+302            residual saturation for oil (index 1) and water (index 0) phases
+303        """
+304        swr0 = self.init_aqueous_saturation
+305        sor0 = self.init_oleic_saturation
+306
+307        Nco0 = 1.44e-4
+308        Nca0 = 1.44e-4
+309
+310        vel_mag = np.sqrt(np.matmul(u, u) + np.matmul(v, v), dtype=np.complex128)
+311        nca = (vel_mag * self.viscosity_array) / sigma
+312        nco = (vel_mag * self.miuo) / sigma
+313
+314        Nca = np.linalg.norm(nca)
+315        Nco = np.linalg.norm(nco)
+316
+317        sor = sor0 * (Nco0 / Nco) ** 0.5213 if Nco >= Nco0 else sor0
+318        swr = swr0 * (Nca0 / Nca) ** 0.1534 if Nca >= Nca0 else swr0
+319
+320        return [swr, sor]  # [residual aqueous saturation, residual oil saturation]
+
+ + +

Compute swr, sor based on capillary numbers (came from compres.m MATLAB file)

+ +

Args:

+ +
sigma (np.ndarray): interfacial tension (IFT)
+
+u (np.ndarray): global pressure matrix.
+
+v (np.ndarray): velocity matrix.
+
+ +

Returns: (list)

+ +
residual saturation for oil (index 1) and water (index 0) phases
+
+
+ + +
+
+ +
+ + def + compute_mobility( self, c: numpy.ndarray, sor: float, swr: float, aqueous: bool, rel_permeability_formula: lib.enumerations.RelativePermeabilityFormula, modified_water_saturation: numpy.ndarray | None = None): + + + +
+ +
322    def compute_mobility(
+323        self,
+324        c: np.ndarray,
+325        sor: float,
+326        swr: float,
+327        aqueous: bool,
+328        rel_permeability_formula: RelativePermeabilityFormula,
+329        modified_water_saturation: np.ndarray | None = None,
+330    ):
+331        """
+332        Computing mobility (made using the compmob.m MATLAB file)
+333        
+334        Raise:
+335        ------
+336            SimulationCalcInputException: Not all required arguments are not provided
+337
+338        Args:
+339        -----
+340            c (np.ndarray): polymer concentration matrix
+341
+342            sor (float): residual saturation oil phase
+343
+344            swr (float): residual saturation water phase
+345
+346            aqueous (bool): boolean for whether we are solving for aqoeous or oleic mobility
+347
+348            rel_permeability_formula (enum 'RelativePermeabilityFormula'): Select the type of relative Permeability formula from the ``RelativePermeabilityFormula`` Enum
+349
+350            surfactant_conc (float): scalar quantity of the initial surfactant concentration
+351        
+352        Returns: (np.ndarray)
+353        ---------------------
+354            aqueous or oleic mobility (depending on the 'aqueous' parameter)
+355        """
+356        assert self.water_saturation is not None, SimulationCalcInputException(
+357            "SimuationInputException: water saturation matrix not initialized. Please try again"
+358        )
+359        assert self.viscosity_array is not None, SimulationCalcInputException(
+360            "SimuationInputException: viscosity matrix not initialized. Please try again"
+361        )
+362        s = (
+363            self.water_saturation
+364            if (modified_water_saturation is None)
+365            else modified_water_saturation
+366        )
+367        miua = self.viscosity_array
+368        if (
+369            rel_permeability_formula.value
+370            == RelativePermeabilityFormula.CoreyTypeEquation.value
+371        ):
+372            nsw0 = (s - self.init_aqueous_saturation) / (
+373                1 - self.init_aqueous_saturation
+374            )
+375            nso0 = (s - self.init_aqueous_saturation) / (
+376                1 - self.init_aqueous_saturation - self.init_oleic_saturation
+377            )
+378            krw0 = nsw0**3.5
+379            kro0 = ((1 - nso0) ** 2) * (1 - nso0**1.5)
+380        else:
+381            nsw = (s - swr) / (1 - swr)
+382            nso = (s - swr) / (1 - swr - sor)
+383            krw0 = nsw * (2.5 * swr * (nsw**2 - 1) + 1)
+384            kro0 = (1 - nso) * (1 - 5 * sor * nso)
+385
+386        return krw0 / miua if aqueous else kro0 / self.miuo
+
+ + +

Computing mobility (made using the compmob.m MATLAB file)

+ +

Raise:

+ +
SimulationCalcInputException: Not all required arguments are not provided
+
+ +

Args:

+ +
c (np.ndarray): polymer concentration matrix
+
+sor (float): residual saturation oil phase
+
+swr (float): residual saturation water phase
+
+aqueous (bool): boolean for whether we are solving for aqoeous or oleic mobility
+
+rel_permeability_formula (enum 'RelativePermeabilityFormula'): Select the type of relative Permeability formula from the ``RelativePermeabilityFormula`` Enum
+
+surfactant_conc (float): scalar quantity of the initial surfactant concentration
+
+ +

Returns: (np.ndarray)

+ +
aqueous or oleic mobility (depending on the 'aqueous' parameter)
+
+
+ + +
+
+ +
+ + def + compute_water_saturation( self, grid: lib.grid.Grid, surfactant: lib.surfactant.Surfactant, polymer: lib.polymer.Polymer, u: numpy.ndarray, v: numpy.ndarray, xmod: numpy.ndarray, ymod: numpy.ndarray, const_parameters: dict, varying_parameters: dict): + + + +
+ +
 388    def compute_water_saturation(
+ 389        self,
+ 390        grid: Grid,
+ 391        surfactant: Surfactant,
+ 392        polymer: Polymer,
+ 393        u: np.ndarray,
+ 394        v: np.ndarray,
+ 395        xmod: np.ndarray,
+ 396        ymod: np.ndarray,
+ 397        const_parameters: dict,
+ 398        varying_parameters: dict,
+ 399    ):
+ 400        """
+ 401        Solving saturation equation (comes from part of the nmmoc_surf_mod_neumann.m file that
+ 402        is for calculating the water saturation)
+ 403        
+ 404        Raises:
+ 405        -------
+ 406            SimulationCalcInputException: If water saturation matrix is None
+ 407
+ 408        Args:
+ 409        -----
+ 410            grid (Grid): the 'Grid' object
+ 411
+ 412            surfactant (Surfactant): The surfactant object
+ 413
+ 414            polymer (Polymer): The polymer object
+ 415
+ 416            u (np.ndarray): global pressure matrix
+ 417
+ 418            v (np.ndarray): velocity matrix
+ 419
+ 420            xmod (np.ndarray): x-dimension coordinate points for formulating the 'Qmod' matrix
+ 421
+ 422            ymod (np.ndarray): y-dimension coordinate points for formulating the 'Qmod' matrix
+ 423
+ 424            const_parameters (dict): constant parameters used in the method
+ 425
+ 426            varying_parameters (dict): parameters whose values can change
+ 427        
+ 428        Returns: (np.ndarray, dict)
+ 429        -----------------------------
+ 430            Updates the ``water_saturation`` matrix and ``varying_parameters`` dict
+ 431        """
+ 432        # Assert statements to ensure that all parameters are property initialized:
+ 433        assert self.water_saturation is not None, SimulationCalcInputException(
+ 434            "SimuationInputException: water saturation matrix not initialized. Please try again"
+ 435        )
+ 436        # Required constants:
+ 437        dx = const_parameters["FD_grid_constants"]["dx"]
+ 438        dy = const_parameters["FD_grid_constants"]["dy"]
+ 439        x = const_parameters["FD_grid_constants"]["x"]
+ 440        y = const_parameters["FD_grid_constants"]["y"]
+ 441        m = const_parameters["FD_grid_constants"]["m"]
+ 442        n = const_parameters["FD_grid_constants"]["n"]
+ 443        phi = self.phi
+ 444        omega1 = const_parameters["Pc_constants"]["omega1"]
+ 445        omega2 = const_parameters["Pc_constants"]["omega2"]
+ 446        Q = np.copy(self.water_saturation)
+ 447        g1 = const_parameters["inlet_total_flow"]
+ 448        KK = const_parameters["KK"]
+ 449        relative_permeability_formula = const_parameters[
+ 450            "relative_permeability_formula"
+ 451        ]
+ 452
+ 453        # retrieving relevant parameters for updating the water saturation
+ 454        ## Time Step:
+ 455        dt = const_parameters["FD_grid_constants"]["dt"]
+ 456        dt_array = const_parameters["FD_grid_constants"]["dt_matrix"]
+ 457
+ 458        # Determining Qmod matrix
+ 459        x1d = x[0, :]
+ 460        y1d = y[:, 0]
+ 461        x_sorted = np.all(np.diff(x1d) > 0)
+ 462        y_sorted = np.all(np.diff(y1d) > 0)
+ 463
+ 464        # reorder Q if a dimension isn't sorted
+ 465        if not x_sorted:
+ 466            x_sort_idx = np.argsort(x1d)
+ 467            x1d = x1d[x_sort_idx]
+ 468            Q = Q[:, x_sort_idx]  # Sort columns of S
+ 469        if not y_sorted:
+ 470            y_sort_idx = np.argsort(y1d)
+ 471            y1d = y1d[y_sort_idx]
+ 472            Q = Q[y_sort_idx, :]  # Sort rows of Q
+ 473
+ 474        interp_func = sp.interpolate.RegularGridInterpolator(
+ 475            (y1d, x1d), Q, method="linear", bounds_error=False, fill_value=None
+ 476        )
+ 477
+ 478        query_points = np.stack([ymod.ravel(), xmod.ravel()], axis=-1)
+ 479        Qmod = interp_func(query_points).reshape(xmod.shape)
+ 480
+ 481        swr = varying_parameters["swr"]
+ 482        sor = varying_parameters["sor"]
+ 483        nsw = (Qmod - swr) / (1 - swr)
+ 484        nso = (Qmod - swr) / (1 - swr - sor)
+ 485        varying_parameters["nsw"] = nsw
+ 486        varying_parameters["nso"] = nso
+ 487
+ 488        ## fractional flow and derivatives
+ 489        assert polymer.concentration_matrix is not None, SimulationCalcInputException(
+ 490            "SimulationCalcInputError:UnknownPolymerConcentrationMatrix"
+ 491        )
+ 492        lambda_a = self.compute_mobility(
+ 493            c=polymer.concentration_matrix,
+ 494            sor=float(sor),
+ 495            swr=float(swr),
+ 496            aqueous=True,
+ 497            rel_permeability_formula=relative_permeability_formula,
+ 498            modified_water_saturation=Qmod,
+ 499        )
+ 500        lambda_o = self.compute_mobility(
+ 501            c=polymer.concentration_matrix,
+ 502            sor=float(sor),
+ 503            swr=float(swr),
+ 504            aqueous=False,
+ 505            rel_permeability_formula=relative_permeability_formula,
+ 506            modified_water_saturation=Qmod,
+ 507        )
+ 508        lambda_total = lambda_a + lambda_o
+ 509        varying_parameters["mobility_parameters"] = {
+ 510            "lambda_a": lambda_a,
+ 511            "lambda_o": lambda_o,
+ 512            "lambda_total": lambda_total,
+ 513        }
+ 514        ## fractional flow calculations
+ 515        f = lambda_a / lambda_total
+ 516        assert KK is not None, SimulationCalcInputException(
+ 517            "SimulationCalcInputError:UnknownPermeabilityTensor"
+ 518        )
+ 519        D = KK * lambda_o * f
+ 520        assert self.viscosity_array is not None, SimulationCalcInputException(
+ 521            "SimulationCalcInputError:UnkownWaterViscosityMatrix"
+ 522        )
+ 523        varying_parameters["fractional_flow_parameters"] = {"f": f, "D": D}
+ 524        pc = (
+ 525            surfactant.eval_IFT
+ 526            * const_parameters["Pc_constants"]["omega2"]
+ 527            * np.sqrt(const_parameters["porosity"])
+ 528        ) / (
+ 529            np.matmul(
+ 530                KK ** (0.5),
+ 531                fractional_matrix_power(
+ 532                    1 - nso, 1 / const_parameters["Pc_constants"]["omega1"]
+ 533                ),
+ 534            )
+ 535        )
+ 536        pc_s = pc / (const_parameters["Pc_constants"]["omega1"] * (1 - nso))
+ 537        pc_g = (pc / surfactant.eval_IFT) * surfactant.eval_dIFT_dGamma + pc_s
+ 538        varying_parameters["capillary_pressure_and_derivatives"] = {
+ 539            "pc": pc,
+ 540            "dpc_ds": pc_s,
+ 541            "dpc_dg": pc_g,
+ 542        }
+ 543        f_c = (-1 * (lambda_o * lambda_a * self.miuo)) / (
+ 544            (lambda_total**2) * self.viscosity_array
+ 545        )
+ 546        f_g = (
+ 547            varying_parameters["relative_permeability_derivatives"]["dkra_dg"]
+ 548            * lambda_o
+ 549        ) / ((lambda_total**2) * self.viscosity_array)
+ 550        varying_parameters["fractional_flow_derivatives"]["df_dc"] = f_c
+ 551        varying_parameters["fractional_flow_derivatives"]["df_dg"] = f_g
+ 552        D_g = D * pc_g
+ 553        D_s = D * pc_s
+ 554        varying_parameters["fractional_flow_derivatives"]["dD_dg"] = D_g
+ 555        varying_parameters["fractional_flow_derivatives"]["dD_ds"] = D_s
+ 556
+ 557        # Updating coefficients with interpolated saturations
+ 558        idx = 1
+ 559        AAA = np.zeros((n * m, n * m))
+ 560        DDD = np.zeros((n * m, 1))
+ 561
+ 562        while (
+ 563            idx <= m * (n - 1) + 1
+ 564            and surfactant.concentration_matrix is not None
+ 565            and polymer.concentration_matrix is not None
+ 566        ):
+ 567            cnt = (idx - 1) // m  # cnt = 0, 1, 2, ... for idx = 1, m+1, 2m+1, 3m+1, ...
+ 568            BB = np.zeros((n, m))
+ 569            AA = np.copy(BB)
+ 570            CC = np.copy(BB)
+ 571            DD = np.zeros((m, 1))
+ 572
+ 573            #'cnt+1' in matlab is 'cnt' in python as matlab indexes from 1 but python indexes from 0
+ 574            for i in range(m):
+ 575                for j in range(n):
+ 576                    if j == i:
+ 577                        if idx == 1:
+ 578                            if i == 0:  # first/left column
+ 579                                DD[i] = (
+ 580                                    (Qmod[cnt][i] / dt_array[cnt][i])
+ 581                                    + g1 * (1 - f[cnt][i])
+ 582                                    + (
+ 583                                        (D_g[cnt][i] + D_g[cnt][i + 1]) / (dx**2)
+ 584                                        + (D_g[cnt + 1][i] + D_g[cnt][i]) / (dy**2)
+ 585                                    )
+ 586                                    * surfactant.concentration_matrix[cnt][i]
+ 587                                    - (D_g[cnt][i] + D_g[cnt][i + 1])
+ 588                                    / (dx**2)
+ 589                                    * surfactant.concentration_matrix[cnt][i + 1]
+ 590                                    - (D_g[cnt][i] + D_g[cnt + 2][i])
+ 591                                    / (dy**2)
+ 592                                    * surfactant.concentration_matrix[cnt + 1][i]
+ 593                                )
+ 594
+ 595                                CC[j][i] = (D_s[cnt][i] + D_s[cnt + 1][i]) / (dy**2)
+ 596
+ 597                                BB[j][i] = (
+ 598                                    1 / dt_array[cnt][i]
+ 599                                    - (D_s[cnt][i] + D_s[cnt][i + 1]) / (dx**2)
+ 600                                    - (D_s[cnt + 1][i] + D_s[cnt][i]) / (dy**2)
+ 601                                )
+ 602
+ 603                                BB[j][i + 1] = (D_s[cnt][i] + D_s[cnt][i + 1]) / (dx**2)
+ 604                            elif i == m - 1:  # last/rightmost column
+ 605                                DD[i] = (
+ 606                                    Qmod[cnt][i] / dt_array[cnt][i]
+ 607                                    + (
+ 608                                        (D_g[cnt][i] + D_g[cnt][i - 1]) / (dx**2)
+ 609                                        + (D_g[cnt + 1][i] + D_g[cnt][i]) / (dy**2)
+ 610                                    )
+ 611                                    * surfactant.concentration_matrix[cnt][i]
+ 612                                    - (D_g[cnt][i] + D_g[cnt][i - 1])
+ 613                                    / (dx**2)
+ 614                                    * surfactant.concentration_matrix[cnt][i - 1]
+ 615                                    - (D_g[cnt][i] + D_g[cnt + 1][i])
+ 616                                    / (dy**2)
+ 617                                    * surfactant.concentration_matrix[cnt + 1][i]
+ 618                                )
+ 619
+ 620                                BB[j][i - 1] = (D_s[cnt][i] + D_s[cnt][i - 1]) / (dx**2)
+ 621
+ 622                                BB[j][i] = (
+ 623                                    1 / dt_array[cnt][i]
+ 624                                    - (D_s[cnt][i] + D_s[cnt][i - 1]) / (dx**2)
+ 625                                    - (D_s[cnt + 1][i] + D_s[cnt][i]) / (dy**2)
+ 626                                )
+ 627
+ 628                                CC[j][i] = (D_s[cnt][i] + D_s[cnt + 1][i]) / (dy**2)
+ 629                            else: # FIXME: stopped here!
+ 630                                DD[i] = (
+ 631                                    Qmod[cnt][i] / dt_array[cnt][i]
+ 632                                    - f_c[cnt][i]
+ 633                                    * (
+ 634                                        u[cnt][i]
+ 635                                        * (
+ 636                                            polymer.concentration_matrix[cnt][i + 1]
+ 637                                            - polymer.concentration_matrix[cnt][i - 1]
+ 638                                        )
+ 639                                        / (2 * dx)
+ 640                                    )
+ 641                                    - f_g[cnt][i]
+ 642                                    * (
+ 643                                        u[cnt][i]
+ 644                                        * (
+ 645                                            surfactant.concentration_matrix[cnt][i + 1]
+ 646                                            - surfactant.concentration_matrix[cnt][
+ 647                                                i - 1
+ 648                                            ]
+ 649                                        )
+ 650                                        / (2 * dx)
+ 651                                    )
+ 652                                    + (
+ 653                                        (
+ 654                                            D_g[cnt][i + 1]
+ 655                                            + D_g[cnt][i - 1]
+ 656                                            + 2 * D_g[cnt][i]
+ 657                                        )
+ 658                                        / (2 * dx**2)
+ 659                                        + (D_g[cnt][i + 1] + D_g[cnt][i]) / (dy**2)
+ 660                                    )
+ 661                                    * surfactant.concentration_matrix[cnt][i]
+ 662                                    - (D_g[cnt][i + 1] + D_g[cnt][i])
+ 663                                    / (2 * dx**2)
+ 664                                    * surfactant.concentration_matrix[cnt][i + 1]
+ 665                                    - (D_g[cnt][i - 1] + D_g[cnt][i])
+ 666                                    / (2 * dx**2)
+ 667                                    * surfactant.concentration_matrix[cnt][i - 1]
+ 668                                    - (D_g[cnt][i] + D_g[cnt + 1][i])
+ 669                                    / (dy**2)
+ 670                                    * surfactant.concentration_matrix[cnt + 1][i]
+ 671                                )
+ 672
+ 673                                BB[j][i] = (
+ 674                                    1 / dt_array[cnt][i]
+ 675                                    - (
+ 676                                        D_s[cnt][i + 1]
+ 677                                        + D_s[cnt][i - 1]
+ 678                                        + 2 * D_s[cnt][i]
+ 679                                    )
+ 680                                    / (2 * dx**2)
+ 681                                    - (D_s[cnt + 1][i] + D_s[cnt][i]) / (dy**2)
+ 682                                )
+ 683                                BB[j][i - 1] = (D_s[cnt][i - 1] + D_s[cnt][i]) / (
+ 684                                    2 * dx**2
+ 685                                )
+ 686                                BB[j][i + 1] = (D_s[cnt][i + 1] + D_s[cnt][i]) / (
+ 687                                    2 * dx**2
+ 688                                )
+ 689
+ 690                                CC[j][i] = (D_s[cnt][i] + D_s[cnt + 1][i]) / (dy**2)
+ 691
+ 692                        elif idx == (m) * (n - 1) + 1:  # topmost row of grid
+ 693                            if i == 0:  # leftmost column
+ 694                                DD[i] = (
+ 695                                    (Qmod[cnt][i] / dt_array[cnt][i])
+ 696                                    + (
+ 697                                        (D_g[cnt][i] + D_g[cnt][i + 1]) / (dx**2)
+ 698                                        + (D_g[cnt - 1][i] + D_g[cnt][i]) / (dy**2)
+ 699                                    )
+ 700                                    * surfactant.concentration_matrix[cnt][i]
+ 701                                    - (D_g[cnt][i] + D_g[cnt][i + 1])
+ 702                                    / (dx**2)
+ 703                                    * surfactant.concentration_matrix[cnt][i + 1]
+ 704                                    - (D_g[cnt][i] + D_g[cnt - 1][i])
+ 705                                    / (dy**2)
+ 706                                    * surfactant.concentration_matrix[cnt - 1][i]
+ 707                                )
+ 708
+ 709                                AA[j][i] = (D_s[cnt][i] + D_s[cnt - 1][i]) / (dy**2)
+ 710
+ 711                                BB[j][i] = (
+ 712                                    1 / dt_array[cnt][i]
+ 713                                    - (D_s[cnt][i] + D_s[cnt][i + 1]) / (dx**2)
+ 714                                    - (D_s[cnt - 1][i] + D_s[cnt][i]) / (dy**2)
+ 715                                )
+ 716
+ 717                                BB[j][i + 1] = (D_s[cnt][i] + D_s[cnt][i + 1]) / (dx**2)
+ 718                            elif i == m - 1:  # rightmost column
+ 719                                DD[i] = (
+ 720                                    (Qmod[cnt][i] / dt_array[cnt][i])
+ 721                                    + (
+ 722                                        (D_g[cnt][i] + D_g[cnt][i - 1]) / (dx**2)
+ 723                                        + (D_g[cnt - 1][i] + D_g[cnt][i]) / (dy**2)
+ 724                                    )
+ 725                                    * surfactant.concentration_matrix[cnt][i]
+ 726                                    - (D_g[cnt][i] + D_g[cnt][i - 1])
+ 727                                    / (dx**2)
+ 728                                    * surfactant.concentration_matrix[cnt][i - 1]
+ 729                                    - (D_g[cnt][i] + D_g[cnt - 1][i])
+ 730                                    / (dy**2)
+ 731                                    * surfactant.concentration_matrix[cnt - 1][i]
+ 732                                )
+ 733
+ 734                                BB[j][i - 1] = (D_s[cnt][i] + D_s[cnt][i - 1]) / (dx**2)
+ 735
+ 736                                BB[j][i] = (
+ 737                                    1 / dt_array[cnt][i]
+ 738                                    - (D_s[cnt][i] + D_s[cnt][i - 1]) / (dx**2)
+ 739                                    - (D_s[cnt - 1][i] + D_s[cnt][i]) / (dy**2)
+ 740                                )
+ 741
+ 742                                AA[j][i] = (D_s[cnt][i] + D_s[cnt - 1][i]) / (dy**2)
+ 743                            else:
+ 744                                DD[i] = (
+ 745                                    Qmod[cnt][i] / dt_array[cnt][i]
+ 746                                    - f_c[cnt][i]
+ 747                                    * (
+ 748                                        u[cnt][i]
+ 749                                        * (
+ 750                                            polymer.concentration_matrix[cnt][i + 1]
+ 751                                            - polymer.concentration_matrix[cnt][i - 1]
+ 752                                        )
+ 753                                        / (2 * dx)
+ 754                                    )
+ 755                                    - f_g[cnt][i]
+ 756                                    * (
+ 757                                        u[cnt][i]
+ 758                                        * (
+ 759                                            surfactant.concentration_matrix[cnt][i + 1]
+ 760                                            - surfactant.concentration_matrix[cnt][
+ 761                                                i - 1
+ 762                                            ]
+ 763                                        )
+ 764                                        / (2 * dx)
+ 765                                    )
+ 766                                    + (
+ 767                                        (
+ 768                                            D_g[cnt][i + 1]
+ 769                                            + D_g[cnt][i - 1]
+ 770                                            + 2 * D_g[cnt][i]
+ 771                                        )
+ 772                                        / (2 * dx**2)
+ 773                                        + (D_g[cnt][i + 1] + D_g[cnt][i]) / (dy**2)
+ 774                                    )
+ 775                                    * surfactant.concentration_matrix[cnt][i]
+ 776                                    - (D_g[cnt][i + 1] + D_g[cnt][i])
+ 777                                    / (2 * dx**2)
+ 778                                    * surfactant.concentration_matrix[cnt][i + 1]
+ 779                                    - (D_g[cnt][i - 1] + D_g[cnt][i])
+ 780                                    / (2 * dx**2)
+ 781                                    * surfactant.concentration_matrix[cnt][i - 1]
+ 782                                    - (D_g[cnt][i] + D_g[cnt - 1][i])
+ 783                                    / (dy**2)
+ 784                                    * surfactant.concentration_matrix[cnt - 1][i]
+ 785                                )
+ 786
+ 787                                BB[j][i] = (
+ 788                                    1 / dt_array[cnt][i]
+ 789                                    - (
+ 790                                        D_s[cnt][i + 1]
+ 791                                        + D_s[cnt][i - 1]
+ 792                                        + 2 * D_s[cnt][i]
+ 793                                    )
+ 794                                    / (2 * dx**2)
+ 795                                    - (D_s[cnt - 1][i] + D_s[cnt][i]) / (dy**2)
+ 796                                )
+ 797                                BB[j][i - 1] = (D_s[cnt][i - 1] + D_s[cnt][i]) / (
+ 798                                    2 * dx**2
+ 799                                )
+ 800                                BB[j][i + 1] = (D_s[cnt][i + 1] + D_s[cnt][i]) / (
+ 801                                    2 * dx**2
+ 802                                )
+ 803
+ 804                                AA[j][i] = (D_s[cnt][i] + D_s[cnt - 1][i]) / (dy**2)
+ 805
+ 806                        else:
+ 807                            if i == 0:
+ 808                                DD[i] = (
+ 809                                    Qmod[cnt][i] / dt_array[cnt][i]
+ 810                                    - f_c[cnt][i]
+ 811                                    * (
+ 812                                        v[cnt][i]
+ 813                                        * (
+ 814                                            polymer.concentration_matrix[cnt + 1][i]
+ 815                                            - polymer.concentration_matrix[cnt][i]
+ 816                                        )
+ 817                                        / (2 * dy)
+ 818                                    )
+ 819                                    - f_g[cnt][i]
+ 820                                    * (
+ 821                                        v[cnt][i]
+ 822                                        * (
+ 823                                            surfactant.concentration_matrix[cnt + 1][i]
+ 824                                            - surfactant.concentration_matrix[cnt][i]
+ 825                                        )
+ 826                                        / (2 * dy)
+ 827                                    )
+ 828                                    + (
+ 829                                        (D_g[cnt][i] + D_g[cnt][i + 1]) / (dx**2)
+ 830                                        + (
+ 831                                            D_g[cnt - 1][i]
+ 832                                            + 2 * D_g[cnt][i]
+ 833                                            + D_g[cnt + 1][i]
+ 834                                        )
+ 835                                        / (2 * dy**2)
+ 836                                    )
+ 837                                    * surfactant.concentration_matrix[cnt][i]
+ 838                                    - (D_g[cnt][i] + D_g[cnt][i + 1])
+ 839                                    / (dx**2)
+ 840                                    * surfactant.concentration_matrix[cnt][i + 1]
+ 841                                    - (D_g[cnt][i] + D_g[cnt + 1][i])
+ 842                                    / (2 * dy**2)
+ 843                                    * surfactant.concentration_matrix[cnt + 1][i]
+ 844                                    - (D_g[cnt][i] + D_g[cnt - 1][i])
+ 845                                    / (2 * dy**2)
+ 846                                    * surfactant.concentration_matrix[cnt - 1][i]
+ 847                                )
+ 848
+ 849                                AA[j][i] = (D_s[cnt][i] + D_s[cnt - 1][i]) / (2 * dy**2)
+ 850
+ 851                                BB[j][i] = (
+ 852                                    1 / dt_array[cnt][i]
+ 853                                    - (D_s[cnt][i] + D_s[cnt][i + 1]) / (dx**2)
+ 854                                    - (
+ 855                                        D_s[cnt - 1][i]
+ 856                                        + 2 * D_s[cnt][i]
+ 857                                        + D_s[cnt + 1][i]
+ 858                                    )
+ 859                                    / (2 * dy**2)
+ 860                                )
+ 861                                BB[j][i + 1] = (D_s[cnt][i] + D_s[cnt][i + 1]) / (dx**2)
+ 862
+ 863                                CC[j][i] = (D_s[cnt][i] + D_s[cnt + 1][i]) / (2 * dy**2)
+ 864                            elif i == m - 1:
+ 865                                DD[i] = (
+ 866                                    Qmod[cnt][i] / dt_array[cnt][i]
+ 867                                    - f_c[cnt][i]
+ 868                                    * (
+ 869                                        v[cnt][i]
+ 870                                        * (
+ 871                                            polymer.concentration_matrix[cnt + 1][i]
+ 872                                            - polymer.concentration_matrix[cnt][i]
+ 873                                        )
+ 874                                        / (2 * dy)
+ 875                                    )
+ 876                                    - f_g[cnt][i]
+ 877                                    * (
+ 878                                        v[cnt][i]
+ 879                                        * (
+ 880                                            surfactant.concentration_matrix[cnt + 1][i]
+ 881                                            - surfactant.concentration_matrix[cnt][i]
+ 882                                        )
+ 883                                        / (2 * dy)
+ 884                                    )
+ 885                                    + (
+ 886                                        (D_g[cnt][i] + D_g[cnt][i - 1]) / (dx**2)
+ 887                                        + (
+ 888                                            D_g[cnt - 1][i]
+ 889                                            + 2 * D_g[cnt][i]
+ 890                                            + D_g[cnt + 1][i]
+ 891                                        )
+ 892                                        / (2 * dy**2)
+ 893                                    )
+ 894                                    * surfactant.concentration_matrix[cnt][i]
+ 895                                    - (D_g[cnt][i] + D_g[cnt][i - 1])
+ 896                                    / (dx**2)
+ 897                                    * surfactant.concentration_matrix[cnt][i - 1]
+ 898                                    - (D_g[cnt][i] + D_g[cnt + 1][i])
+ 899                                    / (2 * dy**2)
+ 900                                    * surfactant.concentration_matrix[cnt + 1][i]
+ 901                                    - (D_g[cnt][i] + D_g[cnt - 1][i])
+ 902                                    / (2 * dy**2)
+ 903                                    * surfactant.concentration_matrix[cnt - 1][i]
+ 904                                )
+ 905
+ 906                                AA[j][i] = (D_s[cnt][i] + D_s[cnt - 1][i]) / (2 * dy**2)
+ 907
+ 908                                BB[j][i] = (
+ 909                                    1 / dt_array[cnt][i]
+ 910                                    - (D_s[cnt][i] + D_s[cnt][i - 1]) / (dx**2)
+ 911                                    - (
+ 912                                        D_s[cnt - 1][i]
+ 913                                        + 2 * D_s[cnt][i]
+ 914                                        + D_s[cnt + 1][i]
+ 915                                    )
+ 916                                    / (2 * dy**2)
+ 917                                )
+ 918                                BB[j][i - 1] = (D_s[cnt][i] + D_s[cnt][i - 1]) / (dx**2)
+ 919
+ 920                                CC[j][i] = (D_s[cnt][i] + D_s[cnt + 1][i]) / (2 * dy**2)
+ 921                            else:
+ 922                                DD[i] = (
+ 923                                    (Qmod[cnt][i] / dt_array[cnt][i])
+ 924                                    - f_c[cnt][i]
+ 925                                    * (
+ 926                                        u[cnt][i]
+ 927                                        * (
+ 928                                            polymer.concentration_matrix[cnt][i + 1]
+ 929                                            - polymer.concentration_matrix[cnt][i - 1]
+ 930                                        )
+ 931                                        / (2 * dx)
+ 932                                        + v[cnt][i]
+ 933                                        * (
+ 934                                            polymer.concentration_matrix[cnt + 1][i]
+ 935                                            - polymer.concentration_matrix[cnt - 1][i]
+ 936                                        )
+ 937                                        / (2 * dy)
+ 938                                    )
+ 939                                    - f_g[cnt][i]
+ 940                                    * (
+ 941                                        u[cnt][i]
+ 942                                        * (
+ 943                                            surfactant.concentration_matrix[cnt][i + 1]
+ 944                                            - surfactant.concentration_matrix[cnt][
+ 945                                                i - 1
+ 946                                            ]
+ 947                                        )
+ 948                                        / (2 * dx)
+ 949                                        + v[cnt][i]
+ 950                                        * (
+ 951                                            surfactant.concentration_matrix[cnt + 1][i]
+ 952                                            - surfactant.concentration_matrix[cnt - 1][
+ 953                                                i
+ 954                                            ]
+ 955                                        )
+ 956                                        / (2 * dy)
+ 957                                    )
+ 958                                    - (
+ 959                                        D_g[cnt][i + 1]
+ 960                                        / (2 * dx**2)
+ 961                                        * (
+ 962                                            surfactant.concentration_matrix[cnt][i + 1]
+ 963                                            - surfactant.concentration_matrix[cnt][i]
+ 964                                        )
+ 965                                        - D_g[cnt][i - 1]
+ 966                                        / (2 * dx**2)
+ 967                                        * (
+ 968                                            surfactant.concentration_matrix[cnt][i - 1]
+ 969                                            - surfactant.concentration_matrix[cnt][i]
+ 970                                        )
+ 971                                        + D_g[cnt][i - 1]
+ 972                                        / (2 * dx**2)
+ 973                                        * (
+ 974                                            surfactant.concentration_matrix[cnt][i - 1]
+ 975                                            - surfactant.concentration_matrix[cnt][
+ 976                                                i + 1
+ 977                                            ]
+ 978                                        )
+ 979                                        + D_g[cnt + 1][i]
+ 980                                        / (2 * dx**2)
+ 981                                        * (
+ 982                                            surfactant.concentration_matrix[cnt + 1][i]
+ 983                                            - surfactant.concentration_matrix[cnt][i]
+ 984                                        )
+ 985                                        + D_g[cnt - 1][i]
+ 986                                        / (2 * dx**2)
+ 987                                        * (
+ 988                                            surfactant.concentration_matrix[cnt - 1][i]
+ 989                                            - surfactant.concentration_matrix[cnt][i]
+ 990                                        )
+ 991                                        + D_g[cnt][i]
+ 992                                        / (2 * dx**2)
+ 993                                        * (
+ 994                                            surfactant.concentration_matrix[cnt + 1][i]
+ 995                                            - surfactant.concentration_matrix[cnt][i]
+ 996                                        )
+ 997                                    )
+ 998                                )
+ 999                                AA[j][i] = (D_s[cnt - 1][i] + D_s[cnt][i]) / (2 * dy**2)
+1000
+1001                                CC[j][i] = (D_s[cnt][i] + D_s[cnt + 1][i]) / (2 * dy**2)
+1002
+1003                                BB[j][i] = 1 / dt_array[cnt][i] - (
+1004                                    (1 / (2 * dx**2))
+1005                                    * (D_s[cnt][i - 1] + 2 * D_s[cnt][i] + D_s[cnt][i + 1])
+1006                                    + (1 / (2 * dy**2))
+1007                                    * (
+1008                                        D_s[cnt - 1][i]
+1009                                        + 2 * D_s[cnt][i]
+1010                                        + D_s[cnt + 1][i]
+1011                                    )
+1012                                )
+1013                                BB[j][i + 1] = (D_s[cnt][i] + D_s[cnt][i + 1]) / (
+1014                                    2 * dx**2
+1015                                )
+1016                                BB[j][i - 1] = (D_s[cnt][i - 1] + D_s[cnt][i]) / (
+1017                                    2 * dx**2
+1018                                )
+1019
+1020            if cnt == 0:
+1021                AAA[:n, : 2 * m] = np.hstack([BB, CC])
+1022            elif cnt == n - 1:
+1023                AAA[(m - 1) * n : m * n, (n - 2) * m : n * m] = np.hstack([AA, BB])
+1024            else:
+1025                AAA[cnt * n : (cnt + 1) * n, (cnt - 1) * m : (cnt + 2) * m] = np.hstack(
+1026                    [AA, BB, CC]
+1027                )
+1028
+1029            DDD[cnt * m : (cnt + 1) * m] = DD
+1030            idx += m
+1031
+1032        # Entering the bicgstab for the saturation calculations
+1033        # bicgstab (Biconjugate Gradient Stabilized) - Iterative algorithm to solve large, sparse, and non-symmetric linear systems of the form Ax = b
+1034
+1035        Qnew_flat, info = bicgstab(AAA, DDD, rtol=10 ** (-10), maxiter=600)
+1036        if info != 0:
+1037            import warnings
+1038            warnings.warn(f"BiCGSTAB: convergence issue (info={info}) in water saturation solver")
+1039        Qnew = Qnew_flat = Qnew_flat.reshape(m, n)
+1040
+1041        Qnew[Qnew < 0] = 0
+1042
+1043        self.water_saturation = Qnew
+1044
+1045        return Qmod, varying_parameters
+
+ + +

Solving saturation equation (comes from part of the nmmoc_surf_mod_neumann.m file that +is for calculating the water saturation)

+ +

Raises:

+ +
SimulationCalcInputException: If water saturation matrix is None
+
+ +

Args:

+ +
grid (Grid): the 'Grid' object
+
+surfactant (Surfactant): The surfactant object
+
+polymer (Polymer): The polymer object
+
+u (np.ndarray): global pressure matrix
+
+v (np.ndarray): velocity matrix
+
+xmod (np.ndarray): x-dimension coordinate points for formulating the 'Qmod' matrix
+
+ymod (np.ndarray): y-dimension coordinate points for formulating the 'Qmod' matrix
+
+const_parameters (dict): constant parameters used in the method
+
+varying_parameters (dict): parameters whose values can change
+
+ +

Returns: (np.ndarray, dict)

+ +
Updates the ``water_saturation`` matrix and ``varying_parameters`` dict
+
+
+ + +
+
+
+ + \ No newline at end of file diff --git a/docs/search.js b/docs/search.js new file mode 100644 index 0000000..b1512c7 --- /dev/null +++ b/docs/search.js @@ -0,0 +1,46 @@ +window.pdocSearch = (function(){ +/** elasticlunr - http://weixsong.github.io * Copyright (C) 2017 Oliver Nightingale * Copyright (C) 2017 Wei Song * MIT Licensed */!function(){function e(e){if(null===e||"object"!=typeof e)return e;var t=e.constructor();for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t}var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.9.5",lunr=t,t.utils={},t.utils.warn=function(e){return function(t){e.console&&console.warn&&console.warn(t)}}(this),t.utils.toString=function(e){return void 0===e||null===e?"":e.toString()},t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var e=Array.prototype.slice.call(arguments),t=e.pop(),n=e;if("function"!=typeof t)throw new TypeError("last argument must be a function");n.forEach(function(e){this.hasHandler(e)||(this.events[e]=[]),this.events[e].push(t)},this)},t.EventEmitter.prototype.removeListener=function(e,t){if(this.hasHandler(e)){var n=this.events[e].indexOf(t);-1!==n&&(this.events[e].splice(n,1),0==this.events[e].length&&delete this.events[e])}},t.EventEmitter.prototype.emit=function(e){if(this.hasHandler(e)){var t=Array.prototype.slice.call(arguments,1);this.events[e].forEach(function(e){e.apply(void 0,t)},this)}},t.EventEmitter.prototype.hasHandler=function(e){return e in this.events},t.tokenizer=function(e){if(!arguments.length||null===e||void 0===e)return[];if(Array.isArray(e)){var n=e.filter(function(e){return null===e||void 0===e?!1:!0});n=n.map(function(e){return t.utils.toString(e).toLowerCase()});var i=[];return n.forEach(function(e){var n=e.split(t.tokenizer.seperator);i=i.concat(n)},this),i}return e.toString().trim().toLowerCase().split(t.tokenizer.seperator)},t.tokenizer.defaultSeperator=/[\s\-]+/,t.tokenizer.seperator=t.tokenizer.defaultSeperator,t.tokenizer.setSeperator=function(e){null!==e&&void 0!==e&&"object"==typeof e&&(t.tokenizer.seperator=e)},t.tokenizer.resetSeperator=function(){t.tokenizer.seperator=t.tokenizer.defaultSeperator},t.tokenizer.getSeperator=function(){return t.tokenizer.seperator},t.Pipeline=function(){this._queue=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in t.Pipeline.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[n]=e},t.Pipeline.getRegisteredFunction=function(e){return e in t.Pipeline.registeredFunctions!=!0?null:t.Pipeline.registeredFunctions[e]},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.getRegisteredFunction(e);if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._queue.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._queue.indexOf(e);if(-1===i)throw new Error("Cannot find existingFn");this._queue.splice(i+1,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._queue.indexOf(e);if(-1===i)throw new Error("Cannot find existingFn");this._queue.splice(i,0,n)},t.Pipeline.prototype.remove=function(e){var t=this._queue.indexOf(e);-1!==t&&this._queue.splice(t,1)},t.Pipeline.prototype.run=function(e){for(var t=[],n=e.length,i=this._queue.length,o=0;n>o;o++){for(var r=e[o],s=0;i>s&&(r=this._queue[s](r,o,e),void 0!==r&&null!==r);s++);void 0!==r&&null!==r&&t.push(r)}return t},t.Pipeline.prototype.reset=function(){this._queue=[]},t.Pipeline.prototype.get=function(){return this._queue},t.Pipeline.prototype.toJSON=function(){return this._queue.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.DocumentStore,this.index={},this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var e=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,e)},t.Index.prototype.off=function(e,t){return this.eventEmitter.removeListener(e,t)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;n._fields=e.fields,n._ref=e.ref,n.documentStore=t.DocumentStore.load(e.documentStore),n.pipeline=t.Pipeline.load(e.pipeline),n.index={};for(var i in e.index)n.index[i]=t.InvertedIndex.load(e.index[i]);return n},t.Index.prototype.addField=function(e){return this._fields.push(e),this.index[e]=new t.InvertedIndex,this},t.Index.prototype.setRef=function(e){return this._ref=e,this},t.Index.prototype.saveDocument=function(e){return this.documentStore=new t.DocumentStore(e),this},t.Index.prototype.addDoc=function(e,n){if(e){var n=void 0===n?!0:n,i=e[this._ref];this.documentStore.addDoc(i,e),this._fields.forEach(function(n){var o=this.pipeline.run(t.tokenizer(e[n]));this.documentStore.addFieldLength(i,n,o.length);var r={};o.forEach(function(e){e in r?r[e]+=1:r[e]=1},this);for(var s in r){var u=r[s];u=Math.sqrt(u),this.index[n].addToken(s,{ref:i,tf:u})}},this),n&&this.eventEmitter.emit("add",e,this)}},t.Index.prototype.removeDocByRef=function(e){if(e&&this.documentStore.isDocStored()!==!1&&this.documentStore.hasDoc(e)){var t=this.documentStore.getDoc(e);this.removeDoc(t,!1)}},t.Index.prototype.removeDoc=function(e,n){if(e){var n=void 0===n?!0:n,i=e[this._ref];this.documentStore.hasDoc(i)&&(this.documentStore.removeDoc(i),this._fields.forEach(function(n){var o=this.pipeline.run(t.tokenizer(e[n]));o.forEach(function(e){this.index[n].removeToken(e,i)},this)},this),n&&this.eventEmitter.emit("remove",e,this))}},t.Index.prototype.updateDoc=function(e,t){var t=void 0===t?!0:t;this.removeDocByRef(e[this._ref],!1),this.addDoc(e,!1),t&&this.eventEmitter.emit("update",e,this)},t.Index.prototype.idf=function(e,t){var n="@"+t+"/"+e;if(Object.prototype.hasOwnProperty.call(this._idfCache,n))return this._idfCache[n];var i=this.index[t].getDocFreq(e),o=1+Math.log(this.documentStore.length/(i+1));return this._idfCache[n]=o,o},t.Index.prototype.getFields=function(){return this._fields.slice()},t.Index.prototype.search=function(e,n){if(!e)return[];e="string"==typeof e?{any:e}:JSON.parse(JSON.stringify(e));var i=null;null!=n&&(i=JSON.stringify(n));for(var o=new t.Configuration(i,this.getFields()).get(),r={},s=Object.keys(e),u=0;u0&&t.push(e);for(var i in n)"docs"!==i&&"df"!==i&&this.expandToken(e+i,t,n[i]);return t},t.InvertedIndex.prototype.toJSON=function(){return{root:this.root}},t.Configuration=function(e,n){var e=e||"";if(void 0==n||null==n)throw new Error("fields should not be null");this.config={};var i;try{i=JSON.parse(e),this.buildUserConfig(i,n)}catch(o){t.utils.warn("user configuration parse failed, will use default configuration"),this.buildDefaultConfig(n)}},t.Configuration.prototype.buildDefaultConfig=function(e){this.reset(),e.forEach(function(e){this.config[e]={boost:1,bool:"OR",expand:!1}},this)},t.Configuration.prototype.buildUserConfig=function(e,n){var i="OR",o=!1;if(this.reset(),"bool"in e&&(i=e.bool||i),"expand"in e&&(o=e.expand||o),"fields"in e)for(var r in e.fields)if(n.indexOf(r)>-1){var s=e.fields[r],u=o;void 0!=s.expand&&(u=s.expand),this.config[r]={boost:s.boost||0===s.boost?s.boost:1,bool:s.bool||i,expand:u}}else t.utils.warn("field name in user configuration not found in index instance fields");else this.addAllFields2UserConfig(i,o,n)},t.Configuration.prototype.addAllFields2UserConfig=function(e,t,n){n.forEach(function(n){this.config[n]={boost:1,bool:e,expand:t}},this)},t.Configuration.prototype.get=function(){return this.config},t.Configuration.prototype.reset=function(){this.config={}},lunr.SortedSet=function(){this.length=0,this.elements=[]},lunr.SortedSet.load=function(e){var t=new this;return t.elements=e,t.length=e.length,t},lunr.SortedSet.prototype.add=function(){var e,t;for(e=0;e1;){if(r===e)return o;e>r&&(t=o),r>e&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o]}return r===e?o:-1},lunr.SortedSet.prototype.locationFor=function(e){for(var t=0,n=this.elements.length,i=n-t,o=t+Math.floor(i/2),r=this.elements[o];i>1;)e>r&&(t=o),r>e&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o];return r>e?o:e>r?o+1:void 0},lunr.SortedSet.prototype.intersect=function(e){for(var t=new lunr.SortedSet,n=0,i=0,o=this.length,r=e.length,s=this.elements,u=e.elements;;){if(n>o-1||i>r-1)break;s[n]!==u[i]?s[n]u[i]&&i++:(t.add(s[n]),n++,i++)}return t},lunr.SortedSet.prototype.clone=function(){var e=new lunr.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},lunr.SortedSet.prototype.union=function(e){var t,n,i;this.length>=e.length?(t=this,n=e):(t=e,n=this),i=t.clone();for(var o=0,r=n.toArray();o

\n"}, "lib.name": {"fullname": "lib.name", "modulename": "lib", "qualname": "name", "kind": "variable", "doc": "

\n", "default_value": "'lib'"}, "lib.Exceptions": {"fullname": "lib.Exceptions", "modulename": "lib.Exceptions", "kind": "module", "doc": "

\n"}, "lib.Exceptions.OutOfRangeError": {"fullname": "lib.Exceptions.OutOfRangeError", "modulename": "lib.Exceptions", "qualname": "OutOfRangeError", "kind": "class", "doc": "

Exception raised for errors in the input if it is out of range.

\n", "bases": "builtins.Exception"}, "lib.Exceptions.OutOfRangeError.__init__": {"fullname": "lib.Exceptions.OutOfRangeError.__init__", "modulename": "lib.Exceptions", "qualname": "OutOfRangeError.__init__", "kind": "function", "doc": "

Args:

\n\n
value (float): value that the user provided in GUI\nmessage (str): Error message\n
\n", "signature": "(value, message='Value is out of the allowed range.')"}, "lib.Exceptions.SimulationCalcInputException": {"fullname": "lib.Exceptions.SimulationCalcInputException", "modulename": "lib.Exceptions", "qualname": "SimulationCalcInputException", "kind": "class", "doc": "

Exception Handling for required inputs within various stages of the simulation

\n", "bases": "builtins.Exception"}, "lib.Exceptions.SimulationCalcInputException.__init__": {"fullname": "lib.Exceptions.SimulationCalcInputException.__init__", "modulename": "lib.Exceptions", "qualname": "SimulationCalcInputException.__init__", "kind": "function", "doc": "

constructor exception object

\n\n

Args:

\n\n
message (str): takes in the error message\n
\n", "signature": "(message)"}, "lib.Exceptions.UserInputException": {"fullname": "lib.Exceptions.UserInputException", "modulename": "lib.Exceptions", "qualname": "UserInputException", "kind": "class", "doc": "

Exception raised for invalid user inputs from the GUI.

\n", "bases": "builtins.Exception"}, "lib.Exceptions.UserInputException.__init__": {"fullname": "lib.Exceptions.UserInputException.__init__", "modulename": "lib.Exceptions", "qualname": "UserInputException.__init__", "kind": "function", "doc": "

Initialize the exception with a message and optional input dictionary.

\n\n

Args:

\n\n
message (str): Description of the validation error.\ninputs (dict, None): Dictionary of user inputs (optional).\n
\n", "signature": "(message: str, inputs: dict | None = None)"}, "lib.enumerations": {"fullname": "lib.enumerations", "modulename": "lib.enumerations", "kind": "module", "doc": "

This python script contains the class definitions for the enumerations that are used within the simulation runs

\n\n

The methods of this class were derived from the MATLAB Surfactant-Polymer Flooding Code developed by\nSourav Dutta and Rohit Mishra.

\n\n

@author: Bhargav Akula Ramesh Kumar, Carlos Acosta Caripo

\n"}, "lib.enumerations.SimulationConstants": {"fullname": "lib.enumerations.SimulationConstants", "modulename": "lib.enumerations", "qualname": "SimulationConstants", "kind": "class", "doc": "

Simulation constants\n(Taken from 2017 paper \"Modeling and simulation of surfactant\u2013polymer flooding using a new hybrid method\")

\n", "bases": "enum.Enum"}, "lib.enumerations.SimulationConstants.Water_Viscosity": {"fullname": "lib.enumerations.SimulationConstants.Water_Viscosity", "modulename": "lib.enumerations", "qualname": "SimulationConstants.Water_Viscosity", "kind": "variable", "doc": "

\n", "default_value": "<SimulationConstants.Water_Viscosity: 1.26>"}, "lib.enumerations.SimulationConstants.Water_Density": {"fullname": "lib.enumerations.SimulationConstants.Water_Density", "modulename": "lib.enumerations", "qualname": "SimulationConstants.Water_Density", "kind": "variable", "doc": "

\n", "default_value": "<SimulationConstants.Water_Density: 1000>"}, "lib.enumerations.SimulationConstants.Oil_Viscosity": {"fullname": "lib.enumerations.SimulationConstants.Oil_Viscosity", "modulename": "lib.enumerations", "qualname": "SimulationConstants.Oil_Viscosity", "kind": "variable", "doc": "

\n", "default_value": "<SimulationConstants.Oil_Viscosity: 10>"}, "lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"fullname": "lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation", "modulename": "lib.enumerations", "qualname": "SimulationConstants.Initial_Residual_Water_Saturation", "kind": "variable", "doc": "

\n", "default_value": "<SimulationConstants.Initial_Residual_Water_Saturation: 0.79>"}, "lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"fullname": "lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial", "modulename": "lib.enumerations", "qualname": "SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial", "kind": "variable", "doc": "

\n", "default_value": "<SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial: 0.1>"}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"fullname": "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial", "modulename": "lib.enumerations", "qualname": "SimulationConstants.Resid_Oleic_Phase_Saturation_Initial", "kind": "variable", "doc": "

\n", "default_value": "<SimulationConstants.Resid_Oleic_Phase_Saturation_Initial: 0.3>"}, "lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"fullname": "lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num", "modulename": "lib.enumerations", "qualname": "SimulationConstants.Aqueous_Phase_Critical_Capillary_Num", "kind": "variable", "doc": "

\n", "default_value": "<SimulationConstants.Aqueous_Phase_Critical_Capillary_Num: 1e-05>"}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"fullname": "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num", "modulename": "lib.enumerations", "qualname": "SimulationConstants.Oleic_Phase_Critical_Capillary_Num", "kind": "variable", "doc": "

\n", "default_value": "<SimulationConstants.Aqueous_Phase_Critical_Capillary_Num: 1e-05>"}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"fullname": "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1", "modulename": "lib.enumerations", "qualname": "SimulationConstants.Capillary_Pressure_Param_1", "kind": "variable", "doc": "

\n", "default_value": "<SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial: 0.1>"}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"fullname": "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2", "modulename": "lib.enumerations", "qualname": "SimulationConstants.Capillary_Pressure_Param_2", "kind": "variable", "doc": "

\n", "default_value": "<SimulationConstants.Capillary_Pressure_Param_2: 0.4>"}, "lib.enumerations.SimulationConstants.Injection_Rate": {"fullname": "lib.enumerations.SimulationConstants.Injection_Rate", "modulename": "lib.enumerations", "qualname": "SimulationConstants.Injection_Rate", "kind": "variable", "doc": "

\n", "default_value": "<SimulationConstants.Injection_Rate: 200>"}, "lib.enumerations.SimulationConstants.Time_Step": {"fullname": "lib.enumerations.SimulationConstants.Time_Step", "modulename": "lib.enumerations", "qualname": "SimulationConstants.Time_Step", "kind": "variable", "doc": "

\n", "default_value": "<SimulationConstants.Time_Step: 0.02>"}, "lib.enumerations.SimulationConstants.Grid_Size": {"fullname": "lib.enumerations.SimulationConstants.Grid_Size", "modulename": "lib.enumerations", "qualname": "SimulationConstants.Grid_Size", "kind": "variable", "doc": "

\n", "default_value": "<SimulationConstants.Grid_Size: 29>"}, "lib.enumerations.SimulationConstants.Source_Flow_Magnitude": {"fullname": "lib.enumerations.SimulationConstants.Source_Flow_Magnitude", "modulename": "lib.enumerations", "qualname": "SimulationConstants.Source_Flow_Magnitude", "kind": "variable", "doc": "

\n", "default_value": "<SimulationConstants.Source_Flow_Magnitude: 120000>"}, "lib.enumerations.SimulationConstants.beta1": {"fullname": "lib.enumerations.SimulationConstants.beta1", "modulename": "lib.enumerations", "qualname": "SimulationConstants.beta1", "kind": "variable", "doc": "

\n", "default_value": "<SimulationConstants.beta1: 15000>"}, "lib.enumerations.PolymerList": {"fullname": "lib.enumerations.PolymerList", "modulename": "lib.enumerations", "qualname": "PolymerList", "kind": "class", "doc": "

List of Polymers that can be selected for the simulation runs

\n", "bases": "enum.Enum"}, "lib.enumerations.PolymerList.Xanthane": {"fullname": "lib.enumerations.PolymerList.Xanthane", "modulename": "lib.enumerations", "qualname": "PolymerList.Xanthane", "kind": "variable", "doc": "

\n", "default_value": "<PolymerList.Xanthane: (1, 1500, array([[ 3.05428284],\n [-0.27294817]]), array([[1.15410398e-04],\n [2.04937780e+00]]))>"}, "lib.enumerations.PolymerList.Schizophyllan": {"fullname": "lib.enumerations.PolymerList.Schizophyllan", "modulename": "lib.enumerations", "qualname": "PolymerList.Schizophyllan", "kind": "variable", "doc": "

\n", "default_value": "<PolymerList.Schizophyllan: (2, 1300, array([[ 4.86265534],\n [-0.41570227]]), array([[0.03647214],\n [1.32175949]]))>"}, "lib.enumerations.PolymerList.No_Polymer": {"fullname": "lib.enumerations.PolymerList.No_Polymer", "modulename": "lib.enumerations", "qualname": "PolymerList.No_Polymer", "kind": "variable", "doc": "

\n", "default_value": "<PolymerList.No_Polymer: (3, 0, [0, 0], [0, 0])>"}, "lib.enumerations.PolymerList.Id": {"fullname": "lib.enumerations.PolymerList.Id", "modulename": "lib.enumerations", "qualname": "PolymerList.Id", "kind": "variable", "doc": "

Id (int): Index for Polymer

\n"}, "lib.enumerations.PolymerList.Density": {"fullname": "lib.enumerations.PolymerList.Density", "modulename": "lib.enumerations", "qualname": "PolymerList.Density", "kind": "variable", "doc": "

Density (float): density of the Polymer

\n"}, "lib.enumerations.PolymerList.n_coeff": {"fullname": "lib.enumerations.PolymerList.n_coeff", "modulename": "lib.enumerations", "qualname": "PolymerList.n_coeff", "kind": "variable", "doc": "

n_coeff (list[float]): 'n' coeffient for the empirical power law equation

\n"}, "lib.enumerations.PolymerList.e_coeff": {"fullname": "lib.enumerations.PolymerList.e_coeff", "modulename": "lib.enumerations", "qualname": "PolymerList.e_coeff", "kind": "variable", "doc": "

e_coeff (list[float]): '\u03b5' coeffient for the empirical power law equation

\n"}, "lib.enumerations.PolymerList.get_by_value": {"fullname": "lib.enumerations.PolymerList.get_by_value", "modulename": "lib.enumerations", "qualname": "PolymerList.get_by_value", "kind": "function", "doc": "

retrieves Polymer from enumeration based on value

\n", "signature": "(cls, value):", "funcdef": "def"}, "lib.enumerations.SurfactantList": {"fullname": "lib.enumerations.SurfactantList", "modulename": "lib.enumerations", "qualname": "SurfactantList", "kind": "class", "doc": "

List of Surfactants that can be selected for the simulation runs

\n\n

FIXME: need to adjust when implementing 'autodiff'

\n", "bases": "enum.Enum"}, "lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate": {"fullname": "lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate", "modulename": "lib.enumerations", "qualname": "SurfactantList.Alkyl_Ether_Sulfate", "kind": "variable", "doc": "

\n", "default_value": "<SurfactantList.Alkyl_Ether_Sulfate: (1, <function SurfactantList.<lambda>>, <function SurfactantList.<lambda>>)>"}, "lib.enumerations.SurfactantList.No_Surfactant": {"fullname": "lib.enumerations.SurfactantList.No_Surfactant", "modulename": "lib.enumerations", "qualname": "SurfactantList.No_Surfactant", "kind": "variable", "doc": "

\n", "default_value": "<SurfactantList.No_Surfactant: (2, <function SurfactantList.<lambda>>, <function SurfactantList.<lambda>>)>"}, "lib.enumerations.SurfactantList.Id": {"fullname": "lib.enumerations.SurfactantList.Id", "modulename": "lib.enumerations", "qualname": "SurfactantList.Id", "kind": "variable", "doc": "

Id (int): Index for Polymer

\n"}, "lib.enumerations.SurfactantList.IFT_equation": {"fullname": "lib.enumerations.SurfactantList.IFT_equation", "modulename": "lib.enumerations", "qualname": "SurfactantList.IFT_equation", "kind": "variable", "doc": "

IFT_equation (lambda): the relationship between surfactant concentration and interfacial tension

\n"}, "lib.enumerations.SurfactantList.derivative_IFT_equation": {"fullname": "lib.enumerations.SurfactantList.derivative_IFT_equation", "modulename": "lib.enumerations", "qualname": "SurfactantList.derivative_IFT_equation", "kind": "variable", "doc": "

derivative_IFT_equation (lambda): the derivative of the IFT_equation

\n"}, "lib.enumerations.SurfactantList.get_by_value": {"fullname": "lib.enumerations.SurfactantList.get_by_value", "modulename": "lib.enumerations", "qualname": "SurfactantList.get_by_value", "kind": "function", "doc": "

retrieves Surfactant from enumeration based on value

\n", "signature": "(cls, value):", "funcdef": "def"}, "lib.enumerations.ModelType": {"fullname": "lib.enumerations.ModelType", "modulename": "lib.enumerations", "qualname": "ModelType", "kind": "class", "doc": "

The simulation model types that can be selected

\n", "bases": "enum.Enum"}, "lib.enumerations.ModelType.No_Shear_Thinning": {"fullname": "lib.enumerations.ModelType.No_Shear_Thinning", "modulename": "lib.enumerations", "qualname": "ModelType.No_Shear_Thinning", "kind": "variable", "doc": "

\n", "default_value": "<ModelType.No_Shear_Thinning: 1>"}, "lib.enumerations.ModelType.Sourav_Implementation": {"fullname": "lib.enumerations.ModelType.Sourav_Implementation", "modulename": "lib.enumerations", "qualname": "ModelType.Sourav_Implementation", "kind": "variable", "doc": "

\n", "default_value": "<ModelType.Sourav_Implementation: 2>"}, "lib.enumerations.ModelType.Shear_Thinning_On": {"fullname": "lib.enumerations.ModelType.Shear_Thinning_On", "modulename": "lib.enumerations", "qualname": "ModelType.Shear_Thinning_On", "kind": "variable", "doc": "

\n", "default_value": "<ModelType.Shear_Thinning_On: 3>"}, "lib.enumerations.PlotType": {"fullname": "lib.enumerations.PlotType", "modulename": "lib.enumerations", "qualname": "PlotType", "kind": "class", "doc": "

Selection of types of plots that can be created for the user

\n", "bases": "enum.Enum"}, "lib.enumerations.PlotType.Saturation_Plot": {"fullname": "lib.enumerations.PlotType.Saturation_Plot", "modulename": "lib.enumerations", "qualname": "PlotType.Saturation_Plot", "kind": "variable", "doc": "

\n", "default_value": "<PlotType.Saturation_Plot: 1>"}, "lib.enumerations.PlotType.Polymer_Concentration_Plot": {"fullname": "lib.enumerations.PlotType.Polymer_Concentration_Plot", "modulename": "lib.enumerations", "qualname": "PlotType.Polymer_Concentration_Plot", "kind": "variable", "doc": "

\n", "default_value": "<PlotType.Polymer_Concentration_Plot: 2>"}, "lib.enumerations.PlotType.Surfactant_Concentration_Plot": {"fullname": "lib.enumerations.PlotType.Surfactant_Concentration_Plot", "modulename": "lib.enumerations", "qualname": "PlotType.Surfactant_Concentration_Plot", "kind": "variable", "doc": "

\n", "default_value": "<PlotType.Surfactant_Concentration_Plot: 3>"}, "lib.enumerations.ResevoirGeometry": {"fullname": "lib.enumerations.ResevoirGeometry", "modulename": "lib.enumerations", "qualname": "ResevoirGeometry", "kind": "class", "doc": "

Selection of the geometry of the resevoir for the simulation

\n", "bases": "enum.Enum"}, "lib.enumerations.ResevoirGeometry.Rectilinear": {"fullname": "lib.enumerations.ResevoirGeometry.Rectilinear", "modulename": "lib.enumerations", "qualname": "ResevoirGeometry.Rectilinear", "kind": "variable", "doc": "

\n", "default_value": "<ResevoirGeometry.Rectilinear: 1>"}, "lib.enumerations.ResevoirGeometry.Quarter_Five_Spot": {"fullname": "lib.enumerations.ResevoirGeometry.Quarter_Five_Spot", "modulename": "lib.enumerations", "qualname": "ResevoirGeometry.Quarter_Five_Spot", "kind": "variable", "doc": "

\n", "default_value": "<ResevoirGeometry.Quarter_Five_Spot: 2>"}, "lib.enumerations.PermeabilityType": {"fullname": "lib.enumerations.PermeabilityType", "modulename": "lib.enumerations", "qualname": "PermeabilityType", "kind": "class", "doc": "

Selection of the permeability profile for each of the simulation runs

\n", "bases": "enum.Enum"}, "lib.enumerations.PermeabilityType.Homogenous": {"fullname": "lib.enumerations.PermeabilityType.Homogenous", "modulename": "lib.enumerations", "qualname": "PermeabilityType.Homogenous", "kind": "variable", "doc": "

\n", "default_value": "<PermeabilityType.Homogenous: 1>"}, "lib.enumerations.PermeabilityType.Heterogenous": {"fullname": "lib.enumerations.PermeabilityType.Heterogenous", "modulename": "lib.enumerations", "qualname": "PermeabilityType.Heterogenous", "kind": "variable", "doc": "

\n", "default_value": "<PermeabilityType.Heterogenous: 2>"}, "lib.enumerations.RelativePermeabilityFormula": {"fullname": "lib.enumerations.RelativePermeabilityFormula", "modulename": "lib.enumerations", "qualname": "RelativePermeabilityFormula", "kind": "class", "doc": "

Selection of the relative permeability formuala\n(krw, Kro)

\n", "bases": "enum.Enum"}, "lib.enumerations.RelativePermeabilityFormula.AmaefuleHandEquation": {"fullname": "lib.enumerations.RelativePermeabilityFormula.AmaefuleHandEquation", "modulename": "lib.enumerations", "qualname": "RelativePermeabilityFormula.AmaefuleHandEquation", "kind": "variable", "doc": "

\n", "default_value": "<RelativePermeabilityFormula.AmaefuleHandEquation: 1>"}, "lib.enumerations.RelativePermeabilityFormula.CoreyTypeEquation": {"fullname": "lib.enumerations.RelativePermeabilityFormula.CoreyTypeEquation", "modulename": "lib.enumerations", "qualname": "RelativePermeabilityFormula.CoreyTypeEquation", "kind": "variable", "doc": "

\n", "default_value": "<RelativePermeabilityFormula.CoreyTypeEquation: 2>"}, "lib.grid": {"fullname": "lib.grid", "modulename": "lib.grid", "kind": "module", "doc": "

This python script contains the class definition for running simulations

\n\n

This Python code has been derived from the MATLAB Surfactant-Polymer Flooding Simulation \ndeveloped by Sourav Dutta and Rohit Mishra.

\n\n

@author: Bhargav Akula Ramesh Kumar and Carlos Acosta Caripo

\n"}, "lib.grid.Grid": {"fullname": "lib.grid.Grid", "modulename": "lib.grid", "qualname": "Grid", "kind": "class", "doc": "

Encapsulates mesh generation, triangulation, FEM matrix assembly, and source vector setup.

\n\n

FIXME: Need to refactor this class to make it more understandable

\n"}, "lib.grid.Grid.__init__": {"fullname": "lib.grid.Grid.__init__", "modulename": "lib.grid", "qualname": "Grid.__init__", "kind": "function", "doc": "

\n", "signature": "(\tm: int,\tn: int,\tleft: float = 0.0,\tright: float = 1.0,\tbottom: float = 0.0,\ttop: float = 1.0)"}, "lib.grid.Grid.m": {"fullname": "lib.grid.Grid.m", "modulename": "lib.grid", "qualname": "Grid.m", "kind": "variable", "doc": "

The number of columns

\n"}, "lib.grid.Grid.n": {"fullname": "lib.grid.Grid.n", "modulename": "lib.grid", "qualname": "Grid.n", "kind": "variable", "doc": "

The number of rows

\n"}, "lib.grid.Grid.left": {"fullname": "lib.grid.Grid.left", "modulename": "lib.grid", "qualname": "Grid.left", "kind": "variable", "doc": "

left most value on grid. Used to compute dx. Has a default value of 0

\n"}, "lib.grid.Grid.right": {"fullname": "lib.grid.Grid.right", "modulename": "lib.grid", "qualname": "Grid.right", "kind": "variable", "doc": "

right most value on grid. Used to compute dx. Has a default value of 1.

\n"}, "lib.grid.Grid.bottom": {"fullname": "lib.grid.Grid.bottom", "modulename": "lib.grid", "qualname": "Grid.bottom", "kind": "variable", "doc": "

Bottom most value on grid. Used to compute dy. Has a default value of 0.

\n"}, "lib.grid.Grid.top": {"fullname": "lib.grid.Grid.top", "modulename": "lib.grid", "qualname": "Grid.top", "kind": "variable", "doc": "

Top most value on grid. Used to compute dy. Has a default value of 1.

\n"}, "lib.grid.Grid.A": {"fullname": "lib.grid.Grid.A", "modulename": "lib.grid", "qualname": "Grid.A", "kind": "variable", "doc": "

A matrix for solving Ax = b

\n"}, "lib.grid.Grid.B": {"fullname": "lib.grid.Grid.B", "modulename": "lib.grid", "qualname": "Grid.B", "kind": "variable", "doc": "

b matrix for solving Ax = b

\n"}, "lib.grid.Grid.get_spacing": {"fullname": "lib.grid.Grid.get_spacing", "modulename": "lib.grid", "qualname": "Grid.get_spacing", "kind": "variable", "doc": "

Provides dx and dy

\n"}, "lib.grid.Grid.get_meshgrid": {"fullname": "lib.grid.Grid.get_meshgrid", "modulename": "lib.grid", "qualname": "Grid.get_meshgrid", "kind": "variable", "doc": "

Generates the x and y coordinates for the FD Mesh

\n"}, "lib.grid.Grid.dx": {"fullname": "lib.grid.Grid.dx", "modulename": "lib.grid", "qualname": "Grid.dx", "kind": "variable", "doc": "

Computes dx

\n"}, "lib.grid.Grid.dy": {"fullname": "lib.grid.Grid.dy", "modulename": "lib.grid", "qualname": "Grid.dy", "kind": "variable", "doc": "

Computes dy

\n"}, "lib.grid.Grid.set_FD_meshgrid": {"fullname": "lib.grid.Grid.set_FD_meshgrid", "modulename": "lib.grid", "qualname": "Grid.set_FD_meshgrid", "kind": "function", "doc": "

Generates FD coordinate grid for SP-flooding.\nUsed for the transport equations.

\n\n

Returns:\n (x, y) meshgrid arrays

\n", "signature": "(self):", "funcdef": "def"}, "lib.grid.Grid.get_flat_index_matrix": {"fullname": "lib.grid.Grid.get_flat_index_matrix", "modulename": "lib.grid", "qualname": "Grid.get_flat_index_matrix", "kind": "function", "doc": "

Returns a matrix of shape (n+1, m+1) with flat indices at each grid point.

\n", "signature": "(self) -> numpy.ndarray:", "funcdef": "def"}, "lib.grid.FEMesh": {"fullname": "lib.grid.FEMesh", "modulename": "lib.grid", "qualname": "FEMesh", "kind": "class", "doc": "

Encapsulates mesh generation, triangulation, FEM matrix assembly, and source vector setup.

\n\n

FIXME: Need to refactor this class to make it more understandable

\n", "bases": "Grid"}, "lib.grid.FEMesh.__init__": {"fullname": "lib.grid.FEMesh.__init__", "modulename": "lib.grid", "qualname": "FEMesh.__init__", "kind": "function", "doc": "

Constructor for the FEMesh class (subclass of the Grid class)

\n\n

Args:\n m (int): num columns\n n (int): num rows

\n", "signature": "(m: int, n: int)"}, "lib.grid.FEMesh.U": {"fullname": "lib.grid.FEMesh.U", "modulename": "lib.grid", "qualname": "FEMesh.U", "kind": "variable", "doc": "

U = cell array with each element = array of vertices of Upper Triangle of\nthe rectangular cell

\n"}, "lib.grid.FEMesh.L": {"fullname": "lib.grid.FEMesh.L", "modulename": "lib.grid", "qualname": "FEMesh.L", "kind": "variable", "doc": "

L = cell array with each element = array of vertices of Lower Triangle of\nthe rectangular cell

\n"}, "lib.grid.FEMesh.grid_size": {"fullname": "lib.grid.FEMesh.grid_size", "modulename": "lib.grid", "qualname": "FEMesh.grid_size", "kind": "variable", "doc": "

row size of square grid (# rows = # cols)

\n"}, "lib.grid.FEMesh.right_hand": {"fullname": "lib.grid.FEMesh.right_hand", "modulename": "lib.grid", "qualname": "FEMesh.right_hand", "kind": "variable", "doc": "

Matrix representation of the rhs of the global pressure and velocity equations that will subsequently be used\nto solve for the global pressure and velocity matrices.

\n"}, "lib.grid.FEMesh.A": {"fullname": "lib.grid.FEMesh.A", "modulename": "lib.grid", "qualname": "FEMesh.A", "kind": "variable", "doc": "

A matrix for solving Ax = b

\n"}, "lib.grid.FEMesh.B": {"fullname": "lib.grid.FEMesh.B", "modulename": "lib.grid", "qualname": "FEMesh.B", "kind": "variable", "doc": "

b matrix for solving Ax = b

\n"}, "lib.grid.FEMesh.sparsed_A": {"fullname": "lib.grid.FEMesh.sparsed_A", "modulename": "lib.grid", "qualname": "FEMesh.sparsed_A", "kind": "variable", "doc": "

sparsed matrix version of matrix A

\n"}, "lib.grid.FEMesh.set_triangulation": {"fullname": "lib.grid.FEMesh.set_triangulation", "modulename": "lib.grid", "qualname": "FEMesh.set_triangulation", "kind": "function", "doc": "

Setting up triangulations for the FEM grid

\n\n

At every point (i,j), U{i,j} & L{i,j} are cells with coordinates of vertices\nof the two triangles obtained by bisecting the rectangle starting at\n(i,j). The bisection line goes from NW to SE.

\n", "signature": "(self):", "funcdef": "def"}, "lib.grid.FEMesh.set_FE_meshgrid": {"fullname": "lib.grid.FEMesh.set_FE_meshgrid", "modulename": "lib.grid", "qualname": "FEMesh.set_FE_meshgrid", "kind": "function", "doc": "

Generate FE coordinate grid for elliptic pressure calculations\nAnalogous to the setGrid.m function in the MATLAB code

\n", "signature": "(self, beta):", "funcdef": "def"}, "lib.grid.FEMesh.set_right_hand": {"fullname": "lib.grid.FEMesh.set_right_hand", "modulename": "lib.grid", "qualname": "FEMesh.set_right_hand", "kind": "function", "doc": "

Sets the right hand side of the equation being solved to update the global pressure and velocity matrices

\n", "signature": "(self, source_prod_matrix):", "funcdef": "def"}, "lib.grid.FEMesh.get_A_B_matrices": {"fullname": "lib.grid.FEMesh.get_A_B_matrices", "modulename": "lib.grid", "qualname": "FEMesh.get_A_B_matrices", "kind": "function", "doc": "

\n", "signature": "(self):", "funcdef": "def"}, "lib.polymer": {"fullname": "lib.polymer", "modulename": "lib.polymer", "kind": "module", "doc": "

This python script contains the class definition for polymers for the surfactant-flooding model

\n\n

The methods of this class were derived from the MATLAB Surfactant-Polymer Flooding Code developed by\nSourav Dutta and Rohit Mishra.

\n\n

@author: Bhargav Akula Ramesh Kumar, Carlos Acosta Caripo

\n"}, "lib.polymer.Polymer": {"fullname": "lib.polymer.Polymer", "modulename": "lib.polymer", "qualname": "Polymer", "kind": "class", "doc": "

Class definition for the polymer objects and their calculations

\n"}, "lib.polymer.Polymer.__init__": {"fullname": "lib.polymer.Polymer.__init__", "modulename": "lib.polymer", "qualname": "Polymer.__init__", "kind": "function", "doc": "

Initializes a instance of the polymer class

\n", "signature": "(\tname: lib.enumerations.PolymerList,\te_coeff: numpy.ndarray,\tn_coeff: numpy.ndarray,\trho: float,\tconcentration_scalar: float,\tphi: numpy.ndarray,\tviscosity_scalar: float | None = None,\tviscosity_matrix: numpy.ndarray | None = None,\tconcentration_matrix: numpy.ndarray | None = None,\tshear_rate: numpy.ndarray | None = None)"}, "lib.polymer.Polymer.name": {"fullname": "lib.polymer.Polymer.name", "modulename": "lib.polymer", "qualname": "Polymer.name", "kind": "variable", "doc": "

name (enum 'PolymerList'): Name of the polymer

\n"}, "lib.polymer.Polymer.concetration_scalar": {"fullname": "lib.polymer.Polymer.concetration_scalar", "modulename": "lib.polymer", "qualname": "Polymer.concetration_scalar", "kind": "variable", "doc": "

concentration_scalar (float): Scalar quantity of concentration. When initializing, this param will equal the initial polymer concentration.

\n"}, "lib.polymer.Polymer.init_concentration_matrix": {"fullname": "lib.polymer.Polymer.init_concentration_matrix", "modulename": "lib.polymer", "qualname": "Polymer.init_concentration_matrix", "kind": "variable", "doc": "

Initial matrix (at time t = 0) representation of polymer concentration within resevoir

\n"}, "lib.polymer.Polymer.concentration_matrix": {"fullname": "lib.polymer.Polymer.concentration_matrix", "modulename": "lib.polymer", "qualname": "Polymer.concentration_matrix", "kind": "variable", "doc": "

concentration_matrix (np.ndarray, None): matrix representation of polymer concentration within resevoir over time

\n"}, "lib.polymer.Polymer.viscosity_matrix": {"fullname": "lib.polymer.Polymer.viscosity_matrix", "modulename": "lib.polymer", "qualname": "Polymer.viscosity_matrix", "kind": "variable", "doc": "

viscosity_matrix (np.ndarray, None): viscosity matrix of the polymer

\n"}, "lib.polymer.Polymer.viscosity_scalar": {"fullname": "lib.polymer.Polymer.viscosity_scalar", "modulename": "lib.polymer", "qualname": "Polymer.viscosity_scalar", "kind": "variable", "doc": "

viscosity_scalar (float, None): scalar quantity of the polymer viscosity

\n"}, "lib.polymer.Polymer.e_coeff": {"fullname": "lib.polymer.Polymer.e_coeff", "modulename": "lib.polymer", "qualname": "Polymer.e_coeff", "kind": "variable", "doc": "

e_coeff (list[float]): The coefficients used to determine epsilon for the empirical power law expression used to determine the viscosity of the aqueous phase

\n"}, "lib.polymer.Polymer.n_coeff": {"fullname": "lib.polymer.Polymer.n_coeff", "modulename": "lib.polymer", "qualname": "Polymer.n_coeff", "kind": "variable", "doc": "

n_coeff (list[float]): The coefficients used to determine epsilon for the empirical power law expression used to determine the viscosity of the aqueous phase

\n"}, "lib.polymer.Polymer.rho": {"fullname": "lib.polymer.Polymer.rho", "modulename": "lib.polymer", "qualname": "Polymer.rho", "kind": "variable", "doc": "

rho (float): Density of polymer

\n"}, "lib.polymer.Polymer.shear_rate": {"fullname": "lib.polymer.Polymer.shear_rate", "modulename": "lib.polymer", "qualname": "Polymer.shear_rate", "kind": "variable", "doc": "

shear_rate (np.ndarray, None): Matrix that will hold the shear rate (the change in velocity normal to the direction of flow)

\n"}, "lib.polymer.Polymer.phi": {"fullname": "lib.polymer.Polymer.phi", "modulename": "lib.polymer", "qualname": "Polymer.phi", "kind": "variable", "doc": "

phi (np.ndarray): arrray used to initialize the concentration matrix (represents porosity of the resevoir)

\n"}, "lib.polymer.Polymer.initialize": {"fullname": "lib.polymer.Polymer.initialize", "modulename": "lib.polymer", "qualname": "Polymer.initialize", "kind": "function", "doc": "

Will initialize the viscosity, shear_rate, and concentration matrices

\n\n

Args:

\n\n
grid_shape (tuple): contain the shape of the grid\n
\n\n

Returns: (Polymer)

\n\n
Initalized Polymer Object\n
\n", "signature": "(self, grid_shape: tuple):", "funcdef": "def"}, "lib.polymer.Polymer.compute_viscosity": {"fullname": "lib.polymer.Polymer.compute_viscosity", "modulename": "lib.polymer", "qualname": "Polymer.compute_viscosity", "kind": "function", "doc": "

Compute polymer viscosity.\nThis function is derived from 'compvis()' in the original MATLAB code (in file compvis.m).

\n\n

Args:

\n\n
grid (Tuple[NDArray[Any], ...]): The FEM grid used for simulation calculations (x and y variables from the MATLAB code)\n\nu (np.ndarray): Matrix related to the global pressure\n\nv (np.ndarray): Matrix related to the velocity matrix\n\nmodel_type (enum 'ModelType'): Will state whether the model will include polymer shear thinning or not\n\naqueous_viscosity (np.ndarray, None): Aqueous viscosity matrix (will come from the ``Water`` class). Only needed when shear thinning OFF\n
\n\n

Returns: (list)

\n\n
the viscosity_matrix (index 0) & shear_rate matrix (index 1) for the polymer within the grid\n
\n", "signature": "(\tself,\tgrid: lib.grid.Grid,\tu: numpy.ndarray,\tv: numpy.ndarray,\tmodel_type: lib.enumerations.ModelType,\taqueous_viscosity: numpy.ndarray | None = None):", "funcdef": "def"}, "lib.polymer.Polymer.compute_concentration": {"fullname": "lib.polymer.Polymer.compute_concentration", "modulename": "lib.polymer", "qualname": "Polymer.compute_concentration", "kind": "function", "doc": "

Computes the polymer concentration

\n\n

Raises:

\n\n
SimulationCalcInputException: Not all required parameters were provided\n
\n\n

Args:

\n\n
grid (Grid): the FDMesh\n\nwater_sat (np.ndarray): the water saturation matrix\n\nu (np.ndarray): Matrix related to the global pressure\n\nv (np.ndarray): Matrix related to the velocity matrix\n\nxmod (np.ndarray): x-dim characteristic coordinates based on Neumann boundary conditions\n\nymod (np.ndarray): y-dim characteristic coordinates based on Neumann boundary conditions\n\nconst_parameters (dict): constant parameters to help with calculations\n\nvarying_parameters (dict): parameters that vary but assist with calculations for water saturation, polymer concentration, and surfactant concentration\n
\n\n

Returns: (dict)

\n\n
The varying parameters that were changed in this method\n
\n", "signature": "(\tself,\tgrid: lib.grid.Grid,\twater_sat: numpy.ndarray,\tu: numpy.ndarray,\tv: numpy.ndarray,\txmod: numpy.ndarray,\tymod: numpy.ndarray,\tconst_parameters: dict,\tvarying_parameters: dict):", "funcdef": "def"}, "lib.polymer.Polymer.divergence": {"fullname": "lib.polymer.Polymer.divergence", "modulename": "lib.polymer", "qualname": "Polymer.divergence", "kind": "function", "doc": "

Calculates Divergence

\n\n

Args:

\n\n
Fx (np.ndarray): Function #1\n\nFy (np.ndarray): Function #2\n\ndx (float): change in the x-dimension\n\ndy (float): change in the y-dimension\n
\n\n

Raises: (np.ndarray)

\n\n
Div F = (\u03b4fx/\u03b4x) + (\u03b4fy/\u03b4y)\n
\n", "signature": "(self, Fx, Fy, dx=1.0, dy=1.0):", "funcdef": "def"}, "lib.simulation": {"fullname": "lib.simulation", "modulename": "lib.simulation", "kind": "module", "doc": "

This python script contains the class definition for running simulations

\n\n

This Python code has been derived from the MATLAB Surfactant-Polymer Flooding Simulation \ndeveloped by Sourav Dutta and Rohit Mishra.

\n\n

@author: Bhargav Akula Ramesh Kumar and Carlos Acosta Caripo

\n"}, "lib.simulation.Simulation": {"fullname": "lib.simulation.Simulation", "modulename": "lib.simulation", "qualname": "Simulation", "kind": "class", "doc": "

Simulation class to run SP-flooding simulations based on MATLAB translation.

\n"}, "lib.simulation.Simulation.__init__": {"fullname": "lib.simulation.Simulation.__init__", "modulename": "lib.simulation", "qualname": "Simulation.__init__", "kind": "function", "doc": "

This method will check the user_input_dict and initialize the simulation

\n\n

Raises:

\n\n
UserInputException: If there is a issue with the user inputs in ``user_input_dict``\nSimulationCalcInputException: If there is an issue with the execution of a calculation during runtime\n
\n\n

Args:

\n\n
user_input_dict (dict): dictionary containing the information from the GUI\n
\n", "signature": "(user_input_dict: dict)"}, "lib.simulation.Simulation.grid_size": {"fullname": "lib.simulation.Simulation.grid_size", "modulename": "lib.simulation", "qualname": "Simulation.grid_size", "kind": "variable", "doc": "

grid_size (float): the dimensions of the square grid

\n"}, "lib.simulation.Simulation.source_flow_magnitude": {"fullname": "lib.simulation.Simulation.source_flow_magnitude", "modulename": "lib.simulation", "qualname": "Simulation.source_flow_magnitude", "kind": "variable", "doc": "

source_flow_magnitude (float): flow rate at injection site

\n"}, "lib.simulation.Simulation.permeability_flag": {"fullname": "lib.simulation.Simulation.permeability_flag", "modulename": "lib.simulation", "qualname": "Simulation.permeability_flag", "kind": "variable", "doc": "

permeability_flag (enum 'PermeabilityType'): sets the permeability field based on enum PermeabilityType

\n"}, "lib.simulation.Simulation.reservoir_geometry": {"fullname": "lib.simulation.Simulation.reservoir_geometry", "modulename": "lib.simulation", "qualname": "Simulation.reservoir_geometry", "kind": "variable", "doc": "

reservoir_geometry (enum 'ResevoirGeometry'): sets the reservoir geometry based on the enum ResevoirGeometry

\n"}, "lib.simulation.Simulation.model_type": {"fullname": "lib.simulation.Simulation.model_type", "modulename": "lib.simulation", "qualname": "Simulation.model_type", "kind": "variable", "doc": "

model_type (enum 'ModelType'): sets the type of simulation being run based on the enum ModelType

\n"}, "lib.simulation.Simulation.relative_permeability_formula": {"fullname": "lib.simulation.Simulation.relative_permeability_formula", "modulename": "lib.simulation", "qualname": "Simulation.relative_permeability_formula", "kind": "variable", "doc": "

relative_permeability_formula (enum 'RelativePermeabilityFormula'): sets the type of permeability formula being used in the simulation, based on the enum RelativePermeabilityFormula

\n"}, "lib.simulation.Simulation.phi": {"fullname": "lib.simulation.Simulation.phi", "modulename": "lib.simulation", "qualname": "Simulation.phi", "kind": "variable", "doc": "

phi (np.ndarray): porosity matrix

\n"}, "lib.simulation.Simulation.KK": {"fullname": "lib.simulation.Simulation.KK", "modulename": "lib.simulation", "qualname": "Simulation.KK", "kind": "variable", "doc": "

KK (np.ndarray): the permeability matrix

\n"}, "lib.simulation.Simulation.time_step": {"fullname": "lib.simulation.Simulation.time_step", "modulename": "lib.simulation", "qualname": "Simulation.time_step", "kind": "variable", "doc": "

time_step (float): The \u0394t

\n"}, "lib.simulation.Simulation.polymer": {"fullname": "lib.simulation.Simulation.polymer", "modulename": "lib.simulation", "qualname": "Simulation.polymer", "kind": "variable", "doc": "

polymer (Polymer): Holds the Polymer object

\n"}, "lib.simulation.Simulation.surfactant": {"fullname": "lib.simulation.Simulation.surfactant", "modulename": "lib.simulation", "qualname": "Simulation.surfactant", "kind": "variable", "doc": "

surfactant (Surfactant): Holds the Surfactant object

\n"}, "lib.simulation.Simulation.water": {"fullname": "lib.simulation.Simulation.water", "modulename": "lib.simulation", "qualname": "Simulation.water", "kind": "variable", "doc": "

water (Water): Holds the Water object

\n"}, "lib.simulation.Simulation.COC": {"fullname": "lib.simulation.Simulation.COC", "modulename": "lib.simulation", "qualname": "Simulation.COC", "kind": "variable", "doc": "

COC (np.ndarray): An array that holds the cummulative oil captured

\n"}, "lib.simulation.Simulation.miuaTcal": {"fullname": "lib.simulation.Simulation.miuaTcal", "modulename": "lib.simulation", "qualname": "Simulation.miuaTcal", "kind": "variable", "doc": "

miuTcal (np.ndarray): An array that caputres the change in the total aqueous viscosity over time

\n"}, "lib.simulation.Simulation.lambdaTcal": {"fullname": "lib.simulation.Simulation.lambdaTcal", "modulename": "lib.simulation", "qualname": "Simulation.lambdaTcal", "kind": "variable", "doc": "

lambdaTcal (np.ndarray): Array that holds the change in the total mobility (\u03bb_T = \u03bb_a + \u03bb_o)

\n"}, "lib.simulation.Simulation.MFW": {"fullname": "lib.simulation.Simulation.MFW", "modulename": "lib.simulation", "qualname": "Simulation.MFW", "kind": "variable", "doc": "

MFW (np.ndarray): Array that holds change in the MFW (mean finger width)

\n"}, "lib.simulation.Simulation.integrated_inlet_flow": {"fullname": "lib.simulation.Simulation.integrated_inlet_flow", "modulename": "lib.simulation", "qualname": "Simulation.integrated_inlet_flow", "kind": "variable", "doc": "

integrated_inlet_flow (float): Basically the integrating the source flow rate over time

\n"}, "lib.simulation.Simulation.source_prod_flow": {"fullname": "lib.simulation.Simulation.source_prod_flow", "modulename": "lib.simulation", "qualname": "Simulation.source_prod_flow", "kind": "variable", "doc": "

source_prod_flow (np.ndarray): The matrix with the source & and production well flow rates

\n\n

assuming that the source flow = production well flow (flow magnitudes are the same!)

\n"}, "lib.simulation.Simulation.scenario_flag": {"fullname": "lib.simulation.Simulation.scenario_flag", "modulename": "lib.simulation", "qualname": "Simulation.scenario_flag", "kind": "variable", "doc": "

Determines the scenario based on the chosen reservoir geometry and permeability.\nReturns the integer value that represents a type of scenario run

\n"}, "lib.simulation.Simulation.run": {"fullname": "lib.simulation.Simulation.run", "modulename": "lib.simulation", "qualname": "Simulation.run", "kind": "function", "doc": "

Executes simulation loop.

\n\n

Raises:

\n\n
SimulationCalcInputException: If there is an issue with the execution of a calculation during runtime\n
\n", "signature": "(self):", "funcdef": "def"}, "lib.surfactant": {"fullname": "lib.surfactant", "modulename": "lib.surfactant", "kind": "module", "doc": "

This python script contains the class definition for surfactants for the surfactant-flooding model

\n\n

The methods of this class were derived from the MATLAB Surfactant-Polymer Flooding Code developed by\nSourav Dutta and Rohit Mishra.

\n\n

@author: Bhargav Akula Ramesh Kumar, Carlos Acosta Caripo

\n"}, "lib.surfactant.Surfactant": {"fullname": "lib.surfactant.Surfactant", "modulename": "lib.surfactant", "qualname": "Surfactant", "kind": "class", "doc": "

Contains property and calculations related to the surfactant object

\n"}, "lib.surfactant.Surfactant.__init__": {"fullname": "lib.surfactant.Surfactant.__init__", "modulename": "lib.surfactant", "qualname": "Surfactant.__init__", "kind": "function", "doc": "

Creates instance of Surfactant class

\n", "signature": "(\tname: lib.enumerations.SurfactantList,\tinitial_concentration: float,\tphi: numpy.ndarray,\tIFT_equation: function | None = None,\tderivative_IFT_equation: function | None = None,\tconcentration_matrix: numpy.ndarray | None = None)"}, "lib.surfactant.Surfactant.name": {"fullname": "lib.surfactant.Surfactant.name", "modulename": "lib.surfactant", "qualname": "Surfactant.name", "kind": "variable", "doc": "

name (enum 'SurfactantList'): Name of the surfactant

\n"}, "lib.surfactant.Surfactant.concentration": {"fullname": "lib.surfactant.Surfactant.concentration", "modulename": "lib.surfactant", "qualname": "Surfactant.concentration", "kind": "variable", "doc": "

concentration (float): Initial concentration of surfactant (scalar quantity)

\n"}, "lib.surfactant.Surfactant.concentration_matrix": {"fullname": "lib.surfactant.Surfactant.concentration_matrix", "modulename": "lib.surfactant", "qualname": "Surfactant.concentration_matrix", "kind": "variable", "doc": "

concentration_matrix (np.ndarray, None): vector representation of surfactant concentration in resevoir

\n"}, "lib.surfactant.Surfactant.IFT_conc_equ": {"fullname": "lib.surfactant.Surfactant.IFT_conc_equ", "modulename": "lib.surfactant", "qualname": "Surfactant.IFT_conc_equ", "kind": "variable", "doc": "

IFT_conc_equ (lambda, None): expression that relates surfactant concentration to interfacial tension b/t oil and water

\n"}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"fullname": "lib.surfactant.Surfactant.derivative_IFT_conc_equ", "modulename": "lib.surfactant", "qualname": "Surfactant.derivative_IFT_conc_equ", "kind": "variable", "doc": "

derivative_IFT_conc_equ (lambda, None): Deriviative of the equation relating IFT to surfactant concentration

\n"}, "lib.surfactant.Surfactant.is_surfactant": {"fullname": "lib.surfactant.Surfactant.is_surfactant", "modulename": "lib.surfactant", "qualname": "Surfactant.is_surfactant", "kind": "variable", "doc": "

flag for whether or not surfactant is in the simulation

\n"}, "lib.surfactant.Surfactant.phi": {"fullname": "lib.surfactant.Surfactant.phi", "modulename": "lib.surfactant", "qualname": "Surfactant.phi", "kind": "variable", "doc": "

phi (np.ndarray): arrray used to initialize the concentration matrix (represents porosity of the resevoir)

\n"}, "lib.surfactant.Surfactant.eval_IFT": {"fullname": "lib.surfactant.Surfactant.eval_IFT", "modulename": "lib.surfactant", "qualname": "Surfactant.eval_IFT", "kind": "variable", "doc": "

evaluate IFT at a given surfactant concentration_matrix

\n"}, "lib.surfactant.Surfactant.eval_dIFT_dGamma": {"fullname": "lib.surfactant.Surfactant.eval_dIFT_dGamma", "modulename": "lib.surfactant", "qualname": "Surfactant.eval_dIFT_dGamma", "kind": "variable", "doc": "

evaluate the d\u03c3/d\u0393 at a particular surfactant concentration matrix

\n"}, "lib.surfactant.Surfactant.initialize": {"fullname": "lib.surfactant.Surfactant.initialize", "modulename": "lib.surfactant", "qualname": "Surfactant.initialize", "kind": "function", "doc": "

This function will initialize the surfactant object

\n\n

Returns: (Surfactant)\n Surfactant object

\n", "signature": "(self):", "funcdef": "def"}, "lib.surfactant.Surfactant.compute_concentration": {"fullname": "lib.surfactant.Surfactant.compute_concentration", "modulename": "lib.surfactant", "qualname": "Surfactant.compute_concentration", "kind": "function", "doc": "

Computing the surfactant concentration matrix

\n\n

Raises:\n SimulationCalcInputException: Not all required inputs were provided

\n\n

Args:\n grid (Grid): FD mesh

\n\n
water_sat (np.ndarray): water saturation matrix\n\nconst_parameters (dict): dictionary object with constant parameters used in calculation\n\nvarying_parameters (dict): dictionary object with varying parameters used in calculation\n\nF (np.ndarray): intermediate matrix used in calcs\n\nGmod (np.ndarray): bilinear interpolant for sur conc on redefined coordinates\n
\n\n

Returns: (dict)\n Returns the varying_parameters dict

\n", "signature": "(\tself,\tgrid: lib.grid.Grid,\twater_sat: numpy.ndarray,\tconst_parameters: dict,\tvarying_parameters: dict,\tF: numpy.ndarray,\tGmod: numpy.ndarray):", "funcdef": "def"}, "lib.test": {"fullname": "lib.test", "modulename": "lib.test", "kind": "module", "doc": "

\n"}, "lib.water": {"fullname": "lib.water", "modulename": "lib.water", "kind": "module", "doc": "

This python script contains the class definition for the water in the surfactant-flooding model

\n\n

The methods of this class were derived from the MATLAB Surfactant-Polymer Flooding Code developed by\nSourav Dutta and Rohit Mishra.

\n\n

@author: Bhargav Akula Ramesh Kumar, Carlos Acosta Caripo

\n"}, "lib.water.Water": {"fullname": "lib.water.Water", "modulename": "lib.water", "qualname": "Water", "kind": "class", "doc": "

Contains the properties and methods for water in the SP-Flooding system

\n"}, "lib.water.Water.__init__": {"fullname": "lib.water.Water.__init__", "modulename": "lib.water", "qualname": "Water.__init__", "kind": "function", "doc": "

Constructor for the Water class

\n", "signature": "(\tinit_water_saturation: float,\tinit_aqueous_saturation: float,\tinit_oleic_saturation: float,\tmiuw: float,\tmiuo: float,\tphi: numpy.ndarray)"}, "lib.water.Water.init_water_saturation": {"fullname": "lib.water.Water.init_water_saturation", "modulename": "lib.water", "qualname": "Water.init_water_saturation", "kind": "variable", "doc": "

init_water_saturation (float): initial residual water saturation

\n"}, "lib.water.Water.init_aqueous_saturation": {"fullname": "lib.water.Water.init_aqueous_saturation", "modulename": "lib.water", "qualname": "Water.init_aqueous_saturation", "kind": "variable", "doc": "

init_aqueous_saturation (float): initial residual aqueous phase saturation below critical capillary number (when \u03c3 = 0)

\n"}, "lib.water.Water.init_oleic_saturation": {"fullname": "lib.water.Water.init_oleic_saturation", "modulename": "lib.water", "qualname": "Water.init_oleic_saturation", "kind": "variable", "doc": "

init_oleic_saturation (float): initial residual oil phase saturation below the critical capillary number (when \u03c3 = 0)

\n"}, "lib.water.Water.miuw": {"fullname": "lib.water.Water.miuw", "modulename": "lib.water", "qualname": "Water.miuw", "kind": "variable", "doc": "

miuw (float): water viscosity

\n"}, "lib.water.Water.miuo": {"fullname": "lib.water.Water.miuo", "modulename": "lib.water", "qualname": "Water.miuo", "kind": "variable", "doc": "

miuo (float): oil viscosity

\n"}, "lib.water.Water.water_saturation": {"fullname": "lib.water.Water.water_saturation", "modulename": "lib.water", "qualname": "Water.water_saturation", "kind": "variable", "doc": "

water_saturation (np.ndarray): The water saturation matrix being updated using the transport equations

\n"}, "lib.water.Water.viscosity_array": {"fullname": "lib.water.Water.viscosity_array", "modulename": "lib.water", "qualname": "Water.viscosity_array", "kind": "variable", "doc": "

viscosity_array (np.ndarray): The water viscosity matrix

\n"}, "lib.water.Water.phi": {"fullname": "lib.water.Water.phi", "modulename": "lib.water", "qualname": "Water.phi", "kind": "variable", "doc": "

phi (np.ndarray): porosity matrix

\n"}, "lib.water.Water.initialize": {"fullname": "lib.water.Water.initialize", "modulename": "lib.water", "qualname": "Water.initialize", "kind": "function", "doc": "

Initializing 'Water' object properties

\n\n

Raises:

\n\n
SimuationInputException: Either Intial water saturation and/or porosity matrix not provided for initializing Water object\n
\n\n

Args:

\n\n
grid_shape (tuple): the n and m parameters from the 'Grid' class\n
\n\n

Returns: (Water)

\n\n
Initializes the Water object\n
\n", "signature": "(self, grid_shape: tuple):", "funcdef": "def"}, "lib.water.Water.compute_viscosity": {"fullname": "lib.water.Water.compute_viscosity", "modulename": "lib.water", "qualname": "Water.compute_viscosity", "kind": "function", "doc": "

Compute aqueous viscosity.

\n\n

Raises:

\n\n
SimulationCalcInputException: Not all required parameters provided\n
\n\n

Args:

\n\n
grid (Grid): Grid object for deterrmining matrix size\n\nmodel_type (enum 'ModelType'): Type of model we are running (Polymer shear thinning ON or OFF)\n\npolymer (Polymer): holds the information about the polymer in the sim\n\nu (np.ndarray, None): global pressure matrix. Only needed when shear thinning ON.\n\nv (np.ndarray, None): velocity matrix. Only needed when shear thinning ON.\n
\n\n

Returns: (np.ndarray)

\n\n
Updated aqueous viscosity matrix\n
\n", "signature": "(\tself,\tgrid: lib.grid.Grid,\tmodel_type: lib.enumerations.ModelType,\tpolymer: lib.polymer.Polymer,\tu: numpy.ndarray | None = None,\tv: numpy.ndarray | None = None):", "funcdef": "def"}, "lib.water.Water.compute_residual_saturations": {"fullname": "lib.water.Water.compute_residual_saturations", "modulename": "lib.water", "qualname": "Water.compute_residual_saturations", "kind": "function", "doc": "

Compute swr, sor based on capillary numbers (came from compres.m MATLAB file)

\n\n

Args:

\n\n
sigma (np.ndarray): interfacial tension (IFT)\n\nu (np.ndarray): global pressure matrix.\n\nv (np.ndarray): velocity matrix.\n
\n\n

Returns: (list)

\n\n
residual saturation for oil (index 1) and water (index 0) phases\n
\n", "signature": "(self, sigma: numpy.ndarray, u: numpy.ndarray, v: numpy.ndarray):", "funcdef": "def"}, "lib.water.Water.compute_mobility": {"fullname": "lib.water.Water.compute_mobility", "modulename": "lib.water", "qualname": "Water.compute_mobility", "kind": "function", "doc": "

Computing mobility (made using the compmob.m MATLAB file)

\n\n

Raise:

\n\n
SimulationCalcInputException: Not all required arguments are not provided\n
\n\n

Args:

\n\n
c (np.ndarray): polymer concentration matrix\n\nsor (float): residual saturation oil phase\n\nswr (float): residual saturation water phase\n\naqueous (bool): boolean for whether we are solving for aqoeous or oleic mobility\n\nrel_permeability_formula (enum 'RelativePermeabilityFormula'): Select the type of relative Permeability formula from the ``RelativePermeabilityFormula`` Enum\n\nsurfactant_conc (float): scalar quantity of the initial surfactant concentration\n
\n\n

Returns: (np.ndarray)

\n\n
aqueous or oleic mobility (depending on the 'aqueous' parameter)\n
\n", "signature": "(\tself,\tc: numpy.ndarray,\tsor: float,\tswr: float,\taqueous: bool,\trel_permeability_formula: lib.enumerations.RelativePermeabilityFormula,\tmodified_water_saturation: numpy.ndarray | None = None):", "funcdef": "def"}, "lib.water.Water.compute_water_saturation": {"fullname": "lib.water.Water.compute_water_saturation", "modulename": "lib.water", "qualname": "Water.compute_water_saturation", "kind": "function", "doc": "

Solving saturation equation (comes from part of the nmmoc_surf_mod_neumann.m file that\nis for calculating the water saturation)

\n\n

Raises:

\n\n
SimulationCalcInputException: If water saturation matrix is None\n
\n\n

Args:

\n\n
grid (Grid): the 'Grid' object\n\nsurfactant (Surfactant): The surfactant object\n\npolymer (Polymer): The polymer object\n\nu (np.ndarray): global pressure matrix\n\nv (np.ndarray): velocity matrix\n\nxmod (np.ndarray): x-dimension coordinate points for formulating the 'Qmod' matrix\n\nymod (np.ndarray): y-dimension coordinate points for formulating the 'Qmod' matrix\n\nconst_parameters (dict): constant parameters used in the method\n\nvarying_parameters (dict): parameters whose values can change\n
\n\n

Returns: (np.ndarray, dict)

\n\n
Updates the ``water_saturation`` matrix and ``varying_parameters`` dict\n
\n", "signature": "(\tself,\tgrid: lib.grid.Grid,\tsurfactant: lib.surfactant.Surfactant,\tpolymer: lib.polymer.Polymer,\tu: numpy.ndarray,\tv: numpy.ndarray,\txmod: numpy.ndarray,\tymod: numpy.ndarray,\tconst_parameters: dict,\tvarying_parameters: dict):", "funcdef": "def"}}, "docInfo": {"lib": {"qualname": 0, "fullname": 1, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 3}, "lib.name": {"qualname": 1, "fullname": 2, "annotation": 0, "default_value": 5, "signature": 0, "bases": 0, "doc": 3}, "lib.Exceptions": {"qualname": 0, "fullname": 2, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 3}, "lib.Exceptions.OutOfRangeError": {"qualname": 1, "fullname": 3, "annotation": 0, "default_value": 0, "signature": 0, "bases": 2, "doc": 16}, "lib.Exceptions.OutOfRangeError.__init__": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 29, "bases": 0, "doc": 23}, "lib.Exceptions.SimulationCalcInputException": {"qualname": 1, "fullname": 3, "annotation": 0, "default_value": 0, "signature": 0, "bases": 2, "doc": 13}, "lib.Exceptions.SimulationCalcInputException.__init__": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 9, "bases": 0, "doc": 21}, "lib.Exceptions.UserInputException": {"qualname": 1, "fullname": 3, "annotation": 0, "default_value": 0, "signature": 0, "bases": 2, "doc": 12}, "lib.Exceptions.UserInputException.__init__": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 37, "bases": 0, "doc": 38}, "lib.enumerations": {"qualname": 0, "fullname": 2, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 53}, "lib.enumerations.SimulationConstants": {"qualname": 1, "fullname": 3, "annotation": 0, "default_value": 0, "signature": 0, "bases": 2, "doc": 20}, "lib.enumerations.SimulationConstants.Water_Viscosity": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 9, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.SimulationConstants.Water_Density": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 8, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.SimulationConstants.Oil_Viscosity": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 8, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"qualname": 5, "fullname": 7, "annotation": 0, "default_value": 11, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"qualname": 6, "fullname": 8, "annotation": 0, "default_value": 12, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"qualname": 6, "fullname": 8, "annotation": 0, "default_value": 12, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"qualname": 6, "fullname": 8, "annotation": 0, "default_value": 12, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"qualname": 6, "fullname": 8, "annotation": 0, "default_value": 12, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"qualname": 5, "fullname": 7, "annotation": 0, "default_value": 12, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"qualname": 5, "fullname": 7, "annotation": 0, "default_value": 11, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.SimulationConstants.Injection_Rate": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 8, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.SimulationConstants.Time_Step": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 9, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.SimulationConstants.Grid_Size": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 8, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.SimulationConstants.Source_Flow_Magnitude": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 9, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.SimulationConstants.beta1": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 7, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.PolymerList": {"qualname": 1, "fullname": 3, "annotation": 0, "default_value": 0, "signature": 0, "bases": 2, "doc": 13}, "lib.enumerations.PolymerList.Xanthane": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 21, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.PolymerList.Schizophyllan": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 20, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.PolymerList.No_Polymer": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 13, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.PolymerList.Id": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 8}, "lib.enumerations.PolymerList.Density": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 9}, "lib.enumerations.PolymerList.n_coeff": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 14}, "lib.enumerations.PolymerList.e_coeff": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 14}, "lib.enumerations.PolymerList.get_by_value": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 16, "bases": 0, "doc": 9}, "lib.enumerations.SurfactantList": {"qualname": 1, "fullname": 3, "annotation": 0, "default_value": 0, "signature": 0, "bases": 2, "doc": 23}, "lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 23, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.SurfactantList.No_Surfactant": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 22, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.SurfactantList.Id": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 8}, "lib.enumerations.SurfactantList.IFT_equation": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 14}, "lib.enumerations.SurfactantList.derivative_IFT_equation": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 13}, "lib.enumerations.SurfactantList.get_by_value": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 16, "bases": 0, "doc": 9}, "lib.enumerations.ModelType": {"qualname": 1, "fullname": 3, "annotation": 0, "default_value": 0, "signature": 0, "bases": 2, "doc": 10}, "lib.enumerations.ModelType.No_Shear_Thinning": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 9, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.ModelType.Sourav_Implementation": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 8, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.ModelType.Shear_Thinning_On": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 9, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.PlotType": {"qualname": 1, "fullname": 3, "annotation": 0, "default_value": 0, "signature": 0, "bases": 2, "doc": 14}, "lib.enumerations.PlotType.Saturation_Plot": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 8, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.PlotType.Polymer_Concentration_Plot": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 9, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.PlotType.Surfactant_Concentration_Plot": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 9, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.ResevoirGeometry": {"qualname": 1, "fullname": 3, "annotation": 0, "default_value": 0, "signature": 0, "bases": 2, "doc": 12}, "lib.enumerations.ResevoirGeometry.Rectilinear": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 7, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.ResevoirGeometry.Quarter_Five_Spot": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 9, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.PermeabilityType": {"qualname": 1, "fullname": 3, "annotation": 0, "default_value": 0, "signature": 0, "bases": 2, "doc": 13}, "lib.enumerations.PermeabilityType.Homogenous": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 7, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.PermeabilityType.Heterogenous": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 7, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.RelativePermeabilityFormula": {"qualname": 1, "fullname": 3, "annotation": 0, "default_value": 0, "signature": 0, "bases": 2, "doc": 11}, "lib.enumerations.RelativePermeabilityFormula.AmaefuleHandEquation": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 7, "signature": 0, "bases": 0, "doc": 3}, "lib.enumerations.RelativePermeabilityFormula.CoreyTypeEquation": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 7, "signature": 0, "bases": 0, "doc": 3}, "lib.grid": {"qualname": 0, "fullname": 2, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 46}, "lib.grid.Grid": {"qualname": 1, "fullname": 3, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 27}, "lib.grid.Grid.__init__": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 102, "bases": 0, "doc": 3}, "lib.grid.Grid.m": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 6}, "lib.grid.Grid.n": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 6}, "lib.grid.Grid.left": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 19}, "lib.grid.Grid.right": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 20}, "lib.grid.Grid.bottom": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 20}, "lib.grid.Grid.top": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 20}, "lib.grid.Grid.A": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 8}, "lib.grid.Grid.B": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 8}, "lib.grid.Grid.get_spacing": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 6}, "lib.grid.Grid.get_meshgrid": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 12}, "lib.grid.Grid.dx": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 6}, "lib.grid.Grid.dy": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 6}, "lib.grid.Grid.set_FD_meshgrid": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 11, "bases": 0, "doc": 22}, "lib.grid.Grid.get_flat_index_matrix": {"qualname": 5, "fullname": 7, "annotation": 0, "default_value": 0, "signature": 19, "bases": 0, "doc": 17}, "lib.grid.FEMesh": {"qualname": 1, "fullname": 3, "annotation": 0, "default_value": 0, "signature": 0, "bases": 1, "doc": 27}, "lib.grid.FEMesh.__init__": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 24, "bases": 0, "doc": 30}, "lib.grid.FEMesh.U": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 18}, "lib.grid.FEMesh.L": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 18}, "lib.grid.FEMesh.grid_size": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 12}, "lib.grid.FEMesh.right_hand": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 29}, "lib.grid.FEMesh.A": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 8}, "lib.grid.FEMesh.B": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 8}, "lib.grid.FEMesh.sparsed_A": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 10}, "lib.grid.FEMesh.set_triangulation": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 11, "bases": 0, "doc": 49}, "lib.grid.FEMesh.set_FE_meshgrid": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 16, "bases": 0, "doc": 20}, "lib.grid.FEMesh.set_right_hand": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 18, "bases": 0, "doc": 20}, "lib.grid.FEMesh.get_A_B_matrices": {"qualname": 5, "fullname": 7, "annotation": 0, "default_value": 0, "signature": 11, "bases": 0, "doc": 3}, "lib.polymer": {"qualname": 0, "fullname": 2, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 50}, "lib.polymer.Polymer": {"qualname": 1, "fullname": 3, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 11}, "lib.polymer.Polymer.__init__": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 213, "bases": 0, "doc": 9}, "lib.polymer.Polymer.name": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 10}, "lib.polymer.Polymer.concetration_scalar": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 21}, "lib.polymer.Polymer.init_concentration_matrix": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 14}, "lib.polymer.Polymer.concentration_matrix": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 17}, "lib.polymer.Polymer.viscosity_matrix": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 13}, "lib.polymer.Polymer.viscosity_scalar": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 13}, "lib.polymer.Polymer.e_coeff": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 27}, "lib.polymer.Polymer.n_coeff": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 27}, "lib.polymer.Polymer.rho": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 8}, "lib.polymer.Polymer.shear_rate": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 26}, "lib.polymer.Polymer.phi": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 19}, "lib.polymer.Polymer.initialize": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 22, "bases": 0, "doc": 42}, "lib.polymer.Polymer.compute_viscosity": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 117, "bases": 0, "doc": 133}, "lib.polymer.Polymer.compute_concentration": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 138, "bases": 0, "doc": 137}, "lib.polymer.Polymer.divergence": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 43, "bases": 0, "doc": 56}, "lib.simulation": {"qualname": 0, "fullname": 2, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 46}, "lib.simulation.Simulation": {"qualname": 1, "fullname": 3, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 14}, "lib.simulation.Simulation.__init__": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 16, "bases": 0, "doc": 72}, "lib.simulation.Simulation.grid_size": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 12}, "lib.simulation.Simulation.source_flow_magnitude": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 12}, "lib.simulation.Simulation.permeability_flag": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 17}, "lib.simulation.Simulation.reservoir_geometry": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 18}, "lib.simulation.Simulation.model_type": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 21}, "lib.simulation.Simulation.relative_permeability_formula": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 26}, "lib.simulation.Simulation.phi": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 8}, "lib.simulation.Simulation.KK": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 9}, "lib.simulation.Simulation.time_step": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 8}, "lib.simulation.Simulation.polymer": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 11}, "lib.simulation.Simulation.surfactant": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 11}, "lib.simulation.Simulation.water": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 11}, "lib.simulation.Simulation.COC": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 14}, "lib.simulation.Simulation.miuaTcal": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 19}, "lib.simulation.Simulation.lambdaTcal": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 23}, "lib.simulation.Simulation.MFW": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 17}, "lib.simulation.Simulation.integrated_inlet_flow": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 16}, "lib.simulation.Simulation.source_prod_flow": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 35}, "lib.simulation.Simulation.scenario_flag": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 24}, "lib.simulation.Simulation.run": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 11, "bases": 0, "doc": 28}, "lib.surfactant": {"qualname": 0, "fullname": 2, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 50}, "lib.surfactant.Surfactant": {"qualname": 1, "fullname": 3, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 11}, "lib.surfactant.Surfactant.__init__": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 134, "bases": 0, "doc": 7}, "lib.surfactant.Surfactant.name": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 10}, "lib.surfactant.Surfactant.concentration": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 12}, "lib.surfactant.Surfactant.concentration_matrix": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 15}, "lib.surfactant.Surfactant.IFT_conc_equ": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 20}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"qualname": 5, "fullname": 7, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 18}, "lib.surfactant.Surfactant.is_surfactant": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 12}, "lib.surfactant.Surfactant.phi": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 19}, "lib.surfactant.Surfactant.eval_IFT": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 10}, "lib.surfactant.Surfactant.eval_dIFT_dGamma": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 11}, "lib.surfactant.Surfactant.initialize": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 11, "bases": 0, "doc": 15}, "lib.surfactant.Surfactant.compute_concentration": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 106, "bases": 0, "doc": 94}, "lib.test": {"qualname": 0, "fullname": 2, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 3}, "lib.water": {"qualname": 0, "fullname": 2, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 51}, "lib.water.Water": {"qualname": 1, "fullname": 3, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 14}, "lib.water.Water.__init__": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 81, "bases": 0, "doc": 9}, "lib.water.Water.init_water_saturation": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 11}, "lib.water.Water.init_aqueous_saturation": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 20}, "lib.water.Water.init_oleic_saturation": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 21}, "lib.water.Water.miuw": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 7}, "lib.water.Water.miuo": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 7}, "lib.water.Water.water_saturation": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 17}, "lib.water.Water.viscosity_array": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 11}, "lib.water.Water.phi": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 8}, "lib.water.Water.initialize": {"qualname": 2, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 22, "bases": 0, "doc": 63}, "lib.water.Water.compute_viscosity": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 134, "bases": 0, "doc": 108}, "lib.water.Water.compute_residual_saturations": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 56, "bases": 0, "doc": 65}, "lib.water.Water.compute_mobility": {"qualname": 3, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 115, "bases": 0, "doc": 119}, "lib.water.Water.compute_water_saturation": {"qualname": 4, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 163, "bases": 0, "doc": 144}}, "length": 161, "save": true}, "index": {"qualname": {"root": {"1": {"docs": {"lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1}}, "df": 1}, "2": {"docs": {"lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"tf": 1}}, "df": 1}, "docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}, "lib.Exceptions.SimulationCalcInputException.__init__": {"tf": 1}, "lib.Exceptions.UserInputException.__init__": {"tf": 1}, "lib.grid.Grid.__init__": {"tf": 1}, "lib.grid.FEMesh.__init__": {"tf": 1}, "lib.polymer.Polymer.__init__": {"tf": 1}, "lib.simulation.Simulation.__init__": {"tf": 1}, "lib.surfactant.Surfactant.__init__": {"tf": 1}, "lib.water.Water.__init__": {"tf": 1}}, "df": 9, "n": {"docs": {"lib.enumerations.PolymerList.n_coeff": {"tf": 1}, "lib.grid.Grid.n": {"tf": 1}, "lib.polymer.Polymer.n_coeff": {"tf": 1}}, "df": 3, "a": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {"lib.name": {"tf": 1}, "lib.polymer.Polymer.name": {"tf": 1}, "lib.surfactant.Surfactant.name": {"tf": 1}}, "df": 3}}}, "u": {"docs": {}, "df": 0, "m": {"docs": {"lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}}, "df": 2}}, "o": {"docs": {"lib.enumerations.PolymerList.No_Polymer": {"tf": 1}, "lib.enumerations.SurfactantList.No_Surfactant": {"tf": 1}, "lib.enumerations.ModelType.No_Shear_Thinning": {"tf": 1}}, "df": 3}}, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "r": {"docs": {"lib.Exceptions.OutOfRangeError": {"tf": 1}, "lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}}, "df": 2}}}}}}}}}}}}}}, "i": {"docs": {}, "df": 0, "l": {"docs": {"lib.enumerations.SimulationConstants.Oil_Viscosity": {"tf": 1}}, "df": 1}}, "l": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "c": {"docs": {"lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.water.Water.init_oleic_saturation": {"tf": 1}}, "df": 3}}}}, "n": {"docs": {"lib.enumerations.ModelType.Shear_Thinning_On": {"tf": 1}}, "df": 1}}, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}, "lib.Exceptions.SimulationCalcInputException.__init__": {"tf": 1}, "lib.Exceptions.UserInputException.__init__": {"tf": 1}, "lib.grid.Grid.__init__": {"tf": 1}, "lib.grid.FEMesh.__init__": {"tf": 1}, "lib.polymer.Polymer.__init__": {"tf": 1}, "lib.polymer.Polymer.init_concentration_matrix": {"tf": 1}, "lib.simulation.Simulation.__init__": {"tf": 1}, "lib.surfactant.Surfactant.__init__": {"tf": 1}, "lib.water.Water.__init__": {"tf": 1}, "lib.water.Water.init_water_saturation": {"tf": 1}, "lib.water.Water.init_aqueous_saturation": {"tf": 1}, "lib.water.Water.init_oleic_saturation": {"tf": 1}}, "df": 13, "i": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}}, "df": 3, "i": {"docs": {}, "df": 0, "z": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.initialize": {"tf": 1}, "lib.surfactant.Surfactant.initialize": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1}}, "df": 3}}}}}}}}, "j": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.SimulationConstants.Injection_Rate": {"tf": 1}}, "df": 1}}}}}}}, "d": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "x": {"docs": {"lib.grid.Grid.get_flat_index_matrix": {"tf": 1}}, "df": 1}}}, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "d": {"docs": {"lib.simulation.Simulation.integrated_inlet_flow": {"tf": 1}}, "df": 1}}}}}}}}, "l": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "t": {"docs": {"lib.simulation.Simulation.integrated_inlet_flow": {"tf": 1}}, "df": 1}}}}, "d": {"docs": {"lib.enumerations.PolymerList.Id": {"tf": 1}, "lib.enumerations.SurfactantList.Id": {"tf": 1}}, "df": 2}, "f": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.SurfactantList.IFT_equation": {"tf": 1}, "lib.enumerations.SurfactantList.derivative_IFT_equation": {"tf": 1}, "lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.eval_IFT": {"tf": 1}}, "df": 5}}, "m": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.ModelType.Sourav_Implementation": {"tf": 1}}, "df": 1}}}}}}}}}}}}}, "s": {"docs": {"lib.surfactant.Surfactant.is_surfactant": {"tf": 1}}, "df": 1}}, "s": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.simulation.Simulation": {"tf": 1}, "lib.simulation.Simulation.__init__": {"tf": 1}, "lib.simulation.Simulation.grid_size": {"tf": 1}, "lib.simulation.Simulation.source_flow_magnitude": {"tf": 1}, "lib.simulation.Simulation.permeability_flag": {"tf": 1}, "lib.simulation.Simulation.reservoir_geometry": {"tf": 1}, "lib.simulation.Simulation.model_type": {"tf": 1}, "lib.simulation.Simulation.relative_permeability_formula": {"tf": 1}, "lib.simulation.Simulation.phi": {"tf": 1}, "lib.simulation.Simulation.KK": {"tf": 1}, "lib.simulation.Simulation.time_step": {"tf": 1}, "lib.simulation.Simulation.polymer": {"tf": 1}, "lib.simulation.Simulation.surfactant": {"tf": 1}, "lib.simulation.Simulation.water": {"tf": 1}, "lib.simulation.Simulation.COC": {"tf": 1}, "lib.simulation.Simulation.miuaTcal": {"tf": 1}, "lib.simulation.Simulation.lambdaTcal": {"tf": 1}, "lib.simulation.Simulation.MFW": {"tf": 1}, "lib.simulation.Simulation.integrated_inlet_flow": {"tf": 1}, "lib.simulation.Simulation.source_prod_flow": {"tf": 1}, "lib.simulation.Simulation.scenario_flag": {"tf": 1}, "lib.simulation.Simulation.run": {"tf": 1}}, "df": 22, "c": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "x": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.Exceptions.SimulationCalcInputException": {"tf": 1}, "lib.Exceptions.SimulationCalcInputException.__init__": {"tf": 1}}, "df": 2}}}}}}}}}}}}}}}}}, "o": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "s": {"docs": {"lib.enumerations.SimulationConstants": {"tf": 1}, "lib.enumerations.SimulationConstants.Water_Viscosity": {"tf": 1}, "lib.enumerations.SimulationConstants.Water_Density": {"tf": 1}, "lib.enumerations.SimulationConstants.Oil_Viscosity": {"tf": 1}, "lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"tf": 1}, "lib.enumerations.SimulationConstants.Injection_Rate": {"tf": 1}, "lib.enumerations.SimulationConstants.Time_Step": {"tf": 1}, "lib.enumerations.SimulationConstants.Grid_Size": {"tf": 1}, "lib.enumerations.SimulationConstants.Source_Flow_Magnitude": {"tf": 1}, "lib.enumerations.SimulationConstants.beta1": {"tf": 1}}, "df": 16}}}}}}}}}}}}}}}}}, "z": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SimulationConstants.Grid_Size": {"tf": 1}, "lib.grid.FEMesh.grid_size": {"tf": 1}, "lib.simulation.Simulation.grid_size": {"tf": 1}}, "df": 3}}}, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.PlotType.Saturation_Plot": {"tf": 1}, "lib.water.Water.init_water_saturation": {"tf": 1}, "lib.water.Water.init_aqueous_saturation": {"tf": 1}, "lib.water.Water.init_oleic_saturation": {"tf": 1}, "lib.water.Water.water_saturation": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 9, "s": {"docs": {"lib.water.Water.compute_residual_saturations": {"tf": 1}}, "df": 1}}}}}}}}}}, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "p": {"docs": {"lib.enumerations.SimulationConstants.Time_Step": {"tf": 1}, "lib.simulation.Simulation.time_step": {"tf": 1}}, "df": 2}}}, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SimulationConstants.Source_Flow_Magnitude": {"tf": 1}, "lib.simulation.Simulation.source_flow_magnitude": {"tf": 1}, "lib.simulation.Simulation.source_prod_flow": {"tf": 1}}, "df": 3}}, "a": {"docs": {}, "df": 0, "v": {"docs": {"lib.enumerations.ModelType.Sourav_Implementation": {"tf": 1}}, "df": 1}}}}}, "c": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "z": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.PolymerList.Schizophyllan": {"tf": 1}}, "df": 1}}}}}}}}}}}, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {"lib.polymer.Polymer.concetration_scalar": {"tf": 1}, "lib.polymer.Polymer.viscosity_scalar": {"tf": 1}}, "df": 2}}}}, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {"lib.simulation.Simulation.scenario_flag": {"tf": 1}}, "df": 1}}}}}}}, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.SurfactantList.No_Surfactant": {"tf": 1}, "lib.enumerations.PlotType.Surfactant_Concentration_Plot": {"tf": 1}, "lib.simulation.Simulation.surfactant": {"tf": 1}, "lib.surfactant.Surfactant": {"tf": 1}, "lib.surfactant.Surfactant.__init__": {"tf": 1}, "lib.surfactant.Surfactant.name": {"tf": 1}, "lib.surfactant.Surfactant.concentration": {"tf": 1}, "lib.surfactant.Surfactant.concentration_matrix": {"tf": 1}, "lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.is_surfactant": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.phi": {"tf": 1}, "lib.surfactant.Surfactant.eval_IFT": {"tf": 1}, "lib.surfactant.Surfactant.eval_dIFT_dGamma": {"tf": 1}, "lib.surfactant.Surfactant.initialize": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}}, "df": 16, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.SurfactantList": {"tf": 1}, "lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate": {"tf": 1}, "lib.enumerations.SurfactantList.No_Surfactant": {"tf": 1}, "lib.enumerations.SurfactantList.Id": {"tf": 1}, "lib.enumerations.SurfactantList.IFT_equation": {"tf": 1}, "lib.enumerations.SurfactantList.derivative_IFT_equation": {"tf": 1}, "lib.enumerations.SurfactantList.get_by_value": {"tf": 1}}, "df": 7}}}}}}}}}}}}, "l": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate": {"tf": 1}}, "df": 1}}}}}}, "h": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations.ModelType.No_Shear_Thinning": {"tf": 1}, "lib.enumerations.ModelType.Shear_Thinning_On": {"tf": 1}, "lib.polymer.Polymer.shear_rate": {"tf": 1}}, "df": 3}}}}, "p": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.ResevoirGeometry.Quarter_Five_Spot": {"tf": 1}}, "df": 1}}, "a": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.grid.Grid.get_spacing": {"tf": 1}}, "df": 1}}}}, "r": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "d": {"docs": {"lib.grid.FEMesh.sparsed_A": {"tf": 1}}, "df": 1}}}}}}, "e": {"docs": {}, "df": 0, "t": {"docs": {"lib.grid.Grid.set_FD_meshgrid": {"tf": 1}, "lib.grid.FEMesh.set_triangulation": {"tf": 1}, "lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}, "lib.grid.FEMesh.set_right_hand": {"tf": 1}}, "df": 4}}}, "u": {"docs": {"lib.grid.FEMesh.U": {"tf": 1}}, "df": 1, "s": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "x": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.Exceptions.UserInputException": {"tf": 1}, "lib.Exceptions.UserInputException.__init__": {"tf": 1}}, "df": 2}}}}}}}}}}}}}}}}}}, "w": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations.SimulationConstants.Water_Viscosity": {"tf": 1}, "lib.enumerations.SimulationConstants.Water_Density": {"tf": 1}, "lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"tf": 1}, "lib.simulation.Simulation.water": {"tf": 1}, "lib.water.Water": {"tf": 1}, "lib.water.Water.__init__": {"tf": 1}, "lib.water.Water.init_water_saturation": {"tf": 1.4142135623730951}, "lib.water.Water.init_aqueous_saturation": {"tf": 1}, "lib.water.Water.init_oleic_saturation": {"tf": 1}, "lib.water.Water.miuw": {"tf": 1}, "lib.water.Water.miuo": {"tf": 1}, "lib.water.Water.water_saturation": {"tf": 1.4142135623730951}, "lib.water.Water.viscosity_array": {"tf": 1}, "lib.water.Water.phi": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1.4142135623730951}}, "df": 19}}}}}, "v": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {"lib.enumerations.SimulationConstants.Water_Viscosity": {"tf": 1}, "lib.enumerations.SimulationConstants.Oil_Viscosity": {"tf": 1}, "lib.polymer.Polymer.viscosity_matrix": {"tf": 1}, "lib.polymer.Polymer.viscosity_scalar": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.water.Water.viscosity_array": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}}, "df": 7}}}}}}}}, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.PolymerList.get_by_value": {"tf": 1}, "lib.enumerations.SurfactantList.get_by_value": {"tf": 1}}, "df": 2}}}}}, "d": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {"lib.enumerations.SimulationConstants.Water_Density": {"tf": 1}, "lib.enumerations.PolymerList.Density": {"tf": 1}}, "df": 2}}}}}, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SurfactantList.derivative_IFT_equation": {"tf": 1}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1}}, "df": 2}}}}}}}}}, "x": {"docs": {"lib.grid.Grid.dx": {"tf": 1}}, "df": 1}, "y": {"docs": {"lib.grid.Grid.dy": {"tf": 1}}, "df": 1}, "i": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.divergence": {"tf": 1}}, "df": 1}}}}}}}}, "f": {"docs": {}, "df": 0, "t": {"docs": {"lib.surfactant.Surfactant.eval_dIFT_dGamma": {"tf": 1}}, "df": 1}}}, "g": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "a": {"docs": {"lib.surfactant.Surfactant.eval_dIFT_dGamma": {"tf": 1}}, "df": 1}}}}}}, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "d": {"docs": {"lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}}, "df": 2, "u": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}}, "df": 2}}}}}, "e": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "y": {"docs": {"lib.enumerations.ResevoirGeometry": {"tf": 1}, "lib.enumerations.ResevoirGeometry.Rectilinear": {"tf": 1}, "lib.enumerations.ResevoirGeometry.Quarter_Five_Spot": {"tf": 1}}, "df": 3}}}}}}}}}}}}, "r": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "r": {"docs": {"lib.simulation.Simulation.reservoir_geometry": {"tf": 1}}, "df": 1}}}}}}}, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations.ResevoirGeometry.Rectilinear": {"tf": 1}}, "df": 1}}}}}}}}}, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "e": {"docs": {"lib.simulation.Simulation.relative_permeability_formula": {"tf": 1}}, "df": 1, "p": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "b": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {"lib.enumerations.RelativePermeabilityFormula": {"tf": 1}, "lib.enumerations.RelativePermeabilityFormula.AmaefuleHandEquation": {"tf": 1}, "lib.enumerations.RelativePermeabilityFormula.CoreyTypeEquation": {"tf": 1}}, "df": 3}}}}}}}}}}}}}}}}}}}}}}}}}}, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SimulationConstants.Injection_Rate": {"tf": 1}, "lib.polymer.Polymer.shear_rate": {"tf": 1}}, "df": 2}}}, "i": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "t": {"docs": {"lib.grid.Grid.right": {"tf": 1}, "lib.grid.FEMesh.right_hand": {"tf": 1}, "lib.grid.FEMesh.set_right_hand": {"tf": 1}}, "df": 3}}}}, "h": {"docs": {}, "df": 0, "o": {"docs": {"lib.polymer.Polymer.rho": {"tf": 1}}, "df": 1}}, "u": {"docs": {}, "df": 0, "n": {"docs": {"lib.simulation.Simulation.run": {"tf": 1}}, "df": 1}}}, "a": {"docs": {"lib.grid.Grid.A": {"tf": 1}, "lib.grid.FEMesh.A": {"tf": 1}, "lib.grid.FEMesh.sparsed_A": {"tf": 1}, "lib.grid.FEMesh.get_A_B_matrices": {"tf": 1}}, "df": 4, "q": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "s": {"docs": {"lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.water.Water.init_aqueous_saturation": {"tf": 1}}, "df": 3}}}}}}, "l": {"docs": {}, "df": 0, "k": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "l": {"docs": {"lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate": {"tf": 1}}, "df": 1}}}}, "m": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "q": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.RelativePermeabilityFormula.AmaefuleHandEquation": {"tf": 1}}, "df": 1}}}}}}}}}}}}}}}}}}}, "r": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "y": {"docs": {"lib.water.Water.viscosity_array": {"tf": 1}}, "df": 1}}}}}, "p": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}}, "df": 4}}}, "i": {"docs": {"lib.polymer.Polymer.phi": {"tf": 1}, "lib.simulation.Simulation.phi": {"tf": 1}, "lib.surfactant.Surfactant.phi": {"tf": 1}, "lib.water.Water.phi": {"tf": 1}}, "df": 4}}, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"tf": 1}}, "df": 2}}}}}}, "o": {"docs": {}, "df": 0, "d": {"docs": {"lib.simulation.Simulation.source_prod_flow": {"tf": 1}}, "df": 1}}}, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "m": {"docs": {"lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"tf": 1}}, "df": 2}}}}, "o": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations.PolymerList.No_Polymer": {"tf": 1}, "lib.enumerations.PlotType.Polymer_Concentration_Plot": {"tf": 1}, "lib.polymer.Polymer": {"tf": 1}, "lib.polymer.Polymer.__init__": {"tf": 1}, "lib.polymer.Polymer.name": {"tf": 1}, "lib.polymer.Polymer.concetration_scalar": {"tf": 1}, "lib.polymer.Polymer.init_concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.viscosity_matrix": {"tf": 1}, "lib.polymer.Polymer.viscosity_scalar": {"tf": 1}, "lib.polymer.Polymer.e_coeff": {"tf": 1}, "lib.polymer.Polymer.n_coeff": {"tf": 1}, "lib.polymer.Polymer.rho": {"tf": 1}, "lib.polymer.Polymer.shear_rate": {"tf": 1}, "lib.polymer.Polymer.phi": {"tf": 1}, "lib.polymer.Polymer.initialize": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.polymer.Polymer.divergence": {"tf": 1}, "lib.simulation.Simulation.polymer": {"tf": 1}}, "df": 20, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.PolymerList": {"tf": 1}, "lib.enumerations.PolymerList.Xanthane": {"tf": 1}, "lib.enumerations.PolymerList.Schizophyllan": {"tf": 1}, "lib.enumerations.PolymerList.No_Polymer": {"tf": 1}, "lib.enumerations.PolymerList.Id": {"tf": 1}, "lib.enumerations.PolymerList.Density": {"tf": 1}, "lib.enumerations.PolymerList.n_coeff": {"tf": 1}, "lib.enumerations.PolymerList.e_coeff": {"tf": 1}, "lib.enumerations.PolymerList.get_by_value": {"tf": 1}}, "df": 9}}}}}}}}}}, "l": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.PlotType.Saturation_Plot": {"tf": 1}, "lib.enumerations.PlotType.Polymer_Concentration_Plot": {"tf": 1}, "lib.enumerations.PlotType.Surfactant_Concentration_Plot": {"tf": 1}}, "df": 3, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.PlotType": {"tf": 1}, "lib.enumerations.PlotType.Saturation_Plot": {"tf": 1}, "lib.enumerations.PlotType.Polymer_Concentration_Plot": {"tf": 1}, "lib.enumerations.PlotType.Surfactant_Concentration_Plot": {"tf": 1}}, "df": 4}}}}}}}, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "b": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {"lib.simulation.Simulation.permeability_flag": {"tf": 1}, "lib.simulation.Simulation.relative_permeability_formula": {"tf": 1}}, "df": 2, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.PermeabilityType": {"tf": 1}, "lib.enumerations.PermeabilityType.Homogenous": {"tf": 1}, "lib.enumerations.PermeabilityType.Heterogenous": {"tf": 1}}, "df": 3}}}}}}}}}}}}}}}}, "c": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}}, "df": 2}}}}}}}, "a": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "y": {"docs": {"lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"tf": 1}}, "df": 4}}}}}}}}, "o": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "f": {"docs": {"lib.enumerations.PolymerList.n_coeff": {"tf": 1}, "lib.enumerations.PolymerList.e_coeff": {"tf": 1}, "lib.polymer.Polymer.e_coeff": {"tf": 1}, "lib.polymer.Polymer.n_coeff": {"tf": 1}}, "df": 4}}}, "n": {"docs": {}, "df": 0, "c": {"docs": {"lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1}}, "df": 2, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.PlotType.Polymer_Concentration_Plot": {"tf": 1}, "lib.enumerations.PlotType.Surfactant_Concentration_Plot": {"tf": 1}, "lib.polymer.Polymer.init_concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.surfactant.Surfactant.concentration": {"tf": 1}, "lib.surfactant.Surfactant.concentration_matrix": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}}, "df": 8}}}}}}}}, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.polymer.Polymer.concetration_scalar": {"tf": 1}}, "df": 1}}}}}}}}}}, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "q": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.RelativePermeabilityFormula.CoreyTypeEquation": {"tf": 1}}, "df": 1}}}}}}}}}}}}}}}, "m": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 7}}}}}, "c": {"docs": {"lib.simulation.Simulation.COC": {"tf": 1}}, "df": 1}}}, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SimulationConstants.Time_Step": {"tf": 1}, "lib.simulation.Simulation.time_step": {"tf": 1}}, "df": 2}}}, "h": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.enumerations.ModelType.No_Shear_Thinning": {"tf": 1}, "lib.enumerations.ModelType.Shear_Thinning_On": {"tf": 1}}, "df": 2}}}}}}}, "o": {"docs": {}, "df": 0, "p": {"docs": {"lib.grid.Grid.top": {"tf": 1}}, "df": 1}}, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.grid.FEMesh.set_triangulation": {"tf": 1}}, "df": 1}}}}}}}}}}}}, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {"lib.simulation.Simulation.model_type": {"tf": 1}}, "df": 1}}}}, "g": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "d": {"docs": {"lib.enumerations.SimulationConstants.Grid_Size": {"tf": 1}, "lib.grid.Grid": {"tf": 1}, "lib.grid.Grid.__init__": {"tf": 1}, "lib.grid.Grid.m": {"tf": 1}, "lib.grid.Grid.n": {"tf": 1}, "lib.grid.Grid.left": {"tf": 1}, "lib.grid.Grid.right": {"tf": 1}, "lib.grid.Grid.bottom": {"tf": 1}, "lib.grid.Grid.top": {"tf": 1}, "lib.grid.Grid.A": {"tf": 1}, "lib.grid.Grid.B": {"tf": 1}, "lib.grid.Grid.get_spacing": {"tf": 1}, "lib.grid.Grid.get_meshgrid": {"tf": 1}, "lib.grid.Grid.dx": {"tf": 1}, "lib.grid.Grid.dy": {"tf": 1}, "lib.grid.Grid.set_FD_meshgrid": {"tf": 1}, "lib.grid.Grid.get_flat_index_matrix": {"tf": 1}, "lib.grid.FEMesh.grid_size": {"tf": 1}, "lib.simulation.Simulation.grid_size": {"tf": 1}}, "df": 19}}}, "e": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.PolymerList.get_by_value": {"tf": 1}, "lib.enumerations.SurfactantList.get_by_value": {"tf": 1}, "lib.grid.Grid.get_spacing": {"tf": 1}, "lib.grid.Grid.get_meshgrid": {"tf": 1}, "lib.grid.Grid.get_flat_index_matrix": {"tf": 1}, "lib.grid.FEMesh.get_A_B_matrices": {"tf": 1}}, "df": 6}, "o": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "y": {"docs": {"lib.simulation.Simulation.reservoir_geometry": {"tf": 1}}, "df": 1}}}}}}}}, "f": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "w": {"docs": {"lib.enumerations.SimulationConstants.Source_Flow_Magnitude": {"tf": 1}, "lib.simulation.Simulation.source_flow_magnitude": {"tf": 1}, "lib.simulation.Simulation.integrated_inlet_flow": {"tf": 1}, "lib.simulation.Simulation.source_prod_flow": {"tf": 1}}, "df": 4}}, "a": {"docs": {}, "df": 0, "t": {"docs": {"lib.grid.Grid.get_flat_index_matrix": {"tf": 1}}, "df": 1}, "g": {"docs": {"lib.simulation.Simulation.permeability_flag": {"tf": 1}, "lib.simulation.Simulation.scenario_flag": {"tf": 1}}, "df": 2}}}, "i": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.ResevoirGeometry.Quarter_Five_Spot": {"tf": 1}}, "df": 1}}}, "d": {"docs": {"lib.grid.Grid.set_FD_meshgrid": {"tf": 1}}, "df": 1}, "e": {"docs": {"lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}}, "df": 1, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "h": {"docs": {"lib.grid.FEMesh": {"tf": 1}, "lib.grid.FEMesh.__init__": {"tf": 1}, "lib.grid.FEMesh.U": {"tf": 1}, "lib.grid.FEMesh.L": {"tf": 1}, "lib.grid.FEMesh.grid_size": {"tf": 1}, "lib.grid.FEMesh.right_hand": {"tf": 1}, "lib.grid.FEMesh.A": {"tf": 1}, "lib.grid.FEMesh.B": {"tf": 1}, "lib.grid.FEMesh.sparsed_A": {"tf": 1}, "lib.grid.FEMesh.set_triangulation": {"tf": 1}, "lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}, "lib.grid.FEMesh.set_right_hand": {"tf": 1}, "lib.grid.FEMesh.get_A_B_matrices": {"tf": 1}}, "df": 13}}}}}, "o": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {"lib.simulation.Simulation.relative_permeability_formula": {"tf": 1}}, "df": 1}}}}}}}, "m": {"docs": {"lib.grid.Grid.m": {"tf": 1}}, "df": 1, "a": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SimulationConstants.Source_Flow_Magnitude": {"tf": 1}, "lib.simulation.Simulation.source_flow_magnitude": {"tf": 1}}, "df": 2}}}}}}}, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "x": {"docs": {"lib.grid.Grid.get_flat_index_matrix": {"tf": 1}, "lib.polymer.Polymer.init_concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.viscosity_matrix": {"tf": 1}, "lib.surfactant.Surfactant.concentration_matrix": {"tf": 1}}, "df": 5}, "c": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {"lib.grid.FEMesh.get_A_B_matrices": {"tf": 1}}, "df": 1}}}}}}}, "o": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "l": {"docs": {"lib.simulation.Simulation.model_type": {"tf": 1}}, "df": 1, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.ModelType": {"tf": 1}, "lib.enumerations.ModelType.No_Shear_Thinning": {"tf": 1}, "lib.enumerations.ModelType.Sourav_Implementation": {"tf": 1}, "lib.enumerations.ModelType.Shear_Thinning_On": {"tf": 1}}, "df": 4}}}}}}}, "b": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {"lib.water.Water.compute_mobility": {"tf": 1}}, "df": 1}}}}}}}, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "d": {"docs": {"lib.grid.Grid.get_meshgrid": {"tf": 1}, "lib.grid.Grid.set_FD_meshgrid": {"tf": 1}, "lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}}, "df": 3}}}}}}}, "i": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.simulation.Simulation.miuaTcal": {"tf": 1}}, "df": 1}}}}}, "w": {"docs": {"lib.water.Water.miuw": {"tf": 1}}, "df": 1}, "o": {"docs": {"lib.water.Water.miuo": {"tf": 1}}, "df": 1}}}, "f": {"docs": {}, "df": 0, "w": {"docs": {"lib.simulation.Simulation.MFW": {"tf": 1}}, "df": 1}}}, "b": {"docs": {"lib.grid.Grid.B": {"tf": 1}, "lib.grid.FEMesh.B": {"tf": 1}, "lib.grid.FEMesh.get_A_B_matrices": {"tf": 1}}, "df": 3, "e": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"1": {"docs": {"lib.enumerations.SimulationConstants.beta1": {"tf": 1}}, "df": 1}, "docs": {}, "df": 0}}}, "y": {"docs": {"lib.enumerations.PolymerList.get_by_value": {"tf": 1}, "lib.enumerations.SurfactantList.get_by_value": {"tf": 1}}, "df": 2}, "o": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "m": {"docs": {"lib.grid.Grid.bottom": {"tf": 1}}, "df": 1}}}}}}, "x": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.PolymerList.Xanthane": {"tf": 1}}, "df": 1}}}}}}}}, "e": {"docs": {"lib.enumerations.PolymerList.e_coeff": {"tf": 1}, "lib.polymer.Polymer.e_coeff": {"tf": 1}}, "df": 2, "t": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate": {"tf": 1}}, "df": 1}}}}, "q": {"docs": {}, "df": 0, "u": {"docs": {"lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1}}, "df": 2, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.SurfactantList.IFT_equation": {"tf": 1}, "lib.enumerations.SurfactantList.derivative_IFT_equation": {"tf": 1}}, "df": 2}}}}}}}, "v": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.surfactant.Surfactant.eval_IFT": {"tf": 1}, "lib.surfactant.Surfactant.eval_dIFT_dGamma": {"tf": 1}}, "df": 2}}}}, "q": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations.ResevoirGeometry.Quarter_Five_Spot": {"tf": 1}}, "df": 1}}}}}}}, "h": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "s": {"docs": {"lib.enumerations.PermeabilityType.Homogenous": {"tf": 1}}, "df": 1}}}}}}}}}, "e": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "s": {"docs": {"lib.enumerations.PermeabilityType.Heterogenous": {"tf": 1}}, "df": 1}}}}}}}}}}}, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "d": {"docs": {"lib.grid.FEMesh.right_hand": {"tf": 1}, "lib.grid.FEMesh.set_right_hand": {"tf": 1}}, "df": 2}}}}, "l": {"docs": {"lib.grid.FEMesh.L": {"tf": 1}}, "df": 1, "e": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "t": {"docs": {"lib.grid.Grid.left": {"tf": 1}}, "df": 1}}}, "a": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "b": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.simulation.Simulation.lambdaTcal": {"tf": 1}}, "df": 1}}}}}}}}}}, "k": {"docs": {}, "df": 0, "k": {"docs": {"lib.simulation.Simulation.KK": {"tf": 1}}, "df": 1}}}}, "fullname": {"root": {"1": {"docs": {"lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1}}, "df": 1}, "2": {"docs": {"lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"tf": 1}}, "df": 1}, "docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}, "lib.Exceptions.SimulationCalcInputException.__init__": {"tf": 1}, "lib.Exceptions.UserInputException.__init__": {"tf": 1}, "lib.grid.Grid.__init__": {"tf": 1}, "lib.grid.FEMesh.__init__": {"tf": 1}, "lib.polymer.Polymer.__init__": {"tf": 1}, "lib.simulation.Simulation.__init__": {"tf": 1}, "lib.surfactant.Surfactant.__init__": {"tf": 1}, "lib.water.Water.__init__": {"tf": 1}}, "df": 9, "l": {"docs": {"lib.grid.FEMesh.L": {"tf": 1}}, "df": 1, "i": {"docs": {}, "df": 0, "b": {"docs": {"lib": {"tf": 1}, "lib.name": {"tf": 1}, "lib.Exceptions": {"tf": 1}, "lib.Exceptions.OutOfRangeError": {"tf": 1}, "lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}, "lib.Exceptions.SimulationCalcInputException": {"tf": 1}, "lib.Exceptions.SimulationCalcInputException.__init__": {"tf": 1}, "lib.Exceptions.UserInputException": {"tf": 1}, "lib.Exceptions.UserInputException.__init__": {"tf": 1}, "lib.enumerations": {"tf": 1}, "lib.enumerations.SimulationConstants": {"tf": 1}, "lib.enumerations.SimulationConstants.Water_Viscosity": {"tf": 1}, "lib.enumerations.SimulationConstants.Water_Density": {"tf": 1}, "lib.enumerations.SimulationConstants.Oil_Viscosity": {"tf": 1}, "lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"tf": 1}, "lib.enumerations.SimulationConstants.Injection_Rate": {"tf": 1}, "lib.enumerations.SimulationConstants.Time_Step": {"tf": 1}, "lib.enumerations.SimulationConstants.Grid_Size": {"tf": 1}, "lib.enumerations.SimulationConstants.Source_Flow_Magnitude": {"tf": 1}, "lib.enumerations.SimulationConstants.beta1": {"tf": 1}, "lib.enumerations.PolymerList": {"tf": 1}, "lib.enumerations.PolymerList.Xanthane": {"tf": 1}, "lib.enumerations.PolymerList.Schizophyllan": {"tf": 1}, "lib.enumerations.PolymerList.No_Polymer": {"tf": 1}, "lib.enumerations.PolymerList.Id": {"tf": 1}, "lib.enumerations.PolymerList.Density": {"tf": 1}, "lib.enumerations.PolymerList.n_coeff": {"tf": 1}, "lib.enumerations.PolymerList.e_coeff": {"tf": 1}, "lib.enumerations.PolymerList.get_by_value": {"tf": 1}, "lib.enumerations.SurfactantList": {"tf": 1}, "lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate": {"tf": 1}, "lib.enumerations.SurfactantList.No_Surfactant": {"tf": 1}, "lib.enumerations.SurfactantList.Id": {"tf": 1}, "lib.enumerations.SurfactantList.IFT_equation": {"tf": 1}, "lib.enumerations.SurfactantList.derivative_IFT_equation": {"tf": 1}, "lib.enumerations.SurfactantList.get_by_value": {"tf": 1}, "lib.enumerations.ModelType": {"tf": 1}, "lib.enumerations.ModelType.No_Shear_Thinning": {"tf": 1}, "lib.enumerations.ModelType.Sourav_Implementation": {"tf": 1}, "lib.enumerations.ModelType.Shear_Thinning_On": {"tf": 1}, "lib.enumerations.PlotType": {"tf": 1}, "lib.enumerations.PlotType.Saturation_Plot": {"tf": 1}, "lib.enumerations.PlotType.Polymer_Concentration_Plot": {"tf": 1}, "lib.enumerations.PlotType.Surfactant_Concentration_Plot": {"tf": 1}, "lib.enumerations.ResevoirGeometry": {"tf": 1}, "lib.enumerations.ResevoirGeometry.Rectilinear": {"tf": 1}, "lib.enumerations.ResevoirGeometry.Quarter_Five_Spot": {"tf": 1}, "lib.enumerations.PermeabilityType": {"tf": 1}, "lib.enumerations.PermeabilityType.Homogenous": {"tf": 1}, "lib.enumerations.PermeabilityType.Heterogenous": {"tf": 1}, "lib.enumerations.RelativePermeabilityFormula": {"tf": 1}, "lib.enumerations.RelativePermeabilityFormula.AmaefuleHandEquation": {"tf": 1}, "lib.enumerations.RelativePermeabilityFormula.CoreyTypeEquation": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.grid.Grid": {"tf": 1}, "lib.grid.Grid.__init__": {"tf": 1}, "lib.grid.Grid.m": {"tf": 1}, "lib.grid.Grid.n": {"tf": 1}, "lib.grid.Grid.left": {"tf": 1}, "lib.grid.Grid.right": {"tf": 1}, "lib.grid.Grid.bottom": {"tf": 1}, "lib.grid.Grid.top": {"tf": 1}, "lib.grid.Grid.A": {"tf": 1}, "lib.grid.Grid.B": {"tf": 1}, "lib.grid.Grid.get_spacing": {"tf": 1}, "lib.grid.Grid.get_meshgrid": {"tf": 1}, "lib.grid.Grid.dx": {"tf": 1}, "lib.grid.Grid.dy": {"tf": 1}, "lib.grid.Grid.set_FD_meshgrid": {"tf": 1}, "lib.grid.Grid.get_flat_index_matrix": {"tf": 1}, "lib.grid.FEMesh": {"tf": 1}, "lib.grid.FEMesh.__init__": {"tf": 1}, "lib.grid.FEMesh.U": {"tf": 1}, "lib.grid.FEMesh.L": {"tf": 1}, "lib.grid.FEMesh.grid_size": {"tf": 1}, "lib.grid.FEMesh.right_hand": {"tf": 1}, "lib.grid.FEMesh.A": {"tf": 1}, "lib.grid.FEMesh.B": {"tf": 1}, "lib.grid.FEMesh.sparsed_A": {"tf": 1}, "lib.grid.FEMesh.set_triangulation": {"tf": 1}, "lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}, "lib.grid.FEMesh.set_right_hand": {"tf": 1}, "lib.grid.FEMesh.get_A_B_matrices": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.polymer.Polymer": {"tf": 1}, "lib.polymer.Polymer.__init__": {"tf": 1}, "lib.polymer.Polymer.name": {"tf": 1}, "lib.polymer.Polymer.concetration_scalar": {"tf": 1}, "lib.polymer.Polymer.init_concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.viscosity_matrix": {"tf": 1}, "lib.polymer.Polymer.viscosity_scalar": {"tf": 1}, "lib.polymer.Polymer.e_coeff": {"tf": 1}, "lib.polymer.Polymer.n_coeff": {"tf": 1}, "lib.polymer.Polymer.rho": {"tf": 1}, "lib.polymer.Polymer.shear_rate": {"tf": 1}, "lib.polymer.Polymer.phi": {"tf": 1}, "lib.polymer.Polymer.initialize": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.polymer.Polymer.divergence": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.simulation.Simulation": {"tf": 1}, "lib.simulation.Simulation.__init__": {"tf": 1}, "lib.simulation.Simulation.grid_size": {"tf": 1}, "lib.simulation.Simulation.source_flow_magnitude": {"tf": 1}, "lib.simulation.Simulation.permeability_flag": {"tf": 1}, "lib.simulation.Simulation.reservoir_geometry": {"tf": 1}, "lib.simulation.Simulation.model_type": {"tf": 1}, "lib.simulation.Simulation.relative_permeability_formula": {"tf": 1}, "lib.simulation.Simulation.phi": {"tf": 1}, "lib.simulation.Simulation.KK": {"tf": 1}, "lib.simulation.Simulation.time_step": {"tf": 1}, "lib.simulation.Simulation.polymer": {"tf": 1}, "lib.simulation.Simulation.surfactant": {"tf": 1}, "lib.simulation.Simulation.water": {"tf": 1}, "lib.simulation.Simulation.COC": {"tf": 1}, "lib.simulation.Simulation.miuaTcal": {"tf": 1}, "lib.simulation.Simulation.lambdaTcal": {"tf": 1}, "lib.simulation.Simulation.MFW": {"tf": 1}, "lib.simulation.Simulation.integrated_inlet_flow": {"tf": 1}, "lib.simulation.Simulation.source_prod_flow": {"tf": 1}, "lib.simulation.Simulation.scenario_flag": {"tf": 1}, "lib.simulation.Simulation.run": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.surfactant.Surfactant": {"tf": 1}, "lib.surfactant.Surfactant.__init__": {"tf": 1}, "lib.surfactant.Surfactant.name": {"tf": 1}, "lib.surfactant.Surfactant.concentration": {"tf": 1}, "lib.surfactant.Surfactant.concentration_matrix": {"tf": 1}, "lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.is_surfactant": {"tf": 1}, "lib.surfactant.Surfactant.phi": {"tf": 1}, "lib.surfactant.Surfactant.eval_IFT": {"tf": 1}, "lib.surfactant.Surfactant.eval_dIFT_dGamma": {"tf": 1}, "lib.surfactant.Surfactant.initialize": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.test": {"tf": 1}, "lib.water": {"tf": 1}, "lib.water.Water": {"tf": 1}, "lib.water.Water.__init__": {"tf": 1}, "lib.water.Water.init_water_saturation": {"tf": 1}, "lib.water.Water.init_aqueous_saturation": {"tf": 1}, "lib.water.Water.init_oleic_saturation": {"tf": 1}, "lib.water.Water.miuw": {"tf": 1}, "lib.water.Water.miuo": {"tf": 1}, "lib.water.Water.water_saturation": {"tf": 1}, "lib.water.Water.viscosity_array": {"tf": 1}, "lib.water.Water.phi": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 161}}, "e": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "t": {"docs": {"lib.grid.Grid.left": {"tf": 1}}, "df": 1}}}, "a": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "b": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.simulation.Simulation.lambdaTcal": {"tf": 1}}, "df": 1}}}}}}}}}}, "n": {"docs": {"lib.enumerations.PolymerList.n_coeff": {"tf": 1}, "lib.grid.Grid.n": {"tf": 1}, "lib.polymer.Polymer.n_coeff": {"tf": 1}}, "df": 3, "a": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {"lib.name": {"tf": 1}, "lib.polymer.Polymer.name": {"tf": 1}, "lib.surfactant.Surfactant.name": {"tf": 1}}, "df": 3}}}, "u": {"docs": {}, "df": 0, "m": {"docs": {"lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}}, "df": 2}}, "o": {"docs": {"lib.enumerations.PolymerList.No_Polymer": {"tf": 1}, "lib.enumerations.SurfactantList.No_Surfactant": {"tf": 1}, "lib.enumerations.ModelType.No_Shear_Thinning": {"tf": 1}}, "df": 3}}, "e": {"docs": {"lib.enumerations.PolymerList.e_coeff": {"tf": 1}, "lib.polymer.Polymer.e_coeff": {"tf": 1}}, "df": 2, "x": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "s": {"docs": {"lib.Exceptions": {"tf": 1}, "lib.Exceptions.OutOfRangeError": {"tf": 1}, "lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}, "lib.Exceptions.SimulationCalcInputException": {"tf": 1}, "lib.Exceptions.SimulationCalcInputException.__init__": {"tf": 1}, "lib.Exceptions.UserInputException": {"tf": 1}, "lib.Exceptions.UserInputException.__init__": {"tf": 1}}, "df": 7}}}}}}}}}, "n": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "s": {"docs": {"lib.enumerations": {"tf": 1}, "lib.enumerations.SimulationConstants": {"tf": 1}, "lib.enumerations.SimulationConstants.Water_Viscosity": {"tf": 1}, "lib.enumerations.SimulationConstants.Water_Density": {"tf": 1}, "lib.enumerations.SimulationConstants.Oil_Viscosity": {"tf": 1}, "lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"tf": 1}, "lib.enumerations.SimulationConstants.Injection_Rate": {"tf": 1}, "lib.enumerations.SimulationConstants.Time_Step": {"tf": 1}, "lib.enumerations.SimulationConstants.Grid_Size": {"tf": 1}, "lib.enumerations.SimulationConstants.Source_Flow_Magnitude": {"tf": 1}, "lib.enumerations.SimulationConstants.beta1": {"tf": 1}, "lib.enumerations.PolymerList": {"tf": 1}, "lib.enumerations.PolymerList.Xanthane": {"tf": 1}, "lib.enumerations.PolymerList.Schizophyllan": {"tf": 1}, "lib.enumerations.PolymerList.No_Polymer": {"tf": 1}, "lib.enumerations.PolymerList.Id": {"tf": 1}, "lib.enumerations.PolymerList.Density": {"tf": 1}, "lib.enumerations.PolymerList.n_coeff": {"tf": 1}, "lib.enumerations.PolymerList.e_coeff": {"tf": 1}, "lib.enumerations.PolymerList.get_by_value": {"tf": 1}, "lib.enumerations.SurfactantList": {"tf": 1}, "lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate": {"tf": 1}, "lib.enumerations.SurfactantList.No_Surfactant": {"tf": 1}, "lib.enumerations.SurfactantList.Id": {"tf": 1}, "lib.enumerations.SurfactantList.IFT_equation": {"tf": 1}, "lib.enumerations.SurfactantList.derivative_IFT_equation": {"tf": 1}, "lib.enumerations.SurfactantList.get_by_value": {"tf": 1}, "lib.enumerations.ModelType": {"tf": 1}, "lib.enumerations.ModelType.No_Shear_Thinning": {"tf": 1}, "lib.enumerations.ModelType.Sourav_Implementation": {"tf": 1}, "lib.enumerations.ModelType.Shear_Thinning_On": {"tf": 1}, "lib.enumerations.PlotType": {"tf": 1}, "lib.enumerations.PlotType.Saturation_Plot": {"tf": 1}, "lib.enumerations.PlotType.Polymer_Concentration_Plot": {"tf": 1}, "lib.enumerations.PlotType.Surfactant_Concentration_Plot": {"tf": 1}, "lib.enumerations.ResevoirGeometry": {"tf": 1}, "lib.enumerations.ResevoirGeometry.Rectilinear": {"tf": 1}, "lib.enumerations.ResevoirGeometry.Quarter_Five_Spot": {"tf": 1}, "lib.enumerations.PermeabilityType": {"tf": 1}, "lib.enumerations.PermeabilityType.Homogenous": {"tf": 1}, "lib.enumerations.PermeabilityType.Heterogenous": {"tf": 1}, "lib.enumerations.RelativePermeabilityFormula": {"tf": 1}, "lib.enumerations.RelativePermeabilityFormula.AmaefuleHandEquation": {"tf": 1}, "lib.enumerations.RelativePermeabilityFormula.CoreyTypeEquation": {"tf": 1}}, "df": 50}}}}}}}}}}}, "t": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate": {"tf": 1}}, "df": 1}}}}, "q": {"docs": {}, "df": 0, "u": {"docs": {"lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1}}, "df": 2, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.SurfactantList.IFT_equation": {"tf": 1}, "lib.enumerations.SurfactantList.derivative_IFT_equation": {"tf": 1}}, "df": 2}}}}}}}, "v": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.surfactant.Surfactant.eval_IFT": {"tf": 1}, "lib.surfactant.Surfactant.eval_dIFT_dGamma": {"tf": 1}}, "df": 2}}}}, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "r": {"docs": {"lib.Exceptions.OutOfRangeError": {"tf": 1}, "lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}}, "df": 2}}}}}}}}}}}}}}, "i": {"docs": {}, "df": 0, "l": {"docs": {"lib.enumerations.SimulationConstants.Oil_Viscosity": {"tf": 1}}, "df": 1}}, "l": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "c": {"docs": {"lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.water.Water.init_oleic_saturation": {"tf": 1}}, "df": 3}}}}, "n": {"docs": {"lib.enumerations.ModelType.Shear_Thinning_On": {"tf": 1}}, "df": 1}}, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}, "lib.Exceptions.SimulationCalcInputException.__init__": {"tf": 1}, "lib.Exceptions.UserInputException.__init__": {"tf": 1}, "lib.grid.Grid.__init__": {"tf": 1}, "lib.grid.FEMesh.__init__": {"tf": 1}, "lib.polymer.Polymer.__init__": {"tf": 1}, "lib.polymer.Polymer.init_concentration_matrix": {"tf": 1}, "lib.simulation.Simulation.__init__": {"tf": 1}, "lib.surfactant.Surfactant.__init__": {"tf": 1}, "lib.water.Water.__init__": {"tf": 1}, "lib.water.Water.init_water_saturation": {"tf": 1}, "lib.water.Water.init_aqueous_saturation": {"tf": 1}, "lib.water.Water.init_oleic_saturation": {"tf": 1}}, "df": 13, "i": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}}, "df": 3, "i": {"docs": {}, "df": 0, "z": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.initialize": {"tf": 1}, "lib.surfactant.Surfactant.initialize": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1}}, "df": 3}}}}}}}}, "j": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.SimulationConstants.Injection_Rate": {"tf": 1}}, "df": 1}}}}}}}, "d": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "x": {"docs": {"lib.grid.Grid.get_flat_index_matrix": {"tf": 1}}, "df": 1}}}, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "d": {"docs": {"lib.simulation.Simulation.integrated_inlet_flow": {"tf": 1}}, "df": 1}}}}}}}}, "l": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "t": {"docs": {"lib.simulation.Simulation.integrated_inlet_flow": {"tf": 1}}, "df": 1}}}}, "d": {"docs": {"lib.enumerations.PolymerList.Id": {"tf": 1}, "lib.enumerations.SurfactantList.Id": {"tf": 1}}, "df": 2}, "f": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.SurfactantList.IFT_equation": {"tf": 1}, "lib.enumerations.SurfactantList.derivative_IFT_equation": {"tf": 1}, "lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.eval_IFT": {"tf": 1}}, "df": 5}}, "m": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.ModelType.Sourav_Implementation": {"tf": 1}}, "df": 1}}}}}}}}}}}}}, "s": {"docs": {"lib.surfactant.Surfactant.is_surfactant": {"tf": 1}}, "df": 1}}, "s": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.simulation": {"tf": 1}, "lib.simulation.Simulation": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.__init__": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.grid_size": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.source_flow_magnitude": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.permeability_flag": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.reservoir_geometry": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.model_type": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.relative_permeability_formula": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.phi": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.KK": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.time_step": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.polymer": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.surfactant": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.water": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.COC": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.miuaTcal": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.lambdaTcal": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.MFW": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.integrated_inlet_flow": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.source_prod_flow": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.scenario_flag": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.run": {"tf": 1.4142135623730951}}, "df": 23, "c": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "x": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.Exceptions.SimulationCalcInputException": {"tf": 1}, "lib.Exceptions.SimulationCalcInputException.__init__": {"tf": 1}}, "df": 2}}}}}}}}}}}}}}}}}, "o": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "s": {"docs": {"lib.enumerations.SimulationConstants": {"tf": 1}, "lib.enumerations.SimulationConstants.Water_Viscosity": {"tf": 1}, "lib.enumerations.SimulationConstants.Water_Density": {"tf": 1}, "lib.enumerations.SimulationConstants.Oil_Viscosity": {"tf": 1}, "lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"tf": 1}, "lib.enumerations.SimulationConstants.Injection_Rate": {"tf": 1}, "lib.enumerations.SimulationConstants.Time_Step": {"tf": 1}, "lib.enumerations.SimulationConstants.Grid_Size": {"tf": 1}, "lib.enumerations.SimulationConstants.Source_Flow_Magnitude": {"tf": 1}, "lib.enumerations.SimulationConstants.beta1": {"tf": 1}}, "df": 16}}}}}}}}}}}}}}}}}, "z": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SimulationConstants.Grid_Size": {"tf": 1}, "lib.grid.FEMesh.grid_size": {"tf": 1}, "lib.simulation.Simulation.grid_size": {"tf": 1}}, "df": 3}}}, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.PlotType.Saturation_Plot": {"tf": 1}, "lib.water.Water.init_water_saturation": {"tf": 1}, "lib.water.Water.init_aqueous_saturation": {"tf": 1}, "lib.water.Water.init_oleic_saturation": {"tf": 1}, "lib.water.Water.water_saturation": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 9, "s": {"docs": {"lib.water.Water.compute_residual_saturations": {"tf": 1}}, "df": 1}}}}}}}}}}, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "p": {"docs": {"lib.enumerations.SimulationConstants.Time_Step": {"tf": 1}, "lib.simulation.Simulation.time_step": {"tf": 1}}, "df": 2}}}, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SimulationConstants.Source_Flow_Magnitude": {"tf": 1}, "lib.simulation.Simulation.source_flow_magnitude": {"tf": 1}, "lib.simulation.Simulation.source_prod_flow": {"tf": 1}}, "df": 3}}, "a": {"docs": {}, "df": 0, "v": {"docs": {"lib.enumerations.ModelType.Sourav_Implementation": {"tf": 1}}, "df": 1}}}}}, "c": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "z": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.PolymerList.Schizophyllan": {"tf": 1}}, "df": 1}}}}}}}}}}}, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {"lib.polymer.Polymer.concetration_scalar": {"tf": 1}, "lib.polymer.Polymer.viscosity_scalar": {"tf": 1}}, "df": 2}}}}, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {"lib.simulation.Simulation.scenario_flag": {"tf": 1}}, "df": 1}}}}}}}, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.SurfactantList.No_Surfactant": {"tf": 1}, "lib.enumerations.PlotType.Surfactant_Concentration_Plot": {"tf": 1}, "lib.simulation.Simulation.surfactant": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.surfactant.Surfactant": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.__init__": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.name": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.concentration": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.concentration_matrix": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.is_surfactant": {"tf": 1.7320508075688772}, "lib.surfactant.Surfactant.phi": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.eval_IFT": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.eval_dIFT_dGamma": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.initialize": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1.4142135623730951}}, "df": 17, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.SurfactantList": {"tf": 1}, "lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate": {"tf": 1}, "lib.enumerations.SurfactantList.No_Surfactant": {"tf": 1}, "lib.enumerations.SurfactantList.Id": {"tf": 1}, "lib.enumerations.SurfactantList.IFT_equation": {"tf": 1}, "lib.enumerations.SurfactantList.derivative_IFT_equation": {"tf": 1}, "lib.enumerations.SurfactantList.get_by_value": {"tf": 1}}, "df": 7}}}}}}}}}}}}, "l": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate": {"tf": 1}}, "df": 1}}}}}}, "h": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations.ModelType.No_Shear_Thinning": {"tf": 1}, "lib.enumerations.ModelType.Shear_Thinning_On": {"tf": 1}, "lib.polymer.Polymer.shear_rate": {"tf": 1}}, "df": 3}}}}, "p": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.ResevoirGeometry.Quarter_Five_Spot": {"tf": 1}}, "df": 1}}, "a": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.grid.Grid.get_spacing": {"tf": 1}}, "df": 1}}}}, "r": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "d": {"docs": {"lib.grid.FEMesh.sparsed_A": {"tf": 1}}, "df": 1}}}}}}, "e": {"docs": {}, "df": 0, "t": {"docs": {"lib.grid.Grid.set_FD_meshgrid": {"tf": 1}, "lib.grid.FEMesh.set_triangulation": {"tf": 1}, "lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}, "lib.grid.FEMesh.set_right_hand": {"tf": 1}}, "df": 4}}}, "u": {"docs": {"lib.grid.FEMesh.U": {"tf": 1}}, "df": 1, "s": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "x": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.Exceptions.UserInputException": {"tf": 1}, "lib.Exceptions.UserInputException.__init__": {"tf": 1}}, "df": 2}}}}}}}}}}}}}}}}}}, "w": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations.SimulationConstants.Water_Viscosity": {"tf": 1}, "lib.enumerations.SimulationConstants.Water_Density": {"tf": 1}, "lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"tf": 1}, "lib.simulation.Simulation.water": {"tf": 1}, "lib.water": {"tf": 1}, "lib.water.Water": {"tf": 1.4142135623730951}, "lib.water.Water.__init__": {"tf": 1.4142135623730951}, "lib.water.Water.init_water_saturation": {"tf": 1.7320508075688772}, "lib.water.Water.init_aqueous_saturation": {"tf": 1.4142135623730951}, "lib.water.Water.init_oleic_saturation": {"tf": 1.4142135623730951}, "lib.water.Water.miuw": {"tf": 1.4142135623730951}, "lib.water.Water.miuo": {"tf": 1.4142135623730951}, "lib.water.Water.water_saturation": {"tf": 1.7320508075688772}, "lib.water.Water.viscosity_array": {"tf": 1.4142135623730951}, "lib.water.Water.phi": {"tf": 1.4142135623730951}, "lib.water.Water.initialize": {"tf": 1.4142135623730951}, "lib.water.Water.compute_viscosity": {"tf": 1.4142135623730951}, "lib.water.Water.compute_residual_saturations": {"tf": 1.4142135623730951}, "lib.water.Water.compute_mobility": {"tf": 1.4142135623730951}, "lib.water.Water.compute_water_saturation": {"tf": 1.7320508075688772}}, "df": 20}}}}}, "v": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {"lib.enumerations.SimulationConstants.Water_Viscosity": {"tf": 1}, "lib.enumerations.SimulationConstants.Oil_Viscosity": {"tf": 1}, "lib.polymer.Polymer.viscosity_matrix": {"tf": 1}, "lib.polymer.Polymer.viscosity_scalar": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.water.Water.viscosity_array": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}}, "df": 7}}}}}}}}, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.PolymerList.get_by_value": {"tf": 1}, "lib.enumerations.SurfactantList.get_by_value": {"tf": 1}}, "df": 2}}}}}, "d": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {"lib.enumerations.SimulationConstants.Water_Density": {"tf": 1}, "lib.enumerations.PolymerList.Density": {"tf": 1}}, "df": 2}}}}}, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SurfactantList.derivative_IFT_equation": {"tf": 1}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1}}, "df": 2}}}}}}}}}, "x": {"docs": {"lib.grid.Grid.dx": {"tf": 1}}, "df": 1}, "y": {"docs": {"lib.grid.Grid.dy": {"tf": 1}}, "df": 1}, "i": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.divergence": {"tf": 1}}, "df": 1}}}}}}}}, "f": {"docs": {}, "df": 0, "t": {"docs": {"lib.surfactant.Surfactant.eval_dIFT_dGamma": {"tf": 1}}, "df": 1}}}, "g": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "a": {"docs": {"lib.surfactant.Surfactant.eval_dIFT_dGamma": {"tf": 1}}, "df": 1}}}}}}, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "d": {"docs": {"lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}}, "df": 2, "u": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}}, "df": 2}}}}}, "e": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "y": {"docs": {"lib.enumerations.ResevoirGeometry": {"tf": 1}, "lib.enumerations.ResevoirGeometry.Rectilinear": {"tf": 1}, "lib.enumerations.ResevoirGeometry.Quarter_Five_Spot": {"tf": 1}}, "df": 3}}}}}}}}}}}}, "r": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "r": {"docs": {"lib.simulation.Simulation.reservoir_geometry": {"tf": 1}}, "df": 1}}}}}}}, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations.ResevoirGeometry.Rectilinear": {"tf": 1}}, "df": 1}}}}}}}}}, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "e": {"docs": {"lib.simulation.Simulation.relative_permeability_formula": {"tf": 1}}, "df": 1, "p": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "b": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {"lib.enumerations.RelativePermeabilityFormula": {"tf": 1}, "lib.enumerations.RelativePermeabilityFormula.AmaefuleHandEquation": {"tf": 1}, "lib.enumerations.RelativePermeabilityFormula.CoreyTypeEquation": {"tf": 1}}, "df": 3}}}}}}}}}}}}}}}}}}}}}}}}}}, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SimulationConstants.Injection_Rate": {"tf": 1}, "lib.polymer.Polymer.shear_rate": {"tf": 1}}, "df": 2}}}, "i": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "t": {"docs": {"lib.grid.Grid.right": {"tf": 1}, "lib.grid.FEMesh.right_hand": {"tf": 1}, "lib.grid.FEMesh.set_right_hand": {"tf": 1}}, "df": 3}}}}, "h": {"docs": {}, "df": 0, "o": {"docs": {"lib.polymer.Polymer.rho": {"tf": 1}}, "df": 1}}, "u": {"docs": {}, "df": 0, "n": {"docs": {"lib.simulation.Simulation.run": {"tf": 1}}, "df": 1}}}, "a": {"docs": {"lib.grid.Grid.A": {"tf": 1}, "lib.grid.FEMesh.A": {"tf": 1}, "lib.grid.FEMesh.sparsed_A": {"tf": 1}, "lib.grid.FEMesh.get_A_B_matrices": {"tf": 1}}, "df": 4, "q": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "s": {"docs": {"lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.water.Water.init_aqueous_saturation": {"tf": 1}}, "df": 3}}}}}}, "l": {"docs": {}, "df": 0, "k": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "l": {"docs": {"lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate": {"tf": 1}}, "df": 1}}}}, "m": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "q": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.RelativePermeabilityFormula.AmaefuleHandEquation": {"tf": 1}}, "df": 1}}}}}}}}}}}}}}}}}}}, "r": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "y": {"docs": {"lib.water.Water.viscosity_array": {"tf": 1}}, "df": 1}}}}}, "p": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}}, "df": 4}}}, "i": {"docs": {"lib.polymer.Polymer.phi": {"tf": 1}, "lib.simulation.Simulation.phi": {"tf": 1}, "lib.surfactant.Surfactant.phi": {"tf": 1}, "lib.water.Water.phi": {"tf": 1}}, "df": 4}}, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"tf": 1}}, "df": 2}}}}}}, "o": {"docs": {}, "df": 0, "d": {"docs": {"lib.simulation.Simulation.source_prod_flow": {"tf": 1}}, "df": 1}}}, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "m": {"docs": {"lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"tf": 1}}, "df": 2}}}}, "o": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations.PolymerList.No_Polymer": {"tf": 1}, "lib.enumerations.PlotType.Polymer_Concentration_Plot": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.polymer.Polymer": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.__init__": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.name": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.concetration_scalar": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.init_concentration_matrix": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.concentration_matrix": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.viscosity_matrix": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.viscosity_scalar": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.e_coeff": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.n_coeff": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.rho": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.shear_rate": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.phi": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.initialize": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.compute_concentration": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.divergence": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.polymer": {"tf": 1}}, "df": 21, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.PolymerList": {"tf": 1}, "lib.enumerations.PolymerList.Xanthane": {"tf": 1}, "lib.enumerations.PolymerList.Schizophyllan": {"tf": 1}, "lib.enumerations.PolymerList.No_Polymer": {"tf": 1}, "lib.enumerations.PolymerList.Id": {"tf": 1}, "lib.enumerations.PolymerList.Density": {"tf": 1}, "lib.enumerations.PolymerList.n_coeff": {"tf": 1}, "lib.enumerations.PolymerList.e_coeff": {"tf": 1}, "lib.enumerations.PolymerList.get_by_value": {"tf": 1}}, "df": 9}}}}}}}}}}, "l": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.PlotType.Saturation_Plot": {"tf": 1}, "lib.enumerations.PlotType.Polymer_Concentration_Plot": {"tf": 1}, "lib.enumerations.PlotType.Surfactant_Concentration_Plot": {"tf": 1}}, "df": 3, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.PlotType": {"tf": 1}, "lib.enumerations.PlotType.Saturation_Plot": {"tf": 1}, "lib.enumerations.PlotType.Polymer_Concentration_Plot": {"tf": 1}, "lib.enumerations.PlotType.Surfactant_Concentration_Plot": {"tf": 1}}, "df": 4}}}}}}}, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "b": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {"lib.simulation.Simulation.permeability_flag": {"tf": 1}, "lib.simulation.Simulation.relative_permeability_formula": {"tf": 1}}, "df": 2, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.PermeabilityType": {"tf": 1}, "lib.enumerations.PermeabilityType.Homogenous": {"tf": 1}, "lib.enumerations.PermeabilityType.Heterogenous": {"tf": 1}}, "df": 3}}}}}}}}}}}}}}}}, "c": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}}, "df": 2}}}}}}}, "a": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "y": {"docs": {"lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"tf": 1}}, "df": 4}}}}}}}}, "o": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "f": {"docs": {"lib.enumerations.PolymerList.n_coeff": {"tf": 1}, "lib.enumerations.PolymerList.e_coeff": {"tf": 1}, "lib.polymer.Polymer.e_coeff": {"tf": 1}, "lib.polymer.Polymer.n_coeff": {"tf": 1}}, "df": 4}}}, "n": {"docs": {}, "df": 0, "c": {"docs": {"lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1}}, "df": 2, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.PlotType.Polymer_Concentration_Plot": {"tf": 1}, "lib.enumerations.PlotType.Surfactant_Concentration_Plot": {"tf": 1}, "lib.polymer.Polymer.init_concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.surfactant.Surfactant.concentration": {"tf": 1}, "lib.surfactant.Surfactant.concentration_matrix": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}}, "df": 8}}}}}}}}, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.polymer.Polymer.concetration_scalar": {"tf": 1}}, "df": 1}}}}}}}}}}, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "q": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.RelativePermeabilityFormula.CoreyTypeEquation": {"tf": 1}}, "df": 1}}}}}}}}}}}}}}}, "m": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 7}}}}}, "c": {"docs": {"lib.simulation.Simulation.COC": {"tf": 1}}, "df": 1}}}, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SimulationConstants.Time_Step": {"tf": 1}, "lib.simulation.Simulation.time_step": {"tf": 1}}, "df": 2}}}, "h": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.enumerations.ModelType.No_Shear_Thinning": {"tf": 1}, "lib.enumerations.ModelType.Shear_Thinning_On": {"tf": 1}}, "df": 2}}}}}}}, "o": {"docs": {}, "df": 0, "p": {"docs": {"lib.grid.Grid.top": {"tf": 1}}, "df": 1}}, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.grid.FEMesh.set_triangulation": {"tf": 1}}, "df": 1}}}}}}}}}}}}, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {"lib.simulation.Simulation.model_type": {"tf": 1}}, "df": 1}}}, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {"lib.test": {"tf": 1}}, "df": 1}}}}, "g": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "d": {"docs": {"lib.enumerations.SimulationConstants.Grid_Size": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.grid.Grid": {"tf": 1.4142135623730951}, "lib.grid.Grid.__init__": {"tf": 1.4142135623730951}, "lib.grid.Grid.m": {"tf": 1.4142135623730951}, "lib.grid.Grid.n": {"tf": 1.4142135623730951}, "lib.grid.Grid.left": {"tf": 1.4142135623730951}, "lib.grid.Grid.right": {"tf": 1.4142135623730951}, "lib.grid.Grid.bottom": {"tf": 1.4142135623730951}, "lib.grid.Grid.top": {"tf": 1.4142135623730951}, "lib.grid.Grid.A": {"tf": 1.4142135623730951}, "lib.grid.Grid.B": {"tf": 1.4142135623730951}, "lib.grid.Grid.get_spacing": {"tf": 1.4142135623730951}, "lib.grid.Grid.get_meshgrid": {"tf": 1.4142135623730951}, "lib.grid.Grid.dx": {"tf": 1.4142135623730951}, "lib.grid.Grid.dy": {"tf": 1.4142135623730951}, "lib.grid.Grid.set_FD_meshgrid": {"tf": 1.4142135623730951}, "lib.grid.Grid.get_flat_index_matrix": {"tf": 1.4142135623730951}, "lib.grid.FEMesh": {"tf": 1}, "lib.grid.FEMesh.__init__": {"tf": 1}, "lib.grid.FEMesh.U": {"tf": 1}, "lib.grid.FEMesh.L": {"tf": 1}, "lib.grid.FEMesh.grid_size": {"tf": 1.4142135623730951}, "lib.grid.FEMesh.right_hand": {"tf": 1}, "lib.grid.FEMesh.A": {"tf": 1}, "lib.grid.FEMesh.B": {"tf": 1}, "lib.grid.FEMesh.sparsed_A": {"tf": 1}, "lib.grid.FEMesh.set_triangulation": {"tf": 1}, "lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}, "lib.grid.FEMesh.set_right_hand": {"tf": 1}, "lib.grid.FEMesh.get_A_B_matrices": {"tf": 1}, "lib.simulation.Simulation.grid_size": {"tf": 1}}, "df": 32}}}, "e": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.PolymerList.get_by_value": {"tf": 1}, "lib.enumerations.SurfactantList.get_by_value": {"tf": 1}, "lib.grid.Grid.get_spacing": {"tf": 1}, "lib.grid.Grid.get_meshgrid": {"tf": 1}, "lib.grid.Grid.get_flat_index_matrix": {"tf": 1}, "lib.grid.FEMesh.get_A_B_matrices": {"tf": 1}}, "df": 6}, "o": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "y": {"docs": {"lib.simulation.Simulation.reservoir_geometry": {"tf": 1}}, "df": 1}}}}}}}}, "f": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "w": {"docs": {"lib.enumerations.SimulationConstants.Source_Flow_Magnitude": {"tf": 1}, "lib.simulation.Simulation.source_flow_magnitude": {"tf": 1}, "lib.simulation.Simulation.integrated_inlet_flow": {"tf": 1}, "lib.simulation.Simulation.source_prod_flow": {"tf": 1}}, "df": 4}}, "a": {"docs": {}, "df": 0, "t": {"docs": {"lib.grid.Grid.get_flat_index_matrix": {"tf": 1}}, "df": 1}, "g": {"docs": {"lib.simulation.Simulation.permeability_flag": {"tf": 1}, "lib.simulation.Simulation.scenario_flag": {"tf": 1}}, "df": 2}}}, "i": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.ResevoirGeometry.Quarter_Five_Spot": {"tf": 1}}, "df": 1}}}, "d": {"docs": {"lib.grid.Grid.set_FD_meshgrid": {"tf": 1}}, "df": 1}, "e": {"docs": {"lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}}, "df": 1, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "h": {"docs": {"lib.grid.FEMesh": {"tf": 1}, "lib.grid.FEMesh.__init__": {"tf": 1}, "lib.grid.FEMesh.U": {"tf": 1}, "lib.grid.FEMesh.L": {"tf": 1}, "lib.grid.FEMesh.grid_size": {"tf": 1}, "lib.grid.FEMesh.right_hand": {"tf": 1}, "lib.grid.FEMesh.A": {"tf": 1}, "lib.grid.FEMesh.B": {"tf": 1}, "lib.grid.FEMesh.sparsed_A": {"tf": 1}, "lib.grid.FEMesh.set_triangulation": {"tf": 1}, "lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}, "lib.grid.FEMesh.set_right_hand": {"tf": 1}, "lib.grid.FEMesh.get_A_B_matrices": {"tf": 1}}, "df": 13}}}}}, "o": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {"lib.simulation.Simulation.relative_permeability_formula": {"tf": 1}}, "df": 1}}}}}}}, "m": {"docs": {"lib.grid.Grid.m": {"tf": 1}}, "df": 1, "a": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SimulationConstants.Source_Flow_Magnitude": {"tf": 1}, "lib.simulation.Simulation.source_flow_magnitude": {"tf": 1}}, "df": 2}}}}}}}, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "x": {"docs": {"lib.grid.Grid.get_flat_index_matrix": {"tf": 1}, "lib.polymer.Polymer.init_concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.viscosity_matrix": {"tf": 1}, "lib.surfactant.Surfactant.concentration_matrix": {"tf": 1}}, "df": 5}, "c": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {"lib.grid.FEMesh.get_A_B_matrices": {"tf": 1}}, "df": 1}}}}}}}, "o": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "l": {"docs": {"lib.simulation.Simulation.model_type": {"tf": 1}}, "df": 1, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.ModelType": {"tf": 1}, "lib.enumerations.ModelType.No_Shear_Thinning": {"tf": 1}, "lib.enumerations.ModelType.Sourav_Implementation": {"tf": 1}, "lib.enumerations.ModelType.Shear_Thinning_On": {"tf": 1}}, "df": 4}}}}}}}, "b": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {"lib.water.Water.compute_mobility": {"tf": 1}}, "df": 1}}}}}}}, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "d": {"docs": {"lib.grid.Grid.get_meshgrid": {"tf": 1}, "lib.grid.Grid.set_FD_meshgrid": {"tf": 1}, "lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}}, "df": 3}}}}}}}, "i": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.simulation.Simulation.miuaTcal": {"tf": 1}}, "df": 1}}}}}, "w": {"docs": {"lib.water.Water.miuw": {"tf": 1}}, "df": 1}, "o": {"docs": {"lib.water.Water.miuo": {"tf": 1}}, "df": 1}}}, "f": {"docs": {}, "df": 0, "w": {"docs": {"lib.simulation.Simulation.MFW": {"tf": 1}}, "df": 1}}}, "b": {"docs": {"lib.grid.Grid.B": {"tf": 1}, "lib.grid.FEMesh.B": {"tf": 1}, "lib.grid.FEMesh.get_A_B_matrices": {"tf": 1}}, "df": 3, "e": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"1": {"docs": {"lib.enumerations.SimulationConstants.beta1": {"tf": 1}}, "df": 1}, "docs": {}, "df": 0}}}, "y": {"docs": {"lib.enumerations.PolymerList.get_by_value": {"tf": 1}, "lib.enumerations.SurfactantList.get_by_value": {"tf": 1}}, "df": 2}, "o": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "m": {"docs": {"lib.grid.Grid.bottom": {"tf": 1}}, "df": 1}}}}}}, "x": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.PolymerList.Xanthane": {"tf": 1}}, "df": 1}}}}}}}}, "q": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations.ResevoirGeometry.Quarter_Five_Spot": {"tf": 1}}, "df": 1}}}}}}}, "h": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "s": {"docs": {"lib.enumerations.PermeabilityType.Homogenous": {"tf": 1}}, "df": 1}}}}}}}}}, "e": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "s": {"docs": {"lib.enumerations.PermeabilityType.Heterogenous": {"tf": 1}}, "df": 1}}}}}}}}}}}, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "d": {"docs": {"lib.grid.FEMesh.right_hand": {"tf": 1}, "lib.grid.FEMesh.set_right_hand": {"tf": 1}}, "df": 2}}}}, "k": {"docs": {}, "df": 0, "k": {"docs": {"lib.simulation.Simulation.KK": {"tf": 1}}, "df": 1}}}}, "annotation": {"root": {"docs": {}, "df": 0}}, "default_value": {"root": {"0": {"2": {"docs": {"lib.enumerations.SimulationConstants.Time_Step": {"tf": 1}}, "df": 1}, "3": {"6": {"4": {"7": {"2": {"1": {"4": {"docs": {"lib.enumerations.PolymerList.Schizophyllan": {"tf": 1}}, "df": 1}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "4": {"9": {"3": {"7": {"7": {"8": {"0": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "+": {"0": {"0": {"docs": {"lib.enumerations.PolymerList.Xanthane": {"tf": 1}}, "df": 1}, "docs": {}, "df": 0}, "docs": {}, "df": 0}}}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {"lib.enumerations.PolymerList.Xanthane": {"tf": 1}}, "df": 1}, "5": {"4": {"2": {"8": {"2": {"8": {"4": {"docs": {"lib.enumerations.PolymerList.Xanthane": {"tf": 1}}, "df": 1}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {"lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}}, "df": 2}, "docs": {"lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"tf": 1}, "lib.enumerations.SimulationConstants.Time_Step": {"tf": 1}, "lib.enumerations.PolymerList.Xanthane": {"tf": 1}, "lib.enumerations.PolymerList.Schizophyllan": {"tf": 1.4142135623730951}, "lib.enumerations.PolymerList.No_Polymer": {"tf": 2.23606797749979}}, "df": 9}, "1": {"0": {"0": {"0": {"docs": {"lib.enumerations.SimulationConstants.Water_Density": {"tf": 1}}, "df": 1}, "docs": {}, "df": 0}, "docs": {"lib.enumerations.SimulationConstants.Oil_Viscosity": {"tf": 1}}, "df": 1}, "2": {"0": {"0": {"0": {"0": {"docs": {"lib.enumerations.SimulationConstants.Source_Flow_Magnitude": {"tf": 1}}, "df": 1}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "3": {"0": {"0": {"docs": {"lib.enumerations.PolymerList.Schizophyllan": {"tf": 1}}, "df": 1}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "5": {"0": {"0": {"0": {"docs": {"lib.enumerations.SimulationConstants.beta1": {"tf": 1}}, "df": 1}, "docs": {"lib.enumerations.PolymerList.Xanthane": {"tf": 1}}, "df": 1}, "docs": {}, "df": 0}, "4": {"1": {"0": {"3": {"9": {"8": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.PolymerList.Xanthane": {"tf": 1}}, "df": 1}}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {"lib.enumerations.SimulationConstants.Water_Viscosity": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1}, "lib.enumerations.PolymerList.Xanthane": {"tf": 1.4142135623730951}, "lib.enumerations.PolymerList.Schizophyllan": {"tf": 1}, "lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate": {"tf": 1}, "lib.enumerations.ModelType.No_Shear_Thinning": {"tf": 1}, "lib.enumerations.PlotType.Saturation_Plot": {"tf": 1}, "lib.enumerations.ResevoirGeometry.Rectilinear": {"tf": 1}, "lib.enumerations.PermeabilityType.Homogenous": {"tf": 1}, "lib.enumerations.RelativePermeabilityFormula.AmaefuleHandEquation": {"tf": 1}}, "df": 11, "e": {"docs": {"lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}}, "df": 2}}, "2": {"0": {"0": {"docs": {"lib.enumerations.SimulationConstants.Injection_Rate": {"tf": 1}}, "df": 1}, "docs": {}, "df": 0}, "6": {"docs": {"lib.enumerations.SimulationConstants.Water_Viscosity": {"tf": 1}}, "df": 1}, "7": {"2": {"9": {"4": {"8": {"1": {"7": {"docs": {"lib.enumerations.PolymerList.Xanthane": {"tf": 1}}, "df": 1}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "9": {"docs": {"lib.enumerations.SimulationConstants.Grid_Size": {"tf": 1}}, "df": 1}, "docs": {"lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"tf": 1}, "lib.enumerations.PolymerList.Xanthane": {"tf": 1}, "lib.enumerations.PolymerList.Schizophyllan": {"tf": 1}, "lib.enumerations.SurfactantList.No_Surfactant": {"tf": 1}, "lib.enumerations.ModelType.Sourav_Implementation": {"tf": 1}, "lib.enumerations.PlotType.Polymer_Concentration_Plot": {"tf": 1}, "lib.enumerations.ResevoirGeometry.Quarter_Five_Spot": {"tf": 1}, "lib.enumerations.PermeabilityType.Heterogenous": {"tf": 1}, "lib.enumerations.RelativePermeabilityFormula.CoreyTypeEquation": {"tf": 1}}, "df": 9}, "3": {"2": {"1": {"7": {"5": {"9": {"4": {"9": {"docs": {"lib.enumerations.PolymerList.Schizophyllan": {"tf": 1}}, "df": 1}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {"lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.PolymerList.Xanthane": {"tf": 1}, "lib.enumerations.PolymerList.No_Polymer": {"tf": 1}, "lib.enumerations.ModelType.Shear_Thinning_On": {"tf": 1}, "lib.enumerations.PlotType.Surfactant_Concentration_Plot": {"tf": 1}}, "df": 5}, "4": {"1": {"5": {"7": {"0": {"2": {"2": {"7": {"docs": {"lib.enumerations.PolymerList.Schizophyllan": {"tf": 1}}, "df": 1}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {"lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"tf": 1}, "lib.enumerations.PolymerList.Schizophyllan": {"tf": 1}}, "df": 2}, "7": {"9": {"docs": {"lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"tf": 1}}, "df": 1}, "docs": {}, "df": 0}, "8": {"6": {"2": {"6": {"5": {"5": {"3": {"4": {"docs": {"lib.enumerations.PolymerList.Schizophyllan": {"tf": 1}}, "df": 1}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {"lib.name": {"tf": 1.4142135623730951}, "lib.enumerations.SimulationConstants.Water_Viscosity": {"tf": 1.4142135623730951}, "lib.enumerations.SimulationConstants.Water_Density": {"tf": 1.4142135623730951}, "lib.enumerations.SimulationConstants.Oil_Viscosity": {"tf": 1.4142135623730951}, "lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"tf": 1.4142135623730951}, "lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1.4142135623730951}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1.4142135623730951}, "lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1.4142135623730951}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1.4142135623730951}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1.4142135623730951}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"tf": 1.4142135623730951}, "lib.enumerations.SimulationConstants.Injection_Rate": {"tf": 1.4142135623730951}, "lib.enumerations.SimulationConstants.Time_Step": {"tf": 1.4142135623730951}, "lib.enumerations.SimulationConstants.Grid_Size": {"tf": 1.4142135623730951}, "lib.enumerations.SimulationConstants.Source_Flow_Magnitude": {"tf": 1.4142135623730951}, "lib.enumerations.SimulationConstants.beta1": {"tf": 1.4142135623730951}, "lib.enumerations.PolymerList.Xanthane": {"tf": 2}, "lib.enumerations.PolymerList.Schizophyllan": {"tf": 2}, "lib.enumerations.PolymerList.No_Polymer": {"tf": 1.4142135623730951}, "lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate": {"tf": 1.4142135623730951}, "lib.enumerations.SurfactantList.No_Surfactant": {"tf": 1.4142135623730951}, "lib.enumerations.ModelType.No_Shear_Thinning": {"tf": 1.4142135623730951}, "lib.enumerations.ModelType.Sourav_Implementation": {"tf": 1.4142135623730951}, "lib.enumerations.ModelType.Shear_Thinning_On": {"tf": 1.4142135623730951}, "lib.enumerations.PlotType.Saturation_Plot": {"tf": 1.4142135623730951}, "lib.enumerations.PlotType.Polymer_Concentration_Plot": {"tf": 1.4142135623730951}, "lib.enumerations.PlotType.Surfactant_Concentration_Plot": {"tf": 1.4142135623730951}, "lib.enumerations.ResevoirGeometry.Rectilinear": {"tf": 1.4142135623730951}, "lib.enumerations.ResevoirGeometry.Quarter_Five_Spot": {"tf": 1.4142135623730951}, "lib.enumerations.PermeabilityType.Homogenous": {"tf": 1.4142135623730951}, "lib.enumerations.PermeabilityType.Heterogenous": {"tf": 1.4142135623730951}, "lib.enumerations.RelativePermeabilityFormula.AmaefuleHandEquation": {"tf": 1.4142135623730951}, "lib.enumerations.RelativePermeabilityFormula.CoreyTypeEquation": {"tf": 1.4142135623730951}}, "df": 33, "x": {"2": {"7": {"docs": {"lib.name": {"tf": 1.4142135623730951}}, "df": 1}, "docs": {}, "df": 0}, "docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.PolymerList.Xanthane": {"tf": 1}}, "df": 1}}}}}}}}, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "b": {"docs": {"lib.name": {"tf": 1}}, "df": 1}}, "t": {"docs": {"lib.enumerations.SimulationConstants.Water_Viscosity": {"tf": 1}, "lib.enumerations.SimulationConstants.Water_Density": {"tf": 1}, "lib.enumerations.SimulationConstants.Oil_Viscosity": {"tf": 1}, "lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"tf": 1}, "lib.enumerations.SimulationConstants.Injection_Rate": {"tf": 1}, "lib.enumerations.SimulationConstants.Time_Step": {"tf": 1}, "lib.enumerations.SimulationConstants.Grid_Size": {"tf": 1}, "lib.enumerations.SimulationConstants.Source_Flow_Magnitude": {"tf": 1}, "lib.enumerations.SimulationConstants.beta1": {"tf": 1}, "lib.enumerations.PolymerList.Xanthane": {"tf": 1}, "lib.enumerations.PolymerList.Schizophyllan": {"tf": 1}, "lib.enumerations.PolymerList.No_Polymer": {"tf": 1}, "lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate": {"tf": 2.23606797749979}, "lib.enumerations.SurfactantList.No_Surfactant": {"tf": 2.23606797749979}, "lib.enumerations.ModelType.No_Shear_Thinning": {"tf": 1}, "lib.enumerations.ModelType.Sourav_Implementation": {"tf": 1}, "lib.enumerations.ModelType.Shear_Thinning_On": {"tf": 1}, "lib.enumerations.PlotType.Saturation_Plot": {"tf": 1}, "lib.enumerations.PlotType.Polymer_Concentration_Plot": {"tf": 1}, "lib.enumerations.PlotType.Surfactant_Concentration_Plot": {"tf": 1}, "lib.enumerations.ResevoirGeometry.Rectilinear": {"tf": 1}, "lib.enumerations.ResevoirGeometry.Quarter_Five_Spot": {"tf": 1}, "lib.enumerations.PermeabilityType.Homogenous": {"tf": 1}, "lib.enumerations.PermeabilityType.Heterogenous": {"tf": 1}, "lib.enumerations.RelativePermeabilityFormula.AmaefuleHandEquation": {"tf": 1}, "lib.enumerations.RelativePermeabilityFormula.CoreyTypeEquation": {"tf": 1}}, "df": 32}, "a": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "b": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "a": {"docs": {"lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate": {"tf": 1.4142135623730951}, "lib.enumerations.SurfactantList.No_Surfactant": {"tf": 1.4142135623730951}}, "df": 2}}}}}}, "s": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "s": {"docs": {"lib.enumerations.SimulationConstants.Water_Viscosity": {"tf": 1}, "lib.enumerations.SimulationConstants.Water_Density": {"tf": 1}, "lib.enumerations.SimulationConstants.Oil_Viscosity": {"tf": 1}, "lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"tf": 1}, "lib.enumerations.SimulationConstants.Injection_Rate": {"tf": 1}, "lib.enumerations.SimulationConstants.Time_Step": {"tf": 1}, "lib.enumerations.SimulationConstants.Grid_Size": {"tf": 1}, "lib.enumerations.SimulationConstants.Source_Flow_Magnitude": {"tf": 1}, "lib.enumerations.SimulationConstants.beta1": {"tf": 1}}, "df": 15}}}}}}}}}}}}}}}}}, "z": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SimulationConstants.Grid_Size": {"tf": 1}}, "df": 1}}}, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1}, "lib.enumerations.PlotType.Saturation_Plot": {"tf": 1}}, "df": 5}}}}}}}}}, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "p": {"docs": {"lib.enumerations.SimulationConstants.Time_Step": {"tf": 1}}, "df": 1}}}, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SimulationConstants.Source_Flow_Magnitude": {"tf": 1}}, "df": 1}}, "a": {"docs": {}, "df": 0, "v": {"docs": {"lib.enumerations.ModelType.Sourav_Implementation": {"tf": 1}}, "df": 1}}}}}, "c": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "z": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.PolymerList.Schizophyllan": {"tf": 1}}, "df": 1}}}}}}}}}}}}, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.SurfactantList.No_Surfactant": {"tf": 1}, "lib.enumerations.PlotType.Surfactant_Concentration_Plot": {"tf": 1}}, "df": 2, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate": {"tf": 1.7320508075688772}, "lib.enumerations.SurfactantList.No_Surfactant": {"tf": 1.7320508075688772}}, "df": 2}}}}}}}}}}}}, "l": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate": {"tf": 1}}, "df": 1}}}}}}, "h": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations.ModelType.No_Shear_Thinning": {"tf": 1}, "lib.enumerations.ModelType.Shear_Thinning_On": {"tf": 1}}, "df": 2}}}}, "p": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.ResevoirGeometry.Quarter_Five_Spot": {"tf": 1}}, "df": 1}}}}, "w": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations.SimulationConstants.Water_Viscosity": {"tf": 1}, "lib.enumerations.SimulationConstants.Water_Density": {"tf": 1}, "lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"tf": 1}}, "df": 3}}}}}, "v": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {"lib.enumerations.SimulationConstants.Water_Viscosity": {"tf": 1}, "lib.enumerations.SimulationConstants.Oil_Viscosity": {"tf": 1}}, "df": 2}}}}}}}}}, "g": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.SimulationConstants.Water_Viscosity": {"tf": 1}, "lib.enumerations.SimulationConstants.Water_Density": {"tf": 1}, "lib.enumerations.SimulationConstants.Oil_Viscosity": {"tf": 1}, "lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"tf": 1}, "lib.enumerations.SimulationConstants.Injection_Rate": {"tf": 1}, "lib.enumerations.SimulationConstants.Time_Step": {"tf": 1}, "lib.enumerations.SimulationConstants.Grid_Size": {"tf": 1}, "lib.enumerations.SimulationConstants.Source_Flow_Magnitude": {"tf": 1}, "lib.enumerations.SimulationConstants.beta1": {"tf": 1}, "lib.enumerations.PolymerList.Xanthane": {"tf": 1}, "lib.enumerations.PolymerList.Schizophyllan": {"tf": 1}, "lib.enumerations.PolymerList.No_Polymer": {"tf": 1}, "lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate": {"tf": 2.23606797749979}, "lib.enumerations.SurfactantList.No_Surfactant": {"tf": 2.23606797749979}, "lib.enumerations.ModelType.No_Shear_Thinning": {"tf": 1}, "lib.enumerations.ModelType.Sourav_Implementation": {"tf": 1}, "lib.enumerations.ModelType.Shear_Thinning_On": {"tf": 1}, "lib.enumerations.PlotType.Saturation_Plot": {"tf": 1}, "lib.enumerations.PlotType.Polymer_Concentration_Plot": {"tf": 1}, "lib.enumerations.PlotType.Surfactant_Concentration_Plot": {"tf": 1}, "lib.enumerations.ResevoirGeometry.Rectilinear": {"tf": 1}, "lib.enumerations.ResevoirGeometry.Quarter_Five_Spot": {"tf": 1}, "lib.enumerations.PermeabilityType.Homogenous": {"tf": 1}, "lib.enumerations.PermeabilityType.Heterogenous": {"tf": 1}, "lib.enumerations.RelativePermeabilityFormula.AmaefuleHandEquation": {"tf": 1}, "lib.enumerations.RelativePermeabilityFormula.CoreyTypeEquation": {"tf": 1}}, "df": 32}, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "d": {"docs": {"lib.enumerations.SimulationConstants.Grid_Size": {"tf": 1}}, "df": 1}}}}, "d": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {"lib.enumerations.SimulationConstants.Water_Density": {"tf": 1}}, "df": 1}}}}}}}, "o": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {"lib.enumerations.SimulationConstants.Oil_Viscosity": {"tf": 1}}, "df": 1}}, "l": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "c": {"docs": {"lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}}, "df": 1}}}}, "n": {"docs": {"lib.enumerations.ModelType.Shear_Thinning_On": {"tf": 1}}, "df": 1}}, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1}}, "df": 4}}}}}, "j": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.SimulationConstants.Injection_Rate": {"tf": 1}}, "df": 1}}}}}}}}, "m": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.ModelType.Sourav_Implementation": {"tf": 1}}, "df": 1}}}}}}}}}}}}}}, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "d": {"docs": {"lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1}}, "df": 3, "u": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"tf": 1}}, "df": 1}}}}}, "e": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "y": {"docs": {"lib.enumerations.ResevoirGeometry.Rectilinear": {"tf": 1}, "lib.enumerations.ResevoirGeometry.Quarter_Five_Spot": {"tf": 1}}, "df": 2}}}}}}}}}}}}}}, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations.ResevoirGeometry.Rectilinear": {"tf": 1}}, "df": 1}}}}}}}}}, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "b": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {"lib.enumerations.RelativePermeabilityFormula.AmaefuleHandEquation": {"tf": 1}, "lib.enumerations.RelativePermeabilityFormula.CoreyTypeEquation": {"tf": 1}}, "df": 2}}}}}}}}}}}}}}}}}}}}}}}}}}, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SimulationConstants.Injection_Rate": {"tf": 1}}, "df": 1}}}}, "a": {"docs": {}, "df": 0, "q": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "s": {"docs": {"lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1}}, "df": 4}}}}}}, "r": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "y": {"docs": {"lib.enumerations.PolymerList.Xanthane": {"tf": 1.4142135623730951}, "lib.enumerations.PolymerList.Schizophyllan": {"tf": 1.4142135623730951}}, "df": 2}}}}, "l": {"docs": {}, "df": 0, "k": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "l": {"docs": {"lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate": {"tf": 1}}, "df": 1}}}}, "m": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "q": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.RelativePermeabilityFormula.AmaefuleHandEquation": {"tf": 1}}, "df": 1}}}}}}}}}}}}}}}}}}}}, "p": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1}, "lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1}}, "df": 5}}}}, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"tf": 1}}, "df": 1}}}}}}}, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "m": {"docs": {"lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"tf": 1}}, "df": 1}}}}, "o": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations.PolymerList.No_Polymer": {"tf": 1}, "lib.enumerations.PlotType.Polymer_Concentration_Plot": {"tf": 1}}, "df": 2, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.PolymerList.Xanthane": {"tf": 1}, "lib.enumerations.PolymerList.Schizophyllan": {"tf": 1}, "lib.enumerations.PolymerList.No_Polymer": {"tf": 1}}, "df": 3}}}}}}}}}}, "l": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.PlotType.Saturation_Plot": {"tf": 1}, "lib.enumerations.PlotType.Polymer_Concentration_Plot": {"tf": 1}, "lib.enumerations.PlotType.Surfactant_Concentration_Plot": {"tf": 1}}, "df": 3, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.PlotType.Saturation_Plot": {"tf": 1}, "lib.enumerations.PlotType.Polymer_Concentration_Plot": {"tf": 1}, "lib.enumerations.PlotType.Surfactant_Concentration_Plot": {"tf": 1}}, "df": 3}}}}}}}, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "b": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.PermeabilityType.Homogenous": {"tf": 1}, "lib.enumerations.PermeabilityType.Heterogenous": {"tf": 1}}, "df": 2}}}}}}}}}}}}}}}}, "c": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}}, "df": 2}}}}}}}, "a": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "y": {"docs": {"lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"tf": 1}}, "df": 3}}}}}}}}, "o": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.PlotType.Polymer_Concentration_Plot": {"tf": 1}, "lib.enumerations.PlotType.Surfactant_Concentration_Plot": {"tf": 1}}, "df": 2}}}}}}}}}}}, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "q": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.RelativePermeabilityFormula.CoreyTypeEquation": {"tf": 1}}, "df": 1}}}}}}}}}}}}}}}}}, "n": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "m": {"docs": {"lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1}}, "df": 2}}, "o": {"docs": {"lib.enumerations.PolymerList.No_Polymer": {"tf": 1}, "lib.enumerations.SurfactantList.No_Surfactant": {"tf": 1}, "lib.enumerations.ModelType.No_Shear_Thinning": {"tf": 1}}, "df": 3}}, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SimulationConstants.Time_Step": {"tf": 1}}, "df": 1}}}, "h": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.enumerations.ModelType.No_Shear_Thinning": {"tf": 1}, "lib.enumerations.ModelType.Shear_Thinning_On": {"tf": 1}}, "df": 2}}}}}}}}, "f": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "w": {"docs": {"lib.enumerations.SimulationConstants.Source_Flow_Magnitude": {"tf": 1}}, "df": 1}}}, "u": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate": {"tf": 1.4142135623730951}, "lib.enumerations.SurfactantList.No_Surfactant": {"tf": 1.4142135623730951}}, "df": 2}}}}}}}, "i": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.ResevoirGeometry.Quarter_Five_Spot": {"tf": 1}}, "df": 1}}}}, "m": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SimulationConstants.Source_Flow_Magnitude": {"tf": 1}}, "df": 1}}}}}}}}, "o": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.ModelType.No_Shear_Thinning": {"tf": 1}, "lib.enumerations.ModelType.Sourav_Implementation": {"tf": 1}, "lib.enumerations.ModelType.Shear_Thinning_On": {"tf": 1}}, "df": 3}}}}}}}}}, "b": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"1": {"docs": {"lib.enumerations.SimulationConstants.beta1": {"tf": 1}}, "df": 1}, "docs": {}, "df": 0}}}}, "e": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate": {"tf": 1}}, "df": 1}}}}}, "q": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations.ResevoirGeometry.Quarter_Five_Spot": {"tf": 1}}, "df": 1}}}}}}}, "h": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "s": {"docs": {"lib.enumerations.PermeabilityType.Homogenous": {"tf": 1}}, "df": 1}}}}}}}}}, "e": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "s": {"docs": {"lib.enumerations.PermeabilityType.Heterogenous": {"tf": 1}}, "df": 1}}}}}}}}}}}}}}, "signature": {"root": {"0": {"docs": {"lib.grid.Grid.__init__": {"tf": 2.449489742783178}, "lib.polymer.Polymer.divergence": {"tf": 1.4142135623730951}}, "df": 2}, "1": {"docs": {"lib.grid.Grid.__init__": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.divergence": {"tf": 1.4142135623730951}}, "df": 2}, "3": {"9": {"docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 1.4142135623730951}}, "df": 1}, "docs": {}, "df": 0}, "docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 4.242640687119285}, "lib.Exceptions.SimulationCalcInputException.__init__": {"tf": 2.8284271247461903}, "lib.Exceptions.UserInputException.__init__": {"tf": 5.5677643628300215}, "lib.enumerations.PolymerList.get_by_value": {"tf": 3.7416573867739413}, "lib.enumerations.SurfactantList.get_by_value": {"tf": 3.7416573867739413}, "lib.grid.Grid.__init__": {"tf": 9.055385138137417}, "lib.grid.Grid.set_FD_meshgrid": {"tf": 3.1622776601683795}, "lib.grid.Grid.get_flat_index_matrix": {"tf": 4}, "lib.grid.FEMesh.__init__": {"tf": 4.47213595499958}, "lib.grid.FEMesh.set_triangulation": {"tf": 3.1622776601683795}, "lib.grid.FEMesh.set_FE_meshgrid": {"tf": 3.7416573867739413}, "lib.grid.FEMesh.set_right_hand": {"tf": 3.7416573867739413}, "lib.grid.FEMesh.get_A_B_matrices": {"tf": 3.1622776601683795}, "lib.polymer.Polymer.__init__": {"tf": 13.038404810405298}, "lib.polymer.Polymer.initialize": {"tf": 4.242640687119285}, "lib.polymer.Polymer.compute_viscosity": {"tf": 9.746794344808963}, "lib.polymer.Polymer.compute_concentration": {"tf": 10.535653752852738}, "lib.polymer.Polymer.divergence": {"tf": 5.830951894845301}, "lib.simulation.Simulation.__init__": {"tf": 3.4641016151377544}, "lib.simulation.Simulation.run": {"tf": 3.1622776601683795}, "lib.surfactant.Surfactant.__init__": {"tf": 10.344080432788601}, "lib.surfactant.Surfactant.initialize": {"tf": 3.1622776601683795}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 9.219544457292887}, "lib.water.Water.__init__": {"tf": 7.874007874011811}, "lib.water.Water.initialize": {"tf": 4.242640687119285}, "lib.water.Water.compute_viscosity": {"tf": 10.488088481701515}, "lib.water.Water.compute_residual_saturations": {"tf": 6.782329983125268}, "lib.water.Water.compute_mobility": {"tf": 9.591663046625438}, "lib.water.Water.compute_water_saturation": {"tf": 11.489125293076057}}, "df": 29, "v": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 5, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "e": {"docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 1.4142135623730951}, "lib.enumerations.PolymerList.get_by_value": {"tf": 1}, "lib.enumerations.SurfactantList.get_by_value": {"tf": 1}}, "df": 3}}}, "r": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 3}}}}}}, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {"lib.polymer.Polymer.__init__": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}}, "df": 2}}}}}}}}}, "m": {"docs": {"lib.grid.Grid.__init__": {"tf": 1}, "lib.grid.FEMesh.__init__": {"tf": 1}}, "df": 2, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "e": {"docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}, "lib.Exceptions.SimulationCalcInputException.__init__": {"tf": 1}, "lib.Exceptions.UserInputException.__init__": {"tf": 1}}, "df": 3}}}}}}, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "x": {"docs": {"lib.grid.FEMesh.set_right_hand": {"tf": 1}, "lib.polymer.Polymer.__init__": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.__init__": {"tf": 1}}, "df": 3}}}}}, "o": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "l": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}}, "df": 2, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}}, "df": 2}}}}}}, "i": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "d": {"docs": {"lib.water.Water.compute_mobility": {"tf": 1}}, "df": 1}}}}}}}, "i": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "w": {"docs": {"lib.water.Water.__init__": {"tf": 1}}, "df": 1}, "o": {"docs": {"lib.water.Water.__init__": {"tf": 1}}, "df": 1}}}}, "i": {"docs": {}, "df": 0, "s": {"docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}}, "df": 1}, "n": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {"lib.simulation.Simulation.__init__": {"tf": 1}}, "df": 1, "s": {"docs": {"lib.Exceptions.UserInputException.__init__": {"tf": 1}}, "df": 1}}}}, "t": {"docs": {"lib.grid.Grid.__init__": {"tf": 1.4142135623730951}, "lib.grid.FEMesh.__init__": {"tf": 1.4142135623730951}}, "df": 2}, "i": {"docs": {}, "df": 0, "t": {"docs": {"lib.water.Water.__init__": {"tf": 1.7320508075688772}}, "df": 1, "i": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.surfactant.Surfactant.__init__": {"tf": 1}}, "df": 1}}}}}}, "f": {"docs": {}, "df": 0, "t": {"docs": {"lib.surfactant.Surfactant.__init__": {"tf": 1.4142135623730951}}, "df": 1}}}, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}}, "df": 1}}, "f": {"docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}}, "df": 1}, "l": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "c": {"docs": {"lib.water.Water.__init__": {"tf": 1}}, "df": 1}}}}}, "t": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "e": {"docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}}, "df": 1}}, "o": {"docs": {}, "df": 0, "p": {"docs": {"lib.grid.Grid.__init__": {"tf": 1}}, "df": 1}}, "u": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.initialize": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1}}, "df": 2}}}}, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}}, "df": 2}}}}, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "w": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "d": {"docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}}, "df": 1}}}}}}, "q": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "s": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.water.Water.__init__": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}}, "df": 3}}}}}}}, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "e": {"docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}}, "df": 1}}}, "t": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.__init__": {"tf": 1}}, "df": 1}}}, "i": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "t": {"docs": {"lib.grid.Grid.__init__": {"tf": 1}}, "df": 1}}}}, "h": {"docs": {}, "df": 0, "o": {"docs": {"lib.polymer.Polymer.__init__": {"tf": 1}}, "df": 1}}, "e": {"docs": {}, "df": 0, "l": {"docs": {"lib.water.Water.compute_mobility": {"tf": 1}}, "df": 1, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "b": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {"lib.water.Water.compute_mobility": {"tf": 1}}, "df": 1}}}}}}}}}}}}}}}}}}}}}}}}}}}, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {"lib.Exceptions.UserInputException.__init__": {"tf": 1}}, "df": 1}}, "e": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "f": {"docs": {"lib.grid.Grid.set_FD_meshgrid": {"tf": 1}, "lib.grid.Grid.get_flat_index_matrix": {"tf": 1}, "lib.grid.FEMesh.set_triangulation": {"tf": 1}, "lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}, "lib.grid.FEMesh.set_right_hand": {"tf": 1}, "lib.grid.FEMesh.get_A_B_matrices": {"tf": 1}, "lib.polymer.Polymer.initialize": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.polymer.Polymer.divergence": {"tf": 1}, "lib.simulation.Simulation.run": {"tf": 1}, "lib.surfactant.Surfactant.initialize": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 18}}}, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "e": {"docs": {"lib.grid.FEMesh.set_right_hand": {"tf": 1}}, "df": 1}}}}, "r": {"docs": {"lib.water.Water.compute_mobility": {"tf": 1}}, "df": 1}}, "c": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {"lib.polymer.Polymer.__init__": {"tf": 1.4142135623730951}}, "df": 1}}}}}, "h": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {"lib.polymer.Polymer.__init__": {"tf": 1}}, "df": 1}}}, "a": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.initialize": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1}}, "df": 2}}}}, "a": {"docs": {}, "df": 0, "t": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}}, "df": 2, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.water.Water.__init__": {"tf": 1.7320508075688772}, "lib.water.Water.compute_mobility": {"tf": 1}}, "df": 2}}}}}}}}}, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {"lib.water.Water.compute_water_saturation": {"tf": 1.7320508075688772}}, "df": 1, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {"lib.surfactant.Surfactant.__init__": {"tf": 1}}, "df": 1}}}}}}}}}}}}}, "i": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "a": {"docs": {"lib.water.Water.compute_residual_saturations": {"tf": 1}}, "df": 1}}}}, "w": {"docs": {}, "df": 0, "r": {"docs": {"lib.water.Water.compute_mobility": {"tf": 1}}, "df": 1}}}, "d": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {"lib.Exceptions.UserInputException.__init__": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.__init__": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1.4142135623730951}, "lib.water.Water.compute_water_saturation": {"tf": 1.4142135623730951}}, "df": 5}}}, "x": {"docs": {"lib.polymer.Polymer.divergence": {"tf": 1}}, "df": 1}, "y": {"docs": {"lib.polymer.Polymer.divergence": {"tf": 1}}, "df": 1}, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "e": {"docs": {"lib.surfactant.Surfactant.__init__": {"tf": 1}}, "df": 1}}}}}}}}}}, "n": {"docs": {"lib.grid.Grid.__init__": {"tf": 1}, "lib.grid.FEMesh.__init__": {"tf": 1}, "lib.polymer.Polymer.__init__": {"tf": 1}}, "df": 3, "o": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "e": {"docs": {"lib.Exceptions.UserInputException.__init__": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.__init__": {"tf": 2.8284271247461903}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.__init__": {"tf": 2.449489742783178}, "lib.water.Water.compute_viscosity": {"tf": 2}, "lib.water.Water.compute_mobility": {"tf": 1.4142135623730951}}, "df": 6}}}, "u": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "y": {"docs": {"lib.grid.Grid.get_flat_index_matrix": {"tf": 1}, "lib.polymer.Polymer.__init__": {"tf": 2.449489742783178}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1.7320508075688772}, "lib.polymer.Polymer.compute_concentration": {"tf": 2.23606797749979}, "lib.surfactant.Surfactant.__init__": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1.7320508075688772}, "lib.water.Water.__init__": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1.4142135623730951}, "lib.water.Water.compute_residual_saturations": {"tf": 1.7320508075688772}, "lib.water.Water.compute_mobility": {"tf": 1.4142135623730951}, "lib.water.Water.compute_water_saturation": {"tf": 2}}, "df": 11}}}}, "d": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "y": {"docs": {"lib.grid.Grid.get_flat_index_matrix": {"tf": 1}, "lib.polymer.Polymer.__init__": {"tf": 2.449489742783178}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1.7320508075688772}, "lib.polymer.Polymer.compute_concentration": {"tf": 2.23606797749979}, "lib.surfactant.Surfactant.__init__": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1.7320508075688772}, "lib.water.Water.__init__": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1.4142135623730951}, "lib.water.Water.compute_residual_saturations": {"tf": 1.7320508075688772}, "lib.water.Water.compute_mobility": {"tf": 1.4142135623730951}, "lib.water.Water.compute_water_saturation": {"tf": 2}}, "df": 11}}}}}}, "a": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.__init__": {"tf": 1}, "lib.surfactant.Surfactant.__init__": {"tf": 1}}, "df": 2}}}}, "c": {"docs": {"lib.water.Water.compute_mobility": {"tf": 1}}, "df": 1, "l": {"docs": {}, "df": 0, "s": {"docs": {"lib.enumerations.PolymerList.get_by_value": {"tf": 1}, "lib.enumerations.SurfactantList.get_by_value": {"tf": 1}}, "df": 2}}, "o": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "f": {"docs": {"lib.polymer.Polymer.__init__": {"tf": 1.4142135623730951}}, "df": 1}}}, "n": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.polymer.Polymer.__init__": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.__init__": {"tf": 1.4142135623730951}}, "df": 2}}}}}}}}}}, "s": {"docs": {}, "df": 0, "t": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 3}}}}}, "l": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "t": {"docs": {"lib.grid.Grid.__init__": {"tf": 1}}, "df": 1}}}, "i": {"docs": {}, "df": 0, "b": {"docs": {"lib.polymer.Polymer.__init__": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.surfactant.Surfactant.__init__": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1.7320508075688772}, "lib.water.Water.compute_mobility": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1.7320508075688772}}, "df": 8}}}, "f": {"docs": {"lib.surfactant.Surfactant.compute_concentration": {"tf": 1}}, "df": 1, "l": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {"lib.grid.Grid.__init__": {"tf": 2}, "lib.polymer.Polymer.__init__": {"tf": 1.7320508075688772}, "lib.surfactant.Surfactant.__init__": {"tf": 1}, "lib.water.Water.__init__": {"tf": 2.23606797749979}, "lib.water.Water.compute_mobility": {"tf": 1.4142135623730951}}, "df": 5}}}}, "x": {"docs": {"lib.polymer.Polymer.divergence": {"tf": 1}}, "df": 1}, "y": {"docs": {"lib.polymer.Polymer.divergence": {"tf": 1}}, "df": 1}, "u": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.surfactant.Surfactant.__init__": {"tf": 1.4142135623730951}}, "df": 1}}}}}}}, "o": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {"lib.water.Water.compute_mobility": {"tf": 1}}, "df": 1}}}}}}}, "b": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "m": {"docs": {"lib.grid.Grid.__init__": {"tf": 1}}, "df": 1}}}}, "o": {"docs": {}, "df": 0, "l": {"docs": {"lib.water.Water.compute_mobility": {"tf": 1}}, "df": 1}}}, "e": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {"lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}}, "df": 1}}}}, "p": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "d": {"docs": {"lib.grid.FEMesh.set_right_hand": {"tf": 1}}, "df": 1}}}, "o": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.water.Water.compute_viscosity": {"tf": 1.7320508075688772}, "lib.water.Water.compute_water_saturation": {"tf": 1.7320508075688772}}, "df": 2, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {"lib.polymer.Polymer.__init__": {"tf": 1}}, "df": 1}}}}}}}}}}, "h": {"docs": {}, "df": 0, "i": {"docs": {"lib.polymer.Polymer.__init__": {"tf": 1}, "lib.surfactant.Surfactant.__init__": {"tf": 1}, "lib.water.Water.__init__": {"tf": 1}}, "df": 3}}, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "s": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1.4142135623730951}, "lib.water.Water.compute_water_saturation": {"tf": 1.4142135623730951}}, "df": 3}}}}}}}}}, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "b": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {"lib.water.Water.compute_mobility": {"tf": 1}}, "df": 1}}}}}}}}}}}}, "e": {"docs": {"lib.polymer.Polymer.__init__": {"tf": 1}}, "df": 1, "n": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "s": {"docs": {"lib.polymer.Polymer.__init__": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.surfactant.Surfactant.__init__": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}}, "df": 5}}}}}}}}}}}, "q": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.surfactant.Surfactant.__init__": {"tf": 1.4142135623730951}}, "df": 1}}}}}}}}, "g": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "d": {"docs": {"lib.polymer.Polymer.initialize": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1.7320508075688772}, "lib.polymer.Polymer.compute_concentration": {"tf": 1.7320508075688772}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1.7320508075688772}, "lib.water.Water.initialize": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1.7320508075688772}, "lib.water.Water.compute_water_saturation": {"tf": 1.7320508075688772}}, "df": 7}}}, "m": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "d": {"docs": {"lib.surfactant.Surfactant.compute_concentration": {"tf": 1}}, "df": 1}}}}, "u": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 5, "s": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.simulation.Simulation.__init__": {"tf": 1}}, "df": 1}}}}, "w": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water.Water.__init__": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}}, "df": 4}}}}}, "x": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "d": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 2}}}}, "y": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "d": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 2}}}}}}, "bases": {"root": {"docs": {}, "df": 0, "b": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "s": {"docs": {"lib.Exceptions.OutOfRangeError": {"tf": 1}, "lib.Exceptions.SimulationCalcInputException": {"tf": 1}, "lib.Exceptions.UserInputException": {"tf": 1}}, "df": 3}}}}}}}}, "e": {"docs": {}, "df": 0, "x": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.Exceptions.OutOfRangeError": {"tf": 1}, "lib.Exceptions.SimulationCalcInputException": {"tf": 1}, "lib.Exceptions.UserInputException": {"tf": 1}}, "df": 3}}}}}}}}, "n": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "m": {"docs": {"lib.enumerations.SimulationConstants": {"tf": 1.4142135623730951}, "lib.enumerations.PolymerList": {"tf": 1.4142135623730951}, "lib.enumerations.SurfactantList": {"tf": 1.4142135623730951}, "lib.enumerations.ModelType": {"tf": 1.4142135623730951}, "lib.enumerations.PlotType": {"tf": 1.4142135623730951}, "lib.enumerations.ResevoirGeometry": {"tf": 1.4142135623730951}, "lib.enumerations.PermeabilityType": {"tf": 1.4142135623730951}, "lib.enumerations.RelativePermeabilityFormula": {"tf": 1.4142135623730951}}, "df": 8}}}}, "g": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "d": {"docs": {"lib.grid.FEMesh": {"tf": 1}}, "df": 1}}}}}}, "doc": {"root": {"0": {"docs": {"lib.grid.Grid.left": {"tf": 1}, "lib.grid.Grid.bottom": {"tf": 1}, "lib.polymer.Polymer.init_concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.water.Water.init_aqueous_saturation": {"tf": 1}, "lib.water.Water.init_oleic_saturation": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}}, "df": 7}, "1": {"docs": {"lib.grid.Grid.right": {"tf": 1}, "lib.grid.Grid.top": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.polymer.Polymer.divergence": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}}, "df": 5}, "2": {"0": {"1": {"7": {"docs": {"lib.enumerations.SimulationConstants": {"tf": 1}}, "df": 1}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "docs": {"lib.polymer.Polymer.divergence": {"tf": 1}}, "df": 1}, "docs": {"lib": {"tf": 1.7320508075688772}, "lib.name": {"tf": 1.7320508075688772}, "lib.Exceptions": {"tf": 1.7320508075688772}, "lib.Exceptions.OutOfRangeError": {"tf": 1.7320508075688772}, "lib.Exceptions.OutOfRangeError.__init__": {"tf": 3}, "lib.Exceptions.SimulationCalcInputException": {"tf": 1.4142135623730951}, "lib.Exceptions.SimulationCalcInputException.__init__": {"tf": 3.1622776601683795}, "lib.Exceptions.UserInputException": {"tf": 1.7320508075688772}, "lib.Exceptions.UserInputException.__init__": {"tf": 3.4641016151377544}, "lib.enumerations": {"tf": 2.6457513110645907}, "lib.enumerations.SimulationConstants": {"tf": 1.7320508075688772}, "lib.enumerations.SimulationConstants.Water_Viscosity": {"tf": 1.7320508075688772}, "lib.enumerations.SimulationConstants.Water_Density": {"tf": 1.7320508075688772}, "lib.enumerations.SimulationConstants.Oil_Viscosity": {"tf": 1.7320508075688772}, "lib.enumerations.SimulationConstants.Initial_Residual_Water_Saturation": {"tf": 1.7320508075688772}, "lib.enumerations.SimulationConstants.Resid_Aqueous_Phase_Saturation_Initial": {"tf": 1.7320508075688772}, "lib.enumerations.SimulationConstants.Resid_Oleic_Phase_Saturation_Initial": {"tf": 1.7320508075688772}, "lib.enumerations.SimulationConstants.Aqueous_Phase_Critical_Capillary_Num": {"tf": 1.7320508075688772}, "lib.enumerations.SimulationConstants.Oleic_Phase_Critical_Capillary_Num": {"tf": 1.7320508075688772}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_1": {"tf": 1.7320508075688772}, "lib.enumerations.SimulationConstants.Capillary_Pressure_Param_2": {"tf": 1.7320508075688772}, "lib.enumerations.SimulationConstants.Injection_Rate": {"tf": 1.7320508075688772}, "lib.enumerations.SimulationConstants.Time_Step": {"tf": 1.7320508075688772}, "lib.enumerations.SimulationConstants.Grid_Size": {"tf": 1.7320508075688772}, "lib.enumerations.SimulationConstants.Source_Flow_Magnitude": {"tf": 1.7320508075688772}, "lib.enumerations.SimulationConstants.beta1": {"tf": 1.7320508075688772}, "lib.enumerations.PolymerList": {"tf": 1.4142135623730951}, "lib.enumerations.PolymerList.Xanthane": {"tf": 1.7320508075688772}, "lib.enumerations.PolymerList.Schizophyllan": {"tf": 1.7320508075688772}, "lib.enumerations.PolymerList.No_Polymer": {"tf": 1.7320508075688772}, "lib.enumerations.PolymerList.Id": {"tf": 1.7320508075688772}, "lib.enumerations.PolymerList.Density": {"tf": 1.7320508075688772}, "lib.enumerations.PolymerList.n_coeff": {"tf": 1.7320508075688772}, "lib.enumerations.PolymerList.e_coeff": {"tf": 2}, "lib.enumerations.PolymerList.get_by_value": {"tf": 1.4142135623730951}, "lib.enumerations.SurfactantList": {"tf": 2.23606797749979}, "lib.enumerations.SurfactantList.Alkyl_Ether_Sulfate": {"tf": 1.7320508075688772}, "lib.enumerations.SurfactantList.No_Surfactant": {"tf": 1.7320508075688772}, "lib.enumerations.SurfactantList.Id": {"tf": 1.7320508075688772}, "lib.enumerations.SurfactantList.IFT_equation": {"tf": 1.7320508075688772}, "lib.enumerations.SurfactantList.derivative_IFT_equation": {"tf": 1.7320508075688772}, "lib.enumerations.SurfactantList.get_by_value": {"tf": 1.4142135623730951}, "lib.enumerations.ModelType": {"tf": 1.4142135623730951}, "lib.enumerations.ModelType.No_Shear_Thinning": {"tf": 1.7320508075688772}, "lib.enumerations.ModelType.Sourav_Implementation": {"tf": 1.7320508075688772}, "lib.enumerations.ModelType.Shear_Thinning_On": {"tf": 1.7320508075688772}, "lib.enumerations.PlotType": {"tf": 1.4142135623730951}, "lib.enumerations.PlotType.Saturation_Plot": {"tf": 1.7320508075688772}, "lib.enumerations.PlotType.Polymer_Concentration_Plot": {"tf": 1.7320508075688772}, "lib.enumerations.PlotType.Surfactant_Concentration_Plot": {"tf": 1.7320508075688772}, "lib.enumerations.ResevoirGeometry": {"tf": 1.4142135623730951}, "lib.enumerations.ResevoirGeometry.Rectilinear": {"tf": 1.7320508075688772}, "lib.enumerations.ResevoirGeometry.Quarter_Five_Spot": {"tf": 1.7320508075688772}, "lib.enumerations.PermeabilityType": {"tf": 1.4142135623730951}, "lib.enumerations.PermeabilityType.Homogenous": {"tf": 1.7320508075688772}, "lib.enumerations.PermeabilityType.Heterogenous": {"tf": 1.7320508075688772}, "lib.enumerations.RelativePermeabilityFormula": {"tf": 1.7320508075688772}, "lib.enumerations.RelativePermeabilityFormula.AmaefuleHandEquation": {"tf": 1.7320508075688772}, "lib.enumerations.RelativePermeabilityFormula.CoreyTypeEquation": {"tf": 1.7320508075688772}, "lib.grid": {"tf": 2.6457513110645907}, "lib.grid.Grid": {"tf": 2.23606797749979}, "lib.grid.Grid.__init__": {"tf": 1.7320508075688772}, "lib.grid.Grid.m": {"tf": 1.4142135623730951}, "lib.grid.Grid.n": {"tf": 1.4142135623730951}, "lib.grid.Grid.left": {"tf": 2}, "lib.grid.Grid.right": {"tf": 2.23606797749979}, "lib.grid.Grid.bottom": {"tf": 2.23606797749979}, "lib.grid.Grid.top": {"tf": 2.23606797749979}, "lib.grid.Grid.A": {"tf": 1.4142135623730951}, "lib.grid.Grid.B": {"tf": 1.4142135623730951}, "lib.grid.Grid.get_spacing": {"tf": 1.4142135623730951}, "lib.grid.Grid.get_meshgrid": {"tf": 1.4142135623730951}, "lib.grid.Grid.dx": {"tf": 2}, "lib.grid.Grid.dy": {"tf": 2}, "lib.grid.Grid.set_FD_meshgrid": {"tf": 2.23606797749979}, "lib.grid.Grid.get_flat_index_matrix": {"tf": 1.7320508075688772}, "lib.grid.FEMesh": {"tf": 2.23606797749979}, "lib.grid.FEMesh.__init__": {"tf": 3.3166247903554}, "lib.grid.FEMesh.U": {"tf": 1.4142135623730951}, "lib.grid.FEMesh.L": {"tf": 1.4142135623730951}, "lib.grid.FEMesh.grid_size": {"tf": 2.23606797749979}, "lib.grid.FEMesh.right_hand": {"tf": 1.7320508075688772}, "lib.grid.FEMesh.A": {"tf": 1.4142135623730951}, "lib.grid.FEMesh.B": {"tf": 1.4142135623730951}, "lib.grid.FEMesh.sparsed_A": {"tf": 2}, "lib.grid.FEMesh.set_triangulation": {"tf": 2.23606797749979}, "lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1.4142135623730951}, "lib.grid.FEMesh.set_right_hand": {"tf": 1.4142135623730951}, "lib.grid.FEMesh.get_A_B_matrices": {"tf": 1.7320508075688772}, "lib.polymer": {"tf": 2.6457513110645907}, "lib.polymer.Polymer": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.__init__": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.name": {"tf": 1.7320508075688772}, "lib.polymer.Polymer.concetration_scalar": {"tf": 2}, "lib.polymer.Polymer.init_concentration_matrix": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.concentration_matrix": {"tf": 1.7320508075688772}, "lib.polymer.Polymer.viscosity_matrix": {"tf": 1.7320508075688772}, "lib.polymer.Polymer.viscosity_scalar": {"tf": 1.7320508075688772}, "lib.polymer.Polymer.e_coeff": {"tf": 1.7320508075688772}, "lib.polymer.Polymer.n_coeff": {"tf": 1.7320508075688772}, "lib.polymer.Polymer.rho": {"tf": 1.7320508075688772}, "lib.polymer.Polymer.shear_rate": {"tf": 2}, "lib.polymer.Polymer.phi": {"tf": 2}, "lib.polymer.Polymer.initialize": {"tf": 4.242640687119285}, "lib.polymer.Polymer.compute_viscosity": {"tf": 4.898979485566356}, "lib.polymer.Polymer.compute_concentration": {"tf": 5.656854249492381}, "lib.polymer.Polymer.divergence": {"tf": 4.69041575982343}, "lib.simulation": {"tf": 2.6457513110645907}, "lib.simulation.Simulation": {"tf": 1.7320508075688772}, "lib.simulation.Simulation.__init__": {"tf": 4.358898943540674}, "lib.simulation.Simulation.grid_size": {"tf": 1.7320508075688772}, "lib.simulation.Simulation.source_flow_magnitude": {"tf": 1.7320508075688772}, "lib.simulation.Simulation.permeability_flag": {"tf": 2.23606797749979}, "lib.simulation.Simulation.reservoir_geometry": {"tf": 2.23606797749979}, "lib.simulation.Simulation.model_type": {"tf": 2.23606797749979}, "lib.simulation.Simulation.relative_permeability_formula": {"tf": 2.23606797749979}, "lib.simulation.Simulation.phi": {"tf": 1.7320508075688772}, "lib.simulation.Simulation.KK": {"tf": 1.7320508075688772}, "lib.simulation.Simulation.time_step": {"tf": 1.7320508075688772}, "lib.simulation.Simulation.polymer": {"tf": 2.23606797749979}, "lib.simulation.Simulation.surfactant": {"tf": 2.23606797749979}, "lib.simulation.Simulation.water": {"tf": 2.23606797749979}, "lib.simulation.Simulation.COC": {"tf": 1.7320508075688772}, "lib.simulation.Simulation.miuaTcal": {"tf": 1.7320508075688772}, "lib.simulation.Simulation.lambdaTcal": {"tf": 2.8284271247461903}, "lib.simulation.Simulation.MFW": {"tf": 2}, "lib.simulation.Simulation.integrated_inlet_flow": {"tf": 1.7320508075688772}, "lib.simulation.Simulation.source_prod_flow": {"tf": 2.449489742783178}, "lib.simulation.Simulation.scenario_flag": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.run": {"tf": 3.1622776601683795}, "lib.surfactant": {"tf": 2.6457513110645907}, "lib.surfactant.Surfactant": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.__init__": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.name": {"tf": 1.7320508075688772}, "lib.surfactant.Surfactant.concentration": {"tf": 2}, "lib.surfactant.Surfactant.concentration_matrix": {"tf": 1.7320508075688772}, "lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1.7320508075688772}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1.7320508075688772}, "lib.surfactant.Surfactant.is_surfactant": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.phi": {"tf": 2}, "lib.surfactant.Surfactant.eval_IFT": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.eval_dIFT_dGamma": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.initialize": {"tf": 2}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 4.58257569495584}, "lib.test": {"tf": 1.7320508075688772}, "lib.water": {"tf": 2.6457513110645907}, "lib.water.Water": {"tf": 1.4142135623730951}, "lib.water.Water.__init__": {"tf": 2}, "lib.water.Water.init_water_saturation": {"tf": 1.7320508075688772}, "lib.water.Water.init_aqueous_saturation": {"tf": 2.23606797749979}, "lib.water.Water.init_oleic_saturation": {"tf": 2.23606797749979}, "lib.water.Water.miuw": {"tf": 1.7320508075688772}, "lib.water.Water.miuo": {"tf": 1.7320508075688772}, "lib.water.Water.water_saturation": {"tf": 1.7320508075688772}, "lib.water.Water.viscosity_array": {"tf": 1.7320508075688772}, "lib.water.Water.phi": {"tf": 1.7320508075688772}, "lib.water.Water.initialize": {"tf": 5}, "lib.water.Water.compute_viscosity": {"tf": 5.477225575051661}, "lib.water.Water.compute_residual_saturations": {"tf": 4.58257569495584}, "lib.water.Water.compute_mobility": {"tf": 5.5677643628300215}, "lib.water.Water.compute_water_saturation": {"tf": 5.830951894845301}}, "df": 161, "e": {"docs": {"lib.enumerations.PolymerList.e_coeff": {"tf": 1}, "lib.polymer.Polymer.e_coeff": {"tf": 1}}, "df": 2, "x": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.Exceptions.OutOfRangeError": {"tf": 1}, "lib.Exceptions.SimulationCalcInputException": {"tf": 1}, "lib.Exceptions.SimulationCalcInputException.__init__": {"tf": 1}, "lib.Exceptions.UserInputException": {"tf": 1}, "lib.Exceptions.UserInputException.__init__": {"tf": 1}}, "df": 5}}}}}}}, "p": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.polymer.Polymer.e_coeff": {"tf": 1}, "lib.polymer.Polymer.n_coeff": {"tf": 1}, "lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}}, "df": 3}}}}}}}}, "e": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.simulation.Simulation.__init__": {"tf": 1}, "lib.simulation.Simulation.run": {"tf": 1}}, "df": 2}}}, "e": {"docs": {}, "df": 0, "s": {"docs": {"lib.simulation.Simulation.run": {"tf": 1}}, "df": 1}}}}}}}, "r": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "r": {"docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}, "lib.Exceptions.SimulationCalcInputException.__init__": {"tf": 1}, "lib.Exceptions.UserInputException.__init__": {"tf": 1}}, "df": 3, "s": {"docs": {"lib.Exceptions.OutOfRangeError": {"tf": 1}}, "df": 1}}}}}, "n": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "m": {"docs": {"lib.polymer.Polymer.name": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.simulation.Simulation.permeability_flag": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.reservoir_geometry": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.model_type": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.relative_permeability_formula": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.name": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1.4142135623730951}}, "df": 9, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.PolymerList.get_by_value": {"tf": 1}, "lib.enumerations.SurfactantList.get_by_value": {"tf": 1}}, "df": 2, "s": {"docs": {"lib.enumerations": {"tf": 1}}, "df": 1}}}}}}}}}}, "c": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {"lib.grid.Grid": {"tf": 1}, "lib.grid.FEMesh": {"tf": 1}}, "df": 2}}}}}}}}}}}, "m": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.enumerations.PolymerList.n_coeff": {"tf": 1}, "lib.enumerations.PolymerList.e_coeff": {"tf": 1}, "lib.polymer.Polymer.e_coeff": {"tf": 1}, "lib.polymer.Polymer.n_coeff": {"tf": 1}}, "df": 4}}}}}}}}, "q": {"docs": {}, "df": 0, "u": {"docs": {"lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1}}, "df": 2, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.PolymerList.n_coeff": {"tf": 1}, "lib.enumerations.PolymerList.e_coeff": {"tf": 1}, "lib.enumerations.SurfactantList.IFT_equation": {"tf": 1}, "lib.enumerations.SurfactantList.derivative_IFT_equation": {"tf": 1.4142135623730951}, "lib.grid.FEMesh.set_right_hand": {"tf": 1}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 7, "s": {"docs": {"lib.grid.Grid.set_FD_meshgrid": {"tf": 1}, "lib.grid.FEMesh.right_hand": {"tf": 1}, "lib.water.Water.water_saturation": {"tf": 1}}, "df": 3}}}}}, "l": {"docs": {"lib.polymer.Polymer.concetration_scalar": {"tf": 1}}, "df": 1}}}}, "a": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "h": {"docs": {"lib.enumerations.PermeabilityType": {"tf": 1}, "lib.grid.Grid.get_flat_index_matrix": {"tf": 1}, "lib.grid.FEMesh.U": {"tf": 1}, "lib.grid.FEMesh.L": {"tf": 1}}, "df": 4}}}, "l": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {"lib.grid.FEMesh.U": {"tf": 1}, "lib.grid.FEMesh.L": {"tf": 1}}, "df": 2}}}}}, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "c": {"docs": {"lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}}, "df": 1}}}}}}}, "v": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "y": {"docs": {"lib.grid.FEMesh.set_triangulation": {"tf": 1}}, "df": 1}}}, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {"lib.surfactant.Surfactant.eval_IFT": {"tf": 1}, "lib.surfactant.Surfactant.eval_dIFT_dGamma": {"tf": 1}}, "df": 2}}}}}}}, "p": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.polymer.Polymer.e_coeff": {"tf": 1}, "lib.polymer.Polymer.n_coeff": {"tf": 1}}, "df": 2}}}}}}, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.water.Water.initialize": {"tf": 1}}, "df": 1}}}}}}, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "e": {"docs": {"lib.water.Water.compute_mobility": {"tf": 1}}, "df": 1, "d": {"docs": {"lib.Exceptions.OutOfRangeError": {"tf": 1}, "lib.Exceptions.UserInputException": {"tf": 1}}, "df": 2}, "s": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.polymer.Polymer.divergence": {"tf": 1}, "lib.simulation.Simulation.__init__": {"tf": 1}, "lib.simulation.Simulation.run": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 8}}}}, "n": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "e": {"docs": {"lib.Exceptions.OutOfRangeError": {"tf": 1}}, "df": 1}}}, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "h": {"docs": {"lib.enumerations": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}}, "df": 6}}}}, "t": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.shear_rate": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.initialize": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.simulation.Simulation.source_flow_magnitude": {"tf": 1}, "lib.simulation.Simulation.integrated_inlet_flow": {"tf": 1}}, "df": 5, "s": {"docs": {"lib.simulation.Simulation.source_prod_flow": {"tf": 1}}, "df": 1}}}}, "e": {"docs": {}, "df": 0, "q": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "d": {"docs": {"lib.Exceptions.SimulationCalcInputException": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}}, "df": 5}}}}}}, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {"lib.enumerations.PolymerList.get_by_value": {"tf": 1}, "lib.enumerations.SurfactantList.get_by_value": {"tf": 1}}, "df": 2}}}}}}, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "s": {"docs": {"lib.grid.Grid.set_FD_meshgrid": {"tf": 1}, "lib.grid.Grid.get_flat_index_matrix": {"tf": 1}, "lib.polymer.Polymer.initialize": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.simulation.Simulation.scenario_flag": {"tf": 1}, "lib.surfactant.Surfactant.initialize": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1.4142135623730951}, "lib.water.Water.initialize": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 13}}}}}, "l": {"docs": {"lib.water.Water.compute_mobility": {"tf": 1}}, "df": 1, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "p": {"docs": {"lib.enumerations.SurfactantList.IFT_equation": {"tf": 1}}, "df": 1}}}}}}, "v": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.RelativePermeabilityFormula": {"tf": 1}, "lib.simulation.Simulation.relative_permeability_formula": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}}, "df": 3, "p": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "b": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {"lib.simulation.Simulation.relative_permeability_formula": {"tf": 1.4142135623730951}, "lib.water.Water.compute_mobility": {"tf": 1.4142135623730951}}, "df": 2}}}}}}}}}}}}}}}}}}}}}, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1}}, "df": 1}}}, "e": {"docs": {}, "df": 0, "d": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.compute_concentration": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant": {"tf": 1}}, "df": 3}, "s": {"docs": {"lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}}, "df": 1}}}}}, "s": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations.ResevoirGeometry": {"tf": 1}, "lib.polymer.Polymer.init_concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.phi": {"tf": 1}, "lib.surfactant.Surfactant.concentration_matrix": {"tf": 1}, "lib.surfactant.Surfactant.phi": {"tf": 1}}, "df": 6, "g": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "y": {"docs": {"lib.simulation.Simulation.reservoir_geometry": {"tf": 1.4142135623730951}}, "df": 1}}}}}}}}}}}}, "r": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "r": {"docs": {"lib.simulation.Simulation.reservoir_geometry": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.scenario_flag": {"tf": 1}}, "df": 2}}}}}}, "i": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.water.Water.init_water_saturation": {"tf": 1}, "lib.water.Water.init_aqueous_saturation": {"tf": 1}, "lib.water.Water.init_oleic_saturation": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1.4142135623730951}}, "df": 5}}}}}}, "f": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "r": {"docs": {"lib.grid.Grid": {"tf": 1}, "lib.grid.FEMesh": {"tf": 1}}, "df": 2}}}}}}, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {"lib.grid.FEMesh.U": {"tf": 1}, "lib.grid.FEMesh.L": {"tf": 1}}, "df": 2}}}}, "l": {"docs": {}, "df": 0, "e": {"docs": {"lib.grid.FEMesh.set_triangulation": {"tf": 1}}, "df": 1}}}}}}}, "p": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.grid.FEMesh.right_hand": {"tf": 1}, "lib.polymer.Polymer.init_concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.concentration_matrix": {"tf": 1}, "lib.surfactant.Surfactant.concentration_matrix": {"tf": 1}}, "df": 4}}}}}, "s": {"docs": {"lib.polymer.Polymer.phi": {"tf": 1}, "lib.simulation.Simulation.scenario_flag": {"tf": 1}, "lib.surfactant.Surfactant.phi": {"tf": 1}}, "df": 3}}}}}}}}, "d": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "d": {"docs": {"lib.surfactant.Surfactant.compute_concentration": {"tf": 1}}, "df": 1}}}}}}}}, "u": {"docs": {}, "df": 0, "n": {"docs": {"lib.simulation.Simulation": {"tf": 1}, "lib.simulation.Simulation.model_type": {"tf": 1}, "lib.simulation.Simulation.scenario_flag": {"tf": 1}}, "df": 3, "s": {"docs": {"lib.enumerations": {"tf": 1}, "lib.enumerations.PolymerList": {"tf": 1}, "lib.enumerations.SurfactantList": {"tf": 1}, "lib.enumerations.PermeabilityType": {"tf": 1}}, "df": 4}, "n": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.grid": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}}, "df": 3}}}}, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {"lib.simulation.Simulation.__init__": {"tf": 1}, "lib.simulation.Simulation.run": {"tf": 1}}, "df": 2}}}}}}, "o": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}}, "df": 6}}}, "w": {"docs": {"lib.grid.FEMesh.grid_size": {"tf": 1}}, "df": 1, "s": {"docs": {"lib.grid.Grid.n": {"tf": 1}, "lib.grid.FEMesh.__init__": {"tf": 1}, "lib.grid.FEMesh.grid_size": {"tf": 1}}, "df": 3}}}, "i": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "t": {"docs": {"lib.grid.Grid.right": {"tf": 1}, "lib.grid.FEMesh.set_right_hand": {"tf": 1}}, "df": 2}}}}, "h": {"docs": {}, "df": 0, "s": {"docs": {"lib.grid.FEMesh.right_hand": {"tf": 1}}, "df": 1}, "o": {"docs": {"lib.polymer.Polymer.rho": {"tf": 1}}, "df": 1}}}, "f": {"docs": {"lib.polymer.Polymer.divergence": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}}, "df": 2, "o": {"docs": {}, "df": 0, "r": {"docs": {"lib.Exceptions.OutOfRangeError": {"tf": 1}, "lib.Exceptions.SimulationCalcInputException": {"tf": 1}, "lib.Exceptions.UserInputException": {"tf": 1}, "lib.enumerations": {"tf": 1}, "lib.enumerations.PolymerList": {"tf": 1}, "lib.enumerations.PolymerList.Id": {"tf": 1}, "lib.enumerations.PolymerList.n_coeff": {"tf": 1}, "lib.enumerations.PolymerList.e_coeff": {"tf": 1}, "lib.enumerations.SurfactantList": {"tf": 1}, "lib.enumerations.SurfactantList.Id": {"tf": 1}, "lib.enumerations.PlotType": {"tf": 1}, "lib.enumerations.ResevoirGeometry": {"tf": 1}, "lib.enumerations.PermeabilityType": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.grid.Grid.A": {"tf": 1}, "lib.grid.Grid.B": {"tf": 1}, "lib.grid.Grid.get_meshgrid": {"tf": 1}, "lib.grid.Grid.set_FD_meshgrid": {"tf": 1.4142135623730951}, "lib.grid.FEMesh.__init__": {"tf": 1}, "lib.grid.FEMesh.right_hand": {"tf": 1}, "lib.grid.FEMesh.A": {"tf": 1}, "lib.grid.FEMesh.B": {"tf": 1}, "lib.grid.FEMesh.set_triangulation": {"tf": 1}, "lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}, "lib.polymer": {"tf": 1.4142135623730951}, "lib.polymer.Polymer": {"tf": 1}, "lib.polymer.Polymer.e_coeff": {"tf": 1}, "lib.polymer.Polymer.n_coeff": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.surfactant": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.is_surfactant": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water": {"tf": 1}, "lib.water.Water": {"tf": 1}, "lib.water.Water.__init__": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1.4142135623730951}, "lib.water.Water.compute_water_saturation": {"tf": 1.7320508075688772}}, "df": 42, "m": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {"lib.enumerations.RelativePermeabilityFormula": {"tf": 1}}, "df": 1}}}, "l": {"docs": {}, "df": 0, "a": {"docs": {"lib.simulation.Simulation.relative_permeability_formula": {"tf": 1.4142135623730951}, "lib.water.Water.compute_mobility": {"tf": 1.4142135623730951}}, "df": 2, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.water.Water.compute_water_saturation": {"tf": 1.4142135623730951}}, "df": 1}}}}}}}}}}, "l": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}, "lib.enumerations.PolymerList.Density": {"tf": 1}, "lib.polymer.Polymer.concetration_scalar": {"tf": 1}, "lib.polymer.Polymer.viscosity_scalar": {"tf": 1}, "lib.polymer.Polymer.rho": {"tf": 1}, "lib.polymer.Polymer.divergence": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.grid_size": {"tf": 1}, "lib.simulation.Simulation.source_flow_magnitude": {"tf": 1}, "lib.simulation.Simulation.time_step": {"tf": 1}, "lib.simulation.Simulation.integrated_inlet_flow": {"tf": 1}, "lib.surfactant.Surfactant.concentration": {"tf": 1}, "lib.water.Water.init_water_saturation": {"tf": 1}, "lib.water.Water.init_aqueous_saturation": {"tf": 1}, "lib.water.Water.init_oleic_saturation": {"tf": 1}, "lib.water.Water.miuw": {"tf": 1}, "lib.water.Water.miuo": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1.7320508075688772}}, "df": 17}}, "o": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.enumerations": {"tf": 1}, "lib.enumerations.SimulationConstants": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.grid.Grid.set_FD_meshgrid": {"tf": 1}, "lib.polymer": {"tf": 1.4142135623730951}, "lib.simulation": {"tf": 1}, "lib.simulation.Simulation": {"tf": 1}, "lib.surfactant": {"tf": 1.4142135623730951}, "lib.water": {"tf": 1.4142135623730951}, "lib.water.Water": {"tf": 1}}, "df": 10}}}}}, "w": {"docs": {"lib.polymer.Polymer.shear_rate": {"tf": 1}, "lib.simulation.Simulation.source_flow_magnitude": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.integrated_inlet_flow": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.source_prod_flow": {"tf": 2.23606797749979}}, "df": 4}}, "a": {"docs": {}, "df": 0, "t": {"docs": {"lib.grid.Grid.get_flat_index_matrix": {"tf": 1}}, "df": 1}, "g": {"docs": {"lib.simulation.Simulation.permeability_flag": {"tf": 1}, "lib.surfactant.Surfactant.is_surfactant": {"tf": 1}}, "df": 2}}}, "r": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "m": {"docs": {"lib.Exceptions.UserInputException": {"tf": 1}, "lib.enumerations": {"tf": 1}, "lib.enumerations.SimulationConstants": {"tf": 1}, "lib.enumerations.PolymerList.get_by_value": {"tf": 1}, "lib.enumerations.SurfactantList.get_by_value": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.grid.FEMesh.set_triangulation": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1.7320508075688772}, "lib.simulation": {"tf": 1}, "lib.simulation.Simulation.__init__": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 17}}}, "i": {"docs": {}, "df": 0, "x": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SurfactantList": {"tf": 1}, "lib.grid.Grid": {"tf": 1}, "lib.grid.FEMesh": {"tf": 1}}, "df": 3}}}, "l": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 4}}, "e": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "d": {"docs": {"lib.simulation.Simulation.permeability_flag": {"tf": 1}}, "df": 1}}}, "n": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.simulation.Simulation.MFW": {"tf": 1}}, "df": 1}}}}}, "e": {"docs": {"lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}}, "df": 1, "m": {"docs": {"lib.grid.Grid": {"tf": 1}, "lib.grid.FEMesh": {"tf": 1}, "lib.grid.FEMesh.set_triangulation": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}}, "df": 4, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "h": {"docs": {"lib.grid.FEMesh.__init__": {"tf": 1}}, "df": 1}}}}}, "d": {"docs": {"lib.grid.Grid.get_meshgrid": {"tf": 1}, "lib.grid.Grid.set_FD_meshgrid": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}}, "df": 3, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "h": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1}}, "df": 1}}}}}, "u": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.polymer.Polymer.divergence": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.initialize": {"tf": 1}}, "df": 4}}}}}}}, "x": {"docs": {"lib.polymer.Polymer.divergence": {"tf": 1}}, "df": 1, "/": {"docs": {}, "df": 0, "\u03b4": {"docs": {}, "df": 0, "x": {"docs": {"lib.polymer.Polymer.divergence": {"tf": 1}}, "df": 1}}}}, "y": {"docs": {"lib.polymer.Polymer.divergence": {"tf": 1}}, "df": 1, "/": {"docs": {}, "df": 0, "\u03b4": {"docs": {}, "df": 0, "y": {"docs": {"lib.polymer.Polymer.divergence": {"tf": 1}}, "df": 1}}}}}, "i": {"docs": {"lib.grid.FEMesh.set_triangulation": {"tf": 1.4142135623730951}}, "df": 1, "n": {"docs": {"lib.Exceptions.OutOfRangeError": {"tf": 1}, "lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}, "lib.Exceptions.SimulationCalcInputException.__init__": {"tf": 1}, "lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}, "lib.polymer.Polymer.shear_rate": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.polymer.Polymer.divergence": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.__init__": {"tf": 1}, "lib.simulation.Simulation.relative_permeability_formula": {"tf": 1}, "lib.simulation.Simulation.miuaTcal": {"tf": 1}, "lib.simulation.Simulation.lambdaTcal": {"tf": 1}, "lib.simulation.Simulation.MFW": {"tf": 1}, "lib.surfactant.Surfactant.concentration_matrix": {"tf": 1}, "lib.surfactant.Surfactant.is_surfactant": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1.7320508075688772}, "lib.water": {"tf": 1}, "lib.water.Water": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 20, "p": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {"lib.Exceptions.OutOfRangeError": {"tf": 1}, "lib.Exceptions.UserInputException.__init__": {"tf": 1}, "lib.simulation.Simulation.__init__": {"tf": 1.7320508075688772}}, "df": 3, "s": {"docs": {"lib.Exceptions.SimulationCalcInputException": {"tf": 1}, "lib.Exceptions.UserInputException": {"tf": 1}, "lib.Exceptions.UserInputException.__init__": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.__init__": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}}, "df": 5}}}}, "v": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "d": {"docs": {"lib.Exceptions.UserInputException": {"tf": 1}}, "df": 1}}}}}, "i": {"docs": {}, "df": 0, "t": {"docs": {"lib.water.Water.init_water_saturation": {"tf": 1}, "lib.water.Water.init_aqueous_saturation": {"tf": 1}, "lib.water.Water.init_oleic_saturation": {"tf": 1}}, "df": 3, "i": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.polymer.Polymer.concetration_scalar": {"tf": 1}, "lib.polymer.Polymer.init_concentration_matrix": {"tf": 1}, "lib.surfactant.Surfactant.concentration": {"tf": 1}, "lib.water.Water.init_water_saturation": {"tf": 1}, "lib.water.Water.init_aqueous_saturation": {"tf": 1}, "lib.water.Water.init_oleic_saturation": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}}, "df": 7, "i": {"docs": {}, "df": 0, "z": {"docs": {}, "df": 0, "e": {"docs": {"lib.Exceptions.UserInputException.__init__": {"tf": 1}, "lib.polymer.Polymer.phi": {"tf": 1}, "lib.polymer.Polymer.initialize": {"tf": 1}, "lib.simulation.Simulation.__init__": {"tf": 1}, "lib.surfactant.Surfactant.phi": {"tf": 1}, "lib.surfactant.Surfactant.initialize": {"tf": 1}}, "df": 6, "s": {"docs": {"lib.polymer.Polymer.__init__": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1}}, "df": 2}}, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.polymer.Polymer.concetration_scalar": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1.4142135623730951}}, "df": 2}}}}}}}}, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "z": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "d": {"docs": {"lib.polymer.Polymer.initialize": {"tf": 1}}, "df": 1}}}}}}}}, "t": {"docs": {"lib.enumerations.PolymerList.Id": {"tf": 1}, "lib.enumerations.SurfactantList.Id": {"tf": 1}, "lib.grid.FEMesh.__init__": {"tf": 1.4142135623730951}}, "df": 3, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.enumerations.SurfactantList.IFT_equation": {"tf": 1}, "lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}}, "df": 3}}}}}}, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {"lib.surfactant.Surfactant.compute_concentration": {"tf": 1}}, "df": 1}}}}}}}, "p": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {"lib.surfactant.Surfactant.compute_concentration": {"tf": 1}}, "df": 1}}}}}}}, "g": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "d": {"docs": {"lib.simulation.Simulation.integrated_inlet_flow": {"tf": 1}}, "df": 1}}, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.simulation.Simulation.integrated_inlet_flow": {"tf": 1}}, "df": 1}}}}}}, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.simulation.Simulation.scenario_flag": {"tf": 1}}, "df": 1}}}}, "i": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.water.Water.initialize": {"tf": 1}}, "df": 1}}}}, "d": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "x": {"docs": {"lib.enumerations.PolymerList.Id": {"tf": 1}, "lib.enumerations.SurfactantList.Id": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1.4142135623730951}, "lib.water.Water.compute_residual_saturations": {"tf": 1.4142135623730951}}, "df": 4}}, "i": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {"lib.grid.Grid.get_flat_index_matrix": {"tf": 1}}, "df": 1}}}}}, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.__init__": {"tf": 1}, "lib.surfactant.Surfactant.__init__": {"tf": 1}}, "df": 2}}}}}}, "c": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}}, "df": 1}}}}}, "f": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.simulation.Simulation.__init__": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}}, "df": 2}}}}}}}}}, "j": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.simulation.Simulation.source_flow_magnitude": {"tf": 1}}, "df": 1}}}}}}}, "l": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "t": {"docs": {"lib.simulation.Simulation.integrated_inlet_flow": {"tf": 1}}, "df": 1}}}}, "f": {"docs": {"lib.Exceptions.OutOfRangeError": {"tf": 1}, "lib.simulation.Simulation.__init__": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.run": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 4, "t": {"docs": {"lib.enumerations.SurfactantList.IFT_equation": {"tf": 1}, "lib.enumerations.SurfactantList.derivative_IFT_equation": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.eval_IFT": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}}, "df": 6}}, "t": {"docs": {"lib.Exceptions.OutOfRangeError": {"tf": 1}, "lib.grid.Grid": {"tf": 1}, "lib.grid.FEMesh": {"tf": 1}}, "df": 3}, "s": {"docs": {"lib.Exceptions.OutOfRangeError": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.simulation.Simulation.__init__": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.run": {"tf": 1}, "lib.surfactant.Surfactant.is_surfactant": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1.4142135623730951}}, "df": 6, "s": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "e": {"docs": {"lib.simulation.Simulation.__init__": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.run": {"tf": 1}}, "df": 2}}}}, "d": {"docs": {"lib.enumerations.PolymerList.Id": {"tf": 1}, "lib.enumerations.SurfactantList.Id": {"tf": 1}}, "df": 2}, "m": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.enumerations.SurfactantList": {"tf": 1}}, "df": 1}}}}}}}}}}}}, "t": {"docs": {"lib.polymer.Polymer.init_concentration_matrix": {"tf": 1}, "lib.simulation.Simulation.time_step": {"tf": 1}, "lib.simulation.Simulation.lambdaTcal": {"tf": 1}}, "df": 3, "h": {"docs": {}, "df": 0, "e": {"docs": {"lib.Exceptions.OutOfRangeError": {"tf": 1}, "lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}, "lib.Exceptions.SimulationCalcInputException": {"tf": 1}, "lib.Exceptions.SimulationCalcInputException.__init__": {"tf": 1}, "lib.Exceptions.UserInputException": {"tf": 1}, "lib.Exceptions.UserInputException.__init__": {"tf": 1.4142135623730951}, "lib.enumerations": {"tf": 2.23606797749979}, "lib.enumerations.PolymerList": {"tf": 1}, "lib.enumerations.PolymerList.Density": {"tf": 1}, "lib.enumerations.PolymerList.n_coeff": {"tf": 1}, "lib.enumerations.PolymerList.e_coeff": {"tf": 1}, "lib.enumerations.SurfactantList": {"tf": 1}, "lib.enumerations.SurfactantList.IFT_equation": {"tf": 1}, "lib.enumerations.SurfactantList.derivative_IFT_equation": {"tf": 1.4142135623730951}, "lib.enumerations.ModelType": {"tf": 1}, "lib.enumerations.PlotType": {"tf": 1}, "lib.enumerations.ResevoirGeometry": {"tf": 1.7320508075688772}, "lib.enumerations.PermeabilityType": {"tf": 1.4142135623730951}, "lib.enumerations.RelativePermeabilityFormula": {"tf": 1}, "lib.grid": {"tf": 1.4142135623730951}, "lib.grid.Grid.m": {"tf": 1}, "lib.grid.Grid.n": {"tf": 1}, "lib.grid.Grid.get_meshgrid": {"tf": 1.4142135623730951}, "lib.grid.Grid.set_FD_meshgrid": {"tf": 1}, "lib.grid.FEMesh.__init__": {"tf": 1.4142135623730951}, "lib.grid.FEMesh.U": {"tf": 1}, "lib.grid.FEMesh.L": {"tf": 1}, "lib.grid.FEMesh.right_hand": {"tf": 1.7320508075688772}, "lib.grid.FEMesh.set_triangulation": {"tf": 2}, "lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1.4142135623730951}, "lib.grid.FEMesh.set_right_hand": {"tf": 1.7320508075688772}, "lib.polymer": {"tf": 2}, "lib.polymer.Polymer": {"tf": 1}, "lib.polymer.Polymer.__init__": {"tf": 1}, "lib.polymer.Polymer.name": {"tf": 1}, "lib.polymer.Polymer.concetration_scalar": {"tf": 1}, "lib.polymer.Polymer.viscosity_matrix": {"tf": 1}, "lib.polymer.Polymer.viscosity_scalar": {"tf": 1}, "lib.polymer.Polymer.e_coeff": {"tf": 2}, "lib.polymer.Polymer.n_coeff": {"tf": 2}, "lib.polymer.Polymer.shear_rate": {"tf": 1.7320508075688772}, "lib.polymer.Polymer.phi": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.initialize": {"tf": 1.7320508075688772}, "lib.polymer.Polymer.compute_viscosity": {"tf": 3.1622776601683795}, "lib.polymer.Polymer.compute_concentration": {"tf": 2.449489742783178}, "lib.polymer.Polymer.divergence": {"tf": 1.4142135623730951}, "lib.simulation": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.__init__": {"tf": 2.449489742783178}, "lib.simulation.Simulation.grid_size": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.permeability_flag": {"tf": 1}, "lib.simulation.Simulation.reservoir_geometry": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.model_type": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.relative_permeability_formula": {"tf": 1.7320508075688772}, "lib.simulation.Simulation.KK": {"tf": 1}, "lib.simulation.Simulation.time_step": {"tf": 1}, "lib.simulation.Simulation.polymer": {"tf": 1}, "lib.simulation.Simulation.surfactant": {"tf": 1}, "lib.simulation.Simulation.water": {"tf": 1}, "lib.simulation.Simulation.COC": {"tf": 1}, "lib.simulation.Simulation.miuaTcal": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.lambdaTcal": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.MFW": {"tf": 1}, "lib.simulation.Simulation.integrated_inlet_flow": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.source_prod_flow": {"tf": 2}, "lib.simulation.Simulation.scenario_flag": {"tf": 1.7320508075688772}, "lib.simulation.Simulation.run": {"tf": 1}, "lib.surfactant": {"tf": 2}, "lib.surfactant.Surfactant": {"tf": 1}, "lib.surfactant.Surfactant.name": {"tf": 1}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.is_surfactant": {"tf": 1}, "lib.surfactant.Surfactant.phi": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.eval_dIFT_dGamma": {"tf": 1}, "lib.surfactant.Surfactant.initialize": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1.4142135623730951}, "lib.water": {"tf": 2.23606797749979}, "lib.water.Water": {"tf": 1.4142135623730951}, "lib.water.Water.__init__": {"tf": 1}, "lib.water.Water.init_oleic_saturation": {"tf": 1}, "lib.water.Water.water_saturation": {"tf": 1.4142135623730951}, "lib.water.Water.viscosity_array": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1.7320508075688772}, "lib.water.Water.compute_viscosity": {"tf": 1.7320508075688772}, "lib.water.Water.compute_mobility": {"tf": 2.23606797749979}, "lib.water.Water.compute_water_saturation": {"tf": 3}}, "df": 85, "i": {"docs": {}, "df": 0, "r": {"docs": {"lib.polymer.Polymer": {"tf": 1}}, "df": 1}}, "r": {"docs": {}, "df": 0, "e": {"docs": {"lib.simulation.Simulation.__init__": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.run": {"tf": 1}}, "df": 2}}}, "a": {"docs": {}, "df": 0, "t": {"docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}, "lib.enumerations": {"tf": 1}, "lib.enumerations.PolymerList": {"tf": 1}, "lib.enumerations.SurfactantList": {"tf": 1}, "lib.enumerations.ModelType": {"tf": 1}, "lib.enumerations.PlotType": {"tf": 1}, "lib.grid.FEMesh.right_hand": {"tf": 1}, "lib.polymer.Polymer.shear_rate": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.COC": {"tf": 1}, "lib.simulation.Simulation.miuaTcal": {"tf": 1}, "lib.simulation.Simulation.lambdaTcal": {"tf": 1}, "lib.simulation.Simulation.MFW": {"tf": 1}, "lib.simulation.Simulation.source_prod_flow": {"tf": 1}, "lib.simulation.Simulation.scenario_flag": {"tf": 1}, "lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 17}}, "i": {"docs": {}, "df": 0, "s": {"docs": {"lib.enumerations": {"tf": 1.4142135623730951}, "lib.grid": {"tf": 1.4142135623730951}, "lib.grid.Grid": {"tf": 1}, "lib.grid.FEMesh": {"tf": 1}, "lib.polymer": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.concetration_scalar": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.simulation": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.__init__": {"tf": 1}, "lib.surfactant": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.initialize": {"tf": 1}, "lib.water": {"tf": 1.4142135623730951}}, "df": 13}, "n": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1.4142135623730951}, "lib.water.Water.compute_viscosity": {"tf": 1.7320508075688772}}, "df": 2}}}}}}}, "a": {"docs": {}, "df": 0, "k": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {"lib.Exceptions.SimulationCalcInputException.__init__": {"tf": 1}}, "df": 1}, "n": {"docs": {"lib.enumerations.SimulationConstants": {"tf": 1}}, "df": 1}}}}, "o": {"docs": {"lib.enumerations.SurfactantList": {"tf": 1}, "lib.grid.Grid": {"tf": 1.4142135623730951}, "lib.grid.Grid.left": {"tf": 1}, "lib.grid.Grid.right": {"tf": 1}, "lib.grid.Grid.bottom": {"tf": 1}, "lib.grid.Grid.top": {"tf": 1}, "lib.grid.FEMesh": {"tf": 1.4142135623730951}, "lib.grid.FEMesh.right_hand": {"tf": 1}, "lib.grid.FEMesh.set_triangulation": {"tf": 1}, "lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}, "lib.grid.FEMesh.set_right_hand": {"tf": 1}, "lib.polymer.Polymer.e_coeff": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.n_coeff": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.shear_rate": {"tf": 1}, "lib.polymer.Polymer.phi": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.compute_concentration": {"tf": 1.7320508075688772}, "lib.simulation.Simulation": {"tf": 1}, "lib.surfactant.Surfactant": {"tf": 1}, "lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.phi": {"tf": 1}}, "df": 22, "p": {"docs": {"lib.grid.Grid.top": {"tf": 1}}, "df": 1}, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.simulation.Simulation.miuaTcal": {"tf": 1}, "lib.simulation.Simulation.lambdaTcal": {"tf": 1}}, "df": 2}}}}, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.SurfactantList.IFT_equation": {"tf": 1}, "lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}}, "df": 3}}}}}}, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.simulation.Simulation.model_type": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.relative_permeability_formula": {"tf": 1}, "lib.simulation.Simulation.scenario_flag": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1.4142135623730951}, "lib.water.Water.compute_mobility": {"tf": 1}}, "df": 6, "s": {"docs": {"lib.enumerations.ModelType": {"tf": 1}, "lib.enumerations.PlotType": {"tf": 1}}, "df": 2}}}}, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.grid.Grid": {"tf": 1}, "lib.grid.FEMesh": {"tf": 1}}, "df": 2, "s": {"docs": {"lib.grid.FEMesh.set_triangulation": {"tf": 1}}, "df": 1}}}}}}}}, "l": {"docs": {}, "df": 0, "e": {"docs": {"lib.grid.FEMesh.U": {"tf": 1}, "lib.grid.FEMesh.L": {"tf": 1}}, "df": 2, "s": {"docs": {"lib.grid.FEMesh.set_triangulation": {"tf": 1}}, "df": 1}}}}}}}, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "t": {"docs": {"lib.grid.Grid.set_FD_meshgrid": {"tf": 1}, "lib.water.Water.water_saturation": {"tf": 1}}, "df": 2}}}}, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.simulation.Simulation": {"tf": 1}}, "df": 1}}}}}}}}}}, "w": {"docs": {}, "df": 0, "o": {"docs": {"lib.grid.FEMesh.set_triangulation": {"tf": 1}}, "df": 1}}, "i": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.init_concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.concentration_matrix": {"tf": 1}, "lib.simulation.Simulation.time_step": {"tf": 1}, "lib.simulation.Simulation.miuaTcal": {"tf": 1}, "lib.simulation.Simulation.integrated_inlet_flow": {"tf": 1}}, "df": 5}}}, "u": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.initialize": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1}}, "df": 2, "[": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "[": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "y": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}}, "df": 1}}}}}}}}}}}}}}}}}, "o": {"docs": {"lib.simulation.Simulation.lambdaTcal": {"tf": 1}}, "df": 1, "u": {"docs": {}, "df": 0, "t": {"docs": {"lib.Exceptions.OutOfRangeError": {"tf": 1}}, "df": 1}}, "f": {"docs": {"lib.Exceptions.OutOfRangeError": {"tf": 1}, "lib.Exceptions.SimulationCalcInputException": {"tf": 1}, "lib.Exceptions.UserInputException.__init__": {"tf": 1.4142135623730951}, "lib.enumerations": {"tf": 1}, "lib.enumerations.SimulationConstants": {"tf": 1}, "lib.enumerations.PolymerList": {"tf": 1}, "lib.enumerations.PolymerList.Density": {"tf": 1}, "lib.enumerations.SurfactantList": {"tf": 1}, "lib.enumerations.SurfactantList.derivative_IFT_equation": {"tf": 1}, "lib.enumerations.PlotType": {"tf": 1.4142135623730951}, "lib.enumerations.ResevoirGeometry": {"tf": 1.4142135623730951}, "lib.enumerations.PermeabilityType": {"tf": 1.4142135623730951}, "lib.enumerations.RelativePermeabilityFormula": {"tf": 1}, "lib.grid.Grid.m": {"tf": 1}, "lib.grid.Grid.n": {"tf": 1}, "lib.grid.Grid.left": {"tf": 1}, "lib.grid.Grid.right": {"tf": 1}, "lib.grid.Grid.bottom": {"tf": 1}, "lib.grid.Grid.top": {"tf": 1}, "lib.grid.Grid.get_flat_index_matrix": {"tf": 1}, "lib.grid.FEMesh.__init__": {"tf": 1}, "lib.grid.FEMesh.U": {"tf": 1.7320508075688772}, "lib.grid.FEMesh.L": {"tf": 1.7320508075688772}, "lib.grid.FEMesh.grid_size": {"tf": 1}, "lib.grid.FEMesh.right_hand": {"tf": 1.4142135623730951}, "lib.grid.FEMesh.sparsed_A": {"tf": 1}, "lib.grid.FEMesh.set_triangulation": {"tf": 1.4142135623730951}, "lib.grid.FEMesh.set_right_hand": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.polymer.Polymer.__init__": {"tf": 1}, "lib.polymer.Polymer.name": {"tf": 1}, "lib.polymer.Polymer.concetration_scalar": {"tf": 1}, "lib.polymer.Polymer.init_concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.viscosity_matrix": {"tf": 1}, "lib.polymer.Polymer.viscosity_scalar": {"tf": 1}, "lib.polymer.Polymer.e_coeff": {"tf": 1}, "lib.polymer.Polymer.n_coeff": {"tf": 1}, "lib.polymer.Polymer.rho": {"tf": 1}, "lib.polymer.Polymer.shear_rate": {"tf": 1}, "lib.polymer.Polymer.phi": {"tf": 1}, "lib.polymer.Polymer.initialize": {"tf": 1}, "lib.simulation.Simulation.__init__": {"tf": 1}, "lib.simulation.Simulation.grid_size": {"tf": 1}, "lib.simulation.Simulation.model_type": {"tf": 1}, "lib.simulation.Simulation.relative_permeability_formula": {"tf": 1}, "lib.simulation.Simulation.scenario_flag": {"tf": 1}, "lib.simulation.Simulation.run": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.surfactant.Surfactant.__init__": {"tf": 1}, "lib.surfactant.Surfactant.name": {"tf": 1}, "lib.surfactant.Surfactant.concentration": {"tf": 1}, "lib.surfactant.Surfactant.concentration_matrix": {"tf": 1}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.phi": {"tf": 1}, "lib.water": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1.4142135623730951}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 59, "f": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}}, "df": 2}}, "b": {"docs": {}, "df": 0, "j": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {"lib.Exceptions.SimulationCalcInputException.__init__": {"tf": 1}, "lib.polymer.Polymer.initialize": {"tf": 1}, "lib.simulation.Simulation.polymer": {"tf": 1}, "lib.simulation.Simulation.surfactant": {"tf": 1}, "lib.simulation.Simulation.water": {"tf": 1}, "lib.surfactant.Surfactant": {"tf": 1}, "lib.surfactant.Surfactant.initialize": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1.4142135623730951}, "lib.water.Water.initialize": {"tf": 1.7320508075688772}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1.7320508075688772}}, "df": 11, "s": {"docs": {"lib.polymer.Polymer": {"tf": 1}}, "df": 1}}}}}, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "d": {"docs": {"lib.grid.FEMesh.set_triangulation": {"tf": 1}}, "df": 1}}}}}}}, "p": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.Exceptions.UserInputException.__init__": {"tf": 1.4142135623730951}}, "df": 1}}}}}}}, "n": {"docs": {"lib.enumerations.PolymerList.get_by_value": {"tf": 1}, "lib.enumerations.SurfactantList.get_by_value": {"tf": 1}, "lib.grid.Grid.left": {"tf": 1}, "lib.grid.Grid.right": {"tf": 1}, "lib.grid.Grid.bottom": {"tf": 1}, "lib.grid.Grid.top": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1.4142135623730951}, "lib.simulation.Simulation": {"tf": 1}, "lib.simulation.Simulation.permeability_flag": {"tf": 1}, "lib.simulation.Simulation.reservoir_geometry": {"tf": 1}, "lib.simulation.Simulation.model_type": {"tf": 1}, "lib.simulation.Simulation.relative_permeability_formula": {"tf": 1}, "lib.simulation.Simulation.scenario_flag": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1.7320508075688772}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}}, "df": 17, "l": {"docs": {}, "df": 0, "y": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1.4142135623730951}}, "df": 2}}}, "v": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.polymer.Polymer.concentration_matrix": {"tf": 1}, "lib.simulation.Simulation.miuaTcal": {"tf": 1}, "lib.simulation.Simulation.integrated_inlet_flow": {"tf": 1}}, "df": 3}}}, "r": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.surfactant.Surfactant.is_surfactant": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1.4142135623730951}}, "df": 4, "i": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}}, "df": 1}}}}}}}, "i": {"docs": {}, "df": 0, "l": {"docs": {"lib.simulation.Simulation.COC": {"tf": 1}, "lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}, "lib.water.Water.init_oleic_saturation": {"tf": 1}, "lib.water.Water.miuo": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}}, "df": 6}}, "l": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "c": {"docs": {"lib.water.Water.init_oleic_saturation": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1.4142135623730951}}, "df": 2}}}}}, "a": {"docs": {"lib.Exceptions.UserInputException.__init__": {"tf": 1}, "lib.enumerations.SimulationConstants": {"tf": 1}, "lib.grid.Grid.left": {"tf": 1}, "lib.grid.Grid.right": {"tf": 1}, "lib.grid.Grid.bottom": {"tf": 1}, "lib.grid.Grid.top": {"tf": 1}, "lib.grid.Grid.A": {"tf": 1}, "lib.grid.Grid.get_flat_index_matrix": {"tf": 1}, "lib.grid.FEMesh.A": {"tf": 1}, "lib.grid.FEMesh.sparsed_A": {"tf": 1}, "lib.polymer.Polymer.__init__": {"tf": 1}, "lib.simulation.Simulation.__init__": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.lambdaTcal": {"tf": 1}, "lib.simulation.Simulation.scenario_flag": {"tf": 1}, "lib.simulation.Simulation.run": {"tf": 1}, "lib.surfactant.Surfactant.eval_IFT": {"tf": 1}, "lib.surfactant.Surfactant.eval_dIFT_dGamma": {"tf": 1}}, "df": 17, "r": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "s": {"docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}, "lib.Exceptions.SimulationCalcInputException.__init__": {"tf": 1}, "lib.Exceptions.UserInputException.__init__": {"tf": 1}, "lib.grid.FEMesh.__init__": {"tf": 1}, "lib.polymer.Polymer.initialize": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.polymer.Polymer.divergence": {"tf": 1}, "lib.simulation.Simulation.__init__": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 15}, "u": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "s": {"docs": {"lib.water.Water.compute_mobility": {"tf": 1}}, "df": 1}}}}}}}, "e": {"docs": {"lib.enumerations": {"tf": 1}, "lib.grid.FEMesh.set_triangulation": {"tf": 1}, "lib.simulation.Simulation.source_prod_flow": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1.4142135623730951}}, "df": 5}, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "y": {"docs": {"lib.grid.FEMesh.U": {"tf": 1.4142135623730951}, "lib.grid.FEMesh.L": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.COC": {"tf": 1}, "lib.simulation.Simulation.miuaTcal": {"tf": 1}, "lib.simulation.Simulation.lambdaTcal": {"tf": 1}, "lib.simulation.Simulation.MFW": {"tf": 1}, "lib.water.Water.viscosity_array": {"tf": 1}}, "df": 7, "s": {"docs": {"lib.grid.Grid.set_FD_meshgrid": {"tf": 1}}, "df": 1}}}, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "y": {"docs": {"lib.polymer.Polymer.phi": {"tf": 1}, "lib.surfactant.Surfactant.phi": {"tf": 1}}, "df": 2}}}}}, "n": {"docs": {"lib.simulation.Simulation.__init__": {"tf": 1}, "lib.simulation.Simulation.COC": {"tf": 1}, "lib.simulation.Simulation.miuaTcal": {"tf": 1}, "lib.simulation.Simulation.run": {"tf": 1}}, "df": 4, "d": {"docs": {"lib.Exceptions.UserInputException.__init__": {"tf": 1}, "lib.enumerations": {"tf": 1}, "lib.enumerations.SimulationConstants": {"tf": 1}, "lib.enumerations.SurfactantList.IFT_equation": {"tf": 1}, "lib.grid": {"tf": 1.4142135623730951}, "lib.grid.Grid": {"tf": 1}, "lib.grid.Grid.get_spacing": {"tf": 1}, "lib.grid.Grid.get_meshgrid": {"tf": 1}, "lib.grid.FEMesh": {"tf": 1}, "lib.grid.FEMesh.right_hand": {"tf": 1.4142135623730951}, "lib.grid.FEMesh.set_right_hand": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.polymer.Polymer": {"tf": 1}, "lib.polymer.Polymer.initialize": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.simulation": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.__init__": {"tf": 1}, "lib.simulation.Simulation.source_prod_flow": {"tf": 1}, "lib.simulation.Simulation.scenario_flag": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.surfactant.Surfactant": {"tf": 1}, "lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}, "lib.water": {"tf": 1}, "lib.water.Water": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 28, "/": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "r": {"docs": {"lib.water.Water.initialize": {"tf": 1}}, "df": 1}}}}, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "s": {"docs": {"lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}}, "df": 1}}}}}}}}, "u": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}}, "df": 6}}}, "o": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "f": {"docs": {"lib.enumerations.SurfactantList": {"tf": 1}}, "df": 1}}}}}}}, "k": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {"lib.enumerations": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}}, "df": 6}}}}, "c": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {"lib.enumerations": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}}, "df": 6}}}}}, "d": {"docs": {}, "df": 0, "j": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.SurfactantList": {"tf": 1}}, "df": 1}}}}}, "s": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "b": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "y": {"docs": {"lib.grid.Grid": {"tf": 1}, "lib.grid.FEMesh": {"tf": 1}}, "df": 2}}}}}, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1}}, "df": 1}}}, "u": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.simulation.Simulation.source_prod_flow": {"tf": 1}}, "df": 1}}}}}}}, "x": {"docs": {"lib.grid.Grid.A": {"tf": 1}, "lib.grid.Grid.B": {"tf": 1}, "lib.grid.FEMesh.A": {"tf": 1}, "lib.grid.FEMesh.B": {"tf": 1}}, "df": 4}, "t": {"docs": {"lib.grid.Grid.get_flat_index_matrix": {"tf": 1}, "lib.grid.FEMesh.set_triangulation": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.init_concentration_matrix": {"tf": 1}, "lib.simulation.Simulation.source_flow_magnitude": {"tf": 1}, "lib.surfactant.Surfactant.eval_IFT": {"tf": 1}, "lib.surfactant.Surfactant.eval_dIFT_dGamma": {"tf": 1}}, "df": 6}, "m": {"docs": {}, "df": 0, "p": {"docs": {"lib.grid.FEMesh.set_triangulation": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.simulation.Simulation.source_prod_flow": {"tf": 1}}, "df": 3}}, "q": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "s": {"docs": {"lib.polymer.Polymer.e_coeff": {"tf": 1}, "lib.polymer.Polymer.n_coeff": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.miuaTcal": {"tf": 1}, "lib.water.Water.init_aqueous_saturation": {"tf": 1.4142135623730951}, "lib.water.Water.compute_viscosity": {"tf": 1.4142135623730951}, "lib.water.Water.compute_mobility": {"tf": 1.7320508075688772}}, "df": 7}}}}}, "o": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "s": {"docs": {"lib.water.Water.compute_mobility": {"tf": 1}}, "df": 1}}}}}}, "l": {"docs": {}, "df": 0, "l": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}}, "df": 4}}, "b": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {"lib.water.Water.compute_viscosity": {"tf": 1}}, "df": 1}}}}}, "v": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 5, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "e": {"docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 1.4142135623730951}, "lib.enumerations.PolymerList.get_by_value": {"tf": 1}, "lib.enumerations.SurfactantList.get_by_value": {"tf": 1}, "lib.grid.Grid.left": {"tf": 1.4142135623730951}, "lib.grid.Grid.right": {"tf": 1.4142135623730951}, "lib.grid.Grid.bottom": {"tf": 1.4142135623730951}, "lib.grid.Grid.top": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.scenario_flag": {"tf": 1}}, "df": 8, "s": {"docs": {"lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 1}}}, "i": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.Exceptions.UserInputException.__init__": {"tf": 1}}, "df": 1}}}}}}}}, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "s": {"docs": {"lib.Exceptions.SimulationCalcInputException": {"tf": 1}}, "df": 1}}}, "a": {"docs": {}, "df": 0, "b": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}}, "df": 1}}}}}}, "y": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1}}, "df": 1, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1.7320508075688772}, "lib.water.Water.compute_water_saturation": {"tf": 1.4142135623730951}}, "df": 3}}}}}}, "e": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "r": {"docs": {"lib.grid.Grid": {"tf": 1}, "lib.grid.FEMesh": {"tf": 1}, "lib.surfactant.Surfactant.concentration_matrix": {"tf": 1}}, "df": 3}}}}, "r": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {"lib.grid.FEMesh.U": {"tf": 1}, "lib.grid.FEMesh.L": {"tf": 1}, "lib.grid.FEMesh.set_triangulation": {"tf": 1}}, "df": 3}}}}}, "s": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.grid.FEMesh.sparsed_A": {"tf": 1}}, "df": 1}}}}}, "l": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {"lib.grid.FEMesh.right_hand": {"tf": 1.4142135623730951}, "lib.grid.FEMesh.set_right_hand": {"tf": 1}, "lib.polymer.Polymer.shear_rate": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 8}}}}}}}, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {"lib.polymer.Polymer.viscosity_matrix": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.viscosity_scalar": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.e_coeff": {"tf": 1}, "lib.polymer.Polymer.n_coeff": {"tf": 1}, "lib.polymer.Polymer.initialize": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 2}, "lib.simulation.Simulation.miuaTcal": {"tf": 1}, "lib.water.Water.miuw": {"tf": 1}, "lib.water.Water.miuo": {"tf": 1}, "lib.water.Water.viscosity_array": {"tf": 1.4142135623730951}, "lib.water.Water.compute_viscosity": {"tf": 1.4142135623730951}}, "df": 11}}}}}}}}}, "u": {"docs": {"lib.grid.FEMesh.U": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 6, "s": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}, "lib.Exceptions.UserInputException": {"tf": 1}, "lib.Exceptions.UserInputException.__init__": {"tf": 1}, "lib.enumerations.PlotType": {"tf": 1}, "lib.simulation.Simulation.__init__": {"tf": 2}}, "df": 5, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "x": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.simulation.Simulation.__init__": {"tf": 1}}, "df": 1}}}}}}}}}}}}}}}, "d": {"docs": {"lib.enumerations": {"tf": 1}, "lib.grid.Grid.left": {"tf": 1}, "lib.grid.Grid.right": {"tf": 1}, "lib.grid.Grid.bottom": {"tf": 1}, "lib.grid.Grid.top": {"tf": 1}, "lib.grid.Grid.set_FD_meshgrid": {"tf": 1}, "lib.grid.FEMesh.right_hand": {"tf": 1}, "lib.polymer.Polymer.e_coeff": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.n_coeff": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.phi": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.simulation.Simulation.relative_permeability_formula": {"tf": 1}, "lib.surfactant.Surfactant.phi": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1.7320508075688772}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 15}}, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.enumerations.SimulationConstants": {"tf": 1}, "lib.water.Water.water_saturation": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}}, "df": 3}}}}, "n": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "b": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "e": {"docs": {"lib.grid.Grid": {"tf": 1}, "lib.grid.FEMesh": {"tf": 1}}, "df": 2}}}}}}}}}}}}}, "p": {"docs": {"lib.grid.FEMesh.set_triangulation": {"tf": 1}}, "df": 1, "p": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.grid.FEMesh.U": {"tf": 1}}, "df": 1}}}, "d": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {"lib.grid.FEMesh.set_right_hand": {"tf": 1}}, "df": 1, "d": {"docs": {"lib.water.Water.water_saturation": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}}, "df": 2}, "s": {"docs": {"lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 1}}}}}}, "{": {"docs": {}, "df": 0, "i": {"docs": {"lib.grid.FEMesh.set_triangulation": {"tf": 1}}, "df": 1}}}, "p": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "d": {"docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}}, "df": 6}, "s": {"docs": {"lib.grid.Grid.get_spacing": {"tf": 1}}, "df": 1}}}}}, "f": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.PermeabilityType": {"tf": 1}}, "df": 1}}}}, "d": {"docs": {"lib.simulation.Simulation.source_prod_flow": {"tf": 1}}, "df": 1, "u": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.simulation.Simulation.source_prod_flow": {"tf": 1.4142135623730951}}, "df": 1}}}}}}}, "p": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {"lib.surfactant.Surfactant": {"tf": 1}}, "df": 1}, "i": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {"lib.water.Water": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1}}, "df": 2}}}}}}}}, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "e": {"docs": {"lib.grid.FEMesh.right_hand": {"tf": 1.4142135623730951}, "lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}, "lib.grid.FEMesh.set_right_hand": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 8}}}}}}}, "y": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations": {"tf": 1}, "lib.grid": {"tf": 1.4142135623730951}, "lib.polymer": {"tf": 1}, "lib.simulation": {"tf": 1.4142135623730951}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}}, "df": 6}}}}}, "o": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations": {"tf": 1}, "lib.enumerations.PolymerList.Id": {"tf": 1}, "lib.enumerations.PolymerList.Density": {"tf": 1}, "lib.enumerations.PolymerList.get_by_value": {"tf": 1}, "lib.enumerations.SurfactantList.Id": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.polymer.Polymer": {"tf": 1}, "lib.polymer.Polymer.__init__": {"tf": 1}, "lib.polymer.Polymer.name": {"tf": 1}, "lib.polymer.Polymer.concetration_scalar": {"tf": 1}, "lib.polymer.Polymer.init_concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.viscosity_matrix": {"tf": 1}, "lib.polymer.Polymer.viscosity_scalar": {"tf": 1}, "lib.polymer.Polymer.rho": {"tf": 1}, "lib.polymer.Polymer.initialize": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1.7320508075688772}, "lib.polymer.Polymer.compute_concentration": {"tf": 1.4142135623730951}, "lib.simulation": {"tf": 1}, "lib.simulation.Simulation.polymer": {"tf": 1.7320508075688772}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 2}, "lib.water.Water.compute_mobility": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1.7320508075688772}}, "df": 26, "s": {"docs": {"lib.enumerations.PolymerList": {"tf": 1}, "lib.polymer": {"tf": 1}}, "df": 2}, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {"lib.polymer.Polymer.name": {"tf": 1}}, "df": 1}}}}}}}}}, "w": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations.PolymerList.n_coeff": {"tf": 1}, "lib.enumerations.PolymerList.e_coeff": {"tf": 1}, "lib.polymer.Polymer.e_coeff": {"tf": 1}, "lib.polymer.Polymer.n_coeff": {"tf": 1}}, "df": 4}}}, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {"lib.grid.Grid.get_flat_index_matrix": {"tf": 1}, "lib.grid.FEMesh.set_triangulation": {"tf": 1}}, "df": 2, "s": {"docs": {"lib.water.Water.compute_water_saturation": {"tf": 1.4142135623730951}}, "df": 1}}}}, "r": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {"lib.polymer.Polymer.phi": {"tf": 1}, "lib.simulation.Simulation.phi": {"tf": 1}, "lib.surfactant.Surfactant.phi": {"tf": 1}, "lib.water.Water.phi": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1}}, "df": 5}}}}}}}, "a": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations.SimulationConstants": {"tf": 1}}, "df": 1}}}, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "m": {"docs": {"lib.polymer.Polymer.concetration_scalar": {"tf": 1}}, "df": 1, "e": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.water.Water.compute_mobility": {"tf": 1}}, "df": 1, "s": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 2.449489742783178}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 2.23606797749979}, "lib.water.Water.initialize": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 2.23606797749979}}, "df": 5}}}}}}}, "t": {"docs": {"lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 1, "i": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {"lib.surfactant.Surfactant.eval_dIFT_dGamma": {"tf": 1}}, "df": 1}}}}}}}}}, "l": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "s": {"docs": {"lib.enumerations.PlotType": {"tf": 1}}, "df": 1}}}}, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "b": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {"lib.enumerations.PermeabilityType": {"tf": 1}, "lib.enumerations.RelativePermeabilityFormula": {"tf": 1}, "lib.simulation.Simulation.permeability_flag": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.relative_permeability_formula": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.KK": {"tf": 1}, "lib.simulation.Simulation.scenario_flag": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1.4142135623730951}}, "df": 7, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {"lib.simulation.Simulation.permeability_flag": {"tf": 1.4142135623730951}}, "df": 1}}}}}}}}}}}}}}}, "h": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.e_coeff": {"tf": 1}, "lib.polymer.Polymer.n_coeff": {"tf": 1}, "lib.water.Water.init_aqueous_saturation": {"tf": 1}, "lib.water.Water.init_oleic_saturation": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1.4142135623730951}}, "df": 5, "s": {"docs": {"lib.water.Water.compute_residual_saturations": {"tf": 1}}, "df": 1}}}}, "i": {"docs": {"lib.polymer.Polymer.phi": {"tf": 1}, "lib.simulation.Simulation.phi": {"tf": 1}, "lib.surfactant.Surfactant.phi": {"tf": 1}, "lib.water.Water.phi": {"tf": 1}}, "df": 4}}}, "g": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "i": {"docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}, "lib.Exceptions.UserInputException": {"tf": 1}, "lib.simulation.Simulation.__init__": {"tf": 1}}, "df": 3}}, "e": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "y": {"docs": {"lib.enumerations.ResevoirGeometry": {"tf": 1}, "lib.simulation.Simulation.reservoir_geometry": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.scenario_flag": {"tf": 1}}, "df": 3}}}}}}, "n": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.grid.Grid": {"tf": 1}, "lib.grid.FEMesh": {"tf": 1}}, "df": 2}}}, "e": {"docs": {"lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}}, "df": 1, "s": {"docs": {"lib.grid.Grid.get_meshgrid": {"tf": 1}, "lib.grid.Grid.set_FD_meshgrid": {"tf": 1}}, "df": 2}}}}}}}}, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "d": {"docs": {"lib.grid.Grid.left": {"tf": 1}, "lib.grid.Grid.right": {"tf": 1}, "lib.grid.Grid.bottom": {"tf": 1}, "lib.grid.Grid.top": {"tf": 1}, "lib.grid.Grid.set_FD_meshgrid": {"tf": 1}, "lib.grid.Grid.get_flat_index_matrix": {"tf": 1}, "lib.grid.FEMesh.__init__": {"tf": 1}, "lib.grid.FEMesh.grid_size": {"tf": 1}, "lib.grid.FEMesh.set_triangulation": {"tf": 1}, "lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}, "lib.polymer.Polymer.initialize": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1.7320508075688772}, "lib.polymer.Polymer.compute_concentration": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.grid_size": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1.4142135623730951}, "lib.water.Water.initialize": {"tf": 1.4142135623730951}, "lib.water.Water.compute_viscosity": {"tf": 1.7320508075688772}, "lib.water.Water.compute_water_saturation": {"tf": 1.7320508075688772}}, "df": 18}}}, "l": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "b": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.grid.FEMesh.right_hand": {"tf": 1.4142135623730951}, "lib.grid.FEMesh.set_right_hand": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 7}}}}}, "o": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {"lib.grid.FEMesh.set_triangulation": {"tf": 1}}, "df": 1}}}, "i": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {"lib.surfactant.Surfactant.eval_IFT": {"tf": 1}}, "df": 1}}}}, "m": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "d": {"docs": {"lib.surfactant.Surfactant.compute_concentration": {"tf": 1}}, "df": 1}}}}, "m": {"docs": {"lib.grid.FEMesh.__init__": {"tf": 1}, "lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 7, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "e": {"docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 1.4142135623730951}, "lib.Exceptions.SimulationCalcInputException.__init__": {"tf": 1.4142135623730951}, "lib.Exceptions.UserInputException.__init__": {"tf": 1.4142135623730951}}, "df": 3}}}}, "h": {"docs": {"lib.grid.Grid": {"tf": 1}, "lib.grid.Grid.get_meshgrid": {"tf": 1}, "lib.grid.FEMesh": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}}, "df": 4, "g": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "d": {"docs": {"lib.grid.Grid.set_FD_meshgrid": {"tf": 1}}, "df": 1}}}}}}, "t": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "d": {"docs": {"lib.enumerations.SimulationConstants": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.simulation.Simulation.__init__": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 4, "s": {"docs": {"lib.enumerations": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}, "lib.water.Water": {"tf": 1}}, "df": 5}}}}}, "a": {"docs": {}, "df": 0, "n": {"docs": {"lib.simulation.Simulation.MFW": {"tf": 1}}, "df": 1}}}, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "b": {"docs": {"lib.enumerations": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1.4142135623730951}, "lib.simulation": {"tf": 1}, "lib.simulation.Simulation": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}}, "df": 11}}}, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "x": {"docs": {"lib.grid.Grid": {"tf": 1}, "lib.grid.Grid.A": {"tf": 1}, "lib.grid.Grid.B": {"tf": 1}, "lib.grid.Grid.get_flat_index_matrix": {"tf": 1}, "lib.grid.FEMesh": {"tf": 1}, "lib.grid.FEMesh.right_hand": {"tf": 1}, "lib.grid.FEMesh.A": {"tf": 1}, "lib.grid.FEMesh.B": {"tf": 1}, "lib.grid.FEMesh.sparsed_A": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.init_concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.concentration_matrix": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.viscosity_matrix": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.shear_rate": {"tf": 1}, "lib.polymer.Polymer.phi": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 2.449489742783178}, "lib.polymer.Polymer.compute_concentration": {"tf": 2}, "lib.simulation.Simulation.phi": {"tf": 1}, "lib.simulation.Simulation.KK": {"tf": 1}, "lib.simulation.Simulation.source_prod_flow": {"tf": 1}, "lib.surfactant.Surfactant.concentration_matrix": {"tf": 1}, "lib.surfactant.Surfactant.phi": {"tf": 1}, "lib.surfactant.Surfactant.eval_IFT": {"tf": 1}, "lib.surfactant.Surfactant.eval_dIFT_dGamma": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1.7320508075688772}, "lib.water.Water.water_saturation": {"tf": 1}, "lib.water.Water.viscosity_array": {"tf": 1}, "lib.water.Water.phi": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 2}, "lib.water.Water.compute_residual_saturations": {"tf": 1.4142135623730951}, "lib.water.Water.compute_mobility": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 2.449489742783178}}, "df": 32}, "c": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {"lib.grid.FEMesh.right_hand": {"tf": 1}, "lib.grid.FEMesh.set_right_hand": {"tf": 1}, "lib.polymer.Polymer.initialize": {"tf": 1}}, "df": 3}}}}}}, "k": {"docs": {}, "df": 0, "e": {"docs": {"lib.grid.Grid": {"tf": 1}, "lib.grid.FEMesh": {"tf": 1}}, "df": 2}}, "g": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "e": {"docs": {"lib.simulation.Simulation.source_flow_magnitude": {"tf": 1}}, "df": 1, "s": {"docs": {"lib.simulation.Simulation.source_prod_flow": {"tf": 1}}, "df": 1}}}}}}}}, "d": {"docs": {}, "df": 0, "e": {"docs": {"lib.water.Water.compute_mobility": {"tf": 1}}, "df": 1}}}, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {"lib.enumerations": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}}, "df": 6}}}}, "u": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.simulation.Simulation.miuaTcal": {"tf": 1}}, "df": 1}}}}, "w": {"docs": {"lib.water.Water.miuw": {"tf": 1}}, "df": 1}, "o": {"docs": {"lib.water.Water.miuo": {"tf": 1}}, "df": 1}}}, "o": {"docs": {}, "df": 0, "d": {"docs": {"lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 1, "e": {"docs": {}, "df": 0, "l": {"docs": {"lib.enumerations.ModelType": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.model_type": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1.4142135623730951}}, "df": 7, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.enumerations.SimulationConstants": {"tf": 1}}, "df": 1}}}, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.simulation.Simulation.model_type": {"tf": 1.4142135623730951}, "lib.water.Water.compute_viscosity": {"tf": 1}}, "df": 3}}}}}}}, "r": {"docs": {}, "df": 0, "e": {"docs": {"lib.grid.Grid": {"tf": 1}, "lib.grid.FEMesh": {"tf": 1}}, "df": 2}}, "s": {"docs": {}, "df": 0, "t": {"docs": {"lib.grid.Grid.left": {"tf": 1}, "lib.grid.Grid.right": {"tf": 1}, "lib.grid.Grid.bottom": {"tf": 1}, "lib.grid.Grid.top": {"tf": 1}}, "df": 4}}, "b": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {"lib.simulation.Simulation.lambdaTcal": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1.7320508075688772}}, "df": 2}}}}}}}, "+": {"1": {"docs": {"lib.grid.Grid.get_flat_index_matrix": {"tf": 1}}, "df": 1}, "docs": {}, "df": 0}, "f": {"docs": {}, "df": 0, "w": {"docs": {"lib.simulation.Simulation.MFW": {"tf": 1.4142135623730951}}, "df": 1}}}, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {"lib.Exceptions.OutOfRangeError.__init__": {"tf": 1}, "lib.Exceptions.SimulationCalcInputException.__init__": {"tf": 1}, "lib.Exceptions.UserInputException.__init__": {"tf": 1}}, "df": 3}, "a": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {"lib.Exceptions.SimulationCalcInputException": {"tf": 1}}, "df": 1}}}, "r": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.grid.FEMesh.set_triangulation": {"tf": 1}}, "df": 1}}}}}, "t": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}}, "df": 1}}}, "e": {"docs": {}, "df": 0, "p": {"docs": {"lib.simulation.Simulation.time_step": {"tf": 1}}, "df": 1}}}, "i": {"docs": {}, "df": 0, "m": {"docs": {"lib.water.Water.compute_viscosity": {"tf": 1}}, "df": 1, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.Exceptions.SimulationCalcInputException": {"tf": 1}, "lib.enumerations": {"tf": 1}, "lib.enumerations.SimulationConstants": {"tf": 1.4142135623730951}, "lib.enumerations.PolymerList": {"tf": 1}, "lib.enumerations.SurfactantList": {"tf": 1}, "lib.enumerations.ModelType": {"tf": 1}, "lib.enumerations.ResevoirGeometry": {"tf": 1}, "lib.enumerations.PermeabilityType": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.simulation.Simulation": {"tf": 1}, "lib.simulation.Simulation.__init__": {"tf": 1}, "lib.simulation.Simulation.model_type": {"tf": 1}, "lib.simulation.Simulation.relative_permeability_formula": {"tf": 1}, "lib.simulation.Simulation.run": {"tf": 1}, "lib.surfactant.Surfactant.is_surfactant": {"tf": 1}}, "df": 17, "s": {"docs": {"lib.grid": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.simulation.Simulation": {"tf": 1}}, "df": 3}, "c": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "x": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.simulation.Simulation.__init__": {"tf": 1}, "lib.simulation.Simulation.run": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 7}}}}}}}}}}}}}}}}}}}}}}}}, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "x": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.water.Water.initialize": {"tf": 1}}, "df": 1}}}}}}}}}}}}}}}}}}}}}, "z": {"docs": {}, "df": 0, "e": {"docs": {"lib.grid.FEMesh.grid_size": {"tf": 1}, "lib.simulation.Simulation.grid_size": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}}, "df": 3}}, "d": {"docs": {}, "df": 0, "e": {"docs": {"lib.grid.FEMesh.set_right_hand": {"tf": 1}}, "df": 1}}, "t": {"docs": {}, "df": 0, "e": {"docs": {"lib.simulation.Simulation.source_flow_magnitude": {"tf": 1}}, "df": 1}}, "g": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "a": {"docs": {"lib.water.Water.compute_residual_saturations": {"tf": 1}}, "df": 1}}}}, "c": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}}, "df": 6}}}}, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {"lib.polymer.Polymer.concetration_scalar": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.viscosity_scalar": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.concentration": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}}, "df": 4}}}}, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {"lib.simulation.Simulation.scenario_flag": {"tf": 1.4142135623730951}}, "df": 1}}}}}}}, "u": {"docs": {}, "df": 0, "r": {"docs": {"lib.surfactant.Surfactant.compute_concentration": {"tf": 1}}, "df": 1, "f": {"docs": {"lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 1, "a": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations": {"tf": 1}, "lib.enumerations.SurfactantList.IFT_equation": {"tf": 1}, "lib.enumerations.SurfactantList.get_by_value": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.polymer": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.simulation.Simulation.surfactant": {"tf": 1.7320508075688772}, "lib.surfactant": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant": {"tf": 1}, "lib.surfactant.Surfactant.__init__": {"tf": 1}, "lib.surfactant.Surfactant.name": {"tf": 1}, "lib.surfactant.Surfactant.concentration": {"tf": 1}, "lib.surfactant.Surfactant.concentration_matrix": {"tf": 1}, "lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.is_surfactant": {"tf": 1}, "lib.surfactant.Surfactant.eval_IFT": {"tf": 1}, "lib.surfactant.Surfactant.eval_dIFT_dGamma": {"tf": 1}, "lib.surfactant.Surfactant.initialize": {"tf": 1.7320508075688772}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water": {"tf": 1.4142135623730951}, "lib.water.Water.compute_mobility": {"tf": 1.4142135623730951}, "lib.water.Water.compute_water_saturation": {"tf": 1.7320508075688772}}, "df": 24, "\u2013": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations.SimulationConstants": {"tf": 1}}, "df": 1}}}}}}}}, "s": {"docs": {"lib.enumerations.SurfactantList": {"tf": 1}, "lib.surfactant": {"tf": 1}}, "df": 2}, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {"lib.surfactant.Surfactant.name": {"tf": 1}}, "df": 1}}}}}}}}}}}}, "b": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "s": {"docs": {"lib.grid.FEMesh.__init__": {"tf": 1}}, "df": 1}}}}}, "s": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "q": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "y": {"docs": {"lib.grid.FEMesh.right_hand": {"tf": 1}}, "df": 1}}}}}}}}}}}, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "v": {"docs": {"lib.enumerations": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}}, "df": 6}}, "c": {"docs": {}, "df": 0, "e": {"docs": {"lib.grid.Grid": {"tf": 1}, "lib.grid.FEMesh": {"tf": 1}, "lib.simulation.Simulation.source_flow_magnitude": {"tf": 1}, "lib.simulation.Simulation.integrated_inlet_flow": {"tf": 1}, "lib.simulation.Simulation.source_prod_flow": {"tf": 1.7320508075688772}}, "df": 5}}}}, "l": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.grid.Grid.A": {"tf": 1}, "lib.grid.Grid.B": {"tf": 1}, "lib.grid.FEMesh.A": {"tf": 1}, "lib.grid.FEMesh.B": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 6}}}, "e": {"docs": {"lib.grid.FEMesh.right_hand": {"tf": 1}}, "df": 1, "d": {"docs": {"lib.grid.FEMesh.set_right_hand": {"tf": 1}}, "df": 1}}}}, "r": {"docs": {"lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}}, "df": 2}}, "e": {"docs": {"lib.grid.FEMesh.set_triangulation": {"tf": 1}}, "df": 1, "l": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {"lib.water.Water.compute_mobility": {"tf": 1}}, "df": 1, "e": {"docs": {}, "df": 0, "d": {"docs": {"lib.enumerations.PolymerList": {"tf": 1}, "lib.enumerations.SurfactantList": {"tf": 1}, "lib.enumerations.ModelType": {"tf": 1}}, "df": 3}}, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.PlotType": {"tf": 1}, "lib.enumerations.ResevoirGeometry": {"tf": 1}, "lib.enumerations.PermeabilityType": {"tf": 1}, "lib.enumerations.RelativePermeabilityFormula": {"tf": 1}}, "df": 4}}}}}}}, "t": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "p": {"docs": {"lib.grid.Grid": {"tf": 1}, "lib.grid.FEMesh": {"tf": 1}}, "df": 2}}, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.grid.FEMesh.set_triangulation": {"tf": 1}}, "df": 1}}}}, "g": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "d": {"docs": {"lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}}, "df": 1}}}}, "s": {"docs": {"lib.grid.FEMesh.set_right_hand": {"tf": 1}, "lib.simulation.Simulation.permeability_flag": {"tf": 1}, "lib.simulation.Simulation.reservoir_geometry": {"tf": 1}, "lib.simulation.Simulation.model_type": {"tf": 1}, "lib.simulation.Simulation.relative_permeability_formula": {"tf": 1}}, "df": 5}}}, "p": {"docs": {"lib.grid.Grid.set_FD_meshgrid": {"tf": 1}, "lib.simulation.Simulation": {"tf": 1}, "lib.water.Water": {"tf": 1}}, "df": 3, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "d": {"docs": {"lib.grid.FEMesh.sparsed_A": {"tf": 1}}, "df": 1}}}}}}, "h": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {"lib.grid.Grid.get_flat_index_matrix": {"tf": 1}, "lib.polymer.Polymer.initialize": {"tf": 1.4142135623730951}, "lib.water.Water.initialize": {"tf": 1}}, "df": 3}}}, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {"lib.polymer.Polymer.shear_rate": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.initialize": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1.7320508075688772}, "lib.water.Water.compute_viscosity": {"tf": 1.7320508075688772}}, "df": 4}}}}, "q": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "e": {"docs": {"lib.grid.FEMesh.grid_size": {"tf": 1}, "lib.simulation.Simulation.grid_size": {"tf": 1}}, "df": 2}}}}}, "a": {"docs": {}, "df": 0, "t": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}}, "df": 2, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water.Water.init_water_saturation": {"tf": 1.4142135623730951}, "lib.water.Water.init_aqueous_saturation": {"tf": 1.4142135623730951}, "lib.water.Water.init_oleic_saturation": {"tf": 1.4142135623730951}, "lib.water.Water.water_saturation": {"tf": 1.4142135623730951}, "lib.water.Water.initialize": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1.4142135623730951}, "lib.water.Water.compute_water_saturation": {"tf": 2}}, "df": 10}}}}}}}}, "m": {"docs": {}, "df": 0, "e": {"docs": {"lib.simulation.Simulation.source_prod_flow": {"tf": 1}}, "df": 1}}}, "y": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "m": {"docs": {"lib.water.Water": {"tf": 1}}, "df": 1}}}}}, "w": {"docs": {}, "df": 0, "r": {"docs": {"lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}}, "df": 2}}}, "h": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "d": {"docs": {"lib.grid.FEMesh.set_right_hand": {"tf": 1}}, "df": 1, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.Exceptions.SimulationCalcInputException": {"tf": 1}}, "df": 1}}}}}}, "s": {"docs": {"lib.grid": {"tf": 1}, "lib.grid.Grid.left": {"tf": 1}, "lib.grid.Grid.right": {"tf": 1}, "lib.grid.Grid.bottom": {"tf": 1}, "lib.grid.Grid.top": {"tf": 1}, "lib.simulation": {"tf": 1}}, "df": 6}}, "y": {"docs": {}, "df": 0, "b": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "d": {"docs": {"lib.enumerations.SimulationConstants": {"tf": 1}}, "df": 1}}}}}, "o": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "d": {"docs": {"lib.polymer.Polymer.shear_rate": {"tf": 1}}, "df": 1, "s": {"docs": {"lib.simulation.Simulation.polymer": {"tf": 1}, "lib.simulation.Simulation.surfactant": {"tf": 1}, "lib.simulation.Simulation.water": {"tf": 1}, "lib.simulation.Simulation.COC": {"tf": 1}, "lib.simulation.Simulation.lambdaTcal": {"tf": 1}, "lib.simulation.Simulation.MFW": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}}, "df": 7}}}}, "e": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "p": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1}}, "df": 1}}}}, "w": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "h": {"docs": {"lib.Exceptions.UserInputException.__init__": {"tf": 1}, "lib.grid.Grid.get_flat_index_matrix": {"tf": 1}, "lib.grid.FEMesh.U": {"tf": 1}, "lib.grid.FEMesh.L": {"tf": 1}, "lib.grid.FEMesh.set_triangulation": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.__init__": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.source_prod_flow": {"tf": 1}, "lib.simulation.Simulation.run": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1.4142135623730951}}, "df": 10, "i": {"docs": {}, "df": 0, "n": {"docs": {"lib.Exceptions.SimulationCalcInputException": {"tf": 1}, "lib.enumerations": {"tf": 1}, "lib.polymer.Polymer.init_concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}}, "df": 5}}}}, "l": {"docs": {}, "df": 0, "l": {"docs": {"lib.grid.FEMesh.right_hand": {"tf": 1}, "lib.polymer.Polymer.concetration_scalar": {"tf": 1}, "lib.polymer.Polymer.shear_rate": {"tf": 1}, "lib.polymer.Polymer.initialize": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1.7320508075688772}, "lib.simulation.Simulation.__init__": {"tf": 1}, "lib.surfactant.Surfactant.initialize": {"tf": 1}}, "df": 7}}, "d": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "h": {"docs": {"lib.simulation.Simulation.MFW": {"tf": 1}}, "df": 1}}}}, "e": {"docs": {"lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}}, "df": 2, "r": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1.4142135623730951}, "lib.surfactant": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water": {"tf": 1}}, "df": 6}}, "l": {"docs": {}, "df": 0, "l": {"docs": {"lib.simulation.Simulation.source_prod_flow": {"tf": 1.4142135623730951}}, "df": 1}}}, "h": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.SurfactantList": {"tf": 1}, "lib.polymer.Polymer.concetration_scalar": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.water.Water.init_aqueous_saturation": {"tf": 1}, "lib.water.Water.init_oleic_saturation": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1.4142135623730951}}, "df": 6}, "t": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.surfactant.Surfactant.is_surfactant": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}}, "df": 3}}}}}, "o": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "e": {"docs": {"lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 1}}}}, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1.7320508075688772}, "lib.simulation.Simulation.water": {"tf": 1.7320508075688772}, "lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1.4142135623730951}, "lib.water": {"tf": 1}, "lib.water.Water": {"tf": 1}, "lib.water.Water.__init__": {"tf": 1}, "lib.water.Water.init_water_saturation": {"tf": 1.4142135623730951}, "lib.water.Water.miuw": {"tf": 1}, "lib.water.Water.water_saturation": {"tf": 1.4142135623730951}, "lib.water.Water.viscosity_array": {"tf": 1}, "lib.water.Water.initialize": {"tf": 2.23606797749979}, "lib.water.Water.compute_residual_saturations": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1.7320508075688772}}, "df": 16}}}}}, "c": {"docs": {"lib.water.Water.compute_mobility": {"tf": 1}}, "df": 1, "o": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 3, "r": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "r": {"docs": {"lib.Exceptions.SimulationCalcInputException.__init__": {"tf": null}, "lib.grid.FEMesh.__init__": {"tf": null}, "lib.water.Water.__init__": {"tf": null}}, "df": 3}}}}}}, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 3, "s": {"docs": {"lib.enumerations.SimulationConstants": {"tf": 1}}, "df": 1}}}}}}, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {"lib.polymer.Polymer.initialize": {"tf": 1}}, "df": 1, "s": {"docs": {"lib.enumerations": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.surfactant.Surfactant": {"tf": 1}, "lib.water": {"tf": 1}, "lib.water.Water": {"tf": 1}}, "df": 8}, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.simulation.Simulation.__init__": {"tf": 1}}, "df": 1}}}}}}}, "c": {"docs": {"lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}}, "df": 4, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.SurfactantList.IFT_equation": {"tf": 1}, "lib.polymer.Polymer.concetration_scalar": {"tf": 1.7320508075688772}, "lib.polymer.Polymer.init_concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.concentration_matrix": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.phi": {"tf": 1}, "lib.polymer.Polymer.initialize": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1.7320508075688772}, "lib.surfactant.Surfactant.concentration": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.concentration_matrix": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.phi": {"tf": 1}, "lib.surfactant.Surfactant.eval_IFT": {"tf": 1}, "lib.surfactant.Surfactant.eval_dIFT_dGamma": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1.4142135623730951}}, "df": 16}}}}}}}}}}, "d": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "s": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1.4142135623730951}}, "df": 1}}}}}}}}, "d": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1.4142135623730951}, "lib.simulation": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}}, "df": 8}}, "e": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "f": {"docs": {"lib.enumerations.PolymerList.n_coeff": {"tf": 1}, "lib.enumerations.PolymerList.e_coeff": {"tf": 1}, "lib.polymer.Polymer.e_coeff": {"tf": 1}, "lib.polymer.Polymer.n_coeff": {"tf": 1}}, "df": 4, "i": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.PolymerList.n_coeff": {"tf": 1}, "lib.enumerations.PolymerList.e_coeff": {"tf": 1}}, "df": 2}}}, "c": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "s": {"docs": {"lib.polymer.Polymer.e_coeff": {"tf": 1}, "lib.polymer.Polymer.n_coeff": {"tf": 1}}, "df": 2}}}}}}}}}}, "l": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "s": {"docs": {"lib.grid.Grid.m": {"tf": 1}, "lib.grid.FEMesh.__init__": {"tf": 1}}, "df": 2}}}}, "s": {"docs": {"lib.grid.FEMesh.grid_size": {"tf": 1}}, "df": 1}}, "m": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {"lib.grid.Grid.left": {"tf": 1}, "lib.grid.Grid.right": {"tf": 1}, "lib.grid.Grid.bottom": {"tf": 1}, "lib.grid.Grid.top": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}}, "df": 7, "s": {"docs": {"lib.grid.Grid.dx": {"tf": 1}, "lib.grid.Grid.dy": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}}, "df": 3}}, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}}, "df": 2}}}}}, "v": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "s": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1.4142135623730951}}, "df": 1}}}, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {"lib.water.Water.compute_residual_saturations": {"tf": 1}}, "df": 1}}}, "m": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "b": {"docs": {"lib.water.Water.compute_mobility": {"tf": 1}}, "df": 1}}}}, "e": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}}, "df": 1, "s": {"docs": {"lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 1}}}, "o": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {"lib.grid.Grid.set_FD_meshgrid": {"tf": 1}, "lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1.4142135623730951}}, "df": 3, "s": {"docs": {"lib.grid.Grid.get_meshgrid": {"tf": 1}, "lib.grid.FEMesh.set_triangulation": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}}, "df": 4}}}}}}}}}, "c": {"docs": {"lib.simulation.Simulation.COC": {"tf": 1}}, "df": 1}}, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "s": {"docs": {"lib.enumerations": {"tf": 1.4142135623730951}, "lib.grid": {"tf": 1}, "lib.grid.Grid": {"tf": 1}, "lib.grid.FEMesh": {"tf": 1}, "lib.grid.FEMesh.__init__": {"tf": 1.4142135623730951}, "lib.polymer": {"tf": 1.4142135623730951}, "lib.polymer.Polymer": {"tf": 1}, "lib.polymer.Polymer.__init__": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.simulation.Simulation": {"tf": 1}, "lib.surfactant": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.__init__": {"tf": 1}, "lib.water": {"tf": 1.4142135623730951}, "lib.water.Water.__init__": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1}}, "df": 16}}}}, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "s": {"docs": {"lib.enumerations": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}}, "df": 6}}}, "i": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "o": {"docs": {"lib.enumerations": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}}, "df": 6}}}}, "n": {"docs": {"lib.enumerations.PolymerList": {"tf": 1}, "lib.enumerations.SurfactantList": {"tf": 1}, "lib.enumerations.ModelType": {"tf": 1}, "lib.enumerations.PlotType": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 5}, "l": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.simulation.Simulation.__init__": {"tf": 1}, "lib.simulation.Simulation.run": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1.4142135623730951}}, "df": 3, "s": {"docs": {"lib.grid.FEMesh.set_FE_meshgrid": {"tf": 1}, "lib.polymer.Polymer": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant": {"tf": 1}}, "df": 5}}}, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 1}}}, "e": {"docs": {}, "df": 0, "s": {"docs": {"lib.polymer.Polymer.divergence": {"tf": 1}}, "df": 1}}}}}}, "s": {"docs": {"lib.surfactant.Surfactant.compute_concentration": {"tf": 1}}, "df": 1}}}, "p": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "d": {"docs": {"lib.simulation.Simulation.COC": {"tf": 1}}, "df": 1}}}}}, "u": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {"lib.simulation.Simulation.miuaTcal": {"tf": 1}}, "df": 1}}}}}, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "y": {"docs": {"lib.water.Water.init_aqueous_saturation": {"tf": 1}, "lib.water.Water.init_oleic_saturation": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}}, "df": 3}}}}}}}, "m": {"docs": {}, "df": 0, "e": {"docs": {"lib.water.Water.compute_residual_saturations": {"tf": 1}}, "df": 1}}}, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "d": {"docs": {"lib.enumerations.PlotType": {"tf": 1}}, "df": 1}, "s": {"docs": {"lib.surfactant.Surfactant.__init__": {"tf": 1}}, "df": 1}}}}}, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.water.Water.init_aqueous_saturation": {"tf": 1}, "lib.water.Water.init_oleic_saturation": {"tf": 1}}, "df": 2}}}}}}}, "e": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "l": {"docs": {"lib.grid.FEMesh.U": {"tf": 1.4142135623730951}, "lib.grid.FEMesh.L": {"tf": 1.4142135623730951}}, "df": 2, "s": {"docs": {"lib.grid.FEMesh.set_triangulation": {"tf": 1}}, "df": 1}}}}, "h": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.shear_rate": {"tf": 1}, "lib.polymer.Polymer.divergence": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.miuaTcal": {"tf": 1}, "lib.simulation.Simulation.lambdaTcal": {"tf": 1}, "lib.simulation.Simulation.MFW": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 6, "d": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1}}, "df": 1}}}}, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "c": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1.4142135623730951}}, "df": 1}}}}}}}}}}}}, "e": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "k": {"docs": {"lib.simulation.Simulation.__init__": {"tf": 1}}, "df": 1}}}, "o": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {"lib.simulation.Simulation.scenario_flag": {"tf": 1}}, "df": 1}}}}}, "u": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "e": {"docs": {"lib.simulation.Simulation.COC": {"tf": 1}}, "df": 1}}}}}}}}}}}, "d": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {"lib.Exceptions.UserInputException.__init__": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1.7320508075688772}, "lib.simulation.Simulation.__init__": {"tf": 2}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 2}, "lib.water.Water.compute_water_saturation": {"tf": 2}}, "df": 5, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "y": {"docs": {"lib.Exceptions.UserInputException.__init__": {"tf": 1.4142135623730951}, "lib.simulation.Simulation.__init__": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1.4142135623730951}}, "df": 3}}}}}}}}, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.polymer.Polymer.shear_rate": {"tf": 1}}, "df": 1}}}}}}}, "m": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1.4142135623730951}}, "df": 1, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.polymer.Polymer.divergence": {"tf": 1.4142135623730951}, "lib.water.Water.compute_water_saturation": {"tf": 1.4142135623730951}}, "df": 2, "s": {"docs": {"lib.simulation.Simulation.grid_size": {"tf": 1}}, "df": 1}}}}}}}}, "v": {"docs": {"lib.polymer.Polymer.divergence": {"tf": 1}}, "df": 1, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.divergence": {"tf": 1}}, "df": 1}}}}}}}}}, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.Exceptions.UserInputException.__init__": {"tf": 1}}, "df": 1}}}}}}}}}, "f": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.grid": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.polymer.Polymer": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}}, "df": 6, "s": {"docs": {"lib.enumerations": {"tf": 1}}, "df": 1}}}}}}}}, "a": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "t": {"docs": {"lib.grid.Grid.left": {"tf": 1}, "lib.grid.Grid.right": {"tf": 1}, "lib.grid.Grid.bottom": {"tf": 1}, "lib.grid.Grid.top": {"tf": 1}}, "df": 4}}}}}, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "d": {"docs": {"lib.enumerations": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}}, "df": 7}}, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "e": {"docs": {"lib.enumerations.SurfactantList.derivative_IFT_equation": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1}}, "df": 2}}}}}, "i": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "e": {"docs": {"lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1}}, "df": 1}}}}}}}}}, "v": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "d": {"docs": {"lib.enumerations": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}}, "df": 6}}}}}}}, "n": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {"lib.enumerations.PolymerList.Density": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.rho": {"tf": 1}}, "df": 2}}}}}, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.e_coeff": {"tf": 1.4142135623730951}, "lib.polymer.Polymer.n_coeff": {"tf": 1.4142135623730951}}, "df": 2, "s": {"docs": {"lib.simulation.Simulation.scenario_flag": {"tf": 1}}, "df": 1}}}}}, "r": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.water.Water.compute_viscosity": {"tf": 1}}, "df": 1}}}}}}}}}}, "p": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.water.Water.compute_mobility": {"tf": 1}}, "df": 1}}}}}}}}, "u": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {"lib.enumerations": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}}, "df": 6}}}, "r": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.simulation.Simulation.__init__": {"tf": 1}, "lib.simulation.Simulation.run": {"tf": 1}}, "df": 2}}}}}, "x": {"docs": {"lib.grid.Grid.left": {"tf": 1}, "lib.grid.Grid.right": {"tf": 1}, "lib.grid.Grid.get_spacing": {"tf": 1}, "lib.grid.Grid.dx": {"tf": 1}, "lib.polymer.Polymer.divergence": {"tf": 1}}, "df": 5}, "y": {"docs": {"lib.grid.Grid.bottom": {"tf": 1}, "lib.grid.Grid.top": {"tf": 1}, "lib.grid.Grid.get_spacing": {"tf": 1}, "lib.grid.Grid.dy": {"tf": 1}, "lib.polymer.Polymer.divergence": {"tf": 1}}, "df": 5}, "\u03c3": {"docs": {}, "df": 0, "/": {"docs": {}, "df": 0, "d": {"docs": {"lib.surfactant.Surfactant.eval_dIFT_dGamma": {"tf": 1}}, "df": 1}}}}, "n": {"docs": {"lib.enumerations.PolymerList.n_coeff": {"tf": 1.4142135623730951}, "lib.grid.FEMesh.__init__": {"tf": 1}, "lib.polymer.Polymer.n_coeff": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1}}, "df": 4, "o": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "e": {"docs": {"lib.Exceptions.UserInputException.__init__": {"tf": 1}, "lib.polymer.Polymer.concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.viscosity_matrix": {"tf": 1}, "lib.polymer.Polymer.viscosity_scalar": {"tf": 1}, "lib.polymer.Polymer.shear_rate": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.surfactant.Surfactant.concentration_matrix": {"tf": 1}, "lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1.4142135623730951}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 11}}, "r": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.polymer.Polymer.shear_rate": {"tf": 1}}, "df": 1}}}}, "t": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.surfactant.Surfactant.is_surfactant": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1}, "lib.water.Water.initialize": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1.4142135623730951}}, "df": 7}}, "e": {"docs": {}, "df": 0, "w": {"docs": {"lib.enumerations.SimulationConstants": {"tf": 1}}, "df": 1}, "e": {"docs": {}, "df": 0, "d": {"docs": {"lib.enumerations.SurfactantList": {"tf": 1}, "lib.grid.Grid": {"tf": 1}, "lib.grid.FEMesh": {"tf": 1}}, "df": 3, "e": {"docs": {}, "df": 0, "d": {"docs": {"lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1.4142135623730951}}, "df": 2}}}}, "u": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "n": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1.4142135623730951}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 2}}}}}}, "u": {"docs": {}, "df": 0, "m": {"docs": {"lib.grid.FEMesh.__init__": {"tf": 1.4142135623730951}}, "df": 1, "b": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.grid.Grid.m": {"tf": 1}, "lib.grid.Grid.n": {"tf": 1}, "lib.water.Water.init_aqueous_saturation": {"tf": 1}, "lib.water.Water.init_oleic_saturation": {"tf": 1}}, "df": 4, "s": {"docs": {"lib.water.Water.compute_residual_saturations": {"tf": 1}}, "df": 1}}}}}}, "+": {"1": {"docs": {"lib.grid.Grid.get_flat_index_matrix": {"tf": 1}}, "df": 1}, "docs": {}, "df": 0}, "w": {"docs": {"lib.grid.FEMesh.set_triangulation": {"tf": 1}}, "df": 1}, "a": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {"lib.polymer.Polymer.name": {"tf": 1.4142135623730951}, "lib.surfactant.Surfactant.name": {"tf": 1.4142135623730951}}, "df": 2}}}, "p": {"docs": {"lib.polymer.Polymer.concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.viscosity_matrix": {"tf": 1}, "lib.polymer.Polymer.shear_rate": {"tf": 1}, "lib.polymer.Polymer.phi": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1.7320508075688772}, "lib.polymer.Polymer.compute_concentration": {"tf": 2.23606797749979}, "lib.polymer.Polymer.divergence": {"tf": 1.7320508075688772}, "lib.simulation.Simulation.phi": {"tf": 1}, "lib.simulation.Simulation.KK": {"tf": 1}, "lib.simulation.Simulation.COC": {"tf": 1}, "lib.simulation.Simulation.miuaTcal": {"tf": 1}, "lib.simulation.Simulation.lambdaTcal": {"tf": 1}, "lib.simulation.Simulation.MFW": {"tf": 1}, "lib.simulation.Simulation.source_prod_flow": {"tf": 1}, "lib.surfactant.Surfactant.concentration_matrix": {"tf": 1}, "lib.surfactant.Surfactant.phi": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1.7320508075688772}, "lib.water.Water.water_saturation": {"tf": 1}, "lib.water.Water.viscosity_array": {"tf": 1}, "lib.water.Water.phi": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1.7320508075688772}, "lib.water.Water.compute_residual_saturations": {"tf": 1.7320508075688772}, "lib.water.Water.compute_mobility": {"tf": 1.4142135623730951}, "lib.water.Water.compute_water_saturation": {"tf": 2.23606797749979}}, "df": 24}, "d": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "y": {"docs": {"lib.polymer.Polymer.concentration_matrix": {"tf": 1}, "lib.polymer.Polymer.viscosity_matrix": {"tf": 1}, "lib.polymer.Polymer.shear_rate": {"tf": 1}, "lib.polymer.Polymer.phi": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1.7320508075688772}, "lib.polymer.Polymer.compute_concentration": {"tf": 2.23606797749979}, "lib.polymer.Polymer.divergence": {"tf": 1.7320508075688772}, "lib.simulation.Simulation.phi": {"tf": 1}, "lib.simulation.Simulation.KK": {"tf": 1}, "lib.simulation.Simulation.COC": {"tf": 1}, "lib.simulation.Simulation.miuaTcal": {"tf": 1}, "lib.simulation.Simulation.lambdaTcal": {"tf": 1}, "lib.simulation.Simulation.MFW": {"tf": 1}, "lib.simulation.Simulation.source_prod_flow": {"tf": 1}, "lib.surfactant.Surfactant.concentration_matrix": {"tf": 1}, "lib.surfactant.Surfactant.phi": {"tf": 1}, "lib.surfactant.Surfactant.compute_concentration": {"tf": 1.7320508075688772}, "lib.water.Water.water_saturation": {"tf": 1}, "lib.water.Water.viscosity_array": {"tf": 1}, "lib.water.Water.phi": {"tf": 1}, "lib.water.Water.compute_viscosity": {"tf": 1.7320508075688772}, "lib.water.Water.compute_residual_saturations": {"tf": 1.7320508075688772}, "lib.water.Water.compute_mobility": {"tf": 1.4142135623730951}, "lib.water.Water.compute_water_saturation": {"tf": 2.23606797749979}}, "df": 24}}}}}}, "m": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "c": {"docs": {"lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 1}}}}}, "b": {"docs": {"lib.grid.Grid.A": {"tf": 1}, "lib.grid.Grid.B": {"tf": 1.4142135623730951}, "lib.grid.FEMesh.A": {"tf": 1}, "lib.grid.FEMesh.B": {"tf": 1.4142135623730951}}, "df": 4, "y": {"docs": {"lib.enumerations": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.grid.FEMesh.set_triangulation": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}}, "df": 7}, "h": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "v": {"docs": {"lib.enumerations": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}}, "df": 6}}}}}}, "e": {"docs": {"lib.enumerations.PolymerList": {"tf": 1}, "lib.enumerations.SurfactantList": {"tf": 1}, "lib.enumerations.ModelType": {"tf": 1}, "lib.enumerations.PlotType": {"tf": 1}, "lib.grid.FEMesh.right_hand": {"tf": 1}}, "df": 5, "t": {"docs": {}, "df": 0, "w": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {"lib.enumerations.SurfactantList.IFT_equation": {"tf": 1}}, "df": 1}}}}}, "e": {"docs": {}, "df": 0, "n": {"docs": {"lib.grid": {"tf": 1}, "lib.simulation": {"tf": 1}}, "df": 2}}, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.grid.FEMesh.set_right_hand": {"tf": 1}, "lib.simulation.Simulation.model_type": {"tf": 1}, "lib.simulation.Simulation.relative_permeability_formula": {"tf": 1}, "lib.water.Water.water_saturation": {"tf": 1}}, "df": 4}}}, "l": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "w": {"docs": {"lib.water.Water.init_aqueous_saturation": {"tf": 1}, "lib.water.Water.init_oleic_saturation": {"tf": 1}}, "df": 2}}}}, "a": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "d": {"docs": {"lib.enumerations.PolymerList.get_by_value": {"tf": 1}, "lib.enumerations.SurfactantList.get_by_value": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1.4142135623730951}, "lib.simulation.Simulation": {"tf": 1}, "lib.simulation.Simulation.permeability_flag": {"tf": 1}, "lib.simulation.Simulation.reservoir_geometry": {"tf": 1}, "lib.simulation.Simulation.model_type": {"tf": 1}, "lib.simulation.Simulation.relative_permeability_formula": {"tf": 1}, "lib.simulation.Simulation.scenario_flag": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}}, "df": 10}}, "i": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "y": {"docs": {"lib.simulation.Simulation.integrated_inlet_flow": {"tf": 1}}, "df": 1}}}}}}}}, "o": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "m": {"docs": {"lib.grid.Grid.bottom": {"tf": 1}}, "df": 1}}}}, "u": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "y": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1.4142135623730951}}, "df": 1}}}}}}, "o": {"docs": {}, "df": 0, "l": {"docs": {"lib.water.Water.compute_mobility": {"tf": 1}}, "df": 1, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {"lib.water.Water.compute_mobility": {"tf": 1}}, "df": 1}}}}}}, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"lib.grid.FEMesh.set_triangulation": {"tf": 1}}, "df": 1}}, "o": {"docs": {}, "df": 0, "n": {"docs": {"lib.grid.FEMesh.set_triangulation": {"tf": 1}}, "df": 1}}}}}}}, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {"lib.surfactant.Surfactant.compute_concentration": {"tf": 1}}, "df": 1}}}}}}}, "u": {"docs": {}, "df": 0, "t": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1}}, "df": 1}}, "/": {"docs": {}, "df": 0, "t": {"docs": {"lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}}, "df": 1}}}, "k": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {"lib.enumerations": {"tf": 1}, "lib.grid": {"tf": 1}, "lib.polymer": {"tf": 1}, "lib.simulation": {"tf": 1}, "lib.surfactant": {"tf": 1}, "lib.water": {"tf": 1}}, "df": 6}}}}, "r": {"docs": {}, "df": 0, "w": {"docs": {"lib.enumerations.RelativePermeabilityFormula": {"tf": 1}}, "df": 1}, "o": {"docs": {"lib.enumerations.RelativePermeabilityFormula": {"tf": 1}}, "df": 1}}, "k": {"docs": {"lib.simulation.Simulation.KK": {"tf": 1}}, "df": 1}}, "l": {"docs": {"lib.grid.FEMesh.L": {"tf": 1}}, "df": 1, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.PolymerList": {"tf": 1}, "lib.enumerations.SurfactantList": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.water.Water.compute_residual_saturations": {"tf": 1}}, "df": 4, "[": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {"lib.enumerations.PolymerList.n_coeff": {"tf": 1}, "lib.enumerations.PolymerList.e_coeff": {"tf": 1}, "lib.polymer.Polymer.e_coeff": {"tf": 1}, "lib.polymer.Polymer.n_coeff": {"tf": 1}}, "df": 4}}}}}}}}, "n": {"docs": {}, "df": 0, "e": {"docs": {"lib.grid.FEMesh.set_triangulation": {"tf": 1}}, "df": 1}}}, "a": {"docs": {}, "df": 0, "w": {"docs": {"lib.enumerations.PolymerList.n_coeff": {"tf": 1}, "lib.enumerations.PolymerList.e_coeff": {"tf": 1}, "lib.polymer.Polymer.e_coeff": {"tf": 1}, "lib.polymer.Polymer.n_coeff": {"tf": 1}}, "df": 4}, "m": {"docs": {}, "df": 0, "b": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "a": {"docs": {"lib.enumerations.SurfactantList.IFT_equation": {"tf": 1}, "lib.enumerations.SurfactantList.derivative_IFT_equation": {"tf": 1}, "lib.surfactant.Surfactant.IFT_conc_equ": {"tf": 1}, "lib.surfactant.Surfactant.derivative_IFT_conc_equ": {"tf": 1}}, "df": 4, "t": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"lib.simulation.Simulation.lambdaTcal": {"tf": 1}}, "df": 1}}}}}}}}}, "e": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "t": {"docs": {"lib.grid.Grid.left": {"tf": 1}}, "df": 1}}}, "o": {"docs": {}, "df": 0, "w": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"lib.grid.FEMesh.L": {"tf": 1}}, "df": 1}}}, "o": {"docs": {}, "df": 0, "p": {"docs": {"lib.simulation.Simulation.run": {"tf": 1}}, "df": 1}}}, "{": {"docs": {}, "df": 0, "i": {"docs": {"lib.grid.FEMesh.set_triangulation": {"tf": 1}}, "df": 1}}}, "x": {"docs": {"lib.grid.Grid.get_meshgrid": {"tf": 1}, "lib.grid.Grid.set_FD_meshgrid": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.polymer.Polymer.divergence": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 6, "m": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "d": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 2}}}}, "y": {"docs": {"lib.grid.Grid.get_meshgrid": {"tf": 1}, "lib.grid.Grid.set_FD_meshgrid": {"tf": 1}, "lib.polymer.Polymer.compute_viscosity": {"tf": 1}, "lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.polymer.Polymer.divergence": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 6, "m": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "d": {"docs": {"lib.polymer.Polymer.compute_concentration": {"tf": 1}, "lib.water.Water.compute_water_saturation": {"tf": 1}}, "df": 2}}}}, "j": {"docs": {"lib.grid.FEMesh.set_triangulation": {"tf": 2}}, "df": 1}, "q": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {"lib.polymer.Polymer.concetration_scalar": {"tf": 1}, "lib.polymer.Polymer.viscosity_scalar": {"tf": 1}, "lib.surfactant.Surfactant.concentration": {"tf": 1}, "lib.water.Water.compute_mobility": {"tf": 1}}, "df": 4}}}}}}}, "m": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "d": {"docs": {"lib.water.Water.compute_water_saturation": {"tf": 1.4142135623730951}}, "df": 1}}}}}}}, "pipeline": ["trimmer"], "_isPrebuiltIndex": true}; + + // mirrored in build-search-index.js (part 1) + // Also split on html tags. this is a cheap heuristic, but good enough. + elasticlunr.tokenizer.setSeperator(/[\s\-.;&_'"=,()]+|<[^>]*>/); + + let searchIndex; + if (docs._isPrebuiltIndex) { + console.info("using precompiled search index"); + searchIndex = elasticlunr.Index.load(docs); + } else { + console.time("building search index"); + // mirrored in build-search-index.js (part 2) + searchIndex = elasticlunr(function () { + this.pipeline.remove(elasticlunr.stemmer); + this.pipeline.remove(elasticlunr.stopWordFilter); + this.addField("qualname"); + this.addField("fullname"); + this.addField("annotation"); + this.addField("default_value"); + this.addField("signature"); + this.addField("bases"); + this.addField("doc"); + this.setRef("fullname"); + }); + for (let doc of docs) { + searchIndex.addDoc(doc); + } + console.timeEnd("building search index"); + } + + return (term) => searchIndex.search(term, { + fields: { + qualname: {boost: 4}, + fullname: {boost: 2}, + annotation: {boost: 2}, + default_value: {boost: 2}, + signature: {boost: 2}, + bases: {boost: 2}, + doc: {boost: 1}, + }, + expand: true + }); +})(); \ No newline at end of file diff --git a/lib/Exceptions.py b/lib/Exceptions.py index 8adc149..0a05e55 100644 --- a/lib/Exceptions.py +++ b/lib/Exceptions.py @@ -2,16 +2,23 @@ class OutOfRangeError(Exception): """Exception raised for errors in the input if it is out of range.""" def __init__(self, value, message="Value is out of the allowed range."): - self.value = value - self.message = message + """ + Args: + ----- + value (float): value that the user provided in GUI + message (str): Error message + """ + self._value = value + self._message = message super().__init__(self.message) def __str__(self): """ - :return: Returns the error message - :rtype: str + Returns: (str) + -------------- + Returns the error message """ - return f"{self.value} -> {self.message}" + return f"{self._value} -> {self._message}" class SimulationCalcInputException(Exception): @@ -22,18 +29,22 @@ class SimulationCalcInputException(Exception): def __init__(self, message): """ constructor exception object - - :param message: takes in the error message - :type message: str + + Args: + ----- + message (str): takes in the error message """ - self.message = message + self._message = message def __str__(self): """ - :return: Returns the error message - :rtype: str + Returns: (str) + -------------- + Returns the error message """ - return self.message + return self._message + + class UserInputException(Exception): @@ -45,19 +56,19 @@ def __init__(self, message: str, inputs: dict | None = None): """ Initialize the exception with a message and optional input dictionary. - :param message: Description of the validation error. - :type message: str - - :param inputs: Dictionary of user inputs (optional). - :type inputs: dict, None + Args: + ----- + message (str): Description of the validation error. + inputs (dict, None): Dictionary of user inputs (optional). """ super().__init__(message) - self.message = message - self.user_inputs = inputs or {} + self._message = message + self._user_inputs = inputs or {} def __str__(self): """ - :return: Returns the error message - :rtype: str + Returns: (str) + -------------- + Returns the error message """ - return f"UserInputException: {self.message}" + return f"UserInputException: {self._message}" diff --git a/lib/enumerations.py b/lib/enumerations.py index e1aa936..8e5be13 100644 --- a/lib/enumerations.py +++ b/lib/enumerations.py @@ -62,22 +62,37 @@ class PolymerList(Enum): @property def Id(self): + """ + Id (int): Index for Polymer + """ return self.value[0] @property def Density(self): # kg/m^3 + """ + Density (float): density of the Polymer + """ return self.value[1] @property def n_coeff(self): # dimensionless + """ + n_coeff (list[float]): 'n' coeffient for the empirical power law equation + """ return self.value[2] @property def e_coeff(self): # dimensionless + """ + e_coeff (list[float]): 'ε' coeffient for the empirical power law equation + """ return self.value[3] @classmethod def get_by_value(cls, value): + """ + retrieves Polymer from enumeration based on value + """ member = next((member for member in cls if member.value[0] == value), None) return member @@ -98,18 +113,30 @@ class SurfactantList(Enum): @property def Id(self): + """ + Id (int): Index for Polymer + """ return self.value[0] @property def IFT_equation(self): + """ + IFT_equation (lambda): the relationship between surfactant concentration and interfacial tension + """ return self.value[1] @property def derivative_IFT_equation(self): + """ + derivative_IFT_equation (lambda): the derivative of the IFT_equation + """ return self.value[2] @classmethod def get_by_value(cls, value): + """ + retrieves Surfactant from enumeration based on value + """ member = next((member for member in cls if member.value[0] == value), None) return member diff --git a/lib/grid.py b/lib/grid.py index da24023..05d0df8 100644 --- a/lib/grid.py +++ b/lib/grid.py @@ -1,3 +1,13 @@ +""" +This python script contains the class definition for running simulations + +This Python code has been derived from the MATLAB Surfactant-Polymer Flooding Simulation +developed by Sourav Dutta and Rohit Mishra. + +@author: Bhargav Akula Ramesh Kumar and Carlos Acosta Caripo + +""" + import numpy as np from scipy.sparse import coo_matrix from matplotlib.tri import Triangulation @@ -6,6 +16,8 @@ class Grid: """ Encapsulates mesh generation, triangulation, FEM matrix assembly, and source vector setup. + + FIXME: Need to refactor this class to make it more understandable """ def __init__( @@ -24,27 +36,124 @@ def __init__( self.bottom = bottom self.top = top - ## FIXME: properties here need to be adjusted based on changes to the corresponding methods - self.tri = None self.A = None self.B = None - self.RHS = None + + _m = None + @property + def m(self): + """ + The number of columns + """ + return self._m + @m.setter + def m(self, value): + self._m = value + + _n = None + @property + def n(self): + """ + The number of rows + """ + return self._n + @n.setter + def n(self, value): + self._n = value + + _left = None + @property + def left(self): + """ + left most value on grid. Used to compute ``dx``. Has a default value of 0 + """ + return self._left + @left.setter + def left(self, value): + self._left = value + + _right = None + @property + def right(self): + """ + right most value on grid. Used to compute ``dx``. Has a default value of 1. + """ + return self._right + @right.setter + def right(self, value): + self._right = value + + _top = None + @property + def top(self): + """ + Top most value on grid. Used to compute ``dy``. Has a default value of 1. + """ + return self._top + @top.setter + def top(self, value): + self._top = value + + _bottom = None + @property + def bottom(self): + """ + Bottom most value on grid. Used to compute ``dy``. Has a default value of 0. + """ + return self._bottom + @bottom.setter + def bottom(self, value): + self._bottom = value + + _A = None + @property + def A(self): + """ + A matrix for solving Ax = b + """ + return self._A + @A.setter + def A(self, value): + self._A = value + + _B = None + @property + def B(self): + """ + b matrix for solving Ax = b + """ + return self._B + @B.setter + def B(self, value): + self._B = value @property def get_spacing(self): + """ + Provides dx and dy + """ return self.dx, self.dy @property def get_meshgrid(self): + """ + Generates the x and y coordinates for the FD Mesh + """ self.x, self.y = self.set_FD_meshgrid() return self.x, self.y @property def dx(self): + """ + Computes ``dx`` + """ return (self.right - self.left) / self.m @property def dy(self): + """ + Computes ``dy`` + """ return (self.top - self.bottom) / self.n def set_FD_meshgrid(self): @@ -69,6 +178,13 @@ def get_flat_index_matrix(self) -> np.ndarray: class FEMesh(Grid): def __init__(self, m: int, n: int): + """ + Constructor for the ``FEMesh`` class (subclass of the ``Grid`` class) + + Args: + m (int): num columns + n (int): num rows + """ super().__init__(m, n) self.U = None self.L = None @@ -78,15 +194,72 @@ def __init__(self, m: int, n: int): self.B = None self.sparsed_A = None + _sparsed_A = None + @property + def sparsed_A(self): + """ + sparsed matrix version of matrix ``A`` + """ + return self._sparsed_A + @sparsed_A.setter + def sparsed_A(self, value): + self._sparsed_A = value + + _grid_size = None + @property + def grid_size(self): + """ + row size of square grid (# rows = # cols) + """ + return self._grid_size + @grid_size.setter + def grid_size(self, value): + self._grid_size = value + + _right_hand = None + @property + def right_hand(self): + """ + Matrix representation of the rhs of the global pressure and velocity equations that will subsequently be used + to solve for the global pressure and velocity matrices. + """ + return self._right_hand + @right_hand.setter + def right_hand(self, value): + self._right_hand = value + + _U = None + @property + def U(self): + """ + U = cell array with each element = array of vertices of Upper Triangle of + the rectangular cell + """ + return self._U + @U.setter + def U(self, value): + self._U = value + + _L = None + @property + def L(self): + """ + L = cell array with each element = array of vertices of Lower Triangle of + the rectangular cell + """ + return self._L + @L.setter + def L(self, value): + self._L = value + def set_triangulation(self): - # Setting up triangulations for the FEM grid - # U = cell array with each element = array of vertices of Upper Triangle of - # the rectangular cell - # L = cell array with each element = array of vertices of Lower Triangle of - # the rectangular cell - # At every point (i,j), U{i,j} & L{i,j} are cells with coordinates of vertices - # of the two triangles obtained by bisecting the rectangle starting at - # (i,j). The bisection line goes from NW to SE. + """ + Setting up triangulations for the FEM grid + + At every point (i,j), U{i,j} & L{i,j} are cells with coordinates of vertices + of the two triangles obtained by bisecting the rectangle starting at + (i,j). The bisection line goes from NW to SE. + """ self.U = np.empty((self.m, self.n), dtype=object) self.L = np.empty((self.m, self.n), dtype=object) @@ -115,12 +288,12 @@ def _polyarea(self, x, y): Calculate the area of a polygon using the Shoelace formula. The vertices are defined by the x and y coordinates. - Parameters: - x (list or array): x-coordinates of the polygon vertices - y (list or array): y-coordinates of the polygon vertices + Args: + x (list or array): x-coordinates of the polygon vertices + y (list or array): y-coordinates of the polygon vertices - Returns: - float: Area of the polygon + Returns: (float) + Area of the polygon """ return 0.5 * abs( sum(x[i] * y[i + 1] - y[i] * x[i + 1] for i in range(-1, len(x) - 1)) @@ -147,14 +320,22 @@ def _set_FE_meshgrid_helper(self, T, beta, V): """ Evaluates beta at the vertices of the element triangle - Input: - % T is a structure array with fields x & y where - % T.x contains x coordinates of vertices of an element triangle - % T.y contains y coordinates of vertices of an element triangle - % beta is the average of the value at the vertices of the - % coefficient $$\beta = K(x) \lambda(s,c,\Gamma)$$ + Information from MATLAB: + % T is a structure array with fields x & y where + % T.x contains x coordinates of vertices of an element triangle + % T.y contains y coordinates of vertices of an element triangle + % beta is the average of the value at the vertices of the + % coefficient $$\beta = K(x) \lambda(s,c,\Gamma)$$ + + Analogous to the weak.m function in the MATLAB code - Analogous to the weak.m function in the MATLAB code + Args: + T: T is a structure array with fields x & y where + beta: beta is the average of the value at the vertices of the coefficient $$\beta = K(x) \lambda(s,c,\Gamma)$$ + V: FIXME: Need to add parameter definition here + + Returns: + FIXME: need to add definition here """ beta_1 = self._beta_func(T["x"][0], T["y"][0], beta) beta_2 = self._beta_func(T["x"][1], T["y"][1], beta) @@ -324,6 +505,9 @@ def set_FE_meshgrid(self, beta): self.grid_size[j, l] = grid def set_right_hand(self, source_prod_matrix): + """ + Sets the right hand side of the equation being solved to update the global pressure and velocity matrices + """ self.right_hand = np.zeros(((self.m + 1) * (self.n + 1), 1)) for j in range(self.m + 1): diff --git a/lib/polymer.py b/lib/polymer.py index 6ab7e31..2fb08cc 100644 --- a/lib/polymer.py +++ b/lib/polymer.py @@ -35,36 +35,6 @@ def __init__( ): """ Initializes a instance of the polymer class - - :param name: Name of the polymer - :type name: enum 'PolymerList' - - :param e_coeff: The coefficients used to determine epsilon for the empirical power law expression used to determine the viscosity of the aqueous phase - :type e_coeff: list - - :param n_coeff: The coefficients used to determine epsilon for the empirical power law expression used to determine the viscosity of the aqueous phase - :type n_coeff: list - - :param rho: Density of polymer - :type rho: float - - :param concentration_scalar: Scalar quantity of concentration. When initializing, this param will equal the initial polymer concentration. - :type concentration_scalar: float - - :param phi: arrray used to initialize the concentration matrix (represents porosity of the resevoir) - :type: np.ndarray - - :param viscosity_scalar: scalar quantity of the polymer viscosity - :type viscosity_scalar: float, None - - :param viscosity_matrix: viscosity matrix of the polymer - :type viscosity_matrix: np.ndarray, None - - :param concentration_matrix: matrix representation of polymer concentration within resevoir - :type concentration_matrix: np.ndarray, None - - :param shear_rate: Matrix that will hold the shear rate (the change in velocity normal to the direction of flow) - :type shear_rate: np.ndarray, None """ # PolymerList object @@ -91,16 +61,142 @@ def __init__( # util param for initialization self.phi = phi # Will need to be created in the simulation class + + _name = None + @property + def name(self): + """ + name (enum 'PolymerList'): Name of the polymer + """ + return self._name + @name.setter + def name(self, value): + self._name = value + + _concetration_scalar = None + @property + def concetration_scalar(self): + """ + concentration_scalar (float): Scalar quantity of concentration. When initializing, this param will equal the initial polymer concentration. + """ + return self._concetration_scalar + @concetration_scalar.setter + def concetration_scalar(self, value): + self._concetration_scalar = value + + _init_concentration_matrix = None + @property + def init_concentration_matrix(self): + """ + Initial matrix (at time t = 0) representation of polymer concentration within resevoir + """ + return self._init_concentration_matrix + @init_concentration_matrix.setter + def init_concentration_matrix(self, value): + self._init_concentration_matrix = value + + _concentration_matrix = None + @property + def concentration_matrix(self): + """ + concentration_matrix (np.ndarray, None): matrix representation of polymer concentration within resevoir over time + """ + return self._concentration_matrix + @concentration_matrix.setter + def concentration_matrix(self, value): + self._concentration_matrix = value + + _viscosity_matrix = None + @property + def viscosity_matrix(self): + """ + viscosity_matrix (np.ndarray, None): viscosity matrix of the polymer + """ + return self._viscosity_matrix + @viscosity_matrix.setter + def viscosity_matrix(self, value): + self._viscosity_matrix = value + + _viscosity_scalar = None + @property + def viscosity_scalar(self): + """ + viscosity_scalar (float, None): scalar quantity of the polymer viscosity + """ + return self._viscosity_scalar + @viscosity_scalar.setter + def viscosity_scalar(self, value): + self._viscosity_scalar = value + + _e_coeff = None + @property + def e_coeff(self): + """ + e_coeff (list[float]): The coefficients used to determine epsilon for the empirical power law expression used to determine the viscosity of the aqueous phase + """ + return self._e_coeff + @e_coeff.setter + def e_coeff(self, value): + self._e_coeff = value + + _n_coeff = None + @property + def n_coeff(self): + """ + n_coeff (list[float]): The coefficients used to determine epsilon for the empirical power law expression used to determine the viscosity of the aqueous phase + """ + return self._n_coeff + @n_coeff.setter + def n_coeff(self, value): + self._n_coeff = value + + _rho = None + @property + def rho(self): + """ + rho (float): Density of polymer + """ + return self._rho + @rho.setter + def rho(self, value): + self._rho = value + + _phi = None + @property + def phi(self): + """ + phi (np.ndarray): arrray used to initialize the concentration matrix (represents porosity of the resevoir) + """ + return self._phi + @phi.setter + def phi(self, value): + self._phi = value + + _shear_rate = None + @property + def shear_rate(self): + """ + shear_rate (np.ndarray, None): Matrix that will hold the shear rate (the change in velocity normal to the direction of flow) + """ + return self._shear_rate + @shear_rate.setter + def shear_rate(self, value): + self._shear_rate = value + + + def initialize(self, grid_shape: tuple): """ Will initialize the viscosity, shear_rate, and concentration matrices - - :param grid_shape: contain the shape of the grid - :type grid_shape: tuple - - :return: Initalized Polymer Object - :rtype: Polymer + + Args: + ----- + grid_shape (tuple): contain the shape of the grid + + Returns: (Polymer) + ----------------- + Initalized Polymer Object """ n = grid_shape[0] m = grid_shape[1] @@ -138,24 +234,22 @@ def compute_viscosity( """ Compute polymer viscosity. This function is derived from 'compvis()' in the original MATLAB code (in file compvis.m). + + Args: + ----- + grid (Tuple[NDArray[Any], ...]): The FEM grid used for simulation calculations (x and y variables from the MATLAB code) - :param grid: The FEM grid used for simulation calculations (x and y variables from the MATLAB code) - :type grid: tuple[NDArray[Any], ...] - - :param u: Matrix related to the global pressure - :type u: np.ndarray + u (np.ndarray): Matrix related to the global pressure - :param v: Matrix related to the velocity matrix - :type v: np.ndarray + v (np.ndarray): Matrix related to the velocity matrix - :param model_type: Will state whether the model will include polymer shear thinning or not - :type model_type: enum 'ModelType' + model_type (enum 'ModelType'): Will state whether the model will include polymer shear thinning or not - :param aqueous_viscosity: Aqueous viscosity matrix (will come from the 'Water' class). Only needed when shear thinning OFF - :type aqueous_viscosity: np.ndarray, None - - :return: the viscosity_matrix (index 0) & shear_rate matrix (index 1) for the polymer within the grid - :rtype: list + aqueous_viscosity (np.ndarray, None): Aqueous viscosity matrix (will come from the ``Water`` class). Only needed when shear thinning OFF + + Returns: (list) + --------------- + the viscosity_matrix (index 0) & shear_rate matrix (index 1) for the polymer within the grid """ # x and y components from meshgrid x = grid.x @@ -278,6 +372,36 @@ def compute_concentration( const_parameters: dict, varying_parameters: dict, ): + """ + Computes the polymer concentration + + Raises: + ------- + SimulationCalcInputException: Not all required parameters were provided + + Args: + ----- + grid (Grid): the FDMesh + + water_sat (np.ndarray): the water saturation matrix + + u (np.ndarray): Matrix related to the global pressure + + v (np.ndarray): Matrix related to the velocity matrix + + xmod (np.ndarray): x-dim characteristic coordinates based on Neumann boundary conditions + + ymod (np.ndarray): y-dim characteristic coordinates based on Neumann boundary conditions + + const_parameters (dict): constant parameters to help with calculations + + varying_parameters (dict): parameters that vary but assist with calculations for water saturation, polymer concentration, and surfactant concentration + + Returns: (dict) + --------------- + The varying parameters that were changed in this method + + """ # initializing variables: # Assert statements to ensure that all parameters are property initialized: assert self.concentration_matrix is not None, SimulationCalcInputException( @@ -395,7 +519,19 @@ def divergence(self, Fx, Fy, dx=1.0, dy=1.0): """ Calculates Divergence - :return: Div F = (δfx/δx) + (δfy/δy) + Args: + ----- + Fx (np.ndarray): Function #1 + + Fy (np.ndarray): Function #2 + + dx (float): change in the x-dimension + + dy (float): change in the y-dimension + + Raises: (np.ndarray) + -------------------- + Div F = (δfx/δx) + (δfy/δy) """ dFx_dx = np.gradient(Fx, dx, axis=1) dFy_dy = np.gradient(Fy, dy, axis=0) diff --git a/lib/simulation.py b/lib/simulation.py index d655646..399ffab 100644 --- a/lib/simulation.py +++ b/lib/simulation.py @@ -10,8 +10,6 @@ import os -import numpy as np -import scipy as sp from grid import Grid, FEMesh from enumerations import ( ModelType, @@ -25,6 +23,8 @@ from Exceptions import SimulationCalcInputException, UserInputException from polymer import Polymer from surfactant import Surfactant +import numpy as np +import scipy as sp from water import Water from scipy.io import loadmat from scipy.sparse.linalg import bicgstab @@ -44,12 +44,15 @@ class Simulation: def __init__(self, user_input_dict: dict): """ This method will check the ``user_input_dict`` and initialize the simulation - - :raises UserInputException: If there is a issue with the user inputs in ``user_input_dict`` - :raises SimulationCalcInputException: If there is an issue with the execution of a calculation during runtime - - :param user_input_dict: dictionary containing the information from the GUI - :type user_input_dict: dict + + Raises: + ------ + UserInputException: If there is a issue with the user inputs in ``user_input_dict`` + SimulationCalcInputException: If there is an issue with the execution of a calculation during runtime + + Args: + ----- + user_input_dict (dict): dictionary containing the information from the GUI """ ## Performs checks on the user input dictionary passed in: try: @@ -191,16 +194,201 @@ def __init__(self, user_input_dict: dict): self.MFW = [] self.integrated_inlet_flow = 0 # "src_total" in the MATLAB version of the code - # Dependent Property of Simulation Class - _source_prod_flow = None + # Property of Simulation Class + _grid_size = None + @property + def grid_size(self): + """ + grid_size (float): the dimensions of the square grid + """ + return self._grid_size + @grid_size.setter + def grid_size(self, value): + self._grid_size = value + + _source_flow_magnitude = None + @property + def source_flow_magnitude(self): + """ + source_flow_magnitude (float): flow rate at injection site + """ + return self._source_flow_magnitude + @source_flow_magnitude.setter + def source_flow_magnitude(self, value): + self._source_flow_magnitude = value + + _permeability_flag = None + @property + def permeability_flag(self): + """ + permeability_flag (enum 'PermeabilityType'): sets the permeability field based on enum ``PermeabilityType`` + """ + return self._permeability_flag + @permeability_flag.setter + def permeability_flag(self, value): + self._permeability_flag = value + _reservoir_geometry = None + @property + def reservoir_geometry(self): + """ + reservoir_geometry (enum 'ResevoirGeometry'): sets the reservoir geometry based on the enum ``ResevoirGeometry`` + """ + return self._reservoir_geometry + @reservoir_geometry.setter + def reservoir_geometry(self, value): + self._reservoir_geometry = value + + _model_type = None + @property + def model_type(self): + """ + model_type (enum 'ModelType'): sets the type of simulation being run based on the enum ``ModelType`` + """ + return self._model_type + @model_type.setter + def model_type(self, value): + self._model_type = value + + _relative_permeability_formula = None + @property + def relative_permeability_formula(self): + """ + relative_permeability_formula (enum 'RelativePermeabilityFormula'): sets the type of permeability formula being used in the simulation, based on the enum ``RelativePermeabilityFormula`` + """ + return self._relative_permeability_formula + @relative_permeability_formula.setter + def relative_permeability_formula(self, value): + self._relative_permeability_formula = value + + _phi = None + @property + def phi(self): + """ + phi (np.ndarray): porosity matrix + """ + return self._phi + @phi.setter + def phi(self, value): + self._phi = value + + _KK = None + @property + def KK(self): + """ + KK (np.ndarray): the permeability matrix + """ + return self._KK + @KK.setter + def KK(self, value): + self._KK = value + + _time_step = None + @property + def time_step(self): + """ + time_step (float): The Δt + """ + return self._time_step + @time_step.setter + def time_step(self, value): + self._time_step = value + + _polymer = None + @property + def polymer(self): + """ + polymer (Polymer): Holds the ``Polymer`` object + """ + return self._polymer + @polymer.setter + def polymer(self, value): + self._polymer = value + + _surfactant = None + @property + def surfactant(self): + """ + surfactant (Surfactant): Holds the ``Surfactant`` object + """ + return self._surfactant + @surfactant.setter + def surfactant(self, value): + self._surfactant = value + + _water = None + @property + def water(self): + """ + water (Water): Holds the ``Water`` object + """ + return self._water + @water.setter + def water(self, value): + self._water = value + + _COC = None + @property + def COC(self): + """ + COC (np.ndarray): An array that holds the cummulative oil captured + """ + return self._COC + @COC.setter + def COC(self, value): + self._COC = value + + _miuaTcal = None + @property + def miuaTcal(self): + """ + miuTcal (np.ndarray): An array that caputres the change in the total aqueous viscosity over time + """ + return self._miuaTcal + @miuaTcal.setter + def miuaTcal(self, value): + self._miuaTcal = value + + _lambdaTcal = None + @property + def lambdaTcal(self): + """ + lambdaTcal (np.ndarray): Array that holds the change in the total mobility (λ_T = λ_a + λ_o) + """ + return self._lambdaTcal + @lambdaTcal.setter + def lambdaTcal(self, value): + self._lambdaTcal = value + + _MFW = None + @property + def MFW(self): + """ + MFW (np.ndarray): Array that holds change in the MFW (mean finger width) + """ + return self._MFW + @MFW.setter + def MFW(self, value): + self._MFW = value + + _integrated_inlet_flow = None + @property + def integrated_inlet_flow(self): + """ + integrated_inlet_flow (float): Basically the integrating the source flow rate over time + """ + return self._integrated_inlet_flow + @integrated_inlet_flow.setter + def integrated_inlet_flow(self, value): + self._integrated_inlet_flow = value + + _source_prod_flow = None @property def source_prod_flow(self): """ - Return - ------ - :return: returns the matrix with the source & and production well flow rates - :rtype: np.ndarray + source_prod_flow (np.ndarray): The matrix with the source & and production well flow rates + + assuming that the source flow = production well flow (flow magnitudes are the same!) """ # setting permeability state if self._source_prod_flow is None: @@ -235,9 +423,12 @@ def source_prod_flow(self): return self._source_prod_flow _scenario_flag = None - @property def scenario_flag(self): + """ + Determines the scenario based on the chosen reservoir geometry and permeability. + Returns the integer value that represents a type of scenario run + """ if self._scenario_flag is None: bool_Homogenous_and_Rectilinear = ( self.permeability_flag.value == PermeabilityType.Homogenous.value @@ -273,10 +464,9 @@ def _initialize_pressure_and_velocity(self): Initializing global pressure ('u') and velocity matrices ('v') Will use the ``n`` and ``m`` properties from ``Grid`` Class for initialization - Return - ------ - :return: the global pressure matrix (index 0) and velocity matrix (index 1) - :rtype: list[np.ndarray] + Returns: (tuple[np.ndarray, np.ndarray]) + ---------------------------------------- + The global pressure matrix (index 0) and velocity matrix (index 1) """ u = np.zeros((self.mesh.n + 1, self.mesh.m + 1), dtype=np.complex128) v = np.zeros((self.mesh.n + 1, self.mesh.m + 1), dtype=np.complex128) @@ -289,9 +479,10 @@ def _compute_pressure_and_velocity_matrices(self, sparsed_A, B, beta): dependent property to calculate the pressure matrix (``u``) and velocity matrix (``v``). Will rely on functions in the ``FEMesh`` class. - - :return: list of update pressure matrix and velocity matrix => [u,v] - :rtype: list[np.ndarray] + + Returns: (list[np.ndarray]) + --------------------------- + List of update pressure matrix and velocity matrix => [u,v] """ max_iterations = 1000 new_u, convergence_flag = bicgstab( @@ -314,10 +505,13 @@ def _compute_pressure_and_velocity_matrices(self, sparsed_A, B, beta): def _get_gradient(self, vn): """ - Helper function to determine the gradients with respect to x and y dimensions + (private method) - :return: tuple with px py which are numpy matrices that hold the gradient wrt to x and y dimensions - :rtype: tuple[_Array[tuple[int, int], float64], NDArray[float64]] + Helper function to determine the gradients with respect to x and y dimensions + + Returns: (tuple[_Array[tuple[int, int], float64], NDArray[float64]]) + -------------------------------------------------------------------- + Tuple with px py which are numpy matrices that hold the gradient wrt to x and y dimensions """ m = self.mesh.m n = self.mesh.n @@ -351,9 +545,10 @@ def _initialize_memmap_properties(self): Will initialize the ``ProdRate`` and ``CROIP`` properties. Using memmaps to allow window's users to run program. - - :return: Initialized ``ProdRate`` and ``CROIP`` properties - :rtype: list + + Returns: (tuple[np.ndarray, np.ndarray]) + ---------------------------------------- + Initialized ``ProdRate`` and ``CROIP`` properties """ os.makedirs("memmaps", exist_ok=True) tf = 500 @@ -372,8 +567,9 @@ def _create_mesh(self): """ (private method) - :return: Initialized FD and FE mesh - :rtype: Tuple[Grid, FEMesh] + Returns: (Tuple[Grid, FEMesh]) + ----------------------------- + Initialized FD and FE mesh """ FD_mesh = Grid(self.grid_size, self.grid_size) @@ -387,8 +583,9 @@ def _initialize_simulation(self): Sets up initial reservoir fields, permeability, and time step. - :return: initialized properties of simulation. Required in ``__init__`` function - :rtype: None + Returns: (None) + --------------- + Initialized properties of simulation. Required in ``__init__`` function """ self.phi = self._compute_phi() @@ -407,8 +604,10 @@ def _compute_phi(self): """ (private method) - Compute level set function phi at each grid point. - Equivalent to MATLAB get_phi_test function. + Returns: (np.ndarray) + --------------------- + Computes and returns the level set function phi at each grid point. + (Equivalent to MATLAB get_phi_test function.) """ m = self.mesh.m n = self.mesh.n @@ -428,10 +627,17 @@ def _z_func_test(self, x, y): """ (private method) - Compute the initial position of the water front. - Equivalent to MATLAB z_func_test. + Args: + ----- + x (np.ndarry): x-dimension coordinates + + y (np.ndarray): y-dimension coordinate points + + Returns: + -------- + Compute and returns the initial position of the water front. + (Equivalent to MATLAB z_func_test.) - Takes array user_input_dict x, y. """ init_front_hs = 0.1 bool_Homogenous_and_Rectilinear = ( @@ -462,9 +668,11 @@ def _z_func_test(self, x, y): def _compute_permeability(self): """ (private method) - - Compute permeability matrix KK based on the flag. - Equivalent to MATLAB KKdef function. + + Returns: + ------- + Compute and returns the permeability matrix KK based on the ``scenario_flag``. + (Equivalent to MATLAB KKdef function.) """ bool_Homogenous_and_Rectilinear = ( self.permeability_flag.value == PermeabilityType.Homogenous.value @@ -496,26 +704,6 @@ def _compute_permeability(self): ) + 1 ) - # elif flag == 3: - # # Impermeable block at center - # KK = 3000 * np.ones((m + 1, m + 1)) - # center = m // 2 - # delta = m // 8 - # KK[ - # center - delta : center + delta + 1, - # center - delta : center + delta + 1, - # ] = 3 - # elif flag == 4: - # # Impermeable blocks off-center - # KK = 3000 * np.ones((m + 1, m + 1)) - # KK[ - # (3*m)//4 - m//12 : (3*m)//4 + m//12 + 1, - # (2*m)//3 - m//12 : (2*m)//3 + m//12 + 1 - # ] = 3 - # KK[ - # m//3 - m//10 : m//3 + m//10 + 1, - # m//3 - m//10 : m//3 + m//10 + 1 - # ] = 3 elif bool_Heterogenous_and_Quarter_Five_Spot: # Load Upper Ness formation (SPE10) mat_data = loadmat( @@ -526,14 +714,6 @@ def _compute_permeability(self): "SimulationInputException: KK matrix not found in KK30Ness.mat file." ) KK = mat_data["KK"] - # elif flag == 6: - # # Load Tarbert formation (SPE10) - # mat_data = loadmat('/Resources/KK30Tabert.mat') - # if 'KK' not in mat_data: - # raise SimulationCalcInputException('SimulationInputException: KK matrix not found in KK30Tabert.mat file.') - # KK = mat_data['KK'] - # else: - # raise SimulationCalcInputException("SimulationInputException: Unknown permeability flag.") return KK def _transport_equation_solver(self, dt): @@ -550,7 +730,12 @@ def _transport_equation_solver(self, dt): ds - derivative with respect to water saturation dc - derivative with respect to polymer concentration - :return: tuple[Water, Polymer, Surfactant] + Returns: (tuple[float, float, float]) + ---------------------------------------------------- + tuple[ocut, wcut, ROIP] + ocut - volume of oil in the production well + wcut - volume of water in the production well + ROIP - residual oil in place (as a volume fraction) """ # Initialize constant parameters const_parameters = {} @@ -918,8 +1103,11 @@ def _transport_equation_solver(self, dt): Gmod=Gmod, ) - # Returning updated Water, Polymer, and Surfactant objects - return self.water, self.polymer, self.surfactant + # calculate the Oil capture, water captured, and residual oil in place + ocut = lambda_o[n-1, m-1] * self.source_flow_magnitude / lambda_total[n-1,m-1] + wcut = lambda_a[n-1, m-1] * self.source_flow_magnitude / lambda_total[n-1,m-1] + ROIP = 100*(np.sum(np.sum(1 - self.water.water_saturation)))/np.sum(np.ones((n*m,1))) + return ocut, wcut, ROIP def _characteristic_coordinates( self, @@ -935,6 +1123,22 @@ def _characteristic_coordinates( Compute redefined characteristic coordinates (xmod, ymod) according to Neumann boundary conditions. will be a helper function to the ``self._transport_equation_solver()`` method. + + Args: + ------ + flag (int): scenario flag for the simulation the user wants to run + + old_water_saturation_matrix (np.ndarray): water saturation matrix from previous iteration + + new_water_saturation_matrix (np.ndarray): water saturation from current iteration + + const_parameters (dict): constant parameters to help with calculations + + varying_parameters (dict): parameters that vary but assist with calculations for water saturation, polymer concentration, and surfactant concentration + + Returns: (tuple[np.ndarray, np.ndarray]) + --------------------------------------- + This method returns ``xmod`` and ``ymod``, which are the modified characteristic coordinates according to the Neumann boundary conditions """ assert self.water.water_saturation is not None, SimulationCalcInputException( "SimulationCalcInputError:UnknownWaterSaturationMatrix" @@ -1027,19 +1231,34 @@ def _export_results(self): os.makedirs("sim_results", exist_ok=True) - np.savetxt("sim_results/COC.csv", self.COC, delimiter=",") - if hasattr(self, "lambdaTcal"): - np.savetxt( - "sim_results/lambdaTcal.csv", np.array(self.lambdaTcal), delimiter="," - ) - if hasattr(self, "miuaTcal"): - np.savetxt( - "sim_results/miuaTcal.csv", np.array(self.miuaTcal), delimiter="," - ) + np.savetxt(f"sim_results/COC_scenario_{self.scenario_flag}.csv", self.COC, delimiter=",") + np.savetxt(f"sim_results/MFW_scenario_{self.scenario_flag}.csv", self.MFW, delimiter=",") + np.savetxt(f"sim_results/CROIP_scenario_{self.scenario_flag}.csv", self.CROIP, delimiter=",") + np.savetxt(f"sim_results/ProdRate_scenario_{self.scenario_flag}.csv", self.ProdRate, delimiter=",") + # if hasattr(self, "lambdaTcal"): + # np.savetxt( + # "sim_results/lambdaTcal.csv", np.array(self.lambdaTcal), delimiter="," + # ) + # if hasattr(self, "miuaTcal"): + # np.savetxt( + # "sim_results/miuaTcal.csv", np.array(self.miuaTcal), delimiter="," + # ) print("Simulation sim_results exported to /sim_results/ folder.") def _compute_MFW(self, UU): + """ + (private function) + + Args: + ----- + UU (np.ndarray): water saturation matrix + + Returns: (np.array) + ------- + list of values which are the mean finger width during each iteration. + Note: Only will run under the Rectilinear Homogenous and Rectilinear Heterogeneous simulation scenarios + """ # post processing of finger width interface = np.zeros((29, 1)) mean_UU_save = np.zeros((29, 29)) @@ -1124,11 +1343,10 @@ def _compute_MFW(self, UU): def run(self): """ Executes simulation loop. - - :raises SimulationCalcInputException: if relevant inputs for calculation not provided or not initialized - - :return: Dictionary with relevant results for plotting and data analysis - :rtype: dict + + Raises: + ------ + SimulationCalcInputException: If there is an issue with the execution of a calculation during runtime """ assert self.water.water_saturation is not None, SimulationCalcInputException( "SimulationCalcInputError:WaterSaturationMatrixUnavailable" @@ -1248,11 +1466,26 @@ def run(self): ) ## STEP 2.5: Solving Transport Equations - self._transport_equation_solver(dt) - + ocut, wcut, ROIP = self._transport_equation_solver(dt) + # self._transport_equation_solver(dt) ## Step 2.6: MFW post processing (excluding QFS) if (self.scenario_flag != 3): # FIXME: compute_MFW currently operates for rectilinear geometries. Implement MFW computation for QFS interface, MFW_val, _ = self._compute_MFW(self.water.water_saturation) self.MFW.append(MFW_val) + + ## STEP 2.7: Updating the cummulative oil captured, Production rate, and the residual oil in place + # arrays for exporting to CSV files + if (t_cal == 0): + self.COC[0,t_cal] = ocut + else: + self.COC[0,t_cal] = self.COC[0,t_cal - 1] + ocut + + self.ProdRate[0,t_cal] = ocut/dt + self.CROIP[0,t_cal] = ROIP + + t_cal += 1 + + self._export_results() + except Exception as e: print(e) diff --git a/lib/surfactant.py b/lib/surfactant.py index 0ccec9a..c34e2d5 100644 --- a/lib/surfactant.py +++ b/lib/surfactant.py @@ -8,12 +8,11 @@ """ from types import LambdaType -from enumerations import SimulationConstants, SurfactantList -from grid import Grid -from Exceptions import SimulationCalcInputException import numpy as np -import scipy as sp from scipy.sparse.linalg import bicgstab +from enumerations import SurfactantList +from grid import Grid +from Exceptions import SimulationCalcInputException class Surfactant: @@ -34,24 +33,6 @@ def __init__( ): """ Creates instance of Surfactant class - - :param name: Name of the surfactant - :type name: enum 'SurfactantList' - - :param concentration: Initial concentration in wppm of surfactant (scalar quantity) - :type concentration: float - - :param phi: arrray used to initialize the concentration matrix (represents porosity of the resevoir) - :type: np.ndarray - - :param IFT_conc_equ: expression that relates surfactant concentration to interfacial tension b/t oil and water - :type IFT_conc_equ: lambda, None - - :param derivative_IFT_conc_equ: Deriviative of the equation relating IFT to surfactant concentration - :type derivative_IFT_conc_equ: lambda, None - - :param concentration_matrix: vector representation of surfactant concentration in resevoir - :type concentration_matrix: np.array, None """ self.name = name self.concentration = initial_concentration @@ -61,6 +42,7 @@ def __init__( self.is_surfactant = True if (initial_concentration > 0) else False self.phi = phi + #CLASS PROPERTIES @property def eval_IFT(self): """ @@ -75,22 +57,97 @@ def eval_IFT(self): def eval_dIFT_dGamma(self): # FIXME: Need to adjust when implementing 'autodiff' """ evaluate the dσ/dΓ at a particular surfactant concentration matrix - - FIXME: need to adjust when implementing 'autodiff' """ assert self.derivative_IFT_conc_equ is not None, SimulationCalcInputException( "SimulationCalcInputError:UnknownDerivativeIFTEquation" ) return self.derivative_IFT_conc_equ(self.concentration_matrix) + _name = None + @property + def name(self): + """ + name (enum 'SurfactantList'): Name of the surfactant + """ + return self._name + @name.setter + def name(self, value): + self._name = value + + _concentration = None + @property + def concentration(self): + """ + concentration (float): Initial concentration of surfactant (scalar quantity) + """ + return self._concentration + @concentration.setter + def concentration(self, value): + self._concentration = value + + _concentration_matrix = None + @property + def concentration_matrix(self): + """ + concentration_matrix (np.ndarray, None): vector representation of surfactant concentration in resevoir + """ + return self._concentration_matrix + @concentration_matrix.setter + def concentration_matrix(self, value): + self._concentration_matrix = value + + _IFT_conc_equ = None + @property + def IFT_conc_equ(self): + """ + IFT_conc_equ (lambda, None): expression that relates surfactant concentration to interfacial tension b/t oil and water + """ + return self._IFT_conc_equ + @IFT_conc_equ.setter + def IFT_conc_equ(self, value): + self._IFT_conc_equ = value + + _derivative_IFT_conc_equ = None + @property + def derivative_IFT_conc_equ(self): + """ + derivative_IFT_conc_equ (lambda, None): Deriviative of the equation relating IFT to surfactant concentration + """ + return self._derivative_IFT_conc_equ + @derivative_IFT_conc_equ.setter + def derivative_IFT_conc_equ(self, value): + self._derivative_IFT_conc_equ = value + + _is_surfactant = None + @property + def is_surfactant(self): + """ + flag for whether or not surfactant is in the simulation + """ + return self._is_surfactant + @is_surfactant.setter + def is_surfactant(self, value): + self._is_surfactant = value + + _phi = None + @property + def phi(self): + """ + phi (np.ndarray): arrray used to initialize the concentration matrix (represents porosity of the resevoir) + """ + return self._phi + @phi.setter + def phi(self, value): + self._phi = value + def initialize( self, ): """ This function will initialize the surfactant object - - :return: Surfactant object - :rtype: Surfactant + + Returns: (Surfactant) + Surfactant object """ if self.concentration_matrix is None: if self.phi is None: @@ -110,6 +167,28 @@ def compute_concentration( F: np.ndarray, Gmod: np.ndarray, ): + """ + Computing the surfactant concentration matrix + + Raises: + SimulationCalcInputException: Not all required inputs were provided + + Args: + grid (Grid): FD mesh + + water_sat (np.ndarray): water saturation matrix + + const_parameters (dict): dictionary object with constant parameters used in calculation + + varying_parameters (dict): dictionary object with varying parameters used in calculation + + F (np.ndarray): intermediate matrix used in calcs + + Gmod (np.ndarray): bilinear interpolant for sur conc on redefined coordinates + + Returns: (dict) + Returns the ``varying_parameters`` dict + """ # initializing constants assert self.concentration_matrix is not None, SimulationCalcInputException( "SimuationInputException: polymer concentration matrix not initialized. Please try again" diff --git a/lib/test.py b/lib/test.py index 09627b5..129c773 100644 --- a/lib/test.py +++ b/lib/test.py @@ -50,8 +50,8 @@ user_dict = { "simulation_id": 1, "model_type": MODEL["No_Shear_Thinning"], - "reservoir_geometry": GEOMETRY["Quarter Five Spot"], - "permeability": PERMEABILITY["Heterogeneous"], + "reservoir_geometry": GEOMETRY["Rectilinear"], + "permeability": PERMEABILITY["Homogeneous"], "polymer_type": POLYMER["Xanthane"], "polymer_concentration": 0.001, "surfactant_type": SURFACTANT["Alkyl_Ether_Sulfate"], diff --git a/lib/water.py b/lib/water.py index f29e156..e972933 100644 --- a/lib/water.py +++ b/lib/water.py @@ -10,9 +10,7 @@ ##EXTERNAL IMPORTS import numpy as np import scipy as sp -from scipy.sparse import coo_matrix, csr_matrix, csc_matrix from scipy.linalg import fractional_matrix_power -from scipy.interpolate import RegularGridInterpolator from scipy.sparse.linalg import bicgstab ##INTERNAL IMPORTS @@ -38,25 +36,7 @@ def __init__( phi: np.ndarray, ): """ - Constructor for the 'Water' class - - :param init_water_saturation: initial water saturation - :type init_water_saturation: float - - :param init_aqueous_saturation: initial aqueous phase saturation - :type init_aqueous_saturation: float - - :param init_oleic_saturation: initial oil phase saturation - :type init_oleic_saturation: float - - :param miuw: water viscosity - :type miuw: float - - :param miuo: oil viscosity - :type miuo: float - - :param phi: porosity matrix - :type phi: np.ndarray + Constructor for the ``Water`` class """ self.init_water_saturation = init_water_saturation self.init_aqueous_saturation = init_aqueous_saturation @@ -67,16 +47,117 @@ def __init__( self.viscosity_array = None # aqueous viscosity matrix self.phi = phi - def initialize(self, grid_shape: tuple): + _init_water_saturation = None + @property + def init_water_saturation(self): + """ + init_water_saturation (float): initial residual water saturation + """ + return self._init_water_saturation + @init_water_saturation.setter + def init_water_saturation(self, value): + self._init_water_saturation = value + + _init_aqueous_saturation = None + @property + def init_aqueous_saturation(self): + """ + init_aqueous_saturation (float): initial residual aqueous phase saturation below critical capillary number (when σ = 0) + """ + return self._init_aqueous_saturation + @init_aqueous_saturation.setter + def init_aqueous_saturation(self, value): + self._init_aqueous_saturation = value + + _init_oleic_saturation = None + @property + def init_oleic_saturation(self): + """ + init_oleic_saturation (float): initial residual oil phase saturation below the critical capillary number (when σ = 0) + """ + return self._init_oleic_saturation + @init_oleic_saturation.setter + def init_oleic_saturation(self, value): + self._init_oleic_saturation = value + + _miuw = None + @property + def miuw(self): + """ + miuw (float): water viscosity + """ + return self._miuw + @miuw.setter + def miuw(self, value): + self._miuw = value + + _miuo = None + @property + def miuo(self): + """ + miuo (float): oil viscosity + """ + return self._miuo + @miuo.setter + def miuo(self, value): + self._miuo = value + + _phi = None + @property + def phi(self): + """ + phi (np.ndarray): porosity matrix + """ + return self._phi + @phi.setter + def phi(self, value): + self._phi = value + + _water_saturation = None + @property + def water_saturation(self): + """ + water_saturation (np.ndarray): The water saturation matrix being updated using the transport equations """ - Initializing 'Water' Object properties + return self._water_saturation + @water_saturation.setter + def water_saturation(self, value): + self._water_saturation = value + + _viscosity_array = None + @property + def viscosity_array(self): + """ + viscosity_array (np.ndarray): The water viscosity matrix + """ + return self._viscosity_array + @viscosity_array.setter + def viscosity_array(self, value): + self._viscosity_array = value - :param grid_shape: the n and m parameters from the 'Grid' class - :type grid_shape: tuple - :return: Updated 'Water' object - :rtype: Water + def initialize(self, grid_shape: tuple): """ + Initializing 'Water' object properties + + Raises: + ------- + SimuationInputException: Either Intial water saturation and/or porosity matrix not provided for initializing Water object + + Args: + ----- + grid_shape (tuple): the n and m parameters from the 'Grid' class + + Returns: (Water) + --------------- + Initializes the Water object + """ + assert self.init_water_saturation is not None, SimulationCalcInputException( + "SimuationInputException: Initial water saturation not initialized. Please try again" + ) + assert self.phi is not None, SimulationCalcInputException( + "SimuationInputException: porosity matrix not initialized. Please try again" + ) # getting values for n and m from grid: n, m = grid_shape @@ -104,24 +185,27 @@ def compute_viscosity( """ Compute aqueous viscosity. - :param grid: Grid object for deterrmining matrix size - :type grid: Grid - - :param model_type: Type of model we are running (Polymer shear thinning ON or OFF) - :type model_type: enum 'ModelType' + Raises: + ------- + SimulationCalcInputException: Not all required parameters provided + + Args: + ----- + grid (Grid): Grid object for deterrmining matrix size - :param polymer: holds the information about the polymer in the sim - :type polymer: Polymer + model_type (enum 'ModelType'): Type of model we are running (Polymer shear thinning ON or OFF) - :param u: global pressure matrix. Only needed when shear thinning ON. - :type u: np.ndarray, None + polymer (Polymer): holds the information about the polymer in the sim - :param v: velocity matrix. Only needed when shear thinning ON. - :type v: np.ndarray, None + u (np.ndarray, None): global pressure matrix. Only needed when shear thinning ON. - :return: updated aqueous viscosity matrix - :rtype: np.ndarray + v (np.ndarray, None): velocity matrix. Only needed when shear thinning ON. + + Returns: (np.ndarray) + -------------------- + Updated aqueous viscosity matrix """ + assert self.viscosity_array is not None, SimulationCalcInputException( "SimuationInputException: aqueous viscosity matrix not initialized. Please try again" ) @@ -169,19 +253,6 @@ def compute_viscosity( w2 = rho_water * (1 - polymer.concentration_matrix) wppm = (w1 / (w1 + w2)) * (10**6) - # determining ε and n for power law equation: - # epsilon_val = polymer.e_coeff[0]*(wppm**polymer.e_coeff[1]) - # n_val = min(polymer.n_coeff[0]*(wppm**polymer.n_coeff[1]),1) - - # epsilon_val = np.zeros((np.size(polymer.concentration_matrix, 0), np.size(polymer.concentration_matrix, 1))) - # n_val = np.zeros((np.size(polymer.concentration_matrix, 0), np.size(polymer.concentration_matrix, 1))) - # print(f'type epsilon_0: {np.shape(epsilon_val)}') - # print(f'type n_0: {np.shape(n_val)}') - # for r in range(np.size(polymer.concentration_matrix, 0)): - # for c in range(np.size(polymer.concentration_matrix, 1)): - # # print(f'i: {r} | j: {c}') - # epsilon_val[r,c] = polymer.e_coeff[0] * wppm[r,c] ** polymer.e_coeff[1] - # n_val[r,c] = min(polymer.n_coeff[0] * wppm[r,c] ** polymer.n_coeff[1], 1) eps = 1e-12 wppm_safe = np.maximum(wppm, eps) @@ -217,17 +288,17 @@ def compute_residual_saturations( """ Compute swr, sor based on capillary numbers (came from compres.m MATLAB file) - :param sigma: interfacial tension (IFT) - :type sigma: np.ndarray + Args: + ----- + sigma (np.ndarray): interfacial tension (IFT) - :param u: global pressure matrix. - :type u: np.ndarray + u (np.ndarray): global pressure matrix. - :param v: velocity matrix. - :type v: np.ndarray - - :return residual saturation for oil (index 1) and water (index 0) phases - :rtype: list + v (np.ndarray): velocity matrix. + + Returns: (list) + --------------- + residual saturation for oil (index 1) and water (index 0) phases """ swr0 = self.init_aqueous_saturation sor0 = self.init_oleic_saturation @@ -245,7 +316,7 @@ def compute_residual_saturations( sor = sor0 * (Nco0 / Nco) ** 0.5213 if Nco >= Nco0 else sor0 swr = swr0 * (Nca0 / Nca) ** 0.1534 if Nca >= Nca0 else swr0 - return [swr, sor] # [residual water saturation, residual oil saturation] + return [swr, sor] # [residual aqueous saturation, residual oil saturation] def compute_mobility( self, @@ -258,27 +329,28 @@ def compute_mobility( ): """ Computing mobility (made using the compmob.m MATLAB file) + + Raise: + ------ + SimulationCalcInputException: Not all required arguments are not provided - :param c: polymer concentration matrix - :type c: np.ndarray - - :param sor: residual saturation oil phase - :type sor: float + Args: + ----- + c (np.ndarray): polymer concentration matrix - :param swr: residual saturation water phase - :type swr: float + sor (float): residual saturation oil phase - :param aqueous: boolean for whether we are solving for aqoeous or oleic mobility - :type aqueous: bool + swr (float): residual saturation water phase - :param rel_permeability_formula: Select the type of relative Permeability formula from the ``RelativePermeabilityFormula`` Enum - :type has_surfactant: enum ``RelativePermeabilityFormula`` + aqueous (bool): boolean for whether we are solving for aqoeous or oleic mobility - :param surfactant_conc: scalar quantity of the initial surfactant concentration - :type surfactant_conc: float + rel_permeability_formula (enum 'RelativePermeabilityFormula'): Select the type of relative Permeability formula from the ``RelativePermeabilityFormula`` Enum - :return: aqueous or oleic mobility (depending on the 'aqueous' parameter) - :rtype: np.ndarray + surfactant_conc (float): scalar quantity of the initial surfactant concentration + + Returns: (np.ndarray) + --------------------- + aqueous or oleic mobility (depending on the 'aqueous' parameter) """ assert self.water_saturation is not None, SimulationCalcInputException( "SimuationInputException: water saturation matrix not initialized. Please try again" @@ -327,38 +399,34 @@ def compute_water_saturation( """ Solving saturation equation (comes from part of the nmmoc_surf_mod_neumann.m file that is for calculating the water saturation) + + Raises: + ------- + SimulationCalcInputException: If water saturation matrix is None - :raises SimulationCalcInputException: If water saturation matrix is None + Args: + ----- + grid (Grid): the 'Grid' object - :param grid: the 'Grid' object - :type grid: Grid + surfactant (Surfactant): The surfactant object - :param surfactant: The surfactant object - :type surfactant: Surfactant + polymer (Polymer): The polymer object - :param polymer: The polymer object - :type polymer: Polymer + u (np.ndarray): global pressure matrix - :param u: global pressure matrix - :type u: np.ndarray + v (np.ndarray): velocity matrix - :param v: velocity matrix - :type v: np.ndarray + xmod (np.ndarray): x-dimension coordinate points for formulating the 'Qmod' matrix - :param xmod: x-dimension coordinate points for formulating the 'Qmod' matrix - :type xmod: np.ndarray + ymod (np.ndarray): y-dimension coordinate points for formulating the 'Qmod' matrix - :param ymod: y-dimension coordinate points for formulating the 'Qmod' matrix - :type ymod: np.ndarray + const_parameters (dict): constant parameters used in the method - :param const_parameters: constant parameters used in the method - :type const_parameters: dict - - :param varying_parameters: parameters whose values can change - :type varying_parameters: dict - - :return: updated ``water_saturation`` matrix and ``varying_parameters`` dict - :rtype: [np.ndarray, list] + varying_parameters (dict): parameters whose values can change + + Returns: (np.ndarray, dict) + ----------------------------- + Updates the ``water_saturation`` matrix and ``varying_parameters`` dict """ # Assert statements to ensure that all parameters are property initialized: assert self.water_saturation is not None, SimulationCalcInputException( @@ -512,7 +580,7 @@ def compute_water_saturation( + g1 * (1 - f[cnt][i]) + ( (D_g[cnt][i] + D_g[cnt][i + 1]) / (dx**2) - + (D_g[cnt + 1][i] + D_g[cnt][i]) / (dx**2) + + (D_g[cnt + 1][i] + D_g[cnt][i]) / (dy**2) ) * surfactant.concentration_matrix[cnt][i] - (D_g[cnt][i] + D_g[cnt][i + 1]) @@ -520,14 +588,14 @@ def compute_water_saturation( * surfactant.concentration_matrix[cnt][i + 1] - (D_g[cnt][i] + D_g[cnt + 2][i]) / (dy**2) - * surfactant.concentration_matrix[cnt + 2][i] + * surfactant.concentration_matrix[cnt + 1][i] ) CC[j][i] = (D_s[cnt][i] + D_s[cnt + 1][i]) / (dy**2) BB[j][i] = ( 1 / dt_array[cnt][i] - - (D_s[cnt + 1][i] + D_s[cnt][i + 1]) / (dx**2) + - (D_s[cnt][i] + D_s[cnt][i + 1]) / (dx**2) - (D_s[cnt + 1][i] + D_s[cnt][i]) / (dy**2) ) @@ -550,14 +618,14 @@ def compute_water_saturation( BB[j][i - 1] = (D_s[cnt][i] + D_s[cnt][i - 1]) / (dx**2) - BB[i][i] = ( + BB[j][i] = ( 1 / dt_array[cnt][i] - (D_s[cnt][i] + D_s[cnt][i - 1]) / (dx**2) - (D_s[cnt + 1][i] + D_s[cnt][i]) / (dy**2) ) CC[j][i] = (D_s[cnt][i] + D_s[cnt + 1][i]) / (dy**2) - else: + else: # FIXME: stopped here! DD[i] = ( Qmod[cnt][i] / dt_array[cnt][i] - f_c[cnt][i] @@ -662,7 +730,7 @@ def compute_water_saturation( * surfactant.concentration_matrix[cnt - 1][i] ) - BB[j][i - 1] = (D_s[cnt][i] + D_s[cnt][i - 1]) / (dy**2) + BB[j][i - 1] = (D_s[cnt][i] + D_s[cnt][i - 1]) / (dx**2) BB[j][i] = ( 1 / dt_array[cnt][i] @@ -789,7 +857,7 @@ def compute_water_saturation( ) / (2 * dy**2) ) - BB[j][i + 1] = (D_s[cnt][i + 1] + D_s[cnt][i]) / (dx**2) + BB[j][i + 1] = (D_s[cnt][i] + D_s[cnt][i + 1]) / (dx**2) CC[j][i] = (D_s[cnt][i] + D_s[cnt + 1][i]) / (2 * dy**2) elif i == m - 1: @@ -969,7 +1037,7 @@ def compute_water_saturation( warnings.warn(f"BiCGSTAB: convergence issue (info={info}) in water saturation solver") Qnew = Qnew_flat = Qnew_flat.reshape(m, n) - Qnew[Qnew > 1] = 1 + Qnew[Qnew < 0] = 0 self.water_saturation = Qnew diff --git a/requirements.txt b/requirements.txt index 0820883..e4617f0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,19 +1,33 @@ -contourpy==1.3.1 +asttokens==3.0.1 +contourpy==1.3.3 cycler==0.12.1 -fonttools==4.56.0 -iniconfig==2.0.0 -kiwisolver==1.4.8 -matplotlib==3.10.1 -numpy==2.2.3 -packaging==24.2 -pandas==2.2.3 -pillow==11.1.0 -pluggy==1.5.0 -pyparsing==3.2.1 -pytest==8.3.4 +decorator==5.2.1 +executing==2.2.1 +fonttools==4.61.1 +ipython==9.8.0 +ipython_pygments_lexers==1.1.1 +jedi==0.19.2 +Jinja2==3.1.6 +kiwisolver==1.4.9 +markdown2==2.5.5 +MarkupSafe==3.0.3 +matplotlib==3.10.8 +matplotlib-inline==0.2.1 +numpy==2.4.0 +packaging==25.0 +pandas==3.0.1 +parso==0.8.5 +pdoc==16.0.0 +pexpect==4.9.0 +pillow==12.0.0 +prompt_toolkit==3.0.52 +ptyprocess==0.7.0 +pure_eval==0.2.3 +Pygments==2.19.2 +pyparsing==3.3.1 python-dateutil==2.9.0.post0 -pytz==2025.1 -scipy==1.15.2 -seaborn==0.13.2 +scipy==1.16.3 six==1.17.0 -tzdata==2025.1 +stack-data==0.6.3 +traitlets==5.14.3 +wcwidth==0.2.14 diff --git a/user_input/gui.py b/user_input/gui.py index 8fca19f..4bf08e5 100644 --- a/user_input/gui.py +++ b/user_input/gui.py @@ -105,7 +105,7 @@ def add_simulation(self) -> None: # Permeability dropdown permeability_options = { - "Homogeneous": 1, + # "Homogeneous": 1, "Heterogeneous": 2, } permeability_var = tk.StringVar(value=list(permeability_options.keys())[0])