def get_bc_parts(mesh, lst): """ Build a size_t function with boundary condition parts. Returns all Robin and Steklov conditions that need to be applied, the shift needed to get a nonnegative function, and the function itself. """ if len(lst) > 0: shift = max(0, -min(e.value for e in lst)) else: return [], [], 0, FacetFunction("size_t", mesh, 0) # values must be shifted by smallest Steklov value since size_t is unsigned fun = FacetFunction("size_t", mesh, shift) for bc in lst: sub = OnBoundary() # overwrite inside function with the one from bc sub.inside = bc.getTest() sub.mark(fun, bc.value + shift) # some conditions may cancel eachother exist = set(np.unique(fun.array())) lst = [e for e in lst if e.value + shift in exist] # separate Robin and Steklov, Dirichlet and Neumann are irrelevant Robin = [e for e in lst if e.value > 1 and e.parValue != 0] Steklov = [e for e in lst if e.value < 0 and e.parValue != 0] return Robin, Steklov, shift, fun
def mark_conditions(mesh, lst): """ Mark all boundary conditions from the list. """ fun = FacetFunction("int", mesh, 0) for bc in lst: sub = OnBoundary() # overwrite inside function with the one from bc sub.inside = bc.getTest() sub.mark(fun, bc.value) return fun.array()
def test_store_mesh(casedir): pp = PostProcessor(dict(casedir=casedir)) from dolfin import (UnitSquareMesh, CellFunction, FacetFunction, AutoSubDomain, Mesh, HDF5File, assemble, Expression, ds, dx) # Store mesh mesh = UnitSquareMesh(6, 6) celldomains = CellFunction("size_t", mesh) celldomains.set_all(0) AutoSubDomain(lambda x: x[0] < 0.5).mark(celldomains, 1) facetdomains = FacetFunction("size_t", mesh) AutoSubDomain(lambda x, on_boundary: x[0] < 0.5 and on_boundary).mark( facetdomains, 1) pp.store_mesh(mesh, celldomains, facetdomains) # Read mesh back mesh2 = Mesh() f = HDF5File(mpi_comm_world(), os.path.join(pp.get_casedir(), "mesh.hdf5"), 'r') f.read(mesh2, "Mesh", False) celldomains2 = CellFunction("size_t", mesh2) f.read(celldomains2, "CellDomains") facetdomains2 = FacetFunction("size_t", mesh2) f.read(facetdomains2, "FacetDomains") e = Expression("1+x[1]", degree=1) dx1 = dx(1, domain=mesh, subdomain_data=celldomains) dx2 = dx(1, domain=mesh2, subdomain_data=celldomains2) C1 = assemble(e * dx1) C2 = assemble(e * dx2) assert abs(C1 - C2) < 1e-10 ds1 = ds(1, domain=mesh, subdomain_data=facetdomains) ds2 = ds(1, domain=mesh2, subdomain_data=facetdomains2) F1 = assemble(e * ds1) F2 = assemble(e * ds2) assert abs(F1 - F2) < 1e-10
def as_pvd(h5_file): '''Store facet and cell function for pvd''' root, ext = os.path.splitext(h5_file) mesh = Mesh() hdf = HDF5File(mesh.mpi_comm(), h5_file, 'r') hdf.read(mesh, '/mesh', False) facet_markers = FacetFunction('size_t', mesh) hdf.read(facet_markers, '/facet_markers') cell_markers = CellFunction('size_t', mesh) hdf.read(cell_markers, '/cell_markers') File(root + 'facets' + '.pvd') << facet_markers File(root + 'volumes' + '.pvd') << cell_markers return True
def derived_bcs(V, original_bcs, u_): new_bcs = [] # Check first if user has declared subdomains subdomain = original_bcs[0].user_sub_domain() if subdomain is None: mesh = V.mesh() ff = FacetFunction("size_t", mesh, 0) for i, bc in enumerate(original_bcs): bc.apply(u_[0].vector()) # Need to initialize bc m = bc.markers() # Get facet indices of boundary ff.array()[m] = i + 1 new_bcs.append(DirichletBC(V, Constant(0), ff, i + 1)) else: for i, bc in enumerate(original_bcs): subdomain = bc.user_sub_domain() new_bcs.append(DirichletBC(V, Constant(0), subdomain)) return new_bcs
def les_setup(u_, mesh, Wale, bcs, CG1Function, nut_krylov_solver, **NS_namespace): """Set up for solving Wale LES model """ DG = FunctionSpace(mesh, "DG", 0) CG1 = FunctionSpace(mesh, "CG", 1) # Compute cell size and put in delta delta = Function(DG) delta.vector().zero() delta.vector().axpy(1.0, assemble(TestFunction(DG)*dx)) # Set up Wale form Gij = grad(u_) Sij = sym(Gij) Skk = tr(Sij) dim = mesh.geometry().dim() Sd = sym(Gij*Gij) - 1./3.*Identity(mesh.geometry().dim())*Skk*Skk nut_form = Wale['Cw']**2 * pow(delta, 2./dim) * pow(inner(Sd, Sd), 1.5) / (Max(pow(inner(Sij, Sij), 2.5) + pow(inner(Sd, Sd), 1.25), 1e-6)) ff = FacetFunction("size_t", mesh, 0) bcs_nut = derived_bcs(CG1, bcs['u0'], u_) nut_ = CG1Function(nut_form, mesh, method=nut_krylov_solver, bcs=bcs_nut, name='nut', bounded=True) return dict(Sij=Sij, Sd=Sd, Skk=Skk, nut_=nut_, delta=delta, bcs_nut=bcs_nut)
def les_setup(u_, mesh, assemble_matrix, CG1Function, nut_krylov_solver, bcs, **NS_namespace): """ Set up for solving the Germano Dynamic LES model applying Lagrangian Averaging. """ # Create function spaces CG1 = FunctionSpace(mesh, "CG", 1) p, q = TrialFunction(CG1), TestFunction(CG1) dim = mesh.geometry().dim() # Define delta and project delta**2 to CG1 delta = pow(CellVolume(mesh), 1. / dim) delta_CG1_sq = project(delta, CG1) delta_CG1_sq.vector().set_local(delta_CG1_sq.vector().array()**2) delta_CG1_sq.vector().apply("insert") # Define nut_ Sij = sym(grad(u_)) magS = sqrt(2 * inner(Sij, Sij)) Cs = Function(CG1) nut_form = Cs**2 * delta**2 * magS # Create nut_ BCs ff = FacetFunction("size_t", mesh, 0) bcs_nut = [] for i, bc in enumerate(bcs['u0']): bc.apply(u_[0].vector()) # Need to initialize bc m = bc.markers() # Get facet indices of boundary ff.array()[m] = i + 1 bcs_nut.append(DirichletBC(CG1, Constant(0), ff, i + 1)) nut_ = CG1Function(nut_form, mesh, method=nut_krylov_solver, bcs=bcs_nut, bounded=True, name="nut") # Create functions for holding the different velocities u_CG1 = as_vector([Function(CG1) for i in range(dim)]) u_filtered = as_vector([Function(CG1) for i in range(dim)]) dummy = Function(CG1) ll = LagrangeInterpolator() # Assemble required filter matrices and functions G_under = Function(CG1, assemble(TestFunction(CG1) * dx)) G_under.vector().set_local(1. / G_under.vector().array()) G_under.vector().apply("insert") G_matr = assemble(inner(p, q) * dx) # Set up functions for Lij and Mij Lij = [Function(CG1) for i in range(dim * dim)] Mij = [Function(CG1) for i in range(dim * dim)] # Check if case is 2D or 3D and set up uiuj product pairs and # Sij forms, assemble required matrices Sijcomps = [Function(CG1) for i in range(dim * dim)] Sijfcomps = [Function(CG1) for i in range(dim * dim)] # Assemble some required matrices for solving for rate of strain terms Sijmats = [assemble_matrix(p.dx(i) * q * dx) for i in range(dim)] if dim == 3: tensdim = 6 uiuj_pairs = ((0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2)) else: tensdim = 3 uiuj_pairs = ((0, 0), (0, 1), (1, 1)) # Set up Lagrange functions JLM = Function(CG1) JLM.vector()[:] += 1E-32 JMM = Function(CG1) JMM.vector()[:] += 1 return dict(Sij=Sij, nut_form=nut_form, nut_=nut_, delta=delta, bcs_nut=bcs_nut, delta_CG1_sq=delta_CG1_sq, CG1=CG1, Cs=Cs, u_CG1=u_CG1, u_filtered=u_filtered, ll=ll, Lij=Lij, Mij=Mij, Sijcomps=Sijcomps, Sijfcomps=Sijfcomps, Sijmats=Sijmats, JLM=JLM, JMM=JMM, dim=dim, tensdim=tensdim, G_matr=G_matr, G_under=G_under, dummy=dummy, uiuj_pairs=uiuj_pairs)
def marked_boundary(mesh): """ Return array of vertex values with 1 on boundary, 0 otherwise. """ fun = FacetFunction("int", mesh, 0) on = OnBoundary() on.mark(fun, 1) return fun.array()
if mpirank == 0: print 'Start assembling KV' MPI.barrier(mpicomm) t0 = time() KV = assemble(weak_V) MPI.barrier(mpicomm) t1 = time() if mpirank == 0: print 'Time to assemble KV = {}'.format(t1 - t0) elif myrun == 2: class LeftRight(SubDomain): def inside(self, x, on_boundary): return (x[0] < 1e-16 or x[0] > 1.0 - 1e-16) \ and on_boundary class_bc_abc = LeftRight() abc_boundaryparts = FacetFunction("size_t", mesh) class_bc_abc.mark(abc_boundaryparts, 1) ds = Measure("ds")[abc_boundaryparts] weak_1 = inner(sqrt(lam1 * rho1) * nabla_grad(trial), nabla_grad(test)) * ds(1) weak_2 = inner(sqrt(lam2 * rho2) * nabla_grad(trial), nabla_grad(test)) * ds(1) lam1.vector()[:] = 1.0 rho1.vector()[:] = 1.0 print 'Start assembling K2' t0 = time() K2 = assemble(weak_2) t1 = time() print 'Time to assemble K2 = {}'.format(t1 - t0)
def construct_sleeve_geometry( t_wall=None, t_gap=None, t_sleeve=None, L_wall=None, L_sleeve=None, refinement_parameter=16, ): # # Define the domain as a polygon mesh = Mesh() domain = Polygon([ dolfin.Point(0.0, 0.0), dolfin.Point(L_wall, 0.0), dolfin.Point(L_wall, t_wall), dolfin.Point((L_wall - L_sleeve), t_wall), dolfin.Point((L_wall - L_sleeve), (t_wall + t_gap)), dolfin.Point(L_wall, (t_wall + t_gap)), dolfin.Point(L_wall, (t_sleeve + t_wall + t_gap)), dolfin.Point((L_wall - L_sleeve), (t_sleeve + t_wall + t_gap)), dolfin.Point((L_wall - L_sleeve - t_sleeve - t_gap), t_wall), dolfin.Point(0.0, t_wall), ], ) # # Define weld region weld_subdomain = Polygon([ dolfin.Point((L_wall - L_sleeve - t_sleeve - t_gap), t_wall), dolfin.Point((L_wall - L_sleeve), t_wall), dolfin.Point((L_wall - L_sleeve), (t_wall + t_sleeve + t_gap)), ]) domain.set_subdomain(1, weld_subdomain) # # Mesh mesh = generate_mesh(domain, refinement_parameter) # # Refine in the weld cell_markers = CellFunction("bool", mesh) cell_markers.set_all(False) c = is_in_weld_region( t_wall=t_wall, t_gap=t_gap, t_sleeve=t_sleeve, L_wall=L_wall, L_sleeve=L_sleeve, ) class MyDomain(SubDomain): def inside(self, x, on_boundary): return c(x) my_domain = MyDomain() my_domain.mark(cell_markers, True) mesh = refine(mesh, cell_markers) # # Define the upper and lower boundaries class Upper(SubDomain): def inside(self, x, on_boundary): # # Define relevant points xb1 = (L_wall - L_sleeve - t_sleeve - t_gap) xb2 = (L_wall - L_sleeve) yb1 = t_wall yb2 = (t_wall + t_sleeve + t_gap) # # Define params for assessing if on a line between points dx_line = xb2 - xb1 dy_line = yb2 - yb1 dx = x[0] - xb1 dy = x[1] - yb1 zero = dx * dy_line - dx_line * dy # is_upper_region_one = x[0] <= xb1 and near(x[1], yb1) is_upper_region_two = x[0] >= xb1 and x[0] <= xb2 and near(zero, 0) is_upper_region_three = x[0] >= xb2 and near(x[1], yb2) # return is_upper_region_one or is_upper_region_two or is_upper_region_three class Lower(SubDomain): def inside(self, x, on_boundary): return near(x[1], 0) # # Set boundaries upper = Upper() lower = Lower() boundaries = FacetFunction("size_t", mesh) boundaries.set_all(0) upper.mark(boundaries, 1) lower.mark(boundaries, 2) # return (mesh, boundaries)
def solve(self): """ Find eigenvalues for transformed mesh. """ self.progress("Building mesh.") # build transformed mesh mesh = self.refineMesh() # dim = mesh.topology().dim() if self.bcLast: mesh = transform_mesh(mesh, self.transformList) Robin, Steklov, shift, bcs = get_bc_parts(mesh, self.bcList) else: Robin, Steklov, shift, bcs = get_bc_parts(mesh, self.bcList) mesh = transform_mesh(mesh, self.transformList) # boundary conditions computed on non-transformed mesh # copy the values to transformed mesh fun = FacetFunction("size_t", mesh, shift) fun.array()[:] = bcs.array()[:] bcs = fun ds = Measure('ds', domain=mesh, subdomain_data=bcs) V = FunctionSpace(mesh, self.method, self.deg) u = TrialFunction(V) v = TestFunction(V) self.progress("Assembling matrices.") wTop = Expression(self.wTop) wBottom = Expression(self.wBottom) # # build stiffness matrix form # s = dot(grad(u), grad(v)) * wTop * dx # add Robin parts for bc in Robin: s += Constant(bc.parValue) * u * v * wTop * ds(bc.value + shift) # # build mass matrix form # if len(Steklov) > 0: m = 0 for bc in Steklov: m += Constant( bc.parValue) * u * v * wBottom * ds(bc.value + shift) else: m = u * v * wBottom * dx # assemble # if USE_EIGEN: # S, M = EigenMatrix(), EigenMatrix() # tempv = EigenVector() # else: S, M = PETScMatrix(), PETScMatrix() # tempv = PETScVector() if not np.any(bcs.array() == shift + 1): # no Dirichlet parts assemble(s, tensor=S) assemble(m, tensor=M) else: # # with EIGEN we could # apply Dirichlet condition symmetrically # completely remove rows and columns # # Dirichlet parts are marked with shift+1 # # temp = Constant(0)*v*dx bc = DirichletBC(V, Constant(0.0), bcs, shift + 1) # assemble_system(s, temp, bc, A_tensor=S, b_tensor=tempv) # assemble_system(m, temp, bc, A_tensor=M, b_tensor=tempv) assemble(s, tensor=S) bc.apply(S) assemble(m, tensor=M) # bc.zero(M) # if USE_EIGEN: # M = M.sparray() # M.eliminate_zeros() # print M.shape # indices = M.indptr[:-1] - M.indptr[1:] < 0 # M = M[indices, :].tocsc()[:, indices] # S = S.sparray()[indices, :].tocsc()[:, indices] # print M.shape # # solve the eigenvalue problem # self.progress("Solving eigenvalue problem.") eigensolver = SLEPcEigenSolver(S, M) eigensolver.parameters["problem_type"] = "gen_hermitian" eigensolver.parameters["solver"] = "krylov-schur" if self.target is not None: eigensolver.parameters["spectrum"] = "target real" eigensolver.parameters["spectral_shift"] = self.target else: eigensolver.parameters["spectrum"] = "smallest magnitude" eigensolver.parameters["spectral_shift"] = -0.01 eigensolver.parameters["spectral_transform"] = "shift-and-invert" eigensolver.solve(self.number) self.progress("Generating eigenfunctions.") if eigensolver.get_number_converged() == 0: return None eigf = [] eigv = [] if self.deg > 1: mesh = refine(mesh) W = FunctionSpace(mesh, 'CG', 1) for i in range(eigensolver.get_number_converged()): pair = eigensolver.get_eigenpair(i)[::2] eigv.append(pair[0]) u = Function(V) u.vector()[:] = pair[1] eigf.append(interpolate(u, W)) return eigv, eigf
class InflowBoundary(SubDomain): def inside(self, x, on_boundary): return on_boundary and near(x[0], x_min) class NoslipBoundary(SubDomain): def inside(self, x, on_boundary): dx = x[0] - c_x dy = x[1] - c_y dr = sqrt(dx**2 + dy**2) return on_boundary and (near(x[1] * (y_max - x[1]), 0) or dr < r + 1E-3) f_f = FacetFunction('size_t', mesh, 0) InflowBoundary().mark(f_f, 13) NoslipBoundary().mark(f_f, 12) # Width of the L domain def compute_width_L_cylinder(unit): return 4 * unit + 4 * unit * cos(pi / 4) # Width of the O domain def compute_width_O_cylinder(unit): return 4 * unit class InflowProfileConstant(Expression):