Example #1
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
Example #2
0
 def stiffness(self):
     """The stiffness matrix as a LinearOperator."""
     u = TrialFunction(self._fefs)
     v = TestFunction(self._fefs)
     a = (nabla_grad(u), nabla_grad(v)) * dx
     A = assemble(a)
     return MatrixOperator(A.array())
Example #3
0
    def __init__(self, parameters, domain):
        rho = Constant(parameters["density [kg/m3]"])
        mu = Constant(parameters["viscosity [Pa*s]"])
        dt = Constant(parameters["dt [s]"])
        u, u_1, u_k, vu = domain.u, domain.u_1, domain.u_k, domain.vu
        p_1 = domain.p_1

        n = FacetNormal(domain.mesh)
        acceleration = rho*inner((u-u_1)/dt, vu) * dx
        convection = dot(div(rho*outer(u_k, u)), vu) * dx
        convection = rho*dot(dot(u_k, nabla_grad(u)), vu) * dx
        pressure = (inner(p_1, div(vu))*dx - dot(p_1*n, vu)*ds)
        diffusion = (-inner(mu * (grad(u) + grad(u).T), grad(vu))*dx)  # good
        # diffusion = (-inner(mu * (grad(u) + grad(u).T), grad(vu))*dx
        #               + dot(mu * (grad(u) + grad(u).T)*n, vu)*ds)  # very slow!

        # F_impl = acceleration + convection + pressure + diffusion

        # dot(u_1, nabla_grad(u_1)) works
        # dot(u, nabla_grad(u_1)) does not change!
        u_mid = (u + u_1) / 2.0
        F_impl = rho*dot((u - u_1) / dt, vu)*dx \
            + rho*dot(dot(u_1, nabla_grad(u_1)), vu)*dx \
            + inner(sigma(u_mid, p_1, mu), epsilon(vu))*dx \
            + dot(p_1*n, vu)*ds - dot(mu*nabla_grad(u_mid)*n, vu)*ds

        self.a, self.L = lhs(F_impl), rhs(F_impl)
        self.domain = domain
        self.A = assemble(self.a)
        [bc.apply(self.A) for bc in domain.bcu]
        return
def burgers_spacedisc(N=10, nu=None, x0=0.0, xE=1.0, retfemdict=False,
                      condensemats=True):

    mesh = dolfin.IntervalMesh(N, x0, xE)
    V = dolfin.FunctionSpace(mesh, 'CG', 1)

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

    # boundaries and conditions
    ugamma = dolfin.Expression('0', degree=1)

    def _spaceboundary(x, on_boundary):
        return on_boundary
    diribc = dolfin.DirichletBC(V, ugamma, _spaceboundary)

    mass = assemble(v*u*dx)
    stif = assemble(nu*inner(nabla_grad(v), nabla_grad(u))*dx)

    M = dts.mat_dolfin2sparse(mass)
    A = dts.mat_dolfin2sparse(stif)

    M, _, bcdict = dts.condense_velmatsbybcs(M, [diribc], return_bcinfo=True)
    ininds = bcdict['ininds']
    A, rhsa = dts.condense_velmatsbybcs(A, [diribc])

    def burger_nonl(vvec, t):
        v0 = expandvfunc(vvec, V=V, ininds=ininds)
        bnl = assemble(0.5*v*((v0*v0).dx(0))*dx)
        return bnl.array()[ininds]

    if retfemdict:
        return M, A, rhsa, burger_nonl, dict(V=V, diribc=diribc, ininds=ininds)
    else:
        return M, A, rhsa, burger_nonl
Example #5
0
 def readV(self, functionspaces_V):
     # Solutions:
     self.V = functionspaces_V['V']
     self.test = TestFunction(self.V)
     self.trial = TrialFunction(self.V)
     self.u0 = Function(self.V)    # u(t-Dt)
     self.u1 = Function(self.V)     # u(t)
     self.u2 = Function(self.V)    # u(t+Dt)
     self.rhs = Function(self.V)
     self.sol = Function(self.V)
     # Parameters:
     self.Vl = functionspaces_V['Vl']
     self.lam = Function(self.Vl)
     self.Vr = functionspaces_V['Vr']
     self.rho = Function(self.Vr)
     if functionspaces_V.has_key('Vm'):
         self.Vm = functionspaces_V['Vm']
         self.mu = Function(self.Vm)
         self.elastic = True
         assert(False)
     else:   
         self.elastic = False
         self.weak_k = inner(self.lam*nabla_grad(self.trial), \
         nabla_grad(self.test))*dx
         self.weak_m = inner(self.rho*self.trial,self.test)*dx
Example #6
0
    def _assemble(self):
        # Get input:
        self.gamma = self.Parameters['gamma']
        if self.Parameters.has_key('beta'): self.beta = self.Parameters['beta']
        else: self.beta = 0.0
        self.Vm = self.Parameters['Vm']
        self.m0 = Function(self.Vm)
        if self.Parameters.has_key('m0'):
            setfct(self.m0, self.Parameters['m0'])
        self.mtrial = TrialFunction(self.Vm)
        self.mtest = TestFunction(self.Vm)
        self.mysample = Function(self.Vm)
        self.draw = Function(self.Vm)
        # Assemble:
        self.R = assemble(inner(nabla_grad(self.mtrial), \
        nabla_grad(self.mtest))*dx)
        self.M = assemble(inner(self.mtrial, self.mtest) * dx)

        self.Msolver = PETScKrylovSolver('cg', 'jacobi')
        self.Msolver.parameters["maximum_iterations"] = 2000
        self.Msolver.parameters["relative_tolerance"] = 1e-24
        self.Msolver.parameters["absolute_tolerance"] = 1e-24
        self.Msolver.parameters["error_on_nonconvergence"] = True
        self.Msolver.parameters["nonzero_initial_guess"] = False
        self.Msolver.set_operator(self.M)

        # preconditioner is Gamma^{-1}:
        if self.beta > 1e-10:
            self.precond = self.gamma * self.R + self.beta * self.M
        else:
            self.precond = self.gamma * self.R + (1e-10) * self.M
        # Minvprior is M.A^2 (if you use M inner-product):
        self.Minvprior = self.gamma * self.R + self.beta * self.M
Example #7
0
def poisson_bilinear_form(coeff_func, V):
    """Assemble the discrete problem (i.e. the stiffness matrix)."""
    # setup problem, assemble and apply boundary conditions
    u = TrialFunction(V)
    v = TestFunction(V)
    a = inner(coeff_func * nabla_grad(u), nabla_grad(v)) * dx
    return a
Example #8
0
    def set_form(self, form):
        """
        This function is called by simulator.set_form to set up the equations
        for the electric field. This function will add an equation that
        sets the field to zero everywhere.

        Args:
            form: A FEniCS variational form.
        """
        # first set rho (not used in calculations for this potential)
        F = Constant(self.simulator.F)
        rho = Function(self.simulator.geometry.V)
        for ion in self.simulator.ion_list:
            rho += F * ion.z * ion.c_new
        self.rho = rho

        # update variational form
        v, d = self.simulator.v_phi, self.simulator.d_phi
        form += (inner(nabla_grad(self.phi_new), nabla_grad(v)) +
                 self.dummy_new * v + self.phi_new * d) * dx

        v, d = self.simulator.v_phi_ps, self.simulator.d_phi_ps
        form += (inner(nabla_grad(self.phi_ps_new), nabla_grad(v)) +
                 self.phi_ps_new * d + v * self.dummy_ps_new) * dx

        return form
Example #9
0
    def __init__(self, cparams, dtype_u, dtype_f):
        """
        Initialization routine

        Args:
            cparams: custom parameters for the example
            dtype_u: particle data type (will be passed parent class)
            dtype_f: acceleration data type (will be passed parent class)
        """

        # define the Dirichlet boundary
        def Boundary(x, on_boundary):
            return on_boundary

        # these parameters will be used later, so assert their existence
        assert 'c_nvars' in cparams
        assert 'nu' in cparams
        assert 't0' in cparams
        assert 'family' in cparams
        assert 'order' in cparams
        assert 'refinements' in cparams

        # add parameters as attributes for further reference
        for k,v in cparams.items():
            setattr(self,k,v)

        df.set_log_level(df.WARNING)

        df.parameters["form_compiler"]["optimize"]     = True
        df.parameters["form_compiler"]["cpp_optimize"] = True

        # set mesh and refinement (for multilevel)
        mesh = df.UnitIntervalMesh(self.c_nvars)
        # mesh = df.UnitSquareMesh(self.c_nvars[0],self.c_nvars[1])
        for i in range(self.refinements):
            mesh = df.refine(mesh)

        # self.mesh = mesh
        # define function space for future reference
        self.V = df.FunctionSpace(mesh, self.family, self.order)
        tmp = df.Function(self.V)
        print('DoFs on this level:',len(tmp.vector().array()))

        # invoke super init, passing number of dofs, dtype_u and dtype_f
        super(fenics_heat,self).__init__(self.V,dtype_u,dtype_f)

        self.g = df.Expression('-sin(a*x[0]) * (sin(t) - b*a*a*cos(t))',a=np.pi,b=self.nu,t=self.t0,degree=self.order)

        # rhs in weak form
        self.w = df.Function(self.V)
        v = df.TestFunction(self.V)
        self.a_K = -self.nu*df.inner(df.nabla_grad(self.w), df.nabla_grad(v))*df.dx + self.g*v*df.dx

        # mass matrix
        u = df.TrialFunction(self.V)
        a_M = u*v*df.dx
        self.M = df.assemble(a_M)

        self.bc = df.DirichletBC(self.V, df.Constant(0.0), Boundary)
Example #10
0
 def sqrt_precision_varf_handler(trial, test): 
     if Theta == None:
         varfL = dl.inner(dl.nabla_grad(trial), dl.nabla_grad(test))*dl.dx
     else:
         varfL = dl.inner(Theta*dl.grad(trial), dl.grad(test))*dl.dx
     varfM = dl.inner(trial,test)*dl.dx
     varfmo = mfun*dl.inner(trial,test)*dl.dx
     return dl.Constant(gamma)*varfL+dl.Constant(delta)*varfM + dl.Constant(pen)*varfmo
Example #11
0
 def assemble_matrix(x, y, nx, ny):
     diffusion.user_parameters['lower0'] = x/nx
     diffusion.user_parameters['lower1'] = y/ny
     diffusion.user_parameters['upper0'] = (x + 1)/nx
     diffusion.user_parameters['upper1'] = (y + 1)/ny
     diffusion.user_parameters['open0'] = (x + 1 == nx)
     diffusion.user_parameters['open1'] = (y + 1 == ny)
     return df.assemble(df.inner(diffusion * df.nabla_grad(u), df.nabla_grad(v)) * df.dx)
Example #12
0
 def assemble_matrix(x, y, nx, ny):
     diffusion.user_parameters["lower0"] = x / nx
     diffusion.user_parameters["lower1"] = y / ny
     diffusion.user_parameters["upper0"] = (x + 1) / nx
     diffusion.user_parameters["upper1"] = (y + 1) / ny
     diffusion.user_parameters["open0"] = x + 1 == nx
     diffusion.user_parameters["open1"] = y + 1 == ny
     return df.assemble(df.inner(diffusion * df.nabla_grad(u), df.nabla_grad(v)) * df.dx)
Example #13
0
 def assemble_matrix(x, y, nx, ny):
     diffusion.user_parameters['lower0'] = x/nx
     diffusion.user_parameters['lower1'] = y/ny
     diffusion.user_parameters['upper0'] = (x + 1)/nx
     diffusion.user_parameters['upper1'] = (y + 1)/ny
     diffusion.user_parameters['open0'] = (x + 1 == nx)
     diffusion.user_parameters['open1'] = (y + 1 == ny)
     return df.assemble(df.inner(diffusion * df.nabla_grad(u), df.nabla_grad(v)) * df.dx)
Example #14
0
def setup_NS(w_NS, u, p, v, q, p0, q0,
             dx, ds, normal,
             dirichlet_bcs_NS, neumann_bcs, boundary_to_mark,
             u_1, rho_, rho_1, mu_, c_1, grad_g_c_,
             dt, grav,
             enable_EC,
             trial_functions,
             use_iterative_solvers,
             p_lagrange,
             mesh,
             q_rhs,
             density_per_concentration,
             K,
             **namespace):
    """ Set up the Navier-Stokes subproblem. """
    mom_1 = rho_1 * u_1
    if enable_EC and density_per_concentration is not None:
        for drhodci, ci_1, grad_g_ci_, Ki in zip(
                density_per_concentration, c_1, grad_g_c_, K):
            if drhodci > 0.:
                mom_1 += -drhodci*Ki*ci_1*grad_g_ci_

    F = (1./dt * rho_1 * df.dot(u - u_1, v) * dx
         + df.inner(df.nabla_grad(u), df.outer(mom_1, v)) * dx
         + 2*mu_*df.inner(df.sym(df.nabla_grad(u)),
                          df.sym(df.nabla_grad(v))) * dx
         + 0.5*(
             1./dt * (rho_ - rho_1) * df.inner(u, v)
             - df.inner(mom_1, df.nabla_grad(df.dot(u, v)))) * dx
         - p * df.div(v) * dx
         - q * df.div(u) * dx
         - rho_ * df.dot(grav, v) * dx)

    for boundary_name, pressure in neumann_bcs["p"].iteritems():
        F += pressure * df.inner(
            normal, v) * ds(boundary_to_mark[boundary_name])

    if enable_EC:
        F += sum([ci_1*df.dot(grad_g_ci_, v)*dx
                  for ci_1, grad_g_ci_ in zip(c_1, grad_g_c_)])

    if p_lagrange:
        F += (p*q0 + q*p0)*dx

    if "u" in q_rhs:
        F += -df.dot(q_rhs["u"], v)*dx

    a, L = df.lhs(F), df.rhs(F)
    if not use_iterative_solvers:
        problem = df.LinearVariationalProblem(a, L, w_NS, dirichlet_bcs_NS)
        solver = df.LinearVariationalSolver(problem)

    else:
        solver = df.LUSolver("mumps")
        # solver.set_operator(A)
        return solver, a, L, dirichlet_bcs_NS

    return solver
def setup_NSu(w_NSu, u, v, dx, ds, normal, dirichlet_bcs_NSu, neumann_bcs,
              boundary_to_mark, u_, p_, u_1, p_1, rho_, rho_1, mu_, c_1,
              grad_g_c_, dt, grav, enable_EC, trial_functions,
              use_iterative_solvers, mesh, density_per_concentration,
              viscosity_per_concentration, K, **namespace):
    """ Set up the Navier-Stokes velocity subproblem. """
    solvers = dict()

    mom_1 = rho_1 * u_1
    if enable_EC and density_per_concentration is not None:
        for drhodci, ci_1, grad_g_ci_, Ki in zip(density_per_concentration,
                                                 c_1, grad_g_c_, K):
            if drhodci > 0.:
                mom_1 += -drhodci * Ki * ci_1 * grad_g_ci_

    F_predict = (
        1. / dt * rho_1 * df.dot(u - u_1, v) * dx +
        df.inner(df.nabla_grad(u), df.outer(mom_1, v)) * dx + 2 * mu_ *
        df.inner(df.sym(df.nabla_grad(u)), df.sym(df.nabla_grad(v))) * dx +
        0.5 * (1. / dt * (rho_ - rho_1) * df.dot(u, v) -
               df.inner(mom_1, df.grad(df.dot(u, v)))) * dx -
        p_1 * df.div(v) * dx - rho_ * df.dot(grav, v) * dx)

    for boundary_name, pressure in neumann_bcs["p"].iteritems():
        F_predict += pressure * df.inner(normal, v) * ds(
            boundary_to_mark[boundary_name])

    if enable_EC:
        F_predict += sum([
            ci_1 * df.dot(grad_g_ci_, v) * dx
            for ci_1, grad_g_ci_ in zip(c_1, grad_g_c_)
        ])

    a_predict, L_predict = df.lhs(F_predict), df.rhs(F_predict)
    #    if not use_iterative_solvers:
    problem_predict = df.LinearVariationalProblem(a_predict, L_predict, w_NSu,
                                                  dirichlet_bcs_NSu)
    solvers["predict"] = df.LinearVariationalSolver(problem_predict)
    if use_iterative_solvers:
        solvers["predict"].parameters["linear_solver"] = "bicgstab"
        solvers["predict"].parameters["preconditioner"] = "amg"

    F_correct = (rho_ * df.inner(u - u_, v) * dx - dt *
                 (p_ - p_1) * df.div(v) * dx)
    a_correct, L_correct = df.lhs(F_correct), df.rhs(F_correct)
    problem_correct = df.LinearVariationalProblem(a_correct, L_correct, w_NSu,
                                                  dirichlet_bcs_NSu)
    solvers["correct"] = df.LinearVariationalSolver(problem_correct)

    if use_iterative_solvers:
        solvers["correct"].parameters["linear_solver"] = "bicgstab"
        solvers["correct"].parameters["preconditioner"] = "amg"
    #else:
    #    solver = df.LUSolver("mumps")
    #    # solver.set_operator(A)
    #    return solver, a, L, dirichlet_bcs_NS

    return solvers
def run_test(nbrep=100):
    mesh = dl.UnitSquareMesh(100,100)
    V = dl.FunctionSpace(mesh, 'Lagrange', 2)
    test, trial = dl.TestFunction(V), dl.TrialFunction(V)
    k = dl.Function(V)
    wkform = dl.inner(k*dl.nabla_grad(test), dl.nabla_grad(trial))*dl.dx
    for ii in xrange(nbrep):
        setfct(k, float(ii+1))
        dl.assemble(wkform)
Example #17
0
    def __init__(self, problem_params, dtype_u=fenics_mesh, dtype_f=rhs_fenics_mesh):
        """
        Initialization routine

        Args:
            problem_params (dict): custom parameters for the example
            dtype_u: FEniCS mesh data type (will be passed to parent class)
            dtype_f: FEniCS mesh data data type with implicit and explicit parts (will be passed to parent class)
        """

        # define the Dirichlet boundary
        # def Boundary(x, on_boundary):
        #     return on_boundary

        # these parameters will be used later, so assert their existence
        essential_keys = ['c_nvars', 't0', 'family', 'order', 'refinements', 'nu']
        for key in essential_keys:
            if key not in problem_params:
                msg = 'need %s to instantiate problem, only got %s' % (key, str(problem_params.keys()))
                raise ParameterError(msg)

        # set logger level for FFC and dolfin
        logging.getLogger('FFC').setLevel(logging.WARNING)
        logging.getLogger('UFL').setLevel(logging.WARNING)

        # set solver and form parameters
        df.parameters["form_compiler"]["optimize"] = True
        df.parameters["form_compiler"]["cpp_optimize"] = True
        df.parameters['allow_extrapolation'] = True

        # set mesh and refinement (for multilevel)
        mesh = df.UnitIntervalMesh(problem_params['c_nvars'])
        for i in range(problem_params['refinements']):
            mesh = df.refine(mesh)

        # define function space for future reference
        self.V = df.FunctionSpace(mesh, problem_params['family'], problem_params['order'])
        tmp = df.Function(self.V)
        print('DoFs on this level:', len(tmp.vector()[:]))

        # invoke super init, passing number of dofs, dtype_u and dtype_f
        super(fenics_heat, self).__init__(self.V, dtype_u, dtype_f, problem_params)

        # Stiffness term (Laplace)
        u = df.TrialFunction(self.V)
        v = df.TestFunction(self.V)
        a_K = -1.0 * df.inner(df.nabla_grad(u), self.params.nu * df.nabla_grad(v)) * df.dx

        # Mass term
        a_M = u * v * df.dx

        self.M = df.assemble(a_M)
        self.K = df.assemble(a_K)

        # set forcing term as expression
        self.g = df.Expression('-cos(a*x[0]) * (sin(t) - b*a*a*cos(t))', a=np.pi, b=self.params.nu, t=self.params.t0,
                               degree=self.params.order)
Example #18
0
 def defineVariationalForm(self):
     self.setGroundPlane()
     self.setMeasures()
     print("Defining variational form...")
     self.F = dolfin.inner(self.eps_exp * dolfin.nabla_grad(self.u),
                           dolfin.nabla_grad(self.v)) * self.dx
     rho = self.setChargeDensity()
     self.F += rho
     self.F += self.getBoundaryComponent(self.u, self.v, self.ds)
Example #19
0
 def setUp(self):
     mesh = UnitSquareMesh(5, 5, 'crossed')
     self.V = FunctionSpace(mesh, 'Lagrange', 2)
     u = interpolate(Expression('1 + 7*(pow(pow(x[0] - 0.5,2) +' + \
     ' pow(x[1] - 0.5,2),0.5) > 0.2)'), self.V)
     test = TestFunction(self.V)
     trial = TrialFunction(self.V)
     m = test*trial*dx
     self.M = assemble(m)
     k = inner(u*nabla_grad(test), nabla_grad(trial))*dx
     self.K = assemble(k)
Example #20
0
def discrete_energy(x_, solutes, density, permittivity, c_cutoff, EC_scheme,
                    dt, density_per_concentration, surface_tension,
                    interface_thickness, enable_NS, enable_PF, enable_EC,
                    **namespace):
    if x_ is None:
        E_list = []
        if enable_NS:
            E_list.append("E_kin")
        if enable_PF:
            E_list.append("E_phi")
        if enable_EC:
            E_list.extend(["E_{}".format(solute[0])
                           for solute in solutes] + ["E_V"])
        return E_list

    if enable_S:
        rho = density[0]
        veps = permittivity[0]
        u = x_["u"]

    if enable_NS:
        rho = density[0]
        veps = permittivity[0]
        u = x_["u"]
        # grad_p = df.grad(x_["p"])

    if enable_PF:
        sigma_bar = surface_tension * 3. / (2 * math.sqrt(2))
        eps = interface_thickness
        phi = x_["phi"]
        rho = ramp(phi, density)
        veps = ramp(phi, permittivity)

    if enable_EC:
        grad_V = df.nabla_grad(x_["V"])
        M_list = []
        for solute in solutes:
            ci = x_[solute[0]]
            if enable_PF:
                betai = ramp(phi, solute[4:6])
            else:
                betai = solute[4]
            M_list.append(alpha(ci) + betai * ci)

    E_list = []
    if enable_NS or enable_S:
        E_list.append(0.5 * rho * df.dot(u, u))
    if enable_PF:
        E_list.append(sigma_bar / eps * pf_potential(phi) + 0.5 * sigma_bar *
                      eps * df.dot(df.nabla_grad(phi), df.nabla_grad(phi)))
    if enable_EC:
        E_list.extend(M_list + [0.5 * veps * df.dot(grad_V, grad_V)])

    return E_list
Example #21
0
 def setUp(self):
     mesh = UnitSquareMesh(5, 5, 'crossed')
     self.V = FunctionSpace(mesh, 'Lagrange', 2)
     u = interpolate(Expression('1 + 7*(pow(pow(x[0] - 0.5,2) +' + \
     ' pow(x[1] - 0.5,2),0.5) > 0.2)'), self.V)
     test = TestFunction(self.V)
     trial = TrialFunction(self.V)
     m = test * trial * dx
     self.M = assemble(m)
     k = inner(u * nabla_grad(test), nabla_grad(trial)) * dx
     self.K = assemble(k)
Example #22
0
 def assembleRaa(self, x):
     """
     Assemble the derivative of the parameter equation with respect to the parameter (Newton method)
     """
     trial = dl.TrialFunction(self.Vh[PARAMETER])
     test = dl.TestFunction(self.Vh[PARAMETER])
     s = vector2Function(x[STATE], Vh[STATE])
     c = vector2Function(x[PARAMETER], Vh[PARAMETER])
     a = vector2Function(x[ADJOINT], Vh[ADJOINT])
     varf = dl.inner(dl.nabla_grad(a),
                     dl.exp(c) * dl.nabla_grad(s)) * trial * test * dl.dx
     return dl.assemble(varf)
Example #23
0
def assemble_lhs(coeff, V):
    """Assemble the discrete problem (i.e. the stiffness matrix)."""
    # setup problem, assemble and apply boundary conditions
    u = TrialFunction(V)
    v = TestFunction(V)
    a = inner(coeff * nabla_grad(u), nabla_grad(v)) * dx
    A = assemble(a)

    # apply boundary conditions
    bc = homogeneous_bc(V)
    bc.apply(A)
    return A
    def costab(self, m1, m2):
        self.gradm1 = project(nabla_grad(m1), self.Vd)
        self.gradm2 = project(nabla_grad(m2), self.Vd)

        cost = 0.0
        for x, vol in zip(self.x, self.vol):
            G = np.array([self.gradm1(x), self.gradm2(x)]).T
            u, s, v = np.linalg.svd(G)
            sqrts2eps = np.sqrt(s**2 + self.eps)
            cost += vol * sqrts2eps.sum()

        cost_global = MPI.sum(self.mpicomm, cost)
        return self.k * cost_global
Example #25
0
def weighted_H1_norm(w, vec, piecewise=False):
    if piecewise:
        DG = FunctionSpace(vec.basis.mesh, "DG", 0)
        s = TestFunction(DG)
        ae = assemble(w * inner(nabla_grad(vec._fefunc), nabla_grad(vec._fefunc)) * s * dx)
        norm_vec = np.array([sqrt(e) for e in ae])
        # map DG dofs to cell indices
        dofs = [DG.dofmap().cell_dofs(c.index())[0] for c in cells(vec.basis.mesh)]
        norm_vec = norm_vec[dofs]
    else:
        ae = assemble(w * inner(nabla_grad(vec._fefunc), nabla_grad(vec._fefunc)) * dx)
        norm_vec = sqrt(ae)
    return norm_vec
Example #26
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
Example #27
0
 def assembleC(self, x):
     """
     Assemble the derivative of the forward problem with respect to the parameter
     """
     trial = dl.TrialFunction(self.Vh[PARAMETER])
     test = dl.TestFunction(self.Vh[STATE])
     s = vector2Function(x[STATE], Vh[STATE])
     c = vector2Function(x[PARAMETER], Vh[PARAMETER])
     Cvarf = dl.inner(
         dl.exp(c) * trial * dl.nabla_grad(s), dl.nabla_grad(test)) * dl.dx
     C = dl.assemble(Cvarf)
     #        print "||c||", x[PARAMETER].norm("l2"), "||s||", x[STATE].norm("l2"), "||C||", C.norm("linf")
     self.bc0.zero(C)
     return C
Example #28
0
    def __init__(self, parameters, domain):
        rho = Constant(parameters["density [kg/m3]"])
        dt = Constant(parameters["dt [s]"])
        p, p_1, vp = domain.p, domain.p_1, domain.vp
        p_1, u_ = domain.p_1, domain.u_

        # F = rho/dt * dot(div(u_), vp) * dx + dot(grad(p-p_1), grad(vp)) * dx
        self.a = dot(nabla_grad(p), nabla_grad(vp))*dx
        self.L = (dot(nabla_grad(p_1), nabla_grad(vp))*dx
                  - (rho/dt)*div(u_)*vp*dx)
        self.A = assemble(self.a)
        [bc.apply(self.A) for bc in domain.bcp]
        self.domain = domain
        return
    def gradab(self, m1, m2):
        self.gradm1 = project(nabla_grad(m1), self.Vd)
        self.gradm2 = project(nabla_grad(m2), self.Vd)

        uwv00, uwv00ind = [], []
        uwv10, uwv10ind = [], []
        uwv01, uwv01ind = [], []
        uwv11, uwv11ind = [], []
        for ii, x in enumerate(self.x):
            G = np.array([self.gradm1(x), self.gradm2(x)]).T
            u, s, v = np.linalg.svd(G)
            sqrts2eps = np.sqrt(s**2 + self.eps)
            W = np.diag(s / sqrts2eps)
            uwv = u.dot(W.dot(v))

            uwv00.append(uwv[0][0])
            uwv00ind.append(ii)

            uwv10.append(uwv[1][0])
            uwv10ind.append(ii)

            uwv01.append(uwv[0][1])
            uwv01ind.append(ii)

            uwv11.append(uwv[1][1])
            uwv11ind.append(ii)

        Grad = Function(self.VV)
        grad = Grad.vector()
        rhsG = Vector()
        self.Gx1test.init_vector(rhsG, 1)

        rhsG.set_local(np.array(uwv00), np.array(uwv00ind, dtype=np.intc))
        rhsG.apply('insert')
        grad.axpy(1.0, self.Gx1test * rhsG)

        rhsG.zero()
        rhsG.set_local(np.array(uwv10), np.array(uwv10ind, dtype=np.intc))
        rhsG.apply('insert')
        grad.axpy(1.0, self.Gy1test * rhsG)

        rhsG.set_local(np.array(uwv01), np.array(uwv01ind, dtype=np.intc))
        rhsG.apply('insert')
        grad.axpy(1.0, self.Gx2test * rhsG)

        rhsG.set_local(np.array(uwv11), np.array(uwv11ind, dtype=np.intc))
        rhsG.apply('insert')
        grad.axpy(1.0, self.Gy2test * rhsG)

        return grad * self.k
Example #30
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)
Example #31
0
 def assembleWau(self, x):
     """
     Assemble the derivative of the parameter equation with respect to the state
     """
     trial = dl.TrialFunction(self.Vh[STATE])
     test = dl.TestFunction(self.Vh[PARAMETER])
     a = dl.Function(self.Vh[ADJOINT], x[ADJOINT])
     c = dl.Function(self.Vh[PARAMETER], x[PARAMETER])
     varf = dl.inner(dl.exp(c) * dl.nabla_grad(trial),
                     dl.nabla_grad(a)) * test * dl.dx
     Wau = dl.assemble(varf)
     dummy = dl.Vector()
     Wau.init_vector(dummy, 0)
     self.bc0.zero_columns(Wau, dummy)
     return Wau
Example #32
0
    def __init__(self, parameters, domain):
        rho = Constant(parameters["density [kg/m3]"])
        dt = Constant(parameters["dt [s]"])
        p, p_1, vp = domain.p, domain.p_1, domain.vp
        p_1, u_ = domain.p_1, domain.u_

        a2 = dot(nabla_grad(p), nabla_grad(vp)) * dx
        L2 = dot(nabla_grad(p_1),
                 nabla_grad(vp)) * dx - (rho / dt) * div(u_) * vp * dx
        A2 = assemble(a2)
        [bc.apply(A2) for bc in domain.bcp]

        self.domain = domain
        self.a2, self.A2, self.L2 = a2, A2, L2
        return
Example #33
0
def integrateFluidStress(v, p, nu, space_dim):
    if space_dim == 2:
        cd_integral = -20. * (nu * v_ref * (1. / l_ref**2) * inner(
            dlfn.nabla_grad(v), dlfn.nabla_grad(vd)) + v_ref**2 *
                              (1. / l_ref) * inner(grad(v) * v, vd) - p_ref *
                              (1. / l_ref) * p * dlfn.div(vd)) * dV
        cd = l_ref**2 * dlfn.assemble(cd_integral)
        cl_integral = -20. * (nu * v_ref * (1. / l_ref**2) * inner(
            dlfn.nabla_grad(v), dlfn.nabla_grad(vl)) + v_ref**2 *
                              (1. / l_ref) * inner(grad(v) * v, vl) - p_ref *
                              (1. / l_ref) * p * dlfn.div(vl)) * dV
        cl = l_ref**2 * dlfn.assemble(cl_integral)
    else:
        raise ValueError("space dimension unequal 2")
    return cd, cl
Example #34
0
 def assembleWau(self, x):
     """
     Assemble the derivative of the parameter equation with respect to the state
     """
     trial = dl.TrialFunction(self.Vh[STATE])
     test = dl.TestFunction(self.Vh[PARAMETER])
     a = vector2Function(x[ADJOINT], Vh[ADJOINT])
     c = vector2Function(x[PARAMETER], Vh[PARAMETER])
     varf = dl.inner(dl.exp(c) * dl.nabla_grad(trial),
                     dl.nabla_grad(a)) * test * dl.dx
     Wau = dl.assemble(varf)
     Wau_t = Transpose(Wau)
     self.bc0.zero(Wau_t)
     Wau = Transpose(Wau_t)
     return Wau
Example #35
0
def setup_NSu(u, v, u_, p_, bcs_NSu, u_1, p_1, phi_, rho_, rho_1, g_, M_, nu_,
              rho_e_, V_, dt, drho, sigma_bar, eps, dveps, grav, enable_PF,
              enable_EC):
    """ Set up the Navier-Stokes subproblem. """
    # Crank-Nicolson velocity
    # u_CN = 0.5*(u_1 + u)

    F_predict = (
        1. / dt * df.sqrt(rho_) *
        df.dot(df.sqrt(rho_) * u - df.sqrt(rho_1) * u_1, v) * df.dx
        # + rho_*df.inner(df.grad(u), df.outer(u_1, v))*df.dx
        # + 2*nu_*df.inner(df.sym(df.grad(u)), df.grad(v))*df.dx
        # - p_1 * df.div(v)*df.dx
        # + df.div(u)*q*df.dx
        + rho_ * df.dot(df.dot(u_1, df.nabla_grad(u)), v) * df.dx +
        2 * nu_ * df.inner(df.sym(df.grad(u)), df.sym(df.grad(v))) * df.dx -
        p_1 * df.div(v) * df.dx - df.dot(rho_ * grav, v) * df.dx)

    phi_filtered = unit_interval_filter(phi_)
    if enable_PF:
        F_predict += -drho * M_ * df.dot(
            df.dot(df.nabla_grad(g_), df.nabla_grad(u)), v) * df.dx
        F_predict += -sigma_bar * eps * df.inner(
            df.outer(df.grad(phi_filtered), df.grad(phi_filtered)),
            df.grad(v)) * df.dx
    if enable_EC and rho_e_ != 0:
        F_predict += rho_e_ * df.dot(df.grad(V_), v) * df.dx
    if enable_PF and enable_EC:
        F_predict += dveps * df.dot(df.grad(phi_filtered), v) * df.dot(
            df.grad(V_), df.grad(V_)) * df.dx

    # a1, L1 = df.lhs(F_predict), df.rhs(F_predict)

    F_correct = (df.inner(u - u_, v) * df.dx +
                 dt / rho_ * df.inner(df.grad(p_ - p_1), v) * df.dx)
    # a3 = df.dot(u, v)*df.dx
    # L3 = df.dot(u_, v)*df.dx - dt*df.dot(df.grad(p_), v)*df.dx
    # a3, L3 = df.lhs(F_correct), df.rhs(F_correct)

    solver = dict()
    # solver["a1"] = a1
    # solver["L1"] = L1
    solver["Fu"] = F_predict
    solver["Fu_corr"] = F_correct
    # solver["a3"] = a3
    # solver["L3"] = L3
    solver["bcs"] = bcs_NSu
    return solver
Example #36
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)
Example #37
0
 def flux_derivative(self, u, coeff):
     a = coeff
     Du = self.differential_op(u)
     Dsigma = dot(nabla_grad(a), Du)
     if element_degree(u) >= 2:
         Dsigma += a * div(Du)
     return Dsigma
    def __init__(self, domain):
        rho, mu, dt, g = domain.rho, domain.mu, domain.dt, domain.g
        u, u_1, vu = domain.u, domain.u_1, domain.vu
        p_1 = domain.p_1

        n = FacetNormal(domain.mesh)

        acceleration = rho * inner((u - u_1) / dt, vu) * dx
        pressure = inner(p_1, div(vu)) * dx - dot(p_1 * n, vu) * ds
        body_force = dot(g*rho, vu)*dx \
            + dot(Constant((0.0, 0.0)), vu) * ds
        # diffusion = (-inner(mu * (grad(u_1) + grad(u_1).T), grad(vu))*dx
        #               + dot(mu * (grad(u_1) + grad(u_1).T)*n, vu)*ds)  # just fine
        # diffusion = (-inner(mu * (grad(u) + grad(u).T), grad(vu))*dx)  # just fine
        # just fine, but horribly slow in combination with ???  -> not reproducable
        diffusion = (-inner(mu * (grad(u) + grad(u).T), grad(vu)) * dx +
                     dot(mu * (grad(u) + grad(u).T) * n, vu) * ds)
        # convection = rho*dot(dot(u, nabla_grad(u_1)), vu) * dx  # no vortices
        convection = rho * dot(dot(u_1, nabla_grad(u)), vu) * dx
        # stabilization = -gamma*psi_p*p_1
        # convection = dot(div(rho * outer(u_1, u_1)), vu) * dx  # not stable!
        # convection = rho * dot(dot(u_1, nabla_grad(u_1)), vu) * dx  # just fine
        F_impl = -acceleration - convection + diffusion + pressure + body_force

        self.a, self.L = lhs(F_impl), rhs(F_impl)
        self.domain = domain
        self.A = assemble(self.a)
        [bc.apply(self.A) for bc in domain.bcu]
        return
Example #39
0
def computeVelocityField(mesh):
    Xh = dl.VectorFunctionSpace(mesh, 'Lagrange', 2)
    Wh = dl.FunctionSpace(mesh, 'Lagrange', 1)
    XW = dl.MixedFunctionSpace([Xh, Wh])

    Re = 1e2

    g = dl.Expression(('0.0', '(x[0] < 1e-14) - (x[0] > 1 - 1e-14)'))
    bc1 = dl.DirichletBC(XW.sub(0), g, v_boundary)
    bc2 = dl.DirichletBC(XW.sub(1), dl.Constant(0), q_boundary, 'pointwise')
    bcs = [bc1, bc2]

    vq = dl.Function(XW)
    (v, q) = dl.split(vq)
    (v_test, q_test) = dl.TestFunctions(XW)

    def strain(v):
        return dl.sym(dl.nabla_grad(v))

    F = ((2. / Re) * dl.inner(strain(v), strain(v_test)) +
         dl.inner(dl.nabla_grad(v) * v, v_test) - (q * dl.div(v_test)) +
         (dl.div(v) * q_test)) * dl.dx

    dl.solve(F == 0,
             vq,
             bcs,
             solver_parameters={
                 "newton_solver": {
                     "relative_tolerance": 1e-4,
                     "maximum_iterations": 100
                 }
             })

    return v
def setup_NSp(w_NSp, p, q, dirichlet_bcs_NSp, dt, u_, p_1, rho_0,
              use_iterative_solvers, **namespace):
    """ Set up Navier-Stokes pressure subproblem. """
    F = (df.dot(df.nabla_grad(p - p_1), df.nabla_grad(q)) * df.dx +
         1. / dt * rho_0 * df.div(u_) * q * df.dx)

    a, L = df.lhs(F), df.rhs(F)

    problem = df.LinearVariationalProblem(a, L, w_NSp, dirichlet_bcs_NSp)
    solver = df.LinearVariationalSolver(problem)

    if use_iterative_solvers:
        solver.parameters["linear_solver"] = "bicgstab"
        solver.parameters["preconditioner"] = "amg"

    return solver
Example #41
0
def setup_NSp(w_NSp, p, q, dx, ds, dirichlet_bcs_NSp, neumann_bcs,
              boundary_to_mark, u_, u_1, p_, p_1, rho_, dt, rho_min,
              use_iterative_solvers, **namespace):
    F = (df.dot(df.nabla_grad(p - p_1), df.nabla_grad(q)) * df.dx +
         1. / dt * rho_min * df.div(u_) * q * df.dx)

    a, L = df.lhs(F), df.rhs(F)
    problem = df.LinearVariationalProblem(a, L, w_NSp, dirichlet_bcs_NSp)
    solver = df.LinearVariationalSolver(problem)

    if use_iterative_solvers:
        solver.parameters["linear_solver"] = "gmres"
        solver.parameters["preconditioner"] = "hypre_amg"  # "amg"
        # solver.parameters["preconditioner"] = "hypre_euclid"

    return solver
Example #42
0
def computeVelocityField(mesh):
    Xh = dl.VectorFunctionSpace(mesh,'Lagrange', 2)
    Wh = dl.FunctionSpace(mesh, 'Lagrange', 1)
    if dlversion() <= (1,6,0):
        XW = dl.MixedFunctionSpace([Xh, Wh])
    else:
        mixed_element = dl.MixedElement([Xh.ufl_element(), Wh.ufl_element()])
        XW = dl.FunctionSpace(mesh, mixed_element)

    
    Re = 1e2
    
    g = dl.Expression(('0.0','(x[0] < 1e-14) - (x[0] > 1 - 1e-14)'), element=Xh.ufl_element())
    bc1 = dl.DirichletBC(XW.sub(0), g, v_boundary)
    bc2 = dl.DirichletBC(XW.sub(1), dl.Constant(0), q_boundary, 'pointwise')
    bcs = [bc1, bc2]
    
    vq = dl.Function(XW)
    (v,q) = dl.split(vq)
    (v_test, q_test) = dl.TestFunctions (XW)
    
    def strain(v):
        return dl.sym(dl.nabla_grad(v))
    
    F = ( (2./Re)*dl.inner(strain(v),strain(v_test))+ dl.inner (dl.nabla_grad(v)*v, v_test)
           - (q * dl.div(v_test)) + ( dl.div(v) * q_test) ) * dl.dx
           
    dl.solve(F == 0, vq, bcs, solver_parameters={"newton_solver":
                                         {"relative_tolerance":1e-4, "maximum_iterations":100,
                                          "linear_solver":"default"}})
        
    return v
Example #43
0
def run_dolfin():

    import dolfin as df

    x_array = np.linspace(-49.5, 49.5, 100)

    mesh = df.IntervalMesh(100, -50, 50)

    Delta = np.sqrt(A / K)
    xi = 2 * A / D

    Delta_s = Delta * 1e9

    V = df.FunctionSpace(mesh, "Lagrange", 1)
    u = df.TrialFunction(V)
    v = df.TestFunction(V)
    u_ = df.Function(V)
    F = -df.inner(df.nabla_grad(u), df.nabla_grad(v)) * df.dx - \
        (0.5 / Delta_s**2) * df.sin(2 * u) * v * df.dx
    F = df.action(F, u_)

    J = df.derivative(F, u_, u)

    # the boundary condition is from equation (8)
    theta0 = np.arcsin(Delta / xi)
    ss = 'x[0]<0? %g: %g ' % (-theta0, theta0)

    u0 = df.Expression(ss)

    def u0_boundary(x, on_boundary):
        return on_boundary

    bc = df.DirichletBC(V, u0, u0_boundary)

    problem = df.NonlinearVariationalProblem(F, u_, bcs=bc, J=J)
    solver = df.NonlinearVariationalSolver(problem)
    solver.solve()

    u_array = u_.vector().array()

    mx_df = []
    for x in x_array:
        mx_df.append(u_(x))

    return mx_df
Example #44
0
 def flux_derivative(self, u, coeff):
     """First derivative of flux."""
     lmbda, mu = coeff
     Du = self.differential_op(u)
     I = Identity(u.cell().d)
     Dsigma = 2.0 * mu * div(Du) + dot(nabla_grad(lmbda), tr(Du) * I)
     if element_degree(u) >= 2:
         Dsigma += lmbda * div(tr(Du) * I)
     return Dsigma
Example #45
0
def evaluate_numerical_flux(w, mu, coeff_field, f):
    '''determine numerical flux sigma_nu with solution w'''
    Lambda = w.active_indices()
    maxm = w.max_order
    if len(coeff_field) < maxm:
        logger.warning("insufficient length of coefficient field for MultiVector (%i < %i)", len(coeff_field), maxm)
        maxm = len(coeff_field)

    # get mean field of coefficient and initialise sigma
    a0_f = coeff_field.mean_func
    sigma_mu = a0_f * nabla_grad(w[mu]._fefunc)

    # iterate m
    for m in range(maxm):
        am_f, am_rv = coeff_field[m]

        # prepare polynomial coefficients
        beta = am_rv.orth_polys.get_beta(mu[m])

        # mu
        r_mu = -beta[0] * w[mu]

        # mu+1
        mu1 = mu.inc(m)
        if mu1 in Lambda:
            w_mu1 = w[mu1]
            r_mu += beta[1] * w_mu1

        # mu-1
        mu2 = mu.dec(m)
        if mu2 in Lambda:
            w_mu2 = w[mu2]
            r_mu += beta[-1] * w_mu2

        # add flux contribution
        sigma_mu = sigma_mu + am_f * nabla_grad(r_mu._fefunc)

    # initialise f
    if not mu:
        f_mu = f
    else:
        f_mu = Constant(0.0)

    return sigma_mu, f_mu
Example #46
0
def evaluate_evp(basis):
    """Evaluate EVP"""
    assert HAVE_SLEPC
    # get FEniCS function space
    V = basis._fefs

    # Define basis and bilinear form
    u = TrialFunction(V)
    v = TestFunction(V)
    a = inner(nabla_grad(u), nabla_grad(v)) * dx

    # Assemble stiffness form
    A = PETScMatrix()
    assemble(a, tensor=A)

    # Create eigensolver
    eigensolver = SLEPcEigenSolver(A)

    # Compute all eigenvalues of A x = \lambda x
    print "Computing eigenvalues..."
    eigensolver.solve()
    return eigensolver
Example #47
0
 def _assemble(self):
     # Get input:
     self.gamma = self.Parameters['gamma']
     if self.Parameters.has_key('beta'): self.beta = self.Parameters['beta']
     else:   self.beta = 0.0
     self.Vm = self.Parameters['Vm']
     if self.Parameters.has_key('m0'):   
         self.m0 = self.Parameters['m0'].copy(deepcopy=True)
         isFunction(self.m0)
     else:   self.m0 = Function(self.Vm)
     self.mtrial = TrialFunction(self.Vm)
     self.mtest = TestFunction(self.Vm)
     self.mysample = Function(self.Vm)
     self.draw = Function(self.Vm)
     # Assemble:
     self.R = assemble(inner(nabla_grad(self.mtrial), \
     nabla_grad(self.mtest))*dx)
     self.M = assemble(inner(self.mtrial, self.mtest)*dx)
     # preconditioner is Gamma^{-1}:
     if self.beta > 1e-16: self.precond = self.gamma*self.R + self.beta*self.M
     else:   self.precond = self.gamma*self.R + (1e-14)*self.M
     # Minvprior is M.A^2 (if you use M inner-product):
     self.Minvprior = self.gamma*self.R + self.beta*self.M
Example #48
0
 def _assemble(self):
     # Get input:
     self.gamma = self.Parameters['gamma']
     if self.Parameters.has_key('beta'): self.beta = self.Parameters['beta']
     else:   self.beta = 0.0
     self.Vm = self.Parameters['Vm']
     if self.Parameters.has_key('m0'):   
         self.m0 = self.Parameters['m0'].copy(deepcopy=True)
         isFunction(self.m0)
     else:   self.m0 = Function(self.Vm)
     self.mtrial = TrialFunction(self.Vm)
     self.mtest = TestFunction(self.Vm)
     self.mysample = Function(self.Vm)
     self.draw = Function(self.Vm)
     # Assemble:
     self.R = assemble(inner(nabla_grad(self.mtrial), \
     nabla_grad(self.mtest))*dx)
     self.M = PETScMatrix()
     assemble(inner(self.mtrial, self.mtest)*dx, tensor=self.M)
     # preconditioner is Gamma^{-1}:
     if self.beta > 1e-16: self.precond = self.gamma*self.R + self.beta*self.M
     else:   self.precond = self.gamma*self.R + (1e-14)*self.M
     # Discrete operator K:
     self.K = self.gamma*self.R + self.beta*self.M
     # Get eigenvalues for M:
     self.eigsolM = SLEPcEigenSolver(self.M)
     self.eigsolM.solve()
     # Solver for M^{-1}:
     self.solverM = LUSolver()
     self.solverM.parameters['reuse_factorization'] = True
     self.solverM.parameters['symmetric'] = True
     self.solverM.set_operator(self.M)
     # Solver for K^{-1}:
     self.solverK = LUSolver()
     self.solverK.parameters['reuse_factorization'] = True
     self.solverK.parameters['symmetric'] = True
     self.solverK.set_operator(self.K)
 def get_conv_diff(u, v, epsilon, wind, stabilize=True):
     a = (
         epsilon*inner(nabla_grad(u), nabla_grad(v))*dx
         + inner(nabla_grad(u), wind)*v*dx
         )
     L = f*v*dx
     if stabilize:
         a += delta*inner(wind, nabla_grad(u))*inner(wind, nabla_grad(v))*dx
         L += delta*f*inner(wind, nabla_grad(v))*dx
     return a, L
    def assembleSystem(self):
        """Assemble the FEM system. This is only run a single time before time-stepping. The values of the coefficient
        fields need to be updated between time-steps
        """
        # Loop through the entire model and composite the system of equations
        self.diffusors = []  # [[compartment, species, diffusivity of species],[ ...],[...]]
        """
           Diffusors have source terms
        """
        self.electrostatic_compartments = [] # (compartment) where electrostatic equations reside
        """
           Has source term
        """
        self.potentials = [] # (membrane)
        """
            No spatial derivatives, just construct ODE
        """
        self.channelvars = [] #(membrane, channel, ...)

        for compartment in self.compartments:
            s = 0
            for species in compartment.species:
                if compartment.diffusivities[species] < 1e-10: continue
                self.diffusors.extend([ [compartment,species,compartment.diffusivities[species]] ])
                s+=compartment.diffusivities[species]*abs(species.z)
            if s>0:
                self.electrostatic_compartments.extend([compartment])
                # Otherwise, there are no mobile charges in the compartment


        # the number of potentials is the number of spatial potentials + number of membrane potentials
        self.numdiffusers = len(self.diffusors)
        self.numpoisson = len(self.electrostatic_compartments)

        # Functions
        # Reaction-diffusion type
        #   Diffusers    :numdiffusers
        #
        # Coefficient
        #   Diffusivities
        self.V_np = dolfin.MixedFunctionSpace([self.v]*(self.numdiffusers))
        self.V_poisson = dolfin.MixedFunctionSpace([self.v]*self.numpoisson)
        #self.V = self.V_diff*self.V_electro
        self.V = dolfin.MixedFunctionSpace([self.v]*(self.numdiffusers+self.numpoisson))

        self.dofs_is = [self.V.sub(j).dofmap().dofs() for j in range(self.numdiffusers+self.numpoisson)]
        self.N = len(self.dofs_is[0])

        self.diffusivities = [dolfin.Function(self.v) for j in range(self.numdiffusers)]

        self.trialfunctions = dolfin.TrialFunctions(self.V)  # Trial function
        self.testfunctions = dolfin.TestFunctions(self.V) # test functions, one for each field

        self.sourcefunctions = [dolfin.Function(self.v) for j in range(self.numpoisson+self.numdiffusers)]

        self.permitivities = [dolfin.Function(self.v) for j in range(self.numpoisson)]

        # index the compartments!

        self.functions__ = dolfin.Function(self.V)

        self.np_assigner = dolfin.FunctionAssigner(self.V_np,[self.v]*self.numdiffusers)
        self.poisson_assigner = dolfin.FunctionAssigner(self.V_poisson,[self.v]*self.numpoisson)
        self.full_assigner = dolfin.FunctionAssigner(self.V,[self.v]*(self.numdiffusers+self.numpoisson))

        self.prev_value__ = dolfin.Function(self.V)
        self.prev_value_ = dolfin.split(self.prev_value__)
        self.prev_value = [dolfin.Function(self.v) for j in range(self.numdiffusers+self.numpoisson)]

        self.vfractionfunctions = [dolfin.Function(self.v) for j in range(len(self.compartments))]
        # Each reaction diffusion eqn should be indexed to a single volume fraction function
        # Each reaction diffusion eqn should be indexed to a single potential function
        # Each reaction diffusion eqn should be indexed to a single valence
        self.dt = dolfin.Constant(0.1)
        self.eqs = []
        self.phi = dolfin.Constant(phi)

        for membrane in self.membranes:
            self.potentials.extend([membrane])
            membrane.phi_m = np.ones(self.N)*membrane.phi_m
        self.num_membrane_potentials = len(self.potentials) # improve this

        """
            Assemble the equations for the system
            Order of equations:
            for compartment in compartments:
                for species in compartment.species
                    diffusion (in order)
                volume
                potential for electrodiffusion
            Membrane potentials


        """
        for j,compartment in enumerate(self.compartments):
            self.vfractionfunctions[j].vector()[:] = self.volfrac[compartment]

        # Set the reaction-diffusion equations
        for j,(trial,old,test,source,D,diffusor) in enumerate(zip(self.trialfunctions[:self.numdiffusers],self.prev_value_[:self.numdiffusers] \
                ,self.testfunctions[:self.numdiffusers], self.sourcefunctions[:self.numdiffusers]\
                ,self.diffusivities,self.diffusors)):
            """
            This instance of the loop corresponds to a diffusion species in self.diffusors
            """
            compartment_index = self.compartments.index(diffusor[0]) # we are in this compartment

            try:
                phi_index = self.electrostatic_compartments.index(diffusor[0]) + self.numdiffusers
                self.eqs.extend([ trial*test*dx-test*old*dx+ \
                        self.dt*(inner(D*nabla_grad(trial),nabla_grad(test)) + \
                        dolfin.Constant(diffusor[1].z/phi)*inner(D*trial*nabla_grad(self.prev_value[phi_index]),nabla_grad(test)))*dx   ])

                """
                self.eqs.extend([ trial*test*dx-test*old*dx+ \
                        self.dt*(inner(D*nabla_grad(trial),nabla_grad(test)) + \
                        dolfin.Constant(diffusor[1].z/phi)*inner(D*trial*nabla_grad(self.prev_value[phi_index]),nabla_grad(test)) - source*test)*dx   ])
                """
                # electrodiffusion here

            except ValueError:
                # No electrodiffusion for this species
                self.eqs.extend([trial*test*dx-old*test*dx+self.dt*(inner(D*nabla_grad(trial),nabla_grad(test))- source*test)*dx ])

            self.prev_value[j].vector()[:] = diffusor[0].value(diffusor[1])
            self.diffusivities[j].vector()[:] = diffusor[2]
            #diffusor[0].setValue(diffusor[1],self.prev_value[j].vector().array()) # do this below instead


        self.full_assigner.assign(self.prev_value__,self.prev_value)
        self.full_assigner.assign(self.functions__,self.prev_value)  # Initial guess for Newton

        """
        Vectorize the values that aren't already vectorized
        """
        for compartment in self.compartments:
            for j,(species, val) in enumerate(compartment.values.items()):
                try:
                    length = len(val)
                    compartment.internalVars.extend([(species,self.N,j*self.N)])
                    compartment.species_internal_lookup[species] = j*self.N
                except:
                    compartment.values[species]= np.ones(self.N)*val
                    #compartment.internalVars.extend([(species,self.N,j*self.N)])
                    compartment.species_internal_lookup[species] = j*self.N


        # Set the electrostatic eqns
        # Each equation is associated with a single compartment as defined in

        for j,(trial, test, source, eps, compartment) in enumerate(zip(self.trialfunctions[self.numdiffusers:],self.testfunctions[self.numdiffusers:], \
                self.sourcefunctions[self.numdiffusers:], self.permitivities, self.electrostatic_compartments)):
            # set the permitivity for this equation
            eps.vector()[:] = F**2*self.volfrac[compartment]/R/T \
                *sum([compartment.diffusivities[species]*species.z**2*compartment.value(species)  for species in compartment.species],axis=0)
            self.eqs.extend( [inner(eps*nabla_grad(trial),nabla_grad(test))*dx - source*test*dx] )

        compartmentfluxes = self.updateSources()

        #


        """
        Set indices for the "internal variables"
        List of tuples
        (compartment/membrane, num of variables)

        Each compartment or membrane has method
        getInternalVars()
        get_dot_InternalVars(t,values)
        get_jacobian_InternalVars(t,values)
        setInternalVars(values)

        The internal variables for each object are stored starting in
        y[obj.system_state_offset]
        """
        self.internalVars = []
        index = 0
        for membrane in self.membranes:
            index2 = 0
            for channel in membrane.channels:
                channeltmp = channel.getInternalVars()
                if channeltmp is not None:
                    self.internalVars.extend([ (channel, len(channeltmp),index2)])
                    channel.system_state_offset = index+index2
                    channel.internalLength = len(channeltmp)
                    index2+=len(channeltmp)
            tmp = membrane.getInternalVars()
            if tmp is not None:
                self.internalVars.extend( [(membrane,len(tmp),index)] )
                membrane.system_state_offset = index
                index += len(tmp)
                membrane.points = self.N
        """
        Compartments at the end, so we may reuse some computations
        """

        for compartment in self.compartments:
            index2 = 0
            compartment.system_state_offset = index  # offset for this object in the overall state
            for species, value in compartment.values.items():
                compartment.internalVars.extend([(species,len(compartment.value(species)),index2)])
                index2 += len(value)
            tmp = compartment.getInternalVars()
            self.internalVars.extend( [(compartment,len(tmp),index)] )
            index += len(tmp)
            compartment.points = self.N

        for key, val in self.volfrac.items():
            self.volfrac[key] = val*np.ones(self.N)

        """
        Solver setup below
        self.pdewolver is the FEM solver for the concentrations
        self.ode is the ODE solver for the membrane and volume fraction
        The ODE solve uses LSODA
        """
        # Define the problem and the solver
        self.equation = sum(self.eqs)
        self.equation_ = dolfin.action(self.equation, self.functions__)
        self.J = dolfin.derivative(self.equation_,self.functions__)
        ffc_options = {"optimize": True, \
            "eliminate_zeros": True, \
            "precompute_basis_const": True, \
            "precompute_ip_const": True, \
            "quadrature_degree": 2}
        self.problem = dolfin.NonlinearVariationalProblem(self.equation_, self.functions__, None, self.J, form_compiler_parameters=ffc_options)
        self.pdesolver  = dolfin.NonlinearVariationalSolver(self.problem)
        self.pdesolver.parameters['newton_solver']['absolute_tolerance'] = 1e-9
        self.pdesolver.parameters['newton_solver']['relative_tolerance'] = 1e-9

        """
        ODE integrator here. Add ability to customize the parameters in the future
        """
        self.t = 0.0
        self.odesolver = ode(self.ode_rhs) #
        self.odesolver.set_integrator('lsoda', nsteps=3000, first_step=1e-6, max_step=5e-3 )
        self.odesolver.set_initial_value(self.getInternalVars(),self.t)

        self.isAssembled = True
Example #51
0
 def updatePD(self):
     """ Update the parameters.
     parameters should be:
         - k(x) = factor inside TV
         - eps = regularization parameter
         - Vm = FunctionSpace for parameter. 
     ||f||_TV = int k(x) sqrt{|grad f|^2 + eps} dx
     """
     # primal dual variables
     self.Vw = FunctionSpace(self.Vm.mesh(), 'DG', 0)
     self.wH = Function(self.Vw*self.Vw)  # dual variable used in Hessian (re-scaled)
     #self.wH = nabla_grad(self.m)/sqrt(self.fTV) # full Hessian
     self.w = Function(self.Vw*self.Vw)  # dual variable for primal-dual, initialized at 0
     self.dm = Function(self.Vm)
     self.dw = Function(self.Vw*self.Vw)  
     self.testw = TestFunction(self.Vw*self.Vw)
     self.trialw = TrialFunction(self.Vw*self.Vw)
     # investigate convergence of dual variable
     self.dualres = self.w*sqrt(self.fTV) - nabla_grad(self.m)
     self.dualresnorm = inner(self.dualres, self.dualres)*dx
     self.normgraddm = inner(nabla_grad(self.dm), nabla_grad(self.dm))*dx
     # Hessian
     self.wkformPDhess = self.kovsq * ( \
     inner(nabla_grad(self.trial), nabla_grad(self.test)) - \
     0.5*( inner(self.wH, nabla_grad(self.test))*\
     inner(nabla_grad(self.trial), nabla_grad(self.m)) + \
     inner(nabla_grad(self.m), nabla_grad(self.test))*\
     inner(nabla_grad(self.trial), self.wH) ) / sqrt(self.fTV) \
     )*dx
     # update dual variable
     self.Mw = assemble(inner(self.trialw, self.testw)*dx)
     self.rhswwk = inner(-self.w, self.testw)*dx + \
     inner(nabla_grad(self.m)+nabla_grad(self.dm), self.testw) \
     /sqrt(self.fTV)*dx + \
     inner(-inner(nabla_grad(self.m),nabla_grad(self.dm))* \
     self.wH/sqrt(self.fTV), self.testw)*dx
Example #52
0
def discretize_fenics(xblocks, yblocks, grid_num_intervals, element_order):

    # assemble system matrices - FEniCS code
    ########################################

    import dolfin as df

    mesh = df.UnitSquareMesh(grid_num_intervals, grid_num_intervals, 'crossed')
    V = df.FunctionSpace(mesh, 'Lagrange', element_order)
    u = df.TrialFunction(V)
    v = df.TestFunction(V)

    diffusion = df.Expression('(lower0 <= x[0]) * (open0 ? (x[0] < upper0) : (x[0] <= upper0)) *' +
                              '(lower1 <= x[1]) * (open1 ? (x[1] < upper1) : (x[1] <= upper1))',
                              lower0=0., upper0=0., open0=0,
                              lower1=0., upper1=0., open1=0,
                              element=df.FunctionSpace(mesh, 'DG', 0).ufl_element())

    def assemble_matrix(x, y, nx, ny):
        diffusion.user_parameters['lower0'] = x/nx
        diffusion.user_parameters['lower1'] = y/ny
        diffusion.user_parameters['upper0'] = (x + 1)/nx
        diffusion.user_parameters['upper1'] = (y + 1)/ny
        diffusion.user_parameters['open0'] = (x + 1 == nx)
        diffusion.user_parameters['open1'] = (y + 1 == ny)
        return df.assemble(df.inner(diffusion * df.nabla_grad(u), df.nabla_grad(v)) * df.dx)

    mats = [assemble_matrix(x, y, xblocks, yblocks)
            for x in range(xblocks) for y in range(yblocks)]
    mat0 = mats[0].copy()
    mat0.zero()
    h1_mat = df.assemble(df.inner(df.nabla_grad(u), df.nabla_grad(v)) * df.dx)
    l2_mat = df.assemble(u * v * df.dx)

    f = df.Constant(1.) * v * df.dx
    F = df.assemble(f)

    bc = df.DirichletBC(V, 0., df.DomainBoundary())
    for m in mats:
        bc.zero(m)
    bc.apply(mat0)
    bc.apply(h1_mat)
    bc.apply(F)

    # wrap everything as a pyMOR discretization
    ###########################################

    # FEniCS wrappers
    from pymor.gui.fenics import FenicsVisualizer
    from pymor.operators.fenics import FenicsMatrixOperator
    from pymor.vectorarrays.fenics import FenicsVector

    # generic pyMOR classes
    from pymor.discretizations.basic import StationaryDiscretization
    from pymor.operators.constructions import LincombOperator, VectorFunctional
    from pymor.parameters.functionals import ProjectionParameterFunctional
    from pymor.parameters.spaces import CubicParameterSpace
    from pymor.vectorarrays.list import ListVectorArray

    # define parameter functionals (same as in pymor.analyticalproblems.thermalblock)
    def parameter_functional_factory(x, y):
        return ProjectionParameterFunctional(component_name='diffusion',
                                             component_shape=(yblocks, xblocks),
                                             coordinates=(yblocks - y - 1, x),
                                             name='diffusion_{}_{}'.format(x, y))
    parameter_functionals = tuple(parameter_functional_factory(x, y)
                                  for x, y in product(xrange(args['XBLOCKS']), xrange(args['YBLOCKS'])))

    # wrap operators
    ops = [FenicsMatrixOperator(mat0)] + [FenicsMatrixOperator(m) for m in mats]
    op = LincombOperator(ops, (1.,) + parameter_functionals)
    rhs = VectorFunctional(ListVectorArray([FenicsVector(F)]))
    h1_product = FenicsMatrixOperator(h1_mat, name='h1_0_semi')
    l2_product = FenicsMatrixOperator(l2_mat, name='l2')

    # build discretization
    visualizer = FenicsVisualizer(V)
    parameter_space = CubicParameterSpace(op.parameter_type, 0.1, 1.)
    d = StationaryDiscretization(op, rhs, products={'h1_0_semi': h1_product,
                                                    'l2': l2_product},
                                 parameter_space=parameter_space,
                                 visualizer=visualizer)

    summary = '''FEniCS discretization:
   number of blocks:      {xblocks}x{yblocks}
   grid intervals:        {grid_num_intervals}
   finite element order:  {element_order}
'''.format(**locals())

    return d, summary
Example #53
0
def _discretize_fenics():

    # assemble system matrices - FEniCS code
    ########################################

    import dolfin as df

    mesh = df.UnitSquareMesh(GRID_INTERVALS, GRID_INTERVALS, 'crossed')
    V = df.FunctionSpace(mesh, 'Lagrange', FENICS_ORDER)
    u = df.TrialFunction(V)
    v = df.TestFunction(V)

    diffusion = df.Expression('(lower0 <= x[0]) * (open0 ? (x[0] < upper0) : (x[0] <= upper0)) *' +
                              '(lower1 <= x[1]) * (open1 ? (x[1] < upper1) : (x[1] <= upper1))',
                              lower0=0., upper0=0., open0=0,
                              lower1=0., upper1=0., open1=0,
                              element=df.FunctionSpace(mesh, 'DG', 0).ufl_element())

    def assemble_matrix(x, y, nx, ny):
        diffusion.user_parameters['lower0'] = x/nx
        diffusion.user_parameters['lower1'] = y/ny
        diffusion.user_parameters['upper0'] = (x + 1)/nx
        diffusion.user_parameters['upper1'] = (y + 1)/ny
        diffusion.user_parameters['open0'] = (x + 1 == nx)
        diffusion.user_parameters['open1'] = (y + 1 == ny)
        return df.assemble(df.inner(diffusion * df.nabla_grad(u), df.nabla_grad(v)) * df.dx)

    mats = [assemble_matrix(x, y, XBLOCKS, YBLOCKS)
            for x in range(XBLOCKS) for y in range(YBLOCKS)]
    mat0 = mats[0].copy()
    mat0.zero()
    h1_mat = df.assemble(df.inner(df.nabla_grad(u), df.nabla_grad(v)) * df.dx)

    f = df.Constant(1.) * v * df.dx
    F = df.assemble(f)

    bc = df.DirichletBC(V, 0., df.DomainBoundary())
    for m in mats:
        bc.zero(m)
    bc.apply(mat0)
    bc.apply(h1_mat)
    bc.apply(F)

    # wrap everything as a pyMOR discretization
    ###########################################

    # FEniCS wrappers
    from pymor.gui.fenics import FenicsVisualizer
    from pymor.operators.fenics import FenicsMatrixOperator
    from pymor.vectorarrays.fenics import FenicsVector

    # define parameter functionals (same as in pymor.analyticalproblems.thermalblock)
    parameter_functionals = [ProjectionParameterFunctional(component_name='diffusion',
                                                           component_shape=(YBLOCKS, XBLOCKS),
                                                           coordinates=(YBLOCKS - y - 1, x))
                             for x in range(XBLOCKS) for y in range(YBLOCKS)]

    # wrap operators
    ops = [FenicsMatrixOperator(mat0, V, V)] + [FenicsMatrixOperator(m, V, V) for m in mats]
    op = LincombOperator(ops, [1.] + parameter_functionals)
    rhs = VectorFunctional(ListVectorArray([FenicsVector(F, V)]))
    h1_product = FenicsMatrixOperator(h1_mat, V, V, name='h1_0_semi')

    # build discretization
    visualizer = FenicsVisualizer(V)
    parameter_space = CubicParameterSpace(op.parameter_type, 0.1, 1.)
    d = StationaryDiscretization(op, rhs, products={'h1_0_semi': h1_product},
                                 parameter_space=parameter_space,
                                 visualizer=visualizer)

    return d
Example #54
0
def test_prb88_184422():
    mu0 = 4 * np.pi * 1e-7

    Ms = 8.6e5
    A = 16e-12
    D = 3.6e-3
    K = 510e3

    mesh = CuboidMesh(nx=100, dx=1, unit_length=1e-9)

    sim = Sim(mesh)

    sim.driver.set_tols(rtol=1e-10, atol=1e-14)

    sim.driver.alpha = 0.5
    sim.driver.gamma = 2.211e5
    sim.Ms = Ms
    sim.do_precession = False

    sim.set_m((0, 0, 1))

    sim.add(UniformExchange(A))
    sim.add(DMI(-D, type='interfacial'))
    sim.add(UniaxialAnisotropy(K, axis=(0, 0, 1)))

    sim.relax(dt=1e-13, stopping_dmdt=0.01, max_steps=5000,
              save_m_steps=None, save_vtk_steps=50)

    m = sim.spin

    mx, my, mz = np.split(m, 3)

    x_array = np.linspace(-49.5, 49.5, 100)

    #plt.plot(x_array, mx)
    #plt.plot(x_array, my)
    #plt.plot(x_array, mz)

    mesh = df.IntervalMesh(100, -50, 50)

    Delta = np.sqrt(A / K)
    xi = 2 * A / D

    Delta_s = Delta * 1e9

    V = df.FunctionSpace(mesh, "Lagrange", 1)
    u = df.TrialFunction(V)
    v = df.TestFunction(V)
    u_ = df.Function(V)
    F = -df.inner(df.nabla_grad(u), df.nabla_grad(v)) * df.dx - \
        (0.5 / Delta_s**2) * df.sin(2 * u) * v * df.dx
    F = df.action(F, u_)

    J = df.derivative(F, u_, u)

    # the boundary condition is from equation (8)
    theta0 = np.arcsin(Delta / xi)
    ss = 'x[0]<0? %g: %g ' % (-theta0, theta0)

    u0 = df.Expression(ss)

    def u0_boundary(x, on_boundary):
        return on_boundary

    bc = df.DirichletBC(V, u0, u0_boundary)

    problem = df.NonlinearVariationalProblem(F, u_, bcs=bc, J=J)
    solver = df.NonlinearVariationalSolver(problem)
    solver.solve()

    u_array = u_.vector().array()

    mx_df = []
    for x in x_array:
        mx_df.append(u_(x))

    #plt.plot(x_array, mx_df)

    assert abs(np.max(mx - mx_df)) < 0.05
Example #55
0
 def update(self, parameters=None):
     """ Update the parameters.
     parameters should be:
         - k(x) = factor inside TV
         - eps = regularization parameter
         - Vm = FunctionSpace for parameter. 
     ||f||_TV = int k(x) sqrt{|grad f|^2 + eps} dx
     """
     # reset some variables
     self.H = None
     # udpate parameters
     if parameters == None:  
         parameters = self.parameters
     else:
         self.parameters.update(parameters)
     GN = self.parameters['GNhessian']
     self.Vm = self.parameters['Vm']
     eps = self.parameters['eps']
     self.k = self.parameters['k']
     # define functions
     self.m = Function(self.Vm)
     self.test, self.trial = TestFunction(self.Vm), TrialFunction(self.Vm)
     # frequently-used variable
     self.fTV = inner(nabla_grad(self.m), nabla_grad(self.m)) + Constant(eps)
     self.kovsq = self.k / sqrt(self.fTV)
     #
     # cost functional
     self.wkformcost = self.k*sqrt(self.fTV)*dx
     # gradient
     self.wkformgrad = self.kovsq*inner(nabla_grad(self.m), nabla_grad(self.test))*dx
     # Hessian
     self.wkformGNhess = self.kovsq*inner(nabla_grad(self.trial), nabla_grad(self.test))*dx
     self.wkformFhess = self.kovsq*( \
     inner(nabla_grad(self.trial), nabla_grad(self.test)) - \
     inner(nabla_grad(self.m), nabla_grad(self.test))*\
     inner(nabla_grad(self.trial), nabla_grad(self.m))/self.fTV )*dx
     if self.isPD(): 
         self.updatePD()
         self.wkformhess = self.wkformPDhess
         print 'TV regularization -- primal-dual Newton'
     else:
         if GN: 
             self.wkformhess = self.wkformGNhess
             print 'TV regularization -- GN Hessian'
         else:   
             self.wkformhess = self.wkformFhess
             print 'TV regularization -- full Hessian'
Example #56
0
def _discretize_fenics():

    # assemble system matrices - FEniCS code
    ########################################

    import dolfin as df

    # discrete function space
    mesh = df.UnitSquareMesh(GRID_INTERVALS, GRID_INTERVALS, 'crossed')
    V = df.FunctionSpace(mesh, 'Lagrange', FENICS_ORDER)
    u = df.TrialFunction(V)
    v = df.TestFunction(V)

    # data functions
    bottom_diffusion = df.Expression('(x[0] > 0.45) * (x[0] < 0.55) * (x[1] < 0.7) * 1.',
                                     element=df.FunctionSpace(mesh, 'DG', 0).ufl_element())
    top_diffusion = df.Expression('(x[0] > 0.35) * (x[0] < 0.40) * (x[1] > 0.3) * 1. +' +
                                  '(x[0] > 0.60) * (x[0] < 0.65) * (x[1] > 0.3) * 1.',
                                  element=df.FunctionSpace(mesh, 'DG', 0).ufl_element())
    initial_data = df.Expression('(x[0] > 0.45) * (x[0] < 0.55) * (x[1] < 0.7) * 10.',
                                 element=df.FunctionSpace(mesh, 'DG', 0).ufl_element())
    neumann_data = df.Expression('(x[0] > 0.45) * (x[0] < 0.55) * 1000.',
                                 element=df.FunctionSpace(mesh, 'DG', 0).ufl_element())

    # assemble matrices and vectors
    l2_mat = df.assemble(df.inner(u, v) * df.dx)
    l2_0_mat = l2_mat.copy()
    h1_mat = df.assemble(df.inner(df.nabla_grad(u), df.nabla_grad(v)) * df.dx)
    h1_0_mat = h1_mat.copy()
    mat0 = h1_mat.copy()
    mat0.zero()
    bottom_mat = df.assemble(bottom_diffusion * df.inner(df.nabla_grad(u), df.nabla_grad(v)) * df.dx)
    top_mat = df.assemble(top_diffusion * df.inner(df.nabla_grad(u), df.nabla_grad(v)) * df.dx)
    u0 = df.project(initial_data, V).vector()
    f = df.assemble(neumann_data * v * df.ds)

    # boundary treatment
    def dirichlet_boundary(x, on_boundary):
        tol = 1e-14
        return on_boundary and (abs(x[0]) < tol or abs(x[0] - 1) < tol or abs(x[1] - 1) < tol)

    bc = df.DirichletBC(V, df.Constant(0.), dirichlet_boundary)
    bc.apply(l2_0_mat)
    bc.apply(h1_0_mat)
    bc.apply(mat0)
    bc.zero(bottom_mat)
    bc.zero(top_mat)
    bc.apply(f)
    bc.apply(u0)

    # wrap everything as a pyMOR discretization
    ###########################################

    from pymor.bindings.fenics import FenicsVectorSpace, FenicsMatrixOperator, FenicsVisualizer

    d = InstationaryDiscretization(
        T=1.,

        initial_data=FenicsVectorSpace(V).make_array([u0]),

        operator=LincombOperator([FenicsMatrixOperator(mat0, V, V),
                                  FenicsMatrixOperator(h1_0_mat, V, V),
                                  FenicsMatrixOperator(bottom_mat, V, V),
                                  FenicsMatrixOperator(top_mat, V, V)],
                                 [1.,
                                  1.,
                                  100. - 1.,
                                  ExpressionParameterFunctional('top - 1.', {'top': 0})]),

        rhs=VectorFunctional(FenicsVectorSpace(V).make_array([f])),

        mass=FenicsMatrixOperator(l2_0_mat, V, V, name='l2'),

        products={'l2': FenicsMatrixOperator(l2_mat, V, V, name='l2'),
                  'l2_0': FenicsMatrixOperator(l2_0_mat, V, V, name='l2_0'),
                  'h1': FenicsMatrixOperator(h1_mat, V, V, name='h1'),
                  'h1_0_semi': FenicsMatrixOperator(h1_0_mat, V, V, name='h1_0_semi')},

        time_stepper=ImplicitEulerTimeStepper(nt=NT),

        parameter_space=CubicParameterSpace({'top': 0}, minimum=1, maximum=100.),

        visualizer=FenicsVisualizer(FenicsVectorSpace(V))
    )

    return d
Example #57
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)
Example #58
0
    def __init__(self, cparams, dtype_u, dtype_f):
        """
        Initialization routine

        Args:
            cparams: custom parameters for the example
            dtype_u: particle data type (will be passed parent class)
            dtype_f: acceleration data type (will be passed parent class)
        """

        # define the Dirichlet boundary
        def Boundary(x, on_boundary):
            return on_boundary

        # these parameters will be used later, so assert their existence
        assert 'c_nvars' in cparams
        assert 't0' in cparams
        assert 'family' in cparams
        assert 'order' in cparams
        assert 'refinements' in cparams

        # add parameters as attributes for further reference
        for k,v in cparams.items():
            setattr(self,k,v)

        df.set_log_level(df.WARNING)

        df.parameters["form_compiler"]["optimize"]     = True
        df.parameters["form_compiler"]["cpp_optimize"] = True

        # set mesh and refinement (for multilevel)
        # mesh = df.UnitIntervalMesh(self.c_nvars)
        # mesh = df.UnitSquareMesh(self.c_nvars[0],self.c_nvars[1])
        mesh = df.IntervalMesh(self.c_nvars,0,100)
        # mesh = df.RectangleMesh(0.0,0.0,2.0,2.0,self.c_nvars[0],self.c_nvars[1])
        for i in range(self.refinements):
            mesh = df.refine(mesh)

        # self.mesh = mesh
        # define function space for future reference
        V = df.FunctionSpace(mesh, self.family, self.order)
        self.V = V*V

        # invoke super init, passing number of dofs, dtype_u and dtype_f
        super(fenics_grayscott,self).__init__(self.V,dtype_u,dtype_f)

        # rhs in weak form
        self.w = df.Function(self.V)
        q1,q2 = df.TestFunctions(self.V)

        self.w1,self.w2 = df.split(self.w)

        self.F1 = (-self.Du*df.inner(df.nabla_grad(self.w1), df.nabla_grad(q1)) - self.w1*(self.w2**2)*q1 + self.A*(1-self.w1)*q1)*df.dx
        self.F2 = (-self.Dv*df.inner(df.nabla_grad(self.w2), df.nabla_grad(q2)) + self.w1*(self.w2**2)*q2 - self.B*    self.w2*q2)*df.dx
        self.F = self.F1+self.F2

        # mass matrix
        u1,u2 = df.TrialFunctions(self.V)
        a_M = u1*q1*df.dx
        M1 = df.assemble(a_M)
        a_M = u2*q2*df.dx
        M2 = df.assemble(a_M)
        self.M = M1+M2
Example #59
0
def _discretize_fenics(xblocks, yblocks, grid_num_intervals, element_order):

    # assemble system matrices - FEniCS code
    ########################################

    import dolfin as df

    mesh = df.UnitSquareMesh(grid_num_intervals, grid_num_intervals, "crossed")
    V = df.FunctionSpace(mesh, "Lagrange", element_order)
    u = df.TrialFunction(V)
    v = df.TestFunction(V)

    diffusion = df.Expression(
        "(lower0 <= x[0]) * (open0 ? (x[0] < upper0) : (x[0] <= upper0)) *"
        + "(lower1 <= x[1]) * (open1 ? (x[1] < upper1) : (x[1] <= upper1))",
        lower0=0.0,
        upper0=0.0,
        open0=0,
        lower1=0.0,
        upper1=0.0,
        open1=0,
        element=df.FunctionSpace(mesh, "DG", 0).ufl_element(),
    )

    def assemble_matrix(x, y, nx, ny):
        diffusion.user_parameters["lower0"] = x / nx
        diffusion.user_parameters["lower1"] = y / ny
        diffusion.user_parameters["upper0"] = (x + 1) / nx
        diffusion.user_parameters["upper1"] = (y + 1) / ny
        diffusion.user_parameters["open0"] = x + 1 == nx
        diffusion.user_parameters["open1"] = y + 1 == ny
        return df.assemble(df.inner(diffusion * df.nabla_grad(u), df.nabla_grad(v)) * df.dx)

    mats = [assemble_matrix(x, y, xblocks, yblocks) for x in range(xblocks) for y in range(yblocks)]
    mat0 = mats[0].copy()
    mat0.zero()
    h1_mat = df.assemble(df.inner(df.nabla_grad(u), df.nabla_grad(v)) * df.dx)
    l2_mat = df.assemble(u * v * df.dx)

    f = df.Constant(1.0) * v * df.dx
    F = df.assemble(f)

    bc = df.DirichletBC(V, 0.0, df.DomainBoundary())
    for m in mats:
        bc.zero(m)
    bc.apply(mat0)
    bc.apply(h1_mat)
    bc.apply(F)

    # wrap everything as a pyMOR discretization
    ###########################################

    # FEniCS wrappers
    from pymor.gui.fenics import FenicsVisualizer
    from pymor.operators.fenics import FenicsMatrixOperator
    from pymor.vectorarrays.fenics import FenicsVector

    # generic pyMOR classes
    from pymor.discretizations.basic import StationaryDiscretization
    from pymor.operators.constructions import LincombOperator, VectorFunctional
    from pymor.parameters.functionals import ProjectionParameterFunctional
    from pymor.parameters.spaces import CubicParameterSpace
    from pymor.vectorarrays.list import ListVectorArray

    # define parameter functionals (same as in pymor.analyticalproblems.thermalblock)
    def parameter_functional_factory(x, y):
        return ProjectionParameterFunctional(
            component_name="diffusion",
            component_shape=(yblocks, xblocks),
            coordinates=(yblocks - y - 1, x),
            name="diffusion_{}_{}".format(x, y),
        )

    parameter_functionals = tuple(parameter_functional_factory(x, y) for x in range(xblocks) for y in range(yblocks))

    # wrap operators
    ops = [FenicsMatrixOperator(mat0, V, V)] + [FenicsMatrixOperator(m, V, V) for m in mats]
    op = LincombOperator(ops, (1.0,) + parameter_functionals)
    rhs = VectorFunctional(ListVectorArray([FenicsVector(F, V)]))
    h1_product = FenicsMatrixOperator(h1_mat, V, V, name="h1_0_semi")
    l2_product = FenicsMatrixOperator(l2_mat, V, V, name="l2")

    # build discretization
    visualizer = FenicsVisualizer(V)
    parameter_space = CubicParameterSpace(op.parameter_type, 0.1, 1.0)
    d = StationaryDiscretization(
        op,
        rhs,
        products={"h1_0_semi": h1_product, "l2": l2_product},
        parameter_space=parameter_space,
        visualizer=visualizer,
    )

    return d
Example #60
0
def discretize(args):
    # first assemble all matrices for the affine decomposition
    import dolfin as df

    mesh = df.UnitSquareMesh(args["--grid"], args["--grid"], "crossed")
    V = df.FunctionSpace(mesh, "Lagrange", args["--order"])
    u = df.TrialFunction(V)
    v = df.TestFunction(V)

    diffusion = df.Expression(
        "(lower0 <= x[0]) * (open0 ? (x[0] < upper0) : (x[0] <= upper0)) *"
        + "(lower1 <= x[1]) * (open1 ? (x[1] < upper1) : (x[1] <= upper1))",
        lower0=0.0,
        upper0=0.0,
        open0=0,
        lower1=0.0,
        upper1=0.0,
        open1=0,
        element=df.FunctionSpace(mesh, "DG", 0).ufl_element(),
    )

    def assemble_matrix(x, y, nx, ny):
        diffusion.user_parameters["lower0"] = x / nx
        diffusion.user_parameters["lower1"] = y / ny
        diffusion.user_parameters["upper0"] = (x + 1) / nx
        diffusion.user_parameters["upper1"] = (y + 1) / ny
        diffusion.user_parameters["open0"] = x + 1 == nx
        diffusion.user_parameters["open1"] = y + 1 == ny
        return df.assemble(df.inner(diffusion * df.nabla_grad(u), df.nabla_grad(v)) * df.dx)

    mats = [
        assemble_matrix(x, y, args["XBLOCKS"], args["YBLOCKS"])
        for x in range(args["XBLOCKS"])
        for y in range(args["YBLOCKS"])
    ]
    mat0 = mats[0].copy()
    mat0.zero()
    h1_mat = df.assemble((df.inner(df.nabla_grad(u), df.nabla_grad(v)) + u * v) * df.dx)

    f = df.Constant(1.0) * v * df.dx
    F = df.assemble(f)

    bc = df.DirichletBC(V, 0.0, df.DomainBoundary())
    for m in mats:
        bc.zero(m)
    bc.apply(mat0)
    bc.apply(F)

    # wrap everything as a pyMOR discretization
    from pymor.gui.fenics import FenicsVisualizer
    from pymor.operators.fenics import FenicsMatrixOperator
    from pymor.vectorarrays.fenics import FenicsVector

    ops = [FenicsMatrixOperator(mat0)] + [FenicsMatrixOperator(m) for m in mats]

    def parameter_functional_factory(x, y):
        return ProjectionParameterFunctional(
            component_name="diffusion",
            component_shape=(args["XBLOCKS"], args["YBLOCKS"]),
            coordinates=(args["YBLOCKS"] - y - 1, x),
            name="diffusion_{}_{}".format(x, y),
        )

    parameter_functionals = tuple(
        parameter_functional_factory(x, y) for x, y in product(xrange(args["XBLOCKS"]), xrange(args["YBLOCKS"]))
    )

    op = LincombOperator(ops, (1.0,) + parameter_functionals)
    rhs = VectorFunctional(ListVectorArray([FenicsVector(F)]))
    h1_product = FenicsMatrixOperator(h1_mat)
    visualizer = FenicsVisualizer(V)
    parameter_space = CubicParameterSpace(op.parameter_type, 0.1, 1.0)
    d = StationaryDiscretization(
        op, rhs, products={"h1": h1_product}, parameter_space=parameter_space, visualizer=visualizer, cache_region=None
    )

    return d