def _getInnerProduct(self, projType, prop=None, invProp=False, invMat=False, doFast=True): """ :param str projType: 'F' for faces 'E' for edges :param numpy.array prop: material property (tensor properties are possible) at each cell center (nC, (1, 3, or 6)) :param bool invProp: inverts the material property :param bool invMat: inverts the matrix :param bool doFast: do a faster implementation if available. :rtype: scipy.sparse.csr_matrix :return: M, the inner product matrix (nE, nE) """ assert projType in [ 'F', 'E' ], "projType must be 'F' for faces or 'E' for edges" fast = None if hasattr(self, '_fastInnerProduct') and doFast: fast = self._fastInnerProduct(projType, prop=prop, invProp=invProp, invMat=invMat) if fast is not None: return fast if invProp: prop = invPropertyTensor(self, prop) tensorType = TensorType(self, prop) Mu = makePropertyTensor(self, prop) Ps = self._getInnerProductProjectionMatrices(projType, tensorType) A = np.sum([P.T * Mu * P for P in Ps]) if invMat and tensorType < 3: A = sdInv(A) elif invMat and tensorType == 3: raise Exception('Solver needed to invert A.') return A
def fields(self, v): if self.bcflag =='up': self.mesh.setCellGradBC(['dirichlet', ['dirichlet', 'neumann']]) elif self.bcflag =='left': self.mesh.setCellGradBC([['neumann', 'dirichlet'], ['dirichlet', 'neumann']]) elif self.bcflag =='right': self.mesh.setCellGradBC([['dirichlet', 'neumann'], ['dirichlet', 'neumann']]) Grad = self.mesh.cellGrad # Be careful about averaging operator AvF2CC = self.mesh.dim*self.mesh.aveF2CC AvF2CCv = self.mesh.aveF2CCV rho = 0.27*np.ones(self.mesh.nC) mu = rho*v**2 Divvec = sp.block_diag((self.mesh.faceDivx, self.mesh.faceDivy)) Mrhocc = sp.block_diag((sdiag(rho), sdiag(rho))) Mmuifvec = sdiag(AvF2CC.T*(1/mu)) Msigf = sdiag(AvF2CCv.T*np.r_[self.sigx, self.sigy]) Msigcc = sp.block_diag((sdiag(self.sigx), sdiag(self.sigy))) MrhoccI = sdInv(Mrhocc) MmuifvecI = sdInv(Mmuifvec) Ivec = sp.hstack((sdiag(np.ones(self.mesh.nC)), sdiag(np.ones(self.mesh.nC)))) if self.stability==False: raise Exception("Stability condition is not satisfied!!") elif self.sigx is False: print "Warning: Absorbing boundary condition was not set yet!!" start = clock() print ">> Start Computing Acoustic Wave" print (">> dt: %5.2e s")%(self.dt) print (">> Optimal dt: %5.2e s")%(self.topt) print (">> Main frequency, fmain: %5.2e Hz")%(self.fmain) print (">> Cell per wavelength (G): %5.2e")%(self.G) if self.storefield==True: Phi = [] #TODO: parallize in terms of sources nsrc = len(self.survey.srcList) for isrc, src in enumerate(self.survey.srcList): print (" Src at (%7.2f, %7.2f): %4i/%4i")%(src.loc[0], src.loc[0], isrc+1, nsrc) phi = np.zeros((self.mesh.nC, src.time.size)) phin = np.zeros(self.mesh.nC*2) phi0 = np.zeros_like(phin) un = np.zeros(self.mesh.nF) u0 = np.zeros_like(un) time = src.time dt = src.dt q = src.getq(self.mesh) qvec = np.r_[q, q]*1/2 for i in range(time.size-1): sn = src.Wave(i+1) s0 = src.Wave(i) phin = phi0-dt*(Msigcc*phi0)+dt*MrhoccI*(1/dt*(sn-s0)*qvec+Divvec*un) phi0 = phin.copy() un = u0 - dt*Msigf*u0 + dt*MmuifvecI*Grad*(Ivec*phi0) u0 = un.copy() phi[:,i+1] = Ivec*phi0 Phi.append(phi) elapsed = clock()-start print (">>Elapsed time: %5.2e s")%(elapsed) return Phi elif self.storefield==False: Data = [] nsrc = len(self.survey.srcList) for isrc, src in enumerate(self.survey.srcList): print (" Src at (%7.2f, %7.2f): %4i/%4i")%(src.loc[0], src.loc[0], isrc+1, nsrc) phi = np.zeros((mesh.nC, time.size)) phin = np.zeros(mesh.nC*2) phi0 = np.zeros_like(phin) un = np.zeros(mesh.nF) u0 = np.zeros_like(un) time = src.time dt = src.dt p = np.zeros((self.mesh.nC, time.size)) q = src.getq(self.mesh) qvec = np.r_[q, q]*1/2 for i in range(time.size-1): sn = src.Wave(i+1) s0 = src.Wave(i) phin = phi0-dt*(Msigcc*phi0)+dt*MrhoccI*(1/dt*(sn-s0)*qvec+Divvec*un) phi0 = phin.copy() un = u0 - dt*Msigf*u0 + dt*MmuifvecI*Grad*(Ivec*phi0) u0 = un.copy() data[i,:] = Proj*(Ivec*phi0) Data.append(data) elapsed = clock()-start print (">>Elapsed time: %5.2e s")%(elapsed) return Data
def fields(self, epsilon, mu, sig0): Seps = sp.block_diag( [sdiag(epsilon * self.sy0), sdiag(epsilon * self.sx0)]) SepsI = sp.block_diag([ sdiag(1. / (epsilon * self.sy0)), sdiag(1. / (epsilon * self.sx0)) ]) Sepsisig = sp.block_diag([ sdiag(sig0 * self.sigy * (1. / epsilon) * self.sy0), sdiag(sig0 * self.sigx * (1. / epsilon) * self.sx0) ]) Ssig = sp.block_diag([ sdiag((self.sigy + sig0) * self.sy0), sdiag((self.sigx + sig0) * self.sx0) ]) Mesmuisigs = sdiag(self.mesh.aveE2CCV.T * np.r_[self.sigs * self.sigy / epsilon * self.sy0, self.sigs * self.sigx / epsilon * self.sx0]) Messigs = sdiag( self.mesh.aveE2CCV.T * np.r_[(self.sigs + self.sigy * mu / epsilon) * self.sy0, (self.sigs + self.sigx * mu / epsilon) * self.sx0]) Mesmu = sdiag(self.mesh.aveE2CCV.T * np.r_[mu * self.sy0, mu * self.sx0]) MesmuI = sdInv(Mesmu) Icc = sp.hstack((speye(self.mesh.nC), speye(self.mesh.nC))) curl = self.mesh.edgeCurl curlvec = sp.block_diag( (curl[:, :self.mesh.nEx], curl[:, self.mesh.nEx:])) if self.stability == False: raise Exception("Stability condition is not satisfied!!") elif self.sigx is False: print "Warning: Absorbing boundary condition was not set yet!!" start = clock() print "" print "***** Start Computing Electromagnetic Wave *****" print "" print(">> dt: %5.2e s") % (self.dt) print(">> Optimal dt: %5.2e s") % (self.topt) print(">> Main frequency, fmain: %5.2e Hz") % (self.fmain) print(">> Cell per wavelength (G): %5.2e") % (self.G) if self.storefield == True: self._Fields = {} #TODO: parallize in terms of sources nsrc = len(self.survey.srcList) for isrc, src in enumerate(self.survey.srcList): print(" Src at (%7.2f, %7.2f): %4i/%4i") % ( src.loc[0], src.loc[0], isrc + 1, nsrc) h0 = np.zeros(self.mesh.nE) h1 = np.zeros(self.mesh.nE) hI0 = np.zeros(self.mesh.nE) hI1 = np.zeros(self.mesh.nE) ed0 = np.zeros(2 * self.mesh.nC) ed1 = np.zeros(2 * self.mesh.nC) eId0 = np.zeros(2 * self.mesh.nC) eId1 = np.zeros(2 * self.mesh.nC) time = src.time dt = src.dt je, jm = src.getq(self.mesh) h = np.zeros((self.mesh.nE, time.size)) e = np.zeros((self.mesh.nC, time.size)) for i in range(time.size - 1): eId0 = eId1.copy() eId1 = eId0 + dt * ed0 ed1 = ed0 + SepsI * dt * ( curlvec * (h1) - Ssig * ed0 - Sepsisig * eId1 - je * src.wave[i]) ed0 = ed1.copy() e[:, i] = Icc * ed1 hI0 = hI1.copy() hI1 = hI0 + dt * h0 h1 = h0 - MesmuI * dt * (curl.T * (Icc * ed0) + Messigs * h0 + Mesmuisigs * hI1 + jm * src.wave[i]) h0 = h1.copy() h[:, i] = h1 self._Fields['E', src] = e self._Fields['H', src] = h elapsed = clock() - start print(">>Elapsed time: %5.2e s") % (elapsed) return self._Fields elif self.storefield == False: Data = {} nsrc = len(self.survey.srcList) for isrc, src in enumerate(self.survey.srcList): print(" Src at (%7.2f, %7.2f): %4i/%4i") % ( src.loc[0], src.loc[0], isrc + 1, nsrc) h0 = np.zeros(mesh.nE) h1 = np.zeros(mesh.nE) hI0 = np.zeros(mesh.nE) hI1 = np.zeros(mesh.nE) ed0 = np.zeros(2 * mesh.nC) ed1 = np.zeros(2 * mesh.nC) eId0 = np.zeros(2 * mesh.nC) eId1 = np.zeros(2 * mesh.nC) time = src.time dt = src.dt je, jm = src.getq(self.mesh) h = np.zeros((mesh.nE, time.size)) e = np.zeros((mesh.nC, time.size)) for i in range(time.size - 1): eId0 = eId1.copy() eId1 = eId0 + dt * ed0 ed1 = ed0 + SepsI * dt * (curlvec * (h1) - Ssig * ed0 - Sepsisig * eId1 - je * wave[i]) ed0 = ed1.copy() e[:, i] = Icc * ed1 hI0 = hI1.copy() hI1 = hI0 + dt * h0 h1 = h0 - MesmuI * dt * (curl.T * (Icc * ed0) + Messigs * h0 + Mesmuisigs * hI1 + jm * wave[i]) h0 = h1.copy() h[:, i] = h1 for rx in src.rxList: Proj = rx.getP(self.mesh) if rx.rxtype.find('E') >= 0: flag = 'E' Data[src, rx] = (Proj * e) elif rx.rxtype.find('H') >= 0: flag = 'H' Data[src, rx] = (Proj * h) elapsed = clock() - start print(">>Elapsed time: %5.2e s") % (elapsed) return Data
def fields(self, epsilon, mu, sig0): Smu = sp.block_diag([sdiag(mu*self.sy0), sdiag(mu*self.sx0)]) SmuI = sp.block_diag([sdiag(1./(mu*self.sy0)), sdiag(1./(mu*self.sx0))]) Smuisig = sp.block_diag([sdiag(self.sigs*self.sigy*(1./epsilon)*self.sy0), sdiag(self.sigs*self.sigx*(1./epsilon)*self.sx0)]) Ssig = sp.block_diag([sdiag((self.sigy*mu/epsilon+self.sigs)*self.sy0), sdiag((self.sigx*mu/epsilon+self.sigs)*self.sx0)]) Mesepsisig = sdiag(self.mesh.aveE2CCV.T*np.r_[1./epsilon*sig0*self.sigy*self.sy0, 1./epsilon*sig0*self.sigx*self.sx0]) Messig = sdiag(self.mesh.aveE2CCV.T*np.r_[(sig0+self.sigy)*self.sy0, (sig0+self.sigx)*self.sx0]) Meseps = sdiag(self.mesh.aveE2CCV.T*np.r_[epsilon*self.sy0, epsilon*self.sx0]) MesepsI = sdInv(Meseps) Icc = sp.hstack((speye(self.mesh.nC), speye(self.mesh.nC))) curl = self.mesh.edgeCurl curlvec = sp.block_diag((curl[:,:self.mesh.nEx], curl[:,self.mesh.nEx:])) if self.stability==False: raise Exception("Stability condition is not satisfied!!") elif self.sigx is False: print "Warning: Absorbing boundary condition was not set yet!!" start = clock() print "" print "***** Start Computing Electromagnetic Wave *****" print "" print (">> dt: %5.2e s")%(self.dt) print (">> Optimal dt: %5.2e s")%(self.topt) print (">> Main frequency, fmain: %5.2e Hz")%(self.fmain) print (">> Cell per wavelength (G): %5.2e")%(self.G) if self.storefield==True: self._Fields ={} #TODO: parallize in terms of sources nsrc = len(self.survey.srcList) for isrc, src in enumerate(self.survey.srcList): print (" Src at (%7.2f, %7.2f): %4i/%4i")%(src.loc[0], src.loc[0], isrc+1, nsrc) hd0 = np.zeros(2*self.mesh.nC) hd1 = np.zeros(2*self.mesh.nC) hId0 = np.zeros(2*self.mesh.nC) hId1 = np.zeros(2*self.mesh.nC) e0 = np.zeros(self.mesh.nE) e1 = np.zeros(self.mesh.nE) eI0 = np.zeros(self.mesh.nE) eI1 = np.zeros(self.mesh.nE) time = src.time dt = src.dt jm, je = src.getq(self.mesh) h = np.zeros((self.mesh.nC, time.size)) e = np.zeros((self.mesh.nE, time.size)) for i in range(time.size-1): eI0 = eI1.copy() eI1 = eI0 + dt*e0 e1 = e0 + MesepsI*dt*(curl.T*(Icc*hd1)-Messig*e0-Mesepsisig*eI1-je*src.wave[i]) e0 = e1.copy() e[:,i] = e1 hId0 = hId1.copy() hId1 = hId0 + dt*hd0 hd1 = hd0 - SmuI*dt*(curlvec*e0+Ssig*hd0+Smuisig*hId1+jm*src.wave[i]*0.5) hd0 = hd1.copy() h[:,i] = Icc*hd1 self._Fields['E', src]= e self._Fields['H', src]= h elapsed = clock()-start print (">>Elapsed time: %5.2e s")%(elapsed) return self._Fields elif self.storefield==False: Data = {} nsrc = len(self.survey.srcList) for isrc, src in enumerate(self.survey.srcList): print (" Src at (%7.2f, %7.2f): %4i/%4i")%(src.loc[0], src.loc[0], isrc+1, nsrc) hd0 = np.zeros(2*mesh.nC) hd1 = np.zeros(2*mesh.nC) hId0 = np.zeros(2*mesh.nC) hId1 = np.zeros(2*mesh.nC) e0 = np.zeros(mesh.nE) e1 = np.zeros(mesh.nE) eI0 = np.zeros(mesh.nE) eI1 = np.zeros(mesh.nE) time = src.time dt = src.dt jm, je = src.getq(self.mesh) h = np.zeros((mesh.nC, time.size)) e = np.zeros((mesh.nE, time.size)) for i in range(time.size-1): eI0 = eI1.copy() eI1 = eI0 + dt*e0 e1 = e0 + MesepsI*dt*(curl.T*(Icc*hd1)-Messig*e0-Mesepsisig*eI1-je*src.wave[i]) e0 = e1.copy() e[:,i] = e1 hId0 = hId1.copy() hId1 = hId0 + dt*hd0 hd1 = hd0 - SmuI*dt*(curlvec*e0+Ssig*hd0+Smuisig*hId1+jm*src.wave[i]) hd0 = hd1.copy() h[:,i] = Icc*hd1 for rx in src.rxList: Proj = rx.getP(self.mesh) if rx.rxtype.find('E') >= 0: flag = 'E' Data[src, rx] = (Proj*e) elif rx.rxtype.find('H') >= 0: flag = 'H' Data[src, rx] = (Proj*h) elapsed = clock()-start print (">>Elapsed time: %5.2e s")%(elapsed) return Data
def fields(self, v): if self.bcflag == 'up': self.mesh.setCellGradBC(['dirichlet', ['dirichlet', 'neumann']]) elif self.bcflag == 'left': self.mesh.setCellGradBC([['neumann', 'dirichlet'], ['dirichlet', 'neumann']]) elif self.bcflag == 'right': self.mesh.setCellGradBC([['dirichlet', 'neumann'], ['dirichlet', 'neumann']]) Grad = self.mesh.cellGrad # Be careful about averaging operator AvF2CC = self.mesh.dim * self.mesh.aveF2CC AvF2CCv = self.mesh.aveF2CCV rho = 0.27 * np.ones(self.mesh.nC) mu = rho * v**2 Divvec = sp.block_diag((self.mesh.faceDivx, self.mesh.faceDivy)) Mrhocc = sp.block_diag((sdiag(rho), sdiag(rho))) Mmuifvec = sdiag(AvF2CC.T * (1 / mu)) Msigf = sdiag(AvF2CCv.T * np.r_[self.sigx, self.sigy]) Msigcc = sp.block_diag((sdiag(self.sigx), sdiag(self.sigy))) MrhoccI = sdInv(Mrhocc) MmuifvecI = sdInv(Mmuifvec) Ivec = sp.hstack( (sdiag(np.ones(self.mesh.nC)), sdiag(np.ones(self.mesh.nC)))) if self.stability == False: raise Exception("Stability condition is not satisfied!!") elif self.sigx is False: print "Warning: Absorbing boundary condition was not set yet!!" start = clock() print ">> Start Computing Acoustic Wave" print(">> dt: %5.2e s") % (self.dt) print(">> Optimal dt: %5.2e s") % (self.topt) print(">> Main frequency, fmain: %5.2e Hz") % (self.fmain) print(">> Cell per wavelength (G): %5.2e") % (self.G) if self.storefield == True: Phi = [] #TODO: parallize in terms of sources nsrc = len(self.survey.srcList) for isrc, src in enumerate(self.survey.srcList): print(" Src at (%7.2f, %7.2f): %4i/%4i") % ( src.loc[0], src.loc[0], isrc + 1, nsrc) phi = np.zeros((self.mesh.nC, src.time.size)) phin = np.zeros(self.mesh.nC * 2) phi0 = np.zeros_like(phin) un = np.zeros(self.mesh.nF) u0 = np.zeros_like(un) time = src.time dt = src.dt q = src.getq(self.mesh) qvec = np.r_[q, q] * 1 / 2 for i in range(time.size - 1): sn = src.Wave(i + 1) s0 = src.Wave(i) phin = phi0 - dt * (Msigcc * phi0) + dt * MrhoccI * ( 1 / dt * (sn - s0) * qvec + Divvec * un) phi0 = phin.copy() un = u0 - dt * Msigf * u0 + dt * MmuifvecI * Grad * (Ivec * phi0) u0 = un.copy() phi[:, i + 1] = Ivec * phi0 Phi.append(phi) elapsed = clock() - start print(">>Elapsed time: %5.2e s") % (elapsed) return Phi elif self.storefield == False: Data = [] nsrc = len(self.survey.srcList) for isrc, src in enumerate(self.survey.srcList): print(" Src at (%7.2f, %7.2f): %4i/%4i") % ( src.loc[0], src.loc[0], isrc + 1, nsrc) phi = np.zeros((mesh.nC, time.size)) phin = np.zeros(mesh.nC * 2) phi0 = np.zeros_like(phin) un = np.zeros(mesh.nF) u0 = np.zeros_like(un) time = src.time dt = src.dt p = np.zeros((self.mesh.nC, time.size)) q = src.getq(self.mesh) qvec = np.r_[q, q] * 1 / 2 for i in range(time.size - 1): sn = src.Wave(i + 1) s0 = src.Wave(i) phin = phi0 - dt * (Msigcc * phi0) + dt * MrhoccI * ( 1 / dt * (sn - s0) * qvec + Divvec * un) phi0 = phin.copy() un = u0 - dt * Msigf * u0 + dt * MmuifvecI * Grad * (Ivec * phi0) u0 = un.copy() data[i, :] = Proj * (Ivec * phi0) Data.append(data) elapsed = clock() - start print(">>Elapsed time: %5.2e s") % (elapsed) return Data
class ProblemATEMIP_b(BaseATEMIPProblem_b): """ Time-Domain EM-IP problem - B-formulation TDEM_b treats the following discretization of Maxwell's equations """ store_fields = False # Only store magnetic field sigmaHatDict = {} def __init__(self, mesh, mapping=None, **kwargs): BaseATEMIPProblem_b.__init__(self, mesh, mapping=mapping, **kwargs) solType = 'b' #: Type of the solution, in this case the 'b' field surveyPair = SurveyTDEM _FieldsForward_pair = FieldsATEMIP_store_bej #: used for the forward calculation only #################################################### # Internal Methods #################################################### def sigmaHat(self, t, ColeColefunc=ColeCole): etc = np.c_[self.curModel.eta, self.curModel.tau, self.curModel.c] unqEtc, uETCind, invInd = uniqueRows(etc) sigmaHat = [] for (ev, tv, cv) in unqEtc: if ev == 0.: sigmaHat.append(0.) else: key = '%.5e_%.5f_%.5e_%.5f' % (t, ev, tv, cv) if self.sigmaHatDict.has_key(key): val = self.sigmaHatDict[key] else: if t == 0: # val = transFilt(F,1e-6) val = ev / (tv * (1. - ev)) else: F = lambda frq: (1j * 2 * np.pi * frq) * ColeColefunc( frq, sigmaInf=1., eta=ev, tau=tv, c=cv) val = transFilt(F, t) self.sigmaHatDict[key] = val sigmaHat.append(val) sigmaHat = self.curModel.sigmaInf * np.array(sigmaHat)[invInd] return sigmaHat @property def MeSigmaInf(self): if getattr(self, '_MeSigmaInf', None) is None: self._MeSigmaInf = self.mesh.getEdgeInnerProduct( self.curModel.sigmaInf) return self._MeSigmaInf @property def MeI(self): if getattr(self, '_MeI', None) is None: self._MeI = self.mesh.getEdgeInnerProduct(invMat=True) return self._MeI def MeAc(self, dt): gamma = self.getGamma(dt) val = self.curModel.sigmaInf - gamma return self.mesh.getEdgeInnerProduct(val) MeAcI = lambda self, dt: sdInv(self.MeAc(dt)) def MeCnk(self, n, k): tn = self.times[n] tk = self.times[k] val = self.sigmaHat(tn - tk) return self.mesh.getEdgeInnerProduct(val) _nJpLast = None _JpLast = None def getJp(self, tInd, F): """ Computation of polarization currents """ # It calls twice !!! # a) getRHS # b) updateFields if tInd == self._nJpLast: # print ">> Curious when self._nJpLast is used:", self._nJpLast jp = self._JpLast else: dt = self.timeSteps[tInd] kappa = self.getKappa(dt) MeK = self.mesh.getEdgeInnerProduct(kappa) jp = MeK * F[:, 'e', tInd] for k in range(tInd): dt = self.timeSteps[k] jp += (dt / 2) * self.MeCnk(tInd + 1, k) * F[:, 'e', k + 1] jp += (dt / 2) * self.MeCnk(tInd + 1, k + 1) * F[:, 'e', k + 1] self._nJpLast = tInd self._JpLast = jp return jp def getA(self, tInd): """ :param int tInd: Time index :rtype: scipy.sparse.csr_matrix :return: A """ dt = self.timeSteps[tInd] return self.MfMui * self.mesh.edgeCurl * self.MeAcI( dt) * self.mesh.edgeCurl.T * self.MfMui + self.MfMui * (1.0 / dt) def getRHS(self, tInd, F): dt = self.timeSteps[tInd] B_last = F[:, 'b', tInd] RHS = self.MfMui*(1/dt)*B_last \ - self.MfMui*self.mesh.edgeCurl*self.MeAcI(dt)*self.getJp(tInd, F) if self.waveformType != "STEPOFF": RHS += self.MfMui * self.mesh.edgeCurl * self.MeAcI( dt) * self.MeS * self.current[tInd + 1] return RHS def updateFields(self, bn, tInd, F): dt = self.timeSteps[tInd] jp = self.getJp(tInd, F) en = self.MeAcI(dt)*self.mesh.edgeCurl.T*self.MfMui*bn \ + self.MeAcI(dt)*jp if self.waveformType != "STEPOFF": en -= self.MeAcI(dt) * self.MeS * self.current[tInd + 1] jn = self.MeI * (self.MeAc(dt) * en - jp) return en, jn def getKappa(self, dt): setc = np.c_[self.curModel.sigmaInf, self.curModel.eta, self.curModel.tau, self.curModel.c] unqEtc, uETCind, invInd = uniqueRows(setc) kappaVals = [] for (sv, ev, tv, cv) in unqEtc: if ev == 0: kappaVal = 0. elif cv == 1.: kappaVal = (dt / 2.) * sv * ev / ((1. - ev) * tv) else: m, d = self.getMD(dt, sv, ev, tv, cv) kappaVal = (m * dt**cv) / (cv + 1) + d * dt / 2 kappaVals.append(kappaVal) kappa = np.array(kappaVals)[invInd] return kappa def getGamma(self, dt): setc = np.c_[self.curModel.sigmaInf, self.curModel.eta, self.curModel.tau, self.curModel.c] unqEtc, uETCind, invInd = uniqueRows(setc) gammaVals = [] for (sv, ev, tv, cv) in unqEtc: if ev == 0: gammaVal = 0. elif cv == 1.: gammaVal = (dt / 2.) * sv * ev / ((1. - ev) * tv) else: m, d = self.getMD(dt, sv, ev, tv, cv) gammaVal = (m * dt**cv) / (cv * (cv + 1)) + d * dt / 2. gammaVals.append(gammaVal) gamma = np.array(gammaVals)[invInd] return gamma def getMD(self, dt, sv, ev, tv, cv): def CCTF(t, sigmaInf, eta, tau, c): F = lambda frq: (1j * 2 * np.pi * frq) * ColeCole( frq, sigmaInf=sigmaInf, eta=eta, tau=tau, c=c) return transFilt(F, t) t = np.r_[1e-20, dt] y = CCTF(t, sv, ev, tv, cv) x = t**(cv - 1) m = (y[0] - y[1]) / (x[0] - x[1]) d = y[1] - m * x[1] return m, d