diff --git a/python/Tutorials/Helical_Antenna.py b/python/Tutorials/Helical_Antenna.py index 7eba365..41b928f 100644 --- a/python/Tutorials/Helical_Antenna.py +++ b/python/Tutorials/Helical_Antenna.py @@ -116,6 +116,8 @@ nf2ff = FDTD.CreateNF2FFBox(opt_resolution=[lambda0/15]*3) if 0: # debugging only CSX_file = os.path.join(Sim_Path, 'helix.xml') + if not os.path.exists(Sim_Path): + os.mkdir(Sim_Path) CSX.Write2XML(CSX_file) os.system(r'AppCSXCAD "{}"'.format(CSX_file)) @@ -153,25 +155,25 @@ theta = arange(0.,180.,1.) phi = arange(-180,180,2) disp( 'calculating the 3D far field...' ) -nf2ff.CalcNF2FF(Sim_Path, f0, theta, phi, read_cached=True, verbose=True ) +nf2ff_res = nf2ff.CalcNF2FF(Sim_Path, f0, theta, phi, read_cached=True, verbose=True ) # -Dmax_dB = 10*log10(nf2ff.Dmax[0]) -E_norm = 20.0*log10(nf2ff.E_norm[0]/np.max(nf2ff.E_norm[0])) + 10*log10(nf2ff.Dmax[0]) +Dmax_dB = 10*log10(nf2ff_res.Dmax[0]) +E_norm = 20.0*log10(nf2ff_res.E_norm[0]/np.max(nf2ff_res.E_norm[0])) + 10*log10(nf2ff_res.Dmax[0]) theta_HPBW = theta[ np.where(squeeze(E_norm[:,phi==0])0 to <=1) + :param TimeStepMethod: 1 or 3 chose timestep method (1=CFL, 3=Rennigs (default)) + :param CellConstantMaterial: set to 1 to assume a material is constant inside a cell (material probing in cell center) + """ @staticmethod def WelcomeScreen(): _openEMS.WelcomeScreen() - """ __cinit__ - NrTS: max. number of timesteps to simulate (e.g. default=1e9) - EndCriteria: end criteria, e.g. 1e-5, simulations stops if energy has decayed by this value (<1e-4 is recommended, default=1e-5) - MaxTime: max. real time in seconds to simulate - OverSampling: nyquist oversampling of time domain dumps - CoordSystem: choose coordinate system (0 Cartesian, 1 Cylindrical) - #MultiGrid: define a cylindrical sub-grid radius - TimeStep: force to use a given timestep (dangerous!) - TimeStepFactor: reduce the timestep by a given factor (>0 to <=1) - TimeStepMethod: 1 or 3 chose timestep method (1=CFL, 3=Rennigs (default)) - CellConstantMaterial: set to 1 to assume a material is constant inside a cell (material probing in cell center) - """ def __cinit__(self, *args, **kw): self.thisptr = new _openEMS() self.CSX = None if 'NrTS' in kw: self.SetNumberOfTimeSteps(kw['NrTS']) + del kw['NrTS'] else: self.SetNumberOfTimeSteps(1e9) if 'EndCriteria' in kw: self.SetEndCriteria(kw['EndCriteria']) + del kw['EndCriteria'] if 'MaxTime' in kw: self.SetMaxTime(kw['MaxTime']) + del kw['MaxTime'] if 'OverSampling' in kw: self.SetOverSampling(kw['OverSampling']) + del kw['OverSampling'] if 'CoordSystem' in kw: self.SetCoordSystem(kw['CoordSystem']) + del kw['CoordSystem'] if 'TimeStep' in kw: self.SetTimeStep(kw['TimeStep']) + del kw['TimeStep'] if 'TimeStepFactor' in kw: self.SetTimeStepFactor(kw['TimeStepFactor']) + del kw['TimeStepFactor'] if 'TimeStepMethod' in kw: self.SetTimeStepMethod(kw['TimeStepMethod']) + del kw['TimeStepMethod'] if 'CellConstantMaterial' in kw: self.SetCellConstantMaterial(kw['CellConstantMaterial']) + del kw['CellConstantMaterial'] + + assert len(kw)==0, 'Unknown keyword arguments: "{}"'.format(kw) def __dealloc__(self): del self.thisptr @@ -58,41 +70,68 @@ cdef class openEMS: self.CSX.thisptr = NULL def SetNumberOfTimeSteps(self, val): + """ SetNumberOfTimeSteps(val) + """ self.thisptr.SetNumberOfTimeSteps(val) def SetEndCriteria(self, val): + """ SetEndCriteria(val) + """ self.thisptr.SetEndCriteria(val) def SetOverSampling(self, val): + """ SetOverSampling(val) + """ self.thisptr.SetOverSampling(val) def SetCellConstantMaterial(self, val): + """ SetCellConstantMaterial(val) + """ self.thisptr.SetCellConstantMaterial(val) def SetCoordSystem(self, val): - assert (val==0 or val==1) + """ SetCoordSystem(val) + """ + assert (val==0 or val==1), 'SetCoordSystem: Invalid coordinate system' if val==0: pass elif val==1: self.SetCylinderCoords() def SetCylinderCoords(self): + """ SetCylinderCoords() + """ self.thisptr.SetCylinderCoords(True) def SetTimeStepMethod(self, val): + """ SetTimeStepMethod(val) + """ self.thisptr.SetTimeStepMethod(val) + def SetTimeStep(self, val): + """ SetTimeStep(val) + """ self.thisptr.SetTimeStep(val) + def SetTimeStepFactor(self, val): + """ SetTimeStepFactor(val) + """ self.thisptr.SetTimeStepFactor(val) + def SetMaxTime(self, val): + """ SetMaxTime(val) + """ self.thisptr.SetMaxTime(val) def SetGaussExcite(self, f0, fc): + """ SetGaussExcite(f0, fc) + """ self.thisptr.SetGaussExcite(f0, fc) def SetBoundaryCond(self, BC): + """ SetBoundaryCond(BC) + """ assert len(BC)==6 for n in range(len(BC)): if type(BC[n])==int: @@ -108,19 +147,27 @@ cdef class openEMS: raise Exception('Unknown boundary condition') def AddLumpedPort(self, port_nr, R, start, stop, p_dir, excite=0, **kw): - assert self.CSX is not None + """ AddLumpedPort(port_nr, R, start, stop, p_dir, excite=0, **kw) + """ + assert self.CSX is not None, 'AddLumpedPort: CSX is not set!' return ports.LumpedPort(self.CSX, port_nr, R, start, stop, p_dir, excite, **kw) def AddRectWaveGuidePort(self, port_nr, start, stop, p_dir, a, b, mode_name, excite=0, **kw): - assert self.CSX is not None + """ AddRectWaveGuidePort(port_nr, start, stop, p_dir, a, b, mode_name, excite=0, **kw) + """ + assert self.CSX is not None, 'AddRectWaveGuidePort: CSX is not set!' return ports.RectWGPort(self.CSX, port_nr, start, stop, p_dir, a, b, mode_name, excite, **kw) def AddMSLPort(self, port_nr, metal_prop, start, stop, prop_dir, exc_dir, excite=0, **kw): - assert self.CSX is not None + """ AddMSLPort(port_nr, metal_prop, start, stop, prop_dir, exc_dir, excite=0, **kw) + """ + assert self.CSX is not None, 'AddMSLPort: CSX is not set!' return ports.MSLPort(self.CSX, port_nr, metal_prop, start, stop, prop_dir, exc_dir, excite, **kw) def CreateNF2FFBox(self, name='nf2ff', start=None, stop=None, **kw): - assert self.CSX is not None + """ CreateNF2FFBox(name='nf2ff', start=None, stop=None, **kw) + """ + assert self.CSX is not None, 'CreateNF2FFBox: CSX is not set!' directions = [True]*6 mirror = [0]*6 BC_size = [0]*6 @@ -152,10 +199,14 @@ cdef class openEMS: return nf2ff.nf2ff(self.CSX, name, start, stop, directions=directions, mirror=mirror, **kw) def SetCSX(self, ContinuousStructure CSX): + """ SetCSX(CSX) + """ self.CSX = CSX self.thisptr.SetCSX(CSX.thisptr) def Run(self, sim_path, cleanup=False, setup_only=False, verbose=None): + """ Run(sim_path, cleanup=False, setup_only=False, verbose=None) + """ if cleanup and os.path.exists(sim_path): shutil.rmtree(sim_path) os.mkdir(sim_path) diff --git a/python/openEMS/ports.py b/python/openEMS/ports.py index 99ae1d5..30492f6 100644 --- a/python/openEMS/ports.py +++ b/python/openEMS/ports.py @@ -116,14 +116,14 @@ class LumpedPort(Port): self.exc_ny = CheckNyDir(exc_dir) self.direction = np.sign(self.stop[self.exc_ny]-self.start[self.exc_ny]) - assert self.start[self.exc_ny]!=self.stop[self.exc_ny] + assert self.start[self.exc_ny]!=self.stop[self.exc_ny], 'LumpedPort: start and stop may not be identical in excitation direction' if self.R > 0: lumped_R = CSX.AddLumpedElement(self.lbl_temp.format('resist'), ny=self.exc_ny, caps=True, R=self.R) elif self.R==0: lumped_R = CSX.AddMetal(self.lbl_temp.format('resist')) - CSX.AddBox(lumped_R, self.start, self.stop, priority=self.priority) + CSX.AddBox(lumped_R, self.start, self.stop, priority=self.priority, edges2grid=kw.get('edges2grid', None)) if excite!=0: exc_vec = np.zeros(3)