Updated 1D_ps problem. Working on testing derivatives, only to 1st order at the commit

This commit is contained in:
GudniRos
2015-06-19 09:54:53 -07:00
parent 422911a95f
commit be0d269af1
7 changed files with 261 additions and 59 deletions
+112 -2
View File
@@ -10,15 +10,125 @@ import numpy as np
import multiprocessing, sys, time
# class eForm_ps(BaseMTProblem):
class eForm_psField(BaseMTProblem):
"""
A MT problem soving a e formulation and primary/secondary fields decomposion.
Solves the equation
"""
# From FDEMproblem: Used to project the fields. Currently not used for MTproblem.
_fieldType = 'e'
_eqLocs = 'EF'
def __init__(self, mesh, **kwargs):
BaseMTProblem.__init__(self, mesh, **kwargs)
def getA(self, freq,):
"""
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
"""
Mmui = self.mesh.getEdgeInnerProduct(1.0/mu_0)
Msig = self.mesh.getFaceInnerProduct(self.curModel.sigma)
# 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
# Mmui = self.MfMui
# Msig = self.MeSigma
C = self.mesh.nodalGrad
# Make A
A = C.T*Mmui*C + 1j*omega(freq)*Msig
# Either return full or only the inner part of A
return A
def getADeriv_m(self, freq, u, v, adjoint=False):
"""
The derivative of A wrt sigma
"""
dsig_dm = self.curModel.sigmaDeriv
dMf_dsig = self.mesh.getFaceInnerProductDeriv(self.curModel.sigma)(u) * self.curModel.sigmaDeriv
if adjoint:
return 1j * omega(freq) * ( dsig_dm.T * ( dMf_dsig.T * v ) )
return 1j * omega(freq) * ( dMf_dsig * ( dsig_dm * v ) )
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 getRHSderiv_m(self, freq, u, v, adjoint=False):
"""
The derivative of the RHS wrt sigma
"""
Src = self.survey.getSrcByFreq(freq)[0]
S_eDeriv = Src.S_eDeriv(self, v, adjoint)
return -1j * omega(freq) * S_eDeriv
def fields(self, m):
'''
Function to calculate all the fields for the model m.
:param np.ndarray (nC,) m: Conductivity model
'''
# Set the current model
self.curModel = m
F = FieldsMT(self.mesh, self.survey)
for freq in self.survey.freqs:
if self.verbose:
startTime = time.time()
print 'Starting work for {:.3e}'.format(freq)
sys.stdout.flush()
A = self.getA(freq)
rhs = self.getRHS(freq)
Ainv = self.Solver(A, **self.solverOpts)
e_s = Ainv * rhs
# Store the fields
Src = self.survey.getSrcByFreq(freq)[0]
# Calculate total e
e = Src.ePrimary(self) + e_s
# Store the fields
# NOTE: only store
F[Src, 'e_1d'] = e[:,1] # Only storing the yx polarization as 1d
# F[Src, 'e_py'] = 0*e[:,0]
# Note curl e = -iwb so b = -curl e /iw
b = -( self.mesh.nodalGrad * e )/( 1j*omega(freq) )
# F[Src, 'b_px'] = 0*b[:,0]
F[Src, 'b_1d'] = b[:,1]
if self.verbose:
print 'Ran for {:f} seconds'.format(time.time()-startTime)
sys.stdout.flush()
return F
class eForm_TotalField(BaseMTProblem):
"""
A MT problem solving a e formulation and a primary/secondary fields decompostion.
A MT problem solving a e formulation and a Total bondary domain decompostion.
Solves the equation:
Math:
"""