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 = _norm(EP1 - EP2, axis=1) # Calculate conduit lengths L1 = _norm(C1 - EP1, axis=1) L2 = _norm(C2 - EP2, axis=1) 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. """ 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 = _norm(EP1 - EP2, axis=1) # Handle the case where pores & throat centroids are not colinear try: Ct = network[throat_centroid][throats] Lt = _norm(Ct - EP1, axis=1) + _norm(Ct - EP2, axis=1) except KeyError: pass return Lt
def discrete_error(X, Y): """Compute the absolute and relative l2-norm errors between two snapshot sets X and Y where Y is an approximation to X, Abs_Err_j = ||X_j - Y_j||_2, Rel_Err_j = ||X_j - Y_j||_2 / ||X_j||_2 = Abs_Err_j / ||X_j||_2. Parameters ---------- X : (n,k) or (n,) ndarray The "true" data. Each column is one snapshot, i.e., X[:,j] is the data at some time t[j]. If one-dimensional, all of X is a single snapshot. Y : (n,k) or (n,) ndarray An approximation to X, i.e., Y[:,j] approximates X[:,j] and corresponds to some time t[j]. If one-dimensional, all of Y is a single snapshot approximation. Returns ------- abs_err : (k,) ndarray or float The absolute error of each pair of snapshots X[:,j] and Y[:,j]. If X and Y are one-dimensional, X and Y are treated as single snapshots, so the error is a float. rel_err : (k,) ndarray or float The relative error of each pair of snapshots X[:,j] and Y[:,j]. If X and Y are one-dimensional, X and Y are treated as single snapshots, so the error is a float. Note that this error may be deceptively large when the norm of a true snapshot, ||X_j|| is small. """ # Check dimensions. if X.shape != Y.shape: raise ValueError("truth X and approximation Y not aligned") if X.ndim not in (1, 2): raise ValueError("X and Y must be one- or two-dimensional") # Compute the error. norm_of_data = _norm(X, axis=0) absolute_error = _norm(X - Y, axis=0) return absolute_error, absolute_error / norm_of_data
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 """ 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]] return _norm(C1 - C2, axis=1)
def norm(x, p=2): if not isfinite(x).all(): return np.nan return _norm(x, p)