예제 #1
0
 def __init__(self, V, Vm, bc, bcadj, \
 RHSinput=[], ObsOp=[], UD=[], Regul=[], Data=[], plot=False, \
 mycomm=None):
     # Define test, trial and all other functions
     self.trial = TrialFunction(V)
     self.test = TestFunction(V)
     self.mtrial = TrialFunction(Vm)
     self.mtest = TestFunction(Vm)
     self.rhs = Function(V)
     self.m = Function(Vm)
     self.mcopy = Function(Vm)
     self.srchdir = Function(Vm)
     self.delta_m = Function(Vm)
     self.MG = Function(Vm)
     self.Grad = Function(Vm)
     self.Gradnorm = 0.0
     self.lenm = len(self.m.vector().array())
     self.u = Function(V)
     self.ud = Function(V)
     self.diff = Function(V)
     self.p = Function(V)
     # Define weak forms to assemble A, C and E
     self._wkforma()
     self._wkformc()
     self._wkforme()
     # Store other info:
     self.ObsOp = ObsOp
     self.UD = UD
     self.reset()    # Initialize U, C and E to []
     self.Data = Data
     self.GN = 1.0   # GN = 0.0 => GN Hessian; = 1.0 => full Hessian
     # Operators and bc
     LinearOperator.__init__(self, self.delta_m.vector(), \
     self.delta_m.vector()) 
     self.bc = bc
     self.bcadj = bcadj
     self._assemble_solverM(Vm)
     self.assemble_A()
     self.assemble_RHS(RHSinput)
     self.Regul = Regul
     # Counters, tolerances and others
     self.nbPDEsolves = 0    # Updated when solve_A called
     self.nbfwdsolves = 0    # Counter for plots
     self.nbadjsolves = 0    # Counter for plots
     self._set_plots(plot)
     # MPI:
     self.mycomm = mycomm
     try:
         self.myrank = MPI.rank(self.mycomm)
     except:
         self.myrank = 0
예제 #2
0
 def __init__(self, V, Vm, bc, bcadj, \
 RHSinput=[], ObsOp=[], UD=[], Regul=[], Data=[], plot=False, \
 mycomm=None):
     # Define test, trial and all other functions
     self.trial = TrialFunction(V)
     self.test = TestFunction(V)
     self.mtrial = TrialFunction(Vm)
     self.mtest = TestFunction(Vm)
     self.rhs = Function(V)
     self.m = Function(Vm)
     self.mcopy = Function(Vm)
     self.srchdir = Function(Vm)
     self.delta_m = Function(Vm)
     self.MG = Function(Vm)
     self.MGv = self.MG.vector()
     self.Grad = Function(Vm)
     self.Gradnorm = 0.0
     self.lenm = len(self.m.vector().array())
     self.u = Function(V)
     self.ud = Function(V)
     self.diff = Function(V)
     self.p = Function(V)
     # Store other info:
     self.ObsOp = ObsOp
     self.UD = UD
     self.reset()  # Initialize U, C and E to []
     self.Data = Data
     self.GN = 1.0  # GN = 0.0 => GN Hessian; = 1.0 => full Hessian
     # Define weak forms to assemble A, C and E
     self._wkforma()
     self._wkformc()
     self._wkforme()
     # Operators and bc
     LinearOperator.__init__(self, self.delta_m.vector(), \
     self.delta_m.vector())
     self.bc = bc
     self.bcadj = bcadj
     self._assemble_solverM(Vm)
     self.assemble_A()
     self.assemble_RHS(RHSinput)
     self.Regul = Regul
     self.regparam = 1.0
     if Regul != []:
         self.PD = self.Regul.isPD()
     # Counters, tolerances and others
     self.nbPDEsolves = 0  # Updated when solve_A called
     self.nbfwdsolves = 0  # Counter for plots
     self.nbadjsolves = 0  # Counter for plots
     # MPI:
     self.mycomm = mycomm
예제 #3
0
 def __init__(self, acousticwavePDE, regularization=None):
     """ 
     Input:
         acousticwavePDE should be an instantiation from class AcousticWave
     """
     self.PDE = acousticwavePDE
     self.PDE.exact = None
     self.fwdsource = self.PDE.ftime
     self.MG = Function(self.PDE.Vl)
     self.MGv = self.MG.vector()
     self.Grad = Function(self.PDE.Vl)
     self.Gradv = self.Grad.vector()
     self.srchdir = Function(self.PDE.Vl)
     self.delta_m = Function(self.PDE.Vl)
     LinearOperator.__init__(self, self.MG.vector(), self.MG.vector())
     self.obsop = None   # Observation operator
     self.dd = None  # observations
     if regularization == None:  self.regularization = ZeroRegularization()
     else:   self.regularization = regularization
     self.alpha_reg = 1.0
     # gradient
     self.lamtest, self.lamtrial = TestFunction(self.PDE.Vl), TrialFunction(self.PDE.Vl)
     self.p, self.v = Function(self.PDE.V), Function(self.PDE.V)
     self.wkformgrad = inner(self.lamtest*nabla_grad(self.p), nabla_grad(self.v))*dx
     # incremental rhs
     self.lamhat = Function(self.PDE.Vl)
     self.ptrial, self.ptest = TrialFunction(self.PDE.V), TestFunction(self.PDE.V)
     self.wkformrhsincr = inner(self.lamhat*nabla_grad(self.ptrial), nabla_grad(self.ptest))*dx
     # Hessian
     self.phat, self.vhat = Function(self.PDE.V), Function(self.PDE.V)
     self.wkformhess = inner(self.lamtest*nabla_grad(self.phat), nabla_grad(self.v))*dx \
     + inner(self.lamtest*nabla_grad(self.p), nabla_grad(self.vhat))*dx
     # Mass matrix:
     weak_m =  inner(self.lamtrial,self.lamtest)*dx
     Mass = assemble(weak_m)
     self.solverM = LUSolver()
     self.solverM.parameters['reuse_factorization'] = True
     self.solverM.parameters['symmetric'] = True
     self.solverM.set_operator(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.abc:
         #TODO: should probably be tested in other situations
         if self.PDE.lumpD:
             print '*** Warning: Damping matrix D is lumped. ',\
             'Make sure gradient is consistent.'
         self.vD, self.pD, self.p1D, self.p2D = Function(self.PDE.V), \
         Function(self.PDE.V), Function(self.PDE.V), Function(self.PDE.V)
         self.wkformgradD = inner(0.5*sqrt(self.PDE.rho/self.PDE.lam)\
         *self.pD, self.vD*self.lamtest)*self.PDE.ds(1)
         self.wkformDprime = inner(0.5*sqrt(self.PDE.rho/self.PDE.lam)\
         *self.lamhat*self.ptrial, self.ptest)*self.PDE.ds(1)
         self.dp, self.dph, self.vhatD = Function(self.PDE.V), \
         Function(self.PDE.V), Function(self.PDE.V)
         self.p1hatD, self.p2hatD = Function(self.PDE.V), Function(self.PDE.V)
         self.wkformhessD = inner(-0.25*sqrt(self.PDE.rho)/(self.PDE.lam*sqrt(self.PDE.lam))\
         *self.lamhat*self.dp, self.vD*self.lamtest)*self.PDE.ds(1) \
         + inner(0.5*sqrt(self.PDE.rho/self.PDE.lam)\
         *self.dph, self.vD*self.lamtest)*self.PDE.ds(1)\
         + inner(0.5*sqrt(self.PDE.rho/self.PDE.lam)\
         *self.dp, self.vhatD*self.lamtest)*self.PDE.ds(1)
예제 #4
0
    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)