Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

generate multiple ciroots restart file #186

Merged
merged 7 commits into from
Jan 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 69 additions & 16 deletions src/module_restart_file.f90
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ module dcaspt2_restart_file

use module_error, only: stop_with_errorcode
use module_file_manager, only: open_formatted_file, check_iostat
use module_global_variables, only: rank, enable_restart, sumc2, sumc2_subspace, e2all, e2_subspace, next_subspace
use module_global_variables, only: rank, enable_restart, sumc2, sumc2_subspace, e2all, e2_subspace, next_subspace, &
len_convert_int_to_chr, totsym, selectroot
implicit none

private
character(len=1) :: subspace_list(8) = (/'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'/)
character(len=1) :: subspace_list(9) = (/'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'/) ! I is not a valid subspace, but it is used to skip A-H subspace calc and print the final energy

public :: is_skip_restart_file_subspace, get_subspace_idx, read_and_validate_restart_file
contains
Expand Down Expand Up @@ -43,6 +44,8 @@ function get_subspace_idx(subspace_char)
get_subspace_idx = 7
case ('H')
get_subspace_idx = 8
case ('I')
get_subspace_idx = 9 ! I is not a valid subspace, but it is used to skip A-H subspace calc and print the final energy
case default
if (rank == 0) print *, "Invalid subspace (not A-H), no need to restart CASPT2 calculation"
call stop_with_errorcode(1)
Expand All @@ -53,26 +56,37 @@ subroutine read_and_validate_restart_file
implicit none

character(len=*), parameter :: key_subspace = "Subspace:", key_sumc2 = "Sumc2:", key_energy = "Energy:"
character(len=*), parameter :: restart_file = "caspt2_restart"
character(len=*), parameter :: restart_file_base = "caspt2_restart"
character(:), allocatable :: restart_file
character(len=len_convert_int_to_chr) :: chr_totsym, chr_root
character(len=500) :: buf, buf_internal
character(len=1) :: subspace
real(kind=8) :: read_sumc2, read_energy
integer :: i, idx, file_unit, iostat, subspace_index
integer :: i, idx, file_unit, iostat, subspace_index, totsym_read, selectroot_read
logical :: restart_file_exists, eof, valid_subspace = .false.

write (chr_totsym, *) totsym
write (chr_root, *) selectroot
restart_file = trim(adjustl(restart_file_base))//"_"//trim(adjustl(chr_totsym))//"_"//trim(adjustl(chr_root))
print *, "Restart file: ", restart_file
inquire (file=restart_file, exist=restart_file_exists)
if (.not. restart_file_exists) call error_restart_file("caspt2_restart file does not exist")

call open_formatted_file(file_unit, "caspt2_restart", "old")
read (file_unit, '(A)', iostat=iostat) buf
call check_iostat(iostat, restart_file, eof)
idx = index(buf, ":")
if (idx == 0) call error_restart_file("Error reading next subspace info in caspt2_restart")
read (buf(idx + 1:), '(A)', iostat=iostat) buf_internal
if (iostat /= 0) call error_restart_file("Error reading next subspace info in caspt2_restart")
buf_internal = trim(adjustl(buf_internal))
read (buf_internal, *) next_subspace
subspace_index = get_subspace_idx(next_subspace)
if (.not. restart_file_exists) then
if (rank == 0) print *, restart_file//" does not exist"
return ! No restart file, continue CASPT2 calculation from scratch
end if

call open_formatted_file(file_unit, restart_file, "old")
call read_totsym(totsym_read)
if (totsym_read /= totsym) then
if (rank == 0) print '(2(A,I0,1x))', "totsym = ", totsym, ", restart file totsym = ", totsym_read
call error_restart_file("totsym in "//restart_file//" does not match with the input file")
end if
call read_selectroot(selectroot_read)
if (selectroot_read /= selectroot) then
if (rank == 0) print '(2(A,I0,1x))', "selectroot = ", selectroot, ", restart file selectroot = ", selectroot_read
call error_restart_file("selectroot in "//restart_file//" does not match with the input file")
end if
call read_next_subspace(subspace_index)

do while (.true.)
read (file_unit, '(A)', iostat=iostat) buf
Expand Down Expand Up @@ -111,6 +125,45 @@ subroutine read_and_validate_restart_file
end do

contains
subroutine read_totsym(totsym_ret)
implicit none
integer, intent(out) :: totsym_ret
read (file_unit, '(A)', iostat=iostat) buf
call check_iostat(iostat, restart_file, eof)
idx = index(buf, ":")
if (idx == 0) call error_restart_file("Error reading totsym info in caspt2_restart")
read (buf(idx + 1:), '(A)', iostat=iostat) buf_internal
if (iostat /= 0) call error_restart_file("Error reading totsym info in caspt2_restart")
read (buf_internal, *) totsym_ret ! convert string to integer
end subroutine read_totsym

subroutine read_selectroot(selectroot_ret)
implicit none
integer, intent(out) :: selectroot_ret
read (file_unit, '(A)', iostat=iostat) buf
call check_iostat(iostat, restart_file, eof)
idx = index(buf, ":")
if (idx == 0) call error_restart_file("Error reading selectroot info in caspt2_restart")
read (buf(idx + 1:), '(A)', iostat=iostat) buf_internal
if (iostat /= 0) call error_restart_file("Error reading selectroot info in caspt2_restart")
read (buf_internal, *) selectroot_ret ! convert string to integer
end subroutine read_selectroot

subroutine read_next_subspace(subpsace_idx_ret)
implicit none
integer, intent(out) :: subpsace_idx_ret
read (file_unit, '(A)', iostat=iostat) buf
call check_iostat(iostat, restart_file, eof)
idx = index(buf, ":")
if (idx == 0) call error_restart_file("Error reading next subspace info in caspt2_restart")
read (buf(idx + 1:), '(A)', iostat=iostat) buf_internal
if (iostat /= 0) call error_restart_file("Error reading next subspace info in caspt2_restart")

buf_internal = trim(adjustl(buf_internal))
read (buf_internal, *) next_subspace
subpsace_idx_ret = get_subspace_idx(next_subspace)
end subroutine read_next_subspace

subroutine error_restart_file(error_message)
character(len=*), intent(in) :: error_message
if (rank == 0) print *, error_message
Expand Down
4 changes: 2 additions & 2 deletions src/r4dcaspt2_tra.f90
Original file line number Diff line number Diff line change
Expand Up @@ -379,8 +379,8 @@ subroutine r4dcaspt2_tra ! DO CASPT2 CALC WITH MO TRANSFORMATION
else if (is_skip_restart_file_subspace("G")) then
if (rank == 0) then
print *, "Skip the calculation of G subspace 2nd order energy because of the caspt2_restart file."
print '("e2e = ",E25.15," a.u.")', e2_subspace(cur_subspace_idx)
print '("sumc2,e = ",E25.15)', sumc2_subspace(cur_subspace_idx)
print '("e2g = ",E25.15," a.u.")', e2_subspace(cur_subspace_idx)
print '("sumc2,g = ",E25.15)', sumc2_subspace(cur_subspace_idx)
end if
else
if (rank == 0) print '(64A)', '----------------------------------------------------------------'
Expand Down
2 changes: 1 addition & 1 deletion test/dev/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@
!**/reference*out
!**/reference.DFPCMO*
!**/test*py
!**/caspt2_restart
!**/caspt2_restart*
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
totsym: 33
selectroot: 1
Next subspace: D
Subspace: A Sumc2: 0.000221008073109341 Energy: -0.000417201652514757
Subspace: B Sumc2: 0.00379829088564885 Energy: -0.00719587322489538
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
totsym: 33
selectroot: 1
Next subspace: I
Subspace: A Sumc2: 9.13251375430076e-05 Energy: -0.000245589275314971
Subspace: B Sumc2: 0.000985786712314481 Energy: -0.00193888117085749
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
totsym: 3
selectroot: 1
Next subspace: G
Subspace: A Sumc2: 0.000290176077845299 Energy: -0.000674686208214684
Subspace: B Sumc2: 0.000338022991004886 Energy: -0.000828681042777347
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
totsym: 2
selectroot: 1
Next subspace: I
Subspace: A Sumc2: 1.18745492650451e-08 Energy: -1.8341565541328e-08
Subspace: B Sumc2: 9.73101597556623e-05 Energy: -0.000252379102333566
Subspace: C Sumc2: 3.89922224486996e-05 Energy: -0.000136569356566604
Subspace: D Sumc2: 0.000681765498284919 Energy: -0.0024092126529112
Subspace: E Sumc2: 0.00133896840395821 Energy: -0.00513415984298757
Subspace: F Sumc2: 0.00208341219392722 Energy: -0.00929205851761709
Subspace: G Sumc2: 0.00761383970080123 Energy: -0.0375547863590626
Subspace: H Sumc2: 0.0110952001597402 Energy: -0.0724952047733335
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
totsym: 2
selectroot: 2
Next subspace: G
Subspace: A Sumc2: 0.00114749747320073 Energy: -0.0018245789474798
Subspace: B Sumc2: 5.6989371416954e-10 Energy: -1.09141354947307e-09
Subspace: C Sumc2: 0.0160604167447912 Energy: -0.0203356728115594
Subspace: D Sumc2: 0.0286587956131426 Energy: -0.0458180570006012
Subspace: E Sumc2: 0.0054397827608431 Energy: -0.0169001778170485
Subspace: F Sumc2: 0.000898046678792155 Energy: -0.0019259253958069
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
totsym: 2
selectroot: 1
Next subspace: C
Subspace: A Sumc2: 0.000599100631118297 Energy: -0.00146013144438255
Subspace: B Sumc2: 0.000473007520468982 Energy: -0.00121734629020479
30 changes: 25 additions & 5 deletions test/unit_test/gen_dcapst2_restart/test_gen_dcaspt2_restart.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def test_pass_subspace_a_and_b(env_setup_gen_restart_file) -> None:
subprocess.run(command.split(), check=True)

string_ref = get_split_string_list_from_output_file(expected_path)
string_result = get_split_string_list_from_output_file("caspt2_restart")
string_result = get_split_string_list_from_output_file("caspt2_restart_2_1")

for ref, result in zip(string_ref, string_result):
assert ref == result
Expand All @@ -29,7 +29,7 @@ def test_pass_full_subspaces(env_setup_gen_restart_file) -> None:
subprocess.run(command.split(), check=True)

string_ref = get_split_string_list_from_output_file(expected_path)
string_result = get_split_string_list_from_output_file("caspt2_restart")
string_result = get_split_string_list_from_output_file("caspt2_restart_33_1")

for ref, result in zip(string_ref, string_result):
assert ref == result
Expand All @@ -43,19 +43,39 @@ def test_pass_in_the_middle_subspace_broken(env_setup_gen_restart_file) -> None:
subprocess.run(command.split(), check=True)

string_ref = get_split_string_list_from_output_file(expected_path)
string_result = get_split_string_list_from_output_file("caspt2_restart")
string_result = get_split_string_list_from_output_file("caspt2_restart_3_1")

for ref, result in zip(string_ref, string_result):
assert ref == result


@pytest.mark.dev
def test_fail(env_setup_gen_restart_file) -> None:
def test_pass_multi_ciroots(env_setup_gen_restart_file) -> None:
(gen_restart_path, test_path, input_path, expected_path) = env_setup_gen_restart_file
os.chdir(test_path)
print(f"input_path: {input_path}")
command = f"{gen_restart_path} {input_path}"
subprocess.run(command.split(), check=True)

for trailing_file_str in ["_2_1", "_2_2"]:
string_ref = get_split_string_list_from_output_file(f"{expected_path}{trailing_file_str}")
string_result = get_split_string_list_from_output_file(f"caspt2_restart{trailing_file_str}")

for ref, result in zip(string_ref, string_result):
assert ref == result
# string_ref = get_split_string_list_from_output_file(expected_path)
# string_result = get_split_string_list_from_output_file("caspt2_restart_4_1")

# for ref, result in zip(string_ref, string_result):
# assert ref == result

@pytest.mark.dev
def test_no_output(env_setup_gen_restart_file) -> None:
(gen_restart_path, test_path, input_path, expected_path) = env_setup_gen_restart_file
os.chdir(test_path)
command = f"{gen_restart_path} {input_path}"
p = subprocess.run(command.split(), capture_output=True)
assert p.returncode != 0 and "ValueError" in p.stderr.decode("utf-8")
assert p.returncode == 0 and p.stdout.decode("utf-8") == "" and p.stderr.decode("utf-8") == ""


@pytest.mark.dev
Expand Down
Loading
Loading