Exemplo n.º 1
0
Arquivo: qmmm.c Projeto: t-/adaptive
/*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 */
Exemplo n.º 2
0
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;

}
Exemplo n.º 3
0
Arquivo: qmmm.c Projeto: t-/adaptive
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 */