11import sys
22
3- from mpmath import mp , MPContext , exp , sqrt , tanh
3+ from mpmath import mp , exp , invertlaplace , sqrt , tanh , workdps
44import numpy as np
55
66import geophires_x .Model as Model
@@ -108,18 +108,29 @@ def Calculate(self, model: Model):
108108 # calculate non-dimensional temperature array
109109 Twnd = []
110110 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 )
118127
119128 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+ )
123134 print (msg )
124135 raise RuntimeError (msg ) from e_
125136
@@ -131,27 +142,3 @@ def Calculate(self, model: Model):
131142
132143 model .logger .info (f'Complete { str (__class__ )} : { sys ._getframe ().f_code .co_name } ' )
133144
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