.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "content/examples/09-flow/plot_inv_flow_richards_1D.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_content_examples_09-flow_plot_inv_flow_richards_1D.py: FLOW: Richards: 1D: Inversion ============================= The example shows an inversion of Richards equation in 1D with a heterogeneous hydraulic conductivity function. The haverkamp model is used with the same parameters as Celia1990_ the boundary and initial conditions are also the same. The simulation domain is 40cm deep and is run for an hour with an exponentially increasing time step that has a maximum of one minute. The general setup of the experiment is an infiltration front that advances downward through the model over time. The model chosen is the saturated hydraulic conductivity inside the hydraulic conductivity function (using haverkamp). The initial model is chosen to be the background (1e-3 cm/s). The saturation data has 2% random Gaussian noise added. The figure shows the recovered saturated hydraulic conductivity next to the true model. The other two figures show the saturation field for the entire simulation for the true and recovered models. Rowan Cockett - 21/12/2016 .. _Celia1990: http://www.webpages.uidaho.edu/ch/papers/Celia.pdf .. GENERATED FROM PYTHON SOURCE LINES 28-155 .. image-sg:: /content/examples/09-flow/images/sphx_glr_plot_inv_flow_richards_1D_001.png :alt: True saturation over time, Recovered saturation over time :srcset: /content/examples/09-flow/images/sphx_glr_plot_inv_flow_richards_1D_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none /home/vsts/work/1/s/simpeg/flow/richards/simulation.py:40: FutureWarning: verbose.debug has been deprecated, please use verbose. It will be removed in version 0.19.0 of SimPEG. /home/vsts/work/1/s/simpeg/simulation.py:197: DefaultSolverWarning: Using the default solver: Pardiso. If you would like to suppress this notification, add warnings.filterwarnings('ignore', simpeg.utils.solver_utils.DefaultSolverWarning) to your script. /home/vsts/work/1/s/simpeg/flow/richards/simulation.py:321: UserWarning: cell_gradient_BC is deprecated and is not longer used. See cell_gradient Running inversion with SimPEG v0.23.0 simpeg.InvProblem will set Regularization.reference_model to m0. simpeg.InvProblem will set Regularization.reference_model to m0. simpeg.InvProblem will set Regularization.reference_model to m0. simpeg.InvProblem is setting bfgsH0 to the inverse of the eval2Deriv. ***Done using same Solver, and solver_opts as the SimulationNDCellCentered problem*** /home/vsts/work/1/s/simpeg/flow/richards/simulation.py:271: UserWarning: cell_gradient_BC is deprecated and is not longer used. See cell_gradient /usr/share/miniconda/envs/simpeg-test/lib/python3.10/site-packages/pymatsolver/direct/pardiso.py:49: PardisoTypeConversionWarning: Converting csc_matrix matrix to CSR format. model has any nan: 0 ============================ Inexact Gauss Newton ============================ # beta phi_d phi_m f |proj(x-g)-x| LS Comment ----------------------------------------------------------------------------- x0 has any nan: 0 0 2.62e+05 1.95e+05 0.00e+00 1.95e+05 2.91e+04 0 1 2.62e+05 1.85e+05 1.43e-02 1.89e+05 7.35e+03 0 2 2.62e+05 1.83e+05 2.26e-02 1.89e+05 1.83e+03 0 Skip BFGS 3 6.56e+04 1.83e+05 2.32e-02 1.84e+05 2.26e+04 2 Skip BFGS 4 6.56e+04 1.66e+05 1.30e-01 1.74e+05 1.26e+04 0 5 6.56e+04 1.55e+05 2.29e-01 1.70e+05 9.75e+03 0 Skip BFGS 6 1.64e+04 1.48e+05 3.16e-01 1.53e+05 2.51e+04 0 Skip BFGS 7 1.64e+04 1.23e+05 7.17e-01 1.34e+05 2.30e+04 0 8 1.64e+04 9.99e+04 1.15e+00 1.19e+05 1.96e+04 0 Skip BFGS 9 4.10e+03 8.14e+04 1.59e+00 8.80e+04 3.01e+04 0 Skip BFGS NewtonRoot stopped by maxIters (30). norm: 1.1787e-04 10 4.10e+03 5.73e+04 2.40e+00 6.71e+04 3.08e+04 0 NewtonRoot stopped by maxIters (30). norm: 2.0143e-04 11 4.10e+03 3.43e+04 3.05e+00 4.68e+04 2.77e+04 0 12 1.02e+03 1.57e+04 3.71e+00 1.95e+04 3.04e+04 0 NewtonRoot stopped by maxIters (30). norm: 1.0604e-04 13 1.02e+03 5.45e+03 4.76e+00 1.03e+04 2.19e+04 0 14 1.02e+03 2.78e+03 5.10e+00 8.00e+03 1.29e+04 0 NewtonRoot stopped by maxIters (30). norm: 1.4761e-04 15 2.56e+02 1.99e+03 5.13e+00 3.30e+03 9.11e+03 0 16 2.56e+02 1.16e+03 6.45e+00 2.81e+03 6.27e+03 0 17 2.56e+02 1.08e+03 6.47e+00 2.74e+03 6.00e+03 1 18 6.40e+01 9.46e+02 6.67e+00 1.37e+03 3.13e+03 0 19 6.40e+01 8.41e+02 8.26e+00 1.37e+03 8.00e+03 0 20 6.40e+01 6.23e+02 8.20e+00 1.15e+03 4.81e+03 0 ------------------------- STOP! ------------------------- 1 : |fc-fOld| = 2.2171e+02 <= tolF*(1+|f0|) = 1.9501e+04 1 : |xc-x_last| = 6.4477e-01 <= tolX*(1+|x0|) = 4.4688e+00 0 : |proj(x-g)-x| = 4.8150e+03 <= tolG = 1.0000e-01 0 : |proj(x-g)-x| = 4.8150e+03 <= 1e3*eps = 1.0000e-02 1 : maxIter = 20 <= iter = 20 ------------------------- DONE! ------------------------- | .. code-block:: Python import matplotlib import matplotlib.pyplot as plt import numpy as np import discretize from simpeg import maps from simpeg import regularization from simpeg import data_misfit from simpeg import optimization from simpeg import inverse_problem from simpeg import directives from simpeg import inversion from simpeg.flow import richards def run(plotIt=True): M = discretize.TensorMesh([np.ones(40)], x0="N") M.set_cell_gradient_BC("dirichlet") # We will use the haverkamp empirical model with parameters from Celia1990 k_fun, theta_fun = richards.empirical.haverkamp( M, A=1.1750e06, gamma=4.74, alpha=1.6110e06, theta_s=0.287, theta_r=0.075, beta=3.96, ) # Here we are making saturated hydraulic conductivity # an exponential mapping to the model (defined below) k_fun.KsMap = maps.ExpMap(nP=M.nC) # Setup the boundary and initial conditions bc = np.array([-61.5, -20.7]) h = np.zeros(M.nC) + bc[0] prob = richards.SimulationNDCellCentered( M, hydraulic_conductivity=k_fun, water_retention=theta_fun, boundary_conditions=bc, initial_conditions=h, do_newton=False, method="mixed", debug=False, ) prob.time_steps = [(5, 25, 1.1), (60, 40)] # Create the survey locs = -np.arange(2, 38, 4.0).reshape(-1, 1) times = np.arange(30, prob.time_mesh.cell_centers_x[-1], 60) rxSat = richards.receivers.Saturation(locs, times) survey = richards.Survey([rxSat]) prob.survey = survey # Create a simple model for Ks Ks = 1e-3 mtrue = np.ones(M.nC) * np.log(Ks) mtrue[15:20] = np.log(5e-2) mtrue[20:35] = np.log(3e-3) mtrue[35:40] = np.log(1e-2) m0 = np.ones(M.nC) * np.log(Ks) # Create some synthetic data and fields relative = 0.02 # The standard deviation for the noise Hs = prob.fields(mtrue) data = prob.make_synthetic_data( mtrue, relative_error=relative, f=Hs, add_noise=True ) # Setup a pretty standard inversion reg = regularization.WeightedLeastSquares(M, alpha_s=1e-1) dmis = data_misfit.L2DataMisfit(simulation=prob, data=data) opt = optimization.InexactGaussNewton(maxIter=20, maxIterCG=10) invProb = inverse_problem.BaseInvProblem(dmis, reg, opt) beta = directives.BetaSchedule(coolingFactor=4) betaest = directives.BetaEstimate_ByEig(beta0_ratio=1e2) target = directives.TargetMisfit() dir_list = [beta, betaest, target] inv = inversion.BaseInversion(invProb, directiveList=dir_list) mopt = inv.run(m0) Hs_opt = prob.fields(mopt) if plotIt: plt.figure(figsize=(14, 9)) ax = plt.subplot(121) plt.semilogx(np.exp(np.c_[mopt, mtrue]), M.gridCC) plt.xlabel("Saturated Hydraulic Conductivity, $K_s$") plt.ylabel("Depth, cm") plt.semilogx([10**-3.9] * len(locs), locs, "ro") plt.legend(("$m_{rec}$", "$m_{true}$", "Data locations"), loc=4) ax = plt.subplot(222) mesh2d = discretize.TensorMesh([prob.time_mesh.h[0] / 60, prob.mesh.h[0]], "0N") sats = [theta_fun(_) for _ in Hs] clr = mesh2d.plot_image(np.c_[sats][1:, :], ax=ax) cmap0 = matplotlib.cm.RdYlBu_r clr[0].set_cmap(cmap0) c = plt.colorbar(clr[0]) c.set_label("Saturation $\\theta$") plt.xlabel("Time, minutes") plt.ylabel("Depth, cm") plt.title("True saturation over time") ax = plt.subplot(224) mesh2d = discretize.TensorMesh([prob.time_mesh.h[0] / 60, prob.mesh.h[0]], "0N") sats = [theta_fun(_) for _ in Hs_opt] clr = mesh2d.plot_image(np.c_[sats][1:, :], ax=ax) cmap0 = matplotlib.cm.RdYlBu_r clr[0].set_cmap(cmap0) c = plt.colorbar(clr[0]) c.set_label("Saturation $\\theta$") plt.xlabel("Time, minutes") plt.ylabel("Depth, cm") plt.title("Recovered saturation over time") plt.tight_layout() if __name__ == "__main__": run() plt.show() .. rst-class:: sphx-glr-timing **Total running time of the script:** (3 minutes 28.175 seconds) **Estimated memory usage:** 288 MB .. _sphx_glr_download_content_examples_09-flow_plot_inv_flow_richards_1D.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_inv_flow_richards_1D.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_inv_flow_richards_1D.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_inv_flow_richards_1D.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_