Package empro :: Package toolkit :: Module fem
[frames] | no frames]

Source Code for Module empro.toolkit.fem

  1  # Copyright 1983-2019 Keysight Technologies, Keysight Confidential 
  2   
  3  import os 
4 5 -class NearField(object):
6 ''' 7 NearField(<projectId>, <simulationId>) 8 NearField(empro.activeProject, <simulationId>) 9 NearField(context) 10 11 creates a near field post processor of a simulation within a project. 12 13 Example: 14 15 import empro 16 from empro.toolkit.engine_support.fem.post_processing import NearField 17 nearField = NearField('C:\\users\\jdoe\\project.ep', '000001') 18 for f in nearField.frequencies: 19 nearField.frequency = f 20 print nearField.frequency 21 print nearField.E(1e-3, 2e-3, 3e-3) # x,y,z coordinates in meters 22 print nearField.H(empro.geometry.Vector3d("1 mm", "2 mm", "3 mm")) 23 print nearField.E([(1e-3, 2e-3, 3e-3), (4e-3, 5e-3, 6e-3)]) 24 '''
25 - def __init__(self, context, simulationId=None):
26 from empro.toolkit import output 27 if os.environ.has_key("NO_FEM_USE_OVM"): 28 import pyfemPost 29 else: 30 import pyfemPlugin as pyfemPost 31 try: 32 query = context.query 33 except AttributeError: 34 try: 35 projectId = context.rootDir 36 except AttributeError: 37 projectId = context 38 else: 39 projectId = query.projectId 40 simulationId = simulationId or query.simulationId 41 assert simulationId, "no simulation specified, either use a simulation specific context or use the simulationId argument" 42 if projectId.rstrip('/\\').endswith('.ep'): 43 designDir = os.path.join(projectId, "Simulations", simulationId, "emds_dsn", "design") 44 else: 45 designDir = os.path.join(projectId, simulationId, "emds_dsn", "design") 46 assert os.path.isdir(designDir), "directory <%s> does not contain a FEM simulation" % designDir 47 self.__femPost = pyfemPost.PyFemInterface() 48 self.__femPost.setSolveName(designDir) 49 self.__femPost.setGeoName(designDir) 50 self.__femPost.Load() 51 self.__unitsPerMeter = self.__femPost.unitsPerMeter() 52 self.excitation = 1 53 self.frequency = self.frequencies[0]
54 55 @property
56 - def frequencies(self):
57 "sequence of available solution frequencies, readonly." 58 return tuple(self.__femPost.getFreqs())
59
60 - def __getFrequency(self):
61 return self.__femPost.getFrequency()
62 - def __setFrequency(self, f):
63 self.__femPost.loadFrequency(f)
64 frequency = property(__getFrequency, __setFrequency, doc="solution frequency, readwrite.") 65 66 @property
67 - def excitations(self):
68 "sequence of available excitation numbers, readonly." 69 return range(1, self.__femPost.getNumberExcitations() + 1)
70
71 - def __getExcitation(self):
72 return self.__excitation
73 - def __setExcitation(self, k):
74 self.__femPost.setExcitation(k) 75 self.__excitation = k
76 excitation = property(__getExcitation, __setExcitation, doc="index of active excitation, readwrite.") 77
78 - def E(self, *args):
79 ''' 80 E(x, y, z) -> (Ex, Ey, Ez) 81 E([(x1, y1, z1), (x2, y2, z2), ...]) -> 82 [(Ex1, Ey1, Ez1), (Ex2, Ey2, Ez2), ...] 83 84 Compute electric field in one point, or in a sequence of points. 85 Coordinates should be specified in meters. The electric field is 86 returned as triples of complex x-, y- and z-components. 87 ''' 88 return self.__value(args, 'E')
89
90 - def H(self, *args):
91 ''' 92 H(x, y, z) -> (Hx, Hy, Hz) 93 H([(x1, y1, z1), (x2, y2, z2), ...]) -> 94 [(Hx1, Hy1, Hz1), (Hx2, Hy2, Hz2), ...] 95 96 Compute magnetic field in one point, or in a sequence of points. 97 Coordinates should be specified in meters. The magnetic field is 98 returned as triples of complex x-, y- and z-components. 99 ''' 100 return self.__value(args, 'H')
101
102 - def __value(self, args, component):
103 import empro 104 assert len(args) == 1 or len(args) == 3 105 if len(args) == 3: 106 return self.__femPost.getValue(self.__scale(args), component) 107 arg = args[0] 108 if isinstance(arg, empro.geometry.Vector3d): 109 return self.__femPost.getValue(self.__scale(arg), component) 110 return self.__femPost.getValues(map(self.__scale, arg), component)
111
112 - def __scale(self, point):
113 import empro 114 if isinstance(point, empro.geometry.Vector3d): 115 point = [float(x) for x in point.x, point.y, point.z] 116 return [x * self.__unitsPerMeter for x in point]
117
118 ################################################################################################ 119 # EIGENSOLVER ################################################################################## 120 ################################################################################################ 121 122 -def getFemSimulator(runID):
123 """ 124 returns the FEM simulator object for a preexisting run <runID> 125 @param runID: run id string, example '000001' 126 """ 127 import empro, os 128 from engine_support.fem.state_machine.emds import StateMachine 129 existingEmproSimulations = empro.activeProject.simulations() 130 if len(existingEmproSimulations) == 0: 131 raise Exception("no empro simulations available or created"); 132 baseDir = os.path.join(empro.activeProject.simulations()[-1].simulationPath(), "..") 133 runDir = os.path.join(baseDir, runID) 134 if not os.path.exists(runDir): 135 raise Exception("run %s not available", runID) 136 workingDir = os.path.join(runDir, "emds_dsn", "design") 137 if not os.path.exists(workingDir): 138 raise Exception("run %s does not contain a valid FEM simulator", runID) 139 designName = os.path.split(workingDir)[1] 140 simulator = StateMachine(workingDir, designName) 141 return simulator
142
143 -def launchFemEigenSolver(targetDeltaFreqRel=0.001, nbEigenFreq=5, lowFreqLimit=1.0e9, options={}):
144 """ 145 launchFemEigenSolver(targetDeltaFreqRel, nbEigenFreq, lowFreqLimit) 146 launches a FEM eigensolve simulation 147 @param targetDeltaFreqRel: stop criterium: Delta(freq)/freq < targetDeltaFreqRel 148 @param nbEigenFreq: number of eigenfrequencies to be calculated 149 @param lowFreqLimit: low frequency limit 150 """ 151 import empro, os 152 153 # configuration output 154 print 'LAUNCHING EIGENSOLVE:' 155 # print ' target Delta(Freq)/Freq : %f' % targetDeltaFreqRel 156 print ' number eigen frequencies to be calculated : %f' % nbEigenFreq 157 print ' low frequency limit : %f GHz' % (lowFreqLimit/1e9) 158 159 # setting empro options 160 simdata = empro.activeProject.createSimulationData() 161 # simdata.name = 'eigensolve from %f GHz (nbEigenFreq=%d, targetDiff=%f)' % (lowFreqLimit/1e9, nbEigenFreq, targetDeltaFreqRel) 162 simdata.name = 'eigensolve from %f GHz (nbEigenFreq=%d)' % (lowFreqLimit/1e9, nbEigenFreq) 163 164 # creating the empro simulation 165 empro.activeProject.createSimulation(False) 166 emprosim = empro.activeProject.simulations()[-1] # grabs the simulation 167 runID = os.path.split(emprosim.simulationPath())[1] 168 169 # fetching the fem simulator 170 simulator = getFemSimulator(runID) 171 172 # setting the options 173 simulator.setOption("general/mode", "eigen") 174 simulator.setOption("eigen/lowFreqLimit", str(lowFreqLimit)) 175 simulator.setOption("eigen/nbEigenFreq", str(nbEigenFreq)) 176 simulator.setOption("refinement/targetDeltaFreqRel", str(targetDeltaFreqRel)) 177 178 # queueing the empro simulation 179 # NOTE: we cannot queue emprosim, because this is a const 180 # --> we can just grab it as the last created simulation 181 emprosim.setQueued(True)
182
183 -def getAllFEMSimIds():
184 """ 185 returns a list of all FEM simulation IDs in the active project 186 """ 187 import empro, os.path 188 return [os.path.basename(sim.simulationPath()) for sim in empro.activeProject.simulations() if sim.engine() == "FEM"]
189
190 -def getResultOfSimulation(iSimID=-1):
191 """ 192 Returns the native fem result manager for a simulation 193 simID == -1 --> the last simulation 194 simID == i --> the ith available simulation 195 simID == '00082' --> run id 00082 196 """ 197 import empro 198 import os 199 if os.environ.has_key("NO_FEM_USE_OVM"): 200 import pyfemPost 201 else: 202 import pyfemPlugin as pyfemPost 203 if iSimID == -1: 204 sim = empro.activeProject.simulations()[-1] 205 elif isinstance(iSimID,int) and 0<=iSimID and iSimID<len(empro.activeProject.simulations()): 206 sim = empro.activeProject.simulations()[iSimID] 207 else: 208 found = False 209 for s in range(len(empro.activeProject.simulations())): 210 sim = empro.activeProject.simulations()[s] 211 simid = os.path.split(sim.simulationPath())[1] 212 try: 213 if int(simid) == int(iSimID): 214 found = True 215 break 216 except: 217 pass 218 if not found: 219 raise Exception("simulation %s not found" % str(iSimID)) 220 if sim.engine() != "FEM": 221 raise Exception("not a FEM simulation") 222 workingDir = os.path.join(sim.simulationPath(), "emds_dsn", "design") 223 if not os.path.exists(workingDir): 224 raise Exception("FEM working dir <%s> does not exist" % workingDir) 225 result = pyfemPost.getResultManager(workingDir) 226 return result
227
228 -def getResultOfLastSimulation():
229 return getResultOfSimulation(-1)
230 231 ################################################################################################ 232 # CONVERGENCE MONITORING ####################################################################### 233 ################################################################################################ 234 235 from engine_support.fem.state_machine.convergence import ( 236 plotConvergence, convergencePlot, plotDiscreteSParam, 237 plotSParamVsPerformance, plotModelSParam) 238