예제 #1
0
    def __init__(self):
        # create mesh object
        self.mesh = conn_mesh()

        # reservoir is supposed to be discretized by external tool
        # read connections and transmissibilities from file
        self.mesh.init('conn2p_2D.txt')
        self.nb = self.mesh.n_blocks

        self.nx = 60
        self.ny = 40
        self.nz = 1

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

        # Set uniform value for all elements of volume array
        # 30m x 30m x 2.5m = 2250 m3
        self.volume.fill(2250)
        self.volume[0:self.nb:60] = 8e9
        self.volume[59:self.nb:60] = 8e9

        # Load heterogeneous porosity values from file,
        # make the resulting ndarray flat,
        # and assign it`s values to the existing array ([:] is very important!)
        self.porosity[:] = np.genfromtxt('poro_2D.txt',
                                         skip_header=True,
                                         skip_footer=True).flatten()

        # Constant definitions
        self.depth.fill(2500)
        self.cond.fill(200)
        self.hcap.fill(2200)

        self.wells = []
예제 #2
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