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
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
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
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
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
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)
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
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)
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()
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
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
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.")
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
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;
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)
""" 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):
# 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)
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)
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)
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)
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)
# 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)
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))
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) )
def dist(k): """ distance from the position at (t+k) to the boundary of c""" return c.distance(Point(yn(t + k)[0:dim]))
# 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)
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,
def build_mesh(): mesh = RectangleMesh(p0=Point(-0.5, -0.5), p1=Point(0.5, 0.5), nx=nx, ny=nx) return mesh