/*!
\todo
Allow center specification inline in the input file, rather than
having to read an external file.
 */
void Center_set::read(vector <string> & words, unsigned int pos,
                      System * sys)
{

  usingsampcenters=usingatoms=0;
  int nelectrons=sys->nelectrons(0)+sys->nelectrons(1);
  unsigned int startpos=pos;

  if(readvalue(words,pos, centerfile, "READ"))
  {

    readcenterfile(centerfile);
  }
  else
  {
    
    pos=startpos;
    if(haskeyword(words, pos,"USEATOMS"))
    {
      //cout << "using atoms " << endl;
      usingatoms=1;
      sys->getAtomicLabels(labels);
      ncenters=labels.size();
      //cout << "ncenters " << ncenters << endl;
    }
    else if(haskeyword(words, pos=0, "USEGLOBAL"))
    {
      usingsampcenters=1;
      sys->getCenterLabels(labels);
      ncenters=labels.size();

      //cout << ncenters << " centers from system " << endl;
    }
    else
    {
      error("Couldn't find anything in center section");
    }

  }

  if(usingsampcenters) {
    sys->getEquivalentCenters(equiv_centers, ncenters_atom, centers_displacement);
  }
  else {
    equiv_centers.Resize(ncenters,1);
    ncenters_atom.Resize(ncenters);
    centers_displacement.Resize(ncenters,3);
    centers_displacement=0;
    for(int cen=0; cen< ncenters; cen++) {
      equiv_centers(cen,0)=cen;
      ncenters_atom(cen)=1;
    }
  }


  edist.Resize(nelectrons,ncenters, 5);
  nbasis.Resize(ncenters);
  nbasis=0;
}
Exemple #2
0
//----------------------------------------------------------------------
void Average_ekt::read(vector <string> & words) { 
  unsigned int pos=0;

  readvalue(words, pos=0,nmo,"NMO");
  readvalue(words,pos=0,npoints_eval,"NPOINTS");
  if(haskeyword(words, pos=0,"OBDM")) 
    eval_obdm=true; 
  else 
    eval_obdm=false;
  if(haskeyword(words, pos=0,"CONDUCTION")) 
    eval_conduction=true; 
  else 
    eval_conduction=false;
  if(haskeyword(words,pos=0,"VALENCE")) 
    eval_valence=true;
  else 
    eval_valence=false;
  if(haskeyword(words,pos=0,"CORBITALS")) 
    complex_orbitals=true;
  else 
    complex_orbitals=false;

  eval_obdm=true; 
  eval_valence=true; 
  eval_conduction=true; 
  occupations.Resize(1);
  occupations(0).Resize(nmo);
  vector <string> orbs;
  if(!readsection(words,pos=0,orbs,"STATES")) { 
    cout << "WARNING: init section does not contain states. Numbering of the density matrix may be incorrect." << endl;
    for(int i=0; i < nmo; i++) 
      occupations[0][i]=i;
  }
  else { 
    nmo=orbs.size();
    occupations[0].Resize(nmo);
    for(int i=0; i< nmo; i++) 
      occupations[0][i]=atoi(orbs[i].c_str())-1;
  }

}
/*!
*/
void Postprocess_method::read(vector <string> words,
                       unsigned int & pos,
                       Program_options & options)
{

  if(!readvalue(words, pos=0, configfile, "READCONFIG"))
    error("Need READCONFIG in Postprocess");
  
  if(!readvalue(words, pos=0, nskip, "NSKIP"))
    nskip=0;
  
  evaluate_energy=true;
  if(haskeyword(words,pos=0,"NOENERGY")) evaluate_energy=false;

  vector <vector < string> > dens_words;
  vector<string> tmp_dens;
  pos=0;
  while(readsection(words, pos, tmp_dens, "DENSITY")) {
    dens_words.push_back(tmp_dens);
  }


  vector <vector < string> > avg_words;
  pos=0;
  while(readsection(words, pos, tmp_dens, "AVERAGE")) {
    avg_words.push_back(tmp_dens);
  }

  
  sys=NULL;
  allocate(options.systemtext[0],  sys);
  sys->generatePseudo(options.pseudotext, pseudo);
  debug_write(cout, "wfdata allocate\n");
  wfdata=NULL;
  if(options.twftext.size() < 1) error("Need TRIALFUNC section for POSTPROCESS");
  allocate(options.twftext[0], sys, wfdata);



   
  average_var.Resize(avg_words.size());
  average_var=NULL;
  for(int i=0; i< average_var.GetDim(0); i++) { 
    allocate(avg_words[i], sys, wfdata, average_var(i));
  }

  densplt.Resize(dens_words.size());
  for(int i=0; i< densplt.GetDim(0); i++) {
    allocate(dens_words[i], sys, options.runid,densplt(i));
  }

  
}
void Dmc_method::read(vector <string> words,
                      unsigned int & pos,
                      Program_options & options)
{
  ndim=3;

  have_read_options=1;

  //vector <string> offsetwords;

  //required options
  if(!readvalue(words, pos=0, timestep, "TIMESTEP"))
    error("Need TIMESTEP in METHOD section");

  //optional options

  if(!readvalue(words, pos=0, nblock, "NBLOCK"))
    nblock=100;
 
  int target_config;
  if(!readvalue(words,pos=0,target_config,"TARGET_CONFIG"))
    target_config=2048;

  if(!readvalue(words, pos=0, nconfig, "NCONFIG"))
    nconfig=max(target_config/mpi_info.nprocs,1);

  if(!readvalue(words, pos=0, nstep, "NSTEP"))
    nstep=max(int(1.0/timestep+0.5),1);
  
  if(!readvalue(words, pos=0, readconfig, "READCONFIG"))
    readconfig=options.runid+".config";

  if(!readvalue(words, pos=0, eref, "EREF"))
    eref=0.0;

  if(!readvalue(words,pos=0, max_poss_weight, "MAX_POSS_WEIGHT")) 
    max_poss_weight=7.0;
  if(haskeyword(words, pos=0, "TMOVES")) tmoves=1;
  else tmoves=0;
  if(haskeyword(words, pos=0, "TMOVESSC")) tmoves_sizeconsistent=1;
  else tmoves_sizeconsistent=0;


  readvalue(words,pos=0,save_trace,"SAVE_TRACE");

  if(!readvalue(words, pos=0, nhist, "CORR_HIST")) 
    nhist=-1;

  if(haskeyword(words, pos=0, "PURE_DMC")) { 
    pure_dmc=1;
    if( nhist < 1 )
      error("CORR_HIST must be > 1 when PURE_DMC is on");
  }
  else pure_dmc=0;

  if(!readvalue(words, pos=0, storeconfig, "STORECONFIG"))
    storeconfig=options.runid+".config";

  if(!readvalue(words, pos=0, log_label, "LABEL"))
    log_label="dmc";

  if(!readvalue(words, pos=0, start_feedback, "START_FEEDBACK"))
    start_feedback=1;

  if(readvalue(words, pos=0, feedback_interval, "FEEDBACK_INTERVAL")) {
    if(feedback_interval < 1) 
      error("FEEDBACK_INTERVAL must be greater than or equal to 1");
  }
  else feedback_interval=5;

  if(!readvalue(words, pos=0, feedback, "FEEDBACK"))
    feedback=1.0;

  if(!readvalue(words, pos=0, branch_start_cutoff, "BRANCH_START_CUTOFF")) 
    branch_start_cutoff=10;
  
  branch_stop_cutoff=branch_start_cutoff*1.5;
  
  
  vector <string> proptxt;
  if(readsection(words, pos=0, proptxt, "PROPERTIES")) 
    mygather.read(proptxt);

  vector<string> tmp_dens;
  pos=0;
  while(readsection(words, pos, tmp_dens, "DENSITY")) {
    dens_words.push_back(tmp_dens);
  }

  pos=0;
  while(readsection(words, pos, tmp_dens, "NONLOCAL_DENSITY")) {
    nldens_words.push_back(tmp_dens);
  }

  pos=0;
  while(readsection(words, pos, tmp_dens, "AVERAGE")) {
    avg_words.push_back(tmp_dens);
  }
  
  vector <string> dynamics_words;
  if(!readsection(words, pos=0, dynamics_words, "DYNAMICS") ) 
    dynamics_words.push_back("SPLIT");

  low_io=0;
  if(haskeyword(words, pos=0,"LOW_IO")) low_io=1;
  
  allocate(dynamics_words, dyngen);
  dyngen->enforceNodes(1);

  //MB: forwark walking lengths 
  fw_length.Resize(0);
  fw_length=0;
  vector <string> fw_words;
  max_fw_length=0;
  if(readsection(words, pos=0, fw_words, "fw_length")){
    fw_length.Resize(fw_words.size());
    for(int i=0;i<fw_words.size();i++){
      fw_length(i)=atoi(fw_words[i].c_str());
      if(fw_length(i) > max_fw_length)
        max_fw_length=fw_length(i);
    }
  }
  //cout <<" Maximum forward walking history is "<<max_fw_length<<" steps"<<endl;

}
void Jastrow_threebody_piece_diffspin::set_up(vector <string> & words, 
                                   System * sys) {
  //cout <<"Start Jastrow_threebody_piece_diffspin::set_up"<<endl;                                 
  vector<string> atomnames;
  sys->getAtomicLabels(atomnames);
  unique_parameters_spin.Resize(2);
  linear_parms.Resize(2);
  int tmpcounter=0;
  for(int s=0;s<unique_parameters_spin.GetSize();s++){
    get_onebody_parms_diffspin(words, atomnames, unique_parameters_spin(s),s,
			       _nparms, parm_labels,
			       linear_parms(s), tmpcounter, parm_centers);
  }

  


  if(unique_parameters_spin(0).GetDim(0)!=unique_parameters_spin(1).GetDim(0))
    error("Need same amount of LIKE_COEFFICIENTS and UNLIKE_COEFFICIENTS sections in three body");
  
  if(unique_parameters_spin(0).GetDim(1)!=unique_parameters_spin(1).GetDim(1))
    error("Need same amount of LIKE_COEFFICIENTS and UNLIKE_COEFFICIENTS parameters in three body");
  

  unsigned int pos=0;  
  int maxnparms=0;
  vector <string> klm_list;
  if(readsection(words,pos=0,klm_list,"SM_TERMS")) { 
    if(klm_list.size()%3 !=0) 
      error("SM_TERMS must contain a multiple of 3 elements");
    maxnparms=klm_list.size()/3;
    int counter=0;
    klm.Resize(maxnparms,3);
    for(int i=0; i< maxnparms; i++) { 
      for(int j=0; j< 3; j++) {
	klm(i,j)=atoi(klm_list[counter++].c_str());
      }
    }
  }
  else maxnparms=make_default_list();

  
  


  int natoms=atomnames.size();
  eebasis_max=0;
  eibasis_max.Resize(natoms);
  eibasis_max=0;
  for(int at=0; at< natoms; at++) {
    if(nparms(at) > maxnparms) 
      error("too many three-body spin parameters on ", atomnames[at]);
    for(int p=0; p < nparms(at); p++) { 
      if(eibasis_max(at) <= klm(p,0)) eibasis_max(at)=klm(p,0)+1;
      if(eibasis_max(at) <= klm(p,1)) eibasis_max(at)=klm(p,1)+1;
      if(eebasis_max <= klm(p,2)) eebasis_max=klm(p,2)+1;
    }
  }
  
  freeze=haskeyword(words, pos=0, "FREEZE");
  nspin_up=sys->nelectrons(0);
  nelectrons=sys->nelectrons(0)+sys->nelectrons(1);
  //cout <<"End Jastrow_threebody_piece_diffspin::set_up"<<endl;  

}
Exemple #6
0
void Average_ekt::read(System * sys, Wavefunction_data * wfdata, vector
    <string> & words) { 
  unsigned int pos=0;
  vector <string> orbs;
  vector <string> mosec;
  if(readsection(words,pos=0, mosec,"ORBITALS")) { 
    //error("Need ORBITALS section in ekt");
    complex_orbitals=false;
    allocate(mosec,sys,momat);
    nmo=momat->getNmo();
  }
  else if(readsection(words,pos=0,mosec,"CORBITALS")) { 
    complex_orbitals=true;
    allocate(mosec,sys,cmomat);
    nmo=cmomat->getNmo();
  }
  else { error("Need ORBITALS or CORBITALS in EKT"); } 
  occupations.Resize(1);

  if(readsection(words,pos=0,orbs,"STATES")) { 
    nmo=orbs.size();
    occupations[0].Resize(nmo);
    for(int i=0; i< nmo; i++) 
      occupations[0][i]=atoi(orbs[i].c_str())-1;
  }
  else if(readsection(words,pos=0,orbs,"EVAL_ORBS")) { 
    nmo=orbs.size();
    occupations[0].Resize(nmo);
    for(int i=0; i< nmo; i++) 
      occupations[0][i]=atoi(orbs[i].c_str());
  }
  else { 
    occupations[0].Resize(nmo);
    for(int i=0; i< nmo; i++) { 
      occupations[0][i]=i;
    }
  }

  deterministic_psp=0;
  if(haskeyword(words,pos=0,"DETERMINISTIC_PSP"))
    deterministic_psp=1;

  dump_data=false;
  if(haskeyword(words,pos=0,"DUMP_DATA"))
    dump_data=true;
  if(!readvalue(words, pos=0,ekt_cutoff,"EKT_CUTOFF"))
    ekt_cutoff=1e3;
  
  
  if(complex_orbitals) 
    cmomat->buildLists(occupations);
  else 
    momat->buildLists(occupations);



  if(!readvalue(words, pos=0,nstep_sample,"NSTEP_SAMPLE"))
    nstep_sample=10;
  if(!readvalue(words,pos=0,npoints_eval,"NPOINTS"))
    npoints_eval=4;
  string mode;
  eval_obdm=false; 
  eval_conduction=false; 
  eval_valence=false; 
  if(readvalue(words,pos=0,mode,"MODE")) {
    if(caseless_eq(mode,"ALL") or caseless_eq(mode, "CONDUCTION")) {
      eval_obdm=true;
      eval_conduction=true;
      eval_valence=true; 
    }
    else if (caseless_eq(mode, "VALENCE")) {
      eval_obdm=true; 
      eval_conduction=true;
    }
    else if (caseless_eq(mode, "OBDM")) {
      eval_obdm=true; 
    }

  }

  eval_obdm=true; 
  eval_conduction=true; 
  eval_valence=true; 
  int ndim=3;
  saved_r.Resize(npoints_eval*2); //r1 and r2;
  for(int i=0; i< npoints_eval*2; i++) saved_r(i).Resize(ndim);
  rk.Resize(npoints_eval*2);

  int warmup_steps=1000;
  Sample_point * sample=NULL;
  sys->generateSample(sample);
  sample->randomGuess();
  Array2 <dcomplex> movals(nmo,1);
  for(int i=0; i< npoints_eval*2; i++) { 
    gen_sample(warmup_steps,1.0,0,movals,sample);
    sample->getElectronPos(0,saved_r(i));
  }
  delete sample;
}
//-------------------------------------------------------------------------
int Cubic_spline::read(
  vector <string> & words,
  unsigned int & pos
)
{

  Array1 <double> basisparms(4);
  atomname=words[0];
  basisparms(0)=.02;  //spacing
  basisparms(1)=2500; //number of points
  basisparms(2)=1e31;
  basisparms(3)=1e31;
  if(!readvalue(words, pos=0, norm_type, "NORMTYPE")) {
    norm_type="GAMESSNORM";
  }

  if(haskeyword(words, pos=0, "NORENORMALIZE")) {
    renormalize=false;
  }
  else {
    renormalize=true;
  }

  doublevar cutmax;
  if(readvalue(words, pos=0, cutmax, "CUTOFF")) {
    requested_cutoff=cutmax;
  }
  else {
    requested_cutoff=-1;
  }

  enforce_cusp=false;
  if(readvalue(words, pos=0, cusp, "CUSP")) enforce_cusp=true;

  match_sto=false;
  if(readvalue(words, pos=0, cusp_matching, "CUSP_MATCHING")) match_sto=true;
  
  zero_derivative=false;
  if(haskeyword(words, pos=0, "ZERO_DERIVATIVE")) zero_derivative=true;

  customspacing=basisparms(0);
  if(readvalue(words, pos=0, customspacing, "SPACING")) {
    basisparms(0)=customspacing;
    basisparms(1)=50.0/customspacing;
  }

  vector <string> basisspec;
  string read_file; //read positions from a file
  if(readsection(words,pos=0, basisspec, "GAMESS"))
  {
    unsigned int newpos=0;
    return readbasis(basisspec, newpos, basisparms);
  }
  else {
    pos=0;
    if(readspline(words)) {
      return 1;
    }
    else {
      error("couldn't find proper basis section in AOSPLINE.  "
            "Try GAMESS { .. }.");
      return 0;
    }
  }

  //We assume that all splines use the same interval,
  //which saves a few floating divisions, so check to make
  //sure the assumption is good.
  for(int i=0; i< splines.GetDim(0); i++) {
    if(!splines(0).match(splines(i))) 
      error("spline ", i, " doesn't match the first one ");
  }
}
void Reptation_method::read(vector <string> words,
                      unsigned int & pos,
                      Program_options & options)
{

  have_read_options=1;

  if(!readvalue(words, pos=0, nblock, "NBLOCK"))
    error("Need NBLOCK in RETPTATION section");

  if(!readvalue(words, pos=0, nstep, "NSTEP"))
    error("Need NSTEP in REPTATION section");

  if(!readvalue(words, pos=0, timestep, "TIMESTEP"))
    error("Need TIMESTEP in REPTATION section");

  if(!readvalue(words, pos=0, reptile_length, "LENGTH"))
    error("Need LENGTH in REPTATION");

  //------------------optional stuff

  print_pdb=haskeyword(words, pos=0,"PRINT_PDB");

  if(!readvalue(words, pos=0, readconfig, "READCONFIG"))
    readconfig=options.runid+".config";

  vector <string> proptxt;
  if(readsection(words, pos=0, proptxt, "PROPERTIES")) 
    mygather.read(proptxt);
  
  if(!readvalue(words, pos=0, log_label, "LABEL"))
    log_label="rmc";

  if(!readvalue(words, pos=0, storeconfig, "STORECONFIG"))
    storeconfig=options.runid+".config";

  if(readvalue(words, pos=0, center_trace, "CENTER_TRACE"))
    canonical_filename(center_trace);

  if(!readvalue(words, pos=0, trace_wait, "TRACE_WAIT"))
    trace_wait=int(.3/timestep)+1;

    
  vector <string> dynamics_words;
  if(!readsection(words, pos=0, dynamics_words, "DYNAMICS") ) 
    dynamics_words.push_back("SPLIT");

  allocate(dynamics_words, sampler);

  
  vector<string> tmp_dens;
  pos=0;
  while(readsection(words, pos, tmp_dens, "DENSITY")) {
    dens_words.push_back(tmp_dens);
  }
  
  pos=0;
  while(readsection(words, pos, tmp_dens, "AVERAGE")) {
    avg_words.push_back(tmp_dens);
  }
  

  sampler->enforceNodes(1);

  guidewf=new Primary;
}
/*!
*/
int HEG_system::read(vector <string> & words,
                          unsigned int & pos)
{
  const int ndim=3;
  int startpos=pos;

  vector <string> latvectxt;

  vector <string> spintxt;
  if(!readsection(words, pos, spintxt, "NSPIN")) {
    error("Need NSPIN in HEG system");
  }
  nspin.Resize(2);
  nspin(0)=atoi(spintxt[0].c_str());
  nspin(1)=atoi(spintxt[1].c_str());
  totnelectrons=nspin(0)+nspin(1);

  vector <string> ktxt;
  if(readsection(words, pos=0, ktxt, "KPOINT")) {
    if(ktxt.size()!=3) error("KPOINT must be a section of size 3");
    kpt.Resize(3);
    for(int i=0; i< 3; i++) 
      kpt(i)=atof(ktxt[i].c_str());
  }
  else {
    kpt.Resize(3);
    kpt=0;
  }

  pos=startpos;
  if(!readsection(words, pos, latvectxt, "BOXSIZE"))
    error("BOXSIZE is required in HEG");
  if(latvectxt.size() != ndim)
    error("BOXSIZE must have exactly ",ndim, " values");

  vector< vector<string> > perturb_sec;
  vector <string> dumstring;
  pos=startpos;
  while(readsection(words, pos,dumstring, "PERTURB")) perturb_sec.push_back(dumstring);
  nperturb=perturb_sec.size();
  perturb_pos.Resize(nperturb, ndim);
  perturb_strength.Resize(nperturb);
  perturb_alpha.Resize(nperturb);
  perturb_spin.Resize(nperturb);
  for(int i=0; i< nperturb; i++) { 
    if(!readsection(perturb_sec[i], pos=0,dumstring,"POS")) error("Need POS in PERTURB");
    if(dumstring.size()!=ndim) error("wrong dimension in POS in PERTURB");
    for(int d=0; d< ndim; d++) perturb_pos(i,d)=atof(dumstring[d].c_str());
    if(!readvalue(perturb_sec[i], pos=0,perturb_strength(i),"STRENGTH")) error("Need STRENGTH in PERTURB");
    if(!readvalue(perturb_sec[i], pos=0,perturb_alpha(i),"SCALE")) error("Need SCALE in PERTURB");
    if(!readvalue(perturb_sec[i], pos=0,perturb_spin(i),"SPIN")) error("Need SPIN in PERTURB");
    
  }

  latVec.Resize(ndim, ndim);
  latVec=0.0;
  for(int i=0; i< ndim; i++)
    latVec(i,i)=atof(latvectxt[i].c_str());
  /*
  for(int i=0; i< ndim; i++) {
    for(int j=0; j< ndim; j++) {
      latVec(i,j)=atof(latvectxt[i*ndim+j].c_str());
    }
  }
  */

  origin.Resize(3);
  vector <string> origintxt;
  if(readsection(words, pos=0, origintxt, "ORIGIN")) {
    if(origintxt.size() < 3) error("ORIGIN section must have at least 3 elements.");
    for(int i=0; i< 3; i++) origin(i)=atof(origintxt[i].c_str());
  }
  else {
    origin=0;   //defaulting the origin to zero
  }

  vector <string> interactiontxt;
  // default is truncated Coulomb
  calcLocChoice=&HEG_system::calcLocTrunc;
  eeModel=2;
  same_spin_int=true;
  diff_spin_int=true;
  if(readsection(words, pos=0, interactiontxt, "INTERACTION")) {
    if( haskeyword(interactiontxt, pos=0, "EWALD") ) {
      calcLocChoice=&HEG_system::calcLocEwald;
      eeModel=1;
    }
    if( haskeyword(interactiontxt, pos=0, "TRUNCCOUL") ) {
      calcLocChoice=&HEG_system::calcLocTrunc;
      eeModel=2;
    }
    if( haskeyword(interactiontxt, pos=0, "GAUSS") ) {
      calcLocChoice=&HEG_system::calcLocGauss;
      eeModel=3;
      if(!readvalue(interactiontxt,pos=0,Gauss_a, "AMP"))
	error("Gauss interaction model requested, but no AMP given.");
      if(!readvalue(interactiontxt,pos=0,Gauss_s, "STDEV"))
	error("Gauss interaction model requested, but no STDEV given.");
      Gauss_s2=Gauss_s*Gauss_s;
    }
    if( haskeyword(interactiontxt, pos=0, "NO_SAME_SPIN") )
      same_spin_int=false;
    if( haskeyword(interactiontxt, pos=0, "NO_DIFF_SPIN") )
      diff_spin_int=false;
  }

  if ( eeModel==1 && ( !same_spin_int || !diff_spin_int ) )
    error("Spin-dependent Ewald interaction not supported.");

  

  //-------------cross products

  //cross product:  0->1x2, 1->2x0, 2->0x1
  Array2 <doublevar> crossProduct(ndim, ndim);
  crossProduct(0,0)=(latVec(1,1)*latVec(2,2)-latVec(1,2)*latVec(2,1));
  crossProduct(0,1)=(latVec(1,2)*latVec(2,0)-latVec(1,0)*latVec(2,2));
  crossProduct(0,2)=(latVec(1,0)*latVec(2,1)-latVec(1,1)*latVec(2,0));

  crossProduct(1,0)=(latVec(2,1)*latVec(0,2)-latVec(2,2)*latVec(0,1));
  crossProduct(1,1)=(latVec(2,2)*latVec(0,0)-latVec(2,0)*latVec(0,2));
  crossProduct(1,2)=(latVec(2,0)*latVec(0,1)-latVec(2,1)*latVec(0,0));

  crossProduct(2,0)=(latVec(0,1)*latVec(1,2)-latVec(0,2)*latVec(1,1));
  crossProduct(2,1)=(latVec(0,2)*latVec(1,0)-latVec(0,0)*latVec(1,2));
  crossProduct(2,2)=(latVec(0,0)*latVec(1,1)-latVec(0,1)*latVec(1,0));


  //------------ reciprocal cell  (used in setupEwald and showinfo)
  recipLatVec.Resize(ndim, ndim);
  doublevar det=Determinant(latVec, ndim);

  debug_write(cout, "cell volume ", det,"\n");
  cellVolume=det;

  for(int i=0; i< ndim; i++) {
    for(int j=0; j< ndim; j++) {
      recipLatVec(i,j)=crossProduct(i,j)/det;
    }
  }

  //------------ normal vectors (needed in enforcePbc)

  normVec.Resize(ndim, ndim);

  for(int i=0; i< ndim; i++) {
    for(int j=0; j < ndim; j++) {
      normVec(i,j)=crossProduct(i,j);
    }

    //Check to make sure the direction is facing out
    doublevar dotprod=0;
    for(int j=0; j < ndim; j++) {
      dotprod+=normVec(i,j)*latVec(i,j);
    }
    if(dotprod < 0) {
      for(int j=0; j< ndim; j++) {
        normVec(i,j)= -normVec(i,j);
      }
    }
  }

  corners.Resize(ndim, ndim);
  for(int i=0; i< ndim; i++) {
    for(int j=0; j< ndim; j++) {
      corners(i,j)=origin(j)+latVec(i,j);
    }
  }


  //------------ setup for interaction calculators (reciprocal part of Ewald sum etc.)
  if ( eeModel == 1 ) setupEwald(crossProduct);
  if ( eeModel == 2 ) setupTruncCoulomb();

  return 1;
}