diff --git a/.gitignore b/.gitignore index 970fc12..ef95009 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,7 @@ *.o *.mod .vscode -cMaponiA3_test* -fMaponiA3_test* -QMCChem_dataset_test Slater* Updates* -tests/test datasets/datasets.* +bin/ diff --git a/Makefile b/Makefile index 271570a..147c26e 100644 --- a/Makefile +++ b/Makefile @@ -1,49 +1,36 @@ -SRC_DIR := src -INC_DIR := include -OBJ_DIR := build -BIN_DIR := bin - -## Used compilers +## Compilers ARCH = -xCORE-AVX2 H5CXX = h5c++ CXX = icpc FC = ifort -## Compiler flags & common obs & libs +## Compiler flags H5CXXFLAGS = -O0 -g CXXFLAGS = -O0 -g -traceback FFLAGS = -O0 -g -traceback -INCLUDE = -I$(INC_DIR) + +INCLUDE = -I $(INC_DIR)/ +DEPS_CXX = $(OBJ_DIR)/SM_MaponiA3.o +DEPS_F = $(DEPS_CXX) $(OBJ_DIR)/SM_MaponiA3_mod.o $(OBJ_DIR)/Helpers_mod.o FLIBS = -lstdc++ -## Deps & objs for C++ cMaponiA3_test_3x3_3 -OBJS = $(OBJ_DIR)/SM_MaponiA3.o -cMaponiA3_test_3x3_3OBJ = cMaponiA3_test_3x3_3.o -fMaponiA3_test_3x3_3OBJ = SM_MaponiA3_mod.o fMaponiA3_test_3x3_3.o -fMaponiA3_test_4x4_2OBJ = Helpers_mod.o SM_MaponiA3_mod.o fMaponiA3_test_4x4_2.o -QMCChem_dataset_testOBJ = Helpers_mod.o SM_MaponiA3_mod.o QMCChem_dataset_test.o - - -## Default build target: build everything -all: cMaponiA3_test_3x3_3 fMaponiA3_test_3x3_3 fMaponiA3_test_4x4_2 QMCChem_dataset_test tests/test - - -## Compile recipes for C++ -$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp | $(OBJ_DIR) - $(CXX) $(ARCH) $(CXXFLAGS) $(INCLUDE) -c -o $@ $< - -## Compile recepies for Fortran -$(OBJ_DIR)/%.o: $(SRC_DIR)/%.f90 | $(OBJ_DIR) - $(FC) $(ARCH) $(FFLAGS) -c -o $@ $< - -## Explicit recipe to trigger rebuild and relinking when headerfile is changed -$(OBJ_DIR)/SM_MaponiA3.o: $(SRC_DIR)/SM_MaponiA3.cpp $(INC_DIR)/Helpers.hpp| $(OBJ_DIR) - $(CXX) $(ARCH) $(CXXFLAGS) $(INCLUDE) -fPIC -c -o $@ $< +SRC_DIR := src +TST_DIR := tests +INC_DIR := include +OBJ_DIR := build +BIN_DIR := bin +EXEC := $(BIN_DIR)/cMaponiA3_test_3x3_3 \ + $(BIN_DIR)/test_h5 \ + $(BIN_DIR)/fMaponiA3_test_3x3_3 \ + $(BIN_DIR)/fMaponiA3_test_4x4_2 \ + $(BIN_DIR)/QMCChem_dataset_test ## Build tagets .PHONY: all clean distclean +all: $(EXEC) + clean: @rm -vrf $(OBJ_DIR) @@ -52,22 +39,46 @@ distclean: clean Slater* Updates.dat -## Linking the C++ example program -$(BIN_DIR)/cMaponiA3_test_3x3_3: $(OBJ_DIR)/$(cMaponiA3_test_3x3_3OBJ) $(OBJS) | $(BIN_DIR) - $(CXX) $(ARCH) $(CXXFLAGS) $(INCLUDE) -o $@ $^ - -## Linking Fortran example program calling the C++ function -$(BIN_DIR)/fMaponiA3_test_3x3_3: $(OBJ_DIR)/$(fMaponiA3_test_3x3_3OBJ) $(OBJS) | $(BIN_DIR) - $(FC) $(ARCH) $(FFLAGS) $(FLIBS) -o $@ $^ - -$(BIN_DIR)/fMaponiA3_test_4x4_2: $(OBJ_DIR)/$(fMaponiA3_test_4x4_2OBJ) $(OBJS) | $(BIN_DIR) - $(FC) $(ARCH) $(FFLAGS) $(FLIBS) -o $@ $^ - -$(BIN_DIR)/QMCChem_dataset_test: $(OBJ_DIR)/$(QMCChem_dataset_testOBJ) $(OBJS) | $(BIN_DIR) - $(FC) $(ARCH) $(FFLAGS) $(FLIBS) -o $@ $^ - -$(BIN_DIR)/test: $(SRC_DIR)/test.cpp $(OBJS) | $(BIN_DIR) - $(H5CXX) $(H5CXXFLAGS) $(INCLUDE) -o $@ $^ - +#### COMPILING $(BIN_DIR) $(OBJ_DIR): mkdir -p $@ + +### IMPLICIT BUILD RULES +## C++ objects +$(OBJ_DIR)/%.o: $(TST_DIR)/%.cpp $(INC_DIR)/* | $(OBJ_DIR) + $(CXX) $(CXXFLAGS) $(ARCH) $(INCLUDE) -c -o $@ $< + +## HDF5/C++ objects +$(OBJ_DIR)/%_h5.o: $(TST_DIR)/%_h5.cpp $(INC_DIR)/* | $(OBJ_DIR) + $(H5CXX) $(H5CXXFLAGS) $(INCLUDE) -c -o $@ $< + +## Fortran modules +$(OBJ_DIR)/%_mod.o: $(SRC_DIR)/%_mod.f90 | $(OBJ_DIR) + $(FC) $(FFLAGS) $(ARCH) -module $(OBJ_DIR)/ -c -o $@ $< + +## Fortran objects +$(OBJ_DIR)/%.o: $(TST_DIR)/%.f90 | $(OBJ_DIR) + $(FC) $(FFLAGS) $(ARCH) -I $(OBJ_DIR)/ -c -o $@ $< + +### EXPLICIT BUILD RULES +## special compiler flag -fPIC otherwise h5c++ builds fail +$(OBJ_DIR)/SM_MaponiA3.o: $(SRC_DIR)/SM_MaponiA3.cpp $(INC_DIR)/* | $(OBJ_DIR) + $(CXX) $(CXXFLAGS) -fPIC $(ARCH) $(INCLUDE) -c -o $@ $< + + + +#### LINKING +$(BIN_DIR)/cMaponiA3_test_3x3_3: $(OBJ_DIR)/cMaponiA3_test_3x3_3.o $(DEPS_CXX) | $(BIN_DIR) + $(CXX) -o $@ $^ + +$(BIN_DIR)/test_h5: $(OBJ_DIR)/test_h5.o $(DEPS_CXX) | $(BIN_DIR) + $(H5CXX) -o $@ $^ + +$(BIN_DIR)/fMaponiA3_test_3x3_3: $(DEPS_F) $(OBJ_DIR)/fMaponiA3_test_3x3_3.o | $(BIN_DIR) + $(FC) $(FLIBS) -o $@ $^ + +$(BIN_DIR)/fMaponiA3_test_4x4_2: $(DEPS_F) $(OBJ_DIR)/fMaponiA3_test_4x4_2.o | $(BIN_DIR) + $(FC) $(FLIBS) -o $@ $^ + +$(BIN_DIR)/QMCChem_dataset_test: $(DEPS_F) $(OBJ_DIR)/QMCChem_dataset_test.o | $(BIN_DIR) + $(FC) $(FLIBS) -o $@ $^ diff --git a/build.sh b/build.sh deleted file mode 100755 index f4c7e12..0000000 --- a/build.sh +++ /dev/null @@ -1,36 +0,0 @@ - - -mkdir build/ bin/ - -## compile tests/test.cpp -icpc -O0 -fPIC -c src/SM_MaponiA3.cpp -o build/SM_MaponiA3.o -I include/ - -## compile tests/fMaponiA3_test_3x3_3.f90 -ifort -c src/SM_MaponiA3_mod.f90 -o build/SM_MaponiA3_mod.o -module build -ifort -c tests/fMaponiA3_test_3x3_3.f90 -o build/fMaponiA3_test_3x3_3.o -I build/ -## link bin/QMCChem_dataset_test -ifort -o bin/fMaponiA3_test_3x3_3 build/fMaponiA3_test_3x3_3.o build/SM_MaponiA3_mod.o build/SM_MaponiA3.o -lstdc++ - -## compile tests/fMaponiA3_test_4x4_2.f90 -ifort -c src/SM_MaponiA3_mod.f90 -o build/SM_MaponiA3_mod.o -module build -ifort -c src/Helpers_mod.f90 -o build/Helpers_mod.o -module build -ifort -c tests/fMaponiA3_test_4x4_2.f90 -o build/fMaponiA3_test_4x4_2.o -I build/ -## link bin/QMCChem_dataset_test -ifort -o bin/fMaponiA3_test_4x4_2 build/fMaponiA3_test_4x4_2.o build/SM_MaponiA3_mod.o build/Helpers_mod.o build/SM_MaponiA3.o -lstdc++ - -## compile tests/QMCChem_dataset_test.f90 -ifort -c src/SM_MaponiA3_mod.f90 -o build/SM_MaponiA3_mod.o -module build -ifort -c src/Helpers_mod.f90 -o build/Helpers_mod.o -module build -ifort -c tests/QMCChem_dataset_test.f90 -o build/QMCChem_dataset_test.o -I build/ -## link bin/QMCChem_dataset_test -ifort -o bin/QMCChem_dataset_test build/QMCChem_dataset_test.o build/SM_MaponiA3_mod.o build/Helpers_mod.o build/SM_MaponiA3.o -lstdc++ - -## compile tests/test.cpp -h5c++ -c tests/test.cpp -o build/test.o -I include/ -## link bin/test -h5c++ -o bin/test build/test.o build/SM_MaponiA3.o - -## compile tests/cMaponiA3_test_3x3_3.cpp -icpc -c tests/cMaponiA3_test_3x3_3.cpp -o build/cMaponiA3_test_3x3_3.o -I include/ -## link bin/cMaponiA3_test_3x3_3 -icpc -o bin/cMaponiA3_test_3x3_3 build/cMaponiA3_test_3x3_3.o build/SM_MaponiA3.o diff --git a/tests/cMaponiA3_test_3x3_3.cpp b/tests/cMaponiA3_test_3x3_3.cpp new file mode 100644 index 0000000..525d15d --- /dev/null +++ b/tests/cMaponiA3_test_3x3_3.cpp @@ -0,0 +1,53 @@ +// main.cpp +#include "SM_MaponiA3.hpp" +#include "Helpers.hpp" + +int main() { + + unsigned int M = 3; // Dimension of the Slater-matrix + unsigned int i, j; // Indices for iterators + + // Declare, allocate all vectors and matrices and fill them with zeros + unsigned int *Ar_index = new unsigned int[M]; + double *A = new double[M*M]; // The matrix to be inverted + double *A0 = new double[M*M]; // A diagonal matrix with the digonal elements of A + double *Ar = new double[M*M]; // The update matrix + double *A0_inv = new double[M*M]; // The inverse + + // Fill with zeros + for (i = 0; i < M; i++) { + for (j = 0; j < M; j++) { + A0[i*M+j] = 0; + Ar[i*M+j] = 0; + A0_inv[i*M+j] = 0; + } + } + + // Initialize A with M=3 and fill acc. to Eq. (17) from paper + A[0] = 1; A[3] = 1; A[6] = -1; + A[1] = 1; A[4] = 1; A[7] = 0; + A[2] = -1; A[5] = 0; A[8] = -1; + + showMatrix(A, M, "A"); + + // Initialize the diagonal matrix A0, + // the inverse of A0_inv of diagonal matrix A0_inv + // and the update matrix Ar + for (i = 0; i < M; i++) { + A0[i*M + i] = A[i*M + i]; + A0_inv[i*M + i] = 1.0/A[i*M + i]; + Ar_index[i] = i+1; // ! First column needs to start with 1 ! + for (j = 0; j < M; j++) { + Ar[i*M + j] = A[i*M + j] - A0[i*M + j]; + } + } + + // Define pointers dim and n_updates to use in Sherman-Morrison(...) function call + MaponiA3(A0_inv, M, M, Ar, Ar_index); + showMatrix(A0_inv, M, "A0_inv"); + + // Deallocate all vectors and matrices + delete [] A, A0, A0_inv, Ar, Ar_index; + + return 0; +} diff --git a/tests/fMaponiA3_test_3x3_3.f90 b/tests/fMaponiA3_test_3x3_3.f90 new file mode 100644 index 0000000..bbc921c --- /dev/null +++ b/tests/fMaponiA3_test_3x3_3.f90 @@ -0,0 +1,59 @@ +program Interface_test + use Sherman_Morrison + implicit none + + integer i, j !! Iterators + integer(c_int) :: Dim, N_updates + integer(c_int), dimension(:), allocatable :: Updates_index + real(c_double), dimension(:,:), allocatable :: A, S, Updates + real(c_double), dimension(:,:), allocatable :: S_inv + + Dim = 3 + N_updates = 3 + allocate(Updates_index(Dim), A(Dim,Dim), S(Dim,Dim), Updates(Dim,Dim), S_inv(Dim,Dim)) + + !! Initialize A with M=3 and fill acc. to Eq. (17) from paper + A(1,1) = 1.0d0 + A(1,2) = 1.0d0 + A(1,3) = -1.0d0 + A(2,1) = 1.0d0 + A(2,2) = 1.0d0 + A(2,3) = 0.0d0 + A(3,1) = -1.0d0 + A(3,2) = 0.0d0 + A(3,3) = -1.0d0 + + do i=1,Dim + do j=1,Dim + write(*,"(F3.0,3X)", advance="no") A(i,j) + end do + write(*,*) + end do + write(*,*) + + !! Prepare the diagonal matrix S and the update matrix Updates + do i=1,Dim + Updates_index(i) = i + do j=1,Dim + if (i == j) then + S(i,j) = A(i,j) + S_inv(i,j) = 1.0d0 / S(i,j) + else + S(i,j) = 0.0d0 + S_inv(i,j) = 0.0d0 + end if + Updates(i,j) = A(i,j) - S(i,j) + end do + end do + + call MaponiA3(S_inv, Dim, N_updates, Updates, Updates_index) + + do i=1,Dim + do j=1,Dim + write(*,"(F3.0,3X)", advance="no") S_inv(i,j) + end do + write(*,*) + end do + + deallocate(Updates_index, A, S, Updates, S_inv) +end program diff --git a/tests/fMaponiA3_test_4x4_2.f90 b/tests/fMaponiA3_test_4x4_2.f90 new file mode 100644 index 0000000..863b87b --- /dev/null +++ b/tests/fMaponiA3_test_4x4_2.f90 @@ -0,0 +1,151 @@ +program Interface_test + use Sherman_Morrison + use Helpers + implicit none + + integer i, j, col !! Iterators + integer(c_int) :: Dim, N_updates + integer(c_int), dimension(:), allocatable :: Updates_index + real(c_double), dimension(:,:), allocatable :: S, A, Updates + real(c_double), dimension(:,:), allocatable :: S_inv, S_inv_t, A_inv + + Dim = 4 + N_updates = 2 + allocate( S(Dim,Dim), S_inv(Dim,Dim), S_inv_t(Dim,Dim), A(Dim,Dim), A_inv(Dim,Dim), & + Updates(Dim,N_updates), Updates_index(N_updates)) + + !! Initialize S, S_inv, A and A_inv + S(1,1) = 1.0d0 + S(1,2) = 0.0d0 + S(1,3) = 1.0d0 + S(1,4) = -1.0d0 + S(2,1) = 0.0d0 + S(2,2) = 1.0d0 + S(2,3) = 1.0d0 + S(2,4) = 0.0d0 + S(3,1) = -1.0d0 + S(3,2) = 0.0d0 + S(3,3) = -1.0d0 + S(3,4) = 0.0d0 + S(4,1) = 1.0d0 + S(4,2) = 1.0d0 + S(4,3) = 1.0d0 + S(4,4) = 1.0d0 + + S_inv(1,1) = 1.0d0 + S_inv(1,2) = -1.0d0 + S_inv(1,3) = 1.0d0 + S_inv(1,4) = 1.0d0 + S_inv(2,1) = 1.0d0 + S_inv(2,2) = 0.0d0 + S_inv(2,3) = 2.0d0 + S_inv(2,4) = 1.0d0 + S_inv(3,1) = -1.0d0 + S_inv(3,2) = 1.0d0 + S_inv(3,3) = -2.0d0 + S_inv(3,4) = -1.0d0 + S_inv(4,1) = -1.0d0 + S_inv(4,2) = 0.0d0 + S_inv(4,3) = -1.0d0 + S_inv(4,4) = 0.0d0 + + A(1,1) = 1.0d0 + A(1,2) = 0.0d0 + A(1,3) = 1.0d0 + A(1,4) = -1.0d0 + A(2,1) = 0.0d0 + A(2,2) = -1.0d0 + A(2,3) = 1.0d0 + A(2,4) = -1.0d0 + A(3,1) = -1.0d0 + A(3,2) = 0.0d0 + A(3,3) = -1.0d0 + A(3,4) = 0.0d0 + A(4,1) = 1.0d0 + A(4,2) = 1.0d0 + A(4,3) = 1.0d0 + A(4,4) = 1.0d0 + + A_inv(1,1) = 0.0d0 + A_inv(1,2) = -1.0d0 + A_inv(1,3) = -2.0d0 + A_inv(1,4) = -1.0d0 + A_inv(2,1) = 1.0d0 + A_inv(2,2) = 0.0d0 + A_inv(2,3) = 2.0d0 + A_inv(2,4) = 1.0d0 + A_inv(3,1) = 0.0d0 + A_inv(3,2) = 1.0d0 + A_inv(3,3) = 1.0d0 + A_inv(3,4) = 1.0d0 + A_inv(4,1) = -1.0d0 + A_inv(4,2) = 0.0d0 + A_inv(4,3) = -1.0d0 + A_inv(4,4) = 0.0d0 + + !! Prepare Updates and Updates_index + Updates(1,1) = 0 + Updates(1,2) = 0 + Updates(2,1) = -2 + Updates(2,2) = -1 + Updates(3,1) = 0 + Updates(3,2) = 0 + Updates(4,1) = 0 + Updates(4,2) = 0 + + Updates_index(1) = 2 + Updates_index(2) = 4 + + !! Write current S and S_inv to file for check in Octave + open(unit = 2000, file = "Slater_old.dat") + open(unit = 3000, file = "Slater_old_inv.dat") + do i=1,dim + do j=1,dim + write(2000,"(E23.15, 1X)", advance="no") S(i,j) + write(3000,"(E23.15, 1X)", advance="no") S_inv(i,j) + end do + write(2000,*) + write(3000,*) + end do + close(2000) + close(3000) + + !! Write Updates to file to check + open(unit = 2000, file = "Updates.dat") + do i=1,dim + do j=1,n_updates + write(2000,"(E23.15, 1X)", advance="no") Updates(i,j) + end do + write(2000,*) + end do + close(2000) + + !! Update S + do i=1,N_updates + do j=1,Dim + col = Updates_index(i) + S(j,col) = S(j,col) + Updates(j,i) + end do + end do + + !! Update S_inv + call Transpose(S_inv, S_inv_t, Dim) + call MaponiA3(S_inv_t, Dim, N_updates, Updates, Updates_index) + call Transpose(S_inv_t, S_inv, Dim) + + !! Write new S and S_inv to file for check in Octave + open(unit = 4000, file = "Slater.dat") + open(unit = 5000, file = "Slater_inv.dat") + do i=1,dim + do j=1,dim + write(4000,"(E23.15, 1X)", advance="no") S(i,j) + write(5000,"(E23.15, 1X)", advance="no") S_inv(i,j) + end do + write(4000,*) + write(5000,*) + end do + close(4000) + close(5000) + + deallocate(Updates_index, A, A_inv, S, Updates, S_inv) +end program diff --git a/tests/test.cpp b/tests/test_h5.cpp similarity index 100% rename from tests/test.cpp rename to tests/test_h5.cpp