def no_test_tri_mass_mat_gauss(self): """Check the integral of a Gaussian on a disk using the mass matrix""" # This is a bad test, since it's never exact. The Gaussian has infinite support, # and this *does* matter numerically. from hedge.mesh.generator import make_disk_mesh from hedge.discretization.local import TriangleDiscretization from math import sqrt, exp, pi sigma_squared = 1 / 219.3 mesh = make_disk_mesh() discr = self.discr_class( make_disk_mesh(), TriangleDiscretization(4), debug=self.discr_class.noninteractive_debug_flags() ) f = discr.interpolate_volume_function(lambda x, el: exp(-x * x / (2 * sigma_squared))) ones = discr.interpolate_volume_function(lambda x, el: 1) # discr.visualize_vtk("gaussian.vtk", [("f", f)]) num_integral_1 = ones * (discr.mass_operator * f) num_integral_2 = f * (discr.mass_operator * ones) dim = 2 true_integral = (2 * pi) ** (dim / 2) * sqrt(sigma_squared) ** dim err_1 = abs(num_integral_1 - true_integral) err_2 = abs(num_integral_2 - true_integral) self.assert_(err_1 < 1e-11) self.assert_(err_2 < 1e-11)
def test_tri_diff_mat(): """Check differentiation matrix along the coordinate axes on a disk Uses sines as the function to differentiate. """ from hedge.mesh.generator import make_disk_mesh from hedge.discretization.local import TriangleDiscretization from math import sin, cos, sqrt from hedge.optemplate import make_nabla nabla = make_nabla(2) for coord in [0, 1]: mesh = make_disk_mesh() discr = discr_class(make_disk_mesh(), TriangleDiscretization(4), debug=discr_class.noninteractive_debug_flags()) f = discr.interpolate_volume_function(lambda x, el: sin(3 * x[coord])) df = discr.interpolate_volume_function(lambda x, el: 3 * cos(3 * x[coord])) df_num = nabla[coord].apply(discr, f) # discr.visualize_vtk("diff-err.vtk", # [("f", f), ("df", df), ("df_num", df_num), ("error", error)]) linf_error = la.norm(df_num - df, numpy.Inf) print linf_error assert linf_error < 4e-5
def test_tri_diff_mat(): """Check differentiation matrix along the coordinate axes on a disk Uses sines as the function to differentiate. """ from hedge.mesh.generator import make_disk_mesh from hedge.discretization.local import TriangleDiscretization from math import sin, cos from hedge.optemplate import make_nabla nabla = make_nabla(2) for coord in [0, 1]: discr = discr_class(make_disk_mesh(), TriangleDiscretization(4), debug=discr_class.noninteractive_debug_flags()) f = discr.interpolate_volume_function(lambda x, el: sin(3 * x[coord])) df = discr.interpolate_volume_function( lambda x, el: 3 * cos(3 * x[coord])) df_num = nabla[coord].apply(discr, f) #discr.visualize_vtk("diff-err.vtk", #[("f", f), ("df", df), ("df_num", df_num), ("error", error)]) linf_error = la.norm(df_num - df, numpy.Inf) print linf_error assert linf_error < 4e-5
def no_test_tri_mass_mat_gauss(self): """Check the integral of a Gaussian on a disk using the mass matrix""" # This is a bad test, since it's never exact. The Gaussian has infinite support, # and this *does* matter numerically. from hedge.mesh.generator import make_disk_mesh from hedge.discretization.local import TriangleDiscretization from math import sqrt, exp, pi sigma_squared = 1 / 219.3 discr = self.discr_class( make_disk_mesh(), TriangleDiscretization(4), debug=self.discr_class.noninteractive_debug_flags()) f = discr.interpolate_volume_function( lambda x, el: exp(-x * x / (2 * sigma_squared))) ones = discr.interpolate_volume_function(lambda x, el: 1) #discr.visualize_vtk("gaussian.vtk", [("f", f)]) num_integral_1 = ones * (discr.mass_operator * f) num_integral_2 = f * (discr.mass_operator * ones) dim = 2 true_integral = (2 * pi)**(dim / 2) * sqrt(sigma_squared)**dim err_1 = abs(num_integral_1 - true_integral) err_2 = abs(num_integral_2 - true_integral) self.assert_(err_1 < 1e-11) self.assert_(err_2 < 1e-11)
def test_projection(): """Test whether projection between different orders works""" from hedge.mesh.generator import make_disk_mesh from hedge.discretization import Projector from hedge.discretization.local import TriangleDiscretization from math import sin, pi from numpy import dot a = numpy.array([1, 3]) def u_analytic(x, el): return sin(dot(a, x)) mesh = make_disk_mesh(r=pi, max_area=0.5) discr2 = discr_class(mesh, TriangleDiscretization(2), debug=discr_class.noninteractive_debug_flags()) discr5 = discr_class(mesh, TriangleDiscretization(5), debug=discr_class.noninteractive_debug_flags()) p2to5 = Projector(discr2, discr5) p5to2 = Projector(discr5, discr2) u2 = discr2.interpolate_volume_function(u_analytic) u2_i = p5to2(p2to5(u2)) assert discr2.norm(u2 - u2_i) < 3e-15
def test_projection(): """Test whether projection between different orders works""" from hedge.mesh.generator import make_disk_mesh from hedge.discretization import Projector from hedge.discretization.local import TriangleDiscretization from hedge.tools import EOCRecorder from math import sin, pi, sqrt from numpy import dot a = numpy.array([1, 3]) def u_analytic(x, el): return sin(dot(a, x)) mesh = make_disk_mesh(r=pi, max_area=0.5) discr2 = discr_class(mesh, TriangleDiscretization(2), debug=discr_class.noninteractive_debug_flags()) discr5 = discr_class(mesh, TriangleDiscretization(5), debug=discr_class.noninteractive_debug_flags()) p2to5 = Projector(discr2, discr5) p5to2 = Projector(discr5, discr2) u2 = discr2.interpolate_volume_function(u_analytic) u2_i = p5to2(p2to5(u2)) assert discr2.norm(u2 - u2_i) < 3e-15
def test_filter(): """Exercise mode-based filtering.""" from hedge.mesh.generator import make_disk_mesh from hedge.discretization.local import TriangleDiscretization from math import sin mesh = make_disk_mesh(r=3.4, max_area=0.5) discr = discr_class(mesh, TriangleDiscretization(5), debug=discr_class.noninteractive_debug_flags()) from hedge.optemplate.operators import FilterOperator from hedge.discretization import ExponentialFilterResponseFunction half_filter = FilterOperator(lambda mid, ldis: 0.5) for eg in discr.element_groups: fmat = half_filter.matrix(eg) n, m = fmat.shape assert la.norm(fmat - 0.5 * numpy.eye(n, m)) < 2e-15 from numpy import dot def test_freq(n): a = numpy.array([1, n]) def u_analytic(x, el): return sin(dot(a, x)) exp_filter = FilterOperator(ExponentialFilterResponseFunction(0.9, 3)) \ .bind(discr) u = discr.interpolate_volume_function(u_analytic) filt_u = exp_filter(u) int_error = abs(discr.integral(u) - discr.integral(filt_u)) l2_ratio = discr.norm(filt_u) / discr.norm(u) assert int_error < 1e-14 assert 0.96 < l2_ratio < 0.99999 test_freq(3) test_freq(5) test_freq(9) test_freq(17)
def test_filter(): """Exercise mode-based filtering.""" from hedge.mesh.generator import make_disk_mesh from hedge.discretization.local import TriangleDiscretization from math import sin mesh = make_disk_mesh(r=3.4, max_area=0.5) discr = discr_class(mesh, TriangleDiscretization(5), debug=discr_class.noninteractive_debug_flags()) from hedge.optemplate.operators import FilterOperator from hedge.discretization import ExponentialFilterResponseFunction half_filter = FilterOperator(lambda mid, ldis: 0.5) for eg in discr.element_groups: fmat = half_filter.matrix(eg) n, m = fmat.shape assert la.norm(fmat - 0.5*numpy.eye(n, m)) < 2e-15 from numpy import dot def test_freq(n): a = numpy.array([1, n]) def u_analytic(x, el): return sin(dot(a, x)) exp_filter = FilterOperator(ExponentialFilterResponseFunction(0.9, 3)) \ .bind(discr) u = discr.interpolate_volume_function(u_analytic) filt_u = exp_filter(u) int_error = abs(discr.integral(u) - discr.integral(filt_u)) l2_ratio = discr.norm(filt_u) / discr.norm(u) assert int_error < 1e-14 assert 0.96 < l2_ratio < 0.99999 test_freq(3) test_freq(5) test_freq(9) test_freq(17)
def main(write_output=True, flux_type_arg="upwind"): from hedge.tools import mem_checkpoint from math import sin, cos, pi, sqrt from math import floor from hedge.backends import guess_run_context rcon = guess_run_context() def f(x): return sin(pi*x) def u_analytic(x, el, t): return f((-numpy.dot(v, x)/norm_v+t*norm_v)) def boundary_tagger(vertices, el, face_nr, all_v): if numpy.dot(el.face_normals[face_nr], v) < 0: return ["inflow"] else: return ["outflow"] dim = 2 if dim == 1: v = numpy.array([1]) if rcon.is_head_rank: from hedge.mesh.generator import make_uniform_1d_mesh mesh = make_uniform_1d_mesh(0, 2, 10, periodic=True) elif dim == 2: v = numpy.array([2,0]) if rcon.is_head_rank: from hedge.mesh.generator import make_disk_mesh mesh = make_disk_mesh(boundary_tagger=boundary_tagger) elif dim == 3: v = numpy.array([0,0,1]) if rcon.is_head_rank: from hedge.mesh.generator import make_cylinder_mesh, make_ball_mesh, make_box_mesh mesh = make_cylinder_mesh(max_volume=0.04, height=2, boundary_tagger=boundary_tagger, periodic=False, radial_subdivisions=32) else: raise RuntimeError, "bad number of dimensions" norm_v = la.norm(v) if rcon.is_head_rank: mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() if dim != 1: mesh_data = mesh_data.reordered_by("cuthill") discr = rcon.make_discretization(mesh_data, order=4) vis_discr = discr from hedge.visualization import VtkVisualizer if write_output: vis = VtkVisualizer(vis_discr, rcon, "fld") # operator setup ---------------------------------------------------------- from hedge.data import \ ConstantGivenFunction, \ TimeConstantGivenFunction, \ TimeDependentGivenFunction from hedge.models.advection import StrongAdvectionOperator, WeakAdvectionOperator op = WeakAdvectionOperator(v, inflow_u=TimeDependentGivenFunction(u_analytic), flux_type=flux_type_arg) u = discr.interpolate_volume_function(lambda x, el: u_analytic(x, el, 0)) # timestep setup ---------------------------------------------------------- from hedge.timestep.runge_kutta import LSRK4TimeStepper stepper = LSRK4TimeStepper() if rcon.is_head_rank: print "%d elements" % len(discr.mesh.elements) # diagnostics setup ------------------------------------------------------- from pytools.log import LogManager, \ add_general_quantities, \ add_simulation_quantities, \ add_run_info if write_output: log_file_name = "advection.dat" else: log_file_name = None logmgr = LogManager(log_file_name, "w", rcon.communicator) add_run_info(logmgr) add_general_quantities(logmgr) add_simulation_quantities(logmgr) discr.add_instrumentation(logmgr) stepper.add_instrumentation(logmgr) from hedge.log import Integral, LpNorm u_getter = lambda: u logmgr.add_quantity(Integral(u_getter, discr, name="int_u")) logmgr.add_quantity(LpNorm(u_getter, discr, p=1, name="l1_u")) logmgr.add_quantity(LpNorm(u_getter, discr, name="l2_u")) logmgr.add_watches(["step.max", "t_sim.max", "l2_u", "t_step.max"]) # timestep loop ----------------------------------------------------------- rhs = op.bind(discr) try: from hedge.timestep import times_and_steps step_it = times_and_steps( final_time=3, logmgr=logmgr, max_dt_getter=lambda t: op.estimate_timestep(discr, stepper=stepper, t=t, fields=u)) for step, t, dt in step_it: if step % 5 == 0 and write_output: visf = vis.make_file("fld-%04d" % step) vis.add_data(visf, [ ("u", discr.convert_volume(u, kind="numpy")), ], time=t, step=step) visf.close() u = stepper(u, t, dt, rhs) true_u = discr.interpolate_volume_function(lambda x, el: u_analytic(x, el, t)) print discr.norm(u-true_u) assert discr.norm(u-true_u) < 1e-2 finally: if write_output: vis.close() logmgr.close() discr.close()
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 main(write_output=True): from math import sin, cos, pi, exp, sqrt from hedge.data import TimeConstantGivenFunction, \ ConstantGivenFunction from hedge.backends import guess_run_context rcon = guess_run_context() dim = 2 def boundary_tagger(fvi, el, fn, all_v): if el.face_normals[fn][0] > 0: return ["dirichlet"] else: return ["neumann"] 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) elif dim == 3: if rcon.is_head_rank: from hedge.mesh.generator import make_ball_mesh mesh = make_ball_mesh(max_volume=0.001) 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=3, debug=["cuda_no_plan"], default_scalar_type=numpy.float64) if write_output: from hedge.visualization import VtkVisualizer vis = VtkVisualizer(discr, rcon, "fld") def u0(x, el): if la.norm(x) < 0.2: return 1 else: return 0 def coeff(x, el): if x[0] < 0: return 0.25 else: return 1 def dirichlet_bc(t, x): return 0 def neumann_bc(t, x): return 2 from hedge.models.diffusion import DiffusionOperator op = DiffusionOperator( discr.dimensions, #coeff=coeff, dirichlet_tag="dirichlet", dirichlet_bc=TimeConstantGivenFunction(ConstantGivenFunction(0)), neumann_tag="neumann", neumann_bc=TimeConstantGivenFunction(ConstantGivenFunction(1))) u = discr.interpolate_volume_function(u0) # diagnostics setup ------------------------------------------------------- from pytools.log import LogManager, \ add_general_quantities, \ add_simulation_quantities, \ add_run_info if write_output: log_file_name = "heat.dat" else: log_file_name = None logmgr = LogManager(log_file_name, "w", rcon.communicator) add_run_info(logmgr) add_general_quantities(logmgr) add_simulation_quantities(logmgr) discr.add_instrumentation(logmgr) from hedge.log import LpNorm u_getter = lambda: u logmgr.add_quantity(LpNorm(u_getter, discr, 1, name="l1_u")) logmgr.add_quantity(LpNorm(u_getter, discr, name="l2_u")) logmgr.add_watches(["step.max", "t_sim.max", "l2_u", "t_step.max"]) # timestep loop ----------------------------------------------------------- from hedge.timestep.runge_kutta import LSRK4TimeStepper, ODE45TimeStepper from hedge.timestep.dumka3 import Dumka3TimeStepper #stepper = LSRK4TimeStepper() stepper = Dumka3TimeStepper( 3, rtol=1e-6, rcon=rcon, vector_primitive_factory=discr.get_vector_primitive_factory(), dtype=discr.default_scalar_type) #stepper = ODE45TimeStepper(rtol=1e-6, rcon=rcon, #vector_primitive_factory=discr.get_vector_primitive_factory(), #dtype=discr.default_scalar_type) stepper.add_instrumentation(logmgr) rhs = op.bind(discr) try: next_dt = op.estimate_timestep(discr, stepper=LSRK4TimeStepper(), t=0, fields=u) from hedge.timestep import times_and_steps step_it = times_and_steps(final_time=0.1, logmgr=logmgr, max_dt_getter=lambda t: next_dt, taken_dt_getter=lambda: taken_dt) for step, t, dt in step_it: if step % 10 == 0 and write_output: visf = vis.make_file("fld-%04d" % step) vis.add_data(visf, [ ("u", discr.convert_volume(u, kind="numpy")), ], time=t, step=step) visf.close() u, t, taken_dt, next_dt = stepper(u, t, next_dt, rhs) #u = stepper(u, t, dt, rhs) assert discr.norm(u) < 1 finally: if write_output: vis.close() logmgr.close() discr.close()
def test_convergence_advec_2d(): """Test whether 2D advection actually converges""" import pyublas from hedge.mesh.generator import make_disk_mesh, make_regular_rect_mesh from hedge.discretization.local import TriangleDiscretization from hedge.timestep import RK4TimeStepper from hedge.tools import EOCRecorder from math import sin, pi, sqrt from hedge.models.advection import StrongAdvectionOperator from hedge.data import TimeDependentGivenFunction v = numpy.array([0.27, 0]) norm_a = la.norm(v) from numpy import dot def f(x): return sin(x) def u_analytic(x, el, t): return f((-dot(v, x) / norm_a + t * norm_a)) def boundary_tagger(vertices, el, face_nr, all_v): if dot(el.face_normals[face_nr], v) < 0: return ["inflow"] else: return ["outflow"] for mesh in [ # non-periodic make_disk_mesh(r=pi, boundary_tagger=boundary_tagger, max_area=0.5), # periodic make_regular_rect_mesh( a=(0, 0), b=(2 * pi, 1), n=(8, 4), periodicity=(True, False), boundary_tagger=boundary_tagger ), ]: for flux_type in StrongAdvectionOperator.flux_types: eoc_rec = EOCRecorder() for order in [1, 2, 3, 4, 5, 6]: discr = discr_class(mesh, TriangleDiscretization(order), debug=discr_class.noninteractive_debug_flags()) op = StrongAdvectionOperator(v, inflow_u=TimeDependentGivenFunction(u_analytic), flux_type=flux_type) u = discr.interpolate_volume_function(lambda x, el: u_analytic(x, el, 0)) stepper = RK4TimeStepper() dt = op.estimate_timestep(discr, stepper=stepper) nsteps = int(1 / dt) rhs = op.bind(discr) for step in range(nsteps): u = stepper(u, step * dt, dt, rhs) u_true = discr.interpolate_volume_function(lambda x, el: u_analytic(x, el, nsteps * dt)) error = u - u_true error_l2 = discr.norm(error) eoc_rec.add_data_point(order, error_l2) if False: print "%s\n%s\n" % (flux_type.upper(), "-" * len(flux_type)) print eoc_rec.pretty_print(abscissa_label="Poly. Order", error_label="L2 Error") assert eoc_rec.estimate_order_of_convergence()[0, 1] > 4 assert eoc_rec.estimate_order_of_convergence(2)[-1, 1] > 10
def test_2d_gauss_theorem(): """Verify Gauss's theorem explicitly on a mesh""" from hedge.mesh.generator import make_disk_mesh from math import sin, cos, sqrt, exp, pi from numpy import dot mesh = make_disk_mesh() order = 2 discr = discr_class(mesh, order=order, debug=discr_class.noninteractive_debug_flags()) ref_discr = discr_class(mesh, order=order) from hedge.flux import make_normal, FluxScalarPlaceholder normal = make_normal(discr.dimensions) flux_f_ph = FluxScalarPlaceholder(0) one_sided_x = flux_f_ph.int * normal[0] one_sided_y = flux_f_ph.int * normal[1] def f1(x, el): return sin(3 * x[0]) + cos(3 * x[1]) def f2(x, el): return sin(2 * x[0]) + cos(x[1]) from hedge.discretization import ones_on_volume ones = ones_on_volume(discr) f1_v = discr.interpolate_volume_function(f1) f2_v = discr.interpolate_volume_function(f2) from hedge.optemplate import BoundaryPair, Field, make_nabla, get_flux_operator nabla = make_nabla(discr.dimensions) diff_optp = nabla[0] * Field("f1") + nabla[1] * Field("f2") divergence = nabla[0].apply(discr, f1_v) + nabla[1].apply(discr, f2_v) int_div = discr.integral(divergence) flux_optp = get_flux_operator(one_sided_x)(BoundaryPair(Field("f1"), Field("fz"))) + get_flux_operator(one_sided_y)( BoundaryPair(Field("f2"), Field("fz")) ) from hedge.mesh import TAG_ALL bdry_val = discr.compile(flux_optp)(f1=f1_v, f2=f2_v, fz=discr.boundary_zeros(TAG_ALL)) ref_bdry_val = ref_discr.compile(flux_optp)(f1=f1_v, f2=f2_v, fz=discr.boundary_zeros(TAG_ALL)) boundary_int = dot(bdry_val, ones) if False: from hedge.visualization import SiloVisualizer vis = SiloVisualizer(discr) visf = vis.make_file("test") from hedge.tools import make_obj_array from hedge.mesh import TAG_ALL vis.add_data( visf, [ ("bdry", bdry_val), ("ref_bdry", ref_bdry_val), ("div", divergence), ("f", make_obj_array([f1_v, f2_v])), ("n", discr.volumize_boundary_field(discr.boundary_normals(TAG_ALL), TAG_ALL)), ], expressions=[("bdiff", "bdry-ref_bdry")], ) # print abs(boundary_int-int_div) assert abs(boundary_int - int_div) < 5e-15
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 test_2d_gauss_theorem(): """Verify Gauss's theorem explicitly on a mesh""" from hedge.mesh.generator import make_disk_mesh from math import sin, cos from numpy import dot mesh = make_disk_mesh() order = 2 discr = discr_class(mesh, order=order, debug=discr_class.noninteractive_debug_flags()) ref_discr = discr_class(mesh, order=order) from hedge.flux import make_normal, FluxScalarPlaceholder normal = make_normal(discr.dimensions) flux_f_ph = FluxScalarPlaceholder(0) one_sided_x = flux_f_ph.int * normal[0] one_sided_y = flux_f_ph.int * normal[1] def f1(x, el): return sin(3 * x[0]) + cos(3 * x[1]) def f2(x, el): return sin(2 * x[0]) + cos(x[1]) from hedge.discretization import ones_on_volume ones = ones_on_volume(discr) f1_v = discr.interpolate_volume_function(f1) f2_v = discr.interpolate_volume_function(f2) from hedge.optemplate import BoundaryPair, Field, make_nabla, \ get_flux_operator nabla = make_nabla(discr.dimensions) divergence = nabla[0].apply(discr, f1_v) + nabla[1].apply(discr, f2_v) int_div = discr.integral(divergence) flux_optp = ( get_flux_operator(one_sided_x)(BoundaryPair(Field("f1"), Field("fz"))) + get_flux_operator(one_sided_y)(BoundaryPair(Field("f2"), Field("fz")))) from hedge.mesh import TAG_ALL bdry_val = discr.compile(flux_optp)(f1=f1_v, f2=f2_v, fz=discr.boundary_zeros(TAG_ALL)) ref_bdry_val = ref_discr.compile(flux_optp)( f1=f1_v, f2=f2_v, fz=discr.boundary_zeros(TAG_ALL)) boundary_int = dot(bdry_val, ones) if False: from hedge.visualization import SiloVisualizer vis = SiloVisualizer(discr) visf = vis.make_file("test") from hedge.tools import make_obj_array from hedge.mesh import TAG_ALL vis.add_data(visf, [ ("bdry", bdry_val), ("ref_bdry", ref_bdry_val), ("div", divergence), ("f", make_obj_array([f1_v, f2_v])), ("n", discr.volumize_boundary_field(discr.boundary_normals(TAG_ALL), TAG_ALL)), ], expressions=[("bdiff", "bdry-ref_bdry")]) #print abs(boundary_int-int_div) assert abs(boundary_int - int_div) < 5e-15
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 test_convergence_advec_2d(): """Test whether 2D advection actually converges""" import pyublas # noqa from hedge.mesh.generator import make_disk_mesh, make_regular_rect_mesh from hedge.discretization.local import TriangleDiscretization from hedge.timestep import RK4TimeStepper from hedge.tools import EOCRecorder from math import sin, pi from hedge.models.advection import StrongAdvectionOperator from hedge.data import TimeDependentGivenFunction v = numpy.array([0.27, 0]) norm_a = la.norm(v) from numpy import dot def f(x): return sin(x) def u_analytic(x, el, t): return f((-dot(v, x) / norm_a + t * norm_a)) def boundary_tagger(vertices, el, face_nr, all_v): if dot(el.face_normals[face_nr], v) < 0: return ["inflow"] else: return ["outflow"] for mesh in [ # non-periodic make_disk_mesh(r=pi, boundary_tagger=boundary_tagger, max_area=0.5), # periodic make_regular_rect_mesh( a=(0, 0), b=(2 * pi, 1), n=(8, 4), periodicity=(True, False), boundary_tagger=boundary_tagger, ) ]: for flux_type in StrongAdvectionOperator.flux_types: eoc_rec = EOCRecorder() for order in [1, 2, 3, 4, 5, 6]: discr = discr_class( mesh, TriangleDiscretization(order), debug=discr_class.noninteractive_debug_flags()) op = StrongAdvectionOperator( v, inflow_u=TimeDependentGivenFunction(u_analytic), flux_type=flux_type) u = discr.interpolate_volume_function( lambda x, el: u_analytic(x, el, 0)) stepper = RK4TimeStepper() dt = op.estimate_timestep(discr, stepper=stepper) nsteps = int(1 / dt) rhs = op.bind(discr) for step in range(nsteps): u = stepper(u, step * dt, dt, rhs) u_true = discr.interpolate_volume_function( lambda x, el: u_analytic(x, el, nsteps * dt)) error = u - u_true error_l2 = discr.norm(error) eoc_rec.add_data_point(order, error_l2) if False: print "%s\n%s\n" % (flux_type.upper(), "-" * len(flux_type)) print eoc_rec.pretty_print(abscissa_label="Poly. Order", error_label="L2 Error") assert eoc_rec.estimate_order_of_convergence()[0, 1] > 4 assert eoc_rec.estimate_order_of_convergence(2)[-1, 1] > 10
def main(write_output=True) : from math import sin, cos, pi, exp, sqrt from hedge.data import TimeConstantGivenFunction, \ ConstantGivenFunction from hedge.backends import guess_run_context rcon = guess_run_context() dim = 2 def boundary_tagger(fvi, el, fn, all_v): if el.face_normals[fn][0] > 0: return ["dirichlet"] else: return ["neumann"] 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) elif dim == 3: if rcon.is_head_rank: from hedge.mesh.generator import make_ball_mesh mesh = make_ball_mesh(max_volume=0.001) 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=3, debug=["cuda_no_plan"], default_scalar_type=numpy.float64) if write_output: from hedge.visualization import VtkVisualizer vis = VtkVisualizer(discr, rcon, "fld") def u0(x, el): if la.norm(x) < 0.2: return 1 else: return 0 def coeff(x, el): if x[0] < 0: return 0.25 else: return 1 def dirichlet_bc(t, x): return 0 def neumann_bc(t, x): return 2 from hedge.models.diffusion import DiffusionOperator op = DiffusionOperator(discr.dimensions, #coeff=coeff, dirichlet_tag="dirichlet", dirichlet_bc=TimeConstantGivenFunction(ConstantGivenFunction(0)), neumann_tag="neumann", neumann_bc=TimeConstantGivenFunction(ConstantGivenFunction(1)) ) u = discr.interpolate_volume_function(u0) # diagnostics setup ------------------------------------------------------- from pytools.log import LogManager, \ add_general_quantities, \ add_simulation_quantities, \ add_run_info if write_output: log_file_name = "heat.dat" else: log_file_name = None logmgr = LogManager(log_file_name, "w", rcon.communicator) add_run_info(logmgr) add_general_quantities(logmgr) add_simulation_quantities(logmgr) discr.add_instrumentation(logmgr) from hedge.log import LpNorm u_getter = lambda: u logmgr.add_quantity(LpNorm(u_getter, discr, 1, name="l1_u")) logmgr.add_quantity(LpNorm(u_getter, discr, name="l2_u")) logmgr.add_watches(["step.max", "t_sim.max", "l2_u", "t_step.max"]) # timestep loop ----------------------------------------------------------- from hedge.timestep.runge_kutta import LSRK4TimeStepper, ODE45TimeStepper from hedge.timestep.dumka3 import Dumka3TimeStepper #stepper = LSRK4TimeStepper() stepper = Dumka3TimeStepper(3, rtol=1e-6, rcon=rcon, vector_primitive_factory=discr.get_vector_primitive_factory(), dtype=discr.default_scalar_type) #stepper = ODE45TimeStepper(rtol=1e-6, rcon=rcon, #vector_primitive_factory=discr.get_vector_primitive_factory(), #dtype=discr.default_scalar_type) stepper.add_instrumentation(logmgr) rhs = op.bind(discr) try: next_dt = op.estimate_timestep(discr, stepper=LSRK4TimeStepper(), t=0, fields=u) from hedge.timestep import times_and_steps step_it = times_and_steps( final_time=0.1, logmgr=logmgr, max_dt_getter=lambda t: next_dt, taken_dt_getter=lambda: taken_dt) for step, t, dt in step_it: if step % 10 == 0 and write_output: visf = vis.make_file("fld-%04d" % step) vis.add_data(visf, [ ("u", discr.convert_volume(u, kind="numpy")), ], time=t, step=step) visf.close() u, t, taken_dt, next_dt = stepper(u, t, next_dt, rhs) #u = stepper(u, t, dt, rhs) assert discr.norm(u) < 1 finally: if write_output: vis.close() logmgr.close() discr.close()
def main(write_output=True): from math import sqrt, pi, exp from os.path import join from hedge.backends import guess_run_context rcon = guess_run_context() epsilon0 = 8.8541878176e-12 # C**2 / (N m**2) mu0 = 4 * pi * 1e-7 # N/A**2. epsilon = 1 * epsilon0 mu = 1 * mu0 output_dir = "maxwell-2d" import os if not os.access(output_dir, os.F_OK): os.makedirs(output_dir) from hedge.mesh.generator import make_disk_mesh mesh = make_disk_mesh(r=0.5, max_area=1e-3) if rcon.is_head_rank: mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() class CurrentSource: shape = (3, ) def __call__(self, x, el): return [0, 0, exp(-80 * la.norm(x))] order = 3 final_time = 1e-8 discr = rcon.make_discretization(mesh_data, order=order, debug=["cuda_no_plan"]) from hedge.visualization import VtkVisualizer if write_output: vis = VtkVisualizer(discr, rcon, join(output_dir, "em-%d" % order)) if rcon.is_head_rank: print "order %d" % order print "#elements=", len(mesh.elements) from hedge.mesh import TAG_ALL, TAG_NONE from hedge.models.em import TMMaxwellOperator from hedge.data import make_tdep_given, TimeIntervalGivenFunction op = TMMaxwellOperator(epsilon, mu, flux_type=1, current=TimeIntervalGivenFunction( make_tdep_given(CurrentSource()), off_time=final_time / 10), absorb_tag=TAG_ALL, pec_tag=TAG_NONE) fields = op.assemble_eh(discr=discr) from hedge.timestep import LSRK4TimeStepper stepper = LSRK4TimeStepper() from time import time last_tstep = time() t = 0 # diagnostics setup --------------------------------------------------- from pytools.log import LogManager, add_general_quantities, \ add_simulation_quantities, add_run_info if write_output: log_file_name = join(output_dir, "maxwell-%d.dat" % order) else: log_file_name = None logmgr = LogManager(log_file_name, "w", rcon.communicator) add_run_info(logmgr) add_general_quantities(logmgr) add_simulation_quantities(logmgr) discr.add_instrumentation(logmgr) stepper.add_instrumentation(logmgr) from pytools.log import IntervalTimer vis_timer = IntervalTimer("t_vis", "Time spent visualizing") logmgr.add_quantity(vis_timer) from hedge.log import EMFieldGetter, add_em_quantities field_getter = EMFieldGetter(discr, op, lambda: fields) add_em_quantities(logmgr, op, field_getter) logmgr.add_watches( ["step.max", "t_sim.max", ("W_field", "W_el+W_mag"), "t_step.max"]) # timestep loop ------------------------------------------------------- rhs = op.bind(discr) try: from hedge.timestep import times_and_steps step_it = times_and_steps( final_time=final_time, logmgr=logmgr, max_dt_getter=lambda t: op.estimate_timestep( discr, stepper=stepper, t=t, fields=fields)) for step, t, dt in step_it: if step % 10 == 0 and write_output: e, h = op.split_eh(fields) visf = vis.make_file( join(output_dir, "em-%d-%04d" % (order, step))) vis.add_data(visf, [ ("e", discr.convert_volume(e, "numpy")), ("h", discr.convert_volume(h, "numpy")), ], time=t, step=step) visf.close() fields = stepper(fields, t, dt, rhs) assert discr.norm(fields) < 0.03 finally: if write_output: vis.close() logmgr.close() discr.close()
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 main(write_output=True): from math import sqrt, pi, exp from os.path import join from hedge.backends import guess_run_context rcon = guess_run_context() epsilon0 = 8.8541878176e-12 # C**2 / (N m**2) mu0 = 4*pi*1e-7 # N/A**2. epsilon = 1*epsilon0 mu = 1*mu0 output_dir = "maxwell-2d" import os if not os.access(output_dir, os.F_OK): os.makedirs(output_dir) from hedge.mesh.generator import make_disk_mesh mesh = make_disk_mesh(r=0.5, max_area=1e-3) if rcon.is_head_rank: mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() class CurrentSource: shape = (3,) def __call__(self, x, el): return [0,0,exp(-80*la.norm(x))] order = 3 final_time = 1e-8 discr = rcon.make_discretization(mesh_data, order=order, debug=["cuda_no_plan"]) from hedge.visualization import VtkVisualizer if write_output: vis = VtkVisualizer(discr, rcon, join(output_dir, "em-%d" % order)) if rcon.is_head_rank: print "order %d" % order print "#elements=", len(mesh.elements) from hedge.mesh import TAG_ALL, TAG_NONE from hedge.models.em import TMMaxwellOperator from hedge.data import make_tdep_given, TimeIntervalGivenFunction op = TMMaxwellOperator(epsilon, mu, flux_type=1, current=TimeIntervalGivenFunction( make_tdep_given(CurrentSource()), off_time=final_time/10), absorb_tag=TAG_ALL, pec_tag=TAG_NONE) fields = op.assemble_eh(discr=discr) from hedge.timestep import LSRK4TimeStepper stepper = LSRK4TimeStepper() from time import time last_tstep = time() t = 0 # diagnostics setup --------------------------------------------------- from pytools.log import LogManager, add_general_quantities, \ add_simulation_quantities, add_run_info if write_output: log_file_name = join(output_dir, "maxwell-%d.dat" % order) else: log_file_name = None logmgr = LogManager(log_file_name, "w", rcon.communicator) add_run_info(logmgr) add_general_quantities(logmgr) add_simulation_quantities(logmgr) discr.add_instrumentation(logmgr) stepper.add_instrumentation(logmgr) from pytools.log import IntervalTimer vis_timer = IntervalTimer("t_vis", "Time spent visualizing") logmgr.add_quantity(vis_timer) from hedge.log import EMFieldGetter, add_em_quantities field_getter = EMFieldGetter(discr, op, lambda: fields) add_em_quantities(logmgr, op, field_getter) logmgr.add_watches(["step.max", "t_sim.max", ("W_field", "W_el+W_mag"), "t_step.max"]) # timestep loop ------------------------------------------------------- rhs = op.bind(discr) try: from hedge.timestep import times_and_steps step_it = times_and_steps( final_time=final_time, logmgr=logmgr, max_dt_getter=lambda t: op.estimate_timestep(discr, stepper=stepper, t=t, fields=fields)) for step, t, dt in step_it: if step % 10 == 0 and write_output: e, h = op.split_eh(fields) visf = vis.make_file(join(output_dir, "em-%d-%04d" % (order, step))) vis.add_data(visf, [ ("e", discr.convert_volume(e, "numpy")), ("h", discr.convert_volume(h, "numpy")), ], time=t, step=step ) visf.close() fields = stepper(fields, t, dt, rhs) assert discr.norm(fields) < 0.03 finally: if write_output: vis.close() logmgr.close() discr.close()
def main(write_output=True, flux_type_arg="upwind"): from hedge.tools import mem_checkpoint from math import sin, cos, pi, sqrt from math import floor from hedge.backends import guess_run_context rcon = guess_run_context() def f(x): return sin(pi * x) def u_analytic(x, el, t): return f((-numpy.dot(v, x) / norm_v + t * norm_v)) def boundary_tagger(vertices, el, face_nr, all_v): if numpy.dot(el.face_normals[face_nr], v) < 0: return ["inflow"] else: return ["outflow"] dim = 2 if dim == 1: v = numpy.array([1]) if rcon.is_head_rank: from hedge.mesh.generator import make_uniform_1d_mesh mesh = make_uniform_1d_mesh(0, 2, 10, periodic=True) elif dim == 2: v = numpy.array([2, 0]) if rcon.is_head_rank: from hedge.mesh.generator import make_disk_mesh mesh = make_disk_mesh(boundary_tagger=boundary_tagger) elif dim == 3: v = numpy.array([0, 0, 1]) if rcon.is_head_rank: from hedge.mesh.generator import make_cylinder_mesh, make_ball_mesh, make_box_mesh mesh = make_cylinder_mesh(max_volume=0.04, height=2, boundary_tagger=boundary_tagger, periodic=False, radial_subdivisions=32) else: raise RuntimeError, "bad number of dimensions" norm_v = la.norm(v) if rcon.is_head_rank: mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() if dim != 1: mesh_data = mesh_data.reordered_by("cuthill") discr = rcon.make_discretization(mesh_data, order=4) vis_discr = discr from hedge.visualization import VtkVisualizer if write_output: vis = VtkVisualizer(vis_discr, rcon, "fld") # operator setup ---------------------------------------------------------- from hedge.data import \ ConstantGivenFunction, \ TimeConstantGivenFunction, \ TimeDependentGivenFunction from hedge.models.advection import StrongAdvectionOperator, WeakAdvectionOperator op = WeakAdvectionOperator(v, inflow_u=TimeDependentGivenFunction(u_analytic), flux_type=flux_type_arg) u = discr.interpolate_volume_function(lambda x, el: u_analytic(x, el, 0)) # timestep setup ---------------------------------------------------------- from hedge.timestep.runge_kutta import LSRK4TimeStepper stepper = LSRK4TimeStepper() if rcon.is_head_rank: print "%d elements" % len(discr.mesh.elements) # diagnostics setup ------------------------------------------------------- from pytools.log import LogManager, \ add_general_quantities, \ add_simulation_quantities, \ add_run_info if write_output: log_file_name = "advection.dat" else: log_file_name = None logmgr = LogManager(log_file_name, "w", rcon.communicator) add_run_info(logmgr) add_general_quantities(logmgr) add_simulation_quantities(logmgr) discr.add_instrumentation(logmgr) stepper.add_instrumentation(logmgr) from hedge.log import Integral, LpNorm u_getter = lambda: u logmgr.add_quantity(Integral(u_getter, discr, name="int_u")) logmgr.add_quantity(LpNorm(u_getter, discr, p=1, name="l1_u")) logmgr.add_quantity(LpNorm(u_getter, discr, name="l2_u")) logmgr.add_watches(["step.max", "t_sim.max", "l2_u", "t_step.max"]) # timestep loop ----------------------------------------------------------- rhs = op.bind(discr) try: from hedge.timestep import times_and_steps step_it = times_and_steps(final_time=3, logmgr=logmgr, max_dt_getter=lambda t: op.estimate_timestep( discr, stepper=stepper, t=t, fields=u)) for step, t, dt in step_it: if step % 5 == 0 and write_output: visf = vis.make_file("fld-%04d" % step) vis.add_data(visf, [ ("u", discr.convert_volume(u, kind="numpy")), ], time=t, step=step) visf.close() u = stepper(u, t, dt, rhs) true_u = discr.interpolate_volume_function( lambda x, el: u_analytic(x, el, t)) print discr.norm(u - true_u) assert discr.norm(u - true_u) < 1e-2 finally: if write_output: vis.close() logmgr.close() discr.close()