Esempio n. 1
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)
def test_2D_dirichlet_regions():
    # Can't do mesh refinement because MeshHierarchy ruins the domain tags
    mesh = Mesh("./2D_mesh.msh")
    dim = mesh.geometric_dimension()
    x = SpatialCoordinate(mesh)

    S = VectorFunctionSpace(mesh, "CG", 1)
    beta = 1.0
    reg_solver = RegularizationSolver(
        S, mesh, beta=beta, gamma=0.0, dx=dx, design_domain=0
    )

    # Exact solution with free Neumann boundary conditions for this domain
    u_exact = Function(S)
    u_exact_component = (-cos(x[0] * pi * 2) + 1) * (-cos(x[1] * pi * 2) + 1)

    u_exact.interpolate(
        as_vector(tuple(u_exact_component for _ in range(dim)))
    )
    f = Function(S)
    f_component = (
        -beta
        * (
            4.0 * pi * pi * cos(2 * pi * x[0]) * (-cos(2 * pi * x[1]) + 1)
            + 4.0 * pi * pi * cos(2 * pi * x[1]) * (-cos(2 * pi * x[0]) + 1)
        )
        + u_exact_component
    )
    f.interpolate(as_vector(tuple(f_component for _ in range(dim))))

    theta = TestFunction(S)
    rhs_form = inner(f, theta) * dx

    velocity = Function(S)
    rhs = assemble(rhs_form)
    reg_solver.solve(velocity, rhs)
    assert norm(project(domainify(u_exact, x) - velocity, S)) < 1e-3
Esempio n. 3
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)
Esempio n. 4
0
def mesh_from_gmsh_code(geo_code, clscale=1.0, dim=2, comm=COMM_WORLD,
                        name="/tmp/tmp", smooth=0, delete_files=True):
    if comm.rank == 0:
        with open("%s.geo" % name, "w") as text_file:
            text_file.write(geo_code)
    comm.Barrier()
    generateGmsh("%s.geo" % name, "%s.msh" % name, dim, clscale,
                 comm=comm, smooth=smooth)
    mesh = Mesh("%s.msh" % name)
    if delete_files:
        try:
            os.remove("%s.geo" % name)
        except OSError:
            pass
        try:
            os.remove("%s.msh" % name)
        except OSError:
            pass
    return mesh
Esempio n. 5
0
def max_mesh_dimension(mesh: fd.Mesh):
    coords = mesh.coordinates
    MAXSP = fd.FunctionSpace(mesh, "R", 0)
    max_y = fd.Function(MAXSP)
    min_y = fd.Function(MAXSP)
    max_x = fd.Function(MAXSP)
    min_x = fd.Function(MAXSP)
    domain = "{[i, j] : 0 <= i < u.dofs}"

    def extract_comp(mode, comp, result):
        instruction = f"""
                       component[0] = abs(u[i, {comp}])
                       """
        fd.par_loop(
            (domain, instruction),
            fd.dx,
            {
                "u": (coords, fd.READ),
                "component": (result, mode)
            },
            is_loopy_kernel=True,
        )
        return result

    max_y_comp = extract_comp(fd.MAX, 1, max_y).dat.data[0]
    min_y_comp = extract_comp(fd.MIN, 1, min_y).dat.data[0]
    max_x_comp = extract_comp(fd.MAX, 0, max_x).dat.data[0]
    min_x_comp = extract_comp(fd.MIN, 0, min_x).dat.data[0]
    max_dim_x = abs(max_x_comp - min_x_comp)
    max_dim_y = abs(max_y_comp - min_y_comp)

    max_dim = max(max_dim_x, max_dim_y)
    if mesh.geometric_dimension() == 3:
        max_z = fd.Function(MAXSP)
        min_z = fd.Function(MAXSP)
        max_z_comp = extract_comp(fd.MAX, 2, max_z).dat.data[0]
        min_z_comp = extract_comp(fd.MIN, 2, min_z).dat.data[0]
        max_dim_z = abs(max_z_comp - min_z_comp)
        max_dim = max(max_dim, max_dim_z)

    return max_dim
xc = L/2.
x, z = SpatialCoordinate(ext_mesh)
hm = 1.
zs = hm*a**2/((x-xc)**2 + a**2)

smooth_z = True
dirname = 'nh_mountain'
if smooth_z:
    dirname += '_smootherz'
    zh = 5000.
    xexpr = as_vector([x, conditional(z < zh, z + cos(0.5*pi*z/zh)**6*zs, z)])
else:
    xexpr = as_vector([x, z + ((H-z)/H)*zs])

new_coords = Function(Vc).interpolate(xexpr)
mesh = Mesh(new_coords)

# sponge function
W_DG = FunctionSpace(mesh, "DG", 2)
x, z = SpatialCoordinate(mesh)
zc = H-10000.
mubar = 0.15/dt
mu_top = conditional(z <= zc, 0.0, mubar*sin((pi/2.)*(z-zc)/(H-zc))**2)
mu = Function(W_DG).interpolate(mu_top)
fieldlist = ['u', 'rho', 'theta']
timestepping = TimesteppingParameters(dt=dt)

output = OutputParameters(dirname=dirname,
                          dumpfreq=18,
                          dumplist=['u'],
                          perturbation_fields=['theta', 'rho'],
def test_3D_dirichlet_regions():
    # Can't do mesh refinement because MeshHierarchy ruins the domain tags
    mesh = Mesh("./3D_mesh.msh")
    dim = mesh.geometric_dimension()
    x = SpatialCoordinate(mesh)
    solver_parameters_amg = {
        "ksp_type": "cg",
        "ksp_converged_reason": None,
        "ksp_rtol": 1e-7,
        "pc_type": "hypre",
        "pc_hypre_type": "boomeramg",
        "pc_hypre_boomeramg_max_iter": 5,
        "pc_hypre_boomeramg_coarsen_type": "PMIS",
        "pc_hypre_boomeramg_agg_nl": 2,
        "pc_hypre_boomeramg_strong_threshold": 0.95,
        "pc_hypre_boomeramg_interp_type": "ext+i",
        "pc_hypre_boomeramg_P_max": 2,
        "pc_hypre_boomeramg_relax_type_all": "sequential-Gauss-Seidel",
        "pc_hypre_boomeramg_grid_sweeps_all": 1,
        "pc_hypre_boomeramg_truncfactor": 0.3,
        "pc_hypre_boomeramg_max_levels": 6,
    }

    S = VectorFunctionSpace(mesh, "CG", 1)
    beta = 1.0
    reg_solver = RegularizationSolver(
        S,
        mesh,
        beta=beta,
        gamma=0.0,
        dx=dx,
        design_domain=0,
        solver_parameters=solver_parameters_amg,
    )

    # Exact solution with free Neumann boundary conditions for this domain
    u_exact = Function(S)
    u_exact_component = (
        (-cos(x[0] * pi * 2) + 1)
        * (-cos(x[1] * pi * 2) + 1)
        * (-cos(x[2] * pi * 2) + 1)
    )

    u_exact.interpolate(
        as_vector(tuple(u_exact_component for _ in range(dim)))
    )
    f = Function(S)
    f_component = (
        -beta
        * (
            4.0
            * pi
            * pi
            * cos(2 * pi * x[0])
            * (-cos(2 * pi * x[1]) + 1)
            * (-cos(2 * pi * x[2]) + 1)
            + 4.0
            * pi
            * pi
            * cos(2 * pi * x[1])
            * (-cos(2 * pi * x[0]) + 1)
            * (-cos(2 * pi * x[2]) + 1)
            + 4.0
            * pi
            * pi
            * cos(2 * pi * x[2])
            * (-cos(2 * pi * x[1]) + 1)
            * (-cos(2 * pi * x[0]) + 1)
        )
        + u_exact_component
    )
    f.interpolate(as_vector(tuple(f_component for _ in range(dim))))

    theta = TestFunction(S)
    rhs_form = inner(f, theta) * dx

    velocity = Function(S)
    rhs = assemble(rhs_form)
    reg_solver.solve(velocity, rhs)
    error = norm(
        project(
            domainify(u_exact, x) - velocity,
            S,
            solver_parameters=solver_parameters_amg,
        )
    )
    assert error < 5e-2
Esempio n. 8
0
def get_latlon_mesh(mesh):
    coords_orig = mesh.coordinates
    coords_fs = coords_orig.function_space()

    if coords_fs.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_elt = TensorProductElement(DG1_hori_elt, DG1_vert_elt)
    else:
        cell = mesh.ufl_cell().cellname()
        DG1_elt = FiniteElement("DG", cell, 1, variant="equispaced")
    vec_DG1 = VectorFunctionSpace(mesh, DG1_elt)
    coords_dg = Function(vec_DG1).interpolate(coords_orig)
    coords_latlon = Function(vec_DG1)
    shapes = {"nDOFs": vec_DG1.finat_element.space_dimension(), 'dim': 3}

    radius = np.min(
        np.sqrt(coords_dg.dat.data[:, 0]**2 + coords_dg.dat.data[:, 1]**2 +
                coords_dg.dat.data[:, 2]**2))
    # lat-lon 'x' = atan2(y, x)
    coords_latlon.dat.data[:, 0] = np.arctan2(coords_dg.dat.data[:, 1],
                                              coords_dg.dat.data[:, 0])
    # lat-lon 'y' = asin(z/sqrt(x^2 + y^2 + z^2))
    coords_latlon.dat.data[:, 1] = np.arcsin(
        coords_dg.dat.data[:, 2] /
        np.sqrt(coords_dg.dat.data[:, 0]**2 + coords_dg.dat.data[:, 1]**2 +
                coords_dg.dat.data[:, 2]**2))
    # our vertical coordinate is radius - the minimum radius
    coords_latlon.dat.data[:,
                           2] = np.sqrt(coords_dg.dat.data[:, 0]**2 +
                                        coords_dg.dat.data[:, 1]**2 +
                                        coords_dg.dat.data[:, 2]**2) - radius

    # We need to ensure that all points in a cell are on the same side of the branch cut in longitude coords
    # This kernel amends the longitude coords so that all longitudes in one cell are close together
    kernel = op2.Kernel(
        """
#define PI 3.141592653589793
#define TWO_PI 6.283185307179586
void splat_coords(double *coords) {{
    double max_diff = 0.0;
    double diff = 0.0;

    for (int i=0; i<{nDOFs}; i++) {{
        for (int j=0; j<{nDOFs}; j++) {{
            diff = coords[i*{dim}] - coords[j*{dim}];
            if (fabs(diff) > max_diff) {{
                max_diff = diff;
            }}
        }}
    }}

    if (max_diff > PI) {{
        for (int i=0; i<{nDOFs}; i++) {{
            if (coords[i*{dim}] < 0) {{
                coords[i*{dim}] += TWO_PI;
            }}
        }}
    }}
}}
""".format(**shapes), "splat_coords")

    op2.par_loop(kernel, coords_latlon.cell_set,
                 coords_latlon.dat(op2.RW, coords_latlon.cell_node_map()))
    return Mesh(coords_latlon)
Esempio n. 9
0
def run_trial(trial_id):
    """
    (key, output), or *None* if use_cache is *True*
    and already have this result stored
    """
    # {{{  Get indexes into lists
    mesh_ndx = trial_id % len(mesh_names)
    trial_id //= len(mesh_names)
    mesh_name = mesh_names[mesh_ndx]
    # If new mesh, delete old mesh and read in new one
    global current_mesh_name, mesh
    if current_mesh_name != mesh_name:
        del mesh
        mesh = Mesh(mesh_name)
        if use_2nd_order:
            mesh = to_2nd_order(mesh)
        current_mesh_name = mesh_name

    mesh_h = mesh_h_vals[mesh_ndx]

    degree_ndx = trial_id % len(degree_list)
    trial_id //= len(degree_list)
    degree = degree_list[degree_ndx]

    kappa_ndx = trial_id % len(kappa_list)
    trial_id //= len(kappa_list)
    kappa = kappa_list[kappa_ndx]

    method_ndx = trial_id % len(method_list)
    trial_id //= len(method_list)
    method = method_list[method_ndx]
    solver_params = method_to_kwargs[method]['solver_parameters']

    # Make sure this is a valid iteration index
    assert trial_id == 0
    # }}}

    kwargs = method_to_kwargs[method]
    # {{{ Create key holding data of this trial run:

    setup_info['h'] = str(mesh_h)
    setup_info['degree'] = str(degree)
    setup_info['kappa'] = str(kappa)
    setup_info['method'] = str(method)

    setup_info['pc_type'] = str(solver_params['pc_type'])
    if solver_params['ksp_type'] == 'preonly':
        setup_info['ksp_rtol'] = ''
        setup_info['ksp_atol'] = ''
    else:
        setup_info['ksp_rtol'] = str(solver_params['ksp_rtol'])
        setup_info['ksp_atol'] = str(solver_params['ksp_atol'])

    if method == 'nonlocal':
        fmm_order = get_fmm_order(kappa, mesh_h)
        setup_info['FMM Order'] = str(fmm_order)
        kwargs['FMM Order'] = fmm_order
    else:
        setup_info['FMM Order'] = ''

    # Add gamma/beta to setup_info if there, else make sure
    # it's recorded as absent in special_key
    for special_key in ['gamma', 'beta']:
        if special_key in solver_params:
            setup_info[special_key] = solver_params[special_key]
        else:
            setup_info[special_key] = ''

    key = frozenset(setup_info.items())
    if key in cache and use_cache:
        return None

    trial = {
        'mesh': mesh,
        'degree': degree,
        'true_sol_expr': get_true_sol_expr(SpatialCoordinate(mesh), kappa)
    }

    # {{{ Solve problem and evaluate error
    output = {}

    true_sol, comp_sol, snes_or_ksp = \
        run_method.run_method(trial, method, kappa,
                              comp_sol_name=method + " Computed Solution", **kwargs)

    if isinstance(snes_or_ksp, PETSc.SNES):
        ksp = snes_or_ksp.getKSP()
    elif isinstance(snes_or_ksp, PETSc.KSP):
        ksp = snes_or_ksp
    else:
        raise ValueError("snes_or_ksp must be of type PETSc.SNES or"
                         " PETSc.KSP")

    l2_err = norms.l2_norm(true_sol - comp_sol, region=inner_region)
    h1_err = norms.h1_norm(true_sol - comp_sol, region=inner_region)

    # }}}

    # Store err in output and return

    output['L2 Error'] = l2_err
    output['H1 Error'] = h1_err

    ndofs = true_sol.dat.data.shape[0]
    output['ndofs'] = str(ndofs)
    if solver_params['ksp_type'] != 'preonly':
        output['Iteration Number'] = ksp.getIterationNumber()
    output['Residual Norm'] = ksp.getResidualNorm()
    output['Converged Reason'] = KSPReasons[ksp.getConvergedReason()]

    if solver_params['ksp_type'] == 'gmres':
        emin, emax = ksp.computeExtremeSingularValues()
        output['Min Extreme Singular Value'] = emin
        output['Max Extreme Singular Value'] = emax

    if visualize:
        plot(comp_sol)
        plot(true_sol)
        plt.show()

    if print_trials:
        for name, val in sorted(key):
            if val != '':
                print('{0: <9}: {1}'.format(name, val))
        for name, val in sorted(output.items()):
            print('{0: <18}: {1}'.format(name, val))

    return key, output
                                str(solver_params[new_special_key])

                # Gets computed solution, prints and caches
                key = frozenset(setup_info.items())

                new_result = not use_cache or key not in cache
                if new_result:
                    # Build mesh if not done so already
                    if mesh is None:
                        logger.info(
                            "Reading Mesh %s with element size %s " +
                            " and mesh order %s...", mesh_file_name, cell_size,
                            order)
                        # read in using open-cascade with 0 refinements, this allows
                        # for order 2 meshes
                        mesh = Mesh(join('meshes/', mesh_file_name))
                        if order == 2:
                            if mesh_name not in [
                                    'circle_in_square', 'ball_in_cube',
                                    'circle_in_square_no_pml'
                            ]:
                                raise NotImplementedError(
                                    "2nd order mesh only avaiilbale" +
                                    " for circle_in_square, circle_in_square_no_pml, or ball_in_cube. "
                                    + " Not available for '%s'" % mesh_name)
                            mesh = to_2nd_order(mesh, inner_bdy_id,
                                                mesh_options['radius'])
                        logger.info("Mesh read in")

                        if visualize:
                            from firedrake import triplot
Esempio n. 11
0
                        if options_prefix[-1] != '_':
                            options_prefix += '_'
                        new_special_key = options_prefix + special_key
                        # FIXME: CHECK FROM COMMAND LINE
                        if new_special_key in solver_params:
                            setup_info[special_key] = str(
                                solver_params[new_special_key])

                # Gets computed solution, prints and caches
                key = frozenset(setup_info.items())

                if not use_cache or key not in cache:
                    # {{{  Read in mesh if haven't already
                    if mesh is None:
                        print("\nReading Mesh...")
                        mesh = Mesh(mesh_name)
                        if use_2nd_order:
                            mesh = to_2nd_order(mesh,
                                                circle_bdy_id=inner_bdy_id)
                        spatial_coord = SpatialCoordinate(mesh)
                        trial['mesh'] = mesh
                        print("Mesh Read in.\n")

                    if true_sol_expr is None:
                        true_sol_expr = get_true_sol_expr(spatial_coord)
                        trial['true_sol_expr'] = true_sol_expr

                    # }}}

                    kwargs = method_to_kwargs[method]
                    true_sol, comp_sol, snes_or_ksp = run_method.run_method(
Esempio n. 12
0
    N = mesh.num_vertices()

    ground_truth = np.zeros((N))
    period = 2 * np.pi / 0.3 * 2
    for i in range(N):
        ground_truth[i] = 2 * np.sin(geodesics.get(i) * period + 0.3)

    return ground_truth


if __name__ == '__main__':
    parser = argument_parser()
    args = parser.parse_args()

    mesh = Mesh('resources/meshes/dragon_connected.msh', dim=3)
    num_eigenpairs = args.num_eigenpairs

    print('Constructing ground truth. It may take a while')
    ground_truth = construct_ground_truth(mesh)

    mayavi_installed = False
    if args.mayavi:
        try:
            import manifold_matern.plotting
            mayavi_installed = True
        except ImportError:
            import warnings
            warnings.warn(
                'Mayavi does not seem to be installed.\n'
                'No mayavi-based plotting will occur.', RuntimeWarning)
Esempio n. 13
0
    if mesh_dim == 3:
        x, y, z = spatial_coord
        norm = sqrt(x**2 + y**2 + z**2)
        return Constant(1j / (4 * pi)) / norm * exp(1j * wave_number * norm)

    elif mesh_dim == 2:
        x, y = spatial_coord
        return Constant(1j / 4) * hankel_function(
            wave_number * sqrt(x**2 + y**2), n=80)
    raise ValueError("Only meshes of dimension 2, 3 supported")


# Get the mesh and appropriate boundary tags
mesh_file_name = 'meshes/circle_in_square/max0%25.msh'
h = mesh_file_name[mesh_file_name.find('%') - 1:mesh_file_name.find('.')]
mesh = Mesh(mesh_file_name)
if mesh.geometric_dimension() == 2:
    scatterer_bdy_id = 1
    outer_bdy_id = 2
else:
    scatterer_bdy_id = 1
    outer_bdy_id = 3

# build fspace and bilinear forms
fspace = FunctionSpace(mesh, 'CG', 1)

u = TrialFunction(fspace)
v = TestFunction(fspace)

wave_number = 0.1  # one of [0.1, 1.0, 5.0, 10.0]
true_sol = get_true_sol_expr(SpatialCoordinate(mesh), wave_number)