def getADeriv_mu(self, freq, u, v, adjoint=False): MeMuDeriv = self.MeMuDeriv(u) if adjoint is True: return 1j*omega(freq) * (MeMuDeriv.T * v) return 1j*omega(freq) * (MeMuDeriv * v)
def _hSecondary(self, jSolution, srcList): h = self._MeMuI * (self._edgeCurl.T * (self._MfRho * jSolution)) for i, src in enumerate(srcList): h[:, i] *= -1.0 / (1j * omega(src.freq)) S_m, _ = src.eval(self.prob) h[:, i] = h[:, i] + 1.0 / (1j * omega(src.freq)) * self._MeMuI * (S_m) return h
def getRHSDeriv(self, freq, src, v, adjoint=False): """ Derivative of the right hand side with respect to the model :param float freq: frequency :param SimPEG.EM.FDEM.Src src: FDEM source :param numpy.ndarray v: vector to take product with :param bool adjoint: adjoint? :rtype: numpy.ndarray :return: product of rhs deriv with a vector """ C = self.mesh.edgeCurl MeMuI = self.MeMuI S_mDeriv, S_eDeriv = src.evalDeriv(self, adjoint=adjoint) if adjoint: if self._makeASymmetric: MfRho = self.MfRho v = MfRho*v return S_mDeriv(MeMuI.T * (C.T * v)) - 1j * omega(freq) * S_eDeriv(v) else: RHSDeriv = C * (MeMuI * S_mDeriv(v)) - 1j * omega(freq) * S_eDeriv(v) if self._makeASymmetric: MfRho = self.MfRho return MfRho.T * RHSDeriv return RHSDeriv
def getADeriv_sigma(self, freq, u, v, adjoint=False): """ Product of the derivative of our system matrix with respect to the conductivity model and a vector .. math :: \\frac{\mathbf{A}(\mathbf{m}) \mathbf{v}}{d \mathbf{m}_{\\sigma}} = i \omega \\frac{d \mathbf{M^e_{\sigma}}(\mathbf{u})\mathbf{v} }{d\mathbf{m}} :param float freq: frequency :param numpy.ndarray u: solution vector (nE,) :param numpy.ndarray v: vector to take prodct with (nP,) or (nD,) for adjoint :param bool adjoint: adjoint? :rtype: numpy.ndarray :return: derivative of the system matrix times a vector (nP,) or adjoint (nD,) """ dMe_dsig = self.MeSigmaDeriv(u) if adjoint: return 1j * omega(freq) * ( dMe_dsig.T * v ) return 1j * omega(freq) * ( dMe_dsig * v )
def _hSecondaryDeriv_m(self, src, v, adjoint=False): """ Derivative of the secondary magnetic field with respect to the inversion model :param SimPEG.EM.FDEM.Src src: source :param numpy.ndarray v: vector to take product with :param bool adjoint: adjoint? :rtype: numpy.ndarray :return: product of the derivative of the secondary magnetic field with respect to the model with a vector """ jSolution = self[[src],'jSolution'] MeMuI = self._MeMuI C = self._edgeCurl MfRho = self._MfRho MfRhoDeriv = self._MfRhoDeriv Me = self._Me if not adjoint: hDeriv_m = -1./(1j*omega(src.freq)) * MeMuI * (C.T * (MfRhoDeriv(jSolution)*v ) ) elif adjoint: hDeriv_m = -1./(1j*omega(src.freq)) * MfRhoDeriv(jSolution).T * ( C * (MeMuI.T * v ) ) S_mDeriv,_ = src.evalDeriv(self.prob, adjoint = adjoint) if not adjoint: S_mDeriv = S_mDeriv(v) hDeriv_m = hDeriv_m + 1./(1j*omega(src.freq)) * MeMuI * (Me * S_mDeriv) elif adjoint: S_mDeriv = S_mDeriv(Me.T * (MeMuI.T * v)) hDeriv_m = hDeriv_m + 1./(1j*omega(src.freq)) * S_mDeriv return hDeriv_m
def getADeriv_mu(self, freq, u, v, adjoint=False): MeMuDeriv = self.MeMuDeriv(u) if adjoint is True: return 1j * omega(freq) * (MeMuDeriv.T * v) return 1j * omega(freq) * (MeMuDeriv * v)
def _bSecondary(self, eSolution, srcList): C = self._edgeCurl b = C * eSolution for i, src in enumerate(srcList): b[:, i] *= -1.0 / (1j * omega(src.freq)) S_m, _ = src.eval(self.prob) b[:, i] = b[:, i] + 1.0 / (1j * omega(src.freq)) * S_m return b
def getADeriv_m(self, freq, u, v, adjoint=False): dsig_dm = self.curModel.sigmaDeriv dMe_dsig = self.MeSigmaDeriv(u) if adjoint: return 1j * omega(freq) * ( dMe_dsig.T * v ) return 1j * omega(freq) * ( dMe_dsig * v )
def getRHSDeriv_m(self, freq, src, v, adjoint=False): C = self.mesh.edgeCurl MfMui = self.MfMui S_mDeriv, S_eDeriv = src.evalDeriv(self, adjoint) if adjoint: dRHS = MfMui * (C * v) return S_mDeriv(dRHS) - 1j * omega(freq) * S_eDeriv(v) else: return C.T * (MfMui * S_mDeriv(v)) -1j * omega(freq) * S_eDeriv(v)
def _hDeriv_u(self, src, du_dm_v, adjoint=False): """ Derivative of the magnetic field with respect to the thing we solved for :param SimPEG.EM.FDEM.Src src: source :param numpy.ndarray du_dm_v: vector to take product with :param bool adjoint: adjoint? :rtype: numpy.ndarray :return: product of the derivative of the magnetic field with respect to the field we solved for with a vector """ if adjoint: return -1./(1j*omega(src.freq)) * self._MfRho.T * (self._edgeCurl * ( self._MeMuI.T * du_dm_v)) return -1./(1j*omega(src.freq)) * self._MeMuI * (self._edgeCurl.T * (self._MfRho * du_dm_v) )
def _b_pyDeriv_u(self, src, du_dm_v, adjoint=False): """ Derivative of b_py with wrt u :param SimPEG.NSEM.src src: The source of the problem :param numpy.ndarray du_dm_v: vector to take product with. Size (nF,) when adjoint=True, (nU,) when adjoint=False :param bool adjoint: adjoint? :rtype: numpy.ndarray :return: The calculated derivative, size (nU,) when adjoint=True. (nF,) when adjoint=False """ # Primary does not depend on u C = sp.hstack((Utils.spzeros(self.mesh.nF, self.mesh.nE), self.mesh.edgeCurl)) # This works for adjoint = None if adjoint: return - 1./(1j*omega(src.freq)) * (C.T * du_dm_v) return - 1./(1j*omega(src.freq)) * (C * du_dm_v)
def getADeriv_m(self, freq, u, v, adjoint=False): """ The derivative of A wrt sigma """ dsig_dm = self.curModel.sigmaDeriv MeMui = self.MeMui # u_src = u['e_1dSolution'] dMfSigma_dm = self.mesh.getFaceInnerProductDeriv(self.curModel.sigma)(u_src) * self.curModel.sigmaDeriv if adjoint: return 1j * omega(freq) * ( dMfSigma_dm.T * v ) # Note: output has to be nN/nF, not nC/nE. # v should be nC return 1j * omega(freq) * ( dMfSigma_dm * v )
def _bSecondaryDeriv_u(self, src, v, adjoint = False): """ Derivative of the secondary magnetic flux density with respect to the thing we solved for :param SimPEG.EM.FDEM.Src src: source :param numpy.ndarray v: vector to take product with :param bool adjoint: adjoint? :rtype: numpy.ndarray :return: product of the derivative of the secondary magnetic flux density with respect to the field we solved for with a vector """ C = self._edgeCurl if adjoint: return - 1./(1j*omega(src.freq)) * (C.T * v) return - 1./(1j*omega(src.freq)) * (C * v)
def _b_pyDeriv_u(self, src, du_dm_v, adjoint=False): """ Derivative of b_py with wrt u :param SimPEG.NSEM.src src: The source of the problem :param numpy.ndarray du_dm_v: vector to take product with. Size (nF,) when adjoint=True, (nU,) when adjoint=False :param bool adjoint: adjoint? :rtype: numpy.ndarray :return: The calculated derivative, size (nU,) when adjoint=True. (nF,) when adjoint=False """ # Primary does not depend on u C = sp.hstack((Utils.spzeros(self.mesh.nF, self.mesh.nE), self.mesh.edgeCurl)) # This works for adjoint = None if adjoint: return -1. / (1j * omega(src.freq)) * (C.T * du_dm_v) return -1. / (1j * omega(src.freq)) * (C * du_dm_v)
def _bDeriv_u(self, src, du_dm_v, adjoint=False): """ Derivative of the magnetic flux density with respect to the thing we solved for :param SimPEG.EM.FDEM.Src src: source :param numpy.ndarray du_dm_v: vector to take product with :param bool adjoint: adjoint? :rtype: numpy.ndarray :return: product of the derivative of the magnetic flux density with respect to the field we solved for with a vector """ n = int(self._aveF2CCV.shape[0] / self._nC) # number of components VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) if adjoint: return -1./(1j*omega(src.freq)) * self._MfRho.T * ( self._edgeCurl * ( self._aveE2CCV.T * (VI.T * du_dm_v) ) ) return -1./(1j*omega(src.freq)) * VI * (self._aveE2CCV * (self._edgeCurl.T * (self._MfRho * du_dm_v)))
def getA(self, freq, full=False): """ Function to get the A matrix. :param float freq: Frequency :param logic full: Return full A or the inner part :rtype: scipy.sparse.csr_matrix :return: A """ MeMui = self.MeMui MfSigma = self.MfSigma # Note: need to use the code above since in the 1D problem I want # e to live on Faces(nodes) and h on edges(cells). Might need to rethink this # Possible that _fieldType and _eqLocs can fix this # MeMui = self.MfMui # MfSigma = self.MfSigma C = self.mesh.nodalGrad # Make A A = C.T * MeMui * C + 1j * omega(freq) * MfSigma # Either return full or only the inner part of A if full: return A else: return A[1:-1, 1:-1]
def _hSecondary(self, jSolution, srcList): """ Secondary magnetic field from bSolution :param numpy.ndarray jSolution: field we solved for :param list srcList: list of sources :rtype: numpy.ndarray :return: secondary magnetic field """ h = self._MeMuI * (self._edgeCurl.T * (self._MfRho * jSolution) ) for i, src in enumerate(srcList): h[:,i] *= -1./(1j*omega(src.freq)) S_m,_ = src.eval(self.prob) h[:,i] = h[:,i]+ 1./(1j*omega(src.freq)) * self._MeMuI * (S_m) return h
def getA(self, freq, full=False): """ Function to get the A matrix. :param float freq: Frequency :param logic full: Return full A or the inner part :rtype: scipy.sparse.csr_matrix :return: A """ MeMui = self.MeMui MfSigma = self.MfSigma # Note: need to use the code above since in the 1D problem I want # e to live on Faces(nodes) and h on edges(cells). Might need to rethink this # Possible that _fieldType and _eqLocs can fix this # MeMui = self.MfMui # MfSigma = self.MfSigma C = self.mesh.nodalGrad # Make A A = C.T*MeMui*C + 1j*omega(freq)*MfSigma # Either return full or only the inner part of A if full: return A else: return A[1:-1,1:-1]
def getADeriv_m(self, freq, u, v, adjoint=False): """ The derivative of A wrt sigma """ dsig_dm = self.curModel.sigmaDeriv MeMui = self.MeMui # u_src = u['e_1dSolution'] dMfSigma_dm = self.mesh.getFaceInnerProductDeriv( self.curModel.sigma)(u_src) * self.curModel.sigmaDeriv if adjoint: return 1j * omega(freq) * (dMfSigma_dm.T * v) # Note: output has to be nN/nF, not nC/nE. # v should be nC return 1j * omega(freq) * (dMfSigma_dm * v)
def _bDeriv_u(self, src, du_dm_v, adjoint=False): """ Derivative of the magnetic flux density with respect to the solution :param SimPEG.EM.FDEM.Src src: source :param numpy.ndarray du_dm_v: vector to take product with :param bool adjoint: adjoint? :rtype: numpy.ndarray :return: product of the derivative of the magnetic flux density with respect to the field we solved for with a vector """ # bPrimary: no model depenency C = self.mesh.nodalGrad if adjoint: bSecondaryDeriv_u = -1. / (1j * omega(src.freq)) * (C.T * du_dm_v) else: bSecondaryDeriv_u = -1. / (1j * omega(src.freq)) * (C * du_dm_v) return bSecondaryDeriv_u
def getRHSDeriv_m(self, freq, v, adjoint=False): """ The derivative of the RHS wrt sigma """ Src = self.survey.getSrcByFreq(freq)[0] S_eDeriv = Src.S_eDeriv_m(self, v, adjoint) return -1j * omega(freq) * S_eDeriv
def getRHSDeriv_m(self, freq, v, adjoint=False): """ The derivative of the RHS with respect to sigma """ Src = self.survey.getSrcByFreq(freq)[0] S_eDeriv = Src.S_eDeriv_m(self, v, adjoint) return -1j * omega(freq) * S_eDeriv
def getRHSDeriv(self, freq, src, v, adjoint=False): """ Derivative of the Right-hand side with respect to the model. This includes calls to derivatives in the sources """ C = self.mesh.edgeCurl MfMui = self.MfMui s_m, s_e = self.getSourceTerm(freq) s_mDeriv, s_eDeriv = src.evalDeriv(self, adjoint=adjoint) MfMuiDeriv = self.MfMuiDeriv(s_m) if adjoint: return (s_mDeriv(MfMui * (C * v)) + MfMuiDeriv.T * (C * v) - 1j * omega(freq) * s_eDeriv(v)) return (C.T * (MfMui * s_mDeriv(v) + MfMuiDeriv * v) - 1j * omega(freq) * s_eDeriv(v))
def _bSecondary(self, eSolution, srcList): """ Secondary magnetic flux density from eSolution :param numpy.ndarray eSolution: field we solved for :param list srcList: list of sources :rtype: numpy.ndarray :return: secondary magnetic flux density """ C = self._edgeCurl b = (C * eSolution) for i, src in enumerate(srcList): b[:,i] *= - 1./(1j*omega(src.freq)) S_m, _ = src.eval(self.prob) b[:,i] = b[:,i]+ 1./(1j*omega(src.freq)) * S_m return b
def _bDeriv_u(self, src, du_dm_v, adjoint=False): """ Derivative of the magnetic flux density with respect to the solution :param SimPEG.EM.FDEM.Src src: source :param numpy.ndarray du_dm_v: vector to take product with :param bool adjoint: adjoint? :rtype: numpy.ndarray :return: product of the derivative of the magnetic flux density with respect to the field we solved for with a vector """ # bPrimary: no model depenency C = self.mesh.nodalGrad if adjoint: bSecondaryDeriv_u = - 1./(1j*omega(src.freq)) * (C.T * du_dm_v) else: bSecondaryDeriv_u = - 1./(1j*omega(src.freq)) * (C * du_dm_v) return bSecondaryDeriv_u
def getRHSDeriv_m(self, freq, src, v, adjoint=False): C = self.mesh.edgeCurl MeMuI = self.MeMuI S_mDeriv, S_eDeriv = src.evalDeriv(self, adjoint) if adjoint: if self._makeASymmetric: MfRho = self.MfRho v = MfRho*v return S_mDeriv(MeMuI.T * (C.T * v)) - 1j * omega(freq) * S_eDeriv(v) else: RHSDeriv = C * (MeMuI * S_mDeriv(v)) - 1j * omega(freq) * S_eDeriv(v) if self._makeASymmetric: MfRho = self.MfRho return MfRho.T * RHSDeriv return RHSDeriv
def bPrimary(self, problem): # Project ePrimary to bPrimary # Satisfies the primary(background) field conditions if problem.mesh.dim == 1: C = problem.mesh.nodalGrad elif problem.mesh.dim == 3: C = problem.mesh.edgeCurl bBG_bp = (- C * self.ePrimary(problem)) * (1 / (1j * omega(self.freq))) return bBG_bp
def _bDeriv_m(self, src, v, adjoint=False): """ Derivative of the magnetic flux density with respect to the inversion model :param SimPEG.EM.FDEM.Src src: source :param numpy.ndarray v: vector to take product with :param bool adjoint: adjoint? :rtype: numpy.ndarray :return: product of the derivative of the magnetic flux density with respect to the model with a vector """ jSolution = self[src,'jSolution'] n = int(self._aveE2CCV.shape[0] / self._nC) # number of components VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) s_mDeriv,_ = src.evalDeriv(self.prob, adjoint = adjoint) if adjoint: v = self._aveE2CCV.T * ( VI.T * v) return 1./(1j * omega(src.freq)) * ( s_mDeriv(v) - self._MfRhoDeriv(jSolution).T * (self._edgeCurl * v )) return 1./(1j * omega(src.freq)) * VI * (self._aveE2CCV * ( s_mDeriv(v) - self._edgeCurl.T * ( self._MfRhoDeriv(jSolution) * v ) ) )
def getRHSDeriv(self, freq, src, v, adjoint=False): """ Derivative of the right hand side with respect to the model :param float freq: frequency :param SimPEG.EM.FDEM.SrcFDEM.BaseFDEMSrc src: FDEM source :param numpy.ndarray v: vector to take product with :param bool adjoint: adjoint? :rtype: numpy.ndarray :return: product of rhs deriv with a vector """ # RHS = C * (MeMuI * s_m) - 1j * omega(freq) * s_e # if self._makeASymmetric is True: # MfRho = self.MfRho # return MfRho.T*RHS C = self.mesh.edgeCurl MeMuI = self.MeMuI MeMuIDeriv = self.MeMuIDeriv s_mDeriv, s_eDeriv = src.evalDeriv(self, adjoint=adjoint) s_m, _ = self.getSourceTerm(freq) if adjoint: if self._makeASymmetric: MfRho = self.MfRho v = MfRho*v CTv = (C.T * v) return ( s_mDeriv(MeMuI.T * CTv) + MeMuIDeriv(s_m).T * CTv - 1j * omega(freq) * s_eDeriv(v) ) else: RHSDeriv = ( C * (MeMuI * s_mDeriv(v) + MeMuIDeriv(s_m) * v) - 1j * omega(freq) * s_eDeriv(v) ) if self._makeASymmetric: MfRho = self.MfRho return MfRho.T * RHSDeriv return RHSDeriv
def _bSecondary(self, eSolution, srcList): C = self.mesh.nodalGrad b = (C * eSolution) for i, src in enumerate(srcList): b[:,i] *= - 1./(1j*omega(src.freq)) # There is no magnetic source in the MT problem # S_m, _ = src.eval(self.survey.prob) # if S_m is not None: # b[:,i] += 1./(1j*omega(src.freq)) * S_m return b
def getRHS(self, freq): """ Function to return the right hand side for the system. :param float freq: Frequency :rtype: numpy.ndarray (nF, 1), numpy.ndarray (nF, 1) :return: RHS for 1 polarizations, primary fields """ # Get sources for the frequncy(polarizations) Src = self.survey.getSrcByFreq(freq)[0] S_e = Src.S_e(self) return -1j * omega(freq) * S_e
def _hSecondaryDeriv_m(self, src, v, adjoint=False): jSolution = self[[src], "jSolution"] MeMuI = self._MeMuI C = self._edgeCurl MfRho = self._MfRho MfRhoDeriv = self._MfRhoDeriv Me = self._Me if not adjoint: hDeriv_m = -1.0 / (1j * omega(src.freq)) * MeMuI * (C.T * (MfRhoDeriv(jSolution) * v)) elif adjoint: hDeriv_m = -1.0 / (1j * omega(src.freq)) * MfRhoDeriv(jSolution).T * (C * (MeMuI.T * v)) S_mDeriv, _ = src.evalDeriv(self.prob, adjoint) if not adjoint: S_mDeriv = S_mDeriv(v) hDeriv_m = hDeriv_m + 1.0 / (1j * omega(src.freq)) * MeMuI * (Me * S_mDeriv) elif adjoint: S_mDeriv = S_mDeriv(Me.T * (MeMuI.T * v)) hDeriv_m = hDeriv_m + 1.0 / (1j * omega(src.freq)) * S_mDeriv return hDeriv_m
def getRHSDeriv(self, freq, src, v, adjoint=False): """ Derivative of the right hand side with respect to the model :param float freq: frequency :param SimPEG.EM.FDEM.Src src: FDEM source :param numpy.ndarray v: vector to take product with :param bool adjoint: adjoint? :rtype: numpy.ndarray :return: product of rhs deriv with a vector """ C = self.mesh.edgeCurl MfMui = self.MfMui S_mDeriv, S_eDeriv = src.evalDeriv(self, adjoint=adjoint) if adjoint: dRHS = MfMui * (C * v) return S_mDeriv(dRHS) - 1j * omega(freq) * S_eDeriv(v) else: return C.T * (MfMui * S_mDeriv(v)) -1j * omega(freq) * S_eDeriv(v)
def s_m(self, prob): """ The magnetic source term :param BaseFDEMProblem prob: FDEM problem :rtype: numpy.ndarray :return: primary magnetic field """ b_p = self.bPrimary(prob) if prob._formulation is 'HJ': b_p = prob.Me * b_p return -1j * omega(self.freq) * b_p
def getRHSDeriv(self, freq, src, v, adjoint=False): """ Derivative of the Right-hand side with respect to the model. This includes calls to derivatives in the sources """ C = self.mesh.edgeCurl MfMui = self.MfMui s_m, s_e = self.getSourceTerm(freq) s_mDeriv, s_eDeriv = src.evalDeriv(self, adjoint=adjoint) MfMuiDeriv = self.MfMuiDeriv(s_m) if adjoint: return ( s_mDeriv(MfMui * (C * v)) + MfMuiDeriv.T * (C * v) - 1j * omega(freq) * s_eDeriv(v) ) return ( C.T * (MfMui * s_mDeriv(v) + MfMuiDeriv * v) - 1j * omega(freq) * s_eDeriv(v) )
def getA(self, freq): """ Function to get the A system. :param float freq: Frequency :rtype: scipy.sparse.csr_matrix :return: A """ Mmui = self.MfMui Msig = self.MeSigma C = self.mesh.edgeCurl return C.T * Mmui * C + 1j * omega(freq) * Msig
def _bSecondaryDeriv_m(self, src, v, adjoint = False): """ Derivative of the secondary magnetic flux density with respect to the inversion model. :param SimPEG.EM.FDEM.Src src: source :param numpy.ndarray v: vector to take product with :param bool adjoint: adjoint? :rtype: numpy.ndarray :return: product of the secondary magnetic flux density derivative with respect to the inversion model with a vector """ S_mDeriv, _ = src.evalDeriv(self.prob, v, adjoint) return 1./(1j * omega(src.freq)) * S_mDeriv
def getADeriv_m(self, freq, u, v, adjoint=False): """ Calculate the derivative of A wrt m. """ # This considers both polarizations and returns a nE,2 matrix for each polarization if adjoint: dMe_dsigV = sp.hstack(( self.MeSigmaDeriv( u['e_pxSolution'] ).T, self.MeSigmaDeriv(u['e_pySolution'] ).T ))*v else: # Need a nE,2 matrix to be returned dMe_dsigV = np.hstack(( mkvc(self.MeSigmaDeriv( u['e_pxSolution'] )*v,2), mkvc( self.MeSigmaDeriv(u['e_pySolution'] )*v,2) )) return 1j * omega(freq) * dMe_dsigV
def getA(self, freq): """ Function to get the A system. :param float freq: Frequency :rtype: scipy.sparse.csr_matrix :return: A """ Mmui = self.MfMui Msig = self.MeSigma C = self.mesh.edgeCurl return C.T*Mmui*C + 1j*omega(freq)*Msig
def _b_pySecondary(self, e_pySolution, srcList): """ py polarization of secondary magnetic flux from source :param numpy.ndarray e_pySolution: py polarization that was solved for :param list srcList: list of sources :rtype: numpy.ndarray :return: secondary magnetic flux as defined by the sources """ C = self.mesh.edgeCurl b = (C * e_pySolution) for i, src in enumerate(srcList): b[:, i] *= -1. / (1j * omega(src.freq)) return b
def _bSecondary(self, eSolution, srcList): """ Primary magnetic flux density from source :param numpy.ndarray eSolution: field we solved for :param list srcList: list of sources :rtype: numpy.ndarray :return: primary magnetic flux density as defined by the sources """ C = self.mesh.nodalGrad b = (C * eSolution) for i, src in enumerate(srcList): b[:, i] *= -1. / (1j * omega(src.freq)) return b
def getADeriv_m(self, freq, u, v, adjoint=False): """ Calculate the derivative of A wrt m. """ # This considers both polarizations and returns a nE,2 matrix for each polarization if adjoint: dMe_dsigV = sp.hstack((self.MeSigmaDeriv(u['e_pxSolution']).T, self.MeSigmaDeriv(u['e_pySolution']).T)) * v else: # Need a nE,2 matrix to be returned dMe_dsigV = np.hstack( (mkvc(self.MeSigmaDeriv(u['e_pxSolution']) * v, 2), mkvc(self.MeSigmaDeriv(u['e_pySolution']) * v, 2))) return 1j * omega(freq) * dMe_dsigV
def getA(self, freq): """ System matrix .. math :: \mathbf{A} = \mathbf{C}^{\\top} \mathbf{M_{\mu^{-1}}^f} \mathbf{C} + i \omega \mathbf{M^e_{\sigma}} :param float freq: Frequency :rtype: scipy.sparse.csr_matrix :return: A """ MfMui = self.MfMui MeSigma = self.MeSigma C = self.mesh.edgeCurl return C.T*MfMui*C + 1j*omega(freq)*MeSigma
def getRHS(self, freq): """ Right hand side for the system .. math :: \mathbf{RHS} = \mathbf{C}^{\\top} \mathbf{M_{\mu^{-1}}^f}\mathbf{s_m} -i\omega\mathbf{M_e}\mathbf{s_e} :param float freq: Frequency :rtype: numpy.ndarray :return: RHS (nE, nSrc) """ S_m, S_e = self.getSourceTerm(freq) C = self.mesh.edgeCurl MfMui = self.MfMui return C.T * (MfMui * S_m) -1j * omega(freq) * S_e
def getA(self, freq): """ System matrix .. math:: \mathbf{A} = \mathbf{C}^{\\top} \mathbf{M_{\\rho}^f} \mathbf{C} + i \omega \mathbf{M_{\mu}^e} :param float freq: Frequency :rtype: scipy.sparse.csr_matrix :return: A """ MeMu = self.MeMu MfRho = self.MfRho C = self.mesh.edgeCurl return C.T * (MfRho * C) + 1j*omega(freq)*MeMu
def getA(self, freq): """ .. math :: \mathbf{A} = \mathbf{C} \mathbf{M^e_{\sigma}}^{-1} \mathbf{C}^T \mathbf{M_{\mu^{-1}}^f} + i \omega :param float freq: Frequency :rtype: scipy.sparse.csr_matrix :return: A """ MfMui = self.MfMui MeSigmaI = self.MeSigmaI(freq) C = self.mesh.edgeCurl iomega = 1j * omega(freq) * sp.eye(self.mesh.nF) A = C * (MeSigmaI * (C.T * MfMui)) + iomega if self._makeASymmetric is True: return MfMui.T * A return A
def getA(self, freq): """ System matrix .. math :: \\mathbf{A} = \\mathbf{C} \\mathbf{M^e_{\\mu^{-1}}} \\mathbf{C}^{\\top} \\mathbf{M^f_{\\sigma^{-1}}} + i\\omega :param float freq: Frequency :rtype: scipy.sparse.csr_matrix :return: A """ MeMuI = self.MeMuI MfRho = self.MfRho C = self.mesh.edgeCurl iomega = 1j * omega(freq) * sp.eye(self.mesh.nF) A = C * MeMuI * C.T * MfRho + iomega if self._makeASymmetric is True: return MfRho.T*A return A
def getRHS(self, freq): """ Right hand side for the system .. math :: \mathbf{RHS} = \mathbf{C} \mathbf{M_{\mu}^e}^{-1}\mathbf{s_m} -i\omega \mathbf{s_e} :param float freq: Frequency :rtype: numpy.ndarray (nE, nSrc) :return: RHS """ S_m, S_e = self.getSourceTerm(freq) C = self.mesh.edgeCurl MeMuI = self.MeMuI RHS = C * (MeMuI * S_m) - 1j * omega(freq) * S_e if self._makeASymmetric is True: MfRho = self.MfRho return MfRho.T*RHS return RHS
def _b_pySecondaryDeriv_u(self, src, v, adjoint = False): # C = sp.kron(self.mesh.edgeCurl,[[0,0],[0,1]]) C = sp.hstack((Utils.spzeros(self.mesh.nF,self.mesh.nE),self.mesh.edgeCurl)) # This works for adjoint = None if adjoint: return - 1./(1j*omega(src.freq)) * (C.T * v) return - 1./(1j*omega(src.freq)) * (C * v)
def _bSecondaryDeriv_u(self, src, v, adjoint = False): C = self.mesh.nodalGrad if adjoint: return - 1./(1j*omega(src.freq)) * (C.T * v) return - 1./(1j*omega(src.freq)) * (C * v)