Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2015-2023 The plumed team 3 : (see the PEOPLE file at the root of the distribution for a list of names) 4 : 5 : See http://www.plumed.org for more information. 6 : 7 : This file is part of plumed, version 2. 8 : 9 : plumed is free software: you can redistribute it and/or modify 10 : it under the terms of the GNU Lesser General Public License as published by 11 : the Free Software Foundation, either version 3 of the License, or 12 : (at your option) any later version. 13 : 14 : plumed is distributed in the hope that it will be useful, 15 : but WITHOUT ANY WARRANTY; without even the implied warranty of 16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 : GNU Lesser General Public License for more details. 18 : 19 : You should have received a copy of the GNU Lesser General Public License 20 : along with plumed. If not, see <http://www.gnu.org/licenses/>. 21 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 22 : #include "core/ActionAtomistic.h" 23 : #include "core/ActionPilot.h" 24 : #include "core/ActionRegister.h" 25 : #include "tools/File.h" 26 : #include "core/PlumedMain.h" 27 : 28 : namespace PLMD { 29 : namespace generic { 30 : 31 : //+PLUMEDOC PRINTANALYSIS DUMPMASSCHARGE 32 : /* 33 : Dump masses and charges on a selected file. 34 : 35 : This command dumps a file that contains charges and masses of the atoms. The following 36 : example shows how it is used: 37 : 38 : ```plumed 39 : c1: COM ATOMS=1-10 40 : c2: COM ATOMS=11-20 41 : DUMPATOMS ATOMS=c1,c2 FILE=coms.xyz STRIDE=100 42 : 43 : DUMPMASSCHARGE FILE=mcfile 44 : ``` 45 : 46 : The DUMPMASSCHARGE command only outputs the masses and charges once in the simulation (during the first step). 47 : 48 : Output the masses and charges in this way is useful if you want to do some postprocessing that relies 49 : on knowing the masses and charges of atoms. To use the mcfile tht is output by the command above you would 50 : use the following driver command to read in the charges and masses from the mcfile. 51 : 52 : \verbatim 53 : plumed driver --mc mcfile --plumed plumed.dat --ixyz traj.xyz 54 : \endverbatim 55 : 56 : DUMPMASSCHARGE outputs the masses of all the atoms by default. However, if you want to write the masses and charges 57 : for a particular subset of the atoms you can use the `ATOMS` keyword as illustrated in the example input below: 58 : 59 : ```plumed 60 : solute_ions: GROUP ATOMS=1-121,200-2012 61 : DUMPATOMS FILE=traj.gro ATOMS=solute_ions STRIDE=100 62 : DUMPMASSCHARGE FILE=mcfile ATOMS=solute_ions 63 : ``` 64 : 65 : */ 66 : //+ENDPLUMEDOC 67 : 68 : class DumpMassCharge: 69 : public ActionAtomistic, 70 : public ActionPilot { 71 : std::string file; 72 : bool first; 73 : bool second; 74 : bool print_masses; 75 : bool print_charges; 76 : public: 77 : explicit DumpMassCharge(const ActionOptions&); 78 : ~DumpMassCharge(); 79 : static void registerKeywords( Keywords& keys ); 80 0 : bool actionHasForces() override { 81 0 : return false; 82 : } 83 : void prepare() override; 84 94 : void calculate() override {} 85 94 : void apply() override {} 86 : void update() override; 87 : }; 88 : 89 : PLUMED_REGISTER_ACTION(DumpMassCharge,"DUMPMASSCHARGE") 90 : 91 16 : void DumpMassCharge::registerKeywords( Keywords& keys ) { 92 16 : Action::registerKeywords( keys ); 93 16 : ActionPilot::registerKeywords( keys ); 94 16 : ActionAtomistic::registerKeywords( keys ); 95 16 : keys.add("compulsory","STRIDE","1","the frequency with which the atoms should be output"); 96 16 : keys.add("atoms", "ATOMS", "the atom indices whose charges and masses you would like to print out"); 97 16 : keys.add("compulsory", "FILE", "file on which to output charges and masses."); 98 16 : keys.addFlag("ONLY_MASSES",false,"Only output masses to file"); 99 16 : keys.addFlag("ONLY_CHARGES",false,"Only output charges to file"); 100 16 : } 101 : 102 14 : DumpMassCharge::DumpMassCharge(const ActionOptions&ao): 103 : Action(ao), 104 : ActionAtomistic(ao), 105 : ActionPilot(ao), 106 14 : first(true), 107 14 : second(true), 108 14 : print_masses(true), 109 14 : print_charges(true) { 110 : std::vector<AtomNumber> atoms; 111 28 : parse("FILE",file); 112 14 : if(file.length()==0) { 113 0 : error("name of output file was not specified"); 114 : } 115 14 : log.printf(" output written to file %s\n",file.c_str()); 116 : 117 28 : parseAtomList("ATOMS",atoms); 118 : 119 14 : if(atoms.size()==0) { 120 10 : std::vector<std::string> strvec(1); 121 : strvec[0]="@mdatoms"; 122 10 : interpretAtomList( strvec,atoms ); 123 10 : } 124 : 125 14 : bool only_masses = false; 126 14 : parseFlag("ONLY_MASSES",only_masses); 127 14 : if(only_masses) { 128 1 : print_charges = false; 129 1 : log.printf(" only masses will be written to file\n"); 130 : } 131 : 132 14 : bool only_charges = false; 133 14 : parseFlag("ONLY_CHARGES",only_charges); 134 14 : if(only_charges) { 135 1 : print_masses = false; 136 1 : log.printf(" only charges will be written to file\n"); 137 : } 138 : 139 : 140 14 : checkRead(); 141 : 142 14 : log.printf(" printing the following atoms:" ); 143 1224 : for(unsigned i=0; i<atoms.size(); ++i) { 144 1210 : log.printf(" %d",atoms[i].serial() ); 145 : } 146 14 : log.printf("\n"); 147 14 : requestAtoms(atoms); 148 : 149 14 : if(only_masses && only_charges) { 150 0 : plumed_merror("using both ONLY_MASSES and ONLY_CHARGES doesn't make sense"); 151 : } 152 : 153 14 : } 154 : 155 94 : void DumpMassCharge::prepare() { 156 94 : if(!first && second) { 157 14 : requestAtoms(std::vector<AtomNumber>()); 158 14 : second=false; 159 : } 160 94 : } 161 : 162 94 : void DumpMassCharge::update() { 163 94 : if(!first) { 164 80 : return; 165 : } 166 14 : first=false; 167 : 168 14 : OFile of; 169 14 : of.link(*this); 170 14 : of.open(file); 171 : 172 1224 : for(unsigned i=0; i<getNumberOfAtoms(); i++) { 173 1210 : int ii=getAbsoluteIndex(i).index(); 174 1210 : of.printField("index",ii); 175 1210 : if(print_masses) { 176 2204 : of.printField("mass",getMass(i)); 177 : } 178 1210 : if(print_charges) { 179 2204 : of.printField("charge",getCharge(i)); 180 : } 181 1210 : of.printField(); 182 : } 183 14 : } 184 : 185 28 : DumpMassCharge::~DumpMassCharge() { 186 28 : } 187 : 188 : 189 : } 190 : }