def residuals(self, part, facefluxes, celltransient, cellsource): """ Calculate FVM residuals Parameters: ----------- facefluxes: vector or None fluxes per unit of surface or None celltransient: float or vector transient term per unit of volume cellsource: float or vector source term per unit of volume Returns: tuple (residuals,FdS) -------- residuals: residuals for each cell, per unit of volume FdS: integral FdS per cell """ assert part is self.mesh.internal or part is self.mesh.boundary idx = part.idx if facefluxes is None: FdS = 0. else: FdS = ad.dot(part.fluxsum, facefluxes) celltransient = ad.getitem(celltransient, idx) cellsource = ad.getitem(cellsource, idx) return self.idx[idx], -FdS / \ part.cells['volume'] + celltransient - cellsource
def _concentration(self, ctx, eq, idx, imref, ref, **kwargs): assert eq.z in [1, -1] if idx is not None: Eband = ad.getitem(ctx.varsOf(eq)[ref], idx) else: Eband = ctx.varsOf(eq)[ref] return self.c(ctx, eq, -(imref - Eband) / eq.z, **kwargs)
def image_correction(self, ctx, eq, ixto): if not self.image_force: return 0. n = eq.mesh.boundaries[self.name]['normal'] F = eq.z * eq.mesh.dotv(ctx.varsOf(eq.poisson)['Ecellv'][ixto], n) F = where(F > self.F_eps, F, self.F_eps) return -eq.z * \ functions.EmtageODwyerBarrierLowering( F, getitem(ctx.varsOf(eq.poisson)['epsilon'], ixto))
def residuals(self, ctx, eq, flux, source=None, transient=0.): variables = ctx.varsOf(eq) yield eq.residuals(eq.mesh.internal, flux, cellsource=source, celltransient=transient) n = len(eq.mesh.boundary.cells) bc_FdS = sparsesum(n, variables['boundary_FdS']) bc_source = sparsesum(n, variables['boundary_sources']) if flux is not None: bc_FdS = dot(eq.mesh.boundary.fluxsum, flux) + bc_FdS if source is not None: bc_source = getitem(source, eq.mesh.boundary.idx) + bc_source bc_transient = getitem(transient, eq.mesh.boundary.idx) variables['total_boundary_FdS'] = bc_FdS variables['total_boundary_sources'] = bc_source variables['total_boundary_transient'] = bc_transient self._evaluate_bc( ctx, eq, bc_FdS, cellsource_boundary=bc_source, celltransient_boundary=bc_transient)
def finalize(self, target, bc_conservation): bc_label_conservation = ad.sparsesum_bare(len(self.bc_labels), bc_conservation) for eq in self.equations: if isinstance(eq, FVMConservationEquation): bc_free_dof = np.arange(len( eq.mesh.boundary.idx))[eq.bc_dof_is_free] i = eq.idx[eq.mesh.boundary.idx[bc_free_dof]] j = self.bc_labels[i] yield i, ad.getitem(bc_label_conservation, j) * (1. / self.bc_label_volume[j])
def value(self, ctx, eq): return getitem( ctx.varsOf(eq.semiconductor)['conc_Ef'][id(eq.owner_eq)], eq._getIdx())
def potential(self, ctx, eq): return self.voltage(ctx, eq) + getitem( ctx.varsOf(eq.semiconductor)['Efv'], eq._getIdx())
def branch_cut_limit(ix): return self.impl.b( np.sqrt(2.) * getitem(nsigma, ix), self.g3_max_c)
def branch_if_inlimit(ix): return getitem(info['b'], ix)