# | Line 6 | Line 6 | |
---|---|---|
6 | * redistribute this software in source and binary code form, provided | |
7 | * that the following conditions are met: | |
8 | * | |
9 | < | * 1. Acknowledgement of the program authors must be made in any |
10 | < | * publication of scientific results based in part on use of the |
11 | < | * program. An acceptable form of acknowledgement is citation of |
12 | < | * the article in which the program was described (Matthew |
13 | < | * A. Meineke, Charles F. Vardeman II, Teng Lin, Christopher |
14 | < | * J. Fennell and J. Daniel Gezelter, "OOPSE: An Object-Oriented |
15 | < | * Parallel Simulation Engine for Molecular Dynamics," |
16 | < | * J. Comput. Chem. 26, pp. 252-271 (2005)) |
17 | < | * |
18 | < | * 2. Redistributions of source code must retain the above copyright |
9 | > | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. | |
11 | * | |
12 | < | * 3. Redistributions in binary form must reproduce the above copyright |
12 | > | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the | |
15 | * distribution. | |
# | Line 37 | Line 28 | |
28 | * arising out of the use of or inability to use software, even if the | |
29 | * University of Notre Dame has been advised of the possibility of | |
30 | * such damages. | |
31 | + | * |
32 | + | * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your |
33 | + | * research, please cite the appropriate papers when you publish your |
34 | + | * work. Good starting points are: |
35 | + | * |
36 | + | * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005). |
37 | + | * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006). |
38 | + | * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 24107 (2008). |
39 | + | * [4] Vardeman & Gezelter, in progress (2009). |
40 | */ | |
41 | ||
42 | #include <stack> | |
# | Line 45 | Line 45 | |
45 | #include "primitives/DirectionalAtom.hpp" | |
46 | #include "primitives/RigidBody.hpp" | |
47 | #include "primitives/Molecule.hpp" | |
48 | + | #include "io/basic_ifstrstream.hpp" |
49 | ||
50 | < | namespace oopse { |
50 | > | namespace OpenMD { |
51 | ||
52 | ||
53 | SelectionEvaluator::SelectionEvaluator(SimInfo* si) | |
54 | < | : info(si), nameFinder(info), distanceFinder(info), indexFinder(info), isLoaded_(false){ |
55 | < | |
56 | < | nStuntDouble = info->getNGlobalAtoms() + info->getNRigidBodies(); |
54 | > | : info(si), nameFinder(info), distanceFinder(info), indexFinder(info), |
55 | > | isLoaded_(false){ |
56 | > | nStuntDouble = info->getNGlobalAtoms() + info->getNGlobalRigidBodies(); |
57 | } | |
58 | ||
59 | < | bool SelectionEvaluator::loadScript(const std::string& filename, const std::string& script) { |
59 | > | bool SelectionEvaluator::loadScript(const std::string& filename, |
60 | > | const std::string& script) { |
61 | clearDefinitionsAndLoadPredefined(); | |
62 | this->filename = filename; | |
63 | this->script = script; | |
64 | if (! compiler.compile(filename, script)) { | |
65 | error = true; | |
66 | errorMessage = compiler.getErrorMessage(); | |
67 | < | std::cerr << "SelectionCompiler Error: " << errorMessage << std::endl; |
67 | > | |
68 | > | sprintf( painCave.errMsg, |
69 | > | "SelectionCompiler Error: %s\n", errorMessage.c_str()); |
70 | > | painCave.severity = OPENMD_ERROR; |
71 | > | painCave.isFatal = 1; |
72 | > | simError(); |
73 | return false; | |
74 | } | |
75 | ||
# | Line 100 | Line 107 | namespace oopse { | |
107 | return loadScriptFileInternal(filename); | |
108 | } | |
109 | ||
110 | < | bool SelectionEvaluator::loadScriptFileInternal(const std::string & filename) { |
111 | < | std::ifstream ifs(filename.c_str()); |
110 | > | bool SelectionEvaluator::loadScriptFileInternal(const std::string & filename) { |
111 | > | ifstrstream ifs(filename.c_str()); |
112 | if (!ifs.is_open()) { | |
113 | return false; | |
114 | } | |
115 | < | |
115 | > | |
116 | const int bufferSize = 65535; | |
117 | char buffer[bufferSize]; | |
118 | std::string script; | |
# | Line 114 | Line 121 | namespace oopse { | |
121 | } | |
122 | return loadScript(filename, script); | |
123 | } | |
124 | < | |
125 | < | void SelectionEvaluator::instructionDispatchLoop(OOPSEBitSet& bs){ |
124 | > | |
125 | > | void SelectionEvaluator::instructionDispatchLoop(OpenMDBitSet& bs){ |
126 | ||
127 | while ( pc < aatoken.size()) { | |
128 | statement = aatoken[pc++]; | |
# | Line 136 | Line 143 | namespace oopse { | |
143 | ||
144 | } | |
145 | ||
146 | < | OOPSEBitSet SelectionEvaluator::expression(const std::vector<Token>& code, int pcStart) { |
147 | < | OOPSEBitSet bs; |
148 | < | std::stack<OOPSEBitSet> stack; |
149 | < | |
146 | > | OpenMDBitSet SelectionEvaluator::expression(const std::vector<Token>& code, |
147 | > | int pcStart) { |
148 | > | OpenMDBitSet bs; |
149 | > | std::stack<OpenMDBitSet> stack; |
150 | > | |
151 | for (int pc = pcStart; pc < code.size(); ++pc) { | |
152 | Token instruction = code[pc]; | |
153 | ||
# | Line 149 | Line 157 | namespace oopse { | |
157 | case Token::expressionEnd: | |
158 | break; | |
159 | case Token::all: | |
160 | < | bs = OOPSEBitSet(nStuntDouble); |
160 | > | bs = OpenMDBitSet(nStuntDouble); |
161 | bs.setAll(); | |
162 | stack.push(bs); | |
163 | break; | |
164 | case Token::none: | |
165 | < | bs = OOPSEBitSet(nStuntDouble); |
165 | > | bs = OpenMDBitSet(nStuntDouble); |
166 | stack.push(bs); | |
167 | break; | |
168 | case Token::opOr: | |
# | Line 171 | Line 179 | namespace oopse { | |
179 | stack.top().flip(); | |
180 | break; | |
181 | case Token::within: | |
174 | – | |
182 | withinInstruction(instruction, stack.top()); | |
183 | break; | |
184 | //case Token::selected: | |
# | Line 206 | Line 213 | namespace oopse { | |
213 | ||
214 | ||
215 | ||
216 | < | OOPSEBitSet SelectionEvaluator::comparatorInstruction(const Token& instruction) { |
216 | > | OpenMDBitSet SelectionEvaluator::comparatorInstruction(const Token& instruction) { |
217 | int comparator = instruction.tok; | |
218 | int property = instruction.intValue; | |
219 | float comparisonValue = boost::any_cast<float>(instruction.value); | |
220 | float propertyValue; | |
221 | < | OOPSEBitSet bs(nStuntDouble); |
221 | > | OpenMDBitSet bs(nStuntDouble); |
222 | bs.clearAll(); | |
223 | ||
224 | SimInfo::MoleculeIterator mi; | |
# | Line 220 | Line 227 | namespace oopse { | |
227 | Atom* atom; | |
228 | Molecule::RigidBodyIterator rbIter; | |
229 | RigidBody* rb; | |
223 | – | |
224 | – | for (mol = info->beginMolecule(mi); mol != NULL; mol = info->nextMolecule(mi)) { |
230 | ||
231 | + | for (mol = info->beginMolecule(mi); mol != NULL; |
232 | + | mol = info->nextMolecule(mi)) { |
233 | + | |
234 | for(atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) { | |
235 | compareProperty(atom, bs, property, comparator, comparisonValue); | |
236 | } | |
237 | < | |
238 | < | for (rb = mol->beginRigidBody(rbIter); rb != NULL; rb = mol->nextRigidBody(rbIter)) { |
239 | < | compareProperty(rb, bs, property, comparator, comparisonValue); |
240 | < | } |
237 | > | |
238 | > | for (rb = mol->beginRigidBody(rbIter); rb != NULL; |
239 | > | rb = mol->nextRigidBody(rbIter)) { |
240 | > | compareProperty(rb, bs, property, comparator, comparisonValue); |
241 | > | } |
242 | } | |
243 | ||
244 | return bs; | |
245 | } | |
246 | ||
247 | < | void SelectionEvaluator::compareProperty(StuntDouble* sd, OOPSEBitSet& bs, int property, int comparator, float comparisonValue) { |
247 | > | void SelectionEvaluator::compareProperty(StuntDouble* sd, OpenMDBitSet& bs, |
248 | > | int property, int comparator, |
249 | > | float comparisonValue) { |
250 | RealType propertyValue = 0.0; | |
251 | switch (property) { | |
252 | case Token::mass: | |
# | Line 254 | Line 265 | namespace oopse { | |
265 | } | |
266 | } | |
267 | break; | |
268 | + | case Token::x: |
269 | + | propertyValue = sd->getPos().x(); |
270 | + | break; |
271 | + | case Token::y: |
272 | + | propertyValue = sd->getPos().y(); |
273 | + | break; |
274 | + | case Token::z: |
275 | + | propertyValue = sd->getPos().z(); |
276 | + | break; |
277 | default: | |
278 | unrecognizedAtomProperty(property); | |
279 | } | |
# | Line 281 | Line 301 | namespace oopse { | |
301 | } | |
302 | if (match) | |
303 | bs.setBitOn(sd->getGlobalIndex()); | |
304 | < | |
304 | > | |
305 | } | |
306 | ||
307 | < | void SelectionEvaluator::withinInstruction(const Token& instruction, OOPSEBitSet& bs){ |
307 | > | void SelectionEvaluator::withinInstruction(const Token& instruction, |
308 | > | OpenMDBitSet& bs){ |
309 | ||
310 | boost::any withinSpec = instruction.value; | |
311 | float distance; | |
# | Line 299 | Line 320 | namespace oopse { | |
320 | ||
321 | bs = distanceFinder.find(bs, distance); | |
322 | } | |
323 | < | |
323 | > | |
324 | void SelectionEvaluator::define() { | |
325 | assert(statement.size() >= 3); | |
326 | < | |
326 | > | |
327 | std::string variable = boost::any_cast<std::string>(statement[1].value); | |
328 | < | |
329 | < | variables.insert(VariablesType::value_type(variable, expression(statement, 2))); |
328 | > | |
329 | > | variables.insert(VariablesType::value_type(variable, |
330 | > | expression(statement, 2))); |
331 | } | |
332 | + | |
333 | ||
311 | – | |
334 | /** @todo */ | |
335 | void SelectionEvaluator::predefine(const std::string& script) { | |
336 | < | |
336 | > | |
337 | if (compiler.compile("#predefine", script)) { | |
338 | std::vector<std::vector<Token> > aatoken = compiler.getAatokenCompiled(); | |
339 | if (aatoken.size() != 1) { | |
# | Line 322 | Line 344 | namespace oopse { | |
344 | std::vector<Token> statement = aatoken[0]; | |
345 | if (statement.size() > 2) { | |
346 | int tok = statement[1].tok; | |
347 | < | if (tok == Token::identifier || (tok & Token::predefinedset) == Token::predefinedset) { |
347 | > | if (tok == Token::identifier || |
348 | > | (tok & Token::predefinedset) == Token::predefinedset) { |
349 | std::string variable = boost::any_cast<std::string>(statement[1].value); | |
350 | variables.insert(VariablesType::value_type(variable, statement)); | |
351 | < | |
351 | > | |
352 | } else { | |
353 | evalError("invalid variable name:" + script); | |
354 | } | |
355 | }else { | |
356 | evalError("bad predefinition length:" + script); | |
357 | < | } |
335 | < | |
357 | > | } |
358 | ||
359 | } else { | |
360 | evalError("predefined set compile error:" + script + | |
361 | "\ncompile error:" + compiler.getErrorMessage()); | |
362 | } | |
341 | – | |
363 | } | |
364 | ||
365 | < | void SelectionEvaluator::select(OOPSEBitSet& bs){ |
365 | > | void SelectionEvaluator::select(OpenMDBitSet& bs){ |
366 | bs = expression(statement, 1); | |
367 | } | |
368 | < | |
369 | < | OOPSEBitSet SelectionEvaluator::lookupValue(const std::string& variable){ |
370 | < | |
371 | < | OOPSEBitSet bs(nStuntDouble); |
368 | > | |
369 | > | OpenMDBitSet SelectionEvaluator::lookupValue(const std::string& variable){ |
370 | > | |
371 | > | OpenMDBitSet bs(nStuntDouble); |
372 | std::map<std::string, boost::any>::iterator i = variables.find(variable); | |
373 | ||
374 | if (i != variables.end()) { | |
375 | < | if (i->second.type() == typeid(OOPSEBitSet)) { |
376 | < | return boost::any_cast<OOPSEBitSet>(i->second); |
375 | > | if (i->second.type() == typeid(OpenMDBitSet)) { |
376 | > | return boost::any_cast<OpenMDBitSet>(i->second); |
377 | } else if (i->second.type() == typeid(std::vector<Token>)){ | |
378 | bs = expression(boost::any_cast<std::vector<Token> >(i->second), 2); | |
379 | i->second = bs; /**@todo fixme */ | |
# | Line 361 | Line 382 | namespace oopse { | |
382 | } else { | |
383 | unrecognizedIdentifier(variable); | |
384 | } | |
385 | < | |
385 | > | |
386 | return bs; | |
387 | } | |
388 | < | |
389 | < | OOPSEBitSet SelectionEvaluator::nameInstruction(const std::string& name){ |
390 | < | |
370 | < | return nameFinder.match(name); |
371 | < | |
388 | > | |
389 | > | OpenMDBitSet SelectionEvaluator::nameInstruction(const std::string& name){ |
390 | > | return nameFinder.match(name); |
391 | } | |
392 | ||
393 | bool SelectionEvaluator::containDynamicToken(const std::vector<Token>& tokens){ | |
# | Line 378 | Line 397 | namespace oopse { | |
397 | return true; | |
398 | } | |
399 | } | |
400 | < | |
400 | > | |
401 | return false; | |
402 | } | |
403 | ||
# | Line 388 | Line 407 | namespace oopse { | |
407 | //predefine(); | |
408 | } | |
409 | ||
410 | < | OOPSEBitSet SelectionEvaluator::evaluate() { |
411 | < | OOPSEBitSet bs(nStuntDouble); |
410 | > | OpenMDBitSet SelectionEvaluator::evaluate() { |
411 | > | OpenMDBitSet bs(nStuntDouble); |
412 | if (isLoaded_) { | |
413 | pc = 0; | |
414 | instructionDispatchLoop(bs); | |
# | Line 398 | Line 417 | namespace oopse { | |
417 | return bs; | |
418 | } | |
419 | ||
420 | < | OOPSEBitSet SelectionEvaluator::indexInstruction(const boost::any& value) { |
421 | < | OOPSEBitSet bs(nStuntDouble); |
420 | > | OpenMDBitSet SelectionEvaluator::indexInstruction(const boost::any& value) { |
421 | > | OpenMDBitSet bs(nStuntDouble); |
422 | ||
423 | if (value.type() == typeid(int)) { | |
424 | int index = boost::any_cast<int>(value); | |
# | Line 436 | Line 455 | namespace oopse { | |
455 | } else { | |
456 | sprintf( painCave.errMsg, | |
457 | "Can not cast GenericData to DoubleGenericData\n"); | |
458 | < | painCave.severity = OOPSE_ERROR; |
458 | > | painCave.severity = OPENMD_ERROR; |
459 | painCave.isFatal = 1; | |
460 | simError(); | |
461 | } |
– | Removed lines |
+ | Added lines |
< | Changed lines |
> | Changed lines |