Example #1
0
void create_read_tnc2(const char *file_name)
{
  if(!read_tnc2)
    read_tnc2 = new ReadNetCDFTrajectoryFile(file_name);
  else {
    cout << " NetCDF MD trajectory has been created already with file name: " 
	 << read_tnc2->file_name() << endl;
    QCrash("Error");
  }
}
// Read geometry and gradient into a molecule object.
// The fragments must already exist with the number of atoms in each set
// and with allocated memory.
void MOLECULE::read_geom_grad(void) {
  int nallatom = g_natom();

#if defined(OPTKING_PACKAGE_PSI)
  // for now read from file 11
  std::ifstream fin;

  string lbl;
  char cline[256];
  int junk;

  try {
    fin.open(FILENAME_GEOM_GRAD_IN, ios_base::in);
    fin.clear();
    fin.exceptions(ios_base::failbit);
    fin.seekg(0);

    // rewind, determine number of geometries
    int nlines = 0;
    try { // ignore exceptions only here
      while (fin.peek() != EOF) {
        fin.getline(cline, 256);
        ++nlines;
      }
    }
    catch (std::ios_base::failure & bf) { }

    int ngeom = nlines / (2*nallatom+2);

    // rewind through old geometries
    fin.clear();
    fin.seekg(0);
    for (int i=0; i< (ngeom-1)*(2*nallatom+2); ++i)
      fin.getline(cline, 256);

    // header line
    fin.getline(cline, 256);

    fin >> junk;
    if (junk != nallatom) throw(INTCO_EXCEPT("wrong number of atoms in text file"));
    fin >> energy;

    for (int f=0; f<fragments.size; ++f) {
      double *Z = fragments[f]->g_Z_pointer();
      double **geom = fragments[f]->g_geom_pointer();

      for (int i=0; i<fragments[f]->g_natom(); ++i) {
        //// check to see if atomic number or symbol
        //if ( isalpha((lbl.c_str())[0]) )
          //Z[i] = Element_to_Z(lbl);
        //else
          fin >> Z[i];

        fin >> geom[i][0];
        fin >> geom[i][1];
        fin >> geom[i][2];
      }
    }

    for (int f=0; f<fragments.size; ++f) {
      double **grad = fragments[f]->g_grad_pointer();
      for (int i=0; i<fragments[f]->g_natom(); ++i) {
        fin >> grad[i][0];
        fin >> grad[i][1];
        fin >> grad[i][2];
      }
    }
    psi::Communicator::world->sync();
    fin.close();
  } // end try reading geometries
  catch (std::ios_base::failure & bf) {
    printf("Error reading molecular geometry and gradient\n");
    fprintf(outfile,"Error reading molecular geometry and gradient\n");
    throw(INTCO_EXCEPT("Error reading molecular geometry and gradient"));
  }

#elif defined(OPTKING_PACKAGE_QCHEM)

  int EFPfrag = 0;
  int EFPatom = 0;
  if (Opt_params.efp_fragments) {
    EFPfrag = EFP::GetInstance()->NFragments();
    std::vector<int> AtomsinEFP = EFP::GetInstance()->NEFPAtoms();
    for (int i = 0; i < EFPfrag; ++i)
      EFPatom += AtomsinEFP[i];
    fprintf(outfile,"\t %d EFP fragments containing %d atoms.\n", EFPfrag, EFPatom);
  }

  double *QX;
  INTEGER *QZ, QNATOMS;
  bool Qnoghosts = true;

  ::get_carts(NULL, &QX, &QZ, &QNATOMS, Qnoghosts);

  int QNATOMS_real = g_natom();
  if (QNATOMS_real != (QNATOMS-EFPatom))
    QCrash("Number of computed real atoms is inconsistent.\n");

  fprintf(outfile, "\tNATOMS (total)=%d (minus EFP)=%d\n", QNATOMS, QNATOMS_real);

  if (Opt_params.print_lvl >= 3) {
    fprintf(outfile,"\tCartesian coordinates from ::get_carts().\n");
    print_array(outfile, QX, 3*QNATOMS);
  }

  int Numgrad = QNATOMS_real*3 + 6*EFPfrag;
  double* QGrad = init_array(Numgrad);

  ::FileMan_Open_Read(FILE_NUCLEAR_GRADIENT);
  ::FileMan(FM_READ, FILE_NUCLEAR_GRADIENT, FM_DP, Numgrad, 0, FM_BEG, QGrad);
  ::FileMan_Close(FILE_NUCLEAR_GRADIENT);

  // store geometry and gradient of real atoms in fragment objects
  int cnt=0;
  for (int f=0; f<fragments.size(); ++f) {

    double *Z = fragments[f]->g_Z_pointer();
    double **geom = fragments[f]->g_geom_pointer();
    double **grad = fragments[f]->g_grad_pointer();

    for (int i=0; i<fragments[f]->g_natom(); ++i) {
      Z[i] = QZ[cnt];
      for (int xyz=0; xyz<3; ++xyz) {
        geom[i][xyz] = QX[3*cnt+xyz];
        grad[i][xyz] = QGrad[3*cnt+xyz];
      }
      ++cnt;
    }

  }
  // Now read in gradients for EFP fragments
  for (int f=0; f<EFPfrag; ++f) {

    double *efp_f = init_array(6);
    for (int i=0; i<6; ++i)
      efp_f[i] = -1 * QGrad[3*QNATOMS_real + 6*f + i];

    efp_fragments[f]->set_forces(efp_f);
    free_array(efp_f);
  }
  free_array(QGrad);

  if (Opt_params.efp_fragments) {
    energy = EFP::GetInstance()->GetEnergy();
  }
  else {
    double E_tmp;
    ::FileMan_Open_Read(FILE_ENERGY);
    ::FileMan(FM_READ, FILE_ENERGY, FM_DP, 1, FILE_POS_CRNT_TOTAL_ENERGY, FM_BEG, &E_tmp);
    ::FileMan_Close(FILE_ENERGY);
    energy = E_tmp;
  }

#endif

  // update interfragment reference points if they exist
  for (int i=0; i<interfragments.size(); ++i)
    interfragments[i]->update_reference_points();

  return;
}