def take_snapshot(self, now): """ This function creates a directory, exports the dielectric structure, then exports the electric and magnetic field vectors to separate HDF5 files. Finally it converts the fields to VTK format (to be readable e. g. by Mayavi2). Note that it is not only called by self.poll(), but I may be also called at will. """ meep.master_printf(" * Saving field snapshot at time=%.4e... \n" % now) ## Export the dielectric structure so that we can visually verify it structure_filename = os.path.join(self.outputdir, 'structure') ## name of the file to save eps (without extension) #if meep.my_rank() == 0 and not os.path.exists(self.outputdir): os.mkdir(self.outputdir) if not os.path.exists(self.outputdir): run_bash("mkdir -p %s" % self.outputdir, anyprocess=True) ## NO DATA #if not os.path.exists(structure_filename): #if meep.my_rank() ==0 : #if not "outputfile" in locals(): outputfile = meep.prepareHDF5File(structure_filename+'.h5') self.field.output_hdf5(meep.Dielectric, self.volume, outputfile) del(outputfile) ## Export the fields snapshot snapshotfiles = [] for (component, compname) in [(meep.Ex, "Ex"), (meep.Ey, "Ey"), (meep.Ez, "Ez"), (meep.Hx, "Hx"), (meep.Hy, "Hy"), (meep.Hz, "Hz")]: snapshotfiles.append("%s/snapshot_%s_t%e.h5" % (self.outputdir, compname, now)) snapshotfile = meep.prepareHDF5File(snapshotfiles[-1]) self.field.output_hdf5(component, self.volume, snapshotfile, 1) del(snapshotfile) ## Convert the files for Mayavi2; join E-fields and H-fields components into vector fields run_bash("h5tovtk %s.h5 -o %s.vtk" % (structure_filename, structure_filename)) run_bash("h5tovtk %s -t 0 -o %s/t%0.3e_Evec.vtk" % (" ".join(snapshotfiles[:3]), self.outputdir, now)) ## todo: use path.join run_bash("h5tovtk %s -t 0 -o %s/t%0.3e_Hvec.vtk" % (" ".join(snapshotfiles[3:]), self.outputdir, now))
def __init__(self, field=None, component=meep.Ex, timebounds=(0, np.inf), timestep=0, volume=None, normal=None, position=None, model=None, pad=0, outputdir="", name=None, outputPNGs=False, outputGIF=True, outputHDF=False, outputVTK=False): """ """ self.field = field self.outputdir = outputdir self.component = component self.timebounds = timebounds self.timestep = timestep self.outputPNGs = outputPNGs self.outputGIF = outputGIF self.outputHDF = outputHDF self.outputVTK = outputVTK if volume: self.volume = volume meep.master_printf("Will record slices at times %.3g, %.3g ... %.3g s \n" % (timebounds[0], timebounds[0]+timestep, timebounds[1])) else: #if not position: #raise RuntimeError("Specify the position of the cut plane (on the axis perpendicular to it)") if normal=="x": self.volume = meep.volume( meep.vec(position, -model.size_y/2+pad, -model.size_z/2+pad), meep.vec(position, model.size_y/2-pad, model.size_z/2-pad)) elif normal=="y": self.volume = meep.volume( meep.vec(-model.size_x/2+pad, position, -model.size_z/2+pad), meep.vec(model.size_x/2-pad, position, model.size_z/2-pad)) elif normal=="z": self.volume = meep.volume( meep.vec(-model.size_x/2+pad, -model.size_y/2+pad, position), meep.vec(model.size_x/2-pad, model.size_y/2-pad, position)) #else: #print normal #raise RuntimeError("Specify the normal parameter as 'x', 'y' or 'z'") meep.master_printf("Will record slices at %s=%.3g m, at times %g, %g ... %g s \n" \ % (normal, position, timebounds[0], timebounds[0]+timestep, timebounds[1])) self.outputdir = outputdir if not name: if not position or not normal: self.name = "SliceByVolume" else: self.name = "Slice_%s%.3e" % (normal, position) else: self.name = name self.images_number = 0 self.last_slice_time = 0. #slices=[] #slices.append({"name":"Ex_xz_slice", "component":meep.Ex, "geom": if not os.path.exists(outputdir): run_bash("mkdir -p %s" % outputdir, anyprocess=True) self.openfile = meep.prepareHDF5File("%s.h5" % (os.path.join(self.outputdir, self.name)))
def run(self): ## TEMPORARY SETTINGS wg_bottom = 0.7 wg_top = 0.7 + 0.22 wg_center = (wg_bottom + wg_top) / 2. #top = 0.7 + 0.38 ## preparing po = self.property_object self.engine.initialise_engine(self.landscape) fields = meep.fields(self.engine.structure) self.save_engine_dielectricum_to_file(po.eps_filename) ## Sources print 'Center wavelength:', po.wavelength print 'Bandwidth:', po.pulse_width center_freq = 1.0 / (float(po.wavelength)) pulse_width_freq = (float(po.pulse_width)) / ( float(po.wavelength)) * center_freq print 'Center frequency:', center_freq print 'Bandwidth:', pulse_width_freq if (po.pulsed_source): src = meep.gaussian_src_time(center_freq, pulse_width_freq) else: src = meep.continuous_src_time(center_freq) source_port_position = po.input_port.transform_copy( Translation(translation=(po.source_input_port_offset, 0))).position print 'wg_center_old:', wg_center wg_center = (po.input_port.wg_definition.process.wg_upper_z_coord + po.input_port.wg_definition.process.wg_lower_z_coord) / 2. print 'wg_center_new:', wg_center c = Coord3(source_port_position[0], source_port_position[1], wg_center) print 'coord:', c source_position_vec = self.make_meep_vec(c) fields.add_point_source(meep.Ey, src, source_position_vec) ## 2D Cross section volumes for oc in po.output_cuts: fn = '%s_eps.h5' % oc.filename vol = oc.get_output_volume(self.engine.meepVol) f_eps = meep.prepareHDF5File(fn) fields.output_hdf5(meep.Dielectric, vol, f_eps) del f_eps system('h5topng %s' % fn) ### Fluxplanes self.fluxes = [] for p in po.output_ports: pp = p.position port_width = p.wg_definition.wg_width wg_bottom = p.wg_definition.process.wg_lower_z_coord wg_top = p.wg_definition.process.wg_upper_z_coord ## Be aware: this is only for ports along y-axis!! vec_near = self.make_meep_vec( Coord3(pp[0], pp[1] - port_width / 2.0, wg_bottom)) vec_far = self.make_meep_vec( Coord3(pp[0], pp[1] + port_width / 2.0, wg_top)) fluxplane = meep.volume(vec_near, vec_far) fx = fields.add_dft_flux_plane( fluxplane, center_freq - (pulse_width_freq / 4.0), center_freq + (pulse_width_freq / 4.0), po.dft_terms) self.fluxes.append(fx) ## Reverse one of the fluxes if necessary if po.load_reversed_flux_from_file_ID > -1: self.fluxes[po.load_reversed_flux_from_file_ID].load_hdf5( fields, po.load_reversed_flux_from_file_filename) if (po.pulsed_source): stop = po.stop_time_multiplier * fields.last_source_time() else: stop = po.stop_time print 'Simulation will run for', stop, 'time units' output_files = [] for oc in po.output_cuts: fn = '%s.h5' % oc.filename oc_file = meep.prepareHDF5File(fn) output_files.append(oc_file) i = 0 n_o_output = 0 while (fields.time() < stop): if (i > po.output_steps): j = 0 for oc in po.output_cuts: vol = oc.get_output_volume(self.engine.meepVol) fields.output_hdf5(meep.Ey, vol, output_files[j], 1) j += 1 n_o_output += 1 i = 0 fields.step() i += 1 print n_o_output, 'images outputted' print 'Outputting field images..' del output_files[:] for oc in po.output_cuts: fn = '%s.h5' % oc.filename fn_eps = '%s_eps.h5' % oc.filename st = 'h5topng -t 0:%d -R -Zc dkbluered -a yarg -A %s %s' % ( n_o_output - 1, fn_eps, fn) print st system(st) print 'Outputting done!' #print 'obtaining fluxes:' self.flux_data = [] for i in range(len(po.output_ports)): fd = meep.getFluxData(self.fluxes[i]) self.flux_data.append(fd) #print fd ## Save flux data if necesarry if po.save_reversed_flux_to_file_ID > -1: fx = self.fluxes[po.save_reversed_flux_to_file_ID] fx.scale_dfts(-1) fx.save_hdf5(fields, po.save_reversed_flux_to_file_filename) return