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 containing charges and masses.
36 : It does so only once in the simulation (at first step).
37 : File can be recycled in the \ref driver tool.
38 :
39 : Notice that masses and charges are only written once at the beginning
40 : of the simulation. In case no atom list is provided, charges and
41 : masses for all atoms are written.
42 :
43 : \par Examples
44 :
45 : You can add the DUMPMASSCHARGE action at the end of the plumed.dat
46 : file that you use during an MD simulations:
47 :
48 : \plumedfile
49 : c1: COM ATOMS=1-10
50 : c2: COM ATOMS=11-20
51 : DUMPATOMS ATOMS=c1,c2 FILE=coms.xyz STRIDE=100
52 :
53 : DUMPMASSCHARGE FILE=mcfile
54 : \endplumedfile
55 :
56 : In this way, you will be able to use the same masses while processing
57 : a trajectory from the \ref driver . To do so, you need to
58 : add the --mc flag on the driver command line, e.g.
59 : \verbatim
60 : plumed driver --mc mcfile --plumed plumed.dat --ixyz traj.xyz
61 : \endverbatim
62 :
63 : With the following input you can dump only the charges for a specific
64 : group:
65 :
66 : \plumedfile
67 : solute_ions: GROUP ATOMS=1-121,200-2012
68 : DUMPATOMS FILE=traj.gro ATOMS=solute_ions STRIDE=100
69 : DUMPMASSCHARGE FILE=mcfile ATOMS=solute_ions
70 : \endplumedfile
71 :
72 : */
73 : //+ENDPLUMEDOC
74 :
75 : class DumpMassCharge:
76 : public ActionAtomistic,
77 : public ActionPilot {
78 : std::string file;
79 : bool first;
80 : bool second;
81 : bool print_masses;
82 : bool print_charges;
83 : public:
84 : explicit DumpMassCharge(const ActionOptions&);
85 : ~DumpMassCharge();
86 : static void registerKeywords( Keywords& keys );
87 0 : bool actionHasForces() override {
88 0 : return false;
89 : }
90 : void prepare() override;
91 94 : void calculate() override {}
92 94 : void apply() override {}
93 : void update() override;
94 : };
95 :
96 : PLUMED_REGISTER_ACTION(DumpMassCharge,"DUMPMASSCHARGE")
97 :
98 18 : void DumpMassCharge::registerKeywords( Keywords& keys ) {
99 18 : Action::registerKeywords( keys );
100 18 : ActionPilot::registerKeywords( keys );
101 18 : ActionAtomistic::registerKeywords( keys );
102 36 : keys.add("compulsory","STRIDE","1","the frequency with which the atoms should be output");
103 36 : keys.add("atoms", "ATOMS", "the atom indices whose charges and masses you would like to print out");
104 36 : keys.add("compulsory", "FILE", "file on which to output charges and masses.");
105 36 : keys.addFlag("ONLY_MASSES",false,"Only output masses to file");
106 36 : keys.addFlag("ONLY_CHARGES",false,"Only output charges to file");
107 18 : }
108 :
109 14 : DumpMassCharge::DumpMassCharge(const ActionOptions&ao):
110 : Action(ao),
111 : ActionAtomistic(ao),
112 : ActionPilot(ao),
113 14 : first(true),
114 14 : second(true),
115 14 : print_masses(true),
116 14 : print_charges(true) {
117 : std::vector<AtomNumber> atoms;
118 28 : parse("FILE",file);
119 14 : if(file.length()==0) {
120 0 : error("name of output file was not specified");
121 : }
122 14 : log.printf(" output written to file %s\n",file.c_str());
123 :
124 28 : parseAtomList("ATOMS",atoms);
125 :
126 14 : if(atoms.size()==0) {
127 10 : std::vector<std::string> strvec(1);
128 : strvec[0]="@mdatoms";
129 10 : interpretAtomList( strvec,atoms );
130 10 : }
131 :
132 14 : bool only_masses = false;
133 14 : parseFlag("ONLY_MASSES",only_masses);
134 14 : if(only_masses) {
135 1 : print_charges = false;
136 1 : log.printf(" only masses will be written to file\n");
137 : }
138 :
139 14 : bool only_charges = false;
140 14 : parseFlag("ONLY_CHARGES",only_charges);
141 14 : if(only_charges) {
142 1 : print_masses = false;
143 1 : log.printf(" only charges will be written to file\n");
144 : }
145 :
146 :
147 14 : checkRead();
148 :
149 14 : log.printf(" printing the following atoms:" );
150 1224 : for(unsigned i=0; i<atoms.size(); ++i) {
151 1210 : log.printf(" %d",atoms[i].serial() );
152 : }
153 14 : log.printf("\n");
154 14 : requestAtoms(atoms);
155 :
156 14 : if(only_masses && only_charges) {
157 0 : plumed_merror("using both ONLY_MASSES and ONLY_CHARGES doesn't make sense");
158 : }
159 :
160 14 : }
161 :
162 94 : void DumpMassCharge::prepare() {
163 94 : if(!first && second) {
164 14 : requestAtoms(std::vector<AtomNumber>());
165 14 : second=false;
166 : }
167 94 : }
168 :
169 94 : void DumpMassCharge::update() {
170 94 : if(!first) {
171 80 : return;
172 : }
173 14 : first=false;
174 :
175 14 : OFile of;
176 14 : of.link(*this);
177 14 : of.open(file);
178 :
179 1224 : for(unsigned i=0; i<getNumberOfAtoms(); i++) {
180 1210 : int ii=getAbsoluteIndex(i).index();
181 1210 : of.printField("index",ii);
182 1210 : if(print_masses) {
183 2204 : of.printField("mass",getMass(i));
184 : }
185 1210 : if(print_charges) {
186 2204 : of.printField("charge",getCharge(i));
187 : }
188 1210 : of.printField();
189 : }
190 14 : }
191 :
192 28 : DumpMassCharge::~DumpMassCharge() {
193 28 : }
194 :
195 :
196 : }
197 : }
|