def test_Maps(self): nP = 10 m = np.random.rand(2 * nP) wires = Maps.Wires(('sigma', nP), ('mu', nP)) objfct1 = ObjectiveFunction.L2ObjectiveFunction(mapping=wires.sigma) objfct2 = ObjectiveFunction.L2ObjectiveFunction(mapping=wires.mu) objfct3 = objfct1 + objfct2 objfct4 = ObjectiveFunction.L2ObjectiveFunction(nP=nP) self.assertTrue(objfct1.nP == 2 * nP) self.assertTrue(objfct2.nP == 2 * nP) self.assertTrue(objfct3.nP == 2 * nP) # print(objfct1.nP, objfct4.nP, objfct4.W.shape, objfct1.W.shape, m[:nP].shape) self.assertTrue(objfct1(m) == objfct4(m[:nP])) self.assertTrue(objfct2(m) == objfct4(m[nP:])) self.assertTrue(objfct3(m) == objfct1(m) + objfct2(m)) objfct1.test() objfct2.test() objfct3.test()
def setUp(self): cs = 25. hx = [(cs, 0, -1.3), (cs, 21), (cs, 0, 1.3)] hz = [(cs, 0, -1.3), (cs, 20)] mesh = Mesh.TensorMesh([hx, hz], x0="CN") blkind0 = Utils.ModelBuilder.getIndicesSphere(np.r_[-100., -200.], 75., mesh.gridCC) blkind1 = Utils.ModelBuilder.getIndicesSphere(np.r_[100., -200.], 75., mesh.gridCC) sigma = np.ones(mesh.nC) * 1e-2 eta = np.zeros(mesh.nC) tau = np.ones_like(sigma) * 1. eta[blkind0] = 0.1 eta[blkind1] = 0.1 tau[blkind0] = 0.1 tau[blkind1] = 0.1 x = mesh.vectorCCx[(mesh.vectorCCx > -155.) & (mesh.vectorCCx < 155.)] Aloc = np.r_[-200., 0.] Bloc = np.r_[200., 0.] M = Utils.ndgrid(x - 25., np.r_[0.]) N = Utils.ndgrid(x + 25., np.r_[0.]) times = np.arange(10) * 1e-3 + 1e-3 rx = SIP.Rx.Dipole(M, N, times) src = SIP.Src.Dipole([rx], Aloc, Bloc) survey = SIP.Survey([src]) wires = Maps.Wires(('eta', mesh.nC), ('taui', mesh.nC)) problem = SIP.Problem2D_CC(mesh, rho=1. / sigma, etaMap=wires.eta, tauiMap=wires.taui, verbose=False) problem.Solver = Solver problem.pair(survey) mSynth = np.r_[eta, 1. / tau] problem.model = mSynth survey.makeSyntheticData(mSynth) # Now set up the problem to do some minimization dmis = DataMisfit.l2_DataMisfit(survey) reg = Regularization.Tikhonov(mesh) opt = Optimization.InexactGaussNewton(maxIterLS=20, maxIter=10, tolF=1e-6, tolX=1e-6, tolG=1e-6, maxIterCG=6) invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta=1e4) inv = Inversion.BaseInversion(invProb) self.inv = inv self.reg = reg self.p = problem self.mesh = mesh self.m0 = mSynth self.survey = survey self.dmis = dmis
def setup_maps(self, mesh, k_fun, theta_fun): wires = Maps.Wires( ('Ks', mesh.nC), ('A', mesh.nC), ('theta_s', mesh.nC) ) k_fun.KsMap = Maps.ExpMap(nP=mesh.nC) * wires.Ks k_fun.AMap = wires.A theta_fun.theta_sMap = wires.theta_s
def setUp(self, parallel=False): frequency = np.array([900, 7200, 56000], dtype=float) hz = np.r_[1.] n_sounding = 10 dx = 20. hx = np.ones(n_sounding) * dx e = np.ones(n_sounding) mSynth = np.r_[e * np.log(1. / 100.), e * 20] x = np.arange(n_sounding) y = np.zeros_like(x) z = np.ones_like(x) * 30. rx_locations = np.c_[x, y, z] src_locations = np.c_[x, y, z] topo = np.c_[x, y, z - 30.].astype(float) wires = Maps.Wires(('sigma', n_sounding), ('h', n_sounding)) expmap = Maps.ExpMap(nP=n_sounding) sigmaMap = expmap * wires.sigma survey = GlobalEM1DSurveyFD(rx_locations=rx_locations, src_locations=src_locations, frequency=frequency, offset=np.ones_like(frequency) * 8., src_type="VMD", rx_type="ppm", field_type='secondary', topo=topo, half_switch=True) problem = GlobalEM1DProblemFD([], sigmaMap=sigmaMap, hMap=wires.h, hz=hz, parallel=parallel, n_cpu=2) problem.pair(survey) survey.makeSyntheticData(mSynth) # Now set up the problem to do some minimization mesh = Mesh.TensorMesh([int(n_sounding * 2)]) dmis = DataMisfit.l2_DataMisfit(survey) reg = Regularization.Tikhonov(mesh) opt = Optimization.InexactGaussNewton(maxIterLS=20, maxIter=10, tolF=1e-6, tolX=1e-6, tolG=1e-6, maxIterCG=6) invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta=0.) inv = Inversion.BaseInversion(invProb) self.inv = inv self.reg = reg self.p = problem self.mesh = mesh self.m0 = mSynth * 1.2 self.survey = survey self.dmis = dmis
def test_haverkamp_k_m(self): mesh = Mesh.TensorMesh([5]) expmap = Maps.IdentityMap(nP=mesh.nC) wires2 = Maps.Wires(('one', mesh.nC), ('two', mesh.nC)) wires3 = Maps.Wires( ('one', mesh.nC), ('two', mesh.nC), ('three', mesh.nC) ) opts = [ ('Ks', dict(KsMap=expmap), 1), ('A', dict(AMap=expmap), 1), ('gamma', dict(gammaMap=expmap), 1), ('Ks-A', dict(KsMap=expmap*wires2.one, AMap=expmap*wires2.two), 2), ('Ks-gamma', dict(KsMap=expmap*wires2.one, gammaMap=expmap*wires2.two), 2), ('A-gamma', dict(AMap=expmap*wires2.one, gammaMap=expmap*wires2.two), 2), ('Ks-A-gamma', dict( KsMap=expmap*wires3.one, AMap=expmap*wires3.two, gammaMap=expmap*wires3.three), 3), ] u = np.random.randn(mesh.nC) for name, opt, nM in opts: np.random.seed(2) hav = Richards.Empirical.Haverkamp_k(mesh, **opt) def fun(m): hav.model = m return hav(u), hav.derivM(u) print('Haverkamp_k test m deriv: ', name) passed = checkDerivative( fun, np.random.randn(mesh.nC * nM), plotIt=False ) self.assertTrue(passed, True)
def spectral_ip_mappings(mesh, indActive=None, inactive_eta=1e-4, inactive_tau=1e-4, inactive_c=1e-4, is_log_eta=True, is_log_tau=True, is_log_c=True): """ Generates Mappings for Spectral Induced Polarization Problem. Three parameters are required to be input: Chargeability (eta), Time constant (tau), and Frequency dependency (c). If there is no topography (indActive is None), model (m) can be either set to m = np.r_[log(eta), log(tau), log(c)] or m = np.r_[eta, tau, c] When indActive is not None, m is m = np.r_[log(eta[indAcitve]), log(tau[indAcitve]), log(c[indAcitve])] or m = np.r_[eta[indAcitve], tau[indAcitve], c[indAcitve]] or TODO: Illustrate input and output variables """ if indActive is None: indActive = np.ones(mesh.nC, dtype=bool) actmap_eta = Maps.InjectActiveCells(mesh, indActive=indActive, valInactive=inactive_eta) actmap_tau = Maps.InjectActiveCells(mesh, indActive=indActive, valInactive=inactive_tau) actmap_c = Maps.InjectActiveCells(mesh, indActive=indActive, valInactive=inactive_c) wires = Maps.Wires(('eta', indActive.sum()), ('tau', indActive.sum()), ('c', indActive.sum())) if is_log_eta: eta_map = actmap_eta * Maps.ExpMap(nP=actmap_eta.nP) * wires.eta else: eta_map = actmap_eta * wires.eta if is_log_tau: tau_map = actmap_tau * Maps.ExpMap(nP=actmap_tau.nP) * wires.tau else: tau_map = actmap_tau * wires.tau if is_log_c: c_map = actmap_c * Maps.ExpMap(nP=actmap_c.nP) * wires.c else: c_map = actmap_c * wires.c return eta_map, tau_map, c_map, wires
def fit_colecole_with_se(self, eta_cc=0.8, tau_cc=0.003, c_cc=0.6): def ColeColeSeigel(f, sigmaInf, eta, tau, c): w = 2 * np.pi * f return sigmaInf * (1 - eta / (1 + (1j * w * tau)**c)) # Step1: Fit Cole-Cole with Stretched Exponential function time = np.logspace(-6, np.log10(0.01), 41) wt, tbase, omega_int = DigFilter.setFrequency(time) frequency = omega_int / (2 * np.pi) # Cole-Cole parameters siginf = 1. self.eta_cc = eta_cc self.tau_cc = tau_cc self.c_cc = c_cc sigma = ColeColeSeigel(frequency, siginf, eta_cc, tau_cc, c_cc) sigTCole = DigFilter.transFiltImpulse(sigma, wt, tbase, omega_int, time, tol=1e-12) wires = Maps.Wires(('eta', 1), ('tau', 1), ('c', 1)) taumap = Maps.ExpMap(nP=1) * wires.tau survey = SESurvey() dtrue = -sigTCole survey.dobs = dtrue m1D = Mesh.TensorMesh([np.ones(3)]) prob = SEInvImpulseProblem(m1D, etaMap=wires.eta, tauMap=taumap, cMap=wires.c) update_sens = Directives.UpdateSensitivityWeights() prob.time = time prob.pair(survey) m0 = np.r_[eta_cc, np.log(tau_cc), c_cc] perc = 0.05 dmisfitpeta = DataMisfit.l2_DataMisfit(survey) dmisfitpeta.W = 1 / (abs(survey.dobs) * perc) reg = regularization.Simple(m1D) opt = Optimization.ProjectedGNCG(maxIter=10) invProb = InvProblem.BaseInvProblem(dmisfitpeta, reg, opt) # Create an inversion object target = Directives.TargetMisfit() invProb.beta = 0. inv = Inversion.BaseInversion(invProb, directiveList=[target]) reg.mref = 0. * m0 prob.counter = opt.counter = Utils.Counter() opt.LSshorten = 0.5 opt.remember('xc') opt.tolX = 1e-20 opt.tolF = 1e-20 opt.tolG = 1e-20 opt.eps = 1e-20 mopt = inv.run(m0) return mopt
def wires(self): """ wires to hook up maps to sigma, mu :rtype: SimPEG.Maps.Wires """ if getattr(self, '_wires', None) is None: self._wires = Maps.Wires( ('sigma', self.mesh.nC), ('mu', self.mesh.nC) ) return self._wires
def setUp(self): # Obtained SE parameters from fitting mopt = self.fit_colecole_with_se() eta, tau, c = mopt[0], np.exp(mopt[1]), mopt[2] # Step2: Set up EMIP problem and Survey csx, csz, ncx, ncz, npadx, npadz = 6.5, 5., 10, 20, 20, 20 hx = [(csx, ncx), (csx, npadx, 1.3)] hz = [(csz, npadz, -1.3), (csz, ncz), (csz, npadz, 1.3)] mesh = Mesh.CylMesh([hx, 1, hz], '00C') sig_half = 0.1 sigmaInf = np.ones(mesh.nC) * sig_half airind = mesh.gridCC[:, 2] > 0. sigmaInf[airind] = 1e-8 etavec = np.ones(mesh.nC) * eta etavec[airind] = 0. tauvec = np.ones(mesh.nC) * tau cvec = np.ones(mesh.nC) * c wiresEM = Maps.Wires(('sigmaInf', mesh.nC), ('eta', mesh.nC), ('tau', mesh.nC), ('c', mesh.nC)) tauvecmap = Maps.ExpMap(nP=mesh.nC) * wiresEM.tau src_z = 30. rxloc = np.array([0., 0., src_z]) srcloc = np.array([0., 0., src_z]) rx = RxEMIP.Point_dbdt( rxloc, np.logspace(np.log10(1e-5), np.log10(0.009), 51), 'z') src = EM.TDEM.Src.CircularLoop([rx], waveform=EM.TDEM.Src.StepOffWaveform(), loc=srcloc, radius=13.) survey = SurveyEMIP([src]) prb_em = Problem3D_e(mesh, sigmaInfMap=wiresEM.sigmaInf, etaMap=wiresEM.eta, tauMap=tauvecmap, cMap=wiresEM.c) prb_em.verbose = False prb_em.timeSteps = [(1e-06, 5), (2.5e-06, 5), (5e-06, 5), (1e-05, 10), (2e-05, 10), (4e-05, 10), (8e-05, 10), (1.6e-04, 10), (3.2e-04, 20)] prb_em.Solver = PardisoSolver prb_em.pair(survey) m = np.r_[sigmaInf, etavec, np.log(tauvec), cvec] self.survey = survey self.src_z = src_z self.m = m self.sig_half = sig_half self.eta = eta self.tau = tau self.c = c self.time = rx.times
def test_basic(self): mesh = Mesh.TensorMesh([10, 10, 10]) wires = Maps.Wires( ('sigma', mesh.nCz), ('mu_casing', 1), ) model = np.arange(mesh.nCz + 1) assert isinstance(wires.sigma, Maps.Projection) assert wires.nP == mesh.nCz + 1 named_model = wires * model named_model.sigma == model[:mesh.nCz] assert named_model.mu_casing == 10
def setUp(self): time = np.logspace(-3, 0, 21) n_loc = 10 wires = Maps.Wires(('eta', n_loc), ('tau', n_loc), ('c', n_loc)) taumap = Maps.ExpMap(nP=n_loc) * wires.tau etamap = Maps.ExpMap(nP=n_loc) * wires.eta cmap = Maps.ExpMap(nP=n_loc) * wires.c eta0, tau0, c0 = 0.1, 10., 0.5 m0 = np.log(np.r_[eta0 * np.ones(n_loc), tau0 * np.ones(n_loc), c0 * np.ones(n_loc)]) survey = SEMultiSurvey(time=time, locs=np.zeros((n_loc, 3))) m1D = Mesh.TensorMesh([np.ones(int(n_loc * 3))]) prob = SEMultiInvProblem(m1D, etaMap=etamap, tauMap=taumap, cMap=cmap) prob.pair(survey) self.survey = survey self.m0 = m0 self.time = time
def test_mappings_and_cell_weights(self): mesh = Mesh.TensorMesh([8, 7, 6]) m = np.random.rand(2*mesh.nC) v = np.random.rand(2*mesh.nC) cell_weights = np.random.rand(mesh.nC) wires = Maps.Wires(('sigma', mesh.nC), ('mu', mesh.nC)) reg = Regularization.SimpleSmall( mesh, mapping=wires.sigma, cell_weights=cell_weights ) objfct = ObjectiveFunction.L2ObjectiveFunction( W=Utils.sdiag(np.sqrt(cell_weights)), mapping=wires.sigma ) self.assertTrue(reg(m) == objfct(m)) self.assertTrue(np.all(reg.deriv(m) == objfct.deriv(m))) self.assertTrue(np.all(reg.deriv2(m, v=v) == objfct.deriv2(m, v=v)))
def test_mappings(self): mesh = Mesh.TensorMesh([8, 7, 6]) m = np.random.rand(2*mesh.nC) wires = Maps.Wires(('sigma', mesh.nC), ('mu', mesh.nC)) for regType in ['Tikhonov', 'Sparse', 'Simple']: reg1 = getattr(Regularization, regType)(mesh, mapping=wires.sigma) reg2 = getattr(Regularization, regType)(mesh, mapping=wires.mu) reg3 = reg1 + reg2 self.assertTrue(reg1.nP == 2*mesh.nC) self.assertTrue(reg2.nP == 2*mesh.nC) self.assertTrue(reg3.nP == 2*mesh.nC) print(reg3(m), reg1(m), reg2(m)) self.assertTrue(reg3(m) == reg1(m) + reg2(m)) reg1.test(eps=TOL) reg2.test(eps=TOL) reg3.test(eps=TOL)
def setUp(self): time = np.logspace(-3, 0, 21) n_loc = 5 wires = Maps.Wires(('eta', n_loc), ('tau', n_loc), ('c', n_loc)) taumap = Maps.ExpMap(nP=n_loc) * wires.tau etamap = Maps.ExpMap(nP=n_loc) * wires.eta cmap = Maps.ExpMap(nP=n_loc) * wires.c survey = SEMultiSurvey(time=time, locs=np.zeros((n_loc, 3)), n_pulse=0) mesh = Mesh.TensorMesh([np.ones(int(n_loc * 3))]) prob = SEMultiInvProblem(mesh, etaMap=etamap, tauMap=taumap, cMap=cmap) prob.pair(survey) eta0, tau0, c0 = 0.1, 10., 0.5 m0 = np.log(np.r_[eta0 * np.ones(n_loc), tau0 * np.ones(n_loc), c0 * np.ones(n_loc)]) survey.makeSyntheticData(m0) # Now set up the problem to do some minimization dmis = DataMisfit.l2_DataMisfit(survey) reg = regularization.Tikhonov(mesh) opt = Optimization.InexactGaussNewton(maxIterLS=20, maxIter=10, tolF=1e-6, tolX=1e-6, tolG=1e-6, maxIterCG=6) invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta=0.) inv = Inversion.BaseInversion(invProb) self.inv = inv self.reg = reg self.p = prob self.survey = survey self.m0 = m0 self.dmis = dmis self.mesh = mesh
# Build list of indecies for the geounits index = [] for unit in geoUnits: # if unit!=0: index += [mgeo==unit] nC = len(index) # Create active map to go from reduce set to full actvMap = Maps.InjectActiveCells(mesh, actv, -100) # Creat reduced identity map homogMap = Maps.SurjectUnits(index) # Create a wire map for a second model space wires = Maps.Wires(('h**o', nC), ('hetero', len(actv))) # Create Sum map sumMap = Maps.SumMap([homogMap*wires.h**o, wires.hetero]) #%% Run inversion prob = PF.Gravity.GravityIntegral(mesh, rhoMap=sumMap, actInd=actv) survey.pair(prob) #%% # Load weighting file dmis = DataMisfit.l2_DataMisfit(survey) dmis.W = 1./survey.std
def wires(self): if getattr(self, '_wires', None) is None: self._wires = Maps.Wires( ('sigma', self.mesh.nC), ('mu', self.mesh.nC) ) return self._wires
silent=True) prob_amp.model = mstart # Change the survey to xyz components survey_amp.srcField.rxList[0].rxType = 'xyz' # Pair the survey and problem survey_amp.pair(prob_amp) # Data misfit function dmis_amp = DataMisfit.l2_DataMisfit(survey_amp) dmis_amp.W = 1./survey_amp.std # Create a block diagonal regularization wires = Maps.Wires(('p', nC), ('s', nC), ('t', nC)) # Create an amplitude map ampMap = Maps.AmplitudeMap(mesh) # Create a regularization reg_a = Regularization.Sparse(mesh, indActive=actv, mapping=ampMap) reg_a.norms = [0, 1, 1, 1] reg_a.alpha_s = 1e+2 reg_a.alpha_x = 1e+2 reg_a.alpha_y = 1e+2 reg_a.alpha_z = 1e+2 #reg_a.eps_p = 5e-3 #reg_a.eps_q = 5e-3 # Create a regularization
nC = len(index) # Collapse mstart and mref to the median reference values mstart = np.asarray([np.median(mref[mref == unit]) for unit in units]) # Collapse mstart and mref to the median unit values mref = mstart.copy() model_map = Maps.SurjectUnits(index) regularization_map = Maps.IdentityMap(nP=nC) regularization_mesh = Mesh.TensorMesh([nC]) regularization_actv = np.ones(nC, dtype='bool') else: if vector_property: model_map = Maps.IdentityMap(nP=3*nC) regularization_map = Maps.Wires(('p', nC), ('s', nC), ('t', nC)) else: model_map = Maps.IdentityMap(nP=nC) regularization_map = Maps.IdentityMap(nP=nC) regularization_mesh = mesh regularization_actv = activeCells # Create identity map if vector_property: global_weights = np.zeros(3*nC) else: idenMap = Maps.IdentityMap(nP=nC) global_weights = np.zeros(nC) def createLocalProb(meshLocal, local_survey, global_weights, ind):
def setUp(self): np.random.seed(0) H0 = (50000., 90., 0.) # The magnetization is set along a different # direction (induced + remanence) M = np.array([45., 90.]) # Create grid of points for topography # Lets create a simple Gaussian topo # and set the active cells [xx, yy] = np.meshgrid( np.linspace(-200, 200, 50), np.linspace(-200, 200, 50) ) b = 100 A = 50 zz = A*np.exp(-0.5*((xx/b)**2. + (yy/b)**2.)) # We would usually load a topofile topo = np.c_[Utils.mkvc(xx), Utils.mkvc(yy), Utils.mkvc(zz)] # Create and array of observation points xr = np.linspace(-100., 100., 20) yr = np.linspace(-100., 100., 20) X, Y = np.meshgrid(xr, yr) Z = A*np.exp(-0.5*((X/b)**2. + (Y/b)**2.)) + 5 # Create a MAGsurvey xyzLoc = np.c_[Utils.mkvc(X.T), Utils.mkvc(Y.T), Utils.mkvc(Z.T)] rxLoc = PF.BaseMag.RxObs(xyzLoc) srcField = PF.BaseMag.SrcField([rxLoc], param=H0) survey = PF.BaseMag.LinearSurvey(srcField) # Create a mesh h = [5, 5, 5] padDist = np.ones((3, 2)) * 100 nCpad = [2, 4, 2] # Get extent of points limx = np.r_[topo[:, 0].max(), topo[:, 0].min()] limy = np.r_[topo[:, 1].max(), topo[:, 1].min()] limz = np.r_[topo[:, 2].max(), topo[:, 2].min()] # Get center of the mesh midX = np.mean(limx) midY = np.mean(limy) midZ = np.mean(limz) nCx = int(limx[0]-limx[1]) / h[0] nCy = int(limy[0]-limy[1]) / h[1] nCz = int(limz[0]-limz[1]+int(np.min(np.r_[nCx, nCy])/3)) / h[2] # Figure out full extent required from input extent = np.max(np.r_[nCx * h[0] + padDist[0, :].sum(), nCy * h[1] + padDist[1, :].sum(), nCz * h[2] + padDist[2, :].sum()]) maxLevel = int(np.log2(extent/h[0]))+1 # Number of cells at the small octree level nCx, nCy, nCz = 2**(maxLevel), 2**(maxLevel), 2**(maxLevel) # Define the mesh and origin # For now cubic cells mesh = Mesh.TreeMesh([np.ones(nCx)*h[0], np.ones(nCx)*h[1], np.ones(nCx)*h[2]]) # Set origin mesh.x0 = np.r_[ -nCx*h[0]/2.+midX, -nCy*h[1]/2.+midY, -nCz*h[2]/2.+midZ ] # Refine the mesh around topography # Get extent of points F = NearestNDInterpolator(topo[:, :2], topo[:, 2]) zOffset = 0 # Cycle through the first 3 octree levels for ii in range(3): dx = mesh.hx.min()*2**ii nCx = int((limx[0]-limx[1]) / dx) nCy = int((limy[0]-limy[1]) / dx) # Create a grid at the octree level in xy CCx, CCy = np.meshgrid( np.linspace(limx[1], limx[0], nCx), np.linspace(limy[1], limy[0], nCy) ) z = F(mkvc(CCx), mkvc(CCy)) # level means number of layers in current OcTree level for level in range(int(nCpad[ii])): mesh.insert_cells( np.c_[ mkvc(CCx), mkvc(CCy), z-zOffset ], np.ones_like(z)*maxLevel-ii, finalize=False ) zOffset += dx mesh.finalize() self.mesh = mesh # Define an active cells from topo actv = Utils.surface2ind_topo(mesh, topo) nC = int(actv.sum()) model = np.zeros((mesh.nC, 3)) # Convert the inclination declination to vector in Cartesian M_xyz = Utils.matutils.dip_azimuth2cartesian(M[0], M[1]) # Get the indicies of the magnetized block ind = Utils.ModelBuilder.getIndicesBlock( np.r_[-20, -20, -10], np.r_[20, 20, 25], mesh.gridCC, )[0] # Assign magnetization values model[ind, :] = np.kron( np.ones((ind.shape[0], 1)), M_xyz*0.05 ) # Remove air cells self.model = model[actv, :] # Create active map to go from reduce set to full self.actvMap = Maps.InjectActiveCells(mesh, actv, np.nan) # Creat reduced identity map idenMap = Maps.IdentityMap(nP=nC*3) # Create the forward model operator prob = PF.Magnetics.MagneticIntegral( mesh, chiMap=idenMap, actInd=actv, modelType='vector' ) # Pair the survey and problem survey.pair(prob) # Compute some data and add some random noise data = prob.fields(Utils.mkvc(self.model)) std = 5 # nT data += np.random.randn(len(data))*std wd = np.ones(len(data))*std # Assigne data and uncertainties to the survey survey.dobs = data survey.std = wd # Create an projection matrix for plotting later actvPlot = Maps.InjectActiveCells(mesh, actv, np.nan) # Create sensitivity weights from our linear forward operator rxLoc = survey.srcField.rxList[0].locs # This Mapping connects the regularizations for the three-component # vector model wires = Maps.Wires(('p', nC), ('s', nC), ('t', nC)) # Create sensitivity weights from our linear forward operator # so that all cells get equal chance to contribute to the solution wr = np.sum(prob.G**2., axis=0)**0.5 wr = (wr/np.max(wr)) # Create three regularization for the different components # of magnetization reg_p = Regularization.Sparse(mesh, indActive=actv, mapping=wires.p) reg_p.mref = np.zeros(3*nC) reg_p.cell_weights = (wires.p * wr) reg_s = Regularization.Sparse(mesh, indActive=actv, mapping=wires.s) reg_s.mref = np.zeros(3*nC) reg_s.cell_weights = (wires.s * wr) reg_t = Regularization.Sparse(mesh, indActive=actv, mapping=wires.t) reg_t.mref = np.zeros(3*nC) reg_t.cell_weights = (wires.t * wr) reg = reg_p + reg_s + reg_t reg.mref = np.zeros(3*nC) # Data misfit function dmis = DataMisfit.l2_DataMisfit(survey) dmis.W = 1./survey.std # Add directives to the inversion opt = Optimization.ProjectedGNCG(maxIter=30, lower=-10, upper=10., maxIterLS=20, maxIterCG=20, tolCG=1e-4) invProb = InvProblem.BaseInvProblem(dmis, reg, opt) # A list of directive to control the inverson betaest = Directives.BetaEstimate_ByEig() # Here is where the norms are applied # Use pick a treshold parameter empirically based on the distribution of # model parameters IRLS = Directives.Update_IRLS( f_min_change=1e-3, maxIRLSiter=0, beta_tol=5e-1 ) # Pre-conditioner update_Jacobi = Directives.UpdatePreconditioner() inv = Inversion.BaseInversion(invProb, directiveList=[IRLS, update_Jacobi, betaest]) # Run the inversion m0 = np.ones(3*nC) * 1e-4 # Starting model mrec_MVIC = inv.run(m0) self.mstart = Utils.matutils.cartesian2spherical(mrec_MVIC.reshape((nC, 3), order='F')) beta = invProb.beta dmis.prob.coordinate_system = 'spherical' dmis.prob.model = self.mstart # Create a block diagonal regularization wires = Maps.Wires(('amp', nC), ('theta', nC), ('phi', nC)) # Create a Combo Regularization # Regularize the amplitude of the vectors reg_a = Regularization.Sparse(mesh, indActive=actv, mapping=wires.amp) reg_a.norms = np.c_[0., 0., 0., 0.] # Sparse on the model and its gradients reg_a.mref = np.zeros(3*nC) # Regularize the vertical angle of the vectors reg_t = Regularization.Sparse(mesh, indActive=actv, mapping=wires.theta) reg_t.alpha_s = 0. # No reference angle reg_t.space = 'spherical' reg_t.norms = np.c_[2., 0., 0., 0.] # Only norm on gradients used # Regularize the horizontal angle of the vectors reg_p = Regularization.Sparse(mesh, indActive=actv, mapping=wires.phi) reg_p.alpha_s = 0. # No reference angle reg_p.space = 'spherical' reg_p.norms = np.c_[2., 0., 0., 0.] # Only norm on gradients used reg = reg_a + reg_t + reg_p reg.mref = np.zeros(3*nC) Lbound = np.kron(np.asarray([0, -np.inf, -np.inf]), np.ones(nC)) Ubound = np.kron(np.asarray([10, np.inf, np.inf]), np.ones(nC)) # Add directives to the inversion opt = Optimization.ProjectedGNCG(maxIter=20, lower=Lbound, upper=Ubound, maxIterLS=20, maxIterCG=30, tolCG=1e-3, stepOffBoundsFact=1e-3, ) opt.approxHinv = None invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta=beta*10.) # Here is where the norms are applied IRLS = Directives.Update_IRLS(f_min_change=1e-4, maxIRLSiter=20, minGNiter=1, beta_tol=0.5, coolingRate=1, coolEps_q=True, betaSearch=False) # Special directive specific to the mag amplitude problem. The sensitivity # weights are update between each iteration. ProjSpherical = Directives.ProjectSphericalBounds() update_SensWeight = Directives.UpdateSensitivityWeights() update_Jacobi = Directives.UpdatePreconditioner() self.inv = Inversion.BaseInversion( invProb, directiveList=[ ProjSpherical, IRLS, update_SensWeight, update_Jacobi ] )
active_map = Maps.InjectActiveCells(mesh, ind_active, air_value) # Define model for cells under the surface topography N = int(ind_active.sum()) model = np.kron(np.ones((N, 1)), np.c_[background_sigma, background_mu]) # Add a conductive and non-permeable layer ind_layer = ((mesh.gridCC[ind_active, 2] > -20.) & (mesh.gridCC[ind_active, 2] < -0)) model[ind_layer, 0] = layer_sigma # Add a conductive and permeable pipe ind_pipe = ((mesh.gridCC[ind_active, 0] < 10.) & (mesh.gridCC[ind_active, 2] > -50.) & (mesh.gridCC[ind_active, 2] < 0.)) model[ind_pipe] = np.c_[pipe_sigma, pipe_mu] # Create model vector and wires model = mkvc(model) wire_map = Maps.Wires(('log_sigma', N), ('mu', N)) # Use combo maps to map from model to mesh sigma_map = Maps.ComboMap([active_map, Maps.ExpMap(), wire_map.log_sigma]) mu_map = Maps.ComboMap([active_map, wire_map.mu]) # Plotting fig = plt.figure(figsize=(5, 5)) ax = fig.add_subplot(111) mesh.plotImage(sigma_map * model, ax=ax, grid=True) ax.set_title('Cylindrically Symmetric Model')
def setUp(self): cs = 25. hx = [(cs, 0, -1.3), (cs, 21), (cs, 0, 1.3)] hy = [(cs, 0, -1.3), (cs, 21), (cs, 0, 1.3)] hz = [(cs, 0, -1.3), (cs, 20), (cs, 0, 1.3)] mesh = Mesh.TensorMesh([hx, hy, hz], x0="CCC") blkind0 = Utils.ModelBuilder.getIndicesSphere( np.r_[-100., -100., -200.], 75., mesh.gridCC ) blkind1 = Utils.ModelBuilder.getIndicesSphere( np.r_[100., 100., -200.], 75., mesh.gridCC ) sigma = np.ones(mesh.nC)*1e-2 airind = mesh.gridCC[:, 2] > 0. sigma[airind] = 1e-8 eta = np.zeros(mesh.nC) tau = np.ones_like(sigma) * 1. c = np.ones_like(sigma) * 0.5 eta[blkind0] = 0.1 eta[blkind1] = 0.1 tau[blkind0] = 0.1 tau[blkind1] = 0.01 actmapeta = Maps.InjectActiveCells(mesh, ~airind, 0.) actmaptau = Maps.InjectActiveCells(mesh, ~airind, 1.) actmapc = Maps.InjectActiveCells(mesh, ~airind, 1.) x = mesh.vectorCCx[(mesh.vectorCCx > -155.) & (mesh.vectorCCx < 155.)] y = mesh.vectorCCy[(mesh.vectorCCy > -155.) & (mesh.vectorCCy < 155.)] Aloc = np.r_[-200., 0., 0.] Bloc = np.r_[200., 0., 0.] M = Utils.ndgrid(x-25., y, np.r_[0.]) N = Utils.ndgrid(x+25., y, np.r_[0.]) times = np.arange(10)*1e-3 + 1e-3 rx = SIP.Rx.Dipole(M, N, times) src = SIP.Src.Dipole([rx], Aloc, Bloc) survey = SIP.Survey([src]) wires = Maps.Wires(('eta', actmapeta.nP), ('taui', actmaptau.nP), ('c', actmapc.nP)) problem = SIP.Problem3D_N( mesh, sigma=sigma, etaMap=actmapeta*wires.eta, tauiMap=actmaptau*wires.taui, cMap=actmapc*wires.c, actinds=~airind, storeJ = True, verbose=False ) problem.Solver = Solver problem.pair(survey) mSynth = np.r_[eta[~airind], 1./tau[~airind], c[~airind]] survey.makeSyntheticData(mSynth) # Now set up the problem to do some minimization dmis = DataMisfit.l2_DataMisfit(survey) dmis = DataMisfit.l2_DataMisfit(survey) reg_eta = Regularization.Simple(mesh, mapping=wires.eta, indActive=~airind) reg_taui = Regularization.Simple(mesh, mapping=wires.taui, indActive=~airind) reg_c = Regularization.Simple(mesh, mapping=wires.c, indActive=~airind) reg = reg_eta + reg_taui + reg_c opt = Optimization.InexactGaussNewton( maxIterLS=20, maxIter=10, tolF=1e-6, tolX=1e-6, tolG=1e-6, maxIterCG=6 ) invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta=1e4) inv = Inversion.BaseInversion(invProb) self.inv = inv self.reg = reg self.p = problem self.mesh = mesh self.m0 = mSynth self.survey = survey self.dmis = dmis
# Build list of indecies for the geounits index = [] nCunit = [] for unit in geoUnits: index += [mref == unit] nCunit += [int((mref == unit).sum())] nC = len(index) # Creat reduced identity map homogMap = Maps.SurjectUnits(index) homogMap.nBlock = 3 if modelDecomposition: # Create a wire map to link the homogeneous and heterogeneous spaces wires = Maps.Wires(('h**o', 3 * nC), ('hetero', int(actv.sum() * 3))) # Create Sum map for the global inverse sumMap = Maps.SumMap([homogMap * wires.h**o, wires.hetero]) wrGlobal = np.zeros(sumMap.shape[1]) else: wrGlobal = np.zeros(homogMap.shape[1]) else: wrGlobal = np.zeros(int(actv.sum() * 3)) actvMap = Maps.InjectActiveCells(mesh, actv, 0)
def setupProblem( mesh, muMod, sigmaMod, prbtype='e', invertMui=False, sigmaInInversion=False, freq=1. ): rxcomp = ['real', 'imag'] loc = Utils.ndgrid( [mesh.vectorCCx, np.r_[0.], mesh.vectorCCz] ) if prbtype in ['e', 'b']: rxfields_y = ['e', 'j'] rxfields_xz = ['b', 'h'] elif prbtype in ['h', 'j']: rxfields_y = ['b', 'h'] rxfields_xz = ['e', 'j'] rxList_edge = [ getattr(FDEM.Rx, 'Point_{f}'.format(f=f))( loc, component=comp, orientation=orient ) for f in rxfields_y for comp in rxcomp for orient in ['y'] ] rxList_face = [ getattr(FDEM.Rx, 'Point_{f}'.format(f=f))( loc, component=comp, orientation=orient ) for f in rxfields_xz for comp in rxcomp for orient in ['x', 'z'] ] rxList = rxList_edge + rxList_face src_loc = np.r_[0., 0., 0.] if prbtype in ['e', 'b']: src = FDEM.Src.MagDipole( rxList=rxList, loc=src_loc, freq=freq ) elif prbtype in ['h', 'j']: ind = Utils.closestPoints(mesh, src_loc, 'Fz') + mesh.vnF[0] vec = np.zeros(mesh.nF) vec[ind] = 1. src = FDEM.Src.RawVec_e(rxList=rxList, freq=freq, s_e=vec) survey = FDEM.Survey([src]) if sigmaInInversion: wires = Maps.Wires( ('mu', mesh.nC), ('sigma', mesh.nC) ) muMap = Maps.MuRelative(mesh) * wires.mu sigmaMap = Maps.ExpMap(mesh) * wires.sigma if invertMui: muiMap = Maps.ReciprocalMap(mesh)*muMap prob = getattr(FDEM, 'Problem3D_{}'.format(prbtype))( mesh, muiMap=muiMap, sigmaMap=sigmaMap ) # m0 = np.hstack([1./muMod, sigmaMod]) else: prob = getattr(FDEM, 'Problem3D_{}'.format(prbtype))( mesh, muMap=muMap, sigmaMap=sigmaMap ) m0 = np.hstack([muMod, sigmaMod]) else: muMap = Maps.MuRelative(mesh) if invertMui: muiMap = Maps.ReciprocalMap(mesh) * muMap prob = getattr(FDEM, 'Problem3D_{}'.format(prbtype))( mesh, sigma=sigmaMod, muiMap=muiMap ) # m0 = 1./muMod else: prob = getattr(FDEM, 'Problem3D_{}'.format(prbtype))( mesh, sigma=sigmaMod, muMap=muMap ) m0 = muMod prob.pair(survey) return m0, prob, survey
# We add some random Gaussian noise (1nT) d_TMI += np.random.randn(len(d_TMI))*0. wd = np.ones(len(d_TMI))*1. # Assign flat uncertainties survey.dobs = d_TMI survey.std = wd rxLoc = survey.srcField.rxList[0].locs # # RUN THE MVI-CARTESIAN FIRST # Create identity map idenMap = Maps.IdentityMap(nP=4*nC) mstart = np.ones(4*len(actv))*1e-4 # Create a block diagonal misfit wire wires_misfit = Maps.Wires(('a', nC), ('pst', 3*nC)) # Create the forward model operator prob_MVI = PF.Magnetics.MagneticVector(mesh, chiMap=wires_misfit.pst, actInd=actv, silent=True) # Explicitely set starting model prob_MVI.model = mstart # Pair the survey and problem survey.pair(prob_MVI) # Create sensitivity weights from our linear forward operator wr = np.sum(prob_MVI.F**2., axis=0) #prob_MVI.JtJdiag = wr
def run_simulation_TD(args): """ args rx_location: Recevier location (x, y, z) src_location: Source location (x, y, z) topo: Topographic location (x, y, z) hz: Thickeness of the vertical layers time: Time (s) field_type: 'secondary' rx_type: src_type: wave_type: offset: Source-Receiver offset (for VMD) a: Source-loop radius (for Circular Loop) time_input_currents: input_currents: n_pulse: base_frequency: sigma: jac_switch: """ rx_location, src_location, topo, hz, time, field_type, rx_type, src_type, wave_type, offset, a, time_input_currents, input_currents, n_pulse, base_frequency, use_lowpass_filter, high_cut_frequency, moment_type, time_dual_moment, time_input_currents_dual_moment, input_currents_dual_moment, base_frequency_dual_moment, sigma, eta, tau, c, h, jac_switch, invert_height, half_switch = args mesh_1d = set_mesh_1d(hz) depth = -mesh_1d.gridN[:-1] TDsurvey = EM1DSurveyTD( rx_location=rx_location, src_location=src_location, topo=topo, depth=depth, time=time, field_type=field_type, rx_type=rx_type, src_type=src_type, wave_type=wave_type, offset=offset, a=a, time_input_currents=time_input_currents, input_currents=input_currents, n_pulse=n_pulse, base_frequency=base_frequency, high_cut_frequency=high_cut_frequency, moment_type=moment_type, time_dual_moment=time_dual_moment, time_input_currents_dual_moment=time_input_currents_dual_moment, input_currents_dual_moment=input_currents_dual_moment, base_frequency_dual_moment=base_frequency_dual_moment, half_switch=half_switch, ) if not invert_height: # Use Exponential Map # This is hard-wired at the moment expmap = Maps.ExpMap(mesh_1d) prob = EM1D( mesh_1d, sigmaMap=expmap, hankel_filter='key_101_2009', eta=eta, tau=tau, c=c ) if prob.ispaired: prob.unpair() if TDsurvey.ispaired: TDsurvey.unpair() prob.pair(TDsurvey) if jac_switch == 'sensitivity_sigma': drespdsig = prob.getJ_sigma(np.log(sigma)) return drespdsig * prob.sigmaDeriv else: resp = TDsurvey.dpred(np.log(sigma)) return resp else: wires = Maps.Wires(('sigma', mesh_1d.nC),('h', 1)) expmap = Maps.ExpMap(mesh_1d) sigmaMap = expmap * wires.sigma prob = EM1D( mesh_1d, sigmaMap=sigmaMap, hMap=wires.h, hankel_filter='key_101_2009', eta=eta, tau=tau, c=c ) if prob.ispaired: prob.unpair() if TDsurvey.ispaired: TDsurvey.unpair() prob.pair(TDsurvey) m = np.r_[np.log(sigma), h] if jac_switch == 'sensitivity_sigma': drespdsig = prob.getJ_sigma(m) return drespdsig * Utils.sdiag(sigma) elif jac_switch == 'sensitivity_height': drespdh = prob.getJ_height(m) return drespdh else: resp = TDsurvey.dpred(m) return resp
def run_simulation_FD(args): """ args rx_location: Recevier location (x, y, z) src_location: Source location (x, y, z) topo: Topographic location (x, y, z) hz: Thickeness of the vertical layers offset: Source-Receiver offset frequency: Frequency (Hz) field_type: rx_type: src_type: sigma: jac_switch : """ rx_location, src_location, topo, hz, offset, frequency, field_type, rx_type, src_type, sigma, eta, tau, c, chi, h, jac_switch, invert_height, half_switch = args mesh_1d = set_mesh_1d(hz) depth = -mesh_1d.gridN[:-1] FDsurvey = EM1DSurveyFD( rx_location=rx_location, src_location=src_location, topo=topo, frequency=frequency, offset=offset, field_type=field_type, rx_type=rx_type, src_type=src_type, depth=depth, half_switch=half_switch ) if not invert_height: # Use Exponential Map # This is hard-wired at the moment expmap = Maps.ExpMap(mesh_1d) prob = EM1D( mesh_1d, sigmaMap=expmap, chi=chi, hankel_filter='key_101_2009', eta=eta, tau=tau, c=c ) if prob.ispaired: prob.unpair() if FDsurvey.ispaired: FDsurvey.unpair() prob.pair(FDsurvey) if jac_switch == 'sensitivity_sigma': drespdsig = prob.getJ_sigma(np.log(sigma)) return drespdsig * prob.sigmaDeriv else: resp = FDsurvey.dpred(np.log(sigma)) return resp else: wires = Maps.Wires(('sigma', mesh_1d.nC),('h', 1)) expmap = Maps.ExpMap(mesh_1d) sigmaMap = expmap * wires.sigma prob = EM1D( mesh_1d, sigmaMap=sigmaMap, hMap=wires.h, chi=chi, hankel_filter='key_101_2009', eta=eta, tau=tau, c=c ) if prob.ispaired: prob.unpair() if FDsurvey.ispaired: FDsurvey.unpair() prob.pair(FDsurvey) m = np.r_[np.log(sigma), h] if jac_switch == 'sensitivity_sigma': drespdsig = prob.getJ_sigma(m) return drespdsig * Utils.sdiag(sigma) elif jac_switch == 'sensitivity_height': drespdh = prob.getJ_height(m) return drespdh else: resp = FDsurvey.dpred(m) return resp
def fitWithStretchedExponetial(time, survey_ip, sources, Rho, start_time=None): if start_time is None: start_time = 0 # Choose all time channels tinds = time > start_time nLoc = survey_ip.dobs.T[tinds, :].shape[1] # Setup wire for different properties wires = Maps.Wires(('eta', nLoc), ('tau', nLoc), ('c', nLoc)) taumap = Maps.ExpMap(nP=nLoc) * wires.tau etamap = Maps.ExpMap(nP=nLoc) * wires.eta cmap = Maps.ExpMap(nP=nLoc) * wires.c # This is almost dummmy mesh and xyz loc at the moment # But, there is potential use later m1D = Mesh.TensorMesh([np.ones(nLoc)]) # # Set survey survey = SEMultiSurvey(time[tinds] * 1e-3, sources[:, :], n_pulse=2, T=4) survey.dobs = (survey_ip.dobs.T[tinds, :]).flatten(order='F') # Set problem prob = SEMultiInvProblem(m1D, etaMap=etamap, tauMap=taumap, cMap=cmap) prob.pair(survey) # Set initial model eta0, tau0, c0 = abs( survey_ip.dobs.T[0, :].T), 1. * np.ones(nLoc), 1. * np.ones(nLoc) m0 = np.r_[np.log(eta0), np.log(tau0), np.log(c0)] std = 0.02 plt.plot(survey.dpred(m0)) plt.plot(survey.dobs, '.') plt.title("Obs & pred") plt.xlabel("data point") plt.ylabel("value") plt.show() mreg = Mesh.TensorMesh([len(m0)]) dmisfit = DataMisfit.l2_DataMisfit(survey) uncert = (abs(survey.dobs) * std + 0.01) * 1.1 dmisfit.W = 1. / uncert reg = Regularization.Simple(mreg) opt = Optimization.ProjectedGNCG(maxIter=20) invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt) # Create an inversion object target = Directives.TargetMisfit() invProb.beta = 0. inv = Inversion.BaseInversion(invProb, directiveList=[target]) # reg.mref = 0.*m0 prob.counter = opt.counter = Utils.Counter() opt.LSshorten = 0.5 opt.remember('xc') opt.tolX = 1e-20 opt.tolF = 1e-20 opt.tolG = 1e-20 opt.eps = 1e-20 m_upper = np.r_[np.ones_like(tau0) * np.log(200), np.ones_like(tau0) * np.log(10.), np.ones_like(tau0) * np.log(1.)] m_lower = np.r_[np.ones_like(tau0) * np.log(1), np.ones_like(tau0) * np.log(1e-2), np.ones_like(tau0) * np.log(0.1)] opt.lower = m_lower opt.upper = m_upper mopt = inv.run(m0) eta = etamap * mopt tau = taumap * mopt c = cmap * mopt DPRED = invProb.dpred.reshape((nLoc, time[tinds].size)) DOBS = survey.dobs.reshape((nLoc, time[tinds].size)) UNCERT = uncert.reshape((nLoc, time[tinds].size)) error = ((eta * 1e-3) / np.sqrt(np.sum((DOBS - DPRED)**2, axis=1) / time[tinds].size)) from matplotlib import colors fig = plt.figure(figsize=(6, 5)) active_inds = (Rho[:, 0] > 10.) & (Rho[:, 0] < 1e3) & (abs( (DPRED - DOBS) / UNCERT).sum(axis=1) / time[tinds].size < 1.) out = plt.scatter(tau[active_inds], c[active_inds], c=eta[active_inds], norm=colors.LogNorm(), cmap="magma", s=2) cb = plt.colorbar(out) plt.xscale('log') plt.yscale('log') plt.xlabel("Tau") plt.ylabel("c") cb.set_label("Eta (mV/V)") plt.show() inds = (abs((DPRED - DOBS) / UNCERT).sum(axis=1) / time[tinds].size < 20.) # print(inds) inds = np.arange(survey.n_location)[inds] out = plt.loglog(time[tinds], DPRED[inds[::2], :].T, 'r') out = plt.loglog(time[tinds], DOBS[inds[::2], :].T, 'kx') print(np.sum((DPRED - DOBS)**2) / time.size) fig, axs = plt.subplots(4, 1) properties = [ Rho[:, 0][active_inds], eta[active_inds], tau[active_inds], c[active_inds] ] titles = ["$\\rho_{a}$", "$\\eta_{a}$", "$\\tau_{a}$", "$c_{a}$"] colors = ['#1f77b4', 'seagreen', 'crimson', 'gold'] for i, ax in enumerate(axs): out = ax.hist(np.log10(properties[i]), bins=50, color=colors[i]) ax.set_title(titles[i]) ax.set_xticklabels([("%.1f") % (10**tick) for tick in ax.get_xticks()]) plt.tight_layout() plt.show() return eta, tau, c, error
# Compute an a median value for each homogeneous units mUnit = np.asarray([np.median(mgeo[mgeo == unit]) for unit in geoUnits]) # Build list of indecies for the geounits index = [] nCunit = [] for unit in geoUnits: index += [mgeo == unit] nCunit += [int((mgeo == unit).sum())] nC = len(index) # Creat reduced identity map homogMap = Maps.SurjectUnits(index) # Create a wire map to link the homogeneous and heterogeneous spaces wires = Maps.Wires(('h**o', nC), ('hetero', int(actv.sum()))) # Create Sum map for the global inverse sumMap = Maps.SumMap([homogMap*wires.h**o, wires.hetero]) # LOOP THROUGH TILES surveyMask = np.ones(survey.nD, dtype='bool') # Keep track of locs used wrGlobal = np.zeros(int(nC + actv.sum())) # Global sensitivity weights if tileProblem: # Loop over different tile size and break # problem to fit in memory usedRAM = np.inf count = 0 while usedRAM > maxRAM: print("Tiling:" + str(count))
# --------- # # We can now attempt the inverse calculations. We put some great care # in design an inversion methology that would yield geologically # reasonable solution for the non-induced problem. # The inversion is done in two stages. First we compute a smooth # solution using a Cartesian coordinate system, then a sparse # inversion in the Spherical domain. # # Create sensitivity weights from our linear forward operator rxLoc = survey.srcField.rxList[0].locs # This Mapping connects the regularizations for the three-component # vector model wires = Maps.Wires(('p', nC), ('s', nC), ('t', nC)) # Create sensitivity weights from our linear forward operator # so that all cells get equal chance to contribute to the solution wr = np.sum(prob.G**2., axis=0)**0.5 wr = (wr / np.max(wr)) # Create three regularization for the different components # of magnetization reg_p = Regularization.Sparse(mesh, indActive=actv, mapping=wires.p) reg_p.mref = np.zeros(3 * nC) reg_p.cell_weights = (wires.p * wr) reg_s = Regularization.Sparse(mesh, indActive=actv, mapping=wires.s) reg_s.mref = np.zeros(3 * nC) reg_s.cell_weights = (wires.s * wr)
# Extract active region actv = driver.activeCells # Use the amplitude model to prime the inversion starting model m_amp = driver.m0 # Create rescaled weigths mamp = (m_amp / m_amp.max() + 1e-2)**-1. # Create active map to go from reduce space to full actvMap = Maps.InjectActiveCells(mesh, actv, 0) nC = int(len(actv)) # Create identity map # Create wires to link the regularization to each model blocks wires = Maps.Wires(('prim', nC), ('second', nC), ('third', nC)) # Create identity map idenMap = Maps.IdentityMap(nP=3 * nC) # Create the forward model operator prob = PF.Magnetics.MagneticVector(mesh, chiMap=idenMap, actInd=actv) # Pair the survey and problem survey.pair(prob) # Data misfit function dmis = DataMisfit.l2_DataMisfit(survey) dmis.W = 1. / survey.std wr = np.sum(prob.F**2., axis=0)**0.5