diff --git a/src/DiagHamInterface.jl b/src/DiagHamInterface.jl index 4d6e455..a7e83e1 100644 --- a/src/DiagHamInterface.jl +++ b/src/DiagHamInterface.jl @@ -4,6 +4,7 @@ Interface to the DiagHam library. module DiagHamInterface export execute_diagham_script +export install_diagham export read_matrix_from_txt export write_to_txt @@ -17,6 +18,7 @@ using Preferences include("utility/backup.jl") include("utility/diagham_path.jl") include("utility/execute_script.jl") +include("utility/diagham_install.jl") include("utility/fileending.jl") include("utility/numbers.jl") include("utility/standards.jl") diff --git a/src/utility/diagham_install.jl b/src/utility/diagham_install.jl new file mode 100644 index 0000000..3c608dc --- /dev/null +++ b/src/utility/diagham_install.jl @@ -0,0 +1,92 @@ +""" + install_diagham(; source_dir, build_dir=nothing, run_dir=nothing, configure_options=["--enable-fqhe","--enable-fti","--with-blas-libs=-lopenblas","--with-lapack-libs=","--enable-lapack"]) + +Checkout and build DiagHam from source. Returns the path to the build directory. + +Parameters are keyword-only and intended to be easily overridden from tests or user code. +""" +function install_diagham(; + source_dir, + build_dir = nothing, + run_dir = nothing, + configure_options = ["--enable-fqhe", "--enable-fti", "--with-blas-libs=-lopenblas", "--with-lapack-libs=", "--enable-lapack"], + ) + source_dir = expanduser(source_dir) + + isnothing(build_dir) && (build_dir = joinpath(source_dir, "build")) + build_dir = expanduser(build_dir) + !isnothing(run_dir) && (run_dir = expanduser(run_dir)) + + # Check if already built (look for a known executable) + exe_check = joinpath(build_dir, "FQHE", "src", "Programs", "FQHEOnTorus", "FQHETorusFermionsTwoBodyGeneric") + if isdir(build_dir) && isfile(exe_check) + @info "DiagHam already installed at $build_dir" + return build_dir + end + + # Checkout DiagHam + if !isdir(source_dir) + @info "Checking out DiagHam from SVN repository..." + run(`svn checkout "https://www.nick-ux.org/diagham/svn/DiagHam/trunk" $source_dir`) + else + @info "DiagHam source already exists at $source_dir" + end + + !isdir(build_dir) && mkdir(build_dir) + # Check if it uses autotools or cmake + if isfile(joinpath(source_dir, "CMakeLists.txt")) + # CMake-based build + + @info "Configuring DiagHam with CMake..." + cd(build_dir) do + run(`cmake $source_dir -DBUILD_FQHE=ON`) + end + + @info "Building DiagHam..." + cd(build_dir) do + nprocs = Sys.CPU_THREADS + run(`make -j$nprocs`) + end + elseif isfile(joinpath(source_dir, "configure")) + # Autotools-based build (older DiagHam versions) + @info "Configuring DiagHam with autotools..." + + cd(build_dir) do + # Run configure from build dir pointing to source dir with FQHE and LAPACK enabled + configure_script = joinpath(source_dir, "configure") + run(`$configure_script $(configure_options...)`) + + @info "Building DiagHam..." + nprocs = Sys.CPU_THREADS + run(`make -j$nprocs`) + end + elseif isfile(joinpath(source_dir, "configure.in")) || isfile(joinpath(source_dir, "Makefile.am")) + # Need to run autoreconf first + @info "Running autoreconf to generate configure script..." + cd(source_dir) do + run(`autoreconf -i`) + end + + cd(build_dir) do + # Run configure from build dir pointing to source dir with FQHE and LAPACK enabled + configure_script = joinpath(source_dir, "configure") + run(`$configure_script --enable-fqhe --enable-fti --with-blas-libs=-lopenblas --with-lapack-libs= --enable-lapack`) + + @info "Building DiagHam..." + nprocs = Sys.CPU_THREADS + run(`make -j$nprocs`) + end + else + error("Could not determine build system for DiagHam") + end + + !isdir(run_dir) && !isnothing(run_dir) && mkdir(run_dir) + + @info "DiagHam installed successfully at $build_dir" + + if !@has_preference("diagham_path") + set_diagham_path(build_dir) + end + + return build_dir +end diff --git a/test/diagham/setup.jl b/test/diagham/setup.jl index 1b92e85..de42121 100644 --- a/test/diagham/setup.jl +++ b/test/diagham/setup.jl @@ -9,115 +9,38 @@ const DIAGHAM_SOURCE_DIR = joinpath(dirname(@__DIR__), "diagham_source") const DIAGHAM_BUILD_DIR = joinpath(DIAGHAM_SOURCE_DIR, "build") const DIAGHAM_RUN_DIR = joinpath(DIAGHAM_BUILD_DIR, "run") -""" - install_diagham() - -Checkout and build DiagHam from source. Returns the path to the build directory. -""" -function install_diagham() - # Check if already built - if isdir(DIAGHAM_BUILD_DIR) && isfile(joinpath(DIAGHAM_BUILD_DIR, "FQHE", "src", "Programs", "FQHEOnTorus", "FQHETorusFermionsTwoBodyGeneric")) - @info "DiagHam already installed at $DIAGHAM_BUILD_DIR" - return DIAGHAM_BUILD_DIR - end - - # Checkout DiagHam if not exists - if !isdir(DIAGHAM_SOURCE_DIR) - @info "Checking out DiagHam from SVN repository..." - mkdir(dirname(DIAGHAM_SOURCE_DIR)) - run(`svn checkout https://www.nick-ux.org/diagham/svn/DiagHam/trunk $DIAGHAM_SOURCE_DIR`) - else - @info "DiagHam source already exists at $DIAGHAM_SOURCE_DIR" - end - - # Check if it uses autotools or cmake - if isfile(joinpath(DIAGHAM_SOURCE_DIR, "CMakeLists.txt")) - # CMake-based build - if !isdir(DIAGHAM_BUILD_DIR) - mkdir(DIAGHAM_BUILD_DIR) - end +using DiagHamInterface: install_diagham - @info "Configuring DiagHam with CMake..." - cd(DIAGHAM_BUILD_DIR) do - run(`cmake $DIAGHAM_SOURCE_DIR -DBUILD_FQHE=ON`) - end - - @info "Building DiagHam..." - cd(DIAGHAM_BUILD_DIR) do - nprocs = Sys.CPU_THREADS - run(`make -j$nprocs`) - end - elseif isfile(joinpath(DIAGHAM_SOURCE_DIR, "configure")) - # Autotools-based build (older DiagHam versions) - @info "Configuring DiagHam with autotools..." - - if !isdir(DIAGHAM_BUILD_DIR) - mkdir(DIAGHAM_BUILD_DIR) - end - - cd(DIAGHAM_BUILD_DIR) do - # Run configure from build dir pointing to source dir with FQHE and LAPACK enabled - configure_script = joinpath(DIAGHAM_SOURCE_DIR, "configure") - run(`$configure_script --enable-fqhe --enable-fti --with-blas-libs=-lopenblas --with-lapack-libs= --enable-lapack`) - - @info "Building DiagHam..." - nprocs = Sys.CPU_THREADS - run(`make -j$nprocs`) - end - elseif isfile(joinpath(DIAGHAM_SOURCE_DIR, "configure.in")) || isfile(joinpath(DIAGHAM_SOURCE_DIR, "Makefile.am")) - # Need to run autoreconf first - @info "Running autoreconf to generate configure script..." - cd(DIAGHAM_SOURCE_DIR) do - run(`autoreconf -i`) - end - - if !isdir(DIAGHAM_BUILD_DIR) - mkdir(DIAGHAM_BUILD_DIR) - end - - cd(DIAGHAM_BUILD_DIR) do - # Run configure from build dir pointing to source dir with FQHE and LAPACK enabled - configure_script = joinpath(DIAGHAM_SOURCE_DIR, "configure") - run(`$configure_script --enable-fqhe --enable-fti --with-blas-libs=-lopenblas --with-lapack-libs= --enable-lapack`) - - @info "Building DiagHam..." - nprocs = Sys.CPU_THREADS - run(`make -j$nprocs`) - end - else - error("Could not determine build system for DiagHam") - end +# Delegate installation to the exported package function so tests and users +# use the shared implementation. The test constants are still defined here +# for convenience and passed to the package function below. - if !isdir(DIAGHAM_RUN_DIR) - mkdir(DIAGHAM_RUN_DIR) - end - - @info "DiagHam installed successfully at $DIAGHAM_BUILD_DIR" - return DIAGHAM_BUILD_DIR -end - -""" - diagham_available() - -Check if DiagHam is available (built and ready to use). -""" -function diagham_available() - # Check for common FQHE executables +function diagham_available(build_dir::AbstractString = DIAGHAM_BUILD_DIR) possible_paths = [ - joinpath(DIAGHAM_BUILD_DIR, "FQHE", "src", "Programs", "FQHEOnDisk", "FQHEDiskFermionsTwoBodyGeneric"), - joinpath(DIAGHAM_BUILD_DIR, "FQHE", "src", "Programs", "FQHEOnTorus", "FQHETorusFermionsTwoBodyGeneric"), - joinpath(DIAGHAM_BUILD_DIR, "FTI", "src", "Programs", "FTI", "FTIGenericInteractionFromFileTwoBands"), - joinpath(DIAGHAM_BUILD_DIR, "src", "Programs", "GenericHamiltonianDiagonalization"), - joinpath(DIAGHAM_BUILD_DIR, "src", "Programs", "GenericOverlap"), + joinpath(build_dir, "FQHE", "src", "Programs", "FQHEOnDisk", "FQHEDiskFermionsTwoBodyGeneric"), + joinpath(build_dir, "FQHE", "src", "Programs", "FQHEOnTorus", "FQHETorusFermionsTwoBodyGeneric"), + joinpath(build_dir, "FTI", "src", "Programs", "FTI", "FTIGenericInteractionFromFileTwoBands"), + joinpath(build_dir, "src", "Programs", "GenericHamiltonianDiagonalization"), + joinpath(build_dir, "src", "Programs", "GenericOverlap"), ] return any(isfile, possible_paths) end -if !diagham_available() + +""" +Call the package `install_diagham` with the test-local defaults. +""" +function ensure_diagham_installed() + if diagham_available(DIAGHAM_BUILD_DIR) + @info "DiagHam already installed at $DIAGHAM_BUILD_DIR" + return DIAGHAM_BUILD_DIR + end + @info "DiagHam not installed, attempting installation..." try - install_diagham() + install_diagham(; source_dir = DIAGHAM_SOURCE_DIR) catch e @warn "Failed to install DiagHam: $e" end + return DIAGHAM_BUILD_DIR end diff --git a/test/diagham/test_execute_diagham_script.jl b/test/diagham/test_execute_diagham_script.jl index 684b365..09db3e8 100644 --- a/test/diagham/test_execute_diagham_script.jl +++ b/test/diagham/test_execute_diagham_script.jl @@ -7,6 +7,8 @@ using Test include("setup.jl") @testset "execute_diagham_script (requires DiagHam)" begin + + @test ensure_diagham_installed() == DIAGHAM_BUILD_DIR if diagham_available() # Set the DiagHam path for these tests @test DiagHamInterface.set_diagham_path(DIAGHAM_BUILD_DIR) == expanduser(DIAGHAM_BUILD_DIR) diff --git a/test/diagham/test_write_matrix_elements.jl b/test/diagham/test_write_matrix_elements.jl index adbdf61..ed7b487 100644 --- a/test/diagham/test_write_matrix_elements.jl +++ b/test/diagham/test_write_matrix_elements.jl @@ -66,6 +66,8 @@ const TEST_ATOL_COMPLEX = 1.0e-10 # Read back and verify coefficients are preserved header, read_indices, read_coeffs = read_matrix_elements(filename) @test all(isapprox.(read_coeffs, coeffs; atol = TEST_ATOL_REAL)) + @test read_indices == indices + @test label == header end end @@ -97,6 +99,11 @@ const TEST_ATOL_COMPLEX = 1.0e-10 # Check that complex coefficients are preserved @test all(isapprox.(read_coeffs, coeffs; atol = TEST_ATOL_COMPLEX)) + @test read_indices == indices + @test label == header + + header, read_indices, read_coeffs = read_matrix_elements(filename; conjugate = true) + @test all(isapprox.(read_coeffs, conj.(coeffs); atol = TEST_ATOL_COMPLEX)) end end