flexcompute / tidy3d

Fast electromagnetic solver (FDTD) at scale.
https://docs.flexcompute.com/projects/tidy3d/en/latest/
GNU Lesser General Public License v2.1
189 stars 44 forks source link

Validation error does not get properly propagated #1981

Closed momchil-flex closed 1 month ago

momchil-flex commented 1 month ago

If you take the optimizer json defined below and try to load it as an AdamOptimizer, you get an abstruse error:

AttributeError: 'NoneType' object has no attribute 'pixel_size'

If you instead only try to load the TopologyDesignRegion part of the json, you get the real error:

ValidationError: 1 validation error for TopologyDesignRegion
transformations -> 0 -> radius
  field required (type=value_error.missing)

In many cases, pydantic manages this well and gives you the underlying error first, but here it's completely missing from the stack trace. Not sure if it has something to do with the fact that it happens in a root validator?

{
    "type": "AdamOptimizer",
    "design": {
        "type": "InverseDesign",
        "task_name": "InverseDesignTask",
        "simulation": {
            "attrs": {},
            "type": "Simulation",
            "center": [
                0,
                0,
                0
            ],
            "size": [
                1,
                1,
                1
            ],
            "medium": {
                "attrs": {},
                "name": "Vacuum",
                "frequency_range": null,
                "allow_gain": false,
                "nonlinear_spec": null,
                "modulation_spec": null,
                "heat_spec": null,
                "type": "Medium",
                "permittivity": 1,
                "conductivity": 0
            },
            "structures": [],
            "symmetry": [
                0,
                0,
                0
            ],
            "sources": [
                {
                    "attrs": {},
                    "name": "pointdipole_0",
                    "type": "PointDipole",
                    "center": [
                        0,
                        0,
                        0
                    ],
                    "size": [
                        0,
                        0,
                        0
                    ],
                    "source_time": {
                        "attrs": {},
                        "amplitude": 1,
                        "phase": 0,
                        "type": "GaussianPulse",
                        "freq0": 193414489032258.06,
                        "fwidth": 19341448903225.805,
                        "offset": 5,
                        "remove_dc_component": true
                    },
                    "interpolate": true,
                    "confine_to_bounds": false,
                    "polarization": "Ey"
                }
            ],
            "boundary_spec": {
                "attrs": {},
                "x": {
                    "attrs": {},
                    "plus": {
                        "attrs": {},
                        "name": null,
                        "type": "PML",
                        "num_layers": 12,
                        "parameters": {
                            "attrs": {},
                            "sigma_order": 3,
                            "sigma_min": 0,
                            "sigma_max": 1.5,
                            "type": "PMLParams",
                            "kappa_order": 3,
                            "kappa_min": 1,
                            "kappa_max": 3,
                            "alpha_order": 1,
                            "alpha_min": 0,
                            "alpha_max": 0
                        }
                    },
                    "minus": {
                        "attrs": {},
                        "name": null,
                        "type": "PML",
                        "num_layers": 12,
                        "parameters": {
                            "attrs": {},
                            "sigma_order": 3,
                            "sigma_min": 0,
                            "sigma_max": 1.5,
                            "type": "PMLParams",
                            "kappa_order": 3,
                            "kappa_min": 1,
                            "kappa_max": 3,
                            "alpha_order": 1,
                            "alpha_min": 0,
                            "alpha_max": 0
                        }
                    },
                    "type": "Boundary"
                },
                "y": {
                    "attrs": {},
                    "plus": {
                        "attrs": {},
                        "name": null,
                        "type": "PML",
                        "num_layers": 12,
                        "parameters": {
                            "attrs": {},
                            "sigma_order": 3,
                            "sigma_min": 0,
                            "sigma_max": 1.5,
                            "type": "PMLParams",
                            "kappa_order": 3,
                            "kappa_min": 1,
                            "kappa_max": 3,
                            "alpha_order": 1,
                            "alpha_min": 0,
                            "alpha_max": 0
                        }
                    },
                    "minus": {
                        "attrs": {},
                        "name": null,
                        "type": "PML",
                        "num_layers": 12,
                        "parameters": {
                            "attrs": {},
                            "sigma_order": 3,
                            "sigma_min": 0,
                            "sigma_max": 1.5,
                            "type": "PMLParams",
                            "kappa_order": 3,
                            "kappa_min": 1,
                            "kappa_max": 3,
                            "alpha_order": 1,
                            "alpha_min": 0,
                            "alpha_max": 0
                        }
                    },
                    "type": "Boundary"
                },
                "z": {
                    "attrs": {},
                    "plus": {
                        "attrs": {},
                        "name": null,
                        "type": "PML",
                        "num_layers": 12,
                        "parameters": {
                            "attrs": {},
                            "sigma_order": 3,
                            "sigma_min": 0,
                            "sigma_max": 1.5,
                            "type": "PMLParams",
                            "kappa_order": 3,
                            "kappa_min": 1,
                            "kappa_max": 3,
                            "alpha_order": 1,
                            "alpha_min": 0,
                            "alpha_max": 0
                        }
                    },
                    "minus": {
                        "attrs": {},
                        "name": null,
                        "type": "PML",
                        "num_layers": 12,
                        "parameters": {
                            "attrs": {},
                            "sigma_order": 3,
                            "sigma_min": 0,
                            "sigma_max": 1.5,
                            "type": "PMLParams",
                            "kappa_order": 3,
                            "kappa_min": 1,
                            "kappa_max": 3,
                            "alpha_order": 1,
                            "alpha_min": 0,
                            "alpha_max": 0
                        }
                    },
                    "type": "Boundary"
                },
                "type": "BoundarySpec"
            },
            "monitors": [],
            "grid_spec": {
                "attrs": {},
                "grid_x": {
                    "attrs": {},
                    "type": "AutoGrid",
                    "min_steps_per_wvl": 10,
                    "max_scale": 1.4,
                    "dl_min": 0,
                    "mesher": {
                        "attrs": {},
                        "type": "GradedMesher"
                    }
                },
                "grid_y": {
                    "attrs": {},
                    "type": "AutoGrid",
                    "min_steps_per_wvl": 10,
                    "max_scale": 1.4,
                    "dl_min": 0,
                    "mesher": {
                        "attrs": {},
                        "type": "GradedMesher"
                    }
                },
                "grid_z": {
                    "attrs": {},
                    "type": "AutoGrid",
                    "min_steps_per_wvl": 10,
                    "max_scale": 1.4,
                    "dl_min": 0,
                    "mesher": {
                        "attrs": {},
                        "type": "GradedMesher"
                    }
                },
                "wavelength": 1.55,
                "override_structures": [],
                "snapping_points": [],
                "type": "GridSpec"
            },
            "version": "2.7.3",
            "lumped_elements": [],
            "subpixel": {
                "attrs": {},
                "dielectric": {
                    "attrs": {},
                    "type": "PolarizedAveraging"
                },
                "metal": {
                    "attrs": {},
                    "type": "Staircasing"
                },
                "pec": {
                    "attrs": {},
                    "type": "PECConformal",
                    "timestep_reduction": 0.3
                },
                "type": "SubpixelSpec"
            },
            "simulation_type": null,
            "courant": 0.99,
            "normalize_index": 0,
            "shutoff": 1e-05,
            "run_time": 1e-12
        },
        "design_region": {
            "type": "TopologyDesignRegion",
            "center": [
                0,
                0,
                0
            ],
            "size": [
                12,
                4,
                0.22
            ],
            "eps_bounds": [
                1,
                5
            ],
            "pixel_size": 0.025,
            "transformations": [
                {
                    "strict_binarize": false,
                    "beta": 10,
                    "eta": 0.5
                }
            ],
            "penalties": [
                {
                    "delta_eta": 0.01,
                    "weight": 0.8,
                    "length_scale": 0.1,
                    "beta": 1,
                    "eta0": 0.5
                }
            ],
            "initialization_spec": {
                "type": "UniformInitializationSpec",
                "value": 0.5
            }
        },
        "metric": {
            "attrs": {},
            "type": "Add",
            "left": {
                "attrs": {},
                "type": "ModePower",
                "name": null,
                "monitor_name": "monitor_s31",
                "freqs": [
                    193414493734202.56
                ],
                "direction": "+",
                "mode_index": 0
            },
            "right": {
                "attrs": {},
                "type": "ModePower",
                "name": null,
                "monitor_name": "monitor_s41",
                "freqs": [
                    193414493734202.56
                ],
                "direction": "+",
                "mode_index": 1
            }
        },
        "output_monitor_names": [
            "monitor_s31",
            "monitor_s41"
        ]
    },
    "learning_rate": 0.01,
    "maximize": true,
    "num_steps": 10,
    "store_full_results": true,
    "beta1": 0.9,
    "beta2": 0.999,
    "eps": 1e-08
}