/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2010 University of Bonn. All rights reserved. * Please see the LICENSE file or "Copyright notice" in builder.cpp for details. */ /* * RepeatBoxAction.cpp * * Created on: May 12, 2010 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/MemDebug.hpp" #include "Descriptors/MoleculePtrDescriptor.hpp" #include "atom.hpp" #include "CodePatterns/Log.hpp" #include "molecule.hpp" #include "LinearAlgebra/Vector.hpp" #include "LinearAlgebra/RealSpaceMatrix.hpp" #include "CodePatterns/Verbose.hpp" #include "World.hpp" #include "Box.hpp" #include #include #include using namespace std; #include "Actions/WorldAction/RepeatBoxAction.hpp" // and construct the stuff #include "RepeatBoxAction.def" #include "Action_impl_pre.hpp" /** =========== define the function ====================== */ Action::state_ptr WorldRepeatBoxAction::performCall() { int count; const element ** Elements; molecule *mol = NULL; int j = 0; atom *Walker = NULL; MoleculeListClass *molecules = World::getInstance().getMolecules(); // obtain information getParametersfromValueStorage(); 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 " << params.Repeater << " times for (x,y,z) axis." << endl); RealSpaceMatrix M = World::getInstance().getDomain().getM(); RealSpaceMatrix newM = M; Vector x,y; int n[NDIM]; RealSpaceMatrix repMat; for (int axis = 0; axis < NDIM; axis++) { params.Repeater[axis] = floor(params.Repeater[axis]); if (params.Repeater[axis] < 1) { DoeLog(1) && (eLog()<< Verbose(1) << "Repetition factor must be greater than 1!" << endl); params.Repeater[axis] = 1; } repMat.at(axis,axis) = params.Repeater[axis]; } newM *= repMat; World::getInstance().setDomain(newM); molecule *newmol = NULL; std::vector vectors; for (n[0] = 0; n[0] < params.Repeater[0]; n[0]++) { y[0] = n[0]; for (n[1] = 0; n[1] < params.Repeater[1]; n[1]++) { y[1] = n[1]; for (n[2] = 0; n[2] < params.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.resize(count); j = 0; for(molecule::iterator AtomRunner = mol->begin(); AtomRunner != mol->end(); ++AtomRunner) { Elements[j] = (*AtomRunner)->getType(); vectors[j] = (*AtomRunner)->getPosition(); 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->setPosition((vectors[k]) + x); Walker->setType(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); } else { DoLog(1) && (Log() << Verbose(1) << "\t ... is empty." << endl); } } } } } // give final box size LOG(0, "Box domain is now " << World::getInstance().getDomain().getM()); 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; } /** =========== end of function ====================== */