def test(): class Bratu: def apply(self, u): return integrate(lambda x: -n_dot_grad(u(x)), dS) - integrate( lambda x: 2.0 * exp(u(x)), dV) def dirichlet(self, u): return [(u, Boundary())] vertices, cells = meshzoo.rectangle(0.0, 2.0, 0.0, 1.0, 101, 51) mesh = meshplex.MeshTri(vertices, cells) f, jac_u = pyfvm.discretize(Bratu(), mesh) def jacobian_solver(u0, rhs): from scipy.sparse import linalg jac = jac_u.get_linear_operator(u0) return linalg.spsolve(jac, rhs) u0 = numpy.zeros(len(vertices)) u = pyfvm.newton(lambda u: f.eval(u), jacobian_solver, u0) # import scipy.optimize # u = scipy.optimize.newton_krylov(f_eval, u0) mesh.write("out.vtk", point_data={"u": u}) return
def poisson(self, mesh, alpha, beta): from scipy.sparse import linalg # Define the problem class Poisson(LinearFvmProblem): def apply(self, u): return integrate(lambda x: - n_dot_grad(u(x)), dS) \ - integrate(lambda x: 1.0, dV) def dirichlet(self, u): return [(u, 'boundary')] linear_system = pyfvm.discretize(Poisson(), mesh) x = linalg.spsolve(linear_system.matrix, linear_system.rhs) k0 = -1 for k, coord in enumerate(mesh.node_coords): # print(coord - [0.5, 0.5, 0.0]) if numpy.linalg.norm(coord - [0.5, 0.5, 0.0]) < 1.0e-5: k0 = k break self.assertNotEqual(k0, -1) self.assertAlmostEqual(x[k0], alpha, delta=1.0e-7) x_dot_x = numpy.dot(x, mesh.control_volumes * x) self.assertAlmostEqual(x_dot_x, beta, delta=1.0e-7) return
def test(): class Bratu(object): def apply(self, u): return integrate(lambda x: -n_dot_grad(u(x)), dS) - integrate( lambda x: 2.0 * exp(u(x)), dV ) def dirichlet(self, u): return [(u, Boundary())] vertices, cells = meshzoo.rectangle(0.0, 2.0, 0.0, 1.0, 101, 51) mesh = meshplex.MeshTri(vertices, cells) f, jac_u = pyfvm.discretize(Bratu(), mesh) def jacobian_solver(u0, rhs): from scipy.sparse import linalg jac = jac_u.get_linear_operator(u0) return linalg.spsolve(jac, rhs) u0 = numpy.zeros(len(vertices)) u = pyfvm.newton(lambda u: f.eval(u), jacobian_solver, u0) # import scipy.optimize # u = scipy.optimize.newton_krylov(f_eval, u0) mesh.write("out.vtk", point_data={"u": u}) return
def test_boundaries(self): import meshzoo from scipy.sparse import linalg class Gamma0(Subdomain): def is_inside(self, x): return x[1] < 0.5 is_boundary_only = True class Gamma1(Subdomain): def is_inside(self, x): return x[1] >= 0.5 is_boundary_only = True # Define the problem class Poisson(LinearFvmProblem): def apply(self, u): return integrate(lambda x: -n_dot_grad(u(x)), dS) \ - integrate(lambda x: 1.0, dV) def dirichlet(self, u): return [ (lambda x: u(x) - 0.0, Gamma0()), (lambda x: u(x) - 1.0, Gamma1()) ] # Create mesh using meshzoo vertices, cells = meshzoo.rectangle.create_mesh( 0.0, 1.0, 0.0, 1.0, 21, 21, zigzag=True ) mesh = pyfvm.meshTri.meshTri(vertices, cells) linear_system = pyfvm.discretize(Poisson(), mesh) x = linalg.spsolve(linear_system.matrix, linear_system.rhs) import meshio meshio.write('test.vtu', mesh.node_coords, {'triangle': mesh.cells['nodes']}, point_data={'x': x}) k0 = -1 for k, coord in enumerate(mesh.node_coords): # print(coord - [0.5, 0.5, 0.0]) if numpy.linalg.norm(coord - [0.5, 0.5, 0.0]) < 1.0e-5: k0 = k break self.assertNotEqual(k0, -1) self.assertAlmostEqual(x[k0], 0.59455184740329481, delta=1.0e-7) x_dot_x = numpy.dot(x, mesh.control_volumes * x) self.assertAlmostEqual(x_dot_x, 0.42881926935620163, delta=1.0e-7) return
def solver(mesh): f, jacobian = pyfvm.discretize(problem, mesh) def jacobian_solver(u0, rhs): from scipy.sparse import linalg jac = jacobian.get_linear_operator(u0) return linalg.spsolve(jac, rhs) u0 = numpy.zeros(len(mesh.node_coords)) u = pyfvm.newton(f.eval, jacobian_solver, u0, verbose=False) return u
def test_neumann(self): import meshzoo from scipy.sparse import linalg class D1(Subdomain): def is_inside(self, x): return x[1] < 0.5 is_boundary_only = True # Define the problem class Poisson(LinearFvmProblem): def apply(self, u): return integrate(lambda x: - n_dot_grad(u(x)), dS) \ + integrate(lambda x: 3.0, dGamma) \ - integrate(lambda x: 1.0, dV) def dirichlet(self, u): return [(u, D1())] # Create mesh using meshzoo vertices, cells = meshzoo.rectangle.create_mesh( 0.0, 1.0, 0.0, 1.0, 21, 21, zigzag=True ) mesh = pyfvm.meshTri.meshTri(vertices, cells) linear_system = pyfvm.discretize(Poisson(), mesh) x = linalg.spsolve(linear_system.matrix, linear_system.rhs) k0 = -1 for k, coord in enumerate(mesh.node_coords): # print(coord - [0.5, 0.5, 0.0]) if numpy.linalg.norm(coord - [0.5, 0.5, 0.0]) < 1.0e-5: k0 = k break self.assertNotEqual(k0, -1) self.assertAlmostEqual(x[k0], -1.3249459366260112, delta=1.0e-7) x_dot_x = numpy.dot(x, mesh.control_volumes * x) self.assertAlmostEqual(x_dot_x, 3.1844205150779601, delta=1.0e-7) return
def test_singular_perturbation(self): import meshzoo from scipy.sparse import linalg # Define the problem class Poisson(LinearFvmProblem): def apply(self, u): return integrate(lambda x: - 1.0e-2 * n_dot_grad(u(x)), dS) \ + integrate(lambda x: u(x), dV) \ - integrate(lambda x: 1.0, dV) def dirichlet(self, u): return [(u, 'boundary')] # Create mesh using meshzoo vertices, cells = meshzoo.rectangle.create_mesh( 0.0, 1.0, 0.0, 1.0, 21, 21, zigzag=True ) mesh = pyfvm.meshTri.meshTri(vertices, cells) linear_system = pyfvm.discretize(Poisson(), mesh) x = linalg.spsolve(linear_system.matrix, linear_system.rhs) k0 = -1 for k, coord in enumerate(mesh.node_coords): # print(coord - [0.5, 0.5, 0.0]) if numpy.linalg.norm(coord - [0.5, 0.5, 0.0]) < 1.0e-5: k0 = k break self.assertNotEqual(k0, -1) self.assertAlmostEqual(x[k0], 0.97335485230869123, delta=1.0e-7) x_dot_x = numpy.dot(x, mesh.control_volumes * x) self.assertAlmostEqual(x_dot_x, 0.49724636865618776, delta=1.0e-7) return
def test_convection(self): import meshzoo from scipy.sparse import linalg # Define the problem class Poisson(LinearFvmProblem): def apply(self, u): a = sympy.Matrix([2, 1, 0]) return integrate(lambda x: - n_dot_grad(u(x)) + dot(a.T, n) * u(x), dS) - \ integrate(lambda x: 1.0, dV) def dirichlet(self, u): return [(u, 'boundary')] # Create mesh using meshzoo vertices, cells = meshzoo.rectangle.create_mesh( 0.0, 1.0, 0.0, 1.0, 21, 21, zigzag=True ) mesh = pyfvm.meshTri.meshTri(vertices, cells) linear_system = pyfvm.discretize(Poisson(), mesh) x = linalg.spsolve(linear_system.matrix, linear_system.rhs) k0 = -1 for k, coord in enumerate(mesh.node_coords): if numpy.linalg.norm(coord - [0.5, 0.5, 0.0]) < 1.0e-5: k0 = k break self.assertNotEqual(k0, -1) self.assertAlmostEqual(x[k0], 0.07041709172659899, delta=1.0e-7) x_dot_x = numpy.dot(x, mesh.control_volumes * x) self.assertAlmostEqual(x_dot_x, 0.0016076431631658172, delta=1.0e-7) return
# 25, 25, 25 # ) # mesh = pyfvm.meshTetra.meshTetra(vertices, cells) # vertices, cells = meshzoo.rectangle.create_mesh( # 0.0, 2.0, # 0.0, 1.0, # 401, 201, # zigzag=True # ) # mesh = pyfvm.meshTri.meshTri(vertices, cells) import mshr import dolfin h = 2.5e-2 # cell_size = 2 * pi / num_boundary_points c = mshr.Circle(dolfin.Point(0., 0., 0.), 1, int(2*pi / h)) # cell_size = 2 * bounding_box_radius / res m = mshr.generate_mesh(c, 2.0 / h) coords = m.coordinates() coords = numpy.c_[coords, numpy.zeros(len(coords))] mesh = pyfvm.meshTri.meshTri(coords, m.cells()) linear_system = pyfvm.discretize(Poisson(), mesh) ml = pyamg.ruge_stuben_solver(linear_system.matrix) x = ml.solve(linear_system.rhs, tol=1e-10) # from scipy.sparse import linalg # x = linalg.spsolve(linear_system.matrix, linear_system.rhs) mesh.write('out.vtu', point_data={'x': x})
def perform_convergence_tests( problem, exact_sol, get_mesh, rng, verbose=False ): n = len(rng) H = numpy.empty(n) error_norm_1 = numpy.empty(n) order_1 = numpy.empty(n-1) error_norm_inf = numpy.empty(n) order_inf = numpy.empty(n-1) if verbose: print(79 * '-') print('k' + 5*' ' + 'num verts' + 4*' ' + 'max edge length' + 4*' ' + '||error||_1' + 8*' ' + '||error||_inf' ) print(38*' ' + '(order)' + 12*' ' + '(order)') print(79 * '-') # Add "zero" to all entities. This later gets translated into # np.zeros with the appropriate length, making sure that scalar # terms in the lambda expression correctly return np.arrays. zero = sympy.Symbol('zero') x = sympy.DeferredVector('x') # See <http://docs.sympy.org/dev/modules/utilities/lambdify.html>. array2array = [{'ImmutableMatrix': numpy.array}, 'numpy'] exact_eval = sympy.lambdify((x, zero), exact_sol(x), modules=array2array) for k in rng: mesh = get_mesh(k) H[k] = max(mesh.edge_lengths) linear_system = pyfvm.discretize(problem, mesh) # x = linalg.spsolve(linear_system.matrix, linear_system.rhs) ml = pyamg.ruge_stuben_solver(linear_system.matrix) x = ml.solve(linear_system.rhs, tol=1e-10) zero = numpy.zeros(len(mesh.node_coords)) error = x - exact_eval(mesh.node_coords.T, zero) # import meshio # meshio.write( # 'sol%d.vtu' % k, # mesh.node_coords, {'triangle': mesh.cells['nodes']}, # point_data={'x': x, 'error': error}, # ) error_norm_1[k] = numpy.sum(abs(mesh.control_volumes * error)) error_norm_inf[k] = max(abs(error)) # numerical orders of convergence if k > 0: order_1[k-1] = \ numpy.log(error_norm_1[k-1] / error_norm_1[k]) / \ numpy.log(H[k-1] / H[k]) order_inf[k-1] = \ numpy.log(error_norm_inf[k-1] / error_norm_inf[k]) / \ numpy.log(H[k-1] / H[k]) if verbose: print print((38*' ' + '%0.5f' + 12*' ' + '%0.5f') % (order_1[k-1], order_inf[k-1]) ) print if verbose: num_nodes = len(mesh.control_volumes) print('%2d %5.3e %0.10e %0.10e %0.10e' % (k, num_nodes, H[k], error_norm_1[k], error_norm_inf[k]) ) return H, error_norm_1, error_norm_inf, order_1, order_inf
import pyfvm from pyfvm.form_language import * import meshzoo from scipy.sparse import linalg class DC(LinearFvmProblem): def apply(self, u): a = sympy.Matrix([2, 1, 0]) return \ integrate(lambda x: -n_dot_grad(u(x)) + dot(a.T, n) * u(x), dS) - \ integrate(lambda x: 1.0, dV) def dirichlet(self, u): return [(u, 'boundary')] vertices, cells = meshzoo.rectangle.create_mesh( 0.0, 1.0, 0.0, 1.0, 51, 51, zigzag=True ) mesh = pyfvm.meshTri.meshTri(vertices, cells) linear_system = pyfvm.discretize(DC(), mesh) x = linalg.spsolve(linear_system.matrix, linear_system.rhs) mesh.write('out.vtu', point_data={'x': x})
# import meshzoo import pyfvm from pyfvm.form_language import * from scipy.sparse import linalg class Singular(LinearFvmProblem): def apply(self, u): return integrate(lambda x: - 1.0e-2 * n_dot_grad(u(x)), dS) \ + integrate(u, dV) \ - integrate(lambda x: 1.0, dV) def dirichlet(self, u): return [(u, 'boundary')] # Create mesh using meshzoo vertices, cells = meshzoo.rectangle.create_mesh( 0.0, 1.0, 0.0, 1.0, 51, 51, zigzag=True ) mesh = pyfvm.meshTri.meshTri(vertices, cells) linear_system = pyfvm.discretize(Singular(), mesh) x = linalg.spsolve(linear_system.matrix, linear_system.rhs) mesh.write('out.vtu', point_data={'x': x})