def retention_curve(g, ax=None): """ Plots the retention curve of the bulk soil: """ if not ax: fig, ax = mpl.pyplot.subplots() mpl.pyplot.xscale('log') soil_class = g.node(g.Ancestors(g.node(g.root).vid_base)[0]).soil_class param = def_param_soil()[soil_class] theta_r, theta_s, alpha, n, k_sat = [param[i] for i in range(5)] m = 1. - 1. / n psi_range = np.arange(0, 150000) theta_ls = [] for psiX in psi_range: theta_ls.append(theta_r + (theta_s - theta_r) * 1. / ((1 + np.absolute(alpha * psiX))**n)**m) psi_range = np.array(psi_range) * 1.e-4 ax.plot(psi_range, theta_ls, label=soil_class) ax.set(xlabel='$\mathregular{-\Psi_{soil}\/[MPa]}$', ylabel='$\mathregular{\Theta_{bulk\/soil}\/[-]}$') ax.legend() return ax
def test_soil_water_potential_drops_faster_for_small_soil_reservoirs_than_bigger_ones(): for soil_class in hydraulic.def_param_soil().keys(): psi_soil_small = hydraulic.soil_water_potential(psi_soil_init=0., water_withdrawal=1., soil_class=soil_class, soil_total_volume=1., psi_min=-3.) psi_soil_big = hydraulic.soil_water_potential(psi_soil_init=0., water_withdrawal=1., soil_class=soil_class, soil_total_volume=2., psi_min=-3.) assert psi_soil_small < psi_soil_big
def retention_curve(g, ax=None): """Plots the retention curve of the bulk soil: Args: g (openalea.mtg.mtg.MTG): an MTG object ax (AxesSubplot or None): if given adds the hydraulic cart to it (default None) Returns: (AxesSubplot) """ if not ax: fig, ax = plt.subplots() plt.xscale('log') soil_class = g.node(g.Ancestors(g.node(g.root).vid_base)[0]).soil_class param = def_param_soil()[soil_class] theta_r, theta_s, alpha, n, k_sat = [param[i] for i in range(5)] m = 1. - 1. / n psi_range = np.arange(0, 150000) theta_ls = [] for psiX in psi_range: theta_ls.append(theta_r + (theta_s - theta_r) * 1. / ((1 + abs(alpha * psiX))**n)**m) psi_range = np.array(psi_range) * 1.e-4 ax.plot(psi_range, theta_ls, label=soil_class) ax.set(xlabel=r'$\mathregular{-\Psi_{soil}\/[MPa]}$', ylabel=r'$\mathregular{\Theta_{bulk\/soil}\/[-]}$') ax.legend() return ax
def test_k_soil_soil_decreases_as_water_potential_decreases(): for soil_class in hydraulic.def_param_soil().keys(): soil_conductivity = [ hydraulic.k_soil_soil(psi, soil_class) for psi in arange(0, -3, -0.1) ] assert all(x >= y for x, y in zip(soil_conductivity, soil_conductivity[1:]))
def test_soil_water_potential_decreases_as_water_withdrawal_increases(): for soil_class in hydraulic.def_param_soil().keys(): psi_soil = [ hydraulic.soil_water_potential(psi_soil_init=0., water_withdrawal=w, soil_class=soil_class, soil_total_volume=1, psi_min=-3.) for w in arange(0, 3, 0.1) ] assert all(x >= y for x, y in zip(psi_soil, psi_soil[1:]))
def test_def_param_soil_returns_the_right_soil_property_values(): ref_values = {'Sand': (0.045, 0.430, 0.145, 2.68, 712.8), 'Loamy_Sand': (0.057, 0.410, 0.124, 2.28, 350.2), 'Sandy_Loam': (0.065, 0.410, 0.075, 1.89, 106.1), 'Loam': (0.078, 0.430, 0.036, 1.56, 24.96), 'Silt': (0.034, 0.460, 0.016, 1.37, 6.00), 'Silty_Loam': (0.067, 0.450, 0.020, 1.41, 10.80), 'Sandy_Clay_Loam': (0.100, 0.390, 0.059, 1.48, 31.44), 'Clay_Loam': (0.095, 0.410, 0.019, 1.31, 6.24), 'Silty_Clay_Loam': (0.089, 0.430, 0.010, 1.23, 1.68), 'Sandy_Clay': (0.100, 0.380, 0.027, 1.23, 2.88), 'Silty_Clay': (0.070, 0.360, 0.005, 1.09, 0.48), 'Clay': (0.068, 0.380, 0.008, 1.09, 4.80)} module_values = hydraulic.def_param_soil() for soil_class, soil_properties in ref_values.items(): assert all(x == y for x, y in zip(soil_properties, module_values[soil_class]))
def test_def_param_soil_returns_Custom_soil_properties_when_provided(): custom_soil = (0.02, 0.3, 0.03, 1.5, 25) assert hydraulic.def_param_soil(custom_soil)['Custom'] == custom_soil