OpenMD 3.0
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
SelectionEvaluator.cpp
1/*
2 * Copyright (c) 2004-present, The University of Notre Dame. All rights
3 * reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
32 * research, please cite the appropriate papers when you publish your
33 * work. Good starting points are:
34 *
35 * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
36 * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
37 * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
38 * [4] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
39 * [5] Kuang & Gezelter, Mol. Phys., 110, 691-701 (2012).
40 * [6] Lamichhane, Gezelter & Newman, J. Chem. Phys. 141, 134109 (2014).
41 * [7] Lamichhane, Newman & Gezelter, J. Chem. Phys. 141, 134110 (2014).
42 * [8] Bhattarai, Newman & Gezelter, Phys. Rev. B 99, 094106 (2019).
43 */
44
45#include "selection/SelectionEvaluator.hpp"
46
47#include <any>
48#include <map>
49#include <stack>
50#include <string>
51#include <utility>
52
53#include "io/ifstrstream.hpp"
54#include "primitives/Atom.hpp"
58#include "types/FixedChargeAdapter.hpp"
59#include "types/FluctuatingChargeAdapter.hpp"
60
61namespace OpenMD {
62
63 SelectionEvaluator::SelectionEvaluator(SimInfo* si) :
64 info(si), nameFinder(info), distanceFinder(info), hullFinder(info),
65 alphaHullFinder(info), indexFinder(info), isLoaded_(false),
66 hasSurfaceArea_(false), hasVolume_(false) {
67 nObjects.push_back(info->getNGlobalAtoms() + info->getNGlobalRigidBodies());
68 nObjects.push_back(info->getNGlobalBonds());
69 nObjects.push_back(info->getNGlobalBends());
70 nObjects.push_back(info->getNGlobalTorsions());
71 nObjects.push_back(info->getNGlobalInversions());
72 nObjects.push_back(info->getNGlobalMolecules());
73 }
74
75 bool SelectionEvaluator::loadScript(const std::string& filename,
76 const std::string& script) {
77 clearDefinitionsAndLoadPredefined();
78 this->filename = filename;
79 this->script = script;
80 if (!compiler.compile(filename, script)) {
81 error = true;
82 errorMessage = compiler.getErrorMessage();
83
84 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
85 "SelectionCompiler Error: %s\n", errorMessage.c_str());
86 painCave.severity = OPENMD_ERROR;
87 painCave.isFatal = 1;
88 simError();
89 return false;
90 }
91
92 pc = 0;
93 aatoken = compiler.getAatokenCompiled();
94 linenumbers = compiler.getLineNumbers();
95 lineIndices = compiler.getLineIndices();
96
97 std::vector<std::vector<Token>>::const_iterator i;
98
99 isDynamic_ = false;
100 for (i = aatoken.begin(); i != aatoken.end(); ++i) {
101 if (containDynamicToken(*i)) {
102 isDynamic_ = true;
103 break;
104 }
105 }
106
107 isLoaded_ = true;
108 return true;
109 }
110
111 void SelectionEvaluator::clearState() {
112 error = false;
113 errorMessage = "";
114 }
115
116 bool SelectionEvaluator::loadScriptString(const std::string& script) {
117 clearState();
118 return loadScript("", script);
119 }
120
121 bool SelectionEvaluator::loadScriptFile(const std::string& filename) {
122 clearState();
123 return loadScriptFileInternal(filename);
124 }
125
126 bool SelectionEvaluator::loadScriptFileInternal(const std::string& filename) {
127 ifstrstream ifs(filename.c_str());
128 if (!ifs.is_open()) { return false; }
129
130 const int bufferSize = 65535;
131 char buffer[bufferSize];
132 std::string script;
133 while (ifs.getline(buffer, bufferSize)) {
134 script += buffer;
135 }
136 return loadScript(filename, script);
137 }
138
139 void SelectionEvaluator::instructionDispatchLoop(SelectionSet& bs) {
140 while (pc < aatoken.size()) {
141 statement = aatoken[pc++];
142 statementLength = statement.size();
143 Token token = statement[0];
144 switch (token.tok) {
145 case Token::define:
146 define();
147 break;
148 case Token::select:
149 select(bs);
150 break;
151 default:
152 unrecognizedCommand(token);
153 return;
154 }
155 }
156 }
157
158 void SelectionEvaluator::instructionDispatchLoop(SelectionSet& bs,
159 int frame) {
160 while (pc < aatoken.size()) {
161 statement = aatoken[pc++];
162 statementLength = statement.size();
163 Token token = statement[0];
164 switch (token.tok) {
165 case Token::define:
166 define();
167 break;
168 case Token::select:
169 select(bs, frame);
170 break;
171 default:
172 unrecognizedCommand(token);
173 return;
174 }
175 }
176 }
177
178 SelectionSet SelectionEvaluator::expression(const std::vector<Token>& code,
179 int pcStart) {
180 SelectionSet bs = createSelectionSets();
181 std::stack<SelectionSet> stack;
182 vector<int> bsSize = bs.size();
183
184 for (unsigned int pc = pcStart; pc < code.size(); ++pc) {
185 Token instruction = code[pc];
186
187 switch (instruction.tok) {
188 case Token::expressionBegin:
189 break;
190 case Token::expressionEnd:
191 break;
192 case Token::all:
193 bs = allInstruction();
194 stack.push(bs);
195 break;
196 case Token::none:
197 bs = createSelectionSets();
198 stack.push(bs);
199 break;
200 case Token::opOr:
201 bs = stack.top();
202 stack.pop();
203 stack.top() |= bs;
204 break;
205 case Token::opAnd:
206 bs = stack.top();
207 stack.pop();
208 stack.top() &= bs;
209 break;
210 case Token::opNot:
211 stack.top().flip();
212 break;
213 case Token::within:
214 withinInstruction(instruction, stack.top());
215 break;
216 case Token::alphahull:
217 stack.push(alphaHullInstruction(instruction));
218 break;
219 case Token::hull:
220 stack.push(hull());
221 break;
222 // case Token::selected:
223 // stack.push(getSelectionSet());
224 // break;
225 case Token::name:
226 stack.push(
227 nameInstruction(std::any_cast<std::string>(instruction.value)));
228 break;
229 case Token::index:
230 stack.push(indexInstruction(instruction.value));
231 break;
232 case Token::identifier:
233 stack.push(lookupValue(std::any_cast<std::string>(instruction.value)));
234 break;
235 case Token::opLT:
236 case Token::opLE:
237 case Token::opGE:
238 case Token::opGT:
239 case Token::opEQ:
240 case Token::opNE:
241 stack.push(comparatorInstruction(instruction));
242 break;
243 default:
244 unrecognizedExpression();
245 }
246 }
247 if (stack.size() != 1)
248 evalError("atom expression compiler error - stack over/underflow");
249
250 return stack.top();
251 }
252
253 SelectionSet SelectionEvaluator::expression(const std::vector<Token>& code,
254 int pcStart, int frame) {
255 SelectionSet bs = createSelectionSets();
256 std::stack<SelectionSet> stack;
257
258 for (unsigned int pc = pcStart; pc < code.size(); ++pc) {
259 Token instruction = code[pc];
260
261 switch (instruction.tok) {
262 case Token::expressionBegin:
263 break;
264 case Token::expressionEnd:
265 break;
266 case Token::all:
267 bs = allInstruction();
268 stack.push(bs);
269 break;
270 case Token::none:
271 bs = SelectionSet(nObjects);
272 stack.push(bs);
273 break;
274 case Token::opOr:
275 bs = stack.top();
276 stack.pop();
277 stack.top() |= bs;
278 break;
279 case Token::opAnd:
280 bs = stack.top();
281 stack.pop();
282 stack.top() &= bs;
283 break;
284 case Token::opNot:
285 stack.top().flip();
286 break;
287 case Token::within:
288 withinInstruction(instruction, stack.top(), frame);
289 break;
290 case Token::alphahull:
291 stack.push(alphaHullInstruction(instruction, frame));
292 break;
293 case Token::hull:
294 stack.push(hull(frame));
295 break;
296 // case Token::selected:
297 // stack.push(getSelectionSet());
298 // break;
299 case Token::name:
300 stack.push(
301 nameInstruction(std::any_cast<std::string>(instruction.value)));
302 break;
303 case Token::index:
304 stack.push(indexInstruction(instruction.value));
305 break;
306 case Token::identifier:
307 stack.push(lookupValue(std::any_cast<std::string>(instruction.value)));
308 break;
309 case Token::opLT:
310 case Token::opLE:
311 case Token::opGE:
312 case Token::opGT:
313 case Token::opEQ:
314 case Token::opNE:
315 stack.push(comparatorInstruction(instruction, frame));
316 break;
317 default:
318 unrecognizedExpression();
319 }
320 }
321 if (stack.size() != 1)
322 evalError("atom expression compiler error - stack over/underflow");
323
324 return stack.top();
325 }
326
327 SelectionSet SelectionEvaluator::comparatorInstruction(
328 const Token& instruction) {
329 int comparator = instruction.tok;
330 int property = instruction.intValue;
331 float comparisonValue = std::any_cast<float>(instruction.value);
332 SelectionSet bs = createSelectionSets();
333 bs.clearAll();
334
335 SimInfo::MoleculeIterator mi;
336 Molecule* mol;
337 Molecule::AtomIterator ai;
338 Atom* atom;
339 Molecule::RigidBodyIterator rbIter;
340 RigidBody* rb;
341
342 for (mol = info->beginMolecule(mi); mol != NULL;
343 mol = info->nextMolecule(mi)) {
344 compareProperty(mol, bs, property, comparator, comparisonValue);
345
346 for (atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) {
347 compareProperty(atom, bs, property, comparator, comparisonValue);
348 }
349
350 for (rb = mol->beginRigidBody(rbIter); rb != NULL;
351 rb = mol->nextRigidBody(rbIter)) {
352 compareProperty(rb, bs, property, comparator, comparisonValue);
353 }
354 }
355
356 return bs.parallelReduce();
357 }
358
359 SelectionSet SelectionEvaluator::comparatorInstruction(
360 const Token& instruction, int frame) {
361 int comparator = instruction.tok;
362 int property = instruction.intValue;
363 float comparisonValue = std::any_cast<float>(instruction.value);
364 SelectionSet bs = createSelectionSets();
365 bs.clearAll();
366
367 SimInfo::MoleculeIterator mi;
368 Molecule* mol;
369 Molecule::AtomIterator ai;
370 Atom* atom;
371 Molecule::RigidBodyIterator rbIter;
372 RigidBody* rb;
373
374 for (mol = info->beginMolecule(mi); mol != NULL;
375 mol = info->nextMolecule(mi)) {
376 compareProperty(mol, bs, property, comparator, comparisonValue, frame);
377
378 for (atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) {
379 compareProperty(atom, bs, property, comparator, comparisonValue, frame);
380 }
381
382 for (rb = mol->beginRigidBody(rbIter); rb != NULL;
383 rb = mol->nextRigidBody(rbIter)) {
384 compareProperty(rb, bs, property, comparator, comparisonValue, frame);
385 }
386 }
387
388 return bs.parallelReduce();
389 }
390
391 void SelectionEvaluator::compareProperty(StuntDouble* sd, SelectionSet& bs,
392 int property, int comparator,
393 float comparisonValue) {
394 RealType propertyValue = 0.0;
395 Vector3d pos;
396
397 switch (property) {
398 case Token::atomno:
399 if (sd->isAtom()) {
400 Atom* atom = static_cast<Atom*>(sd);
401 propertyValue = atom->getGlobalIndex();
402 }
403 break;
404 case Token::mass:
405 propertyValue = sd->getMass();
406 break;
407 case Token::charge:
408 if (sd->isAtom()) {
409 Atom* atom = static_cast<Atom*>(sd);
410 propertyValue = getCharge(atom);
411 } else if (sd->isRigidBody()) {
412 RigidBody* rb = static_cast<RigidBody*>(sd);
413 RigidBody::AtomIterator ai;
414 Atom* atom;
415 for (atom = rb->beginAtom(ai); atom != NULL; atom = rb->nextAtom(ai)) {
416 propertyValue += getCharge(atom);
417 }
418 }
419 break;
420 case Token::x:
421 propertyValue = sd->getPos().x();
422 break;
423 case Token::y:
424 propertyValue = sd->getPos().y();
425 break;
426 case Token::z:
427 propertyValue = sd->getPos().z();
428 break;
429 case Token::wrappedX:
430 pos = sd->getPos();
432 propertyValue = pos.x();
433 break;
434 case Token::wrappedY:
435 pos = sd->getPos();
437 propertyValue = pos.y();
438 break;
439 case Token::wrappedZ:
440 pos = sd->getPos();
442 propertyValue = pos.z();
443 break;
444 case Token::r:
445 propertyValue = sd->getPos().length();
446 break;
447 default:
448 unrecognizedAtomProperty(property);
449 }
450
451 bool match = false;
452 switch (comparator) {
453 case Token::opLT:
454 match = propertyValue < comparisonValue;
455 break;
456 case Token::opLE:
457 match = propertyValue <= comparisonValue;
458 break;
459 case Token::opGE:
460 match = propertyValue >= comparisonValue;
461 break;
462 case Token::opGT:
463 match = propertyValue > comparisonValue;
464 break;
465 case Token::opEQ:
466 match = fabs(propertyValue - comparisonValue) <= OpenMD::epsilon;
467 break;
468 case Token::opNE:
469 match = propertyValue != comparisonValue;
470 break;
471 }
472
473 if (match) bs.bitsets_[STUNTDOUBLE].setBitOn(sd->getGlobalIndex());
474 }
475
476 void SelectionEvaluator::compareProperty(Molecule* mol, SelectionSet& bs,
477 int property, int comparator,
478 float comparisonValue) {
479 RealType propertyValue = 0.0;
480 Vector3d pos;
481
482 switch (property) {
483 case Token::mass:
484 propertyValue = mol->getMass();
485 break;
486 case Token::charge: {
487 Molecule::AtomIterator ai;
488 Atom* atom;
489 for (atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) {
490 propertyValue += getCharge(atom);
491 }
492 } break;
493 case Token::x:
494 propertyValue = mol->getCom().x();
495 break;
496 case Token::y:
497 propertyValue = mol->getCom().y();
498 break;
499 case Token::z:
500 propertyValue = mol->getCom().z();
501 break;
502 case Token::wrappedX:
503 pos = mol->getCom();
505 propertyValue = pos.x();
506 break;
507 case Token::wrappedY:
508 pos = mol->getCom();
510 propertyValue = pos.y();
511 break;
512 case Token::wrappedZ:
513 pos = mol->getCom();
515 propertyValue = pos.z();
516 break;
517 case Token::r:
518 propertyValue = mol->getCom().length();
519 break;
520 default:
521 unrecognizedMoleculeProperty(property);
522 }
523
524 bool match = false;
525 switch (comparator) {
526 case Token::opLT:
527 match = propertyValue < comparisonValue;
528 break;
529 case Token::opLE:
530 match = propertyValue <= comparisonValue;
531 break;
532 case Token::opGE:
533 match = propertyValue >= comparisonValue;
534 break;
535 case Token::opGT:
536 match = propertyValue > comparisonValue;
537 break;
538 case Token::opEQ:
539 match = fabs(propertyValue - comparisonValue) <= OpenMD::epsilon;
540 break;
541 case Token::opNE:
542 match = propertyValue != comparisonValue;
543 break;
544 }
545
546 if (match) bs.bitsets_[MOLECULE].setBitOn(mol->getGlobalIndex());
547 }
548
549 void SelectionEvaluator::compareProperty(Molecule* mol, SelectionSet& bs,
550 int property, int comparator,
551 float comparisonValue, int frame) {
552 RealType propertyValue = 0.0;
553 Vector3d pos;
554 switch (property) {
555 case Token::mass:
556 propertyValue = mol->getMass();
557 break;
558 case Token::charge: {
559 Molecule::AtomIterator ai;
560 Atom* atom;
561 for (atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) {
562 propertyValue += getCharge(atom, frame);
563 }
564 } break;
565 case Token::x:
566 propertyValue = mol->getCom(frame).x();
567 break;
568 case Token::y:
569 propertyValue = mol->getCom(frame).y();
570 break;
571 case Token::z:
572 propertyValue = mol->getCom(frame).z();
573 break;
574 case Token::wrappedX:
575 pos = mol->getCom(frame);
576 info->getSnapshotManager()->getSnapshot(frame)->wrapVector(pos);
577 propertyValue = pos.x();
578 break;
579 case Token::wrappedY:
580 pos = mol->getCom(frame);
581 info->getSnapshotManager()->getSnapshot(frame)->wrapVector(pos);
582 propertyValue = pos.y();
583 break;
584 case Token::wrappedZ:
585 pos = mol->getCom(frame);
586 info->getSnapshotManager()->getSnapshot(frame)->wrapVector(pos);
587 propertyValue = pos.z();
588 break;
589
590 case Token::r:
591 propertyValue = mol->getCom(frame).length();
592 break;
593 default:
594 unrecognizedMoleculeProperty(property);
595 }
596
597 bool match = false;
598 switch (comparator) {
599 case Token::opLT:
600 match = propertyValue < comparisonValue;
601 break;
602 case Token::opLE:
603 match = propertyValue <= comparisonValue;
604 break;
605 case Token::opGE:
606 match = propertyValue >= comparisonValue;
607 break;
608 case Token::opGT:
609 match = propertyValue > comparisonValue;
610 break;
611 case Token::opEQ:
612 match = fabs(propertyValue - comparisonValue) <= OpenMD::epsilon;
613 break;
614 case Token::opNE:
615 match = propertyValue != comparisonValue;
616 break;
617 }
618 if (match) bs.bitsets_[MOLECULE].setBitOn(mol->getGlobalIndex());
619 }
620 void SelectionEvaluator::compareProperty(StuntDouble* sd, SelectionSet& bs,
621 int property, int comparator,
622 float comparisonValue, int frame) {
623 RealType propertyValue = 0.0;
624 Vector3d pos;
625 switch (property) {
626 case Token::atomno:
627 if (sd->isAtom()) {
628 Atom* atom = static_cast<Atom*>(sd);
629 propertyValue = atom->getGlobalIndex();
630 }
631 break;
632 case Token::mass:
633 propertyValue = sd->getMass();
634 break;
635 case Token::charge:
636 if (sd->isAtom()) {
637 Atom* atom = static_cast<Atom*>(sd);
638 propertyValue = getCharge(atom, frame);
639 } else if (sd->isRigidBody()) {
640 RigidBody* rb = static_cast<RigidBody*>(sd);
641 RigidBody::AtomIterator ai;
642 Atom* atom;
643 for (atom = rb->beginAtom(ai); atom != NULL; atom = rb->nextAtom(ai)) {
644 propertyValue += getCharge(atom, frame);
645 }
646 }
647 break;
648 case Token::x:
649 propertyValue = sd->getPos(frame).x();
650 break;
651 case Token::y:
652 propertyValue = sd->getPos(frame).y();
653 break;
654 case Token::z:
655 propertyValue = sd->getPos(frame).z();
656 break;
657 case Token::wrappedX:
658 pos = sd->getPos(frame);
659 info->getSnapshotManager()->getSnapshot(frame)->wrapVector(pos);
660 propertyValue = pos.x();
661 break;
662 case Token::wrappedY:
663 pos = sd->getPos(frame);
664 info->getSnapshotManager()->getSnapshot(frame)->wrapVector(pos);
665 propertyValue = pos.y();
666 break;
667 case Token::wrappedZ:
668 pos = sd->getPos(frame);
669 info->getSnapshotManager()->getSnapshot(frame)->wrapVector(pos);
670 propertyValue = pos.z();
671 break;
672
673 case Token::r:
674 propertyValue = sd->getPos(frame).length();
675 break;
676 default:
677 unrecognizedAtomProperty(property);
678 }
679
680 bool match = false;
681 switch (comparator) {
682 case Token::opLT:
683 match = propertyValue < comparisonValue;
684 break;
685 case Token::opLE:
686 match = propertyValue <= comparisonValue;
687 break;
688 case Token::opGE:
689 match = propertyValue >= comparisonValue;
690 break;
691 case Token::opGT:
692 match = propertyValue > comparisonValue;
693 break;
694 case Token::opEQ:
695 match = fabs(propertyValue - comparisonValue) <= OpenMD::epsilon;
696 break;
697 case Token::opNE:
698 match = propertyValue != comparisonValue;
699 break;
700 }
701 if (match) bs.bitsets_[STUNTDOUBLE].setBitOn(sd->getGlobalIndex());
702 }
703
704 void SelectionEvaluator::withinInstruction(const Token& instruction,
705 SelectionSet& bs) {
706 std::any withinSpec = instruction.value;
707 float distance(0.0);
708 if (withinSpec.type() == typeid(float)) {
709 distance = std::any_cast<float>(withinSpec);
710 } else if (withinSpec.type() == typeid(int)) {
711 distance = std::any_cast<int>(withinSpec);
712 } else {
713 evalError("casting error in withinInstruction");
714 bs.clearAll();
715 }
716
717 bs = distanceFinder.find(bs, distance);
718 }
719
720 void SelectionEvaluator::withinInstruction(const Token& instruction,
721 SelectionSet& bs, int frame) {
722 std::any withinSpec = instruction.value;
723 float distance(0.0);
724 if (withinSpec.type() == typeid(float)) {
725 distance = std::any_cast<float>(withinSpec);
726 } else if (withinSpec.type() == typeid(int)) {
727 distance = std::any_cast<int>(withinSpec);
728 } else {
729 evalError("casting error in withinInstruction");
730 bs.clearAll();
731 }
732
733 bs = distanceFinder.find(bs, distance, frame);
734 }
735
736 SelectionSet SelectionEvaluator::alphaHullInstruction(
737 const Token& instruction) {
738 SelectionSet bs = createSelectionSets();
739
740 std::any alphaSpec = instruction.value;
741 float alpha(0.0);
742 if (alphaSpec.type() == typeid(float)) {
743 alpha = std::any_cast<float>(alphaSpec);
744 } else if (alphaSpec.type() == typeid(int)) {
745 alpha = std::any_cast<int>(alphaSpec);
746 } else {
747 evalError("casting error in alphaHullInstruction");
748 bs.clearAll();
749 }
750
751 alphaHullFinder.setAlpha(alpha);
752 bs = alphaHullFinder.findHull();
753 surfaceArea_ = alphaHullFinder.getSurfaceArea();
754 hasSurfaceArea_ = true;
755 volume_ = alphaHullFinder.getVolume();
756 hasVolume_ = true;
757
758 return bs.parallelReduce();
759 }
760
761 SelectionSet SelectionEvaluator::alphaHullInstruction(
762 const Token& instruction, int frame) {
763 SelectionSet bs = createSelectionSets();
764
765 std::any alphaSpec = instruction.value;
766 float alpha(0.0);
767 if (alphaSpec.type() == typeid(float)) {
768 alpha = std::any_cast<float>(alphaSpec);
769 } else if (alphaSpec.type() == typeid(int)) {
770 alpha = std::any_cast<int>(alphaSpec);
771 } else {
772 evalError("casting error in alphaHullInstruction");
773 bs.clearAll();
774 }
775
776 alphaHullFinder.setAlpha(alpha);
777 bs = alphaHullFinder.findHull(frame);
778 surfaceArea_ = alphaHullFinder.getSurfaceArea();
779 hasSurfaceArea_ = true;
780 volume_ = alphaHullFinder.getVolume();
781 hasVolume_ = true;
782
783 return bs.parallelReduce();
784 }
785
786 void SelectionEvaluator::define() {
787 assert(statement.size() >= 3);
788
789 std::string variable = std::any_cast<std::string>(statement[1].value);
790
791 variables.insert(
792 VariablesType::value_type(variable, expression(statement, 2)));
793 }
794
795 /** @todo */
796 void SelectionEvaluator::predefine(const std::string& script) {
797 if (compiler.compile("#predefine", script)) {
798 std::vector<std::vector<Token>> aatoken = compiler.getAatokenCompiled();
799 if (aatoken.size() != 1) {
800 evalError("predefinition does not have exactly 1 command:" + script);
801 return;
802 }
803 std::vector<Token> statement = aatoken[0];
804 if (statement.size() > 2) {
805 int tok = statement[1].tok;
806 if (tok == Token::identifier ||
807 (tok & Token::predefinedset) == Token::predefinedset) {
808 std::string variable = std::any_cast<std::string>(statement[1].value);
809 variables.insert(VariablesType::value_type(variable, statement));
810
811 } else {
812 evalError("invalid variable name:" + script);
813 }
814 } else {
815 evalError("bad predefinition length:" + script);
816 }
817
818 } else {
819 evalError("predefined set compile error:" + script +
820 "\ncompile error:" + compiler.getErrorMessage());
821 }
822 }
823
824 void SelectionEvaluator::select(SelectionSet& bs) {
825 bs = expression(statement, 1);
826 }
827
828 void SelectionEvaluator::select(SelectionSet& bs, int frame) {
829 bs = expression(statement, 1, frame);
830 }
831
832 SelectionSet SelectionEvaluator::lookupValue(const std::string& variable) {
833 SelectionSet bs = createSelectionSets();
834 std::map<std::string, std::any>::iterator i = variables.find(variable);
835
836 if (i != variables.end()) {
837 if (i->second.type() == typeid(SelectionSet)) {
838 return std::any_cast<SelectionSet>(i->second);
839 } else if (i->second.type() == typeid(std::vector<Token>)) {
840 bs = expression(std::any_cast<std::vector<Token>>(i->second), 2);
841 i->second = bs; /**@todo fixme */
842 return bs.parallelReduce();
843 }
844 } else {
845 unrecognizedIdentifier(variable);
846 }
847
848 return bs.parallelReduce();
849 }
850
851 SelectionSet SelectionEvaluator::nameInstruction(const std::string& name) {
852 return nameFinder.match(name);
853 }
854
855 bool SelectionEvaluator::containDynamicToken(
856 const std::vector<Token>& tokens) {
857 std::vector<Token>::const_iterator i;
858 for (i = tokens.begin(); i != tokens.end(); ++i) {
859 if (i->tok & Token::dynamic) { return true; }
860 }
861
862 return false;
863 }
864
865 void SelectionEvaluator::clearDefinitionsAndLoadPredefined() {
866 variables.clear();
867 // load predefine
868 // predefine();
869 }
870
871 SelectionSet SelectionEvaluator::createSelectionSets() {
872 SelectionSet ss(nObjects);
873 return ss;
874 }
875
876 SelectionSet SelectionEvaluator::evaluate() {
877 SelectionSet bs = createSelectionSets();
878 if (isLoaded_) {
879 pc = 0;
880 instructionDispatchLoop(bs);
881 }
882 return bs.parallelReduce();
883 }
884
885 SelectionSet SelectionEvaluator::evaluate(int frame) {
886 SelectionSet bs = createSelectionSets();
887 if (isLoaded_) {
888 pc = 0;
889 instructionDispatchLoop(bs, frame);
890 }
891 return bs.parallelReduce();
892 }
893
894 SelectionSet SelectionEvaluator::indexInstruction(const std::any& value) {
895 SelectionSet bs = createSelectionSets();
896
897 if (value.type() == typeid(int)) {
898 int index = std::any_cast<int>(value);
899 if (index < 0 ||
900 index >= static_cast<int>(bs.bitsets_[STUNTDOUBLE].size())) {
901 invalidIndex(index);
902 } else {
903 bs = indexFinder.find(index);
904 }
905 } else if (value.type() == typeid(std::pair<int, int>)) {
906 std::pair<int, int> indexRange =
907 std::any_cast<std::pair<int, int>>(value);
908 assert(indexRange.first <= indexRange.second);
909 if (indexRange.first < 0 ||
910 indexRange.second >=
911 static_cast<int>(bs.bitsets_[STUNTDOUBLE].size())) {
912 invalidIndexRange(indexRange);
913 } else {
914 bs = indexFinder.find(indexRange.first, indexRange.second);
915 }
916 }
917
918 return bs.parallelReduce();
919 }
920
921 SelectionSet SelectionEvaluator::allInstruction() {
922 SelectionSet ss = createSelectionSets();
923
924 SimInfo::MoleculeIterator mi;
925 Molecule::AtomIterator ai;
926 Molecule::RigidBodyIterator rbIter;
927 Molecule::BondIterator bondIter;
928 Molecule::BendIterator bendIter;
929 Molecule::TorsionIterator torsionIter;
930 Molecule::InversionIterator inversionIter;
931
932 Molecule* mol;
933 Atom* atom;
934 RigidBody* rb;
935 Bond* bond;
936 Bend* bend;
937 Torsion* torsion;
938 Inversion* inversion;
939
940 // Doing the loop insures that we're actually on this processor.
941
942 for (mol = info->beginMolecule(mi); mol != NULL;
943 mol = info->nextMolecule(mi)) {
944 for (atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) {
945 ss.bitsets_[STUNTDOUBLE].setBitOn(atom->getGlobalIndex());
946 }
947 for (rb = mol->beginRigidBody(rbIter); rb != NULL;
948 rb = mol->nextRigidBody(rbIter)) {
949 ss.bitsets_[STUNTDOUBLE].setBitOn(rb->getGlobalIndex());
950 }
951 for (bond = mol->beginBond(bondIter); bond != NULL;
952 bond = mol->nextBond(bondIter)) {
953 ss.bitsets_[BOND].setBitOn(bond->getGlobalIndex());
954 }
955 for (bend = mol->beginBend(bendIter); bend != NULL;
956 bend = mol->nextBend(bendIter)) {
957 ss.bitsets_[BEND].setBitOn(bend->getGlobalIndex());
958 }
959 for (torsion = mol->beginTorsion(torsionIter); torsion != NULL;
960 torsion = mol->nextTorsion(torsionIter)) {
961 ss.bitsets_[TORSION].setBitOn(torsion->getGlobalIndex());
962 }
963 for (inversion = mol->beginInversion(inversionIter); inversion != NULL;
964 inversion = mol->nextInversion(inversionIter)) {
965 ss.bitsets_[INVERSION].setBitOn(inversion->getGlobalIndex());
966 }
967 ss.bitsets_[MOLECULE].setBitOn(mol->getGlobalIndex());
968 }
969
970 return ss;
971 }
972
973 SelectionSet SelectionEvaluator::hull() {
974 SelectionSet bs = createSelectionSets();
975
976 bs = hullFinder.findHull();
977 surfaceArea_ = hullFinder.getSurfaceArea();
978 hasSurfaceArea_ = true;
979 volume_ = hullFinder.getVolume();
980 hasVolume_ = true;
981
982 return bs.parallelReduce();
983 }
984
985 SelectionSet SelectionEvaluator::hull(int frame) {
986 SelectionSet bs = createSelectionSets();
987
988 bs = hullFinder.findHull(frame);
989
990 return bs.parallelReduce();
991 }
992
993 RealType SelectionEvaluator::getCharge(Atom* atom) {
994 RealType charge = 0.0;
995 AtomType* atomType = atom->getAtomType();
996
998 if (fca.isFixedCharge()) { charge = fca.getCharge(); }
999
1001 if (fqa.isFluctuatingCharge()) { charge += atom->getFlucQPos(); }
1002 return charge;
1003 }
1004
1005 RealType SelectionEvaluator::getCharge(Atom* atom, int frame) {
1006 RealType charge = 0.0;
1007 AtomType* atomType = atom->getAtomType();
1008
1009 FixedChargeAdapter fca = FixedChargeAdapter(atomType);
1010 if (fca.isFixedCharge()) { charge = fca.getCharge(); }
1011
1013 if (fqa.isFluctuatingCharge()) { charge += atom->getFlucQPos(frame); }
1014 return charge;
1015 }
1016} // namespace OpenMD
AtomType is what OpenMD looks to for unchanging data about an atom.
Definition AtomType.hpp:66
RealType getMass()
get total mass of this molecule
Definition Molecule.cpp:266
int getGlobalIndex()
Returns the global index of this molecule.
Definition Molecule.hpp:107
Vector3d getCom()
Returns the current center of mass position of this molecule.
Definition Molecule.cpp:298
std::vector< int > size() const
Returns the number of bits of space actually in use by this SelectionSet to represent bit values.
void clearAll()
Sets all of the bits in this SelectionSet to false.
void flip(std::vector< int > bitIndex)
Sets the bit at the specified index to to the complement of its current value.
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
Definition SimInfo.hpp:93
Molecule * beginMolecule(MoleculeIterator &i)
Returns the first molecule in this SimInfo and intialize the iterator.
Definition SimInfo.cpp:240
Molecule * nextMolecule(MoleculeIterator &i)
Returns the next avaliable Molecule based on the iterator.
Definition SimInfo.cpp:245
SnapshotManager * getSnapshotManager()
Returns the snapshot manager.
Definition SimInfo.hpp:248
void wrapVector(Vector3d &v)
Wrapping the vector according to periodic boundary condition.
Definition Snapshot.cpp:337
Snapshot * getCurrentSnapshot()
Returns the pointer of current snapshot.
"Don't move, or you're dead! Stand up! Captain, we've got them!"
RealType getMass()
Returns the mass of this stuntDouble.
Vector3d getPos()
Returns the current position of this stuntDouble.
bool isRigidBody()
Tests if this stuntDouble is a rigid body.
int getGlobalIndex()
Returns the global index of this stuntDouble.
bool isAtom()
Tests if this stuntDouble is an atom.
Real & z()
Returns reference of the third element of Vector3.
Definition Vector3.hpp:120
Real & x()
Returns reference of the first element of Vector3.
Definition Vector3.hpp:96
Real & y()
Returns reference of the second element of Vector3.
Definition Vector3.hpp:108
Real length()
Returns the length of this vector.
Definition Vector.hpp:393
ifstrstream class provides a stream interface to read data from files.
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
@ INVERSION
Inversions.
@ STUNTDOUBLE
StuntDoubles (Atoms & RigidBodies)
@ TORSION
Torsions.
@ BEND
Bends.
@ BOND
Bonds.
@ MOLECULE
Molecules.
Real distance(const DynamicVector< Real > &v1, const DynamicVector< Real > &v2)
Returns the distance between two DynamicVectors.