From 269a9906d039b279655dfb490faff2323551684d Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Fri, 21 Jun 2024 14:25:16 +0100 Subject: [PATCH 001/293] Update ignore list --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 2aac8242..c31e643d 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ bin/ obj/ *.mod DTESTING/ -DTEST/ \ No newline at end of file +DTEST/ +build/ \ No newline at end of file From 53d97c6540aac5479975154f9a70eb6602b7f562 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Fri, 21 Jun 2024 14:25:25 +0100 Subject: [PATCH 002/293] Add file --- CMakeLists.txt | 186 +++++++++++++++++++++++++++++++++++++++++++++++++ src/raffle.f90 | 90 ++++++++++++++++++++++++ 2 files changed, 276 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 src/raffle.f90 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..c4baf665 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,186 @@ +cmake_minimum_required(VERSION 3.17.5) + +# define build environments +set( CMAKE_INSTALL_PREFIX "$ENV{HOME}/.local/raffle" + CACHE STRING "Select where to install the library." ) +execute_process(COMMAND pwd OUTPUT_VARIABLE CURRENT_WORKING_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) +message("Current working directory: ${CURRENT_WORKING_DIR}") +set( CMAKE_BUILD_PREFIX ${CURRENT_WORKING_DIR} + CACHE STRING "Select where to build the library." ) + +# set the project name +project(raffle NONE) + +# set the library name +set( LIB_NAME ${PROJECT_NAME} ) +set( PROJECT_DESCRIPTION + "Fortran neural network" ) +set( PROJECT_URL "https://github.com/nedtaylor/raffle" ) +set( CMAKE_CONFIGURATION_TYPES "Release" "Parallel" "Serial" "Dev" "Debug" "Parallel_Dev" + CACHE STRING "List of configurations types." ) +set( CMAKE_BUILD_TYPE "Release" + CACHE STRING "Select which configuration to build." ) + +# change name based on parallel +if (CMAKE_BUILD_TYPE MATCHES "Parallel*") + project(raffle_omp NONE) # change project name to parallel + message(FATAL_ERROR "Configuration stopped because Parallel is not yet set up") +endif() + +# set compiler +set(CMAKE_Fortran_COMPILER gfortran + CACHE STRING "Select fortran compiler." ) # Change this to your desired compiler +set(CMAKE_Fortran_STANDARD 2018) + +# set language +enable_language(Fortran) + +# set coverage compiler flags +if (CMAKE_BUILD_TYPE MATCHES "Debug*" OR CMAKE_BUILD_TYPE MATCHES "Dev*") + list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") + set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) + if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") + include(CodeCoverage) + setup_target_for_coverage_gcovr_html( + NAME coverage + EXECUTABLE ctest + EXCLUDE "${PROJECT_SOURCE_DIR}/test/*") + endif() +endif() + +# enable testing +enable_testing() + +# set options for building tests and examples +option(BUILD_TESTS "Build the unit tests" ON) +option(BUILD_EXAMPLES "Build the examples" ON) + +# Define the sources +set(SRC_DIR src) +set(LIB_DIR ${SRC_DIR}/lib) + +set(LIB_FILES + mod_constants.f90 + mod_misc.f90 + mod_misc_maths.f90 + mod_misc_linalg.f90 + mod_rw_geom.f90 + mod_rw_vasprun.f90 + mod_edit_geom.f90 + mod_elements.f90 + mod_ml.f90 + mod_evolver.f90 + mod_buildmap.f90 + mod_atom_adder.f90 + mod_read_structures.f90 +) +foreach(lib ${LIB_FILES}) + list(APPEND PREPENDED_LIB_FILES ${LIB_DIR}/${lib}) +endforeach() +message(STATUS "Modified LIB_FILES: ${PREPENDED_LIB_FILES}") + +if (CMAKE_BUILD_TYPE MATCHES "Parallel*") + set(SRC_FILES raffle_omp.f90) +else() + set(SRC_FILES inputs.f90 generator.f90 raffle.f90) +endif() +foreach(src ${SRC_FILES}) + list(APPEND PREPENDED_SRC_FILES ${SRC_DIR}/${src}) +endforeach() +message(STATUS "Modified SRC_FILES: ${PREPENDED_SRC_FILES}") + +# initialise flags +set(CPPFLAGS "") +set(CFLAGS "") +set(MODULEFLAGS "") +set(MPFLAGS "") +set(WARNFLAGS "") +set(DEVFLAGS "") +set(DEBUGFLAGS "") +set(MEMFLAGS "") +set(OPTIMFLAGS "") +set(FASTFLAGS "") + +# set flags based on compiler +if (CMAKE_Fortran_COMPILER MATCHES ".*gfortran.*" OR CMAKE_Fortran_COMPILER MATCHES ".*gcc.*") + message(STATUS "Using gfortran compiler") + set(PPFLAGS -cpp) + set(MPFLAGS -fopenmp) + set(WARNFLAGS -Wall) + set(DEVFLAGS -g -fbacktrace -fcheck=all -fbounds-check -Og) + set(DEBUGFLAGS -fbounds-check) + set(MEMFLAGS -mcmodel=large) + set(OPTIMFLAGS -O3 -march=native) + set(FASTFLAGS -Ofast -march=native) +elseif (CMAKE_Fortran_COMPILER MATCHES ".*nag.*") + message(STATUS "Using nag compiler") + set(PPFLAGS -f2018 -fpp) + set(MPFLAGS -openmp) + set(WARNFLAGS -Wall) + set(DEVFLAGS -g -mtrace -C=all -colour -O0) + set(DEBUGFLAGS -C=array) + set(MEMFLAGS -mcmodel=large) + set(OPTIMFLAGS -O3) + set(FASTFLAGS -Ofast) +elseif (CMAKE_Fortran_COMPILER MATCHES ".*ifort.*" OR CMAKE_Fortran_COMPILER MATCHES ".*ifx.*") + message(STATUS "Using intel compiler") + set(PPFLAGS -fpp) + set(MPFLAGS -qopenmp) + set(WARNFLAGS -warn all) + set(DEVFLAGS -check all -warn) + set(DEBUGFLAGS -check all -fpe0 -warn -tracekback -debug extended) + set(MEMFLAGS -mcmodel=large) + set(OPTIMFLAGS -O3) + set(FASTFLAGS -Ofast) +else() + # Code for other Fortran compilers + message(STATUS "Using a different Fortran compiler") +endif() + + +# Get the user's home directory +set(HOME_DIR $ENV{HOME}) + +# Specify the paths to the include and library directories +set(ATHENA_INCLUDE_DIR ${HOME_DIR}/.local/athena/include) +set(ATHENA_LIBRARY ${HOME_DIR}/.local/athena/lib/libathena.a) # or libfoo.a for static libraries + +find_library(ATHENA_LIBRARY NAMES athena) + +# Add the include directory +include_directories(${ATHENA_INCLUDE_DIR}) + + + +set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${PPFLAGS}") + + +# create the library +add_library(${PROJECT_NAME} STATIC ${PREPENDED_LIB_FILES} ${PREPENDED_SRC_FILES}) +set(MODULE_DIR ${CMAKE_BUILD_PREFIX}/modules) +set_target_properties(${PROJECT_NAME} PROPERTIES Fortran_MODULE_DIRECTORY ${MODULE_DIR}) +target_link_libraries(${PROJECT_NAME} PUBLIC) + +# replace ".f90" with ".mod" +string(REGEX REPLACE "\\.[^.]*$" ".mod" MODULE_FILES "${SRC_FILES}") + +# installation +install(FILES ${MODULE_DIR}/${MODULE_FILES} DESTINATION include) +install(TARGETS ${PROJECT_NAME} DESTINATION lib) + +# set compile options based on different build configurations +target_compile_options(${PROJECT_NAME} PUBLIC "$<$:${OPTIMFLAGS}>") +target_compile_options(${PROJECT_NAME} PUBLIC "$<$:${OPTIMFLAGS}>") +target_compile_options(${PROJECT_NAME} PUBLIC "$<$:${MPFLAGS}>") +target_compile_options(${PROJECT_NAME} PUBLIC "$<$:${DEVFLAGS}>") +target_compile_options(${PROJECT_NAME} PUBLIC "$<$:${DEBUGFLAGS}>") +target_compile_options(${PROJECT_NAME} PUBLIC "$<$:${MPFLAGS}>") +target_compile_options(${PROJECT_NAME} PUBLIC "$<$:${DEVFLAGS}>") + + +# add coverage compiler flags +if (CMAKE_BUILD_TYPE MATCHES "Debug*" OR CMAKE_BUILD_TYPE MATCHES "Dev*") + append_coverage_compiler_flags() +endif() + +target_link_libraries(raffle ${ATHENA_LIBRARY}) \ No newline at end of file diff --git a/src/raffle.f90 b/src/raffle.f90 new file mode 100644 index 00000000..afd2ed81 --- /dev/null +++ b/src/raffle.f90 @@ -0,0 +1,90 @@ +module raffle + use constants, only: real12 + use inputs + use read_structures, only: get_evolved_gvectors_from_data + use gen, only: generation + use evolver, only: gvector_container_type + implicit none + + type(gvector_container_type) :: gvector_container + real(real12), dimension(3) :: method_probab + + + +! !!!----------------------------------------------------------------------------- +! !!! read input file +! !!!----------------------------------------------------------------------------- +! call set_global_vars() + + +! !!!----------------------------------------------------------------------------- +! !!! check the task and run the appropriate case +! !!!----------------------------------------------------------------------------- +! !!! OLD TASKS !!! +! !!! 0) Run RSS +! !!! 1) Regenerate DIst Files (WIP) +! !!! 2) Run HOST_RSS +! !!! 3) Test +! !!! 4) Sphere_Overlap +! !!! 5) Bondangle_test !!! THIS LITERALLY JUST TESTS THAT THE BONDANGLE METHOD WORKS! DO NOT USE! !!! +! !!! 6) Run evo (Should be run after any set created) +! !!! 7) Add new poscar +! !!! 8) Run evo, but don't regen energies or evolve distributions (only reformat gaussians) +! !!! 9) Run evo, don't get energies but do evolve distributions +! select case(task) +! case(0) +! write(*,*) "NOTHING WAS EVER SET UP FOR CASE 0" +! case(1) +! write(*,*) "Regenerating Distribution Files" +! write(*,*) "DEPRECATED" +! stop 0 +! case(2) +! write(*,*) "Running HOST_RSS" +! case default +! write(*,*) "Invalid option" +! stop 1 +! end select + + +! !!!----------------------------------------------------------------------------- +! !!! read structures from the database and generate gvectors +! !!!----------------------------------------------------------------------------- +! gvector_container = get_evolved_gvectors_from_data( & +! input_dir = database_list, & +! element_file = "elements.dat", & +! bond_file = "chem.in", & +! element_list = element_list, & +! file_format = database_format, & +! gvector_container_template = gvector_container_type(& +! width = width_list, & +! sigma = sigma_list, & +! cutoff_min = cutoff_min_list, & +! cutoff_max = cutoff_max_list ) ) + +! call gvector_container%write_2body(file="2body.txt") +! call gvector_container%write_3body(file="3body.txt") +! call gvector_container%write_4body(file="4body.txt") + + +! !!!----------------------------------------------------------------------------- +! !!! calculate the probability of each placement method +! !!!----------------------------------------------------------------------------- +! method_probab(1) = vps_ratio(1)/real(sum(vps_ratio),real12) +! method_probab(2) = method_probab(1) + & +! vps_ratio(2)/real(sum(vps_ratio),real12) +! method_probab(3) = method_probab(2) + & +! vps_ratio(3)/real(sum(vps_ratio),real12) +! write(*,*) "Method probabilities (void, scan, pseudorandom-walk): ", & +! method_probab + + +! !!!----------------------------------------------------------------------------- +! !!! generate random structures +! !!!----------------------------------------------------------------------------- +! write(*,*) "Generating structures" +! call generation( gvector_container, num_structures, task, & +! element_list, stoichiometry_list, & +! method_probab ) +! write(*,*) "Structures have been successfully generated and saved" + +end module raffle \ No newline at end of file From c51b0822ec3cb95d852d84ca9a2e4ce5ed61c712 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Mon, 24 Jun 2024 15:47:46 +0100 Subject: [PATCH 003/293] Fix argument intents --- src/generator.f90 | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/generator.f90 b/src/generator.f90 index c628828b..61edd651 100644 --- a/src/generator.f90 +++ b/src/generator.f90 @@ -36,13 +36,13 @@ module gen subroutine generation(gvector_container, num_structures, task, & element_list, stoichiometry_list, method_probab, output_dir) implicit none - integer, intent(inout) :: num_structures + integer, intent(in) :: num_structures !! MAKE AN INPUT ARGUMENT THAT IS MAX_NUM_STRUCTURES integer, intent(in) :: task type(gvector_container_type), intent(in) :: gvector_container character(len=1024), intent(in), optional :: output_dir - integer, dimension(:), allocatable, intent(inout) :: stoichiometry_list - character(3), dimension(:), allocatable, intent(inout) :: element_list + integer, dimension(:), intent(in) :: stoichiometry_list + character(3), dimension(:), intent(in) :: element_list real(real12), dimension(3), intent(in), optional :: method_probab type(bas_type) :: basis_host @@ -52,12 +52,14 @@ subroutine generation(gvector_container, num_structures, task, & type(bas_type) :: basis, basis_store integer, dimension(:,:), allocatable :: placement_list, placement_list_shuffled + integer, dimension(:), allocatable :: stoichiometry_list_tot + character(3), dimension(:), allocatable :: element_list_tot integer :: i, j, k integer :: istructure integer :: unit, info_unit, structure_unit integer :: task_ - integer :: num_species, num_atoms, num_insert_atoms + integer :: num_species_tot, num_atoms, num_insert_atoms integer :: num_insert_species real(real12) :: rtmp1 @@ -121,9 +123,9 @@ subroutine generation(gvector_container, num_structures, task, & end if end do spec_loop1 - num_species = basis_store%nspec - element_list = basis_store%spec(:)%name - stoichiometry_list = basis_store%spec(:)%num + num_species_tot = basis_store%nspec + element_list_tot = basis_store%spec(:)%name + stoichiometry_list_tot = basis_store%spec(:)%num ! !!-------------------------------------------------------------------------- @@ -146,10 +148,12 @@ subroutine generation(gvector_container, num_structures, task, & !! ... the total rough cell volume. !! calculate the normalisation factor - normalisation_a = sum(stoichiometry_list**2) - do i = 1, num_species - do j = i + 1, num_species, 1 - normalisation_a = normalisation_a + ( stoichiometry_list(i) + stoichiometry_list(j) )**2 + normalisation_a = sum(stoichiometry_list_tot**2) + do i = 1, num_species_tot + do j = i + 1, num_species_tot, 1 + normalisation_a = normalisation_a + ( & + stoichiometry_list_tot(i) + & + stoichiometry_list_tot(j) )**2 end do end do normalisation_a = ( basis_store%natom ** 2._real12 ) / normalisation_a @@ -180,18 +184,18 @@ subroutine generation(gvector_container, num_structures, task, & gvector_container%bond_info(k)%radius_vdw,& gvector_container%bond_info(i)%radius_covalent ) - j = findloc( element_list, gvector_container%bond_info(i)%element(1), dim=1 ) - k = findloc( element_list, gvector_container%bond_info(i)%element(2), dim=1 ) + j = findloc( element_list_tot, gvector_container%bond_info(i)%element(1), dim=1 ) + k = findloc( element_list_tot, gvector_container%bond_info(i)%element(2), dim=1 ) rtmp1 = connectivity * normalisation_a * & min( & - stoichiometry_list(j) * & + stoichiometry_list_tot(j) * & gvector_container%bond_info(i)%coordination(1), & - stoichiometry_list(k) * & + stoichiometry_list_tot(k) * & gvector_container%bond_info(i)%coordination(2) & ) * total_volume if( gvector_container%bond_info(i)%element(1).eq.& gvector_container%bond_info(i)%element(2) )then - volmin = volmin + stoichiometry_list(j) * & + volmin = volmin + stoichiometry_list_tot(j) * & (4._real12/3._real12) * pi * & ( gvector_container%bond_info(i)%radius_vdw ** 3._real12 ) ! I think this below is to reduce significance of same-species bonding From b98bdb8b0d2c321845e5320f4e4a802f29282c65 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Mon, 24 Jun 2024 15:48:01 +0100 Subject: [PATCH 004/293] Separate src files --- CMakeLists.txt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c4baf665..9d9cbbfc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,10 +79,18 @@ foreach(lib ${LIB_FILES}) endforeach() message(STATUS "Modified LIB_FILES: ${PREPENDED_LIB_FILES}") +set(EXTRA_SRC_FILES + inputs.f90 + generator.f90 +) +foreach(src ${EXTRA_SRC_FILES}) + list(APPEND PREPENDED_SRC_FILES ${SRC_DIR}/${src}) +endforeach() + if (CMAKE_BUILD_TYPE MATCHES "Parallel*") set(SRC_FILES raffle_omp.f90) else() - set(SRC_FILES inputs.f90 generator.f90 raffle.f90) + set(SRC_FILES raffle.f90) endif() foreach(src ${SRC_FILES}) list(APPEND PREPENDED_SRC_FILES ${SRC_DIR}/${src}) From c2a2336a1a956bc68bb9a79fd1a7cd81e44f7e91 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Mon, 24 Jun 2024 15:48:12 +0100 Subject: [PATCH 005/293] Add example setup for raffle procedures --- src/raffle.f90 | 116 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 112 insertions(+), 4 deletions(-) diff --git a/src/raffle.f90 b/src/raffle.f90 index afd2ed81..c1a5485f 100644 --- a/src/raffle.f90 +++ b/src/raffle.f90 @@ -1,16 +1,124 @@ module raffle - use constants, only: real12 - use inputs + use constants, only: real12, pi + use rw_geom, only: bas_type use read_structures, only: get_evolved_gvectors_from_data use gen, only: generation use evolver, only: gvector_container_type implicit none - type(gvector_container_type) :: gvector_container - real(real12), dimension(3) :: method_probab + ! type(gvector_container_type) :: global_gvector_container + ! real(real12), dimension(3) :: method_probab + private + public :: get_gvector_evolved + + contains + + function get_gvector_evolved( & + input_dir, & + element_file, bond_file, element_list, file_format, & + width, sigma, cutoff_min, cutoff_max ) result(tmp) + implicit none + character(len=*), intent(in) :: input_dir + character(len=*), intent(in), optional :: element_file + character(len=*), intent(in), optional :: bond_file + character(3), allocatable, dimension(:), intent(in), optional :: element_list + character(len=*), intent(in), optional :: file_format + real(real12), dimension(:), intent(in), optional :: width + real(real12), dimension(:), intent(in), optional :: sigma + real(real12), dimension(:), intent(in), optional :: cutoff_min + real(real12), dimension(:), intent(in), optional :: cutoff_max + type(gvector_container_type) :: gvector_container + + integer :: tmp + character(len=256) :: element_file_, bond_file_ + real(real12), dimension(3) :: width_, sigma_, cutoff_min_, cutoff_max_ + + if( .not. present(element_file) ) then + element_file_ = "elements.dat" + end if + if( .not. present(bond_file) ) then + bond_file_ = "chem.in" + end if + if( .not. present(width) ) then + width_ = [ 0.025_real12, pi/24._real12, pi/32._real12 ] + end if + if( .not. present(sigma) ) then + sigma_ = [ 0.1_real12, 0.05_real12, 0.05_real12 ] + end if + if( .not. present(cutoff_min) ) then + cutoff_min_ = [ 0.5_real12, 0._real12, 0._real12 ] + end if + if( .not. present(cutoff_max) ) then + cutoff_max_ = [ 6._real12, pi, pi/2._real12 ] + end if + + if( present(element_list))then + gvector_container = get_evolved_gvectors_from_data( & + input_dir = input_dir, & + element_file = element_file, & + bond_file = bond_file, & + element_list = element_list, & + file_format = file_format, & + gvector_container_template = gvector_container_type( & + width = width_, & + sigma = sigma_, & + cutoff_min = cutoff_min_, & + cutoff_max = cutoff_max_ ) & + ) + else + gvector_container = get_evolved_gvectors_from_data( & + input_dir = input_dir, & + element_file = element_file, & + bond_file = bond_file, & + file_format = file_format, & + gvector_container_template = gvector_container_type( & + width = width_, & + sigma = sigma_, & + cutoff_min = cutoff_min_, & + cutoff_max = cutoff_max_ ) & + ) + end if + + end function get_gvector_evolved + + + function get_predicted_structures( & + gvector_container, & + lattice_host, basis_host, & + num_structures, element_list, stoichiometry_list, method_probab, & + task ) & + result(bases) + implicit none + type(gvector_container_type), intent(in) :: gvector_container + integer, intent(in) :: num_structures + integer, intent(in) :: task + character(3), dimension(:), intent(in) :: element_list + integer, dimension(:), intent(in) :: stoichiometry_list + real(real12), dimension(3,3), intent(in) :: lattice_host + type(bas_type) :: basis_host + real(real12), dimension(:), intent(in) :: method_probab + + type(bas_type), dimension(num_structures) :: bases + + call generation( gvector_container, num_structures, task, & + element_list, stoichiometry_list, & + method_probab ) + end function get_predicted_structures + + subroutine get_energies( & + lattice, bases, & + energies, energies_err ) + implicit none + type(bas_type), dimension(:), intent(in) :: bases + real(real12), dimension(3,3), intent(in) :: lattice + real(real12), dimension(:), intent(out) :: energies + real(real12), dimension(:), intent(out) :: energies_err + + end subroutine get_energies + ! !!!----------------------------------------------------------------------------- ! !!! read input file ! !!!----------------------------------------------------------------------------- From 6a28c8be1385866133ede2ae1dd7faa5795c71e4 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Tue, 25 Jun 2024 14:32:37 +0100 Subject: [PATCH 006/293] Add species allocation procedure --- src/lib/mod_rw_geom.f90 | 45 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/src/lib/mod_rw_geom.f90 b/src/lib/mod_rw_geom.f90 index 0ca256fe..56dc6006 100644 --- a/src/lib/mod_rw_geom.f90 +++ b/src/lib/mod_rw_geom.f90 @@ -27,6 +27,7 @@ module rw_geom real(real12) :: charge character(len=3) :: name integer :: num + real(real12) :: lat(3,3) end type spec_type type bas_type type(spec_type), allocatable, dimension(:) :: spec @@ -35,21 +36,61 @@ module rw_geom real(real12) :: energy logical :: lcart=.false. character(len=1024) :: sysname + contains + procedure, pass(this) :: allocate_species end type bas_type type(bas_type) :: basis public :: igeom_input,igeom_output - public :: bas_type + public :: bas_type, spec_type public :: clone_bas public :: convert_bas public :: geom_read,geom_write -!!!updated 2020/02/06 +!!!updated 2024/06/25 contains + + subroutine allocate_species(this, num_species, species_list, natom_list, atoms) + implicit none + class(bas_type), intent(inout) :: this + integer, intent(in), optional :: num_species + character(3), dimension(:), intent(in), optional :: species_list + integer, dimension(:), intent(in), optional :: natom_list + real(real12), dimension(:,:), intent(in), optional :: atoms + + integer :: i, istart, iend + + if(present(num_species)) this%nspec = num_species + + if(allocated(this%spec)) deallocate(this%spec) + allocate(this%spec(this%nspec)) + + species_check: if(present(species_list))then + if(size(species_list).ne.this%nspec) exit species_check + this%spec(:)%name = species_list + end if species_check + + natom_check: if(present(natom_list))then + if(size(natom_list).ne.this%nspec) exit natom_check + this%spec(:)%num = natom_list + istart = 1 + do i = 1, this%nspec + iend = istart + this%spec(i)%num - 1 + allocate(this%spec(i)%atom(this%spec(i)%num,3)) + if(present(atoms))then + this%spec(i)%atom = atoms(istart:iend,:3) + end if + istart = iend + 1 + end do + end if natom_check + + end subroutine allocate_species + + !!!############################################################################# !!! sets up the name of output files and subroutines to read files !!!############################################################################# From c8184a6e67a125f31edbf567b2b738645f9f533f Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Wed, 26 Jun 2024 07:39:56 +0100 Subject: [PATCH 007/293] Fix public private --- src/lib/mod_buildmap.f90 | 5 +++++ src/lib/mod_evolver.f90 | 2 +- src/lib/mod_isolated.f90 | 2 ++ src/lib/mod_misc.f90 | 12 ++++++++++++ src/lib/mod_misc_linalg.f90 | 33 +++++++++++++++++---------------- src/lib/mod_misc_maths.f90 | 1 - src/lib/mod_ml.f90 | 1 + src/lib/mod_read_structures.f90 | 1 - src/lib/mod_rw_geom.f90 | 14 ++++++++------ 9 files changed, 46 insertions(+), 25 deletions(-) diff --git a/src/lib/mod_buildmap.f90 b/src/lib/mod_buildmap.f90 index eaf8046e..29f39edb 100644 --- a/src/lib/mod_buildmap.f90 +++ b/src/lib/mod_buildmap.f90 @@ -8,6 +8,11 @@ module buildmap use evolver, only: gvector_container_type implicit none + + private + public :: buildmap_POINT + + contains !!!############################################################################# diff --git a/src/lib/mod_evolver.f90 b/src/lib/mod_evolver.f90 index 814aa75a..87e8f5f7 100644 --- a/src/lib/mod_evolver.f90 +++ b/src/lib/mod_evolver.f90 @@ -10,9 +10,9 @@ module evolver element_database, element_bond_database implicit none + private - public :: gvector_type, gvector_container_type diff --git a/src/lib/mod_isolated.f90 b/src/lib/mod_isolated.f90 index 50b51ae5..6a02bbf0 100644 --- a/src/lib/mod_isolated.f90 +++ b/src/lib/mod_isolated.f90 @@ -4,10 +4,12 @@ module isolated use vasp_file_handler, only: generate_potcar, kpoints_write, Incarwrite implicit none + private public :: generate_isolated_calculations + contains !!!############################################################################# diff --git a/src/lib/mod_misc.f90 b/src/lib/mod_misc.f90 index d9d41ad8..21d0aea6 100644 --- a/src/lib/mod_misc.f90 +++ b/src/lib/mod_misc.f90 @@ -35,6 +35,18 @@ module misc_raffle implicit none + private + + public :: increment_list, find_loc, closest_below, closest_above + public :: alloc + public :: sort1D, sort2D, sort_str, sort_str_order + public :: set, set_str_output_order + public :: sort_col + public :: swap, shuffle + public :: Icount, readcl, grep, count_occ, flagmaker, loadbar + public :: jump, file_check, touch, to_upper, to_lower + + interface alloc procedure ralloc2D,ralloc3D end interface alloc diff --git a/src/lib/mod_misc_linalg.f90 b/src/lib/mod_misc_linalg.f90 index e84495b2..50bd6b6c 100644 --- a/src/lib/mod_misc_linalg.f90 +++ b/src/lib/mod_misc_linalg.f90 @@ -52,22 +52,6 @@ module misc_linalg implicit none integer, parameter, private :: QuadInt_K = selected_int_kind (16) - interface get_angle - procedure get_angle_from_points, get_angle_from_vectors - end interface get_angle - - interface get_dihedral_angle - procedure get_dihedral_angle_from_points, get_dihedral_angle_from_vectors - end interface get_dihedral_angle - - interface gcd - procedure gcd_vec,gcd_num - end interface gcd - - interface vec_mat_mul - procedure ivec_dmat_mul,rvec_dmat_mul - end interface vec_mat_mul - private @@ -86,6 +70,23 @@ module misc_linalg public :: initialise_tetrahedra + interface get_angle + procedure get_angle_from_points, get_angle_from_vectors + end interface get_angle + + interface get_dihedral_angle + procedure get_dihedral_angle_from_points, get_dihedral_angle_from_vectors + end interface get_dihedral_angle + + interface gcd + procedure gcd_vec,gcd_num + end interface gcd + + interface vec_mat_mul + procedure ivec_dmat_mul,rvec_dmat_mul + end interface vec_mat_mul + + !!!updated 2021/12/09 diff --git a/src/lib/mod_misc_maths.f90 b/src/lib/mod_misc_maths.f90 index 244aa7e8..bbc667b1 100644 --- a/src/lib/mod_misc_maths.f90 +++ b/src/lib/mod_misc_maths.f90 @@ -39,7 +39,6 @@ module misc_maths private - public :: times, gauss, fact, lnsum, triangular_number, safe_acos public :: overlap_indiv_points, overlap, convolve, cross_correl public :: running_avg, mean, median, mode, range, normalise, get_turn_points diff --git a/src/lib/mod_ml.f90 b/src/lib/mod_ml.f90 index dc8fb4e9..3af68214 100644 --- a/src/lib/mod_ml.f90 +++ b/src/lib/mod_ml.f90 @@ -10,6 +10,7 @@ module machine_learning public :: network_train, network_train_graph public :: network_predict, network_predict_graph + type(network_type) :: network diff --git a/src/lib/mod_read_structures.f90 b/src/lib/mod_read_structures.f90 index 987a98c3..71ce4c19 100644 --- a/src/lib/mod_read_structures.f90 +++ b/src/lib/mod_read_structures.f90 @@ -15,7 +15,6 @@ module read_structures private public :: get_evolved_gvectors_from_data - public :: get_graph_from_basis diff --git a/src/lib/mod_rw_geom.f90 b/src/lib/mod_rw_geom.f90 index 56dc6006..3969a091 100644 --- a/src/lib/mod_rw_geom.f90 +++ b/src/lib/mod_rw_geom.f90 @@ -16,8 +16,16 @@ module rw_geom use misc_linalg, only: LUinv,modu implicit none + private + public :: igeom_input,igeom_output + public :: bas_type, spec_type + public :: clone_bas + public :: convert_bas + public :: geom_read,geom_write + + integer :: igeom_input=1,igeom_output=1 real(real12), dimension(3,3) :: lattice @@ -41,12 +49,6 @@ module rw_geom end type bas_type type(bas_type) :: basis - - public :: igeom_input,igeom_output - public :: bas_type, spec_type - public :: clone_bas - public :: convert_bas - public :: geom_read,geom_write !!!updated 2024/06/25 From ff2a82f965303997cb7542ac7f68651ddf135b31 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Thu, 27 Jun 2024 09:20:18 +0100 Subject: [PATCH 008/293] Set up python wrapper --- CMakeLists.txt | 94 ++++++++++++++++++++++++++++++++++++++++++++++++-- kind_map | 18 ++++++++++ 2 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 kind_map diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d9cbbfc..14022df2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,8 +60,8 @@ set(SRC_DIR src) set(LIB_DIR ${SRC_DIR}/lib) set(LIB_FILES - mod_constants.f90 - mod_misc.f90 + mod_constants.f90 + mod_misc.f90 mod_misc_maths.f90 mod_misc_linalg.f90 mod_rw_geom.f90 @@ -120,6 +120,7 @@ if (CMAKE_Fortran_COMPILER MATCHES ".*gfortran.*" OR CMAKE_Fortran_COMPILER MATC set(MEMFLAGS -mcmodel=large) set(OPTIMFLAGS -O3 -march=native) set(FASTFLAGS -Ofast -march=native) + set(PYTHONFLAGS -c -O3 -fPIC) elseif (CMAKE_Fortran_COMPILER MATCHES ".*nag.*") message(STATUS "Using nag compiler") set(PPFLAGS -f2018 -fpp) @@ -150,6 +151,7 @@ endif() set(HOME_DIR $ENV{HOME}) # Specify the paths to the include and library directories +set(ATHENA_ROOT ${HOME_DIR}/.local/athena) set(ATHENA_INCLUDE_DIR ${HOME_DIR}/.local/athena/include) set(ATHENA_LIBRARY ${HOME_DIR}/.local/athena/lib/libathena.a) # or libfoo.a for static libraries @@ -165,7 +167,7 @@ set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${PPFLAGS}") # create the library add_library(${PROJECT_NAME} STATIC ${PREPENDED_LIB_FILES} ${PREPENDED_SRC_FILES}) -set(MODULE_DIR ${CMAKE_BUILD_PREFIX}/modules) +set(MODULE_DIR ${CMAKE_BUILD_PREFIX}/mod) set_target_properties(${PROJECT_NAME} PROPERTIES Fortran_MODULE_DIRECTORY ${MODULE_DIR}) target_link_libraries(${PROJECT_NAME} PUBLIC) @@ -184,6 +186,7 @@ target_compile_options(${PROJECT_NAME} PUBLIC "$<$:${DEVFLAGS}>") target_compile_options(${PROJECT_NAME} PUBLIC "$<$:${DEBUGFLAGS}>") target_compile_options(${PROJECT_NAME} PUBLIC "$<$:${MPFLAGS}>") target_compile_options(${PROJECT_NAME} PUBLIC "$<$:${DEVFLAGS}>") +target_compile_options(${PROJECT_NAME} PUBLIC "$<$:${PYTHONFLAGS}>") # add coverage compiler flags @@ -191,4 +194,89 @@ if (CMAKE_BUILD_TYPE MATCHES "Debug*" OR CMAKE_BUILD_TYPE MATCHES "Dev*") append_coverage_compiler_flags() endif() + + + + +# # Get the directory where object files are generated +get_target_property(OBJECTS ${PROJECT_NAME} EXTERNAL_OBJECT) +# Print the object files directory +set(OBJECTS_DIR ${CMAKE_BUILD_PREFIX}/CMakeFiles/${PROJECT_NAME}.dir) +message(STATUS "Object files directory for ${PROJECT_NAME}: ${OBJECTS_DIR}") + + +# Include f90wrap +find_package(Python3 REQUIRED COMPONENTS Interpreter Development) +find_program(F90WRAP_EXECUTABLE f90wrap) +find_program(F2PY_EXECUTABLE f2py-f90wrap) + +if(NOT F90WRAP_EXECUTABLE) + message(FATAL_ERROR "f90wrap not found. Please install f90wrap.") +endif() + +# Generate f90wrap signature file +set(F90WRAP_FILE ${CMAKE_BINARY_DIR}/f90wrap_${PROJECT_NAME}.f90) +set(KIND_MAP ${CMAKE_SOURCE_DIR}/kind_map) +add_custom_command( + TARGET ${PROJECT_NAME} + POST_BUILD + # OUTPUT ${F90WRAP_FILE} + COMMAND ${F90WRAP_EXECUTABLE} + --default-to-inout + -m ${PROJECT_NAME} + -k ${KIND_MAP} + ${CMAKE_CURRENT_LIST_DIR}/src/raffle.f90 + --only get_gvector_evolved: + DEPENDS ${CMAKE_CURRENT_LIST_DIR}/src/raffle.f90 + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Generating f90wrap signature file" + VERBATIM +) + +# Create a Python module using f2py +add_custom_command( + TARGET ${PROJECT_NAME} + POST_BUILD + # OUTPUT ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.so + COMMAND ${F2PY_EXECUTABLE} + -L${ATHENA_ROOT}/lib + -I${ATHENA_ROOT}/include + -I${MODULE_DIR} + -lathena + -c + -m _${PROJECT_NAME} + ${F90WRAP_FILE} + ${OBJECTS_DIR}/src/*.o + ${OBJECTS_DIR}/src/lib/*.o + DEPENDS ${F90WRAP_FILE} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Creating Python module using f2py" +) + + +# Define output files +set(PY_MODULE ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.py) +file(GLOB SO_MODULE "${CMAKE_BINARY_DIR}/_${PROJECT_NAME}*.so") + +# Create a custom target for the Python module +add_custom_target(python_module ALL + DEPENDS ${SO_MODULE} ${PY_MODULE} +) + +# Installation instructions +install(FILES ${PY_MODULE} DESTINATION lib) +install(FILES ${SO_MODULE} DESTINATION lib) + + +# install(DIRECTORY ${CMAKE_BINARY_DIR}/mod/ DESTINATION include) + +# Print helpful messages +message(STATUS "Build configuration:") +message(STATUS " Source directory: ${SRC_DIR}") +message(STATUS " Output library: ${PROJECT_NAME}") +message(STATUS " Fortran modules directory: ${CMAKE_BINARY_DIR}/mod") +message(STATUS " Python module: ${PROJECT_NAME}.so") + + + target_link_libraries(raffle ${ATHENA_LIBRARY}) \ No newline at end of file diff --git a/kind_map b/kind_map new file mode 100644 index 00000000..e159a9d7 --- /dev/null +++ b/kind_map @@ -0,0 +1,18 @@ +{ + 'real': {'': 'float', + '4': 'float', + '8': 'double', + 'dp': 'double', + 'idp':'double', + 'real12': 'float'}, + 'complex' : {'': 'complex_float', + '8' : 'complex_double', + '16': 'complex_long_double', + 'dp': 'complex_double', + 'real12': 'complex_float'}, + 'integer' : {'' : 'int', + '4': 'int', + '8': 'long_long', + 'dp': 'long_long', + 'quadint_k': 'long_long'} +} \ No newline at end of file From ecf37691a86f4ab18d5dfea2ff79c63e2633432e Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Tue, 2 Jul 2024 14:09:12 +0100 Subject: [PATCH 009/293] Make ATHENA default to off --- .gitignore | 1 + CMakeLists.txt | 49 +++++++++++++++++++++------------ src/generator.f90 | 6 ++++ src/lib/mod_read_structures.f90 | 15 +++++++++- 4 files changed, 53 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index c31e643d..1eb5c093 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ bin/ obj/ *.mod +*.smod DTESTING/ DTEST/ build/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 14022df2..cb72a304 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,7 @@ execute_process(COMMAND pwd OUTPUT_VARIABLE CURRENT_WORKING_DIR OUTPUT_STRIP_TRA message("Current working directory: ${CURRENT_WORKING_DIR}") set( CMAKE_BUILD_PREFIX ${CURRENT_WORKING_DIR} CACHE STRING "Select where to build the library." ) +set(MODULE_DIR ${CMAKE_BUILD_PREFIX}/mod) # set the project name project(raffle NONE) @@ -35,6 +36,9 @@ set(CMAKE_Fortran_STANDARD 2018) # set language enable_language(Fortran) +# get the user's home directory +set(HOME_DIR $ENV{HOME}) + # set coverage compiler flags if (CMAKE_BUILD_TYPE MATCHES "Debug*" OR CMAKE_BUILD_TYPE MATCHES "Dev*") list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") @@ -54,6 +58,7 @@ enable_testing() # set options for building tests and examples option(BUILD_TESTS "Build the unit tests" ON) option(BUILD_EXAMPLES "Build the examples" ON) +option(ENABLE_ATHENA "Build energetic predictions with ATHENA" OFF) # Define the sources set(SRC_DIR src) @@ -68,17 +73,41 @@ set(LIB_FILES mod_rw_vasprun.f90 mod_edit_geom.f90 mod_elements.f90 - mod_ml.f90 mod_evolver.f90 mod_buildmap.f90 mod_atom_adder.f90 mod_read_structures.f90 ) + + +# Add Athena library +if(ENABLE_ATHENA) + # Specify the paths to the include and library directories + set(ATHENA_ROOT ${HOME_DIR}/.local/athena) + set(ATHENA_INCLUDE_DIR ${HOME_DIR}/.local/athena/include) + set(ATHENA_LIBRARY ${HOME_DIR}/.local/athena/lib/libathena.a) # or libfoo.a for static libraries + + find_library(ATHENA_LIBRARY NAMES athena) + + # Add the include directory + include_directories(${ATHENA_INCLUDE_DIR}) + list(APPEND LIB_FILES mod_ml.f90) + + set(F2PY_ATHENA_LIBRARY_FLAGS + -L${ATHENA_ROOT}/lib + -I${ATHENA_ROOT}/include + -lathena + ) +endif() + foreach(lib ${LIB_FILES}) list(APPEND PREPENDED_LIB_FILES ${LIB_DIR}/${lib}) endforeach() message(STATUS "Modified LIB_FILES: ${PREPENDED_LIB_FILES}") + + + set(EXTRA_SRC_FILES inputs.f90 generator.f90 @@ -147,18 +176,6 @@ else() endif() -# Get the user's home directory -set(HOME_DIR $ENV{HOME}) - -# Specify the paths to the include and library directories -set(ATHENA_ROOT ${HOME_DIR}/.local/athena) -set(ATHENA_INCLUDE_DIR ${HOME_DIR}/.local/athena/include) -set(ATHENA_LIBRARY ${HOME_DIR}/.local/athena/lib/libathena.a) # or libfoo.a for static libraries - -find_library(ATHENA_LIBRARY NAMES athena) - -# Add the include directory -include_directories(${ATHENA_INCLUDE_DIR}) @@ -167,7 +184,6 @@ set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${PPFLAGS}") # create the library add_library(${PROJECT_NAME} STATIC ${PREPENDED_LIB_FILES} ${PREPENDED_SRC_FILES}) -set(MODULE_DIR ${CMAKE_BUILD_PREFIX}/mod) set_target_properties(${PROJECT_NAME} PROPERTIES Fortran_MODULE_DIRECTORY ${MODULE_DIR}) target_link_libraries(${PROJECT_NAME} PUBLIC) @@ -239,12 +255,11 @@ add_custom_command( POST_BUILD # OUTPUT ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.so COMMAND ${F2PY_EXECUTABLE} - -L${ATHENA_ROOT}/lib - -I${ATHENA_ROOT}/include + ${F2PY_ATHENA_LIBRARY_FLAGS} -I${MODULE_DIR} - -lathena -c -m _${PROJECT_NAME} + --f90flags="${PPFLAGS}" ${F90WRAP_FILE} ${OBJECTS_DIR}/src/*.o ${OBJECTS_DIR}/src/lib/*.o diff --git a/src/generator.f90 b/src/generator.f90 index 61edd651..dcedd127 100644 --- a/src/generator.f90 +++ b/src/generator.f90 @@ -11,9 +11,11 @@ module gen get_viable_gridpoints, update_viable_gridpoints use evolver, only: gvector_container_type +#ifdef ENABLE_ATHENA use read_structures, only: get_graph_from_basis use machine_learning, only: network_predict_graph use athena, only: graph_type +#endif implicit none @@ -70,7 +72,9 @@ subroutine generation(gvector_container, num_structures, task, & real(real12), dimension(3) :: method_probab_ = [0.33_real12, 0.66_real12, 1.0_real12] +#ifdef ENABLE_ATHENA type(graph_type), dimension(1) :: graph +#endif task_=task if(present(method_probab)) method_probab_ = method_probab @@ -224,11 +228,13 @@ subroutine generation(gvector_container, num_structures, task, & basis_store, basis_host, lattice_host, & placement_list, method_probab_ ) +#ifdef ENABLE_ATHENA !!----------------------------------------------------------------------- !! predict energy using ML !!----------------------------------------------------------------------- graph(1) = get_graph_from_basis(lattice_host, basis) write(*,*) "Predicted energy", network_predict_graph(graph(1:1)) +#endif !!----------------------------------------------------------------------- !! write generated POSCAR diff --git a/src/lib/mod_read_structures.f90 b/src/lib/mod_read_structures.f90 index 71ce4c19..02771dbe 100644 --- a/src/lib/mod_read_structures.f90 +++ b/src/lib/mod_read_structures.f90 @@ -5,17 +5,21 @@ module read_structures use rw_geom, only: bas_type, geom_read, geom_write, igeom_input use rw_vasprun, only: get_energy_from_vasprun, get_structure_from_vasprun use evolver, only: gvector_container_type, gvector_type +#ifdef ENABLE_ATHENA use machine_learning, only: network_setup, & network_train, network_train_graph, & network_predict, network_predict_graph use athena, only: shuffle, random_setup, split, graph_type, edge_type +#endif implicit none private public :: get_evolved_gvectors_from_data +#ifdef ENABLE_ATHENA public :: get_graph_from_basis +#endif contains @@ -48,10 +52,12 @@ function get_evolved_gvectors_from_data(input_dir, & type(gvector_type) :: gvector real(real12), dimension(3,3) :: lattice character(256), dimension(:), allocatable :: structure_list +#ifdef ENABLE_ATHENA type(graph_type), dimension(:), allocatable :: graphs real(real12), dimension(:), allocatable :: labels, labels_train, labels_validate real(real12), dimension(:,:), allocatable :: dataset, data_train, data_validate +#endif if(present(gvector_container_template)) then @@ -102,8 +108,10 @@ function get_evolved_gvectors_from_data(input_dir, & num_structures = 0 +#ifdef ENABLE_ATHENA allocate(graphs(0)) allocate(labels(0)) +#endif do i = 1, size(structure_list) write(*,*) "Reading structure: ", trim(adjustl(structure_list(i))) @@ -139,8 +147,10 @@ function get_evolved_gvectors_from_data(input_dir, & backspace(unit) call geom_read(unit, lattice, basis) call get_elements_masses_and_charges(basis) +#ifdef ENABLE_ATHENA graphs = [ graphs, get_graph_from_basis(lattice, basis) ] labels = [ labels, basis%energy ] +#endif num_structures = num_structures + 1 write(format,'("(""Found structure: "",I4,"" with energy: "",& @@ -244,9 +254,10 @@ function get_evolved_gvectors_from_data(input_dir, & ! write(*,*) labels(size(graphs)-10+1:) ! write(*,*) - +#ifdef ENABLE_ATHENA call network_setup(num_inputs = 2, num_outputs = 1) call network_train_graph(graphs(:), labels(:), num_epochs = 200) +#endif igeom_input = 1 @@ -315,6 +326,7 @@ end function get_structure_list !!!############################################################################# !!! !!!############################################################################# +#ifdef ENABLE_ATHENA function get_graph_from_basis(lattice, basis) result(graph) implicit none type(bas_type), intent(in) :: basis @@ -389,6 +401,7 @@ function get_graph_from_basis(lattice, basis) result(graph) end function get_graph_from_basis +#endif !!!############################################################################# From 4ceb2610ff505a4346c89bc67740f66b66a76a5d Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Tue, 2 Jul 2024 15:33:56 +0100 Subject: [PATCH 010/293] Move RAFFLE to a derived type --- src/generator.f90 | 16 +-- src/lib/mod_evolver.f90 | 68 ++++++++++ src/raffle.f90 | 274 ++++++++++++++-------------------------- 3 files changed, 169 insertions(+), 189 deletions(-) diff --git a/src/generator.f90 b/src/generator.f90 index dcedd127..693679a5 100644 --- a/src/generator.f90 +++ b/src/generator.f90 @@ -35,12 +35,11 @@ module gen !!!############################################################################# !!! !!!############################################################################# - subroutine generation(gvector_container, num_structures, task, & + subroutine generation(gvector_container, num_structures, & element_list, stoichiometry_list, method_probab, output_dir) implicit none integer, intent(in) :: num_structures !! MAKE AN INPUT ARGUMENT THAT IS MAX_NUM_STRUCTURES - integer, intent(in) :: task type(gvector_container_type), intent(in) :: gvector_container character(len=1024), intent(in), optional :: output_dir integer, dimension(:), intent(in) :: stoichiometry_list @@ -60,7 +59,6 @@ subroutine generation(gvector_container, num_structures, task, & integer :: i, j, k integer :: istructure integer :: unit, info_unit, structure_unit - integer :: task_ integer :: num_species_tot, num_atoms, num_insert_atoms integer :: num_insert_species @@ -76,7 +74,6 @@ subroutine generation(gvector_container, num_structures, task, & type(graph_type), dimension(1) :: graph #endif - task_=task if(present(method_probab)) method_probab_ = method_probab @@ -94,13 +91,10 @@ subroutine generation(gvector_container, num_structures, task, & do i = 1, basis_store%nspec allocate(basis_store%spec(i)%atom(basis_store%spec(i)%num,3), source = 0._real12) end do - select case(task_) - case(2) - open(newunit = unit, file = trim(adjustl(filename_host))) - call geom_read(unit,lattice_host, basis_host) - close(unit) - basis_store = bas_merge(basis_host,basis_store) - end select + open(newunit = unit, file = trim(adjustl(filename_host))) + call geom_read(unit,lattice_host, basis_host) + close(unit) + basis_store = bas_merge(basis_host,basis_store) allocate(placement_list(num_insert_atoms,2)) k = 0 diff --git a/src/lib/mod_evolver.f90 b/src/lib/mod_evolver.f90 index 87e8f5f7..cb027b72 100644 --- a/src/lib/mod_evolver.f90 +++ b/src/lib/mod_evolver.f90 @@ -48,6 +48,11 @@ module evolver type(element_type), dimension(:), allocatable :: element_info type(element_bond_type), dimension(:), allocatable :: bond_info contains + procedure, pass(this) :: set_width + procedure, pass(this) :: set_sigma + procedure, pass(this) :: set_cutoff_min + procedure, pass(this) :: set_cutoff_max + procedure, pass(this) :: add, add_basis procedure, pass(this) :: set_element_info procedure, pass(this) :: set_bond_info @@ -116,6 +121,69 @@ module function init_gvector_container(nbins, width, sigma, cutoff_min, cutoff_m end function init_gvector_container !!!############################################################################# + subroutine set_width(this, width) + !! Set the width of the gaussians used in the 2-, 3-, and 4-body + !! distribution functions. + implicit none + + ! Arguments + class(gvector_container_type), intent(inout) :: this + !! Self, parent of the procedure + real(real12), dimension(3), intent(in) :: width + !! Width of the gaussians used in the 2-, 3-, and 4-body + !! distribution functions. + + this%width = width + + end subroutine set_width + + + subroutine set_sigma(this, sigma) + !! Set the sigma of the gaussians used in the 2-, 3-, and 4-body + !! distribution functions. + implicit none + + ! Arguments + class(gvector_container_type), intent(inout) :: this + !! Self, parent of the procedure. + real(real12), dimension(3), intent(in) :: sigma + !! Sigma of the gaussians used in the 2-, 3-, and 4-body + !! distribution functions. + + this%sigma = sigma + + end subroutine set_sigma + + + subroutine set_cutoff_min(this, cutoff_min) + !! Set the minimum cutoff for the 2-, 3-, and 4-body distribution functions. + implicit none + + ! Arguments + class(gvector_container_type), intent(inout) :: this + !! Self, parent of the procedure. + real(real12), dimension(3), intent(in) :: cutoff_min + !! Minimum cutoff for the 2-, 3-, and 4-body distribution functions. + + this%cutoff_min = cutoff_min + + end subroutine set_cutoff_min + + + subroutine set_cutoff_max(this, cutoff_max) + !! Set the maximum cutoff for the 2-, 3-, and 4-body distribution functions. + implicit none + + ! Arguments + class(gvector_container_type), intent(inout) :: this + !! Self, parent of the procedure. + real(real12), dimension(3), intent(in) :: cutoff_max + !! Maximum cutoff for the 2-, 3-, and 4-body distribution functions. + + this%cutoff_max = cutoff_max + + end subroutine set_cutoff_max + !!!############################################################################# !!! write all systems diff --git a/src/raffle.f90 b/src/raffle.f90 index c1a5485f..8deee127 100644 --- a/src/raffle.f90 +++ b/src/raffle.f90 @@ -1,198 +1,116 @@ module raffle - use constants, only: real12, pi + use constants, only: real12 use rw_geom, only: bas_type - use read_structures, only: get_evolved_gvectors_from_data - use gen, only: generation use evolver, only: gvector_container_type implicit none - ! type(gvector_container_type) :: global_gvector_container - ! real(real12), dimension(3) :: method_probab + private - public :: get_gvector_evolved + public :: raffle_generator_type + type :: stoichiometry_type + character(len=3) :: element + integer :: num + end type stoichiometry_type - contains - function get_gvector_evolved( & - input_dir, & - element_file, bond_file, element_list, file_format, & - width, sigma, cutoff_min, cutoff_max ) result(tmp) + type :: raffle_generator_type + real(real12), dimension(3,3) :: lattice_host + type(bas_type) :: basis_host + type(gvector_container_type) :: distributions + real(real12), dimension(3) :: method_probab + contains + procedure :: generate + !procedure :: get_structures + !procedure :: evaluate + end type raffle_generator_type + + interface raffle_generator_type + module function init_raffle_generator( & + lattice_host, basis_host, & + width, sigma, cutoff_min, cutoff_max) result(generator) + real(real12), dimension(3,3), intent(in) :: lattice_host + type(bas_type), intent(in) :: basis_host + real(real12), dimension(3), intent(in), optional :: width + real(real12), dimension(3), intent(in), optional :: sigma + real(real12), dimension(3), intent(in), optional :: cutoff_min + real(real12), dimension(3), intent(in), optional :: cutoff_max + type(raffle_generator_type) :: generator + end function init_raffle_generator + end interface raffle_generator_type + + interface + module subroutine generate( this, & + num_structures, stoichiometry, method_probab ) + class(raffle_generator_type), intent(inout) :: this + integer, intent(in) :: num_structures + type(stoichiometry_type), dimension(:), intent(in) :: stoichiometry + real(real12), dimension(:), intent(in) :: method_probab + end subroutine generate + end interface + +contains + module function init_raffle_generator( & + lattice_host, basis_host, width, sigma, cutoff_min, cutoff_max ) & + result(generator) + !! Initialise an instance of the raffle generator. + !! Set up run-independent parameters. implicit none - character(len=*), intent(in) :: input_dir - character(len=*), intent(in), optional :: element_file - character(len=*), intent(in), optional :: bond_file - character(3), allocatable, dimension(:), intent(in), optional :: element_list - character(len=*), intent(in), optional :: file_format - real(real12), dimension(:), intent(in), optional :: width - real(real12), dimension(:), intent(in), optional :: sigma - real(real12), dimension(:), intent(in), optional :: cutoff_min - real(real12), dimension(:), intent(in), optional :: cutoff_max - type(gvector_container_type) :: gvector_container - - integer :: tmp - character(len=256) :: element_file_, bond_file_ - real(real12), dimension(3) :: width_, sigma_, cutoff_min_, cutoff_max_ - - if( .not. present(element_file) ) then - element_file_ = "elements.dat" - end if - if( .not. present(bond_file) ) then - bond_file_ = "chem.in" - end if - if( .not. present(width) ) then - width_ = [ 0.025_real12, pi/24._real12, pi/32._real12 ] - end if - if( .not. present(sigma) ) then - sigma_ = [ 0.1_real12, 0.05_real12, 0.05_real12 ] - end if - if( .not. present(cutoff_min) ) then - cutoff_min_ = [ 0.5_real12, 0._real12, 0._real12 ] - end if - if( .not. present(cutoff_max) ) then - cutoff_max_ = [ 6._real12, pi, pi/2._real12 ] - end if - - if( present(element_list))then - gvector_container = get_evolved_gvectors_from_data( & - input_dir = input_dir, & - element_file = element_file, & - bond_file = bond_file, & - element_list = element_list, & - file_format = file_format, & - gvector_container_template = gvector_container_type( & - width = width_, & - sigma = sigma_, & - cutoff_min = cutoff_min_, & - cutoff_max = cutoff_max_ ) & - ) - else - gvector_container = get_evolved_gvectors_from_data( & - input_dir = input_dir, & - element_file = element_file, & - bond_file = bond_file, & - file_format = file_format, & - gvector_container_template = gvector_container_type( & - width = width_, & - sigma = sigma_, & - cutoff_min = cutoff_min_, & - cutoff_max = cutoff_max_ ) & - ) - end if - - end function get_gvector_evolved - - - function get_predicted_structures( & - gvector_container, & - lattice_host, basis_host, & - num_structures, element_list, stoichiometry_list, method_probab, & - task ) & - result(bases) + ! Arguments + real(real12), dimension(3,3), intent(in) :: lattice_host + !! Lattice vectors of the host structure. + type(bas_type), intent(in) :: basis_host + !! Basis of the host structure. + real(real12), dimension(3), intent(in), optional :: width + !! Width of the gaussians used in the 2-, 3-, and 4-body + !! distribution functions. + real(real12), dimension(3), intent(in), optional :: sigma + !! Width of the gaussians used in the 2-, 3-, and 4-body + !! distribution functions. + real(real12), dimension(3), intent(in), optional :: cutoff_min + !! Minimum cutoff for the 2-, 3-, and 4-body distribution functions. + real(real12), dimension(3), intent(in), optional :: cutoff_max + !! Maximum cutoff for the 2-, 3-, and 4-body distribution functions. + + type(raffle_generator_type) :: generator + + + generator%lattice_host = lattice_host + generator%basis_host = basis_host + + if( present(width) ) & + call generator%distributions%set_width(width) + if( present(sigma) ) & + call generator%distributions%set_sigma(sigma) + if( present(cutoff_min) ) & + call generator%distributions%set_cutoff_min(cutoff_min) + if( present(cutoff_max) ) & + call generator%distributions%set_cutoff_max(cutoff_max) + + + end function init_raffle_generator + + + module subroutine generate( this, & + num_structures, stoichiometry, method_probab ) + !! Generate random structures. implicit none - type(gvector_container_type), intent(in) :: gvector_container + ! Arguments + class(raffle_generator_type), intent(inout) :: this + !! Instance of the raffle generator. integer, intent(in) :: num_structures - integer, intent(in) :: task - character(3), dimension(:), intent(in) :: element_list - integer, dimension(:), intent(in) :: stoichiometry_list - real(real12), dimension(3,3), intent(in) :: lattice_host - type(bas_type) :: basis_host + !! Number of structures to generate. + type(stoichiometry_type), dimension(:), intent(in) :: stoichiometry + !! Stoichiometry of the structures to generate. real(real12), dimension(:), intent(in) :: method_probab + !! Probability of each placement method. - type(bas_type), dimension(num_structures) :: bases - - call generation( gvector_container, num_structures, task, & - element_list, stoichiometry_list, & + call generation( this%distributions, num_structures, & + stoichiometry(:)%element, stoichiometry(:)%num, & method_probab ) - end function get_predicted_structures - subroutine get_energies( & - lattice, bases, & - energies, energies_err ) - implicit none - type(bas_type), dimension(:), intent(in) :: bases - real(real12), dimension(3,3), intent(in) :: lattice - real(real12), dimension(:), intent(out) :: energies - real(real12), dimension(:), intent(out) :: energies_err - - end subroutine get_energies - -! !!!----------------------------------------------------------------------------- -! !!! read input file -! !!!----------------------------------------------------------------------------- -! call set_global_vars() - - -! !!!----------------------------------------------------------------------------- -! !!! check the task and run the appropriate case -! !!!----------------------------------------------------------------------------- -! !!! OLD TASKS !!! -! !!! 0) Run RSS -! !!! 1) Regenerate DIst Files (WIP) -! !!! 2) Run HOST_RSS -! !!! 3) Test -! !!! 4) Sphere_Overlap -! !!! 5) Bondangle_test !!! THIS LITERALLY JUST TESTS THAT THE BONDANGLE METHOD WORKS! DO NOT USE! !!! -! !!! 6) Run evo (Should be run after any set created) -! !!! 7) Add new poscar -! !!! 8) Run evo, but don't regen energies or evolve distributions (only reformat gaussians) -! !!! 9) Run evo, don't get energies but do evolve distributions -! select case(task) -! case(0) -! write(*,*) "NOTHING WAS EVER SET UP FOR CASE 0" -! case(1) -! write(*,*) "Regenerating Distribution Files" -! write(*,*) "DEPRECATED" -! stop 0 -! case(2) -! write(*,*) "Running HOST_RSS" -! case default -! write(*,*) "Invalid option" -! stop 1 -! end select - - -! !!!----------------------------------------------------------------------------- -! !!! read structures from the database and generate gvectors -! !!!----------------------------------------------------------------------------- -! gvector_container = get_evolved_gvectors_from_data( & -! input_dir = database_list, & -! element_file = "elements.dat", & -! bond_file = "chem.in", & -! element_list = element_list, & -! file_format = database_format, & -! gvector_container_template = gvector_container_type(& -! width = width_list, & -! sigma = sigma_list, & -! cutoff_min = cutoff_min_list, & -! cutoff_max = cutoff_max_list ) ) - -! call gvector_container%write_2body(file="2body.txt") -! call gvector_container%write_3body(file="3body.txt") -! call gvector_container%write_4body(file="4body.txt") - - -! !!!----------------------------------------------------------------------------- -! !!! calculate the probability of each placement method -! !!!----------------------------------------------------------------------------- -! method_probab(1) = vps_ratio(1)/real(sum(vps_ratio),real12) -! method_probab(2) = method_probab(1) + & -! vps_ratio(2)/real(sum(vps_ratio),real12) -! method_probab(3) = method_probab(2) + & -! vps_ratio(3)/real(sum(vps_ratio),real12) -! write(*,*) "Method probabilities (void, scan, pseudorandom-walk): ", & -! method_probab - - -! !!!----------------------------------------------------------------------------- -! !!! generate random structures -! !!!----------------------------------------------------------------------------- -! write(*,*) "Generating structures" -! call generation( gvector_container, num_structures, task, & -! element_list, stoichiometry_list, & -! method_probab ) -! write(*,*) "Structures have been successfully generated and saved" + end subroutine generate end module raffle \ No newline at end of file From 96898473b1472e5fcc8065d70980dc558591da64 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Tue, 2 Jul 2024 15:36:14 +0100 Subject: [PATCH 011/293] Fix missing use statement --- src/raffle.f90 | 1 + 1 file changed, 1 insertion(+) diff --git a/src/raffle.f90 b/src/raffle.f90 index 8deee127..54e19291 100644 --- a/src/raffle.f90 +++ b/src/raffle.f90 @@ -1,5 +1,6 @@ module raffle use constants, only: real12 + use gen, only: generation use rw_geom, only: bas_type use evolver, only: gvector_container_type implicit none From 23951792f153d7506c1eb25407ee7e94f6b19097 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Tue, 2 Jul 2024 16:03:05 +0100 Subject: [PATCH 012/293] Improve file paths --- CMakeLists.txt | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cb72a304..e7d56fcb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -116,14 +116,14 @@ foreach(src ${EXTRA_SRC_FILES}) list(APPEND PREPENDED_SRC_FILES ${SRC_DIR}/${src}) endforeach() -if (CMAKE_BUILD_TYPE MATCHES "Parallel*") - set(SRC_FILES raffle_omp.f90) -else() - set(SRC_FILES raffle.f90) -endif() +set(SRC_FILES + raffle.f90 +) foreach(src ${SRC_FILES}) + list(APPEND F90WRAP_FORTRAN_SRC_FILES ${CMAKE_CURRENT_LIST_DIR}/${SRC_DIR}/${src}) list(APPEND PREPENDED_SRC_FILES ${SRC_DIR}/${src}) endforeach() + message(STATUS "Modified SRC_FILES: ${PREPENDED_SRC_FILES}") # initialise flags @@ -236,14 +236,13 @@ set(KIND_MAP ${CMAKE_SOURCE_DIR}/kind_map) add_custom_command( TARGET ${PROJECT_NAME} POST_BUILD - # OUTPUT ${F90WRAP_FILE} COMMAND ${F90WRAP_EXECUTABLE} --default-to-inout -m ${PROJECT_NAME} -k ${KIND_MAP} - ${CMAKE_CURRENT_LIST_DIR}/src/raffle.f90 - --only get_gvector_evolved: - DEPENDS ${CMAKE_CURRENT_LIST_DIR}/src/raffle.f90 + ${F90WRAP_FORTRAN_SRC_FILES} + --only raffle_generator_type: + DEPENDS ${F90WRAP_FORTRAN_SRC_FILES} WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMENT "Generating f90wrap signature file" VERBATIM @@ -253,7 +252,6 @@ add_custom_command( add_custom_command( TARGET ${PROJECT_NAME} POST_BUILD - # OUTPUT ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.so COMMAND ${F2PY_EXECUTABLE} ${F2PY_ATHENA_LIBRARY_FLAGS} -I${MODULE_DIR} From 5405e107264bfc822b3482a89ea58ad091a49514 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Tue, 2 Jul 2024 16:03:29 +0100 Subject: [PATCH 013/293] Fix formatting --- src/raffle.f90 | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/raffle.f90 b/src/raffle.f90 index 54e19291..184914cb 100644 --- a/src/raffle.f90 +++ b/src/raffle.f90 @@ -23,7 +23,7 @@ module raffle type(gvector_container_type) :: distributions real(real12), dimension(3) :: method_probab contains - procedure :: generate + procedure, pass(this) :: generate !procedure :: get_structures !procedure :: evaluate end type raffle_generator_type @@ -50,9 +50,11 @@ module subroutine generate( this, & type(stoichiometry_type), dimension(:), intent(in) :: stoichiometry real(real12), dimension(:), intent(in) :: method_probab end subroutine generate - end interface + end interface + contains + module function init_raffle_generator( & lattice_host, basis_host, width, sigma, cutoff_min, cutoff_max ) & result(generator) @@ -114,4 +116,5 @@ module subroutine generate( this, & end subroutine generate + end module raffle \ No newline at end of file From 03e85ad677e8b4fa8e887c8558f07f71bc5f65a9 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Wed, 3 Jul 2024 10:42:37 +0100 Subject: [PATCH 014/293] Change ierror to verbose --- src/lib/mod_constants.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/mod_constants.f90 b/src/lib/mod_constants.f90 index b96b8fd8..36efa2f2 100644 --- a/src/lib/mod_constants.f90 +++ b/src/lib/mod_constants.f90 @@ -17,5 +17,5 @@ MODULE constants real(real12), parameter, public :: c_vasp = 0.262465831D0 real(real12), parameter, public :: INF = huge(0._real12) complex(real12), parameter, public :: imag=(0._real12, 1._real12) - integer, public :: ierror = -1 + integer, public :: verbose = 0 end MODULE constants From 2f7653166e72e9990a7ab1630aafa2af38cea161 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Wed, 3 Jul 2024 10:43:08 +0100 Subject: [PATCH 015/293] Move raffle derived type to generator module --- src/generator.f90 | 359 ---------------------------------- src/lib/mod_generator.f90 | 69 +++++++ src/lib/mod_generator_sub.f90 | 270 +++++++++++++++++++++++++ src/raffle.f90 | 112 +---------- 4 files changed, 340 insertions(+), 470 deletions(-) delete mode 100644 src/generator.f90 create mode 100644 src/lib/mod_generator.f90 create mode 100644 src/lib/mod_generator_sub.f90 diff --git a/src/generator.f90 b/src/generator.f90 deleted file mode 100644 index 693679a5..00000000 --- a/src/generator.f90 +++ /dev/null @@ -1,359 +0,0 @@ -module gen - use constants, only: real12, pi - use misc_raffle, only: touch, shuffle - use misc_linalg, only: get_spheres_overlap - use rw_geom, only: bas_type, geom_read, geom_write, clone_bas - use edit_geom, only: bas_merge - ! use isolated, only: generate_isolated_calculations - !use vasp_file_handler, only: incarwrite, kpoints_write, generate_potcar - use inputs, only: vdW, volvar, bins, filename_host, verbose - use add_atom, only: add_atom_void, add_atom_pseudo, add_atom_scan, & - get_viable_gridpoints, update_viable_gridpoints - use evolver, only: gvector_container_type - -#ifdef ENABLE_ATHENA - use read_structures, only: get_graph_from_basis - use machine_learning, only: network_predict_graph - use athena, only: graph_type -#endif - - implicit none - - - private - - public :: generation - - !!! MOVE HOST STRUCTURE TO A BASIS THAT IS AN OPTIONAL ARGUMENT FOR THE ... - !!! ... GENERATION PROCEDURE - !!! that way, remove it from the inputs use - !!! move bins, vdw, volvar - - -contains - -!!!############################################################################# -!!! -!!!############################################################################# - subroutine generation(gvector_container, num_structures, & - element_list, stoichiometry_list, method_probab, output_dir) - implicit none - integer, intent(in) :: num_structures - !! MAKE AN INPUT ARGUMENT THAT IS MAX_NUM_STRUCTURES - type(gvector_container_type), intent(in) :: gvector_container - character(len=1024), intent(in), optional :: output_dir - integer, dimension(:), intent(in) :: stoichiometry_list - character(3), dimension(:), intent(in) :: element_list - real(real12), dimension(3), intent(in), optional :: method_probab - - type(bas_type) :: basis_host - real(real12), dimension(3,3) :: lattice_host - - real(real12), dimension(3,3) :: lattice - type(bas_type) :: basis, basis_store - - integer, dimension(:,:), allocatable :: placement_list, placement_list_shuffled - integer, dimension(:), allocatable :: stoichiometry_list_tot - character(3), dimension(:), allocatable :: element_list_tot - - integer :: i, j, k - integer :: istructure - integer :: unit, info_unit, structure_unit - integer :: num_species_tot, num_atoms, num_insert_atoms - integer :: num_insert_species - - real(real12) :: rtmp1 - real(real12) :: meanvol, connectivity, volmin, total_volume - real(real12) :: normalisation_a - logical :: placed, success - character(1024) :: buffer, output_dir_ = "iteration1" - - real(real12), dimension(3) :: method_probab_ = [0.33_real12, 0.66_real12, 1.0_real12] - -#ifdef ENABLE_ATHENA - type(graph_type), dimension(1) :: graph -#endif - - if(present(method_probab)) method_probab_ = method_probab - - - !!! THINK OF SOME WAY TO HANDLE THE HOST SEPARATELY - !!! THAT CAN SIGNIFICANTLY REDUCE DATA USAGE - num_insert_species = size(element_list) - num_insert_atoms = sum(stoichiometry_list) - allocate(basis_store%spec(num_insert_species)) - basis_store%spec(:)%name = element_list - basis_store%spec(:)%num = stoichiometry_list - basis_store%natom = num_insert_atoms - basis_store%nspec = num_insert_species - basis_store%sysname = "inserts" - - do i = 1, basis_store%nspec - allocate(basis_store%spec(i)%atom(basis_store%spec(i)%num,3), source = 0._real12) - end do - open(newunit = unit, file = trim(adjustl(filename_host))) - call geom_read(unit,lattice_host, basis_host) - close(unit) - basis_store = bas_merge(basis_host,basis_store) - - allocate(placement_list(num_insert_atoms,2)) - k = 0 - spec_loop1: do i = 1, basis_store%nspec - success = .false. - do j = 1, size(element_list) - if(trim(basis_store%spec(i)%name).eq.trim(element_list(j))) & - success = .true. - end do - if(.not.success) cycle - if(i.gt.basis_host%nspec)then - do j = 1, basis_store%spec(i)%num - k = k + 1 - placement_list(k,1) = i - placement_list(k,2) = j - end do - else - do j = 1, basis_store%spec(i)%num - if(j.le.basis_host%spec(i)%num) cycle - k = k + 1 - placement_list(k,1) = i - placement_list(k,2) = j - end do - end if - end do spec_loop1 - - num_species_tot = basis_store%nspec - element_list_tot = basis_store%spec(:)%name - stoichiometry_list_tot = basis_store%spec(:)%num - - - ! !!-------------------------------------------------------------------------- - ! !! set up isolated element calculations - ! !!-------------------------------------------------------------------------- - ! call generate_isolated_calculations(element_list) - - - !!-------------------------------------------------------------------------- - !! create the output directory - !!-------------------------------------------------------------------------- - if(present(output_dir)) output_dir_ = output_dir - call touch(output_dir_) - - - !!-------------------------------------------------------------------------- - !! calculate the expected cell volume - !!-------------------------------------------------------------------------- - !! Meanvol takes the atomic radius and calculates a guestimate for ... - !! ... the total rough cell volume. - - !! calculate the normalisation factor - normalisation_a = sum(stoichiometry_list_tot**2) - do i = 1, num_species_tot - do j = i + 1, num_species_tot, 1 - normalisation_a = normalisation_a + ( & - stoichiometry_list_tot(i) + & - stoichiometry_list_tot(j) )**2 - end do - end do - normalisation_a = ( basis_store%natom ** 2._real12 ) / normalisation_a - - !!! YOU CAN GET EXACT VOLUME TAKEN UP BY HOST STRUCTURE - !!! get volume of all atoms associated with chem.in radius - !!! then subtract all the overlaps - !!! this is calculated by checking for nearest neighbours - !!! apply a packing fraction (0.74 for FCC, 0.68 for BCC, 0.52 for SC) - !!! then work out the estimated volume needed for the inserts - - !! calculate the minimum volume - volmin = 0._real12 - connectivity = vdW / 100._real12 - do i = 1, size(gvector_container%bond_info,1) - j = gvector_container%get_pair_index( & - gvector_container%bond_info(i)%element(1), & - gvector_container%bond_info(i)%element(1) ) - k = gvector_container%get_pair_index( & - gvector_container%bond_info(i)%element(2), & - gvector_container%bond_info(i)%element(2) ) - total_volume = & - ! ( 4._real12 / 3._real12 ) * pi * & - ! ( gvector_container%bond_info(j)%radius_vdw ** 3._real12 + & - ! gvector_container%bond_info(k)%radius_vdw ** 3._real12 ) - & - get_spheres_overlap(& - gvector_container%bond_info(j)%radius_vdw,& - gvector_container%bond_info(k)%radius_vdw,& - gvector_container%bond_info(i)%radius_covalent ) - - j = findloc( element_list_tot, gvector_container%bond_info(i)%element(1), dim=1 ) - k = findloc( element_list_tot, gvector_container%bond_info(i)%element(2), dim=1 ) - rtmp1 = connectivity * normalisation_a * & - min( & - stoichiometry_list_tot(j) * & - gvector_container%bond_info(i)%coordination(1), & - stoichiometry_list_tot(k) * & - gvector_container%bond_info(i)%coordination(2) & - ) * total_volume - if( gvector_container%bond_info(i)%element(1).eq.& - gvector_container%bond_info(i)%element(2) )then - volmin = volmin + stoichiometry_list_tot(j) * & - (4._real12/3._real12) * pi * & - ( gvector_container%bond_info(i)%radius_vdw ** 3._real12 ) - ! I think this below is to reduce significance of same-species bonding - rtmp1 = 0.5_real12 * rtmp1 - else ! Ned introduced this to account for loop now ignoring half the triangle, TEST!!! - rtmp1 = 2._real12 * rtmp1 - end if - volmin = volmin - rtmp1 - end do - meanvol = volmin - - call random_number(rtmp1) - rtmp1 = rtmp1 * 2._real12 - 1._real12 - - write(*,*) meanvol - meanvol = meanvol + ((volvar/100._real12)*rtmp1*meanvol) - write(*,*) "The allocated volume is", meanvol - - - !!-------------------------------------------------------------------------- - !! generate the structures - !!-------------------------------------------------------------------------- - BIGLOOP: do istructure = 1, num_structures - - basis = generate_structure( gvector_container, & - basis_store, basis_host, lattice_host, & - placement_list, method_probab_ ) - -#ifdef ENABLE_ATHENA - !!----------------------------------------------------------------------- - !! predict energy using ML - !!----------------------------------------------------------------------- - graph(1) = get_graph_from_basis(lattice_host, basis) - write(*,*) "Predicted energy", network_predict_graph(graph(1:1)) -#endif - - !!----------------------------------------------------------------------- - !! write generated POSCAR - !!----------------------------------------------------------------------- - write(buffer,'(A,"/struc",I0.3)') trim(output_dir_),istructure - call touch(buffer) - open(newunit = structure_unit, file=trim(buffer)//"/POSCAR") - call geom_write(structure_unit, lattice_host, basis) - close(structure_unit) - write(*,*) - - !!----------------------------------------------------------------------- - !! write additional VASP files - !!----------------------------------------------------------------------- - !call Incarwrite(adjustl(buffer),500, 20*num_atoms) - !call kpoints_write(buffer,3,3,3) - !call generate_potcar(buffer, element_list) - - end do BIGLOOP - write(*,*) "Finished generating structures" - - end subroutine generation -!!!############################################################################# - - -!!!############################################################################# -!!! -!!!############################################################################# - function generate_structure( & - gvector_container, & - basis_initial, basis_host, lattice, & - placement_list, method_probab) result(basis) - implicit none - type(gvector_container_type), intent(in) :: gvector_container - type(bas_type), intent(in) :: basis_initial, basis_host - real(real12), dimension(3,3), intent(in) :: lattice - integer, dimension(:,:), intent(in) :: placement_list - real(real12), dimension(3) :: method_probab - type(bas_type) :: basis - - integer :: i, j, iplaced, void_ticker - integer :: num_insert_atoms - real(real12) :: rtmp1 - logical :: placed - integer, dimension(size(placement_list,1),size(placement_list,2)) :: & - placement_list_shuffled - real(real12), dimension(3) :: method_probab_ - real(real12), dimension(:,:), allocatable :: viable_gridpoints - - - - call clone_bas(basis_initial, basis) - num_insert_atoms = basis%natom - basis_host%natom - - placement_list_shuffled = placement_list - call shuffle(placement_list_shuffled,1) !!! NEED TO SORT OUT RANDOM SEED - - viable_gridpoints = get_viable_gridpoints(bins, lattice, basis, & - [ gvector_container%bond_info(:)%radius_covalent ], & - placement_list_shuffled) - - method_probab_ = method_probab - - iplaced = 0 - void_ticker = 0 - placement_loop: do while (iplaced.lt.num_insert_atoms) - - !!! CHANGE THESE PLACEMENT SUBROUTINES TO FUNCTIONS THAT OUTPUT THE COORDINATE - !!! THEN, THIS LOOP ACTUALLY PLACES IT AT THE END - call random_number(rtmp1) - if(rtmp1.le.method_probab_(1)) then - if(verbose.gt.0) write(*,*) "Add Atom Void" - call add_atom_void( bins, & - lattice, basis, & - placement_list_shuffled(iplaced+1:,:), placed) - else if(rtmp1.le.method_probab_(2)) then - if(verbose.gt.0) write(*,*) "Add Atom Pseudo" - call add_atom_pseudo( bins, & - gvector_container, & - lattice, basis, & - placement_list_shuffled(iplaced+1:,:), & - [ gvector_container%bond_info(:)%radius_covalent ], & - placed ) - if(.not. placed) void_ticker = void_ticker + 1 - else if(rtmp1.le.method_probab_(3)) then - if(verbose.gt.0) write(*,*) "Add Atom Scan" - call add_atom_scan( viable_gridpoints, & - gvector_container, & - lattice, basis, & - placement_list_shuffled(iplaced+1:,:), & - [ gvector_container%bond_info(:)%radius_covalent ], & - placed) - end if - if(.not. placed) then - if(void_ticker.gt.10) & - call add_atom_void( bins, lattice, basis, & - placement_list_shuffled(iplaced+1:,:), placed) - void_ticker = 0 - if(.not.placed) cycle placement_loop - end if - if(verbose.gt.0)then - write(*,'(A)',ADVANCE='NO') achar(13) - write(*,*) "placed", placed - end if - iplaced = iplaced + 1 - if(allocated(viable_gridpoints)) & - call update_viable_gridpoints(viable_gridpoints, lattice, basis, & - [ placement_list_shuffled(iplaced,:) ], & - gvector_container%bond_info( & - ( basis%nspec - & - placement_list_shuffled(iplaced,1)/2 ) * & - ( placement_list_shuffled(iplaced,1) - 1 ) + & - placement_list_shuffled(iplaced,1) & - )%radius_covalent ) - if(.not.allocated(viable_gridpoints).and. & - abs( method_probab_(3) - method_probab_(2) ) .gt. 1.E-3) then - write(*,*) "WARNING: No more viable gridpoints" - write(*,*) "Suppressing SCAN method" - method_probab_ = method_probab_ / method_probab_(2) - method_probab_(3) = method_probab_(2) - end if - - end do placement_loop - - end function generate_structure -!!!############################################################################# - -end module gen \ No newline at end of file diff --git a/src/lib/mod_generator.f90 b/src/lib/mod_generator.f90 new file mode 100644 index 00000000..89d69c2a --- /dev/null +++ b/src/lib/mod_generator.f90 @@ -0,0 +1,69 @@ +module generator + use constants, only: real12 + use rw_geom, only: bas_type + use evolver, only: gvector_container_type + + implicit none + + + private + public :: raffle_generator_type + + + type :: stoichiometry_type + character(len=3) :: element + integer :: num + end type stoichiometry_type + + + type :: raffle_generator_type + integer, dimension(3) :: bins + real(real12), dimension(3,3) :: lattice_host + type(bas_type) :: basis_host + type(gvector_container_type) :: distributions + real(real12), dimension(3) :: method_probab + contains + procedure, pass(this) :: generate + procedure, pass(this), private :: generate_structure + !procedure :: get_structures + !procedure :: evaluate + end type raffle_generator_type + + interface raffle_generator_type + module function init_raffle_generator( & + lattice_host, basis_host, & + width, sigma, cutoff_min, cutoff_max) result(generator) + real(real12), dimension(3,3), intent(in) :: lattice_host + type(bas_type), intent(in) :: basis_host + real(real12), dimension(3), intent(in), optional :: width + real(real12), dimension(3), intent(in), optional :: sigma + real(real12), dimension(3), intent(in), optional :: cutoff_min + real(real12), dimension(3), intent(in), optional :: cutoff_max + type(raffle_generator_type) :: generator + end function init_raffle_generator + end interface raffle_generator_type + + interface + module subroutine generate( this, & + num_structures, stoichiometry, method_probab ) + class(raffle_generator_type), intent(inout) :: this + integer, intent(in) :: num_structures + type(stoichiometry_type), dimension(:), intent(in) :: stoichiometry + real(real12), dimension(:), intent(in), optional :: method_probab + end subroutine generate + + module function generate_structure( & + this, & + basis_initial, & + placement_list, method_probab ) result(basis) + class(raffle_generator_type), intent(in) :: this + type(bas_type), intent(in) :: basis_initial + integer, dimension(:,:), intent(in) :: placement_list + real(real12), dimension(3) :: method_probab + type(bas_type) :: basis + end function generate_structure + end interface + + + +end module generator \ No newline at end of file diff --git a/src/lib/mod_generator_sub.f90 b/src/lib/mod_generator_sub.f90 new file mode 100644 index 00000000..ecc7da3b --- /dev/null +++ b/src/lib/mod_generator_sub.f90 @@ -0,0 +1,270 @@ +submodule(generator) generator_submodule + use constants, only: verbose + use misc_raffle, only: shuffle + use rw_geom, only: geom_read, geom_write, clone_bas + use edit_geom, only: bas_merge + use add_atom, only: add_atom_void, add_atom_pseudo, add_atom_scan, & + get_viable_gridpoints, update_viable_gridpoints + +#ifdef ENABLE_ATHENA + use read_structures, only: get_graph_from_basis + use machine_learning, only: network_predict_graph + use athena, only: graph_type +#endif + + implicit none + + + +contains + + + module function init_raffle_generator( & + lattice_host, basis_host, width, sigma, cutoff_min, cutoff_max ) & + result(generator) + !! Initialise an instance of the raffle generator. + !! Set up run-independent parameters. + implicit none + ! Arguments + real(real12), dimension(3,3), intent(in) :: lattice_host + !! Lattice vectors of the host structure. + type(bas_type), intent(in) :: basis_host + !! Basis of the host structure. + real(real12), dimension(3), intent(in), optional :: width + !! Width of the gaussians used in the 2-, 3-, and 4-body + !! distribution functions. + real(real12), dimension(3), intent(in), optional :: sigma + !! Width of the gaussians used in the 2-, 3-, and 4-body + !! distribution functions. + real(real12), dimension(3), intent(in), optional :: cutoff_min + !! Minimum cutoff for the 2-, 3-, and 4-body distribution functions. + real(real12), dimension(3), intent(in), optional :: cutoff_max + !! Maximum cutoff for the 2-, 3-, and 4-body distribution functions. + + type(raffle_generator_type) :: generator + + + generator%lattice_host = lattice_host + generator%basis_host = basis_host + + if( present(width) ) & + call generator%distributions%set_width(width) + if( present(sigma) ) & + call generator%distributions%set_sigma(sigma) + if( present(cutoff_min) ) & + call generator%distributions%set_cutoff_min(cutoff_min) + if( present(cutoff_max) ) & + call generator%distributions%set_cutoff_max(cutoff_max) + + + end function init_raffle_generator + + + + module subroutine generate(this, num_structures, & + stoichiometry, method_probab) + !! Generate random structures. + implicit none + ! Arguments + class(raffle_generator_type), intent(inout) :: this + !! Instance of the raffle generator. + integer, intent(in) :: num_structures + !! Number of structures to generate. + type(stoichiometry_type), dimension(:), intent(in) :: stoichiometry + !! Stoichiometry of the structures to generate. + real(real12), dimension(:), intent(in), optional :: method_probab + !! Probability of each placement method. + + type(bas_type) :: basis, basis_store + + integer, dimension(:,:), allocatable :: placement_list, placement_list_shuffled + + integer :: i, j, k + integer :: istructure + integer :: unit, info_unit, structure_unit + integer :: num_insert_atoms, num_insert_species + + logical :: placed, success + character(1024) :: buffer + + real(real12), dimension(3) :: method_probab_ = [0.33_real12, 0.66_real12, 1.0_real12] + +#ifdef ENABLE_ATHENA + type(graph_type), dimension(1) :: graph +#endif + + if(present(method_probab)) method_probab_ = method_probab + + + !!! THINK OF SOME WAY TO HANDLE THE HOST SEPARATELY + !!! THAT CAN SIGNIFICANTLY REDUCE DATA USAGE + num_insert_species = size(stoichiometry) + num_insert_atoms = sum(stoichiometry(:)%num) + allocate(basis_store%spec(num_insert_species)) + basis_store%spec(:)%name = stoichiometry(:)%element + basis_store%spec(:)%num = stoichiometry(:)%num + basis_store%natom = num_insert_atoms + basis_store%nspec = num_insert_species + basis_store%sysname = "inserts" + + do i = 1, basis_store%nspec + allocate(basis_store%spec(i)%atom(basis_store%spec(i)%num,3), source = 0._real12) + end do + basis_store = bas_merge(this%basis_host,basis_store) + + allocate(placement_list(num_insert_atoms,2)) + k = 0 + spec_loop1: do i = 1, basis_store%nspec + success = .false. + do j = 1, size(stoichiometry) + if(trim(basis_store%spec(i)%name).eq.trim(stoichiometry(j)%element)) & + success = .true. + end do + if(.not.success) cycle + if(i.gt.this%basis_host%nspec)then + do j = 1, basis_store%spec(i)%num + k = k + 1 + placement_list(k,1) = i + placement_list(k,2) = j + end do + else + do j = 1, basis_store%spec(i)%num + if(j.le.this%basis_host%spec(i)%num) cycle + k = k + 1 + placement_list(k,1) = i + placement_list(k,2) = j + end do + end if + end do spec_loop1 + + + !!-------------------------------------------------------------------------- + !! generate the structures + !!-------------------------------------------------------------------------- + structure_loop: do istructure = 1, num_structures + + basis = this%generate_structure( basis_store, & + placement_list, method_probab_ ) + +#ifdef ENABLE_ATHENA + !!----------------------------------------------------------------------- + !! predict energy using ML + !!----------------------------------------------------------------------- + graph(1) = get_graph_from_basis(this%lattice_host, basis) + write(*,*) "Predicted energy", network_predict_graph(graph(1:1)) +#endif + + end do structure_loop + write(*,*) "Finished generating structures" + + end subroutine generate + + + + module function generate_structure( & + this, & + basis_initial, & + placement_list, method_probab ) result(basis) + !! Generate a single random structure. + implicit none + ! Arguments + class(raffle_generator_type), intent(in) :: this + !! Instance of the raffle generator. + type(bas_type), intent(in) :: basis_initial + !! Initial basis to build upon. + integer, dimension(:,:), intent(in) :: placement_list + !! List of possible placements. + real(real12), dimension(3) :: method_probab + !! Probability of each placement method. + type(bas_type) :: basis + !! Generated basis. + + integer :: i, j, iplaced, void_ticker + integer :: num_insert_atoms + real(real12) :: rtmp1 + logical :: placed + integer, dimension(size(placement_list,1),size(placement_list,2)) :: & + placement_list_shuffled + real(real12), dimension(3) :: method_probab_ + real(real12), dimension(:,:), allocatable :: viable_gridpoints + + + + call clone_bas(basis_initial, basis) + num_insert_atoms = basis%natom - this%basis_host%natom + + placement_list_shuffled = placement_list + call shuffle(placement_list_shuffled,1) !!! NEED TO SORT OUT RANDOM SEED + + viable_gridpoints = get_viable_gridpoints( this%bins, & + this%lattice_host, basis, & + [ this%distributions%bond_info(:)%radius_covalent ], & + placement_list_shuffled ) + + method_probab_ = method_probab + + iplaced = 0 + void_ticker = 0 + placement_loop: do while (iplaced.lt.num_insert_atoms) + + !!! CHANGE THESE PLACEMENT SUBROUTINES TO FUNCTIONS THAT OUTPUT THE COORDINATE + !!! THEN, THIS LOOP ACTUALLY PLACES IT AT THE END + call random_number(rtmp1) + if(rtmp1.le.method_probab_(1)) then + if(verbose.gt.0) write(*,*) "Add Atom Void" + call add_atom_void( this%bins, & + this%lattice_host, basis, & + placement_list_shuffled(iplaced+1:,:), placed) + else if(rtmp1.le.method_probab_(2)) then + if(verbose.gt.0) write(*,*) "Add Atom Pseudo" + call add_atom_pseudo( this%bins, & + this%distributions, & + this%lattice_host, basis, & + placement_list_shuffled(iplaced+1:,:), & + [ this%distributions%bond_info(:)%radius_covalent ], & + placed ) + if(.not. placed) void_ticker = void_ticker + 1 + else if(rtmp1.le.method_probab_(3)) then + if(verbose.gt.0) write(*,*) "Add Atom Scan" + call add_atom_scan( viable_gridpoints, & + this%distributions, & + this%lattice_host, basis, & + placement_list_shuffled(iplaced+1:,:), & + [ this%distributions%bond_info(:)%radius_covalent ], & + placed) + end if + if(.not. placed) then + if(void_ticker.gt.10) & + call add_atom_void( this%bins, this%lattice_host, basis, & + placement_list_shuffled(iplaced+1:,:), placed) + void_ticker = 0 + if(.not.placed) cycle placement_loop + end if + if(verbose.gt.0)then + write(*,'(A)',ADVANCE='NO') achar(13) + write(*,*) "placed", placed + end if + iplaced = iplaced + 1 + if(allocated(viable_gridpoints)) & + call update_viable_gridpoints( viable_gridpoints, & + this%lattice_host, basis, & + [ placement_list_shuffled(iplaced,:) ], & + this%distributions%bond_info( & + ( basis%nspec - & + placement_list_shuffled(iplaced,1)/2 ) * & + ( placement_list_shuffled(iplaced,1) - 1 ) + & + placement_list_shuffled(iplaced,1) & + )%radius_covalent ) + if(.not.allocated(viable_gridpoints).and. & + abs( method_probab_(3) - method_probab_(2) ) .gt. 1.E-3) then + write(*,*) "WARNING: No more viable gridpoints" + write(*,*) "Suppressing SCAN method" + method_probab_ = method_probab_ / method_probab_(2) + method_probab_(3) = method_probab_(2) + end if + + end do placement_loop + + end function generate_structure + +end submodule generator_submodule \ No newline at end of file diff --git a/src/raffle.f90 b/src/raffle.f90 index 184914cb..d98a31db 100644 --- a/src/raffle.f90 +++ b/src/raffle.f90 @@ -1,120 +1,10 @@ module raffle - use constants, only: real12 - use gen, only: generation - use rw_geom, only: bas_type - use evolver, only: gvector_container_type + use generator, only: raffle_generator_type implicit none - private public :: raffle_generator_type - type :: stoichiometry_type - character(len=3) :: element - integer :: num - end type stoichiometry_type - - - type :: raffle_generator_type - real(real12), dimension(3,3) :: lattice_host - type(bas_type) :: basis_host - type(gvector_container_type) :: distributions - real(real12), dimension(3) :: method_probab - contains - procedure, pass(this) :: generate - !procedure :: get_structures - !procedure :: evaluate - end type raffle_generator_type - - interface raffle_generator_type - module function init_raffle_generator( & - lattice_host, basis_host, & - width, sigma, cutoff_min, cutoff_max) result(generator) - real(real12), dimension(3,3), intent(in) :: lattice_host - type(bas_type), intent(in) :: basis_host - real(real12), dimension(3), intent(in), optional :: width - real(real12), dimension(3), intent(in), optional :: sigma - real(real12), dimension(3), intent(in), optional :: cutoff_min - real(real12), dimension(3), intent(in), optional :: cutoff_max - type(raffle_generator_type) :: generator - end function init_raffle_generator - end interface raffle_generator_type - - interface - module subroutine generate( this, & - num_structures, stoichiometry, method_probab ) - class(raffle_generator_type), intent(inout) :: this - integer, intent(in) :: num_structures - type(stoichiometry_type), dimension(:), intent(in) :: stoichiometry - real(real12), dimension(:), intent(in) :: method_probab - end subroutine generate - end interface - - -contains - - module function init_raffle_generator( & - lattice_host, basis_host, width, sigma, cutoff_min, cutoff_max ) & - result(generator) - !! Initialise an instance of the raffle generator. - !! Set up run-independent parameters. - implicit none - ! Arguments - real(real12), dimension(3,3), intent(in) :: lattice_host - !! Lattice vectors of the host structure. - type(bas_type), intent(in) :: basis_host - !! Basis of the host structure. - real(real12), dimension(3), intent(in), optional :: width - !! Width of the gaussians used in the 2-, 3-, and 4-body - !! distribution functions. - real(real12), dimension(3), intent(in), optional :: sigma - !! Width of the gaussians used in the 2-, 3-, and 4-body - !! distribution functions. - real(real12), dimension(3), intent(in), optional :: cutoff_min - !! Minimum cutoff for the 2-, 3-, and 4-body distribution functions. - real(real12), dimension(3), intent(in), optional :: cutoff_max - !! Maximum cutoff for the 2-, 3-, and 4-body distribution functions. - - type(raffle_generator_type) :: generator - - - generator%lattice_host = lattice_host - generator%basis_host = basis_host - - if( present(width) ) & - call generator%distributions%set_width(width) - if( present(sigma) ) & - call generator%distributions%set_sigma(sigma) - if( present(cutoff_min) ) & - call generator%distributions%set_cutoff_min(cutoff_min) - if( present(cutoff_max) ) & - call generator%distributions%set_cutoff_max(cutoff_max) - - - end function init_raffle_generator - - - module subroutine generate( this, & - num_structures, stoichiometry, method_probab ) - !! Generate random structures. - implicit none - ! Arguments - class(raffle_generator_type), intent(inout) :: this - !! Instance of the raffle generator. - integer, intent(in) :: num_structures - !! Number of structures to generate. - type(stoichiometry_type), dimension(:), intent(in) :: stoichiometry - !! Stoichiometry of the structures to generate. - real(real12), dimension(:), intent(in) :: method_probab - !! Probability of each placement method. - - call generation( this%distributions, num_structures, & - stoichiometry(:)%element, stoichiometry(:)%num, & - method_probab ) - - end subroutine generate - - end module raffle \ No newline at end of file From 87cc21acfbfb657bf8e124686db0dbed3911fb4b Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Wed, 3 Jul 2024 10:43:18 +0100 Subject: [PATCH 016/293] Add option to turn off python library --- CMakeLists.txt | 137 +++++++++++++++++++++++++------------------------ 1 file changed, 71 insertions(+), 66 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e7d56fcb..b0910c3d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,6 +59,7 @@ enable_testing() option(BUILD_TESTS "Build the unit tests" ON) option(BUILD_EXAMPLES "Build the examples" ON) option(ENABLE_ATHENA "Build energetic predictions with ATHENA" OFF) +option(BUILD_PYTHON "Build the python library" On) # Define the sources set(SRC_DIR src) @@ -77,6 +78,8 @@ set(LIB_FILES mod_buildmap.f90 mod_atom_adder.f90 mod_read_structures.f90 + mod_generator.f90 + mod_generator_sub.f90 ) @@ -108,13 +111,13 @@ message(STATUS "Modified LIB_FILES: ${PREPENDED_LIB_FILES}") -set(EXTRA_SRC_FILES - inputs.f90 - generator.f90 -) -foreach(src ${EXTRA_SRC_FILES}) - list(APPEND PREPENDED_SRC_FILES ${SRC_DIR}/${src}) -endforeach() +# set(EXTRA_SRC_FILES +# inputs.f90 +# generator.f90 +# ) +# foreach(src ${EXTRA_SRC_FILES}) +# list(APPEND PREPENDED_SRC_FILES ${SRC_DIR}/${src}) +# endforeach() set(SRC_FILES raffle.f90 @@ -214,81 +217,83 @@ endif() -# # Get the directory where object files are generated -get_target_property(OBJECTS ${PROJECT_NAME} EXTERNAL_OBJECT) -# Print the object files directory -set(OBJECTS_DIR ${CMAKE_BUILD_PREFIX}/CMakeFiles/${PROJECT_NAME}.dir) -message(STATUS "Object files directory for ${PROJECT_NAME}: ${OBJECTS_DIR}") +if (BUILD_PYTHON) + # # Get the directory where object files are generated + get_target_property(OBJECTS ${PROJECT_NAME} EXTERNAL_OBJECT) + # Print the object files directory + set(OBJECTS_DIR ${CMAKE_BUILD_PREFIX}/CMakeFiles/${PROJECT_NAME}.dir) + message(STATUS "Object files directory for ${PROJECT_NAME}: ${OBJECTS_DIR}") -# Include f90wrap -find_package(Python3 REQUIRED COMPONENTS Interpreter Development) -find_program(F90WRAP_EXECUTABLE f90wrap) -find_program(F2PY_EXECUTABLE f2py-f90wrap) -if(NOT F90WRAP_EXECUTABLE) - message(FATAL_ERROR "f90wrap not found. Please install f90wrap.") -endif() + # Include f90wrap + find_package(Python3 REQUIRED COMPONENTS Interpreter Development) + find_program(F90WRAP_EXECUTABLE f90wrap) + find_program(F2PY_EXECUTABLE f2py-f90wrap) -# Generate f90wrap signature file -set(F90WRAP_FILE ${CMAKE_BINARY_DIR}/f90wrap_${PROJECT_NAME}.f90) -set(KIND_MAP ${CMAKE_SOURCE_DIR}/kind_map) -add_custom_command( - TARGET ${PROJECT_NAME} - POST_BUILD - COMMAND ${F90WRAP_EXECUTABLE} - --default-to-inout - -m ${PROJECT_NAME} - -k ${KIND_MAP} - ${F90WRAP_FORTRAN_SRC_FILES} - --only raffle_generator_type: - DEPENDS ${F90WRAP_FORTRAN_SRC_FILES} - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - COMMENT "Generating f90wrap signature file" - VERBATIM -) + if(NOT F90WRAP_EXECUTABLE) + message(FATAL_ERROR "f90wrap not found. Please install f90wrap.") + endif() -# Create a Python module using f2py -add_custom_command( - TARGET ${PROJECT_NAME} - POST_BUILD - COMMAND ${F2PY_EXECUTABLE} - ${F2PY_ATHENA_LIBRARY_FLAGS} - -I${MODULE_DIR} - -c - -m _${PROJECT_NAME} - --f90flags="${PPFLAGS}" - ${F90WRAP_FILE} - ${OBJECTS_DIR}/src/*.o - ${OBJECTS_DIR}/src/lib/*.o - DEPENDS ${F90WRAP_FILE} - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - COMMENT "Creating Python module using f2py" -) + # Generate f90wrap signature file + set(F90WRAP_FILE ${CMAKE_BINARY_DIR}/f90wrap_${PROJECT_NAME}.f90) + set(KIND_MAP ${CMAKE_SOURCE_DIR}/kind_map) + add_custom_command( + TARGET ${PROJECT_NAME} + POST_BUILD + COMMAND ${F90WRAP_EXECUTABLE} + --default-to-inout + -m ${PROJECT_NAME} + -k ${KIND_MAP} + ${F90WRAP_FORTRAN_SRC_FILES} + --only raffle_generator_type: + DEPENDS ${F90WRAP_FORTRAN_SRC_FILES} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Generating f90wrap signature file" + VERBATIM + ) + # Create a Python module using f2py + add_custom_command( + TARGET ${PROJECT_NAME} + POST_BUILD + COMMAND ${F2PY_EXECUTABLE} + ${F2PY_ATHENA_LIBRARY_FLAGS} + -I${MODULE_DIR} + -c + -m _${PROJECT_NAME} + --f90flags="${PPFLAGS}" + ${F90WRAP_FILE} + ${OBJECTS_DIR}/src/*.o + ${OBJECTS_DIR}/src/lib/*.o + DEPENDS ${F90WRAP_FILE} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Creating Python module using f2py" + ) -# Define output files -set(PY_MODULE ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.py) -file(GLOB SO_MODULE "${CMAKE_BINARY_DIR}/_${PROJECT_NAME}*.so") -# Create a custom target for the Python module -add_custom_target(python_module ALL - DEPENDS ${SO_MODULE} ${PY_MODULE} -) + # Define output files + set(PY_MODULE ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.py) + file(GLOB SO_MODULE "${CMAKE_BINARY_DIR}/_${PROJECT_NAME}*.so") -# Installation instructions -install(FILES ${PY_MODULE} DESTINATION lib) -install(FILES ${SO_MODULE} DESTINATION lib) + # Create a custom target for the Python module + add_custom_target(python_module ALL + DEPENDS ${SO_MODULE} ${PY_MODULE} + ) + + # Installation instructions + install(FILES ${PY_MODULE} DESTINATION lib) + install(FILES ${SO_MODULE} DESTINATION lib) +endif() -# install(DIRECTORY ${CMAKE_BINARY_DIR}/mod/ DESTINATION include) # Print helpful messages message(STATUS "Build configuration:") message(STATUS " Source directory: ${SRC_DIR}") message(STATUS " Output library: ${PROJECT_NAME}") -message(STATUS " Fortran modules directory: ${CMAKE_BINARY_DIR}/mod") -message(STATUS " Python module: ${PROJECT_NAME}.so") +# message(STATUS " Fortran modules directory: ${CMAKE_BINARY_DIR}/mod") +# message(STATUS " Python module: ${PROJECT_NAME}.so") From 436e110d4cdce1864a60cb62317260959f5533e1 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Wed, 3 Jul 2024 11:51:11 +0100 Subject: [PATCH 017/293] Improve commenting --- src/lib/mod_generator_sub.f90 | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/lib/mod_generator_sub.f90 b/src/lib/mod_generator_sub.f90 index ecc7da3b..06ecbf77 100644 --- a/src/lib/mod_generator_sub.f90 +++ b/src/lib/mod_generator_sub.f90 @@ -112,6 +112,14 @@ module subroutine generate(this, num_structures, & end do basis_store = bas_merge(this%basis_host,basis_store) + + !!-------------------------------------------------------------------------- + !! generate the placement list + !! placement list is the list of number of atoms of each species that can be + !! placed in the structure + !! ... the second dimension is the index of the species and atom in the + !! ... basis_store + !!-------------------------------------------------------------------------- allocate(placement_list(num_insert_atoms,2)) k = 0 spec_loop1: do i = 1, basis_store%nspec From edae70e4829bc661c3c70392ae543978c1b09cbf Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Wed, 3 Jul 2024 12:40:40 +0100 Subject: [PATCH 018/293] Remove commented section --- src/lib/mod_read_structures.f90 | 62 --------------------------------- 1 file changed, 62 deletions(-) diff --git a/src/lib/mod_read_structures.f90 b/src/lib/mod_read_structures.f90 index 02771dbe..b1dc8046 100644 --- a/src/lib/mod_read_structures.f90 +++ b/src/lib/mod_read_structures.f90 @@ -191,69 +191,7 @@ function get_evolved_gvectors_from_data(input_dir, & call gvector_container%evolve(deallocate_systems_after_evolve=.false.) - !!! do not deallocate structures - !!! then load the athena library - !!! set up the network - !!! append 2, 3, and 4 body potentials - !!! HOW DO WE HANDLE SPECIES? - !!! A network for each species? - !!! split dataset into train and test sets - !!! train the network - - ! num_structures = size(gvector_container%system) - ! write(*,*) "LOOKY", gvector_container%nbins - ! allocate(dataset(sum(gvector_container%nbins), num_structures)) - ! do i = 1, num_structures - ! dataset(1:gvector_container%nbins(1),i) = & - ! sum(gvector_container%system(i)%df_2body,dim=2) - ! dataset(gvector_container%nbins(1)+1:& - ! sum(gvector_container%nbins(1:2)),i) = & - ! sum(gvector_container%system(i)%df_3body,dim=2) - ! dataset(sum(gvector_container%nbins(1:2))+1:& - ! sum(gvector_container%nbins(1:3)),i) = & - ! sum(gvector_container%system(i)%df_4body,dim=2) - ! end do - ! allocate(labels(num_structures)) - ! labels = [ gvector_container%system(:)%energy / gvector_container%system(:)%num_atoms ] - - ! call random_setup(1) - ! call split( dataset, labels, & - ! data_train, data_validate, & - ! labels_train, labels_validate, & - ! dim=2, left_size=0.8, right_size=0.2, shuffle=.true., seed=1) - - ! call network_setup(num_inputs = sum(gvector_container%nbins), & - ! num_outputs = 1) - ! call network_train(data_train, labels_train, num_epochs = 100) - - ! write(*,*) "predicting known" - ! write(*,*) -1._real12 * network_predict(data_train(:,1:10)) * sqrt(dot_product(labels_train, labels_train)) - ! write(*,*) labels_train(1:10) - ! write(*,*) - - ! write(*,*) "PREDICTING" - ! write(*,*) "norm", sqrt(dot_product(labels_train, labels_train)) - ! write(*,*) -1._real12 * network_predict(data_validate) * sqrt(dot_product(labels_train, labels_train)) - ! write(*,*) labels_validate - - ! write(*,*) "LABELS" - ! write(*,*) size(labels) - ! write(*,*) labels - ! call network_setup(num_inputs = 2, num_outputs = 1) - ! call network_train_graph(graphs(:size(graphs)-10), labels(:size(graphs)-10), num_epochs = 100) - - - ! write(*,*) "predicting known" - ! write(*,*) network_predict_graph(graphs(:size(graphs)-10)) - ! write(*,*) labels(:size(graphs)-10) - ! write(*,*) - - ! write(*,*) "PREDICTING" - ! write(*,*) network_predict_graph(graphs(size(graphs)-10+1:)) - ! write(*,*) labels(size(graphs)-10+1:) - ! write(*,*) - #ifdef ENABLE_ATHENA call network_setup(num_inputs = 2, num_outputs = 1) call network_train_graph(graphs(:), labels(:), num_epochs = 200) From 7aed53e2fbb969698d9a77a6ef2c9909fc12e1e4 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Wed, 3 Jul 2024 12:41:02 +0100 Subject: [PATCH 019/293] Add create and update procedures --- src/lib/mod_evolver.f90 | 45 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/lib/mod_evolver.f90 b/src/lib/mod_evolver.f90 index cb027b72..386bbcb0 100644 --- a/src/lib/mod_evolver.f90 +++ b/src/lib/mod_evolver.f90 @@ -52,6 +52,9 @@ module evolver procedure, pass(this) :: set_sigma procedure, pass(this) :: set_cutoff_min procedure, pass(this) :: set_cutoff_max + + procedure, pass(this) :: create + procedure, pass(this) :: update procedure, pass(this) :: add, add_basis procedure, pass(this) :: set_element_info @@ -185,6 +188,42 @@ subroutine set_cutoff_max(this, cutoff_max) end subroutine set_cutoff_max + subroutine create(this, basis_list, lattice_list) + !! create the distribution functions from the input file + implicit none + ! Arguments + class(gvector_container_type), intent(inout) :: this + !! Self, parent of the procedure. + type(bas_type), dimension(:), intent(in) :: basis_list + !! List of basis structures. + real(real12), dimension(:,:,:), intent(in) :: lattice_list + !! List of lattice vectors for each basis structure. + + deallocate(this%total%df_2body, this%total%df_3body, this%total%df_4body) + call this%add(basis_list, lattice_list) + call this%evolve() + + end subroutine create + + + subroutine update(this, basis_list, lattice_list) + !! update the distribution functions from the input file + implicit none + ! Arguments + class(gvector_container_type), intent(inout) :: this + !! Self, parent of the procedure. + type(bas_type), dimension(:), intent(in) :: basis_list + !! List of basis structures. + real(real12), dimension(:,:,:), intent(in) :: lattice_list + !! List of lattice vectors for each basis structure. + + + call this%add(basis_list, lattice_list) + call this%evolve() + + end subroutine update + + !!!############################################################################# !!! write all systems !!!############################################################################# @@ -730,7 +769,7 @@ subroutine evolve(this, system, deallocate_systems_after_evolve) integer :: idx1, idx2 integer :: i, j, is, js, num_structures_previous - real(real12) :: weight, energy + real(real12) :: weight, energy, best_energy_old logical :: deallocate_systems_after_evolve_ = .true. real(real12), dimension(:), allocatable :: height integer, dimension(:,:), allocatable :: idx_list @@ -758,6 +797,7 @@ subroutine evolve(this, system, deallocate_systems_after_evolve) !!-------------------------------------------------------------------------- !! get the energy from the lowest formation energy system !!-------------------------------------------------------------------------- + best_energy_old = this%best_energy call this%set_best_energy() @@ -766,6 +806,9 @@ subroutine evolve(this, system, deallocate_systems_after_evolve) !!-------------------------------------------------------------------------- if(.not.allocated(this%total%df_2body))then call this%initialise_gvectors() + else + this%total%df_3body = this%total%df_3body * exp( this%best_energy ) / & + exp( best_energy_old ) end if From 096ac9fe9f798e789b3c3ac5b1d597b0a1630a0b Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Wed, 3 Jul 2024 13:03:05 +0100 Subject: [PATCH 020/293] Remove public access to gvector_type --- src/lib/mod_evolver.f90 | 2 +- src/lib/mod_read_structures.f90 | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/lib/mod_evolver.f90 b/src/lib/mod_evolver.f90 index 386bbcb0..f6818ea7 100644 --- a/src/lib/mod_evolver.f90 +++ b/src/lib/mod_evolver.f90 @@ -13,7 +13,7 @@ module evolver private - public :: gvector_type, gvector_container_type + public :: gvector_container_type type :: gvector_base_type diff --git a/src/lib/mod_read_structures.f90 b/src/lib/mod_read_structures.f90 index b1dc8046..9ea98946 100644 --- a/src/lib/mod_read_structures.f90 +++ b/src/lib/mod_read_structures.f90 @@ -4,7 +4,7 @@ module read_structures use misc_linalg, only: modu use rw_geom, only: bas_type, geom_read, geom_write, igeom_input use rw_vasprun, only: get_energy_from_vasprun, get_structure_from_vasprun - use evolver, only: gvector_container_type, gvector_type + use evolver, only: gvector_container_type #ifdef ENABLE_ATHENA use machine_learning, only: network_setup, & network_train, network_train_graph, & @@ -49,7 +49,6 @@ function get_evolved_gvectors_from_data(input_dir, & integer :: xml_unit, unit, ierror integer :: num_files type(bas_type) :: basis - type(gvector_type) :: gvector real(real12), dimension(3,3) :: lattice character(256), dimension(:), allocatable :: structure_list #ifdef ENABLE_ATHENA @@ -191,7 +190,7 @@ function get_evolved_gvectors_from_data(input_dir, & call gvector_container%evolve(deallocate_systems_after_evolve=.false.) - + #ifdef ENABLE_ATHENA call network_setup(num_inputs = 2, num_outputs = 1) call network_train_graph(graphs(:), labels(:), num_epochs = 200) From be1a2c7d10780e77dea3db074f8e3c5ee489e296 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Wed, 3 Jul 2024 13:07:30 +0100 Subject: [PATCH 021/293] Handle special library files for f2py --- CMakeLists.txt | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b0910c3d..002c4854 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,8 +78,11 @@ set(LIB_FILES mod_buildmap.f90 mod_atom_adder.f90 mod_read_structures.f90 +) + +set(SPECIAL_LIB_FILES mod_generator.f90 - mod_generator_sub.f90 + # mod_generator_sub.f90 ) @@ -106,22 +109,19 @@ endif() foreach(lib ${LIB_FILES}) list(APPEND PREPENDED_LIB_FILES ${LIB_DIR}/${lib}) endforeach() +foreach(lib ${SPECIAL_LIB_FILES}) + list(APPEND PREPENDED_LIB_FILES ${LIB_DIR}/${lib}) +endforeach() message(STATUS "Modified LIB_FILES: ${PREPENDED_LIB_FILES}") - -# set(EXTRA_SRC_FILES -# inputs.f90 -# generator.f90 -# ) -# foreach(src ${EXTRA_SRC_FILES}) -# list(APPEND PREPENDED_SRC_FILES ${SRC_DIR}/${src}) -# endforeach() - set(SRC_FILES raffle.f90 ) +foreach(lib ${SPECIAL_LIB_FILES}) + list(APPEND F90WRAP_FORTRAN_SRC_FILES ${CMAKE_CURRENT_LIST_DIR}/${LIB_DIR}/${lib}) +endforeach() foreach(src ${SRC_FILES}) list(APPEND F90WRAP_FORTRAN_SRC_FILES ${CMAKE_CURRENT_LIST_DIR}/${SRC_DIR}/${src}) list(APPEND PREPENDED_SRC_FILES ${SRC_DIR}/${src}) @@ -236,7 +236,7 @@ if (BUILD_PYTHON) endif() # Generate f90wrap signature file - set(F90WRAP_FILE ${CMAKE_BINARY_DIR}/f90wrap_${PROJECT_NAME}.f90) + set(F90WRAP_FILE ${CMAKE_BINARY_DIR}/f90wrap_*.f90) set(KIND_MAP ${CMAKE_SOURCE_DIR}/kind_map) add_custom_command( TARGET ${PROJECT_NAME} From 5c208d176aa6902eaa80e7a97cab1f6e05306f1d Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Wed, 17 Jul 2024 15:07:29 +0100 Subject: [PATCH 022/293] Edit autogenerated wrapper files --- CMakeLists.txt | 11 +- .../f90wrap_mod_generator.f90 | 374 ++++++++++++++++++ edited_autogen_files/raffle.py | 369 +++++++++++++++++ src/lib/mod_generator.f90 | 324 +++++++++++++-- 4 files changed, 1055 insertions(+), 23 deletions(-) create mode 100644 edited_autogen_files/f90wrap_mod_generator.f90 create mode 100644 edited_autogen_files/raffle.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 002c4854..dea88803 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,6 +81,7 @@ set(LIB_FILES ) set(SPECIAL_LIB_FILES + # mod_rw_geom.f90 mod_generator.f90 # mod_generator_sub.f90 ) @@ -246,13 +247,21 @@ if (BUILD_PYTHON) -m ${PROJECT_NAME} -k ${KIND_MAP} ${F90WRAP_FORTRAN_SRC_FILES} - --only raffle_generator_type: + # --only raffle_generator_type: DEPENDS ${F90WRAP_FORTRAN_SRC_FILES} WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMENT "Generating f90wrap signature file" VERBATIM ) + # Copy f90wrap edited files from edited_autogen_files to ${CMAKE_BINARY_DIR} + add_custom_command( + TARGET ${PROJECT_NAME} + POST_BUILD + COMMAND cp ${CMAKE_CURRENT_LIST_DIR}/edited_autogen_files/* ${CMAKE_BINARY_DIR} + COMMENT "Copying f90wrap edited files" + ) + # Create a Python module using f2py add_custom_command( TARGET ${PROJECT_NAME} diff --git a/edited_autogen_files/f90wrap_mod_generator.f90 b/edited_autogen_files/f90wrap_mod_generator.f90 new file mode 100644 index 00000000..1346bff4 --- /dev/null +++ b/edited_autogen_files/f90wrap_mod_generator.f90 @@ -0,0 +1,374 @@ +! Module generator defined in file /Users/nedtaylor/DCoding/DGit/raffle/src/lib/mod_generator.f90 + +subroutine f90wrap_stoichiometry_type__get__element(this, f90wrap_element) + use generator, only: stoichiometry_type + implicit none + type stoichiometry_type_ptr_type + type(stoichiometry_type), pointer :: p => NULL() + end type stoichiometry_type_ptr_type + integer, intent(in) :: this(2) + type(stoichiometry_type_ptr_type) :: this_ptr + character(3), intent(out) :: f90wrap_element + + this_ptr = transfer(this, this_ptr) + f90wrap_element = this_ptr%p%element +end subroutine f90wrap_stoichiometry_type__get__element + +subroutine f90wrap_stoichiometry_type__set__element(this, f90wrap_element) + use generator, only: stoichiometry_type + implicit none + type stoichiometry_type_ptr_type + type(stoichiometry_type), pointer :: p => NULL() + end type stoichiometry_type_ptr_type + integer, intent(in) :: this(2) + type(stoichiometry_type_ptr_type) :: this_ptr + character(3), intent(in) :: f90wrap_element + + this_ptr = transfer(this, this_ptr) + this_ptr%p%element = f90wrap_element +end subroutine f90wrap_stoichiometry_type__set__element + +subroutine f90wrap_stoichiometry_type__get__num(this, f90wrap_num) + use generator, only: stoichiometry_type + implicit none + type stoichiometry_type_ptr_type + type(stoichiometry_type), pointer :: p => NULL() + end type stoichiometry_type_ptr_type + integer, intent(in) :: this(2) + type(stoichiometry_type_ptr_type) :: this_ptr + integer, intent(out) :: f90wrap_num + + this_ptr = transfer(this, this_ptr) + f90wrap_num = this_ptr%p%num +end subroutine f90wrap_stoichiometry_type__get__num + +subroutine f90wrap_stoichiometry_type__set__num(this, f90wrap_num) + use generator, only: stoichiometry_type + implicit none + type stoichiometry_type_ptr_type + type(stoichiometry_type), pointer :: p => NULL() + end type stoichiometry_type_ptr_type + integer, intent(in) :: this(2) + type(stoichiometry_type_ptr_type) :: this_ptr + integer, intent(in) :: f90wrap_num + + this_ptr = transfer(this, this_ptr) + this_ptr%p%num = f90wrap_num +end subroutine f90wrap_stoichiometry_type__set__num + +subroutine f90wrap_stoichiometry_type_initialise(this) + use generator, only: stoichiometry_type + implicit none + + type stoichiometry_type_ptr_type + type(stoichiometry_type), pointer :: p => NULL() + end type stoichiometry_type_ptr_type + type(stoichiometry_type_ptr_type) :: this_ptr + integer, intent(out), dimension(2) :: this + allocate(this_ptr%p) + this = transfer(this_ptr, this) +end subroutine f90wrap_stoichiometry_type_initialise + +subroutine f90wrap_stoichiometry_type_finalise(this) + use generator, only: stoichiometry_type + implicit none + + type stoichiometry_type_ptr_type + type(stoichiometry_type), pointer :: p => NULL() + end type stoichiometry_type_ptr_type + type(stoichiometry_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + this_ptr = transfer(this, this_ptr) + deallocate(this_ptr%p) +end subroutine f90wrap_stoichiometry_type_finalise + + +subroutine f90wrap_stoich_type_xnum_array__array_getitem__items( & + this, f90wrap_i, itemsitem) + use generator, only: stoichiometry_type + implicit none + + type stoichiometry_type_xnum_array + type(stoichiometry_type), dimension(:), allocatable :: items + end type stoichiometry_type_xnum_array + + type stoichiometry_type_xnum_array_ptr_type + type(stoichiometry_type_xnum_array), pointer :: p => NULL() + end type stoichiometry_type_xnum_array_ptr_type + type stoichiometry_type_ptr_type + type(stoichiometry_type), pointer :: p => NULL() + end type stoichiometry_type_ptr_type + integer, intent(in), dimension(2) :: this + type(stoichiometry_type_xnum_array_ptr_type) :: this_ptr + integer, intent(in) :: f90wrap_i + integer, intent(out) :: itemsitem(2) + type(stoichiometry_type_ptr_type) :: items_ptr + + this_ptr = transfer(this, this_ptr) + if (f90wrap_i < 1 .or. f90wrap_i > size(this_ptr%p%items)) then + call f90wrap_abort("array index out of range") + else + items_ptr%p => this_ptr%p%items(f90wrap_i) + itemsitem = transfer(items_ptr,itemsitem) + endif +end subroutine f90wrap_stoich_type_xnum_array__array_getitem__items + +subroutine f90wrap_stoich_type_xnum_array__array_setitem__items(this, f90wrap_i, itemsitem) + use generator, only: stoichiometry_type + implicit none + + type stoichiometry_type_xnum_array + type(stoichiometry_type), dimension(:), allocatable :: items + end type stoichiometry_type_xnum_array + + type stoichiometry_type_xnum_array_ptr_type + type(stoichiometry_type_xnum_array), pointer :: p => NULL() + end type stoichiometry_type_xnum_array_ptr_type + type stoichiometry_type_ptr_type + type(stoichiometry_type), pointer :: p => NULL() + end type stoichiometry_type_ptr_type + integer, intent(in), dimension(2) :: this + type(stoichiometry_type_xnum_array_ptr_type) :: this_ptr + integer, intent(in) :: f90wrap_i + integer, intent(out) :: itemsitem(2) + type(stoichiometry_type_ptr_type) :: items_ptr + + this_ptr = transfer(this, this_ptr) + if (f90wrap_i < 1 .or. f90wrap_i > size(this_ptr%p%items)) then + call f90wrap_abort("array index out of range") + else + items_ptr = transfer(itemsitem,items_ptr) + this_ptr%p%items(f90wrap_i) = items_ptr%p + endif +end subroutine f90wrap_stoich_type_xnum_array__array_setitem__items + +subroutine f90wrap_stoich_type_xnum_array__array_len__items(this, f90wrap_n) + use generator, only: stoichiometry_type + implicit none + + type stoichiometry_type_xnum_array + type(stoichiometry_type), dimension(:), allocatable :: items + end type stoichiometry_type_xnum_array + + type stoichiometry_type_xnum_array_ptr_type + type(stoichiometry_type_xnum_array), pointer :: p => NULL() + end type stoichiometry_type_xnum_array_ptr_type + integer, intent(in), dimension(2) :: this + type(stoichiometry_type_xnum_array_ptr_type) :: this_ptr + integer, intent(out) :: f90wrap_n + this_ptr = transfer(this, this_ptr) + f90wrap_n = size(this_ptr%p%items) +end subroutine f90wrap_stoich_type_xnum_array__array_len__items + +subroutine f90wrap_stoich_type_xnum_array__array_alloc__items(this, num) + use generator, only: stoichiometry_type + implicit none + + type stoichiometry_type_xnum_array + type(stoichiometry_type), dimension(:), allocatable :: items + end type stoichiometry_type_xnum_array + + type stoichiometry_type_xnum_array_ptr_type + type(stoichiometry_type_xnum_array), pointer :: p => NULL() + end type stoichiometry_type_xnum_array_ptr_type + type(stoichiometry_type_xnum_array_ptr_type) :: this_ptr + integer, intent(in) :: num + integer, intent(inout), dimension(2) :: this + + this_ptr = transfer(this, this_ptr) + allocate(this_ptr%p%items(num)) + this = transfer(this_ptr, this) +end subroutine f90wrap_stoich_type_xnum_array__array_alloc__items + +subroutine f90wrap_stoich_type_xnum_array__array_dealloc__items(this) + use generator, only: stoichiometry_type + implicit none + + type stoichiometry_type_xnum_array + type(stoichiometry_type), dimension(:), allocatable :: items + end type stoichiometry_type_xnum_array + + type stoichiometry_type_xnum_array_ptr_type + type(stoichiometry_type_xnum_array), pointer :: p => NULL() + end type stoichiometry_type_xnum_array_ptr_type + type(stoichiometry_type_xnum_array_ptr_type) :: this_ptr + integer, intent(inout), dimension(2) :: this + + this_ptr = transfer(this, this_ptr) + deallocate(this_ptr%p%items) + this = transfer(this_ptr, this) +end subroutine f90wrap_stoich_type_xnum_array__array_dealloc__items + + +subroutine f90wrap_generator__stoich_type_xnum_array_initialise(this) + use generator, only: stoichiometry_type + implicit none + + type stoichiometry_type_xnum_array + type(stoichiometry_type), dimension(:), allocatable :: items + end type stoichiometry_type_xnum_array + + type stoichiometry_type_xnum_array_ptr_type + type(stoichiometry_type_xnum_array), pointer :: p => NULL() + end type stoichiometry_type_xnum_array_ptr_type + type(stoichiometry_type_xnum_array_ptr_type) :: this_ptr + integer, intent(out), dimension(2) :: this + allocate(this_ptr%p) + this = transfer(this_ptr, this) +end subroutine f90wrap_generator__stoich_type_xnum_array_initialise + +subroutine f90wrap_generator__stoich_type_xnum_array_finalise(this) + use generator, only: stoichiometry_type + implicit none + + type stoichiometry_type_xnum_array + type(stoichiometry_type), dimension(:), allocatable :: items + end type stoichiometry_type_xnum_array + + type stoichiometry_type_xnum_array_ptr_type + type(stoichiometry_type_xnum_array), pointer :: p => NULL() + end type stoichiometry_type_xnum_array_ptr_type + type(stoichiometry_type_xnum_array_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + this_ptr = transfer(this, this_ptr) + deallocate(this_ptr%p) +end subroutine f90wrap_generator__stoich_type_xnum_array_finalise + + + + +subroutine f90wrap_raffle_generator_type__array__bins(this, nd, dtype, dshape, dloc) + use generator, only: raffle_generator_type + use, intrinsic :: iso_c_binding, only : c_int + implicit none + type raffle_generator_type_ptr_type + type(raffle_generator_type), pointer :: p => NULL() + end type raffle_generator_type_ptr_type + integer(c_int), intent(in) :: this(2) + type(raffle_generator_type_ptr_type) :: this_ptr + integer(c_int), intent(out) :: nd + integer(c_int), intent(out) :: dtype + integer(c_int), dimension(10), intent(out) :: dshape + integer*8, intent(out) :: dloc + + nd = 1 + dtype = 5 + this_ptr = transfer(this, this_ptr) + dshape(1:1) = shape(this_ptr%p%bins) + dloc = loc(this_ptr%p%bins) +end subroutine f90wrap_raffle_generator_type__array__bins + +subroutine f90wrap_raffle_generator_type__array__lattice_host(this, nd, dtype, dshape, dloc) + use generator, only: raffle_generator_type + use, intrinsic :: iso_c_binding, only : c_int + implicit none + type raffle_generator_type_ptr_type + type(raffle_generator_type), pointer :: p => NULL() + end type raffle_generator_type_ptr_type + integer(c_int), intent(in) :: this(2) + type(raffle_generator_type_ptr_type) :: this_ptr + integer(c_int), intent(out) :: nd + integer(c_int), intent(out) :: dtype + integer(c_int), dimension(10), intent(out) :: dshape + integer*8, intent(out) :: dloc + + nd = 2 + dtype = 11 + this_ptr = transfer(this, this_ptr) + dshape(1:2) = shape(this_ptr%p%lattice_host) + dloc = loc(this_ptr%p%lattice_host) +end subroutine f90wrap_raffle_generator_type__array__lattice_host + +subroutine f90wrap_raffle_generator_type__array__method_probab(this, nd, dtype, dshape, dloc) + use generator, only: raffle_generator_type + use, intrinsic :: iso_c_binding, only : c_int + implicit none + type raffle_generator_type_ptr_type + type(raffle_generator_type), pointer :: p => NULL() + end type raffle_generator_type_ptr_type + integer(c_int), intent(in) :: this(2) + type(raffle_generator_type_ptr_type) :: this_ptr + integer(c_int), intent(out) :: nd + integer(c_int), intent(out) :: dtype + integer(c_int), dimension(10), intent(out) :: dshape + integer*8, intent(out) :: dloc + + nd = 1 + dtype = 11 + this_ptr = transfer(this, this_ptr) + dshape(1:1) = shape(this_ptr%p%method_probab) + dloc = loc(this_ptr%p%method_probab) +end subroutine f90wrap_raffle_generator_type__array__method_probab + +subroutine f90wrap_generator__raffle_generator_type_initialise(this) + use generator, only: raffle_generator_type + implicit none + + type raffle_generator_type_ptr_type + type(raffle_generator_type), pointer :: p => NULL() + end type raffle_generator_type_ptr_type + type(raffle_generator_type_ptr_type) :: this_ptr + integer, intent(out), dimension(2) :: this + allocate(this_ptr%p) + this = transfer(this_ptr, this) +end subroutine f90wrap_generator__raffle_generator_type_initialise + +subroutine f90wrap_generator__raffle_generator_type_finalise(this) + use generator, only: raffle_generator_type + implicit none + + type raffle_generator_type_ptr_type + type(raffle_generator_type), pointer :: p => NULL() + end type raffle_generator_type_ptr_type + type(raffle_generator_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + this_ptr = transfer(this, this_ptr) + deallocate(this_ptr%p) +end subroutine f90wrap_generator__raffle_generator_type_finalise + +subroutine f90wrap_generator__generate__binding__raffle_generator_type(this, num_structures, stoichiometry, & + method_probab, n0) + use generator, only: raffle_generator_type, stoichiometry_type + implicit none + + type raffle_generator_type_ptr_type + type(raffle_generator_type), pointer :: p => NULL() + end type raffle_generator_type_ptr_type + + + type stoichiometry_type_xnum_array + type(stoichiometry_type), dimension(:), allocatable :: items + end type stoichiometry_type_xnum_array + + type stoichiometry_type_xnum_array_ptr_type + type(stoichiometry_type_xnum_array), pointer :: p => NULL() + end type stoichiometry_type_xnum_array_ptr_type + type(raffle_generator_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + integer, intent(in) :: num_structures + type(stoichiometry_type_xnum_array_ptr_type) :: stoichiometry_ptr + integer, intent(in), dimension(2) :: stoichiometry + real(4), intent(in), optional, dimension(n0) :: method_probab + integer :: n0 + !f2py intent(hide), depend(method_probab) :: n0 = shape(method_probab,0) + this_ptr = transfer(this, this_ptr) + stoichiometry_ptr = transfer(stoichiometry, stoichiometry_ptr) + call this_ptr%p%generate(num_structures=num_structures, stoichiometry=stoichiometry_ptr%p%items, & + method_probab=method_probab) +end subroutine f90wrap_generator__generate__binding__raffle_generator_type + +subroutine f90wrap_generator__print_hello__binding__raffle_generator_type(this) + use generator, only: raffle_generator_type + implicit none + + type raffle_generator_type_ptr_type + type(raffle_generator_type), pointer :: p => NULL() + end type raffle_generator_type_ptr_type + type(raffle_generator_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + this_ptr = transfer(this, this_ptr) + call this_ptr%p%print_hello() +end subroutine f90wrap_generator__print_hello__binding__raffle_generator_type + +! End of module generator defined in file /Users/nedtaylor/DCoding/DGit/raffle/src/lib/mod_generator.f90 + diff --git a/edited_autogen_files/raffle.py b/edited_autogen_files/raffle.py new file mode 100644 index 00000000..a0f6b184 --- /dev/null +++ b/edited_autogen_files/raffle.py @@ -0,0 +1,369 @@ +from __future__ import print_function, absolute_import, division +import _raffle +import f90wrap.runtime +import logging +import numpy + +class Generator(f90wrap.runtime.FortranModule): + """ + Module generator + + + Defined at ../src/lib/mod_generator.f90 lines \ + 1-286 + + """ + @f90wrap.runtime.register_class("raffle.stoichiometry_type") + class stoichiometry_type(f90wrap.runtime.FortranDerivedType): + """ + Type(name=stoichiometry_type) + + + Defined at ../src/lib/mod_generator.f90 lines \ + 19-21 + + """ + def __init__(self, handle=None): + """ + self = Stoichiometry_Type() + + + Defined at ../src/lib/mod_generator.f90 lines \ + 19-21 + + + Returns + ------- + this : Stoichiometry_Type + Object to be constructed + + + Automatically generated constructor for stoichiometry_type + """ + f90wrap.runtime.FortranDerivedType.__init__(self) + result = _raffle.f90wrap_generator__stoichiometry_type_initialise() + self._handle = result[0] if isinstance(result, tuple) else result + + def __del__(self): + """ + Destructor for class Stoichiometry_Type + + + Defined at ../src/lib/mod_generator.f90 lines \ + 19-21 + + Parameters + ---------- + this : Stoichiometry_Type + Object to be destructed + + + Automatically generated destructor for stoichiometry_type + """ + if self._alloc: + _raffle.f90wrap_generator__stoichiometry_type_finalise(this=self._handle) + + @property + def element(self): + """ + Element element ftype=character(len=3) pytype=str + + + Defined at ../src/lib/mod_generator.f90 line \ + 20 + + """ + return _raffle.f90wrap_stoichiometry_type__get__element(self._handle) + + @element.setter + def element(self, element): + _raffle.f90wrap_stoichiometry_type__set__element(self._handle, element) + + @property + def num(self): + """ + Element num ftype=integer pytype=int + + + Defined at ../src/lib/mod_generator.f90 line \ + 21 + + """ + return _raffle.f90wrap_stoichiometry_type__get__num(self._handle) + + @num.setter + def num(self, num): + _raffle.f90wrap_stoichiometry_type__set__num(self._handle, num) + + def __str__(self): + ret = ['{\n'] + ret.append(' element : ') + ret.append(repr(self.element)) + ret.append(',\n num : ') + ret.append(repr(self.num)) + ret.append('}') + return ''.join(ret) + + _dt_array_initialisers = [] + + + @f90wrap.runtime.register_class("raffle.stoichiometry_type_xnum_array") + class stoichiometry_type_xnum_array(f90wrap.runtime.FortranDerivedType): + """ + Type(name=stoichiometry_type_xnum_array) + + + Defined at ../src/lib/mod_generator.f90 lines \ + 19-21 + + """ + def __init__(self, handle=None): + """ + self = Stoichiometry_Type() + + + Defined at ../src/lib/mod_generator.f90 lines \ + 19-21 + + + Returns + ------- + this : Stoichiometry_Type + Object to be constructed + + + Automatically generated constructor for stoichiometry_type + """ + f90wrap.runtime.FortranDerivedType.__init__(self) + result = _raffle.f90wrap_generator__stoich_type_xnum_array_initialise() + self._handle = result[0] if isinstance(result, tuple) else result + + def __del__(self): + """ + Destructor for class Stoichiometry_Type + + + Defined at ../src/lib/mod_generator.f90 lines \ + 19-21 + + Parameters + ---------- + this : Stoichiometry_Type + Object to be destructed + + + Automatically generated destructor for stoichiometry_type + """ + if self._alloc: + _raffle.f90wrap_generator__stoich_type_xnum_array_finalise(this=self._handle) + + def init_array_items(self): + self.items = f90wrap.runtime.FortranDerivedTypeArray(self, + _raffle.f90wrap_stoich_type_xnum_array__array_getitem__items, + _raffle.f90wrap_stoich_type_xnum_array__array_setitem__items, + _raffle.f90wrap_stoich_type_xnum_array__array_len__items, + """ + Element items ftype=type(test_type) pytype=Test_Type + + + Defined at line 0 + + """, Generator.stoichiometry_type) + return self.items + + def allocate(self, size): + """ + Allocate the items array with the given size + + Parameters + ---------- + self : Stoichiometry_Type + size : int + Size of the items array + """ + _raffle.f90wrap_stoich_type_xnum_array__array_alloc__items(self._handle, num=size) + + def deallocate(self): + """ + Deallocate the items array + """ + _raffle.f90wrap_stoich_type_xnum_array__array_dealloc__items(self._handle) + + + + _dt_array_initialisers = [init_array_items] + + + @f90wrap.runtime.register_class("raffle.raffle_generator_type") + class raffle_generator_type(f90wrap.runtime.FortranDerivedType): + """ + Type(name=raffle_generator_type) + + + Defined at ../src/lib/mod_generator.f90 lines \ + 23-34 + + """ + def __init__(self, handle=None): + """ + self = Raffle_Generator_Type() + + + Defined at ../src/lib/mod_generator.f90 lines \ + 23-34 + + + Returns + ------- + this : Raffle_Generator_Type + Object to be constructed + + + Automatically generated constructor for raffle_generator_type + """ + f90wrap.runtime.FortranDerivedType.__init__(self) + result = _raffle.f90wrap_generator__raffle_generator_type_initialise() + self._handle = result[0] if isinstance(result, tuple) else result + + def __del__(self): + """ + Destructor for class Raffle_Generator_Type + + + Defined at ../src/lib/mod_generator.f90 lines \ + 23-34 + + Parameters + ---------- + this : Raffle_Generator_Type + Object to be destructed + + + Automatically generated destructor for raffle_generator_type + """ + if self._alloc: + _raffle.f90wrap_generator__raffle_generator_type_finalise(this=self._handle) + + def print_hello(self): + """ + print_hello__binding__raffle_generator_type(self) + + + Defined at ../src/lib/mod_generator.f90 lines \ + 69-74 + + Parameters + ---------- + this : unknown + + """ + _raffle.f90wrap_generator__print_hello__binding__raffle_generator_type(this=self._handle) + + @property + def bins(self): + """ + Element bins ftype=integer pytype=int + + + Defined at ../src/lib/mod_generator.f90 line \ + 24 + + """ + array_ndim, array_type, array_shape, array_handle = \ + _raffle.f90wrap_raffle_generator_type__array__bins(self._handle) + if array_handle in self._arrays: + bins = self._arrays[array_handle] + else: + bins = f90wrap.runtime.get_array(f90wrap.runtime.sizeof_fortran_t, + self._handle, + _raffle.f90wrap_raffle_generator_type__array__bins) + self._arrays[array_handle] = bins + return bins + + @bins.setter + def bins(self, bins): + self.bins[...] = bins + + @property + def lattice_host(self): + """ + Element lattice_host ftype=real(real12) pytype=float + + + Defined at ../src/lib/mod_generator.f90 line \ + 25 + + """ + array_ndim, array_type, array_shape, array_handle = \ + _raffle.f90wrap_raffle_generator_type__array__lattice_host(self._handle) + if array_handle in self._arrays: + lattice_host = self._arrays[array_handle] + else: + lattice_host = f90wrap.runtime.get_array(f90wrap.runtime.sizeof_fortran_t, + self._handle, + _raffle.f90wrap_raffle_generator_type__array__lattice_host) + self._arrays[array_handle] = lattice_host + return lattice_host + + @lattice_host.setter + def lattice_host(self, lattice_host): + self.lattice_host[...] = lattice_host + + @property + def method_probab(self): + """ + Element method_probab ftype=real(real12) pytype=float + + + Defined at ../src/lib/mod_generator.f90 line \ + 28 + + """ + array_ndim, array_type, array_shape, array_handle = \ + _raffle.f90wrap_raffle_generator_type__array__method_probab(self._handle) + if array_handle in self._arrays: + method_probab = self._arrays[array_handle] + else: + method_probab = f90wrap.runtime.get_array(f90wrap.runtime.sizeof_fortran_t, + self._handle, + _raffle.f90wrap_raffle_generator_type__array__method_probab) + self._arrays[array_handle] = method_probab + return method_probab + + @method_probab.setter + def method_probab(self, method_probab): + self.method_probab[...] = method_probab + + def __str__(self): + ret = ['{\n'] + ret.append(' bins : ') + ret.append(repr(self.bins)) + ret.append(',\n lattice_host : ') + ret.append(repr(self.lattice_host)) + ret.append(',\n method_probab : ') + ret.append(repr(self.method_probab)) + ret.append('}') + return ''.join(ret) + + _dt_array_initialisers = [] + + + _dt_array_initialisers = [] + + +generator = Generator() + +class Raffle(f90wrap.runtime.FortranModule): + """ + Module raffle + + + Defined at ../src/raffle.f90 lines 1-4 + + """ + pass + _dt_array_initialisers = [] + + +raffle = Raffle() + diff --git a/src/lib/mod_generator.f90 b/src/lib/mod_generator.f90 index 89d69c2a..14ab9130 100644 --- a/src/lib/mod_generator.f90 +++ b/src/lib/mod_generator.f90 @@ -3,11 +3,25 @@ module generator use rw_geom, only: bas_type use evolver, only: gvector_container_type + + use constants, only: verbose + use misc_raffle, only: shuffle + use rw_geom, only: geom_read, geom_write, clone_bas + use edit_geom, only: bas_merge + use add_atom, only: add_atom_void, add_atom_pseudo, add_atom_scan, & + get_viable_gridpoints, update_viable_gridpoints + +#ifdef ENABLE_ATHENA + use read_structures, only: get_graph_from_basis + use machine_learning, only: network_predict_graph + use athena, only: graph_type +#endif + implicit none private - public :: raffle_generator_type + public :: raffle_generator_type, stoichiometry_type type :: stoichiometry_type @@ -24,7 +38,8 @@ module generator real(real12), dimension(3) :: method_probab contains procedure, pass(this) :: generate - procedure, pass(this), private :: generate_structure + procedure, pass(this) :: generate_structure + procedure, pass(this) :: print_hello !procedure :: get_structures !procedure :: evaluate end type raffle_generator_type @@ -43,27 +58,292 @@ module function init_raffle_generator( & end function init_raffle_generator end interface raffle_generator_type - interface - module subroutine generate( this, & - num_structures, stoichiometry, method_probab ) - class(raffle_generator_type), intent(inout) :: this - integer, intent(in) :: num_structures - type(stoichiometry_type), dimension(:), intent(in) :: stoichiometry - real(real12), dimension(:), intent(in), optional :: method_probab - end subroutine generate - - module function generate_structure( & - this, & - basis_initial, & - placement_list, method_probab ) result(basis) - class(raffle_generator_type), intent(in) :: this - type(bas_type), intent(in) :: basis_initial - integer, dimension(:,:), intent(in) :: placement_list - real(real12), dimension(3) :: method_probab - type(bas_type) :: basis - end function generate_structure - end interface +! interface +! module subroutine generate( this, & +! num_structures, stoichiometry, method_probab ) +! class(raffle_generator_type), intent(inout) :: this +! integer, intent(in) :: num_structures +! type(stoichiometry_type), dimension(:), intent(in) :: stoichiometry +! real(real12), dimension(:), intent(in), optional :: method_probab +! end subroutine generate + +! module function generate_structure( & +! this, & +! basis_initial, & +! placement_list, method_probab ) result(basis) +! class(raffle_generator_type), intent(in) :: this +! type(bas_type), intent(in) :: basis_initial +! integer, dimension(:,:), intent(in) :: placement_list +! real(real12), dimension(3) :: method_probab +! type(bas_type) :: basis +! end function generate_structure +! end interface + + + contains + + module subroutine print_hello(this) + implicit none + class(raffle_generator_type), intent(in) :: this + + write(*,*) "Hello" + + end subroutine print_hello + + module function init_raffle_generator( & + lattice_host, basis_host, width, sigma, cutoff_min, cutoff_max ) & + result(generator) + !! Initialise an instance of the raffle generator. + !! Set up run-independent parameters. + implicit none + ! Arguments + real(real12), dimension(3,3), intent(in) :: lattice_host + !! Lattice vectors of the host structure. + type(bas_type), intent(in) :: basis_host + !! Basis of the host structure. + real(real12), dimension(3), intent(in), optional :: width + !! Width of the gaussians used in the 2-, 3-, and 4-body + !! distribution functions. + real(real12), dimension(3), intent(in), optional :: sigma + !! Width of the gaussians used in the 2-, 3-, and 4-body + !! distribution functions. + real(real12), dimension(3), intent(in), optional :: cutoff_min + !! Minimum cutoff for the 2-, 3-, and 4-body distribution functions. + real(real12), dimension(3), intent(in), optional :: cutoff_max + !! Maximum cutoff for the 2-, 3-, and 4-body distribution functions. + + type(raffle_generator_type) :: generator + + + generator%lattice_host = lattice_host + generator%basis_host = basis_host + + if( present(width) ) & + call generator%distributions%set_width(width) + if( present(sigma) ) & + call generator%distributions%set_sigma(sigma) + if( present(cutoff_min) ) & + call generator%distributions%set_cutoff_min(cutoff_min) + if( present(cutoff_max) ) & + call generator%distributions%set_cutoff_max(cutoff_max) + + + end function init_raffle_generator + + + + subroutine generate(this, num_structures, & + stoichiometry, method_probab) + !! Generate random structures. + implicit none + ! Arguments + class(raffle_generator_type), intent(inout) :: this + !! Instance of the raffle generator. + integer, intent(in) :: num_structures + !! Number of structures to generate. + type(stoichiometry_type), dimension(:), intent(in) :: stoichiometry + !! Stoichiometry of the structures to generate. + real(real12), dimension(:), intent(in), optional :: method_probab + !! Probability of each placement method. + + type(bas_type) :: basis, basis_store + + integer, dimension(:,:), allocatable :: placement_list, placement_list_shuffled + + integer :: i, j, k + integer :: istructure + integer :: unit, info_unit, structure_unit + integer :: num_insert_atoms, num_insert_species + + logical :: placed, success + character(1024) :: buffer + + real(real12), dimension(3) :: method_probab_ = [0.33_real12, 0.66_real12, 1.0_real12] + +#ifdef ENABLE_ATHENA + type(graph_type), dimension(1) :: graph +#endif + + if(present(method_probab)) method_probab_ = method_probab + + + !!! THINK OF SOME WAY TO HANDLE THE HOST SEPARATELY + !!! THAT CAN SIGNIFICANTLY REDUCE DATA USAGE + num_insert_species = size(stoichiometry) + num_insert_atoms = sum(stoichiometry(:)%num) + allocate(basis_store%spec(num_insert_species)) + basis_store%spec(:)%name = stoichiometry(:)%element + basis_store%spec(:)%num = stoichiometry(:)%num + basis_store%natom = num_insert_atoms + basis_store%nspec = num_insert_species + basis_store%sysname = "inserts" + + do i = 1, basis_store%nspec + allocate(basis_store%spec(i)%atom(basis_store%spec(i)%num,3), source = 0._real12) + end do + basis_store = bas_merge(this%basis_host,basis_store) + + + !!-------------------------------------------------------------------------- + !! generate the placement list + !! placement list is the list of number of atoms of each species that can be + !! placed in the structure + !! ... the second dimension is the index of the species and atom in the + !! ... basis_store + !!-------------------------------------------------------------------------- + allocate(placement_list(num_insert_atoms,2)) + k = 0 + spec_loop1: do i = 1, basis_store%nspec + success = .false. + do j = 1, size(stoichiometry) + if(trim(basis_store%spec(i)%name).eq.trim(stoichiometry(j)%element)) & + success = .true. + end do + if(.not.success) cycle + if(i.gt.this%basis_host%nspec)then + do j = 1, basis_store%spec(i)%num + k = k + 1 + placement_list(k,1) = i + placement_list(k,2) = j + end do + else + do j = 1, basis_store%spec(i)%num + if(j.le.this%basis_host%spec(i)%num) cycle + k = k + 1 + placement_list(k,1) = i + placement_list(k,2) = j + end do + end if + end do spec_loop1 + + + !!-------------------------------------------------------------------------- + !! generate the structures + !!-------------------------------------------------------------------------- + structure_loop: do istructure = 1, num_structures + + basis = this%generate_structure( basis_store, & + placement_list, method_probab_ ) + +#ifdef ENABLE_ATHENA + !!----------------------------------------------------------------------- + !! predict energy using ML + !!----------------------------------------------------------------------- + graph(1) = get_graph_from_basis(this%lattice_host, basis) + write(*,*) "Predicted energy", network_predict_graph(graph(1:1)) +#endif + + end do structure_loop + write(*,*) "Finished generating structures" + + end subroutine generate + + + + module function generate_structure( & + this, & + basis_initial, & + placement_list, method_probab ) result(basis) + !! Generate a single random structure. + implicit none + ! Arguments + class(raffle_generator_type), intent(in) :: this + !! Instance of the raffle generator. + type(bas_type), intent(in) :: basis_initial + !! Initial basis to build upon. + integer, dimension(:,:), intent(in) :: placement_list + !! List of possible placements. + real(real12), dimension(3) :: method_probab + !! Probability of each placement method. + type(bas_type) :: basis + !! Generated basis. + + integer :: i, j, iplaced, void_ticker + integer :: num_insert_atoms + real(real12) :: rtmp1 + logical :: placed + integer, dimension(size(placement_list,1),size(placement_list,2)) :: & + placement_list_shuffled + real(real12), dimension(3) :: method_probab_ + real(real12), dimension(:,:), allocatable :: viable_gridpoints + + + + call clone_bas(basis_initial, basis) + num_insert_atoms = basis%natom - this%basis_host%natom + + placement_list_shuffled = placement_list + call shuffle(placement_list_shuffled,1) !!! NEED TO SORT OUT RANDOM SEED + + viable_gridpoints = get_viable_gridpoints( this%bins, & + this%lattice_host, basis, & + [ this%distributions%bond_info(:)%radius_covalent ], & + placement_list_shuffled ) + + method_probab_ = method_probab + + iplaced = 0 + void_ticker = 0 + placement_loop: do while (iplaced.lt.num_insert_atoms) + + !!! CHANGE THESE PLACEMENT SUBROUTINES TO FUNCTIONS THAT OUTPUT THE COORDINATE + !!! THEN, THIS LOOP ACTUALLY PLACES IT AT THE END + call random_number(rtmp1) + if(rtmp1.le.method_probab_(1)) then + if(verbose.gt.0) write(*,*) "Add Atom Void" + call add_atom_void( this%bins, & + this%lattice_host, basis, & + placement_list_shuffled(iplaced+1:,:), placed) + else if(rtmp1.le.method_probab_(2)) then + if(verbose.gt.0) write(*,*) "Add Atom Pseudo" + call add_atom_pseudo( this%bins, & + this%distributions, & + this%lattice_host, basis, & + placement_list_shuffled(iplaced+1:,:), & + [ this%distributions%bond_info(:)%radius_covalent ], & + placed ) + if(.not. placed) void_ticker = void_ticker + 1 + else if(rtmp1.le.method_probab_(3)) then + if(verbose.gt.0) write(*,*) "Add Atom Scan" + call add_atom_scan( viable_gridpoints, & + this%distributions, & + this%lattice_host, basis, & + placement_list_shuffled(iplaced+1:,:), & + [ this%distributions%bond_info(:)%radius_covalent ], & + placed) + end if + if(.not. placed) then + if(void_ticker.gt.10) & + call add_atom_void( this%bins, this%lattice_host, basis, & + placement_list_shuffled(iplaced+1:,:), placed) + void_ticker = 0 + if(.not.placed) cycle placement_loop + end if + if(verbose.gt.0)then + write(*,'(A)',ADVANCE='NO') achar(13) + write(*,*) "placed", placed + end if + iplaced = iplaced + 1 + if(allocated(viable_gridpoints)) & + call update_viable_gridpoints( viable_gridpoints, & + this%lattice_host, basis, & + [ placement_list_shuffled(iplaced,:) ], & + this%distributions%bond_info( & + ( basis%nspec - & + placement_list_shuffled(iplaced,1)/2 ) * & + ( placement_list_shuffled(iplaced,1) - 1 ) + & + placement_list_shuffled(iplaced,1) & + )%radius_covalent ) + if(.not.allocated(viable_gridpoints).and. & + abs( method_probab_(3) - method_probab_(2) ) .gt. 1.E-3) then + write(*,*) "WARNING: No more viable gridpoints" + write(*,*) "Suppressing SCAN method" + method_probab_ = method_probab_ / method_probab_(2) + method_probab_(3) = method_probab_(2) + end if + end do placement_loop + end function generate_structure end module generator \ No newline at end of file From a5316c005a387c7f0d51e3aaea83bc4a40bb72d7 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Wed, 17 Jul 2024 15:32:07 +0100 Subject: [PATCH 023/293] Handle generate procedure of raffle generator type --- .../f90wrap_mod_generator.f90 | 16 ++++++++++---- edited_autogen_files/raffle.py | 22 +++++++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/edited_autogen_files/f90wrap_mod_generator.f90 b/edited_autogen_files/f90wrap_mod_generator.f90 index 1346bff4..e8238d15 100644 --- a/edited_autogen_files/f90wrap_mod_generator.f90 +++ b/edited_autogen_files/f90wrap_mod_generator.f90 @@ -326,7 +326,8 @@ subroutine f90wrap_generator__raffle_generator_type_finalise(this) deallocate(this_ptr%p) end subroutine f90wrap_generator__raffle_generator_type_finalise -subroutine f90wrap_generator__generate__binding__raffle_generator_type(this, num_structures, stoichiometry, & +subroutine f90wrap_generator__generate__binding__rgt( & + this, num_structures, stoichiometry, & method_probab, n0) use generator, only: raffle_generator_type, stoichiometry_type implicit none @@ -351,11 +352,18 @@ subroutine f90wrap_generator__generate__binding__raffle_generator_type(this, num real(4), intent(in), optional, dimension(n0) :: method_probab integer :: n0 !f2py intent(hide), depend(method_probab) :: n0 = shape(method_probab,0) + write(*,*) "in generate" this_ptr = transfer(this, this_ptr) stoichiometry_ptr = transfer(stoichiometry, stoichiometry_ptr) - call this_ptr%p%generate(num_structures=num_structures, stoichiometry=stoichiometry_ptr%p%items, & - method_probab=method_probab) -end subroutine f90wrap_generator__generate__binding__raffle_generator_type + if(present(method_probab)) then + write(*,*) "method_probab present" + call this_ptr%p%generate(num_structures=num_structures, stoichiometry=stoichiometry_ptr%p%items, & + method_probab=method_probab) + else + write(*,*) "method_probab not present" + call this_ptr%p%generate(num_structures=num_structures, stoichiometry=stoichiometry_ptr%p%items) + end if +end subroutine f90wrap_generator__generate__binding__rgt subroutine f90wrap_generator__print_hello__binding__raffle_generator_type(this) use generator, only: raffle_generator_type diff --git a/edited_autogen_files/raffle.py b/edited_autogen_files/raffle.py index a0f6b184..034df2e2 100644 --- a/edited_autogen_files/raffle.py +++ b/edited_autogen_files/raffle.py @@ -258,6 +258,28 @@ def print_hello(self): """ _raffle.f90wrap_generator__print_hello__binding__raffle_generator_type(this=self._handle) + + def generate(self, num_structures, stoichiometry, method_probab=[1.0, 1.0, 1.0]): + """ + generate__binding__raffle_generator_type(self, num_structures, stoichiometry, method_probab) + + Defined at ../src/lib/mod_generator.f90 lines \ + 76-84 + + Parameters + ---------- + this : unknown + num_structures : int + stoichiometry : stoichiometry_type_xnum_array + method_probab : list of float + + """ + + _raffle.f90wrap_generator__generate__binding__rgt( + this=self._handle, + num_structures=num_structures, + stoichiometry=stoichiometry._handle, + method_probab=method_probab)#, n0=len(method_probab)) @property def bins(self): From 237c39d3983473f0e73f26c2ae1846349f5139ee Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Wed, 17 Jul 2024 20:23:57 +0100 Subject: [PATCH 024/293] Add bas_type handling --- .../f90wrap_mod_generator.f90 | 5 +- edited_autogen_files/f90wrap_mod_rw_geom.f90 | 728 ++++++++++++++++++ edited_autogen_files/raffle.py | 586 ++++++++++++++ 3 files changed, 1316 insertions(+), 3 deletions(-) create mode 100644 edited_autogen_files/f90wrap_mod_rw_geom.f90 diff --git a/edited_autogen_files/f90wrap_mod_generator.f90 b/edited_autogen_files/f90wrap_mod_generator.f90 index e8238d15..a1a62124 100644 --- a/edited_autogen_files/f90wrap_mod_generator.f90 +++ b/edited_autogen_files/f90wrap_mod_generator.f90 @@ -1,4 +1,4 @@ -! Module generator defined in file /Users/nedtaylor/DCoding/DGit/raffle/src/lib/mod_generator.f90 +! Module generator defined in file ../src/lib/mod_generator.f90 subroutine f90wrap_stoichiometry_type__get__element(this, f90wrap_element) use generator, only: stoichiometry_type @@ -199,7 +199,6 @@ subroutine f90wrap_stoich_type_xnum_array__array_dealloc__items(this) this = transfer(this_ptr, this) end subroutine f90wrap_stoich_type_xnum_array__array_dealloc__items - subroutine f90wrap_generator__stoich_type_xnum_array_initialise(this) use generator, only: stoichiometry_type implicit none @@ -378,5 +377,5 @@ subroutine f90wrap_generator__print_hello__binding__raffle_generator_type(this) call this_ptr%p%print_hello() end subroutine f90wrap_generator__print_hello__binding__raffle_generator_type -! End of module generator defined in file /Users/nedtaylor/DCoding/DGit/raffle/src/lib/mod_generator.f90 +! End of module generator defined in file ../src/lib/mod_generator.f90 diff --git a/edited_autogen_files/f90wrap_mod_rw_geom.f90 b/edited_autogen_files/f90wrap_mod_rw_geom.f90 new file mode 100644 index 00000000..02f407f8 --- /dev/null +++ b/edited_autogen_files/f90wrap_mod_rw_geom.f90 @@ -0,0 +1,728 @@ +! Module rw_geom defined in file ../src/lib/mod_rw_geom.f90 + +subroutine f90wrap_spec_type__array__atom(this, nd, dtype, dshape, dloc) + use rw_geom, only: spec_type + use, intrinsic :: iso_c_binding, only : c_int + implicit none + type spec_type_ptr_type + type(spec_type), pointer :: p => NULL() + end type spec_type_ptr_type + integer(c_int), intent(in) :: this(2) + type(spec_type_ptr_type) :: this_ptr + integer(c_int), intent(out) :: nd + integer(c_int), intent(out) :: dtype + integer(c_int), dimension(10), intent(out) :: dshape + integer*8, intent(out) :: dloc + + nd = 2 + dtype = 11 + this_ptr = transfer(this, this_ptr) + if (allocated(this_ptr%p%atom)) then + dshape(1:2) = shape(this_ptr%p%atom) + dloc = loc(this_ptr%p%atom) + else + dloc = 0 + end if +end subroutine f90wrap_spec_type__array__atom + +subroutine f90wrap_spec_type__get__mass(this, f90wrap_mass) + use rw_geom, only: spec_type + implicit none + type spec_type_ptr_type + type(spec_type), pointer :: p => NULL() + end type spec_type_ptr_type + integer, intent(in) :: this(2) + type(spec_type_ptr_type) :: this_ptr + real(4), intent(out) :: f90wrap_mass + + this_ptr = transfer(this, this_ptr) + f90wrap_mass = this_ptr%p%mass +end subroutine f90wrap_spec_type__get__mass + +subroutine f90wrap_spec_type__set__mass(this, f90wrap_mass) + use rw_geom, only: spec_type + implicit none + type spec_type_ptr_type + type(spec_type), pointer :: p => NULL() + end type spec_type_ptr_type + integer, intent(in) :: this(2) + type(spec_type_ptr_type) :: this_ptr + real(4), intent(in) :: f90wrap_mass + + this_ptr = transfer(this, this_ptr) + this_ptr%p%mass = f90wrap_mass +end subroutine f90wrap_spec_type__set__mass + +subroutine f90wrap_spec_type__get__charge(this, f90wrap_charge) + use rw_geom, only: spec_type + implicit none + type spec_type_ptr_type + type(spec_type), pointer :: p => NULL() + end type spec_type_ptr_type + integer, intent(in) :: this(2) + type(spec_type_ptr_type) :: this_ptr + real(4), intent(out) :: f90wrap_charge + + this_ptr = transfer(this, this_ptr) + f90wrap_charge = this_ptr%p%charge +end subroutine f90wrap_spec_type__get__charge + +subroutine f90wrap_spec_type__set__charge(this, f90wrap_charge) + use rw_geom, only: spec_type + implicit none + type spec_type_ptr_type + type(spec_type), pointer :: p => NULL() + end type spec_type_ptr_type + integer, intent(in) :: this(2) + type(spec_type_ptr_type) :: this_ptr + real(4), intent(in) :: f90wrap_charge + + this_ptr = transfer(this, this_ptr) + this_ptr%p%charge = f90wrap_charge +end subroutine f90wrap_spec_type__set__charge + +subroutine f90wrap_spec_type__get__name(this, f90wrap_name) + use rw_geom, only: spec_type + implicit none + type spec_type_ptr_type + type(spec_type), pointer :: p => NULL() + end type spec_type_ptr_type + integer, intent(in) :: this(2) + type(spec_type_ptr_type) :: this_ptr + character(3), intent(out) :: f90wrap_name + + this_ptr = transfer(this, this_ptr) + f90wrap_name = this_ptr%p%name +end subroutine f90wrap_spec_type__get__name + +subroutine f90wrap_spec_type__set__name(this, f90wrap_name) + use rw_geom, only: spec_type + implicit none + type spec_type_ptr_type + type(spec_type), pointer :: p => NULL() + end type spec_type_ptr_type + integer, intent(in) :: this(2) + type(spec_type_ptr_type) :: this_ptr + character(3), intent(in) :: f90wrap_name + + this_ptr = transfer(this, this_ptr) + this_ptr%p%name = f90wrap_name +end subroutine f90wrap_spec_type__set__name + +subroutine f90wrap_spec_type__get__num(this, f90wrap_num) + use rw_geom, only: spec_type + implicit none + type spec_type_ptr_type + type(spec_type), pointer :: p => NULL() + end type spec_type_ptr_type + integer, intent(in) :: this(2) + type(spec_type_ptr_type) :: this_ptr + integer, intent(out) :: f90wrap_num + + this_ptr = transfer(this, this_ptr) + f90wrap_num = this_ptr%p%num +end subroutine f90wrap_spec_type__get__num + +subroutine f90wrap_spec_type__set__num(this, f90wrap_num) + use rw_geom, only: spec_type + implicit none + type spec_type_ptr_type + type(spec_type), pointer :: p => NULL() + end type spec_type_ptr_type + integer, intent(in) :: this(2) + type(spec_type_ptr_type) :: this_ptr + integer, intent(in) :: f90wrap_num + + this_ptr = transfer(this, this_ptr) + this_ptr%p%num = f90wrap_num +end subroutine f90wrap_spec_type__set__num + +subroutine f90wrap_spec_type__array__lat(this, nd, dtype, dshape, dloc) + use rw_geom, only: spec_type + use, intrinsic :: iso_c_binding, only : c_int + implicit none + type spec_type_ptr_type + type(spec_type), pointer :: p => NULL() + end type spec_type_ptr_type + integer(c_int), intent(in) :: this(2) + type(spec_type_ptr_type) :: this_ptr + integer(c_int), intent(out) :: nd + integer(c_int), intent(out) :: dtype + integer(c_int), dimension(10), intent(out) :: dshape + integer*8, intent(out) :: dloc + + nd = 2 + dtype = 11 + this_ptr = transfer(this, this_ptr) + dshape(1:2) = shape(this_ptr%p%lat) + dloc = loc(this_ptr%p%lat) +end subroutine f90wrap_spec_type__array__lat + +subroutine f90wrap_rw_geom__spec_type_initialise(this) + use rw_geom, only: spec_type + implicit none + + type spec_type_ptr_type + type(spec_type), pointer :: p => NULL() + end type spec_type_ptr_type + type(spec_type_ptr_type) :: this_ptr + integer, intent(out), dimension(2) :: this + allocate(this_ptr%p) + this = transfer(this_ptr, this) +end subroutine f90wrap_rw_geom__spec_type_initialise + +subroutine f90wrap_rw_geom__spec_type_finalise(this) + use rw_geom, only: spec_type + implicit none + + type spec_type_ptr_type + type(spec_type), pointer :: p => NULL() + end type spec_type_ptr_type + type(spec_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + this_ptr = transfer(this, this_ptr) + deallocate(this_ptr%p) +end subroutine f90wrap_rw_geom__spec_type_finalise + +subroutine f90wrap_bas_type__array_getitem__spec(f90wrap_this, f90wrap_i, specitem) + + use rw_geom, only: bas_type, spec_type + implicit none + + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + type spec_type_ptr_type + type(spec_type), pointer :: p => NULL() + end type spec_type_ptr_type + integer, intent(in) :: f90wrap_this(2) + type(bas_type_ptr_type) :: this_ptr + integer, intent(in) :: f90wrap_i + integer, intent(out) :: specitem(2) + type(spec_type_ptr_type) :: spec_ptr + + this_ptr = transfer(f90wrap_this, this_ptr) + if (allocated(this_ptr%p%spec)) then + if (f90wrap_i < 1 .or. f90wrap_i > size(this_ptr%p%spec)) then + call f90wrap_abort("array index out of range") + else + spec_ptr%p => this_ptr%p%spec(f90wrap_i) + specitem = transfer(spec_ptr,specitem) + endif + else + call f90wrap_abort("derived type array not allocated") + end if +end subroutine f90wrap_bas_type__array_getitem__spec + +subroutine f90wrap_bas_type__array_setitem__spec(f90wrap_this, f90wrap_i, specitem) + + use rw_geom, only: bas_type, spec_type + implicit none + + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + type spec_type_ptr_type + type(spec_type), pointer :: p => NULL() + end type spec_type_ptr_type + integer, intent(in) :: f90wrap_this(2) + type(bas_type_ptr_type) :: this_ptr + integer, intent(in) :: f90wrap_i + integer, intent(in) :: specitem(2) + type(spec_type_ptr_type) :: spec_ptr + + this_ptr = transfer(f90wrap_this, this_ptr) + if (allocated(this_ptr%p%spec)) then + if (f90wrap_i < 1 .or. f90wrap_i > size(this_ptr%p%spec)) then + call f90wrap_abort("array index out of range") + else + spec_ptr = transfer(specitem,spec_ptr) + this_ptr%p%spec(f90wrap_i) = spec_ptr%p + endif + else + call f90wrap_abort("derived type array not allocated") + end if +end subroutine f90wrap_bas_type__array_setitem__spec + +subroutine f90wrap_bas_type__array_len__spec(f90wrap_this, f90wrap_n) + + use rw_geom, only: bas_type, spec_type + implicit none + + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + type spec_type_ptr_type + type(spec_type), pointer :: p => NULL() + end type spec_type_ptr_type + integer, intent(out) :: f90wrap_n + integer, intent(in) :: f90wrap_this(2) + type(bas_type_ptr_type) :: this_ptr + + this_ptr = transfer(f90wrap_this, this_ptr) + if (allocated(this_ptr%p%spec)) then + f90wrap_n = size(this_ptr%p%spec) + else + f90wrap_n = 0 + end if +end subroutine f90wrap_bas_type__array_len__spec + +subroutine f90wrap_bas_type__get__nspec(this, f90wrap_nspec) + use rw_geom, only: bas_type + implicit none + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + integer, intent(in) :: this(2) + type(bas_type_ptr_type) :: this_ptr + integer, intent(out) :: f90wrap_nspec + + this_ptr = transfer(this, this_ptr) + f90wrap_nspec = this_ptr%p%nspec +end subroutine f90wrap_bas_type__get__nspec + +subroutine f90wrap_bas_type__set__nspec(this, f90wrap_nspec) + use rw_geom, only: bas_type + implicit none + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + integer, intent(in) :: this(2) + type(bas_type_ptr_type) :: this_ptr + integer, intent(in) :: f90wrap_nspec + + this_ptr = transfer(this, this_ptr) + this_ptr%p%nspec = f90wrap_nspec +end subroutine f90wrap_bas_type__set__nspec + +subroutine f90wrap_bas_type__get__natom(this, f90wrap_natom) + use rw_geom, only: bas_type + implicit none + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + integer, intent(in) :: this(2) + type(bas_type_ptr_type) :: this_ptr + integer, intent(out) :: f90wrap_natom + + this_ptr = transfer(this, this_ptr) + f90wrap_natom = this_ptr%p%natom +end subroutine f90wrap_bas_type__get__natom + +subroutine f90wrap_bas_type__set__natom(this, f90wrap_natom) + use rw_geom, only: bas_type + implicit none + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + integer, intent(in) :: this(2) + type(bas_type_ptr_type) :: this_ptr + integer, intent(in) :: f90wrap_natom + + this_ptr = transfer(this, this_ptr) + this_ptr%p%natom = f90wrap_natom +end subroutine f90wrap_bas_type__set__natom + +subroutine f90wrap_bas_type__get__energy(this, f90wrap_energy) + use rw_geom, only: bas_type + implicit none + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + integer, intent(in) :: this(2) + type(bas_type_ptr_type) :: this_ptr + real(4), intent(out) :: f90wrap_energy + + this_ptr = transfer(this, this_ptr) + f90wrap_energy = this_ptr%p%energy +end subroutine f90wrap_bas_type__get__energy + +subroutine f90wrap_bas_type__set__energy(this, f90wrap_energy) + use rw_geom, only: bas_type + implicit none + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + integer, intent(in) :: this(2) + type(bas_type_ptr_type) :: this_ptr + real(4), intent(in) :: f90wrap_energy + + this_ptr = transfer(this, this_ptr) + this_ptr%p%energy = f90wrap_energy +end subroutine f90wrap_bas_type__set__energy + +subroutine f90wrap_bas_type__get__lcart(this, f90wrap_lcart) + use rw_geom, only: bas_type + implicit none + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + integer, intent(in) :: this(2) + type(bas_type_ptr_type) :: this_ptr + logical, intent(out) :: f90wrap_lcart + + this_ptr = transfer(this, this_ptr) + f90wrap_lcart = this_ptr%p%lcart +end subroutine f90wrap_bas_type__get__lcart + +subroutine f90wrap_bas_type__set__lcart(this, f90wrap_lcart) + use rw_geom, only: bas_type + implicit none + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + integer, intent(in) :: this(2) + type(bas_type_ptr_type) :: this_ptr + logical, intent(in) :: f90wrap_lcart + + this_ptr = transfer(this, this_ptr) + this_ptr%p%lcart = f90wrap_lcart +end subroutine f90wrap_bas_type__set__lcart + +subroutine f90wrap_bas_type__get__sysname(this, f90wrap_sysname) + use rw_geom, only: bas_type + implicit none + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + integer, intent(in) :: this(2) + type(bas_type_ptr_type) :: this_ptr + character(1024), intent(out) :: f90wrap_sysname + + this_ptr = transfer(this, this_ptr) + f90wrap_sysname = this_ptr%p%sysname +end subroutine f90wrap_bas_type__get__sysname + +subroutine f90wrap_bas_type__set__sysname(this, f90wrap_sysname) + use rw_geom, only: bas_type + implicit none + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + integer, intent(in) :: this(2) + type(bas_type_ptr_type) :: this_ptr + character(1024), intent(in) :: f90wrap_sysname + + this_ptr = transfer(this, this_ptr) + this_ptr%p%sysname = f90wrap_sysname +end subroutine f90wrap_bas_type__set__sysname + +subroutine f90wrap_rw_geom__bas_type_initialise(this) + use rw_geom, only: bas_type + implicit none + + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + type(bas_type_ptr_type) :: this_ptr + integer, intent(out), dimension(2) :: this + allocate(this_ptr%p) + this = transfer(this_ptr, this) +end subroutine f90wrap_rw_geom__bas_type_initialise + +subroutine f90wrap_rw_geom__bas_type_finalise(this) + use rw_geom, only: bas_type + implicit none + + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + type(bas_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + this_ptr = transfer(this, this_ptr) + deallocate(this_ptr%p) +end subroutine f90wrap_rw_geom__bas_type_finalise + + + + + +subroutine f90wrap_bas_type_xnum_array__array_getitem__items( & + this, f90wrap_i, itemsitem) + use rw_geom, only: bas_type + implicit none + + type bas_type_xnum_array + type(bas_type), dimension(:), allocatable :: items + end type bas_type_xnum_array + + type bas_type_xnum_array_ptr_type + type(bas_type_xnum_array), pointer :: p => NULL() + end type bas_type_xnum_array_ptr_type + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + integer, intent(in), dimension(2) :: this + type(bas_type_xnum_array_ptr_type) :: this_ptr + integer, intent(in) :: f90wrap_i + integer, intent(out) :: itemsitem(2) + type(bas_type_ptr_type) :: items_ptr + + this_ptr = transfer(this, this_ptr) + if (f90wrap_i < 1 .or. f90wrap_i > size(this_ptr%p%items)) then + call f90wrap_abort("array index out of range") + else + items_ptr%p => this_ptr%p%items(f90wrap_i) + itemsitem = transfer(items_ptr,itemsitem) + endif +end subroutine f90wrap_bas_type_xnum_array__array_getitem__items + +subroutine f90wrap_bas_type_xnum_array__array_setitem__items(this, f90wrap_i, itemsitem) + use rw_geom, only: bas_type + implicit none + + type bas_type_xnum_array + type(bas_type), dimension(:), allocatable :: items + end type bas_type_xnum_array + + type bas_type_xnum_array_ptr_type + type(bas_type_xnum_array), pointer :: p => NULL() + end type bas_type_xnum_array_ptr_type + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + integer, intent(in), dimension(2) :: this + type(bas_type_xnum_array_ptr_type) :: this_ptr + integer, intent(in) :: f90wrap_i + integer, intent(out) :: itemsitem(2) + type(bas_type_ptr_type) :: items_ptr + + this_ptr = transfer(this, this_ptr) + if (f90wrap_i < 1 .or. f90wrap_i > size(this_ptr%p%items)) then + call f90wrap_abort("array index out of range") + else + items_ptr = transfer(itemsitem,items_ptr) + this_ptr%p%items(f90wrap_i) = items_ptr%p + endif +end subroutine f90wrap_bas_type_xnum_array__array_setitem__items + +subroutine f90wrap_bas_type_xnum_array__array_len__items(this, f90wrap_n) + use rw_geom, only: bas_type + implicit none + + type bas_type_xnum_array + type(bas_type), dimension(:), allocatable :: items + end type bas_type_xnum_array + + type bas_type_xnum_array_ptr_type + type(bas_type_xnum_array), pointer :: p => NULL() + end type bas_type_xnum_array_ptr_type + integer, intent(in), dimension(2) :: this + type(bas_type_xnum_array_ptr_type) :: this_ptr + integer, intent(out) :: f90wrap_n + this_ptr = transfer(this, this_ptr) + f90wrap_n = size(this_ptr%p%items) +end subroutine f90wrap_bas_type_xnum_array__array_len__items + +subroutine f90wrap_bas_type_xnum_array__array_alloc__items(this, num) + use rw_geom, only: bas_type + implicit none + + type bas_type_xnum_array + type(bas_type), dimension(:), allocatable :: items + end type bas_type_xnum_array + + type bas_type_xnum_array_ptr_type + type(bas_type_xnum_array), pointer :: p => NULL() + end type bas_type_xnum_array_ptr_type + type(bas_type_xnum_array_ptr_type) :: this_ptr + integer, intent(in) :: num + integer, intent(inout), dimension(2) :: this + + this_ptr = transfer(this, this_ptr) + allocate(this_ptr%p%items(num)) + this = transfer(this_ptr, this) +end subroutine f90wrap_bas_type_xnum_array__array_alloc__items + +subroutine f90wrap_bas_type_xnum_array__array_dealloc__items(this) + use rw_geom, only: bas_type + implicit none + + type bas_type_xnum_array + type(bas_type), dimension(:), allocatable :: items + end type bas_type_xnum_array + + type bas_type_xnum_array_ptr_type + type(bas_type_xnum_array), pointer :: p => NULL() + end type bas_type_xnum_array_ptr_type + type(bas_type_xnum_array_ptr_type) :: this_ptr + integer, intent(inout), dimension(2) :: this + + this_ptr = transfer(this, this_ptr) + deallocate(this_ptr%p%items) + this = transfer(this_ptr, this) +end subroutine f90wrap_bas_type_xnum_array__array_dealloc__items + +subroutine f90wrap_rw_geom__bas_type_xnum_array_initialise(this) + use rw_geom, only: bas_type + implicit none + + type bas_type_xnum_array + type(bas_type), dimension(:), allocatable :: items + end type bas_type_xnum_array + + type bas_type_xnum_array_ptr_type + type(bas_type_xnum_array), pointer :: p => NULL() + end type bas_type_xnum_array_ptr_type + type(bas_type_xnum_array_ptr_type) :: this_ptr + integer, intent(out), dimension(2) :: this + allocate(this_ptr%p) + this = transfer(this_ptr, this) +end subroutine f90wrap_rw_geom__bas_type_xnum_array_initialise + +subroutine f90wrap_rw_geom__bas_type_xnum_array_finalise(this) + use rw_geom, only: bas_type + implicit none + + type bas_type_xnum_array + type(bas_type), dimension(:), allocatable :: items + end type bas_type_xnum_array + + type bas_type_xnum_array_ptr_type + type(bas_type_xnum_array), pointer :: p => NULL() + end type bas_type_xnum_array_ptr_type + type(bas_type_xnum_array_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + this_ptr = transfer(this, this_ptr) + deallocate(this_ptr%p) +end subroutine f90wrap_rw_geom__bas_type_xnum_array_finalise + + + + + + +subroutine f90wrap_rw_geom__allocate_species__binding__bas_type(this, num_species, species_list, natom_list, atoms, n0, & + n1, n2, n3) + use rw_geom, only: bas_type + implicit none + + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + type(bas_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + integer, intent(in), optional :: num_species + character(3), intent(in), optional, dimension(n0) :: species_list + integer, intent(in), optional, dimension(n1) :: natom_list + real(4), intent(in), optional, dimension(n2,n3) :: atoms + integer :: n0 + !f2py intent(hide), depend(species_list) :: n0 = shape(species_list,0) + integer :: n1 + !f2py intent(hide), depend(natom_list) :: n1 = shape(natom_list,0) + integer :: n2 + !f2py intent(hide), depend(atoms) :: n2 = shape(atoms,0) + integer :: n3 + !f2py intent(hide), depend(atoms) :: n3 = shape(atoms,1) + this_ptr = transfer(this, this_ptr) + call this_ptr%p%allocate_species(num_species=num_species, species_list=species_list, natom_list=natom_list, atoms=atoms) +end subroutine f90wrap_rw_geom__allocate_species__binding__bas_type + +subroutine f90wrap_rw_geom__geom_read(unit, lat, bas, length) + use rw_geom, only: geom_read, bas_type + implicit none + + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + integer :: unit + !f2py intent(inout) unit + real(4), dimension(3,3) :: lat + !f2py intent(inout) lat + type(bas_type_ptr_type) :: bas_ptr + integer, intent(in), dimension(2) :: bas + integer, optional, intent(in) :: length + bas_ptr = transfer(bas, bas_ptr) + call geom_read(UNIT=unit, lat=lat, bas=bas_ptr%p, length=length) +end subroutine f90wrap_rw_geom__geom_read + +subroutine f90wrap_rw_geom__geom_write(unit, lat, bas) + use rw_geom, only: bas_type, geom_write + implicit none + + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + integer :: unit + !f2py intent(inout) unit + real(4), dimension(3,3) :: lat + !f2py intent(inout) lat + type(bas_type_ptr_type) :: bas_ptr + integer, intent(in), dimension(2) :: bas + bas_ptr = transfer(bas, bas_ptr) + call geom_write(UNIT=unit, lat=lat, bas=bas_ptr%p) +end subroutine f90wrap_rw_geom__geom_write + +subroutine f90wrap_rw_geom__convert_bas(inbas, ret_outbas, latconv) + use rw_geom, only: convert_bas, bas_type + implicit none + + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + type(bas_type_ptr_type) :: inbas_ptr + integer, intent(in), dimension(2) :: inbas + type(bas_type_ptr_type) :: ret_outbas_ptr + integer, intent(out), dimension(2) :: ret_outbas + real(4), dimension(3,3), intent(in) :: latconv + inbas_ptr = transfer(inbas, inbas_ptr) + allocate(ret_outbas_ptr%p) + ret_outbas_ptr%p = convert_bas(inbas=inbas_ptr%p, latconv=latconv) + ret_outbas = transfer(ret_outbas_ptr, ret_outbas) +end subroutine f90wrap_rw_geom__convert_bas + +subroutine f90wrap_rw_geom__clone_bas(inbas, outbas, inlat, outlat, trans_dim) + use rw_geom, only: clone_bas, bas_type + implicit none + + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + type(bas_type_ptr_type) :: inbas_ptr + integer, intent(in), dimension(2) :: inbas + type(bas_type_ptr_type) :: outbas_ptr + integer, intent(in), dimension(2) :: outbas + real(4), dimension(3,3), optional :: inlat + !f2py intent(inout) inlat + real(4), dimension(3,3), optional :: outlat + !f2py intent(inout) outlat + logical, optional, intent(in) :: trans_dim + inbas_ptr = transfer(inbas, inbas_ptr) + outbas_ptr = transfer(outbas, outbas_ptr) + call clone_bas(inbas=inbas_ptr%p, outbas=outbas_ptr%p, inlat=inlat, outlat=outlat, trans_dim=trans_dim) +end subroutine f90wrap_rw_geom__clone_bas + +subroutine f90wrap_rw_geom__get__igeom_input(f90wrap_igeom_input) + use rw_geom, only: rw_geom_igeom_input => igeom_input + implicit none + integer, intent(out) :: f90wrap_igeom_input + + f90wrap_igeom_input = rw_geom_igeom_input +end subroutine f90wrap_rw_geom__get__igeom_input + +subroutine f90wrap_rw_geom__set__igeom_input(f90wrap_igeom_input) + use rw_geom, only: rw_geom_igeom_input => igeom_input + implicit none + integer, intent(in) :: f90wrap_igeom_input + + rw_geom_igeom_input = f90wrap_igeom_input +end subroutine f90wrap_rw_geom__set__igeom_input + +subroutine f90wrap_rw_geom__get__igeom_output(f90wrap_igeom_output) + use rw_geom, only: rw_geom_igeom_output => igeom_output + implicit none + integer, intent(out) :: f90wrap_igeom_output + + f90wrap_igeom_output = rw_geom_igeom_output +end subroutine f90wrap_rw_geom__get__igeom_output + +subroutine f90wrap_rw_geom__set__igeom_output(f90wrap_igeom_output) + use rw_geom, only: rw_geom_igeom_output => igeom_output + implicit none + integer, intent(in) :: f90wrap_igeom_output + + rw_geom_igeom_output = f90wrap_igeom_output +end subroutine f90wrap_rw_geom__set__igeom_output + +! End of module rw_geom defined in file ../src/lib/mod_rw_geom.f90 + diff --git a/edited_autogen_files/raffle.py b/edited_autogen_files/raffle.py index 034df2e2..0c7a634d 100644 --- a/edited_autogen_files/raffle.py +++ b/edited_autogen_files/raffle.py @@ -4,6 +4,592 @@ import logging import numpy +class Rw_Geom(f90wrap.runtime.FortranModule): + """ + Module rw_geom + + + Defined at ../src/lib/mod_rw_geom.f90 lines \ + 13-968 + + """ + @f90wrap.runtime.register_class("raffle.spec_type") + class spec_type(f90wrap.runtime.FortranDerivedType): + """ + Type(name=spec_type) + + + Defined at ../src/lib/mod_rw_geom.f90 lines \ + 26-32 + + """ + def __init__(self, handle=None): + """ + self = Spec_Type() + + + Defined at ../src/lib/mod_rw_geom.f90 lines \ + 26-32 + + + Returns + ------- + this : Spec_Type + Object to be constructed + + + Automatically generated constructor for spec_type + """ + f90wrap.runtime.FortranDerivedType.__init__(self) + result = _raffle.f90wrap_rw_geom__spec_type_initialise() + self._handle = result[0] if isinstance(result, tuple) else result + + def __del__(self): + """ + Destructor for class Spec_Type + + + Defined at ../src/lib/mod_rw_geom.f90 lines \ + 26-32 + + Parameters + ---------- + this : Spec_Type + Object to be destructed + + + Automatically generated destructor for spec_type + """ + if self._alloc: + _raffle.f90wrap_rw_geom__spec_type_finalise(this=self._handle) + + @property + def atom(self): + """ + Element atom ftype=real(real12) pytype=float + + + Defined at ../src/lib/mod_rw_geom.f90 line 27 + + """ + array_ndim, array_type, array_shape, array_handle = \ + _raffle.f90wrap_spec_type__array__atom(self._handle) + if array_handle in self._arrays: + atom = self._arrays[array_handle] + else: + atom = f90wrap.runtime.get_array(f90wrap.runtime.sizeof_fortran_t, + self._handle, + _raffle.f90wrap_spec_type__array__atom) + self._arrays[array_handle] = atom + return atom + + @atom.setter + def atom(self, atom): + self.atom[...] = atom + + @property + def mass(self): + """ + Element mass ftype=real(real12) pytype=float + + + Defined at ../src/lib/mod_rw_geom.f90 line 28 + + """ + return _raffle.f90wrap_spec_type__get__mass(self._handle) + + @mass.setter + def mass(self, mass): + _raffle.f90wrap_spec_type__set__mass(self._handle, mass) + + @property + def charge(self): + """ + Element charge ftype=real(real12) pytype=float + + + Defined at ../src/lib/mod_rw_geom.f90 line 29 + + """ + return _raffle.f90wrap_spec_type__get__charge(self._handle) + + @charge.setter + def charge(self, charge): + _raffle.f90wrap_spec_type__set__charge(self._handle, charge) + + @property + def name(self): + """ + Element name ftype=character(len=3) pytype=str + + + Defined at ../src/lib/mod_rw_geom.f90 line 30 + + """ + return _raffle.f90wrap_spec_type__get__name(self._handle) + + @name.setter + def name(self, name): + _raffle.f90wrap_spec_type__set__name(self._handle, name) + + @property + def num(self): + """ + Element num ftype=integer pytype=int + + + Defined at ../src/lib/mod_rw_geom.f90 line 31 + + """ + return _raffle.f90wrap_spec_type__get__num(self._handle) + + @num.setter + def num(self, num): + _raffle.f90wrap_spec_type__set__num(self._handle, num) + + @property + def lat(self): + """ + Element lat ftype=real(real12) pytype=float + + + Defined at ../src/lib/mod_rw_geom.f90 line 32 + + """ + array_ndim, array_type, array_shape, array_handle = \ + _raffle.f90wrap_spec_type__array__lat(self._handle) + if array_handle in self._arrays: + lat = self._arrays[array_handle] + else: + lat = f90wrap.runtime.get_array(f90wrap.runtime.sizeof_fortran_t, + self._handle, + _raffle.f90wrap_spec_type__array__lat) + self._arrays[array_handle] = lat + return lat + + @lat.setter + def lat(self, lat): + self.lat[...] = lat + + def __str__(self): + ret = ['{\n'] + ret.append(' atom : ') + ret.append(repr(self.atom)) + ret.append(',\n mass : ') + ret.append(repr(self.mass)) + ret.append(',\n charge : ') + ret.append(repr(self.charge)) + ret.append(',\n name : ') + ret.append(repr(self.name)) + ret.append(',\n num : ') + ret.append(repr(self.num)) + ret.append(',\n lat : ') + ret.append(repr(self.lat)) + ret.append('}') + return ''.join(ret) + + _dt_array_initialisers = [] + + + @f90wrap.runtime.register_class("raffle.bas_type") + class bas_type(f90wrap.runtime.FortranDerivedType): + """ + Type(name=bas_type) + + + Defined at ../src/lib/mod_rw_geom.f90 lines \ + 34-42 + + """ + def __init__(self, handle=None): + """ + self = Bas_Type() + + + Defined at ../src/lib/mod_rw_geom.f90 lines \ + 34-42 + + + Returns + ------- + this : Bas_Type + Object to be constructed + + + Automatically generated constructor for bas_type + """ + f90wrap.runtime.FortranDerivedType.__init__(self) + result = _raffle.f90wrap_rw_geom__bas_type_initialise() + self._handle = result[0] if isinstance(result, tuple) else result + + def __del__(self): + """ + Destructor for class Bas_Type + + + Defined at ../src/lib/mod_rw_geom.f90 lines \ + 34-42 + + Parameters + ---------- + this : Bas_Type + Object to be destructed + + + Automatically generated destructor for bas_type + """ + if self._alloc: + _raffle.f90wrap_rw_geom__bas_type_finalise(this=self._handle) + + def allocate_species(self, num_species=None, species_list=None, natom_list=None, \ + atoms=None): + """ + allocate_species__binding__bas_type(self[, num_species, species_list, \ + natom_list, atoms]) + + + Defined at ../src/lib/mod_rw_geom.f90 lines \ + 47-74 + + Parameters + ---------- + this : unknown + num_species : int + species_list : str array + natom_list : int array + atoms : float array + + """ + _raffle.f90wrap_rw_geom__allocate_species__binding__bas_type(this=self._handle, \ + num_species=num_species, species_list=species_list, natom_list=natom_list, \ + atoms=atoms) + + def init_array_spec(self): + self.spec = f90wrap.runtime.FortranDerivedTypeArray(self, + _raffle.f90wrap_bas_type__array_getitem__spec, + _raffle.f90wrap_bas_type__array_setitem__spec, + _raffle.f90wrap_bas_type__array_len__spec, + """ + Element spec ftype=type(spec_type) pytype=Spec_Type + + + Defined at ../src/lib/mod_rw_geom.f90 line 35 + + """, Rw_Geom.spec_type) + return self.spec + + @property + def nspec(self): + """ + Element nspec ftype=integer pytype=int + + + Defined at ../src/lib/mod_rw_geom.f90 line 36 + + """ + return _raffle.f90wrap_bas_type__get__nspec(self._handle) + + @nspec.setter + def nspec(self, nspec): + _raffle.f90wrap_bas_type__set__nspec(self._handle, nspec) + + @property + def natom(self): + """ + Element natom ftype=integer pytype=int + + + Defined at ../src/lib/mod_rw_geom.f90 line 37 + + """ + return _raffle.f90wrap_bas_type__get__natom(self._handle) + + @natom.setter + def natom(self, natom): + _raffle.f90wrap_bas_type__set__natom(self._handle, natom) + + @property + def energy(self): + """ + Element energy ftype=real(real12) pytype=float + + + Defined at ../src/lib/mod_rw_geom.f90 line 38 + + """ + return _raffle.f90wrap_bas_type__get__energy(self._handle) + + @energy.setter + def energy(self, energy): + _raffle.f90wrap_bas_type__set__energy(self._handle, energy) + + @property + def lcart(self): + """ + Element lcart ftype=logical pytype=bool + + + Defined at ../src/lib/mod_rw_geom.f90 line 39 + + """ + return _raffle.f90wrap_bas_type__get__lcart(self._handle) + + @lcart.setter + def lcart(self, lcart): + _raffle.f90wrap_bas_type__set__lcart(self._handle, lcart) + + @property + def sysname(self): + """ + Element sysname ftype=character(len=1024) pytype=str + + + Defined at ../src/lib/mod_rw_geom.f90 line 40 + + """ + return _raffle.f90wrap_bas_type__get__sysname(self._handle) + + @sysname.setter + def sysname(self, sysname): + _raffle.f90wrap_bas_type__set__sysname(self._handle, sysname) + + def __str__(self): + ret = ['{\n'] + ret.append(' nspec : ') + ret.append(repr(self.nspec)) + ret.append(',\n natom : ') + ret.append(repr(self.natom)) + ret.append(',\n energy : ') + ret.append(repr(self.energy)) + ret.append(',\n lcart : ') + ret.append(repr(self.lcart)) + ret.append(',\n sysname : ') + ret.append(repr(self.sysname)) + ret.append('}') + return ''.join(ret) + + _dt_array_initialisers = [init_array_spec] + + + + @f90wrap.runtime.register_class("raffle.bas_type_xnum_array") + class bas_type_xnum_array(f90wrap.runtime.FortranDerivedType): + """ + Type(name=bas_type_xnum_array) + + + Defined at ../src/lib/mod_generator.f90 lines \ + 19-21 + + """ + def __init__(self, handle=None): + """ + self = bas_Type() + + + Defined at ../src/lib/mod_generator.f90 lines \ + 19-21 + + + Returns + ------- + this : bas_Type + Object to be constructed + + + Automatically generated constructor for bas_type + """ + f90wrap.runtime.FortranDerivedType.__init__(self) + result = _raffle.f90wrap_rw_geom__bas_type_xnum_array_initialise() + self._handle = result[0] if isinstance(result, tuple) else result + + def __del__(self): + """ + Destructor for class bas_Type + + + Defined at ../src/lib/mod_generator.f90 lines \ + 19-21 + + Parameters + ---------- + this : bas_type + Object to be destructed + + + Automatically generated destructor for bas_type + """ + if self._alloc: + _raffle.f90wrap_rw_geom__bas_type_xnum_array_finalise(this=self._handle) + + def init_array_items(self): + self.items = f90wrap.runtime.FortranDerivedTypeArray(self, + _raffle.f90wrap_bas_type_xnum_array__array_getitem__items, + _raffle.f90wrap_bas_type_xnum_array__array_setitem__items, + _raffle.f90wrap_bas_type_xnum_array__array_len__items, + """ + Element items ftype=type(test_type) pytype=Test_Type + + + Defined at line 0 + + """, Rw_Geom.bas_type) + return self.items + + def allocate(self, size): + """ + Allocate the items array with the given size + + Parameters + ---------- + self : bas_type + size : int + Size of the items array + """ + _raffle.f90wrap_bas_type_xnum_array__array_alloc__items(self._handle, num=size) + + def deallocate(self): + """ + Deallocate the items array + """ + _raffle.f90wrap_bas_type_xnum_array__array_dealloc__items(self._handle) + + + + _dt_array_initialisers = [init_array_items] + + + @staticmethod + def geom_read(unit, lat, bas, length=None): + """ + geom_read(unit, lat, bas[, length]) + + + Defined at ../src/lib/mod_rw_geom.f90 lines \ + 79-111 + + Parameters + ---------- + unit : int + lat : float array + bas : Bas_Type + length : int + + """ + _raffle.f90wrap_rw_geom__geom_read(unit=unit, lat=lat, bas=bas._handle, \ + length=length) + + @staticmethod + def geom_write(unit, lat, bas): + """ + geom_write(unit, lat, bas) + + + Defined at ../src/lib/mod_rw_geom.f90 lines \ + 117-139 + + Parameters + ---------- + unit : int + lat : float array + bas : Bas_Type + + """ + _raffle.f90wrap_rw_geom__geom_write(unit=unit, lat=lat, bas=bas._handle) + + @staticmethod + def convert_bas(self, latconv): + """ + outbas = convert_bas(self, latconv) + + + Defined at ../src/lib/mod_rw_geom.f90 lines \ + 821-840 + + Parameters + ---------- + inbas : Bas_Type + latconv : float array + + Returns + ------- + outbas : Bas_Type + + """ + outbas = _raffle.f90wrap_rw_geom__convert_bas(inbas=self._handle, \ + latconv=latconv) + outbas = f90wrap.runtime.lookup_class("raffle.bas_type").from_handle(outbas, \ + alloc=True) + return outbas + + @staticmethod + def clone_bas(self, outbas, inlat=None, outlat=None, trans_dim=None): + """ + clone_bas(self, outbas[, inlat, outlat, trans_dim]) + + + Defined at ../src/lib/mod_rw_geom.f90 lines \ + 897-967 + + Parameters + ---------- + inbas : Bas_Type + outbas : Bas_Type + inlat : float array + outlat : float array + trans_dim : bool + + ----------------------------------------------------------------------------- + determines whether user wants output basis extra translational dimension + ----------------------------------------------------------------------------- + """ + _raffle.f90wrap_rw_geom__clone_bas(inbas=self._handle, outbas=outbas._handle, \ + inlat=inlat, outlat=outlat, trans_dim=trans_dim) + + @property + def igeom_input(self): + """ + Element igeom_input ftype=integer pytype=int + + + Defined at ../src/lib/mod_rw_geom.f90 line 24 + + """ + return _raffle.f90wrap_rw_geom__get__igeom_input() + + @igeom_input.setter + def igeom_input(self, igeom_input): + _raffle.f90wrap_rw_geom__set__igeom_input(igeom_input) + + @property + def igeom_output(self): + """ + Element igeom_output ftype=integer pytype=int + + + Defined at ../src/lib/mod_rw_geom.f90 line 24 + + """ + return _raffle.f90wrap_rw_geom__get__igeom_output() + + @igeom_output.setter + def igeom_output(self, igeom_output): + _raffle.f90wrap_rw_geom__set__igeom_output(igeom_output) + + def __str__(self): + ret = ['{\n'] + ret.append(' igeom_input : ') + ret.append(repr(self.igeom_input)) + ret.append(',\n igeom_output : ') + ret.append(repr(self.igeom_output)) + ret.append('}') + return ''.join(ret) + + _dt_array_initialisers = [] + + +rw_geom = Rw_Geom() + class Generator(f90wrap.runtime.FortranModule): """ Module generator From 2fb8d617e31b4a77805c6bceedecbd680251f289 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Thu, 18 Jul 2024 07:21:16 +0100 Subject: [PATCH 025/293] Move mod_rw_geom to special list --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dea88803..d22b0acb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,7 +70,7 @@ set(LIB_FILES mod_misc.f90 mod_misc_maths.f90 mod_misc_linalg.f90 - mod_rw_geom.f90 + # mod_rw_geom.f90 mod_rw_vasprun.f90 mod_edit_geom.f90 mod_elements.f90 @@ -81,7 +81,7 @@ set(LIB_FILES ) set(SPECIAL_LIB_FILES - # mod_rw_geom.f90 + mod_rw_geom.f90 mod_generator.f90 # mod_generator_sub.f90 ) From 32be25b537b4876d9be9525c7b456d866fabfe25 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Thu, 18 Jul 2024 09:11:40 +0100 Subject: [PATCH 026/293] Add ase bas_type converter --- CMakeLists.txt | 2 +- edited_autogen_files/f90wrap_mod_rw_geom.f90 | 230 ++++++++--------- edited_autogen_files/raffle.py | 246 +++++++++++-------- src/lib/mod_rw_geom.f90 | 18 +- 4 files changed, 269 insertions(+), 227 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d22b0acb..5f6d0489 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -247,7 +247,7 @@ if (BUILD_PYTHON) -m ${PROJECT_NAME} -k ${KIND_MAP} ${F90WRAP_FORTRAN_SRC_FILES} - # --only raffle_generator_type: + --only raffle_generator_type stoichiometry_type bas_type: DEPENDS ${F90WRAP_FORTRAN_SRC_FILES} WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMENT "Generating f90wrap signature file" diff --git a/edited_autogen_files/f90wrap_mod_rw_geom.f90 b/edited_autogen_files/f90wrap_mod_rw_geom.f90 index 02f407f8..8141ac33 100644 --- a/edited_autogen_files/f90wrap_mod_rw_geom.f90 +++ b/edited_autogen_files/f90wrap_mod_rw_geom.f90 @@ -592,8 +592,9 @@ end subroutine f90wrap_rw_geom__bas_type_xnum_array_finalise -subroutine f90wrap_rw_geom__allocate_species__binding__bas_type(this, num_species, species_list, natom_list, atoms, n0, & - n1, n2, n3) +subroutine f90wrap_rw_geom__allocate_species__binding__bas_type( & + this, num_species, species_symbols, species_count, atoms, n0, & + n1, n2, n3) use rw_geom, only: bas_type implicit none @@ -603,126 +604,131 @@ subroutine f90wrap_rw_geom__allocate_species__binding__bas_type(this, num_specie type(bas_type_ptr_type) :: this_ptr integer, intent(in), dimension(2) :: this integer, intent(in), optional :: num_species - character(3), intent(in), optional, dimension(n0) :: species_list - integer, intent(in), optional, dimension(n1) :: natom_list + character(3), intent(in), optional, dimension(n0) :: species_symbols + integer, intent(in), optional, dimension(n1) :: species_count real(4), intent(in), optional, dimension(n2,n3) :: atoms integer :: n0 - !f2py intent(hide), depend(species_list) :: n0 = shape(species_list,0) + !f2py intent(hide), depend(species_symbols) :: n0 = shape(species_symbols,0) integer :: n1 - !f2py intent(hide), depend(natom_list) :: n1 = shape(natom_list,0) + !f2py intent(hide), depend(species_count) :: n1 = shape(species_count,0) integer :: n2 !f2py intent(hide), depend(atoms) :: n2 = shape(atoms,0) integer :: n3 !f2py intent(hide), depend(atoms) :: n3 = shape(atoms,1) this_ptr = transfer(this, this_ptr) - call this_ptr%p%allocate_species(num_species=num_species, species_list=species_list, natom_list=natom_list, atoms=atoms) + call this_ptr%p%allocate_species( & + num_species=num_species, & + species_symbols=species_symbols, & + species_count=species_count, & + atoms=atoms & + ) end subroutine f90wrap_rw_geom__allocate_species__binding__bas_type -subroutine f90wrap_rw_geom__geom_read(unit, lat, bas, length) - use rw_geom, only: geom_read, bas_type - implicit none - - type bas_type_ptr_type - type(bas_type), pointer :: p => NULL() - end type bas_type_ptr_type - integer :: unit - !f2py intent(inout) unit - real(4), dimension(3,3) :: lat - !f2py intent(inout) lat - type(bas_type_ptr_type) :: bas_ptr - integer, intent(in), dimension(2) :: bas - integer, optional, intent(in) :: length - bas_ptr = transfer(bas, bas_ptr) - call geom_read(UNIT=unit, lat=lat, bas=bas_ptr%p, length=length) -end subroutine f90wrap_rw_geom__geom_read - -subroutine f90wrap_rw_geom__geom_write(unit, lat, bas) - use rw_geom, only: bas_type, geom_write - implicit none - - type bas_type_ptr_type - type(bas_type), pointer :: p => NULL() - end type bas_type_ptr_type - integer :: unit - !f2py intent(inout) unit - real(4), dimension(3,3) :: lat - !f2py intent(inout) lat - type(bas_type_ptr_type) :: bas_ptr - integer, intent(in), dimension(2) :: bas - bas_ptr = transfer(bas, bas_ptr) - call geom_write(UNIT=unit, lat=lat, bas=bas_ptr%p) -end subroutine f90wrap_rw_geom__geom_write - -subroutine f90wrap_rw_geom__convert_bas(inbas, ret_outbas, latconv) - use rw_geom, only: convert_bas, bas_type - implicit none - - type bas_type_ptr_type - type(bas_type), pointer :: p => NULL() - end type bas_type_ptr_type - type(bas_type_ptr_type) :: inbas_ptr - integer, intent(in), dimension(2) :: inbas - type(bas_type_ptr_type) :: ret_outbas_ptr - integer, intent(out), dimension(2) :: ret_outbas - real(4), dimension(3,3), intent(in) :: latconv - inbas_ptr = transfer(inbas, inbas_ptr) - allocate(ret_outbas_ptr%p) - ret_outbas_ptr%p = convert_bas(inbas=inbas_ptr%p, latconv=latconv) - ret_outbas = transfer(ret_outbas_ptr, ret_outbas) -end subroutine f90wrap_rw_geom__convert_bas - -subroutine f90wrap_rw_geom__clone_bas(inbas, outbas, inlat, outlat, trans_dim) - use rw_geom, only: clone_bas, bas_type - implicit none - - type bas_type_ptr_type - type(bas_type), pointer :: p => NULL() - end type bas_type_ptr_type - type(bas_type_ptr_type) :: inbas_ptr - integer, intent(in), dimension(2) :: inbas - type(bas_type_ptr_type) :: outbas_ptr - integer, intent(in), dimension(2) :: outbas - real(4), dimension(3,3), optional :: inlat - !f2py intent(inout) inlat - real(4), dimension(3,3), optional :: outlat - !f2py intent(inout) outlat - logical, optional, intent(in) :: trans_dim - inbas_ptr = transfer(inbas, inbas_ptr) - outbas_ptr = transfer(outbas, outbas_ptr) - call clone_bas(inbas=inbas_ptr%p, outbas=outbas_ptr%p, inlat=inlat, outlat=outlat, trans_dim=trans_dim) -end subroutine f90wrap_rw_geom__clone_bas - -subroutine f90wrap_rw_geom__get__igeom_input(f90wrap_igeom_input) - use rw_geom, only: rw_geom_igeom_input => igeom_input - implicit none - integer, intent(out) :: f90wrap_igeom_input - - f90wrap_igeom_input = rw_geom_igeom_input -end subroutine f90wrap_rw_geom__get__igeom_input - -subroutine f90wrap_rw_geom__set__igeom_input(f90wrap_igeom_input) - use rw_geom, only: rw_geom_igeom_input => igeom_input - implicit none - integer, intent(in) :: f90wrap_igeom_input - - rw_geom_igeom_input = f90wrap_igeom_input -end subroutine f90wrap_rw_geom__set__igeom_input - -subroutine f90wrap_rw_geom__get__igeom_output(f90wrap_igeom_output) - use rw_geom, only: rw_geom_igeom_output => igeom_output - implicit none - integer, intent(out) :: f90wrap_igeom_output - - f90wrap_igeom_output = rw_geom_igeom_output -end subroutine f90wrap_rw_geom__get__igeom_output - -subroutine f90wrap_rw_geom__set__igeom_output(f90wrap_igeom_output) - use rw_geom, only: rw_geom_igeom_output => igeom_output - implicit none - integer, intent(in) :: f90wrap_igeom_output - - rw_geom_igeom_output = f90wrap_igeom_output -end subroutine f90wrap_rw_geom__set__igeom_output +! subroutine f90wrap_rw_geom__geom_read(unit, lat, bas, length) +! use rw_geom, only: geom_read, bas_type +! implicit none + +! type bas_type_ptr_type +! type(bas_type), pointer :: p => NULL() +! end type bas_type_ptr_type +! integer :: unit +! !f2py intent(inout) unit +! real(4), dimension(3,3) :: lat +! !f2py intent(inout) lat +! type(bas_type_ptr_type) :: bas_ptr +! integer, intent(in), dimension(2) :: bas +! integer, optional, intent(in) :: length +! bas_ptr = transfer(bas, bas_ptr) +! call geom_read(UNIT=unit, lat=lat, bas=bas_ptr%p, length=length) +! end subroutine f90wrap_rw_geom__geom_read + +! subroutine f90wrap_rw_geom__geom_write(unit, lat, bas) +! use rw_geom, only: bas_type, geom_write +! implicit none + +! type bas_type_ptr_type +! type(bas_type), pointer :: p => NULL() +! end type bas_type_ptr_type +! integer :: unit +! !f2py intent(inout) unit +! real(4), dimension(3,3) :: lat +! !f2py intent(inout) lat +! type(bas_type_ptr_type) :: bas_ptr +! integer, intent(in), dimension(2) :: bas +! bas_ptr = transfer(bas, bas_ptr) +! call geom_write(UNIT=unit, lat=lat, bas=bas_ptr%p) +! end subroutine f90wrap_rw_geom__geom_write + +! subroutine f90wrap_rw_geom__convert_bas(inbas, ret_outbas, latconv) +! use rw_geom, only: convert_bas, bas_type +! implicit none + +! type bas_type_ptr_type +! type(bas_type), pointer :: p => NULL() +! end type bas_type_ptr_type +! type(bas_type_ptr_type) :: inbas_ptr +! integer, intent(in), dimension(2) :: inbas +! type(bas_type_ptr_type) :: ret_outbas_ptr +! integer, intent(out), dimension(2) :: ret_outbas +! real(4), dimension(3,3), intent(in) :: latconv +! inbas_ptr = transfer(inbas, inbas_ptr) +! allocate(ret_outbas_ptr%p) +! ret_outbas_ptr%p = convert_bas(inbas=inbas_ptr%p, latconv=latconv) +! ret_outbas = transfer(ret_outbas_ptr, ret_outbas) +! end subroutine f90wrap_rw_geom__convert_bas + +! subroutine f90wrap_rw_geom__clone_bas(inbas, outbas, inlat, outlat, trans_dim) +! use rw_geom, only: clone_bas, bas_type +! implicit none + +! type bas_type_ptr_type +! type(bas_type), pointer :: p => NULL() +! end type bas_type_ptr_type +! type(bas_type_ptr_type) :: inbas_ptr +! integer, intent(in), dimension(2) :: inbas +! type(bas_type_ptr_type) :: outbas_ptr +! integer, intent(in), dimension(2) :: outbas +! real(4), dimension(3,3), optional :: inlat +! !f2py intent(inout) inlat +! real(4), dimension(3,3), optional :: outlat +! !f2py intent(inout) outlat +! logical, optional, intent(in) :: trans_dim +! inbas_ptr = transfer(inbas, inbas_ptr) +! outbas_ptr = transfer(outbas, outbas_ptr) +! call clone_bas(inbas=inbas_ptr%p, outbas=outbas_ptr%p, inlat=inlat, outlat=outlat, trans_dim=trans_dim) +! end subroutine f90wrap_rw_geom__clone_bas + +! subroutine f90wrap_rw_geom__get__igeom_input(f90wrap_igeom_input) +! use rw_geom, only: rw_geom_igeom_input => igeom_input +! implicit none +! integer, intent(out) :: f90wrap_igeom_input + +! f90wrap_igeom_input = rw_geom_igeom_input +! end subroutine f90wrap_rw_geom__get__igeom_input + +! subroutine f90wrap_rw_geom__set__igeom_input(f90wrap_igeom_input) +! use rw_geom, only: rw_geom_igeom_input => igeom_input +! implicit none +! integer, intent(in) :: f90wrap_igeom_input + +! rw_geom_igeom_input = f90wrap_igeom_input +! end subroutine f90wrap_rw_geom__set__igeom_input + +! subroutine f90wrap_rw_geom__get__igeom_output(f90wrap_igeom_output) +! use rw_geom, only: rw_geom_igeom_output => igeom_output +! implicit none +! integer, intent(out) :: f90wrap_igeom_output + +! f90wrap_igeom_output = rw_geom_igeom_output +! end subroutine f90wrap_rw_geom__get__igeom_output + +! subroutine f90wrap_rw_geom__set__igeom_output(f90wrap_igeom_output) +! use rw_geom, only: rw_geom_igeom_output => igeom_output +! implicit none +! integer, intent(in) :: f90wrap_igeom_output + +! rw_geom_igeom_output = f90wrap_igeom_output +! end subroutine f90wrap_rw_geom__set__igeom_output ! End of module rw_geom defined in file ../src/lib/mod_rw_geom.f90 diff --git a/edited_autogen_files/raffle.py b/edited_autogen_files/raffle.py index 0c7a634d..79834d7a 100644 --- a/edited_autogen_files/raffle.py +++ b/edited_autogen_files/raffle.py @@ -241,11 +241,11 @@ def __del__(self): if self._alloc: _raffle.f90wrap_rw_geom__bas_type_finalise(this=self._handle) - def allocate_species(self, num_species=None, species_list=None, natom_list=None, \ + def allocate_species(self, num_species=None, species_symbols=None, species_count=None, \ atoms=None): """ - allocate_species__binding__bas_type(self[, num_species, species_list, \ - natom_list, atoms]) + allocate_species__binding__bas_type(self[, num_species, species_symbols, \ + species_count, atoms]) Defined at ../src/lib/mod_rw_geom.f90 lines \ @@ -255,13 +255,13 @@ def allocate_species(self, num_species=None, species_list=None, natom_list=None, ---------- this : unknown num_species : int - species_list : str array - natom_list : int array + species_symbols : str array + species_count : int array atoms : float array """ _raffle.f90wrap_rw_geom__allocate_species__binding__bas_type(this=self._handle, \ - num_species=num_species, species_list=species_list, natom_list=natom_list, \ + num_species=num_species, species_symbols=species_symbols, species_count=species_count, \ atoms=atoms) def init_array_spec(self): @@ -458,132 +458,168 @@ def deallocate(self): _dt_array_initialisers = [init_array_items] - @staticmethod - def geom_read(unit, lat, bas, length=None): - """ - geom_read(unit, lat, bas[, length]) + def convert_ase_to_bas(ase_atoms): + # Create a new instance of bas_type + bas = Rw_Geom.bas_type() + # Set the number of species + bas.nspec = len(ase_atoms.get_chemical_symbols()) - Defined at ../src/lib/mod_rw_geom.f90 lines \ - 79-111 - - Parameters - ---------- - unit : int - lat : float array - bas : Bas_Type - length : int + # Set the number of atoms + bas.natom = len(ase_atoms) - """ - _raffle.f90wrap_rw_geom__geom_read(unit=unit, lat=lat, bas=bas._handle, \ - length=length) - - @staticmethod - def geom_write(unit, lat, bas): - """ - geom_write(unit, lat, bas) + # Set the energy + # bas.energy = ase_atoms.get_total_energy() + # Set the lattice vectors + lat = ase_atoms.get_cell().flatten() - Defined at ../src/lib/mod_rw_geom.f90 lines \ - 117-139 + # Set the system name + bas.sysname = ase_atoms.get_chemical_formula() - Parameters - ---------- - unit : int - lat : float array - bas : Bas_Type + # Set the species list + species_symbols = ase_atoms.get_chemical_symbols() + species_symbols_unique = sorted(set(species_symbols)) + species_count = [] + atoms = [] + positions = ase_atoms.get_positions() + for species in species_symbols_unique: + species_count.append(sum([1 for symbol in species_symbols if symbol == species])) + for j, symbol in enumerate(species_symbols): + if symbol == species: + atoms.append(positions[j]) - """ - _raffle.f90wrap_rw_geom__geom_write(unit=unit, lat=lat, bas=bas._handle) - - @staticmethod - def convert_bas(self, latconv): - """ - outbas = convert_bas(self, latconv) + # Allocate memory for the atom list + bas.allocate_species(species_symbols=species_symbols, species_count=species_count, atoms=atoms) + return lat, bas + + # @staticmethod + # def geom_read(unit, lat, bas, length=None): + # """ + # geom_read(unit, lat, bas[, length]) - Defined at ../src/lib/mod_rw_geom.f90 lines \ - 821-840 - Parameters - ---------- - inbas : Bas_Type - latconv : float array + # Defined at ../src/lib/mod_rw_geom.f90 lines \ + # 79-111 - Returns - ------- - outbas : Bas_Type + # Parameters + # ---------- + # unit : int + # lat : float array + # bas : Bas_Type + # length : int - """ - outbas = _raffle.f90wrap_rw_geom__convert_bas(inbas=self._handle, \ - latconv=latconv) - outbas = f90wrap.runtime.lookup_class("raffle.bas_type").from_handle(outbas, \ - alloc=True) - return outbas + # """ + # _raffle.f90wrap_rw_geom__geom_read(unit=unit, lat=lat, bas=bas._handle, \ + # length=length) - @staticmethod - def clone_bas(self, outbas, inlat=None, outlat=None, trans_dim=None): - """ - clone_bas(self, outbas[, inlat, outlat, trans_dim]) + # @staticmethod + # def geom_write(unit, lat, bas): + # """ + # geom_write(unit, lat, bas) - Defined at ../src/lib/mod_rw_geom.f90 lines \ - 897-967 - - Parameters - ---------- - inbas : Bas_Type - outbas : Bas_Type - inlat : float array - outlat : float array - trans_dim : bool - - ----------------------------------------------------------------------------- - determines whether user wants output basis extra translational dimension - ----------------------------------------------------------------------------- - """ - _raffle.f90wrap_rw_geom__clone_bas(inbas=self._handle, outbas=outbas._handle, \ - inlat=inlat, outlat=outlat, trans_dim=trans_dim) + # Defined at ../src/lib/mod_rw_geom.f90 lines \ + # 117-139 + + # Parameters + # ---------- + # unit : int + # lat : float array + # bas : Bas_Type + + # """ + # _raffle.f90wrap_rw_geom__geom_write(unit=unit, lat=lat, bas=bas._handle) - @property - def igeom_input(self): - """ - Element igeom_input ftype=integer pytype=int + # @staticmethod + # def convert_bas(self, latconv): + # """ + # outbas = convert_bas(self, latconv) + + + # Defined at ../src/lib/mod_rw_geom.f90 lines \ + # 821-840 + + # Parameters + # ---------- + # inbas : Bas_Type + # latconv : float array + + # Returns + # ------- + # outbas : Bas_Type + + # """ + # outbas = _raffle.f90wrap_rw_geom__convert_bas(inbas=self._handle, \ + # latconv=latconv) + # outbas = f90wrap.runtime.lookup_class("raffle.bas_type").from_handle(outbas, \ + # alloc=True) + # return outbas + + # @staticmethod + # def clone_bas(self, outbas, inlat=None, outlat=None, trans_dim=None): + # """ + # clone_bas(self, outbas[, inlat, outlat, trans_dim]) + + + # Defined at ../src/lib/mod_rw_geom.f90 lines \ + # 897-967 + + # Parameters + # ---------- + # inbas : Bas_Type + # outbas : Bas_Type + # inlat : float array + # outlat : float array + # trans_dim : bool + + # ----------------------------------------------------------------------------- + # determines whether user wants output basis extra translational dimension + # ----------------------------------------------------------------------------- + # """ + # _raffle.f90wrap_rw_geom__clone_bas(inbas=self._handle, outbas=outbas._handle, \ + # inlat=inlat, outlat=outlat, trans_dim=trans_dim) + + # @property + # def igeom_input(self): + # """ + # Element igeom_input ftype=integer pytype=int - Defined at ../src/lib/mod_rw_geom.f90 line 24 + # Defined at ../src/lib/mod_rw_geom.f90 line 24 - """ - return _raffle.f90wrap_rw_geom__get__igeom_input() + # """ + # return _raffle.f90wrap_rw_geom__get__igeom_input() - @igeom_input.setter - def igeom_input(self, igeom_input): - _raffle.f90wrap_rw_geom__set__igeom_input(igeom_input) + # @igeom_input.setter + # def igeom_input(self, igeom_input): + # _raffle.f90wrap_rw_geom__set__igeom_input(igeom_input) - @property - def igeom_output(self): - """ - Element igeom_output ftype=integer pytype=int + # @property + # def igeom_output(self): + # """ + # Element igeom_output ftype=integer pytype=int - Defined at ../src/lib/mod_rw_geom.f90 line 24 + # Defined at ../src/lib/mod_rw_geom.f90 line 24 - """ - return _raffle.f90wrap_rw_geom__get__igeom_output() + # """ + # return _raffle.f90wrap_rw_geom__get__igeom_output() - @igeom_output.setter - def igeom_output(self, igeom_output): - _raffle.f90wrap_rw_geom__set__igeom_output(igeom_output) + # @igeom_output.setter + # def igeom_output(self, igeom_output): + # _raffle.f90wrap_rw_geom__set__igeom_output(igeom_output) - def __str__(self): - ret = ['{\n'] - ret.append(' igeom_input : ') - ret.append(repr(self.igeom_input)) - ret.append(',\n igeom_output : ') - ret.append(repr(self.igeom_output)) - ret.append('}') - return ''.join(ret) + # def __str__(self): + # ret = ['{\n'] + # ret.append(' igeom_input : ') + # ret.append(repr(self.igeom_input)) + # ret.append(',\n igeom_output : ') + # ret.append(repr(self.igeom_output)) + # ret.append('}') + # return ''.join(ret) _dt_array_initialisers = [] diff --git a/src/lib/mod_rw_geom.f90 b/src/lib/mod_rw_geom.f90 index 3969a091..36d70d5a 100644 --- a/src/lib/mod_rw_geom.f90 +++ b/src/lib/mod_rw_geom.f90 @@ -56,12 +56,12 @@ module rw_geom contains - subroutine allocate_species(this, num_species, species_list, natom_list, atoms) + subroutine allocate_species(this, num_species, species_symbols, species_count, atoms) implicit none class(bas_type), intent(inout) :: this integer, intent(in), optional :: num_species - character(3), dimension(:), intent(in), optional :: species_list - integer, dimension(:), intent(in), optional :: natom_list + character(3), dimension(:), intent(in), optional :: species_symbols + integer, dimension(:), intent(in), optional :: species_count real(real12), dimension(:,:), intent(in), optional :: atoms integer :: i, istart, iend @@ -71,14 +71,14 @@ subroutine allocate_species(this, num_species, species_list, natom_list, atoms) if(allocated(this%spec)) deallocate(this%spec) allocate(this%spec(this%nspec)) - species_check: if(present(species_list))then - if(size(species_list).ne.this%nspec) exit species_check - this%spec(:)%name = species_list + species_check: if(present(species_symbols))then + if(size(species_symbols).ne.this%nspec) exit species_check + this%spec(:)%name = species_symbols end if species_check - natom_check: if(present(natom_list))then - if(size(natom_list).ne.this%nspec) exit natom_check - this%spec(:)%num = natom_list + natom_check: if(present(species_count))then + if(size(species_count).ne.this%nspec) exit natom_check + this%spec(:)%num = species_count istart = 1 do i = 1, this%nspec iend = istart + this%spec(i)%num - 1 From 5c48cf6a9b998008c7b245209bba9a2149ecc331 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Thu, 18 Jul 2024 09:48:01 +0100 Subject: [PATCH 027/293] Add bas_type to ase converter --- edited_autogen_files/raffle.py | 35 ++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/edited_autogen_files/raffle.py b/edited_autogen_files/raffle.py index 79834d7a..039dd19c 100644 --- a/edited_autogen_files/raffle.py +++ b/edited_autogen_files/raffle.py @@ -458,13 +458,20 @@ def deallocate(self): _dt_array_initialisers = [init_array_items] + ## make this a procedure of bas_type + ## i.e. bas_type.from_ase + ## also make it part of initialisation. If ase.Atoms is passed, then convert it to bas_type @staticmethod def convert_ase_to_bas(ase_atoms): # Create a new instance of bas_type bas = Rw_Geom.bas_type() + # Get the species symbols + species_symbols = ase_atoms.get_chemical_symbols() + species_symbols_unique = sorted(set(species_symbols)) + # Set the number of species - bas.nspec = len(ase_atoms.get_chemical_symbols()) + bas.nspec = len(species_symbols_unique) # Set the number of atoms bas.natom = len(ase_atoms) @@ -479,8 +486,6 @@ def convert_ase_to_bas(ase_atoms): bas.sysname = ase_atoms.get_chemical_formula() # Set the species list - species_symbols = ase_atoms.get_chemical_symbols() - species_symbols_unique = sorted(set(species_symbols)) species_count = [] atoms = [] positions = ase_atoms.get_positions() @@ -491,9 +496,31 @@ def convert_ase_to_bas(ase_atoms): atoms.append(positions[j]) # Allocate memory for the atom list - bas.allocate_species(species_symbols=species_symbols, species_count=species_count, atoms=atoms) + bas.allocate_species(species_symbols=species_symbols_unique, species_count=species_count, atoms=atoms) return lat, bas + + @staticmethod + def convert_bas_to_ase(bas): + # Create a new instance of ase.Atoms + from ase import Atoms + + # # Set the lattice vectors + # atoms.set_cell(bas.lat) + + # Set the species list + positions = [] + species_string = "" + for i in range(bas.nspec): + for j in range(bas.spec[i].num): + species_string += str(bas.spec[i].name.decode()).strip() + positions.append(bas.spec[i].atom[j]) + + # Set the positions + print(species_string) + print(positions) + + return Atoms(species_string, positions) # @staticmethod # def geom_read(unit, lat, bas, length=None): From 5ef9300c5e30e5f8d54be03bc06294f3e3a92865 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Thu, 18 Jul 2024 10:44:00 +0100 Subject: [PATCH 028/293] Move conversion procedures into bas_type --- edited_autogen_files/raffle.py | 118 +++++++++++++++------------------ src/lib/mod_rw_geom.f90 | 5 +- 2 files changed, 58 insertions(+), 65 deletions(-) diff --git a/edited_autogen_files/raffle.py b/edited_autogen_files/raffle.py index 039dd19c..f845b506 100644 --- a/edited_autogen_files/raffle.py +++ b/edited_autogen_files/raffle.py @@ -3,6 +3,7 @@ import f90wrap.runtime import logging import numpy +from ase import Atoms class Rw_Geom(f90wrap.runtime.FortranModule): """ @@ -278,6 +279,60 @@ def init_array_spec(self): """, Rw_Geom.spec_type) return self.spec + def toase(self): + + # Set the species list + positions = [] + species_string = "" + for i in range(self.nspec): + for j in range(self.spec[i].num): + species_string += str(self.spec[i].name.decode()).strip() + positions.append(self.spec[i].atom[j]) + + # Set the atoms + atoms = Atoms(species_string, positions) + atoms.set_pbc(self.pbc) + + # Set the lattice vectors + atoms.set_cell(bas.lat) + + return atoms + + def fromase(self, atoms): + + # Get the species symbols + species_symbols = atoms.get_chemical_symbols() + species_symbols_unique = sorted(set(species_symbols)) + + # Set the number of species + self.nspec = len(species_symbols_unique) + + # Set the number of atoms + self.natom = len(atoms) + + # Set the energy + # self.energy = atoms.get_total_energy() + + # # Set the lattice vectors + self.lat = atoms.get_cell().flatten() + self.pbc = atoms.pbc + + # Set the system name + self.sysname = atoms.get_chemical_formula() + + # Set the species list + species_count = [] + atom_positions = [] + positions = atoms.get_positions() + for species in species_symbols_unique: + species_count.append(sum([1 for symbol in species_symbols if symbol == species])) + for j, symbol in enumerate(species_symbols): + if symbol == species: + atom_positions.append(positions[j]) + + # Allocate memory for the atom list + self.allocate_species(species_symbols=species_symbols_unique, species_count=species_count, atoms=atom_positions) + @property def nspec(self): """ @@ -457,70 +512,7 @@ def deallocate(self): _dt_array_initialisers = [init_array_items] - - ## make this a procedure of bas_type - ## i.e. bas_type.from_ase - ## also make it part of initialisation. If ase.Atoms is passed, then convert it to bas_type - @staticmethod - def convert_ase_to_bas(ase_atoms): - # Create a new instance of bas_type - bas = Rw_Geom.bas_type() - - # Get the species symbols - species_symbols = ase_atoms.get_chemical_symbols() - species_symbols_unique = sorted(set(species_symbols)) - # Set the number of species - bas.nspec = len(species_symbols_unique) - - # Set the number of atoms - bas.natom = len(ase_atoms) - - # Set the energy - # bas.energy = ase_atoms.get_total_energy() - - # Set the lattice vectors - lat = ase_atoms.get_cell().flatten() - - # Set the system name - bas.sysname = ase_atoms.get_chemical_formula() - - # Set the species list - species_count = [] - atoms = [] - positions = ase_atoms.get_positions() - for species in species_symbols_unique: - species_count.append(sum([1 for symbol in species_symbols if symbol == species])) - for j, symbol in enumerate(species_symbols): - if symbol == species: - atoms.append(positions[j]) - - # Allocate memory for the atom list - bas.allocate_species(species_symbols=species_symbols_unique, species_count=species_count, atoms=atoms) - - return lat, bas - - @staticmethod - def convert_bas_to_ase(bas): - # Create a new instance of ase.Atoms - from ase import Atoms - - # # Set the lattice vectors - # atoms.set_cell(bas.lat) - - # Set the species list - positions = [] - species_string = "" - for i in range(bas.nspec): - for j in range(bas.spec[i].num): - species_string += str(bas.spec[i].name.decode()).strip() - positions.append(bas.spec[i].atom[j]) - - # Set the positions - print(species_string) - print(positions) - - return Atoms(species_string, positions) # @staticmethod # def geom_read(unit, lat, bas, length=None): diff --git a/src/lib/mod_rw_geom.f90 b/src/lib/mod_rw_geom.f90 index 36d70d5a..6fc48478 100644 --- a/src/lib/mod_rw_geom.f90 +++ b/src/lib/mod_rw_geom.f90 @@ -35,14 +35,15 @@ module rw_geom real(real12) :: charge character(len=3) :: name integer :: num - real(real12) :: lat(3,3) end type spec_type type bas_type type(spec_type), allocatable, dimension(:) :: spec integer :: nspec integer :: natom real(real12) :: energy - logical :: lcart=.false. + real(real12) :: lat(3,3) = 0._real12 + logical :: lcart = .false. + logical, dimension(3) :: pbc = .true. character(len=1024) :: sysname contains procedure, pass(this) :: allocate_species From 6c1809bb7aece779a2d38ee463e27fbe57e28c82 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Thu, 18 Jul 2024 11:09:21 +0100 Subject: [PATCH 029/293] Add bas_type initialisation --- edited_autogen_files/raffle.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/edited_autogen_files/raffle.py b/edited_autogen_files/raffle.py index f845b506..3f22e154 100644 --- a/edited_autogen_files/raffle.py +++ b/edited_autogen_files/raffle.py @@ -202,7 +202,7 @@ class bas_type(f90wrap.runtime.FortranDerivedType): 34-42 """ - def __init__(self, handle=None): + def __init__(self, handle=None, atoms=None): """ self = Bas_Type() @@ -222,6 +222,9 @@ def __init__(self, handle=None): f90wrap.runtime.FortranDerivedType.__init__(self) result = _raffle.f90wrap_rw_geom__bas_type_initialise() self._handle = result[0] if isinstance(result, tuple) else result + + if atoms is not None: + self.fromase(atoms) def __del__(self): """ From a3cc02327624147c741f0be18a42e7f50b099cdc Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Thu, 18 Jul 2024 12:16:44 +0100 Subject: [PATCH 030/293] Move lattice into bas_type from spec_type --- edited_autogen_files/f90wrap_mod_rw_geom.f90 | 63 +++++++++----- edited_autogen_files/raffle.py | 86 +++++++++++++------- 2 files changed, 98 insertions(+), 51 deletions(-) diff --git a/edited_autogen_files/f90wrap_mod_rw_geom.f90 b/edited_autogen_files/f90wrap_mod_rw_geom.f90 index 8141ac33..57471ed2 100644 --- a/edited_autogen_files/f90wrap_mod_rw_geom.f90 +++ b/edited_autogen_files/f90wrap_mod_rw_geom.f90 @@ -137,27 +137,6 @@ subroutine f90wrap_spec_type__set__num(this, f90wrap_num) this_ptr%p%num = f90wrap_num end subroutine f90wrap_spec_type__set__num -subroutine f90wrap_spec_type__array__lat(this, nd, dtype, dshape, dloc) - use rw_geom, only: spec_type - use, intrinsic :: iso_c_binding, only : c_int - implicit none - type spec_type_ptr_type - type(spec_type), pointer :: p => NULL() - end type spec_type_ptr_type - integer(c_int), intent(in) :: this(2) - type(spec_type_ptr_type) :: this_ptr - integer(c_int), intent(out) :: nd - integer(c_int), intent(out) :: dtype - integer(c_int), dimension(10), intent(out) :: dshape - integer*8, intent(out) :: dloc - - nd = 2 - dtype = 11 - this_ptr = transfer(this, this_ptr) - dshape(1:2) = shape(this_ptr%p%lat) - dloc = loc(this_ptr%p%lat) -end subroutine f90wrap_spec_type__array__lat - subroutine f90wrap_rw_geom__spec_type_initialise(this) use rw_geom, only: spec_type implicit none @@ -351,6 +330,27 @@ subroutine f90wrap_bas_type__set__energy(this, f90wrap_energy) this_ptr%p%energy = f90wrap_energy end subroutine f90wrap_bas_type__set__energy +subroutine f90wrap_bas_type__array__lat(this, nd, dtype, dshape, dloc) + use rw_geom, only: bas_type + use, intrinsic :: iso_c_binding, only : c_int + implicit none + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + integer(c_int), intent(in) :: this(2) + type(bas_type_ptr_type) :: this_ptr + integer(c_int), intent(out) :: nd + integer(c_int), intent(out) :: dtype + integer(c_int), dimension(10), intent(out) :: dshape + integer*8, intent(out) :: dloc + + nd = 2 + dtype = 11 + this_ptr = transfer(this, this_ptr) + dshape(1:2) = shape(this_ptr%p%lat) + dloc = loc(this_ptr%p%lat) +end subroutine f90wrap_bas_type__array__lat + subroutine f90wrap_bas_type__get__lcart(this, f90wrap_lcart) use rw_geom, only: bas_type implicit none @@ -379,6 +379,27 @@ subroutine f90wrap_bas_type__set__lcart(this, f90wrap_lcart) this_ptr%p%lcart = f90wrap_lcart end subroutine f90wrap_bas_type__set__lcart +subroutine f90wrap_bas_type__array__pbc(this, nd, dtype, dshape, dloc) + use rw_geom, only: bas_type + use, intrinsic :: iso_c_binding, only : c_int + implicit none + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + integer(c_int), intent(in) :: this(2) + type(bas_type_ptr_type) :: this_ptr + integer(c_int), intent(out) :: nd + integer(c_int), intent(out) :: dtype + integer(c_int), dimension(10), intent(out) :: dshape + integer*8, intent(out) :: dloc + + nd = 1 + dtype = 5 + this_ptr = transfer(this, this_ptr) + dshape(1:1) = shape(this_ptr%p%pbc) + dloc = loc(this_ptr%p%pbc) +end subroutine f90wrap_bas_type__array__pbc + subroutine f90wrap_bas_type__get__sysname(this, f90wrap_sysname) use rw_geom, only: bas_type implicit none diff --git a/edited_autogen_files/raffle.py b/edited_autogen_files/raffle.py index 3f22e154..98bcbf3a 100644 --- a/edited_autogen_files/raffle.py +++ b/edited_autogen_files/raffle.py @@ -148,30 +148,6 @@ def num(self): def num(self, num): _raffle.f90wrap_spec_type__set__num(self._handle, num) - @property - def lat(self): - """ - Element lat ftype=real(real12) pytype=float - - - Defined at ../src/lib/mod_rw_geom.f90 line 32 - - """ - array_ndim, array_type, array_shape, array_handle = \ - _raffle.f90wrap_spec_type__array__lat(self._handle) - if array_handle in self._arrays: - lat = self._arrays[array_handle] - else: - lat = f90wrap.runtime.get_array(f90wrap.runtime.sizeof_fortran_t, - self._handle, - _raffle.f90wrap_spec_type__array__lat) - self._arrays[array_handle] = lat - return lat - - @lat.setter - def lat(self, lat): - self.lat[...] = lat - def __str__(self): ret = ['{\n'] ret.append(' atom : ') @@ -184,8 +160,6 @@ def __str__(self): ret.append(repr(self.name)) ret.append(',\n num : ') ret.append(repr(self.num)) - ret.append(',\n lat : ') - ret.append(repr(self.lat)) ret.append('}') return ''.join(ret) @@ -381,13 +355,37 @@ def energy(self): def energy(self, energy): _raffle.f90wrap_bas_type__set__energy(self._handle, energy) + @property + def lat(self): + """ + Element lat ftype=real(real12) pytype=float + + + Defined at /Users/nedtaylor/DCoding/DGit/raffle/src/lib/mod_rw_geom.f90 line 38 + + """ + array_ndim, array_type, array_shape, array_handle = \ + _raffle.f90wrap_bas_type__array__lat(self._handle) + if array_handle in self._arrays: + lat = self._arrays[array_handle] + else: + lat = f90wrap.runtime.get_array(f90wrap.runtime.sizeof_fortran_t, + self._handle, + _raffle.f90wrap_bas_type__array__lat) + self._arrays[array_handle] = lat + return lat + + @lat.setter + def lat(self, lat): + self.lat[...] = lat + @property def lcart(self): """ Element lcart ftype=logical pytype=bool - Defined at ../src/lib/mod_rw_geom.f90 line 39 + Defined at /Users/nedtaylor/DCoding/DGit/raffle/src/lib/mod_rw_geom.f90 line 39 """ return _raffle.f90wrap_bas_type__get__lcart(self._handle) @@ -396,21 +394,45 @@ def lcart(self): def lcart(self, lcart): _raffle.f90wrap_bas_type__set__lcart(self._handle, lcart) + @property + def pbc(self): + """ + Element pbc ftype=logical pytype=bool + + + Defined at /Users/nedtaylor/DCoding/DGit/raffle/src/lib/mod_rw_geom.f90 line 40 + + """ + array_ndim, array_type, array_shape, array_handle = \ + _raffle.f90wrap_bas_type__array__pbc(self._handle) + if array_handle in self._arrays: + pbc = self._arrays[array_handle] + else: + pbc = f90wrap.runtime.get_array(f90wrap.runtime.sizeof_fortran_t, + self._handle, + _raffle.f90wrap_bas_type__array__pbc) + self._arrays[array_handle] = pbc + return pbc + + @pbc.setter + def pbc(self, pbc): + self.pbc[...] = pbc + @property def sysname(self): """ Element sysname ftype=character(len=1024) pytype=str - Defined at ../src/lib/mod_rw_geom.f90 line 40 + Defined at /Users/nedtaylor/DCoding/DGit/raffle/src/lib/mod_rw_geom.f90 line 41 """ return _raffle.f90wrap_bas_type__get__sysname(self._handle) - + @sysname.setter def sysname(self, sysname): _raffle.f90wrap_bas_type__set__sysname(self._handle, sysname) - + def __str__(self): ret = ['{\n'] ret.append(' nspec : ') @@ -419,8 +441,12 @@ def __str__(self): ret.append(repr(self.natom)) ret.append(',\n energy : ') ret.append(repr(self.energy)) + ret.append(',\n lat : ') + ret.append(repr(self.lat)) ret.append(',\n lcart : ') ret.append(repr(self.lcart)) + ret.append(',\n pbc : ') + ret.append(repr(self.pbc)) ret.append(',\n sysname : ') ret.append(repr(self.sysname)) ret.append('}') From d37449b627b5dea812a654f06f98ed999c2636a7 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Thu, 18 Jul 2024 13:07:17 +0100 Subject: [PATCH 031/293] Remove print_hello test --- .../f90wrap_mod_generator.f90 | 13 ------- edited_autogen_files/raffle.py | 37 ++++++------------- src/lib/mod_generator.f90 | 9 ----- 3 files changed, 11 insertions(+), 48 deletions(-) diff --git a/edited_autogen_files/f90wrap_mod_generator.f90 b/edited_autogen_files/f90wrap_mod_generator.f90 index a1a62124..f03c0b08 100644 --- a/edited_autogen_files/f90wrap_mod_generator.f90 +++ b/edited_autogen_files/f90wrap_mod_generator.f90 @@ -364,18 +364,5 @@ subroutine f90wrap_generator__generate__binding__rgt( & end if end subroutine f90wrap_generator__generate__binding__rgt -subroutine f90wrap_generator__print_hello__binding__raffle_generator_type(this) - use generator, only: raffle_generator_type - implicit none - - type raffle_generator_type_ptr_type - type(raffle_generator_type), pointer :: p => NULL() - end type raffle_generator_type_ptr_type - type(raffle_generator_type_ptr_type) :: this_ptr - integer, intent(in), dimension(2) :: this - this_ptr = transfer(this, this_ptr) - call this_ptr%p%print_hello() -end subroutine f90wrap_generator__print_hello__binding__raffle_generator_type - ! End of module generator defined in file ../src/lib/mod_generator.f90 diff --git a/edited_autogen_files/raffle.py b/edited_autogen_files/raffle.py index 98bcbf3a..6144b7db 100644 --- a/edited_autogen_files/raffle.py +++ b/edited_autogen_files/raffle.py @@ -178,7 +178,7 @@ class bas_type(f90wrap.runtime.FortranDerivedType): """ def __init__(self, handle=None, atoms=None): """ - self = Bas_Type() + self = bas_type() Defined at ../src/lib/mod_rw_geom.f90 lines \ @@ -187,7 +187,7 @@ def __init__(self, handle=None, atoms=None): Returns ------- - this : Bas_Type + this : bas_type Object to be constructed @@ -202,7 +202,7 @@ def __init__(self, handle=None, atoms=None): def __del__(self): """ - Destructor for class Bas_Type + Destructor for class bas_type Defined at ../src/lib/mod_rw_geom.f90 lines \ @@ -210,7 +210,7 @@ def __del__(self): Parameters ---------- - this : Bas_Type + this : bas_type Object to be destructed @@ -291,7 +291,7 @@ def fromase(self, atoms): # self.energy = atoms.get_total_energy() # # Set the lattice vectors - self.lat = atoms.get_cell().flatten() + self.lat = numpy.reshape(atoms.get_cell().flatten(), [3,3], order='F') self.pbc = atoms.pbc # Set the system name @@ -556,7 +556,7 @@ def deallocate(self): # ---------- # unit : int # lat : float array - # bas : Bas_Type + # bas : bas_type # length : int # """ @@ -576,7 +576,7 @@ def deallocate(self): # ---------- # unit : int # lat : float array - # bas : Bas_Type + # bas : bas_type # """ # _raffle.f90wrap_rw_geom__geom_write(unit=unit, lat=lat, bas=bas._handle) @@ -592,12 +592,12 @@ def deallocate(self): # Parameters # ---------- - # inbas : Bas_Type + # inbas : bas_type # latconv : float array # Returns # ------- - # outbas : Bas_Type + # outbas : bas_type # """ # outbas = _raffle.f90wrap_rw_geom__convert_bas(inbas=self._handle, \ @@ -617,8 +617,8 @@ def deallocate(self): # Parameters # ---------- - # inbas : Bas_Type - # outbas : Bas_Type + # inbas : bas_type + # outbas : bas_type # inlat : float array # outlat : float array # trans_dim : bool @@ -913,21 +913,6 @@ def __del__(self): """ if self._alloc: _raffle.f90wrap_generator__raffle_generator_type_finalise(this=self._handle) - - def print_hello(self): - """ - print_hello__binding__raffle_generator_type(self) - - - Defined at ../src/lib/mod_generator.f90 lines \ - 69-74 - - Parameters - ---------- - this : unknown - - """ - _raffle.f90wrap_generator__print_hello__binding__raffle_generator_type(this=self._handle) def generate(self, num_structures, stoichiometry, method_probab=[1.0, 1.0, 1.0]): """ diff --git a/src/lib/mod_generator.f90 b/src/lib/mod_generator.f90 index 14ab9130..7e0002de 100644 --- a/src/lib/mod_generator.f90 +++ b/src/lib/mod_generator.f90 @@ -39,7 +39,6 @@ module generator contains procedure, pass(this) :: generate procedure, pass(this) :: generate_structure - procedure, pass(this) :: print_hello !procedure :: get_structures !procedure :: evaluate end type raffle_generator_type @@ -82,14 +81,6 @@ end function init_raffle_generator contains - module subroutine print_hello(this) - implicit none - class(raffle_generator_type), intent(in) :: this - - write(*,*) "Hello" - - end subroutine print_hello - module function init_raffle_generator( & lattice_host, basis_host, width, sigma, cutoff_min, cutoff_max ) & result(generator) From e9f9769115e89dc947206a3481d4c5639a2b8da3 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Fri, 19 Jul 2024 09:02:09 +0100 Subject: [PATCH 032/293] Add generated structure list to generator --- .../f90wrap_mod_generator.f90 | 207 ++++++++++++++++-- edited_autogen_files/raffle.py | 147 +++++++++---- src/lib/mod_generator.f90 | 127 ++++++++--- 3 files changed, 393 insertions(+), 88 deletions(-) diff --git a/edited_autogen_files/f90wrap_mod_generator.f90 b/edited_autogen_files/f90wrap_mod_generator.f90 index f03c0b08..4158d807 100644 --- a/edited_autogen_files/f90wrap_mod_generator.f90 +++ b/edited_autogen_files/f90wrap_mod_generator.f90 @@ -236,28 +236,75 @@ end subroutine f90wrap_generator__stoich_type_xnum_array_finalise -subroutine f90wrap_raffle_generator_type__array__bins(this, nd, dtype, dshape, dloc) +subroutine f90wrap_raffle_generator_type__get__num_structures(this, f90wrap_num_structures) use generator, only: raffle_generator_type - use, intrinsic :: iso_c_binding, only : c_int implicit none type raffle_generator_type_ptr_type type(raffle_generator_type), pointer :: p => NULL() end type raffle_generator_type_ptr_type - integer(c_int), intent(in) :: this(2) + integer, intent(in) :: this(2) type(raffle_generator_type_ptr_type) :: this_ptr - integer(c_int), intent(out) :: nd - integer(c_int), intent(out) :: dtype - integer(c_int), dimension(10), intent(out) :: dshape - integer*8, intent(out) :: dloc + integer, intent(out) :: f90wrap_num_structures - nd = 1 - dtype = 5 this_ptr = transfer(this, this_ptr) - dshape(1:1) = shape(this_ptr%p%bins) - dloc = loc(this_ptr%p%bins) -end subroutine f90wrap_raffle_generator_type__array__bins + f90wrap_num_structures = this_ptr%p%num_structures +end subroutine f90wrap_raffle_generator_type__get__num_structures + +subroutine f90wrap_raffle_generator_type__set__num_structures(this, f90wrap_num_structures) + use generator, only: raffle_generator_type + implicit none + type raffle_generator_type_ptr_type + type(raffle_generator_type), pointer :: p => NULL() + end type raffle_generator_type_ptr_type + integer, intent(in) :: this(2) + type(raffle_generator_type_ptr_type) :: this_ptr + integer, intent(in) :: f90wrap_num_structures + + this_ptr = transfer(this, this_ptr) + this_ptr%p%num_structures = f90wrap_num_structures +end subroutine f90wrap_raffle_generator_type__set__num_structures -subroutine f90wrap_raffle_generator_type__array__lattice_host(this, nd, dtype, dshape, dloc) +subroutine f90wrap_raffle_generator_type__get__host(this, f90wrap_host) + use generator, only: raffle_generator_type + use rw_geom, only: bas_type + implicit none + type raffle_generator_type_ptr_type + type(raffle_generator_type), pointer :: p => NULL() + end type raffle_generator_type_ptr_type + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + integer, intent(in) :: this(2) + type(raffle_generator_type_ptr_type) :: this_ptr + integer, intent(out) :: f90wrap_host(2) + type(bas_type_ptr_type) :: host_ptr + + this_ptr = transfer(this, this_ptr) + host_ptr%p => this_ptr%p%host + f90wrap_host = transfer(host_ptr, f90wrap_host) +end subroutine f90wrap_raffle_generator_type__get__host + +subroutine f90wrap_raffle_generator_type__set__host(this, f90wrap_host) + use generator, only: raffle_generator_type + use rw_geom, only: bas_type + implicit none + type raffle_generator_type_ptr_type + type(raffle_generator_type), pointer :: p => NULL() + end type raffle_generator_type_ptr_type + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + integer, intent(in) :: this(2) + type(raffle_generator_type_ptr_type) :: this_ptr + integer, intent(in) :: f90wrap_host(2) + type(bas_type_ptr_type) :: host_ptr + + this_ptr = transfer(this, this_ptr) + host_ptr = transfer(f90wrap_host, host_ptr) + this_ptr%p%host = host_ptr%p +end subroutine f90wrap_raffle_generator_type__set__host + +subroutine f90wrap_raffle_generator_type__array__bins(this, nd, dtype, dshape, dloc) use generator, only: raffle_generator_type use, intrinsic :: iso_c_binding, only : c_int implicit none @@ -271,12 +318,12 @@ subroutine f90wrap_raffle_generator_type__array__lattice_host(this, nd, dtype, d integer(c_int), dimension(10), intent(out) :: dshape integer*8, intent(out) :: dloc - nd = 2 - dtype = 11 + nd = 1 + dtype = 5 this_ptr = transfer(this, this_ptr) - dshape(1:2) = shape(this_ptr%p%lattice_host) - dloc = loc(this_ptr%p%lattice_host) -end subroutine f90wrap_raffle_generator_type__array__lattice_host + dshape(1:1) = shape(this_ptr%p%bins) + dloc = loc(this_ptr%p%bins) +end subroutine f90wrap_raffle_generator_type__array__bins subroutine f90wrap_raffle_generator_type__array__method_probab(this, nd, dtype, dshape, dloc) use generator, only: raffle_generator_type @@ -299,6 +346,89 @@ subroutine f90wrap_raffle_generator_type__array__method_probab(this, nd, dtype, dloc = loc(this_ptr%p%method_probab) end subroutine f90wrap_raffle_generator_type__array__method_probab +subroutine f90wrap_raffle_generator_type__array_getitem__structures(f90wrap_this, f90wrap_i, structuresitem) + + use generator, only: raffle_generator_type + use rw_geom, only: bas_type + implicit none + + type raffle_generator_type_ptr_type + type(raffle_generator_type), pointer :: p => NULL() + end type raffle_generator_type_ptr_type + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + integer, intent(in) :: f90wrap_this(2) + type(raffle_generator_type_ptr_type) :: this_ptr + integer, intent(in) :: f90wrap_i + integer, intent(out) :: structuresitem(2) + type(bas_type_ptr_type) :: structures_ptr + + this_ptr = transfer(f90wrap_this, this_ptr) + if (allocated(this_ptr%p%structures)) then + if (f90wrap_i < 1 .or. f90wrap_i > size(this_ptr%p%structures)) then + call f90wrap_abort("array index out of range") + else + structures_ptr%p => this_ptr%p%structures(f90wrap_i) + structuresitem = transfer(structures_ptr,structuresitem) + endif + else + call f90wrap_abort("derived type array not allocated") + end if +end subroutine f90wrap_raffle_generator_type__array_getitem__structures + +subroutine f90wrap_raffle_generator_type__array_setitem__structures(f90wrap_this, f90wrap_i, structuresitem) + + use generator, only: raffle_generator_type + use rw_geom, only: bas_type + implicit none + + type raffle_generator_type_ptr_type + type(raffle_generator_type), pointer :: p => NULL() + end type raffle_generator_type_ptr_type + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + integer, intent(in) :: f90wrap_this(2) + type(raffle_generator_type_ptr_type) :: this_ptr + integer, intent(in) :: f90wrap_i + integer, intent(in) :: structuresitem(2) + type(bas_type_ptr_type) :: structures_ptr + + this_ptr = transfer(f90wrap_this, this_ptr) + if (allocated(this_ptr%p%structures)) then + if (f90wrap_i < 1 .or. f90wrap_i > size(this_ptr%p%structures)) then + call f90wrap_abort("array index out of range") + else + structures_ptr = transfer(structuresitem,structures_ptr) + this_ptr%p%structures(f90wrap_i) = structures_ptr%p + endif + else + call f90wrap_abort("derived type array not allocated") + end if +end subroutine f90wrap_raffle_generator_type__array_setitem__structures + +subroutine f90wrap_raffle_generator_type__array_len__structures(f90wrap_this, f90wrap_n) + + use generator, only: raffle_generator_type + use rw_geom, only: bas_type + implicit none + + type raffle_generator_type_ptr_type + type(raffle_generator_type), pointer :: p => NULL() + end type raffle_generator_type_ptr_type + integer, intent(out) :: f90wrap_n + integer, intent(in) :: f90wrap_this(2) + type(raffle_generator_type_ptr_type) :: this_ptr + + this_ptr = transfer(f90wrap_this, this_ptr) + if (allocated(this_ptr%p%structures)) then + f90wrap_n = size(this_ptr%p%structures) + else + f90wrap_n = 0 + end if +end subroutine f90wrap_raffle_generator_type__array_len__structures + subroutine f90wrap_generator__raffle_generator_type_initialise(this) use generator, only: raffle_generator_type implicit none @@ -325,6 +455,26 @@ subroutine f90wrap_generator__raffle_generator_type_finalise(this) deallocate(this_ptr%p) end subroutine f90wrap_generator__raffle_generator_type_finalise +subroutine f90wrap_generator__set_host__binding__rgt(this, host) + use rw_geom, only: bas_type + use generator, only: raffle_generator_type + implicit none + + type raffle_generator_type_ptr_type + type(raffle_generator_type), pointer :: p => NULL() + end type raffle_generator_type_ptr_type + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + type(raffle_generator_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + type(bas_type_ptr_type) :: host_ptr + integer, intent(in), dimension(2) :: host + this_ptr = transfer(this, this_ptr) + host_ptr = transfer(host, host_ptr) + call this_ptr%p%set_host(host=host_ptr%p) +end subroutine f90wrap_generator__set_host__binding__rgt + subroutine f90wrap_generator__generate__binding__rgt( & this, num_structures, stoichiometry, & method_probab, n0) @@ -364,5 +514,26 @@ subroutine f90wrap_generator__generate__binding__rgt( & end if end subroutine f90wrap_generator__generate__binding__rgt +subroutine f90wrap_generator__evaluate__binding__rgt(this, ret_viability, basis) + use rw_geom, only: bas_type + use generator, only: raffle_generator_type + implicit none + + type raffle_generator_type_ptr_type + type(raffle_generator_type), pointer :: p => NULL() + end type raffle_generator_type_ptr_type + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + type(raffle_generator_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + real(4), intent(out) :: ret_viability + type(bas_type_ptr_type) :: basis_ptr + integer, intent(in), dimension(2) :: basis + this_ptr = transfer(this, this_ptr) + basis_ptr = transfer(basis, basis_ptr) + ret_viability = this_ptr%p%evaluate(basis=basis_ptr%p) +end subroutine f90wrap_generator__evaluate__binding__rgt + ! End of module generator defined in file ../src/lib/mod_generator.f90 diff --git a/edited_autogen_files/raffle.py b/edited_autogen_files/raffle.py index 6144b7db..bc5fd79d 100644 --- a/edited_autogen_files/raffle.py +++ b/edited_autogen_files/raffle.py @@ -176,7 +176,7 @@ class bas_type(f90wrap.runtime.FortranDerivedType): 34-42 """ - def __init__(self, handle=None, atoms=None): + def __init__(self, atoms=None, handle=None): """ self = bas_type() @@ -361,7 +361,7 @@ def lat(self): Element lat ftype=real(real12) pytype=float - Defined at /Users/nedtaylor/DCoding/DGit/raffle/src/lib/mod_rw_geom.f90 line 38 + Defined at ../src/lib/mod_rw_geom.f90 line 38 """ array_ndim, array_type, array_shape, array_handle = \ @@ -385,7 +385,7 @@ def lcart(self): Element lcart ftype=logical pytype=bool - Defined at /Users/nedtaylor/DCoding/DGit/raffle/src/lib/mod_rw_geom.f90 line 39 + Defined at ../src/lib/mod_rw_geom.f90 line 39 """ return _raffle.f90wrap_bas_type__get__lcart(self._handle) @@ -400,7 +400,7 @@ def pbc(self): Element pbc ftype=logical pytype=bool - Defined at /Users/nedtaylor/DCoding/DGit/raffle/src/lib/mod_rw_geom.f90 line 40 + Defined at ../src/lib/mod_rw_geom.f90 line 40 """ array_ndim, array_type, array_shape, array_handle = \ @@ -424,7 +424,7 @@ def sysname(self): Element sysname ftype=character(len=1024) pytype=str - Defined at /Users/nedtaylor/DCoding/DGit/raffle/src/lib/mod_rw_geom.f90 line 41 + Defined at ../src/lib/mod_rw_geom.f90 line 41 """ return _raffle.f90wrap_bas_type__get__sysname(self._handle) @@ -512,7 +512,7 @@ def init_array_items(self): _raffle.f90wrap_bas_type_xnum_array__array_setitem__items, _raffle.f90wrap_bas_type_xnum_array__array_len__items, """ - Element items ftype=type(test_type) pytype=Test_Type + Element items ftype=type(bas_type) pytype=bas_type Defined at line 0 @@ -539,7 +539,6 @@ def deallocate(self): _raffle.f90wrap_bas_type_xnum_array__array_dealloc__items(self._handle) - _dt_array_initialisers = [init_array_items] @@ -833,7 +832,7 @@ def init_array_items(self): _raffle.f90wrap_stoich_type_xnum_array__array_setitem__items, _raffle.f90wrap_stoich_type_xnum_array__array_len__items, """ - Element items ftype=type(test_type) pytype=Test_Type + Element items ftype=type(stoichiometry_type) pytype=stoichiometry_type Defined at line 0 @@ -914,6 +913,23 @@ def __del__(self): if self._alloc: _raffle.f90wrap_generator__raffle_generator_type_finalise(this=self._handle) + def set_host(self, host): + """ + set_host__binding__raffle_generator_type(self, host) + + + Defined at ../src/lib/mod_generator.f90 lines \ + 99-108 + + Parameters + ---------- + this : unknown + host : bas_type + + """ + _raffle.f90wrap_generator__set_host__binding__rgt(this=self._handle, \ + host=host._handle) + def generate(self, num_structures, stoichiometry, method_probab=[1.0, 1.0, 1.0]): """ generate__binding__raffle_generator_type(self, num_structures, stoichiometry, method_probab) @@ -934,7 +950,70 @@ def generate(self, num_structures, stoichiometry, method_probab=[1.0, 1.0, 1.0]) this=self._handle, num_structures=num_structures, stoichiometry=stoichiometry._handle, - method_probab=method_probab)#, n0=len(method_probab)) + method_probab=method_probab) + + def evaluate(self, basis): + """ + viability = evaluate__binding__raffle_generator_type(self, basis) + + + Defined at ../src/lib/mod_generator.f90 lines \ + 311-322 + + Parameters + ---------- + this : unknown + basis : bas_type + + Returns + ------- + viability : float + + """ + viability = \ + _raffle.f90wrap_generator__evaluate__binding__rgt(this=self._handle, \ + basis=basis._handle) + return viability + + @property + def num_structures(self): + """ + Element num_structures ftype=integer pytype=int + + + Defined at ../src/lib/mod_generator.f90 line \ + 24 + + """ + return _raffle.f90wrap_raffle_generator_type__get__num_structures(self._handle) + + @num_structures.setter + def num_structures(self, num_structures): + _raffle.f90wrap_raffle_generator_type__set__num_structures(self._handle, \ + num_structures) + + @property + def host(self): + """ + Element host ftype=type(bas_type) pytype=bas_type + + + Defined at ../src/lib/mod_generator.f90 line \ + 25 + + """ + host_handle = _raffle.f90wrap_raffle_generator_type__get__host(self._handle) + if tuple(host_handle) in self._objs: + host = self._objs[tuple(host_handle)] + else: + host = rw_geom.bas_type.from_handle(host_handle) + self._objs[tuple(host_handle)] = host + return host + + @host.setter + def host(self, host): + host = host._handle + _raffle.f90wrap_raffle_generator_type__set__host(self._handle, host) @property def bins(self): @@ -961,31 +1040,6 @@ def bins(self): def bins(self, bins): self.bins[...] = bins - @property - def lattice_host(self): - """ - Element lattice_host ftype=real(real12) pytype=float - - - Defined at ../src/lib/mod_generator.f90 line \ - 25 - - """ - array_ndim, array_type, array_shape, array_handle = \ - _raffle.f90wrap_raffle_generator_type__array__lattice_host(self._handle) - if array_handle in self._arrays: - lattice_host = self._arrays[array_handle] - else: - lattice_host = f90wrap.runtime.get_array(f90wrap.runtime.sizeof_fortran_t, - self._handle, - _raffle.f90wrap_raffle_generator_type__array__lattice_host) - self._arrays[array_handle] = lattice_host - return lattice_host - - @lattice_host.setter - def lattice_host(self, lattice_host): - self.lattice_host[...] = lattice_host - @property def method_probab(self): """ @@ -1011,18 +1065,35 @@ def method_probab(self): def method_probab(self, method_probab): self.method_probab[...] = method_probab + def init_array_structures(self): + self.structures = f90wrap.runtime.FortranDerivedTypeArray(self, + _raffle.f90wrap_raffle_generator_type__array_getitem__structures, + _raffle.f90wrap_raffle_generator_type__array_setitem__structures, + _raffle.f90wrap_raffle_generator_type__array_len__structures, + """ + Element items ftype=type(bas_type) pytype=bas_type + + + Defined at ../src/lib/mod_generator.f90 line \ + 29 + + """, Rw_Geom.bas_type) + return self.structures + def __str__(self): ret = ['{\n'] - ret.append(' bins : ') + ret.append(' num_structures : ') + ret.append(repr(self.num_structures)) + ret.append(',\n host : ') + ret.append(repr(self.host)) + ret.append(',\n bins : ') ret.append(repr(self.bins)) - ret.append(',\n lattice_host : ') - ret.append(repr(self.lattice_host)) ret.append(',\n method_probab : ') ret.append(repr(self.method_probab)) ret.append('}') return ''.join(ret) - _dt_array_initialisers = [] + _dt_array_initialisers = [init_array_structures] _dt_array_initialisers = [] diff --git a/src/lib/mod_generator.f90 b/src/lib/mod_generator.f90 index 7e0002de..b861602f 100644 --- a/src/lib/mod_generator.f90 +++ b/src/lib/mod_generator.f90 @@ -6,7 +6,7 @@ module generator use constants, only: verbose use misc_raffle, only: shuffle - use rw_geom, only: geom_read, geom_write, clone_bas + use rw_geom, only: clone_bas use edit_geom, only: bas_merge use add_atom, only: add_atom_void, add_atom_pseudo, add_atom_scan, & get_viable_gridpoints, update_viable_gridpoints @@ -31,24 +31,25 @@ module generator type :: raffle_generator_type + integer :: num_structures = 0 + type(bas_type) :: host integer, dimension(3) :: bins - real(real12), dimension(3,3) :: lattice_host - type(bas_type) :: basis_host type(gvector_container_type) :: distributions real(real12), dimension(3) :: method_probab + type(bas_type), dimension(:), allocatable :: structures contains + procedure, pass(this) :: set_host procedure, pass(this) :: generate procedure, pass(this) :: generate_structure - !procedure :: get_structures - !procedure :: evaluate + procedure, pass(this) :: get_structures + procedure, pass(this) :: evaluate end type raffle_generator_type interface raffle_generator_type module function init_raffle_generator( & - lattice_host, basis_host, & + host, & width, sigma, cutoff_min, cutoff_max) result(generator) - real(real12), dimension(3,3), intent(in) :: lattice_host - type(bas_type), intent(in) :: basis_host + type(bas_type), intent(in), optional :: host real(real12), dimension(3), intent(in), optional :: width real(real12), dimension(3), intent(in), optional :: sigma real(real12), dimension(3), intent(in), optional :: cutoff_min @@ -82,15 +83,13 @@ end function init_raffle_generator contains module function init_raffle_generator( & - lattice_host, basis_host, width, sigma, cutoff_min, cutoff_max ) & + host, width, sigma, cutoff_min, cutoff_max ) & result(generator) !! Initialise an instance of the raffle generator. !! Set up run-independent parameters. implicit none ! Arguments - real(real12), dimension(3,3), intent(in) :: lattice_host - !! Lattice vectors of the host structure. - type(bas_type), intent(in) :: basis_host + type(bas_type), intent(in), optional :: host !! Basis of the host structure. real(real12), dimension(3), intent(in), optional :: width !! Width of the gaussians used in the 2-, 3-, and 4-body @@ -105,10 +104,7 @@ module function init_raffle_generator( & type(raffle_generator_type) :: generator - - generator%lattice_host = lattice_host - generator%basis_host = basis_host - + if(present(host)) call generator%set_host(host) if( present(width) ) & call generator%distributions%set_width(width) if( present(sigma) ) & @@ -118,10 +114,21 @@ module function init_raffle_generator( & if( present(cutoff_max) ) & call generator%distributions%set_cutoff_max(cutoff_max) - end function init_raffle_generator + subroutine set_host(this, host) + !! Set the host structure. + implicit none + ! Arguments + class(raffle_generator_type), intent(inout) :: this + !! Instance of the raffle generator. + type(bas_type), intent(in) :: host + !! Basis of the host structure. + + this%host = host + end subroutine set_host + subroutine generate(this, num_structures, & stoichiometry, method_probab) @@ -138,11 +145,12 @@ subroutine generate(this, num_structures, & !! Probability of each placement method. type(bas_type) :: basis, basis_store + type(bas_type), dimension(:), allocatable :: tmp_structures integer, dimension(:,:), allocatable :: placement_list, placement_list_shuffled integer :: i, j, k - integer :: istructure + integer :: istructure, num_structures_old, num_structures_new integer :: unit, info_unit, structure_unit integer :: num_insert_atoms, num_insert_species @@ -157,6 +165,14 @@ subroutine generate(this, num_structures, & if(present(method_probab)) method_probab_ = method_probab + if(.not.allocated(this%structures))then + allocate(this%structures(this%num_structures)) + else + allocate(tmp_structures(this%num_structures + num_structures)) + tmp_structures(:this%num_structures) = this%structures(:this%num_structures) + call move_alloc(tmp_structures, this%structures) + end if + !!! THINK OF SOME WAY TO HANDLE THE HOST SEPARATELY !!! THAT CAN SIGNIFICANTLY REDUCE DATA USAGE @@ -172,7 +188,7 @@ subroutine generate(this, num_structures, & do i = 1, basis_store%nspec allocate(basis_store%spec(i)%atom(basis_store%spec(i)%num,3), source = 0._real12) end do - basis_store = bas_merge(this%basis_host,basis_store) + basis_store = bas_merge(this%host,basis_store) !!-------------------------------------------------------------------------- @@ -191,7 +207,7 @@ subroutine generate(this, num_structures, & success = .true. end do if(.not.success) cycle - if(i.gt.this%basis_host%nspec)then + if(i.gt.this%host%nspec)then do j = 1, basis_store%spec(i)%num k = k + 1 placement_list(k,1) = i @@ -199,7 +215,7 @@ subroutine generate(this, num_structures, & end do else do j = 1, basis_store%spec(i)%num - if(j.le.this%basis_host%spec(i)%num) cycle + if(j.le.this%host%spec(i)%num) cycle k = k + 1 placement_list(k,1) = i placement_list(k,2) = j @@ -211,16 +227,19 @@ subroutine generate(this, num_structures, & !!-------------------------------------------------------------------------- !! generate the structures !!-------------------------------------------------------------------------- - structure_loop: do istructure = 1, num_structures - - basis = this%generate_structure( basis_store, & + num_structures_old = this%num_structures + num_structures_new = this%num_structures + num_structures + structure_loop: do istructure = num_structures_old + 1, num_structures_new + + this%structures(i) = this%generate_structure( basis_store, & placement_list, method_probab_ ) + this%num_structures = i #ifdef ENABLE_ATHENA !!----------------------------------------------------------------------- !! predict energy using ML !!----------------------------------------------------------------------- - graph(1) = get_graph_from_basis(this%lattice_host, basis) + graph(1) = get_graph_from_basis(this%host%lat, basis) write(*,*) "Predicted energy", network_predict_graph(graph(1:1)) #endif @@ -261,13 +280,13 @@ module function generate_structure( & call clone_bas(basis_initial, basis) - num_insert_atoms = basis%natom - this%basis_host%natom + num_insert_atoms = basis%natom - this%host%natom placement_list_shuffled = placement_list call shuffle(placement_list_shuffled,1) !!! NEED TO SORT OUT RANDOM SEED viable_gridpoints = get_viable_gridpoints( this%bins, & - this%lattice_host, basis, & + this%host%lat, basis, & [ this%distributions%bond_info(:)%radius_covalent ], & placement_list_shuffled ) @@ -283,13 +302,13 @@ module function generate_structure( & if(rtmp1.le.method_probab_(1)) then if(verbose.gt.0) write(*,*) "Add Atom Void" call add_atom_void( this%bins, & - this%lattice_host, basis, & + this%host%lat, basis, & placement_list_shuffled(iplaced+1:,:), placed) else if(rtmp1.le.method_probab_(2)) then if(verbose.gt.0) write(*,*) "Add Atom Pseudo" call add_atom_pseudo( this%bins, & this%distributions, & - this%lattice_host, basis, & + this%host%lat, basis, & placement_list_shuffled(iplaced+1:,:), & [ this%distributions%bond_info(:)%radius_covalent ], & placed ) @@ -298,14 +317,14 @@ module function generate_structure( & if(verbose.gt.0) write(*,*) "Add Atom Scan" call add_atom_scan( viable_gridpoints, & this%distributions, & - this%lattice_host, basis, & + this%host%lat, basis, & placement_list_shuffled(iplaced+1:,:), & [ this%distributions%bond_info(:)%radius_covalent ], & placed) end if if(.not. placed) then if(void_ticker.gt.10) & - call add_atom_void( this%bins, this%lattice_host, basis, & + call add_atom_void( this%bins, this%host%lat, basis, & placement_list_shuffled(iplaced+1:,:), placed) void_ticker = 0 if(.not.placed) cycle placement_loop @@ -317,7 +336,7 @@ module function generate_structure( & iplaced = iplaced + 1 if(allocated(viable_gridpoints)) & call update_viable_gridpoints( viable_gridpoints, & - this%lattice_host, basis, & + this%host%lat, basis, & [ placement_list_shuffled(iplaced,:) ], & this%distributions%bond_info( & ( basis%nspec - & @@ -337,4 +356,48 @@ module function generate_structure( & end function generate_structure + + function get_structures(this) result(structures) + !! Get the generated structures. + implicit none + ! Arguments + class(raffle_generator_type), intent(in) :: this + !! Instance of the raffle generator. + type(bas_type), dimension(:), allocatable :: structures + !! Generated structures. + + structures = this%structures + end function get_structures + + + function evaluate(this, basis) result(viability) + !! Evaluate the viability of the generated structures. + implicit none + ! Arguments + class(raffle_generator_type), intent(in) :: this + !! Instance of the raffle generator. + type(bas_type), intent(in) :: basis + !! Basis of the structure to evaluate. + real(real12) :: viability + !! Viability of the generated structures. + + viability = 0.0_real12 + stop "Not yet set up" + end function evaluate + + subroutine allocate_structures(this, num_structures) + !! Allocate memory for the generated structures. + implicit none + ! Arguments + class(raffle_generator_type), intent(inout) :: this + !! Instance of the raffle generator. + integer, intent(in) :: num_structures + !! Number of structures to allocate memory for. + + if(allocated(this%structures)) deallocate(this%structures) + allocate(this%structures(num_structures)) + this%num_structures = num_structures + end subroutine allocate_structures + + end module generator \ No newline at end of file From be980cba3bda099ce1dd5df29b568fdd70fc058a Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Fri, 19 Jul 2024 09:07:55 +0100 Subject: [PATCH 033/293] Fix stoichiometry_type initialisation and finalisation --- edited_autogen_files/raffle.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/edited_autogen_files/raffle.py b/edited_autogen_files/raffle.py index bc5fd79d..110058ab 100644 --- a/edited_autogen_files/raffle.py +++ b/edited_autogen_files/raffle.py @@ -710,7 +710,7 @@ def __init__(self, handle=None): Automatically generated constructor for stoichiometry_type """ f90wrap.runtime.FortranDerivedType.__init__(self) - result = _raffle.f90wrap_generator__stoichiometry_type_initialise() + result = _raffle.f90wrap_stoichiometry_type_initialise() self._handle = result[0] if isinstance(result, tuple) else result def __del__(self): @@ -730,7 +730,7 @@ def __del__(self): Automatically generated destructor for stoichiometry_type """ if self._alloc: - _raffle.f90wrap_generator__stoichiometry_type_finalise(this=self._handle) + _raffle.f90wrap_stoichiometry_type_finalise(this=self._handle) @property def element(self): From 60618f35ee4b0165a7cc8f4cf2b4ad8132d7b748 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Fri, 19 Jul 2024 09:19:54 +0100 Subject: [PATCH 034/293] Handle stoichiometry_type initialisation --- edited_autogen_files/raffle.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/edited_autogen_files/raffle.py b/edited_autogen_files/raffle.py index 110058ab..e29db0c4 100644 --- a/edited_autogen_files/raffle.py +++ b/edited_autogen_files/raffle.py @@ -692,7 +692,7 @@ class stoichiometry_type(f90wrap.runtime.FortranDerivedType): 19-21 """ - def __init__(self, handle=None): + def __init__(self, element=None, num=None, handle=None): """ self = Stoichiometry_Type() @@ -712,6 +712,12 @@ def __init__(self, handle=None): f90wrap.runtime.FortranDerivedType.__init__(self) result = _raffle.f90wrap_stoichiometry_type_initialise() self._handle = result[0] if isinstance(result, tuple) else result + + if element: + self.element = element + if num: + self.num = num + def __del__(self): """ From 9486e80a7e1afec4cab9e8963709310738c651a0 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Fri, 19 Jul 2024 10:02:51 +0100 Subject: [PATCH 035/293] Add gvector wrapper --- edited_autogen_files/f90wrap_mod_evolver.f90 | 833 ++++++++++++++++ .../f90wrap_mod_generator.f90 | 40 + edited_autogen_files/raffle.py | 927 ++++++++++++++++++ src/lib/mod_evolver.f90 | 2 +- 4 files changed, 1801 insertions(+), 1 deletion(-) create mode 100644 edited_autogen_files/f90wrap_mod_evolver.f90 diff --git a/edited_autogen_files/f90wrap_mod_evolver.f90 b/edited_autogen_files/f90wrap_mod_evolver.f90 new file mode 100644 index 00000000..92d0796a --- /dev/null +++ b/edited_autogen_files/f90wrap_mod_evolver.f90 @@ -0,0 +1,833 @@ +! Module evolver defined in file ../src/lib/mod_evolver.f90 + +subroutine f90wrap_gvector_base_type__array__df_2body(this, nd, dtype, dshape, dloc) + use evolver, only: gvector_base_type + use, intrinsic :: iso_c_binding, only : c_int + implicit none + type gvector_base_type_ptr_type + type(gvector_base_type), pointer :: p => NULL() + end type gvector_base_type_ptr_type + integer(c_int), intent(in) :: this(2) + type(gvector_base_type_ptr_type) :: this_ptr + integer(c_int), intent(out) :: nd + integer(c_int), intent(out) :: dtype + integer(c_int), dimension(10), intent(out) :: dshape + integer*8, intent(out) :: dloc + + nd = 2 + dtype = 11 + this_ptr = transfer(this, this_ptr) + if (allocated(this_ptr%p%df_2body)) then + dshape(1:2) = shape(this_ptr%p%df_2body) + dloc = loc(this_ptr%p%df_2body) + else + dloc = 0 + end if +end subroutine f90wrap_gvector_base_type__array__df_2body + +subroutine f90wrap_gvector_base_type__array__df_3body(this, nd, dtype, dshape, dloc) + use evolver, only: gvector_base_type + use, intrinsic :: iso_c_binding, only : c_int + implicit none + type gvector_base_type_ptr_type + type(gvector_base_type), pointer :: p => NULL() + end type gvector_base_type_ptr_type + integer(c_int), intent(in) :: this(2) + type(gvector_base_type_ptr_type) :: this_ptr + integer(c_int), intent(out) :: nd + integer(c_int), intent(out) :: dtype + integer(c_int), dimension(10), intent(out) :: dshape + integer*8, intent(out) :: dloc + + nd = 2 + dtype = 11 + this_ptr = transfer(this, this_ptr) + if (allocated(this_ptr%p%df_3body)) then + dshape(1:2) = shape(this_ptr%p%df_3body) + dloc = loc(this_ptr%p%df_3body) + else + dloc = 0 + end if +end subroutine f90wrap_gvector_base_type__array__df_3body + +subroutine f90wrap_gvector_base_type__array__df_4body(this, nd, dtype, dshape, dloc) + use evolver, only: gvector_base_type + use, intrinsic :: iso_c_binding, only : c_int + implicit none + type gvector_base_type_ptr_type + type(gvector_base_type), pointer :: p => NULL() + end type gvector_base_type_ptr_type + integer(c_int), intent(in) :: this(2) + type(gvector_base_type_ptr_type) :: this_ptr + integer(c_int), intent(out) :: nd + integer(c_int), intent(out) :: dtype + integer(c_int), dimension(10), intent(out) :: dshape + integer*8, intent(out) :: dloc + + nd = 2 + dtype = 11 + this_ptr = transfer(this, this_ptr) + if (allocated(this_ptr%p%df_4body)) then + dshape(1:2) = shape(this_ptr%p%df_4body) + dloc = loc(this_ptr%p%df_4body) + else + dloc = 0 + end if +end subroutine f90wrap_gvector_base_type__array__df_4body + +subroutine f90wrap_evolver__gvector_base_type_initialise(this) + use evolver, only: gvector_base_type + implicit none + + type gvector_base_type_ptr_type + type(gvector_base_type), pointer :: p => NULL() + end type gvector_base_type_ptr_type + type(gvector_base_type_ptr_type) :: this_ptr + integer, intent(out), dimension(2) :: this + allocate(this_ptr%p) + this = transfer(this_ptr, this) +end subroutine f90wrap_evolver__gvector_base_type_initialise + +subroutine f90wrap_evolver__gvector_base_type_finalise(this) + use evolver, only: gvector_base_type + implicit none + + type gvector_base_type_ptr_type + type(gvector_base_type), pointer :: p => NULL() + end type gvector_base_type_ptr_type + type(gvector_base_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + this_ptr = transfer(this, this_ptr) + deallocate(this_ptr%p) +end subroutine f90wrap_evolver__gvector_base_type_finalise + +subroutine f90wrap_gvector_type__get__num_atoms(this, f90wrap_num_atoms) + use evolver, only: gvector_type + implicit none + type gvector_type_ptr_type + type(gvector_type), pointer :: p => NULL() + end type gvector_type_ptr_type + integer, intent(in) :: this(2) + type(gvector_type_ptr_type) :: this_ptr + integer, intent(out) :: f90wrap_num_atoms + + this_ptr = transfer(this, this_ptr) + f90wrap_num_atoms = this_ptr%p%num_atoms +end subroutine f90wrap_gvector_type__get__num_atoms + +subroutine f90wrap_gvector_type__set__num_atoms(this, f90wrap_num_atoms) + use evolver, only: gvector_type + implicit none + type gvector_type_ptr_type + type(gvector_type), pointer :: p => NULL() + end type gvector_type_ptr_type + integer, intent(in) :: this(2) + type(gvector_type_ptr_type) :: this_ptr + integer, intent(in) :: f90wrap_num_atoms + + this_ptr = transfer(this, this_ptr) + this_ptr%p%num_atoms = f90wrap_num_atoms +end subroutine f90wrap_gvector_type__set__num_atoms + +subroutine f90wrap_gvector_type__get__energy(this, f90wrap_energy) + use evolver, only: gvector_type + implicit none + type gvector_type_ptr_type + type(gvector_type), pointer :: p => NULL() + end type gvector_type_ptr_type + integer, intent(in) :: this(2) + type(gvector_type_ptr_type) :: this_ptr + real(4), intent(out) :: f90wrap_energy + + this_ptr = transfer(this, this_ptr) + f90wrap_energy = this_ptr%p%energy +end subroutine f90wrap_gvector_type__get__energy + +subroutine f90wrap_gvector_type__set__energy(this, f90wrap_energy) + use evolver, only: gvector_type + implicit none + type gvector_type_ptr_type + type(gvector_type), pointer :: p => NULL() + end type gvector_type_ptr_type + integer, intent(in) :: this(2) + type(gvector_type_ptr_type) :: this_ptr + real(4), intent(in) :: f90wrap_energy + + this_ptr = transfer(this, this_ptr) + this_ptr%p%energy = f90wrap_energy +end subroutine f90wrap_gvector_type__set__energy + +subroutine f90wrap_gvector_type__array__stoichiometry(this, nd, dtype, dshape, dloc) + use evolver, only: gvector_type + use, intrinsic :: iso_c_binding, only : c_int + implicit none + type gvector_type_ptr_type + type(gvector_type), pointer :: p => NULL() + end type gvector_type_ptr_type + integer(c_int), intent(in) :: this(2) + type(gvector_type_ptr_type) :: this_ptr + integer(c_int), intent(out) :: nd + integer(c_int), intent(out) :: dtype + integer(c_int), dimension(10), intent(out) :: dshape + integer*8, intent(out) :: dloc + + nd = 1 + dtype = 5 + this_ptr = transfer(this, this_ptr) + if (allocated(this_ptr%p%stoichiometry)) then + dshape(1:1) = shape(this_ptr%p%stoichiometry) + dloc = loc(this_ptr%p%stoichiometry) + else + dloc = 0 + end if +end subroutine f90wrap_gvector_type__array__stoichiometry + +subroutine f90wrap_gvector_type__array__species(this, nd, dtype, dshape, dloc) + use evolver, only: gvector_type + use, intrinsic :: iso_c_binding, only : c_int + implicit none + type gvector_type_ptr_type + type(gvector_type), pointer :: p => NULL() + end type gvector_type_ptr_type + integer(c_int), intent(in) :: this(2) + type(gvector_type_ptr_type) :: this_ptr + integer(c_int), intent(out) :: nd + integer(c_int), intent(out) :: dtype + integer(c_int), dimension(10), intent(out) :: dshape + integer*8, intent(out) :: dloc + + nd = 2 + dtype = 2 + this_ptr = transfer(this, this_ptr) + if (allocated(this_ptr%p%species)) then + dshape(1:2) = (/len(this_ptr%p%species(1)), shape(this_ptr%p%species)/) + dloc = loc(this_ptr%p%species) + else + dloc = 0 + end if +end subroutine f90wrap_gvector_type__array__species + +subroutine f90wrap_evolver__gvector_type_initialise(this) + use evolver, only: gvector_type + implicit none + + type gvector_type_ptr_type + type(gvector_type), pointer :: p => NULL() + end type gvector_type_ptr_type + type(gvector_type_ptr_type) :: this_ptr + integer, intent(out), dimension(2) :: this + allocate(this_ptr%p) + this = transfer(this_ptr, this) +end subroutine f90wrap_evolver__gvector_type_initialise + +subroutine f90wrap_evolver__gvector_type_finalise(this) + use evolver, only: gvector_type + implicit none + + type gvector_type_ptr_type + type(gvector_type), pointer :: p => NULL() + end type gvector_type_ptr_type + type(gvector_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + this_ptr = transfer(this, this_ptr) + deallocate(this_ptr%p) +end subroutine f90wrap_evolver__gvector_type_finalise + +subroutine f90wrap_evolver__calculate__binding__gvector_type(this, lattice, basis, nbins, width, sigma, cutoff_min, & + cutoff_max) + use evolver, only: gvector_type + use rw_geom, only: bas_type + implicit none + + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + type gvector_type_ptr_type + type(gvector_type), pointer :: p => NULL() + end type gvector_type_ptr_type + type(gvector_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + real(4), dimension(3,3), intent(in) :: lattice + type(bas_type_ptr_type) :: basis_ptr + integer, intent(in), dimension(2) :: basis + integer, dimension(3), intent(in), optional :: nbins + real(4), dimension(3), intent(in), optional :: width + real(4), dimension(3), intent(in), optional :: sigma + real(4), dimension(3), intent(in), optional :: cutoff_min + real(4), dimension(3), intent(in), optional :: cutoff_max + this_ptr = transfer(this, this_ptr) + basis_ptr = transfer(basis, basis_ptr) + call this_ptr%p%calculate(lattice=lattice, basis=basis_ptr%p, nbins=nbins, width=width, sigma=sigma, & + cutoff_min=cutoff_min, cutoff_max=cutoff_max) +end subroutine f90wrap_evolver__calculate__binding__gvector_type + +subroutine f90wrap_gvector_container_type__get__best_system(this, f90wrap_best_system) + use evolver, only: gvector_container_type + implicit none + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + integer, intent(in) :: this(2) + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(out) :: f90wrap_best_system + + this_ptr = transfer(this, this_ptr) + f90wrap_best_system = this_ptr%p%best_system +end subroutine f90wrap_gvector_container_type__get__best_system + +subroutine f90wrap_gvector_container_type__set__best_system(this, f90wrap_best_system) + use evolver, only: gvector_container_type + implicit none + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + integer, intent(in) :: this(2) + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(in) :: f90wrap_best_system + + this_ptr = transfer(this, this_ptr) + this_ptr%p%best_system = f90wrap_best_system +end subroutine f90wrap_gvector_container_type__set__best_system + +subroutine f90wrap_gvector_container_type__get__best_energy(this, f90wrap_best_energy) + use evolver, only: gvector_container_type + implicit none + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + integer, intent(in) :: this(2) + type(gvector_container_type_ptr_type) :: this_ptr + real(4), intent(out) :: f90wrap_best_energy + + this_ptr = transfer(this, this_ptr) + f90wrap_best_energy = this_ptr%p%best_energy +end subroutine f90wrap_gvector_container_type__get__best_energy + +subroutine f90wrap_gvector_container_type__set__best_energy(this, f90wrap_best_energy) + use evolver, only: gvector_container_type + implicit none + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + integer, intent(in) :: this(2) + type(gvector_container_type_ptr_type) :: this_ptr + real(4), intent(in) :: f90wrap_best_energy + + this_ptr = transfer(this, this_ptr) + this_ptr%p%best_energy = f90wrap_best_energy +end subroutine f90wrap_gvector_container_type__set__best_energy + +subroutine f90wrap_gvector_container_type__array__nbins(this, nd, dtype, dshape, dloc) + use evolver, only: gvector_container_type + use, intrinsic :: iso_c_binding, only : c_int + implicit none + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + integer(c_int), intent(in) :: this(2) + type(gvector_container_type_ptr_type) :: this_ptr + integer(c_int), intent(out) :: nd + integer(c_int), intent(out) :: dtype + integer(c_int), dimension(10), intent(out) :: dshape + integer*8, intent(out) :: dloc + + nd = 1 + dtype = 5 + this_ptr = transfer(this, this_ptr) + dshape(1:1) = shape(this_ptr%p%nbins) + dloc = loc(this_ptr%p%nbins) +end subroutine f90wrap_gvector_container_type__array__nbins + +subroutine f90wrap_gvector_container_type__array__sigma(this, nd, dtype, dshape, dloc) + use evolver, only: gvector_container_type + use, intrinsic :: iso_c_binding, only : c_int + implicit none + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + integer(c_int), intent(in) :: this(2) + type(gvector_container_type_ptr_type) :: this_ptr + integer(c_int), intent(out) :: nd + integer(c_int), intent(out) :: dtype + integer(c_int), dimension(10), intent(out) :: dshape + integer*8, intent(out) :: dloc + + nd = 1 + dtype = 11 + this_ptr = transfer(this, this_ptr) + dshape(1:1) = shape(this_ptr%p%sigma) + dloc = loc(this_ptr%p%sigma) +end subroutine f90wrap_gvector_container_type__array__sigma + +subroutine f90wrap_gvector_container_type__array__width(this, nd, dtype, dshape, dloc) + use evolver, only: gvector_container_type + use, intrinsic :: iso_c_binding, only : c_int + implicit none + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + integer(c_int), intent(in) :: this(2) + type(gvector_container_type_ptr_type) :: this_ptr + integer(c_int), intent(out) :: nd + integer(c_int), intent(out) :: dtype + integer(c_int), dimension(10), intent(out) :: dshape + integer*8, intent(out) :: dloc + + nd = 1 + dtype = 11 + this_ptr = transfer(this, this_ptr) + dshape(1:1) = shape(this_ptr%p%width) + dloc = loc(this_ptr%p%width) +end subroutine f90wrap_gvector_container_type__array__width + +subroutine f90wrap_gvector_container_type__array__cutoff_min(this, nd, dtype, dshape, dloc) + use evolver, only: gvector_container_type + use, intrinsic :: iso_c_binding, only : c_int + implicit none + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + integer(c_int), intent(in) :: this(2) + type(gvector_container_type_ptr_type) :: this_ptr + integer(c_int), intent(out) :: nd + integer(c_int), intent(out) :: dtype + integer(c_int), dimension(10), intent(out) :: dshape + integer*8, intent(out) :: dloc + + nd = 1 + dtype = 11 + this_ptr = transfer(this, this_ptr) + dshape(1:1) = shape(this_ptr%p%cutoff_min) + dloc = loc(this_ptr%p%cutoff_min) +end subroutine f90wrap_gvector_container_type__array__cutoff_min + +subroutine f90wrap_gvector_container_type__array__cutoff_max(this, nd, dtype, dshape, dloc) + use evolver, only: gvector_container_type + use, intrinsic :: iso_c_binding, only : c_int + implicit none + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + integer(c_int), intent(in) :: this(2) + type(gvector_container_type_ptr_type) :: this_ptr + integer(c_int), intent(out) :: nd + integer(c_int), intent(out) :: dtype + integer(c_int), dimension(10), intent(out) :: dshape + integer*8, intent(out) :: dloc + + nd = 1 + dtype = 11 + this_ptr = transfer(this, this_ptr) + dshape(1:1) = shape(this_ptr%p%cutoff_max) + dloc = loc(this_ptr%p%cutoff_max) +end subroutine f90wrap_gvector_container_type__array__cutoff_max + +subroutine f90wrap_gvector_container_type__get__total(this, f90wrap_total) + use evolver, only: gvector_container_type, gvector_base_type + implicit none + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type gvector_base_type_ptr_type + type(gvector_base_type), pointer :: p => NULL() + end type gvector_base_type_ptr_type + integer, intent(in) :: this(2) + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(out) :: f90wrap_total(2) + type(gvector_base_type_ptr_type) :: total_ptr + + this_ptr = transfer(this, this_ptr) + total_ptr%p => this_ptr%p%total + f90wrap_total = transfer(total_ptr,f90wrap_total) +end subroutine f90wrap_gvector_container_type__get__total + +subroutine f90wrap_gvector_container_type__set__total(this, f90wrap_total) + use evolver, only: gvector_container_type, gvector_base_type + implicit none + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type gvector_base_type_ptr_type + type(gvector_base_type), pointer :: p => NULL() + end type gvector_base_type_ptr_type + integer, intent(in) :: this(2) + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(in) :: f90wrap_total(2) + type(gvector_base_type_ptr_type) :: total_ptr + + this_ptr = transfer(this, this_ptr) + total_ptr = transfer(f90wrap_total,total_ptr) + this_ptr%p%total = total_ptr%p +end subroutine f90wrap_gvector_container_type__set__total + +subroutine f90wrap_gvector_container_type__array_getitem__system(f90wrap_this, f90wrap_i, systemitem) + + use evolver, only: gvector_type, gvector_container_type + implicit none + + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type gvector_type_ptr_type + type(gvector_type), pointer :: p => NULL() + end type gvector_type_ptr_type + integer, intent(in) :: f90wrap_this(2) + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(in) :: f90wrap_i + integer, intent(out) :: systemitem(2) + type(gvector_type_ptr_type) :: system_ptr + + this_ptr = transfer(f90wrap_this, this_ptr) + if (allocated(this_ptr%p%system)) then + if (f90wrap_i < 1 .or. f90wrap_i > size(this_ptr%p%system)) then + call f90wrap_abort("array index out of range") + else + system_ptr%p => this_ptr%p%system(f90wrap_i) + systemitem = transfer(system_ptr,systemitem) + endif + else + call f90wrap_abort("derived type array not allocated") + end if +end subroutine f90wrap_gvector_container_type__array_getitem__system + +subroutine f90wrap_gvector_container_type__array_setitem__system(f90wrap_this, f90wrap_i, systemitem) + + use evolver, only: gvector_type, gvector_container_type + implicit none + + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type gvector_type_ptr_type + type(gvector_type), pointer :: p => NULL() + end type gvector_type_ptr_type + integer, intent(in) :: f90wrap_this(2) + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(in) :: f90wrap_i + integer, intent(in) :: systemitem(2) + type(gvector_type_ptr_type) :: system_ptr + + this_ptr = transfer(f90wrap_this, this_ptr) + if (allocated(this_ptr%p%system)) then + if (f90wrap_i < 1 .or. f90wrap_i > size(this_ptr%p%system)) then + call f90wrap_abort("array index out of range") + else + system_ptr = transfer(systemitem,system_ptr) + this_ptr%p%system(f90wrap_i) = system_ptr%p + endif + else + call f90wrap_abort("derived type array not allocated") + end if +end subroutine f90wrap_gvector_container_type__array_setitem__system + +subroutine f90wrap_gvector_container_type__array_len__system(f90wrap_this, f90wrap_n) + + use evolver, only: gvector_type, gvector_container_type + implicit none + + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type gvector_type_ptr_type + type(gvector_type), pointer :: p => NULL() + end type gvector_type_ptr_type + integer, intent(out) :: f90wrap_n + integer, intent(in) :: f90wrap_this(2) + type(gvector_container_type_ptr_type) :: this_ptr + + this_ptr = transfer(f90wrap_this, this_ptr) + if (allocated(this_ptr%p%system)) then + f90wrap_n = size(this_ptr%p%system) + else + f90wrap_n = 0 + end if +end subroutine f90wrap_gvector_container_type__array_len__system + +subroutine f90wrap_evolver__gvector_container_type_initialise(this) + use evolver, only: gvector_container_type + implicit none + + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(out), dimension(2) :: this + allocate(this_ptr%p) + this = transfer(this_ptr, this) +end subroutine f90wrap_evolver__gvector_container_type_initialise + +subroutine f90wrap_evolver__gvector_container_type_finalise(this) + use evolver, only: gvector_container_type + implicit none + + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + this_ptr = transfer(this, this_ptr) + deallocate(this_ptr%p) +end subroutine f90wrap_evolver__gvector_container_type_finalise + +subroutine f90wrap_evolver__set_width__binding__gvector_container_type(this, width) + use evolver, only: gvector_container_type + implicit none + + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + real(4), dimension(3), intent(in) :: width + this_ptr = transfer(this, this_ptr) + call this_ptr%p%set_width(width=width) +end subroutine f90wrap_evolver__set_width__binding__gvector_container_type + +subroutine f90wrap_evolver__set_sigma__binding__gvector_container_type(this, sigma) + use evolver, only: gvector_container_type + implicit none + + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + real(4), dimension(3), intent(in) :: sigma + this_ptr = transfer(this, this_ptr) + call this_ptr%p%set_sigma(sigma=sigma) +end subroutine f90wrap_evolver__set_sigma__binding__gvector_container_type + +subroutine f90wrap_evolver__set_cutoff_min__binding__gvector_container7007(this, cutoff_min) + use evolver, only: gvector_container_type + implicit none + + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + real(4), dimension(3), intent(in) :: cutoff_min + this_ptr = transfer(this, this_ptr) + call this_ptr%p%set_cutoff_min(cutoff_min=cutoff_min) +end subroutine f90wrap_evolver__set_cutoff_min__binding__gvector_container7007 + +subroutine f90wrap_evolver__set_cutoff_max__binding__gvector_container047c(this, cutoff_max) + use evolver, only: gvector_container_type + implicit none + + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + real(4), dimension(3), intent(in) :: cutoff_max + this_ptr = transfer(this, this_ptr) + call this_ptr%p%set_cutoff_max(cutoff_max=cutoff_max) +end subroutine f90wrap_evolver__set_cutoff_max__binding__gvector_container047c + +subroutine f90wrap_evolver__add_basis__binding__gvector_container_type(this, lattice, basis) + use rw_geom, only: bas_type + use evolver, only: gvector_container_type + implicit none + + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type bas_type_ptr_type + type(bas_type), pointer :: p => NULL() + end type bas_type_ptr_type + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + real(4), dimension(3,3), intent(in) :: lattice + type(bas_type_ptr_type) :: basis_ptr + integer, intent(in), dimension(2) :: basis + this_ptr = transfer(this, this_ptr) + basis_ptr = transfer(basis, basis_ptr) + call this_ptr%p%add_basis(lattice=lattice, basis=basis_ptr%p) +end subroutine f90wrap_evolver__add_basis__binding__gvector_container_type + +subroutine f90wrap_evolver__set_element_info__binding__gvector_containbcb0(this, element_file, element_list, n0) + use evolver, only: gvector_container_type + implicit none + + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + character*(*), intent(in), optional :: element_file + character(3), intent(in), optional, dimension(n0) :: element_list + integer :: n0 + !f2py intent(hide), depend(element_list) :: n0 = shape(element_list,0) + this_ptr = transfer(this, this_ptr) + call this_ptr%p%set_element_info(element_file=element_file, element_list=element_list) +end subroutine f90wrap_evolver__set_element_info__binding__gvector_containbcb0 + +subroutine f90wrap_evolver__set_bond_info__binding__gvector_container_type(this, bond_file) + use evolver, only: gvector_container_type + implicit none + + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + character*(*), intent(in), optional :: bond_file + this_ptr = transfer(this, this_ptr) + call this_ptr%p%set_bond_info(bond_file=bond_file) +end subroutine f90wrap_evolver__set_bond_info__binding__gvector_container_type + +subroutine f90wrap_evolver__set_best_energy__binding__gvector_containe4680(this) + use evolver, only: gvector_container_type + implicit none + + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + this_ptr = transfer(this, this_ptr) + call this_ptr%p%set_best_energy() +end subroutine f90wrap_evolver__set_best_energy__binding__gvector_containe4680 + +subroutine f90wrap_evolver__initialise_gvectors__binding__gvector_contc1f2(this) + use evolver, only: gvector_container_type + implicit none + + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + this_ptr = transfer(this, this_ptr) + call this_ptr%p%initialise_gvectors() +end subroutine f90wrap_evolver__initialise_gvectors__binding__gvector_contc1f2 + +subroutine f90wrap_evolver__evolve__binding__gvector_container_type(this, system, deallocate_systems_after_evolve) + use evolver, only: gvector_type, gvector_container_type + implicit none + + type gvector_type_ptr_type + type(gvector_type), pointer :: p => NULL() + end type gvector_type_ptr_type + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + type(gvector_type_ptr_type) :: system_ptr + integer, optional, intent(in), dimension(2) :: system + logical, intent(in), optional :: deallocate_systems_after_evolve + this_ptr = transfer(this, this_ptr) + if (present(system)) then + system_ptr = transfer(system, system_ptr) + else + system_ptr%p => null() + end if + call this_ptr%p%evolve(system=system_ptr%p, deallocate_systems_after_evolve=deallocate_systems_after_evolve) +end subroutine f90wrap_evolver__evolve__binding__gvector_container_type + +subroutine f90wrap_evolver__write__binding__gvector_container_type(this, file) + use evolver, only: gvector_container_type + implicit none + + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + character*(*), intent(in) :: file + this_ptr = transfer(this, this_ptr) + call this_ptr%p%write(file=file) +end subroutine f90wrap_evolver__write__binding__gvector_container_type + +subroutine f90wrap_evolver__read__binding__gvector_container_type(this, file) + use evolver, only: gvector_container_type + implicit none + + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + character*(*), intent(in) :: file + this_ptr = transfer(this, this_ptr) + call this_ptr%p%read(file=file) +end subroutine f90wrap_evolver__read__binding__gvector_container_type + +subroutine f90wrap_evolver__write_2body__binding__gvector_container_type(this, file) + use evolver, only: gvector_container_type + implicit none + + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + character*(*), intent(in) :: file + this_ptr = transfer(this, this_ptr) + call this_ptr%p%write_2body(file=file) +end subroutine f90wrap_evolver__write_2body__binding__gvector_container_type + +subroutine f90wrap_evolver__write_3body__binding__gvector_container_type(this, file) + use evolver, only: gvector_container_type + implicit none + + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + character*(*), intent(in) :: file + this_ptr = transfer(this, this_ptr) + call this_ptr%p%write_3body(file=file) +end subroutine f90wrap_evolver__write_3body__binding__gvector_container_type + +subroutine f90wrap_evolver__write_4body__binding__gvector_container_type(this, file) + use evolver, only: gvector_container_type + implicit none + + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + character*(*), intent(in) :: file + this_ptr = transfer(this, this_ptr) + call this_ptr%p%write_4body(file=file) +end subroutine f90wrap_evolver__write_4body__binding__gvector_container_type + +subroutine f90wrap_evolver__get_pair_index__binding__gvector_container4618(this, species1, ret_idx, species2) + use evolver, only: gvector_container_type + implicit none + + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + character(3), intent(in) :: species1 + integer, intent(out) :: ret_idx + character(3), intent(in) :: species2 + this_ptr = transfer(this, this_ptr) + ret_idx = this_ptr%p%get_pair_index(species1=species1, species2=species2) +end subroutine f90wrap_evolver__get_pair_index__binding__gvector_container4618 + +subroutine f90wrap_evolver__get_bin__binding__gvector_container_type(this, value, ret_bin, dim) + use evolver, only: gvector_container_type + implicit none + + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + real(4), intent(in) :: value + integer, intent(out) :: ret_bin + integer, intent(in) :: dim + this_ptr = transfer(this, this_ptr) + ret_bin = this_ptr%p%get_bin(value=value, dim=dim) +end subroutine f90wrap_evolver__get_bin__binding__gvector_container_type + +! End of module evolver defined in file ../src/lib/mod_evolver.f90 + diff --git a/edited_autogen_files/f90wrap_mod_generator.f90 b/edited_autogen_files/f90wrap_mod_generator.f90 index 4158d807..654a5000 100644 --- a/edited_autogen_files/f90wrap_mod_generator.f90 +++ b/edited_autogen_files/f90wrap_mod_generator.f90 @@ -325,6 +325,46 @@ subroutine f90wrap_raffle_generator_type__array__bins(this, nd, dtype, dshape, d dloc = loc(this_ptr%p%bins) end subroutine f90wrap_raffle_generator_type__array__bins +subroutine f90wrap_raffle_generator_type__get__distributions(this, f90wrap_distributions) + use generator, only: raffle_generator_type + use evolver, only: gvector_container_type + implicit none + type raffle_generator_type_ptr_type + type(raffle_generator_type), pointer :: p => NULL() + end type raffle_generator_type_ptr_type + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + integer, intent(in) :: this(2) + type(raffle_generator_type_ptr_type) :: this_ptr + integer, intent(out) :: f90wrap_distributions(2) + type(gvector_container_type_ptr_type) :: distributions_ptr + + this_ptr = transfer(this, this_ptr) + distributions_ptr%p => this_ptr%p%distributions + f90wrap_distributions = transfer(distributions_ptr,f90wrap_distributions) +end subroutine f90wrap_raffle_generator_type__get__distributions + +subroutine f90wrap_raffle_generator_type__set__distributions(this, f90wrap_distributions) + use generator, only: raffle_generator_type + use evolver, only: gvector_container_type + implicit none + type raffle_generator_type_ptr_type + type(raffle_generator_type), pointer :: p => NULL() + end type raffle_generator_type_ptr_type + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + integer, intent(in) :: this(2) + type(raffle_generator_type_ptr_type) :: this_ptr + integer, intent(in) :: f90wrap_distributions(2) + type(gvector_container_type_ptr_type) :: distributions_ptr + + this_ptr = transfer(this, this_ptr) + distributions_ptr = transfer(f90wrap_distributions,distributions_ptr) + this_ptr%p%distributions = distributions_ptr%p +end subroutine f90wrap_raffle_generator_type__set__distributions + subroutine f90wrap_raffle_generator_type__array__method_probab(this, nd, dtype, dshape, dloc) use generator, only: raffle_generator_type use, intrinsic :: iso_c_binding, only : c_int diff --git a/edited_autogen_files/raffle.py b/edited_autogen_files/raffle.py index e29db0c4..d65f6050 100644 --- a/edited_autogen_files/raffle.py +++ b/edited_autogen_files/raffle.py @@ -673,6 +673,905 @@ def deallocate(self): rw_geom = Rw_Geom() +class Evolver(f90wrap.runtime.FortranModule): + """ + Module evolver + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 1-1204 + + """ + @f90wrap.runtime.register_class("raffle.gvector_base_type") + class gvector_base_type(f90wrap.runtime.FortranDerivedType): + """ + Type(name=gvector_base_type) + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 14-17 + + """ + def __init__(self, handle=None): + """ + self = Gvector_Base_Type() + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 14-17 + + + Returns + ------- + this : Gvector_Base_Type + Object to be constructed + + + Automatically generated constructor for gvector_base_type + """ + f90wrap.runtime.FortranDerivedType.__init__(self) + result = _raffle.f90wrap_evolver__gvector_base_type_initialise() + self._handle = result[0] if isinstance(result, tuple) else result + + def __del__(self): + """ + Destructor for class Gvector_Base_Type + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 14-17 + + Parameters + ---------- + this : Gvector_Base_Type + Object to be destructed + + + Automatically generated destructor for gvector_base_type + """ + if self._alloc: + _raffle.f90wrap_evolver__gvector_base_type_finalise(this=self._handle) + + @property + def df_2body(self): + """ + Element df_2body ftype=real(real12) pytype=float + + + Defined at ../src/lib/mod_evolver.f90 line 15 + + """ + array_ndim, array_type, array_shape, array_handle = \ + _raffle.f90wrap_gvector_base_type__array__df_2body(self._handle) + if array_handle in self._arrays: + df_2body = self._arrays[array_handle] + else: + df_2body = f90wrap.runtime.get_array(f90wrap.runtime.sizeof_fortran_t, + self._handle, + _raffle.f90wrap_gvector_base_type__array__df_2body) + self._arrays[array_handle] = df_2body + return df_2body + + @df_2body.setter + def df_2body(self, df_2body): + self.df_2body[...] = df_2body + + @property + def df_3body(self): + """ + Element df_3body ftype=real(real12) pytype=float + + + Defined at ../src/lib/mod_evolver.f90 line 16 + + """ + array_ndim, array_type, array_shape, array_handle = \ + _raffle.f90wrap_gvector_base_type__array__df_3body(self._handle) + if array_handle in self._arrays: + df_3body = self._arrays[array_handle] + else: + df_3body = f90wrap.runtime.get_array(f90wrap.runtime.sizeof_fortran_t, + self._handle, + _raffle.f90wrap_gvector_base_type__array__df_3body) + self._arrays[array_handle] = df_3body + return df_3body + + @df_3body.setter + def df_3body(self, df_3body): + self.df_3body[...] = df_3body + + @property + def df_4body(self): + """ + Element df_4body ftype=real(real12) pytype=float + + + Defined at ../src/lib/mod_evolver.f90 line 17 + + """ + array_ndim, array_type, array_shape, array_handle = \ + _raffle.f90wrap_gvector_base_type__array__df_4body(self._handle) + if array_handle in self._arrays: + df_4body = self._arrays[array_handle] + else: + df_4body = f90wrap.runtime.get_array(f90wrap.runtime.sizeof_fortran_t, + self._handle, + _raffle.f90wrap_gvector_base_type__array__df_4body) + self._arrays[array_handle] = df_4body + return df_4body + + @df_4body.setter + def df_4body(self, df_4body): + self.df_4body[...] = df_4body + + def __str__(self): + ret = ['{\n'] + ret.append(' df_2body : ') + ret.append(repr(self.df_2body)) + ret.append(',\n df_3body : ') + ret.append(repr(self.df_3body)) + ret.append(',\n df_4body : ') + ret.append(repr(self.df_4body)) + ret.append('}') + return ''.join(ret) + + _dt_array_initialisers = [] + + + @f90wrap.runtime.register_class("raffle.gvector_type") + class gvector_type(f90wrap.runtime.FortranDerivedType): + """ + Type(name=gvector_type) + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 19-25 + + """ + def __init__(self, handle=None): + """ + self = Gvector_Type() + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 19-25 + + + Returns + ------- + this : Gvector_Type + Object to be constructed + + + Automatically generated constructor for gvector_type + """ + f90wrap.runtime.FortranDerivedType.__init__(self) + result = _raffle.f90wrap_evolver__gvector_type_initialise() + self._handle = result[0] if isinstance(result, tuple) else result + + def __del__(self): + """ + Destructor for class Gvector_Type + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 19-25 + + Parameters + ---------- + this : Gvector_Type + Object to be destructed + + + Automatically generated destructor for gvector_type + """ + if self._alloc: + _raffle.f90wrap_evolver__gvector_type_finalise(this=self._handle) + + def calculate(self, lattice, basis, nbins=None, width=None, sigma=None, \ + cutoff_min=None, cutoff_max=None): + """ + calculate__binding__gvector_type(self, lattice, basis[, nbins, width, sigma, \ + cutoff_min, cutoff_max]) + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 747-1135 + + Parameters + ---------- + this : unknown + lattice : float array + basis : Bas_Type + nbins : int array + width : float array + sigma : float array + cutoff_min : float array + cutoff_max : float array + + -------------------------------------------------------------------------- + initialise optional variables + -------------------------------------------------------------------------- + """ + _raffle.f90wrap_evolver__calculate__binding__gvector_type(this=self._handle, \ + lattice=lattice, basis=basis._handle, nbins=nbins, width=width, sigma=sigma, \ + cutoff_min=cutoff_min, cutoff_max=cutoff_max) + + @property + def num_atoms(self): + """ + Element num_atoms ftype=integer pytype=int + + + Defined at ../src/lib/mod_evolver.f90 line 20 + + """ + return _raffle.f90wrap_gvector_type__get__num_atoms(self._handle) + + @num_atoms.setter + def num_atoms(self, num_atoms): + _raffle.f90wrap_gvector_type__set__num_atoms(self._handle, num_atoms) + + @property + def energy(self): + """ + Element energy ftype=real(real12) pytype=float + + + Defined at ../src/lib/mod_evolver.f90 line 21 + + """ + return _raffle.f90wrap_gvector_type__get__energy(self._handle) + + @energy.setter + def energy(self, energy): + _raffle.f90wrap_gvector_type__set__energy(self._handle, energy) + + @property + def stoichiometry(self): + """ + Element stoichiometry ftype=integer pytype=int + + + Defined at ../src/lib/mod_evolver.f90 line 22 + + """ + array_ndim, array_type, array_shape, array_handle = \ + _raffle.f90wrap_gvector_type__array__stoichiometry(self._handle) + if array_handle in self._arrays: + stoichiometry = self._arrays[array_handle] + else: + stoichiometry = f90wrap.runtime.get_array(f90wrap.runtime.sizeof_fortran_t, + self._handle, + _raffle.f90wrap_gvector_type__array__stoichiometry) + self._arrays[array_handle] = stoichiometry + return stoichiometry + + @stoichiometry.setter + def stoichiometry(self, stoichiometry): + self.stoichiometry[...] = stoichiometry + + @property + def species(self): + """ + Element species ftype=character(len=3) pytype=str + + + Defined at ../src/lib/mod_evolver.f90 line 23 + + """ + array_ndim, array_type, array_shape, array_handle = \ + _raffle.f90wrap_gvector_type__array__species(self._handle) + if array_handle in self._arrays: + species = self._arrays[array_handle] + else: + species = f90wrap.runtime.get_array(f90wrap.runtime.sizeof_fortran_t, + self._handle, + _raffle.f90wrap_gvector_type__array__species) + self._arrays[array_handle] = species + return species + + @species.setter + def species(self, species): + self.species[...] = species + + def __str__(self): + ret = ['{\n'] + ret.append(' num_atoms : ') + ret.append(repr(self.num_atoms)) + ret.append(',\n energy : ') + ret.append(repr(self.energy)) + ret.append(',\n stoichiometry : ') + ret.append(repr(self.stoichiometry)) + ret.append(',\n species : ') + ret.append(repr(self.species)) + ret.append('}') + return ''.join(ret) + + _dt_array_initialisers = [] + + + @f90wrap.runtime.register_class("raffle.gvector_container_type") + class gvector_container_type(f90wrap.runtime.FortranDerivedType): + """ + Type(name=gvector_container_type) + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 30-62 + + """ + def __init__(self, handle=None): + """ + self = Gvector_Container_Type() + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 30-62 + + + Returns + ------- + this : Gvector_Container_Type + Object to be constructed + + + Automatically generated constructor for gvector_container_type + """ + f90wrap.runtime.FortranDerivedType.__init__(self) + result = _raffle.f90wrap_evolver__gvector_container_type_initialise() + self._handle = result[0] if isinstance(result, tuple) else result + + def __del__(self): + """ + Destructor for class Gvector_Container_Type + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 30-62 + + Parameters + ---------- + this : Gvector_Container_Type + Object to be destructed + + + Automatically generated destructor for gvector_container_type + """ + if self._alloc: + _raffle.f90wrap_evolver__gvector_container_type_finalise(this=self._handle) + + def set_width(self, width): + """ + set_width__binding__gvector_container_type(self, width) + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 108-118 + + Parameters + ---------- + this : unknown + width : float array + + """ + _raffle.f90wrap_evolver__set_width__binding__gvector_container_type(this=self._handle, \ + width=width) + + def set_sigma(self, sigma): + """ + set_sigma__binding__gvector_container_type(self, sigma) + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 120-130 + + Parameters + ---------- + this : unknown + sigma : float array + + """ + _raffle.f90wrap_evolver__set_sigma__binding__gvector_container_type(this=self._handle, \ + sigma=sigma) + + def set_cutoff_min(self, cutoff_min): + """ + set_cutoff_min__binding__gvector_container_type(self, cutoff_min) + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 132-140 + + Parameters + ---------- + this : unknown + cutoff_min : float array + + """ + _raffle.f90wrap_evolver__set_cutoff_min__binding__gvector_container7007(this=self._handle, \ + cutoff_min=cutoff_min) + + def set_cutoff_max(self, cutoff_max): + """ + set_cutoff_max__binding__gvector_container_type(self, cutoff_max) + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 142-150 + + Parameters + ---------- + this : unknown + cutoff_max : float array + + """ + _raffle.f90wrap_evolver__set_cutoff_max__binding__gvector_container047c(this=self._handle, \ + cutoff_max=cutoff_max) + + def add_basis(self, lattice, basis): + """ + add_basis__binding__gvector_container_type(self, lattice, basis) + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 415-430 + + Parameters + ---------- + this : unknown + lattice : float array + basis : Bas_Type + + """ + _raffle.f90wrap_evolver__add_basis__binding__gvector_container_type(this=self._handle, \ + lattice=lattice, basis=basis._handle) + + def set_element_info(self, element_file=None, element_list=None): + """ + set_element_info__binding__gvector_container_type(self[, element_file, \ + element_list]) + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 436-466 + + Parameters + ---------- + this : unknown + element_file : str + element_list : str array + + -------------------------------------------------------------------------- + load the elements database + -------------------------------------------------------------------------- + """ + _raffle.f90wrap_evolver__set_element_info__binding__gvector_containbcb0(this=self._handle, \ + element_file=element_file, element_list=element_list) + + def set_bond_info(self, bond_file=None): + """ + set_bond_info__binding__gvector_container_type(self[, bond_file]) + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 472-526 + + Parameters + ---------- + this : unknown + bond_file : str + + -------------------------------------------------------------------------- + load the element bonds database + -------------------------------------------------------------------------- + """ + _raffle.f90wrap_evolver__set_bond_info__binding__gvector_container_type(this=self._handle, \ + bond_file=bond_file) + + def set_best_energy(self): + """ + set_best_energy__binding__gvector_container_type(self) + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 532-554 + + Parameters + ---------- + this : unknown + + """ + _raffle.f90wrap_evolver__set_best_energy__binding__gvector_containe4680(this=self._handle) + + def initialise_gvectors(self): + """ + initialise_gvectors__binding__gvector_container_type(self) + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 600-630 + + Parameters + ---------- + this : unknown + + """ + _raffle.f90wrap_evolver__initialise_gvectors__binding__gvector_contc1f2(this=self._handle) + + def evolve(self, system=None, deallocate_systems_after_evolve=None): + """ + evolve__binding__gvector_container_type(self[, system, \ + deallocate_systems_after_evolve]) + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 637-740 + + Parameters + ---------- + this : unknown + system : Gvector_Type array + deallocate_systems_after_evolve : bool + + -------------------------------------------------------------------------- + if present, set the deallocate flag + -------------------------------------------------------------------------- + """ + _raffle.f90wrap_evolver__evolve__binding__gvector_container_type(this=self._handle, \ + system=None if system is None else system._handle, \ + deallocate_systems_after_evolve=deallocate_systems_after_evolve) + + def write(self, file): + """ + write__binding__gvector_container_type(self, file) + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 182-210 + + Parameters + ---------- + this : unknown + file : str + + """ + _raffle.f90wrap_evolver__write__binding__gvector_container_type(this=self._handle, \ + file=file) + + def read(self, file): + """ + read__binding__gvector_container_type(self, file) + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 216-260 + + Parameters + ---------- + this : unknown + file : str + + """ + _raffle.f90wrap_evolver__read__binding__gvector_container_type(this=self._handle, \ + file=file) + + def write_2body(self, file): + """ + write_2body__binding__gvector_container_type(self, file) + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 266-295 + + Parameters + ---------- + this : unknown + file : str + + """ + _raffle.f90wrap_evolver__write_2body__binding__gvector_container_type(this=self._handle, \ + file=file) + + def write_3body(self, file): + """ + write_3body__binding__gvector_container_type(self, file) + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 301-315 + + Parameters + ---------- + this : unknown + file : str + + """ + _raffle.f90wrap_evolver__write_3body__binding__gvector_container_type(this=self._handle, \ + file=file) + + def write_4body(self, file): + """ + write_4body__binding__gvector_container_type(self, file) + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 321-335 + + Parameters + ---------- + this : unknown + file : str + + """ + _raffle.f90wrap_evolver__write_4body__binding__gvector_container_type(this=self._handle, \ + file=file) + + def get_pair_index(self, species1, species2): + """ + idx = get_pair_index__binding__gvector_container_type(self, species1, species2) + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 560-575 + + Parameters + ---------- + this : unknown + species1 : str + species2 : str + + Returns + ------- + idx : int + + """ + idx = \ + _raffle.f90wrap_evolver__get_pair_index__binding__gvector_container4618(this=self._handle, \ + species1=species1, species2=species2) + return idx + + def get_bin(self, value, dim): + """ + bin = get_bin__binding__gvector_container_type(self, value, dim) + + + Defined at ../src/lib/mod_evolver.f90 lines \ + 581-594 + + Parameters + ---------- + this : unknown + value : float + dim : int + + Returns + ------- + bin : int + + """ + bin = \ + _raffle.f90wrap_evolver__get_bin__binding__gvector_container_type(this=self._handle, \ + value=value, dim=dim) + return bin + + @property + def best_system(self): + """ + Element best_system ftype=integer pytype=int + + + Defined at ../src/lib/mod_evolver.f90 line 31 + + """ + return _raffle.f90wrap_gvector_container_type__get__best_system(self._handle) + + @best_system.setter + def best_system(self, best_system): + _raffle.f90wrap_gvector_container_type__set__best_system(self._handle, \ + best_system) + + @property + def best_energy(self): + """ + Element best_energy ftype=real(real12) pytype=float + + + Defined at ../src/lib/mod_evolver.f90 line 32 + + """ + return _raffle.f90wrap_gvector_container_type__get__best_energy(self._handle) + + @best_energy.setter + def best_energy(self, best_energy): + _raffle.f90wrap_gvector_container_type__set__best_energy(self._handle, \ + best_energy) + + @property + def nbins(self): + """ + Element nbins ftype=integer pytype=int + + + Defined at ../src/lib/mod_evolver.f90 line 33 + + """ + array_ndim, array_type, array_shape, array_handle = \ + _raffle.f90wrap_gvector_container_type__array__nbins(self._handle) + if array_handle in self._arrays: + nbins = self._arrays[array_handle] + else: + nbins = f90wrap.runtime.get_array(f90wrap.runtime.sizeof_fortran_t, + self._handle, + _raffle.f90wrap_gvector_container_type__array__nbins) + self._arrays[array_handle] = nbins + return nbins + + @nbins.setter + def nbins(self, nbins): + self.nbins[...] = nbins + + @property + def sigma(self): + """ + Element sigma ftype=real(real12) pytype=float + + + Defined at ../src/lib/mod_evolver.f90 line 34 + + """ + array_ndim, array_type, array_shape, array_handle = \ + _raffle.f90wrap_gvector_container_type__array__sigma(self._handle) + if array_handle in self._arrays: + sigma = self._arrays[array_handle] + else: + sigma = f90wrap.runtime.get_array(f90wrap.runtime.sizeof_fortran_t, + self._handle, + _raffle.f90wrap_gvector_container_type__array__sigma) + self._arrays[array_handle] = sigma + return sigma + + @sigma.setter + def sigma(self, sigma): + self.sigma[...] = sigma + + @property + def width(self): + """ + Element width ftype=real(real12) pytype=float + + + Defined at ../src/lib/mod_evolver.f90 line 35 + + """ + array_ndim, array_type, array_shape, array_handle = \ + _raffle.f90wrap_gvector_container_type__array__width(self._handle) + if array_handle in self._arrays: + width = self._arrays[array_handle] + else: + width = f90wrap.runtime.get_array(f90wrap.runtime.sizeof_fortran_t, + self._handle, + _raffle.f90wrap_gvector_container_type__array__width) + self._arrays[array_handle] = width + return width + + @width.setter + def width(self, width): + self.width[...] = width + + @property + def cutoff_min(self): + """ + Element cutoff_min ftype=real(real12) pytype=float + + + Defined at ../src/lib/mod_evolver.f90 line 36 + + """ + array_ndim, array_type, array_shape, array_handle = \ + _raffle.f90wrap_gvector_container_type__array__cutoff_min(self._handle) + if array_handle in self._arrays: + cutoff_min = self._arrays[array_handle] + else: + cutoff_min = f90wrap.runtime.get_array(f90wrap.runtime.sizeof_fortran_t, + self._handle, + _raffle.f90wrap_gvector_container_type__array__cutoff_min) + self._arrays[array_handle] = cutoff_min + return cutoff_min + + @cutoff_min.setter + def cutoff_min(self, cutoff_min): + self.cutoff_min[...] = cutoff_min + + @property + def cutoff_max(self): + """ + Element cutoff_max ftype=real(real12) pytype=float + + + Defined at ../src/lib/mod_evolver.f90 line 37 + + """ + array_ndim, array_type, array_shape, array_handle = \ + _raffle.f90wrap_gvector_container_type__array__cutoff_max(self._handle) + if array_handle in self._arrays: + cutoff_max = self._arrays[array_handle] + else: + cutoff_max = f90wrap.runtime.get_array(f90wrap.runtime.sizeof_fortran_t, + self._handle, + _raffle.f90wrap_gvector_container_type__array__cutoff_max) + self._arrays[array_handle] = cutoff_max + return cutoff_max + + @cutoff_max.setter + def cutoff_max(self, cutoff_max): + self.cutoff_max[...] = cutoff_max + + @property + def total(self): + """ + Element total ftype=type(gvector_base_type) pytype=Gvector_Base_Type + + + Defined at ../src/lib/mod_evolver.f90 line 38 + + """ + total_handle = _raffle.f90wrap_gvector_container_type__get__total(self._handle) + if tuple(total_handle) in self._objs: + total = self._objs[tuple(total_handle)] + else: + total = evolver.gvector_base_type.from_handle(total_handle) + self._objs[tuple(total_handle)] = total + return total + + @total.setter + def total(self, total): + total = total._handle + _raffle.f90wrap_gvector_container_type__set__total(self._handle, total) + + def init_array_system(self): + self.system = f90wrap.runtime.FortranDerivedTypeArray(self, + _raffle.f90wrap_gvector_container_type__array_getitem__system, + _raffle.f90wrap_gvector_container_type__array_setitem__system, + _raffle.f90wrap_gvector_container_type__array_len__system, + """ + Element system ftype=type(gvector_type) pytype=Gvector_Type + + + Defined at ../src/lib/mod_evolver.f90 line 39 + + """, Evolver.gvector_type) + return self.system + + def __str__(self): + ret = ['{\n'] + ret.append(' best_system : ') + ret.append(repr(self.best_system)) + ret.append(',\n best_energy : ') + ret.append(repr(self.best_energy)) + ret.append(',\n nbins : ') + ret.append(repr(self.nbins)) + ret.append(',\n sigma : ') + ret.append(repr(self.sigma)) + ret.append(',\n width : ') + ret.append(repr(self.width)) + ret.append(',\n cutoff_min : ') + ret.append(repr(self.cutoff_min)) + ret.append(',\n cutoff_max : ') + ret.append(repr(self.cutoff_max)) + ret.append(',\n total : ') + ret.append(repr(self.total)) + ret.append('}') + return ''.join(ret) + + _dt_array_initialisers = [init_array_system] + + + _dt_array_initialisers = [] + + +evolver = Evolver() + class Generator(f90wrap.runtime.FortranModule): """ Module generator @@ -1046,6 +1945,32 @@ def bins(self): def bins(self, bins): self.bins[...] = bins + @property + def distributions(self): + """ + Element distributions ftype=type(gvector_container_type) \ + pytype=Gvector_Container_Type + + + Defined at ../src/lib/mod_generator.f90 line \ + 27 + + """ + distributions_handle = \ + _raffle.f90wrap_raffle_generator_type__get__distributions(self._handle) + if tuple(distributions_handle) in self._objs: + distributions = self._objs[tuple(distributions_handle)] + else: + distributions = evolver.gvector_container_type.from_handle(distributions_handle) + self._objs[tuple(distributions_handle)] = distributions + return distributions + + @distributions.setter + def distributions(self, distributions): + distributions = distributions._handle + _raffle.f90wrap_raffle_generator_type__set__distributions(self._handle, \ + distributions) + @property def method_probab(self): """ @@ -1094,6 +2019,8 @@ def __str__(self): ret.append(repr(self.host)) ret.append(',\n bins : ') ret.append(repr(self.bins)) + ret.append(',\n distributions : ') + ret.append(repr(self.distributions)) ret.append(',\n method_probab : ') ret.append(repr(self.method_probab)) ret.append('}') diff --git a/src/lib/mod_evolver.f90 b/src/lib/mod_evolver.f90 index f6818ea7..f630c414 100644 --- a/src/lib/mod_evolver.f90 +++ b/src/lib/mod_evolver.f90 @@ -13,7 +13,7 @@ module evolver private - public :: gvector_container_type + public :: gvector_container_type, gvector_base_type, gvector_type type :: gvector_base_type From e1d061370e0adef1170b68d97da844669e5184c6 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Fri, 19 Jul 2024 11:14:55 +0100 Subject: [PATCH 036/293] Embed lattice in bas_type --- edited_autogen_files/f90wrap_mod_evolver.f90 | 10 +- src/lib/mod_atom_adder.f90 | 27 +- src/lib/mod_buildmap.f90 | 5 +- src/lib/mod_edit_geom.f90 | 233 ++++++++-------- src/lib/mod_evolver.f90 | 73 ++--- src/lib/mod_generator.f90 | 15 +- src/lib/mod_read_structures.f90 | 24 +- src/lib/mod_rw_geom.f90 | 276 ++++++++++--------- src/lib/mod_rw_vasprun.f90 | 5 +- 9 files changed, 305 insertions(+), 363 deletions(-) diff --git a/edited_autogen_files/f90wrap_mod_evolver.f90 b/edited_autogen_files/f90wrap_mod_evolver.f90 index 92d0796a..46baedcd 100644 --- a/edited_autogen_files/f90wrap_mod_evolver.f90 +++ b/edited_autogen_files/f90wrap_mod_evolver.f90 @@ -233,7 +233,7 @@ subroutine f90wrap_evolver__gvector_type_finalise(this) deallocate(this_ptr%p) end subroutine f90wrap_evolver__gvector_type_finalise -subroutine f90wrap_evolver__calculate__binding__gvector_type(this, lattice, basis, nbins, width, sigma, cutoff_min, & +subroutine f90wrap_evolver__calculate__binding__gvector_type(this, basis, nbins, width, sigma, cutoff_min, & cutoff_max) use evolver, only: gvector_type use rw_geom, only: bas_type @@ -247,7 +247,6 @@ subroutine f90wrap_evolver__calculate__binding__gvector_type(this, lattice, basi end type gvector_type_ptr_type type(gvector_type_ptr_type) :: this_ptr integer, intent(in), dimension(2) :: this - real(4), dimension(3,3), intent(in) :: lattice type(bas_type_ptr_type) :: basis_ptr integer, intent(in), dimension(2) :: basis integer, dimension(3), intent(in), optional :: nbins @@ -257,7 +256,7 @@ subroutine f90wrap_evolver__calculate__binding__gvector_type(this, lattice, basi real(4), dimension(3), intent(in), optional :: cutoff_max this_ptr = transfer(this, this_ptr) basis_ptr = transfer(basis, basis_ptr) - call this_ptr%p%calculate(lattice=lattice, basis=basis_ptr%p, nbins=nbins, width=width, sigma=sigma, & + call this_ptr%p%calculate(basis=basis_ptr%p, nbins=nbins, width=width, sigma=sigma, & cutoff_min=cutoff_min, cutoff_max=cutoff_max) end subroutine f90wrap_evolver__calculate__binding__gvector_type @@ -625,7 +624,7 @@ subroutine f90wrap_evolver__set_cutoff_max__binding__gvector_container047c(this, call this_ptr%p%set_cutoff_max(cutoff_max=cutoff_max) end subroutine f90wrap_evolver__set_cutoff_max__binding__gvector_container047c -subroutine f90wrap_evolver__add_basis__binding__gvector_container_type(this, lattice, basis) +subroutine f90wrap_evolver__add_basis__binding__gvector_container_type(this, basis) use rw_geom, only: bas_type use evolver, only: gvector_container_type implicit none @@ -638,12 +637,11 @@ subroutine f90wrap_evolver__add_basis__binding__gvector_container_type(this, lat end type bas_type_ptr_type type(gvector_container_type_ptr_type) :: this_ptr integer, intent(in), dimension(2) :: this - real(4), dimension(3,3), intent(in) :: lattice type(bas_type_ptr_type) :: basis_ptr integer, intent(in), dimension(2) :: basis this_ptr = transfer(this, this_ptr) basis_ptr = transfer(basis, basis_ptr) - call this_ptr%p%add_basis(lattice=lattice, basis=basis_ptr%p) + call this_ptr%p%add_basis(basis=basis_ptr%p) end subroutine f90wrap_evolver__add_basis__binding__gvector_container_type subroutine f90wrap_evolver__set_element_info__binding__gvector_containbcb0(this, element_file, element_list, n0) diff --git a/src/lib/mod_atom_adder.f90 b/src/lib/mod_atom_adder.f90 index 419cdc56..0d071dd0 100644 --- a/src/lib/mod_atom_adder.f90 +++ b/src/lib/mod_atom_adder.f90 @@ -21,14 +21,13 @@ module add_atom !!! add atom to unit cell using the scan method !!!############################################################################# subroutine add_atom_scan (gridpoints, gvector_container, & - lattice, basis, atom_ignore_list, & + basis, atom_ignore_list, & radius_list, placed) implicit none type(gvector_container_type), intent(in) :: gvector_container type(bas_type), intent(inout) :: basis logical, intent(out) :: placed integer, dimension(:,:), intent(in) :: atom_ignore_list - real(real12), dimension(3,3) :: lattice real(real12), dimension(:,:), intent(in) :: gridpoints real(real12), dimension(:) :: radius_list @@ -43,7 +42,7 @@ subroutine add_atom_scan (gridpoints, gvector_container, & allocate(suitability_grid(size(gridpoints,dim=2))) do concurrent( i = 1:size(gridpoints,dim=2) ) suitability_grid(i) = buildmap_POINT( gvector_container, & - gridpoints(:,i), lattice, basis, & + gridpoints(:,i), basis, & atom_ignore_list, radius_list, & 1.1_real12, 0.95_real12) end do @@ -62,12 +61,11 @@ end subroutine add_atom_scan !!!############################################################################# !!! add atom to unit cell considering the void space !!!############################################################################# - subroutine add_atom_void (bin_size, lattice, basis, atom_ignore_list, placed) + subroutine add_atom_void (bin_size, basis, atom_ignore_list, placed) implicit none type(bas_type), intent(inout) :: basis integer, dimension(3), intent(in) :: bin_size integer, dimension(:,:), intent(in) :: atom_ignore_list - real(real12), dimension(3,3), intent(in) :: lattice logical, intent(out) :: placed integer :: i, j, k, l @@ -83,7 +81,7 @@ subroutine add_atom_void (bin_size, lattice, basis, atom_ignore_list, placed) do k = 0, bin_size(3) - 1, 1 tmpvector = [i, j, k] / real(bin_size,real12) smallest_bond = modu(get_min_dist(& - lattice, basis, tmpvector, .false., & + basis, tmpvector, .false., & ignore_list = atom_ignore_list)) if( smallest_bond .gt. best_location_bond ) then best_location_bond = smallest_bond @@ -105,7 +103,7 @@ end subroutine add_atom_void !!! add atom to unit cell using a pseudo-random walk method !!!############################################################################# subroutine add_atom_pseudo (bin_size, gvector_container, & - lattice, basis, atom_ignore_list, & + basis, atom_ignore_list, & radius_list, placed) implicit none type(gvector_container_type), intent(in) :: gvector_container @@ -113,7 +111,6 @@ subroutine add_atom_pseudo (bin_size, gvector_container, & logical, intent(out) :: placed integer, dimension(:,:), intent(in) :: atom_ignore_list integer, dimension(3), intent(in) :: bin_size - real(real12), dimension(3,3), intent(in) :: lattice real(real12), dimension(:), intent(in) :: radius_list integer :: i, j, k, l @@ -140,7 +137,7 @@ subroutine add_atom_pseudo (bin_size, gvector_container, & end do calculated_value = buildmap_POINT( gvector_container, & - tmpvector, lattice, basis, & + tmpvector, basis, & atom_ignore_list, radius_list, & 1.1_real12, 0.95_real12) @@ -169,7 +166,7 @@ subroutine add_atom_pseudo (bin_size, gvector_container, & testvector = testvector - floor(testvector) calculated_test = buildmap_POINT( gvector_container, & - testvector, lattice, basis, & + testvector, basis, & atom_ignore_list, radius_list, & 1.1_real12, 0.95_real12) @@ -222,13 +219,12 @@ end subroutine add_atom_pseudo !!! get the viable gridpoints for adding an atom !!! i.e. only return gridpoints that are not too close to an existing atom !!!############################################################################# - function get_viable_gridpoints(bin_size, lattice, basis, & + function get_viable_gridpoints(bin_size, basis, & radius_list, atom_ignore_list) result(points) implicit none type(bas_type), intent(in) :: basis integer, dimension(3), intent(in) :: bin_size integer, dimension(:,:), intent(in) :: atom_ignore_list - real(real12), dimension(3,3), intent(in) :: lattice real(real12), dimension(:), intent(in) :: radius_list integer, dimension(:), allocatable :: pair_index @@ -255,7 +251,7 @@ function get_viable_gridpoints(bin_size, lattice, basis, & if(all(atom_ignore_list(l,:).eq.[is,ia])) cycle end do if( get_min_dist_between_point_and_atom( & - lattice, basis, & + basis, & [i, j, k] / real(bin_size,real12), [is,ia] ) .lt. & radius_list(pair_index(is)) * 0.95_real12 ) & cycle grid_loop3 @@ -276,12 +272,11 @@ end function get_viable_gridpoints !!! update the viable gridpoints for adding an atom !!! i.e. remove gridpoints that are too close to an existing atom !!!############################################################################# - subroutine update_viable_gridpoints(points, lattice, basis, atom, radius) + subroutine update_viable_gridpoints(points, basis, atom, radius) implicit none type(bas_type), intent(in) :: basis integer, dimension(2) :: atom real(real12), dimension(:,:), allocatable, intent(inout) :: points - real(real12), dimension(3,3), intent(in) :: lattice real(real12), intent(in) :: radius integer :: i, pair_index, num_points @@ -295,7 +290,7 @@ subroutine update_viable_gridpoints(points, lattice, basis, atom, radius) do while (i .le. num_points) i = i + 1 if( get_min_dist_between_point_and_atom( & - lattice, basis, points(:,i), atom ) .lt. & + basis, points(:,i), atom ) .lt. & radius * 0.95_real12 ) then num_points = num_points - 1 points_tmp(:,i:num_points) = points_tmp(:,i+1:num_points+1) diff --git a/src/lib/mod_buildmap.f90 b/src/lib/mod_buildmap.f90 index 29f39edb..db1bd6ce 100644 --- a/src/lib/mod_buildmap.f90 +++ b/src/lib/mod_buildmap.f90 @@ -20,7 +20,7 @@ module buildmap !!!############################################################################# !!! output = suitability of tested point pure function buildmap_POINT(gvector_container, & - position, lattice, basis, atom_ignore_list, & + position, basis, atom_ignore_list, & radius_list, uptol, lowtol) & result(output) implicit none @@ -29,7 +29,6 @@ pure function buildmap_POINT(gvector_container, & type(bas_type), intent(in) :: basis real(real12), dimension(3), intent(in) :: position integer, dimension(:,:), intent(in) :: atom_ignore_list - real(real12), dimension(3,3), intent(in) :: lattice real(real12), dimension(:), intent(in) :: radius_list real(real12) :: output @@ -82,7 +81,7 @@ pure function buildmap_POINT(gvector_container, & !!! ... above upper tolerance, and doesn't fall within 3- and 4-body ... !!! ... check requirements - bondlength = get_min_dist_between_point_and_atom(lattice, basis, & + bondlength = get_min_dist_between_point_and_atom(basis, & position, [is, ia]) !! check if the bondlength is within the tolerance for bonds ... diff --git a/src/lib/mod_edit_geom.f90 b/src/lib/mod_edit_geom.f90 index 61412b5d..7d07cacf 100644 --- a/src/lib/mod_edit_geom.f90 +++ b/src/lib/mod_edit_geom.f90 @@ -287,13 +287,12 @@ end function get_atom_height !!!############################################################################# !!! returns minimum bond within bulk !!!############################################################################# - function get_min_bulk_bond(lat,bas) result(min_bond) + function get_min_bulk_bond(bas) result(min_bond) implicit none integer :: is,ia,js,ja real(real12) :: dtmp1,min_bond type(bas_type) :: bas real(real12), dimension(3) :: vdtmp1 - real(real12), dimension(3,3) :: lat min_bond=huge(0._real12) @@ -305,9 +304,9 @@ function get_min_bulk_bond(lat,bas) result(min_bond) if(is.eq.js.and.ia.eq.ja) cycle atmloop vdtmp1 = bas%spec(js)%atom(ja,:3) - bas%spec(is)%atom(ia,:3) vdtmp1 = & - vdtmp1(1)*lat(1,:3) + & - vdtmp1(2)*lat(2,:3) + & - vdtmp1(3)*lat(3,:3) + vdtmp1(1)*bas%lat(1,:3) + & + vdtmp1(2)*bas%lat(2,:3) + & + vdtmp1(3)*bas%lat(3,:3) dtmp1 = modu(vdtmp1) if(dtmp1.lt.min_bond) min_bond = dtmp1 end do atmloop @@ -324,7 +323,7 @@ end function get_min_bulk_bond !!!############################################################################# !!! returns minimum bond for a specified atom !!!############################################################################# - function get_min_bond(lat,bas,is,ia,axis,labove,tol) result(vsave) + function get_min_bond(bas,is,ia,axis,labove,tol) result(vsave) implicit none integer :: js,ja integer :: axis_ @@ -334,7 +333,6 @@ function get_min_bond(lat,bas,is,ia,axis,labove,tol) result(vsave) integer, intent(in) :: is,ia type(bas_type), intent(in) :: bas - real(real12), dimension(3,3), intent(in) :: lat integer, intent(in), optional :: axis real(real12), intent(in), optional :: tol @@ -373,9 +371,9 @@ function get_min_bond(lat,bas,is,ia,axis,labove,tol) result(vsave) end if end if vdtmp1 = & - vdtmp1(1)*lat(1,:3) + & - vdtmp1(2)*lat(2,:3) + & - vdtmp1(3)*lat(3,:3) + vdtmp1(1)*bas%lat(1,:3) + & + vdtmp1(2)*bas%lat(2,:3) + & + vdtmp1(3)*bas%lat(3,:3) dtmp1 = modu(vdtmp1) if(dtmp1.lt.min_bond)then min_bond = dtmp1 @@ -392,7 +390,7 @@ end function get_min_bond !!!############################################################################# !!! returns minimum bond for a specified atom !!!############################################################################# - function get_min_dist(lat,bas,loc,lignore_close,axis,labove,lreal,tol, & + function get_min_dist(bas,loc,lignore_close,axis,labove,lreal,tol, & ignore_list) result(output) implicit none integer :: js,ja,i @@ -405,7 +403,6 @@ function get_min_dist(lat,bas,loc,lignore_close,axis,labove,lreal,tol, & logical, intent(in) :: lignore_close type(bas_type), intent(in) :: bas real(real12), dimension(3), intent(in) :: loc - real(real12), dimension(3,3), intent(in) :: lat integer, intent(in), optional :: axis real(real12), intent(in), optional :: tol @@ -442,7 +439,7 @@ function get_min_dist(lat,bas,loc,lignore_close,axis,labove,lreal,tol, & else vdtmp1 = vdtmp1 - ceiling(vdtmp1 - 0.5_real12) end if - vdtmp2 = matmul(vdtmp1,lat) + vdtmp2 = matmul(vdtmp1,bas%lat) dtmp1 = modu(vdtmp2) if(dtmp1.lt.min_bond)then min_bond = dtmp1 @@ -462,12 +459,11 @@ end function get_min_dist !!!############################################################################# !!! get the shortest distance between two atoms in a periodic cell !!!############################################################################# - pure function get_min_dist_between_two_atoms(lat,bas,atom_1,atom_2) & + pure function get_min_dist_between_two_atoms(bas,atom_1,atom_2) & result(dist) implicit none type(bas_type), intent(in) :: bas integer, dimension(2), intent(in) :: atom_1,atom_2 - real(real12), dimension(3,3), intent(in) :: lat real(real12) :: dist real(real12), dimension(3) :: vec @@ -475,7 +471,7 @@ pure function get_min_dist_between_two_atoms(lat,bas,atom_1,atom_2) & vec = bas%spec(atom_2(1))%atom(atom_2(2),:3) - & bas%spec(atom_1(1))%atom(atom_1(2),:3) vec = vec - ceiling(vec - 0.5_real12) - vec = matmul(vec,lat) + vec = matmul(vec,bas%lat) dist = modu(vec) end function get_min_dist_between_two_atoms @@ -485,20 +481,19 @@ end function get_min_dist_between_two_atoms !!!############################################################################# !!! get the shortest distance between a point and an atom in a periodic cell !!!############################################################################# - pure function get_min_dist_between_point_and_atom(lat,bas,loc,atom) & + pure function get_min_dist_between_point_and_atom(bas,loc,atom) & result(dist) implicit none type(bas_type), intent(in) :: bas integer, dimension(2), intent(in) :: atom real(real12), dimension(3), intent(in) :: loc - real(real12), dimension(3,3), intent(in) :: lat real(real12) :: dist real(real12), dimension(3) :: vec vec = loc - bas%spec(atom(1))%atom(atom(2),:3) vec = vec - ceiling(vec - 0.5_real12) - vec = matmul(vec,lat) + vec = matmul(vec,bas%lat) dist = modu(vec) end function get_min_dist_between_point_and_atom @@ -508,7 +503,7 @@ end function get_min_dist_between_point_and_atom !!!############################################################################# !!! identify the shortest bond in the crystal, takes in crystal basis !!!############################################################################# - function get_shortest_bond(lat,bas) result(bond) + function get_shortest_bond(bas) result(bond) implicit none integer :: is,js,ia,ja,ja_start real(real12) :: dist,min_bond @@ -516,7 +511,6 @@ function get_shortest_bond(lat,bas) result(bond) type(bond_type) :: bond real(real12), dimension(3) :: vec integer, dimension(2,2) :: atoms - real(real12), dimension(3,3) :: lat min_bond = 100._real12 atoms = 0 @@ -531,7 +525,7 @@ function get_shortest_bond(lat,bas) result(bond) do ja=ja_start,bas%spec(js)%num vec = bas%spec(is)%atom(ia,:3) - bas%spec(js)%atom(ja,:3) vec = vec - ceiling(vec - 0.5_real12) - vec = matmul(vec,lat) + vec = matmul(vec,bas%lat) dist = modu(vec) if(dist.lt.min_bond)then min_bond = dist @@ -560,11 +554,10 @@ end function get_shortest_bond !!!############################################################################# !!! get the neighbour fingerprint !!!############################################################################# - function get_neighbour_fingerprint(loc,lat,bas,cutoff,nbins,width) & + function get_neighbour_fingerprint(loc,bas,cutoff,nbins,width) & result(fingerprint) implicit none real(real12), dimension(3), intent(in) :: loc - real(real12), dimension(3,3), intent(in) :: lat type(bas_type), intent(in) :: bas integer, intent(in), optional :: nbins @@ -604,9 +597,9 @@ function get_neighbour_fingerprint(loc,lat,bas,cutoff,nbins,width) & !! this is not perfect !! won't work for extremely acute/obtuse angle cells !! (due to diagonal path being shorter than individual lattice vectors) - amax = ceiling(cutoff_/modu(lat(1,:))) - bmax = ceiling(cutoff_/modu(lat(2,:))) - cmax = ceiling(cutoff_/modu(lat(3,:))) + amax = ceiling(cutoff_/modu(bas%lat(1,:))) + bmax = ceiling(cutoff_/modu(bas%lat(2,:))) + cmax = ceiling(cutoff_/modu(bas%lat(3,:))) spec_loop: do is=1,bas%nspec atom_loop: do ia=1,bas%spec(is)%num @@ -618,7 +611,7 @@ function get_neighbour_fingerprint(loc,lat,bas,cutoff,nbins,width) & vtmp1(2) = diff(2) + real(j) do k=-cmax,cmax+1,1 vtmp1(3) = diff(3) + real(k) - dtmp1 = modu(matmul(vtmp1,lat)) + dtmp1 = modu(matmul(vtmp1,bas%lat)) if(dtmp1.lt.cutoff_ + width_/2._real12)then bin = nint(nbins_ * ( dtmp1 + width_/2._real12 ) / cutoff_) if(bin.gt.nbins_) cycle @@ -637,7 +630,7 @@ end function get_neighbour_fingerprint !!!############################################################################# !!! get the list of nearest neighbours !!!############################################################################# - function get_nearest_neighbours_atom(lat,bas,is,ia,max,cutoff) result(neighbour) + function get_nearest_neighbours_atom(bas,is,ia,max,cutoff) result(neighbour) implicit none integer :: i,j,k integer :: js,ja,dim,nneigh,natom,loc @@ -648,7 +641,6 @@ function get_nearest_neighbours_atom(lat,bas,is,ia,max,cutoff) result(neighbour) real(real12), allocatable, dimension(:) :: sep_list integer, intent(in) :: is,ia - real(real12), dimension(3,3), intent(in) :: lat type(bas_type), intent(in) :: bas integer, intent(in), optional :: max real(real12), intent(in), optional :: cutoff @@ -661,7 +653,7 @@ function get_nearest_neighbours_atom(lat,bas,is,ia,max,cutoff) result(neighbour) tol = 6._real12 end if !! define these based on tol val - !! ... i.e. modu(lat(1,:)) compare to tol + !! ... i.e. modu(bas%lat(1,:)) compare to tol amax = 1 bmax = 1 cmax = 1 @@ -682,7 +674,7 @@ function get_nearest_neighbours_atom(lat,bas,is,ia,max,cutoff) result(neighbour) vtmp1(2) = diff(2) + real(j) do k=-cmax,cmax,1 vtmp1(3) = diff(3) + real(k) - dtmp1 = modu(matmul(vtmp1,lat)) + dtmp1 = modu(matmul(vtmp1,bas%lat)) if(dtmp1.le.tol)then nneigh = nneigh + 1 atom_list(nneigh,:2) = [js,ja] @@ -721,13 +713,12 @@ end function get_nearest_neighbours_atom !!!############################################################################# !!! get the list of nearest neighbours !!!############################################################################# - function get_nearest_neighbours_basis(lat,bas,max,cutoff) result(neighbour_table) + function get_nearest_neighbours_basis(bas,max,cutoff) result(neighbour_table) implicit none integer :: is,ia integer :: nmax real(real12) :: tol - real(real12), dimension(3,3), intent(in) :: lat type(bas_type), intent(in) :: bas integer, intent(in), optional :: max real(real12), intent(in), optional :: cutoff @@ -754,7 +745,7 @@ function get_nearest_neighbours_basis(lat,bas,max,cutoff) result(neighbour_table allocate(neighbour_table(is)%atom(bas%spec(is)%num)) do ia=1,bas%spec(is)%num neighbour_table(is)%atom(ia) = & - get_nearest_neighbours_atom(lat,bas,is,ia,nmax,tol) + get_nearest_neighbours_atom(bas,is,ia,nmax,tol) end do end do @@ -774,11 +765,10 @@ end function get_nearest_neighbours_basis !!! 2-body gvector radial descriptor !!!############################################################################# !!! Implementation follows original Behler and Parrinello paper - pure function get_gvector_2body(lat, bas, species_1, species_2, & + pure function get_gvector_2body(bas, species_1, species_2, & cutoff, nbins, width) & result(gvector) implicit none - real(real12), dimension(3,3), intent(in) :: lat type(bas_type), intent(in) :: bas integer, intent(in), optional :: nbins @@ -849,9 +839,9 @@ pure function get_gvector_2body(lat, bas, species_1, species_2, & !! this is not perfect !! won't work for extremely acute/obtuse angle cells !! (due to diagonal path being shorter than individual lattice vectors) - amax = ceiling(cutoff_/modu(lat(1,:))) - bmax = ceiling(cutoff_/modu(lat(2,:))) - cmax = ceiling(cutoff_/modu(lat(3,:))) + amax = ceiling(cutoff_/modu(bas%lat(1,:))) + bmax = ceiling(cutoff_/modu(bas%lat(2,:))) + cmax = ceiling(cutoff_/modu(bas%lat(3,:))) allocate(bond_list(0)) !if doesn't work, allocate a dummy bond first spec_loop1: do is=1,bas%nspec @@ -869,7 +859,7 @@ pure function get_gvector_2body(lat, bas, species_1, species_2, & vtmp1(2) = diff(2) + real(j) do k=-cmax,cmax+1,1 vtmp1(3) = diff(3) + real(k) - rtmp1 = modu(matmul(vtmp1,lat)) + rtmp1 = modu(matmul(vtmp1,bas%lat)) if(rtmp1.lt.cutoff_ + width_/2._real12)then bond_list = [ bond_list, bond_type([is,js],rtmp1) ] end if @@ -926,11 +916,10 @@ pure function get_gvector_2body(lat, bas, species_1, species_2, & end function get_gvector_2body !!!----------------------------------------------------------------------------- - pure function get_gvector_2body_alt(lat, bas, species_1, species_2, & + pure function get_gvector_2body_alt(bas, species_1, species_2, & cutoff, nbins, width) & result(gvector) implicit none - real(real12), dimension(3,3), intent(in) :: lat type(bas_type), intent(in) :: bas integer, intent(in), optional :: nbins @@ -986,9 +975,9 @@ pure function get_gvector_2body_alt(lat, bas, species_1, species_2, & !! this is not perfect !! won't work for extremely acute/obtuse angle cells !! (due to diagonal path being shorter than individual lattice vectors) - amax = ceiling(cutoff_/modu(lat(1,:))) - bmax = ceiling(cutoff_/modu(lat(2,:))) - cmax = ceiling(cutoff_/modu(lat(3,:))) + amax = ceiling(cutoff_/modu(bas%lat(1,:))) + bmax = ceiling(cutoff_/modu(bas%lat(2,:))) + cmax = ceiling(cutoff_/modu(bas%lat(3,:))) allocate(bond_list(0)) !if doesn't work, allocate a dummy bond first atom_loop1: do ia=1,bas%spec(species_1_num)%num @@ -1003,7 +992,7 @@ pure function get_gvector_2body_alt(lat, bas, species_1, species_2, & vtmp1(2) = diff(2) + real(j) do k=-cmax,cmax+1,1 vtmp1(3) = diff(3) + real(k) - rtmp1 = modu(matmul(vtmp1,lat)) + rtmp1 = modu(matmul(vtmp1,bas%lat)) if(rtmp1.lt.cutoff_ + width_/2._real12)then bond_list = [ bond_list, rtmp1 ] end if @@ -1054,12 +1043,11 @@ end function get_gvector_2body_alt !!!############################################################################# !!! implemented as is done by Bircher et al. in their 2021 paper !!! https://doi.org/10.1088/2632-2153/abf817 - pure function get_gvector_3body(lat, bas, species_1, x_min, x_max, & + pure function get_gvector_3body(bas, species_1, x_min, x_max, & theta_min, theta_max, & nbins, width) & result(gvector) implicit none - real(real12), dimension(3,3), intent(in) :: lat type(bas_type), intent(in) :: bas integer, intent(in), optional :: nbins @@ -1119,9 +1107,9 @@ pure function get_gvector_3body(lat, bas, species_1, x_min, x_max, & !! this is not perfect !! won't work for extremely acute/obtuse angle cells !! (due to diagonal path being shorter than individual lattice vectors) - amax = ceiling(cutoff/modu(lat(1,:))) - bmax = ceiling(cutoff/modu(lat(2,:))) - cmax = ceiling(cutoff/modu(lat(3,:))) + amax = ceiling(cutoff/modu(bas%lat(1,:))) + bmax = ceiling(cutoff/modu(bas%lat(2,:))) + cmax = ceiling(cutoff/modu(bas%lat(3,:))) atom_loop1: do ia=1,bas%spec(is)%num allocate(bond_list(0)) @@ -1136,7 +1124,7 @@ pure function get_gvector_3body(lat, bas, species_1, x_min, x_max, & vtmp1(2) = diff(2) + real(j) do k=-cmax,cmax+1,1 vtmp1(3) = diff(3) + real(k) - vector = matmul(vtmp1,lat) + vector = matmul(vtmp1,bas%lat) rtmp1 = modu(vector) if(rtmp1.lt.x_min.or.rtmp1.gt.x_max) cycle bond_list = [ bond_list, bond_type(vector) ] @@ -1275,7 +1263,7 @@ end subroutine shift_region !!! Adjusts the amount of vacuum at a location ... !!! ... within a cell and adjusts the basis accordingly !!!############################################################################# - subroutine vacuumer(lat,bas,axis,loc,add,otol) + subroutine vacuumer(bas,axis,loc,add,otol) implicit none integer :: is,ia integer, intent(in) :: axis @@ -1284,23 +1272,22 @@ subroutine vacuumer(lat,bas,axis,loc,add,otol) real(real12), intent(in) :: add,loc type(bas_type) :: bas real(real12), optional :: otol - real(real12),dimension(3,3) :: lat tol=1.E-5 inc=add if(present(otol)) tol=otol cur_vac=min_dist(bas,axis,loc,.true.)-min_dist(bas,axis,loc,.false.) - cur_vac=cur_vac*modu(lat(axis,:)) + cur_vac=cur_vac*modu(bas%lat(axis,:)) diff=cur_vac+inc if(diff.lt.0._real12)then write(0,*) "WARNING! Removing vacuum entirely" end if - mag_old=modu(lat(axis,:)) + mag_old=modu(bas%lat(axis,:)) mag_new=(mag_old+inc)/mag_old - lat(axis,:)=lat(axis,:)*mag_new - inc=inc/modu(lat(axis,:)) + bas%lat(axis,:)=bas%lat(axis,:)*mag_new + inc=inc/modu(bas%lat(axis,:)) tol=tol/mag_old tloc=loc/mag_new+tol @@ -1323,7 +1310,7 @@ end subroutine vacuumer !!! Adjusts the amount of vacuum at a location ... !!! ... within a cell and adjusts the basis accordingly !!!############################################################################# - subroutine set_vacuum(lat,bas,axis,loc,vac,otol) + subroutine set_vacuum(bas,axis,loc,vac,otol) implicit none integer :: is,ia integer, intent(in) :: axis @@ -1332,7 +1319,6 @@ subroutine set_vacuum(lat,bas,axis,loc,vac,otol) real(real12), intent(in) :: vac,loc type(bas_type) :: bas real(real12), optional :: otol - real(real12),dimension(3,3) :: lat tol=0._real12 @@ -1341,13 +1327,13 @@ subroutine set_vacuum(lat,bas,axis,loc,vac,otol) write(0,*) "WARNING! Removing vacuum entirely" end if cur_vac=min_dist(bas,axis,loc,.true.)-min_dist(bas,axis,loc,.false.) - cur_vac=cur_vac*modu(lat(axis,:)) + cur_vac=cur_vac*modu(bas%lat(axis,:)) diff=vac-cur_vac - mag_old=modu(lat(axis,:)) + mag_old=modu(bas%lat(axis,:)) mag_new=(mag_old+diff)/mag_old - lat(axis,:)=lat(axis,:)*mag_new - diff=diff/modu(lat(axis,:)) + bas%lat(axis,:)=bas%lat(axis,:)*mag_new + diff=diff/modu(bas%lat(axis,:)) tol=tol/mag_old tloc=loc/mag_new+tol @@ -1371,26 +1357,26 @@ end subroutine set_vacuum !!! Takes a lattice and makes the define axis orthogonal to the other two !!! WARNING! THIS IS FOR SLAB STRUCTURES! IT REMOVES PERIODICITY ALONG THAT AXIS !!!############################################################################# - subroutine ortho_axis(lat,bas,axis) + subroutine ortho_axis(bas,axis) implicit none integer :: axis real(real12) :: ortho_comp type(bas_type) :: bas integer, dimension(3) :: order real(real12), dimension(3) :: ortho_vec - real(real12), dimension(3,3) :: invlat,lat + real(real12), dimension(3,3) :: invlat - bas=convert_bas(bas,transpose(lat)) + bas=convert_bas(bas,transpose(bas%lat)) order=(/1,2,3/) order=cshift(order,3-axis) - ortho_vec=cross(lat(order(1),:),lat(order(2),:)) - ortho_comp=dot_product(lat(3,:),ortho_vec)/modu(ortho_vec)**2._real12 + ortho_vec=cross(bas%lat(order(1),:),bas%lat(order(2),:)) + ortho_comp=dot_product(bas%lat(3,:),ortho_vec)/modu(ortho_vec)**2._real12 ortho_vec=ortho_vec*ortho_comp - lat(3,:)=ortho_vec - invlat=inverse_3x3(lat) + bas%lat(3,:)=ortho_vec + invlat=inverse_3x3(bas%lat) bas=convert_bas(bas,transpose(invlat)) @@ -1403,7 +1389,7 @@ end subroutine ortho_axis !!! Applies a transformation matrix to a lattice ... !!! ... and extends the basis where needed !!!############################################################################# - subroutine transformer(lat,bas,tfmat,map) + subroutine transformer(bas,tfmat,map) implicit none integer :: i,j,k,l,m,n,is,ia integer :: satom,dim @@ -1415,22 +1401,22 @@ subroutine transformer(lat,bas,tfmat,map) integer, allocatable, dimension(:) :: tmp_map_atom integer, allocatable, dimension(:,:,:) :: new_map real(real12), allocatable, dimension(:,:) :: tmpbas - real(real12), dimension(3,3) :: lat,slat,tfmat,invmat + real(real12), dimension(3,3) :: slat,tfmat,invmat integer, allocatable, dimension(:,:,:), optional, intent(inout) :: map - vol_inc = abs(det(lat)) + vol_inc = abs(det(bas%lat)) if(vol_inc.lt.0.5_real12)then write(0,'(1X,"ERROR: Internal error in transformer function")') write(0,'(2X,"transformer in mod_edit_geom.f90 been supplied a& & lattice with almost zero determinant")') write(0,'(2X,"determinant = ",F0.9)') vol_inc - write(0,'(3(1X,F7.2))') lat + write(0,'(3(1X,F7.2))') bas%lat stop end if call normalise_basis(bas,1._real12,lfloor=.true.,lround=.false.) vol_inc=abs(det(tfmat)) - slat=matmul(tfmat,lat) + slat=matmul(tfmat,bas%lat) invmat=inverse_3x3(tfmat) translvec=0._real12 dim=size(bas%spec(1)%atom(1,:)) @@ -1528,6 +1514,7 @@ subroutine transformer(lat,bas,tfmat,map) sbas%sysname=bas%sysname sbas%nspec=0 sbas%natom=0 + sbas%lat = slat spec_loop1: do is=1,bas%nspec if(allocated(tmpbas)) deallocate(tmpbas) allocate(tmpbas(bas%spec(is)%num*(& @@ -1604,7 +1591,7 @@ subroutine transformer(lat,bas,tfmat,map) write(0,*) bas%natom,nint(vol_inc) write(0,'(3(1X,F7.2))') tfmat open(60,file="broken_cell.vasp") - call geom_write(60,slat,sbas) + call geom_write(60,sbas) close(60) stop end if @@ -1614,7 +1601,7 @@ subroutine transformer(lat,bas,tfmat,map) !!-------------------------------------------------------------------------- !! saves new lattice and basis to original set !!-------------------------------------------------------------------------- - lat=slat + bas%lat=slat deallocate(bas%spec) allocate(bas%spec(sbas%nspec)) bas%sysname=sbas%sysname @@ -1658,12 +1645,12 @@ end function change_basis !!!############################################################################# !!! rotates a region along an axis about that axis !!!############################################################################# - subroutine region_rot(bas,lat,angle,axis,bound1,bound2,tvec) + subroutine region_rot(bas,angle,axis,bound1,bound2,tvec) implicit none integer :: axis,i,j real(real12) :: angle,bound1,bound2 real(real12), dimension(3) :: u,centre - real(real12), dimension(3,3) :: rotmat,ident,lat,invlat + real(real12), dimension(3,3) :: rotmat,ident,invlat type(bas_type) :: bas real(real12), optional, dimension(3) :: tvec @@ -1684,8 +1671,8 @@ subroutine region_rot(bas,lat,angle,axis,bound1,bound2,tvec) !!! Transform the rotation matrix into direct space - invlat=LUinv(lat) - rotmat=matmul(lat,rotmat) + invlat=LUinv(bas%lat) + rotmat=matmul(bas%lat,rotmat) rotmat=matmul(rotmat,invlat) @@ -1890,11 +1877,11 @@ end function primitive_lat !!!############################################################################# !!! Uses Buerger's algorithm to reduce cell. !!!############################################################################# - subroutine reducer(lat,bas,tmptype,ltmp) + subroutine reducer(bas,tmptype,ltmp) implicit none integer :: cell_type integer :: i,j,k,count,limit - real(real12), dimension(3,3) :: lat,newlat,transmat,S,tmp_mat + real(real12), dimension(3,3) :: newlat,transmat,S,tmp_mat real(real12) :: tiny,pi,pi2 logical :: verb,lreduced integer, optional :: tmptype @@ -1914,14 +1901,14 @@ subroutine reducer(lat,bas,tmptype,ltmp) count=0 limit=100 lreduced=.false. - tiny=1E-5*(get_vol(lat))**(1.E0/3.E0) + tiny=1E-5*(get_vol(bas%lat))**(1.E0/3.E0) pi=4._real12*atan(1._real12) pi2=2._real12*atan(1._real12) transmat=0._real12 do i=1,3 transmat(i,i)=1._real12 end do - newlat=lat + newlat=bas%lat !!!----------------------------------------------------------------------------- @@ -1929,7 +1916,7 @@ subroutine reducer(lat,bas,tmptype,ltmp) !!!----------------------------------------------------------------------------- find_reduced: do while(.not.lreduced) count=count+1 - call mkNiggli_lat(lat,newlat,transmat,S) + call mkNiggli_lat(bas%lat,newlat,transmat,S) lreduced=reduced_check(newlat,cell_type,S) if(lreduced) exit if(verb) then @@ -1953,7 +1940,7 @@ subroutine reducer(lat,bas,tmptype,ltmp) call swap(transmat(i,:),transmat(j,:)) transmat=-transmat if(i.eq.2) cycle find_reduced - call mkNiggli_lat(lat,newlat,transmat,S) + call mkNiggli_lat(bas%lat,newlat,transmat,S) end if end do @@ -1966,7 +1953,7 @@ subroutine reducer(lat,bas,tmptype,ltmp) if(i*j*k.gt.0) then tmp_mat=reshape((/i,0,0, 0,j,0, 0,0,k/),shape(tmp_mat)) transmat=matmul(transpose(tmp_mat),transmat) - call mkNiggli_lat(lat,newlat,transmat,S) + call mkNiggli_lat(bas%lat,newlat,transmat,S) end if @@ -1978,7 +1965,7 @@ subroutine reducer(lat,bas,tmptype,ltmp) if(i*j*k.gt.0) then tmp_mat=reshape((/i,0,0, 0,j,0, 0,0,k/),shape(tmp_mat)) transmat=matmul(transpose(tmp_mat),transmat) - call mkNiggli_lat(lat,newlat,transmat,S) + call mkNiggli_lat(bas%lat,newlat,transmat,S) end if @@ -2046,7 +2033,7 @@ subroutine reducer(lat,bas,tmptype,ltmp) tmp_mat=reshape((/-1,0,0, 0,-1,0, 0,0,-1/),shape(tmp_mat)) transmat=matmul(transpose(tmp_mat),transmat) end if - call mkNiggli_lat(lat,newlat,transmat,S) + call mkNiggli_lat(bas%lat,newlat,transmat,S) lreduced=reduced_check(newlat,cell_type,S,"n") if(verb) then write(67,*) lreduced @@ -2057,7 +2044,7 @@ subroutine reducer(lat,bas,tmptype,ltmp) !!!----------------------------------------------------------------------------- !!! Renormalises the lattice and basis into the new lattice !!!----------------------------------------------------------------------------- - lat=newlat + bas%lat=newlat do i=1,bas%nspec do j=1,bas%spec(i)%num bas%spec(i)%atom(j,:3)=& @@ -2442,7 +2429,7 @@ end function bas_merge !!! merges two supplied bases and lattices !!! Does so by stitching one onto the top of the other !!!############################################################################# - subroutine bas_lat_merge(merglat,mergbas,inlat1,inlat2,inbas1,inbas2,axis,inoffset,map1,map2) + subroutine bas_lat_merge(mergbas,inbas1,inbas2,axis,inoffset,map1,map2) implicit none integer :: i,k,axis real(real12) :: c1_ratio,c2_ratio,add,loc,zgap @@ -2451,8 +2438,7 @@ subroutine bas_lat_merge(merglat,mergbas,inlat1,inlat2,inbas1,inbas2,axis,inoffs integer, dimension(3) :: order real(real12), dimension(3) :: unit_vec,offset real(real12), dimension(3), intent(in) :: inoffset - real(real12), dimension(3,3) :: merglat,lat1,lat2 - real(real12), dimension(3,3), intent(in) :: inlat1,inlat2 + real(real12), dimension(3,3) :: merglat integer, allocatable, dimension(:,:,:), optional, intent(inout) :: map1,map2 @@ -2464,18 +2450,18 @@ subroutine bas_lat_merge(merglat,mergbas,inlat1,inlat2,inbas1,inbas2,axis,inoffs deallocate(mergbas%spec) end if - call clone_bas(inbas1,bas1,inlat1,lat1) - call clone_bas(inbas2,bas2,inlat2,lat2) + call clone_bas(inbas1,bas1) + call clone_bas(inbas2,bas2) !!!----------------------------------------------------------------------------- !!! Shifts cells to !!!----------------------------------------------------------------------------- loc=0._real12 - lat1=MATNORM(lat1) + bas1%lat=MATNORM(bas1%lat) add=-min_dist(bas1,axis,loc,.true.) call shifter(bas1,axis,add,.true.) add=-min_dist(bas2,axis,loc,.true.) - lat2=MATNORM(lat2) + bas2%lat=MATNORM(bas2%lat) call shifter(bas2,axis,add,.true.) @@ -2483,36 +2469,36 @@ subroutine bas_lat_merge(merglat,mergbas,inlat1,inlat2,inbas1,inbas2,axis,inoffs !!! reduces vacuum between materials to desired sizes !!!----------------------------------------------------------------------------- loc=1._real12 - call set_vacuum(lat1,bas1,axis,loc,offset(axis)) - call set_vacuum(lat2,bas2,axis,loc,offset(axis)) + call set_vacuum(bas1,axis,loc,offset(axis)) + call set_vacuum(bas2,axis,loc,offset(axis)) order=(/1,2,3/) order=cshift(order,3-axis) do k=1,2 - offset(order(k))=offset(order(k))/modu(lat1(order(k),:)) + offset(order(k))=offset(order(k))/modu(bas1%lat(order(k),:)) end do - unit_vec=uvec(lat1(order(3),:)) + unit_vec=uvec(bas1%lat(order(3),:)) zgap=offset(order(3))/unit_vec(order(3)) !!NOT SET UP OFFSET FEATURE MADE ABOVE!!! MIGHT BE FIXED NOW! NEED TO TEST !loc=1._real12 - !add=zgap+min_dist(bas1,axis,loc)*modu(lat1(axis,:)) - !call vacuumer(lat1,bas1,axis,loc,add) + !add=zgap+min_dist(bas1,axis,loc)*modu(bas1%lat(axis,:)) + !call vacuumer(bas1,axis,loc,add) - !add=zgap+min_dist(bas2,axis,loc)*modu(lat2(axis,:)) - !call vacuumer(lat2,bas2,axis,loc,add) + !add=zgap+min_dist(bas2,axis,loc)*modu(bas2%lat(axis,:)) + !call vacuumer(bas2,axis,loc,add) !!!----------------------------------------------------------------------------- !!! makes supercell !!!----------------------------------------------------------------------------- - merglat(order(1),:)=lat1(order(1),:) - merglat(order(2),:)=lat1(order(2),:) - unit_vec=uvec(lat1(axis,:)) + merglat(order(1),:)=bas1%lat(order(1),:) + merglat(order(2),:)=bas1%lat(order(2),:) + unit_vec=uvec(bas1%lat(axis,:)) ! slat(axis,:)=lat1(axis,:) + ( modu(lat2(axis,:)) + zgap/unit_vec(axis) )*unit_vec - merglat(axis,:)=lat1(axis,:) + modu(lat2(axis,:))*unit_vec - c1_ratio=modu(lat1(axis,:))/modu(merglat(axis,:)) - c2_ratio=modu(lat2(axis,:))/modu(merglat(axis,:)) + merglat(axis,:)=bas1%lat(axis,:) + modu(bas2%lat(axis,:))*unit_vec + c1_ratio=modu(bas1%lat(axis,:))/modu(merglat(axis,:)) + c2_ratio=modu(bas2%lat(axis,:))/modu(merglat(axis,:)) !!!----------------------------------------------------------------------------- @@ -2533,6 +2519,7 @@ subroutine bas_lat_merge(merglat,mergbas,inlat1,inlat2,inbas1,inbas2,axis,inoffs else mergbas=bas_merge(bas1,bas2) end if + mergbas%lat=merglat call normalise_basis(mergbas,1._real12,.true.) @@ -2672,7 +2659,7 @@ end function split_bas !!!############################################################################# !!! returns the bulk basis and lattice of !!!############################################################################# - subroutine get_bulk(lat,bas,axis,bulk_lat,bulk_bas) + subroutine get_bulk(bas,axis,bulk_bas) implicit none integer :: is,ia,ja,len,itmp1 integer :: minspecloc,minatomloc,nxtatomloc @@ -2684,9 +2671,7 @@ subroutine get_bulk(lat,bas,axis,bulk_lat,bulk_bas) integer, intent(in) :: axis type(bas_type), intent(in) :: bas - real(real12), dimension(3,3), intent(in):: lat type(bas_type), intent(out) :: bulk_bas - real(real12), dimension(3,3), intent(out) :: bulk_lat minspecloc = minloc(bas%spec(:)%num,mask=bas%spec(:)%num.ne.0,dim=1) @@ -2767,11 +2752,11 @@ subroutine get_bulk(lat,bas,axis,bulk_lat,bulk_bas) bulk_bas%sysname=bas%sysname - bulk_lat = lat - bulk_lat(axis,:) = matmul(transvec,lat) + bulk_bas%lat = bas%lat + bulk_bas%lat(axis,:) = matmul(transvec,bas%lat) - tf=matmul(inverse(bulk_lat),lat) + tf=matmul(inverse(bulk_bas%lat),bas%lat) write(0,*) tf call clone_bas(splitbas(1),bulk_bas) bulk_bas = convert_bas(splitbas(1),tf) @@ -2876,14 +2861,13 @@ function get_closest_atom_1D(bas,axis,loc,species,above,below) result(atom) end function get_closest_atom_1D !!!----------------------------------------------------- !!!----------------------------------------------------- - function get_closest_atom_3D(lat,bas,loc,species) result(atom) + function get_closest_atom_3D(bas,loc,species) result(atom) implicit none integer :: is,ia integer :: is_start,is_end real(real12) :: dtmp1,dtmp2 real(real12), dimension(3) :: vtmp1 real(real12), dimension(3), intent(in) :: loc - real(real12), dimension(3,3), intent(in) :: lat integer, dimension(2) :: atom type(bas_type), intent(in) :: bas @@ -2904,7 +2888,7 @@ function get_closest_atom_3D(lat,bas,loc,species) result(atom) atom_loop1: do ia=1,bas%spec(is)%num vtmp1 = bas%spec(is)%atom(ia,:) - loc vtmp1 = vtmp1 - ceiling(vtmp1 - 0.5_real12) - vtmp1 = matmul(vtmp1,lat) + vtmp1 = matmul(vtmp1,bas%lat) dtmp2 = modu(vtmp1) if(dtmp2.lt.dtmp1)then dtmp1=dtmp2 @@ -2921,7 +2905,7 @@ end function get_closest_atom_3D !!!############################################################################# !!! returns the largest vacumm gap in the cell along a specified axis !!!############################################################################# - function get_largest_gap(lat,bas,axis,tol,return_lower) result(gap) + function get_largest_gap(bas,axis,tol,return_lower) result(gap) implicit none integer :: i,init,iloc real(real12) :: dtmp1,max_sep,tol_ @@ -2931,7 +2915,6 @@ function get_largest_gap(lat,bas,axis,tol,return_lower) result(gap) integer, intent(in) :: axis type(bas_type), intent(in) :: bas - real(real12), dimension(3,3), intent(in) :: lat real(real12), optional, intent(in) :: tol logical, optional, intent(in) :: return_lower diff --git a/src/lib/mod_evolver.f90 b/src/lib/mod_evolver.f90 index f630c414..da82cb91 100644 --- a/src/lib/mod_evolver.f90 +++ b/src/lib/mod_evolver.f90 @@ -188,7 +188,7 @@ subroutine set_cutoff_max(this, cutoff_max) end subroutine set_cutoff_max - subroutine create(this, basis_list, lattice_list) + subroutine create(this, basis_list) !! create the distribution functions from the input file implicit none ! Arguments @@ -196,17 +196,15 @@ subroutine create(this, basis_list, lattice_list) !! Self, parent of the procedure. type(bas_type), dimension(:), intent(in) :: basis_list !! List of basis structures. - real(real12), dimension(:,:,:), intent(in) :: lattice_list - !! List of lattice vectors for each basis structure. deallocate(this%total%df_2body, this%total%df_3body, this%total%df_4body) - call this%add(basis_list, lattice_list) + call this%add(basis_list) call this%evolve() end subroutine create - subroutine update(this, basis_list, lattice_list) + subroutine update(this, basis_list) !! update the distribution functions from the input file implicit none ! Arguments @@ -214,11 +212,9 @@ subroutine update(this, basis_list, lattice_list) !! Self, parent of the procedure. type(bas_type), dimension(:), intent(in) :: basis_list !! List of basis structures. - real(real12), dimension(:,:,:), intent(in) :: lattice_list - !! List of lattice vectors for each basis structure. - call this%add(basis_list, lattice_list) + call this%add(basis_list) call this%evolve() end subroutine update @@ -417,11 +413,10 @@ end subroutine write_4body !!!############################################################################# !!! add system (basis or gvector) to the container !!!############################################################################# - subroutine add(this, system, lattice) + subroutine add(this, system) implicit none class(gvector_container_type), intent(inout) :: this class(*), dimension(..), intent(in) :: system - real(real12), dimension(..), intent(in), optional :: lattice integer :: i, num_structures_previous character(128) :: buffer @@ -433,19 +428,7 @@ subroutine add(this, system, lattice) type is (gvector_type) this%system = [ this%system, system ] type is (bas_type) - if(.not. present(lattice))then - write(0,*) "ERROR: Lattice vectors not provided" - stop 1 - end if - select rank(lattice) - rank(2) - call this%add_basis(lattice(:,:), system) - rank default - write(0,*) "ERROR: Invalid rank for lattice" - write(buffer,*) rank(lattice) - write(0,*) "Expected rank 2, got ", trim(buffer) - stop 1 - end select + call this%add_basis(system) class default write(0,*) "ERROR: Invalid type for system" write(0,*) "Expected type gvector_type or bas_type" @@ -457,25 +440,9 @@ subroutine add(this, system, lattice) type is (gvector_type) this%system = [ this%system, system ] type is (bas_type) - if(.not. present(lattice))then - write(0,*) "ERROR: Lattice vectors not provided" - stop 1 - end if - select rank(lattice) - rank(2) - do i = 1, size(system) - call this%add_basis(lattice(:,:), system(i)) - end do - rank(3) - do i = 1, size(system) - call this%add_basis(lattice(:,:,i), system(i)) - end do - rank default - write(0,*) "ERROR: Invalid rank for lattice" - write(buffer,*) rank(lattice) - write(0,*) "Expected rank 2, got ", trim(buffer) - stop 1 - end select + do i = 1, size(system) + call this%add_basis(system(i)) + end do class default write(0,*) "ERROR: Invalid type for system" write(0,*) "Expected type gvector_type or bas_type" @@ -497,16 +464,15 @@ end subroutine add !!!############################################################################# !!! generate gvectors from basis and add to the container !!!############################################################################# - subroutine add_basis(this, lattice, basis) + subroutine add_basis(this, basis) implicit none class(gvector_container_type), intent(inout) :: this type(bas_type), intent(in) :: basis - real(real12), dimension(3,3), intent(in) :: lattice integer :: i, num_structures_previous type(gvector_type) :: system - call system%calculate(lattice, basis, width = this%width, & + call system%calculate(basis, width = this%width, & sigma = this%sigma, & cutoff_min = this%cutoff_min, & cutoff_max = this%cutoff_max) @@ -892,13 +858,12 @@ end subroutine evolve !!!############################################################################# -!!! calculate the gvectors for a system from its lattice and basis +!!! calculate the gvectors for a system from its basis !!!############################################################################# - subroutine calculate(this, lattice, basis, & + subroutine calculate(this, basis, & nbins, width, sigma, cutoff_min, cutoff_max) implicit none class(gvector_type), intent(inout) :: this - real(real12), dimension(3,3), intent(in) :: lattice type(bas_type), intent(in) :: basis integer, dimension(3), intent(in), optional :: nbins @@ -986,9 +951,9 @@ subroutine calculate(this, lattice, basis, & !! this is not perfect !! won't work for extremely acute/obtuse angle cells !! (due to diagonal path being shorter than individual lattice vectors) - amax = ceiling(cutoff_max_(1)/modu(lattice(1,:))) - bmax = ceiling(cutoff_max_(1)/modu(lattice(2,:))) - cmax = ceiling(cutoff_max_(1)/modu(lattice(3,:))) + amax = ceiling(cutoff_max_(1)/modu(basis%lat(1,:))) + bmax = ceiling(cutoff_max_(1)/modu(basis%lat(2,:))) + cmax = ceiling(cutoff_max_(1)/modu(basis%lat(3,:))) !!-------------------------------------------------------------------------- @@ -998,7 +963,7 @@ subroutine calculate(this, lattice, basis, & !! estimate number of bonds !write(*,*) "estimated number of bonds: ", triangular_number(basis%natom) * & ! ceiling( (pi * 4._real12/3._real12) * & - ! (cutoff_max(1)**3 - cutoff_min(1)**3)/ get_vol(lattice) ) + ! (cutoff_max(1)**3 - cutoff_min(1)**3)/ get_vol(basis%lat) ) allocate(bond_list(0)) !if doesn't work, allocate a dummy bond first spec_loop1: do is=1,basis%nspec @@ -1014,7 +979,7 @@ subroutine calculate(this, lattice, basis, & vtmp1(2) = diff(2) + real(j, real12) do k=-cmax,cmax+1,1 vtmp1(3) = diff(3) + real(k, real12) - rtmp1 = modu(matmul(vtmp1,lattice)) + rtmp1 = modu(matmul(vtmp1,basis%lat)) if( rtmp1 .gt. cutoff_min_(1) - & width_(1)/2._real12 .and. & rtmp1 .lt. cutoff_max_(1) + & @@ -1022,7 +987,7 @@ subroutine calculate(this, lattice, basis, & bond_list = [ bond_list, bond_type( & species=[is,js], & atom=[ia,ja], skip=.false., & - vector=matmul(vtmp1,lattice)) ] + vector=matmul(vtmp1,basis%lat)) ] end if end do end do diff --git a/src/lib/mod_generator.f90 b/src/lib/mod_generator.f90 index b861602f..c6ef07ff 100644 --- a/src/lib/mod_generator.f90 +++ b/src/lib/mod_generator.f90 @@ -189,6 +189,7 @@ subroutine generate(this, num_structures, & allocate(basis_store%spec(i)%atom(basis_store%spec(i)%num,3), source = 0._real12) end do basis_store = bas_merge(this%host,basis_store) + basis_store%lat = this%host%lat !!-------------------------------------------------------------------------- @@ -239,7 +240,7 @@ subroutine generate(this, num_structures, & !!----------------------------------------------------------------------- !! predict energy using ML !!----------------------------------------------------------------------- - graph(1) = get_graph_from_basis(this%host%lat, basis) + graph(1) = get_graph_from_basis(this%structures(i)) write(*,*) "Predicted energy", network_predict_graph(graph(1:1)) #endif @@ -286,7 +287,7 @@ module function generate_structure( & call shuffle(placement_list_shuffled,1) !!! NEED TO SORT OUT RANDOM SEED viable_gridpoints = get_viable_gridpoints( this%bins, & - this%host%lat, basis, & + basis, & [ this%distributions%bond_info(:)%radius_covalent ], & placement_list_shuffled ) @@ -302,13 +303,13 @@ module function generate_structure( & if(rtmp1.le.method_probab_(1)) then if(verbose.gt.0) write(*,*) "Add Atom Void" call add_atom_void( this%bins, & - this%host%lat, basis, & + basis, & placement_list_shuffled(iplaced+1:,:), placed) else if(rtmp1.le.method_probab_(2)) then if(verbose.gt.0) write(*,*) "Add Atom Pseudo" call add_atom_pseudo( this%bins, & this%distributions, & - this%host%lat, basis, & + basis, & placement_list_shuffled(iplaced+1:,:), & [ this%distributions%bond_info(:)%radius_covalent ], & placed ) @@ -317,14 +318,14 @@ module function generate_structure( & if(verbose.gt.0) write(*,*) "Add Atom Scan" call add_atom_scan( viable_gridpoints, & this%distributions, & - this%host%lat, basis, & + basis, & placement_list_shuffled(iplaced+1:,:), & [ this%distributions%bond_info(:)%radius_covalent ], & placed) end if if(.not. placed) then if(void_ticker.gt.10) & - call add_atom_void( this%bins, this%host%lat, basis, & + call add_atom_void( this%bins, basis, & placement_list_shuffled(iplaced+1:,:), placed) void_ticker = 0 if(.not.placed) cycle placement_loop @@ -336,7 +337,7 @@ module function generate_structure( & iplaced = iplaced + 1 if(allocated(viable_gridpoints)) & call update_viable_gridpoints( viable_gridpoints, & - this%host%lat, basis, & + basis, & [ placement_list_shuffled(iplaced,:) ], & this%distributions%bond_info( & ( basis%nspec - & diff --git a/src/lib/mod_read_structures.f90 b/src/lib/mod_read_structures.f90 index 9ea98946..5305a44e 100644 --- a/src/lib/mod_read_structures.f90 +++ b/src/lib/mod_read_structures.f90 @@ -49,7 +49,6 @@ function get_evolved_gvectors_from_data(input_dir, & integer :: xml_unit, unit, ierror integer :: num_files type(bas_type) :: basis - real(real12), dimension(3,3) :: lattice character(256), dimension(:), allocatable :: structure_list #ifdef ENABLE_ATHENA type(graph_type), dimension(:), allocatable :: graphs @@ -121,13 +120,13 @@ function get_evolved_gvectors_from_data(input_dir, & basis%energy = get_energy_from_vasprun(unit, success) if(.not.success) cycle rewind(unit) - call get_structure_from_vasprun(unit, lattice, basis, success) + call get_structure_from_vasprun(unit, basis, success) if(.not.success) cycle close(unit) case(1) open(newunit=unit, file=trim(adjustl(structure_list(i)))//"/POSCAR") write(*,*) "Reading structures from POSCAR" - call geom_read(unit, lattice, basis) + call geom_read(unit, basis) close(unit) open(newunit=unit, file=trim(adjustl(structure_list(i)))//"/OUTCAR") call grep(unit, 'free energy TOTEN =', lline=.false., success=success) @@ -144,10 +143,10 @@ function get_evolved_gvectors_from_data(input_dir, & if(ierror .ne. 0) exit if(trim(buffer).eq."") cycle backspace(unit) - call geom_read(unit, lattice, basis) + call geom_read(unit, basis) call get_elements_masses_and_charges(basis) #ifdef ENABLE_ATHENA - graphs = [ graphs, get_graph_from_basis(lattice, basis) ] + graphs = [ graphs, get_graph_from_basis(basis) ] labels = [ labels, basis%energy ] #endif @@ -159,7 +158,7 @@ function get_evolved_gvectors_from_data(input_dir, & basis%energy, & ( trim(basis%spec(j)%name), basis%spec(j)%num, & j=1, basis%nspec ) - call gvector_container%add(basis, lattice) + call gvector_container%add(basis) end do cycle end select @@ -167,7 +166,7 @@ function get_evolved_gvectors_from_data(input_dir, & write(*,*) & "Found structure: ", trim(adjustl(structure_list(i))), & " with energy: ", basis%energy - call gvector_container%add(basis, lattice) + call gvector_container%add(basis) num_structures = num_structures + 1 !!! STORE THE ENERGY IN AN ARRAY @@ -264,10 +263,9 @@ end function get_structure_list !!! !!!############################################################################# #ifdef ENABLE_ATHENA - function get_graph_from_basis(lattice, basis) result(graph) + function get_graph_from_basis(basis) result(graph) implicit none type(bas_type), intent(in) :: basis - real(real12), dimension(3,3), intent(in) :: lattice type(graph_type) :: graph integer :: is, ia, js, ja, i, j, k @@ -296,9 +294,9 @@ function get_graph_from_basis(lattice, basis) result(graph) cutoff_min = 0.5_real12 cutoff_max = 6.0_real12 - amax = ceiling(cutoff_max/modu(lattice(1,:))) - bmax = ceiling(cutoff_max/modu(lattice(2,:))) - cmax = ceiling(cutoff_max/modu(lattice(3,:))) + amax = ceiling(cutoff_max/modu(basis%lat(1,:))) + bmax = ceiling(cutoff_max/modu(basis%lat(2,:))) + cmax = ceiling(cutoff_max/modu(basis%lat(3,:))) iatom = 0 allocate(graph%edge(0)) @@ -318,7 +316,7 @@ function get_graph_from_basis(lattice, basis) result(graph) vtmp1(2) = diff(2) + real(j, real12) do k=-cmax,cmax+1,1 vtmp1(3) = diff(3) + real(k, real12) - rtmp1 = modu(matmul(vtmp1,lattice)) + rtmp1 = modu(matmul(vtmp1,basis%lat)) if( rtmp1 .gt. cutoff_min .and. & rtmp1 .lt. cutoff_max )then edge%index = [iatom,jatom] diff --git a/src/lib/mod_rw_geom.f90 b/src/lib/mod_rw_geom.f90 index 6fc48478..1e13d0c8 100644 --- a/src/lib/mod_rw_geom.f90 +++ b/src/lib/mod_rw_geom.f90 @@ -27,7 +27,6 @@ module rw_geom integer :: igeom_input=1,igeom_output=1 - real(real12), dimension(3,3) :: lattice type spec_type real(real12), allocatable ,dimension(:,:) :: atom @@ -48,7 +47,6 @@ module rw_geom contains procedure, pass(this) :: allocate_species end type bas_type - type(bas_type) :: basis @@ -97,39 +95,35 @@ end subroutine allocate_species !!!############################################################################# !!! sets up the name of output files and subroutines to read files !!!############################################################################# - subroutine geom_read(UNIT,lat,bas,length) + subroutine geom_read(UNIT,basis,length) implicit none - integer :: UNIT,dim,i - type(bas_type) :: bas - real(real12), dimension(3,3) :: lat + integer, intent(in) :: UNIT + type(bas_type), intent(out) :: basis integer, optional, intent(in) :: length - lattice=0._real12 + integer :: dim,i + dim=3 if(present(length)) dim=length select case(igeom_input) case(1) - call VASP_geom_read(UNIT,dim) + call VASP_geom_read(UNIT,basis,dim) case(2) - call CASTEP_geom_read(UNIT,dim) + call CASTEP_geom_read(UNIT,basis,dim) case(3) - call QE_geom_read(UNIT,dim) + call QE_geom_read(UNIT,basis,dim) case(4) - !call err_abort('ERROR: ARTEMIS not yet set up for CRYSTAL') - write(0,'("ERROR: ARTEMIS not yet set up for CRYSTAL")') - stop + stop "ERROR: Not yet set up for CRYSTAL" case(5) - call XYZ_geom_read(UNIT,dim) + call XYZ_geom_read(UNIT,basis,dim) write(0,'("WARNING: XYZ file format does not contain lattice data")') case(6) - call extXYZ_geom_read(UNIT,dim) + call extXYZ_geom_read(UNIT,basis,dim) end select - call clone_bas(basis,bas,lattice,lat) - deallocate(basis%spec) if(dim.eq.4)then - do i=1,bas%nspec - bas%spec(i)%atom(:,4)=1._real12 + do i=1,basis%nspec + basis%spec(i)%atom(:,4)=1._real12 end do end if @@ -141,30 +135,28 @@ end subroutine geom_read !!!############################################################################# !!! sets up the name of output files and subroutines to read files !!!############################################################################# - subroutine geom_write(UNIT,lat,bas) + subroutine geom_write(UNIT,basis) implicit none - integer :: UNIT - type(bas_type) :: bas - real(real12), dimension(3,3) :: lat + integer, intent(in) :: UNIT + type(bas_type), intent(in) :: basis !!! MAKE IT CHANGE HERE IF USER SPECIFIES LCART OR NOT !!! AND GIVE IT THE CASTEP AND QE OPTION OF LABC !!! select case(igeom_output) case(1) - call VASP_geom_write(UNIT,lat,bas) + call VASP_geom_write(UNIT,basis) case(2) - call CASTEP_geom_write(UNIT,lat,bas) + call CASTEP_geom_write(UNIT,basis) case(3) - call QE_geom_write(UNIT,lat,bas) + call QE_geom_write(UNIT,basis) case(4) write(0,'("ERROR: ARTEMIS not yet set up for CRYSTAL")') stop - case(5) - write(0,'("ERROR: XYZ format doesn''t need lattice")') - call XYZ_geom_write(UNIT,bas) + case(5) + call XYZ_geom_write(UNIT,basis) case(6) - call extXYZ_geom_write(UNIT,lat,bas) + call extXYZ_geom_write(UNIT,basis) end select @@ -175,14 +167,17 @@ end subroutine geom_write !!!############################################################################# !!! read the POSCAR or CONTCAR file !!!############################################################################# - subroutine VASP_geom_read(UNIT,length) + subroutine VASP_geom_read(UNIT,basis,length) implicit none - integer :: UNIT,pos,count,Reason + integer, intent(in) :: UNIT + type(bas_type), intent(out) :: basis + integer, intent(in), optional :: length + + integer :: pos,count,Reason real(real12) :: scal character(len=100) :: lspec character(len=1024) :: buffer real(real12), dimension(3,3) :: reclat - integer, intent(in), optional :: length integer :: i,j,k,dim @@ -211,9 +206,9 @@ subroutine VASP_geom_read(UNIT,length) !!! read lattice !!!----------------------------------------------------------------------------- do i=1,3 - read(UNIT,*) (lattice(i,j),j=1,3) + read(UNIT,*) (basis%lat(i,j),j=1,3) end do - lattice=scal*lattice + basis%lat=scal*basis%lat !!!----------------------------------------------------------------------------- @@ -273,7 +268,7 @@ subroutine VASP_geom_read(UNIT,length) !!! convert basis if in cartesian coordinates !!!----------------------------------------------------------------------------- if(basis%lcart)then - reclat=transpose(LUinv(lattice))*2._real12*pi + reclat=transpose(LUinv(basis%lat))*2._real12*pi basis=convert_bas(basis,reclat) end if @@ -299,32 +294,33 @@ end subroutine VASP_geom_read !!!############################################################################# !!! writes out the structure in vasp poscar style format !!!############################################################################# - subroutine VASP_geom_write(UNIT,lat_write,bas_write,lcart) + subroutine VASP_geom_write(UNIT,basis,lcart) implicit none - integer :: i,j,UNIT - real(real12), dimension(3,3) :: lat_write - type(bas_type) :: bas_write - character(100) :: fmt,string + integer, intent(in) :: UNIT + type(bas_type), intent(in) :: basis logical, intent(in), optional :: lcart + integer :: i,j + character(100) :: fmt,string + string="Direct" if(present(lcart))then if(lcart) string="Cartesian" end if - write(UNIT,'(A)') trim(adjustl(bas_write%sysname)) + write(UNIT,'(A)') trim(adjustl(basis%sysname)) write(UNIT,'(F15.9)') 1._real12 do i=1,3 - write(UNIT,'(3(F15.9))') lat_write(i,:) + write(UNIT,'(3(F15.9))') basis%lat(i,:) end do - write(fmt,'("(",I0,"(A,1X))")') bas_write%nspec - write(UNIT,trim(adjustl(fmt))) (adjustl(bas_write%spec(j)%name),j=1,bas_write%nspec) - write(fmt,'("(",I0,"(I0,5X))")') bas_write%nspec - write(UNIT,trim(adjustl(fmt))) (bas_write%spec(j)%num,j=1,bas_write%nspec) + write(fmt,'("(",I0,"(A,1X))")') basis%nspec + write(UNIT,trim(adjustl(fmt))) (adjustl(basis%spec(j)%name),j=1,basis%nspec) + write(fmt,'("(",I0,"(I0,5X))")') basis%nspec + write(UNIT,trim(adjustl(fmt))) (basis%spec(j)%num,j=1,basis%nspec) write(UNIT,'(A)') trim(adjustl(string)) - do i=1,bas_write%nspec - do j=1,bas_write%spec(i)%num - write(UNIT,'(3(F15.9))') bas_write%spec(i)%atom(j,1:3) + do i=1,basis%nspec + do j=1,basis%spec(i)%num + write(UNIT,'(3(F15.9))') basis%spec(i)%atom(j,1:3) end do end do @@ -336,11 +332,14 @@ end subroutine VASP_geom_write !!!############################################################################# !!! read the QE geom file !!!############################################################################# - subroutine QE_geom_read(UNIT,length) + subroutine QE_geom_read(UNIT,basis,length) implicit none - integer UNIT,Reason,i,j,k,dim,iline - integer, dimension(1000) :: tmp_natom + integer, intent(in) :: UNIT + type(bas_type), intent(out) :: basis integer, intent(in), optional :: length + + integer Reason,i,j,k,dim,iline + integer, dimension(1000) :: tmp_natom real(real12), dimension(3) :: tmpvec real(real12), dimension(3,3) :: reclat character(len=5) :: ctmp @@ -382,7 +381,7 @@ subroutine QE_geom_read(UNIT,length) end if end do cellparam do i=1,3 - read(UNIT,*) (lattice(i,j),j=1,3) + read(UNIT,*) (basis%lat(i,j),j=1,3) end do @@ -451,7 +450,7 @@ subroutine QE_geom_read(UNIT,length) !!! convert basis if in cartesian coordinates !!!----------------------------------------------------------------------------- if(basis%lcart)then - reclat=transpose(LUinv(lattice))*2._real12*pi + reclat=transpose(LUinv(basis%lat))*2._real12*pi basis=convert_bas(basis,reclat) end if @@ -477,14 +476,15 @@ end subroutine QE_geom_read !!!############################################################################# !!! writes out the structure in QE geom style format !!!############################################################################# - subroutine QE_geom_write(UNIT,lat_write,bas_write,lcart) + subroutine QE_geom_write(UNIT,basis,lcart) implicit none - integer :: i,j,UNIT - real(real12), dimension(3,3) :: lat_write - type(bas_type) :: bas_write - character(10) :: string + integer, intent(in) :: UNIT + type(bas_type), intent(in) :: basis logical, intent(in), optional :: lcart + integer :: i,j + character(10) :: string + string="crystal" if(present(lcart))then if(lcart) string="angstrom" @@ -493,16 +493,17 @@ subroutine QE_geom_write(UNIT,lat_write,bas_write,lcart) write(UNIT,'("CELL_PARAMETERS angstrom")') do i=1,3 - write(UNIT,'(3(F15.9))') lat_write(i,:) + write(UNIT,'(3(F15.9))') basis%lat(i,:) end do write(UNIT,'("ATOMIC_SPECIES")') - do i=1,bas_write%nspec - write(UNIT,'(A)') trim(adjustl(bas_write%spec(i)%name)) + do i=1,basis%nspec + write(UNIT,'(A)') trim(adjustl(basis%spec(i)%name)) end do write(UNIT,'("ATOMIC_POSITIONS",1X,A)') trim(adjustl(string)) - do i=1,bas_write%nspec - do j=1,bas_write%spec(i)%num - write(UNIT,'(A5,1X,3(F15.9))') bas_write%spec(i)%name,bas_write%spec(i)%atom(j,1:3) + do i=1,basis%nspec + do j=1,basis%spec(i)%num + write(UNIT,'(A5,1X,3(F15.9))') & + basis%spec(i)%name,basis%spec(i)%atom(j,1:3) end do end do @@ -514,9 +515,13 @@ end subroutine QE_geom_write !!!############################################################################# !!! reads atoms from an CASTEP file !!!############################################################################# - subroutine CASTEP_geom_read(UNIT,length) + subroutine CASTEP_geom_read(UNIT,basis,length) implicit none - integer :: UNIT,Reason,itmp1 + integer, intent(in) :: UNIT + type(bas_type), intent(out) :: basis + integer, intent(in), optional :: length + + integer :: Reason,itmp1 integer :: i,j,k,dim,iline character(len=5) :: ctmp character(len=20) :: units @@ -526,7 +531,6 @@ subroutine CASTEP_geom_read(UNIT,length) real(real12), dimension(3) :: abc,angle,dvtmp1 real(real12), dimension(3,3) :: reclat character(len=5), dimension(1000) :: tmp_spec - integer, intent(in), optional :: length !!!----------------------------------------------------------------------------- @@ -579,9 +583,9 @@ subroutine CASTEP_geom_read(UNIT,length) if(labc)then read(store,*) units,(abc(i),i=1,3), (angle(j),j=1,3) - lattice=convert_abc_to_lat(abc,angle,.false.) + basis%lat=convert_abc_to_lat(abc,angle,.false.) else - read(store,*) units,(lattice(i,:),i=1,3) + read(store,*) units,(basis%lat(i,:),i=1,3) end if cycle readloop end if lattice_if @@ -645,7 +649,7 @@ subroutine CASTEP_geom_read(UNIT,length) !!! convert basis if in cartesian coordinates !!!----------------------------------------------------------------------------- if(basis%lcart)then - reclat=transpose(LUinv(lattice))*2._real12*pi + reclat=transpose(LUinv(basis%lat))*2._real12*pi basis=convert_bas(basis,reclat) end if @@ -672,12 +676,11 @@ end subroutine CASTEP_geom_read !!!############################################################################# !!! writes lattice and basis in a CASTEP file format !!!############################################################################# - subroutine CASTEP_geom_write(UNIT,lat_write,bas_write,labc,lcart) + subroutine CASTEP_geom_write(UNIT,basis,labc,lcart) implicit none integer :: i,j,UNIT real(real12), dimension(3) :: abc,angle - real(real12), dimension(3,3) :: lat_write - type(bas_type) :: bas_write + type(bas_type) :: basis character(4) :: string_lat,string_bas logical, intent(in), optional :: labc,lcart @@ -703,27 +706,27 @@ subroutine CASTEP_geom_write(UNIT,lat_write,bas_write,labc,lcart) if(present(labc))then if(labc)then do i=1,3 - abc(i)=modu(lat_write(i,:)) + abc(i)=modu(basis%lat(i,:)) end do - angle(1) = dot_product(lat_write(2,:),lat_write(3,:))/(abc(2)*abc(3)) - angle(2) = dot_product(lat_write(1,:),lat_write(3,:))/(abc(1)*abc(3)) - angle(3) = dot_product(lat_write(1,:),lat_write(2,:))/(abc(1)*abc(2)) + angle(1) = dot_product(basis%lat(2,:),basis%lat(3,:))/(abc(2)*abc(3)) + angle(2) = dot_product(basis%lat(1,:),basis%lat(3,:))/(abc(1)*abc(3)) + angle(3) = dot_product(basis%lat(1,:),basis%lat(2,:))/(abc(1)*abc(2)) write(UNIT,'(3(F15.9))') abc write(UNIT,'(3(F15.9))') angle goto 10 end if end if do i=1,3 - write(UNIT,'(3(F15.9))') lat_write(i,:) + write(UNIT,'(3(F15.9))') basis%lat(i,:) end do 10 write(UNIT,'("%endblock LATTICE_",A)') trim(string_lat) write(UNIT,*) write(UNIT,'("%block POSITIONS_",A)') trim(string_bas) - do i=1,bas_write%nspec - do j=1,bas_write%spec(i)%num - write(UNIT,'(A5,1X,3(F15.9))') bas_write%spec(i)%name,bas_write%spec(i)%atom(j,1:3) + do i=1,basis%nspec + do j=1,basis%spec(i)%num + write(UNIT,'(A5,1X,3(F15.9))') basis%spec(i)%name,basis%spec(i)%atom(j,1:3) end do end do write(UNIT,'("%endblock POSITIONS_",A)') trim(string_bas) @@ -736,10 +739,13 @@ end subroutine CASTEP_geom_write !!!############################################################################# !!! reads atoms from an xyz file !!!############################################################################# - subroutine XYZ_geom_read(UNIT,length) + subroutine XYZ_geom_read(UNIT,basis,length) implicit none - integer :: UNIT,Reason + integer, intent(in) :: UNIT + type(bas_type), intent(out) :: basis integer, intent(in), optional :: length + + integer :: Reason integer, allocatable, dimension(:) :: tmp_num real(real12), dimension(3) :: vec real(real12), allocatable, dimension(:,:,:) :: tmp_bas @@ -811,18 +817,20 @@ end subroutine XYZ_geom_read !!!############################################################################# !!! generates cartesian basis !!!############################################################################# - subroutine XYZ_geom_write(UNIT,bas_write) + subroutine XYZ_geom_write(UNIT,basis) implicit none - integer :: i,j,UNIT - type(bas_type) :: bas_write + integer, intent(in) :: UNIT + type(bas_type), intent(in) :: basis + + integer :: i,j - write(UNIT,'("I0")') bas_write%natom - write(UNIT,'("A")') bas_write%sysname - do i=1,bas_write%nspec - do j=1,bas_write%spec(i)%num + write(UNIT,'("I0")') basis%natom + write(UNIT,'("A")') basis%sysname + do i=1,basis%nspec + do j=1,basis%spec(i)%num write(UNIT,'(A5,1X,3(F15.9))') & - bas_write%spec(i)%name,bas_write%spec(i)%atom(j,1:3) + basis%spec(i)%name,basis%spec(i)%atom(j,1:3) end do end do @@ -834,11 +842,14 @@ end subroutine XYZ_geom_write !!!############################################################################# !!! reads lattice and basis from an extended xyz file !!!############################################################################# - subroutine extXYZ_geom_read(UNIT,length) + subroutine extXYZ_geom_read(UNIT,basis,length) implicit none - integer :: UNIT,Reason - integer :: index1, index2 + integer, intent(in) :: UNIT + type(bas_type), intent(out) :: basis integer, intent(in), optional :: length + + integer :: Reason + integer :: index1, index2 integer, allocatable, dimension(:) :: tmp_num real(real12), dimension(3) :: vec real(real12), allocatable, dimension(:,:,:) :: tmp_bas @@ -869,7 +880,7 @@ subroutine extXYZ_geom_read(UNIT,length) end if index1 = index(buffer,'Lattice="') + 9 index2 = index(buffer(index1:),'"') + index1 - 2 - read(buffer(index1:index2),*) ( ( lattice(i,j), j = 1, 3), i = 1, 3) + read(buffer(index1:index2),*) ( ( basis%lat(i,j), j = 1, 3), i = 1, 3) index1 = index(buffer,'free_energy=') + 12 read(buffer(index1:),*) basis%energy @@ -929,30 +940,31 @@ end subroutine extXYZ_geom_read !!!############################################################################# !!! generates cartesian basis !!!############################################################################# - subroutine extXYZ_geom_write(UNIT,lat_write,bas_write) + subroutine extXYZ_geom_write(UNIT,basis) implicit none - integer :: i,j,UNIT - type(bas_type) :: bas_write - real(real12), dimension(3,3) :: lat_write + integer, intent(in) :: UNIT + type(bas_type), intent(in) :: basis + integer :: i,j - write(UNIT,'("I0")') bas_write%natom + + write(UNIT,'("I0")') basis%natom write(UNIT,'(A,8(F0.8,1X),F0.8,A)', advance="no") & - 'Lattice="',((lat_write(i,j),j=1,3),i=1,3),'"' - write(UNIT,'(A,F0.8)', advance="no") ' free_energy=',bas_write%energy + 'Lattice="',((basis%lat(i,j),j=1,3),i=1,3),'"' + write(UNIT,'(A,F0.8)', advance="no") ' free_energy=',basis%energy write(UNIT,'(A)', advance="no") ' pbc="T T T"' - if(bas_write%lcart)then - do i=1,bas_write%nspec - do j=1,bas_write%spec(i)%num + if(basis%lcart)then + do i=1,basis%nspec + do j=1,basis%spec(i)%num write(UNIT,'(A8,3(1X, F16.8))') & - bas_write%spec(i)%name,bas_write%spec(i)%atom(j,1:3) + basis%spec(i)%name,basis%spec(i)%atom(j,1:3) end do end do else - do i=1,bas_write%nspec - do j=1,bas_write%spec(i)%num - write(UNIT,'(A8,3(1X, F16.8))') bas_write%spec(i)%name, & - matmul(bas_write%spec(i)%atom(j,1:3),lat_write) + do i=1,basis%nspec + do j=1,basis%spec(i)%num + write(UNIT,'(A8,3(1X, F16.8))') basis%spec(i)%name, & + matmul(basis%spec(i)%atom(j,1:3),basis%lat) end do end do end if @@ -964,25 +976,25 @@ end subroutine extXYZ_geom_write !!!############################################################################# !!! convert basis using latconv transformation matrix !!!############################################################################# - function convert_bas(inbas,latconv) result(outbas) + function convert_bas(basis,latconv) result(outbas) implicit none + type(bas_type), intent(in) :: basis + real(real12), dimension(3,3), intent(in) :: latconv + integer :: is,ia,dim type(bas_type) :: outbas - type(bas_type), intent(in) :: inbas - real(real12), dimension(3,3), intent(in) :: latconv - - dim=size(inbas%spec(1)%atom(1,:)) - allocate(outbas%spec(inbas%nspec)) - outbas%natom=inbas%natom - outbas%nspec=inbas%nspec - outbas%sysname=inbas%sysname - outbas%lcart=.not.inbas%lcart - do is=1,inbas%nspec - allocate(outbas%spec(is)%atom(inbas%spec(is)%num,dim)) - outbas%spec(is)=inbas%spec(is) - do ia=1,inbas%spec(is)%num + dim=size(basis%spec(1)%atom(1,:)) + allocate(outbas%spec(basis%nspec)) + outbas%natom=basis%natom + outbas%nspec=basis%nspec + outbas%sysname=basis%sysname + outbas%lcart=.not.basis%lcart + do is=1,basis%nspec + allocate(outbas%spec(is)%atom(basis%spec(is)%num,dim)) + outbas%spec(is)=basis%spec(is) + do ia=1,basis%spec(is)%num outbas%spec(is)%atom(ia,1:3)=& matmul(latconv,outbas%spec(is)%atom(ia,1:3)) end do @@ -1065,7 +1077,7 @@ end function convert_lat_to_abc !!!############################################################################# !!! clones basis 1 onto basis 2 !!!############################################################################# - subroutine clone_bas(inbas,outbas,inlat,outlat,trans_dim) + subroutine clone_bas(inbas,outbas,trans_dim) implicit none integer :: i integer :: indim,outdim @@ -1073,7 +1085,6 @@ subroutine clone_bas(inbas,outbas,inlat,outlat,trans_dim) logical :: udef_trans_dim type(bas_type) :: inbas,outbas - real(real12), dimension(3,3), optional :: inlat,outlat logical, optional, intent(in) :: trans_dim @@ -1139,14 +1150,7 @@ subroutine clone_bas(inbas,outbas,inlat,outlat,trans_dim) outbas%lcart = inbas%lcart outbas%sysname = inbas%sysname outbas%energy = inbas%energy - - -!!!----------------------------------------------------------------------------- -!!! clones input lattice to output lattice, if requested -!!!----------------------------------------------------------------------------- - if(present(inlat).and.present(outlat))then - outlat=inlat - end if + outbas%lat = inbas%lat return diff --git a/src/lib/mod_rw_vasprun.f90 b/src/lib/mod_rw_vasprun.f90 index 2d8da057..32f04af6 100644 --- a/src/lib/mod_rw_vasprun.f90 +++ b/src/lib/mod_rw_vasprun.f90 @@ -153,10 +153,9 @@ end function get_energy_from_vasprun !!! then read until but not encountered !!! then read NUMBER NAME MASS VALENCY PSEUDO_NAME - subroutine get_structure_from_vasprun(unit, lattice, basis, found) + subroutine get_structure_from_vasprun(unit, basis, found) implicit none integer, intent(in) :: unit - real(real12), dimension(3,3) :: lattice type(bas_type) :: basis integer :: ierror, i, is, ia @@ -267,7 +266,7 @@ subroutine get_structure_from_vasprun(unit, lattice, basis, found) write(0,*) 'Error reading lattice from vasprun.xml' stop end if - read( line, '(4X,A3,3(1X,F16.8))' ) buffer, lattice(i,:) + read( line, '(4X,A3,3(1X,F16.8))' ) buffer, basis%lat(i,:) end do From 982b820f41b5813cdc3fab783512cff28643a3c4 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Fri, 19 Jul 2024 12:30:38 +0100 Subject: [PATCH 037/293] Add distributions.create wrapper --- edited_autogen_files/f90wrap_mod_evolver.f90 | 27 ++++++++++++++++++++ edited_autogen_files/raffle.py | 17 ++++++++++++ src/lib/mod_evolver.f90 | 4 ++- 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/edited_autogen_files/f90wrap_mod_evolver.f90 b/edited_autogen_files/f90wrap_mod_evolver.f90 index 46baedcd..3c57f6be 100644 --- a/edited_autogen_files/f90wrap_mod_evolver.f90 +++ b/edited_autogen_files/f90wrap_mod_evolver.f90 @@ -624,6 +624,33 @@ subroutine f90wrap_evolver__set_cutoff_max__binding__gvector_container047c(this, call this_ptr%p%set_cutoff_max(cutoff_max=cutoff_max) end subroutine f90wrap_evolver__set_cutoff_max__binding__gvector_container047c +subroutine f90wrap_evolver__create__binding__gvector_container_type(this, basis_list) + use rw_geom, only: bas_type + use evolver, only: gvector_container_type + implicit none + + type gvector_container_type_ptr_type + type(gvector_container_type), pointer :: p => NULL() + end type gvector_container_type_ptr_type + + type bas_type_xnum_array + type(bas_type), dimension(:), allocatable :: items + end type bas_type_xnum_array + + type bas_type_xnum_array_ptr_type + type(bas_type_xnum_array), pointer :: p => NULL() + end type bas_type_xnum_array_ptr_type + type(gvector_container_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + type(bas_type_xnum_array_ptr_type) :: basis_list_ptr + integer, intent(in), dimension(2) :: basis_list + + this_ptr = transfer(this, this_ptr) + basis_list_ptr = transfer(basis_list, basis_list_ptr) + call this_ptr%p%create(basis_list=basis_list_ptr%p%items) +end subroutine f90wrap_evolver__create__binding__gvector_container_type + + subroutine f90wrap_evolver__add_basis__binding__gvector_container_type(this, basis) use rw_geom, only: bas_type use evolver, only: gvector_container_type diff --git a/edited_autogen_files/raffle.py b/edited_autogen_files/raffle.py index d65f6050..963f4cab 100644 --- a/edited_autogen_files/raffle.py +++ b/edited_autogen_files/raffle.py @@ -1109,6 +1109,23 @@ def set_cutoff_max(self, cutoff_max): _raffle.f90wrap_evolver__set_cutoff_max__binding__gvector_container047c(this=self._handle, \ cutoff_max=cutoff_max) + def create(self, basis_list): + """ + create__binding__gvector_container_type(self, basis_list) + + Defined at ../src/lib/mod_evolver.f90 lines \ + 152-162 + + Parameters + ---------- + this : unknown + basis_list : Bas_Type array + + """ + _raffle.f90wrap_evolver__create__binding__gvector_container_type(this=self._handle, \ + basis_list=basis_list._handle) + + def add_basis(self, lattice, basis): """ add_basis__binding__gvector_container_type(self, lattice, basis) diff --git a/src/lib/mod_evolver.f90 b/src/lib/mod_evolver.f90 index da82cb91..bfe0d3cf 100644 --- a/src/lib/mod_evolver.f90 +++ b/src/lib/mod_evolver.f90 @@ -197,7 +197,9 @@ subroutine create(this, basis_list) type(bas_type), dimension(:), intent(in) :: basis_list !! List of basis structures. - deallocate(this%total%df_2body, this%total%df_3body, this%total%df_4body) + if(allocated(this%total%df_2body)) deallocate(this%total%df_2body) + if(allocated(this%total%df_3body)) deallocate(this%total%df_3body) + if(allocated(this%total%df_4body)) deallocate(this%total%df_4body) call this%add(basis_list) call this%evolve() From 45efe11aeb011d501b0b0c833e07fd73e667a6b6 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Fri, 19 Jul 2024 12:30:54 +0100 Subject: [PATCH 038/293] Remove printing and commented sections --- .../f90wrap_mod_generator.f90 | 3 - edited_autogen_files/f90wrap_mod_rw_geom.f90 | 108 ------------------ 2 files changed, 111 deletions(-) diff --git a/edited_autogen_files/f90wrap_mod_generator.f90 b/edited_autogen_files/f90wrap_mod_generator.f90 index 654a5000..87011420 100644 --- a/edited_autogen_files/f90wrap_mod_generator.f90 +++ b/edited_autogen_files/f90wrap_mod_generator.f90 @@ -541,15 +541,12 @@ subroutine f90wrap_generator__generate__binding__rgt( & real(4), intent(in), optional, dimension(n0) :: method_probab integer :: n0 !f2py intent(hide), depend(method_probab) :: n0 = shape(method_probab,0) - write(*,*) "in generate" this_ptr = transfer(this, this_ptr) stoichiometry_ptr = transfer(stoichiometry, stoichiometry_ptr) if(present(method_probab)) then - write(*,*) "method_probab present" call this_ptr%p%generate(num_structures=num_structures, stoichiometry=stoichiometry_ptr%p%items, & method_probab=method_probab) else - write(*,*) "method_probab not present" call this_ptr%p%generate(num_structures=num_structures, stoichiometry=stoichiometry_ptr%p%items) end if end subroutine f90wrap_generator__generate__binding__rgt diff --git a/edited_autogen_files/f90wrap_mod_rw_geom.f90 b/edited_autogen_files/f90wrap_mod_rw_geom.f90 index 57471ed2..c72e6863 100644 --- a/edited_autogen_files/f90wrap_mod_rw_geom.f90 +++ b/edited_autogen_files/f90wrap_mod_rw_geom.f90 @@ -611,8 +611,6 @@ end subroutine f90wrap_rw_geom__bas_type_xnum_array_finalise - - subroutine f90wrap_rw_geom__allocate_species__binding__bas_type( & this, num_species, species_symbols, species_count, atoms, n0, & n1, n2, n3) @@ -645,111 +643,5 @@ subroutine f90wrap_rw_geom__allocate_species__binding__bas_type( & ) end subroutine f90wrap_rw_geom__allocate_species__binding__bas_type -! subroutine f90wrap_rw_geom__geom_read(unit, lat, bas, length) -! use rw_geom, only: geom_read, bas_type -! implicit none - -! type bas_type_ptr_type -! type(bas_type), pointer :: p => NULL() -! end type bas_type_ptr_type -! integer :: unit -! !f2py intent(inout) unit -! real(4), dimension(3,3) :: lat -! !f2py intent(inout) lat -! type(bas_type_ptr_type) :: bas_ptr -! integer, intent(in), dimension(2) :: bas -! integer, optional, intent(in) :: length -! bas_ptr = transfer(bas, bas_ptr) -! call geom_read(UNIT=unit, lat=lat, bas=bas_ptr%p, length=length) -! end subroutine f90wrap_rw_geom__geom_read - -! subroutine f90wrap_rw_geom__geom_write(unit, lat, bas) -! use rw_geom, only: bas_type, geom_write -! implicit none - -! type bas_type_ptr_type -! type(bas_type), pointer :: p => NULL() -! end type bas_type_ptr_type -! integer :: unit -! !f2py intent(inout) unit -! real(4), dimension(3,3) :: lat -! !f2py intent(inout) lat -! type(bas_type_ptr_type) :: bas_ptr -! integer, intent(in), dimension(2) :: bas -! bas_ptr = transfer(bas, bas_ptr) -! call geom_write(UNIT=unit, lat=lat, bas=bas_ptr%p) -! end subroutine f90wrap_rw_geom__geom_write - -! subroutine f90wrap_rw_geom__convert_bas(inbas, ret_outbas, latconv) -! use rw_geom, only: convert_bas, bas_type -! implicit none - -! type bas_type_ptr_type -! type(bas_type), pointer :: p => NULL() -! end type bas_type_ptr_type -! type(bas_type_ptr_type) :: inbas_ptr -! integer, intent(in), dimension(2) :: inbas -! type(bas_type_ptr_type) :: ret_outbas_ptr -! integer, intent(out), dimension(2) :: ret_outbas -! real(4), dimension(3,3), intent(in) :: latconv -! inbas_ptr = transfer(inbas, inbas_ptr) -! allocate(ret_outbas_ptr%p) -! ret_outbas_ptr%p = convert_bas(inbas=inbas_ptr%p, latconv=latconv) -! ret_outbas = transfer(ret_outbas_ptr, ret_outbas) -! end subroutine f90wrap_rw_geom__convert_bas - -! subroutine f90wrap_rw_geom__clone_bas(inbas, outbas, inlat, outlat, trans_dim) -! use rw_geom, only: clone_bas, bas_type -! implicit none - -! type bas_type_ptr_type -! type(bas_type), pointer :: p => NULL() -! end type bas_type_ptr_type -! type(bas_type_ptr_type) :: inbas_ptr -! integer, intent(in), dimension(2) :: inbas -! type(bas_type_ptr_type) :: outbas_ptr -! integer, intent(in), dimension(2) :: outbas -! real(4), dimension(3,3), optional :: inlat -! !f2py intent(inout) inlat -! real(4), dimension(3,3), optional :: outlat -! !f2py intent(inout) outlat -! logical, optional, intent(in) :: trans_dim -! inbas_ptr = transfer(inbas, inbas_ptr) -! outbas_ptr = transfer(outbas, outbas_ptr) -! call clone_bas(inbas=inbas_ptr%p, outbas=outbas_ptr%p, inlat=inlat, outlat=outlat, trans_dim=trans_dim) -! end subroutine f90wrap_rw_geom__clone_bas - -! subroutine f90wrap_rw_geom__get__igeom_input(f90wrap_igeom_input) -! use rw_geom, only: rw_geom_igeom_input => igeom_input -! implicit none -! integer, intent(out) :: f90wrap_igeom_input - -! f90wrap_igeom_input = rw_geom_igeom_input -! end subroutine f90wrap_rw_geom__get__igeom_input - -! subroutine f90wrap_rw_geom__set__igeom_input(f90wrap_igeom_input) -! use rw_geom, only: rw_geom_igeom_input => igeom_input -! implicit none -! integer, intent(in) :: f90wrap_igeom_input - -! rw_geom_igeom_input = f90wrap_igeom_input -! end subroutine f90wrap_rw_geom__set__igeom_input - -! subroutine f90wrap_rw_geom__get__igeom_output(f90wrap_igeom_output) -! use rw_geom, only: rw_geom_igeom_output => igeom_output -! implicit none -! integer, intent(out) :: f90wrap_igeom_output - -! f90wrap_igeom_output = rw_geom_igeom_output -! end subroutine f90wrap_rw_geom__get__igeom_output - -! subroutine f90wrap_rw_geom__set__igeom_output(f90wrap_igeom_output) -! use rw_geom, only: rw_geom_igeom_output => igeom_output -! implicit none -! integer, intent(in) :: f90wrap_igeom_output - -! rw_geom_igeom_output = f90wrap_igeom_output -! end subroutine f90wrap_rw_geom__set__igeom_output - ! End of module rw_geom defined in file ../src/lib/mod_rw_geom.f90 From 201360d3dfc7b2c0d8c5be965c69e0074cf7a070 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Fri, 19 Jul 2024 14:03:12 +0100 Subject: [PATCH 039/293] Handle python null characters --- src/lib/mod_elements.f90 | 4 ++-- src/lib/mod_evolver.f90 | 8 +++++--- src/lib/mod_generator.f90 | 10 ++++++++-- src/lib/mod_misc.f90 | 27 ++++++++++++++++++++++++++- 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/lib/mod_elements.f90 b/src/lib/mod_elements.f90 index 6f6d90a1..e84f3f43 100644 --- a/src/lib/mod_elements.f90 +++ b/src/lib/mod_elements.f90 @@ -42,7 +42,7 @@ subroutine set(this, name) integer :: i do i = 1, size(element_database) - if(element_database(i)%name .eq. name)then + if(trim(element_database(i)%name) .eq. trim(name))then this%name = element_database(i)%name this%mass = element_database(i)%mass this%charge = element_database(i)%charge @@ -51,7 +51,7 @@ subroutine set(this, name) end if end do - write(0,*) 'Element ', name, ' not found in database' + write(0,*) 'Element ', trim(name), ' not found in element database' stop 1 end subroutine set diff --git a/src/lib/mod_evolver.f90 b/src/lib/mod_evolver.f90 index bfe0d3cf..61e89390 100644 --- a/src/lib/mod_evolver.f90 +++ b/src/lib/mod_evolver.f90 @@ -1,6 +1,6 @@ module evolver use constants, only: real12, pi - use misc_raffle, only: set, icount + use misc_raffle, only: set, icount, strip_null use misc_maths, only: lnsum, triangular_number use misc_linalg, only: get_angle, get_vol, cross, modu use rw_geom, only: bas_type @@ -471,7 +471,6 @@ subroutine add_basis(this, basis) class(gvector_container_type), intent(inout) :: this type(bas_type), intent(in) :: basis - integer :: i, num_structures_previous type(gvector_type) :: system call system%calculate(basis, width = this%width, & @@ -930,7 +929,10 @@ subroutine calculate(this, basis, & num_pairs = gamma(real(basis%nspec + 2, real12)) / & ( gamma(real(basis%nspec, real12)) * gamma( 3._real12 ) ) allocate(idx(2,num_pairs)) - this%species = basis%spec(:)%name + allocate(this%species(basis%nspec)) + do is = 1, basis%nspec + this%species(is) = strip_null(basis%spec(is)%name) + end do do is = 1, basis%nspec do js = is, basis%nspec, 1 i = i + 1 diff --git a/src/lib/mod_generator.f90 b/src/lib/mod_generator.f90 index c6ef07ff..40a5f6c8 100644 --- a/src/lib/mod_generator.f90 +++ b/src/lib/mod_generator.f90 @@ -1,5 +1,6 @@ module generator use constants, only: real12 + use misc_raffle, only: strip_null use rw_geom, only: bas_type use evolver, only: gvector_container_type @@ -174,12 +175,15 @@ subroutine generate(this, num_structures, & end if + !!! THINK OF SOME WAY TO HANDLE THE HOST SEPARATELY !!! THAT CAN SIGNIFICANTLY REDUCE DATA USAGE num_insert_species = size(stoichiometry) num_insert_atoms = sum(stoichiometry(:)%num) allocate(basis_store%spec(num_insert_species)) - basis_store%spec(:)%name = stoichiometry(:)%element + do i = 1, size(stoichiometry) + basis_store%spec(i)%name = strip_null(stoichiometry(i)%element) + end do basis_store%spec(:)%num = stoichiometry(:)%num basis_store%natom = num_insert_atoms basis_store%nspec = num_insert_species @@ -204,7 +208,9 @@ subroutine generate(this, num_structures, & spec_loop1: do i = 1, basis_store%nspec success = .false. do j = 1, size(stoichiometry) - if(trim(basis_store%spec(i)%name).eq.trim(stoichiometry(j)%element)) & + if( & + trim(basis_store%spec(i)%name) .eq. & + trim(strip_null(stoichiometry(j)%element))) & success = .true. end do if(.not.success) cycle diff --git a/src/lib/mod_misc.f90 b/src/lib/mod_misc.f90 index 21d0aea6..11e61ea5 100644 --- a/src/lib/mod_misc.f90 +++ b/src/lib/mod_misc.f90 @@ -29,6 +29,7 @@ !!! touch (creates a file if it doesn't exist) !!! to_upper (converts all characters in string to upper case) !!! to_lower (converts all characters in string to lower case) +!!! strip_null (removes null characters from a string) !!!############################################################################# module misc_raffle use constants, only: real12 @@ -45,6 +46,7 @@ module misc_raffle public :: swap, shuffle public :: Icount, readcl, grep, count_occ, flagmaker, loadbar public :: jump, file_check, touch, to_upper, to_lower + public :: strip_null interface alloc @@ -68,7 +70,7 @@ module misc_raffle end interface shuffle -!!!updated 2021/12/08 +!!!updated 2024/07/19 contains @@ -1145,4 +1147,27 @@ function to_lower(buffer) result(lower) end function to_lower !!!##################################################### + +!!!##################################################### +!!! strip null characters from string +!!!##################################################### + function strip_null(buffer) result(stripped) + implicit none + integer :: i + character(*) :: buffer + character(len=len(buffer)) :: stripped + + stripped = "" + do i=1,len(buffer) + if(iachar(buffer(i:i)).ne.0)then + stripped(i:i)=buffer(i:i) + else + exit + end if + end do + + return + end function strip_null + !!!##################################################### + end module misc_raffle From d64c500418e38ba10d8e93703f3e128a1be3fae0 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Fri, 19 Jul 2024 14:26:28 +0100 Subject: [PATCH 040/293] Add bond info call --- src/lib/mod_evolver.f90 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib/mod_evolver.f90 b/src/lib/mod_evolver.f90 index 61e89390..adaa2c71 100644 --- a/src/lib/mod_evolver.f90 +++ b/src/lib/mod_evolver.f90 @@ -201,6 +201,7 @@ subroutine create(this, basis_list) if(allocated(this%total%df_3body)) deallocate(this%total%df_3body) if(allocated(this%total%df_4body)) deallocate(this%total%df_4body) call this%add(basis_list) + call this%set_bond_info() call this%evolve() end subroutine create @@ -217,6 +218,7 @@ subroutine update(this, basis_list) call this%add(basis_list) + call this%set_bond_info() call this%evolve() end subroutine update From 8f69e88109092cb6fc7c090d63404a60d2539793 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Fri, 19 Jul 2024 14:26:39 +0100 Subject: [PATCH 041/293] Fix variable reference --- src/lib/mod_elements.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/mod_elements.f90 b/src/lib/mod_elements.f90 index e84f3f43..233a07de 100644 --- a/src/lib/mod_elements.f90 +++ b/src/lib/mod_elements.f90 @@ -120,7 +120,7 @@ subroutine load_element_bonds(file) !! open file containing element bond data - open(newunit=unit, file=file, status="old") + open(newunit=unit, file=file_, status="old") read(unit, *) buffer if( index(trim(adjustl(buffer)),"#").ne.1 .and. & index(trim(adjustl(buffer)),"element_1").eq.0)then From 0b5a55c88794698afdf829108e25cf8ce2c3e123 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Fri, 19 Jul 2024 14:27:26 +0100 Subject: [PATCH 042/293] Add evolver to f90wrap --- CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f6d0489..ed64adf0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,7 +74,7 @@ set(LIB_FILES mod_rw_vasprun.f90 mod_edit_geom.f90 mod_elements.f90 - mod_evolver.f90 + # mod_evolver.f90 mod_buildmap.f90 mod_atom_adder.f90 mod_read_structures.f90 @@ -82,6 +82,7 @@ set(LIB_FILES set(SPECIAL_LIB_FILES mod_rw_geom.f90 + mod_evolver.f90 mod_generator.f90 # mod_generator_sub.f90 ) @@ -247,7 +248,7 @@ if (BUILD_PYTHON) -m ${PROJECT_NAME} -k ${KIND_MAP} ${F90WRAP_FORTRAN_SRC_FILES} - --only raffle_generator_type stoichiometry_type bas_type: + --only raffle_generator_type stoichiometry_type bas_type gvector_container_type: DEPENDS ${F90WRAP_FORTRAN_SRC_FILES} WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMENT "Generating f90wrap signature file" From 13fc34da486347d6fd5b8627f436319e02b89592 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Fri, 19 Jul 2024 14:45:38 +0100 Subject: [PATCH 043/293] Force deallocation --- src/lib/mod_generator.f90 | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/mod_generator.f90 b/src/lib/mod_generator.f90 index 40a5f6c8..92f7e438 100644 --- a/src/lib/mod_generator.f90 +++ b/src/lib/mod_generator.f90 @@ -360,6 +360,7 @@ module function generate_structure( & end if end do placement_loop + deallocate(viable_gridpoints) end function generate_structure From 919ea5f9a9693c53159d408d42e5cedda852f617 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Fri, 19 Jul 2024 14:52:12 +0100 Subject: [PATCH 044/293] Add file --- edited_autogen_files/f90wrap_raffle.f90 | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 edited_autogen_files/f90wrap_raffle.f90 diff --git a/edited_autogen_files/f90wrap_raffle.f90 b/edited_autogen_files/f90wrap_raffle.f90 new file mode 100644 index 00000000..5272bdc0 --- /dev/null +++ b/edited_autogen_files/f90wrap_raffle.f90 @@ -0,0 +1,4 @@ +! Module raffle defined in file /Users/nedtaylor/DCoding/DGit/raffle/src/raffle.f90 + +! End of module raffle defined in file /Users/nedtaylor/DCoding/DGit/raffle/src/raffle.f90 + From 062fadf6fd0169ce295e5a1624388be321485b0d Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Fri, 19 Jul 2024 14:52:37 +0100 Subject: [PATCH 045/293] Comment out f90wrap --- CMakeLists.txt | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ed64adf0..67833e0e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -237,23 +237,23 @@ if (BUILD_PYTHON) message(FATAL_ERROR "f90wrap not found. Please install f90wrap.") endif() - # Generate f90wrap signature file + # # Generate f90wrap signature file set(F90WRAP_FILE ${CMAKE_BINARY_DIR}/f90wrap_*.f90) - set(KIND_MAP ${CMAKE_SOURCE_DIR}/kind_map) - add_custom_command( - TARGET ${PROJECT_NAME} - POST_BUILD - COMMAND ${F90WRAP_EXECUTABLE} - --default-to-inout - -m ${PROJECT_NAME} - -k ${KIND_MAP} - ${F90WRAP_FORTRAN_SRC_FILES} - --only raffle_generator_type stoichiometry_type bas_type gvector_container_type: - DEPENDS ${F90WRAP_FORTRAN_SRC_FILES} - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - COMMENT "Generating f90wrap signature file" - VERBATIM - ) + # set(KIND_MAP ${CMAKE_SOURCE_DIR}/kind_map) + # add_custom_command( + # TARGET ${PROJECT_NAME} + # POST_BUILD + # COMMAND ${F90WRAP_EXECUTABLE} + # --default-to-inout + # -m ${PROJECT_NAME} + # -k ${KIND_MAP} + # ${F90WRAP_FORTRAN_SRC_FILES} + # --only raffle_generator_type stoichiometry_type bas_type gvector_container_type: + # DEPENDS ${F90WRAP_FORTRAN_SRC_FILES} + # WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + # COMMENT "Generating f90wrap signature file" + # VERBATIM + # ) # Copy f90wrap edited files from edited_autogen_files to ${CMAKE_BINARY_DIR} add_custom_command( From 0c53705ddbe9e6456245e4035396ea75f4bf1f59 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Fri, 19 Jul 2024 14:53:42 +0100 Subject: [PATCH 046/293] Move wrapper files --- CMakeLists.txt | 2 +- {edited_autogen_files => src/wrapper}/f90wrap_mod_evolver.f90 | 0 {edited_autogen_files => src/wrapper}/f90wrap_mod_generator.f90 | 0 {edited_autogen_files => src/wrapper}/f90wrap_mod_rw_geom.f90 | 0 {edited_autogen_files => src/wrapper}/f90wrap_raffle.f90 | 0 {edited_autogen_files => src/wrapper}/raffle.py | 0 6 files changed, 1 insertion(+), 1 deletion(-) rename {edited_autogen_files => src/wrapper}/f90wrap_mod_evolver.f90 (100%) rename {edited_autogen_files => src/wrapper}/f90wrap_mod_generator.f90 (100%) rename {edited_autogen_files => src/wrapper}/f90wrap_mod_rw_geom.f90 (100%) rename {edited_autogen_files => src/wrapper}/f90wrap_raffle.f90 (100%) rename {edited_autogen_files => src/wrapper}/raffle.py (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 67833e0e..06148730 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -259,7 +259,7 @@ if (BUILD_PYTHON) add_custom_command( TARGET ${PROJECT_NAME} POST_BUILD - COMMAND cp ${CMAKE_CURRENT_LIST_DIR}/edited_autogen_files/* ${CMAKE_BINARY_DIR} + COMMAND cp ${CMAKE_CURRENT_LIST_DIR}/src/wrapper/* ${CMAKE_BINARY_DIR} COMMENT "Copying f90wrap edited files" ) diff --git a/edited_autogen_files/f90wrap_mod_evolver.f90 b/src/wrapper/f90wrap_mod_evolver.f90 similarity index 100% rename from edited_autogen_files/f90wrap_mod_evolver.f90 rename to src/wrapper/f90wrap_mod_evolver.f90 diff --git a/edited_autogen_files/f90wrap_mod_generator.f90 b/src/wrapper/f90wrap_mod_generator.f90 similarity index 100% rename from edited_autogen_files/f90wrap_mod_generator.f90 rename to src/wrapper/f90wrap_mod_generator.f90 diff --git a/edited_autogen_files/f90wrap_mod_rw_geom.f90 b/src/wrapper/f90wrap_mod_rw_geom.f90 similarity index 100% rename from edited_autogen_files/f90wrap_mod_rw_geom.f90 rename to src/wrapper/f90wrap_mod_rw_geom.f90 diff --git a/edited_autogen_files/f90wrap_raffle.f90 b/src/wrapper/f90wrap_raffle.f90 similarity index 100% rename from edited_autogen_files/f90wrap_raffle.f90 rename to src/wrapper/f90wrap_raffle.f90 diff --git a/edited_autogen_files/raffle.py b/src/wrapper/raffle.py similarity index 100% rename from edited_autogen_files/raffle.py rename to src/wrapper/raffle.py From 57a952224afe01cff302e2cd601fb67bb7a83ccd Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Fri, 19 Jul 2024 15:08:29 +0100 Subject: [PATCH 047/293] Add python example --- example/wrapper/POSCAR_host | 10 ++++++++ example/wrapper/chem.in | 38 +++++++++++++++++++++++++++++ example/wrapper/elements.dat | 4 +++ example/wrapper/run.py | 47 ++++++++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+) create mode 100644 example/wrapper/POSCAR_host create mode 100644 example/wrapper/chem.in create mode 100644 example/wrapper/elements.dat create mode 100644 example/wrapper/run.py diff --git a/example/wrapper/POSCAR_host b/example/wrapper/POSCAR_host new file mode 100644 index 00000000..06d8b466 --- /dev/null +++ b/example/wrapper/POSCAR_host @@ -0,0 +1,10 @@ +host +1.0 + 5.0 0.0 0.0 + 0.0 5.0 0.0 + 0.0 0.0 10.0 +C +2 +Direct +0.0 0.0 0.0 +0.5 0.5 0.1 diff --git a/example/wrapper/chem.in b/example/wrapper/chem.in new file mode 100644 index 00000000..299544d0 --- /dev/null +++ b/example/wrapper/chem.in @@ -0,0 +1,38 @@ +# element_1 element_2 covalent_radius van_der_waals_radius coordination_1 coordination_2 +O O 1.208 1.52 1 1 +Pd Pd 2.79543 1.63 12 12 +Pd O 2.00474 0 6 3 +S S 2.06 2.27 2 2 +S O 1.45130 0 2 1 +Pd S 2.43915 0 2 8 +C C 1.54461 1.7 4 4 +Al Al 2.85595 1.84 12 12 +Si Si 2.36838 2.10 4 4 +O Si 1.62599 0 2 4 +As As 2.48 1.85 3 3 +Ga Ga 2.724667143 1.87 7 7 +Ga As 2.48990 0 4 4 +Fe Fe 2.46654 1.56 12 12 +Ni Ni 2.48056 1.63 12 12 +Ni O 2.10211 0 6 6 +O Mo 1.972445 0 2 6 +Mo Mo 2.74324 1.54 8 8 +Na Na 3.32 2.27 6 6 +Cl Cl 2.01061 1.75 6 6 +Na Cl 2.84585 0 6 6 +Sn Ca 3.493455 0 4 8 +Ca Ca 3.91868 2.31 12 12 +Sn Sn 2.87792 2.17 4 4 +Ca O 2.41963 0 6 6 +Sn O 2.09221 0 6 3 +Pd Se 2.51720 0 6 3 +Se Se 2.36077 1.90 2 2 +Mg O 2.12824 0 6 6 +Mg Mg 2.184 1.72 4 4 !!! 3.184 +C Mg 2.3 0 5 5 !!! Tentative +C O 1.1752 0 2 1 +Li Li 3.06377 1.82 12 12 +Li S 2.47742 0 4 8 +Li Sc 3.08993 0 3 12 +Sc Sc 3.22090 2.11 12 12 +Sc S 2.61809 0 6 4 \ No newline at end of file diff --git a/example/wrapper/elements.dat b/example/wrapper/elements.dat new file mode 100644 index 00000000..ad41fc26 --- /dev/null +++ b/example/wrapper/elements.dat @@ -0,0 +1,4 @@ +# element energy mass charge +C -9.0266865 12.011 0 +Mg -1.5478236 24.305 0 +O -4.3707458 15.999 0 \ No newline at end of file diff --git a/example/wrapper/run.py b/example/wrapper/run.py new file mode 100644 index 00000000..c2461978 --- /dev/null +++ b/example/wrapper/run.py @@ -0,0 +1,47 @@ +import sys +# caution: path[0] is reserved for script path (or '' in REPL) +sys.path.insert(1, '../build/') + +import build.raffle as raffle +from ase import Atoms +from ase.io import read + +# atoms = Atoms('CC', positions=[[0, 0, 0], [1.2, 0, 0]], pbc=True, cell=[2.4, 2.4, 2.4]) + +print("Initialising raffle generator") +generator = raffle.generator.raffle_generator_type() + + +print("Reading host") +host = read("POSCAR_host") +host_basis = raffle.rw_geom.bas_type(host) +generator.set_host(host_basis) +print("Host read") + +print("Reading database") +database = read("database.xyz", index=":") +num_database = len(database) +database_basis = raffle.rw_geom.bas_type_xnum_array() +database_basis.allocate(num_database) +for i, atoms in enumerate(database): + database_basis.items[i].fromase(atoms) +print("Database read") + +print("Setting database") +generator.distributions.create(database_basis) +print("Database set") + +print("Setting bins (discretisation of host cell)") +generator.bins = [50,50,50] + +print("Setting stoichiometry to insert") +stoich_list = raffle.generator.stoichiometry_type_xnum_array() +stoich_list.allocate(2) +stoich_list.items[0].element = 'C' +stoich_list.items[0].num = 1 +stoich_list.items[1].element = 'Mg' +stoich_list.items[1].num = 2 + +print("Generating...") +generator.generate(num_structures=2, stoichiometry=stoich_list) +print("Generated") \ No newline at end of file From 1ed9384e4fae94885c3fc7e2abf2e4daa47ce0e9 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Fri, 19 Jul 2024 17:11:03 +0100 Subject: [PATCH 048/293] Handle child structures --- example/wrapper/run.py | 24 +++++++++++++++++++----- src/lib/mod_atom_adder.f90 | 10 +++++++++- src/lib/mod_buildmap.f90 | 18 +++++++++++++++--- src/lib/mod_generator.f90 | 10 +++++----- src/wrapper/f90wrap_mod_generator.f90 | 26 ++++++++++++++++++++++++++ src/wrapper/raffle.py | 18 +++++++++++++++++- 6 files changed, 91 insertions(+), 15 deletions(-) diff --git a/example/wrapper/run.py b/example/wrapper/run.py index c2461978..94de8d6c 100644 --- a/example/wrapper/run.py +++ b/example/wrapper/run.py @@ -1,10 +1,10 @@ import sys # caution: path[0] is reserved for script path (or '' in REPL) -sys.path.insert(1, '../build/') +sys.path.insert(1, '../../build/') -import build.raffle as raffle +import raffle from ase import Atoms -from ase.io import read +from ase.io import read, write # atoms = Atoms('CC', positions=[[0, 0, 0], [1.2, 0, 0]], pbc=True, cell=[2.4, 2.4, 2.4]) @@ -25,6 +25,7 @@ database_basis.allocate(num_database) for i, atoms in enumerate(database): database_basis.items[i].fromase(atoms) + print("Database read") print("Setting database") @@ -40,8 +41,21 @@ stoich_list.items[0].element = 'C' stoich_list.items[0].num = 1 stoich_list.items[1].element = 'Mg' -stoich_list.items[1].num = 2 +stoich_list.items[1].num = 1 print("Generating...") generator.generate(num_structures=2, stoichiometry=stoich_list) -print("Generated") \ No newline at end of file +print("Generated") + +print("Getting structures") +# generated_structures = generator.get_structures() +print("number of structures supposed to be generated: ", generator.num_structures) +generated_structures = generator.structures +print("actual number allocated: ",len(generated_structures)) +print("Got structures") + +print("Converting to ASE") +for i, structure in enumerate(generated_structures): + print(f"Converting structure {i}") + atoms = structure.toase() + write(f"POSCAR_{i}", atoms) diff --git a/src/lib/mod_atom_adder.f90 b/src/lib/mod_atom_adder.f90 index 0d071dd0..127e84fd 100644 --- a/src/lib/mod_atom_adder.f90 +++ b/src/lib/mod_atom_adder.f90 @@ -46,10 +46,14 @@ subroutine add_atom_scan (gridpoints, gvector_container, & atom_ignore_list, radius_list, & 1.1_real12, 0.95_real12) end do - if(abs(maxval(suitability_grid)).lt.1.E-6) return + if(abs(maxval(suitability_grid)).lt.1.E-6) then + deallocate(suitability_grid) + return + end if placed = .true. best_gridpoint = maxloc(suitability_grid, dim=1) + deallocate(suitability_grid) basis%spec(atom_ignore_list(1,1))%atom(atom_ignore_list(1,2),:) = & gridpoints(:,best_gridpoint) @@ -264,6 +268,8 @@ function get_viable_gridpoints(bin_size, basis, & end do grid_loop1 allocate(points, source = points_tmp(:,:num_points)) + deallocate(points_tmp, pair_index) + end function get_viable_gridpoints !!!############################################################################# @@ -303,6 +309,8 @@ subroutine update_viable_gridpoints(points, basis, atom, radius) points = points_tmp(:,:num_points) end if + deallocate(points_tmp) + end subroutine update_viable_gridpoints !!!############################################################################# diff --git a/src/lib/mod_buildmap.f90 b/src/lib/mod_buildmap.f90 index db1bd6ce..ef0eb95d 100644 --- a/src/lib/mod_buildmap.f90 +++ b/src/lib/mod_buildmap.f90 @@ -87,6 +87,7 @@ pure function buildmap_POINT(gvector_container, & !! check if the bondlength is within the tolerance for bonds ... !! ... between its own element and the element of the current atom if(bondlength .lt. radius_list(pair_index(ls,is))*lowtol)then + deallocate(pair_index) return else if(bondlength .gt. radius_list(pair_index(ls,is))*uptol)then cycle atom_loop1 @@ -112,7 +113,10 @@ pure function buildmap_POINT(gvector_container, & end do position_storage2 = basis%spec(js)%atom(ja,:) if(get_distance(position,position_storage2).lt.& - radius_list(pair_index(ls,js))*lowtol) return + radius_list(pair_index(ls,js))*lowtol)then + deallocate(pair_index) + return + end if if(get_distance(position,position_storage2).lt.& radius_list(pair_index(ls,js))*uptol) then bin = gvector_container%get_bin( & @@ -145,7 +149,10 @@ pure function buildmap_POINT(gvector_container, & end do position_storage3 = basis%spec(js)%atom(ja,:) if(get_distance(position,position_storage3).lt.& - radius_list(pair_index(ls,ks))*lowtol) return + radius_list(pair_index(ls,ks))*lowtol) then + deallocate(pair_index) + return + end if if(get_distance(position_storage1,position_storage3).lt.& radius_list(pair_index(is,ks))*uptol) then bin = gvector_container%get_bin( & @@ -157,7 +164,10 @@ pure function buildmap_POINT(gvector_container, & dim = 3 ) if(bin.eq.0) cycle contribution = gvector_container%total%df_4body(bin,is) - if(abs(contribution).lt.1.E-6) return + if(abs(contribution).lt.1.E-6) then + deallocate(pair_index) + return + end if !Here have taken a large root of value return, to ... !...account for sumamtion of atoms in 3D. !Will need to think further on this. @@ -173,6 +183,8 @@ pure function buildmap_POINT(gvector_container, & if(abs(viability_2body).lt.1.E-6) viability_2body = 1._real12 output = viability_2body * viability_4body * viability_3body + + deallocate(pair_index) end function buildmap_POINT !!!############################################################################# diff --git a/src/lib/mod_generator.f90 b/src/lib/mod_generator.f90 index 92f7e438..6747d4c7 100644 --- a/src/lib/mod_generator.f90 +++ b/src/lib/mod_generator.f90 @@ -167,7 +167,7 @@ subroutine generate(this, num_structures, & if(present(method_probab)) method_probab_ = method_probab if(.not.allocated(this%structures))then - allocate(this%structures(this%num_structures)) + allocate(this%structures(num_structures)) else allocate(tmp_structures(this%num_structures + num_structures)) tmp_structures(:this%num_structures) = this%structures(:this%num_structures) @@ -238,15 +238,15 @@ subroutine generate(this, num_structures, & num_structures_new = this%num_structures + num_structures structure_loop: do istructure = num_structures_old + 1, num_structures_new - this%structures(i) = this%generate_structure( basis_store, & + this%structures(istructure) = this%generate_structure( basis_store, & placement_list, method_probab_ ) - this%num_structures = i + this%num_structures = istructure #ifdef ENABLE_ATHENA !!----------------------------------------------------------------------- !! predict energy using ML !!----------------------------------------------------------------------- - graph(1) = get_graph_from_basis(this%structures(i)) + graph(1) = get_graph_from_basis(this%structures(istructure)) write(*,*) "Predicted energy", network_predict_graph(graph(1:1)) #endif @@ -360,7 +360,7 @@ module function generate_structure( & end if end do placement_loop - deallocate(viable_gridpoints) + if(allocated(viable_gridpoints)) deallocate(viable_gridpoints) end function generate_structure diff --git a/src/wrapper/f90wrap_mod_generator.f90 b/src/wrapper/f90wrap_mod_generator.f90 index 87011420..078bfbd5 100644 --- a/src/wrapper/f90wrap_mod_generator.f90 +++ b/src/wrapper/f90wrap_mod_generator.f90 @@ -572,5 +572,31 @@ subroutine f90wrap_generator__evaluate__binding__rgt(this, ret_viability, basis) ret_viability = this_ptr%p%evaluate(basis=basis_ptr%p) end subroutine f90wrap_generator__evaluate__binding__rgt +subroutine f90wrap_generator__get_structures__binding__rgt(this, ret_structures) + use rw_geom, only: bas_type + use generator, only: raffle_generator_type + implicit none + + type raffle_generator_type_ptr_type + type(raffle_generator_type), pointer :: p => NULL() + end type raffle_generator_type_ptr_type + + type bas_type_xnum_array + type(bas_type), dimension(:), allocatable :: items + end type bas_type_xnum_array + + type bas_type_xnum_array_ptr_type + type(bas_type_xnum_array), pointer :: p => NULL() + end type bas_type_xnum_array_ptr_type + type(raffle_generator_type_ptr_type) :: this_ptr + integer, intent(in), dimension(2) :: this + integer, intent(out), dimension(2) :: ret_structures + type(bas_type_xnum_array_ptr_type) :: ret_structures_ptr + + this_ptr = transfer(this, this_ptr) + ret_structures_ptr%p%items = this_ptr%p%get_structures() + ret_structures = transfer(ret_structures_ptr,ret_structures) +end subroutine f90wrap_generator__get_structures__binding__rgt + ! End of module generator defined in file ../src/lib/mod_generator.f90 diff --git a/src/wrapper/raffle.py b/src/wrapper/raffle.py index 963f4cab..1e5e05d7 100644 --- a/src/wrapper/raffle.py +++ b/src/wrapper/raffle.py @@ -271,7 +271,7 @@ def toase(self): atoms.set_pbc(self.pbc) # Set the lattice vectors - atoms.set_cell(bas.lat) + atoms.set_cell(self.lat) return atoms @@ -1873,6 +1873,22 @@ def generate(self, num_structures, stoichiometry, method_probab=[1.0, 1.0, 1.0]) num_structures=num_structures, stoichiometry=stoichiometry._handle, method_probab=method_probab) + + def get_structures(self): + """ + structures = get_structures__binding__raffle_generator_type(self) + + + Defined at ../src/lib/mod_generator.f90 lines \ + 86-97 + + Parameters + ---------- + this : unknown + + """ + structures = _raffle.f90wrap_generator__get_structures__binding__rgt(this=self._handle) + return structures def evaluate(self, basis): """ From d98f394a6da6c04e44ad9ad85f6701a5597ab70f Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Sun, 21 Jul 2024 09:32:44 +0100 Subject: [PATCH 049/293] Set up pip install --- CMakeLists.txt | 17 ++++-- MANIFEST.in | 1 + pyproject.toml | 35 +++++++++++ setup.py | 98 +++++++++++++++++++++++++++++++ src/raffle/__init__.py | 12 ++++ src/{wrapper => raffle}/raffle.py | 2 +- 6 files changed, 158 insertions(+), 7 deletions(-) create mode 100644 MANIFEST.in create mode 100644 pyproject.toml create mode 100644 setup.py create mode 100644 src/raffle/__init__.py rename src/{wrapper => raffle}/raffle.py (99%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 06148730..b4835d3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,6 +52,9 @@ if (CMAKE_BUILD_TYPE MATCHES "Debug*" OR CMAKE_BUILD_TYPE MATCHES "Dev*") endif() endif() +# set the output directories +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) + # enable testing enable_testing() @@ -70,11 +73,9 @@ set(LIB_FILES mod_misc.f90 mod_misc_maths.f90 mod_misc_linalg.f90 - # mod_rw_geom.f90 mod_rw_vasprun.f90 mod_edit_geom.f90 mod_elements.f90 - # mod_evolver.f90 mod_buildmap.f90 mod_atom_adder.f90 mod_read_structures.f90 @@ -238,7 +239,7 @@ if (BUILD_PYTHON) endif() # # Generate f90wrap signature file - set(F90WRAP_FILE ${CMAKE_BINARY_DIR}/f90wrap_*.f90) + set(F90WRAP_FILE ${CMAKE_CURRENT_LIST_DIR}/src/wrapper/f90wrap_*.f90) # set(KIND_MAP ${CMAKE_SOURCE_DIR}/kind_map) # add_custom_command( # TARGET ${PROJECT_NAME} @@ -259,10 +260,12 @@ if (BUILD_PYTHON) add_custom_command( TARGET ${PROJECT_NAME} POST_BUILD - COMMAND cp ${CMAKE_CURRENT_LIST_DIR}/src/wrapper/* ${CMAKE_BINARY_DIR} - COMMENT "Copying f90wrap edited files" + COMMAND cp -r ${CMAKE_CURRENT_LIST_DIR}/src/raffle/*.py ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + COMMENT "Copying raffle class file" ) + set(F2PY_OUTPUT_FLAG --quiet > /dev/null 2>&1) + # Create a Python module using f2py add_custom_command( TARGET ${PROJECT_NAME} @@ -274,10 +277,12 @@ if (BUILD_PYTHON) -m _${PROJECT_NAME} --f90flags="${PPFLAGS}" ${F90WRAP_FILE} + --quiet ${OBJECTS_DIR}/src/*.o ${OBJECTS_DIR}/src/lib/*.o + # ${F2PY_OUTPUT_FLAG} DEPENDS ${F90WRAP_FILE} - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + WORKING_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} COMMENT "Creating Python module using f2py" ) diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 00000000..6c67e93f --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1 @@ +include src/raffle/*.py diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..59fce230 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,35 @@ +[project] +name = "raffle" +version = "0.2" +dependencies = [ + "f90wrap>=0.2.15", + "numpy>=2.0.0", + "ase>=3.23.0", +] +requires-python = ">=3.11" +authors = [ + { name = "Ned Thaddeus Taylor", email = "n.t.taylor@exeter.ac.uk" }, + { name = "Joe Pitfield" }, + { name = "Steven Paul Hepplestone", email = "s.p.hepplestone@exeter.ac.uk" }, +] +description = "A material interface structure prediction package" +readme = "README.md" +classifiers = [ + "Development Status :: 3", + "Indented Audience :: Computational materials scientists", + "Programming Language :: Python :: 3.11", + "Programming Language :: Fortran :: F08", + "License :: ", + "Operating System :: OS Independent", +] + +[project.urls] +Homepage = "https://github.com/nedtaylor/raffle" +Issues = "https://github.com/nedtaylor/raffle/issues" + +[build-system] +requires = [ + "f90wrap>=0.2.15", + "setuptools ~= 58.0", + "cython ~= 0.29.0", +] \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 00000000..e29e4056 --- /dev/null +++ b/setup.py @@ -0,0 +1,98 @@ +import os +import sys +import subprocess +from setuptools import setup, Extension, find_packages +from setuptools.command.build_ext import build_ext +import shutil + +class CMakeBuild(build_ext): + """ + Custom build command that uses CMake to build extensions. + + This class extends the `build_ext` command provided by setuptools + to build C/C++ extensions using CMake. + + Attributes: + build_temp (str): The directory where the build files will be placed. + extensions (list): List of extension objects to build. + + Methods: + run(): Runs the build process. + build_extension(ext): Builds a specific extension. + + """ + + def run(self): + # Ensure CMake is installed + try: + subprocess.check_output(['cmake', '--version']) + except OSError: + raise RuntimeError("CMake must be installed to build the following extensions: " + + ", ".join(e.name for e in self.extensions)) + + for ext in self.extensions: + self.build_extension(ext) + + def build_extension(self, ext): + """ + Builds a specific extension using CMake. + + Args: + ext (Extension): The extension object to build. + + """ + extdir = os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name))) + print("extdir: ", extdir) + cmake_args = [ + '-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir, + # '-DPYTHON_EXECUTABLE=' + os.path.abspath(sys.executable) + ] + build_args = ['--config', 'Release'] + + if not os.path.exists(self.build_temp): + os.makedirs(self.build_temp) + + subprocess.check_call(['cmake', ext.sourcedir] + cmake_args, cwd=self.build_temp) + subprocess.check_call(['cmake', '--build', '.'] + build_args, cwd=self.build_temp) + + extdir = extdir + "/raffle" + if not os.path.exists(extdir): + os.makedirs(extdir) + + # Move the generated .so file to the appropriate location + for root, _, files in os.walk(self.build_temp): + for file in files: + if file.endswith('.so') or file.endswith('.py'): + src = os.path.join(root, file) + dest = os.path.join(extdir, file) + print(f"Moving {src} to {dest}") + shutil.move(src, dest) + print(f"Moved {src} to {dest}") + + +class CMakeExtension(Extension): + def __init__(self, name, sourcedir=''): + Extension.__init__(self, name, sources=[]) + self.sourcedir = os.path.abspath(sourcedir) + +setup( + name='raffle', + version='0.2.0', + author='Ned Thaddeus Taylor', + author_email='n.t.taylor@exeter.ac.uk', + description='A Python project with a Fortran library', + long_description=open('README.md').read(), + long_description_content_type='text/markdown', + ext_modules=[CMakeExtension('raffle')], + cmdclass=dict(build_ext=CMakeBuild), + zip_safe=False, + include_package_data=True, + packages=find_packages(where='src'), + package_dir={'': 'src'}, + package_data={ + 'src/raffle': ['*.py'], + 'src': ['*.f90'], + 'src/lib': ['*.f90'], + 'src/wrapper': ['*.f90'], + }, +) diff --git a/src/raffle/__init__.py b/src/raffle/__init__.py new file mode 100644 index 00000000..f65ff686 --- /dev/null +++ b/src/raffle/__init__.py @@ -0,0 +1,12 @@ +""" +raffle package + +This package provides functionality to interface with a Fortran library, +including a Python wrapper around the Fortran code. +""" + +__version__ = '0.2.0' + +from raffle.raffle import * + +__all__ = ['__version__', 'generator', 'rw_geom'] \ No newline at end of file diff --git a/src/wrapper/raffle.py b/src/raffle/raffle.py similarity index 99% rename from src/wrapper/raffle.py rename to src/raffle/raffle.py index 1e5e05d7..4fc67265 100644 --- a/src/wrapper/raffle.py +++ b/src/raffle/raffle.py @@ -1,5 +1,5 @@ from __future__ import print_function, absolute_import, division -import _raffle +import raffle._raffle import f90wrap.runtime import logging import numpy From 85643cd2746ac3a996afc8711034e07a5edbd923 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Sun, 21 Jul 2024 11:07:29 +0100 Subject: [PATCH 050/293] Fix requirements and update README --- CMakeLists.txt | 8 +++--- README.md | 67 +++++++++++++++++++++++++++++++++++++++++++++++--- pyproject.toml | 4 ++- setup.py | 11 +++++++-- 4 files changed, 79 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b4835d3b..28d1018c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -231,12 +231,10 @@ if (BUILD_PYTHON) # Include f90wrap find_package(Python3 REQUIRED COMPONENTS Interpreter Development) - find_program(F90WRAP_EXECUTABLE f90wrap) - find_program(F2PY_EXECUTABLE f2py-f90wrap) - - if(NOT F90WRAP_EXECUTABLE) - message(FATAL_ERROR "f90wrap not found. Please install f90wrap.") + if(NOT DEFINED PYTHON_EXECUTABLE) + set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE}) endif() + set (F2PY_EXECUTABLE ${PYTHON_EXECUTABLE} -m f90wrap --f2py-f90wrap) # # Generate f90wrap signature file set(F90WRAP_FILE ${CMAKE_CURRENT_LIST_DIR}/src/wrapper/f90wrap_*.f90) diff --git a/README.md b/README.md index 753c6922..d13b900e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,63 @@ +# RAFFLE + +by Ned Thaddeus Taylor, Joe Pitfield, and Steven Paul Hepplestone + +RAFFLE (pseudoRandom Approach For Finding Local Energetic minima) is a package for structural prediction applied to material interfaces. RAFFLE can interface with the [Atomic Simulation Environment (ASE)](https://gitlab.com/ase/ase). + +RAFFLE is both a Fortran and a Python library. A standalone Fortran executable is also being developed. The code heavily relies on features of Fortran2008 and above, so there is no backwards compatibility with Fortran95. + +## Requirements + +- Python 3.11 or later (might work on earlier, have not tested) +- Fortran compiler supporting Fortran 2008 standard or later +- NumPy +- f90wrap +- CMake + +Optional: +- ASE + +The library bas been developed and tested using the following Fortran compilers: +- gfortran -- gcc 13.2.0 + +## Installation + +To install RAFFLE, the source must be obtained from the git repository. Use the following commands to get started: +``` + git clone https://github.com/nedtaylor/raffle.git + cd athena +``` + + +Depending on what language will be used in, installation will fary from this point. + +### Python + +For Python, the easiest installation is through pip: +``` +pip install . +``` + +Another option is installing it through cmake, which involves: +``` +mkdir build +cd build +cmake .. +make install +``` + +Then, the path to the install directory (`${HOME}/.local/raffle`) needs to be added to the include path. + +### Fortran + +For Fortran, CMake is required (fpm in the future, hopefully). The Python library installation can be turned off. +``` +mkdir build +cd build +cmake -DBUILD_PYTHON=Off .. +make install +``` + This is a quick how-to guide for using RAFFLE. First, compile using @@ -5,7 +65,7 @@ First, compile using make ``` -It has been developed using gfortran version 13.2.0. It can only be guaranteed to work for this version of fortran for now. It heavily relies on a lot of features of Fortran2008 and above, so there is no backwards compatibility with Fortran95. +## Using First, you need to ensure that the following two files exist in the directory in which you run RAFFLE: ``` @@ -14,7 +74,7 @@ chem.in ``` Each of these files should follow the format found in the current repository. They should each have a header line that starts with "#" and contains the word "element". The example headers should then be followed for filling in data. For the elements.dat, the energy provided can be whatever you want to use as a reference energy. This energy is used for calculating formation energy. The example uses energy/atom of the bulk phase of the element. The mass and charge are not currently used, but data needs to be provided in those columns. - + diff --git a/pyproject.toml b/pyproject.toml index 59fce230..2684ed45 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,6 +30,8 @@ Issues = "https://github.com/nedtaylor/raffle/issues" [build-system] requires = [ "f90wrap>=0.2.15", + "numpy>=2.0.0", "setuptools ~= 58.0", "cython ~= 0.29.0", -] \ No newline at end of file +] +build-backend = "setuptools.build_meta" diff --git a/setup.py b/setup.py index e29e4056..83bd73c8 100644 --- a/setup.py +++ b/setup.py @@ -42,10 +42,9 @@ def build_extension(self, ext): """ extdir = os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name))) - print("extdir: ", extdir) cmake_args = [ '-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir, - # '-DPYTHON_EXECUTABLE=' + os.path.abspath(sys.executable) + '-DPYTHON_EXECUTABLE=' + os.path.abspath(sys.executable) ] build_args = ['--config', 'Release'] @@ -75,12 +74,20 @@ def __init__(self, name, sourcedir=''): Extension.__init__(self, name, sources=[]) self.sourcedir = os.path.abspath(sourcedir) +minimum_requirements = [ + "f90wrap>=0.2.15", + "numpy>=2.0.0", + "ase>=3.23.0", +] + setup( name='raffle', version='0.2.0', author='Ned Thaddeus Taylor', author_email='n.t.taylor@exeter.ac.uk', description='A Python project with a Fortran library', + install_requires=minimum_requirements, + python_requires='>=3.11, <3.12', long_description=open('README.md').read(), long_description_content_type='text/markdown', ext_modules=[CMakeExtension('raffle')], From bfdf6bb78ea7ae076f3595ba7bca2a2072cb12d1 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Sun, 21 Jul 2024 12:08:23 +0100 Subject: [PATCH 051/293] Fix reinstall issue --- CMakeLists.txt | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 28d1018c..284cab0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -228,7 +228,6 @@ if (BUILD_PYTHON) set(OBJECTS_DIR ${CMAKE_BUILD_PREFIX}/CMakeFiles/${PROJECT_NAME}.dir) message(STATUS "Object files directory for ${PROJECT_NAME}: ${OBJECTS_DIR}") - # Include f90wrap find_package(Python3 REQUIRED COMPONENTS Interpreter Development) if(NOT DEFINED PYTHON_EXECUTABLE) @@ -236,6 +235,20 @@ if (BUILD_PYTHON) endif() set (F2PY_EXECUTABLE ${PYTHON_EXECUTABLE} -m f90wrap --f2py-f90wrap) + # determine middle part of shared object filename + string(REPLACE "." "" PYTHON_VERSION ${Python3_VERSION_MAJOR}${Python3_VERSION_MINOR}) + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + set(PLATFORM_TAG "darwin") + elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(PLATFORM_TAG "linux") + elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(PLATFORM_TAG "win_amd64") + else() + set(PLATFORM_TAG "unknown") + endif() + set(FILENAME_MIDDLE "cpython-${PYTHON_VERSION}-${PLATFORM_TAG}") + set(F2PY_OUTPUT_FILE ${CMAKE_BINARY_DIR}/_${PROJECT_NAME}.${FILENAME_MIDDLE}.so) + # # Generate f90wrap signature file set(F90WRAP_FILE ${CMAKE_CURRENT_LIST_DIR}/src/wrapper/f90wrap_*.f90) # set(KIND_MAP ${CMAKE_SOURCE_DIR}/kind_map) @@ -254,10 +267,11 @@ if (BUILD_PYTHON) # VERBATIM # ) + add_custom_target(PY_FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.py) + # Copy f90wrap edited files from edited_autogen_files to ${CMAKE_BINARY_DIR} add_custom_command( - TARGET ${PROJECT_NAME} - POST_BUILD + OUTPUT ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.py ${CMAKE_BINARY_DIR}/__init__.py COMMAND cp -r ${CMAKE_CURRENT_LIST_DIR}/src/raffle/*.py ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} COMMENT "Copying raffle class file" ) @@ -266,7 +280,7 @@ if (BUILD_PYTHON) # Create a Python module using f2py add_custom_command( - TARGET ${PROJECT_NAME} + OUTPUT ${F2PY_OUTPUT_FILE} POST_BUILD COMMAND ${F2PY_EXECUTABLE} ${F2PY_ATHENA_LIBRARY_FLAGS} @@ -278,20 +292,19 @@ if (BUILD_PYTHON) --quiet ${OBJECTS_DIR}/src/*.o ${OBJECTS_DIR}/src/lib/*.o - # ${F2PY_OUTPUT_FLAG} + ${F2PY_OUTPUT_FLAG} DEPENDS ${F90WRAP_FILE} WORKING_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} COMMENT "Creating Python module using f2py" ) - # Define output files set(PY_MODULE ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.py) - file(GLOB SO_MODULE "${CMAKE_BINARY_DIR}/_${PROJECT_NAME}*.so") + # file(GLOB SO_MODULE "${CMAKE_BINARY_DIR}/_${PROJECT_NAME}*.so") # Create a custom target for the Python module add_custom_target(python_module ALL - DEPENDS ${SO_MODULE} ${PY_MODULE} + DEPENDS ${F2PY_OUTPUT_FILE} ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.py ${CMAKE_BINARY_DIR}/__init__.py ) # Installation instructions From e8c431c2e1bb0ec54fae4c46e403b45a1d87e510 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Sun, 21 Jul 2024 12:12:07 +0100 Subject: [PATCH 052/293] Fix import --- .gitignore | 4 +++- src/raffle/__init__.py | 2 +- src/raffle/raffle.py | 10 +++++----- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 1eb5c093..bc991905 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,6 @@ obj/ *.smod DTESTING/ DTEST/ -build/ \ No newline at end of file +build/ +src/*.egg-info +*.egg-info \ No newline at end of file diff --git a/src/raffle/__init__.py b/src/raffle/__init__.py index f65ff686..c6b42116 100644 --- a/src/raffle/__init__.py +++ b/src/raffle/__init__.py @@ -7,6 +7,6 @@ __version__ = '0.2.0' -from raffle.raffle import * +from raffle.raffle import generator, rw_geom __all__ = ['__version__', 'generator', 'rw_geom'] \ No newline at end of file diff --git a/src/raffle/raffle.py b/src/raffle/raffle.py index 4fc67265..67a79e4b 100644 --- a/src/raffle/raffle.py +++ b/src/raffle/raffle.py @@ -1,9 +1,8 @@ from __future__ import print_function, absolute_import, division -import raffle._raffle +import raffle._raffle as _raffle import f90wrap.runtime import logging import numpy -from ase import Atoms class Rw_Geom(f90wrap.runtime.FortranModule): """ @@ -220,7 +219,7 @@ def __del__(self): _raffle.f90wrap_rw_geom__bas_type_finalise(this=self._handle) def allocate_species(self, num_species=None, species_symbols=None, species_count=None, \ - atoms=None): + positions=None): """ allocate_species__binding__bas_type(self[, num_species, species_symbols, \ species_count, atoms]) @@ -240,7 +239,7 @@ def allocate_species(self, num_species=None, species_symbols=None, species_count """ _raffle.f90wrap_rw_geom__allocate_species__binding__bas_type(this=self._handle, \ num_species=num_species, species_symbols=species_symbols, species_count=species_count, \ - atoms=atoms) + atoms=positions) def init_array_spec(self): self.spec = f90wrap.runtime.FortranDerivedTypeArray(self, @@ -257,6 +256,7 @@ def init_array_spec(self): return self.spec def toase(self): + from ase import Atoms # Set the species list positions = [] @@ -308,7 +308,7 @@ def fromase(self, atoms): atom_positions.append(positions[j]) # Allocate memory for the atom list - self.allocate_species(species_symbols=species_symbols_unique, species_count=species_count, atoms=atom_positions) + self.allocate_species(species_symbols=species_symbols_unique, species_count=species_count, positions=atom_positions) @property def nspec(self): From 72c8a0847edf7351a6b70b5299ed5d36df82a893 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Mon, 22 Jul 2024 08:36:29 +0100 Subject: [PATCH 053/293] Add Fortran executable --- CMakeLists.txt | 26 +++++++++++++++++++++----- {src => app}/inputs.f90 | 39 ++++++++++++++++++++++----------------- {src => app}/main.f90 | 21 +++++++++++---------- param.in | 6 ++---- src/raffle.f90 | 4 ++++ 5 files changed, 60 insertions(+), 36 deletions(-) rename {src => app}/inputs.f90 (90%) rename {src => app}/main.f90 (84%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 284cab0d..340b7793 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ set( LIB_NAME ${PROJECT_NAME} ) set( PROJECT_DESCRIPTION "Fortran neural network" ) set( PROJECT_URL "https://github.com/nedtaylor/raffle" ) -set( CMAKE_CONFIGURATION_TYPES "Release" "Parallel" "Serial" "Dev" "Debug" "Parallel_Dev" +set( CMAKE_CONFIGURATION_TYPES "Release" "Parallel" "Serial" "Dev" "Debug" "Executable" CACHE STRING "List of configurations types." ) set( CMAKE_BUILD_TYPE "Release" CACHE STRING "Select which configuration to build." ) @@ -130,6 +130,17 @@ foreach(src ${SRC_FILES}) list(APPEND PREPENDED_SRC_FILES ${SRC_DIR}/${src}) endforeach() + +set(EXECUTABLE_FILES + inputs.f90 + main.f90 +) +set(APP_DIR app) +foreach(src ${EXECUTABLE_FILES}) + list(APPEND PREPENDED_EXECUTABLE_FILES ${APP_DIR}/${src}) +endforeach() + + message(STATUS "Modified SRC_FILES: ${PREPENDED_SRC_FILES}") # initialise flags @@ -206,8 +217,6 @@ target_compile_options(${PROJECT_NAME} PUBLIC "$<$:${OPTIMFLAGS target_compile_options(${PROJECT_NAME} PUBLIC "$<$:${MPFLAGS}>") target_compile_options(${PROJECT_NAME} PUBLIC "$<$:${DEVFLAGS}>") target_compile_options(${PROJECT_NAME} PUBLIC "$<$:${DEBUGFLAGS}>") -target_compile_options(${PROJECT_NAME} PUBLIC "$<$:${MPFLAGS}>") -target_compile_options(${PROJECT_NAME} PUBLIC "$<$:${DEVFLAGS}>") target_compile_options(${PROJECT_NAME} PUBLIC "$<$:${PYTHONFLAGS}>") @@ -216,7 +225,12 @@ if (CMAKE_BUILD_TYPE MATCHES "Debug*" OR CMAKE_BUILD_TYPE MATCHES "Dev*") append_coverage_compiler_flags() endif() - +if (CMAKE_BUILD_TYPE MATCHES "Executable*") + add_executable(raffle_executable ${PREPENDED_EXECUTABLE_FILES}) + target_link_libraries(raffle_executable PRIVATE ${PROJECT_NAME}) + install(TARGETS raffle_executable DESTINATION bin) + set_target_properties(raffle_executable PROPERTIES Fortran_MODULE_DIRECTORY ${MODULE_DIR}) +endif() @@ -323,4 +337,6 @@ message(STATUS " Output library: ${PROJECT_NAME}") -target_link_libraries(raffle ${ATHENA_LIBRARY}) \ No newline at end of file +if(ENABLE_ATHENA) + target_link_libraries(raffle ${ATHENA_LIBRARY}) +endif() \ No newline at end of file diff --git a/src/inputs.f90 b/app/inputs.f90 similarity index 90% rename from src/inputs.f90 rename to app/inputs.f90 index 28637115..5e796a60 100644 --- a/src/inputs.f90 +++ b/app/inputs.f90 @@ -7,18 +7,18 @@ !!!############################################################################# module inputs use misc_raffle, only: file_check,flagmaker, icount, to_lower - use constants, only: real12, ierror, pi + use generator, only: stoichiometry_type + use constants, only: real12, verbose, pi implicit none private - public :: verbose public :: vdW, volvar public :: bins, vps_ratio public :: seed public :: num_structures, num_species, task - public :: stoichiometry_list, element_list + public :: stoich public :: filename_host public :: database_format, database_list public :: cutoff_min_list, cutoff_max_list, width_list, sigma_list @@ -28,13 +28,11 @@ module inputs logical :: lseed - integer :: verbose = 0 integer :: seed !random seed integer :: num_structures ! number of structures to generate integer :: num_species ! total number of species to add integer :: task ! task setting (defines the RAFFLE task) - integer, allocatable, dimension(:) :: stoichiometry_list ! stoichiometry of species to add - character(3), allocatable, dimension(:) :: element_list !species names to add + type(stoichiometry_type), dimension(:), allocatable :: stoich ! stoichiometry of species to add integer :: vdW, volvar @@ -112,7 +110,7 @@ subroutine set_global_vars() elseif(index(buffer,'-v').eq.1)then flag="-v" call flagmaker(buffer,flag,i,skip,empty) - if(.not.empty) read(buffer,*) ierror + if(.not.empty) read(buffer,*) verbose elseif(index(buffer,'-h').eq.1)then write(6,'("Flags:")') write(6,'(2X,"-h : Prints the help for each flag.")') @@ -160,11 +158,13 @@ subroutine read_input_file(file_name) character(*), intent(in) :: file_name integer :: i - integer :: Reason,unit + integer :: Reason,unit, l_pos, r_pos character(1) :: fs - character(1024) :: stoichiometry, elements, database + character(1024) :: stoichiometry, elements, database, buffer real(real12), dimension(3) :: width, sigma character(50), dimension(3) :: cutoff_min, cutoff_max + integer, allocatable, dimension(:) :: stoichiometry_list + character(3), allocatable, dimension(:) :: element_list !!!----------------------------------------------------------------------------- @@ -172,7 +172,7 @@ subroutine read_input_file(file_name) !!!----------------------------------------------------------------------------- namelist /setup/ task, filename_host, seed, vps_ratio, bins, & database_format, database - namelist /structure/ num_structures,num_species,elements,stoichiometry + namelist /structure/ num_structures,stoichiometry namelist /volume/ vdW, volvar namelist /distribution/ cutoff_min, cutoff_max, width, sigma @@ -216,13 +216,18 @@ subroutine read_input_file(file_name) if(trim(stoichiometry).ne."")then - allocate(stoichiometry_list(num_species)) - read(stoichiometry,*) stoichiometry_list - end if - - if(trim(elements).ne."")then - allocate(element_list(num_species)) - read(elements,*) element_list + num_species = icount(stoichiometry,",") + allocate(stoich(num_species)) + l_pos = scan(stoichiometry,"{") + r_pos = scan(stoichiometry,"}", back=.true.) + do i = 1, num_species + read(stoichiometry(l_pos+1:r_pos-1),*) buffer + read(buffer(:scan(buffer,":")-1),*) stoich(i)%element + read(buffer(scan(buffer,":")+1:),*) stoich(i)%num + l_pos = scan(stoichiometry(l_pos+1:),",") + l_pos + end do + else + stop "No stoichiometry specified" end if diff --git a/src/main.f90 b/app/main.f90 similarity index 84% rename from src/main.f90 rename to app/main.f90 index 3bb676ae..5262a2b1 100644 --- a/src/main.f90 +++ b/app/main.f90 @@ -2,13 +2,14 @@ program raffle use constants, only: real12 use inputs use read_structures, only: get_evolved_gvectors_from_data - use gen, only: generation - use evolver, only: gvector_container_type + use raffle, only: raffle_generator_type, gvector_container_type implicit none - type(gvector_container_type) :: gvector_container + ! type(gvector_container_type) :: gvector_container real(real12), dimension(3) :: method_probab + type(raffle_generator_type) :: generator + !!!----------------------------------------------------------------------------- @@ -49,11 +50,11 @@ program raffle !!!----------------------------------------------------------------------------- !!! read structures from the database and generate gvectors !!!----------------------------------------------------------------------------- - gvector_container = get_evolved_gvectors_from_data( & + generator%distributions = get_evolved_gvectors_from_data( & input_dir = database_list, & element_file = "elements.dat", & bond_file = "chem.in", & - element_list = element_list, & + element_list = stoich(:)%element, & file_format = database_format, & gvector_container_template = gvector_container_type(& width = width_list, & @@ -61,9 +62,9 @@ program raffle cutoff_min = cutoff_min_list, & cutoff_max = cutoff_max_list ) ) - call gvector_container%write_2body(file="2body.txt") - call gvector_container%write_3body(file="3body.txt") - call gvector_container%write_4body(file="4body.txt") + call generator%distributions%write_2body(file="2body.txt") + call generator%distributions%write_3body(file="3body.txt") + call generator%distributions%write_4body(file="4body.txt") !!!----------------------------------------------------------------------------- @@ -82,8 +83,8 @@ program raffle !!! generate random structures !!!----------------------------------------------------------------------------- write(*,*) "Generating structures" - call generation( gvector_container, num_structures, task, & - element_list, stoichiometry_list, & + call generator%generate( num_structures, & + stoich, & method_probab ) write(*,*) "Structures have been successfully generated and saved" diff --git a/param.in b/param.in index 35556d0e..9d0696dd 100644 --- a/param.in +++ b/param.in @@ -9,10 +9,8 @@ / &structure - num_structures=1, - num_species=2, - stoichiometry="2 1", - elements="C Mg" + num_structures=10, + stoichiometry="{C:2, Mg:1}", / &volume diff --git a/src/raffle.f90 b/src/raffle.f90 index d98a31db..507f71fc 100644 --- a/src/raffle.f90 +++ b/src/raffle.f90 @@ -1,9 +1,13 @@ module raffle + use constants, only: real12 use generator, only: raffle_generator_type + use evolver, only: gvector_container_type implicit none private + public :: real12 + public :: gvector_container_type public :: raffle_generator_type From d356f0a83e8595cbfca4ff61b861610fd8633d2a Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Mon, 22 Jul 2024 09:05:41 +0100 Subject: [PATCH 054/293] Change executable compilation to option --- CMakeLists.txt | 53 ++++++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 340b7793..8dc27f61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ set( LIB_NAME ${PROJECT_NAME} ) set( PROJECT_DESCRIPTION "Fortran neural network" ) set( PROJECT_URL "https://github.com/nedtaylor/raffle" ) -set( CMAKE_CONFIGURATION_TYPES "Release" "Parallel" "Serial" "Dev" "Debug" "Executable" +set( CMAKE_CONFIGURATION_TYPES "Release" "Parallel" "Serial" "Dev" "Debug" CACHE STRING "List of configurations types." ) set( CMAKE_BUILD_TYPE "Release" CACHE STRING "Select which configuration to build." ) @@ -39,18 +39,18 @@ enable_language(Fortran) # get the user's home directory set(HOME_DIR $ENV{HOME}) -# set coverage compiler flags -if (CMAKE_BUILD_TYPE MATCHES "Debug*" OR CMAKE_BUILD_TYPE MATCHES "Dev*") - list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") - set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) - if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") - include(CodeCoverage) - setup_target_for_coverage_gcovr_html( - NAME coverage - EXECUTABLE ctest - EXCLUDE "${PROJECT_SOURCE_DIR}/test/*") - endif() -endif() +# # set coverage compiler flags +# if (CMAKE_BUILD_TYPE MATCHES "Debug*" OR CMAKE_BUILD_TYPE MATCHES "Dev*") +# list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") +# set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) +# if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") +# include(CodeCoverage) +# setup_target_for_coverage_gcovr_html( +# NAME coverage +# EXECUTABLE ctest +# EXCLUDE "${PROJECT_SOURCE_DIR}/test/*") +# endif() +# endif() # set the output directories set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) @@ -63,6 +63,7 @@ option(BUILD_TESTS "Build the unit tests" ON) option(BUILD_EXAMPLES "Build the examples" ON) option(ENABLE_ATHENA "Build energetic predictions with ATHENA" OFF) option(BUILD_PYTHON "Build the python library" On) +option(BUILD_EXECUTABLE "Build the Fortran executable" On) # Define the sources set(SRC_DIR src) @@ -220,16 +221,22 @@ target_compile_options(${PROJECT_NAME} PUBLIC "$<$:${DEBUGFLAGS}>" target_compile_options(${PROJECT_NAME} PUBLIC "$<$:${PYTHONFLAGS}>") -# add coverage compiler flags -if (CMAKE_BUILD_TYPE MATCHES "Debug*" OR CMAKE_BUILD_TYPE MATCHES "Dev*") - append_coverage_compiler_flags() -endif() - -if (CMAKE_BUILD_TYPE MATCHES "Executable*") - add_executable(raffle_executable ${PREPENDED_EXECUTABLE_FILES}) - target_link_libraries(raffle_executable PRIVATE ${PROJECT_NAME}) - install(TARGETS raffle_executable DESTINATION bin) - set_target_properties(raffle_executable PROPERTIES Fortran_MODULE_DIRECTORY ${MODULE_DIR}) +# # add coverage compiler flags +# if (CMAKE_BUILD_TYPE MATCHES "Debug*" OR CMAKE_BUILD_TYPE MATCHES "Dev*") +# append_coverage_compiler_flags() +# endif() + +if (BUILD_EXECUTABLE) + add_executable(${PROJECT_NAME}_executable ${PREPENDED_EXECUTABLE_FILES}) + target_link_libraries(${PROJECT_NAME}_executable PRIVATE ${PROJECT_NAME}) + install(TARGETS ${PROJECT_NAME}_executable DESTINATION bin) + set_target_properties(${PROJECT_NAME}_executable PROPERTIES Fortran_MODULE_DIRECTORY ${MODULE_DIR}) + target_compile_options(${PROJECT_NAME}_executable PUBLIC "$<$:${OPTIMFLAGS}>") + target_compile_options(${PROJECT_NAME}_executable PUBLIC "$<$:${OPTIMFLAGS}>") + target_compile_options(${PROJECT_NAME}_executable PUBLIC "$<$:${MPFLAGS}>") + target_compile_options(${PROJECT_NAME}_executable PUBLIC "$<$:${DEVFLAGS}>") + target_compile_options(${PROJECT_NAME}_executable PUBLIC "$<$:${DEBUGFLAGS}>") + target_compile_options(${PROJECT_NAME}_executable PUBLIC "$<$:${PYTHONFLAGS}>") endif() From cb71823b01381cca6029e57b02980d39c8c4da86 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Mon, 22 Jul 2024 09:53:11 +0100 Subject: [PATCH 055/293] Add structure printing --- app/inputs.f90 | 5 ++++- app/main.f90 | 32 +++++++++++++++++++++++++++++--- src/lib/mod_generator.f90 | 11 ++++++++++- src/lib/mod_misc.f90 | 2 +- 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/app/inputs.f90 b/app/inputs.f90 index 5e796a60..6400be5b 100644 --- a/app/inputs.f90 +++ b/app/inputs.f90 @@ -22,6 +22,7 @@ module inputs public :: filename_host public :: database_format, database_list public :: cutoff_min_list, cutoff_max_list, width_list, sigma_list + public :: output_dir public :: set_global_vars @@ -45,6 +46,7 @@ module inputs character(1024), dimension(:), allocatable :: database_list ! list of directories containing input database character(1024) :: database_format !format of input file (POSCAR, XYZ, etc. character(1024) :: filename_host !host structure filename + character(1024) :: output_dir !output directory !!!updated 2023/06/16 @@ -171,7 +173,7 @@ subroutine read_input_file(file_name) !!! set up namelists for input file !!!----------------------------------------------------------------------------- namelist /setup/ task, filename_host, seed, vps_ratio, bins, & - database_format, database + database_format, database, verbose, output_dir namelist /structure/ num_structures,stoichiometry namelist /volume/ vdW, volvar namelist /distribution/ cutoff_min, cutoff_max, width, sigma @@ -184,6 +186,7 @@ subroutine read_input_file(file_name) call file_check(unit,file_name) + output_dir = "iteration1" cutoff_min = "-1.0" cutoff_max = "-1.0" width = -1._real12 diff --git a/app/main.f90 b/app/main.f90 index 5262a2b1..e7a5d29d 100644 --- a/app/main.f90 +++ b/app/main.f90 @@ -1,10 +1,15 @@ -program raffle +program raffle_program use constants, only: real12 + use misc_raffle, only: touch use inputs use read_structures, only: get_evolved_gvectors_from_data use raffle, only: raffle_generator_type, gvector_container_type + use rw_geom, only: geom_read, geom_write implicit none + integer :: i, unit + character(1024) :: buffer + ! type(gvector_container_type) :: gvector_container real(real12), dimension(3) :: method_probab @@ -79,6 +84,15 @@ program raffle method_probab +!!!----------------------------------------------------------------------------- +!!! set the host structure +!!!----------------------------------------------------------------------------- + open(newunit=unit, file=filename_host, status='old') + call geom_read(unit, generator%host) + close(unit) + generator%bins = bins + + !!!----------------------------------------------------------------------------- !!! generate random structures !!!----------------------------------------------------------------------------- @@ -86,6 +100,18 @@ program raffle call generator%generate( num_structures, & stoich, & method_probab ) - write(*,*) "Structures have been successfully generated and saved" + write(*,*) "Structures have been successfully generated" + + +!!!----------------------------------------------------------------------------- +!!! save generated structures +!!!----------------------------------------------------------------------------- + do i = 1, generator%num_structures + write(buffer,'(A,"/struc",I0.3)') trim(output_dir),i + call touch(buffer) + open(newunit = unit, file=trim(buffer)//"/POSCAR") + call geom_write(unit, generator%structures(i)) + close(unit) + end do -end program raffle \ No newline at end of file +end program raffle_program \ No newline at end of file diff --git a/src/lib/mod_generator.f90 b/src/lib/mod_generator.f90 index 6747d4c7..305116e5 100644 --- a/src/lib/mod_generator.f90 +++ b/src/lib/mod_generator.f90 @@ -164,8 +164,12 @@ subroutine generate(this, num_structures, & type(graph_type), dimension(1) :: graph #endif + + if(verbose.gt.0) write(*,*) "Setting method probabilities" if(present(method_probab)) method_probab_ = method_probab + + if(verbose.gt.0) write(*,*) "Allocating memory for structures" if(.not.allocated(this%structures))then allocate(this%structures(num_structures)) else @@ -175,7 +179,7 @@ subroutine generate(this, num_structures, & end if - + if(verbose.gt.0) write(*,*) "Setting up basis store" !!! THINK OF SOME WAY TO HANDLE THE HOST SEPARATELY !!! THAT CAN SIGNIFICANTLY REDUCE DATA USAGE num_insert_species = size(stoichiometry) @@ -183,6 +187,7 @@ subroutine generate(this, num_structures, & allocate(basis_store%spec(num_insert_species)) do i = 1, size(stoichiometry) basis_store%spec(i)%name = strip_null(stoichiometry(i)%element) + write(*,*) basis_store%spec(i)%name end do basis_store%spec(:)%num = stoichiometry(:)%num basis_store%natom = num_insert_atoms @@ -192,6 +197,7 @@ subroutine generate(this, num_structures, & do i = 1, basis_store%nspec allocate(basis_store%spec(i)%atom(basis_store%spec(i)%num,3), source = 0._real12) end do + if(.not.allocated(this%host%spec)) stop "Host structure not set" basis_store = bas_merge(this%host,basis_store) basis_store%lat = this%host%lat @@ -203,6 +209,7 @@ subroutine generate(this, num_structures, & !! ... the second dimension is the index of the species and atom in the !! ... basis_store !!-------------------------------------------------------------------------- + if(verbose.gt.0) write(*,*) "Generating placement list" allocate(placement_list(num_insert_atoms,2)) k = 0 spec_loop1: do i = 1, basis_store%nspec @@ -234,10 +241,12 @@ subroutine generate(this, num_structures, & !!-------------------------------------------------------------------------- !! generate the structures !!-------------------------------------------------------------------------- + if(verbose.gt.0) write(*,*) "Entering structure generation loop" num_structures_old = this%num_structures num_structures_new = this%num_structures + num_structures structure_loop: do istructure = num_structures_old + 1, num_structures_new + if(verbose.gt.0) write(*,*) "Generating structure", istructure this%structures(istructure) = this%generate_structure( basis_store, & placement_list, method_probab_ ) this%num_structures = istructure diff --git a/src/lib/mod_misc.f90 b/src/lib/mod_misc.f90 index 11e61ea5..2bcdb4d4 100644 --- a/src/lib/mod_misc.f90 +++ b/src/lib/mod_misc.f90 @@ -1094,7 +1094,7 @@ subroutine touch(file) logical :: exists inquire(file=file, exist=exists) - if(.not.exists) call execute_command_line("mkdir "//file) + if(.not.exists) call execute_command_line("mkdir -p "//file) end subroutine touch !!!##################################################### From 65975598450e3687d989ab13598bdf767c638db0 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Mon, 22 Jul 2024 11:02:18 +0100 Subject: [PATCH 056/293] Fix coordinate conversion between ASE --- src/raffle/raffle.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/raffle/raffle.py b/src/raffle/raffle.py index 67a79e4b..971c3bc7 100644 --- a/src/raffle/raffle.py +++ b/src/raffle/raffle.py @@ -267,11 +267,10 @@ def toase(self): positions.append(self.spec[i].atom[j]) # Set the atoms - atoms = Atoms(species_string, positions) - atoms.set_pbc(self.pbc) - - # Set the lattice vectors - atoms.set_cell(self.lat) + if(self.lcart): + atoms = Atoms(species_string, positions=positions, cell=self.lat, pbc=self.pbc) + else: + atoms = Atoms(species_string, scaled_positions=positions, cell=self.lat, pbc=self.pbc) return atoms @@ -300,7 +299,7 @@ def fromase(self, atoms): # Set the species list species_count = [] atom_positions = [] - positions = atoms.get_positions() + positions = atoms.get_scaled_positions() for species in species_symbols_unique: species_count.append(sum([1 for symbol in species_symbols if symbol == species])) for j, symbol in enumerate(species_symbols): @@ -308,6 +307,7 @@ def fromase(self, atoms): atom_positions.append(positions[j]) # Allocate memory for the atom list + self.lcart = False self.allocate_species(species_symbols=species_symbols_unique, species_count=species_count, positions=atom_positions) @property From 0894bad82b5103aa94eeb41054eb61a021879908 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Mon, 22 Jul 2024 13:10:47 +0100 Subject: [PATCH 057/293] Improve documentation --- src/lib/mod_generator.f90 | 215 +++++++++++++++++++++++++------------- 1 file changed, 142 insertions(+), 73 deletions(-) diff --git a/src/lib/mod_generator.f90 b/src/lib/mod_generator.f90 index 305116e5..c8af1bee 100644 --- a/src/lib/mod_generator.f90 +++ b/src/lib/mod_generator.f90 @@ -1,10 +1,15 @@ module generator + !! Module for generating random structures from host structures. + !! + !! This module contains the raffle generator type, which is used to generate + !! random structures from a host structure. The raffle generator uses + !! distribution functions to determine the placement of atoms in the + !! provided host structure. use constants, only: real12 use misc_raffle, only: strip_null use rw_geom, only: bas_type use evolver, only: gvector_container_type - use constants, only: verbose use misc_raffle, only: shuffle use rw_geom, only: clone_bas @@ -26,27 +31,47 @@ module generator type :: stoichiometry_type + !! Type for storing the stoichiometry of atoms to be placed in the host + !! structure. character(len=3) :: element + !! Element symbol. integer :: num + !! Number of atoms. end type stoichiometry_type type :: raffle_generator_type + !! Type for instance of raffle generator. + !! + !! This type contains the parameters and methods for generating random + !! structures from a host structure, using the RAFFLE method. integer :: num_structures = 0 + !! Number of structures generated. Initialised to zero. type(bas_type) :: host + !! Host structure. integer, dimension(3) :: bins + !! Number of bins to divide the host structure into along each axis. type(gvector_container_type) :: distributions + !! Distribution function container for the 2-, 3-, and 4-body interactions. real(real12), dimension(3) :: method_probab + !! Probability of each placement method. type(bas_type), dimension(:), allocatable :: structures + !! Generated structures. contains procedure, pass(this) :: set_host + !! Procedure to set the host structure. procedure, pass(this) :: generate - procedure, pass(this) :: generate_structure + !! Procedure to generate random structures. + procedure, pass(this), private :: generate_structure + !! Procedure to generate a single random structure. procedure, pass(this) :: get_structures + !! Procedure to return the generated structures. procedure, pass(this) :: evaluate + !! Procedure to evaluate the viability of a structure. end type raffle_generator_type interface raffle_generator_type + !! Constructor for the raffle generator type. module function init_raffle_generator( & host, & width, sigma, cutoff_min, cutoff_max) result(generator) @@ -59,29 +84,8 @@ module function init_raffle_generator( & end function init_raffle_generator end interface raffle_generator_type -! interface -! module subroutine generate( this, & -! num_structures, stoichiometry, method_probab ) -! class(raffle_generator_type), intent(inout) :: this -! integer, intent(in) :: num_structures -! type(stoichiometry_type), dimension(:), intent(in) :: stoichiometry -! real(real12), dimension(:), intent(in), optional :: method_probab -! end subroutine generate - -! module function generate_structure( & -! this, & -! basis_initial, & -! placement_list, method_probab ) result(basis) -! class(raffle_generator_type), intent(in) :: this -! type(bas_type), intent(in) :: basis_initial -! integer, dimension(:,:), intent(in) :: placement_list -! real(real12), dimension(3) :: method_probab -! type(bas_type) :: basis -! end function generate_structure -! end interface - - - contains + +contains module function init_raffle_generator( & host, width, sigma, cutoff_min, cutoff_max ) & @@ -89,6 +93,7 @@ module function init_raffle_generator( & !! Initialise an instance of the raffle generator. !! Set up run-independent parameters. implicit none + ! Arguments type(bas_type), intent(in), optional :: host !! Basis of the host structure. @@ -103,9 +108,15 @@ module function init_raffle_generator( & real(real12), dimension(3), intent(in), optional :: cutoff_max !! Maximum cutoff for the 2-, 3-, and 4-body distribution functions. + ! Local variables type(raffle_generator_type) :: generator + !! Instance of the raffle generator. + ! Handle optional arguments + ! Set up the host structure if(present(host)) call generator%set_host(host) + + ! Set up the distribution function parameters if( present(width) ) & call generator%distributions%set_width(width) if( present(sigma) ) & @@ -132,9 +143,10 @@ end subroutine set_host subroutine generate(this, num_structures, & - stoichiometry, method_probab) + stoichiometry, method_probab, seed) !! Generate random structures. implicit none + ! Arguments class(raffle_generator_type), intent(inout) :: this !! Instance of the raffle generator. @@ -144,31 +156,60 @@ subroutine generate(this, num_structures, & !! Stoichiometry of the structures to generate. real(real12), dimension(:), intent(in), optional :: method_probab !! Probability of each placement method. - - type(bas_type) :: basis, basis_store - type(bas_type), dimension(:), allocatable :: tmp_structures - - integer, dimension(:,:), allocatable :: placement_list, placement_list_shuffled - - integer :: i, j, k - integer :: istructure, num_structures_old, num_structures_new - integer :: unit, info_unit, structure_unit + integer, intent(in), optional :: seed + !! Seed for the random number generator. + + ! Local variables + integer :: i, j, k, istructure, num_structures_old, num_structures_new + !! Loop counters. + integer :: num_seed + !! Number of seeds for the random number generator. integer :: num_insert_atoms, num_insert_species + !! Number of atoms and species to insert (from stoichiometry). + logical :: success + !! Boolean comparison of element symbols. + type(bas_type) :: basis_template + !! Basis of the structure to generate (i.e. allocated species and atoms). + real(real12), dimension(3) :: & + method_probab_ = [0.33_real12, 0.66_real12, 1.0_real12] + !! Default probability of each placement method. + + integer, dimension(:), allocatable :: seed_arr + !! Array of seeds for the random number generator. + type(bas_type), dimension(:), allocatable :: tmp_structures + !! Temporary array of structures (for memory reallocation). - logical :: placed, success - character(1024) :: buffer + integer, dimension(:,:), allocatable :: placement_list + !! List of possible atoms to place in the structure. - real(real12), dimension(3) :: method_probab_ = [0.33_real12, 0.66_real12, 1.0_real12] #ifdef ENABLE_ATHENA type(graph_type), dimension(1) :: graph + !! Graph for machine learning. #endif + !--------------------------------------------------------------------------- + ! set the placement method probabilities + !--------------------------------------------------------------------------- if(verbose.gt.0) write(*,*) "Setting method probabilities" if(present(method_probab)) method_probab_ = method_probab + !--------------------------------------------------------------------------- + ! set the random seed + !--------------------------------------------------------------------------- + if(present(seed))then + call random_seed(size=num_seed) + allocate(seed_arr(num_seed)) + seed_arr = seed + call random_seed(put=seed_arr) + end if + + + !--------------------------------------------------------------------------- + ! allocate memory for structures + !--------------------------------------------------------------------------- if(verbose.gt.0) write(*,*) "Allocating memory for structures" if(.not.allocated(this%structures))then allocate(this%structures(num_structures)) @@ -179,56 +220,60 @@ subroutine generate(this, num_structures, & end if + !--------------------------------------------------------------------------- + ! set up the template basis for generated structures + !--------------------------------------------------------------------------- if(verbose.gt.0) write(*,*) "Setting up basis store" - !!! THINK OF SOME WAY TO HANDLE THE HOST SEPARATELY - !!! THAT CAN SIGNIFICANTLY REDUCE DATA USAGE num_insert_species = size(stoichiometry) num_insert_atoms = sum(stoichiometry(:)%num) - allocate(basis_store%spec(num_insert_species)) + allocate(basis_template%spec(num_insert_species)) do i = 1, size(stoichiometry) - basis_store%spec(i)%name = strip_null(stoichiometry(i)%element) - write(*,*) basis_store%spec(i)%name + basis_template%spec(i)%name = strip_null(stoichiometry(i)%element) + write(*,*) basis_template%spec(i)%name end do - basis_store%spec(:)%num = stoichiometry(:)%num - basis_store%natom = num_insert_atoms - basis_store%nspec = num_insert_species - basis_store%sysname = "inserts" - - do i = 1, basis_store%nspec - allocate(basis_store%spec(i)%atom(basis_store%spec(i)%num,3), source = 0._real12) + basis_template%spec(:)%num = stoichiometry(:)%num + basis_template%natom = num_insert_atoms + basis_template%nspec = num_insert_species + basis_template%sysname = "inserts" + + do i = 1, basis_template%nspec + allocate( & + basis_template%spec(i)%atom(basis_template%spec(i)%num,3), & + source = 0._real12 & + ) end do if(.not.allocated(this%host%spec)) stop "Host structure not set" - basis_store = bas_merge(this%host,basis_store) - basis_store%lat = this%host%lat + basis_template = bas_merge(this%host,basis_template) + basis_template%lat = this%host%lat - !!-------------------------------------------------------------------------- - !! generate the placement list - !! placement list is the list of number of atoms of each species that can be - !! placed in the structure - !! ... the second dimension is the index of the species and atom in the - !! ... basis_store - !!-------------------------------------------------------------------------- + !--------------------------------------------------------------------------- + ! generate the placement list + ! placement list is the list of number of atoms of each species that can be + ! placed in the structure + ! ... the second dimension is the index of the species and atom in the + ! ... basis_template + !--------------------------------------------------------------------------- if(verbose.gt.0) write(*,*) "Generating placement list" allocate(placement_list(num_insert_atoms,2)) k = 0 - spec_loop1: do i = 1, basis_store%nspec + spec_loop1: do i = 1, basis_template%nspec success = .false. do j = 1, size(stoichiometry) if( & - trim(basis_store%spec(i)%name) .eq. & + trim(basis_template%spec(i)%name) .eq. & trim(strip_null(stoichiometry(j)%element))) & success = .true. end do if(.not.success) cycle if(i.gt.this%host%nspec)then - do j = 1, basis_store%spec(i)%num + do j = 1, basis_template%spec(i)%num k = k + 1 placement_list(k,1) = i placement_list(k,2) = j end do else - do j = 1, basis_store%spec(i)%num + do j = 1, basis_template%spec(i)%num if(j.le.this%host%spec(i)%num) cycle k = k + 1 placement_list(k,1) = i @@ -238,23 +283,23 @@ subroutine generate(this, num_structures, & end do spec_loop1 - !!-------------------------------------------------------------------------- - !! generate the structures - !!-------------------------------------------------------------------------- + !--------------------------------------------------------------------------- + ! generate the structures + !--------------------------------------------------------------------------- if(verbose.gt.0) write(*,*) "Entering structure generation loop" num_structures_old = this%num_structures num_structures_new = this%num_structures + num_structures structure_loop: do istructure = num_structures_old + 1, num_structures_new if(verbose.gt.0) write(*,*) "Generating structure", istructure - this%structures(istructure) = this%generate_structure( basis_store, & + this%structures(istructure) = this%generate_structure( basis_template, & placement_list, method_probab_ ) this%num_structures = istructure #ifdef ENABLE_ATHENA - !!----------------------------------------------------------------------- - !! predict energy using ML - !!----------------------------------------------------------------------- + !------------------------------------------------------------------------ + ! predict energy using ML + !------------------------------------------------------------------------ graph(1) = get_graph_from_basis(this%structures(istructure)) write(*,*) "Predicted energy", network_predict_graph(graph(1:1)) #endif @@ -272,6 +317,7 @@ module function generate_structure( & placement_list, method_probab ) result(basis) !! Generate a single random structure. implicit none + ! Arguments class(raffle_generator_type), intent(in) :: this !! Instance of the raffle generator. @@ -284,30 +330,53 @@ module function generate_structure( & type(bas_type) :: basis !! Generated basis. + ! Local variables integer :: i, j, iplaced, void_ticker + !! Loop counters. integer :: num_insert_atoms + !! Number of atoms to insert. real(real12) :: rtmp1 + !! Random number. logical :: placed + !! Boolean for successful placement. integer, dimension(size(placement_list,1),size(placement_list,2)) :: & placement_list_shuffled + !! Shuffled placement list. real(real12), dimension(3) :: method_probab_ + !! Temporary probability of each placement method. + !! This is used to update the probability of the SCAN method if no viable + !! gridpoints are found. real(real12), dimension(:,:), allocatable :: viable_gridpoints + !! Viable gridpoints for placing atoms. - + !--------------------------------------------------------------------------- + ! initialise the basis + !--------------------------------------------------------------------------- call clone_bas(basis_initial, basis) num_insert_atoms = basis%natom - this%host%natom + + !--------------------------------------------------------------------------- + ! shuffle the placement list + !--------------------------------------------------------------------------- placement_list_shuffled = placement_list call shuffle(placement_list_shuffled,1) !!! NEED TO SORT OUT RANDOM SEED + + !--------------------------------------------------------------------------- + ! check for viable gridpoints + !--------------------------------------------------------------------------- viable_gridpoints = get_viable_gridpoints( this%bins, & basis, & [ this%distributions%bond_info(:)%radius_covalent ], & placement_list_shuffled ) - method_probab_ = method_probab + !--------------------------------------------------------------------------- + ! place the atoms + !--------------------------------------------------------------------------- + method_probab_ = method_probab iplaced = 0 void_ticker = 0 placement_loop: do while (iplaced.lt.num_insert_atoms) @@ -402,6 +471,7 @@ function evaluate(this, basis) result(viability) stop "Not yet set up" end function evaluate + subroutine allocate_structures(this, num_structures) !! Allocate memory for the generated structures. implicit none @@ -416,5 +486,4 @@ subroutine allocate_structures(this, num_structures) this%num_structures = num_structures end subroutine allocate_structures - end module generator \ No newline at end of file From b503763bea4b4b87ce0db7d5903741f3e41425c8 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Mon, 22 Jul 2024 13:37:11 +0100 Subject: [PATCH 058/293] Improve documentation --- src/lib/mod_atom_adder.f90 | 264 +++++++++++++++++++++++++------------ src/lib/mod_generator.f90 | 17 ++- 2 files changed, 194 insertions(+), 87 deletions(-) diff --git a/src/lib/mod_atom_adder.f90 b/src/lib/mod_atom_adder.f90 index 127e84fd..1cc4f901 100644 --- a/src/lib/mod_atom_adder.f90 +++ b/src/lib/mod_atom_adder.f90 @@ -1,4 +1,11 @@ module add_atom + !! Module to add atoms to a cell. + !! + !! This module contains subroutines to add atoms to a cell using different + !! placement methods. The methods are: + !! - scan: place the atom at the gridpoint with the highest suitability + !! - void: place the atom in the gridpoint with the largest void space + !! - pseudo: place the atom using a pseudo-random walk method use constants, only: real12 use misc_linalg, only: modu use rw_geom, only: bas_type @@ -16,29 +23,43 @@ module add_atom contains - -!!!############################################################################# -!!! add atom to unit cell using the scan method -!!!############################################################################# - subroutine add_atom_scan (gridpoints, gvector_container, & +!############################################################################### + subroutine add_atom_scan(gridpoints, gvector_container, & basis, atom_ignore_list, & radius_list, placed) + !! SCAN placement method. + !! + !! This method places the atom at the gridpoint with the highest + !! suitability. implicit none + + ! Arguments type(gvector_container_type), intent(in) :: gvector_container + !! Distribution function (gvector) container. type(bas_type), intent(inout) :: basis + !! Structure to add atom to. logical, intent(out) :: placed + !! Boolean to indicate if atom was placed. integer, dimension(:,:), intent(in) :: atom_ignore_list + !! List of atoms to ignore (i.e. indices of atoms not yet placed). real(real12), dimension(:,:), intent(in) :: gridpoints + !! List of gridpoints to consider. real(real12), dimension(:) :: radius_list + !! List of radii for each element. - integer :: el_correct_read,i, j, k,n,l + ! Local variables + integer :: i + !! Loop indices. integer :: best_gridpoint - real(real12), dimension(3) :: tmpvector + !! Index of best gridpoint. real(real12), dimension(:), allocatable :: suitability_grid + !! Suitability of each gridpoint. + !--------------------------------------------------------------------------- + ! run buildmap_point for a set of points in the unit cell + !--------------------------------------------------------------------------- placed = .false. - !! run buildmap_point for a set of points in the unit cell allocate(suitability_grid(size(gridpoints,dim=2))) do concurrent( i = 1:size(gridpoints,dim=2) ) suitability_grid(i) = buildmap_POINT( gvector_container, & @@ -58,28 +79,44 @@ subroutine add_atom_scan (gridpoints, gvector_container, & basis%spec(atom_ignore_list(1,1))%atom(atom_ignore_list(1,2),:) = & gridpoints(:,best_gridpoint) - end subroutine add_atom_scan -!!!############################################################################# + end subroutine add_atom_scan +!############################################################################### - -!!!############################################################################# -!!! add atom to unit cell considering the void space -!!!############################################################################# - subroutine add_atom_void (bin_size, basis, atom_ignore_list, placed) + +!############################################################################### + subroutine add_atom_void(bin_size, basis, atom_ignore_list, placed) + !! VOID placement method. + !! + !! This method returns the gridpoint with the lowest neighbour density. + !! i.e. the point with the lowest density in the cell. implicit none + + ! Arguments type(bas_type), intent(inout) :: basis + !! Structure to add atom to. integer, dimension(3), intent(in) :: bin_size + !! Number of gridpoints in each direction. integer, dimension(:,:), intent(in) :: atom_ignore_list + !! List of atoms to ignore (i.e. indices of atoms not yet placed). logical, intent(out) :: placed + !! Boolean to indicate if atom was placed. - integer :: i, j, k, l + ! Local variables + integer :: i, j, k + !! Loop indices. real(real12), dimension(3) :: best_location - real(real12) :: best_location_bond, smallest_bond, comparison + !! Index of best location to place atom. + real(real12) :: best_location_bond, smallest_bond + !! Bond lengths. real(real12), dimension(3) :: tmpvector + !! Temporary vector for gridpoint. - - best_location_bond = -huge(1._real12) + !--------------------------------------------------------------------------- + ! loop over all gridpoints in the unit cell and find the one with the ... + ! ... largest void space + !--------------------------------------------------------------------------- + best_location_bond = -huge(1._real12) do i = 0, bin_size(1) - 1, 1 do j = 0, bin_size(2) - 1, 1 do k = 0, bin_size(3) - 1, 1 @@ -100,44 +137,63 @@ subroutine add_atom_void (bin_size, basis, atom_ignore_list, placed) placed = .true. end subroutine add_atom_void -!!!############################################################################# +!############################################################################### -!!!############################################################################# -!!! add atom to unit cell using a pseudo-random walk method -!!!############################################################################# - subroutine add_atom_pseudo (bin_size, gvector_container, & +!############################################################################### + subroutine add_atom_pseudo ( gvector_container, & basis, atom_ignore_list, & radius_list, placed) + !! PSEUDO randomwalk placement method. + !! + !! This method places the atom using a pseudo-random walk method. + !! An initial point is chosen at random, and then points nearby are tested + !! to see if they are more suitable than the current point. If they are, + !! the query point is moved to the new point and the process is repeated. + !! The process is repeated, with each point being tested against a random + !! number. If the random number is less than the suitability of the point, + !! the atom is placed at that point. implicit none + + ! Arguments type(gvector_container_type), intent(in) :: gvector_container + !! Distribution function (gvector) container. type(bas_type), intent(inout) :: basis + !! Structure to add atom to. logical, intent(out) :: placed + !! Boolean to indicate if atom was placed. integer, dimension(:,:), intent(in) :: atom_ignore_list - integer, dimension(3), intent(in) :: bin_size + !! List of atoms to ignore (i.e. indices of atoms not yet placed). real(real12), dimension(:), intent(in) :: radius_list + !! List of radii for each element. + ! Local variables integer :: i, j, k, l - real(real12) :: rtmp1, crude_norm + !! Loop indices. + real(real12) :: rtmp1 + !! Random number. + integer :: crude_norm + !! Crude normalisation. real(real12) :: calculated_value, calculated_test + !! Viability values. real(real12), dimension(3) :: tmpvector, testvector + !! Vectors for gridpoints. - !! test a random point in the unit cell + !--------------------------------------------------------------------------- + ! test a random point in the unit cell + !--------------------------------------------------------------------------- i = 0 placed = .false. crude_norm = 0._real12 100 random_loop : do i = i + 1 - ! write(*,'(A)',ADVANCE='NO') achar(13) - ! write(*,'(I5.0, A)', ADVANCE='NO') i !call random_number(rtmp1) !tmpvector = gridpoints(:,floor(rtmp1*size(gridpoints,dim=2))+1) do j = 1, 3 call random_number(rtmp1) tmpvector(j) = rtmp1 - !tmpvector(j) = tmpvector(j) + (rtmp1 * 2._real12 - 1._real12 ) / bin_size(j) end do calculated_value = buildmap_POINT( gvector_container, & @@ -152,8 +208,12 @@ subroutine add_atom_pseudo (bin_size, gvector_container, & if(i.ge.10000) return end do random_loop + + !--------------------------------------------------------------------------- + ! now do a pseudo-random walk to find a suitable point to place the atom + !--------------------------------------------------------------------------- + k = 0 l = 0 - !! if we have found a point, we can now walk around it walk_loop : do do j=1, 3 call random_number(rtmp1) @@ -184,7 +244,7 @@ subroutine add_atom_pseudo (bin_size, gvector_container, & placed = .TRUE. exit walk_loop end if - if(k.gt.10) then + if(k.ge.10) then calculated_value = calculated_value / crude_norm if (rtmp1.lt.calculated_value) then placed = .TRUE. @@ -216,79 +276,113 @@ subroutine add_atom_pseudo (bin_size, gvector_container, & basis%spec(atom_ignore_list(1,1))%atom(atom_ignore_list(1,2),:) = tmpvector end subroutine add_atom_pseudo -!!!############################################################################# +!############################################################################### -!!!############################################################################# -!!! get the viable gridpoints for adding an atom -!!! i.e. only return gridpoints that are not too close to an existing atom -!!!############################################################################# +!############################################################################### function get_viable_gridpoints(bin_size, basis, & radius_list, atom_ignore_list) result(points) - implicit none - type(bas_type), intent(in) :: basis - integer, dimension(3), intent(in) :: bin_size - integer, dimension(:,:), intent(in) :: atom_ignore_list - real(real12), dimension(:), intent(in) :: radius_list - - integer, dimension(:), allocatable :: pair_index - real(real12), dimension(:,:), allocatable :: points_tmp, points + !! Get the viable gridpoints for adding an atom. + !! + !! This function returns a list of gridpoints that are not too close to an + !! existing atom. + implicit none - integer :: i, j, k, l, is, ia, num_points + ! Arguments + type(bas_type), intent(in) :: basis + !! Structure to add atom to. + integer, dimension(3), intent(in) :: bin_size + !! Number of gridpoints in each direction. + integer, dimension(:,:), intent(in) :: atom_ignore_list + !! List of atoms to ignore (i.e. indices of atoms not yet placed). + real(real12), dimension(:), intent(in) :: radius_list + !! List of radii for each element. + + ! Local variables + integer, dimension(:), allocatable :: pair_index + !! List of element pair indices. + real(real12), dimension(:,:), allocatable :: points_tmp, points + !! List of gridpoints. + + ! Local variables + integer :: i, j, k, l, is, ia + !! Loop indices. + integer :: num_points + !! Number of gridpoints. - allocate(points_tmp(3,product(bin_size))) - - !! get list of element pair indices - allocate(pair_index(basis%nspec), source = 0) - do is = 1, basis%nspec - pair_index(is) = ( basis%nspec - is/2 ) * ( is - 1 ) + is - end do - - num_points = 0 - grid_loop1: do i = 0, bin_size(1) - 1, 1 - grid_loop2: do j = 0, bin_size(2) - 1, 1 - grid_loop3: do k = 0, bin_size(3) - 1, 1 - do is = 1, basis%nspec - do ia = 1, basis%spec(is)%num - do l = 1, size(atom_ignore_list,dim=1), 1 - if(all(atom_ignore_list(l,:).eq.[is,ia])) cycle - end do - if( get_min_dist_between_point_and_atom( & - basis, & - [i, j, k] / real(bin_size,real12), [is,ia] ) .lt. & - radius_list(pair_index(is)) * 0.95_real12 ) & - cycle grid_loop3 - end do - end do - num_points = num_points + 1 - points_tmp(:,num_points) = [i, j, k] / real(bin_size,real12) - end do grid_loop3 - end do grid_loop2 - end do grid_loop1 - allocate(points, source = points_tmp(:,:num_points)) - - deallocate(points_tmp, pair_index) + !--------------------------------------------------------------------------- + ! get list of element pair indices + !--------------------------------------------------------------------------- + allocate(pair_index(basis%nspec), source = 0) + do is = 1, basis%nspec + pair_index(is) = ( basis%nspec - is/2 ) * ( is - 1 ) + is + end do + + !--------------------------------------------------------------------------- + ! loop over all gridpoints in the unit cell and check if they are too ... + ! ... close to an existing atom. If they are, remove them from the list ... + ! ... of viable gridpoints + !--------------------------------------------------------------------------- + allocate(points_tmp(3,product(bin_size))) + num_points = 0 + grid_loop1: do i = 0, bin_size(1) - 1, 1 + grid_loop2: do j = 0, bin_size(2) - 1, 1 + grid_loop3: do k = 0, bin_size(3) - 1, 1 + do is = 1, basis%nspec + do ia = 1, basis%spec(is)%num + do l = 1, size(atom_ignore_list,dim=1), 1 + if(all(atom_ignore_list(l,:).eq.[is,ia])) cycle + end do + if( get_min_dist_between_point_and_atom( & + basis, & + [i, j, k] / real(bin_size,real12), [is,ia] ) .lt. & + radius_list(pair_index(is)) * 0.95_real12 ) & + cycle grid_loop3 + end do + end do + num_points = num_points + 1 + points_tmp(:,num_points) = [i, j, k] / real(bin_size,real12) + end do grid_loop3 + end do grid_loop2 + end do grid_loop1 + allocate(points, source = points_tmp(:,:num_points)) + + deallocate(points_tmp, pair_index) end function get_viable_gridpoints -!!!############################################################################# +!############################################################################### -!!!############################################################################# -!!! update the viable gridpoints for adding an atom -!!! i.e. remove gridpoints that are too close to an existing atom -!!!############################################################################# +!############################################################################### subroutine update_viable_gridpoints(points, basis, atom, radius) + !! Update the viable gridpoints after a new atom has been added. implicit none + + ! Arguments type(bas_type), intent(in) :: basis + !! Structure to add atom to. integer, dimension(2) :: atom + !! Index of atom to add. real(real12), dimension(:,:), allocatable, intent(inout) :: points + !! List of gridpoints. real(real12), intent(in) :: radius + !! Radius of added atom. - integer :: i, pair_index, num_points + ! Local variables + integer :: i + !! Loop indices. + integer :: num_points + !! Number of gridpoints. real(real12), dimension(:,:), allocatable :: points_tmp + !! Temporary list of gridpoints. + !--------------------------------------------------------------------------- + ! loop over all gridpoints in the unit cell and check if they are too ... + ! ... close to the new atom. If they are, remove them from the list of ... + ! ... viable gridpoints + !--------------------------------------------------------------------------- if(.not.allocated(points)) return num_points = size(points,dim=2) i = 0 @@ -312,6 +406,6 @@ subroutine update_viable_gridpoints(points, basis, atom, radius) deallocate(points_tmp) end subroutine update_viable_gridpoints -!!!############################################################################# +!############################################################################### end module add_atom \ No newline at end of file diff --git a/src/lib/mod_generator.f90 b/src/lib/mod_generator.f90 index c8af1bee..ce02f8ee 100644 --- a/src/lib/mod_generator.f90 +++ b/src/lib/mod_generator.f90 @@ -87,6 +87,7 @@ end function init_raffle_generator contains +!############################################################################### module function init_raffle_generator( & host, width, sigma, cutoff_min, cutoff_max ) & result(generator) @@ -127,8 +128,10 @@ module function init_raffle_generator( & call generator%distributions%set_cutoff_max(cutoff_max) end function init_raffle_generator +!############################################################################### +!############################################################################### subroutine set_host(this, host) !! Set the host structure. implicit none @@ -140,8 +143,10 @@ subroutine set_host(this, host) this%host = host end subroutine set_host +!############################################################################### +!############################################################################### subroutine generate(this, num_structures, & stoichiometry, method_probab, seed) !! Generate random structures. @@ -308,9 +313,10 @@ subroutine generate(this, num_structures, & write(*,*) "Finished generating structures" end subroutine generate +!############################################################################### - +!############################################################################### module function generate_structure( & this, & basis_initial, & @@ -391,7 +397,7 @@ module function generate_structure( & placement_list_shuffled(iplaced+1:,:), placed) else if(rtmp1.le.method_probab_(2)) then if(verbose.gt.0) write(*,*) "Add Atom Pseudo" - call add_atom_pseudo( this%bins, & + call add_atom_pseudo( & this%distributions, & basis, & placement_list_shuffled(iplaced+1:,:), & @@ -441,8 +447,10 @@ module function generate_structure( & if(allocated(viable_gridpoints)) deallocate(viable_gridpoints) end function generate_structure +!############################################################################### +!############################################################################### function get_structures(this) result(structures) !! Get the generated structures. implicit none @@ -454,8 +462,10 @@ function get_structures(this) result(structures) structures = this%structures end function get_structures +!############################################################################### +!############################################################################### function evaluate(this, basis) result(viability) !! Evaluate the viability of the generated structures. implicit none @@ -470,8 +480,10 @@ function evaluate(this, basis) result(viability) viability = 0.0_real12 stop "Not yet set up" end function evaluate +!############################################################################### +!############################################################################### subroutine allocate_structures(this, num_structures) !! Allocate memory for the generated structures. implicit none @@ -485,5 +497,6 @@ subroutine allocate_structures(this, num_structures) allocate(this%structures(num_structures)) this%num_structures = num_structures end subroutine allocate_structures +!############################################################################### end module generator \ No newline at end of file From ada7f9046d244cbdd54bce6d390ff30ecf692823 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Mon, 22 Jul 2024 13:50:47 +0100 Subject: [PATCH 059/293] Fix input file database string handling --- app/inputs.f90 | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/inputs.f90 b/app/inputs.f90 index 6400be5b..145e5cef 100644 --- a/app/inputs.f90 +++ b/app/inputs.f90 @@ -215,6 +215,14 @@ subroutine read_input_file(file_name) if(trim(database).ne."")then allocate(database_list(icount(database))) read(database,*) database_list + l_pos = 0 + do i = 1, size(database_list) + read(database(l_pos+1:),'(A)') buffer + r_pos = scan(buffer,",") + if(r_pos.eq.0) r_pos = len_trim(buffer) + read(buffer(:r_pos-1),'(A)') database_list(i) + l_pos = scan(database(l_pos+1:),",") + l_pos + end do end if From 2a63e954eee235c3d4067e4511aaccca11fd21b3 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Mon, 22 Jul 2024 14:12:15 +0100 Subject: [PATCH 060/293] Update ignore list --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index bc991905..13338161 100644 --- a/.gitignore +++ b/.gitignore @@ -4,8 +4,10 @@ bin/ obj/ *.mod *.smod +*.txt DTESTING/ DTEST/ build/ src/*.egg-info -*.egg-info \ No newline at end of file +*.egg-info +iteration* \ No newline at end of file From 4df7b3f69342960ae6d47666aee179cf79b09e31 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Mon, 22 Jul 2024 14:12:37 +0100 Subject: [PATCH 061/293] Convert placement methods to functions --- src/lib/mod_atom_adder.f90 | 76 +++++++++++++++++++------------------- src/lib/mod_generator.f90 | 45 +++++++++++----------- 2 files changed, 62 insertions(+), 59 deletions(-) diff --git a/src/lib/mod_atom_adder.f90 b/src/lib/mod_atom_adder.f90 index 1cc4f901..c107c533 100644 --- a/src/lib/mod_atom_adder.f90 +++ b/src/lib/mod_atom_adder.f90 @@ -3,9 +3,9 @@ module add_atom !! !! This module contains subroutines to add atoms to a cell using different !! placement methods. The methods are: - !! - scan: place the atom at the gridpoint with the highest suitability + !! - min: place the atom at the gridpoint with the highest suitability !! - void: place the atom in the gridpoint with the largest void space - !! - pseudo: place the atom using a pseudo-random walk method + !! - walk: place the atom using a pseudo-random walk method use constants, only: real12 use misc_linalg, only: modu use rw_geom, only: bas_type @@ -17,17 +17,17 @@ module add_atom private - public :: add_atom_scan, add_atom_void, add_atom_pseudo + public :: add_atom_min, add_atom_void, add_atom_walk public :: get_viable_gridpoints, update_viable_gridpoints contains !############################################################################### - subroutine add_atom_scan(gridpoints, gvector_container, & + function add_atom_min(gridpoints, gvector_container, & basis, atom_ignore_list, & - radius_list, placed) - !! SCAN placement method. + radius_list, viable) result(point) + !! MIN placement method. !! !! This method places the atom at the gridpoint with the highest !! suitability. @@ -38,14 +38,16 @@ subroutine add_atom_scan(gridpoints, gvector_container, & !! Distribution function (gvector) container. type(bas_type), intent(inout) :: basis !! Structure to add atom to. - logical, intent(out) :: placed - !! Boolean to indicate if atom was placed. + logical, intent(out) :: viable + !! Boolean to indicate if point is viable. integer, dimension(:,:), intent(in) :: atom_ignore_list !! List of atoms to ignore (i.e. indices of atoms not yet placed). real(real12), dimension(:,:), intent(in) :: gridpoints !! List of gridpoints to consider. real(real12), dimension(:) :: radius_list !! List of radii for each element. + real(real12), dimension(3) :: point + !! Point to add atom to. ! Local variables integer :: i @@ -59,7 +61,7 @@ subroutine add_atom_scan(gridpoints, gvector_container, & !--------------------------------------------------------------------------- ! run buildmap_point for a set of points in the unit cell !--------------------------------------------------------------------------- - placed = .false. + viable = .false. allocate(suitability_grid(size(gridpoints,dim=2))) do concurrent( i = 1:size(gridpoints,dim=2) ) suitability_grid(i) = buildmap_POINT( gvector_container, & @@ -72,19 +74,19 @@ subroutine add_atom_scan(gridpoints, gvector_container, & return end if - placed = .true. best_gridpoint = maxloc(suitability_grid, dim=1) deallocate(suitability_grid) - basis%spec(atom_ignore_list(1,1))%atom(atom_ignore_list(1,2),:) = & - gridpoints(:,best_gridpoint) + point = gridpoints(:,best_gridpoint) + viable = .true. - end subroutine add_atom_scan + end function add_atom_min !############################################################################### !############################################################################### - subroutine add_atom_void(bin_size, basis, atom_ignore_list, placed) + function add_atom_void(bin_size, basis, atom_ignore_list, viable) & + result(point) !! VOID placement method. !! !! This method returns the gridpoint with the lowest neighbour density. @@ -98,8 +100,10 @@ subroutine add_atom_void(bin_size, basis, atom_ignore_list, placed) !! Number of gridpoints in each direction. integer, dimension(:,:), intent(in) :: atom_ignore_list !! List of atoms to ignore (i.e. indices of atoms not yet placed). - logical, intent(out) :: placed - !! Boolean to indicate if atom was placed. + logical, intent(out) :: viable + !! Boolean to indicate if point is viable. + real(real12), dimension(3) :: point + !! Point to add atom to. ! Local variables integer :: i, j, k @@ -116,6 +120,7 @@ subroutine add_atom_void(bin_size, basis, atom_ignore_list, placed) ! loop over all gridpoints in the unit cell and find the one with the ... ! ... largest void space !--------------------------------------------------------------------------- + viable = .false. best_location_bond = -huge(1._real12) do i = 0, bin_size(1) - 1, 1 do j = 0, bin_size(2) - 1, 1 @@ -132,19 +137,18 @@ subroutine add_atom_void(bin_size, basis, atom_ignore_list, placed) end do end do - basis%spec(atom_ignore_list(1,1))%atom(atom_ignore_list(1,2),:) = & - best_location - placed = .true. + point = best_location + viable = .true. - end subroutine add_atom_void + end function add_atom_void !############################################################################### !############################################################################### - subroutine add_atom_pseudo ( gvector_container, & + function add_atom_walk ( gvector_container, & basis, atom_ignore_list, & - radius_list, placed) - !! PSEUDO randomwalk placement method. + radius_list, viable) result(point) + !! Pseudo-random walk placement method. !! !! This method places the atom using a pseudo-random walk method. !! An initial point is chosen at random, and then points nearby are tested @@ -160,12 +164,14 @@ subroutine add_atom_pseudo ( gvector_container, & !! Distribution function (gvector) container. type(bas_type), intent(inout) :: basis !! Structure to add atom to. - logical, intent(out) :: placed - !! Boolean to indicate if atom was placed. + logical, intent(out) :: viable + !! Boolean to indicate if point is viable. integer, dimension(:,:), intent(in) :: atom_ignore_list !! List of atoms to ignore (i.e. indices of atoms not yet placed). real(real12), dimension(:), intent(in) :: radius_list !! List of radii for each element. + real(real12), dimension(3) :: point + !! Point to add atom to. ! Local variables integer :: i, j, k, l @@ -184,7 +190,7 @@ subroutine add_atom_pseudo ( gvector_container, & ! test a random point in the unit cell !--------------------------------------------------------------------------- i = 0 - placed = .false. + viable = .false. crude_norm = 0._real12 100 random_loop : do i = i + 1 @@ -240,16 +246,10 @@ subroutine add_atom_pseudo ( gvector_container, & call random_number(rtmp1) if(crude_norm.lt.calculated_value) crude_norm = calculated_value - if (rtmp1.lt.calculated_value) then - placed = .TRUE. - exit walk_loop - end if + if (rtmp1.lt.calculated_value) exit walk_loop if(k.ge.10) then calculated_value = calculated_value / crude_norm - if (rtmp1.lt.calculated_value) then - placed = .TRUE. - exit walk_loop - end if + if (rtmp1.lt.calculated_value) exit walk_loop end if !! if we have tried 10 times, and still no luck, then we need to ... @@ -265,17 +265,17 @@ subroutine add_atom_pseudo ( gvector_container, & call random_number(rtmp1) if(k.gt.10) calculated_test = calculated_test / crude_norm - if (rtmp1.lt.calculated_test) then - placed=.TRUE. + if (rtmp1.lt.calculated_test) then tmpvector = testvector exit walk_loop end if end do walk_loop - basis%spec(atom_ignore_list(1,1))%atom(atom_ignore_list(1,2),:) = tmpvector + point = tmpvector + viable=.true. - end subroutine add_atom_pseudo + end function add_atom_walk !############################################################################### diff --git a/src/lib/mod_generator.f90 b/src/lib/mod_generator.f90 index ce02f8ee..e46246ac 100644 --- a/src/lib/mod_generator.f90 +++ b/src/lib/mod_generator.f90 @@ -14,7 +14,7 @@ module generator use misc_raffle, only: shuffle use rw_geom, only: clone_bas use edit_geom, only: bas_merge - use add_atom, only: add_atom_void, add_atom_pseudo, add_atom_scan, & + use add_atom, only: add_atom_void, add_atom_walk, add_atom_min, & get_viable_gridpoints, update_viable_gridpoints #ifdef ENABLE_ATHENA @@ -234,7 +234,6 @@ subroutine generate(this, num_structures, & allocate(basis_template%spec(num_insert_species)) do i = 1, size(stoichiometry) basis_template%spec(i)%name = strip_null(stoichiometry(i)%element) - write(*,*) basis_template%spec(i)%name end do basis_template%spec(:)%num = stoichiometry(:)%num basis_template%natom = num_insert_atoms @@ -343,15 +342,17 @@ module function generate_structure( & !! Number of atoms to insert. real(real12) :: rtmp1 !! Random number. - logical :: placed - !! Boolean for successful placement. + logical :: viable + !! Boolean for viable placement. integer, dimension(size(placement_list,1),size(placement_list,2)) :: & placement_list_shuffled !! Shuffled placement list. + real(real12), dimension(3) :: point + !! Coordinate of the atom to place. real(real12), dimension(3) :: method_probab_ !! Temporary probability of each placement method. - !! This is used to update the probability of the SCAN method if no viable - !! gridpoints are found. + !! This is used to update the probability of the global minimum method if + !! no viable gridpoints are found. real(real12), dimension(:,:), allocatable :: viable_gridpoints !! Viable gridpoints for placing atoms. @@ -392,37 +393,39 @@ module function generate_structure( & call random_number(rtmp1) if(rtmp1.le.method_probab_(1)) then if(verbose.gt.0) write(*,*) "Add Atom Void" - call add_atom_void( this%bins, & + point = add_atom_void( this%bins, & basis, & - placement_list_shuffled(iplaced+1:,:), placed) + placement_list_shuffled(iplaced+1:,:), viable) else if(rtmp1.le.method_probab_(2)) then - if(verbose.gt.0) write(*,*) "Add Atom Pseudo" - call add_atom_pseudo( & + if(verbose.gt.0) write(*,*) "Add Atom Walk" + point = add_atom_walk( & this%distributions, & basis, & placement_list_shuffled(iplaced+1:,:), & [ this%distributions%bond_info(:)%radius_covalent ], & - placed ) - if(.not. placed) void_ticker = void_ticker + 1 + viable ) + if(.not. viable) void_ticker = void_ticker + 1 else if(rtmp1.le.method_probab_(3)) then - if(verbose.gt.0) write(*,*) "Add Atom Scan" - call add_atom_scan( viable_gridpoints, & + if(verbose.gt.0) write(*,*) "Add Atom Min" + point = add_atom_min( viable_gridpoints, & this%distributions, & basis, & placement_list_shuffled(iplaced+1:,:), & [ this%distributions%bond_info(:)%radius_covalent ], & - placed) + viable) end if - if(.not. placed) then + if(.not. viable) then if(void_ticker.gt.10) & - call add_atom_void( this%bins, basis, & - placement_list_shuffled(iplaced+1:,:), placed) + point = add_atom_void( this%bins, basis, & + placement_list_shuffled(iplaced+1:,:), viable) void_ticker = 0 - if(.not.placed) cycle placement_loop + if(.not.viable) cycle placement_loop end if + basis%spec(placement_list_shuffled(iplaced+1,1))%atom( & + placement_list_shuffled(iplaced+1,2),:3) = point(:3) if(verbose.gt.0)then write(*,'(A)',ADVANCE='NO') achar(13) - write(*,*) "placed", placed + write(*,*) "placed", viable end if iplaced = iplaced + 1 if(allocated(viable_gridpoints)) & @@ -438,7 +441,7 @@ module function generate_structure( & if(.not.allocated(viable_gridpoints).and. & abs( method_probab_(3) - method_probab_(2) ) .gt. 1.E-3) then write(*,*) "WARNING: No more viable gridpoints" - write(*,*) "Suppressing SCAN method" + write(*,*) "Suppressing global minimum method" method_probab_ = method_probab_ / method_probab_(2) method_probab_(3) = method_probab_(2) end if From 1d8a15d449480fbca222d7f6186bf6a8de526b9b Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Mon, 22 Jul 2024 14:13:15 +0100 Subject: [PATCH 062/293] Remove comments --- src/lib/mod_generator.f90 | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/lib/mod_generator.f90 b/src/lib/mod_generator.f90 index e46246ac..11d3ab33 100644 --- a/src/lib/mod_generator.f90 +++ b/src/lib/mod_generator.f90 @@ -387,9 +387,6 @@ module function generate_structure( & iplaced = 0 void_ticker = 0 placement_loop: do while (iplaced.lt.num_insert_atoms) - - !!! CHANGE THESE PLACEMENT SUBROUTINES TO FUNCTIONS THAT OUTPUT THE COORDINATE - !!! THEN, THIS LOOP ACTUALLY PLACES IT AT THE END call random_number(rtmp1) if(rtmp1.le.method_probab_(1)) then if(verbose.gt.0) write(*,*) "Add Atom Void" From 1facec76fd53e19fefbef1ef7f7af7d5c25c9395 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Mon, 22 Jul 2024 14:33:55 +0100 Subject: [PATCH 063/293] Improve documentation --- src/lib/mod_atom_adder.f90 | 8 ++-- src/lib/mod_buildmap.f90 | 76 ++++++++++++++++++++++++++------------ src/lib/mod_constants.f90 | 19 +++------- 3 files changed, 63 insertions(+), 40 deletions(-) diff --git a/src/lib/mod_atom_adder.f90 b/src/lib/mod_atom_adder.f90 index c107c533..cef7438b 100644 --- a/src/lib/mod_atom_adder.f90 +++ b/src/lib/mod_atom_adder.f90 @@ -27,7 +27,7 @@ module add_atom function add_atom_min(gridpoints, gvector_container, & basis, atom_ignore_list, & radius_list, viable) result(point) - !! MIN placement method. + !! Global minimum placement method. !! !! This method places the atom at the gridpoint with the highest !! suitability. @@ -45,7 +45,7 @@ function add_atom_min(gridpoints, gvector_container, & real(real12), dimension(:,:), intent(in) :: gridpoints !! List of gridpoints to consider. real(real12), dimension(:) :: radius_list - !! List of radii for each element. + !! List of radii for each pair of elements. real(real12), dimension(3) :: point !! Point to add atom to. @@ -169,7 +169,7 @@ function add_atom_walk ( gvector_container, & integer, dimension(:,:), intent(in) :: atom_ignore_list !! List of atoms to ignore (i.e. indices of atoms not yet placed). real(real12), dimension(:), intent(in) :: radius_list - !! List of radii for each element. + !! List of radii for each pair of elements. real(real12), dimension(3) :: point !! Point to add atom to. @@ -296,7 +296,7 @@ function get_viable_gridpoints(bin_size, basis, & integer, dimension(:,:), intent(in) :: atom_ignore_list !! List of atoms to ignore (i.e. indices of atoms not yet placed). real(real12), dimension(:), intent(in) :: radius_list - !! List of radii for each element. + !! List of radii for each pair of elements. ! Local variables integer, dimension(:), allocatable :: pair_index diff --git a/src/lib/mod_buildmap.f90 b/src/lib/mod_buildmap.f90 index ef0eb95d..89dc881b 100644 --- a/src/lib/mod_buildmap.f90 +++ b/src/lib/mod_buildmap.f90 @@ -1,4 +1,10 @@ module buildmap + !! Module to build viability map of a structure + !! + !! This module handles the viability map for a structure, which is a map of + !! the system with each point in the map representing the suitability of + !! that point for a new atom. The map is built by checking the bond lengths, + !! bond angles and dihedral angles between the test point and all atoms. use constants, only: real12 use misc_linalg, only: get_distance, get_angle, get_dihedral_angle use rw_geom, only: bas_type @@ -15,35 +21,54 @@ module buildmap contains -!!!############################################################################# -!!! builds a map of the system and returns the value of the map at a given point -!!!############################################################################# -!!! output = suitability of tested point +!############################################################################### pure function buildmap_POINT(gvector_container, & position, basis, atom_ignore_list, & radius_list, uptol, lowtol) & result(output) + !! Build a map of basis and returns the value of the map at a given point implicit none + + ! Arguments type(gvector_container_type), intent(in) :: gvector_container + !! Distribution function (gvector) container. real(real12), intent(in) :: uptol, lowtol + !! Upper and lower tolerance for bond lengths and angles. type(bas_type), intent(in) :: basis + !! Basis of the system. real(real12), dimension(3), intent(in) :: position + !! Position of the test point. integer, dimension(:,:), intent(in) :: atom_ignore_list + !! List of atoms to ignore (i.e. indices of atoms not yet placed). real(real12), dimension(:), intent(in) :: radius_list + !! List of radii for each pair of elements. real(real12) :: output - - integer :: i - integer :: is, ia, js, ja, ks, ka, ls + !! Suitability of the test point. + + ! Local variables + integer :: i, is, ia, js, ja, ks, ka, ls + !! Loop counters. integer :: bin + !! Bin for the distribution function. real(real12) :: contribution, repeat_power, bondlength - real(real12) :: viability_2body !! 2-body is addition - real(real12) :: viability_3body !! 3-body is multiplication - real(real12) :: viability_4body !! 4-body is multiplication + !! Contribution to the viability map, repeat power, bond length. + real(real12) :: viability_2body + !! Viability of the test point for 2-body interactions. + !! 2-body viabilities are summed. + real(real12) :: viability_3body + !! Viability of the test point for 3-body interactions. + !! 3-body viabilities are multiplied. + real(real12) :: viability_4body + !! Viability of the test point for 4-body interactions. + !! 4-body viabilities are multiplied. real(real12), dimension(3) :: & position_storage1, position_storage2, position_storage3 + !! Storage for atom positions. integer, dimension(:,:), allocatable :: pair_index - - + !! Index of element pairs. + + + ! Initialisation output = 0._real12 repeat_power = 1._real12 viability_2body = 0._real12 @@ -51,7 +76,9 @@ pure function buildmap_POINT(gvector_container, & viability_4body = 1._real12 - !! get list of element pair indices + !--------------------------------------------------------------------------- + ! get list of element pair indices + !--------------------------------------------------------------------------- ls = atom_ignore_list(1,1) allocate(pair_index(basis%nspec, basis%nspec), source = 0) do is = 1, basis%nspec @@ -62,10 +89,13 @@ pure function buildmap_POINT(gvector_container, & end do + !--------------------------------------------------------------------------- + ! loop over all atoms in the system + !--------------------------------------------------------------------------- species_loop1: do is=1, basis%nspec - !! loops over all atoms currently in the system - !! 2-body map - !! checks bondlength between the current atom and all other atoms + ! 2-body map + ! check bondlength between test point and all other atoms + !------------------------------------------------------------------------- atom_loop1: do ia = 1, basis%spec(is)%num do i = 1, size(atom_ignore_list,dim=1), 1 if(all(atom_ignore_list(i,:).eq.[is,ia])) cycle atom_loop1 @@ -99,12 +129,12 @@ pure function buildmap_POINT(gvector_container, & viability_2body = viability_2body + contribution - !! loops over all atoms currently in the system - !! 3-body map - !! checks bondangle between the current atom and all other atoms + ! 3-body map + ! check bondangle between test point and all other atoms !! i.e. nested loop here !!! NEEDS TO BE SPECIES AND ATOM !!! SHOULD BE ITS OWN PROCEDURE + !---------------------------------------------------------------------- species_loop2: do js = is, basis%nspec, 1 atom_loop2: do ja = 1, basis%spec(js)%num if(js.eq.is .and. ja.lt.ia) cycle @@ -136,12 +166,12 @@ pure function buildmap_POINT(gvector_container, & if((get_distance(position_storage1,position_storage2).ge.& radius_list(pair_index(ls,js))*uptol)) cycle - !! loops over all atoms currently in the system - !! 4-body map - !! checks dihedral angle between the current atom and all other atoms + ! 4-body map + ! check dihedral angle between test point and all other atoms !! i.e. nested loop here !!! NEEDS TO BE SPECIES AND ATOM !!! SHOULD BE ITS OWN PROCEDURE + !----------------------------------------------------------------- species_loop3: do ks = 1, basis%nspec, 1 atom_loop3: do ka = 1, basis%spec(ks)%num do i = 2, size(atom_ignore_list,dim=1) @@ -187,6 +217,6 @@ pure function buildmap_POINT(gvector_container, & deallocate(pair_index) end function buildmap_POINT -!!!############################################################################# +!############################################################################### end module buildmap \ No newline at end of file diff --git a/src/lib/mod_constants.f90 b/src/lib/mod_constants.f90 index 36efa2f2..d8489f37 100644 --- a/src/lib/mod_constants.f90 +++ b/src/lib/mod_constants.f90 @@ -1,21 +1,14 @@ -MODULE constants +module constants + !! Module with global constants + !! + !! This module contains global constants that may be used throughout the + !! library. implicit none integer, parameter, public :: real12 = Selected_real_kind(6,37)!(15,307) - real(real12), parameter, public :: k_b = 1.3806503e-23 - real(real12), parameter, public :: k_b_ev = 8.61733326e-5 - real(real12), parameter, public :: hbar = 1.05457148e-34 - real(real12), parameter, public :: hbar_ev = 6.58211957e-16 - real(real12), parameter, public :: h = 6.626068e-34 - real(real12), parameter, public :: atomic_mass=1.66053907e-27 - real(real12), parameter, public :: neutron_mass=1.67262158e-27 - real(real12), parameter, public :: electron_mass=9.109383562e-31 - real(real12), parameter, public :: elem_charge=1.60217662e-19 - real(real12), parameter, public :: avogadros=6.022e23 - real(real12), parameter, public :: bohrtoang=0.529177249 real(real12), parameter, public :: pi = 4.D0*atan(1._real12) real(real12), parameter, public :: c = 0.26246582250210965422D0 real(real12), parameter, public :: c_vasp = 0.262465831D0 real(real12), parameter, public :: INF = huge(0._real12) complex(real12), parameter, public :: imag=(0._real12, 1._real12) integer, public :: verbose = 0 -end MODULE constants +end module constants From b4c1ead2c1190ac9051f196f4bd0d80c4352f13e Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Mon, 22 Jul 2024 14:34:11 +0100 Subject: [PATCH 064/293] Remove unused files --- src/lib/mod_generator_sub.f90 | 278 ---------------------------------- src/lib/mod_isolated.f90 | 83 ---------- 2 files changed, 361 deletions(-) delete mode 100644 src/lib/mod_generator_sub.f90 delete mode 100644 src/lib/mod_isolated.f90 diff --git a/src/lib/mod_generator_sub.f90 b/src/lib/mod_generator_sub.f90 deleted file mode 100644 index 06ecbf77..00000000 --- a/src/lib/mod_generator_sub.f90 +++ /dev/null @@ -1,278 +0,0 @@ -submodule(generator) generator_submodule - use constants, only: verbose - use misc_raffle, only: shuffle - use rw_geom, only: geom_read, geom_write, clone_bas - use edit_geom, only: bas_merge - use add_atom, only: add_atom_void, add_atom_pseudo, add_atom_scan, & - get_viable_gridpoints, update_viable_gridpoints - -#ifdef ENABLE_ATHENA - use read_structures, only: get_graph_from_basis - use machine_learning, only: network_predict_graph - use athena, only: graph_type -#endif - - implicit none - - - -contains - - - module function init_raffle_generator( & - lattice_host, basis_host, width, sigma, cutoff_min, cutoff_max ) & - result(generator) - !! Initialise an instance of the raffle generator. - !! Set up run-independent parameters. - implicit none - ! Arguments - real(real12), dimension(3,3), intent(in) :: lattice_host - !! Lattice vectors of the host structure. - type(bas_type), intent(in) :: basis_host - !! Basis of the host structure. - real(real12), dimension(3), intent(in), optional :: width - !! Width of the gaussians used in the 2-, 3-, and 4-body - !! distribution functions. - real(real12), dimension(3), intent(in), optional :: sigma - !! Width of the gaussians used in the 2-, 3-, and 4-body - !! distribution functions. - real(real12), dimension(3), intent(in), optional :: cutoff_min - !! Minimum cutoff for the 2-, 3-, and 4-body distribution functions. - real(real12), dimension(3), intent(in), optional :: cutoff_max - !! Maximum cutoff for the 2-, 3-, and 4-body distribution functions. - - type(raffle_generator_type) :: generator - - - generator%lattice_host = lattice_host - generator%basis_host = basis_host - - if( present(width) ) & - call generator%distributions%set_width(width) - if( present(sigma) ) & - call generator%distributions%set_sigma(sigma) - if( present(cutoff_min) ) & - call generator%distributions%set_cutoff_min(cutoff_min) - if( present(cutoff_max) ) & - call generator%distributions%set_cutoff_max(cutoff_max) - - - end function init_raffle_generator - - - - module subroutine generate(this, num_structures, & - stoichiometry, method_probab) - !! Generate random structures. - implicit none - ! Arguments - class(raffle_generator_type), intent(inout) :: this - !! Instance of the raffle generator. - integer, intent(in) :: num_structures - !! Number of structures to generate. - type(stoichiometry_type), dimension(:), intent(in) :: stoichiometry - !! Stoichiometry of the structures to generate. - real(real12), dimension(:), intent(in), optional :: method_probab - !! Probability of each placement method. - - type(bas_type) :: basis, basis_store - - integer, dimension(:,:), allocatable :: placement_list, placement_list_shuffled - - integer :: i, j, k - integer :: istructure - integer :: unit, info_unit, structure_unit - integer :: num_insert_atoms, num_insert_species - - logical :: placed, success - character(1024) :: buffer - - real(real12), dimension(3) :: method_probab_ = [0.33_real12, 0.66_real12, 1.0_real12] - -#ifdef ENABLE_ATHENA - type(graph_type), dimension(1) :: graph -#endif - - if(present(method_probab)) method_probab_ = method_probab - - - !!! THINK OF SOME WAY TO HANDLE THE HOST SEPARATELY - !!! THAT CAN SIGNIFICANTLY REDUCE DATA USAGE - num_insert_species = size(stoichiometry) - num_insert_atoms = sum(stoichiometry(:)%num) - allocate(basis_store%spec(num_insert_species)) - basis_store%spec(:)%name = stoichiometry(:)%element - basis_store%spec(:)%num = stoichiometry(:)%num - basis_store%natom = num_insert_atoms - basis_store%nspec = num_insert_species - basis_store%sysname = "inserts" - - do i = 1, basis_store%nspec - allocate(basis_store%spec(i)%atom(basis_store%spec(i)%num,3), source = 0._real12) - end do - basis_store = bas_merge(this%basis_host,basis_store) - - - !!-------------------------------------------------------------------------- - !! generate the placement list - !! placement list is the list of number of atoms of each species that can be - !! placed in the structure - !! ... the second dimension is the index of the species and atom in the - !! ... basis_store - !!-------------------------------------------------------------------------- - allocate(placement_list(num_insert_atoms,2)) - k = 0 - spec_loop1: do i = 1, basis_store%nspec - success = .false. - do j = 1, size(stoichiometry) - if(trim(basis_store%spec(i)%name).eq.trim(stoichiometry(j)%element)) & - success = .true. - end do - if(.not.success) cycle - if(i.gt.this%basis_host%nspec)then - do j = 1, basis_store%spec(i)%num - k = k + 1 - placement_list(k,1) = i - placement_list(k,2) = j - end do - else - do j = 1, basis_store%spec(i)%num - if(j.le.this%basis_host%spec(i)%num) cycle - k = k + 1 - placement_list(k,1) = i - placement_list(k,2) = j - end do - end if - end do spec_loop1 - - - !!-------------------------------------------------------------------------- - !! generate the structures - !!-------------------------------------------------------------------------- - structure_loop: do istructure = 1, num_structures - - basis = this%generate_structure( basis_store, & - placement_list, method_probab_ ) - -#ifdef ENABLE_ATHENA - !!----------------------------------------------------------------------- - !! predict energy using ML - !!----------------------------------------------------------------------- - graph(1) = get_graph_from_basis(this%lattice_host, basis) - write(*,*) "Predicted energy", network_predict_graph(graph(1:1)) -#endif - - end do structure_loop - write(*,*) "Finished generating structures" - - end subroutine generate - - - - module function generate_structure( & - this, & - basis_initial, & - placement_list, method_probab ) result(basis) - !! Generate a single random structure. - implicit none - ! Arguments - class(raffle_generator_type), intent(in) :: this - !! Instance of the raffle generator. - type(bas_type), intent(in) :: basis_initial - !! Initial basis to build upon. - integer, dimension(:,:), intent(in) :: placement_list - !! List of possible placements. - real(real12), dimension(3) :: method_probab - !! Probability of each placement method. - type(bas_type) :: basis - !! Generated basis. - - integer :: i, j, iplaced, void_ticker - integer :: num_insert_atoms - real(real12) :: rtmp1 - logical :: placed - integer, dimension(size(placement_list,1),size(placement_list,2)) :: & - placement_list_shuffled - real(real12), dimension(3) :: method_probab_ - real(real12), dimension(:,:), allocatable :: viable_gridpoints - - - - call clone_bas(basis_initial, basis) - num_insert_atoms = basis%natom - this%basis_host%natom - - placement_list_shuffled = placement_list - call shuffle(placement_list_shuffled,1) !!! NEED TO SORT OUT RANDOM SEED - - viable_gridpoints = get_viable_gridpoints( this%bins, & - this%lattice_host, basis, & - [ this%distributions%bond_info(:)%radius_covalent ], & - placement_list_shuffled ) - - method_probab_ = method_probab - - iplaced = 0 - void_ticker = 0 - placement_loop: do while (iplaced.lt.num_insert_atoms) - - !!! CHANGE THESE PLACEMENT SUBROUTINES TO FUNCTIONS THAT OUTPUT THE COORDINATE - !!! THEN, THIS LOOP ACTUALLY PLACES IT AT THE END - call random_number(rtmp1) - if(rtmp1.le.method_probab_(1)) then - if(verbose.gt.0) write(*,*) "Add Atom Void" - call add_atom_void( this%bins, & - this%lattice_host, basis, & - placement_list_shuffled(iplaced+1:,:), placed) - else if(rtmp1.le.method_probab_(2)) then - if(verbose.gt.0) write(*,*) "Add Atom Pseudo" - call add_atom_pseudo( this%bins, & - this%distributions, & - this%lattice_host, basis, & - placement_list_shuffled(iplaced+1:,:), & - [ this%distributions%bond_info(:)%radius_covalent ], & - placed ) - if(.not. placed) void_ticker = void_ticker + 1 - else if(rtmp1.le.method_probab_(3)) then - if(verbose.gt.0) write(*,*) "Add Atom Scan" - call add_atom_scan( viable_gridpoints, & - this%distributions, & - this%lattice_host, basis, & - placement_list_shuffled(iplaced+1:,:), & - [ this%distributions%bond_info(:)%radius_covalent ], & - placed) - end if - if(.not. placed) then - if(void_ticker.gt.10) & - call add_atom_void( this%bins, this%lattice_host, basis, & - placement_list_shuffled(iplaced+1:,:), placed) - void_ticker = 0 - if(.not.placed) cycle placement_loop - end if - if(verbose.gt.0)then - write(*,'(A)',ADVANCE='NO') achar(13) - write(*,*) "placed", placed - end if - iplaced = iplaced + 1 - if(allocated(viable_gridpoints)) & - call update_viable_gridpoints( viable_gridpoints, & - this%lattice_host, basis, & - [ placement_list_shuffled(iplaced,:) ], & - this%distributions%bond_info( & - ( basis%nspec - & - placement_list_shuffled(iplaced,1)/2 ) * & - ( placement_list_shuffled(iplaced,1) - 1 ) + & - placement_list_shuffled(iplaced,1) & - )%radius_covalent ) - if(.not.allocated(viable_gridpoints).and. & - abs( method_probab_(3) - method_probab_(2) ) .gt. 1.E-3) then - write(*,*) "WARNING: No more viable gridpoints" - write(*,*) "Suppressing SCAN method" - method_probab_ = method_probab_ / method_probab_(2) - method_probab_(3) = method_probab_(2) - end if - - end do placement_loop - - end function generate_structure - -end submodule generator_submodule \ No newline at end of file diff --git a/src/lib/mod_isolated.f90 b/src/lib/mod_isolated.f90 deleted file mode 100644 index 6a02bbf0..00000000 --- a/src/lib/mod_isolated.f90 +++ /dev/null @@ -1,83 +0,0 @@ -module isolated - use constants, only: real12 - use rw_geom, only: bas_type, geom_write - use vasp_file_handler, only: generate_potcar, kpoints_write, Incarwrite - implicit none - - - private - - public :: generate_isolated_calculations - - -contains - -!!!############################################################################# -!!! make isolated atom directories and set up enclosing calculations -!!!############################################################################# - subroutine generate_isolated_calculations(element_list) - implicit none - character(len=3), dimension(:), intent(in) :: element_list - - integer :: unit - integer :: i, num_species - type(bas_type) :: basis - real(real12), dimension(3,3) :: lattice = 0._real12 - logical :: exists - character(len=1024) :: tmp - - - num_species = size(element_list) - - !!-------------------------------------------------------------------------- - !! inquires if the directory 'iso' exists, if not, create it - !!-------------------------------------------------------------------------- - inquire(file="iso", exist=exists) - if(.not.exists)then - call execute_command_line("mkdir iso") - end if - - lattice(1,1) = 20._real12 - lattice(2,2) = 20._real12 - lattice(3,3) = 20._real12 - basis%nspec = 1 - basis%natom = 1 - allocate(basis%spec(1)) - basis%spec(1)%num = 1 - allocate(basis%spec(1)%atom(1,3), source = 0.5_real12) - !!-------------------------------------------------------------------------- - !!! prepare isolation calculations for each element - !!-------------------------------------------------------------------------- - do i = 1, num_species - basis%sysname = trim(adjustl(element_list(i)))//" isolated" - basis%spec(1)%name = trim(adjustl(element_list(i))) - - !! write the name of the directory to tmp - write(tmp,'("iso/POSCAR_",A3)') trim(adjustl(element_list(i))) - - !! check if directory already exists, if not, create it - !! COMPLAIN IF EXISTS - inquire(file=tmp, exist=exists) - if(exists) then - write(*,'("ERROR: Directory ",A," already exists")') & - trim(adjustl(tmp)) - stop 1 - else - !! make directory - call execute_command_line("mkdir " // trim(adjustl(tmp))) - - !! write POSCAR file - open(newunit=unit, file=trim(adjustl(tmp))//"/POSCAR") - call geom_write(unit, lattice, basis) - close(unit) - - call generate_potcar(tmp,[element_list(i)]) - call kpoints_write(tmp,1,1,1) - call Incarwrite(tmp,500, 20) !!The 500 here is nstep electronic - end if - end do - - end subroutine generate_isolated_calculations -!!!############################################################################# - -end module isolated \ No newline at end of file From 26695c467d8a17f079145858263bbf1a1e7ab9a9 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Mon, 22 Jul 2024 14:34:35 +0100 Subject: [PATCH 065/293] Add FORD documentation --- .gitignore | 3 ++- ford.md | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 ford.md diff --git a/.gitignore b/.gitignore index 13338161..1059f9c5 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ DTEST/ build/ src/*.egg-info *.egg-info -iteration* \ No newline at end of file +iteration* +doc/html \ No newline at end of file diff --git a/ford.md b/ford.md new file mode 100644 index 00000000..a3cde81e --- /dev/null +++ b/ford.md @@ -0,0 +1,23 @@ +project: +summary: A Fortran library and executable for structure prediction at material interfaces +src_dir: src +output_dir: doc/html +preprocess: false +predocmark: !! +fpp_extensions: f90 +display: public + protected + private +source: true +graph: true +md_extensions: markdown.extensions.toc +coloured_edges: true +sort: permission-alpha +author: Ned Thaddeus Taylor +print_creation_date: true +creation_date: %Y-%m-%d %H:%M %z +project_github: https://github.com/nedtaylor/raffle +project_download: https://github.com/nedtaylor/raffle/releases +github: https://github.com/nedtaylor + +{!README.md!} \ No newline at end of file From c73403b31262f4fc37e0f6a6a9463fe47c9a6183 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Mon, 22 Jul 2024 16:23:06 +0100 Subject: [PATCH 066/293] Handle random seed --- src/raffle/raffle.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/raffle/raffle.py b/src/raffle/raffle.py index 971c3bc7..6b40b800 100644 --- a/src/raffle/raffle.py +++ b/src/raffle/raffle.py @@ -1852,7 +1852,7 @@ def set_host(self, host): _raffle.f90wrap_generator__set_host__binding__rgt(this=self._handle, \ host=host._handle) - def generate(self, num_structures, stoichiometry, method_probab=[1.0, 1.0, 1.0]): + def generate(self, num_structures, stoichiometry, method_probab=[1.0, 1.0, 1.0], seed=None): """ generate__binding__raffle_generator_type(self, num_structures, stoichiometry, method_probab) @@ -1868,11 +1868,18 @@ def generate(self, num_structures, stoichiometry, method_probab=[1.0, 1.0, 1.0]) """ - _raffle.f90wrap_generator__generate__binding__rgt( - this=self._handle, - num_structures=num_structures, - stoichiometry=stoichiometry._handle, - method_probab=method_probab) + if seed is not None: + _raffle.f90wrap_generator__generate__binding__rgt( + this=self._handle, + num_structures=num_structures, + stoichiometry=stoichiometry._handle, + method_probab=method_probab, seed=seed) + else: + _raffle.f90wrap_generator__generate__binding__rgt( + this=self._handle, + num_structures=num_structures, + stoichiometry=stoichiometry._handle, + method_probab=method_probab) def get_structures(self): """ From 557e2f22a53c3f398e48ae5c5e7e79ade4809758 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Tue, 23 Jul 2024 14:02:10 +0100 Subject: [PATCH 067/293] Add fpm support --- CMakeLists.txt | 42 +++++++------------ README.md | 2 +- fpm.toml | 25 +++++++++++ pyproject.toml | 2 +- src/{ => fortran}/lib/mod_atom_adder.f90 | 0 src/{ => fortran}/lib/mod_buildmap.f90 | 0 src/{ => fortran}/lib/mod_constants.f90 | 0 src/{ => fortran}/lib/mod_edit_geom.f90 | 0 src/{ => fortran}/lib/mod_elements.f90 | 0 src/{ => fortran}/lib/mod_evolver.f90 | 0 src/{ => fortran}/lib/mod_generator.f90 | 0 src/{ => fortran}/lib/mod_misc.f90 | 0 src/{ => fortran}/lib/mod_misc_linalg.f90 | 0 src/{ => fortran}/lib/mod_misc_maths.f90 | 0 src/{ => fortran}/lib/mod_ml.f90 | 7 ++++ src/{ => fortran}/lib/mod_read_structures.f90 | 0 src/{ => fortran}/lib/mod_rw_geom.f90 | 0 src/{ => fortran}/lib/mod_rw_vasprun.f90 | 0 .../lib/mod_vasp_file_handler.f90 | 2 +- src/{ => fortran}/raffle.f90 | 0 20 files changed, 51 insertions(+), 29 deletions(-) create mode 100644 fpm.toml rename src/{ => fortran}/lib/mod_atom_adder.f90 (100%) rename src/{ => fortran}/lib/mod_buildmap.f90 (100%) rename src/{ => fortran}/lib/mod_constants.f90 (100%) rename src/{ => fortran}/lib/mod_edit_geom.f90 (100%) rename src/{ => fortran}/lib/mod_elements.f90 (100%) rename src/{ => fortran}/lib/mod_evolver.f90 (100%) rename src/{ => fortran}/lib/mod_generator.f90 (100%) rename src/{ => fortran}/lib/mod_misc.f90 (100%) rename src/{ => fortran}/lib/mod_misc_linalg.f90 (100%) rename src/{ => fortran}/lib/mod_misc_maths.f90 (100%) rename src/{ => fortran}/lib/mod_ml.f90 (98%) rename src/{ => fortran}/lib/mod_read_structures.f90 (100%) rename src/{ => fortran}/lib/mod_rw_geom.f90 (100%) rename src/{ => fortran}/lib/mod_rw_vasprun.f90 (100%) rename src/{ => fortran}/lib/mod_vasp_file_handler.f90 (99%) rename src/{ => fortran}/raffle.f90 (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8dc27f61..6d3ecddd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,7 +67,8 @@ option(BUILD_EXECUTABLE "Build the Fortran executable" On) # Define the sources set(SRC_DIR src) -set(LIB_DIR ${SRC_DIR}/lib) +set(FORTRAN_SRC_DIR ${SRC_DIR}/fortran) +set(LIB_DIR ${FORTRAN_SRC_DIR}/lib) set(LIB_FILES mod_constants.f90 @@ -127,8 +128,8 @@ foreach(lib ${SPECIAL_LIB_FILES}) list(APPEND F90WRAP_FORTRAN_SRC_FILES ${CMAKE_CURRENT_LIST_DIR}/${LIB_DIR}/${lib}) endforeach() foreach(src ${SRC_FILES}) - list(APPEND F90WRAP_FORTRAN_SRC_FILES ${CMAKE_CURRENT_LIST_DIR}/${SRC_DIR}/${src}) - list(APPEND PREPENDED_SRC_FILES ${SRC_DIR}/${src}) + list(APPEND F90WRAP_FORTRAN_SRC_FILES ${CMAKE_CURRENT_LIST_DIR}/${FORTRAN_SRC_DIR}/${src}) + list(APPEND PREPENDED_SRC_FILES ${FORTRAN_SRC_DIR}/${src}) endforeach() @@ -142,8 +143,6 @@ foreach(src ${EXECUTABLE_FILES}) endforeach() -message(STATUS "Modified SRC_FILES: ${PREPENDED_SRC_FILES}") - # initialise flags set(CPPFLAGS "") set(CFLAGS "") @@ -268,7 +267,7 @@ if (BUILD_PYTHON) set(PLATFORM_TAG "unknown") endif() set(FILENAME_MIDDLE "cpython-${PYTHON_VERSION}-${PLATFORM_TAG}") - set(F2PY_OUTPUT_FILE ${CMAKE_BINARY_DIR}/_${PROJECT_NAME}.${FILENAME_MIDDLE}.so) + set(F2PY_OUTPUT_FILE ${CMAKE_BINARY_DIR}/raffle/_${PROJECT_NAME}.${FILENAME_MIDDLE}.so) # # Generate f90wrap signature file set(F90WRAP_FILE ${CMAKE_CURRENT_LIST_DIR}/src/wrapper/f90wrap_*.f90) @@ -292,8 +291,8 @@ if (BUILD_PYTHON) # Copy f90wrap edited files from edited_autogen_files to ${CMAKE_BINARY_DIR} add_custom_command( - OUTPUT ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.py ${CMAKE_BINARY_DIR}/__init__.py - COMMAND cp -r ${CMAKE_CURRENT_LIST_DIR}/src/raffle/*.py ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + OUTPUT ${CMAKE_BINARY_DIR}/raffle/${PROJECT_NAME}.py ${CMAKE_BINARY_DIR}/raffle/__init__.py + COMMAND cp -r ${CMAKE_CURRENT_LIST_DIR}/${SRC_DIR}/raffle ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/. COMMENT "Copying raffle class file" ) @@ -309,41 +308,32 @@ if (BUILD_PYTHON) -c -m _${PROJECT_NAME} --f90flags="${PPFLAGS}" + --include-paths ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/raffle ${F90WRAP_FILE} - --quiet - ${OBJECTS_DIR}/src/*.o - ${OBJECTS_DIR}/src/lib/*.o + ${OBJECTS_DIR}/${FORTRAN_SRC_DIR}/*.o + ${OBJECTS_DIR}/${LIB_DIR}/*.o ${F2PY_OUTPUT_FLAG} - DEPENDS ${F90WRAP_FILE} - WORKING_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + DEPENDS ${F90WRAP_FILE} ${CMAKE_BINARY_DIR}/raffle/${PROJECT_NAME}.py + WORKING_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/raffle COMMENT "Creating Python module using f2py" ) # Define output files - set(PY_MODULE ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.py) + set(PY_MODULE ${CMAKE_BINARY_DIR}/raffle/${PROJECT_NAME}.py ${CMAKE_BINARY_DIR}/raffle/__init__.py) # file(GLOB SO_MODULE "${CMAKE_BINARY_DIR}/_${PROJECT_NAME}*.so") # Create a custom target for the Python module add_custom_target(python_module ALL - DEPENDS ${F2PY_OUTPUT_FILE} ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.py ${CMAKE_BINARY_DIR}/__init__.py + DEPENDS ${F2PY_OUTPUT_FILE} ${CMAKE_BINARY_DIR}/raffle/${PROJECT_NAME}.py ${CMAKE_BINARY_DIR}/raffle/__init__.py ) # Installation instructions - install(FILES ${PY_MODULE} DESTINATION lib) - install(FILES ${SO_MODULE} DESTINATION lib) + install(FILES ${PY_MODULE} DESTINATION .) + install(FILES ${F2PY_OUTPUT_FILE} DESTINATION .) endif() -# Print helpful messages -message(STATUS "Build configuration:") -message(STATUS " Source directory: ${SRC_DIR}") -message(STATUS " Output library: ${PROJECT_NAME}") -# message(STATUS " Fortran modules directory: ${CMAKE_BINARY_DIR}/mod") -# message(STATUS " Python module: ${PROJECT_NAME}.so") - - - if(ENABLE_ATHENA) target_link_libraries(raffle ${ATHENA_LIBRARY}) endif() \ No newline at end of file diff --git a/README.md b/README.md index d13b900e..1de5318f 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ cmake .. make install ``` -Then, the path to the install directory (`${HOME}/.local/raffle`) needs to be added to the include path. +Then, the path to the install directory (`${HOME}/.local/raffle`) needs to be added to the include path. NOTE: this method requires that the user manually installs the `ase`, `numpy` and `f90wrap` modules for Python. ### Fortran diff --git a/fpm.toml b/fpm.toml new file mode 100644 index 00000000..775ab199 --- /dev/null +++ b/fpm.toml @@ -0,0 +1,25 @@ +name = "raffle" +version = "0.2.0" +author = "Ned Thaddeus Taylor" +maintainer = "n.t.taylor@exeter.ac.uk" +description = "A Fortran library and executable for structure prediction at material interfaces" + +[preprocess] +[preprocess.cpp] +suffixes = ["F90", "f90"] + +[library] +source-dir="src/lib" + +[fortran] +implicit-typing = false +implicit-external = false +source-form = "free" + +[[executable]] +name="raffle_executable" +source-dir="app" +main="main.f90" + +[build] +external-modules = ["athena"] diff --git a/pyproject.toml b/pyproject.toml index 2684ed45..23227d6e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ classifiers = [ "Development Status :: 3", "Indented Audience :: Computational materials scientists", "Programming Language :: Python :: 3.11", - "Programming Language :: Fortran :: F08", + "Programming Language :: Fortran :: Fortran 2018", "License :: ", "Operating System :: OS Independent", ] diff --git a/src/lib/mod_atom_adder.f90 b/src/fortran/lib/mod_atom_adder.f90 similarity index 100% rename from src/lib/mod_atom_adder.f90 rename to src/fortran/lib/mod_atom_adder.f90 diff --git a/src/lib/mod_buildmap.f90 b/src/fortran/lib/mod_buildmap.f90 similarity index 100% rename from src/lib/mod_buildmap.f90 rename to src/fortran/lib/mod_buildmap.f90 diff --git a/src/lib/mod_constants.f90 b/src/fortran/lib/mod_constants.f90 similarity index 100% rename from src/lib/mod_constants.f90 rename to src/fortran/lib/mod_constants.f90 diff --git a/src/lib/mod_edit_geom.f90 b/src/fortran/lib/mod_edit_geom.f90 similarity index 100% rename from src/lib/mod_edit_geom.f90 rename to src/fortran/lib/mod_edit_geom.f90 diff --git a/src/lib/mod_elements.f90 b/src/fortran/lib/mod_elements.f90 similarity index 100% rename from src/lib/mod_elements.f90 rename to src/fortran/lib/mod_elements.f90 diff --git a/src/lib/mod_evolver.f90 b/src/fortran/lib/mod_evolver.f90 similarity index 100% rename from src/lib/mod_evolver.f90 rename to src/fortran/lib/mod_evolver.f90 diff --git a/src/lib/mod_generator.f90 b/src/fortran/lib/mod_generator.f90 similarity index 100% rename from src/lib/mod_generator.f90 rename to src/fortran/lib/mod_generator.f90 diff --git a/src/lib/mod_misc.f90 b/src/fortran/lib/mod_misc.f90 similarity index 100% rename from src/lib/mod_misc.f90 rename to src/fortran/lib/mod_misc.f90 diff --git a/src/lib/mod_misc_linalg.f90 b/src/fortran/lib/mod_misc_linalg.f90 similarity index 100% rename from src/lib/mod_misc_linalg.f90 rename to src/fortran/lib/mod_misc_linalg.f90 diff --git a/src/lib/mod_misc_maths.f90 b/src/fortran/lib/mod_misc_maths.f90 similarity index 100% rename from src/lib/mod_misc_maths.f90 rename to src/fortran/lib/mod_misc_maths.f90 diff --git a/src/lib/mod_ml.f90 b/src/fortran/lib/mod_ml.f90 similarity index 98% rename from src/lib/mod_ml.f90 rename to src/fortran/lib/mod_ml.f90 index 3af68214..2fa4b72e 100644 --- a/src/lib/mod_ml.f90 +++ b/src/fortran/lib/mod_ml.f90 @@ -1,21 +1,27 @@ module machine_learning use constants, only: real12 +#ifdef ENABLE_ATHENA use athena +#endif implicit none private +#ifdef ENABLE_ATHENA + public :: network_setup public :: network_train, network_train_graph public :: network_predict, network_predict_graph type(network_type) :: network +#endif contains +#ifdef ENABLE_ATHENA subroutine network_setup(num_inputs, num_outputs) implicit none integer, intent(in) :: num_inputs, num_outputs @@ -161,4 +167,5 @@ function network_predict_graph(graphs) result(y) end function network_predict_graph +#endif end module machine_learning \ No newline at end of file diff --git a/src/lib/mod_read_structures.f90 b/src/fortran/lib/mod_read_structures.f90 similarity index 100% rename from src/lib/mod_read_structures.f90 rename to src/fortran/lib/mod_read_structures.f90 diff --git a/src/lib/mod_rw_geom.f90 b/src/fortran/lib/mod_rw_geom.f90 similarity index 100% rename from src/lib/mod_rw_geom.f90 rename to src/fortran/lib/mod_rw_geom.f90 diff --git a/src/lib/mod_rw_vasprun.f90 b/src/fortran/lib/mod_rw_vasprun.f90 similarity index 100% rename from src/lib/mod_rw_vasprun.f90 rename to src/fortran/lib/mod_rw_vasprun.f90 diff --git a/src/lib/mod_vasp_file_handler.f90 b/src/fortran/lib/mod_vasp_file_handler.f90 similarity index 99% rename from src/lib/mod_vasp_file_handler.f90 rename to src/fortran/lib/mod_vasp_file_handler.f90 index 52f8129f..112e375f 100644 --- a/src/lib/mod_vasp_file_handler.f90 +++ b/src/fortran/lib/mod_vasp_file_handler.f90 @@ -1,6 +1,6 @@ module vasp_file_handler use constants, only: real12 - use misc, only: touch, icount + use misc_raffle, only: touch, icount implicit none private diff --git a/src/raffle.f90 b/src/fortran/raffle.f90 similarity index 100% rename from src/raffle.f90 rename to src/fortran/raffle.f90 From 86277ccd433bae2149bb2df75cbc6171a43858bb Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Tue, 23 Jul 2024 14:02:32 +0100 Subject: [PATCH 068/293] Remove old files --- src/backup/backupgenerator.f90 | 1226 -------------------------------- src/backup/backupsub.f90 | 415 ----------- src/backup/mainBACKUP.f90 | 189 ----- 3 files changed, 1830 deletions(-) delete mode 100644 src/backup/backupgenerator.f90 delete mode 100644 src/backup/backupsub.f90 delete mode 100644 src/backup/mainBACKUP.f90 diff --git a/src/backup/backupgenerator.f90 b/src/backup/backupgenerator.f90 deleted file mode 100644 index d1e4ce48..00000000 --- a/src/backup/backupgenerator.f90 +++ /dev/null @@ -1,1226 +0,0 @@ -module gen -use help -use atomtype -implicit none -contains - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - subroutine generation(leng, atomlist, alistrep, spacelist, formula, structno, options, eltot, elnames, stochio, elrad) - type(unitcell), dimension(:), allocatable :: formula - double precision :: posneg, r, pi, meanvol, q, normvol, cellmultiplier, calc,sigma1 - integer :: l,b,leng, i, j, k, x, y, z, m, structures, structno, prev_structures, modeselect - integer :: errorcounter, ecount, eltot, options, loopcounter - - integer :: eltype - !! box = initial untransformed cubic unit cell - !! a 0 0 - !! 0 b 0 - !! 0 0 c - double precision, dimension(3,3) :: box - double precision, dimension(3) :: angle, spacelist, tmpvector - double precision, dimension(:,:,:,:), allocatable :: bondlist - double precision :: connectivity, volmin, volmax, bondpro1, bondpro2, distribution, tmpvalue - type (atom), dimension(:,:), allocatable :: atomlist, alistrep, alistrepp - character(1024) :: name, tmp, command - character(3), dimension(:), allocatable :: elnames, sing_el - integer, dimension(:), allocatable :: elno, stochio - logical :: dir_e - double precision, dimension(:,:,:), allocatable :: elrad - double precision, dimension(:,:), allocatable :: bondavg, bondminimum - - character(3), dimension(:), allocatable :: tmpels - integer, dimension(:), allocatable :: tmpdig - double precision, dimension(:,:), allocatable :: tempmatrix - - - !! The info file doesn't contain much of use yet. Could build in if relevant - open(11, file="Info") - !! Atomlist contains the information about the positions of all atoms in ALL structures. This may cause issues - !! with memory when large numbers of structures are used, may consider breaking down into seperate iterations - !! (e.g paralyse) - allocate(atomlist(structno,leng)) - !! alistrep contains positions of all atoms repeated in adjacent unit cells. Same point as above. - allocate(alistrep(structno,leng*27)) - !! Calls the function structurecounter, which provides information about the number of currently existing - !! structures in the directory - prev_structures=structurecounter("pos") - !! assigns the length of elno to eltot. NOT SURE WHY, SHOULD BE LENG?. UNLESS ELNO CONTAINS ALL MATERIAL SPECS - allocate(elno(eltot)) - - - - !! bondlist is a list of ALL the bonds between all the atoms and each of it's neighbours in the first tier of recursive repeated unit cells - allocate(bondlist(leng,leng*27,eltot,eltot)) - allocate(bondavg(eltot,eltot)) - !! modeselect=1 is a special option allowing a new poscar to be added in at user specification - modeselect=options - - !! Could implement structno>1 in the future for large imports - if(modeselect.eq.1) structno=1 - structures=1 - loopcounter=0 - - !! elnames is a 1D array containing the symbol for each of the atoms (length=eltot). [generator;eltot~>main;elno]----------------------------------------------------------! -!Sets the value of pi. Will eventually come from a dedicated constants and parameters page! - pi=3.14159265358979323846 ! -!-----------------------------------------------------------------------------------------! - -inquire(file="iso", exist=dir_e) -if(dir_e) then -else -write(command,*) "mkdir iso" -CALL execute_command_line(command) -end if - -!!! This section prepares isolation calculations -do i=1, eltot - - write(name,'(A11,A,A7)')"iso/POSCAR_",trim(adjustl(elnames(i))),"/POSCAR" - !!Calculates the new structure number, and writes it to tmp - write(tmp,'(A11,A3)')"iso/POSCAR_",elnames(i) - !!Checks if a directory to contain that file exsts already (It should never exist, coul add warning) - inquire(file=tmp, exist=dir_e) - if(dir_e) then - else - !!Writes a command to create said directory - write(command,'(A17,A3)')"mkdir iso/POSCAR_",elnames(i) - CALL execute_command_line(command) - open(10+i, file=name) - write(10+i,'(A)') "test" - write(10+i, *) "1.00000000" - write(10+i, *) " ","20.0000000000000000"," ","0.0000000000000000"," ","0.0000000000000000" - write(10+i, *) " ","0.0000000000000000"," ","20.0000000000000000"," ","0.0000000000000000" - write(10+i, *) " ","0.0000000000000000"," ","0.0000000000000000"," ","20.0000000000000000" - write(10+i,*) " ", elnames(i) - write(10+i,*) " ", "1" - write(10+i,*) "Direct" - write(10+i,*) " ","0.5000000000000000"," ","0.5000000000000000"," ","0.5000000000000000" - close(10+i) - - allocate(sing_el(1)) - sing_el(1)=elnames(i) - call potwrite(tmp,sing_el,1) - deallocate(sing_el) - call Jobwrite(tmp,1,1,1) - call Incarwrite(tmp,500, 20) !!The 500 here is nstep electronic - !print*, trim(adjustl(tmp)) - CALL chdir(trim(adjustl(tmp))) - CALL execute_command_line("qsub.sh") - CALL chdir("../../") - end if -end do - - - - - - - - - - - - -!! Builds pos and don subfolders if they do not already exist - -call touchpos() - -inquire(file="don", exist=dir_e) -if(dir_e) then -else - write(command,*) "mkdir don" - CALL execute_command_line(command) -end if - - - - - - -!!! Create the directories for all of the POSCARS to be placed into !!! - !! BIGLOOP is the parent loop for all procesess, generating one structure for each full completed iteration -b=0 - BIGLOOP: do while(structures.le.structno) - - b=structures - do while (b.gt.7) - b=b-7 - end do - print*, b - call touchposdir(structures,prev_structures) -!------------------------------------------------------------------------------------------------! -! !!This section will count the loop number efficiently if no other prints are used in loop ! -! loopcounter=loopcounter+1 ! -! write(6, '(A1, 40X, A1)', advance='no') achar(13), achar(13) ! -! write(6,'(I0.4)', advance='no') loopcounter ! -!------------------------------------------------------------------------------------------------! - - -!!!-------------------------------------------------------------------------------------!!! -!!!Decides if pseudorandom volume will be larger or smaller than atomic volume summation!!! -!!!-------------------------------------------------------------------------------------!!! - - posneg=1 - call random_number(r) - if(r.lt.0.5) then - posneg=-posneg - else - end if - -!!!-------------------------------------------------------------------------------------!!! -!!!Decides the total desired pseudorandom cell volume !!! -!!!-------------------------------------------------------------------------------------!!! - - -!! Meanvol takes the atomic radius and calculates a guestimate for the total rough cell volume. NEED A BETTER METHOD -!! FOR ACCOMPLISHING THIS -!meanvol=4/3*2.2**3*pi*leng -meanvol=0 -volmin=0 -volmax=0 -k=0 -do i=1, eltot - do j=1, eltot -! if(elrad(3,i,i).gt.elrad(3,i,j)) print*, "This element is bonded to more of it's partners than they are to it" -! if(elrad(3,i,i).lt.elrad(3,i,j)) print*, "This element is bonded to less of it's partners than they are to it" - - end do -end do - -k=0 -do i=1, eltot - volmin=volmin+stochio(i)*(4.0/3.0)*pi*(elrad(2,i,i)**3) - do j=1, eltot - if(j.lt.i) cycle - if(i.eq.j) then; - connectivity=0.5 - else - CALL invar(6,tmpdig,tmpels) - connectivity=dble(tmpdig(1)/100.0) - !print*, connectivity - deallocate(tmpdig) - end if - - if(i.eq.j) then - volmin=volmin-connectivity*stochio(i)*elrad(3,i,j)*((dble(stochio(j))/leng)*& - &sphereoverlap(elrad(2,i,i),elrad(2,j,j),elrad(1,i,j),pi)) - else - volmin=volmin-connectivity*(stochio(i)*elrad(3,i,j)+stochio(j)*elrad(4,i,j))*0.5*((dble(stochio(j))/leng)*& - &sphereoverlap(elrad(2,i,i),elrad(2,j,j),elrad(1,i,j),pi)) - - end if - !" print*, volmin, connectivity*stochio(i)*elrad(3,i,j)*((dble(stochio(j))/leng)*& -! &sphereoverlap(elrad(2,i,i),elrad(2,j,j),elrad(1,i,j),pi)) - - !print*,"bonding between elements",(min((elrad(3,i,j)*stochio(i)),(elrad(4,i,j)*stochio(j)))) - - !volmax=volmax+stochio(i)*(4.0/3.0)*pi*(elrad(2,i,i)**3)-connectivity*((dble(stochio(j))/leng)*& - ! &sphereoverlap(elrad(2,i,i),elrad(2,j,j),elrad(1,i,j),pi)) - !print*, volmax - - - - meanvol=volmin - end do - ! meanvol=meanvol+stochio(i)*((connectivity*elrad(1,i,i))+((1.0-connectivity)*elrad(2,i,i)))**3*(4/3)*pi -end do - -!!Adds or subtracts a small quantity from the calculated volume -call random_number(r) -call invar(7,tmpdig,tmpels) -meanvol=meanvol+(dble(tmpdig(1)/100.0)*r*posneg*meanvol) -deallocate(tmpdig) - -!!!-------------------------------------------------------------------------------------!!! -!!Define the random unit cell lengths !!! -!!!-------------------------------------------------------------------------------------!!! - -!! Initialises box, which is a cubic unit serving as the basis for the random unit cel -box=0 -!! q keeps a running total of the "volume" in the loosest sense of the word -q=1 - -call random_number(r) -box(1,1)=0.75+r*2.25 -q=q*r -call random_number(r) -box(2,2)=0.75+r*2.25 -q=q*r -call random_number(r) -box(3,3)=0.75+r*2.25 -q=q*r*1000 - -!!!--------------------------------------------------------------!!! -!!!Sets the random angles between the unit vectors between 60-120!!! -!!!--------------------------------------------------------------!!! - angle(:)=0 -!!! BRAVAIS LATTICES - if (b.eq.1) then !!! Triclinic - do i=1, 3 - call random_number(r) - r=r*60.0+60.0 ! - r=(r*pi)/(180.0) ! - angle(i)=r - end do - else if (b.eq.2) then !!! Cubic - q=1 - call random_number(r) - box(1,1)=0.75+r*2.25 - q=q*(r**3)*1000.0 - box(2,2)=box(1,1) - box(3,3)=box(1,1) - angle(:)=pi/2.0 - else if (b.eq.3) then !!! Monoclinic - angle(3)=pi/2 - angle(1)=pi/2 - call random_number(r) - r=r*60.0+60.0 - r=(r*pi)/(180.0) - angle(2)=r - else if (b.eq.4) then !!! Orthorhombic - angle(:)=pi/2.0 - else if (b.eq.5) then !!! Tetragonal B - q=1 - call random_number(r) - box(1,1)=0.75+r*2.25 - box(2,2)=box(1,1) - q=q*(r**2) - call random_number(r) - box(3,3)=0.75+r*2.25 - q=q*r*1000 - angle(:)=pi/2.0 - - else if (b.eq.6) then !!! Rhombohedral very broken/ Trigonal :-( - q=1 - call random_number(r) - - box(1,1)=0.75+r*2.25 - ! box(1,1)=5.0 - box(2,2)=box(1,1) - box(3,3)=box(1,1) - q=q*(r**3)*1000 - !print*, box(1,1) - call random_number(r) - r=(r*60.0)+60.0 - r=(r*pi)/(180.0) - angle(:)=r - ! angle(:)= 1.75*pi/3.0 - !print*, angle(:) - else if (b.eq.7) then !!! hexagonal - angle(1)=pi/2.0 - angle(2)=pi/2.0 - angle(3)=2.0*pi/3.0 - call random_number(r) - box(1,1)=0.75+r*2.25 - box(2,2)=box(1,1) - q=r**2 - call random_number(r) - box(3,3)=0.75+r*2.25 - q=q*r*1000 - end if - - -!!!---------------------------------!!! -!!Sets the new unit vectors !!! -!!!---------------------------------!!! - -!! Creates a TYPE called formula that contains all the info for a unit cell that is random - -calc=sin(angle(1))**2-cos(angle(2))**2-cos(angle(3))**2 -calc=calc+cos(angle(1))*cos(angle(2))*cos(angle(3))*2 -calc=sqrt(calc) -calc=calc/(sin(angle(1))) - -formula(structures)%cell=0 -formula(structures)%cell(1,1)=box(1,1)*calc -formula(structures)%cell(2,1)=box(1,1)*(cos(angle(3))-cos(angle(1))*cos(angle(2)))/(sin(angle(1))) -formula(structures)%cell(3,1)=box(1,1)*cos(angle(2)) -formula(structures)%cell(2,2)=box(2,2)*sin(angle(1)) -formula(structures)%cell(3,2)=box(2,2)*cos(angle(1)) -formula(structures)%cell(3,3)=box(3,3) - - -write(name,'(A11,I0.3,A7)')"pos/POSCAR_",structures+prev_structures,"/POSCAR" -open(structures+10000, file=name) -write(structures+10000,*) "Test" -write(structures+10000,*) 1.0 - - -!! Adjusts the the lengths of the unit cell vectors by the -normvol=cellvol(formula(structures)%cell) -normvol=abs(normvol)/meanvol - -normvol=normvol**(1.0/3.0) - -do j=1, 3 - do i=1, 3 - formula%cell(i,j)=formula(structures)%cell(i,j)/normvol - - end do - write(structures+10000,*) formula(structures)%cell(:,j) -end do - -!!!----------------------------------------------!!! -!!!Set everything to what it should be and places the atoms -!!!----------------------------------------------!!! - -!!! Assigns all the atoms to the correct species label. -k=0 -z=0 -m=0 -l=0 -do j=1, eltot - -k=k+stochio(j) -m=m+27*stochio(j) - do i=1, leng - if(modeselect.eq.1) exit - if((i.le.k).and.(i.gt.z)) then - atomlist(structures,i)%name=elnames(j) - end if - end do - do i=1, leng*27 - if(modeselect.eq.1) exit - if((i.le.m).and.(i.gt.l)) then - alistrep(structures,i)%name=elnames(j) - end if - end do - -z=k -l=m -end do - - -!!!!!!!!!!!!! This section places the atoms via distribution !!!!!!!!!!!!!!!!!!!!!!!!!!!! -do j=1, 3 - call random_number(r) - atomlist(structures,1)%position(j)=r - alistrep(structures,1)%position(j)=r -end do -errorcounter=0 -atomlist(structures,1)%position(:)=matmul(formula(structures)%cell,atomlist(structures,1)%position(:)) -call atomrepeater(structures,atomlist(structures,1)%position,alistrep,formula,1,leng) -call invar(8,tmpdig,tmpels) -b=tmpdig(1) -deallocate(tmpdig) -print*, dble(b/100.0) -open(99,file="errorfile") -sigma1=0.1 -i=1 -aloop: do while (i.le.leng-1) - if(errorcounter.gt.1000) then - !sigma1=sigma1*1.01 - !print*, "Sigma being increased", sigma1 - - errorcounter=0 - end if - tmpvector=0 - do j=1, 3 - call random_number(r) - tmpvector(j)=r - end do - distribution=0 - tmpvector=matmul(formula(structures)%cell,tmpvector) - - do y=1, i*27 - if(y.eq.i+1) cycle - posneg=1 - do j=1, eltot - do x=1, eltot - if(atomlist(structures,i+1)%name.ne.elnames(j)) cycle - if(alistrep(structures,y)%name.ne.elnames(x)) cycle - if(bondlength(tmpvector,alistrep(structures,y)%position).lt.& - &elrad(1,j,x)*dble(b/100.0)) then - write(99,*) "Atoms too close together" - errorcounter=errorcounter+1 - cycle aloop - end if - distribution=distribution*(y-1) - tmpvalue=bondlength(tmpvector,alistrep(structures,y)%position) - distribution=distribution+& - &(1.0/4.0)*abs(erf((tmpvalue& - &-elrad(1,j,x)+0.5*sigma1)/(sigma1*sqrt(2.0))))-& - &(1.0/4.0)*abs(erf((tmpvalue& - &-elrad(1,j,x)-0.5*sigma1)/(sigma1*sqrt(2.0)))) - if(tmpvalue.lt.10) then - distribution=distribution+0.5*sigma1*0.1 - - end if - distribution=dble(distribution/(1.0*y)) - end do - end do - end do - call random_number(r) - if(r.gt.distribution) then - errorcounter=errorcounter+1 - cycle aloop - end if - print*,r, distribution, i - atomlist(structures,i+1)%position=tmpvector - call atomrepeater(structures,atomlist(structures,i+1)%position,alistrep,formula,i+1,leng) - if(i.eq.leng-1) exit - i=i+1 - errorcounter=0 -end do aloop -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!Build in some failsafes - changing sigma iteratively or change the probability width -!can also change the minimum allowed bondlength now!! Wouldn't use this too often - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!Generate the atomic bonding information files used in upcoming learning algorithm - -do i=1, leng -call generatebondfiles(structures,atomlist,alistrep,eltot,stochio,i) -end do - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -j=0 -k=0 - - -CALL invar(8,tmpdig,tmpels) -do i=1, eltot - do k=1, eltot - do x=1, leng*27 - if(modeselect.eq.1) exit - do y=1, leng*27 - if(x.ge.y) cycle - if(alistrep(structures,x)%name.ne.elnames(k)) cycle - if(alistrep(structures,y)%name.ne.elnames(i)) cycle - if(bondlength(alistrep(structures,x)%position,alistrep(structures,y)%position)& - &.lt.(elrad(1,k,i)*dble(tmpdig(1)/100.0))) then - j=j+1 - close(structures+10000) - print*, "Terminating. Bond lengths too short" - deallocate(tmpdig) - cycle BIGLOOP - end if - end do - end do - end do -end do -deallocate(tmpdig) -m=j -!! The following determines the total number of bonds that each atom has made -!! This is defined by the MAXBOND input parameter -CALL invar(9,tmpdig,tmpels) -do i=1, eltot - do k=1, eltot - if(i.gt.k) cycle - do x=1, leng - - if(modeselect.eq.1) exit - do y=1, leng*27 - if(atomlist(structures,x)%name.ne.elnames(k)) cycle - if(alistrep(structures,y)%name.ne.elnames(i)) cycle - bondlist(x,y,i,k)=bondlength(atomlist(structures,x)%position,alistrep(structures,y)%position) - bondlist(y,x,k,i)=bondlist(x,y,i,k) - if(bondlist(x,y,i,k).gt.(dble(tmpdig(1)/100.0)*elrad(1,i,k))) then; - bondlist(x,y,i,k)=0 - bondlist(y,x,k,i)=0 - cycle - end if - end do - end do - end do -end do -deallocate(tmpdig) - -!! The following, for each species pairing, generates an average bondlength. At the end of -!! the first eltot loop, the value m can be read out to be the total bonding for that pairing -bondavg=0 -inquire(file="bonddata.txt", exist=dir_e) - if(dir_e) then - open(81,status="old",file="bonddata.txt", access="append") - else - open(81,status="new",file="bonddata.txt", access="append") - end if - - -do i=1, eltot - do k=1, eltot - if(i.gt.k) cycle - m=0 - do x=1, leng - if(atomlist(structures,x)%name.ne.elnames(k)) cycle - if(modeselect.eq.1) exit - do y=1, leng*27 - if(bondlist(x,y,i,k).gt.0.001) then - if(alistrep(structures,y)%name.ne.elnames(i)) cycle - bondavg(i,k)=bondavg(i,k)+bondlist(x,y,i,k) - m=m+1 - end if - end do - end do - bondavg(i,k)=(dble(bondavg(i,k))/m) - bondavg(k,i)=bondavg(i,k) - end do -end do -write(81,*) bondavg(1,2) -close(81) - -!allocate(tempmatrix(leng,leng*27)) - -inquire(file="bondsfile.txt", exist=dir_e) - if(dir_e) then - open(81,status="old",file="bondsfile.txt", access="append") - else - open(81,status="new",file="bondsfile.txt", access="append") - end if -do x=1, eltot - do y=1, eltot - if(x.gt.y) cycle - do i=1, leng - m=0 - do j=1, leng*27 - if(bondlist(i,j,x,y).gt.0.001) then; - m=m+1 - write(81,*) bondlist(i,j,x,y),i,j,x,y - !print*, "!!" - !tempmatrix(1,m)=bondlist(i,j,x,y) - end if - end do - !print*, minval(tempmatrix,MASK=tempmatrix.gt.0.01) - !deallocate(tempmatrix) - end do - - end do -end do -close(81) -!! The folowing calculates the difference between all bonds and their corresponding average -!! If that value is greater than a tolerance, the bonds are deemed too varied. -!! This section is primed for deletion, as maybe unimportant -CALL invar(10,tmpdig,tmpels) -do i=1, eltot - do k=1, eltot - do x=1, leng - if(modeselect.eq.1) exit - do y=1, leng*27 - q=abs(bondlist(x,y,i,k)-bondavg(i,k)) - if(q.gt.dble(tmpdig(1)/100.0)*bondavg(i,k)) then - close(structures+10000) - print*, "Terminating. Bond lengths too varied" - deallocate(tmpdig) - cycle BIGLOOP - end if - end do - end do - end do -end do -q=0 -deallocate(tmpdig) - - -do z=1, eltot - do l=1, eltot - do i=1, leng*27 - if(modeselect.eq.1) exit - do k=1, leng*27 - do j=1, leng - if(i.eq.k) cycle - if(alistrep(structures,i)%name.ne.elnames(z)) cycle - if(alistrep(structures,j)%name.ne.elnames(l)) cycle - if(bondlength(alistrep(structures,i)%position,atomlist(structures,j)%position).gt.bondavg(z,l)*1.2) cycle - if(bondlength(alistrep(structures,k)%position,atomlist(structures,j)%position).gt.bondavg(z,l)*1.2) cycle - if(bondlength(alistrep(structures,i)%position,atomlist(structures,j)%position).lt.0.001) cycle - if(bondlength(alistrep(structures,k)%position,atomlist(structures,j)%position).lt.0.001) cycle - - !!NEEDS CORRECTLY IMPLEMENTING WITH MULTIPLE SPECIES - - !print*, bondangle(alistrep(structures,i)%position,& - ! &atomlist(structures,j)%position,alistrep(structures,k)%position) - !if(bondangle(alistrep(structures,i)%position,& - ! &atomlist(structures,j)%position,alistrep(structures,k)%position).lt.10) then - ! close(structures+10000) - ! print*, "Terminating, tiny angles in system" - ! cycle BIGLOOP - !end if - - !if(bondangle(alistrep(structures,i)%position,& - ! &atomlist(structures,j)%position,alistrep(structures,k)%position).gt.170) then - ! close(structures+10000) - ! print*, "Terminating, big angles in system" - ! cycle BIGLOOP - !end if - end do - end do - end do - end do -end do - -!!!THIS SECTION ASSUMES AN AVERAGE COORDINATION NUMBER. THIS IS LIKELY VERY UNPHYSICAL!!! ALSO ASSUMES 2.5A BONDLENGTH -!k=0 -!do i=1, leng -! if(modeselect.eq.1) exit -! do j=1, leng*27 -! if(bondlength(atomlist(structures,i)%position,alistrep(structures,j)%position).gt.(bondavg+0.2)) cycle -! k=k+1 -! end do -!end do -!k=nint(dble(k/leng)) -!m=0 - -!! HYPER SPECIFIC COORDINATION SECTION -!if(k.ne.4) then -! close(structures+10000) -! print*, "Terminating. Coordination number incorrect" -! cycle bigloop -!end if -!!!COORDINATION NUMBER NEEDS TO BE MORE SOPHISTICATED. -!do i=1, leng -! if(modeselect.eq.1) exit -! do j=1, leng*27 -! if(bondlength(atomlist(structures,i)%position,alistrep(structures,j)%position).gt.(bondavg+0.2)) cycle -! m=m+1 -! end do - !print*, m, k -! if(m.gt.k+1) then -! close(structures+10000) -! print*, "Terminating. Coordination number incorrect" -! cycle bigloop -! end if -! if(m.lt.k-1) then -! close(structures+10000) -! cycle bigloop -! end if -! m=0 -!end do -!print*, q - - -if(q.lt.0.0001) then -call poswrite(formula(structures)%cell,atomlist,leng, structures, structno, prev_structures) - -write(tmp,'(A11,I0.3)')"pos/POSCAR_",structures+prev_structures -call Incarwrite(adjustl(tmp),500, 20*leng) -call Jobwrite(tmp,3,3,3) - -write(11,*) "For structure number", structures+prev_structures -write(11,*) "The average bond value is", bondavg -write(11,*) "The lower bound for allowed bonds is", bondavg-0.2 -write(11,*) "The upper bound for allowed bonds is", bondavg+0.2 -call potwrite(tmp, elnames, eltot) -close(structures+10000) -structures=structures+1 - -end if -close(structures+10000) - - - -end do BIGLOOP -end subroutine generation - - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - - -subroutine densitylineplot2(spacelist, formula, atomlist, alistrep, nbin, len, sigma, nbin2, nbinf, structno, atomlistt) - type(unitcell), dimension(:), allocatable :: formula - double precision, dimension(3,3) :: box - double precision, dimension(3) :: test,spacelist - integer :: i,j,k,m,len, n, nbin, nbin2,x,y,z, nbinf, structno, structures, prev_structures,p - type (atom), dimension(:,:), allocatable :: atomlist, alistrep, atomlistt - double precision :: r, meanvol, alpha, beta, gamma,normvol,posneg, pi,q,a,b,c, sigma - integer, dimension(:), allocatable :: seed - double precision, dimension(3) :: angle - type (densitymatrix), dimension(:), allocatable :: density - character(1024) :: name, tmp, command - logical :: dir_e - allocate(atomlistt(structno,len)) - prev_structures=structurecounter("don") - open(71, file='prevstructures.txt') - write(71, '(I0.3)') prev_structures - write(71, '(I0.3)') structno - close(71) - - - - do structures=1, structno - - do i=1, len - allocate(atomlist(structures,i)%radden(2,nbinf*nbin2))!**3)) - atomlist(structures,i)%radden=0 - allocate(atomlistt(structures,i)%radden(2,nbinf*nbin2))!**3)) - atomlistt(structures,:)=atomlist(structures,:) - end do - - - write(name, '(A8,I0.3,A4)') "don/DON_",structures+prev_structures,"/DON" - write(tmp,'(A8,I0.3)') "don/DON_",structures+prev_structures - inquire(file=tmp, exist=dir_e) - if(dir_e) then - else - write(command,'(A14,I0.3)')"mkdir don/DON_",structures+prev_structures - call execute_command_line(command) - end if - - - open(structures+1000, file=name) - - pi=3.14159265358979323846 - j=1 - do k=1, len - do n=1, len*27 - if (n.eq.k) cycle - do i=1, nbin2*nbinf - !atomlist(structures,k)%radden(1,i)=(i-1)*(maxval(formula(1)%cell)/nbin2)! - !!WE ARE HERE CHANGIN TO A 10Angstorm/Nbin circle radius!! - atomlist(structures,k)%radden(1,i)=(i-1)*(10.0/nbin2) - ! if(bondlength(atomlist(structures,k)%position,alistrep(structures,n)%position)& - ! &.ge.((i+0.5)*maxval(formula(1)%cell)/nbin2)) cycle - !print*, dble(i+0.5)*dble(5.0/nbin2), (dble(i-0.5)*dble(5.0/nbin2)),bondlength(atomlist(structures,k)%& - !&position,alistrep(structures,n)%position) - if(bondlength(atomlist(structures,k)%position,alistrep(structures,n)%position)& - &.ge.(dble(i+0.5)*dble(5.0/nbin2))) then - cycle - end if - !if(bondlength(atomlist(structures,k)%position,alistrep(structures,n)%position)& - ! &.lt.((i-0.5)*maxval(formula(1)%cell)/nbin2)) cycle - if(bondlength(atomlist(structures,k)%position,alistrep(structures,n)%position)& - &.lt.(dble(i-0.5)*dble(5.0/nbin2))) then - cycle - end if - atomlist(structures,k)%radden(2,i)=atomlist(structures,k)%radden(2,i)+1.0 - !print*, atomlist(structures,k)%radden(2,i) - !print*,atomlist(k)%radden(2,j) - !print*, "larger" - end do - end do - end do - !print*, atomlist(structures,1)%radden(2,:) - atomlistt=atomlist - do i=1, nbin2*nbinf - do j=1, nbin2*nbinf - do k=1, len - if(k.eq.n) cycle - if(i.eq.j) cycle -! print*, atomlistt(structures,k)%radden(2,i) - atomlistt(structures,k)%radden(2,i)=atomlistt(structures,k)%radden(2,i)+atomlist(structures,k)%radden(2,j)*& - &exp(-((atomlist(structures,k)%radden(1,i)-atomlist(structures,k)%radden(1,j))**2)/(2*sigma**2)) - !print*, atomlistt(structures, k)%radden(2,i) - !!!Shifts down far field into lower sig - !print*, dble((i*5.0)/nbin2) - - !if((dble((i*5.0)/nbin2).gt.2.0)) & - ! &atomlistt(structures,k)%radden(2,i)=(atomlistt(structures,k)%radden(2,i))/(dble(i*5.0/nbin2)**3) - !print*, atomlistt(structures,k)%radden(2,i) - end do - end do - end do - do k=1, len - do i=1, nbin2*nbinf - - !if((dble((i*5.0)/nbin2).gt.3.0)) then - ! atomlistt(structures,k)%radden(2,i)=(atomlistt(structures,k)%radden(2,i))/(dble(i*5.0/nbin2)**3) - ! write(structures+1000,*) atomlistt(structures,k)%radden(:,i) - !else - write(structures+1000, *) atomlistt(structures,k)%radden(:,i) - !end if - end do - !write(structures+1000, *) - write(structures+1000, *) - end do - close(structures+1000) - end do - -end subroutine densitylineplot2 - -subroutine lineplotcomparison(atomlistt, nbin2, formula, structno, nbinf, len, sigma, pi) - type(unitcell), dimension(:), allocatable :: formula - integer :: i,j,k,m,len, n, nbin, nbin2,x,y,z, nbinf, structno, structures, io,l, jp, p - type (atom), dimension(:,:), allocatable :: alistrep, atomlistt, atomlist - double precision :: pi,q,a,b,c, sigma,r, tmp - logical :: file_exists - character(1024) :: name - - name='hello' - - !allocate(r(nbin2*nbinf)) - n=1 - open(96, file="test") - - do i=1, structurecounter("don") - do k=1, len - jp=j - j=1 - write(name,'(A8,I0.3,A4)') "don/DON_", i,"/DON" - open(1000+i, file=name, status='old') - read(1000+i, *) r - do - read(1000+i,*, iostat=io) - if (io/=0) exit - j=j+1 - end do - if(i.ne.1) then - if(jp.ne.j) print*, "Warning your lengths are inconsistent" - end if - close(1000+i) - end do - write(6, '(A1, 40X, A1)', advance='no') achar(13), achar(13) - - write(6,'(A13,I0.3,A10)', advance='no')"Process 1 is ",nint(dble(100.0*i/structurecounter("don"))), "% complete" - end do - - do i=1, structno - do l=1, structno - atomloop: do m=1, len - atomloop2: do p=1, len - r=0 - if(p.gt.m) cycle - if(i.eq.l) cycle - if(i.gt.l) cycle - do k=1, nbin2*nbinf - r=r+5.0*min(atomlistt(i,m)%radden(2,k),(atomlistt(l,p)%radden(2,k)))/nbin2 - end do - r=1-(r/(sqrt(2.0*pi)*27*len*sigma)) - write(96, *) i,r - if(r.gt.0.2) then - exit Atomloop - else if (m.eq.len) then - print*, "I have identified two similar structures",& - &structurecounter("don")-structno+i,structurecounter("don")-structno+l, m - end if - - end do atomloop2 - end do atomloop - end do - end do - - print*, "The analysis of the created structures reveals the above matches" - - if(structurecounter("don").le.structno) then - print*, "No structures exist in databse" - else - allocate(atomlist(1,len)) - do i=1, len - allocate(atomlist(1,i)%radden(2,j)) - end do - - do i=1, structurecounter("don")-structno - write(name,'(A8,I0.3,A4)') "don/DON_", i,"/DON" - open(1000+i, file=name, status='old') - - do l=1, structno - atomloopexistingloop: do m=1, len - do k=1, (j-2)/len - if(l.eq.1) read(1000+i, *) atomlist(1,m)%radden(:,k) - end do - r=0 - if(i.eq.l) cycle - if(i.gt.l) cycle - do k=1,j - r=r+5.0*min(atomlistt(l,m)%radden(2,k),(atomlist(1,m)%radden(2,k)))/nbin2 - end do - r=1-(r/(sqrt(2.0*pi)*27*len*sigma)) - !write(96, *) i,r - if(r.gt.0.2) then - exit Atomloopexistingloop - else if (m.eq.len) then - print*, "One of the structures generated matches a database structure", & - &structurecounter("don")-structno+l,i - end if - end do atomloopexistingloop - close(1000+i) - end do - end do - end if - - print*, "Comparison of these structures with existing structures reveals the above matches" - - close(96) -end subroutine lineplotcomparison - -subroutine symcalc(atomlist, nbin2, nbinf, len, structures, sigma, structno) - integer :: i,j,k,m,len, n, nbin, nbin2,x,y,z, nbinf, structno, structures, io,l, jp - type (atom), dimension(:,:), allocatable :: alistrep, atomlistt, atomlist - double precision :: pi,q,a,b,c, sigma,r, tmp - character(1024) :: name - pi=3.141592564 - open(99, file="test3") - a=0 - - do i=1, structno - do l=1, len - do j=1, nbin2*nbinf - a=a+(dble((5.0)/(nbin2))*atomlist(i,l)%radden(2,j))**2 - a=sqrt(a) - !a=dble(a/(sqrt(2.0*pi)*len*sigma)) - - end do - end do - write(99, *) i,a - end do -end subroutine symcalc - -subroutine chemread(elnames, eltot, elrad) -character(3), dimension(:), allocatable :: elnames -character(3) :: read1, read2 -double precision :: r_vdw, r_cov, c1, c2 -integer :: increment, i, eltot, j, Reason -double precision, dimension(:,:,:), allocatable :: elrad - - - -open(77, file="chem.in", status="old") -do - read(77, *, IOSTAT=Reason) read1, read2, r_cov, r_vdw, c1, c2 - if (Reason.gt.0) then; - stop - ! print*, "Something wrong with chem.in file" - else if(Reason.lt.0) then; - print*, "Done" - exit - else - print*, trim(adjustl(read1)), " ",trim(adjustl(read2))," ", r_cov, " ", r_vdw - do i=1, eltot - do j=1, eltot - if(elnames(i).eq.trim(adjustl(read1))) then; - if(elnames(j).eq.trim(adjustl(read2))) then; - elrad(1,i,j)=r_cov - elrad(2,i,j)=r_vdw - elrad(3,i,j)=c1 - elrad(1,j,i)=r_cov - elrad(2,j,i)=r_vdw - elrad(3,j,i)=c1 - if(elnames(i).ne.elnames(j)) then; - elrad(3,i,j)=c1 - elrad(4,i,j)=c2 - elrad(4,j,i)=c1 - elrad(3,j,i)=c2 - - print*, elnames(i),c1,",",elnames(j),c2 - end if - continue - end if - end if - if(elnames(j).eq.trim(adjustl(read1))) then; - if(elnames(i).eq.trim(adjustl(read2))) then; - elrad(1,j,i)=r_cov - elrad(2,j,i)=r_vdw - elrad(3,j,i)=c1 - if(elnames(i).ne.elnames(j)) then; - elrad(3,j,i)=c1 - elrad(4,j,i)=c2 - elrad(4,j,i)=c1 - elrad(3,j,i)=c2 - - end if - continue - - end if - end if - end do - - end do - end if -end do - -print*, elrad(1,1,1), elrad(1,2,1) -print*, elrad(1,1,2), elrad(1,2,2) - - -print*, elrad(1,1,1), elrad(1,2,1) - - - -end subroutine chemread - -subroutine atomrepeater(structures,position,array,unit,atomnumber,length) -use atomtype -implicit none -type (atom), dimension(:,:), allocatable :: array -double precision, dimension(3) :: position -integer :: j,atomnumber,length,x,y,z,structures,m -type(unitcell), dimension(:), allocatable :: unit - - -m=((atomnumber-1)*27)+1 -do x=-1,1 - do y=-1,1 - do z=-1,1 - do j=1, 3 - !print*, array(structures,m)%position(j),position(j) - array(structures,m)%position(j)=position(j)+& - &(x*unit(structures)%cell(j,1))+& - &(y*unit(structures)%cell(j,2))+& - &(z*unit(structures)%cell(j,3)) - !print*, array(structures,m)%position(j) - end do - m=m+1 - end do - end do -end do -end subroutine atomrepeater - -subroutine generatebondfiles(structures,array,repeatedarray,eltot,stochio,atomnumber) -use atomtype -implicit none -character(1024) :: command,name,tmp -integer :: l,i,structures,prev_structures, eltot, atomnumber, tmpint,m,j -type (atom), dimension(:,:), allocatable :: array, repeatedarray -integer, dimension(:), allocatable :: stochio -logical :: dir_e - -inquire(file="bon",exist=dir_e) -if(dir_e) then - else - call execute_command_line("mkdir bon") - end if - -prev_structures=structurecounter("bon") - -write(tmp,'(A8,I0.3)') "bon/BON_",structures+prev_structures -inquire(file=tmp, exist=dir_e) -if(dir_e) then -else - write(command,'(A14,I0.3)')"mkdir bon/BON_",structures+prev_structures - call execute_command_line(command) -end if - - - - -i=1 -tmpint=atomnumber -do while (i.eq.1) - if((tmpint-stochio(i)).gt.0) then - tmpint=tmpint-stochio(i) - else - i=0 - end if -end do -write(name, '(A8,I0.3,A1,A,A,I0.3)') "bon/BON_",structures+prev_structures,"/",& - &trim(adjustl(array(structures,atomnumber)%name)),"_",tmpint -open(101, file=name) -m=1 -do j=1, eltot - write(101,*) array(structures,m)%name - do i=1, stochio(j) - do l=1, 27 - - write(101,*) bondlength(repeatedarray(structures,m)%position,& - &array(structures,atomnumber)%position) - m=m+1 - end do - end do -end do -!write(tmp,'(A8,I0.3)') "don/DON_",structures+prev_structures -!inquire(file=tmp, exist=dir_e) -!if(dir_e) then -!else -! write(command,'(A14,I0.3)')"mkdir don/DON_",structures+prev_structures -! call execute_command_line(command) -!end if - - -end subroutine generatebondfiles - - subroutine addposcar() - type(unitcell), dimension(:), allocatable :: formula - character(1024) :: tmp, name - character(1024), dimension(:), allocatable :: elnames - double precision :: cellmultiplier - integer :: k,j,i,structno, ecount, eltot, leng,structures, prev_structures - type (atom), dimension(:,:), allocatable :: atomlist, alistrep - integer, dimension(:), allocatable :: elno - !! Wipes the randomly generated formula - structures=1 - structno=1 - prev_structures=structurecounter("pos") - print*, prev_structures - call touchpos() - call touchposdir(structures,prev_structures) - allocate(formula(structno)) - - write(6,*) "Please enter the filename you wish to add to the database" - !read(*, *) name - write(name,"(A6)") "POSCAR" - open(50, file=name) - print*, "step 1" - read(50, '(A)') tmp - read(50, '(F16.0)') cellmultiplier - - do i=1, 3 - read(50, * ) formula(1)%cell(1,i),& - &formula(1)%cell(2,i),formula(1)%cell(3,i) - end do - write(name,'(A11,I0.3,A7)')"pos/POSCAR_",structures+prev_structures,"/POSCAR" - open(structures+10000, file=name,status="new") - write(structures+10000,*) "Test" - write(structures+10000,*) 1.0 - do i=1, 3 - write(structures+10000,*) formula(1)%cell(1,i),formula(1)%cell(2,i),formula(1)%cell(3,i) - end do - read(50,'(A)') tmp - - ecount=0 - eltot=0 - allocate(atomlist(1,1000)) - allocate(elnames(1024)) - do i=1,len(tmp) - if((scan(tmp(i:i+1)," ").eq.0).or.& - &((scan(tmp(i:i+1)," ").eq.2).and.(scan(tmp(i-1:i)," ")& - &.eq.1))) then - eltot=eltot+1 - !print*, tmp(i:i+1) - if(scan(tmp(i:i+1)," ").eq.0) then - elnames(eltot)=tmp(i:i+1) - end if - if((scan(tmp(i:i+1)," ").eq.2).and.(scan(tmp(i-1:i)," ").eq.1)) then - elnames(eltot)=tmp(i:i) - end if - else - end if - end do - - allocate(elno(eltot)) - read(50,'(4X)', advance='no') - k=0 - read(50,*) elno - print*, elno(:) - read(50, *) tmp - k=0 - do i=1, eltot - do j=1, elno(i) - k=k+1 - atomlist(structures,k)%name=elnames(i) - end do - end do - print*, k - - do i=1, eltot - do j=1, elno(i) - read(50, *)& - &atomlist(structures,j)%position(1),atomlist(structures,j)%position(2),& - &atomlist(structures,j)%position(3) - print*, atomlist(structures,j)%position(:) - !print*, atomlist(1,j)%position(1),atomlist(1,j)%position(2),atomlist(1,j)%position(3\ - - end do - end do - - call poswrite(formula(structures)%cell,atomlist,k,1,1,prev_structures) - allocate(alistrep(1,k*27)) - do i=1, k - call atomrepeater(structures,atomlist(structures,i)%position,alistrep,& - &formula,i,k) - end do - do i=1, k - call generatebondfiles(structures,atomlist,alistrep,eltot,elno,i) - end do - - end subroutine addposcar - -end module gen diff --git a/src/backup/backupsub.f90 b/src/backup/backupsub.f90 deleted file mode 100644 index 1af3e64a..00000000 --- a/src/backup/backupsub.f90 +++ /dev/null @@ -1,415 +0,0 @@ -module help -use atomtype -implicit none - - -TYPE densitymatrix - double precision, dimension(3) :: position - double precision :: density - integer :: checked -end type densitymatrix - -TYPE unitcell - double precision, dimension(3,3) :: cell -end type unitcell - -contains -subroutine touchpos() - - character(1024) :: file, command - logical :: dir_e - - inquire(file="pos", exist=dir_e) - if(dir_e) then - else - write(command,*) "mkdir pos" - CALL execute_command_line(command) - end if -end subroutine touchpos - -subroutine touchposdir(structures,prev_structures) - character(1024) :: name, tmp, command - logical :: dir_e - integer :: structures, prev_structures - write(name,'(A11,I0.3,A7)')"pos/POSCAR_",structures+prev_structures,"/POSCAR" - !!Calculates the new structure number, and writes it to tmp - write(tmp,'(A11,I0.3)')"pos/POSCAR_",structures+prev_structures - !!Checks if a directory to contain that file exsts already (It should never exist, could add warning) - inquire(file=tmp, exist=dir_e) - if(dir_e) then - else - !!Writes a command to create said directory - write(command,'(A17,I0.3)')"mkdir pos/POSCAR_",structures+prev_structures - CALL execute_command_line(trim(adjustl(command))) - end if -end subroutine touchposdir - - - - - recursive subroutine invar(a,b,c) - implicit none - integer :: a,i, tmpvar - character(1024) :: buffer, command - integer, dimension(:), allocatable :: b - character(3), dimension(:), allocatable, intent(out) :: c - - - open(71, file="Infile.txt") - rewind(71) - do i=1, a - read(71,'(A,X,A,X,A,X,A,X,A,X,A,X,A,X,A)') buffer - end do - close(71) - ! print*, buffer - write(command,'(4A,X,A,X,A,X,A)') "(echo",' "',trim(adjustl(buffer)),'" | ','sed -e "s/^.*=//g")>tmp.txt' - CALL execute_command_line(command) - !print*, command - open(72,file="tmp.txt") - - if(a.le.3) then - allocate(b(1)) - read(72,*) b - close(72) - else if(a.eq.4) then - close(72) - CALL invar(2,b,c) - - open(71, file="Infile.txt") - rewind(71) - do i=1, a - read(71,'(A,X,A,X,A,X,A,X,A,X,A,X,A,X,A)') buffer - end do - close(71) - ! print*, buffer - write(command,'(4A,X,A,X,A,X,A)') "(echo",' "',trim(adjustl(buffer)),'" | ','sed -e "s/^.*=//g")>tmp.txt' - CALL execute_command_line(command) - ! print*, command - open(72,file="tmp.txt") - - tmpvar=b(1) - deallocate(b) - allocate(c(tmpvar)) - read(72,*) c - - close(72) - - else if(a.eq.5) then - close(72) - CALL invar(2,b,c) - - open(71, file="Infile.txt") - rewind(71) - do i=1, a - read(71,'(A,X,A,X,A,X,A,X,A,X,A,X,A,X,A)') buffer - end do - close(71) - ! print*, buffer - write(command,'(4A,X,A,X,A,X,A)') "(echo",' "',trim(adjustl(buffer)),'" | ','sed -e "s/^.*=//g")>tmp.txt' - CALL execute_command_line(command) - ! print*, command - open(72,file="tmp.txt") - - tmpvar=b(1) - deallocate(b) - allocate(b(tmpvar)) - read(72,*) b - print*, b - close(72) - else if(a.le.10) then - allocate(b(1)) - read(72,*) b - close(72) - end if - - - write(command,*) "rm tmp.txt" - CALL execute_command_line(command) - end subroutine invar -!!!-------------------------------------------------------------!!! -!!!This function provides the cross product of two vectors !!! -!!!-------------------------------------------------------------!!! - -function cross(a,b) result(axb) -implicit none -integer,parameter :: wp=selected_real_kind(15, 307) !double precision -double precision,dimension(3) :: axb -double precision,dimension(3),intent(in) :: a -double precision,dimension(3),intent(in) :: b -axb(1) = a(2)*b(3) - a(3)*b(2) -axb(2) = a(3)*b(1) - a(1)*b(3) -axb(3) = a(1)*b(2) - a(2)*b(1) -end function cross - -!!!---------------------------------------------------------------------------!!! -!!!This function writes a list of atomic positions to the POSCAR in cartesian !!! -!!!---------------------------------------------------------------------------!!! - -subroutine poswrite(box,atomlist,len, structures, structno, prev_structures) - -integer :: i,j, len, reason, structures, structno, prev_structures -type(atom), dimension(:,:) :: atomlist -double precision, dimension(3,3) :: box - -print*, box -do i=1, len - if(i.eq.len) then - write(structures+10000,'(5X,A2)', IOStat=reason, advance="no")& - &atomlist(structures,i)%name - else - !if(i.eq.(len-1)) cycle - if (atomlist(structures,i)%name.eq.atomlist(structures,i+1)%name) cycle - write(structures+10000,'(5X,A2)', IOStat=reason, advance="no") & - &atomlist(structures,i)%name - end if -end do - -write(structures+10000, '(10X)') -!write(structures+10000,*) "HERE" -j=1 -do i=1, len - if(i.eq.len) then - write(structures+10000,'(10X,I3)', IOStat=reason, advance="no") j - else - if (atomlist(structures,i)%name.eq.atomlist(structures,i+1)%name) then - j=j+1 - cycle - else - write(structures+10000,'(9X,I3)', IOStat=reason, advance="no") j - j=1 - - end if - end if -end do - - -write(structures+10000,'(/,A)') "Cartesian" - -do i=1, len - write(structures+10000,'(6X,F0.16,6X,F0.16,6X,F0.16)') atomlist(structures,i)%position(:) -end do - -end subroutine poswrite - -!!!-------------------------------------------------!!! -!!!This function returns normvol as the cell volume !!! -!!!-------------------------------------------------!!! - -function sphereoverlap(r,rp,b, pi) result(volume) - double precision :: r,rp,volume, b, step1, step2, pi, step3 - step1=pi*(r+rp-b)**2 - step2=(b**2)+(2*b*rp)-(3*(rp**2))+(2*b*r)+(6*rp*r)-3*(r**2) - step3=1.0/(12.0*b) -! print*, "Sub.f90 ->" ,step1*step2*step3 - volume=step1*step2*step3 - -end function sphereoverlap - -function cellvol(x) result(normvol) - double precision, dimension(3,3) :: x - double precision, dimension(3) :: a,b,c, tmp - integer :: i - double precision :: normvol - a=x(:,1) - b=x(:,2) - c=x(:,3) - tmp=cross(b,c) - normvol=0 - do i=1,3 - normvol=normvol+a(i)*tmp(i) - end do - !print*, "Cell volume is", abs(normvol) -end function cellvol - - -!!!Bondlength!!! -function bondlength(A,B) result(C) - double precision, dimension(3), intent(in) :: A,B - double precision :: C - C= (((A(1)-B(1))**2)+((A(2)-B(2))**2)+((A(3)-B(3))**2))**0.5 -end function bondlength - -function structurecounter(dir_t) result(n) - logical :: file_exists - character(1024) :: name, dir_name, dir_append - character(3) :: dir_t - integer :: n - n=1 - do while(n.ne.0) - if(dir_t.eq."don") dir_name="/DON_" - if(dir_t.eq."pos") dir_name="/POSCAR_" - if(dir_t.eq."don") dir_append="/DON" - if(dir_t.eq."pos") dir_append="/POSCAR" - if(dir_t.eq."bon") dir_name="/BON_" - if(dir_t.eq."bon") dir_append="/BON" - write(name,'(A3,A,I0.3,A7)') dir_t,trim(adjustl(dir_name)), n,dir_append - name=trim(adjustl(name)) - INQUIRE(FILE=name, EXIST=file_exists) - if(file_exists) then - n=n+1 - cycle - else - n=n-1 - - exit - end if - end do -end function structurecounter - -function bondangle(A,B,C) result(theta) -double precision :: theta, x -double precision, dimension(3) :: A,B,C, bond1, bond2 -integer :: i -bond1(:)=A(:)-B(:) -bond2(:)=C(:)-B(:) -x=0 -do i=1,3 -x=x+bond1(i)*bond2(i) -end do -x=x/(bondlength(A,B)*bondlength(B,C)) -theta=(180.0/3.141592654)*acos(x) - - -!print*, A,B,C,bond1, bond2,"theta is", theta*180.0/3.141592654 -end function bondangle - -subroutine Incarwrite(filepath,nstep,bandno) -character(1024) :: name -integer :: nstep, bandno -character(1024) :: filepath - - -write(name,'(A,A6)') trim(filepath), "/INCAR" -!print*, trim(adjustl(name)) -open(unit=11,file=trim(adjustl(name)), status='new')!"pos/POSCAR_001")!trim(name)) - -write(11, *)"SYSTEM = RSS" -write(11, *)"### sys ###" -write(11, *)"GGA = PE " -write(11, *)"ISYM = 0" -write(11, *)"ENCUT = 500" -write(11, *)"ENAUG = 500" -write(11, *)"PREC = Accurate" -write(11, *)"ISTART = 1" -write(11, *)"ICHARG = 2" -write(11, *)"LWAVE = .FALSE." -write(11, *)"LAECHG =.FALSE." -write(11, *)"LMAXMIX = 6" -write(11, *)"LASPH = .TRUE." -write(11, *)"LMIXTAU = .TRUE." -write(11, *)"LREAL = .FALSE." -write(11, *)"NWRITE = 3" -write(11, *)"ALGO = N" -write(11, *)"LHAR = .FALSE." -write(11, *)"LVTOT = .FALSE." -write(11, *) - -write(11, *)"### vdw ###" -write(11, *)"#IVDW = 11" -write(11, *)"#VDW_RADIUS = 80" -write(11, *)"#VDW_CNRADIUS = 50.0" -write(11, *)"#VDW_S8 = 0.722" -write(11, *)"#VDW_SR = 1.217" -write(11, *) - -write(11, *)"### elc ###" -write(11, *)"#AMIX = 0.6" -write(name,'(I0.3)') nstep -write(11, *)"NELM = ", adjustL(trim(name)) -write(11, *)"NELMIN = 5" -write(11, *)"NELMDL = -5" -write(11, '(1X,A,1X,I0.3)') "NBANDS =", bandno -write(11, *)"EDIFF = 10d-8" -write(11, *)"ISMEAR = 0" - -!!! THIS SHOULD BE CHANGED BASED ON INTUITION - -write(11, *)"SIGMA = 0.2" -write(11, *) - -write(11, *)"### Mag ###" -write(11, *)"ISPIN = 2" -write(11, *)"#MAGMOM = 1 -1 1 1 -1 -1" -write(11, *) - -write(11, *)"### ncl ###" -write(11, *)"#LNONCOLLINEAR = .TRUE." -write(11, *)"#LSORBIT = .TRUE." -write(11, *)"#GGA_COMPAT = .FALSE." -write(11, *) - -write(11, *)"### MPI ###" -write(11, *)"#NCORE = 24" -write(11, *)"#KPAR = 2" -write(11, *) - -write(11, *)"### Rlx ###" -write(11, *)"#LMAXPAW =-1" -write(11, *)"ADDGRID = .TRUE." -write(11, *)"#POTIM = 0.1" -write(11, *)"#NFREE = 15" -write(11, *)"#NSW = 150" -write(11, *)"#ISIF = 2" -write(11, *)"#IBRION = 1" -write(11, *)"#EDIFFG = -0.001" -write(11, *) - -write(11, *)"### dos ###" -write(11, *)"#EMIN = -3.0" -write(11, *)"#EMAX = 6.0" -write(11, *)"#NEDOS = 5000" -write(11, *)"#LORBIT = 11" - -close(11) -end subroutine Incarwrite - -subroutine Jobwrite(filepath, a,b,c) - - integer :: a,b,c -character(1024) :: name -character(20) :: filepath -name=" " -!print*, filepath -write(name,'(A,A8)') trim(filepath), "/KPOINTS" -open(unit=11,file=trim(adjustl(name)), status='new')!"pos/POSCAR_001")!trim(name)) -write(11, '(A7)') "KPOINTS" -write(11, '(A1)') "0" -write(11, '(A1)') "G" -write(11, '(I1,1X,I1,1X,I1)') a, b, c -write(11, '(I1,1X,I1,1X,I1)') 0,0,0 -close(11) -end subroutine Jobwrite - - - - - -subroutine potwrite(filepath, elnames, eltot) - - character(3), dimension(:), allocatable :: elnames - character(1024) :: name - character(20) :: filepath - integer :: eltot, i - name=" " - !print*, filepath - !print*, eltot - do i=1, eltot - - !print*, i - if(i.eq.1) then - !print*, "I reached here" - write(name, '(A3,1X,A6,A2,1X,A1,A,A)') "cat", "potcar", elnames(i),">",trim(adjustl(filepath)),"/POTCAR" - !print*, name - call execute_command_line(name) - else - write(name, '(A,1X,A,A,1X,A,A,1X,A,1X,A,A)') "cat ",trim(adjustl(filepath)),"/POTCAR", "potcar", elnames(i)," >>",& - & trim(adjustl(filepath)),"/POTCAR1" - - call execute_command_line(name) - write(name,'(A,1X,A,A8,1X,A,A)') "mv ",trim(adjustl(filepath)),"/POTCAR1", trim(adjustl(filepath)),"/POTCAR" - call execute_command_line(name) - end if - - end do -end subroutine potwrite -end module help diff --git a/src/backup/mainBACKUP.f90 b/src/backup/mainBACKUP.f90 deleted file mode 100644 index 3d3f7cc7..00000000 --- a/src/backup/mainBACKUP.f90 +++ /dev/null @@ -1,189 +0,0 @@ -PROGRAM random -use help -use gen -use atomtype -implicit none -type(unitcell), dimension(:), allocatable :: formula -double precision, dimension(3,3) :: box -double precision, dimension(3) :: test,spacelist -integer :: i,j,k,m,len, n, clock, reason, nbin, nbin2,x,y,z, nbinf, structno, structures, options, eltot, coordination -integer, dimension(:), allocatable :: stochio -type (atom), dimension(:,:), allocatable :: atomlist, alistrep, atomlistt -double precision :: r, meanvol, alpha, beta, gamma,normvol,posneg, pi,q,a,b,c, sigma, bond_test, returned_val -double precision , dimension(:), allocatable :: cutoff -integer, dimension(:), allocatable :: seed -double precision, dimension(3) :: angle, x1,x2,x3,x4 -type (densitymatrix), dimension(:), allocatable :: density -character(3), dimension(:), allocatable :: elnames -double precision, dimension(:,:,:), allocatable :: elrad -character(1024) :: buffer, command -!!For input -character(1024), dimension(:), allocatable :: tmpels -integer, dimension(:), allocatable :: tmpdig -character(1024) :: dummy - -!!Is Pie -pi=3.14159265358979323846 - - -!!! Reads Input file !!! - -!CALL angledistribution("C ") - -!x1=0.0 -!x2=0.0 -!x3=0.0 -! x4=0.0 -! x1(1)=1.0 -! x3(2)=1.0 -! x4(3)=1.0 -! print*, x1 -! print*, x2 -! print*, x3 -! print*, fourbody(x1,x2,x3,x4) -! stop - - - - -!! This needs to be activated for a full run that reads in new samples -!call bond_evolution() - -CALL invar(1,tmpdig,tmpels) -! GENERATE THIS MANY STRUCTURES -structno=tmpdig(1) -deallocate(tmpdig) -structno=structno!*7 -! THINK THIS IS DEFUNCT -nbin=100 -! RESOLUTION OF DON -nbin2=200 -! RESOLUTOIN OF REPEATED DON -nbinf=2 -! WIDTH OF GAUSSIAN FIT TO DON -sigma=0.2 -! SPECIES NUMBER -CALL invar(2,tmpdig,tmpels) -eltot=tmpdig(1) -deallocate(tmpdig) -! SPECIAL CASES -CALL invar(3,tmpdig,tmpels) -options=tmpdig(1) -deallocate(tmpdig) - - - - - -!!!! 0) Run RSS -!!!! 1) Regenerate DIst Files (WIP) -!!!! 2) Run HOST_RSS -!!!! 3) Test -!!!! 4) Sphere_Overlap -!!!! 5) Bondangle_test -!!!! 6) Run evo (Should be run after any set created) -!!!! 7) Add new poscar -!!!! 8) Run evo, but don't regen energies or evolve distributions (only reformat gaussians) -!!!! 9) Run evo, don't get energies but do evolve distributions -allocate(elnames(eltot)) - -!!!---------------------------------------------------------------------------------------! -!!!Assign the elements of each atom ! -!!!--------------------------------------------------------------------------------------! - - - CALL invar(4,tmpdig,tmpels) - do i=1, eltot - elnames(i)=tmpels(i) - end do - deallocate(tmpels) - allocate(stochio(eltot)) - !! How many of each would you like - CALL invar(5,tmpdig,tmpels) - do i=1, eltot - stochio(i)=tmpdig(i) - end do - deallocate(tmpdig) - len=0 - !! Total number of atoms - do i=1, eltot - len=len+stochio(i) - end do - - - -!!FIX here -if(options.eq.7) then - call addposcar(0,dummy,1,0) - !call addxyzfile() - stop -end if - - -if(options.eq.1) then - call regenerate_distribution_files (800) -stop -end if - -if (options.eq.3) then - bond_test=1.430 - print*, bond_test - CALL evaluate_contribution ("C ","C ",bond_test,returned_val) - stop -end if - - - -if(options.eq.4) then - CALL chemread(elnames,eltot,elrad) - print*, sphereoverlap(2*elrad(1,1,1),elrad(1,1,1),elrad(1,1,1),pi) - print*, (4.0/3.0)*pi*elrad(1,1,1)**3 - stop -end if -if(options.eq.5) then - x1=0.0 - x1(1)=-1.0 - x2=0.0 - x2(2)=0.0 - x3=0.0 - x3(3)=1.0 - print*, bondangle(x1,x2,x3) - stop -end if -if (options.eq.6) then - call bond_evolution(1) - stop -end if -if (options.eq.8) then - call bond_evolution(0) - stop -end if -if (options.eq.9) then - call bond_evolution(2) - stop -end if - -!CALL chemread(elnames,eltot,elrad) -allocate(formula(structno)) - -!!!-----------------------------!!! -!!!Random number initialisation !!! -!!!-----------------------------!!! -CALL RANDOM_SEED(size=n) -ALLOCATE(seed(n)) -CALL SYSTEM_CLOCK(COUNT=clock) -seed = clock + 37 * (/ (i - 1, i = 1, n) /) -CALL RANDOM_SEED(PUT = seed) -DEALLOCATE(seed) - -!!!--------------------------------------------------!!! -!!!Set the number of atoms and generate the unit cell!!! -!!!--------------------------------------------------!!! - - - -call generation(len, atomlist, alistrep, spacelist, formula, structno,options, eltot, elnames, stochio, elrad) -print*, "The structures requested have been successfully generated and saved" - -end PROGRAM random - From cc37fb8150b4887dbed29b02edd2d2d64be16771 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Tue, 23 Jul 2024 14:11:27 +0100 Subject: [PATCH 069/293] Remove superfluous bash scripts --- tools/CurrEn.sh | 72 ------ tools/R2CurrEn.sh | 20 -- tools/SCurrEn.sh | 69 ------ tools/bond_database_builder.sh | 39 ---- tools/bond_evolution.sh | 404 --------------------------------- tools/bondlength_gaussifier.sh | 16 -- tools/similarity.sh | 98 -------- 7 files changed, 718 deletions(-) delete mode 100755 tools/CurrEn.sh delete mode 100755 tools/R2CurrEn.sh delete mode 100755 tools/SCurrEn.sh delete mode 100755 tools/bond_database_builder.sh delete mode 100755 tools/bond_evolution.sh delete mode 100755 tools/bondlength_gaussifier.sh delete mode 100755 tools/similarity.sh diff --git a/tools/CurrEn.sh b/tools/CurrEn.sh deleted file mode 100755 index 88bb951c..00000000 --- a/tools/CurrEn.sh +++ /dev/null @@ -1,72 +0,0 @@ -rm volen.txt -rm currens.txt -for i in $(seq 1 9) -do - echo $i - echo "Final energy from 1st step" - energy=$(grep "e e" pos/POSCAR_00$i/RELAX/OUTCAR | tail -1) - energyp=$(echo $energy | sed -e "s/.* = //g") - echo $i $energyp >> currens.txt - #echo "Current energy from 2nd step" - #grep "e e" pos/POSCAR_00$i2/RELAX/OUTCAR | tail -1 - vectora=$(sed -n 3"p" > volen.txt - -done - -for i in $(seq 10 99) -do - - echo $i - echo "Final energy from 1st step" - energy=$(grep "e e" pos/POSCAR_0$i/RELAX/OUTCAR | tail -1) - energyp=$(echo $energy | sed -e "s/.* = //g") - echo $i $energyp >> currens.txt - #echo "Current energy from 2nd step" - #grep "e e" pos/POSCAR_00$i2/RELAX/OUTCAR | tail -1 - vectora=$(sed -n 3"p" > volen.txt - - - - - - - -done -#echo "hello" -for i in $(seq 100 700) -do - echo $i - echo "Final energy from 1st step" - energy=$(grep "e e" pos/POSCAR_$i/RELAX/OUTCAR | tail -1) - energyp=$(echo $energy | sed -e "s/.* = //g") - echo $i $energyp >> currens.txt - #echo "Current energy from 2nd step" - #grep "e e" pos/POSCAR_00$i2/RELAX/OUTCAR | tail -1 - vectora=$(sed -n 3"p" > volen.txt - - -done diff --git a/tools/R2CurrEn.sh b/tools/R2CurrEn.sh deleted file mode 100755 index 71111a26..00000000 --- a/tools/R2CurrEn.sh +++ /dev/null @@ -1,20 +0,0 @@ -for i in $(seq 1 9) -do - echo $i - echo "Final energy from 1st step" - grep "e e" pos/POSCAR_00$i/RELAX/RELAX2/OUTCAR | tail -1 - #echo "Current energy from 2nd step" - #grep "e e" pos/POSCAR_00$i2/RELAX/OUTCAR | tail -1 -done - -for i in $(seq 10 99) -do - echo $i - grep "e e" pos/POSCAR_0$i/RELAX/RELAX2/OUTCAR | tail -1 -done -#echo "hello" -#for i in $(seq 100 300) -#do -# echo $i -# grep "e e" pos/POSCAR_$i/RELAX/OUTCAR | tail -1 -#done diff --git a/tools/SCurrEn.sh b/tools/SCurrEn.sh deleted file mode 100755 index 558e403e..00000000 --- a/tools/SCurrEn.sh +++ /dev/null @@ -1,69 +0,0 @@ -for i in $(seq 1 9) -do - echo $i - echo "Final energy from 1st step" - energy=$(grep "e e" pos/POSCAR_00$i/OUTCAR | tail -1) - energyp=$(echo $energy | sed -e "s/.* = //g") - echo $energyp >> currens.txt - #echo "Current energy from 2nd step" - #grep "e e" pos/POSCAR_00$i2/RELAX/OUTCAR | tail -1 - vectora=$(sed -n 3"p" > volen.txt - - - - - -done - -for i in $(seq 10 99) -do - - echo $i - echo "Final energy from 1st step" - energy=$(grep "e e" pos/POSCAR_0$i/OUTCAR | tail -1) - energyp=$(echo $energy | sed -e "s/.* = //g") - echo $energyp >> currens.txt - #echo "Current energy from 2nd step" - #grep "e e" pos/POSCAR_00$i2/RELAX/OUTCAR | tail -1 - vectora=$(sed -n 3"p" > volen.txt - - -done - -for i in $(seq 100 700) -do - echo $i - echo "Final energy from 1st step" - energy=$(grep "e e" pos/POSCAR_$i/OUTCAR | tail -1) - energyp=$(echo $energy | sed -e "s/.* = //g") - echo $energyp >> currens.txt - #echo "Current energy from 2nd step" - #grep "e e" pos/POSCAR_00$i2/RELAX/OUTCAR | tail -1 - vectora=$(sed -n 3"p" > volen.txt - - -done diff --git a/tools/bond_database_builder.sh b/tools/bond_database_builder.sh deleted file mode 100755 index 78beb36a..00000000 --- a/tools/bond_database_builder.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash - - -rm bond_element_tempfile -pairing_string=$(echo $(ls *_evolved_bondlength) | sed -e 's|_evolved_bondlength||g') -echo $pairing_string -loop_control=1 -while [[ $loop_control -eq 1 ]] -do - first_element=$(echo $pairing_string | sed -n 's| .*||p') - - if [[ -z $first_element ]]; then - first_element=$pairing_string - loop_control=0 - fi - trimmed_string=$(echo $pairing_string | sed -n 's|[a-zA-Z]*_[a-zA-Z]* ||p') - - pairing_string=$trimmed_string - echo $first_element >> bond_element_tempfile -done - -rm angle_element_tempfile -single_string=$(echo $(ls *_evolved_angles) | sed -e 's|_evolved_angles||g') -echo $single_string -loop_control=1 -while [[ $loop_control -eq 1 ]] -do - first_element=$(echo $single_string | sed -n 's| .*||p') - - if [[ -z $first_element ]]; then - first_element=$single_string - loop_control=0 - fi - trimmed_string=$(echo $single_string | sed -n 's|[a-zA-Z]* ||p') - - single_string=$trimmed_string - echo $first_element >> angle_element_tempfile -done - diff --git a/tools/bond_evolution.sh b/tools/bond_evolution.sh deleted file mode 100755 index 686ac78b..00000000 --- a/tools/bond_evolution.sh +++ /dev/null @@ -1,404 +0,0 @@ -#!/bin/bash - - -best_energy () { - -while read line; do - if [[ -z $line ]]; then - break - fi - if [[ -z $(echo $line | sed -n "s|[0-9]*.[0-9]* ||p") ]]; then - continue - fi - #break line down into location delimiter and energy value - structure_location=$(echo $line | sed -n 's|\..*||p' ) - structure_stage=$(echo $(echo $line | sed -n 's|[0-9]*\.||p' )| sed -n 's| \-*[0-9]*\.*[0-9]*||p') - - echo $structure_location $structure_stage - if [[ $structure_stage == "1" ]]; then - - reader=$(sed -n '7p' < pos/POSCAR_$structure_location/POSCAR) - element_names=$(sed -n '6p ' < pos/POSCAR_$structure_location/POSCAR) - #cell_volume_a=$(sed -n '3p' < pos/POSCAR_$structure_location/POSCAR) - #cell_volume_b=$(sed -n '4p' < pos/POSCAR_$structure_location/POSCAR) - elif [[ $structure_stage == "2" ]]; then - reader=$(sed -n '7p' < pos/POSCAR_$structure_location/RELAX/CONTCAR) - element_names=$(sed -n '6p ' < pos/POSCAR_$structure_location/RELAX/CONTCAR) - #cell_volume_a=$(sed -n '3p' > weightings.txt - -done < tmp_energies.txt - -} - - - - - - -create_distribution () { -#element_string_parent=$(echo $(grep "elements=" Infile.txt) | sed -n "s|elements=||p") -#stochio_list_parent=$(echo $(grep "stochiometry=" Infile.txt) | sed -n "s|stochiometry=||p") -#eltot=$(echo $(grep "speciestotal=" Infile.txt) | sed -n "s|speciestotal=||p") - -rm *_evolved_angle* -rm *_evolved_bond* -rm *_evolved_4* - - -while read weightings_file; do - echo "----------------------------------------------------------------------------------------------------------" - if [[ -z $weightings_file ]]; then - break - fi - structure_location=$(echo $weightings_file | sed -n 's|\..*||p' ) - structure_stage=$(echo $(echo $weightings_file | sed -n 's|[0-9]*\.||p' )| sed -n 's| \-*[0-9]*\.*[0-9]*||p') - echo $structure_location $structure_stage "is the stage that this calculation should be compared to" - if [[ $structure_stage == "1" ]]; then - - reader=$(sed -n '7p' < pos/POSCAR_$structure_location/POSCAR) - element_names=$(sed -n '6p ' < pos/POSCAR_$structure_location/POSCAR) - #cell_volume_a=$(sed -n '3p' < pos/POSCAR_$structure_location/POSCAR) - #cell_volume_b=$(sed -n '4p' < pos/POSCAR_$structure_location/POSCAR) - elif [[ $structure_stage == "2" ]]; then - reader=$(sed -n '7p' < pos/POSCAR_$structure_location/RELAX/CONTCAR) - element_names=$(sed -n '6p ' < pos/POSCAR_$structure_location/RELAX/CONTCAR) - #cell_volume_a=$(sed -n '3p' > $element_current"_"$target_element"_evolved_bondlength" - if [[ $atom_details == "NaN" ]]; then - echo $atom_path_bon - exit - fi - echo $atom_details >> $atom_path_bon$element_current"_"$target_element"_bond_distribution" - fi - fi - done < "$atom_path_bon" - while read atom_angles; do - if [[ -z $atom_angles ]]; then - break - else - #echo $atom_angles - #echo "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" - echo $atom_angles $weighting >> $element_current"_evolved_angles" - fi - done < "$atom_path_bad" - while read atom_four; do - if [[ -z $atom_four ]]; then - break - else - echo $atom_four - echo $atom_four $weighting >> $element_current"_evolved_4body" - fi - done < $atom_path_four - done - done - -done < weightings.txt - -} -best_energy -create_weightings -create_distribution diff --git a/tools/bondlength_gaussifier.sh b/tools/bondlength_gaussifier.sh deleted file mode 100755 index 095cbfe8..00000000 --- a/tools/bondlength_gaussifier.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -gaussify () { - -cap=$1 -bins=$2 -rm "$3"_"$4"_bond_gauss -for i in $(seq 1 $bins); -do - echo $(echo "$i*$cap/$bins" | bc -l) "0" >> "$3"_"$4"_bond_gauss -done -sigma=0.1 - -} - -gaussify $1 $2 $3 $4 diff --git a/tools/similarity.sh b/tools/similarity.sh deleted file mode 100755 index 1d6aa4d1..00000000 --- a/tools/similarity.sh +++ /dev/null @@ -1,98 +0,0 @@ -#!/bin/bash -var=$(>similarity_combinations.txt - - -for i in $(seq 1 $total) -do - reader=$(sed -n '7p' < ../DC_MgO/pos/POSCAR_$(printf "%03d" $i)/POSCAR) - if [[ -z $reader ]]; then - continue 2 - fi - el1=$(echo $reader | cut -d' ' -f1) - tester=$(echo $reader | sed -n "s/ //p") - echo $i - element_names=$(sed -n '6p' < ../DC_MgO/pos/POSCAR_$(printf "%03d" $i)/POSCAR) - - status=0 - statusp=0 - stochio_i=0 - el1=0 - attot=0 - attotp=0 - elle=1 - if [[ -z $tester ]]; then - attotp=$el1 - else - - while [[ $status -ne "-1" ]] - - do - if [[ -z $el1 ]]; then - elle=$(echo "$status-1" | bc -l) - status=-1 - else - - statusp=$(echo "$status + 1" | bc -l) - status=$statusp - #echo "found an element" - attot=$(echo "$el1 + $attotp" | bc -l) - attotp=$attot - el1=$(echo $reader | cut -d' ' -f$status) - - fi - done - fi - echo $i>>similarity_combinations.txt - echo $elle>>similarity_combinations.txt - atoms_total_expression=0 - - - for p in $(seq 1 $elle) - do - - x=$(echo $element_names | sed -n 's|[a-zA-Z]* ||1p') - step_1_stochio=$(echo $reader | sed -n 's|[0-9]* ||1p') - if [[ -z $x ]]; then - y=$element_names - stochio_i=$reader - echo $stochio_i>>similarity_combinations.txt - echo $y>>similarity_combinations.txt - - else - y=$(echo $element_names | sed -n "s| ${x}||p") - element_names=$x - stochio_i=$(echo $reader | sed -n "s| ${step_1_stochio}||p") - reader=$step_1_stochio - - echo $stochio_i >>similarity_combinations.txt - echo $y>>similarity_combinations.txt - - - fi - atoms_total_expression=$atoms_total_expression"+ "$stochio_i - - done - atoms_total=$(echo $atoms_total_expression | bc -l) - echo $atoms_total>>similarity_combinations.txt -done -#Key -#First entry=total structures -#General format -#N+1=structure number -#N+2=ath stoichio -#N+3=ath el name - -#N+2a+1=total atoms From 3d3c32039582243672e9da077a94480e4984cd96 Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Tue, 23 Jul 2024 15:11:24 +0100 Subject: [PATCH 070/293] Move element charge and mass procedure --- src/fortran/lib/mod_read_structures.f90 | 356 ----------------------- src/fortran/lib/mod_rw_geom.f90 | 371 ++++++++++++++++++++++++ 2 files changed, 371 insertions(+), 356 deletions(-) diff --git a/src/fortran/lib/mod_read_structures.f90 b/src/fortran/lib/mod_read_structures.f90 index 5305a44e..4e305263 100644 --- a/src/fortran/lib/mod_read_structures.f90 +++ b/src/fortran/lib/mod_read_structures.f90 @@ -144,7 +144,6 @@ function get_evolved_gvectors_from_data(input_dir, & if(trim(buffer).eq."") cycle backspace(unit) call geom_read(unit, basis) - call get_elements_masses_and_charges(basis) #ifdef ENABLE_ATHENA graphs = [ graphs, get_graph_from_basis(basis) ] labels = [ labels, basis%energy ] @@ -339,359 +338,4 @@ end function get_graph_from_basis #endif !!!############################################################################# - -!!!############################################################################# -!!! get elements masses and charges -!!!############################################################################# - subroutine get_elements_masses_and_charges(basis) - implicit none - type(bas_type), intent(inout) :: basis - - integer :: i - real(real12) :: mass, charge - - do i = 1, basis%nspec - select case(basis%spec(i)%name) - case('H') - mass = 1.00784_real12 - charge = 1.0_real12 - case('He') - mass = 4.0026_real12 - charge = 2.0_real12 - case('Li') - mass = 6.94_real12 - charge = 3.0_real12 - case('Be') - mass = 9.0122_real12 - charge = 4.0_real12 - case('B') - mass = 10.81_real12 - charge = 5.0_real12 - case('C') - mass = 12.011_real12 - charge = 4.0_real12 - case('N') - mass = 14.007_real12 - charge = 5.0_real12 - case('O') - mass = 15.999_real12 - charge = 6.0_real12 - case('F') - mass = 18.998_real12 - charge = 7.0_real12 - case('Na') - mass = 22.989_real12 - charge = 1.0_real12 - case('Mg') - mass = 24.305_real12 - charge = 2.0_real12 - case('Al') - mass = 26.982_real12 - charge = 3.0_real12 - case('Si') - mass = 28.085_real12 - charge = 4.0_real12 - case('P') - mass = 30.974_real12 - charge = 5.0_real12 - case('S') - mass = 32.06_real12 - charge = 6.0_real12 - case('Cl') - mass = 35.453_real12 - charge = 8.0_real12 - case('K') - mass = 39.098_real12 - charge = 1.0_real12 - case('Ca') - mass = 40.078_real12 - charge = 2.0_real12 - case('Sc') - mass = 44.956_real12 - charge = 3.0_real12 - case('Ti') - mass = 47.867_real12 - charge = 4.0_real12 - case('V') - mass = 50.942_real12 - charge = 5.0_real12 - case('Cr') - mass = 51.996_real12 - charge = 6.0_real12 - case('Mn') - mass = 54.938_real12 - charge = 7.0_real12 - case('Fe') - mass = 55.845_real12 - charge = 8.0_real12 - case('Co') - mass = 58.933_real12 - charge = 9.0_real12 - case('Ni') - mass = 58.693_real12 - charge = 10.0_real12 - case('Cu') - mass = 63.546_real12 - charge = 11.0_real12 - case('Zn') - mass = 65.38_real12 - charge = 12.0_real12 - case('Ga') - mass = 69.723_real12 - charge = 13.0_real12 - case('Ge') - mass = 72.63_real12 - charge = 14.0_real12 - case('As') - mass = 74.922_real12 - charge = 15.0_real12 - case('Se') - mass = 78.971_real12 - charge = 16.0_real12 - case('Br') - mass = 79.904_real12 - charge = 17.0_real12 - case('Kr') - mass = 83.798_real12 - charge = 18.0_real12 - case('Rb') - mass = 85.468_real12 - charge = 19.0_real12 - case('Sr') - mass = 87.62_real12 - charge = 20.0_real12 - case('Y') - mass = 88.906_real12 - charge = 21.0_real12 - case('Zr') - mass = 91.224_real12 - charge = 22.0_real12 - case('Nb') - mass = 92.906_real12 - charge = 23.0_real12 - case('Mo') - mass = 95.95_real12 - charge = 24.0_real12 - case('Tc') - mass = 98.0_real12 - charge = 25.0_real12 - case('Ru') - mass = 101.07_real12 - charge = 26.0_real12 - case('Rh') - mass = 102.91_real12 - charge = 27.0_real12 - case('Pd') - mass = 106.42_real12 - charge = 28.0_real12 - case('Ag') - mass = 107.87_real12 - charge = 29.0_real12 - case('Cd') - mass = 112.41_real12 - charge = 30.0_real12 - case('In') - mass = 114.82_real12 - charge = 31.0_real12 - case('Sn') - mass = 118.71_real12 - charge = 32.0_real12 - case('Sb') - mass = 121.76_real12 - charge = 33.0_real12 - case('Te') - mass = 127.6_real12 - charge = 34.0_real12 - case('I') - mass = 126.9_real12 - charge = 35.0_real12 - case('Xe') - mass = 131.29_real12 - charge = 36.0_real12 - case('Cs') - mass = 132.91_real12 - charge = 37.0_real12 - case('Ba') - mass = 137.33_real12 - charge = 38.0_real12 - case('La') - mass = 138.91_real12 - charge = 39.0_real12 - case('Ce') - mass = 140.12_real12 - charge = 40.0_real12 - case('Pr') - mass = 140.91_real12 - charge = 41.0_real12 - case('Nd') - mass = 144.24_real12 - charge = 42.0_real12 - case('Pm') - mass = 145.0_real12 - charge = 43.0_real12 - case('Sm') - mass = 150.36_real12 - charge = 44.0_real12 - case('Eu') - mass = 152.0_real12 - charge = 45.0_real12 - case('Gd') - mass = 157.25_real12 - charge = 46.0_real12 - case('Tb') - mass = 158.93_real12 - charge = 47.0_real12 - case('Dy') - mass = 162.5_real12 - charge = 48.0_real12 - case('Ho') - mass = 164.93_real12 - charge = 49.0_real12 - case('Er') - mass = 167.26_real12 - charge = 50.0_real12 - case('Tm') - mass = 168.93_real12 - charge = 51.0_real12 - case('Yb') - mass = 173.05_real12 - charge = 52.0_real12 - case('Lu') - mass = 174.97_real12 - charge = 53.0_real12 - case('Hf') - mass = 178.49_real12 - charge = 54.0_real12 - case('Ta') - mass = 180.95_real12 - charge = 55.0_real12 - case('W') - mass = 183.84_real12 - charge = 56.0_real12 - case('Re') - mass = 186.21_real12 - charge = 57.0_real12 - case('Os') - mass = 190.23_real12 - charge = 58.0_real12 - case('Ir') - mass = 192.22_real12 - charge = 59.0_real12 - case('Pt') - mass = 195.08_real12 - charge = 60.0_real12 - case('Au') - mass = 196.97_real12 - charge = 61.0_real12 - case('Hg') - mass = 200.59_real12 - charge = 62.0_real12 - case('Tl') - mass = 204.38_real12 - charge = 63.0_real12 - case('Pb') - mass = 207.2_real12 - charge = 64.0_real12 - case('Bi') - mass = 208.98_real12 - charge = 65.0_real12 - case('Th') - mass = 232.04_real12 - charge = 66.0_real12 - case('Pa') - mass = 231.04_real12 - charge = 67.0_real12 - case('U') - mass = 238.03_real12 - charge = 68.0_real12 - case('Np') - mass = 237.0_real12 - charge = 69.0_real12 - case('Pu') - mass = 244.0_real12 - charge = 70.0_real12 - case('Am') - mass = 243.0_real12 - charge = 71.0_real12 - case('Cm') - mass = 247.0_real12 - charge = 72.0_real12 - case('Bk') - mass = 247.0_real12 - charge = 73.0_real12 - case('Cf') - mass = 251.0_real12 - charge = 74.0_real12 - case('Es') - mass = 252.0_real12 - charge = 75.0_real12 - case('Fm') - mass = 257.0_real12 - charge = 76.0_real12 - case('Md') - mass = 258.0_real12 - charge = 77.0_real12 - case('No') - mass = 259.0_real12 - charge = 78.0_real12 - case('Lr') - mass = 262.0_real12 - charge = 79.0_real12 - case('Rf') - mass = 267.0_real12 - charge = 80.0_real12 - case('Db') - mass = 270.0_real12 - charge = 81.0_real12 - case('Sg') - mass = 271.0_real12 - charge = 82.0_real12 - case('Bh') - mass = 270.0_real12 - charge = 83.0_real12 - case('Hs') - mass = 277.0_real12 - charge = 84.0_real12 - case('Mt') - mass = 276.0_real12 - charge = 85.0_real12 - case('Ds') - mass = 281.0_real12 - charge = 86.0_real12 - case('Rg') - mass = 280.0_real12 - charge = 87.0_real12 - case('Cn') - mass = 285.0_real12 - charge = 88.0_real12 - case('Nh') - mass = 284.0_real12 - charge = 89.0_real12 - case('Fl') - mass = 289.0_real12 - charge = 90.0_real12 - case('Mc') - mass = 288.0_real12 - charge = 91.0_real12 - case('Lv') - mass = 293.0_real12 - charge = 92.0_real12 - case('Ts') - mass = 294.0_real12 - charge = 93.0_real12 - case('Og') - mass = 294.0_real12 - charge = 94.0_real12 - case default - ! handle unknown element - mass = 0.0_real12 - charge = 0.0_real12 - end select - basis%spec(i)%mass = mass - basis%spec(i)%charge = charge - end do - - end subroutine get_elements_masses_and_charges -!!!############################################################################# - end module read_structures \ No newline at end of file diff --git a/src/fortran/lib/mod_rw_geom.f90 b/src/fortran/lib/mod_rw_geom.f90 index 1e13d0c8..4f01b25b 100644 --- a/src/fortran/lib/mod_rw_geom.f90 +++ b/src/fortran/lib/mod_rw_geom.f90 @@ -126,6 +126,10 @@ subroutine geom_read(UNIT,basis,length) basis%spec(i)%atom(:,4)=1._real12 end do end if + do i = 1, basis%nspec + call get_element_properties( & + basis%spec(i)%name, basis%spec(i)%mass, basis%spec(i)%charge ) + end do end subroutine geom_read @@ -1157,4 +1161,371 @@ subroutine clone_bas(inbas,outbas,trans_dim) end subroutine clone_bas !!!############################################################################# + +!!!############################################################################# +!!! get elements masses and charges +!!!############################################################################# + subroutine get_element_properties(element, charge, mass) + !! Set the mass and charge of the element + + ! Arguments + implicit none + character(len=3), intent(in) :: element + !! The element name. + real(real12), intent(out), optional :: charge + !! The charge of the element. + real(real12), intent(out), optional :: mass + !! The mass of the element. + + ! Local variables + real(real12) :: mass_, charge_ + + + select case(element) + case('H') + mass_ = 1.00784_real12 + charge_ = 1.0_real12 + case('He') + mass_ = 4.0026_real12 + charge_ = 2.0_real12 + case('Li') + mass_ = 6.94_real12 + charge_ = 3.0_real12 + case('Be') + mass_ = 9.0122_real12 + charge_ = 4.0_real12 + case('B') + mass_ = 10.81_real12 + charge_ = 5.0_real12 + case('C') + mass_ = 12.011_real12 + charge_ = 4.0_real12 + case('N') + mass_ = 14.007_real12 + charge_ = 5.0_real12 + case('O') + mass_ = 15.999_real12 + charge_ = 6.0_real12 + case('F') + mass_ = 18.998_real12 + charge_ = 7.0_real12 + case('Na') + mass_ = 22.989_real12 + charge_ = 1.0_real12 + case('Mg') + mass_ = 24.305_real12 + charge_ = 2.0_real12 + case('Al') + mass_ = 26.982_real12 + charge_ = 3.0_real12 + case('Si') + mass_ = 28.085_real12 + charge_ = 4.0_real12 + case('P') + mass_ = 30.974_real12 + charge_ = 5.0_real12 + case('S') + mass_ = 32.06_real12 + charge_ = 6.0_real12 + case('Cl') + mass_ = 35.453_real12 + charge_ = 8.0_real12 + case('K') + mass_ = 39.098_real12 + charge_ = 1.0_real12 + case('Ca') + mass_ = 40.078_real12 + charge_ = 2.0_real12 + case('Sc') + mass_ = 44.956_real12 + charge_ = 3.0_real12 + case('Ti') + mass_ = 47.867_real12 + charge_ = 4.0_real12 + case('V') + mass_ = 50.942_real12 + charge_ = 5.0_real12 + case('Cr') + mass_ = 51.996_real12 + charge_ = 6.0_real12 + case('Mn') + mass_ = 54.938_real12 + charge_ = 7.0_real12 + case('Fe') + mass_ = 55.845_real12 + charge_ = 8.0_real12 + case('Co') + mass_ = 58.933_real12 + charge_ = 9.0_real12 + case('Ni') + mass_ = 58.693_real12 + charge_ = 10.0_real12 + case('Cu') + mass_ = 63.546_real12 + charge_ = 11.0_real12 + case('Zn') + mass_ = 65.38_real12 + charge_ = 12.0_real12 + case('Ga') + mass_ = 69.723_real12 + charge_ = 13.0_real12 + case('Ge') + mass_ = 72.63_real12 + charge_ = 14.0_real12 + case('As') + mass_ = 74.922_real12 + charge_ = 15.0_real12 + case('Se') + mass_ = 78.971_real12 + charge_ = 16.0_real12 + case('Br') + mass_ = 79.904_real12 + charge_ = 17.0_real12 + case('Kr') + mass_ = 83.798_real12 + charge_ = 18.0_real12 + case('Rb') + mass_ = 85.468_real12 + charge_ = 19.0_real12 + case('Sr') + mass_ = 87.62_real12 + charge_ = 20.0_real12 + case('Y') + mass_ = 88.906_real12 + charge_ = 21.0_real12 + case('Zr') + mass_ = 91.224_real12 + charge_ = 22.0_real12 + case('Nb') + mass_ = 92.906_real12 + charge_ = 23.0_real12 + case('Mo') + mass_ = 95.95_real12 + charge_ = 24.0_real12 + case('Tc') + mass_ = 98.0_real12 + charge_ = 25.0_real12 + case('Ru') + mass_ = 101.07_real12 + charge_ = 26.0_real12 + case('Rh') + mass_ = 102.91_real12 + charge_ = 27.0_real12 + case('Pd') + mass_ = 106.42_real12 + charge_ = 28.0_real12 + case('Ag') + mass_ = 107.87_real12 + charge_ = 29.0_real12 + case('Cd') + mass_ = 112.41_real12 + charge_ = 30.0_real12 + case('In') + mass_ = 114.82_real12 + charge_ = 31.0_real12 + case('Sn') + mass_ = 118.71_real12 + charge_ = 32.0_real12 + case('Sb') + mass_ = 121.76_real12 + charge_ = 33.0_real12 + case('Te') + mass_ = 127.6_real12 + charge_ = 34.0_real12 + case('I') + mass_ = 126.9_real12 + charge_ = 35.0_real12 + case('Xe') + mass_ = 131.29_real12 + charge_ = 36.0_real12 + case('Cs') + mass_ = 132.91_real12 + charge_ = 37.0_real12 + case('Ba') + mass_ = 137.33_real12 + charge_ = 38.0_real12 + case('La') + mass_ = 138.91_real12 + charge_ = 39.0_real12 + case('Ce') + mass_ = 140.12_real12 + charge_ = 40.0_real12 + case('Pr') + mass_ = 140.91_real12 + charge_ = 41.0_real12 + case('Nd') + mass_ = 144.24_real12 + charge_ = 42.0_real12 + case('Pm') + mass_ = 145.0_real12 + charge_ = 43.0_real12 + case('Sm') + mass_ = 150.36_real12 + charge_ = 44.0_real12 + case('Eu') + mass_ = 152.0_real12 + charge_ = 45.0_real12 + case('Gd') + mass_ = 157.25_real12 + charge_ = 46.0_real12 + case('Tb') + mass_ = 158.93_real12 + charge_ = 47.0_real12 + case('Dy') + mass_ = 162.5_real12 + charge_ = 48.0_real12 + case('Ho') + mass_ = 164.93_real12 + charge_ = 49.0_real12 + case('Er') + mass_ = 167.26_real12 + charge_ = 50.0_real12 + case('Tm') + mass_ = 168.93_real12 + charge_ = 51.0_real12 + case('Yb') + mass_ = 173.05_real12 + charge_ = 52.0_real12 + case('Lu') + mass_ = 174.97_real12 + charge_ = 53.0_real12 + case('Hf') + mass_ = 178.49_real12 + charge_ = 54.0_real12 + case('Ta') + mass_ = 180.95_real12 + charge_ = 55.0_real12 + case('W') + mass_ = 183.84_real12 + charge_ = 56.0_real12 + case('Re') + mass_ = 186.21_real12 + charge_ = 57.0_real12 + case('Os') + mass_ = 190.23_real12 + charge_ = 58.0_real12 + case('Ir') + mass_ = 192.22_real12 + charge_ = 59.0_real12 + case('Pt') + mass_ = 195.08_real12 + charge_ = 60.0_real12 + case('Au') + mass_ = 196.97_real12 + charge_ = 61.0_real12 + case('Hg') + mass_ = 200.59_real12 + charge_ = 62.0_real12 + case('Tl') + mass_ = 204.38_real12 + charge_ = 63.0_real12 + case('Pb') + mass_ = 207.2_real12 + charge_ = 64.0_real12 + case('Bi') + mass_ = 208.98_real12 + charge_ = 65.0_real12 + case('Th') + mass_ = 232.04_real12 + charge_ = 66.0_real12 + case('Pa') + mass_ = 231.04_real12 + charge_ = 67.0_real12 + case('U') + mass_ = 238.03_real12 + charge_ = 68.0_real12 + case('Np') + mass_ = 237.0_real12 + charge_ = 69.0_real12 + case('Pu') + mass_ = 244.0_real12 + charge_ = 70.0_real12 + case('Am') + mass_ = 243.0_real12 + charge_ = 71.0_real12 + case('Cm') + mass_ = 247.0_real12 + charge_ = 72.0_real12 + case('Bk') + mass_ = 247.0_real12 + charge_ = 73.0_real12 + case('Cf') + mass_ = 251.0_real12 + charge_ = 74.0_real12 + case('Es') + mass_ = 252.0_real12 + charge_ = 75.0_real12 + case('Fm') + mass_ = 257.0_real12 + charge_ = 76.0_real12 + case('Md') + mass_ = 258.0_real12 + charge_ = 77.0_real12 + case('No') + mass_ = 259.0_real12 + charge_ = 78.0_real12 + case('Lr') + mass_ = 262.0_real12 + charge_ = 79.0_real12 + case('Rf') + mass_ = 267.0_real12 + charge_ = 80.0_real12 + case('Db') + mass_ = 270.0_real12 + charge_ = 81.0_real12 + case('Sg') + mass_ = 271.0_real12 + charge_ = 82.0_real12 + case('Bh') + mass_ = 270.0_real12 + charge_ = 83.0_real12 + case('Hs') + mass_ = 277.0_real12 + charge_ = 84.0_real12 + case('Mt') + mass_ = 276.0_real12 + charge_ = 85.0_real12 + case('Ds') + mass_ = 281.0_real12 + charge_ = 86.0_real12 + case('Rg') + mass_ = 280.0_real12 + charge_ = 87.0_real12 + case('Cn') + mass_ = 285.0_real12 + charge_ = 88.0_real12 + case('Nh') + mass_ = 284.0_real12 + charge_ = 89.0_real12 + case('Fl') + mass_ = 289.0_real12 + charge_ = 90.0_real12 + case('Mc') + mass_ = 288.0_real12 + charge_ = 91.0_real12 + case('Lv') + mass_ = 293.0_real12 + charge_ = 92.0_real12 + case('Ts') + mass_ = 294.0_real12 + charge_ = 93.0_real12 + case('Og') + mass_ = 294.0_real12 + charge_ = 94.0_real12 + case default + ! handle unknown element + mass_ = 0.0_real12 + charge_ = 0.0_real12 + end select + + !---------------------------------------------------------------------------- + ! Return the values + !---------------------------------------------------------------------------- + if(present(mass)) mass = mass_ + if(present(charge)) charge = charge_ + + + end subroutine get_element_properties +!!!############################################################################# + end module rw_geom From 0216bb560794f3399802ecfd75a17bcbd42396ce Mon Sep 17 00:00:00 2001 From: Ned Taylor Date: Tue, 23 Jul 2024 20:30:55 +0100 Subject: [PATCH 071/293] Remove need for elements file --- README.md | 5 +- app/inputs.f90 | 35 +++- app/main.f90 | 22 ++- elements.dat | 4 - example/example_files/POSCAR_host | 10 + example/example_files/chem.in | 38 ++++ example/executable/chem.in | 38 ++++ example/executable/param.in | 35 ++++ example/executable/run.sh | 3 + example/wrapper/elements.dat | 4 - example/wrapper/run.py | 21 ++- src/fortran/lib/mod_atom_adder.f90 | 3 +- src/fortran/lib/mod_elements.f90 | 55 ++++-- src/fortran/lib/mod_evolver.f90 | 231 +++++++++++++++++++++--- src/fortran/lib/mod_generator.f90 | 16 +- src/fortran/lib/mod_read_structures.f90 | 10 +- src/fortran/lib/mod_rw_geom.f90 | 8 +- src/raffle/raffle.py | 79 ++++++-- src/wrapper/f90wrap_mod_evolver.f90 | 30 ++- src/wrapper/f90wrap_mod_generator.f90 | 23 ++- 20 files changed, 565 insertions(+), 105 deletions(-) delete mode 100644 elements.dat create mode 100644 example/example_files/POSCAR_host create mode 100644 example/example_files/chem.in create mode 100644 example/executable/chem.in create mode 100644 example/executable/param.in create mode 100755 example/executable/run.sh delete mode 100644 example/wrapper/elements.dat diff --git a/README.md b/README.md index 1de5318f..666aeb81 100644 --- a/README.md +++ b/README.md @@ -67,13 +67,12 @@ make ## Using -First, you need to ensure that the following two files exist in the directory in which you run RAFFLE: +First, you need to ensure that the following file exists in the directory in which you run RAFFLE: ``` -elements.dat chem.in ``` -Each of these files should follow the format found in the current repository. They should each have a header line that starts with "#" and contains the word "element". The example headers should then be followed for filling in data. For the elements.dat, the energy provided can be whatever you want to use as a reference energy. This energy is used for calculating formation energy. The example uses energy/atom of the bulk phase of the element. The mass and charge are not currently used, but data needs to be provided in those columns. +Each of these files should follow the format found in the current repository. They should each have a header line that starts with "#" and contains the word "element". The example headers should then be followed for filling in data. For the elements.dat, the energy provided can be whatever you want to use as a reference energy. This energy is used for calculating formation energy. The example uses energy/atom of the bulk phase of the element.