Esempio n. 1
0
def _write_attrib(obj_list, k, v, hd):
    #print('obj_list: ',dir(obj_list))
    #print('k: ',k)
    #print('v: ', v)

    unit = False
    if isinstance(v, YTQuantity):
        data = [getattr(i, k).d for i in obj_list]
        unit = True
    elif isinstance(v, YTArray):
        if np.shape(v)[0] == 3:
            data = np.vstack([getattr(i, k).d for i in obj_list])
        else:
            data = [getattr(i, k).d for i in obj_list]
        unit = True
    elif isinstance(v, np.ndarray) and np.shape(v)[0] == 3 and 'list' not in k:
        try:
            data = np.vstack([getattr(i, k) for i in obj_list])
        except:
            mylog.warning('Saver unable to stack: %s %s %s', k, v, np.shape(v))
            return
    elif isinstance(v, (int, float, bool, np.number)):
        data = [getattr(i, k) for i in obj_list]
    else:
        return

    _write_dataset(k, data, hd)
    if unit:
        hd[k].attrs.create('unit', str(v.units).encode('utf8'))
Esempio n. 2
0
 def set_field(self, name, value):
     """
     Set a field with name *name* to value *value*, which is a YTArray.
     The array will be checked to make sure that it has the appropriate size.
     """
     if not isinstance(value, YTArray):
         raise TypeError("value needs to be a YTArray")
     if len(value) == self.num_elements:
         if name in self.fields:
             mylog.warning("Overwriting field %s." % name)
         self.fields[name] = value
     else:
         raise ValueError("The length of the array needs to be %d elements!"
                          % self.num_elements)
Esempio n. 3
0
    def setup_fluid_fields(self):

        setup_magnetic_field_aliases(self, "amrvac",
                                     [f"mag{ax}" for ax in "xyz"])
        self._setup_velocity_fields()  # gas velocities
        self._setup_dust_fields()  # dust derived fields (including velocities)

        # fields with nested dependencies are defined thereafter
        # by increasing level of complexity
        us = self.ds.unit_system

        def _kinetic_energy_density(field, data):
            # devnote : have a look at issue 1301
            return 0.5 * data["gas", "density"] * data["gas",
                                                       "velocity_magnitude"]**2

        self.add_field(
            ("gas", "kinetic_energy_density"),
            function=_kinetic_energy_density,
            units=us["density"] * us["velocity"]**2,
            dimensions=dimensions.density * dimensions.velocity**2,
            sampling_type="cell",
        )

        # magnetic energy density
        if ("amrvac", "b1") in self.field_list:

            def _magnetic_energy_density(field, data):
                emag = 0.5 * data["gas", "magnetic_1"]**2
                for idim in "23":
                    if not ("amrvac", f"b{idim}") in self.field_list:
                        break
                    emag += 0.5 * data["gas", f"magnetic_{idim}"]**2
                # in AMRVAC the magnetic field is defined in units where mu0 = 1,
                # such that
                # Emag = 0.5*B**2 instead of Emag = 0.5*B**2 / mu0
                # To correctly transform the dimensionality from gauss**2 -> rho*v**2,
                # we have to take mu0 into account. If we divide here, units when adding
                # the field should be us["density"]*us["velocity"]**2.
                # If not, they should be us["magnetic_field"]**2 and division should
                # happen elsewhere.
                emag /= 4 * np.pi
                # divided by mu0 = 4pi in cgs,
                # yt handles 'mks' and 'code' unit systems internally.
                return emag

            self.add_field(
                ("gas", "magnetic_energy_density"),
                function=_magnetic_energy_density,
                units=us["density"] * us["velocity"]**2,
                dimensions=dimensions.density * dimensions.velocity**2,
                sampling_type="cell",
            )

        # Adding the thermal pressure field.
        # In AMRVAC we have multiple physics possibilities:
        # - if HD/MHD + energy equation P = (gamma-1)*(e - ekin (- emag)) for (M)HD
        # - if HD/MHD but solve_internal_e is true in parfile, P = (gamma-1)*e for both
        # - if (m)hd_energy is false in parfile (isothermal), P = c_adiab * rho**gamma

        def _full_thermal_pressure_HD(field, data):
            # energy density and pressure are actually expressed in the same unit
            pthermal = (data.ds.gamma -
                        1) * (data["gas", "energy_density"] -
                              data["gas", "kinetic_energy_density"])
            return pthermal

        def _full_thermal_pressure_MHD(field, data):
            pthermal = (
                _full_thermal_pressure_HD(field, data) -
                (data.ds.gamma - 1) * data["gas", "magnetic_energy_density"])
            return pthermal

        def _polytropic_thermal_pressure(field, data):
            return (data.ds.gamma - 1) * data["gas", "energy_density"]

        def _adiabatic_thermal_pressure(field, data):
            return data.ds._c_adiab * data["gas", "density"]**data.ds.gamma

        pressure_recipe = None
        if ("amrvac", "e") in self.field_list:
            if self.ds._e_is_internal:
                pressure_recipe = _polytropic_thermal_pressure
                mylog.info("Using polytropic EoS for thermal pressure.")
            elif ("amrvac", "b1") in self.field_list:
                pressure_recipe = _full_thermal_pressure_MHD
                mylog.info("Using full MHD energy for thermal pressure.")
            else:
                pressure_recipe = _full_thermal_pressure_HD
                mylog.info("Using full HD energy for thermal pressure.")
        elif self.ds._c_adiab is not None:
            pressure_recipe = _adiabatic_thermal_pressure
            mylog.info(
                "Using adiabatic EoS for thermal pressure (isothermal).")
            mylog.warning("If you used usr_set_pthermal you should "
                          "redefine the thermal_pressure field.")

        if pressure_recipe is not None:
            self.add_field(
                ("gas", "thermal_pressure"),
                function=pressure_recipe,
                units=us["density"] * us["velocity"]**2,
                dimensions=dimensions.density * dimensions.velocity**2,
                sampling_type="cell",
            )

            # sound speed and temperature depend on thermal pressure
            def _sound_speed(field, data):
                return np.sqrt(data.ds.gamma *
                               data["gas", "thermal_pressure"] /
                               data["gas", "density"])

            self.add_field(
                ("gas", "sound_speed"),
                function=_sound_speed,
                units=us["velocity"],
                dimensions=dimensions.velocity,
                sampling_type="cell",
            )
        else:
            mylog.warning(
                "e not found and no parfile passed, can not set thermal_pressure."
            )
Esempio n. 4
0
def save(obj, filename='test.hdf5'):
    """Function to save a CAESAR file to disk.

    Parameters
    ----------
    obj : :class:`main.CAESAR`
        Main caesar object to save.
    filename : str, optional
        Filename of the output file.

    Examples
    --------
    >>> obj.save('output.hdf5')
    
    """
    from yt.funcs import mylog

    if os.path.isfile(filename):
        mylog.warning('%s already present, overwriting!' % filename)
        os.remove(filename)
    mylog.info('Writing %s' % filename)

    outfile = h5py.File(filename, 'w')
    outfile.attrs.create('caesar', 315)

    unit_registry = obj.yt_dataset.unit_registry.to_json()
    outfile.attrs.create('unit_registry_json', unit_registry.encode('utf8'))

    serialize_global_attribs(obj, outfile)
    obj.simulation._serialize(obj, outfile)

    if hasattr(obj, 'halos') and obj.nhalos > 0:
        hd = outfile.create_group('halo_data')
        hdd = hd.create_group('lists')
        hddd = hd.create_group('dicts')

        # gather
        index_lists = ['dmlist']
        if 'gas' in obj.data_manager.ptypes: index_lists.append('glist')
        if 'star' in obj.data_manager.ptypes:
            index_lists.extend(['slist', 'galaxy_index_list'])
        if 'dm2' in obj.data_manager.ptypes: index_lists.append('dm2list')
        if 'dm3' in obj.data_manager.ptypes: index_lists.append('dm3list')
        if obj.data_manager.blackholes:
            index_lists.append('bhlist')
        if obj.data_manager.dust:
            index_lists.append('dlist')

        #write
        for vals in index_lists:
            serialize_list(obj.halos, vals, hdd)
        serialize_attributes(obj.halos, hd, hddd)

    if hasattr(obj, 'galaxies') and obj.ngalaxies > 0:
        hd = outfile.create_group('galaxy_data')
        hdd = hd.create_group('lists')
        hddd = hd.create_group('dicts')

        # gather
        index_lists = ['glist', 'slist', 'cloud_index_list']
        if obj.data_manager.blackholes:
            index_lists.append('bhlist')
        if obj.data_manager.dust:
            index_lists.append('dlist')

        # write
        for vals in index_lists:
            serialize_list(obj.galaxies, vals, hdd)
        serialize_attributes(obj.galaxies, hd, hddd)

    if hasattr(obj, 'clouds') and obj.nclouds > 0:
        hd = outfile.create_group('cloud_data')
        hdd = hd.create_group('lists')
        hddd = hd.create_group('dicts')

        # gather
        index_lists = ['glist']

        # write
        for vals in index_lists:
            serialize_list(obj.clouds, vals, hdd)
        serialize_attributes(obj.clouds, hd, hddd)

    if hasattr(obj, 'global_particle_lists'):
        hd = outfile.create_group('global_lists')

        # gather
        global_index_lists = [
            'halo_dmlist', 'halo_glist', 'halo_slist', 'galaxy_glist',
            'galaxy_slist', 'cloud_glist'
        ]
        if obj.data_manager.blackholes:
            global_index_lists.extend(['halo_bhlist', 'galaxy_bhlist'])
        if obj.data_manager.dust:
            global_index_lists.extend(['halo_dlist', 'galaxy_dlist'])

        # write
        for vals in global_index_lists:
            check_and_write_dataset(obj.global_particle_lists, vals, hd)

    outfile.close()
Esempio n. 5
0
File: fields.py Progetto: nozhanb/yt
    def setup_fluid_fields(self):
        def _v1(field, data):
            return data["gas", "moment_1"] / data["gas", "density"]

        def _v2(field, data):
            return data["gas", "moment_2"] / data["gas", "density"]

        def _v3(field, data):
            return data["gas", "moment_3"] / data["gas", "density"]

        us = self.ds.unit_system
        aliases = direction_aliases[self.ds.geometry]
        for idir, alias, func in zip("123", aliases, (_v1, _v2, _v3)):
            if not ("amrvac", "m%s" % idir) in self.field_list:
                break
            self.add_field(("gas", "velocity_%s" % alias),
                           function=func,
                           units=us['velocity'],
                           dimensions=dimensions.velocity,
                           sampling_type="cell")
            self.alias(("gas", "velocity_%s" % idir),
                       ("gas", "velocity_%s" % alias),
                       units=us["velocity"])
            self.alias(("gas", "moment_%s" % alias),
                       ("gas", "moment_%s" % idir),
                       units=us["density"] * us["velocity"])

        setup_magnetic_field_aliases(self, "amrvac",
                                     ["mag%s" % ax for ax in "xyz"])

        # fields with nested dependencies are defined thereafter by increasing level of complexity

        # kinetic pressure is given by 0.5 * rho * v**2
        def _kinetic_energy_density(field, data):
            # devnote : have a look at issue 1301
            return 0.5 * data['gas', 'density'] * data['gas',
                                                       'velocity_magnitude']**2

        self.add_field(("gas", "kinetic_energy_density"),
                       function=_kinetic_energy_density,
                       units=us["density"] * us["velocity"]**2,
                       dimensions=dimensions.density * dimensions.velocity**2,
                       sampling_type="cell")

        # magnetic energy density
        if ('amrvac', 'b1') in self.field_list:

            def _magnetic_energy_density(field, data):
                emag = 0.5 * data['gas', 'magnetic_1']**2
                for idim in '23':
                    if not ('amrvac', 'b%s' % idim) in self.field_list:
                        break
                    emag += 0.5 * data['gas', 'magnetic_%s' % idim]**2
                # important note: in AMRVAC the magnetic field is defined in units where mu0 = 1, such that
                # Emag = 0.5*B**2 instead of Emag = 0.5*B**2 / mu0
                # To correctly transform the dimensionality from gauss**2 -> rho*v**2, we have to take mu0 into account.
                # If we divide here, units when adding the field should be us["density"]*us["velocity"]**2
                # If not, they should be us["magnetic_field"]**2 and division should happen elsewhere.
                emag /= 4 * np.pi
                # divided by mu0 = 4pi in cgs, yt handles 'mks' and 'code' unit systems internally.
                return emag

            self.add_field(
                ('gas', 'magnetic_energy_density'),
                function=_magnetic_energy_density,
                units=us["density"] * us["velocity"]**2,
                dimensions=dimensions.density * dimensions.velocity**2,
                sampling_type='cell')

        # Adding the thermal pressure field.
        # In AMRVAC we have multiple physics possibilities:
        # - if HD/MHD + energy equation, pressure is (gamma-1)*(e - ekin (- emag)) for (M)HD
        # - if HD/MHD but solve_internal_e is true in parfile, pressure is (gamma-1)*e for both
        # - if (m)hd_energy is false in parfile (isothermal), pressure is c_adiab * rho**gamma

        def _full_thermal_pressure_HD(field, data):
            # important note : energy density and pressure are actually expressed in the same unit
            pthermal = (data.ds.gamma -
                        1) * (data['gas', 'energy_density'] -
                              data['gas', 'kinetic_energy_density'])
            return pthermal

        def _full_thermal_pressure_MHD(field, data):
            pthermal = _full_thermal_pressure_HD(field, data) \
                       - (data.ds.gamma - 1) * data["gas", "magnetic_energy_density"]
            return pthermal

        def _polytropic_thermal_pressure(field, data):
            return (data.ds.gamma - 1) * data['gas', 'energy_density']

        def _adiabatic_thermal_pressure(field, data):
            return data.ds._c_adiab * data["gas", "density"]**data.ds.gamma

        pressure_recipe = None
        if ("amrvac", "e") in self.field_list:
            if self.ds._e_is_internal:
                pressure_recipe = _polytropic_thermal_pressure
                mylog.info('Using polytropic EoS for thermal pressure.')
            elif ('amrvac', 'b1') in self.field_list:
                pressure_recipe = _full_thermal_pressure_MHD
                mylog.info('Using full MHD energy for thermal pressure.')
            else:
                pressure_recipe = _full_thermal_pressure_HD
                mylog.info('Using full HD energy for thermal pressure.')
        elif self.ds._c_adiab is not None:
            pressure_recipe = _adiabatic_thermal_pressure
            mylog.info(
                'Using adiabatic EoS for thermal pressure (isothermal).')
            mylog.warning(
                'If you used usr_set_pthermal you should redefine the thermal_pressure field.'
            )

        if pressure_recipe is not None:
            self.add_field(
                ('gas', 'thermal_pressure'),
                function=pressure_recipe,
                units=us['density'] * us['velocity']**2,
                dimensions=dimensions.density * dimensions.velocity**2,
                sampling_type='cell')

            # sound speed and temperature depend on thermal pressure
            def _sound_speed(field, data):
                return np.sqrt(data.ds.gamma *
                               data["gas", "thermal_pressure"] /
                               data["gas", "density"])

            self.add_field(("gas", "sound_speed"),
                           function=_sound_speed,
                           units=us["velocity"],
                           dimensions=dimensions.velocity,
                           sampling_type="cell")
        else:
            mylog.warning(
                "e not found and no parfile passed, can not set thermal_pressure."
            )