def __init__( self, shape: goos.Shape, region: goos.Box3d, mesh: simspace.MeshModel, wavelength: float, background: goos.material.Material = None, simulation_symmetry: List[int] = None, num_points_per_arclen: float = 0.084, ) -> None: super().__init__(shape) self._edge_coords = simspace.create_edge_coords( region, mesh.dx, simulation_symmetry) if background: bg_eps = goos.material.get_material(background).permittivity( wavelength) else: bg_eps = 0 self._grid = gridlock.Grid(self._edge_coords, ext_dir=gridlock.Direction.z, initial=bg_eps, num_grids=3) self._render_params = RenderParams( wlen=wavelength, pts_per_arclen=num_points_per_arclen)
def __init__( self, eps: goos.Function, sources: List[SimSource], solver: str, wavelength: float, bloch_vector: List[float], simulation_space: simspace.SimulationSpace, outputs: List[SimOutput], ) -> None: # Determine the output flow types. output_flow_types = [ maxwell.SIM_REGISTRY.get(out.type).meta["output_type"] for out in outputs ] output_names = [out.name for out in outputs] super().__init__([eps], flow_names=output_names, flow_types=output_flow_types) # Create an empty grid to have access to `dxes` and `shape`. self._grid = gridlock.Grid(simspace.create_edge_coords( simulation_space.sim_region, simulation_space.mesh.dx, reflection_symmetry=simulation_space.reflection_symmetry), ext_dir=gridlock.Direction.z, initial=0, num_grids=3) self._dxes = [self._grid.dxyz, self._grid.autoshifted_dxyz()] eigen_solvers = ["maxwell_eig", "local_direct_eig"] if solver in eigen_solvers: self._solver = _create_solver(solver, None, self._grid.shape) else: raise ValueError( "Invalid solver, solver for eigensolves need to be in " + str(eigen_solvers) + ".") self._simspace = simulation_space if bloch_vector: self._bloch_vector = bloch_vector else: self._bloch_vector = np.array([0, 0, 0]) self._wlen = wavelength #this will be used for the initial guess self._pml_layers = [ int(length / self._simspace.mesh.dx) for length in self._simspace.pml_thickness ] self._symmetry = simulation_space.reflection_symmetry self._sources = _create_sources(sources) self._outputs = _create_outputs(outputs) # Handle caching of simulation results. self._last_results = None self._last_eps = None
def test_gaussian_source_2d(): grid = gridlock.Grid(simspace.create_edge_coords( goos.Box3d(center=[0, 0, 0], extents=[14000, 40, 3000]), 40), ext_dir=gridlock.Direction.z, initial=1, num_grids=3) grid.render() eps = np.array(grid.grids) dxes = [grid.dxyz, grid.autoshifted_dxyz()] sim = maxwell.FdfdSimProp(eps=eps, source=np.zeros_like(eps), wlen=1550, dxes=dxes, pml_layers=[10, 10, 0, 0, 10, 10], grid=grid, solver=maxwell.DIRECT_SOLVER) src = maxwell.GaussianSourceImpl( maxwell.GaussianSource(w0=5200, center=[0, 0, 0], extents=[14000, 0, 0], normal=[0, 0, -1], power=1, theta=0, psi=0, polarization_angle=np.pi / 2, normalize_by_sim=True)) src.before_sim(sim) fields = maxwell.DIRECT_SOLVER.solve( omega=2 * np.pi / sim.wlen, dxes=sim.dxes, epsilon=fdfd_tools.vec(sim.eps), mu=None, J=fdfd_tools.vec(sim.source), pml_layers=sim.pml_layers, bloch_vec=sim.bloch_vec, ) fields = fdfd_tools.unvec(fields, grid.shape) field_y = fields[1].squeeze() np.testing.assert_allclose(field_y[:, 53], np.zeros_like(field_y[:, 53]), atol=1e-4) # Calculate what the amplitude of the Gaussian field should look like. # Amplitude determined empirically through simulation. coords = (np.arange(len(field_y[:, 20])) - len(field_y[:, 20]) / 2) * 40 target_gaussian = np.exp(-coords**2 / 5200**2) * 0.00278 np.testing.assert_allclose(np.abs(field_y[:, 20]), target_gaussian, atol=1e-4)
def __init__( self, eps: goos.Function, sources: List[SimSource], wavelength: float, simulation_space: simspace.SimulationSpace, outputs: List[SimOutput], solver: str = None, solver_info: Solver = None, ) -> None: # Determine the output flow types. output_flow_types = [ maxwell.SIM_REGISTRY.get(out.type).meta["output_type"] for out in outputs ] output_names = [out.name for out in outputs] super().__init__([eps], flow_names=output_names, flow_types=output_flow_types, heavy_compute=True) # Create an empty grid to have access to `dxes` and `shape`. self._grid = gridlock.Grid(simspace.create_edge_coords( simulation_space.sim_region, simulation_space.mesh.dx, reflection_symmetry=simulation_space.reflection_symmetry), ext_dir=gridlock.Direction.z, initial=0, num_grids=3) self._dxes = [self._grid.dxyz, self._grid.autoshifted_dxyz()] self._solver = _create_solver(solver, solver_info, self._grid.shape) self._simspace = simulation_space self._bloch_vector = [0, 0, 0] self._wlen = wavelength self._pml_layers = [ int(length / self._simspace.mesh.dx) for length in self._simspace.pml_thickness ] self._symmetry = simulation_space.reflection_symmetry self._sources = _create_sources(sources) self._outputs = _create_outputs(outputs) # Handle caching of simulation results. self._last_results = None self._last_eps = None