Peano
Loading...
Searching...
No Matches
Quantities.py
Go to the documentation of this file.
1# This file is part of the ExaHyPE2 project. For conditions of distribution and
2# use, please see the copyright notice at www.peano-framework.org
3from typing import List, Union
4
5
6def resolve_quantities(
7 solver,
8 quantities: List[Union[str, int]],
9 include_auxiliary_variables: bool = False,
10) -> List[int]:
11 """!
12
13 Translate names and indices of the entries of Q into sorted indices
14
15 @param solver: exahype2.api.Solver
16 The solver whose entries of Q we refer to.
17
18 @param quantities: List[str or int]
19 A string is the name of a variable as passed to the solver (e.g.
20 "lapse" or "G" for exagrype.api.CCZ4Solver) and selects all of its
21 entries. An int is the index of one entry of Q. The list must not be
22 empty.
23
24 @param include_auxiliary_variables: bool
25 If False, only the unknowns can be selected. Otherwise, the auxiliary
26 variables can be selected, too.
27
28 @return List[int]
29 Sorted indices without duplicates.
30
31 """
32 entries = solver.unknowns + (
33 solver.auxiliary_variables if include_auxiliary_variables else 0
34 )
35 if len(quantities) == 0:
36 raise ValueError(f"Solver {solver.name}: the list of quantities is empty")
37 names = solver.variable_names_per_entry()[:entries]
38 indices = set()
39 for quantity in quantities:
40 if isinstance(quantity, bool) or not isinstance(quantity, (int, str)):
41 raise TypeError(
42 f"Solver {solver.name}: quantities have to be names (str) or "
43 f"indices (int) of entries of Q, but got {quantity!r}"
44 )
45 if isinstance(quantity, int):
46 if not 0 <= quantity < entries:
47 raise ValueError(
48 f"Solver {solver.name}: quantity index {quantity} is out of "
49 f"range, as only {entries} entries can be selected"
50 )
51 indices.add(quantity)
52 else:
53 matches = [
54 index
55 for index, name in enumerate(names)
56 if name == quantity or name.startswith(quantity + "[")
57 ]
58 if not matches:
59 raise ValueError(
60 f"Solver {solver.name}: {quantity!r} is not the name of a "
61 f"variable which can be selected. Available names are "
62 f"{sorted(set(name.split('[')[0] for name in names))}."
63 )
64 indices.update(matches)
65 return sorted(indices)