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; }
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); }