nrpy 2.0.2__tar.gz → 2.0.3__tar.gz

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 (85) hide show
  1. {nrpy-2.0.2 → nrpy-2.0.3}/PKG-INFO +1 -1
  2. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/c_codegen.py +6 -39
  3. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/equations/general_relativity/BSSN_RHSs.py +6 -2
  4. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/equations/general_relativity/BSSN_constraints.py +5 -5
  5. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/equations/general_relativity/BSSN_quantities.py +26 -25
  6. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/equations/general_relativity/g4munu_conversions.py +2 -1
  7. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/equations/general_relativity/psi4_tetrads.py +7 -6
  8. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/equations/special_functions/spin_weighted_spherical_harmonics.py +2 -1
  9. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/examples/two_blackholes_collide.py +5 -5
  10. nrpy-2.0.3/nrpy/helpers/cached_functions.py +106 -0
  11. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/helpers/cse_preprocess_postprocess.py +0 -1
  12. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/helpers/generic.py +6 -2
  13. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/BHaH/general_relativity/BSSN_C_codegen_library.py +0 -1
  14. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/reference_metric.py +2 -1
  15. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy.egg-info/PKG-INFO +1 -1
  16. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy.egg-info/SOURCES.txt +1 -0
  17. {nrpy-2.0.2 → nrpy-2.0.3}/LICENSE +0 -0
  18. {nrpy-2.0.2 → nrpy-2.0.3}/README.md +0 -0
  19. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/__init__.py +0 -0
  20. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/c_function.py +0 -0
  21. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/equations/__init__.py +0 -0
  22. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/equations/general_relativity/ADM_to_BSSN.py +0 -0
  23. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/equations/general_relativity/BSSN_gauge_RHSs.py +0 -0
  24. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/equations/general_relativity/BSSN_to_ADM.py +0 -0
  25. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/equations/general_relativity/InitialData_Cartesian.py +0 -0
  26. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/equations/general_relativity/InitialData_Spherical.py +0 -0
  27. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/equations/general_relativity/T4munu.py +0 -0
  28. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/equations/general_relativity/__init__.py +0 -0
  29. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/equations/general_relativity/nrpylatex/__init__.py +0 -0
  30. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/equations/general_relativity/nrpylatex/test_parse_BSSN.py +0 -0
  31. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/equations/general_relativity/psi4.py +0 -0
  32. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/equations/special_functions/__init__.py +0 -0
  33. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/equations/wave_equation/CommonParams.py +0 -0
  34. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/equations/wave_equation/InitialData.py +0 -0
  35. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/equations/wave_equation/WaveEquationCurvilinear_RHSs.py +0 -0
  36. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/equations/wave_equation/WaveEquation_RHSs.py +0 -0
  37. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/equations/wave_equation/__init__.py +0 -0
  38. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/examples/__init__.py +0 -0
  39. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/examples/wave_equation_cartesian.py +0 -0
  40. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/examples/wave_equation_curvilinear.py +0 -0
  41. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/finite_difference.py +0 -0
  42. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/grid.py +0 -0
  43. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/helpers/__init__.py +0 -0
  44. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/helpers/expr_tree.py +0 -0
  45. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/helpers/functional.py +0 -0
  46. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/helpers/jacobians.py +0 -0
  47. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/helpers/loop.py +0 -0
  48. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/helpers/simd.py +0 -0
  49. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/helpers/simd_intrinsics.h +0 -0
  50. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/indexedexp.py +0 -0
  51. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/BHaH/BHaH_defines_h.py +0 -0
  52. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/BHaH/CodeParameters.py +0 -0
  53. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/BHaH/CurviBoundaryConditions/CurviBoundaryConditions.py +0 -0
  54. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/BHaH/CurviBoundaryConditions/__init__.py +0 -0
  55. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/BHaH/Makefile_helpers.py +0 -0
  56. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/BHaH/MoLtimestepping/MoL.py +0 -0
  57. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/BHaH/MoLtimestepping/RK_Butcher_Table_Dictionary.py +0 -0
  58. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/BHaH/MoLtimestepping/__init__.py +0 -0
  59. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/BHaH/__init__.py +0 -0
  60. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/BHaH/cmdline_input_and_parfiles.py +0 -0
  61. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/BHaH/diagnostics/__init__.py +0 -0
  62. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/BHaH/diagnostics/progress_indicator.py +0 -0
  63. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/BHaH/general_relativity/ADM_Initial_Data_Reader__BSSN_Converter.py +0 -0
  64. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/BHaH/general_relativity/__init__.py +0 -0
  65. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/BHaH/griddata_commondata.py +0 -0
  66. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/BHaH/main_c.py +0 -0
  67. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/BHaH/numerical_grids_and_timestep.py +0 -0
  68. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/BHaH/rfm_precompute.py +0 -0
  69. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/BHaH/simple_loop.py +0 -0
  70. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/BHaH/special_functions/__init__.py +0 -0
  71. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/BHaH/special_functions/spin_weight_minus2_spherical_harmonics.py +0 -0
  72. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/BHaH/xx_tofrom_Cart.py +0 -0
  73. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/CarpetX/__init__.py +0 -0
  74. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/CarpetX/colored.py +0 -0
  75. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/CarpetX/here.py +0 -0
  76. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/CarpetX/sugar.py +0 -0
  77. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/infrastructures/__init__.py +0 -0
  78. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/params.py +0 -0
  79. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/validate_expressions/__init__.py +0 -0
  80. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy/validate_expressions/validate_expressions.py +0 -0
  81. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy.egg-info/dependency_links.txt +0 -0
  82. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy.egg-info/requires.txt +0 -0
  83. {nrpy-2.0.2 → nrpy-2.0.3}/nrpy.egg-info/top_level.txt +0 -0
  84. {nrpy-2.0.2 → nrpy-2.0.3}/setup.cfg +0 -0
  85. {nrpy-2.0.2 → nrpy-2.0.3}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: nrpy
3
- Version: 2.0.2
3
+ Version: 2.0.3
4
4
  Summary: Python/SymPy-based code generation for numerical relativity... and beyond!
5
5
  Home-page: https://github.com/nrpy/nrpy
6
6
  Author: Zachariah Etienne
@@ -7,13 +7,10 @@ Authors: Zachariah B. Etienne; zachetie **at** gmail **dot* com
7
7
  """
8
8
 
9
9
  import logging
10
- from pathlib import Path
11
- import hashlib
12
- import pickle
10
+
13
11
  import re # Regular expressions can be toxic due to edge cases -- we use them sparingly
14
12
  import sys
15
- from typing import List, Union, Dict, Any, Optional, Sequence, Tuple, cast
16
- from appdirs import user_cache_dir # type: ignore
13
+ from typing import List, Union, Dict, Any, Optional, Sequence, Tuple
17
14
  import sympy as sp
18
15
  import nrpy.finite_difference as fin
19
16
  import nrpy.params as par
@@ -55,7 +52,6 @@ class CCodeGen:
55
52
  automatically_read_gf_data_from_memory: bool = False,
56
53
  enforce_c_parameters_must_be_defined: bool = False,
57
54
  enable_fd_functions: bool = False,
58
- cache_enable: bool = True,
59
55
  mem_alloc_style: str = "210",
60
56
  upwind_control_vec: Union[List[sp.Symbol], sp.Symbol] = sp.Symbol("unset"),
61
57
  symbol_to_Rational_dict: Optional[Dict[sp.Basic, sp.Rational]] = None,
@@ -122,7 +118,6 @@ class CCodeGen:
122
118
  )
123
119
  self.enforce_c_parameters_must_be_defined = enforce_c_parameters_must_be_defined
124
120
  self.enable_fd_functions = enable_fd_functions
125
- self.cache_enable = cache_enable
126
121
  self.mem_alloc_style = mem_alloc_style
127
122
  self.upwind_control_vec = upwind_control_vec
128
123
  self.symbol_to_Rational_dict = symbol_to_Rational_dict
@@ -224,10 +219,10 @@ def c_codegen(
224
219
  :return: A string containing the generated C code.
225
220
 
226
221
  >>> x, y, z = sp.symbols("x y z", real=True)
227
- >>> print(c_codegen(x**2 + sp.sqrt(y) - sp.sin(x*z), "double blah", include_braces=False, verbose=False, cache_enable=False))
222
+ >>> print(c_codegen(x**2 + sp.sqrt(y) - sp.sin(x*z), "double blah", include_braces=False, verbose=False))
228
223
  double blah = ((x)*(x)) + sqrt(y) - sin(x*z);
229
224
  <BLANKLINE>
230
- >>> print(c_codegen(x**5 + x**3 + x - 1/x, "REAL_SIMD_ARRAY blah", include_braces=False, verbose=False, enable_simd=True, cache_enable=False))
225
+ >>> print(c_codegen(x**5 + x**3 + x - 1/x, "REAL_SIMD_ARRAY blah", include_braces=False, verbose=False, enable_simd=True))
231
226
  const double dbl_Integer_1 = 1.0;
232
227
  const REAL_SIMD_ARRAY _Integer_1 = ConstSIMD(dbl_Integer_1);
233
228
  <BLANKLINE>
@@ -236,7 +231,7 @@ def c_codegen(
236
231
  <BLANKLINE>
237
232
  REAL_SIMD_ARRAY blah = FusedMulAddSIMD(MulSIMD(x, x), x, FusedMulAddSIMD(MulSIMD(MulSIMD(MulSIMD(x, x), x), x), x, SubSIMD(x, DivSIMD(_Integer_1, x))));
238
233
  <BLANKLINE>
239
- >>> print(c_codegen(x**5 + x**3 + sp.sin(x**3), "REAL_SIMD_ARRAY blah", enable_simd=True, cache_enable=True))
234
+ >>> print(c_codegen(x**5 + x**3 + sp.sin(x**3), "REAL_SIMD_ARRAY blah", enable_simd=True))
240
235
  /*
241
236
  * Original SymPy expression:
242
237
  * "REAL_SIMD_ARRAY blah = x**5 + x**3 + sin(x**3)"
@@ -246,7 +241,7 @@ def c_codegen(
246
241
  REAL_SIMD_ARRAY blah = AddSIMD(tmp0, FusedMulAddSIMD(MulSIMD(MulSIMD(MulSIMD(x, x), x), x), x, SinSIMD(tmp0)));
247
242
  }
248
243
  <BLANKLINE>
249
- >>> print(c_codegen(x**5 + x**3 + sp.sin(x**3), "REAL_SIMD_ARRAY blah", enable_simd=True, cache_enable=True))
244
+ >>> print(c_codegen(x**5 + x**3 + sp.sin(x**3), "REAL_SIMD_ARRAY blah", enable_simd=True))
250
245
  /*
251
246
  * Original SymPy expression:
252
247
  * "REAL_SIMD_ARRAY blah = x**5 + x**3 + sin(x**3)"
@@ -258,26 +253,6 @@ def c_codegen(
258
253
  <BLANKLINE>
259
254
  """
260
255
  CCGParams = CCodeGen(**kwargs)
261
- cache_dir = Path(user_cache_dir("nrpy"))
262
- cache_file = Path("does_not_exist")
263
- if CCGParams.cache_enable:
264
- try:
265
- pickle_expr = pickle.dumps(sympyexpr)
266
- pickle_prms = pickle.dumps(CCGParams.__dict__)
267
- pickle_vars = pickle.dumps(output_varname_str)
268
- pickle_kwgs = pickle.dumps(kwargs)
269
- cache_dir.mkdir(parents=True, exist_ok=True)
270
- cache_file = cache_dir / (
271
- hashlib.sha256(
272
- pickle_expr + pickle_prms + pickle_vars + pickle_kwgs
273
- ).hexdigest()
274
- + ".nrpycache"
275
- )
276
- if cache_file.exists():
277
- with open(cache_file, "rb") as file:
278
- return cast(str, pickle.load(file))
279
- except pickle.PicklingError:
280
- pass
281
256
 
282
257
  # Step 1: Initialize
283
258
  # commentblock: comment block containing the input SymPy string,
@@ -587,14 +562,6 @@ def c_codegen(
587
562
  if CCGParams.include_braces:
588
563
  final_Ccode_output_str += "}\n"
589
564
 
590
- if CCGParams.cache_enable:
591
- try:
592
- if "does_not_exist" not in str(cache_file):
593
- with open(cache_file, "wb") as file:
594
- pickle.dump(final_Ccode_output_str, file)
595
- except pickle.PicklingError:
596
- pass
597
-
598
565
  # Step 7: Return result string
599
566
  return final_Ccode_output_str
600
567
 
@@ -9,6 +9,7 @@ Author: Zachariah B. Etienne
9
9
  # Step 1.a: import all needed modules from NRPy+:
10
10
  from typing import Dict, List
11
11
  import sympy as sp # SymPy: The Python computer algebra package upon which NRPy+ depends
12
+
12
13
  import nrpy.params as par # NRPy+: Parameter interface
13
14
  import nrpy.grid as gri
14
15
  import nrpy.indexedexp as ixp # NRPy+: Symbolic indexed expression (e.g., tensors, vectors, etc.) support
@@ -33,6 +34,8 @@ class BSSNRHSs:
33
34
  def __init__(
34
35
  self, CoordSystem: str = "Cartesian", enable_rfm_precompute: bool = False
35
36
  ):
37
+ enable_T4munu = par.parval_from_str("enable_T4munu")
38
+
36
39
  # Step 1.c: Given the chosen coordinate system, set up
37
40
  # corresponding reference metric and needed
38
41
  # reference metric quantities
@@ -310,7 +313,7 @@ class BSSNRHSs:
310
313
  self.Lambdabar_rhsU[i] += -sp.Rational(4, 3) * alpha * gammabarUU[i][j] * trK_dD[j]
311
314
 
312
315
  # Step 7: Add T4munu if enable_T4munu
313
- if par.parval_from_str("enable_T4munu"):
316
+ if enable_T4munu:
314
317
  if "T4UU00" not in gri.glb_gridfcs_dict:
315
318
  _ = gri.register_gridfunctions_for_single_rank2(
316
319
  "T4UU",
@@ -372,9 +375,10 @@ class BSSNRHSs_dict(Dict[str, BSSNRHSs]):
372
375
 
373
376
  def __getitem__(self, CoordSystem_in: str) -> BSSNRHSs:
374
377
  if CoordSystem_in not in self:
378
+ enable_T4munu = par.parval_from_str("enable_T4munu")
379
+
375
380
  # In case [CoordSystem]_rfm_precompute is passed:
376
381
  CoordSystem = CoordSystem_in.replace("_rfm_precompute", "")
377
- enable_T4munu = par.parval_from_str("enable_T4munu")
378
382
  print(
379
383
  f"Setting up BSSN_RHSs for CoordSystem = {CoordSystem}, enable_T4munu={enable_T4munu}."
380
384
  )
@@ -9,6 +9,7 @@ Author: Zachariah B. Etienne
9
9
  # Step 1: Initialize needed Python/NRPy+ modules
10
10
  from typing import Dict
11
11
  import sympy as sp # SymPy: The Python computer algebra package upon which NRPy+ depends
12
+
12
13
  import nrpy.params as par # NRPy+: Parameter interface
13
14
  import nrpy.indexedexp as ixp # NRPy+: Symbolic indexed expression (e.g., tensors, vectors, etc.) support
14
15
  import nrpy.grid as gri # NRPy+: Functions having to do with numerical grids
@@ -29,6 +30,8 @@ class BSSNconstraints:
29
30
  CoordSystem: str = "Cartesian",
30
31
  enable_rfm_precompute: bool = False,
31
32
  ) -> None:
33
+ register_MU_gridfunctions = par.parval_from_str("register_MU_gridfunctions")
34
+
32
35
  # Step 1.b: Given the chosen coordinate system, set up
33
36
  # corresponding reference metric and needed
34
37
  # reference metric quantities
@@ -52,10 +55,7 @@ class BSSNconstraints:
52
55
  _ = gri.register_gridfunctions(
53
56
  "MSQUARED", group="AUX", gf_array_name="diagnostic_output_gfs"
54
57
  )
55
- if (
56
- par.parval_from_str("register_MU_gridfunctions")
57
- and "MU" not in gri.glb_gridfcs_dict
58
- ):
58
+ if register_MU_gridfunctions and "MU" not in gri.glb_gridfcs_dict:
59
59
  _ = gri.register_gridfunctions_for_single_rank1(
60
60
  "MU", group="AUX", gf_array_name="diagnostic_output_gfs"
61
61
  )
@@ -181,7 +181,7 @@ class BSSNconstraints_dict(Dict[str, BSSNconstraints]):
181
181
  CoordSystem = CoordSystem_in.replace("_rfm_precompute", "")
182
182
  enable_T4munu = par.parval_from_str("enable_T4munu")
183
183
  print(
184
- f"Setting up BSSN_quantities for CoordSystem = {CoordSystem}, enable_T4munu={enable_T4munu}."
184
+ f"Setting up BSSN_constraints for CoordSystem = {CoordSystem}, enable_T4munu={enable_T4munu}."
185
185
  )
186
186
  self.__setitem__(
187
187
  CoordSystem, BSSNconstraints(CoordSystem, enable_rfm_precompute=False)
@@ -42,20 +42,18 @@ class BSSNQuantities:
42
42
 
43
43
  # Check to see if this function has already been called.
44
44
  # If so, do not register the gridfunctions again!
45
- BSSN_quantities_gfs_are_registered = False
46
- for gf in gri.glb_gridfcs_dict.values():
47
- if "hDD00" in gf.name:
48
- self.hDD = ixp.declarerank2("hDD", symmetry="sym01")
49
- self.aDD = ixp.declarerank2("aDD", symmetry="sym01")
50
- self.lambdaU = ixp.declarerank1("lambdaU")
51
- self.vetU = ixp.declarerank1("vetU")
52
- self.betU = ixp.declarerank1("betU")
53
- self.trK, self.cf, self.alpha = sp.symbols(
54
- "trK cf alpha"
55
- ) # , real=True) # no tensor gridfunction is real=True. Do this for consistency.
56
- BSSN_quantities_gfs_are_registered = True
57
-
58
- if not BSSN_quantities_gfs_are_registered:
45
+ LeaveRicciSymbolic = par.parval_from_str("LeaveRicciSymbolic")
46
+
47
+ if any("hDD00" in gf.name for gf in gri.glb_gridfcs_dict.values()):
48
+ self.hDD = ixp.declarerank2("hDD", symmetry="sym01")
49
+ self.aDD = ixp.declarerank2("aDD", symmetry="sym01")
50
+ self.lambdaU = ixp.declarerank1("lambdaU")
51
+ self.vetU = ixp.declarerank1("vetU")
52
+ self.betU = ixp.declarerank1("betU")
53
+ self.trK, self.cf, self.alpha = sp.symbols(
54
+ "trK cf alpha"
55
+ ) # , real=True) # no tensor gridfunction is real=True. Do this for consistency.
56
+ else:
59
57
  # Step 2.a: Register indexed quantities, using ixp.register_... functions
60
58
  self.hDD = gri.register_gridfunctions_for_single_rank2(
61
59
  "hDD", symmetry="sym01", f_infinity=0.0, wavespeed=1.0
@@ -80,12 +78,23 @@ class BSSNQuantities:
80
78
  wavespeed=[1.0, 1.0, sp.sqrt(2.0)],
81
79
  )
82
80
 
81
+ if LeaveRicciSymbolic and not any(
82
+ "RbarDD00" in gf.name for gf in gri.glb_gridfcs_dict.values()
83
+ ):
84
+ self.RbarDD = gri.register_gridfunctions_for_single_rank2(
85
+ "RbarDD",
86
+ symmetry="sym01",
87
+ group="AUXEVOL",
88
+ gf_array_name="auxevol_gfs",
89
+ )
90
+ else:
91
+ self.RbarDD = ixp.declarerank2("RbarDD", symmetry="sym01")
92
+
83
93
  # fmt: off
84
94
  # Step 3: Define all basic conformal BSSN tensors
85
95
  # gammabarDD,AbarDD,LambdabarU,betaU,BU
86
96
  # in terms of BSSN gridfunctions.
87
97
  # Step 3.a: Defines gammabarDD, AbarDD, LambdabarU, betaU, BU
88
-
89
98
  rfm = refmetric.reference_metric[
90
99
  CoordSystem + "_rfm_precompute" if enable_rfm_precompute else CoordSystem
91
100
  ]
@@ -379,16 +388,8 @@ class BSSNQuantities:
379
388
  self.DGammaU[i] += self.gammabarUU[j][k] * self.DGammaUDD[i][j][k]
380
389
 
381
390
  # If we wish to leave Ricci symbolic, there's no point continuing to define RbarDD symbolically:
382
- if par.parval_from_str("LeaveRicciSymbolic"):
383
- Rbar_is_gf = False
384
- for gf in gri.glb_gridfcs_dict.values():
385
- if "RbarDD00" in gf.name:
386
- self.RbarDD = ixp.declarerank2("RbarDD", symmetry="sym01")
387
- Rbar_is_gf = True
388
- if not Rbar_is_gf:
389
- self.RbarDD = gri.register_gridfunctions_for_single_rank2(
390
- "RbarDD", symmetry="sym01", group="AUXEVOL", gf_array_name="auxevol_gfs"
391
- )
391
+ if LeaveRicciSymbolic:
392
+ pass
392
393
  else:
393
394
  # Step 7.c.iii: Define \Delta_{ijk} = \bar{\gamma}_{im} \Delta^m_{jk}
394
395
  DGammaDDD = ixp.zerorank3()
@@ -15,6 +15,7 @@ import nrpy.indexedexp as ixp # NRPy+: Symbolic indexed expression (e.g., tenso
15
15
  from nrpy.equations.general_relativity.BSSN_to_ADM import BSSN_to_ADM
16
16
  from nrpy.equations.general_relativity.ADM_to_BSSN import ADM_to_BSSN
17
17
  from nrpy.equations.general_relativity.BSSN_quantities import BSSN_quantities
18
+ from nrpy.helpers.cached_functions import cached_simplify
18
19
 
19
20
 
20
21
  # g_{mu nu} in terms of BSSN (if inputvars=="BSSN") or ADM (if inputvars=="ADM") variables.
@@ -180,7 +181,7 @@ def g4DD_to_ADM(
180
181
 
181
182
  # Step 4.b: alpha = sqrt(beta^2 - g_{00}):
182
183
  alpha = (
183
- sp.sqrt(sp.simplify(beta_squared) - g4DD[0][0])
184
+ sp.sqrt(cached_simplify(beta_squared) - g4DD[0][0])
184
185
  if not g4DD_is_input_into_this_function
185
186
  else sp.sqrt(beta_squared - g4DD[0][0])
186
187
  )
@@ -16,6 +16,7 @@ import nrpy.indexedexp as ixp # NRPy+: Symbolic indexed expression (e.g., tenso
16
16
  import nrpy.reference_metric as refmetric # NRPy+: Reference metric support
17
17
  from nrpy.equations.general_relativity.BSSN_quantities import BSSN_quantities
18
18
  from nrpy.equations.general_relativity.BSSN_to_ADM import BSSN_to_ADM
19
+ from nrpy.helpers.cached_functions import cached_simplify
19
20
 
20
21
  # Step 1.b: Declare free parameter
21
22
  # use_metric_to_construct_unit_normal=False: consistent with WeylScal4 ETK thorn.
@@ -72,12 +73,12 @@ class Psi4Tetrads:
72
73
  # BSSN.ADM_in_terms_of_BSSN;
73
74
  # simplify detgamma & gammaUU expressions,
74
75
  # which expedites Psi4 codegen.
75
- detgamma = sp.simplify(BtoA.detgamma)
76
+ detgamma = cached_simplify(BtoA.detgamma)
76
77
  gammaUU = ixp.zerorank2()
77
78
  for i in range(3):
78
79
  for j in range(i, 3):
79
80
  # The simplify() here is SLOW, so we try to use it sparingly.
80
- gammaUU[i][j] = gammaUU[j][i] = sp.simplify(BtoA.gammaUU[i][j])
81
+ gammaUU[i][j] = gammaUU[j][i] = cached_simplify(BtoA.gammaUU[i][j])
81
82
 
82
83
  # Step 2.c: Define v1U and v2U
83
84
  v1UCart = [-y, x, sp.sympify(0)]
@@ -90,7 +91,7 @@ class Psi4Tetrads:
90
91
  # Step 2.e.i: Simplify expressions for d xx^j / d x_Cart^i:
91
92
  for i in range(3):
92
93
  for j in range(3):
93
- Jac_dUrfm_dDCartUD[i][j] = sp.simplify(Jac_dUrfm_dDCartUD[i][j])
94
+ Jac_dUrfm_dDCartUD[i][j] = cached_simplify(Jac_dUrfm_dDCartUD[i][j])
94
95
 
95
96
  # Step 2.f: Transform v1U and v2U from the Cartesian to the xx^i basis
96
97
  v1U = ixp.zerorank1()
@@ -119,9 +120,9 @@ class Psi4Tetrads:
119
120
  # Drat. Simplification with certain versions of SymPy & coord systems results in a hang. Let's just
120
121
  # evaluate the expressions so the most trivial optimizations can be performed.
121
122
  for a in range(3):
122
- v1U[a] = v1U[a].doit() # sp.simplify(v1U[a])
123
- v2U[a] = v2U[a].doit() # sp.simplify(v2U[a])
124
- v3U[a] = v3U[a].doit() # sp.simplify(v3U[a])
123
+ v1U[a] = v1U[a].doit() # cached_simplify(v1U[a])
124
+ v2U[a] = v2U[a].doit() # cached_simplify(v2U[a])
125
+ v3U[a] = v3U[a].doit() # cached_simplify(v3U[a])
125
126
 
126
127
  # Step 2.h: Define omega_{ij}
127
128
  omegaDD = ixp.zerorank2()
@@ -11,6 +11,7 @@ Authors: Brandon Clark
11
11
  """
12
12
  from typing import cast, Dict
13
13
  import sympy as sp # SymPy: The Python computer algebra package upon which NRPy+ depends
14
+ from nrpy.helpers.cached_functions import cached_simplify
14
15
 
15
16
 
16
17
  def Y(
@@ -67,7 +68,7 @@ def Y(
67
68
  * (2 * l + 1)
68
69
  / (4 * sp.pi * sp.factorial(l + s) * sp.factorial(l - s))
69
70
  )
70
- * sp.simplify(negative_one**m * sp.sin(th / 2) ** (2 * l) * Sum),
71
+ * cached_simplify(negative_one**m * sp.sin(th / 2) ** (2 * l) * Sum),
71
72
  )
72
73
 
73
74
 
@@ -53,8 +53,8 @@ default_BH1_z_posn = +0.5
53
53
  default_BH2_z_posn = -0.5
54
54
  enable_rfm_precompute = True
55
55
  MoL_method = "RK4"
56
- fd_order = 4
57
- radiation_BC_fd_order = 2
56
+ fd_order = 8
57
+ radiation_BC_fd_order = 8
58
58
  enable_simd = True
59
59
  separate_Ricci_and_BSSN_RHS = True
60
60
  boundary_conditions_desc = "outgoing radiation"
@@ -307,9 +307,9 @@ print("Finished constructing MoL C functions.")
307
307
  xxCart.register_CFunction__Cart_to_xx_and_nearest_i0i1i2(CoordSystem)
308
308
  xxCart.register_CFunction_xx_to_Cart(CoordSystem)
309
309
  progress.register_CFunction_progress_indicator()
310
- # print("Started constructing SWm2SH functions.")
311
- # swm2sh.register_CFunction_spin_weight_minus2_sph_harmonics(maximum_l=8)
312
- # print("Finished constructing SWm2SH functions.")
310
+ print("Started constructing SWm2SH functions.")
311
+ swm2sh.register_CFunction_spin_weight_minus2_sph_harmonics(maximum_l=8)
312
+ print("Finished constructing SWm2SH functions.")
313
313
 
314
314
  #########################################################
315
315
  # STEP 3: Generate header files, register C functions and
@@ -0,0 +1,106 @@
1
+ """
2
+ Cache-enable versions of functions that are
3
+ * normally slow, and
4
+ * called with the same inputs many times during a development cycle.
5
+
6
+ Author: Zachariah B. Etienne
7
+ zachetie **at** gmail **dot* com
8
+ """
9
+ import hashlib
10
+ import pickle
11
+ from pathlib import Path
12
+ from typing import cast, Any
13
+ from appdirs import user_cache_dir # type: ignore
14
+ import sympy as sp
15
+ import nrpy.params as par
16
+
17
+
18
+ def get_hash(unique_id: str) -> str:
19
+ """
20
+ Generate a hash string for a given unique ID.
21
+
22
+ :param unique_id: A unique identifier to be hashed.
23
+ :return: The hash string.
24
+ """
25
+ return hashlib.sha256(unique_id.encode("utf-8")).hexdigest()
26
+
27
+
28
+ def cache_file(unique_id: str) -> Path:
29
+ """
30
+ Generate a cache file path using a unique ID.
31
+
32
+ :param unique_id: A unique identifier to be used for generating the file path.
33
+ :return: The cache file path.
34
+ """
35
+
36
+ if not Path(user_cache_dir("nrpy")).exists():
37
+ Path(user_cache_dir("nrpy")).mkdir(parents=True, exist_ok=True)
38
+ return Path(user_cache_dir("nrpy")) / f"{get_hash(unique_id)}.nrpycache"
39
+
40
+
41
+ def NRPy_params_checksum() -> str:
42
+ return get_hash(
43
+ str(pickle.dumps({k: v for k, v in sorted(par.glb_params_dict.items())}))
44
+ )
45
+
46
+
47
+ def is_cached(unique_id: str) -> bool:
48
+ """
49
+ Check if the file with the given unique ID exists in cache.
50
+
51
+ :param unique_id: A unique identifier to check for.
52
+ :return: True if the file exists, False otherwise.
53
+ """
54
+ return cache_file(unique_id).exists()
55
+
56
+
57
+ def read_cached(unique_id: str) -> Any:
58
+ """
59
+ Read the cached data associated with a unique ID.
60
+
61
+ :param unique_id: A unique identifier to read data for.
62
+ :return: The data read from the cache file.
63
+ """
64
+ # print(f"Reading " + str(unique_id[:80]).replace("\n", ""))
65
+ with open(cache_file(unique_id), "rb") as file:
66
+ # print(f"Reading cached file {file.name}.")
67
+ return pickle.load(file)
68
+
69
+
70
+ def write_cached(unique_id: str, data: Any) -> None:
71
+ """
72
+ Write data to the cache file associated with a unique ID.
73
+
74
+ :param unique_id: A unique identifier to write data for.
75
+ :param data: The data to be written to the cache.
76
+ """
77
+ # print(f"Writing " + str(unique_id[:80]).replace("\n", ""))
78
+ with open(cache_file(unique_id), "wb") as file:
79
+ # print(f"Writing cached file {file.name}.")
80
+ pickle.dump(data, file)
81
+
82
+
83
+ def cached_simplify(expr: sp.Basic) -> sp.Expr:
84
+ """
85
+ Simplify a given sympy expression using a cache to speed up repeated simplifications.
86
+
87
+ :param expr: Sympy expression to be simplified.
88
+ :return: Simplified sympy expression.
89
+ """
90
+ if expr == sp.sympify(0):
91
+ return cast(sp.Expr, sp.sympify(0))
92
+ cache_dir = Path(user_cache_dir("nrpy"))
93
+ try:
94
+ pickle_expr = pickle.dumps(expr)
95
+ cache_dir.mkdir(parents=True, exist_ok=True)
96
+ cache_fle = cache_dir / (hashlib.sha256(pickle_expr).hexdigest() + ".nrpycache")
97
+ if cache_fle.exists():
98
+ with open(cache_fle, "rb") as file:
99
+ return cast(sp.Expr, pickle.load(file))
100
+ else:
101
+ simplified = sp.simplify(expr)
102
+ with open(cache_fle, "wb") as file:
103
+ pickle.dump(simplified, file)
104
+ return cast(sp.Expr, simplified)
105
+ except pickle.PicklingError:
106
+ return cast(sp.Expr, sp.simplify(expr))
@@ -15,7 +15,6 @@ import sympy as sp # SymPy: The Python computer algebra package upon which NRPy
15
15
  from nrpy.helpers.expr_tree import ExprTree
16
16
 
17
17
 
18
- # @profile
19
18
  def cse_preprocess(
20
19
  expr_list: Union[
21
20
  sp.Basic,
@@ -1,12 +1,13 @@
1
1
  """
2
2
  Generic helper functions used throughout NRPy+.
3
3
  """
4
- from typing import List, Any
4
+ from typing import List, Any, cast
5
5
  import subprocess
6
6
  import hashlib
7
7
  import lzma
8
8
  import base64
9
9
  from difflib import ndiff
10
+ from nrpy.helpers.cached_functions import is_cached, read_cached, write_cached
10
11
 
11
12
 
12
13
  #
@@ -74,7 +75,9 @@ def clang_format(
74
75
  return 0;
75
76
  }
76
77
  """
77
-
78
+ unique_id = __name__ + c_code_str + clang_format_options
79
+ if is_cached(unique_id):
80
+ return cast(str, read_cached(unique_id))
78
81
  with subprocess.Popen(
79
82
  ["clang-format", clang_format_options],
80
83
  stdin=subprocess.PIPE,
@@ -86,6 +89,7 @@ def clang_format(
86
89
 
87
90
  # If the process exited without errors, return the formatted code
88
91
  if process.returncode == 0:
92
+ write_cached(unique_id, stdout.decode())
89
93
  return stdout.decode()
90
94
 
91
95
  raise RuntimeError(f"Error using clang-format: {stderr.decode()}")
@@ -165,7 +165,6 @@ def register_CFunction_rhs_eval(
165
165
  read_xxs=not enable_rfm_precompute,
166
166
  OMP_collapse=OMP_collapse,
167
167
  )
168
-
169
168
  cfc.register_CFunction(
170
169
  include_CodeParameters_h=True,
171
170
  includes=includes,
@@ -5,6 +5,7 @@ import sympy as sp
5
5
  import nrpy.indexedexp as ixp
6
6
  import nrpy.params as par
7
7
  from nrpy.helpers.generic import superfast_uniq
8
+ from nrpy.helpers.cached_functions import cached_simplify
8
9
 
9
10
  # grid_physical_size is set based entirely on CoordSystem. So it is a rfm parameter not a grid parameter.
10
11
  par.register_param(bool, __name__, "enable_grid_physical_size", True)
@@ -297,7 +298,7 @@ class ReferenceMetric:
297
298
  for k in range(3):
298
299
  if self.SymPySimplifyExpressions:
299
300
  # ghatDDdD[i][j][k] = sp.trigsimp(sp.diff(ghatDD[i][j], xx[k])) # FIXME: BAD: MUST BE SIMPLIFIED OR ANSWER IS INCORRECT! Must be some bug in sympy...
300
- self.ghatDDdD[i][j][k] = sp.simplify(
301
+ self.ghatDDdD[i][j][k] = cached_simplify(
301
302
  sp.diff(self.ghatDD[i][j], self.xx[k])
302
303
  ) # FIXME: BAD: MUST BE SIMPLIFIED OR ANSWER IS INCORRECT! Must be some bug in sympy...
303
304
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: nrpy
3
- Version: 2.0.2
3
+ Version: 2.0.3
4
4
  Summary: Python/SymPy-based code generation for numerical relativity... and beyond!
5
5
  Home-page: https://github.com/nrpy/nrpy
6
6
  Author: Zachariah Etienne
@@ -42,6 +42,7 @@ nrpy/examples/two_blackholes_collide.py
42
42
  nrpy/examples/wave_equation_cartesian.py
43
43
  nrpy/examples/wave_equation_curvilinear.py
44
44
  nrpy/helpers/__init__.py
45
+ nrpy/helpers/cached_functions.py
45
46
  nrpy/helpers/cse_preprocess_postprocess.py
46
47
  nrpy/helpers/expr_tree.py
47
48
  nrpy/helpers/functional.py
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes