Files | |
| file | calcinfo.h |
| Enter brief description of file here. | |
| file | detcas/cleanup.cc |
| Enter brief description of file here. | |
| file | detcas.cc |
| Orbital optimizer for detci. | |
| file | detcas/diis.cc |
| Enter brief description of file here. | |
| file | f_act.cc |
| Enter brief description of file here. | |
| file | detcas/get_mo_info.cc |
| Enter brief description of file here. | |
| file | globaldefs.h |
| Enter brief description of file here. | |
| file | detcas/globals.h |
| Enter brief description of file here. | |
| file | gradient.cc |
| Enter brief description of file here. | |
| file | hessian.cc |
| Enter brief description of file here. | |
| file | indpairs.cc |
| Enter brief description of file here. | |
| file | indpairs.h |
| Enter brief description of file here. | |
| file | detcas/ints.cc |
| Enter brief description of file here. | |
| file | detcas/params.cc |
| Enter brief description of file here. | |
| file | detcas/params.h |
| Enter brief description of file here. | |
| file | read_dens.cc |
| Enter brief description of file here. | |
| file | read_lag.cc |
| Enter brief description of file here. | |
| file | ref_orbs.cc |
| Enter brief description of file here. | |
| file | rotate_orbs.cc |
| Enter brief description of file here. | |
| file | setup_io.cc |
| Enter brief description of file here. | |
| file | setup_io.h |
| Enter brief description of file here. | |
| file | step.cc |
| Enter brief description of file here. | |
| file | test_bfgs.cc |
| Enter brief description of file here. | |
| file | thetas.cc |
| Enter brief description of file here. | |
Functions | |
| void | psi::detcas::calc_gradient (void) |
| void | psi::detcas::bfgs_hessian (void) |
| void | psi::detcas::ds_hessian (void) |
| void | psi::detcas::calc_hessian (void) |
| void | psi::detcas::scale_gradient (void) |
| int | psi::detcas::take_step (void) |
| void | psi::detcas::rotate_orbs (void) |
| int | psi::detcas::check_conv (void) |
| void psi::detcas::bfgs_hessian | ( | void | ) |
This function calculates a BFGS-updated MO/MO Hessian
C. David Sherrill March 2004
Definition at line 359 of file detcas.cc.
References block_matrix(), psi::detcas::calc_hessian(), init_array(), init_int_array(), invert_matrix(), print_mat(), psio_open(), psio_read_entry(), psio_tocscan(), and psio_write_entry().
00360 { 00361 int i, j, npairs; 00362 double fac, fad, fae, tval; 00363 double *dx, *dg, *hdg, **hess_copy, **hess_copy2, hess_det; 00364 int *idx; 00365 00366 npairs = IndPairs.get_num_pairs(); 00367 00368 psio_open(PSIF_DETCAS, PSIO_OPEN_OLD); 00369 00370 /* If no Hessian in the file */ 00371 if (psio_tocscan(PSIF_DETCAS, "Hessian Inverse") == NULL) { 00372 calc_hessian(); 00373 if (strcmp(Params.hessian, "FULL") != 0) { 00374 CalcInfo.mo_hess = block_matrix(npairs,npairs); 00375 for (i=0; i<npairs; i++) { 00376 CalcInfo.mo_hess[i][i] = 1.0 / CalcInfo.mo_hess_diag[i]; 00377 } 00378 } 00379 else { 00380 hess_copy = block_matrix(npairs, npairs); 00381 idx = init_int_array(npairs); 00382 for (i=0; i<npairs; i++) { 00383 for (j=0; j<npairs; j++) { 00384 hess_copy[i][j] = CalcInfo.mo_hess[i][j]; 00385 } 00386 } 00387 ludcmp(hess_copy,npairs,idx,&hess_det); 00388 00389 for (i=0;i<npairs;i++) hess_det *= hess_copy[i][i]; 00390 fprintf(outfile,"The determinant of the hessian is %8.3E\n",hess_det); 00391 00392 if (Params.level_shift) { 00393 while (hess_det < Params.determ_min) { 00394 fprintf(outfile, "Level shifting hessian by %8.3E\n", Params.shift); 00395 for (i=0; i<npairs; i++) { 00396 CalcInfo.mo_hess[i][i] += Params.shift; 00397 for (j=0; j<npairs; j++) { 00398 hess_copy[i][j] = CalcInfo.mo_hess[i][j]; 00399 } 00400 } 00401 ludcmp(hess_copy,npairs,idx,&hess_det); 00402 for (i=0;i<npairs;i++) hess_det *= hess_copy[i][i]; 00403 fprintf(outfile,"The determinant of the hessian is %8.3E\n",hess_det); 00404 00405 for (i=0; i<npairs; i++) { 00406 for (j=0; j<npairs; j++) { 00407 hess_copy[i][j] = CalcInfo.mo_hess[i][j]; 00408 } 00409 } 00410 } 00411 } 00412 00413 /* n.b. this destroys hess_copy, and mo_hess now is INVERSE Hess */ 00414 invert_matrix(hess_copy,CalcInfo.mo_hess,npairs,outfile); 00415 00416 if (Params.print_lvl > 3) { 00417 fprintf(outfile, "\nInitial MO Hessian Inverse:\n"); 00418 print_mat(CalcInfo.mo_hess,npairs,npairs,outfile); 00419 fprintf(outfile, "\n"); 00420 } 00421 00422 free(idx); 00423 free_block(hess_copy); 00424 } 00425 00426 /* write Hessian */ 00427 psio_write_entry(PSIF_DETCAS, "Hessian Inverse", 00428 (char *) CalcInfo.mo_hess[0], npairs*npairs*sizeof(double)); 00429 /* write thetas */ 00430 psio_write_entry(PSIF_DETCAS, "Thetas", (char *) CalcInfo.theta_cur, 00431 npairs*sizeof(double)); 00432 /* write gradient */ 00433 psio_write_entry(PSIF_DETCAS, "MO Gradient", (char *) CalcInfo.mo_grad, 00434 npairs*sizeof(double)); 00435 psio_close(PSIF_DETCAS, 1); 00436 00437 00438 return; 00439 } /* end initialization of BFGS data */ 00440 00441 dx = init_array(npairs); 00442 dg = init_array(npairs); 00443 hdg = init_array(npairs); 00444 00445 /* read previous Hessian */ 00446 CalcInfo.mo_hess = block_matrix(npairs,npairs); 00447 psio_read_entry(PSIF_DETCAS, "Hessian Inverse", (char *) CalcInfo.mo_hess[0], 00448 npairs*npairs*sizeof(double)); 00449 00450 /* read previous thetas */ 00451 psio_read_entry(PSIF_DETCAS, "Thetas", (char *) dx, npairs*sizeof(double)); 00452 00453 /* read previous gradient */ 00454 psio_read_entry(PSIF_DETCAS, "MO Gradient", (char *) dg, 00455 npairs*sizeof(double)); 00456 00457 /* compute updated Hessian by BFGS procedure, see Numerical Recipies in C */ 00458 00459 /* get difference in thetas and gradient */ 00460 for (i=0; i<npairs; i++) { 00461 dx[i] = CalcInfo.theta_cur[i] - dx[i]; 00462 dg[i] = CalcInfo.mo_grad[i] - dg[i]; 00463 } 00464 00465 if (Params.print_lvl > 3) { 00466 fprintf(outfile, "Delta Theta and Delta Grad arrays:\n"); 00467 for (i=0; i<npairs; i++) { 00468 fprintf(outfile, "%12.7lf %12.7lf\n", dx[i], dg[i]); 00469 } 00470 } 00471 00472 /* hdg = H^-1 * (grad(i+1) - grad(i)) */ 00473 for (i=0; i<npairs; i++) { 00474 hdg[i] = 0.0; 00475 for (j=0; j<npairs; j++) { 00476 hdg[i] += CalcInfo.mo_hess[i][j] * dg[j]; 00477 } 00478 } 00479 00480 fac = fae = 0.0; 00481 00482 for (i=0; i<npairs; i++) { 00483 fac += dg[i] * dx[i]; 00484 fae += dg[i] * hdg[i]; 00485 } 00486 fac = 1.0/fac; 00487 fad = 1.0/fae; 00488 00489 /* the dg bit is the diff between BFGS and DFP */ 00490 for (i=0; i<npairs; i++) dg[i] = fac*dx[i] - fad*hdg[i]; 00491 00492 for (i=0; i<npairs; i++) { 00493 for (j=0; j<npairs; j++) { 00494 CalcInfo.mo_hess[i][j] += fac*dx[i]*dx[j] - fad*hdg[i]*hdg[j] 00495 + fae*dg[i]*dg[j]; 00496 } 00497 } 00498 00499 if (Params.print_lvl > 3) { 00500 fprintf(outfile, "\nBFGS MO Hessian Inverse:\n"); 00501 print_mat(CalcInfo.mo_hess,npairs,npairs,outfile); 00502 fprintf(outfile, "\n"); 00503 } 00504 00505 /* 00506 this doesn't work unless you fix that dg is not overwritten above 00507 when that's ensured, it seems to match 00508 */ 00509 /* 00510 if (Params.print_lvl > 3) { 00511 fprintf(outfile, "Check of dx = H dg\n"); 00512 for (i=0; i<npairs; i++) { 00513 tval = 0.0; 00514 for (j=0; j<npairs; j++) { 00515 tval += CalcInfo.mo_hess[i][j] * dg[j]; 00516 } 00517 fprintf(outfile, "%12.7lf vs %12.7lf\n", dx[i], tval); 00518 } 00519 } 00520 */ 00521 00522 00523 idx = init_int_array(npairs); 00524 hess_copy = block_matrix(npairs, npairs); 00525 for (i=0; i<npairs; i++) { 00526 for (j=0; j<npairs; j++) { 00527 hess_copy[i][j] = CalcInfo.mo_hess[i][j]; 00528 } 00529 } 00530 ludcmp(hess_copy,npairs,idx,&hess_det); 00531 for (i=0; i<npairs; i++) hess_det *= CalcInfo.mo_hess[i][i]; 00532 fprintf(outfile, "The determinant of the inverse Hessian is %8.3E\n", 00533 hess_det); 00534 00535 /* just debug check */ 00536 if (hess_det < 0.0) { 00537 hess_copy = block_matrix(npairs, npairs); 00538 hess_copy2 = block_matrix(npairs, npairs); 00539 for (i=0; i<npairs; i++) { 00540 for (j=0; j<npairs; j++) { 00541 hess_copy[i][j] = CalcInfo.mo_hess[i][j]; 00542 } 00543 } 00544 00545 /* n.b. this destroys hess_copy */ 00546 invert_matrix(hess_copy,hess_copy2,npairs,outfile); 00547 00548 if (Params.print_lvl > 3) { 00549 fprintf(outfile, "\nMO Hessian:\n"); 00550 print_mat(hess_copy2,npairs,npairs,outfile); 00551 fprintf(outfile, "\n"); 00552 } 00553 00554 ludcmp(hess_copy2,npairs,idx,&hess_det); 00555 for (i=0;i<npairs;i++) hess_det *= hess_copy2[i][i]; 00556 fprintf(outfile,"The determinant of the hessian is %8.3E\n",hess_det); 00557 00558 if (Params.level_shift) { 00559 while (hess_det < Params.determ_min) { 00560 fprintf(outfile, "Level shifting hessian by %8.3E\n", Params.shift); 00561 for (i=0; i<npairs; i++) { 00562 hess_copy2[i][i] += Params.shift; 00563 for (j=0; j<npairs; j++) { 00564 hess_copy[i][j] = hess_copy2[i][j]; 00565 } 00566 } 00567 ludcmp(hess_copy,npairs,idx,&hess_det); 00568 for (i=0;i<npairs;i++) hess_det *= hess_copy[i][i]; 00569 fprintf(outfile,"The determinant of the hessian is %8.3E\n",hess_det); 00570 for (i=0; i<npairs; i++) { 00571 for (j=0; j<npairs; j++) { 00572 hess_copy2[i][j] = hess_copy[i][j]; 00573 } 00574 } 00575 } 00576 } 00577 00578 /* n.b. this destroys hess_copy2, and mo_hess now is INVERSE Hess */ 00579 invert_matrix(hess_copy2,CalcInfo.mo_hess,npairs,outfile); 00580 00581 free_block(hess_copy2); 00582 } 00583 00584 free_block(hess_copy); 00585 00586 /* write thetas */ 00587 psio_write_entry(PSIF_DETCAS, "Thetas", (char *) CalcInfo.theta_cur, 00588 npairs*sizeof(double)); 00589 /* write gradient */ 00590 psio_write_entry(PSIF_DETCAS, "MO Gradient", (char *) CalcInfo.mo_grad, 00591 npairs*sizeof(double)); 00592 /* write updated Hessian */ 00593 psio_write_entry(PSIF_DETCAS, "Hessian Inverse", (char *) CalcInfo.mo_hess[0], 00594 npairs*npairs*sizeof(double)); 00595 psio_close(PSIF_DETCAS, 1); 00596 00597 00598 free(idx); 00599 free(dx); 00600 free(dg); 00601 free(hdg); 00602 }
| void psi::detcas::calc_gradient | ( | void | ) |
This function calculates the MO gradient from the MO Lagrangian
Definition at line 250 of file detcas.cc.
References block_matrix(), C_DSCAL(), init_array(), and print_mat().
00251 { 00252 int pair, npair, h, ir_npairs, ir_norbs, offset; 00253 double *ir_mo_grad, **ir_lag, *ir_theta_cur, value, rms; 00254 int *parr, *qarr, *ir_ppair, *ir_qpair; 00255 int p, q; 00256 00257 npair = IndPairs.get_num_pairs(); 00258 parr = IndPairs.get_p_ptr(); 00259 qarr = IndPairs.get_q_ptr(); 00260 00261 CalcInfo.mo_grad = init_array(npair); 00262 00263 /* 00264 calc_grad_1(npair, parr, qarr, CalcInfo.lag, CalcInfo.mo_grad); 00265 calc_grad_2(npair, parr, qarr, CalcInfo.onel_ints, CalcInfo.twoel_ints, 00266 CalcInfo.opdm, CalcInfo.tpdm, CalcInfo.F_act, 00267 (CalcInfo.num_cor_orbs + CalcInfo.num_fzc_orbs), 00268 CalcInfo.npop, CalcInfo.mo_grad); 00269 */ 00270 00271 // scratch array for dEdTheta, big enough for any irrep 00272 ir_mo_grad = init_array(npair); 00273 00274 // calculate dEdU, then dEdTheta 00275 for (h=0,offset=0; h<CalcInfo.nirreps; h++) { 00276 00277 // Setup for this irrep 00278 ir_npairs = IndPairs.get_ir_num_pairs(h); 00279 ir_norbs = CalcInfo.orbs_per_irr[h]; 00280 if (h>0) offset += CalcInfo.orbs_per_irr[h-1]; 00281 if (!ir_npairs) continue; 00282 ir_ppair = IndPairs.get_ir_prel_ptr(h); 00283 ir_qpair = IndPairs.get_ir_qrel_ptr(h); 00284 ir_lag = block_matrix(ir_norbs, ir_norbs); 00285 get_mat_block(CalcInfo.lag, ir_lag, ir_norbs, offset, CalcInfo.pitz2ci); 00286 00287 if (Params.print_lvl > 3) { 00288 fprintf(outfile, "Irrep %d of lagrangian:\n", h); 00289 print_mat(ir_lag, ir_norbs, ir_norbs, outfile); 00290 } 00291 00292 ir_theta_cur = IndPairs.get_irrep_vec(h, CalcInfo.theta_cur); 00293 00294 // Need to mult the Lagrangian by 2 to get dEdU 00295 C_DSCAL(ir_norbs*ir_norbs, 2.0, ir_lag[0], 1); 00296 00297 if (Params.print_lvl > 3) { 00298 fprintf(outfile, "Irrep %d of 2 * lagrangian:\n", h); 00299 print_mat(ir_lag, ir_norbs, ir_norbs, outfile); 00300 } 00301 00302 if (Params.use_thetas) { 00303 // Calc dEdU 00304 premult_by_U(h, CalcInfo.orbs_per_irr[h], ir_lag, ir_npairs, 00305 ir_ppair, ir_qpair, ir_theta_cur); 00306 00307 if (Params.print_lvl > 3) { 00308 fprintf(outfile, "dE/dU:\n", h); 00309 print_mat(ir_lag, ir_norbs, ir_norbs, outfile); 00310 } 00311 00312 // Calculate dEdTheta 00313 calc_dE_dT(CalcInfo.orbs_per_irr[h], ir_lag, ir_npairs, 00314 ir_ppair, ir_qpair, ir_theta_cur, ir_mo_grad); 00315 } 00316 00317 /* non-theta version */ 00318 else { 00319 for (pair=0; pair<ir_npairs; pair++) { 00320 p = ir_ppair[pair]; q = ir_qpair[pair]; 00321 ir_mo_grad[pair] = ir_lag[p][q] - ir_lag[q][p]; 00322 } 00323 } 00324 00325 // Put dEdTheta into the large gradient array 00326 IndPairs.put_irrep_vec(h, ir_mo_grad, CalcInfo.mo_grad); 00327 delete [] ir_theta_cur; 00328 free_block(ir_lag); 00329 } 00330 00331 00332 rms = 0.0; 00333 for (pair=0; pair<npair; pair++) { 00334 value = CalcInfo.mo_grad[pair]; 00335 rms += value * value; 00336 } 00337 00338 if (Params.print_lvl > 2) 00339 IndPairs.print_vec(CalcInfo.mo_grad, "\n\tOrbital Gradient:", outfile); 00340 00341 rms = sqrt(rms); 00342 CalcInfo.mo_grad_rms = rms; 00343 00344 if (Params.print_lvl) 00345 fprintf(outfile, "\n\tRMS Orbital Gradient: %6.4E\n", rms); 00346 }
| void psi::detcas::calc_hessian | ( | void | ) |
This function calculates an approximate MO Hessian from the Fock matrix intermediates and two-electron integrals.
C. David Sherrill April 1998
Definition at line 737 of file detcas.cc.
References block_matrix(), init_array(), and print_mat().
Referenced by psi::detcas::bfgs_hessian(), and psi::detcas::ds_hessian().
00738 { 00739 00740 int npairs, *ppair, *qpair, ncore; 00741 00742 npairs = IndPairs.get_num_pairs(); 00743 ppair = IndPairs.get_p_ptr(); 00744 qpair = IndPairs.get_q_ptr(); 00745 00746 /* Now calculate the approximate diagonal MO Hessian */ 00747 ncore = CalcInfo.num_fzc_orbs + CalcInfo.num_cor_orbs; 00748 00749 if (strcmp(Params.hessian, "DIAG") == 0) { 00750 CalcInfo.mo_hess_diag = init_array(npairs); 00751 00752 if (Params.use_fzc_h == 1) 00753 form_diag_mo_hess(npairs, ppair, qpair, CalcInfo.onel_ints, 00754 CalcInfo.twoel_ints, CalcInfo.opdm, CalcInfo.tpdm, CalcInfo.F_act, 00755 ncore, CalcInfo.npop, CalcInfo.mo_hess_diag); 00756 else 00757 form_diag_mo_hess_yy(npairs, ppair, qpair, CalcInfo.onel_ints, 00758 CalcInfo.twoel_ints, CalcInfo.opdm, CalcInfo.tpdm, CalcInfo.lag, 00759 CalcInfo.mo_hess_diag); 00760 00761 if (Params.print_lvl > 3) 00762 IndPairs.print_vec(CalcInfo.mo_hess_diag,"\n\tDiagonal MO Hessian:", 00763 outfile); 00764 } 00765 else if (strcmp(Params.hessian, "APPROX_DIAG") == 0) { 00766 CalcInfo.mo_hess_diag = init_array(npairs); 00767 form_appx_diag_mo_hess(npairs, ppair, qpair, CalcInfo.onel_ints, 00768 CalcInfo.twoel_ints, CalcInfo.opdm, CalcInfo.tpdm, 00769 CalcInfo.F_act, ncore, CalcInfo.npop, 00770 CalcInfo.mo_hess_diag); 00771 if (Params.print_lvl > 3) 00772 IndPairs.print_vec(CalcInfo.mo_hess_diag,"\n\tAppx Diagonal MO Hessian:", 00773 outfile); 00774 } 00775 else if (strcmp(Params.hessian, "FULL") == 0) { 00776 CalcInfo.mo_hess = block_matrix(npairs,npairs); 00777 form_full_mo_hess(npairs, ppair, qpair, CalcInfo.onel_ints, 00778 CalcInfo.twoel_ints, CalcInfo.opdm, CalcInfo.tpdm, CalcInfo.lag, 00779 CalcInfo.mo_hess); 00780 if (Params.print_lvl > 3) { 00781 fprintf(outfile, "\nMO Hessian:\n"); 00782 print_mat(CalcInfo.mo_hess,npairs,npairs,outfile); 00783 fprintf(outfile, "\n"); 00784 } 00785 } 00786 else { 00787 fprintf(outfile, "(detcas): Unrecognized Hessian option %s\n", 00788 Params.hessian); 00789 } 00790 00791 00792 }
| int psi::detcas::check_conv | ( | void | ) |
check_conv
Check the summary file to see if we've converged
Returns: 1 if converged, otherwise 0
Definition at line 981 of file detcas.cc.
References chkpt_close(), chkpt_init(), chkpt_rd_etot(), and ffile_noexit().
00982 { 00983 FILE *sumfile; 00984 char sumfile_name[] = "file14.dat"; 00985 char comment[MAX_COMMENT]; 00986 int i, entries, iter, nind; 00987 double rmsgrad, scaled_rmsgrad, energy, energy_last; 00988 int converged_energy=0, converged_grad=0, last_converged=0; 00989 double conv_rms_grad, conv_e; 00990 00991 ffile_noexit(&sumfile,sumfile_name,2); 00992 00993 if (sumfile == NULL) { 00994 CalcInfo.iter = 0; 00995 return(0); 00996 } 00997 00998 if (fscanf(sumfile, "%d", &entries) != 1) { 00999 fprintf(outfile,"(print_step): Trouble reading num entries in file %s\n", 01000 sumfile_name); 01001 fclose(sumfile); 01002 CalcInfo.iter = 0; 01003 return(0); 01004 } 01005 01006 CalcInfo.iter = entries; 01007 for (i=0; i<entries; i++) { 01008 fscanf(sumfile, "%d %d %lf %lf %lf %s", &iter, &nind, &scaled_rmsgrad, 01009 &rmsgrad, &energy_last, comment); 01010 } 01011 fclose(sumfile); 01012 01013 chkpt_init(PSIO_OPEN_OLD); 01014 energy = chkpt_rd_etot(); 01015 chkpt_close(); 01016 01017 /* check for convergence */ 01018 conv_rms_grad = pow(10.0, -(Params.rms_grad_convergence)); 01019 conv_e = pow(10.0, -(Params.energy_convergence)); 01020 if (rmsgrad < conv_rms_grad) converged_grad = 1; 01021 if (fabs(energy_last - energy) < conv_e) 01022 converged_energy = 1; 01023 if (strstr(comment, "CONV") != NULL) 01024 last_converged = 1; 01025 01026 if (converged_grad && converged_energy && !last_converged) { 01027 fprintf(outfile, "\n\t*** Calculation Converged ***\n"); 01028 return(1); 01029 } 01030 else { 01031 fprintf(outfile, "\n\t... calculation continuing ...\n"); 01032 return(0); 01033 } 01034 }
| void psi::detcas::ds_hessian | ( | void | ) |
This function calculates a Hessian update by a difference of gradients
C. David Sherrill March 2004
Definition at line 615 of file detcas.cc.
References psi::detcas::calc_hessian(), init_array(), psio_open(), psio_read_entry(), psio_tocscan(), and psio_write_entry().
00616 { 00617 int i, npairs; 00618 double tval; 00619 double *dx, *dg; 00620 00621 npairs = IndPairs.get_num_pairs(); 00622 00623 psio_open(PSIF_DETCAS, PSIO_OPEN_OLD); 00624 00625 /* If no Hessian in the file */ 00626 if (psio_tocscan(PSIF_DETCAS, "Hessian") == NULL) { 00627 calc_hessian(); 00628 if (strcmp(Params.hessian, "FULL") == 0) { 00629 CalcInfo.mo_hess_diag = init_array(npairs); 00630 for (i=0; i<npairs; i++) { 00631 CalcInfo.mo_hess_diag[i] = CalcInfo.mo_hess[i][i]; 00632 } 00633 } 00634 for (i=0; i<npairs; i++) { 00635 if (CalcInfo.mo_hess_diag[i] < MO_HESS_MIN) { 00636 fprintf(outfile, "Warning: MO Hessian denominator too small\n"); 00637 CalcInfo.mo_hess_diag[i] = MO_HESS_MIN; 00638 } 00639 } 00640 00641 if (Params.print_lvl > 3) { 00642 fprintf(outfile, "\nInitial MO Hessian:\n"); 00643 for (i=0; i<npairs; i++) 00644 fprintf(outfile, "%12.6lf\n", CalcInfo.mo_hess_diag[i]); 00645 fprintf(outfile, "\n"); 00646 } 00647 00648 /* write Hessian */ 00649 psio_write_entry(PSIF_DETCAS, "Hessian", 00650 (char *) CalcInfo.mo_hess_diag, npairs*sizeof(double)); 00651 /* write thetas */ 00652 psio_write_entry(PSIF_DETCAS, "Thetas", (char *) CalcInfo.theta_cur, 00653 npairs*sizeof(double)); 00654 /* write gradient */ 00655 psio_write_entry(PSIF_DETCAS, "MO Gradient", (char *) CalcInfo.mo_grad, 00656 npairs*sizeof(double)); 00657 psio_close(PSIF_DETCAS, 1); 00658 return; 00659 } /* end initialization of data */ 00660 00661 dx = init_array(npairs); 00662 dg = init_array(npairs); 00663 00664 /* read previous Hessian */ 00665 CalcInfo.mo_hess_diag = init_array(npairs); 00666 psio_read_entry(PSIF_DETCAS, "Hessian", (char *) CalcInfo.mo_hess_diag, 00667 npairs*sizeof(double)); 00668 00669 /* read previous thetas */ 00670 psio_read_entry(PSIF_DETCAS, "Thetas", (char *) dx, npairs*sizeof(double)); 00671 00672 /* read previous gradient */ 00673 psio_read_entry(PSIF_DETCAS, "MO Gradient", (char *) dg, 00674 npairs*sizeof(double)); 00675 00676 /* compute updated Hessian by David's recipie */ 00677 00678 /* get difference in thetas and gradient */ 00679 for (i=0; i<npairs; i++) { 00680 dx[i] = CalcInfo.theta_cur[i] - dx[i]; 00681 dg[i] = CalcInfo.mo_grad[i] - dg[i]; 00682 } 00683 00684 if (Params.print_lvl > 3) { 00685 fprintf(outfile, "Delta Theta and Delta Grad arrays:\n"); 00686 for (i=0; i<npairs; i++) { 00687 fprintf(outfile, "%12.7lf %12.7lf\n", dx[i], dg[i]); 00688 } 00689 } 00690 00691 /* H = 1/2 [ H + (grad(i+1) - grad(i))/(x(i+1)-x(i)) ] */ 00692 for (i=0; i<npairs; i++) { 00693 tval = dg[i] / dx[i]; 00694 if (tval < - MO_HESS_MIN) tval = - MO_HESS_MIN; 00695 if (tval > 500.0) tval = 500.0; 00696 CalcInfo.mo_hess_diag[i] = 0.5 * (CalcInfo.mo_hess_diag[i] + tval); 00697 if (CalcInfo.mo_hess_diag[i] < MO_HESS_MIN) 00698 CalcInfo.mo_hess_diag[i] = MO_HESS_MIN; 00699 } 00700 00701 if (Params.print_lvl > 3) { 00702 fprintf(outfile, "\nDS MO Hessian:\n"); 00703 for (i=0; i<npairs; i++) 00704 fprintf(outfile, "%12.6lf\n", CalcInfo.mo_hess_diag[i]); 00705 fprintf(outfile, "\n"); 00706 } 00707 00708 /* write thetas */ 00709 psio_write_entry(PSIF_DETCAS, "Thetas", (char *) CalcInfo.theta_cur, 00710 npairs*sizeof(double)); 00711 /* write gradient */ 00712 psio_write_entry(PSIF_DETCAS, "MO Gradient", (char *) CalcInfo.mo_grad, 00713 npairs*sizeof(double)); 00714 /* write updated Hessian */ 00715 psio_write_entry(PSIF_DETCAS, "Hessian", (char *) CalcInfo.mo_hess_diag, 00716 npairs*sizeof(double)); 00717 psio_close(PSIF_DETCAS, 1); 00718 00719 00720 free(dx); 00721 free(dg); 00722 }
| void psi::detcas::rotate_orbs | ( | void | ) |
Rotate the orbitals, irrep by irrep
Definition at line 913 of file detcas.cc.
References chkpt_close(), chkpt_init(), chkpt_wt_scf_irrep(), init_array(), and print_mat().
00914 { 00915 double *ir_theta; 00916 int h, pair, ir_norbs, ir_npairs, *ir_ppair, *ir_qpair; 00917 00918 // First, we need to come up with Theta vectors for each irrep 00919 ir_theta = init_array(IndPairs.get_num_pairs()); // always big enough 00920 for (h=0; h<CalcInfo.nirreps; h++) { 00921 ir_npairs = IndPairs.get_ir_num_pairs(h); 00922 if (ir_npairs) { 00923 ir_norbs = CalcInfo.orbs_per_irr[h]; 00924 ir_theta = IndPairs.get_irrep_vec(h, CalcInfo.theta_cur); 00925 ir_ppair = IndPairs.get_ir_prel_ptr(h); 00926 ir_qpair = IndPairs.get_ir_qrel_ptr(h); 00927 00928 if (Params.print_lvl > 3) { 00929 fprintf(outfile, "Thetas for irrep %d\n", h); 00930 for (pair=0; pair<ir_npairs; pair++) { 00931 fprintf(outfile, "Pair (%2d,%2d) = %12.6lf\n", 00932 ir_ppair[pair], ir_qpair[pair], ir_theta[pair]); 00933 } 00934 fprintf(outfile, "\n"); 00935 fflush(outfile); 00936 } 00937 00938 /* print old coefficients */ 00939 if (Params.print_mos) { 00940 fprintf(outfile, "\n\tOld molecular orbitals for irrep %s\n", 00941 CalcInfo.labels[h]); 00942 print_mat(CalcInfo.mo_coeffs[h], ir_norbs, ir_norbs, outfile); 00943 } 00944 00945 if (Params.use_thetas) 00946 postmult_by_U(h, ir_norbs, CalcInfo.mo_coeffs[h], ir_npairs, 00947 ir_ppair, ir_qpair, ir_theta); 00948 else 00949 postmult_by_exp_R(h, ir_norbs, CalcInfo.mo_coeffs[h], ir_npairs, 00950 ir_ppair, ir_qpair, ir_theta); 00951 00952 /* print new coefficients */ 00953 if (Params.print_mos) { 00954 fprintf(outfile, "\n\tNew molecular orbitals for irrep %s\n", 00955 CalcInfo.labels[h]); 00956 print_mat(CalcInfo.mo_coeffs[h], ir_norbs, ir_norbs, outfile); 00957 } 00958 00959 00960 /* write the new block of MO coefficients to file30 */ 00961 chkpt_init(PSIO_OPEN_OLD); 00962 chkpt_wt_scf_irrep(CalcInfo.mo_coeffs[h], h); 00963 chkpt_close(); 00964 delete [] ir_theta; 00965 } 00966 } 00967 00968 00969 }
| void psi::detcas::scale_gradient | ( | void | ) |
Scales the orbital gradient by the approximate orbital Hessian
Definition at line 803 of file detcas.cc.
References init_array().
00804 { 00805 int pair, npairs; 00806 double rms, value; 00807 00808 npairs = IndPairs.get_num_pairs(); 00809 00810 CalcInfo.theta_step = init_array(npairs); 00811 00812 // All this actually does is scale the gradient by the Hessian 00813 // If we have a diagonal (exact or approximate) Hessian 00814 00815 // BFGS 00816 if (Params.scale_grad && Params.bfgs) { 00817 calc_orb_step_bfgs(npairs, CalcInfo.mo_grad, CalcInfo.mo_hess, 00818 CalcInfo.theta_step); 00819 } 00820 // non-BFGS diagonal Hessian 00821 else if (Params.scale_grad && (strcmp(Params.hessian,"DIAG")==0 || 00822 strcmp(Params.hessian,"APPROX_DIAG")==0)) { 00823 calc_orb_step(npairs, CalcInfo.mo_grad, CalcInfo.mo_hess_diag, 00824 CalcInfo.theta_step); 00825 } 00826 // non-BFGS full Hessian 00827 else if ((Params.scale_grad && strcmp(Params.hessian,"FULL")==0) || 00828 Params.bfgs) { 00829 calc_orb_step_full(npairs, CalcInfo.mo_grad, CalcInfo.mo_hess, 00830 CalcInfo.theta_step); 00831 } 00832 // No Hessian available: take unit step down gradient direction 00833 else { 00834 for (pair=0; pair<npairs; pair++) 00835 CalcInfo.theta_step[pair] = CalcInfo.mo_grad[pair]; 00836 } 00837 00838 00839 if (Params.print_lvl > 3) 00840 IndPairs.print_vec(CalcInfo.theta_step,"\n\tScaled Orbital Grad:", outfile); 00841 00842 rms = 0.0; 00843 for (pair=0; pair<npairs; pair++) { 00844 value = CalcInfo.theta_step[pair]; 00845 rms += value * value; 00846 } 00847 00848 rms = sqrt(rms); 00849 CalcInfo.scaled_mo_grad_rms = rms; 00850 00851 if (Params.print_lvl) 00852 fprintf(outfile, "\n\tScaled RMS Orbital Gradient: %6.4E\n", rms); 00853 00854 if (Params.scale_step != 1.0) { 00855 for (pair=0; pair<npairs; pair++) 00856 CalcInfo.theta_step[pair] *= Params.scale_step; 00857 } 00858 00859 }
| int psi::detcas::take_step | ( | void | ) |
This function takes a step in orbital rotation (theta) space
Returns: type of step taken; 1=regular (Newton-Raphson), 2=diis
Definition at line 871 of file detcas.cc.
00872 { 00873 int npairs, pair, took_diis; 00874 00875 npairs = IndPairs.get_num_pairs(); 00876 00877 /* for debugging purposes */ 00878 if (Params.force_step) { 00879 CalcInfo.theta_cur[Params.force_pair] = Params.force_value; 00880 fprintf(outfile, "Forcing step for pair %d of size %8.3E\n", 00881 Params.force_pair, Params.force_value); 00882 return(1); 00883 } 00884 00885 for (pair=0; pair<npairs; pair++) 00886 CalcInfo.theta_cur[pair] += CalcInfo.theta_step[pair]; 00887 //CalcInfo.theta_cur[pair] = CalcInfo.theta_step[pair]; 00888 00889 if (CalcInfo.iter >= Params.diis_start) 00890 took_diis = diis(npairs, CalcInfo.theta_cur, CalcInfo.theta_step); 00891 //took_diis = diis(npairs, CalcInfo.theta_cur, CalcInfo.mo_grad); 00892 else 00893 took_diis = 0; 00894 00895 if (!took_diis) { 00896 if (Params.print_lvl) 00897 fprintf(outfile, "Taking regular step\n"); 00898 } 00899 00900 return(took_diis+1); 00901 00902 }
1.5.4