1!--------------------------------------------------------------------------------------------------! 2! DFTB+: general package for performing fast atomistic simulations ! 3! Copyright (C) 2006 - 2019 DFTB+ developers group ! 4! ! 5! See the LICENSE file for terms of usage and distribution. ! 6!--------------------------------------------------------------------------------------------------! 7 8#:include 'common.fypp' 9 10 11!> Interface wrapper for the ELSI library 12!> 13module dftbp_elsiiface 14 use dftbp_accuracy, only : dp 15#:if WITH_ELSI 16 use elsi 17#:else 18 use iso_c_binding, only : r8 => c_double, i4 => c_int32_t 19 use dftbp_message, only : error 20#:endif 21 implicit none 22 private 23 24 public :: withElsi, withPexsi 25 public :: elsi_handle, elsi_rw_handle 26 public :: elsi_init, elsi_reinit, elsi_finalize 27 public :: elsi_init_rw, elsi_finalize_rw 28 public :: elsi_set_csc, elsi_set_csc_blk, elsi_set_zero_def, elsi_set_rw_zero_def 29 public :: elsi_dm_real, elsi_dm_complex 30 public :: elsi_dm_real_sparse, elsi_dm_complex_sparse 31 public :: elsi_get_edm_real, elsi_get_edm_complex 32 public :: elsi_get_edm_real_sparse, elsi_get_edm_complex_sparse 33 public :: elsi_write_mat_real_sparse, elsi_write_mat_complex_sparse 34 public :: elsi_write_mat_real, elsi_write_mat_complex 35 public :: elsi_get_pexsi_mu_min, elsi_get_pexsi_mu_max 36 public :: elsi_set_pexsi_mu_min, elsi_set_pexsi_mu_max 37 public :: elsi_get_mu, elsi_get_entropy 38 public :: elsi_set_mu_mp_order, elsi_set_mu_broaden_width, elsi_set_mu_broaden_scheme 39 public :: elsi_set_elpa_solver 40 public :: elsi_set_omm_flavor, elsi_set_omm_n_elpa, elsi_set_omm_tol 41 public :: elsi_set_pexsi_np_per_pole, elsi_set_pexsi_temp, elsi_set_pexsi_n_pole 42 public :: elsi_set_pexsi_n_mu, elsi_set_pexsi_np_symbo, elsi_set_pexsi_delta_e 43 public :: elsi_set_ntpoly_method, elsi_set_ntpoly_filter, elsi_set_ntpoly_tol 44 public :: elsi_set_spin, elsi_set_kpoint 45 public :: elsi_set_output, elsi_set_output_log 46 public :: elsi_ev_complex, elsi_ev_real 47 public :: elsi_set_rw_csc 48 public :: elsi_set_rw_mpi, elsi_set_rw_blacs 49 public :: elsi_set_mpi, elsi_set_mpi_global 50 public :: elsi_set_blacs 51 public :: elsi_set_sing_check 52 53 54 !> Whether code was built with ELSI support 55 logical, parameter :: withElsi = #{if WITH_ELSI}# .true. #{else}# .false. #{endif}# 56 57 !> Whether code was built with PEXSI support 58 logical, parameter :: withPexsi = #{if WITH_PEXSI}# .true. #{else}# .false. #{endif}# 59 60 61#:if not WITH_ELSI 62 63 ! Placeholder types when compiled without ELSI support 64 65 type :: elsi_handle 66 end type elsi_handle 67 68 type :: elsi_rw_handle 69 end type elsi_rw_handle 70 71#:endif 72 73 74contains 75 76#:if not WITH_ELSI 77 78 !> Generates error message, if a stub was called 79 subroutine stubError(routineName) 80 character(*), intent(in) :: routineName 81 82 call error("Internal error: " // trim(routineName) // "() called in a build without ELSI& 83 & support") 84 85 end subroutine stubError 86 87 88 ! 89 ! Placeholder routines when compiled without ELSI support 90 ! 91 92 subroutine elsi_init(eh, solver, parallel_mode, matrix_format, n_basis, n_electron, n_state) 93 type(elsi_handle), intent(out) :: eh 94 integer(i4), intent(in) :: solver 95 integer(i4), intent(in) :: parallel_mode 96 integer(i4), intent(in) :: matrix_format 97 integer(i4), intent(in) :: n_basis 98 real(r8), intent(in) :: n_electron 99 integer(i4), intent(in) :: n_state 100 call stubError("elsi_init") 101 end subroutine elsi_init 102 103 subroutine elsi_reinit(eh) 104 type(elsi_handle), intent(inout) :: eh 105 call stubError("elsi_reinit") 106 end subroutine elsi_reinit 107 108 subroutine elsi_finalize(eh) 109 type(elsi_handle), intent(inout) :: eh 110 call stubError("elsi_finalize") 111 end subroutine elsi_finalize 112 113 114 subroutine elsi_set_csc(eh, nnz_g, nnz_l, n_lcol, row_ind, col_ptr) 115 type(elsi_handle), intent(inout) :: eh 116 integer(i4), intent(in) :: nnz_g 117 integer(i4), intent(in) :: nnz_l 118 integer(i4), intent(in) :: n_lcol 119 integer(i4), intent(in) :: row_ind(:) 120 integer(i4), intent(in) :: col_ptr(:) 121 call stubError("elsi_set_csc") 122 end subroutine elsi_set_csc 123 124 125 subroutine elsi_set_csc_blk(eh, blk) 126 type(elsi_handle), intent(inout) :: eh 127 integer(i4), intent(in) :: blk 128 call stubError("elsi_set_csc_blk") 129 end subroutine elsi_set_csc_blk 130 131 132 subroutine elsi_set_zero_def(eh, zero) 133 type(elsi_handle), intent(inout) :: eh 134 real(r8), intent(in) :: zero 135 end subroutine elsi_set_zero_def 136 137 subroutine elsi_set_rw_zero_def(eh, zero) 138 type(elsi_rw_handle), intent(inout) :: eh 139 real(r8), intent(in) :: zero 140 end subroutine elsi_set_rw_zero_def 141 142 143 subroutine elsi_dm_real(eh, ham, ovlp, dm, ebs) 144 type(elsi_handle), intent(inout) :: eh 145 real(r8), intent(inout) :: ham(:,:) 146 real(r8), intent(inout) :: ovlp(:,:) 147 real(r8), intent(inout) :: dm(:,:) 148 real(r8), intent(inout) :: ebs 149 call stubError("elsi_dm_real") 150 end subroutine elsi_dm_real 151 152 153 subroutine elsi_dm_complex(eh, ham, ovlp, dm, ebs) 154 type(elsi_handle), intent(inout) :: eh 155 complex(r8), intent(inout) :: ham(:,:) 156 complex(r8), intent(inout) :: ovlp(:,:) 157 complex(r8), intent(inout) :: dm(:,:) 158 real(r8), intent(inout) :: ebs 159 call stubError("elsi_dm_complex") 160 end subroutine elsi_dm_complex 161 162 163 subroutine elsi_dm_real_sparse(eh, ham, ovlp, dm, ebs) 164 type(elsi_handle), intent(inout) :: eh 165 real(r8), intent(inout) :: ham(:) 166 real(r8), intent(inout) :: ovlp(:) 167 real(r8), intent(inout) :: dm(:) 168 real(r8), intent(inout) :: ebs 169 call stubError("elsi_dm_real_sparse") 170 end subroutine elsi_dm_real_sparse 171 172 173 subroutine elsi_dm_complex_sparse(eh, ham, ovlp, dm, ebs) 174 type(elsi_handle), intent(inout) :: eh 175 complex(r8), intent(inout) :: ham(:) 176 complex(r8), intent(inout) :: ovlp(:) 177 complex(r8), intent(inout) :: dm(:) 178 real(r8), intent(inout) :: ebs 179 call stubError("elsi_dm_complex_sparse") 180 end subroutine elsi_dm_complex_sparse 181 182 183 subroutine elsi_get_edm_real(eh, edm) 184 type(elsi_handle), intent(inout) :: eh 185 real(r8), intent(out) :: edm(:,:) 186 call stubError("elsi_get_edm_real") 187 end subroutine elsi_get_edm_real 188 189 190 subroutine elsi_get_edm_complex(eh, edm) 191 type(elsi_handle), intent(inout) :: eh 192 complex(r8), intent(out) :: edm(:,:) 193 call stubError("elsi_get_edm_complex") 194 end subroutine elsi_get_edm_complex 195 196 197 subroutine elsi_get_edm_real_sparse(eh, edm) 198 type(elsi_handle), intent(inout) :: eh 199 real(r8), intent(out) :: edm(:) 200 call stubError("elsi_get_edm_real_sparse") 201 end subroutine elsi_get_edm_real_sparse 202 203 204 subroutine elsi_get_edm_complex_sparse(eh, edm) 205 type(elsi_handle), intent(inout) :: eh 206 complex(r8), intent(out) :: edm(:) 207 call stubError("elsi_get_edm_complex_sparse") 208 end subroutine elsi_get_edm_complex_sparse 209 210 211 subroutine elsi_get_mu(eh, mu) 212 type(elsi_handle), intent(inout) :: eh 213 real(r8), intent(out) :: mu 214 call stubError("elsi_get_mu") 215 end subroutine elsi_get_mu 216 217 218 subroutine elsi_get_entropy(eh, entropy) 219 type(elsi_handle), intent(inout) :: eh 220 real(r8), intent(out) :: entropy 221 call stubError("elsi_get_entropy") 222 end subroutine elsi_get_entropy 223 224 225 subroutine elsi_ev_real(eh, ham, ovlp, eval, evec) 226 type(elsi_handle), intent(inout) :: eh 227 real(r8), intent(inout) :: ham(:,:) 228 real(r8), intent(inout) :: ovlp(:,:) 229 real(r8), intent(inout) :: eval(:) 230 real(r8), intent(inout) :: evec(:,:) 231 call stubError("elsi_ev_real") 232 end subroutine elsi_ev_real 233 234 235 subroutine elsi_ev_complex(eh, ham, ovlp, eval, evec) 236 type(elsi_handle), intent(inout) :: eh 237 complex(r8), intent(inout) :: ham(:,:) 238 complex(r8), intent(inout) :: ovlp(:,:) 239 real(r8), intent(inout) :: eval(:) 240 complex(r8), intent(inout) :: evec(:,:) 241 call stubError("elsi_ev_complex") 242 end subroutine elsi_ev_complex 243 244 245 subroutine elsi_set_blacs(eh, blacs_ctxt, block_size) 246 type(elsi_handle), intent(inout) :: eh 247 integer(i4), intent(in) :: blacs_ctxt 248 integer(i4), intent(in) :: block_size 249 call stubError("elsi_set_blacs") 250 end subroutine elsi_set_blacs 251 252 253 subroutine elsi_set_elpa_solver(eh, solver) 254 type(elsi_handle), intent(inout) :: eh 255 integer(i4), intent(in) :: solver 256 call stubError("elsi_set_set_elpa_solver") 257 end subroutine elsi_set_elpa_solver 258 259 260 subroutine elsi_set_kpoint(eh, n_kpt, i_kpt, i_wt) 261 type(elsi_handle), intent(inout) :: eh 262 integer(i4), intent(in) :: n_kpt 263 integer(i4), intent(in) :: i_kpt 264 real(r8), intent(in) :: i_wt 265 call stubError("elsi_set_kpoint") 266 end subroutine elsi_set_kpoint 267 268 269 subroutine elsi_set_spin(eh, n_spin, i_spin) 270 type(elsi_handle), intent(inout) :: eh 271 integer(i4), intent(in) :: n_spin 272 integer(i4), intent(in) :: i_spin 273 call stubError("elsi_set_spin") 274 end subroutine elsi_set_spin 275 276 277 subroutine elsi_set_mpi(eh, comm) 278 type(elsi_handle), intent(inout) :: eh 279 integer(i4), intent(in) :: comm 280 call stubError("elsi_set_mpi") 281 end subroutine elsi_set_mpi 282 283 284 subroutine elsi_set_mpi_global(eh, comm_all) 285 type(elsi_handle), intent(inout) :: eh 286 integer(i4), intent(in) :: comm_all 287 call stubError("elsi_set_mpi_global") 288 end subroutine elsi_set_mpi_global 289 290 291 subroutine elsi_set_sing_check(eh, illcond_check) 292 type(elsi_handle), intent(inout) :: eh 293 integer(i4), intent(in) :: illcond_check 294 call stubError("elsi_set_sing_check") 295 end subroutine elsi_set_sing_check 296 297 298 subroutine elsi_set_mu_broaden_scheme(eh, broaden_scheme) 299 type(elsi_handle), intent(inout) :: eh 300 integer(i4), intent(in) :: broaden_scheme 301 call stubError("elsi_set_mu_broaden_scheme") 302 end subroutine elsi_set_mu_broaden_scheme 303 304 305 subroutine elsi_set_mu_broaden_width(eh, broaden_width) 306 type(elsi_handle), intent(inout) :: eh 307 real(r8), intent(in) :: broaden_width 308 call stubError("elsi_set_mu_broaden_width") 309 end subroutine elsi_set_mu_broaden_width 310 311 312 subroutine elsi_set_mu_mp_order(eh, mp_order) 313 type(elsi_handle), intent(inout) :: eh 314 integer(i4), intent(in) :: mp_order 315 call stubError("elsi_set_mu_broaden_width") 316 end subroutine elsi_set_mu_mp_order 317 318 319 subroutine elsi_set_ntpoly_method(eh, method) 320 type(elsi_handle), intent(inout) :: eh 321 integer(i4), intent(in) :: method 322 call stubError("elsi_set_ntpoly_method") 323 end subroutine elsi_set_ntpoly_method 324 325 326 subroutine elsi_set_ntpoly_filter(eh, filter) 327 type(elsi_handle), intent(inout) :: eh 328 real(r8), intent(in) :: filter 329 call stubError("elsi_set_ntpoly_filter") 330 end subroutine elsi_set_ntpoly_filter 331 332 333 subroutine elsi_set_ntpoly_tol(eh, tol) 334 type(elsi_handle), intent(inout) :: eh 335 real(r8), intent(in) :: tol 336 call stubError("elsi_set_ntpoly_tol") 337 end subroutine elsi_set_ntpoly_tol 338 339 340 subroutine elsi_set_omm_flavor(eh, flavor) 341 type(elsi_handle), intent(inout) :: eh 342 integer(i4), intent(in) :: flavor 343 call stubError("elsi_set_omm_flavor") 344 end subroutine elsi_set_omm_flavor 345 346 347 subroutine elsi_set_omm_n_elpa(eh, n_elpa) 348 type(elsi_handle), intent(inout) :: eh 349 integer(i4), intent(in) :: n_elpa 350 call stubError("elsi_set_omm_n_elpa") 351 end subroutine elsi_set_omm_n_elpa 352 353 354 subroutine elsi_set_omm_tol(eh, tol) 355 type(elsi_handle), intent(inout) :: eh 356 real(r8), intent(in) :: tol 357 call stubError("elsi_set_omm_tol") 358 end subroutine elsi_set_omm_tol 359 360 361 subroutine elsi_set_pexsi_mu_min(eh, mu_min) 362 type(elsi_handle), intent(inout) :: eh 363 real(r8), intent(in) :: mu_min 364 call stubError("elsi_set_pexsi_mu_min") 365 end subroutine elsi_set_pexsi_mu_min 366 367 368 subroutine elsi_set_pexsi_mu_max(eh, mu_max) 369 type(elsi_handle), intent(inout) :: eh 370 real(r8), intent(in) :: mu_max 371 call stubError("elsi_set_pexsi_mu_max") 372 end subroutine elsi_set_pexsi_mu_max 373 374 375 subroutine elsi_get_pexsi_mu_min(eh, mu_min) 376 type(elsi_handle), intent(inout) :: eh 377 real(r8), intent(out) :: mu_min 378 call stubError("elsi_get_pexsi_mu_min") 379 end subroutine elsi_get_pexsi_mu_min 380 381 382 subroutine elsi_get_pexsi_mu_max(eh, mu_max) 383 type(elsi_handle), intent(inout) :: eh 384 real(r8), intent(out) :: mu_max 385 call stubError("elsi_get_pexsi_mu_max") 386 end subroutine elsi_get_pexsi_mu_max 387 388 389 subroutine elsi_set_pexsi_delta_e(eh, delta_e) 390 type(elsi_handle), intent(inout) :: eh 391 real(r8), intent(in) :: delta_e 392 call stubError("elsi_get_pexsi_delta_e") 393 end subroutine elsi_set_pexsi_delta_e 394 395 396 subroutine elsi_set_pexsi_temp(eh, temp) 397 type(elsi_handle), intent(inout) :: eh 398 real(r8), intent(in) :: temp 399 call stubError("elsi_set_pexsi_temp") 400 end subroutine elsi_set_pexsi_temp 401 402 403 subroutine elsi_set_pexsi_n_mu(eh, n_mu) 404 type(elsi_handle), intent(inout) :: eh 405 integer(i4), intent(in) :: n_mu 406 call stubError("elsi_set_pexsi_n_mu") 407 end subroutine elsi_set_pexsi_n_mu 408 409 410 subroutine elsi_set_pexsi_np_symbo(eh, np_symbo) 411 type(elsi_handle), intent(inout) :: eh 412 integer(i4), intent(in) :: np_symbo 413 call stubError("elsi_set_pexsi_np_symbo") 414 end subroutine elsi_set_pexsi_np_symbo 415 416 417 subroutine elsi_set_pexsi_n_pole(eh, n_pole) 418 type(elsi_handle), intent(inout) :: eh 419 integer(i4), intent(in) :: n_pole 420 call stubError("elsi_set_pexsi_np_pole") 421 end subroutine elsi_set_pexsi_n_pole 422 423 424 subroutine elsi_set_pexsi_np_per_pole(eh, np_per_pole) 425 type(elsi_handle), intent(inout) :: eh 426 integer(i4), intent(in) :: np_per_pole 427 call stubError("elsi_set_pexsi_np_per_pole") 428 end subroutine elsi_set_pexsi_np_per_pole 429 430 431 subroutine elsi_set_output(eh, output) 432 type(elsi_handle), intent(inout) :: eh 433 integer(i4), intent(in) :: output 434 call stubError("elsi_set_output") 435 end subroutine elsi_set_output 436 437 438 subroutine elsi_set_output_log(eh, output_log) 439 type(elsi_handle), intent(inout) :: eh 440 integer(i4), intent(in) :: output_log 441 call stubError("elsi_set_output_log") 442 end subroutine elsi_set_output_log 443 444 445 subroutine elsi_init_rw(rwh, task, parallel_mode, n_basis, n_electron) 446 type(elsi_rw_handle), intent(out) :: rwh 447 integer(i4), intent(in) :: task 448 integer(i4), intent(in) :: parallel_mode 449 integer(i4), intent(in) :: n_basis 450 real(r8), intent(in) :: n_electron 451 call stubError("elsi_init_rw") 452 end subroutine elsi_init_rw 453 454 455 subroutine elsi_finalize_rw(rwh) 456 type(elsi_rw_handle), intent(inout) :: rwh 457 call stubError("elsi_finalize_rw") 458 end subroutine elsi_finalize_rw 459 460 461 subroutine elsi_set_rw_csc(rwh, nnz_g, nnz_l_sp, n_lcol_sp) 462 type(elsi_rw_handle), intent(inout) :: rwh 463 integer(i4), intent(in) :: nnz_g 464 integer(i4), intent(in) :: nnz_l_sp 465 integer(i4), intent(in) :: n_lcol_sp 466 call stubError("elsi_set_rw_csc") 467 end subroutine elsi_set_rw_csc 468 469 470 subroutine elsi_set_rw_mpi(rwh, mpi_comm) 471 type(elsi_rw_handle), intent(inout) :: rwh 472 integer(i4), intent(in) :: mpi_comm 473 call stubError("elsi_set_rw_mpi") 474 end subroutine elsi_set_rw_mpi 475 476 477 478 subroutine elsi_set_rw_blacs(rwh, blacs_ctxt, block_size) 479 type(elsi_rw_handle), intent(inout) :: rwh 480 integer(i4), intent(in) :: blacs_ctxt 481 integer(i4), intent(in) :: block_size 482 call stubError("elsi_set_rw_blacs") 483 end subroutine elsi_set_rw_blacs 484 485 486 subroutine elsi_write_mat_real_sparse(rwh, f_name, row_ind, col_ptr, mat) 487 type(elsi_rw_handle), intent(in) :: rwh 488 character(*), intent(in) :: f_name 489 integer(i4), intent(in) :: row_ind(:) 490 integer(i4), intent(in) :: col_ptr(:) 491 real(r8), intent(in) :: mat(:) 492 call stubError("elsi_write_mat_real_sparse") 493 end subroutine elsi_write_mat_real_sparse 494 495 496 subroutine elsi_write_mat_complex_sparse(rwh, f_name, row_ind, col_ptr, mat) 497 type(elsi_rw_handle), intent(in) :: rwh 498 character(*), intent(in) :: f_name 499 integer(i4), intent(in) :: row_ind(:) 500 integer(i4), intent(in) :: col_ptr(:) 501 complex(r8), intent(in) :: mat(:) 502 call stubError("elsi_write_mat_complex_sparse") 503 end subroutine elsi_write_mat_complex_sparse 504 505 506 subroutine elsi_write_mat_real(rwh, f_name, mat) 507 type(elsi_rw_handle), intent(in) :: rwh 508 character(*), intent(in) :: f_name 509 real(r8), intent(in) :: mat(:,:) 510 call stubError("elsi_write_mat_real") 511 end subroutine elsi_write_mat_real 512 513 514 subroutine elsi_write_mat_complex(rwh, f_name, mat) 515 type(elsi_rw_handle), intent(in) :: rwh 516 character(*), intent(in) :: f_name 517 complex(r8), intent(in) :: mat(:,:) 518 call stubError("elsi_write_mat_complex") 519 end subroutine elsi_write_mat_complex 520 521#:endif 522 523end module dftbp_elsiiface 524