ddfem 0.9.0__py3-none-any.whl → 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. ddfem/__init__.py +0 -4
  2. ddfem/base_model.py +200 -0
  3. ddfem/boundary.py +3 -12
  4. ddfem/geometry/__init__.py +3 -3
  5. ddfem/geometry/arc.py +8 -10
  6. ddfem/geometry/box.py +8 -7
  7. ddfem/geometry/circle.py +39 -0
  8. ddfem/geometry/domain.py +4 -16
  9. ddfem/geometry/domain_dune.py +0 -16
  10. ddfem/geometry/helpers.py +12 -19
  11. ddfem/geometry/pie.py +7 -7
  12. ddfem/geometry/primitive_base.py +70 -129
  13. ddfem/geometry/vesica.py +6 -7
  14. ddfem/model2ufl.py +4 -10
  15. ddfem/transformers/DDM1.py +68 -10
  16. ddfem/transformers/Fitted.py +12 -22
  17. ddfem/transformers/Mix0.py +64 -10
  18. ddfem/transformers/NNS.py +72 -11
  19. ddfem/transformers/NS.py +79 -14
  20. ddfem/transformers/__init__.py +0 -1
  21. ddfem/transformers/transformer_base.py +15 -102
  22. {ddfem-0.9.0.dist-info → ddfem-1.0.0.dist-info}/METADATA +1 -2
  23. ddfem-1.0.0.dist-info/RECORD +27 -0
  24. ddfem/examples/__init__.py +0 -0
  25. ddfem/examples/advection_diffusion.py +0 -74
  26. ddfem/examples/beam.py +0 -147
  27. ddfem/examples/cahn_hilliard.py +0 -67
  28. ddfem/examples/chemical_reaction.py +0 -88
  29. ddfem/examples/constant.py +0 -46
  30. ddfem/examples/five_circle_flat.py +0 -197
  31. ddfem/examples/forchheimer.py +0 -48
  32. ddfem/examples/hyperelasticity.py +0 -88
  33. ddfem/examples/linear_elasticity.py +0 -45
  34. ddfem/examples/plaplace.py +0 -29
  35. ddfem/examples/single_circle.py +0 -135
  36. ddfem/examples/triple_circle.py +0 -217
  37. ddfem/examples/triple_circle_beam.py +0 -208
  38. ddfem/geometry/ball.py +0 -24
  39. ddfem/geometry/plane.py +0 -20
  40. ddfem-0.9.0.dist-info/RECORD +0 -41
  41. {ddfem-0.9.0.dist-info → ddfem-1.0.0.dist-info}/WHEEL +0 -0
  42. {ddfem-0.9.0.dist-info → ddfem-1.0.0.dist-info}/licenses/LICENSE +0 -0
  43. {ddfem-0.9.0.dist-info → ddfem-1.0.0.dist-info}/top_level.txt +0 -0
@@ -1,67 +0,0 @@
1
- from dune.ufl import Constant
2
- from ufl import as_tensor, as_vector, dot, grad, inner, zero
3
-
4
- from ddfem.boundary import BndFlux_c, BndFlux_v, BndValue
5
-
6
-
7
- def chModel():
8
- class CHModel:
9
- dimRange = [1, 1]
10
-
11
- M = Constant(1, name="M")
12
- lmbda = Constant(1.0e-02, name="lmbda") # surface parameter
13
- dt = Constant(5.0e-06, name="dt") # time step
14
- theta = Constant(
15
- 0.5, name="theta"
16
- ) # theta=1 -> backward Euler, theta=0.5 -> Crank-Nicolson
17
-
18
- u_h_n = None
19
- Du_h_n = None
20
-
21
- def setup(u_h, DDMModel):
22
- CHModel.u_h_n = u_h.copy()
23
- CHModel.Du_h_n = lambda t, x: DDMModel.sigma(
24
- t, x, CHModel.u_h_n, grad(CHModel.u_h_n)
25
- )
26
-
27
- def energy(U, DU):
28
- C, MU = as_vector([U[0]]), as_vector([U[1]])
29
- DC, DMU = as_tensor([DU[0, :]]), as_tensor([DU[1, :]])
30
-
31
- f = 100 * dot(C, C) * dot(as_vector([1]) - C, as_vector([1]) - C)
32
-
33
- return CHModel.lmbda / 2 * inner(DC, DC) + f
34
-
35
- def F_v(t, x, U, DU):
36
- C, MU = as_vector([U[0]]), as_vector([U[1]])
37
- DC, DMU = as_tensor([DU[0, :]]), as_tensor([DU[1, :]])
38
- c_h_n, mu_h_n = as_vector([CHModel.u_h_n[0]]), as_vector([CHModel.u_h_n[1]])
39
- Du_h_n = CHModel.Du_h_n(t, x)
40
- Dc_h_n, Dmu_h_n = as_vector([Du_h_n[0, :]]), as_vector([Du_h_n[1, :]])
41
-
42
- mu_mid = (1.0 - CHModel.theta) * Dmu_h_n + CHModel.theta * DMU
43
- concentration_F_v = CHModel.M * mu_mid
44
- potential_F_v = CHModel.lmbda * DC
45
-
46
- return as_tensor([concentration_F_v[0, :], potential_F_v[0, :]])
47
-
48
- def S_i(t, x, U, DU):
49
- C, MU = as_vector([U[0]]), as_vector([U[1]])
50
- DC, DMU = as_tensor([DU[0, :]]), as_tensor([DU[1, :]])
51
- c_h_n, mu_h_n = as_vector([CHModel.u_h_n[0]]), as_vector([CHModel.u_h_n[1]])
52
-
53
- concentration_S_i = -(C - c_h_n) / CHModel.dt
54
- potential_S_i = (
55
- MU - (200 + 400 * dot(C, C)) * C + as_vector([600 * dot(C, C)])
56
- )
57
-
58
- return as_vector([concentration_S_i[0], potential_S_i[0]])
59
-
60
- def valF_v(t, x, MU, DMU, n):
61
- return zero(2)
62
-
63
- boundary = {
64
- "full": BndFlux_v(valF_v),
65
- }
66
-
67
- return CHModel
@@ -1,88 +0,0 @@
1
- from dune.ufl import Constant
2
- from ufl import as_vector, conditional, dot, grad, outer, zero
3
-
4
- from ddfem.boundary import BndFlux_c, BndFlux_v, BndValue
5
-
6
-
7
- def crModel():
8
- class PotentialModel:
9
- dimRange = 1
10
- outFactor_i = Constant(1, "outFactor")
11
-
12
- def F_v(t, x, U, DU):
13
- return DU
14
-
15
- def S_e(t, x, U, DU):
16
- return as_vector([-1])
17
-
18
- def valD(t, x, U):
19
- return zero(1)
20
-
21
- boundary = {
22
- "full": BndValue(valD),
23
- }
24
-
25
- class ChemModel:
26
- dimRange = 3
27
-
28
- dt = Constant(0.05, "dt")
29
- diff = Constant(1e-3, "diff") # this is about the boundary for stability
30
- # outFactor_i = diff
31
-
32
- P1 = as_vector([-0.25, -0.25]) # midpoint of first source (close to boundary)
33
- P2 = as_vector([0.25, 0.25]) # midpoint of second source (close to boundary)
34
-
35
- u_h_n = None
36
- dpsi_h = None
37
-
38
- def setup(u_h, DDMPotentialModel, psi_h):
39
- ChemModel.u_h_n = u_h.copy(name="u_h_n")
40
- ChemModel.u_h_n.interpolate(zero(ChemModel.dimRange))
41
-
42
- ChemModel.dpsi_h = lambda x: DDMPotentialModel.sigma(
43
- 0, x, psi_h, grad(psi_h)
44
- )
45
-
46
- def f1(x):
47
- q = x - ChemModel.P1
48
- return conditional(dot(q, q) < 0.04**2, 5, 0)
49
-
50
- def f2(x):
51
- q = x - ChemModel.P2
52
- return conditional(dot(q, q) < 0.04**2, 5, 0)
53
-
54
- def f(t, x):
55
- return conditional(
56
- t < 10,
57
- as_vector([ChemModel.f1(x), ChemModel.f2(x), 0]),
58
- as_vector([0, 0, 0]),
59
- )
60
-
61
- def r(U):
62
- return 10 * as_vector([U[0] * U[1], U[0] * U[1], -2 * U[0] * U[1]])
63
-
64
- def F_v(t, x, U, DU):
65
- return ChemModel.diff * DU
66
-
67
- def velocity(x):
68
- return as_vector([-ChemModel.dpsi_h(x)[0, 1], ChemModel.dpsi_h(x)[0, 0]])
69
-
70
- def F_c(t, x, U):
71
- return outer(U, ChemModel.velocity(x))
72
-
73
- def S_i(t, x, U, DU):
74
- return -(U - ChemModel.u_h_n) / ChemModel.dt
75
-
76
- def S_e(t, x, U, DU):
77
- return ChemModel.f(t, x) - ChemModel.r(ChemModel.u_h_n)
78
-
79
- # boundary = {"full": BndValue(lambda t, x, U: zero(3))}
80
-
81
- boundary = {
82
- "full": [
83
- BndFlux_c(lambda t, x, U, n: zero(ChemModel.dimRange)),
84
- BndFlux_v(lambda t, x, U, DU, n: zero(ChemModel.dimRange)),
85
- ]
86
- }
87
-
88
- return PotentialModel, ChemModel
@@ -1,46 +0,0 @@
1
- from dune.ufl import Constant
2
- from ufl import as_vector, conditional, div, dot, exp, grad, inner, sqrt, outer, zero
3
- import ufl
4
- from ddfem.boundary import AFluxBC, DFluxBC, ValueBC
5
-
6
- def CModel(inverted):
7
- withAdv = False
8
-
9
- class Model:
10
- dimRange = 1
11
- stabFactor = Constant(1)
12
-
13
- def initial(x):
14
- return 2
15
-
16
- def exact(t, x):
17
- return as_vector((2+x[0]-x[0],)) # better way of avoiding 'Cannot determine geometric dimension from expression'
18
-
19
- def K(U, DU):
20
- return 1e-2
21
-
22
- def F_v(t, x, U, DU):
23
- return Model.K(U, DU) * DU
24
-
25
- if withAdv:
26
- def F_c(t, x, U):
27
- return outer(U, as_vector([-2,0.5]) )
28
-
29
- if withAdv:
30
- bndFlux = [ AFluxBC( lambda t,x,U,n: Model.F_c(t,x,U)*n ),
31
- DFluxBC( lambda t,x,U,DU,n: Model.F_v(t,x,U,DU)*n ) ]
32
- else:
33
- # this works: bndFlux = DFluxBC( lambda t,x,U,DU,n: zero(U.ufl_shape)
34
- bndFlux = DFluxBC( lambda t,x,U,DU,n: Model.F_v(t,x,U,DU)*n )
35
- boundary = {
36
- # "full": ValueBC( lambda t,x,U: as_vector([2.]) ),
37
- "full": bndFlux
38
- # "sides": ValueBC( lambda t,x,U: as_vector([2.]) ),
39
- # "ends": [AFluxBC( lambda t,x,U,n: Model.F_c(t,x,U)*n ),
40
- # DFluxBC( lambda t,x,U,DU,n: Model.F_v(t,x,U,DU)*n )]
41
- }
42
-
43
- if inverted:
44
- boundary[range(1,5)] = ValueBC( lambda t,x,U: as_vector([2.]) )
45
-
46
- return Model
@@ -1,197 +0,0 @@
1
- import numpy as np
2
-
3
- try:
4
- import pygmsh
5
- except ImportError:
6
- pygmsh = None
7
-
8
- try:
9
- import dune
10
- except ImportError:
11
- print(
12
- """
13
- Example code requires dune to run. To install run
14
- pip install dune-fem
15
- """
16
- )
17
-
18
- from dune.alugrid import aluConformGrid as leafGridView
19
- from dune.fem import adapt, mark, markNeighbors
20
- from dune.fem.function import gridFunction
21
- from dune.fem.space import lagrange
22
- from dune.fem.view import adaptiveLeafGridView
23
- from dune.grid import cartesianDomain
24
- from dune.ufl import Constant, Space
25
- from ufl import SpatialCoordinate, sqrt
26
-
27
- from ddfem import geometry as gm
28
- from ddfem.geometry.domain_dune import DomainDune
29
-
30
-
31
- def getDomain(
32
- initialRefine,
33
- version,
34
- adaptLevels=0,
35
- epsFactor=4.5,
36
- smoothing=None,
37
- *args,
38
- **kwargs,
39
- ):
40
-
41
- gm.SDF.smoothing = smoothing
42
- shiftx, shifty = sqrt(2) * 1e-6, sqrt(3) * 1e-6
43
- domain_range = [[-1.7 + shiftx, -1.3 + shifty], [1.7 + shiftx, 1.3 + shifty]]
44
- initial_gridsize = [170 * 2**initialRefine, 130 * 2**initialRefine]
45
- h = sqrt(
46
- ((domain_range[1][0] - domain_range[0][0]) / initial_gridsize[0]) ** 2
47
- + ((domain_range[1][1] - domain_range[0][1]) / initial_gridsize[1]) ** 2
48
- )
49
-
50
- def get_eps(h):
51
- return Constant(epsFactor * h * 0.5 ** (adaptLevels / 2), "epsilon")
52
-
53
- balls = [
54
- [1, [0, 0], "Center"],
55
- [0.5, [0, 0.8], "TopCut"],
56
- [0.5, [0, -0.8], "BotCut"],
57
- [0.5, [1, 0], "RightAdd"],
58
- [0.5, [-1, 0], "LeftAdd"],
59
- [1.4, [0, 0], "Cutoff"],
60
- ]
61
-
62
- b = [gm.Ball(c[0], c[1], name=c[2]) for c in balls]
63
- # omega = (b[0] - b[1] - b[2] | b[3] | b[4]) & b[5]
64
-
65
- bulk = b[0] - b[1] - b[2] | b[3] | b[4]
66
- bulk.name = "bulk"
67
-
68
- left_cutoff = b[5] | gm.Plane([-1, 0], -0.4)
69
- left_cutoff.name = "left"
70
- right_cutoff = b[5] | gm.Plane([1, 0], -0.4)
71
- right_cutoff.name = "right"
72
-
73
- cutoff = left_cutoff & right_cutoff # b[5]
74
-
75
- omega = bulk & cutoff
76
- omega.name = "full"
77
-
78
- h_max = h * 3
79
- h_min = h / 2
80
- radius = 5
81
-
82
- x = SpatialCoordinate(Space(2))
83
- sdf = omega(x)
84
-
85
- def spacing(x, y, epsilon):
86
- r_min = epsilon.value
87
- r_max = radius * epsilon.value
88
- dist = np.abs(sdf((x, y)))
89
- if dist <= r_min:
90
- return geom.characteristic_length_min
91
- elif dist >= r_max:
92
- return geom.characteristic_length_max
93
- else:
94
- # Linear
95
- m = (geom.characteristic_length_max - geom.characteristic_length_min) / (
96
- r_max - r_min
97
- )
98
- return m * (dist - r_min) + geom.characteristic_length_min
99
-
100
- if version == "cartesian":
101
- domain = cartesianDomain(*domain_range, initial_gridsize)
102
- epsilon = get_eps(h)
103
-
104
- elif version == "fitted":
105
- if pygmsh is None:
106
- raise AttributeError("'fitted' requires install pygmsh")
107
- with pygmsh.occ.Geometry() as geom:
108
- geom.characteristic_length_max = h_max
109
- geom.characteristic_length_min = h_min
110
- epsilon = get_eps(h_min)
111
-
112
- disks = [geom.add_disk([c[1][0], c[1][1], 0.0], c[0]) for c in balls]
113
-
114
- disk_removed1 = geom.boolean_difference(disks[0], disks[1])
115
- disk_removed2 = geom.boolean_difference(disk_removed1, disks[2])
116
-
117
- disk_add = geom.boolean_union([disk_removed2, disks[3], disks[4]])
118
- shape = geom.boolean_intersection([disk_add, disks[5]])
119
-
120
- geom.set_mesh_size_callback(
121
- lambda dim, tag, x, y, z, lc: spacing(x, y, epsilon),
122
- ignore_other_mesh_sizes=True,
123
- )
124
- mesh = geom.generate_mesh()
125
- points, cells = mesh.points, mesh.cells_dict
126
- domain = {
127
- "vertices": points[:, :2].astype(float),
128
- "simplices": cells["triangle"].astype(int),
129
- }
130
-
131
- elif version == "dune_adaptive":
132
- gridsize = [int(j * h / h_max) for j in initial_gridsize]
133
- domain = cartesianDomain(*domain_range, gridsize)
134
-
135
- elif version == "gmsh_adaptive":
136
- if pygmsh is None:
137
- raise AttributeError("'gmsh_adaptive' requires install pygmsh")
138
- with pygmsh.occ.Geometry() as geom:
139
- geom.characteristic_length_max = h_max
140
- geom.characteristic_length_min = h_min
141
- epsilon = get_eps(h_min)
142
-
143
- geom.add_rectangle(
144
- [domain_range[0][0], domain_range[0][1], 0.0],
145
- domain_range[1][0] - domain_range[0][0],
146
- domain_range[1][1] - domain_range[0][1],
147
- )
148
-
149
- geom.set_mesh_size_callback(
150
- lambda dim, tag, x, y, z, lc: spacing(x, y, epsilon),
151
- ignore_other_mesh_sizes=True,
152
- )
153
- mesh = geom.generate_mesh()
154
- points, cells = mesh.points, mesh.cells_dict
155
- domain = {
156
- "vertices": points[:, :2].astype(float),
157
- "simplices": cells["triangle"].astype(int),
158
- }
159
- else:
160
- raise ValueError("invalid mesh type")
161
-
162
- gridView = adaptiveLeafGridView(leafGridView(domain))
163
-
164
- if version == "dune_adaptive":
165
- omega.epsilon = get_eps(h_min)
166
- omega.epsilon.value *= radius
167
- epsilon_value = omega.epsilon.value
168
-
169
- marker = mark
170
-
171
- refinements = int(2 * np.log2(h_max / h_min))
172
-
173
- region = gridFunction(
174
- omega.phi(x) * (1 - omega.phi(x)), gridView=gridView
175
- ) # interface
176
-
177
- for j in range(1, refinements + 1):
178
-
179
- omega.epsilon.value = epsilon_value * j / refinements
180
- marker(region, 0.00247262315663, maxLevel=refinements) # 1 epsilon
181
-
182
- adapt(gridView.hierarchicalGrid)
183
-
184
- h_min = h_max * 0.5 ** (j / 2)
185
- epsilon = get_eps(h_min)
186
-
187
- omega.propagate_epsilon(epsilon)
188
- domain = omega
189
-
190
- domain = DomainDune(omega, x, gridView)
191
- domain.adapt(level=adaptLevels)
192
-
193
- print(
194
- f"h_max={h_max}, h_min={h_min * 0.5 ** (adaptLevels / 2)}, epsilon={epsilon.value}"
195
- )
196
-
197
- return gridView, domain
@@ -1,48 +0,0 @@
1
- from dune.ufl import Constant
2
- from ufl import as_vector, div, exp, grad, inner, sqrt
3
-
4
- from ddfem.boundary import BndFlux_v, BndValue
5
-
6
-
7
- def fhModel(inverted):
8
- class Model:
9
- dimRange = 1
10
- outFactor_i = Constant(1, "outFactor")
11
-
12
- def initial(x):
13
- return 1 / 2 * (x[0] ** 2 + x[1] ** 2) - 1 / 3 * (x[0] ** 3 - x[1] ** 3) + 1
14
-
15
- def exact(t, x):
16
- return as_vector([exp(-2 * t) * (Model.initial(x) - 1) + 1])
17
-
18
- def K(U, DU):
19
- # DU = exp(-2 * t) * (x[0] - x[0]^2, x[1] + x[1]^2)
20
- return 2 / (1 + sqrt(1 + 4 * sqrt(inner(DU, DU))))
21
-
22
- def F_v(t, x, U, DU):
23
- return Model.K(U, DU) * DU
24
-
25
- def S_i(t, x, U, DU):
26
- return -div(
27
- Model.F_v(t, x, Model.exact(t, x), grad(Model.exact(t, x)))
28
- ) + as_vector([-2 * exp(-2 * t) * (Model.initial(x) - 1)])
29
-
30
- valD = BndValue(lambda t, x, U: Model.exact(t, x))
31
-
32
- valN = BndFlux_v(
33
- lambda t, x, U, DU, n: Model.F_v(
34
- t, x, Model.exact(t, x), grad(Model.exact(t, x))
35
- )
36
- * n
37
- )
38
-
39
- boundary = {
40
- "sides": valD,
41
- "ends": valN,
42
- }
43
-
44
- if inverted:
45
- for i in range(1, 5):
46
- boundary[i] = valD
47
-
48
- return Model
@@ -1,88 +0,0 @@
1
- from dune.ufl import Constant
2
- from ufl import (
3
- Identity,
4
- as_vector,
5
- conditional,
6
- det,
7
- diff,
8
- div,
9
- dot,
10
- grad,
11
- ln,
12
- nabla_div,
13
- nabla_grad,
14
- outer,
15
- replace,
16
- sym,
17
- tr,
18
- variable,
19
- zero,
20
- )
21
- from ufl.algorithms.ad import expand_derivatives
22
-
23
- from ddfem.boundary import BndFlux_v, BndValue
24
-
25
-
26
- def hyModel():
27
- # https://jsdokken.com/dolfinx-tutorial/chapter2/hyperelasticity.html
28
- class Model:
29
- dimRange = 2
30
- rho = Constant(1000, name="density") # kg/m3
31
- g = Constant(9.8, name="gravity") # m/s2
32
-
33
- body = Constant([0.0, -rho * g], "body") # N/m3
34
- vd = Constant([0, 0], "fixedboundary")
35
- T = Constant([0, 0], "traction") # Pa
36
-
37
- outFactor_i = Constant(1, "outFactor")
38
-
39
- # Elasticity parameters
40
- # https://www.efunda.com/formulae/solid_mechanics/mat_mechanics/calc_elastic_constants.cfm
41
- E = 1e7 # Young modulus ; Pa
42
- nu = 0.4 # Poisson ratio ;
43
- lamb = Constant(E * nu / ((1 + nu) * (1 - 2 * nu)), name="Lame_1") # Pa
44
- mu = Constant(E / (2 * (1 + nu)), name="Lame_2") # i.e. Shear modulus ; Pa
45
-
46
- def P(U, DU):
47
- I = Identity(Model.dimRange)
48
- # Stress
49
- # Hyper-elasticity, (compressible neo-Hookean model)
50
- F = variable(I + grad(U)) # Deformation gradient
51
- C = F.T * F # Right Cauchy-Green tensor
52
- J = det(F)
53
- Ic = tr(C) # First Invariant
54
- mu = Model.mu
55
- lamb = Model.lamb
56
- psi = (mu / 2) * (Ic - 3) - mu * ln(J) + (lamb / 2) * (ln(J)) ** 2
57
-
58
- p = diff(psi, F)
59
- p = expand_derivatives(p)
60
- p = replace(p, {F: I + DU})
61
- # p = replace(p, {F: I + grad(U)})
62
-
63
- # Linear-elasticity
64
- # p = lamb * tr(sym(DU)) * I + 2 * mu * sym(DU)
65
-
66
- return p
67
-
68
- def F_v(t, x, U, DU):
69
- return Model.P(U, DU)
70
-
71
- def S_i(t, x, U, DU):
72
- return Model.body
73
-
74
- valD = lambda t, x, U: Model.vd
75
-
76
- valN = lambda t, x, U, DU, n: Model.T
77
-
78
- boundary = {
79
- "left": BndValue(valD),
80
- "other": BndFlux_v(valN),
81
- }
82
- # boundary = {
83
- # "left": BndValue(valD),
84
- # "right": BndFlux_v(valN),
85
- # "bulk": BndFlux_v(valN),
86
- # }
87
-
88
- return Model
@@ -1,45 +0,0 @@
1
- from dune.ufl import Constant
2
- from ufl import Identity, as_vector, div, grad, sym, tr, zero
3
-
4
- from ddfem.boundary import BndFlux_v, BndValue
5
-
6
-
7
- def leModel():
8
- class Model:
9
- dimRange = 2
10
- lamb = Constant(0.1, name="Lame_1")
11
- mu = Constant(1, name="Lame_2")
12
- rho = Constant(1 / 1000, name="density")
13
- g = Constant(9.8, name="gravity")
14
-
15
- outFactor_i = Constant(1, "outFactor")
16
-
17
- vd = Constant([0, 0], "stationary")
18
- vn = Constant([0, 0], "traction")
19
-
20
- I = Identity(dimRange)
21
-
22
- def sigma(U, DU):
23
- return Model.lamb * tr(sym(DU)) * Model.I + 2 * Model.mu * sym(DU)
24
-
25
- def F_v(t, x, U, DU):
26
- return Model.sigma(U, DU)
27
-
28
- def S_i(t, x, U, DU):
29
- return as_vector([0.0, -Model.rho * Model.g])
30
-
31
- valD = lambda t, x, U: Model.vd
32
-
33
- valN = lambda t, x, U, DU, n: Model.vn
34
-
35
- # boundary = {
36
- # "left": BndValue(valD),
37
- # "other": BndFlux_v(valN),
38
- # }
39
- boundary = {
40
- "left": BndValue(valD),
41
- "right": BndFlux_v(valN),
42
- "bulk": BndFlux_v(valN),
43
- }
44
-
45
- return Model
@@ -1,29 +0,0 @@
1
- from dune.ufl import Constant
2
- from ufl import grad, inner
3
-
4
- from ddfem.boundary import BndValue
5
-
6
-
7
- def pModel(power):
8
- class Model:
9
- dimRange = 1
10
- ep = Constant(1e-5, name="ep")
11
- f = Constant([1], name="f")
12
- g = Constant([0], name="g")
13
- p = Constant(power, name="p") # p for p-Laplacian
14
- assert p.value > 1 and p.value < 2**16
15
- outFactor_i = Constant(1, "outFactor")
16
-
17
- def K(u):
18
- return (Model.ep**2 + inner(grad(u), grad(u))) ** ((Model.p - 2) / 2)
19
-
20
- def F_v(t, x, U, DU):
21
- return Model.K(U) * DU
22
-
23
- def S_i(t, x, U, DU):
24
- return Model.f - U
25
-
26
- bc = BndValue(g)
27
- boundary = {1: bc, 2: bc, 3: bc, 4: bc, "full": bc}
28
-
29
- return Model