Introduction
Writing a transformer
Here is an example transformer (identical to the DDM1 transformer implemented in this package):
[1]:
from dune.ufl import Space, DirichletBC
import ufl
import ddfem
space = Space(2, dimRange=1)
domain = [[-1.25,-1.25],[1.25,1.25],[50,50]]
h = 2.5/50
epsilon = 4.5*h # !!!
print(f"h={h},epsilon={epsilon}")
ball = ddfem.geometry.Ball(radius=1, name="full", epsilon=epsilon)
D = lambda x: 0.1 - 0.05*ufl.dot(x,x) # !!!
b = lambda x: 3*ufl.as_vector([x[1],-x[0]]) # !!!
c = lambda x: 0.01 # !!!
f = lambda x: 0.1*ufl.as_vector([1 - ufl.dot(x,x)]) # !!!
g = lambda x: ufl.as_vector([ufl.sin(ufl.pi * x[0]) * ufl.sin(ufl.pi * x[1])]) # !!!
class Model:
def S_i(t, x, U, DU):
return f(x) - c(x) * U
def F_c(t, x, U):
return ufl.outer(U, b(x))
def F_v(t, x, U, DU):
return D(x) * DU
boundary = {"full": ddfem.boundary.BndValue(g)}
outFactor_i = 0.1
outFactor_e = 3
h=0.05,epsilon=0.225
[2]:
@ddfem.transformers.transformer
def DDM1(Model):
class DDModel(Model):
def S_e_source(t, x, U, DU):
return DDModel.phi(x) * Model.S_e(t, x, U, DDModel.sigma(t, x, U, DU))
def S_e_convection(t, x, U, DU):
return -DDModel.BT.BndFlux_cExt(t, x, U)
def S_outside(t, x, U, DU):
return -(
DDModel.BT.jumpV(t, x, U) * (1 - DDModel.phi(x)) / (DDModel.epsilon**3)
)
def S_i_source(t, x, U, DU):
return DDModel.phi(x) * Model.S_i(t, x, U, DDModel.sigma(t, x, U, DU))
def S_i_diffusion(t, x, U, DU):
if DDModel.BT.BndFlux_vExt is not None:
diffusion = DDModel.BT.BndFlux_vExt(t, x, U, DU)
else:
diffusion = ufl.zero(U.ufl_shape)
return diffusion
def F_c(t, x, U):
return DDModel.phi(x) * Model.F_c(t, x, U)
def F_v(t, x, U, DU):
return DDModel.phi(x) * Model.F_v(t, x, U, DDModel.sigma(t, x, U, DU))
return DDModel
[3]:
ModelDDM1 = DDM1(Model, ball)
uh = ddfem.solve(ddfem.model2ufl(ModelDDM1, space, DirichletBC=DirichletBC), domain)
ddfem.plotSolution(ball,uh,figsize=[10,10])
TODO: add information on @ddfem.transformers.transformer decorator