PMEAL / OpenPNM

A Python package for performing pore network modeling of porous media
http://openpnm.org
MIT License
442 stars 175 forks source link

Adding boundary pores and defining physics #984

Closed SeongyeopJung closed 6 years ago

SeongyeopJung commented 6 years ago

HI, I've been using OpenPNM for my research and just updated to V2.0. However, I got some issues for adding boundary pores in Bravais 'fcc' network and VoronoiFiber material and defining physics in two geometries.

  1. Which method can be used to add boundary pores on VoronoiFibers material and Bravais nework?
  2. when using VoronoiFibers material, physics were added like below code,

_phys_air1 = op.physics.Standard(network=net, phase=air, geometry=del_geom) phys_air2 = op.physics.Standard(network=net, phase=air, geometry=vorgeom)

But error returns :

_throat.hydraulic_conductance was not run since the following properties are missing: ['throat.viscosity', 'throat.equivalent_area', 'throat.conduit_lengths'] throat.diffusive_conductance was not run since the following properties are missing: ['throat.diffusivity', 'throat.equivalent_area', 'throat.conduit_lengths'] throat.entry_pressure was not run since the following properties are missing: ['pore.surface_tension', 'throat.diameter'] throat.thermal_conductance was not run since the following properties are missing: ['throat.thermal_conductivity', 'throat.equivalent_area', 'throat.conduit_lengths'] throat.electrical_conductance was not run since the following properties are missing: ['pore.electrical_conductivity', 'throat.electrical_conductivity', 'throat.equivalent_area', 'throat.conduitlengths']

  1. In case of the FCC, I applied boundary pores and defined physics like below,

_Ps = fcc.pores('top') tt.clone_pores(network=fcc, pores=Ps, labels='top'+'_boundary') Ps = fcc.pores('bottom') tt.clone_pores(network=fcc, pores=Ps, labels='bottom'+'_boundary')

Ps_int = fcc.pores('boundary', mode='not') Ps_boun = fcc.pores('boundary') Ts_int = fcc.throats('boundary', mode = 'not') Ts_boun = fcc.throats('boundary') geom = op.geometry.StickAndBall(network=fcc, pores=Ps_int, throats=Ts_int) boun = op.geometry.Boundary(network=fcc, pores=Ps_boun, throats=Ts_boun) air = op.phases.Air(network=fcc) phys_air01 = op.physics.Standard(network=fcc, phase=air, geometry=geom) physair02 = op.physics.Standard(network=fcc, phase=air, geometry=boun)

But this also does not work. What have I done wrong?

  1. Do calc_effective_diffusivity and permeability methods work for both Bravais and VoronoidFibers?

Everything was fine when I was using V1.x . But I got stuck right now.

ma-sadeghi commented 6 years ago

@SeongyeopJung Can you paste here the whole script you're running?

SeongyeopJung commented 6 years ago

@ma-sadeghi Thanks, this is for Bravais FCC network

_import openpnm as op from openpnm import topotools as tt import numpy as np

wrk = op.Workspace() wrk.clear()

space = 0.00005 W = 0.001 D = 0.001 H = 0.0004 shape = [int(round(W/space)), int(round(D/space)), int(round(H/space))] fcc = op.network.Bravais(shape=[shape[0], shape[1], shape[2]], spacing = space, mode='fcc')

Ps = fcc.pores('top') tt.clone_pores(network=fcc, pores=Ps, labels='top'+'_boundary') Ps = fcc.pores('bottom') tt.clone_pores(network=fcc, pores=Ps, labels='bottom'+'_boundary')

Ps_int = fcc.pores('boundary', mode='not') Ps_boun = fcc.pores('boundary') Ts_int = fcc.throats('boundary', mode = 'not') Ts_boun = fcc.throats('boundary') geom = op.geometry.StickAndBall(network=fcc, pores=Ps_int, throats=Ts_int) boun = op.geometry.Boundary(network=fcc, pores=Ps_boun, throats=Ts_boun)

air = op.phases.Air(network=fcc) phys_air01 = op.physics.Standard(network=fcc, phase=air, geometry=geom) phys_air02 = op.physics.Standard(network=fcc, phase=air, geometry=boun)

Define Fickian diffusion algorithm

fd = op.algorithms.FickianDiffusion(network=fcc, phase=air)

inlet = fcc.pores('top_boundary') outlet = fcc.pores('bottom_boundary') fd.set_value_BC(pores=inlet, values=1.0) fd.set_value_BC(pores=outlet, values=0.0)

fd.run()

print(fd.settings)

c = fd['pore.concentration']

fig = tt.plot_connections(network=fcc, throats=geom.throats()) rate_inlet = fd.rate(pores=inlet)[0] print('Mass flow rate from inlet:', rate_inlet, 'mol/s') D_eff = fd.calc_eff_diffusivity()

Define Stokes flow algorithm

sf = op.algorithms.StokesFlow(network = fcc) sf.setup(phase = air) sf.set_value_BC(pores = inlet, values = 101328*2) sf.set_value_BC(pores = outlet, values = 101328) sf.run() K = sf.calc_effpermeability()

SeongyeopJung commented 6 years ago

Ans this is for VoronoiFibers. I was just modifying the example

_import openpnm as op from openpnm.utils import vertexops as vo import scipy as sp import matplotlib.pyplot as plt

scale = 1e-4 wrk = op.Workspace() wrk.clear() sp.random.seed(1) mat = op.materials.VoronoiFibers(num_points=100, fiber_rad=5e-6, resolution=1e-6, shape=[scale, scale, scale], name='test')

net = mat.network print(net)

del_geom = mat.geometries()['test_del'] vor_geom = mat.geometries()['test_vor']

from openpnm import topotools as tt tt.trim(network=net, pores=net.pores('voronoi')) tt.label_faces(network = net) print(net)

fig = tt.plot_connections(network=net, throats=del_geom.throats())

vo.plot_pore(del_geom, pores=del_geom.pores()) vo.plot_throat(del_geom, throats=del_geom.throats()[:4])

plt.figure() del_geom.show_hist(props=['pore.diameter']) plt.show()

plt.figure() del_geom.show_hist(props=['throat.diameter']) plt.show()

del_geom.plot_porosity_profile() del_geom.plot_fiber_slice(plane=[0, 0.5, 0])

Set phase

air = op.phases.Air(network=net)

Set physics

phys_air1 = op.physics.Standard(network=net, phase=air, geometry=del_geom) phys_air2 = op.physics.Standard(network=net, phase=air, geometry=vor_geom)

Set Fickian diffusion algorithm

fd = op.algorithms.FickianDiffusion(network=net, phase=air)

inlet = net.pores('top') outlet = net.pores('bottom') fd.set_value_BC(pores=inlet, values=1.0) fd.set_value_BC(pores=outlet, values=0.0)

fd.run()

print(fd.settings)

c = fd['pore.concentration']_

ma-sadeghi commented 6 years ago

@SeongyeopJung Quick fix:

  1. When cloning pores to add as boundary pores, you need to shift them accordingly so they don't overlap any pores in the original network. Basically, what's happening in your code snippet is that you're cloning top and bottom pores on top of the top and bottom pores, which forces max_size model in StickAndBall to return 0. With 0 as max_size, pore.area is also forced to be 0, which results in 0 conductance for some of the throats, and finally an ill-conditioned A matrix. Either (a) don't try to create boundary pores and simply use top and bottom pores as your actual boundaries or (b) shift the z values of the cloned pores so they won't overlap with top and bottom pores:
topBC = fcc.pores('top_boundary')
temp = fcc['pore.coords'][topBC]
temp[:,2] += space
fcc['pore.coords'][topBC] = temp
bottomBC = fcc.pores('bottom_boundary')
temp = fcc['pore.coords'][bottomBC]
temp[:,2] -= space
fcc['pore.coords'][bottomBC] = temp
  1. For now, don't use Boundary class for your boundary pores. Use StickAndBall instead. I need to dig this deeper. It seems that the Boundary class changes some of the entries in the A matrix to inf. I'll let you know once this is tackled. By the way, version 2.0 is still in beta form and is not official yet. You might want to clone our dev branch which has the latest changes/bug fixes, until an official announcement is made.
jgostick commented 6 years ago

See #986 ... I think we should discuss adding boundary pores more gracefully/automatically. At least each network should have it's own version of add_boundary_pores.

SeongyeopJung commented 6 years ago

@jgostick @ma-sadeghi Thank you so much! Also, could you check question No.2, 'standard' method for defining physics? Sorry for the inconvenience.

ma-sadeghi commented 6 years ago

@SeongyeopJung That is a known issue and we're going to discuss it with the other developers today. Will update you soon :)

jgostick commented 6 years ago

I will close this, since we'll be seeing you tomorrow!