CatomPack MultiColvarBase::getCentralAtomPack( const unsigned& basn, const unsigned& taskIndex ){ unsigned curr=getTaskCode( taskIndex ); CatomPack mypack; if(usespecies){ mypack.resize(1); mypack.setIndex( 0, basn + curr ); mypack.setDerivative( 0, Tensor::identity() ); } else if( ablocks.size()<4 ){ mypack.resize(ablocks.size()); unsigned k=0; std::vector<unsigned> atoms( ablocks.size() ); decodeIndexToAtoms( curr, atoms ); for(unsigned i=0;i<ablocks.size();++i){ if( use_for_central_atom[i] ){ mypack.setIndex( k, basn + atoms[i] ); mypack.setDerivative( k, numberForCentralAtom*Tensor::identity() ); k++; } } } else { unsigned k=0; for(unsigned i=0;i<ablocks.size();++i){ if( use_for_central_atom[i] ){ mypack.setIndex( k, basn + ablocks[i][curr] ); mypack.setDerivative( k, numberForCentralAtom*Tensor::identity() ); k++; } } } return mypack; }
void Value::setGradients() { // Can't do gradients if we don't have derivatives if( !hasDeriv ) return; gradients.clear(); ActionAtomistic*aa=dynamic_cast<ActionAtomistic*>(action); ActionWithArguments*aw=dynamic_cast<ActionWithArguments*>(action); if(aa) { Atoms&atoms((aa->plumed).getAtoms()); for(unsigned j=0; j<aa->getNumberOfAtoms(); ++j) { AtomNumber an=aa->getAbsoluteIndex(j); if(atoms.isVirtualAtom(an)) { const ActionWithVirtualAtom* a=atoms.getVirtualAtomsAction(an); for(const auto & p : a->getGradients()) { // controllare l'ordine del matmul: gradients[p.first]+=matmul(Vector(derivatives[3*j],derivatives[3*j+1],derivatives[3*j+2]),p.second); } } else { for(unsigned i=0; i<3; i++) gradients[an][i]+=derivatives[3*j+i]; } } } else if(aw) { std::vector<Value*> values=aw->getArguments(); for(unsigned j=0; j<derivatives.size(); j++) { for(const auto & p : values[j]->gradients) { AtomNumber iatom=p.first; gradients[iatom]+=p.second*derivatives[j]; } } } else plumed_error(); }
MarkedBlock::FreeCell* MarkedBlock::specializedSweep() { ASSERT(blockState != Allocated && blockState != FreeListed); // This produces a free list that is ordered in reverse through the block. // This is fine, since the allocation code makes no assumptions about the // order of the free list. FreeCell* head = 0; for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) { if (blockState == Marked && m_marks.get(i)) continue; JSCell* cell = reinterpret_cast<JSCell*>(&atoms()[i]); if (blockState == Zapped && !cell->isZapped()) continue; if (blockState != New) callDestructor(cell); if (sweepMode == SweepToFreeList) { FreeCell* freeCell = reinterpret_cast<FreeCell*>(cell); freeCell->next = head; head = freeCell; } } m_state = ((sweepMode == SweepToFreeList) ? FreeListed : Zapped); return head; }
MarkedBlock::FreeList MarkedBlock::specializedSweep() { ASSERT(blockState != Allocated && blockState != FreeListed); ASSERT(!(dtorType == MarkedBlock::None && sweepMode == SweepOnly)); // This produces a free list that is ordered in reverse through the block. // This is fine, since the allocation code makes no assumptions about the // order of the free list. FreeCell* head = 0; size_t count = 0; for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) { if (blockState == Marked && (m_marks.get(i) || (m_newlyAllocated && m_newlyAllocated->get(i)))) continue; JSCell* cell = reinterpret_cast_ptr<JSCell*>(&atoms()[i]); if (dtorType != MarkedBlock::None && blockState != New) callDestructor(cell); if (sweepMode == SweepToFreeList) { FreeCell* freeCell = reinterpret_cast<FreeCell*>(cell); freeCell->next = head; head = freeCell; ++count; } } // We only want to discard the newlyAllocated bits if we're creating a FreeList, // otherwise we would lose information on what's currently alive. if (sweepMode == SweepToFreeList && m_newlyAllocated) m_newlyAllocated.clear(); m_state = ((sweepMode == SweepToFreeList) ? FreeListed : Marked); return FreeList(head, count * cellSize()); }
int main(){ atoms(); velocities(); bonds(); angles(); dihedrals(); }
std::tuple<std::valarray<std::string>, matrix, int> get_coordinates(const std::string filename) { std::string line; std::vector<std::string> coordinate_line; std::ifstream xyzfile (filename); unsigned int n_atoms {0}; std::string atom; std::vector<double> coordinate {}; double x, y, z; if(xyzfile.is_open()) { // Get number of atoms getline(xyzfile, line); n_atoms = stoi(line); // Allocate atoms and coordinates, // now that we know how many atoms are included std::valarray<std::string> atoms(n_atoms); matrix coordinates(3 * n_atoms); // Empty line getline(xyzfile, line); // Read coordinates int i = 0; while(getline(xyzfile, line)) { coordinate_line = split(line, ' '); atom = coordinate_line[0]; x = std::stod(coordinate_line[1]); y = std::stod(coordinate_line[2]); z = std::stod(coordinate_line[3]); // n_cols * row + col coordinates[3*i + 0] = x; coordinates[3*i + 1] = y; coordinates[3*i + 2] = z; atoms[i] = atom; i++; } xyzfile.close(); return make_tuple(atoms, coordinates, n_atoms); } else { std::cerr << "Unable to open " << filename << std::endl; exit(0); } }
std::vector<atom_t> get_atoms(const gsl_vector * x, const opthelper_t & opts) { // Update atomic positions std::vector<atom_t> atoms(opts.atoms); for(size_t i=0;i<opts.dofidx.size();i++) { size_t j=opts.dofidx[i]; atoms[j].x=gsl_vector_get(x,3*i); atoms[j].y=gsl_vector_get(x,3*i+1); atoms[j].z=gsl_vector_get(x,3*i+2); } return atoms; }
bool MultiColvarBase::setupCurrentAtomList( const unsigned& taskCode, AtomValuePack& myatoms ) const { if( usespecies ){ if( isDensity() ) return true; unsigned natomsper=myatoms.setupAtomsFromLinkCells( taskCode, getPositionOfAtomForLinkCells(taskCode), linkcells ); return natomsper>1; } else if( ablocks.size()<4 ){ std::vector<unsigned> atoms( ablocks.size() ); decodeIndexToAtoms( taskCode, atoms ); myatoms.setNumberOfAtoms( ablocks.size() ); for(unsigned i=0;i<ablocks.size();++i) myatoms.setAtom( i, atoms[i] ); } else { myatoms.setNumberOfAtoms( ablocks.size() ); for(unsigned i=0;i<ablocks.size();++i) myatoms.setAtom( i, ablocks[i][taskCode] ); } return true; }
// we do not only provide context atoms, so we also need to override the following std::vector<PluginAtomPtr> MCSIEPlugin::createAtoms(ProgramCtx& ctx) const { MCSIE::CtxData& pcd = ctx.getPluginData<MCSIE>(); if( true ) // provide atoms in every case! pcd.isEnabled() ) { // get context atoms std::vector<PluginAtomPtr> atoms( BaseContextPlugin::createAtoms(ctx)); // register additional atoms atoms.push_back(PluginAtomPtr(new SaturationMetaAtom(pcd))); return atoms; } else { return std::vector<PluginAtomPtr>(); } }
List Factory::convert(Data::Geometry& geometry) { List list; Atoms* atoms(new Atoms()); Bonds* bonds(new Bonds()); list.append(atoms); list.append(bonds); unsigned nAtoms(geometry.nAtoms()); OpenBabel::OBMol obMol; obMol.BeginModify(); AtomMap atomMap; for (unsigned i = 0; i < nAtoms; ++i) { unsigned Z(geometry.atomicNumber(i)); qglviewer::Vec position(geometry.position(i)); Atom* atom(new Atom(geometry.atomicNumber(i))); atom->setPosition(geometry.position(i)); atoms->appendLayer(atom); OpenBabel::OBAtom* obAtom(obMol.NewAtom()); obAtom->SetAtomicNum(Z); obAtom->SetVector(position.x, position.y, position.z); atomMap.insert(obAtom, atom); } obMol.SetTotalCharge(geometry.charge()); obMol.SetTotalSpinMultiplicity(geometry.multiplicity()); obMol.EndModify(); obMol.ConnectTheDots(); obMol.PerceiveBondOrders(); for (OpenBabel::OBMolBondIter obBond(&obMol); obBond; ++obBond) { Atom* begin(atomMap.value(obBond->GetBeginAtom())); Atom* end(atomMap.value(obBond->GetEndAtom())); Bond* bond(new Bond(begin, end)); bond->setOrder(obBond->GetBondOrder()); bonds->appendLayer(bond); } return list; }
Vector MultiColvarBase::getCentralAtomPos( const unsigned& taskIndex ){ unsigned curr=getTaskCode( taskIndex ); if( usespecies || isDensity() ){ return getPositionOfAtomForLinkCells(curr); } else if( ablocks.size()<4 ){ // double factor=1.0/static_cast<double>( ablocks.size() ); Vector mypos; mypos.zero(); std::vector<unsigned> atoms( ablocks.size() ); decodeIndexToAtoms( curr, atoms ); for(unsigned i=0;i<ablocks.size();++i){ if( use_for_central_atom[i] ) mypos+=numberForCentralAtom*getPositionOfAtomForLinkCells(atoms[i]); } return mypos; } else { Vector mypos; mypos.zero(); for(unsigned i=0;i<ablocks.size();++i){ if( use_for_central_atom[i] ) mypos+=numberForCentralAtom*getPositionOfAtomForLinkCells(ablocks[i][curr]); } return mypos; } }
Diamond::~Diamond() { Finder::removeAll(atoms().data(), atoms().size()); }
void Diamond::findAll() { Finder::initFind(atoms().data(), atoms().size()); }
void prepareAtomInsert(int bonus=100) { if (atoms().size() == atoms().capacity()) atoms().reserve(atoms().size() + bonus); }
ocsd_datapath_resp_t TrcPktDecodeEtmV3::processPHdr() { ocsd_datapath_resp_t resp = OCSD_RESP_CONT; OcsdTraceElement *pElem = 0; ocsd_isa isa; Etmv3Atoms atoms(m_config->isCycleAcc()); atoms.initAtomPkt(m_curr_packet_in,m_index_curr_pkt); isa = m_curr_packet_in->ISA(); m_code_follower.setMemSpaceAccess((m_PeContext.getSecLevel() == ocsd_sec_secure) ? OCSD_MEM_SPACE_S : OCSD_MEM_SPACE_N); try { do { // if we do not have a valid address then send any cycle count elements // and stop processing if(m_bNeedAddr) { // output unknown address packet or a cycle count packet if(!m_bSentUnknown || m_config->isCycleAcc()) { pElem = GetNextOpElem(resp); if(m_bSentUnknown || !atoms.numAtoms()) pElem->setType(OCSD_GEN_TRC_ELEM_CYCLE_COUNT); else pElem->setType(OCSD_GEN_TRC_ELEM_ADDR_UNKNOWN); if(m_config->isCycleAcc()) pElem->setCycleCount(atoms.getRemainCC()); m_bSentUnknown = true; } atoms.clearAll(); // skip remaining atoms } else // have an address, can process atoms { pElem = GetNextOpElem(resp); pElem->setType(OCSD_GEN_TRC_ELEM_INSTR_RANGE); // cycle accurate may have a cycle count to use if(m_config->isCycleAcc()) { // note: it is possible to have a CC only atom packet. if(!atoms.numAtoms()) // override type if CC only pElem->setType(OCSD_GEN_TRC_ELEM_CYCLE_COUNT); // set cycle count pElem->setCycleCount(atoms.getAtomCC()); } // now process the atom if(atoms.numAtoms()) { m_code_follower.setISA(isa); m_code_follower.followSingleAtom(m_IAddr,atoms.getCurrAtomVal()); // valid code range if(m_code_follower.hasRange()) { pElem->setAddrRange(m_IAddr,m_code_follower.getRangeEn()); pElem->setLastInstrInfo(atoms.getCurrAtomVal() == ATOM_E, m_code_follower.getInstrType(), m_code_follower.getInstrSubType()); pElem->setISA(isa); if(m_code_follower.hasNextAddr()) m_IAddr = m_code_follower.getNextAddr(); else setNeedAddr(true); } // next address has new ISA? if(m_code_follower.ISAChanged()) isa = m_code_follower.nextISA(); // there is a nacc if(m_code_follower.isNacc()) { if(m_code_follower.hasRange()) { pElem = GetNextOpElem(resp); pElem->setType(OCSD_GEN_TRC_ELEM_ADDR_NACC); } else pElem->updateType(OCSD_GEN_TRC_ELEM_ADDR_NACC); pElem->setAddrStart(m_code_follower.getNaccAddr()); setNeedAddr(true); m_code_follower.clearNacc(); // we have generated some code for the nacc. } } atoms.clearAtom(); // next atom } } while(atoms.numAtoms()); // is tha last element an atom? int numElem = m_outputElemList.getNumElem(); if(numElem >= 1) { // if the last thing is an instruction range, pend it - could be cancelled later. if(m_outputElemList.getElemType(numElem-1) == OCSD_GEN_TRC_ELEM_INSTR_RANGE) m_outputElemList.pendLastNElem(1); } // finally - do we have anything to send yet? m_curr_state = m_outputElemList.elemToSend() ? SEND_PKTS : DECODE_PKTS; } catch(ocsdError &err) { LogError(err); resetDecoder(); // mark decoder as unsynced - dump any current state. } return resp; }
bool LJ6_12::Setup() { // combine the typing stored in obfftype with the parameters from the parameter database OBParameterDBTable * pTable = ((m_function->GetParameterDB())->GetTable(m_tableName)); OBFFType * pOBFFType(m_function->GetOBFFType()); vector<OBFFType::AtomIdentifier> atoms(pOBFFType->GetAtoms()); vector<OBParameterDBTable::Query> query; vector<OBVariant> row; Parameter parameter; string name; map<string,Parameter> parameters; map<string,Parameter>::iterator itr; Index i; vector <Index> v_i; vector <Parameter> v_calcs; OBAtom *a, *b; if ( (pTable==NULL) || (pOBFFType==NULL) ) return false; double sigma_j, sigma_k, epsilon_j, epsilon_k; for(unsigned int j=0; j != atoms.size(); ++j){ for(unsigned int k= j+1; k != atoms.size(); ++k){ if (atoms[j]<atoms[k]) name = atoms[j] + "-" + atoms[k]; else name = atoms[k] + "-" + atoms[j]; itr=parameters.find(name); if (itr==parameters.end()){ query.clear(); query.push_back( OBParameterDBTable::Query(0, OBVariant(atoms[j]))); row = pTable->FindRow(query); sigma_j = row.at(1).AsDouble(); epsilon_j = row.at(2).AsDouble(); query.clear(); query.push_back( OBParameterDBTable::Query(0, OBVariant(atoms[k]))); row = pTable->FindRow(query); sigma_k = row.at(1).AsDouble(); epsilon_k = row.at(2).AsDouble(); (*m_Mix)(parameter.sigma, parameter.epsilon, sigma_j, epsilon_j, sigma_k, epsilon_k); parameters.insert(pair<string,Parameter>(name,parameter)); } else parameter=itr->second; i.iA = j; i.iB = k; if (pOBFFType->IsConnected(i.iA, i.iB)) continue; if (pOBFFType->IsOneThree(i.iA, i.iB)) continue; if (pOBFFType->IsOneFour(i.iA, i.iB)) parameter.epsilon *= m_factorOneFour; v_i.push_back(i); v_calcs.push_back(parameter); } } m_numPairs = v_i.size(); delete [] m_i; delete [] m_calcs; m_i = new Index [m_numPairs]; m_calcs = new Parameter [m_numPairs]; for (size_t i=0; i< m_numPairs; ++i){ m_i[i] = v_i[i]; m_calcs[i] = v_calcs[i]; } return true; }
int main(){ // size in unit cells int nx=5,ny=5,nz=5; // atoms std::vector<atom_t> cellatoms(2); // bcc cellatoms[0].x=0.0; cellatoms[0].y=0.0; cellatoms[0].z=0.0; cellatoms[0].id=0; cellatoms[1].x=0.5; cellatoms[1].y=0.5; cellatoms[1].z=0.5; cellatoms[1].id=1; // cutoff radius (fraction of a) double cutoff=sqrt(3.0)/2.0+0.05; int counter=0; std::vector<std::vector <std::vector <std::vector <atom_t> > > > atoms(0); std::vector<nn_t> neighbours(0); // generate lattice atoms.resize(nx); for(int i=0;i<nx;i++){ atoms[i].resize(ny); for(int j=0;j<ny;j++){ atoms[i][j].resize(nz); for(int k=0;k<nz;k++){ for(int atom=0;atom<cellatoms.size();atom++){ atom_t tmpatom; tmpatom.x=cellatoms[atom].x+double(i); tmpatom.y=cellatoms[atom].y+double(j); tmpatom.z=cellatoms[atom].z+double(k); tmpatom.id=atom; tmpatom.no=counter; counter++; atoms[i][j][k].push_back(tmpatom); //std::cout << atoms[i][j][k][atom].x << " " << atoms[i][j][k][atom].y << " " << atoms[i][j][k][atom].z << " " << atoms[i][j][k][atom].id << " " << atoms[i][j][k][atom].no << " " <<std::endl; } } } } //std::cout << counter << " atoms generated" << std::endl; // calculate neighbourlist for central cell and output to screen int cx=nx/2+1; int cy=ny/2+1; int cz=nz/2+1; // loop over all atoms in local unit cell for(int atom=0;atom<cellatoms.size();atom++){ double ix=atoms[cx][cy][cz][atom].x; double iy=atoms[cx][cy][cz][atom].y; double iz=atoms[cx][cy][cz][atom].z; int iid=atoms[cx][cy][cz][atom].id; int in=atoms[cx][cy][cz][atom].no; //std::cout << ix << " " << iy << " " << iz << " " << iid << " " << in << std::endl; // loop over all other unit cells for(int i=0;i<nx;i++){ for(int j=0;j<ny;j++){ for(int k=0;k<nz;k++){ for(int jatom=0;jatom<cellatoms.size();jatom++){ double jx=atoms[i][j][k][jatom].x; double jy=atoms[i][j][k][jatom].y; double jz=atoms[i][j][k][jatom].z; int jid=atoms[i][j][k][jatom].id; int jn=atoms[i][j][k][jatom].no; //std::cout << jx << " " << jy << " " << jz << " " << jid << " " << jn << std::endl; // exclude self-interaction if(in!=jn){ double range=sqrt((jx-ix)*(jx-ix)+(jy-iy)*(jy-iy)+(jz-iz)*(jz-iz)); if(range<cutoff){ //std::cout << iid << "\t" << jid << "\t" << i-cx << "\t" << j-cy << "\t" << k-cz << std::endl; nn_t tmpnn; tmpnn.i=iid; tmpnn.j=jid; tmpnn.dx=i-cx; tmpnn.dy=j-cy; tmpnn.dz=k-cz; neighbours.push_back(tmpnn); } } } } } } } // output data to screen std::cout << "\t\t\tunit_cell.lcsize=" << cellatoms.size() << ";" << std::endl; std::cout << "\t\t\tunit_cell.hcsize=" << 2 << ";" << std::endl; std::cout << "\t\t\tunit_cell.interaction_range=" << 1 << ";" << std::endl; std::cout << "\t\t\tunit_cell.atom.resize(" << cellatoms.size() << ");" << std::endl; for(int atom=0;atom<cellatoms.size();atom++){ std::cout << "\t\t\t//-----------------------------" << std::endl; std::cout << "\t\t\tunit_cell.atom[" << atom << "].x=" << cellatoms[atom].x << ";"<< std::endl; std::cout << "\t\t\tunit_cell.atom[" << atom << "].y=" << cellatoms[atom].y << ";"<< std::endl; std::cout << "\t\t\tunit_cell.atom[" << atom << "].z=" << cellatoms[atom].z << ";"<< std::endl; std::cout << "\t\t\tunit_cell.atom[" << atom << "].lc=" << atom << ";"<< std::endl; std::cout << "\t\t\tunit_cell.atom[" << atom << "].hc=" << atom << ";"<< std::endl; } std::cout << "\t\t\t//-----------------------------" << std::endl; std::cout << "\t\t\tunit_cell.interaction.resize(" << neighbours.size() << ");" << std::endl; for(int nn=0;nn<neighbours.size();nn++){ std::cout << "\t\t\t//-----------------------------" << std::endl; std::cout << "\t\t\tunit_cell.interaction["<< nn <<"].i="<< neighbours[nn].i<<";" << std::endl; std::cout << "\t\t\tunit_cell.interaction["<< nn <<"].j="<< neighbours[nn].j<<";" << std::endl; std::cout << "\t\t\tunit_cell.interaction["<< nn <<"].dx="<< neighbours[nn].dx<<";" << std::endl; std::cout << "\t\t\tunit_cell.interaction["<< nn <<"].dy="<< neighbours[nn].dy<<";" << std::endl; std::cout << "\t\t\tunit_cell.interaction["<< nn <<"].dz="<< neighbours[nn].dz<<";" << std::endl; } return 0; }
int main(int argc, char **argv) { #ifdef _OPENMP printf("ERKALE - Geometry optimization from Hel, OpenMP version, running on %i cores.\n",omp_get_max_threads()); #else printf("ERKALE - Geometry optimization from Hel, serial version.\n"); #endif print_copyright(); print_license(); #ifdef SVNRELEASE printf("At svn revision %s.\n\n",SVNREVISION); #endif print_hostname(); if(argc!=2) { printf("Usage: $ %s runfile\n",argv[0]); return 0; } // Initialize libint init_libint_base(); // Initialize libderiv init_libderiv_base(); Timer tprog; tprog.print_time(); // Parse settings Settings set; set.add_scf_settings(); set.add_string("SaveChk","File to use as checkpoint","erkale.chk"); set.add_string("LoadChk","File to load old results from",""); set.add_bool("ForcePol","Force polarized calculation",false); set.add_bool("FreezeCore","Freeze the atomic cores?",false); set.add_string("Optimizer","Optimizer to use: CGFR, CGPR, BFGS, BFGS2 (default), SD","BFGS2"); set.add_int("MaxSteps","Maximum amount of geometry steps",256); set.add_string("Criterion","Convergence criterion to use: LOOSE, NORMAL, TIGHT, VERYTIGHT","NORMAL"); set.add_string("OptMovie","xyz movie to store progress in","optimize.xyz"); set.add_string("Result","File to save optimized geometry in","optimized.xyz"); set.set_string("Logfile","erkale_geom.log"); set.parse(std::string(argv[1]),true); set.print(); bool verbose=set.get_bool("Verbose"); int maxiter=set.get_int("MaxSteps"); std::string optmovie=set.get_string("OptMovie"); std::string result=set.get_string("Result"); // Interpret optimizer enum minimizer alg; std::string method=set.get_string("Optimizer"); if(stricmp(method,"CGFR")==0) alg=gCGFR; else if(stricmp(method,"CGPR")==0) alg=gCGPR; else if(stricmp(method,"BFGS")==0) alg=gBFGS; else if(stricmp(method,"BFGS2")==0) alg=gBFGS2; else if(stricmp(method,"SD")==0) alg=gSD; else { ERROR_INFO(); throw std::runtime_error("Unknown optimization method.\n"); } // Interpret optimizer enum convergence crit; method=set.get_string("Criterion"); if(stricmp(method,"LOOSE")==0) crit=LOOSE; else if(stricmp(method,"NORMAL")==0) crit=NORMAL; else if(stricmp(method,"TIGHT")==0) crit=TIGHT; else if(stricmp(method,"VERYTIGHT")==0) crit=VERYTIGHT; else { ERROR_INFO(); throw std::runtime_error("Unknown optimization method.\n"); } // Redirect output? std::string logfile=set.get_string("Logfile"); if(stricmp(logfile,"stdout")!=0) { // Redirect stdout to file FILE *outstream=freopen(logfile.c_str(),"w",stdout); if(outstream==NULL) { ERROR_INFO(); throw std::runtime_error("Unable to redirect output!\n"); } else fprintf(stderr,"\n"); } // Read in atoms. std::string atomfile=set.get_string("System"); const std::vector<atom_t> origgeom=load_xyz(atomfile); std::vector<atom_t> atoms(origgeom); // Are any atoms fixed? std::vector<size_t> dofidx; for(size_t i=0;i<atoms.size();i++) { bool fixed=false; if(atoms[i].el.size()>3) if(stricmp(atoms[i].el.substr(atoms[i].el.size()-3),"-Fx")==0) { fixed=true; atoms[i].el=atoms[i].el.substr(0,atoms[i].el.size()-3); } // Add to degrees of freedom if(!fixed) dofidx.push_back(i); } // Read in basis set BasisSetLibrary baslib; std::string basfile=set.get_string("Basis"); baslib.load_gaussian94(basfile); printf("\n"); // Save to output save_xyz(atoms,"Initial configuration",optmovie,false); // Minimizer options opthelper_t pars; pars.atoms=atoms; pars.baslib=baslib; pars.set=set; pars.dofidx=dofidx; /* Starting point */ gsl_vector *x = gsl_vector_alloc (3*dofidx.size()); for(size_t i=0;i<dofidx.size();i++) { gsl_vector_set(x,3*i,atoms[dofidx[i]].x); gsl_vector_set(x,3*i+1,atoms[dofidx[i]].y); gsl_vector_set(x,3*i+2,atoms[dofidx[i]].z); } // GSL status int status; const gsl_multimin_fdfminimizer_type *T; gsl_multimin_fdfminimizer *s; gsl_multimin_function_fdf minimizer; minimizer.n = x->size; minimizer.f = calc_E; minimizer.df = calc_f; minimizer.fdf = calc_Ef; minimizer.params = (void *) &pars; if(alg==gCGFR) { T = gsl_multimin_fdfminimizer_conjugate_fr; if(verbose) printf("Using Fletcher-Reeves conjugate gradients.\n"); } else if(alg==gCGPR) { T = gsl_multimin_fdfminimizer_conjugate_pr; if(verbose) printf("Using Polak-Ribière conjugate gradients.\n"); } else if(alg==gBFGS) { T = gsl_multimin_fdfminimizer_vector_bfgs; if(verbose) printf("Using the BFGS minimizer.\n"); } else if(alg==gBFGS2) { T = gsl_multimin_fdfminimizer_vector_bfgs2; if(verbose) printf("Using the BFGS2 minimizer.\n"); } else if(alg==gSD) { T = gsl_multimin_fdfminimizer_steepest_descent; if(verbose) printf("Using the steepest descent minimizer.\n"); } else { ERROR_INFO(); throw std::runtime_error("Unsupported minimizer\n"); } // Run an initial calculation double oldE=calc_E(x,minimizer.params); // Turn off verbose setting pars.set.set_bool("Verbose",false); // and load from old checkpoint pars.set.set_string("LoadChk",pars.set.get_string("SaveChk")); // Initialize minimizer s = gsl_multimin_fdfminimizer_alloc (T, minimizer.n); // Use initial step length of 0.02 bohr, and a line search accuracy // 1e-1 (recommended in the GSL manual for BFGS) gsl_multimin_fdfminimizer_set (s, &minimizer, x, 0.02, 1e-1); // Store old force arma::mat oldf=interpret_force(s->gradient); fprintf(stderr,"Geometry optimizer initialized in %s.\n",tprog.elapsed().c_str()); fprintf(stderr,"Entering minimization loop with %s optimizer.\n",set.get_string("Optimizer").c_str()); fprintf(stderr,"%4s %16s %10s %10s %9s %9s %9s %9s %s\n","iter","E","dE","dE/dEproj","disp max","disp rms","f max","f rms", "titer"); std::vector<atom_t> oldgeom(atoms); bool convd=false; int iter; for(iter=1;iter<=maxiter;iter++) { printf("\nGeometry iteration %i\n",(int) iter); fflush(stdout); Timer titer; status = gsl_multimin_fdfminimizer_iterate (s); if (status) { fprintf(stderr,"GSL encountered error: \"%s\".\n",gsl_strerror(status)); break; } // New geometry is std::vector<atom_t> geom=get_atoms(s->x,pars); // Calculate displacements double dmax, drms; get_displacement(geom, oldgeom, dmax, drms); // Calculate projected change of energy double dEproj=calculate_projection(geom,oldgeom,oldf,pars.dofidx); // Actual change of energy is double dE=s->f - oldE; // Switch geometries oldgeom=geom; // Save old force // Get forces double fmax, frms; get_forces(s->gradient, fmax, frms); // Save geometry step char comment[80]; sprintf(comment,"Step %i",(int) iter); save_xyz(get_atoms(s->x,pars),comment,optmovie,true); // Check convergence bool fmaxconv=false, frmsconv=false; bool dmaxconv=false, drmsconv=false; switch(crit) { case(LOOSE): if(fmax < 2.5e-3) fmaxconv=true; if(frms < 1.7e-3) frmsconv=true; if(dmax < 1.0e-2) dmaxconv=true; if(drms < 6.7e-3) drmsconv=true; break; case(NORMAL): if(fmax < 4.5e-4) fmaxconv=true; if(frms < 3.0e-4) frmsconv=true; if(dmax < 1.8e-3) dmaxconv=true; if(drms < 1.2e-3) drmsconv=true; break; case(TIGHT): if(fmax < 1.5e-5) fmaxconv=true; if(frms < 1.0e-5) frmsconv=true; if(dmax < 6.0e-5) dmaxconv=true; if(drms < 4.0e-5) drmsconv=true; break; case(VERYTIGHT): if(fmax < 2.0e-6) fmaxconv=true; if(frms < 1.0e-6) frmsconv=true; if(dmax < 6.0e-6) dmaxconv=true; if(drms < 4.0e-6) drmsconv=true; break; default: ERROR_INFO(); throw std::runtime_error("Not implemented!\n"); } // Converged? const static char cconv[]=" *"; double dEfrac; if(dEproj!=0.0) dEfrac=dE/dEproj; else dEfrac=0.0; fprintf(stderr,"%4d % 16.8f % .3e % .3e %.3e%c %.3e%c %.3e%c %.3e%c %s\n", (int) iter, s->f, dE, dEfrac, dmax, cconv[dmaxconv], drms, cconv[drmsconv], fmax, cconv[fmaxconv], frms, cconv[frmsconv], titer.elapsed().c_str()); fflush(stderr); convd=dmaxconv && drmsconv && fmaxconv && frmsconv; if(convd) { fprintf(stderr,"Converged.\n"); break; } // Store old energy oldE=s->f; // Store old force oldf=interpret_force(s->gradient); } if(convd) save_xyz(get_atoms(s->x,pars),"Optimized geometry",result); gsl_multimin_fdfminimizer_free (s); gsl_vector_free (x); if(iter==maxiter && !convd) { printf("Geometry convergence was not achieved!\n"); } printf("Running program took %s.\n",tprog.elapsed().c_str()); return 0; }
void X11AppContext::processEvent(const x11::GenericEvent& ev) { //macro for easier event creation for registered EventHandler #define EventHandlerEvent(T, W) \ auto handler = eventHandler(W); \ if(!handler) return; \ auto event = T(handler); auto dispatch = [&](Event& event){ if(event.handler) event.handler->handleEvent(event); }; auto responseType = ev.response_type & ~0x80; switch(responseType) { case XCB_MOTION_NOTIFY: { auto& motion = reinterpret_cast<const xcb_motion_notify_event_t&>(ev); auto pos = nytl::Vec2i(motion.event_x, motion.event_y); mouseContext_->move(pos); EventHandlerEvent(MouseMoveEvent, motion.event); event.position = pos; event.screenPosition = nytl::Vec2i(motion.root_x, motion.root_y); dispatch(event); break; } case XCB_EXPOSE: { auto& expose = reinterpret_cast<const xcb_expose_event_t&>(ev); if(expose.count == 0) { EventHandlerEvent(DrawEvent, expose.window); dispatch(event); } break; } case XCB_MAP_NOTIFY: { auto& map = reinterpret_cast<const xcb_map_notify_event_t&>(ev); EventHandlerEvent(DrawEvent, map.window); dispatch(event); break; } case XCB_BUTTON_PRESS: { auto& button = reinterpret_cast<const xcb_button_press_event_t&>(ev); int scroll = 0; if(button.detail == 4) scroll = 1; else if(button.detail == 5) scroll = -1; if(scroll) { EventHandlerEvent(MouseWheelEvent, button.event); event.data = std::make_unique<X11EventData>(ev); event.value = scroll; mouseContext_->onWheel(*mouseContext_, scroll); dispatch(event); break; } auto b = x11ToButton(button.detail); mouseContext_->mouseButton(b, true); EventHandlerEvent(MouseButtonEvent, button.event); event.data = std::make_unique<X11EventData>(ev); event.button = b; event.position = nytl::Vec2i(button.event_x, button.event_y); event.pressed = true; dispatch(event); break; } case XCB_BUTTON_RELEASE: { auto& button = reinterpret_cast<const xcb_button_release_event_t&>(ev); if(button.detail == 4 || button.detail == 5) break; auto b = x11ToButton(button.detail); mouseContext_->mouseButton(b, false); EventHandlerEvent(MouseButtonEvent, button.event); event.data = std::make_unique<X11EventData>(ev); event.button = b; event.position = nytl::Vec2i(button.event_x, button.event_y); event.pressed = false; dispatch(event); break; } case XCB_ENTER_NOTIFY: { auto& enter = reinterpret_cast<const xcb_enter_notify_event_t&>(ev); auto wc = windowContext(enter.event); mouseContext_->over(wc); EventHandlerEvent(MouseCrossEvent, enter.event); event.position = nytl::Vec2i(enter.event_x, enter.event_y); event.entered = true; dispatch(event); break; } case XCB_LEAVE_NOTIFY: { auto& leave = reinterpret_cast<const xcb_enter_notify_event_t&>(ev); auto wc = windowContext(leave.event); if(mouseContext_->over() == wc) mouseContext_->over(nullptr); EventHandlerEvent(MouseCrossEvent, leave.event); event.position = nytl::Vec2i(leave.event_x, leave.event_y); event.entered = false; dispatch(event); break; } case XCB_FOCUS_IN: { auto& focus = reinterpret_cast<const xcb_focus_in_event_t&>(ev); auto wc = windowContext(focus.event); keyboardContext_->focus(wc); EventHandlerEvent(FocusEvent, focus.event); event.focus = true; dispatch(event); break; } case XCB_FOCUS_OUT: { auto& focus = reinterpret_cast<const xcb_focus_in_event_t&>(ev); auto wc = windowContext(focus.event); if(keyboardContext_->focus() == wc)keyboardContext_->focus(nullptr); EventHandlerEvent(FocusEvent, focus.event); event.focus = false; dispatch(event); break; } case XCB_KEY_PRESS: { auto& key = reinterpret_cast<const xcb_key_press_event_t&>(ev); EventHandlerEvent(KeyEvent, key.event); event.pressed = true; if(!keyboardContext_->keyEvent(key.detail, event)) bell(); dispatch(event); break; } case XCB_KEY_RELEASE: { auto& key = reinterpret_cast<const xcb_key_press_event_t&>(ev); EventHandlerEvent(KeyEvent, key.event); event.pressed = false; if(!keyboardContext_->keyEvent(key.detail, event)) bell(); dispatch(event); break; } case XCB_REPARENT_NOTIFY: { auto& reparent = reinterpret_cast<const xcb_reparent_notify_event_t&>(ev); auto wc = windowContext(reparent.window); if(wc) wc->reparentEvent(); break; } case XCB_CONFIGURE_NOTIFY: { auto& configure = reinterpret_cast<const xcb_configure_notify_event_t&>(ev); //todo: something about window state auto nsize = nytl::Vec2ui(configure.width, configure.height); // auto npos = nytl::Vec2i(configure.x, configure.y); //positionEvent auto wc = windowContext(configure.window); if(wc) wc->sizeEvent(nsize); if(!eventHandler(configure.window)) break; /* TODO XXX !important if(any(windowContext(configure.window)->window().size() != nsize)) //sizeEvent { EventHandlerEvent(SizeEvent, configure.window); event->size = nsize; event->change = 0; dispatcher.dispatch(std::move(event)); auto wc = windowContext(configure.window); if(!wc) return true; auto wevent = std::make_unique<SizeEvent>(wc); wevent->size = nsize; wevent->change = 0; dispatcher.dispatch(std::move(wevent)); } if(any(windowContext(configure.window)->window().position() != npos)) { EventHandlerEvent(PositionEvent, configure.window); event->position = npos; event->change = 0; dispatcher.dispatch(std::move(event)); } */ break; } case XCB_CLIENT_MESSAGE: { auto& client = reinterpret_cast<const xcb_client_message_event_t&>(ev); auto protocol = static_cast<unsigned int>(client.data.data32[0]); if(protocol == atoms().wmDeleteWindow) { EventHandlerEvent(CloseEvent, client.window); dispatch(event); } break; } case 0u: { //an error occurred! int code = reinterpret_cast<const xcb_generic_error_t&>(ev).error_code; auto errorMsg = x11::errorMessage(xDisplay(), code); warning("ny::X11AppContext::processEvent: retrieved error code ", code, ", ", errorMsg); break; } default: { //check for xkb event if(ev.response_type == keyboardContext_->xkbEventType()) keyboardContext_->processXkbEvent(ev); // May be needed for gl to work correctly... (TODO: test) // XLockDisplay(xDisplay_); // auto proc = XESetWireToEvent(xDisplay_, ev.response_type & ~0x80, nullptr); // if(proc) // { // XESetWireToEvent(xDisplay_, ev.response_type & ~0x80, proc); // XEvent dummy; // ev.sequence = LastKnownRequestProcessed(xDisplay_); // if(proc(xDisplay_, &dummy, (xEvent*) &ev)) //not handled // { // //TODO // } // } // // XUnlockDisplay(xDisplay_); } } #undef EventHandlerEvent }
bool InchiLineFormat::read(const std::string &formula, chemkit::Molecule *molecule) { // verify formula if(formula.empty()){ return 0; } QString formulaString = formula.c_str(); // add `InChI=` to the start if it is not there if(formula.compare(0, 6, "InChI=") != 0){ formulaString.prepend("InChI="); } // setup input struct inchi_InputINCHI input; input.szInChI = new char[formulaString.size()+1]; strncpy(input.szInChI, formulaString.toAscii().data(), formulaString.size()+1); input.szOptions = 0; // get inchi output inchi_OutputStruct output; int ret = GetStructFromStdINCHI(&input, &output); Q_UNUSED(ret); // build molecule from inchi output QVector<chemkit::Atom *> atoms(output.num_atoms); bool addHydrogens = option("add-hydrogens").toBool(); // add atoms for(int i = 0; i < output.num_atoms; i++){ inchi_Atom *inchiAtom = &output.atom[i]; chemkit::Atom *atom = molecule->addAtom(inchiAtom->elname); atoms[i] = atom; // add implicit hydrogens (if enabled) if(addHydrogens){ for(int j = 0; j < inchiAtom->num_iso_H[0]; j++){ chemkit::Atom *hydrogen = molecule->addAtom(chemkit::Atom::Hydrogen); molecule->addBond(atom, hydrogen); } } } // add bonds for(int i = 0; i < output.num_atoms; i++){ inchi_Atom *inchiAtom = &output.atom[i]; chemkit::Atom *atom = atoms[i]; for(int j = 0; j < inchiAtom->num_bonds; j++){ chemkit::Atom *neighbor = atoms[inchiAtom->neighbor[j]]; molecule->addBond(atom, neighbor, inchiAtom->bond_type[j]); } } // free input and output structures delete [] input.szInChI; FreeStructFromStdINCHI(&output); return true; }