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']
        alat_steps = params['alat_steps']

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

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

        for a in a_sweep:
            self.append_to_report("Preparing structure {0} with alat {1}".format(x_material + "TiO3", a))

            calc = self.get_pw_calculation(self.get_structure(alat=a, x_material=x_material),
                                           self.get_pw_parameters(),
                                           self.get_kpoints())

            self.attach_calculation(calc)

        self.next(self.optimize)
Esempio n. 2
0
    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']
        alat_steps = params['alat_steps']

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

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

        for a in a_sweep:
            self.append_to_report(
                "Preparing structure {0} with alat {1}".format(
                    x_material + "TiO3", a))

            calc = self.get_pw_calculation(
                self.get_structure(alat=a, x_material=x_material),
                self.get_pw_parameters(), self.get_kpoints())

            self.attach_calculation(calc)

        self.next(self.optimize)
Esempio n. 3
0
    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)

        for a in alat_scale:
            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.next(self.optimize)
    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)
Esempio n. 5
0
    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 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)
Esempio n. 7
0
    def optimize(self):

        from aiida.orm.data.parameter import ParameterData

        x_material = self.get_parameter("x_material")
        a_sweep = self.get_attribute("a_sweep")

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

        # Get 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(a_sweep, e_calcs)))[1]
        v_calcs = zip(*sorted(zip(a_sweep, v_calcs)))[1]

        #  Add to report
        #-----------------------------------------
        for i in range(len(a_sweep)):
            self.append_to_report(x_material + "Ti03 simulated with a=" +
                                  str(a_sweep[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)

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

        calc = self.get_pw_calculation(
            self.get_structure(alat=optimal_alat, x_material=x_material),
            self.get_pw_parameters(), self.get_kpoints())
        self.attach_calculation(calc)

        self.next(self.final_step)
    def optimize(self):

        from aiida.orm.data.parameter import ParameterData

        x_material = self.get_parameter("x_material")
        a_sweep = self.get_attribute("a_sweep")

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

        # Get 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(a_sweep, e_calcs)))[1]
        v_calcs = zip(*sorted(zip(a_sweep, v_calcs)))[1]

        #  Add to report
        #-----------------------------------------
        for i in range(len(a_sweep)):
            self.append_to_report(x_material + "Ti03 simulated with a=" + str(a_sweep[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)

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

        calc = self.get_pw_calculation(self.get_structure(alat=optimal_alat, x_material=x_material),
                                       self.get_pw_parameters(),
                                       self.get_kpoints())
        self.attach_calculation(calc)

        self.next(self.final_step)
    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 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 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_pw_calculation(distorted_structure,
                                           self.get_pw_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")
        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 analyze(self):

        from aiida.orm.data.parameter import ParameterData
        import numpy as np

        x_material = self.get_parameter("x_material")
        a_sweep = self.get_attribute("a_sweep")

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

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

        # Calculate results
        #-----------------------------------------
        alat_steps = params['alat_steps']

        s_calcs = np.linspace(-0.002, 0.002, alat_steps).tolist()

        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(a_sweep, e_calcs)))[1]
        v_calcs = zip(*sorted(zip(a_sweep, v_calcs)))[1]

        s_calcs = zip(*sorted(zip(a_sweep, s_calcs)))[1]

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

        s_pymatgen = s.get_pymatgen()

        import pymatgen as mg
        from pymatgen.symmetry.analyzer import SpacegroupAnalyzer

        finder = SpacegroupAnalyzer(s_pymatgen)

        SGN = finder.get_space_group_number()

        #%!%!%--- Classify the Space-Group Number ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!
        if (1 <= SGN and SGN <= 2):  # Triclinic
            LC = 'N'
            SCs = 6

        elif (3 <= SGN and SGN <= 15):  # Monoclinic
            LC = 'M'
            SCs = 4

        elif (16 <= SGN and SGN <= 74):  # Orthorhombic
            LC = 'O'
            SCs = 3

        elif (75 <= SGN and SGN <= 88):  # Tetragonal II
            LC = 'TII'
            SCs = 2

        elif (89 <= SGN and SGN <= 142):  # Tetragonal I
            LC = 'TI'
            SCs = 2

        elif (143 <= SGN and SGN <= 148):  # Rhombohedral II
            LC = 'RII'
            SCs = 2

        elif (149 <= SGN and SGN <= 167):  # Rhombohedral I
            LC = 'RI'
            SCs = 2

        elif (168 <= SGN and SGN <= 176):  # Hexagonal II
            LC = 'HII'
            SCs = 2

        elif (177 <= SGN and SGN <= 194):  # Hexagonal I
            LC = 'HI'
            SCs = 2

        elif (195 <= SGN and SGN <= 206):  # Cubic II
            LC = 'CII'
            SCs = 1

        elif (207 <= SGN and SGN <= 230):  # Cubic I
            LC = 'CI'
            SCs = 1

        else:
            sys.exit('\n ... Oops ERROR: WRONG Space-Group Number !?!?!?\n')

        #%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%#
        #%!%!% ------------ Calculating the first derivative and Cross-Validation Error ------------ %!%!%#
        #%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%#

        A1 = []

        mdri = 0.002
        ordri = 1

        strain = []
        energy = []

        strain = copy.copy(s_calcs)
        energy = copy.copy(e_calcs)

        coeffs = np.polyfit(strain, energy, ordri)
        A1.append(coeffs[ordri - 1])

        A1 = np.array(A1)
        if (len(A1) != SCs):
            sys.exit('\n ... Oops ERROR: The number of data is NOT equal to ' + \
            str(SCs)+'\n')

        S = 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 (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.
#--------------------------------------------------------------------------------------------------

#%!%!%--- Calculating the Pressure ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%

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

        eV_over_ang3_toGPa = 160.21766208
        v0i = int((alat_steps + 1) / 2)
        V0 = v_calcs[v0i]
        S = S / V0 * eV_over_ang3_toGPa
        P = (S[0, 0] + S[1, 1] + S[2, 2]) / -3. * eV_over_ang3_toGPa
        #--------------------------------------------------------------------------------------------------

        self.append_to_report(x_material + "Ti03 simulated with a=" +
                              str(a_sweep[v0i]) + ", e=" + str(e_calcs[v0i]))

        self.append_to_report("stress tensor matrix = " + str(S[0, 0]) +
                              str(S[0, 1]) + str(S[0, 2]))
        self.append_to_report("stress tensor matrix = " + str(S[1, 0]) +
                              str(S[1, 1]) + str(S[1, 2]))
        self.append_to_report("stress tensor matrix = " + str(S[2, 0]) +
                              str(S[2, 1]) + str(S[2, 2]))

        self.append_to_report("external pressure in GPa = " + str(P))

        self.next(self.exit)
    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 analyze(self):

        from aiida.orm.data.parameter import ParameterData
        import numpy as np

        x_material = self.get_parameter("x_material")
        a_sweep = self.get_attribute("a_sweep")

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

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

        # Calculate results
        #-----------------------------------------
        alat_steps = params['alat_steps']

        s_calcs = np.linspace(-0.002, 0.002, alat_steps).tolist()

        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(a_sweep, e_calcs)))[1]
        v_calcs = zip(*sorted(zip(a_sweep, v_calcs)))[1]

        s_calcs = zip(*sorted(zip(a_sweep, s_calcs)))[1]

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

        s_pymatgen = s.get_pymatgen()

        import pymatgen as mg
        from pymatgen.symmetry.analyzer import SpacegroupAnalyzer

        finder = SpacegroupAnalyzer(s_pymatgen)

        SGN = finder.get_space_group_number()

#%!%!%--- Classify the Space-Group Number ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!
        if (1 <= SGN and SGN <= 2):      # Triclinic
            LC = 'N'
            SCs= 6
        
        elif(3 <= SGN and SGN <= 15):    # Monoclinic
            LC = 'M'
            SCs= 4
        
        elif(16 <= SGN and SGN <= 74):   # Orthorhombic
            LC = 'O'
            SCs=  3
        
        elif(75 <= SGN and SGN <= 88):   # Tetragonal II
            LC = 'TII'
            SCs=  2
          
        elif(89 <= SGN and SGN <= 142):  # Tetragonal I
            LC = 'TI'
            SCs=  2
            
        elif(143 <= SGN and SGN <= 148): # Rhombohedral II 
            LC = 'RII'
            SCs=  2
            
        elif(149 <= SGN and SGN <= 167): # Rhombohedral I
            LC = 'RI'
            SCs=  2
            
        elif(168 <= SGN and SGN <= 176): # Hexagonal II
            LC = 'HII'
            SCs=  2
            
        elif(177 <= SGN and SGN <= 194): # Hexagonal I
            LC = 'HI'
            SCs=  2
            
        elif(195 <= SGN and SGN <= 206): # Cubic II
            LC = 'CII'
            SCs=  1
            
        elif(207 <= SGN and SGN <= 230): # Cubic I
            LC = 'CI'
            SCs=  1
            
        else: sys.exit('\n ... Oops ERROR: WRONG Space-Group Number !?!?!?\n')


#%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%#
#%!%!% ------------ Calculating the first derivative and Cross-Validation Error ------------ %!%!%#
#%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%#

        A1 = []
        
        mdri   = 0.002
        ordri  = 1
        
        strain = []
        energy = []

        strain = copy.copy(s_calcs)
        energy = copy.copy(e_calcs)
        
        coeffs = np.polyfit(strain, energy, ordri)
        A1.append(coeffs[ordri-1])
        
        A1 = np.array(A1)
        if (len(A1) != SCs):
            sys.exit('\n ... Oops ERROR: The number of data is NOT equal to ' + \
            str(SCs)+'\n')
        
        S = 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 (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.
#--------------------------------------------------------------------------------------------------

#%!%!%--- Calculating the Pressure ---%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%!%

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

        eV_over_ang3_toGPa = 160.21766208
        v0i = int((alat_steps + 1) / 2)
        V0 = v_calcs [v0i]
        S = S / V0 * eV_over_ang3_toGPa
        P = (S[0,0]+S[1,1]+S[2,2])/-3.*eV_over_ang3_toGPa
#--------------------------------------------------------------------------------------------------

        self.append_to_report(x_material + "Ti03 simulated with a=" + str(a_sweep[v0i]) + ", e=" + str(e_calcs[v0i]))

        self.append_to_report("stress tensor matrix = " + str(S[0,0]) + str(S[0,1]) + str(S[0,2]))
        self.append_to_report("stress tensor matrix = " + str(S[1,0]) + str(S[1,1]) + str(S[1,2]))
        self.append_to_report("stress tensor matrix = " + str(S[2,0]) + str(S[2,1]) + str(S[2,2]))

        self.append_to_report("external pressure in GPa = " + str(P) )

        self.next(self.exit)