├── .gitignore ├── INSTALL.txt ├── LICENSE.txt ├── MANIFEST.in ├── README.txt ├── aradi.notes.txt ├── bin ├── check_dftblog ├── dftbutils ├── skpar ├── skpar_addrepulsive └── skpar_splinerepfit ├── contributors.txt ├── docs ├── Makefile ├── make.bat └── source │ ├── _static │ ├── bs_2_0-0.png │ ├── fakebands.png │ ├── fakebandsplot_0-0.png │ ├── optimisation.flowchart.png │ ├── polyfit1_0-0.png │ ├── skpar.diagram--development.png │ ├── skpar.diagram.png │ └── test_optimise_poly3.png │ ├── about.rst │ ├── commands.rst │ ├── conf.py │ ├── contributors.rst │ ├── develop.rst │ ├── index.rst │ ├── install.rst │ ├── license.rst │ ├── modules.rst │ ├── reference.config.rst │ ├── reference.executables.rst │ ├── reference.objectives.rst │ ├── reference.optimisation.rst │ ├── reference.rst │ ├── reference.tasks.rst │ ├── skpar.core.rst │ ├── skpar.dftbutils.rst │ └── tutorials │ └── tutorials.rst ├── examples ├── C.dia │ ├── 2018-08-28 │ │ ├── freeatoms │ │ │ ├── skdef.hsd │ │ │ └── skgen-freeatoms.sh │ │ ├── skpar_in.yaml │ │ └── template │ │ │ ├── C.dia │ │ │ └── hydrostatic-0.00 │ │ │ │ ├── bs │ │ │ │ └── dftb_in.hsd │ │ │ │ ├── primcell.gen │ │ │ │ └── scc │ │ │ │ └── dftb_in.hsd │ │ │ └── skf │ │ │ └── skdef.template.hsd │ └── ref │ │ └── unpolarised │ │ └── strains │ │ └── hydrostatic_strain_0.000 │ │ ├── INCAR │ │ ├── INCAR-MESH │ │ ├── KPOINTS │ │ ├── KPOINTS-MESH │ │ ├── POSCAR │ │ ├── bands.dat │ │ ├── dos.dat │ │ └── geometry.xyz ├── MoS2-repfit │ ├── refdata │ │ └── toten-MoS2.ml.dat │ ├── skpar.in.yaml │ └── template │ │ ├── MoS2.ml-evol │ │ ├── 100 │ │ │ ├── POS.gen │ │ │ ├── charges.bin │ │ │ └── dftb_in.hsd │ │ ├── 101 │ │ │ ├── POS.gen │ │ │ ├── charges.bin │ │ │ └── dftb_in.hsd │ │ ├── 102 │ │ │ ├── POS.gen │ │ │ ├── charges.bin │ │ │ └── dftb_in.hsd │ │ ├── 103 │ │ │ ├── POS.gen │ │ │ ├── charges.bin │ │ │ └── dftb_in.hsd │ │ ├── 104 │ │ │ ├── POS.gen │ │ │ ├── charges.bin │ │ │ └── dftb_in.hsd │ │ ├── 105 │ │ │ ├── POS.gen │ │ │ ├── charges.bin │ │ │ └── dftb_in.hsd │ │ ├── 106 │ │ │ ├── POS.gen │ │ │ ├── charges.bin │ │ │ └── dftb_in.hsd │ │ ├── 107 │ │ │ ├── POS.gen │ │ │ ├── charges.bin │ │ │ └── dftb_in.hsd │ │ ├── 108 │ │ │ ├── POS.gen │ │ │ ├── charges.bin │ │ │ └── dftb_in.hsd │ │ ├── 109 │ │ │ ├── POS.gen │ │ │ ├── charges.bin │ │ │ └── dftb_in.hsd │ │ ├── 095 │ │ │ ├── POS.gen │ │ │ ├── charges.bin │ │ │ └── dftb_in.hsd │ │ ├── 096 │ │ │ ├── POS.gen │ │ │ ├── charges.bin │ │ │ └── dftb_in.hsd │ │ ├── 097 │ │ │ ├── POS.gen │ │ │ ├── charges.bin │ │ │ └── dftb_in.hsd │ │ ├── 098 │ │ │ ├── POS.gen │ │ │ ├── charges.bin │ │ │ └── dftb_in.hsd │ │ ├── 099 │ │ │ ├── POS.gen │ │ │ ├── charges.bin │ │ │ └── dftb_in.hsd │ │ ├── common.hsd │ │ └── dftb_in.hsd │ │ └── skf │ │ ├── Mo-Mo.skf │ │ ├── Mo-S.skf │ │ ├── Mo-S.template.skf │ │ ├── S-Mo.skf │ │ ├── S-Mo.template.skf │ │ ├── S-S.skf │ │ └── fitpoints.template.dat ├── Si-1 │ ├── Si-diam │ │ ├── bs │ │ │ └── dftb_in.hsd │ │ ├── primcell.gen │ │ └── scc │ │ │ └── dftb_in.hsd │ ├── ref │ │ ├── Ek-Si--SOC.dat │ │ ├── Ek-Si.dat │ │ ├── meff-Si--SOC.dat │ │ ├── meff-Si.dat │ │ └── volen-Si.dat │ ├── skf │ │ ├── skdefs.freeatoms.py │ │ ├── skdefs.template.py │ │ ├── skgen-freeatoms.sh │ │ └── skgen-opt.sh │ └── skpar_in.yaml └── Si-2 │ ├── ref │ ├── Ek-Si--SOC.dat │ ├── Ek-Si.dat │ ├── meff-Si--SOC.dat │ ├── meff-Si.dat │ └── volen-Si.dat │ ├── skpar_in.yaml │ ├── skpar_in_withmeff.yaml │ ├── skpar_in_withplots.yaml │ └── template │ ├── Si-diam │ └── 100 │ │ ├── bs │ │ └── dftb_in.hsd │ │ ├── primcell.gen │ │ └── scc │ │ └── dftb_in.hsd │ └── skf │ ├── skdefs.freeatoms.py │ ├── skdefs.template.py │ ├── skgen-freeatoms.sh │ └── skgen-opt.sh ├── setup.cfg ├── setup.py ├── skpar ├── __init__.py ├── core │ ├── __init__.py │ ├── database.py │ ├── evaluate.py │ ├── input.py │ ├── notes.rst │ ├── objectives.py │ ├── optimise.py │ ├── parameters.py │ ├── plot.py │ ├── pscan.py │ ├── pso.py │ ├── skpar.py │ ├── taskdict.py │ ├── tasks.py │ ├── usertasks.py │ └── utils.py └── dftbutils │ ├── __init__.py │ ├── bandstructure.py │ ├── evol.py │ ├── lattice.py │ ├── plot.py │ ├── queryDFTB.py │ ├── querykLines.py │ ├── repfit.py │ ├── taskdict.py │ └── utils.py └── test ├── __init__.py ├── example-tasks.yaml ├── examplt-balint.yaml ├── reference_data ├── Ek-Si.dat ├── fakebands-2.dat ├── fakebands-2.pdf ├── fakebands-2.png ├── fakebands.dat ├── fakebands.pdf ├── fakebands.png ├── meff-Si.dat ├── refdata_example.dat └── volen-Si.dat ├── sandbox_fargs.py ├── sandbox_subprocess.py ├── skpar_in_Si.yaml ├── skpar_in_optimise.yaml ├── skpar_in_optimise_and_plot.yaml ├── skpar_in_pscan.yaml ├── test_database.py ├── test_dftbutils.py ├── test_dftbutils ├── Si │ ├── UnitCell.gen │ ├── bs │ │ ├── bands_tot.dat │ │ ├── detailed.out │ │ ├── dftb_in.hsd │ │ └── dftb_pin.hsd │ ├── plots-bs │ │ └── bs_0_0.pdf │ └── scc │ │ ├── detailed.out │ │ ├── dftb_in.hsd │ │ └── dftb_pin.hsd ├── bs │ ├── bands_tot.dat │ ├── detailed.out │ └── dftb_pin.hsd ├── scc │ └── detailed.out ├── scc_soc │ └── detailed.out └── skf │ └── skdefs.template.py ├── test_evaluate.py ├── test_executables.py ├── test_input.json ├── test_input.py ├── test_input.yaml ├── test_lattice.py ├── test_newtasks.yaml ├── test_objectives.py ├── test_objectives.yaml ├── test_optimise.py ├── test_optimise ├── model_poly3.py └── template.parameters.dat ├── test_parameters.py ├── test_plot.py ├── test_pscan.py ├── test_pscan ├── model_poly3.py └── template.parameters.dat ├── test_pso.py ├── test_querykLines.py ├── test_tasks.py ├── test_tasks ├── fail.py └── pass.py ├── test_usertasks.py └── usermodule.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled python modules. 2 | *.pyc 3 | *__pycache__ 4 | 5 | # Setuptools distribution folder. 6 | /dist/ 7 | /build/ 8 | 9 | # Sphinx build folder 10 | /docs/build/ 11 | 12 | # Python egg metadata, regenerated from source files by setuptools. 13 | /*.egg-info 14 | /*.egg 15 | 16 | # work directories for tests and examples 17 | _workdir* 18 | _test* 19 | _example* 20 | example/*/*.log 21 | example/*/*.out 22 | example/*/*._work* 23 | 24 | # skpar logs from running tests and examples etc. 25 | docs/*.log 26 | test/*.log 27 | test/skpar*.log 28 | test/dftbutils*.log 29 | test/test_*/*.log 30 | test/test_plot/ 31 | ./*.log 32 | examples/*/*.log 33 | examples/*/nohup.out 34 | 35 | # dropbox 36 | *.DS_Store 37 | 38 | # editor swap and backup files 39 | *~ 40 | *.swp 41 | *.idea 42 | -------------------------------------------------------------------------------- /INSTALL.txt: -------------------------------------------------------------------------------- 1 | RECOMMENDED: 2 | ====================================================================== 3 | Install as user, locally: 4 | pip3 install --user skpar 5 | 6 | 7 | To uninstall: 8 | pip3 uninstall skpar 9 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | SKPAR License Agreement (MIT License) 2 | Copyright (c) 2013-2017 Stanislav Markov 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | 10 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include INSTALL.txt 2 | include LICENSE.txt 3 | include README.txt 4 | include contributors.txt 5 | graft docs 6 | graft examples 7 | graft test 8 | 9 | recursive-exclude docs/build * 10 | recursive-exclude docs/figures * 11 | recursive-exclude docs/ *.log 12 | 13 | global-exclude *.py[co] 14 | global-exclude *DS_Store 15 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | SKPAR is a software tool intended to automate the optimisation of 2 | parameters for the Density Functional Tight Binding (DFTB) theory 3 | as implemented in dftb+ (BCCMS Bremen), lodestar (The University 4 | of Hong Kong) and other computer codes. SKPAR was formerly SKOPT. 5 | 6 | Documentation: http://skpar.readthedocs.io 7 | 8 | SKPAR is under MIT licence. 9 | -------------------------------------------------------------------------------- /aradi.notes.txt: -------------------------------------------------------------------------------- 1 | * General 2 | 3 | √ * Input files contain more than 100 characters per line: shrunk 4 | 5 | √ * I would not allow for untagged module imports. We should rather allow for 6 | module renaming on import or importing specific entries from the module: 7 | 8 | usermodules: 9 | - skpar.dftbutils.taskdict 10 | - [skpar.dftbutils.taskdict, td] 11 | - [skpar.dftbutils.taskdict, [get_evol, set_whatever]] 12 | 13 | Implemented 14 | 15 | √ * Name skpar.dftbutils.taskdict is way too long! Why not just skpar.dftbutils? 16 | Implemented 17 | 18 | 19 | √ * examples/MoS2-repfit/skpar.in.yaml 20 | 21 | √ * Without tagimport: how do you know where to get 'get_evol' from?: Gone 22 | 23 | 24 | * skpar/core/database.py 25 | 26 | √ * Do you want to export update()?: not used on own currently 27 | 28 | √ * What do we need the Query object for?: used in objectives and .core.plot 29 | 30 | 31 | * skpar/core/evaluate.py 32 | 33 | √ * kwargs is never used in Evaluator(): removed 34 | 35 | √ * utopia?: desirable point, which may or may not be within achievable space 36 | 37 | √ * Are all class attributes public? Probably don't need to be, 38 | and will be refactored when style and test-coverage for the module are 39 | worked on; Currently the code is not very neat, and linter complains about 40 | too many attributes (Evaluate) and call parameters (__init__). 41 | 42 | 43 | * skpar/core/test.py 44 | 45 | √ * Why is this checked in?: removed 46 | 47 | * skpar/core/usertasks.py 48 | 49 | √ * ~/.local/share/skpar is a somewhat unfortunate choice. Also users should not 50 | put their own module into the skpar source folder! They will hopefully 51 | obtain skpar via pip and should not meddle with its folders themselves.: 52 | Not used any more 53 | 54 | √ * I am not sure, whether trying to look up the file is a good idea at 55 | all. (What about mypackage.subpackage.module.) Why not just simply try to 56 | import the module? 57 | Not done any more 58 | 59 | * bin/dftbutils 60 | 61 | √ * Calling without argument fails: fixed 62 | 63 | 64 | * Testing 65 | 66 | √ * resulst in 3 failing tests: not if run within the tests directory 67 | 68 | 69 | ----- Additional notes from conversation: 70 | 71 | √ * Database -- use or remove: use 72 | 73 | * Execute task 74 | √ - re-think the useage of kwargs[-1]; alternative is explicit: options={}: keep 75 | as is for the moment 76 | √ - refactor to use popen and ensure continuous output: using subprocess.call() 77 | is sufficient 78 | 79 | * Testing executables -- refactor binaries to only import parsers; then call 80 | the 'main' with options as though these have been parsed from the command 81 | line.: work on this on a separate branch (test-coverage) 82 | 83 | √ remove function definitions inside functions 84 | -------------------------------------------------------------------------------- /bin/check_dftblog: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ $# = 1 ] ; then 4 | logfile=$1 5 | else 6 | logfile='dftb.log' 7 | fi 8 | 9 | if [ -e ${logfile} ] ; then 10 | grep -A 10 ERROR ${logfile} > dftb.err 11 | if [ $? = 1 ] ; then 12 | stat=0 13 | else 14 | echo "DFTB+ ERRORS in ${logfile}:" 15 | cat dftb.err 16 | stat=1 17 | fi 18 | fi 19 | 20 | exit ${stat} 21 | -------------------------------------------------------------------------------- /bin/dftbutils: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import argparse 3 | from skpar.dftbutils.bandstructure import set_bands_parser 4 | from skpar.dftbutils.evol import set_evol_parser 5 | 6 | def main(): 7 | 8 | # argument parsing 9 | # ------------------------------------------------------------------- 10 | parser = argparse.ArgumentParser( 11 | description="Wrapper of DFTB+ for chaining several calculation " 12 | "in a single command" 13 | ) 14 | parser.add_argument( 15 | '-v', '--verbose', dest='verbose', default=False, action='store_true', 16 | help="Verbose console output" 17 | ) 18 | parser.add_argument( 19 | '-n', '--dry_run', dest='dry_run', default=False, action='store_true', 20 | help="Do not run; Only report the setup, i.e. tasklist." 21 | ) 22 | subparsers = parser.add_subparsers(title="Available sub-commands:", 23 | dest='command', 24 | help="") 25 | 26 | # Band-structure calculation 27 | parser_bands = subparsers.add_parser('bands', 28 | parents=[], help='Calculate bandstructure') 29 | set_bands_parser(parser_bands) 30 | 31 | # Energy-volume scan 32 | parser_evol = subparsers.add_parser('evol', 33 | parents=[], help='Do energy-volume scan in a given directory') 34 | set_evol_parser(parser_evol) 35 | 36 | args = parser.parse_args() 37 | # this is sub-optimal as we call parse_args twice... 38 | if args.command: 39 | args.func(args) 40 | else: 41 | args = parser.parse_args(['-h']) 42 | 43 | # func is set in the appropriate subparser 44 | 45 | if __name__ == "__main__": 46 | main() 47 | -------------------------------------------------------------------------------- /bin/skpar: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import argparse 4 | from skpar.core.skpar import SKPAR 5 | 6 | 7 | def main(): 8 | 9 | # argument parsing at start 10 | # ------------------------------------------------------------------- 11 | parser = argparse.ArgumentParser( 12 | description="Tool for optimising Slater-Koster tables for DFTB." 13 | ) 14 | parser.add_argument( 15 | "skpar_input", type=str, default="skpar_in.yaml", action="store", 16 | help="YAML or JSON input file." 17 | ) 18 | parser.add_argument( 19 | '-v', '--verbose', dest='verbose', default=False, action='store_true', 20 | help="Verbose console output (include full log as in ./skpar.debug.log)" 21 | ) 22 | parser.add_argument( 23 | '-n', '--dry_run', dest='dry_run', default=False, action='store_true', 24 | help="Do not run; Only report the setup (tasklist, objectives, optimisation)." 25 | ) 26 | parser.add_argument( 27 | '-e', '--evaluate_only', dest='evaluate_only', default=False, action='store_true', 28 | help="Do not optimise, but execute the task list and evaluate fitness." 29 | ) 30 | args = parser.parse_args() 31 | 32 | skpar = SKPAR(infile=args.skpar_input, verbose=args.verbose) 33 | 34 | if not args.dry_run: 35 | skpar(evalonly=args.evaluate_only) 36 | else: 37 | skpar.logger.warning('DRY RUN: reporting setup only!') 38 | skpar.logger.info(skpar.evaluator) 39 | 40 | 41 | if __name__ == "__main__": 42 | main() 43 | -------------------------------------------------------------------------------- /bin/skpar_addrepulsive: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import argparse 3 | from skpar.dftbutils.repfit import append_spline 4 | 5 | workdir = '.' 6 | 7 | def main(): 8 | # argument parsing 9 | # ------------------------------------------------------------------- 10 | parser = argparse.ArgumentParser( 11 | description="Script that takes an existing SK-file and a " 12 | "spline file and combines them in a new SK-file" 13 | ) 14 | parser.add_argument( 15 | '-i', dest='skin', action='store', 16 | metavar='INPUT', help="Input SK-file" 17 | ) 18 | parser.add_argument( 19 | '-o', dest='skout', action='store', 20 | metavar='OUTPUT', help="Output SK-file" 21 | ) 22 | parser.add_argument( 23 | '-s', dest='spl', default='repulsive.dat', action='store', 24 | metavar='SPLINE', 25 | help="Spline file; Must have the 'Spline' tag included on top!" 26 | ) 27 | parser.add_argument( 28 | '-e', dest='elements', nargs=2, default=None, action='store', 29 | metavar=('A1', 'A2'), 30 | help="Pair of chemical elements whose SKF is patched with a repulsive" 31 | ) 32 | args = parser.parse_args() 33 | if args.elements is not None: 34 | e1, e2 = args.elements 35 | fin1 = "{:s}-{:s}.template.skf".format(e1, e2) 36 | fout1 = "{:s}-{:s}.skf".format(e1, e2) 37 | append_spline(fin=fin1, fspl=args.spl, fout=fout1) 38 | if e1 != e2: 39 | fin2 = "{:s}-{:s}.template.skf".format(e2, e1) 40 | fout2 = "{:s}-{:s}.skf".format(e2, e1) 41 | append_spline(fin=fin2, fspl=args.spl, fout=fout2) 42 | else: 43 | append_spline(fin=args.skin, fspl=args.spl, fout=args.skout) 44 | 45 | if __name__ == '__main__': 46 | main() 47 | -------------------------------------------------------------------------------- /bin/skpar_splinerepfit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import argparse 3 | from skpar.dftbutils.repfit import splinerepfit 4 | #from skpar.dftbutils.repfit import exponentfit 5 | 6 | workdir = '.' 7 | TARGET = 'fitpoints.dat' # target points for the fit 8 | OUTPUT = 'repulsive.dat' # output file with repulsive 9 | 10 | def main(): 11 | # argument parsing 12 | # ------------------------------------------------------------------- 13 | parser = argparse.ArgumentParser( 14 | description="Take some target xy-points," 15 | "and fit a spline over them." 16 | ) 17 | parser.add_argument( 18 | '-t', '--targetpoints', dest='fpts', default=TARGET, action='store_true', 19 | help="A file describing the target for the fit." 20 | ) 21 | parser.add_argument( 22 | '-o', '--output', dest='fout', default=OUTPUT, action='store_true', 23 | help="Output file storing the definition of the fitted repulsive" 24 | ) 25 | args = parser.parse_args() 26 | 27 | splinerepfit(args.fpts, args.fout) 28 | 29 | 30 | 31 | if __name__ == '__main__': 32 | main() 33 | 34 | -------------------------------------------------------------------------------- /contributors.txt: -------------------------------------------------------------------------------- 1 | Stanislav Markov, The University of Hong Kong 2 | 3 | Bálint Aradi, University of Bremen, Germany 4 | -------------------------------------------------------------------------------- /docs/source/_static/bs_2_0-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/docs/source/_static/bs_2_0-0.png -------------------------------------------------------------------------------- /docs/source/_static/fakebands.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/docs/source/_static/fakebands.png -------------------------------------------------------------------------------- /docs/source/_static/fakebandsplot_0-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/docs/source/_static/fakebandsplot_0-0.png -------------------------------------------------------------------------------- /docs/source/_static/optimisation.flowchart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/docs/source/_static/optimisation.flowchart.png -------------------------------------------------------------------------------- /docs/source/_static/polyfit1_0-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/docs/source/_static/polyfit1_0-0.png -------------------------------------------------------------------------------- /docs/source/_static/skpar.diagram--development.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/docs/source/_static/skpar.diagram--development.png -------------------------------------------------------------------------------- /docs/source/_static/skpar.diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/docs/source/_static/skpar.diagram.png -------------------------------------------------------------------------------- /docs/source/_static/test_optimise_poly3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/docs/source/_static/test_optimise_poly3.png -------------------------------------------------------------------------------- /docs/source/commands.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: bash 2 | 3 | .. index:: commands 4 | 5 | .. _commands: 6 | 7 | ====================== 8 | Commands 9 | ====================== 10 | 11 | ``skpar`` 12 | ====================================================================== 13 | 14 | The ``skpar`` command is the primary tool for setting up and running 15 | optimisation. The typical usage is: 16 | 17 | .. code:: bash 18 | 19 | skpar skpar_in.yaml 20 | 21 | The few supported options could be obtained by: 22 | 23 | .. code:: bash 24 | 25 | skpar -h 26 | 27 | usage: skpar [-h] [-v] [-n] [-e] skpar_input 28 | 29 | Tool for optimising Slater-Koster tables for DFTB. 30 | 31 | positional arguments: 32 | skpar_input YAML input file: objectives, tasks, executables, 33 | optimisation options. 34 | 35 | optional arguments: 36 | -h, --help show this help message and exit 37 | -v, --verbose Verbose console output (include full log as in 38 | ./skpar.debug.log) 39 | -n, --dry_run Do not run; Only report the setup (tasklist, 40 | objectives, optimisation). 41 | -e, --evaluate_only Do not optimise, but execute the task list and evaluate 42 | fitness. 43 | 44 | 45 | ``dftbutils`` 46 | ====================================================================== 47 | 48 | The ``dftbutils`` command can be seen as a wrapper around several 49 | related DFTB calculations, example being a band-structure calculation. 50 | It works via subcommands, as follows: 51 | 52 | .. code:: bash 53 | 54 | dftbutils -h 55 | 56 | usage: dftbutils [-h] [-v] [-n] {bands} ... 57 | 58 | Wrapper of DFTB+ for chaining several calculation in a single command 59 | 60 | optional arguments: 61 | -h, --help show this help message and exit 62 | -v, --verbose Verbose console output 63 | -n, --dry_run Do not run; Only report the setup, i.e. tasklist. 64 | 65 | Available sub-commands:: 66 | {bands} 67 | bands Calculate bandstructure 68 | 69 | 70 | ``dftbutils bands`` 71 | ---------------------------------------------------------------------- 72 | This commands makes the calculations of a band-structure into a single 73 | execution step. It assumes that the relevant calculation on a *k*-grid, 74 | for the average density, and the following calculation along *k*-lines 75 | are setup in the ``scc`` and ``bs`` directories respectively. 76 | Currently it supports `dftb+`_ as DFTB executable, and dp_bands from 77 | `dptools`_ as the executable that yields a band-structure array. 78 | So what it does in the end is: 79 | 80 | .. code:: bash 81 | 82 | cd workdir/scc && dftb+ & cd ../ 83 | /bin/cp scc/charges.bin bs 84 | cd bs && dftb+ 85 | dp_bands band.out bands & cd ../../ 86 | 87 | Other options may be added in the future, to eliminate the implicit 88 | reliance on `dftb+` and `dp_bands`. 89 | 90 | 91 | ``dftbutils set`` 92 | ---------------------------------------------------------------------- 93 | This command should allow one to setup the relevant calculations for 94 | ``dftbutils bands``. Currently not supported. 95 | 96 | 97 | 98 | 99 | .. _`dftb+`: http://www.dftb-plus.info/ 100 | .. _`dptools`: http://dftb-plus.info/tools/dptools/ 101 | -------------------------------------------------------------------------------- /docs/source/contributors.rst: -------------------------------------------------------------------------------- 1 | .. index:: contributors 2 | 3 | .. _contributors: 4 | 5 | =============== 6 | Contributors 7 | =============== 8 | 9 | Stanislav Markov, Dept. Chemistry, The University of Hong Kong 10 | 11 | Bálint Aradi, BCCMS, University of Bremen, Germany 12 | -------------------------------------------------------------------------------- /docs/source/develop.rst: -------------------------------------------------------------------------------- 1 | .. index:: develop 2 | 3 | .. _develop: 4 | 5 | ==================== 6 | Development 7 | ==================== 8 | 9 | Further development of SKPAR is along the following lines. 10 | 11 | External Model and Reference Database 12 | ---------------------------------------------------------------------- 13 | The aims is to completely decouple the core of the optimisation 14 | engine from the application specifics. To achieve this: 15 | 16 | * the internal model database dictionary must be taken out of the core 17 | sub-package and queries must be made to address an external database; 18 | * the task handling has to be done by an external task manager, which 19 | can be application specific, and its setup may be still driven by 20 | the input YAML file of SKPAR; 21 | * an external task-manager is needed to wrap the executables that yield 22 | model data and make them store that data in the external model database; 23 | * support for reference databases should complement the current mechanism 24 | through which the declaration of objectives is realised. 25 | 26 | A conceptual block-diagram of the intended development is shown below. 27 | 28 | .. figure:: _static/skpar.diagram--development.png 29 | :width: 55% 30 | 31 | **Conceptual block diagram of SKPAR with external model database** 32 | 33 | Implementation should be straightforward, e.g. by deploying TinyDB_ or similar. 34 | 35 | .. _`TinyDB`: https://pypi.python.org/pypi/tinydb 36 | 37 | As far as task-manager is concerned, ``dftbutils bands`` already represents 38 | an example in this direction, short of putting data in a database. 39 | 40 | Parallelisation 41 | ---------------------------------------------------------------------- 42 | The calculations done within SKPAR consume negligible time in comparison to 43 | the evaluation of the model. 44 | The executables embodying the model are computationally very intense but are 45 | typically parallelised. 46 | However, much gain may be obtained by parallelising the evaluation of individuals 47 | within the population (e.g. per particle, when PSO algorithm is used). 48 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. SKPAR documentation master file, created by 2 | sphinx-quickstart on Tue Dec 27 01:30:55 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to SKPAR's documentation! 7 | ================================= 8 | 9 | SKPAR is a parameter-optimisation framework for the 10 | Density Functional Tight-Binding (DFTB) theory. 11 | 12 | .. _Python: http://www.python.org 13 | .. _`DFTB+`: http://www.dftb-plus.info/ 14 | .. _Lodestar: http://yangtze.hku.hk/new/software.php 15 | .. _dftb.org: http://www.dftb.org/home/ 16 | .. _`MIT license`: https://opensource.org/licenses/MIT 17 | 18 | 19 | News 20 | ==== 21 | 22 | * SKPAR version 0.2.0 released: September 2017 23 | 24 | - New Configuration section in input file allows for individual 25 | directory for each model evaluation, i.e. each parameter set. 26 | Be sure to check the relevant part in :ref:`reference`. 27 | - Strict bounds for PSO particle space, applied per dimension 28 | - Minor bug fixes 29 | 30 | * SKPAR version 0.1.0 released: February 2017. 31 | 32 | Contents 33 | ================== 34 | 35 | .. toctree:: 36 | :maxdepth: 2 37 | 38 | about 39 | install 40 | commands 41 | tutorials/tutorials 42 | reference 43 | modules 44 | license 45 | develop 46 | contributors 47 | 48 | 49 | Indices and tables 50 | ================== 51 | 52 | * :ref:`genindex` 53 | * :ref:`modindex` 54 | * :ref:`search` 55 | 56 | -------------------------------------------------------------------------------- /docs/source/install.rst: -------------------------------------------------------------------------------- 1 | .. index:: install 2 | 3 | .. _install: 4 | 5 | ==================== 6 | Install 7 | ==================== 8 | 9 | The latest release of SKPAR can be found on `GitHub`_. 10 | 11 | .. _GitHub: https://github.com/smarkov/skpar/ 12 | 13 | User (w/o sudo or root privilege): 14 | 15 | .. code:: bash 16 | 17 | pip3 install --upgrade --user skpar 18 | 19 | Please omit the `--user` option above if installing within a virtual environment. 20 | 21 | 22 | Developer: 23 | 24 | Clone the repository and go to the newly created directory of the repository. 25 | 26 | Issue the following command from the root directory of the repository. 27 | 28 | .. code:: bash 29 | 30 | pip3 install --upgrade --user -e . 31 | 32 | Please omit the `--user` option above if installing within a virtual environment. 33 | 34 | 35 | To uninstall: 36 | 37 | .. code:: bash 38 | 39 | pip3 uninstall skpar 40 | 41 | 42 | Dependencies 43 | ==================== 44 | SKPAR's operation requires: 45 | 46 | * YAML_ support, for setting up the optimisation, 47 | * the DEAP_ library, for the Particle Swarm Optimisation engine, 48 | * NumPy_ for data structures, and, 49 | * Matplotlib_ for plotting. 50 | 51 | 52 | .. _`DEAP`: http://deap.readthedocs.io/en/master 53 | .. _`YAML`: http://pyyaml.org/wiki/PyYAMLDocumentation 54 | .. _`NumPy`: http://www.numpy.org 55 | .. _`Matplotlib`: http://matplotlib.org/ 56 | 57 | 58 | Test 59 | =================== 60 | If cloning the repository, once installation of SKPAR and its dependencies 61 | is complete, it is important to ensure that the test suite runs without 62 | failures, so: 63 | 64 | .. code:: bash 65 | 66 | cd skpar_folder/test 67 | python3 -m unittest 68 | 69 | Tests runtime is under 30 sec and should result in no errors or failures. 70 | -------------------------------------------------------------------------------- /docs/source/license.rst: -------------------------------------------------------------------------------- 1 | .. index:: license 2 | 3 | .. _license: 4 | 5 | ======= 6 | License 7 | ======= 8 | 9 | SKPAR is distributed under `The MIT License`_. 10 | 11 | .. _The MIT license: https://opensource.org/licenses/MIT 12 | -------------------------------------------------------------------------------- /docs/source/modules.rst: -------------------------------------------------------------------------------- 1 | .. index:: subpackages and modules 2 | 3 | .. _skpar: 4 | 5 | ===================================== 6 | Subpackage/module Reference 7 | ===================================== 8 | 9 | SKPAR currently includes the following sub-packages: 10 | 11 | .. list-table:: 12 | 13 | * - :ref:`core ` 14 | - the core modules realising the optimisation framework 15 | 16 | * - :ref:`dftbutils ` 17 | - the modules related to a DFTB model 18 | 19 | .. toctree:: 20 | 21 | skpar.core 22 | skpar.dftbutils 23 | -------------------------------------------------------------------------------- /docs/source/reference.config.rst: -------------------------------------------------------------------------------- 1 | .. index:: config 2 | 3 | .. _`reference.config`: 4 | 5 | Configuration 6 | ====================================================================== 7 | 8 | Configuration of the working directory allows for a choice whether 9 | to execute each evaluation step in a separate subdirectory (labeled 10 | by iteration number). Thus it permits to save each model evaluation 11 | and is the first step towards parallelisation. 12 | 13 | Examples: 14 | 15 | .. code-block:: yaml 16 | 17 | config: 18 | # Template files and directories are copied to the individual 19 | # iteration directory under work-root; default is ``.``. 20 | templatedir: template 21 | 22 | # Workroot is the directory where each iteration dir will go 23 | # Default is ``.``. 24 | workroot: _workdir 25 | 26 | # All results are kept if true 27 | # NOTABENE: if true, then workroot may become very large!!! 28 | # NOTABENE: if false (DEFAULT), then plots should be written outside 29 | # workroot; else will be destroyed. 30 | keepworkdirs: true 31 | 32 | The complete example can be found in the `examples/C.dia`_ directory, 33 | while the directory tree layout after the run is recorded in 34 | `examples/C.dia/workdir.tree`_. 35 | 36 | 37 | .. _`examples/C.dia`: ../../../examples/C.dia 38 | .. _`examples/C.dia/workdir.tree`: ../../../examples/C.dia/workdir.tree 39 | -------------------------------------------------------------------------------- /docs/source/reference.executables.rst: -------------------------------------------------------------------------------- 1 | .. index:: executables 2 | 3 | .. _`reference.executables`: 4 | 5 | Executables 6 | ====================================================================== 7 | 8 | Executables are simple aliases to more complex commands invoking 9 | external executables. The alias may contain command-line arguments 10 | and options, a path to the actual command, etc. 11 | 12 | Examples: 13 | 14 | .. code-block:: yaml 15 | 16 | # define aliases to run-task commands 17 | executables: 18 | # alias an executable found along $PATH 19 | atom: gridatom 20 | # alias a shell script in ./skf/ directory 21 | skgen: skf/skgen.sh 22 | # alias a command including input arguments 23 | dftb: mpirun -n 4 dftb+ 24 | # alias a command including input arguments 25 | bands: ~/sw/dp_tools/dp_bands band.out bands 26 | 27 | # use the aliases 28 | tasks: 29 | - run: [skgen, skf, skdefs.py] 30 | - run: [dftb, Si/bs, out.dftb] 31 | - run: [bands, Si/bs, out.bands] 32 | -------------------------------------------------------------------------------- /docs/source/reference.rst: -------------------------------------------------------------------------------- 1 | .. index:: reference 2 | 3 | .. _reference: 4 | 5 | ======================================== 6 | Input File Reference 7 | ======================================== 8 | 9 | SKPAR is controlled by an input file in `YAML`_. The filename is given as 10 | an argument to the ``skpar`` command (e.g. ``skpar skpar_in.yaml``). 11 | Examples of input files can be seen in :ref:`tutorials`, while here we 12 | provide the full details. 13 | 14 | .. _`YAML`: http://pyyaml.org/wiki/PyYAMLDocumentation 15 | 16 | The input file must contain the following four sections, which are 17 | covered in this reference. The sections of the reference correspond to 18 | sections in the input file. 19 | 20 | 21 | .. code-block:: yaml 22 | 23 | tasks: 24 | # tasks defining the model 25 | 26 | objectives: 27 | # objectives steering the optimisation 28 | 29 | optimisation: 30 | # optimisation strategy 31 | 32 | # optional 33 | executables: 34 | # alises of executable commands used in tasks 35 | 36 | # optional 37 | config: 38 | # settings defining work directory layout 39 | 40 | .. toctree:: 41 | 42 | reference.tasks 43 | reference.objectives 44 | reference.optimisation 45 | reference.executables 46 | reference.config 47 | -------------------------------------------------------------------------------- /docs/source/skpar.core.rst: -------------------------------------------------------------------------------- 1 | .. index:: core 2 | 3 | .. _skpar.core: 4 | 5 | core sub-package modules 6 | =========================================================== 7 | 8 | Main Program (skpar.core.skpar) 9 | ------------------------------------- 10 | 11 | .. automodule:: skpar.core.skpar 12 | :members: 13 | :undoc-members: 14 | :show-inheritance: 15 | 16 | 17 | Input handler (skpar.core.input) 18 | ---------------------------------- 19 | 20 | .. automodule:: skpar.core.input 21 | :members: 22 | :undoc-members: 23 | 24 | 25 | Tasks (skpar.core.tasks) 26 | ------------------------- 27 | 28 | .. automodule:: skpar.core.tasks 29 | :members: 30 | :undoc-members: 31 | :show-inheritance: 32 | 33 | 34 | Task Dictionary (skpar.core.taskdict) 35 | ----------------------------------------- 36 | 37 | .. automodule:: skpar.core.taskdict 38 | :members: 39 | :undoc-members: 40 | 41 | 42 | Objectives (skpar.core.objectives) 43 | ----------------------------------- 44 | 45 | .. automodule:: skpar.core.objectives 46 | :members: 47 | :undoc-members: 48 | :show-inheritance: 49 | 50 | 51 | Query (skpar.core.query) 52 | ------------------------- 53 | 54 | .. automodule:: skpar.core.query 55 | :members: 56 | :undoc-members: 57 | :show-inheritance: 58 | 59 | 60 | Evaluator (skpar.core.evaluate) 61 | --------------------------------- 62 | 63 | .. automodule:: skpar.core.evaluate 64 | :members: 65 | :undoc-members: 66 | :show-inheritance: 67 | 68 | Optimiser (skpar.core.optimise) 69 | --------------------------------- 70 | 71 | .. automodule:: skpar.core.optimise 72 | :members: 73 | :undoc-members: 74 | :show-inheritance: 75 | 76 | Parameters (skpar.core.parameters) 77 | ----------------------------------- 78 | 79 | .. automodule:: skpar.core.parameters 80 | :members: 81 | :undoc-members: 82 | :show-inheritance: 83 | 84 | .. _`pso`: 85 | 86 | PSO (skpar.core.pso) 87 | ------------------------------ 88 | 89 | .. automodule:: skpar.core.pso 90 | :members: 91 | :undoc-members: 92 | :show-inheritance: 93 | 94 | Utilities (skpar.core.utils) 95 | ------------------------------ 96 | 97 | .. automodule:: skpar.core.utils 98 | :members: 99 | :undoc-members: 100 | :show-inheritance: 101 | -------------------------------------------------------------------------------- /docs/source/skpar.dftbutils.rst: -------------------------------------------------------------------------------- 1 | .. index:: dftbutils 2 | 3 | .. _skpar.dftbutils: 4 | 5 | dftbutils sub-package 6 | ===================================================== 7 | 8 | Run BS (skpar.dftbutils.runBS) 9 | ------------------------------- 10 | 11 | .. automodule:: skpar.dftbutils.runBS 12 | :members: 13 | :undoc-members: 14 | .. :show-inheritance: 15 | 16 | Query DFTB (skpar.dftbutils.queryDFTB) 17 | ------------------------------------------ 18 | 19 | .. automodule:: skpar.dftbutils.queryDFTB 20 | :members: 21 | :undoc-members: 22 | .. :show-inheritance: 23 | 24 | Query k-Lines (skpar.dftbutils.querykLines) 25 | -------------------------------------------- 26 | 27 | .. automodule:: skpar.dftbutils.querykLines 28 | :members: 29 | :undoc-members: 30 | .. :show-inheritance: 31 | 32 | Lattice (skpar.dftbutils.lattice) 33 | --------------------------------------- 34 | 35 | .. automodule:: skpar.dftbutils.lattice 36 | :members: 37 | :undoc-members: 38 | .. :show-inheritance: 39 | 40 | Plot (skpar.dftbutils.plot) 41 | ----------------------------- 42 | 43 | .. automodule:: skpar.dftbutils.plot 44 | :members: 45 | :undoc-members: 46 | .. :show-inheritance: 47 | 48 | Unils (skpar.dftbutils.utils) 49 | ------------------------------- 50 | 51 | .. automodule:: skpar.dftbutils.utils 52 | :members: 53 | :undoc-members: 54 | .. :show-inheritance: 55 | -------------------------------------------------------------------------------- /examples/C.dia/2018-08-28/freeatoms/skgen-freeatoms.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This script must be run prior to optimisation, outside of optimisation loop. 3 | 4 | skgen -o slateratom atom C 5 | -------------------------------------------------------------------------------- /examples/C.dia/2018-08-28/skpar_in.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | templatedir: template 3 | workroot: ./_workdir 4 | keepworkdirs: true 5 | 6 | 7 | usermodules: 8 | - [skpar.dftbutils, [get_bs]] 9 | 10 | tasks: 11 | - set: [[skf/skdef.template.hsd]] 12 | - run: ['skgen -o slateratom -t sktwocnt ' 13 | '-I ../../../freeatoms/_build sktable -d C C', skf] 14 | - run: [dftbutils bands, C.dia/hydrostatic-0.00] 15 | - get_bs: [C.dia/hydrostatic-0.00/bs, C.dia.hs-0.00, 16 | {latticeinfo: {type: 'FCC', param: 3.56208625213847}}] 17 | - plot: [plot_bs, ../_plots/bands.hs-0.00, [bands, C.dia.hs-0.00], 18 | kvector, queries: [kticklabels]] 19 | 20 | objectives: 21 | - bands: 22 | doc: 'C.dia.hs-0.00: VB' 23 | models: 'C.dia.hs-0.00' 24 | ref: 25 | # This is bandstructure from VASP, transformed so that bands 26 | # are columns in the file. Format is: 27 | # k-pt_Number Distance Kx Ky Kz band1(1) band2(1)... 28 | # The advantage of this is that the band with lowest energy 29 | # also has the lowest column index. 30 | # But for visualisation, bands span horisontally, and SKPAR 31 | # treats the bands-type of data as a 2D array where a band 32 | # is represented by a ROW in the array. 33 | # This is why, we must always transpose bands from dp_bands 34 | # or from vasputils, upon loading, and this is here accomplished 35 | # by the loader_args: {unpack: True}: 36 | # cf. numpy.loadtxt() for details. 37 | file: ~/venv-py37/work/C.dia/ref/unpolarised/strains/hydrostatic_strain_0.000/bands.dat 38 | loader_args: {unpack: True} 39 | process: 40 | # indexes and ranges below refer to file, not array, 41 | # i.e. independent of 'unpack' loader argument 42 | rm_columns: [[1,5]] # remove Nr Dist Kx Ky Kz columns 43 | options: 44 | # Indexes below refer to the resulting 2D array after loading, 45 | # transposing, and application of the rm_rows/rm_columns above. 46 | # Fortran-style index-bounds of bands to use 47 | use_ref: [[1, 4]] 48 | use_model: [[1, 4]] 49 | # Fortran-style index of band-index and k-point-index, 50 | align_ref: [4, max] 51 | # or a function (e.g. min, max) instead of k-point 52 | align_model: [4, max] 53 | subweights: 54 | # NOTABENE: 55 | # -------------------------------------------------- 56 | # Energy values are with respect to the ALIGNEMENT above. 57 | # If we want to have the reference band index as zero, 58 | # we would have to do tricks with the range specification 59 | # behind the curtain, to allow both positive and negative 60 | # band indexes, e.g. [-3, 0], inclusive of either boundary. 61 | # Currently this is *not done*, so only standard Fortran 62 | # range spec is supported. Therefore, band 1 is always 63 | # the lowest lying, and e.g. band 4 is the third above it. 64 | # -------------------------------------------------- 65 | dflt: 1 66 | # [[range], subweight] for E-k points in the given energy range 67 | values: 68 | # notabene: 69 | # the range below is with respect to the alignment value 70 | - [[-0.1, 0.], 5.0] 71 | # [[range], subweight] of bands indexes; fortran-style 72 | bands: 73 | # these affect Light and SO hole masses 74 | - [[2, 3], 1.5] 75 | # emphasize the top VB (affects Heavy hole masses) 76 | - [4 , 2.5] 77 | # emphasize the equilibrium structure 78 | weight: 3. 79 | eval: [rms, relerr] 80 | 81 | 82 | optimisation: 83 | algo: PSO 84 | options: 85 | npart: 2 86 | ngen : 1 87 | parameters: 88 | - R0 : 2.0 5.0 89 | -------------------------------------------------------------------------------- /examples/C.dia/2018-08-28/template/C.dia/hydrostatic-0.00/bs/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "../primcell.gen" 3 | } 4 | 5 | Hamiltonian = DFTB { 6 | SCC = Yes 7 | SCCTolerance = 1e-1 8 | OrbitalResolvedSCC = Yes 9 | ReadInitialCharges = Yes 10 | MaxSCCIterations = 1 11 | SlaterKosterFiles = Type2FileNames { 12 | Prefix = "../../../skf/" 13 | Separator = "-" 14 | Suffix = ".skf" 15 | LowerCaseTypeName = No 16 | } 17 | MaxAngularMomentum { 18 | C = "p" 19 | } 20 | Filling = Fermi { 21 | Temperature [Kelvin] = 0.0 22 | } 23 | KPointsAndWeights = Klines { 24 | 1 0.00000 0.00000 0.00000 # Gamma 25 | 39 0.50000 0.00000 0.50000 # X 26 | 27 | 1 0.50000 0.00000 0.50000 # X 28 | 39 0.50000 0.25000 0.75000 # W 29 | 30 | 1 0.50000 0.25000 0.75000 # W 31 | 39 0.37500 0.37500 0.75000 # K 32 | 33 | 1 0.37500 0.37500 0.75000 # K 34 | 39 0.00000 0.00000 0.00000 # Gamma 35 | 36 | 1 0.00000 0.00000 0.00000 # Gamma 37 | 39 0.50000 0.50000 0.50000 # L 38 | 39 | 1 0.50000 0.50000 0.50000 # L 40 | 39 0.62500 0.25000 0.62500 # U 41 | 42 | 1 0.62500 0.25000 0.62500 # U 43 | 39 0.50000 0.25000 0.75000 # W 44 | 45 | 1 0.50000 0.25000 0.75000 # W 46 | 39 0.50000 0.50000 0.50000 # L 47 | 48 | 1 0.50000 0.50000 0.50000 # L 49 | 39 0.37500 0.37500 0.75000 # K 50 | 51 | 1 0.62500 0.25000 0.62500 # U 52 | 39 0.50000 0.00000 0.50000 # X 53 | } 54 | # SpinPolarisation = {} 55 | # SpinOrbit = { Si [eV] = {0.0 +0.037 0.0} } 56 | } 57 | -------------------------------------------------------------------------------- /examples/C.dia/2018-08-28/template/C.dia/hydrostatic-0.00/primcell.gen: -------------------------------------------------------------------------------- 1 | 2 S 2 | C 3 | 1 1 0.000000000000000 0.000000000000000 0.000000000000000 4 | 2 1 0.890521563034617 0.890521563034617 0.890521563034617 5 | 0.000000000000000 0.000000000000000 0.000000000000000 6 | 0.000000000000000 1.781043126069235 1.781043126069235 7 | 1.781043126069235 0.000000000000000 1.781043126069235 8 | 1.781043126069235 1.781043126069235 0.000000000000000 9 | -------------------------------------------------------------------------------- /examples/C.dia/2018-08-28/template/C.dia/hydrostatic-0.00/scc/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "../primcell.gen" 3 | } 4 | 5 | Hamiltonian = DFTB { 6 | SCC = Yes 7 | SCCTolerance = 1e-7 8 | OrbitalResolvedSCC = Yes 9 | ReadInitialCharges = No 10 | MaxSCCIterations = 100 11 | SlaterKosterFiles = Type2FileNames { 12 | Prefix = "../../../skf/" 13 | Separator = "-" 14 | Suffix = ".skf" 15 | LowerCaseTypeName = No 16 | } 17 | MaxAngularMomentum { 18 | C = "p" 19 | } 20 | Filling = Fermi { 21 | Temperature [Kelvin] = 0.0 22 | } 23 | KPointsAndWeights = SupercellFolding { 24 | 16 0 0 25 | 0 16 0 26 | 0 0 16 27 | 0.5 0.5 0.5 28 | } 29 | # SpinPolarisation = {} 30 | # SpinOrbit = { Si [eV] = {0.0 +0.037 0.0} } 31 | } 32 | -------------------------------------------------------------------------------- /examples/C.dia/ref/unpolarised/strains/hydrostatic_strain_0.000/INCAR: -------------------------------------------------------------------------------- 1 | # Header 2 | SYSTEM = diamond_primitive_PBE 3 | 4 | # Restart option 5 | ISTART = 1 ! read WAVECAR 6 | ICHARG = 11 ! read charge from CHGCAR and keep fixed 7 | 8 | # System 9 | ISPIN = 1 ! non spin polarized calculations 10 | ISMEAR = 0 ! gaussian smearing 11 | ISYM = 2 ! memory conserving symmetrisation of the ch. den. 12 | NBANDS = 12 ! Also excited states 13 | 14 | # OUTPUT 15 | LORBIT = 11 ! CREATE DOSCAR AND PROTCAR 16 | 17 | # Geometry optimization 18 | IBRION = -1 ! no relaxation 19 | 20 | # Electronic optimization 21 | ALGO = Normal ! blocked Davidson iteration scheme 22 | PREC = Accurate ! 1.3ENCUT 23 | 24 | # Parallelisation 25 | NPAR = 4 ! 16 proc 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /examples/C.dia/ref/unpolarised/strains/hydrostatic_strain_0.000/INCAR-MESH: -------------------------------------------------------------------------------- 1 | # Header 2 | SYSTEM = diamond_primitive_PBE 3 | 4 | # Restart option 5 | ISTART = 1 ! read WAVECAR 6 | ICHARG = 11 ! read charge from CHGCAR and keep fixed 7 | 8 | # System 9 | ISPIN = 1 ! non spin polarized calculations 10 | ISMEAR = 0 ! gaussian smearing 11 | ISYM = 2 ! memory conserving symmetrisation of the ch. den. 12 | NBANDS = 12 ! Also excited states 13 | 14 | # OUTPUT 15 | LORBIT = 11 ! CREATE DOSCAR AND PROTCAR 16 | 17 | # Geometry optimization 18 | IBRION = -1 ! no relaxation 19 | 20 | # Electronic optimization 21 | ALGO = Normal ! blocked Davidson iteration scheme 22 | PREC = Accurate ! 1.3ENCUT 23 | 24 | # Parallelisation 25 | NPAR = 4 ! 16 proc 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /examples/C.dia/ref/unpolarised/strains/hydrostatic_strain_0.000/KPOINTS: -------------------------------------------------------------------------------- 1 | k-points for bandstructure G-X-W-K-F-L-U-W-L-K|U-X 2 | 40 3 | line 4 | reciprocal 5 | 0.00000 0.00000 0.00000 1 ! Gamma 6 | 0.50000 0.00000 0.50000 1 ! X 7 | 8 | 0.50000 0.00000 0.50000 1 ! X 9 | 0.50000 0.25000 0.75000 1 ! W 10 | 11 | 0.50000 0.25000 0.75000 1 ! W 12 | 0.37500 0.37500 0.75000 1 ! K 13 | 14 | 0.37500 0.37500 0.75000 1 ! K 15 | 0.00000 0.00000 0.00000 1 ! Gamma 16 | 17 | 0.00000 0.00000 0.00000 1 ! Gamma 18 | 0.50000 0.50000 0.50000 1 ! L 19 | 20 | 0.50000 0.50000 0.50000 1 ! L 21 | 0.62500 0.25000 0.62500 1 ! U 22 | 23 | 0.62500 0.25000 0.62500 1 ! U 24 | 0.50000 0.25000 0.75000 1 ! W 25 | 26 | 0.50000 0.25000 0.75000 1 ! W 27 | 0.50000 0.50000 0.50000 1 ! L 28 | 29 | 0.50000 0.50000 0.50000 1 ! L 30 | 0.37500 0.37500 0.75000 1 ! K 31 | 32 | 0.62500 0.25000 0.62500 1 ! U 33 | 0.50000 0.00000 0.50000 1 ! X -------------------------------------------------------------------------------- /examples/C.dia/ref/unpolarised/strains/hydrostatic_strain_0.000/KPOINTS-MESH: -------------------------------------------------------------------------------- 1 | k-points for bandstructure G-X-W-K-F-L-U-W-L-K|U-X 2 | 40 3 | line 4 | reciprocal 5 | 0.00000 0.00000 0.00000 1 ! Gamma 6 | 0.50000 0.00000 0.50000 1 ! X 7 | 8 | 0.50000 0.00000 0.50000 1 ! X 9 | 0.50000 0.25000 0.75000 1 ! W 10 | 11 | 0.50000 0.25000 0.75000 1 ! W 12 | 0.37500 0.37500 0.75000 1 ! K 13 | 14 | 0.37500 0.37500 0.75000 1 ! K 15 | 0.00000 0.00000 0.00000 1 ! Gamma 16 | 17 | 0.00000 0.00000 0.00000 1 ! Gamma 18 | 0.50000 0.50000 0.50000 1 ! L 19 | 20 | 0.50000 0.50000 0.50000 1 ! L 21 | 0.62500 0.25000 0.62500 1 ! U 22 | 23 | 0.62500 0.25000 0.62500 1 ! U 24 | 0.50000 0.25000 0.75000 1 ! W 25 | 26 | 0.50000 0.25000 0.75000 1 ! W 27 | 0.50000 0.50000 0.50000 1 ! L 28 | 29 | 0.50000 0.50000 0.50000 1 ! L 30 | 0.37500 0.37500 0.75000 1 ! K 31 | 32 | 0.62500 0.25000 0.62500 1 ! U 33 | 0.50000 0.00000 0.50000 1 ! X -------------------------------------------------------------------------------- /examples/C.dia/ref/unpolarised/strains/hydrostatic_strain_0.000/POSCAR: -------------------------------------------------------------------------------- 1 | diamond 2 | 3.5618587319634445 3 | 0.0000000000000000 0.5000000000000000 0.5000000000000000 4 | 0.5000000000000000 0.0000000000000000 0.5000000000000000 5 | 0.5000000000000000 0.5000000000000000 0.0000000000000000 6 | 2 7 | Direct 8 | 0.0000000000000000 0.0000000000000000 0.0000000000000000 9 | 0.2500000000000000 0.2500000000000000 0.2500000000000000 10 | -------------------------------------------------------------------------------- /examples/C.dia/ref/unpolarised/strains/hydrostatic_strain_0.000/geometry.xyz: -------------------------------------------------------------------------------- 1 | 2 2 | "Unknown, cubic" 3 | C 0.000000000 0.000000000 0.000000000 4 | C 0.890464683 0.890464683 0.890464683 5 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/refdata/toten-MoS2.ml.dat: -------------------------------------------------------------------------------- 1 | # Energy [eV], Volume tag 2 | -68.72332588 095 3 | -69.35696217 096 4 | -69.78872449 097 5 | -70.03856017 098 6 | -70.12431929 099 7 | -70.06258145 100 8 | -69.86846402 101 9 | -69.55578871 102 10 | -69.13723525 103 11 | -68.62436212 104 12 | -68.02778307 105 13 | -67.35715565 106 14 | -66.62131101 107 15 | -65.82832034 108 16 | -64.98556677 109 17 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/skpar.in.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | templatedir: template 3 | workroot: ./_workdir/ 4 | keepworkdirs: true 5 | 6 | usermodules: 7 | - [skpar.dftbutils, [get_evol]] 8 | 9 | tasks: 10 | - set: [[skf/fitpoints.template.dat]] 11 | # fit spline repulsive on given points and produce repulsive.dat 12 | - run: [skpar_splinerepfit, skf] 13 | # add repulsive.dat to 1-2.skf and 2-1.skf 14 | - run: ['skpar_addrepulsive -e Mo S', skf] 15 | # energy-volume calculation in the subfolders 16 | # of MoS2.ml-evol under _workdir/iteration/ 17 | - run: ['dftbutils evol', MoS2.ml-evol] 18 | # get total energy for all calculations in 19 | # MoS2.ml-evol subfolders and associate data 20 | # with MoS2.ml model 21 | - get_evol: [MoS2.ml-evol, MoS2.ml] 22 | # which routine to use for plotting, and filename 23 | # what to plot -- objective, model name 24 | # what to use as abscissa (a query is constructed) 25 | - plot: [skparplot, '../plots/etot.vs.strain.pdf', 26 | [totalenergy_volume, MoS2.ml], 27 | 'strain'] 28 | 29 | objectives: 30 | - totalenergy_volume: 31 | doc: MoS2.ml Energy-Volume dependence 32 | models: MoS2.ml 33 | ref: 34 | file: refdata/toten-MoS2.ml.dat # ./ is where this .yaml is 35 | loader_args: 36 | usecols: 0 # Etot[eV]; col[1] is % of equil.lat.const. 37 | options: 38 | align_ref: 5 39 | align_model: 5 40 | subweights: [ 2,2, 3,3,3,3,3,3, 2,2,2, 1,1,1,1] 41 | eval: [rms, relerr] 42 | 43 | 44 | optimisation: 45 | algo: PSO # particle swarm optimisation 46 | options: 47 | npart: 1 # number of particles 48 | ngen : 1 # number of generations 49 | parameters: 50 | # how do we choose the range for the spline values? 51 | - s1: [0.04, 0.08] 52 | - s2: [0.015, 0.04] 53 | - s3: [0.01, 0.02] 54 | - s4: [0.002, 0.015] 55 | - s5: [0, 0.01] 56 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/095/POS.gen: -------------------------------------------------------------------------------- 1 | 9 S 2 | Mo S 3 | 1 1 3.899085000000002 0.750379258114409 9.866029142493165 4 | 2 1 1.299695000000001 2.251137774343233 9.866029142493165 5 | 3 1 -1.299695000000001 3.751896290572053 9.866029142493165 6 | 4 2 2.166158333333335 0.750379258114409 8.359329142493166 7 | 5 2 -0.433231666666669 2.251137774343233 8.359329142493166 8 | 6 2 2.166158333333335 3.751896290572053 8.359329142493166 9 | 7 2 2.166158333333336 0.750379258114409 11.372729142493164 10 | 8 2 -0.433231666666669 2.251137774343233 11.372729142493164 11 | 9 2 2.166158333333335 3.751896290572054 11.372729142493164 12 | 0.000000000000000 0.000000000000000 0.000000000000000 13 | 5.198780000000000 0.000000000000000 0.000000000000000 14 | -2.599390000000000 4.502275548686464 0.000000000000000 15 | 0.000000000000000 0.000000000000000 38.000000000000000 16 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/095/charges.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/examples/MoS2-repfit/template/MoS2.ml-evol/095/charges.bin -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/095/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "POS.gen" 3 | } 4 | 5 | <<+ "../common.hsd" 6 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/096/POS.gen: -------------------------------------------------------------------------------- 1 | 9 S 2 | Mo S 3 | 1 1 3.940128000000002 0.758277987147192 9.969882080835198 4 | 2 1 1.313376000000001 2.274833961441582 9.969882080835198 5 | 3 1 -1.313376000000001 3.791389935735969 9.969882080835198 6 | 4 2 2.188960000000002 0.758277987147192 8.447322080835200 7 | 5 2 -0.437792000000003 2.274833961441582 8.447322080835200 8 | 6 2 2.188960000000001 3.791389935735969 8.447322080835200 9 | 7 2 2.188960000000003 0.758277987147192 11.492442080835199 10 | 8 2 -0.437792000000003 2.274833961441583 11.492442080835199 11 | 9 2 2.188960000000001 3.791389935735971 11.492442080835199 12 | 0.000000000000000 0.000000000000000 0.000000000000000 13 | 5.253504000000000 0.000000000000000 0.000000000000000 14 | -2.626752000000000 4.549667922883164 0.000000000000000 15 | 0.000000000000000 0.000000000000000 38.399999999999999 16 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/096/charges.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/examples/MoS2-repfit/template/MoS2.ml-evol/096/charges.bin -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/096/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "POS.gen" 3 | } 4 | 5 | <<+ "../common.hsd" 6 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/097/POS.gen: -------------------------------------------------------------------------------- 1 | 9 S 2 | Mo S 3 | 1 1 3.981171000000002 0.766176716179975 10.073735019177231 4 | 2 1 1.327057000000001 2.298530148539932 10.073735019177231 5 | 3 1 -1.327057000000001 3.830883580899886 10.073735019177231 6 | 4 2 2.211761666666669 0.766176716179975 8.535315019177233 7 | 5 2 -0.442352333333336 2.298530148539932 8.535315019177233 8 | 6 2 2.211761666666668 3.830883580899886 8.535315019177233 9 | 7 2 2.211761666666670 0.766176716179975 11.612155019177232 10 | 8 2 -0.442352333333336 2.298530148539933 11.612155019177232 11 | 9 2 2.211761666666668 3.830883580899887 11.612155019177232 12 | 0.000000000000000 0.000000000000000 0.000000000000000 13 | 5.308228000000001 0.000000000000000 0.000000000000000 14 | -2.654114000000000 4.597060297079864 0.000000000000000 15 | 0.000000000000000 0.000000000000000 38.799999999999997 16 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/097/charges.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/examples/MoS2-repfit/template/MoS2.ml-evol/097/charges.bin -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/097/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "POS.gen" 3 | } 4 | 5 | <<+ "../common.hsd" 6 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/098/POS.gen: -------------------------------------------------------------------------------- 1 | 9 S 2 | Mo S 3 | 1 1 4.022214000000002 0.774075445212759 10.177587957519265 4 | 2 1 1.340738000000001 2.322226335638282 10.177587957519265 5 | 3 1 -1.340738000000001 3.870377226063802 10.177587957519265 6 | 4 2 2.234563333333336 0.774075445212759 8.623307957519266 7 | 5 2 -0.446912666666669 2.322226335638282 8.623307957519266 8 | 6 2 2.234563333333335 3.870377226063802 8.623307957519266 9 | 7 2 2.234563333333337 0.774075445212759 11.731867957519265 10 | 8 2 -0.446912666666669 2.322226335638283 11.731867957519265 11 | 9 2 2.234563333333335 3.870377226063804 11.731867957519265 12 | 0.000000000000000 0.000000000000000 0.000000000000000 13 | 5.362952000000000 0.000000000000000 0.000000000000000 14 | -2.681476000000000 4.644452671276563 0.000000000000000 15 | 0.000000000000000 0.000000000000000 39.200000000000003 16 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/098/charges.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/examples/MoS2-repfit/template/MoS2.ml-evol/098/charges.bin -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/098/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "POS.gen" 3 | } 4 | 5 | <<+ "../common.hsd" 6 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/099/POS.gen: -------------------------------------------------------------------------------- 1 | 9 S 2 | Mo S 3 | 1 1 4.063257000000002 0.781974174245542 10.281440895861298 4 | 2 1 1.354419000000001 2.345922522736632 10.281440895861298 5 | 3 1 -1.354419000000001 3.909870871227719 10.281440895861298 6 | 4 2 2.257365000000002 0.781974174245542 8.711300895861299 7 | 5 2 -0.451473000000003 2.345922522736632 8.711300895861299 8 | 6 2 2.257365000000001 3.909870871227719 8.711300895861299 9 | 7 2 2.257365000000003 0.781974174245542 11.851580895861298 10 | 8 2 -0.451473000000003 2.345922522736633 11.851580895861298 11 | 9 2 2.257365000000001 3.909870871227720 11.851580895861298 12 | 0.000000000000000 0.000000000000000 0.000000000000000 13 | 5.417676000000000 0.000000000000000 0.000000000000000 14 | -2.708838000000000 4.691845045473263 0.000000000000000 15 | 0.000000000000000 0.000000000000000 39.600000000000001 16 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/099/charges.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/examples/MoS2-repfit/template/MoS2.ml-evol/099/charges.bin -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/099/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "POS.gen" 3 | } 4 | 5 | <<+ "../common.hsd" 6 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/100/POS.gen: -------------------------------------------------------------------------------- 1 | 9 S 2 | Mo S 3 | 1 1 4.104300000000002 0.789872903278325 10.385293834203331 4 | 2 1 1.368100000000001 2.369618709834982 10.385293834203331 5 | 3 1 -1.368100000000001 3.949364516391635 10.385293834203331 6 | 4 2 2.280166666666669 0.789872903278325 8.799293834203333 7 | 5 2 -0.456033333333336 2.369618709834982 8.799293834203333 8 | 6 2 2.280166666666668 3.949364516391635 8.799293834203333 9 | 7 2 2.280166666666670 0.789872903278325 11.971293834203331 10 | 8 2 -0.456033333333336 2.369618709834983 11.971293834203331 11 | 9 2 2.280166666666668 3.949364516391636 11.971293834203331 12 | 0.000000000000000 0.000000000000000 0.000000000000000 13 | 5.472400000000000 0.000000000000000 0.000000000000000 14 | -2.736200000000000 4.739237419669963 0.000000000000000 15 | 0.000000000000000 0.000000000000000 40.000000000000000 16 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/100/charges.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/examples/MoS2-repfit/template/MoS2.ml-evol/100/charges.bin -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/100/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "POS.gen" 3 | } 4 | 5 | <<+ "../common.hsd" 6 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/101/POS.gen: -------------------------------------------------------------------------------- 1 | 9 S 2 | Mo S 3 | 1 1 4.145343000000002 0.797771632311108 10.489146772545364 4 | 2 1 1.381781000000001 2.393314896933332 10.489146772545364 5 | 3 1 -1.381781000000001 3.988858161555551 10.489146772545364 6 | 4 2 2.302968333333336 0.797771632311108 8.887286772545366 7 | 5 2 -0.460593666666669 2.393314896933332 8.887286772545366 8 | 6 2 2.302968333333335 3.988858161555551 8.887286772545366 9 | 7 2 2.302968333333336 0.797771632311108 12.091006772545365 10 | 8 2 -0.460593666666669 2.393314896933333 12.091006772545365 11 | 9 2 2.302968333333335 3.988858161555553 12.091006772545365 12 | 0.000000000000000 0.000000000000000 0.000000000000000 13 | 5.527124000000001 0.000000000000000 0.000000000000000 14 | -2.763562000000000 4.786629793866663 0.000000000000000 15 | 0.000000000000000 0.000000000000000 40.399999999999999 16 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/101/charges.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/examples/MoS2-repfit/template/MoS2.ml-evol/101/charges.bin -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/101/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "POS.gen" 3 | } 4 | 5 | <<+ "../common.hsd" 6 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/102/POS.gen: -------------------------------------------------------------------------------- 1 | 9 S 2 | Mo S 3 | 1 1 4.186386000000002 0.805670361343892 10.592999710887398 4 | 2 1 1.395462000000001 2.417011084031682 10.592999710887398 5 | 3 1 -1.395462000000001 4.028351806719468 10.592999710887398 6 | 4 2 2.325770000000002 0.805670361343892 8.975279710887399 7 | 5 2 -0.465154000000003 2.417011084031682 8.975279710887399 8 | 6 2 2.325770000000001 4.028351806719468 8.975279710887399 9 | 7 2 2.325770000000003 0.805670361343892 12.210719710887398 10 | 8 2 -0.465154000000003 2.417011084031683 12.210719710887398 11 | 9 2 2.325770000000001 4.028351806719469 12.210719710887398 12 | 0.000000000000000 0.000000000000000 0.000000000000000 13 | 5.581848000000001 0.000000000000000 0.000000000000000 14 | -2.790924000000000 4.834022168063362 0.000000000000000 15 | 0.000000000000000 0.000000000000000 40.799999999999997 16 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/102/charges.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/examples/MoS2-repfit/template/MoS2.ml-evol/102/charges.bin -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/102/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "POS.gen" 3 | } 4 | 5 | <<+ "../common.hsd" 6 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/103/POS.gen: -------------------------------------------------------------------------------- 1 | 9 S 2 | Mo S 3 | 1 1 4.227429000000003 0.813569090376675 10.696852649229431 4 | 2 1 1.409143000000001 2.440707271130031 10.696852649229431 5 | 3 1 -1.409143000000001 4.067845451883384 10.696852649229431 6 | 4 2 2.348571666666669 0.813569090376675 9.063272649229432 7 | 5 2 -0.469714333333336 2.440707271130031 9.063272649229432 8 | 6 2 2.348571666666668 4.067845451883384 9.063272649229432 9 | 7 2 2.348571666666670 0.813569090376675 12.330432649229431 10 | 8 2 -0.469714333333336 2.440707271130032 12.330432649229431 11 | 9 2 2.348571666666668 4.067845451883385 12.330432649229431 12 | 0.000000000000000 0.000000000000000 0.000000000000000 13 | 5.636572000000000 0.000000000000000 0.000000000000000 14 | -2.818286000000000 4.881414542260062 0.000000000000000 15 | 0.000000000000000 0.000000000000000 41.200000000000003 16 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/103/charges.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/examples/MoS2-repfit/template/MoS2.ml-evol/103/charges.bin -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/103/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "POS.gen" 3 | } 4 | 5 | <<+ "../common.hsd" 6 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/104/POS.gen: -------------------------------------------------------------------------------- 1 | 9 S 2 | Mo S 3 | 1 1 4.268472000000003 0.821467819409458 10.800705587571464 4 | 2 1 1.422824000000001 2.464403458228381 10.800705587571464 5 | 3 1 -1.422824000000001 4.107339097047300 10.800705587571464 6 | 4 2 2.371373333333336 0.821467819409458 9.151265587571466 7 | 5 2 -0.474274666666669 2.464403458228381 9.151265587571466 8 | 6 2 2.371373333333335 4.107339097047300 9.151265587571466 9 | 7 2 2.371373333333337 0.821467819409458 12.450145587571464 10 | 8 2 -0.474274666666669 2.464403458228382 12.450145587571464 11 | 9 2 2.371373333333335 4.107339097047301 12.450145587571464 12 | 0.000000000000000 0.000000000000000 0.000000000000000 13 | 5.691296000000000 0.000000000000000 0.000000000000000 14 | -2.845648000000000 4.928806916456762 0.000000000000000 15 | 0.000000000000000 0.000000000000000 41.600000000000001 16 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/104/charges.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/examples/MoS2-repfit/template/MoS2.ml-evol/104/charges.bin -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/104/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "POS.gen" 3 | } 4 | 5 | <<+ "../common.hsd" 6 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/105/POS.gen: -------------------------------------------------------------------------------- 1 | 9 S 2 | Mo S 3 | 1 1 4.309515000000002 0.829366548442241 10.904558525913497 4 | 2 1 1.436505000000001 2.488099645326731 10.904558525913497 5 | 3 1 -1.436505000000001 4.146832742211217 10.904558525913497 6 | 4 2 2.394175000000002 0.829366548442241 9.239258525913499 7 | 5 2 -0.478835000000003 2.488099645326731 9.239258525913499 8 | 6 2 2.394175000000001 4.146832742211217 9.239258525913499 9 | 7 2 2.394175000000003 0.829366548442241 12.569858525913499 10 | 8 2 -0.478835000000003 2.488099645326732 12.569858525913499 11 | 9 2 2.394175000000001 4.146832742211219 12.569858525913499 12 | 0.000000000000000 0.000000000000000 0.000000000000000 13 | 5.746020000000001 0.000000000000000 0.000000000000000 14 | -2.873010000000000 4.976199290653462 0.000000000000000 15 | 0.000000000000000 0.000000000000000 42.000000000000000 16 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/105/charges.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/examples/MoS2-repfit/template/MoS2.ml-evol/105/charges.bin -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/105/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "POS.gen" 3 | } 4 | 5 | <<+ "../common.hsd" 6 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/106/POS.gen: -------------------------------------------------------------------------------- 1 | 9 S 2 | Mo S 3 | 1 1 4.350558000000002 0.837265277475025 11.008411464255532 4 | 2 1 1.450186000000001 2.511795832425081 11.008411464255532 5 | 3 1 -1.450186000000001 4.186326387375133 11.008411464255532 6 | 4 2 2.416976666666669 0.837265277475025 9.327251464255534 7 | 5 2 -0.483395333333336 2.511795832425081 9.327251464255534 8 | 6 2 2.416976666666668 4.186326387375133 9.327251464255534 9 | 7 2 2.416976666666670 0.837265277475025 12.689571464255533 10 | 8 2 -0.483395333333336 2.511795832425082 12.689571464255533 11 | 9 2 2.416976666666668 4.186326387375135 12.689571464255533 12 | 0.000000000000000 0.000000000000000 0.000000000000000 13 | 5.800744000000001 0.000000000000000 0.000000000000000 14 | -2.900372000000000 5.023591664850161 0.000000000000000 15 | 0.000000000000000 0.000000000000000 42.400000000000006 16 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/106/charges.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/examples/MoS2-repfit/template/MoS2.ml-evol/106/charges.bin -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/106/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "POS.gen" 3 | } 4 | 5 | <<+ "../common.hsd" 6 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/107/POS.gen: -------------------------------------------------------------------------------- 1 | 9 S 2 | Mo S 3 | 1 1 4.391601000000002 0.845164006507808 11.112264402597566 4 | 2 1 1.463867000000001 2.535492019523431 11.112264402597566 5 | 3 1 -1.463867000000001 4.225820032539049 11.112264402597566 6 | 4 2 2.439778333333336 0.845164006507808 9.415244402597567 7 | 5 2 -0.487955666666670 2.535492019523431 9.415244402597567 8 | 6 2 2.439778333333335 4.225820032539049 9.415244402597567 9 | 7 2 2.439778333333337 0.845164006507808 12.809284402597566 10 | 8 2 -0.487955666666670 2.535492019523432 12.809284402597566 11 | 9 2 2.439778333333335 4.225820032539051 12.809284402597566 12 | 0.000000000000000 0.000000000000000 0.000000000000000 13 | 5.855468000000001 0.000000000000000 0.000000000000000 14 | -2.927734000000001 5.070984039046861 0.000000000000000 15 | 0.000000000000000 0.000000000000000 42.800000000000004 16 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/107/charges.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/examples/MoS2-repfit/template/MoS2.ml-evol/107/charges.bin -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/107/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "POS.gen" 3 | } 4 | 5 | <<+ "../common.hsd" 6 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/108/POS.gen: -------------------------------------------------------------------------------- 1 | 9 S 2 | Mo S 3 | 1 1 4.432644000000002 0.853062735540591 11.216117340939599 4 | 2 1 1.477548000000001 2.559188206621781 11.216117340939599 5 | 3 1 -1.477548000000001 4.265313677702966 11.216117340939599 6 | 4 2 2.462580000000003 0.853062735540591 9.503237340939600 7 | 5 2 -0.492516000000003 2.559188206621781 9.503237340939600 8 | 6 2 2.462580000000002 4.265313677702966 9.503237340939600 9 | 7 2 2.462580000000004 0.853062735540591 12.928997340939599 10 | 8 2 -0.492516000000003 2.559188206621782 12.928997340939599 11 | 9 2 2.462580000000002 4.265313677702967 12.928997340939599 12 | 0.000000000000000 0.000000000000000 0.000000000000000 13 | 5.910192000000001 0.000000000000000 0.000000000000000 14 | -2.955096000000001 5.118376413243560 0.000000000000000 15 | 0.000000000000000 0.000000000000000 43.200000000000003 16 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/108/charges.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/examples/MoS2-repfit/template/MoS2.ml-evol/108/charges.bin -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/108/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "POS.gen" 3 | } 4 | 5 | <<+ "../common.hsd" 6 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/109/POS.gen: -------------------------------------------------------------------------------- 1 | 9 S 2 | Mo S 3 | 1 1 4.473687000000003 0.860961464573374 11.319970279281632 4 | 2 1 1.491229000000001 2.582884393720131 11.319970279281632 5 | 3 1 -1.491229000000001 4.304807322866882 11.319970279281632 6 | 4 2 2.485381666666669 0.860961464573374 9.591230279281634 7 | 5 2 -0.497076333333336 2.582884393720131 9.591230279281634 8 | 6 2 2.485381666666668 4.304807322866882 9.591230279281634 9 | 7 2 2.485381666666670 0.860961464573374 13.048710279281632 10 | 8 2 -0.497076333333336 2.582884393720132 13.048710279281632 11 | 9 2 2.485381666666668 4.304807322866884 13.048710279281632 12 | 0.000000000000000 0.000000000000000 0.000000000000000 13 | 5.964916000000001 0.000000000000000 0.000000000000000 14 | -2.982458000000000 5.165768787440260 0.000000000000000 15 | 0.000000000000000 0.000000000000000 43.600000000000001 16 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/109/charges.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/examples/MoS2-repfit/template/MoS2.ml-evol/109/charges.bin -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/109/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "POS.gen" 3 | } 4 | 5 | <<+ "../common.hsd" 6 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/common.hsd: -------------------------------------------------------------------------------- 1 | Hamiltonian = DFTB { 2 | SCC = Yes 3 | SCCTolerance = 1e-6 4 | SlaterKosterFiles = Type2FileNames { 5 | Prefix = "../../skf/" 6 | Separator = "-" 7 | Suffix = ".skf" 8 | } 9 | MaxAngularMomentum { 10 | Mo = "d" 11 | S = "d" 12 | } 13 | Filling = Fermi { 14 | Temperature [Kelvin] = 0.0 15 | } 16 | KPointsAndWeights = SupercellFolding { 17 | 9 0 0 18 | 0 9 0 19 | 0 0 1 20 | 0.0 0.0 0.0 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/MoS2.ml-evol/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "POS.gen" 3 | } 4 | 5 | <<+ "../common.hsd" 6 | -------------------------------------------------------------------------------- /examples/MoS2-repfit/template/skf/fitpoints.template.dat: -------------------------------------------------------------------------------- 1 | # Fitting points: x-val y-val 2 | # Last line: r_damp(ignored), r_cutoff 3 | # NOTABENE: 1. Exponential head is fitted from x[0]-0.5 to x[0] au. 4 | # 2. 5-th order polynomial extends from x[-1] to rcutoff. 5 | # 3. For the available refdata, Mo-S bond varies between 6 | # 4.35 au (2.3 A) and 4.97 au (2.63 A). 7 | # 8 | 4.35 %(s1)f 9 | 4.41 %(s2)f 10 | 4.67 %(s3)f 11 | 4.84 %(s4)f 12 | 4.97 %(s5)f 13 | 0.0 5.5 14 | -------------------------------------------------------------------------------- /examples/Si-1/Si-diam/bs/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "../primcell.gen" 3 | } 4 | 5 | Hamiltonian = DFTB { 6 | SCC = Yes 7 | OrbitalResolvedSCC = Yes 8 | ReadInitialCharges = Yes 9 | MaxSCCIterations = 1 10 | SlaterKosterFiles = Type2FileNames { 11 | Prefix = "../../skf/" 12 | Separator = "-" 13 | Suffix = ".skf" 14 | LowerCaseTypeName = No 15 | } 16 | MaxAngularMomentum { 17 | Si = "d" 18 | } 19 | Filling = Fermi { 20 | Temperature [Kelvin] = 0.0 21 | } 22 | KPointsAndWeights = Klines { 23 | 1 0.500 0.500 0.500 # L 24 | 266 0.000 0.000 0.000 # Gamma 25 | 300 0.500 0.000 0.500 # X 26 | 138 0.625 0.250 0.625 # U 27 | 1 0.375 0.375 0.750 # K, equiv. to U 28 | 316 0.000 0.000 0.000 # Gamma 29 | } 30 | # SpinPolarisation = {} 31 | # SpinOrbit = { Si [eV] = {0.0 +0.037 0.0} } 32 | } 33 | -------------------------------------------------------------------------------- /examples/Si-1/Si-diam/primcell.gen: -------------------------------------------------------------------------------- 1 | 2 F 2 | Si 3 | 1 1 0.000000000000000 0.000000000000000 0.000000000000000 4 | 2 1 0.250000000000000 0.250000000000000 0.25000000000000 5 | 0.000000000000000 0.000000000000000 0.000000000000000 6 | 2.715500000000000 2.715500000000000 0.000000000000000 7 | 0.000000000000000 2.715500000000000 2.715500000000000 8 | 2.715500000000000 0.000000000000000 2.715500000000000 9 | -------------------------------------------------------------------------------- /examples/Si-1/Si-diam/scc/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "../primcell.gen" 3 | } 4 | 5 | Hamiltonian = DFTB { 6 | SCC = Yes 7 | SCCTolerance = 1e-8 8 | OrbitalResolvedSCC = Yes 9 | ReadInitialCharges = No 10 | MaxSCCIterations = 100 11 | SlaterKosterFiles = Type2FileNames { 12 | Prefix = "../../skf/" 13 | Separator = "-" 14 | Suffix = ".skf" 15 | LowerCaseTypeName = No 16 | } 17 | MaxAngularMomentum { 18 | Si = "d" 19 | } 20 | Filling = Fermi { 21 | Temperature [Kelvin] = 0.0 22 | } 23 | KPointsAndWeights = SupercellFolding { 24 | 16 0 0 25 | 0 16 0 26 | 0 0 16 27 | 0.5 0.5 0.5 28 | } 29 | # SpinPolarisation = {} 30 | # SpinOrbit = { Si [eV] = {0.0 +0.037 0.0} } 31 | } 32 | -------------------------------------------------------------------------------- /examples/Si-1/ref/Ek-Si--SOC.dat: -------------------------------------------------------------------------------- 1 | Ec_G_6 4.15 2 | Ec_G_0 3.35 3 | # 4 | Ev_G_0 0.0 5 | Ev_G_2 0.0 6 | Ev_G_4 -0.045 7 | Ev_G_6 -12.5 8 | # 9 | Ec_L_4 4.15 10 | Ec_L_0 2.4 11 | # 12 | Ev_L_0 -1.2 13 | Ev_L_4 -7.0 14 | Ev_L_6 -9.3 15 | # 16 | Ec_K_0 1.7 17 | Ec_K_2 4.79 18 | # 19 | Ev_K_0 -2.47 20 | Ev_K_2 -4.37 21 | Ev_K_4 -7.16 22 | Ev_K_6 -8.15 23 | # 24 | Ec_X_0 1.35 25 | # 26 | Ev_X_0 -2.9 27 | Ev_X_4 -8.01 28 | Ev_X_6 -8.01 29 | -------------------------------------------------------------------------------- /examples/Si-1/ref/Ek-Si.dat: -------------------------------------------------------------------------------- 1 | # assumint 4 valence bands; i.e. without SOC 2 | Ec_G_3 4.15 3 | Ec_G_0 3.35 4 | # 5 | Ev_G_0 0.0 6 | Ev_G_1 0.0 7 | Ev_G_2 -0.045 8 | Ev_G_3 -12.5 9 | # 10 | Ec_L_2 4.15 11 | Ec_L_0 2.4 12 | # 13 | Ev_L_0 -1.2 14 | Ev_L_2 -7.0 15 | Ev_L_3 -9.3 16 | # 17 | Ec_K_0 1.7 18 | Ec_K_1 4.79 19 | # 20 | Ev_K_0 -2.47 21 | Ev_K_1 -4.37 22 | Ev_K_2 -7.16 23 | Ev_K_3 -8.15 24 | # 25 | Ec_X_0 1.35 26 | # 27 | Ev_X_0 -2.9 28 | Ev_X_2 -8.01 29 | Ev_X_3 -8.01 30 | -------------------------------------------------------------------------------- /examples/Si-1/ref/meff-Si--SOC.dat: -------------------------------------------------------------------------------- 1 | me_GX_0 0.916 2 | me_Xt_0 0.19 3 | mh_GX_0 -0.276 4 | mh_GK_0 -0.738 5 | mh_GL_0 -0.579 6 | mh_GX_2 -0.204 7 | mh_GK_2 -0.139 8 | mh_GL_2 -0.147 9 | mh_GX_4 -0.234 10 | mh_GK_4 -0.234 11 | mh_GL_4 -0.234 12 | cbminpos_GX_0 0.85 13 | -------------------------------------------------------------------------------- /examples/Si-1/ref/meff-Si.dat: -------------------------------------------------------------------------------- 1 | # assumint 4 valence bands; i.e. without SOC 2 | me_GX_0 0.916 3 | me_Xt_0 0.19 4 | mh_GX_0 -0.276 5 | mh_GK_0 -0.738 6 | mh_GL_0 -0.579 7 | mh_GX_1 -0.204 8 | mh_GK_1 -0.139 9 | mh_GL_1 -0.147 10 | mh_GX_2 -0.234 11 | mh_GK_2 -0.234 12 | mh_GL_2 -0.234 13 | cbminpos_GX_0 0.85 14 | -------------------------------------------------------------------------------- /examples/Si-1/ref/volen-Si.dat: -------------------------------------------------------------------------------- 1 | 2.316982982356482523e+02 -3.794729662244810675e-01 2 | 2.390923756673737728e+02 -3.839805647820194179e-01 3 | 2.466421121978409303e+02 -3.872759868943164707e-01 4 | 2.543491292759951250e+02 -3.895470583552673727e-01 5 | 2.622150483507815579e+02 -3.908988454815900404e-01 6 | 2.702414908711454018e+02 -3.913664071281811041e-01 7 | 2.784300782860319714e+02 -3.910606160049174274e-01 8 | 2.867824320443864963e+02 -3.900290257367843849e-01 9 | 2.953001735951540923e+02 -3.883779521175089733e-01 10 | 3.039849243872801026e+02 -3.861584032085128571e-01 11 | 3.128383058697098136e+02 -3.834295821704231666e-01 12 | -------------------------------------------------------------------------------- /examples/Si-1/skf/skdefs.freeatoms.py: -------------------------------------------------------------------------------- 1 | # References: 2 | # [1] Wahiduzzaman et al, JCTC 2013 _9_, exponent for Si is 12.8, and r0 is 4.4 a.u. 3 | # [2] Elstner et al, Phys Rev B 98 4 | # [3] A. Sieck, PhD. Thesis, University of Paderborn, 2000 5 | 6 | atomconfigs = { 7 | "Si": AtomConfig( 8 | # Data from http://www.rsc.org/periodic-table/element/14/silicon 9 | # ---------------------------------------------------------------------- 10 | # [Ne].3s2.3p2 (Ne: [He].2s2.2p6) 11 | # Atomic Radius (non-bonded) [A]: 2.1 12 | # Covalent Radius [A]: 1.14 13 | # Electron Affinity [kJ/mol]: 134.068 14 | # Electronegativity (Pauling scale): 1.9 15 | # Ionisation energies [kJ/mol]: 1st 786.518; 2nd 1577.134; 3rd 3231.585; 4th 4355.523; 5th 16090.571; 6th 19805.55; 7th 23783.6; 8th 29287.16; 16 | znuc=14, 17 | mass=28.085, 18 | # [Ne].3s2.3p2 (Ne: [He].2s2.2p6) 19 | occupations=[ 20 | [ 21 | [1.0, 1.0], 22 | [1.0, 1.0], 23 | [1.0, 1.0], 24 | ], # s 25 | [ 26 | [3.0, 3.0], 27 | [1.0, 1.0], 28 | ], # p 29 | [ 30 | [0.0, 0.0], 31 | ], # d 32 | ], 33 | valenceqns=[ 34 | [ 35 | 3, 36 | ], # s 37 | [ 38 | 3, 39 | ], # p 40 | [ 41 | 3, 42 | ], # d 43 | ], 44 | relativistic=True, 45 | orbitalresolved=True, 46 | # override the d onsite with the value in [1] 47 | # note that gridatom yields very low d-eigenstate 48 | # ideally, we should be able to optimise that 49 | override_onsite={(3, 2): 0.113134}, 50 | ), 51 | } 52 | 53 | skbases = { 54 | "Si": SlaterBasis( 55 | exponents=[ 56 | # Geometric progression, very similar to the one used in PBC 57 | [0.4, 0.97, 2.37, 5.75, 14.0], # s 58 | [0.4, 0.97, 2.37, 5.75, 14.0], # p 59 | [0.4, 0.97, 2.37, 5.75, 14.0], # d 60 | ], 61 | maxpowers=[ 62 | 3, # s 63 | 3, # p 64 | 3, # d 65 | ], 66 | ), 67 | } 68 | 69 | compressions = { 70 | "Si": Compression( 71 | # According to [1], exponent for Si is 12.8, and r0 is 4.4 a.u. 72 | # The rule of thumb [2] gives: 1.8*r_cov = 3.88 a.u. 73 | # According to [3], power=4, r0=5.4 is best for 3s3p3d4s basis 74 | potcomp="potential", 75 | potcomp_parameters=[ 76 | (4, 5.4), # s 77 | (4, 5.4), # p 78 | (4, 5.4), # d 79 | ], 80 | wavecomp="potential", 81 | wavecomp_parameters=[ 82 | (4, 5.4), # s 83 | (4, 5.4), # p 84 | (4, 5.4), # d 85 | ], 86 | ), 87 | } 88 | -------------------------------------------------------------------------------- /examples/Si-1/skf/skdefs.template.py: -------------------------------------------------------------------------------- 1 | # References: 2 | # [1] Wahiduzzaman et al, JCTC 2013 _9_, exponent for Si is 12.8, and r0 is 4.4 a.u. 3 | # [2] Elstner et al, Phys Rev B 98 4 | # [3] A. Sieck, PhD. Thesis, University of Paderborn, 2000 5 | 6 | atomconfigs = { 7 | "Si": AtomConfig( 8 | # Data from http://www.rsc.org/periodic-table/element/14/silicon 9 | # ---------------------------------------------------------------------- 10 | # [Ne].3s2.3p2 (Ne: [He].2s2.2p6) 11 | # Atomic Radius (non-bonded) [A]: 2.1 12 | # Covalent Radius [A]: 1.14 13 | # Electron Affinity [kJ/mol]: 134.068 14 | # Electronegativity (Pauling scale): 1.9 15 | # Ionisation energies [kJ/mol]: 1st 786.518; 2nd 1577.134; 3rd 3231.585; 4th 4355.523; 5th 16090.571; 6th 19805.55; 7th 23783.6; 8th 29287.16; 16 | znuc=14, 17 | mass=28.085, 18 | # [Ne].3s2.3p2 (Ne: [He].2s2.2p6) 19 | occupations=[ 20 | [ [ 1.0, 1.0 ], [ 1.0, 1.0 ], [ 1.0, 1.0 ], ], # s 21 | [ [ 3.0, 3.0 ], [ 1.0, 1.0 ], ], # p 22 | [ [ 0.0, 0.0 ], ], # d 23 | ], 24 | valenceqns=[ 25 | [3, ], # s 26 | [3, ], # p 27 | [3, ], # d 28 | ], 29 | relativistic=True, 30 | orbitalresolved=True, 31 | # override the d onsite with the value in [1] 32 | # note that gridatom yields very low d-eigenstate 33 | # ideally, we should be able to optimise that 34 | # override_onsite={ (3, 2): 0.113134 }, 35 | override_onsite={ (3, 2): %(Si_Ed)f }, 36 | ), 37 | } 38 | 39 | skbases = { 40 | "Si": SlaterBasis( 41 | exponents=[ 42 | # Geometric progression, very similar to the one used in PBC 43 | [0.4, 0.97, 2.37, 5.75, 14.0], # s 44 | [0.4, 0.97, 2.37, 5.75, 14.0], # p 45 | [0.4, 0.97, 2.37, 5.75, 14.0], # d 46 | ], 47 | maxpowers= [ 48 | 3, # s 49 | 3, # p 50 | 3, # d 51 | ] 52 | ), 53 | } 54 | 55 | compressions = { 56 | "Si": Compression( 57 | # According to [1], exponent for Si is 12.8, and r0 is 4.4 a.u. 58 | # The rule of thumb [2] gives: 1.8*r_cov = 3.88 a.u. 59 | # According to [3], power=4, r0=5.4 is best for 3s3p3d4s basis 60 | potcomp="potential", 61 | potcomp_parameters= [ (4, %(Si_r_sp)f), # s 62 | (4, %(Si_r_sp)f), # p 63 | (4, %(Si_r_d)f), # d 64 | ], 65 | wavecomp="potential", 66 | wavecomp_parameters=[ (4, %(Si_r_sp)f), # s 67 | (4, %(Si_r_sp)f), # p 68 | (4, %(Si_r_d)f), # d 69 | ], 70 | ), 71 | } 72 | -------------------------------------------------------------------------------- /examples/Si-1/skf/skgen-freeatoms.sh: -------------------------------------------------------------------------------- 1 | # With this script we obtain the free atoms from 2 | # all-electron calculation within the prescribed basis, 3 | # regardless of compression radii, and 4 | # regardless of valence orbital intended for dftb: 5 | # NOTABENE: this script must be run in advance, 6 | # and NOT in the optimisation loop 7 | 8 | # skgen expects skdevs.py -> make a link 9 | /bin/ln -sf skdefs.freeatoms.py skdefs.py 10 | 11 | # free atoms 12 | skgen atom -b slateratom Si 13 | 14 | # rm link 15 | /bin/rm skdefs.py 16 | -------------------------------------------------------------------------------- /examples/Si-1/skf/skgen-opt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # this script calculates the two-center integrals 3 | # and assembles the skf tables. 4 | # It must be run in the optimisation loop since we 5 | # are trying to optimise the comporession radii 6 | 7 | # NOTABENE: Do not rm skdefs.py within this script. 8 | # At this stage, it should be the one generated by the optimiser! 9 | 10 | skgen potcomp -b slateratom Si 11 | 12 | # now we skip the wavecomp computation, as we actually want the same 13 | # compression for both waves and density 14 | # make dir if not present; do not complain if there 15 | mkdir -p Si/wavecomp 16 | # clean if directory was there 17 | /bin/rm -f Si/wavecomp/* 18 | # copy relevant files 19 | /bin/cp Si/potcomp/wave_03[spd].dat Si/wavecomp/ 20 | 21 | # twocnt -g 0.2 is for grid spacing -s potential for superposition type 22 | skgen twocnt -g 0.02 -s potential Si Si 23 | 24 | # sktable -d is for dummy repulsive 25 | skgen sktable -d Si Si 26 | -------------------------------------------------------------------------------- /examples/Si-1/skpar_in.yaml: -------------------------------------------------------------------------------- 1 | executables: 2 | skgen: ./skf/skgen-opt.sh # script yielding an skf set 3 | bands: dftbutils bands # band-structure calculation 4 | # see documentation for dftbutils sub-package 5 | 6 | tasks: 7 | # Three types of tasks exist: 8 | # - set: [parmeter_file, working_directory, optional_template_file(s)] 9 | # - run: [command, working_directory] 10 | # - get: [what, from_sourse(dir, file or dict), to_destination(dict), optional_kwargs] 11 | # `what` is essentially a function name (see Get-Tasks dictionary) 12 | # ------------------------------------------------------------------------------ 13 | - set: [current.par, skf, skf/skdefs.template.py] # update ./skf/skdefs.py 14 | - run: [skgen, skf] # generate SKF-set 15 | - run: [bands, Si-diam] # run dftb+ and dp_bands in Si-diam 16 | - get: [get_dftbp_bs, Si-diam/bs, Si.bs, # get BS data and put in Si.bs model DB 17 | {latticeinfo: {type: 'FCC', param: 5.431}}] # must know the lattice for what follows 18 | - get: [get_dftbp_meff, Si.bs, # get electron effective masses 19 | {carriers: 'e', directions: ['Gamma-X'], # note: destination is ommitted, 20 | Erange: 0.005, usebandindex: True}] # hence update the sourse 21 | - get: [get_dftbp_meff, Si.bs, # get hole effective masses 22 | {carriers: 'h', directions: ['Gamma-X', 'Gamma-L', 'Gamma-K'], 23 | nb: 3, Erange: 0.005}] 24 | - get: [get_dftbp_Ek , Si.bs, # get eigen-values at special points 25 | {sympts: ['L', 'Gamma', 'X', 'K'], 26 | extract: {'cb': [0,1,2,3], 'vb': [0,1,2,3]}, 27 | align: 'Evb'}] 28 | 29 | objectives: 30 | 31 | - Egap: # item to be queried from model database 32 | doc: Band-gap of Si (diamond) # doc-string for report purposes (optional) 33 | models: Si.bs # model name must match destination of a get-tasks 34 | ref: 1.12 # explicit reference data in for this objective 35 | weight: 4.0 # relative importance of this objective 36 | # objective weight in the overall cost function 37 | eval: [rms, relerr] # objective function: RMS of relative error 38 | 39 | - effective_masses: # items to be queried here will be defined by 40 | doc: Effective masses, Si # explicit keys, since the reference data consists 41 | models: Si.bs # of key-value pairs 42 | ref: 43 | file: ./ref/meff-Si.dat # the reference data is loaded via numpy.loadtxt() 44 | loader_args: 45 | dtype: # NOTABENE: yaml cannot read in tuples, so we must 46 | # use the dictionary formulation of dtype 47 | names: ['keys', 'values'] 48 | formats: ['S15', 'float'] 49 | options: 50 | subweights: # individual data items have sub-weight within an objective 51 | dflt : 0.1 # changing the default (from 1.) to 0. allows us to consider 52 | me_GX_0: 1.0 # only select entries; alternatively, set select entries 53 | me_Xt_0: 0.0 # to zero effectively excludes them from consideration 54 | weight: 1.0 # objective weight in the overall cost function 55 | eval: [rms, abserr] # objective function: RMS of absolute error 56 | 57 | - special_Ek: 58 | doc: Eigenvalues at k-points of high symmetry 59 | models: Si.bs 60 | ref: 61 | file: ./ref/Ek-Si.dat 62 | loader_args: 63 | dtype: # NOTABENE: yaml cannot read in tuples, so we must 64 | # use the dictionary formulation of dtype 65 | names: ['keys', 'values'] 66 | formats: ['S15', 'float'] 67 | options: 68 | subweights: 69 | dflt : 0.1 # changing the default (from 1.) to 0. allows us to consider 70 | me_GX_0: 1.0 # only select entries; alternatively, set select entries 71 | mh_Xt_0: 0.0 # to zero effectively excludes them from consideration 72 | weight: 1.0 73 | eval: [rms, relerr] 74 | 75 | 76 | optimisation: 77 | algo: PSO # algorithm: particle swarm optimisation 78 | options: 79 | npart: 2 # number of particles 80 | ngen : 2 # number of generations 81 | parameters: 82 | - Si_Ed : 0.1 0.3 # parameter names must match with placeholders in 83 | - Si_r_sp: 3.5 7.0 # template files given to set-tasks above 84 | - Si_r_d : 3.5 8.0 85 | -------------------------------------------------------------------------------- /examples/Si-2/ref/Ek-Si--SOC.dat: -------------------------------------------------------------------------------- 1 | Ec_G_6 4.15 2 | Ec_G_0 3.35 3 | # 4 | Ev_G_0 0.0 5 | Ev_G_2 0.0 6 | Ev_G_4 -0.045 7 | Ev_G_6 -12.5 8 | # 9 | Ec_L_4 4.15 10 | Ec_L_0 2.4 11 | # 12 | Ev_L_0 -1.2 13 | Ev_L_4 -7.0 14 | Ev_L_6 -9.3 15 | # 16 | Ec_K_0 1.7 17 | Ec_K_2 4.79 18 | # 19 | Ev_K_0 -2.47 20 | Ev_K_2 -4.37 21 | Ev_K_4 -7.16 22 | Ev_K_6 -8.15 23 | # 24 | Ec_X_0 1.35 25 | # 26 | Ev_X_0 -2.9 27 | Ev_X_4 -8.01 28 | Ev_X_6 -8.01 29 | -------------------------------------------------------------------------------- /examples/Si-2/ref/Ek-Si.dat: -------------------------------------------------------------------------------- 1 | # assumint 4 valence bands; i.e. without SOC 2 | Ec_G_3 4.15 3 | Ec_G_0 3.35 4 | # 5 | Ev_G_0 0.0 6 | Ev_G_1 0.0 7 | Ev_G_2 -0.045 8 | Ev_G_3 -12.5 9 | # 10 | Ec_L_2 4.15 11 | Ec_L_0 2.4 12 | # 13 | Ev_L_0 -1.2 14 | Ev_L_2 -7.0 15 | Ev_L_3 -9.3 16 | # 17 | Ec_K_0 1.7 18 | Ec_K_1 4.79 19 | # 20 | Ev_K_0 -2.47 21 | Ev_K_1 -4.37 22 | Ev_K_2 -7.16 23 | Ev_K_3 -8.15 24 | # 25 | Ec_X_0 1.35 26 | # 27 | Ev_X_0 -2.9 28 | Ev_X_2 -8.01 29 | Ev_X_3 -8.01 30 | -------------------------------------------------------------------------------- /examples/Si-2/ref/meff-Si--SOC.dat: -------------------------------------------------------------------------------- 1 | me_GX_0 0.916 2 | me_Xt_0 0.19 3 | mh_GX_0 -0.276 4 | mh_GK_0 -0.738 5 | mh_GL_0 -0.579 6 | mh_GX_2 -0.204 7 | mh_GK_2 -0.139 8 | mh_GL_2 -0.147 9 | mh_GX_4 -0.234 10 | mh_GK_4 -0.234 11 | mh_GL_4 -0.234 12 | cbminpos_GX_0 0.85 13 | -------------------------------------------------------------------------------- /examples/Si-2/ref/meff-Si.dat: -------------------------------------------------------------------------------- 1 | # assumint 4 valence bands; i.e. without SOC 2 | me_GX_0 0.916 3 | me_Xt_0 0.19 4 | mh_GX_0 -0.276 5 | mh_GK_0 -0.738 6 | mh_GL_0 -0.579 7 | mh_GX_1 -0.204 8 | mh_GK_1 -0.139 9 | mh_GL_1 -0.147 10 | mh_GX_2 -0.234 11 | mh_GK_2 -0.234 12 | mh_GL_2 -0.234 13 | cbminpos_GX_0 0.85 14 | -------------------------------------------------------------------------------- /examples/Si-2/ref/volen-Si.dat: -------------------------------------------------------------------------------- 1 | 2.316982982356482523e+02 -3.794729662244810675e-01 2 | 2.390923756673737728e+02 -3.839805647820194179e-01 3 | 2.466421121978409303e+02 -3.872759868943164707e-01 4 | 2.543491292759951250e+02 -3.895470583552673727e-01 5 | 2.622150483507815579e+02 -3.908988454815900404e-01 6 | 2.702414908711454018e+02 -3.913664071281811041e-01 7 | 2.784300782860319714e+02 -3.910606160049174274e-01 8 | 2.867824320443864963e+02 -3.900290257367843849e-01 9 | 2.953001735951540923e+02 -3.883779521175089733e-01 10 | 3.039849243872801026e+02 -3.861584032085128571e-01 11 | 3.128383058697098136e+02 -3.834295821704231666e-01 12 | -------------------------------------------------------------------------------- /examples/Si-2/template/Si-diam/100/bs/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "../primcell.gen" 3 | } 4 | 5 | Hamiltonian = DFTB { 6 | SCC = Yes 7 | OrbitalResolvedSCC = Yes 8 | ReadInitialCharges = Yes 9 | MaxSCCIterations = 1 10 | SlaterKosterFiles = Type2FileNames { 11 | Prefix = "../../../skf/" 12 | Separator = "-" 13 | Suffix = ".skf" 14 | LowerCaseTypeName = No 15 | } 16 | MaxAngularMomentum { 17 | Si = "d" 18 | } 19 | Filling = Fermi { 20 | Temperature [Kelvin] = 0.0 21 | } 22 | KPointsAndWeights = Klines { 23 | 1 0.500 0.000 0.500 # X 24 | 19 0.000 0.000 0.000 # Gamma 25 | 1 0.000 0.000 0.000 # Gamma 26 | 19 0.375 0.375 0.750 # K, equiv. to U 27 | 1 0.375 0.375 0.750 # K, equiv. to U 28 | 19 0.500 0.500 0.500 # L 29 | 1 0.500 0.500 0.500 # L 30 | 19 0.000 0.000 0.000 # Gamma 31 | } 32 | # SpinPolarisation = {} 33 | # SpinOrbit = { Si [eV] = {0.0 +0.037 0.0} } 34 | } 35 | -------------------------------------------------------------------------------- /examples/Si-2/template/Si-diam/100/primcell.gen: -------------------------------------------------------------------------------- 1 | 2 F 2 | Si 3 | 1 1 0.000000000000000 0.000000000000000 0.000000000000000 4 | 2 1 0.250000000000000 0.250000000000000 0.25000000000000 5 | 0.000000000000000 0.000000000000000 0.000000000000000 6 | 2.715500000000000 2.715500000000000 0.000000000000000 7 | 0.000000000000000 2.715500000000000 2.715500000000000 8 | 2.715500000000000 0.000000000000000 2.715500000000000 9 | -------------------------------------------------------------------------------- /examples/Si-2/template/Si-diam/100/scc/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "../primcell.gen" 3 | } 4 | 5 | Hamiltonian = DFTB { 6 | SCC = Yes 7 | SCCTolerance = 1e-8 8 | OrbitalResolvedSCC = Yes 9 | ReadInitialCharges = No 10 | MaxSCCIterations = 100 11 | SlaterKosterFiles = Type2FileNames { 12 | Prefix = "../../../skf/" 13 | Separator = "-" 14 | Suffix = ".skf" 15 | LowerCaseTypeName = No 16 | } 17 | MaxAngularMomentum { 18 | Si = "d" 19 | } 20 | Filling = Fermi { 21 | Temperature [Kelvin] = 0.0 22 | } 23 | KPointsAndWeights = SupercellFolding { 24 | 16 0 0 25 | 0 16 0 26 | 0 0 16 27 | 0.5 0.5 0.5 28 | } 29 | # SpinPolarisation = {} 30 | # SpinOrbit = { Si [eV] = {0.0 +0.037 0.0} } 31 | } 32 | -------------------------------------------------------------------------------- /examples/Si-2/template/skf/skdefs.freeatoms.py: -------------------------------------------------------------------------------- 1 | # References: 2 | # [1] Wahiduzzaman et al, JCTC 2013 _9_, exponent for Si is 12.8, and r0 is 4.4 a.u. 3 | # [2] Elstner et al, Phys Rev B 98 4 | # [3] A. Sieck, PhD. Thesis, University of Paderborn, 2000 5 | 6 | atomconfigs = { 7 | "Si": AtomConfig( 8 | # Data from http://www.rsc.org/periodic-table/element/14/silicon 9 | # ---------------------------------------------------------------------- 10 | # [Ne].3s2.3p2 (Ne: [He].2s2.2p6) 11 | # Atomic Radius (non-bonded) [A]: 2.1 12 | # Covalent Radius [A]: 1.14 13 | # Electron Affinity [kJ/mol]: 134.068 14 | # Electronegativity (Pauling scale): 1.9 15 | # Ionisation energies [kJ/mol]: 1st 786.518; 2nd 1577.134; 3rd 3231.585; 4th 4355.523; 5th 16090.571; 6th 19805.55; 7th 23783.6; 8th 29287.16; 16 | znuc=14, 17 | mass=28.085, 18 | # [Ne].3s2.3p2 (Ne: [He].2s2.2p6) 19 | occupations=[ 20 | [ 21 | [1.0, 1.0], 22 | [1.0, 1.0], 23 | [1.0, 1.0], 24 | ], # s 25 | [ 26 | [3.0, 3.0], 27 | [1.0, 1.0], 28 | ], # p 29 | [ 30 | [0.0, 0.0], 31 | ], # d 32 | ], 33 | valenceqns=[ 34 | [ 35 | 3, 36 | ], # s 37 | [ 38 | 3, 39 | ], # p 40 | [ 41 | 3, 42 | ], # d 43 | ], 44 | relativistic=True, 45 | orbitalresolved=True, 46 | # override the d onsite with the value in [1] 47 | # note that gridatom yields very low d-eigenstate 48 | # ideally, we should be able to optimise that 49 | override_onsite={(3, 2): 0.113134}, 50 | ), 51 | } 52 | 53 | skbases = { 54 | "Si": SlaterBasis( 55 | exponents=[ 56 | # Geometric progression, very similar to the one used in PBC 57 | [0.4, 0.97, 2.37, 5.75, 14.0], # s 58 | [0.4, 0.97, 2.37, 5.75, 14.0], # p 59 | [0.4, 0.97, 2.37, 5.75, 14.0], # d 60 | ], 61 | maxpowers=[ 62 | 3, # s 63 | 3, # p 64 | 3, # d 65 | ], 66 | ), 67 | } 68 | 69 | compressions = { 70 | "Si": Compression( 71 | # According to [1], exponent for Si is 12.8, and r0 is 4.4 a.u. 72 | # The rule of thumb [2] gives: 1.8*r_cov = 3.88 a.u. 73 | # According to [3], power=4, r0=5.4 is best for 3s3p3d4s basis 74 | potcomp="potential", 75 | potcomp_parameters=[ 76 | (4, 5.4), # s 77 | (4, 5.4), # p 78 | (4, 5.4), # d 79 | ], 80 | wavecomp="potential", 81 | wavecomp_parameters=[ 82 | (4, 5.4), # s 83 | (4, 5.4), # p 84 | (4, 5.4), # d 85 | ], 86 | ), 87 | } 88 | -------------------------------------------------------------------------------- /examples/Si-2/template/skf/skdefs.template.py: -------------------------------------------------------------------------------- 1 | # References: 2 | # [1] Wahiduzzaman et al, JCTC 2013 _9_, exponent for Si is 12.8, and r0 is 4.4 a.u. 3 | # [2] Elstner et al, Phys Rev B 98 4 | # [3] A. Sieck, PhD. Thesis, University of Paderborn, 2000 5 | 6 | atomconfigs = { 7 | "Si": AtomConfig( 8 | # Data from http://www.rsc.org/periodic-table/element/14/silicon 9 | # ---------------------------------------------------------------------- 10 | # [Ne].3s2.3p2 (Ne: [He].2s2.2p6) 11 | # Atomic Radius (non-bonded) [A]: 2.1 12 | # Covalent Radius [A]: 1.14 13 | # Electron Affinity [kJ/mol]: 134.068 14 | # Electronegativity (Pauling scale): 1.9 15 | # Ionisation energies [kJ/mol]: 1st 786.518; 2nd 1577.134; 3rd 3231.585; 4th 4355.523; 5th 16090.571; 6th 19805.55; 7th 23783.6; 8th 29287.16; 16 | znuc=14, 17 | mass=28.085, 18 | # [Ne].3s2.3p2 (Ne: [He].2s2.2p6) 19 | occupations=[ 20 | [ [ 1.0, 1.0 ], [ 1.0, 1.0 ], [ 1.0, 1.0 ], ], # s 21 | [ [ 3.0, 3.0 ], [ 1.0, 1.0 ], ], # p 22 | [ [ 0.0, 0.0 ], ], # d 23 | ], 24 | valenceqns=[ 25 | [3, ], # s 26 | [3, ], # p 27 | [3, ], # d 28 | ], 29 | relativistic=True, 30 | orbitalresolved=True, 31 | # override the d onsite with the value in [1] 32 | # note that gridatom yields very low d-eigenstate 33 | # ideally, we should be able to optimise that 34 | # override_onsite={ (3, 2): 0.113134 }, 35 | override_onsite={ (3, 2): %(Si_Ed)f }, 36 | ), 37 | } 38 | 39 | skbases = { 40 | "Si": SlaterBasis( 41 | exponents=[ 42 | # Geometric progression, very similar to the one used in PBC 43 | [0.4, 0.97, 2.37, 5.75, 14.0], # s 44 | [0.4, 0.97, 2.37, 5.75, 14.0], # p 45 | [0.4, 0.97, 2.37, 5.75, 14.0], # d 46 | ], 47 | maxpowers= [ 48 | 3, # s 49 | 3, # p 50 | 3, # d 51 | ] 52 | ), 53 | } 54 | 55 | compressions = { 56 | "Si": Compression( 57 | # According to [1], exponent for Si is 12.8, and r0 is 4.4 a.u. 58 | # The rule of thumb [2] gives: 1.8*r_cov = 3.88 a.u. 59 | # According to [3], power=4, r0=5.4 is best for 3s3p3d4s basis 60 | potcomp="potential", 61 | potcomp_parameters= [ (4, %(Si_r_sp)f), # s 62 | (4, %(Si_r_sp)f), # p 63 | (4, %(Si_r_d)f), # d 64 | ], 65 | wavecomp="potential", 66 | wavecomp_parameters=[ (4, %(Si_r_sp)f), # s 67 | (4, %(Si_r_sp)f), # p 68 | (4, %(Si_r_d)f), # d 69 | ], 70 | ), 71 | } 72 | -------------------------------------------------------------------------------- /examples/Si-2/template/skf/skgen-freeatoms.sh: -------------------------------------------------------------------------------- 1 | # With this script we obtain the free atoms from 2 | # all-electron calculation within the prescribed basis, 3 | # regardless of compression radii, and 4 | # regardless of valence orbital intended for dftb: 5 | # NOTABENE: this script must be run in advance, 6 | # and NOT in the optimisation loop 7 | 8 | # skgen expects skdevs.py -> make a link 9 | /bin/ln -sf skdefs.freeatoms.py skdefs.py 10 | 11 | # free atoms 12 | skgen atom -b slateratom Si 13 | 14 | # rm link 15 | /bin/rm skdefs.py 16 | -------------------------------------------------------------------------------- /examples/Si-2/template/skf/skgen-opt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # this script calculates the two-center integrals 3 | # and assembles the skf tables. 4 | # It must be run in the optimisation loop since we 5 | # are trying to optimise the comporession radii 6 | 7 | # NOTABENE: Do not rm skdefs.py within this script. 8 | # At this stage, it should be the one generated by the optimiser! 9 | 10 | skgen potcomp -b slateratom Si 11 | 12 | # now we skip the wavecomp computation, as we actually want the same 13 | # compression for both waves and density 14 | # make dir if not present; do not complain if there 15 | mkdir -p Si/wavecomp 16 | # clean if directory was there 17 | /bin/rm -f Si/wavecomp/* 18 | # copy relevant files 19 | /bin/cp Si/potcomp/wave_03[spd].dat Si/wavecomp/ 20 | 21 | # twocnt -g 0.2 is for grid spacing -s potential for superposition type 22 | skgen twocnt -g 0.02 -s potential Si Si 23 | 24 | # sktable -d is for dummy repulsive 25 | skgen sktable -d Si Si 26 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | description-file = README.txt 3 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (C) 2013 - 2017 Stanislav Markov 4 | # Please see the accompanying LICENSE file for further information. 5 | 6 | from setuptools import setup 7 | from os.path import join 8 | import os 9 | import sys 10 | 11 | if sys.version_info < (3, 0, 0, "final", 0): 12 | raise SystemExit("Python 3 is required!") 13 | 14 | name = "skpar" 15 | short_description = ( 16 | "Optimisation of Slater-Koster files (.skf) " 17 | + "for density functional-based tight binding (DFTB)" 18 | ) 19 | long_description = open("README.txt").read() 20 | 21 | version = "0.2.4" 22 | 23 | package_dir = { 24 | "skpar": "skpar", 25 | } 26 | 27 | packages = [] 28 | for dirname, dirnames, filenames in os.walk("skpar"): 29 | if "__init__.py" in filenames: 30 | packages.append(dirname.replace("/", ".")) 31 | 32 | package_data = {} 33 | 34 | scripts = [ 35 | "bin/skpar", 36 | "bin/dftbutils", 37 | "bin/check_dftblog", 38 | "bin/skpar_splinerepfit", 39 | "bin/skpar_addrepulsive", 40 | ] 41 | 42 | ## try to cater for windows 43 | if "sdist" in sys.argv or os.name in ["ce", "nt"]: 44 | for s in scripts[:]: 45 | print("Making .bat files for Windows") 46 | scripts.append(s + ".bat") 47 | 48 | # data_files needs (directory, files-in-this-directory) tuples 49 | data_files = [] 50 | 51 | setup( 52 | name=name, 53 | version=version, 54 | description=short_description, 55 | long_description=long_description, 56 | url="https://github.com/smarkov/skpar", 57 | download_url="https://github.com/smarkov/skpar/archive/{}.tar.gz".format(version), 58 | author="Stanislav Markov, The University of Hong Kong", 59 | author_email="figaro@hku.hk", 60 | keywords=[ 61 | "dftb", 62 | "slater-koster integrals", 63 | "dftb+", 64 | "lodestar", 65 | "particle swarm optimisation", 66 | "optimisation", 67 | "pso", 68 | "skpar", 69 | ], 70 | license="MIT", 71 | platforms=["any"], 72 | packages=packages, 73 | package_dir=package_dir, 74 | package_data=package_data, 75 | scripts=scripts, 76 | data_files=data_files, 77 | install_requires=["numpy", "scipy", "deap", "pyyaml", "matplotlib"], 78 | classifiers=[], 79 | ) 80 | -------------------------------------------------------------------------------- /skpar/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/skpar/__init__.py -------------------------------------------------------------------------------- /skpar/core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/skpar/core/__init__.py -------------------------------------------------------------------------------- /skpar/core/database.py: -------------------------------------------------------------------------------- 1 | """Database and query objects. 2 | """ 3 | import numpy as np 4 | from skpar.core.utils import get_logger 5 | 6 | LOGGER = get_logger(__name__) 7 | 8 | 9 | def update(database, model, data=None): 10 | """Update model storage with input data items. 11 | 12 | Args: 13 | database(obj): supporting get() and update() 14 | model(str or dict): model (dict) or model name 15 | data(dict): key-value items for the model to be updated 16 | """ 17 | if data is None: 18 | data = {} 19 | try: 20 | # model is a key and in DB; update it with data 21 | database.get(model, None).update(data) 22 | except (KeyError, AttributeError): 23 | # model is a key but not in DB; None has no .update() 24 | database.update({model: data}) 25 | except TypeError: 26 | # model is a dict; not hashable 27 | assert data == {}, data 28 | database.update(model) 29 | 30 | 31 | class Database: 32 | """A database object providing several methods to access/modify the data.""" 33 | 34 | def __init__(self): 35 | """Yield an object for data storage, NOT to be accessed directly.""" 36 | self._storage = {} 37 | 38 | def clear(self): 39 | """Clear the contents of DB""" 40 | self._storage = {} 41 | 42 | def update(self, model, data=None): 43 | """Update storage with a new model""" 44 | update(self._storage, model, data) 45 | 46 | def get(self, model, default=None): 47 | """Get a model.""" 48 | return self._storage.get(model, default) 49 | 50 | def get_item(self, model, item): 51 | """Get an item from a model; None if either does not exist.""" 52 | return self._storage.get(model, {}).get(item, None) 53 | 54 | def all(self): 55 | """Yield internal database object""" 56 | return self._storage 57 | 58 | # legacy stuff; will likely disappear when refactoring objectives 59 | def query(self, models, item, atleast_1d=True): 60 | """Return the value of an item from a model or a list of models.""" 61 | _query = Query(models, item, self) 62 | return _query(atleast_1d=atleast_1d) 63 | 64 | 65 | class Query: 66 | """Decouple the declaration of query from performing a query.""" 67 | 68 | def __init__(self, model_names, key, database=None): 69 | """Instantiate a query to be performed later by calling it. 70 | 71 | A call to the object will result in: 72 | database.model.key or 73 | [database.model1.key, database.model2.key, ...] 74 | depending on the number of model names provided 75 | Note that it is mandatory to provide support for database being passed 76 | to __call__ instead of __init__. This way the same queries may be 77 | duplicated and later called in parallel with different databases 78 | 79 | Args: 80 | model_names: level-one keys in the database 81 | key: level-two keys 82 | database: where the search should be performed; could be provided 83 | at call time instead of initialisation 84 | """ 85 | self.database = database 86 | self.model_names = model_names 87 | self.key = key 88 | 89 | def __call__(self, database=None, atleast_1d=True): 90 | """Execute data query. 91 | 92 | Args: 93 | database: database; should not be needed 94 | atleast_1d: return numpy.array even if data is a float 95 | 96 | Return: 97 | The result of the query - as a numpy array by default. 98 | """ 99 | if database is None: 100 | database = self.database 101 | assert database is not None 102 | if isinstance(self.model_names, list): 103 | result = [] 104 | for model in self.model_names: 105 | result.append(database.get(model, {}).get(self.key)) 106 | else: 107 | result = database.get(self.model_names, {}).get(self.key) 108 | if atleast_1d: 109 | result = np.atleast_1d(result) 110 | return result 111 | 112 | def __repr__(self): 113 | """Yield a summary of the query.""" 114 | srepr = [] 115 | srepr.append("\tQuery key: {}".format(self.key)) 116 | srepr.append("\tModel Names: {}".format(self.model_names)) 117 | if self.database: 118 | srepr.append("\tQuery result: {}".format(self.__call__())) 119 | return "\n" + "\n".join(srepr) 120 | -------------------------------------------------------------------------------- /skpar/core/input.py: -------------------------------------------------------------------------------- 1 | """ 2 | Routines to handle the input file of skpar 3 | """ 4 | import os 5 | import json 6 | import yaml 7 | import skpar.core.taskdict as coretd 8 | from skpar.core.utils import get_logger 9 | from skpar.core.objectives import set_objectives 10 | from skpar.core.tasks import get_tasklist, check_taskdict 11 | from skpar.core.tasks import initialise_tasks 12 | from skpar.core.optimise import get_optargs 13 | from skpar.core.usertasks import update_taskdict 14 | 15 | LOGGER = get_logger(__name__) 16 | 17 | 18 | def get_input(filename): 19 | """Read input; Exception for non-existent file.""" 20 | _, intype = os.path.splitext("filename") 21 | with open(filename, "r") as infile: 22 | if intype == "json": 23 | try: 24 | spec = json.load(infile) 25 | except (ValueError, json.JSONDecodeError): 26 | # json.JSONDecodeError is available only python3.5 onwards 27 | LOGGER.critical("Input not a valid JSON") 28 | raise 29 | else: 30 | # if intype == 'yaml': 31 | try: 32 | spec = yaml.safe_load(infile) 33 | except yaml.YAMLError: 34 | LOGGER.warning("Input not a valid YAML") 35 | raise 36 | return spec 37 | 38 | 39 | def parse_input(filename, verbose=True): 40 | """Parse input filename and return the setup""" 41 | userinp = get_input(filename) 42 | # 43 | # CONFIG 44 | configinp = userinp.get("config", None) 45 | config = get_config(configinp, report=True) 46 | # 47 | # OPTIMISATION 48 | optinp = userinp.get("optimisation", None) 49 | optimisation = get_optargs(optinp) 50 | # 51 | # TASKS 52 | taskdict = {} 53 | usermodulesinp = userinp.get("usermodules", None) 54 | # Note the statement below emulates a yaml-like input which delivers 55 | # a list of [module, [list of functions]] items. 56 | update_taskdict(taskdict, [[coretd.__name__, list(coretd.TASKDICT.keys())]]) 57 | # Import user tasks after the core ones, to allow potential 58 | # replacement of `taskdict` entries with user-defined functions 59 | if usermodulesinp: 60 | update_taskdict(taskdict, usermodulesinp) 61 | # 62 | taskinp = userinp.get("tasks", None) 63 | tasklist = get_tasklist(taskinp) 64 | check_taskdict(tasklist, taskdict) 65 | # do trial initialisation in order to report what and how's been parsed 66 | # no assignment means we discard the tasks list here 67 | initialise_tasks(tasklist, taskdict, report=True) 68 | # 69 | # OBJECTIVES 70 | objectivesinp = userinp.get("objectives", None) 71 | objectives = set_objectives(objectivesinp, verbose=verbose) 72 | # 73 | return taskdict, tasklist, objectives, optimisation, config 74 | 75 | 76 | def get_config(userinp, report=True): 77 | """Parse the arguments of 'config' key in user input""" 78 | if userinp is None: 79 | userinp = {} 80 | config = {} 81 | workroot = userinp.get("workroot", None) 82 | if workroot is not None: 83 | workroot = os.path.abspath(os.path.expanduser(workroot)) 84 | config["workroot"] = workroot 85 | templatedir = userinp.get("templatedir", None) 86 | if templatedir is not None: 87 | templatedir = os.path.abspath(os.path.expanduser(templatedir)) 88 | config["templatedir"] = templatedir 89 | config["keepworkdirs"] = userinp.get("keepworkdirs", False) 90 | # related to interpretation of input file 91 | if report: 92 | LOGGER.info("The following configuration was understood:") 93 | for key, val in config.items(): 94 | LOGGER.info("%s: %s", key, val) 95 | return config 96 | -------------------------------------------------------------------------------- /skpar/core/notes.rst: -------------------------------------------------------------------------------- 1 | Generalising tasks: 2 | ====================================================================== 3 | 4 | Purpose: 5 | -------------------------------------------------- 6 | Allow simple extensions via user modules without touching 7 | the main code base 8 | 9 | Concept: 10 | -------------------------------------------------- 11 | Taks are now very simpler objects, holding a name, 12 | corresponding callable, and user arguments to be 13 | passed to the task. 14 | They have a __call__(), during which implicit args 15 | from the caller are passed: environment dictionary 16 | and, database (reference?). 17 | So the actual call to the function corresonding to 18 | the task is: 19 | func(environment, database, *useraargs, **userkwargs) 20 | Since in yaml/json we cannot specify **kwargs, we 21 | parse the userargs and make userargs[-1] into 22 | userkwargs. All mapping arguments can be passed this 23 | way to the user function, and the ones not explicitly 24 | used are passed to further callables inside the function. 25 | This enables to pass arguments to np.loadtxt or to 26 | matplotlib, or to subprocess.check_call etc. 27 | 28 | Aliases: 29 | -------------------------------------------------- 30 | Support for these is dropped at present. 31 | Better to introduce $var instead of old 32 | implementation, to avoid surprises where user 33 | decide to use an identifier that was already 34 | defined as an alias, leading to random behaviour. 35 | 36 | 37 | Parallelism: 38 | -------------------------------------------------- 39 | Task now acquire environment data at call time. 40 | No variable items are held during their 41 | initialisation. 42 | Tasks are now instantiated inside the call of 43 | the evaluator, so that multiple evaluations 44 | (hence multiple instances of the same task) 45 | can be run with different parameters at the same 46 | time. 47 | 48 | 49 | What tasks we can have: 50 | -------------------------------------------------- 51 | :executables: 52 | task name is 'execute' 53 | task arguments: executable, command-line arguments 54 | executed via os.subprocess 55 | 56 | :core functions: 57 | task name is the function name 58 | task arguments are the function arguments 59 | called directly 60 | part of the code 61 | declared in task_dictionary 62 | 63 | 64 | :user functions: 65 | task name is the function name 66 | task arguments are the function arguments 67 | called directly 68 | imported via implib, see usertasks.py 69 | usertasks.py must contain TASKDICT 70 | which will update (potentially could replace) 71 | the global task dict. 72 | declared in task_dictionary 73 | 74 | 75 | 76 | Working with JSON input: 77 | ====================================================================== 78 | Done. 79 | 80 | 81 | 82 | Refactor Objectives: 83 | ====================================================================== 84 | 85 | 86 | 87 | Parameters: 88 | ====================================================================== 89 | Parameter values are now passed to evaluator who does not hold any 90 | reference to the original Parameters list established during parsing 91 | of user input. 92 | Evaluator now holds only parameter names. 93 | Both these points are mandatory to enable parallel calls to evaluator. 94 | -------------------------------------------------------------------------------- /skpar/core/optimise.py: -------------------------------------------------------------------------------- 1 | """Defines a wrapper around user selectable optimisation engines. 2 | """ 3 | import sys 4 | from deap.base import Toolbox 5 | 6 | # skpar 7 | from skpar.core.utils import get_logger 8 | from skpar.core.evaluate import Evaluator 9 | from skpar.core.pso import PSO 10 | from skpar.core.pscan import PSCAN 11 | from skpar.core.parameters import get_parameters 12 | 13 | OPTENGINES = {"pso": PSO, "pscan": PSCAN} 14 | 15 | LOGGER = get_logger(__name__) 16 | 17 | 18 | def get_optargs(userinp): 19 | """Parse user input for optimisation related arguments.""" 20 | try: 21 | algo = userinp.get("algo", "pso").lower() 22 | options = userinp.get("options", {}) 23 | try: 24 | parameters = get_parameters(userinp["parameters"]) 25 | except KeyError as exc: 26 | LOGGER.critical( 27 | "Parameters must be defined under" 'optimisation" in the input file.' 28 | ) 29 | LOGGER.critical(exc) 30 | sys.exit(2) 31 | return algo, options, parameters 32 | except AttributeError: 33 | return None 34 | 35 | 36 | class Optimiser(object): 37 | """Wrapper for different optimization engines.""" 38 | 39 | def __init__(self, algo, parameters, evaluate, options=None, verbose=True): 40 | try: 41 | self.optengine = OPTENGINES[algo] 42 | except KeyError: 43 | LOGGER.critical("Unsupported optimisation algorithm %s", algo) 44 | sys.exit(2) 45 | self.evaluate = evaluate 46 | self.parameters = parameters 47 | if options is None: 48 | options = {} 49 | self.optimise = OPTENGINES[algo](self.parameters, self.evaluate, **options) 50 | self.logger = LOGGER 51 | # report all tasks and objectives 52 | if verbose: 53 | log = self.logger.info 54 | else: 55 | log = self.logger.debug 56 | log("Algorithm: {}".format(algo)) 57 | for item in parameters: 58 | log(item) 59 | 60 | def __call__(self, **kwargs): 61 | output = self.optimise(**kwargs) 62 | return output 63 | 64 | def report(self, *args, **kwargs): 65 | """Report optimiser state.""" 66 | try: 67 | self.optimise.report(*args, **kwargs) 68 | except AttributeError: 69 | # assume optimiser does not have a report method 70 | pass 71 | -------------------------------------------------------------------------------- /skpar/core/skpar.py: -------------------------------------------------------------------------------- 1 | """Main environment of SKPAR""" 2 | import os 3 | import logging 4 | import numpy as np 5 | from skpar.core.utils import get_logger 6 | from skpar.core.input import parse_input 7 | from skpar.core.evaluate import Evaluator 8 | from skpar.core.optimise import Optimiser 9 | 10 | 11 | class SKPAR: 12 | """The main executable object.""" 13 | 14 | def __init__(self, infile="skpar_in.yaml", verbose=True): 15 | 16 | # setup logger 17 | # ------------------------------------------------------------------- 18 | loglevel = logging.DEBUG if verbose else logging.INFO 19 | self.logger = get_logger(name="skpar", filename="skpar.log", verbosity=loglevel) 20 | # specific for printing/reporting from numpy objects 21 | np.set_printoptions(threshold=60, linewidth=79, suppress=True) 22 | 23 | # Project work directory 24 | # ------------------------------------------------------------------- 25 | self.workdir = os.getcwd() 26 | 27 | # Main part 28 | # ------------------------------------------------------------------- 29 | # parse input file 30 | self.logger.info("Parsing input file {:s}".format(infile)) 31 | taskdict, tasklist, objectives, optimisation, config = parse_input( 32 | infile, verbose=verbose 33 | ) 34 | if optimisation is not None: 35 | algo, options, parameters = optimisation 36 | parnames = [p.name for p in parameters] 37 | else: 38 | parnames = None 39 | 40 | # instantiate the evaluator machinery 41 | self.logger.info("Instantiating Evaluator") 42 | self.evaluator = Evaluator( 43 | objectives, tasklist, taskdict, parnames, config, verbose=verbose 44 | ) 45 | 46 | # instantiate the optimiser 47 | if optimisation is not None: 48 | self.do_optimisation = True 49 | self.logger.info("Instantiating Optimiser") 50 | self.optimiser = Optimiser( 51 | algo, parameters, self.evaluator, options, verbose=True 52 | ) 53 | else: 54 | self.do_optimisation = False 55 | 56 | def __call__(self, evalonly=False): 57 | if self.do_optimisation and not evalonly: 58 | # run the optimiser 59 | self.logger.info("Starting optimisation") 60 | self.optimiser() 61 | # issue final report 62 | self.optimiser.report() 63 | self.logger.info("Done.") 64 | else: 65 | # no parameters: pass None to evaluator 66 | fitness = self.evaluator(None) 67 | self.logger.debug("Global fitness: {}".format(fitness)) 68 | 69 | def __repr__(self): 70 | lines = [] 71 | return "\n".join(lines) 72 | -------------------------------------------------------------------------------- /skpar/core/tasks.py: -------------------------------------------------------------------------------- 1 | """Tasks module, defining relevant classes and functions""" 2 | import sys 3 | from skpar.core.utils import get_logger 4 | 5 | LOGGER = get_logger(__name__) 6 | 7 | # TODO: get_tasklist below assumes the legacy definition of tasks in userinput: 8 | # '- taskname: [list_of_task_arguments]'. 9 | # It should be possible to provide an alternative definition: 10 | # '- [taskname, task_argument1, .....task_argumentN]' 11 | # A flag in config file could allow user to select either way. 12 | def get_tasklist(userinp): 13 | """Return a list of tuples of task names and task arguments.""" 14 | if userinp is None: 15 | LOGGER.critical('Missing "tasks:" in user input; Nothing to do. Bye!') 16 | sys.exit(1) 17 | tasklist = [] 18 | for item in userinp: 19 | # due to json/yaml specifics, a task is represented as a dictionary with 20 | # one item only, hence the comma after task, avoiding looping over items 21 | ((taskname, taskargs),) = item.items() 22 | task = (taskname, taskargs) 23 | tasklist.append(task) 24 | return tasklist 25 | 26 | 27 | def check_taskdict(tasklist, taskdict): 28 | """Check task names are in the task dictionary; quit otherwise.""" 29 | for task in tasklist: 30 | if task[0] not in taskdict.keys(): 31 | LOGGER.critical( 32 | "Task {:s} not in TASKDICT; Cannot continue".format(task[0]) 33 | ) 34 | LOGGER.info("Check spelling and verify import of user modules") 35 | LOGGER.info("Use `usermodules: [lisf of modules]` in input") 36 | LOGGER.info( 37 | "TASKDICT currently contains:\n\t{:s}".format( 38 | "\n\t".join( 39 | [ 40 | "{:s}: {}".format(name, func) 41 | for name, func in taskdict.items() 42 | ] 43 | ) 44 | ) 45 | ) 46 | sys.exit(1) 47 | 48 | 49 | def initialise_tasks(tasklist, taskdict, report=False): 50 | """Transform a tasklist into a list of callables as per taskdict. 51 | 52 | Args: 53 | tasklist(list): a list of (task-name, user-arguments) pairs 54 | taskdict(dict): a dictionary mapping task names to actual functions 55 | 56 | Returns: 57 | tasks(list): callable objects, instances of Task class 58 | """ 59 | LOGGER.info("Initialising tasks") 60 | tasks = [] 61 | for taskname, argslist in tasklist: 62 | func = taskdict[taskname] 63 | assert isinstance( 64 | argslist, (list, tuple) 65 | ), "Make sure task arguments are within []; IsString?: {}".format( 66 | isinstance(argslist, str) 67 | ) 68 | tasks.append(Task(taskname, func, argslist)) 69 | 70 | if report: 71 | LOGGER.info("The following tasks will be executed at each iteration.") 72 | for i, task in enumerate(tasks): 73 | LOGGER.info("Task {:d}:\t{:s}".format(i, task.__repr__())) 74 | return tasks 75 | 76 | 77 | class Task: 78 | """Generic wrapper over functions or executables.""" 79 | 80 | def __init__(self, name, func, fargs): 81 | """Create a callable object from user input. 82 | 83 | Note: `fargs` are user defined function arguments. 84 | The function call via the __call__() method of this class allows 85 | for other arguments to be passed by the caller. 86 | 87 | Note: `fargs` is parsed so that if the last item in the list is a dict, 88 | then fargs[-1] becomes **kwargs while fargs[:-1] becomes *args 89 | for the function call 90 | 91 | Args: 92 | name(str): name of the task (to appear in logs) 93 | func(callable): the function being called by __call__() 94 | fargs(list): list of arguments to be passed to func. 95 | """ 96 | self.name = name 97 | self.func = func 98 | # treat last argument as kwargs if dict 99 | if isinstance(fargs[-1], dict): 100 | self.args = fargs[:-1] 101 | self.kwargs = fargs[-1] 102 | else: 103 | self.args = fargs 104 | self.kwargs = {} 105 | 106 | # 107 | def __call__(self, env, database): 108 | """Execute the task, let caller handle any exception raised by func 109 | 110 | Args: 111 | env(dict): a dictionary with implicitly passed args 112 | database(object or dict): a database object serving for data 113 | exchange 114 | """ 115 | self.func(env, database, *self.args, **self.kwargs) 116 | 117 | # 118 | def __repr__(self): 119 | """Yield a summary of the task.""" 120 | srepr = [] 121 | srepr.append("{:s}: {}".format(self.name, self.func)) 122 | if self.args: 123 | srepr.append( 124 | "\t\t\t {:d} args: {:s}".format( 125 | len(self.args), 126 | ", ".join(["{}".format(str(arg)) for arg in self.args]), 127 | ) 128 | ) 129 | if self.kwargs: 130 | srepr.append( 131 | "\t\t\t{:d} kwargs: {:s}".format( 132 | len(self.kwargs.keys()), 133 | ", ".join( 134 | ["{}: {}".format(key, val) for key, val in self.kwargs.items()] 135 | ), 136 | ) 137 | ) 138 | return "\n".join(srepr) 139 | -------------------------------------------------------------------------------- /skpar/core/usertasks.py: -------------------------------------------------------------------------------- 1 | """Enable support for user-defined tasks, dynamically imported at runtime. 2 | 3 | 4 | Any function that is intended to perform a task must be present as a 5 | 'task_name': 'callable_object' item in a dictionary called `TASKDICT` in the 6 | user module that is to be imported by skpar at run time. 7 | 8 | The desired TASKDICT should be ideally inside an installed package. 9 | Alternatively, modules must be found using the standard Python import mechanism, 10 | i.e. must be placed along sys.path. 11 | 12 | .. note:: sys.path is not ever modified; consider using PYTHONPATH in the shell 13 | 14 | :task_name: 15 | task name used in the ``tasks`` section the input file 16 | 17 | :callable object: 18 | the corresponding callable in the user module, that performs the task 19 | 20 | .. note:: that TASKDICT is all capital letters! 21 | 22 | 23 | There are three ways to import tasks from user modules, as per example below: 24 | 25 | .. code:: yaml 26 | 27 | usermodules: 28 | # 1 29 | - mypackage.amodule 30 | # 2 31 | - [mypackage.amodule, alias] 32 | # 3 33 | - [mypackage.amodule, [taskname1, taskname2, ]] 34 | 35 | Each of the three cases mandates different ways to refer to the tasks later in 36 | the ``tasks`` section: 37 | 38 | 1. mypackage.amodule.taskname : .... 39 | 40 | 2. alias.taskname : .... 41 | 42 | 3. taskname1 : .... 43 | 44 | .. note:: The third case allows to overwrite core skpar tasks. 45 | 46 | """ 47 | from importlib import import_module 48 | from skpar.core.utils import get_logger 49 | 50 | LOGGER = get_logger(__name__) 51 | 52 | 53 | def import_taskdict(modname): 54 | """Import user module and return its name and TASKDICT""" 55 | try: 56 | mod = import_module(modname) 57 | except (ImportError, ModuleNotFoundError): 58 | LOGGER.critical("Module %s not found. " "Check it is along PYTHONPATH", modname) 59 | raise 60 | try: 61 | modtd = getattr(mod, "TASKDICT") 62 | except AttributeError: 63 | LOGGER.critical( 64 | "Module %s has no TASKDICT; " "Please, remove it from input, to continue.", 65 | mod.__name__, 66 | ) 67 | raise 68 | return mod.__name__, modtd 69 | 70 | 71 | def tag_dictkeys(tag, dictionary): 72 | """Return the dictionary with tagged keys of the form 'tag.key'""" 73 | tagged = {} 74 | for key, val in dictionary.items(): 75 | tagged[tag + "." + key] = val 76 | return tagged 77 | 78 | 79 | def update_taskdict(taskdict, userinp): 80 | """Update taskdict with tasks from modules described in user input. 81 | 82 | Provides support for the following userinp: 83 | 84 | .. code:: yaml 85 | 86 | usermodules: 87 | # 88 | # user must use modulename.taskname in tasks section 89 | - modulename 90 | # 91 | # user must use modulealias.taskname in tasks section 92 | - [modulename, modulealias] 93 | # 94 | # user must use taskname only in tasks section 95 | - [modulename, [taskname1, taskname2, ...]] 96 | 97 | Args: 98 | taskdict(dict): dictionary to be updated 99 | userinp(list or str): list of modules or a string (single module) 100 | 101 | Returns: 102 | None 103 | 104 | Raises: 105 | AttributeError if an explicit task is not found in user's module TASKDICT 106 | """ 107 | # Make sure we always have a list to work on, else userinp is a string, 108 | # and will be decomposed into characters 109 | if isinstance(userinp, str): 110 | userinp = [userinp] 111 | for item in userinp: 112 | if not isinstance(item, list): 113 | # treat as a module name; get all tasks 114 | modname, modtd = import_taskdict(item) 115 | taskdict.update(tag_dictkeys(modname, modtd)) 116 | else: 117 | modname, modtd = import_taskdict(item[0]) 118 | if isinstance(item[1], list): 119 | # an explicit list of task names to import; do not tag 120 | for key in item[1]: 121 | try: 122 | taskdict[key] = modtd[key] 123 | except KeyError: 124 | LOGGER.critical( 125 | "Task name %s not in %s's TASKDICT", key, modname 126 | ) 127 | raise 128 | else: 129 | # alias the module name 130 | taskdict.update(tag_dictkeys(item[1], modtd)) 131 | -------------------------------------------------------------------------------- /skpar/dftbutils/__init__.py: -------------------------------------------------------------------------------- 1 | from .taskdict import TASKDICT 2 | -------------------------------------------------------------------------------- /skpar/dftbutils/evol.py: -------------------------------------------------------------------------------- 1 | """Executable for calculating Energy versus Strain with DFTB+""" 2 | import os 3 | from os.path import abspath, expanduser 4 | from os.path import join as joinpath 5 | import logging 6 | import argparse 7 | from skpar.dftbutils.utils import get_logger, execute 8 | 9 | 10 | def set_evol_parser(parser=None): 11 | """Define parser options specific for energy-volume scan. 12 | 13 | Parameters: 14 | 15 | parser: python parser 16 | Typically, that will be a sub-parser passed from top executable. 17 | """ 18 | # Initialise argument parser if not provided 19 | if parser is None: 20 | parser = argparse.ArgumentParser( 21 | description="Calculate total energy vs volume dependence." 22 | ) 23 | subparser = False 24 | else: 25 | subparser = True 26 | # Once we have a parser, we can add arguments to it 27 | parser.add_argument( 28 | "-v", 29 | dest="verbose", 30 | default=False, 31 | action="store_true", 32 | help="Raise verbosity level from INFO to DEBUG for the console.", 33 | ) 34 | parser.add_argument( 35 | "-p", 36 | "--plot", 37 | dest="plot", 38 | default=False, 39 | action="store_true", 40 | help="Unsupported: Plot the energy-volume curve.", 41 | ) 42 | parser.add_argument( 43 | "-wd", 44 | dest="workdir", 45 | type=str, 46 | default=".", 47 | action="store", 48 | help="(default: .) Working directory with sub-folders, " 49 | "each sub-folder is for an scc calculation at a " 50 | "specific volume. The execution is in workdir/strain/scc/)", 51 | ) 52 | parser.add_argument( 53 | "-sccdir", 54 | dest="sccdir", 55 | type=str, 56 | default=".", 57 | action="store", 58 | help="(default: the strain folder) Sub-directory under the " 59 | "strain-folders, where the scc calculation for a specific " 60 | "strain is performed. ", 61 | ) 62 | parser.add_argument( 63 | "-dftb", 64 | type=str, 65 | default="dftb+", 66 | action="store", 67 | help="(default: dftb+) dftb executable", 68 | ) 69 | if subparser: 70 | parser.set_defaults(func=main_evol) 71 | return None 72 | else: 73 | return parser 74 | 75 | 76 | def main_evol(args): 77 | """ 78 | Chain the relevant tasks for scanning an energy-volume dependence. 79 | 80 | The key concept/assumption is that we pass only a main directory under 81 | which there are a set of sub-directories named by three digits, 82 | e.g. 099/ 100/ 101/ 102/, where the calculation for a specific volume 83 | is set up in advance. 84 | 85 | Currently this implies serial operation. MPI parallelism over the 86 | different volumes is necessary, but not implemented yet. 87 | """ 88 | # setup logger 89 | # ------------------------------------------------------------------- 90 | loglevel = logging.DEBUG if args.verbose else logging.INFO 91 | logger = get_logger( 92 | name="dftbutils", filename="dftbutils.evol.log", verbosity=loglevel 93 | ) 94 | 95 | # any arguments related to the dftb executable 96 | dftb = args.dftb 97 | dftblog = "dftb.log" 98 | 99 | # deal with e-vol-specific arguments if any 100 | # -------------------------------------------------- 101 | # `workdir` is the main directory; under it there should be a 102 | # sub-folder for each volume. 103 | workdir = abspath(expanduser(args.workdir)) 104 | sccdir = args.sccdir 105 | cwd = os.getcwd() 106 | os.chdir(workdir) 107 | # Automatically establish the available directories for different volumes. 108 | # We are imposing that under strain directory there is an `scc` directory, 109 | # which may not be such a good idea, but allows to have also `bs` for a 110 | # given strain. 111 | strain_dirs = [dd for dd in os.listdir() if dd.isdigit()] 112 | for _dir in strain_dirs: 113 | calcdir = joinpath(workdir, _dir, sccdir) 114 | execute(cmd=dftb, workdir=calcdir, outfile=dftblog) 115 | # Note that dftb+ (at least v1.2) exits with 0 status even if there are 116 | # ERRORS. Therefore, below we ensure we stop in such case, rather than 117 | # diffusing the problem through attempts of subsequent operations. 118 | # check_dftblog is a bash script in skpar/bin/ but this can be moved to 119 | # python instead 120 | execute(cmd=["check_dftblog", dftblog], workdir=sccdir, outfile="chk.log") 121 | os.chdir(cwd) 122 | -------------------------------------------------------------------------------- /skpar/dftbutils/taskdict.py: -------------------------------------------------------------------------------- 1 | """ 2 | Provide mapping between task names available to user and actual functions. 3 | """ 4 | from skpar.core.utils import get_logger 5 | from skpar.dftbutils.queryDFTB import get_dftbp_data, get_bandstructure 6 | from skpar.dftbutils.queryDFTB import get_dftbp_evol 7 | from skpar.dftbutils.queryDFTB import get_effmasses, get_special_Ek 8 | from skpar.dftbutils.plot import magic_plot_bs 9 | 10 | LOGGER = get_logger(__name__) 11 | 12 | TASKDICT = { 13 | # obtain data from model evaluations 14 | "get_data": get_dftbp_data, 15 | "get_evol": get_dftbp_evol, 16 | "get_bs": get_bandstructure, 17 | "get_meff": get_effmasses, 18 | "get_Ek": get_special_Ek, 19 | # plot data 20 | # this one is currently used via the wrapper of PlotTask in ../core/taskdict.py 21 | "plot_bs": magic_plot_bs, 22 | } 23 | -------------------------------------------------------------------------------- /test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/test/__init__.py -------------------------------------------------------------------------------- /test/example-tasks.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | templatedir: test_optimise 3 | workroot: _workdir/test_optimise 4 | keepworkdirs: true 5 | 6 | tasks: 7 | # single template file 8 | - sub: [template.parameters.dat] 9 | # list of template files (one or more items, incl. path) 10 | - sub: [template-1.dat, template-2.dat] 11 | # 12 | # executable command without any further arguments, no need for '' 13 | - run: [python3 model_poly3.py] 14 | # executable command with optional workdir and outfile 15 | - run: ['exe -someoption', somedir, somefile] 16 | # 17 | # get item from file, and put in DB(implicit) as destination.item 18 | - get: [item, from_source, to_destination] 19 | # get item named `key`, process as per options and put in DB[model][key] 20 | - get: [key, source_file, modelname, {scale: 1.5, rm_rows: 2.0}] 21 | 22 | -------------------------------------------------------------------------------- /test/examplt-balint.yaml: -------------------------------------------------------------------------------- 1 | 2 | tasks: 3 | - plot: {bands: ['C_vb', 'C_cb'], gap: C_Egap} 4 | 5 | 6 | objectives: 7 | 8 | bs_diamond: 9 | doc: Some compilicated things 10 | values: MoS2_ml.totalenergy_volume 11 | refs: MoS2_ml_vasp_pbe.totalenergy_volume 12 | weight: 1.0 13 | subweights: [1.0, 2.0, 3.0, 2.0, 1.0] 14 | eval: [rms, relerr] 15 | 16 | 17 | SiC_Eheat: 18 | doc: We will calculate the SiC heat of formation 19 | values: [SiC.Etot, Si.2.Etot, C.2.Etot] 20 | factors: [0.5, -0.5, -0.5] 21 | refs: [SiC_2_pbe_vasp.Etot, Si_2_pbe_vasp.Etot, C_2_pbe_vasp.Etot] 22 | weight: 1.0 23 | eval: [relerr] 24 | 25 | 26 | C_vb: 27 | 28 | 29 | C_cb: 30 | 31 | 32 | C_Egap: 33 | values: ... 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /test/reference_data/Ek-Si.dat: -------------------------------------------------------------------------------- 1 | Ec_G_6 4.15 2 | Ec_G_0 3.35 3 | # 4 | Ev_G_0 0.0 5 | Ev_G_2 0.0 6 | Ev_G_4 -0.045 7 | Ev_G_6 -12.5 8 | # 9 | Ec_L_4 4.15 10 | Ec_L_0 2.4 11 | # 12 | Ev_L_0 -1.2 13 | Ev_L_4 -7.0 14 | Ev_L_6 -9.3 15 | # 16 | Ec_K_0 1.7 17 | Ec_K_2 4.79 18 | # 19 | Ev_K_0 -2.47 20 | Ev_K_2 -4.37 21 | Ev_K_4 -7.16 22 | Ev_K_6 -8.15 23 | # 24 | Ec_X_0 1.35 25 | # 26 | Ev_X_0 -2.9 27 | Ev_X_4 -8.01 28 | Ev_X_6 -8.01 29 | -------------------------------------------------------------------------------- /test/reference_data/fakebands-2.dat: -------------------------------------------------------------------------------- 1 | 1 -1.198 -0.799 -0.596 0.195 0.748 2 | 2 -0.909 -0.655 -0.527 0.125 0.560 3 | 3 -0.693 -0.548 -0.475 0.069 0.396 4 | 4 -0.531 -0.464 -0.434 0.033 0.257 5 | 5 -0.427 -0.413 -0.404 0.012 0.138 6 | 6 -0.405 -0.400 -0.396 0.001 0.055 7 | 7 -0.431 -0.416 -0.408 -0.023 0.009 8 | 8 -0.531 -0.466 -0.436 -0.058 0.029 9 | 9 -0.689 -0.540 -0.472 -0.077 0.072 10 | 10 -0.911 -0.657 -0.527 -0.078 0.125 11 | 11 -1.198 -0.798 -0.600 -0.055 0.201 12 | -------------------------------------------------------------------------------- /test/reference_data/fakebands-2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/test/reference_data/fakebands-2.pdf -------------------------------------------------------------------------------- /test/reference_data/fakebands-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/test/reference_data/fakebands-2.png -------------------------------------------------------------------------------- /test/reference_data/fakebands.dat: -------------------------------------------------------------------------------- 1 | 1 -1.200 -1.200 -0.800 -0.600 0.200 0.750 0.950 1.000 2 | 2 -1.272 -0.912 -0.656 -0.528 0.128 0.562 0.716 0.748 3 | 3 -1.328 -0.688 -0.544 -0.472 0.072 0.398 0.534 0.552 4 | 4 -1.368 -0.528 -0.464 -0.432 0.032 0.258 0.404 0.412 5 | 5 -1.392 -0.432 -0.416 -0.408 0.008 0.142 0.326 0.328 6 | 6 -1.400 -0.400 -0.400 -0.400 0.000 0.050 0.300 0.300 7 | 7 -1.392 -0.432 -0.416 -0.408 -0.018 0.008 0.326 0.328 8 | 8 -1.368 -0.528 -0.464 -0.432 -0.062 0.032 0.404 0.412 9 | 9 -1.328 -0.688 -0.544 -0.472 -0.082 0.072 0.534 0.552 10 | 10 -1.272 -0.912 -0.656 -0.528 -0.078 0.128 0.716 0.748 11 | 11 -1.200 -1.200 -0.800 -0.600 -0.050 0.200 0.950 1.000 12 | -------------------------------------------------------------------------------- /test/reference_data/fakebands.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/test/reference_data/fakebands.pdf -------------------------------------------------------------------------------- /test/reference_data/fakebands.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/test/reference_data/fakebands.png -------------------------------------------------------------------------------- /test/reference_data/meff-Si.dat: -------------------------------------------------------------------------------- 1 | me_GX_0 0.916 2 | me_Xt_0 0.19 3 | mh_GX_0 -0.276 4 | mh_GK_0 -0.738 5 | mh_GL_0 -0.579 6 | mh_GX_2 -0.204 7 | mh_GK_2 -0.139 8 | mh_GL_2 -0.147 9 | mh_GX_4 -0.234 10 | mh_GK_4 -0.234 11 | mh_GL_4 -0.234 12 | cbminpos_GX_0 0.85 13 | -------------------------------------------------------------------------------- /test/reference_data/refdata_example.dat: -------------------------------------------------------------------------------- 1 | # 10 col, 7 rows 2 | 0 1 2 3 4 5 6 7 8 9 3 | 0 1 2 3 4 5 6 7 8 9 4 | 0 1 2 3 4 5 6 7 8 9 5 | 0 1 2 3 4 5 6 7 8 9 6 | 0 1 2 3 4 5 6 7 8 9 7 | 0 1 2 3 4 5 6 7 8 9 8 | 0 1 2 3 4 5 6 7 8 9 9 | -------------------------------------------------------------------------------- /test/reference_data/volen-Si.dat: -------------------------------------------------------------------------------- 1 | 2.316982982356482523e+02 -3.794729662244810675e-01 2 | 2.390923756673737728e+02 -3.839805647820194179e-01 3 | 2.466421121978409303e+02 -3.872759868943164707e-01 4 | 2.543491292759951250e+02 -3.895470583552673727e-01 5 | 2.622150483507815579e+02 -3.908988454815900404e-01 6 | 2.702414908711454018e+02 -3.913664071281811041e-01 7 | 2.784300782860319714e+02 -3.910606160049174274e-01 8 | 2.867824320443864963e+02 -3.900290257367843849e-01 9 | 2.953001735951540923e+02 -3.883779521175089733e-01 10 | 3.039849243872801026e+02 -3.861584032085128571e-01 11 | 3.128383058697098136e+02 -3.834295821704231666e-01 12 | -------------------------------------------------------------------------------- /test/sandbox_fargs.py: -------------------------------------------------------------------------------- 1 | def func(a, b, *args, **kwargs): 2 | print(a, b) 3 | for arg in args: 4 | print(arg) 5 | for key, val in kwargs.items(): 6 | print(key, val) 7 | 8 | 9 | def func2(a, b, c=30, d=40, **kwargs): 10 | print(a, b) 11 | print(c, d) 12 | for key, val in kwargs.items(): 13 | print(key, val) 14 | 15 | 16 | def func3(a, b, c=100, d=200): 17 | print(a, b) 18 | print(c, d) 19 | 20 | 21 | a = 1 22 | b = 2 23 | c = 3 24 | d = 4 25 | e = {"k1": 10, "k2": 20} 26 | print("w/o args/kwargs") 27 | func(a, b) 28 | print("w/ args") 29 | func(a, b, (c, d)) 30 | print("w/ *args and kwargs") 31 | func(a, b, *(c, d), e) 32 | print("w/ *args and **kwargs") 33 | func(a, b, *(c, d), **e) 34 | 35 | print("w/ **kwargs") 36 | f = {"d": d, "c": c} 37 | f.update(e) 38 | func(a, b, **f) 39 | 40 | print("func2 w/ **kwargs") 41 | f = {"d": d, "c": c} 42 | f.update(e) 43 | func2(a, b, **f) 44 | 45 | print("func2 w/ **kwargs") 46 | # f = {'d': d, 'c': c} 47 | f = {} 48 | f.update(e) 49 | func2(a, b, **f) 50 | 51 | print("func3 w/ ") 52 | func3(a, b, c, d, **{}) 53 | -------------------------------------------------------------------------------- /test/sandbox_subprocess.py: -------------------------------------------------------------------------------- 1 | from subprocess import Popen, check_output, PIPE, STDOUT, check_call 2 | import os 3 | import shlex 4 | import glob 5 | 6 | 7 | def call(cmd, **kwargs): 8 | if not isinstance(cmd, list): 9 | cmd = shlex.split(cmd) 10 | parsed_cmd = [ 11 | cmd[0], 12 | ] 13 | for i, word in enumerate(cmd[1:]): 14 | if word[0] == "$": 15 | var = word[1:].strip("{").strip("}") 16 | varval = os.environ.get(var, word) 17 | parsed_cmd.append(varval) 18 | else: 19 | if "*" in word: 20 | items = glob.glob(word) 21 | for item in items: 22 | parsed_cmd.append(item) 23 | else: 24 | parsed_cmd.append(word) 25 | cmd = parsed_cmd 26 | out = check_output(cmd, universal_newlines=True, stderr=STDOUT, **kwargs) 27 | return out 28 | 29 | 30 | cmd = "python --version" 31 | print(call(cmd)) 32 | 33 | cmd = "echo $HOME ${SHELL}" 34 | print(call(cmd)) 35 | 36 | cmd = "ls test*.yaml" 37 | print(call(cmd)) 38 | 39 | cmd = "echo 5" 40 | print(call(cmd)) 41 | -------------------------------------------------------------------------------- /test/skpar_in_Si.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | config: 3 | templatedir: test_dftbutils/Si/bs 4 | workroot: _workdir/test_Si 5 | keepworkdirs: true 6 | 7 | usermodules: 8 | - [skpar.dftbutils, [get_bs, get_Ek, get_meff] ] 9 | # What to do when evaluating a point in parameter space 10 | tasks: 11 | #- set: [parfile, workdir, optional_arguments] 12 | ## for run-tasks, command includes command-line arguments 13 | ## while workdir is optional; default being current (top level) 14 | #- run: [command, workdir] 15 | #- get: [what, from_source(dir, file or dict), to_destination (dict), 16 | # optional_keywordarguments] 17 | #- set: [current.par, test_dftbutils/skf, skdefs.template.py] 18 | #- run: [skgen, skf, ] 19 | #- run: [bs_dftb, Si, ] 20 | #- run: [bs_dftb, SiO2, ] 21 | # Note that once SKPAR sees a dictionary name, it adds it to the QueryDB 22 | # and subsequently, if it sees the same name as a source argument, it 23 | # will use it as a dictionary source database. Hence, user will not be able 24 | # to read a directory of the same name as a dictionary name twice. 25 | # The way around is to make dictionary names and directory names different. 26 | # E.g. a dictionary 'Si/bs' will shadow a directory 'Si/bs' after the 27 | # first task with 'Si/bs' dictionary is registered. To overcome this, 28 | # use './Si/bs' for the directory name and 'Si/bs' for the dictionary name 29 | # or avoid using / in the dictionary names, e.g. use 'Si.bs' instead 30 | - get_bs: ['.', Si.bs, {latticeinfo: {type: 'FCC', param: 5.431}}] 31 | # below we omit the destination, and results will update source dictionary 32 | - get_meff: [Si.bs, {carriers: 'e', directions: ['Gamma-X'], 33 | Erange: 0.005, usebandindex: True}] 34 | - get_meff: [Si.bs, {carriers: 'h', 35 | directions: ['Gamma-X', 'Gamma-L', 'Gamma-K'], 36 | nb: 5, Erange: 0.0015}] 37 | - get_meff: [Si.bs, {carriers: 'h', 38 | directions: ['Gamma-X', 'Gamma-L', 'Gamma-K'], 39 | nb: 3, Erange: 0.008}] 40 | - get_meff: [Si.bs, {carriers: 'h', 41 | directions: ['Gamma-X', 'Gamma-L', 'Gamma-K'], 42 | nb: 1, Erange: 0.002, usebandindex: True}] 43 | # note the use of the 'align: 'Evb'', which is to align the Ek with 44 | # the 0 energy of the reference data 45 | - get_Ek: [Si.bs, {sympts: ['L', 'Gamma', 'X', 'K'], 46 | extract: {'cb': [0,2,4,6], 'vb': [0,2,4,6]}, 47 | align: 'Evb'}] 48 | 49 | 50 | # Individual objectives 51 | objectives: 52 | - Egap: 53 | doc: Band-gap of Si (diamond) 54 | models: Si.bs 55 | ref: 1.12 56 | weight: 4.0 57 | eval: [rms, relerr] 58 | - effective_masses: 59 | doc: Effective masses, Si 60 | models: Si.bs 61 | ref: 62 | file: ./reference_data/meff-Si.dat 63 | loader_args: 64 | dtype: 65 | # NOTABENE: yaml cannot read in tuples, so we must 66 | # use the dictionary formulation of dtype 67 | names: ['keys', 'values'] 68 | formats: ['S15', 'float'] 69 | options: 70 | subweights: 71 | # changing the default (from 1.) to 0. allows us to consider 72 | dflt : 0.1 73 | # only select entries; alternatively, set select entries 74 | me_GX_0: 1.0 75 | # to zero effectively excludes them from consideration 76 | me_Xt_0: 0.0 77 | weight: 1.0 78 | eval: [rms, abserr] 79 | - special_Ek: 80 | doc: Eigenvalues at k-points of symmetry 81 | models: Si.bs 82 | ref: 83 | file: ./reference_data/Ek-Si.dat 84 | loader_args: 85 | dtype: 86 | # NOTABENE: yaml cannot read in tuples, so we must 87 | # use the dictionary formulation of dtype 88 | names: ['keys', 'values'] 89 | formats: ['S15', 'float'] 90 | options: 91 | subweights: 92 | # changing the default (from 1.) to 0. allows us to consider 93 | dflt : 0.1 94 | # only select entries; alternatively, set select entries 95 | me_GX_0: 1.0 96 | # to zero effectively excludes them from consideration 97 | mh_Xt_0: 0.0 98 | weight: 1.0 99 | eval: [rms, relerr] 100 | 101 | 102 | # How to define a global criterion of success/fitness 103 | # Note that the definition of individual objectives 104 | # decalres its own scalarisation procedure, 105 | # while this field remains for the global objective function. 106 | # CURRENTLY NOT SUPPORTED. Defaults are below 107 | # criterion: 108 | # # details of the objective function 109 | # objfun: WES # weighted exponential sum 110 | # objfunpar: 111 | # exp: 2 # exponent 112 | ... 113 | -------------------------------------------------------------------------------- /test/skpar_in_optimise.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | templatedir: test_optimise 3 | workroot: ./_workdir/test_optimise 4 | keepworkdirs: true 5 | 6 | tasks: 7 | - set: [[template.parameters.dat]] 8 | - run: ['python3 model_poly3.py'] 9 | - get: [yval, model_poly3_out.dat, poly3] 10 | 11 | objectives: 12 | - yval: 13 | doc: 3-rd order polynomial values for some values of the argument 14 | models: poly3 15 | ref: [ 36.55, 26.81875, 10., 13.43125, 64.45 ] 16 | eval: [rms, relerr] 17 | 18 | optimisation: 19 | algo: PSO # particle swarm optimisation 20 | options: 21 | npart: 4 # number of particles 22 | ngen : 8 # number of generations 23 | parameters: 24 | - c0: 9.95 10.05 25 | - c1: -2.49 -2.51 26 | - c2: 0.499 0.501 27 | - c3: 0.0499 0.0501 28 | -------------------------------------------------------------------------------- /test/skpar_in_optimise_and_plot.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | templatedir: test_optimise 3 | workroot: ./_workdir/test_optimise_and_plot 4 | keepworkdirs: true 5 | 6 | tasks: 7 | - set: [[template.parameters.dat]] 8 | - run: ['python3 model_poly3.py'] 9 | - get: [yval, model_poly3_out.dat, poly3] 10 | - get: [yval, model_poly3_out.dat, poly3-2] 11 | - get: [xval, model_poly3_xval.dat, poly3] 12 | - get: [xval, model_poly3_xval.dat, poly3-2] 13 | - plot: [skparplot, 'polyfit1', [2], xval] 14 | - plot: [skparplot, 'polyfit2', [[yval, poly3]], xval] 15 | - plot: [skparplot, 'polyfit3', [[yval, poly3], [yval, poly3-2]], xval, 16 | {colors: ['b', 'r', 'g', 'm'], marker:[None, 'o']}] 17 | # currently blah will not yield and plot will pick up skparplot 18 | - plot: [blah, 'polyfit2a', [[yval, poly3-2]]] 19 | # directory must be either absolutised or relative to workroot/iteration 20 | # e.g. 21 | # - get: [get_model_data, 22 | # /home/username/projects/skpar-pr1/skpar/test/reference_data/fakebands-2.dat, 23 | # fakemodel, bands] 24 | - get: [bands, ../../../reference_data/fakebands-2.dat, fakemodel, 25 | {rm_columns: [1], unpack: True}] 26 | - plot: [skparplot, 'fakebandsplot', [[bands, fakemodel]]] 27 | 28 | objectives: 29 | - bands: 30 | models: fakemodel 31 | ref: 32 | # path is relative to SKPAR invokation directory 33 | file: ./reference_data/fakebands.dat 34 | loader_args: {unpack: True} 35 | process: 36 | rm_columns: [1, 2, [8, 9]] 37 | 38 | - yval: 39 | doc: 3-rd order polynomial values for some values of the argument 40 | models: poly3 41 | ref: [ 36.55, 26.81875, 10., 13.43125, 64.45 ] 42 | eval: [rms, relerr] 43 | 44 | - yval: 45 | doc: 3-rd order polynomial values for some values of the argument 46 | models: poly3-2 47 | ref: [ 36.55, 26.81875, 10., 13.43125, 64.45 ] 48 | eval: [rms, relerr] 49 | 50 | optimisation: 51 | algo: PSO # particle swarm optimisation 52 | options: 53 | npart: 2 #4 # number of particles 54 | ngen : 2 #5 # number of generations 55 | parameters: 56 | - c0: 5 15 #9.95 10.05 57 | - c1: -2.49 -2.51 58 | - c2: 0.499 0.501 59 | - c3: 0.0499 0.0501 60 | -------------------------------------------------------------------------------- /test/skpar_in_pscan.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | templatedir: test_pscan 3 | workroot: ./_workdir/test_pscan 4 | keepworkdirs: true 5 | 6 | tasks: 7 | - set: [[template.parameters.dat]] 8 | - run: ['python model_poly3.py'] 9 | - get: [yval, model_poly3_out.dat, poly3] 10 | 11 | objectives: 12 | - yval: 13 | doc: 3-rd order polynomial values for some values of the argument 14 | models: poly3 15 | ref: [ 36.55, 26.81875, 10., 13.43125, 64.45 ] 16 | eval: [rms, relerr] 17 | 18 | optimisation: 19 | algo: PSCAN # scan of the parameter space 20 | parameters: 21 | - c0: 3 9.0 11.0 22 | - c1: 3 -3.0 -2.0 23 | - c2: 1 0.5 0.5 24 | - c3: 1 0.05 0.05 25 | -------------------------------------------------------------------------------- /test/test_database.py: -------------------------------------------------------------------------------- 1 | """Test operation of DB and its methods""" 2 | import unittest 3 | import numpy.testing as nptest 4 | from skpar.core.database import Query, Database, update 5 | 6 | 7 | class DBTest(unittest.TestCase): 8 | """Database test""" 9 | 10 | def test_database(self): 11 | """Can we update model DB""" 12 | database = Database() 13 | self.assertTrue(database is not None) 14 | # 15 | database.update("m1", {"i1": 42}) 16 | self.assertDictEqual(database.all(), {"m1": {"i1": 42}}) 17 | # 18 | database.update("m1", {"i1": 33}) 19 | self.assertDictEqual(database.all(), {"m1": {"i1": 33}}) 20 | # 21 | database.update("m2", {"i1": 10}) 22 | self.assertDictEqual(database.all(), {"m1": {"i1": 33}, "m2": {"i1": 10}}) 23 | # 24 | database.update("m2", {"i2": 20}) 25 | self.assertDictEqual( 26 | database.all(), {"m1": {"i1": 33}, "m2": {"i1": 10, "i2": 20}} 27 | ) 28 | update(database, "m1", {"i2": 25}) 29 | self.assertDictEqual( 30 | database.all(), {"m1": {"i1": 33, "i2": 25}, "m2": {"i1": 10, "i2": 20}} 31 | ) 32 | database.update({"m2": {"i3": 40}}) 33 | self.assertDictEqual( 34 | database.all(), {"m1": {"i1": 33, "i2": 25}, "m2": {"i3": 40}} 35 | ) 36 | # 37 | mdb = database.get("m2") 38 | self.assertDictEqual(mdb, {"i3": 40}) 39 | self.assertEqual(database.get_item("m1", "i2"), 25) 40 | # 41 | # check query initialised without database 42 | query = Query("m2", "i1") 43 | self.assertEqual(query(database, atleast_1d=False), None) 44 | query = Query("m2", "i3") 45 | self.assertEqual(query(database, atleast_1d=False), 40) 46 | # 47 | # check query initialised with database within database.query method 48 | self.assertEqual(database.query("m1", "i1", atleast_1d=False), 33) 49 | nptest.assert_array_equal(database.query("m1", "i1"), [33]) 50 | # 51 | database.clear() 52 | self.assertDictEqual(database.all(), {}) 53 | 54 | 55 | if __name__ == "__main__": 56 | unittest.main() 57 | -------------------------------------------------------------------------------- /test/test_dftbutils/Si/UnitCell.gen: -------------------------------------------------------------------------------- 1 | 2 F 2 | Si 3 | 1 1 0.000000000000000 0.000000000000000 0.000000000000000 4 | 2 1 0.250000000000000 0.250000000000000 0.25000000000000 5 | 0.000000000000000 0.000000000000000 0.000000000000000 6 | 2.715500000000000 2.715500000000000 0.000000000000000 7 | 0.000000000000000 2.715500000000000 2.715500000000000 8 | 2.715500000000000 0.000000000000000 2.715500000000000 9 | -------------------------------------------------------------------------------- /test/test_dftbutils/Si/bs/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "../UnitCell.gen" 3 | } 4 | 5 | Hamiltonian = DFTB { 6 | SCC = Yes 7 | # SCCTolerance = 1e-12 8 | OrbitalResolvedSCC = No 9 | ReadInitialCharges = Yes 10 | MaxSCCIterations = 1 11 | SlaterKosterFiles { 12 | Si-Si = "~/.local/share/dftb/skf-dftb.org/siband-1-1/Si-Si.skf" 13 | } 14 | MaxAngularMomentum { 15 | Si = "d" 16 | } 17 | Filling = Fermi { 18 | Temperature [Kelvin] = 0.0 19 | } 20 | KPointsAndWeights = Klines { 21 | 1 0.500 0.500 0.500 # L 22 | 53 0.000 0.000 0.000 # Gamma 23 | 60 0.500 0.000 0.500 # X 24 | 28 0.625 0.250 0.625 # U 25 | 1 0.375 0.375 0.750 # K, equiv. to U 26 | 63 0.000 0.000 0.000 # Gamma 27 | # 1 0.500 0.500 0.500 # L 28 | # 532 0.000 0.000 0.000 # Gamma 29 | # 600 0.500 0.000 0.500 # X 30 | # 276 0.625 0.250 0.625 # U 31 | # 1 0.375 0.375 0.750 # K, equiv. to U 32 | # 632 0.000 0.000 0.000 # Gamma 33 | } 34 | #432 0.000 0.000 0.000 # Gamma 35 | #500 0.500 0.000 0.500 # X 36 | #176 0.625 0.250 0.625 # U 37 | #532 0.000 0.000 0.000 # Gamma 38 | SpinPolarisation = {} 39 | SpinOrbit = { Si [eV] = {0.0 +0.037 0.0} } 40 | } 41 | 42 | Analysis {} 43 | 44 | 45 | Options {} 46 | 47 | ParserOptions { 48 | ParserVersion = 4 49 | } 50 | -------------------------------------------------------------------------------- /test/test_dftbutils/Si/bs/dftb_pin.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | 2 F 3 | Si 4 | 1 1 0.000000000000000 0.000000000000000 0.000000000000000 5 | 2 1 0.250000000000000 0.250000000000000 0.25000000000000 6 | 0.000000000000000 0.000000000000000 0.000000000000000 7 | 2.715500000000000 2.715500000000000 0.000000000000000 8 | 0.000000000000000 2.715500000000000 2.715500000000000 9 | 2.715500000000000 0.000000000000000 2.715500000000000 10 | } 11 | Hamiltonian = DFTB { 12 | SCC = Yes 13 | OrbitalResolvedSCC = No 14 | ReadInitialCharges = Yes 15 | MaxSCCIterations = 1 16 | SlaterKosterFiles = Si-Si { 17 | "~/.local/share/dftb/skf-dftb.org/siband-1-1/Si-Si.skf" 18 | } 19 | MaxAngularMomentum = Si { 20 | "d" 21 | } 22 | Filling = Fermi { 23 | Temperature [Kelvin] = 0.0 24 | IndependentKFilling = No 25 | } 26 | KPointsAndWeights = Klines { 27 | 1 0.500 0.500 0.500 28 | 53 0.000 0.000 0.000 29 | 60 0.500 0.000 0.500 30 | 28 0.625 0.250 0.625 31 | 1 0.375 0.375 0.750 32 | 63 0.000 0.000 0.000 33 | } 34 | SpinPolarisation = {} 35 | SpinOrbit = { 36 | Si [eV] = { 37 | 0.0 +0.037 0.0 38 | } 39 | Dual = No 40 | } 41 | PolynomialRepulsive = {} 42 | OldRepulsiveSum = No 43 | OldSKInterpolation = No 44 | Charge = 0.000000000000000E+000 45 | SCCTolerance = 1.000000000000000E-005 46 | Mixer = Broyden { 47 | MixingParameter = 0.200000000000000 48 | CachedIterations = -1 49 | InverseJacobiWeight = 1.000000000000000E-002 50 | MinimalWeight = 1.00000000000000 51 | MaximalWeight = 100000.000000000 52 | WeightFactor = 1.000000000000000E-002 53 | } 54 | ElectricField = {} 55 | DampXH = No 56 | EwaldParameter = 0.000000000000000E+000 57 | Eigensolver = DivideAndConquer {} 58 | Dispersion = {} 59 | ThirdOrder = No 60 | ThirdOrderFull = No 61 | } 62 | Analysis = ProjectStates {} 63 | Options = { 64 | CalculateForces = No 65 | ConvergentForcesOnly = Yes 66 | WriteEigenvectors = No 67 | WriteAutotestTag = No 68 | WriteDetailedXML = No 69 | WriteResultsTag = No 70 | WriteDetailedOut = Yes 71 | WriteBandOut = Yes 72 | AtomResolvedEnergies = No 73 | RestartFrequency = 20 74 | RandomSeed = 0 75 | WriteHS = No 76 | WriteRealHS = No 77 | MinimiseMemoryUsage = No 78 | ShowFoldedCoords = No 79 | } 80 | ParserOptions = { 81 | ParserVersion = 4 82 | WriteHSDInput = Yes 83 | WriteXMLInput = No 84 | StopAfterParsing = No 85 | IgnoreUnprocessedNodes = No 86 | } 87 | Driver = {} 88 | -------------------------------------------------------------------------------- /test/test_dftbutils/Si/plots-bs/bs_0_0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dftbplus/skpar/4c574a0e2dc4826697b39c7f41cf34210fe79d9b/test/test_dftbutils/Si/plots-bs/bs_0_0.pdf -------------------------------------------------------------------------------- /test/test_dftbutils/Si/scc/dftb_in.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | <<< "../UnitCell.gen" 3 | } 4 | 5 | Hamiltonian = DFTB { 6 | SCC = Yes 7 | SCCTolerance = 1e-8 8 | OrbitalResolvedSCC = No 9 | ReadInitialCharges = No 10 | MaxSCCIterations = 100 11 | SlaterKosterFiles { 12 | Si-Si = "~/.local/share/dftb/skf-dftb.org/siband-1-1/Si-Si.skf" 13 | } 14 | MaxAngularMomentum { 15 | Si = "d" 16 | } 17 | Filling = Fermi { 18 | Temperature [Kelvin] = 0.0 19 | } 20 | KPointsAndWeights = SupercellFolding { 21 | 16 0 0 22 | 0 16 0 23 | 0 0 16 24 | 0.0 0.0 0.0 25 | } 26 | SpinPolarisation = {} 27 | SpinOrbit = { Si [eV] = {0.0 +0.037 0.0} } 28 | } 29 | 30 | Analysis {} 31 | 32 | 33 | Options {} 34 | 35 | ParserOptions { 36 | ParserVersion = 4 37 | } 38 | -------------------------------------------------------------------------------- /test/test_dftbutils/Si/scc/dftb_pin.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | 2 F 3 | Si 4 | 1 1 0.000000000000000 0.000000000000000 0.000000000000000 5 | 2 1 0.250000000000000 0.250000000000000 0.25000000000000 6 | 0.000000000000000 0.000000000000000 0.000000000000000 7 | 2.715500000000000 2.715500000000000 0.000000000000000 8 | 0.000000000000000 2.715500000000000 2.715500000000000 9 | 2.715500000000000 0.000000000000000 2.715500000000000 10 | } 11 | Hamiltonian = DFTB { 12 | SCC = Yes 13 | SCCTolerance = 1e-8 14 | OrbitalResolvedSCC = No 15 | ReadInitialCharges = No 16 | MaxSCCIterations = 100 17 | SlaterKosterFiles = Si-Si { 18 | "~/.local/share/dftb/skf-dftb.org/siband-1-1/Si-Si.skf" 19 | } 20 | MaxAngularMomentum = Si { 21 | "d" 22 | } 23 | Filling = Fermi { 24 | Temperature [Kelvin] = 0.0 25 | IndependentKFilling = No 26 | } 27 | KPointsAndWeights = SupercellFolding { 28 | 16 0 0 29 | 0 16 0 30 | 0 0 16 31 | 0.0 0.0 0.0 32 | } 33 | SpinPolarisation = {} 34 | SpinOrbit = { 35 | Si [eV] = { 36 | 0.0 +0.037 0.0 37 | } 38 | Dual = No 39 | } 40 | PolynomialRepulsive = {} 41 | OldRepulsiveSum = No 42 | OldSKInterpolation = No 43 | Charge = 0.000000000000000E+000 44 | InitialCharges = {} 45 | Mixer = Broyden { 46 | MixingParameter = 0.200000000000000 47 | CachedIterations = -1 48 | InverseJacobiWeight = 1.000000000000000E-002 49 | MinimalWeight = 1.00000000000000 50 | MaximalWeight = 100000.000000000 51 | WeightFactor = 1.000000000000000E-002 52 | } 53 | ElectricField = {} 54 | DampXH = No 55 | EwaldParameter = 0.000000000000000E+000 56 | Eigensolver = DivideAndConquer {} 57 | Dispersion = {} 58 | ThirdOrder = No 59 | ThirdOrderFull = No 60 | } 61 | Analysis = ProjectStates {} 62 | Options = { 63 | CalculateForces = No 64 | ConvergentForcesOnly = Yes 65 | WriteEigenvectors = No 66 | WriteAutotestTag = No 67 | WriteDetailedXML = No 68 | WriteResultsTag = No 69 | WriteDetailedOut = Yes 70 | WriteBandOut = Yes 71 | AtomResolvedEnergies = No 72 | RestartFrequency = 20 73 | RandomSeed = 0 74 | WriteHS = No 75 | WriteRealHS = No 76 | MinimiseMemoryUsage = No 77 | ShowFoldedCoords = No 78 | } 79 | ParserOptions = { 80 | ParserVersion = 4 81 | WriteHSDInput = Yes 82 | WriteXMLInput = No 83 | StopAfterParsing = No 84 | IgnoreUnprocessedNodes = No 85 | } 86 | Driver = {} 87 | -------------------------------------------------------------------------------- /test/test_dftbutils/bs/detailed.out: -------------------------------------------------------------------------------- 1 | Fermi distribution function 2 | 3 | Calculation with static geometry 4 | 5 | 6 | ******************************************************************************** 7 | iSCC Total electronic Diff electronic SCC error 8 | 1 -0.18641356E+02 0.00000000E+00 0.11330148E+00 9 | ******************************************************************************** 10 | 11 | 12 | Net atomic charges (e) 13 | Atom Net charge 14 | 1 0.13645668 15 | 2 0.13645668 16 | 3 -0.01196350 17 | 4 -0.09584680 18 | 5 -0.09584680 19 | 6 -0.06925626 20 | 21 | COMPONENT = q 22 | 23 | Eigenvalues /H 24 | -1.06983783 -1.07064449 -1.07144571 -1.07224109 -1.07303026 -1.07381282 -1.07458841 -1.07535666 25 | ... 26 | 4.17221056 4.17204496 4.17192527 4.17185289 4.17182867 27 | 28 | Eigenvalues /eV 29 | -29.11176851 -29.13371877 -29.15552108 -29.17716467 -29.19863896 -29.21993359 -29.24103845 -29.26194368 30 | ... 31 | 113.53162577 113.52711969 113.52386272 113.52189317 113.52123409 32 | 33 | Fillings 34 | 2.00000 2.00000 2.00000 2.00000 2.00000 2.00000 2.00000 2.00000 35 | ... 36 | 0.00000 0.00000 0.00000 0.00000 0.00000 37 | 38 | Nr. of electrons (up): 32.00000000 39 | Atom populations (up) 40 | Atom Population 41 | 1 3.86354332 42 | 2 3.86354332 43 | 3 6.01196350 44 | 4 6.09584680 45 | 5 6.09584680 46 | 6 6.06925626 47 | 48 | l-shell populations (up) 49 | Atom Sh. l Population 50 | 1 1 0 0.78986556 51 | 1 2 1 1.66837404 52 | 1 3 2 1.40530372 53 | 2 1 0 0.78986556 54 | 2 2 1 1.66837404 55 | 2 3 2 1.40530372 56 | 3 1 0 1.52015447 57 | 3 2 1 4.49180903 58 | 4 1 0 1.51777955 59 | 4 2 1 4.57806726 60 | 5 1 0 1.51777955 61 | 5 2 1 4.57806726 62 | 6 1 0 1.51838536 63 | 6 2 1 4.55087090 64 | 65 | Orbital populations (up) 66 | Atom Sh. l m Population 67 | 1 1 0 0 0.78986556 68 | 1 2 1 -1 0.56454875 69 | 1 2 1 0 0.54587423 70 | 1 2 1 1 0.55795106 71 | 1 3 2 -2 0.24349524 72 | 1 3 2 -1 0.26512216 73 | 1 3 2 0 0.29231294 74 | 1 3 2 1 0.27996015 75 | 1 3 2 2 0.32441323 76 | 2 1 0 0 0.78986556 77 | 2 2 1 -1 0.56454875 78 | 2 2 1 0 0.54587423 79 | 2 2 1 1 0.55795106 80 | 2 3 2 -2 0.24349524 81 | 2 3 2 -1 0.26512216 82 | 2 3 2 0 0.29231294 83 | 2 3 2 1 0.27996015 84 | 2 3 2 2 0.32441323 85 | 3 1 0 0 1.52015447 86 | 3 2 1 -1 1.49762535 87 | 3 2 1 0 1.49990601 88 | 3 2 1 1 1.49427767 89 | 4 1 0 0 1.51777955 90 | 4 2 1 -1 1.52876456 91 | 4 2 1 0 1.51749514 92 | 4 2 1 1 1.53180756 93 | 5 1 0 0 1.51777955 94 | 5 2 1 -1 1.51521448 95 | 5 2 1 0 1.53104522 96 | 5 2 1 1 1.53180756 97 | 6 1 0 0 1.51838536 98 | 6 2 1 -1 1.52153025 99 | 6 2 1 0 1.52381091 100 | 6 2 1 1 1.50552974 101 | 102 | Fermi energy: 0.0364964093 H 0.9931 eV 103 | Band energy: -20.7183623462 H -563.7753 eV 104 | TS: 0.0000000000 H 0.0000 eV 105 | Band free energy (E-TS): -20.7183623462 H -563.7753 eV 106 | Extrapolated E(0K): -20.7183623462 H -563.7753 eV 107 | Input/Output electrons (q): 32.00000000 32.00000000 108 | 109 | Energy H0: -18.6478107504 H -507.4327 eV 110 | Energy SCC: 0.0064544993 H 0.1756 eV 111 | Total Electronic energy: -18.6413562511 H -507.2571 eV 112 | Repulsive energy: 0.0000000000 H 0.0000 eV 113 | Total energy: -18.6413562511 H -507.2571 eV 114 | Total Mermin free energy: -18.6413562511 H -507.2571 eV 115 | 116 | SCC is NOT converged, maximal SCC iterations exceeded 117 | 118 | -------------------------------------------------------------------------------- /test/test_dftbutils/bs/dftb_pin.hsd: -------------------------------------------------------------------------------- 1 | Geometry = GenFormat { 2 | 6 S 3 | Si O 4 | 1 1 0.000000000000000 -0.000000000000000 0.000000000000000 5 | 2 1 -1.847750000000000 -1.847750000000000 1.847750000000000 6 | 3 2 0.923875000000000 0.923875000000000 0.923875000000000 7 | 4 2 -0.923875000000000 -0.923875000000000 0.923875000000000 8 | 5 2 -0.923875000000000 0.923874999999999 -0.923875000000000 9 | 6 2 0.923875000000000 -0.923875000000000 -0.923875000000000 10 | 0.000000000000000 0.000000000000000 0.000000000000000 11 | 3.695500000000000 0.000000000000000 3.695500000000000 12 | 3.695500000000000 3.695500000000000 0.000000000000000 13 | 0.000000000000000 3.695500000000000 3.695500000000000 14 | } 15 | Hamiltonian = DFTB { 16 | SCC = Yes 17 | OrbitalResolvedSCC = Yes 18 | ReadInitialCharges = Yes 19 | MaxSCCIterations = 1 20 | SlaterKosterFiles = Type2FileNames { 21 | Prefix = "../../skf/" 22 | Separator = "-" 23 | Suffix = ".skf" 24 | LowerCaseTypeName = No 25 | } 26 | MaxAngularMomentum = { 27 | Si = "d" 28 | O = "p" 29 | } 30 | Filling = Fermi { 31 | Temperature [Kelvin] = 0.0 32 | IndependentKFilling = No 33 | } 34 | KPointsAndWeights = Klines { 35 | 1 0.5 0.0 0.5 36 | 85 0.0 0.0 0.0 37 | 90 0.375 0.375 0.750 38 | 52 0.5 0.5 0.5 39 | 73 0.0 0.0 0.0 40 | } 41 | PolynomialRepulsive = {} 42 | OldRepulsiveSum = No 43 | OldSKInterpolation = No 44 | Charge = 0.000000000000000E+000 45 | SCCTolerance = 1.000000000000000E-005 46 | Mixer = Broyden { 47 | MixingParameter = 0.200000000000000 48 | CachedIterations = -1 49 | InverseJacobiWeight = 1.000000000000000E-002 50 | MinimalWeight = 1.00000000000000 51 | MaximalWeight = 100000.000000000 52 | WeightFactor = 1.000000000000000E-002 53 | } 54 | ElectricField = {} 55 | DampXH = No 56 | EwaldParameter = 0.000000000000000E+000 57 | SpinPolarisation = {} 58 | Eigensolver = DivideAndConquer {} 59 | Dispersion = {} 60 | ThirdOrder = No 61 | ThirdOrderFull = No 62 | } 63 | ParserOptions = { 64 | ParserVersion = 4 65 | WriteHSDInput = Yes 66 | WriteXMLInput = No 67 | StopAfterParsing = No 68 | IgnoreUnprocessedNodes = No 69 | } 70 | Driver = {} 71 | Analysis = { 72 | ProjectStates = {} 73 | } 74 | Options = { 75 | CalculateForces = No 76 | ConvergentForcesOnly = Yes 77 | WriteEigenvectors = No 78 | WriteAutotestTag = No 79 | WriteDetailedXML = No 80 | WriteResultsTag = No 81 | WriteDetailedOut = Yes 82 | WriteBandOut = Yes 83 | AtomResolvedEnergies = No 84 | RestartFrequency = 20 85 | RandomSeed = 0 86 | WriteHS = No 87 | WriteRealHS = No 88 | MinimiseMemoryUsage = No 89 | ShowFoldedCoords = No 90 | } 91 | -------------------------------------------------------------------------------- /test/test_dftbutils/scc/detailed.out: -------------------------------------------------------------------------------- 1 | Fermi distribution function 2 | 3 | Calculation with static geometry 4 | 5 | 6 | ******************************************************************************** 7 | iSCC Total electronic Diff electronic SCC error 8 | 7 -0.18761162E+02 -0.35527137E-14 0.24990943E-09 9 | ******************************************************************************** 10 | 11 | 12 | Net atomic charges (e) 13 | Atom Net charge 14 | 1 -0.01021170 15 | 2 -0.01021170 16 | 3 0.00510586 17 | 4 0.00510585 18 | 5 0.00510585 19 | 6 0.00510585 20 | 21 | COMPONENT = q 22 | 23 | Eigenvalues /H 24 | -1.10327235 -1.10140945 -1.09714146 -1.09228219 -1.09053904 -1.09376492 -1.09876209 -1.10233430 25 | ... 26 | 4.03651288 4.01821649 3.97584597 3.88861907 3.88054380 3.93438194 3.98556928 4.03503096 27 | 28 | Eigenvalues /eV 29 | -30.02156816 -29.97087615 -29.85473800 -29.72251067 -29.67507708 -29.76285789 -29.89883772 -29.99604236 30 | ... 31 | 109.83910401 109.34123399 108.18827341 105.81470874 105.59496952 107.05997975 108.45285810 109.79877880 32 | 33 | Fillings 34 | 2.00000 2.00000 2.00000 2.00000 2.00000 2.00000 2.00000 2.00000 35 | ... 36 | 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 37 | 38 | Nr. of electrons (up): 32.00000000 39 | Atom populations (up) 40 | Atom Population 41 | 1 4.01021170 42 | 2 4.01021170 43 | 3 5.99489414 44 | 4 5.99489415 45 | 5 5.99489415 46 | 6 5.99489415 47 | 48 | l-shell populations (up) 49 | Atom Sh. l Population 50 | 1 1 0 0.82323246 51 | 1 2 1 1.68104110 52 | 1 3 2 1.50593814 53 | 2 1 0 0.82323246 54 | 2 2 1 1.68104110 55 | 2 3 2 1.50593814 56 | 3 1 0 1.52237552 57 | 3 2 1 4.47251862 58 | 4 1 0 1.52237552 59 | 4 2 1 4.47251863 60 | 5 1 0 1.52237552 61 | 5 2 1 4.47251863 62 | 6 1 0 1.52237552 63 | 6 2 1 4.47251863 64 | 65 | Orbital populations (up) 66 | Atom Sh. l m Population 67 | 1 1 0 0 0.82323246 68 | 1 2 1 -1 0.56034703 69 | 1 2 1 0 0.56034703 70 | 1 2 1 1 0.56034703 71 | 1 3 2 -2 0.27853537 72 | 1 3 2 -1 0.27853537 73 | 1 3 2 0 0.33516602 74 | 1 3 2 1 0.27853537 75 | 1 3 2 2 0.33516602 76 | 2 1 0 0 0.82323246 77 | 2 2 1 -1 0.56034703 78 | 2 2 1 0 0.56034703 79 | 2 2 1 1 0.56034703 80 | 2 3 2 -2 0.27853537 81 | 2 3 2 -1 0.27853537 82 | 2 3 2 0 0.33516602 83 | 2 3 2 1 0.27853537 84 | 2 3 2 2 0.33516602 85 | 3 1 0 0 1.52237552 86 | 3 2 1 -1 1.49083954 87 | 3 2 1 0 1.49083954 88 | 3 2 1 1 1.49083954 89 | 4 1 0 0 1.52237552 90 | 4 2 1 -1 1.49083954 91 | 4 2 1 0 1.49083954 92 | 4 2 1 1 1.49083954 93 | 5 1 0 0 1.52237552 94 | 5 2 1 -1 1.49083954 95 | 5 2 1 0 1.49083954 96 | 5 2 1 1 1.49083954 97 | 6 1 0 0 1.52237552 98 | 6 2 1 -1 1.49083954 99 | 6 2 1 0 1.49083954 100 | 6 2 1 1 1.49083954 101 | 102 | Fermi energy: -0.1189046431 H -3.2356 eV 103 | Band energy: -20.8368817685 H -567.0004 eV 104 | TS: 0.0000000000 H 0.0000 eV 105 | Band free energy (E-TS): -20.8368817685 H -567.0004 eV 106 | Extrapolated E(0K): -20.8368817685 H -567.0004 eV 107 | Input/Output electrons (q): 32.00000000 32.00000000 108 | 109 | Energy H0: -18.7679941078 H -510.7031 eV 110 | Energy SCC: 0.0068318353 H 0.1859 eV 111 | Total Electronic energy: -18.7611622726 H -510.5172 eV 112 | Repulsive energy: 0.0000000000 H 0.0000 eV 113 | Total energy: -18.7611622726 H -510.5172 eV 114 | Total Mermin free energy: -18.7611622726 H -510.5172 eV 115 | 116 | SCC converged 117 | 118 | 119 | -------------------------------------------------------------------------------- /test/test_dftbutils/skf/skdefs.template.py: -------------------------------------------------------------------------------- 1 | atomconfigs = { 2 | 3 | "Si": AtomConfig( 4 | znuc=14, 5 | mass=28.0855, 6 | occupations=[ 7 | [ [ 1.0, 1.0 ], [ 1.0, 1.0 ], [ 1.0, 1.0 ]], # s 8 | [ [ 3.0, 3.0 ], [ 1.0, 1.0 ]], # p 9 | [ [ 0.0, 0.0 ]], # d 10 | ], 11 | valenceqns=[ 12 | [3, ], # s 13 | [3, ], # p 14 | [3, ], # d 15 | ], 16 | relativistic=True, 17 | orbitalresolved=True, 18 | override_onsite={ 19 | # (3, 2): %(DeltaE_Si_3s, 0, -0.1, 0.1)f, 20 | # (3, 2): %(DeltaE_Si_3p, 0, -0.1, 0.1)f, 21 | (3, 2): %(DeltaE_Si_3d, -0.1, 0.2)f, 22 | } 23 | ), 24 | } 25 | 26 | 27 | skbases = { 28 | "Si": SlaterBasis( 29 | exponents = [[1, 2.41, 5.81, 14], [1, 2.41, 5.81, 14], [3.0, 5.01, 8.38, 14]], 30 | maxpowers = [3, 3, 3], 31 | ), 32 | } 33 | 34 | 35 | compressions = { 36 | "Si": Compression( 37 | potcomp="potential", 38 | potcomp_parameters= [ 39 | (4, %(PotCompRad_Si_sp, 4, 12)f ), 40 | (4, %(PotCompRad_Si_sp, 4, 12)f ), 41 | (4, %(PotCompRad_Si_d, 6, 15)f ), ], 42 | wavecomp="potential", 43 | wavecomp_parameters=[ 44 | (4, %(PotCompRad_Si_sp, 4, 12)f ), 45 | (4, %(PotCompRad_Si_sp, 4, 12)f ), 46 | (4, %(PotCompRad_Si_d, 6, 15)f ), ], 47 | ), 48 | } 49 | -------------------------------------------------------------------------------- /test/test_evaluate.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import logging 3 | import numpy as np 4 | import numpy.testing as nptest 5 | from skpar.core import evaluate as ev 6 | 7 | 8 | class Objv(object): 9 | """Barebone objective""" 10 | 11 | def __init__(self, ff, ww): 12 | self.fitness = ff 13 | self.weight = ww 14 | 15 | def __call__(self, database): 16 | return self.fitness 17 | 18 | 19 | def printwrapper(env, db, msg): 20 | print(env, db, msg) 21 | 22 | 23 | def fexception(env, db, exception=None): 24 | """pass or except depending on the `exception`""" 25 | if exception is not None: 26 | raise exception 27 | else: 28 | return None 29 | 30 | 31 | class EvaluatorTest(unittest.TestCase): 32 | """Check if we can create an evaluator.""" 33 | 34 | def test_evaluator_init_dflt(self): 35 | """Can we instantiate evaluator?""" 36 | objvs = [Objv(2, 1), Objv(2, 1)] 37 | tasklist = [["t1", ["task2"]], ["t2", ["task2"]]] 38 | taskdict = {"t1": printwrapper, "t2": printwrapper} 39 | parnames = ["p0"] 40 | evaluator = ev.Evaluator(objvs, tasklist, taskdict, parnames) 41 | nptest.assert_array_equal(evaluator.weights, np.array([0.5, 0.5])) 42 | params, iteration = [2.0], 1 43 | fitness = evaluator(params, iteration) 44 | self.assertEqual(fitness, 2) 45 | 46 | def test_evaluator_utopia(self): 47 | """Can we instantiate evaluator w/ different utopia point?""" 48 | objvs = [Objv(2, 1), Objv(2, 1)] 49 | tasklist = [["t1", ["task2"]], ["t2", ["task2"]]] 50 | taskdict = {"t1": printwrapper, "t2": printwrapper} 51 | parnames = ["p0"] 52 | evaluator = ev.Evaluator(objvs, tasklist, taskdict, parnames, utopia=np.ones(2)) 53 | nptest.assert_array_equal(evaluator.weights, np.array([0.5, 0.5])) 54 | par, ii = [2.0], 1 55 | fitness = evaluator(par, ii) 56 | self.assertEqual(fitness, 1) 57 | 58 | def test_evaluator_task_failure(self): 59 | """Does evaluation breaks if task fails?""" 60 | objvs = [Objv(2, 1), Objv(2, 1)] 61 | tasklist = [["t1", ["task1"]], ["t2", [RuntimeError]], ["t1", ["task3"]]] 62 | taskdict = { 63 | "t1": printwrapper, 64 | "t2": fexception, 65 | } 66 | parnames = ["p0"] 67 | evaluator = ev.Evaluator(objvs, tasklist, taskdict, parnames) 68 | par, ii = [2.0], 1 69 | self.assertRaises(RuntimeError, evaluator, par, ii) 70 | 71 | 72 | if __name__ == "__main__": 73 | unittest.main() 74 | -------------------------------------------------------------------------------- /test/test_executables.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import yaml 3 | import logging 4 | 5 | logging.basicConfig(level=logging.DEBUG) 6 | logging.basicConfig(format="%(message)s") 7 | logger = logging.getLogger(__name__) 8 | 9 | 10 | class ExecutablesTest(unittest.TestCase): 11 | """Check if we can get the map of executables""" 12 | 13 | def test_getexemap(self): 14 | """Can we construct the dictionary for executables?""" 15 | yamldata = """executables: 16 | atom: gridatom 17 | skgen: skgen.sh 18 | lammps: mpirun -n 4 lmp_mpi 19 | bands: dp_bands band.out bands 20 | """ 21 | exedict = yaml.safe_load(yamldata).get("executables", None) 22 | try: 23 | for key, val in exedict.items(): 24 | logger.debug("{:>10s} : {}".format(key, " ".join(val.split()))) 25 | except AttributeError: 26 | # assume no executables are remapped 27 | pass 28 | 29 | 30 | if __name__ == "__main__": 31 | unittest.main() 32 | -------------------------------------------------------------------------------- /test/test_input.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "templatedir": "test_optimise", 4 | "keepworkdirs": true, 5 | "workroot": "./_workdir/test_optimise" 6 | }, 7 | 8 | "executables": { 9 | "mypy": "python" 10 | }, 11 | 12 | "objectives": [ 13 | {"yval": { 14 | "doc": "3-rd order polynomial values for some values of the argument", 15 | "models": "poly3", 16 | "ref": [36.55, 26.81875, 10.0, 13.43125, 64.45], 17 | "eval": ["rms", "relerr"] } } ], 18 | 19 | "tasks": [ 20 | {"set": ["template.parameters.dat"]}, 21 | {"run": ["mypy model_poly3.py"]}, 22 | {"get": ["get_model_data", "model_poly3_out.dat", "poly3", "yval"]} ], 23 | 24 | "optimisation": { 25 | "options": { 26 | "npart": 4, 27 | "ngen": 8 }, 28 | "algo": "PSO", 29 | "parameters": [ 30 | {"c0": "9.95 10.05"}, 31 | {"c1": "-2.49 -2.51"}, 32 | {"c2": "0.499 0.501"}, 33 | {"c3": "0.0499 0.0501"} ] } 34 | } 35 | -------------------------------------------------------------------------------- /test/test_input.py: -------------------------------------------------------------------------------- 1 | """Test correct parsing of input file""" 2 | import os 3 | import unittest 4 | import logging 5 | from skpar.core.input import parse_input, get_input, get_config 6 | from skpar.core.usertasks import update_taskdict 7 | from skpar.core.tasks import initialise_tasks, get_tasklist 8 | 9 | logging.basicConfig(level=logging.DEBUG) 10 | logging.basicConfig(format="%(message)s") 11 | LOGGER = logging.getLogger(__name__) 12 | 13 | 14 | class ReadInputTest(unittest.TestCase): 15 | """Check if we can read input file""" 16 | 17 | def test_import(self): 18 | """Can we import json?""" 19 | infile = "test_input.yaml" 20 | # check we handle yaml with new routine 21 | data1 = get_input(infile) 22 | # print('data1:') 23 | # print (data1) 24 | 25 | # check we handle json with new routine 26 | infile = "test_input.json" 27 | data2 = get_input(infile) 28 | # print('data2:') 29 | # print (data2) 30 | self.assertDictEqual(data1, data2) 31 | 32 | def test_parse_nonexistent(self): 33 | """Can we report neatly that input file is missing?""" 34 | filename = "skpar_noinput.yaml" 35 | 36 | def wrapper(): 37 | parsed = parse_input(filename) 38 | return parsed 39 | 40 | self.assertRaises(FileNotFoundError, wrapper) 41 | 42 | 43 | class ParseConfigTest(unittest.TestCase): 44 | """Check configuration is interpreted properly""" 45 | 46 | def test_parse_config(self): 47 | """Can we read config well?""" 48 | skparin = "example-tasks.yaml" 49 | userinp = get_input(skparin) 50 | config = get_config(userinp["config"]) 51 | refdict = { 52 | "templatedir": os.path.abspath("./test_optimise"), 53 | "workroot": os.path.abspath("./_workdir/test_optimise"), 54 | "keepworkdirs": True, 55 | } 56 | self.assertDictEqual(refdict, config) 57 | return config 58 | 59 | def test_parse_tasks_core(self): 60 | """Can we read tasks well and initialise correctly?""" 61 | taskdict = {} 62 | update_taskdict(taskdict, [["skpar.core.taskdict", ["sub", "get", "run"]]]) 63 | skparin = "example-tasks.yaml" 64 | userinp = get_input(skparin) 65 | tasklist = get_tasklist(userinp["tasks"]) 66 | for i, task in enumerate(tasklist): 67 | LOGGER.info("task %i : %s", i, task) 68 | tasks = initialise_tasks(tasklist, taskdict, report=True) 69 | self.assertEqual(len(tasks), 6) 70 | 71 | 72 | if __name__ == "__main__": 73 | unittest.main() 74 | -------------------------------------------------------------------------------- /test/test_input.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | templatedir: test_optimise 3 | workroot: ./_workdir/test_optimise 4 | keepworkdirs: true 5 | 6 | tasks: 7 | - set: [template.parameters.dat] 8 | - run: [mypy model_poly3.py] 9 | - get: [get_model_data, model_poly3_out.dat, poly3, yval] 10 | 11 | objectives: 12 | - yval: 13 | doc: 3-rd order polynomial values for some values of the argument 14 | models: poly3 15 | ref: [ 36.55, 26.81875, 10., 13.43125, 64.45 ] 16 | eval: [rms, relerr] 17 | 18 | optimisation: 19 | algo: PSO # particle swarm optimisation 20 | options: 21 | npart: 4 # number of particles 22 | ngen : 8 # number of generations 23 | parameters: 24 | - c0: 9.95 10.05 25 | - c1: -2.49 -2.51 26 | - c2: 0.499 0.501 27 | - c3: 0.0499 0.0501 28 | 29 | executables: 30 | mypy: 'python' 31 | -------------------------------------------------------------------------------- /test/test_lattice.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import logging 3 | import numpy as np 4 | import numpy.testing as nptest 5 | from skpar.dftbutils.lattice import Lattice, repr_lattice, get_dftbp_klines 6 | 7 | logging.basicConfig(level=logging.DEBUG) 8 | logging.basicConfig(format="%(message)s") 9 | logger = logging.getLogger(__name__) 10 | 11 | 12 | class LatticeTest(unittest.TestCase): 13 | def test_simplecubic(self): 14 | """Simple cubic (CUB)""" 15 | latinfo = {"type": "CUB", "param": 1.0} 16 | lat = Lattice(latinfo) 17 | logger.debug(lat) 18 | 19 | def test_bodycenteredcubic(self): 20 | """Body centered cubic (BCC)""" 21 | latinfo = {"type": "BCC", "param": 1.0} 22 | lat = Lattice(latinfo) 23 | logger.debug(lat) 24 | 25 | def test_facecenteredcubic(self): 26 | """Face centered cubic (FCC)""" 27 | latinfo = {"type": "FCC", "param": 1.0} 28 | lat = Lattice(latinfo) 29 | logger.debug(lat) 30 | 31 | def test_hexagonal(self): 32 | """Hexagonal (HEX)""" 33 | a = 1.0 34 | c = 2.0 35 | lat = Lattice({"type": "HEX", "param": [a, c]}) 36 | logger.debug(lat) 37 | 38 | def test_tetragonal(self): 39 | """Tetragonal (TET)""" 40 | a = 8.9385 # 1.0 41 | c = 12.9824 # 2.0 42 | lat = Lattice({"type": "TET", "param": [a, c], "path": "Gamma-M-X-Gamma-Z"}) 43 | logger.debug(lat) 44 | 45 | def test_orthorombic(self): 46 | """Orthorombic (ORC)""" 47 | a = 9.0714 # 1.0 48 | b = 8.7683 # 2.0 49 | c = 12.8024 # 3.0 50 | # lat = Lattice({'type': 'ORC', 'param': [a, b, c], 'path': 'Gamma-S-X-Gamma-Z'}) 51 | lat = Lattice({"type": "ORC", "param": [a, b, c], "path": "Gamma-S-Y-Gamma-Z"}) 52 | # Default Path 53 | lat = Lattice({"type": "ORC", "param": [a, b, c]}) 54 | logger.debug(lat) 55 | 56 | def test_rhombohedral(self): 57 | """Rhombohedral (RHL)""" 58 | a, angle = 5.32208613808, 55.8216166097 59 | lat = Lattice({"type": "RHL", "param": [a, angle]}) 60 | logger.debug(lat) 61 | 62 | def test_monoclinic(self): 63 | """Monoclinic (MCL)""" 64 | a, b, c, angle = 5.17500, 5.17500, 5.29100, 80.78 65 | lat = Lattice({"type": "MCL", "param": [a, b, c, angle]}) 66 | logger.debug(lat) 67 | 68 | def test_monoclinic_facecentered(self): 69 | """Face-centered Monoclinic (MCLC)""" 70 | a, b, c, beta = 12.23, 3.04, 5.8, 103.70 71 | lat = Lattice({"type": "MCLC", "param": [a, b, c, beta]}) 72 | logger.debug(lat) 73 | 74 | 75 | if __name__ == "__main__": 76 | unittest.main() 77 | -------------------------------------------------------------------------------- /test/test_newtasks.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | templatedir: template 3 | workroot: ./_workdir 4 | keepworkdirs: true 5 | 6 | 7 | executables: 8 | skgen: ./template/skf/skgen-opt.sh 9 | bands: dftbutils bands 10 | 11 | tasks: 12 | # - set: [skf/skdefs.template.py] 13 | - substitute_parameters: files: skf/skdefs.template.py 14 | # - run: [skgen, skf] 15 | - skgen: workdir: skf 16 | # - run: [bands, C.dia/hydrostatic-0.00] 17 | - bands: workdir: C.dia/hydrostatic-0.00, update: C.dia.hs-0.00 18 | - get: [get_dftbp_bs, C.dia/hydrostatic-0.00/bs, C.dia.hs-0.00, 19 | {latticeinfo: {type: 'FCC', param: 3.56208625213847}}] 20 | 21 | # This will show both objectives for CB and VB, but no band-gap between them, 22 | # and no k-vector labels either! 23 | # - plot: [plot_objvs, Si-diam/100/bs/bs, [bands, Si.diam.100], kvector] 24 | 25 | # The plot_bs does magic when it sees the first objective being 'Egap'.shape==(1,) 26 | # it shifts the band-gap, so the band-structure is properly shown. 27 | # For this to happen, objectives declaration must be such that VB precedes CB!!! 28 | # The plot_bs will also show k-ticks and labels if requested, as below 29 | - plot: [plot_bs, C.dia/bands.hs-0.00, [bands, C.dia.hs-0.00], 30 | kvector, queries: [kticklabels]] 31 | 32 | # Nota bene: supplying the Egap as objective is optional. VB and CB are printed 33 | # as-is if Egap is not given (e.g. for metal or for a single 'bands' objective. 34 | # - plot: [plot_bs, Si-diam/100/bs/bs_3, [bands, Si.diam.100], kvector, queries: kticklabels] 35 | 36 | tasks: 37 | - plot: {bands: ['C_vb', 'C_cb'], gap: C_Egap} 38 | 39 | 40 | objectives: 41 | 42 | bs_diamond: 43 | doc: Some compilicated things 44 | values: MoS2_ml.totalenergy_volume 45 | refs: MoS2_ml_vasp_pbe.totalenergy_volume 46 | weight: 1.0 47 | subweights: [1.0, 2.0, 3.0, 2.0, 1.0] 48 | eval: [rms, relerr] 49 | 50 | 51 | SiC_Eheat: 52 | doc: We will calculate the SiC heat of formation 53 | values: [SiC.Etot, Si.2.Etot, C.2.Etot] 54 | factors: [0.5, -0.5, -0.5] 55 | refs: [SiC_2_pbe_vasp.Etot, Si_2_pbe_vasp.Etot, C_2_pbe_vasp.Etot] 56 | weight: 1.0 57 | eval: [relerr] 58 | 59 | 60 | C_vb: 61 | 62 | 63 | C_cb: 64 | 65 | 66 | C_Egap: 67 | values: ... 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /test/test_optimise/model_poly3.py: -------------------------------------------------------------------------------- 1 | """Model for testing the optimiser. 2 | 3 | It consists of a 3rd order polynomial. 4 | """ 5 | import numpy as np 6 | from numpy.polynomial.polynomial import polyval 7 | 8 | # read the parameters of the model 9 | # names: ['keys', 'values'] 10 | # formats: ['S15', 'float'] 11 | raw = np.loadtxt("parameters.dat", dtype=[("keys", "S15"), ("values", "float")]) 12 | c = np.array([pair[1] for pair in raw]) 13 | # print(c) 14 | 15 | # do the calculations 16 | xmin, xmax = -10, 10 17 | nref = 5 18 | x = np.linspace(xmin + 1, xmax - 1, nref) 19 | y = polyval(x, c) 20 | 21 | # write the output 22 | # print (y) 23 | with open("model_poly3_out.dat", "wb") as fh: 24 | np.savetxt(fh, y) 25 | with open("model_poly3_xval.dat", "wb") as fh: 26 | np.savetxt(fh, x) 27 | -------------------------------------------------------------------------------- /test/test_optimise/template.parameters.dat: -------------------------------------------------------------------------------- 1 | c0 %(c0)f 2 | c1 %(c1)f 3 | c2 %(c2)f 4 | c3 %(c3)f 5 | -------------------------------------------------------------------------------- /test/test_parameters.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import logging 3 | import os 4 | import os.path 5 | import numpy as np 6 | import numpy.testing as nptest 7 | import yaml 8 | from skpar.core.parameters import get_parameters, update_template 9 | from skpar.core.parameters import update_parameters, substitute_template 10 | 11 | logging.basicConfig(level=logging.DEBUG) 12 | logging.basicConfig(format="%(message)s") 13 | logger = logging.getLogger(__name__) 14 | 15 | 16 | class ParametersTest(unittest.TestCase): 17 | """ 18 | Verify handling of parameters 19 | """ 20 | 21 | def test_get_explicit_parameters(self): 22 | """Can we interpret explicit parameter definitions correctly?""" 23 | yamldata = """parameters: 24 | - r0_Si_sp: 4 2 6 25 | - nc_Si_sp: 4 2 12 i 26 | - rc_O_sp: 1.5 4 27 | - ep_O_sp: 8 i 28 | """ 29 | spec = yaml.safe_load(yamldata)["parameters"] 30 | logging.debug(spec) 31 | params = get_parameters(spec) 32 | self.assertEqual(len(params), 4) 33 | values = [4, 4, 0, 8] 34 | minv = [2, 2, 1.5, None] 35 | maxv = [6, 12, 4, None] 36 | names = ["r0_Si_sp", "nc_Si_sp", "rc_O_sp", "ep_O_sp"] 37 | for i, par in enumerate(params): 38 | self.assertEqual(par.value, values[i]) 39 | self.assertEqual(par.minv, minv[i]) 40 | self.assertEqual(par.maxv, maxv[i]) 41 | self.assertEqual(par.name, names[i]) 42 | logger.debug(par) 43 | 44 | 45 | class TemplateTest(unittest.TestCase): 46 | """Test we can read, update and write the template file.""" 47 | 48 | tmplt = """This is some file 49 | with a few parameters defined like this: 50 | # %%(Dummy) or something like this. 51 | %(Dummy)f # parameter name only 52 | And we want to get 53 | # 2.7 or something like this 54 | by putting a real value in place of %(Gummy)i 55 | and %(Bear)f 56 | """ 57 | 58 | def test_update_template_classparam(self): 59 | """Can we update a template and write it to a file?""" 60 | yamldata = """parameters: 61 | - Dummy: 1.5 62 | - Gummy: 15 i 63 | - Bear : 27 64 | - Fear 65 | """ 66 | spec = yaml.safe_load(yamldata)["parameters"] 67 | logging.debug(spec) 68 | params = get_parameters(spec) 69 | pardict = dict([(p.name, p.value) for p in params]) 70 | updated = update_template(self.tmplt, pardict) 71 | expected = """This is some file 72 | with a few parameters defined like this: 73 | # %(Dummy) or something like this. 74 | 1.500000 # parameter name only 75 | And we want to get 76 | # 2.7 or something like this 77 | by putting a real value in place of 15 78 | and 27.000000 79 | """ 80 | self.assertEqual(updated, expected) 81 | 82 | 83 | class WriteParametersTest(unittest.TestCase): 84 | """Can we write out parameters, given a template file?""" 85 | 86 | def test_writeparameters_listparam(self): 87 | """Can we update a template and write it to a file?""" 88 | template = """%(A)f %(B)f %(C)f""" 89 | ftemplate = "temp.par" 90 | with open(ftemplate, "w") as fh: 91 | fh.write(template) 92 | parameters = [1, 15, 27] 93 | parnames = list("ABC") 94 | expected = """1.000000 15.000000 27.000000""" 95 | fsubs = "subs.par" 96 | substitute_template(parameters, parnames, ftemplate, fsubs) 97 | with open(fsubs, "r") as fh: 98 | lines = fh.readlines() 99 | assert len(lines) == 1 100 | updated = lines[0] 101 | self.assertEqual(updated, expected) 102 | os.remove(ftemplate) 103 | os.remove(fsubs) 104 | 105 | 106 | class UpdateParametersTest(unittest.TestCase): 107 | """Can we update parameters given proper file names?""" 108 | 109 | def test_updateparameters_listparam(self): 110 | template = """%(A)f %(B)f %(C)f""" 111 | ftempl = "test.template.par" 112 | with open(ftempl, "w") as fh: 113 | fh.write(template) 114 | parameters = [1, 15, 27] 115 | parnames = list("ABC") 116 | expected = """1.000000 15.000000 27.000000""" 117 | update_parameters(".", [ftempl], parameters, parnames=parnames) 118 | fout = "test.par" 119 | with open(fout, "r") as fh: 120 | lines = fh.readlines() 121 | assert len(lines) == 1 122 | self.assertEqual(lines[0], expected) 123 | os.remove(fout) 124 | os.remove(ftempl) 125 | 126 | # BA: Disabled: update_parameters can't handle parnames=None. 127 | # BA: But, why should it? 128 | # def test_updateparameters_None(self): 129 | # "Can we handle None for parameters?" 130 | # fcurr = 'curr.par' 131 | # parameters = None 132 | # # update_parameters expects 3 posargs and kwargs 133 | # update_parameters('.', [fcurr], parameters, parnames=None) 134 | # with open(fcurr, 'r') as fh: 135 | # lines = fh.readlines() 136 | # assert len(lines) == 0 137 | # os.remove(fcurr) 138 | 139 | 140 | if __name__ == "__main__": 141 | unittest.main() 142 | -------------------------------------------------------------------------------- /test/test_pscan.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import numpy as np 3 | import numpy.testing as nptest 4 | from numpy.polynomial.polynomial import polyval 5 | import logging 6 | import os, sys 7 | from skpar.core.pscan import PSCAN, pformat 8 | 9 | logging.basicConfig(level=logging.DEBUG) 10 | logging.basicConfig(format="%(message)s") 11 | logger = logging.getLogger(__name__) 12 | 13 | 14 | class PscanTest(unittest.TestCase): 15 | """ 16 | A small test and usage example of the PSCAN engine. 17 | """ 18 | 19 | def test_scan(self): 20 | """Can we instantiate a pscan engine and run it?""" 21 | # Refdata: 5 points from a 3-rd order polynomial 22 | xmin, xmax = -10, 10 23 | nref = 5 24 | xref = np.linspace(xmin + 1, xmax - 1, nref) 25 | c = np.array([10, -2.5, 0.5, 0.05]) 26 | refdata = polyval(xref, c) 27 | logger.debug("Reference data: {}".format(refdata)) 28 | refweights = np.ones(len(refdata)) 29 | 30 | def model(par): 31 | coef = par + [0.05] 32 | return polyval(xref, coef) 33 | 34 | # Define an evaluator function for the fitness e.g. RMS error. 35 | # NOTABENE: 36 | # 1. Fitness must be a tuple-like, hence the atleast_1d below. 37 | # 2. The PSO requires errors to be returned, to allow for an 38 | # alternative stopping critera. This may become optional. 39 | # 3. If the evaluate functions supports 'iteration' argument the PSO 40 | # will call it with iteration (generation, particle_index) in the 41 | # argument list. 42 | # 4. Assumed is that refdata and weights are known in advance; the 43 | # PSO does not need to know about them. 44 | def evaluate(parameters, iteration, refdata=refdata, weights=refweights): 45 | modeldata = model(parameters) 46 | errors = refdata - modeldata 47 | # it seems at least for this example relative error reduces the 48 | # on-average-required number of iterations by significantly - 49 | # e.g. from ~150 to ~ 110, to reduce the ErrTol 50 | fitness = np.atleast_1d( 51 | np.sqrt(sum(weights * np.power(errors / refdata, 2))) 52 | ) 53 | # return fitness, np.max(np.abs(errors/refdata)) 54 | return fitness 55 | 56 | # Variables specific to the optimisation problem 57 | # ---------------------------------------------------------------------- 58 | # Dimensionality and range of the fitting parameters that are representted as a particle: 59 | # in this case, 4 polynomial coefficients are to be fitted, and we provide appropriate 60 | # range for them 61 | # Target coef. are: 10, -2.5, 0.5, 0.05 62 | parameters = [(4, -10.0, 20.0), (3, -3.0, -2.0), (5, 0.0, 2.0)] 63 | objectives = (-1,) 64 | # make an instance of the pscan 65 | optimise = PSCAN(parameters, evaluate, objective_weights=objectives) 66 | 67 | # buzz the particle swarm for ngen generations 68 | population, stats = optimise() 69 | 70 | logger.debug("Best position sequential number: {0}".format(population.ibest)) 71 | logger.debug( 72 | "Best position fitness: {:.5f}".format(population.best.fitness.values[0]) 73 | ) 74 | logger.debug( 75 | "Best parameter values: {}".format( 76 | ", ".join(["{0:.3f}".format(indl) for indl in population.best]) 77 | ) 78 | ) 79 | 80 | # for pt in population: 81 | # logger.debug(pformat(pt)) 82 | 83 | nptest.assert_allclose(population.best, c[:3], rtol=0.1, verbose=True) 84 | self.assertTrue(population.best.fitness.values[0] < 0.2) 85 | 86 | 87 | if __name__ == "__main__": 88 | unittest.main() 89 | -------------------------------------------------------------------------------- /test/test_pscan/model_poly3.py: -------------------------------------------------------------------------------- 1 | """Model for testing the optimiser. 2 | 3 | It consists of a 3rd order polynomial. 4 | """ 5 | import numpy as np 6 | from numpy.polynomial.polynomial import polyval 7 | 8 | # read the parameters of the model 9 | # names: ['keys', 'values'] 10 | # formats: ['S15', 'float'] 11 | raw = np.loadtxt("parameters.dat", dtype=[("keys", "S15"), ("values", "float")]) 12 | c = np.array([pair[1] for pair in raw]) 13 | # print(c) 14 | 15 | # do the calculations 16 | xmin, xmax = -10, 10 17 | nref = 5 18 | x = np.linspace(xmin + 1, xmax - 1, nref) 19 | y = polyval(x, c) 20 | 21 | # write the output 22 | # print (y) 23 | with open("model_poly3_out.dat", "wb") as fh: 24 | np.savetxt(fh, y) 25 | with open("model_poly3_xval.dat", "wb") as fh: 26 | np.savetxt(fh, x) 27 | -------------------------------------------------------------------------------- /test/test_pscan/template.parameters.dat: -------------------------------------------------------------------------------- 1 | c0 %(c0)f 2 | c1 %(c1)f 3 | c2 %(c2)f 4 | c3 %(c3)f 5 | -------------------------------------------------------------------------------- /test/test_querykLines.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import logging 3 | import numpy as np 4 | import numpy.testing as nptest 5 | from skpar.core.database import Database 6 | from skpar.dftbutils import lattice 7 | from skpar.dftbutils.lattice import Lattice 8 | from skpar.dftbutils.queryDFTB import get_dftbp_data, get_bandstructure 9 | from skpar.dftbutils.querykLines import get_klines, greekLabels, get_kvec_abscissa 10 | 11 | logging.basicConfig(level=logging.DEBUG) 12 | logging.basicConfig(format=" %(message)s") 13 | logger = logging.getLogger(__name__) 14 | 15 | 16 | class QuerykLinesTest(unittest.TestCase): 17 | def test_get_klines(self): 18 | # lat = lattice.FCC(3.6955*2) 19 | lat = Lattice({"type": "FCC", "param": 3.6955 * 2}) 20 | refklines = [("X", 0), ("Gamma", 85), ("K", 175), ("L", 227), ("Gamma", 300)] 21 | refklinesdict = {"L": [227], "K": [175], "X": [0], "Gamma": [85, 300]} 22 | klines, klinesdict = get_klines(lat, workdir="test_dftbutils/bs") 23 | self.assertListEqual(refklines, klines) 24 | self.assertDictEqual(refklinesdict, klinesdict) 25 | 26 | 27 | class GetAbscissakVectorTest(unittest.TestCase): 28 | def test_get_kvec_abscissa(self): 29 | """Can we get the bandstructure and extract the kvector info""" 30 | latticeinfo = {"type": "FCC", "param": 1.0} 31 | lat = Lattice(latticeinfo) 32 | kLines = [ 33 | ("L", 0), 34 | ("Gamma", 10), 35 | ("X", 20), 36 | ("U", 30), 37 | ("K", 31), 38 | ("Gamma", 41), 39 | ] 40 | logger.debug("kLines : {}".format(kLines)) 41 | xx, xt, xl = get_kvec_abscissa(lat, kLines) 42 | refxl = ["L", "Γ", "X", "U|K", "Γ"] 43 | refxt = [0, 5.44140, 11.724583399882238, 13.946024868961421, 20.610349276198971] 44 | self.assertListEqual(xl, refxl) 45 | nptest.assert_almost_equal(xt, refxt, 5) 46 | self.assertAlmostEqual(xx[-1], xt[-1]) 47 | self.assertEqual(len(xx), kLines[-1][-1] + 1) 48 | 49 | def test_get_kvec_abscissa2(self): 50 | """Can we get the bandstructure and extract the kvector info""" 51 | latticeinfo = {"type": "FCC", "param": 1.0} 52 | lat = Lattice(latticeinfo) 53 | database = Database() 54 | src = "test_dftbutils/bs" 55 | get_bandstructure( 56 | {"workroot": "."}, database, src, "test", latticeinfo=latticeinfo 57 | ) 58 | kLines = database.get_item("test", "kLines") 59 | bands = database.get_item("test", "bands") 60 | logger.debug("Bands.shape: {}".format(bands.shape)) 61 | logger.debug("kLines : {}".format(kLines)) 62 | xx, xt, xl = get_kvec_abscissa(lat, kLines) 63 | refxl = ["X", "Γ", "K", "L", "Γ"] 64 | refxt = [0, 6.28319, 12.94751, 16.79516, 22.23656] 65 | self.assertListEqual(xl, refxl) 66 | nptest.assert_almost_equal(xt, refxt, 5) 67 | self.assertAlmostEqual(xx[-1], xt[-1]) 68 | self.assertEqual(len(xx), kLines[-1][-1] + 1) 69 | 70 | def test_get_kvec_abscissa3(self): 71 | """Can we get the bandstructure and extract the kvector info, from vasp style kLines""" 72 | latticeinfo = {"type": "FCC", "param": 1.0} 73 | lat = Lattice(latticeinfo) 74 | kLines = [ 75 | ("X", 0), 76 | ("Gamma", 9), 77 | ("Gamma", 10), 78 | ("K", 19), 79 | ("K", 20), 80 | ("L", 29), 81 | ("L", 30), 82 | ("Gamma", 39), 83 | ] 84 | xx, xt, xl = get_kvec_abscissa(lat, kLines) 85 | refxl = ["X", "Γ", "K", "L", "Γ"] 86 | refxt = [0, 6.28319, 12.94751, 16.79516, 22.23656] 87 | self.assertListEqual(xl, refxl) 88 | nptest.assert_almost_equal(xt, refxt, 5) 89 | self.assertAlmostEqual(xx[-1], xt[-1]) 90 | self.assertEqual(len(xx), kLines[-1][-1] + 1) 91 | 92 | 93 | if __name__ == "__main__": 94 | unittest.main() 95 | -------------------------------------------------------------------------------- /test/test_tasks/fail.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | print("About to fail...") 4 | 5 | sys.exit(1) 6 | -------------------------------------------------------------------------------- /test/test_tasks/pass.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | print("Running to pass!") 4 | 5 | sys.exit(0) 6 | -------------------------------------------------------------------------------- /test/test_usertasks.py: -------------------------------------------------------------------------------- 1 | """Test import of user modules and taskdict update by user-defined tasks""" 2 | import unittest 3 | import yaml 4 | 5 | from skpar.core.usertasks import import_taskdict, update_taskdict 6 | from skpar.core.taskdict import TASKDICT as coretd 7 | from skpar.dftbutils.taskdict import TASKDICT as dftbtd 8 | 9 | 10 | class UserTaskTest(unittest.TestCase): 11 | """Can we obtain taskdict from user modules""" 12 | 13 | def test_import_taskdict(self): 14 | """Check we can import TASKDICT from a module""" 15 | # skpar.core 16 | modname, taskdict = import_taskdict("skpar.core.taskdict") 17 | self.assertEqual(modname, "skpar.core.taskdict") 18 | self.assertDictEqual(coretd, taskdict) 19 | # skpar.dftbutils 20 | modname, taskdict = import_taskdict("skpar.dftbutils") 21 | self.assertEqual(modname, "skpar.dftbutils") 22 | self.assertDictEqual(dftbtd, taskdict) 23 | # fail module import (modulenotfounderror is py3.6+) 24 | self.assertRaises( 25 | (ImportError, ModuleNotFoundError), import_taskdict, "skpar.missing" 26 | ) 27 | # fail no TASKDICT (core.__init__.py is empty) 28 | self.assertRaises(AttributeError, import_taskdict, "skpar.core") 29 | 30 | def test_update_taskdict(self): 31 | """Check we can update taskdict from user module""" 32 | yamlinput = """ 33 | usermodules: 34 | - skpar.core.taskdict 35 | """ 36 | userinp = yaml.safe_load(yamlinput)["usermodules"] 37 | taskdict = {} 38 | update_taskdict(taskdict, userinp) 39 | tag = "skpar.core.taskdict" 40 | self.assertEqual(len(coretd), len(taskdict)) 41 | for key, val in coretd.items(): 42 | self.assertTrue(".".join([tag, key]) in taskdict) 43 | self.assertEqual(val, taskdict[tag + "." + key]) 44 | 45 | def test_update_taskdict_multiple(self): 46 | """Check we can update taskdict from multiple modules""" 47 | yamlinput = """ 48 | usermodules: 49 | - [skpar.core.taskdict, [set, get, run, plot]] 50 | - [skpar.dftbutils, [get_bs]] 51 | """ 52 | userinp = yaml.safe_load(yamlinput)["usermodules"] 53 | taskdict = {} 54 | update_taskdict(taskdict, userinp) 55 | self.assertEqual(len(taskdict), 5) 56 | for key in ["set", "get", "run", "plot"]: 57 | self.assertTrue(key in taskdict) 58 | self.assertEqual(coretd[key], taskdict[key]) 59 | for key in ["get_bs"]: 60 | self.assertTrue(key in taskdict) 61 | self.assertEqual(dftbtd[key], taskdict[key]) 62 | 63 | def test_update_taskdict_string(self): 64 | """Check we can update taskdict from user module""" 65 | tag = "skpar.core.taskdict" 66 | taskdict = {} 67 | update_taskdict(taskdict, tag) 68 | self.assertEqual(len(coretd), len(taskdict)) 69 | for key, val in coretd.items(): 70 | self.assertTrue(".".join([tag, key]) in taskdict) 71 | self.assertEqual(val, taskdict[tag + "." + key]) 72 | 73 | def test_update_taskdict_alias(self): 74 | """Check we can update taskdict from user module with alias""" 75 | yamlinput = """ 76 | usermodules: 77 | - [skpar.dftbutils, dftb] 78 | """ 79 | userinp = yaml.safe_load(yamlinput)["usermodules"] 80 | taskdict = {} 81 | update_taskdict(taskdict, userinp) 82 | tag = "dftb" 83 | self.assertEqual(len(dftbtd), len(taskdict)) 84 | for key, val in dftbtd.items(): 85 | self.assertTrue(".".join([tag, key]) in taskdict) 86 | self.assertEqual(val, taskdict[tag + "." + key]) 87 | 88 | def test_update_taskdict_explicit(self): 89 | """Check we can update taskdict from user module with explicit tasks""" 90 | yamlinput = """ 91 | usermodules: 92 | - [skpar.core.taskdict, [set, get, run, plot]] 93 | """ 94 | taskdict = {} 95 | userinp = yaml.safe_load(yamlinput)["usermodules"] 96 | update_taskdict(taskdict, userinp) 97 | self.assertEqual(4, len(taskdict)) 98 | for key in ["set", "get", "run", "plot"]: 99 | self.assertTrue(key in taskdict) 100 | self.assertEqual(coretd[key], taskdict[key]) 101 | # check failing with missing task 102 | yamlinput = """ 103 | usermodules: 104 | - [skpar.core.taskdict, [set, mambo]] 105 | """ 106 | taskdict = {} 107 | userinp = yaml.safe_load(yamlinput)["usermodules"] 108 | self.assertRaises(KeyError, update_taskdict, taskdict, userinp) 109 | 110 | 111 | if __name__ == "__main__": 112 | unittest.main() 113 | -------------------------------------------------------------------------------- /test/usermodule.py: -------------------------------------------------------------------------------- 1 | """Trivial user module.""" 2 | 3 | 4 | def userfunc(say="Hi"): 5 | """Test func with one parameter.""" 6 | return "SKPAR says {}".format(say) 7 | 8 | 9 | TASKDICT = {"greet": userfunc} 10 | --------------------------------------------------------------------------------