/* * RepeatBoxAction.cpp * * Created on: May 12, 2010 * Author: heber */ #include "Helpers/MemDebug.hpp" #include "Actions/WorldAction/RepeatBoxAction.hpp" #include "Actions/ActionRegistry.hpp" #include "atom.hpp" #include "Helpers/Log.hpp" #include "molecule.hpp" #include "LinearAlgebra/Vector.hpp" #include "LinearAlgebra/Matrix.hpp" #include "Helpers/Verbose.hpp" #include "World.hpp" #include "Box.hpp" #include #include using namespace std; #include "UIElements/UIFactory.hpp" #include "UIElements/Dialog.hpp" #include "Actions/ValueStorage.hpp" #include "Descriptors/MoleculeDescriptor.hpp" #include "Descriptors/MoleculePtrDescriptor.hpp" const char WorldRepeatBoxAction::NAME[] = "repeat-box"; WorldRepeatBoxAction::WorldRepeatBoxAction() : Action(NAME) {} WorldRepeatBoxAction::~WorldRepeatBoxAction() {} void WorldRepeatBox(Vector &Repeater) { ValueStorage::getInstance().setCurrentValue(WorldRepeatBoxAction::NAME, Repeater); ActionRegistry::getInstance().getActionByName(WorldRepeatBoxAction::NAME)->call(Action::NonInteractive); }; Dialog * WorldRepeatBoxAction::fillDialog(Dialog *dialog) { ASSERT(dialog,"No Dialog given when filling action dialog"); dialog->queryVector(NAME, false, ValueStorage::getInstance().getDescription(NAME)); return dialog; } Action::state_ptr WorldRepeatBoxAction::performCall() { Vector Repeater; int count; const element ** Elements; molecule *mol = NULL; int j = 0; atom *Walker = NULL; MoleculeListClass *molecules = World::getInstance().getMolecules(); ValueStorage::getInstance().queryCurrentValue(NAME, Repeater); vector AllMolecules; if (mol != NULL) { DoLog(0) && (Log() << Verbose(0) << "Using molecule " << mol->name << "." << endl); AllMolecules = World::getInstance().getAllMolecules(MoleculeByPtr(mol)); } else { DoLog(0) && (Log() << Verbose(0) << "Using all molecules." << endl); AllMolecules = World::getInstance().getAllMolecules(); } (cout << "Repeating box " << Repeater << " times for (x,y,z) axis." << endl); Matrix M = World::getInstance().getDomain().getM(); Matrix newM = M; Vector x,y; int n[NDIM]; Matrix repMat; for (int axis = 0; axis < NDIM; axis++) { Repeater[axis] = floor(Repeater[axis]); if (Repeater[axis] < 1) { DoeLog(1) && (eLog()<< Verbose(1) << "Repetition factor must be greater than 1!" << endl); Repeater[axis] = 1; } repMat.at(axis,axis) = Repeater[axis]; } newM *= repMat; World::getInstance().setDomain(newM); molecule *newmol = NULL; Vector ** vectors = NULL; for (n[0] = 0; n[0] < Repeater[0]; n[0]++) { y[0] = n[0]; for (n[1] = 0; n[1] < Repeater[1]; n[1]++) { y[1] = n[1]; for (n[2] = 0; n[2] < Repeater[2]; n[2]++) { y[2] = n[2]; if ((n[0] == 0) && (n[1] == 0) && (n[2] == 0)) continue; for (vector::iterator MolRunner = AllMolecules.begin(); MolRunner != AllMolecules.end(); ++MolRunner) { mol = *MolRunner; DoLog(1) && (Log() << Verbose(1) << "Current mol is " << mol->name << "." << endl); count = mol->getAtomCount(); // is changed becausing of adding, thus has to be stored away beforehand if (count != 0) { // if there is more than none Elements = new const element *[count]; vectors = new Vector *[count]; j = 0; for(molecule::iterator AtomRunner = mol->begin(); AtomRunner != mol->end(); ++AtomRunner) { Elements[j] = (*AtomRunner)->type; vectors[j] = &(*AtomRunner)->x; j++; } if (count != j) DoeLog(1) && (eLog()<< Verbose(1) << "AtomCount " << count << " is not equal to number of atoms in molecule " << j << "!" << endl); x = y; x *= M; newmol = World::getInstance().createMolecule(); molecules->insert(newmol); for (int k=count;k--;) { // go through every atom of the original cell Walker = World::getInstance().createAtom(); // create a new body Walker->x = (*vectors[k]) + x; Walker->type = Elements[k]; // insert original element cout << "new atom is " << *Walker << endl; newmol->AddAtom(Walker); // and add to the molecule (which increments ElementsInMolecule, AtomCount, ...) } // free memory delete[](Elements); delete[](vectors); } else { DoLog(1) && (Log() << Verbose(1) << "\t ... is empty." << endl); } } } } } return Action::success; } Action::state_ptr WorldRepeatBoxAction::performUndo(Action::state_ptr _state) { // ParserLoadXyzState *state = assert_cast(_state.get()); return Action::failure; // string newName = state->mol->getName(); // state->mol->setName(state->lastName); // // return Action::state_ptr(new ParserLoadXyzState(state->mol,newName)); } Action::state_ptr WorldRepeatBoxAction::performRedo(Action::state_ptr _state){ return Action::failure; } bool WorldRepeatBoxAction::canUndo() { return false; } bool WorldRepeatBoxAction::shouldUndo() { return false; } const string WorldRepeatBoxAction::getName() { return NAME; }