Esempio n. 1
0
 def __init__(self,
              shape,
              spacing=1,
              label_1='primary',
              label_2='secondary',
              **kwargs):
     super().__init__(**kwargs)
     spacing = sp.array(spacing)
     shape = sp.array(shape)
     # Deal with non-3D shape arguments
     shape = sp.pad(shape, [0, 3 - shape.size],
                    mode='constant',
                    constant_values=1)
     net = Cubic(shape=shape, spacing=1)
     net['throat.' + label_1] = True
     net['pore.' + label_1] = True
     single_dim = shape == 1
     shape[single_dim] = 2
     dual = Cubic(shape=shape - 1, spacing=1)
     faces = [['front', 'back'], ['left', 'right'], ['top', 'bottom']]
     faces = [faces[i] for i in sp.where(~single_dim)[0]]
     faces = sp.array(faces).flatten().tolist()
     dual.add_boundary_pores(faces)
     # Add secondary network name as a label
     dual['pore.' + label_2] = True
     dual['throat.' + label_2] = True
     # Shift coordinates prior to stitching
     dual['pore.coords'] += 0.5 * (~single_dim)
     topotools.stitch(net,
                      dual,
                      P_network=net.Ps,
                      P_donor=dual.Ps,
                      len_max=1)
     net['throat.interconnect'] = net['throat.stitched']
     del net['throat.stitched']
     # Clean-up labels
     net['pore.surface'] = False
     net['throat.surface'] = False
     for face in faces:
         # Remove face label from secondary network since it's internal now
         Ps = net.pores(labels=[face, label_2], mode='xnor')
         net['pore.' + face][Ps] = False
         Ps = net.pores(labels=[face + '_boundary'])
         net['pore.' + face][Ps] = True
         Ps = net.pores(face)
         net['pore.surface'][Ps] = True
         Ts = net.find_neighbor_throats(pores=Ps, mode='xnor')
         net['throat.surface'][Ts] = True
         net['throat.' + face] = net.tomask(throats=Ts)
     [net.pop(item) for item in net.labels() if 'boundary' in item]
     # Label non-surface pores and throats as internal
     net['pore.internal'] = True
     net['throat.internal'] = True
     # Transfer all dictionary items from 'net' to 'self'
     [self.update({item: net[item]}) for item in net]
     ws.close_project(net.project)
     # Finally, scale network to requested spacing
     net['pore.coords'] *= spacing
Esempio n. 2
0
    def __init__(self,
                 shape,
                 spacing=1.0,
                 length=1.0,
                 psd_params={'distribution': 'norm',
                             'loc': None,
                             'scale': None},
                 name=None,
                 settings={},
                 **kwargs):
        super().__init__(name=name)
        self.settings.update(defsets)
        self.settings.update(settings)

        if isinstance(shape, int):
            shape = sp.array([shape, shape, 2])
        elif len(shape) == 2:
            shape = sp.concatenate((sp.array(shape), [2]))
        else:
            raise Exception('shape not understood, must be int ' +
                            ' or list of 2 ints')

        if isinstance(spacing, float) or isinstance(spacing, int):
            spacing = float(spacing)
            self.settings['spacing'] = spacing
            spacing = sp.array([spacing, spacing, length])
        else:
            raise Exception('spacing not understood, must be float')

        net = Cubic(shape=shape, spacing=spacing, project=self, **kwargs)
        Ps_top = net.pores('top')
        Ps_bot = net.pores('bottom')
        Ts = net.find_connecting_throat(P1=Ps_top, P2=Ps_bot)
        Ts = net.tomask(throats=Ts)
        trim(network=net, throats=~Ts)

        geom = GenericGeometry(network=net, pores=net.Ps, throats=net.Ts)

        geom.add_model(propname='throat.seed',
                       model=mods.geometry.throat_seed.random)
        if psd_params['loc'] is None:
            psd_params['loc'] = spacing[0]/2
        if psd_params['scale'] is None:
            psd_params['scale'] = spacing[0]/10
        if psd_params['distribution'] in ['norm', 'normal', 'gaussian']:
            geom.add_model(propname='throat.size_distribution',
                           seeds='throat.seed',
                           model=mods.geometry.throat_size.normal,
                           loc=psd_params['loc'], scale=psd_params['scale'])
        elif psd_params['distribution'] in ['weibull']:
            geom.add_model(propname='throat.size_distribution',
                           seeds='throat.seed',
                           model=mods.geometry.throat_size.weibull,
                           loc=psd_params['loc'],
                           scale=psd_params['scale'],
                           shape=psd_params['shape'])
        else:
            temp = psd_params.copy()
            func = getattr(spst, temp.pop('distribution'))
            psd = func.freeze(**temp)
            geom.add_model(propname='throat.size_distribution',
                           seeds='throat.seed',
                           model=mods.geometry.throat_size.generic_distribution,
                           func=psd)

        if sp.any(geom['throat.size_distribution'] < 0):
            logger.warning('Given size distribution produced negative ' +
                           'throat diameters...these will be set to 0')
        geom.add_model(propname='throat.diameter',
                       model=mods.misc.clip,
                       prop='throat.size_distribution',
                       xmin=1e-12, xmax=sp.inf)

        if self.settings['adjust_psd'] is None:
            if geom['throat.size_distribution'].max() > spacing[0]:
                logger.warning('Given size distribution produced throats ' +
                               'larger than the spacing.')

        elif self.settings['adjust_psd'] == 'clip':
            geom.add_model(propname='throat.diameter',
                           model=mods.misc.clip,
                           prop='throat.size_distribution',
                           xmin=1e-12, xmax=spacing[0])
            if geom['throat.size_distribution'].max() > spacing[0]:
                logger.warning('Given size distribution produced throats ' +
                               'larger than the spacing...tube diameters ' +
                               'will be clipped between 0 and given spacing')

        elif self.settings['adjust_psd'] == 'normalize':
            tmin = max(1e-12, geom['throat.size_distribution'].min())
            geom.add_model(propname='throat.diameter',
                           model=mods.misc.normalize,
                           prop='throat.size_distribution',
                           xmin=tmin, xmax=spacing[0])
            if geom['throat.size_distribution'].max() > spacing[0]:
                logger.warning('Given size distribution produced throats ' +
                               'larger than the spacing...tube diameters ' +
                               'will be normalized to fit given spacing')
        else:
            logger.warning('Settings not understood, ignoring')

        geom.add_model(propname='pore.diameter',
                       model=mods.geometry.pore_size.from_neighbor_throats,
                       throat_prop='throat.diameter', mode='max')
        geom.add_model(propname='pore.diameter',
                       model=mods.misc.constant, value=0.0)
        geom.add_model(propname='throat.length',
                       model=mods.geometry.throat_length.ctc)
        geom.add_model(propname='throat.area',
                       model=mods.geometry.throat_area.cylinder)
        geom.add_model(propname='pore.area',
                       model=mods.misc.from_neighbor_throats,
                       throat_prop='throat.area')
        geom.add_model(propname='pore.volume',
                       model=mods.misc.constant, value=0.0)
        geom.add_model(propname='throat.volume',
                       model=mods.geometry.throat_volume.cylinder)

        geom.regenerate_models()

        # Now create a generic phase with physics models on it
        phase = GenericPhase(network=net)
        m = mods.physics.hydraulic_conductance.classic_hagen_poiseuille
        phase.add_model(propname='throat.hydraulic_conductance',
                        model=m, regen_mode='deferred')
        m = mods.physics.diffusive_conductance.classic_ordinary_diffusion
        phase.add_model(propname='throat.diffusive_conductance',
                        model=m, regen_mode='deferred')
        m = mods.physics.diffusive_conductance.classic_ordinary_diffusion
        phase.add_model(propname='throat.entry_pressure',
                        model=m, regen_mode='deferred')
Esempio n. 3
0
    def __init__(self,
                 shape,
                 spacing=1.0,
                 length=1.0,
                 psd_params={
                     'distribution': 'norm',
                     'loc': None,
                     'scale': None
                 },
                 name=None,
                 settings={},
                 **kwargs):
        super().__init__(name=name)
        self.settings.update(defsets)
        self.settings.update(settings)

        if isinstance(shape, int):
            shape = sp.array([shape, shape, 2])
        elif len(shape) == 2:
            shape = sp.concatenate((sp.array(shape), [2]))
        else:
            raise Exception('shape not understood, must be int ' +
                            ' or list of 2 ints')

        if isinstance(spacing, float) or isinstance(spacing, int):
            spacing = float(spacing)
            self.settings['spacing'] = spacing
            spacing = sp.array([spacing, spacing, length])
        else:
            raise Exception('spacing not understood, must be float')

        net = Cubic(shape=shape, spacing=spacing, project=self, **kwargs)
        Ps_top = net.pores('top')
        Ps_bot = net.pores('bottom')
        Ts = net.find_connecting_throat(P1=Ps_top, P2=Ps_bot)
        Ts = net.tomask(throats=Ts)
        trim(network=net, throats=~Ts)

        geom = GenericGeometry(network=net, pores=net.Ps, throats=net.Ts)

        geom.add_model(propname='throat.seed',
                       model=mods.geometry.throat_seed.random)
        if psd_params['loc'] is None:
            psd_params['loc'] = spacing[0] / 2
        if psd_params['scale'] is None:
            psd_params['scale'] = spacing[0] / 10
        if psd_params['distribution'] in ['norm', 'normal', 'gaussian']:
            geom.add_model(propname='throat.size_distribution',
                           seeds='throat.seed',
                           model=mods.geometry.throat_size.normal,
                           loc=psd_params['loc'],
                           scale=psd_params['scale'])
        elif psd_params['distribution'] in ['weibull']:
            geom.add_model(propname='throat.size_distribution',
                           seeds='throat.seed',
                           model=mods.geometry.throat_size.weibull,
                           loc=psd_params['loc'],
                           scale=psd_params['scale'],
                           shape=psd_params['shape'])
        else:
            temp = psd_params.copy()
            func = getattr(spst, temp.pop('distribution'))
            psd = func.freeze(**temp)
            geom.add_model(
                propname='throat.size_distribution',
                seeds='throat.seed',
                model=mods.geometry.throat_size.generic_distribution,
                func=psd)

        if sp.any(geom['throat.size_distribution'] < 0):
            logger.warning('Given size distribution produced negative ' +
                           'throat diameters...these will be set to 0')
        geom.add_model(propname='throat.diameter',
                       model=mods.misc.clip,
                       prop='throat.size_distribution',
                       xmin=1e-12,
                       xmax=sp.inf)

        if self.settings['adjust_psd'] is None:
            if geom['throat.size_distribution'].max() > spacing[0]:
                logger.warning('Given size distribution produced throats ' +
                               'larger than the spacing.')

        elif self.settings['adjust_psd'] == 'clip':
            geom.add_model(propname='throat.diameter',
                           model=mods.misc.clip,
                           prop='throat.size_distribution',
                           xmin=1e-12,
                           xmax=spacing[0])
            if geom['throat.size_distribution'].max() > spacing[0]:
                logger.warning('Given size distribution produced throats ' +
                               'larger than the spacing...tube diameters ' +
                               'will be clipped between 0 and given spacing')

        elif self.settings['adjust_psd'] == 'normalize':
            tmin = max(1e-12, geom['throat.size_distribution'].min())
            geom.add_model(propname='throat.diameter',
                           model=mods.misc.normalize,
                           prop='throat.size_distribution',
                           xmin=tmin,
                           xmax=spacing[0])
            if geom['throat.size_distribution'].max() > spacing[0]:
                logger.warning('Given size distribution produced throats ' +
                               'larger than the spacing...tube diameters ' +
                               'will be normalized to fit given spacing')
        else:
            logger.warning('Settings not understood, ignoring')

        geom.add_model(propname='pore.diameter',
                       model=mods.geometry.pore_size.from_neighbor_throats,
                       throat_prop='throat.diameter',
                       mode='max')
        geom.add_model(propname='pore.diameter',
                       model=mods.misc.constant,
                       value=0.0)
        geom.add_model(propname='throat.length',
                       model=mods.geometry.throat_length.ctc)
        geom.add_model(propname='throat.area',
                       model=mods.geometry.throat_area.cylinder)
        geom.add_model(propname='pore.area',
                       model=mods.misc.from_neighbor_throats,
                       throat_prop='throat.area')
        geom.add_model(propname='pore.volume',
                       model=mods.misc.constant,
                       value=0.0)
        geom.add_model(propname='throat.volume',
                       model=mods.geometry.throat_volume.cylinder)

        geom.regenerate_models()

        # Now create a generic phase with physics models on it
        phase = GenericPhase(network=net)
        m = mods.physics.hydraulic_conductance.classic_hagen_poiseuille
        phase.add_model(propname='throat.hydraulic_conductance',
                        model=m,
                        regen_mode='deferred')
        m = mods.physics.diffusive_conductance.classic_ordinary_diffusion
        phase.add_model(propname='throat.diffusive_conductance',
                        model=m,
                        regen_mode='deferred')
        m = mods.physics.diffusive_conductance.classic_ordinary_diffusion
        phase.add_model(propname='throat.entry_pressure',
                        model=m,
                        regen_mode='deferred')