void Action_Diffusion::Help() const { ShortHelp(); mprintf(" Compute a mean square displacement plot for the atoms in the <mask>.\n" " By default the average displacements are calculated unless 'individual'\n" " is specified. Diffusion constants will be calculated from best-fit linear\n" " regression lines of MSDs vs time unless 'nocalc' is specified.\n"); }
void Action_Diffusion::Help() const { ShortHelp(); mprintf(" Compute a mean square displacement plot for the atoms in the <mask>.\n" " The following files are produced:\n" " x_<suffix>: Mean square displacement(s) in the X direction (in Å^2).\n" " y_<suffix>: Mean square displacement(s) in the Y direction (in Å^2).\n" " z_<suffix>: Mean square displacement(s) in the Z direction (in Å^2).\n" " r_<suffix>: Overall mean square displacement(s) (in Å^2).\n" " a_<suffix>: Total distance travelled (in Å).\n"); }
// Action_Diffusion::Init() Action::RetType Action_Diffusion::Init(ArgList& actionArgs, ActionInit& init, int debugIn) { # ifdef MPI trajComm_ = init.TrajComm(); # endif debug_ = debugIn; image_.InitImaging( !(actionArgs.hasKey("noimage")) ); // Determine if this is old syntax or new. if (actionArgs.Nargs() > 2 && actionArgs.ArgIsMask(1) && validDouble(actionArgs[2])) { // Old syntax: <mask> <time per frame> [average] [<prefix>] printIndividual_ = !(actionArgs.hasKey("average")); calcDiffConst_ = false; mprintf("Warning: Deprecated syntax for 'diffusion'. Consider using new syntax:\n"); ShortHelp(); mask_.SetMaskString( actionArgs.GetMaskNext() ); time_ = actionArgs.getNextDouble(1.0); if (CheckTimeArg(time_)) return Action::ERR; std::string outputNameRoot = actionArgs.GetStringNext(); // Default filename: 'diffusion' if (outputNameRoot.empty()) outputNameRoot.assign("diffusion"); // Open output files ArgList oldArgs("prec 8.3 noheader"); DataFile::DataFormatType dft = DataFile::DATAFILE; outputx_ = init.DFL().AddDataFile(outputNameRoot+"_x.xmgr", dft, oldArgs); outputy_ = init.DFL().AddDataFile(outputNameRoot+"_y.xmgr", dft, oldArgs); outputz_ = init.DFL().AddDataFile(outputNameRoot+"_z.xmgr", dft, oldArgs); outputr_ = init.DFL().AddDataFile(outputNameRoot+"_r.xmgr", dft, oldArgs); outputa_ = init.DFL().AddDataFile(outputNameRoot+"_a.xmgr", dft, oldArgs); } else { // New syntax: [{separateout <suffix> | out <filename>}] [time <time per frame>] // [<mask>] [<set name>] [individual] [diffout <filename>] [nocalc] printIndividual_ = actionArgs.hasKey("individual"); calcDiffConst_ = !(actionArgs.hasKey("nocalc")); std::string suffix = actionArgs.GetStringKey("separateout"); std::string outname = actionArgs.GetStringKey("out"); if (!outname.empty() && !suffix.empty()) { mprinterr("Error: Specify either 'out' or 'separateout', not both.\n"); return Action::ERR; } diffout_ = init.DFL().AddDataFile(actionArgs.GetStringKey("diffout")); time_ = actionArgs.getKeyDouble("time", 1.0); if (CheckTimeArg(time_)) return Action::ERR; mask_.SetMaskString( actionArgs.GetMaskNext() ); // Open output files. if (!suffix.empty()) { FileName FName( suffix ); outputx_ = init.DFL().AddDataFile(FName.PrependFileName("x_"), actionArgs); outputy_ = init.DFL().AddDataFile(FName.PrependFileName("y_"), actionArgs); outputz_ = init.DFL().AddDataFile(FName.PrependFileName("z_"), actionArgs); outputr_ = init.DFL().AddDataFile(FName.PrependFileName("r_"), actionArgs); outputa_ = init.DFL().AddDataFile(FName.PrependFileName("a_"), actionArgs); if (diffout_ == 0 && calcDiffConst_) diffout_ = init.DFL().AddDataFile(FName.PrependFileName("diff_"), actionArgs); } else if (!outname.empty()) { outputr_ = init.DFL().AddDataFile( outname, actionArgs ); outputx_ = outputy_ = outputz_ = outputa_ = outputr_; } } if (diffout_ != 0) calcDiffConst_ = true; // Add DataSets dsname_ = actionArgs.GetStringNext(); if (dsname_.empty()) dsname_ = init.DSL().GenerateDefaultName("Diff"); avg_x_ = init.DSL().AddSet(DataSet::DOUBLE, MetaData(dsname_, "X")); avg_y_ = init.DSL().AddSet(DataSet::DOUBLE, MetaData(dsname_, "Y")); avg_z_ = init.DSL().AddSet(DataSet::DOUBLE, MetaData(dsname_, "Z")); avg_r_ = init.DSL().AddSet(DataSet::DOUBLE, MetaData(dsname_, "R")); avg_a_ = init.DSL().AddSet(DataSet::DOUBLE, MetaData(dsname_, "A")); if (avg_x_ == 0 || avg_y_ == 0 || avg_z_ == 0 || avg_r_ == 0 || avg_a_ == 0) return Action::ERR; if (outputr_ != 0) outputr_->AddDataSet( avg_r_ ); if (outputx_ != 0) outputx_->AddDataSet( avg_x_ ); if (outputy_ != 0) outputy_->AddDataSet( avg_y_ ); if (outputz_ != 0) outputz_->AddDataSet( avg_z_ ); if (outputa_ != 0) outputa_->AddDataSet( avg_a_ ); // Set X dim Xdim_ = Dimension(0.0, time_, "Time"); avg_x_->SetDim(Dimension::X, Xdim_); avg_y_->SetDim(Dimension::X, Xdim_); avg_z_->SetDim(Dimension::X, Xdim_); avg_r_->SetDim(Dimension::X, Xdim_); avg_a_->SetDim(Dimension::X, Xdim_); // Add DataSets for diffusion constant calc if (calcDiffConst_) { MetaData::tsType ts = MetaData::NOT_TS; diffConst_ = init.DSL().AddSet(DataSet::DOUBLE, MetaData(dsname_, "D", ts)); diffLabel_ = init.DSL().AddSet(DataSet::STRING, MetaData(dsname_, "Label", ts)); diffSlope_ = init.DSL().AddSet(DataSet::DOUBLE, MetaData(dsname_, "Slope", ts)); diffInter_ = init.DSL().AddSet(DataSet::DOUBLE, MetaData(dsname_, "Intercept", ts)); diffCorrl_ = init.DSL().AddSet(DataSet::DOUBLE, MetaData(dsname_, "Corr", ts)); if (diffConst_ == 0 || diffLabel_ == 0 || diffSlope_ == 0 || diffInter_ == 0 || diffCorrl_ == 0) return Action::ERR; # ifdef MPI // No sync needed since these are not time series diffConst_->SetNeedsSync( false ); diffLabel_->SetNeedsSync( false ); diffSlope_->SetNeedsSync( false ); diffInter_->SetNeedsSync( false ); diffCorrl_->SetNeedsSync( false ); # endif if (diffout_ != 0) { diffout_->AddDataSet( diffConst_ ); diffout_->AddDataSet( diffSlope_ ); diffout_->AddDataSet( diffInter_ ); diffout_->AddDataSet( diffCorrl_ ); diffout_->AddDataSet( diffLabel_ ); } Dimension Ddim( 1, 1, "Set" ); diffConst_->SetDim(Dimension::X, Ddim); diffLabel_->SetDim(Dimension::X, Ddim); diffSlope_->SetDim(Dimension::X, Ddim); diffInter_->SetDim(Dimension::X, Ddim); diffCorrl_->SetDim(Dimension::X, Ddim); } // Save master data set list, needed when printIndividual_ masterDSL_ = init.DslPtr(); mprintf(" DIFFUSION:\n"); mprintf("\tAtom Mask is [%s]\n", mask_.MaskString()); if (printIndividual_) mprintf("\tBoth average and individual diffusion will be calculated.\n"); else mprintf("\tOnly average diffusion will be calculated.\n"); mprintf("\tData set base name: %s\n", avg_x_->Meta().Name().c_str()); if (image_.UseImage()) mprintf("\tCorrections for imaging enabled.\n"); else mprintf("\tCorrections for imaging disabled.\n"); // If one file defined, assume all are. if (outputx_ != 0) { mprintf("\tOutput files:\n" "\t %s: (x) Mean square displacement(s) in the X direction (in Ang.^2).\n" "\t %s: (y) Mean square displacement(s) in the Y direction (in Ang.^2).\n" "\t %s: (z) Mean square displacement(s) in the Z direction (in Ang.^2).\n" "\t %s: (r) Overall mean square displacement(s) (in Ang.^2).\n" "\t %s: (a) Total distance travelled (in Ang.).\n", outputx_->DataFilename().full(), outputy_->DataFilename().full(), outputz_->DataFilename().full(), outputr_->DataFilename().full(), outputa_->DataFilename().full()); } mprintf("\tThe time between frames is %g ps.\n", time_); if (calcDiffConst_) { mprintf("\tCalculating diffusion constants by fitting slope to MSD vs time\n" "\t and multiplying by 10.0/2*N (where N is # of dimensions), units\n" "\t are 1x10^-5 cm^2/s.\n"); if (diffout_ != 0) mprintf("\tDiffusion constant output to '%s'\n", diffout_->DataFilename().full()); else mprintf("\tDiffusion constant output to STDOUT.\n"); } else mprintf("\tTo calculate diffusion constant from mean squared displacement plots,\n" "\t calculate the slope of MSD vs time and multiply by 10.0/2*N (where N\n" "\t is # of dimensions); this will give units of 1x10^-5 cm^2/s.\n"); return Action::OK; }