drbx 2.0.0.dev0__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 (106) hide show
  1. drbx/__init__.py +20 -0
  2. drbx/__main__.py +5 -0
  3. drbx/cli.py +586 -0
  4. drbx/config/__init__.py +20 -0
  5. drbx/config/boutinp.py +556 -0
  6. drbx/config/model.py +34 -0
  7. drbx/config/normalization.py +66 -0
  8. drbx/data/atomic_rates/__init__.py +1 -0
  9. drbx/data/atomic_rates/iz_AMJUEL_H.x_2.1.5.json +213 -0
  10. drbx/data/atomic_rates/iz_AMJUEL_H.x_2.3.9a.json +213 -0
  11. drbx/data/atomic_rates/rec_AMJUEL_H.x_2.1.8.json +213 -0
  12. drbx/data/atomic_rates/rec_AMJUEL_H.x_2.3.13a.json +213 -0
  13. drbx/geometry/__init__.py +207 -0
  14. drbx/geometry/embedding.py +56 -0
  15. drbx/geometry/essos_import.py +1385 -0
  16. drbx/geometry/fci_geometry.py +4622 -0
  17. drbx/geometry/fci_maps.py +85 -0
  18. drbx/geometry/island_divertor.py +291 -0
  19. drbx/geometry/metric_tensor.py +99 -0
  20. drbx/geometry/open_slab.py +150 -0
  21. drbx/geometry/rotating_ellipse.py +253 -0
  22. drbx/geometry/shifted_torus.py +225 -0
  23. drbx/geometry/stellarator.py +287 -0
  24. drbx/geometry/vmec_extender_import.py +499 -0
  25. drbx/geometry/vmec_jax_import.py +306 -0
  26. drbx/linear/__init__.py +37 -0
  27. drbx/linear/dispersion.py +138 -0
  28. drbx/linear/eigen.py +91 -0
  29. drbx/native/__init__.py +224 -0
  30. drbx/native/array_backend.py +64 -0
  31. drbx/native/deck_runner.py +779 -0
  32. drbx/native/electromagnetic.py +250 -0
  33. drbx/native/expression.py +173 -0
  34. drbx/native/fci.py +295 -0
  35. drbx/native/fci_2_field_rhs.py +182 -0
  36. drbx/native/fci_4_field_rhs.py +1267 -0
  37. drbx/native/fci_boundaries.py +2494 -0
  38. drbx/native/fci_differentiable_case.py +304 -0
  39. drbx/native/fci_drb_EB_rhs.py +1243 -0
  40. drbx/native/fci_drb_rhs.py +190 -0
  41. drbx/native/fci_halo.py +1575 -0
  42. drbx/native/fci_helpers.py +350 -0
  43. drbx/native/fci_model.py +294 -0
  44. drbx/native/fci_neutral.py +139 -0
  45. drbx/native/fci_operators.py +4081 -0
  46. drbx/native/fci_sharding.py +597 -0
  47. drbx/native/fci_sheath_recycling.py +206 -0
  48. drbx/native/fci_time_integrator.py +96 -0
  49. drbx/native/fci_vorticity.py +198 -0
  50. drbx/native/fluid_1d.py +330 -0
  51. drbx/native/hasegawa_wakatani.py +196 -0
  52. drbx/native/limiters.py +57 -0
  53. drbx/native/mesh.py +238 -0
  54. drbx/native/metrics.py +234 -0
  55. drbx/native/neutrals/__init__.py +58 -0
  56. drbx/native/neutrals/atomic_rates.py +134 -0
  57. drbx/native/neutrals/detachment_sol_model.py +221 -0
  58. drbx/native/neutrals/reactions.py +164 -0
  59. drbx/native/neutrals/recycling_sol_model.py +197 -0
  60. drbx/native/sol_flux_tube.py +133 -0
  61. drbx/native/stellarator_turbulence.py +343 -0
  62. drbx/native/transport.py +134 -0
  63. drbx/native/units.py +32 -0
  64. drbx/native/vorticity.py +252 -0
  65. drbx/runtime/__init__.py +53 -0
  66. drbx/runtime/artifacts.py +161 -0
  67. drbx/runtime/memory.py +144 -0
  68. drbx/runtime/output.py +374 -0
  69. drbx/runtime/paths.py +9 -0
  70. drbx/runtime/performance.py +161 -0
  71. drbx/runtime/run_config.py +184 -0
  72. drbx/runtime/scheduler.py +99 -0
  73. drbx/runtime/state.py +40 -0
  74. drbx/validation/__init__.py +424 -0
  75. drbx/validation/autodiff_diffusion.py +329 -0
  76. drbx/validation/autodiff_diffusion_uncertainty.py +235 -0
  77. drbx/validation/diverted_tokamak_movie.py +558 -0
  78. drbx/validation/essos_fieldline_import_campaign.py +181 -0
  79. drbx/validation/essos_imported_artifact_audit.py +535 -0
  80. drbx/validation/essos_imported_drb_movie_campaign.py +2826 -0
  81. drbx/validation/essos_imported_fci_campaign.py +5241 -0
  82. drbx/validation/essos_imported_pytree_campaign.py +406 -0
  83. drbx/validation/essos_vmec_closed_field_campaign.py +314 -0
  84. drbx/validation/essos_vmec_closed_field_transient_campaign.py +629 -0
  85. drbx/validation/essos_vmec_fieldline_surface_campaign.py +620 -0
  86. drbx/validation/fluid_1d_mms_convergence.py +250 -0
  87. drbx/validation/geometry_lineouts.py +136 -0
  88. drbx/validation/geometry_slices.py +178 -0
  89. drbx/validation/publication_plotting.py +91 -0
  90. drbx/validation/stellarator_drb_pytree_campaign.py +621 -0
  91. drbx/validation/stellarator_fci_geometry_campaign.py +200 -0
  92. drbx/validation/stellarator_fci_operator_campaign.py +304 -0
  93. drbx/validation/stellarator_fci_suite_campaign.py +264 -0
  94. drbx/validation/stellarator_metric_mms_campaign.py +289 -0
  95. drbx/validation/stellarator_neutral_physics_campaign.py +255 -0
  96. drbx/validation/stellarator_sheath_recycling_campaign.py +331 -0
  97. drbx/validation/stellarator_sol_showcase.py +628 -0
  98. drbx/validation/stellarator_vorticity_campaign.py +304 -0
  99. drbx/validation/vmec_extender_edge_field_campaign.py +260 -0
  100. drbx/validation/vmec_extender_sol_smoke_campaign.py +365 -0
  101. drbx-2.0.0.dev0.dist-info/METADATA +380 -0
  102. drbx-2.0.0.dev0.dist-info/RECORD +106 -0
  103. drbx-2.0.0.dev0.dist-info/WHEEL +5 -0
  104. drbx-2.0.0.dev0.dist-info/entry_points.txt +2 -0
  105. drbx-2.0.0.dev0.dist-info/licenses/LICENSE +21 -0
  106. drbx-2.0.0.dev0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,213 @@
1
+ {
2
+ "info": {
3
+ "sigma_v_coeffs_ref": "Amjuel H.4 2.3.13a, page 181",
4
+ "sigma_v_E_coeffs_ref": "Amjuel H.10 2.3.13a, page 295",
5
+ "reaction_lbl": "e + he+ -> he",
6
+ "sigma_v_E_notes": "Helium multi-step model, here recombination: radiative + threebody + dielectronic. Fujimoto Formulation II (only ground level transported, no meta-stables kept explicit). The quantity given here happens to be the radiation loss. The loss of potential energy still needs to be subtracted to make this a total electron energy loss (or gain) rate.",
7
+ "sigma_v_notes": "Helium multi-step model, here recombination: radiative + threebody + dielectronic. Fujimoto Formulation II (only ground level transported, no metastables kept explicit).",
8
+ "includes_sigma_v_e": true
9
+ },
10
+ "electron_heating": 24.586,
11
+ "sigma_v_coeffs": [
12
+ [
13
+ -28.72754373123,
14
+ -0.006171082987797,
15
+ 0.02414548639597,
16
+ -0.007188662067622,
17
+ 0.0009481268604767,
18
+ -1.958887458637e-05,
19
+ -5.507786383328e-06,
20
+ 4.35828868693e-07,
21
+ -9.50327209101e-09
22
+ ],
23
+ [
24
+ 1.564233603544,
25
+ -0.03972220721457,
26
+ -0.04466712599181,
27
+ 0.01247359158796,
28
+ -0.001660591942878,
29
+ 6.019181402025e-05,
30
+ 3.800156798817e-06,
31
+ -3.377807793756e-07,
32
+ 6.828447501225e-09
33
+ ],
34
+ [
35
+ -6.182140631482,
36
+ 0.1626641668186,
37
+ 0.03366589582541,
38
+ -0.007413737965595,
39
+ 0.001220189896183,
40
+ -9.50529572475e-05,
41
+ 4.459492214068e-06,
42
+ -1.552772441333e-07,
43
+ 2.866586118879e-09
44
+ ],
45
+ [
46
+ 5.459428677778,
47
+ -0.1700323494998,
48
+ -0.01540106384088,
49
+ 0.0009524545793262,
50
+ -8.734341535385e-05,
51
+ -2.796027477899e-06,
52
+ 4.561981097438e-07,
53
+ 4.940311502014e-09,
54
+ -6.52572501076e-10
55
+ ],
56
+ [
57
+ -2.128115924661,
58
+ 0.07233939709414,
59
+ 0.005819196258503,
60
+ -7.655935845761e-05,
61
+ -1.83794906705e-05,
62
+ 4.72578983298e-06,
63
+ -3.99778241186e-07,
64
+ 1.036731541123e-08,
65
+ -3.373845712183e-11
66
+ ],
67
+ [
68
+ 0.4373730373037,
69
+ -0.01574917019835,
70
+ -0.001456253436544,
71
+ 4.772491845078e-05,
72
+ -1.827059132463e-06,
73
+ -6.94116329271e-08,
74
+ 2.716740135949e-08,
75
+ -1.143121626264e-09,
76
+ 1.295139027087e-11
77
+ ],
78
+ [
79
+ -0.04972257208732,
80
+ 0.001866175274689,
81
+ 0.0002047337498511,
82
+ -1.004438052808e-05,
83
+ 7.59073486585e-07,
84
+ -6.771179147667e-08,
85
+ 1.218720257518e-09,
86
+ 6.78702447954e-11,
87
+ -2.432253541918e-12
88
+ ],
89
+ [
90
+ 0.002967287371427,
91
+ -0.0001147811325052,
92
+ -1.460813593905e-05,
93
+ 7.422385993164e-07,
94
+ -3.281946488134e-08,
95
+ 2.164459880579e-09,
96
+ 1.113868237282e-10,
97
+ -1.513922678655e-11,
98
+ 3.951084520871e-13
99
+ ],
100
+ [
101
+ -7.271204747116e-05,
102
+ 2.874049670122e-06,
103
+ 4.124421172202e-07,
104
+ -1.689203971933e-08,
105
+ -9.071172814458e-10,
106
+ 1.844295219334e-10,
107
+ -2.055023511556e-11,
108
+ 1.101902611511e-12,
109
+ -2.206082129473e-14
110
+ ]
111
+ ],
112
+ "sigma_v_E_coeffs": [
113
+ [
114
+ -25.38377692766,
115
+ -0.04826880987619,
116
+ 0.0679657596731,
117
+ -0.0240171002139,
118
+ 0.004130156138736,
119
+ -0.0003494803122018,
120
+ 1.34502510054e-05,
121
+ -1.323917127568e-07,
122
+ -2.551716207606e-09
123
+ ],
124
+ [
125
+ 2.472758419513,
126
+ 0.1668058989207,
127
+ -0.1265192781981,
128
+ 0.02938171777028,
129
+ -0.00221652505507,
130
+ -0.0001261523686946,
131
+ 2.701401918133e-05,
132
+ -1.370446267883e-06,
133
+ 2.313673787201e-08
134
+ ],
135
+ [
136
+ -8.864417999957,
137
+ -0.1882326730037,
138
+ 0.119402867431,
139
+ -0.02382836629119,
140
+ 0.001134820469638,
141
+ 0.0001782113978272,
142
+ -2.305554399898e-05,
143
+ 9.43029409318e-07,
144
+ -1.305188423829e-08
145
+ ],
146
+ [
147
+ 8.394970578944,
148
+ 0.08397993216045,
149
+ -0.0579697281374,
150
+ 0.01158600348753,
151
+ -0.0007504743150582,
152
+ -2.602911694939e-05,
153
+ 4.568209602293e-06,
154
+ -1.458110560501e-07,
155
+ 9.826599911934e-10
156
+ ],
157
+ [
158
+ -3.465864794112,
159
+ -0.0157268418022,
160
+ 0.01398192327776,
161
+ -0.002700181027443,
162
+ 0.0001902304157269,
163
+ -1.534387905925e-06,
164
+ -1.03206007926e-07,
165
+ -1.355858638619e-08,
166
+ 5.917279771473e-10
167
+ ],
168
+ [
169
+ 0.7479071085372,
170
+ 0.0005997666028811,
171
+ -0.001614053457119,
172
+ 0.0002620866439317,
173
+ -1.103039382799e-05,
174
+ -4.215447554819e-07,
175
+ -9.926133276192e-09,
176
+ 4.148813674084e-09,
177
+ -1.207867670158e-10
178
+ ],
179
+ [
180
+ -0.08863575102304,
181
+ 0.0001901540166344,
182
+ 6.941090299375e-05,
183
+ -3.042043168371e-06,
184
+ -1.677907209787e-06,
185
+ 2.153652742395e-07,
186
+ -6.354480058307e-09,
187
+ -1.223103792568e-10,
188
+ 5.54305794673e-12
189
+ ],
190
+ [
191
+ 0.005484926807853,
192
+ -2.510359436743e-05,
193
+ 1.123735445147e-06,
194
+ -9.198494797723e-07,
195
+ 2.058851315121e-07,
196
+ -1.866416375894e-08,
197
+ 7.564835556537e-10,
198
+ -1.622993472948e-11,
199
+ 2.428986170198e-13
200
+ ],
201
+ [
202
+ -0.0001388441945179,
203
+ 9.1419955967e-07,
204
+ -1.16891589033e-07,
205
+ 3.485370731777e-08,
206
+ -5.086412415216e-09,
207
+ 3.674153797642e-10,
208
+ -1.621809988343e-11,
209
+ 6.737654534264e-13,
210
+ -1.678705755876e-14
211
+ ]
212
+ ]
213
+ }
@@ -0,0 +1,207 @@
1
+ from .essos_import import (
2
+ EssosFieldLineBundle,
3
+ EssosImportedFciGeometry,
4
+ build_essos_vmec_scaled_qa_coordinates,
5
+ build_essos_imported_fci_geometry,
6
+ essos_runtime_available,
7
+ load_essos_field_line_bundle_npz,
8
+ load_essos_coil_field_axis,
9
+ load_essos_vmec_field_axis,
10
+ resolve_essos_landreman_qa_json,
11
+ resolve_essos_landreman_qa_wout,
12
+ save_essos_field_line_bundle_npz,
13
+ trace_essos_coil_field_lines,
14
+ trace_essos_coil_initial_conditions,
15
+ trace_essos_vmec_initial_conditions,
16
+ )
17
+ from .fci_maps import FciMaps, identity_fci_maps, load_fci_maps_netcdf
18
+ from .metric_tensor import MetricTensor3D, build_metric_report, metric_inverse_residual
19
+ from .stellarator import SyntheticStellaratorGeometry, build_synthetic_stellarator_geometry
20
+ from .island_divertor import (
21
+ IslandDivertorField,
22
+ build_island_divertor_geometry,
23
+ island_divertor_connection_length,
24
+ island_divertor_field_line_rhs,
25
+ )
26
+ from .open_slab import build_open_slab_geometry
27
+ from .rotating_ellipse import build_rotating_ellipse_geometry, rotating_ellipse_position
28
+ from .shifted_torus import build_shifted_torus_geometry
29
+ from .vmec_jax_import import (
30
+ evaluate_vmec_jax_surface_field,
31
+ load_vmec_jax_wout,
32
+ trace_vmec_jax_field_lines,
33
+ traced_rotational_transform,
34
+ vmec_jax_boundary_rz,
35
+ vmec_jax_half_mesh_s,
36
+ vmec_jax_runtime_available,
37
+ vmec_jax_surface_rz,
38
+ vmec_jax_wout_summary,
39
+ )
40
+ from .vmec_extender_import import (
41
+ VmecExtenderGrid,
42
+ build_vmec_extender_fci_maps,
43
+ interpolate_vmec_extender_B_cyl,
44
+ load_vmec_extender_grid_netcdf,
45
+ validate_vmec_extender_points_in_bounds,
46
+ vmec_extender_absB,
47
+ vmec_extender_fieldline_rhs_RZ_phi,
48
+ vmec_extender_points_in_bounds,
49
+ )
50
+
51
+ __all__ = [
52
+ "EssosFieldLineBundle",
53
+ "EssosImportedFciGeometry",
54
+ "build_essos_vmec_scaled_qa_coordinates",
55
+ "build_essos_imported_fci_geometry",
56
+ "essos_runtime_available",
57
+ "FciMaps",
58
+ "MetricTensor3D",
59
+ "SyntheticStellaratorGeometry",
60
+ "VmecExtenderGrid",
61
+ "build_metric_report",
62
+ "IslandDivertorField",
63
+ "build_island_divertor_geometry",
64
+ "island_divertor_connection_length",
65
+ "island_divertor_field_line_rhs",
66
+ "build_open_slab_geometry",
67
+ "build_rotating_ellipse_geometry",
68
+ "rotating_ellipse_position",
69
+ "build_shifted_torus_geometry",
70
+ "build_synthetic_stellarator_geometry",
71
+ "build_vmec_extender_fci_maps",
72
+ "identity_fci_maps",
73
+ "interpolate_vmec_extender_B_cyl",
74
+ "load_essos_field_line_bundle_npz",
75
+ "load_essos_coil_field_axis",
76
+ "load_essos_vmec_field_axis",
77
+ "load_fci_maps_netcdf",
78
+ "load_vmec_extender_grid_netcdf",
79
+ "metric_inverse_residual",
80
+ "resolve_essos_landreman_qa_json",
81
+ "resolve_essos_landreman_qa_wout",
82
+ "save_essos_field_line_bundle_npz",
83
+ "trace_essos_coil_field_lines",
84
+ "trace_essos_coil_initial_conditions",
85
+ "trace_essos_vmec_initial_conditions",
86
+ "validate_vmec_extender_points_in_bounds",
87
+ "evaluate_vmec_jax_surface_field",
88
+ "load_vmec_jax_wout",
89
+ "trace_vmec_jax_field_lines",
90
+ "traced_rotational_transform",
91
+ "vmec_jax_boundary_rz",
92
+ "vmec_jax_half_mesh_s",
93
+ "vmec_jax_runtime_available",
94
+ "vmec_jax_surface_rz",
95
+ "vmec_jax_wout_summary",
96
+ "vmec_extender_absB",
97
+ "vmec_extender_fieldline_rhs_RZ_phi",
98
+ "vmec_extender_points_in_bounds",
99
+ ]
100
+
101
+ # --- FCI stack incorporated from PR #3 (Aiken Xie, branch 3D_fci) ---
102
+ from .fci_geometry import (
103
+ BFieldGeometry,
104
+ CellCenteredGrid3D,
105
+ CellVolumeGeometry3D,
106
+ LocalFciDirectionMap,
107
+ LocalCellVolumeGeometry3D,
108
+ FaceBFieldGeometry,
109
+ FaceMetricGeometry,
110
+ FciGeometry3D,
111
+ FciMaps3D,
112
+ LocalFciGeometry3D,
113
+ ConservativeStencilBuilder,
114
+ ConservativeStencilBuilderContext,
115
+ LocalConservativeStencilBuilder,
116
+ LocalStencilBuilder,
117
+ LocalStencilBuilderContext,
118
+ StencilBuilderContext,
119
+ Grid1D,
120
+ HaloLayout3D,
121
+ LocalCellCenteredGrid3D,
122
+ LocalGrid1D,
123
+ LocalBFieldGeometry,
124
+ LocalFciLocalDependencyTable,
125
+ LocalFciMaps3D,
126
+ LocalFciRemoteDependencyTable,
127
+ FCI_DEP_INVALID,
128
+ FCI_DEP_FIELD_INTERIOR,
129
+ FCI_DEP_PHYSICAL_BOUNDARY,
130
+ FCI_DEP_CUT_WALL,
131
+ LocalDomain3D,
132
+ LocalFaceBFieldGeometry,
133
+ LocalRegularFaceGeometry3D,
134
+ LocalFaceMetricGeometry,
135
+ MetricGeometry,
136
+ LocalMetricGeometry,
137
+ NeighborMap3D,
138
+ ShardSpec3D,
139
+ SIDE_PHYSICAL,
140
+ SIDE_SIMPLE_PERIODIC,
141
+ SIDE_AXIS_REGULAR,
142
+ SIDE_TOPOLOGY_MAPPED,
143
+ SIDE_UNUSED,
144
+ RegularFaceGeometry3D,
145
+ LocalSpacing3D,
146
+ Spacing3D,
147
+ build_fci_maps_from_b_contravariant,
148
+ build_curvature_coefficients,
149
+ build_conservative_stencil_from_field,
150
+ build_local_conservative_stencil_from_field,
151
+ build_local_direct_stencil_one_sided_physical_from_halo,
152
+ build_local_stencil_from_field,
153
+ logical_grid_from_axis_vectors,
154
+ )
155
+ __all__ += [
156
+ "BFieldGeometry",
157
+ "CellCenteredGrid3D",
158
+ "CellVolumeGeometry3D",
159
+ "ConservativeStencilBuilder",
160
+ "ConservativeStencilBuilderContext",
161
+ "FCI_DEP_CUT_WALL",
162
+ "FCI_DEP_FIELD_INTERIOR",
163
+ "FCI_DEP_INVALID",
164
+ "FCI_DEP_PHYSICAL_BOUNDARY",
165
+ "FaceBFieldGeometry",
166
+ "FaceMetricGeometry",
167
+ "FciGeometry3D",
168
+ "FciMaps3D",
169
+ "Grid1D",
170
+ "HaloLayout3D",
171
+ "LocalBFieldGeometry",
172
+ "LocalCellCenteredGrid3D",
173
+ "LocalCellVolumeGeometry3D",
174
+ "LocalConservativeStencilBuilder",
175
+ "LocalDomain3D",
176
+ "LocalFaceBFieldGeometry",
177
+ "LocalFaceMetricGeometry",
178
+ "LocalFciDirectionMap",
179
+ "LocalFciGeometry3D",
180
+ "LocalFciLocalDependencyTable",
181
+ "LocalFciMaps3D",
182
+ "LocalFciRemoteDependencyTable",
183
+ "LocalGrid1D",
184
+ "LocalMetricGeometry",
185
+ "LocalRegularFaceGeometry3D",
186
+ "LocalSpacing3D",
187
+ "LocalStencilBuilder",
188
+ "LocalStencilBuilderContext",
189
+ "MetricGeometry",
190
+ "NeighborMap3D",
191
+ "RegularFaceGeometry3D",
192
+ "SIDE_AXIS_REGULAR",
193
+ "SIDE_PHYSICAL",
194
+ "SIDE_SIMPLE_PERIODIC",
195
+ "SIDE_TOPOLOGY_MAPPED",
196
+ "SIDE_UNUSED",
197
+ "ShardSpec3D",
198
+ "Spacing3D",
199
+ "StencilBuilderContext",
200
+ "build_conservative_stencil_from_field",
201
+ "build_curvature_coefficients",
202
+ "build_fci_maps_from_b_contravariant",
203
+ "build_local_conservative_stencil_from_field",
204
+ "build_local_direct_stencil_one_sided_physical_from_halo",
205
+ "build_local_stencil_from_field",
206
+ "logical_grid_from_axis_vectors",
207
+ ]
@@ -0,0 +1,56 @@
1
+ """Metric tensors from an analytic embedding, by automatic differentiation.
2
+
3
+ Given a map from logical coordinates ``u = (x, theta, zeta)`` to Cartesian
4
+ space, the covariant metric is ``g_ij = d_i X . d_j X`` — computed here exactly
5
+ with ``jax.jacfwd`` instead of by hand. Every analytic geometry in the package
6
+ (rotating ellipse, island divertor) builds its :class:`MetricGeometry` through
7
+ this one function, so a new geometry only has to supply its embedding.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from collections.abc import Callable
13
+
14
+ import jax
15
+ import jax.numpy as jnp
16
+
17
+ from .fci_geometry import MetricGeometry
18
+
19
+ __all__ = ["metric_from_position_fn"]
20
+
21
+
22
+ def metric_from_position_fn(
23
+ position_fn: Callable[[jax.Array], jax.Array],
24
+ logical_grid: jax.Array,
25
+ ) -> MetricGeometry:
26
+ """Build the metric on ``logical_grid`` from ``position_fn(u) -> (X, Y, Z)``.
27
+
28
+ The covariant metric is the Gram matrix of the embedding Jacobian, the
29
+ contravariant metric its inverse, and the Jacobian ``sqrt(det g_cov)``.
30
+ """
31
+
32
+ jacobian_of_position = jax.jacfwd(position_fn)
33
+ points = logical_grid.reshape(-1, 3)
34
+ cartesian_jacobian = jax.vmap(jacobian_of_position)(points)
35
+ g_cov = jnp.einsum("pki,pkj->pij", cartesian_jacobian, cartesian_jacobian)
36
+ g_contra = jnp.linalg.inv(g_cov)
37
+ det_g_cov = jnp.linalg.det(g_cov)
38
+ location_shape = logical_grid.shape[:-1]
39
+ g_cov = g_cov.reshape(location_shape + (3, 3))
40
+ g_contra = g_contra.reshape(location_shape + (3, 3))
41
+ jacobian = jnp.sqrt(jnp.abs(det_g_cov)).reshape(location_shape)
42
+ return MetricGeometry(
43
+ J=jacobian,
44
+ g11=g_contra[..., 0, 0],
45
+ g22=g_contra[..., 1, 1],
46
+ g33=g_contra[..., 2, 2],
47
+ g12=g_contra[..., 0, 1],
48
+ g13=g_contra[..., 0, 2],
49
+ g23=g_contra[..., 1, 2],
50
+ g_11=g_cov[..., 0, 0],
51
+ g_22=g_cov[..., 1, 1],
52
+ g_33=g_cov[..., 2, 2],
53
+ g_12=g_cov[..., 0, 1],
54
+ g_13=g_cov[..., 0, 2],
55
+ g_23=g_cov[..., 1, 2],
56
+ )