Esempio n. 1
0
 def createModel(self, params):
     '''
     create a model (potential and DF) specified by the given [scaled] parameters
     '''
     potential = agama.Potential(type='Spheroid',
                                 densityNorm=10**params[0],
                                 scaleRadius=10**params[1],
                                 gamma=params[2],
                                 beta=params[3],
                                 alpha=params[4])
     # first create an un-normalized DF
     dfparams = dict(type='DoublePowerLaw',
                     slopeOut=params[self.numPotParams + 0],
                     slopeIn=params[self.numPotParams + 1],
                     steepness=params[self.numPotParams + 2],
                     coefJrOut=params[self.numPotParams + 3],
                     coefJzOut=(3 - params[self.numPotParams + 3]) / 2,
                     coefJrIn=params[self.numPotParams + 4],
                     coefJzIn=(3 - params[self.numPotParams + 4]) / 2,
                     j0=10**params[self.numPotParams + 5],
                     norm=1.)
     # compute its total mass
     totalMass = agama.DistributionFunction(**dfparams).totalMass()
     # and now normalize the DF to have a unit total mass
     dfparams["norm"] = 1. / totalMass
     df = agama.DistributionFunction(**dfparams)
     return potential, df
    def test(Component, SelfConsistentModel):
        # test a two-component spherical model (to speed up things, do not use disky components);
        # the first component is an isotropic DF of a NFW halo with a cutoff,
        # and the second one represents a more concentrated baryonic component,
        # which will cause the adiabatic contraction of the halo
        # when both components are iterated to achieve equilibrium
        params_comp1 = dict(disklike=False,
                            rminSph=0.01,
                            rmaxSph=100.0,
                            sizeRadialSph=21,
                            lmaxAngularSph=0)
        params_comp2 = dict(disklike=False,
                            rminSph=0.01,
                            rmaxSph=10.0,
                            sizeRadialSph=16,
                            lmaxAngularSph=0)
        params_scm = dict(rminSph=0.005,
                          rmaxSph=200,
                          sizeRadialSph=25,
                          lmaxAngularSph=0)

        potential_init = agama.Potential(type='spheroid',
                                         gamma=1,
                                         beta=3,
                                         mass=20.0,
                                         scaleRadius=5.0,
                                         outerCutoffRadius=40.0)
        df_comp1 = agama.DistributionFunction(type='quasispherical',
                                              density=potential_init,
                                              potential=potential_init)
        df_comp2 = agama.DistributionFunction(type='doublepowerlaw',
                                              norm=12.0,
                                              J0=1.0,
                                              coefJrIn=1.,
                                              coefJzIn=1.,
                                              coefJrOut=1.,
                                              coefJzOut=1.,
                                              slopeIn=1,
                                              slopeOut=6)
        model = SelfConsistentModel(**params_scm)
        model.components.append(Component(df=df_comp1, **params_comp1))
        model.components.append(Component(df=df_comp2, **params_comp2))
        model.potential = potential_init
        for it in range(5):
            model.iterate()
        #model.components[0].getDensity().export('comp1')
        #model.components[1].getDensity().export('comp2')
        return agama.GalaxyModel(model.potential,
                                 df_comp1).moments([1, 0.5, 0.3])
Esempio n. 3
0
 def createModel(self, params):
     '''
     create a model (potential and DF) specified by the given [scaled] parameters
     '''
     potential = agama.Potential(type='Spheroid',
                                 densityNorm=10**params[0],
                                 scaleRadius=10**params[1],
                                 gamma=params[2],
                                 beta=params[3],
                                 alpha=params[4])
     density = agama.Density(type='Spheroid',
                             scaleRadius=10**params[self.numPotParams + 0],
                             gamma=params[self.numPotParams + 1],
                             beta=params[self.numPotParams + 2],
                             alpha=params[self.numPotParams + 3])
     df = agama.DistributionFunction(type='QuasiSpherical',
                                     potential=potential,
                                     density=density,
                                     beta0=params[self.numPotParams + 4],
                                     r_a=10**params[self.numPotParams + 5])
     # check if the DF is everywhere nonnegative
     j = numpy.logspace(-5, 10, 200)
     if any(df(numpy.column_stack((j, j * 0 + 1e-10, j * 0))) <= 0):
         raise ValueError("Bad DF")
     return potential, df
Esempio n. 4
0
    def createDF(self, params):

        # first create an un-normalized DF
        dfparams = dict(type='DoublePowerLaw',
                        slopeOut=params[self.numPotParams + 0],
                        slopeIn=params[self.numPotParams + 1],
                        steepness=params[self.numPotParams + 2],
                        coefJrOut=params[self.numPotParams + 3],
                        coefJzOut=(3 - params[self.numPotParams + 3]) / 2,
                        coefJrIn=params[self.numPotParams + 4],
                        coefJzIn=(3 - params[self.numPotParams + 4]) / 2,
                        j0=10**params[self.numPotParams + 5],
                        norm=1.)
        # compute its total mass
        totalMass = agama.DistributionFunction(**dfparams).totalMass()
        # and now normalize the DF to have a unit total mass
        dfparams["norm"] = 1. / totalMass
        return agama.DistributionFunction(**dfparams)
Esempio n. 5
0
def model_likelihood(params, points):
    print "J0=%6.5g, slopeIn=%6.5g, slopeOut=%6.5g, steepness=%6.5g, coefJrIn=%6.5g: " \
        % (params['J0'], params['slopeIn'], params['slopeOut'], params['steepness'], params['coefJrIn']),
    try:
        dpl = agama.DistributionFunction(**params)
        norm = dpl.totalMass()
        sumlog = numpy.sum(numpy.log(dpl(points) / norm))
        print "LogL=%.8g" % sumlog
        return sumlog
    except ValueError as err:
        print "Exception ", err
        return -1000. * len(points)
Esempio n. 6
0
def contraction(pot_dm,
                pot_bar,
                method='C20',
                beta_dm=0.0,
                rmin=1e-2,
                rmax=1e4):
    '''
    Construct the contracted halo density profile for the given
    initial halo density and the baryonic density profiles.
    Arguments:
      pot_dm:  initial halo potential (assumed to be spherical!).
      pot_bar: potential of baryons (a spherical approximation to it will be used even if it was not spherical).
      method:  choice between two alternative approaches:
        'C20'  (default) uses the approximate correction procedure from Cautun+2020;
        'adiabatic'  uses the invariance of actions in conjunction with an internally constructed halo DF.
      beta_dm: anisotropy coefficient for the halo DF
        (only used with the adiabatic method, must be between -0.5 and 1, default 0 means isotropy).
      rmin (1e-2), rmax(1e4): min/max grid radii for representing the contracted density profile
        (default values are suitable for Milky Way-sized galaxies if expressed in kpc).
    Return:
      the spherically symmetric contracted halo potential.
    '''
    gridr = numpy.logspace(numpy.log10(rmin), numpy.log10(rmax), 101)
    xyz = numpy.column_stack((gridr, gridr * 0, gridr * 0))
    if method == 'adiabatic':
        # create a spherical DF for the DM-only potential/density pair with a constant anisotropy coefficient beta
        df_dm = agama.DistributionFunction(type='QuasiSpherical',
                                           potential=pot_dm,
                                           beta0=beta_dm)
        # create a sphericalized total potential (DM+baryons)
        pot_total_sph = agama.Potential(type='multipole',
                                        potential=agama.Potential(
                                            pot_dm, pot_bar),
                                        lmax=0,
                                        rmin=0.1 * rmin,
                                        rmax=10 * rmax)
        # compute the density generated by the DF in the new total potential at the radial grid
        dens_contracted = agama.GalaxyModel(pot_total_sph,
                                            df_dm).moments(xyz,
                                                           dens=True,
                                                           vel=False,
                                                           vel2=False)
    elif method == 'C20':
        # use the differential (d/dr) form of Eq. (11) from Cautun et al (2020) to approximate the effect of contraction
        cumul_mass_dm = pot_dm.enclosedMass(
            gridr)  # cumulative mass profile of DM
        cumul_mass_bar = pot_bar.enclosedMass(
            gridr)  # same for baryons (sphericalized)
        valid_r = numpy.hstack([
            True, cumul_mass_bar[:-1] < cumul_mass_bar[1:] * 0.999
        ])  # use only those radii where mass keeps increasing
        sph_dens_bar = agama.Density(cumulmass=numpy.column_stack(
            (gridr[valid_r],
             cumul_mass_bar[valid_r])))  # sphericalized baryon density profile
        f_bar = 0.157  # cosmic baryon fraction; the formula is calibrated against simulations only for this value
        eta_bar = cumul_mass_bar / cumul_mass_dm * (
            1. - f_bar
        ) / f_bar  # the last two terms account for transforming the DM mass into the corresponding baryonic mass in dark-matter-only simulations
        first_factor = 0.45 + 0.41 * (eta_bar + 0.98)**0.53
        dens_dm_orig = pot_dm.density(xyz)
        temp = sph_dens_bar.density(
            xyz) - eta_bar * dens_dm_orig * f_bar / (1. - f_bar)
        const_term = 0.41 * 0.53 * (eta_bar + 0.98)**(0.53 - 1.) * (
            1. - f_bar) / f_bar * temp
        dens_contracted = dens_dm_orig * first_factor + const_term  # new values of DM density at the radial grid
    else:
        raise RuntimeError('Invalid choice of method')

    # create a cubic spline interpolator in log-log space
    valid_r = dens_contracted > 0  # make sure the input for log-spline is positive
    dens_contracted_interp = agama.CubicSpline(numpy.log(gridr[valid_r]),
                                               numpy.log(
                                                   dens_contracted[valid_r]),
                                               reg=True)
    # convert the grid-based density profile into a full-fledged potential
    contracted_pot = agama.Potential(
        type="Multipole",
        symmetry="spherical",
        rmin=rmin,
        rmax=rmax,
        density=lambda xyz: numpy.exp(
            dens_contracted_interp(numpy.log(numpy.sum(xyz**2, axis=1)) * 0.5)
        ))
    return contracted_pot
Esempio n. 7
0
#!/usr/bin/python

"""
Create a simple single-component spherical self-consistent model
determined by its distribution function in terms of actions.
We use the true DF of the Plummer model, expressed in terms of actions,
and start iterations from a deliberately wrong initial guess;
nevertheless, after 10 iterations we converge to the true solution within 1%;
each iteration approximately halves the error.
"""
import agama, numpy, matplotlib.pyplot as plt

# the distribution function defining the model
truepot = agama.Potential(type='Plummer')
df = agama.DistributionFunction(type='QuasiSpherical', potential=truepot, density=truepot)

# initial guess for the density profile - deliberately a wrong one
dens = agama.Density(type='Dehnen', mass=0.1, scaleRadius=0.5)

# define the self-consistent model consisting of a single component
params = dict(rminSph=0.001, rmaxSph=1000., sizeRadialSph=40, lmaxAngularSph=0)
comp = agama.Component(df=df, density=dens, disklike=False, **params)
scm = agama.SelfConsistentModel(**params)
scm.components=[comp]

# prepare visualization
r=numpy.logspace(-2.,2.)
xyz=numpy.vstack((r,r*0,r*0)).T
plt.plot(r, dens.density(xyz), label='Init density')
plt.plot(r, truepot.density(xyz), label='True density', c='k')[0].set_dashes([4,4])
Esempio n. 8
0
    densityHalo  = agama.Density(**iniPotenHalo)
    densityDisk  = agama.Density(**iniPotenDisk)

    # add components to SCM - at first, all of them are static density profiles
    model.components.append(agama.Component(density=densityHalo,  disklike=False))
    model.components.append(agama.Component(density=densityBulge, disklike=False))
    model.components.append(agama.Component(density=densityDisk,  disklike=True))

    # compute the initial potential
    model.iterate()
    writeRotationCurve("rotcurve_init", model.potential)

    # initialize the DFs of spheroidal components using the Eddington inversion formula
    # for their respective density profiles in the spherically-symmetric initial guess for the potential
    pot_sph = agama.Potential(type='Multipole', density=model.potential, lmax=0, gridsizer=100, rmin=1e-3, rmax=1e3)
    dfHalo  = agama.DistributionFunction(type='PseudoIsotropic', potential=pot_sph, density=densityHalo)
    dfBulge = agama.DistributionFunction(type='PseudoIsotropic', potential=pot_sph, density=densityBulge)
    printoutInfo(model, 0)

    print "\033[1;33m**** STARTING ONE-COMPONENT MODELLING ****\033[0m\nMasses are:  " \
        "Mhalo=%g,"  % densityHalo.totalMass(), \
        "Mbulge=%g," % densityBulge.totalMass(), \
        "Mdisk=%g"   % densityDisk.totalMass()

    # replace the halo and bulge SCM components with the DF-based ones
    model.components[0] = agama.Component(df=dfHalo,  disklike=False, **iniSCMHalo)
    model.components[1] = agama.Component(df=dfBulge, disklike=False, **iniSCMBulge)

    # do one iteration to determine the self-consistent density profile of the halo and the bulge
    print "\033[1;37mStarting iteration #1\033[0m"
    model.iterate()
Esempio n. 9
0
def isArray(obj, shape):
    return isinstance(obj, numpy.ndarray) and obj.shape == shape


# set up some non-trivial dimensional units
agama.setUnits(length=2, velocity=3, mass=4e6)

dens = agama.Density(type='plummer')
pots = agama.Potential(type='dehnen', gamma=0)  # spherical potential
potf = agama.Potential(type='plummer', q=0.75)  # flattened potential
pott = agama.Potential(type='plummer', p=0.75, q=0.5)  # triaxial potential
actf = agama.ActionFinder(potf)
actm = agama.ActionMapper(potf, [1, 1, 1])
df0 = agama.DistributionFunction(type='quasispherical',
                                 density=pots,
                                 potential=pots,
                                 r_a=2.0)
df1 = agama.DistributionFunction(type='quasispherical',
                                 density=dens,
                                 potential=pots,
                                 beta0=-0.2)
df2 = agama.DistributionFunction(df1, df0)  # composite DF with two components
gms1 = agama.GalaxyModel(pots, df1)  # simple DF, spherical potential
gms2 = agama.GalaxyModel(pots, df2)  # composite DF (2 components), spherical
gmf1 = agama.GalaxyModel(potf, df1)  # simple, flattened
Phi0 = pots.potential(0, 0, 0)  # value of the potential at origin

### test the shapes of output arrays for various inputs ###
# Density class methods
testCond('isFloat(dens.density( 1,0,0 ))'
         )  # single point (3 coordinates) => output is a scalar value
Esempio n. 10
0
    model.components.append(agama.Component(dens=densityGasDisc,
                                            disklike=True))

    # compute the initial potential
    model.iterate()
    writeRotationCurve("rotcurve_init", model.pot)

    print "**** STARTING ONE-COMPONENT MODELLING ****\nMasses are:  " \
        "Mbulge=%g Msun,"% densityBulge.totalMass(), \
        "Mgas=%g Msun,"  % densityGasDisc.totalMass(), \
        "Mdisc=%g Msun," % densityStellarDisc.totalMass(), \
        "Mhalo=%g Msun"  % densityDarkHalo.totalMass()

    # create the dark halo DF from the parameters in INI file;
    # here the initial potential is only used to create epicyclic frequency interpolation table
    dfHalo = agama.DistributionFunction(pot=model.pot, **iniDFDarkHalo)

    # replace the halo SCM component with the DF-based one
    model.components[0] = agama.Component(df=dfHalo,
                                          disklike=False,
                                          **iniSCMHalo)

    # do a few iterations to determine the self-consistent density profile of the halo
    for iteration in range(1, 6):
        print "Starting iteration #%d" % iteration
        model.iterate()
        printoutInfo(model, iteration)

    # now that we have a reasonable guess for the total potential,
    # we may initialize the DF of the stellar components
    dfThinDisc = agama.DistributionFunction(pot=model.pot, **iniDFThinDisc)
    J0       = 1e3,
    slopeIn  = 1.5,
    slopeOut = 1.5,
    steepness= 1.0,
    coefJrIn = 0.8,
    coefJzIn = 1.7,
    coefJrOut= 0.8,
    coefJzOut= 1.7,
    Jcutoff  = 0.56,
    cutoffstrength=1.5,
    rotFrac  = 1.0,  # make a rotating model (just for fun)
    Jphi0    = 0.,   # size of non-(or weakly-)rotating core
    norm     = 1.0)

# compute the mass and rescale norm to get the total mass = 1
params['norm'] /= agama.DistributionFunction(**params).totalMass()
df = agama.DistributionFunction(**params)

# initial guess for the density profile
dens = agama.Potential(type='sersic', mass=1, scaleRadius=0.65, sersicindex=2)

# define the self-consistent model consisting of a single component
params = dict(rminSph=0.01, rmaxSph=10., sizeRadialSph=25, lmaxAngularSph=8)
comp = agama.Component(df=df, density=dens, disklike=False, **params)
scm = agama.SelfConsistentModel(**params)
scm.components=[comp]

# prepare visualization
r=numpy.logspace(-2.,2.)
xyz=numpy.vstack((r,r*0,r*0)).T
plt.plot(r, dens.density(xyz), label='Init density', color='k')
Esempio n. 12
0
#!/usr/bin/python

"""
Create a simple single-component spherical self-consistent model
determined by its distribution function in terms of actions
"""
import agama, numpy, matplotlib.pyplot as plt

# the distribution function defining the model
df = agama.DistributionFunction(type="DoublePowerLaw", J0=1, slopeIn=0, slopeOut=6, norm=30)
mass = df.totalMass()
scaleradius = 2.   # educated guess

# initial guess for the density profile
dens = agama.Density(type='Plummer', mass=mass, scaleRadius=scaleradius)
print "DF mass=", mass, ' Density mass=', dens.totalMass()  # should be identical

# define the self-consistent model consisting of a single component
params = dict(rminSph=0.01, rmaxSph=100., sizeRadialSph=25, lmaxAngularSph=0)
comp = agama.Component(df=df, density=dens, disklike=False, **params)
scm = agama.SelfConsistentModel(**params)
scm.components=[comp]

# prepare visualization
r=numpy.logspace(-2.,2.)
xyz=numpy.vstack((r,r*0,r*0)).T
plt.plot(r, dens.density(xyz), label='Init density')

# perform several iterations of self-consistent modelling procedure
for i in range(5):
    scm.iterate()
Esempio n. 13
0
    model.components.append(agama.Component(density=densityStellarDisk, disklike=True))
    model.components.append(agama.Component(density=densityBulge,       disklike=False))
    model.components.append(agama.Component(density=densityDarkHalo,    disklike=False))
    model.components.append(agama.Component(density=densityGasDisk,     disklike=True))

    # compute the initial potential
    model.iterate()
    printoutInfo(model, "init")

    print("\033[1;33m**** STARTING MODELLING ****\033[0m\nInitial masses of density components: " \
        "Mdisk=%g Msun, Mbulge=%g Msun, Mhalo=%g Msun, Mgas=%g Msun" % \
        (densityStellarDisk.totalMass(), densityBulge.totalMass(), \
        densityDarkHalo.totalMass(), densityGasDisk.totalMass()))

    # create the dark halo DF
    dfHalo  = agama.DistributionFunction(potential=model.potential, **iniDFDarkHalo)
    # same for the bulge
    dfBulge = agama.DistributionFunction(potential=model.potential, **iniDFBulge)
    # same for the stellar components (thin/thick disks and stellar halo)
    dfThinDisk    = agama.DistributionFunction(potential=model.potential, **iniDFThinDisk)
    dfThickDisk   = agama.DistributionFunction(potential=model.potential, **iniDFThickDisk)
    dfStellarHalo = agama.DistributionFunction(potential=model.potential, **iniDFStellarHalo)
    # composite DF of all stellar components except the bulge
    dfStellar     = agama.DistributionFunction(dfThinDisk, dfThickDisk, dfStellarHalo)
    # composite DF of all stellar components including the bulge
    dfStellarAll  = agama.DistributionFunction(dfThinDisk, dfThickDisk, dfStellarHalo, dfBulge)

    # replace the disk, halo and bulge SCM components with the DF-based ones
    model.components[0] = agama.Component(df=dfStellar, disklike=True, **iniSCMDisk)
    model.components[1] = agama.Component(df=dfBulge, disklike=False, **iniSCMBulge)
    model.components[2] = agama.Component(df=dfHalo,  disklike=False, **iniSCMHalo)
Esempio n. 14
0
    ( pot_appr.density(1,0,0), pot_orig.density(1,0,0), MyPlummer(numpy.array([[1,0,0]])) )

# user-defined distribution function, again it must be a function of a single argument --
# a 2d array Mx3, where the columns are Jr,Jz,Jphi, and rows are M independent points
# in action space where the function should be evaluated simultaneously.
# Here, instead of creating a lambda function, we fix the internal constants at the outset.
J0 = 2.0  # constants -- parameters of the DF
Beta = 5.0


def MyDF(J):
    return (J[:, 0] + J[:, 1] + abs(J[:, 2]) + J0)**-Beta


# original DF using a C++ object
df_orig = agama.DistributionFunction( \
    type="DoublePowerLaw", J0=J0, slopeIn=0, slopeOut=Beta, norm=2*numpy.pi**3)

# to compute the total mass, we create an proxy instance of DistributionFunction class
# with a composite DF consisting of a single component (the user-supplied function);
# this proxy class provides the totalMass() method
# that the user-defined Python function itself does not have
mass_orig = df_orig.totalMass()
mass_my = agama.DistributionFunction(MyDF).totalMass()
print "DF mass=%.8g  (orig value=%.8g)" % (mass_my, mass_orig)

# GalaxyModel objects constructed from the C++ DF and from the Python function
# (without the need of a proxy object; in fact, GalaxyModel.df is itself a proxy object)
gm_orig = agama.GalaxyModel(df=df_orig, potential=pot_orig)
gm_my = agama.GalaxyModel(df=MyDF, potential=pot_appr)
# note that different potentials were used for gm_orig and gm_my, so the results may slightly disagree
#!/usr/bin/python
"""
Create a simple single-component spherical self-consistent model
determined by its distribution function in terms of actions.
We use the true DF of the Plummer model, expressed in terms of actions,
and start iterations from a deliberately wrong initial guess;
nevertheless, after 10 iterations we converge to the true solution within 1%;
each iteration approximately halves the error.
"""
import agama, numpy, matplotlib.pyplot as plt

# the distribution function defining the model
truepot = agama.Potential(type='Plummer')
df = agama.DistributionFunction(type='QuasiIsotropic',
                                potential=truepot,
                                density=truepot)

# initial guess for the density profile - deliberately a wrong one
dens = agama.Density(type='Dehnen', mass=0.1, scaleRadius=0.5)

# define the self-consistent model consisting of a single component
params = dict(rminSph=0.001, rmaxSph=1000., sizeRadialSph=40, lmaxAngularSph=0)
comp = agama.Component(df=df, density=dens, disklike=False, **params)
scm = agama.SelfConsistentModel(**params)
scm.components = [comp]

# prepare visualization
r = numpy.logspace(-2., 2.)
xyz = numpy.vstack((r, r * 0, r * 0)).T
plt.plot(r, dens.density(xyz), label='Init density')
plt.plot(r, truepot.density(xyz), label='True density',
Esempio n. 16
0
import agama

mass_unit = (1.0/4.3)*(10.0**(6.0))

agama.setUnits(mass=mass_unit, length=1, velocity=1)

pot = agama.Potential(type='Spheroid', gamma=1.0, beta=3.1, scaleRadius=2.5, outerCutoffRadius=15.0)
df = agama.DistributionFunction(type='QuasiSpherical',potential=pot)
model = agama.GalaxyModel(pot,df)
M = model.sample(10000)

print(M[0][9999,0])
agama.writeSnapshot('test_snapshot.snp',M,'n')


Esempio n. 17
0
    model.iterate()
    plotVcirc(model, 0)

    # introduce DF for the NSD component
    mass = 0.097
    Rdisk = 0.075
    Hdisk = 0.025
    sigmar0 = 75.0
    Rsigmar = 1.0
    sigmamin = 2.0
    Jmin = 10.0
    dfNSD = agama.DistributionFunction(potential=model.potential,
                                       type='QuasiIsothermal',
                                       mass=mass,
                                       Rdisk=Rdisk,
                                       Hdisk=Hdisk,
                                       sigmar0=sigmar0,
                                       Rsigmar=Rsigmar,
                                       sigmamin=sigmamin,
                                       Jmin=Jmin)

    # replace the static density of the NSD by a DF-based component
    model.components[1] = agama.Component(df=dfNSD,
                                          disklike=True,
                                          RminCyl=0.005,
                                          RmaxCyl=0.75,
                                          sizeRadialCyl=20,
                                          zminCyl=0.005,
                                          zmaxCyl=0.25,
                                          sizeVerticalCyl=15)
Esempio n. 18
0
    densityBulge = agama.Density(**iniPotenBulge)
    densityHalo  = agama.Density(**iniPotenHalo)
    potentialBH  = agama.Potential(**iniPotenBH)

    # add components to SCM - at first, all of them are static density profiles
    model.components.append(agama.Component(density=densityDisk,  disklike=True))
    model.components.append(agama.Component(density=densityBulge, disklike=False))
    model.components.append(agama.Component(density=densityHalo,  disklike=False))
    model.components.append(agama.Component(potential=potentialBH))

    # compute the initial potential
    model.iterate()
    printoutInfo(model,'init')

    # construct the DF of the disk component, using the initial (non-spherical) potential
    dfDisk  = agama.DistributionFunction(potential=model.potential, **iniDFDisk)
    # initialize the DFs of spheroidal components using the Eddington inversion formula
    # for their respective density profiles in the initial potential
    dfBulge = agama.DistributionFunction(type='QuasiSpherical', potential=model.potential, density=densityBulge)
    dfHalo  = agama.DistributionFunction(type='QuasiSpherical', potential=model.potential, density=densityHalo)

    print("\033[1;33m**** STARTING ITERATIVE MODELLING ****\033[0m\nMasses (computed from DF): " \
        "Mdisk=%g, Mbulge=%g, Mhalo=%g" % (dfDisk.totalMass(), dfBulge.totalMass(), dfHalo.totalMass()))

    # replace the initially static SCM components with the DF-based ones
    model.components[0] = agama.Component(df=dfDisk,  disklike=True,  **iniSCMDisk)
    model.components[1] = agama.Component(df=dfBulge, disklike=False, **iniSCMBulge)
    model.components[2] = agama.Component(df=dfHalo,  disklike=False, **iniSCMHalo)

    # do a few more iterations to obtain the self-consistent density profile for both disks
    for iteration in range(1,5):
Esempio n. 19
0
hdisk_thick = 1.0

Rsigmar = Rd/q

sigmar0_thin_binney = 27.
sigmar0_thick_binney = 48.

sigmar0_thin = sigmar0_thin_binney * np.exp(R0/Rsigmar)
sigmar0_thick = sigmar0_thick_binney * np.exp(R0/Rsigmar)

sigmamin_thin = 0.05*sigmar0_thin
sigmamin_thick = 0.05*sigmar0_thick
Jmin = 0.05*J0

df_thin = agama.DistributionFunction(type='QuasiIsothermal', potential=mwpot, coefJr=coefJr, coefJz=coefJz, 
                                     Sigma0=Sigma0_thin, Rdisk=Rd, Hdisk=hdisk_thin, sigmar0=sigmar0_thin, 
                                     Rsigmar=Rsigmar, sigmamin=sigmamin_thin, Jmin=Jmin)

df_thick = agama.DistributionFunction(type='QuasiIsothermal', potential=mwpot, coefJr=coefJr, coefJz=coefJz, 
                                      Sigma0=Sigma0_thick, Rdisk=Rd, Hdisk=hdisk_thick, sigmar0=sigmar0_thick, 
                                      Rsigmar=Rsigmar, sigmamin=sigmamin_thick, Jmin=Jmin)

df = agama.DistributionFunction(df_thin, df_thick)
# df = df_thin
gm = agama.GalaxyModel(mwpot, df)

try:
    f = h5.File('posvel_mass.h5', 'r')
    posvel = np.array(f['posvel'])
    mass = np.array(f['mass'])
    f.close()