scieee AI-readable full text Open interactive document viewer

Estimation of Dual Permeability Model Parameters in Agricultural Fields using a Genetic Algorithm-Based Inverse Modeling Framework: Reference code

VASHISHTH, NIRALI; Pandey, Anoop; Ojha, Richa

Abstract

This repository contains the reference code associated with the research article on estimating dual permeability model (DPM) parameters in agricultural fields using a genetic algorithm (GA)-based optimization framework. The study integrates Hydrus-1D for hydrological simulations and employs PyGAD, an open-source Python library, for optimization. The provided code automates the modification of Hydrus-1D input files, executes simulations, processes output data, and optimizes soil hydraulic parameters using genetic algorithms. The workflow involves: Setting up the Hydrus-1D simulation files Modifying the SELECTOR.IN file dynamically Executing the Hydrus-1D model Extracting and analyzing simulated soil moisture data Implementing a genetic algorithm-based optimization to match simulated and observed field data The code has been tested on several type of datasets and boundary condition and works well.

Full text

Reference code for Estimation of Dual Permeability Model Parameters in Agricultural Fields using a Genetic Algorithm-Based Framework Nirali Vashishth, Anoop Pandey, Richa Ojha [email protected] March 6, 2025 1 Simulation-optimization framework Hydrus-1D is used for simulating the flow with varying set of parameters The present study employed open-source python library, PyGAD for optimization. Input Files and Initial Guess of parameters H1D Dual Modify Parameters (evolution theory) Process Simulated Data Compare with Observed Data Inputs and Model Setup The following setup and parameters were used for this study: •Units: Centimeters (cm) and days. 1 •Simulation time window: 102 days. •Soil profile: A 200 cm deep soil column. •Soil Hydraulic Properties (SHPs): Silty loam (Estimated experimentally). •Boundary conditions (BCs): –Upper boundary condition: Atmospheric boundary condition with surface layer. –Lower boundary condition: Free drainage. •Initial condition: As discussed in the manuscript. •Observed Node: 4 nodes at 10cm, 25cm, 50cm and 80cm. •Crop data: Wheat crop data at IIT Kanpur site has been used (optional) We utilized the Hydrus-1D graphical user interface (GUI) to create the reference project. The project file is located in the directory C:\. Modification in SELECTOR.IN file Python Code Example Below is the Python function DPM warming, which was used for hydrological simulations. Importing Libraries and Setting Paths This block imports essential libraries and defines reference folders for the simulation. import os import numpy as np import pandas as pd from shutil import copyfile import pygad hydrus_exec = ’C :\ H1D_Dual . exe ’ ref_folder = ’C:\ Field_DPM ’ Listing 1: Importing Libraries and Setting Paths 2 Setting up Simulation Files This function copies necessary HYDRUS reference files into the simulation folder, where the execution takes place. Creates the input files for HYDRUS executive. Copies the mandatory file Profile.dat to the corresponding folder and creates the corresponding Selector.in. sim_folder = ’C :\\ Simulated_data \\ Field_DPM ’ def setup_simulation_files ( ref_folder , sim_folder ): """ Set up the simulation folder by copying required files . """ os . makedirs ( sim_folder , exist_ok = True ) files_to_copy = [’PROFILE .DAT ’,’ SELECTOR . IN ’,’ ATMOSPH . IN ’] for file_name in files_to_copy : src = os .path . join ( ref_folder , file_name ) dest = os . path . join ( sim_folder , file_name ) if os . path . exists ( src ): copyfile (src , dest ) Listing 2: Setting up Simulation Files Modifying SELECTOR.IN File This function modifies the SELECTOR.IN file to adjust simulation parameters. The file is different for each simulation since the required parameters are variable in simulationoptimization framework. The code reads the reference Selector.in, copies the first 28 lines to the new file, write the van Genuchten parameters to the 27th line, and finally copies the last 10 lines from the reference Selector.in to the new file. def modify_selector_file ( sim_folder , param ): file_path = os. path . join ( sim_folder , ’SELECTOR .IN ’) with open(file_path , ’r’) as file: lines = file. readlines () lines [26] = f’ 0.105 { param [0]:.3 f} { param [1]:.4 f} { param [2]:.3 f} { param [3]:.3 f} 0.500\ n’ with open(file_path , ’w’) as file: file. writelines ( lines ) Listing 3: Modifying SELECTOR.IN File Model Execution and Simulation Processing This function runs the HYDRUS simulation by calling its executable and processing the results. Once the simulation completes, it processes the output data generated by HYDRUS and extracts results by defining a function named postprocess simulated data for a chosen number of nodes. 3 def Model ( ref_folder , hydrus_exec , sim_folder , param , num_nodes ): setup_simulation_files ( ref_folder , sim_folder ) modify_selector_file ( sim_folder , param ) # Run HYDRUS executable exec_path = f’{ hydrus_exec } { sim_folder }’ os . system ( exec_path ) return postprocess_simulated_data ( sim_folder , num_nodes ) Listing 4: Model Execution and Simulation Processing Fitness Function for Genetic Algorithm The fitness function evaluates how well the simulation results match observed data. def fitness_func ( ga_instance , solution , solution_idx ): simulated = Model ( ref_folder , hydrus_exec , sim_folder , solution , 4) return 1.0 / (sum(np.sum (( simulated [i] - obs [i ]) **2) for i, obs in enumerate ([theta_10_obs , theta_25_obs , theta_50_obs , theta_80_obs]) ) + 1e -6) Listing 5: Fitness Function for Genetic Algorithm Genetic Algorithm Framework and Execution This section sets up and runs the genetic algorithm to optimize simulation parameters. gene_space = [{ ’low ’: 0.31 , ’high ’: 0.45} , {’low ’: 0.009 , ’high ’: 0.01} , { ’low ’: 1.47 , ’high ’: 2}, {’low ’: 0.2 , ’high ’: 4}] last_fitness = 0 def on_generation ( ga_instance ): global last_fitness best_fitness = ga_instance . best_solution ( pop_fitness = ga_instance . last_generation_fitness)[1] print (f" Generation { ga_instance . generations_completed } | Fitness : { best_fitness} | Change: {best_fitness - last_fitness}") last_fitness = best_fitness ga_instance = pygad.GA( num_generations =300 , random_seed =100 , num_parents_mating =10 , sol_per_pop =12 , num_genes =4, fitness_func = fitness_func , save_solutions =True , gene_space = gene_space , crossover_type ="uniform", crossover_probability =0.8 , mutation_type ="random", mutation_probability =0.5 , on_generation = on_generation ) ga_instance . run () Listing 6: Genetic Algorithm Framework and Execution 4