def my_health_check(dv): health_error = False from mirgecom.simutil import check_naninf_local, check_range_local if check_naninf_local(discr, "vol", dv.pressure) \ or check_range_local(discr, "vol", dv.pressure, 1e5, 2.4e5): health_error = True logger.info(f"{rank=}: Invalid pressure data found.") if check_range_local(discr, "vol", dv.temperature, 1.498e3, 1.52e3): health_error = True logger.info(f"{rank=}: Invalid temperature data found.") return health_error
def my_health_check(pressure): health_error = False from mirgecom.simutil import check_naninf_local, check_range_local if check_naninf_local(discr, "vol", pressure) \ or check_range_local(discr, "vol", pressure, .8, 1.5): health_error = True logger.info(f"{rank=}: Invalid pressure data found.") return health_error
def my_health_check(cv, dv): import grudge.op as op health_error = False pressure = dv.pressure temperature = dv.temperature from mirgecom.simutil import check_naninf_local, check_range_local if check_naninf_local(discr, "vol", pressure): health_error = True logger.info(f"{rank=}: Invalid pressure data found.") if check_range_local(discr, "vol", pressure, 1e5, 2.6e5): health_error = True logger.info(f"{rank=}: Pressure range violation.") if check_naninf_local(discr, "vol", temperature): health_error = True logger.info(f"{rank=}: Invalid temperature data found.") if check_range_local(discr, "vol", temperature, 1.498e3, 1.6e3): health_error = True logger.info(f"{rank=}: Temperature range violation.") # This check is the temperature convergence check # The current *temperature* is what Pyrometheus gets # after a fixed number of Newton iterations, *n_iter*. # Calling `compute_temperature` here with *temperature* # input as the guess returns the calculated gas temperature after # yet another *n_iter*. # The difference between those two temperatures is the # temperature residual, which can be used as an indicator of # convergence in Pyrometheus `get_temperature`. # Note: The local max jig below works around a very long compile # in lazy mode. temp_resid = compute_temperature_update(cv, temperature) / temperature temp_err = (actx.to_numpy(op.nodal_max_loc(discr, "vol", temp_resid))) if temp_err > 1e-8: health_error = True logger.info( f"{rank=}: Temperature is not converged {temp_resid=}.") return health_error
def my_health_check(pressure, component_errors): health_error = False from mirgecom.simutil import check_naninf_local, check_range_local if check_naninf_local(discr, "vol", pressure) \ or check_range_local(discr, "vol", pressure, .99999999, 1.00000001): health_error = True logger.info(f"{rank=}: Invalid pressure data found.") exittol = .09 if max(component_errors) > exittol: health_error = True if rank == 0: logger.info("Solution diverged from exact soln.") return health_error
def my_checkpoint(step, t, dt, state, force=False): do_health = force or check_step(step, nhealth) and step > 0 do_viz = force or check_step(step, nviz) do_restart = force or check_step(step, nrestart) do_status = force or check_step(step, nstatus) if do_viz or do_health: dv = eos.dependent_vars(state) errors = False if do_health: health_message = "" if check_naninf_local(discr, "vol", dv.pressure): errors = True health_message += "Invalid pressure data found.\n" elif check_range_local(discr, "vol", dv.pressure, min_value=1, max_value=2.e6): errors = True health_message += "Pressure data failed health check.\n" errors = comm.allreduce(errors, MPI.LOR) if errors: if rank == 0: logger.info("Fluid solution failed health check.") if health_message: logger.info(f"{rank=}: {health_message}") #if check_step(step, nrestart) and step != restart_step and not errors: if do_restart or errors: filename = restart_path + snapshot_pattern.format( step=step, rank=rank, casename=casename) restart_dictionary = { "local_mesh": local_mesh, "order": order, "state": state, "t": t, "step": step, "global_nelements": global_nelements, "num_parts": nparts } write_restart_file(actx, restart_dictionary, filename, comm) if do_status or do_viz or errors: local_cfl = get_inviscid_cfl(discr, eos=eos, dt=dt, cv=state) max_cfl = nodal_max(discr, "vol", local_cfl) log_cfl.set_quantity(max_cfl) #if ((check_step(step, nviz) and step != restart_step) or errors): if do_viz or errors: def loc_fn(t): return flame_start_loc + flame_speed * t #exact_soln = PlanarDiscontinuity(dim=dim, disc_location=loc_fn, #sigma=0.0000001, nspecies=nspecies, #temperature_left=temp_ignition, temperature_right=temp_unburned, #pressure_left=pres_burned, pressure_right=pres_unburned, #velocity_left=vel_burned, velocity_right=vel_unburned, #species_mass_left=y_burned, species_mass_right=y_unburned) reaction_rates = eos.get_production_rates(cv=state) # conserved quantities viz_fields = [ #("cv", state), ("CV_rho", state.mass), ("CV_rhoU", state.momentum[0]), ("CV_rhoV", state.momentum[1]), ("CV_rhoE", state.energy) ] # species mass fractions viz_fields.extend( ("Y_" + species_names[i], state.species_mass[i] / state.mass) for i in range(nspecies)) # dependent variables viz_fields.extend([ ("DV", eos.dependent_vars(state)), #("exact_soln", exact_soln), ("reaction_rates", reaction_rates), ("cfl", local_cfl) ]) write_visfile(discr, viz_fields, visualizer, vizname=viz_path + casename, step=step, t=t, overwrite=True, vis_timer=vis_timer) if errors: raise RuntimeError("Error detected by user checkpoint, exiting.")
def test_basic_cfd_healthcheck(actx_factory): """Quick test of some health checking utilities.""" actx = actx_factory() nel_1d = 4 dim = 2 from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh( a=(1.0,) * dim, b=(2.0,) * dim, nelements_per_axis=(nel_1d,) * dim ) order = 3 discr = EagerDGDiscretization(actx, mesh, order=order) nodes = thaw(discr.nodes(), actx) zeros = discr.zeros(actx) ones = zeros + 1.0 # Let's make a very bad state (negative mass) mass = -1*ones velocity = 2 * nodes mom = mass * velocity energy = zeros + .5*np.dot(mom, mom)/mass eos = IdealSingleGas() cv = make_conserved(dim, mass=mass, energy=energy, momentum=mom) pressure = eos.pressure(cv) from mirgecom.simutil import check_range_local assert check_range_local(discr, "vol", mass, min_value=0, max_value=np.inf) assert check_range_local(discr, "vol", pressure, min_value=1e-6, max_value=np.inf) # Let's make another very bad state (nans) mass = 1*ones energy = zeros + 2.5 velocity = np.nan * nodes mom = mass * velocity cv = make_conserved(dim, mass=mass, energy=energy, momentum=mom) pressure = eos.pressure(cv) from mirgecom.simutil import check_naninf_local assert check_naninf_local(discr, "vol", pressure) # Let's make one last very bad state (inf) mass = 1*ones energy = np.inf * ones velocity = 2 * nodes mom = mass * velocity cv = make_conserved(dim, mass=mass, energy=energy, momentum=mom) pressure = eos.pressure(cv) assert check_naninf_local(discr, "vol", pressure) # What the hey, test a good one energy = 2.5 + .5*np.dot(mom, mom) cv = make_conserved(dim, mass=mass, energy=energy, momentum=mom) pressure = eos.pressure(cv) assert not check_naninf_local(discr, "vol", pressure) assert not check_range_local(discr, "vol", pressure, min_value=0, max_value=np.inf)