Skip to content

Commit 1752831

Browse files
committed
Comments Momchil
1 parent d325a9b commit 1752831

File tree

4 files changed

+32
-191
lines changed

4 files changed

+32
-191
lines changed

tidy3d/components/tcad/data/monitor_data/abstract.py

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
HeatChargeMonitorType,
1919
)
2020
from tidy3d.components.types import Coordinate, ScalarSymmetry, annotate_type
21+
from tidy3d.log import log
2122

2223
FieldDataset = Union[
2324
SpatialDataArray, annotate_type(Union[TriangularGridDataset, TetrahedralGridDataset])
@@ -47,15 +48,27 @@ class HeatChargeMonitorData(AbstractMonitorData, ABC):
4748
)
4849

4950
@abstractmethod
50-
def symmetry_expanded_copy(self) -> HeatChargeMonitorData:
51-
"""Return copy of self with symmetry applied."""
51+
def field_components(self) -> dict:
52+
"""Maps the field components to their associated data."""
5253

5354
@abstractmethod
5455
def field_name(self, val: str) -> str:
5556
"""Gets the name of the fields to be plot."""
5657

57-
# def _symmetry_expanded_copy(self, property):
58-
def _symmetry_expanded_copy(self, property: FieldDataset) -> FieldDataset:
58+
@property
59+
def symmetry_expanded_copy(self) -> HeatChargeMonitorData:
60+
"""Return copy of self with symmetry applied."""
61+
62+
new_field_components = {}
63+
for field, val in self.field_components.items():
64+
new_field_components[field] = self._symmetry_expanded_copy_base(property=val)
65+
66+
if len(new_field_components) == 0:
67+
return self
68+
69+
return self.updated_copy(symmetry=(0, 0, 0), **new_field_components)
70+
71+
def _symmetry_expanded_copy_base(self, property: FieldDataset) -> FieldDataset:
5972
"""Return the property with symmetry applied."""
6073

6174
# no symmetry
@@ -118,3 +131,13 @@ def _symmetry_expanded_copy(self, property: FieldDataset) -> FieldDataset:
118131
new_property = new_property.box_clip(bounds=clip_bounds)
119132

120133
return new_property
134+
135+
def _post_init_validators(self):
136+
"""Call validators taking ``self`` that get run after init."""
137+
# validate that data exists for all fields
138+
for field_name, field in self.field_components.items():
139+
if field is None:
140+
log.warning(
141+
f"No data is available for monitor '{self.monitor.name}' field '{field_name}'. "
142+
"This is typically caused by monitor not intersecting any solid medium."
143+
)

tidy3d/components/tcad/data/monitor_data/charge.py

Lines changed: 5 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import numpy as np
88
import pydantic.v1 as pd
99

10-
from tidy3d.components.base import skip_if_fields_missing
1110
from tidy3d.components.data.data_array import (
1211
DataArray,
1312
IndexedFieldVoltageDataArray,
@@ -29,7 +28,6 @@
2928
from tidy3d.components.types import TYPE_TAG_STR, Ax, annotate_type
3029
from tidy3d.components.viz import add_ax_if_none
3130
from tidy3d.exceptions import DataError
32-
from tidy3d.log import log
3331

3432
FieldDataset = Union[
3533
SpatialDataArray, annotate_type(Union[TriangularGridDataset, TetrahedralGridDataset])
@@ -58,28 +56,6 @@ def field_components(self) -> dict[str, DataArray]:
5856
"""Maps the field components to their associated data."""
5957
return {"potential": self.potential}
6058

61-
@pd.validator("potential", always=True)
62-
@skip_if_fields_missing(["monitor"])
63-
def warn_no_data(cls, val, values):
64-
"""Warn if no data provided."""
65-
66-
mnt = values.get("monitor")
67-
68-
if val is None:
69-
log.warning(
70-
f"No data is available for monitor '{mnt.name}'. This is typically caused by "
71-
"monitor not intersecting any solid medium."
72-
)
73-
74-
return val
75-
76-
@property
77-
def symmetry_expanded_copy(self) -> SteadyPotentialData:
78-
"""Return copy of self with symmetry applied."""
79-
80-
new_potential = self._symmetry_expanded_copy(property=self.potential)
81-
return self.updated_copy(potential=new_potential, symmetry=(0, 0, 0))
82-
8359
def field_name(self, val: str) -> str:
8460
"""Gets the name of the fields to be plotted."""
8561
if val == "abs^2":
@@ -143,35 +119,6 @@ def check_correct_data_type(cls, values):
143119

144120
return values
145121

146-
@pd.root_validator(skip_on_failure=True)
147-
def warn_no_data(cls, values):
148-
"""Warn if no data provided."""
149-
150-
mnt = values.get("monitor")
151-
electrons = values.get("electrons")
152-
holes = values.get("holes")
153-
154-
if electrons is None or holes is None:
155-
log.warning(
156-
f"No data is available for monitor '{mnt.name}'. This is typically caused by "
157-
"monitor not intersecting any solid medium."
158-
)
159-
160-
return values
161-
162-
@property
163-
def symmetry_expanded_copy(self) -> SteadyFreeCarrierData:
164-
"""Return copy of self with symmetry applied."""
165-
166-
new_electrons = self._symmetry_expanded_copy(property=self.electrons)
167-
new_holes = self._symmetry_expanded_copy(property=self.holes)
168-
169-
return self.updated_copy(
170-
electrons=new_electrons,
171-
holes=new_holes,
172-
symmetry=(0, 0, 0),
173-
)
174-
175122
def field_name(self, val: str = "") -> str:
176123
"""Gets the name of the fields to be plotted."""
177124
if val == "abs^2":
@@ -259,42 +206,6 @@ def check_correct_data_type(cls, values):
259206

260207
return values
261208

262-
@pd.root_validator(skip_on_failure=True)
263-
def warn_no_data(cls, values):
264-
"""Warn if no data provided."""
265-
266-
mnt = values.get("monitor")
267-
fields = ["Ec", "Ev", "Ei", "Efn", "Efp"]
268-
for field_name in fields:
269-
field_data = values.get(field_name)
270-
271-
if field_data is None:
272-
log.warning(
273-
f"No data is available for monitor '{mnt.name}'. This is typically caused by "
274-
"monitor not intersecting any solid medium."
275-
)
276-
277-
return values
278-
279-
@property
280-
def symmetry_expanded_copy(self) -> SteadyEnergyBandData:
281-
"""Return copy of self with symmetry applied."""
282-
283-
new_Ec = self._symmetry_expanded_copy(property=self.Ec)
284-
new_Ev = self._symmetry_expanded_copy(property=self.Ev)
285-
new_Ei = self._symmetry_expanded_copy(property=self.Ei)
286-
new_Efn = self._symmetry_expanded_copy(property=self.Efn)
287-
new_Efp = self._symmetry_expanded_copy(property=self.Efp)
288-
289-
return self.updated_copy(
290-
Ec=new_Ec,
291-
Ev=new_Ev,
292-
Ei=new_Ei,
293-
Efn=new_Efn,
294-
Efp=new_Efp,
295-
symmetry=(0, 0, 0),
296-
)
297-
298209
def field_name(self, val: str = "") -> str:
299210
"""Gets the name of the fields to be plotted."""
300211
if val == "abs^2":
@@ -418,25 +329,15 @@ class SteadyCapacitanceData(HeatChargeMonitorData):
418329
)
419330
# C_n = electron_capacitance
420331

421-
@pd.validator("hole_capacitance", always=True)
422-
@skip_if_fields_missing(["monitor"])
423-
def warn_no_data(cls, val, values):
424-
"""Warn if no data provided."""
425-
426-
mnt = values.get("monitor")
427-
428-
if val is None:
429-
log.warning(
430-
f"No data is available for monitor '{mnt.name}'. This is typically caused by "
431-
"monitor not intersecting any solid medium."
432-
)
433-
434-
return val
435-
436332
def field_name(self, val: str) -> str:
437333
"""Gets the name of the fields to be plotted."""
438334
return ""
439335

336+
@property
337+
def field_components(self) -> dict[str, UnstructuredFieldType]:
338+
"""Maps the field components to their associated data."""
339+
return {}
340+
440341
@property
441342
def symmetry_expanded_copy(self) -> SteadyCapacitanceData:
442343
"""Return copy of self with symmetry applied."""
@@ -494,21 +395,6 @@ def field_components(self) -> dict[str, UnstructuredFieldType]:
494395
"""Maps the field components to their associated data."""
495396
return {"E": self.E}
496397

497-
@pd.root_validator(skip_on_failure=True)
498-
def warn_no_data(cls, values):
499-
"""Warn if no data provided."""
500-
501-
mnt = values.get("monitor")
502-
E = values.get("E")
503-
504-
if E is None:
505-
log.warning(
506-
f"No data is available for monitor '{mnt.name}'. This is typically caused by "
507-
"monitor not intersecting any solid medium."
508-
)
509-
510-
return values
511-
512398
@pd.root_validator(skip_on_failure=True)
513399
def check_correct_data_type(cls, values):
514400
"""Issue error if incorrect data type is used"""
@@ -526,17 +412,6 @@ def check_correct_data_type(cls, values):
526412

527413
return values
528414

529-
@property
530-
def symmetry_expanded_copy(self) -> SteadyElectricFieldData:
531-
"""Return copy of self with symmetry applied."""
532-
533-
new_E = self._symmetry_expanded_copy(property=self.E)
534-
535-
return self.updated_copy(
536-
E=new_E,
537-
symmetry=(0, 0, 0),
538-
)
539-
540415
def field_name(self, val: str = "") -> str:
541416
"""Gets the name of the fields to be plotted."""
542417
if val == "abs^2":
@@ -569,21 +444,6 @@ def field_components(self) -> dict[str, UnstructuredFieldType]:
569444
"""Maps the field components to their associated data."""
570445
return {"J": self.J}
571446

572-
@pd.root_validator(skip_on_failure=True)
573-
def warn_no_data(cls, values):
574-
"""Warn if no data provided."""
575-
576-
mnt = values.get("monitor")
577-
J = values.get("J")
578-
579-
if J is None:
580-
log.warning(
581-
f"No data is available for monitor '{mnt.name}'. This is typically caused by "
582-
"monitor not intersecting any solid medium."
583-
)
584-
585-
return values
586-
587447
@pd.root_validator(skip_on_failure=True)
588448
def check_correct_data_type(cls, values):
589449
"""Issue error if incorrect data type is used"""
@@ -601,17 +461,6 @@ def check_correct_data_type(cls, values):
601461

602462
return values
603463

604-
@property
605-
def symmetry_expanded_copy(self) -> SteadyCurrentDensityData:
606-
"""Return copy of self with symmetry applied."""
607-
608-
new_J = self._symmetry_expanded_copy(property=self.J)
609-
610-
return self.updated_copy(
611-
J=new_J,
612-
symmetry=(0, 0, 0),
613-
)
614-
615464
def field_name(self, val: str = "") -> str:
616465
"""Gets the name of the fields to be plotted."""
617466
if val == "abs^2":

tidy3d/components/tcad/data/monitor_data/heat.py

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
import pydantic.v1 as pd
88

9-
from tidy3d.components.base import skip_if_fields_missing
109
from tidy3d.components.data.data_array import (
1110
DataArray,
1211
ScalarFieldTimeDataArray,
@@ -19,7 +18,6 @@
1918
)
2019
from tidy3d.components.types import annotate_type
2120
from tidy3d.constants import KELVIN
22-
from tidy3d.log import log
2321

2422
FieldDataset = Union[
2523
SpatialDataArray,
@@ -62,31 +60,9 @@ def field_components(self) -> dict[str, DataArray]:
6260
"""Maps the field components to their associated data."""
6361
return {"temperature": self.temperature}
6462

65-
@pd.validator("temperature", always=True)
66-
@skip_if_fields_missing(["monitor"])
67-
def warn_no_data(cls, val, values):
68-
"""Warn if no data provided."""
69-
70-
mnt = values.get("monitor")
71-
72-
if val is None:
73-
log.warning(
74-
f"No data is available for monitor '{mnt.name}'. This is typically caused by "
75-
"monitor not intersecting any solid medium."
76-
)
77-
78-
return val
79-
8063
def field_name(self, val: str = "") -> str:
8164
"""Gets the name of the fields to be plot."""
8265
if val == "abs^2":
8366
return "|T|², K²"
8467
else:
8568
return "T, K"
86-
87-
@property
88-
def symmetry_expanded_copy(self) -> TemperatureData:
89-
"""Return copy of self with symmetry applied."""
90-
91-
new_temp = self._symmetry_expanded_copy(property=self.temperature)
92-
return self.updated_copy(temperature=new_temp, symmetry=(0, 0, 0))

tidy3d/components/tcad/data/monitor_data/mesh.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,3 @@ def field_components(self) -> dict[str, UnstructuredFieldType]:
6161
def field_name(self, val: str) -> str:
6262
"""Gets the name of the fields to be plot."""
6363
return "Mesh"
64-
65-
@property
66-
def symmetry_expanded_copy(self) -> VolumeMeshData:
67-
"""Return copy of self with symmetry applied."""
68-
69-
new_mesh = self._symmetry_expanded_copy(property=self.mesh)
70-
return self.updated_copy(mesh=new_mesh, symmetry=(0, 0, 0))

0 commit comments

Comments
 (0)