def optimize(self):

        from aiida.orm.data.parameter import ParameterData

        alat_scale = self.get_attribute("alat_scale")

        scale_index = self.get_attribute("scale_index")

        params = self.get_parameters()
        structure_id = params['structure_id']
        x_material = load_node(structure_id).get_formula()

        aiidalogger.info("Retrieving alat_scale as {0}".format(alat_scale))

        # Get calculations/get_step_calculations
        start_calcs = self.get_step_calculations(self.eos)  # .get_calculations()

        # Calculate results
        #-----------------------------------------

        e_calcs = [c.res.energy for c in start_calcs]
        v_calcs = [c.res.volume for c in start_calcs]

        # e_calcs = zip(*sorted(zip(alat_scale, e_calcs)))[1]
        # v_calcs = zip(*sorted(zip(alat_scale, v_calcs)))[1]

        e_calcs = zip(*sorted(zip(scale_index, e_calcs)))[1]
        v_calcs = zip(*sorted(zip(scale_index, v_calcs)))[1]

        #  Add to report
        #-----------------------------------------
        for i in range(len(alat_scale)):
            self.append_to_report(x_material + " simulated with alat_scale=" + str(alat_scale[i]) + ", e=" + str(e_calcs[i]))

        #  Find optimal alat
        #-----------------------------------------

        murnpars, ier = Murnaghan_fit(e_calcs, v_calcs)

        # New optimal alat
        optimal_alat = murnpars[3] ** (1 / 3.0)
        self.add_attribute('optimal_alat', optimal_alat)
        vol0 = load_node(structure_id).get_cell_volume()
        optimal_scale = (murnpars[3] / vol0) ** (1 / 3.0)
        self.add_attribute('optimal_scale', optimal_scale)

        #  Build last calculation
        #-----------------------------------------

        calc = self.get_lapw_calculation(self.get_structure(structure_id=structure_id, scale=optimal_scale),
                                       self.get_lapw_parameters(),
                                       self.get_kpoints())
        self.attach_calculation(calc)

        self.next(self.final_step)
    def get_distorted_index(self, structure_id, LC):

        import numpy as np

        s0 = load_node(structure_id)

        if (LC == 'CI' or \
            LC == 'CII'):
            def_list = ['1']

        if (LC == 'HI' or \
            LC == 'HII'or \
            LC == 'RI' or \
            LC == 'RII'or \
            LC == 'TI' or \
            LC == 'TII'):
            def_list = ['1','3']

        if (LC == 'O'):
            def_list = ['1','2','3']

        if (LC == 'M'):
            if (s0.cell_angles[0] != 90): unique_axis == 'a'
            if (s0.cell_angles[1] != 90): unique_axis == 'b'
            if (s0.cell_angles[2] != 90): unique_axis == 'c'

            if (unique_axis == 'a'): def_list = ['1','2','3','4']
            if (unique_axis == 'b'): def_list = ['1','2','3','5']
            if (unique_axis == 'c'): def_list = ['1','2','3','6']

        if (LC == 'N'):
            def_list = ['1','2','3','4','5','6']

        return def_list
    def stress_tensor(self):

        from aiida.orm import Code, Computer, CalculationFactory
        import numpy as np
        import spglib

        params = self.get_parameters()

        use_symmetry = True
        use_symmetry = params['use_symmetry']
        structure_id = params['structure_id']
        x_material = load_node(structure_id).get_formula()
        
        # alat_steps = params['alat_steps']

        alat_steps = 5
        eps = np.linspace(-0.008, 0.008, alat_steps).tolist()

        aiidalogger.info("Storing eps as " + str(eps))
        self.add_attribute('eps', eps)

        if use_symmetry:
           SGN = self.get_space_group_number(structure_id=structure_id)
        else:
           SGN = 1
        
        self.append_to_report(x_material + " structure has space group number " + str(SGN))

        LC = self.get_Laue_dict(space_group_number=SGN)
        self.add_attribute('LC', LC)

        # distorted_structure_index = range(len(eps * SCs))
        # aiidalogger.info("Storing distorted_structure_index as " + str(distorted_structure_index))
        # self.add_attribute('distorted_structure_index', distorted_structure_index)

        def_list = self.get_distorted_index(structure_id=structure_id, LC=LC)

        distorted_structure_index = []
        eps_index = 0
        for i in def_list:
            for a in eps:
                eps_index = eps_index + 1
                distorted_structure_index.append(eps_index) 

                # M_eps = self.get_strain_matrix(eps=a, def_mtx_index=i)

                M_Lagrange_eps = self.get_Lagrange_strain_matrix(eps=a, def_mtx_index=i)
                
                self.append_to_report("Preparing structure {0} with alat_strain {1} for SC {2}".format(x_material, a, i))

                calc = self.get_lapw_calculation(self.get_Lagrange_distorted_structure(structure_id=structure_id, M_Lagrange_eps=M_Lagrange_eps),
                                               self.get_lapw_parameters(),
                                               self.get_kpoints())

                self.attach_calculation(calc)

        self.add_attribute('distorted_structure_index', distorted_structure_index)

        self.next(self.analyze)
    def start(self):

        params = self.get_parameters()
        structure_id = params['structure_id']

        x_material = load_node(structure_id).get_formula()

        self.append_to_report(x_material + " stress tensor started with structure ID " + str(structure_id))

        self.next(self.stress_tensor)
    def start(self):

        params = self.get_parameters()
        structure_id = params['structure_id']

        # s = self.get_structure(structure_pk, scale)
        x_material = load_node(structure_id).get_formula()

        # self.append_to_report("EOS started")
        self.append_to_report(x_material + " EOS started with structure ID " + str(structure_id))

        self.next(self.eos)
    def get_space_group_number(self, structure_id):

        import numpy as np
        import spglib

        s0 = load_node(structure_id)
        slatt = s0.cell
        spos = np.squeeze(np.asarray(list(np.matrix(s0.cell).T.I * np.matrix(x.position).T for x in s0.sites)))
        snum = np.ones(len(s0.sites))
        scell = (slatt, spos, snum)
        SGN = int(spglib.get_symmetry_dataset(scell)["number"])

        return SGN
    def get_distorted_structure(self, structure_id, M_eps):

        import numpy as np

        s0 = load_node(structure_id)

        distorted_cell = np.dot(s0.cell, M_eps)

        s = StructureData(cell=distorted_cell)
        
        for site in s0.sites:
            kind_name = site.kind_name
            frac_coor = np.squeeze(np.asarray(list(np.matrix(s0.cell).T.I * np.matrix(site.position).T)))
            distorted_position = np.squeeze(np.asarray(list(np.matrix(s.cell).T * np.matrix(frac_coor).T)))
            s.append_atom(position=distorted_position, symbols=kind_name)

        s.store()

        return s
    def get_structure(self, structure_id, scale=1.0):

        import numpy as np

        s0 = load_node(structure_id)

        scaled_cell = np.dot(s0.cell, scale).tolist()

        s = StructureData(cell=scaled_cell)

        for site in s0.sites:
            scaled_position = np.dot(list(site.position), scale)
            kind_name = site.kind_name
            s.append_atom(position=scaled_position, symbols=kind_name)

        # old_positions = [val for sublist in list(x.position for x in s0.sites) for val in sublist]
        # new_positions = [val for sublist in list(scaled_position) for val in sublist]

        # isite = 0
        # start_index = 0
        # end_index = 0

        # for isite in range(len(s0.sites))
        #     start_index = isite * 3
        #     end_index = (isite + 1) * 3
        #     s.sites[isite].position = new_positions[start_index, end_index]

        # cell = [[alat, 0., 0., ],
        #         [0., alat, 0., ],
        #         [0., 0., alat, ],
        # ]

        # BaTiO3 cubic structure
        # s = StructureData(cell=cell)
        # s.append_atom(position=(0., 0., 0.), symbols=x_material)
        # s.append_atom(position=(alat / 2., alat / 2., alat / 2.), symbols=['Ti'])
        # s.append_atom(position=(alat / 2., alat / 2., 0.), symbols=['O'])
        # s.append_atom(position=(alat / 2., 0., alat / 2.), symbols=['O'])
        # s.append_atom(position=(0., alat / 2., alat / 2.), symbols=['O'])

        s.store()

        return s
    def final_step(self):

        from aiida.orm.data.parameter import ParameterData

        optimal_scale = self.get_attribute("optimal_scale")

        params = self.get_parameters()
        structure_id = params['structure_id']

        x_material = load_node(structure_id).get_formula()

        opt_calc = self.get_step_calculations(self.optimize)[0]  # .get_calculations()[0]
        opt_e = opt_calc.get_outputs(type=ParameterData)[0].get_dict()['energy']

        self.append_to_report(x_material + " optimal with alat_scale=" + str(optimal_scale) + ", e=" + str(opt_e))

        self.add_result("scf_converged", opt_calc)

        self.next(self.exit)
    def eos(self):

        from aiida.orm import Code, Computer, CalculationFactory
        import numpy as np

        params = self.get_parameters()

        # x_material = params['x_material']
        # starting_alat = params['starting_alat']

        structure_id = params['structure_id']
        x_material = load_node(structure_id).get_formula()
        
        alat_steps = params['alat_steps']

        # a_sweep = np.linspace(starting_alat * 0.85, starting_alat * 1.15, alat_steps).tolist()

        alat_scale = np.linspace(0.98, 1.02, alat_steps).tolist()

        aiidalogger.info("Storing alat_scale as " + str(alat_scale))
        self.add_attribute('alat_scale', alat_scale)

        scale_index = []
        scale_i = 0
        for a in alat_scale:
            scale_i = scale_i + 1
            scale_index.append(scale_i)
            self.append_to_report("Preparing structure {0} with alat_scale {1}".format(x_material, a))

            calc = self.get_lapw_calculation(self.get_structure(structure_id=structure_id, scale=a),
                                           self.get_lapw_parameters(),
                                           self.get_kpoints())

            self.attach_calculation(calc)

        self.add_attribute('scale_index', scale_index)

        self.next(self.optimize)
    def get_Lagrange_distorted_structure(self, structure_id, M_Lagrange_eps):

        import numpy as np

        s0 = load_node(structure_id)

        one = np.identity(3)

        deform = (np.dot(M_Lagrange_eps.T, M_Lagrange_eps) - one) / 2.

        distorted_cell = np.dot((deform + one) , s0.cell)

        s = StructureData(cell=distorted_cell)

        for site in s0.sites:
            kind_name = site.kind_name
            frac_coor = np.squeeze(np.asarray(list(np.matrix(s0.cell).T.I * np.matrix(site.position).T)))
            distorted_position = np.squeeze(np.asarray(list(np.matrix(s.cell).T * np.matrix(frac_coor).T)))
            s.append_atom(position=distorted_position, symbols=kind_name)

        s.store()

        return s
def launch(input_group, input_structures, repeat_expansion, volumetric_strains,
           norm_strains, shear_strains, random_displacement,
           number_randomized_samples, max_atoms, structure_comments,
           use_conventional_structure, structure_group_label,
           structure_group_description, dryrun):
    """
    Script for distoring the cell shape for an input structure
    """
    if not dryrun:
        structure_group = Group.objects.get_or_create(
            label=structure_group_label,
            description=structure_group_description)[0]
    else:
        structure_group = None

    if input_group:
        structure_nodes = Group.get(label=input_group).nodes
    elif input_structures:
        input_structures = input_structures.split(',')
        structure_nodes = [load_node(x) for x in input_structures]
    else:
        raise Exception("Must use either input group or input structures")
    volumetric_strains = [float(x) for x in volumetric_strains.split(',')]
    norm_strains = [float(x) for x in norm_strains.split(',')]
    shear_strains = [float(x) for x in shear_strains.split(',')]
    repeat_expansion = [int(x) for x in repeat_expansion.split(',')]

    for structure_node in structure_nodes:
        extras = {
            'input_structure': structure_node.uuid,
            'repeats': repeat_expansion,
            'structure_comments': structure_comments
        }

        input_structure_ase = structure_node.get_ase()
        if use_conventional_structure:
            input_structure_ase = get_conventionalstructure(
                input_structure_ase)
            extras['conventional_structure'] = True
        if len(input_structure_ase) > max_atoms:
            print(("Skipping {} too many atoms".format(structure_node)))
            continue
        input_structure_ase = input_structure_ase.repeat(repeat_expansion)
        deformations, strained_structures = get_strained_structures(
            input_structure_ase, norm_strains, shear_strains)
        for i in range(len(strained_structures)):
            extras['deformation'] = deformations[i]
            straindeformed_structure = copy.deepcopy(strained_structures[i])
            straindeformed_cell = copy.deepcopy(straindeformed_structure.cell)
            for j in range(len(volumetric_strains)):
                extras['random_seed'] = None
                extras['random_displacement_stdev'] = None
                extras['volume_strain'] = volumetric_strains[j]
                volume_deformation = 1.0 + volumetric_strains[j]
                extras['volume_deformation'] = volume_deformation

                volumedeformed_structure = copy.deepcopy(
                    straindeformed_structure)
                volumedeformed_structure.set_cell(straindeformed_cell *
                                                  volume_deformation,
                                                  scale_atoms=True)
                store_asestructure(volumedeformed_structure, extras,
                                   structure_group, dryrun)
                for k in range(number_randomized_samples):
                    random_structure = copy.deepcopy(volumedeformed_structure)
                    random_seed = random.randint(1, 2**32 - 1)
                    extras['random_seed'] = random_seed
                    extras['random_displacement_stdev'] = random_displacement
                    random_structure.rattle(stdev=random_displacement,
                                            seed=random_seed)
                    store_asestructure(random_structure, extras,
                                       structure_group, dryrun)
    def stress_tensor(self):

        from aiida.orm import Code, Computer, CalculationFactory
        import numpy as np
        import spglib

        params = self.get_parameters()

        use_symmetry = True
        use_symmetry = params['use_symmetry']
        structure_id = params['structure_id']
        x_material = load_node(structure_id).get_formula()

        # alat_steps = params['alat_steps']

        alat_steps = 5
        eps = np.linspace(-0.008, 0.008, alat_steps).tolist()

        aiidalogger.info("Storing eps as " + str(eps))
        self.add_attribute('eps', eps)
        self.add_attribute('alat_steps', alat_steps)

        if use_symmetry:
            SGN = self.get_space_group_number(structure_id=structure_id)
        else:
            SGN = 1

        self.append_to_report(x_material +
                              " structure has space group number " + str(SGN))

        LC = self.get_Laue_dict(space_group_number=SGN)
        self.add_attribute('LC', LC)

        # distorted_structure_index = range(len(eps * SCs))
        # aiidalogger.info("Storing distorted_structure_index as " + str(distorted_structure_index))
        # self.add_attribute('distorted_structure_index', distorted_structure_index)

        def_list = self.get_Lagrange_distorted_index(structure_id=structure_id,
                                                     LC=LC)
        self.add_attribute('def_list', def_list)

        SCs = len(def_list)
        self.add_attribute('SCs', SCs)

        distorted_structure_index = []
        eps_index = 0
        for i in def_list:
            for a in eps:

                eps_index = eps_index + 1

                distorted_structure_index.append(eps_index)

        self.add_attribute('distorted_structure_index',
                           distorted_structure_index)

        for ii in distorted_structure_index:

            a = eps[ii % alat_steps - 1]
            i = def_list[int((ii - 1) / alat_steps)]

            M_Lagrange_eps = self.get_Lagrange_strain_matrix(eps=a,
                                                             def_mtx_index=i)

            distorted_structure = self.get_Lagrange_distorted_structure(
                structure_id=structure_id, M_Lagrange_eps=M_Lagrange_eps)

            calc = self.get_lapw_calculation(distorted_structure,
                                             self.get_lapw_parameters(),
                                             self.get_kpoints())

            self.attach_calculation(calc)

            self.append_to_report(
                "Preparing structure {0} with alat_strain {1} for SC {2}".
                format(x_material, a, i))
            self.append_to_report(
                "Distorted structure with index {0} has ID {1}".format(
                    ii, distorted_structure.id))
            self.append_to_report("Calculation with pk {0}".format(calc.id))

        self.next(self.analyze)
    def analyze(self):

        from aiida.orm.data.parameter import ParameterData
        import numpy as np
        import scipy.optimize as scimin

        #%!%!%--- CONSTANTS ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!
        _e    =  1.602176565e-19         # elementary charge
        # Bohr  =  5.291772086e-11         # a.u. to meter
        # Ha2eV = 27.211396132             # Ha to eV
        # Tokbar= (_e*Ha2eV)/(1e8*Bohr**3) # Ha/[a.u.]^3 to kbar
        # ToGPa = (_e*Ha2eV)/(1e9*Bohr**3) # Ha/[a.u.]^3 to GPa
        angstrom = 1.0e-10               # angstrom to meter
        ToGPa = _e/(1e9*angstrom**3)     # eV/[\AA]^3 to GPa
        Tokbar = _e/(1e8*angstrom**3)    # eV/[\AA]^3 to kbar
        #__________________________________________________________________________________________________

        alat_steps = self.get_attribute("alat_steps")
        eps = self.get_attribute("eps")
        distorted_structure_index = self.get_attribute("distorted_structure_index")

        #for i in range(len(eps)):
        #    self.append_to_report(" simulated with strain =" + ", e=" + str(eps[i]))

        def_list = self.get_attribute("def_list")

        params = self.get_parameters()
        structure_id = params['structure_id']        
        x_material = load_node(structure_id).get_formula()

        aiidalogger.info("Retrieving eps as {0}".format(eps))

        # Get calculations/get_step_calculations
        start_calcs = self.get_step_calculations(self.stress_tensor)  # .get_calculations()

        # Calculate results
        #-----------------------------------------

        e_calcs = [c.res.energy for c in start_calcs]

        e_calcs = zip(*sorted(zip(distorted_structure_index, e_calcs)))[1]

        e_calcs_correct = e_calcs[::-1]

        #  Add to report
        #-----------------------------------------
        for i in range(len(distorted_structure_index)):
            self.append_to_report(x_material + " simulated with strain =" + str(distorted_structure_index[i]) + ", e=" + str(e_calcs_correct[i]))

        #  Obtain stress tensor by polyfit
        #-----------------------------------------
        #alat_steps = 5
        #SCs = int(len(distorted_structure_index) / alat_steps)

        SCs = self.get_attribute("SCs")
        A2 = []
        energy = []
        fit_order = 3
        #eps = np.linspace(-0.008, 0.008, alat_steps).tolist()

        for i in range(ECs):
            energy = e_calcs_correct[i*alat_steps:(i+1)*alat_steps]
            coeffs = np.polyfit(eps, energy, fit_order)
            A1.append(coeffs[fit_order-1]*ToGPa)
 
            #lsq_coeffs, ier = lsq_fit(energy, eps)
            #A1.append(lsq_coeffs[order-1]*ToGPa)

        A2 = np.array(A2)

        LC = self.get_attribute("LC")


        C = self.get_elastic_constant_matrix(structure_id=structure_id, LC=LC, A2=A2)

        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has stress tensor in GPa C11 ... C16=" + str(C[0,:]))
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has stress tensor in GPa C21 ... C26=" + str(C[1,:]))
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has stress tensor in GPa C31 ... C36=" + str(C[2,:]))
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has stress tensor in GPa C41 ... C46=" + str(C[3,:]))
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has stress tensor in GPa C51 ... C56=" + str(C[4,:]))
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has stress tensor in GPa C61 ... C66=" + str(C[5,:]))

        S  = np.linalg.inv(C)

        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Elastic compliance matrix in 1/GPa S11 ... S16=" + str(S[0,:]))
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Elastic compliance matrix in 1/GPa S21 ... S26=" + str(S[1,:]))
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Elastic compliance matrix in 1/GPa S31 ... S36=" + str(S[2,:]))
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Elastic compliance matrix in 1/GPa S41 ... S46=" + str(S[3,:]))
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Elastic compliance matrix in 1/GPa S51 ... S56=" + str(S[4,:]))
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Elastic compliance matrix in 1/GPa S61 ... S66=" + str(S[5,:]))

        eigval=np.linalg.eig(C)

        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Eigenvalues of elastic constant (stiffness) matrix:=" + str(eigval[0,:]))
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Eigenvalues of elastic constant (stiffness) matrix:=" + str(eigval[1,:]))
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Eigenvalues of elastic constant (stiffness) matrix:=" + str(eigval[2,:]))
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Eigenvalues of elastic constant (stiffness) matrix:=" + str(eigval[3,:]))
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Eigenvalues of elastic constant (stiffness) matrix:=" + str(eigval[4,:]))
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Eigenvalues of elastic constant (stiffness) matrix:=" + str(eigval[5,:]))

#%!%!%--- Calculating the elastic moduli ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%
        BV = (C[0,0]+C[1,1]+C[2,2]+2*(C[0,1]+C[0,2]+C[1,2]))/9
        GV = ((C[0,0]+C[1,1]+C[2,2])-(C[0,1]+C[0,2]+C[1,2])+3*(C[3,3]+C[4,4]+C[5,5]))/15
        EV = (9*BV*GV)/(3*BV+GV)
        nuV= (1.5*BV-GV)/(3*BV+GV)
        BR = 1/(S[0,0]+S[1,1]+S[2,2]+2*(S[0,1]+S[0,2]+S[1,2]))
        GR =15/(4*(S[0,0]+S[1,1]+S[2,2])-4*(S[0,1]+S[0,2]+S[1,2])+3*(S[3,3]+S[4,4]+S[5,5]))
        ER = (9*BR*GR)/(3*BR+GR)
        nuR= (1.5*BR-GR)/(3*BR+GR)
        BH = 0.50*(BV+BR)
        GH = 0.50*(GV+GR)
        EH = (9.*BH*GH)/(3.*BH+GH)
        nuH= (1.5*BH-GH)/(3.*BH+GH)
        AVR= 100.*(GV-GR)/(GV+GR)
#--------------------------------------------------------------------------------------------------

        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Voigt bulk  modulus, B_V (Gpa)" + BV)
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Voigt shear modulus, G_V (Gpa)" + GV)

        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Reuss bulk  modulus, B_R (Gpa)" + BR)
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Reuss shear modulus, G_R (Gpa)" + GR)

        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Hill bulk  modulus, B_H (Gpa)" + BH)
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Hill shear modulus, G_H (Gpa)" + GH)

        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Voigt Young modulus, E_V (Gpa)" + EV)
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Voigt Poisson ratio, nu_V" + nuV)
        
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Reuss Young  modulus, E_R (Gpa)" + ER)
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Reuss Poisson ratio, nu_R " + nuR)

        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Hill Young  modulus, E_H (Gpa)" + EH)
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Hill Poisson modulus, nu_H (Gpa)" + nuH)

        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has Elastic Anisotropy in polycrystalline, AVR =" + nuH)

        self.next(self.exit)
    def get_elastic_constant_matrix(self, structure_id, LC, A2):

        import numpy as np

        s0 = load_node(structure_id)

        C = np.zeros((6,6))
        
        #%!%!%--- Cubic structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%
        if (LC == 'CI' or \
            LC == 'CII'):
            C[0,0] =-2.*(A2[0]-3.*A2[1])/3.
            C[1,1] = C[0,0]
            C[2,2] = C[0,0]
            C[3,3] = A2[2]/6.
            C[4,4] = C[3,3]
            C[5,5] = C[3,3]
            C[0,1] = (2.*A2[0]-3.*A2[1])/3.
            C[0,2] = C[0,1]
            C[1,2] = C[0,1]
        #--------------------------------------------------------------------------------------------------
        
        #%!%!%--- Hexagonal structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%
        if (LC == 'HI' or \
            LC == 'HII'):
            C[0,0] = 2.*A2[3]
            C[0,1] = 2./3.*A2[0] + 4./3.*A2[1] - 2.*A2[2] - 2.*A2[3]
            C[0,2] = 1./6.*A2[0] - 2./3.*A2[1] + 0.5*A2[2]
            C[1,1] = C[0,0]
            C[1,2] = C[0,2]
            C[2,2] = 2.*A2[2]
            C[3,3] =-0.5*A2[2] + 0.5*A2[4]
            C[4,4] = C[3,3]
            C[5,5] = .5*(C[0,0] - C[0,1])
        #--------------------------------------------------------------------------------------------------
        
        #%!%!%--- Rhombohedral I structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!
        if (LC == 'RI'):
            C[0,0] = 2.*A2[3]
            C[0,1] = A2[1]- 2.*A2[3]
            C[0,2] = .5*( A2[0] - A2[1] - A2[2])
            C[0,3] = .5*(-A2[3] - A2[4] + A2[5])
            C[1,1] = C[0,0]
            C[1,2] = C[0,2]
            C[1,3] =-C[0,3]
            C[2,2] = 2.*A2[2]
            C[3,3] = .5*A2[4]
            C[4,4] = C[3,3]
            C[4,5] = C[0,3]
            C[5,5] = .5*(C[0,0] - C[0,1])
        #--------------------------------------------------------------------------------------------------
        
        #%!%!%--- Rhombohedral II structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%
        if (LC == 'RII'):
            C[0,0] = 2.*A2[3]
            C[0,1] = A2[1]- 2.*A2[3]
            C[0,2] = .5*( A2[0] - A2[1] - A2[2])
            C[0,3] = .5*(-A2[3] - A2[4] + A2[5])
            C[0,4] = .5*(-A2[3] - A2[4] + A2[6])
            C[1,1] = C[0,0]
            C[1,2] = C[0,2]
            C[1,3] =-C[0,3]
            C[1,4] =-C[0,4]
            C[2,2] = 2.*A2[2]
            C[3,3] = .5*A2[4]
            C[3,5] =-C[0,4]
            C[4,4] = C[3,3]
            C[4,5] = C[0,3]
            C[5,5] = .5*(C[0,0] - C[0,1])
        #--------------------------------------------------------------------------------------------------
        #%!%!%--- Tetragonal I structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!
        if (LC == 'TI'):
            C[0,0] = (A2[0]+2.*A2[1])/3.+.5*A2[2]-A2[3]
            C[0,1] = (A2[0]+2.*A2[1])/3.-.5*A2[2]-A2[3]
            C[0,2] = A2[0]/6.-2.*A2[1]/3.+.5*A2[3]
            C[1,1] = C[0,0]
            C[1,2] = C[0,2]
            C[2,2] = 2.*A2[3]
            C[3,3] = .5*A2[4]
            C[4,4] = C[3,3]
            C[5,5] = .5*A2[5]
        #--------------------------------------------------------------------------------------------------
        
        #%!%!%--- Tetragonal II structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%
        if (LC == 'TII'):
            C[0,0] = (A2[0]+2.*A2[1])/3.+.5*A2[2]-A2[4]
            C[1,1] = C[0,0]
            C[0,1] = (A2[0]+2.*A2[1])/3.-.5*A2[2]-A2[4]
            C[0,2] = A2[0]/6.-(2./3.)*A2[1]+.5*A2[4]
            C[0,5] = (-A2[2]+A2[3]-A2[6])/4.
            C[1,2] = C[0,2]
            C[1,5] =-C[0,5]
            C[2,2] = 2.*A2[4]
            C[3,3] = .5*A2[5]
            C[4,4] = C[3,3]
            C[5,5] = .5*A2[6]
        #--------------------------------------------------------------------------------------------------
        
        #%!%!%--- Orthorhombic structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!
        if (LC == 'O'):
            C[0,0] = 2.*A2[0]/3.+4.*A2[1]/3.+A2[3]-2.*A2[4]-2.*A2[5]
            C[0,1] = 1.*A2[0]/3.+2.*A2[1]/3.-.5*A2[3]-A2[5]
            C[0,2] = 1.*A2[0]/3.-2.*A2[1]/3.+4.*A2[2]/3.-.5*A2[3]-A2[4]
            C[1,1] = 2.*A2[4]
            C[1,2] =-2.*A2[1]/3.-4.*A2[2]/3.+.5*A2[3]+A2[4]+A2[5]
            C[2,2] = 2.*A2[5]
            C[3,3] = .5*A2[6]
            C[4,4] = .5*A2[7]
            C[5,5] = .5*A2[8]
        #--------------------------------------------------------------------------------------------------
        
        #%!%!%--- Monoclinic structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!
        if (LC == 'M'):
            C[0,0] = 2.*A2[0]/3.+8.*(A2[1]+A2[2])/3.-2.*(A2[5]+A2[8]+A2[9])
            C[0,1] = A2[0]/3.+4.*(A2[1]+A2[2])/3.-2.*A2[5]-A2[9]
            C[0,2] =(A2[0]-4.*A2[2])/3.+A2[5]-A2[8]
            C[0,5] =-1.*A2[0]/6.-2.*(A2[1]+A2[2])/3.+.5*(A2[5]+A2[7]+A2[8]+A2[9]-A2[12])
            C[1,1] = 2.*A2[8]
            C[1,2] =-4.*(2.*A2[1]+A2[2])/3.+2.*A2[5]+A2[8]+A2[9]
            C[1,5] =-1.*A2[0]/6.-2.*(A2[1]+A2[2])/3.-.5*A2[3]+A2[5]+.5*(A2[7]+A2[8]+A2[9])
            C[2,2] = 2.*A2[9]
            C[2,5] =-1.*A2[0]/6.+2.*A2[1]/3.-.5*(A2[3]+A2[4]-A2[7]-A2[8]-A2[9]-A2[12])
            C[3,3] = .5*A2[10]
            C[3,4] = .25*(A2[6]-A2[10]-A2[11])
            C[4,4] = .5*A2[11]
            C[5,5] = .5*A2[12]
        #--------------------------------------------------------------------------------------------------
        
        #%!%!%--- Triclinic structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%
        if (LC == 'N'):
            C[0,0] = 2.*A2[0]
            C[0,1] = 1.*(-A2[0]-A2[1]+A2[6])
            C[0,2] = 1.*(-A2[0]-A2[2]+A2[7])
            C[0,3] = .5*(-A2[0]-A2[3]+A2[8])
            C[0,4] = .5*(-A2[0]+A2[9]-A2[4])
            C[0,5] = .5*(-A2[0]+A2[10]-A2[5])
            C[1,1] = 2.*A2[1]
            C[1,2] = 1.*(A2[11]-A2[1]-A2[2])
            C[1,3] = .5*(A2[12]-A2[1]-A2[3])
            C[1,4] = .5*(A2[13]-A2[1]-A2[4])
            C[1,5] = .5*(A2[14]-A2[1]-A2[5])
            C[2,2] = 2.*A2[2]
            C[2,3] = .5*(A2[15]-A2[2]-A2[3])
            C[2,4] = .5*(A2[16]-A2[2]-A2[4])
            C[2,5] = .5*(A2[17]-A2[2]-A2[5])
            C[3,3] = .5*A2[3]
            C[3,4] = .25*(A2[18]-A2[3]-A2[4])
            C[3,5] = .25*(A2[19]-A2[3]-A2[5])
            C[4,4] = .5*A2[4]
            C[4,5] = .25*(A2[20]-A2[4]-A2[5])
            C[5,5] = .5*A2[5]
        #--------------------------------------------------------------------------------------------------
        
        for i in range(5):
            for j in range(i+1,6):
                C[j,i] = C[i,j]

        V0 = load_node(structure_id).get_cell_volume()
        C = C / V0
        
        return C
Example #16
0
    def calculation_getresults(self, *args):
        """
        Routine to get a list of results of a set of calculations, still
        under development.
        """
        from aiida.common.exceptions import AiidaException
        load_dbenv()
        from aiida.orm import JobCalculation as OrmCalculation
        from aiida.orm.utils import load_node


        class InternalError(AiidaException):
            def __init__(self, real_exception, message):
                self.real_exception = real_exception
                self.message = message


        def get_suggestions(key, correct_keys):
            import difflib
            import string

            similar_kws = difflib.get_close_matches(key, correct_keys)
            if len(similar_kws) == 1:
                return "(Maybe you wanted to specify %s?)" % similar_kws[0]
            elif len(similar_kws) > 1:
                return "(Maybe you wanted to specify one of these: %s?)" % string.join(similar_kws, ', ')
            else:
                return "(No similar keywords found...)"

        # define a function to retrieve the data from the dictionary
        def key_finder(in_dict, the_keys):
            parent_dict = in_dict
            parent_dict_name = '<root level>'
            for new_key in the_keys:
                try:
                    parent_dict = parent_dict[new_key]
                    parent_dict_name = new_key
                except KeyError as e:
                    raise InternalError(e, "Unable to find the key '%s' in '%s' %s" % (
                        new_key, parent_dict_name, get_suggestions(new_key, parent_dict.keys())))
                except Exception as e:
                    if e.__class__ is not InternalError:
                        raise InternalError(e,
                                            "Error retrieving the key '%s' withing '%s', maybe '%s' is not a dict?" % (
                                                the_keys[1], the_keys[0], the_keys[0]))
                    else:
                        raise
            return parent_dict


        def index_finder(data, indices, list_name):
            if not indices:
                return data

            parent_data = data
            parent_name = list_name
            for idx in indices:
                try:
                    index = int(idx)
                    parent_data = parent_data[index]
                    parent_name += ":%s" % index
                except ValueError as e:
                    raise InternalError(e, "%s is not a valid integer (in %s)." % (idx, parent_name))
                except IndexError as e:
                    raise InternalError(e, "Index %s is out of bounds, length of list %s is %s" % (
                        index, parent_name, len(parent_data)))
                except Exception as e:
                    raise InternalError(e, "Invalid index! Maybe %s is not a list?" % parent_name)
            return parent_data


        if not args:
            print >> sys.stderr, "Pass some parameters."
            sys.exit(1)

        # I convert it to a list
        arguments = list(args)

        try:
            sep_idx = arguments.index('--')
        except ValueError:
            print >> sys.stderr, "Separate parameter keys from job-ids with a --!"
            sys.exit(1)

        keys_to_retrieve = arguments[:sep_idx]
        job_list_str = arguments[sep_idx + 1:]

        try:
            job_list = [int(i) for i in job_list_str]
        except ValueError:
            print >> sys.stderr, "All PKs after -- must be valid integers."
            sys.exit(1)


        sep = '\t'  # Default separator: a tab character

        try:
            idx = keys_to_retrieve.index('-s')

            # First pop removes the -s parameter, second pop (now with the same
            # index) retrieves the asked separator. Raises IndexError if nothing
            # is provided after -s.
            _ = keys_to_retrieve.pop(idx)
            sep = keys_to_retrieve.pop(idx)
        except IndexError:
            print >> sys.stderr, "After -s you have to pass a valid separator!"
            sys.exit(1)
        except ValueError:
            # No -s found, use default separator
            pass

        print_header = True  # Default: print the header
        try:
            keys_to_retrieve.remove('--no-header')
            # If here, the key was found: I remove it from the list and set the
            # the print_header flag
            print_header = False
        except ValueError:
            # No --no-header found: pass
            pass

        # check if there is at least one thing to do
        if not job_list:
            print >> sys.stderr, "Failed recognizing a calculation PK."
            sys.exit(1)
        if not keys_to_retrieve:
            print  >> sys.stderr, "Failed recognizing a key to parse."
            sys.exit(1)

        # load the data
        if print_header:
            print "## Job list: %s" % " ".join(job_list_str)
            print "#" + sep.join(str(i) for i in keys_to_retrieve)
        for job in job_list:
            values_to_print = []
            in_found = True
            out_found = True
            c = load_node(job, parent_class=OrmCalculation)
            try:
                i = c.inp.parameters.get_dict()
            except AttributeError:
                i = {}
                in_found = False
            try:
                o = c.out.output_parameters.get_dict()
            except AttributeError:
                out_found = False
                o = {}

            io = {'extras': c.get_extras(), 'attrs': c.get_attrs(),
                  'i': i, 'o': o, 'pk': job, 'label': c.label,
                  'desc': c.description, 'state': c.get_state(),
                  'sched_state': c.get_scheduler_state(),
                  'owner': c.dbnode.user.email}

            try:
                for datakey_full in keys_to_retrieve:
                    split_for_def = datakey_full.split('=')
                    datakey_raw = split_for_def[0]  # Still can contain the function to apply
                    def_val = "=".join(split_for_def[1:]) if len(split_for_def) > 1 else None

                    split_for_func = datakey_raw.split('/')
                    datakey = split_for_func[0]
                    function_to_apply = "/".join(split_for_func[1:]) if len(split_for_func) > 1 else None

                    key_values = [str(i) for i in datakey.split(':')[0].split('.')]
                    indices = [int(i) for i in datakey.split(':')[1:]]  # empty list for simple variables.
                    try:
                        value_key = key_finder(io, key_values)
                        value = index_finder(value_key, indices, list_name=datakey.split(':')[0])
                        # Will do the correct thing if no function is supplied
                        # and function is therefore None
                        value = apply_function(function=function_to_apply, value=value)

                    except InternalError as e:
                        # For any internal error, set the value to the default if
                        # provided, otherwise re-raise the exception
                        if def_val is not None:
                            value = def_val
                        else:
                            if not out_found:
                                if in_found:
                                    e.message += " [NOTE: No output JSON could be found]"
                                else:
                                    e.message += " [NOTE: No output JSON nor input JSON could be found]"
                            raise e

                    values_to_print.append(value)

                    # Not needed: now we can ask explicitly for a job number using the flag
                    # 'jobnum'
                    # values_to_print.append("# %s" % str(job))
                # print on screen
                print sep.join(str(i) for i in values_to_print)
            except InternalError as e:
                print >> sys.stderr, e.message
            except Exception as e:
                print >> sys.stderr, "# Error loading job # %s (%s): %s" % (job, type(e), e)
    def get_stress_tensor_matrix(self, structure_id, LC, A1):

        import numpy as np

        s0 = load_node(structure_id)

        S = np.zeros((3,3))

        #%!%!%--- Cubic structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%
        if (LC == 'CI' or \
            LC == 'CII'):
            S[0,0] = A1[0]
            S[1,1] = S[0,0]
            S[2,2] = S[0,0]
        #--------------------------------------------------------------------------------------------------

        #%!%!%--- Hexagonal, Rhombohedral, and Tetragonal structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%
        if (LC == 'HI' or \
            LC == 'HII'or \
            LC == 'RI' or \
            LC == 'RII'or \
            LC == 'TI' or \
            LC == 'TII'):
            S[0,0] = A1[0]
            S[1,1] = S[0,0]
            S[2,2] = A1[1]
        #--------------------------------------------------------------------------------------------------

        #%!%!%--- Orthorhombic structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!
        if (LC == 'O'):
            S[0,0] = A1[0]
            S[1,1] = A1[1]
            S[2,2] = A1[2]
        #--------------------------------------------------------------------------------------------------

        #%!%!%--- Monoclinic structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!
        if (LC == 'M'):
            S[0,0] = A1[0]
            S[1,1] = A1[1]
            S[2,2] = A1[2]

            if (s0.cell_angles[0] != 90): unique_axis == 'a'
            if (s0.cell_angles[1] != 90): unique_axis == 'b'
            if (s0.cell_angles[2] != 90): unique_axis == 'c'

            if (unique_axis == 'a'): S[1,2] = A1[3]
            if (unique_axis == 'b'): S[0,2] = A1[3]
            if (unique_axis == 'c'): S[0,1] = A1[3]
        #--------------------------------------------------------------------------------------------------

        #%!%!%--- Triclinic structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%
        if (LC == 'N'):
            S[0,0] = A1[0]
            S[1,1] = A1[1]
            S[2,2] = A1[2]
            S[1,2] = A1[3]
            S[0,2] = A1[4]
            S[0,1] = A1[5]
        #--------------------------------------------------------------------------------------------------

        for i in range(2):
            for j in range(i+1, 3):
                S[j,i] = S[i,j]

        V0 = load_node(structure_id).get_cell_volume()
        S = S / V0

        return S
    def get_stress_tensor_matrix(self, structure_id, LC, A1):

        import numpy as np

        s0 = load_node(structure_id)

        S = np.zeros((3,3))

        #%!%!%--- Cubic structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%
        if (LC == 'CI' or \
            LC == 'CII'):
            S[0,0] = A1[0]/3.
            S[1,1] = S[0,0]
            S[2,2] = S[0,0]
        #--------------------------------------------------------------------------------------------------

        #%!%!%--- Hexagonal, Rhombohedral, and Tetragonal structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%
        if (LC == 'HI' or \
            LC == 'HII'or \
            LC == 'RI' or \
            LC == 'RII'or \
            LC == 'TI' or \
            LC == 'TII'):
            S[0,0] = (A1[0] - 1.*A1[1])/3.
            S[1,1] = S[0,0]
            S[2,2] = (A1[0] + 2.*A1[1])/3.
        #--------------------------------------------------------------------------------------------------

        #%!%!%--- Orthorhombic structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!
        if (LC == 'O'):
            S[0,0] = (A1[0] - 2.*A1[1] - 2.*A1[2])/3.
            S[1,1] = (A1[0] + 2.*A1[1])/3.
            S[2,2] = (A1[0] + 2.*A1[2])/3.
        #--------------------------------------------------------------------------------------------------

        #%!%!%--- Monoclinic structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!
        if (LC == 'M'):
            S[0,0] = (A1[0] - 2.*A1[1] - 2.*A1[2])/3.
            S[1,1] = (A1[0] + 2.*A1[1])/3.
            S[2,2] = (A1[0] + 2.*A1[2])/3.

            if (s0.cell_angles[0] != 90): unique_axis == 'a'
            if (s0.cell_angles[1] != 90): unique_axis == 'b'
            if (s0.cell_angles[2] != 90): unique_axis == 'c'

            if (unique_axis == 'a'): S[1,2] = A1[3]/2.
            if (unique_axis == 'b'): S[0,2] = A1[3]/2.
            if (unique_axis == 'c'): S[0,1] = A1[3]/2.
        #--------------------------------------------------------------------------------------------------

        #%!%!%--- Triclinic structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%
        if (LC == 'N'):
            S[0,0] = (A1[0] + 2.* A1[2])/3.,
            S[1,1] = (A1[0] + 2.* A1[1])/3.,
            S[2,2] = (A1[0] - 2.*(A1[1] + A1[2]))/3.,
            S[1,2] = A1[3]/2.,
            S[0,2] = A1[4]/2.,
            S[0,1] = A1[5]/2.
        #--------------------------------------------------------------------------------------------------

        return S
    def analyze(self):

        from aiida.orm.data.parameter import ParameterData
        import numpy as np
        import scipy.optimize as scimin

        #%!%!%--- CONSTANTS ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!
        _e    =  1.602176565e-19         # elementary charge
        # Bohr  =  5.291772086e-11         # a.u. to meter
        # Ha2eV = 27.211396132             # Ha to eV
        # Tokbar= (_e*Ha2eV)/(1e8*Bohr**3) # Ha/[a.u.]^3 to kbar
        # ToGPa = (_e*Ha2eV)/(1e9*Bohr**3) # Ha/[a.u.]^3 to GPa
        angstrom = 1.0e-10               # angstrom to meter
        ToGPa = _e/(1e9*angstrom**3)     # eV/[\AA]^3 to GPa
        Tokbar = _e/(1e8*angstrom**3)    # eV/[\AA]^3 to kbar
        #__________________________________________________________________________________________________

        alat_steps = self.get_attribute("alat_steps")
        eps = self.get_attribute("eps")
        distorted_structure_index = self.get_attribute("distorted_structure_index")

        #for i in range(len(eps)):
        #    self.append_to_report(" simulated with strain =" + ", e=" + str(eps[i]))

        def_list = self.get_attribute("def_list")

        params = self.get_parameters()
        structure_id = params['structure_id']        
        x_material = load_node(structure_id).get_formula()

        aiidalogger.info("Retrieving eps as {0}".format(eps))

        # Get calculations/get_step_calculations
        start_calcs = self.get_step_calculations(self.stress_tensor)  # .get_calculations()

        # Calculate results
        #-----------------------------------------

        e_calcs = [c.res.energy for c in start_calcs]

        e_calcs = zip(*sorted(zip(distorted_structure_index, e_calcs)))[1]

        e_calcs_correct = e_calcs[::-1]

        #  Add to report
        #-----------------------------------------
        for i in range(len(distorted_structure_index)):
            self.append_to_report(x_material + " simulated with strain =" + str(distorted_structure_index[i]) + ", e=" + str(e_calcs_correct[i]))

        #  Obtain stress tensor by polyfit
        #-----------------------------------------
        #alat_steps = 5
        #SCs = int(len(distorted_structure_index) / alat_steps)

        SCs = self.get_attribute("SCs")
        A1 = []
        energy = []
        order = 3
        #eps = np.linspace(-0.008, 0.008, alat_steps).tolist()

        for i in range(SCs):
            energy = e_calcs_correct[i*alat_steps:(i+1)*alat_steps]
            coeffs = np.polyfit(eps, energy, order)
            A1.append(coeffs[order-1]*ToGPa)
 
            #lsq_coeffs, ier = lsq_fit(energy, eps)
            #A1.append(lsq_coeffs[order-1]*ToGPa)

        A1 = np.array(A1)

        LC = self.get_attribute("LC")

        S = self.get_stress_tensor_matrix(structure_id=structure_id, LC=LC, A1=A1)

        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has stress tensor S11, S12, S13=" + str(S[0,:]))
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has stress tensor S21, S22, S23=" + str(S[1,:]))
        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has stress tensor S31, S32, S33=" + str(S[2,:]))

        P = (S[0,0]+S[1,1]+S[2,2])/-3.

        self.append_to_report(x_material + " simulated with structure_id =" + str(structure_id) + " has pressure =" + str(P) + " GPa")

        self.next(self.exit)
def execute(args):
    """
    The main execution of the script, which will run some preliminary checks on the command
    line arguments before passing them to the workchain and running it
    """
    code = load_code(args.codename)
    stm_code = load_code(args.stm_codename)
    height = Float(args.height)
    e1 = Float(args.e1)
    e2 = Float(args.e2)

    protocol = Str(args.protocol)

    alat = 15.  # angstrom
    cell = [
        [
            alat,
            0.,
            0.,
        ],
        [
            0.,
            alat,
            0.,
        ],
        [
            0.,
            0.,
            alat,
        ],
    ]

    # Benzene molecule
    #
    s = StructureData(cell=cell)

    def perm(x, y, z):
        return (z, y + 0.5 * alat, x + 0.5 * alat)

    s.append_atom(position=perm(0.000, 0.000, 0.468), symbols=['H'])
    s.append_atom(position=perm(0.000, 0.000, 1.620), symbols=['C'])
    s.append_atom(position=perm(0.000, -2.233, 1.754), symbols=['H'])
    s.append_atom(position=perm(0.000, 2.233, 1.754), symbols=['H'])
    s.append_atom(position=perm(0.000, -1.225, 2.327), symbols=['C'])
    s.append_atom(position=perm(0.000, 1.225, 2.327), symbols=['C'])
    s.append_atom(position=perm(0.000, -1.225, 3.737), symbols=['C'])
    s.append_atom(position=perm(0.000, 1.225, 3.737), symbols=['C'])
    s.append_atom(position=perm(0.000, -2.233, 4.311), symbols=['H'])
    s.append_atom(position=perm(0.000, 2.233, 4.311), symbols=['H'])
    s.append_atom(position=perm(0.000, 0.000, 4.442), symbols=['C'])
    s.append_atom(position=perm(0.000, 0.000, 5.604), symbols=['H'])

    if args.structure > 0:
        structure = load_node(args.structure)
    else:
        structure = s

    run(SiestaSTMWorkChain,
        code=code,
        stm_code=stm_code,
        structure=structure,
        protocol=protocol,
        height=height,
        e1=e1,
        e2=e2)
    def get_stress_tensor_matrix(self, structure_id, LC, A1):

        import numpy as np

        s0 = load_node(structure_id)

        S = np.zeros((3, 3))

        #%!%!%--- Cubic structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%
        if (LC == 'CI' or \
            LC == 'CII'):
            S[0, 0] = A1[0]
            S[1, 1] = S[0, 0]
            S[2, 2] = S[0, 0]
        #--------------------------------------------------------------------------------------------------

        #%!%!%--- Hexagonal, Rhombohedral, and Tetragonal structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%
        if (LC == 'HI' or \
            LC == 'HII'or \
            LC == 'RI' or \
            LC == 'RII'or \
            LC == 'TI' or \
            LC == 'TII'):
            S[0, 0] = A1[0]
            S[1, 1] = S[0, 0]
            S[2, 2] = A1[1]
        #--------------------------------------------------------------------------------------------------

        #%!%!%--- Orthorhombic structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!
        if (LC == 'O'):
            S[0, 0] = A1[0]
            S[1, 1] = A1[1]
            S[2, 2] = A1[2]
        #--------------------------------------------------------------------------------------------------

        #%!%!%--- Monoclinic structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!
        if (LC == 'M'):
            S[0, 0] = A1[0]
            S[1, 1] = A1[1]
            S[2, 2] = A1[2]

            if (s0.cell_angles[0] != 90): unique_axis == 'a'
            if (s0.cell_angles[1] != 90): unique_axis == 'b'
            if (s0.cell_angles[2] != 90): unique_axis == 'c'

            if (unique_axis == 'a'): S[1, 2] = A1[3]
            if (unique_axis == 'b'): S[0, 2] = A1[3]
            if (unique_axis == 'c'): S[0, 1] = A1[3]
        #--------------------------------------------------------------------------------------------------

        #%!%!%--- Triclinic structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%
        if (LC == 'N'):
            S[0, 0] = A1[0]
            S[1, 1] = A1[1]
            S[2, 2] = A1[2]
            S[1, 2] = A1[3]
            S[0, 2] = A1[4]
            S[0, 1] = A1[5]
        #--------------------------------------------------------------------------------------------------

        for i in range(2):
            for j in range(i + 1, 3):
                S[j, i] = S[i, j]

        V0 = load_node(structure_id).get_cell_volume()
        S = S / V0

        return S
Example #22
0
 def is_ready(self, registry=None):
     return not load_node(pk=self._pk)._is_running()
    def analyze(self):

        from aiida.orm.data.parameter import ParameterData
        import numpy as np
        import scipy.optimize as scimin

        #%!%!%--- CONSTANTS ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!
        _e = 1.602176565e-19  # elementary charge
        # Bohr  =  5.291772086e-11         # a.u. to meter
        # Ha2eV = 27.211396132             # Ha to eV
        # Tokbar= (_e*Ha2eV)/(1e8*Bohr**3) # Ha/[a.u.]^3 to kbar
        # ToGPa = (_e*Ha2eV)/(1e9*Bohr**3) # Ha/[a.u.]^3 to GPa
        angstrom = 1.0e-10  # angstrom to meter
        ToGPa = _e / (1e9 * angstrom**3)  # eV/[\AA]^3 to GPa
        Tokbar = _e / (1e8 * angstrom**3)  # eV/[\AA]^3 to kbar
        #__________________________________________________________________________________________________

        alat_steps = self.get_attribute("alat_steps")
        eps = self.get_attribute("eps")
        distorted_structure_index = self.get_attribute(
            "distorted_structure_index")

        #for i in range(len(eps)):
        #    self.append_to_report(" simulated with strain =" + ", e=" + str(eps[i]))

        def_list = self.get_attribute("def_list")

        params = self.get_parameters()
        structure_id = params['structure_id']
        x_material = load_node(structure_id).get_formula()

        aiidalogger.info("Retrieving eps as {0}".format(eps))

        # Get calculations/get_step_calculations
        start_calcs = self.get_step_calculations(
            self.stress_tensor)  # .get_calculations()

        # Calculate results
        #-----------------------------------------

        e_calcs = [c.res.energy for c in start_calcs]

        e_calcs = zip(*sorted(zip(distorted_structure_index, e_calcs)))[1]

        e_calcs_correct = e_calcs[::-1]

        #  Add to report
        #-----------------------------------------
        for i in range(len(distorted_structure_index)):
            self.append_to_report(x_material + " simulated with strain =" +
                                  str(distorted_structure_index[i]) + ", e=" +
                                  str(e_calcs_correct[i]))

        #  Obtain stress tensor by polyfit
        #-----------------------------------------
        #alat_steps = 5
        #SCs = int(len(distorted_structure_index) / alat_steps)

        SCs = self.get_attribute("SCs")
        A1 = []
        energy = []
        order = 3
        #eps = np.linspace(-0.008, 0.008, alat_steps).tolist()

        for i in range(SCs):
            energy = e_calcs_correct[i * alat_steps:(i + 1) * alat_steps]
            coeffs = np.polyfit(eps, energy, order)
            A1.append(coeffs[order - 1] * ToGPa)

            #lsq_coeffs, ier = lsq_fit(energy, eps)
            #A1.append(lsq_coeffs[order-1]*ToGPa)

        A1 = np.array(A1)

        LC = self.get_attribute("LC")

        S = self.get_stress_tensor_matrix(structure_id=structure_id,
                                          LC=LC,
                                          A1=A1)

        self.append_to_report(x_material + " simulated with structure_id =" +
                              str(structure_id) +
                              " has stress tensor S11, S12, S13=" +
                              str(S[0, :]))
        self.append_to_report(x_material + " simulated with structure_id =" +
                              str(structure_id) +
                              " has stress tensor S21, S22, S23=" +
                              str(S[1, :]))
        self.append_to_report(x_material + " simulated with structure_id =" +
                              str(structure_id) +
                              " has stress tensor S31, S32, S33=" +
                              str(S[2, :]))

        P = (S[0, 0] + S[1, 1] + S[2, 2]) / -3.

        self.append_to_report(x_material + " simulated with structure_id =" +
                              str(structure_id) + " has pressure =" + str(P) +
                              " GPa")

        self.next(self.exit)
    def get_stress_tensor_matrix(self, structure_id, LC, A1):

        import numpy as np

        s0 = load_node(structure_id)

        S = np.zeros((3, 3))

        #%!%!%--- Cubic structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%
        if (LC == 'CI' or \
            LC == 'CII'):
            S[0, 0] = A1[0] / 3.
            S[1, 1] = S[0, 0]
            S[2, 2] = S[0, 0]
        #--------------------------------------------------------------------------------------------------

        #%!%!%--- Hexagonal, Rhombohedral, and Tetragonal structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%
        if (LC == 'HI' or \
            LC == 'HII'or \
            LC == 'RI' or \
            LC == 'RII'or \
            LC == 'TI' or \
            LC == 'TII'):
            S[0, 0] = (A1[0] - 1. * A1[1]) / 3.
            S[1, 1] = S[0, 0]
            S[2, 2] = (A1[0] + 2. * A1[1]) / 3.
        #--------------------------------------------------------------------------------------------------

        #%!%!%--- Orthorhombic structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!
        if (LC == 'O'):
            S[0, 0] = (A1[0] - 2. * A1[1] - 2. * A1[2]) / 3.
            S[1, 1] = (A1[0] + 2. * A1[1]) / 3.
            S[2, 2] = (A1[0] + 2. * A1[2]) / 3.
        #--------------------------------------------------------------------------------------------------

        #%!%!%--- Monoclinic structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!
        if (LC == 'M'):
            S[0, 0] = (A1[0] - 2. * A1[1] - 2. * A1[2]) / 3.
            S[1, 1] = (A1[0] + 2. * A1[1]) / 3.
            S[2, 2] = (A1[0] + 2. * A1[2]) / 3.

            if (s0.cell_angles[0] != 90): unique_axis == 'a'
            if (s0.cell_angles[1] != 90): unique_axis == 'b'
            if (s0.cell_angles[2] != 90): unique_axis == 'c'

            if (unique_axis == 'a'): S[1, 2] = A1[3] / 2.
            if (unique_axis == 'b'): S[0, 2] = A1[3] / 2.
            if (unique_axis == 'c'): S[0, 1] = A1[3] / 2.
        #--------------------------------------------------------------------------------------------------

        #%!%!%--- Triclinic structures ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%
        if (LC == 'N'):
            S[0, 0] = (A1[0] + 2. * A1[2]) / 3.,
            S[1, 1] = (A1[0] + 2. * A1[1]) / 3.,
            S[2, 2] = (A1[0] - 2. * (A1[1] + A1[2])) / 3.,
            S[1, 2] = A1[3] / 2.,
            S[0, 2] = A1[4] / 2.,
            S[0, 1] = A1[5] / 2.
        #--------------------------------------------------------------------------------------------------

        return S