|
4 | 4 |
|
5 | 5 | import json
|
6 | 6 | import pathlib
|
| 7 | +import re |
7 | 8 | from abc import ABC
|
8 | 9 | from collections import defaultdict
|
9 | 10 | from typing import Callable, Optional, Union
|
|
14 | 15 | import xarray as xr
|
15 | 16 |
|
16 | 17 | from tidy3d.components.autograd.utils import split_list
|
17 |
| -from tidy3d.components.base import JSON_TAG, Tidy3dBaseModel |
| 18 | +from tidy3d.components.base import JSON_TAG, Tidy3dBaseModel, cached_property |
18 | 19 | from tidy3d.components.base_sim.data.sim_data import AbstractSimulationData
|
19 | 20 | from tidy3d.components.file_util import replace_values
|
20 | 21 | from tidy3d.components.monitor import Monitor
|
|
29 | 30 | from tidy3d.exceptions import DataError, FileError, Tidy3dKeyError
|
30 | 31 | from tidy3d.log import log
|
31 | 32 |
|
32 |
| -from .data_array import FreqDataArray |
| 33 | +from .data_array import FreqDataArray, TimeDataArray |
33 | 34 | from .monitor_data import AbstractFieldData, FieldTimeData, MonitorDataType, MonitorDataTypes
|
34 | 35 |
|
35 | 36 | DATA_TYPE_MAP = {data.__fields__["monitor"].type_: data for data in MonitorDataTypes}
|
@@ -931,21 +932,29 @@ class SimulationData(AbstractYeeGridSimulationData):
|
931 | 932 | description="A boolean flag denoting whether the simulation run diverged.",
|
932 | 933 | )
|
933 | 934 |
|
934 |
| - @property |
935 |
| - def final_decay_value(self) -> float: |
936 |
| - """Returns value of the field decay at the final time step.""" |
| 935 | + @cached_property |
| 936 | + def field_decay(self) -> TimeDataArray: |
| 937 | + """Returns a TimeDataArray of field decay values over time steps.""" |
937 | 938 | log_str = self.log
|
938 | 939 | if log_str is None:
|
939 | 940 | raise DataError(
|
940 |
| - "No log string in the SimulationData object, can't find final decay value." |
| 941 | + "No log string in the SimulationData object, can't extract field decay." |
941 | 942 | )
|
942 |
| - lines = log_str.split("\n") |
943 |
| - decay_lines = [line for line in lines if "field decay" in line] |
944 |
| - final_decay = 1.0 |
945 |
| - if len(decay_lines) > 0: |
946 |
| - final_decay_line = decay_lines[-1] |
947 |
| - final_decay = float(final_decay_line.split("field decay: ")[-1]) |
948 |
| - return final_decay |
| 943 | + |
| 944 | + matches = re.findall(r"- Time step\s+(\d+)\s+/.*?field decay:\s*([0-9.eE+-]+)", log_str) |
| 945 | + |
| 946 | + steps = [int(m[0]) for m in matches] |
| 947 | + decays = [float(m[1]) for m in matches] |
| 948 | + return TimeDataArray(decays, coords={"t": steps}) |
| 949 | + |
| 950 | + @property |
| 951 | + def final_decay_value(self) -> float: |
| 952 | + """Returns value of the field decay at the final time step.""" |
| 953 | + field_decay = self.field_decay |
| 954 | + if len(field_decay) == 0: |
| 955 | + log.warning("No field decay values found, using 1.0 as final decay value.") |
| 956 | + return 1.0 |
| 957 | + return float(field_decay.values[-1]) |
949 | 958 |
|
950 | 959 | def source_spectrum(self, source_index: int) -> Callable:
|
951 | 960 | """Get a spectrum normalization function for a given source index."""
|
|
0 commit comments