Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix bug in plot_boundaries of plot2D #2079

Merged
merged 1 commit into from
May 24, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 95 additions & 70 deletions python/visualization.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,10 @@ def filter_dict(dict_to_filter, func_with_kwargs):

def place_label(ax, label_text, x, y, centerx, centery, label_parameters=None):

label_parameters = default_label_parameters if label_parameters is None else dict(default_label_parameters, **label_parameters)
if label_parameters is None:
label_parameters = default_label_parameters
else:
label_parameters = dict(default_label_parameters, **label_parameters)

offset = label_parameters['offset']
alpha = label_parameters['label_alpha']
Expand Down Expand Up @@ -215,6 +218,17 @@ def get_2D_dimensions(sim, output_plane):
sim_center, sim_size = (intersection_vol.center, intersection_vol.size)
return sim_center, sim_size


def box_vertices(box_center, box_size):
xmin = box_center.x - 0.5*box_size.x
xmax = box_center.x + 0.5*box_size.x
ymin = box_center.y - 0.5*box_size.y
ymax = box_center.y + 0.5*box_size.y
zmin = box_center.z - 0.5*box_size.z
zmax = box_center.z + 0.5*box_size.z

return xmin, xmax, ymin, ymax, zmin, zmax

# ------------------------------------------------------- #
# actual plotting routines

Expand All @@ -224,23 +238,20 @@ def plot_volume(sim, ax, volume, output_plane=None, plotting_parameters=None, la
from meep.simulation import Volume

# Set up the plotting parameters
plotting_parameters = default_volume_parameters if plotting_parameters is None else dict(default_volume_parameters, **plotting_parameters)
if plotting_parameters is None:
plotting_parameters = default_volume_parameters
else:
plotting_parameters = dict(default_volume_parameters, **plotting_parameters)

# Get domain measurements
sim_center, sim_size = get_2D_dimensions(sim, output_plane)

plane = Volume(center=sim_center, size=sim_size)

# Pull volume parameters
size = volume.size
center = volume.center

xmax = center.x + size.x/2
xmin = center.x - size.x/2
ymax = center.y + size.y/2
ymin = center.y - size.y/2
zmax = center.z + size.z/2
zmin = center.z - size.z/2
xmin, xmax, ymin, ymax, zmin, zmax = box_vertices(center, size)

# Add labels if requested
if label is not None and mp.am_master():
Expand Down Expand Up @@ -336,11 +347,15 @@ def sort_points(xy):

def plot_eps(sim, ax, output_plane=None, eps_parameters=None, frequency=None):
# consolidate plotting parameters
eps_parameters = default_eps_parameters if eps_parameters is None else dict(default_eps_parameters, **eps_parameters)
if eps_parameters is None:
eps_parameters = default_eps_parameters
else:
eps_parameters = dict(default_eps_parameters, **eps_parameters)

# Determine a frequency to plot all epsilon
if frequency is not None:
warnings.warn('The frequency parameter of plot2D has been deprecated. Use the frequency key of the eps_parameters dictionary instead.')
warnings.warn("The frequency parameter of plot2D has been deprecated. "
"Use the frequency key of the eps_parameters dictionary instead.")
oskooi marked this conversation as resolved.
Show resolved Hide resolved
eps_parameters['frequency'] = frequency
if eps_parameters['frequency'] is None:
try:
Expand All @@ -361,17 +376,13 @@ def plot_eps(sim, ax, output_plane=None, eps_parameters=None, frequency=None):
# Get domain measurements
sim_center, sim_size = get_2D_dimensions(sim, output_plane)

xmin = sim_center.x - sim_size.x/2
xmax = sim_center.x + sim_size.x/2
ymin = sim_center.y - sim_size.y/2
ymax = sim_center.y + sim_size.y/2
zmin = sim_center.z - sim_size.z/2
zmax = sim_center.z + sim_size.z/2
xmin, xmax, ymin, ymax, zmin, zmax = box_vertices(sim_center, sim_size)

center = Vector3(sim_center.x, sim_center.y, sim_center.z)
cell_size = Vector3(sim_size.x, sim_size.y, sim_size.z)
if eps_parameters['resolution']:
grid_resolution = eps_parameters['resolution']
else:
grid_resolution = sim.resolution

grid_resolution = eps_parameters['resolution'] if eps_parameters['resolution'] else sim.resolution
Nx = int((xmax - xmin) * grid_resolution + 1)
Ny = int((ymax - ymin) * grid_resolution + 1)
Nz = int((zmax - zmin) * grid_resolution + 1)
Expand Down Expand Up @@ -420,51 +431,66 @@ def plot_eps(sim, ax, output_plane=None, eps_parameters=None, frequency=None):

def plot_boundaries(sim, ax, output_plane=None, boundary_parameters=None):
# consolidate plotting parameters
boundary_parameters = default_boundary_parameters if boundary_parameters is None else dict(default_boundary_parameters, **boundary_parameters)
if boundary_parameters is None:
boundary_parameters = default_boundary_parameters
else:
boundary_parameters = dict(default_boundary_parameters, **boundary_parameters)

def get_boundary_volumes(thickness, direction, side, cylindrical=False):
from meep.simulation import Volume

thickness = boundary.thickness

# Get domain measurements
sim_center, sim_size = get_2D_dimensions(sim, output_plane)

xmin = sim_center.x - sim_size.x/2
xmax = sim_center.x + sim_size.x/2
ymin = sim_center.y - sim_size.y/2
ymax = sim_center.y + sim_size.y/2
zmin = sim_center.z - sim_size.z/2
zmax = sim_center.z + sim_size.z/2

cell_x = sim.cell_size.x
cell_y = sim.cell_size.y
cell_z = sim.cell_size.z
xmin, xmax, ymin, ymax, zmin, zmax = box_vertices(sim.geometry_center, sim.cell_size)

if direction == mp.X and side == mp.Low:
return Volume(center=Vector3(xmin+thickness/2,sim_center.y,sim_center.z),
size=Vector3(thickness,cell_y,cell_z))
return Volume(center=Vector3(xmin+0.5*thickness,
sim.geometry_center.y,
sim.geometry_center.z),
size=Vector3(thickness,
sim.cell_size.y,
sim.cell_size.z))
elif direction == mp.X and side == mp.High:
return Volume(center=Vector3(xmax-thickness/2,sim_center.y,sim_center.z),
size=Vector3(thickness,cell_y,cell_z))
return Volume(center=Vector3(xmax-0.5*thickness,
sim.geometry_center.y,
sim.geometry_center.z),
size=Vector3(thickness,
sim.cell_size.y,
sim.cell_size.z))
elif direction == mp.Y and side == mp.Low:
return Volume(center=Vector3(sim_center.x,ymin+thickness/2,sim_center.z),
size=Vector3(cell_x,thickness,cell_z))
return Volume(center=Vector3(sim.geometry_center.x,
ymin+0.5*thickness,
sim.geometry_center.z),
size=Vector3(sim.cell_size.x,
thickness,
sim.cell_size.z))
elif direction == mp.Y and side == mp.High:
return Volume(center=Vector3(sim_center.x,ymax-thickness/2,sim_center.z),
size=Vector3(cell_x,thickness,cell_z))
return Volume(center=Vector3(sim.geometry_center.x,
ymax-0.5*thickness,
sim.geometry_center.z),
size=Vector3(sim.cell_size.x,
thickness,
sim.cell_size.z))
elif direction == mp.Z and side == mp.Low:
return Volume(center=Vector3(sim_center.x,sim_center.y,zmin+thickness/2),
size=Vector3(cell_x,cell_y,thickness))
return Volume(center=Vector3(sim.geometry_center.x,
sim.geometry_center.y,
zmin+0.5*thickness),
size=Vector3(sim.cell_size.x,
sim.cell_size.y,
thickness))
elif direction == mp.Z and side == mp.High:
return Volume(center=Vector3(sim_center.x,sim_center.y,zmax-thickness/2),
size=Vector3(cell_x,cell_y,thickness))
return Volume(center=Vector3(sim.geometry_center.x,
sim.geometry_center.y,
zmax-0.5*thickness),
size=Vector3(sim.cell_size.x,
sim.cell_size.y,
thickness))
else:
raise ValueError("Invalid boundary type")

import itertools
for boundary in sim.boundary_layers:
# All four sides are the same
# boundary on all four sides
if boundary.direction == mp.ALL and boundary.side == mp.ALL:
if sim.dimensions == 1:
dims = [mp.X]
Expand All @@ -481,15 +507,15 @@ def get_boundary_volumes(thickness, direction, side, cylindrical=False):
continue
vol = get_boundary_volumes(boundary.thickness,*permutation)
ax = plot_volume(sim,ax,vol,output_plane,plotting_parameters=boundary_parameters)
# two sides are the same
# boundary on only two of four sides
elif boundary.side == mp.ALL:
for side in [mp.Low, mp.High]:
if ((boundary.direction == mp.X) and (side == mp.Low)) and (sim.dimensions == mp.CYLINDRICAL or sim.is_cylindrical):
continue
vol = get_boundary_volumes(boundary.thickness,boundary.direction,side)
ax = plot_volume(sim,ax,vol,output_plane,plotting_parameters=boundary_parameters)
# only one side
else:
# boundary on just one side
else:
if ((boundary.direction == mp.X) and (boundary.side == mp.Low)) and (sim.dimensions == mp.CYLINDRICAL or sim.is_cylindrical):
continue
vol = get_boundary_volumes(boundary.thickness,boundary.direction,boundary.side)
Expand All @@ -500,7 +526,10 @@ def plot_sources(sim, ax, output_plane=None, labels=False, source_parameters=Non
from meep.simulation import Volume

# consolidate plotting parameters
source_parameters = default_source_parameters if source_parameters is None else dict(default_source_parameters, **source_parameters)
if source_parameters is None:
source_parameters = default_source_parameters
else:
source_parameters = dict(default_source_parameters, **source_parameters)

label = 'source' if labels else None

Expand All @@ -513,7 +542,10 @@ def plot_monitors(sim, ax, output_plane=None, labels=False, monitor_parameters=N
from meep.simulation import Volume

# consolidate plotting parameters
monitor_parameters = default_monitor_parameters if monitor_parameters is None else dict(default_monitor_parameters, **monitor_parameters)
if monitor_parameters is None:
monitor_parameters = default_monitor_parameters
else:
monitor_parametesr = dict(default_monitor_parameters, **monitor_parameters)

label = 'monitor' if labels else None

Expand All @@ -530,22 +562,17 @@ def plot_fields(sim, ax=None, fields=None, output_plane=None, field_parameters=N
if fields is None:
return ax

field_parameters = default_field_parameters if field_parameters is None else dict(default_field_parameters, **field_parameters)
if field_parameters is None:
field_parameters = default_field_parameters
else:
field_parameters = dict(default_field_parameters, **field_parameters)

# user specifies a field component
if fields in [mp.Ex, mp.Ey, mp.Ez, mp.Er, mp.Ep, mp.Dx, mp.Dy, mp.Dz, mp.Hx, mp.Hy, mp.Hz]:
# Get domain measurements
sim_center, sim_size = get_2D_dimensions(sim, output_plane)

xmin = sim_center.x - sim_size.x/2
xmax = sim_center.x + sim_size.x/2
ymin = sim_center.y - sim_size.y/2
ymax = sim_center.y + sim_size.y/2
zmin = sim_center.z - sim_size.z/2
zmax = sim_center.z + sim_size.z/2

center = Vector3(sim_center.x, sim_center.y, sim_center.z)
cell_size = Vector3(sim_size.x, sim_size.y, sim_size.z)
xmin, xmax, ymin, ymax, zmin, zmax = box_vertices(sim_center, sim_size)

if sim_size.x == 0:
# Plot y on x axis, z on y axis (YZ plane)
Expand All @@ -565,13 +592,16 @@ def plot_fields(sim, ax=None, fields=None, output_plane=None, field_parameters=N
extent = [xmin, xmax, ymin, ymax]
xlabel = 'X'
ylabel = 'Y'
fields = sim.get_array(center=center, size=cell_size, component=fields)
fields = sim.get_array(center=sim_center, size=sim_size, component=fields)
else:
raise ValueError('Please specify a valid field component (mp.Ex, mp.Ey, ...')


fields = field_parameters['post_process'](fields)
fields = np.flipud(fields) if ((sim.dimensions == mp.CYLINDRICAL) or sim.is_cylindrical) else np.rot90(fields)
if (sim.dimensions == mp.CYLINDRICAL) or sim.is_cylindrical:
fields = np.flipud(fields)
else:
fields = np.rot90(fields)

# Either plot the field, or return the array
if ax:
Expand Down Expand Up @@ -632,12 +662,7 @@ def plot3D(sim):
if sim.dimensions < 3:
raise ValueError("Simulation must have 3 dimensions to visualize 3D")

xmin = sim.geometry_center.x - 0.5*sim.cell_size.x
xmax = sim.geometry_center.x + 0.5*sim.cell_size.x
ymin = sim.geometry_center.y - 0.5*sim.cell_size.y
ymax = sim.geometry_center.y + 0.5*sim.cell_size.y
zmin = sim.geometry_center.z - 0.5*sim.cell_size.z
zmax = sim.geometry_center.z + 0.5*sim.cell_size.z
xmin, xmax, ymin, ymax, zmin, zmax = box_vertices(sim.geometry_center, sim.cell_size)

Nx = int(sim.cell_size.x * sim.resolution) + 1
Ny = int(sim.cell_size.y * sim.resolution) + 1
Expand Down