TEST(CjsonTest, atoms) { CjsonFormat cjson; Molecule molecule; bool success = cjson.readFile(std::string(AVOGADRO_DATA) + "/data/ethane.cjson", molecule); EXPECT_TRUE(success); EXPECT_EQ(cjson.error(), ""); EXPECT_EQ(molecule.data("name").toString(), "Ethane"); EXPECT_EQ(molecule.atomCount(), static_cast<size_t>(8)); Atom atom = molecule.atom(0); EXPECT_EQ(atom.atomicNumber(), static_cast<unsigned char>(1)); atom = molecule.atom(1); EXPECT_EQ(atom.atomicNumber(), static_cast<unsigned char>(6)); EXPECT_EQ(atom.position3d().x(), 0.751621); EXPECT_EQ(atom.position3d().y(), -0.022441); EXPECT_EQ(atom.position3d().z(), -0.020839); atom = molecule.atom(7); EXPECT_EQ(atom.atomicNumber(), static_cast<unsigned char>(1)); EXPECT_EQ(atom.position3d().x(), -1.184988); EXPECT_EQ(atom.position3d().y(), 0.004424); EXPECT_EQ(atom.position3d().z(), -0.987522); }
bool AbbreviationExpander::expandAtomAbbreviation (Molecule &mol, int v) { // Determine bonds configuration: number of bonds on the left and on the right Vec3f &pos = mol.getAtomXyz(v); const Vertex &vertex = mol.getVertex(v); int count_left = 0, count_right = 0, count_middle = 0; Array<int> left_atoms, right_atoms; for (int nei = vertex.neiBegin(); nei != vertex.neiEnd(); nei = vertex.neiNext(nei)) { int nei_atom = vertex.neiVertex(nei); Vec3f &nei_pos = mol.getAtomXyz(nei_atom); int order = mol.getBondOrder(vertex.neiEdge(nei)); if (nei_pos.x < pos.x) { count_left += order; left_atoms.push(nei_atom); } else { count_right += order; right_atoms.push(nei_atom); } Vec3f diff = nei_pos; diff.sub(pos); if (fabs(diff.y) > fabs(diff.x)) count_middle += order; } int input_order, output_order; bool on_left = false, on_right = false, is_single = false; if (vertex.degree() == 1) { if (count_middle) on_left = on_right = true; if (count_left) on_right = true; if (count_right) on_left = true; input_order = std::max(count_left, count_right); output_order = 0; is_single = true; } else { on_right = true; input_order = count_left; output_order = count_right; } // Try to expand according to the directions Array<Options> options; if (on_right && !on_left) { options.push(Options(RIGHT, RIGHT)); options.push(Options(LEFT, LEFT)); } else { if (on_right) options.push(Options(RIGHT, RIGHT)); if (on_left) { options.push(Options(LEFT, LEFT)); options.push(Options(LEFT, RIGHT)); options.push(Options(RIGHT, RIGHT)); options.push(Options(LEFT, LEFT, 2)); } } // Duplicate all the options with ignore case flag int opt_cnt = options.size(); for (int i = 0; i < opt_cnt; i++) { Options opt = options[i]; opt.ignore_case = true; options.push(opt); } bool found = false; Molecule expanded; for (int i = 0; i < options.size(); i++) { options[i].set(*this); if (expand(mol.getPseudoAtom(v), input_order, output_order, expanded)) { found = true; break; } } if (!found) return false; // Merge expanded abbreviation with the source molecule and connect bonds Array<int> mapping; mol.mergeWithMolecule(expanded, &mapping); //if (right_atoms.size() == 0) // right_atoms.swap(left_atoms); for (int i = 0; i < left_atoms.size(); i++) mol.flipBond(left_atoms[i], v, mapping[input_index]); int target_end = output_index; if (is_single == 1) target_end = input_index; for (int i = 0; i < right_atoms.size(); i++) mol.flipBond(right_atoms[i], v, mapping[target_end]); // Collect added atoms and set their coordinate to the initial atom // Layout procedure will find correct atom coordinates, but neighbours // should know correct relative position for (int ve = expanded.vertexBegin(); ve != expanded.vertexEnd(); ve = expanded.vertexNext(ve)) { int idx = mapping[ve]; mol.setAtomXyz(idx, mol.getAtomXyz(v)); added_atoms.push(mapping[ve]); } int sid = mol.sgroups.addSGroup(SGroup::SG_TYPE_SUP); Superatom &super = (Superatom &)mol.sgroups.getSGroup(sid); super.subscript.readString(mol.getPseudoAtom(v), true); for (int ve = expanded.vertexBegin(); ve != expanded.vertexEnd(); ve = expanded.vertexNext(ve)) super.atoms.push(mapping[ve]); mol.removeAtom(v); return true; }
static PyObject *set(PyObject *self, PyObject *args) { int i, molid, frame; PyObject *selected, *val; char *attr = 0; // // get molid, frame, list, attribute, and value // if (!PyArg_ParseTuple(args, (char *)"iiO!sO!", &molid, &frame, &PyTuple_Type, &selected, &attr, &PyTuple_Type, &val )) return NULL; // bad args // // check that we have been given either one value or one for each selected // atom // int num_selected = PyTuple_Size(selected); int tuplesize = PyTuple_Size(val); if (tuplesize != 1 && tuplesize != num_selected) { PyErr_SetString(PyExc_ValueError, "wrong number of items"); return NULL; } // // check molecule // VMDApp *app = get_vmdapp(); Molecule *mol = app->moleculeList->mol_from_id(molid); if (!mol) { PyErr_SetString(PyExc_ValueError, "molecule no longer exists"); return NULL; } const int num_atoms = mol->nAtoms; // // Check for a valid attribute // SymbolTable *table = app->atomSelParser; int attrib_index = table->find_attribute(attr); if (attrib_index == -1) { PyErr_SetString(PyExc_ValueError, "unknown atom attribute"); return NULL; } SymbolTableElement *elem = table->fctns.data(attrib_index); if (elem->is_a != SymbolTableElement::KEYWORD && elem->is_a != SymbolTableElement::SINGLEWORD) { PyErr_SetString(PyExc_ValueError, "attribute is not a keyword or singleword"); return NULL; } if (!table->is_changeable(attrib_index)) { PyErr_SetString(PyExc_ValueError, "attribute is not modifiable"); return NULL; } // // convert the list of selected atoms into an array of integer flags // // XXX should check that selected contains valid indices int *flgs = new int[num_atoms]; memset(flgs,0,num_atoms*sizeof(int)); for (i=0; i<num_selected; i++) flgs[PyInt_AsLong(PyTuple_GET_ITEM(selected,i))] = 1; // // set the data // // singlewords can never be set, so macro is NULL. atomsel_ctxt context(table, mol, frame, NULL); if (elem->returns_a == SymbolTableElement::IS_INT) { int *list = new int[num_atoms]; if (tuplesize > 1) { int j=0; for (int i=0; i<num_atoms; i++) { if (flgs[i]) list[i] = PyInt_AsLong(PyTuple_GET_ITEM(val, j++)); } } else { for (int i=0; i<num_atoms; i++) { if (flgs[i]) list[i] = PyInt_AsLong(PyTuple_GET_ITEM(val, 0)); } } elem->set_keyword_int(&context, num_atoms, list, flgs); delete [] list; } else if (elem->returns_a == SymbolTableElement::IS_FLOAT) { double *list = new double[num_atoms]; if (tuplesize > 1) { int j=0; for (int i=0; i<num_atoms; i++) { if (flgs[i]) list[i] = PyFloat_AsDouble(PyTuple_GET_ITEM(val, j++)); } } else { for (int i=0; i<num_atoms; i++) { if (flgs[i]) list[i] = PyFloat_AsDouble(PyTuple_GET_ITEM(val, 0)); } } elem->set_keyword_double(&context, num_atoms, list, flgs); delete [] list; } else if (elem->returns_a == SymbolTableElement::IS_STRING) { const char **list = new const char *[num_atoms]; if (tuplesize > 1) { int j=0; for (int i=0; i<num_atoms; i++) { if (flgs[i]) list[i] = PyString_AsString(PyTuple_GET_ITEM(val, j++)); } } else { for (int i=0; i<num_atoms; i++) { if (flgs[i]) list[i] = PyString_AsString(PyTuple_GET_ITEM(val, 0)); } } elem->set_keyword_string(&context, num_atoms, list, flgs); delete [] list; } // Recompute the color assignments if certain atom attributes are changed. if (!strcmp(attr, "name") || !strcmp(attr, "type") || !strcmp(attr, "resname") || !strcmp(attr, "chain") || !strcmp(attr, "segid") || !strcmp(attr, "segname")) app->moleculeList->add_color_names(molid); mol->force_recalc(DrawMolItem::SEL_REGEN | DrawMolItem::COL_REGEN); delete [] flgs; Py_INCREF(Py_None); return Py_None; }
void NPT::moveA() { SimInfo::MoleculeIterator i; Molecule::IntegrableObjectIterator j; Molecule* mol; StuntDouble* sd; Vector3d Tb, ji; RealType mass; Vector3d vel; Vector3d pos; Vector3d frc; Vector3d sc; int index; thermostat = snap->getThermostat(); loadEta(); instaTemp =thermo.getTemperature(); press = thermo.getPressureTensor(); instaPress = PhysicalConstants::pressureConvert* (press(0, 0) + press(1, 1) + press(2, 2)) / 3.0; instaVol =thermo.getVolume(); Vector3d COM = thermo.getCom(); //evolve velocity half step calcVelScale(); for (mol = info_->beginMolecule(i); mol != NULL; mol = info_->nextMolecule(i)) { for (sd = mol->beginIntegrableObject(j); sd != NULL; sd = mol->nextIntegrableObject(j)) { vel = sd->getVel(); frc = sd->getFrc(); mass = sd->getMass(); getVelScaleA(sc, vel); // velocity half step (use chi from previous step here): vel += dt2*PhysicalConstants::energyConvert/mass* frc - dt2*sc; sd->setVel(vel); if (sd->isDirectional()) { // get and convert the torque to body frame Tb = sd->lab2Body(sd->getTrq()); // get the angular momentum, and propagate a half step ji = sd->getJ(); ji += dt2*PhysicalConstants::energyConvert * Tb - dt2*thermostat.first* ji; rotAlgo_->rotate(sd, ji, dt); sd->setJ(ji); } } } // evolve chi and eta half step thermostat.first += dt2 * (instaTemp / targetTemp - 1.0) / tt2; evolveEtaA(); //calculate the integral of chidt thermostat.second += dt2 * thermostat.first; flucQ_->moveA(); index = 0; for (mol = info_->beginMolecule(i); mol != NULL; mol = info_->nextMolecule(i)) { for (sd = mol->beginIntegrableObject(j); sd != NULL; sd = mol->nextIntegrableObject(j)) { oldPos[index++] = sd->getPos(); } } //the first estimation of r(t+dt) is equal to r(t) for(int k = 0; k < maxIterNum_; k++) { index = 0; for (mol = info_->beginMolecule(i); mol != NULL; mol = info_->nextMolecule(i)) { for (sd = mol->beginIntegrableObject(j); sd != NULL; sd = mol->nextIntegrableObject(j)) { vel = sd->getVel(); pos = sd->getPos(); this->getPosScale(pos, COM, index, sc); pos = oldPos[index] + dt * (vel + sc); sd->setPos(pos); ++index; } } rattle_->constraintA(); } // Scale the box after all the positions have been moved: this->scaleSimBox(); snap->setThermostat(thermostat); saveEta(); }
int main(int argc, char* argv[]) { CommandlineParser parpars("RMSDCalculator", "calculate RMSD between ligand poses", VERSION, String(__DATE__), "Analysis"); parpars.registerMandatoryInputFile("i", "input molecule file"); parpars.registerMandatoryInputFile("org", "molecule file containing the original ('true') poses"); parpars.registerOptionalOutputFile("o", "output molecule file"); parpars.registerFlag("quiet", "by quiet, i.e. do not print progress information"); String man = "This tool calculates the RMSD between different conformations of the same molecule.\n\nThis tool can be used to evaluate the differences between ligand poses taken from co-crystal structures, e.g. generated by a docking run.\nNote:Molecules may be sorted differently in the two input files; a topology hashkey will be used to match molecules to each other.\n\nOutput of this tool is a molecule file which will for each molecule contain a property-tag 'RMSD' holding the calculated RMSD value."; parpars.setToolManual(man); parpars.setSupportedFormats("i",MolFileFactory::getSupportedFormats()); parpars.setSupportedFormats("org",MolFileFactory::getSupportedFormats()); parpars.setSupportedFormats("o","mol2,sdf,drf"); parpars.parse(argc, argv); // Retrieve coordinates of original poses GenericMolFile* original = MolFileFactory::open(parpars.get("org")); HashMap<String, list<Vector3> > original_poses; for (Molecule* mol = original->read(); mol; delete mol, mol = original->read()) { String topology_hash; FlexibleMolecule::generateTopologyHash(mol, topology_hash, true); if (original_poses.find(topology_hash) != original_poses.end()) { Log<<"[Warning:] more than one 'original' conformation for a molecule detected. Will use only the first conformation and ignore all other."<<endl; } else { list<Vector3> l; HashMap<String, list<Vector3> >::iterator map_it = original_poses.insert(make_pair(topology_hash, l)).first; for (AtomConstIterator it = mol->beginAtom(); +it; it++) { if (it->getElement().getSymbol() != "H") { map_it->second.push_back(it->getPosition()); } } } } delete original; // Retrieve coordinates of input poses and calculate RMSDs GenericMolFile* input = MolFileFactory::open(parpars.get("i")); GenericMolFile* output = 0; String filename = parpars.get("o"); if (filename != CommandlineParser::NOT_FOUND) { output = MolFileFactory::open(filename, ios::out, input); } double average_RMSD = 0; int no_mols = 0; int no_valid_rmsds = 0; bool quiet = (parpars.get("quiet")!=CommandlineParser::NOT_FOUND); for (Molecule* mol = input->read(); mol; delete mol, mol = input->read()) { no_mols++; String topology_hash; FlexibleMolecule::generateTopologyHash(mol, topology_hash, true); HashMap<String, list<Vector3> >::iterator map_it = original_poses.find(topology_hash); if (map_it == original_poses.end()) { Log<<"[Warning:] no original pose for molecule '"<<mol->getName()<<"' found, its RMSD can thus not be computed."<<endl; mol->setProperty("RMSD", "N/A"); } else { double RMSD = 0; list<Vector3>::iterator list_it = map_it->second.begin(); int no_heavy_atoms = 0; AtomConstIterator it = mol->beginAtom(); for (; +it ; it++) { if (it->getElement().getSymbol() != "H" && list_it != map_it->second.end()) { RMSD += pow(it->getPosition().getDistance(*list_it), 2); no_heavy_atoms++; list_it++; } } if (it != mol->endAtom() || list_it != map_it->second.end()) { Log.error()<<"[Error:] Number of heavy atoms of input pose do not match number of heavy atoms of original pose!!"<<endl; return 1; } RMSD = sqrt(RMSD/no_heavy_atoms); mol->setProperty("RMSD", RMSD); average_RMSD += RMSD; no_valid_rmsds++; if (!quiet) Log << "RMSD for molecule "<<no_mols<<", '"<<mol->getName()<<"' = "<<RMSD<<endl; } if (output) *output << *mol; } average_RMSD /= no_valid_rmsds; Log <<endl<<"average RMSD = "<<average_RMSD<<endl<<endl; delete input; delete output; return 0; }
bool ChemicalPotential::getDeletion(TMoleculeContainer* cell, double* minco, double* maxco) { if(this->remainingDeletions.empty()) return false; if(cell->getNumberOfParticles() == 0) return false; unsigned idx = *this->remainingDeletions.begin(); this->remainingDeletions.erase(this->remainingDeletions.begin()); double tminco[3]; double tmaxco[3]; if(restrictedControlVolume) for(int d=0; d < 3; d++) { tminco[d] = (minco[d] > control_bottom[d])? minco[d] : control_bottom[d]; tmaxco[d] = (maxco[d] < control_top[d])? maxco[d] : control_top[d]; } else for(int d=0; d < 3; d++) { tminco[d] = minco[d]; tmaxco[d] = maxco[d]; } Molecule* m = cell->begin(); int j=0; for(unsigned i=0; (i < idx); i++) { while(( (m->r(0) > tmaxco[0]) || (m->r(1) > tmaxco[1]) || (m->r(2) > tmaxco[2]) || (m->r(0) < tminco[0]) || (m->r(1) < tminco[1]) || (m->r(2) < tminco[2]) || (m->componentid() != this->componentid) ) && (m != cell->end())) { m = cell->next(); if(m == cell->end()) { if(j == 0) return false; m = cell->begin(); j = 0; } } m = cell->next(); j++; if(m == cell->end()) { if(j == 0) return false; m = cell->begin(); j = 0; } } while( (m->r(0) > tmaxco[0]) || (m->r(1) > tmaxco[1]) || (m->r(2) > tmaxco[2]) || (m->r(0) < tminco[0]) || (m->r(1) < tminco[1]) || (m->r(2) < tminco[2]) || (m->componentid() != this->componentid) ) { m = cell->next(); if(m == cell->end()) { if(j == 0) return false; m = cell->begin(); } } #ifndef NDEBUG global_log->debug() << "ID " << m->id() << " selected for deletion (index " << idx << ")." << std::endl; #endif assert(m->id() < nextid); return true; }
void DensityPlot::process() { Molecule* mol; RigidBody* rb; SimInfo::MoleculeIterator mi; Molecule::RigidBodyIterator rbIter; DumpReader reader(info_, dumpFilename_); int nFrames = reader.getNFrames(); for (int i = 0; i < nFrames; i += step_) { reader.readFrame(i); currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot(); for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) { //change the positions of atoms which belong to the rigidbodies for (rb = mol->beginRigidBody(rbIter); rb != NULL; rb = mol->nextRigidBody(rbIter)) { rb->updateAtoms(); } } if (evaluator_.isDynamic()) { seleMan_.setSelectionSet(evaluator_.evaluate()); } if (cmEvaluator_.isDynamic()) { cmSeleMan_.setSelectionSet(cmEvaluator_.evaluate()); } Vector3d origin = calcNewOrigin(); Mat3x3d hmat = currentSnapshot_->getHmat(); RealType slabVolume = deltaR_ * hmat(0, 0) * hmat(1, 1); int k; for (StuntDouble* sd = seleMan_.beginSelected(k); sd != NULL; sd = seleMan_.nextSelected(k)) { if (!sd->isAtom()) { sprintf( painCave.errMsg, "Can not calculate electron density if it is not atom\n"); painCave.severity = OPENMD_ERROR; painCave.isFatal = 1; simError(); } Atom* atom = static_cast<Atom*>(sd); GenericData* data = atom->getAtomType()->getPropertyByName("nelectron"); if (data == NULL) { sprintf( painCave.errMsg, "Can not find Parameters for nelectron\n"); painCave.severity = OPENMD_ERROR; painCave.isFatal = 1; simError(); } DoubleGenericData* doubleData = dynamic_cast<DoubleGenericData*>(data); if (doubleData == NULL) { sprintf( painCave.errMsg, "Can not cast GenericData to DoubleGenericData\n"); painCave.severity = OPENMD_ERROR; painCave.isFatal = 1; simError(); } RealType nelectron = doubleData->getData(); LennardJonesAdapter lja = LennardJonesAdapter(atom->getAtomType()); RealType sigma = lja.getSigma() * 0.5; RealType sigma2 = sigma * sigma; Vector3d pos = sd->getPos() - origin; for (int j =0; j < nRBins_; ++j) { Vector3d tmp(pos); RealType zdist =j * deltaR_ - halfLen_; tmp[2] += zdist; if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(tmp); RealType wrappedZdist = tmp.z() + halfLen_; if (wrappedZdist < 0.0 || wrappedZdist > len_) { continue; } int which = int(wrappedZdist / deltaR_); density_[which] += nelectron * exp(-zdist*zdist/(sigma2*2.0)) /(slabVolume* sqrt(2*NumericConstant::PI*sigma*sigma)); } } } int nProcessed = nFrames /step_; std::transform(density_.begin(), density_.end(), density_.begin(), std::bind2nd(std::divides<RealType>(), nProcessed)); writeDensity(); }
void Shake::doConstraint(ConstraintPairFuncPtr func) { if (!doShake_) return; Molecule* mol; SimInfo::MoleculeIterator mi; ConstraintElem* consElem; Molecule::ConstraintElemIterator cei; ConstraintPair* consPair; Molecule::ConstraintPairIterator cpi; for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) { for (consElem = mol->beginConstraintElem(cei); consElem != NULL; consElem = mol->nextConstraintElem(cei)) { consElem->setMoved(true); consElem->setMoving(false); } } //main loop of constraint algorithm int done = 0; int iteration = 0; while(!done && iteration < maxConsIteration_){ done = 1; //loop over every constraint pair for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) { for (consPair = mol->beginConstraintPair(cpi); consPair != NULL; consPair = mol->nextConstraintPair(cpi)) { //dispatch constraint algorithm if(consPair->isMoved()) { int exeStatus = (this->*func)(consPair); switch(exeStatus){ case consFail: sprintf(painCave.errMsg, "Constraint failure in Shake::constrainA, " "Constraint Fail\n"); painCave.isFatal = 1; simError(); break; case consSuccess: // constrain the pair by moving two elements done = 0; consPair->getConsElem1()->setMoving(true); consPair->getConsElem2()->setMoving(true); break; case consAlready: // current pair is already constrained, do not need to // move the elements break; default: sprintf(painCave.errMsg, "ConstraintAlgorithm::doConstraint() " "Error: unrecognized status"); painCave.isFatal = 1; simError(); break; } } } }//end for(iter->first()) #ifdef IS_MPI MPI_Allreduce(MPI_IN_PLACE, &done, 1, MPI_INT, MPI_LAND, MPI_COMM_WORLD); #endif errorCheckPoint(); for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) { for (consElem = mol->beginConstraintElem(cei); consElem != NULL; consElem = mol->nextConstraintElem(cei)) { consElem->setMoved(consElem->getMoving()); consElem->setMoving(false); } } iteration++; }//end while if (!done){ sprintf(painCave.errMsg, "Constraint failure in Shake::constrainA, " "too many iterations: %d\n", iteration); painCave.isFatal = 1; simError(); } errorCheckPoint(); }
/* * Evaluate contributions to accumulators. */ void MdPairEnergyCoefficients::sample(long iStep) { if (isAtInterval(iStep)) { #ifndef INTER_NOPAIR // if (!system().isPairListCurrent()) { // system().buildPairList(); // } // First clear neighbor list clear(); // Loop over pairs and construct neighbor list per molecule PairIterator iter; Atom *atom0Ptr; Atom *atom1Ptr; for (pairListPtr_->begin(iter); iter.notEnd(); ++iter) { iter.getPair(atom0Ptr, atom1Ptr); if (selector_.match(*atom0Ptr, *atom1Ptr)) { Pair< Atom * > atomPair; Molecule *moleculePtr; Species *speciesPtr; int speciesId, moleculeId; atomPair[0] = atom0Ptr; atomPair[1] = atom1Ptr; // Store pair in neighbor list of boths atoms' molecules // (do double counting, since pair list counts only unique // pairs) moleculePtr = & atom0Ptr->molecule(); speciesPtr = & moleculePtr->species(); speciesId = speciesPtr->id(); moleculeId = moleculePtr->id(); moleculeNeighbors_[speciesId][moleculeId]. append(atomPair); moleculePtr = & atom1Ptr->molecule(); speciesPtr = & moleculePtr->species(); speciesId = speciesPtr->id(); moleculeId = moleculePtr->id(); // store atomPair in reverse order atomPair[0] = atom1Ptr; atomPair[1] = atom0Ptr; moleculeNeighbors_[speciesId][moleculeId]. append(atomPair); } } // end pair loop // Now loop over all molecules double moleculePESq = 0.0; double pairEnergy=0.0; double twoMoleculePESq=0.0; double rsq; int iSpecies1, iMolecule1; for (iSpecies1 = 0; iSpecies1 < nSpecies_; ++iSpecies1) { Species *species1Ptr; species1Ptr = &system().simulation().species(iSpecies1); for (iMolecule1 = 0; iMolecule1 < species1Ptr->capacity(); ++iMolecule1) { int iSpecies2, iMolecule2; double moleculePairEnergy=0.0; // clear array for pair energy with neighboring molecules for (iSpecies2 = 0; iSpecies2 < nSpecies_; ++iSpecies2) { Species *species2Ptr; species2Ptr = &system().simulation().species(iSpecies2); for (iMolecule2 = 0; iMolecule2 < species2Ptr->capacity(); ++iMolecule2) { twoMoleculePairEnergy_[iSpecies2][iMolecule2]=0.0; } } // Loop over this molecule's neighbors DSArray< Pair< Atom *> > *neighborsPtr; ConstArrayIterator< Pair< Atom *> > it; neighborsPtr=&moleculeNeighbors_[iSpecies1][iMolecule1]; for (neighborsPtr->begin(it); it.notEnd(); ++it) { Atom *atom0Ptr, *atom1Ptr; atom0Ptr = (*it)[0]; atom1Ptr = (*it)[1]; if (selector_.match(*atom0Ptr,*atom1Ptr)) { double energy; Species *species2Ptr; Molecule *molecule2Ptr; int species2Id,molecule2Id; // Load second atom's molecule and species molecule2Ptr = &atom1Ptr->molecule(); species2Ptr = &atom1Ptr->molecule().species(); species2Id = species2Ptr->id(); molecule2Id = molecule2Ptr->id(); rsq = boundaryPtr_->distanceSq(atom0Ptr->position(), atom1Ptr->position()); energy = pairPotentialPtr_->energy(rsq, atom0Ptr->typeId(), atom1Ptr->typeId()); // increment pair energy of this molecule pair twoMoleculePairEnergy_[species2Id][molecule2Id] += energy; } } // end neighbors loop // sum the molecular pair energies and their squares for (iSpecies2 = 0; iSpecies2 < nSpecies_; ++iSpecies2) { Species *species2Ptr; species2Ptr = &system().simulation().species(iSpecies2); for (iMolecule2 = 0; iMolecule2 < species2Ptr->capacity(); ++iMolecule2) { double energy = twoMoleculePairEnergy_[iSpecies2][iMolecule2]; moleculePairEnergy += energy; twoMoleculePESq += energy*energy; } } // accumulate total molecular pair energy and its square pairEnergy += moleculePairEnergy; moleculePESq += moleculePairEnergy*moleculePairEnergy; } // end molecule loop } // end species loop // Sample sum of pair energies pairEnergyAccumulator_.sample(pairEnergy); // Sample sum of squares of molecular pair energy moleculePESqAccumulator_.sample(moleculePESq); // Sample sum of squares of two molecule pair energy twoMoleculePESqAccumulator_.sample(twoMoleculePESq); // Sample square of total pair energy pESqAccumulator_.sample(pairEnergy*pairEnergy); outputFile_ << Dbl(pairEnergy); outputFile_ << Dbl(moleculePESq); outputFile_ << Dbl(twoMoleculePESq); outputFile_ << Dbl(pairEnergy*pairEnergy); #endif outputFile_ << std::endl; } }
bool GAMESSLogFile::write(const Molecule& molecule) { System S; S.insert(*(Molecule*)molecule.create(true)); return write(S); }
void mergeDRFiles(vector<String>& names, string& output_file, Size& best_k, string& e_property, double& score_cutoff, double& score_cuton) { DockResultFile* output = new DockResultFile(output_file, ios::out); bool sort_by_scores = 1; if (e_property == "") sort_by_scores = 0; vector<Result*> new_results; /// First of all, copy Result data map<Result::Method, Result*> result_map; for (Size file = 0; file < names.size(); file++) { DockResultFile* input = new DockResultFile(names[file]); const vector<Result*>* results = input->getResults(); for (Size i = 0; i < results->size(); i++) { map<Result::Method, Result*>::iterator it = result_map.find((*results)[i]->getMethod()); if (it == result_map.end()) { Result* result_copy = new Result(*(*results)[i]); if (!sort_by_scores) output->addResult(result_copy); else new_results.push_back(result_copy); result_map.insert(make_pair(result_copy->getMethod(), result_copy)); } else { *it->second += *(*results)[i]; } } input->close(); delete input; } if (e_property != "") { e_property = "score_"+new_results.back()->getMethodString(); } /// If no sorting is desired, iterate over all input-files and write each input-molecules to output-file if (!sort_by_scores) { output->disableAutomaticResultCreation(); for (Size file = 0; file < names.size(); file++) { GenericMolFile* input = MolFileFactory::open(names[file]); int mol_no = 0; for (Molecule* mol = input->read(); mol; mol = input->read(), mol_no++) { *output << *mol; delete mol; Log.level(20) << "\r" << names[file] << " : " << mol_no+1; Log.flush(); } Log.level(20)<<endl; Log.flush(); input->close(); delete input; } } /// If sorting is desired, iterate over all input-files and save each input-molecules to a map. /// Then write all FlexibleMolecules in this map to the output file and adapt the Result objects. else { multimap < double, FlexibleMolecule* > compounds; // map containing score and conformation-ID set < String > IDs; // IDs of the base-conformations for (Size file = 0; file < names.size(); file++) { DockResultFile* input = new DockResultFile(names[file]); int mol_no = 0; for (Molecule* mol = input->read(); mol; mol = input->read(), mol_no++) { if (!mol->hasProperty(e_property)) { Log.level(10) << "Compound " << mol->getName() << " in file " << names[file] << " has no score property. Skipping this compound." << endl; for (Size i = 0; i < new_results.size(); i++) { new_results[i]->erase(input->getCurrentLigand()); } delete mol; continue; } double score = ((String)mol->getProperty(e_property).toString()).toFloat(); if (score > score_cutoff || score < score_cuton) { for (Size i = 0; i < new_results.size(); i++) { new_results[i]->erase(input->getCurrentLigand()); } delete mol; continue; } if ((compounds.size() < best_k || score < compounds.rbegin()->first)) { FlexibleMolecule* flexmol_copy = new FlexibleMolecule(*input->getCurrentLigand()); compounds.insert(make_pair(score, flexmol_copy)); IDs.insert(flexmol_copy->getId()); if (compounds.size() > best_k) { for (Size i = 0; i < new_results.size(); i++) { new_results[i]->erase(compounds.rbegin()->second); } IDs.erase(compounds.rbegin()->second->getId()); delete compounds.rbegin()->second; multimap<double, FlexibleMolecule*>::iterator it = compounds.end(); it--; compounds.erase(it); } } else { for (Size i = 0; i < new_results.size(); i++) { new_results[i]->erase(input->getCurrentLigand()); } delete mol; } Log.level(20) <<"\r"<<names[file]<<" : "<<mol_no+1<<flush; } Log.level(20)<<endl; input->close(); delete input; } if (compounds.size() < best_k) { Log.level(20)<<"found "<<compounds.size()<<" compounds matching the given criteria."<<endl; } list<String> score_list; for (multimap < double, FlexibleMolecule* > ::iterator it = compounds.begin(); it!=compounds.end(); it++) { output->writeLigand(it->second); score_list.push_back(it->second->getId()); delete it->second; } // Remove those ligands from results for which no final result is available (e.g. due to missing atom parameters) vector < String > import_IDs = *new_results[0]->getInputConformations(); for (Size i = 0; i < import_IDs.size(); i++) { if (IDs.find(import_IDs[i]) == IDs.end()) { vector<vector<Result::ResultData> > data_list; for (Size k = 0; k < new_results.size(); k++) { if (k == 0) { data_list.push_back(*new_results[k]->get(import_IDs[i])); } vector<vector<Result::ResultData> > new_data_list; for (Size j = 0; j < data_list.size(); j++) { for (Size l = 0; l < data_list[j].size(); l++) { String ID = data_list[j][l].getLigandConformationId(); new_data_list.push_back(*new_results[k]->get(ID)); new_results[k]->erase(ID); } } data_list = new_data_list; } } } for (Size i = 0; i < new_results.size(); i++) { list<String> new_list; new_results[i]->sort(score_list, new_list); score_list = new_list; } output->writeResults(new_results); } output->close(); delete output; }
void sortMolecules(vector<String>& names, string& output_file, Size& best_k, string& e_property, double& score_cutoff, double& score_cuton) { multimap<double, Molecule*> compounds; for (Size file = 0; file < names.size(); file++) { GenericMolFile* input = MolFileFactory::open(names[file]); int mol_no = 0; for (Molecule* mol = input->read(); mol; mol = input->read(), mol_no++) { if (!mol->hasProperty(e_property)) { Log.level(10) << "Compound " << mol->getName() << " in file " << names[file] << " has no score property. Skipping this compound." << endl; delete mol; continue; } double score = ((String)mol->getProperty(e_property).toString()).toFloat(); if (score > score_cutoff || score < score_cuton) { delete mol; continue; } if ((compounds.size() < best_k || score < compounds.rbegin()->first)) { compounds.insert(make_pair(score, mol)); if (compounds.size() > best_k) { delete compounds.rbegin()->second; multimap<double, Molecule*>::iterator it = compounds.end(); it--; compounds.erase(it); } } else { delete mol; } Log.level(20) << "\r" << names[file] << " : " << mol_no+1 << flush; } Log.level(20) << endl; Log.flush(); input->close(); delete input; } if (compounds.size() < best_k) { Log.level(20) << "found " << compounds.size() << " compounds matching the given criteria." << endl; } GenericMolFile* output = MolFileFactory::open(output_file, ios::out, "mol2.gz"); for (multimap < double, Molecule* > ::iterator it = compounds.begin(); it!=compounds.end(); it++) { *output << *it->second; delete it->second; } output->close(); delete output; }
static PyObject *contacts(PyObject *self, PyObject *args) { int mol1, frame1, mol2, frame2; PyObject *selected1, *selected2; float cutoff; if (!PyArg_ParseTuple(args, (char *)"iiO!iiO!f:atomselection.contacts", &mol1, &frame1, &PyTuple_Type, &selected1, &mol2, &frame2, &PyTuple_Type, &selected2, &cutoff)) return NULL; VMDApp *app = get_vmdapp(); AtomSel *sel1 = sel_from_py(mol1, frame1, selected1, app); AtomSel *sel2 = sel_from_py(mol2, frame2, selected2, app); if (!sel1 || !sel2) { delete sel1; delete sel2; return NULL; } const float *ts1 = sel1->coordinates(app->moleculeList); const float *ts2 = sel2->coordinates(app->moleculeList); if (!ts1 || !ts2) { PyErr_SetString(PyExc_ValueError, "No coordinates in selection"); delete sel1; delete sel2; return NULL; } Molecule *mol = app->moleculeList->mol_from_id(mol1); GridSearchPair *pairlist = vmd_gridsearch3( ts1, sel1->num_atoms, sel1->on, ts2, sel2->num_atoms, sel2->on, cutoff, -1, (sel1->num_atoms + sel2->num_atoms) * 27); delete sel1; delete sel2; GridSearchPair *p, *tmp; PyObject *list1 = PyList_New(0); PyObject *list2 = PyList_New(0); PyObject *tmp1; PyObject *tmp2; for (p=pairlist; p != NULL; p=tmp) { // throw out pairs that are already bonded MolAtom *a1 = mol->atom(p->ind1); if (mol1 != mol2 || !a1->bonded(p->ind2)) { // Needed to avoid a memory leak. Append increments the refcount // of whatever gets added to it, but so does PyInt_FromLong. // Without a decref, the integers created never have their refcount // go to zero, and you leak memory. tmp1 = PyInt_FromLong(p->ind1); tmp2 = PyInt_FromLong(p->ind2); PyList_Append(list1, tmp1); PyList_Append(list2, tmp2); Py_DECREF(tmp1); Py_DECREF(tmp2); } tmp = p->next; free(p); } PyObject *result = PyList_New(2); PyList_SET_ITEM(result, 0, list1); PyList_SET_ITEM(result, 1, list2); return result; }
using std::ios; Molecule* b; CHECK(Molecule() throw()) b = new Molecule; TEST_NOT_EQUAL(b, 0) RESULT CHECK(~Molecule() throw()) delete b; RESULT CHECK(Molecule(const Molecule& molecule, bool deep = true) throw()) Atom a1; Molecule m("a"), m2; m.append(a1); m2 = Molecule(m); TEST_EQUAL(m2.getName(), "a") TEST_EQUAL(m2.countAtoms(), 1) RESULT CHECK(Molecule(const String& name) throw()) Molecule m("a"); TEST_EQUAL(m.getName(), "a") Molecule m2(""); TEST_EQUAL(m2.getName(), "") RESULT CHECK([EXTRA] clear()) System s;
void CanonicalSmilesSaver::saveMolecule (Molecule &mol_) const { if (mol_.vertexCount() < 1) return; QS_DEF(Array<int>, ignored); QS_DEF(Array<int>, order); QS_DEF(Array<int>, ranks); QS_DEF(Molecule, mol); int i; if (mol_.repeating_units.size() > 0) throw Error("can not canonicalize a polymer"); // Detect hydrogens configuration if aromatic but not ambiguous bool found_invalid_h = false; for (i = mol_.vertexBegin(); i != mol_.vertexEnd(); i = mol_.vertexNext(i)) { if (mol_.isRSite(i) || mol_.isPseudoAtom(i)) continue; if (mol_.getImplicitH_NoThrow(i, -1) == -1) found_invalid_h = true; } if (found_invalid_h) { AromaticityOptions options; options.method = AromaticityOptions::GENERIC; options.unique_dearomatization = true; MoleculeDearomatizer::restoreHydrogens(mol_, options); } mol.clone(mol_, 0, 0); // TODO: canonicalize allenes properly mol.allene_stereo.clear(); ignored.clear_resize(mol.vertexEnd()); ignored.zerofill(); for (i = mol.vertexBegin(); i < mol.vertexEnd(); i = mol.vertexNext(i)) if (mol.convertableToImplicitHydrogen(i)) ignored[i] = 1; for (i = mol.edgeBegin(); i != mol.edgeEnd(); i = mol.edgeNext(i)) if (mol.getBondTopology(i) == TOPOLOGY_RING && mol.cis_trans.getParity(i) != 0) { // we save cis/trans ring bonds into SMILES, but only those who // do not participate in bigger ring systems const Edge &edge = mol.getEdge(i); if (mol.getAtomRingBondsCount(edge.beg) != 2 || mol.getAtomRingBondsCount(edge.end) != 2) { mol.cis_trans.setParity(i, 0); continue; } // also, discard the cis-trans bonds that have been converted to aromatic const Vertex &beg = mol.getVertex(edge.beg); const Vertex &end = mol.getVertex(edge.end); bool have_singlebond_beg = false; bool have_singlebond_end = false; int j; for (j = beg.neiBegin(); j != beg.neiEnd(); j = beg.neiNext(j)) if (mol.getBondOrder(beg.neiEdge(j)) == BOND_SINGLE) have_singlebond_beg = true; for (j = end.neiBegin(); j != end.neiEnd(); j = end.neiNext(j)) if (mol.getBondOrder(end.neiEdge(j)) == BOND_SINGLE) have_singlebond_end = true; if (!have_singlebond_beg || !have_singlebond_end) { mol.cis_trans.setParity(i, 0); continue; } } MoleculeAutomorphismSearch of; of.detect_invalid_cistrans_bonds = find_invalid_stereo; of.detect_invalid_stereocenters = find_invalid_stereo; of.find_canonical_ordering = true; of.ignored_vertices = ignored.ptr(); of.process(mol); of.getCanonicalNumbering(order); for (i = mol.edgeBegin(); i != mol.edgeEnd(); i = mol.edgeNext(i)) if (mol.cis_trans.getParity(i) != 0 && of.invalidCisTransBond(i)) mol.cis_trans.setParity(i, 0); for (i = mol.vertexBegin(); i != mol.vertexEnd(); i = mol.vertexNext(i)) if (mol.stereocenters.getType(i) > MoleculeStereocenters::ATOM_ANY && of.invalidStereocenter(i)) mol.stereocenters.remove(i); ranks.clear_resize(mol.vertexEnd()); for (i = 0; i < order.size(); i++) ranks[order[i]] = i; SmilesSaver saver(_output); saver.ignore_invalid_hcount = false; saver.vertex_ranks = ranks.ptr(); saver.ignore_hydrogens = true; saver.canonize_chiralities = true; saver.saveMolecule(mol); }
void BondAngleDistribution::process() { Molecule* mol; Atom* atom; RigidBody* rb; int myIndex; SimInfo::MoleculeIterator mi; Molecule::RigidBodyIterator rbIter; Molecule::AtomIterator ai; StuntDouble* sd; Vector3d vec; std::vector<Vector3d> bondvec; RealType r; int nBonds; int i; bool usePeriodicBoundaryConditions_ = info_->getSimParams()->getUsePeriodicBoundaryConditions(); DumpReader reader(info_, dumpFilename_); int nFrames = reader.getNFrames(); frameCounter_ = 0; nTotBonds_ = 0; for (int istep = 0; istep < nFrames; istep += step_) { reader.readFrame(istep); frameCounter_++; currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot(); if (evaluator_.isDynamic()) { seleMan_.setSelectionSet(evaluator_.evaluate()); } // update the positions of atoms which belong to the rigidbodies for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) { for (rb = mol->beginRigidBody(rbIter); rb != NULL; rb = mol->nextRigidBody(rbIter)) { rb->updateAtoms(); } } // outer loop is over the selected StuntDoubles: for (sd = seleMan_.beginSelected(i); sd != NULL; sd = seleMan_.nextSelected(i)) { myIndex = sd->getGlobalIndex(); nBonds = 0; bondvec.clear(); // inner loop is over all other atoms in the system: for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) { for (atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) { if (atom->getGlobalIndex() != myIndex) { vec = sd->getPos() - atom->getPos(); if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(vec); // Calculate "bonds" and make a pair list r = vec.length(); // Check to see if neighbor is in bond cutoff if (r < rCut_) { // Add neighbor to bond list's bondvec.push_back(vec); nBonds++; nTotBonds_++; } } } for (int i = 0; i < nBonds-1; i++ ){ Vector3d vec1 = bondvec[i]; vec1.normalize(); for(int j = i+1; j < nBonds; j++){ Vector3d vec2 = bondvec[j]; vec2.normalize(); RealType theta = acos(dot(vec1,vec2))*180.0/NumericConstant::PI; if (theta > 180.0){ theta = 360.0 - theta; } int whichBin = int(theta/deltaTheta_); histogram_[whichBin] += 2; } } } } } writeBondAngleDistribution(); }
TEST(InputGeneratorWidgetTest, exercise) { // Fake a QApplication -- needed to instantiate widgets. int argc = 1; char argName[] = "FakeApp.exe"; char *argv[2] = {argName, NULL}; QApplication app(argc, argv); Q_UNUSED(app); // Setup the widget InputGeneratorWidget widget; QString scriptFilePath(AVOGADRO_DATA "/tests/avogadro/scripts/inputgeneratortest.py"); widget.setInputGeneratorScript(scriptFilePath); Molecule mol; mol.addAtom(6).setPosition3d(Avogadro::Vector3(1, 1, 1)); mol.addAtom(1).setPosition3d(Avogadro::Vector3(2, 3, 4)); mol.addAtom(8).setPosition3d(Avogadro::Vector3(-2, 3, -4)); widget.setMolecule(&mol); // Check that the generator is configured properly. EXPECT_EQ(widget.inputGenerator().displayName().toStdString(), std::string("Input Generator Test")); // Verify that appropriate widgets are produced for each parameter type: EXPECT_TRUE(widget.findChild<QComboBox*>("Test StringList") != NULL); EXPECT_TRUE(widget.findChild<QLineEdit*>("Test String") != NULL); EXPECT_TRUE(widget.findChild<QSpinBox*>("Test Integer") != NULL); EXPECT_TRUE(widget.findChild<QCheckBox*>("Test Boolean") != NULL); EXPECT_TRUE(widget.findChild<FileBrowseWidget*>("Test FilePath") != NULL); // Set a test filepath FileBrowseWidget *testFilePathWidget( widget.findChild<FileBrowseWidget*>("Test FilePath")); QString testFilePath(AVOGADRO_DATA "/data/ethane.cml"); testFilePathWidget->setFileName(testFilePath); // Show the widget so that events are processed widget.show(); // Clear out the event queue so that the text edits are updated: flushEvents(); // Check the contents of the filepath file: QTextEdit *filePathEdit = widget.findChild<QTextEdit*>("job.testFilePath"); QFile testFile(testFilePath); EXPECT_TRUE(testFile.open(QFile::ReadOnly | QFile::Text)); QByteArray refData(testFile.readAll()); EXPECT_EQ(std::string(refData.constData()), filePathEdit->document()->toPlainText().toStdString()); // Check the coords: QTextEdit *coordsEdit = widget.findChild<QTextEdit*>("job.coords"); QString coords(coordsEdit->document()->toPlainText()); EXPECT_TRUE(coords.contains( "C 1.000000 0 1.000000 1 1.000000 1 Carbon")); EXPECT_TRUE(coords.contains( "H 2.000000 0 3.000000 1 4.000000 1 Hydrogen")); EXPECT_TRUE(coords.contains( "O -2.000000 0 3.000000 1 -4.000000 1 Oxygen")); // Test the default reset -- trigger a reset, then verify that testFilePath // is cleared (we set it earlier) QPushButton *defaultsButton(widget.findChild<QPushButton*>("defaultsButton")); defaultsButton->click(); flushEvents(); EXPECT_TRUE(testFilePathWidget->fileName().isEmpty()); EXPECT_EQ(filePathEdit->document()->toPlainText().toStdString(), std::string("Reference file '' does not exist.")); // Test the autogenerated title: QLineEdit *titleEdit = widget.findChild<QLineEdit*>("Title"); EXPECT_EQ(titleEdit->placeholderText().toStdString(), std::string("CHO | Equilibrium Geometry | B3LYP/6-31G(d)")); }
int main(int argc, char* argv[]){ registerHydrodynamicsModels(); gengetopt_args_info args_info; std::string dumpFileName; std::string mdFileName; std::string prefix; //parse the command line option if (cmdline_parser (argc, argv, &args_info) != 0) { exit(1) ; } //get the dumpfile name and meta-data file name if (args_info.input_given){ dumpFileName = args_info.input_arg; } else { strcpy( painCave.errMsg, "No input file name was specified.\n" ); painCave.isFatal = 1; simError(); } if (args_info.output_given){ prefix = args_info.output_arg; } else { prefix = getPrefix(dumpFileName); } std::string outputFilename = prefix + ".diff"; //parse md file and set up the system SimCreator creator; SimInfo* info = creator.createSim(dumpFileName, true); SimInfo::MoleculeIterator mi; Molecule* mol; Molecule::IntegrableObjectIterator ii; StuntDouble* sd; Mat3x3d identMat; identMat(0,0) = 1.0; identMat(1,1) = 1.0; identMat(2,2) = 1.0; Globals* simParams = info->getSimParams(); RealType temperature(0.0); RealType viscosity(0.0); if (simParams->haveViscosity()) { viscosity = simParams->getViscosity(); } else { sprintf(painCave.errMsg, "viscosity must be set\n"); painCave.isFatal = 1; simError(); } if (simParams->haveTargetTemp()) { temperature = simParams->getTargetTemp(); } else { sprintf(painCave.errMsg, "target temperature must be set\n"); painCave.isFatal = 1; simError(); } std::map<std::string, SDShape> uniqueStuntDoubles; for (mol = info->beginMolecule(mi); mol != NULL; mol = info->nextMolecule(mi)) { for (sd = mol->beginIntegrableObject(ii); sd != NULL; sd = mol->nextIntegrableObject(ii)) { if (uniqueStuntDoubles.find(sd->getType()) == uniqueStuntDoubles.end()) { sd->setPos(V3Zero); sd->setA(identMat); if (sd->isRigidBody()) { RigidBody* rb = static_cast<RigidBody*>(sd); rb->updateAtoms(); } SDShape tmp; tmp.shape = ShapeBuilder::createShape(sd); tmp.sd = sd; uniqueStuntDoubles.insert(std::map<std::string, SDShape>::value_type(sd->getType(), tmp)); } } } std::map<std::string, SDShape>::iterator si; for (si = uniqueStuntDoubles.begin(); si != uniqueStuntDoubles.end(); ++si) { HydrodynamicsModel* model; Shape* shape = si->second.shape; StuntDouble* sd = si->second.sd;; if (args_info.model_given) { model = HydrodynamicsModelFactory::getInstance()->createHydrodynamicsModel(args_info.model_arg, sd, info); } else if (shape->hasAnalyticalSolution()) { model = new AnalyticalModel(sd, info); } else { model = new BeadModel(sd, info); } model->init(); std::ofstream ofs; std::stringstream outputBeads; outputBeads << prefix << "_" << model->getStuntDoubleName() << ".xyz"; ofs.open(outputBeads.str().c_str()); model->writeBeads(ofs); ofs.close(); //if beads option is turned on, skip the calculation if (!args_info.beads_flag) { model->calcHydroProps(shape, viscosity, temperature); std::ofstream outputDiff; outputDiff.open(outputFilename.c_str()); model->writeHydroProps(outputDiff); outputDiff.close(); } delete model; } //MemoryUtils::deletePointers(shapes); delete info; }
DistanceFinder::DistanceFinder(SimInfo* info) : info_(info) { nObjects_.push_back(info_->getNGlobalAtoms()+info_->getNGlobalRigidBodies()); nObjects_.push_back(info_->getNGlobalBonds()); nObjects_.push_back(info_->getNGlobalBends()); nObjects_.push_back(info_->getNGlobalTorsions()); nObjects_.push_back(info_->getNGlobalInversions()); stuntdoubles_.resize(nObjects_[STUNTDOUBLE]); bonds_.resize(nObjects_[BOND]); bends_.resize(nObjects_[BEND]); torsions_.resize(nObjects_[TORSION]); inversions_.resize(nObjects_[INVERSION]); SimInfo::MoleculeIterator mi; Molecule::AtomIterator ai; Molecule::RigidBodyIterator rbIter; Molecule::BondIterator bondIter; Molecule::BendIterator bendIter; Molecule::TorsionIterator torsionIter; Molecule::InversionIterator inversionIter; Molecule* mol; Atom* atom; RigidBody* rb; Bond* bond; Bend* bend; Torsion* torsion; Inversion* inversion; for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) { for(atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) { stuntdoubles_[atom->getGlobalIndex()] = atom; } for (rb = mol->beginRigidBody(rbIter); rb != NULL; rb = mol->nextRigidBody(rbIter)) { stuntdoubles_[rb->getGlobalIndex()] = rb; } for (bond = mol->beginBond(bondIter); bond != NULL; bond = mol->nextBond(bondIter)) { bonds_[bond->getGlobalIndex()] = bond; } for (bend = mol->beginBend(bendIter); bend != NULL; bend = mol->nextBend(bendIter)) { bends_[bend->getGlobalIndex()] = bend; } for (torsion = mol->beginTorsion(torsionIter); torsion != NULL; torsion = mol->nextTorsion(torsionIter)) { torsions_[torsion->getGlobalIndex()] = torsion; } for (inversion = mol->beginInversion(inversionIter); inversion != NULL; inversion = mol->nextInversion(inversionIter)) { inversions_[inversion->getGlobalIndex()] = inversion; } } }
void CmfSaver::_encodeExtSection (Molecule &mol, const Mapping &mapping) { bool ext_printed = false; // Process all R-sites for (int i = mol.vertexBegin(); i != mol.vertexEnd(); i = mol.vertexNext(i)) { if (mol.isRSite(i)) { int count = 0; while (mol.getRSiteAttachmentPointByOrder(i, count) >= 0) count++; if (count == 0) continue; if (!ext_printed) { _encode(CMF_EXT); ext_printed = true; } _encode(CMF_RSITE_ATTACHMENTS); int idx = mapping.atom_mapping->at(i); if (idx < 0) throw Error("Internal error: idx < 0"); _output->writePackedUInt(idx); _output->writePackedUInt(count); for (int j = 0; j < count; j++) { int att = mol.getRSiteAttachmentPointByOrder(i, j); int idx2 = mapping.atom_mapping->at(att); if (idx2 < 0) throw Error("Internal error: idx2 < 0"); _output->writePackedUInt(idx2); } } } bool need_print_ext = mol.generic_sgroups.size() > 0 || mol.data_sgroups.size() > 0 || mol.superatoms.size() > 0 || mol.repeating_units.size() > 0 || mol.multiple_groups.size() > 0; if (need_print_ext && !ext_printed) { _encode(CMF_EXT); ext_printed = true; } for (int i = mol.generic_sgroups.begin(); i != mol.generic_sgroups.end(); i = mol.generic_sgroups.next(i)) { BaseMolecule::SGroup &sg = mol.generic_sgroups[i]; _encode(CMF_GENERICSGROUP); _encodeBaseSGroup(mol, sg, mapping); } for (int i = mol.data_sgroups.begin(); i != mol.data_sgroups.end(); i = mol.data_sgroups.next(i)) { BaseMolecule::DataSGroup &sd = mol.data_sgroups[i]; _encode(CMF_DATASGROUP); _encodeBaseSGroup(mol, sd, mapping); _encodeString(sd.description); _encodeString(sd.data); // Pack detached, relative, display_units, and sd.dasp_pos into one byte if (sd.dasp_pos < 0 || sd.dasp_pos > 9) throw Error("DataSGroup dasp_pos field should be less than 10: %d", sd.dasp_pos); byte packed = (sd.dasp_pos & 0x0F) | (sd.detached << 4) | (sd.relative << 5) | (sd.display_units << 6); _output->writeByte(packed); } for (int i = mol.superatoms.begin(); i != mol.superatoms.end(); i = mol.superatoms.next(i)) { BaseMolecule::Superatom &sa = mol.superatoms[i]; _encode(CMF_SUPERATOM); _encodeBaseSGroup(mol, sa, mapping); _encodeString(sa.subscript); if (sa.bond_idx < -1) throw Error("internal error: SGroup bond index is invalid: %d", sa.bond_idx); _output->writePackedUInt(sa.bond_idx + 1); } for (int i = mol.repeating_units.begin(); i != mol.repeating_units.end(); i = mol.repeating_units.next(i)) { BaseMolecule::RepeatingUnit &su = mol.repeating_units[i]; _encode(CMF_REPEATINGUNIT); _encodeBaseSGroup(mol, su, mapping); _encodeString(su.subscript); _output->writePackedUInt(su.connectivity); } for (int i = mol.multiple_groups.begin(); i != mol.multiple_groups.end(); i = mol.multiple_groups.next(i)) { BaseMolecule::MultipleGroup &sm = mol.multiple_groups[i]; _encode(CMF_MULTIPLEGROUP); _encodeBaseSGroup(mol, sm, mapping); _encodeUIntArray(sm.parent_atoms, *mapping.atom_mapping); if (sm.multiplier < 0) throw Error("internal error: SGroup multiplier is negative: %d", sm.multiplier); _output->writePackedUInt(sm.multiplier); } // Encode mappings to restore if (save_mapping) { if (!ext_printed) { _encode(CMF_EXT); ext_printed = true; } _encode(CMF_MAPPING); _encodeUIntArraySkipNegative(*mapping.atom_mapping); _encodeUIntArraySkipNegative(*mapping.bond_mapping); } }
void CmfLoader::loadMolecule (Molecule &mol) { int code; mol.clear(); QS_DEF(Array<int>, cycle_numbers); QS_DEF(Array<int>, atom_stack); _atoms.clear(); _bonds.clear(); _pseudo_labels.clear(); _attachments.clear(); cycle_numbers.clear(); atom_stack.clear(); bool first_atom = true; if (!_getNextCode(code)) return; bool has_ext_part = false; /* Main loop */ do { _BondDesc *bond = 0; if (code > CMF_ALPHABET_SIZE) throw Error("unexpected code"); if (code == CMF_TERMINATOR) break; if (code == CMF_EXT) { has_ext_part = true; // Ext part has to be read till CMF_TERMINATOR break; } if (!first_atom) { int number; while (_readCycleNumber(code, number)) { while (cycle_numbers.size() <= number) cycle_numbers.push(-1); if (cycle_numbers[number] >= 0) throw Error("cycle #%d already in use", number); cycle_numbers[number] = atom_stack.top(); if (!_getNextCode(code)) break; } } if (code == CMF_SEPARATOR) { atom_stack.pop(); first_atom = true; if (!_getNextCode(code)) break; continue; } if (code == CMF_OPEN_BRACKET) { atom_stack.push(atom_stack.top()); if (!_getNextCode(code)) break; continue; } if (code == CMF_CLOSE_BRACKET) { atom_stack.pop(); if (!_getNextCode(code)) break; continue; } if (!first_atom) { bond = &_bonds.push(); bond->beg = atom_stack.top(); } if (bond != 0) { _readBond(code, *bond); int number; if (_readCycleNumber(code, number)) { if (cycle_numbers[number] < 0) throw Error("bad cycle number after bond symbol"); bond->end = cycle_numbers[number]; cycle_numbers[number] = -1; if (!_getNextCode(code)) break; continue; } } _AtomDesc &atom = _atoms.push(); if (!first_atom) atom_stack.pop(); atom_stack.push(_atoms.size() - 1); first_atom = false; if (bond != 0) bond->end = _atoms.size() - 1; memset(&atom, 0, sizeof(_AtomDesc)); atom.hydrogens = -1; atom.valence = -1; atom.pseudo_atom_idx = -1; atom.rsite = false; if (code > 0 && (code < ELEM_MAX || code == CMF_PSEUDOATOM || code == CMF_RSITE || code == CMF_RSITE_EXT)) { if (!_readAtom(code, atom, _atoms.size() - 1)) break; continue; } if (!_getNextCode(code)) break; } while (true); // if have internal decoder, finish it /* if (_decoder_obj.get() != 0) _decoder_obj->finish(); */ /* Reading finished, filling molecule */ int i; for (i = 0; i < _atoms.size(); i++) { mol.addAtom(_atoms[i].label); if (_atoms[i].pseudo_atom_idx >= 0) mol.setPseudoAtom(i, _pseudo_labels.at(_atoms[i].pseudo_atom_idx)); if (_atoms[i].rsite_bits > 0) mol.setRSiteBits(i, _atoms[i].rsite_bits); mol.setAtomCharge(i, _atoms[i].charge); mol.setAtomIsotope(i, _atoms[i].isotope); if (_atoms[i].hydrogens >= 0) mol.setImplicitH(i, _atoms[i].hydrogens); mol.setAtomRadical(i, _atoms[i].radical); if (_atoms[i].highlighted) mol.highlightAtom(i); } for (i = 0; i < _bonds.size(); i++) { int type = _bonds[i].type; int beg = _bonds[i].beg; int end = _bonds[i].end; int tmp; if (_bonds[i].swap) __swap(beg, end, tmp); int idx = mol.addBond_Silent(beg, end, type); if (_bonds[i].in_ring) mol.setEdgeTopology(idx, TOPOLOGY_RING); else mol.setEdgeTopology(idx, TOPOLOGY_CHAIN); if (_bonds[i].direction != 0) mol.setBondDirection(idx, _bonds[i].direction); if (_bonds[i].highlighted) mol.highlightBond(idx); } for (i = 0; i < _attachments.size(); i++) mol.addAttachmentPoint(_attachments[i].index, _attachments[i].atom); mol.validateEdgeTopologies(); if (has_ext_part) _readExtSection(mol); if (atom_flags != 0) { atom_flags->clear(); for (i = 0; i < _atoms.size(); i++) atom_flags->push(_atoms[i].flags); } if (bond_flags != 0) { bond_flags->clear(); for (i = 0; i < _bonds.size(); i++) bond_flags->push(_bonds[i].flags); } if (!skip_cistrans) { for (i = 0; i < _bonds.size(); i++) { if (_bonds[i].cis_trans != 0) { int parity = _bonds[i].cis_trans; if (parity > 0) mol.cis_trans.setParity(i, _bonds[i].cis_trans); else mol.cis_trans.ignore(i); mol.cis_trans.restoreSubstituents(i); } } } if (!skip_valence) { for (i = 0; i < _atoms.size(); i++) { if (_atoms[i].valence >= 0) mol.setValence(i, _atoms[i].valence); } } if (!skip_stereocenters) { for (i = 0; i < _atoms.size(); i++) { if (_atoms[i].stereo_type != 0) mol.stereocenters.add(i, _atoms[i].stereo_type, _atoms[i].stereo_group, _atoms[i].stereo_invert_pyramid); } } for (i = 0; i < _atoms.size(); i++) { if (_atoms[i].allene_stereo_parity != 0) { int left, right, subst[4]; bool pure_h[4]; int parity = _atoms[i].allene_stereo_parity; int tmp; if (!MoleculeAlleneStereo::possibleCenter(mol, i, left, right, subst, pure_h)) throw Error("invalid molecule allene stereo marker"); if (subst[1] != -1 && subst[1] < subst[0]) __swap(subst[1], subst[0], tmp); if (subst[3] != -1 && subst[3] < subst[2]) __swap(subst[3], subst[2], tmp); if (pure_h[0]) { __swap(subst[1], subst[0], tmp); parity = 3 - parity; } if (pure_h[2]) { __swap(subst[2], subst[3], tmp); parity = 3 - parity; } mol.allene_stereo.add(i, left, right, subst, parity); } } // for loadXyz() _mol = &mol; // Check if atom mapping was used if (has_mapping) { // Compute inv_atom_mapping_to_restore inv_atom_mapping_to_restore.clear_resize(atom_mapping_to_restore.size()); for (int i = 0; i < atom_mapping_to_restore.size(); i++) inv_atom_mapping_to_restore[atom_mapping_to_restore[i]] = i; // Compute inv_bond_mapping_to_restore inv_bond_mapping_to_restore.clear_resize(bond_mapping_to_restore.size()); for (int i = 0; i < bond_mapping_to_restore.size(); i++) inv_bond_mapping_to_restore[bond_mapping_to_restore[i]] = i; QS_DEF(Molecule, tmp); tmp.makeEdgeSubmolecule(mol, atom_mapping_to_restore, bond_mapping_to_restore, NULL); mol.clone(tmp, NULL, NULL); } }
void CmfSaver::_encodeAtom (Molecule &mol, int idx, const int *mapping) { int number = 0; if (mol.isPseudoAtom(idx)) { const char *str = mol.getPseudoAtom(idx); size_t len = strlen(str); if (len < 1) throw Error("empty pseudo-atom"); if (len > 255) throw Error("pseudo-atom labels %d characters long are not supported (255 is the limit)", len); _encode(CMF_PSEUDOATOM); _encode((byte)len); do { _encode(*str); } while (*(++str) != 0); } else if (mol.isRSite(idx)) { int bits = mol.getRSiteBits(idx); if (bits > 255) { _encode(CMF_RSITE_EXT); _output->writePackedUInt((unsigned int)bits); } else { _encode(CMF_RSITE); _encode(bits); } } else { number = mol.getAtomNumber(idx); if (number <= 0 || number >= ELEM_MAX) throw Error("unexpected atom label"); _encode(number); } int charge = mol.getAtomCharge(idx); if (charge != 0) { int charge2 = charge - CMF_MIN_CHARGE; if (charge2 < 0 || charge2 >= CMF_NUM_OF_CHARGES) { _encode(CMF_CHARGE_EXT); int charge3 = charge + 128; if (charge3 < 0 || charge >= 256) throw Error("unexpected atom charge: %d", charge); _encode(charge3); } else _encode(charge2 + CMF_CHARGES); } int isotope = mol.getAtomIsotope(idx); if (isotope > 0) { int deviation = isotope - Element::getDefaultIsotope(number); if (deviation == 0) _encode(CMF_ISOTOPE_ZERO); else if (deviation == 1) _encode(CMF_ISOTOPE_PLUS1); else if (deviation == 2) _encode(CMF_ISOTOPE_PLUS2); else if (deviation == -1) _encode(CMF_ISOTOPE_MINUS1); else if (deviation == -2) _encode(CMF_ISOTOPE_MINUS2); else { deviation += 100; if (deviation < 0 || deviation > 255) throw Error("unexpected %s isotope: %d", Element::toString(number), isotope); _encode(CMF_ISOTOPE_OTHER); _encode(deviation); } } int radical = 0; if (!mol.isPseudoAtom(idx) && !mol.isRSite(idx)) { try { radical = mol.getAtomRadical(idx); } catch (Element::Error) { } } if (radical > 0) { if (radical == RADICAL_SINGLET) _encode(CMF_RADICAL_SINGLET); else if (radical == RADICAL_DOUBLET) _encode(CMF_RADICAL_DOUBLET); else if (radical == RADICAL_TRIPLET) _encode(CMF_RADICAL_TRIPLET); else throw Error("bad radical value: %d", radical); } MoleculeStereocenters &stereo = mol.stereocenters; int stereo_type = stereo.getType(idx); if (stereo_type == MoleculeStereocenters::ATOM_ANY) _encode(CMF_STEREO_ANY); else if (stereo_type != 0) { bool rigid; int code; const int *pyramid = stereo.getPyramid(idx); if (pyramid[3] == -1) rigid = MoleculeStereocenters::isPyramidMappingRigid(pyramid, 3, mapping); else rigid = MoleculeStereocenters::isPyramidMappingRigid(pyramid, 4, mapping); if (stereo_type == MoleculeStereocenters::ATOM_ABS) code = CMF_STEREO_ABS_0; else { int group = stereo.getGroup(idx); if (group < 1 || group > CMF_MAX_STEREOGROUPS) throw Error("stereogroup number %d out of range", group); if (stereo_type == MoleculeStereocenters::ATOM_AND) code = CMF_STEREO_AND_0 + group - 1; else // stereo_type == MoleculeStereocenters::ATOM_OR code = CMF_STEREO_OR_0 + group - 1; } if (!rigid) // CMF_STEREO_*_0 -> CMF_STEREO_*_1 code += CMF_MAX_STEREOGROUPS * 2 + 1; _encode(code); } if (mol.allene_stereo.isCenter(idx)) { int left, right, parity, subst[4]; mol.allene_stereo.getByAtomIdx(idx, left, right, subst, parity); if (subst[1] != -1 && mapping[subst[1]] != -1 && mapping[subst[1]] < mapping[subst[0]]) parity = 3 - parity; if (subst[3] != -1 && mapping[subst[3]] != -1 && mapping[subst[3]] < mapping[subst[2]]) parity = 3 - parity; if (parity == 1) _encode(CMF_STEREO_ALLENE_0); else _encode(CMF_STEREO_ALLENE_1); } int impl_h = 0; if (!mol.isPseudoAtom(idx) && !mol.isRSite(idx) && Molecule::shouldWriteHCount(mol, idx)) { try { impl_h = mol.getImplicitH(idx); if (impl_h < 0 || impl_h > CMF_MAX_IMPLICIT_H) throw Error("implicit hydrogen count %d out of range", impl_h); _encode(CMF_IMPLICIT_H + impl_h); } catch (Element::Error) { } } if (!mol.isRSite(idx) && !mol.isPseudoAtom(idx)) { if (mol.getAtomAromaticity(idx) == ATOM_AROMATIC && (charge != 0 || (number != ELEM_C && number != ELEM_O))) { try { int valence = mol.getAtomValence(idx); if (valence < 0 || valence > CMF_MAX_VALENCE) { _encode(CMF_VALENCE_EXT); _output->writePackedUInt(valence); } else _encode(CMF_VALENCE + valence); } catch (Element::Error) { } } } int i; for (i = 1; i <= mol.attachmentPointCount(); i++) { int j, aidx; for (j = 0; (aidx = mol.getAttachmentPoint(i, j)) != -1; j++) if (aidx == idx) { _encode(CMF_ATTACHPT); _encode(i); } } if (atom_flags != 0) { int i, flags = atom_flags[idx]; for (i = 0; i < CMF_NUM_OF_ATOM_FLAGS; i++) if (flags & (1 << i)) _encode(CMF_ATOM_FLAGS + i); } if (save_highlighting) if (mol.isAtomHighlighted(idx)) _encode(CMF_HIGHLIGHTED); }
/* * Generate, attempt and accept or reject a Monte Carlo move. * * A complete move involve the following stepts: * * 1) choose a molecule-i randomly; * 2) find molecule-j of the same type as i, and monomer pairs satisfying * the distance criterion exist; * 3) Delete the two rebridging monomers; first molecule-i, then -j. * 4) Rebuild molecule-j, then -i. (in the JCP paper, the order is chosen * at random.) * */ bool CfbDoubleRebridgeMove::move() { bool found, accept; int iMol, jMol, sign, beginId, nEnd, i; Molecule *iPtr; // pointer to i-th molecule Molecule *jPtr; // pointer to j-th molecule int *bonds; // bond types of a consequtive blocks of atoms Atom *thisPtr; // pointer to the current end atom Atom *tempPtr; // pointer used for swap atom positions double rosenbluth, rosen_r, rosen_f; double energy, energy_r, energy_f; double po2n, pn2o; Vector swapPos; incrementNAttempt(); // Choose a random direction if (random().uniform(0.0, 1.0) > 0.5) sign = +1; else sign = -1; // Search for a pair of candidate sites and calculate probability found = forwardScan(sign, iMol, jMol, beginId, po2n); if (!found) return found; iPtr = &(system().molecule(speciesId_, iMol)); jPtr = &(system().molecule(speciesId_, jMol)); // Save positions for atoms to be regrown thisPtr = &(iPtr->atom(beginId)); tempPtr = &(jPtr->atom(beginId)); for (i = 0; i < nRegrow_; ++i) { iOldPos_[i] = thisPtr->position(); jOldPos_[i] = tempPtr->position(); thisPtr += sign; tempPtr += sign; } // Prepare for the rebridge move accept = false; bonds = new int[nRegrow_ + 1]; if (sign == +1) { for (i = 0; i < nRegrow_ + 1; ++i) bonds[i] = iPtr->bond(beginId - 1 + nRegrow_ - i).typeId(); } else { for (i = 0; i < nRegrow_ + 1; ++i) bonds[i] = iPtr->bond(beginId - nRegrow_ + i).typeId(); } // Deleting atoms: first i-th molecule, then j-th rosen_r = 1.0; energy_r = 0.0; thisPtr = &(iPtr->atom(beginId + (nRegrow_-1)*sign)); deleteSequence(nRegrow_, sign, thisPtr, bonds, rosenbluth, energy); rosen_r *= rosenbluth; energy_r += energy; thisPtr = &(jPtr->atom(beginId + (nRegrow_-1)*sign)); deleteSequence(nRegrow_, sign, thisPtr, bonds, rosenbluth, energy); rosen_r *= rosenbluth; energy_r += energy; // Swap the atom positions of the dangling end if (sign == +1) nEnd = iPtr->nAtom() - beginId - nRegrow_; else nEnd = beginId + 1 - nRegrow_; thisPtr = &(iPtr->atom(beginId + nRegrow_*sign)); tempPtr = &(jPtr->atom(beginId + nRegrow_*sign)); for (i = 0; i < nEnd; ++i) { swapPos = thisPtr->position(); //system().moveAtom(*thisPtr, tempPtr->position()); thisPtr->position() = tempPtr->position(); #ifndef INTER_NOPAIR system().pairPotential().updateAtomCell(*thisPtr); #endif //system().moveAtom(*tempPtr, swapPos); tempPtr->position() = swapPos; #ifndef INTER_NOPAIR system().pairPotential().updateAtomCell(*tempPtr); #endif thisPtr += sign; tempPtr += sign; } // Regrow atoms: first j-th molecule, then i-th rosen_f = 1.0; energy_f = 0.0; thisPtr = &(jPtr->atom(beginId)); addSequence(nRegrow_, sign, thisPtr, bonds, rosenbluth, energy); rosen_f *= rosenbluth; energy_f += energy; thisPtr = &(iPtr->atom(beginId)); addSequence(nRegrow_, sign, thisPtr, bonds, rosenbluth, energy); rosen_f *= rosenbluth; energy_f += energy; // Reverse scan found = reverseScan(sign, iMol, jMol, beginId - sign, pn2o); // Decide whether to accept or reject if (found) accept = random().metropolis(rosen_f * pn2o / rosen_r / po2n); else accept = false; if (accept) { // Increment counter for accepted moves of this class. incrementNAccept(); } else { // If the move is rejected, restore nRegrow_ positions thisPtr = &(iPtr->atom(beginId)); tempPtr = &(jPtr->atom(beginId)); for (i = 0; i < nRegrow_; ++i) { //system().moveAtom(*thisPtr, iOldPos_[i]); thisPtr->position() = iOldPos_[i]; #ifndef INTER_NOPAIR system().pairPotential().updateAtomCell(*thisPtr); #endif //system().moveAtom(*tempPtr, jOldPos_[i]); tempPtr->position() = jOldPos_[i]; #ifndef INTER_NOPAIR system().pairPotential().updateAtomCell(*tempPtr); #endif thisPtr += sign; tempPtr += sign; } // Restore atom positions at the dangling end thisPtr = &(iPtr->atom(beginId + nRegrow_*sign)); tempPtr = &(jPtr->atom(beginId + nRegrow_*sign)); for (i = 0; i < nEnd; ++i) { swapPos = thisPtr->position(); //system().moveAtom(*thisPtr, tempPtr->position()); thisPtr->position() = tempPtr->position(); #ifndef INTER_NOPAIR system().pairPotential().updateAtomCell(*thisPtr); #endif //system().moveAtom(*tempPtr, swapPos); tempPtr->position() = swapPos; #ifndef INTER_NOPAIR system().pairPotential().updateAtomCell(*tempPtr); #endif thisPtr += sign; tempPtr += sign; } } // Release memory delete [] bonds; return accept; }
void CmfSaver::_encodeBond (Molecule &mol, int idx, const int *mapping) { int order = mol.getBondOrder(idx); if (order == BOND_SINGLE) { if (mol.getBondTopology(idx) == TOPOLOGY_RING) _encode(CMF_BOND_SINGLE_RING); else _encode(CMF_BOND_SINGLE_CHAIN); } else if (order == BOND_DOUBLE) { int parity = mol.cis_trans.getParity(idx); if (parity != 0) { int mapped_parity = MoleculeCisTrans::applyMapping(parity, mol.cis_trans.getSubstituents(idx), mapping, true); if (mapped_parity == MoleculeCisTrans::CIS) { if (mol.getBondTopology(idx) == TOPOLOGY_RING) _encode(CMF_BOND_DOUBLE_RING_CIS); else _encode(CMF_BOND_DOUBLE_CHAIN_CIS); } else // mapped_parity == MoleculeCisTrans::TRANS { if (mol.getBondTopology(idx) == TOPOLOGY_RING) _encode(CMF_BOND_DOUBLE_RING_TRANS); else _encode(CMF_BOND_DOUBLE_CHAIN_TRANS); } } else if (mol.cis_trans.isIgnored(idx)) { if (mol.getBondTopology(idx) == TOPOLOGY_RING) _encode(CMF_BOND_DOUBLE_IGNORED_CIS_TRANS_RING); else _encode(CMF_BOND_DOUBLE_IGNORED_CIS_TRANS_CHAIN); } else { if (mol.getBondTopology(idx) == TOPOLOGY_RING) _encode(CMF_BOND_DOUBLE_RING); else _encode(CMF_BOND_DOUBLE_CHAIN); } } else if (order == BOND_TRIPLE) { if (mol.getBondTopology(idx) == TOPOLOGY_RING) _encode(CMF_BOND_TRIPLE_RING); else _encode(CMF_BOND_TRIPLE_CHAIN); } else if (order == BOND_AROMATIC) _encode(CMF_BOND_AROMATIC); else throw Error("bad bond order: %d", order); if (bond_flags != 0) { int i, flags = bond_flags[idx]; for (i = 0; i < CMF_NUM_OF_BOND_FLAGS; i++) if (flags & (1 << i)) _encode(CMF_BOND_FLAGS + i); } if (save_highlighting) if (mol.isBondHighlighted(idx)) _encode(CMF_HIGHLIGHTED); }
void P2OrderParameter::process() { Molecule* mol; RigidBody* rb; SimInfo::MoleculeIterator mi; Molecule::RigidBodyIterator rbIter; StuntDouble* sd1; StuntDouble* sd2; int ii; int jj; int vecCount; bool usePeriodicBoundaryConditions_ = info_->getSimParams()->getUsePeriodicBoundaryConditions(); DumpReader reader(info_, dumpFilename_); int nFrames = reader.getNFrames(); for (int i = 0; i < nFrames; i += step_) { reader.readFrame(i); currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot(); for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) { //change the positions of atoms which belong to the rigidbodies for (rb = mol->beginRigidBody(rbIter); rb != NULL; rb = mol->nextRigidBody(rbIter)) { rb->updateAtoms(); } } Mat3x3d orderTensor(0.0); vecCount = 0; seleMan1_.setSelectionSet(evaluator1_.evaluate()); if (doVect_) { for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL; sd1 = seleMan1_.nextSelected(ii)) { if (sd1->isDirectional()) { Vector3d vec = sd1->getA().transpose()*V3Z; vec.normalize(); orderTensor += outProduct(vec, vec); vecCount++; } } orderTensor /= vecCount; } else { if (doOffset_) { for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL; sd1 = seleMan1_.nextSelected(ii)) { // This will require careful rewriting if StaticProps is // ever parallelized. For an example, see // Thermo::getTaggedAtomPairDistance int sd2Index = sd1->getGlobalIndex() + seleOffset_; sd2 = info_->getIOIndexToIntegrableObject(sd2Index); Vector3d vec = sd1->getPos() - sd2->getPos(); if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(vec); vec.normalize(); orderTensor +=outProduct(vec, vec); vecCount++; } orderTensor /= vecCount; } else { seleMan2_.setSelectionSet(evaluator2_.evaluate()); if (seleMan1_.getSelectionCount() != seleMan2_.getSelectionCount() ) { sprintf( painCave.errMsg, "In frame %d, the number of selected StuntDoubles are\n" "\tnot the same in --sele1 and sele2\n", i); painCave.severity = OPENMD_INFO; painCave.isFatal = 0; simError(); } for (sd1 = seleMan1_.beginSelected(ii), sd2 = seleMan2_.beginSelected(jj); sd1 != NULL && sd2 != NULL; sd1 = seleMan1_.nextSelected(ii), sd2 = seleMan2_.nextSelected(jj)) { Vector3d vec = sd1->getPos() - sd2->getPos(); if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(vec); vec.normalize(); orderTensor +=outProduct(vec, vec); vecCount++; } orderTensor /= vecCount; } } if (vecCount == 0) { sprintf( painCave.errMsg, "In frame %d, the number of selected vectors was zero.\n" "\tThis will not give a meaningful order parameter.", i); painCave.severity = OPENMD_ERROR; painCave.isFatal = 1; simError(); } orderTensor -= (RealType)(1.0/3.0) * Mat3x3d::identity(); Vector3d eigenvalues; Mat3x3d eigenvectors; Mat3x3d::diagonalize(orderTensor, eigenvalues, eigenvectors); int which(-1); RealType maxEval = 0.0; for(int k = 0; k< 3; k++) { if(fabs(eigenvalues[k]) > maxEval) { which = k; maxEval = fabs(eigenvalues[k]); } } RealType p2 = 1.5 * maxEval; //the eigen vector is already normalized in SquareMatrix3::diagonalize Vector3d director = eigenvectors.getColumn(which); if (director[0] < 0) { director.negate(); } RealType angle = 0.0; vecCount = 0; if (doVect_) { for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL; sd1 = seleMan1_.nextSelected(ii)) { if (sd1->isDirectional()) { Vector3d vec = sd1->getA().transpose()*V3Z; vec.normalize(); angle += acos(dot(vec, director)); vecCount++; } } angle = angle/(vecCount*NumericConstant::PI)*180.0; } else { if (doOffset_) { for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL; sd1 = seleMan1_.nextSelected(ii)) { // This will require careful rewriting if StaticProps is // ever parallelized. For an example, see // Thermo::getTaggedAtomPairDistance int sd2Index = sd1->getGlobalIndex() + seleOffset_; sd2 = info_->getIOIndexToIntegrableObject(sd2Index); Vector3d vec = sd1->getPos() - sd2->getPos(); if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(vec); vec.normalize(); angle += acos(dot(vec, director)) ; vecCount++; } angle = angle / (vecCount * NumericConstant::PI) * 180.0; } else { for (sd1 = seleMan1_.beginSelected(ii), sd2 = seleMan2_.beginSelected(jj); sd1 != NULL && sd2 != NULL; sd1 = seleMan1_.nextSelected(ii), sd2 = seleMan2_.nextSelected(jj)) { Vector3d vec = sd1->getPos() - sd2->getPos(); if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(vec); vec.normalize(); angle += acos(dot(vec, director)) ; vecCount++; } angle = angle / (vecCount * NumericConstant::PI) * 180.0; } } OrderParam param; param.p2 = p2; param.director = director; param.angle = angle; orderParams_.push_back(param); } writeP2(); }
void CmfSaver::saveMolecule (Molecule &mol) { /* Walk molecule */ DfsWalk walk(mol); QS_DEF(Array<int>, mapping); if (_ext_encoder != 0) _ext_encoder->start(); walk.walk(); /* Get walking sequence */ const Array<DfsWalk::SeqElem> &v_seq = walk.getSequence(); /* Calculate mapping to the encoded molecule */ walk.calcMapping(mapping); QS_DEF(Array<int>, branch_counters); QS_DEF(Array<int>, cycle_numbers); branch_counters.clear_resize(mol.vertexEnd()); branch_counters.zerofill(); cycle_numbers.clear(); _atom_sequence.clear(); QS_DEF(Array<int>, bond_mapping); bond_mapping.clear_resize(mol.edgeEnd()); bond_mapping.fffill(); int bond_index = 0; /* Encode first atom */ if (v_seq.size() > 0) { _encodeAtom(mol, v_seq[0].idx, mapping.ptr()); _atom_sequence.push(v_seq[0].idx); int j, openings = walk.numOpenings(v_seq[0].idx); for (j = 0; j < openings; j++) { cycle_numbers.push(v_seq[0].idx); _encodeCycleNumer(j); } } /* Main cycle */ int i, j, k; for (i = 1; i < v_seq.size(); i++) { int v_idx = v_seq[i].idx; int e_idx = v_seq[i].parent_edge; int v_prev_idx = v_seq[i].parent_vertex; bool write_atom = true; if (v_prev_idx >= 0) { if (walk.numBranches(v_prev_idx) > 1) if (branch_counters[v_prev_idx] > 0) _encode(CMF_CLOSE_BRACKET); int branches = walk.numBranches(v_prev_idx); if (branches > 1) if (branch_counters[v_prev_idx] < branches - 1) _encode(CMF_OPEN_BRACKET); branch_counters[v_prev_idx]++; if (branch_counters[v_prev_idx] > branches) throw Error("unexpected branch"); _encodeBond(mol, e_idx, mapping.ptr()); bond_mapping[e_idx] = bond_index++; if (save_bond_dirs) { int dir = mol.getBondDirection(e_idx); if (dir != 0) { if (dir == BOND_UP) dir = CMF_BOND_UP; else if (dir == BOND_DOWN) dir = CMF_BOND_DOWN; else dir = CMF_BOND_EITHER; const Edge &edge = mol.getEdge(e_idx); if (edge.beg == v_prev_idx && edge.end == v_idx) ; else if (edge.beg == v_idx && edge.end == v_prev_idx) _encode(CMF_BOND_SWAP_ENDS); else throw Error("internal"); _encode(dir); } } if (walk.isClosure(e_idx)) { for (j = 0; j < cycle_numbers.size(); j++) if (cycle_numbers[j] == v_idx) break; if (j == cycle_numbers.size()) throw Error("cycle number not found"); _encodeCycleNumer(j); cycle_numbers[j] = -1; write_atom = false; } } else _encode(CMF_SEPARATOR); if (write_atom) { _encodeAtom(mol, v_idx, mapping.ptr()); _atom_sequence.push(v_idx); int openings = walk.numOpenings(v_idx); for (j = 0; j < openings; j++) { for (k = 0; k < cycle_numbers.size(); k++) if (cycle_numbers[k] == -1) break; if (k == cycle_numbers.size()) cycle_numbers.push(v_idx); else cycle_numbers[k] = v_idx; _encodeCycleNumer(k); } } } Mapping mapping_group; mapping_group.atom_mapping = &mapping; mapping_group.bond_mapping = &bond_mapping; _encodeExtSection(mol, mapping_group); _encode(CMF_TERMINATOR); // if have internal encoder, finish it if (_encoder_obj.get() != 0) _encoder_obj->finish(); // for saveXyz() _mol = &mol; }
void NPT::moveB(void) { SimInfo::MoleculeIterator i; Molecule::IntegrableObjectIterator j; Molecule* mol; StuntDouble* sd; int index; Vector3d Tb; Vector3d ji; Vector3d sc; Vector3d vel; Vector3d frc; RealType mass; thermostat = snap->getThermostat(); RealType oldChi = thermostat.first; RealType prevChi; loadEta(); //save velocity and angular momentum index = 0; for (mol = info_->beginMolecule(i); mol != NULL; mol = info_->nextMolecule(i)) { for (sd = mol->beginIntegrableObject(j); sd != NULL; sd = mol->nextIntegrableObject(j)) { oldVel[index] = sd->getVel(); if (sd->isDirectional()) oldJi[index] = sd->getJ(); ++index; } } // do the iteration: instaVol =thermo.getVolume(); for(int k = 0; k < maxIterNum_; k++) { instaTemp =thermo.getTemperature(); instaPress =thermo.getPressure(); // evolve chi another half step using the temperature at t + dt/2 prevChi = thermostat.first; thermostat.first = oldChi + dt2 * (instaTemp / targetTemp - 1.0) / tt2; //evolve eta this->evolveEtaB(); this->calcVelScale(); index = 0; for (mol = info_->beginMolecule(i); mol != NULL; mol = info_->nextMolecule(i)) { for (sd = mol->beginIntegrableObject(j); sd != NULL; sd = mol->nextIntegrableObject(j)) { frc = sd->getFrc(); mass = sd->getMass(); getVelScaleB(sc, index); // velocity half step vel = oldVel[index] + dt2*PhysicalConstants::energyConvert/mass* frc - dt2*sc; sd->setVel(vel); if (sd->isDirectional()) { // get and convert the torque to body frame Tb = sd->lab2Body(sd->getTrq()); ji = oldJi[index] + dt2*PhysicalConstants::energyConvert*Tb - dt2*thermostat.first*oldJi[index]; sd->setJ(ji); } ++index; } } rattle_->constraintB(); if ((fabs(prevChi - thermostat.first) <= chiTolerance) && this->etaConverged()) break; } //calculate integral of chidt thermostat.second += dt2 * thermostat.first; snap->setThermostat(thermostat); flucQ_->moveB(); saveEta(); }
// already parsed the "graphics" and "number" terms, what remains are // add, delete, info, and list static int tcl_graphics(VMDApp *app, int molid, int argc, const char *argv[], Tcl_Interp *interp) { // Is this a graphics molecule? Molecule *mol = app->moleculeList->mol_from_id(molid); if (mol == NULL) { Tcl_SetResult(interp, (char *) "graphics: invalid graphics molecule", TCL_STATIC); return TCL_ERROR; } if (argc < 1) { Tcl_SetResult(interp, (char *) "graphics: not enough parameters", TCL_STATIC); return TCL_ERROR; } MoleculeGraphics *gmol = mol->moleculeGraphics(); // what am I to do? if (!strcmp(argv[0], "list")) { if (argc != 1) { Tcl_SetResult(interp, (char *) "graphics: list takes no parameters", TCL_STATIC); return TCL_ERROR; } int num = gmol->num_elements(); for (int i=0; i<num; i++) { int id = gmol->element_id(i); if (id >=0) { char s[10]; sprintf(s, "%d", id); Tcl_AppendElement(interp, s); } } return TCL_OK; } // all the rest take more than one parameter if (argc < 2) { Tcl_SetResult(interp, (char *) "graphics: not enough parameters", TCL_STATIC); return TCL_ERROR; } if (!strcmp(argv[0], "triangle")) { return tcl_graphics_triangle(gmol, argc-1, argv+1, interp); } if (!strcmp(argv[0], "trinorm")) { return tcl_graphics_trinorm(gmol, argc-1, argv+1, interp); } if (!strcmp(argv[0], "tricolor")) { return tcl_graphics_tricolor(gmol, argc-1, argv+1, interp); } if (!strcmp(argv[0], "point")) { return tcl_graphics_point(gmol, argc-1, argv+1, interp); } if (!strcmp(argv[0], "pickpoint")) { return tcl_graphics_pickpoint(gmol, argc-1, argv+1, interp); } if (!strcmp(argv[0], "line")) { return tcl_graphics_line(gmol, argc-1, argv+1, interp); } if (!strcmp(argv[0], "cylinder")) { return tcl_graphics_cylinder(gmol, argc-1, argv+1, interp); } if (!strcmp(argv[0], "cone")) { return tcl_graphics_cone(gmol, argc-1, argv+1, interp); } if (!strcmp(argv[0], "sphere")) { return tcl_graphics_sphere(gmol, argc-1, argv+1, interp); } if (!strcmp(argv[0], "text")) { return tcl_graphics_text(gmol, argc-1, argv+1, interp); } if (!strcmp(argv[0], "materials")) { return tcl_graphics_materials(gmol, argc-1, argv+1, interp); } if (!strcmp(argv[0], "material")) { return tcl_graphics_material(gmol, argc-1, argv+1, interp, app->materialList); } if (!strcmp(argv[0], "color") || !strcmp(argv[1], "colour")) { return tcl_graphics_color(app, gmol, argc-1, argv+1, interp); } if (!strcmp(argv[0], "delete")) { return tcl_graphics_delete(gmol, argc-1, argv+1, interp); } if (!strcmp(argv[0], "exists")) { return tcl_graphics_exists(gmol, argc-1, argv+1, interp); } if (!strcmp(argv[0], "replace")) { return tcl_graphics_replace(gmol, argc-1, argv+1, interp); } if (!strcmp(argv[0], "info")) { return tcl_graphics_info(gmol, argc-1, argv+1, interp); } Tcl_AppendResult(interp, "graphics: don't understand the command: ", argv[0], NULL); return TCL_ERROR; }
static PyObject *py_align(PyObject *self, PyObject *args) { int selmol, selframe, refmol, refframe, movemol, moveframe; PyObject *selobj, *refobj, *moveobj, *weightobj = NULL; if (!PyArg_ParseTuple(args, (char *)"iiO!iiO!iiO!O:atomselection.align", &selmol, &selframe, &PyTuple_Type, &selobj, &refmol, &refframe, &PyTuple_Type, &refobj, &movemol, &moveframe, &PyTuple_Type, &moveobj, &weightobj)) return NULL; // check if movemol is -1. If so, use the sel molecule and timestep instead if (movemol == -1) { movemol = selmol; moveobj = NULL; } VMDApp *app = get_vmdapp(); AtomSel *sel=NULL, *ref=NULL, *move=NULL; if (!(sel = sel_from_py(selmol, selframe, selobj, app)) || !(ref = sel_from_py(refmol, refframe, refobj, app)) || !(move = sel_from_py(movemol, moveframe, moveobj, app))) { delete sel; delete ref; delete move; return NULL; } const float *selts, *refts; float *movets; if (!(selts = sel->coordinates(app->moleculeList)) || !(refts = ref->coordinates(app->moleculeList)) || !(movets = move->coordinates(app->moleculeList))) { delete sel; delete ref; delete move; PyErr_SetString(PyExc_ValueError, "No coordinates in selection"); return NULL; } float *weight = parse_weight(sel, weightobj); if (!weight) { delete sel; delete ref; delete move; return NULL; } // Find the matrix that aligns sel with ref. Apply the transformation to // the atoms in move. // XXX need to add support for the "order" parameter as in Tcl. Matrix4 mat; int rc = measure_fit(sel, ref, selts, refts, weight, NULL, &mat); delete [] weight; delete sel; delete ref; if (rc < 0) { delete move; PyErr_SetString(PyExc_ValueError, (char *)measure_error(rc)); return NULL; } for (int i=0; i<move->num_atoms; i++) { if (move->on[i]) { float *pos = movets+3*i; mat.multpoint3d(pos, pos); } } Molecule *mol = app->moleculeList->mol_from_id(move->molid()); mol->force_recalc(DrawMolItem::MOL_REGEN); delete move; Py_INCREF(Py_None); return Py_None; }
/* * diese Version beschleunigt in alle Raumrichtungen */ void PressureGradient::determineAdditionalAcceleration ( DomainDecompBase* domainDecomp, ParticleContainer* molCont, double dtConstantAcc ) { for( map<unsigned int, double>::iterator uAAit = _universalAdditionalAcceleration[0].begin(); uAAit != _universalAdditionalAcceleration[0].end(); uAAit++ ) { this->_localN[uAAit->first] = 0; for(unsigned short int d = 0; d < 3; d++) this->_localVelocitySum[d][uAAit->first] = 0.0; } for(Molecule* thismol = molCont->begin(); thismol != molCont->end(); thismol = molCont->next()) { unsigned int cid = thismol->componentid(); map<unsigned int, unsigned int>::iterator uCSIDit = this->_universalComponentSetID.find(cid); if(uCSIDit == _universalComponentSetID.end()) continue; unsigned cosetid = uCSIDit->second; this->_localN[cosetid]++; for(unsigned short int d = 0; d < 3; d++) this->_localVelocitySum[d][cosetid] += thismol->v(d); } // domainDecomp->collectCosetVelocity(&_localN, _localVelocitySum, &_globalN, _globalVelocitySum); // domainDecomp->collCommInit( 4 * _localN.size() ); for( map<unsigned int, unsigned int long>::iterator lNit = _localN.begin(); lNit != _localN.end(); lNit++ ) { domainDecomp->collCommAppendUnsLong(lNit->second); for(int d = 0; d < 3; d++) domainDecomp->collCommAppendDouble( this->_localVelocitySum[d][lNit->first]); } domainDecomp->collCommAllreduceSum(); for( map<unsigned int, unsigned long>::iterator lNit = _localN.begin(); lNit != _localN.end(); lNit++ ) { _globalN[lNit->first] = domainDecomp->collCommGetUnsLong(); for(int d = 0; d < 3; d++) _globalVelocitySum[d][lNit->first] = domainDecomp->collCommGetDouble(); } domainDecomp->collCommFinalize(); map<unsigned int, long double>::iterator gVSit; if(!this->_localRank) { for(gVSit = _globalVelocitySum[0].begin(); gVSit != _globalVelocitySum[0].end(); gVSit++) { #ifndef NDEBUG global_log->debug() << "required entries in velocity queue: " << _globalVelocityQueuelength[gVSit->first] << endl; global_log->debug() << "entries in velocity queue: " << _globalPriorVelocitySums[0][gVSit->first].size() << endl; #endif for(unsigned short int d = 0; d < 3; d++) { while(_globalPriorVelocitySums[d][gVSit->first].size() < _globalVelocityQueuelength[gVSit->first]) _globalPriorVelocitySums[d][gVSit->first].push_back(_globalVelocitySum[d][gVSit->first]); } } } if(!this->_localRank) { for(gVSit = _globalVelocitySum[0].begin(); gVSit != _globalVelocitySum[0].end(); gVSit++) { double invgN = 1.0 / this->_globalN[gVSit->first]; double invgtau = 1.0 / this->_universalTau[gVSit->first]; double invgtau2 = invgtau * invgtau; double previousVelocity[3]; for(unsigned short int d = 0; d < 3; d++) { previousVelocity[d] = invgN * _globalPriorVelocitySums[d][gVSit->first].front(); this->_globalPriorVelocitySums[d][gVSit->first].pop_front(); this->_universalAdditionalAcceleration[d][gVSit->first] += dtConstantAcc * invgtau2 * ( this->_globalTargetVelocity[d][gVSit->first] - 2.0*this->_globalVelocitySum[d][gVSit->first]*invgN + previousVelocity[d] ); } #ifndef NDEBUG global_log->debug() << "accelerator no. " << gVSit->first << "previous vz: " << previousVelocity[2] << "current vz: " << _globalVelocitySum[2][gVSit->first]*invgN << endl; #endif } } domainDecomp->collCommInit(7*this->_localN.size()); for( map<unsigned int, unsigned long>::iterator lNit = _localN.begin(); lNit != this->_localN.end(); lNit++ ) { domainDecomp->collCommAppendUnsLong(_globalN[lNit->first]); for(int d=0; d < 3; d++) { domainDecomp->collCommAppendDouble( this->_universalAdditionalAcceleration[d][lNit->first] ); domainDecomp->collCommAppendDouble( this->_globalVelocitySum[d][lNit->first] ); } } domainDecomp->collCommBroadcast(); for( map<unsigned int, unsigned long>::iterator lNit = _localN.begin(); lNit != this->_localN.end(); lNit++ ) { _globalN[lNit->first] = domainDecomp->collCommGetUnsLong(); for(int d=0; d < 3; d++) { this->_universalAdditionalAcceleration[d][lNit->first] = domainDecomp->collCommGetDouble(); this->_globalVelocitySum[d][lNit->first] = domainDecomp->collCommGetDouble(); } } domainDecomp->collCommFinalize(); }