ddfem 1.0.9__py3-none-any.whl → 1.0.11__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 (89) hide show
  1. ddfem/__init__.py +10 -6
  2. ddfem/__main__.py +12 -13
  3. ddfem/boundary.py +2 -2
  4. ddfem/data/2.11.dev20250709/extra.modules +14 -0
  5. ddfem/data/2.11.dev20250709/femscheme_0bb54cd4f1cd1df2477f5f59393c6a2e.cc +43 -0
  6. ddfem/data/2.11.dev20250709/femscheme_5c9e2700386c07226eb4db155fa5ef14.cc +43 -0
  7. ddfem/data/2.11.dev20250709/femscheme_765ef00d995a939c34bdc0d0cc4847ca.cc +43 -0
  8. ddfem/data/2.11.dev20250709/femspace_11b3436cb033df683615c50d5d4239bd_f14dd0b3b474c0cd816334330f55ad72.cc +45 -0
  9. ddfem/data/2.11.dev20250709/femspace_f4f043307753c8e74af23c94c28a3b0d_438586e783f51d84a82e82b0d8daceea.cc +45 -0
  10. ddfem/data/2.11.dev20250709/{integrands_3bde0abfafcf45a3cff4d1029568ab5cv1_3_a524c1196983e65de1c06d7d6afdeb44.cc → integrands_0003e4cbb961fd653fe295d2c4fa50a7v1_3_a524c1196983e65de1c06d7d6afdeb44.cc} +367 -14
  11. ddfem/data/2.11.dev20250709/{integrands_f3ca00a2ef95c9a48de9ec1b807b1b30v1_3_a524c1196983e65de1c06d7d6afdeb44.cc → integrands_0fa4a1c37449cf574971977e10cf682av1_3_a524c1196983e65de1c06d7d6afdeb44.cc} +8 -8
  12. ddfem/data/2.11.dev20250709/{integrands_2e5e6f48655bd358419554a0857f697bv1_3_a524c1196983e65de1c06d7d6afdeb44.cc → integrands_29b696aa653181a57d036f771efa8be9v1_3_a524c1196983e65de1c06d7d6afdeb44.cc} +8 -8
  13. ddfem/data/2.11.dev20250709/{integrands_5e1afa60a15644998389a84306246ea5v1_3_a524c1196983e65de1c06d7d6afdeb44.cc → integrands_536f9ba0ea4ecd1f7d4e2bc43ef29d08v1_3_a524c1196983e65de1c06d7d6afdeb44.cc} +8 -8
  14. ddfem/data/2.11.dev20250709/{integrands_008eefa148b772fa3192dd3c1728c140v1_3_a524c1196983e65de1c06d7d6afdeb44.cc → integrands_5907ab5c70328c21dd308abf09e529aev1_3_a524c1196983e65de1c06d7d6afdeb44.cc} +8 -8
  15. ddfem/data/2.11.dev20250709/{integrands_563572f4cb20b041e8198ba7d5f88584v1_3_a524c1196983e65de1c06d7d6afdeb44.cc → integrands_68eba4e963a61031a52da3365f515585v1_3_a524c1196983e65de1c06d7d6afdeb44.cc} +8 -8
  16. ddfem/data/2.11.dev20250709/integrands_83927be37e79b291517b827b9ddc1983v1_3_a524c1196983e65de1c06d7d6afdeb44.cc +533 -0
  17. ddfem/data/2.11.dev20250709/integrands_8ed2f23c088e3a3d82a3259b663796c7v1_3_a524c1196983e65de1c06d7d6afdeb44.cc +533 -0
  18. ddfem/data/2.11.dev20250709/integrands_af3bbe7d629df162ef8c570e1503bf62v1_3_a524c1196983e65de1c06d7d6afdeb44.cc +762 -0
  19. ddfem/data/2.11.dev20250709/{integrands_2339be3c67df1d67b18125c34ced69c2v1_3_a524c1196983e65de1c06d7d6afdeb44.cc → integrands_bf510277401791ad5e30831b49a8ed7cv1_3_a524c1196983e65de1c06d7d6afdeb44.cc} +25 -14
  20. ddfem/data/2.11.dev20250709/integrands_d0634430f14d3432dae186e57ec5aecav1_3_a524c1196983e65de1c06d7d6afdeb44.cc +587 -0
  21. ddfem/data/2.11.dev20250709/intro.modules +34 -100
  22. ddfem/data/2.11.dev20250709/{localfunction_10ad0a2d88c74db5f4bf5f81e138974f_a524c1196983e65de1c06d7d6afdeb44.cc → localfunction_0cb4ca9e24e2891510640b0737aaab21_a524c1196983e65de1c06d7d6afdeb44.cc} +64 -29
  23. ddfem/data/2.11.dev20250709/localfunction_0f7b2106478c5d2af781b1f377a180d2_a524c1196983e65de1c06d7d6afdeb44.cc +393 -0
  24. ddfem/data/2.11.dev20250709/localfunction_10f9d7a54f79c12d6ca923b9ee56b80d_a524c1196983e65de1c06d7d6afdeb44.cc +324 -0
  25. ddfem/data/2.11.dev20250709/localfunction_10f9d7a54f79c12d6ca923b9ee56b80d_af122c1df944c95cd395ec0f91d0f970.cc +322 -0
  26. ddfem/data/2.11.dev20250709/localfunction_1c20e613977d8cea4cf5227c12aa68a6_a524c1196983e65de1c06d7d6afdeb44.cc +164 -0
  27. ddfem/data/2.11.dev20250709/{localfunction_191355e6250b2d2e260d96f519ad9976_a524c1196983e65de1c06d7d6afdeb44.cc → localfunction_217e4bf8b368a7768c4897cf58f71d84_a524c1196983e65de1c06d7d6afdeb44.cc} +14 -14
  28. ddfem/data/2.11.dev20250709/localfunction_22e797a8f3e8c322f33c41e07bd15165_a524c1196983e65de1c06d7d6afdeb44.cc +1445 -0
  29. ddfem/data/2.11.dev20250709/localfunction_2a97db5a6a479d02138a836cb0890cf2_a524c1196983e65de1c06d7d6afdeb44.cc +173 -0
  30. ddfem/data/2.11.dev20250709/localfunction_2e2afc8df6107683d574a8d96d5249f4_af122c1df944c95cd395ec0f91d0f970.cc +512 -0
  31. ddfem/data/2.11.dev20250709/localfunction_32613626342183eafa360dc1f0f18924_a524c1196983e65de1c06d7d6afdeb44.cc +1425 -0
  32. ddfem/data/2.11.dev20250709/localfunction_37174cfc9d6bf565336cac0d2ea785f5_a524c1196983e65de1c06d7d6afdeb44.cc +786 -0
  33. ddfem/data/2.11.dev20250709/{localfunction_d75993d7ae5919d23117b153e900840d_a524c1196983e65de1c06d7d6afdeb44.cc → localfunction_3d957c5b2628e5120636b8e3f461bc0d_a524c1196983e65de1c06d7d6afdeb44.cc} +64 -29
  34. ddfem/data/2.11.dev20250709/localfunction_3ecaa105be9e3abddf3a85d8adc5d36f_a524c1196983e65de1c06d7d6afdeb44.cc +697 -0
  35. ddfem/data/2.11.dev20250709/{localfunction_f626cd43dc8558135fe0b32cde016644_a524c1196983e65de1c06d7d6afdeb44.cc → localfunction_3ecaf7de7505b53bb0b5fb6d78549387_a524c1196983e65de1c06d7d6afdeb44.cc} +14 -14
  36. ddfem/data/2.11.dev20250709/{localfunction_1d27a90a52b9053192c9cc902283f79b_a524c1196983e65de1c06d7d6afdeb44.cc → localfunction_4192604521151252f1c8fa56a1f9f226_a524c1196983e65de1c06d7d6afdeb44.cc} +14 -14
  37. ddfem/data/2.11.dev20250709/localfunction_4484607e3f9bd9999dbd7bb9d595a7b2_a524c1196983e65de1c06d7d6afdeb44.cc +173 -0
  38. ddfem/data/2.11.dev20250709/localfunction_4976bbef3267846b59f3a26497ffe9db_a524c1196983e65de1c06d7d6afdeb44.cc +474 -0
  39. ddfem/data/2.11.dev20250709/{localfunction_a8c726f728cd35d137188b33301aeef1_a524c1196983e65de1c06d7d6afdeb44.cc → localfunction_4adfaf8a08fac23151af0b1e790db1f7_a524c1196983e65de1c06d7d6afdeb44.cc} +14 -14
  40. ddfem/data/2.11.dev20250709/{localfunction_00f2e5593eeb23f01906255d67244f6e_a524c1196983e65de1c06d7d6afdeb44.cc → localfunction_4f6a526abfe63959f81b09a5796c5eb1_a524c1196983e65de1c06d7d6afdeb44.cc} +44 -29
  41. ddfem/data/2.11.dev20250709/localfunction_5591a2c803b9658084d8f11d44bf3ae1_a524c1196983e65de1c06d7d6afdeb44.cc +485 -0
  42. ddfem/data/2.11.dev20250709/localfunction_6363af791dde11d699a9a3d876cc5d9a_a524c1196983e65de1c06d7d6afdeb44.cc +549 -0
  43. ddfem/data/2.11.dev20250709/localfunction_6363af791dde11d699a9a3d876cc5d9a_af122c1df944c95cd395ec0f91d0f970.cc +547 -0
  44. ddfem/data/2.11.dev20250709/localfunction_65bda5736a84d4aa0ef2d48ebcc90ed5_a524c1196983e65de1c06d7d6afdeb44.cc +173 -0
  45. ddfem/data/2.11.dev20250709/localfunction_6eccfc8fd91ce34d81e7c3962ece5d94_a524c1196983e65de1c06d7d6afdeb44.cc +766 -0
  46. ddfem/data/2.11.dev20250709/localfunction_762aa49bc5a47ad3d8d8bbde36b42ee5_a524c1196983e65de1c06d7d6afdeb44.cc +723 -0
  47. ddfem/data/2.11.dev20250709/localfunction_76e8db0f046ac9e37a793e0bb13eea7b_a524c1196983e65de1c06d7d6afdeb44.cc +292 -0
  48. ddfem/data/2.11.dev20250709/localfunction_7792f4273b0fd848c5a0fc9d6f12683e_a524c1196983e65de1c06d7d6afdeb44.cc +280 -0
  49. ddfem/data/2.11.dev20250709/localfunction_7d81d496538f240d504e5597484ee746_a524c1196983e65de1c06d7d6afdeb44.cc +462 -0
  50. ddfem/data/2.11.dev20250709/localfunction_7f7ef99c50708814ba5a82b0956b0aed_a524c1196983e65de1c06d7d6afdeb44.cc +461 -0
  51. ddfem/data/2.11.dev20250709/localfunction_898de4ae138e0ed305ef1399c66aa10a_a524c1196983e65de1c06d7d6afdeb44.cc +313 -0
  52. ddfem/data/2.11.dev20250709/localfunction_98b04b00bb93b8c6da99c91867e597ca_a524c1196983e65de1c06d7d6afdeb44.cc +639 -0
  53. ddfem/data/2.11.dev20250709/{localfunction_86a0670f34bf2ac8155423a1c1bc2e75_a524c1196983e65de1c06d7d6afdeb44.cc → localfunction_a46a988b5d8571e80fd401a36d7341b7_a524c1196983e65de1c06d7d6afdeb44.cc} +64 -29
  54. ddfem/data/2.11.dev20250709/{localfunction_1d13146d4bff10e178aba773fe2a9f1d_a524c1196983e65de1c06d7d6afdeb44.cc → localfunction_a99a0c7f35b06ac5a1fa7f081b5e64f9_a524c1196983e65de1c06d7d6afdeb44.cc} +14 -14
  55. ddfem/data/2.11.dev20250709/{localfunction_e4557ecff74fe5b37313674e67db2782_a524c1196983e65de1c06d7d6afdeb44.cc → localfunction_a9bb07439605d560b583608f20441342_a524c1196983e65de1c06d7d6afdeb44.cc} +67 -29
  56. ddfem/data/2.11.dev20250709/{localfunction_82d7cb9338bf118426fac2abf41a91a4_a524c1196983e65de1c06d7d6afdeb44.cc → localfunction_cda923259a47bb19861404a9fdb64303_a524c1196983e65de1c06d7d6afdeb44.cc} +14 -14
  57. ddfem/data/2.11.dev20250709/localfunction_d0f33c2dc1ae0e619d85a7621c8e83a6_a524c1196983e65de1c06d7d6afdeb44.cc +325 -0
  58. ddfem/data/2.11.dev20250709/localfunction_d3d9b8a21e3075c9ff40117c5244f28e_a524c1196983e65de1c06d7d6afdeb44.cc +381 -0
  59. ddfem/data/2.11.dev20250709/localfunction_d4b9ca85d48735ee01f395a42eaa0cee_af122c1df944c95cd395ec0f91d0f970.cc +774 -0
  60. ddfem/data/2.11.dev20250709/localfunction_dd1fb4bd60f2d8b3a062dbbdaedb9fee_a524c1196983e65de1c06d7d6afdeb44.cc +869 -0
  61. ddfem/data/2.11.dev20250709/localfunction_dd5ab085a9d94f578c1f3d337ea360a3_a524c1196983e65de1c06d7d6afdeb44.cc +161 -0
  62. ddfem/data/2.11.dev20250709/{localfunction_3e323e81c52891c0ecb656eac273e52f_a524c1196983e65de1c06d7d6afdeb44.cc → localfunction_e2b19c5987f9b6fb0cd5453bfa7f4f9f_a524c1196983e65de1c06d7d6afdeb44.cc} +14 -30
  63. ddfem/data/2.11.dev20250709/{localfunction_e69118a51208cfab8a028711e966e76c_19659fe2f2f74bcfb5d532f1a0d38be9.cc → localfunction_e85b93fe9b8fcd40ee82782fc600b65b_a524c1196983e65de1c06d7d6afdeb44.cc} +89 -78
  64. ddfem/data/extra.modules +13 -0
  65. ddfem/examples/beam.py +43 -50
  66. ddfem/examples/chemical_reaction.py +1 -1
  67. ddfem/examples/five_circle_flat.py +42 -28
  68. ddfem/examples/linear_elasticity.py +5 -1
  69. ddfem/examples/triple_circle.py +86 -83
  70. ddfem/examples/triple_circle_beam.py +71 -61
  71. ddfem/geometry/primitive_base.py +1 -1
  72. {ddfem-1.0.9.dist-info → ddfem-1.0.11.dist-info}/METADATA +35 -3
  73. ddfem-1.0.11.dist-info/RECORD +124 -0
  74. ddfem/data/2.11.dev20250709/boundary.modules +0 -9
  75. ddfem/data/2.11.dev20250709/femspace_90f0a9524a8cb701e8ee5027b7658a0e_0faf32f13b591f4f60f83c591507b9be.cc +0 -40
  76. ddfem/data/2.11.dev20250709/geometry.modules +0 -84
  77. ddfem/data/2.11.dev20250709/hierarchicalgrid_966e2a5c8356c5b278ccd3acad180f0a.cc +0 -30
  78. ddfem/data/2.11.dev20250709/localfunction_aeb3d963412cdc65630e0a4c3c0dde0f_a524c1196983e65de1c06d7d6afdeb44.cc +0 -135
  79. ddfem/data/2.11.dev20250709/localfunction_bdfb7ddf42a423f7d0791458634d4b8f_a524c1196983e65de1c06d7d6afdeb44.cc +0 -135
  80. ddfem/data/2.11.dev20250709/localfunction_c5ebc4ae4b5d3bad6be770eb08c50d08_19659fe2f2f74bcfb5d532f1a0d38be9.cc +0 -1131
  81. ddfem/data/2.11.dev20250709/localfunction_f4583c5cc10d24a8bdedf7510ce9da7b_a524c1196983e65de1c06d7d6afdeb44.cc +0 -299
  82. ddfem/data/2.11.dev20250709/localfunction_f4b1d42cbb447375f39ed834570cd3f0_a524c1196983e65de1c06d7d6afdeb44.cc +0 -135
  83. ddfem/data/2.11.dev20250709/localfunction_fc22d5adaf3b9563160dc2aec55e8ba1_19659fe2f2f74bcfb5d532f1a0d38be9.cc +0 -113
  84. ddfem/data/2.11.dev20250709/transformers.modules +0 -13
  85. ddfem/data/2.11.dev20250709/yaspcoordinates_dim2_ctdouble.cc +0 -55
  86. ddfem-1.0.9.dist-info/RECORD +0 -96
  87. {ddfem-1.0.9.dist-info → ddfem-1.0.11.dist-info}/WHEEL +0 -0
  88. {ddfem-1.0.9.dist-info → ddfem-1.0.11.dist-info}/licenses/LICENSE +0 -0
  89. {ddfem-1.0.9.dist-info → ddfem-1.0.11.dist-info}/top_level.txt +0 -0
ddfem/examples/beam.py CHANGED
@@ -1,14 +1,10 @@
1
1
  import numpy as np
2
2
  import pygmsh
3
- from dune.alugrid import aluConformGrid as leafGridView
4
- from dune.fem import adapt, mark, markNeighbors
5
- from dune.fem.function import gridFunction
6
- from dune.fem.space import lagrange
7
- from dune.fem.view import adaptiveLeafGridView
8
3
  from dune.grid import cartesianDomain
9
4
  from dune.ufl import Constant, Space
10
5
  from ufl import SpatialCoordinate, sqrt
11
6
 
7
+ from ddfem import GridView
12
8
  from ddfem import geometry as gm
13
9
  from ddfem.geometry.domain_dune import DomainDune
14
10
 
@@ -45,31 +41,42 @@ def getDomain(initialRefine, version, adaptLevels=0, epsFactor=4.5, *args, **kwa
45
41
  r_min = epsilon.value
46
42
  r_max = radius * epsilon.value
47
43
  dist = np.abs(sdf((x, y)))
48
- if dist <= r_min:
49
- return geom.characteristic_length_min
50
- elif dist >= r_max:
51
- return geom.characteristic_length_max
52
- else:
44
+
45
+ gmax = geom.characteristic_length_max
46
+ gmin = geom.characteristic_length_min
47
+
48
+ if False:
53
49
  # Linear
54
- m = (geom.characteristic_length_max - geom.characteristic_length_min) / (
55
- r_max - r_min
56
- )
57
- return m * (dist - r_min) + geom.characteristic_length_min
50
+ if dist <= r_min:
51
+ return gmin
52
+ elif dist >= r_max:
53
+ return gmax
54
+ else:
55
+ m = (gmax - gmin) / (r_max - r_min)
56
+ return m * (dist - r_min) + gmin
57
+
58
+ else:
59
+ # Exponential
60
+ R = int(2 * np.log2(gmax / gmin))
61
+ j = max(0, min(R, (dist * R) / r_max - 0.5))
62
+ # j = max(0, min(R, np.floor(dist * R / r_max)))
63
+ return gmax * 0.5 ** ((R - j) / 2)
64
+
65
+ omega.epsilon = get_eps(h_min)
58
66
 
59
67
  if version == "cartesian":
68
+ omega.epsilon = get_eps(h)
60
69
  domain = cartesianDomain(*domain_range, initial_gridsize)
61
- epsilon = get_eps(h)
62
70
 
63
71
  elif version == "fitted":
64
72
  with pygmsh.occ.Geometry() as geom:
65
- geom.characteristic_length_max = h_max
66
- geom.characteristic_length_min = h_min
67
- epsilon = get_eps(h_min)
73
+ geom.characteristic_length_max = h_max / sqrt(2)
74
+ geom.characteristic_length_min = h_min / sqrt(2)
68
75
 
69
76
  rec = geom.add_rectangle([0, 0, 0], 1, 0.15)
70
77
 
71
78
  geom.set_mesh_size_callback(
72
- lambda dim, tag, x, y, z, lc: spacing(x, y, epsilon),
79
+ lambda dim, tag, x, y, z, lc: spacing(x, y, omega.epsilon),
73
80
  ignore_other_mesh_sizes=True,
74
81
  )
75
82
 
@@ -86,12 +93,11 @@ def getDomain(initialRefine, version, adaptLevels=0, epsFactor=4.5, *args, **kwa
86
93
 
87
94
  elif version == "gmsh_adaptive":
88
95
  with pygmsh.occ.Geometry() as geom:
89
- geom.characteristic_length_max = h_max
90
- geom.characteristic_length_min = h_min
91
- epsilon = get_eps(h_min)
96
+ geom.characteristic_length_max = h_max / sqrt(2)
97
+ geom.characteristic_length_min = h_min / sqrt(2)
92
98
 
93
99
  geom.set_mesh_size_callback(
94
- lambda dim, tag, x, y, z, lc: spacing(x, y, epsilon),
100
+ lambda dim, tag, x, y, z, lc: spacing(x, y, omega.epsilon),
95
101
  ignore_other_mesh_sizes=True,
96
102
  )
97
103
 
@@ -111,37 +117,24 @@ def getDomain(initialRefine, version, adaptLevels=0, epsFactor=4.5, *args, **kwa
111
117
  else:
112
118
  raise ValueError("invalid mesh type")
113
119
 
114
- gridView = adaptiveLeafGridView(leafGridView(domain))
115
-
116
120
  if version == "dune_adaptive":
117
- omega.epsilon = get_eps(h_min)
118
- omega.epsilon.value *= radius
119
- epsilon_value = omega.epsilon.value
120
-
121
- marker = mark
122
-
123
121
  refinements = int(2 * np.log2(h_max / h_min))
124
-
125
- region = gridFunction(
126
- omega.phi(x) * (1 - omega.phi(x)), gridView=gridView
127
- ) # interface
128
-
129
- for j in range(1, refinements + 1):
130
-
131
- omega.epsilon.value = epsilon_value * j / refinements
132
- marker(region, 0.00247262315663, maxLevel=refinements) # 1 epsilon
133
-
134
- adapt(gridView.hierarchicalGrid)
135
-
136
- h_min = h_max * 0.5 ** (j / 2)
137
- epsilon = get_eps(h_min)
138
-
139
- omega.epsilon = epsilon
140
- domain = omega
122
+ gridView = GridView(
123
+ domain,
124
+ omega,
125
+ factor=radius,
126
+ refinements=refinements,
127
+ adaptLevels=adaptLevels,
128
+ )
129
+ h_min = h_max * 0.5 ** (refinements / 2)
130
+ omega.epsilon = get_eps(h_min)
131
+ else:
132
+ gridView = GridView(domain)
141
133
 
142
134
  domain = DomainDune(omega, gridView)
143
- # domain.adapt(level=adaptLevels)
144
135
 
145
- print(f"h={h * 0.5 ** (adaptLevels / 2)}, epsilon={epsilon.value}")
136
+ print(
137
+ f"h_max={h_max}, h_min={h_min * 0.5 ** (adaptLevels / 2)}, epsilon={omega.epsilon.value}"
138
+ )
146
139
 
147
140
  return gridView, domain
@@ -37,7 +37,7 @@ def crModel():
37
37
 
38
38
  def setup(u_h, DDMPotentialModel, psi_h):
39
39
  ChemModel.u_h_n = u_h.copy(name="u_h_n")
40
- ChemModel.u_h_n.interpolate(zero(ChemModel.dimRange))
40
+ ChemModel.u_h_n.clear()
41
41
 
42
42
  ChemModel.dpsi_h = lambda x: DDMPotentialModel.sigma(
43
43
  0, x, psi_h, grad(psi_h)
@@ -15,14 +15,12 @@ pip install dune-fem
15
15
  """
16
16
  )
17
17
 
18
- from dune.fem.function import gridFunction
19
- from dune.fem.space import lagrange
20
18
  from dune.grid import cartesianDomain
21
19
  from dune.ufl import Constant, Space
22
20
  from ufl import SpatialCoordinate, sqrt
23
21
 
24
- from ddfem import geometry as gm
25
22
  from ddfem import GridView
23
+ from ddfem import geometry as gm
26
24
  from ddfem.geometry.domain_dune import DomainDune
27
25
 
28
26
 
@@ -75,7 +73,7 @@ def getDomain(
75
73
 
76
74
  h_max = h * 3
77
75
  h_min = h / 2
78
- radius = 5
76
+ radius = 4
79
77
 
80
78
  x = SpatialCoordinate(Space(2))
81
79
  sdf = omega(x)
@@ -84,28 +82,40 @@ def getDomain(
84
82
  r_min = epsilon.value
85
83
  r_max = radius * epsilon.value
86
84
  dist = np.abs(sdf((x, y)))
87
- if dist <= r_min:
88
- return geom.characteristic_length_min
89
- elif dist >= r_max:
90
- return geom.characteristic_length_max
91
- else:
85
+
86
+ gmax = geom.characteristic_length_max
87
+ gmin = geom.characteristic_length_min
88
+
89
+ if False:
92
90
  # Linear
93
- m = (geom.characteristic_length_max - geom.characteristic_length_min) / (
94
- r_max - r_min
95
- )
96
- return m * (dist - r_min) + geom.characteristic_length_min
91
+ if dist <= r_min:
92
+ return gmin
93
+ elif dist >= r_max:
94
+ return gmax
95
+ else:
96
+ m = (gmax - gmin) / (r_max - r_min)
97
+ return m * (dist - r_min) + gmin
97
98
 
98
- omega.epsilon = get_eps(h)
99
+ else:
100
+ # Exponential
101
+ R = int(2 * np.log2(gmax / gmin))
102
+ j = max(0, min(R, (dist * R) / r_max - 0.5))
103
+ # j = max(0, min(R, np.floor(dist * R / r_max)))
104
+ return gmax * 0.5 ** ((R - j) / 2)
105
+
106
+ omega.epsilon = get_eps(h_min)
99
107
 
100
108
  if version == "cartesian":
101
- domain = cartesianDomain(*domain_range, initial_gridsize)
109
+ omega.epsilon = get_eps(h)
110
+ # domain = cartesianDomain(*domain_range, initial_gridsize)
111
+ domain = [*domain_range, initial_gridsize]
102
112
 
103
113
  elif version == "fitted":
104
114
  if pygmsh is None:
105
115
  raise AttributeError("'fitted' requires install pygmsh")
106
116
  with pygmsh.occ.Geometry() as geom:
107
- geom.characteristic_length_max = h_max
108
- geom.characteristic_length_min = h_min
117
+ geom.characteristic_length_max = h_max / sqrt(2)
118
+ geom.characteristic_length_min = h_min / sqrt(2)
109
119
 
110
120
  disks = [geom.add_disk([c[1][0], c[1][1], 0.0], c[0]) for c in balls]
111
121
 
@@ -136,8 +146,8 @@ def getDomain(
136
146
  if pygmsh is None:
137
147
  raise AttributeError("'gmsh_adaptive' requires install pygmsh")
138
148
  with pygmsh.occ.Geometry() as geom:
139
- geom.characteristic_length_max = h_max
140
- geom.characteristic_length_min = h_min
149
+ geom.characteristic_length_max = h_max / sqrt(2)
150
+ geom.characteristic_length_min = h_min / sqrt(2)
141
151
 
142
152
  geom.add_rectangle(
143
153
  [domain_range[0][0], domain_range[0][1], 0.0],
@@ -158,18 +168,22 @@ def getDomain(
158
168
  else:
159
169
  raise ValueError("invalid mesh type")
160
170
 
161
- if not version == "dune_adaptive":
162
- gridView = GridView(domain)
163
- else:
171
+ if version == "dune_adaptive":
164
172
  refinements = int(2 * np.log2(h_max / h_min))
165
- gridView = GridView(domain,omega,
166
- factor=radius,
167
- refinements=refinements,
168
- adaptLevels=adaptLevels)
173
+ gridView = GridView(
174
+ domain,
175
+ omega,
176
+ filterTolerance=10 * omega.epsilon.value,
177
+ factor=radius,
178
+ refinements=refinements,
179
+ adaptLevels=adaptLevels,
180
+ )
169
181
  h_min = h_max * 0.5 ** (refinements / 2)
170
- omega.epsilon.value = get_eps(h_min)
182
+ omega.epsilon = get_eps(h_min)
183
+ else:
184
+ gridView = GridView(domain)
171
185
 
172
- domain = DomainDune(omega, gridView)
186
+ domain = DomainDune(omega, gridView, filterTolerance=10 * omega.epsilon.value)
173
187
 
174
188
  print(
175
189
  f"h_max={h_max}, h_min={h_min * 0.5 ** (adaptLevels / 2)}, epsilon={omega.epsilon.value}"
@@ -1,5 +1,5 @@
1
1
  from dune.ufl import Constant
2
- from ufl import Identity, as_vector, div, grad, sym, tr, zero
2
+ from ufl import Identity, as_vector, inner, sqrt, sym, tr
3
3
 
4
4
  from ddfem.boundary import BndFlux_v, BndValue
5
5
 
@@ -28,6 +28,10 @@ def leModel():
28
28
  def S_i(t, x, U, DU):
29
29
  return as_vector([0.0, -Model.rho * Model.g])
30
30
 
31
+ def von_Mises(U, DU):
32
+ s = Model.sigma(U, DU) - (1.0 / 3) * tr(Model.sigma(U, DU)) * Identity(2)
33
+ return sqrt(3.0 / 2 * inner(s, s))
34
+
31
35
  valD = lambda t, x, U: Model.vd
32
36
 
33
37
  valN = lambda t, x, U, DU, n: Model.vn
@@ -15,15 +15,11 @@ pip install dune-fem
15
15
  """
16
16
  )
17
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
18
  from dune.grid import cartesianDomain
24
19
  from dune.ufl import Constant, Space
25
20
  from ufl import SpatialCoordinate, sqrt
26
21
 
22
+ from ddfem import GridView
27
23
  from ddfem import geometry as gm
28
24
  from ddfem.geometry.domain_dune import DomainDune
29
25
 
@@ -61,7 +57,7 @@ def getDomain(
61
57
 
62
58
  h_max = h * 3
63
59
  h_min = h / 2
64
- radius = 5
60
+ radius = 4
65
61
 
66
62
  x = SpatialCoordinate(Space(2))
67
63
  sdf = omega(x)
@@ -70,51 +66,61 @@ def getDomain(
70
66
  r_min = epsilon.value
71
67
  r_max = radius * epsilon.value
72
68
  dist = np.abs(sdf((x, y)))
73
- if dist <= r_min:
74
- return geom.characteristic_length_min
75
- elif dist >= r_max:
76
- return geom.characteristic_length_max
77
- else:
78
- # Linear
79
- m = (geom.characteristic_length_max - geom.characteristic_length_min) / (
80
- r_max - r_min
81
- )
82
- return m * (dist - r_min) + geom.characteristic_length_min
83
69
 
84
- if version == "cartesian":
85
- domain = cartesianDomain(*domain_range, initial_gridsize)
86
- epsilon = get_eps(h)
70
+ gmax = geom.characteristic_length_max
71
+ gmin = geom.characteristic_length_min
87
72
 
88
- elif version == "fitted":
89
- if pygmsh is None:
90
- raise AttributeError("'fitted' requires install pygmsh")
91
- with pygmsh.occ.Geometry() as geom:
92
- geom.characteristic_length_max = h_max
93
- geom.characteristic_length_min = h_min
94
- epsilon = get_eps(h_min)
73
+ if False:
74
+ # Linear
75
+ if dist <= r_min:
76
+ return gmin
77
+ elif dist >= r_max:
78
+ return gmax
79
+ else:
80
+ m = (gmax - gmin) / (r_max - r_min)
81
+ return m * (dist - r_min) + gmin
95
82
 
96
- disks = [geom.add_disk([c[1][0], c[1][1], 0.0], c[0]) for c in balls]
83
+ else:
84
+ # Exponential
85
+ R = int(2 * np.log2(gmax / gmin))
86
+ j = max(0, min(R, (dist * R) / r_max - 0.5))
87
+ # j = max(0, min(R, np.floor(dist * R / r_max)))
88
+ return gmax * 0.5 ** ((R - j) / 2)
97
89
 
98
- ds = geom.boolean_union([disks[0], disks[1]])
99
- shape = geom.boolean_intersection([ds, disks[2]])
100
- if inverted:
101
- rectangle = geom.add_rectangle(
102
- [domain_range[0][0], domain_range[0][1], 0.0],
103
- domain_range[1][0] - domain_range[0][0],
104
- domain_range[1][1] - domain_range[0][1],
105
- )
106
- geom.boolean_difference(rectangle, shape)
90
+ omega.epsilon = get_eps(h_min)
91
+ if version == "cartesian":
92
+ omega.epsilon = get_eps(h)
93
+ domain = cartesianDomain(*domain_range, initial_gridsize)
107
94
 
108
- geom.set_mesh_size_callback(
109
- lambda dim, tag, x, y, z, lc: spacing(x, y, epsilon),
110
- ignore_other_mesh_sizes=True,
111
- )
112
- mesh = geom.generate_mesh()
113
- points, cells = mesh.points, mesh.cells_dict
114
- domain = {
115
- "vertices": points[:, :2].astype(float),
116
- "simplices": cells["triangle"].astype(int),
117
- }
95
+ # elif version == "fitted":
96
+ # if pygmsh is None:
97
+ # raise AttributeError("'fitted' requires install pygmsh")
98
+ # with pygmsh.occ.Geometry() as geom:
99
+ # geom.characteristic_length_max = h_max / sqrt(2)
100
+ # geom.characteristic_length_min = h_min / sqrt(2)
101
+
102
+ # disks = [geom.add_disk([c[1][0], c[1][1], 0.0], c[0]) for c in balls]
103
+
104
+ # ds = geom.boolean_union([disks[0], disks[1]])
105
+ # shape = geom.boolean_intersection([ds, disks[2]])
106
+ # if inverted:
107
+ # rectangle = geom.add_rectangle(
108
+ # [domain_range[0][0], domain_range[0][1], 0.0],
109
+ # domain_range[1][0] - domain_range[0][0],
110
+ # domain_range[1][1] - domain_range[0][1],
111
+ # )
112
+ # geom.boolean_difference(rectangle, shape)
113
+
114
+ # geom.set_mesh_size_callback(
115
+ # lambda dim, tag, x, y, z, lc: spacing(x, y, omega.epsilon),
116
+ # ignore_other_mesh_sizes=True,
117
+ # )
118
+ # mesh = geom.generate_mesh()
119
+ # points, cells = mesh.points, mesh.cells_dict
120
+ # domain = {
121
+ # "vertices": points[:, :2].astype(float),
122
+ # "simplices": cells["triangle"].astype(int),
123
+ # }
118
124
 
119
125
  elif version == "dune_adaptive":
120
126
  gridsize = [int(j * h / h_max) for j in initial_gridsize]
@@ -124,9 +130,8 @@ def getDomain(
124
130
  if pygmsh is None:
125
131
  raise AttributeError("'gmsh_adaptive' requires install pygmsh")
126
132
  with pygmsh.occ.Geometry() as geom:
127
- geom.characteristic_length_max = h_max
128
- geom.characteristic_length_min = h_min
129
- epsilon = get_eps(h_min)
133
+ geom.characteristic_length_max = h_max / sqrt(2)
134
+ geom.characteristic_length_min = h_min / sqrt(2)
130
135
 
131
136
  geom.add_rectangle(
132
137
  [domain_range[0][0], domain_range[0][1], 0.0],
@@ -135,7 +140,7 @@ def getDomain(
135
140
  )
136
141
 
137
142
  geom.set_mesh_size_callback(
138
- lambda dim, tag, x, y, z, lc: spacing(x, y, epsilon),
143
+ lambda dim, tag, x, y, z, lc: spacing(x, y, omega.epsilon),
139
144
  ignore_other_mesh_sizes=True,
140
145
  )
141
146
  mesh = geom.generate_mesh()
@@ -145,13 +150,12 @@ def getDomain(
145
150
  "simplices": cells["triangle"].astype(int),
146
151
  }
147
152
 
148
- elif version == "gmsh_embedded":
153
+ elif version == "gmsh_embedded" or version == "fitted":
149
154
  if pygmsh is None:
150
155
  raise AttributeError("'fitted' requires install pygmsh")
151
156
  with pygmsh.occ.Geometry() as geom:
152
- geom.characteristic_length_max = h_max
153
- geom.characteristic_length_min = h_min
154
- epsilon = get_eps(h_min)
157
+ geom.characteristic_length_max = h_max / sqrt(2)
158
+ geom.characteristic_length_min = h_min / sqrt(2)
155
159
 
156
160
  disks = [geom.add_disk([c[1][0], c[1][1], 0.0], c[0]) for c in balls]
157
161
 
@@ -165,53 +169,52 @@ def getDomain(
165
169
 
166
170
  geom.boolean_fragments(rectangle, shape)
167
171
 
172
+ geom.add_physical(shape, label="fitted_domain")
173
+
168
174
  geom.set_mesh_size_callback(
169
- lambda dim, tag, x, y, z, lc: spacing(x, y, epsilon),
175
+ lambda dim, tag, x, y, z, lc: spacing(x, y, omega.epsilon),
170
176
  ignore_other_mesh_sizes=True,
171
177
  )
172
178
  mesh = geom.generate_mesh()
173
179
  points, cells = mesh.points, mesh.cells_dict
180
+
181
+ if version == "fitted":
182
+ fitted_domain_indices = mesh.cell_sets_dict["fitted_domain"]["triangle"]
183
+ mesh_cells = cells["triangle"][fitted_domain_indices].astype(int)
184
+ else:
185
+ mesh_cells = cells["triangle"].astype(int)
186
+
174
187
  domain = {
175
188
  "vertices": points[:, :2].astype(float),
176
- "simplices": cells["triangle"].astype(int),
189
+ "simplices": mesh_cells,
177
190
  }
178
191
 
179
192
  else:
180
193
  raise ValueError("invalid mesh type")
181
194
 
182
- gridView = adaptiveLeafGridView(leafGridView(domain))
183
-
184
195
  if version == "dune_adaptive":
185
- omega.epsilon = get_eps(h_min)
186
- omega.epsilon.value *= radius
187
- epsilon_value = omega.epsilon.value
188
-
189
- marker = mark
190
-
191
196
  refinements = int(2 * np.log2(h_max / h_min))
192
-
193
- region = gridFunction(
194
- omega.phi(x) * (1 - omega.phi(x)), gridView=gridView
195
- ) # interface
196
-
197
- for j in range(1, refinements + 1):
198
-
199
- omega.epsilon.value = epsilon_value * j / refinements
200
- marker(region, 0.00247262315663, maxLevel=refinements) # 1 epsilon
201
-
202
- adapt(gridView.hierarchicalGrid)
203
-
204
- h_min = h_max * 0.5 ** (j / 2)
205
- epsilon = get_eps(h_min)
206
-
207
- omega.epsilon = epsilon
208
- domain = omega
197
+ gridView = GridView(
198
+ domain,
199
+ omega,
200
+ filterTolerance=10 * omega.epsilon.value,
201
+ factor=radius,
202
+ refinements=refinements,
203
+ adaptLevels=adaptLevels,
204
+ )
205
+ h_min = h_max * 0.5 ** (refinements / 2)
206
+ omega.epsilon = get_eps(h_min)
207
+ else:
208
+ gridView = GridView(
209
+ domain,
210
+ omega,
211
+ filterTolerance=10 * omega.epsilon.value,
212
+ )
209
213
 
210
214
  domain = DomainDune(omega, gridView)
211
- domain.adapt(level=adaptLevels)
212
215
 
213
216
  print(
214
- f"h_max={h_max}, h_min={h_min * 0.5 ** (adaptLevels / 2)}, epsilon={epsilon.value}"
217
+ f"h_max={h_max}, h_min={h_min * 0.5 ** (adaptLevels / 2)}, epsilon={omega.epsilon.value}"
215
218
  )
216
219
 
217
220
  return gridView, domain