From 6985350222742f37bc6401b114806ad7348907d0 Mon Sep 17 00:00:00 2001 From: craig-warren Date: Sat, 11 Mar 2023 18:23:43 -0700 Subject: [PATCH] Adding patterns --- ...na_like_GSSI_1500_patterns_E_rxsorigin.txt | 3 + docs/source/accelerators.rst | 18 ++-- docs/source/hpc.rst | 6 +- examples/antenna_like_GSSI_1500_patterns.py | 84 +++++++++++++++++++ examples/antenna_like_GSSI_1500_patterns_H | 48 +++++++++++ gprMax/cmds_multiuse.py | 1 + toolboxes/AntennaPatterns/README.rst | 18 ++-- 7 files changed, 157 insertions(+), 21 deletions(-) create mode 100644 antenna_like_GSSI_1500_patterns_E_rxsorigin.txt create mode 100644 examples/antenna_like_GSSI_1500_patterns.py create mode 100644 examples/antenna_like_GSSI_1500_patterns_H diff --git a/antenna_like_GSSI_1500_patterns_E_rxsorigin.txt b/antenna_like_GSSI_1500_patterns_E_rxsorigin.txt new file mode 100644 index 00000000..e16ca1d0 --- /dev/null +++ b/antenna_like_GSSI_1500_patterns_E_rxsorigin.txt @@ -0,0 +1,3 @@ +0.125000 +0.190000 +0.190000 diff --git a/docs/source/accelerators.rst b/docs/source/accelerators.rst index 560e4815..57c77505 100644 --- a/docs/source/accelerators.rst +++ b/docs/source/accelerators.rst @@ -1,8 +1,8 @@ .. _accelerators: -********************************* -Accelerators - OpenMP/CUDA/OpenCL -********************************* +****************** +OpenMP/CUDA/OpenCL +****************** The most computationally intensive parts of gprMax, which are the FDTD solver loops, have been parallelised using different CPU and GPU accelerators to offer performance and flexibility. @@ -17,7 +17,7 @@ Some of these accelerators and frameworks require additional software to be inst .. note:: You can use the ``get_host_spec.py`` module (in ``toolboxes/Utilities``) to help you understand what hardware (CPU/GPU) you have and how gprMax can use it with the aforementioned accelerators. - + OpenMP ====== @@ -58,13 +58,13 @@ Software required The following steps provide guidance on how to install the extra components to allow gprMax to run on your NVIDIA GPU: 1. Install the `NVIDIA CUDA Toolkit `_. You can follow the Installation Guides in the `NVIDIA CUDA Toolkit Documentation `_ You must ensure the version of CUDA you install is compatible with the compiler you are using. This information can usually be found in a table in the CUDA Installation Guide under System Requirements. -2. You may need to add the location of the CUDA compiler (:code:`nvcc`) to your user path environment variable, e.g. for Windows :code:`C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\bin` or Linux/macOS :code:`/Developer/NVIDIA/CUDA-10.0/bin`. -3. Install the pycuda Python module. Open a Terminal (Linux/macOS) or Command Prompt (Windows), navigate into the top-level gprMax directory, and if it is not already active, activate the gprMax conda environment :code:`conda activate gprMax`. Run :code:`pip install pycuda` +2. You may need to add the location of the CUDA compiler (``nvcc``) to your user path environment variable, e.g. for Windows ``C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.X\bin`` or Linux/macOS ``/Developer/NVIDIA/CUDA-X.X/bin``. +3. Install the pycuda Python module. Open a Terminal (Linux/macOS) or Command Prompt (Windows), navigate into the top-level gprMax directory, and if it is not already active, activate the gprMax conda environment ``conda activate gprMax``. Run ``pip install pycuda`` Example ------- -Open a Terminal (Linux/macOS) or Command Prompt (Windows), navigate into the top-level gprMax directory, and if it is not already active, activate the gprMax conda environment :code:`conda activate gprMax` +Open a Terminal (Linux/macOS) or Command Prompt (Windows), navigate into the top-level gprMax directory, and if it is not already active, activate the gprMax conda environment ``conda activate gprMax`` Run one of the test models: @@ -74,7 +74,7 @@ Run one of the test models: .. note:: - If you want to select a specific GPU card on your system, you can specify an integer after the :code:`-gpu` flag. The integer should be the NVIDIA CUDA device ID for a specific GPU card. If it is not specified it defaults to device ID 0. + If you want to select a specific GPU card on your system, you can specify an integer after the ``-gpu`` flag. The integer should be the NVIDIA CUDA device ID for a specific GPU card. If it is not specified it defaults to device ID 0. OpenCL @@ -111,4 +111,4 @@ For example, to run a B-scan that contains 60 A-scans (traces) on a system with .. note:: - The argument given with `-mpi` is number of MPI tasks, i.e. master + workers, for MPI task farm. So in this case, 1 master (CPU) and 4 workers (GPU cards). The integers given with the `-gpu` argument are the NVIDIA CUDA device IDs for the specific GPU cards to be used. + The argument given with ``-mpi`` is number of MPI tasks, i.e. master + workers, for MPI task farm. So in this case, 1 master (CPU) and 4 workers (GPU cards). The integers given with the ``-gpu`` argument are the NVIDIA CUDA device IDs for the specific GPU cards to be used. diff --git a/docs/source/hpc.rst b/docs/source/hpc.rst index 4443efdd..4f240000 100644 --- a/docs/source/hpc.rst +++ b/docs/source/hpc.rst @@ -1,8 +1,8 @@ .. _hpc: -************************** -High-performance computing -************************** +*** +HPC +*** High-performance computing (HPC) environments usually require jobs to be submitted to a queue using a job script. The following are examples of job scripts for a HPC environment that uses `Open Grid Scheduler/Grid Engine `_, and are intended as general guidance to help you get started. Using gprMax in an HPC environment is heavily dependent on the configuration of your specific HPC/cluster, e.g. the names of parallel environments (``-pe``) and compiler modules will depend on how they were defined by your system administrator. diff --git a/examples/antenna_like_GSSI_1500_patterns.py b/examples/antenna_like_GSSI_1500_patterns.py new file mode 100644 index 00000000..2e8de864 --- /dev/null +++ b/examples/antenna_like_GSSI_1500_patterns.py @@ -0,0 +1,84 @@ +from pathlib import Path + +import numpy as np + +import gprMax +from toolboxes.GPRAntennaModels.GSSI import antenna_like_GSSI_1500 + +# File path for output +fn = Path(__file__) + +# Discretisation +dl = 0.001 + +scene = gprMax.Scene() + +title = gprMax.Title(name=fn.with_suffix('').name) +dxdydz = gprMax.Discretisation(p1=(dl, dl, dl)) +pml = gprMax.PMLProps(thickness=14) +scene.add(title) +scene.add(dxdydz) +scene.add(pml) + +timewindows = np.array([4.5e-9]) # For 0.3m max +radii = np.linspace(0.1, 0.3, 20) +theta = np.linspace(3, 357, 60) +selector = 0 + +fs = np.array([0.040, 0.040, 0.040]) +domain_size = np.array([2 * fs[0] + 0.170, + 2 * fs[1] + 2 * radii[-1], + 2 * fs[2] + 2 * radii[-1]]) +domain = gprMax.Domain(p1=(domain_size[0], domain_size[1], domain_size[2])) +time_window = gprMax.TimeWindow(time=timewindows[selector]) +scene.add(domain) +scene.add(time_window) + +antennaposition = np.array([domain_size[0] / 2, + fs[1] + radii[-1], + fs[2] + radii[-1]]) +gssi_objects = antenna_like_GSSI_1500(antennaposition[0], + antennaposition[1], + antennaposition[2]) +for obj in gssi_objects: + scene.add(obj) + +## Can introduce soil model +# soil = gprMax.SoilPeplinski(sand_fraction=0.5, clay_fraction=0.5, +# bulk_density=2.0, sand_density=2.66, +# water_fraction_lower=0.001, +# water_fraction_upper=0.25, +# id='mySoil') +# scene.add(soil) +# fbox = gprMax.FractalBox(p1=(0, 0, 0), p2=(domain_size[0], domain_size[1], fs[2] + radii[-1]), +# frac_dim=1.5, weighting=[1, 1, 1], n_materials=50, +# mixing_model_id=soil.id, id='mySoilBox') +# scene.add(fbox) + +mat = gprMax.Material(er=5, se=0, mr=1, sm=0, id='er5') +scene.add(mat) +box = gprMax.Box(p1=(0, 0, 0), p2=(domain_size[0], domain_size[1], fs[2] + radii[-1]), + material_id='er5') +scene.add(box) + +## Save the position of the antenna to file for use when processing results +np.savetxt(fn.with_suffix('').name + '_rxsorigin.txt', antennaposition, fmt="%f") + +## Generate receiver points for pattern +for radius in range(len(radii)): + ## E-plane circle (yz plane, x=0, phi=pi/2,3pi/2) + x = radii[radius] * np.sin(theta * np.pi /180) * np.cos(90 * np.pi / 180) + y = radii[radius] * np.sin(theta * np.pi /180) * np.sin(90 * np.pi / 180) + z = radii[radius] * np.cos(theta * np.pi /180) + for rxpt in range(len(theta)): + rx = gprMax.Rx(p1=(x[rxpt] + antennaposition[0], + y[rxpt] + antennaposition[1], + z[rxpt] + antennaposition[2])) + scene.add(rx) + +gv1 = gprMax.GeometryView(p1=(0, 0, 0), p2=(domain_size[0], domain_size[1], domain_size[2]), + dl=(dl, dl, dl), filename='antenna_like_GSSI_1500_patterns', + output_type='n') +scene.add(gv1) + +gprMax.run(scenes=[scene], geometry_only=True, outputfile=fn, gpu=None) \ No newline at end of file diff --git a/examples/antenna_like_GSSI_1500_patterns_H b/examples/antenna_like_GSSI_1500_patterns_H new file mode 100644 index 00000000..eae5bbb9 --- /dev/null +++ b/examples/antenna_like_GSSI_1500_patterns_H @@ -0,0 +1,48 @@ +#title: GSSI 1.5GHz antenna field patterns +#dx_dy_dz: 0.001 0.001 0.001 +#pml_cells: 14 + +#python: +import os +import numpy as np + +from gprMax.input_cmd_funcs import * +from user_libs.antennas.GSSI import antenna_like_GSSI_1500 + +filename = os.path.splitext(os.path.split(inputfile)[1])[0] + +timewindows = np.array([4.5e-9]) # For 0.3m max +radii = np.linspace(0.1, 0.3, 20) +theta = np.linspace(3, 357, 60) +materials = ['5 0 1 0 er5'] # Can add more to list and use selector integer to choose +selector = 0 + +fs = np.array([0.040, 0.040, 0.040]) +domain = np.array([2 * fs[0] + 2 * radii[-1], 2 * fs[1] + 0.107, 2 * fs[2] + 2 * radii[-1]]) +antennaposition = np.array([fs[0] + radii[-1], domain[1] / 2, fs[2] + radii[-1]]) +antenna_like_GSSI_1500(antennaposition[0], antennaposition[1], antennaposition[2]) + +print('#domain: {:.3f} {:.3f} {:.3f}'.format(domain[0], domain[1], domain[2])) +print('#time_window: {:.3e}'.format(timewindows[selector])) + +## Can introduce soil model +#print('#soil_peplinski: 0.5 0.5 2.0 2.66 0.001 0.25 mySoil') +#print('#fractal_box: 0 0 0 {} {} {} 1.5 1 1 1 50 mySoil mySoilBox 1'.format(domain[0], domain[1], fs[2] + radii[-1])) + +print('#material: {}'.format(materials[selector])) +print('#box: 0 0 0 {} {} {} {} n'.format(domain[0], domain[1], fs[2] + radii[-1], materials[selector].split()[-1])) + +## Save the position of the antenna to file for use when processing results +np.savetxt(os.path.join(os.path.dirname(inputfile), filename + '_rxsorigin.txt'), antennaposition, fmt="%f") + +## Generate receiver points for pattern +for radius in range(len(radii)): + ## H-plane circle (xz plane, y=0, phi=0,pi) + x = radii[radius] * np.sin(theta * np.pi /180) * np.cos(180 * np.pi / 180) + y = radii[radius] * np.sin(theta * np.pi /180) * np.sin(180 * np.pi / 180) + z = radii[radius] * np.cos(theta * np.pi /180) + for rxpt in range(len(theta)): + print('#rx: {:.3f} {:.3f} {:.3f}'.format(x[rxpt] + antennaposition[0], y[rxpt] + antennaposition[1], z[rxpt] + antennaposition[2])) + +geometry_view(0, 0, 0, domain[0], domain[1], domain[2], 0.001, 0.001, 0.001, filename, 'n') +#end_python: \ No newline at end of file diff --git a/gprMax/cmds_multiuse.py b/gprMax/cmds_multiuse.py index faa525f1..59ebab2b 100644 --- a/gprMax/cmds_multiuse.py +++ b/gprMax/cmds_multiuse.py @@ -1372,6 +1372,7 @@ class SoilPeplinski(UserObjectMulti): water fraction of the soil. water_fraction_upper: float required for upper boundary of volumetric water fraction of the soil. + id: string used as identifier for soil. """ def __init__(self, **kwargs): diff --git a/toolboxes/AntennaPatterns/README.rst b/toolboxes/AntennaPatterns/README.rst index 45800677..8ef94cf2 100644 --- a/toolboxes/AntennaPatterns/README.rst +++ b/toolboxes/AntennaPatterns/README.rst @@ -26,26 +26,26 @@ The package contains scripts to help calculate, process, and visualise field pat Package contents ================ -* `initial_save.py` is a module that calculates and stores (in a Numpy file) the field patterns from the output file of a simulation. -* `plot_fields.py` is a module that plots the field patterns. It should be used after the field pattern data has been processed and stored using the `initial_save.py` module. +* ``initial_save.py`` is a module that calculates and stores (in a Numpy file) the field patterns from the output file of a simulation. +* ``plot_fields.py`` is a module that plots the field patterns. It should be used after the field pattern data has been processed and stored using the ``initial_save.py`` module. -The package has been designed to work with input files found in the `examples` directory: +The package has been designed to work with input files found in the ``examples`` directory: -* `antenna_like_GSSI_1500_patterns_E.in` is an input file that includes an antenna model similar to a GSSI 1.5 GHz antenna and receivers to calculate a field pattern in the principal E-plane of the antenna -* `antenna_like_GSSI_1500_patterns_H.in` is an input file that includes an antenna model similar to a GSSI 1.5 GHz antenna and receivers to calculate a field pattern in the principal H-plane of the antenna +* ``antenna_like_GSSI_1500_patterns_E.in`` is an input file that includes an antenna model similar to a GSSI 1.5 GHz antenna and receivers to calculate a field pattern in the principal E-plane of the antenna +* ``antenna_like_GSSI_1500_patterns_H.in`` is an input file that includes an antenna model similar to a GSSI 1.5 GHz antenna and receivers to calculate a field pattern in the principal H-plane of the antenna How to use the package ====================== * Firstly you should familiarise yourself with the example model input file. Edit the input file as desired and run one of the simulations for either E-plane or H-plane patterns. -* Whilst the simulation is running edit the 'user configurable parameters' sections of the `initial_save.py` and `plot_fields.py` modules to match the setup of the simulation. -* Once the simulation has completed, run the `initial_save.py` module on the output file, e.g. for the E-plane `python -m toolboxes.AntennaPatterns.initial_save examples/antenna_like_GSSI_1500_patterns_E_Er5.h5`. This will produce a Numpy file containing the field pattern data. -* Plot the field pattern data by running the `plot_fields.py` module on the Numpy file, e.g. for the E-plane `python -m toolboxes.AntennaPatterns.plot_fields examples/antenna_like_GSSI_1500_patterns_E_Er5.npy` +* Whilst the simulation is running edit the 'user configurable parameters' sections of the ``initial_save.py`` and ``plot_fields.py`` modules to match the setup of the simulation. +* Once the simulation has completed, run the ``initial_save.py`` module on the output file, e.g. for the E-plane ``python -m toolboxes.AntennaPatterns.initial_save examples/antenna_like_GSSI_1500_patterns_E_Er5.h5``. This will produce a Numpy file containing the field pattern data. +* Plot the field pattern data by running the ``plot_fields.py`` module on the Numpy file, e.g. for the E-plane ``python -m toolboxes.AntennaPatterns.plot_fields examples/antenna_like_GSSI_1500_patterns_E_Er5.npy`` .. tip:: - If you want to create different plots you just need to edit and re-run the `plot_fields.py` module on the Numpy file, i.e. you don't have to re-process the output file. + If you want to create different plots you just need to edit and re-run the ``plot_fields.py`` module on the Numpy file, i.e. you don't have to re-process the output file. .. figure:: ../../images_shared/antenna_like_GSSI_1500_patterns_E_Er5.png