Use-Case 04.1: TBP-Diluent-H_2O-HNO_3-UO_2^{2+}-Air Mixing Parameter Study

Single-Stage Solvex Development Cortix Tech 30Sep2025

1. Use-Case 04.1: TBP-Diluent-H\(_2\)O-HNO\(_3\)-UO\(_2^{2+}\)-Air Mixing Parameter Study#

Cortix Tech Logo

Developer: Valmor F. de Almeida, PhD

Cortix Tech, Lowell, MA 01854, USA

Revision date: 02Dec25

Early stage of parametric study simulation using Cortix. The goal here is to provide a mininum framework to help the testing of fixed-parameter simulations.

1.1. Objectives#

  • Develop a usecase scenario for water, nitric acid, and uranyl extraction by TBP with a vapor phase parametric study.

  • Test implementation and present results.

  • Basic tentative flow scheme (pseudo-code):

    import run_stg_script
    archive = list()
    for params in param_list:
        stg = stg_run_script(params)
        archive.append(stg)
    for stg in archive:
        stg.plot_efficiency()
    
'''AI assistance options'''
# Set all to False if you do not have access to OpenAI API and/or AI codes below
cortix_ai = True # Some basic cell AI explanation help
'''Generate proprietary knowledge database?'''
db_save = False # set this to false if going public (online) with this notebook
'''Other helpers'''
fig_count = 0
tbl_count = 0
markdown_display = True # if False code cell output is type: stream, else: markdown. Use True for in-house conversion to .md

1.2. Mass Transfer and Inflow Relative Humidity Variation#

The entire system is prepared as a batch job.

'''Read batch run file'''
from run_tbp_h2o_hno3_uo22plus_air import main as run

if cortix_ai:
    from cortix import CortixAI
    cortix_ai = CortixAI(llm_model='gpt-5-mini', llm_cleverness=0.8)
    cortix_ai.markdown_header_level = 'h3'

if cortix_ai:
    cortix_ai.explain(markdown_display=markdown_display, save_supporting_info=db_save)
Cortix AI assistant: working on explanation...

Overview

This snippet does three things: declares a short module docstring, imports a callable named main from another module and aliases it as run, and — conditionally, when a variable named cortix_ai is truthy — constructs a CortixAI object and calls one of its methods with two keyword arguments.

Line-by-line explanation

  • The first line is a module docstring: ‘Read batch run file’ (a short description attached to the module).

  • from run_tbp_h2o_hno3_uo22plus_air import main as run

    • Imports the object named main from the module run_tbp_h2o_hno3_uo22plus_air and binds it locally to the name run.

    • After this import, calling run(…) would invoke that main function (or callable).

  • if cortix_ai:

    • Tests the truthiness of the name cortix_ai. If it evaluates to True, the indented block runs.

    • This presumes cortix_ai is already defined in the surrounding scope before this snippet executes.

  • from cortix import CortixAI
    
    • Imports the CortixAI class (or callable) from the cortix package inside the conditional branch.

  • cortix_ai = CortixAI(llm_model='gpt-5-mini', llm_cleverness=0.8)
    
    • Instantiates CortixAI with two keyword arguments: llm_model set to ‘gpt-5-mini’ and llm_cleverness set to 0.8.

    • The resulting instance is assigned back to the name cortix_ai, replacing the previous value of cortix_ai in the current scope.

  • cortix_ai.markdown_header_level = 'h3'
    
    • Sets an attribute named markdown_header_level on the CortixAI instance to the string ‘h3’.

  • if cortix_ai:

    • A second truthiness check of cortix_ai; if True, the next line runs.

    • Note this will be True if cortix_ai was truthy before and/or if the prior conditional created a CortixAI instance and assigned it to cortix_ai.

  • cortix_ai.explain(markdown_display=markdown_display, save_supporting_info=db_save)
    
    • Calls the explain method on the cortix_ai instance, passing two keyword arguments: markdown_display (value taken from a name in scope) and save_supporting_info set to the value of db_save in scope.

    • The snippet does not define markdown_display or db_save, so those names must exist in the surrounding context.

Runtime assumptions and observable side effects

  • The snippet assumes the following names exist in scope before it runs:

    • cortix_ai (used as a condition and then reassigned if True)

    • markdown_display and db_save (passed as keyword arguments to the method call)

  • The import of run (main) makes a callable available locally as run; no call to run appears in this snippet.

  • The conditional import and instantiation of CortixAI occur only if cortix_ai is truthy at runtime.

  • The assignment cortix_ai = CortixAI(…) replaces the previous value of cortix_ai in the current namespace with the new instance.

  • The cortix_ai.explain(…) invocation is executed only if cortix_ai evaluates as truthy at that second check; it passes values from the current scope into the method.

AI Parameters:
+ LLM model (OpenAI) = gpt-5-mini
+ LLM cleverness     = 1.0
+ Total # of tokens  = 3449
'''Prepare params dictionary'''
params = dict()
params['make-plots'] = False
params['verbose'] = False
params['loglevel'] = 'error'

Here the base relaxation time of all reactions is progressively increased and all stage data saved for future efficiency analysis.

'''Vary parameter of study'''
stages = list()

rxn_tau_factors = (0.8, 1.1, 1.3, 1.0, 1.2, 0.7, 0.5, 0.9, 0.7)
param_tau_factors = [0.1, 0.5, 1.0, 1.5]

inflow_relative_humidity = 25
param_inflow_rh_factors = [0.1, 0.5, 1.0, 1.5]

for param_tau_factor, param_inflow_rh_factor in zip(param_tau_factors, param_inflow_rh_factors):
    
    params['tau-factor-0'] = rxn_tau_factors[0] * param_tau_factor
    params['tau-factor-1'] = rxn_tau_factors[1] * param_tau_factor
    params['tau-factor-2'] = rxn_tau_factors[2] * param_tau_factor
    params['tau-factor-3'] = rxn_tau_factors[3] * param_tau_factor
    params['tau-factor-4'] = rxn_tau_factors[4] * param_tau_factor
    params['tau-factor-5'] = rxn_tau_factors[5] * param_tau_factor
    params['tau-factor-6'] = rxn_tau_factors[6] * param_tau_factor
    params['tau-factor-7'] = rxn_tau_factors[7] * param_tau_factor
    params['tau-factor-8'] = rxn_tau_factors[8] * param_tau_factor
    print('tau-factor ', param_tau_factor)

    params['inflow-relative-humidity'] = param_inflow_rh_factor * inflow_relative_humidity
    print('inflow-relative-humidity ', params['inflow-relative-humidity'])
    
    stg = run(params)

    stages.append(stg)

if cortix_ai:
    cortix_ai.explain(markdown_display=markdown_display, save_supporting_info=db_save)
tau-factor  0.1
inflow-relative-humidity  2.5
Total mass rate density (mixture volume) residual [g/L-s]= -1.66533e-16
total mass inflow rate [g/min]   = 7.213e+02
total mass outflow rate [g/min]  =  7.171e+02
	 net total mass flow rate [g/min] = -4.149e+00
tau-factor  0.5
inflow-relative-humidity  12.5
Total mass rate density (mixture volume) residual [g/L-s]= -1.66533e-16
total mass inflow rate [g/min]   = 7.312e+02
total mass outflow rate [g/min]  =  7.349e+02
	 net total mass flow rate [g/min] = 3.696e+00
tau-factor  1.0
inflow-relative-humidity  25.0
Total mass rate density (mixture volume) residual [g/L-s]= -3.33067e-16
total mass inflow rate [g/min]   = 7.450e+02
total mass outflow rate [g/min]  =  7.484e+02
	 net total mass flow rate [g/min] = 3.353e+00
tau-factor  1.5
inflow-relative-humidity  37.5
Total mass rate density (mixture volume) residual [g/L-s]= 0.00000e+00
total mass inflow rate [g/min]   = 7.595e+02
total mass outflow rate [g/min]  =  7.438e+02
	 net total mass flow rate [g/min] = -1.571e+01
Cortix AI assistant: working on explanation...

Overview

This snippet runs a parameter sweep: it scales a set of nine “reaction tau” baseline values by several multipliers, scales an inflow relative-humidity baseline by corresponding multipliers, updates a params mapping accordingly, invokes run(params) for each parameter pair, and collects the returned stage objects in a list.

Data and variables

  • The code defines:

    • rxn_tau_factors: tuple of 9 baseline floats (one per tau-factor index 0..8).

    • param_tau_factors: list of 4 scaling factors for the tau values.

    • inflow_relative_humidity: integer baseline 25.

    • param_inflow_rh_factors: list of 4 scaling factors for the inflow RH.

    • stages: initially empty list to collect results.

    • params: assumed to be an existing dictionary (mutated in-place).

    • cortix_ai, markdown_display, db_save: referenced at the end (used only if cortix_ai is truthy).

Loop mechanics and side effects

  • The loop iterates over pairs from zip(param_tau_factors, param_inflow_rh_factors). Because both lists have length 4, the loop runs 4 iterations.

  • In each iteration:

    • It multiplies each of the nine rxn_tau_factors by the current param_tau_factor and assigns the results into params with keys ‘tau-factor-0’ through ‘tau-factor-8’. These assignments overwrite any previous values in params for those keys.

    • It prints the current param_tau_factor via print(‘tau-factor ‘, param_tau_factor).

    • It computes params[‘inflow-relative-humidity’] = param_inflow_rh_factor * inflow_relative_humidity and prints that value via print(‘inflow-relative-humidity ‘, …).

    • It calls stg = run(params) and appends stg to the stages list. run(params) is invoked with the current, mutated params dictionary.

    • After the iteration, params retains the last-assigned values until the next iteration modifies them.

Numeric examples (values produced)

  • inflow-relative-humidity values computed each iteration:

    • 0.1 * 25 = 2.5

    • 0.5 * 25 = 12.5

    • 1.0 * 25 = 25.0

    • 1.5 * 25 = 37.5

  • tau-factor assignments by iteration (each entry is rxn_tau_factors[i] * param_tau_factor):

    • For param_tau_factor = 0.1:

      • 0.08, 0.11, 0.13, 0.10, 0.12, 0.07, 0.05, 0.09, 0.07

    • For param_tau_factor = 0.5:

      • 0.40, 0.55, 0.65, 0.50, 0.60, 0.35, 0.25, 0.45, 0.35

    • For param_tau_factor = 1.0:

      • 0.8, 1.1, 1.3, 1.0, 1.2, 0.7, 0.5, 0.9, 0.7 (same as the baseline tuple)

    • For param_tau_factor = 1.5:

      • 1.2, 1.65, 1.95, 1.5, 1.8, 1.05, 0.75, 1.35, 1.05

Outputs and final state

  • stages becomes a list containing the stg object returned by run(params) from each of the 4 iterations, so len(stages) == 4 after the loop.

  • params ends up with the tau-factor and inflow-relative-humidity values from the final iteration (param_tau_factor = 1.5, param_inflow_rh_factor = 1.5), unless run(params) or other code mutates it further.

  • The print statements emit the current scaling factor and the computed inflow-relative-humidity each iteration.

  • If cortix_ai is truthy, the code calls cortix_ai.explain(markdown_display=markdown_display, save_supporting_info=db_save).

AI Parameters:
+ LLM model (OpenAI) = gpt-5-mini
+ LLM cleverness     = 1.0
+ Total # of tokens  = 4262

1.3. Overall Stage Efficiency#

Parameter variation impact on stage efficiency.

'''Stage overall efficiency'''
from cortix import Units as unit
import matplotlib.pyplot as plt

efficiencies = list()

for stg in stages:
    efficiencies.append(stg.efficiency_history(mean=True))

for eff, tau, rh in zip(efficiencies, param_tau_factors, param_inflow_rh_factors):
    quant = eff
    # Edit quant for AI use below
    quant.name += f"""; @ parameter tau factor = {tau} and parameter relative humidity {rh}"""
    quant.value.name = quant.name
    quant.plot(title=r'Stage Efficiency w/ $\tau_{\mathrm{f}}$ = %2.1f; rh$_{\mathrm{f}}$ = %2.1f'%(tau,rh), x_scaling=1/unit.min, x_label='Time [min]', y_label=quant.latex_name+
               ' ['+quant.unit+']', show=True, figsize=[10,3], error_data=True, error_fill=False)
if cortix_ai: 
    cortix_ai.explain(markdown_display=markdown_display, save_supporting_info=db_save)

fig_count += 1
print(f'Figure {fig_count}: Stage efficiency variation with parameters.')
../../_images/893c7e817fcb95f56a64db872152815e2dd4e45d267033df2850b3c8f699cc4b.png ../../_images/c332a367f0272bdc1220994cd081cfd19d75a215e189188b58dab71c9514e129.png ../../_images/df762513d84cc4a2454cfa14196a1d5023c471003381c412019badde65b29bf7.png ../../_images/3ab0faddbad554963511cff2363bad703b1c23ae4ffa03b8789a67ceaa72a675.png
Cortix AI assistant: working on explanation...

Overview

  • The script builds and plots per-stage efficiency histories for a sequence of stage objects, annotating each plotted quantity with parameter values and incrementing a figure counter before printing a summary line.

Imports and setup

  • from cortix import Units as unit: imports unit definitions; unit.min is later used for x-axis scaling.

  • import matplotlib.pyplot as plt: standard plotting library (plt is not used directly in the shown snippet but is available).

  • efficiencies = list(): prepares an empty list to accumulate efficiency-history objects.

Collection of efficiency histories

  • for stg in stages: iterates over an iterable named stages (each element expected to be a stage object).

    • stg.efficiency_history(mean=True) is called for each stage; the returned object is appended to efficiencies.

    • The appended objects (referred to later as eff) represent time-series quantities with metadata (name, value, unit, latex_name, and plotting methods).

Per-parameter plotting loop

  • for eff, tau, rh in zip(efficiencies, param_tau_factors, param_inflow_rh_factors): iterates in parallel over the collected efficiency objects and two parameter lists (tau factors and relative-humidity factors).

    • quant = eff: assigns a local reference quant to the current efficiency object.

    • quant.name += f”””; @ parameter tau factor = {tau} and parameter relative humidity {rh}”””: appends parameter information to the quantity’s name string.

    • quant.value.name = quant.name: sets the nested value name to match the updated quantity name (so associated value metadata carries the same label).

    • quant.plot(…): calls the quantity’s plot method with these arguments:

      • title: a raw string containing LaTeX fragments and then formatted with %2.1f for tau and rh (so the title shows numeric values with one decimal place). Example pattern: Stage Efficiency w/ $\tau_{\mathrm{f}}$ = 1.0; rh$_{\mathrm{f}}$ = 0.5

      • x_scaling=1/unit.min: rescales the time axis from base units to minutes (factor 1 per minute).

      • x_label=’Time [min]’: label for the x axis.

      • y_label=quant.latex_name + ‘ [’ + quant.unit + ‘]’: constructs the y-axis label from the quantity’s LaTeX name and its unit in square brackets.

      • show=True: display the plot immediately (handled by the quantity’s plot method).

      • figsize=[10,3]: figure size in inches (wide and short).

      • error_data=True, error_fill=False: request plotting of error bars/data but disable a filled error band (specific rendering governed by the plot implementation).

Conditional auxiliary call and final output

  • if cortix_ai: cortix_ai.explain(markdown_display=markdown_display, save_supporting_info=db_save)

    • The call to cortix_ai.explain is executed only if cortix_ai evaluates truthy; it is invoked with two keyword arguments passed through from local variables.

  • fig_count += 1: increments a running figure counter (assumes fig_count was defined earlier).

  • print(f’Figure {fig_count}: Stage efficiency variation with parameters.’): prints a one-line summary identifying the updated figure count and the plotted content.

Data and side-effect summary

  • Side effects performed by the snippet:

    • Mutates quantity metadata (quant.name and quant.value.name) to include parameter annotations.

    • Produces one plot per zipped tuple (efficiency, tau, rh) via quant.plot.

    • Optionally calls cortix_ai.explain when cortix_ai is present.

    • Increments and prints fig_count.

  • Inputs expected (not defined in snippet):

    • stages: iterable of stage objects exposing efficiency_history(mean=True).

    • param_tau_factors and param_inflow_rh_factors: iterables of numeric parameter values of equal length to efficiencies.

    • cortix_ai, markdown_display, db_save, fig_count: external variables referenced by the snippet.

AI Parameters:
+ LLM model (OpenAI) = gpt-5-mini
+ LLM cleverness     = 1.0
+ Total # of tokens  = 3753
Figure 1: Stage efficiency variation with parameters.

1.3.1. Analysis#

LLM analysis.

'''Analyze efficiencies'''
if cortix_ai: 
    cortix_ai.explain(quant=efficiencies, markdown_header_level='<h4>', markdown_display=markdown_display, save_supporting_info=db_save)
Cortix AI assistant: working on explanation...

Summary

  • Four time-series (tau factor = 0.1, 0.5, 1.0, 1.5) share the same time grid (0 … 247.699 s) and identical initial values at t = 0 (column 0 = 15.0002, column 1 = 21.6026).

  • Column “0” increases with time and approaches a plateau; column “1” decreases with time and approaches a low steady value.

  • The rate and asymptotic values depend strongly on the tau factor: smaller tau → faster rise of column 0 and faster fall of column 1.

Time evolution — column 0 (first numeric column)

  • At t = 0 all cases start at 15.0002.

  • Early-time growth (t ≈ 15–31 s) is much faster for small tau:

    • tau = 0.1: 81.53 (t = 15.48 s) → 87.78 (t = 30.96 s)

    • tau = 0.5: 44.03 → 57.24

    • tau = 1.0: 29.54 → 39.04

    • tau = 1.5: 23.79 → 30.37

  • Long-time plateau (t = 247.699 s) values:

    • tau = 0.1: 91.7701

    • tau = 0.5: 69.4544

    • tau = 1.0: 53.4794

    • tau = 1.5: 43.6286

  • Interpretation: increasing tau factor slows the approach to higher efficiency and lowers the asymptotic efficiency in column 0.

Time evolution — column 1 (second numeric column)

  • All cases start at 21.6026 and monotonically decrease.

  • Early-time decrease (t ≈ 15–31 s):

    • tau = 0.1: 21.60 → 15.09 → 6.91 by 30.96 s

    • tau = 0.5: 21.60 → 19.21 → 15.29

    • tau = 1.0: 21.60 → 17.99 → 15.15

    • tau = 1.5: 21.60 → 17.37 → 14.53

  • Long-time plateau (t = 247.699 s) values:

    • tau = 0.1: 2.12651

    • tau = 0.5: 6.34104

    • tau = 1.0: 7.69490

    • tau = 1.5: 7.90588

  • Interpretation: smaller tau yields a faster and deeper reduction in column 1; larger tau produces a slower decline and a higher steady residual.

Direct comparison and key takeaways

  • At intermediate and long times, the series are well separated by tau:

    • Column 0 ordering (largest to smallest) at t = 247.7 s: tau 0.1 > 0.5 > 1.0 > 1.5.

    • Column 1 ordering (smallest to largest) at t = 247.7 s: tau 0.1 < 0.5 < 1.0 < 1.5.

  • Magnitude of change relative to t = 0:

    • Column 0 net increase by t = 247.7 s:

      • +76.77 (tau 0.1), +54.45 (0.5), +38.48 (1.0), +28.63 (1.5).

    • Column 1 net decrease by t = 247.7 s:

      • −19.48 (tau 0.1), −15.26 (0.5), −13.91 (1.0), −13.70 (1.5).

  • Dynamics:

    • tau = 0.1 reaches near-steady values earlier (by ~30–120 s) compared with larger tau where approach to steady state is slower and plateaus at lower (column 0) / higher (column 1) magnitudes.

  • Overall conclusion: Tau factor is a controlling time-scale parameter here — smaller tau accelerates conversion of the quantity represented by column 1 into that represented by column 0 and produces a higher steady-state for column 0 and a lower residual for column 1.

AI Parameters:
+ LLM model (OpenAI) = gpt-5-mini
+ LLM cleverness     = 1.0
+ Total # of tokens  = 5879
'''Stage overall efficiency'''
from cortix import Units as unit
import matplotlib.pyplot as plt

for eff, tau, rh in zip(efficiencies, param_tau_factors, param_inflow_rh_factors):
    quant = eff
    quant.plot(title=r'Stage Efficiency w/ $\tau_\mathrm{f}$ = %2.1f; rh$_{\mathrm{f}}$ = %2.1f'%(tau,rh), x_scaling=1/unit.min, x_label='Time [min]', y_label=quant.latex_name+
               ' ['+quant.unit+']', legend=['E', 'std'], show=True, figsize=[10,3], error_data=False, error_fill=False)
fig_count += 1
print(f'Figure {fig_count}: Stage efficiency and deviation variation with parameters.')
../../_images/4bad6dbce3a406a103174028ebbe8aa2734c519407661d42bbf4bb55fd88ad43.png ../../_images/5fd77a73a1a7e8ac689ff62be85402f5e09befb8f2e641214be9b06502e1672c.png ../../_images/c559f817ff34a020b27285abe5f03a9adb14b322095518cffdcc8e415a5f8ced.png ../../_images/46977071a71b0f15126283b8c2b634a5befd911aa564c3addbd83c9e621d9eb8.png
Figure 2: Stage efficiency and deviation variation with parameters.
'''For debugging purposes'''
import matplotlib.pyplot as plt
import numpy as np

for eff in efficiencies:
    data = eff.value
    values = list()
    errors = list()
    for entry in data:
        values.append(entry[0])
        errors.append(entry[1])
    values = np.array(values)
    errors = np.array(errors)
    
    plt.plot(data.index/60, values)
    plt.fill_between(data.index/60, values - errors, values + errors, alpha=0.15)
    
plt.grid()

fig_count += 1
print(f'Figure {fig_count}: Multiplot efficiency variation with parameters.')
Figure 3: Multiplot efficiency variation with parameters.
../../_images/5a36b424acb54af7abcb156a4c540c87f6c45f53dfba51eabb85ba75e447a3f7.png