你已经派生过 gprMax
镜像自地址
https://gitee.com/sunhf/gprMax.git
已同步 2025-08-08 07:24:19 +08:00
Changes to package structure and config module. Added ability to choose E or H fields in snapshots.
这个提交包含在:
@@ -1,4 +1,4 @@
|
|||||||
# This is where the version number is set and read by setup.py and conf.py (for the docs)
|
# This is where the version number is set and read by setup.py and conf.py (for the docs)
|
||||||
|
|
||||||
__version__ = '3.1.5'
|
__version__ = '3.1.6b0'
|
||||||
codename = 'Big Smoke'
|
codename = 'Big Smoke'
|
||||||
|
@@ -20,10 +20,16 @@ import numpy as np
|
|||||||
cimport numpy as np
|
cimport numpy as np
|
||||||
|
|
||||||
|
|
||||||
ctypedef fused floattype_t:
|
ctypedef fused float_or_double:
|
||||||
np.float32_t
|
float
|
||||||
np.float64_t
|
double
|
||||||
|
|
||||||
ctypedef fused complextype_t:
|
ctypedef fused float_or_double_complex:
|
||||||
np.complex64_t
|
float complex
|
||||||
np.complex128_t
|
double complex
|
||||||
|
|
||||||
|
ctypedef fused real_or_complex:
|
||||||
|
float
|
||||||
|
double
|
||||||
|
float complex
|
||||||
|
double complex
|
||||||
|
@@ -16,63 +16,64 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with gprMax. If not, see <http://www.gnu.org/licenses/>.
|
# along with gprMax. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
import cython
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from scipy.constants import c
|
from scipy.constants import c
|
||||||
from scipy.constants import mu_0 as m0
|
from scipy.constants import mu_0 as m0
|
||||||
from scipy.constants import epsilon_0 as e0
|
from scipy.constants import epsilon_0 as e0
|
||||||
|
|
||||||
from gprMax.utilities import get_host_info
|
from .utilities import get_host_info
|
||||||
|
|
||||||
# Impedance of free space (Ohms)
|
# Impedance of free space (Ohms)
|
||||||
z0 = np.sqrt(m0 / e0)
|
z0 = np.sqrt(m0 / e0)
|
||||||
|
|
||||||
# Setting whether messages and progress bars are printed
|
# General setting for the simulation
|
||||||
messages = True
|
# inputfilepath: path to inputfile location
|
||||||
progressbars = messages
|
# outputfilepath: path to outputfile location
|
||||||
|
# messages: whether to print all messages as output to stdout or not
|
||||||
|
# progressbars: whether to show progress bars on stdoout or not
|
||||||
|
# mode: 2D TMx, 2D TMy, 2D TMz, or 3D
|
||||||
|
# cpu, cuda, opencl: solver type
|
||||||
|
general = {'inputfilepath': '', 'outputfilepath': '', 'messages': True,
|
||||||
|
'progressbars': True, 'mode': None, 'cpu': True, 'cuda': False, 'opencl': False}
|
||||||
|
|
||||||
# Store information about host machine
|
# Store information about host machine
|
||||||
hostinfo = get_host_info()
|
hostinfo = get_host_info()
|
||||||
|
|
||||||
# Store information about any GPUs as a list of GPU objects
|
# Store information for CUDA solver type
|
||||||
gpus = None
|
# gpus: information about any GPUs as a list of GPU objects
|
||||||
|
# snapsgpu2cpu: copy snapshot data from GPU to CPU during simulation
|
||||||
# Copy snapshot data from GPU to CPU during simulation
|
|
||||||
# N.B. This will happen if the requested snapshots are too large to fit
|
# N.B. This will happen if the requested snapshots are too large to fit
|
||||||
# on the memory of the GPU. If True this will slow performance significantly
|
# on the memory of the GPU. If True this will slow performance significantly
|
||||||
snapsgpu2cpu = False
|
cuda = {'gpus': None, 'snapsgpu2cpu': False}
|
||||||
|
|
||||||
# Numerical dispersion analysis parameters
|
# Numerical dispersion analysis parameters
|
||||||
# Threshold (dB) down from maximum power (0dB) of main frequency used
|
# highestfreqthres: threshold (dB) down from maximum power (0dB) of main frequency used
|
||||||
# to calculate highest frequency for numerical dispersion analysis
|
# to calculate highest frequency for numerical dispersion analysis
|
||||||
# Maximum allowable percentage physical phase-velocity phase error
|
# maxnumericaldisp: maximum allowable percentage physical phase-velocity phase error
|
||||||
# Minimum grid sampling of smallest wavelength for physical wave propagation
|
# mingridsampling: minimum grid sampling of smallest wavelength for physical wave propagation
|
||||||
numdispersion = {'highestfreqthres': 40, 'maxnumericaldisp': 2, 'mingridsampling': 3}
|
numdispersion = {'highestfreqthres': 40, 'maxnumericaldisp': 2, 'mingridsampling': 3}
|
||||||
|
|
||||||
# Simulation mode - 2D TMx, 2D TMy, 2D TMz, or 3D
|
# Materials
|
||||||
mode = None
|
# maxpoles: Maximum number of dispersive material poles in a model
|
||||||
|
materials = {'maxpoles': 0, 'dispersivedtype': None, 'dispersiveCdtype': None}
|
||||||
|
|
||||||
# Data types
|
# Data types
|
||||||
# Solid and ID arrays use 32-bit integers (0 to 4294967295)
|
# Solid and ID arrays use 32-bit integers (0 to 4294967295)
|
||||||
# Rigid arrays use 8-bit integers (the smallest available type to store true/false)
|
# Rigid arrays use 8-bit integers (the smallest available type to store true/false)
|
||||||
# Fractal and dispersive coefficient arrays use complex numbers (complextype)
|
# Fractal and dispersive coefficient arrays use complex numbers (complex)
|
||||||
# which are represented as two floats
|
# which are represented as two floats
|
||||||
# Main field arrays use floats (floattype) and complex numbers (complextype)
|
# Main field arrays use floats (float_or_double) and complex numbers (complex)
|
||||||
|
# Precision of float_or_double and complex: single or double for numpy and C (CUDA) arrays
|
||||||
# Precision of floattype and complextype: single or double
|
|
||||||
precision = 'single'
|
precision = 'single'
|
||||||
|
|
||||||
if precision == 'single':
|
if precision == 'single':
|
||||||
# For numpy arrays
|
dtypes = {'float_or_double': np.float32, 'complex': np.complex64,
|
||||||
floattype = np.float32
|
'cython_float_or_double': cython.float, 'cython_complex': cython.floatcomplex,
|
||||||
complextype = np.complex64
|
'C_float_or_double': 'float', 'C_complex': 'pycuda::complex<float>'}
|
||||||
# For C (CUDA) arrays
|
|
||||||
cudafloattype = 'float'
|
|
||||||
cudacomplextype = 'pycuda::complex<float>'
|
|
||||||
|
|
||||||
elif precision == 'double':
|
elif precision == 'double':
|
||||||
# For numpy arrays
|
dtypes = {'float_or_double': np.float64, 'complex': np.complex128,
|
||||||
floattype = np.float64
|
'cython_float_or_double': cython.double, 'cython_complex': cython.doublecomplex,
|
||||||
complextype = np.complex128
|
'C_float_or_double': 'double', 'C_complex': 'pycuda::complex<double>'}
|
||||||
# For C (CUDA) arrays
|
|
||||||
cudafloattype = 'double'
|
|
||||||
cudacomplextype = 'pycuda::complex<double>'
|
|
||||||
|
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
from string import Template
|
from string import Template
|
||||||
|
|
||||||
kernels_template_fields = Template("""
|
kernel_template_fields = Template("""
|
||||||
|
|
||||||
#include <pycuda-complex.hpp>
|
#include <pycuda-complex.hpp>
|
||||||
|
|
||||||
@@ -33,11 +33,12 @@ kernels_template_fields = Template("""
|
|||||||
__device__ __constant__ $REAL updatecoeffsE[$N_updatecoeffsE];
|
__device__ __constant__ $REAL updatecoeffsE[$N_updatecoeffsE];
|
||||||
__device__ __constant__ $REAL updatecoeffsH[$N_updatecoeffsH];
|
__device__ __constant__ $REAL updatecoeffsH[$N_updatecoeffsH];
|
||||||
|
|
||||||
/////////////////////////////////////////////////
|
|
||||||
// Electric field updates - standard materials //
|
|
||||||
/////////////////////////////////////////////////
|
|
||||||
|
|
||||||
__global__ void update_e(int NX, int NY, int NZ, const unsigned int* __restrict__ ID, $REAL *Ex, $REAL *Ey, $REAL *Ez, const $REAL* __restrict__ Hx, const $REAL* __restrict__ Hy, const $REAL* __restrict__ Hz) {
|
///////////////////////////////////////////////
|
||||||
|
// Electric field updates - normal materials //
|
||||||
|
///////////////////////////////////////////////
|
||||||
|
|
||||||
|
__global__ void update_electric(int NX, int NY, int NZ, const unsigned int* __restrict__ ID, $REAL *Ex, $REAL *Ey, $REAL *Ez, const $REAL* __restrict__ Hx, const $REAL* __restrict__ Hy, const $REAL* __restrict__ Hz) {
|
||||||
|
|
||||||
// This function updates electric field values.
|
// This function updates electric field values.
|
||||||
//
|
//
|
||||||
@@ -77,11 +78,57 @@ __global__ void update_e(int NX, int NY, int NZ, const unsigned int* __restrict_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////
|
||||||
|
// Magnetic field updates //
|
||||||
|
////////////////////////////
|
||||||
|
|
||||||
|
__global__ void update_magnetic(int NX, int NY, int NZ, const unsigned int* __restrict__ ID, $REAL *Hx, $REAL *Hy, $REAL *Hz, const $REAL* __restrict__ Ex, const $REAL* __restrict__ Ey, const $REAL* __restrict__ Ez) {
|
||||||
|
|
||||||
|
// This function updates magnetic field values.
|
||||||
|
//
|
||||||
|
// Args:
|
||||||
|
// NX, NY, NZ: Number of cells of the model domain
|
||||||
|
// ID, E, H: Access to ID and field component arrays
|
||||||
|
|
||||||
|
// Obtain the linear index corresponding to the current thread
|
||||||
|
int idx = blockIdx.x * blockDim.x + threadIdx.x;
|
||||||
|
|
||||||
|
// Convert the linear index to subscripts for 3D field arrays
|
||||||
|
int i = idx / ($NY_FIELDS * $NZ_FIELDS);
|
||||||
|
int j = (idx % ($NY_FIELDS * $NZ_FIELDS)) / $NZ_FIELDS;
|
||||||
|
int k = (idx % ($NY_FIELDS * $NZ_FIELDS)) % $NZ_FIELDS;
|
||||||
|
|
||||||
|
// Convert the linear index to subscripts for 4D material ID array
|
||||||
|
int i_ID = (idx % ($NX_ID * $NY_ID * $NZ_ID)) / ($NY_ID * $NZ_ID);
|
||||||
|
int j_ID = ((idx % ($NX_ID * $NY_ID * $NZ_ID)) % ($NY_ID * $NZ_ID)) / $NZ_ID;
|
||||||
|
int k_ID = ((idx % ($NX_ID * $NY_ID * $NZ_ID)) % ($NY_ID * $NZ_ID)) % $NZ_ID;
|
||||||
|
|
||||||
|
// Hx component
|
||||||
|
if (NX != 1 && i > 0 && i < NX && j >= 0 && j < NY && k >= 0 && k < NZ) {
|
||||||
|
int materialHx = ID[INDEX4D_ID(3,i_ID,j_ID,k_ID)];
|
||||||
|
Hx[INDEX3D_FIELDS(i,j,k)] = updatecoeffsH[INDEX2D_MAT(materialHx,0)] * Hx[INDEX3D_FIELDS(i,j,k)] - updatecoeffsH[INDEX2D_MAT(materialHx,2)] * (Ez[INDEX3D_FIELDS(i,j+1,k)] - Ez[INDEX3D_FIELDS(i,j,k)]) + updatecoeffsH[INDEX2D_MAT(materialHx,3)] * (Ey[INDEX3D_FIELDS(i,j,k+1)] - Ey[INDEX3D_FIELDS(i,j,k)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hy component
|
||||||
|
if (NY != 1 && i >= 0 && i < NX && j > 0 && j < NY && k >= 0 && k < NZ) {
|
||||||
|
int materialHy = ID[INDEX4D_ID(4,i_ID,j_ID,k_ID)];
|
||||||
|
Hy[INDEX3D_FIELDS(i,j,k)] = updatecoeffsH[INDEX2D_MAT(materialHy,0)] * Hy[INDEX3D_FIELDS(i,j,k)] - updatecoeffsH[INDEX2D_MAT(materialHy,3)] * (Ex[INDEX3D_FIELDS(i,j,k+1)] - Ex[INDEX3D_FIELDS(i,j,k)]) + updatecoeffsH[INDEX2D_MAT(materialHy,1)] * (Ez[INDEX3D_FIELDS(i+1,j,k)] - Ez[INDEX3D_FIELDS(i,j,k)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hz component
|
||||||
|
if (NZ != 1 && i >= 0 && i < NX && j >= 0 && j < NY && k > 0 && k < NZ) {
|
||||||
|
int materialHz = ID[INDEX4D_ID(5,i_ID,j_ID,k_ID)];
|
||||||
|
Hz[INDEX3D_FIELDS(i,j,k)] = updatecoeffsH[INDEX2D_MAT(materialHz,0)] * Hz[INDEX3D_FIELDS(i,j,k)] - updatecoeffsH[INDEX2D_MAT(materialHz,1)] * (Ey[INDEX3D_FIELDS(i+1,j,k)] - Ey[INDEX3D_FIELDS(i,j,k)]) + updatecoeffsH[INDEX2D_MAT(materialHz,2)] * (Ex[INDEX3D_FIELDS(i,j+1,k)] - Ex[INDEX3D_FIELDS(i,j,k)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////
|
///////////////////////////////////////////////////
|
||||||
// Electric field updates - dispersive materials //
|
// Electric field updates - dispersive materials //
|
||||||
///////////////////////////////////////////////////
|
///////////////////////////////////////////////////
|
||||||
|
|
||||||
__global__ void update_e_dispersive_A(int NX, int NY, int NZ, int MAXPOLES, const $COMPLEX* __restrict__ updatecoeffsdispersive, $COMPLEX *Tx, $COMPLEX *Ty, $COMPLEX *Tz, const unsigned int* __restrict__ ID, $REAL *Ex, $REAL *Ey, $REAL *Ez, const $REAL* __restrict__ Hx, const $REAL* __restrict__ Hy, const $REAL* __restrict__ Hz) {
|
__global__ void update_electric_dispersive_A(int NX, int NY, int NZ, int MAXPOLES, const $REAL_OR_COMPLEX* __restrict__ updatecoeffsdispersive, $REAL_OR_COMPLEX *Tx, $REAL_OR_COMPLEX *Ty, $REAL_OR_COMPLEX *Tz, const unsigned int* __restrict__ ID, $REAL *Ex, $REAL *Ey, $REAL *Ez, const $REAL* __restrict__ Hx, const $REAL* __restrict__ Hy, const $REAL* __restrict__ Hz) {
|
||||||
|
|
||||||
// This function is part A of updates to electric field values when dispersive materials (with multiple poles) are present.
|
// This function is part A of updates to electric field values when dispersive materials (with multiple poles) are present.
|
||||||
//
|
//
|
||||||
@@ -142,7 +189,7 @@ __global__ void update_e_dispersive_A(int NX, int NY, int NZ, int MAXPOLES, cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__global__ void update_e_dispersive_B(int NX, int NY, int NZ, int MAXPOLES, const $COMPLEX* __restrict__ updatecoeffsdispersive, $COMPLEX *Tx, $COMPLEX *Ty, $COMPLEX *Tz, const unsigned int* __restrict__ ID, const $REAL* __restrict__ Ex, const $REAL* __restrict__ Ey, const $REAL* __restrict__ Ez) {
|
__global__ void update_electric_dispersive_B(int NX, int NY, int NZ, int MAXPOLES, const $REAL_OR_COMPLEX* __restrict__ updatecoeffsdispersive, $REAL_OR_COMPLEX *Tx, $REAL_OR_COMPLEX *Ty, $REAL_OR_COMPLEX *Tz, const unsigned int* __restrict__ ID, const $REAL* __restrict__ Ex, const $REAL* __restrict__ Ey, const $REAL* __restrict__ Ez) {
|
||||||
|
|
||||||
// This function is part B which updates the dispersive field arrays when dispersive materials (with multiple poles) are present.
|
// This function is part B which updates the dispersive field arrays when dispersive materials (with multiple poles) are present.
|
||||||
//
|
//
|
||||||
@@ -194,49 +241,4 @@ __global__ void update_e_dispersive_B(int NX, int NY, int NZ, int MAXPOLES, cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////
|
|
||||||
// Magnetic field updates //
|
|
||||||
////////////////////////////
|
|
||||||
|
|
||||||
__global__ void update_h(int NX, int NY, int NZ, const unsigned int* __restrict__ ID, $REAL *Hx, $REAL *Hy, $REAL *Hz, const $REAL* __restrict__ Ex, const $REAL* __restrict__ Ey, const $REAL* __restrict__ Ez) {
|
|
||||||
|
|
||||||
// This function updates magnetic field values.
|
|
||||||
//
|
|
||||||
// Args:
|
|
||||||
// NX, NY, NZ: Number of cells of the model domain
|
|
||||||
// ID, E, H: Access to ID and field component arrays
|
|
||||||
|
|
||||||
// Obtain the linear index corresponding to the current thread
|
|
||||||
int idx = blockIdx.x * blockDim.x + threadIdx.x;
|
|
||||||
|
|
||||||
// Convert the linear index to subscripts for 3D field arrays
|
|
||||||
int i = idx / ($NY_FIELDS * $NZ_FIELDS);
|
|
||||||
int j = (idx % ($NY_FIELDS * $NZ_FIELDS)) / $NZ_FIELDS;
|
|
||||||
int k = (idx % ($NY_FIELDS * $NZ_FIELDS)) % $NZ_FIELDS;
|
|
||||||
|
|
||||||
// Convert the linear index to subscripts for 4D material ID array
|
|
||||||
int i_ID = (idx % ($NX_ID * $NY_ID * $NZ_ID)) / ($NY_ID * $NZ_ID);
|
|
||||||
int j_ID = ((idx % ($NX_ID * $NY_ID * $NZ_ID)) % ($NY_ID * $NZ_ID)) / $NZ_ID;
|
|
||||||
int k_ID = ((idx % ($NX_ID * $NY_ID * $NZ_ID)) % ($NY_ID * $NZ_ID)) % $NZ_ID;
|
|
||||||
|
|
||||||
// Hx component
|
|
||||||
if (NX != 1 && i > 0 && i < NX && j >= 0 && j < NY && k >= 0 && k < NZ) {
|
|
||||||
int materialHx = ID[INDEX4D_ID(3,i_ID,j_ID,k_ID)];
|
|
||||||
Hx[INDEX3D_FIELDS(i,j,k)] = updatecoeffsH[INDEX2D_MAT(materialHx,0)] * Hx[INDEX3D_FIELDS(i,j,k)] - updatecoeffsH[INDEX2D_MAT(materialHx,2)] * (Ez[INDEX3D_FIELDS(i,j+1,k)] - Ez[INDEX3D_FIELDS(i,j,k)]) + updatecoeffsH[INDEX2D_MAT(materialHx,3)] * (Ey[INDEX3D_FIELDS(i,j,k+1)] - Ey[INDEX3D_FIELDS(i,j,k)]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hy component
|
|
||||||
if (NY != 1 && i >= 0 && i < NX && j > 0 && j < NY && k >= 0 && k < NZ) {
|
|
||||||
int materialHy = ID[INDEX4D_ID(4,i_ID,j_ID,k_ID)];
|
|
||||||
Hy[INDEX3D_FIELDS(i,j,k)] = updatecoeffsH[INDEX2D_MAT(materialHy,0)] * Hy[INDEX3D_FIELDS(i,j,k)] - updatecoeffsH[INDEX2D_MAT(materialHy,3)] * (Ex[INDEX3D_FIELDS(i,j,k+1)] - Ex[INDEX3D_FIELDS(i,j,k)]) + updatecoeffsH[INDEX2D_MAT(materialHy,1)] * (Ez[INDEX3D_FIELDS(i+1,j,k)] - Ez[INDEX3D_FIELDS(i,j,k)]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hz component
|
|
||||||
if (NZ != 1 && i >= 0 && i < NX && j >= 0 && j < NY && k > 0 && k < NZ) {
|
|
||||||
int materialHz = ID[INDEX4D_ID(5,i_ID,j_ID,k_ID)];
|
|
||||||
Hz[INDEX3D_FIELDS(i,j,k)] = updatecoeffsH[INDEX2D_MAT(materialHz,0)] * Hz[INDEX3D_FIELDS(i,j,k)] - updatecoeffsH[INDEX2D_MAT(materialHz,1)] * (Ey[INDEX3D_FIELDS(i+1,j,k)] - Ey[INDEX3D_FIELDS(i,j,k)]) + updatecoeffsH[INDEX2D_MAT(materialHz,2)] * (Ex[INDEX3D_FIELDS(i,j+1,k)] - Ex[INDEX3D_FIELDS(i,j,k)]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
""")
|
""")
|
||||||
|
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
from string import Template
|
from string import Template
|
||||||
|
|
||||||
kernels_template_sources = Template("""
|
kernel_template_sources = Template("""
|
||||||
|
|
||||||
// Macros for converting subscripts to linear index:
|
// Macros for converting subscripts to linear index:
|
||||||
#define INDEX2D_MAT(m, n) (m)*($NY_MATCOEFFS)+(n)
|
#define INDEX2D_MAT(m, n) (m)*($NY_MATCOEFFS)+(n)
|
||||||
|
@@ -1,412 +0,0 @@
|
|||||||
# Copyright (C) 2015-2019: The University of Edinburgh
|
|
||||||
# Authors: Craig Warren and Antonis Giannopoulos
|
|
||||||
#
|
|
||||||
# This file is part of gprMax.
|
|
||||||
#
|
|
||||||
# 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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
cimport numpy as np
|
|
||||||
from cython.parallel import prange
|
|
||||||
|
|
||||||
from gprMax.config cimport floattype_t
|
|
||||||
from gprMax.config cimport complextype_t
|
|
||||||
|
|
||||||
|
|
||||||
###############################################
|
|
||||||
# Electric field updates - standard materials #
|
|
||||||
###############################################
|
|
||||||
cpdef void update_electric(
|
|
||||||
int nx,
|
|
||||||
int ny,
|
|
||||||
int nz,
|
|
||||||
int nthreads,
|
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
|
||||||
floattype_t[:, :, ::1] Ex,
|
|
||||||
floattype_t[:, :, ::1] Ey,
|
|
||||||
floattype_t[:, :, ::1] Ez,
|
|
||||||
floattype_t[:, :, ::1] Hx,
|
|
||||||
floattype_t[:, :, ::1] Hy,
|
|
||||||
floattype_t[:, :, ::1] Hz
|
|
||||||
):
|
|
||||||
"""This function updates the electric field components.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
nx, ny, nz (int): Grid size in cells
|
|
||||||
nthreads (int): Number of threads to use
|
|
||||||
updatecoeffs, ID, E, H (memoryviews): Access to update coeffients, ID and field component arrays
|
|
||||||
"""
|
|
||||||
|
|
||||||
cdef Py_ssize_t i, j, k
|
|
||||||
cdef int materialEx, materialEy, materialEz
|
|
||||||
|
|
||||||
# 2D - Ex component
|
|
||||||
if nx == 1:
|
|
||||||
for i in prange(0, nx, nogil=True, schedule='static', num_threads=nthreads):
|
|
||||||
for j in range(1, ny):
|
|
||||||
for k in range(1, nz):
|
|
||||||
materialEx = ID[0, i, j, k]
|
|
||||||
Ex[i, j, k] = updatecoeffsE[materialEx, 0] * Ex[i, j, k] + updatecoeffsE[materialEx, 2] * (Hz[i, j, k] - Hz[i, j - 1, k]) - updatecoeffsE[materialEx, 3] * (Hy[i, j, k] - Hy[i, j, k - 1])
|
|
||||||
|
|
||||||
# 2D - Ey component
|
|
||||||
elif ny == 1:
|
|
||||||
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
|
||||||
for j in range(0, ny):
|
|
||||||
for k in range(1, nz):
|
|
||||||
materialEy = ID[1, i, j, k]
|
|
||||||
Ey[i, j, k] = updatecoeffsE[materialEy, 0] * Ey[i, j, k] + updatecoeffsE[materialEy, 3] * (Hx[i, j, k] - Hx[i, j, k - 1]) - updatecoeffsE[materialEy, 1] * (Hz[i, j, k] - Hz[i - 1, j, k])
|
|
||||||
|
|
||||||
# 2D - Ez component
|
|
||||||
elif nz == 1:
|
|
||||||
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
|
||||||
for j in range(1, ny):
|
|
||||||
for k in range(0, nz):
|
|
||||||
materialEz = ID[2, i, j, k]
|
|
||||||
Ez[i, j, k] = updatecoeffsE[materialEz, 0] * Ez[i, j, k] + updatecoeffsE[materialEz, 1] * (Hy[i, j, k] - Hy[i - 1, j, k]) - updatecoeffsE[materialEz, 2] * (Hx[i, j, k] - Hx[i, j - 1, k])
|
|
||||||
|
|
||||||
# 3D
|
|
||||||
else:
|
|
||||||
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
|
||||||
for j in range(1, ny):
|
|
||||||
for k in range(1, nz):
|
|
||||||
materialEx = ID[0, i, j, k]
|
|
||||||
materialEy = ID[1, i, j, k]
|
|
||||||
materialEz = ID[2, i, j, k]
|
|
||||||
Ex[i, j, k] = updatecoeffsE[materialEx, 0] * Ex[i, j, k] + updatecoeffsE[materialEx, 2] * (Hz[i, j, k] - Hz[i, j - 1, k]) - updatecoeffsE[materialEx, 3] * (Hy[i, j, k] - Hy[i, j, k - 1])
|
|
||||||
Ey[i, j, k] = updatecoeffsE[materialEy, 0] * Ey[i, j, k] + updatecoeffsE[materialEy, 3] * (Hx[i, j, k] - Hx[i, j, k - 1]) - updatecoeffsE[materialEy, 1] * (Hz[i, j, k] - Hz[i - 1, j, k])
|
|
||||||
Ez[i, j, k] = updatecoeffsE[materialEz, 0] * Ez[i, j, k] + updatecoeffsE[materialEz, 1] * (Hy[i, j, k] - Hy[i - 1, j, k]) - updatecoeffsE[materialEz, 2] * (Hx[i, j, k] - Hx[i, j - 1, k])
|
|
||||||
|
|
||||||
# Ex components at i = 0
|
|
||||||
for j in prange(1, ny, nogil=True, schedule='static', num_threads=nthreads):
|
|
||||||
for k in range(1, nz):
|
|
||||||
materialEx = ID[0, 0, j, k]
|
|
||||||
Ex[0, j, k] = updatecoeffsE[materialEx, 0] * Ex[0, j, k] + updatecoeffsE[materialEx, 2] * (Hz[0, j, k] - Hz[0, j - 1, k]) - updatecoeffsE[materialEx, 3] * (Hy[0, j, k] - Hy[0, j, k - 1])
|
|
||||||
|
|
||||||
# Ey components at j = 0
|
|
||||||
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
|
||||||
for k in range(1, nz):
|
|
||||||
materialEy = ID[1, i, 0, k]
|
|
||||||
Ey[i, 0, k] = updatecoeffsE[materialEy, 0] * Ey[i, 0, k] + updatecoeffsE[materialEy, 3] * (Hx[i, 0, k] - Hx[i, 0, k - 1]) - updatecoeffsE[materialEy, 1] * (Hz[i, 0, k] - Hz[i - 1, 0, k])
|
|
||||||
|
|
||||||
# Ez components at k = 0
|
|
||||||
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
|
||||||
for j in range(1, ny):
|
|
||||||
materialEz = ID[2, i, j, 0]
|
|
||||||
Ez[i, j, 0] = updatecoeffsE[materialEz, 0] * Ez[i, j, 0] + updatecoeffsE[materialEz, 1] * (Hy[i, j, 0] - Hy[i - 1, j, 0]) - updatecoeffsE[materialEz, 2] * (Hx[i, j, 0] - Hx[i, j - 1, 0])
|
|
||||||
|
|
||||||
|
|
||||||
#################################################
|
|
||||||
# Electric field updates - dispersive materials #
|
|
||||||
#################################################
|
|
||||||
cpdef void update_electric_dispersive_multipole_A(
|
|
||||||
int nx,
|
|
||||||
int ny,
|
|
||||||
int nz,
|
|
||||||
int nthreads,
|
|
||||||
int maxpoles,
|
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
|
||||||
complextype_t[:, ::1] updatecoeffsdispersive,
|
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
|
||||||
complextype_t[:, :, :, ::1] Tx,
|
|
||||||
complextype_t[:, :, :, ::1] Ty,
|
|
||||||
complextype_t[:, :, :, ::1] Tz,
|
|
||||||
floattype_t[:, :, ::1] Ex,
|
|
||||||
floattype_t[:, :, ::1] Ey,
|
|
||||||
floattype_t[:, :, ::1] Ez,
|
|
||||||
floattype_t[:, :, ::1] Hx,
|
|
||||||
floattype_t[:, :, ::1] Hy,
|
|
||||||
floattype_t[:, :, ::1] Hz
|
|
||||||
):
|
|
||||||
"""This function updates the electric field components when dispersive materials (with multiple poles) are present.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
nx, ny, nz (int): Grid size in cells
|
|
||||||
maxpoles (int): Maximum number of poles
|
|
||||||
nthreads (int): Number of threads to use
|
|
||||||
updatecoeffs, T, ID, E, H (memoryviews): Access to update coeffients, temporary, ID and field component arrays
|
|
||||||
"""
|
|
||||||
|
|
||||||
cdef Py_ssize_t i, j, k, pole
|
|
||||||
cdef int material
|
|
||||||
cdef float phi = 0
|
|
||||||
|
|
||||||
# Ex component
|
|
||||||
if ny != 1 or nz != 1:
|
|
||||||
for i in prange(0, nx, nogil=True, schedule='static', num_threads=nthreads):
|
|
||||||
for j in range(1, ny):
|
|
||||||
for k in range(1, nz):
|
|
||||||
material = ID[0, i, j, k]
|
|
||||||
phi = 0
|
|
||||||
for pole in range(maxpoles):
|
|
||||||
phi = phi + updatecoeffsdispersive[material, pole * 3].real * Tx[pole, i, j, k].real
|
|
||||||
Tx[pole, i, j, k] = updatecoeffsdispersive[material, 1 + (pole * 3)] * Tx[pole, i, j, k] + updatecoeffsdispersive[material, 2 + (pole * 3)] * Ex[i, j, k]
|
|
||||||
Ex[i, j, k] = updatecoeffsE[material, 0] * Ex[i, j, k] + updatecoeffsE[material, 2] * (Hz[i, j, k] - Hz[i, j - 1, k]) - updatecoeffsE[material, 3] * (Hy[i, j, k] - Hy[i, j, k - 1]) - updatecoeffsE[material, 4] * phi
|
|
||||||
|
|
||||||
# Ey component
|
|
||||||
if nx != 1 or nz != 1:
|
|
||||||
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
|
||||||
for j in range(0, ny):
|
|
||||||
for k in range(1, nz):
|
|
||||||
material = ID[1, i, j, k]
|
|
||||||
phi = 0
|
|
||||||
for pole in range(maxpoles):
|
|
||||||
phi = phi + updatecoeffsdispersive[material, pole * 3].real * Ty[pole, i, j, k].real
|
|
||||||
Ty[pole, i, j, k] = updatecoeffsdispersive[material, 1 + (pole * 3)] * Ty[pole, i, j, k] + updatecoeffsdispersive[material, 2 + (pole * 3)] * Ey[i, j, k]
|
|
||||||
Ey[i, j, k] = updatecoeffsE[material, 0] * Ey[i, j, k] + updatecoeffsE[material, 3] * (Hx[i, j, k] - Hx[i, j, k - 1]) - updatecoeffsE[material, 1] * (Hz[i, j, k] - Hz[i - 1, j, k]) - updatecoeffsE[material, 4] * phi
|
|
||||||
|
|
||||||
# Ez component
|
|
||||||
if nx != 1 or ny != 1:
|
|
||||||
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
|
||||||
for j in range(1, ny):
|
|
||||||
for k in range(0, nz):
|
|
||||||
material = ID[2, i, j, k]
|
|
||||||
phi = 0
|
|
||||||
for pole in range(maxpoles):
|
|
||||||
phi = phi + updatecoeffsdispersive[material, pole * 3].real * Tz[pole, i, j, k].real
|
|
||||||
Tz[pole, i, j, k] = updatecoeffsdispersive[material, 1 + (pole * 3)] * Tz[pole, i, j, k] + updatecoeffsdispersive[material, 2 + (pole * 3)] * Ez[i, j, k]
|
|
||||||
Ez[i, j, k] = updatecoeffsE[material, 0] * Ez[i, j, k] + updatecoeffsE[material, 1] * (Hy[i, j, k] - Hy[i - 1, j, k]) - updatecoeffsE[material, 2] * (Hx[i, j, k] - Hx[i, j - 1, k]) - updatecoeffsE[material, 4] * phi
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cpdef void update_electric_dispersive_multipole_B(
|
|
||||||
int nx,
|
|
||||||
int ny,
|
|
||||||
int nz,
|
|
||||||
int nthreads,
|
|
||||||
int maxpoles,
|
|
||||||
complextype_t[:, ::1] updatecoeffsdispersive,
|
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
|
||||||
complextype_t[:, :, :, ::1] Tx,
|
|
||||||
complextype_t[:, :, :, ::1] Ty,
|
|
||||||
complextype_t[:, :, :, ::1] Tz,
|
|
||||||
floattype_t[:, :, ::1] Ex,
|
|
||||||
floattype_t[:, :, ::1] Ey,
|
|
||||||
floattype_t[:, :, ::1] Ez
|
|
||||||
):
|
|
||||||
"""This function updates a temporary dispersive material array when disperisive materials (with multiple poles) are present.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
nx, ny, nz (int): Grid size in cells
|
|
||||||
maxpoles (int): Maximum number of poles
|
|
||||||
nthreads (int): Number of threads to use
|
|
||||||
updatecoeffs, T, ID, E (memoryviews): Access to update coeffients, temporary, ID and field component arrays
|
|
||||||
"""
|
|
||||||
|
|
||||||
cdef Py_ssize_t i, j, k, pole
|
|
||||||
cdef int material
|
|
||||||
|
|
||||||
# Ex component
|
|
||||||
if ny != 1 or nz != 1:
|
|
||||||
for i in prange(0, nx, nogil=True, schedule='static', num_threads=nthreads):
|
|
||||||
for j in range(1, ny):
|
|
||||||
for k in range(1, nz):
|
|
||||||
material = ID[0, i, j, k]
|
|
||||||
for pole in range(maxpoles):
|
|
||||||
Tx[pole, i, j, k] = Tx[pole, i, j, k] - updatecoeffsdispersive[material, 2 + (pole * 3)] * Ex[i, j, k]
|
|
||||||
|
|
||||||
# Ey component
|
|
||||||
if nx != 1 or nz != 1:
|
|
||||||
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
|
||||||
for j in range(0, ny):
|
|
||||||
for k in range(1, nz):
|
|
||||||
material = ID[1, i, j, k]
|
|
||||||
for pole in range(maxpoles):
|
|
||||||
Ty[pole, i, j, k] = Ty[pole, i, j, k] - updatecoeffsdispersive[material, 2 + (pole * 3)] * Ey[i, j, k]
|
|
||||||
|
|
||||||
# Ez component
|
|
||||||
if nx != 1 or ny != 1:
|
|
||||||
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
|
||||||
for j in range(1, ny):
|
|
||||||
for k in range(0, nz):
|
|
||||||
material = ID[2, i, j, k]
|
|
||||||
for pole in range(maxpoles):
|
|
||||||
Tz[pole, i, j, k] = Tz[pole, i, j, k] - updatecoeffsdispersive[material, 2 + (pole * 3)] * Ez[i, j, k]
|
|
||||||
|
|
||||||
|
|
||||||
cpdef void update_electric_dispersive_1pole_A(
|
|
||||||
int nx,
|
|
||||||
int ny,
|
|
||||||
int nz,
|
|
||||||
int nthreads,
|
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
|
||||||
complextype_t[:, ::1] updatecoeffsdispersive,
|
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
|
||||||
complextype_t[:, :, :, ::1] Tx,
|
|
||||||
complextype_t[:, :, :, ::1] Ty,
|
|
||||||
complextype_t[:, :, :, ::1] Tz,
|
|
||||||
floattype_t[:, :, ::1] Ex,
|
|
||||||
floattype_t[:, :, ::1] Ey,
|
|
||||||
floattype_t[:, :, ::1] Ez,
|
|
||||||
floattype_t[:, :, ::1] Hx,
|
|
||||||
floattype_t[:, :, ::1] Hy,
|
|
||||||
floattype_t[:, :, ::1] Hz
|
|
||||||
):
|
|
||||||
"""This function updates the electric field components when dispersive materials (with 1 pole) are present.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
nx, ny, nz (int): Grid size in cells
|
|
||||||
nthreads (int): Number of threads to use
|
|
||||||
updatecoeffs, T, ID, E, H (memoryviews): Access to update coeffients, temporary, ID and field component arrays
|
|
||||||
"""
|
|
||||||
|
|
||||||
cdef Py_ssize_t i, j, k
|
|
||||||
cdef int material
|
|
||||||
cdef float phi = 0
|
|
||||||
|
|
||||||
# Ex component
|
|
||||||
if ny != 1 or nz != 1:
|
|
||||||
for i in prange(0, nx, nogil=True, schedule='static', num_threads=nthreads):
|
|
||||||
for j in range(1, ny):
|
|
||||||
for k in range(1, nz):
|
|
||||||
material = ID[0, i, j, k]
|
|
||||||
phi = updatecoeffsdispersive[material, 0].real * Tx[0, i, j, k].real
|
|
||||||
Tx[0, i, j, k] = updatecoeffsdispersive[material, 1] * Tx[0, i, j, k] + updatecoeffsdispersive[material, 2] * Ex[i, j, k]
|
|
||||||
Ex[i, j, k] = updatecoeffsE[material, 0] * Ex[i, j, k] + updatecoeffsE[material, 2] * (Hz[i, j, k] - Hz[i, j - 1, k]) - updatecoeffsE[material, 3] * (Hy[i, j, k] - Hy[i, j, k - 1]) - updatecoeffsE[material, 4] * phi
|
|
||||||
|
|
||||||
# Ey component
|
|
||||||
if nx != 1 or nz != 1:
|
|
||||||
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
|
||||||
for j in range(0, ny):
|
|
||||||
for k in range(1, nz):
|
|
||||||
material = ID[1, i, j, k]
|
|
||||||
phi = updatecoeffsdispersive[material, 0].real * Ty[0, i, j, k].real
|
|
||||||
Ty[0, i, j, k] = updatecoeffsdispersive[material, 1] * Ty[0, i, j, k] + updatecoeffsdispersive[material, 2] * Ey[i, j, k]
|
|
||||||
Ey[i, j, k] = updatecoeffsE[material, 0] * Ey[i, j, k] + updatecoeffsE[material, 3] * (Hx[i, j, k] - Hx[i, j, k - 1]) - updatecoeffsE[material, 1] * (Hz[i, j, k] - Hz[i - 1, j, k]) - updatecoeffsE[material, 4] * phi
|
|
||||||
|
|
||||||
# Ez component
|
|
||||||
if nx != 1 or ny != 1:
|
|
||||||
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
|
||||||
for j in range(1, ny):
|
|
||||||
for k in range(0, nz):
|
|
||||||
material = ID[2, i, j, k]
|
|
||||||
phi = updatecoeffsdispersive[material, 0].real * Tz[0, i, j, k].real
|
|
||||||
Tz[0, i, j, k] = updatecoeffsdispersive[material, 1] * Tz[0, i, j, k] + updatecoeffsdispersive[material, 2] * Ez[i, j, k]
|
|
||||||
Ez[i, j, k] = updatecoeffsE[material, 0] * Ez[i, j, k] + updatecoeffsE[material, 1] * (Hy[i, j, k] - Hy[i - 1, j, k]) - updatecoeffsE[material, 2] * (Hx[i, j, k] - Hx[i, j - 1, k]) - updatecoeffsE[material, 4] * phi
|
|
||||||
|
|
||||||
|
|
||||||
cpdef void update_electric_dispersive_1pole_B(
|
|
||||||
int nx,
|
|
||||||
int ny,
|
|
||||||
int nz,
|
|
||||||
int nthreads,
|
|
||||||
complextype_t[:, ::1] updatecoeffsdispersive,
|
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
|
||||||
complextype_t[:, :, :, ::1] Tx,
|
|
||||||
complextype_t[:, :, :, ::1] Ty,
|
|
||||||
complextype_t[:, :, :, ::1] Tz,
|
|
||||||
floattype_t[:, :, ::1] Ex,
|
|
||||||
floattype_t[:, :, ::1] Ey,
|
|
||||||
floattype_t[:, :, ::1] Ez
|
|
||||||
):
|
|
||||||
"""This function updates a temporary dispersive material array when disperisive materials (with 1 pole) are present.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
nx, ny, nz (int): Grid size in cells
|
|
||||||
nthreads (int): Number of threads to use
|
|
||||||
updatecoeffs, T, ID, E (memoryviews): Access to update coeffients, temporary, ID and field component arrays
|
|
||||||
"""
|
|
||||||
|
|
||||||
cdef Py_ssize_t i, j, k
|
|
||||||
cdef int material
|
|
||||||
|
|
||||||
# Ex component
|
|
||||||
if ny != 1 or nz != 1:
|
|
||||||
for i in prange(0, nx, nogil=True, schedule='static', num_threads=nthreads):
|
|
||||||
for j in range(1, ny):
|
|
||||||
for k in range(1, nz):
|
|
||||||
material = ID[0, i, j, k]
|
|
||||||
Tx[0, i, j, k] = Tx[0, i, j, k] - updatecoeffsdispersive[material, 2] * Ex[i, j, k]
|
|
||||||
|
|
||||||
# Ey component
|
|
||||||
if nx != 1 or nz != 1:
|
|
||||||
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
|
||||||
for j in range(0, ny):
|
|
||||||
for k in range(1, nz):
|
|
||||||
material = ID[1, i, j, k]
|
|
||||||
Ty[0, i, j, k] = Ty[0, i, j, k] - updatecoeffsdispersive[material, 2] * Ey[i, j, k]
|
|
||||||
|
|
||||||
# Ez component
|
|
||||||
if nx != 1 or ny != 1:
|
|
||||||
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
|
||||||
for j in range(1, ny):
|
|
||||||
for k in range(0, nz):
|
|
||||||
material = ID[2, i, j, k]
|
|
||||||
Tz[0, i, j, k] = Tz[0, i, j, k] - updatecoeffsdispersive[material, 2] * Ez[i, j, k]
|
|
||||||
|
|
||||||
|
|
||||||
##########################
|
|
||||||
# Magnetic field updates #
|
|
||||||
##########################
|
|
||||||
cpdef void update_magnetic(
|
|
||||||
int nx,
|
|
||||||
int ny,
|
|
||||||
int nz,
|
|
||||||
int nthreads,
|
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
|
||||||
floattype_t[:, :, ::1] Ex,
|
|
||||||
floattype_t[:, :, ::1] Ey,
|
|
||||||
floattype_t[:, :, ::1] Ez,
|
|
||||||
floattype_t[:, :, ::1] Hx,
|
|
||||||
floattype_t[:, :, ::1] Hy,
|
|
||||||
floattype_t[:, :, ::1] Hz
|
|
||||||
):
|
|
||||||
"""This function updates the magnetic field components.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
nx, ny, nz (int): Grid size in cells
|
|
||||||
nthreads (int): Number of threads to use
|
|
||||||
updatecoeffs, ID, E, H (memoryviews): Access to update coeffients, ID and field component arrays
|
|
||||||
"""
|
|
||||||
|
|
||||||
cdef Py_ssize_t i, j, k
|
|
||||||
cdef int materialHx, materialHy, materialHz
|
|
||||||
|
|
||||||
# 2D
|
|
||||||
if nx == 1 or ny == 1 or nz == 1:
|
|
||||||
# Hx component
|
|
||||||
if ny == 1 or nz == 1:
|
|
||||||
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
|
||||||
for j in range(0, ny):
|
|
||||||
for k in range(0, nz):
|
|
||||||
materialHx = ID[3, i, j, k]
|
|
||||||
Hx[i, j, k] = updatecoeffsH[materialHx, 0] * Hx[i, j, k] - updatecoeffsH[materialHx, 2] * (Ez[i, j + 1, k] - Ez[i, j, k]) + updatecoeffsH[materialHx, 3] * (Ey[i, j, k + 1] - Ey[i, j, k])
|
|
||||||
|
|
||||||
# Hy component
|
|
||||||
if nx == 1 or nz == 1:
|
|
||||||
for i in prange(0, nx, nogil=True, schedule='static', num_threads=nthreads):
|
|
||||||
for j in range(1, ny):
|
|
||||||
for k in range(0, nz):
|
|
||||||
materialHy = ID[4, i, j, k]
|
|
||||||
Hy[i, j, k] = updatecoeffsH[materialHy, 0] * Hy[i, j, k] - updatecoeffsH[materialHy, 3] * (Ex[i, j, k + 1] - Ex[i, j, k]) + updatecoeffsH[materialHy, 1] * (Ez[i + 1, j, k] - Ez[i, j, k])
|
|
||||||
|
|
||||||
# Hz component
|
|
||||||
if nx == 1 or ny == 1:
|
|
||||||
for i in prange(0, nx, nogil=True, schedule='static', num_threads=nthreads):
|
|
||||||
for j in range(0, ny):
|
|
||||||
for k in range(1, nz):
|
|
||||||
materialHz = ID[5, i, j, k]
|
|
||||||
Hz[i, j, k] = updatecoeffsH[materialHz, 0] * Hz[i, j, k] - updatecoeffsH[materialHz, 1] * (Ey[i + 1, j, k] - Ey[i, j, k]) + updatecoeffsH[materialHz, 2] * (Ex[i, j + 1, k] - Ex[i, j, k])
|
|
||||||
# 3D
|
|
||||||
else:
|
|
||||||
for i in prange(0, nx, nogil=True, schedule='static', num_threads=nthreads):
|
|
||||||
for j in range(0, ny):
|
|
||||||
for k in range(0, nz):
|
|
||||||
materialHx = ID[3, i + 1, j, k]
|
|
||||||
materialHy = ID[4, i, j + 1, k]
|
|
||||||
materialHz = ID[5, i, j, k + 1]
|
|
||||||
Hx[i + 1, j, k] = updatecoeffsH[materialHx, 0] * Hx[i + 1, j, k] - updatecoeffsH[materialHx, 2] * (Ez[i + 1, j + 1, k] - Ez[i + 1, j, k]) + updatecoeffsH[materialHx, 3] * (Ey[i + 1, j, k + 1] - Ey[i + 1, j, k])
|
|
||||||
Hy[i, j + 1, k] = updatecoeffsH[materialHy, 0] * Hy[i, j + 1, k] - updatecoeffsH[materialHy, 3] * (Ex[i, j + 1, k + 1] - Ex[i, j + 1, k]) + updatecoeffsH[materialHy, 1] * (Ez[i + 1, j + 1, k] - Ez[i, j + 1, k])
|
|
||||||
Hz[i, j, k + 1] = updatecoeffsH[materialHz, 0] * Hz[i, j, k + 1] - updatecoeffsH[materialHz, 1] * (Ey[i + 1, j, k + 1] - Ey[i, j, k + 1]) + updatecoeffsH[materialHz, 2] * (Ex[i, j + 1, k + 1] - Ex[i, j, k + 1])
|
|
@@ -0,0 +1,514 @@
|
|||||||
|
# Copyright (C) 2015-2019: The University of Edinburgh
|
||||||
|
# Authors: Craig Warren and Antonis Giannopoulos
|
||||||
|
#
|
||||||
|
# This file is part of gprMax.
|
||||||
|
#
|
||||||
|
# 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
cimport numpy as np
|
||||||
|
from cython.parallel import prange
|
||||||
|
|
||||||
|
from gprMax.config cimport float_or_double
|
||||||
|
from gprMax.config cimport real_or_complex
|
||||||
|
|
||||||
|
cdef double mycreal(double complex dc) nogil:
|
||||||
|
cdef double complex* dcptr = &dc
|
||||||
|
return (<double *>dcptr)[0]
|
||||||
|
|
||||||
|
|
||||||
|
#########################################################
|
||||||
|
# Electric field updates - dispersive materials - Debye #
|
||||||
|
#########################################################
|
||||||
|
cpdef void update_electric_dispersive_debye_multipole_A(
|
||||||
|
int nx,
|
||||||
|
int ny,
|
||||||
|
int nz,
|
||||||
|
int nthreads,
|
||||||
|
int maxpoles,
|
||||||
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
|
float_or_double[:, ::1] updatecoeffsdispersive,
|
||||||
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
|
float_or_double[:, :, :, ::1] Tx,
|
||||||
|
float_or_double[:, :, :, ::1] Ty,
|
||||||
|
float_or_double[:, :, :, ::1] Tz,
|
||||||
|
float_or_double[:, :, ::1] Ex,
|
||||||
|
float_or_double[:, :, ::1] Ey,
|
||||||
|
float_or_double[:, :, ::1] Ez,
|
||||||
|
float_or_double[:, :, ::1] Hx,
|
||||||
|
float_or_double[:, :, ::1] Hy,
|
||||||
|
float_or_double[:, :, ::1] Hz
|
||||||
|
):
|
||||||
|
"""This function updates the electric field components when dispersive materials (with multiple poles) are present.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
nx, ny, nz (int): Grid size in cells
|
||||||
|
nthreads (int): Number of threads to use
|
||||||
|
maxpoles (int): Maximum number of poles
|
||||||
|
updatecoeffs, T, ID, E, H (memoryviews): Access to update coeffients, temporary, ID and field component arrays
|
||||||
|
"""
|
||||||
|
|
||||||
|
cdef Py_ssize_t i, j, k, pole
|
||||||
|
cdef int material
|
||||||
|
cdef float phi = 0
|
||||||
|
|
||||||
|
# Ex component
|
||||||
|
if ny != 1 or nz != 1:
|
||||||
|
for i in prange(0, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(1, ny):
|
||||||
|
for k in range(1, nz):
|
||||||
|
material = ID[0, i, j, k]
|
||||||
|
phi = 0
|
||||||
|
for pole in range(maxpoles):
|
||||||
|
phi = phi + updatecoeffsdispersive[material, pole * 3] * Tx[pole, i, j, k]
|
||||||
|
Tx[pole, i, j, k] = updatecoeffsdispersive[material, 1 + (pole * 3)] * Tx[pole, i, j, k] + updatecoeffsdispersive[material, 2 + (pole * 3)] * Ex[i, j, k]
|
||||||
|
Ex[i, j, k] = updatecoeffsE[material, 0] * Ex[i, j, k] + updatecoeffsE[material, 2] * (Hz[i, j, k] - Hz[i, j - 1, k]) - updatecoeffsE[material, 3] * (Hy[i, j, k] - Hy[i, j, k - 1]) - updatecoeffsE[material, 4] * phi
|
||||||
|
|
||||||
|
# Ey component
|
||||||
|
if nx != 1 or nz != 1:
|
||||||
|
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(0, ny):
|
||||||
|
for k in range(1, nz):
|
||||||
|
material = ID[1, i, j, k]
|
||||||
|
phi = 0
|
||||||
|
for pole in range(maxpoles):
|
||||||
|
phi = phi + updatecoeffsdispersive[material, pole * 3] * Ty[pole, i, j, k]
|
||||||
|
Ty[pole, i, j, k] = updatecoeffsdispersive[material, 1 + (pole * 3)] * Ty[pole, i, j, k] + updatecoeffsdispersive[material, 2 + (pole * 3)] * Ey[i, j, k]
|
||||||
|
Ey[i, j, k] = updatecoeffsE[material, 0] * Ey[i, j, k] + updatecoeffsE[material, 3] * (Hx[i, j, k] - Hx[i, j, k - 1]) - updatecoeffsE[material, 1] * (Hz[i, j, k] - Hz[i - 1, j, k]) - updatecoeffsE[material, 4] * phi
|
||||||
|
|
||||||
|
# Ez component
|
||||||
|
if nx != 1 or ny != 1:
|
||||||
|
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(1, ny):
|
||||||
|
for k in range(0, nz):
|
||||||
|
material = ID[2, i, j, k]
|
||||||
|
phi = 0
|
||||||
|
for pole in range(maxpoles):
|
||||||
|
phi = phi + updatecoeffsdispersive[material, pole * 3] * Tz[pole, i, j, k]
|
||||||
|
Tz[pole, i, j, k] = updatecoeffsdispersive[material, 1 + (pole * 3)] * Tz[pole, i, j, k] + updatecoeffsdispersive[material, 2 + (pole * 3)] * Ez[i, j, k]
|
||||||
|
Ez[i, j, k] = updatecoeffsE[material, 0] * Ez[i, j, k] + updatecoeffsE[material, 1] * (Hy[i, j, k] - Hy[i - 1, j, k]) - updatecoeffsE[material, 2] * (Hx[i, j, k] - Hx[i, j - 1, k]) - updatecoeffsE[material, 4] * phi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cpdef void update_electric_dispersive_debye_multipole_B(
|
||||||
|
int nx,
|
||||||
|
int ny,
|
||||||
|
int nz,
|
||||||
|
int nthreads,
|
||||||
|
int maxpoles,
|
||||||
|
float_or_double[:, ::1] updatecoeffsdispersive,
|
||||||
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
|
float_or_double[:, :, :, ::1] Tx,
|
||||||
|
float_or_double[:, :, :, ::1] Ty,
|
||||||
|
float_or_double[:, :, :, ::1] Tz,
|
||||||
|
float_or_double[:, :, ::1] Ex,
|
||||||
|
float_or_double[:, :, ::1] Ey,
|
||||||
|
float_or_double[:, :, ::1] Ez
|
||||||
|
):
|
||||||
|
"""This function updates a temporary dispersive material array when disperisive materials (with multiple poles) are present.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
nx, ny, nz (int): Grid size in cells
|
||||||
|
nthreads (int): Number of threads to use
|
||||||
|
maxpoles (int): Maximum number of poles
|
||||||
|
updatecoeffs, T, ID, E (memoryviews): Access to update coeffients, temporary, ID and field component arrays
|
||||||
|
"""
|
||||||
|
|
||||||
|
cdef Py_ssize_t i, j, k, pole
|
||||||
|
cdef int material
|
||||||
|
|
||||||
|
# Ex component
|
||||||
|
if ny != 1 or nz != 1:
|
||||||
|
for i in prange(0, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(1, ny):
|
||||||
|
for k in range(1, nz):
|
||||||
|
material = ID[0, i, j, k]
|
||||||
|
for pole in range(maxpoles):
|
||||||
|
Tx[pole, i, j, k] = Tx[pole, i, j, k] - updatecoeffsdispersive[material, 2 + (pole * 3)] * Ex[i, j, k]
|
||||||
|
|
||||||
|
# Ey component
|
||||||
|
if nx != 1 or nz != 1:
|
||||||
|
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(0, ny):
|
||||||
|
for k in range(1, nz):
|
||||||
|
material = ID[1, i, j, k]
|
||||||
|
for pole in range(maxpoles):
|
||||||
|
Ty[pole, i, j, k] = Ty[pole, i, j, k] - updatecoeffsdispersive[material, 2 + (pole * 3)] * Ey[i, j, k]
|
||||||
|
|
||||||
|
# Ez component
|
||||||
|
if nx != 1 or ny != 1:
|
||||||
|
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(1, ny):
|
||||||
|
for k in range(0, nz):
|
||||||
|
material = ID[2, i, j, k]
|
||||||
|
for pole in range(maxpoles):
|
||||||
|
Tz[pole, i, j, k] = Tz[pole, i, j, k] - updatecoeffsdispersive[material, 2 + (pole * 3)] * Ez[i, j, k]
|
||||||
|
|
||||||
|
|
||||||
|
cpdef void update_electric_dispersive_debye_1pole_A(
|
||||||
|
int nx,
|
||||||
|
int ny,
|
||||||
|
int nz,
|
||||||
|
int nthreads,
|
||||||
|
int maxpoles,
|
||||||
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
|
float_or_double[:, ::1] updatecoeffsdispersive,
|
||||||
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
|
float_or_double[:, :, :, ::1] Tx,
|
||||||
|
float_or_double[:, :, :, ::1] Ty,
|
||||||
|
float_or_double[:, :, :, ::1] Tz,
|
||||||
|
float_or_double[:, :, ::1] Ex,
|
||||||
|
float_or_double[:, :, ::1] Ey,
|
||||||
|
float_or_double[:, :, ::1] Ez,
|
||||||
|
float_or_double[:, :, ::1] Hx,
|
||||||
|
float_or_double[:, :, ::1] Hy,
|
||||||
|
float_or_double[:, :, ::1] Hz
|
||||||
|
):
|
||||||
|
"""This function updates the electric field components when dispersive materials (with 1 pole) are present.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
nx, ny, nz (int): Grid size in cells
|
||||||
|
nthreads (int): Number of threads to use
|
||||||
|
maxpoles (int): Maximum number of poles
|
||||||
|
updatecoeffs, T, ID, E, H (memoryviews): Access to update coeffients, temporary, ID and field component arrays
|
||||||
|
"""
|
||||||
|
|
||||||
|
cdef Py_ssize_t i, j, k
|
||||||
|
cdef int material
|
||||||
|
cdef float phi = 0
|
||||||
|
|
||||||
|
# Ex component
|
||||||
|
if ny != 1 or nz != 1:
|
||||||
|
for i in prange(0, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(1, ny):
|
||||||
|
for k in range(1, nz):
|
||||||
|
material = ID[0, i, j, k]
|
||||||
|
phi = updatecoeffsdispersive[material, 0] * Tx[0, i, j, k]
|
||||||
|
Tx[0, i, j, k] = updatecoeffsdispersive[material, 1] * Tx[0, i, j, k] + updatecoeffsdispersive[material, 2] * Ex[i, j, k]
|
||||||
|
Ex[i, j, k] = updatecoeffsE[material, 0] * Ex[i, j, k] + updatecoeffsE[material, 2] * (Hz[i, j, k] - Hz[i, j - 1, k]) - updatecoeffsE[material, 3] * (Hy[i, j, k] - Hy[i, j, k - 1]) - updatecoeffsE[material, 4] * phi
|
||||||
|
|
||||||
|
# Ey component
|
||||||
|
if nx != 1 or nz != 1:
|
||||||
|
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(0, ny):
|
||||||
|
for k in range(1, nz):
|
||||||
|
material = ID[1, i, j, k]
|
||||||
|
phi = updatecoeffsdispersive[material, 0] * Ty[0, i, j, k]
|
||||||
|
Ty[0, i, j, k] = updatecoeffsdispersive[material, 1] * Ty[0, i, j, k] + updatecoeffsdispersive[material, 2] * Ey[i, j, k]
|
||||||
|
Ey[i, j, k] = updatecoeffsE[material, 0] * Ey[i, j, k] + updatecoeffsE[material, 3] * (Hx[i, j, k] - Hx[i, j, k - 1]) - updatecoeffsE[material, 1] * (Hz[i, j, k] - Hz[i - 1, j, k]) - updatecoeffsE[material, 4] * phi
|
||||||
|
|
||||||
|
# Ez component
|
||||||
|
if nx != 1 or ny != 1:
|
||||||
|
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(1, ny):
|
||||||
|
for k in range(0, nz):
|
||||||
|
material = ID[2, i, j, k]
|
||||||
|
phi = updatecoeffsdispersive[material, 0] * Tz[0, i, j, k]
|
||||||
|
Tz[0, i, j, k] = updatecoeffsdispersive[material, 1] * Tz[0, i, j, k] + updatecoeffsdispersive[material, 2] * Ez[i, j, k]
|
||||||
|
Ez[i, j, k] = updatecoeffsE[material, 0] * Ez[i, j, k] + updatecoeffsE[material, 1] * (Hy[i, j, k] - Hy[i - 1, j, k]) - updatecoeffsE[material, 2] * (Hx[i, j, k] - Hx[i, j - 1, k]) - updatecoeffsE[material, 4] * phi
|
||||||
|
|
||||||
|
|
||||||
|
cpdef void update_electric_dispersive_debye_1pole_B(
|
||||||
|
int nx,
|
||||||
|
int ny,
|
||||||
|
int nz,
|
||||||
|
int nthreads,
|
||||||
|
int maxpoles,
|
||||||
|
float_or_double[:, ::1] updatecoeffsdispersive,
|
||||||
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
|
float_or_double[:, :, :, ::1] Tx,
|
||||||
|
float_or_double[:, :, :, ::1] Ty,
|
||||||
|
float_or_double[:, :, :, ::1] Tz,
|
||||||
|
float_or_double[:, :, ::1] Ex,
|
||||||
|
float_or_double[:, :, ::1] Ey,
|
||||||
|
float_or_double[:, :, ::1] Ez
|
||||||
|
):
|
||||||
|
"""This function updates a temporary dispersive material array when disperisive materials (with 1 pole) are present.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
nx, ny, nz (int): Grid size in cells
|
||||||
|
nthreads (int): Number of threads to use
|
||||||
|
maxpoles (int): Maximum number of poles
|
||||||
|
updatecoeffs, T, ID, E (memoryviews): Access to update coeffients, temporary, ID and field component arrays
|
||||||
|
"""
|
||||||
|
|
||||||
|
cdef Py_ssize_t i, j, k
|
||||||
|
cdef int material
|
||||||
|
|
||||||
|
# Ex component
|
||||||
|
if ny != 1 or nz != 1:
|
||||||
|
for i in prange(0, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(1, ny):
|
||||||
|
for k in range(1, nz):
|
||||||
|
material = ID[0, i, j, k]
|
||||||
|
Tx[0, i, j, k] = Tx[0, i, j, k] - updatecoeffsdispersive[material, 2] * Ex[i, j, k]
|
||||||
|
|
||||||
|
# Ey component
|
||||||
|
if nx != 1 or nz != 1:
|
||||||
|
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(0, ny):
|
||||||
|
for k in range(1, nz):
|
||||||
|
material = ID[1, i, j, k]
|
||||||
|
Ty[0, i, j, k] = Ty[0, i, j, k] - updatecoeffsdispersive[material, 2] * Ey[i, j, k]
|
||||||
|
|
||||||
|
# Ez component
|
||||||
|
if nx != 1 or ny != 1:
|
||||||
|
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(1, ny):
|
||||||
|
for k in range(0, nz):
|
||||||
|
material = ID[2, i, j, k]
|
||||||
|
Tz[0, i, j, k] = Tz[0, i, j, k] - updatecoeffsdispersive[material, 2] * Ez[i, j, k]
|
||||||
|
|
||||||
|
|
||||||
|
#################################################################
|
||||||
|
# Electric field updates - dispersive materials - Drude, Lorenz #
|
||||||
|
#################################################################
|
||||||
|
cpdef void update_electric_dispersive_multipole_A(
|
||||||
|
int nx,
|
||||||
|
int ny,
|
||||||
|
int nz,
|
||||||
|
int nthreads,
|
||||||
|
int maxpoles,
|
||||||
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
|
real_or_complex[:, ::1] updatecoeffsdispersive,
|
||||||
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
|
real_or_complex[:, :, :, ::1] Tx,
|
||||||
|
real_or_complex[:, :, :, ::1] Ty,
|
||||||
|
real_or_complex[:, :, :, ::1] Tz,
|
||||||
|
float_or_double[:, :, ::1] Ex,
|
||||||
|
float_or_double[:, :, ::1] Ey,
|
||||||
|
float_or_double[:, :, ::1] Ez,
|
||||||
|
float_or_double[:, :, ::1] Hx,
|
||||||
|
float_or_double[:, :, ::1] Hy,
|
||||||
|
float_or_double[:, :, ::1] Hz
|
||||||
|
):
|
||||||
|
"""This function updates the electric field components when dispersive materials (with multiple poles) are present.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
nx, ny, nz (int): Grid size in cells
|
||||||
|
nthreads (int): Number of threads to use
|
||||||
|
maxpoles (int): Maximum number of poles
|
||||||
|
updatecoeffs, T, ID, E, H (memoryviews): Access to update coeffients, temporary, ID and field component arrays
|
||||||
|
"""
|
||||||
|
|
||||||
|
cdef Py_ssize_t i, j, k, pole
|
||||||
|
cdef int material
|
||||||
|
cdef float phi
|
||||||
|
|
||||||
|
# Ex component
|
||||||
|
if ny != 1 or nz != 1:
|
||||||
|
for i in prange(0, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(1, ny):
|
||||||
|
for k in range(1, nz):
|
||||||
|
material = ID[0, i, j, k]
|
||||||
|
phi = 0
|
||||||
|
for pole in range(maxpoles):
|
||||||
|
phi = phi + mycreal(updatecoeffsdispersive[material, pole * 3]) * mycreal(Tx[pole, i, j, k])
|
||||||
|
Tx[pole, i, j, k] = updatecoeffsdispersive[material, 1 + (pole * 3)] * Tx[pole, i, j, k] + updatecoeffsdispersive[material, 2 + (pole * 3)] * Ex[i, j, k]
|
||||||
|
Ex[i, j, k] = updatecoeffsE[material, 0] * Ex[i, j, k] + updatecoeffsE[material, 2] * (Hz[i, j, k] - Hz[i, j - 1, k]) - updatecoeffsE[material, 3] * (Hy[i, j, k] - Hy[i, j, k - 1]) - updatecoeffsE[material, 4] * phi
|
||||||
|
|
||||||
|
# Ey component
|
||||||
|
if nx != 1 or nz != 1:
|
||||||
|
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(0, ny):
|
||||||
|
for k in range(1, nz):
|
||||||
|
material = ID[1, i, j, k]
|
||||||
|
phi = 0
|
||||||
|
for pole in range(maxpoles):
|
||||||
|
phi = phi + mycreal(updatecoeffsdispersive[material, pole * 3]) * mycreal(Ty[pole, i, j, k])
|
||||||
|
Ty[pole, i, j, k] = updatecoeffsdispersive[material, 1 + (pole * 3)] * Ty[pole, i, j, k] + updatecoeffsdispersive[material, 2 + (pole * 3)] * Ey[i, j, k]
|
||||||
|
Ey[i, j, k] = updatecoeffsE[material, 0] * Ey[i, j, k] + updatecoeffsE[material, 3] * (Hx[i, j, k] - Hx[i, j, k - 1]) - updatecoeffsE[material, 1] * (Hz[i, j, k] - Hz[i - 1, j, k]) - updatecoeffsE[material, 4] * phi
|
||||||
|
|
||||||
|
# Ez component
|
||||||
|
if nx != 1 or ny != 1:
|
||||||
|
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(1, ny):
|
||||||
|
for k in range(0, nz):
|
||||||
|
material = ID[2, i, j, k]
|
||||||
|
phi = 0
|
||||||
|
for pole in range(maxpoles):
|
||||||
|
phi = phi + mycreal(updatecoeffsdispersive[material, pole * 3]) * mycreal(Tz[pole, i, j, k])
|
||||||
|
Tz[pole, i, j, k] = updatecoeffsdispersive[material, 1 + (pole * 3)] * Tz[pole, i, j, k] + updatecoeffsdispersive[material, 2 + (pole * 3)] * Ez[i, j, k]
|
||||||
|
Ez[i, j, k] = updatecoeffsE[material, 0] * Ez[i, j, k] + updatecoeffsE[material, 1] * (Hy[i, j, k] - Hy[i - 1, j, k]) - updatecoeffsE[material, 2] * (Hx[i, j, k] - Hx[i, j - 1, k]) - updatecoeffsE[material, 4] * phi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cpdef void update_electric_dispersive_multipole_B(
|
||||||
|
int nx,
|
||||||
|
int ny,
|
||||||
|
int nz,
|
||||||
|
int nthreads,
|
||||||
|
int maxpoles,
|
||||||
|
real_or_complex[:, ::1] updatecoeffsdispersive,
|
||||||
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
|
real_or_complex[:, :, :, ::1] Tx,
|
||||||
|
real_or_complex[:, :, :, ::1] Ty,
|
||||||
|
real_or_complex[:, :, :, ::1] Tz,
|
||||||
|
float_or_double[:, :, ::1] Ex,
|
||||||
|
float_or_double[:, :, ::1] Ey,
|
||||||
|
float_or_double[:, :, ::1] Ez
|
||||||
|
):
|
||||||
|
"""This function updates a temporary dispersive material array when disperisive materials (with multiple poles) are present.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
nx, ny, nz (int): Grid size in cells
|
||||||
|
nthreads (int): Number of threads to use
|
||||||
|
maxpoles (int): Maximum number of poles
|
||||||
|
updatecoeffs, T, ID, E (memoryviews): Access to update coeffients, temporary, ID and field component arrays
|
||||||
|
"""
|
||||||
|
|
||||||
|
cdef Py_ssize_t i, j, k, pole
|
||||||
|
cdef int material
|
||||||
|
|
||||||
|
# Ex component
|
||||||
|
if ny != 1 or nz != 1:
|
||||||
|
for i in prange(0, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(1, ny):
|
||||||
|
for k in range(1, nz):
|
||||||
|
material = ID[0, i, j, k]
|
||||||
|
for pole in range(maxpoles):
|
||||||
|
Tx[pole, i, j, k] = Tx[pole, i, j, k] - updatecoeffsdispersive[material, 2 + (pole * 3)] * Ex[i, j, k]
|
||||||
|
|
||||||
|
# Ey component
|
||||||
|
if nx != 1 or nz != 1:
|
||||||
|
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(0, ny):
|
||||||
|
for k in range(1, nz):
|
||||||
|
material = ID[1, i, j, k]
|
||||||
|
for pole in range(maxpoles):
|
||||||
|
Ty[pole, i, j, k] = Ty[pole, i, j, k] - updatecoeffsdispersive[material, 2 + (pole * 3)] * Ey[i, j, k]
|
||||||
|
|
||||||
|
# Ez component
|
||||||
|
if nx != 1 or ny != 1:
|
||||||
|
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(1, ny):
|
||||||
|
for k in range(0, nz):
|
||||||
|
material = ID[2, i, j, k]
|
||||||
|
for pole in range(maxpoles):
|
||||||
|
Tz[pole, i, j, k] = Tz[pole, i, j, k] - updatecoeffsdispersive[material, 2 + (pole * 3)] * Ez[i, j, k]
|
||||||
|
|
||||||
|
|
||||||
|
cpdef void update_electric_dispersive_1pole_A(
|
||||||
|
int nx,
|
||||||
|
int ny,
|
||||||
|
int nz,
|
||||||
|
int nthreads,
|
||||||
|
int maxpoles,
|
||||||
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
|
real_or_complex[:, ::1] updatecoeffsdispersive,
|
||||||
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
|
real_or_complex[:, :, :, ::1] Tx,
|
||||||
|
real_or_complex[:, :, :, ::1] Ty,
|
||||||
|
real_or_complex[:, :, :, ::1] Tz,
|
||||||
|
float_or_double[:, :, ::1] Ex,
|
||||||
|
float_or_double[:, :, ::1] Ey,
|
||||||
|
float_or_double[:, :, ::1] Ez,
|
||||||
|
float_or_double[:, :, ::1] Hx,
|
||||||
|
float_or_double[:, :, ::1] Hy,
|
||||||
|
float_or_double[:, :, ::1] Hz
|
||||||
|
):
|
||||||
|
"""This function updates the electric field components when dispersive materials (with 1 pole) are present.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
nx, ny, nz (int): Grid size in cells
|
||||||
|
nthreads (int): Number of threads to use
|
||||||
|
maxpoles (int): Maximum number of poles
|
||||||
|
updatecoeffs, T, ID, E, H (memoryviews): Access to update coeffients, temporary, ID and field component arrays
|
||||||
|
"""
|
||||||
|
|
||||||
|
cdef Py_ssize_t i, j, k
|
||||||
|
cdef int material
|
||||||
|
cdef float phi = 0
|
||||||
|
|
||||||
|
# Ex component
|
||||||
|
if ny != 1 or nz != 1:
|
||||||
|
for i in prange(0, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(1, ny):
|
||||||
|
for k in range(1, nz):
|
||||||
|
material = ID[0, i, j, k]
|
||||||
|
phi = mycreal(updatecoeffsdispersive[material, 0]) * mycreal(Tx[0, i, j, k])
|
||||||
|
Tx[0, i, j, k] = updatecoeffsdispersive[material, 1] * Tx[0, i, j, k] + updatecoeffsdispersive[material, 2] * Ex[i, j, k]
|
||||||
|
Ex[i, j, k] = updatecoeffsE[material, 0] * Ex[i, j, k] + updatecoeffsE[material, 2] * (Hz[i, j, k] - Hz[i, j - 1, k]) - updatecoeffsE[material, 3] * (Hy[i, j, k] - Hy[i, j, k - 1]) - updatecoeffsE[material, 4] * phi
|
||||||
|
|
||||||
|
# Ey component
|
||||||
|
if nx != 1 or nz != 1:
|
||||||
|
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(0, ny):
|
||||||
|
for k in range(1, nz):
|
||||||
|
material = ID[1, i, j, k]
|
||||||
|
phi = mycreal(updatecoeffsdispersive[material, 0]) * mycreal(Ty[0, i, j, k])
|
||||||
|
Ty[0, i, j, k] = updatecoeffsdispersive[material, 1] * Ty[0, i, j, k] + updatecoeffsdispersive[material, 2] * Ey[i, j, k]
|
||||||
|
Ey[i, j, k] = updatecoeffsE[material, 0] * Ey[i, j, k] + updatecoeffsE[material, 3] * (Hx[i, j, k] - Hx[i, j, k - 1]) - updatecoeffsE[material, 1] * (Hz[i, j, k] - Hz[i - 1, j, k]) - updatecoeffsE[material, 4] * phi
|
||||||
|
|
||||||
|
# Ez component
|
||||||
|
if nx != 1 or ny != 1:
|
||||||
|
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(1, ny):
|
||||||
|
for k in range(0, nz):
|
||||||
|
material = ID[2, i, j, k]
|
||||||
|
phi = mycreal(updatecoeffsdispersive[material, 0]) * mycreal(Tz[0, i, j, k])
|
||||||
|
Tz[0, i, j, k] = updatecoeffsdispersive[material, 1] * Tz[0, i, j, k] + updatecoeffsdispersive[material, 2] * Ez[i, j, k]
|
||||||
|
Ez[i, j, k] = updatecoeffsE[material, 0] * Ez[i, j, k] + updatecoeffsE[material, 1] * (Hy[i, j, k] - Hy[i - 1, j, k]) - updatecoeffsE[material, 2] * (Hx[i, j, k] - Hx[i, j - 1, k]) - updatecoeffsE[material, 4] * phi
|
||||||
|
|
||||||
|
|
||||||
|
cpdef void update_electric_dispersive_1pole_B(
|
||||||
|
int nx,
|
||||||
|
int ny,
|
||||||
|
int nz,
|
||||||
|
int nthreads,
|
||||||
|
int maxpoles,
|
||||||
|
real_or_complex[:, ::1] updatecoeffsdispersive,
|
||||||
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
|
real_or_complex[:, :, :, ::1] Tx,
|
||||||
|
real_or_complex[:, :, :, ::1] Ty,
|
||||||
|
real_or_complex[:, :, :, ::1] Tz,
|
||||||
|
float_or_double[:, :, ::1] Ex,
|
||||||
|
float_or_double[:, :, ::1] Ey,
|
||||||
|
float_or_double[:, :, ::1] Ez
|
||||||
|
):
|
||||||
|
"""This function updates a temporary dispersive material array when disperisive materials (with 1 pole) are present.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
nx, ny, nz (int): Grid size in cells
|
||||||
|
nthreads (int): Number of threads to use
|
||||||
|
maxpoles (int): Maximum number of poles
|
||||||
|
updatecoeffs, T, ID, E (memoryviews): Access to update coeffients, temporary, ID and field component arrays
|
||||||
|
"""
|
||||||
|
|
||||||
|
cdef Py_ssize_t i, j, k
|
||||||
|
cdef int material
|
||||||
|
|
||||||
|
# Ex component
|
||||||
|
if ny != 1 or nz != 1:
|
||||||
|
for i in prange(0, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(1, ny):
|
||||||
|
for k in range(1, nz):
|
||||||
|
material = ID[0, i, j, k]
|
||||||
|
Tx[0, i, j, k] = Tx[0, i, j, k] - updatecoeffsdispersive[material, 2] * Ex[i, j, k]
|
||||||
|
|
||||||
|
# Ey component
|
||||||
|
if nx != 1 or nz != 1:
|
||||||
|
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(0, ny):
|
||||||
|
for k in range(1, nz):
|
||||||
|
material = ID[1, i, j, k]
|
||||||
|
Ty[0, i, j, k] = Ty[0, i, j, k] - updatecoeffsdispersive[material, 2] * Ey[i, j, k]
|
||||||
|
|
||||||
|
# Ez component
|
||||||
|
if nx != 1 or ny != 1:
|
||||||
|
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(1, ny):
|
||||||
|
for k in range(0, nz):
|
||||||
|
material = ID[2, i, j, k]
|
||||||
|
Tz[0, i, j, k] = Tz[0, i, j, k] - updatecoeffsdispersive[material, 2] * Ez[i, j, k]
|
@@ -0,0 +1,172 @@
|
|||||||
|
cdef float phi# Copyright (C) 2015-2019: The University of Edinburgh
|
||||||
|
# Authors: Craig Warren and Antonis Giannopoulos
|
||||||
|
#
|
||||||
|
# This file is part of gprMax.
|
||||||
|
#
|
||||||
|
# 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
cimport numpy as np
|
||||||
|
from cython.parallel import prange
|
||||||
|
|
||||||
|
from gprMax.config cimport float_or_double
|
||||||
|
|
||||||
|
|
||||||
|
###############################################
|
||||||
|
# Electric field updates - standard materials #
|
||||||
|
###############################################
|
||||||
|
cpdef void update_electric(
|
||||||
|
int nx,
|
||||||
|
int ny,
|
||||||
|
int nz,
|
||||||
|
int nthreads,
|
||||||
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
|
float_or_double[:, :, ::1] Ex,
|
||||||
|
float_or_double[:, :, ::1] Ey,
|
||||||
|
float_or_double[:, :, ::1] Ez,
|
||||||
|
float_or_double[:, :, ::1] Hx,
|
||||||
|
float_or_double[:, :, ::1] Hy,
|
||||||
|
float_or_double[:, :, ::1] Hz
|
||||||
|
):
|
||||||
|
"""This function updates the electric field components.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
nx, ny, nz (int): Grid size in cells
|
||||||
|
nthreads (int): Number of threads to use
|
||||||
|
updatecoeffs, ID, E, H (memoryviews): Access to update coeffients, ID and field component arrays
|
||||||
|
"""
|
||||||
|
|
||||||
|
cdef Py_ssize_t i, j, k
|
||||||
|
cdef int materialEx, materialEy, materialEz
|
||||||
|
|
||||||
|
# 2D - Ex component
|
||||||
|
if nx == 1:
|
||||||
|
for i in prange(0, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(1, ny):
|
||||||
|
for k in range(1, nz):
|
||||||
|
materialEx = ID[0, i, j, k]
|
||||||
|
Ex[i, j, k] = updatecoeffsE[materialEx, 0] * Ex[i, j, k] + updatecoeffsE[materialEx, 2] * (Hz[i, j, k] - Hz[i, j - 1, k]) - updatecoeffsE[materialEx, 3] * (Hy[i, j, k] - Hy[i, j, k - 1])
|
||||||
|
|
||||||
|
# 2D - Ey component
|
||||||
|
elif ny == 1:
|
||||||
|
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(0, ny):
|
||||||
|
for k in range(1, nz):
|
||||||
|
materialEy = ID[1, i, j, k]
|
||||||
|
Ey[i, j, k] = updatecoeffsE[materialEy, 0] * Ey[i, j, k] + updatecoeffsE[materialEy, 3] * (Hx[i, j, k] - Hx[i, j, k - 1]) - updatecoeffsE[materialEy, 1] * (Hz[i, j, k] - Hz[i - 1, j, k])
|
||||||
|
|
||||||
|
# 2D - Ez component
|
||||||
|
elif nz == 1:
|
||||||
|
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(1, ny):
|
||||||
|
for k in range(0, nz):
|
||||||
|
materialEz = ID[2, i, j, k]
|
||||||
|
Ez[i, j, k] = updatecoeffsE[materialEz, 0] * Ez[i, j, k] + updatecoeffsE[materialEz, 1] * (Hy[i, j, k] - Hy[i - 1, j, k]) - updatecoeffsE[materialEz, 2] * (Hx[i, j, k] - Hx[i, j - 1, k])
|
||||||
|
|
||||||
|
# 3D
|
||||||
|
else:
|
||||||
|
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(1, ny):
|
||||||
|
for k in range(1, nz):
|
||||||
|
materialEx = ID[0, i, j, k]
|
||||||
|
materialEy = ID[1, i, j, k]
|
||||||
|
materialEz = ID[2, i, j, k]
|
||||||
|
Ex[i, j, k] = updatecoeffsE[materialEx, 0] * Ex[i, j, k] + updatecoeffsE[materialEx, 2] * (Hz[i, j, k] - Hz[i, j - 1, k]) - updatecoeffsE[materialEx, 3] * (Hy[i, j, k] - Hy[i, j, k - 1])
|
||||||
|
Ey[i, j, k] = updatecoeffsE[materialEy, 0] * Ey[i, j, k] + updatecoeffsE[materialEy, 3] * (Hx[i, j, k] - Hx[i, j, k - 1]) - updatecoeffsE[materialEy, 1] * (Hz[i, j, k] - Hz[i - 1, j, k])
|
||||||
|
Ez[i, j, k] = updatecoeffsE[materialEz, 0] * Ez[i, j, k] + updatecoeffsE[materialEz, 1] * (Hy[i, j, k] - Hy[i - 1, j, k]) - updatecoeffsE[materialEz, 2] * (Hx[i, j, k] - Hx[i, j - 1, k])
|
||||||
|
|
||||||
|
# Ex components at i = 0
|
||||||
|
for j in prange(1, ny, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for k in range(1, nz):
|
||||||
|
materialEx = ID[0, 0, j, k]
|
||||||
|
Ex[0, j, k] = updatecoeffsE[materialEx, 0] * Ex[0, j, k] + updatecoeffsE[materialEx, 2] * (Hz[0, j, k] - Hz[0, j - 1, k]) - updatecoeffsE[materialEx, 3] * (Hy[0, j, k] - Hy[0, j, k - 1])
|
||||||
|
|
||||||
|
# Ey components at j = 0
|
||||||
|
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for k in range(1, nz):
|
||||||
|
materialEy = ID[1, i, 0, k]
|
||||||
|
Ey[i, 0, k] = updatecoeffsE[materialEy, 0] * Ey[i, 0, k] + updatecoeffsE[materialEy, 3] * (Hx[i, 0, k] - Hx[i, 0, k - 1]) - updatecoeffsE[materialEy, 1] * (Hz[i, 0, k] - Hz[i - 1, 0, k])
|
||||||
|
|
||||||
|
# Ez components at k = 0
|
||||||
|
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(1, ny):
|
||||||
|
materialEz = ID[2, i, j, 0]
|
||||||
|
Ez[i, j, 0] = updatecoeffsE[materialEz, 0] * Ez[i, j, 0] + updatecoeffsE[materialEz, 1] * (Hy[i, j, 0] - Hy[i - 1, j, 0]) - updatecoeffsE[materialEz, 2] * (Hx[i, j, 0] - Hx[i, j - 1, 0])
|
||||||
|
|
||||||
|
|
||||||
|
##########################
|
||||||
|
# Magnetic field updates #
|
||||||
|
##########################
|
||||||
|
cpdef void update_magnetic(
|
||||||
|
int nx,
|
||||||
|
int ny,
|
||||||
|
int nz,
|
||||||
|
int nthreads,
|
||||||
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
|
float_or_double[:, :, ::1] Ex,
|
||||||
|
float_or_double[:, :, ::1] Ey,
|
||||||
|
float_or_double[:, :, ::1] Ez,
|
||||||
|
float_or_double[:, :, ::1] Hx,
|
||||||
|
float_or_double[:, :, ::1] Hy,
|
||||||
|
float_or_double[:, :, ::1] Hz
|
||||||
|
):
|
||||||
|
"""This function updates the magnetic field components.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
nx, ny, nz (int): Grid size in cells
|
||||||
|
nthreads (int): Number of threads to use
|
||||||
|
updatecoeffs, ID, E, H (memoryviews): Access to update coeffients, ID and field component arrays
|
||||||
|
"""
|
||||||
|
|
||||||
|
cdef Py_ssize_t i, j, k
|
||||||
|
cdef int materialHx, materialHy, materialHz
|
||||||
|
|
||||||
|
# 2D
|
||||||
|
if nx == 1 or ny == 1 or nz == 1:
|
||||||
|
# Hx component
|
||||||
|
if ny == 1 or nz == 1:
|
||||||
|
for i in prange(1, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(0, ny):
|
||||||
|
for k in range(0, nz):
|
||||||
|
materialHx = ID[3, i, j, k]
|
||||||
|
Hx[i, j, k] = updatecoeffsH[materialHx, 0] * Hx[i, j, k] - updatecoeffsH[materialHx, 2] * (Ez[i, j + 1, k] - Ez[i, j, k]) + updatecoeffsH[materialHx, 3] * (Ey[i, j, k + 1] - Ey[i, j, k])
|
||||||
|
|
||||||
|
# Hy component
|
||||||
|
if nx == 1 or nz == 1:
|
||||||
|
for i in prange(0, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(1, ny):
|
||||||
|
for k in range(0, nz):
|
||||||
|
materialHy = ID[4, i, j, k]
|
||||||
|
Hy[i, j, k] = updatecoeffsH[materialHy, 0] * Hy[i, j, k] - updatecoeffsH[materialHy, 3] * (Ex[i, j, k + 1] - Ex[i, j, k]) + updatecoeffsH[materialHy, 1] * (Ez[i + 1, j, k] - Ez[i, j, k])
|
||||||
|
|
||||||
|
# Hz component
|
||||||
|
if nx == 1 or ny == 1:
|
||||||
|
for i in prange(0, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(0, ny):
|
||||||
|
for k in range(1, nz):
|
||||||
|
materialHz = ID[5, i, j, k]
|
||||||
|
Hz[i, j, k] = updatecoeffsH[materialHz, 0] * Hz[i, j, k] - updatecoeffsH[materialHz, 1] * (Ey[i + 1, j, k] - Ey[i, j, k]) + updatecoeffsH[materialHz, 2] * (Ex[i, j + 1, k] - Ex[i, j, k])
|
||||||
|
# 3D
|
||||||
|
else:
|
||||||
|
for i in prange(0, nx, nogil=True, schedule='static', num_threads=nthreads):
|
||||||
|
for j in range(0, ny):
|
||||||
|
for k in range(0, nz):
|
||||||
|
materialHx = ID[3, i + 1, j, k]
|
||||||
|
materialHy = ID[4, i, j + 1, k]
|
||||||
|
materialHz = ID[5, i, j, k + 1]
|
||||||
|
Hx[i + 1, j, k] = updatecoeffsH[materialHx, 0] * Hx[i + 1, j, k] - updatecoeffsH[materialHx, 2] * (Ez[i + 1, j + 1, k] - Ez[i + 1, j, k]) + updatecoeffsH[materialHx, 3] * (Ey[i + 1, j, k + 1] - Ey[i + 1, j, k])
|
||||||
|
Hy[i, j + 1, k] = updatecoeffsH[materialHy, 0] * Hy[i, j + 1, k] - updatecoeffsH[materialHy, 3] * (Ex[i, j + 1, k + 1] - Ex[i, j + 1, k]) + updatecoeffsH[materialHy, 1] * (Ez[i + 1, j + 1, k] - Ez[i, j + 1, k])
|
||||||
|
Hz[i, j, k + 1] = updatecoeffsH[materialHz, 0] * Hz[i, j, k + 1] - updatecoeffsH[materialHz, 1] * (Ey[i + 1, j, k + 1] - Ey[i, j, k + 1]) + updatecoeffsH[materialHz, 2] * (Ex[i, j + 1, k + 1] - Ex[i, j, k + 1])
|
@@ -20,10 +20,10 @@ import numpy as np
|
|||||||
cimport numpy as np
|
cimport numpy as np
|
||||||
from cython.parallel import prange
|
from cython.parallel import prange
|
||||||
|
|
||||||
from gprMax.config cimport complextype_t
|
from gprMax.config cimport float_or_double_complex
|
||||||
|
|
||||||
|
|
||||||
cpdef void generate_fractal2D(int nx, int ny, int nthreads, int b, np.float64_t[:] weighting, np.float64_t[:] v1, np.complex128_t[:, ::1] A, complextype_t[:, ::1] fractalsurface):
|
cpdef void generate_fractal2D(int nx, int ny, int nthreads, int b, np.float64_t[:] weighting, np.float64_t[:] v1, np.complex128_t[:, ::1] A, float_or_double_complex[:, ::1] fractalsurface):
|
||||||
"""This function generates a fractal surface for a 2D array.
|
"""This function generates a fractal surface for a 2D array.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -55,7 +55,7 @@ cpdef void generate_fractal2D(int nx, int ny, int nthreads, int b, np.float64_t[
|
|||||||
fractalsurface[i, j] = A[i, j] * 1 / (rr**b)
|
fractalsurface[i, j] = A[i, j] * 1 / (rr**b)
|
||||||
|
|
||||||
|
|
||||||
cpdef void generate_fractal3D(int nx, int ny, int nz, int nthreads, int b, np.float64_t[:] weighting, np.float64_t[:] v1, np.complex128_t[:, :, ::1] A, complextype_t[:, :, ::1] fractalvolume):
|
cpdef void generate_fractal3D(int nx, int ny, int nz, int nthreads, int b, np.float64_t[:] weighting, np.float64_t[:] v1, np.complex128_t[:, :, ::1] A, float_or_double_complex[:, :, ::1] fractalvolume):
|
||||||
"""This function generates a fractal volume for a 3D array.
|
"""This function generates a fractal volume for a 3D array.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@@ -20,7 +20,7 @@ import numpy as np
|
|||||||
cimport numpy as np
|
cimport numpy as np
|
||||||
from cython.parallel import prange
|
from cython.parallel import prange
|
||||||
|
|
||||||
from gprMax.config cimport floattype_t
|
from gprMax.config cimport float_or_double
|
||||||
|
|
||||||
|
|
||||||
cpdef void order1_xminus(
|
cpdef void order1_xminus(
|
||||||
@@ -31,20 +31,20 @@ cpdef void order1_xminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ey and Ez field components for the xminus slab.
|
"""This function updates the Ey and Ez field components for the xminus slab.
|
||||||
@@ -59,7 +59,7 @@ cpdef void order1_xminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEy, materialEz
|
cdef int nx, ny, nz, materialEy, materialEz
|
||||||
cdef floattype_t dx, dHy, dHz, RA01, RB0, RE0, RF0
|
cdef float_or_double dx, dHy, dHz, RA01, RB0, RE0, RF0
|
||||||
dx = d
|
dx = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -94,20 +94,20 @@ cpdef void order2_xminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ey and Ez field components for the xminus slab.
|
"""This function updates the Ey and Ez field components for the xminus slab.
|
||||||
@@ -122,7 +122,7 @@ cpdef void order2_xminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEy, materialEz
|
cdef int nx, ny, nz, materialEy, materialEz
|
||||||
cdef floattype_t dx, dHy, dHz, RA0, RB0, RE0, RF0, RA1, RB1, RE1, RF1, RA01
|
cdef float_or_double dx, dHy, dHz, RA0, RB0, RE0, RF0, RA1, RB1, RE1, RF1, RA01
|
||||||
dx = d
|
dx = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -165,20 +165,20 @@ cpdef void order1_xplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ey and Ez field components for the xplus slab.
|
"""This function updates the Ey and Ez field components for the xplus slab.
|
||||||
@@ -193,7 +193,7 @@ cpdef void order1_xplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEy, materialEz
|
cdef int nx, ny, nz, materialEy, materialEz
|
||||||
cdef floattype_t dx, dHy, dHz, RA01, RB0, RE0, RF0
|
cdef float_or_double dx, dHy, dHz, RA01, RB0, RE0, RF0
|
||||||
dx = d
|
dx = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -228,20 +228,20 @@ cpdef void order2_xplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ey and Ez field components for the xplus slab.
|
"""This function updates the Ey and Ez field components for the xplus slab.
|
||||||
@@ -256,7 +256,7 @@ cpdef void order2_xplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEy, materialEz
|
cdef int nx, ny, nz, materialEy, materialEz
|
||||||
cdef floattype_t dx, dHy, dHz, RA0, RB0, RE0, RF0, RA1, RB1, RE1, RF1, RA01
|
cdef float_or_double dx, dHy, dHz, RA0, RB0, RE0, RF0, RA1, RB1, RE1, RF1, RA01
|
||||||
dx = d
|
dx = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -299,20 +299,20 @@ cpdef void order1_yminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ex and Ez field components for the yminus slab.
|
"""This function updates the Ex and Ez field components for the yminus slab.
|
||||||
@@ -327,7 +327,7 @@ cpdef void order1_yminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEx, materialEz
|
cdef int nx, ny, nz, materialEx, materialEz
|
||||||
cdef floattype_t dy, dHx, dHz, RA01, RB0, RE0, RF0
|
cdef float_or_double dy, dHx, dHz, RA01, RB0, RE0, RF0
|
||||||
dy = d
|
dy = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -362,20 +362,20 @@ cpdef void order2_yminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ex and Ez field components for the yminus slab.
|
"""This function updates the Ex and Ez field components for the yminus slab.
|
||||||
@@ -390,7 +390,7 @@ cpdef void order2_yminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEx, materialEz
|
cdef int nx, ny, nz, materialEx, materialEz
|
||||||
cdef floattype_t dy, dHx, dHz, RA0, RB0, RE0, RF0, RA1, RB1, RE1, RF1, RA01
|
cdef float_or_double dy, dHx, dHz, RA0, RB0, RE0, RF0, RA1, RB1, RE1, RF1, RA01
|
||||||
dy = d
|
dy = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -433,20 +433,20 @@ cpdef void order1_yplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ex and Ez field components for the yplus slab.
|
"""This function updates the Ex and Ez field components for the yplus slab.
|
||||||
@@ -461,7 +461,7 @@ cpdef void order1_yplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEx, materialEz
|
cdef int nx, ny, nz, materialEx, materialEz
|
||||||
cdef floattype_t dy, dHx, dHz, RA01, RB0, RE0, RF0
|
cdef float_or_double dy, dHx, dHz, RA01, RB0, RE0, RF0
|
||||||
dy = d
|
dy = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -496,20 +496,20 @@ cpdef void order2_yplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ex and Ez field components for the yplus slab.
|
"""This function updates the Ex and Ez field components for the yplus slab.
|
||||||
@@ -524,7 +524,7 @@ cpdef void order2_yplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEx, materialEz
|
cdef int nx, ny, nz, materialEx, materialEz
|
||||||
cdef floattype_t dy, dHx, dHz, RA0, RB0, RE0, RF0, RA1, RB1, RE1, RF1, RA01
|
cdef float_or_double dy, dHx, dHz, RA0, RB0, RE0, RF0, RA1, RB1, RE1, RF1, RA01
|
||||||
dy = d
|
dy = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -567,20 +567,20 @@ cpdef void order1_zminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ex and Ey field components for the zminus slab.
|
"""This function updates the Ex and Ey field components for the zminus slab.
|
||||||
@@ -595,7 +595,7 @@ cpdef void order1_zminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEx, materialEy
|
cdef int nx, ny, nz, materialEx, materialEy
|
||||||
cdef floattype_t dz, dHx, dHy, RA01, RB0, RE0, RF0
|
cdef float_or_double dz, dHx, dHy, RA01, RB0, RE0, RF0
|
||||||
dz = d
|
dz = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -630,20 +630,20 @@ cpdef void order2_zminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ex and Ey field components for the zminus slab.
|
"""This function updates the Ex and Ey field components for the zminus slab.
|
||||||
@@ -658,7 +658,7 @@ cpdef void order2_zminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEx, materialEy
|
cdef int nx, ny, nz, materialEx, materialEy
|
||||||
cdef floattype_t dz, dHx, dHy, RA0, RB0, RE0, RF0, RA1, RB1, RE1, RF1, RA01
|
cdef float_or_double dz, dHx, dHy, RA0, RB0, RE0, RF0, RA1, RB1, RE1, RF1, RA01
|
||||||
dz = d
|
dz = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -701,20 +701,20 @@ cpdef void order1_zplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ex and Ey field components for the zplus slab.
|
"""This function updates the Ex and Ey field components for the zplus slab.
|
||||||
@@ -729,7 +729,7 @@ cpdef void order1_zplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEx, materialEy
|
cdef int nx, ny, nz, materialEx, materialEy
|
||||||
cdef floattype_t dz, dHx, dHy, RA01, RB0, RE0, RF0
|
cdef float_or_double dz, dHx, dHy, RA01, RB0, RE0, RF0
|
||||||
dz = d
|
dz = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -764,20 +764,20 @@ cpdef void order2_zplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ex and Ey field components for the zplus slab.
|
"""This function updates the Ex and Ey field components for the zplus slab.
|
||||||
@@ -792,7 +792,7 @@ cpdef void order2_zplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEx, materialEy
|
cdef int nx, ny, nz, materialEx, materialEy
|
||||||
cdef floattype_t dz, dHx, dHy, RA0, RB0, RE0, RF0, RA1, RB1, RE1, RF1, RA01
|
cdef float_or_double dz, dHx, dHy, RA0, RB0, RE0, RF0, RA1, RB1, RE1, RF1, RA01
|
||||||
dz = d
|
dz = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
cdef floattype_t# Copyright (C) 2015-2019: The University of Edinburgh
|
cdef float_or_double# Copyright (C) 2015-2019: The University of Edinburgh
|
||||||
# Authors: Craig Warren and Antonis Giannopoulos
|
# Authors: Craig Warren and Antonis Giannopoulos
|
||||||
#
|
#
|
||||||
# This file is part of gprMax.
|
# This file is part of gprMax.
|
||||||
@@ -20,7 +20,7 @@ import numpy as np
|
|||||||
cimport numpy as np
|
cimport numpy as np
|
||||||
from cython.parallel import prange
|
from cython.parallel import prange
|
||||||
|
|
||||||
from gprMax.config cimport floattype_t
|
from gprMax.config cimport float_or_double
|
||||||
|
|
||||||
|
|
||||||
cpdef void order1_xminus(
|
cpdef void order1_xminus(
|
||||||
@@ -31,20 +31,20 @@ cpdef void order1_xminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ey and Ez field components for the xminus slab.
|
"""This function updates the Ey and Ez field components for the xminus slab.
|
||||||
@@ -59,7 +59,7 @@ cpdef void order1_xminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEy, materialEz
|
cdef int nx, ny, nz, materialEy, materialEz
|
||||||
cdef floattype_t dx, dHy, dHz, IRA, IRA1, RB0, RC0, RE0, RF0
|
cdef float_or_double dx, dHy, dHz, IRA, IRA1, RB0, RC0, RE0, RF0
|
||||||
dx = d
|
dx = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -96,20 +96,20 @@ cpdef void order2_xminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ey and Ez field components for the xminus slab.
|
"""This function updates the Ey and Ez field components for the xminus slab.
|
||||||
@@ -124,7 +124,7 @@ cpdef void order2_xminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEy, materialEz
|
cdef int nx, ny, nz, materialEy, materialEz
|
||||||
cdef floattype_t dx, dHy, dHz, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
cdef float_or_double dx, dHy, dHz, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
||||||
dx = d
|
dx = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -170,20 +170,20 @@ cpdef void order1_xplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ey and Ez field components for the xplus slab.
|
"""This function updates the Ey and Ez field components for the xplus slab.
|
||||||
@@ -198,7 +198,7 @@ cpdef void order1_xplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEy, materialEz
|
cdef int nx, ny, nz, materialEy, materialEz
|
||||||
cdef floattype_t dx, dHy, dHz, IRA, IRA1, RB0, RC0, RE0, RF0
|
cdef float_or_double dx, dHy, dHz, IRA, IRA1, RB0, RC0, RE0, RF0
|
||||||
dx = d
|
dx = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -235,20 +235,20 @@ cpdef void order2_xplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ey and Ez field components for the xplus slab.
|
"""This function updates the Ey and Ez field components for the xplus slab.
|
||||||
@@ -263,7 +263,7 @@ cpdef void order2_xplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEy, materialEz
|
cdef int nx, ny, nz, materialEy, materialEz
|
||||||
cdef floattype_t dx, dHy, dHz, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
cdef float_or_double dx, dHy, dHz, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
||||||
dx = d
|
dx = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -309,20 +309,20 @@ cpdef void order1_yminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ex and Ez field components for the yminus slab.
|
"""This function updates the Ex and Ez field components for the yminus slab.
|
||||||
@@ -337,7 +337,7 @@ cpdef void order1_yminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEx, materialEz
|
cdef int nx, ny, nz, materialEx, materialEz
|
||||||
cdef floattype_t dy, dHx, dHz, IRA, IRA1, RB0, RC0, RE0, RF0
|
cdef float_or_double dy, dHx, dHz, IRA, IRA1, RB0, RC0, RE0, RF0
|
||||||
dy = d
|
dy = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -374,20 +374,20 @@ cpdef void order2_yminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ex and Ez field components for the yminus slab.
|
"""This function updates the Ex and Ez field components for the yminus slab.
|
||||||
@@ -402,7 +402,7 @@ cpdef void order2_yminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEx, materialEz
|
cdef int nx, ny, nz, materialEx, materialEz
|
||||||
cdef floattype_t dy, dHx, dHz, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
cdef float_or_double dy, dHx, dHz, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
||||||
dy = d
|
dy = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -448,20 +448,20 @@ cpdef void order1_yplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ex and Ez field components for the yplus slab.
|
"""This function updates the Ex and Ez field components for the yplus slab.
|
||||||
@@ -476,7 +476,7 @@ cpdef void order1_yplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEx, materialEz
|
cdef int nx, ny, nz, materialEx, materialEz
|
||||||
cdef floattype_t dy, dHx, dHz, IRA, IRA1, RB0, RC0, RE0, RF0
|
cdef float_or_double dy, dHx, dHz, IRA, IRA1, RB0, RC0, RE0, RF0
|
||||||
dy = d
|
dy = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -513,20 +513,20 @@ cpdef void order2_yplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ex and Ez field components for the yplus slab.
|
"""This function updates the Ex and Ez field components for the yplus slab.
|
||||||
@@ -541,7 +541,7 @@ cpdef void order2_yplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEx, materialEz
|
cdef int nx, ny, nz, materialEx, materialEz
|
||||||
cdef floattype_t dy, dHx, dHz, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
cdef float_or_double dy, dHx, dHz, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
||||||
dy = d
|
dy = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -587,20 +587,20 @@ cpdef void order1_zminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ex and Ey field components for the zminus slab.
|
"""This function updates the Ex and Ey field components for the zminus slab.
|
||||||
@@ -615,7 +615,7 @@ cpdef void order1_zminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEx, materialEy
|
cdef int nx, ny, nz, materialEx, materialEy
|
||||||
cdef floattype_t dz, dHx, dHy, IRA, IRA1, RB0, RC0, RE0, RF0
|
cdef float_or_double dz, dHx, dHy, IRA, IRA1, RB0, RC0, RE0, RF0
|
||||||
dz = d
|
dz = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -652,20 +652,20 @@ cpdef void order2_zminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ex and Ey field components for the zminus slab.
|
"""This function updates the Ex and Ey field components for the zminus slab.
|
||||||
@@ -680,7 +680,7 @@ cpdef void order2_zminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEx, materialEy
|
cdef int nx, ny, nz, materialEx, materialEy
|
||||||
cdef floattype_t dz, dHx, dHy, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
cdef float_or_double dz, dHx, dHy, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
||||||
dz = d
|
dz = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -726,20 +726,20 @@ cpdef void order1_zplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ex and Ey field components for the zplus slab.
|
"""This function updates the Ex and Ey field components for the zplus slab.
|
||||||
@@ -754,7 +754,7 @@ cpdef void order1_zplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEx, materialEy
|
cdef int nx, ny, nz, materialEx, materialEy
|
||||||
cdef floattype_t dz, dHx, dHy, IRA, IRA1, RB0, RC0, RE0, RF0
|
cdef float_or_double dz, dHx, dHy, IRA, IRA1, RB0, RC0, RE0, RF0
|
||||||
dz = d
|
dz = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -791,20 +791,20 @@ cpdef void order2_zplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsE,
|
float_or_double[:, ::1] updatecoeffsE,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Ex and Ey field components for the zplus slab.
|
"""This function updates the Ex and Ey field components for the zplus slab.
|
||||||
@@ -819,7 +819,7 @@ cpdef void order2_zplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialEx, materialEy
|
cdef int nx, ny, nz, materialEx, materialEy
|
||||||
cdef floattype_t dz, dHx, dHy, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
cdef float_or_double dz, dHx, dHy, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
||||||
dz = d
|
dz = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
|
@@ -20,7 +20,7 @@ import numpy as np
|
|||||||
cimport numpy as np
|
cimport numpy as np
|
||||||
from cython.parallel import prange
|
from cython.parallel import prange
|
||||||
|
|
||||||
from gprMax.config cimport floattype_t
|
from gprMax.config cimport float_or_double
|
||||||
|
|
||||||
|
|
||||||
cpdef void order1_xminus(
|
cpdef void order1_xminus(
|
||||||
@@ -31,20 +31,20 @@ cpdef void order1_xminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hy and Hz field components for the xminus slab.
|
"""This function updates the Hy and Hz field components for the xminus slab.
|
||||||
@@ -59,7 +59,7 @@ cpdef void order1_xminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHy, materialHz
|
cdef int nx, ny, nz, materialHy, materialHz
|
||||||
cdef floattype_t dx, dEy, dEz, RA01, RB0, RE0, RF0
|
cdef float_or_double dx, dEy, dEz, RA01, RB0, RE0, RF0
|
||||||
dx = d
|
dx = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -94,20 +94,20 @@ cpdef void order2_xminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hy and Hz field components for the xminus slab.
|
"""This function updates the Hy and Hz field components for the xminus slab.
|
||||||
@@ -122,7 +122,7 @@ cpdef void order2_xminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHy, materialHz
|
cdef int nx, ny, nz, materialHy, materialHz
|
||||||
cdef floattype_t dx, dEy, dEz, RA0, RA01, RB0, RE0, RF0, RA1, RB1, RE1, RF1
|
cdef float_or_double dx, dEy, dEz, RA0, RA01, RB0, RE0, RF0, RA1, RB1, RE1, RF1
|
||||||
dx = d
|
dx = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -165,20 +165,20 @@ cpdef void order1_xplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hy and Hz field components for the xplus slab.
|
"""This function updates the Hy and Hz field components for the xplus slab.
|
||||||
@@ -193,7 +193,7 @@ cpdef void order1_xplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHy, materialHz
|
cdef int nx, ny, nz, materialHy, materialHz
|
||||||
cdef floattype_t dx, dEy, dEz, RA01, RB0, RE0, RF0
|
cdef float_or_double dx, dEy, dEz, RA01, RB0, RE0, RF0
|
||||||
dx = d
|
dx = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -228,20 +228,20 @@ cpdef void order2_xplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hy and Hz field components for the xplus slab.
|
"""This function updates the Hy and Hz field components for the xplus slab.
|
||||||
@@ -256,7 +256,7 @@ cpdef void order2_xplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHy, materialHz
|
cdef int nx, ny, nz, materialHy, materialHz
|
||||||
cdef floattype_t dx, dEy, dEz, RA0, RA01, RB0, RE0, RF0, RA1, RB1, RE1, RF1
|
cdef float_or_double dx, dEy, dEz, RA0, RA01, RB0, RE0, RF0, RA1, RB1, RE1, RF1
|
||||||
dx = d
|
dx = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -299,20 +299,20 @@ cpdef void order1_yminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hx and Hz field components for the yminus slab.
|
"""This function updates the Hx and Hz field components for the yminus slab.
|
||||||
@@ -327,7 +327,7 @@ cpdef void order1_yminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHx, materialHz
|
cdef int nx, ny, nz, materialHx, materialHz
|
||||||
cdef floattype_t dy, dEx, dEz, RA01, RB0, RE0, RF0
|
cdef float_or_double dy, dEx, dEz, RA01, RB0, RE0, RF0
|
||||||
dy = d
|
dy = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -362,20 +362,20 @@ cpdef void order2_yminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hx and Hz field components for the yminus slab.
|
"""This function updates the Hx and Hz field components for the yminus slab.
|
||||||
@@ -390,7 +390,7 @@ cpdef void order2_yminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHx, materialHz
|
cdef int nx, ny, nz, materialHx, materialHz
|
||||||
cdef floattype_t dy, dEx, dEz, RA0, RA01, RB0, RE0, RF0, RA1, RB1, RE1, RF1
|
cdef float_or_double dy, dEx, dEz, RA0, RA01, RB0, RE0, RF0, RA1, RB1, RE1, RF1
|
||||||
dy = d
|
dy = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -433,20 +433,20 @@ cpdef void order1_yplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hx and Hz field components for the yplus slab.
|
"""This function updates the Hx and Hz field components for the yplus slab.
|
||||||
@@ -461,7 +461,7 @@ cpdef void order1_yplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHx, materialHz
|
cdef int nx, ny, nz, materialHx, materialHz
|
||||||
cdef floattype_t dy, dEx, dEz, RA01, RB0, RE0, RF0
|
cdef float_or_double dy, dEx, dEz, RA01, RB0, RE0, RF0
|
||||||
dy = d
|
dy = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -496,20 +496,20 @@ cpdef void order2_yplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hx and Hz field components for the yplus slab.
|
"""This function updates the Hx and Hz field components for the yplus slab.
|
||||||
@@ -524,7 +524,7 @@ cpdef void order2_yplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHx, materialHz
|
cdef int nx, ny, nz, materialHx, materialHz
|
||||||
cdef floattype_t dy, dEx, dEz, RA0, RA01, RB0, RE0, RF0, RA1, RB1, RE1, RF1
|
cdef float_or_double dy, dEx, dEz, RA0, RA01, RB0, RE0, RF0, RA1, RB1, RE1, RF1
|
||||||
dy = d
|
dy = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -567,20 +567,20 @@ cpdef void order1_zminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hx and Hy field components for the zminus slab.
|
"""This function updates the Hx and Hy field components for the zminus slab.
|
||||||
@@ -595,7 +595,7 @@ cpdef void order1_zminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHx, materialHy
|
cdef int nx, ny, nz, materialHx, materialHy
|
||||||
cdef floattype_t dz, dEx, dEy, RA01, RB0, RE0, RF0
|
cdef float_or_double dz, dEx, dEy, RA01, RB0, RE0, RF0
|
||||||
dz = d
|
dz = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -630,20 +630,20 @@ cpdef void order2_zminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hx and Hy field components for the zminus slab.
|
"""This function updates the Hx and Hy field components for the zminus slab.
|
||||||
@@ -658,7 +658,7 @@ cpdef void order2_zminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHx, materialHy
|
cdef int nx, ny, nz, materialHx, materialHy
|
||||||
cdef floattype_t dz, dEx, dEy, RA0, RA01, RB0, RE0, RF0, RA1, RB1, RE1, RF1
|
cdef float_or_double dz, dEx, dEy, RA0, RA01, RB0, RE0, RF0, RA1, RB1, RE1, RF1
|
||||||
dz = d
|
dz = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -701,20 +701,20 @@ cpdef void order1_zplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hx and Hy field components for the zplus slab.
|
"""This function updates the Hx and Hy field components for the zplus slab.
|
||||||
@@ -729,7 +729,7 @@ cpdef void order1_zplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHx, materialHy
|
cdef int nx, ny, nz, materialHx, materialHy
|
||||||
cdef floattype_t dz, dEx, dEy, RA01, RB0, RE0, RF0
|
cdef float_or_double dz, dEx, dEy, RA01, RB0, RE0, RF0
|
||||||
dz = d
|
dz = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -764,20 +764,20 @@ cpdef void order2_zplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hx and Hy field components for the zplus slab.
|
"""This function updates the Hx and Hy field components for the zplus slab.
|
||||||
@@ -792,7 +792,7 @@ cpdef void order2_zplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHx, materialHy
|
cdef int nx, ny, nz, materialHx, materialHy
|
||||||
cdef floattype_t dz, dEx, dEy, RA0, RA01, RB0, RE0, RF0, RA1, RB1, RE1, RF1
|
cdef float_or_double dz, dEx, dEy, RA0, RA01, RB0, RE0, RF0, RA1, RB1, RE1, RF1
|
||||||
dz = d
|
dz = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
|
@@ -20,7 +20,7 @@ import numpy as np
|
|||||||
cimport numpy as np
|
cimport numpy as np
|
||||||
from cython.parallel import prange
|
from cython.parallel import prange
|
||||||
|
|
||||||
from gprMax.config cimport floattype_t
|
from gprMax.config cimport float_or_double
|
||||||
|
|
||||||
|
|
||||||
cpdef void order1_xminus(
|
cpdef void order1_xminus(
|
||||||
@@ -31,20 +31,20 @@ cpdef void order1_xminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hy and Hz field components for the xminus slab.
|
"""This function updates the Hy and Hz field components for the xminus slab.
|
||||||
@@ -59,7 +59,7 @@ cpdef void order1_xminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHy, materialHz
|
cdef int nx, ny, nz, materialHy, materialHz
|
||||||
cdef floattype_t dx, dEy, dEz, IRA, IRA1, RB0, RC0, RE0, RF0
|
cdef float_or_double dx, dEy, dEz, IRA, IRA1, RB0, RC0, RE0, RF0
|
||||||
dx = d
|
dx = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -96,20 +96,20 @@ cpdef void order2_xminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hy and Hz field components for the xminus slab.
|
"""This function updates the Hy and Hz field components for the xminus slab.
|
||||||
@@ -124,7 +124,7 @@ cpdef void order2_xminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHy, materialHz
|
cdef int nx, ny, nz, materialHy, materialHz
|
||||||
cdef floattype_t dx, dEy, dEz, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
cdef float_or_double dx, dEy, dEz, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
||||||
dx = d
|
dx = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -170,20 +170,20 @@ cpdef void order1_xplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hy and Hz field components for the xplus slab.
|
"""This function updates the Hy and Hz field components for the xplus slab.
|
||||||
@@ -198,7 +198,7 @@ cpdef void order1_xplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHy, materialHz
|
cdef int nx, ny, nz, materialHy, materialHz
|
||||||
cdef floattype_t dx, dEy, dEz, IRA, IRA1, RB0, RC0, RE0, RF0
|
cdef float_or_double dx, dEy, dEz, IRA, IRA1, RB0, RC0, RE0, RF0
|
||||||
dx = d
|
dx = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -235,20 +235,20 @@ cpdef void order2_xplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hy and Hz field components for the xplus slab.
|
"""This function updates the Hy and Hz field components for the xplus slab.
|
||||||
@@ -263,7 +263,7 @@ cpdef void order2_xplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHy, materialHz
|
cdef int nx, ny, nz, materialHy, materialHz
|
||||||
cdef floattype_t dx, dEy, dEz, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
cdef float_or_double dx, dEy, dEz, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
||||||
dx = d
|
dx = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -309,20 +309,20 @@ cpdef void order1_yminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hx and Hz field components for the yminus slab.
|
"""This function updates the Hx and Hz field components for the yminus slab.
|
||||||
@@ -337,7 +337,7 @@ cpdef void order1_yminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHx, materialHz
|
cdef int nx, ny, nz, materialHx, materialHz
|
||||||
cdef floattype_t dy, dEx, dEz, IRA, IRA1, RB0, RC0, RE0, RF0
|
cdef float_or_double dy, dEx, dEz, IRA, IRA1, RB0, RC0, RE0, RF0
|
||||||
dy = d
|
dy = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -374,20 +374,20 @@ cpdef void order2_yminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hx and Hz field components for the yminus slab.
|
"""This function updates the Hx and Hz field components for the yminus slab.
|
||||||
@@ -402,7 +402,7 @@ cpdef void order2_yminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHx, materialHz
|
cdef int nx, ny, nz, materialHx, materialHz
|
||||||
cdef floattype_t dy, dEx, dEz, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
cdef float_or_double dy, dEx, dEz, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
||||||
dy = d
|
dy = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -448,20 +448,20 @@ cpdef void order1_yplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hx and Hz field components for the yplus slab.
|
"""This function updates the Hx and Hz field components for the yplus slab.
|
||||||
@@ -476,7 +476,7 @@ cpdef void order1_yplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHx, materialHz
|
cdef int nx, ny, nz, materialHx, materialHz
|
||||||
cdef floattype_t dy, dEx, dEz, IRA, IRA1, RB0, RC0, RE0, RF0
|
cdef float_or_double dy, dEx, dEz, IRA, IRA1, RB0, RC0, RE0, RF0
|
||||||
dy = d
|
dy = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -513,20 +513,20 @@ cpdef void order2_yplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hx and Hz field components for the yplus slab.
|
"""This function updates the Hx and Hz field components for the yplus slab.
|
||||||
@@ -541,7 +541,7 @@ cpdef void order2_yplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHx, materialHz
|
cdef int nx, ny, nz, materialHx, materialHz
|
||||||
cdef floattype_t dy, dEx, dEz, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
cdef float_or_double dy, dEx, dEz, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
||||||
dy = d
|
dy = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -587,20 +587,20 @@ cpdef void order1_zminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hx and Hy field components for the zminus slab.
|
"""This function updates the Hx and Hy field components for the zminus slab.
|
||||||
@@ -615,7 +615,7 @@ cpdef void order1_zminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHx, materialHy
|
cdef int nx, ny, nz, materialHx, materialHy
|
||||||
cdef floattype_t dz, dEx, dEy, IRA, IRA1, RB0, RC0, RE0, RF0
|
cdef float_or_double dz, dEx, dEy, IRA, IRA1, RB0, RC0, RE0, RF0
|
||||||
dz = d
|
dz = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -652,20 +652,20 @@ cpdef void order2_zminus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hx and Hy field components for the zminus slab.
|
"""This function updates the Hx and Hy field components for the zminus slab.
|
||||||
@@ -680,7 +680,7 @@ cpdef void order2_zminus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHx, materialHy
|
cdef int nx, ny, nz, materialHx, materialHy
|
||||||
cdef floattype_t dz, dEx, dEy, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
cdef float_or_double dz, dEx, dEy, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
||||||
dz = d
|
dz = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -726,20 +726,20 @@ cpdef void order1_zplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hx and Hy field components for the zplus slab.
|
"""This function updates the Hx and Hy field components for the zplus slab.
|
||||||
@@ -754,7 +754,7 @@ cpdef void order1_zplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHx, materialHy
|
cdef int nx, ny, nz, materialHx, materialHy
|
||||||
cdef floattype_t dz, dEx, dEy, IRA, IRA1, RB0, RC0, RE0, RF0
|
cdef float_or_double dz, dEx, dEy, IRA, IRA1, RB0, RC0, RE0, RF0
|
||||||
dz = d
|
dz = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
@@ -791,20 +791,20 @@ cpdef void order2_zplus(
|
|||||||
int zs,
|
int zs,
|
||||||
int zf,
|
int zf,
|
||||||
int nthreads,
|
int nthreads,
|
||||||
floattype_t[:, ::1] updatecoeffsH,
|
float_or_double[:, ::1] updatecoeffsH,
|
||||||
np.uint32_t[:, :, :, ::1] ID,
|
np.uint32_t[:, :, :, ::1] ID,
|
||||||
floattype_t[:, :, ::1] Ex,
|
float_or_double[:, :, ::1] Ex,
|
||||||
floattype_t[:, :, ::1] Ey,
|
float_or_double[:, :, ::1] Ey,
|
||||||
floattype_t[:, :, ::1] Ez,
|
float_or_double[:, :, ::1] Ez,
|
||||||
floattype_t[:, :, ::1] Hx,
|
float_or_double[:, :, ::1] Hx,
|
||||||
floattype_t[:, :, ::1] Hy,
|
float_or_double[:, :, ::1] Hy,
|
||||||
floattype_t[:, :, ::1] Hz,
|
float_or_double[:, :, ::1] Hz,
|
||||||
floattype_t[:, :, :, ::1] Phi1,
|
float_or_double[:, :, :, ::1] Phi1,
|
||||||
floattype_t[:, :, :, ::1] Phi2,
|
float_or_double[:, :, :, ::1] Phi2,
|
||||||
floattype_t[:, ::1] RA,
|
float_or_double[:, ::1] RA,
|
||||||
floattype_t[:, ::1] RB,
|
float_or_double[:, ::1] RB,
|
||||||
floattype_t[:, ::1] RE,
|
float_or_double[:, ::1] RE,
|
||||||
floattype_t[:, ::1] RF,
|
float_or_double[:, ::1] RF,
|
||||||
float d
|
float d
|
||||||
):
|
):
|
||||||
"""This function updates the Hx and Hy field components for the zplus slab.
|
"""This function updates the Hx and Hy field components for the zplus slab.
|
||||||
@@ -819,7 +819,7 @@ cpdef void order2_zplus(
|
|||||||
|
|
||||||
cdef Py_ssize_t i, j, k, ii, jj, kk
|
cdef Py_ssize_t i, j, k, ii, jj, kk
|
||||||
cdef int nx, ny, nz, materialHx, materialHy
|
cdef int nx, ny, nz, materialHx, materialHy
|
||||||
cdef floattype_t dz, dEx, dEy, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
cdef float_or_double dz, dEx, dEy, IRA, IRA1, RB0, RC0, RE0, RF0, RB1, RC1, RE1, RF1, Psi1, Psi2
|
||||||
dz = d
|
dz = d
|
||||||
nx = xf - xs
|
nx = xf - xs
|
||||||
ny = yf - ys
|
ny = yf - ys
|
||||||
|
@@ -18,35 +18,35 @@
|
|||||||
|
|
||||||
cimport numpy as np
|
cimport numpy as np
|
||||||
|
|
||||||
from gprMax.config cimport floattype_t
|
from gprMax.config cimport float_or_double
|
||||||
|
|
||||||
|
|
||||||
cpdef void calculate_snapshot_fields(
|
cpdef void calculate_snapshot_fields(
|
||||||
int nx,
|
int nx,
|
||||||
int ny,
|
int ny,
|
||||||
int nz,
|
int nz,
|
||||||
floattype_t[:, :, ::1] sliceEx,
|
float_or_double[:, :, ::1] sliceEx,
|
||||||
floattype_t[:, :, ::1] sliceEy,
|
float_or_double[:, :, ::1] sliceEy,
|
||||||
floattype_t[:, :, ::1] sliceEz,
|
float_or_double[:, :, ::1] sliceEz,
|
||||||
floattype_t[:, :, ::1] sliceHx,
|
float_or_double[:, :, ::1] sliceHx,
|
||||||
floattype_t[:, :, ::1] sliceHy,
|
float_or_double[:, :, ::1] sliceHy,
|
||||||
floattype_t[:, :, ::1] sliceHz,
|
float_or_double[:, :, ::1] sliceHz,
|
||||||
floattype_t[:, :, ::1] snapEx,
|
float_or_double[:, :, ::1] snapEx,
|
||||||
floattype_t[:, :, ::1] snapEy,
|
float_or_double[:, :, ::1] snapEy,
|
||||||
floattype_t[:, :, ::1] snapEz,
|
float_or_double[:, :, ::1] snapEz,
|
||||||
floattype_t[:, :, ::1] snapHx,
|
float_or_double[:, :, ::1] snapHx,
|
||||||
floattype_t[:, :, ::1] snapHy,
|
float_or_double[:, :, ::1] snapHy,
|
||||||
floattype_t[:, :, ::1] snapHz
|
float_or_double[:, :, ::1] snapHz
|
||||||
):
|
):
|
||||||
"""This function calculates electric and magnetic values at points from
|
"""This function calculates electric and magnetic values at points from
|
||||||
averaging values in cells
|
averaging values in cells.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nx, ny, nz (int): Size of snapshot array
|
nx, ny, nz (int): Size of snapshot array
|
||||||
sliceEx, sliceEy, sliceEz,
|
sliceEx, sliceEy, sliceEz,
|
||||||
sliceHx, sliceHy, sliceHz (memoryview): Access to slices of field arrays
|
sliceHx, sliceHy, sliceHz (memoryview): Access to slices of field arrays
|
||||||
snapEx, snapEy, snapEz, snapHx,
|
snapEx, snapEy, snapEz,
|
||||||
snapHy, snapHz (memoryview): Access to snapshot arrays
|
snapHx, snapHy, snapHz (memoryview): Access to snapshot arrays
|
||||||
"""
|
"""
|
||||||
|
|
||||||
cdef Py_ssize_t i, j, k
|
cdef Py_ssize_t i, j, k
|
||||||
@@ -54,9 +54,8 @@ cpdef void calculate_snapshot_fields(
|
|||||||
for i in range(nx):
|
for i in range(nx):
|
||||||
for j in range(ny):
|
for j in range(ny):
|
||||||
for k in range(nz):
|
for k in range(nz):
|
||||||
|
# The electric field component value at a point comes from the
|
||||||
# The electric field component value at a point comes from
|
# average of the 4 electric field component values in that cell.
|
||||||
# average of the 4 electric field component values in that cell
|
|
||||||
snapEx[i, j, k] = (sliceEx[i, j, k] + sliceEx[i, j + 1, k] +
|
snapEx[i, j, k] = (sliceEx[i, j, k] + sliceEx[i, j + 1, k] +
|
||||||
sliceEx[i, j, k + 1] + sliceEx[i, j + 1, k + 1]) / 4
|
sliceEx[i, j, k + 1] + sliceEx[i, j + 1, k + 1]) / 4
|
||||||
snapEy[i, j, k] = (sliceEy[i, j, k] + sliceEy[i + 1, j, k] +
|
snapEy[i, j, k] = (sliceEy[i, j, k] + sliceEy[i + 1, j, k] +
|
||||||
@@ -64,8 +63,9 @@ cpdef void calculate_snapshot_fields(
|
|||||||
snapEz[i, j, k] = (sliceEz[i, j, k] + sliceEz[i + 1, j, k] +
|
snapEz[i, j, k] = (sliceEz[i, j, k] + sliceEz[i + 1, j, k] +
|
||||||
sliceEz[i, j + 1, k] + sliceEz[i + 1, j + 1, k]) / 4
|
sliceEz[i, j + 1, k] + sliceEz[i + 1, j + 1, k]) / 4
|
||||||
|
|
||||||
# The magnetic field component value at a point comes from average
|
# The magnetic field component value at a point comes from
|
||||||
# of 2 magnetic field component values in that cell and the following cell
|
# average of 2 magnetic field component values in that cell and
|
||||||
|
# the neighbouring cell.
|
||||||
snapHx[i, j, k] = (sliceHx[i, j, k] + sliceHx[i + 1, j, k]) / 2
|
snapHx[i, j, k] = (sliceHx[i, j, k] + sliceHx[i + 1, j, k]) / 2
|
||||||
snapHy[i, j, k] = (sliceHy[i, j, k] + sliceHy[i, j + 1, k]) / 2
|
snapHy[i, j, k] = (sliceHy[i, j, k] + sliceHy[i, j + 1, k]) / 2
|
||||||
snapHz[i, j, k] = (sliceHz[i, j, k] + sliceHz[i, j, k + 1]) / 2
|
snapHz[i, j, k] = (sliceHz[i, j, k] + sliceHz[i, j, k + 1]) / 2
|
||||||
|
@@ -37,7 +37,9 @@ class GeneralError(ValueError):
|
|||||||
|
|
||||||
|
|
||||||
class CmdInputError(ValueError):
|
class CmdInputError(ValueError):
|
||||||
"""Handles errors in user specified commands. Subclasses the ValueError class."""
|
"""Handles errors in user specified commands. Subclasses the ValueError
|
||||||
|
class.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, message, *args):
|
def __init__(self, message, *args):
|
||||||
|
|
||||||
|
@@ -20,7 +20,7 @@ from string import Template
|
|||||||
|
|
||||||
import h5py
|
import h5py
|
||||||
|
|
||||||
from gprMax._version import __version__
|
from ._version import __version__
|
||||||
|
|
||||||
|
|
||||||
def store_outputs(iteration, Ex, Ey, Ez, Hx, Hy, Hz, G):
|
def store_outputs(iteration, Ex, Ey, Ez, Hx, Hy, Hz, G):
|
||||||
@@ -28,8 +28,10 @@ def store_outputs(iteration, Ex, Ey, Ez, Hx, Hy, Hz, G):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
iteration (int): Current iteration number.
|
iteration (int): Current iteration number.
|
||||||
Ex, Ey, Ez, Hx, Hy, Hz (memory view): Current electric and magnetic field values.
|
Ex, Ey, Ez, Hx, Hy, Hz (memory view): Current electric and magnetic
|
||||||
G (class): Grid class instance - holds essential parameters describing the model.
|
field values.
|
||||||
|
G (class): Grid class instance - holds essential parameters describing
|
||||||
|
the model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for rx in G.rxs:
|
for rx in G.rxs:
|
||||||
@@ -41,7 +43,8 @@ def store_outputs(iteration, Ex, Ey, Ez, Hx, Hy, Hz, G):
|
|||||||
# Store current component
|
# Store current component
|
||||||
else:
|
else:
|
||||||
func = globals()[output]
|
func = globals()[output]
|
||||||
rx.outputs[output][iteration] = func(rx.xcoord, rx.ycoord, rx.zcoord, Hx, Hy, Hz, G)
|
rx.outputs[output][iteration] = func(rx.xcoord, rx.ycoord, rx.zcoord,
|
||||||
|
Hx, Hy, Hz, G)
|
||||||
|
|
||||||
for tl in G.transmissionlines:
|
for tl in G.transmissionlines:
|
||||||
tl.Vtotal[iteration] = tl.voltage[tl.antpos]
|
tl.Vtotal[iteration] = tl.voltage[tl.antpos]
|
||||||
@@ -94,8 +97,10 @@ def write_hdf5_outputfile(outputfile, Ex, Ey, Ez, Hx, Hy, Hz, G):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
outputfile (str): Name of the output file.
|
outputfile (str): Name of the output file.
|
||||||
Ex, Ey, Ez, Hx, Hy, Hz (memory view): Current electric and magnetic field values.
|
Ex, Ey, Ez, Hx, Hy, Hz (memory view): Current electric and magnetic
|
||||||
G (class): Grid class instance - holds essential parameters describing the model.
|
field values.
|
||||||
|
G (class): Grid class instance - holds essential parameters describing
|
||||||
|
the model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
f = h5py.File(outputfile, 'w')
|
f = h5py.File(outputfile, 'w')
|
||||||
|
@@ -19,12 +19,10 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
from scipy import fftpack
|
from scipy import fftpack
|
||||||
|
|
||||||
from gprMax.config import floattype
|
import gprMax.config as config
|
||||||
from gprMax.config import complextype
|
from .cython.fractals_generate import generate_fractal2D
|
||||||
from gprMax.config import hostinfo
|
from .cython.fractals_generate import generate_fractal3D
|
||||||
from gprMax.cython.fractals_generate import generate_fractal2D
|
from .utilities import round_value
|
||||||
from gprMax.cython.fractals_generate import generate_fractal3D
|
|
||||||
from gprMax.utilities import round_value
|
|
||||||
|
|
||||||
np.seterr(divide='raise')
|
np.seterr(divide='raise')
|
||||||
|
|
||||||
@@ -37,9 +35,11 @@ class FractalSurface(object):
|
|||||||
def __init__(self, xs, xf, ys, yf, zs, zf, dimension):
|
def __init__(self, xs, xf, ys, yf, zs, zf, dimension):
|
||||||
"""
|
"""
|
||||||
Args:
|
Args:
|
||||||
xs, xf, ys, yf, zs, zf (float): Extent of the fractal surface (one pair of
|
xs, xf, ys, yf, zs, zf (float): Extent of the fractal surface
|
||||||
coordinates must be equal to correctly define a surface).
|
(one pair of coordinates must be
|
||||||
dimension (float): Fractal dimension that controls the fractal distribution.
|
equal to correctly define a surface).
|
||||||
|
dimension (float): Fractal dimension that controls the fractal
|
||||||
|
distribution.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.ID = None
|
self.ID = None
|
||||||
@@ -66,7 +66,8 @@ class FractalSurface(object):
|
|||||||
"""Generate a 2D array with a fractal distribution.
|
"""Generate a 2D array with a fractal distribution.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
G (class): Grid class instance - holds essential parameters describing the model.
|
G (class): Grid class instance - holds essential parameters
|
||||||
|
describing the model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.xs == self.xf:
|
if self.xs == self.xf:
|
||||||
@@ -76,10 +77,11 @@ class FractalSurface(object):
|
|||||||
elif self.zs == self.zf:
|
elif self.zs == self.zf:
|
||||||
surfacedims = (self.nx, self.ny)
|
surfacedims = (self.nx, self.ny)
|
||||||
|
|
||||||
self.fractalsurface = np.zeros(surfacedims, dtype=complextype)
|
self.fractalsurface = np.zeros(surfacedims, dtype=config.dtypes['complex'])
|
||||||
|
|
||||||
# Positional vector at centre of array, scaled by weighting
|
# Positional vector at centre of array, scaled by weighting
|
||||||
v1 = np.array([self.weighting[0] * (surfacedims[0]) / 2, self.weighting[1] * (surfacedims[1]) / 2])
|
v1 = np.array([self.weighting[0] * (surfacedims[0]) / 2, self.weighting[1]
|
||||||
|
* (surfacedims[1]) / 2])
|
||||||
|
|
||||||
# 2D array of random numbers to be convolved with the fractal function
|
# 2D array of random numbers to be convolved with the fractal function
|
||||||
R = np.random.RandomState(self.seed)
|
R = np.random.RandomState(self.seed)
|
||||||
@@ -91,7 +93,8 @@ class FractalSurface(object):
|
|||||||
A = fftpack.fftshift(A)
|
A = fftpack.fftshift(A)
|
||||||
|
|
||||||
# Generate fractal
|
# Generate fractal
|
||||||
generate_fractal2D(surfacedims[0], surfacedims[1], hostinfo['ompthreads'], self.b, self.weighting, v1, A, self.fractalsurface)
|
generate_fractal2D(surfacedims[0], surfacedims[1], config.hostinfo['ompthreads'],
|
||||||
|
self.b, self.weighting, v1, A, self.fractalsurface)
|
||||||
|
|
||||||
# Shift the zero frequency component to start of the array
|
# Shift the zero frequency component to start of the array
|
||||||
self.fractalsurface = fftpack.ifftshift(self.fractalsurface)
|
self.fractalsurface = fftpack.ifftshift(self.fractalsurface)
|
||||||
@@ -101,8 +104,10 @@ class FractalSurface(object):
|
|||||||
fractalmin = np.amin(self.fractalsurface)
|
fractalmin = np.amin(self.fractalsurface)
|
||||||
fractalmax = np.amax(self.fractalsurface)
|
fractalmax = np.amax(self.fractalsurface)
|
||||||
fractalrange = fractalmax - fractalmin
|
fractalrange = fractalmax - fractalmin
|
||||||
self.fractalsurface = self.fractalsurface * ((self.fractalrange[1] - self.fractalrange[0]) / fractalrange) \
|
self.fractalsurface = (self.fractalsurface * ((self.fractalrange[1]
|
||||||
+ self.fractalrange[0] - ((self.fractalrange[1] - self.fractalrange[0]) / fractalrange) * fractalmin
|
- self.fractalrange[0]) / fractalrange)
|
||||||
|
+ self.fractalrange[0] - ((self.fractalrange[1]
|
||||||
|
- self.fractalrange[0]) / fractalrange) * fractalmin)
|
||||||
|
|
||||||
|
|
||||||
class FractalVolume(object):
|
class FractalVolume(object):
|
||||||
@@ -112,7 +117,8 @@ class FractalVolume(object):
|
|||||||
"""
|
"""
|
||||||
Args:
|
Args:
|
||||||
xs, xf, ys, yf, zs, zf (float): Extent of the fractal volume.
|
xs, xf, ys, yf, zs, zf (float): Extent of the fractal volume.
|
||||||
dimension (float): Fractal dimension that controls the fractal distribution.
|
dimension (float): Fractal dimension that controls the fractal
|
||||||
|
distribution.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.ID = None
|
self.ID = None
|
||||||
@@ -139,7 +145,8 @@ class FractalVolume(object):
|
|||||||
"""Generate a 3D volume with a fractal distribution.
|
"""Generate a 3D volume with a fractal distribution.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
G (class): Grid class instance - holds essential parameters describing the model.
|
G (class): Grid class instance - holds essential parameters
|
||||||
|
describing the model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Scale filter according to size of fractal volume
|
# Scale filter according to size of fractal volume
|
||||||
@@ -158,10 +165,11 @@ class FractalVolume(object):
|
|||||||
# Adjust weighting to account for filter scaling
|
# Adjust weighting to account for filter scaling
|
||||||
self.weighting = np.multiply(self.weighting, filterscaling)
|
self.weighting = np.multiply(self.weighting, filterscaling)
|
||||||
|
|
||||||
self.fractalvolume = np.zeros((self.nx, self.ny, self.nz), dtype=complextype)
|
self.fractalvolume = np.zeros((self.nx, self.ny, self.nz), dtype=config.dtypes['complex'])
|
||||||
|
|
||||||
# Positional vector at centre of array, scaled by weighting
|
# Positional vector at centre of array, scaled by weighting
|
||||||
v1 = np.array([self.weighting[0] * self.nx / 2, self.weighting[1] * self.ny / 2, self.weighting[2] * self.nz / 2])
|
v1 = np.array([self.weighting[0] * self.nx / 2, self.weighting[1]
|
||||||
|
* self.ny / 2, self.weighting[2] * self.nz / 2])
|
||||||
|
|
||||||
# 3D array of random numbers to be convolved with the fractal function
|
# 3D array of random numbers to be convolved with the fractal function
|
||||||
R = np.random.RandomState(self.seed)
|
R = np.random.RandomState(self.seed)
|
||||||
@@ -173,7 +181,8 @@ class FractalVolume(object):
|
|||||||
A = fftpack.fftshift(A)
|
A = fftpack.fftshift(A)
|
||||||
|
|
||||||
# Generate fractal
|
# Generate fractal
|
||||||
generate_fractal3D(self.nx, self.ny, self.nz, hostinfo['ompthreads'], self.b, self.weighting, v1, A, self.fractalvolume)
|
generate_fractal3D(self.nx, self.ny, self.nz, config.hostinfo['ompthreads'],
|
||||||
|
self.b, self.weighting, v1, A, self.fractalvolume)
|
||||||
|
|
||||||
# Shift the zero frequency component to the start of the array
|
# Shift the zero frequency component to the start of the array
|
||||||
self.fractalvolume = fftpack.ifftshift(self.fractalvolume)
|
self.fractalvolume = fftpack.ifftshift(self.fractalvolume)
|
||||||
@@ -186,9 +195,10 @@ class FractalVolume(object):
|
|||||||
self.fractalvolume[:, j, k] = np.digitize(self.fractalvolume[:, j, k], bins, right=True)
|
self.fractalvolume[:, j, k] = np.digitize(self.fractalvolume[:, j, k], bins, right=True)
|
||||||
|
|
||||||
def generate_volume_mask(self):
|
def generate_volume_mask(self):
|
||||||
|
"""Generate a 3D volume to use as a mask for adding rough surfaces,
|
||||||
|
water and grass/roots. Zero signifies the mask is not set, one
|
||||||
|
signifies the mask is set.
|
||||||
"""
|
"""
|
||||||
Generate a 3D volume to use as a mask for adding rough surfaces, water and grass/roots.
|
|
||||||
Zero signifies the mask is not set, one signifies the mask is set."""
|
|
||||||
|
|
||||||
self.mask = np.zeros((self.nx, self.ny, self.nz), dtype=np.int8)
|
self.mask = np.zeros((self.nx, self.ny, self.nz), dtype=np.int8)
|
||||||
maskxs = self.originalxs - self.xs
|
maskxs = self.originalxs - self.xs
|
||||||
@@ -210,7 +220,8 @@ class Grass(object):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
self.numblades = numblades
|
self.numblades = numblades
|
||||||
self.geometryparams = np.zeros((self.numblades, 6), dtype=floattype)
|
self.geometryparams = np.zeros((self.numblades, 6),
|
||||||
|
dtype=config.dtypes['float_or_double'])
|
||||||
self.seed = None
|
self.seed = None
|
||||||
|
|
||||||
# Randomly defined parameters that will be used to calculate geometry
|
# Randomly defined parameters that will be used to calculate geometry
|
||||||
@@ -238,8 +249,10 @@ class Grass(object):
|
|||||||
x, y (float): x and y coordinates of grass blade.
|
x, y (float): x and y coordinates of grass blade.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
x = self.geometryparams[blade, 2] * (height / self.geometryparams[blade, 0]) * (height / self.geometryparams[blade, 0])
|
x = (self.geometryparams[blade, 2] * (height / self.geometryparams[blade, 0])
|
||||||
y = self.geometryparams[blade, 3] * (height / self.geometryparams[blade, 1]) * (height / self.geometryparams[blade, 1])
|
* (height / self.geometryparams[blade, 0]))
|
||||||
|
y = (self.geometryparams[blade, 3] * (height / self.geometryparams[blade, 1])
|
||||||
|
* (height / self.geometryparams[blade, 1]))
|
||||||
x = round_value(x)
|
x = round_value(x)
|
||||||
y = round_value(y)
|
y = round_value(y)
|
||||||
|
|
||||||
|
@@ -23,10 +23,12 @@ import h5py
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
from struct import pack
|
from struct import pack
|
||||||
|
|
||||||
from gprMax._version import __version__
|
import gprMax.config as config
|
||||||
from gprMax.cython.geometry_outputs import define_normal_geometry
|
|
||||||
from gprMax.cython.geometry_outputs import define_fine_geometry
|
from ._version import __version__
|
||||||
from gprMax.utilities import round_value
|
from .cython.geometry_outputs import define_normal_geometry
|
||||||
|
from .cython.geometry_outputs import define_fine_geometry
|
||||||
|
from .utilities import round_value
|
||||||
|
|
||||||
|
|
||||||
class GeometryView(object):
|
class GeometryView(object):
|
||||||
@@ -104,16 +106,15 @@ class GeometryView(object):
|
|||||||
+ np.dtype(np.uint32).itemsize * vtk_cell_offsets
|
+ np.dtype(np.uint32).itemsize * vtk_cell_offsets
|
||||||
+ np.dtype(np.uint32).itemsize * 4)
|
+ np.dtype(np.uint32).itemsize * 4)
|
||||||
|
|
||||||
def set_filename(self, appendmodelnumber, G):
|
def set_filename(self, appendmodelnumber):
|
||||||
"""
|
"""
|
||||||
Construct filename from user-supplied name and model run number.
|
Construct filename from user-supplied name and model run number.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
appendmodelnumber (str): Text to append to filename.
|
appendmodelnumber (str): Text to append to filename.
|
||||||
G (class): Grid class instance - holds essential parameters describing the model.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.filename = os.path.abspath(os.path.join(G.inputdirectory, self.basefilename + appendmodelnumber))
|
self.filename = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(config.general['inputfilepath'])), self.basefilename + appendmodelnumber))
|
||||||
self.filename += self.fileext
|
self.filename += self.fileext
|
||||||
|
|
||||||
def write_vtk(self, G, pbar):
|
def write_vtk(self, G, pbar):
|
||||||
|
@@ -28,22 +28,17 @@ from enum import Enum
|
|||||||
import h5py
|
import h5py
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from gprMax._version import __version__
|
from ._version import __version__
|
||||||
from gprMax._version import codename
|
from ._version import codename
|
||||||
import gprMax.config as config
|
import gprMax.config as config
|
||||||
from gprMax.config import c
|
from .exceptions import GeneralError
|
||||||
from gprMax.config import e0
|
from .model_build_run import run_model
|
||||||
from gprMax.config import m0
|
from .utilities import detect_check_gpus
|
||||||
from gprMax.config import z0
|
from .utilities import get_terminal_width
|
||||||
from gprMax.config import hostinfo
|
from .utilities import human_size
|
||||||
from gprMax.exceptions import GeneralError
|
from .utilities import logo
|
||||||
from gprMax.model_build_run import run_model
|
from .utilities import open_path_file
|
||||||
from gprMax.utilities import detect_check_gpus
|
from .utilities import timer
|
||||||
from gprMax.utilities import get_terminal_width
|
|
||||||
from gprMax.utilities import human_size
|
|
||||||
from gprMax.utilities import logo
|
|
||||||
from gprMax.utilities import open_path_file
|
|
||||||
from gprMax.utilities import timer
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""This is the main function for gprMax."""
|
"""This is the main function for gprMax."""
|
||||||
@@ -116,24 +111,24 @@ def run_main(args):
|
|||||||
logo(__version__ + ' (' + codename + ')')
|
logo(__version__ + ' (' + codename + ')')
|
||||||
|
|
||||||
# Print information about host machine
|
# Print information about host machine
|
||||||
hyperthreading = ', {} cores with HT'.format(hostinfo['logicalcores']) if hostinfo['hyperthreading'] else ''
|
hyperthreading = ', {} cores with HT'.format(config.hostinfo['logicalcores']) if config.hostinfo['hyperthreading'] else ''
|
||||||
print('\nHost: {} | {} | {} x {} ({} cores{}) | {} RAM | {}'.format(hostinfo['hostname'],
|
print('\nHost: {} | {} | {} x {} ({} cores{}) | {} RAM | {}'.format(config.hostinfo['hostname'],
|
||||||
hostinfo['machineID'], hostinfo['sockets'], hostinfo['cpuID'], hostinfo['physicalcores'],
|
config.hostinfo['machineID'], config.hostinfo['sockets'], config.hostinfo['cpuID'], config.hostinfo['physicalcores'],
|
||||||
hyperthreading, human_size(hostinfo['ram'], a_kilobyte_is_1024_bytes=True), hostinfo['osversion']))
|
hyperthreading, human_size(config.hostinfo['ram'], a_kilobyte_is_1024_bytes=True), config.hostinfo['osversion']))
|
||||||
|
|
||||||
# Get information/setup any Nvidia GPU(s)
|
# Get information/setup any Nvidia GPU(s)
|
||||||
if args.gpu is not None:
|
if args.gpu is not None:
|
||||||
# Flatten a list of lists
|
# Flatten a list of lists
|
||||||
if any(isinstance(element, list) for element in args.gpu):
|
if any(isinstance(element, list) for element in args.gpu):
|
||||||
args.gpu = [val for sublist in args.gpu for val in sublist]
|
args.gpu = [val for sublist in args.gpu for val in sublist]
|
||||||
config.gpus, allgpustext = detect_check_gpus(args.gpu)
|
config.cuda['gpus'], allgpustext = detect_check_gpus(args.gpu)
|
||||||
print('GPU(s): {}'.format(' | '.join(allgpustext)))
|
print('GPU(s): {}'.format(' | '.join(allgpustext)))
|
||||||
|
|
||||||
# Process input file
|
# Process input file
|
||||||
with open_path_file(args.inputfile) as inputfile:
|
with open_path_file(args.inputfile) as inputfile:
|
||||||
|
|
||||||
# Create a separate namespace that users can access in any Python code blocks in the input file
|
# Create a separate namespace that users can access in any Python code blocks in the input file
|
||||||
usernamespace = {'c': c, 'e0': e0, 'm0': m0, 'z0': z0, 'number_model_runs': args.n, 'inputfile': os.path.abspath(inputfile.name)}
|
usernamespace = {'c': config.c, 'e0': config.e0, 'm0': config.m0, 'z0': config.z0, 'number_model_runs': args.n, 'inputfile': os.path.abspath(inputfile.name)}
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
# Process for benchmarking simulation #
|
# Process for benchmarking simulation #
|
||||||
@@ -167,8 +162,8 @@ def run_main(args):
|
|||||||
else:
|
else:
|
||||||
if args.task and args.restart:
|
if args.task and args.restart:
|
||||||
raise GeneralError('Job array and restart modes cannot be used together')
|
raise GeneralError('Job array and restart modes cannot be used together')
|
||||||
if config.gpus:
|
if config.cuda['gpus']:
|
||||||
config.gpus = config.gpus[0]
|
config.cuda['gpus'] = config.cuda['gpus'][0]
|
||||||
run_std_sim(args, inputfile, usernamespace)
|
run_std_sim(args, inputfile, usernamespace)
|
||||||
|
|
||||||
|
|
||||||
@@ -201,7 +196,7 @@ def run_std_sim(args, inputfile, usernamespace):
|
|||||||
for currentmodelrun in range(modelstart, modelend):
|
for currentmodelrun in range(modelstart, modelend):
|
||||||
run_model(args, currentmodelrun, modelend - 1, numbermodelruns, inputfile, usernamespace)
|
run_model(args, currentmodelrun, modelend - 1, numbermodelruns, inputfile, usernamespace)
|
||||||
tsimend = timer()
|
tsimend = timer()
|
||||||
simcompletestr = '\n=== Simulation on {} completed in [HH:MM:SS]: {}'.format(hostinfo['hostname'], datetime.timedelta(seconds=tsimend - tsimstart))
|
simcompletestr = '\n=== Simulation on {} completed in [HH:MM:SS]: {}'.format(config.hostinfo['hostname'], datetime.timedelta(seconds=tsimend - tsimstart))
|
||||||
print('{} {}\n'.format(simcompletestr, '=' * (get_terminal_width() - 1 - len(simcompletestr))))
|
print('{} {}\n'.format(simcompletestr, '=' * (get_terminal_width() - 1 - len(simcompletestr))))
|
||||||
|
|
||||||
|
|
||||||
@@ -219,8 +214,8 @@ def run_benchmark_sim(args, inputfile, usernamespace):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Store information about host machine
|
# Store information about host machine
|
||||||
hyperthreading = ', {} cores with HT'.format(hostinfo['logicalcores']) if hostinfo['hyperthreading'] else ''
|
hyperthreading = ', {} cores with HT'.format(config.hostinfo['logicalcores']) if config.hostinfo['hyperthreading'] else ''
|
||||||
machineIDlong = '{}; {} x {} ({} cores{}); {} RAM; {}'.format(hostinfo['machineID'], hostinfo['sockets'], hostinfo['cpuID'], hostinfo['physicalcores'], hyperthreading, human_size(hostinfo['ram'], a_kilobyte_is_1024_bytes=True), hostinfo['osversion'])
|
machineIDlong = '{}; {} x {} ({} cores{}); {} RAM; {}'.format(config.hostinfo['machineID'], config.hostinfo['sockets'], config.hostinfo['cpuID'], config.hostinfo['physicalcores'], hyperthreading, human_size(config.hostinfo['ram'], a_kilobyte_is_1024_bytes=True), config.hostinfo['osversion'])
|
||||||
|
|
||||||
# Initialise arrays to hold CPU thread info and times, and GPU info and times
|
# Initialise arrays to hold CPU thread info and times, and GPU info and times
|
||||||
cputhreads = np.array([], dtype=np.int32)
|
cputhreads = np.array([], dtype=np.int32)
|
||||||
@@ -232,8 +227,8 @@ def run_benchmark_sim(args, inputfile, usernamespace):
|
|||||||
if args.gpu is None:
|
if args.gpu is None:
|
||||||
# Number of CPU threads to benchmark - start from single thread and double threads until maximum number of physical cores
|
# Number of CPU threads to benchmark - start from single thread and double threads until maximum number of physical cores
|
||||||
threads = 1
|
threads = 1
|
||||||
maxthreads = hostinfo['physicalcores']
|
maxthreads = config.hostinfo['physicalcores']
|
||||||
maxthreadspersocket = hostinfo['physicalcores'] / hostinfo['sockets']
|
maxthreadspersocket = config.hostinfo['physicalcores'] / config.hostinfo['sockets']
|
||||||
while threads < maxthreadspersocket:
|
while threads < maxthreadspersocket:
|
||||||
cputhreads = np.append(cputhreads, int(threads))
|
cputhreads = np.append(cputhreads, int(threads))
|
||||||
threads *= 2
|
threads *= 2
|
||||||
@@ -271,7 +266,7 @@ def run_benchmark_sim(args, inputfile, usernamespace):
|
|||||||
# Run GPU benchmark
|
# Run GPU benchmark
|
||||||
else:
|
else:
|
||||||
args.gpu = gpus[(currentmodelrun - 1)]
|
args.gpu = gpus[(currentmodelrun - 1)]
|
||||||
os.environ['OMP_NUM_THREADS'] = str(hostinfo['physicalcores'])
|
os.environ['OMP_NUM_THREADS'] = str(config.hostinfo['physicalcores'])
|
||||||
gputimes[(currentmodelrun - 1)] = run_model(args, currentmodelrun, modelend - 1, numbermodelruns, inputfile, usernamespace)
|
gputimes[(currentmodelrun - 1)] = run_model(args, currentmodelrun, modelend - 1, numbermodelruns, inputfile, usernamespace)
|
||||||
|
|
||||||
# Get model size (in cells) and number of iterations
|
# Get model size (in cells) and number of iterations
|
||||||
|
@@ -26,17 +26,11 @@ import numpy as np
|
|||||||
np.seterr(invalid='raise')
|
np.seterr(invalid='raise')
|
||||||
|
|
||||||
import gprMax.config as config
|
import gprMax.config as config
|
||||||
from gprMax.config import c
|
from .exceptions import GeneralError
|
||||||
from gprMax.config import floattype
|
from .pml import PML
|
||||||
from gprMax.config import complextype
|
from .utilities import fft_power
|
||||||
from gprMax.config import numdispersion
|
from .utilities import human_size
|
||||||
from gprMax.config import hostinfo
|
from .utilities import round_value
|
||||||
from gprMax.exceptions import GeneralError
|
|
||||||
from gprMax.materials import Material
|
|
||||||
from gprMax.pml import PML
|
|
||||||
from gprMax.utilities import fft_power
|
|
||||||
from gprMax.utilities import human_size
|
|
||||||
from gprMax.utilities import round_value
|
|
||||||
|
|
||||||
|
|
||||||
class Grid(object):
|
class Grid(object):
|
||||||
@@ -87,9 +81,6 @@ class FDTDGrid(Grid):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.inputfilename = ''
|
|
||||||
self.inputdirectory = ''
|
|
||||||
self.outputdirectory = ''
|
|
||||||
self.title = ''
|
self.title = ''
|
||||||
self.memoryusage = 0
|
self.memoryusage = 0
|
||||||
|
|
||||||
@@ -144,24 +135,24 @@ class FDTDGrid(Grid):
|
|||||||
|
|
||||||
def initialise_field_arrays(self):
|
def initialise_field_arrays(self):
|
||||||
"""Initialise arrays for the electric and magnetic field components."""
|
"""Initialise arrays for the electric and magnetic field components."""
|
||||||
self.Ex = np.zeros((self.nx + 1, self.ny + 1, self.nz + 1), dtype=floattype)
|
self.Ex = np.zeros((self.nx + 1, self.ny + 1, self.nz + 1), dtype=config.dtypes['float_or_double'])
|
||||||
self.Ey = np.zeros((self.nx + 1, self.ny + 1, self.nz + 1), dtype=floattype)
|
self.Ey = np.zeros((self.nx + 1, self.ny + 1, self.nz + 1), dtype=config.dtypes['float_or_double'])
|
||||||
self.Ez = np.zeros((self.nx + 1, self.ny + 1, self.nz + 1), dtype=floattype)
|
self.Ez = np.zeros((self.nx + 1, self.ny + 1, self.nz + 1), dtype=config.dtypes['float_or_double'])
|
||||||
self.Hx = np.zeros((self.nx + 1, self.ny + 1, self.nz + 1), dtype=floattype)
|
self.Hx = np.zeros((self.nx + 1, self.ny + 1, self.nz + 1), dtype=config.dtypes['float_or_double'])
|
||||||
self.Hy = np.zeros((self.nx + 1, self.ny + 1, self.nz + 1), dtype=floattype)
|
self.Hy = np.zeros((self.nx + 1, self.ny + 1, self.nz + 1), dtype=config.dtypes['float_or_double'])
|
||||||
self.Hz = np.zeros((self.nx + 1, self.ny + 1, self.nz + 1), dtype=floattype)
|
self.Hz = np.zeros((self.nx + 1, self.ny + 1, self.nz + 1), dtype=config.dtypes['float_or_double'])
|
||||||
|
|
||||||
def initialise_std_update_coeff_arrays(self):
|
def initialise_std_update_coeff_arrays(self):
|
||||||
"""Initialise arrays for storing update coefficients."""
|
"""Initialise arrays for storing update coefficients."""
|
||||||
self.updatecoeffsE = np.zeros((len(self.materials), 5), dtype=floattype)
|
self.updatecoeffsE = np.zeros((len(self.materials), 5), dtype=config.dtypes['float_or_double'])
|
||||||
self.updatecoeffsH = np.zeros((len(self.materials), 5), dtype=floattype)
|
self.updatecoeffsH = np.zeros((len(self.materials), 5), dtype=config.dtypes['float_or_double'])
|
||||||
|
|
||||||
def initialise_dispersive_arrays(self):
|
def initialise_dispersive_arrays(self, dtype):
|
||||||
"""Initialise arrays for storing coefficients when there are dispersive materials present."""
|
"""Initialise arrays for storing coefficients when there are dispersive materials present."""
|
||||||
self.Tx = np.zeros((Material.maxpoles, self.nx + 1, self.ny + 1, self.nz + 1), dtype=complextype)
|
self.Tx = np.zeros((config.materials['maxpoles'], self.nx + 1, self.ny + 1, self.nz + 1), dtype=dtype)
|
||||||
self.Ty = np.zeros((Material.maxpoles, self.nx + 1, self.ny + 1, self.nz + 1), dtype=complextype)
|
self.Ty = np.zeros((config.materials['maxpoles'], self.nx + 1, self.ny + 1, self.nz + 1), dtype=dtype)
|
||||||
self.Tz = np.zeros((Material.maxpoles, self.nx + 1, self.ny + 1, self.nz + 1), dtype=complextype)
|
self.Tz = np.zeros((config.materials['maxpoles'], self.nx + 1, self.ny + 1, self.nz + 1), dtype=dtype)
|
||||||
self.updatecoeffsdispersive = np.zeros((len(self.materials), 3 * Material.maxpoles), dtype=complextype)
|
self.updatecoeffsdispersive = np.zeros((len(self.materials), 3 * config.materials['maxpoles']), dtype=dtype)
|
||||||
|
|
||||||
def memory_estimate_basic(self):
|
def memory_estimate_basic(self):
|
||||||
"""Estimate the amount of memory (RAM) required to run a model."""
|
"""Estimate the amount of memory (RAM) required to run a model."""
|
||||||
@@ -174,7 +165,7 @@ class FDTDGrid(Grid):
|
|||||||
rigidarrays = (12 + 6) * self.nx * self.ny * self.nz * np.dtype(np.int8).itemsize
|
rigidarrays = (12 + 6) * self.nx * self.ny * self.nz * np.dtype(np.int8).itemsize
|
||||||
|
|
||||||
# 6 x field arrays + 6 x ID arrays
|
# 6 x field arrays + 6 x ID arrays
|
||||||
fieldarrays = (6 + 6) * (self.nx + 1) * (self.ny + 1) * (self.nz + 1) * np.dtype(floattype).itemsize
|
fieldarrays = (6 + 6) * (self.nx + 1) * (self.ny + 1) * (self.nz + 1) * np.dtype(config.dtypes['float_or_double']).itemsize
|
||||||
|
|
||||||
# PML arrays
|
# PML arrays
|
||||||
pmlarrays = 0
|
pmlarrays = 0
|
||||||
@@ -206,21 +197,21 @@ class FDTDGrid(Grid):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Check if model can be built and/or run on host
|
# Check if model can be built and/or run on host
|
||||||
if self.memoryusage > hostinfo['ram']:
|
if self.memoryusage > config.hostinfo['ram']:
|
||||||
raise GeneralError('Memory (RAM) required ~{} exceeds {} detected!\n'.format(human_size(self.memoryusage), human_size(hostinfo['ram'], a_kilobyte_is_1024_bytes=True)))
|
raise GeneralError('Memory (RAM) required ~{} exceeds {} detected!\n'.format(human_size(self.memoryusage), human_size(config.hostinfo['ram'], a_kilobyte_is_1024_bytes=True)))
|
||||||
|
|
||||||
# Check if model can be run on specified GPU if required
|
# Check if model can be run on specified GPU if required
|
||||||
if config.gpus is not None:
|
if config.cuda['gpus'] is not None:
|
||||||
if self.memoryusage - snapsmemsize > config.gpus.totalmem:
|
if self.memoryusage - snapsmemsize > config.cuda['gpus'].totalmem:
|
||||||
raise GeneralError('Memory (RAM) required ~{} exceeds {} detected on specified {} - {} GPU!\n'.format(human_size(self.memoryusage), human_size(config.gpus.totalmem, a_kilobyte_is_1024_bytes=True), config.gpus.deviceID, config.gpus.name))
|
raise GeneralError('Memory (RAM) required ~{} exceeds {} detected on specified {} - {} GPU!\n'.format(human_size(self.memoryusage), human_size(config.cuda['gpus'].totalmem, a_kilobyte_is_1024_bytes=True), config.cuda['gpus'].deviceID, config.cuda['gpus'].name))
|
||||||
|
|
||||||
# If the required memory without the snapshots will fit on the GPU then transfer and store snaphots on host
|
# If the required memory without the snapshots will fit on the GPU then transfer and store snaphots on host
|
||||||
if snapsmemsize != 0 and self.memoryusage - snapsmemsize < config.gpus.totalmem:
|
if snapsmemsize != 0 and self.memoryusage - snapsmemsize < config.cuda['gpus'].totalmem:
|
||||||
config.snapsgpu2cpu = True
|
config.cuda['snapsgpu2cpu'] = True
|
||||||
|
|
||||||
def gpu_set_blocks_per_grid(self):
|
def gpu_set_blocks_per_grid(self):
|
||||||
"""Set the blocks per grid size used for updating the electric and magnetic field arrays on a GPU."""
|
"""Set the blocks per grid size used for updating the electric and magnetic field arrays on a GPU."""
|
||||||
config.gpus.bpg = (int(np.ceil(((self.nx + 1) * (self.ny + 1) * (self.nz + 1)) / config.gpus.tpb[0])), 1, 1)
|
config.cuda['gpus'].bpg = (int(np.ceil(((self.nx + 1) * (self.ny + 1) * (self.nz + 1)) / config.cuda['gpus'].tpb[0])), 1, 1)
|
||||||
|
|
||||||
def gpu_initialise_arrays(self):
|
def gpu_initialise_arrays(self):
|
||||||
"""Initialise standard field arrays on GPU."""
|
"""Initialise standard field arrays on GPU."""
|
||||||
@@ -298,7 +289,7 @@ def dispersion_analysis(G):
|
|||||||
|
|
||||||
# Set maximum frequency to a threshold drop from maximum power, ignoring DC value
|
# Set maximum frequency to a threshold drop from maximum power, ignoring DC value
|
||||||
try:
|
try:
|
||||||
freqthres = np.where(power[freqmaxpower:] < -numdispersion['highestfreqthres'])[0][0] + freqmaxpower
|
freqthres = np.where(power[freqmaxpower:] < -config.numdispersion['highestfreqthres'])[0][0] + freqmaxpower
|
||||||
results['maxfreq'].append(freqs[freqthres])
|
results['maxfreq'].append(freqs[freqthres])
|
||||||
except ValueError:
|
except ValueError:
|
||||||
results['error'] = 'unable to calculate maximum power from waveform, most likely due to undersampling.'
|
results['error'] = 'unable to calculate maximum power from waveform, most likely due to undersampling.'
|
||||||
@@ -324,7 +315,7 @@ def dispersion_analysis(G):
|
|||||||
er = x.er
|
er = x.er
|
||||||
# If there are dispersive materials calculate the complex relative permittivity
|
# If there are dispersive materials calculate the complex relative permittivity
|
||||||
# at maximum frequency and take the real part
|
# at maximum frequency and take the real part
|
||||||
if x.poles > 0:
|
if x.__class__.__name__ is 'DispersiveMaterial':
|
||||||
er = x.calculate_er(results['maxfreq'])
|
er = x.calculate_er(results['maxfreq'])
|
||||||
er = er.real
|
er = er.real
|
||||||
if er > maxer:
|
if er > maxer:
|
||||||
@@ -333,7 +324,7 @@ def dispersion_analysis(G):
|
|||||||
results['material'] = next(x for x in G.materials if x.ID == matmaxer)
|
results['material'] = next(x for x in G.materials if x.ID == matmaxer)
|
||||||
|
|
||||||
# Minimum velocity
|
# Minimum velocity
|
||||||
minvelocity = c / np.sqrt(maxer)
|
minvelocity = config.c / np.sqrt(maxer)
|
||||||
|
|
||||||
# Minimum wavelength
|
# Minimum wavelength
|
||||||
minwavelength = minvelocity / results['maxfreq']
|
minwavelength = minvelocity / results['maxfreq']
|
||||||
@@ -350,18 +341,18 @@ def dispersion_analysis(G):
|
|||||||
delta = max(G.dx, G.dy)
|
delta = max(G.dx, G.dy)
|
||||||
|
|
||||||
# Courant stability factor
|
# Courant stability factor
|
||||||
S = (c * G.dt) / delta
|
S = (config.c * G.dt) / delta
|
||||||
|
|
||||||
# Grid sampling density
|
# Grid sampling density
|
||||||
results['N'] = minwavelength / delta
|
results['N'] = minwavelength / delta
|
||||||
|
|
||||||
# Check grid sampling will result in physical wave propagation
|
# Check grid sampling will result in physical wave propagation
|
||||||
if int(np.floor(results['N'])) >= numdispersion['mingridsampling']:
|
if int(np.floor(results['N'])) >= config.numdispersion['mingridsampling']:
|
||||||
# Numerical phase velocity
|
# Numerical phase velocity
|
||||||
vp = np.pi / (results['N'] * np.arcsin((1 / S) * np.sin((np.pi * S) / results['N'])))
|
vp = np.pi / (results['N'] * np.arcsin((1 / S) * np.sin((np.pi * S) / results['N'])))
|
||||||
|
|
||||||
# Physical phase velocity error (percentage)
|
# Physical phase velocity error (percentage)
|
||||||
results['deltavp'] = (((vp * c) - c) / c) * 100
|
results['deltavp'] = (((vp * config.c) - config.c) / config.c) * 100
|
||||||
|
|
||||||
# Store rounded down value of grid sampling density
|
# Store rounded down value of grid sampling density
|
||||||
results['N'] = int(np.floor(results['N']))
|
results['N'] = int(np.floor(results['N']))
|
||||||
@@ -369,21 +360,6 @@ def dispersion_analysis(G):
|
|||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
||||||
def get_other_directions(direction):
|
|
||||||
"""Return the two other directions from x, y, z given a single direction
|
|
||||||
|
|
||||||
Args:
|
|
||||||
direction (str): Component x, y or z
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
(tuple): Two directions from x, y, z
|
|
||||||
"""
|
|
||||||
|
|
||||||
directions = {'x': ('y', 'z'), 'y': ('x', 'z'), 'z': ('x', 'y')}
|
|
||||||
|
|
||||||
return directions[direction]
|
|
||||||
|
|
||||||
|
|
||||||
def Ix(x, y, z, Hx, Hy, Hz, G):
|
def Ix(x, y, z, Hx, Hy, Hz, G):
|
||||||
"""Calculates the x-component of current at a grid position.
|
"""Calculates the x-component of current at a grid position.
|
||||||
|
|
||||||
|
@@ -20,7 +20,7 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
|
|
||||||
from gprMax.exceptions import CmdInputError
|
from .exceptions import CmdInputError
|
||||||
|
|
||||||
|
|
||||||
def process_python_include_code(inputfile, usernamespace):
|
def process_python_include_code(inputfile, usernamespace):
|
||||||
@@ -151,7 +151,7 @@ def process_include_files(hashcmds, inputfile):
|
|||||||
return processedincludecmds
|
return processedincludecmds
|
||||||
|
|
||||||
|
|
||||||
def write_processed_file(processedlines, appendmodelnumber, G):
|
def write_processed_file(processedlines, appendmodelnumber):
|
||||||
"""
|
"""
|
||||||
Writes an input file after any Python code and include commands
|
Writes an input file after any Python code and include commands
|
||||||
in the original input file have been processed.
|
in the original input file have been processed.
|
||||||
@@ -160,10 +160,9 @@ def write_processed_file(processedlines, appendmodelnumber, G):
|
|||||||
processedlines (list): Input commands after after processing any
|
processedlines (list): Input commands after after processing any
|
||||||
Python code and include commands.
|
Python code and include commands.
|
||||||
appendmodelnumber (str): Text to append to filename.
|
appendmodelnumber (str): Text to append to filename.
|
||||||
G (class): Grid class instance - holds essential parameters describing the model.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
processedfile = os.path.join(G.inputdirectory, os.path.splitext(G.inputfilename)[0] + appendmodelnumber + '_processed.in')
|
processedfile = os.path.join(outputfilepath, os.path.splitext(inputfilepath)[0] + appendmodelnumber + '_processed.in')
|
||||||
|
|
||||||
with open(processedfile, 'w') as f:
|
with open(processedfile, 'w') as f:
|
||||||
for item in processedlines:
|
for item in processedlines:
|
||||||
|
@@ -23,31 +23,30 @@ import h5py
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
from gprMax.config import floattype
|
import gprMax.config as config
|
||||||
from gprMax.config import messages
|
|
||||||
from gprMax.config import progressbars
|
from .input_cmds_file import check_cmd_names
|
||||||
from gprMax.input_cmds_file import check_cmd_names
|
from .input_cmds_multiuse import process_multicmds
|
||||||
from gprMax.input_cmds_multiuse import process_multicmds
|
from .exceptions import CmdInputError
|
||||||
from gprMax.exceptions import CmdInputError
|
from .fractals import FractalSurface
|
||||||
from gprMax.fractals import FractalSurface
|
from .fractals import FractalVolume
|
||||||
from gprMax.fractals import FractalVolume
|
from .fractals import Grass
|
||||||
from gprMax.fractals import Grass
|
from .cython.geometry_primitives import build_edge_x
|
||||||
from gprMax.cython.geometry_primitives import build_edge_x
|
from .cython.geometry_primitives import build_edge_y
|
||||||
from gprMax.cython.geometry_primitives import build_edge_y
|
from .cython.geometry_primitives import build_edge_z
|
||||||
from gprMax.cython.geometry_primitives import build_edge_z
|
from .cython.geometry_primitives import build_face_yz
|
||||||
from gprMax.cython.geometry_primitives import build_face_yz
|
from .cython.geometry_primitives import build_face_xz
|
||||||
from gprMax.cython.geometry_primitives import build_face_xz
|
from .cython.geometry_primitives import build_face_xy
|
||||||
from gprMax.cython.geometry_primitives import build_face_xy
|
from .cython.geometry_primitives import build_triangle
|
||||||
from gprMax.cython.geometry_primitives import build_triangle
|
from .cython.geometry_primitives import build_box
|
||||||
from gprMax.cython.geometry_primitives import build_box
|
from .cython.geometry_primitives import build_cylinder
|
||||||
from gprMax.cython.geometry_primitives import build_cylinder
|
from .cython.geometry_primitives import build_cylindrical_sector
|
||||||
from gprMax.cython.geometry_primitives import build_cylindrical_sector
|
from .cython.geometry_primitives import build_sphere
|
||||||
from gprMax.cython.geometry_primitives import build_sphere
|
from .cython.geometry_primitives import build_voxels_from_array
|
||||||
from gprMax.cython.geometry_primitives import build_voxels_from_array
|
from .cython.geometry_primitives import build_voxels_from_array_mask
|
||||||
from gprMax.cython.geometry_primitives import build_voxels_from_array_mask
|
from .materials import Material
|
||||||
from gprMax.materials import Material
|
from .utilities import round_value
|
||||||
from gprMax.utilities import round_value
|
from .utilities import get_terminal_width
|
||||||
from gprMax.utilities import get_terminal_width
|
|
||||||
|
|
||||||
|
|
||||||
def process_geometrycmds(geometry, G):
|
def process_geometrycmds(geometry, G):
|
||||||
@@ -63,9 +62,9 @@ def process_geometrycmds(geometry, G):
|
|||||||
# Disable progress bar if on Windows as it does not update properly
|
# Disable progress bar if on Windows as it does not update properly
|
||||||
# when messages are printed for geometry
|
# when messages are printed for geometry
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
progressbarsgeo = False
|
progressbarsgeo = True
|
||||||
else:
|
else:
|
||||||
progressbarsgeo = not progressbars
|
progressbarsgeo = not config.general['progressbars']
|
||||||
|
|
||||||
for object in tqdm(geometry, desc='Processing geometry related cmds', unit='cmds', ncols=get_terminal_width() - 1, file=sys.stdout, disable=progressbarsgeo):
|
for object in tqdm(geometry, desc='Processing geometry related cmds', unit='cmds', ncols=get_terminal_width() - 1, file=sys.stdout, disable=progressbarsgeo):
|
||||||
tmp = object.split()
|
tmp = object.split()
|
||||||
@@ -137,12 +136,12 @@ def process_geometrycmds(geometry, G):
|
|||||||
G.rigidE[:, xs:xs + rigidE.shape[1], ys:ys + rigidE.shape[2], zs:zs + rigidE.shape[3]] = rigidE
|
G.rigidE[:, xs:xs + rigidE.shape[1], ys:ys + rigidE.shape[2], zs:zs + rigidE.shape[3]] = rigidE
|
||||||
G.rigidH[:, xs:xs + rigidH.shape[1], ys:ys + rigidH.shape[2], zs:zs + rigidH.shape[3]] = rigidH
|
G.rigidH[:, xs:xs + rigidH.shape[1], ys:ys + rigidH.shape[2], zs:zs + rigidH.shape[3]] = rigidH
|
||||||
G.ID[:, xs:xs + ID.shape[1], ys:ys + ID.shape[2], zs:zs + ID.shape[3]] = ID + numexistmaterials
|
G.ID[:, xs:xs + ID.shape[1], ys:ys + ID.shape[2], zs:zs + ID.shape[3]] = ID + numexistmaterials
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
tqdm.write('Geometry objects from file {} inserted at {:g}m, {:g}m, {:g}m, with corresponding materials file {}.'.format(geofile, xs * G.dx, ys * G.dy, zs * G.dz, matfile))
|
tqdm.write('Geometry objects from file {} inserted at {:g}m, {:g}m, {:g}m, with corresponding materials file {}.'.format(geofile, xs * G.dx, ys * G.dy, zs * G.dz, matfile))
|
||||||
except KeyError:
|
except KeyError:
|
||||||
averaging = False
|
averaging = False
|
||||||
build_voxels_from_array(xs, ys, zs, numexistmaterials, averaging, data, G.solid, G.rigidE, G.rigidH, G.ID)
|
build_voxels_from_array(xs, ys, zs, numexistmaterials, averaging, data, G.solid, G.rigidE, G.rigidH, G.ID)
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
tqdm.write('Geometry objects from file (voxels only) {} inserted at {:g}m, {:g}m, {:g}m, with corresponding materials file {}.'.format(geofile, xs * G.dx, ys * G.dy, zs * G.dz, matfile))
|
tqdm.write('Geometry objects from file (voxels only) {} inserted at {:g}m, {:g}m, {:g}m, with corresponding materials file {}.'.format(geofile, xs * G.dx, ys * G.dy, zs * G.dz, matfile))
|
||||||
|
|
||||||
elif tmp[0] == '#edge:':
|
elif tmp[0] == '#edge:':
|
||||||
@@ -201,7 +200,7 @@ def process_geometrycmds(geometry, G):
|
|||||||
for k in range(zs, zf):
|
for k in range(zs, zf):
|
||||||
build_edge_z(xs, ys, k, material.numID, G.rigidE, G.rigidH, G.ID)
|
build_edge_z(xs, ys, k, material.numID, G.rigidE, G.rigidH, G.ID)
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
tqdm.write('Edge from {:g}m, {:g}m, {:g}m, to {:g}m, {:g}m, {:g}m of material {} created.'.format(xs * G.dx, ys * G.dy, zs * G.dz, xf * G.dx, yf * G.dy, zf * G.dz, tmp[7]))
|
tqdm.write('Edge from {:g}m, {:g}m, {:g}m, to {:g}m, {:g}m, {:g}m of material {} created.'.format(xs * G.dx, ys * G.dy, zs * G.dz, xf * G.dx, yf * G.dy, zf * G.dz, tmp[7]))
|
||||||
|
|
||||||
elif tmp[0] == '#plate:':
|
elif tmp[0] == '#plate:':
|
||||||
@@ -309,7 +308,7 @@ def process_geometrycmds(geometry, G):
|
|||||||
for j in range(ys, yf):
|
for j in range(ys, yf):
|
||||||
build_face_xy(i, j, zs, numIDx, numIDy, G.rigidE, G.rigidH, G.ID)
|
build_face_xy(i, j, zs, numIDx, numIDy, G.rigidE, G.rigidH, G.ID)
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
tqdm.write('Plate from {:g}m, {:g}m, {:g}m, to {:g}m, {:g}m, {:g}m of material(s) {} created.'.format(xs * G.dx, ys * G.dy, zs * G.dz, xf * G.dx, yf * G.dy, zf * G.dz, ', '.join(materialsrequested)))
|
tqdm.write('Plate from {:g}m, {:g}m, {:g}m, to {:g}m, {:g}m, {:g}m of material(s) {} created.'.format(xs * G.dx, ys * G.dy, zs * G.dz, xf * G.dx, yf * G.dy, zf * G.dz, ', '.join(materialsrequested)))
|
||||||
|
|
||||||
elif tmp[0] == '#triangle:':
|
elif tmp[0] == '#triangle:':
|
||||||
@@ -422,7 +421,7 @@ def process_geometrycmds(geometry, G):
|
|||||||
|
|
||||||
build_triangle(x1, y1, z1, x2, y2, z2, x3, y3, z3, normal, thickness, G.dx, G.dy, G.dz, numID, numIDx, numIDy, numIDz, averaging, G.solid, G.rigidE, G.rigidH, G.ID)
|
build_triangle(x1, y1, z1, x2, y2, z2, x3, y3, z3, normal, thickness, G.dx, G.dy, G.dz, numID, numIDx, numIDy, numIDz, averaging, G.solid, G.rigidE, G.rigidH, G.ID)
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
if thickness > 0:
|
if thickness > 0:
|
||||||
if averaging:
|
if averaging:
|
||||||
dielectricsmoothing = 'on'
|
dielectricsmoothing = 'on'
|
||||||
@@ -517,7 +516,7 @@ def process_geometrycmds(geometry, G):
|
|||||||
|
|
||||||
build_box(xs, xf, ys, yf, zs, zf, numID, numIDx, numIDy, numIDz, averaging, G.solid, G.rigidE, G.rigidH, G.ID)
|
build_box(xs, xf, ys, yf, zs, zf, numID, numIDx, numIDy, numIDz, averaging, G.solid, G.rigidE, G.rigidH, G.ID)
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
if averaging:
|
if averaging:
|
||||||
dielectricsmoothing = 'on'
|
dielectricsmoothing = 'on'
|
||||||
else:
|
else:
|
||||||
@@ -598,7 +597,7 @@ def process_geometrycmds(geometry, G):
|
|||||||
|
|
||||||
build_cylinder(x1, y1, z1, x2, y2, z2, r, G.dx, G.dy, G.dz, numID, numIDx, numIDy, numIDz, averaging, G.solid, G.rigidE, G.rigidH, G.ID)
|
build_cylinder(x1, y1, z1, x2, y2, z2, r, G.dx, G.dy, G.dz, numID, numIDx, numIDy, numIDz, averaging, G.solid, G.rigidE, G.rigidH, G.ID)
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
if averaging:
|
if averaging:
|
||||||
dielectricsmoothing = 'on'
|
dielectricsmoothing = 'on'
|
||||||
else:
|
else:
|
||||||
@@ -719,7 +718,7 @@ def process_geometrycmds(geometry, G):
|
|||||||
|
|
||||||
build_cylindrical_sector(ctr1, ctr2, level, sectorstartangle, sectorangle, r, normal, thickness, G.dx, G.dy, G.dz, numID, numIDx, numIDy, numIDz, averaging, G.solid, G.rigidE, G.rigidH, G.ID)
|
build_cylindrical_sector(ctr1, ctr2, level, sectorstartangle, sectorangle, r, normal, thickness, G.dx, G.dy, G.dz, numID, numIDx, numIDy, numIDz, averaging, G.solid, G.rigidE, G.rigidH, G.ID)
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
if thickness > 0:
|
if thickness > 0:
|
||||||
if averaging:
|
if averaging:
|
||||||
dielectricsmoothing = 'on'
|
dielectricsmoothing = 'on'
|
||||||
@@ -798,7 +797,7 @@ def process_geometrycmds(geometry, G):
|
|||||||
|
|
||||||
build_sphere(xc, yc, zc, r, G.dx, G.dy, G.dz, numID, numIDx, numIDy, numIDz, averaging, G.solid, G.rigidE, G.rigidH, G.ID)
|
build_sphere(xc, yc, zc, r, G.dx, G.dy, G.dz, numID, numIDx, numIDy, numIDz, averaging, G.solid, G.rigidE, G.rigidH, G.ID)
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
if averaging:
|
if averaging:
|
||||||
dielectricsmoothing = 'on'
|
dielectricsmoothing = 'on'
|
||||||
else:
|
else:
|
||||||
@@ -879,7 +878,7 @@ def process_geometrycmds(geometry, G):
|
|||||||
volume.weighting = np.array([float(tmp[8]), float(tmp[9]), float(tmp[10])])
|
volume.weighting = np.array([float(tmp[8]), float(tmp[9]), float(tmp[10])])
|
||||||
volume.averaging = averagefractalbox
|
volume.averaging = averagefractalbox
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
if volume.averaging:
|
if volume.averaging:
|
||||||
dielectricsmoothing = 'on'
|
dielectricsmoothing = 'on'
|
||||||
else:
|
else:
|
||||||
@@ -1002,7 +1001,7 @@ def process_geometrycmds(geometry, G):
|
|||||||
surface.generate_fractal_surface(G)
|
surface.generate_fractal_surface(G)
|
||||||
volume.fractalsurfaces.append(surface)
|
volume.fractalsurfaces.append(surface)
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
tqdm.write('Fractal surface from {:g}m, {:g}m, {:g}m, to {:g}m, {:g}m, {:g}m with fractal dimension {:g}, fractal weightings {:g}, {:g}, fractal seeding {}, and range {:g}m to {:g}m, added to {}.'.format(xs * G.dx, ys * G.dy, zs * G.dz, xf * G.dx, yf * G.dy, zf * G.dz, surface.dimension, surface.weighting[0], surface.weighting[1], surface.seed, float(tmp[10]), float(tmp[11]), surface.operatingonID))
|
tqdm.write('Fractal surface from {:g}m, {:g}m, {:g}m, to {:g}m, {:g}m, {:g}m with fractal dimension {:g}, fractal weightings {:g}, {:g}, fractal seeding {}, and range {:g}m to {:g}m, added to {}.'.format(xs * G.dx, ys * G.dy, zs * G.dz, xf * G.dx, yf * G.dy, zf * G.dz, surface.dimension, surface.weighting[0], surface.weighting[1], surface.seed, float(tmp[10]), float(tmp[11]), surface.operatingonID))
|
||||||
|
|
||||||
if tmp[0] == '#add_surface_water:':
|
if tmp[0] == '#add_surface_water:':
|
||||||
@@ -1110,7 +1109,7 @@ def process_geometrycmds(geometry, G):
|
|||||||
if testwater:
|
if testwater:
|
||||||
raise CmdInputError("'" + ' '.join(tmp) + "'" + ' requires the time step for the model to be less than the relaxation time required to model water.')
|
raise CmdInputError("'" + ' '.join(tmp) + "'" + ' requires the time step for the model to be less than the relaxation time required to model water.')
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
tqdm.write('Water on surface from {:g}m, {:g}m, {:g}m, to {:g}m, {:g}m, {:g}m with depth {:g}m, added to {}.'.format(xs * G.dx, ys * G.dy, zs * G.dz, xf * G.dx, yf * G.dy, zf * G.dz, filldepth, surface.operatingonID))
|
tqdm.write('Water on surface from {:g}m, {:g}m, {:g}m, to {:g}m, {:g}m, {:g}m with depth {:g}m, added to {}.'.format(xs * G.dx, ys * G.dy, zs * G.dz, xf * G.dx, yf * G.dy, zf * G.dz, filldepth, surface.operatingonID))
|
||||||
|
|
||||||
if tmp[0] == '#add_grass:':
|
if tmp[0] == '#add_grass:':
|
||||||
@@ -1260,7 +1259,7 @@ def process_geometrycmds(geometry, G):
|
|||||||
|
|
||||||
volume.fractalsurfaces.append(surface)
|
volume.fractalsurfaces.append(surface)
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
tqdm.write('{} blades of grass on surface from {:g}m, {:g}m, {:g}m, to {:g}m, {:g}m, {:g}m with fractal dimension {:g}, fractal seeding {}, and range {:g}m to {:g}m, added to {}.'.format(numblades, xs * G.dx, ys * G.dy, zs * G.dz, xf * G.dx, yf * G.dy, zf * G.dz, surface.dimension, surface.seed, float(tmp[8]), float(tmp[9]), surface.operatingonID))
|
tqdm.write('{} blades of grass on surface from {:g}m, {:g}m, {:g}m, to {:g}m, {:g}m, {:g}m with fractal dimension {:g}, fractal seeding {}, and range {:g}m to {:g}m, added to {}.'.format(numblades, xs * G.dx, ys * G.dy, zs * G.dz, xf * G.dx, yf * G.dy, zf * G.dz, surface.dimension, surface.seed, float(tmp[8]), float(tmp[9]), surface.operatingonID))
|
||||||
|
|
||||||
# Process any modifications to the original fractal box then generate it
|
# Process any modifications to the original fractal box then generate it
|
||||||
@@ -1301,7 +1300,7 @@ def process_geometrycmds(geometry, G):
|
|||||||
|
|
||||||
# If there is only 1 bin then a normal material is being used, otherwise a mixing model
|
# If there is only 1 bin then a normal material is being used, otherwise a mixing model
|
||||||
if volume.nbins == 1:
|
if volume.nbins == 1:
|
||||||
volume.fractalvolume = np.ones((volume.nx, volume.ny, volume.nz), dtype=floattype)
|
volume.fractalvolume = np.ones((volume.nx, volume.ny, volume.nz), dtype=config.dtypes['float_or_double'])
|
||||||
materialnumID = next(x.numID for x in G.materials if x.ID == volume.operatingonID)
|
materialnumID = next(x.numID for x in G.materials if x.ID == volume.operatingonID)
|
||||||
volume.fractalvolume *= materialnumID
|
volume.fractalvolume *= materialnumID
|
||||||
else:
|
else:
|
||||||
|
@@ -20,30 +20,27 @@ from colorama import init
|
|||||||
from colorama import Fore
|
from colorama import Fore
|
||||||
from colorama import Style
|
from colorama import Style
|
||||||
init()
|
init()
|
||||||
|
from copy import deepcopy
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
import gprMax.config as config
|
import gprMax.config as config
|
||||||
from gprMax.config import z0
|
from .exceptions import CmdInputError
|
||||||
from gprMax.config import floattype
|
from .geometry_outputs import GeometryView
|
||||||
from gprMax.config import gpus
|
from .geometry_outputs import GeometryObjects
|
||||||
from gprMax.config import messages
|
from .materials import DispersiveMaterial
|
||||||
|
from .materials import Material
|
||||||
from gprMax.exceptions import CmdInputError
|
from .materials import PeplinskiSoil
|
||||||
from gprMax.geometry_outputs import GeometryView
|
from .pml import CFSParameter
|
||||||
from gprMax.geometry_outputs import GeometryObjects
|
from .pml import CFS
|
||||||
from gprMax.materials import Material
|
from .receivers import Rx
|
||||||
from gprMax.materials import PeplinskiSoil
|
from .snapshots import Snapshot
|
||||||
from gprMax.pml import CFSParameter
|
from .sources import VoltageSource
|
||||||
from gprMax.pml import CFS
|
from .sources import HertzianDipole
|
||||||
from gprMax.receivers import Rx
|
from .sources import MagneticDipole
|
||||||
from gprMax.snapshots import Snapshot
|
from .sources import TransmissionLine
|
||||||
from gprMax.sources import VoltageSource
|
from .utilities import round_value
|
||||||
from gprMax.sources import HertzianDipole
|
from .waveforms import Waveform
|
||||||
from gprMax.sources import MagneticDipole
|
|
||||||
from gprMax.sources import TransmissionLine
|
|
||||||
from gprMax.utilities import round_value
|
|
||||||
from gprMax.waveforms import Waveform
|
|
||||||
|
|
||||||
|
|
||||||
def process_multicmds(multicmds, G):
|
def process_multicmds(multicmds, G):
|
||||||
@@ -84,7 +81,7 @@ def process_multicmds(multicmds, G):
|
|||||||
w.amp = float(tmp[1])
|
w.amp = float(tmp[1])
|
||||||
w.freq = float(tmp[2])
|
w.freq = float(tmp[2])
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
print('Waveform {} of type {} with maximum amplitude scaling {:g}, frequency {:g}Hz created.'.format(w.ID, w.type, w.amp, w.freq))
|
print('Waveform {} of type {} with maximum amplitude scaling {:g}, frequency {:g}Hz created.'.format(w.ID, w.type, w.amp, w.freq))
|
||||||
|
|
||||||
G.waveforms.append(w)
|
G.waveforms.append(w)
|
||||||
@@ -155,7 +152,7 @@ def process_multicmds(multicmds, G):
|
|||||||
|
|
||||||
v.calculate_waveform_values(G)
|
v.calculate_waveform_values(G)
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
print('Voltage source with polarity {} at {:g}m, {:g}m, {:g}m, resistance {:.1f} Ohms,'.format(v.polarisation, v.xcoord * G.dx, v.ycoord * G.dy, v.zcoord * G.dz, v.resistance) + startstop + 'using waveform {} created.'.format(v.waveformID))
|
print('Voltage source with polarity {} at {:g}m, {:g}m, {:g}m, resistance {:.1f} Ohms,'.format(v.polarisation, v.xcoord * G.dx, v.ycoord * G.dy, v.zcoord * G.dz, v.resistance) + startstop + 'using waveform {} created.'.format(v.waveformID))
|
||||||
|
|
||||||
G.voltagesources.append(v)
|
G.voltagesources.append(v)
|
||||||
@@ -233,7 +230,7 @@ def process_multicmds(multicmds, G):
|
|||||||
|
|
||||||
h.calculate_waveform_values(G)
|
h.calculate_waveform_values(G)
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
if '2D' in config.mode:
|
if '2D' in config.mode:
|
||||||
print('Hertzian dipole is a line source in 2D with polarity {} at {:g}m, {:g}m, {:g}m,'.format(h.polarisation, h.xcoord * G.dx, h.ycoord * G.dy, h.zcoord * G.dz) + startstop + 'using waveform {} created.'.format(h.waveformID))
|
print('Hertzian dipole is a line source in 2D with polarity {} at {:g}m, {:g}m, {:g}m,'.format(h.polarisation, h.xcoord * G.dx, h.ycoord * G.dy, h.zcoord * G.dz) + startstop + 'using waveform {} created.'.format(h.waveformID))
|
||||||
else:
|
else:
|
||||||
@@ -305,7 +302,7 @@ def process_multicmds(multicmds, G):
|
|||||||
|
|
||||||
m.calculate_waveform_values(G)
|
m.calculate_waveform_values(G)
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
print('Magnetic dipole with polarity {} at {:g}m, {:g}m, {:g}m,'.format(m.polarisation, m.xcoord * G.dx, m.ycoord * G.dy, m.zcoord * G.dz) + startstop + 'using waveform {} created.'.format(m.waveformID))
|
print('Magnetic dipole with polarity {} at {:g}m, {:g}m, {:g}m,'.format(m.polarisation, m.xcoord * G.dx, m.ycoord * G.dy, m.zcoord * G.dz) + startstop + 'using waveform {} created.'.format(m.waveformID))
|
||||||
|
|
||||||
G.magneticdipoles.append(m)
|
G.magneticdipoles.append(m)
|
||||||
@@ -341,7 +338,7 @@ def process_multicmds(multicmds, G):
|
|||||||
check_coordinates(xcoord, ycoord, zcoord)
|
check_coordinates(xcoord, ycoord, zcoord)
|
||||||
if xcoord < G.pmlthickness['x0'] or xcoord > G.nx - G.pmlthickness['xmax'] or ycoord < G.pmlthickness['y0'] or ycoord > G.ny - G.pmlthickness['ymax'] or zcoord < G.pmlthickness['z0'] or zcoord > G.nz - G.pmlthickness['zmax']:
|
if xcoord < G.pmlthickness['x0'] or xcoord > G.nx - G.pmlthickness['xmax'] or ycoord < G.pmlthickness['y0'] or ycoord > G.ny - G.pmlthickness['ymax'] or zcoord < G.pmlthickness['z0'] or zcoord > G.nz - G.pmlthickness['zmax']:
|
||||||
print(Fore.RED + "WARNING: '" + cmdname + ': ' + ' '.join(tmp) + "'" + ' sources and receivers should not normally be positioned within the PML.' + Style.RESET_ALL)
|
print(Fore.RED + "WARNING: '" + cmdname + ': ' + ' '.join(tmp) + "'" + ' sources and receivers should not normally be positioned within the PML.' + Style.RESET_ALL)
|
||||||
if resistance <= 0 or resistance >= z0:
|
if resistance <= 0 or resistance >= config.z0:
|
||||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires a resistance greater than zero and less than the impedance of free space, i.e. 376.73 Ohms')
|
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires a resistance greater than zero and less than the impedance of free space, i.e. 376.73 Ohms')
|
||||||
|
|
||||||
# Check if there is a waveformID in the waveforms list
|
# Check if there is a waveformID in the waveforms list
|
||||||
@@ -381,7 +378,7 @@ def process_multicmds(multicmds, G):
|
|||||||
t.calculate_waveform_values(G)
|
t.calculate_waveform_values(G)
|
||||||
t.calculate_incident_V_I(G)
|
t.calculate_incident_V_I(G)
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
print('Transmission line with polarity {} at {:g}m, {:g}m, {:g}m, resistance {:.1f} Ohms,'.format(t.polarisation, t.xcoord * G.dx, t.ycoord * G.dy, t.zcoord * G.dz, t.resistance) + startstop + 'using waveform {} created.'.format(t.waveformID))
|
print('Transmission line with polarity {} at {:g}m, {:g}m, {:g}m, resistance {:.1f} Ohms,'.format(t.polarisation, t.xcoord * G.dx, t.ycoord * G.dy, t.zcoord * G.dz, t.resistance) + startstop + 'using waveform {} created.'.format(t.waveformID))
|
||||||
|
|
||||||
G.transmissionlines.append(t)
|
G.transmissionlines.append(t)
|
||||||
@@ -413,23 +410,30 @@ def process_multicmds(multicmds, G):
|
|||||||
# If no ID or outputs are specified, use default
|
# If no ID or outputs are specified, use default
|
||||||
if len(tmp) == 3:
|
if len(tmp) == 3:
|
||||||
r.ID = r.__class__.__name__ + '(' + str(r.xcoord) + ',' + str(r.ycoord) + ',' + str(r.zcoord) + ')'
|
r.ID = r.__class__.__name__ + '(' + str(r.xcoord) + ',' + str(r.ycoord) + ',' + str(r.zcoord) + ')'
|
||||||
|
|
||||||
for key in Rx.defaultoutputs:
|
for key in Rx.defaultoutputs:
|
||||||
r.outputs[key] = np.zeros(G.iterations, dtype=floattype)
|
r.outputs[key] = np.zeros(G.iterations, dtype=config.dtypes['float_or_double'])
|
||||||
else:
|
else:
|
||||||
r.ID = tmp[3]
|
r.ID = tmp[3]
|
||||||
# Get allowable outputs
|
# Get allowable outputs
|
||||||
if gpus is not None:
|
if config.cuda['gpus'] is not None:
|
||||||
allowableoutputs = Rx.gpu_allowableoutputs
|
allowableoutputs = Rx.gpu_allowableoutputs
|
||||||
else:
|
else:
|
||||||
allowableoutputs = Rx.allowableoutputs
|
allowableoutputs = Rx.allowableoutputs
|
||||||
# Check and add field output names
|
# Check, sort and add field output names
|
||||||
for field in tmp[4::]:
|
fieldnames = tmp[4::]
|
||||||
|
fieldnames = sorted(fieldnames, key=lambda x: allowableoutputs.index(x))
|
||||||
|
for field in fieldnames:
|
||||||
if field in allowableoutputs:
|
if field in allowableoutputs:
|
||||||
r.outputs[field] = np.zeros(G.iterations, dtype=floattype)
|
r.outputs[field] = np.zeros(G.iterations, dtype=config.dtypes['float_or_double'])
|
||||||
else:
|
else:
|
||||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' contains an output type that is not allowable. Allowable outputs in current context are {}'.format(allowableoutputs))
|
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' contains an output type that is not allowable. Allowable outputs in current context are {}'.format(allowableoutputs))
|
||||||
|
|
||||||
if messages:
|
# Keep track of maximum number of field outputs on a receiver
|
||||||
|
if len(r.outputs) > Rx.maxnumoutputs:
|
||||||
|
Rx.maxnumoutputs = len(r.outputs)
|
||||||
|
|
||||||
|
if config.general['messages']:
|
||||||
print('Receiver at {:g}m, {:g}m, {:g}m with output component(s) {} created.'.format(r.xcoord * G.dx, r.ycoord * G.dy, r.zcoord * G.dz, ', '.join(r.outputs)))
|
print('Receiver at {:g}m, {:g}m, {:g}m with output component(s) {} created.'.format(r.xcoord * G.dx, r.ycoord * G.dy, r.zcoord * G.dz, ', '.join(r.outputs)))
|
||||||
|
|
||||||
G.rxs.append(r)
|
G.rxs.append(r)
|
||||||
@@ -479,7 +483,7 @@ def process_multicmds(multicmds, G):
|
|||||||
else:
|
else:
|
||||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' the step size should not be less than the spatial discretisation')
|
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' the step size should not be less than the spatial discretisation')
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
print('Receiver array {:g}m, {:g}m, {:g}m, to {:g}m, {:g}m, {:g}m with steps {:g}m, {:g}m, {:g}m'.format(xs * G.dx, ys * G.dy, zs * G.dz, xf * G.dx, yf * G.dy, zf * G.dz, dx * G.dx, dy * G.dy, dz * G.dz))
|
print('Receiver array {:g}m, {:g}m, {:g}m, to {:g}m, {:g}m, {:g}m with steps {:g}m, {:g}m, {:g}m'.format(xs * G.dx, ys * G.dy, zs * G.dz, xf * G.dx, yf * G.dy, zf * G.dz, dx * G.dx, dy * G.dy, dz * G.dz))
|
||||||
|
|
||||||
for x in range(xs, xf + 1, dx):
|
for x in range(xs, xf + 1, dx):
|
||||||
@@ -494,8 +498,8 @@ def process_multicmds(multicmds, G):
|
|||||||
r.zcoordorigin = z
|
r.zcoordorigin = z
|
||||||
r.ID = r.__class__.__name__ + '(' + str(x) + ',' + str(y) + ',' + str(z) + ')'
|
r.ID = r.__class__.__name__ + '(' + str(x) + ',' + str(y) + ',' + str(z) + ')'
|
||||||
for key in Rx.defaultoutputs:
|
for key in Rx.defaultoutputs:
|
||||||
r.outputs[key] = np.zeros(G.iterations, dtype=floattype)
|
r.outputs[key] = np.zeros(G.iterations, dtype=config.dtypes['float_or_double'])
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
print(' Receiver at {:g}m, {:g}m, {:g}m with output component(s) {} created.'.format(r.xcoord * G.dx, r.ycoord * G.dy, r.zcoord * G.dz, ', '.join(r.outputs)))
|
print(' Receiver at {:g}m, {:g}m, {:g}m with output component(s) {} created.'.format(r.xcoord * G.dx, r.ycoord * G.dy, r.zcoord * G.dz, ', '.join(r.outputs)))
|
||||||
G.rxs.append(r)
|
G.rxs.append(r)
|
||||||
|
|
||||||
@@ -544,7 +548,7 @@ def process_multicmds(multicmds, G):
|
|||||||
|
|
||||||
s = Snapshot(xs, ys, zs, xf, yf, zf, dx, dy, dz, time, tmp[10])
|
s = Snapshot(xs, ys, zs, xf, yf, zf, dx, dy, dz, time, tmp[10])
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
print('Snapshot from {:g}m, {:g}m, {:g}m, to {:g}m, {:g}m, {:g}m, discretisation {:g}m, {:g}m, {:g}m, at {:g} secs with filename {} created.'.format(xs * G.dx, ys * G.dy, zs * G.dz, xf * G.dx, yf * G.dy, zf * G.dz, dx * G.dx, dy * G.dy, dz * G.dz, s.time * G.dt, s.basefilename))
|
print('Snapshot from {:g}m, {:g}m, {:g}m, to {:g}m, {:g}m, {:g}m, discretisation {:g}m, {:g}m, {:g}m, at {:g} secs with filename {} created.'.format(xs * G.dx, ys * G.dy, zs * G.dz, xf * G.dx, yf * G.dy, zf * G.dz, dx * G.dx, dy * G.dy, dz * G.dz, s.time * G.dt, s.basefilename))
|
||||||
|
|
||||||
G.snapshots.append(s)
|
G.snapshots.append(s)
|
||||||
@@ -582,7 +586,7 @@ def process_multicmds(multicmds, G):
|
|||||||
if m.se == float('inf'):
|
if m.se == float('inf'):
|
||||||
m.averagable = False
|
m.averagable = False
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
tqdm.write('Material {} with eps_r={:g}, sigma={:g} S/m; mu_r={:g}, sigma*={:g} Ohm/m created.'.format(m.ID, m.er, m.se, m.mr, m.sm))
|
tqdm.write('Material {} with eps_r={:g}, sigma={:g} S/m; mu_r={:g}, sigma*={:g} Ohm/m created.'.format(m.ID, m.er, m.se, m.mr, m.sm))
|
||||||
|
|
||||||
# Append the new material object to the materials list
|
# Append the new material object to the materials list
|
||||||
@@ -608,21 +612,25 @@ def process_multicmds(multicmds, G):
|
|||||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' material(s) {} do not exist'.format(notfound))
|
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' material(s) {} do not exist'.format(notfound))
|
||||||
|
|
||||||
for material in materials:
|
for material in materials:
|
||||||
material.type = 'debye'
|
dispersivemat = DispersiveMaterial(material.numID, material.ID)
|
||||||
material.poles = poles
|
dispersivemat.type = 'debye'
|
||||||
material.averagable = False
|
dispersivemat.poles = poles
|
||||||
|
dispersivemat.averagable = False
|
||||||
for pole in range(1, 2 * poles, 2):
|
for pole in range(1, 2 * poles, 2):
|
||||||
# N.B Not checking if relaxation times are greater than time-step
|
# N.B Not checking if relaxation times are greater than time-step
|
||||||
if float(tmp[pole]) > 0:
|
if float(tmp[pole]) > 0:
|
||||||
material.deltaer.append(float(tmp[pole]))
|
dispersivemat.deltaer.append(float(tmp[pole]))
|
||||||
material.tau.append(float(tmp[pole + 1]))
|
dispersivemat.tau.append(float(tmp[pole + 1]))
|
||||||
else:
|
else:
|
||||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires positive values for the permittivity difference.')
|
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires positive values for the permittivity difference.')
|
||||||
if material.poles > Material.maxpoles:
|
if dispersivemat.poles > config.materials['maxpoles']:
|
||||||
Material.maxpoles = material.poles
|
config.materials['maxpoles'] = dispersivemat.poles
|
||||||
|
|
||||||
if messages:
|
# Replace original (non-dispersive) material with new dispersive instance
|
||||||
tqdm.write('Debye disperion added to {} with delta_eps_r={}, and tau={} secs created.'.format(material.ID, ', '.join('%4.2f' % deltaer for deltaer in material.deltaer), ', '.join('%4.3e' % tau for tau in material.tau)))
|
G.materials[material.numID] = dispersivemat
|
||||||
|
|
||||||
|
if config.general['messages']:
|
||||||
|
tqdm.write('Debye disperion added to {} with delta_eps_r={}, and tau={} secs created.'.format(dispersivemat.ID, ', '.join('%4.2f' % deltaer for deltaer in dispersivemat.deltaer), ', '.join('%4.3e' % tau for tau in dispersivemat.tau)))
|
||||||
|
|
||||||
cmdname = '#add_dispersion_lorentz'
|
cmdname = '#add_dispersion_lorentz'
|
||||||
if multicmds[cmdname] is not None:
|
if multicmds[cmdname] is not None:
|
||||||
@@ -654,10 +662,10 @@ def process_multicmds(multicmds, G):
|
|||||||
material.alpha.append(float(tmp[pole + 2]))
|
material.alpha.append(float(tmp[pole + 2]))
|
||||||
else:
|
else:
|
||||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires positive values for the permittivity difference and frequencies, and associated times that are greater than the time step for the model.')
|
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires positive values for the permittivity difference and frequencies, and associated times that are greater than the time step for the model.')
|
||||||
if material.poles > Material.maxpoles:
|
if material.poles > config.materials['maxpoles']:
|
||||||
Material.maxpoles = material.poles
|
config.materials['maxpoles'] = material.poles
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
tqdm.write('Lorentz disperion added to {} with delta_eps_r={}, omega={} secs, and gamma={} created.'.format(material.ID, ', '.join('%4.2f' % deltaer for deltaer in material.deltaer), ', '.join('%4.3e' % tau for tau in material.tau), ', '.join('%4.3e' % alpha for alpha in material.alpha)))
|
tqdm.write('Lorentz disperion added to {} with delta_eps_r={}, omega={} secs, and gamma={} created.'.format(material.ID, ', '.join('%4.2f' % deltaer for deltaer in material.deltaer), ', '.join('%4.3e' % tau for tau in material.tau), ', '.join('%4.3e' % alpha for alpha in material.alpha)))
|
||||||
|
|
||||||
cmdname = '#add_dispersion_drude'
|
cmdname = '#add_dispersion_drude'
|
||||||
@@ -689,10 +697,10 @@ def process_multicmds(multicmds, G):
|
|||||||
material.alpha.append(float(tmp[pole + 1]))
|
material.alpha.append(float(tmp[pole + 1]))
|
||||||
else:
|
else:
|
||||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires positive values for the frequencies, and associated times that are greater than the time step for the model.')
|
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires positive values for the frequencies, and associated times that are greater than the time step for the model.')
|
||||||
if material.poles > Material.maxpoles:
|
if material.poles > config.materials['maxpoles']:
|
||||||
Material.maxpoles = material.poles
|
config.materials['maxpoles'] = material.poles
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
tqdm.write('Drude disperion added to {} with omega={} secs, and gamma={} secs created.'.format(material.ID, ', '.join('%4.3e' % tau for tau in material.tau), ', '.join('%4.3e' % alpha for alpha in material.alpha)))
|
tqdm.write('Drude disperion added to {} with omega={} secs, and gamma={} secs created.'.format(material.ID, ', '.join('%4.3e' % tau for tau in material.tau), ', '.join('%4.3e' % alpha for alpha in material.alpha)))
|
||||||
|
|
||||||
cmdname = '#soil_peplinski'
|
cmdname = '#soil_peplinski'
|
||||||
@@ -719,7 +727,7 @@ def process_multicmds(multicmds, G):
|
|||||||
# Create a new instance of the Material class material (start index after pec & free_space)
|
# Create a new instance of the Material class material (start index after pec & free_space)
|
||||||
s = PeplinskiSoil(tmp[6], float(tmp[0]), float(tmp[1]), float(tmp[2]), float(tmp[3]), (float(tmp[4]), float(tmp[5])))
|
s = PeplinskiSoil(tmp[6], float(tmp[0]), float(tmp[1]), float(tmp[2]), float(tmp[3]), (float(tmp[4]), float(tmp[5])))
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
print('Mixing model (Peplinski) used to create {} with sand fraction {:g}, clay fraction {:g}, bulk density {:g}g/cm3, sand particle density {:g}g/cm3, and water volumetric fraction {:g} to {:g} created.'.format(s.ID, s.S, s.C, s.rb, s.rs, s.mu[0], s.mu[1]))
|
print('Mixing model (Peplinski) used to create {} with sand fraction {:g}, clay fraction {:g}, bulk density {:g}g/cm3, sand particle density {:g}g/cm3, and water volumetric fraction {:g} to {:g} created.'.format(s.ID, s.S, s.C, s.rb, s.rs, s.mu[0], s.mu[1]))
|
||||||
|
|
||||||
# Append the new material object to the materials list
|
# Append the new material object to the materials list
|
||||||
@@ -769,7 +777,7 @@ def process_multicmds(multicmds, G):
|
|||||||
|
|
||||||
g = GeometryView(xs, ys, zs, xf, yf, zf, dx, dy, dz, tmp[9], fileext)
|
g = GeometryView(xs, ys, zs, xf, yf, zf, dx, dy, dz, tmp[9], fileext)
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
print('Geometry view from {:g}m, {:g}m, {:g}m, to {:g}m, {:g}m, {:g}m, discretisation {:g}m, {:g}m, {:g}m, with filename base {} created.'.format(xs * G.dx, ys * G.dy, zs * G.dz, xf * G.dx, yf * G.dy, zf * G.dz, dx * G.dx, dy * G.dy, dz * G.dz, g.basefilename))
|
print('Geometry view from {:g}m, {:g}m, {:g}m, to {:g}m, {:g}m, {:g}m, discretisation {:g}m, {:g}m, {:g}m, with filename base {} created.'.format(xs * G.dx, ys * G.dy, zs * G.dz, xf * G.dx, yf * G.dy, zf * G.dz, dx * G.dx, dy * G.dy, dz * G.dz, g.basefilename))
|
||||||
|
|
||||||
# Append the new GeometryView object to the geometry views list
|
# Append the new GeometryView object to the geometry views list
|
||||||
@@ -799,7 +807,7 @@ def process_multicmds(multicmds, G):
|
|||||||
|
|
||||||
g = GeometryObjects(xs, ys, zs, xf, yf, zf, tmp[6])
|
g = GeometryObjects(xs, ys, zs, xf, yf, zf, tmp[6])
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
print('Geometry objects in the volume from {:g}m, {:g}m, {:g}m, to {:g}m, {:g}m, {:g}m, will be written to {}, with materials written to {}'.format(xs * G.dx, ys * G.dy, zs * G.dz, xf * G.dx, yf * G.dy, zf * G.dz, g.filename, g.materialsfilename))
|
print('Geometry objects in the volume from {:g}m, {:g}m, {:g}m, to {:g}m, {:g}m, {:g}m, will be written to {}, with materials written to {}'.format(xs * G.dx, ys * G.dy, zs * G.dz, xf * G.dx, yf * G.dy, zf * G.dz, g.filename, g.materialsfilename))
|
||||||
|
|
||||||
# Append the new GeometryView object to the geometry objects to write list
|
# Append the new GeometryView object to the geometry objects to write list
|
||||||
@@ -849,7 +857,7 @@ def process_multicmds(multicmds, G):
|
|||||||
cfs.kappa = cfskappa
|
cfs.kappa = cfskappa
|
||||||
cfs.sigma = cfssigma
|
cfs.sigma = cfssigma
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
print('PML CFS parameters: alpha (scaling: {}, scaling direction: {}, min: {:g}, max: {:g}), kappa (scaling: {}, scaling direction: {}, min: {:g}, max: {:g}), sigma (scaling: {}, scaling direction: {}, min: {:g}, max: {}) created.'.format(cfsalpha.scalingprofile, cfsalpha.scalingdirection, cfsalpha.min, cfsalpha.max, cfskappa.scalingprofile, cfskappa.scalingdirection, cfskappa.min, cfskappa.max, cfssigma.scalingprofile, cfssigma.scalingdirection, cfssigma.min, cfssigma.max))
|
print('PML CFS parameters: alpha (scaling: {}, scaling direction: {}, min: {:g}, max: {:g}), kappa (scaling: {}, scaling direction: {}, min: {:g}, max: {:g}), sigma (scaling: {}, scaling direction: {}, min: {:g}, max: {}) created.'.format(cfsalpha.scalingprofile, cfsalpha.scalingdirection, cfsalpha.min, cfsalpha.max, cfskappa.scalingprofile, cfskappa.scalingdirection, cfskappa.min, cfskappa.max, cfssigma.scalingprofile, cfssigma.scalingdirection, cfssigma.min, cfssigma.max))
|
||||||
|
|
||||||
G.cfs.append(cfs)
|
G.cfs.append(cfs)
|
||||||
|
@@ -29,16 +29,12 @@ import numpy as np
|
|||||||
from scipy import interpolate
|
from scipy import interpolate
|
||||||
|
|
||||||
import gprMax.config as config
|
import gprMax.config as config
|
||||||
from gprMax.config import c
|
from .exceptions import CmdInputError
|
||||||
from gprMax.config import floattype
|
from .exceptions import GeneralError
|
||||||
from gprMax.config import gpus as gpu
|
from .pml import PML
|
||||||
from gprMax.config import hostinfo
|
from .utilities import human_size
|
||||||
from gprMax.exceptions import CmdInputError
|
from .utilities import round_value
|
||||||
from gprMax.exceptions import GeneralError
|
from .waveforms import Waveform
|
||||||
from gprMax.pml import PML
|
|
||||||
from gprMax.utilities import human_size
|
|
||||||
from gprMax.utilities import round_value
|
|
||||||
from gprMax.waveforms import Waveform
|
|
||||||
|
|
||||||
|
|
||||||
def process_singlecmds(singlecmds, G):
|
def process_singlecmds(singlecmds, G):
|
||||||
@@ -57,9 +53,9 @@ def process_singlecmds(singlecmds, G):
|
|||||||
if len(tmp) != 1:
|
if len(tmp) != 1:
|
||||||
raise CmdInputError(cmd + ' requires exactly one parameter')
|
raise CmdInputError(cmd + ' requires exactly one parameter')
|
||||||
if singlecmds[cmd].lower() == 'y':
|
if singlecmds[cmd].lower() == 'y':
|
||||||
config.messages = True
|
config.general['messages'] = True
|
||||||
elif singlecmds[cmd].lower() == 'n':
|
elif singlecmds[cmd].lower() == 'n':
|
||||||
config.messages = False
|
config.general['messages'] = False
|
||||||
else:
|
else:
|
||||||
raise CmdInputError(cmd + ' requires input values of either y or n')
|
raise CmdInputError(cmd + ' requires input values of either y or n')
|
||||||
|
|
||||||
@@ -73,7 +69,7 @@ def process_singlecmds(singlecmds, G):
|
|||||||
# os.environ['OMP_DISPLAY_ENV'] = 'TRUE' # Prints OMP version and environment variables (useful for debug)
|
# os.environ['OMP_DISPLAY_ENV'] = 'TRUE' # Prints OMP version and environment variables (useful for debug)
|
||||||
|
|
||||||
# Catch bug with Windows Subsystem for Linux (https://github.com/Microsoft/BashOnWindows/issues/785)
|
# Catch bug with Windows Subsystem for Linux (https://github.com/Microsoft/BashOnWindows/issues/785)
|
||||||
if 'Microsoft' in hostinfo['osversion']:
|
if 'Microsoft' in config.hostinfo['osversion']:
|
||||||
os.environ['KMP_AFFINITY'] = 'disabled'
|
os.environ['KMP_AFFINITY'] = 'disabled'
|
||||||
del os.environ['OMP_PLACES']
|
del os.environ['OMP_PLACES']
|
||||||
del os.environ['OMP_PROC_BIND']
|
del os.environ['OMP_PROC_BIND']
|
||||||
@@ -90,28 +86,28 @@ def process_singlecmds(singlecmds, G):
|
|||||||
config.hostinfo['ompthreads'] = int(os.environ.get('OMP_NUM_THREADS'))
|
config.hostinfo['ompthreads'] = int(os.environ.get('OMP_NUM_THREADS'))
|
||||||
else:
|
else:
|
||||||
# Set number of threads to number of physical CPU cores
|
# Set number of threads to number of physical CPU cores
|
||||||
config.hostinfo['ompthreads'] = hostinfo['physicalcores']
|
config.hostinfo['ompthreads'] = config.hostinfo['physicalcores']
|
||||||
os.environ['OMP_NUM_THREADS'] = str(config.hostinfo['ompthreads'])
|
os.environ['OMP_NUM_THREADS'] = str(config.hostinfo['ompthreads'])
|
||||||
|
|
||||||
if config.messages:
|
if config.general['messages']:
|
||||||
print('CPU (OpenMP) threads: {}'.format(config.hostinfo['ompthreads']))
|
print('CPU (OpenMP) threads: {}'.format(config.hostinfo['ompthreads']))
|
||||||
if config.hostinfo['ompthreads'] > hostinfo['physicalcores']:
|
if config.hostinfo['ompthreads'] > config.hostinfo['physicalcores']:
|
||||||
print(Fore.RED + 'WARNING: You have specified more threads ({}) than available physical CPU cores ({}). This may lead to degraded performance.'.format(config.hostinfo['ompthreads'], hostinfo['physicalcores']) + Style.RESET_ALL)
|
print(Fore.RED + 'WARNING: You have specified more threads ({}) than available physical CPU cores ({}). This may lead to degraded performance.'.format(config.hostinfo['ompthreads'], config.hostinfo['physicalcores']) + Style.RESET_ALL)
|
||||||
|
|
||||||
# Print information about any GPU in use
|
# Print information about any GPU in use
|
||||||
if config.messages:
|
if config.general['messages']:
|
||||||
if gpu is not None:
|
if config.cuda['gpus'] is not None:
|
||||||
print('GPU: {} - {}'.format(gpu.deviceID, gpu.name))
|
print('GPU: {} - {}'.format(config.cuda['gpus'].deviceID, config.cuda['gpus'].name))
|
||||||
|
|
||||||
# Print information about precision of main field values
|
# Print information about precision of main field values
|
||||||
if config.messages:
|
if config.general['messages']:
|
||||||
print('Output data type: {}\n'.format(np.dtype(floattype).name))
|
print('Output data type: {}\n'.format(np.dtype(config.dtypes['float_or_double']).name))
|
||||||
|
|
||||||
# Title
|
# Title
|
||||||
cmd = '#title'
|
cmd = '#title'
|
||||||
if singlecmds[cmd] is not None:
|
if singlecmds[cmd] is not None:
|
||||||
G.title = singlecmds[cmd]
|
G.title = singlecmds[cmd]
|
||||||
if config.messages:
|
if config.general['messages']:
|
||||||
print('Model title: {}'.format(G.title))
|
print('Model title: {}'.format(G.title))
|
||||||
|
|
||||||
# Spatial discretisation
|
# Spatial discretisation
|
||||||
@@ -128,7 +124,7 @@ def process_singlecmds(singlecmds, G):
|
|||||||
G.dx = tmp[0]
|
G.dx = tmp[0]
|
||||||
G.dy = tmp[1]
|
G.dy = tmp[1]
|
||||||
G.dz = tmp[2]
|
G.dz = tmp[2]
|
||||||
if config.messages:
|
if config.general['messages']:
|
||||||
print('Spatial discretisation: {:g} x {:g} x {:g}m'.format(G.dx, G.dy, G.dz))
|
print('Spatial discretisation: {:g} x {:g} x {:g}m'.format(G.dx, G.dy, G.dz))
|
||||||
|
|
||||||
# Domain
|
# Domain
|
||||||
@@ -141,34 +137,34 @@ def process_singlecmds(singlecmds, G):
|
|||||||
G.nz = round_value(tmp[2] / G.dz)
|
G.nz = round_value(tmp[2] / G.dz)
|
||||||
if G.nx == 0 or G.ny == 0 or G.nz == 0:
|
if G.nx == 0 or G.ny == 0 or G.nz == 0:
|
||||||
raise CmdInputError(cmd + ' requires at least one cell in every dimension')
|
raise CmdInputError(cmd + ' requires at least one cell in every dimension')
|
||||||
if config.messages:
|
if config.general['messages']:
|
||||||
print('Domain size: {:g} x {:g} x {:g}m ({:d} x {:d} x {:d} = {:g} cells)'.format(tmp[0], tmp[1], tmp[2], G.nx, G.ny, G.nz, (G.nx * G.ny * G.nz)))
|
print('Domain size: {:g} x {:g} x {:g}m ({:d} x {:d} x {:d} = {:g} cells)'.format(tmp[0], tmp[1], tmp[2], G.nx, G.ny, G.nz, (G.nx * G.ny * G.nz)))
|
||||||
|
|
||||||
# Time step CFL limit (either 2D or 3D); switch off appropriate PMLs for 2D
|
# Time step CFL limit (either 2D or 3D); switch off appropriate PMLs for 2D
|
||||||
if G.nx == 1:
|
if G.nx == 1:
|
||||||
G.dt = 1 / (c * np.sqrt((1 / G.dy) * (1 / G.dy) + (1 / G.dz) * (1 / G.dz)))
|
G.dt = 1 / (config.c * np.sqrt((1 / G.dy) * (1 / G.dy) + (1 / G.dz) * (1 / G.dz)))
|
||||||
config.mode = '2D TMx'
|
config.mode = '2D TMx'
|
||||||
G.pmlthickness['x0'] = 0
|
G.pmlthickness['x0'] = 0
|
||||||
G.pmlthickness['xmax'] = 0
|
G.pmlthickness['xmax'] = 0
|
||||||
elif G.ny == 1:
|
elif G.ny == 1:
|
||||||
G.dt = 1 / (c * np.sqrt((1 / G.dx) * (1 / G.dx) + (1 / G.dz) * (1 / G.dz)))
|
G.dt = 1 / (config.c * np.sqrt((1 / G.dx) * (1 / G.dx) + (1 / G.dz) * (1 / G.dz)))
|
||||||
config.mode = '2D TMy'
|
config.mode = '2D TMy'
|
||||||
G.pmlthickness['y0'] = 0
|
G.pmlthickness['y0'] = 0
|
||||||
G.pmlthickness['ymax'] = 0
|
G.pmlthickness['ymax'] = 0
|
||||||
elif G.nz == 1:
|
elif G.nz == 1:
|
||||||
G.dt = 1 / (c * np.sqrt((1 / G.dx) * (1 / G.dx) + (1 / G.dy) * (1 / G.dy)))
|
G.dt = 1 / (config.c * np.sqrt((1 / G.dx) * (1 / G.dx) + (1 / G.dy) * (1 / G.dy)))
|
||||||
config.mode = '2D TMz'
|
config.mode = '2D TMz'
|
||||||
G.pmlthickness['z0'] = 0
|
G.pmlthickness['z0'] = 0
|
||||||
G.pmlthickness['zmax'] = 0
|
G.pmlthickness['zmax'] = 0
|
||||||
else:
|
else:
|
||||||
G.dt = 1 / (c * np.sqrt((1 / G.dx) * (1 / G.dx) + (1 / G.dy) * (1 / G.dy) + (1 / G.dz) * (1 / G.dz)))
|
G.dt = 1 / (config.c * np.sqrt((1 / G.dx) * (1 / G.dx) + (1 / G.dy) * (1 / G.dy) + (1 / G.dz) * (1 / G.dz)))
|
||||||
config.mode = '3D'
|
config.mode = '3D'
|
||||||
|
|
||||||
# Round down time step to nearest float with precision one less than hardware maximum.
|
# Round down time step to nearest float with precision one less than hardware maximum.
|
||||||
# Avoids inadvertently exceeding the CFL due to binary representation of floating point number.
|
# Avoids inadvertently exceeding the CFL due to binary representation of floating point number.
|
||||||
G.dt = round_value(G.dt, decimalplaces=d.getcontext().prec - 1)
|
G.dt = round_value(G.dt, decimalplaces=d.getcontext().prec - 1)
|
||||||
|
|
||||||
if config.messages:
|
if config.general['messages']:
|
||||||
print('Mode: {}'.format(config.mode))
|
print('Mode: {}'.format(config.mode))
|
||||||
print('Time step (at CFL limit): {:g} secs'.format(G.dt))
|
print('Time step (at CFL limit): {:g} secs'.format(G.dt))
|
||||||
|
|
||||||
@@ -181,7 +177,7 @@ def process_singlecmds(singlecmds, G):
|
|||||||
if tmp[0] <= 0 or tmp[0] > 1:
|
if tmp[0] <= 0 or tmp[0] > 1:
|
||||||
raise CmdInputError(cmd + ' requires the value of the time step stability factor to be between zero and one')
|
raise CmdInputError(cmd + ' requires the value of the time step stability factor to be between zero and one')
|
||||||
G.dt = G.dt * tmp[0]
|
G.dt = G.dt * tmp[0]
|
||||||
if config.messages:
|
if config.general['messages']:
|
||||||
print('Time step (modified): {:g} secs'.format(G.dt))
|
print('Time step (modified): {:g} secs'.format(G.dt))
|
||||||
|
|
||||||
# Time window
|
# Time window
|
||||||
@@ -206,7 +202,7 @@ def process_singlecmds(singlecmds, G):
|
|||||||
G.iterations = int(np.ceil(tmp / G.dt)) + 1
|
G.iterations = int(np.ceil(tmp / G.dt)) + 1
|
||||||
else:
|
else:
|
||||||
raise CmdInputError(cmd + ' must have a value greater than zero')
|
raise CmdInputError(cmd + ' must have a value greater than zero')
|
||||||
if config.messages:
|
if config.general['messages']:
|
||||||
print('Time window: {:g} secs ({} iterations)'.format(G.timewindow, G.iterations))
|
print('Time window: {:g} secs ({} iterations)'.format(G.timewindow, G.iterations))
|
||||||
|
|
||||||
# PML cells
|
# PML cells
|
||||||
@@ -248,7 +244,7 @@ def process_singlecmds(singlecmds, G):
|
|||||||
G.srcsteps[0] = round_value(float(tmp[0]) / G.dx)
|
G.srcsteps[0] = round_value(float(tmp[0]) / G.dx)
|
||||||
G.srcsteps[1] = round_value(float(tmp[1]) / G.dy)
|
G.srcsteps[1] = round_value(float(tmp[1]) / G.dy)
|
||||||
G.srcsteps[2] = round_value(float(tmp[2]) / G.dz)
|
G.srcsteps[2] = round_value(float(tmp[2]) / G.dz)
|
||||||
if config.messages:
|
if config.general['messages']:
|
||||||
print('Simple sources will step {:g}m, {:g}m, {:g}m for each model run.'.format(G.srcsteps[0] * G.dx, G.srcsteps[1] * G.dy, G.srcsteps[2] * G.dz))
|
print('Simple sources will step {:g}m, {:g}m, {:g}m for each model run.'.format(G.srcsteps[0] * G.dx, G.srcsteps[1] * G.dy, G.srcsteps[2] * G.dz))
|
||||||
|
|
||||||
# rx_steps
|
# rx_steps
|
||||||
@@ -260,7 +256,7 @@ def process_singlecmds(singlecmds, G):
|
|||||||
G.rxsteps[0] = round_value(float(tmp[0]) / G.dx)
|
G.rxsteps[0] = round_value(float(tmp[0]) / G.dx)
|
||||||
G.rxsteps[1] = round_value(float(tmp[1]) / G.dy)
|
G.rxsteps[1] = round_value(float(tmp[1]) / G.dy)
|
||||||
G.rxsteps[2] = round_value(float(tmp[2]) / G.dz)
|
G.rxsteps[2] = round_value(float(tmp[2]) / G.dz)
|
||||||
if config.messages:
|
if config.general['messages']:
|
||||||
print('All receivers will step {:g}m, {:g}m, {:g}m for each model run.'.format(G.rxsteps[0] * G.dx, G.rxsteps[1] * G.dy, G.rxsteps[2] * G.dz))
|
print('All receivers will step {:g}m, {:g}m, {:g}m for each model run.'.format(G.rxsteps[0] * G.dx, G.rxsteps[1] * G.dy, G.rxsteps[2] * G.dz))
|
||||||
|
|
||||||
# Excitation file for user-defined source waveforms
|
# Excitation file for user-defined source waveforms
|
||||||
@@ -284,7 +280,7 @@ def process_singlecmds(singlecmds, G):
|
|||||||
if not os.path.isfile(excitationfile):
|
if not os.path.isfile(excitationfile):
|
||||||
excitationfile = os.path.abspath(os.path.join(G.inputdirectory, excitationfile))
|
excitationfile = os.path.abspath(os.path.join(G.inputdirectory, excitationfile))
|
||||||
|
|
||||||
if config.messages:
|
if config.general['messages']:
|
||||||
print('\nExcitation file: {}'.format(excitationfile))
|
print('\nExcitation file: {}'.format(excitationfile))
|
||||||
|
|
||||||
# Get waveform names
|
# Get waveform names
|
||||||
@@ -292,7 +288,7 @@ def process_singlecmds(singlecmds, G):
|
|||||||
waveformIDs = f.readline().split()
|
waveformIDs = f.readline().split()
|
||||||
|
|
||||||
# Read all waveform values into an array
|
# Read all waveform values into an array
|
||||||
waveformvalues = np.loadtxt(excitationfile, skiprows=1, dtype=floattype)
|
waveformvalues = np.loadtxt(excitationfile, skiprows=1, dtype=config.dtypes['float_or_double'])
|
||||||
|
|
||||||
# Time array (if specified) for interpolation, otherwise use simulation time
|
# Time array (if specified) for interpolation, otherwise use simulation time
|
||||||
if waveformIDs[0].lower() == 'time':
|
if waveformIDs[0].lower() == 'time':
|
||||||
@@ -326,7 +322,7 @@ def process_singlecmds(singlecmds, G):
|
|||||||
# Interpolate waveform values
|
# Interpolate waveform values
|
||||||
w.userfunc = interpolate.interp1d(waveformtime, singlewaveformvalues, **kwargs)
|
w.userfunc = interpolate.interp1d(waveformtime, singlewaveformvalues, **kwargs)
|
||||||
|
|
||||||
if config.messages:
|
if config.general['messages']:
|
||||||
print('User waveform {} created using {} and, if required, interpolation parameters (kind: {}, fill value: {}).'.format(w.ID, timestr, kwargs['kind'], kwargs['fill_value']))
|
print('User waveform {} created using {} and, if required, interpolation parameters (kind: {}, fill value: {}).'.format(w.ID, timestr, kwargs['kind'], kwargs['fill_value']))
|
||||||
|
|
||||||
G.waveforms.append(w)
|
G.waveforms.append(w)
|
||||||
@@ -334,5 +330,7 @@ def process_singlecmds(singlecmds, G):
|
|||||||
# Set the output directory
|
# Set the output directory
|
||||||
cmd = '#output_dir'
|
cmd = '#output_dir'
|
||||||
if singlecmds[cmd] is not None:
|
if singlecmds[cmd] is not None:
|
||||||
outputdir = singlecmds[cmd]
|
config.outputfilepath = singlecmds[cmd]
|
||||||
G.outputdirectory = outputdir
|
|
||||||
|
if config.general['messages']:
|
||||||
|
print('Output directory: {}'.format(config.outputfilepath))
|
||||||
|
@@ -18,28 +18,13 @@
|
|||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from gprMax.config import e0
|
import gprMax.config as config
|
||||||
from gprMax.config import m0
|
|
||||||
from gprMax.config import complextype
|
|
||||||
|
|
||||||
|
|
||||||
class Material(object):
|
class Material(object):
|
||||||
"""Materials, their properties and update coefficients."""
|
"""Super-class to describe generic, non-dispersive materials,
|
||||||
|
their properties and update coefficients.
|
||||||
# Maximum number of dispersive material poles in a model
|
"""
|
||||||
maxpoles = 0
|
|
||||||
|
|
||||||
# Properties of water from: http://dx.doi.org/10.1109/TGRS.2006.873208
|
|
||||||
waterer = 80.1
|
|
||||||
watereri = 4.9
|
|
||||||
waterdeltaer = waterer - watereri
|
|
||||||
watertau = 9.231e-12
|
|
||||||
|
|
||||||
# Properties of grass from: http://dx.doi.org/10.1007/BF00902994
|
|
||||||
grasser = 18.5087
|
|
||||||
grasseri = 12.7174
|
|
||||||
grassdeltaer = grasser - grasseri
|
|
||||||
grasstau = 1.0793e-11
|
|
||||||
|
|
||||||
def __init__(self, numID, ID):
|
def __init__(self, numID, ID):
|
||||||
"""
|
"""
|
||||||
@@ -60,27 +45,85 @@ class Material(object):
|
|||||||
self.mr = 1.0
|
self.mr = 1.0
|
||||||
self.sm = 0.0
|
self.sm = 0.0
|
||||||
|
|
||||||
# Parameters for dispersive materials
|
|
||||||
self.poles = 0
|
|
||||||
self.deltaer = []
|
|
||||||
self.tau = []
|
|
||||||
self.alpha = []
|
|
||||||
|
|
||||||
def calculate_update_coeffsH(self, G):
|
def calculate_update_coeffsH(self, G):
|
||||||
"""Calculates the magnetic update coefficients of the material.
|
"""Calculates the magnetic update coefficients of the material.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
G (class): Grid class instance - holds essential parameters describing the model.
|
G (class): Grid class instance - holds essential parameters
|
||||||
|
describing the model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
HA = (m0 * self.mr / G.dt) + 0.5 * self.sm
|
HA = (config.m0 * self.mr / G.dt) + 0.5 * self.sm
|
||||||
HB = (m0 * self.mr / G.dt) - 0.5 * self.sm
|
HB = (config.m0 * self.mr / G.dt) - 0.5 * self.sm
|
||||||
self.DA = HB / HA
|
self.DA = HB / HA
|
||||||
self.DBx = (1 / G.dx) * 1 / HA
|
self.DBx = (1 / G.dx) * 1 / HA
|
||||||
self.DBy = (1 / G.dy) * 1 / HA
|
self.DBy = (1 / G.dy) * 1 / HA
|
||||||
self.DBz = (1 / G.dz) * 1 / HA
|
self.DBz = (1 / G.dz) * 1 / HA
|
||||||
self.srcm = 1 / HA
|
self.srcm = 1 / HA
|
||||||
|
|
||||||
|
def calculate_update_coeffsE(self, G):
|
||||||
|
"""Calculates the electric update coefficients of the material.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (class): Grid class instance - holds essential parameters
|
||||||
|
describing the model.
|
||||||
|
"""
|
||||||
|
|
||||||
|
EA = (config.e0 * self.er / G.dt) + 0.5 * self.se
|
||||||
|
EB = (config.e0 * self.er / G.dt) - 0.5 * self.se
|
||||||
|
|
||||||
|
if self.ID == 'pec' or self.se == float('inf'):
|
||||||
|
self.CA = 0
|
||||||
|
self.CBx = 0
|
||||||
|
self.CBy = 0
|
||||||
|
self.CBz = 0
|
||||||
|
self.srce = 0
|
||||||
|
else:
|
||||||
|
self.CA = EB / EA
|
||||||
|
self.CBx = (1 / G.dx) * 1 / EA
|
||||||
|
self.CBy = (1 / G.dy) * 1 / EA
|
||||||
|
self.CBz = (1 / G.dz) * 1 / EA
|
||||||
|
self.srce = 1 / EA
|
||||||
|
|
||||||
|
def calculate_er(self, freq):
|
||||||
|
"""Calculates the complex relative permittivity of the material at a
|
||||||
|
specific frequency.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
freq (float): Frequency used to calculate complex relative
|
||||||
|
permittivity.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
er (float): Complex relative permittivity.
|
||||||
|
"""
|
||||||
|
|
||||||
|
return self.er
|
||||||
|
|
||||||
|
|
||||||
|
class DispersiveMaterial(Material):
|
||||||
|
"""Class to describe materials with frequency dependent properties, e.g.
|
||||||
|
Debye, Drude, Lorenz
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Properties of water from: http://dx.doi.org/10.1109/TGRS.2006.873208
|
||||||
|
waterer = 80.1
|
||||||
|
watereri = 4.9
|
||||||
|
waterdeltaer = waterer - watereri
|
||||||
|
watertau = 9.231e-12
|
||||||
|
|
||||||
|
# Properties of grass from: http://dx.doi.org/10.1007/BF00902994
|
||||||
|
grasser = 18.5087
|
||||||
|
grasseri = 12.7174
|
||||||
|
grassdeltaer = grasser - grasseri
|
||||||
|
grasstau = 1.0793e-11
|
||||||
|
|
||||||
|
def __init__(self, numID, ID):
|
||||||
|
super().__init__(numID, ID)
|
||||||
|
self.poles = 0
|
||||||
|
self.deltaer = []
|
||||||
|
self.tau = []
|
||||||
|
self.alpha = []
|
||||||
|
|
||||||
def calculate_update_coeffsE(self, G):
|
def calculate_update_coeffsE(self, G):
|
||||||
"""Calculates the electric update coefficients of the material.
|
"""Calculates the electric update coefficients of the material.
|
||||||
|
|
||||||
@@ -91,13 +134,12 @@ class Material(object):
|
|||||||
|
|
||||||
# The implementation of the dispersive material modelling comes from the
|
# The implementation of the dispersive material modelling comes from the
|
||||||
# derivation in: http://dx.doi.org/10.1109/TAP.2014.2308549
|
# derivation in: http://dx.doi.org/10.1109/TAP.2014.2308549
|
||||||
if self.maxpoles > 0:
|
self.w = np.zeros(config.materials['maxpoles'], dtype=config.materials['dispersivedtype'])
|
||||||
self.w = np.zeros(self.maxpoles, dtype=complextype)
|
self.q = np.zeros(config.materials['maxpoles'], dtype=config.materials['dispersivedtype'])
|
||||||
self.q = np.zeros(self.maxpoles, dtype=complextype)
|
self.zt = np.zeros(config.materials['maxpoles'], dtype=config.materials['dispersivedtype'])
|
||||||
self.zt = np.zeros(self.maxpoles, dtype=complextype)
|
self.zt2 = np.zeros(config.materials['maxpoles'], dtype=config.materials['dispersivedtype'])
|
||||||
self.zt2 = np.zeros(self.maxpoles, dtype=complextype)
|
self.eqt = np.zeros(config.materials['maxpoles'], dtype=config.materials['dispersivedtype'])
|
||||||
self.eqt = np.zeros(self.maxpoles, dtype=complextype)
|
self.eqt2 = np.zeros(config.materials['maxpoles'], dtype=config.materials['dispersivedtype'])
|
||||||
self.eqt2 = np.zeros(self.maxpoles, dtype=complextype)
|
|
||||||
|
|
||||||
for x in range(self.poles):
|
for x in range(self.poles):
|
||||||
if 'debye' in self.type:
|
if 'debye' in self.type:
|
||||||
@@ -122,20 +164,9 @@ class Material(object):
|
|||||||
self.zt[x] = (self.w[x] / self.q[x]) * (1 - self.eqt[x]) / G.dt
|
self.zt[x] = (self.w[x] / self.q[x]) * (1 - self.eqt[x]) / G.dt
|
||||||
self.zt2[x] = (self.w[x] / self.q[x]) * (1 - self.eqt2[x])
|
self.zt2[x] = (self.w[x] / self.q[x]) * (1 - self.eqt2[x])
|
||||||
|
|
||||||
EA = (e0 * self.er / G.dt) + 0.5 * self.se - (e0 / G.dt) * np.sum(self.zt2.real)
|
EA = (config.e0 * self.er / G.dt) + 0.5 * self.se - (config.e0 / G.dt) * np.sum(self.zt2.real)
|
||||||
EB = (e0 * self.er / G.dt) - 0.5 * self.se - (e0 / G.dt) * np.sum(self.zt2.real)
|
EB = (config.e0 * self.er / G.dt) - 0.5 * self.se - (config.e0 / G.dt) * np.sum(self.zt2.real)
|
||||||
|
|
||||||
else:
|
|
||||||
EA = (e0 * self.er / G.dt) + 0.5 * self.se
|
|
||||||
EB = (e0 * self.er / G.dt) - 0.5 * self.se
|
|
||||||
|
|
||||||
if self.ID == 'pec' or self.se == float('inf'):
|
|
||||||
self.CA = 0
|
|
||||||
self.CBx = 0
|
|
||||||
self.CBy = 0
|
|
||||||
self.CBz = 0
|
|
||||||
self.srce = 0
|
|
||||||
else:
|
|
||||||
self.CA = EB / EA
|
self.CA = EB / EA
|
||||||
self.CBx = (1 / G.dx) * 1 / EA
|
self.CBx = (1 / G.dx) * 1 / EA
|
||||||
self.CBy = (1 / G.dy) * 1 / EA
|
self.CBy = (1 / G.dy) * 1 / EA
|
||||||
@@ -143,11 +174,12 @@ class Material(object):
|
|||||||
self.srce = 1 / EA
|
self.srce = 1 / EA
|
||||||
|
|
||||||
def calculate_er(self, freq):
|
def calculate_er(self, freq):
|
||||||
"""
|
"""Calculates the complex relative permittivity of the material at a
|
||||||
Calculates the complex relative permittivity of the material at a specific frequency.
|
specific frequency.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
freq (float): Frequency used to calculate complex relative permittivity.
|
freq (float): Frequency used to calculate complex relative
|
||||||
|
permittivity.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
er (float): Complex relative permittivity.
|
er (float): Complex relative permittivity.
|
||||||
@@ -156,15 +188,15 @@ class Material(object):
|
|||||||
# Permittivity at infinite frequency if the material is dispersive
|
# Permittivity at infinite frequency if the material is dispersive
|
||||||
er = self.er
|
er = self.er
|
||||||
|
|
||||||
if self.poles > 0:
|
|
||||||
w = 2 * np.pi * freq
|
w = 2 * np.pi * freq
|
||||||
er += self.se / (w * e0)
|
er += self.se / (w * config.e0)
|
||||||
if 'debye' in self.type:
|
if 'debye' in self.type:
|
||||||
for pole in range(self.poles):
|
for pole in range(self.poles):
|
||||||
er += self.deltaer[pole] / (1 + 1j * w * self.tau[pole])
|
er += self.deltaer[pole] / (1 + 1j * w * self.tau[pole])
|
||||||
elif 'lorentz' in self.type:
|
elif 'lorentz' in self.type:
|
||||||
for pole in range(self.poles):
|
for pole in range(self.poles):
|
||||||
er += (self.deltaer[pole] * self.tau[pole]**2) / (self.tau[pole]**2 + 2j * w * self.alpha[pole] - w**2)
|
er += ((self.deltaer[pole] * self.tau[pole]**2)
|
||||||
|
/ (self.tau[pole]**2 + 2j * w * self.alpha[pole] - w**2))
|
||||||
elif 'drude' in self.type:
|
elif 'drude' in self.type:
|
||||||
ersum = 0
|
ersum = 0
|
||||||
for pole in range(self.poles):
|
for pole in range(self.poles):
|
||||||
@@ -175,36 +207,41 @@ class Material(object):
|
|||||||
|
|
||||||
|
|
||||||
def process_materials(G):
|
def process_materials(G):
|
||||||
"""
|
"""Process complete list of materials - calculate update coefficients,
|
||||||
Process complete list of materials - calculate update coefficients,
|
|
||||||
store in arrays, and build text list of materials/properties
|
store in arrays, and build text list of materials/properties
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
G (class): Grid class instance - holds essential parameters describing the model.
|
G (class): Grid class instance - holds essential parameters
|
||||||
|
describing the model.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
materialsdata (list): List of material IDs, names, and properties to print a table.
|
materialsdata (list): List of material IDs, names, and properties to
|
||||||
|
print a table.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if Material.maxpoles == 0:
|
if config.materials['maxpoles'] == 0:
|
||||||
materialsdata = [['\nID', '\nName', '\nType', '\neps_r', 'sigma\n[S/m]', '\nmu_r', 'sigma*\n[Ohm/m]', 'Dielectric\nsmoothable']]
|
materialsdata = [['\nID', '\nName', '\nType', '\neps_r', 'sigma\n[S/m]',
|
||||||
|
'\nmu_r', 'sigma*\n[Ohm/m]', 'Dielectric\nsmoothable']]
|
||||||
else:
|
else:
|
||||||
materialsdata = [['\nID', '\nName', '\nType', '\neps_r', 'sigma\n[S/m]', 'Delta\neps_r', 'tau\n[s]', 'omega\n[Hz]', 'delta\n[Hz]', 'gamma\n[Hz]', '\nmu_r', 'sigma*\n[Ohm/m]', 'Dielectric\nsmoothable']]
|
materialsdata = [['\nID', '\nName', '\nType', '\neps_r', 'sigma\n[S/m]',
|
||||||
|
'Delta\neps_r', 'tau\n[s]', 'omega\n[Hz]', 'delta\n[Hz]',
|
||||||
|
'gamma\n[Hz]', '\nmu_r', 'sigma*\n[Ohm/m]', 'Dielectric\nsmoothable']]
|
||||||
|
|
||||||
for material in G.materials:
|
for material in G.materials:
|
||||||
# Calculate update coefficients for material
|
# Calculate update coefficients for specific material
|
||||||
material.calculate_update_coeffsE(G)
|
material.calculate_update_coeffsE(G)
|
||||||
material.calculate_update_coeffsH(G)
|
material.calculate_update_coeffsH(G)
|
||||||
|
|
||||||
# Store all update coefficients together
|
# Add update coefficients to overall storage for all materials
|
||||||
G.updatecoeffsE[material.numID, :] = material.CA, material.CBx, material.CBy, material.CBz, material.srce
|
G.updatecoeffsE[material.numID, :] = material.CA, material.CBx, material.CBy, material.CBz, material.srce
|
||||||
G.updatecoeffsH[material.numID, :] = material.DA, material.DBx, material.DBy, material.DBz, material.srcm
|
G.updatecoeffsH[material.numID, :] = material.DA, material.DBx, material.DBy, material.DBz, material.srcm
|
||||||
|
|
||||||
# Store coefficients for any dispersive materials
|
# Add update coefficients to overall storage for dispersive materials
|
||||||
if Material.maxpoles > 0:
|
if hasattr(material, 'poles'):
|
||||||
z = 0
|
z = 0
|
||||||
for pole in range(Material.maxpoles):
|
for pole in range(config.materials['maxpoles']):
|
||||||
G.updatecoeffsdispersive[material.numID, z:z + 3] = e0 * material.eqt2[pole], material.eqt[pole], material.zt[pole]
|
G.updatecoeffsdispersive[material.numID, z:z + 3] = (config.e0
|
||||||
|
* material.eqt2[pole], material.eqt[pole], material.zt[pole])
|
||||||
z += 3
|
z += 3
|
||||||
|
|
||||||
# Construct information on material properties for printing table
|
# Construct information on material properties for printing table
|
||||||
@@ -214,7 +251,7 @@ def process_materials(G):
|
|||||||
materialtext.append(material.type)
|
materialtext.append(material.type)
|
||||||
materialtext.append('{:g}'.format(material.er))
|
materialtext.append('{:g}'.format(material.er))
|
||||||
materialtext.append('{:g}'.format(material.se))
|
materialtext.append('{:g}'.format(material.se))
|
||||||
if Material.maxpoles > 0:
|
if config.materials['maxpoles'] > 0:
|
||||||
if 'debye' in material.type:
|
if 'debye' in material.type:
|
||||||
materialtext.append('\n'.join('{:g}'.format(deltaer) for deltaer in material.deltaer))
|
materialtext.append('\n'.join('{:g}'.format(deltaer) for deltaer in material.deltaer))
|
||||||
materialtext.append('\n'.join('{:g}'.format(tau) for tau in material.tau))
|
materialtext.append('\n'.join('{:g}'.format(tau) for tau in material.tau))
|
||||||
@@ -242,9 +279,8 @@ def process_materials(G):
|
|||||||
|
|
||||||
|
|
||||||
class PeplinskiSoil(object):
|
class PeplinskiSoil(object):
|
||||||
"""
|
"""Soil objects that are characterised according to a mixing model
|
||||||
Soil objects that are characterised according to a mixing
|
by Peplinski (http://dx.doi.org/10.1109/36.387598).
|
||||||
model by Peplinski (http://dx.doi.org/10.1109/36.387598).
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, ID, sandfraction, clayfraction, bulkdensity, sandpartdensity, watervolfraction):
|
def __init__(self, ID, sandfraction, clayfraction, bulkdensity, sandpartdensity, watervolfraction):
|
||||||
@@ -254,8 +290,10 @@ class PeplinskiSoil(object):
|
|||||||
sandfraction (float): Sand fraction of the soil.
|
sandfraction (float): Sand fraction of the soil.
|
||||||
clayfraction (float): Clay fraction of the soil.
|
clayfraction (float): Clay fraction of the soil.
|
||||||
bulkdensity (float): Bulk density of the soil (g/cm3).
|
bulkdensity (float): Bulk density of the soil (g/cm3).
|
||||||
sandpartdensity (float): Density of the sand particles in the soil (g/cm3).
|
sandpartdensity (float): Density of the sand particles in the
|
||||||
watervolfraction (float): Two numbers that specify a range for the volumetric water fraction of the soil.
|
soil (g/cm3).
|
||||||
|
watervolfraction (float): Two numbers that specify a range for the
|
||||||
|
volumetric water fraction of the soil.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.ID = ID
|
self.ID = ID
|
||||||
@@ -267,9 +305,9 @@ class PeplinskiSoil(object):
|
|||||||
self.startmaterialnum = 0
|
self.startmaterialnum = 0
|
||||||
|
|
||||||
def calculate_debye_properties(self, nbins, G):
|
def calculate_debye_properties(self, nbins, G):
|
||||||
"""
|
"""Calculates the real and imaginery part of a Debye model for the soil
|
||||||
Calculates the real and imaginery part of a Debye model for the soil as
|
as well as a conductivity. It uses an approximation to a semi-empirical
|
||||||
well as a conductivity. It uses an approximation to a semi-empirical model (http://dx.doi.org/10.1109/36.387598).
|
model (http://dx.doi.org/10.1109/36.387598).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nbins (int): Number of bins to use to create the different materials.
|
nbins (int): Number of bins to use to create the different materials.
|
||||||
@@ -279,7 +317,8 @@ class PeplinskiSoil(object):
|
|||||||
# Debye model properties of water
|
# Debye model properties of water
|
||||||
f = 1.3e9
|
f = 1.3e9
|
||||||
w = 2 * np.pi * f
|
w = 2 * np.pi * f
|
||||||
erealw = Material.watereri + ((Material.waterdeltaer) / (1 + (w * Material.watertau)**2))
|
erealw = DispersiveMaterial.watereri + ((DispersiveMaterial.waterdeltaer)
|
||||||
|
/ (1 + (w * DispersiveMaterial.watertau)**2))
|
||||||
|
|
||||||
a = 0.65 # Experimentally derived constant
|
a = 0.65 # Experimentally derived constant
|
||||||
es = (1.01 + 0.44 * self.rs)**2 - 0.062 # Relative permittivity of sand particles
|
es = (1.01 + 0.44 * self.rs)**2 - 0.062 # Relative permittivity of sand particles
|
||||||
@@ -300,12 +339,13 @@ class PeplinskiSoil(object):
|
|||||||
muiter = np.nditer(mumaterials, flags=['c_index'])
|
muiter = np.nditer(mumaterials, flags=['c_index'])
|
||||||
while not muiter.finished:
|
while not muiter.finished:
|
||||||
# Real part for frequencies in the range 1.4GHz to 18GHz
|
# Real part for frequencies in the range 1.4GHz to 18GHz
|
||||||
er = (1 + (self.rb / self.rs) * ((es**a) - 1) + (muiter[0]**b1 * erealw**a) - muiter[0]) ** (1 / a)
|
er = (1 + (self.rb / self.rs) * ((es**a) - 1) + (muiter[0]**b1 * erealw**a)
|
||||||
|
- muiter[0]) ** (1 / a)
|
||||||
# Real part for frequencies in the range 0.3GHz to 1.3GHz (linear correction to 1.4-18GHz value)
|
# Real part for frequencies in the range 0.3GHz to 1.3GHz (linear correction to 1.4-18GHz value)
|
||||||
er = 1.15 * er - 0.68
|
er = 1.15 * er - 0.68
|
||||||
|
|
||||||
# Permittivity at infinite frequency
|
# Permittivity at infinite frequency
|
||||||
eri = er - (muiter[0]**(b2 / a) * Material.waterdeltaer)
|
eri = er - (muiter[0]**(b2 / a) * DispersiveMaterial.waterdeltaer)
|
||||||
|
|
||||||
# Effective conductivity
|
# Effective conductivity
|
||||||
sig = muiter[0]**(b2 / a) * ((sigf * (self.rs - self.rb)) / (self.rs * muiter[0]))
|
sig = muiter[0]**(b2 / a) * ((sigf * (self.rs - self.rb)) / (self.rs * muiter[0]))
|
||||||
@@ -319,16 +359,16 @@ class PeplinskiSoil(object):
|
|||||||
else:
|
else:
|
||||||
self.startmaterialnum = len(G.materials)
|
self.startmaterialnum = len(G.materials)
|
||||||
if not material:
|
if not material:
|
||||||
m = Material(len(G.materials), requiredID)
|
m = DispersiveMaterial(len(G.materials), requiredID)
|
||||||
m.type = 'debye'
|
m.type = 'debye'
|
||||||
m.averagable = False
|
m.averagable = False
|
||||||
m.poles = 1
|
m.poles = 1
|
||||||
if m.poles > Material.maxpoles:
|
if m.poles > config.materials['maxpoles']:
|
||||||
Material.maxpoles = m.poles
|
config.materials['maxpoles'] = m.poles
|
||||||
m.er = eri
|
m.er = eri
|
||||||
m.se = sig
|
m.se = sig
|
||||||
m.deltaer.append(er - eri)
|
m.deltaer.append(er - eri)
|
||||||
m.tau.append(Material.watertau)
|
m.tau.append(DispersiveMaterial.watertau)
|
||||||
G.materials.append(m)
|
G.materials.append(m)
|
||||||
|
|
||||||
muiter.iternext()
|
muiter.iternext()
|
||||||
|
@@ -32,58 +32,49 @@ from terminaltables import SingleTable
|
|||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
import gprMax.config as config
|
import gprMax.config as config
|
||||||
from gprMax.config import floattype
|
from .cuda.fields_updates import kernel_template_fields
|
||||||
from gprMax.config import complextype
|
from .cuda.source_updates import kernel_template_sources
|
||||||
from gprMax.config import cudafloattype
|
from .cython.fields_updates_normal import update_electric
|
||||||
from gprMax.config import cudacomplextype
|
from .cython.fields_updates_normal import update_magnetic
|
||||||
from gprMax.config import numdispersion
|
from .cython.fields_updates_dispersive import update_electric_dispersive_1pole_A
|
||||||
from gprMax.config import hostinfo
|
from .cython.fields_updates_dispersive import update_electric_dispersive_1pole_B
|
||||||
from gprMax.config import messages
|
from .cython.fields_updates_dispersive import update_electric_dispersive_multipole_A
|
||||||
from gprMax.config import progressbars
|
from .cython.fields_updates_dispersive import update_electric_dispersive_multipole_B
|
||||||
from gprMax.config import snapsgpu2cpu
|
from .cython.fields_updates_dispersive import update_electric_dispersive_debye_1pole_A
|
||||||
from gprMax.exceptions import GeneralError
|
from .cython.fields_updates_dispersive import update_electric_dispersive_debye_1pole_B
|
||||||
|
from .cython.fields_updates_dispersive import update_electric_dispersive_debye_multipole_A
|
||||||
from gprMax.fields_outputs import store_outputs
|
from .cython.fields_updates_dispersive import update_electric_dispersive_debye_multipole_B
|
||||||
from gprMax.fields_outputs import kernel_template_store_outputs
|
from .cython.yee_cell_build import build_electric_components
|
||||||
from gprMax.fields_outputs import write_hdf5_outputfile
|
from .cython.yee_cell_build import build_magnetic_components
|
||||||
|
from .exceptions import GeneralError
|
||||||
from gprMax.cython.fields_updates import update_electric
|
from .fields_outputs import store_outputs
|
||||||
from gprMax.cython.fields_updates import update_magnetic
|
from .fields_outputs import kernel_template_store_outputs
|
||||||
from gprMax.cython.fields_updates import update_electric_dispersive_multipole_A
|
from .fields_outputs import write_hdf5_outputfile
|
||||||
from gprMax.cython.fields_updates import update_electric_dispersive_multipole_B
|
from .grid import FDTDGrid
|
||||||
from gprMax.cython.fields_updates import update_electric_dispersive_1pole_A
|
from .grid import dispersion_analysis
|
||||||
from gprMax.cython.fields_updates import update_electric_dispersive_1pole_B
|
from .input_cmds_geometry import process_geometrycmds
|
||||||
from gprMax.cuda.fields_updates import kernels_template_fields
|
from .input_cmds_file import process_python_include_code
|
||||||
|
from .input_cmds_file import write_processed_file
|
||||||
from gprMax.grid import FDTDGrid
|
from .input_cmds_file import check_cmd_names
|
||||||
from gprMax.grid import dispersion_analysis
|
from .input_cmds_singleuse import process_singlecmds
|
||||||
|
from .input_cmds_multiuse import process_multicmds
|
||||||
from gprMax.input_cmds_geometry import process_geometrycmds
|
from .materials import Material
|
||||||
from gprMax.input_cmds_file import process_python_include_code
|
from .materials import process_materials
|
||||||
from gprMax.input_cmds_file import write_processed_file
|
from .pml import CFS
|
||||||
from gprMax.input_cmds_file import check_cmd_names
|
from .pml import PML
|
||||||
from gprMax.input_cmds_singleuse import process_singlecmds
|
from .pml import build_pmls
|
||||||
from gprMax.input_cmds_multiuse import process_multicmds
|
from .receivers import gpu_initialise_rx_arrays
|
||||||
from gprMax.materials import Material
|
from .receivers import gpu_get_rx_array
|
||||||
from gprMax.materials import process_materials
|
from .receivers import Rx
|
||||||
from gprMax.pml import CFS
|
from .snapshots import Snapshot
|
||||||
from gprMax.pml import PML
|
from .snapshots import gpu_initialise_snapshot_array
|
||||||
from gprMax.pml import build_pmls
|
from .snapshots import gpu_get_snapshot_array
|
||||||
from gprMax.receivers import gpu_initialise_rx_arrays
|
from .sources import gpu_initialise_src_arrays
|
||||||
from gprMax.receivers import gpu_get_rx_array
|
from .utilities import get_terminal_width
|
||||||
from gprMax.snapshots import Snapshot
|
from .utilities import human_size
|
||||||
from gprMax.snapshots import gpu_initialise_snapshot_array
|
from .utilities import open_path_file
|
||||||
from gprMax.snapshots import gpu_get_snapshot_array
|
from .utilities import round32
|
||||||
from gprMax.cuda.snapshots import kernel_template_store_snapshot
|
from .utilities import timer
|
||||||
from gprMax.sources import gpu_initialise_src_arrays
|
|
||||||
from gprMax.cuda.source_updates import kernels_template_sources
|
|
||||||
from gprMax.utilities import get_terminal_width
|
|
||||||
from gprMax.utilities import human_size
|
|
||||||
from gprMax.utilities import open_path_file
|
|
||||||
from gprMax.utilities import round32
|
|
||||||
from gprMax.utilities import timer
|
|
||||||
from gprMax.cython.yee_cell_build import build_electric_components
|
|
||||||
from gprMax.cython.yee_cell_build import build_magnetic_components
|
|
||||||
|
|
||||||
|
|
||||||
def run_model(args, currentmodelrun, modelend, numbermodelruns, inputfile, usernamespace):
|
def run_model(args, currentmodelrun, modelend, numbermodelruns, inputfile, usernamespace):
|
||||||
@@ -117,10 +108,10 @@ def run_model(args, currentmodelrun, modelend, numbermodelruns, inputfile, usern
|
|||||||
# Initialise an instance of the FDTDGrid class
|
# Initialise an instance of the FDTDGrid class
|
||||||
G = FDTDGrid()
|
G = FDTDGrid()
|
||||||
|
|
||||||
G.inputfilename = os.path.split(inputfile.name)[1]
|
config.inputfilepath = os.path.realpath(inputfile.name)
|
||||||
G.inputdirectory = os.path.dirname(os.path.abspath(inputfile.name))
|
config.outputfilepath = os.path.dirname(os.path.abspath(config.inputfilepath))
|
||||||
inputfilestr = '\n--- Model {}/{}, input file: {}'.format(currentmodelrun, modelend, inputfile.name)
|
inputfilestr = '\n--- Model {}/{}, input file: {}'.format(currentmodelrun, modelend, inputfile.name)
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
print(Fore.GREEN + '{} {}\n'.format(inputfilestr, '-' * (get_terminal_width() - 1 - len(inputfilestr))) + Style.RESET_ALL)
|
print(Fore.GREEN + '{} {}\n'.format(inputfilestr, '-' * (get_terminal_width() - 1 - len(inputfilestr))) + Style.RESET_ALL)
|
||||||
|
|
||||||
# Add the current model run to namespace that can be accessed by
|
# Add the current model run to namespace that can be accessed by
|
||||||
@@ -135,12 +126,12 @@ def run_model(args, currentmodelrun, modelend, numbermodelruns, inputfile, usern
|
|||||||
for key, value in sorted(usernamespace.items()):
|
for key, value in sorted(usernamespace.items()):
|
||||||
if key != '__builtins__':
|
if key != '__builtins__':
|
||||||
uservars += '{}: {}, '.format(key, value)
|
uservars += '{}: {}, '.format(key, value)
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
print('Constants/variables used/available for Python scripting: {{{}}}\n'.format(uservars[:-2]))
|
print('Constants/variables used/available for Python scripting: {{{}}}\n'.format(uservars[:-2]))
|
||||||
|
|
||||||
# Write a file containing the input commands after Python or include file commands have been processed
|
# Write a file containing the input commands after Python or include file commands have been processed
|
||||||
if args.write_processed:
|
if args.write_processed:
|
||||||
write_processed_file(processedlines, appendmodelnumber, G)
|
write_processed_file(processedlines, appendmodelnumber)
|
||||||
|
|
||||||
# Check validity of command names and that essential commands are present
|
# Check validity of command names and that essential commands are present
|
||||||
singlecmds, multicmds, geometry = check_cmd_names(processedlines)
|
singlecmds, multicmds, geometry = check_cmd_names(processedlines)
|
||||||
@@ -157,18 +148,17 @@ def run_model(args, currentmodelrun, modelend, numbermodelruns, inputfile, usern
|
|||||||
|
|
||||||
# Process parameters for commands that can only occur once in the model
|
# Process parameters for commands that can only occur once in the model
|
||||||
process_singlecmds(singlecmds, G)
|
process_singlecmds(singlecmds, G)
|
||||||
from gprMax.config import mode
|
|
||||||
|
|
||||||
# Process parameters for commands that can occur multiple times in the model
|
# Process parameters for commands that can occur multiple times in the model
|
||||||
if messages: print()
|
if config.general['messages']: print()
|
||||||
process_multicmds(multicmds, G)
|
process_multicmds(multicmds, G)
|
||||||
|
|
||||||
# Estimate and check memory (RAM) usage
|
# Estimate and check memory (RAM) usage
|
||||||
G.memory_estimate_basic()
|
G.memory_estimate_basic()
|
||||||
G.memory_check()
|
G.memory_check()
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
memGPU = ''
|
memGPU = ''
|
||||||
if config.gpus:
|
if config.cuda['gpus']:
|
||||||
memGPU = ' host + ~{} GPU'.format(human_size(G.memoryusage))
|
memGPU = ' host + ~{} GPU'.format(human_size(G.memoryusage))
|
||||||
print('\nMemory (RAM) required: ~{}{}\n'.format(human_size(G.memoryusage), memGPU))
|
print('\nMemory (RAM) required: ~{}{}\n'.format(human_size(G.memoryusage), memGPU))
|
||||||
|
|
||||||
@@ -184,16 +174,16 @@ def run_model(args, currentmodelrun, modelend, numbermodelruns, inputfile, usern
|
|||||||
process_geometrycmds(geometry, G)
|
process_geometrycmds(geometry, G)
|
||||||
|
|
||||||
# Build the PMLs and calculate initial coefficients
|
# Build the PMLs and calculate initial coefficients
|
||||||
if messages: print()
|
if config.general['messages']: print()
|
||||||
if all(value == 0 for value in G.pmlthickness.values()):
|
if all(value == 0 for value in G.pmlthickness.values()):
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
print('PML: switched off')
|
print('PML: switched off')
|
||||||
pass # If all the PMLs are switched off don't need to build anything
|
pass # If all the PMLs are switched off don't need to build anything
|
||||||
else:
|
else:
|
||||||
# Set default CFS parameters for PML if not given
|
# Set default CFS parameters for PML if not given
|
||||||
if not G.cfs:
|
if not G.cfs:
|
||||||
G.cfs = [CFS()]
|
G.cfs = [CFS()]
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
if all(value == G.pmlthickness['x0'] for value in G.pmlthickness.values()):
|
if all(value == G.pmlthickness['x0'] for value in G.pmlthickness.values()):
|
||||||
pmlinfo = str(G.pmlthickness['x0'])
|
pmlinfo = str(G.pmlthickness['x0'])
|
||||||
else:
|
else:
|
||||||
@@ -202,14 +192,14 @@ def run_model(args, currentmodelrun, modelend, numbermodelruns, inputfile, usern
|
|||||||
pmlinfo += '{}: {}, '.format(key, value)
|
pmlinfo += '{}: {}, '.format(key, value)
|
||||||
pmlinfo = pmlinfo[:-2] + ' cells'
|
pmlinfo = pmlinfo[:-2] + ' cells'
|
||||||
print('PML: formulation: {}, order: {}, thickness: {}'.format(G.pmlformulation, len(G.cfs), pmlinfo))
|
print('PML: formulation: {}, order: {}, thickness: {}'.format(G.pmlformulation, len(G.cfs), pmlinfo))
|
||||||
pbar = tqdm(total=sum(1 for value in G.pmlthickness.values() if value > 0), desc='Building PML boundaries', ncols=get_terminal_width() - 1, file=sys.stdout, disable=not progressbars)
|
pbar = tqdm(total=sum(1 for value in G.pmlthickness.values() if value > 0), desc='Building PML boundaries', ncols=get_terminal_width() - 1, file=sys.stdout, disable=not config.general['progressbars'])
|
||||||
build_pmls(G, pbar)
|
build_pmls(G, pbar)
|
||||||
pbar.close()
|
pbar.close()
|
||||||
|
|
||||||
# Build the model, i.e. set the material properties (ID) for every edge
|
# Build the model, i.e. set the material properties (ID) for every edge
|
||||||
# of every Yee cell
|
# of every Yee cell
|
||||||
if messages: print()
|
if config.general['messages']: print()
|
||||||
pbar = tqdm(total=2, desc='Building main grid', ncols=get_terminal_width() - 1, file=sys.stdout, disable=not progressbars)
|
pbar = tqdm(total=2, desc='Building main grid', ncols=get_terminal_width() - 1, file=sys.stdout, disable=not config.general['progressbars'])
|
||||||
build_electric_components(G.solid, G.rigidE, G.ID, G)
|
build_electric_components(G.solid, G.rigidE, G.ID, G)
|
||||||
pbar.update()
|
pbar.update()
|
||||||
build_magnetic_components(G.solid, G.rigidH, G.ID, G)
|
build_magnetic_components(G.solid, G.rigidH, G.ID, G)
|
||||||
@@ -218,19 +208,19 @@ def run_model(args, currentmodelrun, modelend, numbermodelruns, inputfile, usern
|
|||||||
|
|
||||||
# Add PEC boundaries to invariant direction in 2D modes
|
# Add PEC boundaries to invariant direction in 2D modes
|
||||||
# N.B. 2D modes are a single cell slice of 3D grid
|
# N.B. 2D modes are a single cell slice of 3D grid
|
||||||
if '2D TMx' in mode:
|
if '2D TMx' in config.mode:
|
||||||
# Ey & Ez components
|
# Ey & Ez components
|
||||||
G.ID[1, 0, :, :] = 0
|
G.ID[1, 0, :, :] = 0
|
||||||
G.ID[1, 1, :, :] = 0
|
G.ID[1, 1, :, :] = 0
|
||||||
G.ID[2, 0, :, :] = 0
|
G.ID[2, 0, :, :] = 0
|
||||||
G.ID[2, 1, :, :] = 0
|
G.ID[2, 1, :, :] = 0
|
||||||
elif '2D TMy' in mode:
|
elif '2D TMy' in config.mode:
|
||||||
# Ex & Ez components
|
# Ex & Ez components
|
||||||
G.ID[0, :, 0, :] = 0
|
G.ID[0, :, 0, :] = 0
|
||||||
G.ID[0, :, 1, :] = 0
|
G.ID[0, :, 1, :] = 0
|
||||||
G.ID[2, :, 0, :] = 0
|
G.ID[2, :, 0, :] = 0
|
||||||
G.ID[2, :, 1, :] = 0
|
G.ID[2, :, 1, :] = 0
|
||||||
elif '2D TMz' in mode:
|
elif '2D TMz' in config.mode:
|
||||||
# Ex & Ey components
|
# Ex & Ey components
|
||||||
G.ID[0, :, :, 0] = 0
|
G.ID[0, :, :, 0] = 0
|
||||||
G.ID[0, :, :, 1] = 0
|
G.ID[0, :, :, 1] = 0
|
||||||
@@ -245,16 +235,23 @@ def run_model(args, currentmodelrun, modelend, numbermodelruns, inputfile, usern
|
|||||||
# Initialise arrays of update coefficients to pass to update functions
|
# Initialise arrays of update coefficients to pass to update functions
|
||||||
G.initialise_std_update_coeff_arrays()
|
G.initialise_std_update_coeff_arrays()
|
||||||
|
|
||||||
# Initialise arrays of update coefficients and temporary values if
|
# Set datatype for dispersive arrays if there are any dispersive materials.
|
||||||
# there are any dispersive materials
|
if config.materials['maxpoles'] != 0:
|
||||||
if Material.maxpoles != 0:
|
drudelorentz = any([m for m in G.materials if 'drude' in m.type or 'lorentz' in m.type])
|
||||||
|
if drudelorentz:
|
||||||
|
config.materials['dispersivedtype'] = config.dtypes['complex']
|
||||||
|
config.materials['dispersiveCdtype'] = config.dtypes['C_complex']
|
||||||
|
else:
|
||||||
|
config.materials['dispersivedtype'] = config.dtypes['float_or_double']
|
||||||
|
config.materials['dispersiveCdtype'] = config.dtypes['C_float_or_double']
|
||||||
|
|
||||||
# Update estimated memory (RAM) usage
|
# Update estimated memory (RAM) usage
|
||||||
G.memoryusage += int(3 * Material.maxpoles * (G.nx + 1) * (G.ny + 1) * (G.nz + 1) * np.dtype(complextype).itemsize)
|
G.memoryusage += int(3 * config.materials['maxpoles'] * (G.nx + 1) * (G.ny + 1) * (G.nz + 1) * np.dtype(config.materials['dispersivedtype']).itemsize)
|
||||||
G.memory_check()
|
G.memory_check()
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
print('\nMemory (RAM) required - updated (dispersive): ~{}\n'.format(human_size(G.memoryusage)))
|
print('\nMemory (RAM) required - updated (dispersive): ~{}\n'.format(human_size(G.memoryusage)))
|
||||||
|
|
||||||
G.initialise_dispersive_arrays()
|
G.initialise_dispersive_arrays(config.materials['dispersivedtype'])
|
||||||
|
|
||||||
# Check there is sufficient memory to store any snapshots
|
# Check there is sufficient memory to store any snapshots
|
||||||
if G.snapshots:
|
if G.snapshots:
|
||||||
@@ -264,13 +261,13 @@ def run_model(args, currentmodelrun, modelend, numbermodelruns, inputfile, usern
|
|||||||
snapsmemsize += (2 * snap.datasizefield)
|
snapsmemsize += (2 * snap.datasizefield)
|
||||||
G.memoryusage += int(snapsmemsize)
|
G.memoryusage += int(snapsmemsize)
|
||||||
G.memory_check(snapsmemsize=int(snapsmemsize))
|
G.memory_check(snapsmemsize=int(snapsmemsize))
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
print('\nMemory (RAM) required - updated (snapshots): ~{}\n'.format(human_size(G.memoryusage)))
|
print('\nMemory (RAM) required - updated (snapshots): ~{}\n'.format(human_size(G.memoryusage)))
|
||||||
|
|
||||||
# Process complete list of materials - calculate update coefficients,
|
# Process complete list of materials - calculate update coefficients,
|
||||||
# store in arrays, and build text list of materials/properties
|
# store in arrays, and build text list of materials/properties
|
||||||
materialsdata = process_materials(G)
|
materialsdata = process_materials(G)
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
print('\nMaterials:')
|
print('\nMaterials:')
|
||||||
materialstable = SingleTable(materialsdata)
|
materialstable = SingleTable(materialsdata)
|
||||||
materialstable.outer_border = False
|
materialstable.outer_border = False
|
||||||
@@ -279,19 +276,19 @@ def run_model(args, currentmodelrun, modelend, numbermodelruns, inputfile, usern
|
|||||||
|
|
||||||
# Check to see if numerical dispersion might be a problem
|
# Check to see if numerical dispersion might be a problem
|
||||||
results = dispersion_analysis(G)
|
results = dispersion_analysis(G)
|
||||||
if results['error'] and messages:
|
if results['error'] and config.general['messages']:
|
||||||
print(Fore.RED + "\nWARNING: Numerical dispersion analysis not carried out as {}".format(results['error']) + Style.RESET_ALL)
|
print(Fore.RED + "\nWARNING: Numerical dispersion analysis not carried out as {}".format(results['error']) + Style.RESET_ALL)
|
||||||
elif results['N'] < numdispersion['mingridsampling']:
|
elif results['N'] < config.numdispersion['mingridsampling']:
|
||||||
raise GeneralError("Non-physical wave propagation: Material '{}' has wavelength sampled by {} cells, less than required minimum for physical wave propagation. Maximum significant frequency estimated as {:g}Hz".format(results['material'].ID, results['N'], results['maxfreq']))
|
raise GeneralError("Non-physical wave propagation: Material '{}' has wavelength sampled by {} cells, less than required minimum for physical wave propagation. Maximum significant frequency estimated as {:g}Hz".format(results['material'].ID, results['N'], results['maxfreq']))
|
||||||
elif results['deltavp'] and np.abs(results['deltavp']) > numdispersion['maxnumericaldisp'] and messages:
|
elif results['deltavp'] and np.abs(results['deltavp']) > config.numdispersion['maxnumericaldisp'] and config.general['messages']:
|
||||||
print(Fore.RED + "\nWARNING: Potentially significant numerical dispersion. Estimated largest physical phase-velocity error is {:.2f}% in material '{}' whose wavelength sampled by {} cells. Maximum significant frequency estimated as {:g}Hz".format(results['deltavp'], results['material'].ID, results['N'], results['maxfreq']) + Style.RESET_ALL)
|
print(Fore.RED + "\nWARNING: Potentially significant numerical dispersion. Estimated largest physical phase-velocity error is {:.2f}% in material '{}' whose wavelength sampled by {} cells. Maximum significant frequency estimated as {:g}Hz".format(results['deltavp'], results['material'].ID, results['N'], results['maxfreq']) + Style.RESET_ALL)
|
||||||
elif results['deltavp'] and messages:
|
elif results['deltavp'] and config.general['messages']:
|
||||||
print("\nNumerical dispersion analysis: estimated largest physical phase-velocity error is {:.2f}% in material '{}' whose wavelength sampled by {} cells. Maximum significant frequency estimated as {:g}Hz".format(results['deltavp'], results['material'].ID, results['N'], results['maxfreq']))
|
print("\nNumerical dispersion analysis: estimated largest physical phase-velocity error is {:.2f}% in material '{}' whose wavelength sampled by {} cells. Maximum significant frequency estimated as {:g}Hz".format(results['deltavp'], results['material'].ID, results['N'], results['maxfreq']))
|
||||||
|
|
||||||
# If geometry information to be reused between model runs
|
# If geometry information to be reused between model runs
|
||||||
else:
|
else:
|
||||||
inputfilestr = '\n--- Model {}/{}, input file (not re-processed, i.e. geometry fixed): {}'.format(currentmodelrun, modelend, inputfile.name)
|
inputfilestr = '\n--- Model {}/{}, input file (not re-processed, i.e. geometry fixed): {}'.format(currentmodelrun, modelend, inputfile.name)
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
print(Fore.GREEN + '{} {}\n'.format(inputfilestr, '-' * (get_terminal_width() - 1 - len(inputfilestr))) + Style.RESET_ALL)
|
print(Fore.GREEN + '{} {}\n'.format(inputfilestr, '-' * (get_terminal_width() - 1 - len(inputfilestr))) + Style.RESET_ALL)
|
||||||
|
|
||||||
# Clear arrays for field components
|
# Clear arrays for field components
|
||||||
@@ -320,18 +317,16 @@ def run_model(args, currentmodelrun, modelend, numbermodelruns, inputfile, usern
|
|||||||
receiver.zcoord = receiver.zcoordorigin + (currentmodelrun - 1) * G.rxsteps[2]
|
receiver.zcoord = receiver.zcoordorigin + (currentmodelrun - 1) * G.rxsteps[2]
|
||||||
|
|
||||||
# Write files for any geometry views and geometry object outputs
|
# Write files for any geometry views and geometry object outputs
|
||||||
if not (G.geometryviews or G.geometryobjectswrite) and args.geometry_only and messages:
|
if not (G.geometryviews or G.geometryobjectswrite) and args.geometry_only and config.general['messages']:
|
||||||
print(Fore.RED + '\nWARNING: No geometry views or geometry objects to output found.' + Style.RESET_ALL)
|
print(Fore.RED + '\nWARNING: No geometry views or geometry objects to output found.' + Style.RESET_ALL)
|
||||||
if G.geometryviews:
|
if config.general['messages']: print()
|
||||||
if messages: print()
|
|
||||||
for i, geometryview in enumerate(G.geometryviews):
|
for i, geometryview in enumerate(G.geometryviews):
|
||||||
geometryview.set_filename(appendmodelnumber, G)
|
geometryview.set_filename(appendmodelnumber)
|
||||||
pbar = tqdm(total=geometryview.datawritesize, unit='byte', unit_scale=True, desc='Writing geometry view file {}/{}, {}'.format(i + 1, len(G.geometryviews), os.path.split(geometryview.filename)[1]), ncols=get_terminal_width() - 1, file=sys.stdout, disable=not progressbars)
|
pbar = tqdm(total=geometryview.datawritesize, unit='byte', unit_scale=True, desc='Writing geometry view file {}/{}, {}'.format(i + 1, len(G.geometryviews), os.path.split(geometryview.filename)[1]), ncols=get_terminal_width() - 1, file=sys.stdout, disable=not config.general['progressbars'])
|
||||||
geometryview.write_vtk(G, pbar)
|
geometryview.write_vtk(G, pbar)
|
||||||
pbar.close()
|
pbar.close()
|
||||||
if G.geometryobjectswrite:
|
|
||||||
for i, geometryobject in enumerate(G.geometryobjectswrite):
|
for i, geometryobject in enumerate(G.geometryobjectswrite):
|
||||||
pbar = tqdm(total=geometryobject.datawritesize, unit='byte', unit_scale=True, desc='Writing geometry object file {}/{}, {}'.format(i + 1, len(G.geometryobjectswrite), os.path.split(geometryobject.filename)[1]), ncols=get_terminal_width() - 1, file=sys.stdout, disable=not progressbars)
|
pbar = tqdm(total=geometryobject.datawritesize, unit='byte', unit_scale=True, desc='Writing geometry object file {}/{}, {}'.format(i + 1, len(G.geometryobjectswrite), os.path.split(geometryobject.filename)[1]), ncols=get_terminal_width() - 1, file=sys.stdout, disable=not config.general['progressbars'])
|
||||||
geometryobject.write_hdf5(G, pbar)
|
geometryobject.write_hdf5(G, pbar)
|
||||||
pbar.close()
|
pbar.close()
|
||||||
|
|
||||||
@@ -341,29 +336,17 @@ def run_model(args, currentmodelrun, modelend, numbermodelruns, inputfile, usern
|
|||||||
|
|
||||||
# Run simulation
|
# Run simulation
|
||||||
else:
|
else:
|
||||||
# Output filename
|
# Check and set output directory and filename
|
||||||
inputdirectory, inputfilename = os.path.split(os.path.join(G.inputdirectory, G.inputfilename))
|
if not os.path.isdir(config.outputfilepath):
|
||||||
if G.outputdirectory is None:
|
os.mkdir(config.outputfilepath)
|
||||||
outputdir = inputdirectory
|
if config.general['messages']:
|
||||||
else:
|
print('\nCreated output directory: {}'.format(config.outputfilepath))
|
||||||
outputdir = G.outputdirectory
|
outputfile = os.path.join(config.outputfilepath, os.path.splitext(os.path.split(config.inputfilepath)[1])[0] + appendmodelnumber + '.out')
|
||||||
# Save current directory
|
if config.general['messages']:
|
||||||
curdir = os.getcwd()
|
|
||||||
os.chdir(inputdirectory)
|
|
||||||
outputdir = os.path.abspath(outputdir)
|
|
||||||
if not os.path.isdir(outputdir):
|
|
||||||
os.mkdir(outputdir)
|
|
||||||
if messages:
|
|
||||||
print('\nCreated output directory: {}'.format(outputdir))
|
|
||||||
# Restore current directory
|
|
||||||
os.chdir(curdir)
|
|
||||||
basename, ext = os.path.splitext(inputfilename)
|
|
||||||
outputfile = os.path.join(outputdir, basename + appendmodelnumber + '.out')
|
|
||||||
if messages:
|
|
||||||
print('\nOutput file: {}\n'.format(outputfile))
|
print('\nOutput file: {}\n'.format(outputfile))
|
||||||
|
|
||||||
# Main FDTD solving functions for either CPU or GPU
|
# Main FDTD solving functions for either CPU or GPU
|
||||||
if config.gpus is None:
|
if config.cuda['gpus'] is None:
|
||||||
tsolve = solve_cpu(currentmodelrun, modelend, G)
|
tsolve = solve_cpu(currentmodelrun, modelend, G)
|
||||||
else:
|
else:
|
||||||
tsolve, memsolve = solve_gpu(currentmodelrun, modelend, G)
|
tsolve, memsolve = solve_gpu(currentmodelrun, modelend, G)
|
||||||
@@ -374,21 +357,21 @@ def run_model(args, currentmodelrun, modelend, numbermodelruns, inputfile, usern
|
|||||||
# Write any snapshots to file
|
# Write any snapshots to file
|
||||||
if G.snapshots:
|
if G.snapshots:
|
||||||
# Create directory and construct filename from user-supplied name and model run number
|
# Create directory and construct filename from user-supplied name and model run number
|
||||||
snapshotdir = os.path.join(G.inputdirectory, os.path.splitext(G.inputfilename)[0] + '_snaps' + appendmodelnumber)
|
snapshotdir = os.path.splitext(config.inputfilepath)[0] + '_snaps' + appendmodelnumber
|
||||||
if not os.path.exists(snapshotdir):
|
if not os.path.exists(snapshotdir):
|
||||||
os.mkdir(snapshotdir)
|
os.mkdir(snapshotdir)
|
||||||
|
|
||||||
if messages: print()
|
if config.general['messages']: print()
|
||||||
for i, snap in enumerate(G.snapshots):
|
for i, snap in enumerate(G.snapshots):
|
||||||
snap.filename = os.path.abspath(os.path.join(snapshotdir, snap.basefilename + '.vti'))
|
snap.filename = os.path.abspath(os.path.join(snapshotdir, snap.basefilename + '.vti'))
|
||||||
pbar = tqdm(total=snap.vtkdatawritesize, leave=True, unit='byte', unit_scale=True, desc='Writing snapshot file {} of {}, {}'.format(i + 1, len(G.snapshots), os.path.split(snap.filename)[1]), ncols=get_terminal_width() - 1, file=sys.stdout, disable=not progressbars)
|
pbar = tqdm(total=snap.vtkdatawritesize, leave=True, unit='byte', unit_scale=True, desc='Writing snapshot file {} of {}, {}'.format(i + 1, len(G.snapshots), os.path.split(snap.filename)[1]), ncols=get_terminal_width() - 1, file=sys.stdout, disable=not config.general['progressbars'])
|
||||||
snap.write_vtk_imagedata(pbar, G)
|
snap.write_vtk_imagedata(pbar, G)
|
||||||
pbar.close()
|
pbar.close()
|
||||||
if messages: print()
|
if config.general['messages']: print()
|
||||||
|
|
||||||
if messages:
|
if config.general['messages']:
|
||||||
memGPU = ''
|
memGPU = ''
|
||||||
if config.gpus:
|
if config.cuda['gpus']:
|
||||||
memGPU = ' host + ~{} GPU'.format(human_size(memsolve))
|
memGPU = ' host + ~{} GPU'.format(human_size(memsolve))
|
||||||
print('\nMemory (RAM) used: ~{}{}'.format(human_size(p.memory_full_info().uss), memGPU))
|
print('\nMemory (RAM) used: ~{}{}'.format(human_size(p.memory_full_info().uss), memGPU))
|
||||||
print('Solving time [HH:MM:SS]: {}'.format(datetime.timedelta(seconds=tsolve)))
|
print('Solving time [HH:MM:SS]: {}'.format(datetime.timedelta(seconds=tsolve)))
|
||||||
@@ -415,9 +398,26 @@ def solve_cpu(currentmodelrun, modelend, G):
|
|||||||
tsolve (float): Time taken to execute solving (seconds)
|
tsolve (float): Time taken to execute solving (seconds)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Set update functions if there are dispersive materials
|
||||||
|
if config.materials['maxpoles'] != 0:
|
||||||
|
if config.materials['dispersivedtype'] == config.dtypes['complex']:
|
||||||
|
if config.materials['maxpoles'] == 1:
|
||||||
|
update_electric_dispersive_A = update_electric_dispersive_1pole_A
|
||||||
|
update_electric_dispersive_B = update_electric_dispersive_1pole_B
|
||||||
|
elif config.materials['maxpoles'] > 1:
|
||||||
|
update_electric_dispersive_A = update_electric_dispersive_multipole_A
|
||||||
|
update_electric_dispersive_B = update_electric_dispersive_multipole_B
|
||||||
|
elif config.materials['dispersivedtype'] == config.dtypes['float_or_double']:
|
||||||
|
if config.materials['maxpoles'] == 2:
|
||||||
|
update_electric_dispersive_A = update_electric_dispersive_debye_1pole_A
|
||||||
|
update_electric_dispersive_B = update_electric_dispersive_debye_1pole_B
|
||||||
|
elif config.materials['maxpoles'] == 1:
|
||||||
|
update_electric_dispersive_A = update_electric_dispersive_debye_multipole_A
|
||||||
|
update_electric_dispersive_B = update_electric_dispersive_debye_multipole_B
|
||||||
|
|
||||||
tsolvestart = timer()
|
tsolvestart = timer()
|
||||||
|
|
||||||
for iteration in tqdm(range(G.iterations), desc='Running simulation, model ' + str(currentmodelrun) + '/' + str(modelend), ncols=get_terminal_width() - 1, file=sys.stdout, disable=not progressbars):
|
for iteration in tqdm(range(G.iterations), desc='Running simulation, model ' + str(currentmodelrun) + '/' + str(modelend), ncols=get_terminal_width() - 1, file=sys.stdout, disable=not config.general['progressbars']):
|
||||||
# Store field component values for every receiver and transmission line
|
# Store field component values for every receiver and transmission line
|
||||||
store_outputs(iteration, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz, G)
|
store_outputs(iteration, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz, G)
|
||||||
|
|
||||||
@@ -427,7 +427,7 @@ def solve_cpu(currentmodelrun, modelend, G):
|
|||||||
snap.store(G)
|
snap.store(G)
|
||||||
|
|
||||||
# Update magnetic field components
|
# Update magnetic field components
|
||||||
update_magnetic(G.nx, G.ny, G.nz, hostinfo['ompthreads'], G.updatecoeffsH, G.ID, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz)
|
update_magnetic(G.nx, G.ny, G.nz, config.hostinfo['ompthreads'], G.updatecoeffsH, G.ID, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz)
|
||||||
|
|
||||||
# Update magnetic field components with the PML correction
|
# Update magnetic field components with the PML correction
|
||||||
for pml in G.pmls:
|
for pml in G.pmls:
|
||||||
@@ -439,14 +439,12 @@ def solve_cpu(currentmodelrun, modelend, G):
|
|||||||
|
|
||||||
# Update electric field components
|
# Update electric field components
|
||||||
# All materials are non-dispersive so do standard update
|
# All materials are non-dispersive so do standard update
|
||||||
if Material.maxpoles == 0:
|
if config.materials['maxpoles'] == 0:
|
||||||
update_electric(G.nx, G.ny, G.nz, hostinfo['ompthreads'], G.updatecoeffsE, G.ID, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz)
|
update_electric(G.nx, G.ny, G.nz, config.hostinfo['ompthreads'], G.updatecoeffsE, G.ID, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz)
|
||||||
# If there are any dispersive materials do 1st part of dispersive update
|
# If there are any dispersive materials do 1st part of dispersive update
|
||||||
# (it is split into two parts as it requires present and updated electric field values).
|
# (it is split into two parts as it requires present and updated electric field values).
|
||||||
elif Material.maxpoles == 1:
|
else:
|
||||||
update_electric_dispersive_1pole_A(G.nx, G.ny, G.nz, hostinfo['ompthreads'], G.updatecoeffsE, G.updatecoeffsdispersive, G.ID, G.Tx, G.Ty, G.Tz, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz)
|
update_electric_dispersive_A(G.nx, G.ny, G.nz, config.hostinfo['ompthreads'], config.materials['maxpoles'], G.updatecoeffsE, G.updatecoeffsdispersive, G.ID, G.Tx, G.Ty, G.Tz, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz)
|
||||||
elif Material.maxpoles > 1:
|
|
||||||
update_electric_dispersive_multipole_A(G.nx, G.ny, G.nz, hostinfo['ompthreads'], Material.maxpoles, G.updatecoeffsE, G.updatecoeffsdispersive, G.ID, G.Tx, G.Ty, G.Tz, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz)
|
|
||||||
|
|
||||||
# Update electric field components with the PML correction
|
# Update electric field components with the PML correction
|
||||||
for pml in G.pmls:
|
for pml in G.pmls:
|
||||||
@@ -460,10 +458,8 @@ def solve_cpu(currentmodelrun, modelend, G):
|
|||||||
# (it is split into two parts as it requires present and updated electric
|
# (it is split into two parts as it requires present and updated electric
|
||||||
# field values). Therefore it can only be completely updated after the
|
# field values). Therefore it can only be completely updated after the
|
||||||
# electric field has been updated by the PML and source updates.
|
# electric field has been updated by the PML and source updates.
|
||||||
if Material.maxpoles == 1:
|
if config.materials['maxpoles'] != 0:
|
||||||
update_electric_dispersive_1pole_B(G.nx, G.ny, G.nz, hostinfo['ompthreads'], G.updatecoeffsdispersive, G.ID, G.Tx, G.Ty, G.Tz, G.Ex, G.Ey, G.Ez)
|
update_electric_dispersive_B(G.nx, G.ny, G.nz, config.hostinfo['ompthreads'], config.materials['maxpoles'], G.updatecoeffsdispersive, G.ID, G.Tx, G.Ty, G.Tz, G.Ex, G.Ey, G.Ez)
|
||||||
elif Material.maxpoles > 1:
|
|
||||||
update_electric_dispersive_multipole_B(G.nx, G.ny, G.nz, hostinfo['ompthreads'], Material.maxpoles, G.updatecoeffsdispersive, G.ID, G.Tx, G.Ty, G.Tz, G.Ex, G.Ey, G.Ez)
|
|
||||||
|
|
||||||
tsolve = timer() - tsolvestart
|
tsolve = timer() - tsolvestart
|
||||||
|
|
||||||
@@ -494,32 +490,30 @@ def solve_gpu(currentmodelrun, modelend, G):
|
|||||||
compiler_opts = None
|
compiler_opts = None
|
||||||
|
|
||||||
# Create device handle and context on specifc GPU device (and make it current context)
|
# Create device handle and context on specifc GPU device (and make it current context)
|
||||||
dev = drv.Device(config.gpus.deviceID)
|
dev = drv.Device(config.cuda['gpus'].deviceID)
|
||||||
ctx = dev.make_context()
|
ctx = dev.make_context()
|
||||||
|
|
||||||
# Electric and magnetic field updates - prepare kernels, and get kernel functions
|
# Electric and magnetic field updates - prepare kernels, get kernel functions, and initialise arrays on GPU
|
||||||
if Material.maxpoles > 0:
|
if config.materials['maxpoles'] == 0:
|
||||||
kernels_fields = SourceModule(kernels_template_fields.substitute(REAL=cudafloattype, COMPLEX=cudacomplextype, N_updatecoeffsE=G.updatecoeffsE.size, N_updatecoeffsH=G.updatecoeffsH.size, NY_MATCOEFFS=G.updatecoeffsE.shape[1], NY_MATDISPCOEFFS=G.updatecoeffsdispersive.shape[1], NX_FIELDS=G.Ex.shape[0], NY_FIELDS=G.Ex.shape[1], NZ_FIELDS=G.Ex.shape[2], NX_ID=G.ID.shape[1], NY_ID=G.ID.shape[2], NZ_ID=G.ID.shape[3], NX_T=G.Tx.shape[1], NY_T=G.Tx.shape[2], NZ_T=G.Tx.shape[3]), options=compiler_opts)
|
kernels_fields = SourceModule(kernels_template_fields.substitute(REAL=config.dtypes['C_float_or_double'], REAL_OR_COMPLEX=config.dtypes['C_complex'], N_updatecoeffsE=G.updatecoeffsE.size, N_updatecoeffsH=G.updatecoeffsH.size, NY_MATCOEFFS=G.updatecoeffsE.shape[1], NY_MATDISPCOEFFS=1, NX_FIELDS=G.Ex.shape[0], NY_FIELDS=G.Ex.shape[1], NZ_FIELDS=G.Ex.shape[2], NX_ID=G.ID.shape[1], NY_ID=G.ID.shape[2], NZ_ID=G.ID.shape[3], NX_T=1, NY_T=1, NZ_T=1), options=compiler_opts)
|
||||||
else: # Set to one any substitutions for dispersive materials
|
|
||||||
kernels_fields = SourceModule(kernels_template_fields.substitute(REAL=cudafloattype, COMPLEX=cudacomplextype, N_updatecoeffsE=G.updatecoeffsE.size, N_updatecoeffsH=G.updatecoeffsH.size, NY_MATCOEFFS=G.updatecoeffsE.shape[1], NY_MATDISPCOEFFS=1, NX_FIELDS=G.Ex.shape[0], NY_FIELDS=G.Ex.shape[1], NZ_FIELDS=G.Ex.shape[2], NX_ID=G.ID.shape[1], NY_ID=G.ID.shape[2], NZ_ID=G.ID.shape[3], NX_T=1, NY_T=1, NZ_T=1), options=compiler_opts)
|
else: # # If there are any dispersive materials (updates are split into two parts as they require present and updated electric field values).
|
||||||
|
kernels_fields = SourceModule(kernels_template_fields.substitute(REAL=config.dtypes['C_float_or_double'], REAL_OR_COMPLEX=config.dtypes['C_complex'], N_updatecoeffsE=G.updatecoeffsE.size, N_updatecoeffsH=G.updatecoeffsH.size, NY_MATCOEFFS=G.updatecoeffsE.shape[1], NY_MATDISPCOEFFS=G.updatecoeffsdispersive.shape[1], NX_FIELDS=G.Ex.shape[0], NY_FIELDS=G.Ex.shape[1], NZ_FIELDS=G.Ex.shape[2], NX_ID=G.ID.shape[1], NY_ID=G.ID.shape[2], NZ_ID=G.ID.shape[3], NX_T=G.Tx.shape[1], NY_T=G.Tx.shape[2], NZ_T=G.Tx.shape[3]), options=compiler_opts)
|
||||||
|
update_e_dispersive_A_gpu = kernels_fields.get_function("update_e_dispersive_A")
|
||||||
|
update_e_dispersive_B_gpu = kernels_fields.get_function("update_e_dispersive_B")
|
||||||
|
G.gpu_initialise_dispersive_arrays()
|
||||||
update_e_gpu = kernels_fields.get_function("update_e")
|
update_e_gpu = kernels_fields.get_function("update_e")
|
||||||
update_h_gpu = kernels_fields.get_function("update_h")
|
update_h_gpu = kernels_fields.get_function("update_h")
|
||||||
|
|
||||||
# Copy material coefficient arrays to constant memory of GPU (must be <64KB) for fields kernels
|
# Copy material coefficient arrays to constant memory of GPU (must be <64KB) for fields kernels
|
||||||
updatecoeffsE = kernels_fields.get_global('updatecoeffsE')[0]
|
updatecoeffsE = kernels_fields.get_global('updatecoeffsE')[0]
|
||||||
updatecoeffsH = kernels_fields.get_global('updatecoeffsH')[0]
|
updatecoeffsH = kernels_fields.get_global('updatecoeffsH')[0]
|
||||||
if G.updatecoeffsE.nbytes + G.updatecoeffsH.nbytes > config.gpus.constmem:
|
if G.updatecoeffsE.nbytes + G.updatecoeffsH.nbytes > config.cuda['gpus'].constmem:
|
||||||
raise GeneralError('Too many materials in the model to fit onto constant memory of size {} on {} - {} GPU'.format(human_size(config.gpus.constmem), config.gpus.deviceID, config.gpus.name))
|
raise GeneralError('Too many materials in the model to fit onto constant memory of size {} on {} - {} GPU'.format(human_size(config.cuda['gpus'].constmem), config.cuda['gpus'].deviceID, config.cuda['gpus'].name))
|
||||||
else:
|
else:
|
||||||
drv.memcpy_htod(updatecoeffsE, G.updatecoeffsE)
|
drv.memcpy_htod(updatecoeffsE, G.updatecoeffsE)
|
||||||
drv.memcpy_htod(updatecoeffsH, G.updatecoeffsH)
|
drv.memcpy_htod(updatecoeffsH, G.updatecoeffsH)
|
||||||
|
|
||||||
# Electric and magnetic field updates - dispersive materials - get kernel functions and initialise array on GPU
|
|
||||||
if Material.maxpoles > 0: # If there are any dispersive materials (updates are split into two parts as they require present and updated electric field values).
|
|
||||||
update_e_dispersive_A_gpu = kernels_fields.get_function("update_e_dispersive_A")
|
|
||||||
update_e_dispersive_B_gpu = kernels_fields.get_function("update_e_dispersive_B")
|
|
||||||
G.gpu_initialise_dispersive_arrays()
|
|
||||||
|
|
||||||
# Electric and magnetic field updates - set blocks per grid and initialise field arrays on GPU
|
# Electric and magnetic field updates - set blocks per grid and initialise field arrays on GPU
|
||||||
G.gpu_set_blocks_per_grid()
|
G.gpu_set_blocks_per_grid()
|
||||||
G.gpu_initialise_arrays()
|
G.gpu_initialise_arrays()
|
||||||
@@ -527,12 +521,10 @@ def solve_gpu(currentmodelrun, modelend, G):
|
|||||||
# PML updates
|
# PML updates
|
||||||
if G.pmls:
|
if G.pmls:
|
||||||
# Prepare kernels
|
# Prepare kernels
|
||||||
pmlmodulelectric = 'gprMax.pml_updates.pml_updates_electric_' + G.pmlformulation + '_gpu'
|
kernelelectricfunc = getattr(import_module('gprMax.cuda.pml_updates_electric_' + G.pmlformulation), 'kernels_template_pml_electric_' + G.pmlformulation)
|
||||||
kernelelectricfunc = getattr(import_module(pmlmodulelectric), 'kernels_template_pml_electric_' + G.pmlformulation)
|
kernelmagneticfunc = getattr(import_module('gprMax.cuda.pml_updates_magnetic_' + G.pmlformulation), 'kernels_template_pml_magnetic_' + G.pmlformulation)
|
||||||
pmlmodulemagnetic = 'gprMax.pml_updates.pml_updates_magnetic_' + G.pmlformulation + '_gpu'
|
kernels_pml_electric = SourceModule(kernelelectricfunc.substitute(REAL=config.dtypes['C_float_or_double'], N_updatecoeffsE=G.updatecoeffsE.size, NY_MATCOEFFS=G.updatecoeffsE.shape[1], NX_FIELDS=G.Ex.shape[0], NY_FIELDS=G.Ex.shape[1], NZ_FIELDS=G.Ex.shape[2], NX_ID=G.ID.shape[1], NY_ID=G.ID.shape[2], NZ_ID=G.ID.shape[3]), options=compiler_opts)
|
||||||
kernelmagneticfunc = getattr(import_module(pmlmodulemagnetic), 'kernels_template_pml_magnetic_' + G.pmlformulation)
|
kernels_pml_magnetic = SourceModule(kernelmagneticfunc.substitute(REAL=config.dtypes['C_float_or_double'], N_updatecoeffsH=G.updatecoeffsH.size, NY_MATCOEFFS=G.updatecoeffsH.shape[1], NX_FIELDS=G.Hx.shape[0], NY_FIELDS=G.Hx.shape[1], NZ_FIELDS=G.Hx.shape[2], NX_ID=G.ID.shape[1], NY_ID=G.ID.shape[2], NZ_ID=G.ID.shape[3]), options=compiler_opts)
|
||||||
kernels_pml_electric = SourceModule(kernelelectricfunc.substitute(REAL=cudafloattype, N_updatecoeffsE=G.updatecoeffsE.size, NY_MATCOEFFS=G.updatecoeffsE.shape[1], NX_FIELDS=G.Ex.shape[0], NY_FIELDS=G.Ex.shape[1], NZ_FIELDS=G.Ex.shape[2], NX_ID=G.ID.shape[1], NY_ID=G.ID.shape[2], NZ_ID=G.ID.shape[3]), options=compiler_opts)
|
|
||||||
kernels_pml_magnetic = SourceModule(kernelmagneticfunc.substitute(REAL=cudafloattype, N_updatecoeffsH=G.updatecoeffsH.size, NY_MATCOEFFS=G.updatecoeffsH.shape[1], NX_FIELDS=G.Hx.shape[0], NY_FIELDS=G.Hx.shape[1], NZ_FIELDS=G.Hx.shape[2], NX_ID=G.ID.shape[1], NY_ID=G.ID.shape[2], NZ_ID=G.ID.shape[3]), options=compiler_opts)
|
|
||||||
# Copy material coefficient arrays to constant memory of GPU (must be <64KB) for PML kernels
|
# Copy material coefficient arrays to constant memory of GPU (must be <64KB) for PML kernels
|
||||||
updatecoeffsE = kernels_pml_electric.get_global('updatecoeffsE')[0]
|
updatecoeffsE = kernels_pml_electric.get_global('updatecoeffsE')[0]
|
||||||
updatecoeffsH = kernels_pml_magnetic.get_global('updatecoeffsH')[0]
|
updatecoeffsH = kernels_pml_magnetic.get_global('updatecoeffsH')[0]
|
||||||
@@ -549,12 +541,13 @@ def solve_gpu(currentmodelrun, modelend, G):
|
|||||||
# Initialise arrays on GPU
|
# Initialise arrays on GPU
|
||||||
rxcoords_gpu, rxs_gpu = gpu_initialise_rx_arrays(G)
|
rxcoords_gpu, rxs_gpu = gpu_initialise_rx_arrays(G)
|
||||||
# Prepare kernel and get kernel function
|
# Prepare kernel and get kernel function
|
||||||
kernel_store_outputs = SourceModule(kernel_template_store_outputs.substitute(REAL=cudafloattype, NY_RXCOORDS=3, NX_RXS=6, NY_RXS=G.iterations, NZ_RXS=len(G.rxs), NX_FIELDS=G.Ex.shape[0], NY_FIELDS=G.Ex.shape[1], NZ_FIELDS=G.Ex.shape[2]), options=compiler_opts)
|
|
||||||
|
kernel_store_outputs = SourceModule(kernel_template_store_outputs.substitute(REAL=config.dtypes['C_float_or_double'], NY_RXCOORDS=3, NX_RXS=len(Rx.gpu_allowableoutputs), NY_RXS=G.iterations, NZ_RXS=len(G.rxs), NX_FIELDS=G.Ex.shape[0], NY_FIELDS=G.Ex.shape[1], NZ_FIELDS=G.Ex.shape[2]), options=compiler_opts)
|
||||||
store_outputs_gpu = kernel_store_outputs.get_function("store_outputs")
|
store_outputs_gpu = kernel_store_outputs.get_function("store_outputs")
|
||||||
|
|
||||||
# Sources - initialise arrays on GPU, prepare kernel and get kernel functions
|
# Sources - initialise arrays on GPU, prepare kernel and get kernel functions
|
||||||
if G.voltagesources + G.hertziandipoles + G.magneticdipoles:
|
if G.voltagesources + G.hertziandipoles + G.magneticdipoles:
|
||||||
kernels_sources = SourceModule(kernels_template_sources.substitute(REAL=cudafloattype, N_updatecoeffsE=G.updatecoeffsE.size, N_updatecoeffsH=G.updatecoeffsH.size, NY_MATCOEFFS=G.updatecoeffsE.shape[1], NY_SRCINFO=4, NY_SRCWAVES=G.iterations, NX_FIELDS=G.Ex.shape[0], NY_FIELDS=G.Ex.shape[1], NZ_FIELDS=G.Ex.shape[2], NX_ID=G.ID.shape[1], NY_ID=G.ID.shape[2], NZ_ID=G.ID.shape[3]), options=compiler_opts)
|
kernels_sources = SourceModule(kernels_template_sources.substitute(REAL=config.dtypes['C_float_or_double'], N_updatecoeffsE=G.updatecoeffsE.size, N_updatecoeffsH=G.updatecoeffsH.size, NY_MATCOEFFS=G.updatecoeffsE.shape[1], NY_SRCINFO=4, NY_SRCWAVES=G.iterations, NX_FIELDS=G.Ex.shape[0], NY_FIELDS=G.Ex.shape[1], NZ_FIELDS=G.Ex.shape[2], NX_ID=G.ID.shape[1], NY_ID=G.ID.shape[2], NZ_ID=G.ID.shape[3]), options=compiler_opts)
|
||||||
# Copy material coefficient arrays to constant memory of GPU (must be <64KB) for source kernels
|
# Copy material coefficient arrays to constant memory of GPU (must be <64KB) for source kernels
|
||||||
updatecoeffsE = kernels_sources.get_global('updatecoeffsE')[0]
|
updatecoeffsE = kernels_sources.get_global('updatecoeffsE')[0]
|
||||||
updatecoeffsH = kernels_sources.get_global('updatecoeffsH')[0]
|
updatecoeffsH = kernels_sources.get_global('updatecoeffsH')[0]
|
||||||
@@ -575,7 +568,7 @@ def solve_gpu(currentmodelrun, modelend, G):
|
|||||||
# Initialise arrays on GPU
|
# Initialise arrays on GPU
|
||||||
snapEx_gpu, snapEy_gpu, snapEz_gpu, snapHx_gpu, snapHy_gpu, snapHz_gpu = gpu_initialise_snapshot_array(G)
|
snapEx_gpu, snapEy_gpu, snapEz_gpu, snapHx_gpu, snapHy_gpu, snapHz_gpu = gpu_initialise_snapshot_array(G)
|
||||||
# Prepare kernel and get kernel function
|
# Prepare kernel and get kernel function
|
||||||
kernel_store_snapshot = SourceModule(kernel_template_store_snapshot.substitute(REAL=cudafloattype, NX_SNAPS=Snapshot.nx_max, NY_SNAPS=Snapshot.ny_max, NZ_SNAPS=Snapshot.nz_max, NX_FIELDS=G.Ex.shape[0], NY_FIELDS=G.Ex.shape[1], NZ_FIELDS=G.Ex.shape[2]), options=compiler_opts)
|
kernel_store_snapshot = SourceModule(kernel_template_store_snapshot.substitute(REAL=config.dtypes['C_float_or_double'], NX_SNAPS=Snapshot.nx_max, NY_SNAPS=Snapshot.ny_max, NZ_SNAPS=Snapshot.nz_max, NX_FIELDS=G.Ex.shape[0], NY_FIELDS=G.Ex.shape[1], NZ_FIELDS=G.Ex.shape[2]), options=compiler_opts)
|
||||||
store_snapshot_gpu = kernel_store_snapshot.get_function("store_snapshot")
|
store_snapshot_gpu = kernel_store_snapshot.get_function("store_snapshot")
|
||||||
|
|
||||||
# Iteration loop timer
|
# Iteration loop timer
|
||||||
@@ -583,7 +576,7 @@ def solve_gpu(currentmodelrun, modelend, G):
|
|||||||
iterend = drv.Event()
|
iterend = drv.Event()
|
||||||
iterstart.record()
|
iterstart.record()
|
||||||
|
|
||||||
for iteration in tqdm(range(G.iterations), desc='Running simulation, model ' + str(currentmodelrun) + '/' + str(modelend), ncols=get_terminal_width() - 1, file=sys.stdout, disable=not progressbars):
|
for iteration in tqdm(range(G.iterations), desc='Running simulation, model ' + str(currentmodelrun) + '/' + str(modelend), ncols=get_terminal_width() - 1, file=sys.stdout, disable=not config.general['progressbars']):
|
||||||
|
|
||||||
# Get GPU memory usage on final iteration
|
# Get GPU memory usage on final iteration
|
||||||
if iteration == G.iterations - 1:
|
if iteration == G.iterations - 1:
|
||||||
@@ -600,7 +593,7 @@ def solve_gpu(currentmodelrun, modelend, G):
|
|||||||
# Store any snapshots
|
# Store any snapshots
|
||||||
for i, snap in enumerate(G.snapshots):
|
for i, snap in enumerate(G.snapshots):
|
||||||
if snap.time == iteration + 1:
|
if snap.time == iteration + 1:
|
||||||
if not snapsgpu2cpu:
|
if not config.cuda['snapsgpu2cpu']:
|
||||||
store_snapshot_gpu(np.int32(i), np.int32(snap.xs),
|
store_snapshot_gpu(np.int32(i), np.int32(snap.xs),
|
||||||
np.int32(snap.xf), np.int32(snap.ys),
|
np.int32(snap.xf), np.int32(snap.ys),
|
||||||
np.int32(snap.yf), np.int32(snap.zs),
|
np.int32(snap.yf), np.int32(snap.zs),
|
||||||
@@ -629,7 +622,7 @@ def solve_gpu(currentmodelrun, modelend, G):
|
|||||||
update_h_gpu(np.int32(G.nx), np.int32(G.ny), np.int32(G.nz),
|
update_h_gpu(np.int32(G.nx), np.int32(G.ny), np.int32(G.nz),
|
||||||
G.ID_gpu.gpudata, G.Hx_gpu.gpudata, G.Hy_gpu.gpudata,
|
G.ID_gpu.gpudata, G.Hx_gpu.gpudata, G.Hy_gpu.gpudata,
|
||||||
G.Hz_gpu.gpudata, G.Ex_gpu.gpudata, G.Ey_gpu.gpudata,
|
G.Hz_gpu.gpudata, G.Ex_gpu.gpudata, G.Ey_gpu.gpudata,
|
||||||
G.Ez_gpu.gpudata, block=config.gpus.tpb, grid=config.gpus.bpg)
|
G.Ez_gpu.gpudata, block=config.cuda['gpus'].tpb, grid=config.cuda['gpus'].bpg)
|
||||||
|
|
||||||
# Update magnetic field components with the PML correction
|
# Update magnetic field components with the PML correction
|
||||||
for pml in G.pmls:
|
for pml in G.pmls:
|
||||||
@@ -638,7 +631,7 @@ def solve_gpu(currentmodelrun, modelend, G):
|
|||||||
# Update magnetic field components for magetic dipole sources
|
# Update magnetic field components for magetic dipole sources
|
||||||
if G.magneticdipoles:
|
if G.magneticdipoles:
|
||||||
update_magnetic_dipole_gpu(np.int32(len(G.magneticdipoles)), np.int32(iteration),
|
update_magnetic_dipole_gpu(np.int32(len(G.magneticdipoles)), np.int32(iteration),
|
||||||
floattype(G.dx), floattype(G.dy), floattype(G.dz),
|
config.dtypes['float_or_double'](G.dx), config.dtypes['float_or_double'](G.dy), config.dtypes['float_or_double'](G.dz),
|
||||||
srcinfo1_magnetic_gpu.gpudata, srcinfo2_magnetic_gpu.gpudata,
|
srcinfo1_magnetic_gpu.gpudata, srcinfo2_magnetic_gpu.gpudata,
|
||||||
srcwaves_magnetic_gpu.gpudata, G.ID_gpu.gpudata,
|
srcwaves_magnetic_gpu.gpudata, G.ID_gpu.gpudata,
|
||||||
G.Hx_gpu.gpudata, G.Hy_gpu.gpudata, G.Hz_gpu.gpudata,
|
G.Hx_gpu.gpudata, G.Hy_gpu.gpudata, G.Hz_gpu.gpudata,
|
||||||
@@ -646,20 +639,20 @@ def solve_gpu(currentmodelrun, modelend, G):
|
|||||||
|
|
||||||
# Update electric field components
|
# Update electric field components
|
||||||
# If all materials are non-dispersive do standard update
|
# If all materials are non-dispersive do standard update
|
||||||
if Material.maxpoles == 0:
|
if config.materials['maxpoles'] == 0:
|
||||||
update_e_gpu(np.int32(G.nx), np.int32(G.ny), np.int32(G.nz), G.ID_gpu.gpudata,
|
update_e_gpu(np.int32(G.nx), np.int32(G.ny), np.int32(G.nz), G.ID_gpu.gpudata,
|
||||||
G.Ex_gpu.gpudata, G.Ey_gpu.gpudata, G.Ez_gpu.gpudata,
|
G.Ex_gpu.gpudata, G.Ey_gpu.gpudata, G.Ez_gpu.gpudata,
|
||||||
G.Hx_gpu.gpudata, G.Hy_gpu.gpudata, G.Hz_gpu.gpudata,
|
G.Hx_gpu.gpudata, G.Hy_gpu.gpudata, G.Hz_gpu.gpudata,
|
||||||
block=config.gpus.tpb, grid=config.gpus.bpg)
|
block=config.cuda['gpus'].tpb, grid=config.cuda['gpus'].bpg)
|
||||||
# If there are any dispersive materials do 1st part of dispersive update
|
# If there are any dispersive materials do 1st part of dispersive update
|
||||||
# (it is split into two parts as it requires present and updated electric field values).
|
# (it is split into two parts as it requires present and updated electric field values).
|
||||||
else:
|
else:
|
||||||
update_e_dispersive_A_gpu(np.int32(G.nx), np.int32(G.ny), np.int32(G.nz),
|
update_e_dispersive_A_gpu(np.int32(G.nx), np.int32(G.ny), np.int32(G.nz),
|
||||||
np.int32(Material.maxpoles), G.updatecoeffsdispersive_gpu.gpudata,
|
np.int32(config.materials['maxpoles']), G.updatecoeffsdispersive_gpu.gpudata,
|
||||||
G.Tx_gpu.gpudata, G.Ty_gpu.gpudata, G.Tz_gpu.gpudata, G.ID_gpu.gpudata,
|
G.Tx_gpu.gpudata, G.Ty_gpu.gpudata, G.Tz_gpu.gpudata, G.ID_gpu.gpudata,
|
||||||
G.Ex_gpu.gpudata, G.Ey_gpu.gpudata, G.Ez_gpu.gpudata,
|
G.Ex_gpu.gpudata, G.Ey_gpu.gpudata, G.Ez_gpu.gpudata,
|
||||||
G.Hx_gpu.gpudata, G.Hy_gpu.gpudata, G.Hz_gpu.gpudata,
|
G.Hx_gpu.gpudata, G.Hy_gpu.gpudata, G.Hz_gpu.gpudata,
|
||||||
block=config.gpus.tpb, grid=config.gpus.bpg)
|
block=config.cuda['gpus'].tpb, grid=config.cuda['gpus'].bpg)
|
||||||
|
|
||||||
# Update electric field components with the PML correction
|
# Update electric field components with the PML correction
|
||||||
for pml in G.pmls:
|
for pml in G.pmls:
|
||||||
@@ -668,7 +661,7 @@ def solve_gpu(currentmodelrun, modelend, G):
|
|||||||
# Update electric field components for voltage sources
|
# Update electric field components for voltage sources
|
||||||
if G.voltagesources:
|
if G.voltagesources:
|
||||||
update_voltage_source_gpu(np.int32(len(G.voltagesources)), np.int32(iteration),
|
update_voltage_source_gpu(np.int32(len(G.voltagesources)), np.int32(iteration),
|
||||||
floattype(G.dx), floattype(G.dy), floattype(G.dz),
|
config.dtypes['float_or_double'](G.dx), config.dtypes['float_or_double'](G.dy), config.dtypes['float_or_double'](G.dz),
|
||||||
srcinfo1_voltage_gpu.gpudata, srcinfo2_voltage_gpu.gpudata,
|
srcinfo1_voltage_gpu.gpudata, srcinfo2_voltage_gpu.gpudata,
|
||||||
srcwaves_voltage_gpu.gpudata, G.ID_gpu.gpudata,
|
srcwaves_voltage_gpu.gpudata, G.ID_gpu.gpudata,
|
||||||
G.Ex_gpu.gpudata, G.Ey_gpu.gpudata, G.Ez_gpu.gpudata,
|
G.Ex_gpu.gpudata, G.Ey_gpu.gpudata, G.Ez_gpu.gpudata,
|
||||||
@@ -677,26 +670,26 @@ def solve_gpu(currentmodelrun, modelend, G):
|
|||||||
# Update electric field components for Hertzian dipole sources (update any Hertzian dipole sources last)
|
# Update electric field components for Hertzian dipole sources (update any Hertzian dipole sources last)
|
||||||
if G.hertziandipoles:
|
if G.hertziandipoles:
|
||||||
update_hertzian_dipole_gpu(np.int32(len(G.hertziandipoles)), np.int32(iteration),
|
update_hertzian_dipole_gpu(np.int32(len(G.hertziandipoles)), np.int32(iteration),
|
||||||
floattype(G.dx), floattype(G.dy), floattype(G.dz),
|
config.dtypes['float_or_double'](G.dx), config.dtypes['float_or_double'](G.dy), config.dtypes['float_or_double'](G.dz),
|
||||||
srcinfo1_hertzian_gpu.gpudata, srcinfo2_hertzian_gpu.gpudata,
|
srcinfo1_hertzian_gpu.gpudata, srcinfo2_hertzian_gpu.gpudata,
|
||||||
srcwaves_hertzian_gpu.gpudata, G.ID_gpu.gpudata,
|
srcwaves_hertzian_gpu.gpudata, G.ID_gpu.gpudata,
|
||||||
G.Ex_gpu.gpudata, G.Ey_gpu.gpudata, G.Ez_gpu.gpudata,
|
G.Ex_gpu.gpudata, G.Ey_gpu.gpudata, G.Ez_gpu.gpudata,
|
||||||
block=(1, 1, 1), grid=(round32(len(G.hertziandipoles)), 1, 1))
|
block=(1, 1, 1), grid=(round32(len(G.hertziandipoles)), 1, 1))
|
||||||
|
|
||||||
# If there are any dispersive materials do 2nd part of dispersive update (it is split into two parts as it requires present and updated electric field values). Therefore it can only be completely updated after the electric field has been updated by the PML and source updates.
|
# If there are any dispersive materials do 2nd part of dispersive update (it is split into two parts as it requires present and updated electric field values). Therefore it can only be completely updated after the electric field has been updated by the PML and source updates.
|
||||||
if Material.maxpoles > 0:
|
if config.materials['maxpoles'] > 0:
|
||||||
update_e_dispersive_B_gpu(np.int32(G.nx), np.int32(G.ny), np.int32(G.nz),
|
update_e_dispersive_B_gpu(np.int32(G.nx), np.int32(G.ny), np.int32(G.nz),
|
||||||
np.int32(Material.maxpoles), G.updatecoeffsdispersive_gpu.gpudata,
|
np.int32(config.materials['maxpoles']), G.updatecoeffsdispersive_gpu.gpudata,
|
||||||
G.Tx_gpu.gpudata, G.Ty_gpu.gpudata, G.Tz_gpu.gpudata, G.ID_gpu.gpudata,
|
G.Tx_gpu.gpudata, G.Ty_gpu.gpudata, G.Tz_gpu.gpudata, G.ID_gpu.gpudata,
|
||||||
G.Ex_gpu.gpudata, G.Ey_gpu.gpudata, G.Ez_gpu.gpudata,
|
G.Ex_gpu.gpudata, G.Ey_gpu.gpudata, G.Ez_gpu.gpudata,
|
||||||
block=config.gpus.tpb, grid=config.gpus.bpg)
|
block=config.cuda['gpus'].tpb, grid=config.cuda['gpus'].bpg)
|
||||||
|
|
||||||
# Copy output from receivers array back to correct receiver objects
|
# Copy output from receivers array back to correct receiver objects
|
||||||
if G.rxs:
|
if G.rxs:
|
||||||
gpu_get_rx_array(rxs_gpu.get(), rxcoords_gpu.get(), G)
|
gpu_get_rx_array(rxs_gpu.get(), rxcoords_gpu.get(), G)
|
||||||
|
|
||||||
# Copy data from any snapshots back to correct snapshot objects
|
# Copy data from any snapshots back to correct snapshot objects
|
||||||
if G.snapshots and not snapsgpu2cpu:
|
if G.snapshots and not config.cuda['snapsgpu2cpu']:
|
||||||
for i, snap in enumerate(G.snapshots):
|
for i, snap in enumerate(G.snapshots):
|
||||||
gpu_get_snapshot_array(snapEx_gpu.get(), snapEy_gpu.get(), snapEz_gpu.get(),
|
gpu_get_snapshot_array(snapEx_gpu.get(), snapEy_gpu.get(), snapEz_gpu.get(),
|
||||||
snapHx_gpu.get(), snapHy_gpu.get(), snapHz_gpu.get(), i, snap)
|
snapHx_gpu.get(), snapHy_gpu.get(), snapHz_gpu.get(), i, snap)
|
||||||
|
225
gprMax/pml.py
225
gprMax/pml.py
@@ -22,21 +22,18 @@ import numpy as np
|
|||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
import gprMax.config as config
|
import gprMax.config as config
|
||||||
from gprMax.config import e0
|
|
||||||
from gprMax.config import z0
|
|
||||||
from gprMax.config import floattype
|
|
||||||
from gprMax.config import hostinfo
|
|
||||||
from gprMax.exceptions import GeneralError
|
|
||||||
|
|
||||||
|
|
||||||
class CFSParameter(object):
|
class CFSParameter(object):
|
||||||
"""Individual CFS parameter (e.g. alpha, kappa, or sigma)."""
|
"""Individual CFS parameter (e.g. alpha, kappa, or sigma)."""
|
||||||
|
|
||||||
# Allowable scaling profiles and directions
|
# Allowable scaling profiles and directions
|
||||||
scalingprofiles = {'constant': 0, 'linear': 1, 'quadratic': 2, 'cubic': 3, 'quartic': 4, 'quintic': 5, 'sextic': 6, 'septic': 7, 'octic': 8}
|
scalingprofiles = {'constant': 0, 'linear': 1, 'quadratic': 2, 'cubic': 3,
|
||||||
|
'quartic': 4, 'quintic': 5, 'sextic': 6, 'septic': 7, 'octic': 8}
|
||||||
scalingdirections = ['forward', 'reverse']
|
scalingdirections = ['forward', 'reverse']
|
||||||
|
|
||||||
def __init__(self, ID=None, scaling='polynomial', scalingprofile=None, scalingdirection='forward', min=0, max=0):
|
def __init__(self, ID=None, scaling='polynomial', scalingprofile=None,
|
||||||
|
scalingdirection='forward', min=0, max=0):
|
||||||
"""
|
"""
|
||||||
Args:
|
Args:
|
||||||
ID (str): Identifier for CFS parameter, can be: 'alpha', 'kappa' or 'sigma'.
|
ID (str): Identifier for CFS parameter, can be: 'alpha', 'kappa' or 'sigma'.
|
||||||
@@ -71,60 +68,73 @@ class CFS(object):
|
|||||||
self.sigma = CFSParameter(ID='sigma', scalingprofile='quartic', min=0, max=None)
|
self.sigma = CFSParameter(ID='sigma', scalingprofile='quartic', min=0, max=None)
|
||||||
|
|
||||||
def calculate_sigmamax(self, d, er, mr, G):
|
def calculate_sigmamax(self, d, er, mr, G):
|
||||||
"""Calculates an optimum value for sigma max based on underlying material properties.
|
"""Calculates an optimum value for sigma max based on underlying
|
||||||
|
material properties.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
d (float): dx, dy, or dz in direction of PML.
|
d (float): dx, dy, or dz in direction of PML.
|
||||||
er (float): Average permittivity of underlying material.
|
er (float): Average permittivity of underlying material.
|
||||||
mr (float): Average permeability of underlying material.
|
mr (float): Average permeability of underlying material.
|
||||||
G (class): Grid class instance - holds essential parameters describing the model.
|
G (class): Grid class instance - holds essential parameters
|
||||||
|
describing the model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Calculation of the maximum value of sigma from http://dx.doi.org/10.1109/8.546249
|
# Calculation of the maximum value of sigma from http://dx.doi.org/10.1109/8.546249
|
||||||
m = CFSParameter.scalingprofiles[self.sigma.scalingprofile]
|
m = CFSParameter.scalingprofiles[self.sigma.scalingprofile]
|
||||||
self.sigma.max = (0.8 * (m + 1)) / (z0 * d * np.sqrt(er * mr))
|
self.sigma.max = (0.8 * (m + 1)) / (config.z0 * d * np.sqrt(er * mr))
|
||||||
|
|
||||||
def scaling_polynomial(self, order, Evalues, Hvalues):
|
def scaling_polynomial(self, order, Evalues, Hvalues):
|
||||||
"""Applies the polynomial to be used for the scaling profile for electric and magnetic PML updates.
|
"""Applies the polynomial to be used for the scaling profile for
|
||||||
|
electric and magnetic PML updates.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
order (int): Order of polynomial for scaling profile.
|
order (int): Order of polynomial for scaling profile.
|
||||||
Evalues (float): numpy array holding scaling profile values for electric PML update.
|
Evalues (float): numpy array holding scaling profile values for
|
||||||
Hvalues (float): numpy array holding scaling profile values for magnetic PML update.
|
electric PML update.
|
||||||
|
Hvalues (float): numpy array holding scaling profile values for
|
||||||
|
magnetic PML update.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Evalues (float): numpy array holding scaling profile values for electric PML update.
|
Evalues (float): numpy array holding scaling profile values for
|
||||||
Hvalues (float): numpy array holding scaling profile values for magnetic PML update.
|
electric PML update.
|
||||||
|
Hvalues (float): numpy array holding scaling profile values for
|
||||||
|
magnetic PML update.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
tmp = (np.linspace(0, (len(Evalues) - 1) + 0.5, num=2 * len(Evalues)) / (len(Evalues) - 1)) ** order
|
tmp = (np.linspace(0, (len(Evalues) - 1) + 0.5, num=2 * len(Evalues))
|
||||||
|
/ (len(Evalues) - 1)) ** order
|
||||||
Evalues = tmp[0:-1:2]
|
Evalues = tmp[0:-1:2]
|
||||||
Hvalues = tmp[1::2]
|
Hvalues = tmp[1::2]
|
||||||
|
|
||||||
return Evalues, Hvalues
|
return Evalues, Hvalues
|
||||||
|
|
||||||
def calculate_values(self, thickness, parameter):
|
def calculate_values(self, thickness, parameter):
|
||||||
"""Calculates values for electric and magnetic PML updates based on profile type and minimum and maximum values.
|
"""Calculates values for electric and magnetic PML updates based on
|
||||||
|
profile type and minimum and maximum values.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
thickness (int): Thickness of PML in cells.
|
thickness (int): Thickness of PML in cells.
|
||||||
parameter (CFSParameter): Instance of CFSParameter
|
parameter (CFSParameter): Instance of CFSParameter
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Evalues (float): numpy array holding profile value for electric PML update.
|
Evalues (float): numpy array holding profile value for electric
|
||||||
Hvalues (float): numpy array holding profile value for magnetic PML update.
|
PML update.
|
||||||
|
Hvalues (float): numpy array holding profile value for magnetic
|
||||||
|
PML update.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Extra cell of thickness added to allow correct scaling of electric and magnetic values
|
# Extra cell of thickness added to allow correct scaling of electric and magnetic values
|
||||||
Evalues = np.zeros(thickness + 1, dtype=floattype)
|
Evalues = np.zeros(thickness + 1, dtype=config.dtypes['float_or_double'])
|
||||||
Hvalues = np.zeros(thickness + 1, dtype=floattype)
|
Hvalues = np.zeros(thickness + 1, dtype=config.dtypes['float_or_double'])
|
||||||
|
|
||||||
if parameter.scalingprofile == 'constant':
|
if parameter.scalingprofile == 'constant':
|
||||||
Evalues += parameter.max
|
Evalues += parameter.max
|
||||||
Hvalues += parameter.max
|
Hvalues += parameter.max
|
||||||
|
|
||||||
elif parameter.scaling == 'polynomial':
|
elif parameter.scaling == 'polynomial':
|
||||||
Evalues, Hvalues = self.scaling_polynomial(CFSParameter.scalingprofiles[parameter.scalingprofile], Evalues, Hvalues)
|
Evalues, Hvalues = self.scaling_polynomial(
|
||||||
|
CFSParameter.scalingprofiles[parameter.scalingprofile],
|
||||||
|
Evalues, Hvalues)
|
||||||
if parameter.ID == 'alpha':
|
if parameter.ID == 'alpha':
|
||||||
Evalues = Evalues * (self.alpha.max - self.alpha.min) + self.alpha.min
|
Evalues = Evalues * (self.alpha.max - self.alpha.min) + self.alpha.min
|
||||||
Hvalues = Hvalues * (self.alpha.max - self.alpha.min) + self.alpha.min
|
Hvalues = Hvalues * (self.alpha.max - self.alpha.min) + self.alpha.min
|
||||||
@@ -167,7 +177,8 @@ class PML(object):
|
|||||||
def __init__(self, G, ID=None, direction=None, xs=0, xf=0, ys=0, yf=0, zs=0, zf=0):
|
def __init__(self, G, ID=None, direction=None, xs=0, xf=0, ys=0, yf=0, zs=0, zf=0):
|
||||||
"""
|
"""
|
||||||
Args:
|
Args:
|
||||||
G (class): Grid class instance - holds essential parameters describing the model.
|
G (class): Grid class instance - holds essential parameters
|
||||||
|
describing the model.
|
||||||
ID (str): Identifier for PML slab.
|
ID (str): Identifier for PML slab.
|
||||||
direction (str): Direction of increasing absorption.
|
direction (str): Direction of increasing absorption.
|
||||||
xs, xf, ys, yf, zs, zf (float): Extent of the PML slab.
|
xs, xf, ys, yf, zs, zf (float): Extent of the PML slab.
|
||||||
@@ -204,20 +215,32 @@ class PML(object):
|
|||||||
"""Initialise arrays to store fields in PML."""
|
"""Initialise arrays to store fields in PML."""
|
||||||
|
|
||||||
if self.direction[0] == 'x':
|
if self.direction[0] == 'x':
|
||||||
self.EPhi1 = np.zeros((len(self.CFS), self.nx + 1, self.ny, self.nz + 1), dtype=floattype)
|
self.EPhi1 = np.zeros((len(self.CFS), self.nx + 1, self.ny, self.nz + 1),
|
||||||
self.EPhi2 = np.zeros((len(self.CFS), self.nx + 1, self.ny + 1, self.nz), dtype=floattype)
|
dtype=config.dtypes['float_or_double'])
|
||||||
self.HPhi1 = np.zeros((len(self.CFS), self.nx, self.ny + 1, self.nz), dtype=floattype)
|
self.EPhi2 = np.zeros((len(self.CFS), self.nx + 1, self.ny + 1, self.nz),
|
||||||
self.HPhi2 = np.zeros((len(self.CFS), self.nx, self.ny, self.nz + 1), dtype=floattype)
|
dtype=config.dtypes['float_or_double'])
|
||||||
|
self.HPhi1 = np.zeros((len(self.CFS), self.nx, self.ny + 1, self.nz),
|
||||||
|
dtype=config.dtypes['float_or_double'])
|
||||||
|
self.HPhi2 = np.zeros((len(self.CFS), self.nx, self.ny, self.nz + 1),
|
||||||
|
dtype=config.dtypes['float_or_double'])
|
||||||
elif self.direction[0] == 'y':
|
elif self.direction[0] == 'y':
|
||||||
self.EPhi1 = np.zeros((len(self.CFS), self.nx, self.ny + 1, self.nz + 1), dtype=floattype)
|
self.EPhi1 = np.zeros((len(self.CFS), self.nx, self.ny + 1, self.nz + 1),
|
||||||
self.EPhi2 = np.zeros((len(self.CFS), self.nx + 1, self.ny + 1, self.nz), dtype=floattype)
|
dtype=config.dtypes['float_or_double'])
|
||||||
self.HPhi1 = np.zeros((len(self.CFS), self.nx + 1, self.ny, self.nz), dtype=floattype)
|
self.EPhi2 = np.zeros((len(self.CFS), self.nx + 1, self.ny + 1, self.nz),
|
||||||
self.HPhi2 = np.zeros((len(self.CFS), self.nx, self.ny, self.nz + 1), dtype=floattype)
|
dtype=config.dtypes['float_or_double'])
|
||||||
|
self.HPhi1 = np.zeros((len(self.CFS), self.nx + 1, self.ny, self.nz),
|
||||||
|
dtype=config.dtypes['float_or_double'])
|
||||||
|
self.HPhi2 = np.zeros((len(self.CFS), self.nx, self.ny, self.nz + 1),
|
||||||
|
dtype=config.dtypes['float_or_double'])
|
||||||
elif self.direction[0] == 'z':
|
elif self.direction[0] == 'z':
|
||||||
self.EPhi1 = np.zeros((len(self.CFS), self.nx, self.ny + 1, self.nz + 1), dtype=floattype)
|
self.EPhi1 = np.zeros((len(self.CFS), self.nx, self.ny + 1, self.nz + 1),
|
||||||
self.EPhi2 = np.zeros((len(self.CFS), self.nx + 1, self.ny, self.nz + 1), dtype=floattype)
|
dtype=config.dtypes['float_or_double'])
|
||||||
self.HPhi1 = np.zeros((len(self.CFS), self.nx + 1, self.ny, self.nz), dtype=floattype)
|
self.EPhi2 = np.zeros((len(self.CFS), self.nx + 1, self.ny, self.nz + 1),
|
||||||
self.HPhi2 = np.zeros((len(self.CFS), self.nx, self.ny + 1, self.nz), dtype=floattype)
|
dtype=config.dtypes['float_or_double'])
|
||||||
|
self.HPhi1 = np.zeros((len(self.CFS), self.nx + 1, self.ny, self.nz),
|
||||||
|
dtype=config.dtypes['float_or_double'])
|
||||||
|
self.HPhi2 = np.zeros((len(self.CFS), self.nx, self.ny + 1, self.nz),
|
||||||
|
dtype=config.dtypes['float_or_double'])
|
||||||
|
|
||||||
def calculate_update_coeffs(self, er, mr, G):
|
def calculate_update_coeffs(self, er, mr, G):
|
||||||
"""Calculates electric and magnetic update coefficients for the PML.
|
"""Calculates electric and magnetic update coefficients for the PML.
|
||||||
@@ -225,17 +248,26 @@ class PML(object):
|
|||||||
Args:
|
Args:
|
||||||
er (float): Average permittivity of underlying material
|
er (float): Average permittivity of underlying material
|
||||||
mr (float): Average permeability of underlying material
|
mr (float): Average permeability of underlying material
|
||||||
G (class): Grid class instance - holds essential parameters describing the model.
|
G (class): Grid class instance - holds essential parameters
|
||||||
|
describing the model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.ERA = np.zeros((len(self.CFS), self.thickness), dtype=floattype)
|
self.ERA = np.zeros((len(self.CFS), self.thickness),
|
||||||
self.ERB = np.zeros((len(self.CFS), self.thickness), dtype=floattype)
|
dtype=config.dtypes['float_or_double'])
|
||||||
self.ERE = np.zeros((len(self.CFS), self.thickness), dtype=floattype)
|
self.ERB = np.zeros((len(self.CFS), self.thickness),
|
||||||
self.ERF = np.zeros((len(self.CFS), self.thickness), dtype=floattype)
|
dtype=config.dtypes['float_or_double'])
|
||||||
self.HRA = np.zeros((len(self.CFS), self.thickness), dtype=floattype)
|
self.ERE = np.zeros((len(self.CFS), self.thickness),
|
||||||
self.HRB = np.zeros((len(self.CFS), self.thickness), dtype=floattype)
|
dtype=config.dtypes['float_or_double'])
|
||||||
self.HRE = np.zeros((len(self.CFS), self.thickness), dtype=floattype)
|
self.ERF = np.zeros((len(self.CFS), self.thickness),
|
||||||
self.HRF = np.zeros((len(self.CFS), self.thickness), dtype=floattype)
|
dtype=config.dtypes['float_or_double'])
|
||||||
|
self.HRA = np.zeros((len(self.CFS), self.thickness),
|
||||||
|
dtype=config.dtypes['float_or_double'])
|
||||||
|
self.HRB = np.zeros((len(self.CFS), self.thickness),
|
||||||
|
dtype=config.dtypes['float_or_double'])
|
||||||
|
self.HRE = np.zeros((len(self.CFS), self.thickness),
|
||||||
|
dtype=config.dtypes['float_or_double'])
|
||||||
|
self.HRF = np.zeros((len(self.CFS), self.thickness),
|
||||||
|
dtype=config.dtypes['float_or_double'])
|
||||||
|
|
||||||
for x, cfs in enumerate(self.CFS):
|
for x, cfs in enumerate(self.CFS):
|
||||||
if not cfs.sigma.max:
|
if not cfs.sigma.max:
|
||||||
@@ -247,31 +279,33 @@ class PML(object):
|
|||||||
# Define different parameters depending on PML formulation
|
# Define different parameters depending on PML formulation
|
||||||
if G.pmlformulation == 'HORIPML':
|
if G.pmlformulation == 'HORIPML':
|
||||||
# HORIPML electric update coefficients
|
# HORIPML electric update coefficients
|
||||||
tmp = (2 * e0 * Ekappa) + G.dt * (Ealpha * Ekappa + Esigma)
|
tmp = (2 * config.e0 * Ekappa) + G.dt * (Ealpha * Ekappa + Esigma)
|
||||||
self.ERA[x, :] = (2 * e0 + G.dt * Ealpha) / tmp
|
self.ERA[x, :] = (2 * config.e0 + G.dt * Ealpha) / tmp
|
||||||
self.ERB[x, :] = (2 * e0 * Ekappa) / tmp
|
self.ERB[x, :] = (2 * config.e0 * Ekappa) / tmp
|
||||||
self.ERE[x, :] = ((2 * e0 * Ekappa) - G.dt * (Ealpha * Ekappa + Esigma)) / tmp
|
self.ERE[x, :] = ((2 * config.e0 * Ekappa) - G.dt
|
||||||
|
* (Ealpha * Ekappa + Esigma)) / tmp
|
||||||
self.ERF[x, :] = (2 * Esigma * G.dt) / (Ekappa * tmp)
|
self.ERF[x, :] = (2 * Esigma * G.dt) / (Ekappa * tmp)
|
||||||
|
|
||||||
# HORIPML magnetic update coefficients
|
# HORIPML magnetic update coefficients
|
||||||
tmp = (2 * e0 * Hkappa) + G.dt * (Halpha * Hkappa + Hsigma)
|
tmp = (2 * config.e0 * Hkappa) + G.dt * (Halpha * Hkappa + Hsigma)
|
||||||
self.HRA[x, :] = (2 * e0 + G.dt * Halpha) / tmp
|
self.HRA[x, :] = (2 * config.e0 + G.dt * Halpha) / tmp
|
||||||
self.HRB[x, :] = (2 * e0 * Hkappa) / tmp
|
self.HRB[x, :] = (2 * config.e0 * Hkappa) / tmp
|
||||||
self.HRE[x, :] = ((2 * e0 * Hkappa) - G.dt * (Halpha * Hkappa + Hsigma)) / tmp
|
self.HRE[x, :] = ((2 * config.e0 * Hkappa) - G.dt
|
||||||
|
* (Halpha * Hkappa + Hsigma)) / tmp
|
||||||
self.HRF[x, :] = (2 * Hsigma * G.dt) / (Hkappa * tmp)
|
self.HRF[x, :] = (2 * Hsigma * G.dt) / (Hkappa * tmp)
|
||||||
|
|
||||||
elif G.pmlformulation == 'MRIPML':
|
elif G.pmlformulation == 'MRIPML':
|
||||||
tmp = 2 * e0 + G.dt * Ealpha
|
tmp = 2 * config.e0 + G.dt * Ealpha
|
||||||
self.ERA[x, :] = Ekappa + (G.dt * Esigma) / tmp
|
self.ERA[x, :] = Ekappa + (G.dt * Esigma) / tmp
|
||||||
self.ERB[x, :] = (2 * e0) / tmp
|
self.ERB[x, :] = (2 * config.e0) / tmp
|
||||||
self.ERE[x, :] = ((2 * e0) - G.dt * Ealpha) / tmp
|
self.ERE[x, :] = ((2 * config.e0) - G.dt * Ealpha) / tmp
|
||||||
self.ERF[x, :] = (2 * Esigma * G.dt) / tmp
|
self.ERF[x, :] = (2 * Esigma * G.dt) / tmp
|
||||||
|
|
||||||
# MRIPML magnetic update coefficients
|
# MRIPML magnetic update coefficients
|
||||||
tmp = 2 * e0 + G.dt * Halpha
|
tmp = 2 * config.e0 + G.dt * Halpha
|
||||||
self.HRA[x, :] = Hkappa + (G.dt * Hsigma) / tmp
|
self.HRA[x, :] = Hkappa + (G.dt * Hsigma) / tmp
|
||||||
self.HRB[x, :] = (2 * e0) / tmp
|
self.HRB[x, :] = (2 * config.e0) / tmp
|
||||||
self.HRE[x, :] = ((2 * e0) - G.dt * Halpha) / tmp
|
self.HRE[x, :] = ((2 * config.e0) - G.dt * Halpha) / tmp
|
||||||
self.HRF[x, :] = (2 * Hsigma * G.dt) / tmp
|
self.HRF[x, :] = (2 * Hsigma * G.dt) / tmp
|
||||||
|
|
||||||
def update_electric(self, G):
|
def update_electric(self, G):
|
||||||
@@ -283,7 +317,10 @@ class PML(object):
|
|||||||
|
|
||||||
pmlmodule = 'gprMax.cython.pml_updates_electric_' + G.pmlformulation
|
pmlmodule = 'gprMax.cython.pml_updates_electric_' + G.pmlformulation
|
||||||
func = getattr(import_module(pmlmodule), 'order' + str(len(self.CFS)) + '_' + self.direction)
|
func = getattr(import_module(pmlmodule), 'order' + str(len(self.CFS)) + '_' + self.direction)
|
||||||
func(self.xs, self.xf, self.ys, self.yf, self.zs, self.zf, hostinfo['ompthreads'], G.updatecoeffsE, G.ID, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz, self.EPhi1, self.EPhi2, self.ERA, self.ERB, self.ERE, self.ERF, self.d)
|
func(self.xs, self.xf, self.ys, self.yf, self.zs, self.zf,
|
||||||
|
config.hostinfo['ompthreads'], G.updatecoeffsE, G.ID,
|
||||||
|
G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz, self.EPhi1, self.EPhi2,
|
||||||
|
self.ERA, self.ERB, self.ERE, self.ERF, self.d)
|
||||||
|
|
||||||
def update_magnetic(self, G):
|
def update_magnetic(self, G):
|
||||||
"""This functions updates magnetic field components with the PML correction.
|
"""This functions updates magnetic field components with the PML correction.
|
||||||
@@ -294,7 +331,10 @@ class PML(object):
|
|||||||
|
|
||||||
pmlmodule = 'gprMax.cython.pml_updates_magnetic_' + G.pmlformulation
|
pmlmodule = 'gprMax.cython.pml_updates_magnetic_' + G.pmlformulation
|
||||||
func = getattr(import_module(pmlmodule), 'order' + str(len(self.CFS)) + '_' + self.direction)
|
func = getattr(import_module(pmlmodule), 'order' + str(len(self.CFS)) + '_' + self.direction)
|
||||||
func(self.xs, self.xf, self.ys, self.yf, self.zs, self.zf, hostinfo['ompthreads'], G.updatecoeffsH, G.ID, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz, self.HPhi1, self.HPhi2, self.HRA, self.HRB, self.HRE, self.HRF, self.d)
|
func(self.xs, self.xf, self.ys, self.yf, self.zs, self.zf,
|
||||||
|
config.hostinfo['ompthreads'], G.updatecoeffsH, G.ID,
|
||||||
|
G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz, self.HPhi1, self.HPhi2,
|
||||||
|
self.HRA, self.HRB, self.HRE, self.HRF, self.d)
|
||||||
|
|
||||||
def gpu_set_blocks_per_grid(self, G):
|
def gpu_set_blocks_per_grid(self, G):
|
||||||
"""Set the blocks per grid size used for updating the PML field arrays on a GPU.
|
"""Set the blocks per grid size used for updating the PML field arrays on a GPU.
|
||||||
@@ -303,7 +343,10 @@ class PML(object):
|
|||||||
G (class): Grid class instance - holds essential parameters describing the model.
|
G (class): Grid class instance - holds essential parameters describing the model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
config.gpus.bpg = (int(np.ceil(((self.EPhi1.shape[1] + 1) * (self.EPhi1.shape[2] + 1) * (self.EPhi1.shape[3] + 1)) / config.gpus.tpb[0])), 1, 1)
|
config.cuda['gpus'].bpg = (int(np.ceil(((self.EPhi1.shape[1] + 1)
|
||||||
|
* (self.EPhi1.shape[2] + 1)
|
||||||
|
* (self.EPhi1.shape[3] + 1))
|
||||||
|
/ config.cuda['gpus'].tpb[0])), 1, 1)
|
||||||
|
|
||||||
def gpu_initialise_arrays(self):
|
def gpu_initialise_arrays(self):
|
||||||
"""Initialise PML field and coefficient arrays on GPU."""
|
"""Initialise PML field and coefficient arrays on GPU."""
|
||||||
@@ -327,42 +370,76 @@ class PML(object):
|
|||||||
"""Get update functions from PML kernels.
|
"""Get update functions from PML kernels.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
kernelselectric: PyCuda SourceModule containing PML kernels for electric updates.
|
kernelselectric: PyCuda SourceModule containing PML kernels for
|
||||||
kernelsmagnetic: PyCuda SourceModule containing PML kernels for magnetic updates.
|
electric updates.
|
||||||
|
kernelsmagnetic: PyCuda SourceModule containing PML kernels for
|
||||||
|
magnetic updates.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from pycuda.compiler import SourceModule
|
from pycuda.compiler import SourceModule
|
||||||
|
|
||||||
self.update_electric_gpu = kernelselectric.get_function('order' + str(len(self.CFS)) + '_' + self.direction)
|
self.update_electric = kernelselectric.get_function('order' + str(len(self.CFS))
|
||||||
self.update_magnetic_gpu = kernelsmagnetic.get_function('order' + str(len(self.CFS)) + '_' + self.direction)
|
+ '_' + self.direction)
|
||||||
|
self.update_magnetic = kernelsmagnetic.get_function('order' + str(len(self.CFS))
|
||||||
|
+ '_' + self.direction)
|
||||||
|
|
||||||
def gpu_update_electric(self, G):
|
def gpu_update_electric(self, G):
|
||||||
"""This functions updates electric field components with the PML correction on the GPU.
|
"""This functions updates electric field components with the PML
|
||||||
|
correction on the GPU.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
G (class): Grid class instance - holds essential parameters describing the model.
|
G (class): Grid class instance - holds essential parameters
|
||||||
|
describing the model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.update_electric_gpu(np.int32(self.xs), np.int32(self.xf), np.int32(self.ys), np.int32(self.yf), np.int32(self.zs), np.int32(self.zf), np.int32(self.EPhi1.shape[1]), np.int32(self.EPhi1.shape[2]), np.int32(self.EPhi1.shape[3]), np.int32(self.EPhi2.shape[1]), np.int32(self.EPhi2.shape[2]), np.int32(self.EPhi2.shape[3]), np.int32(self.thickness), G.ID_gpu.gpudata, G.Ex_gpu.gpudata, G.Ey_gpu.gpudata, G.Ez_gpu.gpudata, G.Hx_gpu.gpudata, G.Hy_gpu.gpudata, G.Hz_gpu.gpudata, self.EPhi1_gpu.gpudata, self.EPhi2_gpu.gpudata, self.ERA_gpu.gpudata, self.ERB_gpu.gpudata, self.ERE_gpu.gpudata, self.ERF_gpu.gpudata, floattype(self.d), block=config.gpus.tpb, grid=config.gpus.bpg)
|
self.update_electric(np.int32(self.xs), np.int32(self.xf),
|
||||||
|
np.int32(self.ys), np.int32(self.yf),
|
||||||
|
np.int32(self.zs), np.int32(self.zf),
|
||||||
|
np.int32(self.EPhi1.shape[1]), np.int32(self.EPhi1.shape[2]),
|
||||||
|
np.int32(self.EPhi1.shape[3]), np.int32(self.EPhi2.shape[1]),
|
||||||
|
np.int32(self.EPhi2.shape[2]), np.int32(self.EPhi2.shape[3]),
|
||||||
|
np.int32(self.thickness), G.ID_gpu.gpudata,
|
||||||
|
G.Ex_gpu.gpudata, G.Ey_gpu.gpudata, G.Ez_gpu.gpudata,
|
||||||
|
G.Hx_gpu.gpudata, G.Hy_gpu.gpudata, G.Hz_gpu.gpudata,
|
||||||
|
self.EPhi1_gpu.gpudata, self.EPhi2_gpu.gpudata,
|
||||||
|
self.ERA_gpu.gpudata, self.ERB_gpu.gpudata,
|
||||||
|
self.ERE_gpu.gpudata, self.ERF_gpu.gpudata,
|
||||||
|
config.dtypes['float_or_double'](self.d),
|
||||||
|
block=config.cuda['gpus'].tpb, grid=config.cuda['gpus'].bpg)
|
||||||
|
|
||||||
def gpu_update_magnetic(self, G):
|
def gpu_update_magnetic(self, G):
|
||||||
"""This functions updates magnetic field components with the PML correction on the GPU.
|
"""This functions updates magnetic field components with the PML
|
||||||
|
correction on the GPU.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
G (class): Grid class instance - holds essential parameters describing the model.
|
G (class): Grid class instance - holds essential parameters
|
||||||
|
describing the model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.update_magnetic_gpu(np.int32(self.xs), np.int32(self.xf), np.int32(self.ys), np.int32(self.yf), np.int32(self.zs), np.int32(self.zf), np.int32(self.HPhi1.shape[1]), np.int32(self.HPhi1.shape[2]), np.int32(self.HPhi1.shape[3]), np.int32(self.HPhi2.shape[1]), np.int32(self.HPhi2.shape[2]), np.int32(self.HPhi2.shape[3]), np.int32(self.thickness), G.ID_gpu.gpudata, G.Ex_gpu.gpudata, G.Ey_gpu.gpudata, G.Ez_gpu.gpudata, G.Hx_gpu.gpudata, G.Hy_gpu.gpudata, G.Hz_gpu.gpudata, self.HPhi1_gpu.gpudata, self.HPhi2_gpu.gpudata, self.HRA_gpu.gpudata, self.HRB_gpu.gpudata, self.HRE_gpu.gpudata, self.HRF_gpu.gpudata, floattype(self.d), block=config.gpus.tpb, grid=config.gpus.bpg)
|
self.update_magnetic(np.int32(self.xs), np.int32(self.xf),
|
||||||
|
np.int32(self.ys), np.int32(self.yf),
|
||||||
|
np.int32(self.zs), np.int32(self.zf),
|
||||||
|
np.int32(self.HPhi1.shape[1]), np.int32(self.HPhi1.shape[2]),
|
||||||
|
np.int32(self.HPhi1.shape[3]), np.int32(self.HPhi2.shape[1]),
|
||||||
|
np.int32(self.HPhi2.shape[2]), np.int32(self.HPhi2.shape[3]),
|
||||||
|
np.int32(self.thickness), G.ID_gpu.gpudata,
|
||||||
|
G.Ex_gpu.gpudata, G.Ey_gpu.gpudata, G.Ez_gpu.gpudata,
|
||||||
|
G.Hx_gpu.gpudata, G.Hy_gpu.gpudata, G.Hz_gpu.gpudata,
|
||||||
|
self.HPhi1_gpu.gpudata, self.HPhi2_gpu.gpudata,
|
||||||
|
self.HRA_gpu.gpudata, self.HRB_gpu.gpudata,
|
||||||
|
self.HRE_gpu.gpudata, self.HRF_gpu.gpudata,
|
||||||
|
config.dtypes['float_or_double'](self.d),
|
||||||
|
block=config.cuda['gpus'].tpb, grid=config.cuda['gpus'].bpg)
|
||||||
|
|
||||||
|
|
||||||
def build_pmls(G, pbar):
|
def build_pmls(G, pbar):
|
||||||
"""
|
"""This function builds instances of the PML and calculates the initial
|
||||||
This function builds instances of the PML and calculates the initial
|
|
||||||
parameters and coefficients including setting profile
|
parameters and coefficients including setting profile
|
||||||
(based on underlying material er and mr from solid array).
|
(based on underlying material er and mr from solid array).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
G (class): Grid class instance - holds essential parameters describing the model.
|
G (class): Grid class instance - holds essential parameters
|
||||||
|
describing the model.
|
||||||
pbar (class): Progress bar class instance.
|
pbar (class): Progress bar class instance.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@@ -20,7 +20,7 @@ from collections import OrderedDict
|
|||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from gprMax.config import floattype
|
import gprMax.config as config
|
||||||
|
|
||||||
|
|
||||||
class Rx(object):
|
class Rx(object):
|
||||||
@@ -29,6 +29,7 @@ class Rx(object):
|
|||||||
allowableoutputs = ['Ex', 'Ey', 'Ez', 'Hx', 'Hy', 'Hz', 'Ix', 'Iy', 'Iz']
|
allowableoutputs = ['Ex', 'Ey', 'Ez', 'Hx', 'Hy', 'Hz', 'Ix', 'Iy', 'Iz']
|
||||||
gpu_allowableoutputs = allowableoutputs[:-3]
|
gpu_allowableoutputs = allowableoutputs[:-3]
|
||||||
defaultoutputs = allowableoutputs[:-3]
|
defaultoutputs = allowableoutputs[:-3]
|
||||||
|
maxnumoutputs = 0
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
||||||
@@ -43,10 +44,12 @@ class Rx(object):
|
|||||||
|
|
||||||
|
|
||||||
def gpu_initialise_rx_arrays(G):
|
def gpu_initialise_rx_arrays(G):
|
||||||
"""Initialise arrays on GPU for receiver coordinates and to store field components for receivers.
|
"""Initialise arrays on GPU for receiver coordinates and to store field
|
||||||
|
components for receivers.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
G (class): Grid class instance - holds essential parameters describing the model.
|
G (class): Grid class instance - holds essential parameters
|
||||||
|
describing the model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import pycuda.gpuarray as gpuarray
|
import pycuda.gpuarray as gpuarray
|
||||||
@@ -58,8 +61,10 @@ def gpu_initialise_rx_arrays(G):
|
|||||||
rxcoords[i, 1] = rx.ycoord
|
rxcoords[i, 1] = rx.ycoord
|
||||||
rxcoords[i, 2] = rx.zcoord
|
rxcoords[i, 2] = rx.zcoord
|
||||||
|
|
||||||
# Array to store field components for receivers on GPU - rows are field components; columns are iterations; pages are receivers
|
# Array to store field components for receivers on GPU - rows are field components;
|
||||||
rxs = np.zeros((len(Rx.gpu_allowableoutputs), G.iterations, len(G.rxs)), dtype=floattype)
|
# columns are iterations; pages are receivers
|
||||||
|
rxs = np.zeros((Rx.maxnumoutputs, G.iterations, len(G.rxs)),
|
||||||
|
dtype=config.dtypes['float_or_double'])
|
||||||
|
|
||||||
# Copy arrays to GPU
|
# Copy arrays to GPU
|
||||||
rxcoords_gpu = gpuarray.to_gpu(rxcoords)
|
rxcoords_gpu = gpuarray.to_gpu(rxcoords)
|
||||||
@@ -72,17 +77,17 @@ def gpu_get_rx_array(rxs_gpu, rxcoords_gpu, G):
|
|||||||
"""Copy output from receivers array used on GPU back to receiver objects.
|
"""Copy output from receivers array used on GPU back to receiver objects.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
rxs_gpu (float): numpy array of receiver data from GPU - rows are field components; columns are iterations; pages are receivers.
|
rxs_gpu (float): numpy array of receiver data from GPU - rows are field
|
||||||
|
components; columns are iterations; pages are receivers.
|
||||||
rxcoords_gpu (float): numpy array of receiver coordinates from GPU.
|
rxcoords_gpu (float): numpy array of receiver coordinates from GPU.
|
||||||
G (class): Grid class instance - holds essential parameters describing the model.
|
G (class): Grid class instance - holds essential parameters
|
||||||
|
describing the model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for rx in G.rxs:
|
for rx in G.rxs:
|
||||||
for rxgpu in range(len(G.rxs)):
|
for rxgpu in range(len(G.rxs)):
|
||||||
if rx.xcoord == rxcoords_gpu[rxgpu, 0] and rx.ycoord == rxcoords_gpu[rxgpu, 1] and rx.zcoord == rxcoords_gpu[rxgpu, 2]:
|
if rx.xcoord == rxcoords_gpu[rxgpu, 0] and \
|
||||||
rx.outputs['Ex'] = rxs_gpu[0, :, rxgpu]
|
rx.ycoord == rxcoords_gpu[rxgpu, 1] and \
|
||||||
rx.outputs['Ey'] = rxs_gpu[1, :, rxgpu]
|
rx.zcoord == rxcoords_gpu[rxgpu, 2]:
|
||||||
rx.outputs['Ez'] = rxs_gpu[2, :, rxgpu]
|
for k, v in rx.outputs.items():
|
||||||
rx.outputs['Hx'] = rxs_gpu[3, :, rxgpu]
|
v = rxs_gpu[Rx.gpu_allowableoutputs.index(k), :, rxgpu]
|
||||||
rx.outputs['Hy'] = rxs_gpu[4, :, rxgpu]
|
|
||||||
rx.outputs['Hz'] = rxs_gpu[5, :, rxgpu]
|
|
||||||
|
@@ -22,10 +22,9 @@ from struct import pack
|
|||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from gprMax.config import floattype
|
import gprMax.config as config
|
||||||
from gprMax.config import snapsgpu2cpu
|
from .cython.snapshots import calculate_snapshot_fields
|
||||||
from gprMax.cython.snapshots import calculate_snapshot_fields
|
from .utilities import round_value
|
||||||
from gprMax.utilities import round_value
|
|
||||||
|
|
||||||
|
|
||||||
class Snapshot(object):
|
class Snapshot(object):
|
||||||
@@ -48,14 +47,15 @@ class Snapshot(object):
|
|||||||
byteorder = 'BigEndian'
|
byteorder = 'BigEndian'
|
||||||
|
|
||||||
# Set format text and string depending on float type
|
# Set format text and string depending on float type
|
||||||
if np.dtype(floattype).name == 'float32':
|
if config.dtypes['float_or_double'] == np.float32:
|
||||||
floatname = 'Float32'
|
floatname = 'Float32'
|
||||||
floatstring = 'f'
|
floatstring = 'f'
|
||||||
elif np.dtype(floattype).name == 'float64':
|
elif config.dtypes['float_or_double'] == np.float64:
|
||||||
floatname = 'Float64'
|
floatname = 'Float64'
|
||||||
floatstring = 'd'
|
floatstring = 'd'
|
||||||
|
|
||||||
def __init__(self, xs=None, ys=None, zs=None, xf=None, yf=None, zf=None, dx=None, dy=None, dz=None, time=None, filename=None):
|
def __init__(self, xs=None, ys=None, zs=None, xf=None, yf=None, zf=None,
|
||||||
|
dx=None, dy=None, dz=None, time=None, filename=None):
|
||||||
"""
|
"""
|
||||||
Args:
|
Args:
|
||||||
xs, xf, ys, yf, zs, zf (int): Extent of the volume in cells.
|
xs, xf, ys, yf, zs, zf (int): Extent of the volume in cells.
|
||||||
@@ -64,6 +64,7 @@ class Snapshot(object):
|
|||||||
filename (str): Filename to save to.
|
filename (str): Filename to save to.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
self.fieldoutputs = {'electric': True, 'magnetic': True}
|
||||||
self.xs = xs
|
self.xs = xs
|
||||||
self.ys = ys
|
self.ys = ys
|
||||||
self.zs = zs
|
self.zs = zs
|
||||||
@@ -80,8 +81,13 @@ class Snapshot(object):
|
|||||||
self.sy = slice(self.ys, self.yf + self.dy, self.dy)
|
self.sy = slice(self.ys, self.yf + self.dy, self.dy)
|
||||||
self.sz = slice(self.zs, self.zf + self.dz, self.dz)
|
self.sz = slice(self.zs, self.zf + self.dz, self.dz)
|
||||||
self.ncells = self.nx * self.ny * self.nz
|
self.ncells = self.nx * self.ny * self.nz
|
||||||
self.datasizefield = 3 * np.dtype(floattype).itemsize * self.ncells
|
self.datasizefield = (3 * np.dtype(config.dtypes['float_or_double']).itemsize
|
||||||
self.vtkdatawritesize = 2 * self.datasizefield + 2 * np.dtype(np.uint32).itemsize
|
* self.ncells)
|
||||||
|
self.vtkdatawritesize = ((self.fieldoutputs['electric']
|
||||||
|
+ self.fieldoutputs['magnetic']) * self.datasizefield
|
||||||
|
+ (self.fieldoutputs['electric']
|
||||||
|
+ self.fieldoutputs['magnetic'])
|
||||||
|
* np.dtype(np.uint32).itemsize)
|
||||||
self.time = time
|
self.time = time
|
||||||
self.basefilename = filename
|
self.basefilename = filename
|
||||||
|
|
||||||
@@ -101,12 +107,12 @@ class Snapshot(object):
|
|||||||
Hzslice = np.ascontiguousarray(G.Hz[self.sx, self.sy, self.sz])
|
Hzslice = np.ascontiguousarray(G.Hz[self.sx, self.sy, self.sz])
|
||||||
|
|
||||||
# Create arrays to hold the field data for snapshot
|
# Create arrays to hold the field data for snapshot
|
||||||
Exsnap = np.zeros((self.nx, self.ny, self.nz), dtype=floattype)
|
Exsnap = np.zeros((self.nx, self.ny, self.nz), dtype=config.dtypes['float_or_double'])
|
||||||
Eysnap = np.zeros((self.nx, self.ny, self.nz), dtype=floattype)
|
Eysnap = np.zeros((self.nx, self.ny, self.nz), dtype=config.dtypes['float_or_double'])
|
||||||
Ezsnap = np.zeros((self.nx, self.ny, self.nz), dtype=floattype)
|
Ezsnap = np.zeros((self.nx, self.ny, self.nz), dtype=config.dtypes['float_or_double'])
|
||||||
Hxsnap = np.zeros((self.nx, self.ny, self.nz), dtype=floattype)
|
Hxsnap = np.zeros((self.nx, self.ny, self.nz), dtype=config.dtypes['float_or_double'])
|
||||||
Hysnap = np.zeros((self.nx, self.ny, self.nz), dtype=floattype)
|
Hysnap = np.zeros((self.nx, self.ny, self.nz), dtype=config.dtypes['float_or_double'])
|
||||||
Hzsnap = np.zeros((self.nx, self.ny, self.nz), dtype=floattype)
|
Hzsnap = np.zeros((self.nx, self.ny, self.nz), dtype=config.dtypes['float_or_double'])
|
||||||
|
|
||||||
# Calculate field values at points (comes from averaging field components in cells)
|
# Calculate field values at points (comes from averaging field components in cells)
|
||||||
calculate_snapshot_fields(
|
calculate_snapshot_fields(
|
||||||
@@ -140,24 +146,48 @@ class Snapshot(object):
|
|||||||
G (class): Grid class instance - holds essential parameters describing the model.
|
G (class): Grid class instance - holds essential parameters describing the model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
hfield_offset = 3 * np.dtype(floattype).itemsize * self.ncells + np.dtype(np.uint32).itemsize
|
hfield_offset = (3 * np.dtype(config.dtypes['float_or_double']).itemsize
|
||||||
|
* self.ncells + np.dtype(np.uint32).itemsize)
|
||||||
|
|
||||||
self.filehandle = open(self.filename, 'wb')
|
self.filehandle = open(self.filename, 'wb')
|
||||||
self.filehandle.write('<?xml version="1.0"?>\n'.encode('utf-8'))
|
self.filehandle.write('<?xml version="1.0"?>\n'.encode('utf-8'))
|
||||||
self.filehandle.write('<VTKFile type="ImageData" version="1.0" byte_order="{}">\n'.format(Snapshot.byteorder).encode('utf-8'))
|
self.filehandle.write('<VTKFile type="ImageData" version="1.0" byte_order="{}">\n'
|
||||||
self.filehandle.write('<ImageData WholeExtent="{} {} {} {} {} {}" Origin="0 0 0" Spacing="{:.3} {:.3} {:.3}">\n'.format(self.xs, round_value(self.xf / self.dx), self.ys, round_value(self.yf / self.dy), self.zs, round_value(self.zf / self.dz), self.dx * G.dx, self.dy * G.dy, self.dz * G.dz).encode('utf-8'))
|
.format(Snapshot.byteorder).encode('utf-8'))
|
||||||
self.filehandle.write('<Piece Extent="{} {} {} {} {} {}">\n'.format(self.xs, round_value(self.xf / self.dx), self.ys, round_value(self.yf / self.dy), self.zs, round_value(self.zf / self.dz)).encode('utf-8'))
|
self.filehandle.write('<ImageData WholeExtent="{} {} {} {} {} {}" Origin="0 0 0" Spacing="{:.3} {:.3} {:.3}">\n'
|
||||||
|
.format(self.xs, round_value(self.xf / self.dx),
|
||||||
|
self.ys, round_value(self.yf / self.dy), self.zs,
|
||||||
|
round_value(self.zf / self.dz), self.dx * G.dx,
|
||||||
|
self.dy * G.dy, self.dz * G.dz).encode('utf-8'))
|
||||||
|
self.filehandle.write('<Piece Extent="{} {} {} {} {} {}">\n'
|
||||||
|
.format(self.xs, round_value(self.xf / self.dx),
|
||||||
|
self.ys, round_value(self.yf / self.dy),
|
||||||
|
self.zs, round_value(self.zf / self.dz)).encode('utf-8'))
|
||||||
|
|
||||||
|
if self.fieldoutputs['electric'] and self.fieldoutputs['magnetic']:
|
||||||
self.filehandle.write('<CellData Vectors="E-field H-field">\n'.encode('utf-8'))
|
self.filehandle.write('<CellData Vectors="E-field H-field">\n'.encode('utf-8'))
|
||||||
self.filehandle.write('<DataArray type="{}" Name="E-field" NumberOfComponents="3" format="appended" offset="0" />\n'.format(Snapshot.floatname).encode('utf-8'))
|
self.filehandle.write('<DataArray type="{}" Name="E-field" NumberOfComponents="3" format="appended" offset="0" />\n'
|
||||||
self.filehandle.write('<DataArray type="{}" Name="H-field" NumberOfComponents="3" format="appended" offset="{}" />\n'.format(Snapshot.floatname, hfield_offset).encode('utf-8'))
|
.format(Snapshot.floatname).encode('utf-8'))
|
||||||
|
self.filehandle.write('<DataArray type="{}" Name="H-field" NumberOfComponents="3" format="appended" offset="{}" />\n'
|
||||||
|
.format(Snapshot.floatname, hfield_offset).encode('utf-8'))
|
||||||
|
elif self.fieldoutputs['electric']:
|
||||||
|
self.filehandle.write('<CellData Vectors="E-field">\n'.encode('utf-8'))
|
||||||
|
self.filehandle.write('<DataArray type="{}" Name="E-field" NumberOfComponents="3" format="appended" offset="0" />\n'
|
||||||
|
.format(Snapshot.floatname).encode('utf-8'))
|
||||||
|
elif self.fieldoutputs['magnetic']:
|
||||||
|
self.filehandle.write('<CellData Vectors="H-field">\n'.encode('utf-8'))
|
||||||
|
self.filehandle.write('<DataArray type="{}" Name="H-field" NumberOfComponents="3" format="appended" offset="0" />\n'
|
||||||
|
.format(Snapshot.floatname).encode('utf-8'))
|
||||||
|
|
||||||
self.filehandle.write('</CellData>\n</Piece>\n</ImageData>\n<AppendedData encoding="raw">\n_'.encode('utf-8'))
|
self.filehandle.write('</CellData>\n</Piece>\n</ImageData>\n<AppendedData encoding="raw">\n_'.encode('utf-8'))
|
||||||
|
|
||||||
|
if self.fieldoutputs['electric']:
|
||||||
# Write number of bytes of appended data as UInt32
|
# Write number of bytes of appended data as UInt32
|
||||||
self.filehandle.write(pack('I', self.datasizefield))
|
self.filehandle.write(pack('I', self.datasizefield))
|
||||||
pbar.update(n=4)
|
pbar.update(n=4)
|
||||||
self.electric.tofile(self.filehandle)
|
self.electric.tofile(self.filehandle)
|
||||||
pbar.update(n=self.datasizefield)
|
pbar.update(n=self.datasizefield)
|
||||||
|
|
||||||
|
if self.fieldoutputs['magnetic']:
|
||||||
# Write number of bytes of appended data as UInt32
|
# Write number of bytes of appended data as UInt32
|
||||||
self.filehandle.write(pack('I', self.datasizefield))
|
self.filehandle.write(pack('I', self.datasizefield))
|
||||||
pbar.update(n=4)
|
pbar.update(n=4)
|
||||||
@@ -192,14 +222,22 @@ def gpu_initialise_snapshot_array(G):
|
|||||||
# GPU - blocks per grid - according to largest requested snapshot
|
# GPU - blocks per grid - according to largest requested snapshot
|
||||||
Snapshot.bpg = (int(np.ceil(((Snapshot.nx_max) * (Snapshot.ny_max) * (Snapshot.nz_max)) / Snapshot.tpb[0])), 1, 1)
|
Snapshot.bpg = (int(np.ceil(((Snapshot.nx_max) * (Snapshot.ny_max) * (Snapshot.nz_max)) / Snapshot.tpb[0])), 1, 1)
|
||||||
|
|
||||||
# 4D arrays to store snapshots on GPU, e.g. snapEx(time, x, y, z)
|
# 4D arrays to store snapshots on GPU, e.g. snapEx(time, x, y, z);
|
||||||
numsnaps = 1 if snapsgpu2cpu else len(G.snapshots)
|
# if snapshots are not being stored on the GPU during the simulation then
|
||||||
snapEx = np.zeros((numsnaps, Snapshot.nx_max, Snapshot.ny_max, Snapshot.nz_max), dtype=floattype)
|
# they are copied back to the host after each iteration, hence numsnaps = 1
|
||||||
snapEy = np.zeros((numsnaps, Snapshot.nx_max, Snapshot.ny_max, Snapshot.nz_max), dtype=floattype)
|
numsnaps = 1 if config.cuda['snapsgpu2cpu'] else len(G.snapshots)
|
||||||
snapEz = np.zeros((numsnaps, Snapshot.nx_max, Snapshot.ny_max, Snapshot.nz_max), dtype=floattype)
|
snapEx = np.zeros((numsnaps, Snapshot.nx_max, Snapshot.ny_max, Snapshot.nz_max),
|
||||||
snapHx = np.zeros((numsnaps, Snapshot.nx_max, Snapshot.ny_max, Snapshot.nz_max), dtype=floattype)
|
dtype=config.dtypes['float_or_double'])
|
||||||
snapHy = np.zeros((numsnaps, Snapshot.nx_max, Snapshot.ny_max, Snapshot.nz_max), dtype=floattype)
|
snapEy = np.zeros((numsnaps, Snapshot.nx_max, Snapshot.ny_max, Snapshot.nz_max),
|
||||||
snapHz = np.zeros((numsnaps, Snapshot.nx_max, Snapshot.ny_max, Snapshot.nz_max), dtype=floattype)
|
dtype=config.dtypes['float_or_double'])
|
||||||
|
snapEz = np.zeros((numsnaps, Snapshot.nx_max, Snapshot.ny_max, Snapshot.nz_max),
|
||||||
|
dtype=config.dtypes['float_or_double'])
|
||||||
|
snapHx = np.zeros((numsnaps, Snapshot.nx_max, Snapshot.ny_max, Snapshot.nz_max),
|
||||||
|
dtype=config.dtypes['float_or_double'])
|
||||||
|
snapHy = np.zeros((numsnaps, Snapshot.nx_max, Snapshot.ny_max, Snapshot.nz_max),
|
||||||
|
dtype=config.dtypes['float_or_double'])
|
||||||
|
snapHz = np.zeros((numsnaps, Snapshot.nx_max, Snapshot.ny_max, Snapshot.nz_max),
|
||||||
|
dtype=config.dtypes['float_or_double'])
|
||||||
|
|
||||||
# Copy arrays to GPU
|
# Copy arrays to GPU
|
||||||
snapEx_gpu = gpuarray.to_gpu(snapEx)
|
snapEx_gpu = gpuarray.to_gpu(snapEx)
|
||||||
|
@@ -20,12 +20,11 @@ from copy import deepcopy
|
|||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from gprMax.config import c
|
import gprMax.config as config
|
||||||
from gprMax.config import floattype
|
from .grid import Ix
|
||||||
from gprMax.grid import Ix
|
from .grid import Iy
|
||||||
from gprMax.grid import Iy
|
from .grid import Iz
|
||||||
from gprMax.grid import Iz
|
from .utilities import round_value
|
||||||
from gprMax.utilities import round_value
|
|
||||||
|
|
||||||
|
|
||||||
class Source(object):
|
class Source(object):
|
||||||
@@ -52,10 +51,10 @@ class Source(object):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Waveform values for electric sources - calculated half a timestep later
|
# Waveform values for electric sources - calculated half a timestep later
|
||||||
self.waveformvaluesJ = np.zeros((G.iterations), dtype=floattype)
|
self.waveformvaluesJ = np.zeros((G.iterations), dtype=config.dtypes['float_or_double'])
|
||||||
|
|
||||||
# Waveform values for magnetic sources
|
# Waveform values for magnetic sources
|
||||||
self.waveformvaluesM = np.zeros((G.iterations), dtype=floattype)
|
self.waveformvaluesM = np.zeros((G.iterations), dtype=config.dtypes['float_or_double'])
|
||||||
|
|
||||||
waveform = next(x for x in G.waveforms if x.ID == self.waveformID)
|
waveform = next(x for x in G.waveforms if x.ID == self.waveformID)
|
||||||
|
|
||||||
@@ -72,7 +71,8 @@ class VoltageSource(Source):
|
|||||||
"""
|
"""
|
||||||
A voltage source can be a hard source if it's resistance is zero, i.e. the
|
A voltage source can be a hard source if it's resistance is zero, i.e. the
|
||||||
time variation of the specified electric field component is prescribed.
|
time variation of the specified electric field component is prescribed.
|
||||||
If it's resistance is non-zero it behaves as a resistive voltage source."""
|
If it's resistance is non-zero it behaves as a resistive voltage source.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@@ -114,8 +114,7 @@ class VoltageSource(Source):
|
|||||||
Ez[i, j, k] = -1 * self.waveformvaluesJ[iteration] / G.dz
|
Ez[i, j, k] = -1 * self.waveformvaluesJ[iteration] / G.dz
|
||||||
|
|
||||||
def create_material(self, G):
|
def create_material(self, G):
|
||||||
"""
|
"""Create a new material at the voltage source location that adds the
|
||||||
Create a new material at the voltage source location that adds the
|
|
||||||
voltage source conductivity to the underlying parameters.
|
voltage source conductivity to the underlying parameters.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -231,8 +230,8 @@ def gpu_initialise_src_arrays(sources, G):
|
|||||||
import pycuda.gpuarray as gpuarray
|
import pycuda.gpuarray as gpuarray
|
||||||
|
|
||||||
srcinfo1 = np.zeros((len(sources), 4), dtype=np.int32)
|
srcinfo1 = np.zeros((len(sources), 4), dtype=np.int32)
|
||||||
srcinfo2 = np.zeros((len(sources)), dtype=floattype)
|
srcinfo2 = np.zeros((len(sources)), dtype=config.dtypes['float_or_double'])
|
||||||
srcwaves = np.zeros((len(sources), G.iterations), dtype=floattype)
|
srcwaves = np.zeros((len(sources), G.iterations), dtype=config.dtypes['float_or_double'])
|
||||||
for i, src in enumerate(sources):
|
for i, src in enumerate(sources):
|
||||||
srcinfo1[i, 0] = src.xcoord
|
srcinfo1[i, 0] = src.xcoord
|
||||||
srcinfo1[i, 1] = src.ycoord
|
srcinfo1[i, 1] = src.ycoord
|
||||||
@@ -262,9 +261,8 @@ def gpu_initialise_src_arrays(sources, G):
|
|||||||
|
|
||||||
|
|
||||||
class TransmissionLine(Source):
|
class TransmissionLine(Source):
|
||||||
"""
|
"""A transmission line source is a one-dimensional transmission line
|
||||||
A transmission line source is a one-dimensional transmission
|
which is attached virtually to a grid cell.
|
||||||
line which is attached virtually to a grid cell.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, G):
|
def __init__(self, G):
|
||||||
@@ -282,7 +280,7 @@ class TransmissionLine(Source):
|
|||||||
|
|
||||||
# Spatial step of transmission line (N.B if the magic time step is
|
# Spatial step of transmission line (N.B if the magic time step is
|
||||||
# used it results in instabilities for certain impedances)
|
# used it results in instabilities for certain impedances)
|
||||||
self.dl = np.sqrt(3) * c * G.dt
|
self.dl = np.sqrt(3) * config.c * G.dt
|
||||||
|
|
||||||
# Number of cells in the transmission line (initially a long line to
|
# Number of cells in the transmission line (initially a long line to
|
||||||
# calculate incident voltage and current); consider putting ABCs/PML at end
|
# calculate incident voltage and current); consider putting ABCs/PML at end
|
||||||
@@ -294,16 +292,15 @@ class TransmissionLine(Source):
|
|||||||
# Cell position of where line connects to antenna/main grid
|
# Cell position of where line connects to antenna/main grid
|
||||||
self.antpos = 10
|
self.antpos = 10
|
||||||
|
|
||||||
self.voltage = np.zeros(self.nl, dtype=floattype)
|
self.voltage = np.zeros(self.nl, dtype=config.dtypes['float_or_double'])
|
||||||
self.current = np.zeros(self.nl, dtype=floattype)
|
self.current = np.zeros(self.nl, dtype=config.dtypes['float_or_double'])
|
||||||
self.Vinc = np.zeros(G.iterations, dtype=floattype)
|
self.Vinc = np.zeros(G.iterations, dtype=config.dtypes['float_or_double'])
|
||||||
self.Iinc = np.zeros(G.iterations, dtype=floattype)
|
self.Iinc = np.zeros(G.iterations, dtype=config.dtypes['float_or_double'])
|
||||||
self.Vtotal = np.zeros(G.iterations, dtype=floattype)
|
self.Vtotal = np.zeros(G.iterations, dtype=config.dtypes['float_or_double'])
|
||||||
self.Itotal = np.zeros(G.iterations, dtype=floattype)
|
self.Itotal = np.zeros(G.iterations, dtype=config.dtypes['float_or_double'])
|
||||||
|
|
||||||
def calculate_incident_V_I(self, G):
|
def calculate_incident_V_I(self, G):
|
||||||
"""
|
"""Calculates the incident voltage and current with a long length
|
||||||
Calculates the incident voltage and current with a long length
|
|
||||||
transmission line not connected to the main grid from: http://dx.doi.org/10.1002/mop.10415
|
transmission line not connected to the main grid from: http://dx.doi.org/10.1002/mop.10415
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -326,7 +323,7 @@ class TransmissionLine(Source):
|
|||||||
G (class): Grid class instance - holds essential parameters describing the model.
|
G (class): Grid class instance - holds essential parameters describing the model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
h = (c * G.dt - self.dl) / (c * G.dt + self.dl)
|
h = (config.c * G.dt - self.dl) / (config.c * G.dt + self.dl)
|
||||||
|
|
||||||
self.voltage[0] = h * (self.voltage[1] - self.abcv0) + self.abcv1
|
self.voltage[0] = h * (self.voltage[1] - self.abcv0) + self.abcv1
|
||||||
self.abcv0 = self.voltage[0]
|
self.abcv0 = self.voltage[0]
|
||||||
@@ -341,10 +338,10 @@ class TransmissionLine(Source):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Update all the voltage values along the line
|
# Update all the voltage values along the line
|
||||||
self.voltage[1:self.nl] -= self.resistance * (c * G.dt / self.dl) * (self.current[1:self.nl] - self.current[0:self.nl - 1])
|
self.voltage[1:self.nl] -= self.resistance * (config.c * G.dt / self.dl) * (self.current[1:self.nl] - self.current[0:self.nl - 1])
|
||||||
|
|
||||||
# Update the voltage at the position of the one-way injector excitation
|
# Update the voltage at the position of the one-way injector excitation
|
||||||
self.voltage[self.srcpos] += (c * G.dt / self.dl) * self.waveformvaluesJ[iteration]
|
self.voltage[self.srcpos] += (config.c * G.dt / self.dl) * self.waveformvaluesJ[iteration]
|
||||||
|
|
||||||
# Update ABC before updating current
|
# Update ABC before updating current
|
||||||
self.update_abc(G)
|
self.update_abc(G)
|
||||||
@@ -358,10 +355,10 @@ class TransmissionLine(Source):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Update all the current values along the line
|
# Update all the current values along the line
|
||||||
self.current[0:self.nl - 1] -= (1 / self.resistance) * (c * G.dt / self.dl) * (self.voltage[1:self.nl] - self.voltage[0:self.nl - 1])
|
self.current[0:self.nl - 1] -= (1 / self.resistance) * (config.c * G.dt / self.dl) * (self.voltage[1:self.nl] - self.voltage[0:self.nl - 1])
|
||||||
|
|
||||||
# Update the current one cell before the position of the one-way injector excitation
|
# Update the current one cell before the position of the one-way injector excitation
|
||||||
self.current[self.srcpos - 1] += (1 / self.resistance) * (c * G.dt / self.dl) * self.waveformvaluesM[iteration]
|
self.current[self.srcpos - 1] += (1 / self.resistance) * (config.c * G.dt / self.dl) * self.waveformvaluesM[iteration]
|
||||||
|
|
||||||
def update_electric(self, iteration, updatecoeffsE, ID, Ex, Ey, Ez, G):
|
def update_electric(self, iteration, updatecoeffsE, ID, Ex, Ey, Ez, G):
|
||||||
"""Updates electric field value in the main grid from voltage value in the transmission line.
|
"""Updates electric field value in the main grid from voltage value in the transmission line.
|
||||||
@@ -416,95 +413,3 @@ class TransmissionLine(Source):
|
|||||||
self.current[self.antpos] = Iz(i, j, k, G.Hx, G.Hy, G.Hz, G)
|
self.current[self.antpos] = Iz(i, j, k, G.Hx, G.Hy, G.Hz, G)
|
||||||
|
|
||||||
self.update_current(iteration, G)
|
self.update_current(iteration, G)
|
||||||
|
|
||||||
|
|
||||||
class PlaneWave(Source):
|
|
||||||
"""A plane wave source. It uses a total-field/scattered-field (TF/SF) formulation."""
|
|
||||||
|
|
||||||
def __init__(self, G):
|
|
||||||
"""
|
|
||||||
Args:
|
|
||||||
G (class): Grid class instance - holds essential parameters describing the model.
|
|
||||||
"""
|
|
||||||
|
|
||||||
super(Source, self).__init__()
|
|
||||||
|
|
||||||
# Coordinates defining Huygen's surface
|
|
||||||
self.xs = 0
|
|
||||||
self.xf = 0
|
|
||||||
self.ys = 0
|
|
||||||
self.yf = 0
|
|
||||||
self.zs = 0
|
|
||||||
self.zf = 0
|
|
||||||
|
|
||||||
# Spherical coordinates defining incident unit wavevector (k)
|
|
||||||
self.theta = 0 # 0 <= theta <= 180
|
|
||||||
self.phi = 0 # 0 <= phi <= 360
|
|
||||||
|
|
||||||
# Angle that incident electric field makes with k cross z
|
|
||||||
self.psi = 0 # 0 <= psi <= 360
|
|
||||||
|
|
||||||
def calculate_origin(self, G):
|
|
||||||
"""Calculate origin of TF/SF interface with incident wavefront."""
|
|
||||||
|
|
||||||
if self.theta >= 0 and self.theta <= 90:
|
|
||||||
if self.phi >= 0 and self.phi <= 90:
|
|
||||||
self.xcoordorigin = 0
|
|
||||||
self.ycoordorigin = 0
|
|
||||||
self.zcoordorigin = 0
|
|
||||||
|
|
||||||
elif self.phi > 90 and self.phi <= 180:
|
|
||||||
self.xcoordorigin = G.nx
|
|
||||||
self.ycoordorigin = 0
|
|
||||||
self.zcoordorigin = 0
|
|
||||||
|
|
||||||
elif self.phi > 180 and self.phi <= 270:
|
|
||||||
self.xcoordorigin = G.nx
|
|
||||||
self.ycoordorigin = G.ny
|
|
||||||
self.zcoordorigin = 0
|
|
||||||
|
|
||||||
elif self.phi > 270 and self.phi <= 360:
|
|
||||||
self.xcoordorigin = 0
|
|
||||||
self.ycoordorigin = G.ny
|
|
||||||
self.zcoordorigin = 0
|
|
||||||
|
|
||||||
elif self.theta > 90 and self.theta <= 180:
|
|
||||||
if self.phi >= 0 and self.phi <= 90:
|
|
||||||
self.xcoordorigin = 0
|
|
||||||
self.ycoordorigin = 0
|
|
||||||
self.zcoordorigin = G.nz
|
|
||||||
|
|
||||||
elif self.phi > 90 and self.phi <= 180:
|
|
||||||
self.xcoordorigin = G.nx
|
|
||||||
self.ycoordorigin = 0
|
|
||||||
self.zcoordorigin = G.nz
|
|
||||||
|
|
||||||
elif self.phi > 180 and self.phi <= 270:
|
|
||||||
self.xcoordorigin = G.nx
|
|
||||||
self.ycoordorigin = G.ny
|
|
||||||
self.zcoordorigin = G.nz
|
|
||||||
|
|
||||||
elif self.phi > 270 and self.phi <= 360:
|
|
||||||
self.xcoordorigin = 0
|
|
||||||
self.ycoordorigin = G.ny
|
|
||||||
self.zcoordorigin = G.nz
|
|
||||||
|
|
||||||
def calculate_vector_components(self):
|
|
||||||
"""Calculate components of incident fields."""
|
|
||||||
|
|
||||||
self.theta = np.deg2rad(self.theta)
|
|
||||||
self.phi = np.deg2rad(self.phi)
|
|
||||||
self.psi = np.deg2rad(self.psi)
|
|
||||||
|
|
||||||
# Components of incident unit wavevector
|
|
||||||
self.kx = np.sin(self.theta) * np.cos(self.phi)
|
|
||||||
self.ky = np.sin(self.theta) * np.sin(self.phi)
|
|
||||||
self.kz = np.cos(self.theta)
|
|
||||||
|
|
||||||
# Components of incident field vectors
|
|
||||||
self.Exinc = np.cos(self.psi) * np.sin(self.phi) - np.sin(self.psi) * np.cos(self.theta) * np.cos(self.phi)
|
|
||||||
self.Eyinc = -np.cos(self.psi) * np.cos(self.phi) - np.sin(self.psi) * np.cos(self.theta) * np.sin(self.phi)
|
|
||||||
self.Ezinc = np.sin(self.psi) * np.sin(self.theta)
|
|
||||||
self.Hxinc = np.sin(self.psi) * np.sin(self.phi) + np.cos(self.psi) * np.cos(self.theta) * np.cos(self.phi)
|
|
||||||
self.Hyinc = -np.sin(self.psi) * np.cos(self.phi) + np.cos(self.psi) * np.cos(self.theta) * np.sin(self.phi)
|
|
||||||
self.Hzinc = -np.cos(self.psi) * np.sin(self.theta)
|
|
||||||
|
@@ -27,15 +27,15 @@ import subprocess
|
|||||||
from shutil import get_terminal_size
|
from shutil import get_terminal_size
|
||||||
import sys
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
|
from time import perf_counter
|
||||||
|
|
||||||
from colorama import init
|
from colorama import init
|
||||||
from colorama import Fore
|
from colorama import Fore
|
||||||
from colorama import Style
|
from colorama import Style
|
||||||
init()
|
init()
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from time import process_time
|
|
||||||
|
|
||||||
from gprMax.exceptions import GeneralError
|
from .exceptions import GeneralError
|
||||||
|
|
||||||
|
|
||||||
def get_terminal_width():
|
def get_terminal_width():
|
||||||
@@ -86,8 +86,7 @@ def logo(version):
|
|||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def open_path_file(path_or_file):
|
def open_path_file(path_or_file):
|
||||||
"""
|
"""Accepts either a path as a string or a file object and returns a file
|
||||||
Accepts either a path as a string or a file object and returns a file
|
|
||||||
object (http://stackoverflow.com/a/6783680).
|
object (http://stackoverflow.com/a/6783680).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -417,4 +416,4 @@ def detect_check_gpus(deviceIDs):
|
|||||||
|
|
||||||
def timer():
|
def timer():
|
||||||
"""Function to return the current process wide time in fractional seconds."""
|
"""Function to return the current process wide time in fractional seconds."""
|
||||||
return process_time()
|
return perf_counter()
|
||||||
|
@@ -18,8 +18,6 @@
|
|||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from gprMax.utilities import round_value
|
|
||||||
|
|
||||||
|
|
||||||
class Waveform(object):
|
class Waveform(object):
|
||||||
"""Definitions of waveform shapes that can be used with sources."""
|
"""Definitions of waveform shapes that can be used with sources."""
|
||||||
|
@@ -40,22 +40,22 @@ from tests.analytical_solutions import hertzian_dipole_fs
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
basepath = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'models_')
|
basepath = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'models_')
|
||||||
# basepath += 'basic'
|
basepath += 'basic'
|
||||||
# basepath += 'advanced'
|
# basepath += 'advanced'
|
||||||
basepath += 'pmls'
|
# basepath += 'pmls'
|
||||||
|
|
||||||
# List of available basic test models
|
# List of available basic test models
|
||||||
# testmodels = ['hertzian_dipole_fs_analytical', '2D_ExHyHz', '2D_EyHxHz', '2D_EzHxHy', 'cylinder_Ascan_2D', 'hertzian_dipole_fs', 'hertzian_dipole_hs', 'hertzian_dipole_dispersive', 'magnetic_dipole_fs', 'pmls']
|
testmodels = ['hertzian_dipole_fs_analytical', '2D_ExHyHz', '2D_EyHxHz', '2D_EzHxHy', 'cylinder_Ascan_2D', 'hertzian_dipole_fs', 'hertzian_dipole_hs', 'hertzian_dipole_dispersive', 'magnetic_dipole_fs']
|
||||||
|
|
||||||
# List of available advanced test models
|
# List of available advanced test models
|
||||||
# testmodels = ['antenna_GSSI_1500_fs', 'antenna_MALA_1200_fs']
|
# testmodels = ['antenna_GSSI_1500_fs', 'antenna_MALA_1200_fs']
|
||||||
|
|
||||||
# List of available PML models
|
# List of available PML models
|
||||||
testmodels = ['pml_x0', 'pml_y0', 'pml_z0', 'pml_xmax', 'pml_ymax', 'pml_zmax', 'pml_3D_pec_plate']
|
# testmodels = ['pml_x0', 'pml_y0', 'pml_z0', 'pml_xmax', 'pml_ymax', 'pml_zmax', 'pml_3D_pec_plate']
|
||||||
|
|
||||||
# Select a specific model if desired
|
# Select a specific model if desired
|
||||||
# testmodels = testmodels[:-1]
|
# testmodels = testmodels[:-1]
|
||||||
testmodels = [testmodels[6]]
|
# testmodels = [testmodels[6]]
|
||||||
testresults = dict.fromkeys(testmodels)
|
testresults = dict.fromkeys(testmodels)
|
||||||
path = '/rxs/rx1/'
|
path = '/rxs/rx1/'
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ for i, model in enumerate(testmodels):
|
|||||||
|
|
||||||
# Run model
|
# Run model
|
||||||
inputfile = os.path.join(basepath, model + os.path.sep + model + '.in')
|
inputfile = os.path.join(basepath, model + os.path.sep + model + '.in')
|
||||||
api(inputfile, gpu=[None])
|
api(inputfile, gpu=None)
|
||||||
|
|
||||||
# Special case for analytical comparison
|
# Special case for analytical comparison
|
||||||
if model == 'hertzian_dipole_fs_analytical':
|
if model == 'hertzian_dipole_fs_analytical':
|
||||||
@@ -80,12 +80,12 @@ for i, model in enumerate(testmodels):
|
|||||||
outputstest = list(filetest[path].keys())
|
outputstest = list(filetest[path].keys())
|
||||||
|
|
||||||
# Arrays for storing time
|
# Arrays for storing time
|
||||||
floattype = filetest[path + outputstest[0]].dtype
|
float_or_double = filetest[path + outputstest[0]].dtype
|
||||||
timetest = np.linspace(0, (filetest.attrs['Iterations'] - 1) * filetest.attrs['dt'], num=filetest.attrs['Iterations']) / 1e-9
|
timetest = np.linspace(0, (filetest.attrs['Iterations'] - 1) * filetest.attrs['dt'], num=filetest.attrs['Iterations']) / 1e-9
|
||||||
timeref = timetest
|
timeref = timetest
|
||||||
|
|
||||||
# Arrays for storing field data
|
# Arrays for storing field data
|
||||||
datatest = np.zeros((filetest.attrs['Iterations'], len(outputstest)), dtype=floattype)
|
datatest = np.zeros((filetest.attrs['Iterations'], len(outputstest)), dtype=float_or_double)
|
||||||
for ID, name in enumerate(outputstest):
|
for ID, name in enumerate(outputstest):
|
||||||
datatest[:, ID] = filetest[path + str(name)][:]
|
datatest[:, ID] = filetest[path + str(name)][:]
|
||||||
if np.any(np.isnan(datatest[:, ID])):
|
if np.any(np.isnan(datatest[:, ID])):
|
||||||
@@ -117,18 +117,18 @@ for i, model in enumerate(testmodels):
|
|||||||
# Check that type of float used to store fields matches
|
# Check that type of float used to store fields matches
|
||||||
if filetest[path + outputstest[0]].dtype != fileref[path + outputsref[0]].dtype:
|
if filetest[path + outputstest[0]].dtype != fileref[path + outputsref[0]].dtype:
|
||||||
print(Fore.RED + 'WARNING: Type of floating point number in test model ({}) does not match type in reference solution ({})\n'.format(filetest[path + outputstest[0]].dtype, fileref[path + outputsref[0]].dtype) + Style.RESET_ALL)
|
print(Fore.RED + 'WARNING: Type of floating point number in test model ({}) does not match type in reference solution ({})\n'.format(filetest[path + outputstest[0]].dtype, fileref[path + outputsref[0]].dtype) + Style.RESET_ALL)
|
||||||
floattyperef = fileref[path + outputsref[0]].dtype
|
float_or_doubleref = fileref[path + outputsref[0]].dtype
|
||||||
floattypetest = filetest[path + outputstest[0]].dtype
|
float_or_doubletest = filetest[path + outputstest[0]].dtype
|
||||||
|
|
||||||
# Arrays for storing time
|
# Arrays for storing time
|
||||||
timeref = np.zeros((fileref.attrs['Iterations']), dtype=floattyperef)
|
timeref = np.zeros((fileref.attrs['Iterations']), dtype=float_or_doubleref)
|
||||||
timeref = np.linspace(0, (fileref.attrs['Iterations'] - 1) * fileref.attrs['dt'], num=fileref.attrs['Iterations']) / 1e-9
|
timeref = np.linspace(0, (fileref.attrs['Iterations'] - 1) * fileref.attrs['dt'], num=fileref.attrs['Iterations']) / 1e-9
|
||||||
timetest = np.zeros((filetest.attrs['Iterations']), dtype=floattypetest)
|
timetest = np.zeros((filetest.attrs['Iterations']), dtype=float_or_doubletest)
|
||||||
timetest = np.linspace(0, (filetest.attrs['Iterations'] - 1) * filetest.attrs['dt'], num=filetest.attrs['Iterations']) / 1e-9
|
timetest = np.linspace(0, (filetest.attrs['Iterations'] - 1) * filetest.attrs['dt'], num=filetest.attrs['Iterations']) / 1e-9
|
||||||
|
|
||||||
# Arrays for storing field data
|
# Arrays for storing field data
|
||||||
dataref = np.zeros((fileref.attrs['Iterations'], len(outputsref)), dtype=floattyperef)
|
dataref = np.zeros((fileref.attrs['Iterations'], len(outputsref)), dtype=float_or_doubleref)
|
||||||
datatest = np.zeros((filetest.attrs['Iterations'], len(outputstest)), dtype=floattypetest)
|
datatest = np.zeros((filetest.attrs['Iterations'], len(outputstest)), dtype=float_or_doubletest)
|
||||||
for ID, name in enumerate(outputsref):
|
for ID, name in enumerate(outputsref):
|
||||||
dataref[:, ID] = fileref[path + str(name)][:]
|
dataref[:, ID] = fileref[path + str(name)][:]
|
||||||
datatest[:, ID] = filetest[path + str(name)][:]
|
datatest[:, ID] = filetest[path + str(name)][:]
|
||||||
|
在新工单中引用
屏蔽一个用户