Beispiel #1
0
    def __init__(self, n_points=100):
        # call base class constructor
        super().__init__()

        self.hcap = np.array(self.reservoir.mesh.heat_capacity, copy=False)
        self.conduction = np.array(self.reservoir.mesh.rock_cond, copy=False)
        self.hcap.fill(2200)
        self.conduction.fill(181.44)

        # Create property containers:
        self.property_container = property_container(
            phase_name=['water', 'steam', 'temperature', 'energy'],
            component_name=['H2O'])

        # Define properties in property_container (IAPWS is the default property package for Geothermal in DARTS)
        # Users can define their custom properties in custom_properties.py; several property examples are defined there.
        self.rock = [value_vector([1, 0, 273.15])]
        self.property_container.temperature = iapws_temperature_evaluator()
        self.property_container.water_enthalpy = iapws_water_enthalpy_evaluator(
        )
        self.property_container.steam_enthalpy = iapws_steam_enthalpy_evaluator(
        )
        self.property_container.water_saturation = iapws_water_saturation_evaluator(
        )
        self.property_container.steam_saturation = iapws_steam_saturation_evaluator(
        )
        self.property_container.water_relperm = iapws_water_relperm_evaluator()
        self.property_container.steam_relperm = iapws_steam_relperm_evaluator()
        self.property_container.water_density = iapws_water_density_evaluator()
        self.property_container.steam_density = iapws_steam_density_evaluator()
        self.property_container.water_viscosity = iapws_water_viscosity_evaluator(
        )
        self.property_container.steam_viscosity = iapws_steam_viscosity_evaluator(
        )
        self.property_container.rock_compaction = custom_rock_compaction_evaluator(
            self.rock)
        self.property_container.rock_energy = custom_rock_energy_evaluator(
            self.rock)

        self.physics = Geothermal_Custom(
            timer=self.timer,
            n_points=128,
            min_p=1,
            max_p=151,
            min_e=1000,
            max_e=55000,
            property_container=self.property_container)

        self.params.first_ts = 1e0
        self.params.mult_ts = 2
        self.params.max_ts = 92

        # Newton tolerance is relatively high because of L2-norm for residual and well segments
        self.params.tolerance_newton = 1e-1
        self.params.tolerance_linear = 1e-3
        self.params.max_i_newton = 20
        self.params.max_i_linear = 30
        self.runtime = 3650
        self.inj = value_vector([0.999])
Beispiel #2
0
    def __init__(self, n_points=100):
        # call base class constructor
        super().__init__()

        property_container = PropertyContainer(phase_name=['water', 'oil'], component_name=['w', 'o'])

        # Define property evaluators based on custom properties
        property_container.density_ev = dict([('water', DensityWater()), ('oil', DensityOil())])
        property_container.viscosity_ev = dict([('water', ViscosityWater()), ('oil', ViscosityOil())])
        property_container.watersat_ev = WaterSaturation()
        property_container.rel_perm_ev = dict([('water', PhaseRelPerm("water")), ('oil', PhaseRelPerm("oil"))])
        property_container.capillary_ev = CapillaryPressure()
        property_container.rock_compress_ev = RockCompactionEvaluator()

        # create physics
        self.grav = 0
        self.physics = DeadOil(self.timer, n_points=400, min_p=0, max_p=1000, min_z=1e-13,
                               property_container=property_container, grav=self.grav)
        self.params.first_ts = 1e-2
        self.params.mult_ts = 2
        self.params.max_ts = 15

        # Newton tolerance is relatively high because of L2-norm for residual and well segments
        self.params.tolerance_newton = 1e-3
        self.params.tolerance_linear = 1e-3
        self.params.max_i_newton = 20
        self.params.max_i_linear = 30
        self.runtime = 900
        self.inj = value_vector([0.999])
Beispiel #3
0
    def __init__(self, n_points=100):
        # call base class constructor
        super().__init__()

        self.pvt = 'bo_physics.in'
        self.property_container = PropertyContainer(
            phase_name=['gas', 'oil', 'water'],
            component_name=['gas', 'oil', 'water'],
            pvt=self.pvt)

        # Define property evaluators based on custom properties
        self.property_container.pb_ev = BubblePointPres(self.pvt)
        self.property_container.rs_ev = Rs(self.pvt)
        self.property_container.xgo_ev = Xgo(self.pvt)
        self.property_container.density_ev = dict([
            ('gas', DensityGas(self.pvt)), ('oil', DensityOil(self.pvt)),
            ('water', DensityWater(self.pvt))
        ])
        self.property_container.viscosity_ev = dict([
            ('gas', VsicoGas(self.pvt)), ('oil', ViscoOil(self.pvt)),
            ('water', ViscoWat(self.pvt))
        ])
        self.property_container.sat_ev = dict([('gas', Gassat(self.pvt)),
                                               ('oil', Oilsat(self.pvt)),
                                               ('water', Watsat(self.pvt))])
        # stone I model is used, then OW is water-oil system, and GO is gas-oil system
        self.property_container.rel_perm_ev = dict([
            ('gas', GasRelPerm(self.pvt)), ('oil', OilRelPerm(self.pvt)),
            ('water', WatRelPerm(self.pvt)), ('OW', Krow(self.pvt)),
            ('GO', Krog(self.pvt))
        ])
        self.property_container.rock_compress_ev = RockCompactionEvaluator(
            self.pvt)

        # create physics
        self.grav = 0
        self.physics = BlackOil(self.timer,
                                n_points=500,
                                min_p=0,
                                max_p=450,
                                min_z=1e-13,
                                property_container=self.property_container,
                                grav=self.grav)

        self.params.first_ts = 1e-2
        self.params.mult_ts = 2
        self.params.max_ts = 15

        # Newton tolerance is relatively high because of L2-norm for residual and well segments
        self.params.tolerance_newton = 1e-2
        self.params.tolerance_linear = 1e-3
        self.params.max_i_newton = 20
        self.params.max_i_linear = 30
        self.params.newton_type = sim_params.newton_local_chop
        self.params.nonlinear_norm_type = sim_params.L1
        self.inj = value_vector([1e-8, 1e-8])
Beispiel #4
0
    def __init__(self, n_points=100):
        # call base class constructor
        super().__init__()
        """Physical properties"""
        # Create property containers:
        self.property_container = property_container(
            phase_name=['gas', 'Aq'], component_name=['CO2', 'H2O'])
        self.components = self.property_container.component_name
        self.phases = self.property_container.phase_name
        """ properties correlations """
        self.property_container.flash_ev = Flash(self.components)
        self.property_container.density_ev = dict([('Aq', DensityBrine()),
                                                   ('gas', DensityVap())])
        self.property_container.viscosity_ev = dict([('Aq', ViscosityBrine()),
                                                     ('gas', ViscosityVap())])
        self.property_container.rel_perm_ev = dict([('Aq', PhaseRelPerm("Aq")),
                                                    ('gas',
                                                     PhaseRelPerm("gas"))])
        self.property_container.rel_well_perm_ev = dict([
            ('Aq', WellPhaseRelPerm("Aq")), ('gas', WellPhaseRelPerm("gas"))
        ])
        """ Activate physics """
        self.physics = CO2Brine(self.timer,
                                n_points=501,
                                min_p=100,
                                max_p=500,
                                min_z=1e-10,
                                max_z=1 - 1e-10,
                                property_container=self.property_container)

        self.params.first_ts = 1e-2
        self.params.mult_ts = 2
        self.params.max_ts = 5

        # Newton tolerance is relatively high because of L2-norm for residual and well segments
        self.params.tolerance_newton = 1e-3
        self.params.tolerance_linear = 1e-3
        self.params.max_i_newton = 20
        self.params.max_i_linear = 30
        self.runtime = 900
        self.inj = value_vector([0.999])
Beispiel #5
0
    def export_vtk_comp(self, file_name='data'):
        properties_vector = properties_evaluator(self.property_container)
        nb = self.reservoir.nb
        X = np.array(self.physics.engine.X)
        pres = X[0:2 * nb:2]
        zg = X[1:2 * nb:2]
        Sg = np.zeros(nb)
        xg = np.zeros(nb)

        for i in range(nb):
            state = value_vector([pres[i], zg[i]])
            [
                Sg[i],
                xg[i],
            ] = properties_vector.evaluate(state)

        self.export_vtk(file_name=file_name,
                        local_cell_data={
                            'GasSat': Sg,
                            'xCO2': xg
                        })
Beispiel #6
0
    def export_vtk_bo(self, file_name='data'):
        properties_vector = Properties(self.property_container)
        nb = self.reservoir.nb
        X = np.array(self.physics.engine.X)
        pres = X[0:3 * nb:3]
        zg = X[1:3 * nb:3]
        zo = X[2:3 * nb:3]
        So = np.zeros(nb)
        Sg = np.zeros(nb)
        Sw = np.zeros(nb)
        pbub = np.zeros(nb)

        for i in range(nb):
            state = value_vector([pres[i], zg[i], zo[i]])
            [So[i], Sw[i], Sg[i], pbub[i]] = properties_vector.evaluate(state)

        self.export_vtk(file_name=file_name,
                        local_cell_data={
                            'OilSat': So,
                            'GasSat': Sg,
                            'WatSat': Sw
                        })
Beispiel #7
0
    def __init__(self,
                 timer,
                 nx: int,
                 ny: int,
                 nz: int,
                 dx,
                 dy,
                 dz,
                 permx,
                 permy,
                 permz,
                 poro,
                 depth,
                 actnum=1,
                 global_to_local=0,
                 op_num=0,
                 coord=0,
                 zcorn=0,
                 is_cpg=False):
        """
        Class constructor method
        :param timer: timer object to measure discretization time
        :param nx: number of reservoir blocks in the x-direction
        :param ny: number of reservoir blocks in the y-direction
        :param nz: number of reservoir blocks in the z-direction
        :param dx: size of the reservoir blocks in the x-direction (scalar or vector form) [m]
        :param dy: size of the reservoir blocks in the y-direction (scalar or vector form) [m]
        :param dz: size of the reservoir blocks in the z-direction (scalar or vector form) [m]
        :param permx: permeability of the reservoir blocks in the x-direction (scalar or vector form) [mD]
        :param permy: permeability of the reservoir blocks in the y-direction (scalar or vector form) [mD]
        :param permz: permeability of the reservoir blocks in the z-direction (scalar or vector form) [mD]
        :param poro: porosity of the reservoir blocks
        :param actnum: attribute of activity of the reservoir blocks (all are active by default)
        :param global_to_local: one can define arbitrary indexing (mapping from global to local) for local
                                arrays. Default indexing is by X (fastest),then Y, and finally Z (slowest)
        :param op_num: index of required operator set of the reservoir blocks (the first by default).
                       Use to introduce PVTNUM, SCALNUM, etc.
        :param coord: COORD keyword values for more accurate geometry during VTK export (no values by default)
        :param zcron: ZCORN keyword values for more accurate geometry during VTK export (no values by default)

        """

        self.timer = timer
        self.nx = nx
        self.ny = ny
        self.nz = nz
        self.coord = coord
        self.zcorn = zcorn
        self.permx = permx
        self.permy = permy
        self.permz = permz
        self.n = nx * ny * nz
        self.global_data = {
            'dx': dx,
            'dy': dy,
            'dz': dz,
            'permx': permx,
            'permy': permy,
            'permz': permz,
            'poro': poro,
            'depth': depth,
            'actnum': actnum,
            'op_num': op_num,
        }
        self.discretizer = StructDiscretizer(nx=nx,
                                             ny=ny,
                                             nz=nz,
                                             dx=dx,
                                             dy=dy,
                                             dz=dz,
                                             permx=permx,
                                             permy=permy,
                                             permz=permz,
                                             global_to_local=global_to_local,
                                             coord=coord,
                                             zcorn=zcorn,
                                             is_cpg=is_cpg)

        self.timer.node['initialization'].node[
            'connection list generation'] = timer_node()
        self.timer.node['initialization'].node[
            'connection list generation'].start()
        if self.discretizer.is_cpg:
            cell_m, cell_p, tran, tran_thermal = self.discretizer.calc_cpg_discr(
            )
        else:
            cell_m, cell_p, tran, tran_thermal = self.discretizer.calc_structured_discr(
            )
        self.timer.node['initialization'].node[
            'connection list generation'].stop()

        volume = self.discretizer.calc_volumes()
        self.global_data['volume'] = volume

        # apply actnum filter if needed - all arrays providing a value for a single grid block should be passed
        arrs = [poro, depth, volume, op_num]
        cell_m, cell_p, tran, tran_thermal, arrs_local = self.discretizer.apply_actnum_filter(
            actnum, cell_m, cell_p, tran, tran_thermal, arrs)
        poro, depth, volume, op_num = arrs_local
        self.global_data['global_to_local'] = self.discretizer.global_to_local
        # create mesh object
        self.mesh = conn_mesh()

        # Initialize mesh using built connection list
        self.mesh.init(index_vector(cell_m), index_vector(cell_p),
                       value_vector(tran), value_vector(tran_thermal))

        # taking into account actnum
        self.nb = volume.size

        # Create numpy arrays wrapped around mesh data (no copying)
        self.poro = np.array(self.mesh.poro, copy=False)
        self.depth = np.array(self.mesh.depth, copy=False)
        self.volume = np.array(self.mesh.volume, copy=False)
        self.op_num = np.array(self.mesh.op_num, copy=False)
        self.hcap = np.array(self.mesh.heat_capacity, copy=False)
        self.rcond = np.array(self.mesh.rock_cond, copy=False)

        self.poro[:] = poro
        self.depth[:] = depth
        self.volume[:] = volume
        self.op_num[:] = op_num

        self.wells = []

        self.vtk_z = 0
        self.vtk_y = 0
        self.vtk_x = 0
        self.vtk_filenames_and_times = {}
        self.vtkobj = 0

        if np.isscalar(self.coord):
            # Usual structured grid generated from DX, DY, DZ, DEPTH
            self.vtk_grid_type = 0
        else:
            # CPG grid from COORD ZCORN
            self.vtk_grid_type = 1