/*initialization Gaussian/Mopac/etc*/ void init_QMroutine(t_commrec *cr, t_QMrec *qm, t_MMrec *mm) { /* makes a call to the requested QM routine (qm->QMmethod) */ if (qm->QMmethod<eQMmethodRHF){ #ifdef GMX_QMMM_MOPAC /* do a semi-empiprical calculation */ init_mopac(cr,qm,mm); #else gmx_fatal(FARGS,"Semi-empirical QM only supported with Mopac."); #endif } else { /* do an ab-initio calculation */ #ifdef GMX_QMMM_GAMESS init_gamess(cr,qm,mm); #elif defined GMX_QMMM_GAUSSIAN init_gaussian(cr,qm,mm); #elif defined GMX_QMMM_ORCA init_orca(cr,qm,mm); #else gmx_fatal(FARGS,"Ab-initio calculation only supported with Gamess, Gaussian or ORCA."); #endif } } /* init_QMroutine */
int main( int argc, char* argv[]) { //Parameter initialisation std::vector<double> para; if( argc == 1) { std::cout << "Reading from input.txt\n"; try{ para = file::read_input( "input.txt"); } catch (toefl::Message& m) { m.display(); throw m; } } else if( argc == 2) { std::cout << "Reading from "<<argv[1]<<"\n"; try{ para = file::read_input( argv[1]); } catch (toefl::Message& m) { m.display(); throw m; } } else { std::cerr << "ERROR: Too many arguments!\nUsage: "<< argv[0]<<" [filename]\n"; return -1; } omp_set_num_threads( para[20]); std::cout<< "With "<<omp_get_max_threads()<<" threads\n"; const toefl::Parameters p(para); field_ratio = p.lx/p.ly; if( p.bc_x != toefl::TL_PERIODIC) { std::cerr << "Only periodic boundaries allowed!\n"; return -1; } try{p.consistencyCheck();} catch( toefl::Message& m){m.display();throw m;} p.display(std::cout); //construct solvers toefl::DFT_DFT_Solver<3> solver( p); // place some gaussian blobs in the field try{ toefl::Matrix<double, toefl::TL_DFT> ne{ p.ny, p.nx, 0.}, nz{ ne}, phi{ ne}; init_gaussian( ne, p.posX, p.posY, p.blob_width/p.lx, p.blob_width/p.ly, p.amp); //init_gaussian_column( nz, 0.6, 0.05/field_ratio, p.imp_amp); std::array< toefl::Matrix<double, toefl::TL_DFT>,3> arr3{{ ne, nz, phi}}; //now set the field to be computed solver.init( arr3, toefl::IONS); }catch( toefl::Message& m){m.display();} cv::VideoCapture cap(0); if( !cap.isOpened()) { std::cerr << "Camera not found\n"; return -1; } cap.set( CV_CAP_PROP_FRAME_WIDTH, p.nx); cap.set( CV_CAP_PROP_FRAME_HEIGHT, p.ny); cv::Mat last, current, flow, vel(p.ny, p.nx, CV_32F); std::vector<cv::Mat> v; cv::namedWindow("Current",cv::WINDOW_NORMAL); cv::namedWindow("Velocity",cv::WINDOW_NORMAL); double t = 0.; toefl::Timer timer; toefl::Timer overhead; solver.first_step(); solver.second_step(); t+= 2*p.dt; toefl::Matrix<double, toefl::TL_DFT> src( p.ny, p.nx, 0.); cv::Mat grey, colored, show( p.ny, p.nx, CV_32F); cap >> last; cv::cvtColor( last, last, CV_BGR2GRAY); //convert colors while( true) { init_gaussian( src, 0.5+0.25*sin(t), 0.75, p.blob_width/p.lx, p.blob_width/p.ly, p.amp); cap >> current; // get a new frame from camera cv::cvtColor(current, current, CV_BGR2GRAY); //convert colors cv::GaussianBlur(current, current, cv::Size(21,21), 0, 0); //Kernel size, sigma_x, sigma_y calcOpticalFlowFarneback(last, current, flow, 0.5, 1, 5, 3, 5, 1.2, 0); cv::split( flow, v); //erster index y, zweiter index x for( unsigned i=0; i<v[0].rows; i++) for( unsigned j=0; j<v[0].cols; j++) vel.at<float>( i,j) = sqrt( v[0].at<float>(i,j)*v[0].at<float>(i,j) + v[1].at<float>(i,j)*v[1].at<float>(i,j) ); for( unsigned i=0; i<vel.rows; i++) for( unsigned j=0; j<vel.cols; j++) if( vel.at<float>(i,j) < 1) vel.at<float>(i,j) = 0; //scale velocity to 1 in order to account for distance from camera double min, max; cv::minMaxLoc( vel, &min, &max); std::cout << min <<" "<<max<<std::endl; if( max > 1) // if someone is there for( unsigned i=0; i<vel.rows; i++) for( unsigned j=0; j<vel.cols; j++) vel.at<float>( i,j) /= max; cv::flip( vel, vel, +1); //for( unsigned i=0; i<src.rows(); i++) // for( unsigned j=0; j<src.cols(); j++) // src(i,j) = 0.5*vel.at<double>(i,j); overhead.tic(); //const toefl::Matrix<double, toefl::TL_DFT>& field = solver.getField( toefl::IMPURITIES); const toefl::Matrix<double, toefl::TL_DFT>& field = solver.getField( toefl::ELECTRONS); for( unsigned i=0; i<p.ny; i++) for( unsigned j=0; j<p.nx; j++) show.at<float>(i,j) = (float)field(i,j); cv::minMaxLoc( show, &min, &max); show.convertTo(grey, CV_8U, 255.0/(2.*max), 255.0/2.); cv::minMaxLoc( grey, &min, &max); //cv::applyColorMap( grey, colored, cv::COLORMAP_BONE); //cv::applyColorMap( grey, colored, cv::COLORMAP_COOL); //cv::applyColorMap( grey, colored, cv::COLORMAP_HOT); //cv::applyColorMap( grey, colored, cv::COLORMAP_HSV); //cv::applyColorMap( grey, colored, cv::COLORMAP_JET); cv::applyColorMap( grey, colored, cv::COLORMAP_OCEAN); //cv::applyColorMap( grey, colored, cv::COLORMAP_PINK); //cv::applyColorMap( grey, colored, cv::COLORMAP_RAINBOW); //cv::applyColorMap( grey, colored, cv::COLORMAP_SPRING); //cv::applyColorMap( grey, colored, cv::COLORMAP_SUMMER); //cv::applyColorMap( grey, colored, cv::COLORMAP_AUTUMN); //cv::applyColorMap( grey, colored, cv::COLORMAP_WINTER); window_str << std::setprecision(2) << std::fixed; window_str << "time = "<<t; //cv::addText( colored, window_str.str(), cv::Point(50,50)); window_str.str(""); std::cout << colored.rows << " " << colored.cols<<"\n"; std::cout << vel.rows << " " << vel.cols<<"\n"; std::cout << show.rows << " " << show.cols<<"\n"; std::cout << src.rows() << " " << src.cols()<<"\n"; cv::imshow("Current", colored); //for( unsigned i=0; i<src.rows(); i++) //for( unsigned j=0; j<src.cols(); j++) //show.at<double>(i,j) = src(i,j); cv::imshow("Velocity", vel); timer.tic(); for(unsigned i=0; i<p.itstp; i++) { toefl::Matrix<double, toefl::TL_DFT> voidmatrix( 2,2,(bool)toefl::TL_VOID); solver.step(src ); t+= p.dt; } timer.toc(); overhead.toc(); //swap fields cv::Mat temp = last; last = current; current = temp; if(cv::waitKey(30) >= 0) break; } ////////////////////////////////glfw and opencv////////////////////////////// std::cout << "Average time for one step = "<<timer.diff()/(double)p.itstp<<"s\n"; std::cout << "Overhead for visualisation, etc. per step = "<<(overhead.diff()-timer.diff())/(double)p.itstp<<"s\n"; ////////////////////////////////////////////////////////////////// fftw_cleanup(); return 0; }
void init_QMMMrec(t_commrec *cr, matrix box, gmx_mtop_t *mtop, t_inputrec *ir, t_forcerec *fr) { /* we put the atomsnumbers of atoms that belong to the QMMM group in * an array that will be copied later to QMMMrec->indexQM[..]. Also * it will be used to create an QMMMrec->bQMMM index array that * simply contains true/false for QM and MM (the other) atoms. */ gmx_groups_t *groups; atom_id *qm_arr=NULL,vsite,ai,aj; int qm_max=0,qm_nr=0,i,j,jmax,k,l,nrvsite2=0; t_QMMMrec *qr; t_MMrec *mm; t_iatom *iatoms; real c12au,c6au; gmx_mtop_atomloop_all_t aloop; t_atom *atom; gmx_mtop_ilistloop_all_t iloop; int a_offset; t_ilist *ilist_mol; c6au = (HARTREE2KJ*AVOGADRO*pow(BOHR2NM,6)); c12au = (HARTREE2KJ*AVOGADRO*pow(BOHR2NM,12)); fprintf(stderr,"there we go!\n"); /* Make a local copy of the QMMMrec */ qr = fr->qr; /* bQMMM[..] is an array containing TRUE/FALSE for atoms that are * QM/not QM. We first set all elemenst at false. Afterwards we use * the qm_arr (=MMrec->indexQM) to changes the elements * corresponding to the QM atoms at TRUE. */ qr->QMMMscheme = ir->QMMMscheme; /* we take the possibility into account that a user has * defined more than one QM group: */ /* an ugly work-around in case there is only one group In this case * the whole system is treated as QM. Otherwise the second group is * always the rest of the total system and is treated as MM. */ /* small problem if there is only QM.... so no MM */ jmax = ir->opts.ngQM; if(qr->QMMMscheme==eQMMMschemeoniom) qr->nrQMlayers = jmax; else qr->nrQMlayers = 1; groups = &mtop->groups; /* there are jmax groups of QM atoms. In case of multiple QM groups * I assume that the users wants to do ONIOM. However, maybe it * should also be possible to define more than one QM subsystem with * independent neighbourlists. I have to think about * that.. 11-11-2003 */ snew(qr->qm,jmax); for(j=0;j<jmax;j++){ /* new layer */ aloop = gmx_mtop_atomloop_all_init(mtop); while (gmx_mtop_atomloop_all_next(aloop,&i,&atom)) { if(qm_nr >= qm_max){ qm_max += 1000; srenew(qm_arr,qm_max); } if (ggrpnr(groups,egcQMMM ,i) == j) { /* hack for tip4p */ qm_arr[qm_nr++] = i; } } if(qr->QMMMscheme==eQMMMschemeoniom){ /* add the atoms to the bQMMM array */ /* I assume that users specify the QM groups from small to * big(ger) in the mdp file */ qr->qm[j] = mk_QMrec(); /* we need to throw out link atoms that in the previous layer * existed to separate this QMlayer from the previous * QMlayer. We use the iatoms array in the idef for that * purpose. If all atoms defining the current Link Atom (Dummy2) * are part of the current QM layer it needs to be removed from * qm_arr[]. */ iloop = gmx_mtop_ilistloop_all_init(mtop); while (gmx_mtop_ilistloop_all_next(iloop,&ilist_mol,&a_offset)) { nrvsite2 = ilist_mol[F_VSITE2].nr; iatoms = ilist_mol[F_VSITE2].iatoms; for(k=0; k<nrvsite2; k+=4) { vsite = a_offset + iatoms[k+1]; /* the vsite */ ai = a_offset + iatoms[k+2]; /* constructing atom */ aj = a_offset + iatoms[k+3]; /* constructing atom */ if (ggrpnr(groups, egcQMMM, vsite) == ggrpnr(groups, egcQMMM, ai) && ggrpnr(groups, egcQMMM, vsite) == ggrpnr(groups, egcQMMM, aj)) { /* this dummy link atom needs to be removed from the qm_arr * before making the QMrec of this layer! */ for(i=0;i<qm_nr;i++){ if(qm_arr[i]==vsite){ /* drop the element */ for(l=i;l<qm_nr;l++){ qm_arr[l]=qm_arr[l+1]; } qm_nr--; } } } } } /* store QM atoms in this layer in the QMrec and initialise layer */ init_QMrec(j,qr->qm[j],qm_nr,qm_arr,mtop,ir); /* we now store the LJ C6 and C12 parameters in QM rec in case * we need to do an optimization */ if(qr->qm[j]->bOPT || qr->qm[j]->bTS){ for(i=0;i<qm_nr;i++){ qr->qm[j]->c6[i] = C6(fr->nbfp,mtop->ffparams.atnr, atom->type,atom->type)/c6au; qr->qm[j]->c12[i] = C12(fr->nbfp,mtop->ffparams.atnr, atom->type,atom->type)/c12au; } } /* now we check for frontier QM atoms. These occur in pairs that * construct the vsite */ iloop = gmx_mtop_ilistloop_all_init(mtop); while (gmx_mtop_ilistloop_all_next(iloop,&ilist_mol,&a_offset)) { nrvsite2 = ilist_mol[F_VSITE2].nr; iatoms = ilist_mol[F_VSITE2].iatoms; for(k=0; k<nrvsite2; k+=4){ vsite = a_offset + iatoms[k+1]; /* the vsite */ ai = a_offset + iatoms[k+2]; /* constructing atom */ aj = a_offset + iatoms[k+3]; /* constructing atom */ if(ggrpnr(groups,egcQMMM,ai) < (groups->grps[egcQMMM].nr-1) && (ggrpnr(groups,egcQMMM,aj) >= (groups->grps[egcQMMM].nr-1))){ /* mark ai as frontier atom */ for(i=0;i<qm_nr;i++){ if( (qm_arr[i]==ai) || (qm_arr[i]==vsite) ){ qr->qm[j]->frontatoms[i]=TRUE; } } } else if(ggrpnr(groups,egcQMMM,aj) < (groups->grps[egcQMMM].nr-1) && (ggrpnr(groups,egcQMMM,ai) >= (groups->grps[egcQMMM].nr-1))){ /* mark aj as frontier atom */ for(i=0;i<qm_nr;i++){ if( (qm_arr[i]==aj) || (qm_arr[i]==vsite)){ qr->qm[j]->frontatoms[i]=TRUE; } } } } } } } if(qr->QMMMscheme!=eQMMMschemeoniom){ /* standard QMMM, all layers are merged together so there is one QM * subsystem and one MM subsystem. * Also we set the charges to zero in the md->charge arrays to prevent * the innerloops from doubly counting the electostatic QM MM interaction */ for (k=0;k<qm_nr;k++){ gmx_mtop_atomnr_to_atom(mtop,qm_arr[k],&atom); atom->q = 0.0; atom->qB = 0.0; } qr->qm[0] = mk_QMrec(); /* store QM atoms in the QMrec and initialise */ init_QMrec(0,qr->qm[0],qm_nr,qm_arr,mtop,ir); if(qr->qm[0]->bOPT || qr->qm[0]->bTS){ for(i=0;i<qm_nr;i++){ gmx_mtop_atomnr_to_atom(mtop,qm_arr[i],&atom); qr->qm[0]->c6[i] = C6(fr->nbfp,mtop->ffparams.atnr, atom->type,atom->type)/c6au; qr->qm[0]->c12[i] = C12(fr->nbfp,mtop->ffparams.atnr, atom->type,atom->type)/c12au; } } /* find frontier atoms and mark them true in the frontieratoms array. */ for(i=0;i<qm_nr;i++) { gmx_mtop_atomnr_to_ilist(mtop,qm_arr[i],&ilist_mol,&a_offset); nrvsite2 = ilist_mol[F_VSITE2].nr; iatoms = ilist_mol[F_VSITE2].iatoms; for(k=0;k<nrvsite2;k+=4){ vsite = a_offset + iatoms[k+1]; /* the vsite */ ai = a_offset + iatoms[k+2]; /* constructing atom */ aj = a_offset + iatoms[k+3]; /* constructing atom */ if(ggrpnr(groups,egcQMMM,ai) < (groups->grps[egcQMMM].nr-1) && (ggrpnr(groups,egcQMMM,aj) >= (groups->grps[egcQMMM].nr-1))){ /* mark ai as frontier atom */ if ( (qm_arr[i]==ai) || (qm_arr[i]==vsite) ){ qr->qm[0]->frontatoms[i]=TRUE; } } else if (ggrpnr(groups,egcQMMM,aj) < (groups->grps[egcQMMM].nr-1) && (ggrpnr(groups,egcQMMM,ai) >=(groups->grps[egcQMMM].nr-1))) { /* mark aj as frontier atom */ if ( (qm_arr[i]==aj) || (qm_arr[i]==vsite) ){ qr->qm[0]->frontatoms[i]=TRUE; } } } } /* MM rec creation */ mm = mk_MMrec(); mm->scalefactor = ir->scalefactor; mm->nrMMatoms = (mtop->natoms)-(qr->qm[0]->nrQMatoms); /* rest of the atoms */ qr->mm = mm; } else {/* ONIOM */ /* MM rec creation */ mm = mk_MMrec(); mm->scalefactor = ir->scalefactor; mm->nrMMatoms = 0; qr->mm = mm; } /* these variables get updated in the update QMMMrec */ if(qr->nrQMlayers==1){ /* with only one layer there is only one initialisation * needed. Multilayer is a bit more complicated as it requires * re-initialisation at every step of the simulation. This is due * to the use of COMMON blocks in the fortran QM subroutines. */ if (qr->qm[0]->QMmethod<eQMmethodRHF) { #ifdef GMX_QMMM_MOPAC /* semi-empiprical 1-layer ONIOM calculation requested (mopac93) */ init_mopac(cr,qr->qm[0],qr->mm); #else gmx_fatal(FARGS,"Semi-empirical QM only supported with Mopac."); #endif } else { /* ab initio calculation requested (gamess/gaussian/ORCA) */ #ifdef GMX_QMMM_GAMESS init_gamess(cr,qr->qm[0],qr->mm); #elif defined GMX_QMMM_GAUSSIAN init_gaussian(cr,qr->qm[0],qr->mm); #elif defined GMX_QMMM_ORCA init_orca(cr,qr->qm[0],qr->mm); #else gmx_fatal(FARGS,"Ab-initio calculation only supported with Gamess, Gaussian or ORCA."); #endif } } } /* init_QMMMrec */