예제 #1
0
void DustSystem::writedensity() const
{
    // construct a private class instance to do the work (parallelized)
    WriteDensity wd(this);
    Parallel* parallel = find<ParallelFactory>()->parallel();

    // get the dimension of the dust system
    int dimDust = dimension();

    // For the xy plane (always)
    {
        wd.setup(1,1,0);
        parallel->call(&wd, Np);
        wd.write();
    }

    // For the xz plane (only if dimension is at least 2)
    if (dimDust >= 2)
    {
        wd.setup(1,0,1);
        parallel->call(&wd, Np);
        wd.write();
    }

    // For the yz plane (only if dimension is 3)
    if (dimDust == 3)
    {
        wd.setup(0,1,1);
        parallel->call(&wd, Np);
        wd.write();
    }
}
예제 #2
0
void DustSystem::writequality() const
{
    Log* log = find<Log>();
    Units* units = find<Units>();
    Parallel* parallel = find<ParallelFactory>()->parallel();

    // Density metric

    log->info("Calculating quality metric for the grid density...");
    DustSystemDensityCalculator calc1(this, _Nrandom, _Ncells/5);
    parallel->call(&calc1, _Nrandom);

    log->info("  Mean value of density delta: "
              + QString::number(units->omassvolumedensity(calc1.meanDelta()*1e9))
              + " nano" + units->umassvolumedensity());
    log->info("  Standard deviation of density delta: "
              + QString::number(units->omassvolumedensity(calc1.stddevDelta()*1e9))
              + " nano" + units->umassvolumedensity());

    // Optical depth metric

    log->info("Calculating quality metric for the optical depth in the grid...");
    DustSystemDepthCalculator calc2(this, _Nrandom, _Ncells/50, _Nrandom*10);
    parallel->call(&calc2, _Nrandom);

    log->info("  Mean value of optical depth delta: " + QString::number(calc2.meanDelta()));
    log->info("  Standard deviation of optical depth delta: " + QString::number(calc2.stddevDelta()));

    // Output to file

    QString filename = find<FilePaths>()->output("ds_quality.dat");
    log->info("Writing quality metrics for the grid to " + filename + "...");
    ofstream file(filename.toLocal8Bit().constData());
    file << "Mean value of density delta: "
         << units->omassvolumedensity(calc1.meanDelta()) << ' '
         << units->umassvolumedensity().toStdString() << '\n'
         << "Standard deviation of density delta: "
         << units->omassvolumedensity(calc1.stddevDelta()) << ' '
         << units->umassvolumedensity().toStdString() << '\n';
    file << "Mean value of optical depth delta: "
         << calc2.meanDelta() << '\n'
         << "Standard deviation of optical depth delta: "
         << calc2.stddevDelta() << '\n';
    file.close();
    log->info("File " + filename + " created.");
}
예제 #3
0
void DustSystem::writedepthmap() const
{
    // construct a private class instance to do the work (parallelized)
    WriteDepthMap wdm(this);
    Parallel* parallel = find<ParallelFactory>()->parallel();
    parallel->call(&wdm, Npy);
    wdm.write();
}
예제 #4
0
void PanDustSystem::write() const
{
    DustSystem::write();

    // If requested, output the interstellar radiation field in every dust cell to a data file
    if (_writeISRF)
    {
        WavelengthGrid* lambdagrid = find<WavelengthGrid>();
        Units* units = find<Units>();

        // Create a text file
        TextOutFile file(this, "ds_isrf", "ISRF");

        // Write the header
        file.writeLine("# Mean field intensities for all dust cells with nonzero absorption");
        file.addColumn("dust cell index", 'd');
        file.addColumn("x coordinate of cell center (" + units->ulength() + ")", 'g');
        file.addColumn("y coordinate of cell center (" + units->ulength() + ")", 'g');
        file.addColumn("z coordinate of cell center (" + units->ulength() + ")", 'g');
        for (int ell=0; ell<_Nlambda; ell++)
            file.addColumn("J_lambda (W/m3/sr) for lambda = "
                           + QString::number(units->owavelength(lambdagrid->lambda(ell)))
                           + " " + units->uwavelength(), 'g');

        // Write one line for each dust cell with nonzero absorption
        for (int m=0; m<_Ncells; m++)
        {
            double Ltotm = Labs(m);
            if (Ltotm>0.0)
            {
                QList<double> values;
                Position bfr = _grid->centralPositionInCell(m);
                values << m << units->olength(bfr.x()) << units->olength(bfr.y()) << units->olength(bfr.z());
                for (auto J : meanintensityv(m)) values << J;
                file.writeRow(values);
            }
        }
    }

    // If requested, output temperate map(s) along coordiate axes cuts
    if (_writeTemp)
    {
        // construct a private class instance to do the work (parallelized)
        WriteTemp wt(this);
        Parallel* parallel = find<ParallelFactory>()->parallel();

        // get the dimension of the dust grid
        int dimDust = _grid->dimension();

        // Create an assigner that assigns all the work to the root process
        RootAssigner* assigner = new RootAssigner(0);
        assigner->assign(Np);

        // For the xy plane (always)
        {
            wt.setup(1,1,0);
            parallel->call(&wt, assigner);
            wt.write();
        }

        // For the xz plane (only if dimension is at least 2)
        if (dimDust >= 2)
        {
            wt.setup(1,0,1);
            parallel->call(&wt, assigner);
            wt.write();
        }

        // For the yz plane (only if dimension is 3)
        if (dimDust == 3)
        {
            wt.setup(0,1,1);
            parallel->call(&wt, assigner);
            wt.write();
        }
    }
}
예제 #5
0
void PanDustSystem::write() const
{
    DustSystem::write();

    PeerToPeerCommunicator* comm = find<PeerToPeerCommunicator>();
    bool dataParallel = comm->dataParallel();

    // If requested, output the interstellar radiation field in every dust cell to a data file
    if (_writeISRF)
    {
        WavelengthGrid* lambdagrid = find<WavelengthGrid>();
        Units* units = find<Units>();

        // Create a text file
        TextOutFile file(this, "ds_isrf", "ISRF");

        // Write the header
        file.writeLine("# Mean field intensities for all dust cells with nonzero absorption");
        file.addColumn("dust cell index", 'd');
        file.addColumn("x coordinate of cell center (" + units->ulength() + ")", 'g');
        file.addColumn("y coordinate of cell center (" + units->ulength() + ")", 'g');
        file.addColumn("z coordinate of cell center (" + units->ulength() + ")", 'g');
        for (int ell=0; ell<_Nlambda; ell++)
            file.addColumn("J_lambda (W/m3/sr) for lambda = "
                           + QString::number(units->owavelength(lambdagrid->lambda(ell)))
                           + " " + units->uwavelength(), 'g');

        // Write one line for each dust cell with nonzero absorption
        for (int m=0; m<_Ncells; m++)
        {
            if (!dataParallel)
            {
                double Ltotm = Labs(m);
                if (Ltotm>0.0)
                {
                    QList<double> values;
                    Position bfr = _grid->centralPositionInCell(m);
                    values << m << units->olength(bfr.x()) << units->olength(bfr.y()) << units->olength(bfr.z());

                    for (auto J : meanintensityv(m)) values << J;
                    file.writeRow(values);
                }
            }
            else // for distributed mode
            {
                QList<double> values;
                Position bfr = _grid->centralPositionInCell(m);
                values << m << units->olength(bfr.x()) << units->olength(bfr.y()) << units->olength(bfr.z());

                // the correct process gets Jv
                Array Jv(_Nlambda);
                if (_assigner->validIndex(m)) Jv = meanintensityv(m);

                // and broadcasts it
                int sender = _assigner->rankForIndex(m);
                comm->broadcast(Jv,sender);

                if (Jv.sum()>0)
                {
                    for (auto J : Jv) values << J;
                    file.writeRow(values);
                }
            }
        }
    }

    // If requested, output temperature map(s) along coordinate axes and temperature data for each dust cell
    if (_writeTemp)
    {
        // Parallelize the calculation over the threads
        Parallel* parallel = find<ParallelFactory>()->parallel();
        // If the necessary data is distributed over the processes, do the calculation on all processes.
        // Else, let the root do everything.
        bool isRoot = comm->isRoot();

        // Output temperature map(s) along coordinate axes
        {
            // Construct a private class instance to do the work (parallelized)
            WriteTempCut wt(this);

            // Get the dimension of the dust grid
            int dimDust = _grid->dimension();

            // For the xy plane (always)
            {
                wt.setup(1,1,0);
                if (dataParallel) parallel->call(&wt, Np);
                else if (isRoot) parallel->call(&wt, Np);
                wt.write();
            }

            // For the xz plane (only if dimension is at least 2)
            if (dimDust >= 2)
            {
                wt.setup(1,0,1);
                if (dataParallel) parallel->call(&wt, Np);
                else if (isRoot) parallel->call(&wt, Np);
                wt.write();
            }

            // For the yz plane (only if dimension is 3)
            if (dimDust == 3)
            {
                wt.setup(0,1,1);
                if (dataParallel) parallel->call(&wt, Np);
                else if (isRoot) parallel->call(&wt, Np);
                wt.write();
            }
        }

        // Output a text file with temperature data for each dust cell
        {
            find<Log>()->info("Calculating indicative dust temperatures for each cell...");

            // Construct a private class instance to do the work (parallelized)
            WriteTempData wt(this);

            // Call the body on the right cells. If everything is available, no unnecessary communication will be done.
            if (dataParallel)
            {
                // Calculate the temperature for the cells owned by this process
                parallel->call(&wt, _assigner);
            }
            else if (isRoot)
            {
                // Let root calculate it for everything
                parallel->call(&wt, _Ncells);
            }
            wt.write();
        }
    }
}