27 USE cp_dbcsr_api,
ONLY: dbcsr_distribution_get_num_images
68#include "./base/base_uses.f90"
76 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'distribution_methods'
104 molecule_kind_set, molecule_set, &
105 local_molecules, force_env_section, &
106 prev_molecule_kind_set, &
107 prev_local_molecules)
117 POINTER :: prev_molecule_kind_set
120 CHARACTER(len=*),
PARAMETER :: routinen =
'distribute_molecules_1d'
122 INTEGER :: atom_a, bin, handle, iatom, imolecule, imolecule_kind, imolecule_local, &
123 imolecule_prev_kind, iparticle_kind, ipe, iw, kind_a, molecule_a, n, natom, nbins, nload, &
124 nmolecule, nmolecule_kind, nparticle_kind, nsgf, output_unit
125 INTEGER(int_8) :: bin_price
126 INTEGER(int_8),
ALLOCATABLE,
DIMENSION(:) :: workload_count, workload_fill
127 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: nmolecule_local, nparticle_local, work
128 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
129 LOGICAL :: found, has_prev_subsys_info, is_local
135 CALL timeset(routinen, handle)
137 has_prev_subsys_info = .false.
138 IF (
PRESENT(prev_local_molecules) .AND. &
139 PRESENT(prev_molecule_kind_set))
THEN
140 IF (
ASSOCIATED(prev_local_molecules) .AND. &
141 ASSOCIATED(prev_molecule_kind_set))
THEN
142 has_prev_subsys_info = .true.
148 associate(group => logger%para_env, mype => logger%para_env%mepos + 1, &
149 npe => logger%para_env%num_pe)
151 ALLOCATE (workload_count(npe))
152 workload_count(:) = 0
154 ALLOCATE (workload_fill(npe))
157 nmolecule_kind =
SIZE(molecule_kind_set)
159 ALLOCATE (nmolecule_local(nmolecule_kind))
160 nmolecule_local(:) = 0
162 ALLOCATE (local_molecule(nmolecule_kind))
164 nparticle_kind =
SIZE(atomic_kind_set)
166 ALLOCATE (nparticle_local(nparticle_kind))
167 nparticle_local(:) = 0
177 DO imolecule_kind = 1, nmolecule_kind
179 molecule_kind => molecule_kind_set(imolecule_kind)
181 NULLIFY (molecule_list)
187 molecule_list=molecule_list, &
194 nload = max(natom, nsgf)
195 nmolecule =
SIZE(molecule_list)
199 DO imolecule = 1, nmolecule
200 IF (has_prev_subsys_info)
THEN
201 DO imolecule_prev_kind = 1,
SIZE(prev_molecule_kind_set)
202 IF (any(prev_local_molecules%list(imolecule_prev_kind)%array( &
203 1:prev_local_molecules%n_el(imolecule_prev_kind)) == molecule_list(imolecule)))
THEN
205 nmolecule_local(imolecule_kind) = nmolecule_local(imolecule_kind) + 1
210 IF (.NOT. found)
THEN
211 cpabort(
"No topmost heap element found.")
215 IF (bin_price /= workload_count(ipe))
THEN
216 cpabort(
"inconsistent heap")
219 workload_count(ipe) = workload_count(ipe) + nload
220 IF (ipe == mype)
THEN
221 nmolecule_local(imolecule_kind) = nmolecule_local(imolecule_kind) + 1
224 bin_price = workload_count(ipe)
230 n = nmolecule_local(imolecule_kind)
233 ALLOCATE (local_molecule(imolecule_kind)%array(n))
235 NULLIFY (local_molecule(imolecule_kind)%array)
239 DO imolecule = 1, nmolecule
241 IF (has_prev_subsys_info)
THEN
242 DO imolecule_prev_kind = 1,
SIZE(prev_molecule_kind_set)
243 IF (any(prev_local_molecules%list(imolecule_prev_kind)%array( &
244 1:prev_local_molecules%n_el(imolecule_prev_kind)) == molecule_list(imolecule)))
THEN
250 IF (.NOT. found)
THEN
251 cpabort(
"No topmost heap element found.")
255 IF (bin_price /= workload_fill(ipe))
THEN
256 cpabort(
"inconsistent heap")
259 workload_fill(ipe) = workload_fill(ipe) + nload
260 is_local = (ipe == mype)
263 imolecule_local = imolecule_local + 1
264 molecule_a = molecule_list(imolecule)
265 local_molecule(imolecule_kind)%array(imolecule_local) = molecule_a
267 atom_a = molecule_set(molecule_a)%first_atom + iatom - 1
271 nparticle_local(kind_a) = nparticle_local(kind_a) + 1
274 IF (.NOT. has_prev_subsys_info)
THEN
275 bin_price = workload_fill(ipe)
282 IF (any(workload_fill /= workload_count))
THEN
283 cpabort(
"Inconsistent heaps encountered")
292 n_el=nmolecule_local, &
293 para_env=logger%para_env)
298 n_el=nparticle_local, &
299 para_env=logger%para_env)
303 nparticle_local(:) = 0
305 DO imolecule_kind = 1, nmolecule_kind
307 IF (nmolecule_local(imolecule_kind) == 0) cycle
309 local_molecules%list(imolecule_kind)%array(:) = &
310 local_molecule(imolecule_kind)%array(:)
312 molecule_kind => molecule_kind_set(imolecule_kind)
317 DO imolecule = 1, nmolecule_local(imolecule_kind)
318 molecule_a = local_molecule(imolecule_kind)%array(imolecule)
320 atom_a = molecule_set(molecule_a)%first_atom + iatom - 1
323 nparticle_local(kind_a) = nparticle_local(kind_a) + 1
324 local_particles%list(kind_a)%array(nparticle_local(kind_a)) = atom_a
333 force_env_section,
"PRINT%DISTRIBUTION1D"),
cp_p_file))
THEN
346 work(mype) = sum(nmolecule_local)
349 IF (output_unit > 0)
THEN
350 WRITE (unit=output_unit, &
351 fmt=
"(/, T2, A, T51, A, /, (T52, I6, T73, I8))") &
352 "DISTRIBUTION OF THE MOLECULES", &
353 "Process Number of molecules", &
354 (ipe - 1, work(ipe), ipe=1, npe)
355 WRITE (unit=output_unit, fmt=
"(T55, A3, T73, I8)") &
363 IF (ipe == mype)
THEN
364 WRITE (unit=iw, fmt=
"(/, T3, A)") &
365 "Process Kind Local molecules (global indices)"
366 DO imolecule_kind = 1, nmolecule_kind
367 IF (imolecule_kind == 1)
THEN
368 WRITE (unit=iw, fmt=
"(T4, I6, 2X, I5, (T21, 10I6))") &
369 ipe - 1, imolecule_kind, &
370 (local_molecules%list(imolecule_kind)%array(imolecule), &
371 imolecule=1, nmolecule_local(imolecule_kind))
373 WRITE (unit=iw, fmt=
"(T12, I5, (T21, 10I6))") &
375 (local_molecules%list(imolecule_kind)%array(imolecule), &
376 imolecule=1, nmolecule_local(imolecule_kind))
388 work(mype) = sum(nparticle_local)
391 IF (output_unit > 0)
THEN
392 WRITE (unit=output_unit, &
393 fmt=
"(/, T2, A, T51, A, /, (T52, I6, T73, I8))") &
394 "DISTRIBUTION OF THE PARTICLES", &
395 "Process Number of particles", &
396 (ipe - 1, work(ipe), ipe=1, npe)
397 WRITE (unit=output_unit, fmt=
"(T55, A3, T73, I8)") &
405 IF (ipe == mype)
THEN
406 WRITE (unit=iw, fmt=
"(/, T3, A)") &
407 "Process Kind Local particles (global indices)"
408 DO iparticle_kind = 1, nparticle_kind
409 IF (iparticle_kind == 1)
THEN
410 WRITE (unit=iw, fmt=
"(T4, I6, 2X, I5, (T20, 10I6))") &
411 ipe - 1, iparticle_kind, &
412 (local_particles%list(iparticle_kind)%array(iatom), &
413 iatom=1, nparticle_local(iparticle_kind))
415 WRITE (unit=iw, fmt=
"(T12, I5, (T20, 10I6))") &
417 (local_particles%list(iparticle_kind)%array(iatom), &
418 iatom=1, nparticle_local(iparticle_kind))
428 "PRINT%DISTRIBUTION1D")
433 DEALLOCATE (workload_count)
435 DEALLOCATE (workload_fill)
437 DEALLOCATE (nmolecule_local)
439 DEALLOCATE (nparticle_local)
441 DO imolecule_kind = 1, nmolecule_kind
442 IF (
ASSOCIATED(local_molecule(imolecule_kind)%array))
THEN
443 DEALLOCATE (local_molecule(imolecule_kind)%array)
446 DEALLOCATE (local_molecule)
448 CALL timestop(handle)
478 qs_kind_set, molecule_kind_set, molecule_set, &
479 distribution_2d, blacs_env, force_env_section)
480 TYPE(cell_type),
POINTER :: cell
481 TYPE(atomic_kind_type),
DIMENSION(:),
POINTER :: atomic_kind_set
482 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
483 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
484 TYPE(molecule_kind_type),
DIMENSION(:),
POINTER :: molecule_kind_set
485 TYPE(molecule_type),
DIMENSION(:),
POINTER :: molecule_set
486 TYPE(distribution_2d_type),
POINTER :: distribution_2d
487 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
488 TYPE(section_vals_type),
POINTER :: force_env_section
490 CHARACTER(len=*),
PARAMETER :: routinen =
'distribute_molecules_2d'
492 INTEGER :: cluster_price, cost_model, handle, iatom, iatom_mol, iatom_one, ikind, imol, &
493 imolecule, imolecule_kind, iparticle_kind, ipcol, iprow, iw, kind_a, n, natom, natom_mol, &
494 nclusters, nmolecule, nmolecule_kind, nparticle_kind, nsgf, output_unit
495 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: cluster_list, cluster_prices, &
496 nparticle_local_col, &
497 nparticle_local_row, work
498 INTEGER,
DIMENSION(:),
POINTER :: lmax_basis, molecule_list
499 INTEGER,
DIMENSION(:, :),
POINTER :: cluster_col_distribution, &
500 cluster_row_distribution, &
501 col_distribution, row_distribution
502 LOGICAL :: basic_cluster_optimization, basic_optimization, basic_spatial_optimization, &
503 molecular_distribution, skip_optimization
504 REAL(kind=dp),
ALLOCATABLE,
DIMENSION(:, :) :: coords, pbc_scaled_coords
505 REAL(kind=dp),
DIMENSION(3) :: center
506 TYPE(cp_1d_i_p_type),
DIMENSION(:),
POINTER :: local_particle_col, local_particle_row
507 TYPE(cp_logger_type),
POINTER :: logger
508 TYPE(gto_basis_set_type),
POINTER :: orb_basis_set
509 TYPE(molecule_kind_type),
POINTER :: molecule_kind
510 TYPE(section_vals_type),
POINTER :: distribution_section
514 CALL timeset(routinen, handle)
516 logger => cp_get_default_logger()
518 distribution_section => section_vals_get_subs_vals(force_env_section,
"DFT%QS%DISTRIBUTION")
520 CALL section_vals_val_get(distribution_section,
"2D_MOLECULAR_DISTRIBUTION", l_val=molecular_distribution)
521 CALL section_vals_val_get(distribution_section,
"SKIP_OPTIMIZATION", l_val=skip_optimization)
522 CALL section_vals_val_get(distribution_section,
"BASIC_OPTIMIZATION", l_val=basic_optimization)
523 CALL section_vals_val_get(distribution_section,
"BASIC_SPATIAL_OPTIMIZATION", l_val=basic_spatial_optimization)
524 CALL section_vals_val_get(distribution_section,
"BASIC_CLUSTER_OPTIMIZATION", l_val=basic_cluster_optimization)
526 CALL section_vals_val_get(distribution_section,
"COST_MODEL", i_val=cost_model)
529 associate(group => blacs_env%para_env, myprow => blacs_env%mepos(1) + 1, mypcol => blacs_env%mepos(2) + 1, &
530 nprow => blacs_env%num_pe(1), npcol => blacs_env%num_pe(2))
532 nmolecule_kind =
SIZE(molecule_kind_set)
533 CALL get_molecule_kind_set(molecule_kind_set, nmolecule=nmolecule)
535 nparticle_kind =
SIZE(atomic_kind_set)
536 CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, natom=natom)
542 ALLOCATE (row_distribution(natom, 2))
543 ALLOCATE (col_distribution(natom, 2))
546 row_distribution = -1; col_distribution = -1
548 ALLOCATE (local_particle_col(nparticle_kind))
549 ALLOCATE (local_particle_row(nparticle_kind))
550 ALLOCATE (nparticle_local_row(nparticle_kind))
551 ALLOCATE (nparticle_local_col(nparticle_kind))
553 IF (basic_optimization .OR. basic_spatial_optimization .OR. basic_cluster_optimization)
THEN
555 IF (molecular_distribution)
THEN
556 nclusters = nmolecule
561 ALLOCATE (cluster_list(nclusters))
562 ALLOCATE (cluster_prices(nclusters))
563 ALLOCATE (cluster_row_distribution(nclusters, 2))
564 ALLOCATE (cluster_col_distribution(nclusters, 2))
565 cluster_row_distribution = -1; cluster_col_distribution = -1
568 CALL section_vals_val_get(distribution_section,
"COST_MODEL", i_val=cost_model)
569 IF (.NOT. molecular_distribution)
THEN
571 IF (iatom > nclusters)
THEN
572 cpabort(
"Bounds error")
574 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
575 cluster_list(iatom) = iatom
576 SELECT CASE (cost_model)
577 CASE (model_block_count)
578 CALL get_qs_kind(qs_kind_set(ikind), nsgf=nsgf)
580 CASE (model_block_lmax)
581 CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set)
582 CALL get_gto_basis_set(orb_basis_set, lmax=lmax_basis)
583 cluster_price = maxval(lmax_basis)
585 CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set)
586 CALL get_gto_basis_set(orb_basis_set, lmax=lmax_basis)
587 cluster_price = 8 + (maxval(lmax_basis)**2)
589 cluster_prices(iatom) = cluster_price
593 DO imolecule_kind = 1, nmolecule_kind
594 molecule_kind => molecule_kind_set(imolecule_kind)
595 CALL get_molecule_kind(molecule_kind=molecule_kind, molecule_list=molecule_list, natom=natom_mol)
596 DO imolecule = 1,
SIZE(molecule_list)
598 cluster_list(imol) = imol
600 DO iatom_mol = 1, natom_mol
601 iatom = molecule_set(molecule_list(imolecule))%first_atom + iatom_mol - 1
602 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
603 SELECT CASE (cost_model)
604 CASE (model_block_count)
605 CALL get_qs_kind(qs_kind_set(ikind), nsgf=nsgf)
606 cluster_price = cluster_price + nsgf
607 CASE (model_block_lmax)
608 CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set)
609 CALL get_gto_basis_set(orb_basis_set, lmax=lmax_basis)
610 cluster_price = cluster_price + maxval(lmax_basis)
612 CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set)
613 CALL get_gto_basis_set(orb_basis_set, lmax=lmax_basis)
614 cluster_price = cluster_price + 8 + (maxval(lmax_basis)**2)
617 cluster_prices(imol) = cluster_price
623 IF (basic_optimization)
THEN
624 CALL make_basic_distribution(cluster_list, cluster_prices, &
625 nprow, cluster_row_distribution(:, 1), npcol, cluster_col_distribution(:, 1))
627 IF (basic_cluster_optimization)
THEN
628 IF (molecular_distribution)
THEN
629 cpabort(
"clustering and molecular blocking NYI")
631 ALLOCATE (pbc_scaled_coords(3, natom), coords(3, natom))
633 CALL real_to_scaled(pbc_scaled_coords(:, iatom), pbc(particle_set(iatom)%r(:), cell), cell)
634 coords(:, iatom) = pbc(particle_set(iatom)%r(:), cell)
636 CALL make_cluster_distribution(coords, pbc_scaled_coords, cell, cluster_prices, &
637 nprow, cluster_row_distribution, npcol, cluster_col_distribution)
639 ALLOCATE (pbc_scaled_coords(3, nclusters))
640 IF (.NOT. molecular_distribution)
THEN
643 CALL real_to_scaled(pbc_scaled_coords(:, iatom), pbc(particle_set(iatom)%r(:), cell), cell)
648 DO imolecule_kind = 1, nmolecule_kind
649 molecule_kind => molecule_kind_set(imolecule_kind)
650 CALL get_molecule_kind(molecule_kind=molecule_kind, molecule_list=molecule_list, natom=natom_mol)
651 DO imolecule = 1,
SIZE(molecule_list)
653 iatom_one = molecule_set(molecule_list(imolecule))%first_atom
655 DO iatom_mol = 1, natom_mol
656 iatom = molecule_set(molecule_list(imolecule))%first_atom + iatom_mol - 1
658 pbc(particle_set(iatom)%r(:) - particle_set(iatom_one)%r(:), cell) + particle_set(iatom_one)%r(:)
660 center = center/natom_mol
661 CALL real_to_scaled(pbc_scaled_coords(:, imol), pbc(center, cell), cell)
666 CALL make_basic_spatial_distribution(pbc_scaled_coords, cluster_prices, &
667 nprow, cluster_row_distribution(:, 1), npcol, cluster_col_distribution(:, 1))
669 DEALLOCATE (pbc_scaled_coords)
674 IF (.NOT. molecular_distribution)
THEN
675 row_distribution = cluster_row_distribution
676 col_distribution = cluster_col_distribution
679 DO imolecule_kind = 1, nmolecule_kind
680 molecule_kind => molecule_kind_set(imolecule_kind)
681 CALL get_molecule_kind(molecule_kind=molecule_kind, molecule_list=molecule_list, natom=natom_mol)
682 DO imolecule = 1,
SIZE(molecule_list)
684 DO iatom_mol = 1, natom_mol
685 iatom = molecule_set(molecule_list(imolecule))%first_atom + iatom_mol - 1
686 row_distribution(iatom, :) = cluster_row_distribution(imol, :)
687 col_distribution(iatom, :) = cluster_col_distribution(imol, :)
694 DEALLOCATE (cluster_list)
695 DEALLOCATE (cluster_prices)
696 DEALLOCATE (cluster_row_distribution)
697 DEALLOCATE (cluster_col_distribution)
701 cpabort(
"Invalid optimization for DFT%QS%DISTRIBUTION")
707 nparticle_local_col = 0
708 nparticle_local_row = 0
710 CALL get_atomic_kind(atomic_kind=particle_set(iatom)%atomic_kind, kind_number=kind_a)
711 IF (row_distribution(iatom, 1) == myprow) nparticle_local_row(kind_a) = nparticle_local_row(kind_a) + 1
712 IF (col_distribution(iatom, 1) == mypcol) nparticle_local_col(kind_a) = nparticle_local_col(kind_a) + 1
716 DO iparticle_kind = 1, nparticle_kind
717 n = nparticle_local_row(iparticle_kind)
718 ALLOCATE (local_particle_row(iparticle_kind)%array(n))
720 n = nparticle_local_col(iparticle_kind)
721 ALLOCATE (local_particle_col(iparticle_kind)%array(n))
725 nparticle_local_col = 0
726 nparticle_local_row = 0
728 CALL get_atomic_kind(atomic_kind=particle_set(iatom)%atomic_kind, kind_number=kind_a)
729 IF (row_distribution(iatom, 1) == myprow)
THEN
730 nparticle_local_row(kind_a) = nparticle_local_row(kind_a) + 1
731 local_particle_row(kind_a)%array(nparticle_local_row(kind_a)) = iatom
733 IF (col_distribution(iatom, 1) == mypcol)
THEN
734 nparticle_local_col(kind_a) = nparticle_local_col(kind_a) + 1
735 local_particle_col(kind_a)%array(nparticle_local_col(kind_a)) = iatom
740 row_distribution(:, 1) = row_distribution(:, 1) - 1
741 col_distribution(:, 1) = col_distribution(:, 1) - 1
742 CALL distribution_2d_create(distribution_2d, &
743 row_distribution_ptr=row_distribution, &
744 col_distribution_ptr=col_distribution, &
745 local_rows_ptr=local_particle_row, &
746 local_cols_ptr=local_particle_col, &
749 NULLIFY (local_particle_row)
750 NULLIFY (local_particle_col)
751 NULLIFY (row_distribution)
752 NULLIFY (col_distribution)
755 IF (btest(cp_print_key_should_output(logger%iter_info, &
756 force_env_section,
"PRINT%DISTRIBUTION"), cp_p_file))
THEN
758 output_unit = cp_print_key_unit_nr(logger, force_env_section,
"PRINT%DISTRIBUTION", &
763 ALLOCATE (work(nprow))
766 IF (mypcol == 1) work(myprow) = sum(distribution_2d%n_local_rows)
770 IF (output_unit > 0)
THEN
771 WRITE (unit=output_unit, &
772 fmt=
"(/, T2, A, /, T15, A, /, (T16, I10, T41, I10, T71, I10))") &
773 "DISTRIBUTION OF THE PARTICLES (ROWS)", &
774 "Process row Number of particles Number of matrix rows", &
775 (iprow - 1, work(iprow), -1, iprow=1, nprow)
776 WRITE (unit=output_unit, fmt=
"(T23, A3, T41, I10, T71, I10)") &
778 CALL m_flush(output_unit)
785 ALLOCATE (work(npcol))
788 IF (myprow == 1) work(mypcol) = sum(distribution_2d%n_local_cols)
792 IF (output_unit > 0)
THEN
793 WRITE (unit=output_unit, &
794 fmt=
"(/, T2, A, /, T15, A, /, (T16, I10, T41, I10, T71, I10))") &
795 "DISTRIBUTION OF THE PARTICLES (COLUMNS)", &
796 "Process col Number of particles Number of matrix columns", &
797 (ipcol - 1, work(ipcol), -1, ipcol=1, npcol)
798 WRITE (unit=output_unit, fmt=
"(T23, A3, T41, I10, T71, I10)") &
800 CALL m_flush(output_unit)
805 CALL cp_print_key_finished_output(output_unit, logger, force_env_section, &
806 "PRINT%DISTRIBUTION")
810 IF (btest(cp_print_key_should_output(logger%iter_info, &
811 force_env_section,
"PRINT%DISTRIBUTION2D"), cp_p_file))
THEN
813 iw = cp_logger_get_default_unit_nr(logger, local=.true.)
814 CALL distribution_2d_write(distribution_2d, &
817 long_description=.true.)
823 DEALLOCATE (nparticle_local_row)
825 DEALLOCATE (nparticle_local_col)
827 CALL timestop(handle)
842 SUBROUTINE make_basic_distribution(cluster_list, cluster_prices, &
843 nprows, row_distribution, npcols, col_distribution)
844 INTEGER,
DIMENSION(:),
INTENT(INOUT) :: cluster_list, cluster_prices
845 INTEGER,
INTENT(IN) :: nprows
846 INTEGER,
DIMENSION(:),
INTENT(OUT) :: row_distribution
847 INTEGER,
INTENT(IN) :: npcols
848 INTEGER,
DIMENSION(:),
INTENT(OUT) :: col_distribution
850 CHARACTER(len=*),
PARAMETER :: routinen =
'make_basic_distribution'
852 INTEGER :: bin, cluster, cluster_index, &
853 cluster_price, nbins, nclusters, pcol, &
854 pgrid_gcd, prow, timing_handle
855 INTEGER(int_8) :: bin_price
857 TYPE(cp_heap_type) :: bin_heap
861 CALL timeset(routinen, timing_handle)
862 nbins =
lcm(nprows, npcols)
863 pgrid_gcd =
gcd(nprows, npcols)
864 CALL sort(cluster_prices,
SIZE(cluster_list), cluster_list)
865 CALL cp_heap_new(bin_heap, nbins)
866 CALL cp_heap_fill(bin_heap, [(0_int_8, bin=1, nbins)])
868 nclusters =
SIZE(cluster_list)
871 DO cluster_index = nclusters, 1, -1
872 cluster = cluster_list(cluster_index)
873 CALL cp_heap_get_first(bin_heap, bin, bin_price, found)
874 IF (.NOT. found)
THEN
875 cpabort(
"No topmost heap element found.")
878 prow = int((bin - 1)*pgrid_gcd/npcols)
879 IF (prow >= nprows)
THEN
880 cpabort(
"Invalid process row.")
882 pcol = int((bin - 1)*pgrid_gcd/nprows)
883 IF (pcol >= npcols)
THEN
884 cpabort(
"Invalid process column.")
886 row_distribution(cluster) = prow + 1
887 col_distribution(cluster) = pcol + 1
889 cluster_price = cluster_prices(cluster_index)
890 bin_price = bin_price + cluster_price
891 CALL cp_heap_reset_first(bin_heap, bin_price)
893 CALL cp_heap_release(bin_heap)
894 CALL timestop(timing_handle)
895 END SUBROUTINE make_basic_distribution
909 SUBROUTINE make_basic_spatial_distribution(pbc_scaled_coords, costs, &
910 nprows, row_distribution, npcols, col_distribution)
911 REAL(kind=dp),
DIMENSION(:, :),
INTENT(IN) :: pbc_scaled_coords
912 INTEGER,
DIMENSION(:),
INTENT(IN) :: costs
913 INTEGER,
INTENT(IN) :: nprows
914 INTEGER,
DIMENSION(:),
INTENT(OUT) :: row_distribution
915 INTEGER,
INTENT(IN) :: npcols
916 INTEGER,
DIMENSION(:),
INTENT(OUT) :: col_distribution
918 CHARACTER(len=*),
PARAMETER :: routinen =
'make_basic_spatial_distribution'
920 INTEGER :: handle, iatom, natoms, nbins, pgrid_gcd
921 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: bin_costs, distribution
923 CALL timeset(routinen, handle)
926 nbins =
lcm(nprows, npcols)
927 pgrid_gcd =
gcd(nprows, npcols)
928 ALLOCATE (bin_costs(nbins), distribution(natoms))
931 CALL spatial_recurse(pbc_scaled_coords, costs, [(iatom, iatom=1, natoms)], bin_costs, distribution, 0)
937 row_distribution(iatom) = (distribution(iatom) - 1)*pgrid_gcd/npcols + 1
938 col_distribution(iatom) = (distribution(iatom) - 1)*pgrid_gcd/nprows + 1
941 DEALLOCATE (bin_costs, distribution)
943 CALL timestop(handle)
945 END SUBROUTINE make_basic_spatial_distribution
956 RECURSIVE SUBROUTINE spatial_recurse(pbc_scaled_coords, costs, indices, bin_costs, distribution, level)
957 REAL(kind=dp),
DIMENSION(:, :),
INTENT(IN) :: pbc_scaled_coords
958 INTEGER,
DIMENSION(:),
INTENT(IN) :: costs, indices
959 INTEGER,
DIMENSION(:),
INTENT(INOUT) :: bin_costs, distribution
960 INTEGER,
INTENT(IN) :: level
962 INTEGER :: iatom, ibin, natoms, nbins, nhalf
963 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_costs_sorted, atom_permutation, &
964 bin_costs_sorted, permutation
965 REAL(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: coord
968 nbins =
SIZE(bin_costs)
969 nhalf = (natoms + 1)/2
971 IF (natoms <= nbins)
THEN
973 ALLOCATE (bin_costs_sorted(nbins), permutation(nbins))
974 bin_costs_sorted(:) = bin_costs
975 CALL sort(bin_costs_sorted, nbins, permutation)
976 ALLOCATE (atom_costs_sorted(natoms), atom_permutation(natoms))
977 atom_costs_sorted(:) = costs
978 CALL sort(atom_costs_sorted, natoms, atom_permutation)
981 DO iatom = natoms, 1, -1
986 bin_costs(permutation(ibin)) = bin_costs(permutation(ibin)) + atom_costs_sorted(iatom)
987 distribution(indices(atom_permutation(iatom))) = permutation(ibin)
989 DEALLOCATE (bin_costs_sorted, permutation, atom_costs_sorted, atom_permutation)
993 ALLOCATE (coord(natoms), permutation(natoms))
994 coord(:) = pbc_scaled_coords(mod(level, 3) + 1, :)
995 CALL sort(coord, natoms, permutation)
996 CALL spatial_recurse(pbc_scaled_coords(:, permutation(1:nhalf)), costs(permutation(1:nhalf)), &
997 indices(permutation(1:nhalf)), bin_costs, distribution, level + 1)
998 CALL spatial_recurse(pbc_scaled_coords(:, permutation(nhalf + 1:)), costs(permutation(nhalf + 1:)), &
999 indices(permutation(nhalf + 1:)), bin_costs, distribution, level + 1)
1000 DEALLOCATE (coord, permutation)
1003 END SUBROUTINE spatial_recurse
1018 SUBROUTINE make_cluster_distribution(coords, scaled_coords, cell, costs, &
1019 nprows, row_distribution, npcols, col_distribution)
1020 REAL(kind=dp),
DIMENSION(:, :),
INTENT(IN) :: coords, scaled_coords
1021 TYPE(cell_type),
POINTER :: cell
1022 INTEGER,
DIMENSION(:),
INTENT(IN) :: costs
1023 INTEGER,
INTENT(IN) :: nprows
1024 INTEGER,
DIMENSION(:, :),
INTENT(OUT) :: row_distribution
1025 INTEGER,
INTENT(IN) :: npcols
1026 INTEGER,
DIMENSION(:, :),
INTENT(OUT) :: col_distribution
1028 CHARACTER(len=*),
PARAMETER :: routinen =
'make_cluster_distribution'
1030 INTEGER :: handle, i, icluster, level, natom, &
1032 INTEGER(KIND=int_8) :: ncluster
1033 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_to_cluster, cluster_cost, &
1034 cluster_count, cluster_to_col, &
1035 cluster_to_row, piv_cost, proc_cost, &
1037 REAL(kind=dp) :: fold(3)
1038 REAL(kind=dp),
ALLOCATABLE,
DIMENSION(:, :) :: cluster_center, cluster_high, cluster_low
1040 CALL timeset(routinen, handle)
1042 output_unit = cp_logger_get_default_io_unit()
1045 ncluster = dbcsr_distribution_get_num_images(sum(costs), natom, nprows, npcols)
1046 ALLOCATE (atom_to_cluster(natom))
1047 ALLOCATE (cluster_cost(ncluster))
1048 ALLOCATE (cluster_to_row(ncluster))
1049 ALLOCATE (cluster_to_col(ncluster))
1050 ALLOCATE (sorted_cost(ncluster))
1051 ALLOCATE (piv_cost(ncluster))
1055 CALL cluster_recurse(coords, scaled_coords, cell, costs, atom_to_cluster, ncluster, icluster, cluster_cost)
1057 sorted_cost(:) = cluster_cost(:)
1058 CALL sort(sorted_cost, int(ncluster), piv_cost)
1060 ALLOCATE (proc_cost(nprows))
1061 proc_cost = 0; level = 1
1062 CALL assign_clusters(cluster_cost, piv_cost, proc_cost, cluster_to_row, nprows)
1064 DEALLOCATE (proc_cost);
ALLOCATE (proc_cost(npcols))
1065 proc_cost = 0; level = 1
1066 CALL assign_clusters(cluster_cost, piv_cost, proc_cost, cluster_to_col, npcols)
1069 row_distribution(i, 1) = cluster_to_row(atom_to_cluster(i))
1070 row_distribution(i, 2) = atom_to_cluster(i)
1071 col_distribution(i, 1) = cluster_to_col(atom_to_cluster(i))
1072 col_distribution(i, 2) = atom_to_cluster(i)
1076 ALLOCATE (cluster_center(3, ncluster))
1077 ALLOCATE (cluster_low(3, ncluster))
1078 ALLOCATE (cluster_high(3, ncluster))
1079 ALLOCATE (cluster_count(ncluster))
1082 cluster_count(atom_to_cluster(i)) = cluster_count(atom_to_cluster(i)) + 1
1083 cluster_center(:, atom_to_cluster(i)) = coords(:, i)
1085 cluster_low = huge(0.0_dp)/2
1086 cluster_high = -huge(0.0_dp)/2
1088 fold = pbc(coords(:, i) - cluster_center(:, atom_to_cluster(i)), cell) + cluster_center(:, atom_to_cluster(i))
1089 cluster_low(:, atom_to_cluster(i)) = min(cluster_low(:, atom_to_cluster(i)), fold(:))
1090 cluster_high(:, atom_to_cluster(i)) = max(cluster_high(:, atom_to_cluster(i)), fold(:))
1092 IF (output_unit > 0)
THEN
1093 WRITE (output_unit, *)
1094 WRITE (output_unit,
'(T2,A)')
"Cluster distribution information"
1095 WRITE (output_unit,
'(T2,A,T48,I8)')
"Number of atoms", natom
1096 WRITE (output_unit,
'(T2,A,T48,I8)')
"Number of clusters", ncluster
1097 WRITE (output_unit,
'(T2,A,T48,I8)')
"Largest cluster in atoms", maxval(cluster_count)
1098 WRITE (output_unit,
'(T2,A,T48,I8)')
"Smallest cluster in atoms", minval(cluster_count)
1099 WRITE (output_unit,
'(T2,A,T48,F8.3,I8)')
"Largest cartesian extend [a.u.]/cluster x=", &
1100 maxval(cluster_high(1, :) - cluster_low(1, :), mask=(cluster_count > 0)), &
1101 maxloc(cluster_high(1, :) - cluster_low(1, :), mask=(cluster_count > 0))
1102 WRITE (output_unit,
'(T2,A,T48,F8.3,I8)')
"Largest cartesian extend [a.u.]/cluster y=", &
1103 maxval(cluster_high(2, :) - cluster_low(2, :), mask=(cluster_count > 0)), &
1104 maxloc(cluster_high(2, :) - cluster_low(2, :), mask=(cluster_count > 0))
1105 WRITE (output_unit,
'(T2,A,T48,F8.3,I8)')
"Largest cartesian extend [a.u.]/cluster z=", &
1106 maxval(cluster_high(3, :) - cluster_low(3, :), mask=(cluster_count > 0)), &
1107 maxloc(cluster_high(3, :) - cluster_low(3, :), mask=(cluster_count > 0))
1110 DEALLOCATE (atom_to_cluster, cluster_cost, cluster_to_row, cluster_to_col, sorted_cost, piv_cost, proc_cost)
1111 CALL timestop(handle)
1113 END SUBROUTINE make_cluster_distribution
1123 SUBROUTINE assign_clusters(cluster_cost, piv_cost, proc_cost, cluster_assign, nproc)
1124 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: cluster_cost, piv_cost, proc_cost, &
1128 CHARACTER(len=*),
PARAMETER :: routinen =
'assign_clusters'
1130 INTEGER :: handle, i, ilevel, offset, &
1131 piv_pcost(nproc), sort_proc_cost(nproc)
1133 CALL timeset(routinen, handle)
1135 DO ilevel = 1,
SIZE(cluster_cost)/nproc
1136 sort_proc_cost(:) = proc_cost(:)
1137 CALL sort(sort_proc_cost, nproc, piv_pcost)
1139 offset = (
SIZE(cluster_cost)/nproc - ilevel + 1)*nproc + 1
1141 cluster_assign(piv_cost(offset - i)) = piv_pcost(i)
1142 proc_cost(piv_pcost(i)) = proc_cost(piv_pcost(i)) + cluster_cost(piv_cost(offset - i))
1146 CALL timestop(handle)
1148 END SUBROUTINE assign_clusters
1165 RECURSIVE SUBROUTINE cluster_recurse(coord, scaled_coord, cell, costs, cluster_inds, ncluster, icluster, fin_cluster_cost)
1166 REAL(kind=dp),
DIMENSION(:, :),
INTENT(IN) :: coord, scaled_coord
1167 TYPE(cell_type),
POINTER :: cell
1168 INTEGER,
DIMENSION(:),
INTENT(IN) :: costs
1169 INTEGER,
DIMENSION(:),
INTENT(INOUT) :: cluster_inds
1170 INTEGER(KIND=int_8),
INTENT(INOUT) :: ncluster
1171 INTEGER,
INTENT(INOUT) :: icluster
1172 INTEGER,
DIMENSION(:),
INTENT(INOUT) :: fin_cluster_cost
1174 INTEGER :: i, ibeg, iend, maxv(1), min_seed, &
1175 natoms, nleft, nsplits, seed, tot_cost
1176 INTEGER(KIND=int_8),
ALLOCATABLE,
DIMENSION(:) :: ncluster_new
1177 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: cluster_cost, inds_tmp, nat_cluster, piv
1179 REAL(kind=dp) :: balance, balance_new, conv
1181 natoms =
SIZE(coord, 2)
1184 IF (natoms <= 1)
THEN
1187 nsplits = min(int(min(int(max(6, int(60.00/log(real(natoms, kind=dp)))), kind=int_8), ncluster)), natoms)
1189 IF (nsplits == 1)
THEN
1190 icluster = icluster + 1
1191 cluster_inds = icluster
1192 fin_cluster_cost(icluster) = sum(costs)
1194 ALLOCATE (cluster_cost(nsplits), ncluster_new(nsplits), inds_tmp(natoms), piv(natoms), nat_cluster(nsplits))
1196 cluster_cost = 0; seed = 300; found = .true.; min_seed = seed
1197 CALL kmeans(nsplits, coord, scaled_coord, cell, cluster_inds, nat_cluster, seed, conv)
1198 balance = maxval(real(nat_cluster, kind=dp))/minval(real(nat_cluster, kind=dp))
1202 IF (natoms < 1000 .AND. balance > 1.1)
THEN
1205 IF (balance > 1.1)
THEN
1206 CALL kmeans(nsplits, coord, scaled_coord, cell, cluster_inds, nat_cluster, seed + i*40, conv)
1207 balance_new = maxval(real(nat_cluster, kind=dp))/minval(real(nat_cluster, kind=dp))
1208 IF (balance_new < balance)
THEN
1209 balance = balance_new
1210 min_seed = seed + i*40
1219 IF (.NOT. found)
CALL kmeans(nsplits, coord, scaled_coord, cell, cluster_inds, nat_cluster, min_seed, conv)
1223 cluster_cost(cluster_inds(i)) = cluster_cost(cluster_inds(i)) + costs(i)
1225 tot_cost = sum(cluster_cost)
1227 ncluster_new(:) = ncluster*cluster_cost(:)/tot_cost
1228 nleft = int(ncluster - sum(ncluster_new))
1231 IF (ncluster_new(i) == 0)
THEN
1238 IF (nleft /= 0)
THEN
1239 DO i = 1, abs(nleft)
1241 maxv = minloc(cluster_cost/ncluster_new)
1242 IF (ncluster_new(maxv(1)) /= 1)
THEN
1243 ncluster_new(maxv) = ncluster_new(maxv) - 1
1245 maxv = maxloc(ncluster_new)
1246 ncluster_new(maxv) = ncluster_new(maxv) - 1
1249 maxv = maxloc(cluster_cost/ncluster_new)
1250 ncluster_new(maxv) = ncluster_new(maxv) + 1
1256 inds_tmp(:) = cluster_inds(:)
1257 CALL sort(inds_tmp, natoms, piv)
1261 IF (nat_cluster(i) == 0) cycle
1262 iend = iend + nat_cluster(i)
1263 CALL cluster_recurse(coord(:, piv(ibeg:iend)), scaled_coord(:, piv(ibeg:iend)), cell, costs(piv(ibeg:iend)), &
1264 inds_tmp(ibeg:iend), ncluster_new(i), icluster, fin_cluster_cost)
1265 ibeg = ibeg + nat_cluster(i)
1268 cluster_inds(piv(:)) = inds_tmp
1269 DEALLOCATE (cluster_cost, ncluster_new, inds_tmp, piv, nat_cluster)
1273 END SUBROUTINE cluster_recurse
1289 SUBROUTINE kmeans(ncent, coord, scaled_coord, cell, cluster, nat_cl, seed, tot_var)
1291 REAL(kind=dp),
DIMENSION(:, :) :: coord, scaled_coord
1292 TYPE(cell_type),
POINTER :: cell
1293 INTEGER,
DIMENSION(:) :: cluster, nat_cl
1295 REAL(kind=dp) :: tot_var
1297 CHARACTER(len=*),
PARAMETER :: routinen =
'kmeans'
1299 INTEGER :: handle, i, ind, itn, j, nat, oldc
1301 REAL(kind=dp) :: average(3, ncent, 2), cent_coord(3, ncent), devi, deviat(ncent), dist, &
1302 dvec(3), old_var, rn, scaled_cent(3, ncent), var_cl(ncent)
1303 REAL(kind=dp),
ALLOCATABLE,
DIMENSION(:, :) :: dmat
1304 REAL(kind=dp),
DIMENSION(3, 2) :: initial_seed
1305 TYPE(rng_stream_type) :: rng_stream
1307 CALL timeset(routinen, handle)
1309 initial_seed = real(seed, dp); nat =
SIZE(coord, 2)
1310 ALLOCATE (dmat(ncent, nat))
1312 rng_stream = rng_stream_type(name=
"kmeans uniform distribution [0,1]", &
1313 distribution_type=uniform, seed=initial_seed)
1316 rn = rng_stream%next()
1317 ind = ceiling(rn*nat)
1318 cent_coord(:, 1) = coord(:, ind)
1321 rn = rng_stream%next()
1322 ind = ceiling(rn*nat)
1323 cent_coord(:, i) = coord(:, ind)
1326 dvec = pbc(cent_coord(:, j), cent_coord(:, i), cell)
1328 IF (dist < devi) devi = dist
1330 rn = rng_stream%next()
1331 IF (rn < devi**2/169.0)
EXIT
1337 cluster = 0; old_var = huge(1.0_dp)
1339 changed = .false.; var_cl = 0.0_dp; tot_var = 0.0_dp; nat_cl = 0; deviat = 0.0_dp
1343 dvec = pbc(cent_coord(:, j), coord(:, i), cell)
1344 dmat(j, i) = dot_product(dvec, dvec)
1348 devi = huge(1.0_dp); oldc = cluster(i)
1350 dist = dmat(j, i) + max(nat_cl(j)**2/nat*ncent, nat/ncent)
1351 IF (dist < devi)
THEN
1352 devi = dist; cluster(i) = j
1355 deviat(cluster(i)) = deviat(cluster(i)) + sqrt(devi)
1356 nat_cl(cluster(i)) = nat_cl(cluster(i)) + 1
1357 tot_var = tot_var + devi
1358 IF (oldc /= cluster(i)) changed = .true.
1362 IF (tot_var >= old_var)
EXIT
1367 DO i = 1,
SIZE(coord, 2)
1368 average(:, cluster(i), 1) = average(:, cluster(i), 1) + cos(scaled_coord(:, i)*2.0_dp*pi)
1369 average(:, cluster(i), 2) = average(:, cluster(i), 2) + sin(scaled_coord(:, i)*2.0_dp*pi)
1373 IF (nat_cl(i) == 0)
THEN
1374 rn = rng_stream%next()
1375 scaled_cent(:, i) = scaled_coord(:, ceiling(rn*nat))
1377 average(:, i, 1) = average(:, i, 1)/real(nat_cl(i), dp)
1378 average(:, i, 2) = average(:, i, 2)/real(nat_cl(i), dp)
1379 scaled_cent(:, i) = (atan2(-average(:, i, 2), -average(:, i, 1)) + pi)/(2.0_dp*pi)
1380 CALL scaled_to_real(cent_coord(:, i), scaled_cent(:, i), cell)
1388 CALL timestop(handle)
1390 END SUBROUTINE kmeans
static int gcd(const int a, const int b)
Private routine for computing greatest common divisor of two numbers.
static int lcm(const int a, const int b)
Private routine for computing least common multiple of two numbers.
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind_set(atomic_kind_set, atom_of_kind, kind_of, natom_of_kind, maxatom, natom, nshell, fist_potential_present, shell_present, shell_adiabatic, shell_check_distance, damping_present)
Get attributes of an atomic kind set.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
subroutine, public get_gto_basis_set(gto_basis_set, name, aliases, norm_type, kind_radius, ncgf, nset, nsgf, cgf_symbol, sgf_symbol, norm_cgf, set_radius, lmax, lmin, lx, ly, lz, m, ncgf_set, npgf, nsgf_set, nshell, cphi, pgf_radius, sphi, scon, zet, first_cgf, first_sgf, l, last_cgf, last_sgf, n, gcc, maxco, maxl, maxpgf, maxsgf_set, maxshell, maxso, nco_sum, npgf_sum, nshell_sum, maxder, short_kind_radius, npgf_seg_sum, ccon)
...
Handles all functions related to the CELL.
subroutine, public scaled_to_real(r, s, cell)
Transform scaled cell coordinates real coordinates. r=h*s.
subroutine, public real_to_scaled(s, r, cell)
Transform real to scaled cell coordinates. s=h_inv*r.
various utilities that regard array of different kinds: output, allocation,... maybe it is not a good...
methods related to the blacs parallel environment
various routines to log and control the output. The idea is that decisions about where to log should ...
recursive integer function, public cp_logger_get_default_unit_nr(logger, local, skip_not_ionode)
asks the default unit number of the given logger. try to use cp_logger_get_unit_nr
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
subroutine, public cp_heap_fill(heap, values)
Fill heap with given values.
subroutine, public cp_heap_new(heap, n)
...
subroutine, public cp_heap_get_first(heap, key, value, found)
Returns the first heap element without removing it.
subroutine, public cp_heap_release(heap)
...
subroutine, public cp_heap_reset_first(heap, value)
Changes the value of the minimum heap element and rebalances the heap.
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
integer, parameter, public cp_p_file
integer function, public cp_print_key_should_output(iteration_info, basis_section, print_key_path, used_print_key, first_time)
returns what should be done with the given property if btest(res,cp_p_store) then the property should...
stores a lists of integer that are local to a processor. The idea is that these integers represent ob...
subroutine, public distribution_1d_create(distribution_1d, para_env, listbased_distribution, n_el, n_lists)
creates a local list
stores a mapping of 2D info (e.g. matrix) on a 2D processor distribution (i.e. blacs grid) where cpus...
subroutine, public distribution_2d_create(distribution_2d, blacs_env, local_rows_ptr, n_local_rows, local_cols_ptr, row_distribution_ptr, col_distribution_ptr, n_local_cols, n_row_distribution, n_col_distribution)
initializes the distribution_2d
subroutine, public distribution_2d_write(distribution_2d, unit_nr, local, long_description)
writes out the given distribution
Distribution methods for atoms, particles, or molecules.
subroutine, public distribute_molecules_1d(atomic_kind_set, particle_set, local_particles, molecule_kind_set, molecule_set, local_molecules, force_env_section, prev_molecule_kind_set, prev_local_molecules)
Distribute molecules and particles.
subroutine, public distribute_molecules_2d(cell, atomic_kind_set, particle_set, qs_kind_set, molecule_kind_set, molecule_set, distribution_2d, blacs_env, force_env_section)
Distributes the particle pairs creating a 2d distribution optimally suited for quickstep.
Defines the basic variable types.
integer, parameter, public int_8
integer, parameter, public dp
Machine interface based on Fortran 2003 and POSIX.
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
Collection of simple mathematical functions and subroutines.
elemental integer function, public lcm(a, b)
computes the least common multiplier of two numbers
elemental integer function, public gcd(a, b)
computes the greatest common divisor of two number
Define the molecule kind structure types and the corresponding functionality.
subroutine, public get_molecule_kind(molecule_kind, atom_list, bond_list, bend_list, ub_list, impr_list, opbend_list, colv_list, fixd_list, g3x3_list, g4x6_list, vsite_list, torsion_list, shell_list, name, mass, charge, kind_number, natom, nbend, nbond, nub, nimpr, nopbend, nconstraint, nconstraint_fixd, nfixd, ncolv, ng3x3, ng4x6, nvsite, nfixd_restraint, ng3x3_restraint, ng4x6_restraint, nvsite_restraint, nrestraints, nmolecule, nsgf, nshell, ntorsion, molecule_list, nelectron, nelectron_alpha, nelectron_beta, bond_kind_set, bend_kind_set, ub_kind_set, impr_kind_set, opbend_kind_set, torsion_kind_set, molname_generated)
Get informations about a molecule kind.
subroutine, public get_molecule_kind_set(molecule_kind_set, maxatom, natom, nbond, nbend, nub, ntorsion, nimpr, nopbend, nconstraint, nconstraint_fixd, nmolecule, nrestraints)
Get informations about a molecule kind set.
Define the data structure for the molecule information.
Parallel (pseudo)random number generator (RNG) for multiple streams and substreams of random numbers.
integer, parameter, public uniform
Define the data structure for the particle information.
Define the quickstep kind type and their sub types.
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, cneo_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zatom, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, u_of_dft_plus_u, j_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, j0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, init_u_ramping_each_scf, reltmat, ghost, monovalent, floating, name, element_symbol, pao_basis_size, pao_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
All kind of helpful little routines.
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
represent a pointer to a 1d array
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
type of a logger, at the moment it contains just a print level starting at which level it should be l...
structure to store local (to a processor) ordered lists of integers.
distributes pairs on a 2d grid of processors
Provides all information about a quickstep kind.