mirror of
https://github.com/QuantumPackage/qp2.git
synced 2024-10-08 08:57:19 +02:00
Merge branch 'dev-stable' of github.com:QuantumPackage/qp2 into dev-stable
This commit is contained in:
commit
0272c6489a
@ -46,7 +46,7 @@ def main(arguments):
|
||||
append_bats(dirname, filenames)
|
||||
else:
|
||||
for (dirname, _, filenames) in os.walk(os.getcwd(), followlinks=False):
|
||||
if "IRPF90_temp" not in dirname:
|
||||
if "IRPF90_temp" not in dirname and "external" not in dirname:
|
||||
append_bats(dirname, filenames)
|
||||
l_bats = [y for _, y in sorted(l_bats)]
|
||||
|
||||
@ -67,6 +67,7 @@ def main(arguments):
|
||||
os.system(test+" python3 bats_to_sh.py "+bats_file+
|
||||
"| bash")
|
||||
else:
|
||||
# print(" ".join(["bats", "--verbose-run", "--trace", bats_file]))
|
||||
subprocess.check_call(["bats", "--verbose-run", "--trace", bats_file], env=os.environ)
|
||||
|
||||
|
||||
|
12
etc/qp.rc
12
etc/qp.rc
@ -110,6 +110,11 @@ function qp()
|
||||
unset COMMAND
|
||||
;;
|
||||
|
||||
"test")
|
||||
shift
|
||||
qp_test $@
|
||||
;;
|
||||
|
||||
*)
|
||||
which "qp_$1" &> /dev/null
|
||||
if [[ $? -eq 0 ]] ; then
|
||||
@ -183,7 +188,7 @@ _qp_Complete()
|
||||
;;
|
||||
esac;;
|
||||
set_file)
|
||||
COMPREPLY=( $(compgen -W "$(for i in * ; do [[ -f ${i}/ezfio/.version ]] && echo $i ; done)" -- ${cur} ) )
|
||||
COMPREPLY=( $(compgen -W "$(for i in $(find . -name ezfio | sed 's/ezfio$/.version/') ; do [[ -f $i ]] && echo ${i%/.version} ; done)" -- ${cur} ) )
|
||||
return 0
|
||||
;;
|
||||
plugins)
|
||||
@ -215,10 +220,15 @@ _qp_Complete()
|
||||
return 0
|
||||
;;
|
||||
esac;;
|
||||
test)
|
||||
COMPREPLY=( $(compgen -W "-v -a " -- $cur ) )
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
COMPREPLY=( $(compgen -W 'plugins set_file \
|
||||
unset_file man \
|
||||
create_ezfio \
|
||||
test \
|
||||
convert_output_to_ezfio \
|
||||
-h update' -- $cur ) )
|
||||
|
||||
|
97
src/mo_localization/84.mo_localization.bats
Normal file
97
src/mo_localization/84.mo_localization.bats
Normal file
@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
source $QP_ROOT/tests/bats/common.bats.sh
|
||||
source $QP_ROOT/quantum_package.rc
|
||||
|
||||
zero () {
|
||||
if [ -z "$1" ]; then echo 0.0; else echo $1; fi
|
||||
}
|
||||
|
||||
function run() {
|
||||
thresh1=1e-10
|
||||
thresh2=1e-12
|
||||
thresh3=1e-4
|
||||
test_exe scf || skip
|
||||
qp set_file $1
|
||||
qp edit --check
|
||||
qp reset -d
|
||||
qp set_frozen_core
|
||||
qp set localization localization_method boys
|
||||
file="$(echo $1 | sed 's/.ezfio//g')"
|
||||
energy="$(cat $1/hartree_fock/energy)"
|
||||
fb_err1="$(qp run debug_gradient_loc | grep 'Max error' | tail -n 1 | awk '{print $3}')"
|
||||
fb_err2="$(qp run debug_hessian_loc | grep 'Max error' | tail -n 1 | awk '{print $3}')"
|
||||
qp run localization > $file.loc.out
|
||||
fb_energy="$(qp run print_energy | grep -A 1 'Nuclear repulsion energy' | tail -n 1 )"
|
||||
fb_c="$(cat $file.loc.out | grep 'Criterion:Core' | tail -n 1 | awk '{print $3}')i"
|
||||
fb_i="$(cat $file.loc.out | grep 'Criterion:Inactive' | tail -n 1 | awk '{print $3}')"
|
||||
fb_a="$(cat $file.loc.out | grep 'Criterion:Active' | tail -n 1 | awk '{print $3}')"
|
||||
fb_v="$(cat $file.loc.out | grep 'Criterion:Virtual' | tail -n 1 | awk '{print $3}')"
|
||||
qp reset -a
|
||||
qp run scf
|
||||
qp set_frozen_core
|
||||
qp set localization localization_method pipek
|
||||
pm_err1="$(qp run debug_gradient_loc | grep 'Max error' | tail -n 1 | awk '{print $3}')"
|
||||
pm_err2="$(qp run debug_hessian_loc | grep 'Max error' | tail -n 1 | awk '{print $3}')"
|
||||
qp run localization > $file.loc.out
|
||||
pm_c="$(cat $file.loc.out | grep 'Criterion:Core' | tail -n 1 | awk '{print $3}')i"
|
||||
pm_i="$(cat $file.loc.out | grep 'Criterion:Inactive' | tail -n 1 | awk '{print $3}')"
|
||||
pm_a="$(cat $file.loc.out | grep 'Criterion:Active' | tail -n 1 | awk '{print $3}')"
|
||||
pm_v="$(cat $file.loc.out | grep 'Criterion:Virtual' | tail -n 1 | awk '{print $3}')"
|
||||
pm_energy="$(qp run print_energy | grep -A 1 'Nuclear repulsion energy' | tail -n 1 )"
|
||||
qp set localization localization_method boys
|
||||
qp reset -a
|
||||
qp run scf
|
||||
qp set_frozen_core
|
||||
eq $energy $fb_energy $thresh1
|
||||
eq $fb_err1 0.0 $thresh2
|
||||
eq $fb_err2 0.0 $thresh2
|
||||
eq $energy $pm_energy $thresh1
|
||||
eq $pm_err1 0.0 $thresh2
|
||||
eq $pm_err2 0.0 $thresh2
|
||||
fb_c=$(zero $fb_c)
|
||||
fb_i=$(zero $fb_i)
|
||||
fb_a=$(zero $fb_a)
|
||||
fb_v=$(zero $fb_v)
|
||||
pm_c=$(zero $pm_c)
|
||||
pm_i=$(zero $pm_i)
|
||||
pm_a=$(zero $pm_a)
|
||||
pm_v=$(zero $pm_v)
|
||||
eq $fb_c $2 $thresh3
|
||||
eq $fb_i $3 $thresh3
|
||||
eq $fb_a $4 $thresh3
|
||||
eq $fb_v $5 $thresh3
|
||||
eq $pm_c $6 $thresh3
|
||||
eq $pm_i $7 $thresh3
|
||||
eq $pm_a $8 $thresh3
|
||||
eq $pm_v $9 $thresh3
|
||||
}
|
||||
|
||||
@test "b2_stretched" {
|
||||
run b2_stretched.ezfio -32.1357551678876 -47.0041982094667 0.0 -223.470015856259 -1.99990778964451 -2.51376723927071 0.0 -12.8490602539275
|
||||
}
|
||||
|
||||
@test "clo" {
|
||||
run clo.ezfio -44.1624001765291 -32.4386660941387 0.0 -103.666309287187 -5.99985418946811 -5.46871580225222 0.0 -20.2480064922275
|
||||
}
|
||||
|
||||
@test "clf" {
|
||||
run clf.ezfio -47.5143398826967 -35.7206886315104 0.0 -107.043029033468 -5.99994222062230 -6.63916513458470 0.0 -19.7035159913484
|
||||
}
|
||||
|
||||
@test "h2o2" {
|
||||
run h2o2.ezfio -7.76848143170524 -30.9694344369829 0.0 -175.898343829453 -1.99990497554575 -5.62980322957485 0.0 -33.5699813186666
|
||||
}
|
||||
|
||||
@test "h2o" {
|
||||
run h2o.ezfio 0.0 -2.52317434969591 0.0 -45.3136377925359 0.0 -3.01248365356981 0.0 -22.4470831240924
|
||||
}
|
||||
|
||||
@test "h3coh" {
|
||||
run h3coh.ezfio -3.66763692804590 -24.0463089480870 0.0 -111.485948435075 -1.99714061342078 -4.89242181322988 0.0 -23.6405412057679
|
||||
}
|
||||
|
||||
@test "n2h4" {
|
||||
run n2h4.ezfio -7.46608163002070 -35.7632174051822 0.0 -305.913449004632 -1.99989326143356 -4.62496615892268 0.0 -51.5171904685553
|
||||
}
|
||||
|
54
src/mo_localization/EZFIO.cfg
Normal file
54
src/mo_localization/EZFIO.cfg
Normal file
@ -0,0 +1,54 @@
|
||||
[localization_method]
|
||||
type: character*(32)
|
||||
doc: Method for the orbital localization. boys: Foster-Boys, pipek: Pipek-Mezey.
|
||||
interface: ezfio,provider,ocaml
|
||||
default: boys
|
||||
|
||||
[localization_max_nb_iter]
|
||||
type: integer
|
||||
doc: Maximal number of iterations for the orbital localization.
|
||||
interface: ezfio,provider,ocaml
|
||||
default: 1000
|
||||
|
||||
[localization_use_hessian]
|
||||
type: logical
|
||||
doc: If true, it uses the trust region algorithm with the gradient and the diagonal of the hessian. Else it computes the rotation between each pair of MOs that should be applied to maximize/minimize the localization criterion. The last option is not easy to converge.
|
||||
interface: ezfio,provider,ocaml
|
||||
default: true
|
||||
|
||||
[auto_mo_class]
|
||||
type: logical
|
||||
doc: If true, set automatically the classes.
|
||||
interface: ezfio,provider,ocaml
|
||||
default: true
|
||||
|
||||
[thresh_loc_max_elem_grad]
|
||||
type: double precision
|
||||
doc: Threshold for the convergence, the localization exits when the largest element in the gradient is smaller than thresh_localization_max_elem_grad.
|
||||
interface: ezfio,provider,ocaml
|
||||
default: 1.e-6
|
||||
|
||||
[kick_in_mos]
|
||||
type: logical
|
||||
doc: If True, it applies a rotation of an angle angle_pre_rot between the MOs of a same mo_class before the localization.
|
||||
interface: ezfio,provider,ocaml
|
||||
default: true
|
||||
|
||||
[angle_pre_rot]
|
||||
type: double precision
|
||||
doc: To define the angle for the rotation of the MOs before the localization (in rad).
|
||||
interface: ezfio,provider,ocaml
|
||||
default: 0.1
|
||||
|
||||
[sort_mos_by_e]
|
||||
type: logical
|
||||
doc: If True, the MOs are sorted using the diagonal elements of the Fock matrix.
|
||||
interface: ezfio,provider,ocaml
|
||||
default: false
|
||||
|
||||
[debug_hf]
|
||||
type: logical
|
||||
doc: If True, prints the HF energy before/after the different steps of the localization. Only for debugging.
|
||||
interface: ezfio,provider,ocaml
|
||||
default: false
|
||||
|
3
src/mo_localization/NEED
Normal file
3
src/mo_localization/NEED
Normal file
@ -0,0 +1,3 @@
|
||||
hartree_fock
|
||||
utils_trust_region
|
||||
determinants
|
113
src/mo_localization/README.md
Normal file
113
src/mo_localization/README.md
Normal file
@ -0,0 +1,113 @@
|
||||
# Orbital localisation
|
||||
To localize the MOs:
|
||||
```
|
||||
qp run localization
|
||||
```
|
||||
By default, the different otbital classes are automatically set by splitting
|
||||
the orbitales in the following classes:
|
||||
- Core -> Core
|
||||
- Active, doubly occupied -> Inactive
|
||||
- Active, singly occupied -> Active
|
||||
- Active, empty -> Virtual
|
||||
- Deleted -> Deleted
|
||||
The orbitals will be localized among each class, excpect the deleted ones.
|
||||
If you want to choose another splitting, you can set
|
||||
```
|
||||
qp set mo_localization auto_mo_class false
|
||||
```
|
||||
and define the classes with
|
||||
```
|
||||
qp set_mo_class -c [] -a [] -v [] -i [] -d []
|
||||
```
|
||||
for more information
|
||||
```
|
||||
qp set_mo_class -q
|
||||
```
|
||||
We don't care about the name of the
|
||||
mo classes. The algorithm just localizes all the MOs of
|
||||
a given class between them, for all the classes, except the deleted MOs.
|
||||
If you are using the last option don't forget to reset the initial mo classes
|
||||
after the localization.
|
||||
|
||||
Before the localization, a kick is done for each mo class
|
||||
(except the deleted ones) to break the MOs. This is done by
|
||||
doing a given rotation between the MOs.
|
||||
This feature can be removed by setting:
|
||||
```
|
||||
qp set localization kick_in_mos false
|
||||
```
|
||||
and the default angle for the rotation can be changed with:
|
||||
```
|
||||
qp set localization angle_pre_rot 1e-3 # or something else
|
||||
```
|
||||
|
||||
After the localization, the MOs of each class (except the deleted ones)
|
||||
can be sorted between them using the diagonal elements of
|
||||
the fock matrix with:
|
||||
```
|
||||
qp set localization sort_mos_by_e true
|
||||
```
|
||||
|
||||
You can check the Hartree-Fock energy before/during/after the localization
|
||||
by putting (only for debugging):
|
||||
```
|
||||
qp set localization debug_hf true
|
||||
```
|
||||
|
||||
## Foster-Boys & Pipek-Mezey
|
||||
Foster-Boys:
|
||||
```
|
||||
qp set localization localization_method boys
|
||||
```
|
||||
|
||||
Pipek-Mezey:
|
||||
```
|
||||
qp set localization localization_method pipek
|
||||
```
|
||||
|
||||
# Break the spatial symmetry of the MOs
|
||||
This program work exactly as the localization.
|
||||
To break the spatial symmetry of the MOs:
|
||||
```
|
||||
qp run break_spatial_sym
|
||||
```
|
||||
The default angle for the rotations is too big for this kind of
|
||||
application, a value between 1e-3 and 1e-6 should break the spatial
|
||||
symmetry with just a small change in the energy:
|
||||
```
|
||||
qp set localization angle_pre_rot 1e-3
|
||||
```
|
||||
|
||||
# With or without hessian + trust region
|
||||
With hessian + trust region
|
||||
```
|
||||
qp set localization localisation_use_hessian true
|
||||
```
|
||||
It uses the trust region algorithm with the diagonal of the hessian of the
|
||||
localization criterion with respect to the MO rotations.
|
||||
|
||||
Without the hessian and the trust region
|
||||
```
|
||||
qp set localization localisation_use_hessian false
|
||||
```
|
||||
By doing so it does not require to store the hessian but the
|
||||
convergence is not easy, in particular for virtual MOs.
|
||||
It seems that it not possible to converge with Pipek-Mezey
|
||||
localization with this approach.
|
||||
|
||||
# Parameters
|
||||
Some other parameters are available for the localization (qp edit for more details).
|
||||
|
||||
# Tests
|
||||
```
|
||||
qp test
|
||||
```
|
||||
|
||||
# Org files
|
||||
The org files are stored in the directory org in order to avoid overwriting on user changes.
|
||||
The org files can be modified, to export the change to the source code, run
|
||||
```
|
||||
./TANGLE_org_mode.sh
|
||||
mv *.irp.f ../.
|
||||
```
|
||||
|
27
src/mo_localization/break_spatial_sym.irp.f
Normal file
27
src/mo_localization/break_spatial_sym.irp.f
Normal file
@ -0,0 +1,27 @@
|
||||
! ! A small program to break the spatial symmetry of the MOs.
|
||||
|
||||
! ! You have to defined your MO classes or set security_mo_class to false
|
||||
! ! with:
|
||||
! ! qp set orbital_optimization security_mo_class false
|
||||
|
||||
! ! The default angle for the rotations is too big for this kind of
|
||||
! ! application, a value between 1e-3 and 1e-6 should break the spatial
|
||||
! ! symmetry with just a small change in the energy.
|
||||
|
||||
|
||||
program break_spatial_sym
|
||||
|
||||
!BEGIN_DOC
|
||||
! Break the symmetry of the MOs with a rotation
|
||||
!END_DOC
|
||||
|
||||
implicit none
|
||||
|
||||
kick_in_mos = .True.
|
||||
TOUCH kick_in_mos
|
||||
|
||||
call set_classes_loc
|
||||
call apply_pre_rotation
|
||||
call unset_classes_loc
|
||||
|
||||
end
|
65
src/mo_localization/debug_gradient_loc.irp.f
Normal file
65
src/mo_localization/debug_gradient_loc.irp.f
Normal file
@ -0,0 +1,65 @@
|
||||
program debug_gradient_loc
|
||||
|
||||
!BEGIN_DOC
|
||||
! Check if the gradient is correct
|
||||
!END_DOC
|
||||
|
||||
implicit none
|
||||
|
||||
integer :: list_size, n
|
||||
integer, allocatable :: list(:)
|
||||
double precision, allocatable :: v_grad(:), v_grad2(:)
|
||||
double precision :: norm, max_elem, threshold, max_error
|
||||
integer :: i, nb_error
|
||||
|
||||
threshold = 1d-12
|
||||
|
||||
list_size = dim_list_act_orb
|
||||
|
||||
allocate(list(list_size))
|
||||
|
||||
list = list_act
|
||||
|
||||
n = list_size*(list_size-1)/2
|
||||
|
||||
allocate(v_grad(n),v_grad2(n))
|
||||
|
||||
if (localization_method == 'boys') then
|
||||
print*,'Foster-Boys'
|
||||
call gradient_FB(n,list_size,list,v_grad,max_elem,norm)
|
||||
call gradient_FB_omp(n,list_size,list,v_grad2,max_elem,norm)
|
||||
elseif (localization_method == 'pipek') then
|
||||
print*,'Pipek-Mezey'
|
||||
call gradient_PM(n,list_size,list,v_grad,max_elem,norm)
|
||||
call gradient_PM(n,list_size,list,v_grad2,max_elem,norm)
|
||||
else
|
||||
print*,'Unknown localization_method, please select boys or pipek'
|
||||
call abort
|
||||
endif
|
||||
|
||||
do i = 1, n
|
||||
print*,i,v_grad(i)
|
||||
enddo
|
||||
|
||||
v_grad = v_grad - v_grad2
|
||||
|
||||
nb_error = 0
|
||||
max_elem = 0d0
|
||||
|
||||
do i = 1, n
|
||||
if (dabs(v_grad(i)) > threshold) then
|
||||
print*,v_grad(i)
|
||||
nb_error = nb_error + 1
|
||||
if (dabs(v_grad(i)) > max_elem) then
|
||||
max_elem = v_grad(i)
|
||||
endif
|
||||
endif
|
||||
enddo
|
||||
|
||||
print*,'Threshold error', threshold
|
||||
print*, 'Nb error', nb_error
|
||||
print*,'Max error', max_elem
|
||||
|
||||
deallocate(v_grad,v_grad2)
|
||||
|
||||
end
|
65
src/mo_localization/debug_hessian_loc.irp.f
Normal file
65
src/mo_localization/debug_hessian_loc.irp.f
Normal file
@ -0,0 +1,65 @@
|
||||
program debug_hessian_loc
|
||||
|
||||
!BEGIN_DOC
|
||||
! Check if the hessian is correct
|
||||
!END_DOC
|
||||
|
||||
implicit none
|
||||
|
||||
integer :: list_size, n
|
||||
integer, allocatable :: list(:)
|
||||
double precision, allocatable :: H(:), H2(:)
|
||||
double precision :: threshold, max_error, max_elem
|
||||
integer :: i, nb_error
|
||||
|
||||
threshold = 1d-12
|
||||
|
||||
list_size = dim_list_act_orb
|
||||
|
||||
allocate(list(list_size))
|
||||
|
||||
list = list_act
|
||||
|
||||
n = list_size*(list_size-1)/2
|
||||
|
||||
allocate(H(n),H2(n))
|
||||
|
||||
if (localization_method == 'boys') then
|
||||
print*,'Foster-Boys'
|
||||
call hessian_FB(n,list_size,list,H)
|
||||
call hessian_FB_omp(n,list_size,list,H2)
|
||||
elseif(localization_method == 'pipek') then
|
||||
print*,'Pipek-Mezey'
|
||||
call hessian_PM(n,list_size,list,H)
|
||||
call hessian_PM(n,list_size,list,H2)
|
||||
else
|
||||
print*,'Unknown localization_method, please select boys or pipek'
|
||||
call abort
|
||||
endif
|
||||
|
||||
do i = 1, n
|
||||
print*,i,H(i)
|
||||
enddo
|
||||
|
||||
H = H - H2
|
||||
|
||||
nb_error = 0
|
||||
max_elem = 0d0
|
||||
|
||||
do i = 1, n
|
||||
if (dabs(H(i)) > threshold) then
|
||||
print*,H(i)
|
||||
nb_error = nb_error + 1
|
||||
if (dabs(H(i)) > max_elem) then
|
||||
max_elem = H(i)
|
||||
endif
|
||||
endif
|
||||
enddo
|
||||
|
||||
print*,'Threshold error', threshold
|
||||
print*, 'Nb error', nb_error
|
||||
print*,'Max error', max_elem
|
||||
|
||||
deallocate(H,H2)
|
||||
|
||||
end
|
16
src/mo_localization/kick_the_mos.irp.f
Normal file
16
src/mo_localization/kick_the_mos.irp.f
Normal file
@ -0,0 +1,16 @@
|
||||
program kick_the_mos
|
||||
|
||||
!BEGIN_DOC
|
||||
! To do a small rotation of the MOs
|
||||
!END_DOC
|
||||
|
||||
implicit none
|
||||
|
||||
kick_in_mos = .True.
|
||||
TOUCH kick_in_mos
|
||||
|
||||
call set_classes_loc
|
||||
call apply_pre_rotation
|
||||
call unset_classes_loc
|
||||
|
||||
end
|
520
src/mo_localization/localization.irp.f
Normal file
520
src/mo_localization/localization.irp.f
Normal file
@ -0,0 +1,520 @@
|
||||
program localization
|
||||
|
||||
implicit none
|
||||
|
||||
call set_classes_loc
|
||||
call run_localization
|
||||
call unset_classes_loc
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
! Variables:
|
||||
! | pre_rot(mo_num, mo_num) | double precision | Matrix for the pre rotation |
|
||||
! | R(mo_num,mo_num) | double precision | Rotation matrix |
|
||||
! | tmp_R(:,:) | double precision | Rottation matrix in a subsapce |
|
||||
! | prev_mos(ao_num, mo_num) | double precision | Previous mo_coef |
|
||||
! | spatial_extent(mo_num) | double precision | Spatial extent of the orbitals |
|
||||
! | criterion | double precision | Localization criterion |
|
||||
! | prev_criterion | double precision | Previous criterion |
|
||||
! | criterion_model | double precision | Estimated next criterion |
|
||||
! | rho | double precision | Ratio to measure the agreement between the model |
|
||||
! | | | and the reality |
|
||||
! | delta | double precision | Radisu of the trust region |
|
||||
! | norm_grad | double precision | Norm of the gradient |
|
||||
! | info | integer | for dsyev from Lapack |
|
||||
! | max_elem | double precision | maximal element in the gradient |
|
||||
! | v_grad(:) | double precision | Gradient |
|
||||
! | H(:,:) | double precision | Hessian (diagonal) |
|
||||
! | e_val(:) | double precision | Eigenvalues of the hessian |
|
||||
! | W(:,:) | double precision | Eigenvectors of the hessian |
|
||||
! | tmp_x(:) | double precision | Step in 1D (in a subaspace) |
|
||||
! | tmp_m_x(:,:) | double precision | Step in 2D (in a subaspace) |
|
||||
! | tmp_list(:) | double precision | List of MOs in a mo_class |
|
||||
! | i,j,k | integer | Indexes in the full MO space |
|
||||
! | tmp_i, tmp_j, tmp_k | integer | Indexes in a subspace |
|
||||
! | l | integer | Index for the mo_class |
|
||||
! | key(:) | integer | Key to sort the eigenvalues of the hessian |
|
||||
! | nb_iter | integer | Number of iterations |
|
||||
! | must_exit | logical | To exit the trust region loop |
|
||||
! | cancel_step | logical | To cancel a step |
|
||||
! | not_*converged | logical | To localize the different mo classes |
|
||||
! | t* | double precision | To measure the time |
|
||||
! | n | integer | mo_num*(mo_num-1)/2, number of orbital parameters |
|
||||
! | tmp_n | integer | dim_subspace*(dim_subspace-1)/2 |
|
||||
! | | | Number of dimension in the subspace |
|
||||
|
||||
! Variables in qp_edit for the localization:
|
||||
! | localization_method |
|
||||
! | localization_max_nb_iter |
|
||||
! | default_mo_class |
|
||||
! | thresh_loc_max_elem_grad |
|
||||
! | kick_in_mos |
|
||||
! | angle_pre_rot |
|
||||
|
||||
! + all the variables for the trust region
|
||||
|
||||
! Cf. qp_edit orbital optimization
|
||||
|
||||
|
||||
subroutine run_localization
|
||||
|
||||
include 'pi.h'
|
||||
|
||||
BEGIN_DOC
|
||||
! Orbital localization
|
||||
END_DOC
|
||||
|
||||
implicit none
|
||||
|
||||
! Variables
|
||||
double precision, allocatable :: pre_rot(:,:), R(:,:)
|
||||
double precision, allocatable :: prev_mos(:,:), spatial_extent(:), tmp_R(:,:)
|
||||
double precision :: criterion, norm_grad
|
||||
integer :: i,j,k,l,p, tmp_i, tmp_j, tmp_k
|
||||
integer :: info
|
||||
integer :: n, tmp_n, tmp_list_size
|
||||
double precision, allocatable :: v_grad(:), H(:), tmp_m_x(:,:), tmp_x(:),W(:),e_val(:)
|
||||
double precision :: max_elem, t1, t2, t3, t4, t5, t6
|
||||
integer, allocatable :: tmp_list(:), key(:)
|
||||
double precision :: prev_criterion, rho, delta, criterion_model
|
||||
integer :: nb_iter, nb_sub_iter
|
||||
logical :: not_converged, not_core_converged
|
||||
logical :: not_act_converged, not_inact_converged, not_virt_converged
|
||||
logical :: use_trust_region, must_exit, cancel_step,enforce_step_cancellation
|
||||
|
||||
n = mo_num*(mo_num-1)/2
|
||||
|
||||
! Allocation
|
||||
allocate(spatial_extent(mo_num))
|
||||
allocate(pre_rot(mo_num, mo_num), R(mo_num, mo_num))
|
||||
allocate(prev_mos(ao_num, mo_num))
|
||||
|
||||
! Locality before the localization
|
||||
call compute_spatial_extent(spatial_extent)
|
||||
|
||||
! Choice of the method
|
||||
print*,''
|
||||
print*,'Localization method:',localization_method
|
||||
if (localization_method == 'boys') then
|
||||
print*,'Foster-Boys localization'
|
||||
elseif (localization_method == 'pipek') then
|
||||
print*,'Pipek-Mezey localization'
|
||||
else
|
||||
print*,'Unknown localization_method, please select boys or pipek'
|
||||
call abort
|
||||
endif
|
||||
print*,''
|
||||
|
||||
! Localization criterion (FB, PM, ...) for each mo_class
|
||||
print*,'### Before the pre rotation'
|
||||
|
||||
! Debug
|
||||
if (debug_hf) then
|
||||
print*,'HF energy:', HF_energy
|
||||
endif
|
||||
|
||||
do l = 1, 4
|
||||
if (l==1) then ! core
|
||||
tmp_list_size = dim_list_core_orb
|
||||
elseif (l==2) then ! act
|
||||
tmp_list_size = dim_list_act_orb
|
||||
elseif (l==3) then ! inact
|
||||
tmp_list_size = dim_list_inact_orb
|
||||
else ! virt
|
||||
tmp_list_size = dim_list_virt_orb
|
||||
endif
|
||||
|
||||
! Allocation tmp array
|
||||
allocate(tmp_list(tmp_list_size))
|
||||
|
||||
! To give the list of MOs in a mo_class
|
||||
if (l==1) then ! core
|
||||
tmp_list = list_core
|
||||
elseif (l==2) then
|
||||
tmp_list = list_act
|
||||
elseif (l==3) then
|
||||
tmp_list = list_inact
|
||||
else
|
||||
tmp_list = list_virt
|
||||
endif
|
||||
|
||||
if (tmp_list_size >= 2) then
|
||||
call criterion_localization(tmp_list_size, tmp_list,criterion)
|
||||
print*,'Criterion:', criterion, mo_class(tmp_list(1))
|
||||
endif
|
||||
|
||||
deallocate(tmp_list)
|
||||
|
||||
enddo
|
||||
|
||||
! Debug
|
||||
!print*,'HF', HF_energy
|
||||
|
||||
! Loc
|
||||
|
||||
! Pre rotation, to give a little kick in the MOs
|
||||
call apply_pre_rotation()
|
||||
|
||||
! Criterion after the pre rotation
|
||||
! Localization criterion (FB, PM, ...) for each mo_class
|
||||
print*,'### After the pre rotation'
|
||||
|
||||
! Debug
|
||||
if (debug_hf) then
|
||||
touch mo_coef
|
||||
print*,'HF energy:', HF_energy
|
||||
endif
|
||||
|
||||
do l = 1, 4
|
||||
if (l==1) then ! core
|
||||
tmp_list_size = dim_list_core_orb
|
||||
elseif (l==2) then ! act
|
||||
tmp_list_size = dim_list_act_orb
|
||||
elseif (l==3) then ! inact
|
||||
tmp_list_size = dim_list_inact_orb
|
||||
else ! virt
|
||||
tmp_list_size = dim_list_virt_orb
|
||||
endif
|
||||
|
||||
if (tmp_list_size >= 2) then
|
||||
! Allocation tmp array
|
||||
allocate(tmp_list(tmp_list_size))
|
||||
|
||||
! To give the list of MOs in a mo_class
|
||||
if (l==1) then ! core
|
||||
tmp_list = list_core
|
||||
elseif (l==2) then
|
||||
tmp_list = list_act
|
||||
elseif (l==3) then
|
||||
tmp_list = list_inact
|
||||
else
|
||||
tmp_list = list_virt
|
||||
endif
|
||||
|
||||
call criterion_localization(tmp_list_size, tmp_list,criterion)
|
||||
print*,'Criterion:', criterion, trim(mo_class(tmp_list(1)))
|
||||
|
||||
deallocate(tmp_list)
|
||||
endif
|
||||
|
||||
enddo
|
||||
|
||||
! Debug
|
||||
!print*,'HF', HF_energy
|
||||
|
||||
print*,''
|
||||
print*,'========================'
|
||||
print*,' Orbital localization'
|
||||
print*,'========================'
|
||||
print*,''
|
||||
|
||||
!Initialization
|
||||
not_converged = .TRUE.
|
||||
|
||||
! To do the localization only if there is at least 2 MOs
|
||||
if (dim_list_core_orb >= 2) then
|
||||
not_core_converged = .TRUE.
|
||||
else
|
||||
not_core_converged = .FALSE.
|
||||
endif
|
||||
|
||||
if (dim_list_act_orb >= 2) then
|
||||
not_act_converged = .TRUE.
|
||||
else
|
||||
not_act_converged = .FALSE.
|
||||
endif
|
||||
|
||||
if (dim_list_inact_orb >= 2) then
|
||||
not_inact_converged = .TRUE.
|
||||
else
|
||||
not_inact_converged = .FALSE.
|
||||
endif
|
||||
|
||||
if (dim_list_virt_orb >= 2) then
|
||||
not_virt_converged = .TRUE.
|
||||
else
|
||||
not_virt_converged = .FALSE.
|
||||
endif
|
||||
|
||||
! Loop over the mo_classes
|
||||
do l = 1, 4
|
||||
|
||||
if (l==1) then ! core
|
||||
not_converged = not_core_converged
|
||||
tmp_list_size = dim_list_core_orb
|
||||
elseif (l==2) then ! act
|
||||
not_converged = not_act_converged
|
||||
tmp_list_size = dim_list_act_orb
|
||||
elseif (l==3) then ! inact
|
||||
not_converged = not_inact_converged
|
||||
tmp_list_size = dim_list_inact_orb
|
||||
else ! virt
|
||||
not_converged = not_virt_converged
|
||||
tmp_list_size = dim_list_virt_orb
|
||||
endif
|
||||
|
||||
! Next iteration if converged = true
|
||||
if (.not. not_converged) then
|
||||
cycle
|
||||
endif
|
||||
|
||||
! Allocation tmp array
|
||||
allocate(tmp_list(tmp_list_size))
|
||||
|
||||
! To give the list of MOs in a mo_class
|
||||
if (l==1) then ! core
|
||||
tmp_list = list_core
|
||||
elseif (l==2) then
|
||||
tmp_list = list_act
|
||||
elseif (l==3) then
|
||||
tmp_list = list_inact
|
||||
else
|
||||
tmp_list = list_virt
|
||||
endif
|
||||
|
||||
! Display
|
||||
if (not_converged) then
|
||||
print*,''
|
||||
print*,'###', trim(mo_class(tmp_list(1))), 'MOs ###'
|
||||
print*,''
|
||||
endif
|
||||
|
||||
! Size for the 2D -> 1D transformation
|
||||
tmp_n = tmp_list_size * (tmp_list_size - 1)/2
|
||||
|
||||
! Without hessian + trust region
|
||||
if (.not. localization_use_hessian) then
|
||||
|
||||
! Allocation of temporary arrays
|
||||
allocate(v_grad(tmp_n), tmp_m_x(tmp_list_size, tmp_list_size))
|
||||
allocate(tmp_R(tmp_list_size, tmp_list_size), tmp_x(tmp_n))
|
||||
|
||||
! Criterion
|
||||
call criterion_localization(tmp_list_size, tmp_list, prev_criterion)
|
||||
|
||||
! Init
|
||||
nb_iter = 0
|
||||
delta = 1d0
|
||||
|
||||
!Loop
|
||||
do while (not_converged)
|
||||
|
||||
print*,''
|
||||
print*,'***********************'
|
||||
print*,'Iteration', nb_iter
|
||||
print*,'***********************'
|
||||
print*,''
|
||||
|
||||
! Angles of rotation
|
||||
call theta_localization(tmp_list, tmp_list_size, tmp_m_x, max_elem)
|
||||
tmp_m_x = - tmp_m_x * delta
|
||||
|
||||
! Rotation submatrix
|
||||
call rotation_matrix(tmp_m_x, tmp_list_size, tmp_R, tmp_list_size, tmp_list_size, &
|
||||
info, enforce_step_cancellation)
|
||||
|
||||
! To ensure that the rotation matrix is unitary
|
||||
if (enforce_step_cancellation) then
|
||||
print*, 'Step cancellation, too large error in the rotation matrix'
|
||||
delta = delta * 0.5d0
|
||||
cycle
|
||||
else
|
||||
delta = min(delta * 2d0, 1d0)
|
||||
endif
|
||||
|
||||
! Full rotation matrix and application of the rotation
|
||||
call sub_to_full_rotation_matrix(tmp_list_size, tmp_list, tmp_R, R)
|
||||
call apply_mo_rotation(R, prev_mos)
|
||||
|
||||
! Update the needed data
|
||||
call update_data_localization()
|
||||
|
||||
! New criterion
|
||||
call criterion_localization(tmp_list_size, tmp_list, criterion)
|
||||
print*,'Criterion:', trim(mo_class(tmp_list(1))), nb_iter, criterion
|
||||
print*,'Max elem :', max_elem
|
||||
print*,'Delta :', delta
|
||||
|
||||
nb_iter = nb_iter + 1
|
||||
|
||||
! Exit
|
||||
if (nb_iter >= localization_max_nb_iter .or. dabs(max_elem) < thresh_loc_max_elem_grad) then
|
||||
not_converged = .False.
|
||||
endif
|
||||
enddo
|
||||
|
||||
! Save the changes
|
||||
call update_data_localization()
|
||||
call save_mos()
|
||||
TOUCH mo_coef
|
||||
|
||||
! Deallocate
|
||||
deallocate(v_grad, tmp_m_x, tmp_list)
|
||||
deallocate(tmp_R, tmp_x)
|
||||
|
||||
! Trust region
|
||||
else
|
||||
|
||||
! Allocation of temporary arrays
|
||||
allocate(v_grad(tmp_n), H(tmp_n), tmp_m_x(tmp_list_size, tmp_list_size))
|
||||
allocate(tmp_R(tmp_list_size, tmp_list_size))
|
||||
allocate(tmp_x(tmp_n), W(tmp_n), e_val(tmp_n), key(tmp_n))
|
||||
|
||||
! ### Initialization ###
|
||||
delta = 0d0 ! can be deleted (normally)
|
||||
nb_iter = 0 ! Must start at 0 !!!
|
||||
rho = 0.5d0 ! Must be 0.5
|
||||
|
||||
! Compute the criterion before the loop
|
||||
call criterion_localization(tmp_list_size, tmp_list, prev_criterion)
|
||||
|
||||
! Loop until the convergence
|
||||
do while (not_converged)
|
||||
|
||||
print*,''
|
||||
print*,'***********************'
|
||||
print*,'Iteration', nb_iter
|
||||
print*,'***********************'
|
||||
print*,''
|
||||
|
||||
! Gradient
|
||||
call gradient_localization(tmp_n, tmp_list_size, tmp_list, v_grad, max_elem, norm_grad)
|
||||
! Diagonal hessian
|
||||
call hessian_localization(tmp_n, tmp_list_size, tmp_list, H)
|
||||
|
||||
! Diagonalization of the diagonal hessian by hands
|
||||
!call diagonalization_hessian(tmp_n,H,e_val,w)
|
||||
do i = 1, tmp_n
|
||||
e_val(i) = H(i)
|
||||
enddo
|
||||
|
||||
! Key list for dsort
|
||||
do i = 1, tmp_n
|
||||
key(i) = i
|
||||
enddo
|
||||
|
||||
! Sort of the eigenvalues
|
||||
call dsort(e_val, key, tmp_n)
|
||||
|
||||
! Eigenvectors
|
||||
W = 0d0
|
||||
do i = 1, tmp_n
|
||||
W(i) = dble(key(i))
|
||||
enddo
|
||||
|
||||
! To enter in the loop just after
|
||||
cancel_step = .True.
|
||||
nb_sub_iter = 0
|
||||
|
||||
! Loop to reduce the trust radius until the criterion decreases and rho >= thresh_rho
|
||||
do while (cancel_step)
|
||||
print*,'-----------------------------'
|
||||
print*, mo_class(tmp_list(1))
|
||||
print*,'Iteration:', nb_iter
|
||||
print*,'Sub iteration:', nb_sub_iter
|
||||
print*,'Max elem grad:', max_elem
|
||||
print*,'-----------------------------'
|
||||
|
||||
! Hessian,gradient,Criterion -> x
|
||||
call trust_region_step_w_expected_e(tmp_n,1, H, W, e_val, v_grad, prev_criterion, &
|
||||
rho, nb_iter, delta, criterion_model, tmp_x, must_exit)
|
||||
|
||||
! Internal loop exit condition
|
||||
if (must_exit) then
|
||||
print*,'trust_region_step_w_expected_e sent: Exit'
|
||||
exit
|
||||
endif
|
||||
|
||||
! 1D tmp -> 2D tmp
|
||||
call vec_to_mat_v2(tmp_n, tmp_list_size, tmp_x, tmp_m_x)
|
||||
|
||||
! Rotation submatrix (square matrix tmp_list_size by tmp_list_size)
|
||||
call rotation_matrix(tmp_m_x, tmp_list_size, tmp_R, tmp_list_size, tmp_list_size, &
|
||||
info, enforce_step_cancellation)
|
||||
|
||||
if (enforce_step_cancellation) then
|
||||
print*, 'Step cancellation, too large error in the rotation matrix'
|
||||
rho = 0d0
|
||||
cycle
|
||||
endif
|
||||
|
||||
! tmp_R to R, subspace to full space
|
||||
call sub_to_full_rotation_matrix(tmp_list_size, tmp_list, tmp_R, R)
|
||||
|
||||
! Rotation of the MOs
|
||||
call apply_mo_rotation(R, prev_mos)
|
||||
|
||||
! Update the things related to mo_coef
|
||||
call update_data_localization()
|
||||
|
||||
! Update the criterion
|
||||
call criterion_localization(tmp_list_size, tmp_list, criterion)
|
||||
print*,'Criterion:', trim(mo_class(tmp_list(1))), nb_iter, criterion
|
||||
|
||||
! Criterion -> step accepted or rejected
|
||||
call trust_region_is_step_cancelled(nb_iter, prev_criterion, criterion, &
|
||||
criterion_model, rho, cancel_step)
|
||||
|
||||
! Cancellation of the step, previous MOs
|
||||
if (cancel_step) then
|
||||
mo_coef = prev_mos
|
||||
endif
|
||||
|
||||
nb_sub_iter = nb_sub_iter + 1
|
||||
enddo
|
||||
!call save_mos() !### depend of the time for 1 iteration
|
||||
|
||||
! To exit the external loop if must_exti = .True.
|
||||
if (must_exit) then
|
||||
exit
|
||||
endif
|
||||
|
||||
! Step accepted, nb iteration + 1
|
||||
nb_iter = nb_iter + 1
|
||||
|
||||
! External loop exit conditions
|
||||
if (DABS(max_elem) < thresh_loc_max_elem_grad) then
|
||||
not_converged = .False.
|
||||
endif
|
||||
if (nb_iter > localization_max_nb_iter) then
|
||||
not_converged = .False.
|
||||
endif
|
||||
enddo
|
||||
|
||||
! Deallocation of temporary arrays
|
||||
deallocate(v_grad, H, tmp_m_x, tmp_R, tmp_list, tmp_x, W, e_val, key)
|
||||
|
||||
! Save the MOs
|
||||
call save_mos()
|
||||
TOUCH mo_coef
|
||||
|
||||
! Debug
|
||||
if (debug_hf) then
|
||||
touch mo_coef
|
||||
print*,'HF energy:', HF_energy
|
||||
endif
|
||||
|
||||
endif
|
||||
enddo
|
||||
|
||||
! Seems unecessary
|
||||
TOUCH mo_coef
|
||||
|
||||
! To sort the MOs using the diagonal elements of the Fock matrix
|
||||
if (sort_mos_by_e) then
|
||||
call run_sort_by_fock_energies()
|
||||
endif
|
||||
|
||||
! Debug
|
||||
if (debug_hf) then
|
||||
touch mo_coef
|
||||
print*,'HF energy:', HF_energy
|
||||
endif
|
||||
|
||||
! Locality after the localization
|
||||
call compute_spatial_extent(spatial_extent)
|
||||
|
||||
end
|
2008
src/mo_localization/localization_sub.irp.f
Normal file
2008
src/mo_localization/localization_sub.irp.f
Normal file
File diff suppressed because it is too large
Load Diff
7
src/mo_localization/org/TANGLE_org_mode.sh
Executable file
7
src/mo_localization/org/TANGLE_org_mode.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
list='ls *.org'
|
||||
for element in $list
|
||||
do
|
||||
emacs --batch $element -f org-babel-tangle
|
||||
done
|
28
src/mo_localization/org/break_spatial_sym.org
Normal file
28
src/mo_localization/org/break_spatial_sym.org
Normal file
@ -0,0 +1,28 @@
|
||||
! A small program to break the spatial symmetry of the MOs.
|
||||
|
||||
! You have to defined your MO classes or set security_mo_class to false
|
||||
! with:
|
||||
! qp set orbital_optimization security_mo_class false
|
||||
|
||||
! The default angle for the rotations is too big for this kind of
|
||||
! application, a value between 1e-3 and 1e-6 should break the spatial
|
||||
! symmetry with just a small change in the energy.
|
||||
|
||||
#+BEGIN_SRC f90 :comments org :tangle break_spatial_sym.irp.f
|
||||
program break_spatial_sym
|
||||
|
||||
!BEGIN_DOC
|
||||
! Break the symmetry of the MOs with a rotation
|
||||
!END_DOC
|
||||
|
||||
implicit none
|
||||
|
||||
kick_in_mos = .True.
|
||||
TOUCH kick_in_mos
|
||||
|
||||
call set_classes_loc
|
||||
call apply_pre_rotation
|
||||
call unset_classes_loc
|
||||
|
||||
end
|
||||
#+END_SRC
|
67
src/mo_localization/org/debug_gradient_loc.org
Normal file
67
src/mo_localization/org/debug_gradient_loc.org
Normal file
@ -0,0 +1,67 @@
|
||||
#+BEGIN_SRC f90 :comments org :tangle debug_gradient_loc.irp.f
|
||||
program debug_gradient_loc
|
||||
|
||||
!BEGIN_DOC
|
||||
! Check if the gradient is correct
|
||||
!END_DOC
|
||||
|
||||
implicit none
|
||||
|
||||
integer :: list_size, n
|
||||
integer, allocatable :: list(:)
|
||||
double precision, allocatable :: v_grad(:), v_grad2(:)
|
||||
double precision :: norm, max_elem, threshold, max_error
|
||||
integer :: i, nb_error
|
||||
|
||||
threshold = 1d-12
|
||||
|
||||
list_size = dim_list_act_orb
|
||||
|
||||
allocate(list(list_size))
|
||||
|
||||
list = list_act
|
||||
|
||||
n = list_size*(list_size-1)/2
|
||||
|
||||
allocate(v_grad(n),v_grad2(n))
|
||||
|
||||
if (localization_method == 'boys') then
|
||||
print*,'Foster-Boys'
|
||||
call gradient_FB(n,list_size,list,v_grad,max_elem,norm)
|
||||
call gradient_FB_omp(n,list_size,list,v_grad2,max_elem,norm)
|
||||
elseif (localization_method == 'pipek') then
|
||||
print*,'Pipek-Mezey'
|
||||
call gradient_PM(n,list_size,list,v_grad,max_elem,norm)
|
||||
call gradient_PM(n,list_size,list,v_grad2,max_elem,norm)
|
||||
else
|
||||
print*,'Unknown localization_method, please select boys or pipek'
|
||||
call abort
|
||||
endif
|
||||
|
||||
do i = 1, n
|
||||
print*,i,v_grad(i)
|
||||
enddo
|
||||
|
||||
v_grad = v_grad - v_grad2
|
||||
|
||||
nb_error = 0
|
||||
max_elem = 0d0
|
||||
|
||||
do i = 1, n
|
||||
if (dabs(v_grad(i)) > threshold) then
|
||||
print*,v_grad(i)
|
||||
nb_error = nb_error + 1
|
||||
if (dabs(v_grad(i)) > max_elem) then
|
||||
max_elem = v_grad(i)
|
||||
endif
|
||||
endif
|
||||
enddo
|
||||
|
||||
print*,'Threshold error', threshold
|
||||
print*, 'Nb error', nb_error
|
||||
print*,'Max error', max_elem
|
||||
|
||||
deallocate(v_grad,v_grad2)
|
||||
|
||||
end
|
||||
#+END_SRC
|
67
src/mo_localization/org/debug_hessian_loc.org
Normal file
67
src/mo_localization/org/debug_hessian_loc.org
Normal file
@ -0,0 +1,67 @@
|
||||
#+BEGIN_SRC f90 :comments org :tangle debug_hessian_loc.irp.f
|
||||
program debug_hessian_loc
|
||||
|
||||
!BEGIN_DOC
|
||||
! Check if the hessian is correct
|
||||
!END_DOC
|
||||
|
||||
implicit none
|
||||
|
||||
integer :: list_size, n
|
||||
integer, allocatable :: list(:)
|
||||
double precision, allocatable :: H(:), H2(:)
|
||||
double precision :: threshold, max_error, max_elem
|
||||
integer :: i, nb_error
|
||||
|
||||
threshold = 1d-12
|
||||
|
||||
list_size = dim_list_act_orb
|
||||
|
||||
allocate(list(list_size))
|
||||
|
||||
list = list_act
|
||||
|
||||
n = list_size*(list_size-1)/2
|
||||
|
||||
allocate(H(n),H2(n))
|
||||
|
||||
if (localization_method == 'boys') then
|
||||
print*,'Foster-Boys'
|
||||
call hessian_FB(n,list_size,list,H)
|
||||
call hessian_FB_omp(n,list_size,list,H2)
|
||||
elseif(localization_method == 'pipek') then
|
||||
print*,'Pipek-Mezey'
|
||||
call hessian_PM(n,list_size,list,H)
|
||||
call hessian_PM(n,list_size,list,H2)
|
||||
else
|
||||
print*,'Unknown localization_method, please select boys or pipek'
|
||||
call abort
|
||||
endif
|
||||
|
||||
do i = 1, n
|
||||
print*,i,H(i)
|
||||
enddo
|
||||
|
||||
H = H - H2
|
||||
|
||||
nb_error = 0
|
||||
max_elem = 0d0
|
||||
|
||||
do i = 1, n
|
||||
if (dabs(H(i)) > threshold) then
|
||||
print*,H(i)
|
||||
nb_error = nb_error + 1
|
||||
if (dabs(H(i)) > max_elem) then
|
||||
max_elem = H(i)
|
||||
endif
|
||||
endif
|
||||
enddo
|
||||
|
||||
print*,'Threshold error', threshold
|
||||
print*, 'Nb error', nb_error
|
||||
print*,'Max error', max_elem
|
||||
|
||||
deallocate(H,H2)
|
||||
|
||||
end
|
||||
#+END_SRC
|
18
src/mo_localization/org/kick_the_mos.org
Normal file
18
src/mo_localization/org/kick_the_mos.org
Normal file
@ -0,0 +1,18 @@
|
||||
#+BEGIN_SRC f90 :comments org :tangle kick_the_mos.irp.f
|
||||
program kick_the_mos
|
||||
|
||||
!BEGIN_DOC
|
||||
! To do a small rotation of the MOs
|
||||
!END_DOC
|
||||
|
||||
implicit none
|
||||
|
||||
kick_in_mos = .True.
|
||||
TOUCH kick_in_mos
|
||||
|
||||
call set_classes_loc
|
||||
call apply_pre_rotation
|
||||
call unset_classes_loc
|
||||
|
||||
end
|
||||
#+END_SRC
|
2899
src/mo_localization/org/localization.org
Normal file
2899
src/mo_localization/org/localization.org
Normal file
File diff suppressed because it is too large
Load Diff
62
src/mo_optimization/83.mo_optimization.bats
Normal file
62
src/mo_optimization/83.mo_optimization.bats
Normal file
@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
source $QP_ROOT/tests/bats/common.bats.sh
|
||||
source $QP_ROOT/quantum_package.rc
|
||||
|
||||
|
||||
function run() {
|
||||
thresh=2e-3
|
||||
test_exe scf || skip
|
||||
qp set_file $1
|
||||
qp edit --check
|
||||
qp reset -a
|
||||
qp run scf
|
||||
qp set_frozen_core
|
||||
qp set determinants n_states 2
|
||||
qp set determinants read_wf true
|
||||
qp set mo_two_e_ints io_mo_two_e_integrals None
|
||||
file="$(echo $1 | sed 's/.ezfio//g')"
|
||||
qp run cis
|
||||
qp run debug_gradient_list_opt > $file.debug_g.out
|
||||
err3="$(grep 'Max error:' $file.debug_g.out | awk '{print $3}')"
|
||||
qp run debug_hessian_list_opt > $file.debug_h1.out
|
||||
err1="$(grep 'Max error:' $file.debug_h1.out | awk '{print $3}')"
|
||||
qp run orb_opt > $file.opt1.out
|
||||
energy1="$(grep 'State average energy:' $file.opt1.out | tail -n 1 | awk '{print $4}')"
|
||||
qp set orbital_optimization optimization_method diag
|
||||
qp reset -d
|
||||
qp run scf
|
||||
qp run cis
|
||||
qp run debug_hessian_list_opt > $file.debug_h2.out
|
||||
err2="$(grep 'Max error_H:' $file.debug_h2.out | awk '{print $3}')"
|
||||
qp run orb_opt > $file.opt2.out
|
||||
energy2="$(grep 'State average energy:' $file.opt2.out | tail -n 1 | awk '{print $4}')"
|
||||
qp set orbital_optimization optimization_method full
|
||||
qp reset -d
|
||||
qp run scf
|
||||
eq $energy1 $2 $thresh
|
||||
eq $energy2 $3 $thresh
|
||||
eq $err1 0.0 1e-12
|
||||
eq $err2 0.0 1e-12
|
||||
eq $err3 0.0 1e-12
|
||||
}
|
||||
|
||||
@test "b2_stretched" {
|
||||
run b2_stretched.ezfio -48.9852901484277 -48.9852937541510
|
||||
}
|
||||
|
||||
@test "h2o" {
|
||||
run h2o.ezfio -75.9025622449206 -75.8691844585879
|
||||
}
|
||||
|
||||
@test "h2s" {
|
||||
run h2s.ezfio -398.576255809878 -398.574145943928
|
||||
}
|
||||
|
||||
@test "hbo" {
|
||||
run hbo.ezfio -99.9234823022109 -99.9234763597840
|
||||
}
|
||||
|
||||
@test "hco" {
|
||||
run hco.ezfio -113.204915552241 -113.204905207050
|
||||
}
|
23
src/mo_optimization/EZFIO.cfg
Normal file
23
src/mo_optimization/EZFIO.cfg
Normal file
@ -0,0 +1,23 @@
|
||||
[optimization_method]
|
||||
type: character*(32)
|
||||
doc: Define the kind of hessian for the orbital optimization full : full hessian, diag : diagonal hessian, none : no hessian
|
||||
interface: ezfio,provider,ocaml
|
||||
default: full
|
||||
|
||||
[n_det_max_opt]
|
||||
type: integer
|
||||
doc: Maximal number of the determinants in the wf for the orbital optimization (to stop the optimization if n_det > n_det_max_opt)
|
||||
interface: ezfio,provider,ocaml
|
||||
default: 200000
|
||||
|
||||
[optimization_max_nb_iter]
|
||||
type: integer
|
||||
doc: Maximal number of iterations for the orbital optimization
|
||||
interface: ezfio,provider,ocaml
|
||||
default: 20
|
||||
|
||||
[thresh_opt_max_elem_grad]
|
||||
type: double precision
|
||||
doc: Threshold for the convergence, the optimization exits when the biggest element in the gradient is smaller than thresh_optimization_max_elem_grad
|
||||
interface: ezfio,provider,ocaml
|
||||
default: 1.e-5
|
7
src/mo_optimization/NEED
Normal file
7
src/mo_optimization/NEED
Normal file
@ -0,0 +1,7 @@
|
||||
two_body_rdm
|
||||
hartree_fock
|
||||
cipsi
|
||||
davidson_undressed
|
||||
selectors_full
|
||||
generators_full
|
||||
utils_trust_region
|
74
src/mo_optimization/README.md
Normal file
74
src/mo_optimization/README.md
Normal file
@ -0,0 +1,74 @@
|
||||
# Orbital optimization
|
||||
|
||||
## Methods
|
||||
Different methods are available:
|
||||
- full hessian
|
||||
```
|
||||
qp set orbital_optimization optimization_method full
|
||||
```
|
||||
- diagonal hessian
|
||||
```
|
||||
qp set orbital_optimization optimization_method diag
|
||||
```
|
||||
- identity matrix
|
||||
```
|
||||
qp set orbital_optimization optimization_method none
|
||||
```
|
||||
|
||||
After the optimization the ezfio contains the optimized orbitals
|
||||
|
||||
## For a fixed number of determinants
|
||||
To optimize the MOs for the actual determinants:
|
||||
```
|
||||
qp run orb_opt
|
||||
```
|
||||
|
||||
## For a complete optimization, i.e, with a larger and larger wave function
|
||||
To optimize the MOs with a larger and larger wave function:
|
||||
```
|
||||
qp run optimization
|
||||
```
|
||||
|
||||
The results are stored in the EZFIO in "mo_optimization/result_opt",
|
||||
with the following format:
|
||||
(1) (2) (3) (4)
|
||||
1: Number of determinants in the wf,
|
||||
2: Cispi energy before the optimization,
|
||||
3: Cipsi energy after the optimization,
|
||||
4: Energy difference between (2) and (3).
|
||||
|
||||
The optimization process if the following:
|
||||
- we do a first cipsi step to obtain a small number of determinants in the wf
|
||||
- we run an orbital optimization for this wf
|
||||
- we do a new cipsi step to double the number of determinants in the wf
|
||||
- we run an orbital optimization for this wf
|
||||
- ...
|
||||
- we do that until the energy difference between (2) and (3) is
|
||||
smaller than the targeted accuracy for the cispi (targeted_accuracy_cipsi in qp edit)
|
||||
or the wf is larger than a given size (n_det_max_opt in qp_edit)
|
||||
- after that you can reset your determinants (qp reset -d) and run a clean Cispi calculation
|
||||
|
||||
### End of the optimization
|
||||
You can choos the number of determinants after what the
|
||||
optimization will stop:
|
||||
```
|
||||
qp set orbital_optimization n_det_max_opt 1e5 # or any number
|
||||
```
|
||||
## Weight of the states
|
||||
You can change the weights of the differents states directly in qp edit.
|
||||
It will affect ths weights used in the orbital optimization.
|
||||
|
||||
# Tests
|
||||
To run the tests:
|
||||
```
|
||||
qp test
|
||||
```
|
||||
|
||||
# Org files
|
||||
The org files are stored in the directory org in order to avoid overwriting on user changes.
|
||||
The org files can be modified, to export the change to the source code, run
|
||||
```
|
||||
./TANGLE_org_mode.sh
|
||||
mv *.irp.f ../.
|
||||
```
|
||||
|
12
src/mo_optimization/class.irp.f
Normal file
12
src/mo_optimization/class.irp.f
Normal file
@ -0,0 +1,12 @@
|
||||
BEGIN_PROVIDER [ logical, do_only_1h1p ]
|
||||
&BEGIN_PROVIDER [ logical, do_only_cas ]
|
||||
&BEGIN_PROVIDER [ logical, do_ddci ]
|
||||
implicit none
|
||||
BEGIN_DOC
|
||||
! In the FCI case, all those are always false
|
||||
END_DOC
|
||||
do_only_1h1p = .False.
|
||||
do_only_cas = .False.
|
||||
do_ddci = .False.
|
||||
END_PROVIDER
|
||||
|
1
src/mo_optimization/constants.h
Normal file
1
src/mo_optimization/constants.h
Normal file
@ -0,0 +1 @@
|
||||
logical, parameter :: debug=.False.
|
78
src/mo_optimization/debug_gradient_list_opt.irp.f
Normal file
78
src/mo_optimization/debug_gradient_list_opt.irp.f
Normal file
@ -0,0 +1,78 @@
|
||||
! Debug the gradient
|
||||
|
||||
! *Program to check the gradient*
|
||||
|
||||
! The program compares the result of the first and last code for the
|
||||
! gradient.
|
||||
|
||||
! Provided:
|
||||
! | mo_num | integer | number of MOs |
|
||||
|
||||
! Internal:
|
||||
! | n | integer | number of orbitals pairs (p,q) p<q |
|
||||
! | v_grad(n) | double precision | Original gradient |
|
||||
! | v_grad2(n) | double precision | Gradient |
|
||||
! | i | integer | index |
|
||||
! | threshold | double precision | threshold for the errors |
|
||||
! | max_error | double precision | maximal error in the gradient |
|
||||
! | nb_error | integer | number of error in the gradient |
|
||||
|
||||
|
||||
program debug_gradient_list
|
||||
|
||||
implicit none
|
||||
|
||||
! Variables
|
||||
|
||||
double precision, allocatable :: v_grad(:), v_grad2(:)
|
||||
integer :: n,m
|
||||
integer :: i
|
||||
double precision :: threshold
|
||||
double precision :: max_error, max_elem, norm
|
||||
integer :: nb_error
|
||||
|
||||
m = dim_list_act_orb
|
||||
! Definition of n
|
||||
n = m*(m-1)/2
|
||||
|
||||
PROVIDE mo_two_e_integrals_in_map ! Vérifier pour suppression
|
||||
|
||||
! Allocation
|
||||
allocate(v_grad(n), v_grad2(n))
|
||||
|
||||