op2.init(**opt) # Set up finite element identity problem E = FiniteElement("Lagrange", "triangle", 1) v = TestFunction(E) u = TrialFunction(E) f = Coefficient(E) a = v*u*dx L = v*f*dx # Generate code for mass and rhs assembly. mass, = compile_form(a, "mass") rhs, = compile_form(L, "rhs") # Set up simulation data structures NUM_ELE = 2 NUM_NODES = 4 valuetype = np.float64 nodes = op2.Set(NUM_NODES, 1, "nodes") vnodes = op2.Set(NUM_NODES, 2, "vnodes") elements = op2.Set(NUM_ELE, 1, "elements") elem_node_map = np.asarray([ 0, 1, 3, 2, 3, 1 ], dtype=np.uint32) elem_node = op2.Map(elements, nodes, 3, elem_node_map, "elem_node") elem_vnode = op2.Map(elements, vnodes, 3, elem_node_map, "elem_vnode")
def main(opt): # Set up finite element identity problem E = FiniteElement("Lagrange", "triangle", 1) v = TestFunction(E) u = TrialFunction(E) f = Coefficient(E) a = v * u * dx L = v * f * dx # Generate code for mass and rhs assembly. mass, = compile_form(a, "mass") rhs, = compile_form(L, "rhs") # Set up simulation data structures NUM_ELE = 2 NUM_NODES = 4 valuetype = np.float64 nodes = op2.Set(NUM_NODES, "nodes") elements = op2.Set(NUM_ELE, "elements") elem_node_map = np.array([0, 1, 3, 2, 3, 1], dtype=np.uint32) elem_node = op2.Map(elements, nodes, 3, elem_node_map, "elem_node") sparsity = op2.Sparsity((nodes, nodes), (elem_node, elem_node), "sparsity") mat = op2.Mat(sparsity, valuetype, "mat") coord_vals = np.array([(0.0, 0.0), (2.0, 0.0), (1.0, 1.0), (0.0, 1.5)], dtype=valuetype) coords = op2.Dat(nodes ** 2, coord_vals, valuetype, "coords") f = op2.Dat(nodes, np.array([1.0, 2.0, 3.0, 4.0]), valuetype, "f") b = op2.Dat(nodes, np.zeros(NUM_NODES, dtype=valuetype), valuetype, "b") x = op2.Dat(nodes, np.zeros(NUM_NODES, dtype=valuetype), valuetype, "x") # Assemble and solve op2.par_loop(mass, elements, mat(op2.INC, (elem_node[op2.i[0]], elem_node[op2.i[1]])), coords(op2.READ, elem_node, flatten=True)) op2.par_loop(rhs, elements, b(op2.INC, elem_node[op2.i[0]]), coords(op2.READ, elem_node, flatten=True), f(op2.READ, elem_node)) solver = op2.Solver() solver.solve(mat, x, b) # Print solution if opt['print_output']: print "Expected solution: %s" % f.data print "Computed solution: %s" % x.data # Save output (if necessary) if opt['return_output']: return f.data, x.data if opt['save_output']: import pickle with open("mass2d.out", "w") as out: pickle.dump((f.data, x.data), out)
bdry = op2.Dat(b_nodes, 1, bdry_vals, np.float64, "bdry") sparsity = op2.Sparsity((elem_node, elem_node), "sparsity") mat = op2.Mat(sparsity, np.float64, "mat") # Set up finite element problem V = FiniteElement("Lagrange", "interval", 1) u = Coefficient(V) u_next = TrialFunction(V) v = TestFunction(V) a = (dot(u,grad(u_next))*v + nu*grad(u_next)*grad(v))*dx L = v*u*dx burgers, = compile_form(a, "burgers") rhs, = compile_form(L, "rhs") # Initial condition i_cond_code =""" void i_cond(double *c, double *t) { double pi = 3.14159265358979; *t = *c*2; } """ i_cond = op2.Kernel(i_cond_code, "i_cond") op2.par_loop(i_cond, nodes,
# Set up finite element problem E = FiniteElement("Lagrange", "triangle", 1) v = TestFunction(E) u = TrialFunction(E) f = Coefficient(E) g = Coefficient(E) a = dot(grad(v,), grad(u)) * dx L = v * f * dx # Generate code for Laplacian and rhs assembly. laplacian, = compile_form(a, "laplacian") rhs, = compile_form(L, "rhs") # Set up simulation data structures NUM_ELE = 8 NUM_NODES = 9 NUM_BDRY_ELE = 2 NUM_BDRY_NODE = 6 valuetype = np.float64 nodes = op2.Set(NUM_NODES, "nodes") elements = op2.Set(NUM_ELE, "elements") bdry_nodes = op2.Set(NUM_BDRY_NODE, "boundary_nodes") elem_node_map = np.asarray([0, 1, 4, 4, 3, 0, 1, 2, 5, 5, 4, 1, 3, 4, 7, 7, 6,
q = TestFunction(T) t = Coefficient(T) u = Coefficient(V) diffusivity = 0.1 M = p * q * dx d = dt * (diffusivity * dot(grad(q), grad(p)) - dot(grad(q), u) * p) * dx a = M + 0.5 * d L = action(M - 0.5 * d, t) # Generate code for mass and rhs assembly. lhs, = compile_form(a, "lhs") rhs, = compile_form(L, "rhs") # Set up simulation data structures valuetype = np.float64 nodes, coords, elements, elem_node = read_triangle(opt['mesh']) num_nodes = nodes.size sparsity = op2.Sparsity((nodes, nodes), (elem_node, elem_node), "sparsity") mat = op2.Mat(sparsity, valuetype, "mat") tracer_vals = np.zeros(num_nodes, dtype=valuetype) tracer = op2.Dat(nodes, tracer_vals, valuetype, "tracer")
def main(opt): # Set up finite element problem dt = 0.0001 T = FiniteElement("Lagrange", "triangle", 1) V = VectorElement("Lagrange", "triangle", 1) p = TrialFunction(T) q = TestFunction(T) t = Coefficient(T) u = Coefficient(V) a = Coefficient(T) diffusivity = 0.1 M = p * q * dx adv_rhs = (q * t + dt * dot(grad(q), u) * t) * dx d = -dt * diffusivity * dot(grad(q), grad(p)) * dx diff = M - 0.5 * d diff_rhs = action(M + 0.5 * d, t) # Generate code for mass and rhs assembly. adv, = compile_form(M, "adv") adv_rhs, = compile_form(adv_rhs, "adv_rhs") diff, = compile_form(diff, "diff") diff_rhs, = compile_form(diff_rhs, "diff_rhs") # Set up simulation data structures valuetype = np.float64 nodes, vnodes, coords, elements, elem_node, elem_vnode = read_triangle(opt['mesh']) num_nodes = nodes.size sparsity = op2.Sparsity((elem_node, elem_node), "sparsity") if opt['advection']: adv_mat = op2.Mat(sparsity, valuetype, "adv_mat") op2.par_loop(adv, elements(3, 3), adv_mat((elem_node[op2.i[0]], elem_node[op2.i[1]]), op2.INC), coords(elem_vnode, op2.READ)) if opt['diffusion']: diff_mat = op2.Mat(sparsity, valuetype, "diff_mat") op2.par_loop(diff, elements(3, 3), diff_mat((elem_node[op2.i[0]], elem_node[op2.i[1]]), op2.INC), coords(elem_vnode, op2.READ)) tracer_vals = np.zeros(num_nodes, dtype=valuetype) tracer = op2.Dat(nodes, tracer_vals, valuetype, "tracer") b_vals = np.zeros(num_nodes, dtype=valuetype) b = op2.Dat(nodes, b_vals, valuetype, "b") velocity_vals = np.asarray([1.0, 0.0] * num_nodes, dtype=valuetype) velocity = op2.Dat(vnodes, velocity_vals, valuetype, "velocity") # Set initial condition i_cond_code = """void i_cond(double *c, double *t) { double A = 0.1; // Normalisation double D = 0.1; // Diffusivity double pi = 3.14159265358979; double x = c[0]-(0.45+%(T)f); double y = c[1]-0.5; double r2 = x*x+y*y; *t = A*(exp(-r2/(4*D*%(T)f))/(4*pi*D*%(T)f)); } """ T = 0.01 i_cond = op2.Kernel(i_cond_code % {'T': T}, "i_cond") op2.par_loop(i_cond, nodes, coords(op2.IdentityMap, op2.READ), tracer(op2.IdentityMap, op2.WRITE)) # Assemble and solve if opt['visualize']: vis_coords = np.asarray([[x, y, 0.0] for x, y in coords.data_ro], dtype=np.float64) import viper v = viper.Viper(x=viper_shape(tracer.data_ro), coordinates=vis_coords, cells=elem_node.values) solver = op2.Solver() while T < 0.015: # Advection if opt['advection']: b.zero() op2.par_loop(adv_rhs, elements(3), b(elem_node[op2.i[0]], op2.INC), coords(elem_vnode, op2.READ), tracer(elem_node, op2.READ), velocity(elem_vnode, op2.READ)) solver.solve(adv_mat, tracer, b) # Diffusion if opt['diffusion']: b.zero() op2.par_loop(diff_rhs, elements(3), b(elem_node[op2.i[0]], op2.INC), coords(elem_vnode, op2.READ), tracer(elem_node, op2.READ)) solver.solve(diff_mat, tracer, b) if opt['visualize']: v.update(viper_shape(tracer.data_ro)) T = T + dt if opt['print_output'] or opt['test_output']: analytical_vals = np.zeros(num_nodes, dtype=valuetype) analytical = op2.Dat(nodes, analytical_vals, valuetype, "analytical") i_cond = op2.Kernel(i_cond_code % {'T': T}, "i_cond") op2.par_loop(i_cond, nodes, coords(op2.IdentityMap, op2.READ), analytical(op2.IdentityMap, op2.WRITE)) # Print error w.r.t. analytical solution if opt['print_output']: print "Expected - computed solution: %s" % tracer.data - analytical.data if opt['test_output']: l2norm = dot(t - a, t - a) * dx l2_kernel, = compile_form(l2norm, "error_norm") result = op2.Global(1, [0.0]) op2.par_loop(l2_kernel, elements, result(op2.INC), coords(elem_vnode,op2.READ), tracer(elem_node,op2.READ), analytical(elem_node,op2.READ) ) with open("adv_diff.%s.out" % os.path.split(opt['mesh'])[-1], "w") as out: out.write(str(result.data[0]) + "\n")
def run(diffusivity, current_time, dt, endtime, **kwargs): op2.init(**kwargs) # Set up finite element problem T = FiniteElement("Lagrange", "triangle", 1) V = VectorElement("Lagrange", "triangle", 1) p = TrialFunction(T) q = TestFunction(T) t = Coefficient(T) u = Coefficient(V) diffusivity = 0.1 M = p * q * dx adv_rhs = (q * t + dt * dot(grad(q), u) * t) * dx d = -dt * diffusivity * dot(grad(q), grad(p)) * dx diff_matrix = M - 0.5 * d diff_rhs = action(M + 0.5 * d, t) # Generate code for mass and rhs assembly. mass = compile_form(M, "mass")[0] adv_rhs = compile_form(adv_rhs, "adv_rhs")[0] diff_matrix = compile_form(diff_matrix, "diff_matrix")[0] diff_rhs = compile_form(diff_rhs, "diff_rhs")[0] # Set up simulation data structures valuetype = np.float64 nodes, coords, elements, elem_node = read_triangle(kwargs['mesh']) num_nodes = nodes.size sparsity = op2.Sparsity((elem_node, elem_node), 1, "sparsity") mat = op2.Mat(sparsity, valuetype, "mat") tracer_vals = np.asarray([0.0] * num_nodes, dtype=valuetype) tracer = op2.Dat(nodes, 1, tracer_vals, valuetype, "tracer") b_vals = np.asarray([0.0] * num_nodes, dtype=valuetype) b = op2.Dat(nodes, 1, b_vals, valuetype, "b") velocity_vals = np.asarray([1.0, 0.0] * num_nodes, dtype=valuetype) velocity = op2.Dat(nodes, 2, velocity_vals, valuetype, "velocity") # Set initial condition i_cond_code = """ void i_cond(double *c, double *t) { double i_t = 0.01; // Initial time double A = 0.1; // Normalisation double D = 0.1; // Diffusivity double pi = 3.141459265358979; double x = c[0]-0.5; double y = c[1]-0.5; double r = sqrt(x*x+y*y); if (r<0.25) *t = A*(exp((-(r*r))/(4*D*i_t))/(4*pi*D*i_t)); else *t = 0.0; } """ i_cond = op2.Kernel(i_cond_code, "i_cond") op2.par_loop(i_cond, nodes, coords(op2.IdentityMap, op2.READ), tracer(op2.IdentityMap, op2.WRITE)) zero_dat_code = """ void zero_dat(double *dat) { *dat = 0.0; } """ zero_dat = op2.Kernel(zero_dat_code, "zero_dat") # Assemble and solve have_advection = True have_diffusion = True def timestep_iteration(): # Advection if have_advection: tic('advection') tic('assembly') mat.zero() op2.par_loop( mass, elements(3, 3), mat((elem_node[op2.i[0]], elem_node[op2.i[1]]), op2.INC), coords(elem_node, op2.READ)) op2.par_loop(zero_dat, nodes, b(op2.IdentityMap, op2.WRITE)) op2.par_loop(adv_rhs, elements(3), b(elem_node[op2.i[0]], op2.INC), coords(elem_node, op2.READ), tracer(elem_node, op2.READ), velocity(elem_node, op2.READ)) toc('assembly') tic('solve') op2.solve(mat, tracer, b) toc('solve') toc('advection') # Diffusion if have_diffusion: tic('diffusion') tic('assembly') mat.zero() op2.par_loop( diff_matrix, elements(3, 3), mat((elem_node[op2.i[0]], elem_node[op2.i[1]]), op2.INC), coords(elem_node, op2.READ)) op2.par_loop(zero_dat, nodes, b(op2.IdentityMap, op2.WRITE)) op2.par_loop(diff_rhs, elements(3), b(elem_node[op2.i[0]], op2.INC), coords(elem_node, op2.READ), tracer(elem_node, op2.READ)) toc('assembly') tic('solve') op2.solve(mat, tracer, b) toc('solve') toc('diffusion') # Perform 1 iteration to warm up plan cache then reset initial condition timestep_iteration() op2.par_loop(i_cond, nodes, coords(op2.IdentityMap, op2.READ), tracer(op2.IdentityMap, op2.WRITE)) reset() # Timed iteration t1 = clock() while current_time < endtime: timestep_iteration() current_time += dt runtime = clock() - t1 print "/fluidity :: %f" % runtime summary('profile_pyop2_%s_%s.csv' % (opt['mesh'].split('/')[-1], opt['backend']))
def main(opt): # Set up finite element problem E = FiniteElement("Lagrange", "triangle", 1) v = TestFunction(E) u = TrialFunction(E) f = Coefficient(E) a = dot(grad(v,), grad(u)) * dx L = v * f * dx # Generate code for Laplacian and rhs assembly. laplacian, = compile_form(a, "laplacian") rhs, = compile_form(L, "rhs") # Set up simulation data structures NUM_ELE = 8 NUM_NODES = 9 NUM_BDRY_NODE = 6 valuetype = np.float64 nodes = op2.Set(NUM_NODES, "nodes") elements = op2.Set(NUM_ELE, "elements") bdry_nodes = op2.Set(NUM_BDRY_NODE, "boundary_nodes") elem_node_map = np.array([0, 1, 4, 4, 3, 0, 1, 2, 5, 5, 4, 1, 3, 4, 7, 7, 6, 3, 4, 5, 8, 8, 7, 4], dtype=np.uint32) elem_node = op2.Map(elements, nodes, 3, elem_node_map, "elem_node") bdry_node_node_map = np.array([0, 1, 2, 6, 7, 8], dtype=valuetype) bdry_node_node = op2.Map(bdry_nodes, nodes, 1, bdry_node_node_map, "bdry_node_node") sparsity = op2.Sparsity((nodes, nodes), (elem_node, elem_node), "sparsity") mat = op2.Mat(sparsity, valuetype, "mat") coord_vals = np.array([(0.0, 0.0), (0.5, 0.0), (1.0, 0.0), (0.0, 0.5), (0.5, 0.5), (1.0, 0.5), (0.0, 1.0), (0.5, 1.0), (1.0, 1.0)], dtype=valuetype) coords = op2.Dat(nodes ** 2, coord_vals, valuetype, "coords") u_vals = np.array([1.0, 1.0, 1.0, 1.5, 1.5, 1.5, 2.0, 2.0, 2.0]) f = op2.Dat(nodes, np.zeros(NUM_NODES, dtype=valuetype), valuetype, "f") b = op2.Dat(nodes, np.zeros(NUM_NODES, dtype=valuetype), valuetype, "b") x = op2.Dat(nodes, np.zeros(NUM_NODES, dtype=valuetype), valuetype, "x") u = op2.Dat(nodes, u_vals, valuetype, "u") bdry_vals = np.array([1.0, 1.0, 1.0, 2.0, 2.0, 2.0], dtype=valuetype) bdry = op2.Dat(bdry_nodes, bdry_vals, valuetype, "bdry") # Assemble matrix and rhs op2.par_loop(laplacian, elements, mat(op2.INC, (elem_node[op2.i[0]], elem_node[op2.i[1]])), coords(op2.READ, elem_node, flatten=True)) op2.par_loop(rhs, elements, b(op2.INC, elem_node[op2.i[0]]), coords(op2.READ, elem_node, flatten=True), f(op2.READ, elem_node)) # Apply strong BCs mat.zero_rows([0, 1, 2, 6, 7, 8], 1.0) strongbc_rhs = op2.Kernel(""" void strongbc_rhs(double *val, double *target) { *target = *val; } """, "strongbc_rhs") op2.par_loop(strongbc_rhs, bdry_nodes, bdry(op2.READ), b(op2.WRITE, bdry_node_node[0])) solver = op2.Solver(ksp_type='gmres') solver.solve(mat, x, b) # Print solution if opt['print_output']: print "Expected solution: %s" % u.data print "Computed solution: %s" % x.data # Save output (if necessary) if opt['return_output']: return u.data, x.data if opt['save_output']: import pickle with open("laplace.out", "w") as out: pickle.dump((u.data, x.data), out)
def main(opt): # Set up finite element problem dt = 0.0001 T = FiniteElement("Lagrange", "triangle", 1) V = VectorElement("Lagrange", "triangle", 1) p = TrialFunction(T) q = TestFunction(T) t = Coefficient(T) u = Coefficient(V) a = Coefficient(T) diffusivity = 0.1 M = p * q * dx adv_rhs = (q * t + dt * dot(grad(q), u) * t) * dx d = -dt * diffusivity * dot(grad(q), grad(p)) * dx diff = M - 0.5 * d diff_rhs = action(M + 0.5 * d, t) # Generate code for mass and rhs assembly. adv, = compile_form(M, "adv") adv_rhs, = compile_form(adv_rhs, "adv_rhs") diff, = compile_form(diff, "diff") diff_rhs, = compile_form(diff_rhs, "diff_rhs") # Set up simulation data structures valuetype = np.float64 f = gzip.open(opt['mesh'] + '.' + str(op2.MPI.comm.rank) + '.pickle.gz') elements, nodes, elem_node, coords = load(f) f.close() coords = op2.Dat(nodes ** 2, coords.data, np.float64, "dcoords") num_nodes = nodes.total_size sparsity = op2.Sparsity((nodes, nodes), (elem_node, elem_node), "sparsity") if opt['advection']: adv_mat = op2.Mat(sparsity, valuetype, "adv_mat") op2.par_loop(adv, elements, adv_mat(op2.INC, (elem_node[op2.i[0]], elem_node[op2.i[1]])), coords(op2.READ, elem_node)) if opt['diffusion']: diff_mat = op2.Mat(sparsity, valuetype, "diff_mat") op2.par_loop(diff, elements, diff_mat(op2.INC, (elem_node[op2.i[0]], elem_node[op2.i[1]])), coords(op2.READ, elem_node)) tracer_vals = np.zeros(num_nodes, dtype=valuetype) tracer = op2.Dat(nodes, tracer_vals, valuetype, "tracer") b_vals = np.zeros(num_nodes, dtype=valuetype) b = op2.Dat(nodes, b_vals, valuetype, "b") velocity_vals = np.asarray([1.0, 0.0] * num_nodes, dtype=valuetype) velocity = op2.Dat(nodes ** 2, velocity_vals, valuetype, "velocity") # Set initial condition i_cond_code = """void i_cond(double *c, double *t) { double A = 0.1; // Normalisation double D = 0.1; // Diffusivity double pi = 3.14159265358979; double x = c[0]-(0.45+%(T)f); double y = c[1]-0.5; double r2 = x*x+y*y; *t = A*(exp(-r2/(4*D*%(T)f))/(4*pi*D*%(T)f)); } """ T = 0.01 i_cond = op2.Kernel(i_cond_code % {'T': T}, "i_cond") op2.par_loop(i_cond, nodes, coords(op2.READ), tracer(op2.WRITE)) # Assemble and solve solver = op2.Solver() while T < 0.015: # Advection if opt['advection']: b.zero() op2.par_loop(adv_rhs, elements, b(op2.INC, elem_node[op2.i[0]]), coords(op2.READ, elem_node), tracer(op2.READ, elem_node), velocity(op2.READ, elem_node)) solver.solve(adv_mat, tracer, b) # Diffusion if opt['diffusion']: b.zero() op2.par_loop(diff_rhs, elements, b(op2.INC, elem_node[op2.i[0]]), coords(op2.READ, elem_node), tracer(op2.READ, elem_node)) solver.solve(diff_mat, tracer, b) T = T + dt if opt['print_output'] or opt['test_output']: analytical_vals = np.zeros(num_nodes, dtype=valuetype) analytical = op2.Dat(nodes, analytical_vals, valuetype, "analytical") i_cond = op2.Kernel(i_cond_code % {'T': T}, "i_cond") op2.par_loop(i_cond, nodes, coords(op2.READ), analytical(op2.WRITE)) # Print error w.r.t. analytical solution if opt['print_output']: print "Rank: %d Expected - computed solution: %s" % \ (op2.MPI.comm.rank, tracer.data - analytical.data) if opt['test_output']: l2norm = dot(t - a, t - a) * dx l2_kernel, = compile_form(l2norm, "error_norm") result = op2.Global(1, [0.0]) op2.par_loop(l2_kernel, elements, result(op2.INC), coords(op2.READ, elem_node), tracer(op2.READ, elem_node), analytical(op2.READ, elem_node) ) if op2.MPI.comm.rank == 0: with open("adv_diff_mpi.%s.out" % os.path.split(opt['mesh'])[-1], "w") as out: out.write(str(result.data[0])) else: # hack to prevent mpi communication dangling result.data
def main(opt): # Set up finite element problem E = FiniteElement("Lagrange", "triangle", 1) v = TestFunction(E) u = TrialFunction(E) f = Coefficient(E) g = Coefficient(E) a = dot(grad(v,), grad(u)) * dx L = v * f * dx + v * g * ds(2) # Generate code for Laplacian and rhs assembly. laplacian, = compile_form(a, "laplacian") rhs, weak = compile_form(L, "rhs") # Set up simulation data structures NUM_ELE = 8 NUM_NODES = 9 NUM_BDRY_ELE = 2 NUM_BDRY_NODE = 3 valuetype = np.float64 nodes = op2.Set(NUM_NODES, "nodes") elements = op2.Set(NUM_ELE, "elements") # Elements that Weak BC will be assembled over top_bdry_elements = op2.Set(NUM_BDRY_ELE, "top_boundary_elements") # Nodes that Strong BC will be applied over bdry_nodes = op2.Set(NUM_BDRY_NODE, "boundary_nodes") elem_node_map = np.array([0, 1, 4, 4, 3, 0, 1, 2, 5, 5, 4, 1, 3, 4, 7, 7, 6, 3, 4, 5, 8, 8, 7, 4], dtype=np.uint32) elem_node = op2.Map(elements, nodes, 3, elem_node_map, "elem_node") top_bdry_elem_node_map = np.array([7, 6, 3, 8, 7, 4], dtype=valuetype) top_bdry_elem_node = op2.Map(top_bdry_elements, nodes, 3, top_bdry_elem_node_map, "top_bdry_elem_node") bdry_node_node_map = np.array([0, 1, 2], dtype=valuetype) bdry_node_node = op2.Map( bdry_nodes, nodes, 1, bdry_node_node_map, "bdry_node_node") sparsity = op2.Sparsity((nodes, nodes), (elem_node, elem_node), "sparsity") mat = op2.Mat(sparsity, valuetype, "mat") coord_vals = np.array([(0.0, 0.0), (0.5, 0.0), (1.0, 0.0), (0.0, 0.5), (0.5, 0.5), (1.0, 0.5), (0.0, 1.0), (0.5, 1.0), (1.0, 1.0)], dtype=valuetype) coords = op2.Dat(nodes ** 2, coord_vals, valuetype, "coords") u_vals = np.array([1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0]) f = op2.Dat(nodes, np.zeros(NUM_NODES, dtype=valuetype), valuetype, "f") b = op2.Dat(nodes, np.zeros(NUM_NODES, dtype=valuetype), valuetype, "b") x = op2.Dat(nodes, np.zeros(NUM_NODES, dtype=valuetype), valuetype, "x") u = op2.Dat(nodes, u_vals, valuetype, "u") bdry = op2.Dat(bdry_nodes, np.ones(3, dtype=valuetype), valuetype, "bdry") # This isn't perfect, defining the boundary gradient on more nodes than are on # the boundary is couter-intuitive bdry_grad_vals = np.asarray([2.0] * 9, dtype=valuetype) bdry_grad = op2.Dat(nodes, bdry_grad_vals, valuetype, "gradient") facet = op2.Global(1, 2, np.uint32, "facet") # If a form contains multiple integrals with differing coefficients, FFC # generates kernels that take all the coefficients of the entire form (not # only the respective integral) as arguments. Arguments that correspond to # forms that are not used in that integral are simply not referenced. # We therefore need a dummy argument in place of the coefficient that is not # used in the par_loop for OP2 to generate the correct kernel call. # Assemble matrix and rhs op2.par_loop(laplacian, elements, mat(op2.INC, (elem_node[op2.i[0]], elem_node[op2.i[1]])), coords(op2.READ, elem_node, flatten=True)) op2.par_loop(rhs, elements, b(op2.INC, elem_node[op2.i[0]]), coords(op2.READ, elem_node, flatten=True), f(op2.READ, elem_node), bdry_grad(op2.READ, elem_node)) # argument ignored # Apply weak BC op2.par_loop(weak, top_bdry_elements, b(op2.INC, top_bdry_elem_node[op2.i[0]]), coords(op2.READ, top_bdry_elem_node, flatten=True), f(op2.READ, top_bdry_elem_node), # argument ignored bdry_grad(op2.READ, top_bdry_elem_node), facet(op2.READ)) # Apply strong BC mat.zero_rows([0, 1, 2], 1.0) strongbc_rhs = op2.Kernel(""" void strongbc_rhs(double *val, double *target) { *target = *val; } """, "strongbc_rhs") op2.par_loop(strongbc_rhs, bdry_nodes, bdry(op2.READ), b(op2.WRITE, bdry_node_node[0])) solver = op2.Solver(ksp_type='gmres') solver.solve(mat, x, b) # Print solution if opt['return_output']: return u.data, x.data if opt['print_output']: print "Expected solution: %s" % u.data print "Computed solution: %s" % x.data # Save output (if necessary) if opt['save_output']: import pickle with open("weak_bcs.out", "w") as out: pickle.dump((u.data, x.data), out)
def run(diffusivity, current_time, dt, endtime, **kwargs): op2.init(**kwargs) # Set up finite element problem T = FiniteElement("Lagrange", "triangle", 1) V = VectorElement("Lagrange", "triangle", 1) p = TrialFunction(T) q = TestFunction(T) t = Coefficient(T) u = Coefficient(V) diffusivity = 0.1 M = p * q * dx adv_rhs = (q * t + dt * dot(grad(q), u) * t) * dx d = -dt * diffusivity * dot(grad(q), grad(p)) * dx diff_matrix = M - 0.5 * d diff_rhs = action(M + 0.5 * d, t) # Generate code for mass and rhs assembly. mass = compile_form(M, "mass")[0] adv_rhs = compile_form(adv_rhs, "adv_rhs")[0] diff_matrix = compile_form(diff_matrix, "diff_matrix")[0] diff_rhs = compile_form(diff_rhs, "diff_rhs")[0] # Set up simulation data structures valuetype = np.float64 nodes, coords, elements, elem_node = read_triangle(kwargs["mesh"]) num_nodes = nodes.size sparsity = op2.Sparsity((elem_node, elem_node), 1, "sparsity") mat = op2.Mat(sparsity, valuetype, "mat") tracer_vals = np.asarray([0.0] * num_nodes, dtype=valuetype) tracer = op2.Dat(nodes, 1, tracer_vals, valuetype, "tracer") b_vals = np.asarray([0.0] * num_nodes, dtype=valuetype) b = op2.Dat(nodes, 1, b_vals, valuetype, "b") velocity_vals = np.asarray([1.0, 0.0] * num_nodes, dtype=valuetype) velocity = op2.Dat(nodes, 2, velocity_vals, valuetype, "velocity") # Set initial condition i_cond_code = """ void i_cond(double *c, double *t) { double i_t = 0.01; // Initial time double A = 0.1; // Normalisation double D = 0.1; // Diffusivity double pi = 3.141459265358979; double x = c[0]-0.5; double y = c[1]-0.5; double r = sqrt(x*x+y*y); if (r<0.25) *t = A*(exp((-(r*r))/(4*D*i_t))/(4*pi*D*i_t)); else *t = 0.0; } """ i_cond = op2.Kernel(i_cond_code, "i_cond") op2.par_loop(i_cond, nodes, coords(op2.IdentityMap, op2.READ), tracer(op2.IdentityMap, op2.WRITE)) zero_dat_code = """ void zero_dat(double *dat) { *dat = 0.0; } """ zero_dat = op2.Kernel(zero_dat_code, "zero_dat") # Assemble and solve have_advection = True have_diffusion = True def timestep_iteration(): # Advection if have_advection: tic("advection") tic("assembly") mat.zero() op2.par_loop( mass, elements(3, 3), mat((elem_node[op2.i[0]], elem_node[op2.i[1]]), op2.INC), coords(elem_node, op2.READ), ) op2.par_loop(zero_dat, nodes, b(op2.IdentityMap, op2.WRITE)) op2.par_loop( adv_rhs, elements(3), b(elem_node[op2.i[0]], op2.INC), coords(elem_node, op2.READ), tracer(elem_node, op2.READ), velocity(elem_node, op2.READ), ) toc("assembly") tic("solve") op2.solve(mat, tracer, b) toc("solve") toc("advection") # Diffusion if have_diffusion: tic("diffusion") tic("assembly") mat.zero() op2.par_loop( diff_matrix, elements(3, 3), mat((elem_node[op2.i[0]], elem_node[op2.i[1]]), op2.INC), coords(elem_node, op2.READ), ) op2.par_loop(zero_dat, nodes, b(op2.IdentityMap, op2.WRITE)) op2.par_loop( diff_rhs, elements(3), b(elem_node[op2.i[0]], op2.INC), coords(elem_node, op2.READ), tracer(elem_node, op2.READ), ) toc("assembly") tic("solve") op2.solve(mat, tracer, b) toc("solve") toc("diffusion") # Perform 1 iteration to warm up plan cache then reset initial condition timestep_iteration() op2.par_loop(i_cond, nodes, coords(op2.IdentityMap, op2.READ), tracer(op2.IdentityMap, op2.WRITE)) reset() # Timed iteration t1 = clock() while current_time < endtime: timestep_iteration() current_time += dt runtime = clock() - t1 print "/fluidity :: %f" % runtime summary("profile_pyop2_%s_%s.csv" % (opt["mesh"].split("/")[-1], opt["backend"]))
def main(opt): # Set up finite element identity problem E = FiniteElement("Lagrange", "triangle", 1) v = TestFunction(E) u = TrialFunction(E) f = Coefficient(E) a = v * u * dx L = v * f * dx # Generate code for mass and rhs assembly. mass, = compile_form(a, "mass") rhs, = compile_form(L, "rhs") # Set up simulation data structures valuetype = np.float64 nodes, coords, elements, elem_node = read_triangle(opt['mesh']) sparsity = op2.Sparsity((nodes, nodes), (elem_node, elem_node), "sparsity") mat = op2.Mat(sparsity, valuetype, "mat") b = op2.Dat(nodes, np.zeros(nodes.size, dtype=valuetype), valuetype, "b") x = op2.Dat(nodes, np.zeros(nodes.size, dtype=valuetype), valuetype, "x") # Set up initial condition f_vals = np.array([2 * X + 4 * Y for X, Y in coords.data], dtype=valuetype) f = op2.Dat(nodes, f_vals, valuetype, "f") # Assemble and solve op2.par_loop(mass, elements, mat(op2.INC, (elem_node[op2.i[0]], elem_node[op2.i[1]])), coords(op2.READ, elem_node, flatten=True)) op2.par_loop(rhs, elements, b(op2.INC, elem_node[op2.i[0]]), coords(op2.READ, elem_node, flatten=True), f(op2.READ, elem_node)) solver = op2.Solver() solver.solve(mat, x, b) # Print solution (if necessary) if opt['print_output']: print "Expected solution: %s" % f.data print "Computed solution: %s" % x.data # Save output (if necessary) if opt['return_output']: return f.data, x.data if opt['save_output']: from cPickle import dump, HIGHEST_PROTOCOL import gzip out = gzip.open("mass2d_triangle.out.gz", "wb") dump((f.data, x.data, b.data, mat.array), out, HIGHEST_PROTOCOL) out.close()