|
175 | 175 | FIXED_ANGLE_DT_SAFETY_FACTOR = 0.9
|
176 | 176 |
|
177 | 177 |
|
| 178 | +def validate_boundaries_for_zero_dims(): |
| 179 | + """Error if absorbing boundaries, bloch boundaries, unmatching pec/pmc, or symmetry is used along a zero dimension.""" |
| 180 | + |
| 181 | + @pydantic.validator("boundary_spec", allow_reuse=True, always=True) |
| 182 | + @skip_if_fields_missing(["size", "symmetry"]) |
| 183 | + def boundaries_for_zero_dims(cls, val, values): |
| 184 | + """Error if absorbing boundaries, bloch boundaries, unmatching pec/pmc, or symmetry is used along a zero dimension.""" |
| 185 | + boundaries = val.to_list |
| 186 | + size = values.get("size") |
| 187 | + symmetry = values.get("symmetry") |
| 188 | + axis_names = "xyz" |
| 189 | + |
| 190 | + for dim, (boundary, symmetry_dim, size_dim) in enumerate(zip(boundaries, symmetry, size)): |
| 191 | + if size_dim == 0: |
| 192 | + axis = axis_names[dim] |
| 193 | + num_absorbing_bdries = sum(isinstance(bnd, AbsorberSpec) for bnd in boundary) |
| 194 | + num_bloch_bdries = sum(isinstance(bnd, BlochBoundary) for bnd in boundary) |
| 195 | + |
| 196 | + if num_absorbing_bdries > 0: |
| 197 | + raise SetupError( |
| 198 | + f"The simulation has zero size along the {axis} axis, so " |
| 199 | + "using a PML or absorbing boundary along that axis is incorrect. " |
| 200 | + f"Use either 'Periodic' or 'BlochBoundary' along {axis}." |
| 201 | + ) |
| 202 | + |
| 203 | + if num_bloch_bdries > 0: |
| 204 | + raise SetupError( |
| 205 | + f"The simulation has zero size along the {axis} axis, " |
| 206 | + "using a Bloch boundary along such an axis is not supported because of " |
| 207 | + "the Bloch vector definition in units of '2 * pi / (size along dimension)'. Use a small " |
| 208 | + "but nonzero size along the dimension instead." |
| 209 | + ) |
| 210 | + |
| 211 | + if symmetry_dim != 0: |
| 212 | + raise SetupError( |
| 213 | + f"The simulation has zero size along the {axis} axis, so " |
| 214 | + "using symmetry along that axis is incorrect. Use 'PECBoundary' " |
| 215 | + "or 'PMCBoundary' to select source polarization if needed and set " |
| 216 | + f"Simulation.symmetry to 0 along {axis}." |
| 217 | + ) |
| 218 | + |
| 219 | + if boundary[0] != boundary[1]: |
| 220 | + raise SetupError( |
| 221 | + f"The simulation has zero size along the {axis} axis. " |
| 222 | + f"The boundary condition for {axis} plus and {axis} " |
| 223 | + "minus must be the same." |
| 224 | + ) |
| 225 | + |
| 226 | + return val |
| 227 | + |
| 228 | + return boundaries_for_zero_dims |
| 229 | + |
| 230 | + |
178 | 231 | class AbstractYeeGridSimulation(AbstractSimulation, ABC):
|
179 | 232 | """
|
180 | 233 | Abstract class for a simulation involving electromagnetic fields defined on a Yee grid.
|
@@ -2803,53 +2856,6 @@ def check_fixed_angle_components(cls, values):
|
2803 | 2856 |
|
2804 | 2857 | return values
|
2805 | 2858 |
|
2806 |
| - @pydantic.validator("boundary_spec", always=True) |
2807 |
| - @skip_if_fields_missing(["size", "symmetry"]) |
2808 |
| - def boundaries_for_zero_dims(cls, val, values): |
2809 |
| - """Error if absorbing boundaries, bloch boundaries, unmatching pec/pmc, or symmetry is used along a zero dimension.""" |
2810 |
| - boundaries = val.to_list |
2811 |
| - size = values.get("size") |
2812 |
| - symmetry = values.get("symmetry") |
2813 |
| - axis_names = "xyz" |
2814 |
| - |
2815 |
| - for dim, (boundary, symmetry_dim, size_dim) in enumerate(zip(boundaries, symmetry, size)): |
2816 |
| - if size_dim == 0: |
2817 |
| - axis = axis_names[dim] |
2818 |
| - num_absorbing_bdries = sum(isinstance(bnd, AbsorberSpec) for bnd in boundary) |
2819 |
| - num_bloch_bdries = sum(isinstance(bnd, BlochBoundary) for bnd in boundary) |
2820 |
| - |
2821 |
| - if num_absorbing_bdries > 0: |
2822 |
| - raise SetupError( |
2823 |
| - f"The simulation has zero size along the {axis} axis, so " |
2824 |
| - "using a PML or absorbing boundary along that axis is incorrect. " |
2825 |
| - f"Use either 'Periodic' or 'BlochBoundary' along {axis}." |
2826 |
| - ) |
2827 |
| - |
2828 |
| - if num_bloch_bdries > 0: |
2829 |
| - raise SetupError( |
2830 |
| - f"The simulation has zero size along the {axis} axis, " |
2831 |
| - "using a Bloch boundary along such an axis is not supported because of " |
2832 |
| - "the Bloch vector definition in units of '2 * pi / (size along dimension)'. Use a small " |
2833 |
| - "but nonzero size along the dimension instead." |
2834 |
| - ) |
2835 |
| - |
2836 |
| - if symmetry_dim != 0: |
2837 |
| - raise SetupError( |
2838 |
| - f"The simulation has zero size along the {axis} axis, so " |
2839 |
| - "using symmetry along that axis is incorrect. Use 'PECBoundary' " |
2840 |
| - "or 'PMCBoundary' to select source polarization if needed and set " |
2841 |
| - f"Simulation.symmetry to 0 along {axis}." |
2842 |
| - ) |
2843 |
| - |
2844 |
| - if boundary[0] != boundary[1]: |
2845 |
| - raise SetupError( |
2846 |
| - f"The simulation has zero size along the {axis} axis. " |
2847 |
| - f"The boundary condition for {axis} plus and {axis} " |
2848 |
| - "minus must be the same." |
2849 |
| - ) |
2850 |
| - |
2851 |
| - return val |
2852 |
| - |
2853 | 2859 | @pydantic.validator("sources", always=True)
|
2854 | 2860 | def _validate_num_sources(cls, val):
|
2855 | 2861 | """Error if too many sources present."""
|
@@ -5201,3 +5207,5 @@ def from_scene(cls, scene: Scene, **kwargs) -> Simulation:
|
5201 | 5207 | medium=scene.medium,
|
5202 | 5208 | **kwargs,
|
5203 | 5209 | )
|
| 5210 | + |
| 5211 | + _boundaries_for_zero_dims = validate_boundaries_for_zero_dims() |
0 commit comments