File: input_cp2k_ls.F

package info (click to toggle)
cp2k 6.1-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 204,532 kB
  • sloc: fortran: 835,196; f90: 59,605; python: 9,861; sh: 7,882; cpp: 4,868; ansic: 2,807; xml: 2,185; lisp: 733; pascal: 612; perl: 547; makefile: 497; csh: 16
file content (605 lines) | stat: -rw-r--r-- 33,571 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
!--------------------------------------------------------------------------------------------------!
!   CP2K: A general program to perform molecular dynamics simulations                              !
!   Copyright (C) 2000 - 2018  CP2K developers group                                               !
!--------------------------------------------------------------------------------------------------!

! **************************************************************************************************
!> \brief input for the linear scaling (LS) section
!> \author Joost VandeVondele
! **************************************************************************************************
MODULE input_cp2k_ls
   USE bibliography,                    ONLY: Lin2009,&
                                              Lin2013,&
                                              Niklasson2003,&
                                              Shao2003,&
                                              VandeVondele2012
   USE cp_output_handling,              ONLY: cp_print_key_section_create,&
                                              high_print_level
   USE cp_units,                        ONLY: cp_unit_to_cp2k
   USE input_constants,                 ONLY: &
        ls_cluster_atomic, ls_cluster_molecular, ls_s_inversion_hotelling, &
        ls_s_inversion_sign_sqrt, ls_s_preconditioner_atomic, ls_s_preconditioner_molecular, &
        ls_s_preconditioner_none, ls_scf_line_search_3point, ls_scf_line_search_3point_2d, &
        ls_scf_ns, ls_scf_pexsi, ls_scf_tc2, ls_scf_trs4
   USE input_keyword_types,             ONLY: keyword_create,&
                                              keyword_release,&
                                              keyword_type
   USE input_section_types,             ONLY: section_add_keyword,&
                                              section_add_subsection,&
                                              section_create,&
                                              section_release,&
                                              section_type
   USE input_val_types,                 ONLY: integer_t,&
                                              real_t
   USE kinds,                           ONLY: dp
   USE pao_input,                       ONLY: create_pao_section
   USE qs_density_mixing_types,         ONLY: create_mixing_section
   USE string_utilities,                ONLY: s2a
#include "./base/base_uses.f90"

   IMPLICIT NONE
   PRIVATE

   CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'input_cp2k_ls'

   PUBLIC :: create_ls_scf_section

CONTAINS
! **************************************************************************************************
!> \brief creates the linear scaling scf section
!> \param section ...
!> \author Joost VandeVondele [2010-10]
! **************************************************************************************************
   SUBROUTINE create_ls_scf_section(section)
      TYPE(section_type), POINTER                        :: section

      CHARACTER(len=*), PARAMETER :: routineN = 'create_ls_scf_section', &
         routineP = moduleN//':'//routineN

      TYPE(keyword_type), POINTER                        :: keyword
      TYPE(section_type), POINTER                        :: subsection

      CPASSERT(.NOT. ASSOCIATED(section))
      CALL section_create(section, "LS_SCF", &
                          description="Specifies the parameters of the linear scaling SCF routines", &
                          n_keywords=24, n_subsections=3, repeats=.FALSE., &
                          citations=(/VandeVondele2012/))

      NULLIFY (keyword, subsection)

      CALL keyword_create(keyword, name="LS_DIIS", &
                          description="Perform DIIS within linear scaling SCF", &
                          usage="LS_DIIS", lone_keyword_l_val=.TRUE., &
                          default_l_val=.FALSE.)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="INI_DIIS", &
                          description="Iteration cycle to start DIIS Kohn-Sham matrix update", &
                          usage="INI_DIIS 2", default_i_val=2)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="MAX_DIIS", &
                          description="Size of LS_DIIS buffer", &
                          usage="MAX_DIIS 4", default_i_val=4)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="NMIXING", &
                          description="Minimal number of density mixing before start DIIS", &
                          usage="NMIXING 2", default_i_val=2)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="EPS_DIIS", &
                          description="Threshold on the convergence to start using DIIS", &
                          usage="EPS_DIIS 1.e-1", default_r_val=1.e-1_dp)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="MAX_SCF", &
                          description="Maximum number of SCF iteration to be performed for one optimization", &
                          usage="MAX_SCF 200", default_i_val=20)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create( &
         keyword, name="EPS_SCF", &
         description="Target accuracy for the SCF convergence in terms of change of the total energy per electron.", &
         usage="EPS_SCF 1.e-6", default_r_val=1.e-7_dp)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="MIXING_FRACTION", &
                          description="Mixing density matrices uses the specified fraction in the SCF procedure.", &
                          usage="MIXING_FRACTION 0.4", default_r_val=0.45_dp)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="EPS_FILTER", &
                          description="Threshold used for filtering matrix operations.", &
                          usage="EPS_FILTER 1.0E-7", default_r_val=1.0E-6_dp)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="EPS_LANCZOS", &
                          description="Threshold used for lanczos estimates.", &
                          usage="EPS_LANCZOS 1.0E-4", default_r_val=1.0E-3_dp)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="MAX_ITER_LANCZOS", &
                          description="Maximum number of lanczos iterations.", &
                          usage="MAX_ITER_LANCZOS ", default_i_val=128)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="MU", &
                          description="Value (or initial guess) for the chemical potential,"// &
                          " i.e. some suitable energy between HOMO and LUMO energy.", &
                          usage="MU 0.0", default_r_val=-0.1_dp)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="FIXED_MU", &
                          description="Should the calculation be performed at fixed chemical potential,"// &
                          " or should it be found fixing the number of electrons", &
                          usage="FIXED_MU .TRUE.", default_l_val=.FALSE., lone_keyword_l_val=.TRUE.)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="EXTRAPOLATION_ORDER", &
                          description="Number of previous matrices used for the ASPC extrapolation of the initial guess. "// &
                          "0 implies that an atomic guess is used at each step. "// &
                          "low (1-2) will result in a drift of the constant of motion during MD. "// &
                          "high (>5) might be somewhat unstable, leading to more SCF iterations.", &
                          usage="EXTRAPOLATION_ORDER 3", default_i_val=4)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="S_PRECONDITIONER", &
                          description="Preconditions S with some appropriate form.", &
                          usage="S_PRECONDITIONER MOLECULAR", &
                          default_i_val=ls_s_preconditioner_atomic, &
                          enum_c_vals=s2a("NONE", "ATOMIC", "MOLECULAR"), &
                          enum_desc=s2a("No preconditioner", &
                                        "Using atomic blocks", &
                                        "Using molecular sub-blocks. Recommended if molecules are defined and not too large."), &
                          enum_i_vals=(/ls_s_preconditioner_none, ls_s_preconditioner_atomic, ls_s_preconditioner_molecular/))
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="PURIFICATION_METHOD", &
                          description="Scheme used to purify the Kohn-Sham matrix into the density matrix.", &
                          usage="PURIFICATION_METHOD TRS4", &
                          default_i_val=ls_scf_ns, &
                          citations=(/VandeVondele2012, Niklasson2003/), &
                          enum_c_vals=s2a("SIGN_MATRIX", "TRS4", "TC2", "PEXSI"), &
                          enum_desc=s2a("Newton-Schulz sign matrix iteration.", &
                                        "Trace resetting 4th order scheme", &
                                        "Trace conserving 2nd order scheme", &
                                        "PEXSI method"), &
                          enum_i_vals=(/ls_scf_ns, ls_scf_trs4, ls_scf_tc2, ls_scf_pexsi/))
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="DYNAMIC_THRESHOLD", &
                          description="Should the threshold for the purification be chosen dynamically", &
                          usage="DYNAMIC_THRESHOLD .TRUE.", default_l_val=.FALSE., lone_keyword_l_val=.TRUE.)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="NON_MONOTONIC", &
                          description="Should the purification be performed non-monotonically. Relevant for TC2 only.", &
                          usage="NON_MONOTONIC .TRUE.", default_l_val=.TRUE., lone_keyword_l_val=.TRUE.)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create( &
         keyword, name="MATRIX_CLUSTER_TYPE", &
         description="Specify how atomic blocks should be clustered in the used matrices, in order to improve flop rate, "// &
         "and possibly speedup the matrix multiply. Note that the atomic s_preconditioner can not be used."// &
         "Furthermore, since screening is on matrix blocks, "// &
         "slightly more accurate results can be expected with molecular.", &
         usage="MATRIX_CLUSTER_TYPE MOLECULAR", &
         default_i_val=ls_cluster_atomic, &
         enum_c_vals=s2a("ATOMIC", "MOLECULAR"), &
         enum_desc=s2a("Using atomic blocks", &
                       "Using molecular blocks."), &
         enum_i_vals=(/ls_cluster_atomic, ls_cluster_molecular/))
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="SINGLE_PRECISION_MATRICES", &
                          description="Matrices used within the LS code can be either double or single precision.", &
                          usage="SINGLE_PRECISION_MATRICES", default_l_val=.FALSE., lone_keyword_l_val=.TRUE.)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create( &
         keyword, name="RESTART_WRITE", &
         description="Write the density matrix at the end of the SCF (currently requires EXTRAPOLATION_ORDER>0). "// &
         "Files might be rather large.", &
         usage="RESTART_READ", default_l_val=.FALSE., lone_keyword_l_val=.TRUE.)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="RESTART_READ", &
                          description="Read the density matrix before the (first) SCF.", &
                          usage="RESTART_READ", default_l_val=.FALSE., lone_keyword_l_val=.TRUE.)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="S_INVERSION", &
                          description="Method used to compute the inverse of S.", &
                          usage="S_PRECONDITIONER MOLECULAR", &
                          default_i_val=ls_s_inversion_sign_sqrt, &
                          enum_c_vals=s2a("SIGN_SQRT", "HOTELLING"), &
                          enum_desc=s2a("Using the inverse sqrt as obtained from sign function iterations.", &
                                        "Using the Hotellign iteration."), &
                          enum_i_vals=(/ls_s_inversion_sign_sqrt, ls_s_inversion_hotelling/))
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="SIGN_SQRT_ORDER", &
                          description="Order of the sqrt iteration, should be 2..5, 3 or 5 recommended", &
                          usage="SIGN_SQRT_ORDER 5", &
                          default_i_val=3)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="REPORT_ALL_SPARSITIES", &
                          description="Run the sparsity report at the end of the SCF", &
                          usage="REPORT_ALL_SPARSITIES", default_l_val=.TRUE., lone_keyword_l_val=.TRUE.)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="PERFORM_MU_SCAN", &
                          description="Do a scan of the chemical potential after the SCF", &
                          usage="PERFORM_MU_SCAN", default_l_val=.FALSE., lone_keyword_l_val=.TRUE.)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="CHECK_S_INV", &
                          description="Perform an accuracy check on the inverse/sqrt of the s matrix.", &
                          usage="CHECK_S_INV", default_l_val=.FALSE., lone_keyword_l_val=.TRUE.)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL create_ls_curvy_section(subsection)
      CALL section_add_subsection(section, subsection)
      CALL section_release(subsection)

      CALL create_chebyshev_section(subsection)
      CALL section_add_subsection(section, subsection)
      CALL section_release(subsection)

      CALL create_mixing_section(subsection, ls_scf=.TRUE.)
      CALL section_add_subsection(section, subsection)
      CALL section_release(subsection)

      CALL create_pexsi_section(subsection)
      CALL section_add_subsection(section, subsection)
      CALL section_release(subsection)

      CALL create_pao_section(subsection)
      CALL section_add_subsection(section, subsection)
      CALL section_release(subsection)

   END SUBROUTINE create_ls_scf_section

! **************************************************************************************************
!> \brief creates the DOS section
!> \param section ...
!> \author Joost VandeVondele, Jinwoong Cha [2012-10]
! **************************************************************************************************
   SUBROUTINE create_chebyshev_section(section)
      TYPE(section_type), POINTER                        :: section

      CHARACTER(len=*), PARAMETER :: routineN = 'create_chebyshev_section', &
         routineP = moduleN//':'//routineN

      TYPE(keyword_type), POINTER                        :: keyword
      TYPE(section_type), POINTER                        :: print_key

      CPASSERT(.NOT. ASSOCIATED(section))

      CALL section_create(section, "CHEBYSHEV", &
                          description="Specifies the parameters needed for the chebyshev expansion based properties.", &
                          n_keywords=24, n_subsections=3, repeats=.FALSE.)

      NULLIFY (keyword)
      NULLIFY (print_key)

      CALL keyword_create(keyword, name="N_CHEBYSHEV", &
                          description="Order of the polynomial expansion.", &
                          usage="N_CHEBYSHEV 2000", default_i_val=500)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      ! A DOS print key
      CALL cp_print_key_section_create(print_key, "DOS", &
                                       description="Controls the printing of the Density of States (DOS).", &
                                       print_level=high_print_level, filename="")
      CALL keyword_create(keyword, name="N_GRIDPOINTS", &
                          description="Number of points in the computed DOS", &
                          usage="N_GRIDPOINTS 10000", default_i_val=2000)
      CALL section_add_keyword(print_key, keyword)
      CALL keyword_release(keyword)
      CALL section_add_subsection(section, print_key)
      CALL section_release(print_key)

      ! Energy specific electron density cubes
      CALL cp_print_key_section_create( &
         print_key, &
         name="PRINT_SPECIFIC_E_DENSITY_CUBE", &
         description="Controls the printing of cube files with "// &
         "the electronic density (states) "// &
         "contributing to the density of states within "// &
         "the specific energy range "// &
         "(MIN_ENERGY ≤ E ≤ MAX_ENERGY). MIN_ENERGY and MAX_ENERGY need to be specified explicitly.", &
         print_level=high_print_level, filename="")

      CALL keyword_create(keyword, name="stride", &
                          description="The stride (X,Y,Z) used to write the cube file "// &
                          "(larger values result in smaller cube files). You can provide 3 numbers (for X,Y,Z) or"// &
                          " 1 number valid for all components.", &
                          usage="STRIDE 2 2 2", n_var=-1, default_i_vals=(/2, 2, 2/), type_of_var=integer_t)
      CALL section_add_keyword(print_key, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="MIN_ENERGY", &
                          description="Lower bounds of the energy ranges of interest.", &
                          usage="MIN_ENERGY -1.01 -0.62 0.10 .. ", &
                          type_of_var=real_t, n_var=-1)
      CALL section_add_keyword(print_key, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="MAX_ENERGY", &
                          description="Upper bounds of the energy ranges of interest.", &
                          usage="MAX_ENERGY -0.81 -0.43 0.22 .. ", &
                          type_of_var=real_t, n_var=-1)
      CALL section_add_keyword(print_key, keyword)
      CALL keyword_release(keyword)

      CALL section_add_subsection(section, print_key)
      CALL section_release(print_key)

   END SUBROUTINE create_chebyshev_section

! **************************************************************************************************
!> \brief creates the curvy_steps section in linear scaling scf
!> \param section ...
!> \author Florian Schiffmann [2012-10]
! **************************************************************************************************
   SUBROUTINE create_ls_curvy_section(section)
      TYPE(section_type), POINTER                        :: section

      CHARACTER(len=*), PARAMETER :: routineN = 'create_ls_curvy_section', &
         routineP = moduleN//':'//routineN

      TYPE(keyword_type), POINTER                        :: keyword

      CPASSERT(.NOT. ASSOCIATED(section))
      CALL section_create(section, "CURVY_STEPS", &
                          description="Specifies the parameters of the linear scaling SCF routines", &
                          n_keywords=24, n_subsections=3, repeats=.FALSE., &
                          citations=(/Shao2003/))

      NULLIFY (keyword)

      CALL keyword_create(keyword, name="LINE_SEARCH", &
                          description="Line serch type used in the curvy_setp optimization.", &
                          usage="LINE Search 3POINT", default_i_val=ls_scf_line_search_3point, &
                          enum_c_vals=s2a("3POINT", "3POINT_2D"), &
                          enum_desc=s2a("Performs a three point line search", &
                                        "Only for spin unrestricted calcualtions. Separate step sizes for alpha and beta spin"// &
                                        " using a fit to a 2D parabolic function"), &
                          enum_i_vals=(/ls_scf_line_search_3point, ls_scf_line_search_3point_2d/))
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="N_BCH_HISTORY", &
                          description="Number of stored matrices in the Baker-Campbell-Hausdorff series. "// &
                          "Reduces the BCH evaluation during line search but can be memory intense. ", &
                          usage="N_BCH_HISTORY 5", &
                          default_i_val=7)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="MIN_HESSIAN_SHIFT", &
                          description="Minimal eigenvalue shift for the Hessian in the Newton iteration."// &
                          " Useful for small band gap systems (0.5-1.0 recommended). ", &
                          usage="MIN_HESSIAN_SHIFT 0.0", default_r_val=0.0_dp)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="FILTER_FACTOR", &
                          description="Allows to set a seperate EPS_FILTER in the newton iterations."// &
                          " The new EPS is EPS_FILTER*FILTER_FACTOR.", &
                          usage="FILTER_FACTOR 10.0", default_r_val=1.0_dp)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="FILTER_FACTOR_SCALE", &
                          description="Allows for dynamic EPS_FILTER. Updates the filter factor every SCF-Newton "// &
                          "step by FILTER_FACTOR=FILTER_FACTOR*FILTER_FACTOR_SCALE", &
                          usage="FILTER_FACTOR_SCALE 0.5", default_r_val=1.0_dp)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="MIN_FILTER", &
                          description="Lowest EPS_FILTER in dynamic filtering. Given as multiple of EPS_FILTER:"// &
                          " EPS_FILTER_MIN=EPS_FILTER*MIN_FILTER", &
                          usage="FILTER_FACTOR 1.0", default_r_val=1.0_dp)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

   END SUBROUTINE create_ls_curvy_section

! **************************************************************************************************
!> \brief creates the PEXSI library subsection of the linear scaling section.
!> \param section ...
!> \par History
!>      11.2014 created [Patrick Seewald]
!> \author Patrick Seewald
! **************************************************************************************************
   SUBROUTINE create_pexsi_section(section)
      TYPE(section_type), POINTER                        :: section

      CHARACTER(len=*), PARAMETER :: routineN = 'create_pexsi_section', &
         routineP = moduleN//':'//routineN

      TYPE(keyword_type), POINTER                        :: keyword

      CPASSERT(.NOT. ASSOCIATED(section))

      CALL section_create(section, "PEXSI", &
                          description="Specifies the parameters of the PEXSI library. The density matrix is calculated "// &
                          "with PEXSI if PURIFICATION_METHOD (in LS_SCF section) is set to PEXSI. "// &
                          "The computational cost of PEXSI is at most quadratically scaling w.r.t. the system size "// &
                          "and PEXSI is applicable to insulating and metallic systems. The value of EPS_PGF_ORB "// &
                          "(in QS input section) defines the sparsity of the matrices sent to PEXSI and EPS_FILTER "// &
                          "is overwritten with 0.", &
                          n_keywords=17, repeats=.FALSE., citations=(/Lin2009, Lin2013/))
      NULLIFY (keyword)

      CALL keyword_create(keyword, name="TEMPERATURE", &
                          description="Electronic temperature", &
                          default_r_val=cp_unit_to_cp2k(value=300.0_dp, unit_str="K"), &
                          unit_str="K")
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="GAP", &
                          description="Spectral gap. Note: This can be set to be 0 in most cases.", &
                          default_r_val=0.0_dp, unit_str="hartree")
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="NUM_POLE", &
                          description="Number of terms in the pole expansion (should be even).", &
                          default_i_val=64)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="IS_INERTIA_COUNT", &
                          description="Whether inertia counting is used each time the DFT driver "// &
                          "of PEXSI is invoked. If FALSE, inertia counting is still used in the "// &
                          "first SCF iteration.", &
                          default_l_val=.FALSE., lone_keyword_l_val=.TRUE.)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="MAX_PEXSI_ITER", &
                          description="Maximum number of PEXSI iterations after each inertia counting procedure.", &
                          default_i_val=5)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="MU_MIN_0", &
                          description="Initial guess of lower bound for mu.", &
                          default_r_val=-5.0_dp, unit_str="hartree")
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="MU_MAX_0", &
                          description="Initial guess of upper bound for mu.", &
                          default_r_val=5.0_dp, unit_str="hartree")
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="MU_INERTIA_TOLERANCE", &
                          description="Stopping criterion in terms of the chemical potential for the "// &
                          "inertia counting procedure.", &
                          default_r_val=0.01_dp, unit_str="hartree")
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="MU_INERTIA_EXPANSION", &
                          description="If the chemical potential is not in the initial interval, "// &
                          "the interval is expanded by MU_INERTIA_EXPANSION.", &
                          default_r_val=0.15_dp, unit_str="hartree")
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="MU_PEXSI_SAFE_GUARD", &
                          description="Safe guard criterion in terms of the chemical potential to "// &
                          "reinvoke the inertia counting procedure.", &
                          default_r_val=0.01_dp, unit_str="hartree")
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="NUM_ELECTRON_PEXSI_TOLERANCE", &
                          description="Stopping criterion of the PEXSI iteration in terms of "// &
                          "The number of electrons compared to the exact number of electrons. "// &
                          "This threshold is the target tolerance applied at convergence of SCF.", &
                          default_r_val=0.1_dp)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="NUM_ELECTRON_INITIAL_TOLERANCE", &
                          description="The same as NUM_ELECTRON_PEXSI_TOLERANCE but applied in the first SCF steps. "// &
                          "If set to a value smaller than NUM_ELECTRON_PEXSI_TOLERANCE, it is overwritten with "// &
                          "NUM_ELECTRON_PEXSI_TOLERANCE (default). If set to a value larger than "// &
                          "NUM_ELECTRON_PEXSI_TOLERANCE, the PEXSI tolerance in number of electrons is set adaptively "// &
                          "according to the SCF convergence error of the previous SCF step. This reduces the number "// &
                          "of PEXSI iterations in the first SCF steps but leads to at least one more SCF step.", &
                          default_r_val=0.0_dp)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="ORDERING", &
                          description="Ordering strategy for factorization and selected inversion.", &
                          enum_c_vals=s2a("PARALLEL", "SEQUENTIAL", "MULTIPLE_MINIMUM_DEGREE"), &
                          enum_desc=s2a("Parallel ordering using ParMETIS/PT-SCOTCH (PARMETIS option in SuperLU_DIST)", &
                                        "Sequential ordering using METIS (METIS_AT_PLUS_A option in SuperLU_DIST)", &
                                        "Multiple minimum degree ordering (MMD_AT_PLUS_A option in SuperLU_DIST)"), &
                          enum_i_vals=(/0, 1, 2/), default_i_val=0)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="ROW_ORDERING", &
                          description="row permutation strategy for factorization and selected inversion.", &
                          enum_c_vals=s2a("NOROWPERM", "LARGEDIAG"), &
                          enum_desc=s2a("No row permutation (NOROWPERM option in SuperLU_DIST)", &
                                        "Make diagonal entry larger than off diagonal (LargeDiag option in SuperLU_DIST)"), &
                          enum_i_vals=(/0, 1/), default_i_val=0)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="NP_SYMB_FACT", &
                          description="Number of processors for PARMETIS/PT-SCOTCH. Only used if ORDERING is set to PARALLEL. "// &
                          "If 0, the number of processors for PARMETIS/PT-SCOTCH will be set equal to the number of "// &
                          "MPI ranks per pole. Note: if more than one processor is used, a segmentation fault may occur in the "// &
                          "symbolic factorization phase.", &
                          default_i_val=1)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="VERBOSITY", &
                          description="The level of output information.", &
                          enum_c_vals=s2a("SILENT", "BASIC", "DETAILED"), &
                          enum_i_vals=(/0, 1, 2/), default_i_val=1)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="MIN_RANKS_PER_POLE", &
                          description="The minimum number of processors used for each pole. The real "// &
                          "number of processors per pole is the smallest number greater or equal to "// &
                          "MIN_RANKS_PER_POLE that divides MPI size without remainder. For efficiency, MIN_RANKS_PER_POLE "// &
                          "should be a small numbers (limited by the available memory).", &
                          default_i_val=64)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

      CALL keyword_create(keyword, name="CSR_SCREENING", &
                          description="Whether distance screening should be applied to improve sparsity of CSR matrices.", &
                          default_l_val=.TRUE., lone_keyword_l_val=.TRUE.)
      CALL section_add_keyword(section, keyword)
      CALL keyword_release(keyword)

   END SUBROUTINE create_pexsi_section

END MODULE input_cp2k_ls