Overall Design

The design of OpenPNM is to separate different types of properties between different objects. There are 5 types: Network, Geometry, Phase, Physics, and Algorithms. Each of these are described in more detail below, but their names clearly indicate what sort of data or calculations are assigned to each.

The image below outlines how each of the main objects in OpenPNM descend from the Python dict class. Using the Object Oriented Programming (OOP) paradigm, each of the main OpenPNM objects actually descend from a common class called Core. The Core class defines the majority of the functionality, which is then enhanced and extended by each descendent. This extra functionality is explored in more detail for each main object in the sections below.

http://i.imgur.com/k4Far1W.png

Core

Core is a subclass of the Python Dictionary or dict. A dict is a very handy data structure that can store any piece of data by name, using the following:

>>> # Instantiate a dict and add some values by name
>>> foo = dict()
>>> foo['an_int'] = 1
>>> foo['a_list'] = [1, 2, 3]
>>> foo['a_string'] = 'bar'
>>> # And data can be retrieved by name
>>> foo['an_int']
1
>>> foo['a_list']
[1, 2, 3]

The Python dict class comes with a variety of methods for adding, removing, and inspecting the data stored within. The following command will generate a list of all these methods, which include things like pop for removing items from the dictionary, and keys for listing all the current dictionary entries.

>>> methods = [item for item in dir(foo) if not item.startswith('_')]

The Core class possess all of these methods, plus another few dozen methods that were added by OpenPNM. These additional methods also pertain to the manipulation of data, but are specific to the types of data used in OpenPNM.

1. Querying Defined Properties and Labels

Returns a list of which properties or labels exist in the dictionary. These methods are basically the same as the keys method, but return a subset of the entries. Any arrays of Boolean type are considered labels, while all other are properties. The returned list outputs a nicely formatted table to the command line when it is printed.

props([element, mode]) Returns a list containing the names of all defined pore or throat properties.
labels([pores, throats, element, mode]) Returns the labels applied to specified pore or throat locations

2. Counting Pores and Throats

Returns the number of pores or throats that the object controls. Both optionally accept a list of labels and returns the number of pores or throats possessing those labels. There is a mode argument which allows control over how the label query is performed. Np and Nt are short-cuts that return the total number of pores or throats.

num_pores([labels, mode]) Returns the number of pores of the specified labels
num_throats([labels, mode]) Return the number of throats of the specified labels
Np A shortcut to query the total number of pores on the object’
Nt A shortcut to query the total number of throats on the object’

3. Retrieving a List of Specific Pores and Throats

Returns a list of pore or throat indices. Both optionally accept a list of labels and returns only a list of pores or throats possessing those labels. There is a mode argument which allows control over how the label query is performed. Ps and Ts are short-cuts that return ALL of the pore or throat indices.

pores([labels, mode]) Returns pore locations where given labels exist, according to the logic specified by the mode argument.
throats([labels, mode]) Returns throat locations where given labels exist, according to the logic specified by the mode argument.
Ps A shortcut to get a list of all pores on the object
Ts A shortcut to get a list of all throats on the object

4. Converting Between Masks and Indices

These methods allow the conversion between numeric indices and Boolean masks.

tomask([pores, throats]) Convert a list of pore or throat indices into a boolean mask of the
toindices(mask) Convert a boolean mask a list of pore or throat indices

5. Mapping Pore and Throat Indices Between Objects

Each Core object has it’s own internal numbering scheme, so these methods are for converting the pore or throat indices from one object to another. Practically speaking this usually means mapping from a Geometry or Physics object onto the Network, so Pnet and Tnet are short-cuts for retrieving a list of pore or throat indices on the network.

map_pores([target, pores, return_mapping]) Accepts a list of pores from the caller object and maps them onto the
map_throats([target, throats, return_mapping]) Accepts a list of throats from the caller object and maps them onto the
Pnet A shortcut to retrieve the mapping of the current object’s pores onto the network.
Tnet A shortcut to retrieve the mapping of the current object’s throats onto the network.

6. Looking Up Other Objects in the Simulation

When each object is instantiated it is associated with the other objects within the simulation. These methods allow for retrieval of these other objects.

OpenPNM.Base.Core.network
OpenPNM.Base.Core.geometries
OpenPNM.Base.Core.phases
OpenPNM.Base.Core.physics

7. Interpolating Between Pore and Throat Data

Data is often calculated or assigned to pores or throats only. This method enables the conversion of data between these.

interpolate_data(data) Determines a pore (or throat) property as the average of it’s

8. Check the Health of all Data Arrays

Checks whether any data on the object is not well formed, such as containing NaNs, or infs. This is handy be running an algorithm to ensure that all necessary properties have been defined everywhere.

check_data_health([props, element]) Check the health of pore and throat data arrays.

9. Using Pore-Scale Models

The models attribute actually contains a nested dictionary which stores all the information related to the pore-scale models. This is described elsewhere in detail. add_model and regenerate are wrapper or helper methods to provide quicker access to the add and regenerate methods of the models dict.

add_model(propname, model[, regen_mode]) Add specified property estimation model to the object.
regenerate([props, mode]) This updates properties using any models on the object that were

10. Find and Set the Object’s Name

Contains a unique string identifier for the object. It can be specified or assigned at will, but no to objects can have the same name.

name

Network

1. Check the Health of Associated Geometry Objects

Inspects that all pores and throats have been assigned to a Geometry object.

check_geometry_health() Perform a check to find pores with overlapping or undefined Geometries

2. Check the Health of the Netowrk Topology

Performs a suite of topological checks for ill conditioned networks (disconnected pores, duplicate throats, etc.)

check_network_health() This method check the network topological health by checking for:

3. Manipulate Pore Topology

These are topological manipulation methods that are used to add or remove pores and throats from the network. These are helper methods for the actual functions in Network.tools.

clone_pores(pores[, apply_label, mode]) This function as been moved to Network.tools and remains here for backward compatibility.
connect_pores(pores1, pores2[, labels]) This function as been moved to Network.tools and remains here for backward compatibility.
extend([pore_coords, throat_conns, labels]) This function as been moved to Network.tools and remains here for backward compatibility.
stitch(donor, P_donor, P_network, method[, ...]) This function as been moved to Network.tools and remains here for backward compatibility.
trim([pores, throats]) This function as been moved to Network.tools and remains here for backward compatibility.

4. Query Neighborhood

These methods can be used to query the neighborhood around a given set of pores.

find_neighbor_pores(pores[, mode, flatten, ...]) Returns a list of pores neighboring the given pore(s)
find_neighbor_throats(pores[, mode, flatten]) Returns a list of throats neighboring the given pore(s)
find_nearby_pores(pores, distance[, ...]) Find all pores within a given radial distance of the input pore(s) regardless of whether or not they are toplogically connected.
find_connected_pores([throats, flatten]) Return a list of pores connected to the given list of throats
find_connecting_throat(P1, P2) Return the throat number connecting pairs of pores

5. Adjacency and Incidence Matrices

Returns a Scipy Sparse array describing the topology of the network.

create_adjacency_matrix([data, sprsfmt, ...]) Generates a weighted adjacency matrix in the desired sparse format
create_incidence_matrix([data, sprsfmt, ...]) Creates an incidence matrix filled with supplied throat values

6. Search for Clusters of Pores

Finds connected clusters of pores based on a given list of Boolean values. The 2nd generation of this algorithm has more options that the original, which was kept for backwards compatibility.

find_clusters([mask]) Identify connected clusters of pores in the network.
find_clusters2([mask, t_labels]) Identify connected clusters of pores in the network.

7. Query the Domain Size

These calculate the bulk dimensions of the domain.

domain_area(face) Calculate the area of a given network face
domain_length(face_1, face_2) Calculate the distance between two faces of the network
domain_bulk_volume()
domain_pore_volume()

Geometry

1. Assign Geometry to Specific Pores and Throats

When instantiating a Geometry object it is normal to specify which pores and throats it applies to. These can be adjusted after the fact with this method.

set_locations([pores, throats, mode]) Assign or unassign a Geometry object to specified locations

Phase

1. Check the Health of Associated Physics Objects

Inspects that all pores and throats have been assigned to a Physics object.

check_physics_health() Perform a check to find pores which have overlapping or undefined Physics

2. Check the Health of a Mixture Phase

Mixtures are not fully implemented yet, but this makes sure all mole fractions sum to 1.

check_mixture_health() Query the properties of the ‘virtual phases’ that make up a mixture

Physics

1. Assign Physics to Specific Pores and Throats

When instantiating a Physics object it is normal to specify which pores and throats it applies to. These can be adjusted after the fact with this method.

set_locations([pores, throats, mode]) Assign or unassign a Physics object to specified locations

2. Lookup the Parent Phase

The phases method of the Core class gives the ability to find a list of all Phases in the simulation, but this method returns a handle to the specific Phase it’s associated with.

parent_phase

Algorithms

Depending on the Algorithm in question, the additional methods can vary. Most have:

1. Specifying Setup Parameters

This method is called to specify some of the optional parameters

2. Setting Boundary Conditions

Used to specify the boundary conditions of the simulation. Some methods also include set_inlets and set_outlets.