In [5]:
import json
from collections import namedtuple
with open('../scripts/constant_current.json', 'r') as fp:
params_dict = json.load(fp)
params = namedtuple('ParamClass', params_dict.keys())(*params_dict.values())
In [11]:
R = params.router
D = params.diffusionCupric
c = params.bulkCupric
#delta = params.delta
delta = 15e-6
n = params.charge
F = params.faradaysConstant
A = R**2 / 2
b = 1.0
I = D * c * n * F * A * b / (params.featureDepth)
print 'current:',I
In [9]:
print params
The simulations are actually using a current of $2\times 10^{-7}$ A as this seems to work better numerically
In [1]:
%load_ext autoreload
%autoreload 4
from sumatra.projects import load_project
from extremefill2D.tools import smt_ipy_table
from extremefill2D.multiViewer import MultiViewer
project = load_project('../scripts')
In [2]:
import json
fields = ['label', 'reason', 'timestamp', 'parameters', 'duration', 'version', 'tags']
parameters = ['current', 'rboundary', 'Nx', 'capacitance', 'totalTime', 'delta', 'router', 'rboundary', 'featureDepth']
jsonfile = '../scripts/constant_current.json'
with open(jsonfile, 'rb') as ff:
params_dict = json.load(ff)
print params_dict
print params_dict['router']
In [3]:
records = project.record_store.list(project.name, tags=['constant_current2'])
viewer = MultiViewer(records, figsize=(5., 5.))
viewer.plot(times=(0., 800.), xlim=49e-6, ylim=-90e-6)
smt_ipy_table(records, fields=fields, parameters=parameters)
Out[3]:
In [4]:
records = project.record_store.list(project.name, tags=['constant_current5'])
viewer = MultiViewer(records, figsize=(5., 5.))
viewer.plot(times=(0., 500.), xlim=49e-6, ylim=-90e-6)
smt_ipy_table(records, fields=fields, parameters=parameters)
Out[4]:
In [5]:
records = project.record_store.list(project.name, tags=['constant_current6'])
viewer = MultiViewer(records, figsize=(5., 5.))
viewer.plot(times=(0., 100, 200, 300, 400, 500.), xlim=49e-6, ylim=-90e-6)
smt_ipy_table(records, fields=fields, parameters=parameters)
Out[5]:
The following simulations allow deposition at cells which have more than one neighbouring cell that lies across the interface.
The aim of this was to try and remove the strange one cell thick gap that occurs during deposition when all side wall wetting is prevented.
Unfortunately, this leads to side wall wetting up the feature, which is not really physical either.
In [6]:
records = project.record_store.list(project.name, tags=['constant_current7'])
viewer = MultiViewer(records, figsize=(5., 5.))
viewer.plot(times=np.linspace(0., 5000., 10), xlim=49e-6, ylim=-90e-6)
smt_ipy_table(records, fields=fields, parameters=parameters)
Out[6]:
These simulations are for no corner deposition for longer times and for different grid densities.
The aim of these simulations is to demonstrate that
(a) as the grid is refined the non-wetting at the side wall has no impact on the filling
(b) that the filling remains flat during the entire filling
In [7]:
records = project.record_store.list(project.name, tags=['constant_current8'])
viewer = MultiViewer(records, figsize=(5., 5.))
viewer.plot(times=np.linspace(0.0, 5000., 10), xlim=49e-6, ylim=-90e-6)
smt_ipy_table(records, fields=fields, parameters=parameters)
Out[7]:
These simulations are for no corner deposition for longer times and for different grid densities.
The aim of these simulations is to demonstrate that
(a) as the grid is refined the non-wetting at the side wall has no impact on the filling
(b) that the filling remains flat during the entire filling
(c) the filling exits the trench
One simulation was lost due to a database crash.
In [8]:
records = project.record_store.list(project.name, tags=['constant_current9'])
viewer = MultiViewer(records, figsize=(5., 5.))
viewer.plot(times=np.linspace(0.0, 8000., 20), xlim=49e-6, ylim=-90e-6)
smt_ipy_table(records, fields=fields, parameters=parameters)
Out[8]:
Running constant_current10
: run jobs for longer, Nx=100
, 200
and 400
.
In [10]:
!qstat
In [9]:
records = project.record_store.list(project.name, tags=['constant_current10'])
viewer = MultiViewer(records, figsize=(5., 5.))
viewer.plot(times=np.linspace(0.0, 8000., 20), xlim=49e-6, ylim=-90e-6)
smt_ipy_table(records, fields=fields, parameters=parameters)
Out[9]:
The boundary layer is the shape of a hemispherical cap. This is designed as a gross approximation to the shape that the boundary layer might have with a large feature and a convection field. The goal is to ascertain whether the filling becomes convex or maintains a flat shape. Intuitively the fill shape should be convex.
The tag for these simulations is constant_current11
.
In [4]:
!qstat
In [8]:
records = project.record_store.list(project.name, tags=['constant_current11'])
viewer = MultiViewer(records, figsize=(5., 5.))
viewer.plot(times=np.linspace(0.0, 8000., 20), xlim=49e-6, ylim=-90e-6)
smt_ipy_table(records, fields=fields, parameters=parameters + ['cap_radius'])
Out[8]:
Clearly the growth is remaining flat even though we have big dip in the boundary layer. What could be happending?
the boundary layer shape algorithm could be implemented incorrectly
we are not running near the diffusion limit so there isn't much of a decrease in the value of the cupric field down the trench, the remedy is just to increase the overall current
In the above simulations, the metal field is not being saved. To check the above issues, the cupric field will be saved and plotted to diagonse this issue. Also the simulation only needs to be run for a short time.
In [11]:
records = project.record_store.list(project.name, tags=['constant_current12'])
viewer = MultiViewer(records, figsize=(5., 5.))
viewer.plot(times=np.linspace(0.0, 2000., 20), xlim=49e-6, ylim=-90e-6)
smt_ipy_table(records, fields=fields, parameters=parameters + ['cap_radius'])
Out[11]:
In [12]:
import os
import fipy as fp
import matplotlib.pyplot as plt
import numpy as np
from extremefill2D.dicttable import DictTable
import brewer2mpl
def plot_cupric(record, datafile=None, index=None):
if record is not None:
datafile = os.path.join(record.datastore.root, record.output_data[0].path)
label = record.label
else:
label = ''
data = DictTable(datafile, 'r')
if index is None:
index = int(data.getLatestIndex())
data0 = data[0]
mesh = fp.Grid2D(nx=data0['nx'], ny=data0['ny'], dx=data0['dx'], dy=data0['dy'])
dy = mesh.dy
shape = (mesh.ny, mesh.nx)
x = mesh.x.value
y = mesh.y.value
fig = plt.figure()
ax = fig.add_subplot(111)
cupric = data[index]['cupric']
#set1 = brewer2mpl.get_map('BuGn', 'sequential', 9).mpl_colors
def flip(a, shape):
a = np.reshape(a, shape)
return a.swapaxes(0,1)
x = flip(x, shape)
y = flip(y, shape)
cupric = flip(cupric, shape)
plt.contourf(x, y, cupric, np.linspace(0, 1001, 10))
plt.colorbar()
ax.set_aspect(1.)
plt.title(label)
In [8]:
plot_cupric(records[0])
It is clear from the above image that the cupric variable is not fixed at 1000.0 in the hemisphierical cap of radius 3.75e-5.
In [63]:
datafile = os.path.join('../scripts/Data', 'data.h5')
plot_cupric(None, datafile)
In [62]:
records = project.record_store.list(project.name, tags=['constant_current13'])
viewer = MultiViewer(records, figsize=(5., 5.))
viewer.plot(times=np.linspace(0.0, 2000., 20), xlim=49e-6, ylim=-90e-6)
smt_ipy_table(records, fields=fields, parameters=parameters + ['cap_radius'])
Out[62]:
In [63]:
plot_cupric(records[0])
The filling is still flat even though the shape of the cap is now correct. Probably now need to drive the system with a higher current to get more differential in the cupric.
In [4]:
records = project.record_store.list(project.name, tags=['constant_current14'])
smt_ipy_table(records, fields=fields, parameters=parameters + ['cap_radius'])
Out[4]:
In [5]:
viewer = MultiViewer(records, figsize=(5., 5.))
viewer.plot(times=np.linspace(0.0, 4000., 20), xlim=49e-6, ylim=-90e-6)
Increasing $I$ eventually leads to non-planar interface growth, however, there is a critical value (diffusion limit) of $I$ for which the numerical solution becomes unstable. This estimated limit should be about
$$ I = \frac{D c}{\delta} F n A \approx 2.4\times 10^{-6} \text{(A)} $$for $\delta = 15\times 10^{-6} \text{(m)}$. However, the $I=8\times 10^{-7} \text{(A)}$ (8dc1a7af
) simulation is unstable. The simulation output shows NANs after about 170 time steps, likewise for 359649bd
. The output from 8dc1a7af
on previous time steps to the NANs shows a struggle for the curent to converge and it never exceeds a value of $I=6.1\times 10^{-7} \text{(A)}$, a far lower value than the theoretical diffusion limit. The images below show the cupric fields at early times after they have reached a steady state. It is clear that 8dc1a7af
is at the diffusion limit.
The next group of simulations will run with $I$ between $4$ and $6\times 10^{-7} \text{(A)}$ and increasing values of rboundary
.
In [9]:
plot_cupric(records[0], index=300)
In [10]:
plot_cupric(records[1], index=100)
In [3]:
from extremefill2D.tools import getSMTRecords
records = project.record_store.list(project.name, tags=['constant_current15'])
records50 = getSMTRecords(records, parameters={'rboundary' : 50e-6})
smt_ipy_table(records50, fields=fields, parameters=parameters + ['cap_radius'])
Out[3]:
In [7]:
viewer = MultiViewer(records50, figsize=(5., 5.))
viewer.plot(times=np.linspace(0.0, 5000., 20), xlim=49e-6, ylim=-90e-6)
In [17]:
records100 = getSMTRecords(records, parameters={'rboundary' : 100e-6})
smt_ipy_table(records100, fields=fields, parameters=parameters + ['cap_radius'])
Out[17]:
In [16]:
viewer = MultiViewer(records100, figsize=(5., 5.))
viewer.plot(times=np.linspace(0.0, 4000., 20), xlim=49e-6, ylim=-90e-6)
In [19]:
records200 = getSMTRecords(records, parameters={'rboundary' : 200e-6})
smt_ipy_table(records200, fields=fields, parameters=parameters + ['cap_radius'])
Out[19]:
In [20]:
viewer = MultiViewer(records200, figsize=(5., 5.))
viewer.plot(times=np.linspace(0.0, 4000., 20), xlim=49e-6, ylim=-90e-6)
In [21]:
records400 = getSMTRecords(records, parameters={'rboundary' : 400e-6})
smt_ipy_table(records400, fields=fields, parameters=parameters + ['cap_radius'])
Out[21]:
In [22]:
viewer = MultiViewer(records400, figsize=(5., 5.))
viewer.plot(times=np.linspace(0.0, 4000., 20), xlim=49e-6, ylim=-90e-6)
In [ ]:
In [9]:
4e-7 * 1.2**np.arange(10)
Out[9]:
In [ ]:
In [3]:
from extremefill2D.tools import getSMTRecords
records_17 = project.record_store.list(project.name, tags=['constant_current17'])
smt_ipy_table(records_17, fields=fields, parameters=parameters + ['cap_radius'])
Out[3]:
In [4]:
%load_ext autoreload
%autoreload 4
from sumatra.projects import load_project
from extremefill2D.tools import smt_ipy_table
from extremefill2D.multiViewer import MultiViewer
viewer = MultiViewer(records_17, figsize=(5., 5.))
viewer.plot(times=np.linspace(0.0, 4000., 20), xlim=49e-6, ylim=-90e-6)
In [15]:
?plot_cupric
In [27]:
plot_cupric(records_17[-2], index=200)
In [28]:
np.logspace(1, 3, 5)
Out[28]:
In [30]:
x0 = np.log10(4.8e-7)
x1 = np.log10(5.76e-7)
np.logspace(x0, x1, 5)
Out[30]:
In [3]:
from extremefill2D.tools import getSMTRecords
records_18 = project.record_store.list(project.name, tags=['constant_current18'])
records_18_sorted = sorted(records_18, key=lambda r: r.parameters['current'])
smt_ipy_table(records_18_sorted, fields=fields, parameters=parameters + ['cap_radius'])
Out[3]:
In [5]:
%load_ext autoreload
%autoreload 4
from sumatra.projects import load_project
from extremefill2D.tools import smt_ipy_table
from extremefill2D.multiViewer import MultiViewer
reshaped_records = zip(*[iter(records_18_sorted)]*4)
viewer = MultiViewer(reshaped_records, figsize=(5., 5.))
viewer.plot(times=np.linspace(0.0, 4000., 20), xlim=49e-6, ylim=-90e-6)
In [4]:
print len(records_18)
In [ ]: