<jupyter_start><jupyter_text>Using Source and Sink Terms for a Chemical Reaction`OpenPNM` is capable of simulating chemical reactions in pores by adding source and sink terms. This example shows how to add source and sink terms to a steady state fickian diffusion simulation.<jupyter_code>import warnings
import scipy as sp
import numpy as np
import openpnm as op
import matplotlib.pyplot as plt
np.set_printoptions(precision=5)
np.random.seed(10)
%matplotlib inline<jupyter_output><empty_output><jupyter_text>Create Network and Other ObjectsStart by creating the network, geometry, phase and physics objects as usual:<jupyter_code>pn = op.network.Cubic(shape=[40, 40], spacing=1e-4)
geo = op.geometry.StickAndBall(network=pn, pores=pn.Ps, throats=pn.Ts)
gas = op.phases.Air(network=pn)
phys = op.physics.Standard(network=pn, phase=gas, geometry=geo)<jupyter_output><empty_output><jupyter_text>Now add the source and sink models to the physics object.  In this case we'll think of the as chemical reactions.  We'll add one source term and one sink term, meaning one negative reaction rate and one positive reaction rate<jupyter_code>gas['pore.concentration'] = 0
phys['pore.sinkA'] = -1e-10
phys['pore.sinkb'] = 1
phys.add_model(propname='pore.sink', model=op.models.physics.generic_source_term.power_law,
               A1='pore.sinkA', A2='pore.sinkb', X='pore.concentration')
phys['pore.srcA'] = 1e-11
phys['pore.srcb'] = 1
phys.add_model(propname='pore.source', model=op.models.physics.generic_source_term.power_law,
               A1='pore.srcA', A2='pore.srcb', X='pore.concentration')<jupyter_output><empty_output><jupyter_text>Setup Fickian Diffusion with Sink TermsNow we setup a FickianDiffusion algorithm, with concentration boundary conditions on two side, and apply the sink term to 3 pores:<jupyter_code>rx = op.algorithms.FickianDiffusion(network=pn)
rx.setup(phase=gas)
rx.set_source(propname='pore.sink', pores=[420, 820, 1220])
rx.set_value_BC(values=1, pores=pn.pores('front'))
rx.set_value_BC(values=1, pores=pn.pores('back'))
rx.run()<jupyter_output><empty_output><jupyter_text>Plot DistributionsWe can use the ``plot_connections`` and ``plot_coordinates`` to get a quick view of the pore network, with colors and sizes scaled appropriately.<jupyter_code>pn['pore.concentration'] = rx['pore.concentration']
fig = plt.figure(figsize=[15, 15])
fig = op.topotools.plot_connections(network=pn, color='k', alpha=.2, fig=fig)
fig = op.topotools.plot_coordinates(network=pn, color_by=pn['pore.concentration'],
                                    size_by=pn['pore.diameter'], cmap='plasma',
                                    fig=fig, markersize=100)
_ = plt.axis('off')<jupyter_output><empty_output><jupyter_text>Plot Distributions as HeatmapsBecause the network is a 2D cubic, it is convenient to visualize it as an image, so we reshape the 'pore.concentration' array that is produced by the FickianDiffusion algorithm upon running, and turn it into a colormap representing concentration in each pore.<jupyter_code>pn['pore.concentration'] = rx['pore.concentration']
fig = plt.figure(figsize=[15, 15])
fig = op.topotools.plot_connections(network=pn, color='k', alpha=0, fig=fig)
fig = op.topotools.plot_coordinates(network=pn, color_by=pn['pore.concentration'], cmap='plasma',
                                    fig=fig, markersize=420, marker='s')
_ = plt.axis('off')<jupyter_output><empty_output><jupyter_text>Setup Fickian Diffusion with Source TermsSimilarly, for the source term:<jupyter_code>rx = op.algorithms.FickianDiffusion(network=pn)
rx.setup(phase=gas)
rx.set_source(propname='pore.source', pores=[420, 820, 1220])
rx.set_value_BC(values=1, pores=pn.pores('front'))
rx.set_value_BC(values=1, pores=pn.pores('back'))
rx.run()<jupyter_output><empty_output><jupyter_text>And plotting the result as a color map:<jupyter_code>#NBVAL_IGNORE_OUTPUT
pn['pore.concentration'] = rx['pore.concentration'] - 1
fig = plt.figure(figsize=[15, 15])
fig = op.topotools.plot_connections(network=pn, color='k', alpha=0, fig=fig)
fig = op.topotools.plot_coordinates(network=pn, color_by=pn['pore.concentration'], cmap='plasma',
                                    fig=fig, markersize=420, marker='s')
_ = plt.axis('off')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12535211267605634, 'fraction_numerical': 0.017136150234741784, 'mean_word_length': 5.731437598736177, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '509820', 'license': 'MIT', 'n_tokens_mistral': 1538, 'n_tokens_neox': 1430, 'n_words': 329, 'path': 'examples/notebooks/algorithms/reactive/diffusion_with_source_and_sink_terms.ipynb', 'repo_name': 'Eravalord/OpenPNM', 'size': '4260'}