Exemplo n.º 1
0
def test_average(geometry, mesh):

    cell = mesh.ufl_cell().cellname()
    DG1_elt = FiniteElement("DG", cell, 1, variant="equispaced")
    vec_DG1 = VectorFunctionSpace(mesh, DG1_elt)
    vec_DG0 = VectorFunctionSpace(mesh, "DG", 0)
    vec_CG1 = VectorFunctionSpace(mesh, "CG", 1)

    # We will fill DG1_field with values, and average them to CG_field
    # First need to put the values into DG0 and then interpolate
    DG0_field = Function(vec_DG0)
    DG1_field = Function(vec_DG1)
    CG_field = Function(vec_CG1)
    weights = Function(vec_CG1)

    DG0_field, weights, true_values, CG_index = setup_values(
        geometry, DG0_field, weights)

    DG1_field.interpolate(DG0_field)
    kernel = kernels.Average(vec_CG1)
    kernel.apply(CG_field, weights, DG1_field)

    tolerance = 1e-12
    if geometry == "1D":
        assert abs(CG_field.dat.data[CG_index] - true_values) < tolerance
    elif geometry == "2D":
        assert abs(CG_field.dat.data[CG_index][0] - true_values[0]) < tolerance
        assert abs(CG_field.dat.data[CG_index][1] - true_values[1]) < tolerance
Exemplo n.º 2
0
def setup_2d_recovery(dirname):

    L = 100.
    W = 100.

    deltax = L / 5.
    deltay = W / 5.
    ncolumnsx = int(L / deltax)
    ncolumnsy = int(W / deltay)

    mesh = PeriodicRectangleMesh(ncolumnsx,
                                 ncolumnsy,
                                 L,
                                 W,
                                 direction='y',
                                 quadrilateral=True)
    x, y = SpatialCoordinate(mesh)

    # spaces
    VDG0 = FunctionSpace(mesh, "DG", 0)
    VCG1 = FunctionSpace(mesh, "CG", 1)
    VDG1 = FunctionSpace(mesh, "DG", 1)
    Vu = FunctionSpace(mesh, "RTCF", 1)
    VuCG1 = VectorFunctionSpace(mesh, "CG", 1)
    VuDG1 = VectorFunctionSpace(mesh, "DG", 1)

    # set up initial conditions
    np.random.seed(0)
    expr = np.random.randn() + np.random.randn() * x

    # our actual theta and rho and v
    rho_CG1_true = Function(VCG1).interpolate(expr)
    v_CG1_true = Function(VuCG1).interpolate(as_vector([expr, expr]))

    # make the initial fields by projecting expressions into the lowest order spaces
    rho_DG0 = Function(VDG0).interpolate(expr)
    rho_CG1 = Function(VCG1)
    v_Vu = Function(Vu).project(as_vector([expr, expr]))
    v_CG1 = Function(VuCG1)

    # make the recoverers and do the recovery
    rho_recoverer = Recoverer(rho_DG0,
                              rho_CG1,
                              VDG=VDG1,
                              boundary_method=Boundary_Method.dynamics)
    v_recoverer = Recoverer(v_Vu,
                            v_CG1,
                            VDG=VuDG1,
                            boundary_method=Boundary_Method.dynamics)

    rho_recoverer.project()
    v_recoverer.project()

    rho_diff = errornorm(rho_CG1, rho_CG1_true) / norm(rho_CG1_true)
    v_diff = errornorm(v_CG1, v_CG1_true) / norm(v_CG1_true)

    return (rho_diff, v_diff)
Exemplo n.º 3
0
def test_2D_cartesian_recovery(geometry, element, mesh, expr):

    family = "RTCF" if element == "quadrilateral" else "BDM"

    # horizontal base spaces
    cell = mesh.ufl_cell().cellname()

    # DG1
    DG1_elt = FiniteElement("DG", cell, 1, variant="equispaced")
    DG1 = FunctionSpace(mesh, DG1_elt)
    vec_DG1 = VectorFunctionSpace(mesh, DG1_elt)

    # spaces
    DG0 = FunctionSpace(mesh, "DG", 0)
    CG1 = FunctionSpace(mesh, "CG", 1)
    Vu = FunctionSpace(mesh, family, 1)
    vec_CG1 = VectorFunctionSpace(mesh, "CG", 1)

    # our actual theta and rho and v
    rho_CG1_true = Function(CG1).interpolate(expr)
    v_CG1_true = Function(vec_CG1).interpolate(as_vector([expr, expr]))

    # make the initial fields by projecting expressions into the lowest order spaces
    rho_DG0 = Function(DG0).interpolate(expr)
    rho_CG1 = Function(CG1)
    v_Vu = Function(Vu).project(as_vector([expr, expr]))
    v_CG1 = Function(vec_CG1)

    # make the recoverers and do the recovery
    rho_recoverer = Recoverer(rho_DG0,
                              rho_CG1,
                              VDG=DG1,
                              boundary_method=Boundary_Method.dynamics)
    v_recoverer = Recoverer(v_Vu,
                            v_CG1,
                            VDG=vec_DG1,
                            boundary_method=Boundary_Method.dynamics)

    rho_recoverer.project()
    v_recoverer.project()

    rho_diff = errornorm(rho_CG1, rho_CG1_true) / norm(rho_CG1_true)
    v_diff = errornorm(v_CG1, v_CG1_true) / norm(v_CG1_true)

    tolerance = 1e-7
    error_message = ("""
                     Incorrect recovery for {variable} with {boundary} boundary method
                     on {geometry} 2D Cartesian plane with {element} elements
                     """)
    assert rho_diff < tolerance, error_message.format(variable='rho',
                                                      boundary='dynamics',
                                                      geometry=geometry,
                                                      element=element)
    assert v_diff < tolerance, error_message.format(variable='v',
                                                    boundary='dynamics',
                                                    geometry=geometry,
                                                    element=element)
Exemplo n.º 4
0
def PeriodicIntervalMesh(ncells, length):
    """Generate a periodic mesh of an interval.

    :arg ncells: The number of cells over the interval.
    :arg length: The length the interval."""

    if ncells < 3:
        raise ValueError("1D periodic meshes with fewer than 3 \
cells are not currently supported")

    m = CircleManifoldMesh(ncells)
    coord_fs = VectorFunctionSpace(m, 'DG', 1, dim=1)
    old_coordinates = m.coordinates
    new_coordinates = Function(coord_fs)

    periodic_kernel = """double Y,pi;
            Y = 0.5*(old_coords[0][1]-old_coords[1][1]);
            pi=3.141592653589793;
            for(int i=0;i<2;i++){
            new_coords[i][0] = atan2(old_coords[i][1],old_coords[i][0])/pi/2;
            if(new_coords[i][0]<0.) new_coords[i][0] += 1;
            if(new_coords[i][0]==0 && Y<0.) new_coords[i][0] = 1.0;
            new_coords[i][0] *= L[0];
            }"""

    cL = Constant(length)

    par_loop(periodic_kernel, dx,
             {"new_coords": (new_coordinates, WRITE),
              "old_coords": (old_coordinates, READ),
              "L": (cL, READ)})

    return mesh.Mesh(new_coordinates)
    def __init__(self, mesh, nu, rho, dt=0.001, verbose=False):
        self.verbose = verbose
        self.mesh = mesh
        self.dt = dt
        self.nu = nu
        self.rho = rho
        self.mu = self.nu * self.rho
        self.has_nullspace = False

        self.forcing = Constant((0.0, 0.0, 0.0))

        self.V = VectorFunctionSpace(self.mesh, "CG", 2)
        self.Q = FunctionSpace(self.mesh, "CG", 1)
        self.W = self.V * self.Q

        self.solver_parameters = {
            "mat_type": "aij",
            "snes_type": "ksponly",
            "ksp_type": "fgmres",
            "pc_type": "asm",
            "pc_asm_type": "restrict",
            "pc_asm_overlap": 2,
            "sub_ksp_type": "preonly",
            "sub_pc_type": "ilu",
            "sub_pc_factor_levels": 1,
        }

        if self.verbose:
            self.solver_parameters["snes_monitor"] = True
            self.solver_parameters["ksp_converged_reason"] = True
Exemplo n.º 6
0
def test_dg_transport_vector(tmpdir, geometry, equation_form, tracer_setup):
    setup = tracer_setup(tmpdir, geometry)
    state = setup.state
    gdim = state.mesh.geometric_dimension()
    f_init = as_vector([setup.f_init] * gdim)
    V = VectorFunctionSpace(state.mesh, "DG", 1)
    if equation_form == "advective":
        eqn = AdvectionEquation(state,
                                V,
                                "f",
                                ufamily=setup.family,
                                udegree=setup.degree)
    else:
        eqn = ContinuityEquation(state,
                                 V,
                                 "f",
                                 ufamily=setup.family,
                                 udegree=setup.degree)
    state.fields("f").interpolate(f_init)
    state.fields("u").project(setup.uexpr)
    transport_schemes = [(eqn, SSPRK3(state))]
    f_end = as_vector([setup.f_end] * gdim)
    error = run(state, transport_schemes, setup.tmax, f_end)
    assert error < setup.tol, \
        'The transport error is greater than the permitted tolerance'
Exemplo n.º 7
0
def PeriodicIntervalMesh(ncells, length):
    """Generate a periodic mesh of an interval.

    :arg ncells: The number of cells over the interval.
    :arg length: The length the interval."""

    m = CircleManifoldMesh(ncells)
    coord_fs = VectorFunctionSpace(m, 'DG', 1, dim=1)
    old_coordinates = Function(m.coordinates)
    new_coordinates = Function(coord_fs)

    periodic_kernel = """double Y,pi;
            Y = 0.5*(old_coords[0][1]-old_coords[1][1]);
            pi=3.141592653589793;
            for(int i=0;i<2;i++){
            new_coords[i][0] = atan2(old_coords[i][1],old_coords[i][0])/pi/2;
            if(new_coords[i][0]<0.) new_coords[i][0] += 1;
            if(new_coords[i][0]==0 && Y<0.) new_coords[i][0] = 1.0;
            new_coords[i][0] *= L;
            }"""

    periodic_kernel = periodic_kernel.replace('L', str(length))

    par_loop(
        periodic_kernel, dx, {
            "new_coords": (new_coordinates, WRITE),
            "old_coords": (old_coordinates, READ)
        })

    m.coordinates = new_coordinates
    return m
Exemplo n.º 8
0
    def setup(self, state):
        if not self._initialised:
            # check geometric dimension is 3D
            if state.mesh.geometric_dimension() != 3:
                raise ValueError(
                    'Spherical components only work when the geometric dimension is 3!'
                )
            space = FunctionSpace(state.mesh, "CG", 1)
            super().setup(state, space=space)

        V = VectorFunctionSpace(state.mesh, "CG", 1)
        self.x, self.y, self.z = SpatialCoordinate(state.mesh)
        self.x_hat = Function(V).interpolate(
            Constant(as_vector([1.0, 0.0, 0.0])))
        self.y_hat = Function(V).interpolate(
            Constant(as_vector([0.0, 1.0, 0.0])))
        self.z_hat = Function(V).interpolate(
            Constant(as_vector([0.0, 0.0, 1.0])))
        self.R = sqrt(self.x**2 + self.y**2)  # distance from z axis
        self.r = sqrt(self.x**2 + self.y**2 +
                      self.z**2)  # distance from origin
        self.f = state.fields(self.fname)
        if np.prod(self.f.ufl_shape) != 3:
            raise ValueError(
                'Components can only be found of a vector function space in 3D.'
            )
Exemplo n.º 9
0
def test_gaussian_elimination(geometry, mesh):

    cell = mesh.ufl_cell().cellname()
    DG1_elt = FiniteElement("DG", cell, 1, variant="equispaced")
    DG1 = FunctionSpace(mesh, DG1_elt)
    vec_DG1 = VectorFunctionSpace(mesh, DG1_elt)

    act_coords = Function(vec_DG1)
    eff_coords = Function(vec_DG1)
    field_init = Function(DG1)
    field_true = Function(DG1)
    field_final = Function(DG1)

    # We now include things for the num of exterior values, which may be removed
    DG0 = FunctionSpace(mesh, "DG", 0)
    num_ext = Function(DG0)
    num_ext.dat.data[0] = 1.0

    # Get initial and true conditions
    field_init, field_true, act_coords, eff_coords = setup_values(
        geometry, field_init, field_true, act_coords, eff_coords)

    kernel = kernels.GaussianElimination(DG1)
    kernel.apply(field_init, field_final, act_coords, eff_coords, num_ext)

    tolerance = 1e-12
    assert abs(field_true.dat.data[0] - field_final.dat.data[0]) < tolerance
    assert abs(field_true.dat.data[1] - field_final.dat.data[1]) < tolerance

    if geometry == "2D":
        assert abs(field_true.dat.data[2] -
                   field_final.dat.data[2]) < tolerance
        assert abs(field_true.dat.data[3] -
                   field_final.dat.data[3]) < tolerance
Exemplo n.º 10
0
def fdrake_mesh(request):
    mesh_name = request.param
    if mesh_name == "FiredrakeUnitIntervalMesh":
        return UnitIntervalMesh(100)
    elif mesh_name == "FiredrakeUnitSquareMesh":
        return UnitSquareMesh(10, 10)
    elif mesh_name == "FiredrakeUnitSquareMesh-order2":
        m = UnitSquareMesh(10, 10)
        fspace = VectorFunctionSpace(m, "CG", 2)
        coords = Function(fspace).interpolate(SpatialCoordinate(m))
        from firedrake.mesh import Mesh
        return Mesh(coords)
    elif mesh_name == "FiredrakeUnitCubeMesh":
        return UnitCubeMesh(5, 5, 5)
    elif mesh_name not in ("annulus.msh", "blob2d-order1-h4e-2.msh",
                           "blob2d-order1-h6e-2.msh",
                           "blob2d-order1-h8e-2.msh"):
        raise ValueError("Unexpected value for request.param")

    # Firedrake can't read in higher order meshes from gmsh,
    # so we can only use the order1 blobs
    from firedrake import Mesh
    fd_mesh = Mesh(mesh_name)
    fd_mesh.init()
    return fd_mesh
Exemplo n.º 11
0
    def __init__(self, mesh, conditions, timestepping, params, output, solver_params):

        self.timestepping = timestepping
        self.timestep = timestepping.timestep
        self.timescale = timestepping.timescale
        self.params = params
        if output is None:
            raise RuntimeError("You must provide a directory name for dumping results")
        else:
            self.output = output
        self.outfile = File(output.dirname)
        self.dump_count = 0
        self.dump_freq = output.dumpfreq
        self.solver_params = solver_params
        self.mesh = mesh
        self.conditions = conditions

        if conditions.steady_state == True:
            self.ind = 1
        else:
            self.ind = 1
        
        family = conditions.family
        self.x, self.y = SpatialCoordinate(mesh)
        self.n = FacetNormal(mesh)
        self.V = VectorFunctionSpace(mesh, family, conditions.order + 1)
        self.U = FunctionSpace(mesh, family, conditions.order + 1)
        self.U1 = FunctionSpace(mesh, 'DG', conditions.order)
        self.S = TensorFunctionSpace(mesh, 'DG', conditions.order)
        self.D = FunctionSpace(mesh, 'DG', 0)
        self.W1 = MixedFunctionSpace([self.V, self.S])
        self.W2 = MixedFunctionSpace([self.V, self.U1, self.U1])
        self.W3 = MixedFunctionSpace([self.V, self.S, self.U1, self.U1])
Exemplo n.º 12
0
def test_average(geometry, mesh):

    vec_CG1 = VectorFunctionSpace(mesh, "CG", 1)

    # We will fill DG_field with values, and average them to CG_field
    weights = Function(vec_CG1)
    true_values = Function(vec_CG1)

    true_values = setup_values(geometry, true_values)

    kernel = kernels.AverageWeightings(vec_CG1)
    kernel.apply(weights)

    tolerance = 1e-12
    if geometry == "1D":
        for i, (weight, true) in enumerate(
                zip(weights.dat.data[:], true_values.dat.data[:])):
            assert abs(weight - true
                       ) < tolerance, "Weight not correct at position %i" % i
    elif geometry == "2D":
        for i, (weight, true) in enumerate(
                zip(weights.dat.data[:], true_values.dat.data[:])):
            for weight_j, true_j in zip(weight, true):
                assert abs(
                    weight_j - true_j
                ) < tolerance, "Weight not correct at position %i" % i
Exemplo n.º 13
0
def to_2nd_order(mesh, circle_bdy_id=None, rad=1.0):

    # make new coordinates function
    V = VectorFunctionSpace(mesh, 'CG', 2)
    new_coordinates = project(mesh.coordinates, V)

    # If we have a circle, move any nodes on the circle bdy
    # onto the circle. Note circle MUST be centered at origin
    if circle_bdy_id is not None:
        nodes_on_circle = V.boundary_nodes(circle_bdy_id, 'geometric')
        #Force all cell nodes to have given radius :arg:`rad`
        for node in nodes_on_circle:
            scale = rad / la.norm(new_coordinates.dat.data[node])
            new_coordinates.dat.data[node] *= scale

    # Make a new mesh with given coordinates
    return Mesh(new_coordinates)
Exemplo n.º 14
0
def meshcoords(mesh, fs):
    "shared routine for creating fem coordinates"

    W = VectorFunctionSpace(mesh, fs.ufl_element())
    X = interpolate(mesh.coordinates, W)
    meshcoords = X.vector().gather()

    return meshcoords
Exemplo n.º 15
0
def PeriodicIntervalMesh(ncells, length, comm=COMM_WORLD):
    """Generate a periodic mesh of an interval.

    :arg ncells: The number of cells over the interval.
    :arg length: The length the interval.
    :kwarg comm: Optional communicator to build the mesh on (defaults to
        COMM_WORLD).
    """

    if ncells < 3:
        raise ValueError("1D periodic meshes with fewer than 3 \
cells are not currently supported")

    m = CircleManifoldMesh(ncells, comm=comm)
    coord_fs = VectorFunctionSpace(m, 'DG', 1, dim=1)
    old_coordinates = m.coordinates
    new_coordinates = Function(coord_fs)

    periodic_kernel = """
    const double pi = 3.141592653589793;
    const double eps = 1e-12;
    double a = atan2(old_coords[0][1], old_coords[0][0]) / (2*pi);
    double b = atan2(old_coords[1][1], old_coords[1][0]) / (2*pi);
    int swap = 0;
    if ( a >= b ) {
        const double tmp = b;
        b = a;
        a = tmp;
        swap = 1;
    }
    if ( fabs(b) < eps && a < -eps ) {
        b = 1.0;
    }
    if ( a < -eps ) {
        a += 1;
    }
    if ( b < -eps ) {
        b += 1;
    }
    if ( swap ) {
        const double tmp = b;
        b = a;
        a = tmp;
    }
    new_coords[0][0] = a * L[0];
    new_coords[1][0] = b * L[0];
    """

    cL = Constant(length)

    par_loop(
        periodic_kernel, dx, {
            "new_coords": (new_coordinates, WRITE),
            "old_coords": (old_coordinates, READ),
            "L": (cL, READ)
        })

    return mesh.Mesh(new_coordinates)
Exemplo n.º 16
0
def get_latlon_mesh(mesh):
    """Build 2D projected mesh of spherical mesh"""
    crds_orig = mesh.coordinates
    mesh_dg_fs = VectorFunctionSpace(mesh, "DG", 1)
    crds_dg = Function(mesh_dg_fs)
    crds_latlon = Function(mesh_dg_fs)
    par_loop(
        """
for (int i=0; i<3; i++) {
    for (int j=0; j<3; j++) {
        dg[i][j] = cg[i][j];
    }
}
""", dx, {
            'dg': (crds_dg, WRITE),
            'cg': (crds_orig, READ)
        })

    # lat-lon 'x' = atan2(y, x)
    crds_latlon.dat.data[:, 0] = arctan2(crds_dg.dat.data[:, 1],
                                         crds_dg.dat.data[:, 0])
    # lat-lon 'y' = asin(z/sqrt(x^2 + y^2 + z^2))
    crds_latlon.dat.data[:, 1] = (arcsin(
        crds_dg.dat.data[:, 2] /
        np_sqrt(crds_dg.dat.data[:, 0]**2 + crds_dg.dat.data[:, 1]**2 +
                crds_dg.dat.data[:, 2]**2)))
    crds_latlon.dat.data[:, 2] = 0.0

    kernel = op2.Kernel(
        """
#define PI 3.141592653589793
#define TWO_PI 6.283185307179586
void splat_coords(double **coords) {
    double diff0 = (coords[0][0] - coords[1][0]);
    double diff1 = (coords[0][0] - coords[2][0]);
    double diff2 = (coords[1][0] - coords[2][0]);

    if (fabs(diff0) > PI || fabs(diff1) > PI || fabs(diff2) > PI) {
        const int sign0 = coords[0][0] < 0 ? -1 : 1;
        const int sign1 = coords[1][0] < 0 ? -1 : 1;
        const int sign2 = coords[2][0] < 0 ? -1 : 1;
        if (sign0 < 0) {
            coords[0][0] += TWO_PI;
        }
        if (sign1 < 0) {
            coords[1][0] += TWO_PI;
        }
        if (sign2 < 0) {
            coords[2][0] += TWO_PI;
        }
    }
}
""", "splat_coords")

    op2.par_loop(kernel, crds_latlon.cell_set,
                 crds_latlon.dat(op2.RW, crds_latlon.cell_node_map()))
    return Mesh(crds_latlon)
Exemplo n.º 17
0
    def _prepare_output(self, function, cg):
        from firedrake import FunctionSpace, VectorFunctionSpace, \
            TensorFunctionSpace, Function, Projector, Interpolator

        name = function.name()

        # Need to project/interpolate?
        # If space is linear and continuity of output space matches
        # continuity of current space, then we can just use the
        # input function.
        if is_linear(function.function_space()) and \
           is_dg(function.function_space()) == (not cg) and \
           is_cg(function.function_space()) == cg:
            return OFunction(array=get_array(function),
                             name=name, function=function)

        # OK, let's go and do it.
        if cg:
            family = "Lagrange"
        else:
            family = "Discontinuous Lagrange"

        output = self._output_functions.get(function)
        if output is None:
            # Build appropriate space for output function.
            shape = function.ufl_shape
            if len(shape) == 0:
                V = FunctionSpace(function.ufl_domain(), family, 1)
            elif len(shape) == 1:
                if numpy.prod(shape) > 3:
                    raise ValueError("Can't write vectors with more than 3 components")
                V = VectorFunctionSpace(function.ufl_domain(), family, 1,
                                        dim=shape[0])
            elif len(shape) == 2:
                if numpy.prod(shape) > 9:
                    raise ValueError("Can't write tensors with more than 9 components")
                V = TensorFunctionSpace(function.ufl_domain(), family, 1,
                                        shape=shape)
            else:
                raise ValueError("Unsupported shape %s" % (shape, ))
            output = Function(V)
            self._output_functions[function] = output

        if self.project:
            projector = self._mappers.get(function)
            if projector is None:
                projector = Projector(function, output)
                self._mappers[function] = projector
            projector.project()
        else:
            interpolator = self._mappers.get(function)
            if interpolator is None:
                interpolator = Interpolator(function, output)
                self._mappers[function] = interpolator
            interpolator.interpolate()

        return OFunction(array=get_array(output), name=name, function=output)
Exemplo n.º 18
0
def elasticity(mesh, degree):
    V = VectorFunctionSpace(mesh, 'CG', degree)
    u = TrialFunction(V)
    v = TestFunction(V)

    def eps(u):
        return (grad(u) + grad(u).T) / 2

    return inner(eps(v), eps(u)) * dx

    return inner(grad(u), grad(v)) * dx
Exemplo n.º 19
0
def _get_coordinates(mesh):
    r"""Return the coordinates of a mesh if the mesh is piecewise linear,
    or interpolate them to piecewise linear if the mesh is curved"""
    coordinates = mesh.coordinates
    element = coordinates.function_space().ufl_element()
    if element.degree() != 1:
        from firedrake import VectorFunctionSpace, interpolate
        V = VectorFunctionSpace(mesh, element.family(), 1)
        coordinates = interpolate(coordinates, V)

    return coordinates
def test_vector_recovered_space_setup(tmpdir, geometry, tracer_setup):

    # Make mesh and state using routine from conftest
    setup = tracer_setup(tmpdir, geometry, degree=0)
    state = setup.state
    mesh = state.mesh
    gdim = state.mesh.geometric_dimension()

    # Spaces for recovery
    Vu = state.spaces("HDiv", family=setup.family, degree=setup.degree)
    if geometry == "slice":
        VDG1 = state.spaces("DG1_equispaced")
        Vec_DG1 = VectorFunctionSpace(mesh, VDG1.ufl_element(), name='Vec_DG1')
        Vec_CG1 = VectorFunctionSpace(mesh, "CG", 1, name='Vec_CG1')
        Vu_brok = FunctionSpace(mesh, BrokenElement(Vu.ufl_element()))

        rec_opts = RecoveredOptions(embedding_space=Vec_DG1,
                                    recovered_space=Vec_CG1,
                                    broken_space=Vu_brok,
                                    boundary_method=Boundary_Method.dynamics)
    else:
        raise NotImplementedError(
            f'Recovered spaces for geometry {geometry} have not been implemented'
        )

    # Make equation
    eqn = AdvectionEquation(state, Vu, "f", ufamily=setup.family, udegree=1)

    # Initialise fields
    f_init = as_vector([setup.f_init] * gdim)
    state.fields("f").project(f_init)
    state.fields("u").project(setup.uexpr)

    transport_scheme = [(eqn, SSPRK3(state, options=rec_opts))]

    f_end = as_vector([setup.f_end] * gdim)

    # Run and check error
    error = run(state, transport_scheme, setup.tmax, f_end)
    assert error < setup.tol, \
        'The transport error is greater than the permitted tolerance'
Exemplo n.º 21
0
def correct_eff_coords(eff_coords):
    """
    Correct the effective coordinates calculated by simply averaging
    which will not be correct at periodic boundaries.
    :arg eff_coords: the effective coordinates in vec_DG1 space.
    """

    mesh = eff_coords.function_space().mesh()
    vec_CG1 = VectorFunctionSpace(mesh, "CG", 1)

    if vec_CG1.extruded:
        cell = mesh._base_mesh.ufl_cell().cellname()
        DG1_hori_elt = FiniteElement("DG", cell, 1, variant="equispaced")
        DG1_vert_elt = FiniteElement("DG", interval, 1, variant="equispaced")
        DG1_element = TensorProductElement(DG1_hori_elt, DG1_vert_elt)
    else:
        cell = mesh.ufl_cell().cellname()
        DG1_element = FiniteElement("DG", cell, 1, variant="equispaced")

    vec_DG1 = VectorFunctionSpace(mesh, DG1_element)

    x = SpatialCoordinate(mesh)

    if eff_coords.function_space() != vec_DG1:
        raise ValueError('eff_coords needs to be in the vector DG1 space')

    # obtain different coords in DG1
    DG1_coords = Function(vec_DG1).interpolate(x)
    CG1_coords_from_DG1 = Function(vec_CG1)
    averager = Averager(DG1_coords, CG1_coords_from_DG1)
    averager.project()
    DG1_coords_from_averaged_CG1 = Function(vec_DG1).interpolate(
        CG1_coords_from_DG1)
    DG1_coords_diff = Function(vec_DG1).interpolate(
        DG1_coords - DG1_coords_from_averaged_CG1)

    # interpolate coordinates, adjusting those different coordinates
    adjusted_coords = Function(vec_DG1)
    adjusted_coords.interpolate(eff_coords + DG1_coords_diff)

    return adjusted_coords
Exemplo n.º 22
0
def setup_IPdiffusion(dirname, vector, DG):

    dt = 0.01
    L = 10.
    m = PeriodicIntervalMesh(50, L)
    mesh = ExtrudedMesh(m, layers=50, layer_height=0.2)

    fieldlist = ['u', 'D']
    timestepping = TimesteppingParameters(dt=dt)
    parameters = CompressibleParameters()
    output = OutputParameters(dirname=dirname)

    state = State(mesh,
                  vertical_degree=1,
                  horizontal_degree=1,
                  family="CG",
                  timestepping=timestepping,
                  parameters=parameters,
                  output=output,
                  fieldlist=fieldlist)

    x = SpatialCoordinate(mesh)
    if vector:
        kappa = Constant([[0.05, 0.], [0., 0.05]])
        if DG:
            Space = VectorFunctionSpace(mesh, "DG", 1)
        else:
            Space = state.spaces("HDiv")
        fexpr = as_vector([exp(-(L / 2. - x[0])**2 - (L / 2. - x[1])**2), 0.])
    else:
        kappa = 0.05
        if DG:
            Space = state.spaces("DG")
        else:
            Space = state.spaces("HDiv_v")
        fexpr = exp(-(L / 2. - x[0])**2 - (L / 2. - x[1])**2)

    f = state.fields("f", Space)
    try:
        f.interpolate(fexpr)
    except NotImplementedError:
        # finat elements raise NotImplementedError if they don't
        # advertise a dual for interpolation.
        f.project(fexpr)

    mu = 5.
    f_diffusion = InteriorPenalty(state,
                                  f.function_space(),
                                  kappa=kappa,
                                  mu=mu)
    diffused_fields = [("f", f_diffusion)]
    stepper = AdvectionDiffusion(state, diffused_fields=diffused_fields)
    return stepper
def run_advection_diffusion(tmpdir):

    # Mesh, state and equation
    L = 10
    mesh = PeriodicIntervalMesh(20, L)
    dt = 0.02
    tmax = 1.0

    diffusion_params = DiffusionParameters(kappa=0.75, mu=5)
    output = OutputParameters(dirname=str(tmpdir), dumpfreq=25)
    state = State(mesh, dt=dt, output=output)
    V = state.spaces("DG", "DG", 1)
    Vu = VectorFunctionSpace(mesh, "CG", 1)

    equation = AdvectionDiffusionEquation(
        state, V, "f", Vu=Vu, diffusion_parameters=diffusion_params)

    problem = [(equation, ((SSPRK3(state), transport), (BackwardEuler(state),
                                                        diffusion)))]

    # Initial conditions
    x = SpatialCoordinate(mesh)
    xc_init = 0.25 * L
    xc_end = 0.75 * L
    umax = 0.5 * L / tmax

    # Get minimum distance on periodic interval to xc
    x_init = conditional(
        sqrt((x[0] - xc_init)**2) < 0.5 * L, x[0] - xc_init,
        L + x[0] - xc_init)

    x_end = conditional(
        sqrt((x[0] - xc_end)**2) < 0.5 * L, x[0] - xc_end, L + x[0] - xc_end)

    f_init = 5.0
    f_end = f_init / 2.0
    f_width_init = L / 10.0
    f_width_end = f_width_init * 2.0
    f_init_expr = f_init * exp(-(x_init / f_width_init)**2)
    f_end_expr = f_end * exp(-(x_end / f_width_end)**2)

    state.fields('f').interpolate(f_init_expr)
    state.fields('u').interpolate(as_vector([Constant(umax)]))
    f_end = state.fields('f_end', V).interpolate(f_end_expr)

    # Time stepper
    timestepper = PrescribedTransport(state, problem)
    timestepper.run(0, tmax=tmax)

    error = norm(state.fields('f') - f_end) / norm(f_end)

    return error
Exemplo n.º 24
0
    def _prepare_output(self, function, max_elem):
        from firedrake import FunctionSpace, VectorFunctionSpace, \
            TensorFunctionSpace, Function, Projector, Interpolator

        name = function.name()
        # Need to project/interpolate?
        # If space is not the max element, we can do so.
        if function.ufl_element == max_elem:
            return OFunction(array=get_array(function),
                             name=name,
                             function=function)
        #  OK, let's go and do it.
        shape = function.ufl_shape
        output = self._output_functions.get(function)
        if output is None:
            # Build appropriate space for output function.
            shape = function.ufl_shape
            if len(shape) == 0:
                V = FunctionSpace(function.ufl_domain(), max_elem)
            elif len(shape) == 1:
                if numpy.prod(shape) > 3:
                    raise ValueError(
                        "Can't write vectors with more than 3 components")
                V = VectorFunctionSpace(function.ufl_domain(),
                                        max_elem,
                                        dim=shape[0])
            elif len(shape) == 2:
                if numpy.prod(shape) > 9:
                    raise ValueError(
                        "Can't write tensors with more than 9 components")
                V = TensorFunctionSpace(function.ufl_domain(),
                                        max_elem,
                                        shape=shape)
            else:
                raise ValueError("Unsupported shape %s" % (shape, ))
            output = Function(V)
            self._output_functions[function] = output
        if self.project:
            projector = self._mappers.get(function)
            if projector is None:
                projector = Projector(function, output)
                self._mappers[function] = projector
            projector.project()
        else:
            interpolator = self._mappers.get(function)
            if interpolator is None:
                interpolator = Interpolator(function, output)
                self._mappers[function] = interpolator
            interpolator.interpolate()

        return OFunction(array=get_array(output), name=name, function=output)
Exemplo n.º 25
0
def FunctionSpaceDegreeRaise(V, degree_raise):
    element = V._ufl_element

    degree = element.degree(0)
    space_type = repr(element)[0]
    element_type = element.family()

    mesh = V.mesh()
    if space_type == 'V':
        V = VectorFunctionSpace(mesh, element_type, degree + degree_raise)
    elif space_type == 'F':
        V = FunctionSpace(mesh, element_type, degree + degree_raise)

    return V
Exemplo n.º 26
0
def test_average(geometry, mesh):

    cell = mesh.ufl_cell().cellname()
    DG1_elt = FiniteElement("DG", cell, 1, variant="equispaced")
    vec_DG1 = VectorFunctionSpace(mesh, DG1_elt)
    vec_CG1 = VectorFunctionSpace(mesh, "CG", 1)

    # We will fill DG_field with values, and average them to CG_field
    DG_field = Function(vec_DG1)
    CG_field = Function(vec_CG1)
    weights = Function(vec_CG1)

    DG_field, weights, true_values = setup_values(geometry, DG_field, weights)

    kernel = kernels.Average(vec_CG1)
    kernel.apply(CG_field, weights, DG_field)

    tolerance = 1e-12
    if geometry == "1D":
        assert abs(CG_field.dat.data[1] - true_values) < tolerance
    elif geometry == "2D":
        assert abs(CG_field.dat.data[2][0] - true_values[0]) < tolerance
        assert abs(CG_field.dat.data[2][1] - true_values[1]) < tolerance
Exemplo n.º 27
0
    def __init__(self):
        N = 5
        self.mesh = UnitSquareMesh(N, N)
        self.T0 = self.mesh.coordinates.copy(deepcopy=True)
        # random perturmabion
        h = 1 / N
        self.X = SpatialCoordinate(self.mesh)
        W = VectorFunctionSpace(self.mesh, "CG", 1)
        self.w = Function(W)
        vec = self.w.vector()
        np.random.seed(1)
        vec.set_local(
            np.random.uniform(-h / 3., h / 3., size=vec.get_local().shape))

        self.name = "missing name"
        self.bc = None
Exemplo n.º 28
0
    def set_bdy_as_target(self, bdy_id, method):
        """
            :arg bdy_id: An iterable of subdomain ids as could be
                              accepted as the :arg:`subdomain` in
                              a :class:`DirichletBC` from :mod:`firedrake`.
            :arg method: A method for determining bdy nodes as
                         in :class:`DirichletBC', either 'geometric'
                         or 'topological'
        """
        mesh = self._function_space.mesh()

        # if just passed an int, convert to an iterable of ints
        # so that just one case to deal with
        if isinstance(bdy_id, int):
            bdy_id = [bdy_id]
        target_markers = set(bdy_id)

        # Check that bdy ids are valid
        if not target_markers <= set(mesh.exterior_facets.unique_markers):
            warn("The following bdy ids are not exterior facet ids: %s" %
                 (target_markers - set(mesh.exterior_facets.unique_markers)))

        if not target_markers & set(mesh.exterior_facets.unique_markers):
            raise ValueError("No bdy ids are exterior facet ids")

        self._target_indices = set()
        for marker in target_markers:
            self._target_indices |= set(
                self._function_space.boundary_nodes(marker, method))
        self._target_indices = np.array(list(self._target_indices),
                                        dtype=np.int32)

        # Get coordinates of nodes
        coords = SpatialCoordinate(mesh)
        function_space_dim = VectorFunctionSpace(
            mesh,
            self._function_space.ufl_element().family(),
            degree=self._function_space.ufl_element().degree())

        coords = Function(function_space_dim).interpolate(coords)
        coords = np.real(coords.dat.data)

        target_pts = coords[self._target_indices]
        # change from [nnodes][ambient_dim] to [ambient_dim][nnodes]
        target_pts = np.transpose(target_pts).copy()
        self._target = PointsTarget(target_pts)
Exemplo n.º 29
0
def prepare_trial(trial, true_sol_name, cl_ctx, queue):
    tuple_trial = trial_to_tuple(trial)
    if tuple_trial not in prepared_trials:

        mesh = trial['mesh']
        degree = trial['degree']
        kappa = trial['kappa']

        function_space = FunctionSpace(mesh, 'CG', degree)
        vect_function_space = VectorFunctionSpace(mesh, 'CG', degree)

        true_sol = get_true_sol(function_space, kappa, cl_ctx, queue)
        true_sol = Function(function_space).interpolate(true_sol)
        prepared_trials[tuple_trial] = (mesh, function_space,
                                        vect_function_space, true_sol,
                                        grad(true_sol))

    return prepared_trials[tuple_trial]
Exemplo n.º 30
0
def get_target_points_and_indices(fspace, boundary_ids):
    """
    Get  the points from the function space which lie on the given boundary
    id as a pytential PointsTarget, and their indices into the
    firedrake function

    :return: (target_indices, target_points)
    """
    # if just passed an int, convert to an iterable of ints
    # so that just one case to deal with
    if isinstance(boundary_ids, int):
        boundary_ids = [boundary_ids]
    target_markers = set(boundary_ids)

    # Check that bdy ids are valid
    if not target_markers <= set(fspace.mesh().exterior_facets.unique_markers):
        raise ValueError(
            "The following bdy ids are not exterior facet ids: %s" %
            (target_markers -
             set(fspace.mesh().exterior_facets.unique_markers)))

    if not target_markers & set(fspace.mesh().exterior_facets.unique_markers):
        raise ValueError("No bdy ids are exterior facet ids")

    target_indices = set()
    for marker in target_markers:
        target_indices |= set(fspace.boundary_nodes(marker, 'topological'))
    target_indices = np.array(list(target_indices), dtype=np.int32)

    target_indices = np.array(target_indices, dtype=np.int32)
    # Get coordinates of nodes
    coords = SpatialCoordinate(fspace.mesh())
    function_space_dim = VectorFunctionSpace(
        fspace.mesh(),
        fspace.ufl_element().family(),
        degree=fspace.ufl_element().degree())

    coords = Function(function_space_dim).interpolate(coords)
    coords = np.real(coords.dat.data)

    target_pts = coords[target_indices]
    # change from [nnodes][ambient_dim] to [ambient_dim][nnodes]
    target_pts = np.transpose(target_pts).copy()
    return (target_indices, PointsTarget(target_pts))