Contents
Introduction to gprMax
gprMax is a simulation software for 3D (forward) modeling of GPR (Ground Penetrating RADAR) that uses Yee’s method (FDTD (Finite Difference Time Domain)) to simulate EM wave propagation (solving Maxwell’s equations). While the purpose intended is GPR, it can be utilized for other RADAR applications that require detailed wave propagation as well. A major advantage of gprMax is that it offers GPU (nVIDIA CUDA) support.
gprMax is written in Python with critical parts written in Cython. The source code is hosted on GitHub and there is no indication that C,C++,FORTRAN or Julia is used anywhere. Further, it supports OpenMPI for multi CPU computation. It can be combined with multi GPU support.
A major advantage of using simulation software when it comes to engineering and geoscience is that, given realistic material models, we can generate more data than someone could ever collect with field work. This allows for training better machine learning models as well as optimize engineering processes. gprMax offers scritable input files and scritable geometries which makes it super easy to scale up simulation quantities.
An additional feature of gprMax is that we can model antennas as well. This allows for antenna optimization for certain responses (e.g. finding a Nazi gold train in Poland ;)).
Installation
The installation process is pretty straight forward. The default installation process requires conda and makes the process flawless.
$ git clone https://github.com/gprmax/gprMax
$ cd gprMax
$ conda env create -f conda_env.yml
$ conda activate gprMax
(gprMax) $ python setup.py build
(gprMax) $ python setup.py install
If we want to use suitable nVIDIA GPUs, then we have to make sure that all CUDA packages are installed and we’re good to go. However, the official conda list seems to be broken. Use this one instead! The environment is named gprMaxCuda
.
If you dare to run it on a Raspberry Pi (which works, then use either pip3
to install libraries required or use virtualenv
.
Structure of gprMax
Let’s look at some important source code folders first.
|
|-gprMax
|-tests
|-tools
|-user_libs
\user_models
gprMax
contains the source code of the simulation software and test
contains unit tests and some examples (e.g. as Jupyter notebooks). The internals are visualized here.
user_libs
contains some interesting things such as the Austin Man & Women human body model, models for antennas and materials as well as functions for Taguchi optimization.
user_models
contains some examples provided by the authors of gprMax. Unfortunately, they are the only “reference” I could find on geometries etc. I’m going to write something more descriptive some time this or next month (and will link it here).
Perhaps the most important folder here is tools
since it contains post-processing tools for plotting and extracting results which btw are stored as h5 files but called .out
.
Examples provided
Let’s have a quick look at some examples. For my current projects they are enough to get started with but for more complex stuff, there is a lack of documentation.
2D A-scan
The 2D (half-space) A-scan example shows the simplest thing we can do with gprMax. We are creating a 2D plane (half-space) that contains a metal cylinder. Let’s look at the input file to understand some of the input parameters:
#title: A-scan from a metal cylinder buried in a dielectric half-space
#domain: 0.240 0.210 0.002
#dx_dy_dz: 0.002 0.002 0.002
#time_window: 3e-9
#material: 6 0 1 0 half_space
#waveform: ricker 1 1.5e9 my_ricker
#hertzian_dipole: z 0.100 0.170 0 my_ricker
#rx: 0.140 0.170 0
#box: 0 0 0 0.240 0.170 0.002 half_space
#cylinder: 0.120 0.080 0 0.120 0.080 0.002 0.010 pec
#geometry_view: 0 0 0 0.240 0.210 0.002 0.002 0.002 0.002 cylinder_half_space n
The first line of an input file defiles the title (#title
). It seems like python comments are used for defining properties since it basically is written in Python and further it allows Python functions in the input files.
#domain
defines the extend of the computational domain in the unit of meters. Since we are using finite differences here, we are dealing with a structured mesh and therefore have to define discretization. It seems like #dx_dy_dz
is the only thing we can use. I haven’t found any way (so far) to discretize with different precision (e.g. similar to OpenFOAM snappyHexMesh). Besides spatial discretization, we have to deal with temporal (time) discretization. We use #time_window
for that. Here we have two options:
- using an integer to define the number of iterations
- using a floating point number to define the simulation time and iterations and time steps are calculated internally
A very important task when it comes to numerical simulation is the selection of material parameters. We define material parameters with #material
. It requires 5 parameters. The first one is the relative permittivity, the second is conductivity [Siemens/meter], the third is the relative permeability, the fourth is the magnetic loss [Ohm/meter] of the material and the fith and final parameter is an identifier string. We are able to define anisotropic materials but that is part of another blog post. With #box
, #cylinder
and #sphere
we can create volume objects. #box
is defined with the lower left coordinates (x,y,z) followed by the upper right coordinates (x,y,z) followed by the name of the material assigned to it. Dielectric smoothing can be assigned by a followed y
or n
. #cylinder
is defined by xyz coordinates of both faces followed by the radius of the cylinder. Finally, we have to assign a material. In this case it is pec
which is a predefined material for metal. Another predefined material is free_space
. Again, we can enable or disable dielectric smoothing.
So far we enjoyed generating materials and geometries. Since we want to simulate EM wave propagation, we have to defined a waveform and receivers. We can select from a variety of waveforms (e.g. ricker
), define a scaling factor as well as the frequency it is centered around. Finally, we assign a name to it. This is how we can simulate multiple sources. #hertzian_dipole
defines the location of the source (TX) and #rx
the location of the receiver (RX).
#geometry_view
saves the geometry we generated to a VTK file which we can view with e.g. Paraview. This is the geometry we generate with this example script:

(gprMax) $ python -m gprMax ./cylinder_Ascan_2D.in -gpu
=== Electromagnetic modelling software based on the Finite-Difference Time-Domain (FDTD) method
www.gprmax.com __ __
__ _ _ __ _ __| \/ | __ ___ __
/ _` | '_ \| '__| |\/| |/ _` \ \/ /
| (_| | |_) | | | | | | (_| |> <
\__, | .__/|_| |_| |_|\__,_/_/\_\
|___/|_|
v3.1.5 (Big Smoke)
Copyright (C) 2015-2019: The University of Edinburgh
Authors: Craig Warren and Antonis Giannopoulos
...
...
...
--- Model 1/1, input file: ./cylinder_Ascan_2D.in -----------------------------
Constants/variables used/available for Python scripting: {c: 299792458.0, current_model_run: 1, e0: 8.854187817620389e-12, inputfile: ./cylinder_Ascan_2D.in, m0: 1.2566370614359173e-06, number_model_runs: 1, z0: 376.73031346177066}
Model title: A-scan from a metal cylinder buried in a dielectric half-space
Number of CPU (OpenMP) threads: 4
GPU solving using: 0 - GeForce GTX 1060 6GB
Spatial discretisation: 0.002 x 0.002 x 0.002m
Domain size: 0.24 x 0.21 x 0.002m (120 x 105 x 1 = 12600 cells)
Mode: 2D TMz
Time step (at CFL limit): 4.71731e-12 secs
Time window: 3e-09 secs (637 iterations)
Waveform my_ricker of type ricker with maximum amplitude scaling 1, frequency 1.5e+09Hz created.
Hertzian dipole with polarity z at 0.1m, 0.17m, 0m, using waveform my_ricker created.
Receiver at 0.14m, 0.17m, 0m with output component(s) Ex, Ey, Ez, Hx, Hy, Hz created.
Material half_space with eps_r=6, sigma=0 S/m; mu_r=1, sigma*=0 Ohm/m created.
Geometry view from 0m, 0m, 0m, to 0.24m, 0.21m, 0.002m, discretisation 0.002m, 0.002m, 0.002m, with filename base cylinder_half_space created.
Memory (RAM) required: ~51.5MB host + ~51.5MB GPU
Box from 0m, 0m, 0m, to 0.24m, 0.17m, 0.002m of material(s) half_space created, dielectric smoothing is on.
Cylinder with face centres 0.12m, 0.08m, 0m and 0.12m, 0.08m, 0.002m, with radius 0.01m, of material(s) pec created, dielectric smoothing is off.
Processing geometry related cmds: 100%|██████| 2/2 [00:00<00:00, 1074.09cmds/s]
PML: formulation: HORIPML, order: 1, thickness: x0: 10, y0: 10, z0: 0, xmax: 10, ymax: 10, zmax: 0 cells
Building PML boundaries: 100%|██████████████████| 4/4 [00:00<00:00, 446.07it/s]
Building main grid: 100%|███████████████████████| 2/2 [00:00<00:00, 521.74it/s]
Materials:
| | | | sigma | | sigma* | Dielectric
ID | Name | Type | eps_r | [S/m] | mu_r | [Ohm/m] | smoothable
----+---------------------------------------------+---------------------+-------+-------+------+---------+------------
0 | pec | builtin | 1 | inf | 1 | 0 | False
1 | free_space | builtin | 1 | 0 | 1 | 0 | True
2 | half_space | | 6 | 0 | 1 | 0 | True
3 | free_space+free_space+half_space+half_space | dielectric-smoothed | 3.5 | 0 | 1 | 0 | True
Numerical dispersion analysis: estimated largest physical phase-velocity error is -0.42% in material 'half_space' whose wavelength sampled by 14 cells. Maximum significant frequency estimated as 4.32623e+09Hz
Writing geometry view file 1/1, cylinder_half_space.vti: 0%| | 0.00/75.6k [00:Writing geometry view file 1/1, cylinder_half_space.vti: 100%|█| 75.6k/75.6k [00:00<00:00, 2.25Mbyte/s]
Output file: ./cylinder_Ascan_2D.out
Running simulation, model 1/1: 100%|███████| 637/637 [00:00<00:00, 1763.66it/s]
Memory (RAM) used: ~206MB host + ~313MB GPU
Solving time [HH:MM:SS]: 0:00:00.362102
=== Simulation completed in [HH:MM:SS]: 0:00:00.706580 ========================
We have to understand that we record only the data at the receiver and no full mesh snapshots using the script above. We can visualize the receiver record using tools provided in tools.
(gprMax) $ python -m tools.plot_Ascan outputfile.out

2D B-scan
Let’s try something a bit more advanced. Usually, we don’t do single scans (A scans) but we move around with our GPR equipment.
#title: B-scan from a metal cylinder buried in a dielectric half-space
#domain: 0.240 0.210 0.002
#dx_dy_dz: 0.002 0.002 0.002
#time_window: 3e-9
#material: 6 0 1 0 half_space
#waveform: ricker 1 1.5e9 my_ricker
#hertzian_dipole: z 0.040 0.170 0 my_ricker
#rx: 0.080 0.170 0
#src_steps: 0.002 0 0
#rx_steps: 0.002 0 0
#box: 0 0 0 0.240 0.170 0.002 half_space
#cylinder: 0.120 0.080 0 0.120 0.080 0.002 0.010 pec
The input file is very similar to the example above. However, there is one important difference. We have two new paramters, #src_steps
and #rx_steps
. XYZ increments for each time step are assigned to move the transmitter and/or receiver position.
$ python -m gprMax ./cylinder_Bscan_2D.in -gpu
=== Electromagnetic modelling software based on the Finite-Difference Time-Domain (FDTD) method
www.gprmax.com __ __
__ _ _ __ _ __| \/ | __ ___ __
/ _` | '_ \| '__| |\/| |/ _` \ \/ /
| (_| | |_) | | | | | | (_| |> <
\__, | .__/|_| |_| |_|\__,_/_/\_\
|___/|_|
v3.1.5 (Big Smoke)
Copyright (C) 2015-2019: The University of Edinburgh
Authors: Craig Warren and Antonis Giannopoulos
gprMax is free software: you can redistribute it and/or modify it under the terms of
the GNU General Public License as published by the Free Software Foundation, either
version 3 of the License, or (at your option) any later version.
gprMax is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with gprMax.
If not, see www.gnu.org/licenses.
...
...
...
--- Model 1/1, input file: ./cylinder_Bscan_2D.in --------------------------------------
Constants/variables used/available for Python scripting: {c: 299792458.0, current_model_run: 1, e0: 8.854187817620389e-12, inputfile: ./cylinder_Bscan_2D.in, m0: 1.2566370614359173e-06, number_model_runs: 1, z0: 376.73031346177066}
Model title: B-scan from a metal cylinder buried in a dielectric half-space
Number of CPU (OpenMP) threads: 4
GPU solving using: 0 - GeForce GTX 1060 6GB
Spatial discretisation: 0.002 x 0.002 x 0.002m
Domain size: 0.24 x 0.21 x 0.002m (120 x 105 x 1 = 12600 cells)
Mode: 2D TMz
Time step (at CFL limit): 4.71731e-12 secs
Time window: 3e-09 secs (637 iterations)
Simple sources will step 0.002m, 0m, 0m for each model run.
All receivers will step 0.002m, 0m, 0m for each model run.
Waveform my_ricker of type ricker with maximum amplitude scaling 1, frequency 1.5e+09Hz created.
Hertzian dipole with polarity z at 0.04m, 0.17m, 0m, using waveform my_ricker created.
Receiver at 0.08m, 0.17m, 0m with output component(s) Ex, Ey, Ez, Hx, Hy, Hz created.
Material half_space with eps_r=6, sigma=0 S/m; mu_r=1, sigma*=0 Ohm/m created.
Memory (RAM) required: ~51.5MB host + ~51.5MB GPU
Box from 0m, 0m, 0m, to 0.24m, 0.17m, 0.002m of material(s) half_space created, dielectric smoothing is on.
Cylinder with face centres 0.12m, 0.08m, 0m and 0.12m, 0.08m, 0.002m, with radius 0.01m, of material(s) pec created, dielectric smoothing is off.
Processing geometry related cmds: 100%|███████████████| 2/2 [00:00<00:00, 1506.30cmds/s]
PML: formulation: HORIPML, order: 1, thickness: x0: 10, y0: 10, z0: 0, xmax: 10, ymax: 10, zmax: 0 cells
Building PML boundaries: 100%|███████████████████████████| 4/4 [00:00<00:00, 637.58it/s]
Building main grid: 100%|████████████████████████████████| 2/2 [00:00<00:00, 558.98it/s]
Materials:
| | | | sigma | | sigma* | Dielectric
ID | Name | Type | eps_r | [S/m] | mu_r | [Ohm/m] | smoothable
----+---------------------------------------------+---------------------+-------+-------+------+---------+------------
0 | pec | builtin | 1 | inf | 1 | 0 | False
1 | free_space | builtin | 1 | 0 | 1 | 0 | True
2 | half_space | | 6 | 0 | 1 | 0 | True
3 | free_space+free_space+half_space+half_space | dielectric-smoothed | 3.5 | 0 | 1 | 0 | True
Numerical dispersion analysis: estimated largest physical phase-velocity error is -0.42% in material 'half_space' whose wavelength sampled by 14 cells. Maximum significant frequency estimated as 4.32623e+09Hz
Output file: ./cylinder_Bscan_2D.out
Running simulation, model 1/1: 100%|████████████████| 637/637 [00:00<00:00, 1724.40it/s]
Memory (RAM) used: ~206MB host + ~372MB GPU
Solving time [HH:MM:SS]: 0:00:00.370340
=== Simulation completed in [HH:MM:SS]: 0:00:00.661412 =================================
Unfortunately, I can’t visualize the results since it seems like Bscan visualization works with 3D only but I’m not so sure about it and it has no priority for me to figure it out.
3D with realistic soil properties
Let’s build something more realistic. The probably most important and most challenging thing to build correctly is a realistic soil or rock model. This example utilizes a stochastic model of soil property distribution by Peplinski et al. 1995 as described in Giannakis 2016 (PhD thesis).
#title: Heterogeneous soil using a stochastic distribution of dielectric properties given by a mixing model from Peplinski
#domain: 0.4 0.4 0.4
#dx_dy_dz: 0.001 0.001 0.001
#time_window: 6e-9
#waveform: ricker 1 1.5e9 my_ricker
#hertzian_dipole: y 0.045 0.075 0.085 my_ricker
#rx: 0.105 0.075 0.085
#soil_peplinski: 0.5 0.5 2.0 2.66 0.001 0.25 my_soil
#fractal_box: 0 0 0 0.15 0.15 0.070 1.5 1 1 1 50 my_soil my_soil_box
#add_surface_roughness: 0 0 0.070 0.15 0.15 0.070 1.5 1 1 0.065 0.080 my_soil_box
#geometry_view: 0 0 0 0.15 0.15 0.1 0.001 0.001 0.001 heterogeneous_soil n
#soil_peplinski
is a pre-defined for this. It is defined by the sand fraction followed by the clay fraction. Other properties are bulk density, sand particle density and a defined range of water fraction (volumetric). Additionally, we use a realistic surface model using #add_surface_roughness
. The first six parameters define a #fractal_box
followed by 3 fractions for each direction and a range defined by two values that define surface roughness.

$ python -m gprMax ./heterogeneous_soil.in -gpu
=== Electromagnetic modelling software based on the Finite-Difference Time-Domain (FDTD) method
www.gprmax.com __ __
__ _ _ __ _ __| \/ | __ ___ __
/ _` | '_ \| '__| |\/| |/ _` \ \/ /
| (_| | |_) | | | | | | (_| |> <
\__, | .__/|_| |_| |_|\__,_/_/\_\
|___/|_|
v3.1.5 (Big Smoke)
Copyright (C) 2015-2019: The University of Edinburgh
Authors: Craig Warren and Antonis Giannopoulos
gprMax is free software: you can redistribute it and/or modify it under the terms of
the GNU General Public License as published by the Free Software Foundation, either
version 3 of the License, or (at your option) any later version.
gprMax is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with gprMax.
If not, see www.gnu.org/licenses.
...
...
...
--- Model 1/1, input file: ./heterogeneous_soil.in -------------------------------------
Constants/variables used/available for Python scripting: {c: 299792458.0, current_model_run: 1, e0: 8.854187817620389e-12, inputfile: ./heterogeneous_soil.in, m0: 1.2566370614359173e-06, number_model_runs: 1, z0: 376.73031346177066}
Model title: Heterogeneous soil using a stochastic distribution of dielectric properties given by a mixing model from Peplinski
Number of CPU (OpenMP) threads: 4
GPU solving using: 0 - GeForce GTX 1060 6GB
Spatial discretisation: 0.001 x 0.001 x 0.001m
Domain size: 0.4 x 0.4 x 0.4m (400 x 400 x 400 = 6.4e+07 cells)
Mode: 3D
Time step (at CFL limit): 1.92583e-12 secs
Time window: 6e-09 secs (3117 iterations)
Waveform my_ricker of type ricker with maximum amplitude scaling 1, frequency 1.5e+09Hz created.
Hertzian dipole with polarity y at 0.045m, 0.075m, 0.085m, using waveform my_ricker created.
Receiver at 0.105m, 0.075m, 0.085m with output component(s) Ex, Ey, Ez, Hx, Hy, Hz created.
Mixing model (Peplinski) used to create my_soil with sand fraction 0.5, clay fraction 0.5, bulk density 2g/cm3, sand particle density 2.66g/cm3, and water volumetric fraction 0.001 to 0.25 created.
Geometry view from 0m, 0m, 0m, to 0.15m, 0.15m, 0.1m, discretisation 0.001m, 0.001m, 0.001m, with filename base heterogeneous_soil created.
Memory (RAM) required: ~4.59GB host + ~4.59GB GPU
Fractal box my_soil_box from 0m, 0m, 0m, to 0.15m, 0.15m, 0.07m with my_soil, fractal dimension 1.5, fractal weightings 1, 1, 1, fractal seeding None, with 50 material(s) created, dielectric smoothing is off.
Fractal surface from 0m, 0m, 0.07m, to 0.15m, 0.15m, 0.07m with fractal dimension 1.5, fractal weightings 1, 1, fractal seeding None, and range 0.065m to 0.08m, added to my_soil_box.
Processing geometry related cmds: 100%|█████████████████| 2/2 [00:02<00:00, 1.12s/cmds]
PML: formulation: HORIPML, order: 1, thickness: 10
Building PML boundaries: 100%|████████████████████████████| 6/6 [00:11<00:00, 1.68s/it]
Building main grid: 100%|█████████████████████████████████| 2/2 [00:04<00:00, 2.58s/it]
Memory (RAM) required - updated (dispersive): ~6.14GB
Materials:
| | | | sigma | Delta | tau | omega | delta | gamma | | sigma* | Dielectric
ID | Name | Type | eps_r | [S/m] | eps_r | [s] | [Hz] | [Hz] | [Hz] | mu_r | [Ohm/m] | smoothable
----+------------+---------+---------+-----------+-----------+-----------+-------+-------+-------+------+---------+------------
0 | pec | builtin | 1 | inf | | | | | | 1 | 0 | False
1 | free_space | builtin | 1 | 0 | | | | | | 1 | 0 | True
2 | |0.0035| | debye | 3.67822 | 0.0109054 | 0.0191009 | 9.231e-12 | | | | 1 | 0 | False
3 | |0.0086| | debye | 3.93309 | 0.0165236 | 0.0704761 | 9.231e-12 | | | | 1 | 0 | False
4 | |0.0137| | debye | 4.16545 | 0.0205139 | 0.139061 | 9.231e-12 | | | | 1 | 0 | False
5 | |0.0188| | debye | 4.38366 | 0.0237684 | 0.220869 | 9.231e-12 | | | | 1 | 0 | False
6 | |0.0239| | debye | 4.59147 | 0.0265794 | 0.313802 | 9.231e-12 | | | | 1 | 0 | False
7 | |0.0289| | debye | 4.79108 | 0.0290859 | 0.416508 | 9.231e-12 | | | | 1 | 0 | False
8 | |0.0340| | debye | 4.98393 | 0.0313671 | 0.528021 | 9.231e-12 | | | | 1 | 0 | False
9 | |0.0391| | debye | 5.17106 | 0.0334729 | 0.647611 | 9.231e-12 | | | | 1 | 0 | False
10 | |0.0442| | debye | 5.35323 | 0.0354373 | 0.774695 | 9.231e-12 | | | | 1 | 0 | False
11 | |0.0493| | debye | 5.53106 | 0.0372846 | 0.908801 | 9.231e-12 | | | | 1 | 0 | False
12 | |0.0544| | debye | 5.70502 | 0.0390329 | 1.04953 | 9.231e-12 | | | | 1 | 0 | False
13 | |0.0594| | debye | 5.8755 | 0.040696 | 1.19655 | 9.231e-12 | | | | 1 | 0 | False
14 | |0.0645| | debye | 6.04283 | 0.0422849 | 1.34955 | 9.231e-12 | | | | 1 | 0 | False
15 | |0.0696| | debye | 6.20729 | 0.0438084 | 1.5083 | 9.231e-12 | | | | 1 | 0 | False
16 | |0.0747| | debye | 6.36912 | 0.0452736 | 1.67255 | 9.231e-12 | | | | 1 | 0 | False
17 | |0.0798| | debye | 6.52852 | 0.0466866 | 1.8421 | 9.231e-12 | | | | 1 | 0 | False
18 | |0.0848| | debye | 6.68567 | 0.0480524 | 2.01678 | 9.231e-12 | | | | 1 | 0 | False
19 | |0.0899| | debye | 6.84073 | 0.0493752 | 2.19642 | 9.231e-12 | | | | 1 | 0 | False
20 | |0.0950| | debye | 6.99384 | 0.0506588 | 2.38085 | 9.231e-12 | | | | 1 | 0 | False
21 | |0.1001| | debye | 7.14511 | 0.0519062 | 2.56996 | 9.231e-12 | | | | 1 | 0 | False
22 | |0.1052| | debye | 7.29467 | 0.0531203 | 2.7636 | 9.231e-12 | | | | 1 | 0 | False
23 | |0.1103| | debye | 7.44261 | 0.0543036 | 2.96166 | 9.231e-12 | | | | 1 | 0 | False
24 | |0.1153| | debye | 7.58903 | 0.055458 | 3.16402 | 9.231e-12 | | | | 1 | 0 | False
25 | |0.1204| | debye | 7.734 | 0.0565857 | 3.3706 | 9.231e-12 | | | | 1 | 0 | False
26 | |0.1255| | debye | 7.87761 | 0.0576883 | 3.58129 | 9.231e-12 | | | | 1 | 0 | False
27 | |0.1306| | debye | 8.01991 | 0.0587673 | 3.796 | 9.231e-12 | | | | 1 | 0 | False
28 | |0.1357| | debye | 8.16098 | 0.0598242 | 4.01464 | 9.231e-12 | | | | 1 | 0 | False
29 | |0.1407| | debye | 8.30087 | 0.0608602 | 4.23715 | 9.231e-12 | | | | 1 | 0 | False
30 | |0.1458| | debye | 8.43964 | 0.0618764 | 4.46343 | 9.231e-12 | | | | 1 | 0 | False
31 | |0.1509| | debye | 8.57734 | 0.0628739 | 4.69343 | 9.231e-12 | | | | 1 | 0 | False
32 | |0.1560| | debye | 8.71401 | 0.0638536 | 4.92708 | 9.231e-12 | | | | 1 | 0 | False
33 | |0.1611| | debye | 8.84969 | 0.0648165 | 5.1643 | 9.231e-12 | | | | 1 | 0 | False
34 | |0.1662| | debye | 8.98443 | 0.0657633 | 5.40505 | 9.231e-12 | | | | 1 | 0 | False
35 | |0.1712| | debye | 9.11827 | 0.0666948 | 5.64926 | 9.231e-12 | | | | 1 | 0 | False
36 | |0.1763| | debye | 9.25123 | 0.0676117 | 5.89687 | 9.231e-12 | | | | 1 | 0 | False
37 | |0.1814| | debye | 9.38335 | 0.0685145 | 6.14784 | 9.231e-12 | | | | 1 | 0 | False
38 | |0.1865| | debye | 9.51467 | 0.069404 | 6.40212 | 9.231e-12 | | | | 1 | 0 | False
39 | |0.1916| | debye | 9.64521 | 0.0702807 | 6.65965 | 9.231e-12 | | | | 1 | 0 | False
40 | |0.1966| | debye | 9.775 | 0.0711451 | 6.92039 | 9.231e-12 | | | | 1 | 0 | False
41 | |0.2017| | debye | 9.90407 | 0.0719976 | 7.1843 | 9.231e-12 | | | | 1 | 0 | False
42 | |0.2068| | debye | 10.0324 | 0.0728388 | 7.45133 | 9.231e-12 | | | | 1 | 0 | False
43 | |0.2119| | debye | 10.1601 | 0.073669 | 7.72144 | 9.231e-12 | | | | 1 | 0 | False
44 | |0.2170| | debye | 10.2872 | 0.0744886 | 7.99459 | 9.231e-12 | | | | 1 | 0 | False
45 | |0.2221| | debye | 10.4135 | 0.0752981 | 8.27074 | 9.231e-12 | | | | 1 | 0 | False
46 | |0.2271| | debye | 10.5393 | 0.0760978 | 8.54986 | 9.231e-12 | | | | 1 | 0 | False
47 | |0.2322| | debye | 10.6645 | 0.076888 | 8.83192 | 9.231e-12 | | | | 1 | 0 | False
48 | |0.2373| | debye | 10.7891 | 0.077669 | 9.11687 | 9.231e-12 | | | | 1 | 0 | False
49 | |0.2424| | debye | 10.9132 | 0.0784411 | 9.40468 | 9.231e-12 | | | | 1 | 0 | False
50 | |0.2475| | debye | 11.0367 | 0.0792047 | 9.69532 | 9.231e-12 | | | | 1 | 0 | False
51 | |0.2525| | debye | 11.1596 | 0.07996 | 9.98877 | 9.231e-12 | | | | 1 | 0 | False
Numerical dispersion analysis: estimated largest physical phase-velocity error is -0.45% in material '|0.2525|' whose wavelength sampled by 15 cells. Maximum significant frequency estimated as 4.16471e+09Hz
Writing geometry view file 1/1, heterogeneous_soil.vti: 0%| | 0.00/13.5M [00:00<?, ?bytWriting geometry view file 1/1, heterogeneous_soil.vti: 100%|█| 13.5M/13.5M [00:00<00:00, 161Mbyte/s]
Output file: ./heterogeneous_soil.out
Running simulation, model 1/1: 100%|████████████████| 3117/3117 [05:40<00:00, 9.25it/s]
Memory (RAM) used: ~2.32GB host + ~5.22GB GPU
Solving time [HH:MM:SS]: 0:05:47.092594
=== Simulation completed in [HH:MM:SS]: 0:06:07.930280 =============================================================================================================================
This produces more realistic responses:
