Structural and electronic properties stored in all_minima_data.npy¶

In this notebook we describe how to read and use the data stored in the jupyter dictionary all_minima_data.npy. The dictionary stores all data employed in the manuscript "Principles of isomer stability in small clusters" (https://doi.org/10.1039/D2MA01088G) by Giuseppe Fisicaro (CNR-IMM Catania, Italy - Giuseppe.Fisicaro@imm.cnr.it), Bastian Schaefer, Jonas A. Finkler, and Stefan Goedecker (Department of Physics, University of Basel, Switzerland).

Data refer to all minima (43606 different isomers) found by the Minima Hopping method. We explored the potential energy surface of 58 different neutral and charged clusters, that are:

  • Na$_n^q$ (Na$_8^{-1,0,+1}$, Na$_{10}^{-1,0,+1}$, Na$_{15}^{0,+1}$)

  • Mg$_n^q$ (Mg$_{10}^{-1,0,+1,+2}$, Mg$_{11}^{-1,0,+1,+2}$, Mg$_{14}^{-1,0,+1,+2}$, Mg$_{15}^{0,+1,+2}$)

  • Al$_n^q$ (Al$_7^{-1,0,+1,+2}$, Al$_{10}^{-1,0,+1,+2}$, Al$_{13}^{-1,0,+1,+2}$, Al$_{14}^{-1,0,+1,+2}$ Al$_{15}^{0,+1,+2}$)

  • Al$_{12}$Si$^{-1,0,+1,+2}$

  • Si$_n^q$ (Si$_{10}^{0,+1,+2}$, Si$_{15}^{0,+1,+2,+3}$, Si$_{20}^{0,+1}$)

  • Ge$_{15}^{0,+1,+2}$

We applied structure predictions driven by the Minima Hopping method at Density Functional Theory (DFT) level. All ab initio DFT calculations were performed with the BigDFT package. Computational details are reported in the main manuscript.

In [1]:
import numpy
# All cluster families
clusters = ['Na8', 'Na10', 'Na15', 'Mg10', 'Mg11', 'Mg14', 'Mg15','Al7', 'Al10', 'Al13', 'Al12Si', 'Al14', 'Al15', 'Si10', 'Si15', 'Si20','Ge15']
# All charge states for all cluster families
systems = {'Al10': ['Al10m1', 'Al10', 'Al10p1', 'Al10p2'], 'Na15': ['Na15', 'Na15p1'], 'Mg15': ['Mg15', 'Mg15p1', 'Mg15p2'],'Al13': ['Al13m1', 'Al13', 'Al13p1', 'Al13p2'], 'Al12Si': ['Al12Sim1', 'Al12Si', 'Al12Sip1', 'Al12Sip2'], 'Al14': ['Al14m1', 'Al14', 'Al14p1', 'Al14p2'], 'Al15': ['Al15', 'Al15p1', 'Al15p2'], 'Mg11': ['Mg11m1', 'Mg11', 'Mg11p1', 'Mg11p2'], 'Mg10': ['Mg10m1', 'Mg10', 'Mg10p1', 'Mg10p2'], 'Si20': ['Si20', 'Si20p1'], 'Ge15': ['Ge15', 'Ge15p1', 'Ge15p2'], 'Si15': ['Si15', 'Si15p1', 'Si15p2', 'Si15p3'], 'Mg14': ['Mg14m1', 'Mg14', 'Mg14p1', 'Mg14p2'], 'Al7': ['Al7m1', 'Al7', 'Al7p1', 'Al7p2'], 'Si10': ['Si10', 'Si10p1', 'Si10p2'], 'Na10': ['Na10m1', 'Na10', 'Na10p1'], 'Na8': ['Na8m1', 'Na8', 'Na8p1']}
# Dictionary storing all minima names. Same names as the name.xyz files for the atomic coordinates of all minima in the tar file all_minima_xyz_structures.tar.gz 
all_minima = numpy.load('all_minima_names.npy', allow_pickle=True).item()
In [2]:
# List of systems:
# Cluster name Xnq being:
#     X -> element type
#     n -> total number of atoms
#     q -> charge state as follow:
#         q = m1 -> negatively charged cluster with plus one electron
#         q = p1 -> positively charged cluster with minus one electron
#         q = p2 -> positively charged cluster with minus two electrons
#         q = p3 -> positively charged cluster with minus three electrons
for cluster in clusters:
    print(systems[cluster])
    print('')
['Na8m1', 'Na8', 'Na8p1']

['Na10m1', 'Na10', 'Na10p1']

['Na15', 'Na15p1']

['Mg10m1', 'Mg10', 'Mg10p1', 'Mg10p2']

['Mg11m1', 'Mg11', 'Mg11p1', 'Mg11p2']

['Mg14m1', 'Mg14', 'Mg14p1', 'Mg14p2']

['Mg15', 'Mg15p1', 'Mg15p2']

['Al7m1', 'Al7', 'Al7p1', 'Al7p2']

['Al10m1', 'Al10', 'Al10p1', 'Al10p2']

['Al13m1', 'Al13', 'Al13p1', 'Al13p2']

['Al12Sim1', 'Al12Si', 'Al12Sip1', 'Al12Sip2']

['Al14m1', 'Al14', 'Al14p1', 'Al14p2']

['Al15', 'Al15p1', 'Al15p2']

['Si10', 'Si10p1', 'Si10p2']

['Si15', 'Si15p1', 'Si15p2', 'Si15p3']

['Si20', 'Si20p1']

['Ge15', 'Ge15p1', 'Ge15p2']

In [3]:
# Report on the total number of isomers characterizing each potential energy surface
# for each cluster family and charge state.
print('All cluster families are:')
print(clusters)
print('')
tot_min = 0
for cluster in clusters:
    print('System: {}'.format(cluster))
    print('It has the following neutral and charged run: {}'.format(systems[cluster]))
    print('Total number of minima are:')
    tot_num_min = 0
    for key in all_minima[cluster]:
        print('{} : {}'.format(key, len(all_minima[cluster][key])))
        tot_num_min += len(all_minima[cluster][key])
    tot_min += tot_num_min
    print('Total number of minima for {} are: {}'.format(cluster,tot_num_min))
    print('')
print('Total number of minima for all systems are: {}'.format(tot_min))
All cluster families are:
['Na8', 'Na10', 'Na15', 'Mg10', 'Mg11', 'Mg14', 'Mg15', 'Al7', 'Al10', 'Al13', 'Al12Si', 'Al14', 'Al15', 'Si10', 'Si15', 'Si20', 'Ge15']

System: Na8
It has the following neutral and charged run: ['Na8m1', 'Na8', 'Na8p1']
Total number of minima are:
Na8 : 12
Na8p1 : 16
Na8m1 : 32
Total number of minima for Na8 are: 60

System: Na10
It has the following neutral and charged run: ['Na10m1', 'Na10', 'Na10p1']
Total number of minima are:
Na10m1 : 86
Na10 : 25
Na10p1 : 38
Total number of minima for Na10 are: 149

System: Na15
It has the following neutral and charged run: ['Na15', 'Na15p1']
Total number of minima are:
Na15 : 298
Na15p1 : 181
Total number of minima for Na15 are: 479

System: Mg10
It has the following neutral and charged run: ['Mg10m1', 'Mg10', 'Mg10p1', 'Mg10p2']
Total number of minima are:
Mg10m1 : 43
Mg10p1 : 105
Mg10p2 : 234
Mg10 : 56
Total number of minima for Mg10 are: 438

System: Mg11
It has the following neutral and charged run: ['Mg11m1', 'Mg11', 'Mg11p1', 'Mg11p2']
Total number of minima are:
Mg11p2 : 450
Mg11p1 : 172
Mg11m1 : 76
Mg11 : 64
Total number of minima for Mg11 are: 762

System: Mg14
It has the following neutral and charged run: ['Mg14m1', 'Mg14', 'Mg14p1', 'Mg14p2']
Total number of minima are:
Mg14p1 : 754
Mg14 : 351
Mg14p2 : 2728
Mg14m1 : 387
Total number of minima for Mg14 are: 4220

System: Mg15
It has the following neutral and charged run: ['Mg15', 'Mg15p1', 'Mg15p2']
Total number of minima are:
Mg15p1 : 510
Mg15 : 584
Mg15p2 : 1135
Total number of minima for Mg15 are: 2229

System: Al7
It has the following neutral and charged run: ['Al7m1', 'Al7', 'Al7p1', 'Al7p2']
Total number of minima are:
Al7 : 15
Al7m1 : 10
Al7p1 : 19
Al7p2 : 67
Total number of minima for Al7 are: 111

System: Al10
It has the following neutral and charged run: ['Al10m1', 'Al10', 'Al10p1', 'Al10p2']
Total number of minima are:
Al10 : 49
Al10p2 : 204
Al10p1 : 81
Al10m1 : 77
Total number of minima for Al10 are: 411

System: Al13
It has the following neutral and charged run: ['Al13m1', 'Al13', 'Al13p1', 'Al13p2']
Total number of minima are:
Al13p1 : 241
Al13 : 312
Al13p2 : 894
Al13m1 : 321
Total number of minima for Al13 are: 1768

System: Al12Si
It has the following neutral and charged run: ['Al12Sim1', 'Al12Si', 'Al12Sip1', 'Al12Sip2']
Total number of minima are:
Al12Sim1 : 2999
Al12Sip2 : 5442
Al12Sip1 : 2920
Al12Si : 5060
Total number of minima for Al12Si are: 16421

System: Al14
It has the following neutral and charged run: ['Al14m1', 'Al14', 'Al14p1', 'Al14p2']
Total number of minima are:
Al14m1 : 824
Al14p2 : 1251
Al14 : 495
Al14p1 : 610
Total number of minima for Al14 are: 3180

System: Al15
It has the following neutral and charged run: ['Al15', 'Al15p1', 'Al15p2']
Total number of minima are:
Al15 : 730
Al15p1 : 617
Al15p2 : 586
Total number of minima for Al15 are: 1933

System: Si10
It has the following neutral and charged run: ['Si10', 'Si10p1', 'Si10p2']
Total number of minima are:
Si10p2 : 127
Si10p1 : 246
Si10 : 215
Total number of minima for Si10 are: 588

System: Si15
It has the following neutral and charged run: ['Si15', 'Si15p1', 'Si15p2', 'Si15p3']
Total number of minima are:
Si15p1 : 831
Si15 : 1399
Si15p3 : 770
Si15p2 : 1380
Total number of minima for Si15 are: 4380

System: Si20
It has the following neutral and charged run: ['Si20', 'Si20p1']
Total number of minima are:
Si20p1 : 783
Si20 : 3560
Total number of minima for Si20 are: 4343

System: Ge15
It has the following neutral and charged run: ['Ge15', 'Ge15p1', 'Ge15p2']
Total number of minima are:
Ge15p1 : 601
Ge15 : 888
Ge15p2 : 645
Total number of minima for Ge15 are: 2134

Total number of minima for all systems are: 43606

The following jupyter dictionary stores all data of all local minima:

In [4]:
all_minima_data = numpy.load('all_minima_data.npy',encoding="latin1", allow_pickle=True).item()

Data in all_minima_data dictionary are stored as follow:

In [ ]:
#  ----   NOT RUN THIS CELL   ---
# IT PURPOSE IS TO EXPLAIN THE all_minima_data.npy dictionary!!!

# This loop runs over all clusters
for cluster in clusters:
    
    # This loop runs over all charge states of the cluster
    for charge in systems[cluster]:
        
        # This loop runs over all minima found by the structure prediction algorithm
        # in increasing order of energy, that is all_minima[0] is the global minimum,
        # for a given cluster in a given charge state,
        for minima in all_minima[cluster][charge]:
            
            # float: Final Kohn–Sham (KS) energy [Ha] at Density Functional Theory level of the optimized minima
            all_minima_data[cluster][charge][minima]['KS-Final-energy']
            
            # dictionary: all single KS energy contributions [Ha] from BigDFT output
            # that are Ekin, EXC Epot, Enl, Eion, EvXC, EH
            all_minima_data[cluster][charge][minima]['KS-energy-contributions']
            
            # 2dim turple: (average coordination, average distance from the coordinated atoms [\AA])
            all_minima_data[cluster][charge][minima]['Coordination']
            
            # 2dim turple: (energy with respect to the global minimum [Ha], fingerprint distance from the global minimum)
            all_minima_data[cluster][charge][minima]['Fingerprint-distance-GM']
            
            # 2dim turple: (eccentricity e (not used in the main manuscript) from the tensor moment of inertia, 3dim list with eigenvalues w_i from the tensor moment of inertia)
            # definition: e = 1.0 - min_{i=1,2,3}(w_i)/e_{ave} being w_i the eigenvalues of the moment of inertia tensor and
            # e_{ave} the average value of the three w_i eigenvalues.
            all_minima_data[cluster][charge][minima]['Eccentricity']

            # 3dim turple: (surface, volume, Surface/volume ratio) calculated from a soft-spheres cavity following the cavity recipe employed in implicit solvation calculations [see Fisicato et al J. Chem. Theory Comput. 2017, 13, 3829-3845] 
            # used a discretization of 0.4 for the three-dimensional mesh.
            all_minima_data[cluster][charge][minima]['Soft-spheres-cavity']
            
            # float: Fermi level [Ha]
            all_minima_data[cluster][charge][minima]['Fermi-level']
            
            # float: Homo-Lumo gap [eV]
            all_minima_data[cluster][charge][minima]['Homo-Lumo-gap']
            
            # 2dim list: [Homo, Lumo] [Ha]
            all_minima_data[cluster][charge][minima]['Homo-Lumo']
            
            # float: Electric dipole [Debye]
            all_minima_data[cluster][charge][minima]['Dipole']
            
            # float: Adiabatic Ionization energy (AIE) [eV]
            all_minima_data[cluster][charge][minima]['Adiabatic-Ionization-energy']
            
            # float: Vertical Ionization energy (VIE) [eV]
            all_minima_data[cluster][charge][minima]['Vertical-Ionization-energy']
            
            # float: Vertical Electron Affinity (VEA) [eV]
            all_minima_data[cluster]['Vertical-Electron-Affinity'][charge][minima]
            
            # float: Chemical Hardness (CH) [eV] defined as CH = (VIE - VEA) * 0.5
            all_minima_data[cluster][charge][minima]['Chemical-Hardness']
            
            # list: KS Eigenvalue degeneracy list:
            # Two or more KS eigenvalues are considered degenerate if their difference is lower than 10$^{-4}$ Ha
            all_minima_data[cluster][charge][minima]['Eigenvalue-degeneracy']
            
            # str: Point group from get_pymatgen_pointgroup(filename,tol=0.0009)
            all_minima_data[cluster][charge][minima]['Pointgroup']
            
            # float: Magic numbers distance (old data not used in the main manuscript)
            all_minima_data[cluster][charge][minima]['Magic-numbers-distance']
            
            # float: Shape factor S, Eq. 3 main paper, using the three eigenvalues w_i from the tensor moment of inertia
            all_minima_data[cluster][charge][minima]['Shape-factor']

Following an example of the data structure for the global minimum of the negatively charged 13 atoms aluminium cluster $Al_{13}^{-1}$.

In [5]:
cluster='Al13'                      # atomic cluster, in this case 13 aluminium atoms
charge='Al13m1'                     # charge state, in this case a negatively charged cluster with plus one electron
gm = all_minima[cluster][charge][0] # name of the isomer and the related xyz file, in this case
                                    # the first isomer min0001.xyz which is the global minimum
print('structure {} of {}'.format(gm,charge))
print()
data = all_minima_data[cluster][charge][gm]
for key, value in data.items():
    print('{}: {}'.format(key,value))
structure min0001.xyz of Al13m1

KS-Final-energy: -26.672682316180612
KS-energy-contributions: {'Ekin': 10.2615186034, 'Epot': -21.9890576123, 'Enl': 5.53892229827, 'EXC': -9.76593655157, 'Eion': 109.576778592, 'EvXC': -12.6808186756, 'EH': 132.975726322}
Coordination: (6.461538461538462, 2.756180098685976)
Fingerprint-distance-GM: (0.0, 0.0)
Eccentricity: [7.480495536338339e-07, array([56.53917193, 56.53921001, 56.53926072])]
Soft-spheres-cavity: (1077.205149367351, 3033.8631505531966, 0.35506056005556236)
Fermi-level: -0.0704798069373447
Homo-Lumo-gap: 1.88213733039336
Homo-Lumo: [-0.0704798069373447, -0.00131253276386935]
Dipole: 0.002061988
Adiabatic-Ionization-energy: 3.32572943701146
Vertical-Ionization-energy: 3.567871607220811
Vertical-Electron-Affinity: -1.4665926176456832
Chemical-Hardness: 2.517232112433247
Eigenvalue-degeneracy: [1, 3, 5, 1, 3, 3, 4]
Magic-numbers-distance: 0.011859395862305888
Pointgroup: Ih
Shape-factor: -2.2322208803604582e-07
In [ ]: