Esempio n. 1
0
    def __init__(self,
                 X=None,
                 T=None,
                 time_steps=5,
                 max_time=0.4,
                 num_cells=25,
                 L=1.):
        """Initialize the objet.

        Keyword Arguments:
            X           ---     The sensor locations.
            T           ---     The sensor measurment times.
            time_steps  ---     How many timesteps do you want to measure.
            max_time    ---     The maximum solution time.
            num_cells   ---     The number of cells per dimension.
            L           ---     The size of the computational domain.
        """
        assert isinstance(num_cells, int)
        self._num_cells = num_cells
        assert isinstance(L, float) and L > 0.
        self._dx = L / self.num_cells
        self._mesh = Grid2D(dx=self.dx,
                            dy=self.dx,
                            nx=self.num_cells,
                            ny=self.num_cells)
        self._phi = CellVariable(name='solution variable', mesh=self.mesh)
        self._source = CellVariable(name='source term',
                                    mesh=self.mesh,
                                    hasOld=True)
        self._eqX = TransientTerm() == ExplicitDiffusionTerm(
            coeff=1.) + self.source
        self._eqI = TransientTerm() == DiffusionTerm(coeff=1.) + self.source
        self._eq = self._eqX + self._eqI
        assert isinstance(max_time, float) and max_time > 0.
        self._max_time = max_time
        #self.max_time / time_steps #.
        if X is None:
            idx = range(self.num_cells**2)
        else:
            idx = []
            x1, x2 = self.mesh.cellCenters
            for x in X:
                dist = (x1 - x[0])**2 + (x2 - x[1])**2
                idx.append(np.argmin(dist))
        self._idx = idx
        if T is None:
            T = np.linspace(0, self.max_time, time_steps)[1:]
        self._max_time = T[-1]
        self._T = T
        self._dt = self.T[0] / time_steps
        super(Diffusion, self).__init__(5,
                                        len(self.T) * len(self.idx),
                                        name='Diffusion Solver')
Esempio n. 2
0
 def _buildEq(self):
     """
     Build the equation to solve, we can change this method to impelement other
     schemes, e.g. Crank-Nicholson.
     """
     # The current scheme is an implicit-upwind
     if self.q > 0.0:
         self.vr = self.vrVisc + self.vrTid
         self.eq = TransientTerm(var=self.Sigma) == - ExplicitUpwindConvectionTerm(coeff=self.vr, var=self.Sigma)
     else:
         self.vr = self.vrVisc
         mask_coeff = (self.mesh.facesLeft * self.mesh.faceNormals).getDivergence()
         self.eq = TransientTerm(var=self.Sigma) == - ExplicitUpwindConvectionTerm(coeff=self.vr, var=self.Sigma)\
                                                    - mask_coeff*3.0/2*self.nu/self.mesh.x*self.Sigma.old
    def __solve_diffusion(self, model):
        oxygen_grid = model.environments[self.oxygen_env_name]
        nx = oxygen_grid.xsize
        ny = oxygen_grid.ysize
        nz = oxygen_grid.zsize

        dx = dy = dz = 1.0

        D = self.oxygen_diffusion_coeff

        mesh = Grid3D(dx=dx, dy=dy, nx=nx, ny=ny, dz=dz, nz=nz)

        phi = CellVariable(name="solutionvariable", mesh=mesh)
        phi.setValue(0.)

        start = time.time()
        for _ in range(self.diffusion_solve_iterations):
            source_grid, sink_grid = self.__get_source_sink_grids(phi, model)
            eq = TransientTerm() == DiffusionTerm(
                coeff=D) + source_grid - sink_grid

            eq.solve(var=phi, dt=1)
            eq = TransientTerm() == DiffusionTerm(coeff=D)

            eq.solve(var=phi, dt=self.dt)
        end = time.time()
        print("Solving oxygen diffusion took %s seconds" % str(end - start))

        return phi, nx, ny, nz
Esempio n. 4
0
class Diffusion:
    def __init__(self, x, y, z, patch_l, D, timeStepDuration, steps):
        # Domain
        self.nx = int(x / patch_l)
        self.ny = int(y / patch_l)
        self.nz = int(z / patch_l)

        self.patch_l = patch_l
        self.D = D  # mm2/hr
        self.timeStepDuration = timeStepDuration  # hr
        self.steps = steps  # number of steps

        self.mesh = PeriodicGrid3D(dx=self.patch_l,
                                   dy=self.patch_l,
                                   dz=self.patch_l,
                                   nx=self.nx,
                                   ny=self.ny,
                                   nz=self.nz)
        self.eq = TransientTerm() == DiffusionTerm(coeff=D)
        print("dx = {}, nx = {} zx {}".format(self.patch_l, self.nx, self.nz))

    def run(self, initialConditions, step_n):
        pinit = np.zeros(
            self.nx * self.ny *
            self.nz)  #TODO: how to map from the ABM domain to this form
        if initialConditions == None:
            for i in range(self.nx * self.ny * self.nz):
                pinit[i] = float(
                    decimal.Decimal(random.randrange(8, 50)) /
                    1000000)  #ng/mm3
        else:
            pass

        print("Initial values:")
        print(pinit)
        phi = CellVariable(name="Concentration (ng/ml)",
                           mesh=self.mesh,
                           value=pinit)
        t = Variable(0.)
        for step in range(step_n):
            print("Time = {}".format(t.value))
            self.eq.solve(var=phi, dt=self.timeStepDuration)
            t.setValue(t.value + self.timeStepDuration)
        return phi.value
Esempio n. 5
0
    def __init__(self, x, y, z, patch_l, D, timeStepDuration, steps):
        # Domain
        self.nx = int(x / patch_l)
        self.ny = int(y / patch_l)
        self.nz = int(z / patch_l)

        self.patch_l = patch_l
        self.D = D  # mm2/hr
        self.timeStepDuration = timeStepDuration  # hr
        self.steps = steps  # number of steps

        self.mesh = PeriodicGrid3D(dx=self.patch_l,
                                   dy=self.patch_l,
                                   dz=self.patch_l,
                                   nx=self.nx,
                                   ny=self.ny,
                                   nz=self.nz)
        self.eq = TransientTerm() == DiffusionTerm(coeff=D)
        print("dx = {}, nx = {} zx {}".format(self.patch_l, self.nx, self.nz))
Esempio n. 6
0
    def test_init(self, model):

        with pytest.raises(TypeError):
            eqn = ModelEquation()

        COEFF = 3
        eqn = ModelEquation(model, 'domain.abc', coeff=COEFF)
        assert eqn.varpath == 'domain.abc'
        assert eqn.term_transient == TransientTerm(var=eqn.var, coeff=COEFF)
        assert eqn.term_transient.coeff == COEFF
        assert eqn.term_diffusion is None
        assert eqn.sources_total is None
        assert not eqn.track_budget
Esempio n. 7
0
def solve_pde(
        xmin,  # domain min
        xmax,  # domain max
        Tmax,  # time max
        theta=1,  # dynamics drift
        mu=0,  # dynamics stable level
        sigma=1,  # dynamics noise
        dx=0.01,  # space discretization
        dt=0.01,  # time discretization
        gbm=False):  # state-dependent drift

    mesh = Grid1D(dx=dx, nx=(xmax - xmin) / dx) + xmin
    Tsteps = int(Tmax / dt) + 1

    x_face = mesh.faceCenters
    x_cell = mesh.cellCenters[0]
    V = CellVariable(name="V", mesh=mesh, value=0.)

    # PDE
    if gbm:
        eq = TransientTerm(
            var=V) == (DiffusionTerm(coeff=float(sigma) * sigma / 2, var=V) -
                       UpwindConvectionTerm(
                           coeff=float(theta) * (x_face - float(mu)), var=V) +
                       V * (float(theta) - x_cell))
    else:
        eq = TransientTerm(
            var=V) == (DiffusionTerm(coeff=float(sigma) * sigma / 2, var=V) -
                       UpwindConvectionTerm(coeff=float(theta) *
                                            (x_face - float(mu)),
                                            var=V) + V * float(theta))

    # Boundary conditions
    V.constrain(1., mesh.facesRight)
    V.faceGrad.constrain([0.], mesh.facesLeft)

    # Solve by stepping in time
    sol = np.zeros((Tsteps, mesh.nx))
    for step in range(Tsteps):
        eq.solve(var=V, dt=dt)
        sol[step] = V.value

    X = mesh.cellCenters.value[0]
    T = dt * np.arange(Tsteps)
    return T, X, sol
    def define_ode(self, current_time):

        x, y = self.mesh.faceCenters

        # Internal source specificatio - currently no functional
        internal_source_value = self.parameter.internal_source_value
        internal_source_region = self.parameter.internal_source_region

        internal_source_mask = (
            (x > internal_source_region.xmin) &
            (x < internal_source_region.xmax) &
            (y > internal_source_region.ymin) &
            (y < internal_source_region.ymax)
        )

        # Get convection data
        convection = self.define_convection_variable(current_time)

        eq = TransientTerm() == - ConvectionTerm(coeff=convection) \
            + DiffusionTerm(coeff=self.parameter.Diffusivity)\
            - ImplicitSourceTerm(coeff=self.parameter.Decay)\
            # + ImplicitSourceTerm(coeff=internal_source_value*internal_source_mask)  # Internal source not working

        return eq
#!/usr/bin/env python

from fipy import Grid1D, CellVariable, TransientTerm, DiffusionTerm, Viewer
#
m = Grid1D(nx=100, Lx=1.)
#
v0 = CellVariable(mesh=m, hasOld=True, value=0.5)
v1 = CellVariable(mesh=m, hasOld=True, value=0.5)
#
v0.constrain(0, m.facesLeft)
v0.constrain(1, m.facesRight)
#
v1.constrain(1, m.facesLeft)
v1.constrain(0, m.facesRight)
#
eq0 = TransientTerm() == DiffusionTerm(coeff=0.01) - v1.faceGrad.divergence
eq1 = TransientTerm() == v0.faceGrad.divergence + DiffusionTerm(coeff=0.01)
#
vi = Viewer((v0, v1))
#
for t in range(100): 
    v0.updateOld()
    v1.updateOld()
    res0 = res1 = 1e100
    while max(res0, res1) > 0.1:
        res0 = eq0.sweep(var=v0, dt=1e-5)
        res1 = eq1.sweep(var=v1, dt=1e-5)
    if t % 10 == 0:
        vi.plot()
Esempio n. 10
0
timeStepDuration = cfl * dx / abs(velocity)
steps = 1000

mesh = Grid1D(dx = dx, nx = nx)

startingArray = numerix.zeros(nx, 'd')
startingArray[50:90] = 1.

var = CellVariable(
    name = "advection variable",
    mesh = mesh,
    value = startingArray)

var.constrain(valueLeft, mesh.facesLeft)
var.constrain(valueRight, mesh.facesRight)

eq = TransientTerm() - PowerLawConvectionTerm(coeff = (velocity,))

if __name__ == '__main__':

    viewer = Viewer(vars=(var,))
    viewer.plot()
    raw_input("press key to continue")
    for step in range(steps):
        eq.solve(var,
                 dt = timeStepDuration,
                 solver = LinearLUSolver(tolerance = 1.e-15))
        viewer.plot()
    viewer.plot()
    raw_input('finished')
Esempio n. 11
0
shift = 1.

KMVar = CellVariable(mesh=mesh, value=params['KM'] * shift, hasOld=1)
KCVar = CellVariable(mesh=mesh, value=params['KC'] * shift, hasOld=1)
TMVar = CellVariable(mesh=mesh, value=params['TM'] * shift, hasOld=1)
TCVar = CellVariable(mesh=mesh, value=params['TC'] * shift, hasOld=1)
P3Var = CellVariable(mesh=mesh, value=params['P3'] * shift, hasOld=1)
P2Var = CellVariable(mesh=mesh, value=params['P2'] * shift, hasOld=1)
RVar = CellVariable(mesh=mesh, value=params['R'], hasOld=1)

PN = P3Var + P2Var

KMscCoeff = params['chiK'] * (RVar + 1) * (1 - KCVar - KMVar.cellVolumeAverage)
KMspCoeff = params['lambdaK'] / (1 + PN / params['kappaK'])
KMEq = TransientTerm() - KMscCoeff + ImplicitSourceTerm(KMspCoeff)

TMscCoeff = params['chiT'] * (1 - TCVar - TMVar.cellVolumeAverage)
TMspCoeff = params['lambdaT'] * (KMVar + params['zetaT'])
TMEq = TransientTerm() - TMscCoeff + ImplicitSourceTerm(TMspCoeff)

TCscCoeff = params['lambdaT'] * (TMVar * KMVar).cellVolumeAverage
TCspCoeff = params['lambdaTstar']
TCEq = TransientTerm() - TCscCoeff + ImplicitSourceTerm(TCspCoeff)

PIP2PITP = PN / (PN / params['kappam'] + PN.cellVolumeAverage /
                 params['kappac'] + 1) + params['zetaPITP']

P3spCoeff = params['lambda3'] * (TMVar + params['zeta3T'])
P3scCoeff = params['chi3'] * KMVar * (PIP2PITP /
                                      (1 + KMVar / params['kappa3']) +
Esempio n. 12
0
# d2gdx_a2 = grad(dgdx_a)
# print (dgdx_a(0.4))
if GIBBS == "FH":
    dgdx_a = ((1.0 / N_A) - (1.0 / N_B)) + (1.0 / N_A) * numerix.log(x_a) - (
        1.0 / N_B) * numerix.log(1.0 - x_a) + chi_AB * (1.0 - 2 * x_a)
    d2gdx_a2 = (1.0 / (N_A * x_a)) + (1.0 / (N_B * (1.0 - x_a))) - 2 * chi_AB
elif GIBBS != "FH":
    print("Implent more stuff you lazy f**k")

# Define the equations

# evaluating kappa
kappa = (2.0 / 3.0) * chi_AB

# eqn 1 is the 2nd order transport equation
eq1 = (TransientTerm(var=x_a)) == DiffusionTerm(coeff=x_a * (1 - x_a),
                                                var=mu_AB)

# Try constant mobility
eq0 = (TransientTerm(var=x_a)) == DiffusionTerm(coeff=1, var=mu_AB)

# eqn 2 is the chemical potential definition
eq2 = (ImplicitSourceTerm(coeff=1., var=mu_AB)) == ImplicitSourceTerm(
    coeff=d2gdx_a2, var=x_a) - d2gdx_a2 * x_a + dgdx_a - DiffusionTerm(
        coeff=kappa, var=x_a)

# write eq2 without the fipy trick:
eq3 = (ImplicitSourceTerm(
    coeff=1, var=mu_AB)) == dgdx_a - DiffusionTerm(coeff=kappa, var=x_a)

# Adding the equations together
Esempio n. 13
0
dx = L / nx
dy = L / ny

mesh = Grid2D(dx, dy, nx, ny)

phase = CellVariable(name = 'PhaseField', mesh = mesh, value = 1.)

theta = ModularVariable(name = 'Theta', mesh = mesh, value = 1.)
x, y = mesh.cellCenters
theta.setValue(0., where=(x - L / 2.)**2 + (y - L / 2.)**2 < (L / 4.)**2)

mPhiVar = phase - 0.5 + temperature * phase * (1 - phase)
thetaMag = theta.old.grad.mag
implicitSource = mPhiVar * (phase - (mPhiVar < 0))
implicitSource += (2 * s + epsilon**2 * thetaMag) * thetaMag

phaseEq = TransientTerm(phaseTransientCoeff) == \
          ExplicitDiffusionTerm(alpha**2) \
          - ImplicitSourceTerm(implicitSource) \
          + (mPhiVar > 0) * mPhiVar * phase

if __name__ == '__main__':

    phaseViewer = Viewer(vars = phase)
    phaseViewer.plot()
    for step in range(steps):
        phaseEq.solve(phase, dt = timeStepDuration)
        phaseViewer.plot()
    input('finished')
Esempio n. 14
0
#EQUATION SETUP BASIC DESCRIPTION
'''Equations to solve for each varible must be defined:
  -TransientTerm = dvar/dt
  -ConvectionTerm = dvar/dx
  -DiffusionTerm = d^2var/dx^2
  -Source terms can be described as they would appear mathematically
Notes:  coeff = terms that are multiplied by the Term.. must be rank-1 FaceVariable for ConvectionTerm
        "var" must be defined for each Term if they are not all the variable being solved for,
        otherwise will see "fipy.terms.ExplicitVariableError: Terms with explicit Variables cannot mix with Terms with implicit Variables." '''

#In English:  dPion/dt = -1/q * divergence.Jp(x,t) - k_rec * Nion(x,t) * Pion(x,t) where
#             Jp = q * mu_p * E(x,t) * Pion(x,t) - q * Dp * grad.Pion(x,t)         and     E(x,t) = -grad.potential(x,t)
# Continuity Equation

Pion.equation = TransientTerm(
    coeff=1,
    var=Pion) == mu_p * (ConvectionTerm(coeff=potential.faceGrad, var=Pion) +
                         Pion * potential.faceGrad.divergence) + DiffusionTerm(
                             coeff=Dp, var=Pion) - k_rec * Pion * Nion

#In English:  dNion/dt = 1/q * divergence.Jn(x,t) - k_rec * Nion(x,t) * Pion(x,t)   where
#             Jn = q * mu_n * E(x,t) * Nion(x,t) - q * Dn * grad.Nion(x,t)         and     E(x,t) = -grad.potential(x,t)
# Continuity Equation

Nion.equation = TransientTerm(
    coeff=1, var=Nion
) == -mu_n * (ConvectionTerm(coeff=potential.faceGrad, var=Nion) +
              Nion * potential.faceGrad.divergence) + DiffusionTerm(
                  coeff=Dn, var=Nion) - k_rec * Pion * Nion

#In English:  d^2potential/dx^2 = -q/epsilon * Charge_Density      and     Charge Density = Pion + Nion
#ref: https://github.com/usnistgov/fipy/blob/develop/documentation/USAGE.rst#applying-robin-boundary-conditions
#warning: avoid confusion between convectionCoeff in that fipy documentation, which refers to terms involving "a", and convectionCoeff here, which refers to a heat transfer convection coefficient at a boundary
Gamma0 = D_thermal
Gamma = FaceVariable(mesh=mesh, value=Gamma0)
mask = surfaceFaces
Gamma.setValue(0., where=mask)
dPf = FaceVariable(mesh=mesh,
                   value=mesh._faceToCellDistanceRatio *
                   mesh.cellDistanceVectors)
Af = FaceVariable(mesh=mesh, value=mesh._faceAreas)
#RobinCoeff = (mask * Gamma0 * Af / (dPf.dot(a) + b)).divergence  #a is zero in our case
b = 1.
RobinCoeff = (mask * Gamma0 * Af / b).divergence  #a is zero in our case
#eq = (TransientTerm() == DiffusionTerm(coeff=Gamma) + RobinCoeff * g - ImplicitSourceTerm(coeff=RobinCoeff * mesh.faceNormals.dot(a)))   #a is zero in our case
# g in this formulation is -convectionCoeff/k*var, where var=T-T_infinity
eq = (TransientTerm() == DiffusionTerm(coeff=Gamma) +
      ImplicitSourceTerm(RobinCoeff * -convectionCoeff / k))

# embed()
# sys.exit()

#either show the fipy viewer or make a T(s,t) plot; doing both at once is too much of a hassle to debug
showViewer = False  #SETTING
if showViewer:
    #viewer=Viewer(vars=var,datamin=T_infinity,datamax=T_initial)
    viewer = Viewer(vars=var)

    viewer.plot()

dt_explicit = cellSize**2 / 2. / D_thermal
Esempio n. 16
0
mesh = Grid2D(dx=dx, dy=dx, nx=nx, ny=ny)

x0 = (L - boxSize) / 2
x1 = (L + boxSize) / 2

distanceVariable = DistanceVariable(mesh=mesh, value=1., hasOld=1)

x, y = mesh.cellCenters
distanceVariable.setValue(-1,
                          where=((x0 < x) & (x < x1)) & ((x0 < y) & (y < x1)))

surfactantVariable = SurfactantVariable(distanceVar=distanceVariable, value=1.)

from fipy.variables.surfactantConvectionVariable import SurfactantConvectionVariable
surfactantEquation = TransientTerm() - \
    ExplicitUpwindConvectionTerm(SurfactantConvectionVariable(distanceVariable))

advectionEquation = TransientTerm() + AdvectionTerm(velocity)

if __name__ == '__main__':
    distanceViewer = Viewer(vars=distanceVariable, datamin=-.001, datamax=.001)
    surfactantViewer = Viewer(vars=surfactantVariable, datamin=0., datamax=2.)

    distanceVariable.calcDistanceFunction()

    for step in range(steps):
        print numerix.sum(surfactantVariable)
        distanceVariable.updateOld()
        surfactantEquation.solve(surfactantVariable, dt=1)
        advectionEquation.solve(distanceVariable, dt=timeStepDuration)
Esempio n. 17
0
dx = L / nx
m = Grid1D(nx=nx, dx=dx) + X0
x, = m.cellCenters

q = CellVariable(mesh=m, rank=1, elementshape=(2, ))

q[0, :] = numerix.exp(-50 * (x - 0.3)**2) * numerix.cos(20 * (x - 0.3))
q[0, x > 0.3] = 0.

Ax = FaceVariable(mesh=m,
                  rank=3,
                  value=[((0, K), (1 / rho, 0))],
                  elementshape=(1, 2, 2))

eqn = TransientTerm() + CentralDifferenceConvectionTerm(Ax) == 0

if __name__ == '__main__':
    from fipy import MatplotlibViewer as Viewer
    vi = Viewer((q[0], q[1]))
    vi.plot()

for step in range(500):
    eqn.solve(q, dt=cfl * dx)
    if step % 10 == 0 and __name__ == '__main__':
        vi.plot()

if __name__ == '__main__':
    import fipy.tests.doctestPlus
    exec(fipy.tests.doctestPlus._getScript())
Esempio n. 18
0
def runSimpleTrenchSystem(faradaysConstant=9.6e4,
                          gasConstant=8.314,
                          transferCoefficient=0.5,
                          rateConstant0=1.76,
                          rateConstant3=-245e-6,
                          catalystDiffusion=1e-9,
                          siteDensity=9.8e-6,
                          molarVolume=7.1e-6,
                          charge=2,
                          metalDiffusion=5.6e-10,
                          temperature=298.,
                          overpotential=-0.3,
                          metalConcentration=250.,
                          catalystConcentration=5e-3,
                          catalystCoverage=0.,
                          currentDensity0=0.26,
                          currentDensity1=45.,
                          cellSize=0.1e-7,
                          trenchDepth=0.5e-6,
                          aspectRatio=2.,
                          trenchSpacing=0.6e-6,
                          boundaryLayerDepth=0.3e-6,
                          numberOfSteps=5,
                          displayViewers=True):

    cflNumber = 0.2
    numberOfCellsInNarrowBand = 10
    cellsBelowTrench = 10

    yCells = cellsBelowTrench \
             + int((trenchDepth + boundaryLayerDepth) / cellSize)

    xCells = int(trenchSpacing / 2 / cellSize)

    from fipy.tools import serialComm
    mesh = Grid2D(dx = cellSize,
                  dy = cellSize,
                  nx = xCells,
                  ny = yCells,
                  communicator=serialComm)

    narrowBandWidth = numberOfCellsInNarrowBand * cellSize

    distanceVar = DistanceVariable(
        name = 'distance variable',
        mesh = mesh,
        value = -1.,
        hasOld = 1)

    bottomHeight = cellsBelowTrench * cellSize
    trenchHeight = bottomHeight + trenchDepth
    trenchWidth = trenchDepth / aspectRatio
    sideWidth = (trenchSpacing - trenchWidth) / 2

    x, y = mesh.cellCenters
    distanceVar.setValue(1., where=(y > trenchHeight) | ((y > bottomHeight) & (x < xCells * cellSize - sideWidth)))

    distanceVar.calcDistanceFunction(order=2)

    catalystVar = SurfactantVariable(
        name = "catalyst variable",
        value = catalystCoverage,
        distanceVar = distanceVar)

    bulkCatalystVar = CellVariable(
        name = 'bulk catalyst variable',
        mesh = mesh,
        value = catalystConcentration)

    metalVar = CellVariable(
        name = 'metal variable',
        mesh = mesh,
        value = metalConcentration)

    expoConstant = -transferCoefficient * faradaysConstant / (gasConstant * temperature)

    tmp = currentDensity1 * catalystVar.interfaceVar

    exchangeCurrentDensity = currentDensity0 + tmp

    expo = numerix.exp(expoConstant * overpotential)
    currentDensity = expo * exchangeCurrentDensity * metalVar / metalConcentration

    depositionRateVariable = currentDensity * molarVolume / (charge * faradaysConstant)

    extensionVelocityVariable = CellVariable(
        name = 'extension velocity',
        mesh = mesh,
        value = depositionRateVariable)

    surfactantEquation = AdsorbingSurfactantEquation(
        surfactantVar = catalystVar,
        distanceVar = distanceVar,
        bulkVar = bulkCatalystVar,
        rateConstant = rateConstant0 + rateConstant3 * overpotential**3)

    advectionEquation = TransientTerm() + AdvectionTerm(extensionVelocityVariable)

    metalEquation = buildMetalIonDiffusionEquation(
        ionVar = metalVar,
        distanceVar = distanceVar,
        depositionRate = depositionRateVariable,
        diffusionCoeff = metalDiffusion,
        metalIonMolarVolume = molarVolume,
    )

    metalVar.constrain(metalConcentration, mesh.facesTop)

    from .surfactantBulkDiffusionEquation import buildSurfactantBulkDiffusionEquation
    bulkCatalystEquation = buildSurfactantBulkDiffusionEquation(
        bulkVar = bulkCatalystVar,
        distanceVar = distanceVar,
        surfactantVar = catalystVar,
        diffusionCoeff = catalystDiffusion,
        rateConstant = rateConstant0 * siteDensity
    )

    bulkCatalystVar.constrain(catalystConcentration, mesh.facesTop)

    if displayViewers:
        try:
            from .mayaviSurfactantViewer import MayaviSurfactantViewer
            viewer = MayaviSurfactantViewer(distanceVar, catalystVar.interfaceVar, zoomFactor = 1e6, datamax=0.5, datamin=0.0, smooth = 1, title = 'catalyst coverage')
        except:
            viewer = MultiViewer(viewers=(
                Viewer(distanceVar, datamin=-1e-9, datamax=1e-9),
                Viewer(catalystVar.interfaceVar)))
    else:
        viewer = None

    levelSetUpdateFrequency = int(0.8 * narrowBandWidth \
                                  / (cellSize * cflNumber * 2))

    for step in range(numberOfSteps):

        if step>5 and step % 5 == 0 and viewer is not None:
            viewer.plot()

        if step % levelSetUpdateFrequency == 0:
            distanceVar.calcDistanceFunction(order=2)

        extensionVelocityVariable.setValue(depositionRateVariable())

        distanceVar.updateOld()

        distanceVar.extendVariable(extensionVelocityVariable, order=2)
        dt = cflNumber * cellSize / extensionVelocityVariable.max()

        advectionEquation.solve(distanceVar, dt = dt)
        surfactantEquation.solve(catalystVar, dt = dt)
        metalEquation.solve(metalVar, dt = dt)
        bulkCatalystEquation.solve(bulkCatalystVar, dt = dt, solver=GeneralSolver(tolerance=1e-15, iterations=2000))


    try:
        import os
        filepath = os.path.splitext(__file__)[0] + '.gz'
        print(catalystVar.allclose(numerix.loadtxt(filepath), rtol = 1e-4))
    except:
        return 0
Esempio n. 19
0
    value = 1.,
    hasOld = 1
    )

x, y = mesh.cellCenters
cellRadius = numerix.sqrt((x - L / 2.)**2 + (y - L / 2.)**2)
distanceVariable.setValue(cellRadius - initialRadius)

initialSurfactantValue =  1.

surfactantVariable = SurfactantVariable(
    value = initialSurfactantValue,
    distanceVar = distanceVariable
    )

advectionEquation = TransientTerm() + AdvectionTerm(velocity)

from fipy.variables.surfactantConvectionVariable import SurfactantConvectionVariable
surfactantEquation = TransientTerm() - \
    ExplicitUpwindConvectionTerm(SurfactantConvectionVariable(distanceVariable))

if __name__ == '__main__':

    distanceViewer = Viewer(vars=distanceVariable,
                            datamin=-initialRadius, datamax=initialRadius)
    surfactantViewer = Viewer(vars=surfactantVariable, datamin=-1., datamax=100.)
    distanceViewer.plot()
    surfactantViewer.plot()

    print('total surfactant before:', numerix.sum(surfactantVariable * mesh.cellVolumes))
Esempio n. 20
0
class Circumbinary(object):
    def __init__(self, rmax=1.0e4, ncell=300, dt=1.0e-6, delta=1.0e-100,
                 fudge=1.0e-3, q=1.0, gamma=100, mdisk=0.1, odir='output',
                 bellLin=True, emptydt=0.001, **kargs):
        self.rmax = rmax
        self.ncell = ncell
        self.dt = dt
        self.delta = delta
        self.mDisk = mdisk
        Omega0 = (G*M/(gamma*a)**3)**0.5
        nu0 = alpha*cs**2/Omega0
        self.chi = 2*fudge*q**2*np.sqrt(G*M)/nu0/a*(gamma*a)**1.5
        self.T0 = mu*Omega0/alpha/k*nu0
        self.gamma = gamma
        self.fudge = fudge
        self.q = q
        self.nu0 = nu0
        self.t = 0.0
        self.odir = odir
        self.bellLin = bellLin
        self.emptydt = emptydt
        self._genGrid()
        self.r = self.mesh.cellCenters.value[0]
        self.rF = self.mesh.faceCenters.value[0]
        if self.q > 0.0:
            self.gap = np.where(self.rF < 1.7/gamma)
        else:
            self.gap = np.where(self.rF < 1.0/gamma)
        self._genSigma()
        self._genTorque()
        self._genT(bellLin=self.bellLin, **kargs)
        self._genVr()
        self._buildEq()

    def _genGrid(self, inB=1.0):
        """Generate a logarithmically spaced grid"""
        logFaces = np.linspace(-np.log(self.gamma/inB), np.log(self.rmax), num=self.ncell+1)
        logFacesLeft = logFaces[:-1]
        logFacesRight = logFaces[1:]
        dr = tuple(np.exp(logFacesRight) - np.exp(logFacesLeft))
        self.mesh = CylindricalGrid1D(dr=dr, origin=(inB/self.gamma,))

    def _genSigma(self, width=0.1):
        """Create dependent variable Sigma"""
        # Gaussian initial condition
        value = self.mDisk*M/np.sqrt(2*np.pi)/(self.gamma*a*width)*\
                np.exp(-0.5*np.square(self.r-1.0)/width**2)/(2*np.pi*self.gamma*self.r*a)
        # Make it dimensionless
        value /= self.mDisk*M/(self.gamma*a)**2
        idxs = np.where(self.r < 0.1)
        value[idxs] = 0.0
        value = tuple(value)

        # Create the dependent variable and set the boundary conditions
        # to zero
        self.Sigma = CellVariable(name='Surface density',
                                 mesh=self.mesh, hasOld=True, value=value)
        #self.Sigma.constrain(0, self.mesh.facesLeft)
        #self.Sigma.constrain(0, self.mesh.facesRight)

    def _genTorque(self):
        """Generate Torque"""
        self.Lambda = FaceVariable(name='Torque at cell faces', mesh=self.mesh, rank=1)
        self.LambdaCell = CellVariable(name='Torque at cell centers', mesh=self.mesh)
        LambdaArr = np.zeros(self.rF.shape)
        LambdaArr[1:] = self.chi*np.power(1.0/(self.rF[1:]*self.gamma-1.0), 4)
        #LambdaArr[self.gap] = 0.0; LambdaArr[self.gap] = LambdaArr.max()
        self.Lambda.setValue(LambdaArr)
        self.LambdaCell.setValue(self.chi*np.power(1.0/(self.r*self.gamma-1.0), 4))
        self.LambdaCell[np.where(self.LambdaCell > LambdaArr.max())] = LambdaArr.max()

    def _interpT(self):
        """
        Get an initial guess for T using an interpolation of the solutions for T
        in the various thermodynamic limits.
        """
        Lambda = self.Lambda/self.chi*self.fudge*self.q**2*G*M/a
        LambdaCell = self.LambdaCell/self.chi*self.fudge*self.q**2*G*M/a
        Sigma = self.Sigma*M/(self.gamma*a)**2
        r = self.r*a*self.gamma #In physical units (cgs)
        self.Omega = np.sqrt(G*M/r**3)
        self.TvThin = np.power(9.0/4*alpha*k/sigma/mu/kappa0*self.Omega, 1.0/(3.0+beta))
        self.TtiThin = np.power(1/sigma/kappa0*(OmegaIn-self.Omega)*LambdaCell, 1.0/(4.0+beta))
        self.Ti = np.power(np.square(eta/7*L/4/np.pi/sigma)*k/mu/G/M*r**(-3), 1.0/7)
        self.TvThick = np.power(27.0/64*kappa0*alpha*k/sigma/mu*self.Omega*Sigma**2, 1.0/(3.0-beta))
        self.TtiThick = np.power(3*kappa0/16/sigma*Sigma**2*(OmegaIn-self.Omega)*LambdaCell, 1.0/(4.0-beta))
        #return np.power(self.TvThin**4 + self.TvThick**4 + self.TtiThin**4 + self.TtiThick**4 + self.Ti**4, 1.0/4)/self.T0
        return np.power(self.TvThin**4 + self.TvThick**4 + self.Ti**4, 1.0/4)/self.T0

    def _genT(self, bellLin=True, **kargs):
        """Create a cell variable for temperature"""
        if bellLin:
            @pickle_results(os.path.join(self.odir, "interpolator.pkl"))
            def buildInterpolator(r, gamma, q, fudge, mDisk, **kargs):
                # Keep in mind that buildTemopTable() returns the log10's of the values
                rGrid, SigmaGrid, temp = thermopy.buildTempTable(r*a*gamma, q=q, f=fudge, **kargs)
                # Go back to dimensionless units
                rGrid -= np.log10(a*gamma)
                SigmaGrid -= np.log10(mDisk*M/gamma**2/a**2)
                # Get the range of values for Sigma in the table
                rangeSigma = (np.power(10.0, SigmaGrid.min()), np.power(10.0, SigmaGrid.max()))
                # Interpolate in the log of dimensionless units
                return rangeSigma, RectBivariateSpline(rGrid, SigmaGrid, temp)
            # Pass the radial grid in phsyical units
            # Get back interpolator in logarithmic space
            rangeSigma, log10Interp = buildInterpolator(self.r, self.gamma, self.q, self.fudge, self.mDisk, **kargs)
            rGrid = np.log10(self.r)
            SigmaMin = np.ones(rGrid.shape)*rangeSigma[0]
            SigmaMax = np.ones(rGrid.shape)*rangeSigma[1]
            r = self.r*a*self.gamma #In physical units (cgs)
            self.Omega = np.sqrt(G*M/r**3)
            Ti = np.power(np.square(eta/7*L/4/np.pi/sigma)*k/mu/G/M*r**(-3), 1.0/7)
            T = np.zeros(Ti.shape)
            # Define wrapper function that uses the interpolator and stores the results
            # in an array given as a second argument. It can handle zero or negative
            # Sigma values.
            def func(Sigma):
                good = np.logical_and(Sigma > rangeSigma[0], Sigma < rangeSigma[1])
                badMin = np.logical_and(True, Sigma < rangeSigma[0])
                badMax = np.logical_and(True, Sigma > rangeSigma[1])
                if np.sum(good) > 0:
                    T[good] = np.power(10.0, log10Interp.ev(rGrid[good], np.log10(Sigma[good])))
                if np.sum(badMin) > 0:
                    T[badMin] = np.power(10.0, log10Interp.ev(rGrid[badMin], np.log10(SigmaMin[badMin])))
                if np.sum(badMax) > 0:
                    raise ValueError("Extrapolation to large values of Sigma is not allowed, build a table with a larger Sigmax")
                    T[badMax] = np.power(10.0, log10Interp.ev(rGrid[badMax], np.log10(SigmaMax[badMax])))
                return T
            # Store interpolator as an instance method
            self._bellLinT = func
            # Save the temperature as an operator variable
            self.T = self.Sigma._UnaryOperatorVariable(lambda x: self._bellLinT(x))

        # Initialize T with the interpolation of the various thermodynamic limits
        else:
            self.T = self._interpT()

    def _genVr(self):
        """Generate the face variable that stores the velocity values"""
        r = self.r #In dimensionless units (cgs)
        # viscosity at cell centers in cgs
        self.nu = alpha*k/mu/self.Omega/self.nu0*self.T
        self.visc = r**0.5*self.nu*self.Sigma
        #self.visc.grad.constrain([self.visc/2/self.r[0]], self.mesh.facesLeft)
        #self.Sigma.constrain(self.visc.grad/self.nu*2*self.r**0.5, where=self.mesh.facesLeft)
        # I add the delta to avoid divisions by zero
        self.vrVisc = -3/self.rF**(0.5)/(self.Sigma.faceValue + self.delta)*self.visc.faceGrad
        if self.q > 0.0:
            self.vrTid = self.Lambda*np.sqrt(self.rF)

    def _buildEq(self):
        """
        Build the equation to solve, we can change this method to impelement other
        schemes, e.g. Crank-Nicholson.
        """
        # The current scheme is an implicit-upwind
        if self.q > 0.0:
            self.vr = self.vrVisc + self.vrTid
            self.eq = TransientTerm(var=self.Sigma) == - ExplicitUpwindConvectionTerm(coeff=self.vr, var=self.Sigma)
        else:
            self.vr = self.vrVisc
            mask_coeff = (self.mesh.facesLeft * self.mesh.faceNormals).getDivergence()
            self.eq = TransientTerm(var=self.Sigma) == - ExplicitUpwindConvectionTerm(coeff=self.vr, var=self.Sigma)\
                                                       - mask_coeff*3.0/2*self.nu/self.mesh.x*self.Sigma.old

    def dimensionalSigma(self):
        """
        Return Sigma in dimensional form (cgs)
        """
        return self.Sigma.value*self.mDisk*M/(self.gamma*a)**2

    def dimensionalFJ(self):
        """
        Return the viscous torque in dimensional units (cgs)
        """
        return 3*np.pi*self.nu.value*self.nu0*self.dimensionalSigma()*np.sqrt(G*M*self.r*a*self.gamma)

    def dimensionalTime(self, t=None, mode='yr'):
        """
        Return current time in dimensional units (years or seconds)
        """
        if t == None:
            t = self.t
        if mode == 'yr' or mode == 'years' or mode == 'year':
            return t*(a*self.gamma)**2/self.nu0/(365*24*60*60)
        else:
            return t*(a*self.gamma)**2/self.nu0

    def dimensionlessTime(self, t, mode='yr'):
        """
        Returns the dimensionless value of the time given as an argument
        """
        if mode == 'yr' or mode == 'years' or mode == 'year':
            return t/(a*self.gamma)**2*self.nu0*(365*24*60*60)
        else:
            return t/(a*self.gamma)**2*self.nu0

    def singleTimestep(self, dtMax=0.001, dt=None, update=True, emptyDt=False):
        """
        Evolve the system for a single timestep of size `dt`
        """
        if dt:
            self.dt = dt
        if emptyDt:
            vr = self.vr.value[0]
            if self.q == 0.0:
                vr[0] = -3.0/2*self.nu.faceValue.value[0]/self.rF[0]
            #vr[np.where(self.Sigma.value)] = self.delta
            self.flux = self.rF[1:]*vr[1:]-self.rF[:-1]*vr[:-1]
            self.flux = np.maximum(self.flux, self.delta)
            self.dts = self.mesh.cellVolumes/(self.flux)
            self.dts[np.where(self.Sigma.value == 0.0)] = np.inf
            self.dts[self.gap] = np.inf
            self.dt = self.emptydt*np.amin(self.dts)
        self.dt = min(dtMax, self.dt)
        try:
            self.eq.sweep(dt=self.dt)
            if np.any(self.Sigma.value < 0.0):
                self.singleTimestep(dt=self.dt/2)
            if update:
                self.Sigma.updateOld()
            self.t += self.dt
        except FloatingPointError:
            import ipdb; ipdb.set_trace()

    def evolve(self, deltaTime, **kargs):
        """
        Evolve the system using the singleTimestep method
        """
        tEv = self.t + deltaTime
        while self.t < tEv:
            dtMax = tEv - self.t
            self.singleTimestep(dtMax=dtMax, **kargs)

    def revert(self):
        """
        Revert evolve method if update=False was used, otherwise
        it has no effect.
        """
        self.Sigma.setValue(self.Sigma.old.value)

    def writeToFile(self):
        fName = self.odir + '/t{0}.pkl'.format(self.t)
        with open(fName, 'wb') as f:
            pickle.dump((self.t, self.Sigma.getValue()), f)

    def readFromFile(self, fName):
        with open(fName, 'rb') as f:
            t, Sigma = pickle.load(f)
        self.t = t
        self.Sigma.setValue(Sigma)

    def loadTimesList(self):
        path = self.odir
        files = os.listdir(path)
        if '.DS_Store' in files:
            files.remove('.DS_Store')
        if 'interpolator.pkl' in files:
            files.remove('interpolator.pkl')
        if 'init.pkl' in files:
            files.remove('init.pkl')
        self.times = np.zeros((len(files),))
        for i, f in enumerate(files):
            match = re.match(r"^t((\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?)\.pkl", f)
            if match == None:
                print "WARNING: File {0} has an unexepected name".format(f)
                files.remove(f)
                continue
            self.times[i] = float(match.group(1))
        self.times.sort()
        self.files = files

    def loadTime(self, t):
        """
        Load the file with the time closest to `t`
        """
        idx = (np.abs(self.times-t)).argmin()
        fName = self.odir + '/t'+str(self.times[idx]) + '.pkl'
        self.readFromFile(fName)
Esempio n. 21
0
cfl = 0.1
K = 4.
rho = 1.

dx = L / nx
m = Grid1D(nx=nx, dx=dx) + X0
x, = m.cellCenters

q = CellVariable(mesh=m, rank=1, elementshape=(2,))

q[0,:] = numerix.exp(-50 * (x - 0.3)**2) * numerix.cos(20 * (x - 0.3))
q[0, x > 0.3] = 0.

Ax = FaceVariable(mesh=m, rank=3, value=[((0, K), (1 / rho, 0))], elementshape=(1, 2, 2))

eqn = TransientTerm() + CentralDifferenceConvectionTerm(Ax) == 0

if  __name__ == '__main__':
    from fipy import MatplotlibViewer as Viewer
    vi = Viewer((q[0], q[1]))
    vi.plot()

for step in range(500):
    eqn.solve(q, dt=cfl * dx)
    if step % 10 ==  0 and  __name__ == '__main__':
        vi.plot()

if __name__ == '__main__':
    import fipy.tests.doctestPlus
    exec(fipy.tests.doctestPlus._getScript())
Esempio n. 22
0
timeStepDuration = cfl * dx / abs(velocity)
steps = 1000

mesh = Grid1D(dx = dx, nx = nx)

startingArray = numerix.zeros(nx, 'd')
startingArray[50:90] = 1.

var = CellVariable(
    name = "advection variable",
    mesh = mesh,
    value = startingArray)

var.constrain(valueLeft, mesh.facesLeft)
var.constrain(valueRight, mesh.facesRight)

eq = TransientTerm() - PowerLawConvectionTerm(coeff = (velocity,))

if __name__ == '__main__':

    viewer = Viewer(vars=(var,))
    viewer.plot()
    input("press key to continue")
    for step in range(steps):
        eq.solve(var,
                 dt = timeStepDuration,
                 solver = LinearLUSolver(tolerance = 1.e-15))
        viewer.plot()
    viewer.plot()
    input('finished')
Esempio n. 23
0
filename = 'infiniteCylinder01.msh'
mesh = Gmsh2D(filename, communicator=serialComm)
del filename

T_initial = 425.08  #deg K

var = CellVariable(mesh=mesh, value=T_initial)

rho = 6980.  #kg/m^3
cp = 227.  #J/kg/K
k = 59.6  #W/m/K
D_thermal = k / rho / cp

D = FaceVariable(mesh=mesh, value=D_thermal)

eq = TransientTerm() == DiffusionTerm(coeff=D)

X_faces, Y_faces = mesh.faceCenters

surfaceFaces = (Y_faces > 0) & (
    (X_faces**2 + Y_faces**2)**.5 > R_outer - cellSize / 10.)

#convectionCoeff=200.  #W/m^2/K
Bi_desired = 10.
convectionCoeff = Bi_desired * k / R_inner
logging.info('convection coefficient is %.2E' % convectionCoeff)

Bi = convectionCoeff * R_inner / k  #Biot number
logging.info('Biot number is %.2E' % Bi)

T_infinity = 293.15  #deg K
Esempio n. 24
0
phi[:] = noise

D = a = epsilon = 1.
# kappa = log(phi)
N_A = 400
N_B = 400
chi_AB = 0.0075
kappa = chi_AB / 6.0
# dfdphi = a**2 * phi * (1 - phi) * (1 - 2 * phi)
# dfdphi_ = a**2 * (1 - phi) * (1 - 2 * phi)
# d2fdphi2 = a**2 * (1 - 6 * phi * (1 - phi))

dfdphi = ((1.0 / N_A) - (1.0 / N_B)) + (1.0 / N_A) * numerix.log(phi) - (
    1.0 / N_B) * numerix.log(1.0 - phi) + chi_AB * (1.0 - 2 * phi)
d2fdphi2 = (1.0 / (N_A * phi)) + (1.0 / (N_B * (1.0 - phi))) - 2 * chi_AB
eq1 = (TransientTerm(var=phi) == DiffusionTerm(coeff=D, var=psi))
eq2 = (ImplicitSourceTerm(
    coeff=1., var=psi) == ImplicitSourceTerm(coeff=d2fdphi2, var=phi) -
       d2fdphi2 * phi + dfdphi - DiffusionTerm(coeff=kappa, var=phi))

eq = eq1 & eq2

elapsed = 0.
dt = 1.0
if __name__ == "__main__":
    duration = 1000.

solver = LinearLUSolver(tolerance=1e-9, iterations=500)

while elapsed < duration:
    elapsed += dt
Esempio n. 25
0
def runSimpleTrenchSystem(faradaysConstant=9.6e4,
                          gasConstant=8.314,
                          transferCoefficient=0.5,
                          rateConstant0=1.76,
                          rateConstant3=-245e-6,
                          catalystDiffusion=1e-9,
                          siteDensity=9.8e-6,
                          molarVolume=7.1e-6,
                          charge=2,
                          metalDiffusion=5.6e-10,
                          temperature=298.,
                          overpotential=-0.3,
                          metalConcentration=250.,
                          catalystConcentration=5e-3,
                          catalystCoverage=0.,
                          currentDensity0=0.26,
                          currentDensity1=45.,
                          cellSize=0.1e-7,
                          trenchDepth=0.5e-6,
                          aspectRatio=2.,
                          trenchSpacing=0.6e-6,
                          boundaryLayerDepth=0.3e-6,
                          numberOfSteps=5,
                          displayViewers=True):

    cflNumber = 0.2
    numberOfCellsInNarrowBand = 10
    cellsBelowTrench = 10

    yCells = cellsBelowTrench \
             + int((trenchDepth + boundaryLayerDepth) / cellSize)

    xCells = int(trenchSpacing / 2 / cellSize)

    from fipy.tools import serialComm
    mesh = Grid2D(dx=cellSize,
                  dy=cellSize,
                  nx=xCells,
                  ny=yCells,
                  communicator=serialComm)

    narrowBandWidth = numberOfCellsInNarrowBand * cellSize

    distanceVar = DistanceVariable(name='distance variable',
                                   mesh=mesh,
                                   value=-1.,
                                   hasOld=1)

    bottomHeight = cellsBelowTrench * cellSize
    trenchHeight = bottomHeight + trenchDepth
    trenchWidth = trenchDepth / aspectRatio
    sideWidth = (trenchSpacing - trenchWidth) / 2

    x, y = mesh.cellCenters
    distanceVar.setValue(1.,
                         where=(y > trenchHeight) |
                         ((y > bottomHeight) &
                          (x < xCells * cellSize - sideWidth)))

    distanceVar.calcDistanceFunction(order=2)

    catalystVar = SurfactantVariable(name="catalyst variable",
                                     value=catalystCoverage,
                                     distanceVar=distanceVar)

    bulkCatalystVar = CellVariable(name='bulk catalyst variable',
                                   mesh=mesh,
                                   value=catalystConcentration)

    metalVar = CellVariable(name='metal variable',
                            mesh=mesh,
                            value=metalConcentration)

    expoConstant = -transferCoefficient * faradaysConstant \
                   / (gasConstant * temperature)

    tmp = currentDensity1 * catalystVar.interfaceVar

    exchangeCurrentDensity = currentDensity0 + tmp

    expo = numerix.exp(expoConstant * overpotential)
    currentDensity = expo * exchangeCurrentDensity * metalVar \
                     / metalConcentration

    depositionRateVariable = currentDensity * molarVolume \
                             / (charge * faradaysConstant)

    extensionVelocityVariable = CellVariable(name='extension velocity',
                                             mesh=mesh,
                                             value=depositionRateVariable)

    surfactantEquation = AdsorbingSurfactantEquation(
        surfactantVar=catalystVar,
        distanceVar=distanceVar,
        bulkVar=bulkCatalystVar,
        rateConstant=rateConstant0 + rateConstant3 * overpotential**3)

    advectionEquation = TransientTerm() + AdvectionTerm(
        extensionVelocityVariable)

    metalEquation = buildMetalIonDiffusionEquation(
        ionVar=metalVar,
        distanceVar=distanceVar,
        depositionRate=depositionRateVariable,
        diffusionCoeff=metalDiffusion,
        metalIonMolarVolume=molarVolume,
    )

    metalVar.constrain(metalConcentration, mesh.facesTop)

    from surfactantBulkDiffusionEquation import buildSurfactantBulkDiffusionEquation
    bulkCatalystEquation = buildSurfactantBulkDiffusionEquation(
        bulkVar=bulkCatalystVar,
        distanceVar=distanceVar,
        surfactantVar=catalystVar,
        diffusionCoeff=catalystDiffusion,
        rateConstant=rateConstant0 * siteDensity)

    bulkCatalystVar.constrain(catalystConcentration, mesh.facesTop)

    if displayViewers:
        try:
            from mayaviSurfactantViewer import MayaviSurfactantViewer
            viewer = MayaviSurfactantViewer(distanceVar,
                                            catalystVar.interfaceVar,
                                            zoomFactor=1e6,
                                            datamax=0.5,
                                            datamin=0.0,
                                            smooth=1,
                                            title='catalyst coverage')
        except:
            viewer = MultiViewer(
                viewers=(Viewer(distanceVar, datamin=-1e-9, datamax=1e-9),
                         Viewer(catalystVar.interfaceVar)))
    else:
        viewer = None

    levelSetUpdateFrequency = int(0.8 * narrowBandWidth \
                                  / (cellSize * cflNumber * 2))

    for step in range(numberOfSteps):

        if step > 5 and step % 5 == 0 and viewer is not None:
            viewer.plot()

        if step % levelSetUpdateFrequency == 0:
            distanceVar.calcDistanceFunction(order=2)

        extensionVelocityVariable.setValue(depositionRateVariable())

        distanceVar.updateOld()

        distanceVar.extendVariable(extensionVelocityVariable, order=2)
        dt = cflNumber * cellSize / extensionVelocityVariable.max()

        advectionEquation.solve(distanceVar, dt=dt)
        surfactantEquation.solve(catalystVar, dt=dt)
        metalEquation.solve(metalVar, dt=dt)
        bulkCatalystEquation.solve(bulkCatalystVar,
                                   dt=dt,
                                   solver=GeneralSolver(tolerance=1e-15,
                                                        iterations=2000))

    try:
        import os
        filepath = os.path.splitext(__file__)[0] + '.gz'
        print catalystVar.allclose(numerix.loadtxt(filepath), rtol=1e-4)
    except:
        return 0
Esempio n. 26
0
               Plane Surface(11) = {10};
               ''' % locals())
else:
    nx = 20
    ny = nx
    dx = 1.
    dy = dx
    L = dx * nx
    mesh = Grid2D(dx=dx, dy=dy, nx=nx, ny=ny)

#We create a :class:`~fipy.variables.cellVariable.CellVariable` and initialize it to zero:
phi = CellVariable(name="solution variable", mesh=mesh, value=0.)
#and then create a diffusion equation.  This is solved by default with an
#iterative conjugate gradient solver.
D = 1.
eq = TransientTerm() == DiffusionTerm(coeff=D)

X, Y = mesh.faceCenters

if doBlob:
    phi.constrain([random.random() for x in X], mesh.exteriorFaces)

elif doCirc:

    phi.constrain(X, mesh.exteriorFaces)
else:
    #We apply Dirichlet boundary conditions
    valueTopLeft = 0
    valueBottomRight = 1
    #to the top-left and bottom-right corners.  Neumann boundary conditions
    #are automatically applied to the top-right and bottom-left corners.
# plt.plot(x, y01(x))
# plt.plot(x, y03(x))
# plt.show()

mesh = Grid1D(dx=dx, nx=nx)  # Establish mesh in how many dimensions necessary
Pion = CellVariable(mesh=mesh, name='Positive ion Charge Density', value=y01(x))
Nion = CellVariable(mesh=mesh, name='Negative ion Charge Density', value=y02(x))
# Hole = CellVariable(mesh=mesh, name='Hole Density',value=y03(x))
# Electron = CellVariable(mesh=mesh, name='Electron Density',value=y04(x))
potential = CellVariable(mesh=mesh, name='Potential')

#### Equations set-up ####
# In English:  dPion/dt = -1/q * divergence.Jp(x,t) - k_rec * Nion(x,t) * Pion(x,t) where
#             Jp = q * mu_p * E(x,t) * Pion(x,t) - q * Dp * grad.Pion(x,t)         and     E(x,t) = -grad.potential(x,t)
# Continuity Equation
Pion_equation = TransientTerm(coeff=1., var=Pion) == mu_p_1 * ConvectionTerm(coeff=potential.faceGrad, var=Pion) + Dp_1 * DiffusionTerm(coeff=1., var=Pion) - k_rec * Pion * Nion
# In English:  dNion/dt = 1/q * divergence.Jn(x,t) - k_rec * Nion(x,t) * Pion(x,t)   where
#             Jn = q * mu_n * E(x,t) * Nion(x,t) - q * Dn * grad.Nion(x,t)         and     E(x,t) = -grad.potential(x,t)
# Continuity Equation
Nion_equation = TransientTerm(coeff=1., var=Nion) == -mu_n_1 * ConvectionTerm(coeff=potential.faceGrad, var=Nion) + Dn_1 * DiffusionTerm(coeff=1., var=Nion) - k_rec * Pion * Nion
# Electron_equation = TransientTerm(coeff=1., var=Electron) == -mu_n_2 * ConvectionTerm(coeff=potential.faceGrad, var=Electron) + Dn_2 * DiffusionTerm(coeff=1., var=Electron) - k_rec * Electron * Hole
# Hole_equation = TransientTerm(coeff=1., var=Hole) == mu_p_2 * ConvectionTerm(coeff=potential.faceGrad, var=Hole) + Dp_2 * DiffusionTerm(coeff=1., var=Hole) - k_rec * Electron * Hole
# In English:  d^2potential/dx^2 = -q/epsilon * Charge_Density      and     Charge Density= Pion-Nion
# Poisson's Equation
potential_equation = DiffusionTerm(coeff=1., var=potential) == -(q / epsilon) * (Pion - Nion)
# potential_equation = DiffusionTerm(coeff=1., var=potential) == -(q / epsilon) * (Pion - Nion + Hole - Electron)
### Boundary conditions ###
# Fipy is defaulted to be no-flux, so we only need to constrain potential

potential.constrain(0., where=mesh.exteriorFaces)
Esempio n. 28
0
"""
# Order of file imports from the following import: input_handling.py,
# parameters.py, variable_decl.py, boundary_init_cond
from src.boundary_init_cond import *
from src.calculate_coeffs import *
# fipy.tools.numerix and dump is also imported from the above

from fipy import TransientTerm, DiffusionTerm, Viewer, TSVViewer
from fipy.solvers import *

import os  # For saving files to a specified directory
from shutil import copyfile

# ----------------- PDE Declarations ----------------------
# Density Equation
density.equation = TransientTerm(coeff=1.0, var=density)\
    == DiffusionTerm(coeff=Diffusivity, var=density)

# Energy Equation
temperature.equation = TransientTerm(coeff=density, var=temperature)\
    == DiffusionTerm(coeff=(Diffusivity * density / zeta), var=temperature)\
    + DiffusionTerm(coeff=Diffusivity * temperature, var=density)

# Z Equation, Taylor-expanded model
G = a + b * (Z - Z_S) + c * (Z - Z_S)**3
S_Z = ((c_n * temperature) / density**2) * density.grad[0]\
    + (c_T / density) * temperature.grad[0] + G
Z.equation = TransientTerm(coeff=epsilon, var=Z)\
    == DiffusionTerm(coeff=mu, var=Z) + S_Z

# Fully-Coupled Equation
Esempio n. 29
0
    temp_xR = (2 * temp_i[1:-1, :-2] - 2 * temp_i[1:-1, 1:-1]) / (dy**2)
    temp_f[1:-1, 1:-1] = temp_xx + temp_yy
    temp_f[-1, 1:-1] = temp_xR
    temp_f[0, 1:-1] = temp_xL
    temp_f[1:-1, 0] = temp_yL
    return temp_f


#%% Phase Field Derivative

#%% Phase Field Variable
phase = CellVariable(name=r'$\phi$', mesh=mesh, hasOld=True)
D_temp = CellVariable(name=r'$\Delta T$', mesh=mesh, hasOld=True)
CHANGE_TEMP = 2.25
#%% Heat Equation
heatEQ = (TransientTerm() == DiffusionTerm(CHANGE_TEMP) +
          (phase - phase.old) / D_time)

#%% Parameter Setup
# ALPHA = 0.015 # Alpha CONSTANT
C_ani = 0.02  # Component of (D) the anisotropic diffusion tensor in 2D
N = 6.  # Symmetry
THETA = np.pi / 8  # Orientation

psi = THETA + np.arctan2(phase.faceGrad[1], phase.faceGrad[0])

PHI = np.tan(N * psi / 2)
PHI_SQ = PHI**2
BETA = (1. - PHI_SQ) / (1. + PHI_SQ)
D_BETA_D_PSI = -N * 2 * PHI / (1 + PHI_SQ)
D_DIAG = (1 + C_ani * BETA)
Esempio n. 30
0
def runGold(faradaysConstant=9.6e4,
            consumptionRateConstant=2.6e+6,
            molarVolume=10.21e-6,
            charge=1.0,
            metalDiffusion=1.7e-9,
            metalConcentration=20.0,
            catalystCoverage=0.15,
            currentDensity0=3e-2 * 16,
            currentDensity1=6.5e-1 * 16,
            cellSize=0.1e-7,
            trenchDepth=0.2e-6,
            aspectRatio=1.47,
            trenchSpacing=0.5e-6,
            boundaryLayerDepth=90.0e-6,
            numberOfSteps=10,
            taperAngle=6.0,
            displayViewers=True):

    cflNumber = 0.2
    numberOfCellsInNarrowBand = 20

    mesh = TrenchMesh(cellSize=cellSize,
                      trenchSpacing=trenchSpacing,
                      trenchDepth=trenchDepth,
                      boundaryLayerDepth=boundaryLayerDepth,
                      aspectRatio=aspectRatio,
                      angle=numerix.pi * taperAngle / 180.)

    narrowBandWidth = numberOfCellsInNarrowBand * cellSize

    distanceVar = GapFillDistanceVariable(name='distance variable',
                                          mesh=mesh,
                                          value=-1.)

    distanceVar.setValue(1., where=mesh.electrolyteMask)
    distanceVar.calcDistanceFunction()

    catalystVar = SurfactantVariable(name="catalyst variable",
                                     value=catalystCoverage,
                                     distanceVar=distanceVar)

    metalVar = CellVariable(name='metal variable',
                            mesh=mesh,
                            value=metalConcentration)

    exchangeCurrentDensity = currentDensity0 + currentDensity1 * catalystVar.interfaceVar

    currentDensity = metalVar / metalConcentration * exchangeCurrentDensity

    depositionRateVariable = currentDensity * molarVolume / charge / faradaysConstant

    extensionVelocityVariable = CellVariable(name='extension velocity',
                                             mesh=mesh,
                                             value=depositionRateVariable)

    catalystSurfactantEquation = AdsorbingSurfactantEquation(
        catalystVar,
        distanceVar=distanceVar,
        bulkVar=0,
        rateConstant=0,
        consumptionCoeff=consumptionRateConstant * extensionVelocityVariable)

    advectionEquation = TransientTerm() + FirstOrderAdvectionTerm(
        extensionVelocityVariable)

    metalEquation = buildMetalIonDiffusionEquation(
        ionVar=metalVar,
        distanceVar=distanceVar,
        depositionRate=depositionRateVariable,
        diffusionCoeff=metalDiffusion,
        metalIonMolarVolume=molarVolume)

    metalVar.constrain(metalConcentration, mesh.facesTop)

    if displayViewers:

        try:
            from .mayaviSurfactantViewer import MayaviSurfactantViewer
            viewer = MayaviSurfactantViewer(distanceVar,
                                            catalystVar.interfaceVar,
                                            zoomFactor=1e6,
                                            datamax=1.0,
                                            datamin=0.0,
                                            smooth=1,
                                            title='catalyst coverage',
                                            animate=True)

        except:

            class PlotVariable(CellVariable):
                def __init__(self, var=None, name=''):
                    CellVariable.__init__(self, mesh=mesh.fineMesh, name=name)
                    self.var = self._requires(var)

                def _calcValue(self):
                    return numerix.array(self.var(self.mesh.cellCenters))

            viewer = MultiViewer(
                viewers=(Viewer(
                    PlotVariable(
                        var=distanceVar), datamax=1e-9, datamin=-1e-9),
                         Viewer(PlotVariable(var=catalystVar.interfaceVar))))
    else:
        viewer = None

    levelSetUpdateFrequency = int(0.7 * narrowBandWidth / cellSize /
                                  cflNumber / 2)
    step = 0

    while step < numberOfSteps:

        if step % 10 == 0 and viewer is not None:
            viewer.plot()

        if step % levelSetUpdateFrequency == 0:

            distanceVar.calcDistanceFunction()

        extensionVelocityVariable.setValue(
            numerix.array(depositionRateVariable))

        dt = cflNumber * cellSize / max(extensionVelocityVariable.globalValue)
        distanceVar.extendVariable(extensionVelocityVariable)

        advectionEquation.solve(distanceVar, dt=dt)

        catalystSurfactantEquation.solve(catalystVar, dt=dt)

        metalEquation.solve(metalVar, dt=dt)

        step += 1

    point = ((5e-09, ), (1.15e-07, ))
    value = 1.45346701e-09
    return abs(float(distanceVar(point, order=1)) - value) < cellSize / 10.0
Esempio n. 31
0
def runGold(faradaysConstant=9.6e4,
            consumptionRateConstant=2.6e+6,
            molarVolume=10.21e-6,
            charge=1.0,
            metalDiffusion=1.7e-9,
            metalConcentration=20.0,
            catalystCoverage=0.15,
            currentDensity0=3e-2 * 16,
            currentDensity1=6.5e-1 * 16,
            cellSize=0.1e-7,
            trenchDepth=0.2e-6,
            aspectRatio=1.47,
            trenchSpacing=0.5e-6,
            boundaryLayerDepth=90.0e-6,
            numberOfSteps=10,
            taperAngle=6.0,
            displayViewers=True):

    cflNumber = 0.2
    numberOfCellsInNarrowBand = 20

    mesh = TrenchMesh(cellSize = cellSize,
                      trenchSpacing = trenchSpacing,
                      trenchDepth = trenchDepth,
                      boundaryLayerDepth = boundaryLayerDepth,
                      aspectRatio = aspectRatio,
                      angle = numerix.pi * taperAngle / 180.)

    narrowBandWidth = numberOfCellsInNarrowBand * cellSize

    distanceVar = GapFillDistanceVariable(
       name = 'distance variable',
       mesh = mesh,
       value = -1.)

    distanceVar.setValue(1., where=mesh.electrolyteMask)
    distanceVar.calcDistanceFunction()

    catalystVar = SurfactantVariable(
        name = "catalyst variable",
        value = catalystCoverage,
        distanceVar = distanceVar)

    metalVar = CellVariable(
        name = 'metal variable',
        mesh = mesh,
        value = metalConcentration)

    exchangeCurrentDensity = currentDensity0 + currentDensity1 * catalystVar.interfaceVar

    currentDensity = metalVar / metalConcentration * exchangeCurrentDensity

    depositionRateVariable = currentDensity * molarVolume / charge / faradaysConstant

    extensionVelocityVariable = CellVariable(
        name = 'extension velocity',
        mesh = mesh,
        value = depositionRateVariable)

    catalystSurfactantEquation = AdsorbingSurfactantEquation(
        catalystVar,
        distanceVar = distanceVar,
        bulkVar = 0,
        rateConstant = 0,
        consumptionCoeff = consumptionRateConstant * extensionVelocityVariable)

    advectionEquation = TransientTerm() + FirstOrderAdvectionTerm(extensionVelocityVariable)

    metalEquation = buildMetalIonDiffusionEquation(
        ionVar = metalVar,
        distanceVar = distanceVar,
        depositionRate = depositionRateVariable,
        diffusionCoeff = metalDiffusion,
        metalIonMolarVolume = molarVolume)

    metalVar.constrain(metalConcentration, mesh.facesTop)

    if displayViewers:

        try:
            from .mayaviSurfactantViewer import MayaviSurfactantViewer
            viewer = MayaviSurfactantViewer(distanceVar, catalystVar.interfaceVar, zoomFactor = 1e6, datamax=1.0, datamin=0.0, smooth = 1, title = 'catalyst coverage', animate=True)

        except:

            class PlotVariable(CellVariable):
                def __init__(self, var = None, name = ''):
                    CellVariable.__init__(self, mesh = mesh.fineMesh, name = name)
                    self.var = self._requires(var)

                def _calcValue(self):
                    return numerix.array(self.var(self.mesh.cellCenters))

            viewer = MultiViewer(viewers=(
                    Viewer(PlotVariable(var = distanceVar), datamax=1e-9, datamin=-1e-9),
                    Viewer(PlotVariable(var = catalystVar.interfaceVar))))
    else:
        viewer = None

    levelSetUpdateFrequency = int(0.7 * narrowBandWidth / cellSize / cflNumber / 2)
    step = 0

    while step < numberOfSteps:

        if step % 10 == 0 and viewer is not None:
            viewer.plot()

        if step % levelSetUpdateFrequency == 0:

            distanceVar.calcDistanceFunction()

        extensionVelocityVariable.setValue(numerix.array(depositionRateVariable))

        dt = cflNumber * cellSize / max(extensionVelocityVariable.globalValue)
        distanceVar.extendVariable(extensionVelocityVariable)

        advectionEquation.solve(distanceVar, dt = dt)

        catalystSurfactantEquation.solve(catalystVar, dt = dt)

        metalEquation.solve(metalVar, dt = dt)

        step += 1

    point = ((5e-09,), (1.15e-07,))
    value = 1.45346701e-09
    return abs(float(distanceVar(point, order=1)) - value) < cellSize / 10.0
Esempio n. 32
0
elif GIBBS != "FH":
    print("Implent more stuff you lazy f**k")

# Define the equations

# evaluating kappa
kappa = (1.0 / 6.0) * chi_AB

# # eqn 1 is the 2nd order transport equation
# eq1 = (TransientTerm(var=x_a)) == DiffusionTerm(coeff = x_a * (1 - x_a), var=mu_AB)

# # eqn 2 is the chemical potential definition
# eq2 = (ImplicitSourceTerm(coeff=1. , var=mu_AB)) == ImplicitSourceTerm(coeff=d2gdx_a2, var=x_a) - d2gdx_a2 * x_a + dgdx_a - DiffusionTerm(coeff=kappa, var=x_a)

# eq1 is the transport equation
eq1 = (TransientTerm(coeff=numerix.exp(a), var=a)) == DiffusionTerm(
    coeff=numerix.exp(a) * (1.0 - numerix.exp(a)), var=mu_AB)

#eq2 is the chemical potential
eq2 = (ImplicitSourceTerm(
    coeff=1., var=mu_AB)) == dgda * (1.0 / numerix.exp(a)) - DiffusionTerm(
        coeff=kappa, var=exp_a)

eq3 = (ImplicitSourceTerm(coeff=1, var=exp_a)) == numerix.exp(a)
# Adding the equations together
eq = eq1 & eq2 & eq3

elapsed = 0.
dt = DT
if __name__ == "__main__":
    duration = TIME_MAX
Esempio n. 33
0
from fipy import CellVariable, Tri2D, TransientTerm, ExplicitDiffusionTerm, DefaultSolver, Viewer
from fipy.tools import numerix

dx = 1.
dy = 1.
nx = 10
ny = 1
valueLeft = 0.
valueRight = 1.
timeStepDuration = 0.02

mesh = Tri2D(dx, dy, nx, ny)

var = CellVariable(name="concentration", mesh=mesh, value=valueLeft)

eq = TransientTerm() == ExplicitDiffusionTerm()

solver = DefaultSolver(tolerance=1e-6, iterations=1000)

var.constrain(valueLeft, mesh.facesLeft)
var.constrain(valueRight, mesh.facesRight)

answer = numerix.array([
    0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
    0.00000000e+00, 0.00000000e+00, 1.58508452e-07, 6.84325019e-04,
    7.05111362e-02, 7.81376523e-01, 0.00000000e+00, 0.00000000e+00,
    0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
    0.00000000e+00, 4.99169535e-05, 1.49682805e-02, 3.82262622e-01,
    0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
    0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 4.06838361e-06,
    3.67632029e-03, 1.82227062e-01, 0.00000000e+00, 0.00000000e+00,
Esempio n. 34
0
def solve_Te(Qe_tot=2e6,
             H0=0,
             Hw=0.1,
             Te_bc=100,
             chi=1,
             a0=1,
             R0=3,
             E0=1.5,
             b_pos=0.98,
             b_height=6e19,
             b_sol=2e19,
             b_width=0.01,
             b_slope=0.01,
             nr=100,
             dt=100,
             plots=True):
    """
    :param Qe_tot: heating power [W]
    :type Qe_tot: numpy float
    :param H0: position of Gaussian [-]
    :type H0: numpy float
    :param Hw: width of Gaussian [-]
    :type Hw: numpy float
    :param Te_bc: outer edge Te boundary condition [eV]
    :type Te_bc: numpy float
    :param chi: thermal diffusivity [?]
    :type chi: numpy float
    :param a0: minor radius [m]
    :type a0: numpy float
    :param R0: major radius [m]
    :type R0: numpy float
    :param E0: ellipticity
    :type E0: numpy float
    :param b_pos: position of density pedestal [-]
    :type b_pos:  numpy float
    :param b_height: height of density pedestal [m^-3]
    :type b_height: numpy float
    :param b_sol: sol value for density pedestal [m^-3]
    :type b_sol: numpy float
    :param b_width: width of density pedestal [-]
    :type b_width: numpy float
    :param b_slope: slope of density pedestal [?]
    :type b_slope: numpy float
    :param nr: number of radial grid points
    :type nr: inteher
    :param dt: time-step [s]
    :type dt: numpy float
    :param plots: enable plots
    :type plots: boolean
    :return: array of Te values [eV]
    :type: numpy float array
    :return: array of ne values [m^-3]
    :type: numpy float array
    :return: rho values corresponding to the Te and ne values [m]
    :type: numpy float array
    :return: rho_norm values corresponding to the Te and ne values [-]
    :type: numpy float array

    [email protected]
    """

    if plots:
        import os
        import matplotlib
        if not os.getenv("DISPLAY"):
            matplotlib.use('Agg')
        import matplotlib.pylab as plt

    import scipy.constants
    from fipy import Variable, FaceVariable, CellVariable, TransientTerm, DiffusionTerm, Viewer, meshes

    a = a0 * np.sqrt(E0)
    V = 2 * np.pi * 2 * np.pi * R0
    mesh = meshes.CylindricalGrid1D(nr=nr, Lr=a)
    Te = CellVariable(name="Te", mesh=mesh, value=1e3)
    ne = CellVariable(name="ne",
                      mesh=mesh,
                      value=F_ped(mesh.cellCenters.value[0] / a, b_pos,
                                  b_height, b_sol, b_width, b_slope))
    Qe = CellVariable(name="Qe",
                      mesh=mesh,
                      value=np.exp(-((mesh.cellCenters.value / a - H0) /
                                     (Hw))**2)[0])
    Qe = Qe * Qe_tot / ((mesh.cellVolumes * Qe.value).sum() * V)

    print('Volume = %s m^3' % (mesh.cellVolumes.sum() * V))
    print('Heating power = %0.3e W' % ((mesh.cellVolumes * Qe).sum() * V))

    Te.constrain(Te_bc, mesh.facesRight)
    eqI = TransientTerm(
        coeff=scipy.constants.e * ne *
        1.5) == DiffusionTerm(coeff=scipy.constants.e * ne * chi) + Qe

    if plots:
        viewer = Viewer(vars=(Te),
                        title='Heating power = %0.3e W\nchi = %s' %
                        (Qe.cellVolumeAverage.value * V, chi),
                        datamin=0,
                        datamax=5000)

    eqI.solve(var=Te, dt=dt)
    if plots:
        viewer.plot()

    return Te.value, ne.value, mesh.cellCenters.value[
        0], mesh.cellCenters.value[0] / a
Esempio n. 35
0
Pion = CellVariable(mesh=mesh,
                    name='Positive ion Charge Density',
                    value=y01(mesh.x))
Nion = CellVariable(mesh=mesh,
                    name='Negative ion Charge Density',
                    value=y02(mesh.x))
potential = CellVariable(mesh=mesh, name='Potential', value=y03(mesh.x))
Jp = CellVariable(mesh=mesh, name='Positive ion Current Density', value=0.)
Jn = CellVariable(mesh=mesh, name='Negative ion Current Density', value=0.)

Jp.value = -mu_p * Pion * potential.arithmeticFaceValue.divergence + Dn * Pion.arithmeticFaceValue.divergence
Jn.value = -mu_n * Nion * potential.arithmeticFaceValue.divergence + Dn * Pion.arithmeticFaceValue.divergence

Pion.equation = TransientTerm(
    coeff=1,
    var=Pion) == -k_rec * Pion * Nion + (Jp.arithmeticFaceValue).divergence
Nion.equation = TransientTerm(
    coeff=1,
    var=Nion) == -k_rec * Pion * Nion - (Jn.arithmeticFaceValue).divergence
potential.equation = DiffusionTerm(coeff=epsilon, var=potential) == Pion - Nion

Pion.constrain(0., where=mesh.facesLeft)
Pion.constrain(0., where=mesh.facesRight)
Nion.constrain(0., where=mesh.facesLeft)
Nion.constrain(0., where=mesh.facesRight)
potential.constrain(0., where=mesh.facesLeft)
potential.constrain(0., where=mesh.facesRight)

eq = Pion.equation & Nion.equation & potential.equation
Esempio n. 36
0
# Setting the initial composition of the system with noise
noise = UniformNoiseVariable(mesh=mesh,
                             minimum=(a_0 - noise_mag),
                             maximum=(a_0 + noise_mag))
a[:] = noise

# differentiate g(a)
dgda = ((1.0 / n_a) - (1.0 / n_b)) + (1.0 / n_a) * numerix.log(a) - (
    1.0 / n_b) * numerix.log(1.0 - a) + chi_AB * (1.0 - 2 * a)
d2gda2 = (1.0 / (n_a * a)) + (1.0 / (n_b * (1.0 - a))) - 2 * chi_AB

# Evaluate kappa
kappa = (2.0 / 3.0) * chi_AB

# Defining the equations
eq1 = (TransientTerm(var=a)) == DiffusionTerm(coeff=a * (1.0 - a), var=mu_AB)
eq2 = (ImplicitSourceTerm(
    coeff=1.0, var=mu_AB)) == dgda - DiffusionTerm(coeff=kappa, var=a)
# eq2 = (ImplicitSourceTerm(coeff=1.0, var=mu_AB)) == ImplicitSourceTerm(coeff=d2gda2, var=a) - d2gda2*a + dgda - DiffusionTerm(coeff=kappa, var=a)

# Coupling the equations
eq = eq1 & eq2

# Setting up the solver
solver = LinearLUSolver(tolerance=1e-9, iterations=50, precon="ilu")

# Set up time stepping
dt = 10.0
duration = 20000
time_stride = 100
timestep = 0
Esempio n. 37
0
alpha = 0.015
temperature = 1.

dx = L / nx

mesh = Grid1D(dx=dx, nx=nx)

phase = CellVariable(name='PhaseField', mesh=mesh, value=1.)

theta = ModularVariable(name='Theta', mesh=mesh, value=1.)
theta.setValue(0., where=mesh.cellCenters[0] > L / 2.)

mPhiVar = phase - 0.5 + temperature * phase * (1 - phase)
thetaMag = theta.old.grad.mag
implicitSource = mPhiVar * (phase - (mPhiVar < 0))
implicitSource += (2 * s + epsilon**2 * thetaMag) * thetaMag

phaseEq = TransientTerm(phaseTransientCoeff) == \
          ExplicitDiffusionTerm(alpha**2) \
          - ImplicitSourceTerm(implicitSource) \
          + (mPhiVar > 0) * mPhiVar * phase

if __name__ == '__main__':

    phaseViewer = Viewer(vars=phase)
    phaseViewer.plot()
    for step in range(steps):
        phaseEq.solve(phase, dt=timeStepDuration)
        phaseViewer.plot()
    input('finished')
    C.append(
        CellVariable(name=components[i].encode(),
                     mesh=mesh,
                     value=c[i * nxyz:(i + 1) * nxyz]))
    C[i].constrain(bc_conc[i], mesh.facesLeft)
    C[i].faceGrad.constrain(0, mesh.facesRight)
if __name__ == '__main__':
    viewer = Viewer(vars=(C[4]), datamin=0., datamax=1e-4)
    viewer.plot()
#===================================================
D = 0.0  # assume there is no diffusion except numerical diffusion hahahaha
u = (1.5 / 432000, )  # m/s equivalent to 1 dt/day
eqX = []
for i in range(ncomps):
    if (i != 4):
        eqX.append(TransientTerm() == DiffusionTerm(coeff=D) -
                   UpwindConvectionTerm(coeff=u))
    else:
        # I am assuming that microbes are attached
        #eqX.append(TransientTerm() == DiffusionTerm(coeff=D))
        eqX.append(TransientTerm() == DiffusionTerm(coeff=D) -
                   UpwindConvectionTerm(coeff=u))
#timeStepDuration = 0.9 * dx**2 / (2 * D) # the maximum time step
time_step = 432000.0
t = 0
C_old = list(C)
steps = -1
t_final = 120 * 432000.0
tol = 0.1
trial = 0
H2SProductionData = np.zeros((maxTimeStep, nxyz), dtype='float')
Esempio n. 39
0
steps = int(L / 4. / dt / velocity)

mesh = Grid1D(dx=dx, nx=nx)

periodicMesh = PeriodicGrid1D(dx=dx, nx=nx // 2)

startingArray = numerix.zeros(nx, 'd')
startingArray[2 * nx // 10:3 * nx // 10] = 1.

var1 = CellVariable(name="non-periodic", mesh=mesh, value=startingArray)

var2 = CellVariable(name="periodic",
                    mesh=periodicMesh,
                    value=startingArray[:nx // 2])

eq1 = TransientTerm() - VanLeerConvectionTerm(coeff=(-velocity, ))
eq2 = TransientTerm() - VanLeerConvectionTerm(coeff=(-velocity, ))

if __name__ == '__main__':

    viewer1 = Viewer(vars=var1)
    viewer2 = Viewer(vars=var2)
    viewer1.plot()
    viewer2.plot()

    newVar2 = var2.copy()

    for step in range(steps):
        eq1.solve(var=var1, dt=dt, solver=DefaultAsymmetricSolver())
        eq2.solve(var=var2, dt=dt, solver=DefaultAsymmetricSolver())
        viewer1.plot()
source = (phase - lamda * uu * (1 - phase**2)) * (1 - phase**2)


theta = numerix.arctan2(phase.faceGrad[1], phase.faceGrad[0])
W = W_0 * (1 + epsilon_m * numerix.cos(mm * theta - theta_0))

W_theta = - W_0 * mm * epsilon_m * numerix.sin(mm * theta - theta_0)

# Build up the diffusivity matrix
I0 = Variable(value=((1,0), (0,1)))
I1 = Variable(value=((0,-1), (1,0)))
Dphase = W**2 * I0 + W * W_theta * I1


heat_eqn = TransientTerm() == DiffusionTerm(DD) + (phase - phase.old) / dt / 2.

phase_eqn = TransientTerm(tau) == DiffusionTerm(Dphase) + source

initialize()

solid_area = (np.array(phase.globalValue)>0).sum()*dx*dy # initial size of solid nucleus
if parallelComm.procID==0:
    print 'solid area', solid_area

total_steps = 20000
sweeps = 2
tolerance = 0.5

# Serial:
#from fipy.solvers.pysparse import LinearLUSolver as Solver