def _setup_equation(self, biomass_height): height = biomass_height + self._layer_height size = height * self._layer mesh = self.space.construct_mesh(height) variables, terms = [], [] phi = CellVariable(name=self.solute.name, mesh=mesh, hasOld=True) for r in self.reactions: variables.append( CellVariable(name=f"{r.bacteria.name}_rate", mesh=mesh, value=0.0)) terms.append( ImplicitSourceTerm(coeff=(variables[-1] / (phi + self._sr)))) equation = DiffusionTerm(coeff=self.diffusivity) - sum(terms) phi.constrain(1, where=mesh.facesTop) for var, coef in zip( variables, [r.rate_coefficient()[:size] for r in self.reactions]): try: var.setValue(coef / self.space.dV) except ValueError as err: print("Boundary layer height greater than system size") raise err phi.setValue(self.solute.value.reshape(-1)[:size]) return equation, phi, size
def add_source_term_from(self, path, coeff = 1): """ Add a source term from the model path Args: path (str): Path to model store coeff (int, float): coeff for source term Raises: ValueError if path does not point to an object """ if self.finalized: raise RuntimeError('Equation already finalized, cannot add terms') self.logger.info('{} Adding source term from {!r} (coeff={}'.format( self, path, coeff)) if not isinstance(coeff, (int, float)): raise ValueError('Source coeff should be int or float, not {}'.format(type(coeff))) if path in self.source_exprs: raise RuntimeError('Source term path already exists: {!r}'.format(path)) obj = self.model.get_object(path) """:type: Process""" # expr = obj.evaluate() # self.logger.debug('Created source expr: {!r}'.format(expr)) self.source_coeffs[path] = coeff full_expr = obj.as_term() self.source_exprs[path] = coeff * full_expr self.source_formulae[path] = coeff * obj.expr() var, S0, S1 = obj.as_source_for(self.varname) assert var is self.var, 'Got var: {!r} and self.var: {!r}'.format( var, self.var) if S1 is not 0: # do not use != 0 as it fails for array type vars S1 = ImplicitSourceTerm(coeff=S1, var=self.var) term = S0 + S1 else: term = S0 self.source_terms[path] = term * coeff self.logger.debug('Created source {!r}: {!r}'.format(path, term))
def test_add_source_term_from(self, model): eqn = ModelEquation(model, 'domain.abc', coeff=5) # model.get_object.return_value = rv = mock.MagicMock(CellVariable) rv = model.get_object.return_value rv.as_term = fullexpr = mock.Mock(SourceTerm) fullexpr.return_value = mock.MagicMock(Variable) rv.expr = expr = mock.MagicMock(CellVariable) rv.as_source_for = source = mock.Mock(SourceTerm) source.return_value = (mock.Mock(CellVariable), mock.Mock(SourceTerm), mock.Mock(SourceTerm)) # rv.__mul__ = lambda x: x # for eqn_term * coeff S0 = eqn.var S1 = 3 S1term = ImplicitSourceTerm(var=eqn.var, coeff=S1) source.return_value = eqn.var, S0, S1 varpath = 'domain.var1' coeff = 1.5 with pytest.raises(ValueError): eqn.add_source_term_from(varpath, coeff=None) eqn.add_source_term_from(varpath, coeff) assert varpath in eqn.source_terms assert varpath in eqn.source_exprs assert varpath in eqn.source_formulae assert eqn.source_exprs[varpath] == coeff * fullexpr() assert eqn.source_formulae[varpath] == coeff * expr() # assert eqn.source_terms[varpath] == S0 + S1term with pytest.raises(RuntimeError): eqn.add_source_term_from(varpath, coeff)
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 eq = eq1 & eq2 elapsed = 0. dt = DT if __name__ == "__main__": duration = TIME_MAX
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) D_OFF = C_ani * D_BETA_D_PSI I0 = Variable(value=((1, 0), (0, 1))) I1 = Variable(value=((0, -1), (1, 0))) DIF_COEF = ALPHA**2 * (1. + C_ani * BETA) * (D_DIAG * I0 + D_OFF * I1) TAU = 0.0003 KAPPA_1 = 0.9 KAPPA_2 = 20. phase_EQ = (TransientTerm(TAU) == DiffusionTerm(DIF_COEF) + ImplicitSourceTerm( (phase - 0.5 - KAPPA_1 / np.pi * np.arctan(KAPPA_2 * D_temp)) * (1 - phase))) #%% Circular Solidified Region in the Center radius = DX * 5.0 C_circ = (NX * DX / 2, NY * DY / 2) X, Y = mesh.cellCenters phase.setValue(1., where=((X - C_circ[0])**2 + (Y - C_circ[1])**2) < radius**2) D_temp.setValue(-0.5) #%% Plotting if __name__ == "__main__": try: import pylab
#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 tFinal_nd = 2. #SETTING dimensionless final temperature
D_Zohm = (D_max + D_min) / 2.0 + ((D_max - D_min) * numerix.tanh(Z)) / 2.0 # Stap's Model alpha_sup = 0.5 D_Staps = D_min + (D_max - D_min) / (1.0 + alpha_sup * numerix.dot(Z.grad, Z.grad)) # Flow-Shear Model a1, a3 = 1.0, 0.5 # ASSUMES a2 = 0 D_Shear = D_min + (D_max - D_min) / (1.0 + a1 * (Z)**2 + a3 * numerix.dot(Z.grad, Z.grad)) # CHOOSE DIFFUSIVITY HERE! D_choice = D_Staps # If Diffusivity is a Cell/Face variable Diffusivity.setValue(D_choice) Diffusivity.equation = (ImplicitSourceTerm(1.0)) # ----------------- Boundary Conditions ------------------- """ Density Boundary Conditions: d/dx(n(0)) == n / lambda_n d/dx(n(L)) == -Gamma_c / Diffusivity """ density.faceGrad.constrain(density.faceValue / lambda_n, mesh.facesLeft) density.faceGrad.constrain(-Gamma_c / Diffusivity.faceValue, mesh.facesRight) """ Temperature Boundary Conditions: d/dx(T(0)) = T / lambda_T d/dx(T(L)) = zeta*(Gamma_c*T - q_c*(gamma - 1)) / (Diffusivity * n) """
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 elapsed = 0
cm.constrain(0, m.facesLeft) cm.constrain(0, m.facesRight) cim.constrain(0, m.facesLeft) cim.constrain(0, m.facesRight) # advective flow velocity u = FaceVariable(mesh=m, value=(0.0,), rank=1) # 1D convection diffusion equation (mobile domain) # version with \frac{\partial c_{im}}{\partial t} eqM = (TransientTerm(1.0,var=cm) + TransientTerm(betaT,var=cim) == DiffusionTerm(DR,var=cm) - ExponentialConvectionTerm(u/(Rm*phim),var=cm)) # immobile domain (lumped approach) eqIM = TransientTerm(Rim*phiim,var=cim) == beta/Rim*(cm - ImplicitSourceTerm(1.0,var=cim)) # couple equations eqn = eqM & eqIM viewer = Viewer(vars=(cm,cim), datamin=0.0, datamax=1.0) viewer.plot() time = 0.0 for step in range(steps): time += timeStep if time < 0.5: u.setValue((1.0,)) elif time < 1.0: u.setValue((0.0,))
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 eq.solve(dt=dt, solver=solver) phi.setValue(0.0, where=phi < 0.0)
value=mesh._faceToCellDistanceRatio * mesh.cellDistanceVectors) Af = FaceVariable(mesh=mesh, value=mesh._faceAreas) b = k #RobinCoeff = (mask * Gamma0 * Af * mesh.faceNormals / (-dPf.dot(a) + b)).divergence #I changed a sign in the denominator since I suspect a sign error #a is convectionCoeff times n_hat #20181211: I am getting same result whichever sign in the denominator I go with; solution is stuck at initial condition RobinCoeff = ( mask * Gamma0 * Af * mesh.faceNormals / (-convectionCoeff * dPf.dot(mesh.faceNormals) + b) ).divergence #I changed a sign in the denominator since I suspect a sign error g = convectionCoeff * T_infinity #eq = (TransientTerm() == DiffusionTerm(coeff=Gamma) + RobinCoeff * g - ImplicitSourceTerm(coeff=RobinCoeff * mesh.faceNormals.dot(a))) #a is convectionCoeff times n_hat eq = (TransientTerm() == DiffusionTerm(coeff=Gamma) + RobinCoeff * g - ImplicitSourceTerm(coeff=RobinCoeff * convectionCoeff)) # 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() time.sleep(.25) dt_explicit = cellSize**2 / 2. / D_thermal
noise = GaussianNoiseVariable(mesh=mesh, mean = A_RAW, variance = NOISE_MAGNITUDE).value x_a[:] = noise 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) kappa = (1.0/6.0)*chi_AB # eq1 = TransientTerm(var=x_a) == ConvectionTerm(coeff= ((x_a*(1.0 - x_a))*[[1]]).rank *xi.faceGrad) + DiffusionTerm((x_a *(1.0 - x_a), kappa), var = x_a) eq1 = TransientTerm(var=x_a) == DiffusionTerm(coeff= x_a*(1.0 - x_a), var = xi) + DiffusionTerm((x_a *(1.0 - x_a), kappa), var = x_a) eq2 = ImplicitSourceTerm(coeff=1, var= xi) == dgdx_a eq = eq1 & eq2 elapsed = 0. dt = DT if __name__ == "__main__": duration = TIME_MAX time_stride = TIME_STRIDE timestep = 0 # Defining the solver solver = LinearLUSolver(tolerance=1e-10, iterations=50)
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) D_OFF = C_ani * D_BETA_D_PSI I0 = Variable(value = ((1, 0), (0, 1))) I1 = Variable(value = ((0, -1), (1, 0))) DIF_COEF = ALPHA ** 2 * (1. + C_ani * BETA) * (D_DIAG * I0 + D_OFF * I1) TAU = 0.0003 KAPPA_1 = 0.9 KAPPA_2 = 20. phase_EQ = (TransientTerm(TAU) == DiffusionTerm(DIF_COEF) + ImplicitSourceTerm((phase - 0.5 - KAPPA_1 / np.pi * np.arctan(KAPPA_2 * D_temp)) * (1 - phase))) #%% Circular Solidified Region in the Center radius = DX * 5.0 C_circ = (NX * DX / 2, NY * DY / 2) X, Y = mesh.cellCenters phase.setValue(1., where=((X - C_circ[0])**2 + (Y - C_circ[1])**2) < radius**2) D_temp.setValue(-0.5) #%% Plotting if __name__ == "__main__": try: import pylab class DendriteViewer(Matplotlib2DGridViewer): def __init__(self, phase, D_temp, title = None,
c.value = 0.0 c.setValue((0.3 * numerix.sin(2.0 * x * numerix.pi)) + 0.5) # Setting up the no-flux boundary conditions c.faceGrad.constrain(0.0, where=mesh.facesLeft) c.faceGrad.constrain(0.0, where=mesh.facesRight) # Provide value for diffusion and reaction coefficient D = 1.0 k = -2.0 # Specifying our alpha value. We will only use backwards Euler going forward alpha = 1 # Defining the equation with the reaction term. eq = TransientTerm() == DiffusionTerm(coeff=D) + ImplicitSourceTerm(coeff=k) # We can use a much larger dt now since we are using an implicit method. dt = 0.001 # We might not want to see the output from every single timestep, so we define a stride parameter time_stride = 100 timestep = 0 run_time = 0.5 t = timestep * dt # We first initialise the default viewer to get things started: # if __name__ == "__main__": # viewer = Viewer(vars=(c), datamin=0., datamax=1.)
value=mesh._faceToCellDistanceRatio * mesh.cellDistanceVectors) b = k #RobinCoeff = (mask * Gamma0 * Af * mesh.faceNormals / (-dPf.dot(a) + b)).divergence #I changed a sign in the denominator since I suspect a sign error #a is convectionCoeff times n_hat #20181211: I am getting same result whichever sign in the denominator I go with; solution is stuck at initial condition RobinCoeff = ( mask * Gamma0 * mesh.faceNormals / (-convectionCoeff * dPf.dot(mesh.faceNormals) + b) ) #I changed a sign in the denominator since I suspect a sign error g = convectionCoeff * T_infinity #eq = (TransientTerm() == DiffusionTerm(coeff=Gamma) + RobinCoeff * g - ImplicitSourceTerm(coeff=RobinCoeff * mesh.faceNormals.dot(a))) #a is convectionCoeff times n_hat eq = (TransientTerm() == DiffusionTerm(coeff=Gamma) + (RobinCoeff * g).divergence - ImplicitSourceTerm(coeff=(RobinCoeff * convectionCoeff).divergence)) # 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() time.sleep(.25) dt_explicit = cellSize**2 / 2. / D_thermal
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']) +
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')
# 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 time_stride = TIME_STRIDE timestep = 0 # Defining the solver to improve numerical stabilty