1
1
import sys
2
2
3
- from mpmath import mp , MPContext , exp , sqrt , tanh
3
+ from mpmath import mp , exp , invertlaplace , sqrt , tanh , workdps
4
4
import numpy as np
5
5
6
6
import geophires_x .Model as Model
@@ -108,18 +108,29 @@ def Calculate(self, model: Model):
108
108
# calculate non-dimensional temperature array
109
109
Twnd = []
110
110
try :
111
- dps = mp .dps
112
- if self .gringarten_stehfest_precision .Provided :
113
- dps = self .gringarten_stehfest_precision .value
114
-
115
- for t in range (1 , len (model .reserv .timevector .value )):
116
- # Twnd = Twnd + [float(invertlaplace(fp, td[t], method='stehfest'))]
117
- Twnd = Twnd + [float (_thread_safe_invertlaplace_stehfest (fp , td [t ], dps ))]
111
+ # Determine the required precision for this calculation.
112
+ precision = (
113
+ self .gringarten_stehfest_precision .value
114
+ if self .gringarten_stehfest_precision .Provided
115
+ else mp .dps
116
+ )
117
+
118
+ # Use the workdps context manager for a robust, thread-safe solution.
119
+ # It temporarily sets mp.dps for this block and restores it automatically.
120
+ with workdps (precision ):
121
+ # A list comprehension is a more concise way to build the list.
122
+ twnd_list = [
123
+ float (invertlaplace (fp , td [t ], method = 'stehfest' ))
124
+ for t in range (1 , len (model .reserv .timevector .value ))
125
+ ]
126
+ Twnd = np .asarray (twnd_list )
118
127
119
128
except Exception as e_ :
120
- msg = (f'Error: GEOPHIRES could not execute numerical inverse laplace calculation for reservoir model 1 '
121
- f'({ self .gringarten_stehfest_precision .Name } = { dps } ). '
122
- 'Simulation will abort.' )
129
+ msg = (
130
+ f'Error: GEOPHIRES could not execute numerical inverse laplace calculation for reservoir model 1 '
131
+ f'({ self .gringarten_stehfest_precision .Name } = { precision } ). '
132
+ 'Simulation will abort.'
133
+ )
123
134
print (msg )
124
135
raise RuntimeError (msg ) from e_
125
136
@@ -131,27 +142,3 @@ def Calculate(self, model: Model):
131
142
132
143
model .logger .info (f'Complete { str (__class__ )} : { sys ._getframe ().f_code .co_name } ' )
133
144
134
-
135
- # noinspection SpellCheckingInspection
136
- def _thread_safe_invertlaplace_stehfest (fp , t , dps ):
137
- """
138
- Calculates the inverse Laplace transform at a specific precision
139
- without modifying the global mpmath context.
140
-
141
- Args:
142
- fp: The Laplace-space function.
143
- t: The time at which to evaluate the inverse transform.
144
- dps: The desired decimal places of precision for this calculation.
145
-
146
- Returns:
147
- The result of the inverse Laplace transform.
148
- """
149
- # Create a local, temporary context object.
150
- local_ctx = MPContext ()
151
-
152
- # Set the desired precision *only* on this local context.
153
- local_ctx .dps = dps
154
-
155
- # Call invertlaplace from the local_ctx object. It will use its own
156
- # precision when instantiating the stehfest method internally.
157
- return local_ctx .invertlaplace (fp , t , method = 'stehfest' )
0 commit comments