def main(write_output=True): from hedge.data import GivenFunction, ConstantGivenFunction from hedge.backends import guess_run_context rcon = guess_run_context() dim = 2 def boundary_tagger(fvi, el, fn, points): from math import atan2, pi normal = el.face_normals[fn] if -90/180*pi < atan2(normal[1], normal[0]) < 90/180*pi: return ["neumann"] else: return ["dirichlet"] if dim == 2: if rcon.is_head_rank: from hedge.mesh.generator import make_disk_mesh mesh = make_disk_mesh(r=0.5, boundary_tagger=boundary_tagger, max_area=1e-2) elif dim == 3: if rcon.is_head_rank: from hedge.mesh.generator import make_ball_mesh mesh = make_ball_mesh(max_volume=0.0001, boundary_tagger=lambda fvi, el, fn, points: ["dirichlet"]) else: raise RuntimeError, "bad number of dimensions" if rcon.is_head_rank: print "%d elements" % len(mesh.elements) mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() discr = rcon.make_discretization(mesh_data, order=5, debug=[]) def dirichlet_bc(x, el): from math import sin return sin(10*x[0]) def rhs_c(x, el): if la.norm(x) < 0.1: return 1000 else: return 0 def my_diff_tensor(): result = numpy.eye(dim) result[0,0] = 0.1 return result try: from hedge.models.poisson import PoissonOperator from hedge.second_order import \ IPDGSecondDerivative, LDGSecondDerivative, \ StabilizedCentralSecondDerivative from hedge.mesh import TAG_NONE, TAG_ALL op = PoissonOperator(discr.dimensions, diffusion_tensor=my_diff_tensor(), #dirichlet_tag="dirichlet", #neumann_tag="neumann", dirichlet_tag=TAG_ALL, neumann_tag=TAG_NONE, #dirichlet_tag=TAG_ALL, #neumann_tag=TAG_NONE, dirichlet_bc=GivenFunction(dirichlet_bc), neumann_bc=ConstantGivenFunction(-10), scheme=StabilizedCentralSecondDerivative(), #scheme=LDGSecondDerivative(), #scheme=IPDGSecondDerivative(), ) bound_op = op.bind(discr) from hedge.iterative import parallel_cg u = -parallel_cg(rcon, -bound_op, bound_op.prepare_rhs(discr.interpolate_volume_function(rhs_c)), debug=20, tol=5e-4, dot=discr.nodewise_dot_product, x=discr.volume_zeros()) if write_output: from hedge.visualization import SiloVisualizer, VtkVisualizer vis = VtkVisualizer(discr, rcon) visf = vis.make_file("fld") vis.add_data(visf, [ ("sol", discr.convert_volume(u, kind="numpy")), ]) visf.close() finally: discr.close()
def compute_initial_condition(rcon, discr, method, state, maxwell_op, potential_bc, force_zero=False): from hedge.models.poisson import PoissonOperator from hedge.mesh import TAG_ALL, TAG_NONE from hedge.data import ConstantGivenFunction, GivenVolumeInterpolant def rel_l2_error(field, true): from hedge.tools import relative_error return relative_error(discr.norm(field - true), discr.norm(true)) mean_beta = method.mean_beta(state) gamma = method.units.gamma_from_beta(mean_beta) # see doc/notes.tm for derivation of IC def make_scaling_matrix(beta_scale, other_scale): if la.norm(mean_beta) < 1e-10: return other_scale * numpy.eye(discr.dimensions) else: beta_unit = mean_beta / la.norm(mean_beta) return ( other_scale * numpy.identity(discr.dimensions) + (beta_scale - other_scale) * numpy.outer(beta_unit, beta_unit)) poisson_op = PoissonOperator(discr.dimensions, diffusion_tensor=make_scaling_matrix( 1 / gamma**2, 1), dirichlet_tag=TAG_ALL, neumann_tag=TAG_NONE, dirichlet_bc=potential_bc) rho_prime = method.deposit_rho(state) rho_tilde = rho_prime / gamma bound_poisson = poisson_op.bind(discr) if force_zero: phi_tilde = discr.volume_zeros() else: from hedge.iterative import parallel_cg phi_tilde = -parallel_cg( rcon, -bound_poisson, bound_poisson.prepare_rhs(rho_tilde / maxwell_op.epsilon), debug=40 if "poisson" in method.debug else False, tol=1e-10) from hedge.tools import ptwise_dot from hedge.models.nd_calculus import GradientOperator e_tilde = ptwise_dot( 2, 1, make_scaling_matrix(1 / gamma, 1), GradientOperator(discr.dimensions).bind(discr)(phi_tilde)) e_prime = ptwise_dot(2, 1, make_scaling_matrix(1, gamma), e_tilde) from pyrticle.tools import make_cross_product v_e_to_h_cross = make_cross_product(method, maxwell_op, "v", "e", "h") h_prime = (1 / maxwell_op.mu) * gamma / maxwell_op.c * v_e_to_h_cross( mean_beta, e_tilde) if "ic" in method.debug: deposited_charge = discr.integral(rho_prime) real_charge = numpy.sum(state.charges) print "charge: supposed=%g deposited=%g error=%g %%" % ( real_charge, deposited_charge, 100 * abs(deposited_charge - real_charge) / abs(real_charge)) from hedge.models.nd_calculus import DivergenceOperator bound_div_op = DivergenceOperator(discr.dimensions).bind(discr) d_tilde = maxwell_op.epsilon * e_tilde d_prime = maxwell_op.epsilon * e_prime #divD_prime_ldg = bound_poisson.div(d_prime) #divD_prime_ldg2 = bound_poisson.div(d_prime, maxwell_op.epsilon*gamma*phi_tilde) from hedge.optemplate import InverseMassOperator divD_prime_ldg3 = maxwell_op.epsilon*\ (InverseMassOperator().apply(discr, bound_poisson.op(gamma*phi_tilde))) divD_prime_central = bound_div_op(d_prime) print "l2 div D_prime error central: %g" % \ rel_l2_error(divD_prime_central, rho_prime) #print "l2 div D_prime error ldg: %g" % \ #rel_l2_error(divD_prime_ldg, rho_prime) #print "l2 div D_prime error ldg with phi: %g" % \ #rel_l2_error(divD_prime_ldg2, rho_prime) print "l2 div D_prime error ldg with phi 3: %g" % \ rel_l2_error(divD_prime_ldg3, rho_prime) if "vis_files" in method.debug: from hedge.visualization import SiloVisualizer vis = SiloVisualizer(discr) visf = vis.make_file("ic") vis.add_data( visf, [ ("phi_moving", phi_tilde), ("rho_moving", rho_tilde), ("e_moving", e_tilde), ("rho_lab", rho_prime), #("divD_lab_ldg", divD_prime_ldg), #("divD_lab_ldg2", divD_prime_ldg2), #("divD_lab_ldg3", divD_prime_ldg3), ("divD_lab_central", divD_prime_central), ("e_lab", e_prime), ("h_lab", h_prime), ], ) method.add_to_vis(vis, visf, state) visf.close() return maxwell_op.assemble_fields(e=e_prime, h=h_prime, discr=discr)
def test_elliptic(): """Test various properties of elliptic operators.""" from hedge.tools import unit_vector def matrix_rep(op): h, w = op.shape mat = numpy.zeros(op.shape) for j in range(w): mat[:, j] = op(unit_vector(w, j)) return mat def check_grad_mat(): import pyublas if not pyublas.has_sparse_wrappers(): return grad_mat = op.grad_matrix() #print len(discr), grad_mat.nnz, type(grad_mat) for i in range(10): u = numpy.random.randn(len(discr)) mat_result = grad_mat * u op_result = numpy.hstack(op.grad(u)) err = la.norm(mat_result - op_result) * la.norm(op_result) assert err < 1e-5 def check_matrix_tgt(): big = numpy.zeros((20, 20), flavor=numpy.SparseBuildMatrix) small = numpy.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) print small from hedge._internal import MatrixTarget tgt = MatrixTarget(big, 4, 4) tgt.begin(small.shape[0], small.shape[1]) print "YO" tgt.add_coefficients(4, 4, small) print "DUDE" tgt.finalize() print big import pymbolic v_x = pymbolic.var("x") truesol = pymbolic.parse("math.sin(x[0]**2*x[1]**2)") truesol_c = pymbolic.compile(truesol, variables=["x"]) def laplace(expression, variables): return sum( pymbolic.diff(pymbolic.diff(expression, var), var) for var in variables) rhs = laplace(truesol, [v_x[0], v_x[1]]) rhs_c = pymbolic.compile(rhs, variables=["x", "el"]) from hedge.mesh import TAG_ALL, TAG_NONE from hedge.mesh.generator import make_disk_mesh mesh = make_disk_mesh(r=0.5, max_area=0.1, faces=20) mesh = mesh.reordered_by("cuthill") from hedge.backends import CPURunContext rcon = CPURunContext() from hedge.tools import EOCRecorder eocrec = EOCRecorder() for order in [1, 2, 3, 4, 5]: for flux in ["ldg", "ip"]: from hedge.discretization.local import TriangleDiscretization discr = rcon.make_discretization( mesh, TriangleDiscretization(order), debug=discr_class.noninteractive_debug_flags()) from hedge.data import GivenFunction from hedge.models.poisson import PoissonOperator op = PoissonOperator( discr.dimensions, dirichlet_tag=TAG_ALL, dirichlet_bc=GivenFunction(lambda x, el: truesol_c(x)), neumann_tag=TAG_NONE) bound_op = op.bind(discr) if order <= 3: mat = matrix_rep(bound_op) sym_err = la.norm(mat - mat.T) #print sym_err assert sym_err < 1e-12 #check_grad_mat() from hedge.iterative import parallel_cg truesol_v = discr.interpolate_volume_function( lambda x, el: truesol_c(x)) sol_v = -parallel_cg(rcon, -bound_op, bound_op.prepare_rhs( discr.interpolate_volume_function(rhs_c)), tol=1e-10, max_iterations=40000) eocrec.add_data_point(order, discr.norm(sol_v - truesol_v)) #print eocrec.pretty_print() assert eocrec.estimate_order_of_convergence()[0, 1] > 8
def test_elliptic(): """Test various properties of elliptic operators.""" from hedge.tools import unit_vector def matrix_rep(op): h, w = op.shape mat = numpy.zeros(op.shape) for j in range(w): mat[:, j] = op(unit_vector(w, j)) return mat def check_grad_mat(): import pyublas if not pyublas.has_sparse_wrappers(): return grad_mat = op.grad_matrix() # print len(discr), grad_mat.nnz, type(grad_mat) for i in range(10): u = numpy.random.randn(len(discr)) mat_result = grad_mat * u op_result = numpy.hstack(op.grad(u)) err = la.norm(mat_result - op_result) * la.norm(op_result) assert la.norm(mat_result - op_result) * la.norm(op_result) < 1e-5 def check_matrix_tgt(): big = num.zeros((20, 20), flavor=num.SparseBuildMatrix) small = num.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) print small from hedge._internal import MatrixTarget tgt = MatrixTarget(big, 4, 4) tgt.begin(small.shape[0], small.shape[1]) print "YO" tgt.add_coefficients(4, 4, small) print "DUDE" tgt.finalize() print big import pymbolic v_x = pymbolic.var("x") truesol = pymbolic.parse("math.sin(x[0]**2*x[1]**2)") truesol_c = pymbolic.compile(truesol, variables=["x"]) rhs = pymbolic.simplify(pymbolic.laplace(truesol, [v_x[0], v_x[1]])) rhs_c = pymbolic.compile(rhs, variables=["x", "el"]) from hedge.mesh import TAG_ALL, TAG_NONE from hedge.mesh.generator import make_disk_mesh mesh = make_disk_mesh(r=0.5, max_area=0.1, faces=20) mesh = mesh.reordered_by("cuthill") from hedge.backends import CPURunContext rcon = CPURunContext() from hedge.tools import EOCRecorder eocrec = EOCRecorder() for order in [1, 2, 3, 4, 5]: for flux in ["ldg", "ip"]: from hedge.discretization.local import TriangleDiscretization discr = rcon.make_discretization( mesh, TriangleDiscretization(order), debug=discr_class.noninteractive_debug_flags() ) from hedge.data import GivenFunction from hedge.models.poisson import PoissonOperator op = PoissonOperator( discr.dimensions, dirichlet_tag=TAG_ALL, dirichlet_bc=GivenFunction(lambda x, el: truesol_c(x)), neumann_tag=TAG_NONE, ) bound_op = op.bind(discr) if order <= 3: mat = matrix_rep(bound_op) sym_err = la.norm(mat - mat.T) # print sym_err assert sym_err < 1e-12 # check_grad_mat() from hedge.iterative import parallel_cg truesol_v = discr.interpolate_volume_function(lambda x, el: truesol_c(x)) sol_v = -parallel_cg( rcon, -bound_op, bound_op.prepare_rhs(discr.interpolate_volume_function(rhs_c)), tol=1e-10, max_iterations=40000, ) eocrec.add_data_point(order, discr.norm(sol_v - truesol_v)) # print eocrec.pretty_print() assert eocrec.estimate_order_of_convergence()[0, 1] > 8
def main(write_output=True): from hedge.data import GivenFunction, ConstantGivenFunction from hedge.backends import guess_run_context rcon = guess_run_context() dim = 2 def boundary_tagger(fvi, el, fn, points): from math import atan2, pi normal = el.face_normals[fn] if -90 / 180 * pi < atan2(normal[1], normal[0]) < 90 / 180 * pi: return ["neumann"] else: return ["dirichlet"] if dim == 2: if rcon.is_head_rank: from hedge.mesh.generator import make_disk_mesh mesh = make_disk_mesh(r=0.5, boundary_tagger=boundary_tagger, max_area=1e-2) elif dim == 3: if rcon.is_head_rank: from hedge.mesh.generator import make_ball_mesh mesh = make_ball_mesh( max_volume=0.0001, boundary_tagger=lambda fvi, el, fn, points: ["dirichlet"]) else: raise RuntimeError, "bad number of dimensions" if rcon.is_head_rank: print "%d elements" % len(mesh.elements) mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() discr = rcon.make_discretization(mesh_data, order=5, debug=[]) def dirichlet_bc(x, el): from math import sin return sin(10 * x[0]) def rhs_c(x, el): if la.norm(x) < 0.1: return 1000 else: return 0 def my_diff_tensor(): result = numpy.eye(dim) result[0, 0] = 0.1 return result try: from hedge.models.poisson import PoissonOperator from hedge.second_order import \ IPDGSecondDerivative, LDGSecondDerivative, \ StabilizedCentralSecondDerivative from hedge.mesh import TAG_NONE, TAG_ALL op = PoissonOperator( discr.dimensions, diffusion_tensor=my_diff_tensor(), #dirichlet_tag="dirichlet", #neumann_tag="neumann", dirichlet_tag=TAG_ALL, neumann_tag=TAG_NONE, #dirichlet_tag=TAG_ALL, #neumann_tag=TAG_NONE, dirichlet_bc=GivenFunction(dirichlet_bc), neumann_bc=ConstantGivenFunction(-10), scheme=StabilizedCentralSecondDerivative(), #scheme=LDGSecondDerivative(), #scheme=IPDGSecondDerivative(), ) bound_op = op.bind(discr) from hedge.iterative import parallel_cg u = -parallel_cg(rcon, -bound_op, bound_op.prepare_rhs( discr.interpolate_volume_function(rhs_c)), debug=20, tol=5e-4, dot=discr.nodewise_dot_product, x=discr.volume_zeros()) if write_output: from hedge.visualization import SiloVisualizer, VtkVisualizer vis = VtkVisualizer(discr, rcon) visf = vis.make_file("fld") vis.add_data(visf, [ ("sol", discr.convert_volume(u, kind="numpy")), ]) visf.close() finally: discr.close()
def compute_initial_condition(rcon, discr, method, state, maxwell_op, potential_bc, force_zero=False): from hedge.models.poisson import PoissonOperator from hedge.mesh import TAG_ALL, TAG_NONE from hedge.data import ConstantGivenFunction, GivenVolumeInterpolant def rel_l2_error(field, true): from hedge.tools import relative_error return relative_error( discr.norm(field-true), discr.norm(true)) mean_beta = method.mean_beta(state) gamma = method.units.gamma_from_beta(mean_beta) # see doc/notes.tm for derivation of IC def make_scaling_matrix(beta_scale, other_scale): if la.norm(mean_beta) < 1e-10: return other_scale*numpy.eye(discr.dimensions) else: beta_unit = mean_beta/la.norm(mean_beta) return (other_scale*numpy.identity(discr.dimensions) + (beta_scale-other_scale)*numpy.outer(beta_unit, beta_unit)) poisson_op = PoissonOperator( discr.dimensions, diffusion_tensor=make_scaling_matrix(1/gamma**2, 1), dirichlet_tag=TAG_ALL, neumann_tag=TAG_NONE, dirichlet_bc=potential_bc) rho_prime = method.deposit_rho(state) rho_tilde = rho_prime/gamma bound_poisson = poisson_op.bind(discr) if force_zero: phi_tilde = discr.volume_zeros() else: from hedge.iterative import parallel_cg phi_tilde = -parallel_cg(rcon, -bound_poisson, bound_poisson.prepare_rhs( rho_tilde/maxwell_op.epsilon), debug=40 if "poisson" in method.debug else False, tol=1e-10) from hedge.tools import ptwise_dot from hedge.models.nd_calculus import GradientOperator e_tilde = ptwise_dot(2, 1, make_scaling_matrix(1/gamma, 1), GradientOperator(discr.dimensions).bind(discr)(phi_tilde)) e_prime = ptwise_dot(2, 1, make_scaling_matrix(1, gamma), e_tilde) from pyrticle.tools import make_cross_product v_e_to_h_cross = make_cross_product(method, maxwell_op, "v", "e", "h") h_prime = (1/maxwell_op.mu)*gamma/maxwell_op.c * v_e_to_h_cross(mean_beta, e_tilde) if "ic" in method.debug: deposited_charge = discr.integral(rho_prime) real_charge = numpy.sum(state.charges) print "charge: supposed=%g deposited=%g error=%g %%" % ( real_charge, deposited_charge, 100*abs(deposited_charge-real_charge)/abs(real_charge) ) from hedge.models.nd_calculus import DivergenceOperator bound_div_op = DivergenceOperator(discr.dimensions).bind(discr) d_tilde = maxwell_op.epsilon*e_tilde d_prime = maxwell_op.epsilon*e_prime #divD_prime_ldg = bound_poisson.div(d_prime) #divD_prime_ldg2 = bound_poisson.div(d_prime, maxwell_op.epsilon*gamma*phi_tilde) from hedge.optemplate import InverseMassOperator divD_prime_ldg3 = maxwell_op.epsilon*\ (InverseMassOperator().apply(discr, bound_poisson.op(gamma*phi_tilde))) divD_prime_central = bound_div_op(d_prime) print "l2 div D_prime error central: %g" % \ rel_l2_error(divD_prime_central, rho_prime) #print "l2 div D_prime error ldg: %g" % \ #rel_l2_error(divD_prime_ldg, rho_prime) #print "l2 div D_prime error ldg with phi: %g" % \ #rel_l2_error(divD_prime_ldg2, rho_prime) print "l2 div D_prime error ldg with phi 3: %g" % \ rel_l2_error(divD_prime_ldg3, rho_prime) if "vis_files" in method.debug: from hedge.visualization import SiloVisualizer vis = SiloVisualizer(discr) visf = vis.make_file("ic") vis.add_data(visf, [ ("phi_moving", phi_tilde), ("rho_moving", rho_tilde), ("e_moving", e_tilde), ("rho_lab", rho_prime), #("divD_lab_ldg", divD_prime_ldg), #("divD_lab_ldg2", divD_prime_ldg2), #("divD_lab_ldg3", divD_prime_ldg3), ("divD_lab_central", divD_prime_central), ("e_lab", e_prime), ("h_lab", h_prime), ], ) method.add_to_vis(vis, visf, state) visf.close() return maxwell_op.assemble_fields(e=e_prime, h=h_prime, discr=discr)