Ejemplo n.º 1
0
def npt_equi_conf(npt_name):
    thermo_file = os.path.join(npt_name, 'log.lammps')
    dump_file = os.path.join(npt_name, 'dump.equi')
    j_file = os.path.join(npt_name, 'in.json')
    jdata = json.load(open(j_file))
    stat_skip = jdata['stat_skip']
    stat_bsize = jdata['stat_bsize']

    data = lib.lammps.get_thermo(thermo_file)
    lx, lxe = block_avg(data[:, 8], skip=stat_skip, block_size=stat_bsize)
    ly, lye = block_avg(data[:, 9], skip=stat_skip, block_size=stat_bsize)
    lz, lze = block_avg(data[:, 10], skip=stat_skip, block_size=stat_bsize)
    xy, xye = block_avg(data[:, 11], skip=stat_skip, block_size=stat_bsize)
    xz, xze = block_avg(data[:, 12], skip=stat_skip, block_size=stat_bsize)
    yz, yze = block_avg(data[:, 13], skip=stat_skip, block_size=stat_bsize)

    last_dump = lib.lammps.get_last_dump(dump_file).split('\n')
    sys_data = lib.dump.system_data(last_dump)
    sys_data['cell'][0][0] = lx
    sys_data['cell'][1][1] = ly
    sys_data['cell'][2][2] = lz
    sys_data['cell'][1][0] = xy
    sys_data['cell'][2][0] = xz
    sys_data['cell'][2][1] = yz

    conf_lmp = lib.lmp.from_system_data(sys_data)
    return conf_lmp
Ejemplo n.º 2
0
def _compute_thermo(lmplog, natoms, stat_skip, stat_bsize):
    data = get_thermo(lmplog)
    ea, ee = block_avg(data[:, 3], skip=stat_skip, block_size=stat_bsize)
    ha, he = block_avg(data[:, 4], skip=stat_skip, block_size=stat_bsize)
    ta, te = block_avg(data[:, 5], skip=stat_skip, block_size=stat_bsize)
    pa, pe = block_avg(data[:, 6], skip=stat_skip, block_size=stat_bsize)
    va, ve = block_avg(data[:, 7], skip=stat_skip, block_size=stat_bsize)
    thermo_info = {}
    thermo_info['p'] = pa
    thermo_info['p_err'] = pe
    thermo_info['v'] = va / natoms
    thermo_info['v_err'] = ve / np.sqrt(natoms)
    thermo_info['e'] = ea / natoms
    thermo_info['e_err'] = ee / np.sqrt(natoms)
    thermo_info['h'] = ha / natoms
    thermo_info['h_err'] = he / np.sqrt(natoms)
    thermo_info['t'] = ta
    thermo_info['t_err'] = te
    unit_cvt = 1e5 * (1e-10**3) / pc.electron_volt
    thermo_info['pv'] = pa * va * unit_cvt / natoms
    thermo_info['pv_err'] = pe * va * unit_cvt / np.sqrt(natoms)
    return thermo_info
Ejemplo n.º 3
0
def _post_tasks(iter_name, step, natoms):
    jdata = json.load(open(os.path.join(iter_name, 'in.json')))
    stat_skip = jdata['stat_skip']
    stat_bsize = jdata['stat_bsize']
    all_tasks = glob.glob(os.path.join(iter_name, 'task.[0-9]*'))
    all_tasks.sort()
    ntasks = len(all_tasks)

    all_lambda = []
    all_dp_a = []
    all_dp_e = []

    for ii in all_tasks:
        log_name = os.path.join(ii, 'log.lammps')
        data = get_thermo(log_name)
        np.savetxt(os.path.join(ii, 'data'), data, fmt='%.6e')
        dp_a, dp_e = block_avg(data[:, 8],
                               skip=stat_skip,
                               block_size=stat_bsize)
        dp_a /= natoms
        dp_e /= np.sqrt(natoms)
        lmda_name = os.path.join(ii, 'lambda.out')
        ll = float(open(lmda_name).read())
        all_lambda.append(ll)
        all_dp_a.append(dp_a)
        all_dp_e.append(dp_e)

    all_lambda = np.array(all_lambda)
    all_dp_a = np.array(all_dp_a)
    all_dp_e = np.array(all_dp_e)
    de = all_dp_a
    all_err = all_dp_e

    all_print = []
    # all_print.append(np.arange(len(all_lambda)))
    all_print.append(all_lambda)
    all_print.append(de)
    all_print.append(all_err)
    all_print = np.array(all_print)
    np.savetxt(os.path.join(iter_name, 'hti.out'),
               all_print.T,
               fmt='%.8e',
               header='lmbda dU dU_err')

    diff_e, err = integrate(all_lambda, de, all_err)
    sys_err = integrate_sys_err(all_lambda, de)

    thermo_info = _compute_thermo(os.path.join(all_tasks[-1], 'log.lammps'),
                                  natoms, stat_skip, stat_bsize)

    return diff_e, [err, sys_err], thermo_info
Ejemplo n.º 4
0
def post_tasks(iter_name,
               jdata,
               Eo,
               Eo_err=0,
               To=None,
               natoms=None,
               scheme='s',
               shift=0.0):
    equi_conf = get_task_file_abspath(iter_name, jdata['equi_conf'])
    if natoms == None:
        natoms = get_natoms(equi_conf)
        if 'copies' in jdata:
            natoms *= np.prod(jdata['copies'])
    stat_skip = jdata['stat_skip']
    stat_bsize = jdata['stat_bsize']
    ens = jdata['ens']
    path = jdata['path']

    all_tasks = glob.glob(os.path.join(iter_name, 'task.[0-9]*'))
    all_tasks.sort()
    ntasks = len(all_tasks)

    all_t = []
    all_e = []
    all_e_err = []
    integrand = []
    integrand_err = []
    if 'nvt' in ens and path == 't':
        # TotEng
        stat_col = 3
        print('# TI in NVT along T path')
    elif 'npt' in ens and (path == 't' or path == 't-ginv'):
        # Enthalpy
        stat_col = 4
        print('# TI in NPT along T path')
    elif 'npt' in ens and path == 'p':
        # volume
        stat_col = 7
        print('# TI in NPT along P path')
    else:
        raise RuntimeError('invalid ens or path setting')
    print('# natoms: %d' % natoms)

    for ii in all_tasks:
        # get T or P
        thermo_name = os.path.join(ii, 'thermo.out')
        tt = float(open(thermo_name).read())
        all_t.append(tt)
        # get energy stat
        log_name = os.path.join(ii, 'log.lammps')
        data = get_thermo(log_name)
        np.savetxt(os.path.join(ii, 'data'), data, fmt='%.6e')
        ea, ee = block_avg(data[:, stat_col],
                           skip=stat_skip,
                           block_size=stat_bsize)
        # COM corr
        if path == 't' or path == 't-ginv':
            ea += 1.5 * pc.Boltzmann * tt / pc.electron_volt
        elif path == 'p':
            temp = jdata['temps']
            ea += 1.5 * pc.Boltzmann * temp / pc.electron_volt
        else:
            raise RuntimeError('invalid path setting')
        # normalized by number of atoms
        ea /= natoms
        if path == 't' or path == 't-ginv':
            ea -= shift
        ee /= np.sqrt(natoms)
        all_e.append(ea)
        all_e_err.append(ee)
        # gen integrand
        if path == 't' or path == 't-ginv':
            integrand.append(ea / (tt * tt))
            integrand_err.append(ee / (tt * tt))
        elif path == 'p':
            # cvt from barA^3 to eV
            unit_cvt = 1e5 * (1e-10**3) / pc.electron_volt
            integrand.append(ea * unit_cvt)
            integrand_err.append(ee * unit_cvt)
        else:
            raise RuntimeError('invalid path setting')

    all_print = []
    all_print.append(all_t)
    all_print.append(integrand)
    all_print.append(all_e)
    all_print.append(all_e_err)

    all_e_divide_T = np.asarray(all_e) / np.asarray(all_t)
    all_print.append(all_e_divide_T)

    all_print = np.array(all_print)
    np.savetxt(os.path.join(iter_name, 'ti.out'),
               all_print.T,
               fmt='%.8e',
               header='t/p Integrand U/V U/V_err U/T')

    info0 = _compute_thermo(os.path.join(all_tasks[0], 'log.lammps'), natoms,
                            stat_skip, stat_bsize)
    info1 = _compute_thermo(os.path.join(all_tasks[-1], 'log.lammps'), natoms,
                            stat_skip, stat_bsize)
    _print_thermo_info(info0, 'at start point')
    _print_thermo_info(info1, 'at end point')

    if To is not None:
        index = all_t.index(To)
        if index == None:
            if 'nvt' == ens:
                raise RuntimeError('cannot find %f in T', To)
            elif 'npt' in ens:
                raise RuntimeError('cannot find %f in P', To)
        all_t_1 = all_t[0:index + 1]
        integrand_1 = integrand[0:index + 1]
        integrand_err_1 = integrand_err[0:index + 1]
        all_t_1 = np.flip(all_t_1, 0)
        integrand_1 = np.flip(integrand_1, 0)
        integrand_err_1 = np.flip(integrand_err_1, 0)
        all_t_2 = all_t[index:]
        integrand_2 = integrand[index:]
        integrand_err_2 = integrand_err[index:]
        all_temps_1, all_press_1, all_fe_1, all_fe_err_1, all_fe_sys_err_1 \
            = _thermo_inte(jdata, Eo, Eo_err, all_t_1, integrand_1, integrand_err_1, scheme = scheme)
        all_temps_2, all_press_2, all_fe_2, all_fe_err_2, all_fe_sys_err_2 \
            = _thermo_inte(jdata, Eo, Eo_err, all_t_2, integrand_2, integrand_err_2, scheme = scheme)
        all_temps_1 = np.flip(all_temps_1, 0)
        all_press_1 = np.flip(all_press_1, 0)
        all_fe_1 = np.flip(all_fe_1, 0)
        all_fe_err_1 = np.flip(all_fe_err_1, 0)
        all_fe_sys_err_1 = np.flip(all_fe_sys_err_1, 0)
        all_temps = np.append(all_temps_1, all_temps_2[1:])
        all_press = np.append(all_press_1, all_press_2[1:])
        all_fe = np.append(all_fe_1, all_fe_2[1:])
        all_fe_err = np.append(all_fe_err_1, all_fe_err_2[1:])
        all_fe_sys_err = np.append(all_fe_sys_err_1, all_fe_sys_err_2[1:])
    else:
        all_temps, all_press, all_fe, all_fe_err, all_fe_sys_err \
            = _thermo_inte(jdata, Eo, Eo_err, all_t, integrand, integrand_err, scheme = scheme)

    all_temps = np.asarray(all_temps)
    all_fe_divide_T = np.asarray(all_fe) / np.asarray(all_temps)
    all_fe_to_H_divide_T_temp = list(
        -(all_fe_divide_T[:-2] - all_fe_divide_T[2:]) /
        (all_temps[:-2] - all_temps[2:]) *
        all_temps[1:-1])  # *all_temps[1:-1])
    all_fe_to_H_divide_T_temp.insert(0, 0.00)
    all_fe_to_H_divide_T_temp.append(0.00)
    all_fe_to_H_divide_T = np.asarray(all_fe_to_H_divide_T_temp)
    all_fe_to_H = all_fe_to_H_divide_T_temp * all_temps

    if 'nvt' == ens:
        print('#%8s  %20s  %9s  %9s  %9s  %9s %15s' %
              ('T(ctrl)', 'F', 'stat_err', 'inte_err', 'err', 'F/T',
               '-T*d(F/T)/dT, -T^2*d(F/T)/dT'))
        for ii in range(len(all_temps)):
            print(
                '%9.2f  %20.12f  %9.2e  %9.2e  %9.2e  %15.8e  %15.8e %15.8e' %
                (all_temps[ii], all_fe[ii], all_fe_err[ii], all_fe_sys_err[ii],
                 np.linalg.norm([all_fe_err[ii], all_fe_sys_err[ii]
                                 ]), all_fe_divide_T[ii],
                 all_fe_to_H_divide_T[ii], all_fe_to_H[ii]))
    elif 'npt' in ens:
        print('#%8s  %15s  %20s  %9s  %9s  %9s  %9s %15s' %
              ('T(ctrl)', 'P(ctrl)', 'F', 'stat_err', 'inte_err', 'err', 'F/T',
               '-T*d(F/T)/dT, -T^2*d(F/T)/dT'))
        for ii in range(len(all_temps)):
            print(
                '%9.2f  %15.8e  %20.12f  %9.2e  %9.2e  %9.2e  %15.8e  %15.8e %15.8e'
                % (all_temps[ii], all_press[ii], all_fe[ii], all_fe_err[ii],
                   all_fe_sys_err[ii],
                   np.linalg.norm([all_fe_err[ii], all_fe_sys_err[ii]
                                   ]), all_fe_divide_T[ii],
                   all_fe_to_H_divide_T[ii], all_fe_to_H[ii]))
Ejemplo n.º 5
0
def _post_tasks(iter_name,
                jdata,
                natoms=None,
                scheme='s',
                switch='one-step',
                step='both'):
    stat_skip = jdata['stat_skip']
    stat_bsize = jdata['stat_bsize']
    all_tasks = glob.glob(os.path.join(iter_name, 'task.[0-9]*'))
    all_tasks.sort()
    ntasks = len(all_tasks)
    equi_conf = get_task_file_abspath(iter_name, jdata['equi_conf'])
    assert (os.path.isfile(equi_conf))
    if natoms == None:
        natoms = get_natoms(equi_conf)
        if 'copies' in jdata:
            natoms *= np.prod(jdata['copies'])
    print('# natoms: %d' % natoms)

    all_lambda = []
    all_es = []
    all_es_err = []
    all_ed = []
    all_ed_err = []
    all_ep = []
    all_ep_err = []

    print("# task  lambda   spring_pot_eng  deepmd_pot_eng")
    for ii in all_tasks:
        log_name = os.path.join(ii, 'log.lammps')
        data = get_thermo(log_name)
        np.savetxt(os.path.join(ii, 'data'), data, fmt='%.6e')
        sa, se = block_avg(data[:, 8], skip=stat_skip, block_size=stat_bsize)
        da, de = block_avg(data[:, 9], skip=stat_skip, block_size=stat_bsize)
        pa, pe = block_avg(data[:, 2], skip=stat_skip, block_size=stat_bsize)
        sa /= natoms
        se /= np.sqrt(natoms)
        da /= natoms
        de /= np.sqrt(natoms)
        pa /= natoms
        pe /= np.sqrt(natoms)
        lmda_name = os.path.join(ii, 'lambda.out')
        ll = float(open(lmda_name).read())
        all_lambda.append(ll)
        all_es.append(sa)
        all_ed.append(da)
        all_ep.append(pa)
        all_es_err.append(se)
        all_ed_err.append(de)
        all_ep_err.append(pe)
        print(f"{ii}  {ll}  {sa}  {da}")

    all_lambda = np.array(all_lambda)
    all_es = np.array(all_es)
    all_ed = np.array(all_ed)
    all_ep = np.array(all_ep)
    all_es_err = np.array(all_es_err)
    all_ed_err = np.array(all_ed_err)
    all_ep_err = np.array(all_ep_err)
    if switch == 'one-step' or switch == 'two-step':
        if step == 'both':
            de = all_ed / all_lambda - all_es / (1 - all_lambda)
            all_err = np.sqrt(
                np.square(all_ed_err / all_lambda) +
                np.square(all_es_err / (1 - all_lambda)))
        elif step == 'deep_on':
            de = all_ed / all_lambda
            # de = all_ep / all_lambda
            all_err = all_ed_err / all_lambda
        elif step == 'spring_off':
            de = -all_es / (1 - all_lambda)
            # de = -all_ep / (1 - all_lambda)
            all_err = all_es_err / (1 - all_lambda)
        else:
            raise RuntimeError('unknow step', step)
    elif switch == 'three-step':
        if step == 'lj_on' or step == 'deep_on':
            de = all_ed
            all_err = all_ed_err
        elif step == 'spring_off':
            de = -all_es / (1 - all_lambda) + all_ed
            all_err = np.sqrt(
                np.square(all_es_err / (1 - all_lambda)) +
                np.square(all_ed_err))
        else:
            raise RuntimeError('unknow step', step)
    else:
        raise RuntimeError('unknow switch', switch)

    all_print = []
    # all_print.append(np.arange(len(all_lambda)))
    all_print.append(all_lambda)
    all_print.append(de)
    all_print.append(all_err)
    all_print.append(all_ed / all_lambda)
    all_print.append(all_es / (1 - all_lambda))
    all_print.append(all_ed_err / all_lambda)
    all_print.append(all_es_err / (1 - all_lambda))
    all_print = np.array(all_print)
    np.savetxt(os.path.join(iter_name, 'hti.out'),
               all_print.T,
               fmt='%.8e',
               header='lmbda dU dU_err Ud Us Ud_err Us_err')

    new_lambda, i, i_e, s_e = integrate_range(all_lambda,
                                              de,
                                              all_err,
                                              scheme=scheme)
    print('~~', new_lambda, i, i_e, s_e)
    if new_lambda[-1] != all_lambda[-1]:
        if new_lambda[-1] == all_lambda[-2]:
            _, i1, i_e1, s_e1 = integrate_range(all_lambda[-2:],
                                                de[-2:],
                                                all_err[-2:],
                                                scheme='t')
            diff_e = i[-1] + i1[-1]
            err = np.linalg.norm([s_e[-1], s_e1[-1]])
            sys_err = i_e[-1] + i_e1[-1]
        else:
            raise RuntimeError("lambda does not match!")
    else:
        diff_e = i[-1]
        err = s_e[-1]
        sys_err = i_e[-1]

    # diff_e, err = integrate(all_lambda, de, all_err)
    # sys_err = integrate_sys_err(all_lambda, de)

    path_endpnt = os.path.join(iter_name, 'task.endpnt')
    if os.path.isdir(path_endpnt):
        print('# Found end point, compute thermo info from it')
        thermo_info = _compute_thermo(os.path.join(path_endpnt, 'log.lammps'),
                                      natoms, stat_skip, stat_bsize)
    else:
        print(
            '# Not found end point, compute thermo info from the last lambda')
        thermo_info = _compute_thermo(
            os.path.join(all_tasks[-1], 'log.lammps'), natoms, stat_skip,
            stat_bsize)

    return diff_e, [err, sys_err], thermo_info
Ejemplo n.º 6
0
def _compute_thermo(lmplog, natoms, stat_skip, stat_bsize):
    data = lib.lammps.get_thermo(lmplog)
    ea, ee = block_avg(data[:, 3], skip=stat_skip, block_size=stat_bsize)
    ha, he = block_avg(data[:, 4], skip=stat_skip, block_size=stat_bsize)
    ta, te = block_avg(data[:, 5], skip=stat_skip, block_size=stat_bsize)
    pa, pe = block_avg(data[:, 6], skip=stat_skip, block_size=stat_bsize)
    va, ve = block_avg(data[:, 7], skip=stat_skip, block_size=stat_bsize)
    lxx, lxxe = block_avg(data[:, 8], skip=stat_skip, block_size=stat_bsize)
    lyy, lyye = block_avg(data[:, 9], skip=stat_skip, block_size=stat_bsize)
    lzz, lzze = block_avg(data[:, 10], skip=stat_skip, block_size=stat_bsize)
    lxy, lxye = block_avg(data[:, 11], skip=stat_skip, block_size=stat_bsize)
    lxz, lxze = block_avg(data[:, 12], skip=stat_skip, block_size=stat_bsize)
    lyz, lyze = block_avg(data[:, 13], skip=stat_skip, block_size=stat_bsize)
    pxx, pxxe = block_avg(data[:, 14], skip=stat_skip, block_size=stat_bsize)
    pyy, pyye = block_avg(data[:, 15], skip=stat_skip, block_size=stat_bsize)
    pzz, pzze = block_avg(data[:, 16], skip=stat_skip, block_size=stat_bsize)
    pxy, pxye = block_avg(data[:, 17], skip=stat_skip, block_size=stat_bsize)
    pxz, pxze = block_avg(data[:, 18], skip=stat_skip, block_size=stat_bsize)
    pyz, pyze = block_avg(data[:, 19], skip=stat_skip, block_size=stat_bsize)
    thermo_info = {}
    thermo_info['natoms'] = natoms
    thermo_info['p'] = pa
    thermo_info['p_err'] = pe
    thermo_info['v'] = va / natoms
    thermo_info['v_err'] = ve / np.sqrt(natoms)
    thermo_info['e'] = ea / natoms
    thermo_info['e_err'] = ee / np.sqrt(natoms)
    thermo_info['t'] = ta
    thermo_info['t_err'] = te
    thermo_info['h'] = ha / natoms
    thermo_info['h_err'] = he / np.sqrt(natoms)
    unit_cvt = 1e5 * (1e-10**3) / pc.electron_volt
    thermo_info['pv'] = pa * va * unit_cvt / natoms
    thermo_info['pv_err'] = pe * va * unit_cvt / np.sqrt(natoms)
    thermo_info['lxx'] = lxx
    thermo_info['lxx_err'] = lxxe
    thermo_info['lyy'] = lyy
    thermo_info['lyy_err'] = lyye
    thermo_info['lzz'] = lzz
    thermo_info['lzz_err'] = lzze
    thermo_info['lxy'] = lxy
    thermo_info['lxy_err'] = lxye
    thermo_info['lxz'] = lxz
    thermo_info['lxz_err'] = lxze
    thermo_info['lyz'] = lyz
    thermo_info['lyz_err'] = lyze
    thermo_info['pxx'] = pxx
    thermo_info['pxx_err'] = pxxe
    thermo_info['pyy'] = pyy
    thermo_info['pyy_err'] = pyye
    thermo_info['pzz'] = pzz
    thermo_info['pzz_err'] = pzze
    thermo_info['pxy'] = pxy
    thermo_info['pxy_err'] = pxye
    thermo_info['pxz'] = pxz
    thermo_info['pxz_err'] = pxze
    thermo_info['pyz'] = pyz
    thermo_info['pyz_err'] = pyze
    return thermo_info
Ejemplo n.º 7
0
def _post_tasks(iter_name, step, natoms, scheme = 's') :
    jdata = json.load(open(os.path.join(iter_name, 'in.json')))
    stat_skip = jdata['stat_skip']
    stat_bsize = jdata['stat_bsize']
    all_tasks = glob.glob(os.path.join(iter_name, 'task.[0-9]*'))
    all_tasks.sort()
    ntasks = len(all_tasks)
    
    all_lambda = []
    all_bd_a = []
    all_bd_e = []
    all_ag_a = []
    all_ag_e = []
    all_dp_a = []
    all_dp_e = []

    for ii in all_tasks :
        log_name = os.path.join(ii, 'log.lammps')
        data = get_thermo(log_name)
        np.savetxt(os.path.join(ii, 'data'), data, fmt = '%.6e')
        bd_a, bd_e = block_avg(data[:, 8], skip = stat_skip, block_size = stat_bsize)
        ag_a, ag_e = block_avg(data[:, 9], skip = stat_skip, block_size = stat_bsize)
        dp_a, dp_e = block_avg(data[:,10], skip = stat_skip, block_size = stat_bsize)
        bd_a /= natoms
        ag_a /= natoms
        dp_a /= natoms
        bd_e /= np.sqrt(natoms)
        ag_e /= np.sqrt(natoms)
        dp_e /= np.sqrt(natoms)
        lmda_name = os.path.join(ii, 'lambda.out')
        ll = float(open(lmda_name).read())
        all_lambda.append(ll)
        all_bd_a.append(bd_a)
        all_bd_e.append(bd_e)
        all_ag_a.append(ag_a)
        all_ag_e.append(ag_e)
        all_dp_a.append(dp_a)
        all_dp_e.append(dp_e)

    all_lambda = np.array(all_lambda)
    all_bd_a = np.array(all_bd_a)
    all_bd_e = np.array(all_bd_e)
    all_ag_a = np.array(all_ag_a)
    all_ag_e = np.array(all_ag_e)
    all_dp_a = np.array(all_dp_a)
    all_dp_e = np.array(all_dp_e)
    if step == 'angle_on' :        
        de = all_ag_a / all_lambda + all_dp_a
        all_err = np.sqrt(np.square(all_ag_e / all_lambda) +
                          np.square(all_dp_e))
    elif step == 'deep_on' :
        de = all_dp_a
        all_err = all_dp_e
    elif step == 'bond_angle_off' :
        de = - (all_bd_a + all_ag_a) / (1 - all_lambda) + all_dp_a
        all_err = np.sqrt(np.square(all_bd_e / (1 - all_lambda)) + 
                          np.square(all_ag_e / (1 - all_lambda)) + 
                          np.square(all_dp_e))

    all_print = []
    # all_print.append(np.arange(len(all_lambda)))
    all_print.append(all_lambda)
    all_print.append(de)
    all_print.append(all_err)
    all_print = np.array(all_print)
    np.savetxt(os.path.join(iter_name, 'hti.out'), 
               all_print.T, 
               fmt = '%.8e', 
               header = 'lmbda dU dU_err')

    new_lambda, i, i_e, s_e = integrate_range(all_lambda, de, all_err, scheme = scheme)
    if new_lambda[-1] != all_lambda[-1] :
        if new_lambda[-1] == all_lambda[-2]:
            _, i1, i_e1, s_e1 = integrate_range(all_lambda[-2:], de[-2:], all_err[-2:], scheme='t')
            diff_e = i[-1] + i1[-1]
            err = np.linalg.norm([s_e[-1], s_e1[-1]])
            sys_err = i_e[-1] + i_e1[-1]
        else :
            raise RuntimeError("lambda does not match!")
    else:
        diff_e = i[-1]
        err = s_e[-1]
        sys_err = i_e[-1]

    # diff_e, err = integrate(all_lambda, de, all_err)
    # sys_err = integrate_sys_err(all_lambda, de)

    thermo_info = _compute_thermo(os.path.join(all_tasks[-1], 'log.lammps'), 
                                  natoms,
                                  stat_skip, stat_bsize)

    return diff_e, [err, sys_err], thermo_info