def conduit_lengths(target, throat_endpoints='throat.endpoints', throat_length='throat.length'): r""" Calculate conduit lengths. A conduit is defined as half pore + throat + half pore. Parameters ---------- target : OpenPNM Object The object which this model is associated with. This controls the length of the calculated array, and also provides access to other necessary properties. throat_endpoints : string Dictionary key of the throat endpoint values. throat_diameter : string Dictionary key of the throat length values. throat_length : string (optional) Dictionary key of the throat length values. If not given then the direct distance bewteen the two throat end points is used. Returns ------- Dictionary containing conduit lengths, which can be accessed via the dict keys 'pore1', 'pore2', and 'throat'. """ _np.warnings.filterwarnings('ignore', category=RuntimeWarning) network = target.project.network throats = network.map_throats(throats=target.Ts, origin=target) cn = network['throat.conns'][throats] # Get pore coordinates C1 = network['pore.coords'][cn[:, 0]] C2 = network['pore.coords'][cn[:, 1]] # Get throat endpoints and length EP1 = network[throat_endpoints + '.head'][throats] EP2 = network[throat_endpoints + '.tail'][throats] try: # Look up throat length if given Lt = network[throat_length][throats] except KeyError: # Calculate throat length otherwise Lt = _sqrt(((EP1 - EP2)**2).sum(axis=1)) # Calculate conduit lengths L1 = _sqrt(((C1 - EP1)**2).sum(axis=1)) L2 = _sqrt(((C2 - EP2)**2).sum(axis=1)) _np.warnings.filterwarnings('default', category=RuntimeWarning) return {'pore1': L1, 'throat': Lt, 'pore2': L2}
def piecewise(target, throat_endpoints='throat.endpoints', throat_centroid='throat.centroid'): r""" Calculate throat length from end points and optionally a centroid Parameters ---------- target : OpenPNM Object The object which this model is associated with. This controls the length of the calculated array, and also provides access to other necessary properties. throat_endpoints : string Dictionary key of the throat endpoint values. throat_centroid : string Dictionary key of the throat centroid values, optional. Returns ------- Lt : ndarray Array containing throat lengths for the given geometry. Notes ----- (1) By default, the model assumes that the centroids of pores and the connecting throat in each conduit are colinear. (2) If `throat_centroid` is passed, the model accounts for the extra length. This could be useful for Voronoi or extracted networks. """ _np.warnings.filterwarnings('ignore', category=RuntimeWarning) network = target.project.network throats = network.map_throats(throats=target.Ts, origin=target) # Get throat endpoints EP1 = network[throat_endpoints + '.head'][throats] EP2 = network[throat_endpoints + '.tail'][throats] # Calculate throat length Lt = _sqrt(((EP1 - EP2)**2).sum(axis=1)) # Handle the case where pores & throat centroids are not colinear try: Ct = network[throat_centroid][throats] Lt = _sqrt(((Ct - EP1)**2).sum(axis=1)) + \ _sqrt(((Ct - EP2)**2).sum(axis=1)) except KeyError: pass _np.warnings.filterwarnings('default', category=RuntimeWarning) return Lt
def conduit_lengths(target, throat_endpoints='throat.endpoints', throat_length='throat.length'): r""" Calculate conduit lengths. A conduit is defined as half pore + throat + half pore. Parameters ---------- target : OpenPNM Object The object which this model is associated with. This controls the length of the calculated array, and also provides access to other necessary properties. throat_endpoints : string Dictionary key of the throat endpoint values. throat_diameter : string Dictionary key of the throat length values. throat_length : string (optional) Dictionary key of the throat length values. If not given then the direct distance bewteen the two throat end points is used. Returns ------- Dictionary containing conduit lengths, which can be accessed via the dict keys 'pore1', 'pore2', and 'throat'. """ network = target.project.network throats = network.map_throats(throats=target.Ts, origin=target) cn = network['throat.conns'][throats] # Get pore coordinates C1 = network['pore.coords'][cn[:, 0]] C2 = network['pore.coords'][cn[:, 1]] # Get throat endpoints and length EP1 = network[throat_endpoints + '.head'][throats] EP2 = network[throat_endpoints + '.tail'][throats] try: # Look up throat length if given Lt = network[throat_length][throats] except KeyError: # Calculate throat length otherwise Lt = _sqrt(((EP1 - EP2)**2).sum(axis=1)) # Calculate conduit lengths L1 = _sqrt(((C1 - EP1)**2).sum(axis=1)) L2 = _sqrt(((C2 - EP2)**2).sum(axis=1)) return {'pore1': L1, 'throat': Lt, 'pore2': L2}
def ctc(target): r""" Calculate throat length assuming point-like pores, i.e. center-to-center distance between pores. Also, this model assumes that pores and throat centroids are colinear. Parameters ---------- target : OpenPNM Object The object which this model is associated with. This controls the length of the calculated array, and also provides access to other necessary properties. Returns ------- value : NumPy ndarray Array containing throat length values. """ network = target.project.network throats = network.map_throats(throats=target.Ts, origin=target) cn = network['throat.conns'][throats] C1 = network['pore.coords'][cn[:, 0]] C2 = network['pore.coords'][cn[:, 1]] value = _sqrt(((C1 - C2)**2).sum(axis=1)) return value
def ctc(target, pore_diameter='pore.diameter'): r""" Calculate throat length assuming point-like pores, i.e. center-to-center distance between pores. Also, this models assumes that pores and throat centroids are colinear. Parameters ---------- target : OpenPNM Object The object which this model is associated with. This controls the length of the calculated array, and also provides access to other necessary properties. pore_diameter : string Dictionary key of the pore diameter values """ _np.warnings.filterwarnings('ignore', category=RuntimeWarning) network = target.project.network throats = network.map_throats(throats=target.Ts, origin=target) cn = network['throat.conns'][throats] C1 = network['pore.coords'][cn[:, 0]] C2 = network['pore.coords'][cn[:, 1]] value = _sqrt(((C1 - C2)**2).sum(axis=1)) _np.warnings.filterwarnings('default', category=RuntimeWarning) return value
def piecewise(target, throat_endpoints='throat.endpoints', throat_centroid='throat.centroid'): r""" Calculate throat length from end points and optionally a centroid Parameters ---------- target : OpenPNM Object The object which this model is associated with. This controls the length of the calculated array, and also provides access to other necessary properties. throat_endpoints : string Dictionary key of the throat endpoint values. throat_centroid : string Dictionary key of the throat centroid values, optional. Returns ------- Lt : ndarray Array containing throat lengths for the given geometry. Notes ----- (1) By default, the model assumes that the centroids of pores and the connecting throat in each conduit are colinear. (2) If `throat_centroid` is passed, the model accounts for the extra length. This could be useful for Voronoi or extracted networks. """ network = target.project.network throats = network.map_throats(throats=target.Ts, origin=target) # Get throat endpoints EP1 = network[throat_endpoints + '.head'][throats] EP2 = network[throat_endpoints + '.tail'][throats] # Calculate throat length Lt = _sqrt(((EP1 - EP2)**2).sum(axis=1)) # Handle the case where pores & throat centroids are not colinear try: Ct = network[throat_centroid][throats] Lt = _sqrt(((Ct - EP1)**2).sum(axis=1)) + \ _sqrt(((Ct - EP2)**2).sum(axis=1)) except KeyError: pass return Lt
def classic(target, pore_diameter='pore.diameter'): r""" Find throat length as the pore-to-pore center distance, less the radii of each pore. Parameters ---------- target : OpenPNM object The object which this model is associated with. This controls the length of the calculated array, and also provides access to other necessary properties. pore_diameter : string Dictionary key of the pore diameter values """ network = target.project.network throats = network.map_throats(throats=target.Ts, origin=target) cn = network['throat.conns'][throats] C1 = network['pore.coords'][cn[:, 0]] C2 = network['pore.coords'][cn[:, 1]] D = _sqrt(((C1 - C2)**2).sum(axis=1)) value = D - _np.sum(network[pore_diameter][cn], axis=1)/2 return value
def classic(target, pore_diameter='pore.diameter'): r""" Find throat length as the pore-to-pore center distance, less the radii of each pore. Parameters ---------- target : OpenPNM object The object which this model is associated with. This controls the length of the calculated array, and also provides access to other necessary properties. pore_diameter : string Dictionary key of the pore diameter values """ network = target.project.network throats = network.map_throats(throats=target.Ts, origin=target) cn = network['throat.conns'][throats] C1 = network['pore.coords'][cn[:, 0]] C2 = network['pore.coords'][cn[:, 1]] D = _sqrt(((C1 - C2)**2).sum(axis=1)) value = D - _np.sum(network[pore_diameter][cn], axis=1) / 2 return value
def ball_and_stick_2D(target, pore_area='pore.area', throat_area='throat.area', pore_diameter='pore.diameter', throat_diameter='throat.diameter', conduit_lengths='throat.conduit_lengths'): r""" Calculate conduit shape factors for throat conductance associated with diffusion-like physics (ex. thermal/diffusive/electrical conductance), assuming pores and throats are circles (balls) and rectangles (sticks). Parameters ---------- target : OpenPNM Object The object which this model is associated with. This controls the length of the calculated array, and also provides access to other necessary properties. pore_area : string Dictionary key of the pore area values throat_area : string Dictionary key of the throat area values pore_diameter : string Dictionary key of the pore diameter values throat_diameter : string Dictionary key of the throat diameter values conduit_lengths : string Dictionary key of the conduit lengths' values Returns ------- SF : dictionary Dictionary containing conduit shape factors to be used in conductance models associated with diffusion-like physics. Shape factors are accessible via the keys: 'pore1', 'pore2' and 'throat'. Notes ----- (1) This model accounts for the variable cross-section area in circles. (2) WARNING: This model could break if `conduit_lengths` does not correspond to an actual ball and stick! Example: pore length is greater than pore radius --> :( """ _np.warnings.filterwarnings('ignore', category=RuntimeWarning) network = target.project.network throats = network.map_throats(throats=target.Ts, origin=target) cn = network['throat.conns'][throats] # Get pore diameter D1 = network[pore_diameter][cn[:, 0]] D2 = network[pore_diameter][cn[:, 1]] # Get conduit lengths L1 = network[conduit_lengths + '.pore1'][throats] L2 = network[conduit_lengths + '.pore2'][throats] Lt = network[conduit_lengths + '.throat'][throats] # Get pore/throat baseline areas (the one used in generic conductance) A1 = network[pore_area][cn[:, 0]] A2 = network[pore_area][cn[:, 1]] At = network[throat_area][throats] # Preallocating F, SF # F is INTEGRAL(1/A) dx , x : 0 --> L F1, F2, Ft = _sp.zeros((3, len(Lt))) SF1, SF2, SFt = _sp.ones((3, len(Lt))) # Setting SF to 1 when Li = 0 (ex. boundary pores) # INFO: This is needed since area could also be zero, which confuses NumPy m1, m2, mt = [Li != 0 for Li in [L1, L2, Lt]] SF1[~m1] = SF2[~m2] = SFt[~mt] = 1 F1[m1] = (0.5 * _atanh(2*L1/_sqrt(D1**2 - 4*L1**2)))[m1] F2[m2] = (0.5 * _atanh(2*L2/_sqrt(D2**2 - 4*L2**2)))[m2] Ft[mt] = (Lt/At)[mt] # Calculate conduit shape factors SF1[m1] = (L1 / (A1*F1))[m1] SF2[m2] = (L2 / (A2*F2))[m2] SFt[mt] = (Lt / (At*Ft))[mt] _np.warnings.filterwarnings('default', category=RuntimeWarning) return {'pore1': SF1, 'throat': SFt, 'pore2': SF2}