|
1 | 1 | import sys
|
2 | 2 |
|
3 |
| -from mpmath import mp |
| 3 | +from mpmath import mp, MPContext, exp, sqrt, tanh |
4 | 4 | import numpy as np
|
5 |
| -from mpmath import * |
| 5 | + |
6 | 6 | import geophires_x.Model as Model
|
7 | 7 | from .Parameter import intParameter
|
8 | 8 | from .Reservoir import Reservoir
|
@@ -108,27 +108,50 @@ def Calculate(self, model: Model):
|
108 | 108 | # calculate non-dimensional temperature array
|
109 | 109 | Twnd = []
|
110 | 110 | try:
|
111 |
| - stash_dps = mp.dps |
| 111 | + dps = mp.dps |
112 | 112 | if self.gringarten_stehfest_precision.Provided:
|
113 |
| - mp.dps = self.gringarten_stehfest_precision.value |
| 113 | + dps = self.gringarten_stehfest_precision.value |
114 | 114 |
|
115 | 115 | for t in range(1, len(model.reserv.timevector.value)):
|
116 |
| - Twnd = Twnd + [float(invertlaplace(fp, td[t], method='stehfest'))] |
117 |
| - except Exception as e_: |
118 |
| - mp.dps = stash_dps |
| 116 | + # Twnd = Twnd + [float(invertlaplace(fp, td[t], method='stehfest'))] |
| 117 | + Twnd = Twnd + [float(_thread_safe_invertlaplace_stehfest(fp, td[t], dps))] |
119 | 118 |
|
| 119 | + except Exception as e_: |
120 | 120 | msg = (f'Error: GEOPHIRES could not execute numerical inverse laplace calculation for reservoir model 1 '
|
121 |
| - f'({self.gringarten_stehfest_precision.Name} = {mpmath.dps}). ' |
| 121 | + f'({self.gringarten_stehfest_precision.Name} = {dps}). ' |
122 | 122 | 'Simulation will abort.')
|
123 | 123 | print(msg)
|
124 | 124 | raise RuntimeError(msg) from e_
|
125 | 125 |
|
126 |
| - mp.dps = stash_dps |
127 |
| - |
128 | 126 | Twnd = np.asarray(Twnd)
|
129 | 127 |
|
130 | 128 | # calculate dimensional temperature, add initial rock temperature to beginning of array
|
131 | 129 | model.reserv.Tresoutput.value = model.reserv.Trock.value - (Twnd * (model.reserv.Trock.value - model.wellbores.Tinj.value))
|
132 | 130 | model.reserv.Tresoutput.value = np.append([model.reserv.Trock.value], model.reserv.Tresoutput.value)
|
133 | 131 |
|
134 | 132 | model.logger.info(f'Complete {str(__class__)}: {sys._getframe().f_code.co_name}')
|
| 133 | + |
| 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