예제 #1
0
 def inside(self, x, on_boundary):
     tol = 1E-14
     point = Point(x[0], x[1])
     if on_boundary and point.distance(midpoint)**2 - radius**2 < tol:
         return True
     else:
         return False
예제 #2
0
def _find_cell(g, q, p):
    """Find the cell q should be in.

    If q is in the interior of a cell c, then return c. If q is in the
    intersection of several cells, return the one that is in the direction of
    q.
    """
    mesh = g.function_space().mesh()
    csi = mesh.bounding_box_tree().compute_entity_collisions(Point(q))
    cs = [Cell(mesh, i) for i in csi]
    cs = [c for c in cs if c.distance(Point(q)) == 0]
    if len(cs) == 0:
        raise RuntimeError('Point {} is not inside any mesh cell. This should '
                           'not be possible.'.format(q))
    elif len(cs) == 1:
        # all good
        return cs[0]
    else:
        # close to faces of lower dimension leading to multiple collisions
        # choose the best cell using p
        def try_step(c):
            ginv = inv(_eval_metric(g, c, q))
            dq = ginv.dot(p)
            qn = q + dq * DOLFIN_SQRT_EPS * 10
            return c.distance(Point(qn))

        return min(cs, key=try_step)
def generate_rectangle_mesh(mesh_resolution):
    # Generate domain and mesh
    xmin, xmax = -2, 2
    ymin, ymax = -2, 2
    mesh = generate_mesh(Rectangle(Point(xmin, ymin), Point(xmax, ymax)),
                         mesh_resolution)
    return mesh
예제 #4
0
def build_wave_breaker(start_loc, length, n_fins, l, d, rod_start, rod_stop):
    """
    Build the wave breaker

    Input:
        start_loc - starting location
        length - length of breaker
        n_fins - number of fins
        l - length of fin wing
        d - width of fin wing
        rod_start - starting position for support rod
        rot_stop - stopping position for support rod
    Output:
        breaker - domain of wave breaker
    """

    # build support rod
    rod_pt1 = Point(rod_start)
    rod_pt2 = Point(rod_stop)

    # get fins
    fins = fin_sequence(start_loc, length, n_fins, l, d)

    # assemble together
    domain = Rectangle(rod_pt1, rod_pt2)

    for fin in fins:
        # += may have odd behavior
        domain = domain + fin

    return domain
예제 #5
0
파일: initialise.py 프로젝트: vdda/flem
def initialise(dem, bounds, res):
    """
    Function to initialise the model space

    :param dem: 0 = no input DEM; 1 = input DEM
    :param bounds: west, south, east, north - if no DEM [0, 0, lx, ly]; if DEM [west, south, east, north]
    :param res: model resolution along the y-axis.
    :return model_space, u_n, mesh, V, bc:
    """

    if dem == 0:
        lx = bounds[1]
        ly = bounds[3]

        # Create mesh and define function space
        domain = Rectangle(Point(0, 0), Point(lx / ly, ly / ly))
        mesh = generate_mesh(domain, res)

        V = FunctionSpace(mesh, 'P', 1)

        # Define initial value
        u_D = Constant(0)
        eps = 10 / ly
        u_n = interpolate(u_D, V)
        u_n.vector().set_local(u_n.vector().get_local() +
                               eps * np.random.random(u_n.vector().size()))

    if dem == 1:
        u_n, lx, ly, mesh, V = read_dem(bounds, res)

    # boundary conditions

    class East(SubDomain):
        def inside(self, x, on_boundary):
            return near(x[0], lx / ly)

    class West(SubDomain):
        def inside(self, x, on_boundary):
            return near(x[0], 0.0)

    class North(SubDomain):
        def inside(self, x, on_boundary):
            return near(x[1], ly / ly)

    class South(SubDomain):
        def inside(self, x, on_boundary):
            return near(x[1], 0.0)

    # Should make this into an option!

    bc = [DirichletBC(V, u_n, West()), DirichletBC(V, u_n, East())]

    # def boundary(x, on_boundary):
    #   return on_boundary
    # bc = DirichletBC(V, u_n, boundary)

    model_space = [lx, ly, res]

    return model_space, u_n, mesh, V, bc
예제 #6
0
def gen_rect_mesh(nx, ny, xmin, xmax, ymin, ymax, outfile, direction='right'):

    mesh = RectangleMesh(MPI.COMM_SELF,
                         Point(xmin, ymin),
                         Point(xmax, ymax),
                         nx, ny, direction)

    File(MPI.COMM_SELF, outfile) << mesh
예제 #7
0
파일: meshing.py 프로젝트: JacobDowns/cslvr
    def eliminate_intersections(self, dist=10):
        """
    Eliminate intersecting boundary elements. <dist> is an integer specifiying
    how far forward to look to eliminate intersections.  If any intersections
    are found, this method is called recursively until none are found.
    """
        s = "::: eliminating intersections :::"
        print_text(s, self.color)

        class Point:
            def __init__(self, x, y):
                self.x = x
                self.y = y

        def ccw(A, B, C):
            return (C.y - A.y) * (B.x - A.x) > (B.y - A.y) * (C.x - A.x)

        def intersect(A, B, C, D):
            return ccw(A, C, D) != ccw(B, C, D) and ccw(A, B, C) != ccw(
                A, B, D)

        lc = self.longest_cont

        flag = ones(len(lc))
        intr = False
        for ii in range(len(lc) - 1):

            A = Point(*lc[ii])
            B = Point(*lc[ii + 1])

            for jj in range(ii, min(ii + dist, len(lc) - 1)):

                C = Point(*lc[jj])
                D = Point(*lc[jj + 1])

                if intersect(A, B, C, D) and ii != jj + 1 and ii + 1 != jj:
                    s = "  - intersection found between node %i and %i"
                    print_text(s % (ii + 1, jj), 'red')
                    flag[ii + 1] = 0
                    flag[jj] = 0
                    intr = True

        counter = 0
        new_cont = zeros((sum(flag), 2))
        for ii, fl in enumerate(flag):
            if fl:
                new_cont[counter, :] = lc[ii, :]
                counter += 1

        self.longest_cont = new_cont
        s = "::: eliminated %i nodes :::"
        print_text(s % sum(flag == 0), self.color)
        # call again if required :
        if intr:
            self.eliminate_intersections(dist)
예제 #8
0
파일: read_dem.py 프로젝트: vdda/flem
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
예제 #9
0
def reference_data(H, L, mesh_type, mesh_size, padding=0.07):
    g = kepler_jacobi_metric(c=H)
    (q0, p0, _, _, (c, a, b), _, _) = exact_kepler(H, L)
    if mesh_type == 'uniform':
        # uniform rectangular mesh containing the orbit
        mesh = RectangleMesh(Point(c[0] - a - padding, c[1] - b - padding),
                             Point(c[0] + a + padding, c[1] + b + padding),
                             mesh_size, mesh_size)
    else:
        # unstructured annular mesh containing the orbit
        ell_out = Ellipse(Point(c), a + padding, b + padding)
        ell_in = Ellipse(Point(c), a - padding, b - padding)
        domain = ell_out - ell_in
        mesh = generate_mesh(domain, mesh_size)
    return (q0, p0, g, mesh)
예제 #10
0
파일: meshing.py 프로젝트: JacobDowns/cslvr
    def extrude_mesh(self, l, z_offset):
        # accepts the number of layers and the length of extrusion

        mesh = self.mesh

        # Extrude vertices
        all_coords = []
        for i in linspace(0, z_offset, l):
            all_coords.append(
                hstack((mesh.coordinates(), i * ones((self.n_v2, 1)))))
        self.global_vertices = vstack(all_coords)

        # Extrude cells (tris to tetrahedra)
        for i in range(l - 1):
            for c in self.mesh.cells():
                # Make a prism out of 2 stacked triangles
                vertices = hstack((c + i * self.n_v2, c + (i + 1) * self.n_v2))

                # Determine prism orientation
                smallest_vertex_index = argmin(vertices)

                # Map to I-ordering of Dompierre et al.
                mapping = self.indirection_table[smallest_vertex_index]

                # Determine which subdivision scheme to use.
                if min(vertices[mapping][[1, 5]]) < min(
                        vertices[mapping][[2, 4]]):
                    local_tets = vstack((vertices[mapping][[0,1,2,5]],\
                                         vertices[mapping][[0,1,5,4]],\
                                         vertices[mapping][[0,4,5,3]]))
                else:
                    local_tets = vstack((vertices[mapping][[0,1,2,4]],\
                                         vertices[mapping][[0,4,2,5]],\
                                         vertices[mapping][[0,4,5,3]]))
                # Concatenate local tet to cell array
                self.global_tets = vstack((self.global_tets, local_tets))

        # Eliminate phantom initialization tet
        self.global_tets = self.global_tets[1:, :]

        # Query number of vertices and tets in new mesh
        self.n_verts = self.global_vertices.shape[0]
        self.n_tets = self.global_tets.shape[0]

        # Initialize new dolfin mesh of dimension 3
        self.new_mesh = Mesh()
        m = MeshEditor()
        m.open(self.new_mesh, 3, 3)
        m.init_vertices(self.n_verts, self.n_verts)
        m.init_cells(self.n_tets, self.n_tets)

        # Copy vertex data into new mesh
        for i, v in enumerate(self.global_vertices):
            m.add_vertex(i, Point(*v))

        # Copy cell data into new mesh
        for j, c in enumerate(self.global_tets):
            m.add_cell(j, *c)

        m.close()
예제 #11
0
def build_fin(loc, l, d):
    """
    Build a fin as a domain to be meshed

    Input: 
        loc - location of outer most corner coordinates [x, y]
        l - length of fin
        d - thickness of fin
    Output:
        fin - fin domain
    """

    # define the fin as a polygon
    angle = np.radians(45)
    # vertices, proceeding counter-clockwise
    pts = np.zeros((2, 6))
    # leave pts[:, 0] alone
    pts[:, 1] = [l * np.cos(angle), l * np.sin(angle)]
    pts[:, 2] = [(l + d) * np.cos(angle), (l - d) * np.sin(angle)]
    pts[:, 3] = [d / np.cos(angle), 0]

    pts[0, 4] = pts[0, 2]  # flip point along x-axis
    pts[1, 4] = -pts[1, 2]
    pts[0, 5] = pts[0, 1]
    pts[1, 5] = -pts[1, 1]

    # shift over to loc
    # convert to mshr Points
    points = []
    for j in range(6):
        points.append(Point(pts[:, -j] + loc))

    # build polygon
    poly = Polygon(points)
    return poly
예제 #12
0
def get_geometry(domain_part):
    nx = ny = 9

    if domain_part is DomainPart.LEFT:
        p0 = Point(x_left, y_bottom)
        p1 = Point(x_coupling, y_top)
    elif domain_part is DomainPart.RIGHT:
        p0 = Point(x_coupling, y_bottom)
        p1 = Point(x_right, y_top)
    else:
        raise Exception("invalid domain_part: {}".format(domain_part))

    mesh = RectangleMesh(p0, p1, nx, ny, diagonal="left")
    coupling_boundary = StraightBoundary()
    remaining_boundary = ExcludeStraightBoundary()

    return mesh, coupling_boundary, remaining_boundary
예제 #13
0
def box_mesh(width=1.0, dim=1, nelements=8):
    """Make a rectangular mesh of dimension 1-3

    Parameters:
    width=1.0: width (also length and height) of space
    dim=1: 1, 2, or 3, dimension of space
    nelements=8: division of space into elements
    """
    if dim == 1:
        return IntervalMesh(nelements, 0.0, width)
    elif dim == 2:
        return RectangleMesh(Point(np.array([0.0, 0.0], dtype=float)),
                             Point(np.array([width, width], dtype=float)),
                             nelements, nelements)
    elif dim == 3:
        return BoxMesh(Point(np.array([0.0, 0.0, 0.0], dtype=float)),
                       Point(np.array([width, width, width], dtype=float)),
                       nelements, nelements, nelements)
    else:
        raise KSDGException("Only dimensions 1, 2, 3 supported.")
예제 #14
0
def get_geometry(domain_part):
    nx = 5
    ny = 10
    low_resolution = 5
    high_resolution = 5
    n_vertices = 20

    if domain_part is DomainPart.LEFT:
        nx = nx * 3
    elif domain_part is DomainPart.RIGHT:
        ny = ny * 2
    elif domain_part is DomainPart.CIRCULAR:
        n_vertices = n_vertices
    elif domain_part is DomainPart.RECTANGLE:
        n_vertices = n_vertices
    else:
        raise Exception("invalid domain_part: {}".format(domain_part))

    if domain_part is DomainPart.LEFT or domain_part is DomainPart.RIGHT:
        if domain_part is DomainPart.LEFT:
            p0 = Point(x_left, y_bottom)
            p1 = Point(x_coupling, y_top)
        elif domain_part is DomainPart.RIGHT:
            p0 = Point(x_coupling, y_bottom)
            p1 = Point(x_right, y_top)
        else:
            raise Exception("invalid control flow!")
        mesh = RectangleMesh(p0, p1, nx, ny)
        coupling_boundary = StraightBoundary()
        remaining_boundary = ExcludeStraightBoundary()

    elif domain_part is DomainPart.CIRCULAR or domain_part is DomainPart.RECTANGLE:
        p0 = Point(x_left, y_bottom)
        p1 = Point(x_right, y_top)
        whole_domain = mshr.Rectangle(p0, p1)
        if domain_part is DomainPart.CIRCULAR:
            circular_domain = mshr.Circle(midpoint, radius, n_vertices)
            mesh = mshr.generate_mesh(circular_domain, high_resolution, "cgal")
        elif domain_part is DomainPart.RECTANGLE:
            circular_domain = mshr.Circle(midpoint, radius, n_vertices)
            mesh = mshr.generate_mesh(whole_domain - circular_domain,
                                      low_resolution, "cgal")
        else:
            raise Exception("invalid control flow!")
        coupling_boundary = CircleBoundary()
        remaining_boundary = ExcludeCircleBoundary()

    else:
        raise Exception("invalid control flow!")

    return mesh, coupling_boundary, remaining_boundary
예제 #15
0
from fenics import File

if __name__ == '__main__':
    fenics.set_log_level(30)  # only display warnings or errors

    # here we solve a heat diffusion equation over time:
    # we use a finite difference scheme in time (backward Euler) and a variational approach in space
    # namely we iterate over (small) timesteps, each time solving a Poisson equation via finite elements

    T = 2.0  # final time
    num_steps = 50  # number of time steps
    dt = T / num_steps  # time step size

    # Create mesh and define function space
    nx = ny = 30
    mesh = RectangleMesh(Point(-2, -2), Point(2, 2), nx, ny)
    V = FunctionSpace(mesh, 'P', 1)

    # Define boundary condition
    def boundary(x, on_boundary):
        return on_boundary

    bc = DirichletBC(V, Constant(0), boundary)  # null Dirichlet conditions

    # Define initial value
    u_0 = Expression('exp(-a*pow(x[0], 2) - a*pow(x[1], 2))', degree=2, a=5)
    # the initial condition here is a "gaussian hill" of parameter alpha centered in the origin
    u_n = interpolate(u_0, V)
    # since we will be using iteratively the solution from the previous time step to compute the one
    # at the current time step, we need to convert the initial datum's expression to a Function object:
    # there are two ways to do this: either via the project() method or the interpolate() method;
예제 #16
0
    solve(a == L, flux)


# Create mesh and define function space
nx = 100
ny = 25
nz = 1

fenics_dt = 0.01  # time step size
dt_out = 0.2  # interval for writing VTK files
y_top = 0
y_bottom = y_top - .25
x_left = 0
x_right = x_left + 1

p0 = Point(x_left, y_bottom, 0)
p1 = Point(x_right, y_top, 1)

mesh = RectangleMesh(p0, p1, nx, ny)
V = FunctionSpace(mesh, 'P', 1)
V_g = VectorFunctionSpace(mesh, 'P', 1)

alpha = 1  # m^2/s, https://en.wikipedia.org/wiki/Thermal_diffusivity
k = 100  # kg * m / s^3 / K, https://en.wikipedia.org/wiki/Thermal_conductivity

# Define boundary condition
u_D = Constant('310')
u_D_function = interpolate(u_D, V)
# We will only exchange flux in y direction on coupling interface. No initialization necessary.
V_flux_y = V_g.sub(1)
예제 #17
0
"""
Problem setup for HT fenics-fenics tutorial
"""

from fenics import SubDomain, Point, RectangleMesh, near, Function, VectorFunctionSpace, Expression
from my_enums import DomainPart, ProblemType
import mshr
import numpy as np

y_bottom, y_top = 0, 1
x_left, x_right = 0, 2
x_coupling = 1.5  # x coordinate of coupling interface
radius = 0.2
midpoint = Point(0.5, 0.5)


class ExcludeStraightBoundary(SubDomain):
    def get_user_input_args(self, args):
        self._interface = args.interface

    def inside(self, x, on_boundary):
        tol = 1E-14
        if on_boundary and not near(x[0], x_coupling, tol) or near(
                x[1], y_top, tol) or near(x[1], y_bottom, tol):
            return True
        else:
            return False


class ExcludeCircleBoundary(SubDomain):
    def inside(self, x, on_boundary):
예제 #18
0
# Geometry and material properties
dim = 2  # number of dimensions
H = 1
W = 0.1
rho = 3000
E = 4000000
nu = 0.3

mu = Constant(E / (2.0 * (1.0 + nu)))

lambda_ = Constant(E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu)))

# create Mesh
n_x_Direction = 4
n_y_Direction = 26
mesh = RectangleMesh(Point(-W / 2, 0), Point(W / 2, H), n_x_Direction,
                     n_y_Direction)

h = Constant(H / n_y_Direction)

# create Function Space
V = VectorFunctionSpace(mesh, 'P', 2)

# BCs
tol = 1E-14

# Trial and Test Functions
du = TrialFunction(V)
v = TestFunction(V)

u_np1 = Function(V)
예제 #19
0
from cslvr    import *
from fenics   import Point, BoxMesh, Expression, sqrt, pi

alpha = 0.1 * pi / 180 
L     = 10000

p1    = Point(0.0, 0.0, 0.0)
p2    = Point(L,   L,   1)
mesh  = BoxMesh(p1, p2, 15, 15, 10)

model = D3Model(mesh, out_dir = './ISMIP_HOM_C_results/', use_periodic = True)

surface = Expression('- x[0] * tan(alpha)', alpha=alpha, 
                     element=model.Q.ufl_element())
bed     = Expression('- x[0] * tan(alpha) - 1000.0', alpha=alpha, 
                     element=model.Q.ufl_element())
beta    = Expression('1000 + 1000 * sin(2*pi*x[0]/L) * sin(2*pi*x[1]/L)',
                     alpha=alpha, L=L, element=model.Q.ufl_element())

model.calculate_boundaries()
model.deform_mesh_to_geometry(surface, bed)

model.init_mask(1.0)  # all grounded
model.init_beta(beta)
model.init_A(1e-16)
model.init_E(1.0)

#mom = MomentumBP(model)
#mom = MomentumDukowiczBP(model)
mom = MomentumDukowiczStokesReduced(model)
#mom = MomentumDukowiczBrinkerhoffStokes(model)
예제 #20
0
    bilinear_form_fluid_adjoint,
    functional_fluid_adjoint,
    bilinear_form_solid_adjoint,
    functional_solid_adjoint,
)
from relaxation import relaxation
from shooting import shooting
from compute_residuals import compute_residuals
from refine import refine

parameters["allow_extrapolation"] = True
param = Parameters()

# Create meshes
mesh_f = RectangleMesh(
    Point(0.0, 0.0),
    Point(4.0, 1.0),
    param.NUMBER_ELEMENTS_HORIZONTAL,
    param.NUMBER_ELEMENTS_VERTICAL,
    diagonal="right",
)
mesh_s = RectangleMesh(
    Point(0.0, -1.0),
    Point(4.0, 0.0),
    param.NUMBER_ELEMENTS_HORIZONTAL,
    param.NUMBER_ELEMENTS_VERTICAL,
    diagonal="left",
)
boundary_mesh = BoundaryMesh(mesh_f, "exterior")
inner_boundary = Inner_boundary()
mesh_i = SubMesh(boundary_mesh, inner_boundary)
    def __init__(
            self, eval_times, n=10, lx=1., ly=.1, lz=.1,
            f=(0.0, 0.0, -50.), time=1., timestep=.1,
            tol=1e-5, max_iter=30, rel_tol=1e-10, param_remapper=None):
        """Parameters
        ----------
        eval_times: numpy.ndarray
            Times at which evaluation (interpolation) of the solution is required.
        n: int, default 10
            Dimension of the grid along the smallest side of the beam
            (the grid size along all other dimensions will be scaled proportionally.
        lx: float, default 1.
            Length of the beam along the x axis.
        ly: float, default .1
            Length of the beam along the y axis.
        lz: float, default .1
            Length of the beam along the z axis.
        f: tuple or numpy.ndarray, default (0.0, 0.0, -50.)
            Force per unit volume acting on the beam.
        time: float, default 1.
            Final time of the simulation.
        timestep: float, default 1.
            Time discretization step to solve the problem.
        tol: float, default 1e-5
            Tolerance parameter to ensure the last time step is included in the solution.
        max_iter: int, default 30
            Maximum iterations for the SNES solver.
        rel_tol: int,
            Relative tolerance for the convergence of the SNES solver.
        param_remapper: object, default None
            Either None (no remapping of the parameters), or a function remapping
            the parameter of the problem (Young's modulus) to values suitable for the
            definition of the solution.
        """
        # solver parameters
        self.solver = CountIt(solve)
        self.solver_parameters = {
            'nonlinear_solver': 'snes',
            'snes_solver': {
                'linear_solver': 'lu',
                'line_search': 'basic',
                'maximum_iterations': max_iter,
                'relative_tolerance': rel_tol,
                'report': False,
                'error_on_nonconvergence': False}}
        self.param_remapper = param_remapper

        # mesh creation
        self.n = n
        self.lx = lx
        self.ly = ly
        self.lz = lz

        min_len = min(lx, ly, lz)
        mesh_dims = (int(n * lx / min_len), int(n * ly / min_len), int(n * lz / min_len))
        self.mesh = BoxMesh(Point(0, 0, 0), Point(lx, ly, lz), *mesh_dims)
        self.V = VectorFunctionSpace(self.mesh, 'Lagrange', 1)

        # boundary conditions
        self.left = CompiledSubDomain('near(x[0], side) && on_boundary', side=0.0)
        self.right = CompiledSubDomain('near(x[0], side) && on_boundary', side=lx)
        self.top = CompiledSubDomain('near(x[2], side) && on_boundary', side=lz)

        self.boundaries = MeshFunction('size_t', self.mesh, self.mesh.topology().dim() - 1, 0)
        self.boundaries.set_all(0)
        self.left.mark(self.boundaries, 1)
        self.right.mark(self.boundaries, 2)
        self.top.mark(self.boundaries, 3)

        self.bcs1 = DirichletBC(self.V, Constant([0.0, 0.0, 0.0]), self.boundaries, 1)
        self.bcs2 = DirichletBC(self.V, Constant([0.0, 0.0, 0.0]), self.boundaries, 2)
        self.bcs = [self.bcs1, self.bcs2]

        # surface force
        self.f = Constant(f)
        self.ds = Measure('ds', domain=self.mesh, subdomain_data=self.boundaries)

        # evaluation times
        self.eval_times = eval_times
        self.dt = timestep
        self.T = time + tol
        self.times = np.arange(self.dt, self.T, self.dt)
        self.time = Expression('t', t=self.dt, degree=0)
예제 #22
0
def exponential_map(g, t0, q0, p0, h, T, verbose=True):
    """ Compute the generalized exponential map on a Regge metric

    Input
         g     a Regge metric
         t0    starting time
         q0    initial position
         p0    initial momentum
         h     ODE solver step size
         T     stopping time

    Output
         ts    time steps
         qh    position as a function of t
         ph    momentum as a function of t
    """
    # initialization
    dim = g.ufl_shape[0]
    mesh = g.function_space().mesh()
    step = _incell_geodesic_step_maker(g)  # ODE solver
    c = _find_cell(g, q0, p0)  # find the starting cell

    # info
    print('Geodesic computation...')
    print(' Initial position: {}'.format(q0))
    print(' Initial momentum: {}'.format(p0))
    print(' Step size: {}. Maximum time: {}'.format(h, T))

    # main loop
    t = t0
    y = concatenate([q0, p0])
    ts = [t0]
    ys = [lambda t: concatenate([q0, p0])]
    while True:
        if verbose:
            print(' progress: {:0.2f}%.'.format(abs(t / T * 100.0)), end='\r')

        # Step 1: solve smooth geodesic equation inside a cell
        while True:
            yn = step(c, t, y, h)
            qn = yn(t + h)[0:dim]
            if c.distance(Point(qn)) > DOLFIN_SQRT_EPS:
                # going out of the cell, break
                break
            # update
            t = t + h
            ts.append(t)
            y = yn
            ys.append(yn)

        # Step 2: truncate the last step to hit the boundary facet
        def dist(k):
            """ distance from the position at (t+k) to the boundary of c"""
            return c.distance(Point(yn(t + k)[0:dim]))

        # bisect to find k such that the position at (t+k)
        # (1) is within DOLFIN_SQRT_EPS of the boundary
        # (2) is outside of the current cell
        a = 0
        k = h
        min_dist = dist(k)
        while min_dist > DOLFIN_SQRT_EPS or abs(a - k) < DOLFIN_EPS_LARGE:
            x = (a + k) / 2.0
            fx = dist(x)
            if fx > 0:
                k = x
                min_dist = fx
            else:
                a = x
        # update (y is updated in the next rotation step)
        t = t + k
        ts.append(t)
        ys.append(yn)

        # Step 3: stop if maximum time T is reached
        if ts[-1] > T:
            break

        # Step 4: rotate p and cross to the next cell if it exists
        # find the facets closest to the end point
        [qn, pn] = split(yn(t), 2)
        f = min(facets(c), key=lambda f: f.distance(Point(qn)))
        # find adjacent cells to the chosen facet
        ncs = f.entities(c.dim())
        if len(ncs) == 1:  # hit domain boundary
            print('Boundary reached at t={}. Terminate.'.format(t))
            break
        else:  # go to the opposite cell
            # find the next cell
            nc = Cell(mesh, list(set(ncs) - {c.index()})[0])
            # rotate p
            pn = _facet_crossing(pn, g, qn, f, c, nc)
            # update
            y = concatenate([qn, pn])
            c = nc

        # Step 5: check if the new starting point is in c.
        # This failure can happen when the curve goes near a face of low
        # dimension. The small over-crossing (k computed is always greater than
        # the exact value) might end up in another cell. In this case, find the
        # correct cell and restart. This commits an error proportion to
        # DOLFIN_SQRT_EPS in the position without changing the momentum.
        if c.distance(Point(qn)) > 0:
            print(' Warning: the geodesic came near a face of low dimension '
                  'at time {}.'.format(t))
            c = _find_cell(g, qn, pn)

    def solh(t):
        """ The final global piecewise smooth interpolant. """
        # deal with the case when t is just a single number
        if isscalar(t):
            t = array([t])
        # assume t is sorted

        tmp = zeros((len(t), 2 * dim))
        i = 0
        for j in range(len(t)):
            # find the smallest i such that ts[i]>t[j]
            while (i < len(ys)) and (ts[i] < t[j]):
                i = i + 1
            # t[j] should be evaluted using yn[i]
            if i < len(ys):
                tmp[j] = ys[i](t[j])
            else:
                tmp[j] = nan
        return (tmp[:, 0:dim], tmp[:, dim:])  # (q, p) split

    return (array(ts), solh)
예제 #23
0
from fenics import Point
import os

#===============================================================================
# model properties :
out_dir = 'data/'  # output directory

# create the output directory if it does not exist :
d = os.path.dirname(out_dir)
if not os.path.exists(d): os.makedirs(d)

# create a material :
r_max = 0.15  # disk radius          [m]
res = 100  # disk mesh resolution

# upper-right disk :
domain1 = Circle(Point(0.66, 0.66), r_max)
mesh1 = generate_mesh(domain1, res)
X1, V1 = calculate_mesh_midpoints_and_volumes(mesh1)

# lower-left disk :
domain2 = Circle(Point(0.34, 0.34), r_max)
mesh2 = generate_mesh(domain2, res)
X2, V2 = calculate_mesh_midpoints_and_volumes(mesh2)

# load the data created by the "gen_data.py" script :
X1 = np.savetxt(out_dir + 'X1.txt', X1)
X2 = np.savetxt(out_dir + 'X2.txt', X2)
V1 = np.savetxt(out_dir + 'V1.txt', V1)
V2 = np.savetxt(out_dir + 'V2.txt', V2)
예제 #24
0

# Numerical properties
tol = 1E-14

# Beam material properties
rho = 1000  # density
E = 5600000.0  # Young's modulus
nu = 0.4  # Poisson's ratio
lambda_ = Constant(E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu)))  # first Lame constant
mu = Constant(E / (2.0 * (1.0 + nu)))  # second Lame constant

# create Mesh
n_x_Direction = 20  # DoFs in x direction
n_y_Direction = 4  # DoFs in y direction
mesh = RectangleMesh(Point(x_left, y_bottom), Point(x_right, y_top), n_x_Direction, n_y_Direction)

# create Function Space
V = VectorFunctionSpace(mesh, 'P', 2)

# Trial and Test Functions
du = TrialFunction(V)
v = TestFunction(V)

# displacement fields
u_np1 = Function(V)
saved_u_old = Function(V)

# function known from previous timestep
u_n = Function(V)
v_n = Function(V)
예제 #25
0
 def try_step(c):
     ginv = inv(_eval_metric(g, c, q))
     dq = ginv.dot(p)
     qn = q + dq * DOLFIN_SQRT_EPS * 10
     return c.distance(Point(qn))
예제 #26
0
from fenics import Point

# Topological dimension
nDim = 3

# Points used for face elements
points = (
	Point(0.0,0.0,0.0),
	Point(1.0,0.0,0.0),
	Point(0.0,1.0,0.0),
	Point(0.0,0.0,1.0)
)

# Number of faces elements
nFaces = 4

# Face elements
faces = (
	(1,2,3),
	(0,2,3),
	(0,1,3),
	(0,1,2)
)
예제 #27
0
 def dist(k):
     """ distance from the position at (t+k) to the boundary of c"""
     return c.distance(Point(yn(t + k)[0:dim]))
예제 #28
0
# Numerical properties
tol = 1E-14

# Beam material properties
rho = 1000  # density
E = 5600000.0  # Young's modulus
nu = 0.4  # Poisson's ratio
lambda_ = Constant(E * nu / ((1.0 + nu) *
                             (1.0 - 2.0 * nu)))  # first Lame constant
mu = Constant(E / (2.0 * (1.0 + nu)))  # second Lame constant

# create Mesh
n_x_Direction = 20  # DoFs in x direction
n_y_Direction = 4  # DoFs in y direction
mesh = RectangleMesh(Point(x_left, y_bottom), Point(x_right, y_top),
                     n_x_Direction, n_y_Direction)

# create Function Space
V = VectorFunctionSpace(mesh, 'P', 2)

# Trial and Test Functions
du = TrialFunction(V)
v = TestFunction(V)

# displacement fields
u_np1 = Function(V)
saved_u_old = Function(V)

# function known from previous timestep
u_n = Function(V)
예제 #29
0
    error_tol = 10**-2  # error increases. If we use subcycling, we cannot assume that we still get the exact solution.
    # TODO Using waveform relaxation, we should be able to obtain the exact solution here, as well.
elif subcycle is Subcyling.NONMATCHING:
    fenics_dt = .03  # time step size
    error_tol = 10**-1  # error increases. If we use subcycling, we cannot assume that we still get the exact solution.
    # TODO Using waveform relaxation, we should be able to obtain the exact solution here, as well.

alpha = 3  # parameter alpha
beta = 1.3  # parameter beta
gamma = args.gamma  # parameter gamma, dependence of heat flux on time
y_bottom, y_top = 0, 1
x_left, x_right = 0, 2
x_coupling = 1.5  # x coordinate of coupling interface

if domain_part is DomainPart.LEFT:
    p0 = Point(x_left, y_bottom)
    p1 = Point(x_coupling, y_top)
elif domain_part is DomainPart.RIGHT:
    p0 = Point(x_coupling, y_bottom)
    p1 = Point(x_right, y_top)

mesh = RectangleMesh(p0, p1, nx, ny)
V = FunctionSpace(mesh, 'P', 2)

# Define boundary condition
u_D = Expression(
    '1 + gamma*t*x[0]*x[0] + (1-gamma)*x[0]*x[0] + alpha*x[1]*x[1] + beta*t',
    degree=2,
    alpha=alpha,
    beta=beta,
    gamma=gamma,
예제 #30
0
def build_mesh():
    mesh = RectangleMesh(p0=Point(-0.5, -0.5),
                         p1=Point(0.5, 0.5),
                         nx=nx,
                         ny=nx)
    return mesh