Exemplo n.º 1
0
arma::vec DIIS::get_w() {
  // DIIS error
  arma::mat de=get_diis_error();
  double err=arma::max(arma::abs(de.col(de.n_cols-1)));

  // Weight
  arma::vec w;
  
  if(useadiis && !usediis) {
    w=get_w_adiis();
    if(verbose) {
      printf("ADIIS weights\n");
      print_mat(w.t(),"% .2e ");
    }    
  } else if(!useadiis && usediis) {
    // Use DIIS only if error is smaller than threshold
    if(err>diisthr)
      throw std::runtime_error("DIIS error too large.\n");

    w=get_w_diis();

    if(verbose) {
      printf("DIIS weights\n");
      print_mat(w.t(),"% .2e ");
    }    
  } else if(useadiis && usediis) {
    // Sliding scale
    double diisw=std::max(std::min(1.0 - (err-diisthr)/(diiseps-diisthr), 1.0), 0.0);

    // Determine cooloff
    if(cooloff>0) {
      diisw=0.0;
      cooloff--;
    } else {
      // Check if energy has increased
      arma::vec E=get_energies();
      if(E.n_elem>1 &&  E(E.n_elem-1)-E(E.n_elem-2) > COOLTHR) {
	cooloff=2;
	diisw=0.0;
      }
    }

    arma::vec wa=get_w_adiis();
    arma::vec wd=get_w_diis();
    w=diisw*wd + (1.0-diisw)*wa;
    
    if(verbose) {
      printf("ADIIS weights\n");
      print_mat(wa.t(),"% .2e ");
      printf("CDIIS weights\n");
      print_mat(wd.t(),"% .2e ");
      printf(" DIIS weights\n");
      print_mat(w.t(),"% .2e ");
    }    
    
  } else
    throw std::runtime_error("Nor DIIS or ADIIS has been turned on.\n");
    
  return w;
}
Exemplo n.º 2
0
void compute_energies(struct_all_ode *s, double * x) {
    struct_inputs_get_energies *sige = &s->inputs_get_energies;
    struct_outputs_get_energies *soge = &s->outputs_get_energies;
    sige->ph = x[INDX_PH];
    sige->th = x[INDX_TH];
    sige->x = x[INDX_X];
    sige->z = x[INDX_Z];
    sige->r = x[INDX_R];
    sige->vph = x[INDX_VPH];
    sige->vth = x[INDX_VTH];
    sige->vx = x[INDX_VX];
    sige->vz = x[INDX_VZ];
    sige->vr = x[INDX_VR];
    get_energies(soge, sige);
}