def __init__(self, regul, param, isprint=False): """ Arguments: regul = regularization for inversion parameters param = inversion parameters (either 'a' or 'b') isprint = boolean """ self.param = param if self.param == 'a': self.regul1 = regul self.regul2 = ZeroRegularization(regul.Vm) elif self.param == 'b': self.regul1 = ZeroRegularization(regul.Vm) self.regul2 = regul else: if isprint: print "[SingleRegularization] *** Error: argument 'param' must be 'a' or 'b'" sys.exit(1) self.isprint = isprint Vm = regul.Vm self.VmVm = createMixedFS(Vm, Vm) self.ab = Function(self.VmVm) bd = BlockDiagonal(Vm, Vm, Vm.mesh().mpi_comm()) self.saa = bd.saa if isprint: print '[SingleRegularization] inversion parameter {}'.format( self.param) if self.isPD(): print '[SingleRegularization] Using primal-dual TV'
def __init__(self, mpicomm_global, acousticwavePDE, sources, \ sourcesindex, timestepsindex, \ invparam='ab', regularization=None): """ Input: acousticwavePDE should be an instantiation from class AcousticWave """ self.mpicomm_global = mpicomm_global self.PDE = acousticwavePDE self.PDE.exact = None self.obsop = None # Observation operator self.dd = None # observations self.fwdsource = sources self.srcindex = sourcesindex self.tsteps = timestepsindex self.PDEcount = 0 self.inverta = False self.invertb = False if 'a' in invparam: self.inverta = True if 'b' in invparam: self.invertb = True assert self.inverta + self.invertb > 0 Vm = self.PDE.Vm V = self.PDE.V VmVm = createMixedFS(Vm, Vm) self.ab = Function(VmVm) # used for conversion (Vm,Vm)->VmVm self.invparam = invparam self.MG = Function(VmVm) self.MGv = self.MG.vector() self.Grad = Function(VmVm) self.srchdir = Function(VmVm) self.delta_m = Function(VmVm) self.m_bkup = Function(VmVm) LinearOperator.__init__(self, self.MGv, self.MGv) self.GN = False if regularization == None: print '[ObjectiveAcoustic] *** Warning: Using zero regularization' self.regularization = ZeroRegularization(Vm) else: self.regularization = regularization self.PD = self.regularization.isPD() self.alpha_reg = 1.0 self.p, self.q = Function(V), Function(V) self.phat, self.qhat = Function(V), Function(V) self.ahat, self.bhat = Function(Vm), Function(Vm) self.ptrial, self.ptest = TrialFunction(V), TestFunction(V) self.mtest, self.mtrial = TestFunction(Vm), TrialFunction(Vm) if self.PDE.parameters['lumpM']: self.Mprime = LumpedMassMatrixPrime(Vm, V, self.PDE.M.ratio) self.get_gradienta = self.get_gradienta_lumped self.get_hessiana = self.get_hessiana_lumped self.get_incra = self.get_incra_lumped else: self.wkformgrada = inner(self.mtest*self.p, self.q)*dx self.get_gradienta = self.get_gradienta_full self.wkformhessa = inner(self.phat*self.mtest, self.q)*dx \ + inner(self.p*self.mtest, self.qhat)*dx self.wkformhessaGN = inner(self.p*self.mtest, self.qhat)*dx self.get_hessiana = self.get_hessiana_full self.wkformrhsincra = inner(self.ahat*self.ptrial, self.ptest)*dx self.get_incra = self.get_incra_full self.wkformgradb = inner(self.mtest*nabla_grad(self.p), nabla_grad(self.q))*dx self.wkformgradbout = assemble(self.wkformgradb) self.wkformrhsincrb = inner(self.bhat*nabla_grad(self.ptrial), nabla_grad(self.ptest))*dx self.wkformhessb = inner(nabla_grad(self.phat)*self.mtest, nabla_grad(self.q))*dx \ + inner(nabla_grad(self.p)*self.mtest, nabla_grad(self.qhat))*dx self.wkformhessbGN = inner(nabla_grad(self.p)*self.mtest, nabla_grad(self.qhat))*dx # Mass matrix: self.mmtest, self.mmtrial = TestFunction(VmVm), TrialFunction(VmVm) weak_m = inner(self.mmtrial, self.mmtest)*dx self.Mass = assemble(weak_m) self.solverM = PETScKrylovSolver("cg", "jacobi") self.solverM.parameters["maximum_iterations"] = 2000 self.solverM.parameters["absolute_tolerance"] = 1e-24 self.solverM.parameters["relative_tolerance"] = 1e-24 self.solverM.parameters["report"] = False self.solverM.parameters["error_on_nonconvergence"] = True self.solverM.parameters["nonzero_initial_guess"] = False # True? self.solverM.set_operator(self.Mass) # Time-integration factors self.factors = np.ones(self.PDE.times.size) self.factors[0], self.factors[-1] = 0.5, 0.5 self.factors *= self.PDE.Dt self.invDt = 1./self.PDE.Dt # Absorbing BCs if self.PDE.parameters['abc']: assert not self.PDE.parameters['lumpD'] self.wkformgradaABC = inner( self.mtest*sqrt(self.PDE.b/self.PDE.a)*self.p, self.q)*self.PDE.ds(1) self.wkformgradbABC = inner( self.mtest*sqrt(self.PDE.a/self.PDE.b)*self.p, self.q)*self.PDE.ds(1) self.wkformgradaABCout = assemble(self.wkformgradaABC) self.wkformgradbABCout = assemble(self.wkformgradbABC) self.wkformincrrhsABC = inner( (self.ahat*sqrt(self.PDE.b/self.PDE.a) + self.bhat*sqrt(self.PDE.a/self.PDE.b))*self.ptrial, self.ptest)*self.PDE.ds(1) self.wkformhessaABC = inner( (self.bhat/sqrt(self.PDE.a*self.PDE.b) - self.ahat*sqrt(self.PDE.b/(self.PDE.a*self.PDE.a*self.PDE.a))) *self.p*self.mtest, self.q)*self.PDE.ds(1) self.wkformhessbABC = inner( (self.ahat/sqrt(self.PDE.a*self.PDE.b) - self.bhat*sqrt(self.PDE.a/(self.PDE.b*self.PDE.b*self.PDE.b))) *self.p*self.mtest, self.q)*self.PDE.ds(1)