int is_on_cur_desk(Window w) { unsigned long w_desk, cur_desk; if (get_atoms(root, net_cur_desk, XA_CARDINAL, 0, &cur_desk, 1, NULL) && (get_atoms(w, net_wm_desk, XA_CARDINAL, 0, &w_desk, 1, NULL))) return IS_ON_DESK(w_desk, cur_desk); else return 1; }
double calc_E(const gsl_vector *x, void *par) { Timer t; // Get the helpers opthelper_t *p=(opthelper_t *) par; // Get the atomic positions std::vector<atom_t> atoms=get_atoms(x,*p); // print_xyz(atoms); // Construct basis set BasisSet basis; construct_basis(basis,atoms,p->baslib,p->set); // Perform the electronic structure calculation enum calcd mode=run_calc(basis,p->set,false); // Solution checkpoint Checkpoint solchk(p->set.get_string("SaveChk"),false); // Current energy is energy_t en; solchk.read(en); if(mode==FULLCALC) { ERROR_INFO(); throw std::runtime_error("Should have not computed forces for energy.\n"); } else if(mode==ECALC) printf("Computed energy % .8f in %s.\n",en.E,t.elapsed().c_str()); else printf("Found energy % .8f in checkpoint file.\n",en.E); fflush(stdout); return en.E; }
int is_skip(Window w) { Atom win_type, state; int i; unsigned long r; if (get_atoms(w, net_wm_wintype, XA_ATOM, 0, &win_type, 1, NULL) && (win_type == net_wm_type_dock || win_type == net_wm_type_desk)) return 1; for (i = 0, r = 1; r; i += r) if ((r = get_atoms(w, net_wm_state, XA_ATOM, i, &state, 1, NULL)) && (state == net_wm_state_skipt || state == net_wm_state_skipp)) return 1; return 0; }
void calc_Ef(const gsl_vector *x, void *par, double *E, gsl_vector *g) { Timer t; // Get the helpers opthelper_t *p=(opthelper_t *) par; // Get the atomic positions std::vector<atom_t> atoms=get_atoms(x,*p); // print_xyz(atoms); // Construct basis set BasisSet basis; construct_basis(basis,atoms,p->baslib,p->set); // Perform the electronic structure calculation enum calcd mode=run_calc(basis,p->set,true); // Solution checkpoint Checkpoint solchk(p->set.get_string("SaveChk"),false); // Energy energy_t en; solchk.read(en); *E=en.E; // Force arma::vec f; solchk.read("Force",f); // Set components for(size_t i=0;i<p->dofidx.size();i++) { size_t j=p->dofidx[i]; gsl_vector_set(g,3*i ,-f(3*j)); gsl_vector_set(g,3*i+1,-f(3*j+1)); gsl_vector_set(g,3*i+2,-f(3*j+2)); } double frms, fmax; get_forces(g,fmax,frms); if(mode==ECALC) { ERROR_INFO(); throw std::runtime_error("Should have not computed just the energy for forces.\n"); } else if(mode==FULLCALC) printf("Computed energy % .8f and forces (max = %.3e, rms = %.3e) in %s.\n",en.E,fmax,frms,t.elapsed().c_str()); else if(mode==FORCECALC) printf("Found energy % .8f in checkpoint file and calculated forces (max = %.3e, rms = %.3e) in %s.\n",en.E,fmax,frms,t.elapsed().c_str()); else if(mode==NOCALC) printf("Found energy and forces in checkpoint file.\n"); fflush(stdout); }
void check_states(client_t *c) { Atom state; unsigned long read, left; int i; for (i = 0, left = 1; left; i += read) { read = get_atoms(c->win, net_wm_state, XA_ATOM, i, &state, 1, &left); if (read) { if (state == net_wm_state_shaded) shade_client(c); else if (state == net_wm_state_mh || state == net_wm_state_mv) zoom_client(c); } else { break; } } }
client_t *new_client(Window w) { client_t *c; XWindowAttributes attr; XColor exact; long supplied; Atom win_type; c = malloc(sizeof *c); c->next = head; head = c; c->name = get_wm_name(w); c->win = w; c->frame = None; c->size.flags = 0; c->ignore_unmap = 0; #ifdef SHAPE c->shaped = 0; #endif c->shaded = 0; c->zoomed = 0; c->decor = 1; XGetWMNormalHints(dpy, c->win, &c->size, &supplied); XGetTransientForHint(dpy, c->win, &c->trans); XGetWindowAttributes(dpy, c->win, &attr); c->geom.x = attr.x; c->geom.y = attr.y; c->geom.w = attr.width; c->geom.h = attr.height; c->cmap = attr.colormap; c->old_bw = attr.border_width; #ifdef DEBUG dump_name(c, "creating", 'w'); dump_geom(c, "initial"); #endif XAllocNamedColor(dpy, c->cmap, opt_fg, &fg, &exact); XAllocNamedColor(dpy, c->cmap, opt_bg, &bg, &exact); XAllocNamedColor(dpy, c->cmap, opt_bd, &bd, &exact); if (get_atoms(c->win, net_wm_wintype, XA_ATOM, 0, &win_type, 1, NULL)) c->decor = HAS_DECOR(win_type); if (get_atoms(c->win, net_wm_desk, XA_CARDINAL, 0, &c->desk, 1, NULL)) { if (c->desk == -1) c->desk = DESK_ALL; /* FIXME */ if (c->desk >= ndesks && c->desk != DESK_ALL) c->desk = cur_desk; } else { set_atoms(c->win, net_wm_desk, XA_CARDINAL, &cur_desk, 1); c->desk = cur_desk; } #ifdef DEBUG dump_info(c); #endif check_states(c); /* We are not actually keeping the stack one in order. However, every * fancy panel uses it and nothing else, no matter what the spec says. * (I'm not sure why, as rearranging the list every time the stacking * changes would be distracting. GNOME's window list applet doesn't.) */ append_atoms(root, net_client_list, XA_WINDOW, &c->win, 1); append_atoms(root, net_client_stack, XA_WINDOW, &c->win, 1); return c; }
static int init_geom(client_t *c, strut_t *s) { Atom win_type, state; int screen_x = DisplayWidth(dpy, screen); int screen_y = DisplayHeight(dpy, screen); int wmax = screen_x - s->left - s->right; int hmax = screen_y - s->top - s->bottom; int mouse_x, mouse_y; /* We decide the geometry for these types of windows, so we can just * ignore everything and return right away. If c->zoomed is set, that * means we've already set things up, but otherwise, we do it here. */ if (c->zoomed) return 1; if (get_atoms(c->win, net_wm_state, XA_ATOM, 0, &state, 1, NULL) && state == net_wm_state_fs) { c->geom.x = 0; c->geom.y = 0; c->geom.w = screen_x; c->geom.h = screen_y; return 1; } /* Here, we merely set the values; they're in the same place regardless * of whether the user or the program specified them. We'll distinguish * between the two cases later, if we need to. */ if (c->size.flags & (USSize|PSize)) { if (c->size.width > 0) c->geom.w = c->size.width; if (c->size.height > 0) c->geom.h = c->size.height; } if (c->size.flags & (USPosition|PPosition)) { if (c->size.x > 0) c->geom.x = c->size.x; if (c->size.y > 0) c->geom.y = c->size.y; } /* Several types of windows can put themselves wherever they want, but we * need to read the size hints to get that position before returning. */ if (get_atoms(c->win, net_wm_wintype, XA_ATOM, 0, &win_type, 1, NULL) && CAN_PLACE_SELF(win_type)) return 1; /* At this point, maybe nothing was set, or something went horribly wrong * and the values are garbage. So, make a guess, based on the pointer. */ if (c->geom.x <= 0 && c->geom.y <= 0) { get_pointer(&mouse_x, &mouse_y); recalc_map(c, c->geom, mouse_x, mouse_y, mouse_x, mouse_y, s); } /* In any case, if we got this far, we need to do a further sanity check * and make sure that the window isn't overlapping any struts -- except * for transients, because they might be a panel-type client popping up a * notification window over themselves. */ if (!c->trans) { if (c->geom.x + c->geom.w > screen_x - s->right) c->geom.x = screen_x - s->right - c->geom.w; if (c->geom.y + c->geom.h > screen_y - s->bottom) c->geom.y = screen_y - s->bottom - c->geom.h; if (c->geom.x < s->left || c->geom.w > wmax) c->geom.x = s->left; if (c->geom.y < s->top || c->geom.h > hmax) c->geom.y = s->top; } /* Finally, we decide if we were ultimately satisfied with the position * given, or if we had to make something up, so that the caller can * consider using some other method. */ return c->trans || c->size.flags & USPosition; }
int main(int argc, char **argv) { #ifdef _OPENMP printf("ERKALE - Geometry optimization from Hel, OpenMP version, running on %i cores.\n",omp_get_max_threads()); #else printf("ERKALE - Geometry optimization from Hel, serial version.\n"); #endif print_copyright(); print_license(); #ifdef SVNRELEASE printf("At svn revision %s.\n\n",SVNREVISION); #endif print_hostname(); if(argc!=2) { printf("Usage: $ %s runfile\n",argv[0]); return 0; } // Initialize libint init_libint_base(); // Initialize libderiv init_libderiv_base(); Timer tprog; tprog.print_time(); // Parse settings Settings set; set.add_scf_settings(); set.add_string("SaveChk","File to use as checkpoint","erkale.chk"); set.add_string("LoadChk","File to load old results from",""); set.add_bool("ForcePol","Force polarized calculation",false); set.add_bool("FreezeCore","Freeze the atomic cores?",false); set.add_string("Optimizer","Optimizer to use: CGFR, CGPR, BFGS, BFGS2 (default), SD","BFGS2"); set.add_int("MaxSteps","Maximum amount of geometry steps",256); set.add_string("Criterion","Convergence criterion to use: LOOSE, NORMAL, TIGHT, VERYTIGHT","NORMAL"); set.add_string("OptMovie","xyz movie to store progress in","optimize.xyz"); set.add_string("Result","File to save optimized geometry in","optimized.xyz"); set.set_string("Logfile","erkale_geom.log"); set.parse(std::string(argv[1]),true); set.print(); bool verbose=set.get_bool("Verbose"); int maxiter=set.get_int("MaxSteps"); std::string optmovie=set.get_string("OptMovie"); std::string result=set.get_string("Result"); // Interpret optimizer enum minimizer alg; std::string method=set.get_string("Optimizer"); if(stricmp(method,"CGFR")==0) alg=gCGFR; else if(stricmp(method,"CGPR")==0) alg=gCGPR; else if(stricmp(method,"BFGS")==0) alg=gBFGS; else if(stricmp(method,"BFGS2")==0) alg=gBFGS2; else if(stricmp(method,"SD")==0) alg=gSD; else { ERROR_INFO(); throw std::runtime_error("Unknown optimization method.\n"); } // Interpret optimizer enum convergence crit; method=set.get_string("Criterion"); if(stricmp(method,"LOOSE")==0) crit=LOOSE; else if(stricmp(method,"NORMAL")==0) crit=NORMAL; else if(stricmp(method,"TIGHT")==0) crit=TIGHT; else if(stricmp(method,"VERYTIGHT")==0) crit=VERYTIGHT; else { ERROR_INFO(); throw std::runtime_error("Unknown optimization method.\n"); } // Redirect output? std::string logfile=set.get_string("Logfile"); if(stricmp(logfile,"stdout")!=0) { // Redirect stdout to file FILE *outstream=freopen(logfile.c_str(),"w",stdout); if(outstream==NULL) { ERROR_INFO(); throw std::runtime_error("Unable to redirect output!\n"); } else fprintf(stderr,"\n"); } // Read in atoms. std::string atomfile=set.get_string("System"); const std::vector<atom_t> origgeom=load_xyz(atomfile); std::vector<atom_t> atoms(origgeom); // Are any atoms fixed? std::vector<size_t> dofidx; for(size_t i=0;i<atoms.size();i++) { bool fixed=false; if(atoms[i].el.size()>3) if(stricmp(atoms[i].el.substr(atoms[i].el.size()-3),"-Fx")==0) { fixed=true; atoms[i].el=atoms[i].el.substr(0,atoms[i].el.size()-3); } // Add to degrees of freedom if(!fixed) dofidx.push_back(i); } // Read in basis set BasisSetLibrary baslib; std::string basfile=set.get_string("Basis"); baslib.load_gaussian94(basfile); printf("\n"); // Save to output save_xyz(atoms,"Initial configuration",optmovie,false); // Minimizer options opthelper_t pars; pars.atoms=atoms; pars.baslib=baslib; pars.set=set; pars.dofidx=dofidx; /* Starting point */ gsl_vector *x = gsl_vector_alloc (3*dofidx.size()); for(size_t i=0;i<dofidx.size();i++) { gsl_vector_set(x,3*i,atoms[dofidx[i]].x); gsl_vector_set(x,3*i+1,atoms[dofidx[i]].y); gsl_vector_set(x,3*i+2,atoms[dofidx[i]].z); } // GSL status int status; const gsl_multimin_fdfminimizer_type *T; gsl_multimin_fdfminimizer *s; gsl_multimin_function_fdf minimizer; minimizer.n = x->size; minimizer.f = calc_E; minimizer.df = calc_f; minimizer.fdf = calc_Ef; minimizer.params = (void *) &pars; if(alg==gCGFR) { T = gsl_multimin_fdfminimizer_conjugate_fr; if(verbose) printf("Using Fletcher-Reeves conjugate gradients.\n"); } else if(alg==gCGPR) { T = gsl_multimin_fdfminimizer_conjugate_pr; if(verbose) printf("Using Polak-Ribière conjugate gradients.\n"); } else if(alg==gBFGS) { T = gsl_multimin_fdfminimizer_vector_bfgs; if(verbose) printf("Using the BFGS minimizer.\n"); } else if(alg==gBFGS2) { T = gsl_multimin_fdfminimizer_vector_bfgs2; if(verbose) printf("Using the BFGS2 minimizer.\n"); } else if(alg==gSD) { T = gsl_multimin_fdfminimizer_steepest_descent; if(verbose) printf("Using the steepest descent minimizer.\n"); } else { ERROR_INFO(); throw std::runtime_error("Unsupported minimizer\n"); } // Run an initial calculation double oldE=calc_E(x,minimizer.params); // Turn off verbose setting pars.set.set_bool("Verbose",false); // and load from old checkpoint pars.set.set_string("LoadChk",pars.set.get_string("SaveChk")); // Initialize minimizer s = gsl_multimin_fdfminimizer_alloc (T, minimizer.n); // Use initial step length of 0.02 bohr, and a line search accuracy // 1e-1 (recommended in the GSL manual for BFGS) gsl_multimin_fdfminimizer_set (s, &minimizer, x, 0.02, 1e-1); // Store old force arma::mat oldf=interpret_force(s->gradient); fprintf(stderr,"Geometry optimizer initialized in %s.\n",tprog.elapsed().c_str()); fprintf(stderr,"Entering minimization loop with %s optimizer.\n",set.get_string("Optimizer").c_str()); fprintf(stderr,"%4s %16s %10s %10s %9s %9s %9s %9s %s\n","iter","E","dE","dE/dEproj","disp max","disp rms","f max","f rms", "titer"); std::vector<atom_t> oldgeom(atoms); bool convd=false; int iter; for(iter=1;iter<=maxiter;iter++) { printf("\nGeometry iteration %i\n",(int) iter); fflush(stdout); Timer titer; status = gsl_multimin_fdfminimizer_iterate (s); if (status) { fprintf(stderr,"GSL encountered error: \"%s\".\n",gsl_strerror(status)); break; } // New geometry is std::vector<atom_t> geom=get_atoms(s->x,pars); // Calculate displacements double dmax, drms; get_displacement(geom, oldgeom, dmax, drms); // Calculate projected change of energy double dEproj=calculate_projection(geom,oldgeom,oldf,pars.dofidx); // Actual change of energy is double dE=s->f - oldE; // Switch geometries oldgeom=geom; // Save old force // Get forces double fmax, frms; get_forces(s->gradient, fmax, frms); // Save geometry step char comment[80]; sprintf(comment,"Step %i",(int) iter); save_xyz(get_atoms(s->x,pars),comment,optmovie,true); // Check convergence bool fmaxconv=false, frmsconv=false; bool dmaxconv=false, drmsconv=false; switch(crit) { case(LOOSE): if(fmax < 2.5e-3) fmaxconv=true; if(frms < 1.7e-3) frmsconv=true; if(dmax < 1.0e-2) dmaxconv=true; if(drms < 6.7e-3) drmsconv=true; break; case(NORMAL): if(fmax < 4.5e-4) fmaxconv=true; if(frms < 3.0e-4) frmsconv=true; if(dmax < 1.8e-3) dmaxconv=true; if(drms < 1.2e-3) drmsconv=true; break; case(TIGHT): if(fmax < 1.5e-5) fmaxconv=true; if(frms < 1.0e-5) frmsconv=true; if(dmax < 6.0e-5) dmaxconv=true; if(drms < 4.0e-5) drmsconv=true; break; case(VERYTIGHT): if(fmax < 2.0e-6) fmaxconv=true; if(frms < 1.0e-6) frmsconv=true; if(dmax < 6.0e-6) dmaxconv=true; if(drms < 4.0e-6) drmsconv=true; break; default: ERROR_INFO(); throw std::runtime_error("Not implemented!\n"); } // Converged? const static char cconv[]=" *"; double dEfrac; if(dEproj!=0.0) dEfrac=dE/dEproj; else dEfrac=0.0; fprintf(stderr,"%4d % 16.8f % .3e % .3e %.3e%c %.3e%c %.3e%c %.3e%c %s\n", (int) iter, s->f, dE, dEfrac, dmax, cconv[dmaxconv], drms, cconv[drmsconv], fmax, cconv[fmaxconv], frms, cconv[frmsconv], titer.elapsed().c_str()); fflush(stderr); convd=dmaxconv && drmsconv && fmaxconv && frmsconv; if(convd) { fprintf(stderr,"Converged.\n"); break; } // Store old energy oldE=s->f; // Store old force oldf=interpret_force(s->gradient); } if(convd) save_xyz(get_atoms(s->x,pars),"Optimized geometry",result); gsl_multimin_fdfminimizer_free (s); gsl_vector_free (x); if(iter==maxiter && !convd) { printf("Geometry convergence was not achieved!\n"); } printf("Running program took %s.\n",tprog.elapsed().c_str()); return 0; }