def test_pde_constrained(polynomial_order, in_expression): interpolate_expression = Expression(in_expression, degree=3) xmin, xmax = 0., 1. ymin, ymax = 0., 1. property_idx = 1 dt = 1. k = polynomial_order # Make mesh mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 40, 40) # Make function spaces and functions W_e = FiniteElement("DG", mesh.ufl_cell(), k) T_e = FiniteElement("DG", mesh.ufl_cell(), 0) Wbar_e = FiniteElement("DGT", mesh.ufl_cell(), k) W = FunctionSpace(mesh, W_e) T = FunctionSpace(mesh, T_e) Wbar = FunctionSpace(mesh, Wbar_e) psi_h, psi0_h = Function(W), Function(W) lambda_h = Function(T) psibar_h = Function(Wbar) uadvect = Constant((0, 0)) # Define particles x = RandomRectangle(Point(xmin, ymin), Point(xmax, ymax)).generate([500, 500]) s = assign_particle_values(x, interpolate_expression) psi0_h.assign(interpolate_expression) # Just make a complicated particle, possibly with scalars and vectors mixed p = particles(x, [s], mesh) p.interpolate(psi0_h, 1) # Initialize forms FuncSpace_adv = { 'FuncSpace_local': W, 'FuncSpace_lambda': T, 'FuncSpace_bar': Wbar } forms_pde = FormsPDEMap(mesh, FuncSpace_adv).forms_theta_linear( psi0_h, uadvect, dt, Constant(1.0)) pde_projection = PDEStaticCondensation(mesh, p, forms_pde['N_a'], forms_pde['G_a'], forms_pde['L_a'], forms_pde['H_a'], forms_pde['B_a'], forms_pde['Q_a'], forms_pde['R_a'], forms_pde['S_a'], [], property_idx) # Assemble and solve pde_projection.assemble(True, True) pde_projection.solve_problem(psibar_h, psi_h, lambda_h, 'none', 'default') error_psih = abs(assemble((psi_h - psi0_h) * (psi_h - psi0_h) * dx)) error_lamb = abs(assemble(lambda_h * lambda_h * dx)) assert error_psih < 1e-15 assert error_lamb < 1e-15
def test_closed_boundary(advection_scheme): # FIXME: rk3 scheme does not bounces off the wall properly xmin, xmax = 0., 1. ymin, ymax = 0., 1. mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 10, 10) # Particle x = np.array([[0.975, 0.475]]) # Given velocity field: vexpr = Constant((1., 0.)) # Given time do_step: dt = 0.05 # Then bounced position is x_bounced = np.array([[0.975, 0.475]]) p = particles(x, [x, x], mesh) V = VectorFunctionSpace(mesh, "CG", 1) v = Function(V) v.assign(vexpr) # Different boundary parts bound_left = UnitSquareLeft() bound_right = UnitSquareRight() bound_top = UnitSquareTop() bound_bottom = UnitSquareBottom() # Mark all facets facet_marker = MeshFunction('size_t', mesh, mesh.topology().dim() - 1) facet_marker.set_all(0) # Mark as closed bound_right.mark(facet_marker, 1) # Mark other boundaries as open bound_left.mark(facet_marker, 2) bound_top.mark(facet_marker, 2) bound_bottom.mark(facet_marker, 2) if advection_scheme == 'euler': ap = advect_particles(p, V, v, facet_marker) elif advection_scheme == 'rk2': ap = advect_rk2(p, V, v, facet_marker) elif advection_scheme == 'rk3': ap = advect_rk3(p, V, v, facet_marker) else: assert False # Do one timestep, particle must bounce from wall of ap.do_step(dt) xpE = p.positions() # Check if particle correctly bounced off from closed wall xpE_root = comm.gather(xpE, root=0) if comm.rank == 0: xpE_root = np.float64(np.vstack(xpE_root)) error = np.linalg.norm(x_bounced - xpE_root) assert(error < 1e-10)
def test_open_boundary(advection_scheme): xmin, xmax = 0.0, 1.0 ymin, ymax = 0.0, 1.0 pres = 3 mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 10, 10) # Particle x = RandomRectangle(Point(0.955, 0.45), Point(1.0, 0.55)).generate([pres, pres]) x = comm.bcast(x, root=0) # Given velocity field: vexpr = Constant((1.0, 1.0)) # Given time do_step: dt = 0.05 p = particles(x, [x, x], mesh) V = VectorFunctionSpace(mesh, "CG", 1) v = Function(V) v.assign(vexpr) # Different boundary parts bound_left = UnitSquareLeft() bound_right = UnitSquareRight() bound_top = UnitSquareTop() bound_bottom = UnitSquareBottom() # Mark all facets facet_marker = MeshFunction("size_t", mesh, mesh.topology().dim() - 1) facet_marker.set_all(0) # Mark as open bound_right.mark(facet_marker, 2) # Mark other boundaries as closed bound_left.mark(facet_marker, 1) bound_top.mark(facet_marker, 1) bound_bottom.mark(facet_marker, 1) if advection_scheme == "euler": ap = advect_particles(p, V, v, facet_marker) elif advection_scheme == "rk2": ap = advect_rk2(p, V, v, facet_marker) elif advection_scheme == "rk3": ap = advect_rk3(p, V, v, facet_marker) else: assert False # Do one timestep, particle must bounce from wall of ap.do_step(dt) num_particles = p.number_of_particles() # Check if all particles left domain if comm.rank == 0: assert (num_particles == 0)
def test_advect_periodic_facet_marker(advection_scheme): xmin, xmax = 0.0, 1.0 ymin, ymax = 0.0, 1.0 mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 10, 10) facet_marker = MeshFunction("size_t", mesh, mesh.topology().dim() - 1) facet_marker.set_all(0) boundaries = Boundaries() boundaries.mark(facet_marker, 3) lims = np.array([ [xmin, xmin, ymin, ymax], [xmax, xmax, ymin, ymax], [xmin, xmax, ymin, ymin], [xmin, xmax, ymax, ymax], ]) vexpr = Constant((1.0, 1.0)) V = VectorFunctionSpace(mesh, "CG", 1) x = RandomRectangle(Point(0.05, 0.05), Point(0.15, 0.15)).generate([3, 3]) x = comm.bcast(x, root=0) dt = 0.05 v = Function(V) v.assign(vexpr) p = particles(x, [x * 0, x**2], mesh) if advection_scheme == "euler": ap = advect_particles(p, V, v, facet_marker, lims.flatten()) elif advection_scheme == "rk2": ap = advect_rk2(p, V, v, facet_marker, lims.flatten()) elif advection_scheme == "rk3": ap = advect_rk3(p, V, v, facet_marker, lims.flatten()) else: assert False xp0 = p.positions() t = 0.0 while t < 1.0 - 1e-12: ap.do_step(dt) t += dt xpE = p.positions() # Check if position correct xp0_root = comm.gather(xp0, root=0) xpE_root = comm.gather(xpE, root=0) if comm.Get_rank() == 0: xp0_root = np.float32(np.vstack(xp0_root)) xpE_root = np.float32(np.vstack(xpE_root)) error = np.linalg.norm(xp0_root - xpE_root) assert error < 1e-10
def test_l2projection_bounded(polynomial_order, lb, ub): # Test l2 projection if it stays within bounds given by lb and ub interpolate_expression = SlottedDisk(radius=0.15, center=[0.5, 0.5], width=0.05, depth=0., degree=3, lb=lb, ub=ub) xmin, xmax = 0., 1. ymin, ymax = 0., 1. property_idx = 5 mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 40, 40) V = FunctionSpace(mesh, "DG", polynomial_order) x = RandomRectangle(Point(xmin, ymin), Point(xmax, ymax)).generate([500, 500]) s = assign_particle_values(x, interpolate_expression) # Just make a complicated particle, possibly with scalars and vectors mixed p = particles(x, [x, s, x, x, s], mesh) vh = Function(V) lstsq_rho = l2projection(p, V, property_idx) lstsq_rho.project(vh, lb, ub) # Assert if it stays within bounds assert np.all(vh.vector().get_local() < ub + 1e-12) assert np.all(vh.vector().get_local() > lb - 1e-12)
def test_l2projection(polynomial_order, in_expression): # Test l2 projection for scalar and vector valued expression interpolate_expression = Expression(in_expression, degree=3) xmin, xmax = 0., 1. ymin, ymax = 0., 1. property_idx = 5 mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 40, 40) if len(interpolate_expression.ufl_shape) == 0: V = FunctionSpace(mesh, "DG", polynomial_order) elif len(interpolate_expression.ufl_shape) == 1: V = VectorFunctionSpace(mesh, "DG", polynomial_order) v_exact = Function(V) v_exact.interpolate(interpolate_expression) x = RandomRectangle(Point(xmin, ymin), Point(xmax, ymax)).generate([500, 500]) s = assign_particle_values(x, interpolate_expression) # Just make a complicated particle, possibly with scalars and vectors mixed p = particles(x, [x, s, x, x, s], mesh) vh = Function(V) lstsq_rho = l2projection(p, V, property_idx) lstsq_rho.project(vh) error_sq = abs(assemble(dot(v_exact - vh, v_exact - vh) * dx)) assert error_sq < 1e-15
def test_mesh_generator_2d(): """Basic functionality test.""" mesh = RectangleMesh(Point(0.0, 0.0), Point(1.0, 1.0), 5, 5) for x in mesh.coordinates(): x[0] += 0.5 * x[1] w = RandomCell(mesh) pts = w.generate(3) assert len(pts) == mesh.num_cells() * 3 interpolate_expression = Expression("x[0] + x[1]", degree=1) s = assign_particle_values(pts, interpolate_expression, on_root=False) p = particles(pts, [s], mesh) assert np.linalg.norm(np.sum(pts, axis=1) - s) <= 1e-15 assert np.linalg.norm(pts - p.positions()) <= 1e-15
def test_lhs_rhs_simple(): """Test taking lhs/rhs of DOLFIN specific forms (constants without cell). """ mesh = RectangleMesh(MPI.comm_world, [numpy.array([0.0, 0.0, 0.0]), numpy.array([2.0, 1.0, 0.0])], [3, 5], CellType.triangle) V = FunctionSpace(mesh, "CG", 1) f = 2.0 g = 3.0 v = TestFunction(V) u = TrialFunction(V) F = inner(g * grad(f * v), grad(u)) * dx + f * v * dx a, L = system(F) Fl = lhs(F) Fr = rhs(F) assert(Fr) a0 = inner(grad(v), grad(u)) * dx n = assemble(a).norm("frobenius") # noqa nl = assemble(Fl).norm("frobenius") # noqa n0 = 6.0 * assemble(a0).norm("frobenius") # noqa assert round(n - n0, 7) == 0 assert round(n - nl, 7) == 0
def test_radius_ratio_min_radius_ratio_max(): mesh1d = UnitIntervalMesh(MPI.comm_self, 4) x = mesh1d.geometry.points x[4] = mesh1d.geometry.points[3] # Create 2D mesh with one equilateral triangle mesh2d = RectangleMesh( MPI.comm_world, [numpy.array([0.0, 0.0, 0.0]), numpy.array([1.0, 1.0, 0.0])], [1, 1], CellType.Type.triangle, cpp.mesh.GhostMode.none, 'left') x = mesh2d.geometry.points x[3, :2] += 0.5 * (sqrt(3.0) - 1.0) # Create 3D mesh with regular tetrahedron and degenerate cells mesh3d = UnitCubeMesh(MPI.comm_self, 1, 1, 1) x = mesh3d.geometry.points x[6][0] = 1.0 x[3][1] = 0.0 rmin, rmax = MeshQuality.radius_ratio_min_max(mesh1d) assert round(rmin - 0.0, 7) == 0 assert round(rmax - 1.0, 7) == 0 rmin, rmax = MeshQuality.radius_ratio_min_max(mesh2d) assert round(rmin - 2.0 * sqrt(2.0) / (2.0 + sqrt(2.0)), 7) == 0 assert round(rmax - 1.0, 7) == 0 rmin, rmax = MeshQuality.radius_ratio_min_max(mesh3d) assert round(rmin - 0.0, 7) == 0 assert round(rmax - 1.0, 7) == 0
def mesh_Square(n=10, method='regular'): if method == 'mshr': dom = mshr.Rectangle(Point(-1., -1.), Point(1., 1.)) mesh = mshr.generate_mesh(dom, n, "cgal") elif method == 'regular': mesh = RectangleMesh(Point(-1., -1.), Point(1., 1.), n, n) return mesh
def test_advect_periodic(advection_scheme): # FIXME: this unit test is sensitive to the ordering of the particle # array, i.e. xp0_root and xpE_root may contain exactly the same entries # but only in a different order. This will return an error right now xmin, xmax = 0., 1. ymin, ymax = 0., 1. pres = 3 mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 10, 10) lims = np.array([[xmin, xmin, ymin, ymax], [xmax, xmax, ymin, ymax], [xmin, xmax, ymin, ymin], [xmin, xmax, ymax, ymax]]) vexpr = Constant((1., 1.)) V = VectorFunctionSpace(mesh, "CG", 1) x = RandomRectangle(Point(0.05, 0.05), Point(0.15, 0.15)).generate([pres, pres]) x = comm.bcast(x, root=0) dt = 0.05 v = Function(V) v.assign(vexpr) p = particles(x, [x*0, x**2], mesh) if advection_scheme == 'euler': ap = advect_particles(p, V, v, 'periodic', lims.flatten()) elif advection_scheme == 'rk2': ap = advect_rk2(p, V, v, 'periodic', lims.flatten()) elif advection_scheme == 'rk3': ap = advect_rk3(p, V, v, 'periodic', lims.flatten()) else: assert False xp0 = p.positions() t = 0. while t < 1.-1e-12: ap.do_step(dt) t += dt xpE = p.positions() # Check if position correct xp0_root = comm.gather(xp0, root=0) xpE_root = comm.gather(xpE, root=0) num_particles = p.number_of_particles() if comm.Get_rank() == 0: xp0_root = np.float32(np.vstack(xp0_root)) xpE_root = np.float32(np.vstack(xpE_root)) # Sort on x positions xp0_root = xp0_root[xp0_root[:, 0].argsort(), :] xpE_root = xpE_root[xpE_root[:, 0].argsort(), :] error = np.linalg.norm(xp0_root - xpE_root) assert error < 1e-10 assert num_particles - pres**2 == 0
def mesh2d(): """Create 2D mesh with one equilateral triangle""" mesh2d = RectangleMesh( MPI.comm_world, [numpy.array([0.0, 0.0, 0.0]), numpy.array([1., 1., 0.0])], [1, 1], CellType.triangle, cpp.mesh.GhostMode.none, 'left') mesh2d.geometry.points[3, :2] += 0.5 * (math.sqrt(3.0) - 1.0) return mesh2d
def mesh2d(): # Create 2D mesh with one equilateral triangle mesh2d = RectangleMesh.create( MPI.comm_world, [Point(0, 0)._cpp_object, Point(1, 1)._cpp_object], [1, 1], CellType.Type.triangle, cpp.mesh.GhostMode.none, 'left') mesh2d.geometry.points[3] += 0.5 * (sqrt(3.0) - 1.0) return mesh2d
def __init__(self): mesh = RectangleMesh(Point(-0.5, -0.5), Point(+0.5, +0.5), 20, 20) self.V = FunctionSpace(mesh, "Lagrange", 1) u = TrialFunction(self.V) v = TestFunction(self.V) self.a = assemble(dot(grad(u), grad(v)) * dx) self.m = assemble(u * v * dx)
def test_bounded_domain_boundary(xlims, ylims, advection_scheme): xmin, xmax = xlims ymin, ymax = ylims pres = 1 mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 10, 10) ymin += 0.0025 lims = np.array([xmin, xmax, ymin, ymax]) v_arr = np.array([-1.0, -1.0]) vexpr = Constant(v_arr) V = VectorFunctionSpace(mesh, "CG", 1) x = RandomRectangle(Point(0.05, 0.05), Point(0.15, 0.15)).generate([pres, pres]) dt = 0.005 v = Function(V) v.assign(vexpr) p = particles(x, [x], mesh) if advection_scheme == 'euler': ap = advect_particles(p, V, v, 'bounded', lims.flatten()) elif advection_scheme == 'rk2': ap = advect_rk2(p, V, v, 'bounded', lims.flatten()) elif advection_scheme == 'rk3': ap = advect_rk3(p, V, v, 'bounded', lims.flatten()) else: assert False original_num_particles = p.number_of_particles() t = 0. while t < 3.0 - 1e-12: ap.do_step(dt) t += dt assert p.number_of_particles() == original_num_particles xpn = np.array(p.get_property(0)).reshape((-1, 2)) x0 = np.array(p.get_property(1)).reshape((-1, 2)) analytical_position = x0 + t * v_arr analytical_position[:, 0] = np.maximum( np.minimum(xmax, analytical_position[:, 0]), xmin) analytical_position[:, 1] = np.maximum( np.minimum(ymax, analytical_position[:, 1]), ymin) error = np.abs(xpn - analytical_position) assert np.all(np.abs(error) < 1e-12)
def gen_mesh(n_gridpoints, dim): if dim == 2: #if(dolfin.__version__[2] <= 4): # mesh = RectangleMesh(0,0,1,1,n_gridpoints,n_gridpoints,"left"); #else: p0 = Point(0, 0) p1 = Point(1, 1) mesh = RectangleMesh(p0, p1, n_gridpoints, n_gridpoints, "left") else: p0 = Point(0, 0, 0) p1 = Point(1, 1, 0) mesh = BoxMesh(p0, p1, n_gridpoints, n_gridpoints, n_gridpoints) return mesh
def test_cmscr1d_img_custom_mesh(self): print("Running test 'test_cmscr1d_img_custom_mesh'") # Create zero image. img = np.zeros((10, 25)) # Create custom mesh. m, n = img.shape mesh = RectangleMesh(Point(0, 0), Point(0.1, 1), m - 1, n - 1) v, k, res, fun, converged = cmscr1d_img(img, 1.0, 1.0, 1.0, 1.0, 1.0, 'mesh', mesh=mesh) np.testing.assert_allclose(v.shape, img.shape) np.testing.assert_allclose(v, np.zeros_like(v)) np.testing.assert_allclose(k.shape, img.shape) np.testing.assert_allclose(k, np.zeros_like(k))
def pot(): # Define mesh and boundaries. mesh = RectangleMesh(0.0, 0.0, 0.4, 0.1, 120, 30, "left/right") V = VectorFunctionSpace(mesh, "CG", 2) Q = FunctionSpace(mesh, "CG", 1) class LeftBoundary(SubDomain): def inside(self, x, on_boundary): return on_boundary and x[0] < GMSH_EPS left_boundary = LeftBoundary() class RightBoundary(SubDomain): def inside(self, x, on_boundary): return on_boundary and x[0] > 0.4 - GMSH_EPS right_boundary = RightBoundary() class LowerBoundary(SubDomain): def inside(self, x, on_boundary): return on_boundary and x[1] < GMSH_EPS lower_boundary = LowerBoundary() class UpperBoundary(SubDomain): def inside(self, x, on_boundary): return on_boundary and x[1] > 0.1 - GMSH_EPS upper_boundary = UpperBoundary() # Boundary conditions for the velocity. u_bcs = [ DirichletBC(V, (0.0, 0.0), lower_boundary), DirichletBC(V.sub(1), 0.0, upper_boundary), DirichletBC(V.sub(0), 0.0, right_boundary), DirichletBC(V.sub(0), 0.0, left_boundary), ] p_bcs = [] return mesh, V, Q, u_bcs, p_bcs, [lower_boundary], [right_boundary, left_boundary]
def generate_rectangle(x0, y0, x1, y1, nx, ny): """ Creates a square mesh of given elements and length with markers on the sides: left, bottom, right and top """ from dolfin import RectangleMesh, Point, SubDomain, MeshFunction, Measure, near mesh = RectangleMesh(Point(x0, y0), Point(x1, y1), nx, ny) # Subdomains: Solid class Left(SubDomain): def inside(self, x, on_boundary): return near(x[0], x0) and on_boundary class Right(SubDomain): def inside(self, x, on_boundary): return near(x[0], x1) and on_boundary class Top(SubDomain): def inside(self, x, on_boundary): return near(x[1], y1) and on_boundary class Bottom(SubDomain): def inside(self, x, on_boundary): return near(x[1], y0) and on_boundary left, right, top, bottom = Left(), Right(), Top(), Bottom() LEFT, RIGHT, TOP, BOTTOM = 1, 2, 3, 4 # Set numbering NONE = 99 # Marker for empty boundary markers = MeshFunction("size_t", mesh, 1) markers.set_all(0) boundaries = (left, right, top, bottom) def_names = (LEFT, RIGHT, TOP, BOTTOM) for side, num in zip(boundaries, def_names): side.mark(markers, num) return mesh, markers, LEFT, RIGHT, TOP, BOTTOM, NONE
def test_eim_approximation_17(expression_type, basis_generation): """ This test is similar to test 15. However, in contrast to test 15, the solution is not split at all. * EIM: unsplit solution is used in the definition of the parametrized expression, similarly to test 11. * DEIM: unsplit solution is used in the definition of the parametrized tensor. This results in a single coefficient of type Function, which however is stored internally by UFL as an Indexed of Function and a mute index. This test requires the FEniCS backend to properly differentiate between Indexed objects with a fixed index (such as a component of the solution as in test 13) and Indexed objects with a mute index, which should be treated has if the entire solution was required. """ @StoreMapFromProblemNameToProblem @StoreMapFromProblemToTrainingStatus @StoreMapFromSolutionToProblem class MockProblem(ParametrizedProblem): def __init__(self, V, **kwargs): # Call parent ParametrizedProblem.__init__( self, os.path.join("test_eim_approximation_17_tempdir", expression_type, basis_generation, "mock_problem")) # Minimal subset of a ParametrizedDifferentialProblem self.V = V self._solution = Function(V) self.components = ["u", "s", "p"] # Parametrized function to be interpolated x = SpatialCoordinate(V.mesh()) mu = SymbolicParameters(self, V, (-1., -1.)) self.f00 = 1. / sqrt( pow(x[0] - mu[0], 2) + pow(x[1] - mu[1], 2) + 0.01) self.f01 = 1. / sqrt( pow(x[0] - mu[0], 4) + pow(x[1] - mu[1], 4) + 0.01) # Inner product f = TrialFunction(self.V) g = TestFunction(self.V) self.inner_product = assemble(inner(f, g) * dx) # Collapsed vector and space self.V0 = V.sub(0).collapse() self.V00 = V.sub(0).sub(0).collapse() self.V1 = V.sub(1).collapse() def name(self): return "MockProblem_17_" + expression_type + "_" + basis_generation def init(self): pass def solve(self): assert not hasattr(self, "_is_solving") self._is_solving = True f00 = project(self.f00, self.V00) f01 = project(self.f01, self.V00) assign(self._solution.sub(0).sub(0), f00) assign(self._solution.sub(0).sub(1), f01) delattr(self, "_is_solving") return self._solution @StoreMapFromProblemToReductionMethod @UpdateMapFromProblemToTrainingStatus class MockReductionMethod(ReductionMethod): def __init__(self, truth_problem, **kwargs): # Call parent ReductionMethod.__init__( self, os.path.join("test_eim_approximation_17_tempdir", expression_type, basis_generation, "mock_problem")) # Minimal subset of a DifferentialProblemReductionMethod self.truth_problem = truth_problem self.reduced_problem = None # I/O self.folder["basis"] = os.path.join( self.truth_problem.folder_prefix, "basis") # Gram Schmidt self.GS = GramSchmidt(self.truth_problem.inner_product) def initialize_training_set(self, ntrain, enable_import=True, sampling=None, **kwargs): return ReductionMethod.initialize_training_set( self, self.truth_problem.mu_range, ntrain, enable_import, sampling, **kwargs) def initialize_testing_set(self, ntest, enable_import=False, sampling=None, **kwargs): return ReductionMethod.initialize_testing_set( self, self.truth_problem.mu_range, ntest, enable_import, sampling, **kwargs) def offline(self): self.reduced_problem = MockReducedProblem(self.truth_problem) if self.folder["basis"].create( ): # basis folder was not available yet for (index, mu) in enumerate(self.training_set): self.truth_problem.set_mu(mu) print("solving mock problem at mu =", self.truth_problem.mu) f = self.truth_problem.solve() self.update_basis_matrix((index, f)) self.reduced_problem.basis_functions.save( self.folder["basis"], "basis") else: self.reduced_problem.basis_functions.load( self.folder["basis"], "basis") self._finalize_offline() return self.reduced_problem def update_basis_matrix(self, index_and_snapshot): (index, snapshot) = index_and_snapshot component = "u" if index % 2 == 0 else "s" self.reduced_problem.basis_functions.enrich(snapshot, component) self.GS.apply(self.reduced_problem.basis_functions[component], 0) def error_analysis(self, N=None, **kwargs): pass def speedup_analysis(self, N=None, **kwargs): pass @StoreMapFromProblemToReducedProblem class MockReducedProblem(ParametrizedProblem): @sync_setters("truth_problem", "set_mu", "mu") @sync_setters("truth_problem", "set_mu_range", "mu_range") def __init__(self, truth_problem, **kwargs): # Call parent ParametrizedProblem.__init__( self, os.path.join("test_eim_approximation_17_tempdir", expression_type, basis_generation, "mock_problem")) # Minimal subset of a ParametrizedReducedDifferentialProblem self.truth_problem = truth_problem self.basis_functions = BasisFunctionsMatrix(self.truth_problem.V) self.basis_functions.init(self.truth_problem.components) self._solution = None def solve(self): print("solving mock reduced problem at mu =", self.mu) assert not hasattr(self, "_is_solving") self._is_solving = True f = self.truth_problem.solve() f_N = transpose( self.basis_functions) * self.truth_problem.inner_product * f # Return the reduced solution self._solution = OnlineFunction(f_N) delattr(self, "_is_solving") return self._solution class ParametrizedFunctionApproximation(EIMApproximation): def __init__(self, truth_problem, expression_type, basis_generation): self.V = truth_problem.V # folder_prefix = os.path.join("test_eim_approximation_17_tempdir", expression_type, basis_generation) assert expression_type in ("Function", "Vector", "Matrix") if expression_type == "Function": # Call Parent constructor EIMApproximation.__init__( self, truth_problem, ParametrizedExpressionFactory(truth_problem._solution), folder_prefix, basis_generation) elif expression_type == "Vector": v = TestFunction(self.V) form = inner(truth_problem._solution, v) * dx # Call Parent constructor EIMApproximation.__init__(self, truth_problem, ParametrizedTensorFactory(form), folder_prefix, basis_generation) elif expression_type == "Matrix": u = TrialFunction(self.V) v = TestFunction(self.V) form = inner(truth_problem._solution, u) * v[0] * dx # Call Parent constructor EIMApproximation.__init__(self, truth_problem, ParametrizedTensorFactory(form), folder_prefix, basis_generation) else: # impossible to arrive here anyway thanks to the assert raise AssertionError("Invalid expression_type") # 1. Create the mesh for this test mesh = RectangleMesh(Point(0.1, 0.1), Point(0.9, 0.9), 20, 20) # 2. Create Finite Element space (Lagrange P1) element_0 = VectorElement("Lagrange", mesh.ufl_cell(), 2) element_1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1) element = MixedElement(element_0, element_1) V = FunctionSpace(mesh, element, components=[["u", "s"], "p"]) # 3. Create a parametrized problem problem = MockProblem(V) mu_range = [(-1., -0.01), (-1., -0.01)] problem.set_mu_range(mu_range) # 4. Create a reduction method and run the offline phase to generate the corresponding # reduced problem reduction_method = MockReductionMethod(problem) reduction_method.initialize_training_set(16, sampling=EquispacedDistribution()) reduction_method.offline() # 5. Allocate an object of the ParametrizedFunctionApproximation class parametrized_function_approximation = ParametrizedFunctionApproximation( problem, expression_type, basis_generation) parametrized_function_approximation.set_mu_range(mu_range) # 6. Prepare reduction with EIM parametrized_function_reduction_method = EIMApproximationReductionMethod( parametrized_function_approximation) parametrized_function_reduction_method.set_Nmax(16) parametrized_function_reduction_method.set_tolerance(0.) # 7. Perform EIM offline phase parametrized_function_reduction_method.initialize_training_set( 64, sampling=EquispacedDistribution()) reduced_parametrized_function_approximation = parametrized_function_reduction_method.offline( ) # 8. Perform EIM online solve online_mu = (-1., -1.) reduced_parametrized_function_approximation.set_mu(online_mu) reduced_parametrized_function_approximation.solve() # 9. Perform EIM error analysis parametrized_function_reduction_method.initialize_testing_set(100) parametrized_function_reduction_method.error_analysis()
def initMesh(self, n): self.mesh = RectangleMesh(Point(-.5, -.5), Point(0.5, 0.5), n, n)
def initMesh(self, n): self.mesh = RectangleMesh(Point(0., 0.), Point(1.0, 1.0), n, n)
TestFunction, TrialFunction, solve) from dolfin.function.specialfunctions import SpatialCoordinate from dolfin.io import XDMFFile from dolfin.cpp.mesh import CellType from ufl import ds, dx, grad, inner # We begin by defining a mesh of the domain and a finite element # function space :math:`V` relative to this mesh. As the unit square is # a very standard domain, we can use a built-in mesh provided by the # class :py:class:`UnitSquareMesh <dolfin.cpp.UnitSquareMesh>`. In order # to create a mesh consisting of 32 x 32 squares with each square # divided into two triangles, we do as follows :: # Create mesh and define function space mesh = RectangleMesh( MPI.comm_world, [np.array([0, 0, 0]), np.array([1, 1, 0])], [32, 32], CellType.triangle, dolfin.cpp.mesh.GhostMode.none) V = FunctionSpace(mesh, ("Lagrange", 1)) cmap = dolfin.fem.create_coordinate_map(mesh.ufl_domain()) mesh.geometry.coord_mapping = cmap # The second argument to :py:class:`FunctionSpace # <dolfin.functions.functionspace.FunctionSpace>` is the finite element # family, while the third argument specifies the polynomial # degree. Thus, in this case, our space ``V`` consists of first-order, # continuous Lagrange finite element functions (or in order words, # continuous piecewise linear polynomials). # # Next, we want to consider the Dirichlet boundary condition. A simple # Python function, returning a boolean, can be used to define the
def test_eim_approximation_20(expression_type, basis_generation): """ This test is the version of test 19 where high fidelity solution is used in place of reduced order one. """ @StoreMapFromProblemNameToProblem @StoreMapFromProblemToTrainingStatus @StoreMapFromSolutionToProblem class MockProblem(ParametrizedProblem): def __init__(self, V, **kwargs): # Call parent ParametrizedProblem.__init__( self, os.path.join("test_eim_approximation_20_tempdir", expression_type, basis_generation, "mock_problem")) # Minimal subset of a ParametrizedDifferentialProblem self.V = V self._solution = Function(V) self.components = ["u", "s", "p"] # Parametrized function to be interpolated x = SpatialCoordinate(V.mesh()) mu = SymbolicParameters(self, V, (-1., -1.)) self.f00 = 1. / sqrt( pow(x[0] - mu[0], 2) + pow(x[1] - mu[1], 2) + 0.01) self.f01 = 1. / sqrt( pow(x[0] - mu[0], 4) + pow(x[1] - mu[1], 4) + 0.01) # Inner product f = TrialFunction(self.V) g = TestFunction(self.V) self.inner_product = assemble(inner(f, g) * dx) # Collapsed vector and space self.V0 = V.sub(0).collapse() self.V00 = V.sub(0).sub(0).collapse() self.V1 = V.sub(1).collapse() def name(self): return "MockProblem_20_" + expression_type + "_" + basis_generation def init(self): pass def solve(self): print("solving mock problem at mu =", self.mu) assert not hasattr(self, "_is_solving") self._is_solving = True f00 = project(self.f00, self.V00) f01 = project(self.f01, self.V00) assign(self._solution.sub(0).sub(0), f00) assign(self._solution.sub(0).sub(1), f01) delattr(self, "_is_solving") return self._solution @StoreMapFromProblemToReductionMethod class MockReductionMethod(ReductionMethod): def __init__(self, truth_problem, **kwargs): # Call parent ReductionMethod.__init__( self, os.path.join("test_eim_approximation_20_tempdir", expression_type, basis_generation, "mock_problem")) # Minimal subset of a DifferentialProblemReductionMethod self.truth_problem = truth_problem self.reduced_problem = None def initialize_training_set(self, ntrain, enable_import=True, sampling=None, **kwargs): return ReductionMethod.initialize_training_set( self, self.truth_problem.mu_range, ntrain, enable_import, sampling, **kwargs) def initialize_testing_set(self, ntest, enable_import=False, sampling=None, **kwargs): return ReductionMethod.initialize_testing_set( self, self.truth_problem.mu_range, ntest, enable_import, sampling, **kwargs) def offline(self): pass def update_basis_matrix(self, snapshot): pass def error_analysis(self, N=None, **kwargs): pass def speedup_analysis(self, N=None, **kwargs): pass class ParametrizedFunctionApproximation(EIMApproximation): def __init__(self, truth_problem, expression_type, basis_generation): self.V = truth_problem.V0 (f0, _) = split(truth_problem._solution) # folder_prefix = os.path.join("test_eim_approximation_20_tempdir", expression_type, basis_generation) assert expression_type in ("Function", "Vector", "Matrix") if expression_type == "Function": # Call Parent constructor EIMApproximation.__init__( self, truth_problem, ParametrizedExpressionFactory(grad(f0)), folder_prefix, basis_generation) elif expression_type == "Vector": v = TestFunction(self.V) form = inner(grad(f0), grad(v)) * dx # Call Parent constructor EIMApproximation.__init__(self, truth_problem, ParametrizedTensorFactory(form), folder_prefix, basis_generation) elif expression_type == "Matrix": u = TrialFunction(self.V) v = TestFunction(self.V) form = inner(grad(f0), grad(u)) * v[0] * dx # Call Parent constructor EIMApproximation.__init__(self, truth_problem, ParametrizedTensorFactory(form), folder_prefix, basis_generation) else: # impossible to arrive here anyway thanks to the assert raise AssertionError("Invalid expression_type") # 1. Create the mesh for this test mesh = RectangleMesh(Point(0.1, 0.1), Point(0.9, 0.9), 20, 20) # 2. Create Finite Element space (Lagrange P1) element_0 = VectorElement("Lagrange", mesh.ufl_cell(), 2) element_1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1) element = MixedElement(element_0, element_1) V = FunctionSpace(mesh, element, components=[["u", "s"], "p"]) # 3. Create a parametrized problem problem = MockProblem(V) mu_range = [(-1., -0.01), (-1., -0.01)] problem.set_mu_range(mu_range) # 4. Create a reduction method, but postpone generation of the reduced problem MockReductionMethod(problem) # 5. Allocate an object of the ParametrizedFunctionApproximation class parametrized_function_approximation = ParametrizedFunctionApproximation( problem, expression_type, basis_generation) parametrized_function_approximation.set_mu_range(mu_range) # 6. Prepare reduction with EIM parametrized_function_reduction_method = EIMApproximationReductionMethod( parametrized_function_approximation) parametrized_function_reduction_method.set_Nmax(16) parametrized_function_reduction_method.set_tolerance(0.) # 7. Perform EIM offline phase parametrized_function_reduction_method.initialize_training_set( 64, sampling=EquispacedDistribution()) reduced_parametrized_function_approximation = parametrized_function_reduction_method.offline( ) # 8. Perform EIM online solve online_mu = (-1., -1.) reduced_parametrized_function_approximation.set_mu(online_mu) reduced_parametrized_function_approximation.solve() # 9. Perform EIM error analysis parametrized_function_reduction_method.initialize_testing_set(100) parametrized_function_reduction_method.error_analysis()
from dolfin import (MPI, CellType, DirichletBC, Function, FunctionSpace, Point, RectangleMesh, TestFunction, TrialFunction, solve) from dolfin.function.specialfunctions import SpatialCoordinate from dolfin.io import XDMFFile from ufl import ds, dx, grad, inner # We begin by defining a mesh of the domain and a finite element # function space :math:`V` relative to this mesh. As the unit square is # a very standard domain, we can use a built-in mesh provided by the # class :py:class:`UnitSquareMesh <dolfin.cpp.UnitSquareMesh>`. In order # to create a mesh consisting of 32 x 32 squares with each square # divided into two triangles, we do as follows :: # Create mesh and define function space mesh = RectangleMesh( MPI.comm_world, [Point(0, 0)._cpp_object, Point(1, 1)._cpp_object], [32, 32], CellType.Type.triangle, dolfin.cpp.mesh.GhostMode.none) V = FunctionSpace(mesh, ("Lagrange", 1)) cmap = dolfin.fem.create_coordinate_map(mesh.ufl_domain()) mesh.geometry.coord_mapping = cmap # The second argument to :py:class:`FunctionSpace # <dolfin.functions.functionspace.FunctionSpace>` is the finite element # family, while the third argument specifies the polynomial # degree. Thus, in this case, our space ``V`` consists of first-order, # continuous Lagrange finite element functions (or in order words, # continuous piecewise linear polynomials). # # Next, we want to consider the Dirichlet boundary condition. A simple # Python function, returning a boolean, can be used to define the
def test_div_grad_then_integrate_over_cells_and_boundary(): # Define 2D geometry n = 10 mesh = RectangleMesh(Point(0.0, 0.0), Point(2.0, 3.0), 2 * n, 3 * n) x, y = SpatialCoordinate(mesh) xs = 0.1 + 0.8 * x / 2 # scaled to be within [0.1,0.9] # ys = 0.1 + 0.8 * y / 3 # scaled to be within [0.1,0.9] n = FacetNormal(mesh) # Define list of expressions to test, and configure accuracies # these expressions are known to pass with. The reason some # functions are less accurately integrated is likely that the # default choice of quadrature rule is not perfect F_list = [] def reg(exprs, acc=10): for expr in exprs: F_list.append((expr, acc)) # FIXME: 0*dx and 1*dx fails in the ufl-ffc-jit framework somewhere # reg([Constant(0.0, cell=cell)]) # reg([Constant(1.0, cell=cell)]) monomial_list = [x**q for q in range(2, 6)] reg(monomial_list) reg([2.3 * p + 4.5 * q for p in monomial_list for q in monomial_list]) reg([xs**xs]) reg( [xs**(xs**2)], 8 ) # Note: Accuracies here are from 1D case, not checked against 2D results. reg([xs**(xs**3)], 6) reg([xs**(xs**4)], 2) # Special functions: reg([atan(xs)], 8) reg([sin(x), cos(x), exp(x)], 5) reg([ln(xs), pow(x, 2.7), pow(2.7, x)], 3) reg([asin(xs), acos(xs)], 1) reg([tan(xs)], 7) # To handle tensor algebra, make an x dependent input tensor # xx and square all expressions def reg2(exprs, acc=10): for expr in exprs: F_list.append((inner(expr, expr), acc)) xx = as_matrix([[2 * x**2, 3 * x**3], [11 * x**5, 7 * x**4]]) xxs = as_matrix([[2 * xs**2, 3 * xs**3], [11 * xs**5, 7 * xs**4]]) x3v = as_vector([3 * x**2, 5 * x**3, 7 * x**4]) cc = as_matrix([[2, 3], [4, 5]]) reg2( [xx] ) # TODO: Make unit test for UFL from this, results in listtensor with free indices reg2([x3v]) reg2([cross(3 * x3v, as_vector([-x3v[1], x3v[0], x3v[2]]))]) reg2([xx.T]) reg2([tr(xx)]) reg2([det(xx)]) reg2([dot(xx, 0.1 * xx)]) reg2([outer(xx, xx.T)]) reg2([dev(xx)]) reg2([sym(xx)]) reg2([skew(xx)]) reg2([elem_mult(7 * xx, cc)]) reg2([elem_div(7 * xx, xx + cc)]) reg2([elem_pow(1e-3 * xxs, 1e-3 * cc)]) reg2([elem_pow(1e-3 * cc, 1e-3 * xx)]) reg2([elem_op(lambda z: sin(z) + 2, 0.03 * xx)], 2) # pretty inaccurate... # FIXME: Add tests for all UFL operators: # These cause discontinuities and may be harder to test in the # above fashion: # 'inv', 'cofac', # 'eq', 'ne', 'le', 'ge', 'lt', 'gt', 'And', 'Or', 'Not', # 'conditional', 'sign', # 'jump', 'avg', # 'LiftingFunction', 'LiftingOperator', # FIXME: Test other derivatives: (but algorithms for operator # derivatives are the same!): # 'variable', 'diff', # 'Dx', 'grad', 'div', 'curl', 'rot', 'Dn', 'exterior_derivative', # Run through all operators defined above and compare integrals debug = 0 if debug: F_list = F_list[1:] for F, acc in F_list: if debug: print('\n', "F:", str(F)) # Integrate over domain and its boundary int_dx = assemble(div(grad(F)) * dx(mesh)) # noqa int_ds = assemble(dot(grad(F), n) * ds(mesh)) # noqa if debug: print(int_dx, int_ds) # Compare results. Using custom relative delta instead of # decimal digits here because some numbers are >> 1. delta = min(abs(int_dx), abs(int_ds)) * 10**-acc assert int_dx - int_ds <= delta
def rectangle(): return RectangleMesh.create( MPI.comm_world, [Point(0, 0)._cpp_object, Point(2, 2)._cpp_object], [5, 5], CellType.Type.triangle, cpp.mesh.GhostMode.none)
t = 0. T_end = 2. dt = Constant(0.025) num_steps = int(np.rint(T_end / float(dt))) xmin, ymin = 0., 0. xmax, ymax = 1., 1. xc, yc = 0.25, 0.5 nx, ny = 32, 32 pres = 400 k = 1 # Directory for output outdir_base = './../../results/MovingMesh/' mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), nx, ny) n = FacetNormal(mesh) outfile = File(mesh.mpi_comm(), outdir_base+"psi_h.pvd") V = VectorFunctionSpace(mesh, 'DG', 2) Vcg = VectorFunctionSpace(mesh, 'CG', 1) boundaries = MeshFunction("size_t", mesh, mesh.topology().dim()-1) boundaries.set_all(0) ds = Measure('ds', domain=mesh, subdomain_data=boundaries) # Create function spaces Q_E_Rho = FiniteElement("DG", mesh.ufl_cell(), k) T_1 = FunctionSpace(mesh, 'DG', 0) Qbar_E = FiniteElement("DGT", mesh.ufl_cell(), k)
def test_eim_approximation_07(expression_type, basis_generation): """ The aim of this test is to check the interpolation of tensor valued functions. * EIM: test interpolation of a scalar function * DEIM: test interpolation of form with integrand given by the inner product of a vector valued function and some derivative of a test/trial functions of a vector function space """ class MockProblem(ParametrizedProblem): def __init__(self, V, **kwargs): ParametrizedProblem.__init__(self, "") self.V = V def name(self): return "MockProblem_07_" + expression_type + "_" + basis_generation class ParametrizedFunctionApproximation(EIMApproximation): def __init__(self, V, expression_type, basis_generation): self.V = V # Parametrized function to be interpolated mock_problem = MockProblem(V) f_expression = ( ("1/sqrt(pow(x[0]-mu[0], 2) + pow(x[1]-mu[1], 2) + 0.01)", "exp( - 2*pow(x[0]-mu[0], 2) - 2*pow(x[1]-mu[1], 2) )"), ("10.*(1-x[0])*cos(3*pi*(pi+mu[1])*(1+x[1]))*exp(-(pi+mu[0])*(1+x[0]))", "sqrt(pow(x[0]-mu[0], 2) + pow(x[1]-mu[1], 2) + 0.01)") ) tensor_element = TensorElement(V.sub(0).ufl_element()) f = ParametrizedExpression(mock_problem, f_expression, mu=(-1., -1.), element=tensor_element) # folder_prefix = os.path.join("test_eim_approximation_07_tempdir", expression_type, basis_generation) assert expression_type in ("Function", "Vector", "Matrix") if expression_type == "Function": # Call Parent constructor EIMApproximation.__init__( self, mock_problem, ParametrizedExpressionFactory(f), folder_prefix, basis_generation) elif expression_type == "Vector": v = TestFunction(V) form = inner(f, grad(v)) * dx # Call Parent constructor EIMApproximation.__init__( self, mock_problem, ParametrizedTensorFactory(form), folder_prefix, basis_generation) elif expression_type == "Matrix": u = TrialFunction(V) v = TestFunction(V) form = inner(grad(u) * f, grad(v)) * dx # Call Parent constructor EIMApproximation.__init__( self, mock_problem, ParametrizedTensorFactory(form), folder_prefix, basis_generation) else: # impossible to arrive here anyway thanks to the assert raise AssertionError("Invalid expression_type") # 1. Create the mesh for this test mesh = RectangleMesh(Point(0.1, 0.1), Point(0.9, 0.9), 20, 20) # 2. Create Finite Element space (Lagrange P1) V = VectorFunctionSpace(mesh, "Lagrange", 1) # 3. Allocate an object of the ParametrizedFunctionApproximation class parametrized_function_approximation = ParametrizedFunctionApproximation(V, expression_type, basis_generation) mu_range = [(-1., -0.01), (-1., -0.01)] parametrized_function_approximation.set_mu_range(mu_range) # 4. Prepare reduction with EIM parametrized_function_reduction_method = EIMApproximationReductionMethod(parametrized_function_approximation) parametrized_function_reduction_method.set_Nmax(50) parametrized_function_reduction_method.set_tolerance(0.) # 5. Perform the offline phase parametrized_function_reduction_method.initialize_training_set(225, sampling=EquispacedDistribution()) reduced_parametrized_function_approximation = parametrized_function_reduction_method.offline() # 6. Perform an online solve online_mu = (-1., -1.) reduced_parametrized_function_approximation.set_mu(online_mu) reduced_parametrized_function_approximation.solve() # 7. Perform an error analysis parametrized_function_reduction_method.initialize_testing_set(225) parametrized_function_reduction_method.error_analysis()
def RunJob(Tb, mu_value, path): runtimeInit = clock() tfile = File(path + '/t6t.pvd') mufile = File(path + "/mu.pvd") ufile = File(path + '/velocity.pvd') gradpfile = File(path + '/gradp.pvd') pfile = File(path + '/pstar.pvd') parameters = open(path + '/parameters', 'w', 0) vmeltfile = File(path + '/vmelt.pvd') rhofile = File(path + '/rhosolid.pvd') for name in dir(): ev = str(eval(name)) if name[0] != '_' and ev[0] != '<': parameters.write(name + ' = ' + ev + '\n') temp_values = [27. + 273, Tb + 273, 1300. + 273, 1305. + 273] dTemp = temp_values[3] - temp_values[0] temp_values = [x / dTemp for x in temp_values] # non dimensionalising temp mu_a = mu_value # this was taken from the blankenbach paper, can change.. Ep = b / dTemp mu_bot = exp(-Ep * (temp_values[3] * dTemp - 1573) + cc) * mu_a Ra = rho_0 * alpha * g * dTemp * h**3 / (kappa_0 * mu_a) w0 = rho_0 * alpha * g * dTemp * h**2 / mu_a tau = h / w0 p0 = mu_a * w0 / h print(mu_a, mu_bot, Ra, w0, p0) vslipx = 1.6e-09 / w0 vslip = Constant((vslipx, 0.0)) # nondimensional noslip = Constant((0.0, 0.0)) dt = 3.E11 / tau tEnd = 3.E13 / tau # non-dimensionalising times class PeriodicBoundary(SubDomain): def inside(self, x, on_boundary): return left(x, on_boundary) def map(self, x, y): y[0] = x[0] - MeshWidth y[1] = x[1] pbc = PeriodicBoundary() class TempExp(Expression): def eval(self, value, x): if x[1] >= LAB(x): value[0] = temp_values[0] + (temp_values[1] - temp_values[0] ) * (MeshHeight - x[1]) / (MeshHeight - LAB(x)) else: value[0] = temp_values[3] - ( temp_values[3] - temp_values[2]) * (x[1]) / (LAB(x)) class FluidTemp(Expression): def eval(self, value, x): if value[0] < 1295: value[0] = 1295 mesh = RectangleMesh(Point(0.0, 0.0), Point(MeshWidth, MeshHeight), nx, ny) Svel = VectorFunctionSpace(mesh, 'CG', 2, constrained_domain=pbc) Spre = FunctionSpace(mesh, 'CG', 1, constrained_domain=pbc) Stemp = FunctionSpace(mesh, 'CG', 1, constrained_domain=pbc) Smu = FunctionSpace(mesh, 'CG', 1, constrained_domain=pbc) Sgradp = VectorFunctionSpace(mesh, 'CG', 2, constrained_domain=pbc) Srho = FunctionSpace(mesh, 'CG', 1, constrained_domain=pbc) S0 = MixedFunctionSpace([Svel, Spre, Stemp]) u = Function(S0) v, p, T = split(u) v_t, p_t, T_t = TestFunctions(S0) T0 = interpolate(TempExp(), Stemp) muExp = Expression( 'exp(-Ep * (T_val * dTemp - 1573) + cc * x[2] / meshHeight)', Smu.ufl_element(), Ep=Ep, dTemp=dTemp, cc=cc, meshHeight=MeshHeight, T_val=T0) mu = interpolate(muExp, Smu) rhosolid = Function(Srho) deltarho = Function(Srho) v0 = Function(Svel) vmelt = Function(Svel) v_theta = (1. - theta) * v0 + theta * v T_theta = (1. - theta) * T + theta * T0 r_v = (inner(sym(grad(v_t)), 2.*mu*sym(grad(v))) \ - div(v_t)*p \ - T*v_t[1] )*dx r_p = p_t * div(v) * dx r_T = (T_t*((T - T0) \ + dt*inner(v_theta, grad(T_theta))) \ + (dt/Ra)*inner(grad(T_t), grad(T_theta)) )*dx # + k_s*(Tf-T_theta)*dt Tf = T0.interpolate(FluidTemp()) # Tf = T0.interpolate(Expression('value[0] >= 1295.0 ? value[0] : 1295.0')) # Tf.interpolate(Expression('value[0] >= 1295 ? value[0] : 1295')) # project(Expression('value[0] >= 1295 ? value[0] : 1295'), Tf) # Alex, a question for you: # can you see if there is a way to set Tf = T in regions where T >=1295 celsius # # 1295 celsius is my arbitrary choice for the LAB isotherm. In regions # where T < 1295 C, set Tf to be some constant for now, such as 1295 C. # Once we do this, then we can add in a term like that last line above where # it will only be non-zero when the solid temperature, T, is cooler than 1295 # can you do this? After this is done, we will then worry about a calculation # where we solve for Tf as a function of time in the regions cooler than 1295 C # Makes sense? If not, we can skype soon -- email me with questions # 3/19/16 r = r_v + r_p + r_T bcv0 = DirichletBC(S0.sub(0), noslip, top) bcv1 = DirichletBC(S0.sub(0), vslip, bottom) bcp0 = DirichletBC(S0.sub(1), Constant(0.0), bottom) bct0 = DirichletBC(S0.sub(2), Constant(temp_values[0]), top) bct1 = DirichletBC(S0.sub(2), Constant(temp_values[3]), bottom) bcs = [bcv0, bcv1, bcp0, bct0, bct1] t = 0 count = 0 while (t < tEnd): solve(r == 0, u, bcs) t += dt nV, nP, nT = u.split() gp = grad(nP) rhosolid = rho_0 * (1 - alpha * (nT * dTemp - 1573)) deltarho = rhosolid - rhomelt yvec = Constant((0.0, 1.0)) vmelt = nV * w0 - darcy * (gp * p0 / h - deltarho * yvec * g) if (count % 100 == 0): pfile << nP ufile << nV tfile << nT mufile << mu gradpfile << project(grad(nP), Sgradp) mufile << project(mu * mu_a, Smu) rhofile << project(rhosolid, Srho) vmeltfile << project(vmelt, Svel) count += 1 assign(T0, nT) assign(v0, nV) mu.interpolate(muExp) print('Case mu=%g, Tb=%g complete.' % (mu_a, Tb), ' Run time =', clock() - runtimeInit, 's')