|
| 1 | +#= Test Geometry Optimization on an aluminium supercell. |
| 2 | +=# |
| 3 | +using LinearAlgebra |
| 4 | +using DFTK |
| 5 | +using ASEconvert |
| 6 | +using LazyArtifacts |
| 7 | +using AtomsCalculators |
| 8 | +using Unitful |
| 9 | +using UnitfulAtomic |
| 10 | +using Random |
| 11 | +using OptimizationOptimJL |
| 12 | + |
| 13 | +using GeometryOptimization |
| 14 | + |
| 15 | + |
| 16 | +function build_al_supercell(rep=1) |
| 17 | + pseudodojo_psp = artifact"pd_nc_sr_lda_standard_0.4.1_upf/Al.upf" |
| 18 | + a = 7.65339 # true lattice constant. |
| 19 | + lattice = a * Matrix(I, 3, 3) |
| 20 | + Al = ElementPsp(:Al; psp=load_psp(pseudodojo_psp)) |
| 21 | + atoms = [Al, Al, Al, Al] |
| 22 | + positions = [[0.0, 0.0, 0.0], [0.0, 0.5, 0.5], [0.5, 0.0, 0.5], [0.5, 0.5, 0.0]] |
| 23 | + unit_cell = periodic_system(lattice, atoms, positions) |
| 24 | + |
| 25 | + # Make supercell in ASE: |
| 26 | + # We convert our lattice to the conventions used in ASE, make the supercell |
| 27 | + # and then convert back ... |
| 28 | + supercell_ase = convert_ase(unit_cell) * pytuple((rep, 1, 1)) |
| 29 | + supercell = pyconvert(AbstractSystem, supercell_ase) |
| 30 | + |
| 31 | + # Unfortunately right now the conversion to ASE drops the pseudopotential information, |
| 32 | + # so we need to reattach it: |
| 33 | + supercell = attach_psp(supercell; Al=pseudodojo_psp) |
| 34 | + return supercell |
| 35 | +end; |
| 36 | + |
| 37 | +al_supercell = build_al_supercell(1) |
| 38 | + |
| 39 | +# Create a simple calculator for the model. |
| 40 | +model_kwargs = (; functionals = [:lda_x, :lda_c_pw], temperature = 1e-4) |
| 41 | +basis_kwargs = (; kgrid = [6, 6, 6], Ecut = 30.0) |
| 42 | +scf_kwargs = (; tol = 1e-6) |
| 43 | +calculator = DFTKCalculator(al_supercell; model_kwargs, basis_kwargs, scf_kwargs, verbose=true) |
| 44 | + |
| 45 | +energy_true = AtomsCalculators.potential_energy(al_supercell, calculator) |
| 46 | + |
| 47 | +# Starting position is a random perturbation of the equilibrium one. |
| 48 | +Random.seed!(1234) |
| 49 | +x0 = vcat(position(al_supercell)...) |
| 50 | +σ = 0.5u"angstrom"; x0_pert = x0 + σ * rand(Float64, size(x0)) |
| 51 | +al_supercell = update_not_clamped_positions(al_supercell, x0_pert) |
| 52 | +energy_pert = AtomsCalculators.potential_energy(al_supercell, calculator) |
| 53 | + |
| 54 | +println("Initial guess distance (norm) from true parameters $(norm(x0 - x0_pert)).") |
| 55 | +println("Initial regret $(energy_pert - energy_true).") |
| 56 | + |
| 57 | +optim_options = (f_tol=1e-6, iterations=6, show_trace=true) |
| 58 | + |
| 59 | +results = minimize_energy!(al_supercell, calculator; optim_options...) |
| 60 | +println(results) |
0 commit comments