{ "cells": [ { "cell_type": "markdown", "id": "9eb831f3-66b4-4601-9e84-fe801e7aa9fc", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "# Solute and water transport parameters" ] }, { "cell_type": "code", "id": "b6cc47ef-4c99-4005-b041-b44dcb72312d", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [], "ExecuteTime": { "end_time": "2026-02-26T10:28:32.239372Z", "start_time": "2026-02-26T10:28:31.363049Z" } }, "source": [ "from openalea.widgets.plantgl import PlantGL # notebook viewer 3D\n", "from openalea.plantgl.algo.view import view # 2D view\n", "\n", "from openalea.hydroroot.main import root_builder, hydroroot_solute_flow\n", "from openalea.hydroroot.init_parameter import Parameters\n", "from openalea.hydroroot.read_file import read_archi_data\n", "from openalea.hydroroot.display import mtg_scene\n" ], "outputs": [], "execution_count": 1 }, { "cell_type": "markdown", "id": "6d85c30b-723a-420a-8491-1da6c84f697c", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "Read the yaml file and set the Parameters variables, assuming that the code is run from the example folder" ] }, { "cell_type": "code", "id": "e8f87e3b-3e41-476a-9aa2-c2ad676606cf", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [], "ExecuteTime": { "end_time": "2026-02-26T10:28:32.253194Z", "start_time": "2026-02-26T10:28:32.245188Z" } }, "source": [ "parameter = Parameters()\n", "parameter.read_file('parameters_Ctr-3P2.yml')" ], "outputs": [], "execution_count": 2 }, { "cell_type": "markdown", "id": "11548f4b-dd19-43b3-b4e8-5ceff22b2684", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "Read the architecture file and build the MTG" ] }, { "cell_type": "code", "id": "62a1f2a1-0aa6-492c-8b6f-5c20a7ab3f28", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [], "ExecuteTime": { "end_time": "2026-02-26T10:28:32.393348Z", "start_time": "2026-02-26T10:28:32.293820Z" } }, "source": [ "fname = parameter.archi['input_dir'] + parameter.archi['input_file'][0]\n", "df = read_archi_data(fname)\n", "g, primary_length, total_length, surface, seed = root_builder( primary_length = parameter.archi['primary_length'],\n", " delta = parameter.archi['branching_delay'],\n", " nude_length = parameter.archi['nude_length'], \n", " df = df,\n", " segment_length = parameter.archi['segment_length'],\n", " length_data = parameter.archi['length_data'],\n", " order_max = parameter.archi['order_max'],\n", " order_decrease_factor = parameter.archi['order_decrease_factor'],\n", " ref_radius = parameter.archi['ref_radius'])" ], "outputs": [], "execution_count": 3 }, { "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "cell_type": "markdown", "source": "In the code the concentration are in $mol.\\mu L^{-1}$, then we convert them from $mol.m^{-3}$", "id": "b7185f39f382a967" }, { "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [], "ExecuteTime": { "end_time": "2026-02-26T10:28:32.408579Z", "start_time": "2026-02-26T10:28:32.406473Z" } }, "cell_type": "code", "source": [ "Cse = parameter.solute['Cse'] * 1e-9 # mol/m3 -> mol/microL, external permeating solute concentration\n", "Ce = parameter.solute['Ce'] * 1e-9 # mol/m3 -> mol/microL, external non-permeating solute concentration" ], "id": "8865eb091ed8b66c", "outputs": [], "execution_count": 4 }, { "cell_type": "markdown", "id": "28d53799-afd2-4df8-9178-8b7204706d59", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": "Perform the calculation" }, { "cell_type": "code", "id": "f5c05023-42e7-4aef-b4cf-eee675a24f5e", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [], "ExecuteTime": { "end_time": "2026-02-26T10:28:32.771414Z", "start_time": "2026-02-26T10:28:32.453761Z" } }, "source": [ "g, Jv = hydroroot_solute_flow(g, psi_e = parameter.exp['psi_e'],\n", " psi_base = parameter.exp['psi_base'],\n", " k0 = parameter.hydro['k0'],\n", " axial_conductivity_data = parameter.hydro['axial_conductance_data'],\n", " J_s = parameter.solute['J_s'],\n", " Ps=parameter.solute['P_s'],\n", " Cse = Cse,\n", " Ce=Ce,\n", " sigma = parameter.solute['Sigma'])" ], "outputs": [], "execution_count": 5 }, { "cell_type": "code", "id": "8cb74613-2f9c-418a-af07-8247f6d5b4a6", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [], "ExecuteTime": { "end_time": "2026-02-26T10:28:32.783465Z", "start_time": "2026-02-26T10:28:32.778675Z" } }, "source": [ "result=f\"\"\"\n", "primary length (m): {primary_length}\n", "surface (m2): {surface}\n", "total length (m): {total_length}\n", "flux (microL/s): {Jv}\n", "\"\"\"\n", "print(result)" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "primary length (m): 0.434\n", "surface (m2): 0.005643500494241343\n", "total length (m): 3.979\n", "flux (microL/s): 0.025700314390474904\n", "\n" ] } ], "execution_count": 6 }, { "cell_type": "markdown", "id": "0707c4b6-d135-4e8f-9ac0-7ee15962a0e7", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "Display the concentration in the architecture 3D view" ] }, { "cell_type": "code", "id": "7fc6e80b-5927-429a-ac7b-a2c90ffa30d5", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [], "ExecuteTime": { "end_time": "2026-02-26T10:28:33.924358Z", "start_time": "2026-02-26T10:28:32.827790Z" } }, "source": [ "s = mtg_scene(g, prop_cmap = 'C') # create a scene from the mtg with the property j is the radial flux in ul/s\n", "PlantGL(s)" ], "outputs": [ { "data": { "text/plain": [ "Plot(antialias=3, axes=['x', 'y', 'z'], axes_helper=1.0, axes_helper_colors=[16711680, 65280, 255], background…" ], "application/vnd.jupyter.widget-view+json": { "version_major": 2, "version_minor": 0, "model_id": "584d9a2bf0734c209206a738e1942f32" } }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 7 }, { "metadata": { "ExecuteTime": { "end_time": "2026-02-26T10:28:34.201735Z", "start_time": "2026-02-26T10:28:33.947700Z" } }, "cell_type": "code", "source": [ "g, Jv = hydroroot_solute_flow(g, psi_e = parameter.exp['psi_base'],\n", " psi_base = parameter.exp['psi_base'],\n", " k0 = parameter.hydro['k0'],\n", " axial_conductivity_data = parameter.hydro['axial_conductance_data'],\n", " J_s = parameter.solute['J_s'],\n", " Ps=parameter.solute['P_s'],\n", " Cse = Cse,\n", " Ce=Ce,\n", " sigma = parameter.solute['Sigma'])\n", "result=f\"\"\"\n", "primary length (m): {primary_length:.3f}\n", "surface (m2): {surface:.3e}\n", "total length (m): {total_length:.3f}\n", "flux (microL/s): {Jv:.4f}\n", "\"\"\"\n", "print(result)" ], "id": "30bb6ef9b4de542a", "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "primary length (m): 0.434\n", "surface (m2): 5.644e-03\n", "total length (m): 3.979\n", "flux (microL/s): 0.0072\n", "\n" ] } ], "execution_count": 8 }, { "metadata": {}, "cell_type": "markdown", "source": [ "#### Adjustement of Js\n", "\n", "Let try to adjust the active pumping rate `Js` to simulate a higher flux `Jv_to_fit`\n", "\n", "The adjustement is done by a simple Newton-Raphson scheme" ], "id": "379068dc79a7c3b0" }, { "metadata": { "ExecuteTime": { "end_time": "2026-02-26T10:28:38.446573Z", "start_time": "2026-02-26T10:28:34.207862Z" } }, "cell_type": "code", "source": [ "Jv_to_fit = 0.01\n", "Js_old = parameter.solute['J_s']\n", "F_old = (Jv - Jv_to_fit) ** 2.0 # the objective function\n", "Js = 1.1*parameter.solute['J_s'] # to initiate a simulation in the loop to compare with the previous one\n", "eps = 1e-10 # the accuracy wanted\n", "F = 1. # to launch the loop\n", "# Newton-Raphson loop to get Js\n", "while (F > eps):\n", " g, Jv = hydroroot_solute_flow(g, psi_e = parameter.exp['psi_e'],\n", " psi_base = parameter.exp['psi_base'],\n", " k0 = parameter.hydro['k0'],\n", " axial_conductivity_data = parameter.hydro['axial_conductance_data'],\n", " J_s = Js,\n", " Ps=parameter.solute['P_s'],\n", " Cse = Cse,\n", " Ce=Ce,\n", " sigma = parameter.solute['Sigma'])\n", "\n", " F = (Jv - Jv_to_fit) ** 2.0 # the objective function\n", " if abs(F) > eps:\n", " dfdJs = (F - F_old) / (Js - Js_old) # the derivative of F according to Js\n", " Js_old = Js\n", " Js = Js_old - F / dfdJs # new estimate\n", " F_old = F" ], "id": "de146e8361e19cd2", "outputs": [], "execution_count": 9 }, { "metadata": { "ExecuteTime": { "end_time": "2026-02-26T10:28:38.695810Z", "start_time": "2026-02-26T10:28:38.692685Z" } }, "cell_type": "code", "source": [ "result=f\"\"\"\n", "Jv to fit: {Jv_to_fit:.4f}\n", "Simulated Jv: {Jv:.4f}\n", "Js 1st guess: {parameter.solute['J_s']:.3e}\n", "adjusted Js: {Js:.3e}\n", "\"\"\"\n", "print(result)" ], "id": "855f3d719ef3fed2", "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Jv to fit: 0.0100\n", "Simulated Jv: 0.0100\n", "Js 1st guess: 1.714e-07\n", "adjusted Js: 2.864e-07\n", "\n" ] } ], "execution_count": 10 } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.12" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": {}, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 5 }