s.setBotBC("noFlux") s.setVGParameters([loam]) s.initializeProblem() s.setCriticalPressure(wilting_point) """ Initialize xylem model """ rs = pb.MappedRootSystem() rs.readParameters(path + name + ".xml") if not periodic: sdf = pb.SDF_PlantBox(0.99 * (max_b[0] - min_b[0]), 0.99 * (max_b[1] - min_b[1]), max_b[2] - min_b[2]) else: sdf = pb.SDF_PlantBox(np.Inf, np.Inf, max_b[2] - min_b[2]) rs.setGeometry(sdf) rs.initialize() rs.simulate(rs_age, False) r = XylemFluxPython(rs) init_conductivities(r, age_dependent) """ Coupling (map indices) """ picker = lambda x, y, z: s.pick([x, y, z]) r.rs.setSoilGrid(picker) # maps segments r.rs.setRectangularGrid(pb.Vector3d(min_b), pb.Vector3d(max_b), pb.Vector3d(cell_number), True) r.test() # sanity checks nodes = r.get_nodes() cci = picker(nodes[0, 0], nodes[0, 1], nodes[0, 2]) # collar cell index """ Numerical solution """ start_time = timeit.default_timer() x_, y_ = [], [] sx = s.getSolutionHead() # inital condition, solverbase.py N = round(sim_time / dt) t = 0.
import matplotlib.pyplot as plt """ Parameters """ kz = 4.32e-2 # axial conductivity [cm^3/day] kr = 1.728e-4 # radial conductivity [1/day] p_s = -200 # static soil pressure [cm] p0 = -500 # dircichlet bc at top simtime = 14 # [day] for task b """ root system """ rs = pb.MappedRootSystem() path = "../../../modelparameter/rootsystem/" name = "Anagallis_femina_Leitner_2010" # Zea_mays_1_Leitner_2010 rs.readParameters(path + name + ".xml") rs.initialize() rs.simulate(simtime, False) """ root problem """ r = XylemFluxPython(rs) r.setKr([kr]) r.setKx([kz]) nodes = r.get_nodes() soil_index = lambda x, y, z: 0 r.rs.setSoilGrid(soil_index) """ Numerical solution """ rx = r.solve_dirichlet(0., p0, p_s, [p_s], True) fluxes = r.segFluxes(simtime, rx, -200 * np.ones(rx.shape), False) # cm3/day print("Transpiration", r.collar_flux(simtime, rx, [p_s]), "cm3/day") """ plot results """ plt.plot(rx, nodes[:, 2], "r*") plt.xlabel("Xylem pressure (cm)") plt.ylabel("Depth (m)") plt.title("Xylem matric potential (cm)") plt.show()
from xylem_flux import XylemFluxPython # Python hybrid solver import plantbox as pb import rsml_reader as rsml import vtk_plot as vp from math import * import numpy as np def vector_3d(a): return pb.Vector3d(a[0], a[1], a[2]) """ root problem """ r = XylemFluxPython("RootSystem.rsml") # returns a MappedSegments object segs = r.rs.segments nodes = r.rs.nodes for i in range(0, len(nodes)): nodes[i] = vector_3d(np.array(nodes[i]) / 100.) r.rs.nodes = nodes """ Mixed plot """ ana = pb.SegmentAnalyser(r.rs) pd = vp.segs_to_polydata(ana, 1.e-2, ["radius", "subType", "creationTime"]) print("Root system bounds", pd.GetBounds()) rootActor, rootCBar = vp.plot_roots(pd, "creationTime", False) ug = vp.read_vtu("benchmark3d_2-00001.vtu") print("Mesh bounds", ug.GetBounds()) meshActor, meshCBar = vp.plot_mesh(
""" numerical solution of transpiration -1 cm3/day""" for j in range(1, simtime): rs.simulate(1, False) t = np.array(rs.getParameter("type")) v = np.array(rs.getParameter(stype)) segment = np.array(rs.getNumberOfSegments()) v_[j] = np.sum(v) v1_[j] = np.sum(v[t == 1]) v2_[j] = np.sum(v[t == 2]) v3_[j] = np.sum(v[t == 3]) v4_[j] = np.sum(v[t == 4]) segment_[j] = np.sum(segment) """ set up xylem parameters """ r = XylemFluxPython(rs) r.setKrTables( [kr0[:, 1], kr1[:, 1], kr2[:, 1], kr3[:, 1], kr4[:, 1], kr5[:, 1]], [kr0[:, 0], kr1[:, 0], kr2[:, 0], kr3[:, 0], kr4[:, 0], kr5[:, 0]]) r.setKxTables( [kz0[:, 1], kz1[:, 1], kz2[:, 1], kz3[:, 1], kz4[:, 1], kz5[:, 1]], [kz0[:, 0], kz1[:, 0], kz2[:, 0], kz3[:, 0], kz4[:, 0], kz5[:, 0]]) suf = r.get_suf(j) print("Sum of SUF", np.sum(suf), "from", np.min(suf), "to", np.max(suf), "summed positive", np.sum(suf[suf >= 0])) krs, jc = r.get_krs(j) print("Krs: ", krs) print("time: ", j)
rs = pb.MappedRootSystem() p_s = np.linspace(-200, -400, 2001) # 2 meter down, from -200 to -400, resolution in mm soil_index = lambda x, y, z: int(-10 * z ) # maps to p_s (hydrostatic equilibirum) rs.setSoilGrid(soil_index) path = "../../../modelparameter/rootsystem/" name = "Anagallis_femina_Leitner_2010" # Zea_mays_1_Leitner_2010 rs.setSeed(1) rs.readParameters(path + name + ".xml") rs.initialize() rs.simulate(simtime, False) p_s = np.linspace(-200, -400, 2001) # 2 meter down, resolution in mm """ set up xylem parameters """ r = XylemFluxPython(rs) r.setKr([kr]) # or use setKrTables, see XylemFlux.h r.setKx([kz]) """ numerical solution of transpiration -1 cm3/day""" rx = r.solve_neumann( simtime, -1, p_s, True) # True: matric potential given per cell (not per segment) print("solved") fluxes = r.segFluxes(simtime, rx, p_s, False, True) # cm3/day (double simTime, rx, sx, approx, cells print("Transpiration", r.collar_flux(simtime, rx, p_s), np.sum(fluxes), "cm3/day") suf = np.array(fluxes) / -1. # [1] """ Additional vtk plot """ ana = pb.SegmentAnalyser(r.rs)
r_, k_ = [], [] for p in rs.getRootRandomParameter(): p.dx = 0.1 r_.append(p.r) k_.append(p.lmax) kr1[2:, 0] = get_age(kr1[2:, 0], r_[1], k_[1]) kz1[:, 0] = get_age(kz1[:, 0], r_[1], k_[1]) kr2[2:, 0] = get_age(kr2[2:, 0], r_[2], k_[2]) kz2[:, 0] = get_age(kz2[:, 0], r_[2], k_[2]) kr3[2:, 0] = get_age(kr3[2:, 0], r_[3], k_[3]) kz3[:, 0] = get_age(kz3[:, 0], r_[3], k_[3]) rs.initialize() rs.simulate(simtime, False) """ set up xylem parameters """ r = XylemFluxPython(rs) # defaults... kr4 = kr1 # basal kr5 = kr1 # shoot borne kz4 = kz1 kz5 = kz1 r.setKrTables( [kr0[:, 1], kr1[:, 1], kr2[:, 1], kr3[:, 1], kr4[:, 1], kr5[:, 1]], [kr0[:, 0], kr1[:, 0], kr2[:, 0], kr3[:, 0], kr4[:, 0], kr5[:, 0]]) r.setKxTables( [kz0[:, 1], kz1[:, 1], kz2[:, 1], kz3[:, 1], kz4[:, 1], kz5[:, 1]], [kz0[:, 0], kz1[:, 0], kz2[:, 0], kz3[:, 0], kz4[:, 0], kz5[:, 0]]) """ for debugging """ r.test() r.plot_conductivities() shoot_segs = rs.getShootSegments()
kr3 = kr2 """ root system """ rs = pb.MappedRootSystem() rs.openFile(name, "") rs.setSeed(2) # fix randomness set_all_sd(rs, 0) # set all std to zero, and dx = 0.1 cm rs.getRootSystemParameter().seedPos.z = -3 # -0.01 rs.initialize() rs.simulate( simtime, False ) # simulate all, then use age dependent conductivities for predefined growth # # Plot, using vtk # vp.plot_roots(rs, "creationTime") """ set up xylem parameters """ r = XylemFluxPython(rs) kr4 = kr1 # basal kr5 = kr1 # shoot borne r.setKrTables( [kr1[:, 1], kr1[:, 1], kr2[:, 1], kr3[:, 1], kr4[:, 1], kr5[:, 1]], [kr1[:, 0], kr1[:, 0], kr2[:, 0], kr3[:, 0], kr4[:, 0], kr5[:, 0]]) r.setKx([kx, kx, kx, kx, kx, kx]) # """ for debugging """ # r.test() # r.plot_conductivities() # shoot_segs = rs.getShootSegments() # print("Shoot segments", [str(s) for s in shoot_segs]) # print("Shoot type", rs.subTypes[0]) """ numerical solution of transpiration -1 cm3/day""" krs_, l_, jc_ = [], [], []
"""root system length over time""" import sys sys.path.append("../../.."); sys.path.append("../../../src/python_modules") import plantbox as pb import numpy as np import matplotlib.pyplot as plt import rsml_reader as rsml import math from xylem_flux import XylemFluxPython # Python hybrid solver import vtk_plot as vp """ root problem """ r = XylemFluxPython("RootSystem.rsml") r.test() polylines, props, funcs = rsml.read_rsml("RootSystem.rsml") print(len(polylines), "roots") # print(props["parent-poly"]) # print(props["parent-node"]) print("Tap root number of nodes", len(polylines[0])) for i in range(1, len(polylines)): pp = int(props["parent-poly"][i]) pn = int(props["parent-node"][i]) try: n0 = polylines[pp][pn] n1 = polylines[i][0] print("root", i, np.linalg.norm(np.array(n1) - np.array(n0))) except: print("root", i, "index out of range", "parent-node", pn, "length", len(polylines[pp]))
import rsml_reader as rsml import estimate_root_params as es from xylem_flux import XylemFluxPython import vtk_plot as vp import plantbox as pb time = range(1, 3) # measurement times (not in the rsml) name = ["RSML/m1/dicot/lupin/lupin_d{:g}.rsml".format(a) for a in range(1, 10)] # time = range(1, 3) # measurement times (not in the rsml) # name = ["RSML/m1/monocot/maize/PL0{:g}_DAS0{:g}.rsml".format(1, a) for a in range(1, 8)] # time = [75] # measurement times (not in the rsml) # name = ["RSML/Maize_Kutschera.rsml"] rs = XylemFluxPython( name[0]) # parses rsml, XylemFluxPython.rs is of type MappedRootSegments ana = pb.SegmentAnalyser( rs.rs) # convert MappedRootSegments to a SegmentAnalyser # radii = ana.data["radius"] # DOES NOT WORK (why?) # for i in range(0, len(radii)): # radii[i] /= 116.93 # ana.data["radius"] = radii pd = vp.segs_to_polydata( ana, 1. / 116.93) # makes a vtkPolydata (to save as .vtp, or visualize with vtk) vp.plot_roots(pd, "radius") # plots vtkPolydata into an interactive window
simtime = 20 # [day] for task b """ root system """ rs = pb.MappedRootSystem() path = "../../../CPlantBox//modelparameter/rootsystem/" name = "Glycine_max" rs.setSeed(1) rs.readParameters(path + name + ".xml") rs.getRootSystemParameter().seedPos.z = -0.1 rs.initialize() rs.simulate(simtime, False) print() print("Shoot segments: ", [str(s) for s in rs.getShootSegments()]) print() """ set up xylem parameters """ r = XylemFluxPython(rs) r.setKr([kr]) # or use setKrTables, see XylemFlux.h r.setKx([kz]) r.test() """ numerical solution of transpiration -1 cm3/day""" suf = r.get_suf(0.) print("Sum of SUF", np.sum(suf), "from", np.min(suf), "to", np.max(suf), "summed positive", np.sum(suf[suf >= 0])) krs = r.get_krs(0.) print("Krs: ", krs) """ Additional vtk plot """ ana = pb.SegmentAnalyser(r.rs) ana.addData("SUF", suf) # cut off for vizualisation vp.plot_roots(ana, "SUF", "Soil uptake fraction (cm3 day)") # "fluxes"
p0 = -500 # dircichlet bc at top simtime = 14 # [day] for task b """ root system """ rs = pb.MappedPlant() #pb.MappedRootSystem() #pb.MappedPlant() path = "../../../modelparameter/plant/" #"../../../modelparameter/rootsystem/" name = "manyleaves" #"Anagallis_femina_Leitner_2010" # Zea_mays_1_Leitner_2010 rs.readParameters(path + name + ".xml") soil_index = lambda x, y, z : 0 rs.setSoilGrid(soil_index) rs.initialize() rs.simulate(3, False) #rs.simulate(simtime, False) #test to see if works in case of several simulate r = XylemFluxPython(rs) nodes = r.get_nodes() """ we can give a kr/kx: constant across type: r.setKx([[kz]]) by type: r.setKx([[kz], [kz2], [kz3]]) by type and subtype: r.setKx([[kz, kz2], [kza, kzb], [kzd, kzf]]) att: the bud (from which the leaf grows) has to have a kz one of the above + time dependant: constant across type: r.setKx([[kz1, kz2, kr3]], [[age1, age2, age3]]) by type: r.setKxTables([[[kz1, kz2, kr3],[kza, kzb, krc]]], [[[age1, age2, age3], [agea, ageb, agec]]]) by type and subtype: r.setKxTables([[[kz1, kz2, kr3],[kza, kzb, krc]],[[kz1, kz2, kr3],[kza, kzb, krc]]], [[[age1, age2, age3], [agea, ageb, agec]],[[age1, age2, age3], [agea, ageb, agec]]]) """ r.setKr([[kr],[kr_stem],[gs]])
p_a = -100000 #static air pressure #p0 = -500 # dircichlet bc at top simtime = 14.0 # [day] for task b k_soil = [] """ root system """ rs = pb.MappedPlant() #pb.MappedRootSystem() #pb.MappedPlant() path = "../../../modelparameter/plant/" #"../../../modelparameter/rootsystem/" name = "manyleaves" #"Anagallis_femina_Leitner_2010" # Zea_mays_1_Leitner_2010 rs.readParameters(path + name + ".xml") soil_index = lambda x, y, z: 0 rs.setSoilGrid(soil_index) rs.initialize() rs.simulate(3, False) #rs.simulate(simtime, False) #test to see if works in case of several simulate r = XylemFluxPython(rs) nodes = r.get_nodes() tiproots, tipstem, tipleaf = r.get_organ_nodes_tips( ) #end node of end segment of each organ node_tips = np.concatenate((tiproots, tipstem, tipleaf)) tiproots, tipstem, tipleaf = r.get_organ_segments_tips( ) #end segment of each organ seg_tips = np.concatenate((tiproots, tipstem, tipleaf)) """ we can give a kr/kx: constant across type: r.setKx([[kz]]) by type: r.setKx([[kz], [kz2], [kz3]]) by type and subtype: r.setKx([[kz, kz2], [kza, kzb], [kzd, kzf]]) att: the bud (from which the leaf grows) has to have a kz one of the above + time dependant: constant across type: r.setKx([[kz1, kz2, kr3]], [[age1, age2, age3]])