romtools.workflows.residual_evaluator
Protocol for interfacing with external application to compute residual snapshots corresponding to existing state snapshots.
1''' 2Protocol for interfacing with external application to compute residual snapshots 3corresponding to existing state snapshots. 4''' 5 6from typing import Protocol, Iterable, Tuple 7import numpy as np 8 9from romtools.workflows.workflow_utils import create_empty_dir 10 11 12class ResidualEvaluator(Protocol): 13 ''' 14 Baseline residual evaluator protocol 15 ''' 16 17 def compute_reduced_states(self, filename: str) -> np.ndarray: 18 ''' 19 Reads the full-order model solution(s) from the specified filename 20 and computes the corresponding reduced state(s) 21 22 Args: 23 filename (str): filename of the file containing the full-order model solution data 24 25 Returns: 26 `np.ndarray`: The projected full-order solution in a 1- or 2-dimensional array. 27 1st dimension: reduced state, 2nd dimension: sample index corresponding full-model 28 solution data file. 29 30 ''' 31 pass 32 33 def evaluate_full_residuals( 34 self, 35 run_directory: str, 36 full_model_directory: str, 37 reduced_states: np.ndarray, 38 parameter_sample: dict, 39 ) -> np.ndarray: 40 ''' 41 Evaluate the full-order model residuals corresponding to full states reconstructed from 42 an array of reduced states 43 44 Args: 45 run_directory (str): Absolute path to directory in which residual is being computed. 46 full_model_directory (str): Absolute path to directory in which the full model data was computed. 47 reduced_state (np.ndarray): 2-dimensional reduced state vector. 1st dimension: reduced state, 48 2nd dimension: sample index 49 parameter_sample: Dictionary contatining parameter names and sample values 50 51 Returns: 52 `np.ndarray`: The full-order residual in tensor form, should be 3-dimensional, even for a single sample 53 ''' 54 pass 55 56 def evaluate_full_residuals_and_jacobian_basis_products( 57 self, 58 run_directory: str, 59 full_model_directory: str, 60 reduced_states: np.ndarray, 61 parameter_sample: dict, 62 ) -> Tuple[np.ndarray, np.ndarray]: 63 ''' 64 Evaluate the full-order model residuals corresponding to full states reconstructed from 65 an array of reduced states 66 67 Args: 68 run_directory (str): Absolute path to directory in which residual is being computed. 69 full_model_directory (str): Absolute path to directory in which the full model data was computed. 70 reduced_state (np.ndarray): 2-dimensional reduced state vector. 1st dimension: reduced state, 71 2nd dimension: sample index 72 parameter_sample: Dictionary contatining parameter names and sample values 73 74 Returns: 75 `np.ndarray`: The full-order residual in tensor form, should be 3-dimensional, even for a single sample 76 `np.ndarray`: The full-order jacobian-basis product in tensor form, should be 4-dimensional, even for a single sample 77 1st dimension: sample index, 2nd dimension: variable index, 3rd dimension: spatial index, 4th dimension: modal index 78 ''' 79 pass 80 81 82class TransientResidualEvaluator(Protocol): 83 ''' 84 Baseline residual evaluator protocol 85 ''' 86 87 def compute_reduced_states(self, filename: str) -> np.ndarray: 88 ''' 89 Reads the full-order model solution and time stamps from the specified filename 90 and computes the corresponding reduced states 91 92 Args: 93 filename (str): filename of the file containing the full-order model solution data 94 95 Returns: 96 `np.ndarray`: The projected full-order solution in a 2- or 3-dimensional array. 1st 97 dimension: reduced state, 2nd dimension: time, 3rd dimension: other states in time 98 stencil. If the array is 2-dimensional, it is assumed that the states are sequential 99 in time. 100 101 ''' 102 pass 103 104 def get_times(self, filename: str) -> np.ndarray: 105 ''' 106 Reads and outputs time stamps from the specified filename 107 108 Args: 109 filename (str): filename of the file containing the full-order model solution data 110 111 Returns: 112 `np.ndarray`: The corresponding solution time stamps in a 1- or 2-dimensional array. 113 The optional 2nd dimension is only needed if the reduced projected full-order solution 114 array is 3-dimensional; the 2nd dimension contains the time stamps of the other states 115 in the time-stencil for a given time stamp. 116 117 ''' 118 pass 119 120 def evaluate_full_residuals( 121 self, 122 run_directory: str, 123 full_model_directory: str, 124 reduced_states: np.ndarray, 125 parameter_sample: dict, 126 times: np.ndarray, 127 ) -> np.ndarray: 128 ''' 129 Evaluate the full-order model residuals corresponding to full states reconstructed from 130 an array of reduced states 131 132 Args: 133 run_directory (str): Absolute path to directory in which residual is being computed. 134 full_model_directory (str): Absolute path to directory in which the full model data was computed. 135 reduced_state (np.ndarray): 2- or 3-dimensional reduced state vector. 1st dimension: reduced state, 136 2nd dimension: time, 3rd dimension: other states in time stencil. If the array is 2-dimensional, it 137 is assumed that the states are sequential in time. 138 parameter_sample: Dictionary contatining parameter names and sample values 139 times (np.ndarray): 1-dimensional or 2-dimesional vector of time stamps. The optional 140 2nd dimension is only needed if the reduced state array is 3-dimensional; the 2nd dimension 141 contains the time stamps of the other states in the time-stencil for a given time stamp. 142 143 Returns: 144 `np.ndarray`: The full-order residual in tensor form, should be 3-dimensional, even for a single time step 145 ''' 146 pass 147 148 def evaluate_full_residuals_and_jacobian_basis_products( 149 self, 150 run_directory: str, 151 full_model_directory: str, 152 reduced_states: np.ndarray, 153 parameter_sample: dict, 154 times: np.ndarray, 155 ) -> Tuple[np.ndarray, np.ndarray]: 156 ''' 157 Evaluate the full-order model residuals corresponding to full states reconstructed from 158 an array of reduced states 159 160 Args: 161 run_directory (str): Absolute path to directory in which residual is being computed. 162 full_model_directory (str): Absolute path to directory in which the full model data was computed. 163 reduced_state (np.ndarray): 2- or 3-dimensional reduced state vector. 1st dimension: reduced state, 164 2nd dimension: time, 3rd dimension: other states in time stencil. If the array is 2-dimensional, it 165 is assumed that the states are sequential in time. 166 parameter_sample: Dictionary contatining parameter names and sample values 167 times (np.ndarray): 1-dimensional or 2-dimesional vector of time stamps. The optional 168 2nd dimension is only needed if the reduced state array is 3-dimensional; the 2nd dimension 169 contains the time stamps of the other states in the time-stencil for a given time stamp. 170 171 Returns: 172 `np.ndarray`: The full-order residual in tensor form, should be 3-dimensional, even for a single time step. 173 `np.ndarray`: The full-order jacobian-basis product in tensor form, should be 4-dimensional, even for a single sample 174 1st dimension: sample index, 2nd dimension: variable index, 3rd dimension: spatial index, 4th dimension: modal index 175 ''' 176 pass 177 178 179def evaluate_and_load_steady_residual_snapshots( 180 residual_evaluator: ResidualEvaluator, 181 full_state_directories: Iterable[str], 182 state_filename: str, 183 absolute_run_directory: str, 184) -> np.ndarray: 185 ''' 186 Core algorithm that takes a residual_evaluator, a list of steady full-order model 187 snapshot directories, and a snapshot_filename, and computes the corresponding 188 residual snapshots. 189 190 Args: 191 residual_evaluator (ResidualEvaluator): steady residual evaluator we wish to use 192 full_state_directories (list[str]): list of directories containing full state data 193 state_filename (str): filename or base filename of file containing state data 194 absolute_run_directory (str): absolute path to base directory in which residuals are evaluated 195 196 Returns: 197 `np.ndarray`: The full-order residual snapshots in tensor form. 198 ''' 199 200 run_directory_base = f"{absolute_run_directory}/res_" 201 202 all_residual_snapshots = [] 203 n_vars = -1 204 n_x = -1 205 for index, full_model_dir in enumerate(full_state_directories): 206 # Read and project FOM snapshot 207 reduced_state = residual_evaluator.compute_reduced_states( 208 full_model_dir + "/" + state_filename 209 ) 210 211 # Set up corresponding directory 212 run_directory = f"{run_directory_base}{index}" 213 create_empty_dir(run_directory) 214 215 # Evaluate residual 216 residual_snapshot = residual_evaluator.evaluate_full_residuals( 217 run_directory, full_model_dir, reduced_state, None 218 ) 219 220 # check residual snapshot size and shape 221 if n_vars == -1 and n_x == -1: 222 n_vars = residual_snapshot.shape[0] 223 n_x = residual_snapshot.shape[1] 224 assert residual_snapshot.shape[0] == n_vars 225 assert residual_snapshot.shape[1] == n_x 226 227 all_residual_snapshots.append(residual_snapshot) 228 229 # convert list to array 230 # does it kill memory usage to do this? 231 return np.concatenate(all_residual_snapshots, axis=2) 232 233 234def evaluate_and_load_steady_residual_and_jacobian_snapshots( 235 residual_evaluator: ResidualEvaluator, 236 full_state_directories: Iterable[str], 237 state_filename: str, 238 absolute_run_directory: str, 239) -> Tuple[np.ndarray, np.ndarray]: 240 ''' 241 Core algorithm that takes a residual_evaluator, a list of steady full-order model 242 snapshot directories, and a snapshot_filename, and computes the corresponding 243 residual and Jacobian-basis product snapshots. 244 245 Args: 246 residual_evaluator (ResidualEvaluator): steady residual evaluator we wish to use 247 full_state_directories (list[str]): list of directories containing full state data 248 state_filename (str): filename or base filename of file containing state data 249 absolute_run_directory (str): absolute path to base directory in which residuals are evaluated 250 251 Returns: 252 `np.ndarray`: The full-order residual snapshots in tensor form. 253 `np.ndarray`: The full-order Jacobian-basis product snapshots in tensor form. 254 ''' 255 256 run_directory_base = f"{absolute_run_directory}/res_" 257 258 all_residual_snapshots = [] 259 all_jacobian_snapshots = [] 260 n_vars = -1 261 n_x = -1 262 n_modes = -1 263 for index, full_model_dir in enumerate(full_state_directories): 264 # Read and project FOM snapshot 265 reduced_state = residual_evaluator.compute_reduced_states( 266 full_model_dir + "/" + state_filename 267 ) 268 269 # Set up corresponding directory 270 run_directory = f"{run_directory_base}{index}" 271 create_empty_dir(run_directory) 272 273 # Evaluate residual 274 residual_snapshot, jacobian_snapshot = ( 275 residual_evaluator.evaluate_full_residuals_and_jacobian_basis_products( 276 run_directory, full_model_dir, reduced_state, None 277 ) 278 ) 279 280 # check residual snapshot size and shape 281 if n_vars == -1 and n_x == -1: 282 n_vars = residual_snapshot.shape[0] 283 n_x = residual_snapshot.shape[1] 284 assert residual_snapshot.shape[0] == n_vars 285 assert residual_snapshot.shape[1] == n_x 286 287 # check Jacobian-basis product snapshot size and shape 288 if n_modes == -1: 289 n_modes = jacobian_snapshot.shape[3] 290 assert jacobian_snapshot.shape[1] == n_vars 291 assert jacobian_snapshot.shape[2] == n_x 292 293 all_residual_snapshots.append(residual_snapshot) 294 all_jacobian_snapshots.append(jacobian_snapshot) 295 296 # convert list to array 297 # does it kill memory usage to do this? 298 return np.concatenate(all_residual_snapshots, axis=2), np.concatenate( 299 all_jacobian_snapshots, axis=0 300 ) 301 302 303def evaluate_and_load_unsteady_residual_snapshots( 304 residual_evaluator: TransientResidualEvaluator, 305 full_state_directories: Iterable[str], 306 state_filename: str, 307 absolute_run_directory: str, 308) -> np.ndarray: 309 ''' 310 Core algorithm that takes a residual_evaluator, a list of unsteady full-order model 311 snapshot directories, and a snapshot_filename, and computes the corresponding 312 residual snapshots. 313 314 Args: 315 residual_evaluator (TransientResidualEvaluator): transient residual evaluator we wish to use 316 full_state_directories (list[str]): list of directories containing full state data 317 state_filename (str): filename or base filename of file containing state data 318 absolute_run_directory (str): absolute path to base directory in which residuals are evaluated 319 320 Returns: 321 `np.ndarray`: The full-order residual snapshots in tensor form. 322 323 ''' 324 325 run_directory_base = f"{absolute_run_directory}/res_" 326 327 all_residual_snapshots = [] 328 n_vars = -1 329 n_x = -1 330 for index, full_model_dir in enumerate(full_state_directories): 331 # Read and project FOM snapshots 332 reduced_states = residual_evaluator.compute_reduced_states( 333 full_model_dir + "/" + state_filename 334 ) 335 times = residual_evaluator.get_times(full_model_dir + "/" + state_filename) 336 337 # Set up corresponding directory 338 run_directory = f"{run_directory_base}{index}" 339 create_empty_dir(run_directory) 340 341 # Evaluate residuals 342 residual_snapshots = residual_evaluator.evaluate_full_residuals( 343 run_directory, full_model_dir, reduced_states, None, times 344 ) 345 346 # check residual snapshot size and shape 347 assert residual_snapshots.ndim == 3 348 if n_vars == -1 and n_x == -1: 349 n_vars = residual_snapshots.shape[0] 350 n_x = residual_snapshots.shape[1] 351 assert residual_snapshots.shape[0] == n_vars 352 assert residual_snapshots.shape[1] == n_x 353 354 all_residual_snapshots.append(residual_snapshots) 355 356 # convert list to array 357 # does it kill memory usage to do this? 358 return np.concatenate(all_residual_snapshots, axis=2) 359 360 361def evaluate_and_load_unsteady_residual_and_jacobian_snapshots( 362 residual_evaluator: TransientResidualEvaluator, 363 full_state_directories: Iterable[str], 364 state_filename: str, 365 absolute_run_directory: str, 366) -> Tuple[np.ndarray, np.ndarray]: 367 ''' 368 Core algorithm that takes a residual_evaluator, a list of unsteady full-order model 369 snapshot directories, and a snapshot_filename, and computes the corresponding 370 residual snapshots. 371 372 Args: 373 residual_evaluator (TransientResidualEvaluator): transient residual evaluator we wish to use 374 full_state_directories (list[str]): list of directories containing full state data 375 state_filename (str): filename or base filename of file containing state data 376 absolute_run_directory (str): absolute path to base directory in which residuals are evaluated 377 378 Returns: 379 `np.ndarray`: The full-order residual snapshots in tensor form. 380 `np.ndarray`: The full-order Jacobian-basis product snapshots in tensor form. 381 ''' 382 383 run_directory_base = f"{absolute_run_directory}/res_" 384 385 all_residual_snapshots = [] 386 all_jacobian_snapshots = [] 387 n_vars = -1 388 n_x = -1 389 n_modes = -1 390 for index, full_model_dir in enumerate(full_state_directories): 391 # Read and project FOM snapshots 392 reduced_states = residual_evaluator.compute_reduced_states( 393 full_model_dir + "/" + state_filename 394 ) 395 times = residual_evaluator.get_times(full_model_dir + "/" + state_filename) 396 397 # Set up corresponding directory 398 run_directory = f"{run_directory_base}{index}" 399 create_empty_dir(run_directory) 400 401 # Evaluate residuals 402 residual_snapshots, jacobian_snapshots = ( 403 residual_evaluator.evaluate_full_residuals_and_jacobian_basis_products( 404 run_directory, full_model_dir, reduced_states, None, times 405 ) 406 ) 407 408 # check residual snapshot size and shape 409 assert residual_snapshots.ndim == 3 410 if n_vars == -1 and n_x == -1: 411 n_vars = residual_snapshots.shape[0] 412 n_x = residual_snapshots.shape[1] 413 assert residual_snapshots.shape[0] == n_vars 414 assert residual_snapshots.shape[1] == n_x 415 416 # check residual snapshot size and shape 417 assert jacobian_snapshots.ndim == 4 418 if n_modes == -1: 419 n_modes = jacobian_snapshots.shape[3] 420 assert jacobian_snapshots.shape[1] == n_vars 421 assert jacobian_snapshots.shape[2] == n_x 422 assert jacobian_snapshots.shape[3] == n_modes 423 424 all_residual_snapshots.append(residual_snapshots) 425 all_jacobian_snapshots.append(jacobian_snapshots) 426 427 # convert list to array 428 # does it kill memory usage to do this? 429 return np.concatenate(all_residual_snapshots, axis=2), np.concatenate( 430 all_jacobian_snapshots, axis=0 431 )
13class ResidualEvaluator(Protocol): 14 ''' 15 Baseline residual evaluator protocol 16 ''' 17 18 def compute_reduced_states(self, filename: str) -> np.ndarray: 19 ''' 20 Reads the full-order model solution(s) from the specified filename 21 and computes the corresponding reduced state(s) 22 23 Args: 24 filename (str): filename of the file containing the full-order model solution data 25 26 Returns: 27 `np.ndarray`: The projected full-order solution in a 1- or 2-dimensional array. 28 1st dimension: reduced state, 2nd dimension: sample index corresponding full-model 29 solution data file. 30 31 ''' 32 pass 33 34 def evaluate_full_residuals( 35 self, 36 run_directory: str, 37 full_model_directory: str, 38 reduced_states: np.ndarray, 39 parameter_sample: dict, 40 ) -> np.ndarray: 41 ''' 42 Evaluate the full-order model residuals corresponding to full states reconstructed from 43 an array of reduced states 44 45 Args: 46 run_directory (str): Absolute path to directory in which residual is being computed. 47 full_model_directory (str): Absolute path to directory in which the full model data was computed. 48 reduced_state (np.ndarray): 2-dimensional reduced state vector. 1st dimension: reduced state, 49 2nd dimension: sample index 50 parameter_sample: Dictionary contatining parameter names and sample values 51 52 Returns: 53 `np.ndarray`: The full-order residual in tensor form, should be 3-dimensional, even for a single sample 54 ''' 55 pass 56 57 def evaluate_full_residuals_and_jacobian_basis_products( 58 self, 59 run_directory: str, 60 full_model_directory: str, 61 reduced_states: np.ndarray, 62 parameter_sample: dict, 63 ) -> Tuple[np.ndarray, np.ndarray]: 64 ''' 65 Evaluate the full-order model residuals corresponding to full states reconstructed from 66 an array of reduced states 67 68 Args: 69 run_directory (str): Absolute path to directory in which residual is being computed. 70 full_model_directory (str): Absolute path to directory in which the full model data was computed. 71 reduced_state (np.ndarray): 2-dimensional reduced state vector. 1st dimension: reduced state, 72 2nd dimension: sample index 73 parameter_sample: Dictionary contatining parameter names and sample values 74 75 Returns: 76 `np.ndarray`: The full-order residual in tensor form, should be 3-dimensional, even for a single sample 77 `np.ndarray`: The full-order jacobian-basis product in tensor form, should be 4-dimensional, even for a single sample 78 1st dimension: sample index, 2nd dimension: variable index, 3rd dimension: spatial index, 4th dimension: modal index 79 ''' 80 pass
Baseline residual evaluator protocol
1771def _no_init_or_replace_init(self, *args, **kwargs): 1772 cls = type(self) 1773 1774 if cls._is_protocol: 1775 raise TypeError('Protocols cannot be instantiated') 1776 1777 # Already using a custom `__init__`. No need to calculate correct 1778 # `__init__` to call. This can lead to RecursionError. See bpo-45121. 1779 if cls.__init__ is not _no_init_or_replace_init: 1780 return 1781 1782 # Initially, `__init__` of a protocol subclass is set to `_no_init_or_replace_init`. 1783 # The first instantiation of the subclass will call `_no_init_or_replace_init` which 1784 # searches for a proper new `__init__` in the MRO. The new `__init__` 1785 # replaces the subclass' old `__init__` (ie `_no_init_or_replace_init`). Subsequent 1786 # instantiation of the protocol subclass will thus use the new 1787 # `__init__` and no longer call `_no_init_or_replace_init`. 1788 for base in cls.__mro__: 1789 init = base.__dict__.get('__init__', _no_init_or_replace_init) 1790 if init is not _no_init_or_replace_init: 1791 cls.__init__ = init 1792 break 1793 else: 1794 # should not happen 1795 cls.__init__ = object.__init__ 1796 1797 cls.__init__(self, *args, **kwargs)
18 def compute_reduced_states(self, filename: str) -> np.ndarray: 19 ''' 20 Reads the full-order model solution(s) from the specified filename 21 and computes the corresponding reduced state(s) 22 23 Args: 24 filename (str): filename of the file containing the full-order model solution data 25 26 Returns: 27 `np.ndarray`: The projected full-order solution in a 1- or 2-dimensional array. 28 1st dimension: reduced state, 2nd dimension: sample index corresponding full-model 29 solution data file. 30 31 ''' 32 pass
Reads the full-order model solution(s) from the specified filename and computes the corresponding reduced state(s)
Arguments:
- filename (str): filename of the file containing the full-order model solution data
Returns:
np.ndarray
: The projected full-order solution in a 1- or 2-dimensional array. 1st dimension: reduced state, 2nd dimension: sample index corresponding full-model solution data file.
34 def evaluate_full_residuals( 35 self, 36 run_directory: str, 37 full_model_directory: str, 38 reduced_states: np.ndarray, 39 parameter_sample: dict, 40 ) -> np.ndarray: 41 ''' 42 Evaluate the full-order model residuals corresponding to full states reconstructed from 43 an array of reduced states 44 45 Args: 46 run_directory (str): Absolute path to directory in which residual is being computed. 47 full_model_directory (str): Absolute path to directory in which the full model data was computed. 48 reduced_state (np.ndarray): 2-dimensional reduced state vector. 1st dimension: reduced state, 49 2nd dimension: sample index 50 parameter_sample: Dictionary contatining parameter names and sample values 51 52 Returns: 53 `np.ndarray`: The full-order residual in tensor form, should be 3-dimensional, even for a single sample 54 ''' 55 pass
Evaluate the full-order model residuals corresponding to full states reconstructed from an array of reduced states
Arguments:
- run_directory (str): Absolute path to directory in which residual is being computed.
- full_model_directory (str): Absolute path to directory in which the full model data was computed.
- reduced_state (np.ndarray): 2-dimensional reduced state vector. 1st dimension: reduced state,
- 2nd dimension: sample index
- parameter_sample: Dictionary contatining parameter names and sample values
Returns:
np.ndarray
: The full-order residual in tensor form, should be 3-dimensional, even for a single sample
57 def evaluate_full_residuals_and_jacobian_basis_products( 58 self, 59 run_directory: str, 60 full_model_directory: str, 61 reduced_states: np.ndarray, 62 parameter_sample: dict, 63 ) -> Tuple[np.ndarray, np.ndarray]: 64 ''' 65 Evaluate the full-order model residuals corresponding to full states reconstructed from 66 an array of reduced states 67 68 Args: 69 run_directory (str): Absolute path to directory in which residual is being computed. 70 full_model_directory (str): Absolute path to directory in which the full model data was computed. 71 reduced_state (np.ndarray): 2-dimensional reduced state vector. 1st dimension: reduced state, 72 2nd dimension: sample index 73 parameter_sample: Dictionary contatining parameter names and sample values 74 75 Returns: 76 `np.ndarray`: The full-order residual in tensor form, should be 3-dimensional, even for a single sample 77 `np.ndarray`: The full-order jacobian-basis product in tensor form, should be 4-dimensional, even for a single sample 78 1st dimension: sample index, 2nd dimension: variable index, 3rd dimension: spatial index, 4th dimension: modal index 79 ''' 80 pass
Evaluate the full-order model residuals corresponding to full states reconstructed from an array of reduced states
Arguments:
- run_directory (str): Absolute path to directory in which residual is being computed.
- full_model_directory (str): Absolute path to directory in which the full model data was computed.
- reduced_state (np.ndarray): 2-dimensional reduced state vector. 1st dimension: reduced state,
- 2nd dimension: sample index
- parameter_sample: Dictionary contatining parameter names and sample values
Returns:
np.ndarray
: The full-order residual in tensor form, should be 3-dimensional, even for a single samplenp.ndarray
: The full-order jacobian-basis product in tensor form, should be 4-dimensional, even for a single sample 1st dimension: sample index, 2nd dimension: variable index, 3rd dimension: spatial index, 4th dimension: modal index
83class TransientResidualEvaluator(Protocol): 84 ''' 85 Baseline residual evaluator protocol 86 ''' 87 88 def compute_reduced_states(self, filename: str) -> np.ndarray: 89 ''' 90 Reads the full-order model solution and time stamps from the specified filename 91 and computes the corresponding reduced states 92 93 Args: 94 filename (str): filename of the file containing the full-order model solution data 95 96 Returns: 97 `np.ndarray`: The projected full-order solution in a 2- or 3-dimensional array. 1st 98 dimension: reduced state, 2nd dimension: time, 3rd dimension: other states in time 99 stencil. If the array is 2-dimensional, it is assumed that the states are sequential 100 in time. 101 102 ''' 103 pass 104 105 def get_times(self, filename: str) -> np.ndarray: 106 ''' 107 Reads and outputs time stamps from the specified filename 108 109 Args: 110 filename (str): filename of the file containing the full-order model solution data 111 112 Returns: 113 `np.ndarray`: The corresponding solution time stamps in a 1- or 2-dimensional array. 114 The optional 2nd dimension is only needed if the reduced projected full-order solution 115 array is 3-dimensional; the 2nd dimension contains the time stamps of the other states 116 in the time-stencil for a given time stamp. 117 118 ''' 119 pass 120 121 def evaluate_full_residuals( 122 self, 123 run_directory: str, 124 full_model_directory: str, 125 reduced_states: np.ndarray, 126 parameter_sample: dict, 127 times: np.ndarray, 128 ) -> np.ndarray: 129 ''' 130 Evaluate the full-order model residuals corresponding to full states reconstructed from 131 an array of reduced states 132 133 Args: 134 run_directory (str): Absolute path to directory in which residual is being computed. 135 full_model_directory (str): Absolute path to directory in which the full model data was computed. 136 reduced_state (np.ndarray): 2- or 3-dimensional reduced state vector. 1st dimension: reduced state, 137 2nd dimension: time, 3rd dimension: other states in time stencil. If the array is 2-dimensional, it 138 is assumed that the states are sequential in time. 139 parameter_sample: Dictionary contatining parameter names and sample values 140 times (np.ndarray): 1-dimensional or 2-dimesional vector of time stamps. The optional 141 2nd dimension is only needed if the reduced state array is 3-dimensional; the 2nd dimension 142 contains the time stamps of the other states in the time-stencil for a given time stamp. 143 144 Returns: 145 `np.ndarray`: The full-order residual in tensor form, should be 3-dimensional, even for a single time step 146 ''' 147 pass 148 149 def evaluate_full_residuals_and_jacobian_basis_products( 150 self, 151 run_directory: str, 152 full_model_directory: str, 153 reduced_states: np.ndarray, 154 parameter_sample: dict, 155 times: np.ndarray, 156 ) -> Tuple[np.ndarray, np.ndarray]: 157 ''' 158 Evaluate the full-order model residuals corresponding to full states reconstructed from 159 an array of reduced states 160 161 Args: 162 run_directory (str): Absolute path to directory in which residual is being computed. 163 full_model_directory (str): Absolute path to directory in which the full model data was computed. 164 reduced_state (np.ndarray): 2- or 3-dimensional reduced state vector. 1st dimension: reduced state, 165 2nd dimension: time, 3rd dimension: other states in time stencil. If the array is 2-dimensional, it 166 is assumed that the states are sequential in time. 167 parameter_sample: Dictionary contatining parameter names and sample values 168 times (np.ndarray): 1-dimensional or 2-dimesional vector of time stamps. The optional 169 2nd dimension is only needed if the reduced state array is 3-dimensional; the 2nd dimension 170 contains the time stamps of the other states in the time-stencil for a given time stamp. 171 172 Returns: 173 `np.ndarray`: The full-order residual in tensor form, should be 3-dimensional, even for a single time step. 174 `np.ndarray`: The full-order jacobian-basis product in tensor form, should be 4-dimensional, even for a single sample 175 1st dimension: sample index, 2nd dimension: variable index, 3rd dimension: spatial index, 4th dimension: modal index 176 ''' 177 pass
Baseline residual evaluator protocol
1771def _no_init_or_replace_init(self, *args, **kwargs): 1772 cls = type(self) 1773 1774 if cls._is_protocol: 1775 raise TypeError('Protocols cannot be instantiated') 1776 1777 # Already using a custom `__init__`. No need to calculate correct 1778 # `__init__` to call. This can lead to RecursionError. See bpo-45121. 1779 if cls.__init__ is not _no_init_or_replace_init: 1780 return 1781 1782 # Initially, `__init__` of a protocol subclass is set to `_no_init_or_replace_init`. 1783 # The first instantiation of the subclass will call `_no_init_or_replace_init` which 1784 # searches for a proper new `__init__` in the MRO. The new `__init__` 1785 # replaces the subclass' old `__init__` (ie `_no_init_or_replace_init`). Subsequent 1786 # instantiation of the protocol subclass will thus use the new 1787 # `__init__` and no longer call `_no_init_or_replace_init`. 1788 for base in cls.__mro__: 1789 init = base.__dict__.get('__init__', _no_init_or_replace_init) 1790 if init is not _no_init_or_replace_init: 1791 cls.__init__ = init 1792 break 1793 else: 1794 # should not happen 1795 cls.__init__ = object.__init__ 1796 1797 cls.__init__(self, *args, **kwargs)
88 def compute_reduced_states(self, filename: str) -> np.ndarray: 89 ''' 90 Reads the full-order model solution and time stamps from the specified filename 91 and computes the corresponding reduced states 92 93 Args: 94 filename (str): filename of the file containing the full-order model solution data 95 96 Returns: 97 `np.ndarray`: The projected full-order solution in a 2- or 3-dimensional array. 1st 98 dimension: reduced state, 2nd dimension: time, 3rd dimension: other states in time 99 stencil. If the array is 2-dimensional, it is assumed that the states are sequential 100 in time. 101 102 ''' 103 pass
Reads the full-order model solution and time stamps from the specified filename and computes the corresponding reduced states
Arguments:
- filename (str): filename of the file containing the full-order model solution data
Returns:
np.ndarray
: The projected full-order solution in a 2- or 3-dimensional array. 1st dimension: reduced state, 2nd dimension: time, 3rd dimension: other states in time stencil. If the array is 2-dimensional, it is assumed that the states are sequential in time.
105 def get_times(self, filename: str) -> np.ndarray: 106 ''' 107 Reads and outputs time stamps from the specified filename 108 109 Args: 110 filename (str): filename of the file containing the full-order model solution data 111 112 Returns: 113 `np.ndarray`: The corresponding solution time stamps in a 1- or 2-dimensional array. 114 The optional 2nd dimension is only needed if the reduced projected full-order solution 115 array is 3-dimensional; the 2nd dimension contains the time stamps of the other states 116 in the time-stencil for a given time stamp. 117 118 ''' 119 pass
Reads and outputs time stamps from the specified filename
Arguments:
- filename (str): filename of the file containing the full-order model solution data
Returns:
np.ndarray
: The corresponding solution time stamps in a 1- or 2-dimensional array. The optional 2nd dimension is only needed if the reduced projected full-order solution array is 3-dimensional; the 2nd dimension contains the time stamps of the other states in the time-stencil for a given time stamp.
121 def evaluate_full_residuals( 122 self, 123 run_directory: str, 124 full_model_directory: str, 125 reduced_states: np.ndarray, 126 parameter_sample: dict, 127 times: np.ndarray, 128 ) -> np.ndarray: 129 ''' 130 Evaluate the full-order model residuals corresponding to full states reconstructed from 131 an array of reduced states 132 133 Args: 134 run_directory (str): Absolute path to directory in which residual is being computed. 135 full_model_directory (str): Absolute path to directory in which the full model data was computed. 136 reduced_state (np.ndarray): 2- or 3-dimensional reduced state vector. 1st dimension: reduced state, 137 2nd dimension: time, 3rd dimension: other states in time stencil. If the array is 2-dimensional, it 138 is assumed that the states are sequential in time. 139 parameter_sample: Dictionary contatining parameter names and sample values 140 times (np.ndarray): 1-dimensional or 2-dimesional vector of time stamps. The optional 141 2nd dimension is only needed if the reduced state array is 3-dimensional; the 2nd dimension 142 contains the time stamps of the other states in the time-stencil for a given time stamp. 143 144 Returns: 145 `np.ndarray`: The full-order residual in tensor form, should be 3-dimensional, even for a single time step 146 ''' 147 pass
Evaluate the full-order model residuals corresponding to full states reconstructed from an array of reduced states
Arguments:
- run_directory (str): Absolute path to directory in which residual is being computed.
- full_model_directory (str): Absolute path to directory in which the full model data was computed.
- reduced_state (np.ndarray): 2- or 3-dimensional reduced state vector. 1st dimension: reduced state,
- 2nd dimension: time, 3rd dimension: other states in time stencil. If the array is 2-dimensional, it
- is assumed that the states are sequential in time.
- parameter_sample: Dictionary contatining parameter names and sample values
- times (np.ndarray): 1-dimensional or 2-dimesional vector of time stamps. The optional
- 2nd dimension is only needed if the reduced state array is 3-dimensional; the 2nd dimension
- contains the time stamps of the other states in the time-stencil for a given time stamp.
Returns:
np.ndarray
: The full-order residual in tensor form, should be 3-dimensional, even for a single time step
149 def evaluate_full_residuals_and_jacobian_basis_products( 150 self, 151 run_directory: str, 152 full_model_directory: str, 153 reduced_states: np.ndarray, 154 parameter_sample: dict, 155 times: np.ndarray, 156 ) -> Tuple[np.ndarray, np.ndarray]: 157 ''' 158 Evaluate the full-order model residuals corresponding to full states reconstructed from 159 an array of reduced states 160 161 Args: 162 run_directory (str): Absolute path to directory in which residual is being computed. 163 full_model_directory (str): Absolute path to directory in which the full model data was computed. 164 reduced_state (np.ndarray): 2- or 3-dimensional reduced state vector. 1st dimension: reduced state, 165 2nd dimension: time, 3rd dimension: other states in time stencil. If the array is 2-dimensional, it 166 is assumed that the states are sequential in time. 167 parameter_sample: Dictionary contatining parameter names and sample values 168 times (np.ndarray): 1-dimensional or 2-dimesional vector of time stamps. The optional 169 2nd dimension is only needed if the reduced state array is 3-dimensional; the 2nd dimension 170 contains the time stamps of the other states in the time-stencil for a given time stamp. 171 172 Returns: 173 `np.ndarray`: The full-order residual in tensor form, should be 3-dimensional, even for a single time step. 174 `np.ndarray`: The full-order jacobian-basis product in tensor form, should be 4-dimensional, even for a single sample 175 1st dimension: sample index, 2nd dimension: variable index, 3rd dimension: spatial index, 4th dimension: modal index 176 ''' 177 pass
Evaluate the full-order model residuals corresponding to full states reconstructed from an array of reduced states
Arguments:
- run_directory (str): Absolute path to directory in which residual is being computed.
- full_model_directory (str): Absolute path to directory in which the full model data was computed.
- reduced_state (np.ndarray): 2- or 3-dimensional reduced state vector. 1st dimension: reduced state,
- 2nd dimension: time, 3rd dimension: other states in time stencil. If the array is 2-dimensional, it
- is assumed that the states are sequential in time.
- parameter_sample: Dictionary contatining parameter names and sample values
- times (np.ndarray): 1-dimensional or 2-dimesional vector of time stamps. The optional
- 2nd dimension is only needed if the reduced state array is 3-dimensional; the 2nd dimension
- contains the time stamps of the other states in the time-stencil for a given time stamp.
Returns:
np.ndarray
: The full-order residual in tensor form, should be 3-dimensional, even for a single time step.np.ndarray
: The full-order jacobian-basis product in tensor form, should be 4-dimensional, even for a single sample 1st dimension: sample index, 2nd dimension: variable index, 3rd dimension: spatial index, 4th dimension: modal index
180def evaluate_and_load_steady_residual_snapshots( 181 residual_evaluator: ResidualEvaluator, 182 full_state_directories: Iterable[str], 183 state_filename: str, 184 absolute_run_directory: str, 185) -> np.ndarray: 186 ''' 187 Core algorithm that takes a residual_evaluator, a list of steady full-order model 188 snapshot directories, and a snapshot_filename, and computes the corresponding 189 residual snapshots. 190 191 Args: 192 residual_evaluator (ResidualEvaluator): steady residual evaluator we wish to use 193 full_state_directories (list[str]): list of directories containing full state data 194 state_filename (str): filename or base filename of file containing state data 195 absolute_run_directory (str): absolute path to base directory in which residuals are evaluated 196 197 Returns: 198 `np.ndarray`: The full-order residual snapshots in tensor form. 199 ''' 200 201 run_directory_base = f"{absolute_run_directory}/res_" 202 203 all_residual_snapshots = [] 204 n_vars = -1 205 n_x = -1 206 for index, full_model_dir in enumerate(full_state_directories): 207 # Read and project FOM snapshot 208 reduced_state = residual_evaluator.compute_reduced_states( 209 full_model_dir + "/" + state_filename 210 ) 211 212 # Set up corresponding directory 213 run_directory = f"{run_directory_base}{index}" 214 create_empty_dir(run_directory) 215 216 # Evaluate residual 217 residual_snapshot = residual_evaluator.evaluate_full_residuals( 218 run_directory, full_model_dir, reduced_state, None 219 ) 220 221 # check residual snapshot size and shape 222 if n_vars == -1 and n_x == -1: 223 n_vars = residual_snapshot.shape[0] 224 n_x = residual_snapshot.shape[1] 225 assert residual_snapshot.shape[0] == n_vars 226 assert residual_snapshot.shape[1] == n_x 227 228 all_residual_snapshots.append(residual_snapshot) 229 230 # convert list to array 231 # does it kill memory usage to do this? 232 return np.concatenate(all_residual_snapshots, axis=2)
Core algorithm that takes a residual_evaluator, a list of steady full-order model snapshot directories, and a snapshot_filename, and computes the corresponding residual snapshots.
Arguments:
- residual_evaluator (ResidualEvaluator): steady residual evaluator we wish to use
- full_state_directories (list[str]): list of directories containing full state data
- state_filename (str): filename or base filename of file containing state data
- absolute_run_directory (str): absolute path to base directory in which residuals are evaluated
Returns:
np.ndarray
: The full-order residual snapshots in tensor form.
235def evaluate_and_load_steady_residual_and_jacobian_snapshots( 236 residual_evaluator: ResidualEvaluator, 237 full_state_directories: Iterable[str], 238 state_filename: str, 239 absolute_run_directory: str, 240) -> Tuple[np.ndarray, np.ndarray]: 241 ''' 242 Core algorithm that takes a residual_evaluator, a list of steady full-order model 243 snapshot directories, and a snapshot_filename, and computes the corresponding 244 residual and Jacobian-basis product snapshots. 245 246 Args: 247 residual_evaluator (ResidualEvaluator): steady residual evaluator we wish to use 248 full_state_directories (list[str]): list of directories containing full state data 249 state_filename (str): filename or base filename of file containing state data 250 absolute_run_directory (str): absolute path to base directory in which residuals are evaluated 251 252 Returns: 253 `np.ndarray`: The full-order residual snapshots in tensor form. 254 `np.ndarray`: The full-order Jacobian-basis product snapshots in tensor form. 255 ''' 256 257 run_directory_base = f"{absolute_run_directory}/res_" 258 259 all_residual_snapshots = [] 260 all_jacobian_snapshots = [] 261 n_vars = -1 262 n_x = -1 263 n_modes = -1 264 for index, full_model_dir in enumerate(full_state_directories): 265 # Read and project FOM snapshot 266 reduced_state = residual_evaluator.compute_reduced_states( 267 full_model_dir + "/" + state_filename 268 ) 269 270 # Set up corresponding directory 271 run_directory = f"{run_directory_base}{index}" 272 create_empty_dir(run_directory) 273 274 # Evaluate residual 275 residual_snapshot, jacobian_snapshot = ( 276 residual_evaluator.evaluate_full_residuals_and_jacobian_basis_products( 277 run_directory, full_model_dir, reduced_state, None 278 ) 279 ) 280 281 # check residual snapshot size and shape 282 if n_vars == -1 and n_x == -1: 283 n_vars = residual_snapshot.shape[0] 284 n_x = residual_snapshot.shape[1] 285 assert residual_snapshot.shape[0] == n_vars 286 assert residual_snapshot.shape[1] == n_x 287 288 # check Jacobian-basis product snapshot size and shape 289 if n_modes == -1: 290 n_modes = jacobian_snapshot.shape[3] 291 assert jacobian_snapshot.shape[1] == n_vars 292 assert jacobian_snapshot.shape[2] == n_x 293 294 all_residual_snapshots.append(residual_snapshot) 295 all_jacobian_snapshots.append(jacobian_snapshot) 296 297 # convert list to array 298 # does it kill memory usage to do this? 299 return np.concatenate(all_residual_snapshots, axis=2), np.concatenate( 300 all_jacobian_snapshots, axis=0 301 )
Core algorithm that takes a residual_evaluator, a list of steady full-order model snapshot directories, and a snapshot_filename, and computes the corresponding residual and Jacobian-basis product snapshots.
Arguments:
- residual_evaluator (ResidualEvaluator): steady residual evaluator we wish to use
- full_state_directories (list[str]): list of directories containing full state data
- state_filename (str): filename or base filename of file containing state data
- absolute_run_directory (str): absolute path to base directory in which residuals are evaluated
Returns:
np.ndarray
: The full-order residual snapshots in tensor form.np.ndarray
: The full-order Jacobian-basis product snapshots in tensor form.
304def evaluate_and_load_unsteady_residual_snapshots( 305 residual_evaluator: TransientResidualEvaluator, 306 full_state_directories: Iterable[str], 307 state_filename: str, 308 absolute_run_directory: str, 309) -> np.ndarray: 310 ''' 311 Core algorithm that takes a residual_evaluator, a list of unsteady full-order model 312 snapshot directories, and a snapshot_filename, and computes the corresponding 313 residual snapshots. 314 315 Args: 316 residual_evaluator (TransientResidualEvaluator): transient residual evaluator we wish to use 317 full_state_directories (list[str]): list of directories containing full state data 318 state_filename (str): filename or base filename of file containing state data 319 absolute_run_directory (str): absolute path to base directory in which residuals are evaluated 320 321 Returns: 322 `np.ndarray`: The full-order residual snapshots in tensor form. 323 324 ''' 325 326 run_directory_base = f"{absolute_run_directory}/res_" 327 328 all_residual_snapshots = [] 329 n_vars = -1 330 n_x = -1 331 for index, full_model_dir in enumerate(full_state_directories): 332 # Read and project FOM snapshots 333 reduced_states = residual_evaluator.compute_reduced_states( 334 full_model_dir + "/" + state_filename 335 ) 336 times = residual_evaluator.get_times(full_model_dir + "/" + state_filename) 337 338 # Set up corresponding directory 339 run_directory = f"{run_directory_base}{index}" 340 create_empty_dir(run_directory) 341 342 # Evaluate residuals 343 residual_snapshots = residual_evaluator.evaluate_full_residuals( 344 run_directory, full_model_dir, reduced_states, None, times 345 ) 346 347 # check residual snapshot size and shape 348 assert residual_snapshots.ndim == 3 349 if n_vars == -1 and n_x == -1: 350 n_vars = residual_snapshots.shape[0] 351 n_x = residual_snapshots.shape[1] 352 assert residual_snapshots.shape[0] == n_vars 353 assert residual_snapshots.shape[1] == n_x 354 355 all_residual_snapshots.append(residual_snapshots) 356 357 # convert list to array 358 # does it kill memory usage to do this? 359 return np.concatenate(all_residual_snapshots, axis=2)
Core algorithm that takes a residual_evaluator, a list of unsteady full-order model snapshot directories, and a snapshot_filename, and computes the corresponding residual snapshots.
Arguments:
- residual_evaluator (TransientResidualEvaluator): transient residual evaluator we wish to use
- full_state_directories (list[str]): list of directories containing full state data
- state_filename (str): filename or base filename of file containing state data
- absolute_run_directory (str): absolute path to base directory in which residuals are evaluated
Returns:
np.ndarray
: The full-order residual snapshots in tensor form.
362def evaluate_and_load_unsteady_residual_and_jacobian_snapshots( 363 residual_evaluator: TransientResidualEvaluator, 364 full_state_directories: Iterable[str], 365 state_filename: str, 366 absolute_run_directory: str, 367) -> Tuple[np.ndarray, np.ndarray]: 368 ''' 369 Core algorithm that takes a residual_evaluator, a list of unsteady full-order model 370 snapshot directories, and a snapshot_filename, and computes the corresponding 371 residual snapshots. 372 373 Args: 374 residual_evaluator (TransientResidualEvaluator): transient residual evaluator we wish to use 375 full_state_directories (list[str]): list of directories containing full state data 376 state_filename (str): filename or base filename of file containing state data 377 absolute_run_directory (str): absolute path to base directory in which residuals are evaluated 378 379 Returns: 380 `np.ndarray`: The full-order residual snapshots in tensor form. 381 `np.ndarray`: The full-order Jacobian-basis product snapshots in tensor form. 382 ''' 383 384 run_directory_base = f"{absolute_run_directory}/res_" 385 386 all_residual_snapshots = [] 387 all_jacobian_snapshots = [] 388 n_vars = -1 389 n_x = -1 390 n_modes = -1 391 for index, full_model_dir in enumerate(full_state_directories): 392 # Read and project FOM snapshots 393 reduced_states = residual_evaluator.compute_reduced_states( 394 full_model_dir + "/" + state_filename 395 ) 396 times = residual_evaluator.get_times(full_model_dir + "/" + state_filename) 397 398 # Set up corresponding directory 399 run_directory = f"{run_directory_base}{index}" 400 create_empty_dir(run_directory) 401 402 # Evaluate residuals 403 residual_snapshots, jacobian_snapshots = ( 404 residual_evaluator.evaluate_full_residuals_and_jacobian_basis_products( 405 run_directory, full_model_dir, reduced_states, None, times 406 ) 407 ) 408 409 # check residual snapshot size and shape 410 assert residual_snapshots.ndim == 3 411 if n_vars == -1 and n_x == -1: 412 n_vars = residual_snapshots.shape[0] 413 n_x = residual_snapshots.shape[1] 414 assert residual_snapshots.shape[0] == n_vars 415 assert residual_snapshots.shape[1] == n_x 416 417 # check residual snapshot size and shape 418 assert jacobian_snapshots.ndim == 4 419 if n_modes == -1: 420 n_modes = jacobian_snapshots.shape[3] 421 assert jacobian_snapshots.shape[1] == n_vars 422 assert jacobian_snapshots.shape[2] == n_x 423 assert jacobian_snapshots.shape[3] == n_modes 424 425 all_residual_snapshots.append(residual_snapshots) 426 all_jacobian_snapshots.append(jacobian_snapshots) 427 428 # convert list to array 429 # does it kill memory usage to do this? 430 return np.concatenate(all_residual_snapshots, axis=2), np.concatenate( 431 all_jacobian_snapshots, axis=0 432 )
Core algorithm that takes a residual_evaluator, a list of unsteady full-order model snapshot directories, and a snapshot_filename, and computes the corresponding residual snapshots.
Arguments:
- residual_evaluator (TransientResidualEvaluator): transient residual evaluator we wish to use
- full_state_directories (list[str]): list of directories containing full state data
- state_filename (str): filename or base filename of file containing state data
- absolute_run_directory (str): absolute path to base directory in which residuals are evaluated
Returns:
np.ndarray
: The full-order residual snapshots in tensor form.np.ndarray
: The full-order Jacobian-basis product snapshots in tensor form.