Ejemplo n.º 1
0
    def __init__(self, space_name, variable_name, function_space):

        # Define initial interface values
        self.interface_new = Function(function_space)
        self.interface_old = Function(function_space)

        # Define initial values for time loop
        self.new = Function(function_space)
        self.old = Function(function_space)

        # Create arrays of empty functions and iterations
        self.array = []
        self.iterations = []

        # Create pvd files
        self.pvd = File(f"solutions/{space_name}/pvd/{variable_name}.pvd")

        # Remember space
        self.function_space = function_space

        # Remember space and variable names
        self.space_name = space_name
        self.variable_name = variable_name

        # Create HDF5 counter
        self.HDF5_counter = 0
Ejemplo n.º 2
0
def project_gradient_neumann(
        f0,
        degree=None,
        mesh=None,
        solver_type='gmres',
        preconditioner_type='default'
    ):
    """Find an approximation to f0 that has the same gradient

    The resulting function also satisfies homogeneous Neumann boundary
    conditions.

    Parameters:    
    f0: the function to approximate
    mesh=None: the mesh on which to approximate it If not provided, the
        mesh is extracted from f0.
    degree=None: degree of the polynomial approximation. extracted
        from f0 if not provided. 
    solver_type='gmres': The linear solver type to use.
    preconditioner_type='default': Preconditioner type to use
    """
    if not mesh: mesh = f0.function_space().mesh()
    element = f0.ufl_element()
    if not degree:
        degree = element.degree()
    CE = FiniteElement('CG', mesh.ufl_cell(), degree)
    CS = FunctionSpace(mesh, CE)
    DE = FiniteElement('DG', mesh.ufl_cell(), degree)
    DS = FunctionSpace(mesh, DE)
    CVE = VectorElement('CG', mesh.ufl_cell(), degree - 1)
    CV = FunctionSpace(mesh, CVE)
    RE = FiniteElement('R', mesh.ufl_cell(), 0)
    R = FunctionSpace(mesh, RE)
    CRE = MixedElement([CE, RE])
    CR = FunctionSpace(mesh, CRE)
    f = fe.project(f0, CS,
                   solver_type=solver_type,
                   preconditioner_type=preconditioner_type)
    g = fe.project(fe.grad(f), CV,
                   solver_type=solver_type,
                   preconditioner_type=preconditioner_type)
    lf = fe.project(fe.nabla_div(g), CS,
                    solver_type=solver_type,
                    preconditioner_type=preconditioner_type)
    tf, tc = TrialFunction(CR)
    wf, wc = TestFunctions(CR)
    dx = Measure('dx', domain=mesh,
                 metadata={'quadrature_degree': min(degree, 10)})
    a = (fe.dot(fe.grad(tf), fe.grad(wf)) + tc * wf + tf * wc) * dx
    L = (f * wc - lf * wf) * dx
    igc = Function(CR)
    fe.solve(a == L, igc,
             solver_parameters={'linear_solver': solver_type,
                                 'preconditioner': preconditioner_type}
    )
    ig, c = igc.sub(0), igc.sub(1)
    igd = fe.project(ig, DS,
                     solver_type=solver_type,
                     preconditioner_type=preconditioner_type)
    return igd
Ejemplo n.º 3
0
    def __init__(self, function):
        """Expand a Function defined on a corner mesh to a full mesh.

        Required parameter:
        funcion: the Function to be expanded.
        """
        self.VS = function.function_space()
        self.submesh = self.VS.mesh()
        self.dim = self.submesh.geometric_dimension()
        self.nss = self.VS.num_sub_spaces()
        self.nfields = self.nss // (2**self.dim)
        self.subcoords = self.submesh.coordinates()
        self.vtrans = integerify_transform(self.subcoords)
        self.icols = ['i' + str(i) for i in range(self.dim)]
        self.emesh, self.maps, self.cellmaps, self.vertexmaps = (expand_mesh(
            self.submesh, self.vtrans))
        self.dcoords = np.reshape(self.VS.tabulate_dof_coordinates(),
                                  (-1, self.dim))
        self.dtrans = integerify_transform(self.dcoords)
        self.eSE = scalar_element(self.VS)
        self.degree = self.eSE.degree()
        self.eVE = MixedElement([self.eSE] * self.nfields)
        self.eVS = FunctionSpace(self.emesh, self.eVE)
        self.sub_dof_list = dof_list(self.VS, self.dtrans)
        subs = self.sub_dof_list['sub'].values
        self.sub_dof_list['submesh'] = subs % (2**self.dim)
        self.sub_dof_list['field'] = subs // (2**self.dim)
        sc = self.sub_dof_list[['submesh', 'cell']].values
        self.sub_dof_list['ecell'] = self.cellmaps[(sc[:, 0], sc[:, 1])]
        self.e_dof_list = dof_list(self.eVS, self.dtrans)
        self.remap = self.sub2e_map()
        self.symmetries = evenodd_symmetries(self.dim)
        self.eomat = evenodd_matrix(self.symmetries)
        self.sub_function = Function(self.VS)
        self.expanded_function = Function(self.eVS)
Ejemplo n.º 4
0
    def test_multiplication(self):
        print(
            '\n== testing multiplication of system matrix for problem of weighted projection ===='
        )
        for dim, pol_order in itertools.product([2, 3], [1, 2]):
            N = 2  # no. of elements

            print('dim={0}, pol_order={1}, N={2}'.format(dim, pol_order, N))

            # creating MESH and defining MATERIAL
            if dim == 2:
                mesh = UnitSquareMesh(N, N)
                m = Expression("1+10*16*x[0]*(1-x[0])*x[1]*(1-x[1])",
                               degree=2)  # material coefficients
            elif dim == 3:
                mesh = UnitCubeMesh(N, N, N)
                m = Expression("1+10*16*x[0]*(1-x[0])*(1-x[1])*x[2]",
                               degree=2)  # material coefficients

            mesh.coordinates()[:] += 0.1 * np.random.random(
                mesh.coordinates().shape)  # mesh perturbation

            V = FunctionSpace(mesh, "CG", pol_order)  # original FEM space
            W = FunctionSpace(mesh, "CG", 2 * pol_order)  # double-grid space

            print('assembling local matrices for DoGIP...')
            Bhat = get_Bhat(
                dim, pol_order,
                problem=0)  # projection between V on W on a reference element
            AT_dogip = get_A_T(m, V, W, problem=0)

            dofmapV = V.dofmap()

            def system_multiplication_DoGIP(AT_dogip, Bhat, u_vec):
                # mutliplication with DoGIP decomposition
                Au = np.zeros_like(u_vec)
                for ii, cell in enumerate(cells(mesh)):
                    ind = dofmapV.cell_dofs(ii)  # local to global map
                    Au[ind] += Bhat.T.dot(AT_dogip[ii] * Bhat.dot(u_vec[ind]))
                return Au

            print('assembling FEM sparse matrix')
            u, v = TrialFunction(V), TestFunction(V)
            Asp = assemble(m * u * v * dx, tensor=EigenMatrix())  #
            Asp = Asp.sparray()

            print('multiplication...')
            ur = Function(V)  # creating random vector
            ur_vec = 5 * np.random.random(V.dim())
            ur.vector().set_local(ur_vec)

            Au_DoGIP = system_multiplication_DoGIP(
                AT_dogip, Bhat, ur_vec)  # DoGIP multiplication
            Auex = Asp.dot(ur_vec)  # FEM multiplication with sparse matrix

            # testing the difference between DoGIP and FEniCS
            self.assertAlmostEqual(0, np.linalg.norm(Auex - Au_DoGIP))
            print('...ok')
Ejemplo n.º 5
0
def problem_mix(T, dt, E, coupling, VV, boundaries, rho_s, lambda_, mu_s, f,
                bcs, **Solid_namespace):
    # Temporal parameters
    t = 0
    k = Constant(dt)

    # Split problem to two 1.order differential equations
    psi, phi = TestFunctions(VV)

    # Functions, wd is for holding the solution
    d_ = {}
    w_ = {}
    wd_ = {}
    for time in ["n", "n-1", "n-2", "n-3"]:
        if time == "n" and E not in [None, reference]:
            tmp_wd = Function(VV)
            wd_[time] = tmp_wd
            wd = TrialFunction(VV)
            w, d = split(wd)
        else:
            wd = Function(VV)
            wd_[time] = wd
            w, d = split(wd)

        d_[time] = d
        w_[time] = w

    # Time derivative
    if coupling == "center":
        G = rho_s / (2 * k) * inner(w_["n"] - w_["n-2"], psi) * dx
    else:
        G = rho_s / k * inner(w_["n"] - w_["n-1"], psi) * dx

    # Stress tensor
    G += inner(Piola2(d_, w_, k, lambda_, mu_s, E_func=E), grad(psi)) * dx

    # External forces, like gravity
    G -= rho_s * inner(f, psi) * dx

    # d-w coupling
    if coupling == "CN":
        G += inner(d_["n"] - d_["n-1"] - k * 0.5 *
                   (w_["n"] + w_["n-1"]), phi) * dx
    elif coupling == "imp":
        G += inner(d_["n"] - d_["n-1"] - k * w_["n"], phi) * dx
    elif coupling == "exp":
        G += inner(d_["n"] - d_["n-1"] - k * w_["n-1"], phi) * dx
    elif coupling == "center":
        G += innter(d_["n"] - d_["n-2"] - 2 * k * w["n-1"], phi) * dx
    else:
        print "The coupling %s is not implemented, 'CN', 'imp', and 'exp' are the only valid choices."
        sys.exit(0)

    # Solve
    if E in [None, reference]:
        solver_nonlinear(G, d_, w_, wd_, bcs, T, dt, **Solid_namespace)
    else:
        solver_linear(G, d_, w_, wd_, bcs, T, dt, **Solid_namespace)
Ejemplo n.º 6
0
    def test_DoGIP_vs_FEniCS(self):
        print(
            '\n== testing DoGIP vs. FEniCS for problem of weighted projection ===='
        )

        for dim, pol_order in itertools.product([2, 3], [1, 2]):
            print('dim={}; pol_order={}'.format(dim, pol_order))
            N = 2
            # creating MESH, defining MATERIAL and SOURCE
            if dim == 2:
                mesh = UnitSquareMesh(N, N)
                m = Expression("1+10*16*x[0]*(1-x[0])*x[1]*(1-x[1])",
                               degree=3)  # material coefficients
                f = Expression("x[0]*x[0]*x[1]", degree=2)
            elif dim == 3:
                mesh = UnitCubeMesh(N, N, N)
                m = Expression("1+100*x[0]*(1-x[0])*x[1]*x[2]",
                               degree=2)  # material coefficients
                f = Expression("(1-x[0])*x[1]*x[2]", degree=2)

            mesh.coordinates()[:] += 0.1 * np.random.random(
                mesh.coordinates().shape)  # mesh perturbation

            ## standard approach with FEniCS #############################################
            V = FunctionSpace(mesh, "CG", pol_order)  # original FEM space
            u, v = TrialFunction(V), TestFunction(V)
            u_fenics = Function(V)
            solve(m * u * v * dx == m * f * v * dx, u_fenics)

            ## DoGIP - double-grid integration with interpolation-projection #############
            W = FunctionSpace(mesh, "CG", 2 * pol_order)  # double-grid space
            w = TestFunction(W)
            A_dogip = assemble(
                m * w *
                dx).get_local()  # diagonal matrix of material coefficients
            b = assemble(m * f * v * dx)  # vector of right-hand side

            # assembling interpolation-projection matrix B
            B = get_B(V, W, problem=0)

            # # linear solver on double grid, standard
            Afun = lambda x: B.T.dot(A_dogip * B.dot(x))

            Alinoper = linalg.LinearOperator((V.dim(), V.dim()),
                                             matvec=Afun,
                                             dtype=np.float)
            x, info = linalg.cg(Alinoper,
                                b.get_local(),
                                x0=np.zeros(V.dim()),
                                tol=1e-10,
                                maxiter=1e3,
                                callback=None)

            # testing the difference between DoGIP and FEniCS
            self.assertAlmostEqual(
                0, np.linalg.norm(u_fenics.vector().get_local() - x))
            print('...ok')
Ejemplo n.º 7
0
def main():
    np.random.seed(793817931)
    degree = 3
    mesh = UnitSquareMesh(2, 2)
    gdim = mesh.geometry().dim()
    fs = FunctionSpace(mesh, 'CG', degree)
    f = Function(fs)
    random_function(f)
    print(f.vector()[:])
Ejemplo n.º 8
0
    def shooting_gmres(direction):

        # Define empty functions on interface
        increment = Function(interface.function_space)
        (increment_displacement,
         increment_velocity) = increment.split(increment)

        # Split entrance vectors
        direction_split = np.split(direction, 2)

        # Set values of functions on interface
        increment_displacement.vector().set_local(displacement_interface +
                                                  param.EPSILON *
                                                  direction_split[0])
        increment_velocity.vector().set_local(velocity_interface +
                                              param.EPSILON *
                                              direction_split[1])

        # Interpolate functions on solid subdomain
        increment_displacement_solid = interpolate(
            increment_displacement, solid.function_space_split[0])
        increment_velocity_solid = interpolate(increment_velocity,
                                               solid.function_space_split[1])
        displacement_solid.new.assign(increment_displacement_solid)
        velocity_solid.new.assign(increment_velocity_solid)

        # Compute shooting function
        shooting_function_increment = shooting_function(
            displacement_fluid,
            velocity_fluid,
            displacement_solid,
            velocity_solid,
            functional_fluid_initial,
            functional_solid_initial,
            bilinear_form_fluid,
            functional_fluid,
            bilinear_form_solid,
            functional_solid,
            first_time_step,
            fluid,
            solid,
            interface,
            param,
            fluid_macrotimestep,
            solid_macrotimestep,
            adjoint,
        )

        return (shooting_function_increment -
                shooting_function_value) / param.EPSILON
Ejemplo n.º 9
0
    def __init__(self,
                 grid_shape,
                 f,
                 init_z,
                 dirichlet,
                 degree=1,
                 polynomial_type='P',
                 reparam=True):
        """Parameters
        ----------
        grid_shape : numpy.array or list
            Defines the grid dimensions of the mesh used to solve the problem.
        f : str
            Source term of the Poisson equation in a form accepted by FEniCS (C++ style string)
        init_z : numpy.ndarray
            Placeholder value(s) for parameters of the model.
        dirichlet : str
            Dirichlet boundary conditions in string form accepted by FEniCS.
        degree : int, default 1
            Polynomial degree for the functional space.
        polynomial_type : str, default 'P'
            String encoding the type of polynomials in the functional space, according to FEniCS conventions
            (defaults to Lagrange polynomials).
        reparam: bool, default True
            Boolean indicating whether input parameters are to be reparametrized according to
            an inverse-logit transform.
        """
        def boundary(x, on_boundary):
            return on_boundary

        self.grid_shape = grid_shape
        self.mesh = UnitSquareMesh(*grid_shape)

        self.V = FunctionSpace(self.mesh, polynomial_type, degree)
        self.dirichlet = DirichletBC(self.V,
                                     Expression(dirichlet, degree=degree + 3),
                                     boundary)
        self._paramnames = ['param{}'.format(i) for i in range(len(init_z))]
        self.f = Expression(f,
                            degree=degree,
                            **dict(zip(self._paramnames, init_z)))
        u = TrialFunction(self.V)
        v = TestFunction(self.V)

        self.a = dot(grad(u), grad(v)) * dx
        self.L = self.f * v * dx
        self.u = Function(self.V)
        self.reparam = reparam
        self.solver = CountIt(solve)
Ejemplo n.º 10
0
def read_dem(bounds, res):
    """
    Function to read in a DEM from SRTM amd interplolate it onto a dolphyn mesh. This function uses the python package
    'elevation' (http://elevation.bopen.eu/en/stable/) and the gdal libraries.

    I will assume you want the 30m resolution SRTM model.

    :param bounds: west, south, east, north coordinates
    :return u_n, lx, ly: the elevation interpolated onto the dolphyn mesh and the lengths of the domain
    """
    west, south, east, north = bounds

    # Create a temporary file to store the DEM and go get it using elevation
    dem_path = 'tmp.tif'
    output = os.getcwd() + '/' + dem_path
    elv.clip(bounds=bounds, output=output, product='SRTM1')

    # read in the DEM into a numpy array
    gdal_data = gdal.Open(output)
    data_array = gdal_data.ReadAsArray().astype(np.float)

    # The DEM is 30m per pixel, so lets make a array for x and y at 30 m
    ny, nx = np.shape(data_array)
    lx = nx * 30
    ly = ny * 30

    x, y = np.meshgrid(np.linspace(0, lx / ly, nx), np.linspace(0, 1, ny))

    # Create mesh and define function space
    domain = Rectangle(Point(0, 0), Point(lx / ly, 1))
    mesh = generate_mesh(domain, res)
    V = FunctionSpace(mesh, 'P', 1)
    u_n = Function(V)

    # Get the global coordinates
    gdim = mesh.geometry().dim()
    gc = V.tabulate_dof_coordinates().reshape((-1, gdim))

    # Interpolate elevation into the initial condition
    elevation = interpolate.griddata((x.flatten(), y.flatten()),
                                     data_array.flatten(),
                                     (gc[:, 0], gc[:, 1]),
                                     method='nearest')
    u_n.vector()[:] = elevation

    # remove tmp DEM
    os.remove(output)

    return u_n, lx, ly, mesh, V
Ejemplo n.º 11
0
    def compute_steady_state(self):

        names = {'Cl', 'Na', 'K'}

        P1 = FiniteElement('P', fe.triangle, 1)
        element = MixedElement([P1, P1, P1])
        V = FunctionSpace(self.mesh, element)
        self.V_conc = V

        (u_cl, u_na, u_k) = TrialFunction(V)
        (v_cl, v_na, v_k) = TestFunction(V)

        assert (self.flow is not None)

        n = fe.FacetNormal(self.mesh)

        # F = ( self.F_diff_conv(u_cl, v_cl, n, grad(self.phi), 1. ,1., 0.)
        #    + self.F_diff_conv(u_na, v_na, n, grad(self.phi), 1. ,1., 0.)
        #    + self.F_diff_conv(u_k , v_k , n, grad(self.phi), 1. ,1., 0.) )

        dx, ds = self.dx, self.ds
        flow = self.flow
        F = inner(grad(u_cl), grad(v_cl)) * dx \
            + inner(flow, grad(u_cl)) * v_cl * dx \
            + inner(grad(u_na), grad(v_na)) * dx \
            + inner(flow, grad(u_na)) * v_na * dx \
            + inner(grad(u_k), grad(v_k)) * dx \
            + inner(flow, grad(u_k)) * v_k * dx

        a, L = fe.lhs(F), fe.rhs(F)
        a_mat = fe.assemble(a)
        L_vec = fe.assemble(L)
        # solve
        u = Function(V)
        fe.solve(a_mat, u.vector(), L_vec)

        u_cl, u_na, u_k = u.split()

        output1 = fe.File('/tmp/steady_state_cl.pvd')
        output1 << u_cl
        output2 = fe.File('/tmp/steady_state_na.pvd')
        output2 << u_na
        output3 = fe.File('/tmp/steady_state_k.pvd')
        output3 << u_k

        self.u_cl = u_cl
        self.u_na = u_na
        self.u_k = u_k
Ejemplo n.º 12
0
    def solve(self, **arguments):

        t_start = time.clock()

        # definig Function space on this mesh using Lagrange
        #polynoimals of degree 1.
        H = FunctionSpace(self.mesh, "CG", 1)

        # Setting up the variational problem
        v = TrialFunction(H)
        w = TestFunction(H)

        epsilon = Constant(arguments[Components().Diffusion])
        f = Constant(0)

        a = (epsilon * inner(grad(v), grad(w)) + inner(v, w)) * dx
        #Still have to figure it how to use a Neumann Condition here
        L = f * w * dx

        # solving the variational problem.
        v = Function(H)
        solve(a == L, v)

        self.solution.extend(v.vector().array())

        return [self.solution, time.clock() - t_start]
Ejemplo n.º 13
0
    def solve(self, **arguments):

        t_start = time.clock()

        # definig Function space on this mesh using Lagrange
        #polynoimals of degree 1.
        H = FunctionSpace(self.mesh, "CG", 1)

        # Setting up the variational problem
        v = TrialFunction(H)
        w = TestFunction(H)

        epsilon = Constant(arguments[Components().Diffusion])
        f = Expression("(1 - epsilon*4*pow(pi,2))*cos(2*pi*x[0])",\
                       epsilon=epsilon, degree=1)

        a = (epsilon * inner(grad(v), grad(w)) + inner(v, w)) * dx
        L = f * w * dx

        # solving the variational problem.
        v = Function(H)
        solve(a == L, v)

        self.solution.extend(v.vector().array())

        return [self.solution, time.clock() - t_start]
def run_fokker_planck(nx, num_steps, t_0 = 0, t_final=10):

    # define mesh
    mesh = IntervalMesh(nx, -200, 200)
    # define function space. 
    V = FunctionSpace(mesh, "Lagrange", 1)

    # Homogenous Neumann BCs don't have to be defined as they are the default in dolfin
    # define parameters.
    dt = (t_final-t_0) / num_steps

    # set mu and sigma 
    mu = Constant(-1)
    D = Constant(1)

    # define initial conditions u_0
    u_0 = Expression('x[0]', degree=1)

    # set U_n to be the interpolant of u_0 over the function space V. Note that 
    # u_n is the value of u at the previous timestep, while u is the current value. 
    u_n = interpolate(u_0, V)

    # Define variational problem
    u = TrialFunction(V)
    v = TestFunction(V)
    F = u*v*dx + dt*inner(D*grad(u), grad(v))*dx + dt*mu*grad(u)[0]*v*dx - inner(u_n, v)*dx

    # isolate the bilinear and linear forms. 
    a, L = lhs(F), rhs(F)

    # initialize function to capture solution. 
    t = 0 
    u_h = Function(V)

    plt.figure(figsize=(15, 15))

    # time-stepping section
    for n in range(num_steps):
        t += dt 

        # compute solution 
        solve(a == L, u_h)
        u_n.assign(u_h)

        # Plot solutions intermittently
        if n % (num_steps // 10) == 0 and num_steps > 0:

            plot(u_h, label='t = %s' % t)
    
    plt.legend() 
    plt.grid()
    plt.title("Finite Element Solutions to Fokker-Planck Equation with $\mu(x, t) = -(x+1)$ , $D(x, t) = e^t x^2$, $t_n$ = %s" % t_final)
    plt.ylabel("$u(x, t)$")
    plt.xlabel("x")
    plt.savefig("fpe/fokker-planck-solutions-mu.png")
    plt.clf() 

    # return the approximate solution evaluated on the coordinates, and the actual coordinates. 
    return u_n.compute_vertex_values(), mesh.coordinates() 
Ejemplo n.º 15
0
def dual_error_estimates(resolution):
    mesh = UnitSquareMesh(resolution, resolution)

    def all_boundary(_, on_boundary):
        return on_boundary

    zero = Constant(0.0)

    def a(u, v):
        return inner(grad(u), grad(v)) * dx

    def L(f, v):
        return f * v * dx

    # Primal problem
    f = Expression("32.*x[0]*(1. - x[0])+32.*x[1]*(1. - x[1])",
                   domain=mesh,
                   degree=5)
    ue = Expression("16.*x[0]*(1. - x[0])*x[1]*(1. - x[1])",
                    domain=mesh,
                    degree=5)

    Qp = FunctionSpace(mesh, 'CG', 1)
    bcp = DirichletBC(Qp, zero, all_boundary)

    u = TrialFunction(Qp)
    v = TestFunction(Qp)

    U = Function(Qp)
    solve(a(u, v) == L(f, v), U, bcp)

    # Dual problem
    Qd = FunctionSpace(mesh, 'CG', 2)
    psi = Constant(1.0)
    bcd = DirichletBC(Qd, zero, all_boundary)

    w = TestFunction(Qd)
    phi = TrialFunction(Qd)
    Phi = Function(Qd)
    solve(a(w, phi) == L(psi, w), Phi, bcd)

    # Compute errors
    e1 = compute_error(ue, U)
    e2 = assemble((inner(grad(U), grad(Phi)) - f * Phi) * dx)
    print("e1 = {}".format(e1))
    print("e2 = {}".format(e2))
Ejemplo n.º 16
0
def evenodd_functions(
    omesh,
    degree,
    func,
    width=None,
    evenodd=None
):
    """Break a function into even and odd components

    Required parameters:
    omesh: the mesh on which the function is defined
    degree: the degree of the FunctionSpace 
    func: the Function. This has to be something that fe.interpolate
        can interpolate onto a FunctionSpace or that fe.project can
        project onto a FunctionSpace.
    width: the width of the domain on which func is defined. (If not
        provided, this will be determined from omesh.
    evenodd: the symmetries of the functions to be constructed
        evenodd_symmetries(dim) is used if this is not provided
    """
    SS = FunctionSpace(omesh, 'CG', degree)
    dim = omesh.geometry().dim()
    comm = omesh.mpi_comm()
    rank = comm.rank
    if width is None:
        stats = mesh_stats(omesh)
        width = stats['xmax']
    if evenodd is None:
        evenodd = evenodd_symmetries(dim)
    try:
        f0 = fe.interpolate(func, SS)
    except TypeError:
        f0 = fe.project(func, SS)
    vec0 = f0.vector().gather_on_zero()
    dofcoords = gather_dof_coords(SS)
    ndofs = len(dofcoords)
    fvecs = np.empty((2**dim, len(vec0)), float)
    flips = evenodd_symmetries(dim)
    for row,flip in enumerate(flips):
        newcoords = (width*flip
                     + (1 - 2*flip)*dofcoords)
        remap = coord_remap(SS, newcoords)
        E = evenodd_matrix(evenodd)
        if rank == 0:
            fvecs[row, :] = vec0[remap]
            components = np.matmul(2**(-dim)*E, fvecs)
        else:
            components = np.zeros((2**dim, ndofs), float)
    logPERIODIC('components.shape', components.shape)
    fs = []
    logPERIODIC('broadcasting function DOFs')
    for c in components:
        f = Function(SS)
        f = bcast_function(SS, c, f)
        # f.set_allow_extrapolation(True)
        fs.append(f)
    return(fs)
Ejemplo n.º 17
0
def test_solve() -> None:
    dt = 0.01
    mesh = UnitIntervalMesh(10)
    params = MassAirPhaseParameters(V=None, mesh=mesh, dt=dt)
    mass_air_phase = MassAirPhase(params=params)
    a, L = mass_air_phase.construct_variation_problem()
    print(type(a))
    print(type(L))
    P = Function(params.V)
    P_prev = params.P_prev
    num_steps = 10
    t = 0
    sols = []
    for n in range(num_steps):
        t, P_prev, P = step(time=t, dt=dt, p_prev=P_prev, p=P, a=a, l=L)
        sols.append(P.vector().get_local())
    for s in sols:
        plt.plot(s)

    plt.show()
Ejemplo n.º 18
0
def test_solve() -> None:
    mesh = UnitIntervalMesh(10)
    p = BulkTemperatureParameters(V=None, mesh=mesh, dt=0.01)
    bulk_temp = BulkTemperature(params=p)
    V = p.V
    dt = p.dt
    T_prev = p.T_prev
    a, L = bulk_temp.construct_variation_problem()

    T = Function(V)
    num_steps = 10
    t = 0
    sols = []
    for n in range(num_steps):
        bc = bulk_temp.make_bcs(V, 0, -10)
        t, T_prev, T = step(time=t, dt=dt, t_prev=T_prev, t=T, a=a, l=L, bc=bc)
        sols.append(T.vector().array())
    for s in sols:
        plt.plot(s)
    plt.show()
Ejemplo n.º 19
0
    def solve(self, **arguments):

        t_start = time.clock()

        # definig Function space on this mesh using Lagrange
        #polynoimals of degree 1.
        H = FunctionSpace(self.mesh, "CG", 1)

        # Setting up the variational problem
        v = TrialFunction(H)
        w = TestFunction(H)

        coeff_dx2 = Constant(1)
        coeff_v = Constant(1)

        f = Expression("(4*pow(pi,2))*exp(-(1/coeff_v)*t)*sin(2*pi*x[0])",
                       {'coeff_v': coeff_v},
                       degree=2)

        v0 = Expression("sin(2*pi*x[0])", degree=2)

        f.t = 0

        def boundary(x, on_boundary):
            return on_boundary

        bc = DirichletBC(H, v0, boundary)

        v1 = interpolate(v0, H)
        dt = self.steps.time

        a = (dt * inner(grad(v), grad(w)) + dt * coeff_v * inner(v, w)) * dx
        L = (f * dt - coeff_v * v1) * w * dx

        A = assemble(a)
        v = Function(H)

        T = self.domain.time[-1]
        t = dt

        # solving the variational problem.
        while t <= T:
            b = assemble(L, tensor=b)
            vo.t = t
            bc.apply(A, b)

            solve(A, v.vector(), b)
            t += dt

            v1.assign(v)

        self.solution.extend(v.vector().array())

        return [self.solution, time.clock() - t_start]
Ejemplo n.º 20
0
def fluid_to_solid(function, solid: Space, fluid: Space, param: Parameters,
                   subspace_index):

    function_vector = function.vector()
    vertex_to_dof_fluid = vertex_to_dof_map(
        fluid.function_space_split[subspace_index])
    result = Function(solid.function_space_split[subspace_index])
    result_vector = result.vector()
    vector_to_dif_solid = vertex_to_dof_map(
        solid.function_space_split[subspace_index])
    horizontal = param.NUMBER_ELEMENTS_HORIZONTAL + 1
    vertical = param.NUMBER_ELEMENTS_VERTICAL + 1
    for i in range(2):

        for j in range(horizontal):

            result_vector[vector_to_dif_solid[
                (vertical - i - 1) * horizontal +
                j]] = function_vector[vertex_to_dof_fluid[i * horizontal + j]]

    return result
Ejemplo n.º 21
0
def solve_wave_equation(u0, u1, u_boundary, f, domain, mesh, degree):
    """Solving the wave equation using CG-CG method.

    Args:
        u0: Initial data.
        u1: Initial velocity.
        u_boundary: Dirichlet boundary condition.
        f: Right-hand side.
        domain: Space-time domain.
        mesh: Computational mesh.
        degree: CG(degree) will be used as the finite element.
    Outputs:
        uh: Numerical solution.
    """
    # Element
    V = FunctionSpace(mesh, "CG", degree)
    # Measures on the initial and terminal slice
    mask = MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0)
    domain.get_initial_slice().mark(mask, 1)
    ends = ds(subdomain_data=mask)
    # Form
    g = Constant(((-1.0, 0.0), (0.0, 1.0)))
    u = TrialFunction(V)
    v = TestFunction(V)
    a = dot(grad(v), dot(g, grad(u))) * dx
    L = f * v * dx + u1 * v * ends(1)
    # Assembled matrices
    A = assemble(a, keep_diagonal=True)
    b = assemble(L, keep_diagonal=True)
    # Spatial boundary condition
    bc = DirichletBC(V, u_boundary, domain.get_spatial_boundary())
    bc.apply(A, b)
    # Temporal boundary conditions (by hand)
    (A, b) = apply_time_boundary_conditions(domain, V, u0, A, b)
    # Solve
    solver = LUSolver()
    solver.set_operator(A)
    uh = Function(V)
    solver.solve(uh.vector(), b)
    return uh
Ejemplo n.º 22
0
  def get_nearest(self, fn):
    """
    returns a dolfin Function object with values given by interpolated 
    nearest-neighbor data <fn>.
    """
    #FIXME: get to work with a change of projection.
    # get the dofmap to map from mesh vertex indices to function indicies :
    df    = self.func_space.dofmap()
    dfmap = df.vertex_to_dof_map(self.mesh)
    
    unew  = Function(self.func_space)         # existing dataset projection
    uocom = unew.vector().array()             # mesh indexed main vertex values
    
    d     = float64(self.data[fn])            # original matlab spec dataset

    # get arrays of x-values for specific domain
    xs    = self.x
    ys    = self.y
    
    for v in vertices(self.mesh):
      # mesh vertex x,y coordinate :
      i   = v.index()
      p   = v.point()
      x   = p.x()
      y   = p.y()
      
      # indexes of closest datapoint to specific dataset's x and y domains :
      idx = abs(xs - x).argmin()
      idy = abs(ys - y).argmin()
      
      # data value for closest value :
      dv  = d[idy, idx] 
      if dv > 0:
        dv = 1.0
      uocom[i] = dv
    
    # set the values of the empty function's vertices to the data values :
    unew.vector().set_local(uocom[dfmap])
    return unew
Ejemplo n.º 23
0
  def get_nearest(self, fn):
    """
    returns a dolfin Function object with values given by interpolated
    nearest-neighbor data <fn>.
    """
    #FIXME: get to work with a change of projection.
    # get the dofmap to map from mesh vertex indices to function indicies :
    df    = self.func_space.dofmap()
    dfmap = df.vertex_to_dof_map(self.mesh)

    unew  = Function(self.func_space)         # existing dataset projection
    uocom = unew.vector().array()             # mesh indexed main vertex values

    d     = float64(self.data[fn])            # original matlab spec dataset

    # get arrays of x-values for specific domain
    xs    = self.x
    ys    = self.y

    for v in vertices(self.mesh):
      # mesh vertex x,y coordinate :
      i   = v.index()
      p   = v.point()
      x   = p.x()
      y   = p.y()

      # indexes of closest datapoint to specific dataset's x and y domains :
      idx = abs(xs - x).argmin()
      idy = abs(ys - y).argmin()

      # data value for closest value :
      dv  = d[idy, idx]
      if dv > 0:
        dv = 1.0
      uocom[i] = dv

    # set the values of the empty function's vertices to the data values :
    unew.vector().set_local(uocom[dfmap])
    return unew
    def _solve(self, z, x=None):
        # problem variables
        du = TrialFunction(self.V)                          # incremental displacement
        v = TestFunction(self.V)                            # test function
        u = Function(self.V)                                # displacement from previous iteration

        # kinematics
        ii = Identity(3)                                    # identity tensor dimension 3
        f = ii + grad(u)                                    # deformation gradient
        c = f.T * f                                         # right Cauchy-Green tensor

        # invariants of deformation tensors
        ic = tr(c)
        j = det(f)

        # elasticity parameters
        if type(z) in [list, np.ndarray]:
            param = self.param_remapper(z[0]) if self.param_remapper is not None else z[0]
        else:
            param = self.param_remapper(z) if self.param_remapper is not None else z

        e_var = variable(Constant(param))                   # Young's modulus
        nu = Constant(.3)                                   # Shear modulus (Lamè's second parameter)
        mu, lmbda = e_var / (2 * (1 + nu)), e_var * nu / ((1 + nu) * (1 - 2 * nu))

        # strain energy density, total potential energy
        psi = (mu / 2) * (ic - 3) - mu * ln(j) + (lmbda / 2) * (ln(j)) ** 2
        pi = psi * dx - self.time * dot(self.f, u) * self.ds(3)

        ff = derivative(pi, u, v)                           # compute first variation of pi
        jj = derivative(ff, u, du)                          # compute jacobian of f

        # solving
        if x is not None:
            numeric_evals = np.zeros(shape=(x.shape[1], len(self.times)))
            evals = np.zeros(shape=(x.shape[1], len(self.eval_times)))
        else:
            numeric_evals = None
            evals = None
        for it, t in enumerate(self.times):
            self.time.t = t
            self.solver(ff == 0, u, self.bcs, J=jj, bcs=self.bcs, solver_parameters=self.solver_parameters)
            if x is not None:
                numeric_evals[:, it] = np.log(np.array([-u(x_)[2] for x_ in x.T]).T)

        # time-interpolation
        if x is not None:
            for i in range(evals.shape[0]):
                evals[i, :] = np.interp(self.eval_times, self.times, numeric_evals[i, :])
        return (evals, u) if x is not None else u
Ejemplo n.º 25
0
 def __init__(self, *, V: Optional[FunctionSpace], mesh: Mesh,
              dt: float) -> None:
     V = V or FunctionSpace(mesh, "Lagrange", 1)
     self.V = V
     self.T = TrialFunction(V)
     self.v = TestFunction(V)
     self.T_prev = Function(V)
     self.P_s = Constant(1.0)
     self.c_s = Constant(1.0)
     self.k_e = Constant(1.0)
     self.Q_pc = Constant(1.0)
     self.Q_sw = Constant(1.0)
     self.Q_mm = Constant(1.0)
     self.dt = Constant(dt)
Ejemplo n.º 26
0
def local_project(v, V, u=None):
    """Element-wise projection using LocalSolver"""
    dv = TrialFunction(V)
    v_ = TestFunction(V)
    a_proj = inner(dv, v_) * dx
    b_proj = inner(v, v_) * dx
    solver = LocalSolver(a_proj, b_proj)
    solver.factorize()
    if u is None:
        u = Function(V)
        solver.solve_local_rhs(u)
        return u
    else:
        solver.solve_local_rhs(u)
        return
Ejemplo n.º 27
0
def morph_fenics(mesh, nodes, u, other_fix=[]):
    """
    Morph using FEniCS Functions.
    Returns a CG0 Function of DeltaX, such that
    w = DeltaX / dt
    """
    X_orig = mesh.coordinates().copy()
    X_defo = X_orig.copy()
    uN = u.compute_vertex_values().reshape(u.geometric_dimension(),
                                           len(nodes)).T
    X_defo[list(nodes), :] += uN
    # Warp the mesh
    X_new = do_tri_map(list(nodes) + list(other_fix), X_defo, X_orig)
    mesh.coordinates()[:] = X_new
    # Calculate w
    from fenics import VectorFunctionSpace, Function
    V = VectorFunctionSpace(mesh, "CG", 1)
    DeltaX = Function(V)
    nodeorder = V.dofmap().dofs(mesh, 0)
    utot = (X_new - X_orig).ravel()
    for i, l in enumerate(nodeorder):
        DeltaX.vector()[l] = utot[i]

    return DeltaX  # w = DeltaX / Dt
Ejemplo n.º 28
0
 def __init__(self, *, V: Optional[FunctionSpace], mesh: Mesh, dt: float):
     V = V or FunctionSpace(mesh, "Lagrange", 1)
     self.V = V
     self.u = TrialFunction(V)
     self.v = TestFunction(V)
     self.P_prev = Function(V)
     self.theta_a = Constant(1.0)
     self.D_e = Constant(1.0)
     self.P_d = Constant(1.0)
     self.my_v = Constant(1.0)
     self.my_d = Constant(1.0)
     self.alpha_th = Constant(1.0)
     self.M_mm = Constant(1.0)
     self.q_h = Constant(1.0)
     self.T_s = project(Constant(-5.0), V)
     self.dt = Constant(dt)
     self.mesh = mesh
Ejemplo n.º 29
0
    def load(self, number):

        # Load solution in HDF5 format
        function = Function(self.function_space)
        file = HDF5File(
            MPI.comm_world,
            f"solutions/{self.space_name}"
            f"/HDF5/{self.variable_name}_{number}.h5",
            "r",
        )
        file.read(
            function,
            f"solutions/{self.space_name}"
            f"/HDF5/{self.variable_name}_{number}",
        )
        file.close()

        return function
Ejemplo n.º 30
0
def function_interpolate(fin, fsout, coords=None, method='nearest'):
    """Copy a fenics Function

    Required arguments:
    fin: the input Function to copy
    fsout: the output FunctionSpace onto which to copy it

    Optional arguments:
    coords: the global coordinates of the DOFs of the FunctionSpace on
    which fin is defined. If not provided, gather_dof_coords will be
    called to get them. If you intend to do several interpolations
    from functions defined on the same FunctionSpace, you can avoid
    multiple calls to gather_dof_coords by supplying this argument.
    method='nearest': the method argument of
    scipy.interpolate.griddata.

    Returns:
    The values from fin are interpolated into fout, a Function defined
    on fsout. fout is returned.
    """
    comm = fsout.mesh().mpi_comm()
    logGATHER('comm.size', comm.size)
    try:
        fsin = fin.function_space()
    except AttributeError:  # fallback for Constant
        fout = fe.interpolate(fin, fsout)
        return (fout)
    vlen = fsin.dim()  # # dofs
    logGATHER('vlen', vlen)
    if coords is None:
        coords = gather_dof_coords(fsin)
    logGATHER('fsin.mesh().mpi_comm().size', fsin.mesh().mpi_comm().size)
    try:
        vec0 = fin.vector().gather_on_zero()
    except AttributeError:  # fallback for Constant
        fout = fe.interpolate(fin, fsout)
        return (fout)
    if comm.rank == 0:
        vec = vec0.copy()
    else:
        vec = np.empty(vlen)
    comm.Bcast(vec, root=0)
    logGATHER('vec', vec)
    fout = Function(fsout)
    fout.vector()[:] = griddata(coords,
                                vec,
                                fsout.tabulate_dof_coordinates(),
                                method=method).flatten()
    fout.vector().apply('insert')
    return (fout)
Ejemplo n.º 31
0
def solve():
    mesh = UnitIntervalMesh(10)
    V = FunctionSpace(mesh, "Lagrange", 1)
    dt = 0.01
    bt_params = bulk_temperature.BulkTemperatureParameters(V=V,
                                                           mesh=mesh,
                                                           dt=dt)
    bt = bulk_temperature.BulkTemperature(params=bt_params)
    a_T, L_T = bt.construct_variation_problem()
    T = Function(V)
    bt_params.T_prev.vector().set_local(
        np.random.uniform(0, -10,
                          bt_params.T_prev.vector().size()))
    map_params = mass_air_phase.MassAirPhaseParameters(V=V, mesh=mesh, dt=dt)
    map_params.T_s = T
    ma_ph = mass_air_phase.MassAirPhase(params=map_params)
    a_P, L_P = ma_ph.construct_variation_problem()
    P = Function(V)
    num_steps = 10
    t = 0
    T_sols = [bt_params.T_prev.vector().array()]
    P_sols = []
    for n in range(num_steps):
        bc = bt.make_bcs(V, 0, -10)
        _, bt_params.T_prev, T = bulk_temperature.step(time=t,
                                                       dt=dt,
                                                       t_prev=bt_params.T_prev,
                                                       t=T,
                                                       a=a_T,
                                                       l=L_T,
                                                       bc=bc)
        _, map_params.P_prev, P = mass_air_phase.step(time=t,
                                                      dt=dt,
                                                      p_prev=map_params.P_prev,
                                                      p=P,
                                                      a=a_P,
                                                      l=L_P)
        t += dt
        T_sols.append(T.vector().array())
        P_sols.append(P.vector().array())
    for T_s in T_sols:
        plt.plot(T_s)
    plt.figure()
    for P_s in P_sols:
        plt.plot(P_s)

    plt.show()