Esempio n. 1
0
def test_automesh():
    """
    automesh should return a meshed array whose length is within its range.
    """
    diffsys = DiffSystem(Xr=[0, 1], X=[0, 1], DC=[1e-14, 1e-13])
    dis = mesh(0, 1000, 201)
    profile_init = step(dis, 500, diffsys)
    time = 200 * 3600
    profile = sphSim(profile_init, diffsys, time)
    dism = automesh(profile, diffsys, n=[300, 400])

    assert len(dism) >= 300 and len(dism) <= 400
Esempio n. 2
0
def test_SFplot():
    """
    SFplot should return an axes object when a DiffProfile and time is passed
    """
    diffsys = DiffSystem(Xr=[0, 1], X=[0, 1], DC=[1e-14, 1e-13])
    dis = mesh(0, 1000, 201)
    profile_init = step(dis, 500, diffsys)
    time = 200 * 3600
    profile = sphSim(profile_init, diffsys, time)
    ax = SFplot(profile, time, Xlim=[0, 1], label='test')

    assert isinstance(ax, Axes)
Esempio n. 3
0
def test_dispfunc():
    """
    disfunc and profilefunc should give functions to copy profile data.
    """
    diffsys = DiffSystem(Xr=[0, 1], X=[0, 1], DC=[1e-14, 1e-13])
    dis = mesh(0, 1000, 201)
    profile_init = step(dis, 500, diffsys)
    time = 200 * 3600
    profile = sphSim(profile_init, diffsys, time)

    fX = profilefunc(profile)
    fdis = disfunc(profile.dis, profile.X)

    assert np.all(abs(splev(dis, fX) - profile.X) < 0.01)
    assert np.all(abs(splev(profile.X, fdis) - dis) < 0.1)
Esempio n. 4
0
def test_sphsim():
    """
    Single-phase system simulation.
    Offset of the simulated matano plane should be very small.
    """
    diffsys = DiffSystem(Xr=[0, 1], X=[0, 1], DC=[1e-14, 1e-14])
    dis = mesh(0, 1000, 201)
    profile_init = step(dis, 500, diffsys)
    time = 200 * 3600
    profile_final = sphSim(profile_init, diffsys, time)

    mpi = matanocalc(profile_init, [0, 1])
    mpf = matanocalc(profile_final, [0, 1])

    assert isinstance(profile_final, DiffProfile)
    assert len(profile_final.If) == diffsys.Np + 1
    assert abs(mpi - mpf) < 1
Esempio n. 5
0
def test_mphsim():
    """
    Multiple-phase system simulation.
    Offset of the simulated matano plane should be very small.
    """
    Xr = [[0, .4], [.6, 1]]
    X = np.linspace(0, 1, 101)
    DC = np.linspace(1, 2, 101) * 1e-14
    diffsys = DiffSystem(Xr=Xr, X=X, DC=DC)
    dis = mesh(0, 1000, 201)
    profile_init = step(dis, 500, diffsys)
    time = 200 * 3600
    profile_final = mphSim(profile_init, diffsys, time)

    mpi = matanocalc(profile_init, [0, 1])
    mpf = matanocalc(profile_final, [0, 1])

    assert isinstance(profile_final, DiffProfile)
    assert len(profile_final.If) == diffsys.Np + 1
    assert abs(mpi - mpf) < 1
Esempio n. 6
0
def FSA(profile_exp,
        profile_sm,
        diffsys,
        time,
        Xlim=[],
        n=[400, 500],
        w=None,
        f=None,
        alpha=0.3,
        name=''):
    """
    Forward Simulation Analysis
    Extract diffusion coefficients based on a diffusion profile.
    Please do not close any plot window during the FSA process.

    This is the final step of FSA.

    Parameters
    ----------
    profile_exp : DiffProfile
        Experimental diffusion profile, used for comparison with simulation
        results.
    profile_sm : DiffProfile
        Diffusion profile after data smooth on experimental profile.
    diffsys : DiffSystem
        Diffusion coefficients
    time : float
        Diffusion time in seconds
    Xlim : list (float), optional
        Passed to 'pydiffusion.Dtools.SF', 'pydiffusion.utils.step'.
        Indicates the left and right concentration limits for calculation.
        Default value = [profile.X[0], profile.X[-1]].
    n : list. optional
        Passed to 'pydiffusion.utils.automesh'.
        Meshing number range, default = [400, 500].
    w : list, optional
        Weights of each phase to calculate error.
        Passed to 'pydiffusion.utils.error_profile'.
    f : function of Meshing
        Keyword argument of automesh()
    alpha : float
        Keyword argument of automesh()
    name : str, optional
        Name the output DiffProfile

    Returns
    -------
    profile_sim : DiffProfile
        Simulated diffusion profile after FSA.
    diffsys_sim : DiffSystem
        Calculated diffusion efficients by FSA.

    Examples
    --------
    After datasmooth() and Dmodel(), FSA can be performed to calculate accurate diffusion coefficients:

    >>> ds = datasmooth(exp)
    >>> dsys = Dmodel(ds, time)
    >>> fsa = FSA(exp, ds, dsys, time)

    """
    # Create step profile on meshed grids
    dism = automesh(profile=profile_sm, diffsys=diffsys, n=n, f=f, alpha=alpha)
    matano = matanocalc(profile_sm, Xlim)
    if Xlim == [] and profile_sm.X[-1] < profile_sm.X[0]:
        profile_init = step(dism, matano, diffsys,
                            [diffsys.Xr[-1, 1], diffsys.Xr[0, 0]])
    else:
        profile_init = step(dism, matano, diffsys, Xlim)

    # Determine the stop criteria of forward simulations
    error_sm = error_profile(profile_sm, profile_exp)
    ipt = input(
        'Default error = %.6f\nInput the stop criteria of error: [%.6f]\n' %
        (error_sm, error_sm * 2))
    error_stop = error_sm * 2 if ipt == '' else float(ipt)

    # If there is no Xspl info in diffsys, use Phase Mode
    # else: ask if use Phase or Point Mode
    if diffsys.Xspl is not None:
        ipt = input(
            'Use Phase Mode? [n]\n(The shape of diffusivity curve does not change)\n'
        )
        pp = False if 'y' in ipt or 'Y' in ipt else True
    else:
        pp = False

    if name == '':
        name = profile_exp.name + '_FSA'

    # Diffusion coefficients used for forward simulations
    diffsys_sim = DiffSystem(diffsys.Xr,
                             diffsys.Dfunc,
                             Xspl=diffsys.Xspl,
                             name=name)

    # Plot FSA status
    fig = plt.figure('FSA', figsize=(16, 6))
    ax1, ax2 = fig.add_subplot(121), fig.add_subplot(122)
    profileplot(profile_exp,
                ax1,
                ls='none',
                marker='o',
                c='b',
                fillstyle='none')
    profileplot(profile_sm, ax1, ls='-', c='g', lw=1)
    SFplot(profile_sm, time, Xlim, ax2, ls='none', c='b', marker='.')
    DCplot(diffsys_sim, ax2, ls='-', c='r', lw=2)
    plt.draw()
    plt.tight_layout()
    plt.pause(0.1)

    n_sim = 0
    while True:

        # Simulation
        n_sim += 1
        profile_sim = mphSim(profile_init, diffsys_sim, time, name=name)
        error_sim = error_profile(profile_sim, profile_exp, w)
        print('Simulation %i, error = %f(%f)' % (n_sim, error_sim, error_stop))

        # Plot simulation results
        ax1.cla()
        ax2.cla()
        profileplot(profile_exp,
                    ax1,
                    ls='none',
                    marker='o',
                    c='b',
                    fillstyle='none')
        profileplot(profile_sm, ax1, ls='-', c='g', lw=1)
        profileplot(profile_sim, ax1, ls='-', c='r', lw=2)
        SFplot(profile_sm, time, Xlim, ax2, ls='none', c='b', marker='.')
        DCplot(diffsys_sim, ax2, ls='-', c='r', lw=2)
        plt.draw()
        plt.tight_layout()

        # DC adjust
        Dfunc_adjust = [0] * diffsys_sim.Np

        # If error > stop criteria, continue simulation by auto DC adjustment
        if error_sim > error_stop:
            for ph in range(diffsys_sim.Np):
                try:
                    Dfunc_adjust[ph] = Dadjust(profile_sm, profile_sim,
                                               diffsys_sim, ph, pp)
                except (ValueError, TypeError) as error:
                    ita_finish()
                    raise error
            diffsys_sim.Dfunc = Dfunc_adjust

        # If error < stop criteria or simulate too many times
        if error_sim <= error_stop or n_sim > 9:

            ita_start()

            # Ask if exit
            ipt = ask_input('Satisfied with FSA? [n]')
            if 'y' in ipt or 'Y' in ipt:
                ita_finish()
                break

            # If use Point Mode
            if diffsys_sim.Xspl is not None:
                ipt = ask_input('Use Point Mode (y) or Phase Mode (n)? [y]')
                pp = False if 'n' in ipt or 'N' in ipt else True
                if pp:
                    for ph in range(diffsys_sim.Np):
                        try:
                            Dfunc_adjust[ph] = Dadjust(profile_sm, profile_sim,
                                                       diffsys_sim, ph, pp)
                        except (ValueError, TypeError) as error:
                            ita_finish()
                            raise error
                    diffsys_sim.Dfunc = Dfunc_adjust

                    DCplot(diffsys_sim, ax2, ls='-', c='m', lw=2)
                    plt.draw()
                    plt.pause(0.1)
                    ita_finish()
                    continue

            # Phase Mode, ask if use manual input for each phase
            pp = False
            ipt = input('Phase Mode\nManually input for each phase? [n]')
            manual = True if 'y' in ipt or 'Y' in ipt else False
            for ph in range(diffsys_sim.Np):
                if manual:
                    ipt = input(
                        'Input deltaD for phase # %i:\n(DC = DC * 10^deltaD, default deltaD = auto)\n'
                        % (ph + 1))
                    deltaD = float(ipt) if ipt != '' else None
                else:
                    deltaD = None
                try:
                    Dfunc_adjust[ph] = Dadjust(profile_sm, profile_sim,
                                               diffsys_sim, ph, pp, deltaD)
                except (ValueError, TypeError) as error:
                    ita_finish()
                    raise error

            # Apply the adjustment to diffsys_sim
            diffsys_sim.Dfunc = Dfunc_adjust

            DCplot(diffsys_sim, ax2, ls='-', c='m', lw=2)
            plt.draw()
            plt.pause(0.1)
            ita_finish()

    return profile_sim, diffsys_sim
Esempio n. 7
0
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from pydiffusion.core import DiffSystem
from pydiffusion.utils import step, mesh
from pydiffusion.simulation import mphSim
from pydiffusion.plot import profileplot, DCplot
from pydiffusion.io import read_csv, save_csv

# Create diffusion system with constant DC
diffsys = DiffSystem(Xr=[0, 1], X=[0, 1], DC=[1e-14, 1e-14], name='Constant D')

# Create initial step profile
dis = mesh(0, 1000, 501)
profile_init = step(dis, 500, diffsys, name='Intitial step profile')

fig = plt.figure(figsize=(16, 6))
ax1, ax2 = fig.add_subplot(121), fig.add_subplot(122)
ax1.set_title('Diffusion Coefficients', fontsize=15)
ax2.set_title('Initial Step Profile', fontsize=15)
DCplot(diffsys, ax1)
profileplot(profile_init, ax2)

# Diffusion simulation using the setups
time = 200 * 3600
profile_final = mphSim(profile_init, diffsys, time)

ax = profileplot(profile_init, ls='--')
profileplot(profile_final, ax, c='r')

# Read diffusion coefficients data of Ni-Mo system
Esempio n. 8
0
from pydiffusion.simulation import ErrorAnalysis
from pydiffusion.plot import DCplot, profileplot

# Read data, create bias
profile_fsa, diffsys_TiZr = read_csv('examples/data/TiZr.csv', [0, 1])
profile_exp, _ = read_csv('examples/data/TiZr_exp.csv')
diffsys_bias = DCbias(diffsys_TiZr, 0.2, 0.1)

ax = DCplot(diffsys_TiZr, label='original')
DCplot(diffsys_bias, ax, c='r', ls='--', label='bias')
plt.pause(1.0)

# Error analysis with low accuracy
dism = automesh(profile_fsa, diffsys_TiZr, [300, 350])
mp = matanocalc(profile_fsa, [0, 1])
profile_init = step(dism, mp, diffsys_TiZr)
time = 100 * 3600
error_result = ErrorAnalysis(profile_exp,
                             profile_init,
                             diffsys_TiZr,
                             time,
                             loc=3,
                             accuracy=1e-2,
                             output=True)

fig = plt.figure(figsize=(16, 6))
ax1, ax2 = fig.add_subplot(121), fig.add_subplot(122)
DCplot(diffsys_TiZr, ax1, error_result)
profileplot(profile_fsa, ax2, error_result)
profileplot(profile_exp, ax2, marker='o', ls='none', fillstyle='none')
plt.pause(1.0)