Beispiel #1
0
def TwoGaussianImmuneResponse2D(strength, x, y, Ra):
    #Test : plt.plot(r,10*numerix.exp(-r**2/(2*dz))/numerix.sqrt(2*numerix.pi*2*dz))
    return ((strength) * numerix.exp(-((x + 0.6)**2 + (y - 0.3)**2) /
                                     (2 * Ra)) +
            (strength) * numerix.exp(-((x - 0.6)**2 + (y - 0.2)**2) /
                                     (2 * Ra))) / (numerix.sqrt(
                                         2 * numerix.pi * Ra))
Beispiel #2
0
    def calc_dep_vars(self, params):
        Fbar = params.faradaysConstant / params.gasConstant / params.temperature
        self.coeff_forward0 = params.alpha0 * Fbar
        self.coeff_backward0 = (params.alpha_ - params.alpha0) * Fbar
        self.coeff_forward1 = params.alpha1 * Fbar
        self.coeff_backward1 = (params.alpha_ - params.alpha1) * Fbar
        exp_forward0 = numerix.exp(self.coeff_forward0 * self.potential)
        exp_backward0 = numerix.exp(-self.coeff_backward0 * self.potential)
        exp_forward1 = numerix.exp(self.coeff_forward1 * self.potential)
        exp_backward1 = numerix.exp(-self.coeff_backward1 * self.potential)
        cbar =  self.cupric / params.bulkCupric

        I0 = params.i0 * (1 - self.interfaceTheta)
        I1 = params.i1 * self.interfaceTheta

        self.beta_forward0 = cbar * I0 * exp_forward0
        self.beta_backward0 = cbar * I0 * exp_backward0
        self.beta_forward1 = cbar * I1 * exp_forward1
        self.beta_backward1 = cbar * I1 * exp_backward1

        self.baseCurrent = I0 * (exp_forward0 - exp_backward0) + I1 * (exp_forward1 - exp_backward1)
        self.currentDensity = cbar * self.baseCurrent
        self.currentDerivative = cbar * (I0 * (self.coeff_forward0 *  exp_forward0 + self.coeff_backward0 * exp_backward0) \
                                         + I1 * (self.coeff_forward1 *  exp_forward1 + self.coeff_backward1 * exp_backward1))
        self.depositionRate = self.currentDensity * params.omega / params.charge / params.faradaysConstant
Beispiel #3
0
 def calc_BV(self, j0,
             overpotential):  # Coded here is the RHS of the BV equation
     # print(overpotential)                                                                                          # Code to debug the exponential overflow issue when the number of nodes in each domain is changed
     # print(numerix.exp(((1-self.alpha)*F*(overpotential))/(R*self.T)))                                             # Overpotential values are high, causing the exponents to overflow, it seems..
     # print(numerix.exp((-self.alpha*F*(overpotential))/(R*self.T)))
     return (j0 * (
         numerix.exp(
             ((1 - self.alpha) * F * (overpotential)) / (R * self.T)
         )  # Returns a value for "j", flux density on the LHS of the equation
         - numerix.exp((-self.alpha * F * (overpotential)) / (R * self.T))))
Beispiel #4
0
 def __call__(self, x):
     """Evaluate the solver."""
     self.phi.value = 0.
     x_center = x[:2]
     tau = x[2]
     h = x[3]
     s = x[4]
     x, y = self.mesh.cellCenters
     self.source.value = 0.5 * s / (math.pi * h**2) * numerix.exp(-0.5 * (
         (x_center[0] - x)**2 + (x_center[1] - y)**2) / (2. * h**2))
     y_all = []
     t = 0.
     self._times = []
     next_time = 0
     while t < self.max_time:
         t += self.dt
         add = False
         if next_time < len(self.T) and t >= self.T[next_time]:
             t = self.T[next_time]
             next_time += 1
             add = True
         if t >= tau:
             self.source.value = 0.
         self.eq.solve(var=self.phi, dt=self.dt)
         if add:
             self._times.append(t)
             y_all.append([self.phi.value[i] for i in self.idx])
     y = np.hstack(y_all)
     y = y.reshape((self.T.shape[0], len(self.idx))).flatten(order='F')
     return y
Beispiel #5
0
 def __call__(self, x):
     """Evaluate the solver."""
     self.phi.value = 0.
     x_center = x[:2]
     tau = x[2]
     h = x[3]
     s = x[4]
     x, y = self.mesh.cellCenters
     self.source.value = 0.5 * s / (math.pi * h ** 2) * numerix.exp(-0.5 *
             ((x_center[0] - x) ** 2 + (x_center[1] - y) ** 2)
             / (2. * h ** 2))
     y_all = []
     t = 0.
     self._times = []
     next_time = 0
     while t < self.max_time:
         t += self.dt
         add = False
         if next_time < len(self.T) and t >= self.T[next_time]:
             t = self.T[next_time]
             next_time += 1
             add = True
         if t >= tau:
             self.source.value = 0.
         self.eq.solve(var=self.phi, dt=self.dt)
         if add:
             self._times.append(t)
             y_all.append([self.phi.value[i] for i in self.idx])
     y = np.hstack(y_all)
     y = y.reshape((self.T.shape[0], len(self.idx))).flatten(order='F')
     return y
Beispiel #6
0
 def define_non_uniform_comp_domain_rad(
     self, shells_per_particle, normalised_particle_radius
 ):  # Non-uniform radial domain, electrode particles
     self.nr = int(shells_per_particle)
     self.Rs_normalised = normalised_particle_radius
     self.dr = numerix.diff(
         numerix.log(1 - numerix.linspace(
             0, 1.0 - numerix.exp(self.Rs_normalised), self.nr + 1)))
     self.p2d_mesh = Grid2D(dx=self.dx,
                            dy=self.dr,
                            Lx=self.L_normalised,
                            Ly=self.Rs_normalised)
     self.dummy, self.radial_faces = self.p2d_mesh.faceCenters  # Create a shorthand name for accessing y-axis faces in the particle mesh
Beispiel #7
0
 def fluxes(self, ts):
     # wind-independent roughness as in doi:10.3189/2014JoG13J045
     Tsurf = ts.variables['T_right'][self.indexCell(ts)]
     # Tsurf = ts.variables['T'][self.indexCell]
     # sat; T in Celsius; in Pa
     VPsurf = 100 * 6.1094 * numerix.exp(
         (17.625 * Tsurf) / (Tsurf + 243.04))
     # T in Celsius
     flux_radiation = (self.Sin * (1 - self.bc_parameters['albedo']) +
                       self.bc_parameters['emissivity'] * self.Lin -
                       self.bc_parameters['emissivity'] * Stefan_Boltzmann *
                       (Tsurf + 273.15)**4)
     C = von_Karman**2 / (numerix.log(
         (self.meas_height - self.bc_parameters['d0']) /
         self.bc_parameters['z0m']) * numerix.log(
             (self.meas_height - self.bc_parameters['d0']) /
             self.bc_parameters['z0a']))
     flux_latent = (self.bc_parameters['beta'] * C * rho_air * Le * 0.622 *
                    self.wind * (self.VPair - VPsurf) / self.pressure)
     flux_sensible = C * rho_air * cp_air * self.wind * (self.Tair - Tsurf)
     return Fluxes(radiation=flux_radiation,
                   latent=flux_latent,
                   sensible=flux_sensible,
                   total=flux_radiation + flux_latent + flux_sensible)
Beispiel #8
0
def loopGaussianKernel(z, dz):
    n = z.shape[0]
    m = z.shape[0]
    kern = sp.lil_matrix((n, m), dtype=np.float64)
    # kern = numerix.zeros((n,m))
    # eps = 1e-10
    eps = dz**2
    digits = len(str(n - 1))
    delete = "\b" * (digits + 1)
    for i in range(n):
        #if i>0:
        # for j in range(m):
        # if j>0:
        #      kern[i, j] = numerix.exp((-(2*z[i] - z[j])**2)/(2*eps))
        kern[i] = numerix.exp((-(2 * z[i] - z)**2) / (2 * eps))
        # kern = kern + sp.coo_matrix((np.array([numerix.exp((-(2*z[i] - z[j])**2)/(2*eps))]), (np.array([i]), np.array([j]))), shape=(n, m))
        # kern.tocsc()
        #/numerix.sqrt(2*numerix.pi*eps)
        # print "{0}{1:{2}}".format(delete, i, digits),

        # level = int((np.float(i)/np.float(n))*100)
        # print "{0}%\r".format((np.float(i)/np.float(n)*100))
        # print "#"*(level+1),
    return kern / numerix.sqrt(2 * numerix.pi * eps)
Beispiel #9
0
def SigmaF2D(amp, x,y, Rs):
    #Test : plt.plot(r,10*numerix.exp(-r**2/(2*dz**2))/(numerix.sqrt(dz**2)*numerix.sqrt(2*numerix.pi)))
    return amp*numerix.exp(-(x**2 + y**2)/(2*Rs))/(numerix.sqrt(2*numerix.pi*Rs))
Beispiel #10
0
def gaussian(x, mu, sig):
    return numerix.exp(-numerix.power(x - mu, 2.) /
                       (2 * numerix.power(sig, 2.)))
Beispiel #11
0
def gaussianDivisionRate(z, mean, sigma):
    #Test : plt.plot(r,10*numerix.exp(-r**2/(2*dz))/numerix.sqrt(2*numerix.pi*2*dz))
    return numerix.exp(-(z - mean)**2 /
                       (2 * sigma**2)) / (sigma * numerix.sqrt(2 * numerix.pi))
Beispiel #12
0
def AxiSymetricGaussianImmuneResponse(r, Ra):
    #Test : plt.plot(r,10*numerix.exp(-r**2/(2*dz))/numerix.sqrt(2*numerix.pi*2*dz))
    return 22 * numerix.exp(-r**2 /
                            (2 * Ra)) / (numerix.sqrt(2 * numerix.pi * Ra))
Beispiel #13
0
def GaussianKernel2D(strength, x, y, Ra):
    return strength * numerix.exp(-(
        (x**2) + (y**2)) / (2 * Ra)) / (numerix.sqrt(2 * numerix.pi * Ra))
Beispiel #14
0
    def run(self,
            dt=.5e-7,
            dtMax=1e+20,
            dtMin=.5e-7,
            totalSteps=400,
            view=False,
            PRINT=False,
            sweeps=5,
            tol=1e-10,
            delta=150e-6,
            deltaRef=0.03,
            featureDepth=56e-6,
            i1=-40.,
            i0=40.,
            diffusionCupric=2.65e-10,
            appliedPotential=-0.25,
            faradaysConstant=9.6485e4,
            gasConstant=8.314,
            temperature=298.,
            alpha=0.4,
            charge=2,
            bulkCupric=1000.,
            bulkSuppressor=.02,
            diffusionSuppressor=9.2e-11,
            kappa=15.26,
            kPlus=150.,
            kMinus=2.45e7,
            omega=7.1e-6,
            gamma=2.5e-7,
            perimeterRatio=1. / 2.8e-6 * 0.093,
            areaRatio=0.093,
            capacitance=0.3,
            dt_mult=1e+10):

        r"""
        Run an individual simulation.

        :Parameters:
          - `dt`: time step size
          - `dtMax`: maximum time step size
          - `dtMin`: minimum time step size
          - `totalSteps`: total time steps
          - `view`: whether to view the simulation while running
          - `PRINT`: print convergence data
          - `sweeps`: number of sweeps at each time step
          - `tol`: tolerance to exit sweep loop
          - `delta`: boundary layer depth
          - `deltaRef`: distance to reference electrode
          - `featureDepth`: depth of the feature
          - `i1`: current density constant
          - `i0`: current density constant
          - `diffusionCupric`: cupric diffusion
          - `appliedPotential`: applied potential
          - `faradaysConstant`: Faraday's constant
          - `gasConstant`: gas constant
          - `temperature`: temperature
          - `alpha`: kinetic factor
          - `charge`: charge
          - `bulkCupric`: bulk cupric concentration
          - `bulkSuppressor`: bulk suppressor concentration
          - `diffusionSuppressor`: suppressor diffusion
          - `kappa`: conductivity
          - `kPlus`: suppressor adsorption factor
          - `kMinus`: suppressor incorporation factor
          - `omega`: copper molar volume
          - `gamma`: saturation suppressor coverage,
          - `perimeterRatio`: feature perimeter ratio
          - `areaRatio`: feature area ratio
          - `capacitance`: capacitance
        """

        Fbar = faradaysConstant / gasConstant / temperature
        self.parameters = locals().copy()
        del self.parameters['self']
        self.parameters['trenchWidth'] = 2 * 0.093 / perimeterRatio
        self.parameters['fieldWidth'] = 2 / perimeterRatio
        
        epsilon = 1e-30 

        L = delta + featureDepth
        N = 1000
        dx = L / N 
        mesh = fipy.Grid1D(nx=N, dx=dx) - [[featureDepth]]

        potential = fipy.CellVariable(mesh=mesh, hasOld=True, name=r'$\psi$')
        potential[:] = -appliedPotential

        cupric = fipy.CellVariable(mesh=mesh, hasOld=True, name=r'$c_{cu}$')
        cupric[:] = bulkCupric
        cupric.constrain(bulkCupric, mesh.facesRight)

        suppressor = fipy.CellVariable(mesh=mesh, hasOld=True, name=r'$c_{\theta}$')
        suppressor[:] = bulkSuppressor
        suppressor.constrain(bulkSuppressor, mesh.facesRight)

        theta = fipy.CellVariable(mesh=mesh, hasOld=True, name=r'$\theta$')

        I0 = (i0 + i1 * theta)
        baseCurrent = I0 * (numerix.exp(alpha * Fbar * potential) \
                                - numerix.exp(-(2 - alpha) * Fbar * potential))
        cbar =  cupric / bulkCupric
        current = cbar * baseCurrent
        currentDerivative = cbar * I0 * (alpha * Fbar *  numerix.exp(alpha * Fbar * potential) \
                                             + (2 - alpha) * Fbar * numerix.exp(-(2 - alpha) * Fbar * potential))

        def dirac(x):
            value = numerix.zeros(mesh.numberOfCells, 'd')
            ID = numerix.argmin(abs(mesh.x - x))
            if mesh.x[ID] < x:
                ID = ID + 1
            value[ID] = 1. / dx
            return value

        THETA = (mesh.x < 0) * perimeterRatio + dirac(0) * (1 - areaRatio) + dirac(-featureDepth) * areaRatio
        AREA = (mesh.x < 0) * (areaRatio - 1) + 1 
        THETA_UPPER = fipy.CellVariable(mesh=mesh)
        THETA_UPPER[-1] = kappa / dx / (deltaRef - delta)

        potentialEq = fipy.TransientTerm(capacitance * THETA) == fipy.DiffusionTerm(kappa * AREA) \
            - THETA * (current - potential * currentDerivative) \
            - fipy.ImplicitSourceTerm(THETA * currentDerivative) \
            - THETA_UPPER * appliedPotential - fipy.ImplicitSourceTerm(THETA_UPPER) 

        cupricEq = fipy.TransientTerm(AREA) == fipy.DiffusionTerm(diffusionCupric * AREA) \
            - fipy.ImplicitSourceTerm(baseCurrent * THETA / (bulkCupric * charge * faradaysConstant))

        suppressorEq = fipy.TransientTerm(AREA) == fipy.DiffusionTerm(diffusionSuppressor * AREA) \
            - fipy.ImplicitSourceTerm(gamma * kPlus * (1 - theta) * THETA)

        thetaEq =  fipy.TransientTerm(THETA + epsilon) == kPlus * suppressor * THETA \
            - fipy.ImplicitSourceTerm(THETA * (kPlus * suppressor + kMinus * current * (omega / charge / faradaysConstant)))

        t = 0.

        if view:
            potentialBar = -potential / appliedPotential
            potentialBar.name = r'$\bar{\eta}$'
            cbar.name = r'$\bar{c_{cu}}$'
            suppressorBar = suppressor / bulkSuppressor
            suppressorBar.name = r'$\bar{c_{\theta}}$'

            viewer = fipy.Viewer((theta, suppressorBar, cbar, potentialBar), datamax=1, datamin=0.0, xmin=-featureDepth)

            viewer.axes.legend([var.name for var in viewer.vars], loc='lower right', prop={'size':16})
            viewer.axes.tick_params(labelsize=14)
            viewer.axes.set_xticks((-50e-6, 0e-6, 50e-6, 100e-6, 150e-6))
            viewer.axes.set_xticklabels((-50, 0, 50, 100, 150))
            viewer.axes.set_xlabel(r'$x$ ($\mu$m)', fontsize=16)
            
        potentials = []
        for step in range(totalSteps):
            if view:
                viewer.axes.set_title(r'$t=%1.2e$ (s)' % t, fontsize=18)
                viewer.plot(filename='movie/movie%s.png' %  str(step).rjust(6, '0'))

            potential.updateOld()
            cupric.updateOld()
            suppressor.updateOld()
            theta.updateOld()

            for sweep in range(sweeps):
                potentialRes = potentialEq.sweep(potential, dt=dt)
                cupricRes = cupricEq.sweep(cupric, dt=dt)
                suppressorRes = suppressorEq.sweep(suppressor, dt=dt)
                thetaRes = thetaEq.sweep(theta, dt=dt)
                res = numpy.array((potentialRes, cupricRes, suppressorRes, thetaRes))
                if sweep == 0:
                    res0 = res
                else:
                    if ((res / res0) < tol).all():
                        break

                if PRINT:
                    print res / res0

            if sweep == sweeps - 1 and PRINT:
                print 'Did not reach sufficient tolerance'
                print 'kPlus',kPlus
                print 'kMinus',kMinus
                print 'res',res

            if PRINT:
                print 'theta',theta[0]
                print 'cBar_supp',suppressor[0] / bulkSuppressor
                print 'cBar_cu',cupric[0] / bulkCupric
                print 'potentialBar',-potential[0] / appliedPotential
                print 'dt',dt
                print 'step',step

            t += dt

            dt = dt * dt_mult
            dt = min((dt, dtMax))
            dt = max((dt, dtMin))
            potentials.append(-float(potential[0]))
        if view:
            viewer.plot()

        self.parameters['potential'] = numpy.array(potential)
        self.parameters['cupric'] = numpy.array(cupric)
        self.parameters['suppressor'] = numpy.array(suppressor)
        self.parameters['theta'] = numpy.array(theta)
        self.parameters['potentials'] = numpy.array(potentials)
Beispiel #15
0
def SigmaF1D(x, Rs):
    #Test : plt.plot(r,10*numerix.exp(-r**2/(2*dz**2))/(numerix.sqrt(dz**2)*numerix.sqrt(2*numerix.pi)))
    # return 0.00001*numerix.exp(-((x)**2)/(2*Rs))/(numerix.sqrt(2*numerix.pi*Rs))
    return 10.*numerix.exp(-((x)**2)/(2*Rs))/(numerix.sqrt(2*numerix.pi*Rs))
Beispiel #16
0
def GaussianKernel(strength, x, Ra):
    return strength * numerix.exp(-(x**2) / (2 * Ra)) / (numerix.sqrt(
        2 * numerix.pi * Ra))
Beispiel #17
0
def TwoSigmaF2D(x,y, Rs):
    #Test : plt.plot(r,10*numerix.exp(-r**2/(2*dz**2))/(numerix.sqrt(dz**2)*numerix.sqrt(2*numerix.pi)))
    return ((200e-3+0.)*numerix.exp(-((x+0.6)**2 + (y-0.3)**2)/(2*Rs))
            +(300e-3+0.)*numerix.exp(-((x-0.6)**2 + (y-0.2)**2)/(2*Rs)))/(numerix.sqrt(2*numerix.pi*Rs))
Beispiel #18
0
def AxiSymmetricSigmaF(r, Rs):
    #Test : plt.plot(r,10*numerix.exp(-r**2/(2*dz**2))/(numerix.sqrt(dz**2)*numerix.sqrt(2*numerix.pi)))
    return 10*numerix.exp(-((r)**2)/(2*Rs))/(numerix.sqrt(2*numerix.pi*Rs))
Beispiel #19
0
def GaussianImmuneResponse2D(strength, x, y, Ra):
    #Test : plt.plot(r,10*numerix.exp(-r**2/(2*dz))/numerix.sqrt(2*numerix.pi*2*dz))
    return strength * numerix.exp(-(
        (x**2) + (y**2)) / (2 * Ra)) / (numerix.sqrt(2 * numerix.pi * Ra))
Beispiel #20
0
def AxiSymmetricGaussianGammaF(r, Rs):
    #Test : plt.plot(r,10*numerix.exp(-r**2/(2*dz**2))/(numerix.sqrt(dz**2)*numerix.sqrt(2*numerix.pi)))
    return 0.03 * numerix.exp(-(r**2) /
                              (2 * Rs)) / (numerix.sqrt(2 * numerix.pi * Rs))
Beispiel #21
0
def gaussianGammaF(x, Rs):
    #Test : plt.plot(r,10*numerix.exp(-r**2/(2*dz**2))/(numerix.sqrt(dz**2)*numerix.sqrt(2*numerix.pi)))
    return 0.3 * numerix.exp(-(x**2) /
                             (2 * Rs)) / (numerix.sqrt(2 * numerix.pi * Rs))
Beispiel #22
0
def GaussianConversionRate(r, mean, Rp):
    #Test : plt.plot(r,10*numerix.exp(-r**2/(2*dz**2))/(numerix.sqrt(dz**2)*numerix.sqrt(2*numerix.pi)))
    return 0.3*numerix.exp(-(r-mean)**2/(2*Rp))/(numerix.sqrt(2*numerix.pi*Rp))
Beispiel #23
0
def GaussianConversionRate2D(amp, x,y, mean, Rp):
    #Test : plt.plot(r,10*numerix.exp(-r**2/(2*dz**2))/(numerix.sqrt(dz**2)*numerix.sqrt(2*numerix.pi)))
    return amp*numerix.exp(-((x-mean)**2 + (y-mean)**2)/(2*Rp))/(numerix.sqrt(2*numerix.pi*Rp))