def test_write_murnaghan_data():
    with TemporaryDirectory() as tmp_dir:
        correct_file = os.path.join(input_dir, 'murnaghan_parameters.dat.correct')
        s = [0.95, 0.975, 1, 1.025, 1.05]
        abc_guess = [6.6, 6.6, 6.6]
        abc_list = [si*np.array(abc_guess) for si in s]
        pvu = [[0.5,0.5,-0.5], [-0.5,0.5,0.5], [0.5,-0.5,0.5]]
        volumes = [94.091762000, 101.717255250, 109.744000000, 118.182284750, 127.042398000]
        energies_hartree = [-7.515024550, -7.516721665, -7.517852086, -7.518522990, -7.518821239]
        fit = m.MurnaghanFit(volumes, energies_hartree)
        fit.E0 = -7.518851002  # fake results
        fit.B0 = 0.000433261789  # fake results
        fit.BP = 3.505747298  # fake results
        fit.V0 = 131.192891163  # fake results
        m.write_murnaghan_data(fit, volumes, abc_list)
        with open(correct_file) as f1, open('murnaghan_parameters.dat') as f2:
            assert f1.readlines() == f2.readlines()
def test_integration_abinit():
    """
    lattice paramter sweep and murnaghan fitting should run correctly
    
    Requires abinit set up correctly. Also, this test is fragile because
    different abinit versions could calulate different energies. If this causes
    problems in the future, either increase np.isclose tolerance or (worse) update
    energy values to new abinit outputs.
    If the energy values are wrong, the murnaghan paramters will be too.
    """
    with TemporaryDirectory() as tmp_dir:
        # set up example input files in temporary directory
        os.mkdir('templatedir')
        shutil.copy(os.path.join(input_dir, 'files.example.Li'), 
                    os.path.join('templatedir', 'files'))
        shutil.copy(os.path.join(input_dir, 'Li.PAW.abinit'),
                    os.path.join('templatedir', 'Li.PAW.abinit'))

        # run sweep  in tmp_dir
        energy_driver = 'abinit'
        template_file = os.path.join(input_dir, 'abinit.in.template.Li')
        s = [0.95, 0.975, 1, 1.025, 1.05]
        abc_guess = [3.3, 3.3, 3.3]
        abc_list = [si*np.array(abc_guess) for si in s]
        pvu = [[0.5,0.5,-0.5], [-0.5,0.5,0.5], [0.5,-0.5,0.5]]
        volumes, energy_list_hartree = m.lattice_parameter_sweep(energy_driver, template_file, abc_list, prim_vec_unscaled=pvu)

        fit = m.MurnaghanFit(volumes, energy_list_hartree)
        m.write_murnaghan_data(fit, volumes, abc_list)  # don't really need to do this
        # assert data files written (correctly or not)
        # assert data files written (correctly or not)
        assert os.path.exists('energies.dat')
        assert os.path.exists('murnaghan_parameters.dat')

    # assert volumes and energies are correct
    assert np.isclose(volumes, [15.40574269, 16.65427268, 17.9685, 19.3501092, 20.80078481]).all()
    assert np.isclose(energy_list_hartree, [-5.93211143, -6.04145629, -6.13957171, -6.22787361, -6.30747694], atol=1e-3, rtol=0).all()
    # assert murnaghan parameters are correct
    assert np.isclose(fit.E0, -6.7617490608, atol=1e-4, rtol=0)
    assert np.isclose(fit.B0, 0.02539667138, atol=1e-4, rtol=0)
    assert np.isclose(fit.BP, 1.71091944591, atol=1e-1, rtol=0)
    assert np.isclose(fit.V0, 49.4869248327, atol=1e-2, rtol=0)
def test_integration_espresso():
    """
    lattice paramter sweep and murnaghan fitting should run correctly
    
    Requires Quantum Espresso set up correctly. Also, this test is fragile because
    different Espresso versions could calulate different energies. If this causes
    problems in the future, either increase np.isclose tolerance or (worse) update
    energy values to new Espresso outputs.
    If the energy values are wrong, the murnaghan parameters will be too.
    """
    with TemporaryDirectory() as tmp_dir:
        # set up example input files in temporary directory
        os.mkdir('templatedir')
        shutil.copy(os.path.join(input_dir, 'espresso.in.template.Si'), 
                    os.path.join('templatedir', 'espresso.in.template'))
        shutil.copy(os.path.join(input_dir, 'Si_pseudopotential_espresso.UPF'), 
                    os.path.join('templatedir', 'Si.UPF'))
        # run sweep in tmp_dir
        energy_driver = 'quantumespresso'
        template_file = 'espresso.in.template'
        s = [0.9, 0.95, 1, 1.05, 1.1]
        abc_guess = [11, 11, 11]
        abc_list = [si*np.array(abc_guess) for si in s]
        pvu = [[0.5,0.5,0.0], [0.0,0.5,0.5], [0.5,0.0,0.5]]
        volumes, energy_list_hartree = m.lattice_parameter_sweep(energy_driver, template_file, abc_list, prim_vec_unscaled=pvu)

        fit = m.MurnaghanFit(volumes, energy_list_hartree)
        m.write_murnaghan_data(fit, volumes, abc_list)  # don't really need to do this
        # assert data files written (correctly or not)
        assert os.path.exists('energies.dat')
        assert os.path.exists('murnaghan_parameters.dat')

    # assert volumes and energies are correct
    assert np.isclose(volumes, [242.574750000, 285.291531250, 332.750000000, 385.199718750, 442.890250000]).all()
    assert np.isclose(energy_list_hartree, [-7.249155685, -7.313223885, -7.345433545, -7.362979705, -7.437627675]).all()
    # assert murnaghan parameters are correct
    assert np.isclose(fit.E0, -8.438825256, atol=1e-4, rtol=0)
    assert np.isclose(fit.B0, 0.000167482725, atol=1e-5, rtol=0)
    assert np.isclose(fit.BP, 0.345630525, atol=1e-2, rtol=0)
    assert np.isclose(fit.V0, 6323.527132569, atol=1e-1, rtol=0)
def test_integration_elk():
    """
    lattice paramter sweep and murnaghan fitting should run correctly
    
    Requires elk set up correctly. Also, this test is fragile because
    different elk versions could calulate different energies. If this causes
    problems in the future, either increase np.isclose tolerance or (worse) update
    energy values to new elk outputs.
    If the energy values are wrong, the murnaghan paramters will be too.
    """
    with TemporaryDirectory() as tmp_dir:
        # set up example input files in temporary directory
        os.mkdir('templatedir')
        shutil.copy(os.path.join(input_dir, 'elk.in.template.Li'), 
                    os.path.join('templatedir', 'elk.in.template'))
        shutil.copy(os.path.join(input_dir, 'Li.in.elkspecies'), 
                    os.path.join('templatedir', 'Li.in'))
        # run sweep  in tmp_dir
        energy_driver = 'elk'
        template_file = 'elk.in.template'
        s = [0.95, 0.975, 1, 1.025, 1.05]
        abc_guess = [7.6, 7.6, 7.6]
        abc_list = [si*np.array(abc_guess) for si in s]
        pvu = [[0.5,0.5,0.0], [0.0,0.5,0.5], [0.5,0.0,0.5]]
        volumes, energy_list_hartree = m.lattice_parameter_sweep(energy_driver, template_file, abc_list, prim_vec_unscaled=pvu)

        fit = m.MurnaghanFit(volumes, energy_list_hartree)
        m.write_murnaghan_data(fit, volumes, abc_list)  # don't really need to do this
        # assert data files written (correctly or not)
        assert os.path.exists('energies.dat')
        assert os.path.exists('murnaghan_parameters.dat')

    # assert volumes and energies are correct
    assert np.isclose(volumes, [94.091762000, 101.717255250, 109.744000000, 118.182284750, 127.042398000]).all()
    assert np.isclose(energy_list_hartree, [-7.515024699, -7.516721695, -7.517852094, -7.518522940, -7.518821210], atol=1e-3, rtol=0).all()
    # assert murnaghan parameters are correct
    assert np.isclose(fit.E0, -7.518850974, atol=1e-4, rtol=0)
    assert np.isclose(fit.B0, 0.00043323874, atol=1e-5, rtol=0)
    assert np.isclose(fit.BP, 3.505576932, atol=1e-2, rtol=0)
    assert np.isclose(fit.V0, 131.193402033, atol=1e0, rtol=0)
def test_integration_socorro():
    """
    lattice paramter sweep and murnaghan fitting should run correctly
    
    Requires socorro set up correctly. Also, this test is fragile because
    different socorro versions could calulate different energies. If this causes
    problems in the future, either increase np.isclose tolerance or (worse) update
    energy values to new socorro outputs.
    If the energy values are wrong, the murnaghan paramters will be too.
    """
    with TemporaryDirectory() as tmp_dir:
        # set up example input files in temporary directory
        shutil.copytree(os.path.join(input_dir, 'socorro_LiF'), 'templatedir')
        # run sweep  in tmp_dir
        energy_driver = 'socorro'
        template_file = 'crystal.template'
        s = [0.95, 0.975, 1, 1.025, 1.05]
        abc_guess = [7.6, 7.6, 7.6]
        abc_list = [si*np.array(abc_guess) for si in s]
        pvu = [[0.5,0.5,0.0], [0.0,0.5,0.5], [0.5,0.0,0.5]]
        volumes, energy_list_hartree = m.lattice_parameter_sweep(energy_driver, template_file, abc_list, prim_vec_unscaled=pvu)

        fit = m.MurnaghanFit(volumes, energy_list_hartree)
        m.write_murnaghan_data(fit, volumes, abc_list)  # don't really need to do this
        # assert data files written (correctly or not)
        assert os.path.exists('energies.dat')
        assert os.path.exists('murnaghan_parameters.dat')

    # assert volumes and energies are correct
    assert np.isclose(volumes, [94.091762000, 101.717255250, 109.744000000, 118.182284750, 127.042398000]).all()
    assert np.isclose(energy_list_hartree, [-37.012225020, -37.042712697, -37.067941736, -37.090042723, -37.106637075], atol=1e-5, rtol=0).all()
    # assert murnaghan parameters are correct
    assert np.isclose(fit.E0, -37.129044175, atol=1e-4, rtol=0)
    assert np.isclose(fit.B0, 0.00722071666, atol=1e-5, rtol=0)
    assert np.isclose(fit.BP, 0.643620090, atol=1e-2, rtol=0)
    assert np.isclose(fit.V0, 156.473079733, atol=1e-1, rtol=0)
# scales to loop though. These get multiplied by abc_guess
s = [0.95, 0.975, 1.0, 1.025, 1.05]
# lattice parameter guesses
abc_guess = [6.3, 6.3, 6.3]
# this list of abc arrays gets passed to actual sweep
abc_list = [si * np.array(abc_guess) for si in s]
# unscaled primitve vectors
pvu = [[0.5, 0.5, -0.5], [-0.5, 0.5, 0.5], [0.5, -0.5, 0.5]]
# run lattice paramter sweep
volumes, energy_list_hartree = m.lattice_parameter_sweep(energy_driver,
                                                         template_file,
                                                         abc_list,
                                                         prim_vec_unscaled=pvu)
# fit to EOS and write fit data to file
fit = m.MurnaghanFit(volumes, energy_list_hartree)
m.write_murnaghan_data(fit, volumes, abc_list)

# # EXAMPLE RUN FOR WURTZITE GaN USING 2D POLYNOMIAL FIT
# # AND THE SOCORRO CODE.
# # THE TEMPLATEDIR DIRECTORY WITH THE CRYSTAL TEMPLATE
# # AND PSEUDOPOTENTIALS/PAWs NEEDS TO BE SET UP AS DESCRIBED
# # IN THE README

# energy_driver = 'socorro'
# # template file is usually 'abinit.in.template' for abinit,
# # 'crystal.template' for socorro,
# # or 'elk.in.template' for elk
# template_file = 'crystal.template'
#
# # create list of a,b,c values to test
# s_a = [0.99, 0.995, 1.0, 1.005, 1.01]  # scales for a/b lattice parameters