예제 #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)
예제 #2
0
    def __init__(self, model, particle, variation, kernel, options, comm):
        self.model = model
        self.particle = particle  # number of particles
        self.variation = variation
        self.kernel = kernel
        self.options = options
        self.comm = comm
        self.rank = comm.Get_rank()
        self.nproc = comm.Get_size()

        self.save_kernel = options["save_kernel"]
        self.type_Hessian = options["type_Hessian"]
        self.ncalls = 0
        self.gls = GlobalLocalSwitch(self.model, self.particle, self.options,
                                     self.comm)

        if not self.options["is_projection"]:
            if self.particle.number_particles_all == 1:
                z_trial = dl.TrialFunction(self.gls.Vh_Local)
                z_test = dl.TestFunction(self.gls.Vh_Local)
                self.Hessian = dl.assemble(z_trial * z_test * dl.dx)
            else:
                z_vec = [None] * particle.number_particles_all
                c_vec = [None] * particle.number_particles_all
                for n in range(particle.number_particles_all):
                    z_trial = dl.TrialFunction(self.gls.Vh_Global.sub(0))
                    z_test = dl.TestFunction(self.gls.Vh_Global.sub(0))
                    z_vec[n] = z_trial
                    c_vec[n] = z_test
                z_vec = dl.as_vector(z_vec)
                c_vec = dl.as_vector(c_vec)
                self.Hessian = dl.assemble(dl.dot(c_vec, z_vec) * dl.dx)
예제 #3
0
    def __init__(self,
                 parameters,
                 mesh_name,
                 facet_name,
                 bc_dict={
                     "obstacle": 2,
                     "channel_walls": 1,
                     "inlet": 3,
                     "outlet": 4
                 }):
        """
        Create the required function spaces, functions and boundary conditions
        for a channel flow problem
        """
        self.bc_dict = bc_dict
        self.mesh = df.Mesh()
        with df.XDMFFile(mesh_name) as infile:
            infile.read(self.mesh)

        mvc = df.MeshValueCollection("size_t", self.mesh,
                                     self.mesh.topology().dim() - 1)
        with df.XDMFFile(facet_name) as infile:
            infile.read(mvc, "name_to_read")
        self.mf = mf = df.cpp.mesh.MeshFunctionSizet(self.mesh, mvc)

        self.V = V = df.VectorFunctionSpace(self.mesh, 'P',
                                            parameters["degree velocity"])
        self.Q = Q = df.FunctionSpace(self.mesh, 'P',
                                      parameters["degree pressure"])
        self.rho = df.Constant(parameters["density [kg/m3]"])
        self.mu = df.Constant(parameters["viscosity [Pa*s]"])
        self.dt = df.Constant(parameters["dt [s]"])
        self.g = df.Constant((0, 0))
        self.vu, self.vp = df.TestFunction(V), df.TestFunction(Q)
        self.u_, self.p_ = df.Function(V), df.Function(Q)
        self.u_1, self.p_1 = df.Function(V), df.Function(Q)
        self.u_k, self.p_k = df.Function(V), df.Function(Q)
        self.u, self.p = df.TrialFunction(V), df.TrialFunction(Q)  # unknown!

        self.U_m = U_m = parameters["velocity [m/s]"]
        x = [0, .41 / 2]  # center of the channel
        Ucenter = 4. * U_m * x[1] * (.41 - x[1]) / (.41 * .41)
        U0_str = "4.*U_m*x[1]*(.41-x[1])/(.41*.41)"
        self.U_mean = np.mean(2 / 3 * Ucenter)

        U0 = df.Expression((U0_str, "0"), U_m=U_m, degree=2)
        bc0 = df.DirichletBC(V, df.Constant((0, 0)), mf, bc_dict["obstacle"])
        bc1 = df.DirichletBC(V, df.Constant((0, 0)), mf,
                             bc_dict["channel_walls"])
        bc2 = df.DirichletBC(V, U0, mf, bc_dict["inlet"])
        bc3 = df.DirichletBC(Q, df.Constant(0), mf, bc_dict["outlet"])
        self.bcu = [bc0, bc1, bc2]
        self.bcp = [bc3]
        self.ds_ = df.Measure("ds", domain=self.mesh, subdomain_data=mf)
        return
예제 #4
0
    def setUp(self):
        mesh = dl.UnitSquareMesh(10, 10)
        self.mpi_rank = dl.MPI.rank(mesh.mpi_comm())
        self.mpi_size = dl.MPI.size(mesh.mpi_comm())

        Vh1 = dl.FunctionSpace(mesh, 'Lagrange', 1)

        uh, vh = dl.TrialFunction(Vh1), dl.TestFunction(Vh1)
        mh, test_mh = dl.TrialFunction(Vh1), dl.TestFunction(Vh1)

        ## Set up B
        ndim = 2
        ntargets = 200
        np.random.seed(seed=1)
        targets = np.random.uniform(0.1, 0.9, [ntargets, ndim])
        B = assemblePointwiseObservation(Vh1, targets)

        ## Set up Asolver
        alpha = dl.Constant(1.0)
        varfA = ufl.inner(ufl.grad(uh), ufl.grad(vh))*ufl.dx +\
                    alpha*ufl.inner(uh,vh)*ufl.dx
        A = dl.assemble(varfA)
        Asolver = PETScKrylovSolver(A.mpi_comm(), "cg", amg_method())
        Asolver.set_operator(A)
        Asolver.parameters["maximum_iterations"] = 100
        Asolver.parameters["relative_tolerance"] = 1e-12

        ## Set up C
        varfC = ufl.inner(mh, vh) * ufl.dx
        C = dl.assemble(varfC)

        self.Hop = Hop(B, Asolver, C)

        ## Set up RHS Matrix M.
        varfM = ufl.inner(mh, test_mh) * ufl.dx
        self.M = dl.assemble(varfM)
        self.Minv = PETScKrylovSolver(self.M.mpi_comm(), "cg", amg_method())
        self.Minv.set_operator(self.M)
        self.Minv.parameters["maximum_iterations"] = 100
        self.Minv.parameters["relative_tolerance"] = 1e-12

        myRandom = Random(self.mpi_rank, self.mpi_size)

        x_vec = dl.Vector(mesh.mpi_comm())
        self.Hop.init_vector(x_vec, 1)

        k_evec = 10
        p_evec = 50
        self.Omega = MultiVector(x_vec, k_evec + p_evec)
        self.k_evec = k_evec

        myRandom.normal(1., self.Omega)
예제 #5
0
 def setup_fnc_spaces(self):
     """
     Call me again if the mesh is modified, like after adaptive meshing.
     """
     # Linear Lagrange triangles for the velocity.
     self.v_fnc_space = dfn.FunctionSpace(self.mesh, "CG", 1)
     self.v = dfn.TrialFunction(self.v_fnc_space)
     self.vt = dfn.TestFunction(self.v_fnc_space)
     # We use piecewise constant discontinuous elements so that
     # no matrix inversion is required in order to update the stress
     self.S_fnc_space = dfn.VectorFunctionSpace(self.mesh, "DG", 0)
     self.S = dfn.TrialFunction(self.S_fnc_space)
     self.St = dfn.TestFunction(self.S_fnc_space)
예제 #6
0
 def __init__(self, adjoint = False):
     self.dt     = dol.Constant(0)
     self.uold   = dol.interpolate(self.u0_expr, self.V)
     self.u0     = dol.interpolate(self.u0_expr, self.V)
     self.unew   = dol.Function(self.V)
     self.ulow   = dol.Function(self.V)
     self.v      = dol.TestFunction(self.V)
     self.utrial = dol.TrialFunction(self.V)
     
     if adjoint:
         self.zold   = dol.interpolate(self.z0_expr, self.V)
         self.z0     = dol.interpolate(self.z0_expr, self.V)
         self.znew   = dol.Function(self.V)
         self.ztrial = dol.TrialFunction(self.V)
예제 #7
0
def testblockdiagonal():
    mesh = dl.UnitSquareMesh(40, 40)
    V1 = dl.FunctionSpace(mesh, "Lagrange", 2)
    test1, trial1 = dl.TestFunction(V1), dl.TrialFunction(V1)
    V2 = dl.FunctionSpace(mesh, "Lagrange", 2)
    test2, trial2 = dl.TestFunction(V2), dl.TrialFunction(V2)
    V1V2 = createMixedFS(V1, V2)
    test12, trial12 = dl.TestFunction(V1V2), dl.TrialFunction(V1V2)
    bd = BlockDiagonal(V1, V2, mesh.mpi_comm())

    mpirank = dl.MPI.rank(mesh.mpi_comm())

    if mpirank == 0: print 'mass+mass'
    M1 = dl.assemble(dl.inner(test1, trial1) * dl.dx)
    M2 = dl.assemble(dl.inner(test1, trial2) * dl.dx)
    M12bd = bd.assemble(M1, M2)
    M12 = dl.assemble(dl.inner(test12, trial12) * dl.dx)
    diff = M12bd - M12
    nn = diff.norm('frobenius')
    if mpirank == 0:
        print '\nnn={}'.format(nn)

    if mpirank == 0: print 'mass+2ndD'
    D2 = dl.assemble(
        dl.inner(dl.nabla_grad(test1), dl.nabla_grad(trial2)) * dl.dx)
    M1D2bd = bd.assemble(M1, D2)
    tt1, tt2 = test12
    tl1, tl2 = trial12
    M1D2 = dl.assemble(
        dl.inner(tt1, tl1) * dl.dx +
        dl.inner(dl.nabla_grad(tt2), dl.nabla_grad(tl2)) * dl.dx)
    diff = M1D2bd - M1D2
    nn = diff.norm('frobenius')
    if mpirank == 0:
        print 'nn={}'.format(nn)

    if mpirank == 0: print 'wM+wM'
    u11 = dl.interpolate(dl.Expression("x[0]*x[1]", degree=10), V1)
    u22 = dl.interpolate(dl.Expression("11+x[0]+x[1]", degree=10), V2)
    M1 = dl.assemble(dl.inner(u11 * test1, trial1) * dl.dx)
    M2 = dl.assemble(dl.inner(u22 * test1, trial2) * dl.dx)
    M12bd = bd.assemble(M1, M2)
    ua, ub = dl.interpolate(dl.Expression(("x[0]*x[1]", "11+x[0]+x[1]"),\
    degree=10), V1V2)
    M12 = dl.assemble(
        dl.inner(ua * tt1, tl1) * dl.dx + dl.inner(ub * tt2, tl2) * dl.dx)
    diff = M12bd - M12
    nn = diff.norm('frobenius')
    if mpirank == 0:
        print 'nn={}'.format(nn)
    def get_initial_conditions(self,rho_solute=const.rhom):
        """
        Set the initial condition at the end of melting (melting can be solved analytically
        """

        # --- Initial states --- #
        # ice temperature
        self.u0_i = dolfin.Function(self.ice_V)
        T,lam,self.R_melt,self.t_melt = analyticalMelt(np.exp(self.ice_coords[:,0])*self.R_melt,self.T_inf,self.Q_initialize,R_target=self.R_melt)
        self.u0_i.vector()[:] = T/abs(self.T_inf)
        # solution temperature
        self.u0_s = dolfin.Function(self.sol_V)
        T,lam,self.R_melt,self.t_melt = analyticalMelt(np.exp(self.sol_coords[:,0])*self.R_melt,self.T_inf,self.Q_initialize,R_target=self.R_melt)
        self.u0_s.vector()[:] = T/abs(self.T_inf)
        # solution concentration
        self.u0_c = dolfin.interpolate(dolfin.Constant(self.C_init),self.sol_V)

        # --- Time Array --- #
        # Now that we have the melt-out time, we can define the time array
        self.ts = np.arange(self.t_melt,self.t_final+self.dt,self.dt)/self.t0
        self.dt /= self.t0
        # Define the ethanol source
        self.source_timing = self.ts[np.argmin(abs(self.ts-self.source_timing/self.t0))]
        if 'gaussian_source' in self.flags:
            self.source_duration /= self.t0
            self.source = self.source_mass_final/(self.source_duration*np.sqrt(np.pi))*np.exp(-((self.ts-self.source_timing)/self.source_duration)**2.)
        else:
            self.source = np.zeros_like(self.ts)
            self.source[np.argmin(abs(self.ts-self.source_timing))] = self.source_mass_final/self.dt

        # --- Define the test and trial functions --- #
        self.u_i = dolfin.TrialFunction(self.ice_V)
        self.v_i = dolfin.TestFunction(self.ice_V)
        self.T_i = dolfin.Function(self.ice_V)
        self.u_s = dolfin.TrialFunction(self.sol_V)
        self.v_s = dolfin.TestFunction(self.sol_V)
        self.T_s = dolfin.Function(self.sol_V)
        self.C = dolfin.Function(self.sol_V)
        self.Tf = Tf_depression(self.C,linear=True)/abs(self.T_inf)
        self.Tf_wall = dolfin.project(self.Tf,self.sol_V).vector()[self.sol_idx_wall]
        # Get the updated solution properties
        self.rhos = dolfin.project(dolfin.Expression('C + rhow*(1.-C/rho)',degree=1,C=self.C,rhow=const.rhow,rho=rho_solute),self.sol_V)
        self.cs = dolfin.project(dolfin.Expression('ce*(C/rho) + cw*(1.-C/rho)',degree=1,C=self.C,cw=const.cw,ce=const.ce,rho=rho_solute),self.sol_V)
        self.ks = dolfin.project(dolfin.Expression('ke*(C/rho) + kw*(1.-C/rho)',degree=1,C=self.C,kw=const.kw,ke=const.ke,rho=rho_solute),self.sol_V)
        self.rhos_wall = self.rhos.vector()[self.sol_idx_wall]
        self.cs_wall = self.cs.vector()[self.sol_idx_wall]
        self.ks_wall = self.ks.vector()[self.sol_idx_wall]

        self.flags.append('get_ic')
예제 #9
0
    def setUp(self):
        mesh = dl.UnitSquareMesh(10, 10)
        self.mpi_rank = dl.MPI.rank(mesh.mpi_comm())
        self.mpi_size = dl.MPI.size(mesh.mpi_comm())

        Vh1 = dl.FunctionSpace(mesh, 'Lagrange', 1)

        uh, vh = dl.TrialFunction(Vh1), dl.TestFunction(Vh1)
        mh = dl.TrialFunction(Vh1)

        # Define B
        ndim = 2
        ntargets = 10
        np.random.seed(seed=1)
        targets = np.random.uniform(0.1, 0.9, [ntargets, ndim])
        B = assemblePointwiseObservation(Vh1, targets)

        # Define Asolver
        alpha = dl.Constant(0.1)
        varfA = dl.inner(dl.nabla_grad(uh), dl.nabla_grad(vh))*dl.dx +\
                    alpha*dl.inner(uh,vh)*dl.dx
        A = dl.assemble(varfA)
        Asolver = dl.PETScKrylovSolver(A.mpi_comm(), "cg", amg_method())
        Asolver.set_operator(A)
        Asolver.parameters["maximum_iterations"] = 100
        Asolver.parameters["relative_tolerance"] = 1e-12

        # Define M
        varfC = dl.inner(mh, vh) * dl.dx
        C = dl.assemble(varfC)

        self.J = J_op(B, Asolver, C)

        self.k_evec = 10
        p_evec = 50

        myRandom = Random(self.mpi_rank, self.mpi_size)

        x_vec = dl.Vector(C.mpi_comm())
        C.init_vector(x_vec, 1)

        self.Omega = MultiVector(x_vec, self.k_evec + p_evec)
        myRandom.normal(1., self.Omega)

        y_vec = dl.Vector(C.mpi_comm())
        B.init_vector(y_vec, 0)
        self.Omega_adj = MultiVector(y_vec, self.k_evec + p_evec)
        myRandom.normal(1., self.Omega_adj)
예제 #10
0
def delta_dg(mesh, expr):
    CG = df.FunctionSpace(mesh, "CG", 1)
    DG = df.FunctionSpace(mesh, "DG", 0)

    CG3 = df.VectorFunctionSpace(mesh, "CG", 1)
    DG3 = df.VectorFunctionSpace(mesh, "DG", 0)

    m = df.interpolate(expr, DG3)
    n = df.FacetNormal(mesh)

    u_dg = df.TrialFunction(DG)
    v_dg = df.TestFunction(DG)

    u3 = df.TrialFunction(CG3)
    v3 = df.TestFunction(CG3)

    a = u_dg * df.inner(v3, n) * df.ds - u_dg * df.div(v3) * df.dx

    mm = m.vector().array()
    mm.shape = (3, -1)

    K = df.assemble(a).array()
    L3 = df.assemble(df.dot(v3, df.Constant([1, 1, 1])) * df.dx).array()
    f = np.dot(K, mm[0]) / L3

    fun1 = df.Function(CG3)
    fun1.vector().set_local(f)
    df.plot(fun1)

    a = df.div(u3) * v_dg * df.dx
    A = df.assemble(a).array()
    L = df.assemble(v_dg * df.dx).array()

    h = np.dot(A, f) / L

    fun = df.Function(DG)
    fun.vector().set_local(h)
    df.plot(fun)
    res = []
    for x in xs:
        res.append(fun(x, 5, 0.5))
    """
    fun2 =df.interpolate(fun, df.VectorFunctionSpace(mesh, "CG", 1))
    file = df.File('field2.pvd')
    file << fun2
    """

    return res
예제 #11
0
 def _get_rtmass(self,output_petsc=True):
     """
     Get the square root of assembled mass matrix M using lumping.
     --credit to: Umberto Villa
     """
     test = df.TestFunction(self.V)
     V_deg = self.V.ufl_element().degree()
     try:
         V_q_fe = df.FiniteElement('Quadrature',self.V.mesh().ufl_cell(),2*V_deg,quad_scheme='default')
         V_q = df.FunctionSpace(self.V.mesh(),V_q_fe)
     except:
         print('Use FiniteElement in specifying FunctionSpace after version 1.6.0!')
         V_q = df.FunctionSpace(self.V.mesh(), 'Quadrature', 2*self.V._FunctionSpace___degree)
     trial_q = df.TrialFunction(V_q)
     test_q = df.TestFunction(V_q)
     M_q = df.PETScMatrix()
     df.assemble(trial_q*test_q*df.dx,tensor=M_q,form_compiler_parameters={'quadrature_degree': 2*V_deg})
     ones = df.interpolate(df.Constant(1.), V_q).vector()
     dM_q = M_q*ones
     M_q.zero()
     dM_q_2fill = ones.array() / np.sqrt(dM_q.array() )
     dM_q.set_local( dM_q_2fill )
     M_q.set_diagonal(dM_q)
     mixedM = df.PETScMatrix()
     df.assemble(trial_q*test*df.dx,tensor=mixedM,form_compiler_parameters={'quadrature_degree': 2*V_deg})
     if output_petsc and df.has_petsc4py():
         rtM = df.PETScMatrix(df.as_backend_type(mixedM).mat().matMult(df.as_backend_type(M_q).mat()))
     else:
         rtM = sps.csr_matrix(mixedM.array()*dM_q_2fill)
         csr_trim0(rtM,1e-12)
     return rtM
예제 #12
0
    def __init__(self, simulation, u_conv):
        """
        Given a velocity in DG, e.g DG2, produce a velocity in DGT0,
        i.e. a constant on each facet
        """
        V = u_conv[0].function_space()
        V_dgt0 = dolfin.FunctionSpace(V.mesh(), 'DGT', 0)
        u = dolfin.TrialFunction(V_dgt0)
        v = dolfin.TestFunction(V_dgt0)

        ndim = simulation.ndim
        w = u_conv
        w_new = dolfin.as_vector(
            [dolfin.Function(V_dgt0) for _ in range(ndim)])

        dot, avg, dS, ds = dolfin.dot, dolfin.avg, dolfin.dS, dolfin.ds
        a = dot(avg(u), avg(v)) * dS + dot(u, v) * ds

        L = []
        for d in range(ndim):
            L.append(avg(w[d]) * avg(v) * dS + w[d] * v * ds)

        self.lhs = [dolfin.Form(Li) for Li in L]
        self.A = dolfin.assemble(a)
        self.solver = dolfin.PETScKrylovSolver('cg')
        self.velocity = simulation.data['u_conv_dgt0'] = w_new
def test_basic_interior_facet_assembly():

    ghost_mode = dolfin.cpp.mesh.GhostMode.none
    if (dolfin.MPI.size(dolfin.MPI.comm_world) > 1):
        ghost_mode = dolfin.cpp.mesh.GhostMode.shared_facet

    mesh = dolfin.RectangleMesh(
        dolfin.MPI.comm_world,
        [numpy.array([0.0, 0.0, 0.0]),
         numpy.array([1.0, 1.0, 0.0])], [5, 5],
        cell_type=dolfin.cpp.mesh.CellType.Type.triangle,
        ghost_mode=ghost_mode)

    V = dolfin.function.FunctionSpace(mesh, ("DG", 1))
    u, v = dolfin.TrialFunction(V), dolfin.TestFunction(V)

    a = ufl.inner(ufl.avg(u), ufl.avg(v)) * ufl.dS

    A = dolfin.fem.assemble_matrix(a)
    A.assemble()
    assert isinstance(A, PETSc.Mat)

    L = ufl.conj(ufl.avg(v)) * ufl.dS

    b = dolfin.fem.assemble_vector(L)
    b.assemble()
    assert isinstance(b, PETSc.Vec)
예제 #14
0
    def linear_solver(self, phi_k):

        # cast params as constant functions so that, if they are set to 0, FEniCS still understand
        # what is being integrated
        mu, M = Constant(self.physics.mu), Constant(self.physics.M)
        lam = Constant(self.physics.lam)
        mn, mf = Constant(self.mn), Constant(self.mf)

        D = self.physics.D

        # boundary condition
        Dirichlet_bc = self.get_Dirichlet_bc()

        # trial and test function
        phi = d.TrialFunction(self.fem.S)
        v = d.TestFunction(self.fem.S)

        # r^(D-1)
        rD = Expression('pow(x[0],D-1)', D=D, degree=self.fem.func_degree)

        # bilinear form a and linear form L
        a = - inner( grad(phi), grad(v) ) * rD * dx + ( (mu/mn)**2  \
            - 3.*lam*(mf/mn)**2*phi_k**2 ) * phi * v * rD * dx
        L = ((mn**(D - 2.) / (mf * M)) * self.source.rho - 2. * lam *
             (mf / mn)**2 * phi_k**3) * v * rD * dx

        # define a vector with the solution
        sol = d.Function(self.fem.S)

        # solve linearised system
        pde = d.LinearVariationalProblem(a, L, sol, Dirichlet_bc)
        solver = d.LinearVariationalSolver(pde)
        solver.solve()

        return sol
예제 #15
0
    def assembleA(self, x, assemble_adjoint=False, assemble_rhs=False):
        """
        Assemble the matrices and rhs for the forward/adjoint problems
        """
        trial = dl.TrialFunction(self.Vh[STATE])
        test = dl.TestFunction(self.Vh[STATE])
        c = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
        Avarf = dl.inner(
            dl.exp(c) * dl.nabla_grad(trial), dl.nabla_grad(test)) * dl.dx
        if not assemble_adjoint:
            bform = dl.inner(self.f, test) * dl.dx
            Matrix, rhs = dl.assemble_system(Avarf, bform, self.bc)
        else:
            # Assemble the adjoint of A (i.e. the transpose of A)
            s = vector2Function(x[STATE], self.Vh[STATE])
            bform = dl.inner(dl.Constant(0.), test) * dl.dx
            Matrix, _ = dl.assemble_system(dl.adjoint(Avarf), bform, self.bc0)
            Bu = -(self.B * x[STATE])
            Bu += self.u_o
            rhs = dl.Vector()
            self.B.init_vector(rhs, 1)
            self.B.transpmult(Bu, rhs)
            rhs *= 1.0 / self.noise_variance

        if assemble_rhs:
            return Matrix, rhs
        else:
            return Matrix
예제 #16
0
def run_model(kappa,forcing,function_space,boundary_conditions=None):
    """
    Solve complex valued Helmholtz equation by solving coupled system, one
    for the real part of the solution one for the imaginary part.

    """
    mesh = function_space.mesh()
    kappa_sq = kappa**2
    
    if boundary_conditions==None:
        bndry_obj  = dl.CompiledSubDomain("on_boundary")
        boundary_conditions = [['dirichlet',bndry_obj,[0,0]]]

    num_bndrys = len(boundary_conditions)
    boundaries = mark_boundaries(mesh,boundary_conditions)
    dirichlet_bcs = collect_dirichlet_boundaries(
        function_space,boundary_conditions,boundaries)

    # To express integrals over the boundary parts using ds(i), we must first
    # redefine the measure ds in terms of our boundary markers:
    ds = dl.Measure('ds', domain=mesh, subdomain_data=boundaries)
    #dx = dl.Measure('dx', domain=mesh)
    dx = dl.dx
    
    (pr, pi) = dl.TrialFunction(function_space)
    (vr, vi) = dl.TestFunction(function_space)

    # real part
    bilinear_form =  kappa_sq*(pr*vr - pi*vi)*dx
    bilinear_form += (-dl.inner(dl.nabla_grad(pr),dl.nabla_grad(vr))+
          dl.inner(dl.nabla_grad(pi),dl.nabla_grad(vi)))*dx
    # imaginary part
    bilinear_form += kappa_sq*(pr*vi + pi*vr)*dx
    bilinear_form += -(dl.inner(dl.nabla_grad(pr),dl.nabla_grad(vi))+
           dl.inner(dl.nabla_grad(pi),dl.nabla_grad(vr)))*dx
    
    for ii in range(num_bndrys):
        if (boundary_conditions[ii][0]=='robin'):
            alpha_real, alpha_imag = boundary_conditions[ii][3]
            bilinear_form -= alpha_real*(pr*vr-pi*vi)*ds(ii)
            bilinear_form -= alpha_imag*(pr*vi+pi*vr)*ds(ii)

    forcing_real,forcing_imag=forcing
    rhs = (forcing_real*vr+forcing_real*vi+forcing_imag*vr-forcing_imag*vi)*dx
                               
    for ii in range(num_bndrys):
        if ((boundary_conditions[ii][0]=='robin') or
            (boundary_conditions[ii][0]=='neumann')):
            beta_real, beta_imag=boundary_conditions[ii][2]
            # real part of robin boundary conditions
            rhs+=(beta_real*vr - beta_imag*vi)*ds(ii)
            # imag part of robin boundary conditions
            rhs+=(beta_real*vi + beta_imag*vr)*ds(ii)        

    # compute solution
    p = dl.Function(function_space)
    #solve(a == L, p)
    dl.solve(bilinear_form == rhs, p, bcs=dirichlet_bcs)

    return p
예제 #17
0
def solve_initial_pressure(w_NSp, p, q, u, v, bcs_NSp, M_, g_, phi_, rho_,
                           rho_e_, V_, drho, sigma_bar, eps, grav, dveps,
                           enable_PF, enable_EC):
    V = u.function_space()
    grad_p = df.TrialFunction(V)
    grad_p_out = df.Function(V)
    F_grad_p = (df.dot(grad_p, v) * df.dx - rho_ * df.dot(grav, v) * df.dx)
    if enable_PF:
        F_grad_p += -drho * M_ * df.inner(df.grad(u), df.outer(df.grad(g_),
                                                               v)) * df.dx
        F_grad_p += -sigma_bar * eps * df.inner(
            df.outer(df.grad(phi_), df.grad(phi_)), df.grad(v)) * df.dx
    if enable_EC and rho_e_ != 0:
        F_grad_p += rho_e_ * df.dot(df.grad(V_), v) * df.dx
    if enable_PF and enable_EC:
        F_grad_p += dveps * df.dot(df.grad(phi_), v) * df.dot(
            df.grad(V_), df.grad(V_)) * df.dx

    info_red("Solving initial grad_p...")
    df.solve(df.lhs(F_grad_p) == df.rhs(F_grad_p), grad_p_out)

    F_p = (df.dot(df.grad(q), df.grad(p)) * df.dx -
           df.dot(df.grad(q), grad_p_out) * df.dx)
    info_red("Solving initial p...")
    df.solve(df.lhs(F_p) == df.rhs(F_p), w_NSp, bcs_NSp)
예제 #18
0
    def get_initial_conditions(self,melt_velocity=-1./3600.):
        """
        Set the initial condition to no melted ice and all at the bulk ice temperature

        Parameters
        ----------
        melt_velocity: float
            velocity of the downgoing drill (m/s)
        """

        # --- Initial states --- #
        # ice temperature
        self.u0_i = dolfin.interpolate(dolfin.Constant(self.Tstar),self.ice_V)
        # the upward velocity is equal to negative the melt rate (the mesh is Lagrangian following the drill)
        self.velocity = dolfin.Expression('melt',melt=melt_velocity*self.t0,degree=1)

        # --- Time Array --- #
        # Now that we have the melt-out time, we can define the time array
        self.ts = np.arange(0.,self.t_final+self.dt,self.dt)/self.t0
        self.dt /= self.t0

        # --- Define the test and trial functions --- #
        self.u_i = dolfin.TrialFunction(self.ice_V)
        self.v_i = dolfin.TestFunction(self.ice_V)
        self.T_i = dolfin.Function(self.ice_V)

        self.flags.append('get_ic')
예제 #19
0
 def solveFwd(self, state, x):
     """ Solve the possibly nonlinear forward problem:
     Given :math:`m`, find :math:`u` such that
     
         .. math:: \\delta_p F(u, m, p;\\hat{p}) = 0,\\quad \\forall \\hat{p}."""
     self.n_calls["forward"] += 1
     if self.solver is None:
         self.solver = self._createLUSolver()
     if self.is_fwd_linear:
         u = dl.TrialFunction(self.Vh[STATE])
         m = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
         p = dl.TestFunction(self.Vh[ADJOINT])
         res_form = self.varf_handler(u, m, p)
         A_form = ufl.lhs(res_form)
         b_form = ufl.rhs(res_form)
         A, b = dl.assemble_system(A_form, b_form, bcs=self.bc)
         self.solver.set_operator(A)
         self.solver.solve(state, b)
     else:
         u = vector2Function(x[STATE], self.Vh[STATE])
         m = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
         p = dl.TestFunction(self.Vh[ADJOINT])
         res_form = self.varf_handler(u, m, p)
         dl.solve(res_form == 0, u, self.bc)
         state.zero()
         state.axpy(1., u.vector())
def make_mass_matrix_unlumped(function_space_V):
    V = function_space_V
    u_trial = dl.TrialFunction(V)
    v_test = dl.TestFunction(V)
    mass_form = u_trial * v_test * dl.dx
    M = dl.assemble(mass_form)
    return M
예제 #21
0
파일: dolfin.py 프로젝트: pkgw/vernon
    def solve(self, vkscale=1., lscale=1., sscale=1.):
        """This approach only works for small grids since the memory requirements
        rapidly become prohibitive. (nl, nk, nv) = (8, 45, 40) is just barely
        doable on my laptop. If the memory is available, computation time is
        not significant.

        """
        D = d.Function(self.tensor_space) # diffusion tensor
        Q = d.Function(self.scalar_space) # source term
        u = d.TrialFunction(self.scalar_space) # u is my 'f'
        v = d.TestFunction(self.scalar_space)
        soln = d.Function(self.scalar_space)

        a = d.dot(d.dot(D, d.grad(u)), d.grad(v)) * d.dx
        L = Q * v * d.dx
        equation = (a == L)
        soln = d.Function(self.scalar_space)

        bc = d.DirichletBC(self.scalar_space, d.Constant(0), direct_boundary)

        dbuf = np.zeros(D.vector().size()).reshape((-1, 3, 3))
        dbuf[:,0,0] = self.D_VV * vkscale
        dbuf[:,1,0] = self.D_VK * vkscale
        dbuf[:,0,1] = self.D_VK * vkscale
        dbuf[:,1,1] = self.D_KK * vkscale
        dbuf[:,2,2] = self.D_LL * lscale
        D.vector()[:] = dbuf.reshape((-1,))

        Q.vector()[:] = self.source_term * sscale

        d.solve(equation, soln, bc)

        return self.to_cube(soln.vector().array())
    def _init_forms(self):

        logger.debug("Initialize forms mechanics problem")
        # Displacement and hydrostatic_pressure
        u, p = dolfin.split(self.state)
        v, q = dolfin.split(self.state_test)

        # Some mechanical quantities
        F = dolfin.variable(kinematics.DeformationGradient(u))
        J = kinematics.Jacobian(F)
        dx = self.geometry.dx

        internal_energy = (self.material.strain_energy(F, ) +
                           self.material.compressibility(p, J))

        self._virtual_work = dolfin.derivative(
            internal_energy * dx,
            self.state,
            self.state_test,
        )

        external_work = self._external_work(u, v)
        if external_work is not None:
            self._virtual_work += external_work

        self._set_dirichlet_bc()
        self._jacobian = dolfin.derivative(
            self._virtual_work,
            self.state,
            dolfin.TrialFunction(self.state_space),
        )
        self._init_solver()
예제 #23
0
def test_custom_mesh_loop_cffi_rank2(set_vals):
    """Test numba assembler for bilinear form"""

    mesh = dolfin.generation.UnitSquareMesh(dolfin.MPI.comm_world, 64, 64)
    V = dolfin.FunctionSpace(mesh, ("Lagrange", 1))

    # Test against generated code and general assembler
    u, v = dolfin.TrialFunction(V), dolfin.TestFunction(V)
    a = inner(u, v) * dx
    A0 = dolfin.fem.assemble_matrix(a)
    A0.assemble()

    A0.zeroEntries()
    start = time.time()
    dolfin.fem.assemble_matrix(A0, a)
    end = time.time()
    print("Time (C++, pass 2):", end - start)
    A0.assemble()

    # Unpack mesh and dofmap data
    c = mesh.topology.connectivity(2, 0).connections()
    pos = mesh.topology.connectivity(2, 0).pos()
    geom = mesh.geometry.points
    dofs = V.dofmap().dof_array

    A1 = A0.copy()
    for i in range(2):
        A1.zeroEntries()
        start = time.time()
        assemble_matrix_cffi(A1.handle, (c, pos), geom, dofs, set_vals, PETSc.InsertMode.ADD_VALUES)
        end = time.time()
        print("Time (Numba, pass {}): {}".format(i, end - start))
        A1.assemble()

    assert (A1 - A0).norm() == pytest.approx(0.0)
예제 #24
0
    def __init__(self, Vh, dX, bc, form=None):
        """
        Constructor:
        - Vh: the finite element space for the state variable.
        - dX: the integrator on subdomain X where observation are presents.
        E.g. dX = dl.dx means observation on all \Omega and dX = dl.ds means observations on all \partial \Omega.
        - bc: If the forward problem imposes Dirichlet boundary conditions u = u_D on \Gamma_D;
              bc is a dl.DirichletBC object that prescribes homogeneuos Dirichlet conditions u = 0 on \Gamma_D.
        - form: if form = None we compute the L^2(X) misfit:
          \int_X (u - ud)^2 dX,
          otherwise the integrand specified in form will be used.
        """
        if form is None:
            u, v = dl.TrialFunction(Vh), dl.TestFunction(Vh)
            self.W = dl.assemble(dl.inner(u, v) * dX)
        else:
            self.W = dl.assemble(form)

        if bc is not None:
            Wt = Transpose(self.W)
            self.bc.zero(Wt)
            self.W = Transpose(Wt)
            self.bc.zero(self.W)
        self.d = dl.Vector()
        self.W.init_vector(self.d, 1)
        self.noise_variance = 0
예제 #25
0
 def __init__(self,V,sigma=1.25,s=0.0625,mean=None,rel_tol=1e-10,max_iter=100,**kwargs):
     self.V=V
     self.dim=V.dim()
     self.dof_coords=get_dof_coords(V)
     self.sigma=sigma
     self.s=s
     self.mean=mean
     self.mpi_comm=kwargs['mpi_comm'] if 'mpi_comm' in kwargs else df.mpi_comm_world()
     
     # mass matrix and its inverse
     M_form=df.inner(df.TrialFunction(V),df.TestFunction(V))*df.dx
     self.M=df.PETScMatrix()
     df.assemble(M_form,tensor=self.M)
     self.Msolver = df.PETScKrylovSolver("cg", "jacobi")
     self.Msolver.set_operator(self.M)
     self.Msolver.parameters["maximum_iterations"] = max_iter
     self.Msolver.parameters["relative_tolerance"] = rel_tol
     self.Msolver.parameters["error_on_nonconvergence"] = True
     self.Msolver.parameters["nonzero_initial_guess"] = False
     # square root of mass matrix
     self.rtM=self._get_rtmass()
     
     # kernel matrix and its square root
     self.K=self._get_ker()
     self.rtK = _get_sqrtm(self.K,'K')
     
     # set solvers
     for op in ['K']:
         operator=getattr(self, op)
         solver=self._set_solver(operator,op)
         setattr(self, op+'solver', solver)
     
     if mean is None:
         self.mean=df.Vector()
         self.init_vector(self.mean,0)
예제 #26
0
파일: Solver.py 프로젝트: 19ec94/f2me
    def custom_newton_solver(self):
        V = self.my_function_space_cls.V
        F = self.my_var_prob_cls.F
        #self.u = my_function_space_cls.u
        du = df.TrialFunction(V)  #TrialFunctions --> wrong, without 's'
        Jac = df.derivative(F, self.u, du)

        absolute_tol = 1E-5
        relative_tol = 9E-2
        u_inc = df.Function(V)
        nIter = 0
        relative_residual = 1
        CONVERGED = True
        MAX_ITER = 5000
        while relative_residual > relative_tol and nIter < MAX_ITER and CONVERGED:
            nIter += 1
            A, b = df.assemble_system(Jac, -(F), [])
            df.solve(A, u_inc.vector(), b)
            #df.solve(F == 0, u_inc.vector(), [], J=Jac,  solver_parameters={'newton_solver' : {'linear_solver' : 'mumps'}})
            relative_residual = u_inc.vector().norm('l2')
            #a = df.assemble(F)
            residual = b.norm('l2')
            lmbda = 0.8
            self.u.vector()[:] += lmbda * u_inc.vector()
            if residual > 1000:
                CONVERGED = False
                print("Did not converge after {} Iterations".format(nIter))
            elif residual < absolute_tol:
                CONVERGED = False
                print("converged after {} Iterations".format(nIter))
            print('{0:2d}  {1:3.2E}  {2:5e}'.format(nIter, relative_residual,
                                                    residual))
예제 #27
0
def test_basic_assembly():
    mesh = dolfin.generation.UnitSquareMesh(dolfin.MPI.comm_world, 12, 12)
    V = dolfin.FunctionSpace(mesh, ("Lagrange", 1))
    u, v = dolfin.TrialFunction(V), dolfin.TestFunction(V)

    a = 1.0 * inner(u, v) * dx
    L = inner(1.0, v) * dx

    # Initial assembly
    A = dolfin.fem.assemble(a)
    b = dolfin.fem.assemble(L)
    assert isinstance(A, dolfin.cpp.la.PETScMatrix)
    assert isinstance(b, dolfin.cpp.la.PETScVector)

    # Second assembly
    A = dolfin.fem.assemble(A, a)
    b = dolfin.fem.assemble(b, L)
    assert isinstance(A, dolfin.cpp.la.PETScMatrix)
    assert isinstance(b, dolfin.cpp.la.PETScVector)

    # Function as coefficient
    f = dolfin.Function(V)
    a = f * inner(u, v) * dx
    A = dolfin.fem.assemble(a)
    assert isinstance(A, dolfin.cpp.la.PETScMatrix)
예제 #28
0
def get_distance_function(config, domains):
    V = dolfin.FunctionSpace(config.domain.mesh, "CG", 1)
    v = dolfin.TestFunction(V)
    d = dolfin.TrialFunction(V)
    sol = dolfin.Function(V)
    s = dolfin.interpolate(Constant(1.0), V)
    domains_func = dolfin.Function(dolfin.FunctionSpace(config.domain.mesh, "DG", 0))
    domains_func.vector().set_local(domains.array().astype(numpy.float))

    def boundary(x):
        eps_x = config.params["turbine_x"]
        eps_y = config.params["turbine_y"]

        min_val = 1
        for e_x, e_y in [(-eps_x, 0), (eps_x, 0), (0, -eps_y), (0, eps_y)]:
            try:
                min_val = min(min_val, domains_func((x[0] + e_x, x[1] + e_y)))
            except RuntimeError:
                pass

        return min_val == 1.0

    bc = dolfin.DirichletBC(V, 0.0, boundary)

    # Solve the diffusion problem with a constant source term
    log(INFO, "Solving diffusion problem to identify feasible area ...")
    a = dolfin.inner(dolfin.grad(d), dolfin.grad(v)) * dolfin.dx
    L = dolfin.inner(s, v) * dolfin.dx
    dolfin.solve(a == L, sol, bc)

    return sol
예제 #29
0
    def __init__(me, function_space_V, initial_points=None):
        me.V = function_space_V
        me.N = me.V.dim()

        u_trial = dl.TrialFunction(me.V)
        v_test = dl.TestFunction(me.V)

        mass_form = u_trial * v_test * dl.dx
        me.M = dl.assemble(mass_form)

        me.constant_one_function = dl.interpolate(dl.Constant(1.0), me.V)

        me.NPPSS = NeumannPoissonSolver(me.V)
        me.solve_neumann_poisson = me.NPPSS.solve
        me.solve_neumann_point_source = me.NPPSS.solve_point_source

        me.points = list()
        me.impulse_responses = list()
        me.solve_S = lambda x: np.nan
        me.eta = np.zeros(me.num_pts)
        me.mu = np.nan
        me.smooth_basis = list()
        me.weighting_functions = list()

        if initial_points is not None:
            me.add_points(initial_points)
예제 #30
0
    def __init__(self, V, kappa):
        '''
        Parameters
        ----------
        V : dolfin.FunctionSpace
            Function space.
        kappa : float
            Filter diffusivity constant.

        '''

        if not isinstance(V, dolfin.FunctionSpace):
            raise TypeError(
                'Parameter `V` must be of type `dolfin.FunctionSpace`.')

        v = dolfin.TestFunction(V)
        f = dolfin.TrialFunction(V)

        x = V.mesh().coordinates()
        l = (x.max(0) - x.min(0)).min()
        k = Constant(float(kappa) * l**2)

        a_M = f * v * dx
        a_D = k * dot(grad(f), grad(v)) * dx

        A = assemble(a_M + a_D)
        self._M = assemble(a_M)

        self.solver = dolfin.LUSolver(A, "mumps")
        self.solver.parameters["symmetric"] = True