ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-3.0/src/brains/SimCreator.cpp
Revision: 1725
Committed: Wed Nov 10 22:01:06 2004 UTC (19 years, 10 months ago) by tim
File size: 10375 byte(s)
Log Message:
another painful day
(1) SimCreator, SimInfo, mpiSimulation
(2) DumpReader, DumpWriter (InitializeFrom File will be removed)
(3) ForceField (at least LJ) and BondType, BendType, TorsionType
(4)Integrator
(5)oopse.cpp
(6)visitors & Dump2XYZ
(7)SimpleBuilder
(8)Constraint & ZConstraint

File Contents

# User Rev Content
1 tim 1703 /*
2     * Copyright (C) 2000-2004 Object Oriented Parallel Simulation Engine (OOPSE) project
3     *
4     * Contact: oopse@oopse.org
5     *
6     * This program is free software; you can redistribute it and/or
7     * modify it under the terms of the GNU Lesser General Public License
8     * as published by the Free Software Foundation; either version 2.1
9     * of the License, or (at your option) any later version.
10     * All we ask is that proper credit is given for our work, which includes
11     * - but is not limited to - adding the above copyright notice to the beginning
12     * of your source code files, and to any copyright notice that you may distribute
13     * with programs based on this work.
14     *
15     * This program is distributed in the hope that it will be useful,
16     * but WITHOUT ANY WARRANTY; without even the implied warranty of
17     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18     * GNU Lesser General Public License for more details.
19     *
20     * You should have received a copy of the GNU Lesser General Public License
21     * along with this program; if not, write to the Free Software
22     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23     *
24     */
25    
26 tim 1725 /**
27     * @file SimCreator.cpp
28     * @author tlin
29     * @date 11/03/2004
30     * @time 13:51am
31     * @version 1.0
32     */
33    
34     #include "brains/SimCreator.hpp"
35 tim 1703 namespace oopse {
36    
37 tim 1712 void SimSetup::parseFile(char* mdfile, MakeStamps* stamps, Globals* globals){
38     #ifdef IS_MPI
39     if (worldRank == 0){
40     #endif // is_mpi
41    
42    
43     globals->initalize();
44     set_interface_stamps(stamps, globals);
45    
46     #ifdef IS_MPI
47     mpiEventInit();
48     #endif
49    
50     yacc_BASS(mdfile);
51    
52     #ifdef IS_MPI
53     throwMPIEvent(NULL);
54     }
55     else{
56     set_interface_stamps(stamps, globals);
57     mpiEventInit();
58     MPIcheckPoint();
59     mpiEventLoop();
60     }
61     #endif
62    
63 tim 1703 }
64    
65 tim 1712
66 tim 1719 SimInfo* SimCreator::createSim(const std::string& mdfile) {
67     MakeStamps* stamps = new MakeStamps();
68 tim 1712
69     Globals* globals = new Globals();
70    
71     //parse meta-data file
72     parseFile(mdfile, stamps, globals);
73    
74     //create the force field
75 tim 1725 ForceFiled* ff = ForceFieldFactory::getInstance()->createObject(globals->getForceField());
76 tim 1712
77 tim 1719 //create SimInfo
78     SimInfo* info = new SimInfo();
79     info->setGlobals(globals);
80     info->setForceField(ff);
81    
82     //extract the molecule stamps and add them into SimInfo
83     compList(stamps, info);
84 tim 1712
85 tim 1719 //gather parameters (SimCreator only retrieves the parameters which will be used to create
86     // the simulation)
87     gatherParameters(info);
88 tim 1712
89     //divide the molecules and determine the global index of molecules
90 tim 1719
91 tim 1712 //create the molecules
92 tim 1719 createMolecules(info);
93 tim 1712
94 tim 1725 //set the global index of atoms, rigidbodies and cutoffgroups (only need to be set once, the
95     //global index will never change again). Local indices of atoms and rigidbodies are already set by
96     //MoleculeCreator class which actually delegates the responsibility to LocalIndexManager.
97     setGlobalIndices(info);
98    
99 tim 1712 //allocate memory for DataStorage(circular reference, need to break it)
100 tim 1719 info->setSnapshotManager(new SimSnapshotManager(info);
101 tim 1712
102 tim 1725 //load initial coordinates, some extra information are pushed into SimInfo's property map ( such as
103     //eta, chi for NPT integrator)
104 tim 1719 DumpReader reader(info->getInitFilename());
105     int nframes = reader->getNframes();
106    
107     if (nframes > 0) {
108     reader.readFrame(info, nframes - 1);
109     } else {
110     //invalid initial coordinate file
111    
112     }
113    
114 tim 1712
115     //initialize fortran
116 tim 1719
117     return info;
118 tim 1712 }
119    
120 tim 1725 void SimCreator::gatherParameters(SimInfo* info) {
121     //model->addProperty(new StringGenericData("Ensemble", globals->getForceFiled()));
122     //model->addProperty(new DoubleGenericData("dt"), globals->getDt());
123    
124     //setup seed for random number generator
125     int seedValue;
126     Globals* globals = info->getGlobals();
127    
128     if (globals->haveSeed()){
129     seedValue = globals->getSeed();
130    
131     if(seedValue / 1000000000 == 0){
132     sprintf(painCave.errMsg,
133     "Seed for sprng library should contain at least 9 digits\n"
134     "OOPSE will generate a seed for user\n");
135     painCave.isFatal = 0;
136     simError();
137    
138     //using seed generated by system instead of invalid seed set by user
139     #ifndef IS_MPI
140     seedValue = make_sprng_seed();
141     #else
142     if (worldRank == 0){
143     seedValue = make_sprng_seed();
144     }
145     MPI_Bcast(&seedValue, 1, MPI_INT, 0, MPI_COMM_WORLD);
146     #endif
147     } //end if (seedValue /1000000000 == 0)
148     } else{
149    
150     #ifndef IS_MPI
151     seedValue = make_sprng_seed();
152     #else
153     if (worldRank == 0){
154     seedValue = make_sprng_seed();
155     }
156     MPI_Bcast(&seedValue, 1, MPI_INT, 0, MPI_COMM_WORLD);
157     #endif
158     }//end of globals->haveSeed()
159     info->setSeed(seedValue);
160    
161     //
162     std::string prefix;
163     #ifdef IS_MPI
164     if (worldRank == 0){
165     #endif // is_mpi
166    
167     if(globals->haveFinalConfig()) {
168     prefix = getPrefix(globals->getFinalConfig());
169     } else {
170     prefix = getPrefix(mdfile_);
171     }
172    
173     info->setFinalConfFileName(prefix + ".eor");
174     info->setDumpFileName(prefix + ".dump");
175     info->setStatFileName(prefix + ".stat");
176    
177     #ifdef IS_MPI
178     }
179     #endif
180    
181    
182    
183 tim 1712 }
184    
185     #ifdef IS_MPI
186 tim 1713 void SimCreator::mpiMolDivide(){
187    
188     mpiSim = new mpiSimulation(info);
189 tim 1712
190 tim 1713 mpiSim->divideLabor();
191 tim 1712
192     }
193 tim 1713 #endif
194 tim 1712
195 tim 1719 Molecule* SimCreator::createMolecules(SimInfo* info) {
196 tim 1725 MoleculeCreator molCreator;
197     int stampId;
198 tim 1713
199    
200 tim 1725 for (int i = 0; i < info->getNGlobalMolecules(); i++){
201     if (info->getMolToProc(i) == worldRank){
202 tim 1713
203 tim 1725 stampId = info->getMoleculeStampId(i);
204     Molecule* mol = molCreator.createMolecule(info->getForceField(),
205     info->getMoleculeStamp(stampId), stampId, i);
206 tim 1719
207     info->addMolecule(mol);
208     }
209     }
210    
211 tim 1713 }
212    
213 tim 1719
214     void SimSetup::compList(MakeStamps* stamps,SimInfo* info) {
215     int i;
216     char* id;
217     MoleculeStamp* currentStamp;
218     Component* the_components = info->getGlobals()->getComponents();
219     int n_components = info->getGlobals()->getNComponents();
220    
221     if (!globals->haveNMol()){
222     // we don't have the total number of molecules, so we assume it is
223     // given in each component
224    
225     for (i = 0; i < n_components; i++){
226     if (!the_components[i]->haveNMol()){
227     // we have a problem
228     sprintf(painCave.errMsg,
229     "SimSetup Error. No global NMol or component NMol given.\n"
230     "\tCannot calculate the number of atoms.\n");
231     painCave.isFatal = 1;
232     simError();
233     }
234    
235     id = the_components[i]->getType();
236     currentStamp = stamps->extractMolStamp(id);
237     if (currentStamp == NULL){
238     sprintf(painCave.errMsg,
239     "SimSetup error: Component \"%s\" was not found in the "
240     "list of declared molecules\n",
241     id);
242     painCave.isFatal = 1;
243     simError();
244     }
245    
246 tim 1725 info->addMoleculeStamp(currentStamp, the_components[i]->getNMol);
247 tim 1719
248     } //end for (i = 0; i < n_components; i++)
249    
250     } else{
251     sprintf(painCave.errMsg,
252     "SimSetup error.\n"
253     "\tSorry, the ability to specify total"
254     " nMols and then give molfractions in the components\n"
255     "\tis not currently supported."
256     " Please give nMol in the components.\n");
257     painCave.isFatal = 1;
258     simError();
259     }
260    
261     #ifdef IS_MPI
262     strcpy(checkPointMsg, "Component stamps successfully extracted\n");
263     MPIcheckPoint();
264     #endif // is_mpi
265     }
266    
267 tim 1725 void SimCreator::setGlobalIndices(SimInfo* info) {
268     typename SimInfo::MoleculeIterator mi;
269     typename Molecule::AtomIterator ai;
270     typename Molecule::RigidBodyIterator ri;
271     typename Molecule::CutoffGroupIterator ci;
272     Molecule* mol;
273     Atom* atom;
274     RigidBody* rb;
275     CutoffGroup* cg;
276     int beginAtomIndex;
277     int beginRigidBodyIndex;
278     int beginCutoffGroupIndex;
279 tim 1719
280 tim 1725 #ifdef IS_MPI
281     beginAtomIndex = 0;
282     beginRigidBodyIndex = 0;
283     beginCutoffGroupIndex = 0;
284     #else
285     int nproc;
286     int myNode;
287    
288     myNode = worldRank;
289     MPI_Comm_size(MPI_COMM_WORLD, &nproc);
290    
291     std::vector<int> tmpAtomsInProc(nproc, 0);
292     std::vector<int> tmpRigidBodiesInProc(nproc, 0);
293     std::vector<int> tmpCutoffGroupsInProc(nproc, 0);
294     std::vector<int> NumAtomsInProc(nproc, 0);
295     std::vector<int> NumRigidBodiesInProc(nproc, 0);
296     std::vector<int> NumCutoffGroupsInProc(nproc, 0);
297    
298     tmpAtomInProc[myNode] = info->getNAtoms();
299     tmpRigidBodiesInProc[myNode] = info->getNRigidBodiess();
300     tmpCutoffGroupsInProc[myNode] = info->getNCutoffGroupss();
301    
302     //do MPI_ALLREDUCE to exchange the total number of atoms, rigidbodies and cutoff groups
303     MPI_Allreduce(&tmpAtomsInProc[0], &NumAtomsInProc[0], nproc, MPI_INT,MPI_SUM, MPI_COMM_WORLD);
304     MPI_Allreduce(&tmpRigidBodiesInProc[0], &NumRigidBodiesInProc[0], nproc, MPI_INT,MPI_SUM, MPI_COMM_WORLD);
305     MPI_Allreduce(&tmpCutoffGroupsInProc[0], &NumCutoffGroupsInProc[0], nproc, MPI_INT,MPI_SUM, MPI_COMM_WORLD);
306    
307     beginAtomIndex = 0;
308     beginRigidBodyIndex = 0;
309     beginCutoffGroupIndex = 0;
310    
311     for (int i = 0; i < nproc; i++) {
312     beginAtomIndex += NumAtomsInProc[i];
313     beginRigidBodyIndex += NumRigidBodiesInProc[i];
314     beginCutoffGroupIndex += NumCutoffGroupsInProc[i];
315     }
316    
317     #endif
318    
319     for (mol = info->beginMolecule(mi); mol != NULL; mol = info->nextMolecule(mi)) {
320    
321     //local index(index in DataStorge) of atom is important
322     for (atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) {
323     atom->setGlobalIndex(beginAtomIndex++);
324     }
325    
326     for (rb = mol->beginRigidBody(ri); rb != NULL; rb = mol->nextRigidBody(ri)) {
327     rb->setGlobalIndex(beginRigidBodyIndex++);
328     }
329    
330     //local index of cutoff group is trivial, it only depends on the order of travesing
331     for (cg = mol->beginCutoffGroup(ci); cg != NULL; cg = mol->nextCutoffGroup(ci)) {
332     cg->setGlobalIndex(beginCutoffGroupIndex++);
333     }
334    
335     }
336     }
337    
338 tim 1703 } //end namespace oopse