Source code for latticeinputs.bmdl

# -*- coding: utf-8 -*-
"""
Created on Wed Dec  3 15:09:24 2014

@author: Matti Ropo
@author: Henrik Levämäki

"""

from __future__ import print_function
import sys
import datetime
import pyemto.common.common as common
import numpy as np

[docs]class Bmdl: """Contains information about BMDL input files for EMTO 5.8 program. :param jobname_lat: (Default value = None) :type jobname_lat: :param lat: (Default value = None) :type lat: :param latparams: (Default value = None) :type latparams: :param latvectors: (Default value = None) :type latvectors: :param basis: (Default value = None) :type basis: :param msgl: (Default value = None) :type msgl: :param nprn: (Default value = None) :type nprn: :param bmdl_nl: (Default value = None) :type bmdl_nl: :param lamda: (Default value = None) :type lamda: :param amax: (Default value = None) :type amax: :param bmax: (Default value = None) :type bmax: :param nqr2: (Default value = None) :type nqr2: :param ca: hcp c/a ratio (Default value = None) :type ca: float :returns: None :rtype: None """ def __init__(self, jobname_lat=None, lat=None, latparams=None, latvectors=None, basis=None, msgl=None, nprn=None, bmdl_nl=None, lamda=None, amax=None, bmax=None, nqr2=None, ca=None): self.lat = lat self.jobname_lat = jobname_lat self.latparams = latparams self.latvectors = latvectors if basis is None: self.basis = None else: self.basis = np.asarray(basis) self.msgl = msgl self.nprn = nprn self.bmdl_nl = bmdl_nl self.lamda = lamda self.amax = amax self.bmax = bmax self.nqr2 = nqr2 self.ca = ca # hcp's c/a
[docs] def output(self): """Outputs BMDL input file as a formatted string Creates a long string containing the batch job script which will later be written on disk. :returns: batch script input file :rtype: str """ mdlfile = "bmdl/" prnfile = "bmdl/" now = datetime.datetime.now() line = "BMDL HP......=N "\ + str(now.day) + "." + str(now.month) + "." + str(now.year) + "\n" JOBNAMline = "JOBNAM...=" + self.jobname_lat MSGLline = "MSGL.= " + str(self.msgl) NPRNline = "NPRN.= " + str(self.nprn) line = line + \ "{0:21s}{1:9s} {2:9s}".format( JOBNAMline, MSGLline, NPRNline) + "\n" line = line + "DIR001=" + mdlfile + "\n" line = line + "DIR006=" + prnfile + "\n" line = line + "Madelung potential for {0}".format(self.jobname_lat) + "\n" line = line + "NL.....={0:2d}".format(self.bmdl_nl) + "\n" line = line + "LAMDA....= {0:4.2f} AMAX....= {1:4.2f} BMAX....= {2:4.2f}"\ .format(self.lamda, self.amax, self.bmax) + "\n" line = line + "NQ....={0:3d} LAT...={1:2d} IPRIM.= {2} NQR2..= {3}"\ .format(self.nq, common.lat_to_ibz(self.lat), self.iprim, self.nqr2) + "\n" line = line + "A........={0:10.8f} B.......={1:10.8f} C.......={2:10.8f}"\ .format(self.latparams[0], self.latparams[1], self.latparams[2]) + "\n" if self.iprim == 1: line = line + "ALPHA....={0:10.6f} BETA....={1:10.6f} GAMMA...={2:10.6f}"\ .format(self.latvectors[0], self.latvectors[1], self.latvectors[2]) + "\n" elif self.iprim == 0: line = line + "BSX......={0:10.7f} BSY.....={1:10.7f} BSZ.....={2:10.7f}"\ .format(self.latvectors[0][0], self.latvectors[0][1], self.latvectors[0][2]) + "\n" line = line + "BSX......={0:10.7f} BSY.....={1:10.7f} BSZ.....={2:10.7f}"\ .format(self.latvectors[1][0], self.latvectors[1][1], self.latvectors[1][2]) + "\n" line = line + "BSX......={0:10.7f} BSY.....={1:10.7f} BSZ.....={2:10.7f}"\ .format(self.latvectors[2][0], self.latvectors[2][1], self.latvectors[2][2]) + "\n" for i in range(self.nq): line = line + "QX({3:03})..={0:10.7f} QY({3:03}).={1:10.7f} QZ({3:03}).={2:10.7f}"\ .format(self.basis[i,0], self.basis[i,1], self.basis[i,2], i + 1) + "\n" return line
[docs] def write_input_file(self, folder=None): """Save BMDL input data to file named by self.jobname_lat :param folder: (Default value = None) :type folder: :returns: :rtype: """ # Check data integrity before anything is written on disk or run self.check_input_file() if folder is None: #sys.exit('Bmdl.write_input_file: \'folder\' has to be given!') folder = "./" else: common.check_folders(folder) fl = open(folder + '/{0}.bmdl'.format(self.jobname_lat), "w") fl.write(self.output()) fl.close()
[docs] def set_values(self, key, value): """ :param key: :type key: :param value: :type value: :returns: :rtype: """ if hasattr(self, key): setattr(self, key, value) if key == 'ca' and self.lat == 'hcp': # c/a has changed => update lattice parameters self.latparams = [1.0, 1.0, self.ca] self.latvectors = [ [1.0, 0.0, 0.0], [-0.5, 0.8660254, 0.0], [0.0, 0.0, self.ca]] self.basis = np.asarray([ [0.0, 0.0, 0.0], [0.0, 0.57735027, self.ca / 2.0]]) else: print('WARNING: Bmdl() class has no attribute \'{0}\''.format(key)) return
[docs] def check_input_file(self): """Perform various checks on the class data. Makes sure that all necessary data exists before we attempt to write the input file to disk. :returns: None :rtype: None """ if self.ca is None and self.lat == 'hcp': #sys.exit('Bmdl.check_input_file: for hcp \'ca\' = c/a has to be given!') self.ca = 1.632993 if self.lat is None: sys.exit('Bmdl.check_input_file: \'lat\' has to be given!') elif self.jobname_lat is None and self.lat is not None: self.jobname_lat = self.lat if self.latparams is None: if self.lat == 'hcp': self.latparams = [1.0, 1.0, self.ca] else: self.latparams = [1.0, 1.0, 1.0] if self.latvectors is None: if self.lat == 'sc': self.latvectors = [ [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]] elif self.lat == 'bcc': self.latvectors = [ [0.5, 0.5, -0.5], [0.5, -0.5, 0.5], [-0.5, 0.5, 0.5]] elif self.lat == 'fcc': self.latvectors = [ [0.0, 0.5, 0.5], [0.5, 0.0, 0.5], [0.5, 0.5, 0.0]] elif self.lat == 'hcp': self.latvectors = [ [1.0, 0.0, 0.0], [-0.5, 0.8660254, 0.0], [0.0, 0.0, self.ca]] if self.basis is None: if self.lat == 'hcp': self.basis = np.asarray([ [0.0, 0.0, 0.0], [0.0, 0.57735027, self.ca / 2.0]]) else: self.basis = np.array([[0.0, 0.0, 0.0]]) # Make sure basis is a numpy array of shape np.array([[xxx], [xxx]]) if isinstance(self.basis, list): self.basis = np.asarray(self.basis) elif isinstance(self.basis, np.ndarray): pass if len(self.basis.shape) == 1: self.basis = np.asarray([self.basis]) self.nq = self.basis.shape[0] if isinstance(self.latvectors[0], list): if len(self.latvectors) == 1: self.iprim = 1 else: self.iprim = 0 else: self.iprim = 1 if self.msgl is None: self.msgl = 1 if self.nprn is None: self.nprn = 0 if self.bmdl_nl is None: self.bmdl_nl = 7 if self.lamda is None: self.lamda = 2.5 if self.amax is None: self.amax = 4.5 if self.bmax is None: self.bmax = 4.5 if self.nqr2 is None: self.nqr2 = 0 return