41#include "./base/base_uses.f90"
46 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'optimize_basis_utils'
67 LOGICAL,
INTENT(IN),
OPTIONAL :: quiet_output, embedded_training
69 CHARACTER(LEN=default_path_length) :: main_dir
70 INTEGER :: ikind, iset, iweight, nrep
71 LOGICAL :: frontier_orbitals_explicit, &
74 optbas_section, powell_section, &
83 IF (
PRESENT(quiet_output)) opt_bas%quiet_output = quiet_output
84 use_embedded_training = .false.
85 IF (
PRESENT(embedded_training)) use_embedded_training = embedded_training
87 CALL section_vals_val_get(optbas_section,
"BASIS_TEMPLATE_FILE", c_val=opt_bas%template_basis_file)
92 CALL section_vals_val_get(optbas_section,
"USE_CONDITION_NUMBER", l_val=opt_bas%use_condition_number)
94 CALL generate_initial_basis(kind_section, opt_bas, para_env)
96 CALL section_vals_get(frontier_orbitals_section, explicit=frontier_orbitals_explicit)
97 IF (use_embedded_training)
THEN
99 ELSE IF (frontier_orbitals_explicit)
THEN
102 r_val=opt_bas%occupied_weight)
104 r_val=opt_bas%virtual_weight)
106 r_val=opt_bas%empty_overlap_weight)
108 r_val=opt_bas%gap_weight)
110 r_val=opt_bas%coefficient_weight)
112 r_val=opt_bas%gap_energy_scale)
114 r_val=opt_bas%virtual_energy_cutoff)
116 r_val=opt_bas%virtual_energy_smoothing)
120 opt_bas%work_basis_file = trim(adjustl(main_dir))//
"/"//trim(adjustl(opt_bas%work_basis_file))
122 IF (frontier_orbitals_explicit)
THEN
123 IF (opt_bas%gap_energy_scale <= 0.0_dp) cpabort(
"GAP_ENERGY_SCALE must be positive")
124 IF (opt_bas%virtual_energy_smoothing <= 0.0_dp)
THEN
125 cpabort(
"VIRTUAL_ENERGY_SMOOTHING must be positive")
127 IF (min(opt_bas%occupied_weight, opt_bas%virtual_weight, &
128 opt_bas%empty_overlap_weight, opt_bas%gap_weight, &
129 opt_bas%coefficient_weight) < 0.0_dp)
THEN
130 cpabort(
"FRONTIER_ORBITALS weights must be non-negative")
134 DO ikind = 1, opt_bas%nkind
135 DO iset = 1, opt_bas%kind_basis(ikind)%flex_basis(0)%nsets
136 IF (any(opt_bas%kind_basis(ikind)%flex_basis(0)%subset(iset)%opt_exps))
THEN
137 cpabort(
"FRONTIER_ORBITALS requires fixed Gaussian exponents")
144 IF (use_embedded_training)
THEN
145 IF (opt_bas%ntraining_sets /= 0)
THEN
146 CALL cp_abort(__location__, &
147 "TRAINING_FILES is not allowed together with FRONTIER_ORBITAL_SCREENING "// &
148 "because it is overwritten automatically")
150 opt_bas%ntraining_sets = 1
151 ELSE IF (opt_bas%ntraining_sets == 0)
THEN
152 cpabort(
"No training set was specified in the Input")
155 ALLOCATE (opt_bas%training_input(opt_bas%ntraining_sets))
156 ALLOCATE (opt_bas%training_dir(opt_bas%ntraining_sets))
157 IF (use_embedded_training)
THEN
158 opt_bas%training_input(1) =
""
159 opt_bas%training_dir(1) =
"."
161 DO iset = 1, opt_bas%ntraining_sets
164 CALL section_vals_val_get(train_section,
"INPUT_FILE_NAME", c_val=opt_bas%training_input(iset), &
169 CALL init_powell_var(opt_bas%powell_param, powell_section)
170 opt_bas%powell_param%nvar =
SIZE(opt_bas%x_opt)
172 CALL generate_derived_basis_sets( &
175 CALL generate_basis_combinations(opt_bas, optbas_section)
178 ALLOCATE (opt_bas%fval_weight(0:opt_bas%ncombinations))
179 opt_bas%fval_weight = 1.0_dp
181 CALL section_vals_val_get(optbas_section,
"RESIDUUM_WEIGHT", r_val=opt_bas%fval_weight(iweight - 1), &
186 ALLOCATE (opt_bas%condition_weight(0:opt_bas%ncombinations))
187 opt_bas%condition_weight = 1.0_dp
189 CALL section_vals_val_get(optbas_section,
"CONDITION_WEIGHT", r_val=opt_bas%condition_weight(iweight - 1), &
193 CALL generate_computation_groups(opt_bas, optbas_section, para_env)
195 IF (.NOT. opt_bas%quiet_output)
CALL print_opt_info(opt_bas)
203 SUBROUTINE print_opt_info(opt_bas)
206 INTEGER :: icomb, ikind, unit_nr
211 IF (logger%para_env%is_source())
THEN
215 IF (unit_nr > 0)
THEN
216 WRITE (unit_nr,
'(1X,A,A)')
"BASOPT| Total number of calculations ", &
217 trim(
cp_to_string(opt_bas%ncombinations*opt_bas%ntraining_sets))
218 WRITE (unit_nr,
'(A)')
""
219 DO icomb = 1, opt_bas%ncombinations
220 WRITE (unit_nr,
'(1X,A,A)')
"BASOPT| Content of basis combination ", trim(
cp_to_string(icomb))
221 DO ikind = 1, opt_bas%nkind
222 WRITE (unit_nr,
'(1X,A,A4,4X,A,3X,A)')
"BASOPT| Element: ", trim(opt_bas%kind_basis(ikind)%element), &
223 "Basis set: ", trim(opt_bas%kind_basis(ikind)%flex_basis(opt_bas%combination(icomb, ikind))%basis_name)
225 WRITE (unit_nr,
'(A)')
""
228 END SUBROUTINE print_opt_info
237 SUBROUTINE generate_basis_combinations(opt_bas, optbas_section)
241 INTEGER :: i, ikind, j, n_rep
242 INTEGER,
DIMENSION(:),
POINTER :: i_vals, tmp_i, tmp_i2
243 LOGICAL :: explicit, raise
247 CALL section_vals_val_get(optbas_section,
"BASIS_COMBINATIONS", explicit=explicit, n_rep_val=n_rep)
248 IF (.NOT. explicit)
THEN
249 opt_bas%ncombinations = 1
250 ALLOCATE (tmp_i(opt_bas%nkind))
251 ALLOCATE (tmp_i2(opt_bas%nkind))
252 DO ikind = 1, opt_bas%nkind
253 opt_bas%ncombinations = opt_bas%ncombinations*
SIZE(opt_bas%kind_basis(ikind)%flex_basis)
254 tmp_i(ikind) = opt_bas%kind_basis(ikind)%nbasis_deriv
256 ALLOCATE (opt_bas%combination(opt_bas%ncombinations, opt_bas%nkind))
258 DO i = 1, opt_bas%ncombinations
259 DO j = 1, opt_bas%nkind
260 opt_bas%combination(i, j) = tmp_i2(j)
262 tmp_i2(opt_bas%nkind) = tmp_i2(opt_bas%nkind) + 1
264 DO j = opt_bas%nkind, 1, -1
265 IF (raise) tmp_i2(j) = tmp_i2(j) + 1
266 IF (tmp_i2(j) > tmp_i(j))
THEN
275 opt_bas%ncombinations = n_rep
276 ALLOCATE (opt_bas%combination(opt_bas%ncombinations, opt_bas%nkind))
279 opt_bas%combination(i, :) = i_vals(:)
283 END SUBROUTINE generate_basis_combinations
299 INTEGER :: set_id, bas_id
301 INTEGER :: ncom, nset
303 ncom = opt_bas%ncombinations
304 nset = opt_bas%ntraining_sets
306 set_id = (calc_id)/ncom + 1
307 bas_id = mod(calc_id, ncom) + 1
320 SUBROUTINE generate_computation_groups(opt_bas, optbas_section, para_env)
325 INTEGER :: iadd1, iadd2, icount, igroup, isize, j, &
327 INTEGER,
DIMENSION(:),
POINTER :: i_vals
330 nproc = para_env%num_pe
331 ncalc = opt_bas%ncombinations*opt_bas%ntraining_sets
335 IF (.NOT. explicit)
THEN
336 IF (nproc >= ncalc)
THEN
338 iadd2 = mod(nproc, ncalc)
339 ALLOCATE (opt_bas%comp_group(ncalc))
340 ALLOCATE (opt_bas%group_partition(0:ncalc - 1))
341 DO igroup = 0, ncalc - 1
342 ALLOCATE (opt_bas%comp_group(igroup + 1)%member_list(1))
343 opt_bas%comp_group(igroup + 1)%member_list(1) = igroup
344 opt_bas%group_partition(igroup) = iadd1
345 IF (igroup < iadd2) opt_bas%group_partition(igroup) = opt_bas%group_partition(igroup) + 1
349 iadd2 = mod(ncalc, nproc)
350 ALLOCATE (opt_bas%comp_group(nproc))
351 ALLOCATE (opt_bas%group_partition(0:nproc - 1))
353 DO igroup = 0, nproc - 1
354 opt_bas%group_partition(igroup) = 1
356 IF (igroup < iadd2) isize = isize + 1
357 ALLOCATE (opt_bas%comp_group(igroup + 1)%member_list(isize))
359 opt_bas%comp_group(igroup + 1)%member_list(j) = icount
370 IF (nptot /= nproc)
THEN
371 CALL cp_abort(__location__, &
372 "Number of processors in group distribution does not match number of MPI tasks."// &
373 " Please change input.")
375 IF (.NOT. isize <= ncalc)
THEN
376 CALL cp_abort(__location__, &
377 "Number of Groups larger than number of calculations"// &
378 " Please change input.")
380 cpassert(nptot == nproc)
381 ALLOCATE (opt_bas%comp_group(isize))
382 ALLOCATE (opt_bas%group_partition(0:isize - 1))
383 IF (isize < ncalc)
THEN
385 iadd2 = mod(ncalc, isize)
387 DO igroup = 0, isize - 1
388 opt_bas%group_partition(igroup) = i_vals(igroup + 1)
390 IF (igroup < iadd2) isize = isize + 1
391 ALLOCATE (opt_bas%comp_group(igroup + 1)%member_list(isize))
393 opt_bas%comp_group(igroup + 1)%member_list(j) = icount
398 DO igroup = 0, isize - 1
399 opt_bas%group_partition(igroup) = i_vals(igroup + 1)
400 ALLOCATE (opt_bas%comp_group(igroup + 1)%member_list(1))
401 opt_bas%comp_group(igroup + 1)%member_list(1) = igroup
406 END SUBROUTINE generate_computation_groups
420 CHARACTER(LEN=default_path_length) :: output_file
423 INTEGER :: ibasis, ikind, unit_nr
425 DO ikind = 1, opt_bas%nkind
426 DO ibasis = 1, opt_bas%kind_basis(ikind)%nbasis_deriv
427 CALL update_used_parts(opt_bas%kind_basis(ikind)%deriv_info(ibasis), &
428 opt_bas%kind_basis(ikind)%flex_basis(0), &
429 opt_bas%kind_basis(ikind)%flex_basis(ibasis))
434 IF (para_env%is_source())
THEN
435 CALL open_file(file_name=output_file, file_status=
"UNKNOWN", &
436 file_action=
"WRITE", unit_number=unit_nr)
440 DO ikind = 1, opt_bas%nkind
441 DO ibasis = 0, opt_bas%kind_basis(ikind)%nbasis_deriv
442 CALL write_basis(opt_bas%kind_basis(ikind)%flex_basis(ibasis), opt_bas%kind_basis(ikind)%element, &
446 IF (para_env%is_source())
CALL close_file(unit_number=unit_nr)
459 SUBROUTINE update_used_parts(info_new, basis, basis_new)
463 INTEGER :: icont, iset, jcont, jset
466 DO iset = 1, basis%nsets
467 IF (info_new%in_use_set(iset))
THEN
469 basis_new%subset(jset)%exps(:) = basis%subset(iset)%exps
471 DO icont = 1, basis%subset(iset)%ncon_tot
472 IF (info_new%use_contr(iset)%in_use(icont))
THEN
474 basis_new%subset(jset)%coeff(:, jcont) = basis%subset(iset)%coeff(:, icont)
480 END SUBROUTINE update_used_parts
490 SUBROUTINE generate_derived_basis_sets(opt_bas, para_env, write_work_file)
493 LOGICAL,
INTENT(IN) :: write_work_file
495 INTEGER :: ibasis, ikind, iref, jbasis, unit_nr
497 DO ikind = 1, opt_bas%nkind
498 CALL init_deriv_info_ref(opt_bas%kind_basis(ikind)%deriv_info(0), opt_bas%kind_basis(ikind)%flex_basis(0))
499 opt_bas%kind_basis(ikind)%deriv_info(0)%basis_name = trim(adjustl(opt_bas%kind_basis(ikind)%basis_name))
501 DO ibasis = 1, opt_bas%kind_basis(ikind)%nbasis_deriv
502 iref = opt_bas%kind_basis(ikind)%deriv_info(ibasis)%reference_set
503 DO jbasis = 0, opt_bas%kind_basis(ikind)%nbasis_deriv
504 IF (iref == jbasis)
CALL setup_used_parts_init_basis(opt_bas%kind_basis(ikind)%deriv_info(ibasis), &
505 opt_bas%kind_basis(ikind)%deriv_info(iref), &
506 opt_bas%kind_basis(ikind)%flex_basis(0), &
507 opt_bas%kind_basis(ikind)%flex_basis(ibasis))
512 IF (write_work_file .AND. para_env%is_source())
THEN
513 CALL open_file(file_name=opt_bas%work_basis_file, file_status=
"UNKNOWN", &
514 file_action=
"WRITE", unit_number=unit_nr)
518 DO ikind = 1, opt_bas%nkind
519 DO ibasis = 0, opt_bas%kind_basis(ikind)%nbasis_deriv
520 IF (len_trim(opt_bas%kind_basis(ikind)%deriv_info(ibasis)%basis_name) > 0)
THEN
521 opt_bas%kind_basis(ikind)%flex_basis(ibasis)%basis_name = &
522 trim(adjustl(opt_bas%kind_basis(ikind)%deriv_info(ibasis)%basis_name))
524 opt_bas%kind_basis(ikind)%flex_basis(ibasis)%basis_name = &
525 trim(adjustl(opt_bas%kind_basis(ikind)%basis_name))//
"-DERIVED_SET-"//adjustl(
cp_to_string(ibasis))
527 IF (write_work_file)
THEN
528 CALL write_basis(opt_bas%kind_basis(ikind)%flex_basis(ibasis), &
529 opt_bas%kind_basis(ikind)%element, unit_nr)
533 IF (write_work_file .AND. para_env%is_source())
CALL close_file(unit_number=unit_nr)
535 END SUBROUTINE generate_derived_basis_sets
547 CHARACTER(LEN=default_string_length) :: element
550 INTEGER :: iexp, iset
552 IF (unit_nr > 0)
THEN
553 WRITE (unit=unit_nr, fmt=
"(A)") trim(adjustl(element))//
" "//trim(adjustl(basis%basis_name))
554 WRITE (unit=unit_nr, fmt=
"(1X,I0)") basis%nsets
555 DO iset = 1, basis%nsets
556 WRITE (unit=unit_nr, fmt=
"(30(1X,I0))") basis%subset(iset)%n, basis%subset(iset)%lmin, basis%subset(iset)%lmax, &
557 basis%subset(iset)%nexp, basis%subset(iset)%l
558 DO iexp = 1, basis%subset(iset)%nexp
559 WRITE (unit=unit_nr, fmt=
"(T2,F24.14,30(1X,ES24.14))") &
560 basis%subset(iset)%exps(iexp), basis%subset(iset)%coeff(iexp, :)
577 SUBROUTINE setup_used_parts_init_basis(info_new, info_ref, basis, basis_new)
581 INTEGER :: i, jset, lind, nsets
585 ALLOCATE (info_new%in_use_set(
SIZE(info_ref%in_use_set)))
586 info_new%in_use_set(:) = info_ref%in_use_set
587 ALLOCATE (info_new%use_contr(
SIZE(info_ref%in_use_set)))
588 DO i = 1,
SIZE(info_ref%in_use_set)
589 ALLOCATE (info_new%use_contr(i)%in_use(
SIZE(info_ref%use_contr(i)%in_use)))
590 info_new%use_contr(i)%in_use(:) = info_ref%use_contr(i)%in_use
592 DO i = 1, info_new%nsets
593 info_new%in_use_set(info_new%remove_set(i)) = .false.
595 DO i = 1, info_new%ncontr
596 lind = convert_l_contr_to_entry(basis%subset(info_new%remove_contr(i, 1))%lmin, &
597 basis%subset(info_new%remove_contr(i, 1))%l, &
598 info_new%remove_contr(i, 3), info_new%remove_contr(i, 2))
600 info_new%use_contr(info_new%remove_contr(i, 1))%in_use(lind) = .false.
604 DO i = 1, basis%nsets
605 IF (info_new%in_use_set(i)) nsets = nsets + 1
607 basis_new%nsets = nsets
608 ALLOCATE (basis_new%subset(nsets))
610 DO i = 1, basis%nsets
611 IF (info_new%in_use_set(i))
THEN
613 CALL create_new_subset(basis%subset(i), basis_new%subset(jset), info_new%use_contr(jset)%in_use)
617 END SUBROUTINE setup_used_parts_init_basis
627 SUBROUTINE create_new_subset(subset, subset_new, in_use)
629 LOGICAL,
DIMENSION(:) :: in_use
631 INTEGER :: icon, iind, il
632 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: tmp_l
634 ALLOCATE (tmp_l(
SIZE(subset%l)))
636 subset_new%lmin = subset%lmin
637 subset_new%lmax = subset%lmin - 1
638 subset_new%nexp = subset%nexp
639 subset_new%n = subset%n
640 DO il = 1,
SIZE(subset%l)
641 DO icon = 1, subset%l(il)
642 iind = convert_l_contr_to_entry(subset%lmin, subset%l, icon, subset%lmin + il - 1)
643 IF (.NOT. in_use(iind)) tmp_l(il) = tmp_l(il) - 1
645 IF (tmp_l(il) > 0) subset_new%lmax = subset_new%lmax + 1
647 subset_new%nl = subset_new%lmax - subset_new%lmin + 1
648 subset_new%ncon_tot = sum(tmp_l)
649 ALLOCATE (subset_new%l(subset_new%nl))
650 ALLOCATE (subset_new%coeff(subset_new%nexp, subset_new%ncon_tot))
651 ALLOCATE (subset_new%exps(subset_new%nexp))
652 subset_new%exps(:) = subset%exps
653 DO il = 1,
SIZE(subset%l)
654 IF (tmp_l(il) == 0)
EXIT
655 subset_new%l(il) = tmp_l(il)
659 DO icon = 1, subset%ncon_tot
660 IF (in_use(icon))
THEN
662 subset_new%coeff(:, iind) = subset%coeff(:, icon)
666 END SUBROUTINE create_new_subset
675 SUBROUTINE init_deriv_info_ref(info, basis)
681 ALLOCATE (info%in_use_set(basis%nsets))
682 info%in_use_set = .true.
683 ALLOCATE (info%use_contr(basis%nsets))
684 DO i = 1, basis%nsets
685 ALLOCATE (info%use_contr(i)%in_use(basis%subset(i)%ncon_tot))
686 info%use_contr(i)%in_use = .true.
689 END SUBROUTINE init_deriv_info_ref
700 SUBROUTINE generate_initial_basis(kind_section, opt_bas, para_env)
705 INTEGER :: ikind, variable_counter
710 ALLOCATE (opt_bas%kind_basis(opt_bas%nkind))
714 DO ikind = 1, opt_bas%nkind
715 CALL section_vals_val_get(kind_section,
"_SECTION_PARAMETERS_", c_val=opt_bas%kind_basis(ikind)%element, &
717 CALL section_vals_val_get(kind_section,
"BASIS_SET", c_val=opt_bas%kind_basis(ikind)%basis_name, &
721 CALL section_vals_get(set_section, n_repetition=opt_bas%kind_basis(ikind)%nbasis_deriv, explicit=explicit)
722 IF (.NOT. explicit) opt_bas%kind_basis(ikind)%nbasis_deriv = 0
723 ALLOCATE (opt_bas%kind_basis(ikind)%flex_basis(0:opt_bas%kind_basis(ikind)%nbasis_deriv))
724 ALLOCATE (opt_bas%kind_basis(ikind)%deriv_info(0:opt_bas%kind_basis(ikind)%nbasis_deriv))
726 CALL fill_basis_template(kind_section, opt_bas%kind_basis(ikind)%flex_basis(0), opt_bas%template_basis_file, &
727 opt_bas%kind_basis(ikind)%element, opt_bas%kind_basis(ikind)%basis_name, para_env, ikind)
729 CALL setup_exp_constraints(kind_section, opt_bas%kind_basis(ikind)%flex_basis(0))
731 CALL parse_derived_basis(kind_section, opt_bas%kind_basis(ikind)%deriv_info, ikind)
733 variable_counter = variable_counter + opt_bas%kind_basis(ikind)%flex_basis(0)%nopt
736 ALLOCATE (opt_bas%x_opt(variable_counter))
739 DO ikind = 1, opt_bas%nkind
740 CALL assign_x_to_basis(opt_bas%x_opt, opt_bas%kind_basis(ikind)%flex_basis(0), variable_counter)
743 cpassert(variable_counter ==
SIZE(opt_bas%x_opt))
745 END SUBROUTINE generate_initial_basis
755 SUBROUTINE parse_derived_basis(kind_section, deriv_info, ikind)
760 INTEGER :: i_rep, iset, jset, n_rep, nsets
761 INTEGER,
DIMENSION(:),
POINTER :: i_vals
765 nsets =
SIZE(deriv_info) - 1
774 deriv_info(iset)%reference_set = i_vals(1)
775 CALL section_vals_val_get(set1_section,
"REMOVE_CONTRACTION", explicit=explicit, n_rep_val=n_rep, &
777 deriv_info(iset)%ncontr = n_rep
779 ALLOCATE (deriv_info(iset)%remove_contr(n_rep, 3))
783 deriv_info(iset)%remove_contr(i_rep, :) = i_vals(:)
788 deriv_info(iset)%nsets = n_rep
790 ALLOCATE (deriv_info(iset)%remove_set(n_rep))
794 deriv_info(iset)%remove_set(i_rep) = i_vals(1)
799 END SUBROUTINE parse_derived_basis
808 SUBROUTINE setup_exp_constraints(kind1_section, flex_basis)
812 INTEGER :: ipgf, irep, iset, nrep
813 INTEGER,
DIMENSION(:),
POINTER :: def_exp
814 LOGICAL :: is_bound, is_varlim
822 CALL section_vals_val_get(const_section,
"MAX_VAR_FRACTION", explicit=is_varlim, i_rep_section=irep)
823 IF (is_bound .AND. is_varlim)
THEN
824 CALL cp_abort(__location__,
"Exponent has two constraints. "// &
825 "This is not possible at the moment. Please change input.")
827 IF (.NOT. is_bound .AND. .NOT. is_varlim)
THEN
828 CALL cp_abort(__location__,
"Exponent is declared to be constraint but none is given"// &
829 " Please change input.")
831 IF (def_exp(1) == -1)
THEN
832 DO iset = 1, flex_basis%nsets
833 IF (def_exp(2) == -1)
THEN
834 DO ipgf = 1, flex_basis%subset(iset)%nexp
835 CALL set_constraint(flex_basis, iset, ipgf, const_section, is_bound, is_varlim, irep)
838 IF (def_exp(2) <= flex_basis%subset(iset)%nexp)
THEN
839 CALL cp_abort(__location__, &
840 "Exponent declared in constraint is larger than number of exponents in the set"// &
841 " Please change input.")
843 CALL set_constraint(flex_basis, iset, def_exp(2), const_section, is_bound, is_varlim, irep)
847 IF (.NOT. def_exp(1) <= flex_basis%nsets)
THEN
848 CALL cp_abort(__location__, &
849 "Set number of constraint is larger than number of sets in the template basis set."// &
850 " Please change input.")
852 IF (def_exp(2) == -1)
THEN
853 DO ipgf = 1, flex_basis%subset(iset)%nexp
854 CALL set_constraint(flex_basis, def_exp(1), ipgf, const_section, is_bound, is_varlim, irep)
857 IF (.NOT. def_exp(2) <= flex_basis%subset(def_exp(1))%nexp)
THEN
858 CALL cp_abort(__location__, &
859 "Exponent declared in constraint is larger than number of exponents in the set"// &
860 " Please change input.")
862 CALL set_constraint(flex_basis, def_exp(1), def_exp(2), const_section, is_bound, is_varlim, irep)
867 END SUBROUTINE setup_exp_constraints
882 SUBROUTINE set_constraint(flex_basis, iset, ipgf, const_section, is_bound, is_varlim, irep)
884 INTEGER :: iset, ipgf
886 LOGICAL :: is_bound, is_varlim
889 REAL(kind=
dp) :: r_val
890 REAL(kind=
dp),
DIMENSION(:),
POINTER :: r_vals
892 IF (flex_basis%subset(iset)%exp_has_const(ipgf))
THEN
893 CALL cp_abort(__location__, &
894 "Multiple constraints due to collision in CONSTRAIN_EXPONENTS."// &
895 " Please change input.")
897 flex_basis%subset(iset)%exp_has_const(ipgf) = .true.
899 flex_basis%subset(iset)%exp_const(ipgf)%const_type = 0
901 flex_basis%subset(iset)%exp_const(ipgf)%llim = minval(r_vals)
902 flex_basis%subset(iset)%exp_const(ipgf)%ulim = maxval(r_vals)
903 r_val = flex_basis%subset(iset)%exps(ipgf)
904 IF (flex_basis%subset(iset)%exps(ipgf) > maxval(r_vals) .OR. flex_basis%subset(iset)%exps(ipgf) < minval(r_vals))
THEN
905 CALL cp_abort(__location__, &
907 " declared in constraint is out of bounds of constraint"//
cp_to_string(minval(r_vals))// &
909 " Please change input.")
911 flex_basis%subset(iset)%exp_const(ipgf)%init = sum(r_vals)/2.0_dp
912 flex_basis%subset(iset)%exp_const(ipgf)%var_fac = maxval(r_vals)/flex_basis%subset(iset)%exp_const(ipgf)%init - 1.0_dp
915 flex_basis%subset(iset)%exp_const(ipgf)%const_type = 1
917 flex_basis%subset(iset)%exp_const(ipgf)%var_fac = r_vals(1)
918 flex_basis%subset(iset)%exp_const(ipgf)%init = flex_basis%subset(iset)%exps(ipgf)
921 END SUBROUTINE set_constraint
931 SUBROUTINE assign_x_to_basis(x, basis, x_ind)
932 REAL(kind=
dp),
DIMENSION(:) :: x
936 INTEGER :: icont, ipgf, iset
938 DO iset = 1, basis%nsets
939 DO ipgf = 1, basis%subset(iset)%nexp
940 IF (basis%subset(iset)%opt_exps(ipgf))
THEN
942 basis%subset(iset)%exp_x_ind(ipgf) = x_ind
943 x(x_ind) = basis%subset(iset)%exps(ipgf)
945 DO icont = 1, basis%subset(iset)%ncon_tot
946 IF (basis%subset(iset)%opt_coeff(ipgf, icont))
THEN
948 basis%subset(iset)%coeff_x_ind(ipgf, icont) = x_ind
949 x(x_ind) = basis%subset(iset)%coeff(ipgf, icont)
955 END SUBROUTINE assign_x_to_basis
969 SUBROUTINE fill_basis_template(kind1_section, flex_basis, template_basis_file, element, basis_name, para_env, ikind)
972 CHARACTER(LEN=default_path_length) :: template_basis_file
973 CHARACTER(LEN=default_string_length) :: element, basis_name
977 INTEGER :: icont, idof, ipgf, irep, iset, nrep
978 INTEGER,
DIMENSION(:),
POINTER :: switch
980 CALL parse_basis(flex_basis, template_basis_file, element, basis_name, para_env)
986 DO iset = 1, flex_basis%nsets
991 flex_basis%subset(iset)%opt_coeff = .true.
992 flex_basis%subset(iset)%opt_exps = .true.
994 flex_basis%subset(iset)%opt_coeff = .true.
996 flex_basis%subset(iset)%opt_exps = .true.
998 cpabort(
"No initialization available?????")
1002 CALL section_vals_val_get(kind1_section,
"SWITCH_CONTRACTION_STATE", n_rep_val=nrep, i_rep_section=ikind)
1005 i_rep_section=ikind, i_vals=switch)
1006 icont = convert_l_contr_to_entry(flex_basis%subset(switch(1))%lmin, flex_basis%subset(switch(1))%l, switch(3), switch(2))
1007 DO ipgf = 1, flex_basis%subset(switch(1))%nexp
1008 flex_basis%subset(switch(1))%opt_coeff(ipgf, icont) = .NOT. flex_basis%subset(switch(1))%opt_coeff(ipgf, icont)
1012 CALL section_vals_val_get(kind1_section,
"SWITCH_COEFF_STATE", n_rep_val=nrep, i_rep_section=ikind)
1015 i_rep_section=ikind, i_vals=switch)
1016 icont = convert_l_contr_to_entry(flex_basis%subset(switch(1))%lmin, flex_basis%subset(switch(1))%l, switch(3), switch(2))
1017 flex_basis%subset(switch(1))%opt_coeff(switch(4), icont) = &
1018 .NOT. flex_basis%subset(switch(1))%opt_coeff(switch(4), icont)
1021 CALL section_vals_val_get(kind1_section,
"SWITCH_EXP_STATE", n_rep_val=nrep, i_rep_section=ikind)
1024 i_rep_section=ikind, i_vals=switch)
1025 flex_basis%subset(switch(1))%opt_exps(switch(2)) = .NOT. flex_basis%subset(switch(1))%opt_exps(switch(2))
1028 CALL section_vals_val_get(kind1_section,
"SWITCH_SET_STATE", n_rep_val=nrep, i_rep_section=ikind)
1031 i_rep_section=ikind, i_vals=switch)
1032 DO ipgf = 1, flex_basis%subset(switch(2))%nexp
1033 SELECT CASE (switch(1))
1035 DO icont = 1, flex_basis%subset(switch(2))%ncon_tot
1036 flex_basis%subset(switch(2))%opt_coeff(ipgf, icont) = &
1037 .NOT. flex_basis%subset(switch(2))%opt_coeff(ipgf, icont)
1039 flex_basis%subset(switch(2))%opt_exps(ipgf) = .NOT. flex_basis%subset(switch(2))%opt_exps(ipgf)
1041 flex_basis%subset(switch(2))%opt_exps(ipgf) = .NOT. flex_basis%subset(switch(2))%opt_exps(ipgf)
1043 DO icont = 1, flex_basis%subset(switch(2))%ncon_tot
1044 flex_basis%subset(switch(2))%opt_coeff(ipgf, icont) = &
1045 .NOT. flex_basis%subset(switch(2))%opt_coeff(ipgf, icont)
1048 cpabort(
"Invalid option in SWITCH_SET_STATE, 1st value has to be 0, 1 or 2")
1054 DO irep = 1, flex_basis%nsets
1055 IF (flex_basis%subset(irep)%nexp == 1)
THEN
1056 DO ipgf = 1, flex_basis%subset(irep)%nexp
1057 flex_basis%subset(irep)%opt_coeff(ipgf, 1) = .false.
1064 DO irep = 1, flex_basis%nsets
1065 DO ipgf = 1, flex_basis%subset(irep)%nexp
1066 DO icont = 1, flex_basis%subset(irep)%ncon_tot
1067 IF (flex_basis%subset(irep)%opt_coeff(ipgf, icont)) flex_basis%nopt = flex_basis%nopt + 1
1069 IF (flex_basis%subset(irep)%opt_exps(ipgf)) flex_basis%nopt = flex_basis%nopt + 1
1073 END SUBROUTINE fill_basis_template
1086 FUNCTION convert_l_contr_to_entry(lmin, nl, icontr, l)
RESULT(ientry)
1088 INTEGER,
DIMENSION(:) :: nl
1089 INTEGER :: icontr, l, ientry
1091 INTEGER :: i, icon2l, iwork
1096 icon2l = icon2l + nl(i)
1098 ientry = icon2l + icontr
1100 END FUNCTION convert_l_contr_to_entry
1112 SUBROUTINE parse_basis(flex_basis, template_basis_file, element, basis_name, para_env)
1114 CHARACTER(LEN=default_path_length) :: template_basis_file
1115 CHARACTER(LEN=default_string_length) :: element, basis_name
1118 CHARACTER(LEN=240) :: line
1119 CHARACTER(LEN=242) :: line2
1120 CHARACTER(LEN=LEN(basis_name)+2) :: basis_name2
1121 CHARACTER(LEN=LEN(element)+2) :: element2
1122 INTEGER :: iset, strlen1, strlen2
1123 LOGICAL :: basis_found, found, match
1126 basis_found = .false.
1129 CALL parser_create(parser, template_basis_file, para_env=para_env)
1137 line2 =
" "//line//
" "
1138 element2 =
" "//trim(element)//
" "
1139 basis_name2 =
" "//trim(basis_name)//
" "
1140 strlen1 = len_trim(element2) + 1
1141 strlen2 = len_trim(basis_name2) + 1
1142 IF ((index(line2, element2(:strlen1)) > 0) .AND. &
1143 (index(line2, basis_name2(:strlen2)) > 0)) match = .true.
1146 ALLOCATE (flex_basis%subset(flex_basis%nsets))
1147 DO iset = 1, flex_basis%nsets
1148 CALL parse_subset(parser, flex_basis%subset(iset))
1150 basis_found = .true.
1159 IF (.NOT. basis_found)
CALL cp_abort(__location__, &
1160 "The requested basis set <"//trim(basis_name)// &
1161 "> for element <"//trim(element)//
"> was not "// &
1162 "found in the template basis set file ")
1164 END SUBROUTINE parse_basis
1172 SUBROUTINE parse_subset(parser, subset)
1176 CHARACTER(len=20*default_string_length) :: line_att
1177 INTEGER :: icon1, icon2, il, ipgf, ishell, istart
1178 REAL(kind=
dp) :: gs_scale
1179 REAL(kind=
dp),
POINTER :: r_val
1186 subset%nl = subset%lmax - subset%lmin + 1
1188 ALLOCATE (subset%l(subset%nl))
1189 ALLOCATE (subset%exps(subset%nexp))
1190 ALLOCATE (subset%exp_has_const(subset%nexp))
1191 subset%exp_has_const = .false.
1192 ALLOCATE (subset%opt_exps(subset%nexp))
1193 subset%opt_exps = .false.
1194 ALLOCATE (subset%exp_const(subset%nexp))
1195 ALLOCATE (subset%exp_x_ind(subset%nexp))
1196 DO ishell = 1, subset%nl
1199 subset%ncon_tot = sum(subset%l)
1200 ALLOCATE (subset%coeff(subset%nexp, subset%ncon_tot))
1201 ALLOCATE (subset%opt_coeff(subset%nexp, subset%ncon_tot))
1202 subset%opt_coeff = .false.
1203 ALLOCATE (subset%coeff_x_ind(subset%nexp, subset%ncon_tot))
1204 DO ipgf = 1, subset%nexp
1206 subset%exps(ipgf) = r_val
1207 DO ishell = 1, subset%ncon_tot
1209 subset%coeff(ipgf, ishell) = r_val
1215 DO il = 1, subset%nl
1216 DO icon1 = istart, istart + subset%l(il) - 2
1217 DO icon2 = icon1 + 1, istart + subset%l(il) - 1
1218 gs_scale = dot_product(subset%coeff(:, icon2), subset%coeff(:, icon1))/ &
1219 dot_product(subset%coeff(:, icon1), subset%coeff(:, icon1))
1220 subset%coeff(:, icon2) = subset%coeff(:, icon2) - gs_scale*subset%coeff(:, icon1)
1223 istart = istart + subset%l(il)
1227 DO icon1 = 1, subset%ncon_tot
1228 subset%coeff(:, icon1) = subset%coeff(:, icon1)/norm2(subset%coeff(:, icon1))
1232 END SUBROUTINE parse_subset
1241 SUBROUTINE init_powell_var(p_param, powell_section)
1253 END SUBROUTINE init_powell_var
Utility routines to open and close files. Tracking of preconnections.
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
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
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
Utility routines to read data from files. Kept as close as possible to the old parser because.
subroutine, public parser_search_string(parser, string, ignore_case, found, line, begin_line, search_from_begin_of_file)
Search a string pattern in a file defined by its logical unit number "unit". A case sensitive search ...
Utility routines to read data from files. Kept as close as possible to the old parser because.
subroutine, public parser_release(parser)
releases the parser
subroutine, public parser_create(parser, file_name, unit_nr, para_env, end_section_label, separator_chars, comment_char, continuation_char, quote_char, section_char, parse_white_lines, initial_variables, apply_preprocessing)
Start a parser run. Initial variables allow to @SET stuff before opening the file.
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
integer, parameter, public default_path_length
Machine interface based on Fortran 2003 and POSIX.
integer, parameter, public default_output_unit
subroutine, public m_getcwd(curdir)
...
Interface to the message passing library MPI.
integer, parameter, public method_mo_fit_occ
integer, parameter, public method_mo_fit_occ_virtual
subroutine, public get_set_and_basis_id(calc_id, opt_bas, set_id, bas_id)
returns a mapping from the calculation id to the trainings set id and basis combination id
subroutine, public optimize_basis_init_read_input(opt_bas, root_section, para_env, quiet_output, embedded_training)
initialize all parts of the optimization type and read input settings
subroutine, public write_basis(basis, element, unit_nr)
Write a basis set file which can be used from CP2K.
subroutine, public update_derived_basis_sets(opt_bas, write_it, output_file, para_env)
Regenerate the basis sets from reference 0 after an update from the optimizer to reference was perfor...
Utilities for string manipulations.
character(len=1), parameter, public newline
elemental subroutine, public uppercase(string)
Convert all lower case characters in a string to upper case.
type of a logger, at the moment it contains just a print level starting at which level it should be l...
stores all the informations relevant to an mpi environment
type containing all information needed for basis matching