Octopus
geom_opt.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2007 M. Marques, A. Castro, A. Rubio, G. Bertsch, M. Oliveira
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20#include "build_info.h"
21
22module geom_opt_oct_m
24 use debug_oct_m
28 use forces_oct_m
29 use global_oct_m
31 use io_oct_m
34 use ions_oct_m
35 use, intrinsic :: iso_fortran_env
37 use lcao_oct_m
38 use loct_oct_m
39 use math_oct_m
40 use mesh_oct_m
43 use mpi_oct_m
46 use parser_oct_m
47 use pcm_oct_m
51 use scf_oct_m
57 use unit_oct_m
59 use v_ks_oct_m
61
62 implicit none
63
64 private
65 public :: geom_opt_run
66
67 type geom_opt_t
68 private
69 integer(int64) :: type
70 integer :: method
71 real(real64) :: step
72 real(real64) :: line_tol
73 real(real64) :: fire_mass
74 integer :: fire_integrator
75 real(real64) :: tolgrad
76 real(real64) :: toldr
77 integer :: max_iter
78 integer :: what2minimize
79
81 type(scf_t) :: scfv
82 type(ions_t), pointer :: ions
83 type(hamiltonian_elec_t), pointer :: hm
84 type(electrons_t), pointer :: syst
85 class(mesh_t), pointer :: mesh
86 type(states_elec_t), pointer :: st
87 integer :: dim
88 integer :: periodic_dim
89 integer :: size
90 integer :: fixed_atom = 0
91
92 real(real64), allocatable :: cell_force(:, :)
93 logical :: symmetrize = .false.
94 real(real64), allocatable :: initial_length(:)
95 real(real64), allocatable :: initial_rlattice(:, :)
96 real(real64), allocatable :: inv_initial_rlattice(:, :)
97 real(real64) :: pressure = m_zero
98
99 logical :: poscar_output = .false.
100
102 integer :: calculator
103 logical :: ml_preopt = .false.
104 end type geom_opt_t
105
106 type(geom_opt_t), save :: g_opt
107
108 integer, parameter :: &
109 MINWHAT_ENERGY = 1, &
111
112 integer, parameter :: &
113 GO_IONS = 1, &
114 go_cell = 2, &
115 go_volume = 4
116
117 integer, parameter :: &
118 GO_CALCULATOR_INTERNAL = 1, &
120
121contains
122
123 ! ---------------------------------------------------------
124 subroutine mattersim_paths(mattersim_share, mattersim_python, namespace)
125 character(len=*), intent(out) :: mattersim_share, mattersim_python
126 type(namespace_t), intent(in) :: namespace
127
128 logical :: python_exists
129
130 ! In build-tree runs conf%share points to build/share, but the
131 ! MatterSim virtual environment is created when installing Octopus.
132 mattersim_share = trim(conf%share)
133 mattersim_python = trim(mattersim_share) // "/mattersim_env/bin/python"
134 inquire(file=trim(mattersim_python), exist=python_exists)
135 if (python_exists) return
136
137 mattersim_share = share_dir
138 mattersim_python = trim(mattersim_share) // "/mattersim_env/bin/python"
139 inquire(file=trim(mattersim_python), exist=python_exists)
140 if (python_exists) return
141
142 message(1) = 'Unable to find the MatterSim Python environment.'
143 message(2) = 'Please install Octopus with MatterSim support before using the MatterSim calculator.'
144 call messages_fatal(2, namespace=namespace)
145 end subroutine mattersim_paths
147 ! ---------------------------------------------------------
148 subroutine geom_opt_run(system, from_scratch)
149 class(*), intent(inout) :: system
150 logical, intent(inout) :: from_scratch
152 push_sub(geom_opt_run)
153
154 select type (system)
156 message(1) = "CalculationMode = go not implemented for multi-system calculations"
157 call messages_fatal(1, namespace=system%namespace)
158 type is (electrons_t)
159 call geom_opt_run_legacy(system, from_scratch)
160 end select
163 end subroutine geom_opt_run
164
165 ! ---------------------------------------------------------
166 subroutine geom_opt_run_legacy(sys, fromscratch)
167 type(electrons_t), target, intent(inout) :: sys
168 logical, intent(inout) :: fromscratch
170 integer :: ierr
171 real(real64), allocatable :: coords(:)
172 real(real64) :: energy
173
174 real(real64), allocatable :: mass(:)
175 integer :: iatom, imass
176 type(restart_t) :: restart_load
177 logical :: known_lower_bound
178 logical :: default_val
180 push_sub(geom_opt_run_legacy)
182 ! For 1D-periodic systems the ion-ion interaction (hence the forces) and the stress
183 ! tensor are not implemented.
184 if (sys%space%periodic_dim == 1) then
185 message(1) = "Geometry optimization is not allowed for systems periodic in 1D, "
186 message(2) = "as the ion-ion interaction and the stress tensor are not available."
187 call messages_fatal(2, namespace=sys%namespace)
188 end if
189
190 if (sys%space%periodic_dim == 2) then
191 call messages_experimental("Geometry optimization for 2D-periodic systems", namespace=sys%namespace)
192 end if
193
194
195 if (sys%hm%pcm%run_pcm) then
196 call messages_not_implemented("PCM for CalculationMode /= gs or td", namespace=sys%namespace)
197 end if
198
199 if (sys%kpoints%use_symmetries) then
200 call messages_experimental("KPoints symmetries with CalculationMode = go", namespace=sys%namespace)
201 end if
202
203 g_opt%symmetrize = sys%kpoints%use_symmetries .or. sys%st%symmetrize_density
204
205 call init_(fromscratch)
206
207 ! load wavefunctions
208 if (.not. fromscratch) then
209 call restart_load%init(sys%namespace, restart_gs, restart_type_load, sys%mc, ierr, mesh=sys%gr)
210 if (ierr == 0) then
211 call states_elec_load(restart_load, sys%namespace, sys%space, sys%st, sys%gr, sys%kpoints, &
212 fixed_occ=.false., ierr=ierr)
213 end if
214 call restart_load%end()
215 if (ierr /= 0) then
216 message(1) = "Unable to read wavefunctions: Starting from scratch."
217 call messages_warning(1, namespace=sys%namespace)
218 fromscratch = .true.
219 end if
220 end if
222 call scf_init(g_opt%scfv, sys%namespace, sys%gr, sys%ions, sys%st, sys%mc, sys%hm, sys%space)
223
224 if (bitand(g_opt%type, go_cell) /= 0 .or. bitand(g_opt%type, go_volume) /= 0) then
225 if (.not. g_opt%scfv%calc_stress) then
226 message(1) = "In order to optimize the cell, one needs to set SCFCalculateStress = yes."
227 call messages_fatal(1, namespace=sys%namespace)
228 end if
229 end if
230
231 if (fromscratch) then
232 call lcao_run(sys%namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, sys%st, sys%ks, sys%hm, &
233 lmm_r = g_opt%scfv%lmm_r, known_lower_bound=known_lower_bound)
234 call scf_set_lower_bound_is_known(g_opt%scfv, known_lower_bound)
235 else
236 ! setup Hamiltonian
237 message(1) = 'Info: Setting up Hamiltonian.'
238 call messages_info(1, namespace=sys%namespace)
239 call v_ks_h_setup(sys%namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, sys%st, sys%ks, sys%hm)
240 call scf_set_lower_bound_is_known(g_opt%scfv, .true.)
241 end if
242
243 !Initial point
244 safe_allocate(coords(1:g_opt%size))
245 call to_coords(g_opt, coords)
246
247 if (sys%st%pack_states .and. sys%hm%apply_packed()) call sys%st%pack()
248
249 !Minimize
250 select case (g_opt%method)
252 call minimize_multidim_nograd(g_opt%method, g_opt%size, coords, g_opt%step,&
253 g_opt%toldr, g_opt%max_iter, &
254 calc_point_ng, write_iter_info_ng, energy, ierr)
255
256 case (minmethod_fire)
257
258 safe_allocate(mass(1:g_opt%size))
259 mass = g_opt%fire_mass
260 imass = 1
261 do iatom = 1, sys%ions%natoms
262 if (g_opt%fixed_atom == iatom) cycle
263 if (g_opt%ions%fixed(iatom)) cycle
264 if (g_opt%fire_mass <= m_zero) mass(imass:imass + 2) = sys%ions%mass(iatom)
265 imass = imass + g_opt%dim
266 end do
267
268 !TODO: add variable to use Euler integrator
269 call minimize_fire(g_opt%size, g_opt%ions%space%dim, coords, g_opt%step, g_opt%tolgrad, &
270 g_opt%max_iter, calc_point, write_iter_info, energy, ierr, mass, integrator=g_opt%fire_integrator)
271
272 safe_deallocate_a(mass)
273
274 case default
275 call minimize_multidim(g_opt%method, g_opt%size, coords, g_opt%step ,&
276 g_opt%line_tol , g_opt%tolgrad, g_opt%toldr, g_opt%max_iter, &
277 calc_point, write_iter_info, energy, ierr)
278
279 end select
280
281 if (ierr == 1025) then
282 ! not a GSL error, set by our minimize routines, so we must handle it separately
283 message(1) = "Reached maximum number of iterations allowed by GOMaxIter."
284 call messages_info(1, namespace=sys%namespace)
285 else if (ierr /= 0 .and. g_opt%method /= minmethod_fire) then
286 message(1) = "Error occurred during the GSL minimization procedure:"
287 call loct_strerror(ierr, message(2))
288 call messages_fatal(2, namespace=sys%namespace)
289 end if
290
291 if (sys%st%pack_states .and. sys%hm%apply_packed()) call sys%st%unpack()
292
293
294 ! print out geometry
295 message(1) = "Writing final coordinates to min.xyz"
296 call messages_info(1, namespace=sys%namespace)
297 call from_coords(g_opt, coords)
298 call g_opt%ions%write_xyz('./min')
299
300 safe_deallocate_a(coords)
301 call scf_end(g_opt%scfv)
302 ! Because g_opt has the "save" attribute, we need to explicitly empty the criteria list here, or there will be a memory leak.
303 call g_opt%scfv%criterion_list%empty()
304 call end_()
305
306 pop_sub(geom_opt_run_legacy)
307 contains
308
309 ! ---------------------------------------------------------
310 subroutine init_(fromscratch)
311 logical, intent(inout) :: fromscratch
312
313 logical :: center, does_exist
314 integer :: iter, iatom, idir
315 character(len=100) :: filename
316 real(real64) :: default_toldr
317 real(real64) :: default_step
318 type(read_coords_info) :: xyz
319
320 push_sub(geom_opt_run_legacy.init_)
321
322 if (sys%space%is_periodic()) then
323 call messages_experimental('Geometry optimization for periodic systems', namespace=sys%namespace)
324 end if
325
326 !%Variable GOType
327 !%Type flag
328 !%Default ions
329 !%Section Calculation Modes::Geometry Optimization
330 !%Description
331 !% This variable defines which parameters are allowed to change during the optimization.
332 !% Multiple options can be chosen e.g. “ion_positions + cell_shape”.
333 !% Only one type of lattice vectors relaxation is possible.
334 !%Option ion_positions 1
335 !% Relax position of ions based on the forces acting on the ions.
336 !%Option cell_shape 2
337 !% Relax cell shape. This changes lattice vector lengths and directions
338 !% based on the stress acting on the lattice vectors.
339 !% See for instance Wentzcovitch, PRB 44, 2358 (1991).
340 !%Option cell_volume 4
341 !% Relax cell volume. Only allow for rescaling the lengths of lattice vectors.
342 !% This is a simplication of the option cell_shape, where only a diagonal strain is allowed.
343 !%End
344
345 call parse_variable(sys%namespace, 'GOType', go_ions, g_opt%type)
346 if (.not. varinfo_valid_option('GOType', g_opt%type, is_flag=.true.)) then
347 call messages_input_error(sys%namespace, 'GOType')
348 end if
349
350 write(message(1),'(a)') 'Input: [GOType = '
351 if (bitand(g_opt%type, go_ions) /= 0) then
352 write(message(1),'(a,1x,a)') trim(message(1)), 'ion_positions'
353 end if
354 if (bitand(g_opt%type, go_cell) /= 0) then
355 if (len_trim(message(1)) > 16) then
356 write(message(1),'(a,1x,a)') trim(message(1)), '+'
357 end if
358 write(message(1),'(a,1x,a)') trim(message(1)), 'cell_shape'
359 end if
360 if (bitand(g_opt%type, go_volume) /= 0) then
361 if (len_trim(message(1)) > 16) then
362 write(message(1),'(a,1x,a)') trim(message(1)), '+'
363 end if
364 write(message(1),'(a,1x,a)') trim(message(1)), 'cell_volume'
365 end if
366 write(message(1),'(2a)') trim(message(1)), ']'
367 call messages_info(1, namespace=sys%namespace)
368
369 if (bitand(g_opt%type, go_volume) /= 0 .and. bitand(g_opt%type, go_cell) /= 0) then
370 message(1) = "Cell and volume optimization cannot be used simultaneously."
371 call messages_fatal(1, namespace=sys%namespace)
372 end if
373
374
375 if (bitand(g_opt%type, go_cell) /= 0 .or. bitand(g_opt%type, go_volume) /= 0) then
376 if (parse_is_defined(sys%namespace, 'TDMomentumTransfer') .or. &
377 parse_is_defined(sys%namespace, 'TDReducedMomentumTransfer')) then
378 call messages_not_implemented("Cell dynamics with TDMomentumTransfer and TDReducedMomentumTransfer")
379 end if
380 end if
381
382 do iatom = 1, sys%ions%natoms
383 select type(spec=>sys%ions%atom(iatom)%species)
384 class is(allelectron_t)
385 write(message(1),'(a)') "Geometry optimization for all-electron potential is not implemented."
386 call messages_fatal(1)
387 end select
388 end do
389
390
391 call states_elec_allocate_wfns(sys%st, sys%gr, packed=.true.)
392
393 ! shortcuts
394 g_opt%mesh => sys%gr
395 g_opt%ions => sys%ions
396 g_opt%st => sys%st
397 g_opt%hm => sys%hm
398 g_opt%syst => sys
399 g_opt%dim = sys%space%dim
400 g_opt%periodic_dim = sys%space%periodic_dim
401
402 g_opt%size = 0
403 ! Ion dyamics
404 if (bitand(g_opt%type, go_ions) /= 0) then
405 g_opt%size = g_opt%dim * g_opt%ions%natoms
406 end if
407
408 ! Cell dynamics
409 if (bitand(g_opt%type, go_cell) /= 0) then
410 g_opt%size = g_opt%size + (g_opt%periodic_dim +1) * g_opt%periodic_dim / 2
411 safe_allocate(g_opt%cell_force(1:g_opt%periodic_dim, 1:g_opt%periodic_dim))
412 end if
413
414 ! Volume dynamics
415 if (bitand(g_opt%type, go_volume) /= 0) then
416 g_opt%size = g_opt%size + g_opt%periodic_dim
417 safe_allocate(g_opt%cell_force(1:g_opt%periodic_dim, 1:1))
418 ! Store the length of the original lattic vectors, to work with reduced lengthes
419 safe_allocate(g_opt%initial_length(1:g_opt%periodic_dim))
420 do idir = 1, g_opt%periodic_dim
421 g_opt%initial_length(idir) = norm2(g_opt%ions%latt%rlattice(1:g_opt%periodic_dim, idir))
422 end do
423 end if
424
425 ! Store the initial lattice vectors and the inverse matrix
426 if (bitand(g_opt%type, go_cell) /= 0 .or. bitand(g_opt%type, go_volume) /= 0) then
427 safe_allocate(g_opt%initial_rlattice(1:g_opt%periodic_dim, 1:g_opt%periodic_dim))
428 g_opt%initial_rlattice(1:g_opt%periodic_dim, 1:g_opt%periodic_dim) &
429 = g_opt%ions%latt%rlattice(1:g_opt%periodic_dim, 1:g_opt%periodic_dim)
430 safe_allocate(g_opt%inv_initial_rlattice(1:g_opt%periodic_dim, 1:g_opt%periodic_dim))
431 g_opt%inv_initial_rlattice(:, :) = g_opt%initial_rlattice(:, :)
432 call lalg_inverse(g_opt%periodic_dim, g_opt%inv_initial_rlattice, 'dir')
433 end if
434
435 if(g_opt%ions%space%is_periodic()) then
436 call parse_variable(sys%namespace, 'HydrostaticPressure', m_zero, g_opt%pressure)
437 end if
438
439 !%Variable GOCenter
440 !%Type logical
441 !%Default no
442 !%Section Calculation Modes::Geometry Optimization
443 !%Description
444 !% (Experimental) If set to yes, Octopus centers the geometry at
445 !% every optimization step. It also reduces the degrees of
446 !% freedom of the optimization by using the translational
447 !% invariance.
448 !%End
449 call parse_variable(sys%namespace, 'GOCenter', .false., center)
450
451 if (center .and. bitand(g_opt%type, go_ions) /= 0) then
452 g_opt%fixed_atom = 1
453 g_opt%size = g_opt%size - g_opt%dim
454 call messages_experimental('GOCenter', namespace=sys%namespace)
455 end if
456
457 !Check if atoms are allowed to move and redifine g_opt%size
458 do iatom = 1, g_opt%ions%natoms
459 if (g_opt%ions%fixed(iatom) .and. bitand(g_opt%type, go_ions) /= 0) then
460 g_opt%size = g_opt%size - g_opt%dim
461 end if
462 end do
463
464 assert(g_opt%size > 0)
465
466 !%Variable GOMethod
467 !%Type integer
468 !%Default fire
469 !%Section Calculation Modes::Geometry Optimization
470 !%Description
471 !% Method by which the minimization is performed. For more information see the
472 !% <a href=https://www.gnu.org/software/gsl/doc/html/multimin.html>
473 !% GSL documentation</a>.
474 !%Option steep 1
475 !% Simple steepest descent.
476 !%Option steep_native -1
477 !% (Experimental) Non-gsl implementation of steepest descent.
478 !%Option cg_fr 2
479 !% Fletcher-Reeves conjugate-gradient algorithm. The
480 !% conjugate-gradient algorithm proceeds as a succession of line
481 !% minimizations. The sequence of search directions is used to build
482 !% up an approximation to the curvature of the function in the
483 !% neighborhood of the minimum.
484 !%Option cg_pr 3
485 !% Polak-Ribiere conjugate-gradient algorithm.
486 !%Option cg_bfgs 4
487 !% Vector Broyden-Fletcher-Goldfarb-Shanno (BFGS) conjugate-gradient algorithm.
488 !% It is a quasi-Newton method which builds up an approximation to the second
489 !% derivatives of the function <i>f</i> using the difference between successive gradient
490 !% vectors. By combining the first and second derivatives, the algorithm is able
491 !% to take Newton-type steps towards the function minimum, assuming quadratic
492 !% behavior in that region.
493 !%Option cg_bfgs2 5
494 !% The bfgs2 version of this minimizer is the most efficient version available,
495 !% and is a faithful implementation of the line minimization scheme described in
496 !% Fletcher, <i>Practical Methods of Optimization</i>, Algorithms 2.6.2 and 2.6.4.
497 !%Option simplex 6
498 !% This is experimental, and in fact, <b>not</b> recommended unless you just want to
499 !% fool around. It is the Nead-Melder simplex algorithm, as implemented in the
500 !% GNU Scientific Library (GSL). It does not make use of the gradients (<i>i.e.</i>, the
501 !% forces) which makes it less efficient than other schemes. It is included here
502 !% for completeness, since it is free.
503 !%Option fire 8
504 !% The FIRE algorithm. See also <tt>GOFireMass</tt> and <tt>GOFireIntegrator</tt>.
505 !% Ref: E. Bitzek, P. Koskinen, F. Gahler, M. Moseler, and P. Gumbsch, <i>Phys. Rev. Lett.</i> <b>97</b>, 170201 (2006).
506 !%End
507 call parse_variable(sys%namespace, 'GOMethod', minmethod_fire, g_opt%method)
508 if (.not. varinfo_valid_option('GOMethod', g_opt%method)) call messages_input_error(sys%namespace, 'GOMethod')
509
510
511 call messages_print_var_option("GOMethod", g_opt%method, namespace=sys%namespace)
512
513 !%Variable GOTolerance
514 !%Type float
515 !%Default 0.001 H/b (0.051 eV/A)
516 !%Section Calculation Modes::Geometry Optimization
517 !%Description
518 !% Convergence criterion, for stopping the minimization. In
519 !% units of force; minimization is stopped when all forces on
520 !% ions are smaller than this criterion, or the
521 !% <tt>GOMinimumMove</tt> is satisfied. If <tt>GOTolerance < 0</tt>,
522 !% this criterion is ignored.
523 !%End
524 call parse_variable(sys%namespace, 'GOTolerance', 0.001_real64, g_opt%tolgrad, units_inp%force)
525
526 !%Variable GOMinimumMove
527 !%Type float
528 !%Section Calculation Modes::Geometry Optimization
529 !%Description
530 !% Convergence criterion, for stopping the minimization. In
531 !% units of length; minimization is stopped when the coordinates
532 !% of all species change less than <tt>GOMinimumMove</tt>, or the
533 !% <tt>GOTolerance</tt> criterion is satisfied.
534 !% If <tt>GOMinimumMove < 0</tt>, this criterion is ignored.
535 !% Default is -1, except 0.001 b with <tt>GOMethod = simplex</tt>.
536 !% Note that if you use <tt>GOMethod = simplex</tt>,
537 !% then you must supply a non-zero <tt>GOMinimumMove</tt>.
538 !%End
539 if (g_opt%method == minmethod_nmsimplex) then
540 default_toldr = 0.001_real64
541 else
542 default_toldr = -m_one
543 end if
544 call parse_variable(sys%namespace, 'GOMinimumMove', default_toldr, g_opt%toldr, units_inp%length)
545
546 if (g_opt%method == minmethod_nmsimplex .and. g_opt%toldr <= m_zero) call messages_input_error(sys%namespace, 'GOMinimumMove')
547
548 !%Variable GOStep
549 !%Type float
550 !%Section Calculation Modes::Geometry Optimization
551 !%Description
552 !% Initial step for the geometry optimizer. The default is 0.5.
553 !% WARNING: in some weird units.
554 !% For the FIRE minimizer, default value is 0.1 fs,
555 !% and corresponds to the initial time-step for the MD.
556 !%End
557 if (g_opt%method /= minmethod_fire) then
558 default_step = m_half
559 call parse_variable(sys%namespace, 'GOStep', default_step, g_opt%step)
560 else
561 default_step = 0.1_real64*unit_femtosecond%factor
562 call parse_variable(sys%namespace, 'GOStep', default_step, g_opt%step, unit = units_inp%time)
563 end if
564
565 !%Variable GOLineTol
566 !%Type float
567 !%Default 0.1
568 !%Section Calculation Modes::Geometry Optimization
569 !%Description
570 !% Tolerance for line-minimization. Applies only to GSL methods
571 !% that use the forces.
572 !% WARNING: in some weird units.
573 !%End
574 call parse_variable(sys%namespace, 'GOLineTol', 0.1_real64, g_opt%line_tol)
575
576 !%Variable GOMaxIter
577 !%Type integer
578 !%Default 200
579 !%Section Calculation Modes::Geometry Optimization
580 !%Description
581 !% Even if the convergence criterion is not satisfied, the minimization will stop
582 !% after this number of iterations.
583 !%End
584 call parse_variable(sys%namespace, 'GOMaxIter', 200, g_opt%max_iter)
585 if (g_opt%max_iter <= 0) then
586 message(1) = "GOMaxIter has to be larger than 0"
587 call messages_fatal(1, namespace=sys%namespace)
588 end if
589
590 !%Variable GOFireMass
591 !%Type float
592 !%Default 1.0 amu
593 !%Section Calculation Modes::Geometry Optimization
594 !%Description
595 !% The Fire algorithm (<tt>GOMethod = fire</tt>) assumes that all degrees of freedom
596 !% are comparable. All the velocities should be on the same
597 !% scale, which for heteronuclear systems can be roughly
598 !% achieved by setting all the atom masses equal, to the value
599 !% specified by this variable.
600 !% By default the mass of a proton is selected (1 amu).
601 !% However, a selection of <tt>GOFireMass = 0.01</tt> can, in manys systems,
602 !% speed up the geometry optimization procedure.
603 !% If <tt>GOFireMass</tt> <= 0, the masses of each
604 !% species will be used.
605 !%End
606 call parse_variable(sys%namespace, 'GOFireMass', m_one*unit_amu%factor, g_opt%fire_mass, unit = unit_amu)
607
608 !%Variable GOFireIntegrator
609 !%Type integer
610 !%Default verlet
611 !%Section Calculation Modes::Geometry Optimization
612 !%Description
613 !% The Fire algorithm (<tt>GOMethod = fire</tt>) uses a molecular dynamics
614 !% integrator to compute new geometries and velocities.
615 !% Currently, two integrator schemes can be selected
616 !%Option euler 0
617 !% The Explicit Euler method.
618 !%Option verlet 1
619 !% The Velocity Verlet algorithm.
620 !%Option semi_implicit_euler 2
621 !% Semi-implicit Euler integration, see J. Guénolé, et al. Computational Materials Science 175 (2020) 109584.
622 !%End
623 call parse_variable(sys%namespace, 'GOFireIntegrator', option__gofireintegrator__verlet, g_opt%fire_integrator)
624
625 call messages_obsolete_variable(sys%namespace, 'GOWhat2Minimize', 'GOObjective')
626
627 !%Variable GOObjective
628 !%Type integer
629 !%Default minimize_energy
630 !%Section Calculation Modes::Geometry Optimization
631 !%Description
632 !% This rather esoteric option allows one to choose which
633 !% objective function to minimize during a geometry
634 !% minimization. The use of this variable may lead to
635 !% inconsistencies, so please make sure you know what you are
636 !% doing.
637 !%Option minimize_energy 1
638 !% Use the total energy as objective function.
639 !%Option minimize_forces 2
640 !% Use <math>\sqrt{\sum_i \left| f_i \right|^2}</math> as objective function.
641 !% Note that in this case one still uses the forces as the gradient of the objective function.
642 !% This is, of course, inconsistent, and may lead to very strange behavior.
643 !%End
644 call parse_variable(sys%namespace, 'GOObjective', minwhat_energy, g_opt%what2minimize)
645 if (.not. varinfo_valid_option('GOObjective', g_opt%what2minimize)) call messages_input_error(sys%namespace, 'GOObjective')
646 call messages_print_var_option("GOObjective", g_opt%what2minimize, namespace=sys%namespace)
647
648
649 !%Variable XYZGOConstrains
650 !%Type string
651 !%Section Calculation Modes::Geometry Optimization
652 !%Description
653 !% <tt>Octopus</tt> will try to read the coordinate-dependent constrains from the XYZ file
654 !% specified by the variable <tt>XYZGOConstrains</tt>.
655 !% Note: It is important for the contrains to maintain the ordering
656 !% in which the atoms were defined in the coordinates specifications.
657 !% Moreover, constrains impose fixed absolute coordinates, therefore
658 !% constrains are not compatible with GOCenter = yes
659 !%End
660
661 !%Variable XSFGOConstrains
662 !%Type string
663 !%Section Calculation Modes::Geometry Optimization
664 !%Description
665 !% Like <tt>XYZGOConstrains</tt> but in XCrySDen format, as in <tt>XSFCoordinates</tt>.
666 !%End
667
668 !%Variable PDBGOConstrains
669 !%Type string
670 !%Section Calculation Modes::Geometry Optimization
671 !%Description
672 !% Like <tt>XYZGOConstrains</tt> but in PDB format, as in <tt>PDBCoordinates</tt>.
673 !%End
674
675 !%Variable GOConstrains
676 !%Type block
677 !%Section Calculation Modes::Geometry Optimization
678 !%Description
679 !% If <tt>XYZGOConstrains</tt>, <tt>PDBConstrains</tt>, and <tt>XSFGOConstrains</tt>
680 !% are not present, <tt>Octopus</tt> will try to fetch the geometry optimization
681 !% contrains from this block. If this block is not present, <tt>Octopus</tt>
682 !% will not set any constrains. The format of this block can be
683 !% illustrated by this example:
684 !%
685 !% <tt>%GOConstrains
686 !% <br>&nbsp;&nbsp;'C' | 1 | 0 | 0
687 !% <br>&nbsp;&nbsp;'O' | &nbsp;1 | 0 | 0
688 !% <br>%</tt>
689 !%
690 !% Coordinates with a constrain value of 0 will be optimized, while
691 !% coordinates with a constrain different from zero will be kept fixed. So,
692 !% in this example the x coordinates of both atoms will remain fixed and the
693 !% distance between the two atoms along the x axis will be constant.
694 !%
695 !% Note: It is important for the constrains to maintain the ordering
696 !% in which the atoms were defined in the coordinates specifications.
697 !% Moreover, constrains impose fixed absolute coordinates, therefore
698 !% constrains are not compatible with GOCenter = yes
699 !%End
700
701 call read_coords_init(xyz)
702 call read_coords_read('GOConstrains', xyz, g_opt%ions%space, sys%namespace)
703 if (xyz%source /= read_coords_err) then
704 !Sanity check
705 if (g_opt%ions%natoms /= xyz%n) then
706 write(message(1), '(a,i4,a,i4)') 'I need exactly ', g_opt%ions%natoms, ' constrains, but I found ', xyz%n
707 call messages_fatal(1, namespace=sys%namespace)
708 end if
709 ! copy information and adjust units
710 do iatom = 1, g_opt%ions%natoms
711 where(abs(xyz%atom(iatom)%x) <= m_epsilon)
712 g_opt%ions%atom(iatom)%c = m_zero
713 elsewhere
714 g_opt%ions%atom(iatom)%c = m_one
715 end where
716 end do
717
718 call read_coords_end(xyz)
719
720
721 if (g_opt%fixed_atom > 0) then
722 call messages_not_implemented("GOCenter with constrains", namespace=sys%namespace)
723 end if
724 else
725 do iatom = 1, g_opt%ions%natoms
726 g_opt%ions%atom(iatom)%c = m_zero
727 end do
728 end if
729
730 !%Variable GOCalculator
731 !%Type integer
732 !%Default internal
733 !%Section Calculation Modes::Geometry Optimization
734 !%Description
735 !% Defines what calculator is used for performing geometry optimization.
736 !% By default, Octopus is used for computing the forces and energy.
737 !% However, it is possible to use (if selected at compile time) a machine-learned
738 !% universal force field to do the optimization of the geometry instead of Octopus.
739 !%
740 !%Option internal 1
741 !% Usual case: forces/stress are only computed by Octopus
742 !%Option mattersim 2
743 !% MatterSim deep learning atomistic model.
744 !%End
745 call parse_variable(sys%namespace, 'GOCalculator', go_calculator_internal, g_opt%calculator)
746 if (.not. varinfo_valid_option('GOCalculator', g_opt%calculator)) then
747 call messages_input_error(sys%namespace, 'GOCalculator')
748 end if
749#ifndef HAVE_MATTERSIM
750 if (g_opt%calculator == go_calculator_mattersim) then
751 message(1) = 'Octopus was not compiled with support for MatterSim'
752 call messages_fatal(1, namespace=sys%namespace)
753 end if
754#endif
755
756 !%Variable GOMLPreoptimize
757 !%Type logical
758 !%Default yes (if compiled with MatterSim)
759 !%Section Calculation Modes::Geometry Optimization
760 !%Description
761 !% If true, a machine-learned force field is used to pre-optimize the geometry,
762 !% once, before the actual optimization starts.
763 !% Currently, only uses MatterSim. This is not compatible with <tt>GOCalculator=mattersim</tt>.
764 !% Requires Octopus to be compiled with MatterSim; the default is no otherwise.
765 !% The default is also no for <tt>GOCalculator=mattersim</tt>, and when relaxing
766 !% the cell of a system which is not periodic along all three directions.
767 !% The pre-optimization keeps the coordinates fixed by <tt>GOConstrains</tt> and
768 !% <tt>GOCenter</tt>, as well as the atoms of a fixed species.
769 !%End
770#ifdef HAVE_MATTERSIM
771 default_val = .true.
772 if (g_opt%calculator == go_calculator_mattersim) default_val = .false.
773 !TODO: Add support for mixed periodicity
774 if (sys%space%periodic_dim /= 3 .and. &
775 (bitand(g_opt%type, go_cell) /= 0 .or. bitand(g_opt%type, go_volume) /= 0)) default_val = .false.
776#else
777 default_val = .false.
778#endif
779 call parse_variable(sys%namespace, 'GOMLPreoptimize', default_val, g_opt%ml_preopt)
780#ifndef HAVE_MATTERSIM
781 if (g_opt%ml_preopt) then
782 message(1) = 'Octopus was not compiled with support for MatterSim'
783 call messages_fatal(1, namespace=sys%namespace)
784 end if
785#endif
786
787 call io_mkdir('geom', sys%namespace)
788
789 if (g_opt%ml_preopt) then
790 call ml_preopt(g_opt)
791 end if
792
793
794 call io_rm("geom/optimization.log", sys%namespace)
795
796 call io_rm("work-geom.xyz", sys%namespace)
797
798 if (.not. fromscratch) then
799 inquire(file = './last.xyz', exist = does_exist)
800 if (.not. does_exist) fromscratch = .true.
801 end if
802
803 if (.not. fromscratch) call g_opt%ions%read_xyz('./last')
804
805 ! clean out old geom/go.XXXX.xyz files. must be consistent with write_iter_info
806 iter = 1
807 do
808 write(filename, '(a,i4.4,a)') "geom/go.", iter, ".xyz"
809 inquire(file = trim(filename), exist = does_exist)
810 if (does_exist) then
811 call io_rm(trim(filename), sys%namespace)
812 if (sys%space%periodic_dim > 0) then
813 write(filename, '(a,i4.4,a)') "geom/go.", iter, ".xyz_red"
814 call io_rm(trim(filename), sys%namespace)
815 write(filename, '(a,i4.4,a)') "geom/go.", iter, ".xsf"
816 call io_rm(trim(filename), sys%namespace)
817 end if
818 iter = iter + 1
819 else
820 exit
821 end if
822 ! TODO: clean forces directory
823 end do
824
825 call g_opt%scfv%restart_dump%init(sys%namespace, restart_gs, restart_type_dump, sys%mc, ierr, mesh=sys%gr)
826
828 end subroutine init_
829
830
831 ! ---------------------------------------------------------
832 subroutine end_()
833 push_sub(geom_opt_run_legacy.end_)
834
835 call states_elec_deallocate_wfns(sys%st)
836
837 call g_opt%scfv%restart_dump%end()
838
839 nullify(g_opt%mesh)
840 nullify(g_opt%ions)
841 nullify(g_opt%st)
842 nullify(g_opt%hm)
843 nullify(g_opt%syst)
844
845 safe_deallocate_a(g_opt%cell_force)
846
848 end subroutine end_
849
850 end subroutine geom_opt_run_legacy
851
852
853 ! ---------------------------------------------------------
856 subroutine calc_point(size, coords, objective, getgrad, df)
857 integer, intent(in) :: size
858 real(real64), intent(in) :: coords(size)
859 real(real64), intent(inout) :: objective
860 integer, intent(in) :: getgrad
861 real(real64), intent(inout) :: df(size)
862
863 integer :: iatom, idir, jdir, iunit, command_status, command_exit
864 real(real64), dimension(g_opt%periodic_dim, g_opt%periodic_dim) :: stress, strain, right_stretch, inv_right_stretch, &
865 rotation, sym_stress
866 real(real64) :: det
867 character(len=MAX_PATH_LEN) :: cmd, mattersim_share, mattersim_python
868
869 push_sub(calc_point)
870
871 assert(size == g_opt%size)
872 command_status = 0
873 command_exit = 0
874
875 call from_coords(g_opt, coords)
876
877 if (bitand(g_opt%type, go_cell) /= 0 .or. bitand(g_opt%type, go_volume) /= 0 ) then
878 call ion_dynamics_box_update(g_opt%syst%namespace, g_opt%syst%gr, g_opt%syst%space, g_opt%ions%latt)
879 end if
880
881 if (g_opt%fixed_atom /= 0) then
882 call g_opt%ions%translate(g_opt%ions%center())
883 end if
884
885 ! When the system is periodic in some directions, the atoms might have moved to a an adjacent cell,
886 ! so we need to move them back to the original cell
887 call g_opt%ions%fold_atoms_into_cell()
888
889 ! Some atoms might have moved outside the simulation box. We stop if this happens.
890 do iatom = 1, g_opt%ions%natoms
891 if (.not. g_opt%syst%gr%box%contains_point(g_opt%ions%pos(:, iatom))) then
892 if (g_opt%syst%space%periodic_dim /= g_opt%syst%space%dim) then
893 ! FIXME: This could fail for partial periodicity systems
894 ! because contains_point is too strict with atoms close to
895 ! the upper boundary to the cell.
896 write(message(1), '(a,i5,a)') "Atom ", iatom, " has moved outside the box during the geometry optimization."
897 call messages_fatal(1, namespace=g_opt%syst%namespace)
898 end if
899 end if
900 end do
901
902 if (g_opt%calculator==go_calculator_internal) then
903 call g_opt%ions%write_xyz('./work-geom', append = .true.)
904 else
905 if (g_opt%ions%space%is_periodic()) then
906 call write_extended_xyz_file('.', 'work-geom', g_opt%ions%space, g_opt%ions%latt, g_opt%ions%pos, g_opt%ions%atom, &
907 g_opt%syst%gr%box, g_opt%syst%namespace)
908 else
909 call g_opt%ions%write_xyz('./work-geom', append = .false.)
910 end if
911 end if
912
913 ! Update lattice vectors and regenerate grid
914 if (bitand(g_opt%type, go_cell) /= 0 .or. bitand(g_opt%type, go_volume) /= 0 ) then
915 call electrons_lattice_vectors_update(g_opt%syst%namespace, g_opt%syst%gr, &
916 g_opt%syst%space, g_opt%syst%hm%psolver, g_opt%syst%hm%kpoints, &
917 g_opt%syst%mc, g_opt%syst%st%qtot, g_opt%ions%latt)
918 end if
919
920 ! This is already set to zero for periodic systems
921 if (g_opt%ions%force_total_enforce) then
922 call forces_set_total_to_zero(g_opt%ions, g_opt%ions%tot_force)
923 end if
924
925 call scf_print_mem_use(g_opt%syst%namespace)
926
927 ! Select the calculator: Octopus or a ML force field
928 select case (g_opt%calculator)
929 case (go_calculator_internal)
930
931 call scf_mix_clear(g_opt%scfv)
932 call hamiltonian_elec_epot_generate(g_opt%hm, g_opt%syst%namespace, g_opt%syst%space, g_opt%syst%gr, &
933 g_opt%ions, g_opt%syst%ext_partners, g_opt%st)
934 call density_calc(g_opt%st, g_opt%syst%gr, g_opt%st%rho, &
935 ep = g_opt%hm%ep, vnl = g_opt%hm%uspp_overlap, phase = g_opt%hm%phase)
936 call v_ks_calc(g_opt%syst%ks, g_opt%syst%namespace, g_opt%syst%space, g_opt%hm, g_opt%st, &
937 g_opt%ions,g_opt%syst%ext_partners, calc_eigenval = .true.)
938 call energy_calc_total(g_opt%syst%namespace, g_opt%syst%space, g_opt%hm, g_opt%syst%gr, g_opt%st, g_opt%syst%ext_partners)
939
940 ! do SCF calculation
941 call scf_run(g_opt%scfv, g_opt%syst%namespace, g_opt%syst%space, g_opt%syst%mc, g_opt%syst%gr, &
942 g_opt%ions, g_opt%syst%ext_partners, &
943 g_opt%st, g_opt%syst%ks, g_opt%hm, outp = g_opt%syst%outp, verbosity = verb_compact, restart_dump=g_opt%scfv%restart_dump)
944
945 call scf_print_mem_use(g_opt%syst%namespace)
946
948 call mattersim_paths(mattersim_share, mattersim_python, g_opt%syst%namespace)
949 if (mpi_world%is_root()) then
950 ! Execute a system call for the current geometry
951 ! -I isolates the venv python from any external PYTHONPATH/PYTHONHOME
952 cmd = trim(mattersim_python) // " -I " // trim(mattersim_share) &
953 // "/scripts/run_mattersim.py work-geom.xyz ml_forces.xyz " // trim(mattersim_share)
954 call execute_command_line(trim(cmd), exitstat=command_exit, cmdstat=command_status)
955 if (command_status == 0) command_status = command_exit
956 end if
957 call mpi_world%bcast(command_status, 1, mpi_integer, 0)
958 if (command_status /= 0) then
959 write(message(1), '(a,i0)') 'MatterSim force calculation failed with exit status ', command_status
960 call messages_fatal(1, namespace=g_opt%syst%namespace)
961 end if
962 call mpi_world%barrier()
963
964 ! Read the result from MatterSim
965 iunit = io_open('ml_forces.xyz', global_namespace, action='read')
966 read(iunit, *) g_opt%hm%energy%total
967 do iatom = 1, g_opt%ions%natoms
968 read(iunit,*) g_opt%ions%tot_force(:, iatom)
969 end do
970 read(iunit, *) ! skip comment line
971 if (bitand(g_opt%type, go_cell) /= 0 .or. bitand(g_opt%type, go_volume) /= 0) then
972 do idir = 1, 3
973 read(iunit,*) g_opt%syst%st%stress_tensors%total(:, idir)
974 end do
975 end if
976 call io_close(iunit)
977
978 end select
979
980 ! Convert stress into cell force
981 ! This is the Parrinello-Rahman equation of motion of the cell,
982 ! see Parrinello and Rahman, J. Appl. Pys. 52, 7182 (1981), Eq. 2.10.
983 ! Here we use a slightly different definition, in which we evolve the right stretch tensor
984 ! instead of h, because this is a symmetric matrix.
985 ! The deformation tensor is defined as F = (1+\epsilon) = h h_0^{-1},
986 ! where \epsilon is the infinitesimal strain tensor
987 ! Using the polar decomposition F = R U, we can request to have \ddot{U} that remains symmetric
988 ! in order to kill all the rotation
989 if (bitand(g_opt%type, go_cell) /= 0) then
990 stress = -g_opt%syst%st%stress_tensors%total(1:g_opt%periodic_dim, 1:g_opt%periodic_dim)
991
992 ! Replace \sigma = sym(R^T \sigma R)
993 ! We first compute R from the right polar decomposition R = F U^-1
994 strain = matmul(g_opt%ions%latt%rlattice(1:g_opt%periodic_dim,1:g_opt%periodic_dim), g_opt%inv_initial_rlattice)
995 right_stretch = lalg_remove_rotation(g_opt%periodic_dim, strain)
996 inv_right_stretch = right_stretch
997 call lalg_inverse(g_opt%periodic_dim, inv_right_stretch, 'dir')
998 rotation = matmul(strain, inv_right_stretch)
999 ! In some cases, R can contain a reflection. To guarantee that U is SPD, we multiply by the determinant of R
1000 det = lalg_determinant(g_opt%periodic_dim, rotation, preserve_mat=.true.)
1001
1002 ! Compute the symmetrized stress
1003 sym_stress = matmul(transpose(rotation), matmul(stress, rotation))
1004 sym_stress = m_half*(sym_stress + transpose(sym_stress)) * det
1005
1006 ! The external hydrostatic pressure enters as a full -P on each diagonal component of the
1007 ! stress, such that at equilibrium the internal stress balances the pressure (\sigma = -P I).
1008 do idir = 1, g_opt%periodic_dim
1009 sym_stress(idir, idir) = sym_stress(idir, idir) - g_opt%pressure
1010 end do
1011 g_opt%cell_force = sym_stress * g_opt%ions%latt%rcell_volume
1012
1013 g_opt%cell_force = matmul(g_opt%cell_force, inv_right_stretch)
1014 ! The cell force is the gradient with respect to the symmetric right stretch tensor U,
1015 ! so we symmetrize it.
1016 g_opt%cell_force = m_half*(g_opt%cell_force + transpose(g_opt%cell_force))
1017 end if
1018
1019 ! Convert stress into cell force
1020 if (bitand(g_opt%type, go_volume) /= 0) then
1021 stress = g_opt%syst%st%stress_tensors%total(1:g_opt%periodic_dim, 1:g_opt%periodic_dim)
1022 do idir = 1, g_opt%periodic_dim
1023 g_opt%cell_force(idir, 1) = -(g_opt%pressure + stress(idir, idir)) * g_opt%ions%latt%rcell_volume
1024 end do
1025 end if
1026
1027 if (bitand(g_opt%type, go_cell) /= 0 .or. bitand(g_opt%type, go_volume) /= 0) then
1028 write(message(1),'(a,3a,a)') ' Stress tensor [', trim(units_abbrev(units_out%length)), ']'
1029 do idir = 1, g_opt%periodic_dim
1030 write(message(1+idir),'(9e18.10)') (units_from_atomic(units_out%length, g_opt%syst%st%stress_tensors%total(jdir, idir)), &
1031 jdir = 1, g_opt%periodic_dim)
1032 end do
1033 call messages_info(1+g_opt%periodic_dim, namespace=g_opt%ions%namespace, debug_only=.true.)
1034 write(message(1),'(a,3a,a)') ' Cell force tensor [', trim(units_abbrev(units_out%length)), ']'
1035 do idir = 1, ubound(g_opt%cell_force, 2)
1036 write(message(1+idir),'(9e18.10)') (units_from_atomic(units_out%length, g_opt%cell_force(jdir, idir)), &
1037 jdir = 1, g_opt%periodic_dim)
1038 end do
1039 call messages_info(1+g_opt%periodic_dim, namespace=g_opt%ions%namespace, debug_only=.true.)
1040 end if
1041
1042
1043 ! store results
1044 if (getgrad == 1) call to_grad(g_opt, df)
1045
1046 if (g_opt%what2minimize == minwhat_forces) then
1047 objective = m_zero
1048 do iatom = 1, g_opt%ions%natoms
1049 if (g_opt%ions%fixed(iatom)) cycle
1050 objective = objective + sum(g_opt%ions%tot_force(:, iatom)**2)
1051 end do
1052 if (bitand(g_opt%type, go_cell) /= 0) then
1053 do idir = 1, g_opt%periodic_dim
1054 objective = objective + sum(g_opt%cell_force(:, idir)**2)
1055 end do
1056 end if
1057 if (bitand(g_opt%type, go_volume) /= 0) then
1058 objective = objective + sum(g_opt%cell_force(:,1)**2)
1059 end if
1060 objective = sqrt(objective)
1061 else
1062 objective = g_opt%hm%energy%total
1063 end if
1064
1065 pop_sub(calc_point)
1066 end subroutine calc_point
1067
1068
1069 ! ---------------------------------------------------------
1074 subroutine calc_point_ng(size, coords, objective)
1075 integer :: size
1076 real(real64) :: coords(size)
1077 real(real64) :: objective
1078
1079 integer :: getgrad
1080 real(real64), allocatable :: df(:)
1081
1082 push_sub(calc_point_ng)
1083
1084 assert(size == g_opt%size)
1085
1086 getgrad = 0
1087 safe_allocate(df(1:size))
1088 df = m_zero
1089
1090 call calc_point(size, coords, objective, getgrad, df)
1091 safe_deallocate_a(df)
1092
1093 pop_sub(calc_point_ng)
1094 end subroutine calc_point_ng
1095
1096
1097 ! ---------------------------------------------------------
1099 subroutine write_iter_info(geom_iter, size, energy, maxdx, maxdf, coords)
1100 integer, intent(in) :: geom_iter
1101 integer, intent(in) :: size
1102 real(real64), intent(in) :: energy, maxdx, maxdf
1103 real(real64), intent(in) :: coords(size)
1104
1105 character(len=256) :: c_geom_iter, title, c_forces_iter
1106 integer :: iunit
1107
1108 push_sub(write_iter_info)
1109
1110 write(c_geom_iter, '(a,i4.4)') "go.", geom_iter
1111 write(title, '(f16.10,2x,a)') units_from_atomic(units_out%energy, energy), trim(units_abbrev(units_out%energy))
1112 call g_opt%ions%write_xyz('geom/'//trim(c_geom_iter), comment = trim(title))
1113 call g_opt%ions%write_xyz('./last')
1114
1115 if(g_opt%periodic_dim > 0) then
1116 call g_opt%ions%write_xyz('geom/'//trim(c_geom_iter), comment = 'Reduced coordinates', reduce_coordinates = .true.)
1117 call write_xsf_geometry_file('geom', trim(c_geom_iter), g_opt%ions%space, g_opt%ions%latt, &
1118 g_opt%ions%pos, g_opt%ions%atom, g_opt%syst%gr, g_opt%ions%grp, g_opt%syst%namespace)
1119 end if
1120
1121 if (g_opt%syst%outp%what(option__output__forces)) then
1122 write(c_forces_iter, '(a,i4.4)') "forces.", geom_iter
1123 if (bitand(g_opt%syst%outp%how(option__output__forces), option__outputformat__bild) /= 0) then
1124 call g_opt%ions%write_bild_forces_file('forces', trim(c_forces_iter))
1125 else
1126 call write_xsf_geometry_file('forces', trim(c_forces_iter), g_opt%ions%space, g_opt%ions%latt, &
1127 g_opt%ions%pos, g_opt%ions%atom, g_opt%syst%gr, g_opt%ions%grp, g_opt%syst%namespace, &
1128 total_forces=g_opt%ions%tot_force)
1129 end if
1130 end if
1131
1132 if (g_opt%ions%grp%is_root()) then
1133 iunit = io_open(trim('geom/optimization.log'), g_opt%syst%namespace, &
1134 action = 'write', position = 'append')
1135
1136 if (geom_iter == 1) then
1137 if (bitand(g_opt%type, go_cell) /= 0) then
1138 write(iunit, '(a10,5(5x,a20),a)') '# iter','energy [' // trim(units_abbrev(units_out%energy)) // ']', &
1139 'max_force [' // trim(units_abbrev(units_out%force)) // ']',&
1140 ' max_dr [' // trim(units_abbrev(units_out%length)) // ']', &
1141 ' a, b, c ['// trim(units_abbrev(units_out%length)) // ']', &
1142 ' volume ['// trim(units_abbrev(units_out%length**3)) // ']',&
1143 ' alpha, beta, gamma [degrees]'
1144 else
1145 write(iunit, '(a10,3(5x,a20))') '# iter','energy [' // trim(units_abbrev(units_out%energy)) // ']', &
1146 'max_force [' // trim(units_abbrev(units_out%force)) // ']',&
1147 ' max_dr [' // trim(units_abbrev(units_out%length)) // ']'
1148 end if
1149 end if
1150
1151 if (bitand(g_opt%type, go_cell) /= 0) then
1152 write(iunit, '(i10,10f25.15)') geom_iter, units_from_atomic(units_out%energy, energy), &
1153 units_from_atomic(units_out%force,maxdf), &
1154 units_from_atomic(units_out%length,maxdx), &
1155 units_from_atomic(units_out%length,norm2(g_opt%ions%latt%rlattice(1:3, 1))),&
1156 units_from_atomic(units_out%length,norm2(g_opt%ions%latt%rlattice(1:3, 2))),&
1157 units_from_atomic(units_out%length,norm2(g_opt%ions%latt%rlattice(1:3, 3))),&
1158 units_from_atomic(units_out%length**3, g_opt%ions%latt%rcell_volume), &
1159 g_opt%ions%latt%alpha, g_opt%ions%latt%beta, g_opt%ions%latt%gamma
1160 else
1161 write(iunit, '(i10,3f25.15)') geom_iter, units_from_atomic(units_out%energy, energy), &
1162 units_from_atomic(units_out%force,maxdf), &
1163 units_from_atomic(units_out%length,maxdx)
1164 end if
1165
1166 call io_close(iunit)
1167 end if
1168
1169 call messages_new_line()
1170 call messages_new_line()
1171
1172 call messages_write("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++", new_line = .true.)
1173
1174 call messages_write("+++++++++++++++++++++ MINIMIZATION ITER #:")
1175 call messages_write(geom_iter, fmt = "I5")
1176 call messages_write(" ++++++++++++++++++++++", new_line = .true.)
1177
1178 call messages_write(" Energy = ")
1179 call messages_write(energy, units = units_out%energy, fmt = "es15.8,1x", print_units = .true., new_line = .true.)
1180
1181 if (g_opt%periodic_dim == 0) then
1182 if (maxdf > m_zero) then
1183 call messages_write(" Max force = ")
1184 call messages_write(maxdf, units = units_out%force, fmt = "f18.10,1x", print_units = .true., new_line = .true.)
1185 end if
1186
1187 call messages_write(" Max dr = ")
1188 call messages_write(maxdx, units = units_out%length, fmt = "f18.10,1x", print_units = .true., new_line = .true.)
1189 else
1190 if (maxdf > m_zero) then
1191 call messages_write(" Max reduced force = ")
1192 call messages_write(maxdf, fmt = "f16.10,1x", print_units = .false., new_line = .true.)
1193 end if
1194
1195 call messages_write(" Max reduced dr = ")
1196 call messages_write(maxdx, fmt = "f16.10,1x", print_units = .false., new_line = .true.)
1197 end if
1198
1199 call messages_write("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++", new_line = .true.)
1200 call messages_write("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++", new_line = .true.)
1201 call messages_new_line()
1202 call messages_new_line()
1203 call messages_info()
1204
1205 pop_sub(write_iter_info)
1206 end subroutine write_iter_info
1207
1208 ! ---------------------------------------------------------
1210 subroutine to_coords(gopt, coords)
1211 type(geom_opt_t), intent(in) :: gopt
1212 real(real64), contiguous, intent(out) :: coords(:)
1213
1214 integer :: iatom, idir, jdir, icoord
1215 real(real64) :: tmp_pos(gopt%dim), strain(g_opt%periodic_dim,g_opt%periodic_dim)
1216
1217 push_sub(to_coords)
1218
1219 icoord = 1
1220 ! Ion dynamics
1221 if (bitand(g_opt%type, go_ions) /= 0) then
1222 do iatom = 1, gopt%ions%natoms
1223 if (gopt%fixed_atom == iatom) cycle
1224 if (gopt%ions%fixed(iatom)) cycle
1225 tmp_pos = gopt%ions%pos(1:gopt%dim, iatom)
1226 if (gopt%fixed_atom > 0) tmp_pos = tmp_pos - gopt%ions%pos(1:gopt%dim, gopt%fixed_atom)
1227 tmp_pos = gopt%ions%latt%cart_to_red(tmp_pos)
1228 do idir = 1, gopt%dim
1229 coords(icoord) = tmp_pos(idir)
1230 icoord = icoord + 1
1231 end do
1232 end do
1233 end if
1234
1235 ! Cell dynamics
1236 if (bitand(g_opt%type, go_cell) /= 0) then
1237 ! We compute the change in the right stretch tensor U, defined as h = U h_0.
1238 ! Only the periodic block of the lattice is relaxed; the non-periodic (e.g. vacuum)
1239 ! direction is left untouched, which is essential for 2D systems.
1240 strain = matmul(gopt%ions%latt%rlattice(1:g_opt%periodic_dim, 1:g_opt%periodic_dim), g_opt%inv_initial_rlattice)
1241 do idir = 1, g_opt%periodic_dim
1242 do jdir = idir, g_opt%periodic_dim
1243 coords(icoord) = strain(idir, jdir)
1244 icoord = icoord + 1
1245 end do
1246 end do
1247 end if
1248
1249 ! Volume dynamics
1250 if (bitand(g_opt%type, go_volume) /= 0) then
1251 do idir = 1, g_opt%periodic_dim
1252 coords(icoord) = norm2(gopt%ions%latt%rlattice(1:g_opt%periodic_dim, idir))/g_opt%initial_length(idir)
1253 icoord = icoord + 1
1254 end do
1255 end if
1256
1257
1258 pop_sub(to_coords)
1259 end subroutine to_coords
1260
1261 ! ---------------------------------------------------------
1263 subroutine to_grad(gopt, grad)
1264 type(geom_opt_t), intent(in) :: gopt
1265 real(real64), contiguous, intent(out) :: grad(:)
1266
1267 integer :: iatom, idir, jdir, icoord
1268 real(real64) :: tmp_force(1:gopt%dim)
1269
1270 push_sub(to_grad)
1271
1272 icoord = 1
1273 ! Ion dynamics
1274 if (bitand(g_opt%type, go_ions) /= 0) then
1275 do iatom = 1, gopt%ions%natoms
1276 if (gopt%fixed_atom == iatom) cycle
1277 if (gopt%ions%fixed(iatom)) cycle
1278 do idir = 1, gopt%dim
1279 if (abs(gopt%ions%atom(iatom)%c(idir)) <= m_epsilon) then
1280 tmp_force(idir) = -gopt%ions%tot_force(idir, iatom)
1281 else
1282 tmp_force(idir) = m_zero
1283 end if
1284 if (gopt%fixed_atom > 0) then
1285 tmp_force(idir) = tmp_force(idir) + gopt%ions%tot_force(idir, gopt%fixed_atom)
1286 end if
1287 end do
1288 tmp_force = gopt%ions%latt%cart_to_red(tmp_force)
1289 do idir = 1, gopt%dim
1290 grad(icoord) = tmp_force(idir)
1291 icoord = icoord + 1
1292 end do
1293 end do
1294 end if
1295
1296 ! Cell dynamics
1297 if (bitand(g_opt%type, go_cell) /= 0) then
1298 do idir = 1, g_opt%periodic_dim
1299 do jdir = idir, g_opt%periodic_dim
1300 grad(icoord) = -g_opt%cell_force(idir, jdir)
1301 icoord = icoord + 1
1302 end do
1303 end do
1304 end if
1305
1306 ! Volume dynamics
1307 if (bitand(g_opt%type, go_volume) /= 0) then
1308 do idir = 1, g_opt%periodic_dim
1309 grad(icoord) = -g_opt%cell_force(idir, 1)
1310 icoord = icoord + 1
1311 end do
1312 end if
1313
1314
1315 pop_sub(to_grad)
1316 end subroutine to_grad
1317
1318 ! ---------------------------------------------------------
1320 subroutine from_coords(gopt, coords)
1321 type(geom_opt_t), intent(inout) :: gopt
1322 real(real64), contiguous, intent(in) :: coords(:)
1323
1324 integer :: iatom, idir, jdir, icoord
1325 real(real64) :: tmp_pos(gopt%dim, gopt%ions%natoms), strain(g_opt%periodic_dim,g_opt%periodic_dim)
1326 real(real64) :: eigenvalues(g_opt%periodic_dim)
1327
1328 push_sub(from_coords)
1329
1330 ! Get the new reduced atomic coordinates
1331 tmp_pos = m_zero
1332 icoord = 1
1333 ! Ion dynamics
1334 if (bitand(g_opt%type, go_ions) /= 0) then
1335 do iatom = 1, gopt%ions%natoms
1336 if (gopt%fixed_atom == iatom) cycle
1337 if (gopt%ions%fixed(iatom)) cycle
1338 do idir = 1, gopt%dim
1339 tmp_pos(idir, iatom) = coords(icoord)
1340 icoord = icoord + 1
1341 end do
1342 end do
1343 else
1344 do iatom = 1, gopt%ions%natoms
1345 tmp_pos(:, iatom) = gopt%ions%latt%cart_to_red(gopt%ions%pos(:, iatom))
1346 end do
1347 end if
1348
1349 ! Updating the lattice vectors
1350 if (bitand(g_opt%type, go_cell) /= 0) then
1351 do idir = 1, g_opt%periodic_dim
1352 do jdir = idir, g_opt%periodic_dim
1353 strain(idir, jdir) = coords(icoord)
1354 icoord = icoord + 1
1355 end do
1356 end do
1357 call upper_triangular_to_hermitian(g_opt%periodic_dim, strain)
1358
1359 ! Get the new lattice vectors from the new right stretch tensor U
1360 ! The strain tensor is defined as A = U * A_0.
1361 ! Only the periodic block is updated; the non-periodic (e.g. vacuum) lattice
1362 ! direction is preserved, which is essential for 2D systems (otherwise the
1363 ! vacuum direction would be corrupted/collapse).
1364 gopt%ions%latt%rlattice(1:g_opt%periodic_dim, 1:g_opt%periodic_dim) = matmul(strain, g_opt%initial_rlattice)
1365
1366 ! Sanity check: the right stretch tensor U must remain symmetric positive-definite.
1367 ! Note: lalg_eigensolve overwrites strain with the eigenvectors, but strain is no longer
1368 ! needed below, so this is safe.
1369 call lalg_eigensolve(g_opt%periodic_dim, strain, eigenvalues)
1370 assert(all(eigenvalues > m_zero))
1371 end if
1372
1373 ! Updating the lattice vectors
1374 if (bitand(g_opt%type, go_volume) /= 0) then
1375 do idir = 1, g_opt%periodic_dim
1376 gopt%ions%latt%rlattice(1:g_opt%periodic_dim, idir) = coords(icoord) &
1377 * gopt%initial_rlattice(1:g_opt%periodic_dim, idir)
1378 icoord = icoord + 1
1379 end do
1380 end if
1381
1382 ! Symmetrize and update the lattice vectors
1383 if (bitand(g_opt%type, go_cell) /= 0 .or. bitand(g_opt%type, go_volume) /= 0) then
1384 call g_opt%syst%gr%symmetrizer%symmetrize_lattice_vectors(g_opt%periodic_dim, g_opt%initial_rlattice, &
1385 gopt%ions%latt%rlattice(1:g_opt%periodic_dim, 1:g_opt%periodic_dim), gopt%symmetrize)
1386 call gopt%ions%update_lattice_vectors(gopt%ions%latt, gopt%symmetrize)
1387 end if
1388
1389 ! Ion dynamics
1390 if (bitand(g_opt%type, go_ions) /= 0) then
1391 ! To Cartesian coordinates
1392 do iatom = 1, gopt%ions%natoms
1393 if (gopt%fixed_atom == iatom) cycle
1394 if (gopt%ions%fixed(iatom)) cycle
1395 tmp_pos(:, iatom) = gopt%ions%latt%red_to_cart(tmp_pos(:, iatom))
1396 do idir = 1, gopt%dim
1397 if (abs(gopt%ions%atom(iatom)%c(idir)) <= m_epsilon) then
1398 gopt%ions%pos(idir, iatom) = tmp_pos(idir, iatom)
1399 end if
1400 end do
1401 if (gopt%fixed_atom > 0) then
1402 gopt%ions%pos(:, iatom) = gopt%ions%pos(:, iatom) + gopt%ions%pos(:, gopt%fixed_atom)
1403 end if
1404 end do
1405 else
1406 do iatom = 1, gopt%ions%natoms
1407 gopt%ions%pos(:, iatom) = gopt%ions%latt%red_to_cart(tmp_pos(:, iatom))
1408 end do
1409 end if
1410
1411 if (gopt%symmetrize) then
1412 call gopt%ions%symmetrize_atomic_coord()
1413 end if
1414
1415 if (bitand(g_opt%type, go_cell) /= 0) then
1416 call gopt%ions%print_spacegroup()
1417 end if
1418
1419 pop_sub(from_coords)
1420 end subroutine from_coords
1421
1422 ! ---------------------------------------------------------
1424 subroutine write_iter_info_ng(geom_iter, size, energy, maxdx, coords)
1425 integer, intent(in) :: geom_iter
1426 integer, intent(in) :: size
1427 real(real64), intent(in) :: energy, maxdx
1428 real(real64), intent(in) :: coords(size)
1429
1430 push_sub(write_iter_info_ng)
1431 call write_iter_info(geom_iter, size, energy, maxdx, -m_one, coords)
1432
1433 pop_sub(write_iter_info_ng)
1434 end subroutine write_iter_info_ng
1435
1436
1437 ! ---------------------------------------------------------
1439 subroutine ml_preopt(g_opt)
1440 type(geom_opt_t), intent(inout) :: g_opt
1441
1442 integer :: iunit, iatom, idir, command_status, command_exit
1443 logical :: has_constrains
1444 character(len=MAX_PATH_LEN) :: cmd, mattersim_share, mattersim_python
1445 character(len=64) :: constrains_arg
1446
1447 push_sub(ml_preopt)
1448 command_status = 0
1449 command_exit = 0
1450
1451 call io_rm('ml_cell.xyz', g_opt%syst%namespace)
1452
1453 if (g_opt%ions%space%is_periodic()) then
1454 call write_extended_xyz_file('.', 'work-geom', g_opt%ions%space, g_opt%ions%latt, g_opt%ions%pos, g_opt%ions%atom, &
1455 g_opt%syst%gr%box, g_opt%syst%namespace)
1456 else
1457 call g_opt%ions%write_xyz('./work-geom', append = .false.)
1458 end if
1459
1460 ! MatterSim relaxes every atom, so the fixed coordinates (GOConstrains, GOCenter
1461 ! and fixed species) have to be passed explicitly to the pre-optimizer.
1462 has_constrains = any(g_opt%ions%fixed) .or. g_opt%fixed_atom > 0
1463 do iatom = 1, g_opt%ions%natoms
1464 has_constrains = has_constrains .or. any(g_opt%ions%atom(iatom)%c /= 0)
1465 end do
1466
1467 constrains_arg = ''
1468 if (has_constrains) then
1469 constrains_arg = ' --constrains ml_constrains.dat'
1470 if (mpi_world%is_root()) then
1471 iunit = io_open('ml_constrains.dat', global_namespace, action='write')
1472 do iatom = 1, g_opt%ions%natoms
1473 if (g_opt%ions%fixed(iatom) .or. iatom == g_opt%fixed_atom) then
1474 write(iunit, '(3(1x,i1))') (1, idir = 1, g_opt%ions%space%dim)
1475 else
1476 write(iunit, '(3(1x,i1))') (g_opt%ions%atom(iatom)%c(idir), idir = 1, g_opt%ions%space%dim)
1477 end if
1478 end do
1479 call io_close(iunit)
1480 end if
1481 end if
1482
1483 call mattersim_paths(mattersim_share, mattersim_python, g_opt%syst%namespace)
1484 if (mpi_world%is_root()) then
1485 ! Execute a system call for the current geometry
1486 ! -I isolates the venv python from any external PYTHONPATH/PYTHONHOME
1487 write(cmd, '(a,1x,es24.16,1x,i0,1x,l1,a)') &
1488 trim(mattersim_python) // " -I " // trim(mattersim_share) &
1489 // "/scripts/run_mattersim_preopt.py work-geom.xyz ml_cell.xyz " // trim(mattersim_share), &
1490 g_opt%pressure, g_opt%type, g_opt%symmetrize, trim(constrains_arg)
1491 call execute_command_line(trim(cmd), exitstat=command_exit, cmdstat=command_status)
1492 if (command_status == 0) command_status = command_exit
1493 end if
1494
1495 call mpi_world%bcast(command_status, 1, mpi_integer, 0)
1496 if (command_status /= 0) then
1497 write(message(1), '(a,i0)') 'MatterSim pre-optimization failed with exit status ', command_status
1498 call messages_fatal(1, namespace=g_opt%syst%namespace)
1499 end if
1500
1501 call mpi_world%barrier()
1502
1503 ! Read the result from MatterSim
1504 iunit = io_open('ml_cell.xyz', global_namespace, action='read')
1505 do iatom = 1, g_opt%ions%natoms
1506 read(iunit,*) g_opt%ions%pos(:, iatom)
1507 end do
1508 read(iunit, *) ! skip comment line
1509 if (bitand(g_opt%type, go_cell) /= 0 .or. bitand(g_opt%type, go_volume) /= 0) then
1510 do idir = 1, 3
1511 read(iunit,*) g_opt%ions%latt%rlattice(:, idir)
1512 end do
1513 end if
1514 call io_close(iunit)
1515
1516 call g_opt%ions%update_lattice_vectors(g_opt%ions%latt, g_opt%symmetrize)
1517
1518 if (debug%info) then
1519 call g_opt%ions%print_spacegroup()
1520 end if
1521
1522 call g_opt%ions%fold_atoms_into_cell()
1523
1524 ! Update lattice vectors and regenerate grid
1525 if (bitand(g_opt%type, go_cell) /= 0 .or. bitand(g_opt%type, go_volume) /= 0 ) then
1526 call electrons_lattice_vectors_update(g_opt%syst%namespace, g_opt%syst%gr, &
1527 g_opt%syst%space, g_opt%syst%hm%psolver, g_opt%syst%hm%kpoints, &
1528 g_opt%syst%mc, g_opt%syst%st%qtot, g_opt%ions%latt)
1529 end if
1530
1531 call hamiltonian_elec_epot_generate(g_opt%hm, g_opt%syst%namespace, g_opt%syst%space, g_opt%syst%gr, &
1532 g_opt%ions, g_opt%syst%ext_partners, g_opt%st)
1533
1534 call g_opt%ions%print_spacegroup()
1535
1536 pop_sub(ml_preopt)
1537 end subroutine ml_preopt
1538
1539end module geom_opt_oct_m
1540
1541!! Local Variables:
1542!! mode: f90
1543!! coding: utf-8
1544!! End:
subroutine init_(fromscratch)
Definition: geom_opt.F90:384
subroutine end_()
Definition: geom_opt.F90:906
Note that lalg_determinant and lalg_inverse are just wrappers over the same routine.
Definition: lalg_adv.F90:181
type(debug_t), save, public debug
Definition: debug.F90:133
This module implements a calculator for the density and defines related functions.
Definition: density.F90:99
subroutine, public density_calc(st, gr, density, istin, ep, vnl, phase)
Computes the density from the orbitals in st.
Definition: density.F90:832
subroutine, public energy_calc_total(namespace, space, hm, gr, st, ext_partners, iunit, full)
This subroutine calculates the total energy of the system. Basically, it adds up the KS eigenvalues,...
subroutine, public forces_set_total_to_zero(ions, force)
Definition: forces.F90:529
subroutine, public geom_opt_run(system, from_scratch)
Definition: geom_opt.F90:222
integer, parameter go_calculator_mattersim
Definition: geom_opt.F90:190
subroutine calc_point_ng(size, coords, objective)
Same as calc_point, but without the gradients. No intents here is unfortunately required because the ...
Definition: geom_opt.F90:1148
subroutine to_grad(gopt, grad)
Transfer data from the forces to the work array for the gradients (grad)
Definition: geom_opt.F90:1337
integer, parameter go_cell
Definition: geom_opt.F90:185
integer, parameter minwhat_forces
Definition: geom_opt.F90:181
subroutine write_iter_info_ng(geom_iter, size, energy, maxdx, coords)
Same as write_iter_info, but without the gradients.
Definition: geom_opt.F90:1498
subroutine ml_preopt(g_opt)
Calls a python script to do a pre-optimization based on machine-learned interatomic potential.
Definition: geom_opt.F90:1513
subroutine write_iter_info(geom_iter, size, energy, maxdx, maxdf, coords)
Output the information after each iteration of the geometry optimization.
Definition: geom_opt.F90:1173
subroutine calc_point(size, coords, objective, getgrad, df)
Note: you might think it would be better to change the arguments with '(size)' below to '(:)'....
Definition: geom_opt.F90:930
subroutine to_coords(gopt, coords)
Transfer the data from the data structures to the work array (coords)
Definition: geom_opt.F90:1284
integer, parameter go_volume
Definition: geom_opt.F90:185
subroutine from_coords(gopt, coords)
Transfer the data from the work array (coords) to the actual data structures.
Definition: geom_opt.F90:1394
subroutine geom_opt_run_legacy(sys, fromscratch)
Definition: geom_opt.F90:240
subroutine mattersim_paths(mattersim_share, mattersim_python, namespace)
Definition: geom_opt.F90:198
real(real64), parameter, public m_zero
Definition: global.F90:173
real(real64), parameter, public m_epsilon
Definition: global.F90:189
type(conf_t), public conf
Global instance of Octopus configuration.
Definition: global.F90:163
real(real64), parameter, public m_half
Definition: global.F90:179
real(real64), parameter, public m_one
Definition: global.F90:174
subroutine, public hamiltonian_elec_epot_generate(this, namespace, space, gr, ions, ext_partners, st, time)
subroutine, public write_extended_xyz_file(dir, fname, space, latt, pos, atoms, box, namespace)
Write an extended xyz file compatible with ASE.
subroutine, public write_xsf_geometry_file(dir, fname, space, latt, pos, atoms, mesh, mpi_grp, namespace, total_forces)
Definition: io.F90:93
subroutine, public io_close(iunit, grp)
Definition: io.F90:444
subroutine, public io_rm(fname, namespace)
Definition: io.F90:369
subroutine, public io_mkdir(fname, namespace, parents)
Definition: io.F90:338
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
Definition: io.F90:379
subroutine, public electrons_lattice_vectors_update(namespace, gr, space, psolver, kpoints, mc, qtot, new_latt)
subroutine, public ion_dynamics_box_update(namespace, gr, space, new_latt)
real(real64) function, dimension(1:n, 1:n), public lalg_remove_rotation(n, A)
Remove rotation from affine transformation A by computing the polar decomposition and discarding the ...
Definition: lalg_adv.F90:500
subroutine, public lcao_run(namespace, space, gr, ions, ext_partners, st, ks, hm, st_start, lmm_r, known_lower_bound)
Definition: lcao.F90:744
System information (time, memory, sysname)
Definition: loct.F90:94
subroutine, public loct_strerror(errno, res)
Definition: loct.F90:361
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:94
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:97
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1048
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:501
subroutine, public messages_obsolete_variable(namespace, name, rep)
Definition: messages.F90:980
subroutine, public messages_new_line()
Definition: messages.F90:1069
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:138
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:386
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:671
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1020
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:570
integer, parameter, public minmethod_nmsimplex
Definition: minimizer.F90:116
integer, parameter, public minmethod_fire
Definition: minimizer.F90:116
type(mpi_grp_t), public mpi_world
Definition: mpi.F90:317
This module implements the basic mulsisystem class, a container system for other systems.
type(namespace_t), public global_namespace
Definition: namespace.F90:112
logical function, public parse_is_defined(namespace, name)
Definition: parser.F90:440
/* To use the profiling module, call profiling_in and profiling_out with the label of the region as a...
Definition: profiling.F90:122
integer, parameter, public read_coords_err
for read_coords_info::file_type
subroutine, public read_coords_init(gf)
subroutine, public read_coords_end(gf)
subroutine, public read_coords_read(what, gf, space, namespace)
integer, parameter, public restart_gs
Definition: restart.F90:133
integer, parameter, public restart_type_dump
Definition: restart.F90:161
integer, parameter, public restart_type_load
Definition: restart.F90:161
subroutine, public scf_set_lower_bound_is_known(scf, known_lower_bound)
Set the flag lower_bound_is_known.
Definition: scf.F90:1689
subroutine, public scf_print_mem_use(namespace)
Definition: scf.F90:1569
subroutine, public scf_mix_clear(scf)
Definition: scf.F90:584
integer, parameter, public verb_compact
Definition: scf.F90:183
subroutine, public scf_init(scf, namespace, gr, ions, st, mc, hm, space)
Definition: scf.F90:237
subroutine, public scf_end(scf)
Definition: scf.F90:554
subroutine, public scf_run(scf, namespace, space, mc, gr, ions, ext_partners, st, ks, hm, outp, verbosity, iters_done, restart_dump)
Legacy version of the SCF code.
Definition: scf.F90:835
subroutine, public states_elec_deallocate_wfns(st)
Deallocates the KS wavefunctions defined within a states_elec_t structure.
subroutine, public states_elec_allocate_wfns(st, mesh, wfs_type, skip, packed)
Allocates the KS wavefunctions defined within a states_elec_t structure.
This module handles reading and writing restart information for the states_elec_t.
subroutine, public states_elec_load(restart, namespace, space, st, mesh, kpoints, fixed_occ, ierr, iter, lr, lowest_missing, label, verbose, skip)
returns in ierr: <0 => Fatal error, or nothing read =0 => read all wavefunctions >0 => could only rea...
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:111
character(len=20) pure function, public units_abbrev(this)
Definition: unit.F90:202
This module defines the unit system, used for input and output.
type(unit_t), public unit_femtosecond
Time in femtoseconds.
type(unit_t), public unit_amu
Mass in atomic mass units (AKA Dalton).
type(unit_system_t), public units_out
type(unit_system_t), public units_inp
the units systems for reading and writing
subroutine, public v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, calc_eigenval, time, calc_energy, calc_current, force_semilocal)
Definition: v_ks.F90:765
subroutine, public v_ks_h_setup(namespace, space, gr, ions, ext_partners, st, ks, hm, calc_eigenval, calc_current)
Definition: v_ks.F90:711
An abstract type for all electron species.
Class describing the electron system.
Definition: electrons.F90:199
Container class for lists of system_oct_m::system_t.
int true(void)