def test_comparison_checker(self): cell = triangle element = FiniteElement("Lagrange", cell, 1) u = TrialFunction(element) v = TestFunction(element) a = conditional(ge(abs(u), imag(v)), u, v) b = conditional(le(sqrt(abs(u)), imag(v)), as_ufl(1), as_ufl(1j)) c = conditional(gt(abs(u), pow(imag(v), 0.5)), sin(u), cos(v)) d = conditional(lt(as_ufl(-1), as_ufl(1)), u, v) e = max_value(as_ufl(0), real(u)) f = min_value(sin(u), cos(v)) g = min_value(sin(pow(u, 3)), cos(abs(v))) assert do_comparison_check(a) == conditional(ge(real(abs(u)), real(imag(v))), u, v) with pytest.raises(ComplexComparisonError): b = do_comparison_check(b) with pytest.raises(ComplexComparisonError): c = do_comparison_check(c) assert do_comparison_check(d) == conditional(lt(real(as_ufl(-1)), real(as_ufl(1))), u, v) assert do_comparison_check(e) == max_value(real(as_ufl(0)), real(real(u))) assert do_comparison_check(f) == min_value(real(sin(u)), real(cos(v))) assert do_comparison_check(g) == min_value(real(sin(pow(u, 3))), real(cos(abs(v))))
def setup_problem(self, debug=False): # # assemble the matrix, if necessary (once for all time points) # if not hasattr(self, 'A'): drho_integral = vectotal([ tdrho * wrho * self.dx for tdrho, wrho in zip(self.tdrhos, self.wrhos) ]) dU_integral = vectotal( [tdU * wU * self.dx for tdU, wU in zip(self.tdUs, self.wUs)]) self.A = fe.assemble(drho_integral + dU_integral) for bc in self.bcs: bc.apply(self.A) self.dsol = Function(self.VS) self.drhos = self.dsol.split()[:2**self.dim] self.dUs = self.dsol.split()[2**self.dim:] # # These are the values of rho and U themselves (not their # symmetrized versions) on all subdomains of the original # domain. # if not hasattr(self, 'rhosds'): self.rhosds = matmul(self.eomat, self.irhos) # self.Usds is a list of nligands lists. Sublist i is of # length 2**dim and lists the value of ligand i on each of the # 2**dim subdomains. # if not hasattr(self, 'Usds'): self.Usds = [ matmul(self.eomat, self.iUs[i * 2**self.dim:(i + 1) * 2**self.dim]) for i in range(self.nligands) ] # # assemble RHS (for each time point, but compile only once) # if not hasattr(self, 'rho_terms'): self.sigma = self.params['sigma'] self.s2 = self.sigma * self.sigma / 2 self.rho_min = self.params['rho_min'] self.rhopen = self.params['rhopen'] self.grhopen = self.params['grhopen'] # # Compute fluxes on subdomains. # Vsds is a list of length 2**dim, the value of V on each # subdomain. # self.Vsds = [] for Usd, rhosd in zip(zip(*self.Usds), self.rhosds): self.Vsds.append(self.V(Usd, rhosd)) # # I may need to adjust the signs of the subdomain vs by # the symmetries of the combinations # self.vsds = [ -ufl.grad(Vsd) - (self.s2 * ufl.grad(rhosd) / ufl.max_value(rhosd, self.rho_min)) for Vsd, rhosd in zip(self.Vsds, self.rhosds) ] self.fluxsds = [ vsd * rhosd for vsd, rhosd in zip(self.vsds, self.rhosds) ] self.vnsds = [ ufl.max_value(ufl.dot(vsd, self.n), 0) for vsd in self.vsds ] self.facet_fluxsds = [ (vnsd('+') * ufl.max_value(rhosd('+'), 0.0) - vnsd('-') * ufl.max_value(rhosd('-'), 0.0)) for vnsd, rhosd in zip(self.vnsds, self.rhosds) ] # # Now combine the subdomain fluxes to get the fluxes for # the symmetrized functions # self.fluxs = matmul((2.0**-self.dim) * self.eomat, self.fluxsds) self.facet_fluxs = matmul((2.0**-self.dim) * self.eomat, self.facet_fluxsds) self.rho_flux_jump = vectotal([ -facet_flux * ufl.jump(wrho) * self.dS for facet_flux, wrho in zip(self.facet_fluxs, self.wrhos) ]) self.rho_grad_move = vectotal([ ufl.dot(flux, ufl.grad(wrho)) * self.dx for flux, wrho in zip(self.fluxs, self.wrhos) ]) self.rho_penalty = vectotal([ -(self.rhopen * self.degree**2 / self.havg) * ufl.dot(ufl.jump(rho, self.n), ufl.jump(wrho, self.n)) * self.dS for rho, wrho in zip(self.irhos, self.wrhos) ]) self.grho_penalty = vectotal([ -self.grhopen * self.degree**2 * (ufl.jump(ufl.grad(rho), self.n) * ufl.jump(ufl.grad(wrho), self.n)) * self.dS for rho, wrho in zip(self.irhos, self.wrhos) ]) self.rho_terms = (self.rho_flux_jump + self.rho_grad_move + self.rho_penalty + self.grho_penalty) if not hasattr(self, 'U_terms'): self.U_min = self.params['U_min'] self.Upen = self.params['Upen'] self.gUpen = self.params['gUpen'] self.U_decay = 0.0 self.U_secretion = 0.0 self.jump_gUw = 0.0 self.U_diffusion = 0.0 self.U_penalty = 0.0 self.gU_penalty = 0.0 for j, lig in enumerate(self.ligands.ligands()): sl = slice(j * 2**self.dim, (j + 1) * 2**self.dim) self.U_decay += -lig.gamma * sum([ iUi * wUi * self.dx for iUi, wUi in zip(self.iUs[sl], self.wUs[sl]) ]) self.U_secretion += lig.s * sum([ rho * wU * self.dx for rho, wU in zip(self.irhos, self.wUs[sl]) ]) self.jump_gUw += lig.D * sum([ ufl.jump(wU * ufl.grad(U), self.n) * self.dS for wU, U in zip(self.wUs[sl], self.iUs[sl]) ]) self.U_diffusion += -lig.D * sum([ ufl.dot(ufl.grad(U), ufl.grad(wU)) * self.dx for U, wU in zip(self.iUs[sl], self.wUs[sl]) ]) self.U_penalty += -self.Upen * self.degree**2 * sum([ (1.0 / self.havg) * ufl.dot(ufl.jump(U, self.n), ufl.jump(wU, self.n)) * self.dS for U, wU in zip(self.iUs[sl], self.wUs[sl]) ]) self.gU_penalty += -self.gUpen * self.degree**2 * sum([ ufl.jump(ufl.grad(U), self.n) * ufl.jump(ufl.grad(wU), self.n) * self.dS for U, wU in zip(self.iUs[sl], self.wUs[sl]) ]) self.U_terms = ( # decay and secretion self.U_decay + self.U_secretion + # diffusion self.jump_gUw + self.U_diffusion + # penalties (to enforce continuity) self.U_penalty + self.gU_penalty) if not hasattr(self, 'all_terms'): self.all_terms = self.rho_terms + self.U_terms if not hasattr(self, 'J_terms'): self.J_terms = fe.derivative(self.all_terms, self.sol)
def setup_problem(self, debug=False): # # assemble the matrix, if necessary (once for all time points) # if not hasattr(self, 'A'): drho_integral = vectotal( [tdrho*wrho*self.dx for tdrho,wrho in zip(self.tdrhos, self.wrhos)] ) dU_integral = vectotal( [tdU*wU*self.dx for tdU,wU in zip(self.tdUs, self.wUs) ] ) self.A = fe.assemble(drho_integral + dU_integral) for bc in self.bcs: bc.apply(self.A) # if self.solver_type == 'lu': # self.solver = fe.LUSolver( # self.A, # ) # self.solver.parameters['reuse_factorization'] = True # else: # self.solver = fe.KrylovSolver( # self.A, # self.solver_type, # self.preconditioner_type # ) self.dsol = Function(self.VS) self.drhos = self.dsol.split()[: 2**self.dim] self.dUs = self.dsol.split()[2**self.dim :] # # These are the values of rho and U themselves (not their # symmetrized versions) on all subdomains of the original # domain. # if not hasattr(self, 'rhosds'): self.rhosds = matmul(self.eomat, self.irhos) if not hasattr(self, 'Usds'): self.Usds = matmul(self.eomat, self.iUs) # # assemble RHS (for each time point, but compile only once) # if not hasattr(self, 'rho_terms'): self.sigma = self.params['sigma'] self.s2 = self.sigma * self.sigma / 2 self.rho_min = self.params['rho_min'] self.rhopen = self.params['rhopen'] self.grhopen = self.params['grhopen'] # # Compute fluxes on subdomains. # self.Vsds = [self.V(Usd, rhosd) for Usd,rhosd in zip(self.Usds, self.rhosds)] # # I may need to adjust the signs of the subdomain vs by # the symmetries of the combinations # self.vsds = [-ufl.grad(Vsd) - ( self.s2*ufl.grad(rhosd)/ufl.max_value(rhosd, self.rho_min) ) for Vsd,rhosd in zip(self.Vsds, self.rhosds)] self.fluxsds = [vsd * rhosd for vsd,rhosd in zip(self.vsds, self.rhosds)] self.vnsds = [ufl.max_value(ufl.dot(vsd, self.n), 0) for vsd in self.vsds] self.facet_fluxsds = [( vnsd('+')*ufl.max_value(rhosd('+'), 0.0) - vnsd('-')*ufl.max_value(rhosd('-'), 0.0) ) for vnsd,rhosd in zip(self.vnsds, self.rhosds)] # # Now combine the subdomain fluxes to get the fluxes for # the symmetrized functions # self.fluxs = matmul((2.0**-self.dim)*self.eomat, self.fluxsds) self.facet_fluxs = matmul((2.0**-self.dim)*self.eomat, self.facet_fluxsds) self.rho_flux_jump = vectotal( [-facet_flux*ufl.jump(wrho)*self.dS for facet_flux,wrho in zip(self.facet_fluxs, self.wrhos)] ) self.rho_grad_move = vectotal( [ufl.dot(flux, ufl.grad(wrho))*self.dx for flux,wrho in zip(self.fluxs, self.wrhos)] ) self.rho_penalty = vectotal( [-(self.rhopen * self.degree**2 / self.havg) * ufl.dot(ufl.jump(rho, self.n), ufl.jump(wrho, self.n)) * self.dS for rho,wrho in zip(self.irhos, self.wrhos)] ) self.grho_penalty = vectotal( [-self.grhopen * self.degree**2 * (ufl.jump(ufl.grad(rho), self.n) * ufl.jump(ufl.grad(wrho), self.n)) * self.dS for rho,wrho in zip(self.irhos, self.wrhos)] ) self.rho_terms = ( self.rho_flux_jump + self.rho_grad_move + self.rho_penalty + self.grho_penalty ) if not hasattr(self, 'U_terms'): self.U_min = self.params['U_min'] self.gamma = self.params['gamma'] self.s = self.params['s'] self.D = self.params['D'] self.Upen = self.params['Upen'] self.gUpen = self.params['gUpen'] self.U_decay = vectotal( [-self.gamma * U * wU * self.dx for U,wU in zip(self.iUs, self.wUs)] ) self.U_secretion = vectotal( [self.s * rho * wU * self.dx for rho, wU in zip(self.irhos, self.wUs)] ) self.jump_gUw = vectotal( [self.D * ufl.jump(wU * ufl.grad(U), self.n) * self.dS for wU, U in zip(self.wUs, self.iUs) ] ) self.U_diffusion = vectotal( [-self.D * ufl.dot(ufl.grad(U), ufl.grad(wU))*self.dx for U,wU in zip(self.iUs, self.wUs) ] ) self.U_penalty = vectotal( [-(self.Upen * self.degree**2 / self.havg) * ufl.dot(ufl.jump(U, self.n), ufl.jump(wU, self.n))*self.dS for U,wU in zip(self.iUs, self.wUs) ] ) self.gU_penalty = vectotal( [-self.gUpen * self.degree**2 * ufl.jump(ufl.grad(U), self.n) * ufl.jump(ufl.grad(wU), self.n) * self.dS for U,wU in zip(self.iUs, self.wUs) ] ) self.U_terms = ( # decay and secretion self.U_decay + self.U_secretion + # diffusion self.jump_gUw + self.U_diffusion + # penalties (to enforce continuity) self.U_penalty + self.gU_penalty ) if not hasattr(self, 'all_terms'): self.all_terms = self.rho_terms + self.U_terms if not hasattr(self, 'J_terms'): self.J_terms = fe.derivative(self.all_terms, self.sol)
def setup_problem(self, t, debug=False): self.set_time(t) # # assemble the matrix, if necessary (once for all time points) # if not hasattr(self, 'A'): logVARIABLE('making matrix A') self.drho_integral = sum([ tdrho * wrho * self.dx for tdrho, wrho in zip(self.tdrhos, self.wrhos) ]) self.dU_integral = sum( [tdU * wU * self.dx for tdU, wU in zip(self.tdUs, self.wUs)]) logVARIABLE('assembling A') self.A = fe.PETScMatrix() logVARIABLE('self.A', self.A) fe.assemble(self.drho_integral + self.dU_integral, tensor=self.A) logVARIABLE('A assembled. Applying BCs') pA = fe.as_backend_type(self.A).mat() Adiag = pA.getDiagonal() logVARIABLE('Adiag.array', Adiag.array) # self.A = fe.assemble(self.drho_integral + self.dU_integral + # self.dP_integral) for bc in self.bcs: bc.apply(self.A) Adiag = pA.getDiagonal() logVARIABLE('Adiag.array', Adiag.array) self.dsol = Function(self.VS) dsolsplit = self.dsol.split() self.drhos, self.dUs = (dsolsplit[:2**self.dim], dsolsplit[2**self.dim:]) # # assemble RHS (for each time point, but compile only once) # # # These are the values of rho and U themselves (not their # symmetrized versions) on all subdomains of the original # domain. # if not hasattr(self, 'rhosds'): self.rhosds = matmul(self.eomat, self.irhos) # self.Usds is a list of nligands lists. Sublist i is of # length 2**dim and lists the value of ligand i on each of the # 2**dim subdomains. # if not hasattr(self, 'Usds'): self.Usds = [ matmul(self.eomat, self.iUs[i * 2**self.dim:(i + 1) * 2**self.dim]) for i in range(self.nligands) ] if not hasattr(self, 'rho_terms'): logVARIABLE('making rho_terms') self.sigma = self.iparams['sigma'] self.s2 = self.sigma * self.sigma / 2 self.rhomin = self.iparams['rhomin'] self.rhopen = self.iparams['rhopen'] self.grhopen = self.iparams['grhopen'] # # Compute fluxes on subdomains. # Vsds is a list of length 2**dim, the value of V on each # subdomain. # self.Vsds = [] for Usd, rhosd in zip(zip(*self.Usds), self.rhosds): self.Vsds.append(self.V(Usd, ufl.max_value(rhosd, self.rhomin))) self.vsds = [ -ufl.grad(Vsd) - (self.s2 * ufl.grad(rhosd) / ufl.max_value(rhosd, self.rhomin)) for Vsd, rhosd in zip(self.Vsds, self.rhosds) ] self.fluxsds = [ vsd * rhosd for vsd, rhosd in zip(self.vsds, self.rhosds) ] self.vnsds = [ ufl.max_value(ufl.dot(vsd, self.n), 0) for vsd in self.vsds ] self.facet_fluxsds = [ (vnsd('+') * ufl.max_value(rhosd('+'), 0.0) - vnsd('-') * ufl.max_value(rhosd('-'), 0.0)) for vnsd, rhosd in zip(self.vnsds, self.rhosds) ] # # Now combine the subdomain fluxes to get the fluxes for # the symmetrized functions # self.fluxs = matmul((2.0**-self.dim) * self.eomat, self.fluxsds) self.facet_fluxs = matmul((2.0**-self.dim) * self.eomat, self.facet_fluxsds) self.rho_flux_jump = sum([ -facet_flux * ufl.jump(wrho) * self.dS for facet_flux, wrho in zip(self.facet_fluxs, self.wrhos) ]) self.rho_grad_move = sum([ ufl.dot(flux, ufl.grad(wrho)) * self.dx for flux, wrho in zip(self.fluxs, self.wrhos) ]) self.rho_penalty = sum([ -(self.degree**2 / self.havg) * ufl.dot(ufl.jump(rho, self.n), ufl.jump(self.rhopen * wrho, self.n)) * self.dS for rho, wrho in zip(self.irhos, self.wrhos) ]) self.grho_penalty = sum([ self.degree**2 * (ufl.jump(ufl.grad(rho), self.n) * ufl.jump(ufl.grad(-self.grhopen * wrho), self.n)) * self.dS for rho, wrho in zip(self.irhos, self.wrhos) ]) self.rho_terms = (self.rho_flux_jump + self.rho_grad_move + self.rho_penalty + self.grho_penalty) logVARIABLE('rho_terms made') if not hasattr(self, 'U_terms'): logVARIABLE('making U_terms') self.Umin = self.iparams['Umin'] self.Upen = self.iparams['Upen'] self.gUpen = self.iparams['gUpen'] self.U_decay = 0.0 self.U_secretion = 0.0 self.jump_gUw = 0.0 self.U_diffusion = 0.0 self.U_penalty = 0.0 self.gU_penalty = 0.0 for j, lig in enumerate(self.iligands.ligands()): sl = slice(j * 2**self.dim, (j + 1) * 2**self.dim) self.U_decay += sum([ -lig.gamma * iUi * wUi * self.dx for iUi, wUi in zip(self.iUs[sl], self.wUs[sl]) ]) self.U_secretion += sum([ lig.s * rho * wU * self.dx for rho, wU in zip(self.irhos, self.wUs[sl]) ]) self.jump_gUw += sum([ ufl.jump(lig.D * wU * ufl.grad(U), self.n) * self.dS for wU, U in zip(self.wUs[sl], self.iUs[sl]) ]) self.U_diffusion += sum([ -lig.D * ufl.dot(ufl.grad(U), ufl.grad(wU)) * self.dx for U, wU in zip(self.iUs[sl], self.wUs[sl]) ]) self.U_penalty += sum([ (-self.degree**2 / self.havg) * ufl.dot(ufl.jump(U, self.n), ufl.jump(self.Upen * wU, self.n)) * self.dS for U, wU in zip(self.iUs[sl], self.wUs[sl]) ]) self.gU_penalty += sum([ -self.degree**2 * ufl.jump(ufl.grad(U), self.n) * ufl.jump(ufl.grad(self.gUpen * wU), self.n) * self.dS for U, wU in zip(self.iUs[sl], self.wUs[sl]) ]) self.U_terms = ( # decay and secretion self.U_decay + self.U_secretion + # diffusion self.jump_gUw + self.U_diffusion + # penalties (to enforce continuity) self.U_penalty + self.gU_penalty) logVARIABLE('U_terms made') if not hasattr(self, 'all_terms'): logVARIABLE('making all_terms') self.all_terms = self.rho_terms + self.U_terms if not hasattr(self, 'J_terms'): logVARIABLE('making J_terms') self.J_terms = fe.derivative(self.all_terms, self.sol)
def setup_problem(self, t, debug=False): self.set_time(t) # # assemble the matrix, if necessary (once for all time points) # if not hasattr(self, 'A'): self.drho_integral = self.tdrho * self.wrho * self.dx self.dU_integral = sum([ tdUi * wUi * self.dx for tdUi, wUi in zip(self.tdUs, self.wUs) ]) logVARIABLE('assembling A') self.A = PETScMatrix() logVARIABLE('self.A', self.A) fe.assemble(self.drho_integral + self.dU_integral, tensor=self.A) logVARIABLE('A assembled. Applying BCs') self.dsol = Function(self.VS) dsolsplit = self.dsol.split() self.drho, self.dUs = dsolsplit[0], dsolsplit[1:] # # assemble RHS (for each time point, but compile only once) # if not hasattr(self, 'rho_terms'): self.sigma = self.iparams['sigma'] self.s2 = self.sigma * self.sigma / 2 self.rhomin = self.iparams['rhomin'] self.rhopen = self.iparams['rhopen'] self.grhopen = self.iparams['grhopen'] self.v = -ufl.grad( self.V(self.iUs, ufl.max_value(self.irho, self.rhomin)) - (self.s2 * ufl.grad(self.irho) / ufl.max_value(self.irho, self.rhomin))) self.flux = self.v * self.irho self.vn = ufl.max_value(ufl.dot(self.v, self.n), 0) self.facet_flux = ufl.jump(self.vn * ufl.max_value(self.irho, 0.0)) self.rho_flux_jump = -self.facet_flux * ufl.jump( self.wrho) * self.dS self.rho_grad_move = ufl.dot(self.flux, ufl.grad( self.wrho)) * self.dx self.rho_penalty = -( (self.degree**2 / self.havg) * ufl.dot(ufl.jump(self.irho, self.n), ufl.jump(self.rhopen * self.wrho, self.n)) * self.dS) self.grho_penalty = -( self.degree**2 * (ufl.jump(ufl.grad(self.irho), self.n) * ufl.jump( ufl.grad(self.grhopen * self.wrho), self.n)) * self.dS) self.rho_terms = (self.rho_flux_jump + self.rho_grad_move + self.rho_penalty + self.grho_penalty) if not hasattr(self, 'U_terms'): self.Umin = self.iparams['Umin'] self.Upen = self.iparams['Upen'] self.gUpen = self.iparams['gUpen'] self.U_decay = sum([ -lig.gamma * iUi * wUi * self.dx for lig, iUi, wUi in zip( self.iligands.ligands(), self.iUs, self.wUs) ]) self.U_secretion = sum([ lig.s * self.irho * wUi * self.dx for lig, wUi in zip(self.iligands.ligands(), self.wUs) ]) self.jump_gUw = sum([ ufl.jump(lig.D * wUi * ufl.grad(iUi), self.n) * self.dS for lig, wUi, iUi in zip(self.iligands.ligands(), self.wUs, self.iUs) ]) self.U_diffusion = sum([ -lig.D * ufl.dot(ufl.grad(iUi), ufl.grad(wUi)) * self.dx for lig, iUi, wUi in zip(self.iligands.ligands(), self.iUs, self.wUs) ]) self.U_penalty = sum([ -(self.degree**2 / self.havg) * ufl.dot( ufl.jump(iUi, self.n), ufl.jump(self.Upen * wUi, self.n)) * self.dS for iUi, wUi in zip(self.iUs, self.wUs) ]) self.gU_penalty = sum([ -self.degree**2 * ufl.jump(ufl.grad(iUi), self.n) * ufl.jump(ufl.grad(self.gUpen * wUi), self.n) * self.dS for iUi, wUi in zip(self.iUs, self.wUs) ]) self.U_terms = ( # decay and secretion self.U_decay + self.U_secretion + # diffusion self.jump_gUw + self.U_diffusion + # penalties (to enforce continuity) self.U_penalty + self.gU_penalty) if not hasattr(self, 'all_terms'): self.all_terms = self.rho_terms + self.U_terms if not hasattr(self, 'J_terms'): self.J_terms = fe.derivative(self.all_terms, self.sol)
def setup_problem(self, debug=False): # # assemble the matrix, if necessary (once for all time points) # if not hasattr(self, 'A'): drho_integral = self.tdrho * self.wrho * self.dx dU_integral = self.tdU * self.wU * self.dx self.A = fe.assemble(drho_integral + dU_integral) # if self.solver_type == 'lu': # self.solver = fe.LUSolver( # self.A, # method=self.solver_type # ) # self.solver.parameters['reuse_factorization'] = True # else: # self.solver = fe.KrylovSolver( # self.A, # self.solver_type, # self.preconditioner_type # ) self.dsol = Function(self.VS) self.drho, self.dU = self.dsol.sub(0), self.dsol.sub(1) # # assemble RHS (has to be done for each time point) # if not hasattr(self, 'rho_terms'): self.sigma = self.params['sigma'] self.s2 = self.sigma * self.sigma / 2 self.rho_min = self.params['rho_min'] self.rhopen = self.params['rhopen'] self.grhopen = self.params['grhopen'] self.v = -ufl.grad(self.V(self.iU, self.irho)) self.flux = self.v * self.irho self.vn = ufl.max_value(ufl.dot(self.v, self.n), 0) self.facet_flux = (self.vn('+') * self.irho('+') - self.vn('-') * self.irho('-')) self.rho_flux_jump = -self.facet_flux * ufl.jump( self.wrho) * self.dS self.rho_grad_move = ufl.dot(self.flux, ufl.grad( self.wrho)) * self.dx self.rho_penalty = -( (self.rhopen * self.degree**2 / self.havg) * ufl.dot( ufl.jump(self.irho, self.n), ufl.jump(self.wrho, self.n)) * self.dS) # self.facet_flux = ( # self.vn('+')*self.rho('+') - self.vn('-')*self.rho('-') # ) # self.rho_flux_jump = -self.facet_flux*ufl.jump(self.wrho)*self.dS # self.rho_grad_move = ufl.dot(self.flux, ufl.grad(self.wrho))*self.dx self.jump_grhow = ( self.s2 * ufl.jump(self.wrho * ufl.grad(self.irho), self.n) * self.dS) self.rho_diffusion = -self.s2 * ufl.dot(ufl.grad( self.irho), ufl.grad(self.wrho)) * self.dx # self.rho_penalty = -( # (self.rhopen * self.degree**2 / self.havg) * # ufl.dot(ufl.jump(self.rho, self.n), # ufl.jump(self.wrho, self.n)) * self.dS # ) self.grho_penalty = -(self.grhopen * self.degree**2 * (ufl.jump(ufl.grad(self.irho), self.n) * ufl.jump(ufl.grad(self.wrho), self.n)) * self.dS) self.rho_terms = ( # advection terms self.rho_flux_jump + self.rho_grad_move + # diffusive terms self.rho_diffusion + self.jump_grhow + # penalty terms (to enforce continuity) self.rho_penalty + self.grho_penalty) if not hasattr(self, 'U_terms'): self.U_min = self.params['U_min'] self.gamma = self.params['gamma'] self.s = self.params['s'] self.D = self.params['D'] self.Upen = self.params['Upen'] self.gUpen = self.params['gUpen'] self.U_decay = -self.gamma * self.iU * self.wU * self.dx self.U_secretion = self.s * self.irho * self.wU * self.dx self.jump_gUw = (self.D * ufl.jump(self.wU * ufl.grad(self.iU), self.n) * self.dS) self.U_diffusion = -self.D * ufl.dot(ufl.grad(self.iU), ufl.grad(self.wU)) * self.dx self.U_penalty = -( (self.Upen * self.degree**2 / self.havg) * ufl.dot(ufl.jump(self.iU, self.n), ufl.jump(self.wU, self.n)) * self.dS) self.gU_penalty = -(self.gUpen * self.degree**2 * (ufl.jump(ufl.grad(self.iU), self.n) * ufl.jump(ufl.grad(self.wU), self.n)) * self.dS) self.U_terms = ( # decay and secretion self.U_decay + self.U_secretion + # diffusion self.jump_gUw + self.U_diffusion + # penalties (to enforce continuity) self.U_penalty + self.gU_penalty) if not hasattr(self, 'all_terms'): self.all_terms = self.rho_terms + self.U_terms if not hasattr(self, 'all_terms'): self.all_terms = self.rho_terms + self.U_terms if not hasattr(self, 'J_terms'): self.J_terms = fe.derivative(self.all_terms, self.sol)
def setup_problem(self, debug=False): # # assemble the matrix, if necessary (once for all time points) # if not hasattr(self, 'A'): self.drho_integral = self.tdrho * self.wrho * self.dx self.dU_integral = self.tdU * self.wU * self.dx self.A = fe.assemble(self.drho_integral + self.dU_integral) # if self.solver_type == 'lu': # self.solver = fe.LUSolver( # self.A, # ) # self.solver.parameters['reuse_factorization'] = True # else: # self.solver = fe.KrylovSolver( # self.A, # self.solver_type, # self.preconditioner_type # ) # self.solver.parameters.add('linear_solver', self.solver_type) # kparams = fe.Parameters('krylov_solver') # kparams.add('report', True) # kparams.add('nonzero_initial_guess', True) # self.solver.parameters.add(kparams) # lparams = fe.Parameters('lu_solver') # lparams.add('report', True) # lparams.add('reuse_factorization', True) # lparams.add('verbose', True) # self.solver.parameters.add(lparams) self.dsol = Function(self.VS) self.drho, self.dU = self.dsol.sub(0), self.dsol.sub(1) # # assemble RHS (for each time point, but compile only once) # if not hasattr(self, 'rho_terms'): self.sigma = self.params['sigma'] self.s2 = self.sigma * self.sigma / 2 self.rho_min = self.params['rho_min'] self.rhopen = self.params['rhopen'] self.grhopen = self.params['grhopen'] self.v = -ufl.grad(self.V(self.iU, self.irho)) - ( self.s2 * ufl.grad(self.irho) / ufl.max_value(self.irho, self.rho_min)) self.flux = self.v * self.irho self.vn = ufl.max_value(ufl.dot(self.v, self.n), 0) self.facet_flux = ( self.vn('+') * ufl.max_value(self.irho('+'), 0.0) - self.vn('-') * ufl.max_value(self.irho('-'), 0.0)) self.rho_flux_jump = -self.facet_flux * ufl.jump( self.wrho) * self.dS self.rho_grad_move = ufl.dot(self.flux, ufl.grad( self.wrho)) * self.dx self.rho_penalty = -( (self.rhopen * self.degree**2 / self.havg) * ufl.dot( ufl.jump(self.irho, self.n), ufl.jump(self.wrho, self.n)) * self.dS) self.grho_penalty = -(self.grhopen * self.degree**2 * (ufl.jump(ufl.grad(self.irho), self.n) * ufl.jump(ufl.grad(self.wrho), self.n)) * self.dS) self.rho_terms = (self.rho_flux_jump + self.rho_grad_move + self.rho_penalty + self.grho_penalty) if not hasattr(self, 'U_terms'): self.U_min = self.params['U_min'] self.gamma = self.params['gamma'] self.s = self.params['s'] self.D = self.params['D'] self.Upen = self.params['Upen'] self.gUpen = self.params['gUpen'] self.U_decay = -self.gamma * self.iU * self.wU * self.dx self.U_secretion = self.s * self.irho * self.wU * self.dx self.jump_gUw = (self.D * ufl.jump(self.wU * ufl.grad(self.iU), self.n) * self.dS) self.U_diffusion = -self.D * ufl.dot(ufl.grad(self.iU), ufl.grad(self.wU)) * self.dx self.U_penalty = -( (self.Upen * self.degree**2 / self.havg) * ufl.dot(ufl.jump(self.iU, self.n), ufl.jump(self.wU, self.n)) * self.dS) self.gU_penalty = -(self.gUpen * self.degree**2 * (ufl.jump(ufl.grad(self.iU), self.n) * ufl.jump(ufl.grad(self.wU), self.n)) * self.dS) self.U_terms = ( # decay and secretion self.U_decay + self.U_secretion + # diffusion self.jump_gUw + self.U_diffusion + # penalties (to enforce continuity) self.U_penalty + self.gU_penalty) if not hasattr(self, 'all_terms'): self.all_terms = self.rho_terms + self.U_terms if not hasattr(self, 'J_terms'): self.J_terms = fe.derivative(self.all_terms, self.sol)
def boundary_R(x, on_boundary): return on_boundary and near(x[0], 1) bc_R = DirichletBC(V, p_R, boundary_R) bcs = [bc_L, bc_R] # Defining variational problem p = TrialFunction(V) v = TestFunction(V) d = 2 I = Identity(d) x, y = SpatialCoordinate(mesh) M = max_value(Constant(0.10), exp(-(10 * y - 1.0 * sin(10 * x) - 5.0)**2)) K = M * I a = dot(K * grad(p), grad(v)) * dx f1 = as_vector((-2 * x, 0)) f = nabla_div(dot(-K, f1)) L = inner(f, v) * dx # Computing solutions p = Function(V) solve(a == L, p, bcs) u_bar = -K * grad(p) # Projecting the Velocity profile W = VectorFunctionSpace(mesh, 'P', 1) u_bar1 = project(u_bar, W)