def __init__(self, **kwargs): #if a keyword argument 'simul_params' is provided, then expand it into a list of keyword arguments and join it with the current keyword arguments if 'simul_params' in kwargs: p = kwargs['simul_params'] if "component" in p: p["structure"] = p["component"] del p["component"] from pysimul.log import PYSIMUL_LOG as LOG LOG.deprecation_warning( "Please switch the name of simulation parameter 'component' to 'structure'.", 3) if (not isinstance(p, dict)): raise PythonSimulateException( "Keyword argument 'simul_params' must be of type 'dict'. Current type is : '%'" % type(p)) props = self.__unlocked_properties__() for name, val in p.items(): if isinstance(val, SimulationParameterContainer): self.__set_properties__(val, p) elif isinstance(val, list): for v in val: if isinstance(v, SimulationParameterContainer): self.__set_properties__(v, p) if name in props: kwargs[name] = val del kwargs['simul_params'] super(SimulationParameterContainer, self).__init__(**kwargs)
def get_window_south_west(self): if (not self.has_window_defined()): return self.size_info().south_west else: LOG.debug("Simulation window size : %f x %f" % (self.window_width, self.window_height)) sw = self.window_size_info.south_west return sw
def define_geometry(self): LOG.debug("Running virtual fabrication 3d on structure %s...") from ipkiss.plugins.vfabrication.vfabrication import virtual_fabrication_3d vf = virtual_fabrication_3d( structure=self.structure, include_growth=self.include_growth, environment=self.environment, grid=1.0 / (float(self.resolution_factor) * float(self.resolution)), process_flow=self.vfabrication_process_flow, material_stack_factory=self.material_stack_factory) geometry = vf.geometry LOG.debug("Virtual fabrication ready.") return geometry
def get_material_dataset_for_subset(self, corner, width, height, angle=0): angle = angle % 360.0 H = do_hash("%s-%f-%f-%f" % (str(corner), width, height, angle)) #cache already requested datasets in a dictionary attribute total_resolution = self.get_total_resolution() if not (H in self.material_dataset_dict): corner = Coord2(corner[0], corner[1]) w_range = numpy.arange(0, numpy.ceil(width * total_resolution)) h_range = numpy.arange(0, numpy.ceil(height * total_resolution)) LOG.debug( "Creating the material matrix with resolution of %i : %i x %i elements." % (total_resolution, len(w_range), len(h_range))) mat = numpy.zeros([len(w_range), len(h_range)], Material) if (angle != 0): for w in w_range: delta_w = float(w) / total_resolution current_corner = corner.move_polar_copy(delta_w, angle) for h in h_range: delta_h = float(h) / total_resolution point = current_corner.move_polar_copy( delta_h, angle + 90) mat[w, h] = self.geometry.get_material(point) self.material_dataset_dict[H] = mat else: #faster implementation for the special case where angle == 0 ref_point = corner - self.geometry.size_info.south_west delta_x = int(ref_point[0] * float(total_resolution)) delta_y = int(ref_point[1] * float(total_resolution)) x_min = max(0, min(w_range) + delta_x) y_min = max(0, min(h_range) + delta_y) x_max = max(w_range) + delta_x y_max = max(h_range) + delta_y full_material_array = self.geometry.get_material_array() mat = full_material_array[x_min:x_max + 1, y_min:y_max + 1] self.material_dataset_dict[H] = mat return self.material_dataset_dict[H]
def __init__(self, simul_params): if "component" in simul_params: #FIXME -- THIS MAY BE REMOVED IN A LATER PHASE... simul_params["structure"] = simul_params["component"] del simul_params["component"] LOG.deprecation_warning( "Please switch the name of simulation parameter 'component' to 'structure'.", -1) struct = simul_params["structure"] simul_params["simulation_id"] = struct.name.replace("<", "").replace( ">", "") if "vfabrication_process_flow" not in simul_params: simul_params[ "vfabrication_process_flow"] = TECH.VFABRICATION.PROCESS_FLOW if "material_stack_factory" not in simul_params: simul_params["material_stack_factory"] = TECH.MATERIAL_STACKS dim = self.__get_simulation_dimension__(simul_params) if dim == 2: if ("engine" in simul_params): # FIXME: ENgine should check its parameters itself. # Possible solution: add parameter check to StrongPropertyInitializer # to check parameter requirements without need for instantiation. try: from pysimul.runtime.camfr_engine.camfr_engine import CamfrEngine except ImportError: pass try: from pysimul.runtime.MeepFDTD.MeepFDTD import MeepSimulationEngine except ImportError: pass if 'CamfrEngine' in sys.modules and isinstance( simul_params["engine"], CamfrEngine): if ("resolution_factor" not in simul_params) or ( simul_params["resolution_factor"] != 1): simul_params["resolution_factor"] = 1 LOG.warning( "Parameter 'resolution_factor' forced to 1 for CAMFR engine." ) elif 'MeepSimulationEngine' in sys.modules and isinstance( simul_params["engine"], MeepSimulationEngine): if ("resolution_factor" not in simul_params): simul_params["resolution_factor"] = 2 LOG.warning( "Parameter 'resolution_factor' was missing and thus set to 2 for MEEP engine." ) SimulationDefinition.__init__(self, simul_params=simul_params)
def visualize(self, aspect_ratio_equal=True): LOG.debug("Preparing the 2D visualization...") from dependencies.matplotlib_wrapper import Figure from dependencies.shapely_wrapper import PolygonPatch geom = self.simulation_volume.geometry si = geom.size_info fig = Figure() ax = fig.add_axes([0.05, 0.05, 0.85, 0.85], projection='rectilinear') LOG.debug("Painting the polygons per material stack type...") total = len(geom.material_stacks_shapely_polygons) count = 0.0 from dependencies.shapely_wrapper import Polygon, PolygonPatch references_for_legend = dict() for (material_stack_id, mb) in geom.material_stacks_shapely_polygons: color = geom.material_stack_factory[ material_stack_id].display_style.color.html_string() if (not (mb is None)) and (not mb.georep.is_empty): for polygon in mb.georep_list: if isinstance(polygon, Polygon): patch = PolygonPatch(polygon, fc=color) patch.set_linewidth(1) ax.add_patch(patch) references_for_legend[material_stack_id] = ( patch, geom.material_stack_factory[material_stack_id].name ) else: LOG.error( "An element of type %s will not be plotted." % type(polygon)) count = count + 1.0 percent_complete = int(count / total * 100.0) if aspect_ratio_equal: ax.set_aspect('equal') ##legend from dependencies.matplotlib_wrapper import font_manager prop = font_manager.FontProperties(size=10) patches_for_legend = [ref[0] for ref in references_for_legend.values()] labels_for_legend = [ref[1] for ref in references_for_legend.values()] ax.legend(patches_for_legend, labels_for_legend, loc=(0.5, 0.9), prop=prop) ax.autoscale_view() return fig
def set_camfr_settings(self, camfr_technology): camfr_technology.overwrite_allowed = ["WAVELENGTH"] self.camfr_technology = camfr_technology if (type(self.camfr_technology.WAVELENGTH) == int): raise Exception( "Invalid type for camfr_technology.WAVELENGTH : expected float, not int. " ) if (self.camfr_technology.WAVELENGTH > 1.7) or (self.camfr_technology.WAVELENGTH < 1.0): raise Exception( "Invalid range for camfr_technology.WAVELENGTH : expected a float value between 1.0 (1000 nm) and 1.7 (1.7000nm). " ) camfr.set_lambda(self.camfr_technology.WAVELENGTH) LOG.debug("Camfr wavelength : %f micron" % self.camfr_technology.WAVELENGTH) camfr.set_N(self.camfr_technology.NMODES) LOG.debug("Camfr number of modes : %i" % self.camfr_technology.NMODES) camfr.set_polarisation(self.camfr_technology.POLARIZATION) LOG.debug("Camfr polarization : %s" % str(self.camfr_technology.POLARIZATION)) camfr.set_lower_PML(self.camfr_technology.PML) camfr.set_upper_PML(self.camfr_technology.PML) LOG.debug("Camfr PML : %f" % self.camfr_technology.PML)
def __init__(self, **kwargs): super(StructureSimulationVolume2D, self).__init__(**kwargs) LOG.debug("Size of simulation volume : %f x %f" % (self.width, self.height))
def field_for_geometry( self, geometry, field_extraction_geometry_x_positions=[], field_extraction_grid=0.01, max_slabs=None, geometry_figure_filename="geometry_for_camfr_field_calculation_%s.png", mode_profile_figure_filename="mode_profile_%s.png", geometry_name=None, validation_criterium=__criterium_always_ok__, ref_filename=None, delta_wavelength_faulty_result=0.000001, inc_field=None): LOG.debug("Now starting camfr_engine::field_for_geometry...") mode_profile_figure_filename = mode_profile_figure_filename % geometry_name if len(field_extraction_geometry_x_positions) == 0: raise PythonSimulateException( "Please specify the x positions at which to extract the field profiles. Parameter 'field_extraction_geometry_x_positions' is empty list." ) maximum_faulty_iterations = 5 validation = False iterations_counter = 0 while (not validation) and (iterations_counter < maximum_faulty_iterations): camfr_stack_expr = self.get_camfr_stack_expr_for_geometry( geometry=geometry, max_slabs=max_slabs, geometry_figure_filename=geometry_figure_filename, geometry_name=geometry_name) camfr_stack = camfr.Stack(camfr_stack_expr) LOG.debug("Camfr stack dimensions : (%f,%f)" % (camfr_stack.length(), camfr_stack.width())) #set the incident field and calculate if inc_field is None: self.set_inc_field(camfr_stack) else: self.set_mode_profile_field(camfr_stack, inc_field, si.south) LOG.debug("Initiating the camfr calculation...") camfr_stack.calc() #LOG.debug("Initiating the camfr plot...") #camfr_stack.plot() - doesn't work with Python 2.6 yet beta = camfr_stack.inc().mode(0).kz() si = geometry.size_info camfr_z_positions = [ p - si.west for p in field_extraction_geometry_x_positions ] field_profiles = [] for z_position in camfr_z_positions: LOG.debug( "Now getting the field profile for Camfr z-position %f (geometry position %f)..." % (z_position, z_position + si.west)) # get the field profile f = [] invalid_probing = True geometry_y_positions = numpy.arange(si.south, si.north, field_extraction_grid) camfr_x_positions = geometry_y_positions - si.south for camfr_x in camfr_x_positions: coord = camfr.Coord(camfr_x, 0.0, z_position) cf = camfr_stack.field(coord) f += [ ElectroMagneticField(value=[ ElectricField(value=(cf.Ez(), cf.E1(), cf.E2())), MagneticField(value=(cf.Hz(), cf.H1(), cf.H2())) ]) ] geometry_x_position = z_position + si.west fp = ElectroMagneticFieldProfile2D(positions=[ Coord2(geometry_x_position, camfr_x + si.south) for camfr_x in camfr_x_positions ], fields=f) field_profiles.append(fp) transmission = camfr_stack.T21(0, 0) if self.save_images: #ensure that output directories exist csv_output_dir = "pysimul_camfr_output/csv/" if not os.path.exists(csv_output_dir): os.makedirs(csv_output_dir) img_output_dir = "pysimul_camfr_output/images/" if not os.path.exists(img_output_dir): os.makedirs(img_output_dir) #from dependencies.matplotlib_wrapper import pyplot #save field to file (image and csv) #Hz #save to image #pyplot.clf() #field_for_plot_real = [f.H.value.z.real for f in fp.fields] #Hz | Ey -> f.E.value.y #field_for_plot_imag = [f.H.value.z.imag for f in fp.fields] #field_for_plot_abs = list(abs(numpy.array(field_for_plot_real) + (1j)*numpy.array(field_for_plot_imag))) #pyplot.plot(geometry_y_positions,field_for_plot_abs ,'g') #pyplot.plot(geometry_y_positions,field_for_plot_real,'b') #pyplot.plot(geometry_y_positions,field_for_plot_imag,'r') image_file = "%sHz_%f_W%f_%s" % ( img_output_dir, geometry_x_position, self.camfr_technology.WAVELENGTH, mode_profile_figure_filename) #pyplot.savefig(image_file) #save values to csv csv_file = image_file.replace('images', 'csv') csv_file = csv_file.replace('png', 'csv') csv_file_handle = open(csv_file, 'w') data_for_csv = [[ p, f.H.value.z.real ] for p, f in zip(geometry_y_positions, fp.fields)] numpy.savetxt(csv_file_handle, numpy.array(data_for_csv), delimiter=', ') csv_file_handle.close() #Hy #save to image #pyplot.clf() #field_for_plot_real = [f.H.value.y.real for f in fp.fields] #Hz | Ey -> f.E.value.y #field_for_plot_imag = [f.H.value.y.imag for f in fp.fields] #field_for_plot_abs = list(abs(numpy.array(field_for_plot_real) + (1j)*numpy.array(field_for_plot_imag))) #pyplot.plot(geometry_y_positions,field_for_plot_abs ,'g') #pyplot.plot(geometry_y_positions,field_for_plot_real,'b') #pyplot.plot(geometry_y_positions,field_for_plot_imag,'r') image_file = "%sHy_%f_W%f_%s" % ( img_output_dir, geometry_x_position, self.camfr_technology.WAVELENGTH, mode_profile_figure_filename) #pyplot.savefig(image_file) #save values to csv csv_file = image_file.replace('images', 'csv') csv_file = csv_file.replace('png', 'csv') csv_file_handle = open(csv_file, 'w') data_for_csv = [[ p, f.H.value.y.real ] for p, f in zip(geometry_y_positions, fp.fields)] numpy.savetxt(csv_file_handle, numpy.array(data_for_csv), delimiter=', ') csv_file_handle.close() #Hx #save to image #pyplot.clf() #field_for_plot_real = [f.H.value.x.real for f in fp.fields] #Hz | Ey -> f.E.value.y #field_for_plot_imag = [f.H.value.x.imag for f in fp.fields] #field_for_plot_abs = list(abs(numpy.array(field_for_plot_real) + (1j)*numpy.array(field_for_plot_imag))) #pyplot.plot(geometry_y_positions,field_for_plot_abs ,'g') #pyplot.plot(geometry_y_positions,field_for_plot_real,'b') #pyplot.plot(geometry_y_positions,field_for_plot_imag,'r') image_file = "%sHx_%f_W%f_%s" % ( img_output_dir, geometry_x_position, self.camfr_technology.WAVELENGTH, mode_profile_figure_filename) #pyplot.savefig(image_file) #save values to csv csv_file = image_file.replace('images', 'csv') csv_file = csv_file.replace('png', 'csv') csv_file_handle = open(csv_file, 'w') data_for_csv = [[ p, f.H.value.x.real ] for p, f in zip(geometry_y_positions, fp.fields)] numpy.savetxt(csv_file_handle, numpy.array(data_for_csv), delimiter=', ') csv_file_handle.close() #Ez #save to image #pyplot.clf() #field_for_plot_real = [f.E.value.z.real for f in fp.fields] #field_for_plot_imag = [f.E.value.z.imag for f in fp.fields] #field_for_plot_abs = list(abs(numpy.array(field_for_plot_real) + (1j)*numpy.array(field_for_plot_imag))) #pyplot.plot(geometry_y_positions,field_for_plot_abs ,'g') #pyplot.plot(geometry_y_positions,field_for_plot_real,'b') #pyplot.plot(geometry_y_positions,field_for_plot_imag,'r') image_file = "%sEz_%f_W%f_%s" % ( img_output_dir, geometry_x_position, self.camfr_technology.WAVELENGTH, mode_profile_figure_filename) #pyplot.savefig(image_file) ##save values to csv csv_file = image_file.replace('images', 'csv') csv_file = csv_file.replace('png', 'csv') csv_file_handle = open(csv_file, 'w') data_for_csv = [[ p, f.E.value.z.real ] for p, f in zip(geometry_y_positions, fp.fields)] numpy.savetxt(csv_file_handle, numpy.array(data_for_csv), delimiter=', ') csv_file_handle.close() #Ey #save to image #pyplot.clf() #field_for_plot_real = [f.E.value.y.real for f in fp.fields] #field_for_plot_imag = [f.E.value.y.imag for f in fp.fields] #field_for_plot_abs = list(abs(numpy.array(field_for_plot_real) + (1j)*numpy.array(field_for_plot_imag))) #pyplot.plot(geometry_y_positions,field_for_plot_abs ,'g') #pyplot.plot(geometry_y_positions,field_for_plot_real,'b') #pyplot.plot(geometry_y_positions,field_for_plot_imag,'r') image_file = "%sEy_%f_W%f_%s" % ( img_output_dir, geometry_x_position, self.camfr_technology.WAVELENGTH, mode_profile_figure_filename) #pyplot.savefig(image_file) ##save values to csv csv_file = image_file.replace('images', 'csv') csv_file = csv_file.replace('png', 'csv') csv_file_handle = open(csv_file, 'w') data_for_csv = [[ p, f.E.value.y.real ] for p, f in zip(geometry_y_positions, fp.fields)] numpy.savetxt(csv_file_handle, numpy.array(data_for_csv), delimiter=', ') csv_file_handle.close() #Ex #save to image #pyplot.clf() #field_for_plot_real = [f.E.value.x.real for f in fp.fields] #field_for_plot_imag = [f.E.value.x.imag for f in fp.fields] #field_for_plot_abs = list(abs(numpy.array(field_for_plot_real) + (1j)*numpy.array(field_for_plot_imag))) #pyplot.plot(geometry_y_positions,field_for_plot_abs ,'g') #pyplot.plot(geometry_y_positions,field_for_plot_real,'b') #pyplot.plot(geometry_y_positions,field_for_plot_imag,'r') image_file = "%sEx_%f_W%f_%s" % ( img_output_dir, geometry_x_position, self.camfr_technology.WAVELENGTH, mode_profile_figure_filename) #pyplot.savefig(image_file) ##save values to csv csv_file = image_file.replace('images', 'csv') csv_file = csv_file.replace('png', 'csv') csv_file_handle = open(csv_file, 'w') data_for_csv = [[ p, f.E.value.x.real ] for p, f in zip(geometry_y_positions, fp.fields)] numpy.savetxt(csv_file_handle, numpy.array(data_for_csv), delimiter=', ') csv_file_handle.close() iterations_counter = iterations_counter + 1 validation = validation_criterium(ref_filename, field_profiles) if (not validation): self.camfr_technology.WAVELENGTH = self.camfr_technology.WAVELENGTH + delta_wavelength_faulty_result LOG.warning( "WARNING FROM CAMFR_ENGINE : little bit shift of wavelength due to wrong result. New wavelength = %f" % self.camfr_technology.WAVELENGTH) self.set_camfr_settings(self.camfr_technology) camfr.free_tmps() if (iterations_counter >= maximum_faulty_iterations): LOG.warning( "ERROR FROM CAMFR_ENGINE : no result could be obtained that is accepted by the validation criterium ! Is your criterium correct ??" ) return (field_profiles, beta, transmission)
def get_camfr_stack_expr_for_geometry( self, geometry, max_slabs=None, geometry_figure_filename="geometry_for_camfr_field_calculation_%s.png", geometry_name=None): LOG.debug("Now starting camfr_engine::field_for_geometry...") geometry_figure_filename = geometry_figure_filename % geometry_name from pysics.materials.electromagnetics import get_epsilon_for_material_id #retrieve the material matrix for the geometry mat = geometry.get_material_array() #convert into matrix with epsilon valie from pysics.materials.electromagnetics import transform_material_stack_matrix_in_effective_index_epsilon_matrix eps = transform_material_stack_matrix_in_effective_index_epsilon_matrix( mat, geometry.material_stack_factory) #create auxiliary arrays for plotting grid_step = 1.0 / float(geometry.resolution) si = geometry.size_info len_x = eps.shape[0] len_y = eps.shape[1] X = numpy.linspace(si.west, si.east, num=len_x) Y = numpy.linspace(si.south, si.north, num=len_y) if self.save_images: #plot from pysics.materials.all import * #from dependencies.matplotlib_wrapper import pyplot #pyplot.clf() #pyplot.contourf(X, Y, eps.transpose(), antialiased = True) #transpose: for some reason, contourf uses flipped x en y axes.... the other matplotlib functions work on regular x/y axes... #pyplot.colorbar(orientation='vertical', format = '%i', shrink = 0.5) #pyplot.axis('equal') #pyplot.savefig(geometry_figure_filename, dpi=300) #create a working array 'deltas' with the same dimensions as eps : the first column should contain ones, #the other columns will indicate if there is a difference between that columns in "eps" and the next column deltas = numpy.ones_like(eps) d = numpy.diff(eps, axis=0) for d_counter in xrange(d.shape[0]): deltas[d_counter + 1] = d[d_counter] #now identify the slabs and their width slabs_specifications = [] current_slab_eps = [] current_slab_pixel_width = 0 LOG.debug("Calculating the camfr slabs...") for eps_column, delta_column in zip(eps, deltas): if (any(delta_column)): #if the current eps-column is different from the previous ones, finish the previous slab and add it to the list "slabs_specifications" slabs_specifications.append( (current_slab_eps, current_slab_pixel_width)) #start a new slab current_slab_eps = eps_column current_slab_pixel_width = 1 else: current_slab_pixel_width = current_slab_pixel_width + 1 slabs_specifications.append( (current_slab_eps, current_slab_pixel_width)) camfr_stack_expr = camfr.Expression() #must hold materials and slabs in an attribute list, otherwise camfr segmentation faults when cleanup by the garbage collector self.materials = dict() self.slabs = [] #create camfr slabs if (max_slabs == None): max_slabs = len(slabs_specifications) stack_width = 0.0 for slab_spec in slabs_specifications[1:max_slabs + 1]: eps_column = slab_spec[0] slab_width = slab_spec[1] if (slab_width == 0) and (len(slabs_specifications[1:]) == 1): raise PythonSimulateException( "No slabs could be determined. Fatal error in camfr_engine::mode_profile_for_geometry (is your resolution high enough??)" ) #do the same trick again, but now for the heights material_specifications = [] current_material_eps = 0 current_material_height = 0 deltas = [1] for d in numpy.diff(eps_column): deltas.append(d) for eps, delta in zip(eps_column, deltas): if (delta != 0): material_specifications.append( (current_material_eps, current_material_height)) current_material_eps = eps current_material_height = 1 else: current_material_height = current_material_height + 1 material_specifications.append( (current_material_eps, current_material_height)) LOG.debug("Camfr slab %i : z-width = %f - materials: " % (len(self.slabs) + 1, slab_width * grid_step)) for ms in material_specifications[1:]: LOG.debug(" n=%s, height=%s" % (numpy.sqrt(ms[0]), ms[1] * grid_step)) #now we know for the current slab which materials are needed with what height camfr_slab_expr = camfr.Expression() for mat_eps, mat_height in material_specifications[1:]: if mat_eps in self.materials: mat = self.materials[mat_eps] else: mat = camfr.Material(numpy.sqrt(mat_eps)) self.materials[mat_eps] = mat camfr_slab_expr.add(mat(mat_height * grid_step)) camfr_slab = camfr.Slab(camfr_slab_expr) self.slabs.append(camfr_slab) #now add this slab to the camfr stack expression camfr_stack_expr.add(camfr_slab(slab_width * grid_step)) stack_width = stack_width + slab_width LOG.debug("Camfr: cumulative width of slabs : %f" % (stack_width * grid_step)) LOG.debug("Camfr stack total width = %f" % (stack_width * grid_step)) LOG.debug("Camfr stack expression created.") return camfr_stack_expr