Ejemplo n.º 1
0
Integer ParseNonbondedFile::parse(StringParser *sp)
{
ParseComment parseComment("[#;");
ParseSigmaEpsilonCharge parseSEC;

Units *DU = Units::distanceUnits();
Units *EU = Units::energyUnits();

int NParsed = 0;
do{
sp->skipChars(" \t\n");
if(sp->isOver()) return 1;

if(expectStatement(sp,&parseComment)) continue;

if(!expectStatement(sp,&parseSEC)) return NParsed>0;


SigmaEpsilonCharge sec;

sec.sigma = parseSEC.m_sigma * DU->unit2unit("nm","Angstr");
sec.epsilon = parseSEC.m_epsilon * EU->unit2unit("kJ/mol","kcal/mol");
sec.charge = parseSEC.m_charge;
	
(*m_ff)[parseSEC.m_atomType] = sec;
NParsed++;

}while(1);

}
Ejemplo n.º 2
0
bool
VerticalDatum::transform(const VerticalDatum* from,
                         const VerticalDatum* to,
                         double               lat_deg,
                         double               lon_deg,
                         double&              in_out_z)
{
    if ( from == to )
        return true;

    if ( from )
    {
        in_out_z = from->msl2hae( lat_deg, lon_deg, in_out_z );
    }

    Units fromUnits = from ? from->getUnits() : Units::METERS;
    Units toUnits = to ? to->getUnits() : Units::METERS;

    in_out_z = fromUnits.convertTo(toUnits, in_out_z);

    if ( to )
    {
        in_out_z = to->hae2msl( lat_deg, lon_deg, in_out_z );
    }

    return true;
}
Ejemplo n.º 3
0
int PSPower::GetNumberOfUnits(PSData* pData)
{
	if (!pData)
		pData = TG.GetData();

	Units vUnits = pData->GetUnits(this);
	return vUnits.size();
}
Ejemplo n.º 4
0
bool
is_2D_char_2D_type(MContext *mc, DNode *t)
{
    Units *units = (dale::Units*) mc->units;
    Node *n = units->top()->dnc->toNode(t);
    n = units->top()->mp->parsePotentialMacroCall(n);
    return (n && n->token && !n->token->str_value.compare("char"));
}
Ejemplo n.º 5
0
void Units::MergeFrom(const Units& from) {
    GOOGLE_CHECK_NE(&from, this);
    if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
        if (from._has_bit(0)) {
            set_ret(from.ret());
        }
    }
    mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}
Ejemplo n.º 6
0
void MDAtomsTyped<T>::setUnits(const Units& units,const Units& MDUnits){
  double lscale=units.getLength()/MDUnits.getLength();
  double escale=units.getEnergy()/MDUnits.getEnergy();
// scalep and scaleb are used to convert MD to plumed
  scalep=1.0/lscale;
  scaleb=1.0/lscale;
// scalef and scalev are used to convert plumed to MD
  scalef=escale/lscale;
  scalev=escale;
}
Ejemplo n.º 7
0
BD_convert::BD_convert (const Units& units, const symbol has, const symbol want,
                        const symbol bulk_unit)
  : in (units.get_convertion (has, bulk_unit)),
    out (units.get_convertion (Units::dry_soil_fraction (), want)),
    bulk (-42.42e42)
{ 
#if 0
  std::ostringstream tmp;
  tmp << "has = " << has << ", bulk_unit = " << bulk_unit
      << ", dsf = " << Units::dry_soil_fraction () << ", want = " << want;
  Assertion::message (tmp.str ());
#endif  
}
Ejemplo n.º 8
0
VerticalDatum::VerticalDatum( const Units& units ) :
_name      ( units.getName() ),
_initString( units.getName() ),
_units     ( units )
{
    //nop
}
Ejemplo n.º 9
0
bool
is_2D_pointer_2D_to_2D_type(MContext *mc, DNode *t, DNode *pointee)
{
    Units *units = (dale::Units*) mc->units;
    Node *n = units->top()->dnc->toNode(t);
    n = units->top()->mp->parsePotentialMacroCall(n);
    if (!n) {
        return false;
    }

    Node *n2 = units->top()->dnc->toNode(pointee);
    n2 = units->top()->mp->parsePotentialMacroCall(n2);
    if (!n2) {
        return false;
    }

    int error_count_begin =
        units->top()->ctx->er->getErrorTypeCount(ErrorType::Error);

    Type *type  = FormTypeParse(units, n,  false, false);
    Type *type2 = FormTypeParse(units, n2, false, false);

    units->top()->ctx->er->popErrors(error_count_begin);
    if (!type || !type2) {
        return false;
    }
    return (type->points_to->isEqualTo(type2));
}
Ejemplo n.º 10
0
bool
types_2D_equal(MContext *mc, DNode *t1, DNode *t2)
{
    Units *units = (dale::Units*) mc->units;

    Node *n = units->top()->dnc->toNode(t1);
    n = units->top()->mp->parsePotentialMacroCall(n);
    if (!n) {
        return false;
    }

    Node *n2 = units->top()->dnc->toNode(t2);
    n2 = units->top()->mp->parsePotentialMacroCall(n2);
    if (!n2) {
        return false;
    }

    int error_count_begin =
        units->top()->ctx->er->getErrorTypeCount(ErrorType::Error);

    Type *type1 = FormTypeParse(units, n,  false, false);
    Type *type2 = FormTypeParse(units, n2, false, false);

    units->top()->ctx->er->popErrors(error_count_begin);
    if (!type1 || !type2) {
        return 0;
    }
    return (type1->isEqualTo(type2));
}
Ejemplo n.º 11
0
void SED::write(const QString& filename) const
{
    WavelengthGrid* lambdagrid = find<WavelengthGrid>();
    Units* units = find<Units>();

    ofstream file(filename.toLocal8Bit().constData());
    file << setprecision(8) << scientific;
    for (int ell=0; ell<lambdagrid->Nlambda(); ell++)
    {
        double lambda = lambdagrid->lambda(ell);
        double dlambda = lambdagrid->dlambda(ell);
        file << units->owavelength(lambda)
             << '\t'
             << _Lv[ell]/dlambda*lambda
             << endl;
    }
    file.close();
}
Ejemplo n.º 12
0
// class methods
double Units::convertValue(double value, const Units& fromUnits, const Units& toUnits) {
  if (fromUnits.isSameDimensionAs(toUnits)) {
    return (value * fromUnits._conversion / toUnits._conversion);
  }
  else {
    cerr << "Units are not dimensionally consistent" << endl;
    return 0.;
  }
}
Ejemplo n.º 13
0
ContourFindingBase::ContourFindingBase(const ActionOptions&ao):
Action(ao),
ActionWithInputGrid(ao),
mymin(this),
mydata(NULL)
{
  if( ingrid->noDerivatives() ) error("cannot find contours if input grid has no derivatives");
  parse("CONTOUR",contour); 
  log.printf("  calculating dividing surface along which function equals %f \n", contour);

  if( keywords.exists("FILE") ){
      std::string file; parse("FILE",file);
      if(file.length()==0 && keywords.style("FILE","compulsory") ) error("name out output file was not specified");
      else if( file.length()>0 ){
         std::string type=Tools::extension(file);
         log<<"  file name "<<file<<"\n";
         if(type!="xyz") error("can only print xyz file type with contour finding");

         fmt_xyz="%f";
         std::string precision; parse("PRECISION",precision);
         if(precision.length()>0){
           int p; Tools::convert(precision,p);
           log<<"  with precision "<<p<<"\n";
           std::string a,b;
           Tools::convert(p+5,a);
           Tools::convert(p,b);
           fmt_xyz="%"+a+"."+b+"f";
         }

         std::string unitname; parse("UNITS",unitname);
         if(unitname!="PLUMED"){
           Units myunit; myunit.setLength(unitname);
           lenunit=plumed.getAtoms().getUnits().getLength()/myunit.getLength();
         }
         else lenunit=1.0; 

         of.link(*this); of.open(file); 

         // Now create a store data vessel to hold the points
         mydata=buildDataStashes( NULL );
      }
  }
}
Ejemplo n.º 14
0
	QString FrameCd::sizeDescription( const Units& units ) const
	{
		if ( units.toEnum() == Units::IN )
		{
			QString dStr = StrUtil::formatFraction( 2 * mR1.in() );

			return QString().sprintf( "%s %s %s",
						  qPrintable(dStr),
						  qPrintable(units.toTrName()),
						  qPrintable(tr("diameter")) );
		}
		else
		{
			return QString().sprintf( "%.5g %s %s",
						  2 * mR1.inUnits(units),
						  qPrintable(units.toTrName()),
						  qPrintable(tr("diameter")) );
		}
	}
Ejemplo n.º 15
0
bool
VCheck::Compatible::valid (const Units& units, symbol value, Treelog& msg) const
{
  if (units.can_convert (dimension, value))
    return true;
  
  std::ostringstream tmp;
  tmp << "Cannot convert [" << dimension << "] to [" << value << "]";
  msg.error (tmp.str ());
  return false;
}
Ejemplo n.º 16
0
void InstrumentFrame::calibrateAndWriteDataFrames(int ell, QList<Array*> farrays, QStringList fnames)
{
    Units* units = find<Units>();
    WavelengthGrid* lambdagrid = find<WavelengthGrid>();

    // conversion from bolometric luminosities (units W) to monochromatic luminosities (units W/m)
    // --> divide by delta-lambda
    double dlambda = lambdagrid->dlambda(ell);

    // correction for the area of the pixels of the images; the units are now W/m/sr
    // --> divide by area
    double xpresang = 2.0*atan(_xpres/(2.0*_distance));
    double ypresang = 2.0*atan(_ypres/(2.0*_distance));
    double area = xpresang*ypresang;

    // calibration step 3: conversion of the flux per pixel from monochromatic luminosity units (W/m/sr)
    // to flux density units (W/m3/sr) by taking into account the distance
    // --> divide by fourpid2
    double fourpid2 = 4.0*M_PI*_distance*_distance;

    // conversion from program SI units (at this moment W/m3/sr) to the correct output units
    // --> multiply by unit conversion factor
    double unitfactor = units->osurfacebrightness(lambdagrid->lambda(ell), 1.);

    // Perform the conversion, in place
    foreach (Array* farr, farrays)
    {
        (*farr) *= (unitfactor / (dlambda * area * fourpid2));
    }

    // Write a FITS file for each array
    for (int q = 0; q < farrays.size(); q++)
    {
        QString filename = _instrument->instrumentName() + "_" + fnames[q] + "_" + QString::number(ell);
        QString description = fnames[q] + " flux " + QString::number(ell);

        // Create the image and save it
        Image image(this, _Nxp, _Nyp, 1, _xpres, _ypres, "surfacebrightness");
        image.saveto(this, *(farrays[q]), filename, description);
    }
}
Ejemplo n.º 17
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.");
}
Ejemplo n.º 18
0
s16 Battle::AIAttackPosition(Arena & arena, const Unit & b, const Indexes & positions)
{
    s16 res = -1;

    if(b.isMultiCellAttack())
    {
        res = AIMaxQualityPosition(positions);
    }
    else
    if(b.isDoubleCellAttack())
    {
        Indexes results;
        results.reserve(12);

	const Units enemies(arena.GetForce(b.GetColor(), true), true);

	if(1 < enemies.size())
	{
	    for(Units::const_iterator
		it1 = enemies.begin(); it1 != enemies.end(); ++it1)
	    {
		const Indexes around = Board::GetAroundIndexes(**it1);

		for(Indexes::const_iterator
		    it2 = around.begin(); it2 != around.end(); ++it2)
		{
		    const Unit* unit = Board::GetCell(*it2)->GetUnit();
		    if(unit && enemies.end() != std::find(enemies.begin(), enemies.end(), unit))
			results.push_back(*it2);
		}
	    }

    	    if(results.size())
    	    {
        	// find passable results
        	Indexes passable = Arena::GetBoard()->GetPassableQualityPositions(b);
        	Indexes::iterator it2 = results.begin();

        	for(Indexes::const_iterator
		    it = results.begin(); it != results.end(); ++it)
            	    if(passable.end() != std::find(passable.begin(), passable.end(), *it))
                	*it2++ = *it;

        	if(it2 != results.end())
            	    results.resize(std::distance(results.begin(), it2));

        	// get max quality
        	if(results.size())
            	    res = AIMaxQualityPosition(results);
    	    }
	}
    }

    return 0 > res ? AIShortDistance(b.GetHeadIndex(), positions) : res;
}
Ejemplo n.º 19
0
static bool
get_type(MContext *mc, DNode *dnode, Type **type)
{
    Units *units = (dale::Units*) mc->units;
    Node *n = units->top()->dnc->toNode(dnode);
    n = units->top()->mp->parsePotentialMacroCall(n);
    if (!n) {
        return false;
    }

    int error_count_begin =
        units->top()->ctx->er->getErrorTypeCount(ErrorType::Error);

    *type = FormTypeParse(units, n, false, false);

    units->top()->ctx->er->popErrors(error_count_begin);
    if (!*type) {
        return false;
    }

    return true;
}
Ejemplo n.º 20
0
CString PSPower::GetAllInfo()
{
	CString strInfo, strSCs, strArmies, strFleets;
	int nArmies = 0;
	int nFleets = 0;
	SCs vSCs = TG.GetSCs(this);
	strSCs.Format(L"%d%s", vSCs.size(), (vSCs.size() != 1) ? L" SC-s:" : L" SC:");
	for (int i = 0; i < vSCs.size(); i++)
		strSCs += " " + vSCs[i]->m_pProvince->m_strName;

	Units vUnits = TG.GetUnits(this);
	for (int i = 0; i < vUnits.size(); i++)
	{
		if (vUnits[i]->GetType() == ARMY)
		{
			nArmies++;
			strArmies += " " + vUnits[i]->GetLocation()->m_strName;
		}
		else
		{
			nFleets++;
			strFleets += " " + vUnits[i]->GetLocation()->m_strName;
			CString strName = vUnits[i]->GetCoast()->m_strName;
			if (strName != "Central")
			{
				strFleets += "(" + strName + ")";
			}
		}
	}

	if (!nArmies && ! nFleets && vSCs.empty())
		strInfo.Format(L"%s%s%s", m_strName, L":\r\n", L"Eliminated\r\n\r\n");// TODO: Conditions may vary.
	else
		strInfo.Format(L"%s%s%s%s%d%s%s%s%d%s%s%s", m_strName, L":\r\n", strSCs, L"\r\n", 
			nArmies, (nArmies != 1) ? L" Armies: " : L" Army: ", strArmies, L"\r\n", 
			nFleets, (nFleets != 1) ? L" Fleets: " : L" Fleet: ", strFleets, "\r\n\r\n");

	return strInfo;
}
Ejemplo n.º 21
0
void PerspectiveInstrument::write()
{
    Units* units = find<Units>();
    WavelengthGrid* lambdagrid = find<WavelengthGrid>();
    int Nlambda = find<WavelengthGrid>()->Nlambda();

    // Put the data cube in a list of f-array pointers, as the sumResults function requires
    QList< Array* > farrays;
    farrays << &_ftotv;

    // Sum the flux arrays element-wise across the different processes
    sumResults(farrays);

    // Multiply each sample by lambda/dlamdba and by the constant factor 1/(4 pi s^2)
    // to obtain the surface brightness and convert to output units (such as W/m2/arcsec2)

    double front = 1. / (4.*M_PI*_s*_s);
    for (int ell=0; ell<Nlambda; ell++)
    {
        double lambda = lambdagrid->lambda(ell);
        double dlambda = lambdagrid->dlambda(ell);
        for (int i=0; i<_Nx; i++)
        {
            for (int j=0; j<_Ny; j++)
            {
                int m = i + _Nx*j + _Nx*_Ny*ell;
                _ftotv[m] = units->osurfacebrightness(lambda, _ftotv[m]*front/dlambda);
            }
        }
    }

    // Write a FITS file containing the data cube

    QString filename = _instrumentname + "_total";
    Image image(this, _Nx, _Ny, Nlambda, _s, _s, "surfacebrightness");
    image.saveto(this, _ftotv, filename, "total flux");
}
Ejemplo n.º 22
0
Units::Units(const Units& other)
{
	setSystem(other.system());
	setTemp(other.temp());
	setPressure(other.pressure());
	setSpeed(other.speed());
	setLongDistance(other.longDistance());
	setShortDistance(other.shortDistance());
	
	QObject::connect(this, SIGNAL(systemChanged(Weather::Units::System)), this, SLOT(onSystemChanged()));	
	QObject::connect(this, SIGNAL(tempChanged(Weather::Units::Temperature)), this, SIGNAL(unitsChanged()));
	QObject::connect(this, SIGNAL(pressureChanged(Weather::Units::Pressure)), this, SIGNAL(unitsChanged()));
	QObject::connect(this, SIGNAL(speedChanged(Weather::Units::Speed)), this, SIGNAL(unitsChanged()));
	QObject::connect(this, SIGNAL(longDistanceChanged(Weather::Units::Distance)), this, SIGNAL(unitsChanged()));
	QObject::connect(this, SIGNAL(shortDistanceChanged(Weather::Units::Distance)), this, SIGNAL(unitsChanged()));
}
Ejemplo n.º 23
0
void InstrumentFrame::calibrateAndWriteDataFrames(int ell, QList<Array*> farrays, QStringList fnames)
{
    PeerToPeerCommunicator* comm = find<PeerToPeerCommunicator>();
    if (!comm->isRoot()) return;

    Units* units = find<Units>();
    WavelengthGrid* lambdagrid = find<WavelengthGrid>();

    // conversion from bolometric luminosities (units W) to monochromatic luminosities (units W/m)
    // --> divide by delta-lambda
    double dlambda = lambdagrid->dlambda(ell);

    // correction for the area of the pixels of the images; the units are now W/m/sr
    // --> divide by area
    double xpresang = 2.0*atan(_xpres/(2.0*_distance));
    double ypresang = 2.0*atan(_ypres/(2.0*_distance));
    double area = xpresang*ypresang;

    // calibration step 3: conversion of the flux per pixel from monochromatic luminosity units (W/m/sr)
    // to flux density units (W/m3/sr) by taking into account the distance
    // --> divide by fourpid2
    double fourpid2 = 4.0*M_PI*_distance*_distance;

    // conversion from program SI units (at this moment W/m3/sr) to the correct output units
    // --> multiply by unit conversion factor
    double unitfactor = units->osurfacebrightness(lambdagrid->lambda(ell), 1.);

    // perform the conversion, in place
    foreach (Array* farr, farrays)
    {
        (*farr) *= (unitfactor / (dlambda * area * fourpid2));
    }

    // write a FITS file for each array
    for (int q = 0; q < farrays.size(); q++)
    {
        QString filename = find<FilePaths>()->output(_instrument->instrumentName()
                                                     + "_" + fnames[q] + "_" + QString::number(ell) + ".fits");
        find<Log>()->info("Writing " + fnames[q] + " flux " + QString::number(ell)
                                                     + " to FITS file " + filename + "...");
        FITSInOut::write(filename, *(farrays[q]), _Nxp, _Nyp, 1,
                       units->olength(_xpres), units->olength(_ypres),
                       units->usurfacebrightness(), units->ulength());
    }
}
Ejemplo n.º 24
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();
        }
    }
}
Ejemplo n.º 25
0
int Driver<real>::main(FILE* in,FILE*out,Communicator& pc){

  Units units;
  PDB pdb;

// Parse everything
  bool printhelpdebug; parseFlag("--help-debug",printhelpdebug);
  if( printhelpdebug ){
      fprintf(out,"%s",
         "Additional options for debug (only to be used in regtest):\n"
         "  [--debug-float]         : turns on the single precision version (to check float interface)\n"
         "  [--debug-dd]            : use a fake domain decomposition\n"
         "  [--debug-pd]            : use a fake particle decomposition\n"
      );
      return 0;
  }
  // Are we reading trajectory data
  bool noatoms; parseFlag("--noatoms",noatoms);

  std::string fakein; 
  bool debugfloat=parse("--debug-float",fakein);
  if(debugfloat && sizeof(real)!=sizeof(float)){
      CLTool* cl=cltoolRegister().create(CLToolOptions("driver-float"));    //new Driver<float>(*this);
      cl->setInputData(this->getInputData());
      int ret=cl->main(in,out,pc);
      delete cl;
      return ret;
  }

  bool debug_pd=parse("--debug-pd",fakein);
  bool debug_dd=parse("--debug-dd",fakein);
  if( debug_pd || debug_dd ){
    if(noatoms) error("cannot debug without atoms");
  }

// set up for multi replica driver:
  int multi=0;
  parse("--multi",multi);
  Communicator intracomm;
  Communicator intercomm;
  if(multi){
    int ntot=pc.Get_size();
    int nintra=ntot/multi;
    if(multi*nintra!=ntot) error("invalid number of processes for multi environment");
    pc.Split(pc.Get_rank()/nintra,pc.Get_rank(),intracomm);
    pc.Split(pc.Get_rank()%nintra,pc.Get_rank(),intercomm);
  } else {
    intracomm.Set_comm(pc.Get_comm());
  }

// set up for debug replica exchange:
  bool debug_grex=parse("--debug-grex",fakein);
  int  grex_stride=0;
  FILE*grex_log=NULL;
  if(debug_grex){
    if(noatoms) error("must have atoms to debug_grex");
    if(multi<2)  error("--debug_grex needs --multi with at least two replicas");
    Tools::convert(fakein,grex_stride);
    string n; Tools::convert(intercomm.Get_rank(),n);
    string file;
    parse("--debug-grex-log",file);
    if(file.length()>0){
      file+="."+n;
      grex_log=fopen(file.c_str(),"w");
    }
  }

// Read the plumed input file name  
  string plumedFile; parse("--plumed",plumedFile);
// the timestep
  double t; parse("--timestep",t);
  real timestep=real(t);
// the stride
  unsigned stride; parse("--trajectory-stride",stride);
// are we writing forces
  string dumpforces(""), dumpforcesFmt("%f");; 
  if(!noatoms) parse("--dump-forces",dumpforces);
  if(dumpforces!="") parse("--dump-forces-fmt",dumpforcesFmt);

  string trajectory_fmt;

// Read in an xyz file
  string trajectoryFile(""), pdbfile("");
  bool pbc_cli_given=false; vector<double> pbc_cli_box(9,0.0);
  if(!noatoms){
     std::string traj_xyz; parse("--ixyz",traj_xyz);
     std::string traj_gro; parse("--igro",traj_gro);
     if(traj_xyz.length()>0 && traj_gro.length()>0){
       fprintf(stderr,"ERROR: cannot provide more than one trajectory file\n");
       if(grex_log)fclose(grex_log);
       return 1;
     }
     if(traj_xyz.length()>0 && trajectoryFile.length()==0){
       trajectoryFile=traj_xyz;
       trajectory_fmt="xyz";
     }
     if(traj_gro.length()>0 && trajectoryFile.length()==0){
       trajectoryFile=traj_gro;
       trajectory_fmt="gro";
     }
     if(trajectoryFile.length()==0){
       fprintf(stderr,"ERROR: missing trajectory data\n"); 
       if(grex_log)fclose(grex_log);
       return 1;
     }
     string lengthUnits(""); parse("--length-units",lengthUnits);
     if(lengthUnits.length()>0) units.setLength(lengthUnits);
  
     parse("--pdb",pdbfile);
     if(pdbfile.length()>0){
       bool check=pdb.read(pdbfile,false,1.0);
       if(!check) error("error reading pdb file");
     }

     string pbc_cli_list; parse("--box",pbc_cli_list);
     if(pbc_cli_list.length()>0) {
       pbc_cli_given=true;
       vector<string> words=Tools::getWords(pbc_cli_list,",");
       if(words.size()==3){
         for(int i=0;i<3;i++) sscanf(words[i].c_str(),"%100lf",&(pbc_cli_box[4*i]));
       } else if(words.size()==9) {
         for(int i=0;i<9;i++) sscanf(words[i].c_str(),"%100lf",&(pbc_cli_box[i]));
       } else {
         string msg="ERROR: cannot parse command-line box "+pbc_cli_list;
         fprintf(stderr,"%s\n",msg.c_str());
         return 1;
       }

     }
  }

  if( debug_dd && debug_pd ) error("cannot use debug-dd and debug-pd at the same time");
  if(debug_pd || debug_dd){
    if( !Communicator::initialized() ) error("needs mpi for debug-pd");
  }

  Plumed p;
  int rr=sizeof(real);
  p.cmd("setRealPrecision",&rr);
  int checknatoms=-1;
  int step=0;
  if(Communicator::initialized()){
    if(multi){
      if(intracomm.Get_rank()==0) p.cmd("GREX setMPIIntercomm",&intercomm.Get_comm());
      p.cmd("GREX setMPIIntracomm",&intracomm.Get_comm());
      p.cmd("GREX init");
    } 
    p.cmd("setMPIComm",&intracomm.Get_comm());
  } 
  p.cmd("setMDLengthUnits",&units.getLength());
  p.cmd("setMDEngine","driver");
  p.cmd("setTimestep",&timestep);
  p.cmd("setPlumedDat",plumedFile.c_str());
  p.cmd("setLog",out);

  if(multi){
    string n;
    Tools::convert(intercomm.Get_rank(),n);
    trajectoryFile+="."+n;
  }

  FILE* fp=NULL; FILE* fp_forces=NULL;
  if(!noatoms){
     if (trajectoryFile=="-") 
       fp=in;
     else {
       fp=fopen(trajectoryFile.c_str(),"r");
       if(!fp){
         string msg="ERROR: Error opening XYZ file "+trajectoryFile;
         fprintf(stderr,"%s\n",msg.c_str());
         return 1;
       }
     }

     if(dumpforces.length()>0){
       if(Communicator::initialized() && pc.Get_size()>1){
         string n;
         Tools::convert(pc.Get_rank(),n);
         dumpforces+="."+n;
       }
       fp_forces=fopen(dumpforces.c_str(),"w");
     }
  }

  std::string line;
  std::vector<real> coordinates;
  std::vector<real> forces;
  std::vector<real> masses;
  std::vector<real> charges;
  std::vector<real> cell;
  std::vector<real> virial;

// variables to test particle decomposition
  int pd_nlocal;
  int pd_start;
// variables to test random decomposition (=domain decomposition)
  std::vector<int>  dd_gatindex;
  std::vector<int>  dd_g2l;
  std::vector<real> dd_masses;
  std::vector<real> dd_charges;
  std::vector<real> dd_forces;
  std::vector<real> dd_coordinates;
  int dd_nlocal;
// random stream to choose decompositions
  Random rnd;

  while(true){
    if(!noatoms){
       if(!Tools::getline(fp,line)) break;
    }

    int natoms;
    bool first_step=false;
    if(!noatoms){
      if(trajectory_fmt=="gro") if(!Tools::getline(fp,line)) error("premature end of trajectory file");
      sscanf(line.c_str(),"%100d",&natoms);
    }
    if(checknatoms<0 && !noatoms){
      pd_nlocal=natoms;
      pd_start=0;
      first_step=true;
      masses.assign(natoms,real(1.0));
      charges.assign(natoms,real(0.0));
      if(pdbfile.length()>0){
        for(unsigned i=0;i<pdb.size();++i){
          AtomNumber an=pdb.getAtomNumbers()[i];
          unsigned index=an.index();
          if( index>=unsigned(natoms) ) error("atom index in pdb exceeds the number of atoms in trajectory");
          masses[index]=pdb.getOccupancy()[i];
          charges[index]=pdb.getBeta()[i];
        }
      }
    } else if( checknatoms<0 && noatoms ){ 
      natoms=0; 
    }
    if( checknatoms<0 ){
      checknatoms=natoms;
      p.cmd("setNatoms",&natoms);
      p.cmd("init");
    }
    if(checknatoms!=natoms){
       std::string stepstr; Tools::convert(step,stepstr);
       error("number of atoms in frame " + stepstr + " does not match number of atoms in first frame");
    }

    coordinates.assign(3*natoms,real(0.0));
    forces.assign(3*natoms,real(0.0));
    cell.assign(9,real(0.0));
    virial.assign(9,real(0.0));

    if( first_step || rnd.U01()>0.5){
      if(debug_pd){
        int npe=intracomm.Get_size();
        vector<int> loc(npe,0);
        vector<int> start(npe,0);
        for(int i=0;i<npe-1;i++){
          int cc=(natoms*2*rnd.U01())/npe;
          if(start[i]+cc>natoms) cc=natoms-start[i];
          loc[i]=cc;
          start[i+1]=start[i]+loc[i];
        }
        loc[npe-1]=natoms-start[npe-1];
        intracomm.Bcast(loc,0);
        intracomm.Bcast(start,0);
        pd_nlocal=loc[intracomm.Get_rank()];
        pd_start=start[intracomm.Get_rank()];
        if(intracomm.Get_rank()==0){
          fprintf(out,"\nDRIVER: Reassigning particle decomposition\n");
          fprintf(out,"DRIVER: "); for(int i=0;i<npe;i++) fprintf(out,"%d ",loc[i]); printf("\n");
          fprintf(out,"DRIVER: "); for(int i=0;i<npe;i++) fprintf(out,"%d ",start[i]); printf("\n");
        }
        p.cmd("setAtomsNlocal",&pd_nlocal);
        p.cmd("setAtomsContiguous",&pd_start);
      } else if(debug_dd){
        int npe=intracomm.Get_size();
        int rank=intracomm.Get_rank();
        dd_charges.assign(natoms,0.0);
        dd_masses.assign(natoms,0.0);
        dd_gatindex.assign(natoms,-1);
        dd_g2l.assign(natoms,-1);
        dd_coordinates.assign(3*natoms,0.0);
        dd_forces.assign(3*natoms,0.0);
        dd_nlocal=0;
        for(int i=0;i<natoms;++i){
          double r=rnd.U01()*npe;
          int n; for(n=0;n<npe;n++) if(n+1>r)break;
          plumed_assert(n<npe);
          if(n==rank){
            dd_gatindex[dd_nlocal]=i;
            dd_g2l[i]=dd_nlocal;
            dd_charges[dd_nlocal]=charges[i];
            dd_masses[dd_nlocal]=masses[i];
            dd_nlocal++;
          }
        }
        if(intracomm.Get_rank()==0){
          fprintf(out,"\nDRIVER: Reassigning particle decomposition\n");
        }
        p.cmd("setAtomsNlocal",&dd_nlocal);
        p.cmd("setAtomsGatindex",&dd_gatindex[0]);
      }
    }

    int plumedStopCondition=0;
    p.cmd("setStep",&step);
    p.cmd("setStopFlag",&plumedStopCondition);
    if(!noatoms){
       if(trajectory_fmt=="xyz"){
         if(!Tools::getline(fp,line)) error("premature end of trajectory file");

         std::vector<double> celld(9,0.0);
         if(pbc_cli_given==false) {
           std::vector<std::string> words;
           words=Tools::getWords(line);
           if(words.size()==3){
             sscanf(line.c_str(),"%100lf %100lf %100lf",&celld[0],&celld[4],&celld[8]);
           } else if(words.size()==9){
             sscanf(line.c_str(),"%100lf %100lf %100lf %100lf %100lf %100lf %100lf %100lf %100lf",
                    &celld[0], &celld[1], &celld[2],
                    &celld[3], &celld[4], &celld[5],
                    &celld[6], &celld[7], &celld[8]);
           } else error("needed box in second line of xyz file");
         } else {			// from command line
           celld=pbc_cli_box;
         }
         for(unsigned i=0;i<9;i++)cell[i]=real(celld[i]);
       }
  	   int ddist=0;
       // Read coordinates
       for(int i=0;i<natoms;i++){
         bool ok=Tools::getline(fp,line);
         if(!ok) error("premature end of trajectory file");
         double cc[3];
         if(trajectory_fmt=="xyz"){
           char dummy[1000];
           std::sscanf(line.c_str(),"%999s %100lf %100lf %100lf",dummy,&cc[0],&cc[1],&cc[2]);
         } else if(trajectory_fmt=="gro"){
           // do the gromacs way
           if(!i){
        	   //
        	   // calculate the distance between dots (as in gromacs gmxlib/confio.c, routine get_w_conf )
        	   //
        	   const char      *p1, *p2, *p3;
        	   p1 = strchr(line.c_str(), '.');
        	   if (p1 == NULL) error("seems there are no coordinates in the gro file");
        	   p2 = strchr(&p1[1], '.');
        	   if (p2 == NULL) error("seems there is only one coordinates in the gro file");
        	   ddist = p2 - p1;
        	   p3 = strchr(&p2[1], '.');
        	   if (p3 == NULL)error("seems there are only two coordinates in the gro file");
        	   if (p3 - p2 != ddist)error("not uniform spacing in fields in the gro file");
           }
           Tools::convert(line.substr(20,ddist),cc[0]);
           Tools::convert(line.substr(20+ddist,ddist),cc[1]);
           Tools::convert(line.substr(20+ddist+ddist,ddist),cc[2]);
         } else plumed_error();
         if(!debug_pd || ( i>=pd_start && i<pd_start+pd_nlocal) ){
           coordinates[3*i]=real(cc[0]);
           coordinates[3*i+1]=real(cc[1]);
           coordinates[3*i+2]=real(cc[2]);
         }
       }
       if(trajectory_fmt=="gro"){
         if(!Tools::getline(fp,line)) error("premature end of trajectory file");
         std::vector<string> words=Tools::getWords(line);
         if(words.size()<3) error("cannot understand box format");
         Tools::convert(words[0],cell[0]);
         Tools::convert(words[1],cell[4]);
         Tools::convert(words[2],cell[8]);
         if(words.size()>3) Tools::convert(words[3],cell[1]);
         if(words.size()>4) Tools::convert(words[4],cell[2]);
         if(words.size()>5) Tools::convert(words[5],cell[3]);
         if(words.size()>6) Tools::convert(words[6],cell[5]);
         if(words.size()>7) Tools::convert(words[7],cell[6]);
         if(words.size()>8) Tools::convert(words[8],cell[7]);
       }

       if(debug_dd){
         for(int i=0;i<dd_nlocal;++i){
           int kk=dd_gatindex[i];
           dd_coordinates[3*i+0]=coordinates[3*kk+0];
           dd_coordinates[3*i+1]=coordinates[3*kk+1];
           dd_coordinates[3*i+2]=coordinates[3*kk+2];
         }
         p.cmd("setForces",&dd_forces[0]);
         p.cmd("setPositions",&dd_coordinates[0]);
         p.cmd("setMasses",&dd_masses[0]);
         p.cmd("setCharges",&dd_charges[0]);
       } else {
         p.cmd("setForces",&forces[3*pd_start]);
         p.cmd("setPositions",&coordinates[3*pd_start]);
         p.cmd("setMasses",&masses[pd_start]);
         p.cmd("setCharges",&charges[pd_start]);
       }
       p.cmd("setBox",&cell[0]);
       p.cmd("setVirial",&virial[0]);
   }
   p.cmd("calc");

// this is necessary as only processor zero is adding to the virial:
   intracomm.Bcast(virial,0);
   if(debug_pd) intracomm.Sum(forces);
   if(debug_dd){
     for(int i=0;i<dd_nlocal;i++){
       forces[3*dd_gatindex[i]+0]=dd_forces[3*i+0];
       forces[3*dd_gatindex[i]+1]=dd_forces[3*i+1];
       forces[3*dd_gatindex[i]+2]=dd_forces[3*i+2];
     }
     dd_forces.assign(3*natoms,0.0);
     intracomm.Sum(forces);
   }
   if(debug_grex &&step%grex_stride==0){
     p.cmd("GREX savePositions");
     if(intracomm.Get_rank()>0){
       p.cmd("GREX prepare");
     } else {
       int r=intercomm.Get_rank();
       int n=intercomm.Get_size();
       int partner=r+(2*((r+step/grex_stride)%2))-1;
       if(partner<0)partner=0;
       if(partner>=n) partner=n-1;
       p.cmd("GREX setPartner",&partner);
       p.cmd("GREX calculate");
       p.cmd("GREX shareAllDeltaBias");
       for(int i=0;i<n;i++){
         string s; Tools::convert(i,s);
         real a; s="GREX getDeltaBias "+s; p.cmd(s.c_str(),&a);
         if(grex_log) fprintf(grex_log," %f",a);
       }
       if(grex_log) fprintf(grex_log,"\n");
     }
   }


   if(fp_forces){
     fprintf(fp_forces,"%d\n",natoms);
     string fmt=dumpforcesFmt+" "+dumpforcesFmt+" "+dumpforcesFmt+"\n";
     fprintf(fp_forces,fmt.c_str(),virial[0],virial[4],virial[8]);
     fmt="X "+fmt;
     for(int i=0;i<natoms;i++)
       fprintf(fp_forces,fmt.c_str(),forces[3*i],forces[3*i+1],forces[3*i+2]);
   }

    if(noatoms && plumedStopCondition) break;

    step+=stride;
  }
  p.cmd("runFinalJobs");

  if(fp_forces) fclose(fp_forces);
  if(fp && fp!=in)fclose(fp);
  if(grex_log) fclose(grex_log);
  
  return 0;
}
Ejemplo n.º 26
0
void DustSystem::writecellproperties() const
{
    Log* log = find<Log>();
    Units* units = find<Units>();

    // open the file and write a header
    QString filename = find<FilePaths>()->output("ds_cellprops.dat");
    log->info("Writing dust cell properties to " + filename + "...");
    ofstream file(filename.toLocal8Bit().constData());
    file << "# column 1: volume (" << units->uvolume().toStdString() << ")\n";
    file << "# column 2: density (" << units->umassvolumedensity().toStdString() << ")\n";
    file << "# column 3: mass fraction\n";
    file << "# column 4: optical depth\n";

    // write a line for each cell; remember the tau values so we can compute some statistics
    Array tauV(_Ncells);
    double totalmass = _dd->mass();
    for (int m=0; m<_Ncells; m++)
    {
        double rho = density(m);
        double V = volume(m);
        double delta = (rho*V)/totalmass;
        double tau = Units::kappaV()*rho*pow(V,1./3.);
        file << units->ovolume(V) << '\t' << units->omassvolumedensity(rho) << '\t' << delta << '\t' << tau << '\n';
        tauV[m] = tau;
    }

    // calculate some statistics on optical depth
    double tauavg = tauV.sum()/_Ncells;
    double taumin = tauV.min();
    double taumax = tauV.max();
    const int Nbins = 500;
    vector<int> countV(Nbins+1);
    for (int m=0; m<_Ncells; m++)
    {
        int index = qMax(0,qMin(Nbins, static_cast<int>((tauV[m]-taumin)/(taumax-taumin)*Nbins)));
        countV[index]++;
    }
    int count = 0;
    int index = 0;
    for (; index<Nbins; index++)
    {
        count += countV[index];
        if (count > 0.9*_Ncells) break;
    }
    double tau90 = taumin + index*(taumax-taumin)/Nbins;

    // write the statistics on optical depth to the file
    file << "# smallest optical depth: " << taumin << '\n';
    file << "# largest optical depth:  " << taumax << '\n';
    file << "# average optical depth:  " << tauavg << '\n';
    file << "# 90 % of the cells have optical depth smaller than: " << tau90 << '\n';

    // close the file
    file.close();
    log->info("File " + filename + " created.");

    // report the statistics on optical depth to the console
    log->info("  Smallest optical depth: " + QString::number(taumin));
    log->info("  Largest optical depth:  " + QString::number(taumax));
    log->info("  Average optical depth:  " + QString::number(tauavg));
    log->info("  90 % of the cells have optical depth smaller than: " + QString::number(tau90));
}
Ejemplo n.º 27
0
bool
SpatialReference::transformZ(std::vector<osg::Vec3d>& points,
                             const SpatialReference*  outputSRS,
                             bool                     pointsAreLatLong) const
{
    const VerticalDatum* outVDatum = outputSRS->getVerticalDatum();

    // same vdatum, no xformation necessary.
    if ( _vdatum.get() == outVDatum )
        return true;

    Units inUnits = _vdatum.valid() ? _vdatum->getUnits() : Units::METERS;
    Units outUnits = outVDatum ? outVDatum->getUnits() : inUnits;

    if ( isGeographic() || pointsAreLatLong )
    {
        for( unsigned i=0; i<points.size(); ++i )
        {
            if ( _vdatum.valid() )
            {
                // to HAE:
                points[i].z() = _vdatum->msl2hae( points[i].y(), points[i].x(), points[i].z() );
            }

            // do the units conversion:
            points[i].z() = inUnits.convertTo(outUnits, points[i].z());

            if ( outVDatum )
            {
                // to MSL:
                points[i].z() = outVDatum->hae2msl( points[i].y(), points[i].x(), points[i].z() );
            }
        }
    }

    else // need to xform input points
    {
        // copy the points and convert them to geographic coordinates (lat/long with the same Z):
        std::vector<osg::Vec3d> geopoints(points);
        transform( geopoints, getGeographicSRS() );

        for( unsigned i=0; i<geopoints.size(); ++i )
        {
            if ( _vdatum.valid() )
            {
                // to HAE:
                points[i].z() = _vdatum->msl2hae( geopoints[i].y(), geopoints[i].x(), points[i].z() );
            }

            // do the units conversion:
            points[i].z() = inUnits.convertTo(outUnits, points[i].z());

            if ( outVDatum )
            {
                // to MSL:
                points[i].z() = outVDatum->hae2msl( geopoints[i].y(), geopoints[i].x(), points[i].z() );
            }
        }
    }

    return true;
}
Ejemplo n.º 28
0
void DustSystem::writeconvergence() const
{
    // Perform a convergence check on the grid. First calculate the total
    // mass and the principle axes surface densities by integrating
    // over the grid.

    find<Log>()->info("Performing a convergence check on the grid...");

    // calculation of the mass

    double M = 0.0;
    for (int m=0; m<_Ncells; m++)
    {
        M += density(m)*volume(m);
    }

    // calculation of the X-axis surface density

    double SigmaX = 0;
    DustGridPath dgp(Position(0.,0.,0.), Direction(1.,0.,0.));
    _grid->path(&dgp);
    SigmaX += dgp.opticalDepth([this](int m){ return density(m); });
    dgp.setDirection(Direction(-1.,0.,0.));
    _grid->path(&dgp);
    SigmaX += dgp.opticalDepth([this](int m){ return density(m); });

    // calculation of the Y-axis surface density

    double SigmaY = 0.0;
    dgp.setDirection(Direction(0.,1.,0.));
    _grid->path(&dgp);
    SigmaY += dgp.opticalDepth([this](int m){ return density(m); });
    dgp.setDirection(Direction(0.,-1.,0.));
    _grid->path(&dgp);
    SigmaY += dgp.opticalDepth([this](int m){ return density(m); });

    // calculation of the Z-axis surface density

    double SigmaZ = 0.0;
    dgp.setDirection(Direction(0.,0.,1.));
    _grid->path(&dgp);
    SigmaZ += dgp.opticalDepth([this](int m){ return density(m); });
    dgp.setDirection(Direction(0.,0.,-1.));
    _grid->path(&dgp);
    SigmaZ += dgp.opticalDepth([this](int m){ return density(m); });

    // Compare these values to the expected values and write the result to file

    QString filename = find<FilePaths>()->output("ds_convergence.dat");
    find<Log>()->info("Writing convergence check on the dust system to " + filename + "...");
    Units* units = find<Units>();
    ofstream file(filename.toLocal8Bit().constData());
    file << "Convergence check on the grid: \n";
    switch (_dd->dimension())
    {
        case 1:
        {
            double Sigmar = 0.5*SigmaX;
            double Sigmarref = 0.5*_dd->SigmaX();
            file << "   - radial (r-axis) surface density\n"
                 << "         expected value = " << units->omasssurfacedensity(Sigmarref)
                 << " " << units->umasssurfacedensity().toStdString() << "\n"
                 << "         actual value =   " << units->omasssurfacedensity(Sigmar)
                 << " " << units->umasssurfacedensity().toStdString() << "\n";
        }
        break;
        case 2:
        {
            double SigmaR = 0.5*SigmaX;
            double SigmaRref = 0.5*_dd->SigmaX();
            double SigmaZref = _dd->SigmaZ();
            file << "   - edge-on (R-axis) surface density\n"
                 << "         expected value = " << units->omasssurfacedensity(SigmaRref)
                 << " " << units->umasssurfacedensity().toStdString() << "\n"
                 << "         actual value =   " << units->omasssurfacedensity(SigmaR)
                 << " " << units->umasssurfacedensity().toStdString() << "\n"
                 << "   - face-on (Z-axis) surface density\n"
                 << "         expected value = " << units->omasssurfacedensity(SigmaZref)
                 << " " << units->umasssurfacedensity().toStdString() << "\n"
                 << "         actual value =   " << units->omasssurfacedensity(SigmaZ)
                 << " " << units->umasssurfacedensity().toStdString() << "\n";
        }
        break;
        case 3:
        {
            double SigmaXref = _dd->SigmaX();
            double SigmaYref = _dd->SigmaY();
            double SigmaZref = _dd->SigmaZ();
            file << "   - X-axis surface density\n"
                 << "         expected value = " << units->omasssurfacedensity(SigmaXref)
                 << " " << units->umasssurfacedensity().toStdString() << "\n"
                 << "         actual value =   " << units->omasssurfacedensity(SigmaX)
                 << " " << units->umasssurfacedensity().toStdString() << "\n"
                 << "   - Y-axis surface density\n"
                 << "         expected value = " << units->omasssurfacedensity(SigmaYref)
                 << " " << units->umasssurfacedensity().toStdString() << "\n"
                 << "         actual value =   " << units->omasssurfacedensity(SigmaY)
                 << " " << units->umasssurfacedensity().toStdString() << "\n"
                 << "   - Z-axis surface density\n"
                 << "         expected value = " << units->omasssurfacedensity(SigmaZref)
                 << " " << units->umasssurfacedensity().toStdString() << "\n"
                 << "         actual value =   " << units->omasssurfacedensity(SigmaZ)
                 << " " << units->umasssurfacedensity().toStdString() << "\n";
        }
        break;
        default:
            throw FATALERROR("Wrong dimension in dust distribution");
    }
    double Mref = _dd->mass();
    file << "   - total dust mass\n"
         << "         expected value = " << units->omass(Mref)
         << " " << units->umass().toStdString() << "\n"
         << "         actual value =   " << units->omass(M)
         << " " << units->umass().toStdString() << "\n";
    file.close();
    find<Log>()->info("File " + filename + " created.");
}
Ejemplo n.º 29
0
void SPHStarburstComp::setupSelfBefore()
{
    StellarComp::setupSelfBefore();

    // cache the random generator
    _random = find<Random>();

    // local constant for units
    const double pc = Units::pc();

    // vectors storing the particle attributes (r and h are data members since we need those after setup)
    std::vector<double> SFRv;
    std::vector<double> Zv;
    std::vector<double> logCv;
    std::vector<double> Pv;
    std::vector<double> fPDRv;

    // load the SPH star particles
    QString filepath = find<FilePaths>()->input(_filename);
    QFile infile(filepath);
    if (!infile.open(QIODevice::ReadOnly|QIODevice::Text))
        throw FATALERROR("Could not open the SPH HII region data file " + filepath);
    find<Log>()->info("Reading SPH HII region particles from file " + filepath + "...");
    int Nparts = 0;
    double SFRtot = 0;
    while (!infile.atEnd())
    {
        // read a line, split it in columns, and skip empty and comment lines
        QList<QByteArray> columns = infile.readLine().simplified().split(' ');
        if (!columns.isEmpty() && !columns[0].startsWith('#'))
        {
            // get the column values; missing or illegal values default to zero
            _rv.push_back(Vec(columns.value(0).toDouble()*pc,
                              columns.value(1).toDouble()*pc,
                              columns.value(2).toDouble()*pc));
            _hv.push_back(columns.value(3).toDouble()*pc);
            SFRv.push_back(columns.value(4).toDouble());  // star formation rate in Msun / yr
            Zv.push_back(columns.value(5).toDouble());    // metallicity as dimensionless fraction
            logCv.push_back(columns.value(6).toDouble()); // log compactness (Groves 2008) as dimensionless value
            Pv.push_back(columns.value(7).toDouble());    // ISM pressure in Pa
            fPDRv.push_back(columns.value(8).toDouble()); // dimensionless photo-dissociation region covering fraction

            Nparts++;
            SFRtot += columns.value(4).toDouble();
        }
    }
    infile.close();

    double Mtot = SFRtot * 1.e7;  // total stellar mass from total sfr over the last 10 Myr

    find<Log>()->info("  Total number of SPH HII region particles: " + QString::number(Nparts));
    find<Log>()->info("  Total stellar mass: " + QString::number(Mtot) + " Msun");

    find<Log>()->info("Filling the vectors with the SEDs of the particles... ");

    // construct the library of SED models
    MappingsSEDFamily map(this);

    // construct a temporary matrix Lvv with the luminosity of each particle at each wavelength
    // and also the permanent vector _Ltotv with the total luminosity for every wavelength bin
    int Nlambda = find<WavelengthGrid>()->Nlambda();
    ArrayTable<2> Lvv(Nlambda,Nparts);
    _Ltotv.resize(Nlambda);
    double Ltot = 0;
    for (int i=0; i<Nparts; i++)
    {
        const Array& Lv = map.luminosities(SFRv[i], Zv[i], logCv[i], Pv[i], fPDRv[i]);
        for (int ell=0; ell<Nlambda; ell++)
        {
            Lvv[ell][i] = Lv[ell];
            _Ltotv[ell] += Lv[ell];
            Ltot += Lv[ell];
        }
    }
    find<Log>()->info("  HII luminosity: " + QString::number(Ltot/Units::Lsun()) + " Lsun");

    // construct the permanent vectors _Xvv with the normalized cumulative luminosities (per wavelength bin)
    _Xvv.resize(Nlambda,0);
    for (int ell=0; ell<Nlambda; ell++)
    {
        NR::cdf(_Xvv[ell], Lvv[ell]);
    }

    // if requested, write a data file with the luminosities per wavelength
    if (_writeLuminosities)
    {
        Units* units = find<Units>();
        WavelengthGrid* lambdagrid = find<WavelengthGrid>();

        // Create a text file
        TextOutFile file(this, "HII_luminosities", "HII luminosities");

        // Write the header
        file.addColumn("lambda (" + units->uwavelength() + ")");
        file.addColumn("luminosity (" + units->ubolluminosity() + ")");

        // Write the body
        for (int ell=0; ell<Nlambda; ell++)
        {
            file.writeRow(QList<double>() << units->owavelength(lambdagrid->lambda(ell))
                                          << units->obolluminosity(_Ltotv[ell]));
        }
    }
}
Ejemplo n.º 30
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();
        }
    }
}