ddfem 1.0.0__py3-none-any.whl → 1.0.1__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 +4 -0
  2. ddfem/boundary.py +12 -3
  3. ddfem/examples/__init__.py +0 -0
  4. ddfem/examples/advection_diffusion.py +74 -0
  5. ddfem/examples/beam.py +147 -0
  6. ddfem/examples/cahn_hilliard.py +67 -0
  7. ddfem/examples/chemical_reaction.py +88 -0
  8. ddfem/examples/constant.py +46 -0
  9. ddfem/examples/five_circle_flat.py +197 -0
  10. ddfem/examples/forchheimer.py +48 -0
  11. ddfem/examples/hyperelasticity.py +88 -0
  12. ddfem/examples/linear_elasticity.py +45 -0
  13. ddfem/examples/plaplace.py +29 -0
  14. ddfem/examples/single_circle.py +135 -0
  15. ddfem/examples/triple_circle.py +217 -0
  16. ddfem/examples/triple_circle_beam.py +208 -0
  17. ddfem/geometry/__init__.py +3 -3
  18. ddfem/geometry/arc.py +10 -8
  19. ddfem/geometry/ball.py +24 -0
  20. ddfem/geometry/box.py +7 -8
  21. ddfem/geometry/domain.py +16 -4
  22. ddfem/geometry/domain_dune.py +16 -0
  23. ddfem/geometry/helpers.py +19 -12
  24. ddfem/geometry/pie.py +7 -7
  25. ddfem/geometry/plane.py +20 -0
  26. ddfem/geometry/primitive_base.py +129 -70
  27. ddfem/geometry/vesica.py +7 -6
  28. ddfem/model2ufl.py +10 -4
  29. ddfem/transformers/DDM1.py +10 -68
  30. ddfem/transformers/Fitted.py +22 -12
  31. ddfem/transformers/Mix0.py +10 -64
  32. ddfem/transformers/NNS.py +11 -72
  33. ddfem/transformers/NS.py +14 -79
  34. ddfem/transformers/__init__.py +1 -0
  35. ddfem/transformers/transformer_base.py +102 -15
  36. {ddfem-1.0.0.dist-info → ddfem-1.0.1.dist-info}/METADATA +2 -6
  37. ddfem-1.0.1.dist-info/RECORD +41 -0
  38. ddfem/base_model.py +0 -200
  39. ddfem/geometry/circle.py +0 -39
  40. ddfem-1.0.0.dist-info/RECORD +0 -27
  41. {ddfem-1.0.0.dist-info → ddfem-1.0.1.dist-info}/WHEEL +0 -0
  42. {ddfem-1.0.0.dist-info → ddfem-1.0.1.dist-info}/licenses/LICENSE +0 -0
  43. {ddfem-1.0.0.dist-info → ddfem-1.0.1.dist-info}/top_level.txt +0 -0
ddfem/transformers/NNS.py CHANGED
@@ -1,6 +1,6 @@
1
1
  from ufl import as_vector, conditional, dot, grad, sqrt, zero
2
2
 
3
- from .transformer_base import transformer_base
3
+ from .transformer_base import transformer
4
4
 
5
5
  """
6
6
  Paper: using x^- = 1/2(x-|x|), x^+ = 1/2(x+|x|) so that x = x^+ + x^-, i.e., x^+ - x = - x^-
@@ -29,18 +29,9 @@ model = - ddm2.F_c(u).grad(v) - ddm2.S_e(u)v
29
29
  """
30
30
 
31
31
 
32
- def NDDM(OriginalModel, domainDescription):
33
- Model = transformer_base(OriginalModel, domainDescription)
34
-
32
+ @transformer
33
+ def NDDM(Model):
35
34
  class DDModel(Model):
36
- def sigma(t, x, U, DU=None):
37
- if DU:
38
- return DU
39
- return grad(U)
40
-
41
- # self.normal = grad(self.sign_dist)
42
- # self.projection = self.x - self.sign_dist * self.normal
43
-
44
35
  def S_e_source(t, x, U, DU):
45
36
  return DDModel.phi(x) * Model.S_e(t, x, U, DDModel.sigma(t, x, U, DU))
46
37
 
@@ -60,31 +51,11 @@ def NDDM(OriginalModel, domainDescription):
60
51
  else:
61
52
  convec = zero(U.ufl_shape)
62
53
 
63
- convec += DDModel.BT.BndFlux_cExt(t, x, U)
54
+ convec -= DDModel.BT.BndFlux_cExt(t, x, U)
64
55
  return convec
65
56
 
66
- if hasattr(Model, "S_e") and hasattr(Model, "F_c"):
67
- print("NDDM: S_e and F_c")
68
-
69
- def S_e(t, x, U, DU):
70
- return DDModel.S_e_source(t, x, U, DU) + DDModel.S_e_convection(
71
- t, x, U, DU
72
- )
73
-
74
- elif hasattr(Model, "S_e"):
75
- print("NDDM: S_e")
76
-
77
- def S_e(t, x, U, DU):
78
- return DDModel.S_e_source(t, x, U, DU)
79
-
80
- elif hasattr(Model, "F_c"):
81
- print("NDDM: F_c")
82
-
83
- def S_e(t, x, U, DU):
84
- return DDModel.S_e_convection(t, x, U, DU)
85
-
86
- def S_i_stability(t, x, U, DU):
87
- return -Model.stabFactor * (
57
+ def S_outside(t, x, U, DU):
58
+ return -(
88
59
  DDModel.BT.jumpV(t, x, U) * (1 - DDModel.phi(x)) / (DDModel.epsilon**2)
89
60
  )
90
61
 
@@ -92,7 +63,7 @@ def NDDM(OriginalModel, domainDescription):
92
63
  return DDModel.phi(x) * Model.S_i(t, x, U, DDModel.sigma(t, x, U, DU))
93
64
 
94
65
  def S_i_diffusion(t, x, U, DU):
95
- beta = 3 * (1 - DDModel.phi(x)) * Model.stabFactor / (2 * DDModel.epsilon)
66
+ beta = 3 * (1 - DDModel.phi(x)) / (2 * DDModel.epsilon)
96
67
  diffusion = beta * (
97
68
  sqrt(dot(grad(DDModel.phi(x)), grad(DDModel.phi(x))))
98
69
  * DDModel.BT.jumpV(t, x, U)
@@ -102,42 +73,10 @@ def NDDM(OriginalModel, domainDescription):
102
73
  diffusion += DDModel.BT.jumpFv(t, x, U, DU, Fv)
103
74
  return -diffusion
104
75
 
105
- if hasattr(Model, "S_i") and hasattr(Model, "F_v"):
106
- print("NDDM: S_i and F_v")
107
-
108
- def S_i(t, x, U, DU):
109
- return (
110
- DDModel.S_i_stability(t, x, U, DU)
111
- + DDModel.S_i_source(t, x, U, DU)
112
- + DDModel.S_i_diffusion(t, x, U, DU)
113
- )
114
-
115
- elif hasattr(Model, "F_v"):
116
- print("NDDM: F_v")
117
-
118
- def S_i(t, x, U, DU):
119
- return DDModel.S_i_stability(t, x, U, DU) + DDModel.S_i_diffusion(
120
- t, x, U, DU
121
- )
122
-
123
- elif hasattr(Model, "S_i"):
124
- print("NDDM: S_i")
125
-
126
- def S_i(t, x, U, DU):
127
- return DDModel.S_i_stability(t, x, U, DU) + DDModel.S_i_source(
128
- t, x, U, DU
129
- )
130
-
131
- if hasattr(Model, "F_c"):
132
- print("NDDM: F_c")
133
-
134
- def F_c(t, x, U):
135
- return DDModel.phi(x) * Model.F_c(t, x, U)
136
-
137
- if hasattr(Model, "F_v"):
138
- print("NDDM: F_v")
76
+ def F_c(t, x, U):
77
+ return DDModel.phi(x) * Model.F_c(t, x, U)
139
78
 
140
- def F_v(t, x, U, DU):
141
- return DDModel.phi(x) * Model.F_v(t, x, U, DDModel.sigma(t, x, U, DU))
79
+ def F_v(t, x, U, DU):
80
+ return DDModel.phi(x) * Model.F_v(t, x, U, DDModel.sigma(t, x, U, DU))
142
81
 
143
82
  return DDModel
ddfem/transformers/NS.py CHANGED
@@ -1,6 +1,6 @@
1
1
  from ufl import as_vector, conditional, dot, grad, outer, sqrt, zero
2
2
 
3
- from .transformer_base import transformer_base
3
+ from .transformer_base import transformer
4
4
 
5
5
  """
6
6
  Paper: using x^- = 1/2(x-|x|), x^+ = 1/2(x+|x|) so that x = x^+ + x^-, i.e., x^+ - x = - x^-
@@ -29,18 +29,9 @@ model = - ddm2.F_c(u).grad(v) - ddm2.S_e(u)v
29
29
  """
30
30
 
31
31
 
32
- def NSDDM(OriginalModel, domainDescription):
33
- Model = transformer_base(OriginalModel, domainDescription)
34
-
32
+ @transformer
33
+ def NSDDM(Model):
35
34
  class DDModel(Model):
36
- def sigma(t, x, U, DU=None):
37
- if DU:
38
- return DU
39
- return grad(U)
40
-
41
- # self.normal = grad(self.sign_dist)
42
- # self.projection = self.x - self.sign_dist * self.normal
43
-
44
35
  def S_e_source(t, x, U, DU):
45
36
  return DDModel.phi(x) * Model.S_e(t, x, U, DDModel.sigma(t, x, U, DU))
46
37
 
@@ -60,31 +51,11 @@ def NSDDM(OriginalModel, domainDescription):
60
51
  else:
61
52
  convec = zero(U.ufl_shape)
62
53
 
63
- convec += DDModel.BT.BndFlux_cExt(t, x, U)
54
+ convec -= DDModel.BT.BndFlux_cExt(t, x, U)
64
55
  return convec
65
56
 
66
- if hasattr(Model, "S_e") and hasattr(Model, "F_c"):
67
- print("NSDDM: S_e and F_c")
68
-
69
- def S_e(t, x, U, DU):
70
- return DDModel.S_e_source(t, x, U, DU) + DDModel.S_e_convection(
71
- t, x, U, DU
72
- )
73
-
74
- elif hasattr(Model, "S_e"):
75
- print("NSDDM: S_e")
76
-
77
- def S_e(t, x, U, DU):
78
- return DDModel.S_e_source(t, x, U, DU)
79
-
80
- elif hasattr(Model, "F_c"):
81
- print("NSDDM: F_c")
82
-
83
- def S_e(t, x, U, DU):
84
- return DDModel.S_e_convection(t, x, U, DU)
85
-
86
- def S_i_stability(t, x, U, DU):
87
- return -DDModel.stabFactor * (
57
+ def S_outside(t, x, U, DU):
58
+ return -(
88
59
  DDModel.BT.jumpV(t, x, U) * (1 - DDModel.phi(x)) / (DDModel.epsilon**2)
89
60
  )
90
61
 
@@ -92,7 +63,7 @@ def NSDDM(OriginalModel, domainDescription):
92
63
  return DDModel.phi(x) * Model.S_i(t, x, U, DDModel.sigma(t, x, U, DU))
93
64
 
94
65
  def S_i_diffusion(t, x, U, DU):
95
- beta = 6 * (1 - DDModel.phi(x)) * Model.stabFactor / DDModel.epsilon
66
+ beta = 6 * (1 - DDModel.phi(x)) / DDModel.epsilon
96
67
  diffusion = beta * (
97
68
  sqrt(dot(grad(DDModel.phi(x)), grad(DDModel.phi(x))))
98
69
  * DDModel.BT.jumpV(t, x, U)
@@ -102,50 +73,14 @@ def NSDDM(OriginalModel, domainDescription):
102
73
  diffusion += DDModel.BT.jumpFv(t, x, U, DU, Fv)
103
74
  return -diffusion
104
75
 
105
- if hasattr(Model, "S_i") and hasattr(Model, "F_v"):
106
- print("NSDDM: S_i and F_v")
107
-
108
- def S_i(t, x, U, DU):
109
- return (
110
- DDModel.S_i_stability(t, x, U, DU)
111
- + DDModel.S_i_source(t, x, U, DU)
112
- + DDModel.S_i_diffusion(t, x, U, DU)
113
- )
76
+ def F_c(t, x, U):
77
+ return DDModel.phi(x) * Model.F_c(t, x, U)
114
78
 
115
- elif hasattr(Model, "F_v"):
116
- print("NSDDM: F_v")
79
+ def F_v(t, x, U, DU):
80
+ diffusion = DDModel.phi(x) * Model.F_v(t, x, U, DDModel.sigma(t, x, U, DU))
117
81
 
118
- def S_i(t, x, U, DU):
119
- return DDModel.S_i_stability(t, x, U, DU) + DDModel.S_i_diffusion(
120
- t, x, U, DU
121
- )
122
-
123
- elif hasattr(Model, "S_i"):
124
- print("NSDDM: S_i")
125
-
126
- def S_i(t, x, U, DU):
127
- return DDModel.S_i_stability(t, x, U, DU) + DDModel.S_i_source(
128
- t, x, U, DU
129
- )
130
-
131
- if hasattr(Model, "F_c"):
132
- print("NSDDM: F_c")
133
-
134
- def F_c(t, x, U):
135
- return DDModel.phi(x) * Model.F_c(t, x, U)
136
-
137
- if hasattr(Model, "F_v"):
138
- print("NSDDM: F_v")
139
-
140
- def F_v(t, x, U, DU):
141
- diffusion = DDModel.phi(x) * Model.F_v(
142
- t, x, U, DDModel.sigma(t, x, U, DU)
143
- )
144
-
145
- out = outer(DDModel.BT.jumpV(t, x, U), grad(DDModel.phi(x)))
146
- diffusion += Model.F_v_lin_mult(
147
- t, x, U, DDModel.sigma(t, x, U, DU), out
148
- )
149
- return diffusion
82
+ out = outer(DDModel.BT.jumpV(t, x, U), grad(DDModel.phi(x)))
83
+ diffusion += Model.F_v_lin_mult(t, x, U, DDModel.sigma(t, x, U, DU), out)
84
+ return diffusion
150
85
 
151
86
  return DDModel
@@ -3,3 +3,4 @@ from .Fitted import Fitted
3
3
  from .Mix0 import Mix0DDM
4
4
  from .NNS import NDDM
5
5
  from .NS import NSDDM
6
+ from .transformer_base import transformer, posttransformer, pretransformer
@@ -1,22 +1,30 @@
1
- from ufl import as_matrix, diff, dot, inner, replace, variable, zero
1
+ from ufl import as_matrix, diff, dot, grad, inner, replace, variable, zero
2
2
  from ufl.algorithms.ad import expand_derivatives
3
3
 
4
4
  from ..boundary import BndFlux_c, BndFlux_v, BndValue, BoundaryTerms
5
5
 
6
6
 
7
- def transformer_base(Model, domainDescription):
7
+ def pretransformer(Model, domainDescription):
8
8
  class DDBase(Model):
9
9
  BT = BoundaryTerms(Model, domainDescription)
10
10
  boundary = BT.physical
11
11
  domain = BT.domain
12
12
 
13
+ hasFlux_c = hasattr(Model, "F_c")
14
+ hasFlux_v = hasattr(Model, "F_v")
15
+ hasSource_i = hasattr(Model, "S_i")
16
+ hasSource_e = hasattr(Model, "S_e")
17
+
18
+ hasOutFactor_i = hasattr(Model, "outFactor_i")
19
+ hasOutFactor_e = hasattr(Model, "outFactor_e")
20
+
13
21
  if BT.BndValueExt is not None:
14
- boundary[lambda x: DDBase.domain.omega.chi(x) < 0.5] = BndValue(
15
- BT.BndValueExt
16
- )
22
+ boundary[lambda x: DDBase.domain.chi(x) < 0.5] = BndValue(BT.BndValueExt)
23
+
24
+ assert (
25
+ hasOutFactor_i or hasOutFactor_e
26
+ ), "Dirichlet boundary requires the attribute outFactor_i or outFactor_e for outside term scaling"
17
27
  else:
18
- hasFlux_c = hasattr(Model, "F_c")
19
- hasFlux_v = hasattr(Model, "F_v")
20
28
 
21
29
  if hasFlux_c:
22
30
  valFc = BndFlux_c(lambda t, x, U, n: -DDBase.BT.BndFlux_cExt(t, x, U))
@@ -30,13 +38,18 @@ def transformer_base(Model, domainDescription):
30
38
  valN = valFc
31
39
  elif hasFlux_v:
32
40
  valN = valFv
33
- boundary[lambda x: DDBase.domain.omega.chi(x) < 0.5] = valN
41
+ boundary[lambda x: DDBase.domain.chi(x) < 0.5] = valN
34
42
 
35
43
  phi = domain.phi
36
44
  epsilon = domain.omega.epsilon
37
- ep = domain.omega.external_projection
45
+ ep = domain.external_projection
38
46
 
39
- if hasattr(Model, "S_e"):
47
+ def sigma(t, x, U, DU=None):
48
+ if DU:
49
+ return DU
50
+ return grad(U)
51
+
52
+ if hasSource_e:
40
53
 
41
54
  def S_e(t, x, U, DU):
42
55
  return replace(
@@ -44,7 +57,7 @@ def transformer_base(Model, domainDescription):
44
57
  {x: DDBase.ep(x)},
45
58
  )
46
59
 
47
- if hasattr(Model, "S_i"):
60
+ if hasSource_i:
48
61
 
49
62
  def S_i(t, x, U, DU):
50
63
  return replace(
@@ -52,20 +65,20 @@ def transformer_base(Model, domainDescription):
52
65
  {x: DDBase.ep(x)},
53
66
  )
54
67
 
55
- if hasattr(Model, "F_c"):
68
+ if hasFlux_c:
56
69
 
57
70
  def F_c(t, x, U):
58
- return Model.F_c(t, DDBase.ep(x), U)
71
+ # return Model.F_c(t, DDBase.ep(x), U)
59
72
 
60
73
  return replace(
61
74
  expand_derivatives(Model.F_c(t, x, U)),
62
75
  {x: DDBase.ep(x)},
63
76
  )
64
77
 
65
- if hasattr(Model, "F_v"):
78
+ if hasFlux_v:
66
79
 
67
80
  def F_v(t, x, U, DU):
68
- return Model.F_v(t, DDBase.ep(x), U, DU)
81
+ # return Model.F_v(t, DDBase.ep(x), U, DU)
69
82
 
70
83
  return replace(
71
84
  expand_derivatives(Model.F_v(t, x, U, DU)),
@@ -124,3 +137,77 @@ def transformer_base(Model, domainDescription):
124
137
  )
125
138
 
126
139
  return DDBase
140
+
141
+
142
+ def posttransformer(DDModel):
143
+ class DDM(DDModel):
144
+ if DDModel.hasSource_e or DDModel.hasFlux_c or DDModel.hasOutFactor_e:
145
+
146
+ def S_e(t, x, U, DU):
147
+ total = zero(U.ufl_shape)
148
+
149
+ if DDModel.hasOutFactor_e:
150
+ total += DDModel.outFactor_e * DDModel.S_outside(t, x, U, DU)
151
+ if DDModel.hasSource_e:
152
+ total += DDModel.S_e_source(t, x, U, DU)
153
+ if DDModel.hasFlux_c:
154
+ total += DDModel.S_e_convection(t, x, U, DU)
155
+ return total
156
+
157
+ else:
158
+ try:
159
+ del DDModel.S_e
160
+ except AttributeError:
161
+ pass
162
+
163
+ if DDModel.hasSource_i or DDModel.hasFlux_v or DDModel.hasOutFactor_i:
164
+
165
+ def S_i(t, x, U, DU):
166
+ total = zero(U.ufl_shape)
167
+
168
+ if DDModel.hasOutFactor_i:
169
+ total += DDModel.outFactor_i * DDModel.S_outside(t, x, U, DU)
170
+ if DDModel.hasSource_i:
171
+ total += DDModel.S_i_source(t, x, U, DU)
172
+ if DDModel.hasFlux_v:
173
+ total += DDModel.S_i_diffusion(t, x, U, DU)
174
+ return total
175
+
176
+ else:
177
+ try:
178
+ del DDModel.S_i
179
+ except AttributeError:
180
+ pass
181
+
182
+ if DDModel.hasFlux_c:
183
+
184
+ def F_c(t, x, U):
185
+ return DDModel.F_c(t, x, U)
186
+
187
+ else:
188
+ try:
189
+ del DDModel.F_c
190
+ except AttributeError:
191
+ pass
192
+
193
+ if DDModel.hasFlux_v:
194
+
195
+ def F_v(t, x, U, DU):
196
+ return DDModel.F_v(t, x, U, DU)
197
+
198
+ else:
199
+ try:
200
+ del DDModel.F_v
201
+ except AttributeError:
202
+ pass
203
+
204
+ return DDM
205
+
206
+
207
+ def transformer(transformer):
208
+ def _transformer(OriginalModel, domainDescription):
209
+ PreModel = pretransformer(OriginalModel, domainDescription)
210
+ Model = transformer(PreModel)
211
+ return posttransformer(Model)
212
+
213
+ return _transformer
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ddfem
3
- Version: 1.0.0
3
+ Version: 1.0.1
4
4
  Summary: Diffuse domain finite element solver
5
5
  Author-email: Luke Benfield <luke.benfield@warwick.ac.uk>, Andreas Dedner <a.s.dedner@warwick.ac.uk>
6
6
  License-Expression: MIT
@@ -12,14 +12,10 @@ Requires-Python: >=3.9
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
14
  Requires-Dist: fenics-ufl>=2022
15
+ Requires-Dist: numpy
15
16
  Dynamic: license-file
16
17
 
17
18
  # Diffuse Domain Finite Element Methods
18
19
 
19
20
  This is a package for solving complex PDEs based on the diffuse domain idea.
20
21
 
21
- Build package by running
22
-
23
- ```bash
24
- python3 -m build
25
- ```
@@ -0,0 +1,41 @@
1
+ ddfem/__init__.py,sha256=N860erjFVjXifNwEQ_ejRF99ub195M6eC9GIOqeIhyU,106
2
+ ddfem/boundary.py,sha256=qpvvjRBBUZHZULIRovuz1h8U30KQRtYERIJxN5O251c,7570
3
+ ddfem/dune.py,sha256=oU4bKiG4AndEhMVhAi1Nnmo9cEhjceTW3X2ptv6ombU,67
4
+ ddfem/model2ufl.py,sha256=lEEmMmZWbcxprHD9pRWwZfIdiLg3ScQkR7V_N48qqAw,4265
5
+ ddfem/examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ ddfem/examples/advection_diffusion.py,sha256=9UPILICF3Sfh3SA7zJk6iDabXmvIa4GowJd62qaWOd8,2081
7
+ ddfem/examples/beam.py,sha256=awZvrgw92ANJgD1MGhhEVZ0eBsSNmhuwegpS8AHiiPk,4687
8
+ ddfem/examples/cahn_hilliard.py,sha256=-T6p5-BY98sQ5y9Vcd2YVokamQQ66nA7uUqJDRQjzB0,2308
9
+ ddfem/examples/chemical_reaction.py,sha256=9zNgGuCT25Z0Z_ru8pNoK1MOOrYA8r3UkfGvmNRQXpw,2488
10
+ ddfem/examples/constant.py,sha256=6wFiKnsbjMKk9hInJwnCa8d7Thp7uPZGJ-1805V243Y,1508
11
+ ddfem/examples/five_circle_flat.py,sha256=NbNmmz8jMwfFa7ZfEDUq0g5BF94z_ivvbPA2jVLs6PM,6049
12
+ ddfem/examples/forchheimer.py,sha256=3mpdYVzRn9tmtq7kQBP-vlx9L7HmAHdqbVVRABRd2TY,1311
13
+ ddfem/examples/hyperelasticity.py,sha256=YyoZhruTMpTfUIL4ioOkwe9FFPf_ffCMHsMsBV4SZ_w,2373
14
+ ddfem/examples/linear_elasticity.py,sha256=N3wpzzhD4wRpBqmEYFV39_Nx7RuNgfeEMsTWpdzIdgk,1164
15
+ ddfem/examples/plaplace.py,sha256=yiuYdJpDrFHl1oLG7WWtAs26x2s9vjSXlTsijXTPBxc,751
16
+ ddfem/examples/single_circle.py,sha256=m3tg7frVTLnP8Cxfx_6fbvoUb2mJ3ltgNnrX5URAwRw,4601
17
+ ddfem/examples/triple_circle.py,sha256=bo8ZD1B7biXe1HwVDv97O6B5EVsku5TCft3Oqamay7E,7089
18
+ ddfem/examples/triple_circle_beam.py,sha256=J9_U2MuRBGnhUT1w_IimuyfTLzds_XD2CCv9o4nWD_w,6607
19
+ ddfem/geometry/__init__.py,sha256=ePmkipwfdhM88qrStE__n0VFKqvl8AKK4VjsAsivt4Y,295
20
+ ddfem/geometry/arc.py,sha256=ouK8gxkd2f8RtpAK33p6-zU5RoyMejxEge2IEcCOtR4,1381
21
+ ddfem/geometry/ball.py,sha256=Q_ped9ay3KypU8sKutAXPH9XkEFJx5hIK7qTCy1Y26E,679
22
+ ddfem/geometry/box.py,sha256=ecXUMI2a17-hZZyUXol08z7wk3IZn1yHE_CV9YIyR18,915
23
+ ddfem/geometry/domain.py,sha256=n4Cu1sFy19ONUuQec2EICtoSBYzS-H_sLB2YxU5dads,1363
24
+ ddfem/geometry/domain_dune.py,sha256=2ArzeRU42o4-TS21DXajPSCXj_3SlgGdehgN7QJhQzc,2600
25
+ ddfem/geometry/helpers.py,sha256=kunsuciuJJwkcZgDn8A7wbKYSqIAYjdvhei_YfjvVtk,1049
26
+ ddfem/geometry/pie.py,sha256=WjgYPI6YvkcxPTQB1SjdN22dFQHV0X8kSO6QcXDLBSU,1003
27
+ ddfem/geometry/plane.py,sha256=hCRLa06yXfXzfms2JIbAusdPf5qFUy9DrjNDfZ-0TGA,500
28
+ ddfem/geometry/primitive_base.py,sha256=gq3s2CIXk1qBnOEGys217yd_zXQr_UXrDXRpagQ3oiY,9419
29
+ ddfem/geometry/vesica.py,sha256=g28RxdoDpUiq9QR9sHUJkO05-F3YTDOTOxcNm1tyV4E,1747
30
+ ddfem/transformers/DDM1.py,sha256=73TW_mCPjdvRGo65D9uMUiw7ygYZCQuGFPIPvEmz43o,1092
31
+ ddfem/transformers/Fitted.py,sha256=GdaA0znMfw_U_QNAngZSYJB3ZJgH_BAnvrL_viZqals,2908
32
+ ddfem/transformers/Mix0.py,sha256=ZYeL6jrIIFCvVjCt_evB7sOG0ES3tmm5j-6W8gjK11k,3816
33
+ ddfem/transformers/NNS.py,sha256=lGQVCd1x6KrzVyOEAIttaDXBFjP9nLBIj9wnp_fvYtg,3416
34
+ ddfem/transformers/NS.py,sha256=fsih358oeayvmovhTAuddjbx7O0K_faF5qTAMQdHH8s,3612
35
+ ddfem/transformers/__init__.py,sha256=okno6aFZoIPaJRi_Nw7cM63jpy18rS2yHsSuG7Vb4Og,195
36
+ ddfem/transformers/transformer_base.py,sha256=Ey6iGk203lnzJOhLjMxyQNgKbclba_RIPpMW22OT7zQ,6347
37
+ ddfem-1.0.1.dist-info/licenses/LICENSE,sha256=7EI8xVBu6h_7_JlVw-yPhhOZlpY9hP8wal7kHtqKT_E,1074
38
+ ddfem-1.0.1.dist-info/METADATA,sha256=_jSNqnAB71Fb33U16dUgV6jGoSyb1kLlpYGGbZaJv88,663
39
+ ddfem-1.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
40
+ ddfem-1.0.1.dist-info/top_level.txt,sha256=LF2T9-5A2Bak81PqbCcsAex8d5Xrla2Wq8yrlQi-ZtY,6
41
+ ddfem-1.0.1.dist-info/RECORD,,
ddfem/base_model.py DELETED
@@ -1,200 +0,0 @@
1
- import inspect
2
-
3
- import ufl
4
- from ufl import as_matrix, as_vector, diff, dot, inner, outer, variable, zero
5
- from ufl.algorithms.ad import expand_derivatives
6
- from ufl.algorithms.apply_derivatives import apply_derivatives
7
-
8
-
9
- class BaseModel:
10
- boundary = {}
11
-
12
- @staticmethod
13
- def function(self, *args, **kwargs):
14
- uh = self._function(*args, **kwargs)
15
- uh.boundary = self.boundary
16
- return uh
17
-
18
- # U_t + div[F_c(x,t,U) - F_v(x,t,U,grad[U]) ] = S(x,t,U, grad[U]).
19
-
20
- @classmethod
21
- def F_c_lin(cls, t, x, U):
22
- U = variable(U)
23
- d = diff(cls.F_c(t, x, U), U)
24
- d = apply_derivatives(expand_derivatives(d))
25
- return d
26
-
27
- # U.ufl_shape == (1,)
28
- # F_c(U).ufl_shape == (1, 2,)
29
- # diff(F_c(U), U).ufl_shape == (1, 2, 1)
30
- # n.ufl_shape == (2,)
31
- #
32
- # s, t = F_c(U).ufl_shape
33
- # f_c = as_matrix([[dot(d[i, j, :], U) for j in range(t)] for i in range(s)])
34
- #
35
- # w, = U.ufl_shape
36
- # convec = as_vector([dot([f_c[w, :], n) for i in range(w)]) # f_c * n
37
- #
38
- # switch order
39
-
40
- @classmethod
41
- def F_c_lin_mult(cls, t, x, U, n):
42
- G = cls.F_c_lin(t, x, U)
43
- # try:
44
- # d = dot(G, n)
45
- # print("F_c dot")
46
- # return d
47
- # except:
48
- m, d, m_ = G.ufl_shape
49
- return as_matrix([[dot(G[i, :, k], n) for k in range(m_)] for i in range(m)])
50
-
51
- @classmethod
52
- def F_v_lin(cls, t, x, U, DU):
53
- DU = variable(DU)
54
- d = diff(cls.F_v(t, x, U, DU), DU)
55
- d = apply_derivatives(expand_derivatives(d))
56
- return d
57
-
58
- @classmethod
59
- def F_v_lin_mult(cls, t, x, U, DU, v):
60
- G = cls.F_v_lin(t, x, U, DU)
61
- # try:
62
- # d = dot(G, v)
63
- # print("F_v dot")
64
- # return d
65
- # except:
66
- m, d = v.ufl_shape
67
- return as_matrix(
68
- [[inner(G[i, k, :, :], v) for k in range(d)] for i in range(m)]
69
- )
70
-
71
- # avoid issue with variable capturing in lambdas in the for loop below
72
- # https://www.geeksforgeeks.org/why-do-python-lambda-defined-in-a-loop-with-different-values-all-return-the-same-result/
73
- def _createV(v, U=None):
74
- if U is None:
75
- return lambda t, x, u: v # classify
76
- return lambda t, x: v(t, x, U) # jumpV
77
-
78
- def _createF(v, U=None, DU=None, N=None):
79
- if U is None and DU is None and N is None:
80
- return lambda t, x, u, _, n: v(t, x, u, n) # classify
81
- elif U and N and DU is None:
82
- return lambda t, x: v(t, x, U, N) # jumpAF
83
- elif U and N and DU:
84
- return lambda t, x: v(t, x, U, DU, N) # jumpDF
85
-
86
- @staticmethod
87
- def classify_boundary(Model):
88
- boundaryDict = getattr(Model, "boundary_d", {})
89
-
90
- boundaryAFlux = {} # Fluxes for the advection term
91
- boundaryDFlux = {} # Fluxes for the diffusion term
92
- boundaryValue = {} # Boundary values for Dirichlet
93
-
94
- hasAdvFlux = hasattr(Model, "F_c")
95
- hasDiffFlux = hasattr(Model, "F_v")
96
-
97
- for k, f in boundaryDict.items():
98
- if isinstance(f, (tuple, list)):
99
- assert (
100
- hasAdvFlux and hasDiffFlux
101
- ), "two boundary fluxes provided but only one bulk flux given"
102
- boundaryAFlux[k], boundaryDFlux[k] = f
103
- # (f[0](t, x, u, n), f[1](t, x, u, grad(u), n))
104
-
105
- elif isinstance(f, ufl.core.expr.Expr):
106
- boundaryValue[k] = BaseModel._createV(f)
107
-
108
- else:
109
- num_args = len(inspect.signature(f).parameters)
110
-
111
- if num_args == 3:
112
- boundaryValue[k] = f # f(t, x, u)
113
-
114
- elif num_args == 4:
115
- if hasAdvFlux and not hasDiffFlux:
116
- boundaryAFlux[k] = f # f(t, x, u, n)
117
- elif not hasAdvFlux and hasDiffFlux:
118
- boundaryDFlux[k] = BaseModel._createF(f)
119
- else:
120
- assert not (
121
- hasAdvFlux and hasDiffFlux
122
- ), "one boundary fluxes provided but two bulk fluxes given"
123
-
124
- else:
125
- raise NotImplementedError(f"boundary function {num_args} arguments")
126
-
127
- return boundaryAFlux, boundaryDFlux, boundaryValue
128
-
129
- @staticmethod
130
- def boundaryTerms(Model, domain):
131
- boundaryAFlux, boundaryDFlux, boundaryValue = BaseModel.classify_boundary(Model)
132
- bd_weight = []
133
- bN_weight = []
134
-
135
- for model_key in boundaryValue.keys():
136
- phi_i_proj = domain.bndProjSDFs(model_key)
137
- bd_weight.append(phi_i_proj)
138
-
139
- for model_key in {*boundaryAFlux.keys(), *boundaryDFlux.keys()}:
140
- phi_i_proj = domain.bndProjSDFs(model_key)
141
- bN_weight.append(phi_i_proj)
142
-
143
- def total_weight(t, x):
144
- weight = 1e-10 # tol
145
- for w in bd_weight + bN_weight:
146
- weight += w(t, x)
147
- return weight
148
-
149
- # perhaps switch methods around so that gExt is setup and then
150
- # jumpD does sum(w)*U - gExt. But then the exception needs to be caught...
151
- def jumpV(t, x, U, U1=None):
152
- jdv = zero(U.ufl_shape)
153
-
154
- if U1 is None:
155
- U1 = U
156
-
157
- for g, w in zip(boundaryValue.values(), bd_weight):
158
- g_tmp = BaseModel._createV(v=g, U=U)
159
- g_ext = domain.omega.boundary_extend(g_tmp)
160
-
161
- jdv += w(t, x) * (U1 - g_ext(t, x))
162
-
163
- return jdv / total_weight(t, x)
164
-
165
- if len(boundaryValue) == 0:
166
- gExt = None
167
- else:
168
-
169
- def gExt(t, x, U):
170
- z = zero(U.ufl_shape)
171
- return -jumpV(t, x, U, z)
172
-
173
- # the models expect to be provided with a unit normal in the boundary fluxes
174
- def jumpDF(t, x, U, DU, Fv):
175
- # (sigma.n-gN)*ds(N) = - wN ( sigma.Dphi + gN|Dphi| )
176
- # = wN ( (-sigma.Dphi) - gN(t,x,-Dphi/|Dphi|)|Dphi| )
177
- # = wN ( sigma.sn - gN(t,x,sn) ) with sn = -Dphi
178
- jdf = zero(U.ufl_shape)
179
-
180
- fv_scaled = Fv * domain.scaledNormal(x)
181
- for g, w in zip(boundaryDFlux.values(), bN_weight):
182
- g_tmp = BaseModel._createF(v=g, U=U, DU=DU, N=domain.scaledNormal(x))
183
- g_ext = domain.omega.boundary_extend(g_tmp)
184
-
185
- jdf += w(t, x) * (fv_scaled - g_ext(t, x))
186
-
187
- return jdf / total_weight(t, x)
188
-
189
- def jumpAF(t, x, U):
190
- jda = zero(U.ufl_shape)
191
-
192
- for g, w in zip(boundaryAFlux.values(), bN_weight):
193
- g_tmp = BaseModel._createF(v=g, U=U, N=domain.scaledNormal(x))
194
- g_ext = domain.omega.boundary_extend(g_tmp)
195
-
196
- jda += -w(t, x) * g_ext(t, x)
197
-
198
- return jda / total_weight(t, x)
199
-
200
- return jumpV, gExt, jumpDF, jumpAF