Example #1
0
    def _solveTangentProblem(self, dstate, m_hat, x):
        """
        The predictor step for the parameter continuation algorithm.
        """
        state_fun = vector2Function(x[STATE], self.Vh[STATE])
        statel_fun = vector2Function(x[STATE], self.Vh[STATE])
        param_fun = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
        param_hat_fun = vector2Function(m_hat, self.Vh[PARAMETER])
        x_test = [
            dl.TestFunction(self.Vh[STATE]),
            dl.TestFunction(self.Vh[PARAMETER])
        ]
        x_trial = [
            dl.TrialFunction(self.Vh[STATE]),
            dl.TrialFunction(self.Vh[PARAMETER])
        ]

        res = self.model.residual(state_fun, x_test[STATE], dl.Constant(0.),
                                  param_fun, None, statel_fun, True)
        Aform = dl.derivative(res, state_fun, x_trial[STATE]) + dl.derivative(
            res, statel_fun, x_trial[STATE])
        b_form = dl.derivative(res, param_fun, param_hat_fun)

        A, b = dl.assemble_system(Aform,
                                  b_form,
                                  self.bcs0,
                                  form_compiler_parameters=self.fcp)
        solver = dl.PETScLUSolver()
        solver.set_operator(A)
        solver.solve(dstate, -b)
Example #2
0
    def __init__(self, Vh, model, bcs, bcs0, initial_guess, verbose=True):
        """
        Constructor:
        - Vh: a list of finite element space for the state, parameter and adjoint variables.
              Note that the space for the state and adjoint variables need to be the same.
        - model: a class that provides the weak form for the residual and Jacobian of the forward problem.
                 See RANSModel_inadeguate_Cmu for an example.
        - bcs: list of essential boundary conditions for the forward problem.
        - bcs0: list of (homogeneus) essential boundary conditions for the adjoint and incremental problems.
        - initial_guess: an initial guess vector for the TransientContinuation solver
        """
        self.Vh = Vh
        self.model = model
        self.bcs = bcs
        self.bcs0 = bcs0

        self.initial_guess = initial_guess.copy()

        self.verbose = verbose

        self.x_cont = None
        self.x_latest = None
        self.final_norm_cont = 1e-10

        self.A = []
        self.Asolver = dl.PETScLUSolver()
        self.C = []
        self.Wum = []
        self.Wmm = []
        self.Wuu = []

        self.fcp = {}
        self.fcp["quadrature_degree"] = 3
Example #3
0
    def do_linear_solve(self):
        A, Qdu, b = self.A, self.Qdu, self.b
        q = self.q

        solver = dolfin.PETScLUSolver("umfpack")
        solver.solve(A, Qdu, b)

        ### trash not working code ###

        # solver = dolfin.KrylovSolver('gmres', 'ilu')
        # prm = solver.parameters
        # prm['absolute_tolerance'] = 1E-5
        # prm['relative_tolerance'] = 1E-5
        # prm['maximum_iterations'] = 5000
        # prm["monitor_convergence"] = True

        # solver.solve(A, Qdu, b)

        # try:
        #     solver.solve(self.A, Qdu, self.b)
        # except:
        #     try:
        #         prm['nonzero_initial_guess'] = True
        #         solver.solve(self.A, Qdu, self.b)
        #     except:
        #         raise

        if q is not None:
            dolfin.as_backend_type(self.du.vector()).vec().pointwiseMult(
                q, Qdu.vec())
        else:
            self.du.vector()[:] = Qdu.get_local(
            )  # FIXME: EXTREMELY INEFFICIENT!
Example #4
0
    def __init__(self, mesh, Vh, prior, misfit, simulation_times,
                 wind_velocity, gls_stab):
        self.mesh = mesh
        self.Vh = Vh
        self.prior = prior
        self.misfit = misfit
        # Assume constant timestepping
        self.simulation_times = simulation_times
        dt = simulation_times[1] - simulation_times[0]

        u = dl.TrialFunction(Vh[STATE])
        v = dl.TestFunction(Vh[STATE])

        kappa = dl.Constant(.001)
        dt_expr = dl.Constant(dt)

        r_trial = u + dt_expr * (-ufl.div(kappa * ufl.grad(u)) +
                                 ufl.inner(wind_velocity, ufl.grad(u)))
        r_test = v + dt_expr * (-ufl.div(kappa * ufl.grad(v)) +
                                ufl.inner(wind_velocity, ufl.grad(v)))

        h = dl.CellDiameter(mesh)
        vnorm = ufl.sqrt(ufl.inner(wind_velocity, wind_velocity))
        if gls_stab:
            tau = ufl.min_value((h * h) / (dl.Constant(2.) * kappa), h / vnorm)
        else:
            tau = dl.Constant(0.)

        self.M = dl.assemble(ufl.inner(u, v) * dl.dx)
        self.M_stab = dl.assemble(ufl.inner(u, v + tau * r_test) * dl.dx)
        self.Mt_stab = dl.assemble(ufl.inner(u + tau * r_trial, v) * dl.dx)
        Nvarf = (ufl.inner(kappa * ufl.grad(u), ufl.grad(v)) +
                 ufl.inner(wind_velocity, ufl.grad(u)) * v) * dl.dx
        Ntvarf = (ufl.inner(kappa * ufl.grad(v), ufl.grad(u)) +
                  ufl.inner(wind_velocity, ufl.grad(v)) * u) * dl.dx
        self.N = dl.assemble(Nvarf)
        self.Nt = dl.assemble(Ntvarf)
        stab = dl.assemble(tau * ufl.inner(r_trial, r_test) * dl.dx)
        self.L = self.M + dt * self.N + stab
        self.Lt = self.M + dt * self.Nt + stab

        self.solver = dl.PETScLUSolver(dl.as_backend_type(self.L))
        self.solvert = dl.PETScLUSolver(dl.as_backend_type(self.Lt))

        # Part of model public API
        self.gauss_newton_approx = False
Example #5
0
    def __init__(self, Vh, varf_handler, bc, bc0, is_fwd_linear=False):
        self.Vh = Vh
        self.varf_handler = varf_handler
        self.bc = bc
        self.bc0 = bc0

        self.A = []
        self.At = []
        self.C = []
        self.Wau = []
        self.Waa = []
        self.Wuu = []

        self.solver_fwd_inc = dl.PETScLUSolver()
        self.solver_adj_inc = dl.PETScLUSolver()

        self.is_fwd_linear = is_fwd_linear
Example #6
0
    def _set_solver(self,operator,op_name=None):
        """
        Set the solver of an operator
        """
        if type(operator) is df.PETScMatrix:
            if df.__version__<='1.6.0':
                solver = df.PETScLUSolver('mumps' if df.has_lu_solver_method('mumps') else 'default')
                solver.set_operator(operator)
                solver.parameters['reuse_factorization']=True
            else:
                solver = df.PETScLUSolver(self.mpi_comm,operator,'mumps' if df.has_lu_solver_method('mumps') else 'default')
#             solver.set_operator(operator)
#             solver.parameters['reuse_factorization']=True
            if op_name == 'K':
                solver.parameters['symmetric']=True
        else:
            import scipy.sparse.linalg as spsla
            solver = spsla.splu(operator.tocsc(copy=True))
        return solver
Example #7
0
 def __init__(self,A):
     """
     Contructor
     
     INPUT:
     - A: a s.p.d. finite element matrix
     """
     self.Ainv = dl.PETScLUSolver()
     self.Ainv.set_operator(A)
     self.tmp = dl.Vector()
     A.init_vector(self.tmp,0)
    def setLinearizationPoint(self, x):
        """ Set the values of the state and parameter
            for the incremental Fwd and Adj solvers """
        u = vector2Function(x[STATE], self.Vh[STATE])
        a = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
        p = vector2Function(x[ADJOINT], self.Vh[ADJOINT])
        x_fun = [u, a, p]

        f_form = self.varf_handler(u, a, p)

        g_form = [None, None, None]
        for i in range(3):
            g_form[i] = dl.derivative(f_form, x_fun[i])

        self.A, dummy = dl.assemble_system(dl.derivative(g_form[ADJOINT], u),
                                           g_form[ADJOINT], self.bc0)
        self.At, dummy = dl.assemble_system(dl.derivative(g_form[STATE], p),
                                            g_form[STATE], self.bc0)
        self.C = dl.assemble(dl.derivative(g_form[ADJOINT], a))
        [bc.zero(self.C) for bc in self.bc0]
        self.Wau = dl.assemble(dl.derivative(g_form[PARAMETER], u))
        Wau_t = Transpose(self.Wau)
        [bc.zero(Wau_t) for bc in self.bc0]
        self.Wau = Transpose(Wau_t)

        self.Wuu = dl.assemble(dl.derivative(g_form[STATE], u))
        [bc.zero(self.Wuu) for bc in self.bc0]
        Wuu_t = Transpose(self.Wuu)
        [bc.zero(Wuu_t) for bc in self.bc0]
        self.Wuu = Transpose(Wuu_t)

        self.Waa = dl.assemble(dl.derivative(g_form[PARAMETER], a))

        if self.solver_fwd_inc is None:
            self.solver_fwd_inc = dl.PETScLUSolver()
            self.solver_adj_inc = dl.PETScLUSolver()

        self.solver_fwd_inc.set_operator(self.A)
        self.solver_adj_inc.set_operator(self.At)
Example #9
0
 def __init__(self, Vh, varf_handler, bc, bc0, is_fwd_linear = False):
     self.Vh = Vh
     self.varf_handler = varf_handler
     if type(bc) is dl.DirichletBC:
         self.bc = [bc]
     else:
         self.bc = bc
     if type(bc0) is dl.DirichletBC:
         self.bc0 = [bc0]
     else:
         self.bc0 = bc0
     
     self.A  = []
     self.At = []
     self.C = []
     self.Wau = []
     self.Waa = []
     self.Wuu = []
     
     self.solver_fwd_inc = dl.PETScLUSolver()
     self.solver_adj_inc = dl.PETScLUSolver()
     
     self.is_fwd_linear = is_fwd_linear
Example #10
0
 def solveAdj(self, adj, x, adj_rhs, tol):
     """ Solve the linear Adj Problem: 
         Given a, u; find p such that
         \delta_u F(u,a,p;\hat_u) = 0 \for all \hat_u
     """
     problem = NonlinearProblem(self.Vh[STATE], self.model, self.bcs,
                                self.bcs0)
     problem.fcp = self.fcp
     extra_args = (dl.Constant(0.),
                   vector2Function(x[PARAMETER],
                                   self.Vh[PARAMETER]), None, None, True)
     A = problem.Jacobian(x[STATE], extra_args)
     problem.applyBC0(adj_rhs)
     solver = dl.PETScLUSolver()
     solver.set_operator(A)
     solver.solve_transpose(x[ADJOINT], adj_rhs)
Example #11
0
 def solveAdj(self, adj, x, adj_rhs, tol):
     """ Solve the linear Adj Problem: 
         Given a, u; find p such that
         \delta_u F(u,a,p;\hat_u) = 0 \for all \hat_u
     """
     u = vector2Function(x[STATE], self.Vh[STATE])
     a = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
     p = dl.Function(self.Vh[ADJOINT])
     du = dl.TestFunction(self.Vh[STATE])
     dp = dl.TrialFunction(self.Vh[ADJOINT])
     varf = self.varf_handler(u,a,p)
     adj_form = dl.derivative( dl.derivative(varf, u, du), p, dp )
     Aadj, dummy = dl.assemble_system(adj_form, dl.Constant(0.)*dl.inner(u,du)*dl.dx, self.bc0)
     solver = dl.PETScLUSolver()
     solver.set_operator(Aadj)
     solver.solve(adj, adj_rhs)
    def computeTangent(self):

        dy = df.Measure('dx', self.mesh)
        vol = df.assemble(df.Constant(1.0) * dy)
        y = df.SpatialCoordinate(self.mesh)
        Eps = df.Constant(((0., 0.), (0., 0.)))  # just placeholder

        form = self.multiscaleModel(self.mesh, self.sigmaLaw, Eps, self.others)
        a, f, bcs, W = form()

        start = timer()
        A = mp.block_assemble(a)
        if (len(bcs) > 0):
            bcs.apply(A)

        # decompose just once (the faster for single process)
        solver = df.PETScLUSolver('superlu')
        sol = mp.BlockFunction(W)

        end = timer()
        print('time assembling system', end - start)

        for i in range(self.nvoigt):
            start = timer()
            Eps.assign(df.Constant(macro_strain(i)))
            F = mp.block_assemble(f)
            if (len(bcs) > 0):
                bcs.apply(F)

            solver.solve(A, sol.block_vector(), F)
            sol.block_vector().block_function().apply("to subfunctions")

            sig_mu = self.sigmaLaw(df.dot(Eps, y) + sol[0])
            sigma_hom = Integral(sig_mu, dy, (2, 2)) / vol

            self.Chom_[:, i] = sigma_hom.flatten()[[0, 3, 1]]

            end = timer()
            print('time in solving system', end - start)

        print(self.Chom_)

        # from the second run onwards, just returns
        self.getTangent = self.getTangent_

        return self.Chom_
Example #13
0
    def __init__(self,
                 solver_method,
                 preconditioner=None,
                 lu_method=None,
                 parameters=None):
        """
        Wrap a DOLFIN PETScKrylovSolver or PETScLUSolver

        You must either specify solver_method = 'lu' and give the name
        of the solver, e.g lu_solver='mumps' or give a valid Krylov
        solver name, eg. solver_method='minres' and give the name of a
        preconditioner, eg. preconditioner_name='hypre_amg'.

        The parameters argument is a *list* of dictionaries which are
        to be used as parameters to the Krylov solver. Settings in the
        first dictionary in this list will be (potentially) overwritten
        by settings in later dictionaries. The use case is to provide
        sane defaults as well as allow the user to override the defaults
        in the input file

        The reason for this wrapper is to provide easy querying of
        iterative/direct and not crash when set_reuse_preconditioner is
        run before the first solve. This simplifies usage
        """
        self.solver_method = solver_method
        self.preconditioner = preconditioner
        self.lu_method = lu_method
        self.input_parameters = parameters

        self.is_first_solve = True
        self.is_iterative = False
        self.is_direct = False

        if solver_method.lower() == 'lu':
            solver = dolfin.PETScLUSolver(lu_method)
            self.is_direct = True
        else:
            precon = dolfin.PETScPreconditioner(preconditioner)
            solver = dolfin.PETScKrylovSolver(solver_method, precon)
            self._pre_obj = precon  # Keep from going out of scope
            self.is_iterative = True

        for parameter_set in parameters:
            apply_settings(solver_method, solver.parameters, parameter_set)

        self._solver = solver
Example #14
0
 def forward_sensitivities(self, sm, dm):
     
     assert self.extra_args[self.parameter_location] == None
     assert self.extra_args[self.field_location] == None
     assert self.extra_args[-1] == True
     
     d_state = dl.Function( self.Vh[STATE] ).vector()
     dd_state = dl.Function( self.Vh[STATE] ).vector()
     
     [state_fun, m_fun] = [vector2Function(sm[ii], self.Vh[ii]) for ii in range(2)]
     dm_fun = vector2Function(dm, self.Vh[PARAMETER])
     e_mean_fun =vector2Function(self.field.e_mean, self.Vh[FIELD])
     
     test = dl.TestFunction(self.Vh[STATE])
     trial = dl.TrialFunction(self.Vh[STATE])
     
     self.extra_args[self.parameter_location] = m_fun
     self.extra_args[self.field_location] = e_mean_fun
     
     res_form = self.model.residual(state_fun, test, *self.extra_args)
     
     J_form = dl.derivative(res_form, state_fun, trial)
     b1_form = dl.derivative(res_form, m_fun, dm_fun)
     
     J, b1 = dl.assemble_system(J_form, b1_form, bcs = self.bcs0, form_compiler_parameters = self.fcp)
     Jsolver = dl.PETScLUSolver()
     Jsolver.set_operator(J)
     Jsolver.solve(d_state, -b1)
     
     d_state_fun = vector2Function(d_state, self.Vh[STATE])
     
     b2_form = dl.derivative( dl.derivative(res_form, state_fun, d_state_fun), state_fun, d_state_fun ) \
              + dl.Constant(2.)*dl.derivative( dl.derivative(res_form, state_fun, d_state_fun), m_fun, dm_fun ) \
              + dl.derivative( dl.derivative(res_form, m_fun, dm_fun), m_fun, dm_fun )
              
     b2 = dl.assemble(b2_form, form_compiler_parameters=self.fcp)
     [bc.apply(b2) for bc in self.bcs0]
     
     Jsolver.solve(dd_state, -b2)
     
     self.extra_args[self.parameter_location] = None
     self.extra_args[self.field_location] = None
     
     return d_state, dd_state        
Example #15
0
    def get_tangent(self):
        if self.Chom_ is None:
            self.Chom_ = np.zeros((self.nvoigt, self.nvoigt))

            dy = ufl.Measure("dx", self.mesh)
            vol = df.assemble(df.Constant(1.0) * dy)
            y = ufl.SpatialCoordinate(self.mesh)
            Eps = df.Constant(((0., 0.), (0., 0.)))  # just placeholder

            form = self.multiscale_model(self.mesh, self.sigma_law, Eps,
                                         self.others)
            a, f, bcs, W = form()

            start = timer()
            A = mp.block_assemble(a)
            if len(bcs) > 0:
                bcs.apply(A)

            # decompose just once, since the matrix A is the same in every solve
            solver = df.PETScLUSolver("superlu")
            sol = mp.BlockFunction(W)

            end = timer()
            print("time assembling system", end - start)

            for i in range(self.nvoigt):
                start = timer()
                Eps.assign(df.Constant(self.macro_strain(i)))
                F = mp.block_assemble(f)
                if len(bcs) > 0:
                    bcs.apply(F)

                solver.solve(A, sol.block_vector(), F)
                sol.block_vector().block_function().apply("to subfunctions")

                sig_mu = self.sigma_law(df.dot(Eps, y) + sol[0])
                sigma_hom = self.integrate(sig_mu, dy, (2, 2)) / vol

                self.Chom_[:, i] = sigma_hom.flatten()[[0, 3, 1]]

                end = timer()
                print("time in solving system", end - start)

        return self.Chom_
Example #16
0
 def solveFwd(self, state, x, tol):
     """ Solve the possibly nonlinear Fwd Problem:
     Given a, find u such that
     \delta_p F(u,a,p;\hat_p) = 0 \for all \hat_p"""
     if self.is_fwd_linear:
         u = dl.TrialFunction(self.Vh[STATE])
         a = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
         p = dl.TestFunction(self.Vh[ADJOINT])
         res_form = self.varf_handler(u, a, p)
         A_form = dl.lhs(res_form)
         b_form = dl.rhs(res_form)
         A, b = dl.assemble_system(A_form, b_form, bcs=self.bc)
         solver = dl.PETScLUSolver()
         solver.set_operator(A)
         solver.solve(state, b)
     else:
         u = vector2Function(x[STATE], self.Vh[STATE])
         a = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
         p = dl.TestFunction(self.Vh[ADJOINT])
         res_form = self.varf_handler(u, a, p)
         dl.solve(res_form == 0, u, self.bc)
         state.zero()
         state.axpy(1., u.vector())
Example #17
0
def PETScLUSolver(comm, method='default'):
    if not hasattr(dl.PETScLUSolver, 'set_operator'):
        dl.PETScLUSolver.set_operator = _PETScLUSolver_set_operator

    return dl.PETScLUSolver(comm, method)
Example #18
0
    def solveAdj(self, adj, x, adj_rhs, tol):
        """ Solve the linear Adj Problem: 
            Given a, u; find p such that
            \delta_u F(u,a,p;\hat_u) = 0 \for all \hat_u
        """
        assert self.extra_args[-1] == True
        assert self.extra_args[self.parameter_location] == None
        assert self.extra_args[self.field_location] == None
        
        s0_fun = vector2Function(x[STATE].s0, self.Vh[STATE])
        m_fun  = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
        e_fun = vector2Function(self.field.e_mean, self.Vh[FIELD])
        p_fun = dl.Function(self.Vh[STATE])
        
        self.extra_args[self.parameter_location] = m_fun
        self.extra_args[self.field_location] = e_fun
        
        test = dl.TestFunction(self.Vh[STATE])
        trial = dl.TrialFunction(self.Vh[STATE])
                
        res_form = self.model.residual(s0_fun, p_fun, *self.extra_args)
        Jt_form = dl.derivative(dl.derivative(res_form, s0_fun, test), p_fun, trial)
        
        Jt = dl.assemble(Jt_form, form_compiler_parameters = self.fcp)
        [bc.apply(Jt) for bc in self.bcs0]
        Jtsolver = dl.PETScLUSolver()
        Jtsolver.set_operator(Jt)
        
        rhs0 = adj_rhs.s0.copy()
        
        for ii in range(self.field.n_fields):
            #Second order incrementals
            rhs = adj_rhs.s2[ii].copy()
            [bc.apply(rhs) for bc in self.bcs0]
            Jtsolver.solve(adj.s2[ii], rhs)
            #First order incrementals
            s1_fun = vector2Function(x[STATE].s1[ii], self.Vh[STATE])
            de_fun = vector2Function(self.field.ei[ii], self.Vh[FIELD])
            p2_fun = vector2Function(adj.s2[ii], self.Vh[ADJOINT])
            res_form1 = self.model.residual(s0_fun, p2_fun, *self.extra_args)
            du_res_form1 = dl.derivative(res_form1, s0_fun, test)
            duu_res_form1 = dl.derivative(du_res_form1, s0_fun, s1_fun)
            due_res_form1 = dl.derivative(du_res_form1, e_fun, de_fun)
            rhs = dl.assemble(dl.Constant(-2.)*duu_res_form1 + dl.Constant(-2.)*due_res_form1)
            rhs.axpy(1., adj_rhs.s1[ii])
            [bc.apply(rhs) for bc in self.bcs0]
            Jtsolver.solve(adj.s1[ii], rhs)
            #Accumulate terms for the adjoint
            #first term
            p1_fun = vector2Function(adj.s1[ii], self.Vh[ADJOINT])
            res_form0a = self.model.residual(s0_fun, p1_fun, *self.extra_args)
            du_res_form0a = dl.derivative(res_form0a, s0_fun, test)
            duu_res_form0a = dl.derivative(du_res_form0a, s0_fun, s1_fun)
            due_res_form0a = dl.derivative(du_res_form0a, e_fun, de_fun)
            rhs = dl.assemble(-duu_res_form0a-due_res_form0a)
            rhs0.axpy(1., rhs)
            #second term
            s2_fun = vector2Function(x[STATE].s2[ii], self.Vh[STATE])
            res_form0b = self.model.residual(s0_fun, p2_fun, *self.extra_args)
            du_res_form0b = dl.derivative(res_form0b, s0_fun, test)
            duu_res_form0b = dl.derivative(du_res_form0b, s0_fun, s2_fun)
            duuu_res_form0b = dl.derivative(dl.derivative(du_res_form0b, s0_fun, s1_fun), s0_fun, s1_fun)
            duue_res_form0b = dl.derivative(dl.derivative(du_res_form0b, s0_fun, s1_fun), e_fun, de_fun)
            duee_res_form0b = dl.derivative(dl.derivative(du_res_form0b, e_fun, de_fun), e_fun, de_fun)
            rhs = dl.assemble(-duu_res_form0b-duuu_res_form0b-dl.Constant(2.)*duue_res_form0b-duee_res_form0b)
            rhs0.axpy(1., rhs)

        [bc.apply(rhs0) for bc in self.bcs0]
        Jtsolver.solve(adj.s0, rhs0)
        
        self.extra_args[self.parameter_location] = None
        self.extra_args[self.field_location] = None
Example #19
0
 def solveFwd(self, state, x, tol):
     """ Solve the possibly nonlinear Fwd Problem:
     Given a, find u such that
     \delta_p F(u,a,p;\hat_p) = 0 \for all \hat_p"""
     
     # STEP 1. Find state0
     dm_norms = [ (x[PARAMETER] - mi).norm("l2") for mi in self.continuation_ms]
     
     min_dm_norms, idx = min( (dm_norms[ii], ii) for ii in range(len(self.continuation_ms)))
     
     m_start = self.continuation_ms[idx].copy()
     state.s0.zero()
     state.s0.axpy(1., self.continuation_states[idx])
     
     while (x[PARAMETER]-m_start).norm("l2") > dl.DOLFIN_EPS:
         self._fwd_cont(state.s0, m_start, x[PARAMETER])
                 
     if len(self.continuation_ms) < self.continuation_maxlen:
         self.continuation_states.append(state.s0.copy())
         self.continuation_ms.append(x[PARAMETER].copy())
     else:
         index = (self.continuation_i % (self.continuation_maxlen-1)) +1
         self.continuation_states[index] = state.s0.copy()
         self.continuation_ms[index] = x[PARAMETER].copy()
         self.continuation_i = index 
     
     # 2. Solve the first and second order incrementals
     s0_fun = vector2Function(state.s0, self.Vh[STATE])
     m_fun  = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
     e_fun = vector2Function(self.field.e_mean, self.Vh[FIELD])
     
     self.extra_args[self.parameter_location] = m_fun
     self.extra_args[self.field_location] = e_fun
     self.extra_args[-1] = True
     
     test = dl.TestFunction(self.Vh[STATE])
     trial = dl.TrialFunction(self.Vh[STATE])
     
     res_form = self.model.residual(s0_fun, test, *self.extra_args)
     Jform = dl.derivative(res_form ,s0_fun, trial)
     
     J = dl.assemble(Jform, form_compiler_parameters = self.fcp)
     [bc.apply(J) for bc in self.bcs0]
     Jsolver = dl.PETScLUSolver()
     Jsolver.set_operator(J)
     
     for ii in range(self.field.n_fields):
         de_fun = vector2Function(self.field.ei[ii], self.Vh[FIELD])
         b1_form = dl.derivative(res_form, e_fun, de_fun)
         b1 = dl.assemble(b1_form, form_compiler_parameters = self.fcp)
         [bc.apply(b1) for bc in self.bcs0]
         Jsolver.solve(state.s1[ii], -b1)
         s1_fun = vector2Function(state.s1[ii], self.Vh[STATE])
         b2_form = dl.derivative( dl.derivative(res_form, s0_fun, s1_fun), s0_fun, s1_fun) + \
                   dl.Constant(2.)*dl.derivative( dl.derivative(res_form, s0_fun, s1_fun), e_fun, de_fun) + \
                   dl.derivative( dl.derivative(res_form, e_fun, de_fun), e_fun, de_fun)
         b2 = dl.assemble(b2_form, form_compiler_parameters = self.fcp)
         [bc.apply(b2) for bc in self.bcs0]
         Jsolver.solve(state.s2[ii], -b2)
         
     self.extra_args[self.parameter_location] = None
     self.extra_args[self.field_location] = None
Example #20
0
 def _createLUSolver(self):
     if dlversion() <= (1,6,0):
         return dl.PETScLUSolver()
     else:
         return dl.PETScLUSolver(self.Vh[STATE].mesh().mpi_comm() )
Example #21
0
    def __init__(self, mesh, Vh, t_init, t_final, t_1, dt, wind_velocity,
                 gls_stab, Prior):
        self.mesh = mesh
        self.Vh = Vh
        self.t_init = t_init
        self.t_final = t_final
        self.t_1 = t_1
        self.dt = dt
        self.sim_times = np.arange(self.t_init, self.t_final + .5 * self.dt,
                                   self.dt)

        u = dl.TrialFunction(Vh[STATE])
        v = dl.TestFunction(Vh[STATE])

        kappa = dl.Constant(.001)
        dt_expr = dl.Constant(self.dt)

        r_trial = u + dt_expr * (-dl.div(kappa * dl.nabla_grad(u)) +
                                 dl.inner(wind_velocity, dl.nabla_grad(u)))
        r_test = v + dt_expr * (-dl.div(kappa * dl.nabla_grad(v)) +
                                dl.inner(wind_velocity, dl.nabla_grad(v)))

        h = dl.CellSize(mesh)
        vnorm = dl.sqrt(dl.inner(wind_velocity, wind_velocity))
        if gls_stab:
            tau = dl.Min((h * h) / (dl.Constant(2.) * kappa), h / vnorm)
        else:
            tau = dl.Constant(0.)

        self.M = dl.assemble(dl.inner(u, v) * dl.dx)
        self.M_stab = dl.assemble(dl.inner(u, v + tau * r_test) * dl.dx)
        self.Mt_stab = dl.assemble(dl.inner(u + tau * r_trial, v) * dl.dx)
        Nvarf = (dl.inner(kappa * dl.nabla_grad(u), dl.nabla_grad(v)) +
                 dl.inner(wind_velocity, dl.nabla_grad(u)) * v) * dl.dx
        Ntvarf = (dl.inner(kappa * dl.nabla_grad(v), dl.nabla_grad(u)) +
                  dl.inner(wind_velocity, dl.nabla_grad(v)) * u) * dl.dx
        self.N = dl.assemble(Nvarf)
        self.Nt = dl.assemble(Ntvarf)
        stab = dl.assemble(tau * dl.inner(r_trial, r_test) * dl.dx)
        self.L = self.M + dt * self.N + stab
        self.Lt = self.M + dt * self.Nt + stab

        boundaries = dl.FacetFunction("size_t", mesh)
        boundaries.set_all(0)

        class InsideBoundary(dl.SubDomain):
            def inside(self, x, on_boundary):
                x_in = x[0] > dl.DOLFIN_EPS and x[0] < 1 - dl.DOLFIN_EPS
                y_in = x[1] > dl.DOLFIN_EPS and x[1] < 1 - dl.DOLFIN_EPS
                return on_boundary and x_in and y_in

        Gamma_M = InsideBoundary()
        Gamma_M.mark(boundaries, 1)
        ds_marked = dl.Measure("ds", subdomain_data=boundaries)

        self.Q = dl.assemble(self.dt * dl.inner(u, v) * ds_marked(1))

        self.Prior = Prior

        if dlversion() <= (1, 6, 0):
            self.solver = dl.PETScLUSolver()
        else:
            self.solver = dl.PETScLUSolver(self.mesh.mpi_comm())
        self.solver.set_operator(self.L)

        if dlversion() <= (1, 6, 0):
            self.solvert = dl.PETScLUSolver()
        else:
            self.solvert = dl.PETScLUSolver(self.mesh.mpi_comm())
        self.solvert.set_operator(self.Lt)

        self.ud = self.generate_vector(STATE)
        self.noise_variance = 0
        # Part of model public API
        self.gauss_newton_approx = False
    def computeTangent(self):

        self.readMesh()
        sigmaLaw = lambda u: self.lame[0] * nabla_div(u) * df.Identity(
            2) + 2 * self.lame[1] * symgrad(u)

        dy = self.mesh.dx  # specially for the case of enriched mesh, otherwise it does not work
        vol = df.assemble(df.Constant(1.0) * dy(0)) + df.assemble(
            df.Constant(1.0) * dy(1))

        y = df.SpatialCoordinate(self.mesh)
        Eps = df.Constant(((0., 0.), (0., 0.)))  # just placeholder

        form = self.multiscaleModel(self.mesh, sigmaLaw, Eps, self.others)
        a, f, bcs, W = form()

        start = timer()
        A = mp.block_assemble(a)
        if (len(bcs) > 0):
            bcs.apply(A)

        solver = df.PETScLUSolver('superlu')
        sol = mp.BlockFunction(W)

        if (self.model == 'lin' or self.model == 'dnn'):
            Vref = self.others['uD'].function_space()
            Mref = Vref.mesh()
            normal = df.FacetNormal(Mref)
            volMref = 4.0

        B = np.zeros((2, 2))

        for i in range(self.nvoigt):

            start = timer()
            if (self.model == 'lin' or self.model == 'dnn'):
                self.others['uD'].vector().set_local(
                    self.others['uD{0}_'.format(i)])

                B = -feut.Integral(df.outer(self.others['uD'], normal),
                                   Mref.ds, (2, 2)) / volMref
                T = feut.affineTransformationExpression(
                    np.zeros(2), B,
                    Mref)  # ignore a, since the basis is already translated
                self.others['uD'].vector().set_local(
                    self.others['uD'].vector().get_local()[:] +
                    df.interpolate(T, Vref).vector().get_local()[:])

            Eps.assign(df.Constant(mscm.macro_strain(i) - B))

            F = mp.block_assemble(f)
            if (len(bcs) > 0):
                bcs.apply(F)

            solver.solve(A, sol.block_vector(), F)
            sol.block_vector().block_function().apply("to subfunctions")

            sig_mu = sigmaLaw(df.dot(Eps, y) + sol[0])
            sigma_hom = sum([Integral(sig_mu, dy(i), (2, 2))
                             for i in [0, 1]]) / vol

            self.Chom_[:, i] = sigma_hom.flatten()[[0, 3, 1]]

            end = timer()
            print('time in solving system', end - start)  # Time in seconds

        self.getTangent = self.getTangent_  # from the second run onwards, just returns

        return self.Chom_
Example #23
0
 def _createLUSolver(self):
     return dl.PETScLUSolver(self.Vh[STATE].mesh().mpi_comm())
Example #24
0
def unconstrained_newton_solve(F,J,uh,dirichlet_bcs=None,bc0=None,
                               linear_solver=None,opts=dict()):
    """
    F: dl.Expression
        The variational form.

    uh : dl.Function
        Final solution. The initial state on entry to the function 
        will be used as initial guess and then overwritten

    dirichlet_bcs : list
        The Dirichlet boundary conditions on the unknown u.

    bc0 : list
        The Dirichlet boundary conditions for the step (du) in the Newton 
        iterations.
    
    """
    max_iter = opts.get("max_iter",50)
    # exit when sqrt(g,g)/sqrt(g_0,g_0) <= rel_tolerance"
    rtol = opts.get("rel_tolerance",1e-8)
    # exit when sqrt(g,g) <= abs_tolerance
    atol = opts.get("abs_tolerance",1e-9)
    # exit when (g,du) <= gdu_tolerance
    gdu_tol = opts.get("gdu_tolerance",1e-14)
    # define armijo sufficient decrease
    c_armijo = opts.get("c_armijo",1e-4)
    # exit if max backtracking steps reached
    max_backtrack = opts.get("max_backtracking_iter",20)
    # define verbosity
    prt_level = opts.get("print_level",0)

    termination_reasons = ["Maximum number of Iteration reached",      #0
                           "Norm of the gradient less than tolerance", #1
                           "Maximum number of backtracking reached",   #2
                           "Norm of (g, du) less than tolerance",      #3
                           "Norm of residual less than tolerance"]     #4
    it = 0
    total_cg_iter = 0
    converged = False
    reason = 0

    if prt_level > 0:
        print ("Solving Nonlinear Problem")

    # Applying boundary conditions
    if dirichlet_bcs is not None:
        if type(dirichlet_bcs) is dl.DirichletBC:
            bcsl  = [dirichlet_bcs]
        else:
            bcsl = dirichlet_bcs
        [bc.apply(uh.vector()) for bc in bcsl]

    if type(bc0) is dl.DirichletBC:
        bc0  = [bc0]


    # Setting variables
    gn = dl.assemble(F)
    res_func = dl.Function(uh.function_space())
    res_func.assign(dl.Function(uh.function_space(),gn))
    res = res_func.vector()
    if bc0 is not None:
        for bc in bc0:
            bc.apply(res)
    Fn = res.norm("l2")
    g0_norm = gn.norm("l2")
    gn_norm = g0_norm
    tol = max(g0_norm*rtol, atol)
    res_tol=max(Fn*rtol, atol)
    du = dl.Function(uh.function_space()).vector()
    
    if linear_solver =='PETScLU': 
        linear_solver = dl.PETScLUSolver(uh.function_space().mesh().mpi_comm())
    else:
        assert linear_solver is None

    if prt_level > 0:
        print( "{0:>3}  {1:>6} {2:>15} {3:>15} {4:>15} {5:>15} {6:>6}".format(
            "Nit", "CGit", "||r||", "||g||", "(g,du)", "alpha", "Nbt") )
        print("{0:3d} {1:6d}    {2:15e} {3:15e}     {4:15}   {5:10} {6:s}".format(
            0, 0, Fn, g0_norm, "    NA    ", "    NA", "NA") )

    converged = False
    reason = 0
    nbt = 0
         
    for it in range(max_iter):
        if bc0 is not None:
            [Hn, gn] = dl.assemble_system(J, F, bc0)
        else:
            Hn = dl.assemble(J)
            gn = dl.assemble(F)

        Hn.init_vector(du,1)
        if linear_solver is None:
            lin_it = dl.solve(Hn, du, -gn, "cg", "petsc_amg")
        else:
            linear_solver.set_operator(Hn)
            lin_it = linear_solver.solve(du, -gn)
        total_cg_iter += lin_it

        du_gn = du.inner(gn)
            
        alpha = 1.0
        if (np.abs(du_gn) < gdu_tol):
            converged = True
            reason = 3
            uh.vector().axpy(alpha,du)
            gn_norm = gn.norm("l2")
            Fn = gn_norm
            break

        uh_backtrack = uh.copy(deepcopy=True)
        bk_converged = False

        #Backtrack
        for nbt in range(max_backtrack):
            uh.assign(uh_backtrack)
            uh.vector().axpy(alpha,du)
            res = dl.assemble(F)
            if bc0 is not None:
                for bc in bc0:
                    bc.apply(res)
            Fnext=res.norm("l2")
            #print(Fn,Fnext,Fn + alpha*c_armijo*du_gn)
            if Fnext < Fn + alpha*c_armijo*du_gn:
            #if True:
                Fn = Fnext
                bk_converged = True
                break
            alpha /= 2.

        if not bk_converged:
            reason = 2
            break

        gn_norm = gn.norm("l2")

        if prt_level > 0:
            print("{0:3d} {1:6d}    {2:15e} {3:15e} {4:15e} {5:15e} {6:3d}".format(
                it+1, lin_it, Fn, gn_norm, du_gn, alpha, nbt+1) )

        if gn_norm < tol:
            converged = True
            reason = 1
            break

        if Fn< res_tol:
            converged=True
            reason = 4
            break

    if prt_level > 0:
        if reason is 3:
            print("{0:3d} {1:6d}    {2:15e} {3:15e} {4:15e} {5:15e} {6:3d}".format(
                it+1, lin_it, Fn, gn_norm, du_gn, alpha, nbt+1) )
        print( termination_reasons[reason] )
        if converged:
            print("Newton converged in ", it, \
                  "nonlinear iterations and ", total_cg_iter,
                  "linear iterations." )
        else:
            print("Newton did NOT converge in ", it, "iterations." )
        print ("Final norm of the gradient: ", gn_norm)
        print ("Value of the cost functional: ", Fn )

    if reason in [0,2]:
        raise Exception(termination_reasons[reason])

    return uh
Example #25
0
    def solve(self, x):

        rtol = self.parameters["rel_tolerance"]
        atol = self.parameters["abs_tolerance"]
        max_iter = self.parameters["max_iter"]
        max_backtracking = self.parameters["max_backtracking"]

        self.problem.applyBC(x)

        if self.callback is not None:
            self.callback(x)

        r = self.problem.residual(x, self.extra_args)

        norm_r0 = self._norm_r(r)
        norm_r = norm_r0

        self.initial_norm = norm_r0

        tol = max(atol, rtol * norm_r0)

        self.converged = False
        it = 0

        d = dl.Vector()

        if (self.parameters["print_level"] >= 1):
            print "\n{0:3} {1:15} {2:15}".format("It", "||r||", "alpha")

        if self.parameters["print_level"] >= 1:
            print "{0:3d} {1:15e} {2:15e}".format(it, norm_r0, 1.)

        while it < max_iter and not self.converged:

            J = self.problem.Jacobian(x, self.extra_args)

            JSolver = dl.PETScLUSolver()
            JSolver.set_operator(J)
            JSolver.solve(d, -r)

            alpha = 1.
            backtracking_converged = False
            j = 0
            while j < max_backtracking and not backtracking_converged:
                x_new = x + alpha * d
                r = self.problem.residual(x_new, self.extra_args)
                try:
                    norm_r_new = self._norm_r(r)
                except:
                    norm_r_new = norm_r + 1.
                if norm_r_new <= norm_r:
                    x.axpy(alpha, d)
                    norm_r = norm_r_new
                    backtracking_converged = True
                else:
                    alpha = .5 * alpha
                    j = j + 1

            if not backtracking_converged:
                if self.parameters["print_level"] >= 0:
                    print "Backtracking failed at iteration", it, ". Residual norm is ", norm_r
                self.converged = False
                self.final_it = it
                self.final_norm = norm_r
                break

            if norm_r_new < tol:
                if self.parameters["print_level"] >= 0:
                    print "Converged in ", it, "iterations with final residual norm", norm_r_new
                self.final_norm = norm_r_new
                self.converged = True
                self.final_it = it
                break

            it = it + 1

            if self.parameters["print_level"] >= 1:
                print "{0:3d} {1:15e} {2:15e}".format(it, norm_r, alpha)

            if self.callback is not None:
                self.callback(x)

        if not self.converged:
            self.final_norm = norm_r_new
            self.final_it = it
            if self.parameters["print_level"] >= 0:
                print "Not Converged in ", it, "iterations. Final residual norm", norm_r_new
Example #26
0
 def _createLUSolver(self):
     if dlversion() <= (1, 6, 0):
         return dl.PETScLUSolver()
         # return dl.PETScKrylovSolver("cg", amg_method())
     else:
         return dl.PETScLUSolver(self.Vh[STATE].mesh().mpi_comm())
    # Hamiltonian and mass matrix forms
    h = (u_r * v_r + u_z * v_z) * r * (
        drdz(0) + drdz(1)) + potential * r * u * v * r * drdz(0)
    m = (u * v * r) * (drdz(0) + drdz(1))

    # Mass matrix
    M = df.PETScMatrix()
    df.assemble(m, tensor=M)

    # Hamiltonian matrix
    H = df.PETScMatrix()
    df.assemble(h, tensor=H)

    # Solution
    psi = df.Function(V)
    solver = df.PETScLUSolver(H)
    solver.parameters['symmetric'] = True

    solver.solve(psi.vector(), Psi0)

    q = psi.vector()

    # Do inverse iteration
    for k in range(5):
        Mq = M * q
        qHq = q.inner(H * q)
        qMq = q.inner(Mq)

        # Rayleigh quotient
        E = qHq / qMq
        print(E)