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 : ```plumed 53 : plumed driver --mc mcfile --plumed plumed.dat --ixyz traj.xyz 54 : ``` 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 : Notice, also, that you can print the masses and charges on separate files by using the `ONLY_MASSES` and `ONLY_CHARGES` flags 66 : as shown below: 67 : 68 : ```plumed 69 : DUMPMASSCHARGE FILE=mfile ATOMS=1-100 ONLY_MASSES 70 : DUMPMASSCHARGE FILE=qfile ATOMS=1-100 ONLY_CHARGES 71 : ``` 72 : 73 : */ 74 : //+ENDPLUMEDOC 75 : 76 : class DumpMassCharge: 77 : public ActionAtomistic, 78 : public ActionPilot { 79 : std::string file; 80 : bool first; 81 : bool second; 82 : bool print_masses; 83 : bool print_charges; 84 : public: 85 : explicit DumpMassCharge(const ActionOptions&); 86 : ~DumpMassCharge(); 87 : static void registerKeywords( Keywords& keys ); 88 0 : bool actionHasForces() override { 89 0 : return false; 90 : } 91 : void prepare() override; 92 94 : void calculate() override {} 93 94 : void apply() override {} 94 : void update() override; 95 : }; 96 : 97 : PLUMED_REGISTER_ACTION(DumpMassCharge,"DUMPMASSCHARGE") 98 : 99 16 : void DumpMassCharge::registerKeywords( Keywords& keys ) { 100 16 : Action::registerKeywords( keys ); 101 16 : ActionPilot::registerKeywords( keys ); 102 16 : ActionAtomistic::registerKeywords( keys ); 103 16 : keys.add("hidden","STRIDE","the frequency with which the atoms should be output"); 104 16 : keys.add("atoms", "ATOMS", "the atom indices whose charges and masses you would like to print out"); 105 16 : keys.add("compulsory", "FILE", "file on which to output charges and masses."); 106 16 : keys.addFlag("ONLY_MASSES",false,"Only output masses to file"); 107 16 : keys.addFlag("ONLY_CHARGES",false,"Only output charges to file"); 108 16 : } 109 : 110 14 : DumpMassCharge::DumpMassCharge(const ActionOptions&ao): 111 : Action(ao), 112 : ActionAtomistic(ao), 113 : ActionPilot(ao), 114 14 : first(true), 115 14 : second(true), 116 14 : print_masses(true), 117 14 : print_charges(true) { 118 : std::vector<AtomNumber> atoms; 119 28 : parse("FILE",file); 120 14 : if(file.length()==0) { 121 0 : error("name of output file was not specified"); 122 : } 123 14 : log.printf(" output written to file %s\n",file.c_str()); 124 : 125 28 : parseAtomList("ATOMS",atoms); 126 : 127 14 : if(atoms.size()==0) { 128 10 : std::vector<std::string> strvec(1); 129 : strvec[0]="@mdatoms"; 130 10 : interpretAtomList( strvec,atoms ); 131 10 : } 132 : 133 14 : bool only_masses = false; 134 14 : parseFlag("ONLY_MASSES",only_masses); 135 14 : if(only_masses) { 136 1 : print_charges = false; 137 1 : log.printf(" only masses will be written to file\n"); 138 : } 139 : 140 14 : bool only_charges = false; 141 14 : parseFlag("ONLY_CHARGES",only_charges); 142 14 : if(only_charges) { 143 1 : print_masses = false; 144 1 : log.printf(" only charges will be written to file\n"); 145 : } 146 : 147 : 148 14 : checkRead(); 149 : 150 14 : log.printf(" printing the following atoms:" ); 151 1224 : for(unsigned i=0; i<atoms.size(); ++i) { 152 1210 : log.printf(" %d",atoms[i].serial() ); 153 : } 154 14 : log.printf("\n"); 155 14 : requestAtoms(atoms); 156 : 157 14 : if(only_masses && only_charges) { 158 0 : plumed_merror("using both ONLY_MASSES and ONLY_CHARGES doesn't make sense"); 159 : } 160 : 161 14 : } 162 : 163 94 : void DumpMassCharge::prepare() { 164 94 : if(!first && second) { 165 14 : requestAtoms(std::vector<AtomNumber>()); 166 14 : second=false; 167 : } 168 94 : } 169 : 170 94 : void DumpMassCharge::update() { 171 94 : if(!first) { 172 80 : return; 173 : } 174 14 : first=false; 175 : 176 14 : OFile of; 177 14 : of.link(*this); 178 14 : of.open(file); 179 : 180 1224 : for(unsigned i=0; i<getNumberOfAtoms(); i++) { 181 1210 : int ii=getAbsoluteIndex(i).index(); 182 1210 : of.printField("index",ii); 183 1210 : if(print_masses) { 184 2204 : of.printField("mass",getMass(i)); 185 : } 186 1210 : if(print_charges) { 187 2204 : of.printField("charge",getCharge(i)); 188 : } 189 1210 : of.printField(); 190 : } 191 14 : } 192 : 193 28 : DumpMassCharge::~DumpMassCharge() { 194 28 : } 195 : 196 : 197 : } 198 : }