ddfem 1.0.0__py3-none-any.whl → 1.0.2__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 (45) hide show
  1. ddfem/__init__.py +5 -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 +19 -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 +11 -4
  29. ddfem/plot.py +13 -0
  30. ddfem/transformers/DDM1.py +10 -68
  31. ddfem/transformers/Fitted.py +22 -12
  32. ddfem/transformers/Mix0.py +10 -64
  33. ddfem/transformers/NNS.py +11 -72
  34. ddfem/transformers/NS.py +14 -79
  35. ddfem/transformers/__init__.py +1 -0
  36. ddfem/transformers/transformer_base.py +102 -15
  37. {ddfem-1.0.0.dist-info → ddfem-1.0.2.dist-info}/METADATA +5 -6
  38. ddfem-1.0.2.dist-info/RECORD +41 -0
  39. ddfem/base_model.py +0 -200
  40. ddfem/dune.py +0 -3
  41. ddfem/geometry/circle.py +0 -39
  42. ddfem-1.0.0.dist-info/RECORD +0 -27
  43. {ddfem-1.0.0.dist-info → ddfem-1.0.2.dist-info}/WHEEL +0 -0
  44. {ddfem-1.0.0.dist-info → ddfem-1.0.2.dist-info}/licenses/LICENSE +0 -0
  45. {ddfem-1.0.0.dist-info → ddfem-1.0.2.dist-info}/top_level.txt +0 -0
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
ddfem/dune.py DELETED
@@ -1,3 +0,0 @@
1
- import geometry
2
- from geometry import dunedomain
3
- geometry.domain =
ddfem/geometry/circle.py DELETED
@@ -1,39 +0,0 @@
1
- from ufl import as_vector
2
-
3
- from .helpers import ufl_length
4
- from .primitive_base import ORIGIN, SDF
5
-
6
-
7
- class Circle(SDF):
8
- def __init__(self, radius, center=ORIGIN, *args, **kwargs):
9
- super().__init__(*args, **kwargs)
10
- self.radius = radius
11
-
12
- assert len(center) == 2
13
- if isinstance(center, (list, tuple)):
14
- center = as_vector(center)
15
- self.center = center
16
-
17
- def __repr__(self):
18
- return f"Circle({self.radius}, {self.center})"
19
-
20
- def sdf(self, x):
21
- center_x = x - self.center
22
- return ufl_length(center_x) - self.radius
23
-
24
- class Sphere(SDF):
25
- def __init__(self, radius, center=ORIGIN, *args, **kwargs):
26
- super().__init__(*args, **kwargs)
27
- self.radius = radius
28
-
29
- if isinstance(center, (list, tuple)):
30
- center = as_vector(center)
31
- self.center = center
32
-
33
- def __repr__(self):
34
- return f"Circle({self.radius}, {self.center})"
35
-
36
- def sdf(self, x):
37
- center_x = x - self.center
38
- return ufl_length(center_x) - self.radius
39
-
@@ -1,27 +0,0 @@
1
- ddfem/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- ddfem/base_model.py,sha256=BJGMMTy-qa3CuYVJILwcZ4mtY8cVUtzFtn9NOm87IeE,6825
3
- ddfem/boundary.py,sha256=8PQp7LXlHxA8yn4bQbF_vLljKY4XezJbPkziX9o9IvU,7196
4
- ddfem/dune.py,sha256=oU4bKiG4AndEhMVhAi1Nnmo9cEhjceTW3X2ptv6ombU,67
5
- ddfem/model2ufl.py,sha256=PhbaLqJ4DS9EVKdi22f-iFxFsd97qsN-IYK0AU3a2is,4094
6
- ddfem/geometry/__init__.py,sha256=P4mAihoy07qck7_TI-4m6NlsEM0i4wvuC_Xuo7vxHCY,293
7
- ddfem/geometry/arc.py,sha256=r8l4zQonfgWzA37B3dVXaZ5UhHgkTXL-4KedVG0PWvk,1365
8
- ddfem/geometry/box.py,sha256=QwtqYVDmZE9CLWRUqNsmw58WqjvBtG0WBoFruuJZWVs,925
9
- ddfem/geometry/circle.py,sha256=prlh37BuPIYRxo1v56UAxa2-Os1YJXsNbOWGOOMkWX4,1049
10
- ddfem/geometry/domain.py,sha256=scATAs_0qkeDuIlQ6ejl2j4GSuOZt1sL3PpT_-6aBh0,1110
11
- ddfem/geometry/domain_dune.py,sha256=eR3MXlHAE0c9swUWAsNzPEzJyqHHtU2ZMvQDPd7JiCw,2112
12
- ddfem/geometry/helpers.py,sha256=iykom4lPPQwnInydnUux8dhL1IL5kfOzJvpjSKDGaUw,825
13
- ddfem/geometry/pie.py,sha256=3X2gv4AdEYCrl5Po089luULQ6TYptEJm1SVAZR1VPHI,993
14
- ddfem/geometry/primitive_base.py,sha256=d5vedYORVKfJKFQeAULAIJFalZYn5xcZncX93hPYDlc,8041
15
- ddfem/geometry/vesica.py,sha256=NseyI7SRxGkA_wmw503P25MD524IMhkh1ZEQgUddWFA,1702
16
- ddfem/transformers/DDM1.py,sha256=pKj0PaB7m7kyLu_iHu0ol9_KU_tHeAatxwDutqRSdks,2854
17
- ddfem/transformers/Fitted.py,sha256=XTE1U68RVfezC9ascdvEBYmd6F1pn8KW5mHws02Wxns,2550
18
- ddfem/transformers/Mix0.py,sha256=DUDFt7vUvhQgMlyYSptClTYkZ1jcS2mYbZXcoCy_0zs,5530
19
- ddfem/transformers/NNS.py,sha256=yeH-sk_p6BgjHo2rThGRoiCqNETnh6Tzc5KJEFEPuqU,5310
20
- ddfem/transformers/NS.py,sha256=LBno0zhDWc81Lv2yMvxM7YpbWqnrsVUC-t0q39_gZ0k,5604
21
- ddfem/transformers/__init__.py,sha256=46DtyvhBUqtrWGBfinekdz4ahjoHW4pd7sPL2vdR-Xs,120
22
- ddfem/transformers/transformer_base.py,sha256=ho7Gz_97dA4W_7Nj6UlSQLKMaAJhdBN_mOhsD1BArRU,3888
23
- ddfem-1.0.0.dist-info/licenses/LICENSE,sha256=7EI8xVBu6h_7_JlVw-yPhhOZlpY9hP8wal7kHtqKT_E,1074
24
- ddfem-1.0.0.dist-info/METADATA,sha256=vSTe1NTH9Sleq5jIEkeDVgMVNl1TKWm2392KCsL2TnA,697
25
- ddfem-1.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
26
- ddfem-1.0.0.dist-info/top_level.txt,sha256=LF2T9-5A2Bak81PqbCcsAex8d5Xrla2Wq8yrlQi-ZtY,6
27
- ddfem-1.0.0.dist-info/RECORD,,
File without changes