def compute_bs(): from numpy import array from pylada.escan import read_input, exec_input, ReducedBPoints from pylada.vff import Vff # reads input file. input = read_input("input.py") # creating unrelaxed structure. structure = input.vff.lattice.to_structure() structure.atoms[0].type = "Si" structure.atoms[1].type = "Ge" structure.scale = 5.65 # some kpoints + associated name X = array( [1,0,0], dtype="float64" ) G = array( [0,0,0], dtype="float64" ) L = array( [0.5,0.5,0.5], dtype="float64" ) W = array( [0, 0.5,1], dtype="float64" ) # Each job is performed for a given kpoint (first argument), at a given # reference energy (third argument). Results are stored in a specific directory # (second arguement). The expected eigenvalues are given in the fourth argument. input = read_input('input.py') kescan = exec_input(repr(input.escan).replace('Escan', 'KEscan')).functional kescan.fft_mesh = 14, 14, 14 kescan.kpoints = ReducedBPoints(density=20) + (X, G) + (G, L) result = kescan( structure, outdir='results/projections', nbstates = len(structure.atoms) * 4 + 4, eref = None )
def gajobs(path, inputpath = "input.py"): from copy import deepcopy import IPython.ipapi from numpy import array, all from pylada.ga.escan.elemental.functional import Darwin as Functional from pylada.ga.escan.elemental.evaluator import EffectiveMass as Evaluator from pylada.ga.escan.elemental import Converter from pylada.ga.functional import minimize from pylada.jobs import JobFolder from pylada.escan import read_input # reads input file. input = read_input(inputpath) jobfolder = JobFolder() for type in ["ee", "hh"]: for direction in ["epi", "perp"]: for scale in input.scales: for range in input.ranges: nmin, nmax = min(range), max(range) for trial in input.trials: escan = deepcopy(input.escan) escan.vff.lattice.scale = scale if direction == "perp": escan.direction = input.growth_direction elif all(array(input.growth_direction) - (0,0,1) == (0,0,0)): escan.direction = (1, 0, 0), (0, 1, 0) elif all(array(input.growth_direction) - (1,1,0) == (0,0,0)): escan.direction = (0, 0, 1), (-1, 1, 0) else: raise ValueError("Unknown growth direction.") if type == "ee": escan.type = "e" elif type == "hh" or type == "lh": escan.type = "h" converter = Converter(growth=input.growth_direction, lattice=escan.vff.lattice) kwargs = { "popsize": input.population_size, "rate": input.offspring_rate, "max_gen": input.max_generations, "pools": input.pools, "crossover_rate": input.crossover_rate, "swap_rate": input.swap_rate, "growth_rate": input.growth_rate, "nmin": nmin, "nmax": nmax, "dosym": input.dosym, "rootworkdir": "$GSCRATCH", "comparison": minimize } kwargs.update(getattr(input, 'kwargs', {})) evaluator = Evaluator( converter = converter, functional = escan, **getattr(input, 'kwargs', {}) ) functional = Functional(evaluator, **kwargs) functional.n = slice(2,4) if type == "lh" else slice(0,2) name = "{0[0]}{0[1]}{0[2]}/{1}/{2}/"\ .format(input.growth_direction, direction, type) name += "scale_{0:.2f}/{1}_{2}/trial_{3}".format(scale, nmin, nmax, trial) gajob = jobfolder / name gajob.functional = functional ip = IPython.ipapi.get() ip.user_ns["current_jobfolder"] = jobfolder ip.magic("savejobs " + path)
def gajobs(path, inputpath="input.py"): from copy import deepcopy import IPython.ipapi from pylada.ga.escan.elemental.functional import Darwin as Functional from pylada.ga.escan.elemental.evaluator import Dipole as Evaluator from pylada.ga.escan.elemental import LayeredConverter as Converter from pylada.jobs import JobFolder from pylada.escan import read_input # reads input file. input = read_input(inputpath) jobfolder = JobFolder() for scale in input.scales: for p in input.periods: for trial in input.trials: supercell = input.supercell(p) escan = deepcopy(input.escan) escan.fft_mesh = input.fftmesh(supercell) escan.vff.lattice.scale = scale converter = Converter(supercell, lattice=escan.vff.lattice) evaluator = Evaluator(converter=converter, escan=escan, **input.kwargs) evaluator._outdir.envvar = "$SCRATCH" functional = Functional(evaluator) functional.popsize = input.population_size functional.max_gen = input.max_generations functional.rate = input.offspring_rate functional.mean_conc = input.mean_conc functional.stddev_conc = input.stddev_conc functional.pools = input.pools gajob = jobfolder / "scale_{0:.2f}/period_{1}/trial_{2}".format(scale, p, trial) gajob.functional = functional ip = IPython.ipapi.get() ip.user_ns["current_jobfolder"] = jobfolder ip.magic("savejobs " + path)
def gajobs(path, inputpath = "input.py"): from copy import deepcopy import IPython.ipapi from pylada.ga.escan.elemental.functional import Darwin as Functional from pylada.ga.escan.elemental.evaluator import Dipole as Evaluator from pylada.ga.escan.elemental import Converter from pylada.jobs import JobFolder from pylada.escan import read_input # reads input file. input = read_input(inputpath) jobfolder = JobFolder() for scale in input.scales: for range in input.ranges: nmin, nmax = min(range), max(range) for trial in input.trials: escan = deepcopy(input.escan) escan.vff.lattice.scale = scale converter = Converter(growth=input.growth_direction, lattice=escan.vff.lattice) kwargs = { "popsizse": input.population_size, "rate": input.offspring_rate, "max_gen": input.max_generations, "pools": input.pools, "crossover_rate": input.crossover_rate, "swap_rate": input.swap_rate, "growth_rate": input.growth_rate, "nmin": nmin, "nmax": nmax, "dosym": input.dosym, "rootworkdir": input.rootworkdir } kwargs.update(getattr(input, 'kwargs', {})) evaluator = Evaluator( converter = converter, functional = escan, **getattr(input, 'kwargs', {}) ) functional = Functional(evaluator, **kwargs) gajob = jobfolder / "{4[0]}{4[1]}{4[2]}/scale_{0:.2f}/{1}_{2}/trial_{3}"\ .format(scale, nmin, nmax, trial, input.growth_direction) gajob.functional = functional ip = IPython.ipapi.get() ip.user_ns["current_jobfolder"] = jobfolder ip.magic("savejobs " + path)
# You should have received a copy of the GNU General Public License along with PyLaDa. If not, see # <http://www.gnu.org/licenses/>. ############################### from sys import exit from shutil import rmtree from os.path import exists, join from math import ceil, sqrt from numpy import dot, array, matrix from numpy.linalg import norm from boost.mpi import world from pylada.vff import Vff from pylada.crystal import Structure, Lattice, fill_structure from pylada.escan import read_input input = read_input("input.py") structure = Structure() structure.set_cell = (4, 0, 0.5),\ (0, 1, 0),\ (0, 0, 0.5) structure = fill_structure(structure.cell) for i, atom in enumerate(structure.atoms): atom.type = "Si" if i < len(structure.atoms)/2 else "Ge" result_str = Structure() result_str.scale = 5.450000e+00 result_str.set_cell = (4.068890e+00, -4.235770e-18, 5.083297e-01),\ (-1.694308e-17, 1.016103e+00, 2.238072e-18),\ (-2.252168e-03, 8.711913e-18, 5.083297e-01)
def create_sl(path, direction, nmin, nmax, nstep, x=0.5, density=10e0, input='input.py'): """ Creates dictionary of superlattices. :Parameters: path : str Path to output dictionary. direction : callable(int)->(3x3, 3x1) A callable taking the number of layers on input and returning a tuple consisting of a supercell with the correct number of layers and the direction of growth of the superlattice. The supercell must be have the correct periodicity: two vectors should be parallel to the substrate such that layers can actually be defined. Otherwise, there is not one-to-one correspondance between atoms and layers: the same atom could belong to different layers. A number of examples are given in this module: `direction001`, `direction011`, `direction111`. nmin : int Minimum number of layers. nmax : int Maximum number of layers (excluded). nstep : int Step between layers: [``nmin``, ``nmin``+``nstep``, ``nmin``+2*``nstep``, ..., ``nmax``[ x : float Concentration in Si of the superlattice. Should be between 0 and 1. density : float Kpoint density for escan calculations, input : str Path to input file containing escan functional. """ from IPython.ipapi import get as get_ipy from numpy.linalg import norm, inv from pylada.jobs import JobFolder from pylada.escan import read_input, exec_input, ReducedKDensity from pylada.crystal.binary import zinc_blende from pylada.crystal import layer_iterator ip = get_ipy() input = read_input(input) kescan = exec_input(repr(input.escan).replace('Escan', 'KEscan')).functional lattice = zinc_blende() lattice.sites[0].type = 'Si', 'Ge' lattice.sites[1].type = 'Si', 'Ge' lattice.scale = 5.45 lattice.find_space_group() density = 10e0 * max([1e0/norm(u) for u in inv(lattice.cell)]) rootjobs = ip.user_ns.get('current_jobfolder', JobFolder()) for n0 in range(nmin, nmax, nstep): # create structure cell, dir = direction(n0) structure = lattice.to_structure(cell) # reduction not necessary if cell function done right. N0 = int(len([0 for layer in layer_iterator(structure, dir)]) * x+1e-8) for i, layer in enumerate(layer_iterator(structure, dir)): for atom in layer: atom.type = 'Si' if i < N0 else 'Ge' xp = float(len([0 for atom in structure.atoms if atom.type == 'Si'])) xp /= float(len(structure.atoms)) assert abs(xp - x) < 1e-12 # name and scale. structure.name = "{0[0]}{0[1]}{0[2]}/x_{1:0<4.3}/n_{2}".format(dir, x, n0) structure.scale = scale(structure) # creates job-folder. jobfolder = rootjobs / structure.name jobfolder.jobparams['structure'] = structure.copy() jobfolder.functional = kescan.copy() jobfolder.functional.kpoints = ReducedKDensity(density, (0.5, 0.5, 0.5)) jobfolder.functional.reference = None jobfolder.functional.fft_mesh = fftmesh(structure.cell) jobfolder.functional.nbstates = int(len(structure.atoms) * 4 * 1.5+0.5) if 'current_jobfolder' not in ip.user_ns: ip.user_ns["current_jobfolder"] = rootjobs ip.magic("savejobs " + path) return
from math import fabs as abs from numpy import array from pylada.crystal import fill_structure from pylada.escan import read_input from pylada.escan.emass import Functional input = read_input("input.py", namespace = {"Escan": Functional}) G = array([0,0,0], dtype="float64") X = array([0,0,1], dtype="float64") structure = fill_structure(input.vff.lattice.cell, input.vff.lattice) input.escan.nbstates = len(structure.atoms) * 4 + 4 input.escan.tolerance = 1e-12 orig = input.escan( structure, direction=(0,0,1), outdir="results/emass/100", \ do_relax_kpoint=False, type="e" ) assert abs(orig.mass[0] - 0.4381) < 0.01 # Gamma conduction emass result = input.escan( structure, direction=((0,0,1), (1,1,1)), outdir="results/hmass", \ do_relax_kpoint=False, type="h", bandgap=orig.extract_bg ) assert abs(result.mass[0][0] - 0.2769) < 0.01 # Gamma conduction heavy hmass (100 direction) assert abs(result.mass[0][2] - 0.2059) < 0.01 # Gamma conduction light hmass (100 direction) assert abs(result.mass[1][0] - 0.6885) < 0.01 # Gamma conduction heavy hmass (111 direction) assert abs(result.mass[1][2] - 0.1460) < 0.01 # Gamma conduction light hmass (111 direction)
# your option) any later version. # # PyLaDa is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even # the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along with PyLaDa. If not, see # <http://www.gnu.org/licenses/>. ############################### from numpy import array from pylada.escan import read_input, exec_input, ReducedBPoints from pylada.crystal.binary import zinc_blende X = array( [1,0,0], dtype="float64" ) G = array( [0,0,0], dtype="float64" ) L = array( [0.5,0.5,0.5], dtype="float64" ) W = array( [0, 0.5,1], dtype="float64" ) input = read_input('input.py') kescan = exec_input(repr(input.escan).replace('Escan', 'KEscan')).functional structure = zinc_blende().to_structure(subs={'A':'Si', 'B':'Si'}) structure.scale = 5.45 kescan.fft_mesh = 14, 14, 14 kescan.kpoints = ReducedBPoints(density=20) + (X, G) + (G, L) result = kescan( structure, outdir='results/kescan', nbstates = len(structure.atoms) * 4 + 4, eref = None )
def create_start(path, nall = 3, nrand = 5, nmax=100, density=10e0, input='input.py'): """ Creates dictionary with input structures for Si/Ge. :Parameters: path : str Path to output dictionary. nall : int All structure with ``nall`` (excluded) unit-cells are included in the final dictionary. nrand : int Structures between ``nall`` (included) and ``nrand`` (excluded) unit-cells are also considered for inclusion in the final dictionary. However, only ``nmax`` are randomly chosen in the end. nmax : int Structures between ``nall`` (included) and ``nrand`` (excluded) unit-cells are also considered for inclusion in the final dictionary. However, only ``nmax`` are randomly chosen in the end. density : float Kpoint density for escan calculations, input : str Path to input file containing escan functional. Creates a job-dictionary with a number of structures sampled from an exhaustive list of structures to evaluate using escan. """ from random import shuffle from itertools import chain from IPython.ipapi import get as get_ipy from numpy.linalg import norm, inv from pylada.enumeration import Enum from pylada.crystal.binary import zinc_blende from pylada.jobs import JobFolder from pylada.escan import read_input, exec_input, ReducedKDensity from pylada.crystal.gruber import Reduction input = read_input(input) kescan = exec_input(repr(input.escan).replace('Escan', 'KEscan')).functional enum = Enum(zinc_blende()) enum.sites[0].type = 'Si', 'Ge' enum.sites[1].type = 'Si', 'Ge' enum.scale = 5.45 enum.find_space_group() density = density * max([1e0/norm(u) for u in inv(enum.cell * enum.scale).T]) strs = [u for n in range(nall, nrand) for u in enum.xn(n)] shuffle(strs) strs = [enum.as_structure(*u) for u in strs[:nmax]] alls = [structure for n in range(nall) for structure in enum.structures(n)] jobs = JobFolder() for i, structure in enumerate(chain(alls, strs)): structure.name = str(i) nSi = len([a.type for a in structure.atoms if a.type == 'Si']) structure.scale = float(nSi) / float(n) * enum.scale + float(n - nSi) / float(n) * 5.69 jobfolder = jobs / structure.name jobfolder.jobparams['structure'] = structure.copy() jobfolder.structure.cell = Reduction()(jobfolder.structure.cell) jobfolder.functional = kescan.copy() jobfolder.functional.kpoints = ReducedKDensity(density, (0.5, 0.5, 0.5)) jobfolder.functional.reference = None jobfolder.functional.fft_mesh = fftmesh(structure.cell) jobfolder.functional.nbstates = int(len(structure.atoms) * 4 * 1.5+0.5) ip = get_ipy() ip.user_ns["current_jobfolder"] = jobfolder.root ip.magic("savejobs " + path) return