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
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 GetAz(Bx, By, Jz, Nc, dl): mesh = Grid2D(dx=dl[0], dy=dl[1], nx=Nc[0], ny=Nc[1]) _Az = CellVariable(mesh=mesh, value=0.0) _Bx = CellVariable(mesh=mesh) _Bx.value = np.reshape(Bx, Nc[0] * Nc[1], order='F') _By = CellVariable(mesh=mesh) _By.value = np.reshape(By, Nc[0] * Nc[1], order='F') _Jz = CellVariable(mesh=mesh) _Jz.value = np.reshape(Jz, Nc[0] * Nc[1], order='F') _Az.equation = (DiffusionTerm(coeff=1.0) + _Jz == 0) # beware of the sign of the flux : always consider outward direction BCs = [ FixedFlux(value=_By.getFaceValue(), faces=mesh.getFacesLeft()), FixedFlux(value=-_By.getFaceValue(), faces=mesh.getFacesRight()), FixedFlux(value=-_Bx.getFaceValue(), faces=mesh.getFacesBottom()), FixedFlux(value=_Bx.getFaceValue(), faces=mesh.getFacesTop()) ] _Az.equation.solve(var=_Az, boundaryConditions=BCs) Az = np.reshape(_Az.value, Nc, order='F') return Az
def icir_rect(self): # step 1: Mesh mesh = Grid2D(dx=self.gsize, dy=self.gsize, nx=self.xy_n[0], ny=self.xy_n[1]) # step 2: Equation phi = CellVariable(mesh=mesh, name='potential phi', value=0.) eqn = (DiffusionTerm(coeff = 1.) == 0.) # step 3: Boundary conditions # compute flow of 4 vertexes # one vertex has 2 components of wind vector, (x, y) vertexWindVec = np.array([ [0.0 for i in range(2)] for i in range(4)]) for i in range(4): # 4 vertexes for j in range(2): # 2 components vertexWindVec[i, j] = self.mean_flow[j] \ + self.colored_noise(self.vertexWindVecRanInc[i][j]) # interpolate flow vector on sim area edges, and set neumann boundary # conditions, because /grad /phi = V(x,y) # get all points which lie on the center of edges of cells X, Y = mesh.faceCenters # /grad /phi array, of points of mesh face centers # grad_phi_bc[0, :] /grad/phi_x # grad_phi_bc[1, :] /grad/phi_y grad_phi_bc = np.zeros_like(mesh.faceCenters()) # p: points on one edge to interpolate, 1 dimension # vx, vy: x&y components of interpolated wind vectors of points list p # vertex index, for interpolate bc on 4 edges # vertexIndex[0] = [1,2], down boundary, 0<x<nx*dx, y=0 # vertexIndex[1] = [1,0], left boundary, x=0, 0<y<ny*dy # vertexIndex[2] = [0,3], up boundary, 0<x<nx*dx, y=ny*dy # vertexIndex[3] = [2,3], right boundary, x=nx*dx, 0<y<ny*dy vertexIndex = np.array([ [1,2], [1,0], [0,3], [2,3] ]) for i in range(4): # 4 edges for 2D rect area p = np.arange(self.gsize/2, self.gsize*self.xy_n[i%2], self.gsize) vx = np.interp(p, [0.0, self.gsize*self.xy_n[i%2]], \ [vertexWindVec[vertexIndex[0,0], 0], \ vertexWindVec[vertexIndex[0,1], 0]]).T.reshape(1,-1)[0] vy = np.interp(p, [0.0, self.gsize*self.xy_n[i%2]], \ [vertexWindVec[vertexIndex[0,0], 1], \ vertexWindVec[vertexIndex[0,1], 1]]).T.reshape(1,-1)[0] print 'vx = ' + str(vx) if i == 0: # down boundary grad_phi_bc[:, mesh.facesDown()] = np.array([vx, vy]) elif i == 1: # left boundary grad_phi_bc[:, mesh.facesLeft()] = np.array([vx, vy]) elif i == 2: # up boundary grad_phi_bc[:, mesh.facesUp()] = np.array([vx, vy]) elif i == 3: # right boundary grad_phi_bc[:, mesh.facesRight()] = np.array([vx, vy]) # set neumann boundary condition phi.faceGrad.constrain(((grad_phi_bc[0]),(grad_phi_bc[1])), where=mesh.exteriorFaces) # step 4: Solve eqn.solve(var=phi) #print str(phi) #print str(type(np.array(phi))) self.wind_phi_field = np.array(phi) self.wind_mesh_centers = mesh.cellCenters()
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 __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')
def _add_diffusion_term(self, coeff): """ Add a linear diffusion term to the equation Args: coeff (int, float, term): Coefficient for diffusion term """ if self.finalized: raise RuntimeError('Equation already finalized, cannot add terms') term = DiffusionTerm(var=self.var, coeff=coeff) self.logger.debug('Created implicit diffusion term with coeff: {!r}'.format(coeff)) self.term_diffusion = term
def GetAz(Bx, By, Jz, Nc, dl): mesh = Grid2D(dx=dl[0], dy=dl[1], nx=Nc[0], ny=Nc[1]) _Az = CellVariable(mesh=mesh, value=0.0) _Bx = CellVariable(mesh=mesh) _Bx.value = np.reshape(Bx, Nc[0] * Nc[1], order='F') _By = CellVariable(mesh=mesh) _By.value = np.reshape(By, Nc[0] * Nc[1], order='F') _Jz = CellVariable(mesh=mesh) _Jz.value = np.reshape(Jz, Nc[0] * Nc[1], order='F') _Az.equation = (DiffusionTerm(coeff=1.0) + _Jz == 0) #diffcoeff = CellVariable(mesh=mesh, value = 1.0) #diffTerm = DiffusionTerm(coeff = diffcoeff) #diffTerm = DiffusionTerm(coeff = 1.0) #diffcoeff.constrain(0., mesh.exteriorFaces) # beware of the sign of the flux : always consider outward direction _Az.faceGrad.constrain(_By.arithmeticFaceValue, where=mesh.facesLeft) _Az.faceGrad.constrain(-_By.arithmeticFaceValue, where=mesh.facesRight) _Az.faceGrad.constrain(-_Bx.arithmeticFaceValue, where=mesh.facesBottom) _Az.faceGrad.constrain(_Bx.arithmeticFaceValue, where=mesh.facesTop) #_Az.faceGrad.constrain( _By.arithmeticFaceValue[mesh.facesLeft] , where=mesh.facesLeft) #_Az.faceGrad.constrain(-_By.arithmeticFaceValue[mesh.facesRight] , where=mesh.facesRight) #_Az.faceGrad.constrain(-_Bx.arithmeticFaceValue[mesh.facesBottom] , where=mesh.facesBottom) #_Az.faceGrad.constrain( _Bx.arithmeticFaceValue[mesh.facesTop] , where=mesh.facesTop) #_Az.equation = (diffTerm+_Jz == 0) #_Az.equation = (DiffusionTerm(diffcoeff)+ (mesh.exteriorFaces*exteriorFlux).divergence + _Jz== 0) #_Az.equation = (diffTerm + _Jz == 0) #BCs = [FixedFlux(value= _By.getFaceValue(), faces=mesh.getFacesLeft()), # FixedFlux(value=-_By.getFaceValue(), faces=mesh.getFacesRight()), # FixedFlux(value=-_Bx.getFaceValue(), faces=mesh.getFacesBottom()), # FixedFlux(value= _Bx.getFaceValue(), faces=mesh.getFacesTop())] #_Az.equation.solve(var=_Az, boundaryConditions=BCs) _Az.equation.solve(var=_Az) Az = np.reshape(_Az.value, Nc, order='F') return Az
def test_add_diffusion_term_from(self, model): # input should be path, coeff eqn = ModelEquation(model, 'domain.abc', coeff=5) model.get_object.return_value = rv = mock.Mock(CellVariable) rv.as_term = rvt = mock.Mock() rvt.return_value = v = Variable(1.5) varpath = 'domain.var1' coeff = 1.1 assert eqn.term_diffusion is None assert eqn.diffusion_def is () eqn.add_diffusion_term_from(varpath, coeff) assert eqn.term_diffusion == DiffusionTerm(var=eqn.var, coeff=v * coeff) assert eqn.diffusion_def == (varpath, coeff)
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 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
dPf = FaceVariable(mesh=mesh, 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
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')
var.constrain(valueBottomTop, mesh.facesTop) var.constrain(valueBottomTop, mesh.facesBottom) #do the 2D problem for comparison nx = 8 # FIXME: downsized temporarily from 10 due to https://github.com/usnistgov/fipy/issues/622 ny = 5 dx = 1. dy = 1. mesh2 = Grid2D(dx = dx, dy = dy, nx = nx, ny = ny) var2 = CellVariable(name = "solution variable 2D", mesh = mesh2, value = valueBottomTop) var2.constrain(valueLeftRight, mesh2.facesLeft) var2.constrain(valueLeftRight, mesh2.facesRight) var2.constrain(valueBottomTop, mesh2.facesTop) var2.constrain(valueBottomTop, mesh2.facesBottom) eqn = DiffusionTerm() if __name__ == '__main__': eqn.solve(var2) viewer = Viewer(var2) viewer.plot() input("finished")
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 steps = 253 dt = 6 if __name__ == "__main__": viewer = Viewer(vars=(Nion, ), datamin=-1e15, datamax=1e15)
# 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 eq = eq1 & eq2
Physical Line("Ground") = {4, 5, 6}; Physical Surface("Field") = {1}; Physical Surface("Anode") = {2}; Physical Surface("Cathode") = {3}; """ for refinement in range(10): mesh = Gmsh2D(geo, background=monitor) charge = CellVariable(mesh=mesh, name=r"$\rho$", value=0.) charge.setValue(+1, where=mesh.physicalCells["Anode"]) charge.setValue(-1, where=mesh.physicalCells["Cathode"]) potential = CellVariable(mesh=mesh, name=r"$\psi$") potential.constrain(0., where=mesh.physicalFaces["Ground"]) eq = DiffusionTerm(coeff=1.) == -charge res0 = eq.sweep(var=potential) res = eq.justResidualVector(var=potential) res1 = numerix.L2norm(res) res1a = CellVariable(mesh=mesh, value=abs(res)) res = CellVariable(mesh=mesh, name="residual", value=abs(res) / mesh.cellVolumes**(1./mesh.dim) / 1e-3) # want cells no bigger than 1 and no smaller than 0.001 maxSize = 1. minSize = 0.001 monitor = CellVariable(mesh=mesh, name="monitor", value= 1. / (res + maxSize) + minSize)
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)
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
from __future__ import division from __future__ import unicode_literals from builtins import input __docformat__ = 'restructuredtext' from fipy import CellVariable, Grid1D, LinearLUSolver, NthOrderBoundaryCondition, DiffusionTerm, Viewer Lx = 1. nx = 100000 dx = Lx / nx mesh = Grid1D(dx = dx, nx = nx) var = CellVariable(mesh = mesh) eq = DiffusionTerm((1.0, 1.0)) BCs = (NthOrderBoundaryCondition(mesh.facesLeft, 0., 0), NthOrderBoundaryCondition(mesh.facesRight, Lx, 0), NthOrderBoundaryCondition(mesh.facesLeft, 0., 2), NthOrderBoundaryCondition(mesh.facesRight, 0., 2)) solver = LinearLUSolver(iterations=10) if __name__ == '__main__': eq.solve(var, boundaryConditions = BCs, solver = solver) viewer = Viewer(var) viewer.plot()
temp_left = temperature.faceValue / lambda_T temperature.faceGrad.constrain(temp_left, mesh.facesLeft) temp_right = (zeta * (Gamma_c*temperature.faceValue - q_c*(gamma - 1.0)))\ / (Diffusivity.faceValue * density.faceValue) temperature.faceGrad.constrain(temp_right, mesh.facesRight) """ Paquay considered these Z Boundary Conditions: d/dx(Z(0)) == Z / lambda_Z mu*D/epsilon * d/dx(Z(L)) == 0 """ Z.faceGrad.constrain(Z.faceValue / lambda_Z, mesh.facesLeft) Z.faceGrad.constrain(0.0, mesh.facesRight) # ----------------- PDE Declarations ---------------------- density.equation = (DiffusionTerm(coeff=Diffusivity, var=density) == 0) temperature.equation = (0 ==\ DiffusionTerm(coeff=(Diffusivity*density/zeta), var=temperature)\ + DiffusionTerm(coeff=-Diffusivity*temperature, var=density)) 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 = (0 == DiffusionTerm(coeff=mu, var=Z) + S_Z) full_equation = density.equation & temperature.equation & Z.equation viewer = Viewer((density, temperature, Z, Diffusivity), xmin=0.0, xmax=L) restol = 1e-1
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
#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
# 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)
-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 # Poisson's Equation potential.equation = DiffusionTerm(
# 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 full_equation = density.equation & temperature.equation & Z.equation
'''.format(cellSize, l1, l2, math.tan(beta) * (l2 - l1), l3, math.tan(alpha) * l3) mesh = Gmsh3D(geometryTemplate) # Enthaelt die Temperatur phi = CellVariable(name="Temperature", mesh=mesh, value=T0) # boundry conditions ---------------------------------------------------------- phi.constrain(Ti, where=mesh.physicalFaces["inner"]) phi.constrain(Te, where=mesh.physicalFaces["outer"]) # calculation ----------------------------------------------------------------- viewer = Viewer(vars=phi, datamin=200., datamax=Te * 1.01) print "Calculation started" started = time.clock() # Loest die Stationaere Waermegleichung DiffusionTerm(coeff=D).solve(var=phi) print "Calculation finished, took {} seconds".format(time.clock() - started) viewer.plot() raw_input("Press enter to close ...")
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
>>> print var.allclose(analyticalArray) 1 """ __docformat__ = 'restructuredtext' from fipy import Tri2D, CellVariable, DiffusionTerm, Viewer nx = 50 dx = 1. mesh = Tri2D(dx = dx, nx = nx) valueLeft = 0. valueRight = 1. var = CellVariable(name = "solution-variable", mesh = mesh, value = valueLeft) var.constrain(valueLeft, mesh.facesLeft) var.constrain(valueRight, mesh.facesRight) if __name__ == '__main__': DiffusionTerm().solve(var) viewer = Viewer(vars=var) viewer.plot() x = mesh.cellCenters[0] Lx = nx * dx analyticalArray = valueLeft + (valueRight - valueLeft) * x / Lx print var.allclose(analyticalArray) raw_input("finished")
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
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']) + params['zeta3PITP']) + params['zeta3'] P3Eq = TransientTerm() - DiffusionTerm( params['diffusionCoeff']) - P3scCoeff + ImplicitSourceTerm(P3spCoeff) P2scCoeff = scCoeff = params[ 'chi2'] + params['lambda3'] * params['zeta3T'] * P3Var P2spCoeff = params['lambda2'] * (TMVar + params['zeta2T']) P2Eq = TransientTerm() - DiffusionTerm( params['diffusionCoeff']) - P2scCoeff + ImplicitSourceTerm(P2spCoeff) KCscCoeff = params['alphaKstar'] * params['lambdaK'] * ( KMVar / (1 + PN / params['kappaK'])).cellVolumeAverage KCspCoeff = params['lambdaKstar'] / (params['kappaKstar'] + KCVar) KCEq = TransientTerm() - KCscCoeff + ImplicitSourceTerm(KCspCoeff) eqs = ((KMVar, KMEq), (TMVar, TMEq), (TCVar, TCEq), (P3Var, P3Eq), (P2Var, P2Eq), (KCVar, KCEq))
# 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