Skip to content

Commit a86aa2e

Browse files
authored
Add python tools documentation to sphinx (#1991)
* Adding python autodocs to sphinx, fixing docstring errors * Adding type hints for python tools * Modernizing python setup configurations * Adding hdf5_wrapper unit tests
1 parent 720e7d0 commit a86aa2e

39 files changed

+921
-427
lines changed

geosx_mesh_tools_package/geosx_mesh_tools/abaqus_converter.py

Lines changed: 29 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
1-
import meshio
2-
from meshio._mesh import CellBlock
1+
import meshio # type: ignore[import]
2+
from meshio._mesh import CellBlock # type: ignore[import]
33
import numpy as np
4-
import argparse
54
import logging
6-
import sys
75

86

9-
def convert_abaqus_to_gmsh(input_mesh, output_mesh, logger=None):
7+
def convert_abaqus_to_gmsh(input_mesh: str, output_mesh: str, logger: logging.Logger = None) -> int:
108
"""
11-
@brief Convert an abaqus mesh to gmsh 2 format, preserving nodeset information.
12-
@details If the code encounters any issues with region/element indices,
13-
the conversion will attempt to continue, with errors
14-
indicated by -1 values in the output file.
15-
@param input_mesh path of the input abaqus file
16-
@param output_mesh path of the output gmsh file
17-
@param logger an instance of logging.Logger
9+
Convert an abaqus mesh to gmsh 2 format, preserving nodeset information.
10+
11+
If the code encounters any issues with region/element indices,
12+
the conversion will attempt to continue, with errors
13+
indicated by -1 values in the output file.
14+
15+
Args:
16+
input_mesh (str): path of the input abaqus file
17+
output_mesh (str): path of the output gmsh file
18+
logger (logging.Logger): an instance of logging.Logger
19+
20+
Returns:
21+
int: Number of potential warnings encountered during conversion
1822
"""
1923
# Initialize the logger if it is empty
2024
if not logger:
@@ -123,15 +127,20 @@ def convert_abaqus_to_gmsh(input_mesh, output_mesh, logger=None):
123127
return (n_warnings > 0)
124128

125129

126-
def convert_abaqus_to_vtu(input_mesh, output_mesh, logger=None):
130+
def convert_abaqus_to_vtu(input_mesh: str, output_mesh: str, logger: logging.Logger = None) -> int:
127131
"""
128-
@brief Convert an abaqus mesh to vtu format, preserving nodeset information.
129-
@details If the code encounters any issues with region/element indices,
130-
the conversion will attempt to continue, with errors
131-
indicated by -1 values in the output file.
132-
@param input_mesh path of the input abaqus file
133-
@param output_mesh path of the output vtu file
134-
@param logger an instance of logging.Logger
132+
Convert an abaqus mesh to vtu format, preserving nodeset information.
133+
134+
If the code encounters any issues with region/element indices, the conversion will
135+
attempt to continue, with errors indicated by -1 values in the output file.
136+
137+
Args:
138+
input_mesh (str): path of the input abaqus file
139+
output_mesh (str): path of the output vtu file
140+
logger (logging.Logger): a logger instance
141+
142+
Returns:
143+
int: Number of potential warnings encountered during conversion
135144
"""
136145
# Initialize the logger if it is empty
137146
if not logger:
@@ -159,33 +168,3 @@ def convert_abaqus_to_vtu(input_mesh, output_mesh, logger=None):
159168
logger.info('Done!')
160169

161170
return (n_warnings > 0)
162-
163-
164-
def main():
165-
"""
166-
@brief Entry point for the abaqus convertor console script
167-
@arg input_mesh Input abaqus file name
168-
@arg output_mesh Output gmsh or vtu file name
169-
"""
170-
171-
# Parse the user arguments
172-
parser = argparse.ArgumentParser()
173-
parser.add_argument('input', type=str, help='Input abaqus mesh file name')
174-
parser.add_argument('output', type=str, help='Output gmsh mesh file name')
175-
parser.add_argument('-v', '--verbose', help='Increase verbosity level', action="store_true")
176-
args = parser.parse_args()
177-
178-
# Set up a logger
179-
logging.basicConfig(level=logging.WARNING)
180-
logger = logging.getLogger(__name__)
181-
if args.verbose:
182-
logger.setLevel(logging.INFO)
183-
184-
# Call the converter
185-
err = 0
186-
if ('.msh' in args.output):
187-
err = convert_abaqus_to_gmsh(args.input, args.output, logger)
188-
else:
189-
err = convert_abaqus_to_vtu(args.input, args.output, logger)
190-
if err:
191-
sys.exit('Warnings detected: check the output file for potential errors!')
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import argparse
2+
import logging
3+
import sys
4+
5+
6+
def build_abaqus_converter_input_parser() -> argparse.ArgumentParser:
7+
"""Build the input argument parser
8+
9+
Returns:
10+
argparse.ArgumentParser: a parser instance
11+
"""
12+
parser = argparse.ArgumentParser()
13+
parser.add_argument('input', type=str, help='Input abaqus mesh file name')
14+
parser.add_argument('output', type=str, help='Output gmsh/vtu mesh file name')
15+
parser.add_argument('-v', '--verbose', help='Increase verbosity level', action="store_true")
16+
return parser
17+
18+
19+
def main() -> None:
20+
"""
21+
Entry point for the abaqus convertor console script
22+
23+
Args:
24+
input (str): Input abaqus mesh file name
25+
output (str): Output mesh file name
26+
-v/--verbose (flag): Increase verbosity level
27+
"""
28+
from geosx_mesh_tools import abaqus_converter
29+
30+
# Parse the user arguments
31+
parser = build_abaqus_converter_input_parser()
32+
args = parser.parse_args()
33+
34+
# Set up a logger
35+
logging.basicConfig(level=logging.WARNING)
36+
logger = logging.getLogger(__name__)
37+
if args.verbose:
38+
logger.setLevel(logging.INFO)
39+
40+
# Call the converter
41+
err = 0
42+
if ('.msh' in args.output):
43+
err = abaqus_converter.convert_abaqus_to_gmsh(args.input, args.output, logger)
44+
else:
45+
err = abaqus_converter.convert_abaqus_to_vtu(args.input, args.output, logger)
46+
if err:
47+
sys.exit('Warnings detected: check the output file for potential errors!')
48+
49+
50+
if __name__ == '__main__':
51+
main()

geosx_mesh_tools_package/geosx_mesh_tools/py.typed

Whitespace-only changes.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[build-system]
2+
requires = ["setuptools>=42", "wheel"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[tool.mypy]
6+
python_version = "3.8"
7+
warn_return_any = true
8+
warn_unused_configs = true

geosx_mesh_tools_package/setup.cfg

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[metadata]
2+
name = geosx_mesh_tools
3+
version = 0.2.0
4+
description = Tools for managing meshes in GEOSX
5+
author = Christopher Sherman
6+
author_email = [email protected]
7+
license = LGPL-2.1
8+
9+
[options]
10+
packages =
11+
geosx_mesh_tools
12+
install_requires =
13+
meshio>=5.3.2
14+
numpy
15+
python_requires = >=3.6
16+
17+
[options.package_data]
18+
geosx_mesh_tools = py.typed
19+
20+
[options.entry_points]
21+
console_scripts =
22+
convert_abaqus = geosx_mesh_tools.main:main

geosx_mesh_tools_package/setup.py

Lines changed: 0 additions & 10 deletions
This file was deleted.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
"""@package geosx_xml_tools
1+
"""
22
A python module that enables advanced xml features for GEOSX.
33
"""

geosx_xml_tools_package/geosx_xml_tools/attribute_coverage.py

Lines changed: 55 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,34 @@
1-
from lxml import etree as ElementTree
1+
from lxml import etree as ElementTree # type: ignore[import]
22
import os
33
from pathlib import Path
4-
import argparse
4+
from typing import Any, Iterable, Dict
5+
from geosx_xml_tools import command_line_parsers
56

7+
record_type = Dict[str, Dict[str, Any]]
68

7-
def parse_schema_element(root,
8-
node,
9-
xsd='{http://www.w3.org/2001/XMLSchema}',
10-
recursive_types=['PeriodicEvent', 'SoloEvent', 'HaltEvent'],
11-
folders=['src', 'examples']):
9+
10+
def parse_schema_element(root: ElementTree.Element,
11+
node: ElementTree.Element,
12+
xsd: str = '{http://www.w3.org/2001/XMLSchema}',
13+
recursive_types: Iterable[str] = ['PeriodicEvent', 'SoloEvent', 'HaltEvent'],
14+
folders: Iterable[str] = ['src', 'examples']) -> record_type:
1215
"""Parse the xml schema at the current level
1316
14-
@arg root the root schema node
15-
@arg node current schema node
16-
@arg xsd the file namespace
17-
@arg recursive_types node tags that allow recursive nesting
18-
@arg folders folders to sort xml attribute usage into
17+
Args:
18+
root (lxml.etree.Element): the root schema node
19+
node (lxml.etree.Element): current schema node
20+
xsd (str): the file namespace
21+
recursive_types (list): node tags that allow recursive nesting
22+
folders (list): folders to sort xml attribute usage into
23+
24+
Returns:
25+
dict: Dictionary of attributes and children for the current node
1926
"""
2027

2128
element_type = node.get('type')
2229
element_name = node.get('name')
2330
element_def = root.find("%scomplexType[@name='%s']" % (xsd, element_type))
24-
local_types = {'attributes': {}, 'children': {}}
31+
local_types: record_type = {'attributes': {}, 'children': {}}
2532

2633
# Parse attributes
2734
for attribute in element_def.findall('%sattribute' % (xsd)):
@@ -41,23 +48,28 @@ def parse_schema_element(root,
4148
return local_types
4249

4350

44-
def parse_schema(fname):
51+
def parse_schema(fname: str) -> record_type:
4552
"""Parse the schema file into the xml attribute usage dict
4653
47-
@arg fname schema name
54+
Args:
55+
fname (str): schema name
56+
57+
Returns:
58+
dict: Dictionary of attributes and children for the entire schema
4859
"""
4960
xml_tree = ElementTree.parse(fname)
5061
xml_root = xml_tree.getroot()
5162
problem_node = xml_root.find("{http://www.w3.org/2001/XMLSchema}element")
5263
return {'Problem': parse_schema_element(xml_root, problem_node)}
5364

5465

55-
def collect_xml_attributes_level(local_types, node, folder):
66+
def collect_xml_attributes_level(local_types: record_type, node: ElementTree.Element, folder: str) -> None:
5667
"""Collect xml attribute usage at the current level
5768
58-
@arg local_types dict containing attribute usage
59-
@arg node current xml node
60-
@arg folder the source folder for the current file
69+
Args:
70+
local_types (dict): dictionary containing attribute usage
71+
node (lxml.etree.Element): current xml node
72+
folder (str): the source folder for the current file
6173
"""
6274
for ka in node.attrib.keys():
6375
local_types['attributes'][ka][folder].append(node.get(ka))
@@ -67,12 +79,13 @@ def collect_xml_attributes_level(local_types, node, folder):
6779
collect_xml_attributes_level(local_types['children'][child.tag], child, folder)
6880

6981

70-
def collect_xml_attributes(xml_types, fname, folder):
82+
def collect_xml_attributes(xml_types: record_type, fname: str, folder: str) -> None:
7183
"""Collect xml attribute usage in a file
7284
73-
@arg xml_types dict containing attribute usage
74-
@arg fname name of the target file
75-
@arg folder the source folder for the current file
85+
Args:
86+
xml_types (dict): dictionary containing attribute usage
87+
fname (str): name of the target file
88+
folder (str): the source folder for the current file
7689
"""
7790
parser = ElementTree.XMLParser(remove_comments=True, remove_blank_text=True)
7891
xml_tree = ElementTree.parse(fname, parser=parser)
@@ -81,11 +94,14 @@ def collect_xml_attributes(xml_types, fname, folder):
8194
collect_xml_attributes_level(xml_types['Problem'], xml_root, folder)
8295

8396

84-
def write_attribute_usage_xml_level(local_types, node, folders=['src', 'examples']):
97+
def write_attribute_usage_xml_level(local_types: record_type,
98+
node: ElementTree.Element,
99+
folders: Iterable[str] = ['src', 'examples']) -> None:
85100
"""Write xml attribute usage file at a given level
86101
87-
@arg local_types dict containing attribute usage at the current level
88-
@arg node current xml node
102+
Args:
103+
local_types (dict): dict containing attribute usage at the current level
104+
node (lxml.etree.Element): current xml node
89105
"""
90106

91107
# Write attributes
@@ -112,11 +128,12 @@ def write_attribute_usage_xml_level(local_types, node, folders=['src', 'examples
112128
write_attribute_usage_xml_level(local_types['children'][ka], child)
113129

114130

115-
def write_attribute_usage_xml(xml_types, fname):
131+
def write_attribute_usage_xml(xml_types: record_type, fname: str) -> None:
116132
"""Write xml attribute usage file
117133
118-
@arg xml_types dict containing attribute usage by xml type
119-
@arg fname output file name
134+
Args:
135+
xml_types (dict): dictionary containing attribute usage by xml type
136+
fname (str): output file name
120137
"""
121138
xml_root = ElementTree.Element('Problem')
122139
xml_tree = ElementTree.ElementTree(xml_root)
@@ -125,11 +142,12 @@ def write_attribute_usage_xml(xml_types, fname):
125142
xml_tree.write(fname, pretty_print=True)
126143

127144

128-
def process_xml_files(geosx_root, output_name):
145+
def process_xml_files(geosx_root: str, output_name: str) -> None:
129146
"""Test for xml attribute usage
130147
131-
@arg geosx_root GEOSX root directory
132-
@arg output_name output file name
148+
Args:
149+
geosx_root (str): GEOSX root directory
150+
output_name (str): output file name
133151
"""
134152

135153
# Parse the schema
@@ -149,17 +167,16 @@ def process_xml_files(geosx_root, output_name):
149167
write_attribute_usage_xml(xml_types, output_name)
150168

151169

152-
def main():
170+
def main() -> None:
153171
"""Entry point for the xml attribute usage test script
154172
155-
@arg -r/--root GEOSX root directory
156-
@arg -o/--output output file name
173+
Args:
174+
-r/--root (str): GEOSX root directory
175+
-o/--output (str): output file name
157176
"""
158177

159178
# Parse the user arguments
160-
parser = argparse.ArgumentParser()
161-
parser.add_argument('-r', '--root', type=str, help='GEOSX root', default='')
162-
parser.add_argument('-o', '--output', type=str, help='Output file name', default='attribute_test.xml')
179+
parser = command_line_parsers.build_attribute_coverage_input_parser()
163180
args = parser.parse_args()
164181

165182
# Parse the xml files

0 commit comments

Comments
 (0)