Avoid duplication of waveform pre-calculation values.

这个提交包含在:
Craig Warren
2025-02-04 16:47:15 +00:00
父节点 366902dc0b
当前提交 3b19844ddd

146
gprMax/sources.py 普通文件 -> 可执行文件
查看文件

@@ -41,29 +41,10 @@ class Source:
self.start = None
self.stop = None
self.waveformID = None
def calculate_waveform_values(self, G):
"""Calculates all waveform values for source for duration of simulation.
Args:
G: FDTDGrid class describing a grid in a model.
"""
# Waveform values for sources that need to be calculated on whole timesteps
self.waveformvalues_wholedt = np.zeros((G.iterations), dtype=config.sim_config.dtypes["float_or_double"])
self.waveformvalues_wholedt = None
# Waveform values for sources that need to be calculated on half timesteps
self.waveformvalues_halfdt = np.zeros((G.iterations), dtype=config.sim_config.dtypes["float_or_double"])
waveform = next(x for x in G.waveforms if x.ID == self.waveformID)
for iteration in range(G.iterations):
time = G.dt * iteration
if time >= self.start and time <= self.stop:
# Set the time of the waveform evaluation to account for any
# delay in the start
time -= self.start
self.waveformvalues_wholedt[iteration] = waveform.calculate_value(time, G.dt)
self.waveformvalues_halfdt[iteration] = waveform.calculate_value(time + 0.5 * G.dt, G.dt)
self.waveformvalues_halfdt = None
class VoltageSource(Source):
@@ -77,6 +58,36 @@ class VoltageSource(Source):
super().__init__()
self.resistance = None
def calculate_waveform_values(self, G):
"""Calculates all waveform values for source for duration of simulation.
Args:
G: FDTDGrid class describing a grid in a model.
"""
# Check if a source matches existing source in terms of waveform and
# does not have a customised start/stop time. If so, use its
# pre-calculated waveform values, otherwise calculate them.
src_match = False
if self.start == 0 and self.stop == G.timewindow:
for src in G.voltagesources:
if src.waveformID == self.waveformID:
src_match = True
self.waveformvalues_wholedt = src.waveformvalues_wholedt
if not src_match:
waveform = next(x for x in G.waveforms if x.ID == self.waveformID)
self.waveformvalues_wholedt = np.zeros((G.iterations), dtype=config.sim_config.dtypes["float_or_double"])
for iteration in range(G.iterations):
time = G.dt * iteration
if time >= self.start and time <= self.stop:
# Set the time of the waveform evaluation to account for any
# delay in the start
time -= self.start
self.waveformvalues_wholedt[iteration] = waveform.calculate_value(time, G.dt)
def update_electric(self, iteration, updatecoeffsE, ID, Ex, Ey, Ez, G):
"""Updates electric field values for a voltage source.
@@ -168,6 +179,36 @@ class HertzianDipole(Source):
super().__init__()
self.dl = None
def calculate_waveform_values(self, G):
"""Calculates all waveform values for source for duration of simulation.
Args:
G: FDTDGrid class describing a grid in a model.
"""
# Check if a source matches existing source in terms of waveform and
# does not have a customised start/stop time. If so, use its
# pre-calculated waveform values, otherwise calculate them.
src_match = False
if self.start == 0 and self.stop == G.timewindow:
for src in G.hertziandipoles:
if src.waveformID == self.waveformID:
src_match = True
self.waveformvalues_halfdt = src.waveformvalues_halfdt
if not src_match:
waveform = next(x for x in G.waveforms if x.ID == self.waveformID)
self.waveformvalues_halfdt = np.zeros((G.iterations), dtype=config.sim_config.dtypes["float_or_double"])
for iteration in range(G.iterations):
time = G.dt * iteration
if time >= self.start and time <= self.stop:
# Set the time of the waveform evaluation to account for any
# delay in the start
time -= self.start
self.waveformvalues_halfdt[iteration] = waveform.calculate_value(time + 0.5 * G.dt, G.dt)
def update_electric(self, iteration, updatecoeffsE, ID, Ex, Ey, Ez, G):
"""Updates electric field values for a Hertzian dipole.
@@ -214,6 +255,36 @@ class HertzianDipole(Source):
class MagneticDipole(Source):
"""A magnetic dipole is an additive source (magnetic current density)."""
def calculate_waveform_values(self, G):
"""Calculates all waveform values for source for duration of simulation.
Args:
G: FDTDGrid class describing a grid in a model.
"""
# Check if a source matches existing source in terms of waveform and
# does not have a customised start/stop time. If so, use its
# pre-calculated waveform values, otherwise calculate them.
src_match = False
if self.start == 0 and self.stop == G.timewindow:
for src in G.magneticdipoles:
if src.waveformID == self.waveformID:
src_match = True
self.waveformvalues_wholedt = src.waveformvalues_wholedt
if not src_match:
waveform = next(x for x in G.waveforms if x.ID == self.waveformID)
self.waveformvalues_wholedt = np.zeros((G.iterations), dtype=config.sim_config.dtypes["float_or_double"])
for iteration in range(G.iterations):
time = G.dt * iteration
if time >= self.start and time <= self.stop:
# Set the time of the waveform evaluation to account for any
# delay in the start
time -= self.start
self.waveformvalues_wholedt[iteration] = waveform.calculate_value(time, G.dt)
def update_magnetic(self, iteration, updatecoeffsH, ID, Hx, Hy, Hz, G):
"""Updates magnetic field values for a magnetic dipole.
@@ -358,6 +429,39 @@ class TransmissionLine(Source):
self.Vtotal = np.zeros(G.iterations, dtype=config.sim_config.dtypes["float_or_double"])
self.Itotal = np.zeros(G.iterations, dtype=config.sim_config.dtypes["float_or_double"])
def calculate_waveform_values(self, G):
"""Calculates all waveform values for source for duration of simulation.
Args:
G: FDTDGrid class describing a grid in a model.
"""
# Check if a source matches existing source in terms of waveform and
# does not have a customised start/stop time. If so, use its
# pre-calculated waveform values, otherwise calculate them.
src_match = False
if self.start == 0 and self.stop == G.timewindow:
for src in G.transmissionlines:
if src.waveformID == self.waveformID:
src_match = True
self.waveformvalues_wholedt = src.waveformvalues_wholedt
self.waveformvalues_halfdt = src.waveformvalues_halfdt
if not src_match:
waveform = next(x for x in G.waveforms if x.ID == self.waveformID)
self.waveformvalues_wholedt = np.zeros((G.iterations), dtype=config.sim_config.dtypes["float_or_double"])
self.waveformvalues_halfdt = np.zeros((G.iterations), dtype=config.sim_config.dtypes["float_or_double"])
for iteration in range(G.iterations):
time = G.dt * iteration
if time >= self.start and time <= self.stop:
# Set the time of the waveform evaluation to account for any
# delay in the start
time -= self.start
self.waveformvalues_wholedt[iteration] = waveform.calculate_value(time, G.dt)
self.waveformvalues_halfdt[iteration] = waveform.calculate_value(time + 0.5 * G.dt, G.dt)
def calculate_incident_V_I(self, G):
"""Calculates the incident voltage and current with a long length
transmission line not connected to the main grid