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); }
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; }
int PSPower::GetNumberOfUnits(PSData* pData) { if (!pData) pData = TG.GetData(); Units vUnits = pData->GetUnits(this); return vUnits.size(); }
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")); }
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()); }
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; }
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 }
VerticalDatum::VerticalDatum( const Units& units ) : _name ( units.getName() ), _initString( units.getName() ), _units ( units ) { //nop }
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)); }
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)); }
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(); }
// 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.; } }
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 ); } } }
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")) ); } }
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; }
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); } }
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."); }
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; }
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; }
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; }
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"); }
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())); }
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()); } }
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(); } } }
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",×tep); 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; }
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)); }
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; }
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."); }
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])); } } }
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(); } } }