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
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)
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)
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
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
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
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
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)