PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
 
Loading...
Searching...
No Matches
Functions | Variables
audit_field_catalog Namespace Reference

Functions

dict compiled_eulerian ()
 Canonical name to layout for every compiled Eulerian catalog entry.
 
set compiled_particle ()
 Canonical names of every compiled particle catalog entry.
 
set compiled_layouts ()
 Layout vocabulary the header defines.
 
str page_section (str heading)
 One @section body from the catalog page.
 
tuple documented_eulerian (str section)
 Field-to-layout mapping the inventory section publishes.
 
set documented_particle (str section)
 Particle field names the inventory section publishes.
 
set documented_layouts ()
 Layout vocabulary the layout section tabulates.
 
int main ()
 Fail when the published catalog inventory and the compiled catalog disagree.
 

Variables

 REPO_ROOT = Path(__file__).resolve().parents[2]
 
str EULERIAN_CATALOG = REPO_ROOT / "src" / "field_catalog.c"
 
str PARTICLE_CATALOG = REPO_ROOT / "src" / "particle_field_catalog.c"
 
str LAYOUT_HEADER = REPO_ROOT / "include" / "field_catalog.h"
 
str PAGE = REPO_ROOT / "docs" / "pages" / "56_Field_Identity_and_Layout_Catalog.md"
 
dict GROUP_LAYOUTS
 
 ENTRY_RE
 
 PARTICLE_ENTRY_RE = re.compile(r'PARTICLE_FIELD_ENTRY\(\s*PARTICLE_FIELD_ID_\w+\s*,\s*"([^"]+)"')
 
 LAYOUT_ENUM_RE = re.compile(r"^\s*(FIELD_LAYOUT_\w+)", re.M)
 
 BACKTICKED_RE = re.compile(r"`([A-Za-z_][A-Za-z0-9_]*)`")
 

Detailed Description

Enforce that the documented field catalog matches the compiled one.

Function Documentation

◆ compiled_eulerian()

dict audit_field_catalog.compiled_eulerian ( )

Canonical name to layout for every compiled Eulerian catalog entry.

Returns
Mapping of field name to FIELD_LAYOUT_* value.

Definition at line 37 of file audit_field_catalog.py.

37def compiled_eulerian() -> dict:
38 """!
39 @brief Canonical name to layout for every compiled Eulerian catalog entry.
40 @return Mapping of field name to `FIELD_LAYOUT_*` value.
41 """
42 return dict(ENTRY_RE.findall(EULERIAN_CATALOG.read_text(encoding="utf-8")))
43
44
Here is the caller graph for this function:

◆ compiled_particle()

set audit_field_catalog.compiled_particle ( )

Canonical names of every compiled particle catalog entry.

Returns
Set of particle field names.

Definition at line 45 of file audit_field_catalog.py.

45def compiled_particle() -> set:
46 """!
47 @brief Canonical names of every compiled particle catalog entry.
48 @return Set of particle field names.
49 """
50 return set(PARTICLE_ENTRY_RE.findall(PARTICLE_CATALOG.read_text(encoding="utf-8")))
51
52
Here is the caller graph for this function:

◆ compiled_layouts()

set audit_field_catalog.compiled_layouts ( )

Layout vocabulary the header defines.

Returns
Set of FIELD_LAYOUT_* enumerators.

Definition at line 53 of file audit_field_catalog.py.

53def compiled_layouts() -> set:
54 """!
55 @brief Layout vocabulary the header defines.
56 @return Set of `FIELD_LAYOUT_*` enumerators.
57 """
58 text = LAYOUT_HEADER.read_text(encoding="utf-8")
59 body = text[text.index("FIELD_LAYOUT_NODE_CENTERED"):]
60 return set(LAYOUT_ENUM_RE.findall(body[: body.index("} FieldLayout;")]))
61
62
Here is the caller graph for this function:

◆ page_section()

str audit_field_catalog.page_section ( str  heading)

One @section body from the catalog page.

Parameters
[in]headingSection id to extract.
Returns
Section text up to the next section.

Definition at line 63 of file audit_field_catalog.py.

63def page_section(heading: str) -> str:
64 """!
65 @brief One `@section` body from the catalog page.
66 @param[in] heading Section id to extract.
67 @return Section text up to the next section.
68 """
69 text = PAGE.read_text(encoding="utf-8")
70 start = text.index(heading)
71 following = text.find("@section", start + len(heading))
72 return text[start: following if following != -1 else len(text)]
73
74
Here is the caller graph for this function:

◆ documented_eulerian()

tuple audit_field_catalog.documented_eulerian ( str  section)

Field-to-layout mapping the inventory section publishes.

Parameters
[in]sectionInventory section body.
Returns
Tuple of the mapping and any structural problems found.

Definition at line 75 of file audit_field_catalog.py.

75def documented_eulerian(section: str) -> tuple:
76 """!
77 @brief Field-to-layout mapping the inventory section publishes.
78 @param[in] section Inventory section body.
79 @return Tuple of the mapping and any structural problems found.
80 """
81 problems: list = []
82 block = re.search(r"((?:^- .*(?:\n(?!\n)(?!- ).*)*\n)+)", section, re.M)
83 if not block:
84 return {}, ["section 6 no longer contains a layout-grouped list"]
85 documented: dict = {}
86 for item in re.findall(r"^- (.*?)(?=^- |\Z)", block.group(1), re.S | re.M):
87 label, _, body = item.partition(":")
88 layout = GROUP_LAYOUTS.get(label.strip())
89 if layout is None:
90 problems.append(f"section 6 lists an unrecognized layout group '{label.strip()}'")
91 continue
92 for name in BACKTICKED_RE.findall(body):
93 documented[name] = layout
94 return documented, problems
95
96
Here is the caller graph for this function:

◆ documented_particle()

set audit_field_catalog.documented_particle ( str  section)

Particle field names the inventory section publishes.

Parameters
[in]sectionInventory section body.
Returns
Set of documented particle field names.

Definition at line 97 of file audit_field_catalog.py.

97def documented_particle(section: str) -> set:
98 """!
99 @brief Particle field names the inventory section publishes.
100 @param[in] section Inventory section body.
101 @return Set of documented particle field names.
102 """
103 match = re.search(r"The particle inventory is:(.*?)\.\s", section, re.S)
104 return set(BACKTICKED_RE.findall(match.group(1))) if match else set()
105
106
Here is the caller graph for this function:

◆ documented_layouts()

set audit_field_catalog.documented_layouts ( )

Layout vocabulary the layout section tabulates.

Returns
Set of documented FIELD_LAYOUT_* enumerators.

Definition at line 107 of file audit_field_catalog.py.

107def documented_layouts() -> set:
108 """!
109 @brief Layout vocabulary the layout section tabulates.
110 @return Set of documented `FIELD_LAYOUT_*` enumerators.
111 """
112 section = page_section("@section p56_layout_sec")
113 return set(re.findall(r"\|\s*`(FIELD_LAYOUT_\w+)`\s*\|", section))
114
115
Here is the call graph for this function:
Here is the caller graph for this function:

◆ main()

int audit_field_catalog.main ( )

Fail when the published catalog inventory and the compiled catalog disagree.

Checks identity sets, layout assignment, and layout vocabulary. It does not check degrees of freedom, DM family, synchronization class, availability, capability flags, or whether the runtime actually allocates a field.

Returns
Process status code.

Definition at line 116 of file audit_field_catalog.py.

116def main() -> int:
117 """!
118 @brief Fail when the published catalog inventory and the compiled catalog disagree.
119
120 @details Checks identity sets, layout assignment, and layout vocabulary. It does not
121 check degrees of freedom, DM family, synchronization class, availability,
122 capability flags, or whether the runtime actually allocates a field.
123 @return Process status code.
124 """
125 code = compiled_eulerian()
126 section = page_section("@section p56_inventory_sec")
127 documented, problems = documented_eulerian(section)
128
129 for name in sorted(set(code) - set(documented)):
130 problems.append(f"{name}: in the compiled catalog, absent from section 6")
131 for name in sorted(set(documented) - set(code)):
132 problems.append(f"{name}: listed in section 6, absent from the compiled catalog")
133 for name in sorted(set(code) & set(documented)):
134 if code[name] != documented[name]:
135 problems.append(
136 f"{name}: compiled as {code[name]}, documented under {documented[name]}"
137 )
138
139 header_layouts, page_layouts = compiled_layouts(), documented_layouts()
140 for layout in sorted(header_layouts - page_layouts):
141 problems.append(f"{layout}: defined in the header, absent from the section 4 table")
142 for layout in sorted(page_layouts - header_layouts):
143 problems.append(f"{layout}: tabulated in section 4, absent from the header")
144
145 particles_code, particles_page = compiled_particle(), documented_particle(section)
146 for name in sorted(particles_code - particles_page):
147 problems.append(f"{name}: in the compiled particle catalog, absent from section 6")
148 for name in sorted(particles_page - particles_code):
149 problems.append(f"{name}: listed as a particle field, absent from the compiled catalog")
150
151 if problems:
152 print("Field catalog documentation does not match the compiled catalog:", file=sys.stderr)
153 for problem in problems:
154 print(f" {problem}", file=sys.stderr)
155 print(
156 "\nUpdate docs/pages/56_Field_Identity_and_Layout_Catalog.md section 6 to match\n"
157 "src/field_catalog.c and src/particle_field_catalog.c. The compiled catalog is\n"
158 "authoritative; the page is the published record of it.",
159 file=sys.stderr,
160 )
161 return 1
162
163 print(
164 f"Field catalog audit passed: {len(code)} Eulerian and {len(particles_code)} particle "
165 f"identities, {len(header_layouts)} layouts. Degrees of freedom, DM family, "
166 "synchronization class, availability, capabilities, and runtime allocation are "
167 "not checked."
168 )
169 return 0
170
171
int main(int argc, char **argv)
Entry point for the postprocessor executable.
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ REPO_ROOT

audit_field_catalog.REPO_ROOT = Path(__file__).resolve().parents[2]

Definition at line 11 of file audit_field_catalog.py.

◆ EULERIAN_CATALOG

str audit_field_catalog.EULERIAN_CATALOG = REPO_ROOT / "src" / "field_catalog.c"

Definition at line 12 of file audit_field_catalog.py.

◆ PARTICLE_CATALOG

str audit_field_catalog.PARTICLE_CATALOG = REPO_ROOT / "src" / "particle_field_catalog.c"

Definition at line 13 of file audit_field_catalog.py.

◆ LAYOUT_HEADER

str audit_field_catalog.LAYOUT_HEADER = REPO_ROOT / "include" / "field_catalog.h"

Definition at line 14 of file audit_field_catalog.py.

◆ PAGE

str audit_field_catalog.PAGE = REPO_ROOT / "docs" / "pages" / "56_Field_Identity_and_Layout_Catalog.md"

Definition at line 15 of file audit_field_catalog.py.

◆ GROUP_LAYOUTS

dict audit_field_catalog.GROUP_LAYOUTS
Initial value:
1= {
2 "node-centered": "FIELD_LAYOUT_NODE_CENTERED",
3 "shifted cell-centered": "FIELD_LAYOUT_CELL_CENTERED",
4 "component-staggered": "FIELD_LAYOUT_COMPONENT_STAGGERED",
5 "I-face family": "FIELD_LAYOUT_I_FACE",
6 "J-face family": "FIELD_LAYOUT_J_FACE",
7 "K-face family": "FIELD_LAYOUT_K_FACE",
8}

Definition at line 18 of file audit_field_catalog.py.

◆ ENTRY_RE

audit_field_catalog.ENTRY_RE
Initial value:
1= re.compile(
2 r'FIELD_(?:COORDINATE_)?ENTRY\‍(\s*FIELD_ID_\w+\s*,\s*"([^"]+)"'
3 r'[^)]*?(FIELD_LAYOUT_\w+)',
4 re.S,
5)

Definition at line 27 of file audit_field_catalog.py.

◆ PARTICLE_ENTRY_RE

audit_field_catalog.PARTICLE_ENTRY_RE = re.compile(r'PARTICLE_FIELD_ENTRY\(\s*PARTICLE_FIELD_ID_\w+\s*,\s*"([^"]+)"')

Definition at line 32 of file audit_field_catalog.py.

◆ LAYOUT_ENUM_RE

audit_field_catalog.LAYOUT_ENUM_RE = re.compile(r"^\s*(FIELD_LAYOUT_\w+)", re.M)

Definition at line 33 of file audit_field_catalog.py.

◆ BACKTICKED_RE

audit_field_catalog.BACKTICKED_RE = re.compile(r"`([A-Za-z_][A-Za-z0-9_]*)`")

Definition at line 34 of file audit_field_catalog.py.