Source code for yt.frontends.gamer.fields

from yt._typing import KnownFieldsT
from yt.fields.field_info_container import FieldInfoContainer
from yt.fields.tensor_fields import setup_stress_energy_ideal

from .cfields import SRHDFields

b_units = "code_magnetic"
pre_units = "code_mass / (code_length*code_time**2)"
erg_units = "code_mass / (code_length*code_time**2)"
rho_units = "code_mass / code_length**3"
mom_units = "code_mass / (code_length**2*code_time)"
vel_units = "code_velocity"
pot_units = "code_length**2/code_time**2"

psi_units = "code_mass**(1/2) / code_length**(3/2)"


[docs] class GAMERFieldInfo(FieldInfoContainer): known_other_fields: KnownFieldsT = ( # hydro fields on disk (GAMER outputs conservative variables) ("Dens", (rho_units, [], None)), ("MomX", (mom_units, ["momentum_density_x"], None)), ("MomY", (mom_units, ["momentum_density_y"], None)), ("MomZ", (mom_units, ["momentum_density_z"], None)), ("Engy", (erg_units, ["total_energy_density"], None)), ("Pote", (pot_units, ["gravitational_potential"], None)), # MHD fields on disk (CC=cell-centered) ("CCMagX", (b_units, [], "B_x")), ("CCMagY", (b_units, [], "B_y")), ("CCMagZ", (b_units, [], "B_z")), # psiDM fields on disk ("Real", (psi_units, ["psidm_real_part"], None)), ("Imag", (psi_units, ["psidm_imaginary_part"], None)), # particle fields on disk (deposited onto grids) ("ParDens", (rho_units, ["particle_density_on_grid"], None)), ("TotalDens", (rho_units, ["total_density_on_grid"], None)), ) known_particle_fields: KnownFieldsT = ( ("ParMass", ("code_mass", ["particle_mass"], None)), ("ParPosX", ("code_length", ["particle_position_x"], None)), ("ParPosY", ("code_length", ["particle_position_y"], None)), ("ParPosZ", ("code_length", ["particle_position_z"], None)), ("ParVelX", ("code_velocity", ["particle_velocity_x"], None)), ("ParVelY", ("code_velocity", ["particle_velocity_y"], None)), ("ParVelZ", ("code_velocity", ["particle_velocity_z"], None)), ("ParCreTime", ("code_time", ["particle_creation_time"], None)), ) def __init__(self, ds, field_list): super().__init__(ds, field_list) # add primitive and other derived variables
[docs] def setup_fluid_fields(self): pc = self.ds.units.physical_constants from yt.fields.magnetic_field import setup_magnetic_field_aliases unit_system = self.ds.unit_system unit_system.registry = self.ds.unit_registry # TODO: Why do I need this?! if self.ds.srhd: c2 = pc.clight * pc.clight c = pc.clight.in_units("code_length / code_time") if self.ds.eos == 4: fgen = SRHDFields(self.ds.eos, 0.0, c.d) else: fgen = SRHDFields(self.ds.eos, self.ds.gamma, c.d) def _sound_speed(field, data): out = fgen.sound_speed(data["gamer", "Temp"].d) return data.ds.arr(out, "code_velocity").to(unit_system["velocity"]) def _gamma(field, data): out = fgen.gamma_field(data["gamer", "Temp"].d) return data.ds.arr(out, "dimensionless") # coordinate frame density self.alias( ("gas", "frame_density"), ("gamer", "Dens"), units=unit_system["density"], ) self.add_field( ("gas", "gamma"), sampling_type="cell", function=_gamma, units="" ) # 4-velocity spatial components def four_velocity_xyz(u): def _four_velocity(field, data): out = fgen.four_velocity_xyz( data["gamer", f"Mom{u.upper()}"].d, data["gamer", "Dens"].d, data["gamer", "Temp"].d, ) return data.ds.arr(out, "code_velocity").to(unit_system["velocity"]) return _four_velocity for u in "xyz": self.add_field( ("gas", f"four_velocity_{u}"), sampling_type="cell", function=four_velocity_xyz(u), units=unit_system["velocity"], ) # lorentz factor def _lorentz_factor(field, data): out = fgen.lorentz_factor( data["gamer", "Dens"].d, data["gamer", "MomX"].d, data["gamer", "MomY"].d, data["gamer", "MomZ"].d, data["gamer", "Temp"].d, ) return data.ds.arr(out, "dimensionless") self.add_field( ("gas", "lorentz_factor"), sampling_type="cell", function=_lorentz_factor, units="", ) # velocity def velocity_xyz(v): def _velocity(field, data): out = fgen.velocity_xyz( data["gamer", "Dens"].d, data["gamer", "MomX"].d, data["gamer", "MomY"].d, data["gamer", "MomZ"].d, data["gamer", "Temp"].d, data["gamer", f"Mom{v.upper()}"].d, ) return data.ds.arr(out, "code_velocity").to(unit_system["velocity"]) return _velocity for v in "xyz": self.add_field( ("gas", f"velocity_{v}"), sampling_type="cell", function=velocity_xyz(v), units=unit_system["velocity"], ) # density def _density(field, data): dens = fgen.density( data["gamer", "Dens"].d, data["gamer", "MomX"].d, data["gamer", "MomY"].d, data["gamer", "MomZ"].d, data["gamer", "Temp"].d, ) return data.ds.arr(dens, rho_units).to(unit_system["density"]) self.add_field( ("gas", "density"), sampling_type="cell", function=_density, units=unit_system["density"], ) # pressure def _pressure(field, data): out = fgen.pressure( data["gamer", "Dens"].d, data["gamer", "MomX"].d, data["gamer", "MomY"].d, data["gamer", "MomZ"].d, data["gamer", "Temp"].d, ) return data.ds.arr(out, pre_units).to(unit_system["pressure"]) # thermal energy per mass (i.e., specific) def _specific_thermal_energy(field, data): out = fgen.specific_thermal_energy( data["gamer", "Dens"].d, data["gamer", "MomX"].d, data["gamer", "MomY"].d, data["gamer", "MomZ"].d, data["gamer", "Temp"].d, ) return data.ds.arr(out, "code_length**2 / code_time**2").to( unit_system["specific_energy"] ) # total energy per mass def _specific_total_energy(field, data): E = data["gamer", "Engy"] + data["gamer", "Dens"] * c2 return E / data["gamer", "Dens"] def _kinetic_energy_density(field, data): out = fgen.kinetic_energy_density( data["gamer", "Dens"].d, data["gamer", "MomX"].d, data["gamer", "MomY"].d, data["gamer", "MomZ"].d, data["gamer", "Temp"].d, ) return data.ds.arr(out, erg_units).to(unit_system["pressure"]) self.add_field( ("gas", "kinetic_energy_density"), sampling_type="cell", function=_kinetic_energy_density, units=unit_system["pressure"], ) self.add_field( ("gas", "kinetic_energy_density"), sampling_type="cell", function=_kinetic_energy_density, units=unit_system["pressure"], ) self.add_field( ("gas", "sound_speed"), sampling_type="cell", function=_sound_speed, units=unit_system["velocity"], ) def _mach_number(field, data): out = fgen.mach_number( data["gamer", "Dens"].d, data["gamer", "MomX"].d, data["gamer", "MomY"].d, data["gamer", "MomZ"].d, data["gamer", "Temp"].d, ) return data.ds.arr(out, "dimensionless") self.add_field( ("gas", "mach_number"), sampling_type="cell", function=_mach_number, units="", ) setup_stress_energy_ideal(self) else: # not RHD # density self.alias( ("gas", "density"), ("gamer", "Dens"), units=unit_system["density"] ) # velocity def velocity_xyz(v): def _velocity(field, data): return data["gas", f"momentum_density_{v}"] / data["gas", "density"] return _velocity for v in "xyz": self.add_field( ("gas", f"velocity_{v}"), sampling_type="cell", function=velocity_xyz(v), units=unit_system["velocity"], ) # ==================================================== # note that yt internal fields assume # [specific_thermal_energy] = [energy per mass] # [kinetic_energy_density] = [energy per volume] # [magnetic_energy_density] = [energy per volume] # and we further adopt # [specific_total_energy] = [energy per mass] # [total_energy_density] = [energy per volume] # ==================================================== # thermal energy per volume def et(data): ek = ( 0.5 * ( data["gamer", "MomX"] ** 2 + data["gamer", "MomY"] ** 2 + data["gamer", "MomZ"] ** 2 ) / data["gamer", "Dens"] ) Et = data["gamer", "Engy"] - ek if self.ds.mhd: # magnetic_energy is a yt internal field Et -= data["gas", "magnetic_energy_density"] return Et # thermal energy per mass (i.e., specific) def _specific_thermal_energy(field, data): return et(data) / data["gamer", "Dens"] # total energy per mass def _specific_total_energy(field, data): return data["gamer", "Engy"] / data["gamer", "Dens"] # pressure def _pressure(field, data): return et(data) * (data.ds.gamma - 1.0) self.add_field( ("gas", "specific_thermal_energy"), sampling_type="cell", function=_specific_thermal_energy, units=unit_system["specific_energy"], ) def _thermal_energy_density(field, data): return data["gas", "density"] * data["gas", "specific_thermal_energy"] self.add_field( ("gas", "thermal_energy_density"), sampling_type="cell", function=_thermal_energy_density, units=unit_system["pressure"], ) self.add_field( ("gas", "specific_total_energy"), sampling_type="cell", function=_specific_total_energy, units=unit_system["specific_energy"], ) self.add_field( ("gas", "pressure"), sampling_type="cell", function=_pressure, units=unit_system["pressure"], ) # mean molecular weight if hasattr(self.ds, "mu"): def _mu(field, data): return data.ds.mu * data["index", "ones"] self.add_field( ("gas", "mean_molecular_weight"), sampling_type="cell", function=_mu, units="", ) # temperature def _temperature(field, data): return ( data.ds.mu * data["gas", "pressure"] * pc.mh / (data["gas", "density"] * pc.kb) ) self.add_field( ("gas", "temperature"), sampling_type="cell", function=_temperature, units=unit_system["temperature"], ) # magnetic field aliases --> magnetic_field_x/y/z if self.ds.mhd: setup_magnetic_field_aliases(self, "gamer", [f"CCMag{v}" for v in "XYZ"])
[docs] def setup_particle_fields(self, ptype): super().setup_particle_fields(ptype)