Exemple #1
0
 def domain_length(self, face_1, face_2):
     r"""
     Returns the distance between two faces
     No coplanar checking this is done in vertex_dimension
     """
     L = vo.vertex_dimension(self, face_1, face_2, parm='length')
     return L
 def domain_length(self, face_1, face_2):
     r"""
     Returns the distance between two faces
     No coplanar checking this is done in vertex_dimension
     """
     L = vo.vertex_dimension(self, face_1, face_2, parm='length')
     return L
 def test_simple_cubic(self):
     pn = OpenPNM.Network.DelaunayCubic(shape=[3, 3, 3])
     pn.add_boundaries()
     B1 = pn.pores("top_boundary")
     B2 = pn.pores("bottom_boundary")
     assert vo.vertex_dimension(pn, B1, B2, 'minmax') == [0.0, 3.0, 0.0,
                                                          3.0, 0.0, 3.0]
     assert pn.num_pores() == 81
Exemple #4
0
    def domain_area(self, face):
        r"""
        Returns the area of a face
        No coplanar checking this is done in vertex_dimension
        """
        A = vo.vertex_dimension(self, face, parm='area')

        return A
    def domain_area(self, face):
        r"""
        Returns the area of a face
        No coplanar checking this is done in vertex_dimension
        """
        A = vo.vertex_dimension(self, face, parm='area')

        return A
Exemple #6
0
    def domain_area(self,face):
        r"""
        Returns the area of a face
        No coplanar checking this is done in vertex_dimension
        Example
        --------
        >>> import OpenPNM
        >>> pn = OpenPNM.Network.Delaunay(num_pores=100, domain_size=[3,2,1])
        >>> pn.add_boundaries()
        >>> B1 = pn.pores("left_boundary")
        >>> B2 = pn.pores("right_boundary")
        >>> pn.domain_area(B1)
        3.0
        """
        A = vo.vertex_dimension(self,face,parm='area')

        return A
Exemple #7
0
    def domain_length(self,face_1,face_2):
        r"""
        Returns the distance between two faces
        No coplanar checking this is done in vertex_dimension

        Example
        --------
        >>> import OpenPNM
        >>> pn = OpenPNM.Network.Delaunay(num_pores=100, domain_size=[3,2,1])
        >>> pn.add_boundaries()
        >>> B1 = pn.pores("left_boundary")
        >>> B2 = pn.pores("right_boundary")
        >>> pn.domain_length(B1,B2)
        2.0
        """
        L = vo.vertex_dimension(self,face_1,face_2,parm='length')
        return L
    def _calc_eff_prop(self, check_health=False):
        r"""
        This returns the main parameters for calculating the effective
        property in a linear transport equation.
        It also checks for the proper boundary conditions, inlets and outlets.

        Parameters
        ----------
        check_health : boolean(optional)
            It analyzes the inlet and outlet pores to check their spatial
            positions
        """
        try:
            self[self._quantity]
        except KeyError:
            raise Exception('The algorithm has not been run yet. Cannot ' +
                            'calculate effective property.')
        # Determine boundary conditions by analyzing algorithm object
        Ps = self.pores('pore.Dirichlet')
        BCs = sp.unique(self['pore.bcval_Dirichlet'][Ps])
        if sp.shape(BCs)[0] != 2:
            raise Exception('The supplied algorithm did not have appropriate' +
                            ' BCs')
        inlets = sp.where(self['pore.' +
                               'bcval_Dirichlet'] == sp.amax(BCs))[0]
        outlets = sp.where(self['pore.' +
                                'bcval_Dirichlet'] == sp.amin(BCs))[0]

        # Analyze input and output pores
        if check_health:
            # Check for coplanarity
            if self._net.iscoplanar(inlets) is False:
                raise Exception('The inlet pores do not define a plane. ' +
                                'Effective property will be approximation')
            if self._net.iscoplanar(outlets) is False:
                raise Exception('The outlet pores do not define a plane. ' +
                                'Effective property will be approximation')
            # Ensure pores are on a face of domain
            # (only 1 non-self neighbor each)
            PnI = self._net.find_neighbor_pores(pores=inlets,
                                                mode='not_intersection',
                                                excl_self=True)
            if sp.shape(PnI) != sp.shape(inlets):
                logger.warning('The inlet pores have too many neighbors. ' +
                               'Internal pores appear to be selected.')
                pass
            PnO = self._net.find_neighbor_pores(pores=outlets,
                                                mode='not_intersection',
                                                excl_self=True)
            if sp.shape(PnO) != sp.shape(outlets):
                logger.warning('The outlet pores have too many neighbors. ' +
                               'Internal pores appear to be selected.')
                pass

        # Fetch area and length of domain
        if 'pore.vert_index' in self._net.props():
            A = vo.vertex_dimension(network=self._net, face1=inlets,
                                    parm='area')
            L = vo.vertex_dimension(network=self._net, face1=inlets,
                                    face2=outlets, parm='length')
        else:
            A = self._net.domain_area(face=inlets)
            L = self._net.domain_length(face_1=inlets, face_2=outlets)
        flow = self.rate(pores=inlets)
        D = sp.sum(flow)*L/A/(BCs[0] - BCs[1])
        return D
Exemple #9
0
    def add_boundaries(self):
        r"""
        This method identifies pores in the original Voronoi object that straddle a
        boundary imposed by the reflection. The pore inside the original set of pores
        (with index 0 - Np) is identified and the coordinates are saved. The vertices
        making up the boundary throat are retrieved from the ridge_dict values and
        these are used to identify which boundary the throat sits at.
        A new pore and new connection is created with coordinates lying on the
        boundary plane.
        N.B This method will only work properly if the original network remains
            unaltered i.e. not trimmed or extended
            This preserves the connection between pore index on the network object
            and the Voronoi object
            The point of using this method is so that the throat vertices created by
            the Voronoi object are preserved

        This method will create boundary pores at the centre of the voronoi faces
        that align with the outer planes of the domain.
        The original pores in the domain are labelled internal and the boundary pores
        are labelled external

        Examples
        --------
        >>> import OpenPNM
        >>> pn = OpenPNM.Network.Delaunay(num_pores=100,
        ...                               domain_size=[0.0001,0.0001,0.0001])
        >>> pn.add_boundaries()
        >>> pn.num_pores('boundary') > 0
        True
        """

        bound_conns = []
        bound_coords = []
        bound_vert_index = []
        throat_vert_index = []
        # Find boundary extent
        [x_min, x_max, y_min, y_max, z_min, z_max] = \
            vo.vertex_dimension(self, self.pores(), parm='minmax')
        min_point = np.around(np.array([x_min, y_min, z_min]), 10)
        max_point = np.around(np.array([x_max, y_max, z_max]), 10)
        Np = self.num_pores()
        Nt = self.num_throats()
        new_throat_count = 0
        # ridge_dict contains a dictionary where the key is a set of 2 neighbouring
        # pores and the value is the vertex indices that form the throat or ridge
        # between them
        for p, v in self._vor.ridge_dict.items():
            # If the vertex with index -1 is contained in list then the ridge is
            # unbounded - ignore these
            if np.all(np.asarray(v) >= 0):
                # Boundary throats will be those connecting one pore inside the
                # original set and one out
                if (p[0] in range(Np) and p[1] not in range(Np)) or \
                        (p[0] not in range(Np) and p[1] in range(Np)):
                    # The dictionary key is not in numerical order so find the pore
                    # index inside
                    if p[0] in range(Np):
                        my_pore = p[0]
                    else:
                        my_pore = p[1]
                    my_pore_coord = self["pore.coords"][my_pore]
                    new_pore_coord = my_pore_coord.copy()
                    # Rounding necessary here to identify the plane as Voronoi can
                    # have 1e-17 and smaller errors
                    throat_verts = np.around(self._vor.vertices[v], 10)
                    # Find which plane we are aligned with (if any) and align
                    # new_pore with throat plane
                    if len(np.unique(throat_verts[:, 0])) == 1:
                        new_pore_coord[0] = np.unique(throat_verts[:, 0])
                    elif len(np.unique(throat_verts[:, 1])) == 1:
                        new_pore_coord[1] = np.unique(throat_verts[:, 1])
                    elif len(np.unique(throat_verts[:, 2])) == 1:
                        new_pore_coord[2] = np.unique(throat_verts[:, 2])
                    else:
                        new_pore_coord = np.mean(throat_verts, axis=0)
                        pass
                    bound_coords.append(new_pore_coord)
                    bound_conns.append(
                        np.array([my_pore, new_throat_count + Np]))
                    bound_vert_index.append(dict(zip(v, throat_verts)))
                    throat_vert_index.append(dict(zip(v, throat_verts)))
                    new_throat_count += 1

        # Add new pores and connections
        self.extend(pore_coords=bound_coords, throat_conns=bound_conns)
        # Record new number of pores
        Mp = self.num_pores()
        Mt = self.num_throats()
        new_pore_ids = np.arange(Np, Mp)
        new_throat_ids = np.arange(Nt, Mt)
        # Identify which boundary the pore sits on
        front = self.pores()[self['pore.coords'][:, 0] == min_point[0]]
        back = self.pores()[self['pore.coords'][:, 0] == max_point[0]]
        left = self.pores()[self['pore.coords'][:, 1] == min_point[1]]
        right = self.pores()[self['pore.coords'][:, 1] == max_point[1]]
        bottom = self.pores()[self['pore.coords'][:, 2] == min_point[2]]
        top = self.pores()[self['pore.coords'][:, 2] == max_point[2]]
        if len(top) == 0:
            top = self.pores()[self['pore.coords'][:, 2] == np.asarray(
                bound_coords)[:, 2].max()]
        # Assign labels
        self['pore.boundary'] = False
        self['pore.boundary'][new_pore_ids] = True
        self['throat.boundary'] = False
        self['throat.boundary'][new_throat_ids] = True
        self['pore.right_boundary'] = False
        self['pore.left_boundary'] = False
        self['pore.front_boundary'] = False
        self['pore.back_boundary'] = False
        self['pore.top_boundary'] = False
        self['pore.bottom_boundary'] = False
        self['pore.right_boundary'][right] = True
        self['pore.left_boundary'][left] = True
        self['pore.front_boundary'][front] = True
        self['pore.back_boundary'][back] = True
        self['pore.top_boundary'][top] = True
        self['pore.bottom_boundary'][bottom] = True
        # Save the throat verts
        self["pore.vert_index"][new_pore_ids] = bound_vert_index
        self["throat.vert_index"][new_throat_ids] = throat_vert_index
Exemple #10
0
    def _calc_eff_prop(self, check_health=False):
        r"""
        This returns the main parameters for calculating the effective
        property in a linear transport equation.  It also checks for the
        proper boundary conditions, inlets and outlets.

        Parameters
        ----------
        check_health : boolean (optional)
            It analyzes the inlet and outlet pores to check their spatial
            positions
        """
        try:
            self[self._quantity]
        except KeyError:
            raise Exception('The algorithm has not been run yet. Cannot ' +
                            'calculate effective property.')
        # Determine boundary conditions by analyzing algorithm object
        Ps = self.pores('pore.Dirichlet')
        BCs = sp.unique(self['pore.bcval_Dirichlet'][Ps])
        if sp.shape(BCs)[0] != 2:
            raise Exception('The supplied algorithm did not have appropriate' +
                            ' BCs')
        inlets = sp.where(self['pore.' + 'bcval_Dirichlet'] == sp.amax(BCs))[0]
        outlets = sp.where(self['pore.' +
                                'bcval_Dirichlet'] == sp.amin(BCs))[0]

        # Analyze input and output pores
        if check_health:
            # Check for coplanarity
            if self._net.iscoplanar(inlets) is False:
                raise Exception('The inlet pores do not define a plane. ' +
                                'Effective property will be approximation')
            if self._net.iscoplanar(outlets) is False:
                raise Exception('The outlet pores do not define a plane. ' +
                                'Effective property will be approximation')
            # Ensure pores are on a face of domain
            # (only 1 non-self neighbor each)
            PnI = self._net.find_neighbor_pores(pores=inlets,
                                                mode='not_intersection',
                                                excl_self=True)
            if sp.shape(PnI) != sp.shape(inlets):
                logger.warning('The inlet pores have too many neighbors. ' +
                               'Internal pores appear to be selected.')
                pass
            PnO = self._net.find_neighbor_pores(pores=outlets,
                                                mode='not_intersection',
                                                excl_self=True)
            if sp.shape(PnO) != sp.shape(outlets):
                logger.warning('The outlet pores have too many neighbors. ' +
                               'Internal pores appear to be selected.')
                pass

        # Fetch area and length of domain
        if 'pore.vert_index' in self._net.props():
            A = vo.vertex_dimension(network=self._net,
                                    face1=inlets,
                                    parm='area')
            L = vo.vertex_dimension(network=self._net,
                                    face1=inlets,
                                    face2=outlets,
                                    parm='length')
        else:
            A = self._net.domain_area(face=inlets)
            L = self._net.domain_length(face_1=inlets, face_2=outlets)
        flow = self.rate(pores=inlets)
        D = sp.sum(flow) * L / A / (BCs[0] - BCs[1])
        return D
Exemple #11
0
    def add_boundaries(self):

        r"""
        This method identifies pores in the original Voronoi object that straddle a boundary imposed by the reflection
        The pore inside the original set of pores (with index 0 - Np) is identified and the coordinates are saved
        The vertices making up the boundary throat are retrieved from the ridge_dict values and these are used to identify
        which boundary the throat sits at.
        A new pore and new connection is created with coordinates lying on the boundary plane
        N.B This method will only work properly if the original network remains unaltered i.e. not trimmed or extended
            This preserves the connection between pore index on the network object and the Voronoi object
            The point of using this method is so that the throat vertices created by the Voronoi object are preserved

        This method will create boundary pores at the centre of the voronoi faces that
        align with the outer planes of the domain.
        The original pores in the domain are labelled internal and the boundary pores
        are labelled external

        Examples
        --------
        >>> import OpenPNM
        >>> pn = OpenPNM.Network.Delaunay(num_pores=100, domain_size=[0.0001,0.0001,0.0001])
        >>> pn.add_boundaries()
        >>> pn.num_pores("boundary")>0
        True
        """

        bound_conns=[]
        bound_coords=[]
        bound_vert_index=[]
        throat_vert_index=[]
        #Find boundary extent
        [x_min,x_max,y_min,y_max,z_min,z_max]=vo.vertex_dimension(self,self.pores(),parm='minmax')
        min_point = np.around(np.array([x_min,y_min,z_min]),10)
        max_point = np.around(np.array([x_max,y_max,z_max]),10)
        Np = self.num_pores()
        Nt = self.num_throats()
        new_throat_count = 0
        # ridge_dict contains a dictionary where the key is a set of 2 neighbouring pores and the value is the vertex indices
        # that form the throat or ridge between them
        for p,v in self._vor.ridge_dict.items():
            # if the vertex with index -1 is contained in list then the ridge is unbounded - ignore these
            if np.all(np.asarray(v) >=0):
                #boundary throats will be those connecting one pore inside the original set and one out
                if  (p[0] in range(Np) and p[1] not in range(Np)) or\
                    (p[0] not in range(Np) and p[1] in range(Np)):
                    # the dictionary key is not in numerical order so find the pore index inside
                    if p[0] in range(Np):
                        my_pore=p[0]
                    else:
                        my_pore=p[1]
                    my_pore_coord = self["pore.coords"][my_pore]
                    new_pore_coord = my_pore_coord.copy()
                    #rounding necessary here to identify the plane as Voronoi can have 1e-17 and smaller errors
                    throat_verts = np.around(self._vor.vertices[v],10)
                    #find which plane we are aligned with (if any) and align new_pore with throat plane
                    if len(np.unique(throat_verts[:,0])) == 1:
                        new_pore_coord[0]=np.unique(throat_verts[:,0])
                    elif len(np.unique(throat_verts[:,1])) == 1:
                        new_pore_coord[1]=np.unique(throat_verts[:,1])
                    elif len(np.unique(throat_verts[:,2])) == 1:
                        new_pore_coord[2]=np.unique(throat_verts[:,2])
                    else:
                        new_pore_coord = throat_verts.mean()
                    bound_coords.append(new_pore_coord)
                    bound_conns.append(np.array([my_pore,new_throat_count+Np]))
                    bound_vert_index.append(dict(zip(v,throat_verts)))
                    throat_vert_index.append(dict(zip(v,throat_verts)))
                    new_throat_count += 1

        #Add new pores and connections
        self.extend(pore_coords=bound_coords, throat_conns=bound_conns)
        #Record new number of pores
        Mp = self.num_pores()
        Mt = self.num_throats()
        new_pore_ids = np.arange(Np,Mp)
        new_throat_ids = np.arange(Nt,Mt)
        #Identify which boundary the pore sits on
        front = self.pores()[self['pore.coords'][:,0]==min_point[0]]
        back = self.pores()[self['pore.coords'][:,0]==max_point[0]]
        left = self.pores()[self['pore.coords'][:,1]==min_point[1]]
        right = self.pores()[self['pore.coords'][:,1]==max_point[1]]
        bottom = self.pores()[self['pore.coords'][:,2]==min_point[2]]
        top = self.pores()[self['pore.coords'][:,2]==max_point[2]]
        #Assign labels
        self['pore.boundary'] = False
        self['pore.boundary'][new_pore_ids] = True
        self['pore.right_boundary'] = False
        self['pore.left_boundary'] = False
        self['pore.front_boundary'] = False
        self['pore.back_boundary'] = False
        self['pore.top_boundary'] = False
        self['pore.bottom_boundary'] = False
        self['pore.right_boundary'][right] = True
        self['pore.left_boundary'][left] = True
        self['pore.front_boundary'][front] = True
        self['pore.back_boundary'][back] = True
        self['pore.top_boundary'][top] = True
        self['pore.bottom_boundary'][bottom] = True
        #Save the throat verts
        self["pore.vert_index"][new_pore_ids] = bound_vert_index
        self["throat.vert_index"][new_throat_ids] = throat_vert_index