示例#1
0
 def test_get_special_Ek(self):
     """Get E(k) for k obtained from the kLines"""
     env = {}
     database = Database()
     model = 'test.Ek'
     src = 'test_dftbutils/Si/bs'
     get_bandstructure(env,
                       database,
                       src,
                       model,
                       latticeinfo={
                           'type': 'FCC',
                           'param': 5.431
                       })
     dst = database.get(model)
     get_special_Ek(env, database, model, model)
     self.assertAlmostEqual(dst['Ec_L_0'], 0.4, places=3)
     self.assertAlmostEqual(dst['Ec_G_0'], 1.616, places=3)
     self.assertAlmostEqual(dst['Ec_X_0'], 0.2025, places=3)
     self.assertAlmostEqual(dst['Ec_U_0'], 0.6915, places=3)
     self.assertAlmostEqual(dst['Ec_K_0'], 0.6915, places=3)
     #
     self.assertAlmostEqual(dst['Ev_L_0'], -2.5016, places=3)
     self.assertAlmostEqual(dst['Ev_G_0'], -1.1289, places=3)
     self.assertAlmostEqual(dst['Ev_X_0'], -3.9592, places=3)
     self.assertAlmostEqual(dst['Ev_U_0'], -3.5885, places=3)
     self.assertAlmostEqual(dst['Ev_K_0'], -3.5885, places=3)
示例#2
0
 def test_get_special_Ek_options(self):
     """Get E(k) for explicitly given, and multiple bands"""
     env = {}
     database = Database()
     model = 'test.Ek'
     src = 'test_dftbutils/Si/bs'
     get_bandstructure(env,
                       database,
                       src,
                       model,
                       latticeinfo={
                           'type': 'FCC',
                           'param': 5.431
                       })
     dst = database.get(model)
     get_special_Ek(env,
                    database,
                    model,
                    model,
                    sympts=['K', 'L'],
                    extract={
                        'cb': [0, 2, 4, 6],
                        'vb': [0, 2, 4, 6]
                    })
     self.assertAlmostEqual(dst['Ec_L_4'], 2.8089, places=3)
     self.assertAlmostEqual(dst['Ec_L_0'], 0.3995, places=3)
     self.assertAlmostEqual(dst['Ec_K_0'], 0.6915, places=3)
     #
     self.assertAlmostEqual(dst['Ev_L_0'], -2.5016, places=3)
     self.assertAlmostEqual(dst['Ev_L_4'], -7.842, places=3)
     self.assertAlmostEqual(dst['Ev_L_6'], -11.3369, places=3)
     self.assertAlmostEqual(dst['Ev_K_0'], -3.5884, places=3)
     self.assertAlmostEqual(dst['Ev_K_2'], -4.963, places=3)
     self.assertAlmostEqual(dst['Ev_K_4'], -8.694, places=3)
     self.assertAlmostEqual(dst['Ev_K_6'], -9.8759, places=3)
示例#3
0
 def test_objtype_values_single_model_single_data(self):
     """Can we create value-type objective for a single model"""
     yamldata = """objectives:
         - band_gap:
             doc: Band gap, Si
             models: Si/bs
             ref: 1.12
             weight: 3.0
     """
     dat = 1.2
     ow  = 1.
     spec = yaml.load(yamldata)['objectives'][0]
     que = 'band_gap'
     ref = 1.12
     www = 3.0
     mnm = 'Si/bs'
     # set data base
     database = Database()
     database.update('Si/bs')
     modeldb = database.get('Si/bs')
     # check declaration
     objv = oo.get_objective(spec)
     self.assertEqual(objv.objtype, 'values')
     self.assertEqual(objv.model_names, mnm)
     self.assertEqual(objv.model_weights, ow)
     self.assertEqual(objv.weight, www)
     self.assertEqual(objv.ref_data, ref)
     self.assertEqual(objv.subweights, ow)
     self.assertEqual(objv.query_key, que)
     # check __call__()
     modeldb['band_gap'] = dat
     mdat, rdat, weights = objv.get(database)
     self.assertEqual(mdat, dat)
     self.assertEqual(rdat, ref)
     self.assertEqual(weights, ow)
示例#4
0
 def test_evaluate_bands(self):
     """Can we evaluate value-type objective of type bands (2D array)"""
     yamldata = """objectives:
         - bands: 
             models: A
             ref: 
                 file: ./reference_data/fakebands.dat
                 loader_args: {unpack: False}
                 process:
                     rm_columns: 1
             eval: [RMS, relerr]
     """
     # set model data
     database = Database()
     database.update('A')
     db1 = database.get('A')
     # declaration of objective
     spec = yaml.load(yamldata)['objectives'][0]
     objv = oo.get_objective(spec)
     self.assertAlmostEqual(1., np.sum(objv.subweights))
     #logger.debug(objv.ref_data)
     #logger.debug(objv.subweights)
     db1['bands'] = objv.ref_data * 1.1
     cost = np.sqrt(np.sum(objv.subweights*relerr(objv.ref_data, db1['bands'])**2))
     #logger.debug(cost)
     # evaluate
     self.assertAlmostEqual(cost, objv(database))
示例#5
0
 def test_execution_get_dftbp(self):
     """Can we execute the declared get_dftbp_* tasks?"""
     taskdict = {}
     update_taskdict(taskdict,
                     [['skpar.core.taskdict', ['get', 'sub', 'run']]])
     update_taskdict(
         taskdict, [['skpar.dftbutils', ['get_bs', 'get_meff', 'get_Ek']]])
     userinp = yaml.load(self.yamlin)
     tasklist = get_tasklist(userinp['tasks'])
     tasks = initialise_tasks(tasklist, taskdict)
     #
     database = Database()
     env = {
         'workroot': '.',
     }
     for task in tasks:
         print(task)
         task(env, database)
     # 'Si.bs' should be added through the task execution
     db = database.get('Si.bs')
     self.assertAlmostEqual(db['Egap'], 1.129, places=3)
     self.assertAlmostEqual(db['Ef'], -3.0621, places=4)
     self.assertAlmostEqual(db['me_GX'], 0.935, places=3)
     self.assertAlmostEqual(db['mh_GK'], -1.891, places=3)
     self.assertAlmostEqual(db['Ec_L_0'], 0.4, places=3)
     self.assertAlmostEqual(db['Ec_G_0'], 1.6156, places=3)
     self.assertAlmostEqual(db['Ec_X_0'], 0.2025, places=3)
     self.assertAlmostEqual(db['Ec_U_0'], 0.6915, places=3)
     self.assertAlmostEqual(db['Ec_K_0'], 0.6915, places=3)
示例#6
0
 def test_skparplot(self):
     """Can we plot a band-structure objectives?"""
     env = {}
     database = Database()
     latticeinfo = {'type': 'FCC', 'param': 5.4315}
     model = 'Si.bs'
     filename = '_workdir/test_plot/bs1.pdf'
     get_bandstructure(env,
                       database,
                       'test_dftbutils/Si/bs/',
                       model,
                       latticeinfo=latticeinfo)
     modeldb = database.get(model)
     bands = modeldb['bands']
     eps = 0.25
     jitter = eps * (0.5 - random(bands.shape))
     altbands = bands + jitter
     if os.path.exists(filename):
         os.remove(filename)
     else:
         os.makedirs('_workdir/test_plot', exist_ok=True)
     skparplot(modeldb['kvector'], [altbands, bands],
               filename=filename,
               xticklabels=modeldb['kticklabels'],
               xlabel='wave-vector',
               ylabel='Energy, eV',
               linelabels=['ref', 'model'],
               ylim=(-13, 6))
     self.assertTrue(os.path.exists(filename))
示例#7
0
 def test_objtype_keyvaluepairs(self):
     """Can we create objective from given key-value pairs"""
     yamldata = """objectives:
         - meff:
             doc: Effective masses, Si
             models: Si/bs
             ref: 
                 file: ./reference_data/meff-Si.dat
                 loader_args: 
                     dtype:
                     # NOTABENE: yaml cannot read in tuples, so we must
                     #           use the dictionary formulation of dtype
                         names: ['keys', 'values']
                         formats: ['S15', 'float']
             options:
                 normalise: false
                 subweights: 
                     # consider only a couple of entries from available data
                     dflt: 0.
                     me_GX_0: 2.
                     mh_GX_0: 1.
             weight: 1.5
     """
     spec = yaml.load(yamldata)['objectives'][0]
     que = 'meff'
     # NOTABENE: order here must coincide with order in ref:file
     ref = np.array([('me_GX_0', 0.916), ('mh_GX_0', -0.276)],
                    dtype=[('keys', 'S15'), ('values', 'float')])
     ref = ref['values']
     subw = np.array([2., 1.])
     doc = spec[que]['doc']
     oww = spec[que]['weight']
     mnm = spec[que]['models']
     # check declaration
     objv = oo.get_objective(spec)
     logger.debug(objv)
     self.assertEqual(objv.doc, doc)
     self.assertEqual(objv.weight, oww)
     self.assertEqual(objv.model_names, mnm)
     self.assertEqual(objv.model_weights, 1.)
     nptest.assert_array_equal(objv.ref_data, ref, verbose=True)
     nptest.assert_array_equal(objv.subweights, subw, verbose=True)
     self.assertEqual(objv.query_key, ['me_GX_0', 'mh_GX_0'])
     self.assertEqual(objv.objtype, 'keyval_pairs')
     # set data base: 
     # could be done either before or after declaration
     database = Database()
     dat = [0.9, -0.5, 1.2]
     database.update('Si/bs', {'me_GX_0': dat[0], 'mh_GX_0': dat[1],
                                  'me_GL_2':dat[2]})
     # check __call__()
     mdat, rdat, weights = objv.get(database)
     #logger.debug(mdat)
     #logger.debug(rdat)
     #logger.debug(weights)
     # NOTABENE: order depends on the order in the reference file!!!
     nptest.assert_array_equal(mdat, np.asarray(dat[0:2]), verbose=True)
     nptest.assert_array_equal(rdat, ref, verbose=True)
     nptest.assert_array_equal(weights, subw, verbose=True)
示例#8
0
 def test_simple(self):
     """Can we parse task declarations successfully"""
     jsondata = """ {
         "tasks": [
                 {"sub": [["./tmp/template.parameters.dat"]]} ,
                 {"run": ["cp parameters.dat value.dat", "./tmp"]} ,
                 {"get": ["value", "tmp/value.dat", "model"]}
             ]
         }
     """
     yamldata = """
         tasks:
             - sub: [[./tmp/template.parameters.dat]]
             - run: ["cp parameters.dat value.dat", ./tmp]
             - get: [value, tmp/value.dat, model]
         """
     taskdict = {}
     update_taskdict(taskdict,
                     [['skpar.core.taskdict', ['get', 'sub', 'run']]])
     yamldata = yaml.load(yamldata)
     # print('yaml data')
     # pprint(yamldata)
     jsondata = json.loads(jsondata)
     # print('json data')
     # pprint(jsondata)
     # self.assertTrue(jsondata == yamldata) # fails for whatever reason
     tasklist = []
     userinp = yamldata
     tasklist = get_tasklist(userinp['tasks'])
     tasks = initialise_tasks(tasklist, taskdict)
     #
     var = 10
     database = Database()
     par = Parameter('p0', value=var)
     workroot = './'
     coreargs = {
         'workroot': workroot,
         'parametervalues': [par.value],
         'parameternames': [par.name]
     }
     try:
         shutil.rmtree('./tmp')
     except FileNotFoundError:
         pass
     os.makedirs('./tmp')
     with open('./tmp/template.parameters.dat', 'w') as template:
         template.writelines("%(p0)f\n")
     # with open('./tmp/template.parameters.dat', 'r') as template:
     #     tmplstr = template.readlines()
     # print(tmplstr)
     LOGGER.info('Executing tasks')
     for task in tasks:
         # LOGGER.info(task)
         task(coreargs, database)
     self.assertEqual(np.atleast_1d(var),
                      database.get('model', {}).get('value'))
     shutil.rmtree('./tmp')
示例#9
0
 def test_objtype_values_single_model_array_data(self):
     """Can we create 1d-array-values-type objective for a single model"""
     yamldata = """objectives:
         - Etot(Vol):
             doc: 'Energy-Volume dependnce of Wurtziteac structure'
             models: GaN-W-ac 
             ref: [-20.236, -21.099, -21.829, -22.45, -22.967,
                 -23.387, -23.719, -23.974, 
                 -24.158, -24.278, -24.304, -24.348, -24.309,
                 -24.228, -24.11 , -23.952, 
                 -23.769, -23.559, -23.328, -23.076, -22.809]
             options:
                 subweights: [1,1,1,1,1, 2,2,2, 3,3,3,3,3, 2,2,2, 1,1,1,1,1]
     """
     data = [-20.24,-21.1,-21.83,-22.45,-22.97,
         -23.4,-23.72,-23.97,
         -24.2,-24.3,-24.3,-24.35,-24.31, 
         -24.23,-24.11,-23.9,
         -23.77,-23.56,-23.3,-23.1,-22.8]
     logger.info(data)
     que = 'Etot(Vol)'
     ref = [-20.236, -21.099, -21.829, -22.45,-22.967,
                 -23.387, -23.719, -23.974,
                 -24.158, -24.278, -24.304,  -24.348, -24.309, 
                 -24.228, -24.11,  -23.952,
                 -23.769, -23.559, -23.328,  -23.076, -22.809]
     sbw = [1,1,1,1,1, 2,2,2, 3,3,3,3,3, 2,2,2, 1,1,1,1,1]
     sbw = np.asarray(sbw)/np.sum(sbw) # normalise
     model = 'GaN-W-ac'
     # set data base
     database = Database()
     database.update(model)
     modeldb = database.get(model)
     # check declaration
     spec = yaml.load(yamldata)['objectives'][0]
     logger.info(spec)
     objv = oo.get_objective(spec)
     self.assertEqual(objv.model_names, model)
     self.assertEqual(objv.model_weights, 1.)
     self.assertEqual(objv.weight, 1)
     nptest.assert_array_equal(objv.ref_data, ref, verbose=True)
     nptest.assert_array_equal(objv.subweights, sbw, verbose=True)
     self.assertEqual(objv.query_key, que)
     self.assertEqual(objv.objtype, 'values')
     # check __call__()
     modeldb[que] = data
     mdata, rdata, weights = objv.get(database)
     nptest.assert_array_equal(mdata, data, verbose=True)
     nptest.assert_array_equal(rdata, ref, verbose=True)
     nptest.assert_array_equal(weights, sbw, verbose=True)
示例#10
0
 def test_get_bandstructure(self):
     """Can we get the bandstructure and gap/cb/vb details?"""
     env = {}
     database = Database()
     src = 'test_dftbutils/bs'
     dst = 'test.bs'
     get_bandstructure(env, database, src, dst)
     modeldict = database.get(dst)
     nptest.assert_array_almost_equal(modeldict['bands'], self.ref_bands)
     self.assertEqual(modeldict['nkpts'], self.ref_nk)
     self.assertEqual(modeldict['nbands'], self.ref_nb)
     self.assertEqual(modeldict['Ef'], self.ref_Ef)
     self.assertEqual(modeldict['Egap'], self.ref_Eg)
     self.assertEqual(modeldict['Ecb'], self.ref_Ec)
     self.assertEqual(modeldict['Evb'], self.ref_Ev)
示例#11
0
 def test_get_dftbp_data(self):
     env = {}
     database = Database()
     #
     src = 'test_dftbutils/scc'
     dst = 'test.scc'
     get_dftbp_data(env, database, src, dst)
     modeldict = database.get(dst)
     self.assertDictEqual(modeldict, self.ref_scc)
     #
     src = 'test_dftbutils/bs'
     dst = 'test.bs'
     get_dftbp_data(env, database, src, dst)
     modeldict = database.get(dst)
     self.assertDictEqual(modeldict, self.ref_bs)
示例#12
0
 def test_evaluate_singleitem(self):
     """Can we evaluate value-type objective for a single model"""
     yamldata = """objectives:
         - item:
             models: A
             ref: 1.0
     """
     # set data base
     database = Database()
     database.update('A')
     db = database.get('A')
     # declaration of objective
     spec = yaml.load(yamldata)['objectives'][0]
     objv = oo.get_objective(spec)
     # evaluate
     db['item'] = 1.2
     self.assertAlmostEqual(0.2, objv(database))
示例#13
0
 def test_evaluate_multiplemodels_singleitem(self):
     """Can we evaluate value-type objective for multiple models"""
     yamldata = """objectives:
         - item:
             models: [A, B, C]
             ref: [2.0, 2., 3.]
             options:
                 # normalise: True
                 subweights: [2, 1, 1.5]
     """
     # set model data
     database = Database()
     db1 = {'item': 1.0}
     db2 = {'item': 1.0}
     db3 = {'item': 1.0}
     database.update('A', db1)
     _db = database.get('A')
     self.assertDictEqual(_db, db1)
     database.update('B', db2)
     database.update('C', db3)
     # declaration of objective
     spec = yaml.load(yamldata)['objectives'][0]
     objv = oo.get_objective(spec)
     # evaluate
     self.assertAlmostEqual(1.4142135623730951, objv(database))
示例#14
0
 def test_get_kvec_abscissa2(self):
     """Can we get the bandstructure and extract the kvector info"""
     latticeinfo = {'type': 'FCC', 'param': 1.}
     lat = Lattice(latticeinfo)
     database = Database()
     src = 'test_dftbutils/bs'
     get_bandstructure({'workroot': '.'}, database, src, 'test', latticeinfo=latticeinfo)
     kLines = database.get_item('test', 'kLines')
     bands = database.get_item('test', 'bands')
     logger.debug('Bands.shape: {}'.format(bands.shape))
     logger.debug('kLines     : {}'.format(kLines))
     xx, xt, xl = get_kvec_abscissa(lat, kLines)
     refxl = ['X', 'Γ', 'K', 'L', 'Γ']
     refxt = [0, 6.28319, 12.94751, 16.79516, 22.23656]
     self.assertListEqual(xl, refxl)
     nptest.assert_almost_equal(xt, refxt, 5)
     self.assertAlmostEqual(xx[-1], xt[-1])
     self.assertEqual(len(xx), kLines[-1][-1]+1)
示例#15
0
 def test_twopartemplates(self):
     """Can we parse task declarations successfully"""
     yamldata = """
         tasks:
             - sub: [[./tmp/template.par1.dat, ./tmp/template.par2.dat]]
             - run: ['bash run.sh', ./tmp]
             - get: [value, tmp/values.dat, model]
         """
     taskdict = {}
     update_taskdict(taskdict,
                     [['skpar.core.taskdict', ['get', 'sub', 'run']]])
     yamldata = yaml.load(yamldata)['tasks']
     tasklist = []
     tasklist = get_tasklist(yamldata)
     tasks = initialise_tasks(tasklist, taskdict)
     #
     var1 = 10
     var2 = 20
     database = Database()
     params = [Parameter('p0', value=var1), Parameter('p1', value=var2)]
     workroot = './'
     coreargs = {
         'parametervalues': [p.value for p in params],
         'parameternames': [p.name for p in params]
     }
     try:
         shutil.rmtree('./tmp')
     except FileNotFoundError:
         pass
     os.makedirs('./tmp')
     with open('./tmp/template.par1.dat', 'w') as template:
         template.writelines("%(p0)f\n")
     with open('./tmp/template.par2.dat', 'w') as template:
         template.writelines("%(p1)f\n")
     with open('./tmp/run.sh', 'w') as template:
         template.writelines('cat par*.dat > values.dat\n')
     for task in tasks:
         LOGGER.info(task)
         task(coreargs, database)
     self.assertListEqual([var1, var2],
                          list(database.get('model', {}).get('value')))
     shutil.rmtree('./tmp')
示例#16
0
 def test_get_effmasses_default(self):
     """Can we get effective masses in addition to band-structure, with default settings?"""
     env = {}
     database = Database()
     src = 'test_dftbutils/Si/bs'
     model = 'test.meff'
     get_bandstructure(env,
                       database,
                       src,
                       model,
                       latticeinfo={
                           'type': 'FCC',
                           'param': 5.431
                       })
     dst = database.get(model)
     # the values below are in oldskpar.debug.log in the above dir
     self.assertTrue(dst['withSOC'])
     self.assertEqual(dst['ivbtop'], 7)
     self.assertEqual(dst['nkpts'], 206)
     self.assertEqual(dst['nbands'], 36)
     self.assertAlmostEqual(dst['Ef'], -3.0621, places=3)
     self.assertAlmostEqual(dst['Egap'], 1.1289, places=3)
     self.assertAlmostEqual(dst['Ecb'], -3.06221, places=3)
     self.assertAlmostEqual(dst['Evb'], -4.19099, places=3)
     #
     ref_klines = [('L', 0), ('Gamma', 53), ('X', 113), ('U', 141),
                   ('K', 142), ('Gamma', 205)]
     ref_klinesdict = {
         'K': [142],
         'X': [113],
         'Gamma': [53, 205],
         'L': [0],
         'U': [141]
     }
     self.assertListEqual(dst['kLines'], ref_klines)
     self.assertDictEqual(dst['kLinesDict'], ref_klinesdict)
     get_effmasses(env, database, model, model)
     ref_meff_tags = ['me_LG', 'me_GX', 'me_XU', 'me_KG']
     ref_meff_tags.extend(['mh_LG', 'mh_GX', 'mh_XU', 'mh_KG'])
     self.assertTrue(all([key in dst for key in ref_meff_tags]))
示例#17
0
 def test_objtype_weightedsum(self):
     """Can we create objective from pairs of value-weight"""
     yamldata = """objectives:
         - Etot:
             doc: "heat of formation, SiO2"
             models: 
                 - [SiO2-quartz/scc, 1.]
                 - [Si/scc, -0.5] 
                 - [O2/scc, -1]
             ref: 1.8 
             weight: 1.2
     """
     spec = yaml.load(yamldata)['objectives'][0]
     que = 'Etot'
     ref = spec[que]['ref']
     doc = spec[que]['doc']
     oww = spec[que]['weight']
     mnm = [m[0] for m in spec[que]['models']]
     mww = np.asarray([m[1] for m in spec[que]['models']])
     subw = 1.
     # set data base: 
     # could be done either before or after declaration
     database = Database()
     # check declaration
     objv = oo.get_objective(spec)
     self.assertEqual(objv.doc, doc)
     self.assertEqual(objv.weight, oww)
     self.assertEqual(objv.model_names, mnm)
     nptest.assert_array_equal(objv.model_weights, mww, verbose=True)
     self.assertEqual(objv.ref_data, ref)
     self.assertEqual(objv.subweights, subw)
     self.assertEqual(objv.query_key, 'Etot')
     self.assertEqual(objv.objtype, 'weighted_sum')
     dat = [20, 12, 16]
     database.update('SiO2-quartz/scc', {'Etot': dat[0]})
     database.update('Si/scc', {'Etot': dat[1]})
     database.update('O2/scc', {'Etot': dat[2]})
     # check __call__()
     mdat, rdat, weights = objv.get(database)
     nptest.assert_array_equal(mdat, np.dot(np.asarray(dat), np.asarray(mww)), verbose=True)
     nptest.assert_array_equal(rdat, ref, verbose=True)
     nptest.assert_array_equal(weights, subw, verbose=True)
示例#18
0
    def evaluate(self, parametervalues, iteration=None):
        """Evaluate the global fitness of a given point in parameter space.

        This is the only object accessible to the optimiser, therefore only
        two arguments can be passed.

        Args:
            parametervalues (list): current point in design/parameter space
            iteration: (int or tupple): current iteration or current
                generation and individual index within generation

        Return:
            fitness (float): global fitness of the current design point
        """

        # Create individual working directory for each evaluation
        origdir = os.getcwd()
        workroot = self.config['workroot']
        if workroot is None:
            workdir = origdir
        else:
            workdir = get_workdir(iteration, workroot)
            create_workdir(workdir, self.config['templatedir'])

        # Initialise model database
        self.logger.info('Initialising ModelDataBase.')
        # database may be something different than a dictionary, but
        # whatever object it is, should have:
        #     update_modeldb(modelname, datadict) -- update modeldb
        #     get_modeldb(modelname) -- return a ref to modeldb
        # The point is that for every individual evaluation, we must
        # have individual model DB, so evaluations can be done in parallel.
        database = Database()
        # database = {} currently works too
        # Wrap the environment in a single dict
        env = {
            'workroot': workdir,
            'logger': self.logger,
            'parameternames': self.parnames,
            'parametervalues': parametervalues,
            'iteration': iteration,
            'taskdict': self.taskdict,
            'objectives': self.objectives
        }
        # Initialise and then execute the tasks
        tasks = initialise_tasks(self.tasklist, self.taskdict, report=False)
        self.logger.info('Iteration %s', iteration)
        self.logger.info('===========================')
        if self.parnames:
            parstr = [
                '{:s}({:.4g})'.format(name, val)
                for name, val in zip(self.parnames, parametervalues)
            ]
            self.logger.info('Parameters: {:s}'.format(' '.join(parstr)))


#        do we really need to pass workdir and to os.chdir???
#        move the for loop to a function.
#        execute_tasks(tasks, env, database, workdir, logger)
        for i, task in enumerate(tasks):
            os.chdir(workdir)
            try:
                task(env, database)
            except:
                self.logger.critical('Task %i FAILED:\n%s', i, task)
                raise

        # Evaluate individual fitness for each objective
        objvfitness = eval_objectives(self.objectives, database)
        # Evaluate global fitness
        cost = self.costf(self.utopia, objvfitness, self.weights)
        self._msg('{:<15s}: {}\n'.format('Overall cost', cost))

        # Remove iteration-specific working dir if not needed:
        if (not self.config['keepworkdirs']) and (workroot is not None):
            destroy_workdir(workdir)
        os.chdir(origdir)

        return np.atleast_1d(cost)
示例#19
0
    def test_parse_input(self):
        """Can we parse input, create an optimiser instance, and run the tasks?
        """
        filename = "skpar_in_optimise.yaml"
        taskdict, tasklist, objectives, optimisation, config =\
            parse_input(filename)
        print (taskdict)
        print (tasklist)
        workroot = config.get('workroot', None)
        templatedir = config.get('templatedir', None)
        create_workdir(workroot, templatedir)
        algo, options, parameters = optimisation
        parnames = [p.name for p in parameters]
        evaluate = Evaluator(objectives, tasklist, taskdict, parnames, config)
        optimiser = Optimiser(algo, parameters, evaluate, options)
        # initialise parameter values, pretending to be optimisation engine
        params = np.array([10.0, -2.5, 0.5, 0.05])
        for pini, par in zip(params, optimiser.parameters):
            par.value = pini
        logger.debug ("### ---------------------------------------- ###")
        logger.debug ("### ----------- Parameters ----------------- ###")
        logger.debug ("### ---------------------------------------- ###")
        for pp in optimiser.parameters:
            logger.debug (pp)

        # initialise tasks manually
        optimiser.evaluate.tasks = initialise_tasks(tasklist, taskdict,
                                                    report=True)
        env = {'workroot': workroot,
               'parameternames': parnames,
               'parametervalues': params,
               'iteration': None}
        workdir = workroot
        database = Database()

        # check task 0
        self.assertEqual(optimiser.evaluate.tasks[0].name, 'set')
        self.assertEqual(optimiser.evaluate.tasks[0].func,
                         core_taskdict.substitute_parameters)
        self.assertEqual(optimiser.evaluate.tasks[0].args,
                         [['template.parameters.dat']])
        optimiser.evaluate.tasks[0](env, database)
        parfile = os.path.abspath(os.path.join(workdir, 'parameters.dat'))
        raw = np.loadtxt(parfile, dtype=[('keys', 'S15'), ('values', 'float')])
        _values = np.array([pair[1] for pair in raw])
        _names = [pair[0].decode("utf-8") for pair in raw]
        nptest.assert_array_equal(params, _values)
        self.assertListEqual(parnames, _names)

        # check task 1
        exe = 'python3'.split()
        self.assertEqual(optimiser.evaluate.tasks[1].name, 'run')
        self.assertEqual(optimiser.evaluate.tasks[1].func,
                         core_taskdict.execute)
        self.assertEqual(optimiser.evaluate.tasks[1].args,
                         ['python3 model_poly3.py'])
        optimiser.evaluate.tasks[1](env, database)

        # check task 2
        self.assertEqual(optimiser.evaluate.tasks[2].name, 'get')
        self.assertEqual(optimiser.evaluate.tasks[2].func,
                         core_taskdict.get_model_data)
        self.assertEqual(optimiser.evaluate.tasks[2].args,
                         ['yval', 'model_poly3_out.dat', 'poly3'])
        optimiser.evaluate.tasks[2](env, database)
        modeldb = database.get('poly3') 
        self.assertTrue(modeldb is not None)
        datafile = os.path.abspath(os.path.join(workdir, 'model_poly3_out.dat'))
        dataout = np.loadtxt(datafile)
        nptest.assert_array_equal(modeldb['yval'], dataout)
        logger.debug("Model DB poly3:")
        logger.debug(database.get('poly3').items())
示例#20
0
 def test_database(self):
     """Can we update model DB"""
     database = Database()
     self.assertTrue(database is not None)
     #
     database.update('m1', {'i1': 42})
     self.assertDictEqual(database.all(), {'m1': {'i1': 42}})
     #
     database.update('m1', {'i1': 33})
     self.assertDictEqual(database.all(), {'m1': {'i1': 33}})
     #
     database.update('m2', {'i1': 10})
     self.assertDictEqual(database.all(), {'m1': {'i1': 33},
                                           'm2': {'i1': 10}})
     #
     database.update('m2', {'i2': 20})
     self.assertDictEqual(database.all(), {'m1': {'i1': 33},
                                           'm2': {'i1': 10,
                                                  'i2': 20}})
     update(database, 'm1', {'i2': 25})
     self.assertDictEqual(database.all(), {'m1': {'i1': 33,
                                                  'i2': 25},
                                           'm2': {'i1': 10,
                                                  'i2': 20}})
     database.update({'m2': {'i3': 40}})
     self.assertDictEqual(database.all(), {'m1': {'i1': 33,
                                                  'i2': 25},
                                           'm2': {'i3': 40}})
     #
     mdb = database.get('m2')
     self.assertDictEqual(mdb, {'i3': 40})
     self.assertEqual(database.get_item('m1', 'i2'), 25)
     #
     # check query initialised without database
     query = Query('m2', 'i1')
     self.assertEqual(query(database, atleast_1d=False), None)
     query = Query('m2', 'i3')
     self.assertEqual(query(database, atleast_1d=False), 40)
     #
     # check query initialised with database within database.query method
     self.assertEqual(database.query('m1', 'i1', atleast_1d=False), 33)
     nptest.assert_array_equal(database.query('m1', 'i1'), [33])
     #
     database.clear()
     self.assertDictEqual(database.all(), {})
示例#21
0
    def test_objtype_bands(self):
        """Can we create objective from spec for bands?"""
        yamldata = """objectives:
            - bands: 
                doc: Valence Band, Si
                models: Si/bs
                ref: 
                    file: ./reference_data/fakebands.dat 
                    loader_args: {unpack: True}
                    process:       # eliminate unused columns, like k-pt enumeration
                        # indexes and ranges below refer to file, not array, 
                        # i.e. independent of 'unpack' loader argument
                        rm_columns: 1                # filter k-point enumeration, and bands, potentially
                        # rm_rows   : [[18,36], [1,4]] # filter k-points if needed for some reason
                        # scale     : 1                # for unit conversion, e.g. Hartree to eV, if needed
                options:
                    use_ref: [[2, 4]]                # fortran-style index-bounds of bands to use
                    use_model: [[1, 3]]              # model has lesser number of bands
                    # Alignment works after data has been masked by use_* clause, and therefore
                    # the indexes below do not correspond to original but masked array
                    align_ref: [3, max]              # fortran-style index of band and k-point,
                    align_model: [3, max]            # or a function (e.g. min, max) instead of k-point
                    normalise: false
                    subweights: 
                        # NOTABENE:
                        # --------------------------------------------------
                        # Energy values are with respect to the ALIGNEMENT.
                        # If we want to have the reference  band index as zero,
                        # we would have to do tricks with the range specification 
                        # behind the curtain, to allow both positive and negative 
                        # band indexes, e.g. [-3, 0], INCLUSIVE of either boundary.
                        # Currently this is not done, so only standard Fortran
                        # range spec is supported. Therefore, band 1 is always
                        # the lowest lying, and e.g. band 4 is the third above it.
                        # --------------------------------------------------
                        dflt: 1
                        values: # [[range], subweight] for E-k points in the given range of energy
                        # notabene: the range below is with respect to the alignment value
                            - [[-0.2, 0.], 3.5]
                        bands: # [[range], subweight] of bands indexes; fortran-style
                            - [[2, 3], 1.5]   # two valence bands below the top VB
                            - [4 , 3.0]       # emphasize the reference band
                        # not supported yet     ipoint:
                weight: 1.0
            """
        spec = yaml.load(yamldata)['objectives'][0]
        que  = 'bands'
        doc  = spec[que]['doc']
        model  = 'Si/bs'
        mww = [1]
        oww  = 1
        ref  = np.loadtxt('reference_data/fakebands.dat', unpack=True)
        ref  = ref[2:5] # remove 1st col of file(k-pt enum.), consider first 3 bands from 2nd
        shift = -0.4 # this is the top of the VB (cf: fakebands.dat)
        ref -= shift
        shape = ref.shape
        # we have use_model => only a subset of bands is needed
        subset_ind = np.array([0,1,2])
        # subweights
        subw  = np.ones(shape)
        subw[1:2] = 1.5
        subw[2] = 3.0
        # subweights on value are the last one to be applied
        subw[ref > -0.2] = 3.5
        subw = subw/np.sum(subw)
        database = Database()
#        # check declaration
        objv = oo.get_objective(spec)
        self.assertEqual(objv.doc, doc)
        self.assertEqual(objv.query_key, que)
        self.assertEqual(objv.weight, oww)
        self.assertEqual(objv.model_names, model)
        nptest.assert_array_equal(objv.model_weights, mww)
        nptest.assert_array_equal(objv.ref_data, ref, verbose=True)
        nptest.assert_array_equal(objv.subset_ind, subset_ind, verbose=True)
        nptest.assert_array_equal(objv.subweights, subw, verbose=True)
        # check the __call__()
        data = np.loadtxt("reference_data/fakebands-2.dat", unpack=True)
        database.update('Si/bs', {'bands': data[1:]})
        mdat, rdat, weights = objv.get(database)
        nptest.assert_array_almost_equal(mdat, ref, decimal=2, verbose=True)
        nptest.assert_array_equal(rdat, ref, verbose=True)
        nptest.assert_array_equal(weights, subw, verbose=True)
示例#22
0
 def test_objtype_values_multiple_models(self):
     """Can we create a value-type objective from several models"""
     yamldata = """objectives:
         - Etot:
             doc: Energy vs volume, Si
             models: [Si/scc-1, Si/scc, Si/scc+1,]
             ref: [23., 10, 15.]
             options:
                 normalise: false
                 subweights: [1., 3., 1.,]
     """
     spec = yaml.load(yamldata)['objectives'][0]
     que = 'Etot'
     ref = [23., 10, 15.]
     mnm = ['Si/scc-1', 'Si/scc', 'Si/scc+1',]
     subw = [1., 3., 1.]
     # check declaration
     objv = oo.get_objective(spec)
     self.assertEqual(objv.model_names, mnm)
     self.assertEqual(objv.weight, 1)
     nptest.assert_array_equal(objv.model_weights, [1]*3, verbose=True)
     nptest.assert_array_equal(objv.ref_data, ref, verbose=True)
     nptest.assert_array_equal(objv.subweights, subw, verbose=True)
     self.assertEqual(objv.query_key, que)
     # set data base: 
     # could be done either before or after declaration
     database = Database()
     database.update('Si/scc-1')
     database.update('Si/scc')
     database.update('Si/scc+1')
     dat = [20, 12, 16]
     database.update('Si/scc-1', {'Etot': dat[0]})
     database.update('Si/scc', {'Etot': dat[1]})
     database.update('Si/scc+1', {'Etot': dat[2]})
     # check __call__()
     mdat, rdat, weights = objv.get(database)
     nptest.assert_array_equal(mdat, dat, verbose=True)
     nptest.assert_array_equal(rdat, ref, verbose=True)
     nptest.assert_array_equal(weights, subw, verbose=True)
示例#23
0
 def test_get_effmasses_select(self):
     """Can we get select effective masses with a control options?"""
     env = {}
     database = Database()
     model = 'test.meff'
     # NOTABENE: the refdata here is from SOC calculation!!!
     src = 'test_dftbutils/Si/bs'
     get_bandstructure(env,
                       database,
                       src,
                       model,
                       latticeinfo={
                           'type': 'FCC',
                           'param': 5.431
                       })
     dst = database.get(model)
     directions = ['Gamma-X', 'Gamma-L', 'Gamma-K']
     # Example how to extract different masses over a different energy window:
     # Note that subsequent extractions overwrite final data in dst, so we start with
     # the deepest bands, and than reduce the number of bands, towards to top of VB
     # The energy window should be adjusted depending on the anticipated curvature of the band
     get_effmasses(env,
                   database,
                   model,
                   model,
                   directions=directions,
                   carriers='e',
                   nb=1,
                   Erange=0.005,
                   usebandindex=True)
     # get the lowest band masses: (spin-orbit); forceErange seems to not work properly?
     get_effmasses(env,
                   database,
                   model,
                   model,
                   directions=directions,
                   carriers='h',
                   nb=5,
                   Erange=0.0015,
                   forceErange=True)
     # get the light hole bands (3 and 4)
     get_effmasses(env,
                   database,
                   model,
                   model,
                   directions=directions,
                   carriers='h',
                   nb=3,
                   Erange=0.008)
     # get the top two (heavy hole) bands (1 and 2); enforce indexing! (i.e. add _0)
     get_effmasses(env,
                   database,
                   model,
                   model,
                   directions=directions,
                   carriers='h',
                   nb=1,
                   Erange=0.002,
                   usebandindex=True)
     self.assertAlmostEqual(dst['me_GX_0'], 0.935, places=3)
     self.assertAlmostEqual(dst['mh_GX_0'], -0.278, places=2)
     self.assertAlmostEqual(dst['mh_GK_0'], -1.891, places=3)
     self.assertAlmostEqual(dst['mh_GL_0'], -0.633, places=3)
     self.assertAlmostEqual(dst['mh_GX_2'], -0.286, places=3)
     self.assertAlmostEqual(dst['mh_GK_2'], -0.362, places=3)
     self.assertAlmostEqual(dst['mh_GL_2'], -2.2426, places=3)
     self.assertAlmostEqual(dst['mh_GX_4'], -0.1389, places=3)
     self.assertAlmostEqual(dst['mh_GK_4'], -0.095, places=3)
     self.assertAlmostEqual(dst['mh_GL_4'], -0.086, places=3)
     self.assertAlmostEqual(dst['cbminpos_GX_0'], 0.817, places=2)