ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/selection/SelectionEvaluator.cpp
Revision: 3520
Committed: Mon Sep 7 16:31:51 2009 UTC (15 years, 9 months ago) by cli2
File size: 13337 byte(s)
Log Message:
Added new restraint infrastructure
Added MolecularRestraints
Added ObjectRestraints
Added RestraintStamp
Updated thermodynamic integration to use ObjectRestraints
Added Quaternion mathematics for twist swing decompositions
Significantly updated RestWriter and RestReader to use dump-like files
Added selections for x, y, and z coordinates of atoms
Removed monolithic Restraints class
Fixed a few bugs in gradients of Euler angles in DirectionalAtom and RigidBody
Added some rotational capabilities to prinicpalAxisCalculator

File Contents

# User Rev Content
1 tim 1961 /*
2     * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3     *
4     * The University of Notre Dame grants you ("Licensee") a
5     * non-exclusive, royalty free, license to use, modify and
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
19     * notice, this list of conditions and the following disclaimer.
20     *
21     * 3. Redistributions in binary form must reproduce the above copyright
22     * notice, this list of conditions and the following disclaimer in the
23     * documentation and/or other materials provided with the
24     * distribution.
25     *
26     * This software is provided "AS IS," without a warranty of any
27     * kind. All express or implied conditions, representations and
28     * warranties, including any implied warranty of merchantability,
29     * fitness for a particular purpose or non-infringement, are hereby
30     * excluded. The University of Notre Dame and its licensors shall not
31     * be liable for any damages suffered by licensee as a result of
32     * using, modifying or distributing the software or its
33     * derivatives. In no event will the University of Notre Dame or its
34     * licensors be liable for any lost revenue, profit or data, or for
35     * direct, indirect, special, consequential, incidental or punitive
36     * damages, however caused and regardless of the theory of liability,
37     * arising out of the use of or inability to use software, even if the
38     * University of Notre Dame has been advised of the possibility of
39     * such damages.
40     */
41    
42 tim 1967 #include <stack>
43 tim 1961 #include "selection/SelectionEvaluator.hpp"
44 tim 1967 #include "primitives/Atom.hpp"
45     #include "primitives/DirectionalAtom.hpp"
46     #include "primitives/RigidBody.hpp"
47     #include "primitives/Molecule.hpp"
48    
49 tim 1961 namespace oopse {
50    
51    
52 gezelter 2204 SelectionEvaluator::SelectionEvaluator(SimInfo* si)
53 tim 2097 : info(si), nameFinder(info), distanceFinder(info), indexFinder(info), isLoaded_(false){
54    
55 gezelter 2204 nStuntDouble = info->getNGlobalAtoms() + info->getNRigidBodies();
56     }
57 tim 1967
58 gezelter 2204 bool SelectionEvaluator::loadScript(const std::string& filename, const std::string& script) {
59 tim 1972 clearDefinitionsAndLoadPredefined();
60 tim 1962 this->filename = filename;
61     this->script = script;
62     if (! compiler.compile(filename, script)) {
63 gezelter 2204 error = true;
64     errorMessage = compiler.getErrorMessage();
65     std::cerr << "SelectionCompiler Error: " << errorMessage << std::endl;
66     return false;
67 tim 1962 }
68    
69     pc = 0;
70     aatoken = compiler.getAatokenCompiled();
71     linenumbers = compiler.getLineNumbers();
72     lineIndices = compiler.getLineIndices();
73 tim 1972
74     std::vector<std::vector<Token> >::const_iterator i;
75    
76     isDynamic_ = false;
77     for (i = aatoken.begin(); i != aatoken.end(); ++i) {
78 gezelter 2204 if (containDynamicToken(*i)) {
79     isDynamic_ = true;
80     break;
81     }
82 tim 1972 }
83    
84     isLoaded_ = true;
85 tim 1962 return true;
86 gezelter 2204 }
87 tim 1962
88 gezelter 2204 void SelectionEvaluator::clearState() {
89 tim 1962 error = false;
90 tim 1965 errorMessage = "";
91 gezelter 2204 }
92 tim 1962
93 gezelter 2204 bool SelectionEvaluator::loadScriptString(const std::string& script) {
94 tim 1962 clearState();
95 tim 1965 return loadScript("", script);
96 gezelter 2204 }
97 tim 1962
98 gezelter 2204 bool SelectionEvaluator::loadScriptFile(const std::string& filename) {
99 tim 1962 clearState();
100     return loadScriptFileInternal(filename);
101 gezelter 2204 }
102 tim 1962
103 gezelter 2204 bool SelectionEvaluator::loadScriptFileInternal(const std::string & filename) {
104     std::ifstream ifs(filename.c_str());
105 tim 1972 if (!ifs.is_open()) {
106 gezelter 2204 return false;
107 tim 1972 }
108    
109     const int bufferSize = 65535;
110     char buffer[bufferSize];
111     std::string script;
112     while(ifs.getline(buffer, bufferSize)) {
113 gezelter 2204 script += buffer;
114 tim 1972 }
115     return loadScript(filename, script);
116 gezelter 2204 }
117 tim 1966
118 tim 2469 void SelectionEvaluator::instructionDispatchLoop(OOPSEBitSet& bs){
119 tim 1972
120 tim 1965 while ( pc < aatoken.size()) {
121 gezelter 2204 statement = aatoken[pc++];
122     statementLength = statement.size();
123     Token token = statement[0];
124     switch (token.tok) {
125     case Token::define:
126     define();
127     break;
128     case Token::select:
129     select(bs);
130     break;
131     default:
132     unrecognizedCommand(token);
133     return;
134     }
135 tim 1962 }
136 tim 1972
137 gezelter 2204 }
138 tim 1962
139 tim 2469 OOPSEBitSet SelectionEvaluator::expression(const std::vector<Token>& code, int pcStart) {
140     OOPSEBitSet bs;
141     std::stack<OOPSEBitSet> stack;
142 tim 1967
143 tim 1972 for (int pc = pcStart; pc < code.size(); ++pc) {
144 tim 1962 Token instruction = code[pc];
145 tim 1966
146 tim 1962 switch (instruction.tok) {
147 tim 1965 case Token::expressionBegin:
148 tim 1962 break;
149 tim 1965 case Token::expressionEnd:
150 tim 1966 break;
151 tim 1965 case Token::all:
152 tim 2469 bs = OOPSEBitSet(nStuntDouble);
153 tim 1967 bs.setAll();
154     stack.push(bs);
155 tim 1962 break;
156 tim 1965 case Token::none:
157 tim 2469 bs = OOPSEBitSet(nStuntDouble);
158 tim 1967 stack.push(bs);
159 tim 1962 break;
160 tim 1965 case Token::opOr:
161 tim 1967 bs = stack.top();
162     stack.pop();
163     stack.top() |= bs;
164 tim 1962 break;
165 tim 1965 case Token::opAnd:
166 tim 1967 bs = stack.top();
167     stack.pop();
168     stack.top() &= bs;
169 tim 1962 break;
170 tim 1965 case Token::opNot:
171 tim 1967 stack.top().flip();
172 tim 1962 break;
173 tim 1965 case Token::within:
174 tim 1967
175     withinInstruction(instruction, stack.top());
176 tim 1962 break;
177 gezelter 2204 //case Token::selected:
178     // stack.push(getSelectionSet());
179     // break;
180 tim 1965 case Token::name:
181 tim 1967 stack.push(nameInstruction(boost::any_cast<std::string>(instruction.value)));
182 tim 1962 break;
183 tim 1979 case Token::index:
184     stack.push(indexInstruction(instruction.value));
185 tim 1965 break;
186     case Token::identifier:
187 tim 1967 stack.push(lookupValue(boost::any_cast<std::string>(instruction.value)));
188 tim 1965 break;
189     case Token::opLT:
190     case Token::opLE:
191     case Token::opGE:
192     case Token::opGT:
193     case Token::opEQ:
194     case Token::opNE:
195 tim 1967 stack.push(comparatorInstruction(instruction));
196 tim 1962 break;
197     default:
198     unrecognizedExpression();
199     }
200     }
201 tim 1967 if (stack.size() != 1)
202 tim 1962 evalError("atom expression compiler error - stack over/underflow");
203 tim 1967
204     return stack.top();
205 tim 1962 }
206    
207    
208    
209 tim 2469 OOPSEBitSet SelectionEvaluator::comparatorInstruction(const Token& instruction) {
210 tim 1962 int comparator = instruction.tok;
211     int property = instruction.intValue;
212 tim 1967 float comparisonValue = boost::any_cast<float>(instruction.value);
213     float propertyValue;
214 tim 2469 OOPSEBitSet bs(nStuntDouble);
215 tim 1979 bs.clearAll();
216 tim 1967
217     SimInfo::MoleculeIterator mi;
218     Molecule* mol;
219     Molecule::AtomIterator ai;
220     Atom* atom;
221     Molecule::RigidBodyIterator rbIter;
222     RigidBody* rb;
223    
224     for (mol = info->beginMolecule(mi); mol != NULL; mol = info->nextMolecule(mi)) {
225 tim 1965
226 gezelter 2204 for(atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) {
227     compareProperty(atom, bs, property, comparator, comparisonValue);
228     }
229 tim 1967
230 gezelter 2204 for (rb = mol->beginRigidBody(rbIter); rb != NULL; rb = mol->nextRigidBody(rbIter)) {
231     compareProperty(rb, bs, property, comparator, comparisonValue);
232     }
233 tim 1962 }
234    
235 tim 1967 return bs;
236 gezelter 2204 }
237 tim 1962
238 tim 2469 void SelectionEvaluator::compareProperty(StuntDouble* sd, OOPSEBitSet& bs, int property, int comparator, float comparisonValue) {
239 tim 2759 RealType propertyValue = 0.0;
240 gezelter 2204 switch (property) {
241     case Token::mass:
242     propertyValue = sd->getMass();
243     break;
244     case Token::charge:
245     if (sd->isAtom()){
246     Atom* atom = static_cast<Atom*>(sd);
247     propertyValue = getCharge(atom);
248     } else if (sd->isRigidBody()) {
249     RigidBody* rb = static_cast<RigidBody*>(sd);
250     RigidBody::AtomIterator ai;
251     Atom* atom;
252     for (atom = rb->beginAtom(ai); atom != NULL; atom = rb->nextAtom(ai)) {
253     propertyValue+= getCharge(atom);
254     }
255     }
256     break;
257 cli2 3520 case Token::x:
258     propertyValue = sd->getPos().x();
259     break;
260     case Token::y:
261     propertyValue = sd->getPos().y();
262     break;
263     case Token::z:
264     propertyValue = sd->getPos().z();
265     break;
266 gezelter 2204 default:
267     unrecognizedAtomProperty(property);
268     }
269 tim 1967
270 gezelter 2204 bool match = false;
271     switch (comparator) {
272     case Token::opLT:
273     match = propertyValue < comparisonValue;
274     break;
275     case Token::opLE:
276     match = propertyValue <= comparisonValue;
277     break;
278     case Token::opGE:
279     match = propertyValue >= comparisonValue;
280     break;
281     case Token::opGT:
282     match = propertyValue > comparisonValue;
283     break;
284     case Token::opEQ:
285     match = propertyValue == comparisonValue;
286     break;
287     case Token::opNE:
288     match = propertyValue != comparisonValue;
289     break;
290     }
291     if (match)
292     bs.setBitOn(sd->getGlobalIndex());
293 tim 1967
294 gezelter 2204 }
295 tim 1967
296 tim 2469 void SelectionEvaluator::withinInstruction(const Token& instruction, OOPSEBitSet& bs){
297 tim 1979
298 tim 1965 boost::any withinSpec = instruction.value;
299 tim 1979 float distance;
300 tim 1966 if (withinSpec.type() == typeid(float)){
301 gezelter 2204 distance = boost::any_cast<float>(withinSpec);
302 tim 1979 } else if (withinSpec.type() == typeid(int)) {
303 gezelter 2204 distance = boost::any_cast<int>(withinSpec);
304 tim 1979 } else {
305 gezelter 2204 evalError("casting error in withinInstruction");
306     bs.clearAll();
307 tim 1962 }
308 tim 1966
309 tim 1979 bs = distanceFinder.find(bs, distance);
310 gezelter 2204 }
311 tim 1962
312 gezelter 2204 void SelectionEvaluator::define() {
313 tim 1966 assert(statement.size() >= 3);
314    
315     std::string variable = boost::any_cast<std::string>(statement[1].value);
316 tim 1967
317 tim 2035 variables.insert(VariablesType::value_type(variable, expression(statement, 2)));
318 gezelter 2204 }
319 tim 1962
320 tim 1967
321 gezelter 2204 /** @todo */
322     void SelectionEvaluator::predefine(const std::string& script) {
323 tim 1962
324 tim 1966 if (compiler.compile("#predefine", script)) {
325 gezelter 2204 std::vector<std::vector<Token> > aatoken = compiler.getAatokenCompiled();
326     if (aatoken.size() != 1) {
327     evalError("predefinition does not have exactly 1 command:"
328     + script);
329     return;
330     }
331     std::vector<Token> statement = aatoken[0];
332     if (statement.size() > 2) {
333     int tok = statement[1].tok;
334     if (tok == Token::identifier || (tok & Token::predefinedset) == Token::predefinedset) {
335     std::string variable = boost::any_cast<std::string>(statement[1].value);
336     variables.insert(VariablesType::value_type(variable, statement));
337 tim 1966
338 gezelter 2204 } else {
339     evalError("invalid variable name:" + script);
340     }
341     }else {
342     evalError("bad predefinition length:" + script);
343     }
344 tim 1966
345    
346     } else {
347 gezelter 2204 evalError("predefined set compile error:" + script +
348     "\ncompile error:" + compiler.getErrorMessage());
349 tim 1966 }
350    
351 gezelter 2204 }
352 tim 1966
353 tim 2469 void SelectionEvaluator::select(OOPSEBitSet& bs){
354 tim 1972 bs = expression(statement, 1);
355 gezelter 2204 }
356 tim 1966
357 tim 2469 OOPSEBitSet SelectionEvaluator::lookupValue(const std::string& variable){
358 tim 1966
359 tim 2469 OOPSEBitSet bs(nStuntDouble);
360 tim 1966 std::map<std::string, boost::any>::iterator i = variables.find(variable);
361 tim 1979
362 tim 1966 if (i != variables.end()) {
363 tim 2469 if (i->second.type() == typeid(OOPSEBitSet)) {
364     return boost::any_cast<OOPSEBitSet>(i->second);
365 gezelter 2204 } else if (i->second.type() == typeid(std::vector<Token>)){
366     bs = expression(boost::any_cast<std::vector<Token> >(i->second), 2);
367     i->second = bs; /**@todo fixme */
368     return bs;
369     }
370 tim 1967 } else {
371 gezelter 2204 unrecognizedIdentifier(variable);
372 tim 1966 }
373 tim 1979
374     return bs;
375 gezelter 2204 }
376 tim 1966
377 tim 2469 OOPSEBitSet SelectionEvaluator::nameInstruction(const std::string& name){
378 tim 1967
379 tim 1979 return nameFinder.match(name);
380 tim 1972
381 gezelter 2204 }
382 tim 1967
383 gezelter 2204 bool SelectionEvaluator::containDynamicToken(const std::vector<Token>& tokens){
384 tim 1972 std::vector<Token>::const_iterator i;
385     for (i = tokens.begin(); i != tokens.end(); ++i) {
386 gezelter 2204 if (i->tok & Token::dynamic) {
387     return true;
388     }
389 tim 1972 }
390 tim 1967
391 tim 1972 return false;
392 gezelter 2204 }
393 tim 1972
394 gezelter 2204 void SelectionEvaluator::clearDefinitionsAndLoadPredefined() {
395 tim 1972 variables.clear();
396     //load predefine
397     //predefine();
398 gezelter 2204 }
399 tim 1972
400 tim 2469 OOPSEBitSet SelectionEvaluator::evaluate() {
401     OOPSEBitSet bs(nStuntDouble);
402 tim 1972 if (isLoaded_) {
403 gezelter 2204 pc = 0;
404     instructionDispatchLoop(bs);
405 tim 1972 }
406    
407     return bs;
408 gezelter 2204 }
409 tim 1979
410 tim 2469 OOPSEBitSet SelectionEvaluator::indexInstruction(const boost::any& value) {
411     OOPSEBitSet bs(nStuntDouble);
412 tim 1979
413     if (value.type() == typeid(int)) {
414 gezelter 2204 int index = boost::any_cast<int>(value);
415     if (index < 0 || index >= bs.size()) {
416     invalidIndex(index);
417     } else {
418     bs = indexFinder.find(index);
419     }
420 tim 1979 } else if (value.type() == typeid(std::pair<int, int>)) {
421 gezelter 2204 std::pair<int, int> indexRange= boost::any_cast<std::pair<int, int> >(value);
422     assert(indexRange.first <= indexRange.second);
423     if (indexRange.first < 0 || indexRange.second >= bs.size()) {
424     invalidIndexRange(indexRange);
425     }else {
426     bs = indexFinder.find(indexRange.first, indexRange.second);
427     }
428 tim 1979 }
429    
430     return bs;
431 gezelter 2204 }
432 tim 1979
433 tim 2116
434 tim 2759 RealType SelectionEvaluator::getCharge(Atom* atom) {
435     RealType charge =0.0;
436 tim 2116 AtomType* atomType = atom->getAtomType();
437     if (atomType->isCharge()) {
438 gezelter 2204 GenericData* data = atomType->getPropertyByName("Charge");
439     if (data != NULL) {
440     DoubleGenericData* doubleData= dynamic_cast<DoubleGenericData*>(data);
441 tim 2116
442 gezelter 2204 if (doubleData != NULL) {
443     charge = doubleData->getData();
444 tim 2116
445 gezelter 2204 } else {
446     sprintf( painCave.errMsg,
447     "Can not cast GenericData to DoubleGenericData\n");
448     painCave.severity = OOPSE_ERROR;
449     painCave.isFatal = 1;
450     simError();
451     }
452     }
453 tim 2116 }
454    
455     return charge;
456 gezelter 2204 }
457 tim 2116
458     }