diff --git a/build_docs.py b/build_docs.py new file mode 100644 index 0000000..d319132 --- /dev/null +++ b/build_docs.py @@ -0,0 +1,475 @@ +#!/usr/bin/env python3 +import os +import re +import ast +import shutil + +class FortranParser: + """A robust line-by-line state-machine parser for Fortran free-form source files. + Correctly resolves line continuations (`&`) and extracts Doxygen/FORD-style comments. + """ + def __init__(self): + # Match MODULE name (excluding MODULE PROCEDURE) + self.module_re = re.compile(r'^\s*module\s+(\w+)\s*$', re.IGNORECASE) + # Match SUBROUTINE name + self.subroutine_re = re.compile(r'^\s*(?:recursive\s+|mpich\s+)?subroutine\s+(\w+)\s*(?:\(([^)]*)\))?', re.IGNORECASE) + # Match FUNCTION name + self.function_re = re.compile( + r'^\s*(?:recursive\s+)?(?:real|integer|double\s+precision|logical|character|complex)?(?:\([\w*=]+\))?\s*function\s+(\w+)\s*(?:\(([^)]*)\))?', + re.IGNORECASE + ) + + def parse_file(self, filepath): + with open(filepath, 'r', encoding='utf-8') as f: + raw_lines = f.readlines() + + # Resolve line continuations using & + lines = [] + current_line = "" + for line in raw_lines: + trimmed = line.strip() + # If the entire line is a comment, keep it as is + if trimmed.startswith('!'): + lines.append((line.rstrip('\r\n'), True)) + continue + + # Partition the line by '!' to separate code and inline comments + code_part = "" + in_string = False + str_char = None + for i, char in enumerate(line): + if char in ("'", '"'): + if not in_string: + in_string = True + str_char = char + elif str_char == char: + in_string = False + elif char == '!' and not in_string: + code_part = line[:i] + break + else: + code_part = line + + code_trimmed = code_part.strip() + if code_trimmed.endswith('&'): + current_line += code_trimmed[:-1].strip() + " " + else: + if current_line: + lines.append((current_line + code_trimmed, False)) + current_line = "" + else: + lines.append((line.rstrip('\r\n'), False)) + + # Parse resolved lines + elements = [] + current_comments = [] + module_doc = "" + in_module = False + + for line_str, is_cmt in lines: + trimmed = line_str.strip() + if is_cmt or trimmed.startswith('!'): + if trimmed.startswith('!>') or trimmed.startswith('!!'): + cleaned_comment = trimmed[2:].strip() + current_comments.append(cleaned_comment) + continue + + if not trimmed: + if not in_module and not elements and current_comments: + module_doc = "\n".join(current_comments) + current_comments = [] + continue + + m_mod = self.module_re.match(trimmed) + m_sub = self.subroutine_re.match(trimmed) + m_func = self.function_re.match(trimmed) + + if m_mod: + in_module = True + mod_name = m_mod.group(1) + elements.append({ + 'type': 'module', + 'name': mod_name, + 'doc': "\n".join(current_comments) if current_comments else "" + }) + current_comments = [] + elif m_sub: + sub_name = m_sub.group(1) + args_str = m_sub.group(2) or "" + args = [a.strip() for a in args_str.split(',') if a.strip()] + elements.append({ + 'type': 'subroutine', + 'name': sub_name, + 'args': args, + 'doc': "\n".join(current_comments) if current_comments else "" + }) + current_comments = [] + elif m_func: + func_name = m_func.group(1) + args_str = m_func.group(2) or "" + args = [a.strip() for a in args_str.split(',') if a.strip()] + elements.append({ + 'type': 'function', + 'name': func_name, + 'args': args, + 'doc': "\n".join(current_comments) if current_comments else "" + }) + current_comments = [] + else: + # Clear comment buffer if normal statement is met + current_comments = [] + + return { + 'doc': module_doc, + 'elements': elements + } + + +class PythonASTParser: + """Uses Python standard library `ast` module to safely parse classes, methods, + decorators, functions, and Google-style docstrings from Python modules. + """ + def get_node_name(self, node): + if hasattr(ast, 'unparse'): + return ast.unparse(node).strip() + if isinstance(node, ast.Name): + return node.id + elif isinstance(node, ast.Attribute): + return f"{self.get_node_name(node.value)}.{node.attr}" + elif isinstance(node, ast.Call): + return f"{self.get_node_name(node.func)}(...)" + return str(node) + + def parse_file(self, filepath): + with open(filepath, 'r', encoding='utf-8') as f: + content = f.read() + try: + tree = ast.parse(content) + except SyntaxError as e: + print(f"Syntax error parsing {filepath}: {e}") + return None + + module_doc = ast.get_docstring(tree) or "" + elements = [] + + for node in ast.iter_child_nodes(tree): + if isinstance(node, ast.ClassDef): + class_doc = ast.get_docstring(node) or "" + methods = [] + for child in ast.iter_child_nodes(node): + if isinstance(child, ast.FunctionDef): + method_doc = ast.get_docstring(child) or "" + args = [a.arg for a in child.args.args] + decorators = [self.get_node_name(d) for d in child.decorator_list] + methods.append({ + 'name': child.name, + 'args': args, + 'doc': method_doc, + 'decorators': decorators + }) + elements.append({ + 'type': 'class', + 'name': node.name, + 'bases': [self.get_node_name(b) for b in node.bases], + 'doc': class_doc, + 'methods': methods + }) + elif isinstance(node, ast.FunctionDef): + func_doc = ast.get_docstring(node) or "" + args = [a.arg for a in node.args.args] + decorators = [self.get_node_name(d) for d in node.decorator_list] + elements.append({ + 'type': 'function', + 'name': node.name, + 'args': args, + 'doc': func_doc, + 'decorators': decorators + }) + return { + 'doc': module_doc, + 'elements': elements + } + + +def format_docstring(doc): + """Formats raw docstrings/comments into clean Markdown.""" + if not doc: + return "*No description provided.*" + + # Process Google Style or Doxygen tags into neat markdown sections + lines = doc.split('\n') + formatted_lines = [] + in_args = False + in_returns = False + + for line in lines: + trimmed = line.strip() + + # Google style section headers + if trimmed == 'Args:': + formatted_lines.append("\n**Arguments:**\n") + in_args = True + in_returns = False + continue + elif trimmed == 'Returns:': + formatted_lines.append("\n**Returns:**\n") + in_args = False + in_returns = True + continue + elif trimmed in ('Raises:', 'Attributes:'): + formatted_lines.append(f"\n**{trimmed[:-1]}:**\n") + in_args = in_returns = False + continue + + # Parse params inside arguments or return + if in_args and trimmed: + # Format "arg_name (type): description" + match = re.match(r'^([\w_]+)\s*(?:\(([^)]+)\))?\s*:\s*(.*)$', trimmed) + if match: + name, arg_type, desc = match.groups() + type_str = f" *({arg_type})*" if arg_type else "" + formatted_lines.append(f"- ` {name} `{type_str}: {desc}") + continue + + # Parse Doxygen tags + if trimmed.startswith('@param'): + match = re.match(r'^@param\s+([\w_]+)\s*(.*)$', trimmed) + if match: + name, desc = match.groups() + formatted_lines.append(f"- ` {name} `: {desc}") + continue + elif trimmed.startswith('@return'): + desc = trimmed.replace('@return', '').strip() + formatted_lines.append(f"\n**Returns:**\n\n{desc}") + continue + elif trimmed.startswith('@note'): + desc = trimmed.replace('@note', '').strip() + formatted_lines.append(f"\n> [!NOTE]\n> {desc}") + continue + elif trimmed.startswith('@author'): + desc = trimmed.replace('@author', '').strip() + formatted_lines.append(f"\n*Author: {desc}*") + continue + + formatted_lines.append(line) + + return "\n".join(formatted_lines).strip() + + +def build_all_docs(): + workspace_dir = os.path.dirname(os.path.abspath(__file__)) + code_dir = os.path.join(workspace_dir, "code") + docs_dir = os.path.join(workspace_dir, "docs") + + # Recreate the docs directory + if os.path.exists(docs_dir): + shutil.rmtree(docs_dir) + os.makedirs(docs_dir, exist_ok=True) + + fortran_parser = FortranParser() + py_parser = PythonASTParser() + + # Files to parse + fortran_files = [ + "Compact.f90", + "m_arrays.f90", + "m_calculate.f90", + "m_openmpi.f90", + "m_parameters.f90", + "post.f90", + "post_dns.f90" + ] + + python_files = [ + ("code_gen.py", "code/code_gen/code_gen.py"), + ("post.py", "code/code_gen/post.py"), + ("pycompact.py", "code/pycompact/pycompact.py") + ] + + all_modules = [] + + # 1. Parse Fortran files + for fname in fortran_files: + path = os.path.join(code_dir, fname) + if not os.path.exists(path): + continue + + print(f"Parsing Fortran file: {fname}") + res = fortran_parser.parse_file(path) + if not res: + continue + + all_modules.append({ + 'name': fname, + 'lang': 'fortran', + 'data': res + }) + + # 2. Parse Python files + for key_name, rel_path in python_files: + path = os.path.join(workspace_dir, rel_path) + if not os.path.exists(path): + continue + + print(f"Parsing Python file: {key_name}") + res = py_parser.parse_file(path) + if not res: + continue + + all_modules.append({ + 'name': key_name, + 'lang': 'python', + 'data': res + }) + + # 3. Generate Markdown files + for mod in all_modules: + mname = mod['name'] + lang = mod['lang'] + data = mod['data'] + + md_filename = mname.replace('.f90', '.md').replace('.py', '.md') + md_path = os.path.join(docs_dir, md_filename) + + with open(md_path, 'w', encoding='utf-8') as md_file: + # Header banner + badge = "Fortran Source" if lang == 'fortran' else "Python Source" + badge_color = "blue" if lang == 'fortran' else "green" + + md_file.write(f"# {mname}\n\n") + md_file.write(f"![Language](https://img.shields.io/badge/Language-{badge}-{badge_color}?style=for-the-badge)\n\n") + + # Smart Overview Fallback + overview_doc = data['doc'].strip() + if not overview_doc: + for elem in data['elements']: + if elem['type'] == 'module' and elem.get('doc'): + overview_doc = elem['doc'].strip() + break + else: + for elem in data['elements']: + if elem.get('doc'): + overview_doc = elem['doc'].strip() + break + + md_file.write("## Overview\n\n") + md_file.write(format_docstring(overview_doc) + "\n\n") + + # Table of Contents + md_file.write("## API Index\n\n") + has_elements = False + for elem in data['elements']: + has_elements = True + elem_type = elem['type'].capitalize() + md_file.write(f"- [{elem_type}: `{elem['name']}`](#{elem['name'].lower()})\n") + if not has_elements: + md_file.write("*No direct class or function definitions extracted from this file.*\n") + md_file.write("\n---\n\n") + + # API Reference details + md_file.write("## API Reference\n\n") + for elem in data['elements']: + el_name = elem['name'] + el_type = elem['type'] + el_doc = format_docstring(elem.get('doc', '')) + + # Format headers depending on type + if el_type == 'module': + md_file.write(f"### [Module] `{el_name}`\n\n") + md_file.write(el_doc + "\n\n") + elif el_type == 'class': + bases_str = f"({', '.join(elem['bases'])})" if elem['bases'] else "" + md_file.write(f"### [Class] `{el_name}{bases_str}`\n\n") + md_file.write(el_doc + "\n\n") + + if elem['methods']: + md_file.write("#### Methods\n\n") + for method in elem['methods']: + m_args = ", ".join(method['args']) + decs = "".join([f"`@{d}`
" for d in method['decorators']]) + md_file.write(f"##### `{method['name']}({m_args})`\n\n") + if decs: + md_file.write(f"**Decorators:** {decs}\n\n") + md_file.write(format_docstring(method['doc']) + "\n\n") + elif el_type in ('subroutine', 'function'): + args_str = ", ".join(elem['args']) + decs = "".join([f"`@{d}`
" for d in elem.get('decorators', [])]) + elem_badge = "Subroutine" if el_type == 'subroutine' else "Function" + + md_file.write(f"### [{elem_badge}] `{el_name}`\n\n") + md_file.write("```fortran\n" if lang == 'fortran' else "```python\n") + md_file.write(f"{el_type} {el_name}({args_str})\n") + md_file.write("```\n\n") + + if decs: + md_file.write(f"**Decorators:** {decs}\n\n") + + md_file.write(el_doc + "\n\n") + + md_file.write("---\n\n") + + # 4. Generate master README.md index + readme_path = os.path.join(docs_dir, "README.md") + with open(readme_path, 'w', encoding='utf-8') as ri: + ri.write("# HPC DNS Post-Processing Reference Manual\n\n") + ri.write("> [!NOTE]\n") + ri.write("> This reference documentation is automatically generated from codebase comments and AST analysis using the literal programming compiler.\n\n") + + ri.write("## Project Architecture Overview\n\n") + ri.write("This suite compiles algebraic DSL budget equations, performs high-order compact finite difference calculus, and exports physical terms via MPI-IO. Below is the primary software module pipeline:\n\n") + + # Include a Mermaid architecture diagram + ri.write("```mermaid\n") + ri.write("graph TD\n") + ri.write(" A[code_gen.py / DSL Input] -->|AST Compiler Pipeline| B[post.py / Code Gen]\n") + ri.write(" B -->|Generates budget kernels| C[m_calculate.f90]\n") + ri.write(" C -->|LU Tridiagonal Solvers| D[Compact.f90]\n") + ri.write(" C -->|Array allocations| E[m_arrays.f90]\n") + ri.write(" F[post.f90 / Main Driver] -->|Orchestrates calculations| C\n") + ri.write(" F -->|Parallelizes domain| G[m_openmpi.f90]\n") + ri.write(" F -->|Loads run configuration| H[m_parameters.f90]\n") + ri.write(" I[pycompact.py / Bindings] -->|Wraps CPU calculations| C\n") + ri.write("```\n\n") + + ri.write("## Reference Files Index\n\n") + ri.write("| Document / Code Module | Language | Description | \n") + ri.write("| --- | --- | --- |\n") + + for mod in all_modules: + mname = mod['name'] + lang_label = "Fortran 90" if mod['lang'] == 'fortran' else "Python" + doc_link = mname.replace('.f90', '.md').replace('.py', '.md') + + # Smart summary from first line of doc + overview_doc = mod['data']['doc'].strip() + if not overview_doc: + for elem in mod['data']['elements']: + if elem['type'] == 'module' and elem.get('doc'): + overview_doc = elem['doc'].strip() + break + else: + for elem in mod['data']['elements']: + if elem.get('doc'): + overview_doc = elem['doc'].strip() + break + + doc_lines = overview_doc.split('\n') + brief = doc_lines[0] if doc_lines and doc_lines[0] else "*No overview description provided.*" + brief = brief.replace('@brief', '').replace('@author', '').strip() + if brief.startswith('Google') or brief.startswith('Ignis'): + for line in doc_lines: + line_clean = line.replace('@brief', '').replace('@author', '').strip() + if line_clean and not line.strip().startswith('@'): + brief = line_clean + break + + ri.write(f"| [{mname}]({doc_link}) | **{lang_label}** | {brief} |\n") + + ri.write("\n---\n") + ri.write("*Generated dynamically by `build_docs.py`.*") + + print(f"\nDocumentation built successfully under {docs_dir}!") + + +if __name__ == "__main__": + build_all_docs() diff --git a/code/Compact.f90 b/code/Compact.f90 index 3eec03d..b62f844 100644 --- a/code/Compact.f90 +++ b/code/Compact.f90 @@ -1,3 +1,9 @@ + !> @author Ignis + !> @brief High-order compact finite difference scheme solver. + !! + !! This module handles the generation of tridiagonal/pentadiagonal matrices, + !! LU decomposition calculations, and tridiagonal solver operations for periodic + !! and non-periodic boundary conditions. MODULE Compact use, intrinsic :: iso_fortran_env, only: real64 IMPLICIT NONE @@ -12,6 +18,16 @@ CONTAINS + !> Entry point for LU decomposition calculations. + !! + !! Prepares the workspace allocations and runs the decomposition calculation for all three directions. + !! + !! @param nx Grid size in x-direction. + !! @param ny Grid size in y-direction. + !! @param nz Grid size in z-direction. + !! @param xp Periodic flag for x-direction (0 = periodic, other = non-periodic). + !! @param yp Periodic flag for y-direction (0 = periodic, other = non-periodic). + !! @param zp Periodic flag for z-direction (0 = periodic, other = non-periodic). SUBROUTINE ludcmp(nx,ny,nz,xp,yp,zp) INTEGER, INTENT(IN) :: nx,ny,nz INTEGER, INTENT(IN) :: xp,yp,zp diff --git a/code/code_gen/code_gen.py b/code/code_gen/code_gen.py index 680741a..d46f0dd 100644 --- a/code/code_gen/code_gen.py +++ b/code/code_gen/code_gen.py @@ -136,6 +136,17 @@ class VersionInfo(object): def test(terms_raw, report=False, latex=False): + """Compiles the post-processing term specifications from DSL into targets. + + This compiles the Lark AST through all 4 pipeline stages (Stage 1 to 4) + and outputs the resulting Fortran source code via Jinja2, a LaTeX equation + dictionary, or a code generation IR report. + + Args: + terms_raw (str): The raw string contents of the DSL terms specification input file. + report (bool): If True, generates and saves the intermediate code generation report. + latex (bool): If True, prints LaTeX equations of the averaged terms to stdout. + """ parser = Lark(calc_grammar, parser='lalr', @@ -176,6 +187,11 @@ def test(terms_raw, report=False, latex=False): def build_info(terms_raw): + """Generates and prints build information for the current code generation run. + + Args: + terms_raw (str): The raw string contents of the DSL terms specification input file. + """ vinfo = VersionInfo(terms_raw) diff --git a/code/m_calculate.f90 b/code/m_calculate.f90 index 791959e..ebae9e7 100644 --- a/code/m_calculate.f90 +++ b/code/m_calculate.f90 @@ -1,3 +1,9 @@ +!> @author Google DeepMind Team & Ignis +!> @brief DNS post-processing mathematical operations and derivatives. +!! +!! This module calculates spatial derivatives (first and second derivatives in X, Y, Z directions) +!! using high-order compact finite difference schemes. It also calculates chemical reaction rates, +!! positive/negative component extraction, and threshold operations. module m_calculate use, intrinsic :: iso_fortran_env, only: real64 @@ -19,6 +25,10 @@ module m_calculate contains + !> Initializes the workspace arrays and matrices. + !! + !! Pre-allocates transposed workspace buffers (`xsrc`, `xdst`, `rsrc`, `rdst`) + !! and performs the LU decomposition setup via `ludcmp` for the tridiagonal compact schemes. subroutine m_calculate_init integer :: ierr @@ -76,7 +86,11 @@ contains end subroutine ddx1d - subroutine ddx(dst, src) + !> Computes the first-order derivative in the X-direction. + !! + !! @param src 3D input scalar field (nxp, nyp, nzp). + !! @param dst 3D output derivative field (nxp, nyp, nzp). + subroutine ddx(dst, src) real*8, dimension(nxp,nyp,nzp), intent(in) :: src real*8, dimension(nxp,nyp,nzp), intent(out) :: dst @@ -102,7 +116,11 @@ contains end subroutine ddx - subroutine ddy(dst, src) + !> Computes the first-order derivative in the Y-direction. + !! + !! @param src 3D input scalar field (nxp, nyp, nzp). + !! @param dst 3D output derivative field (nxp, nyp, nzp). + subroutine ddy(dst, src) real*8, dimension(nxp,nyp,nzp), intent(in) :: src real*8, dimension(nxp,nyp,nzp), intent(out) :: dst @@ -119,7 +137,11 @@ contains end subroutine ddy - subroutine ddz(dst, src) + !> Computes the first-order derivative in the Z-direction. + !! + !! @param src 3D input scalar field (nxp, nyp, nzp). + !! @param dst 3D output derivative field (nxp, nyp, nzp). + subroutine ddz(dst, src) real*8, dimension(nxp,nyp,nzp), intent(in) :: src real*8, dimension(nxp,nyp,nzp), intent(out) :: dst @@ -259,6 +281,13 @@ contains end subroutine tp2 + !> Computes the chemical reaction rate based on the progress variable c. + !! + !! This uses a piecewise exponential/Arrhenius model depending on whether the progress variable + !! is below c_cut, above c_ref, or intermediate. + !! + !! @param c The progress variable (0.0 to 1.0). + !! @return The computed reaction rate. real(real64) function rxn_rate (c) real(real64) :: c diff --git a/docs/Compact.md b/docs/Compact.md new file mode 100644 index 0000000..112e3d9 --- /dev/null +++ b/docs/Compact.md @@ -0,0 +1,261 @@ +# Compact.f90 + +![Language](https://img.shields.io/badge/Language-Fortran Source-blue?style=for-the-badge) + +## Overview + +*Author: Ignis* +@brief High-order compact finite difference scheme solver. + +This module handles the generation of tridiagonal/pentadiagonal matrices, +LU decomposition calculations, and tridiagonal solver operations for periodic +and non-periodic boundary conditions. + +## API Index + +- [Module: `Compact`](#compact) +- [Subroutine: `ludcmp`](#ludcmp) +- [Subroutine: `ludcmp_allocate`](#ludcmp_allocate) +- [Subroutine: `ludcmp_deallocate`](#ludcmp_deallocate) +- [Subroutine: `ludcmp_testalloc`](#ludcmp_testalloc) +- [Subroutine: `ludcmp_calculate`](#ludcmp_calculate) +- [Subroutine: `test_nonp_lud1`](#test_nonp_lud1) +- [Subroutine: `test_nonp_lud2`](#test_nonp_lud2) +- [Subroutine: `test_p_lud1`](#test_p_lud1) +- [Subroutine: `test_p_lud2`](#test_p_lud2) +- [Subroutine: `nonp_lud`](#nonp_lud) +- [Subroutine: `p_lud`](#p_lud) +- [Subroutine: `stdlu`](#stdlu) +- [Subroutine: `ptdlu`](#ptdlu) +- [Subroutine: `rhs1np`](#rhs1np) +- [Subroutine: `dfnonp`](#dfnonp) +- [Subroutine: `dfp`](#dfp) +- [Subroutine: `ptdslv`](#ptdslv) +- [Subroutine: `d2fp`](#d2fp) +- [Subroutine: `tdslv`](#tdslv) +- [Subroutine: `d2fnonp`](#d2fnonp) + +--- + +## API Reference + +### [Module] `Compact` + +*Author: Ignis* +@brief High-order compact finite difference scheme solver. + +This module handles the generation of tridiagonal/pentadiagonal matrices, +LU decomposition calculations, and tridiagonal solver operations for periodic +and non-periodic boundary conditions. + +--- + +### [Subroutine] `ludcmp` + +```fortran +subroutine ludcmp(nx, ny, nz, xp, yp, zp) +``` + +Entry point for LU decomposition calculations. + +Prepares the workspace allocations and runs the decomposition calculation for all three directions. + +- ` nx `: Grid size in x-direction. +- ` ny `: Grid size in y-direction. +- ` nz `: Grid size in z-direction. +- ` xp `: Periodic flag for x-direction (0 = periodic, other = non-periodic). +- ` yp `: Periodic flag for y-direction (0 = periodic, other = non-periodic). +- ` zp `: Periodic flag for z-direction (0 = periodic, other = non-periodic). + +--- + +### [Subroutine] `ludcmp_allocate` + +```fortran +subroutine ludcmp_allocate(nx, ny, nz, xp, yp, zp) +``` + +*No description provided.* + +--- + +### [Subroutine] `ludcmp_deallocate` + +```fortran +subroutine ludcmp_deallocate(xp, yp, zp) +``` + +*No description provided.* + +--- + +### [Subroutine] `ludcmp_testalloc` + +```fortran +subroutine ludcmp_testalloc() +``` + +*No description provided.* + +--- + +### [Subroutine] `ludcmp_calculate` + +```fortran +subroutine ludcmp_calculate(nx, ny, nz, xp, yp, zp) +``` + +*No description provided.* + +--- + +### [Subroutine] `test_nonp_lud1` + +```fortran +subroutine test_nonp_lud1(xx, coef) +``` + +*No description provided.* + +--- + +### [Subroutine] `test_nonp_lud2` + +```fortran +subroutine test_nonp_lud2(xx, coef) +``` + +*No description provided.* + +--- + +### [Subroutine] `test_p_lud1` + +```fortran +subroutine test_p_lud1(xx, coef1, coef2) +``` + +*No description provided.* + +--- + +### [Subroutine] `test_p_lud2` + +```fortran +subroutine test_p_lud2(xx, coef1, coef2) +``` + +*No description provided.* + +--- + +### [Subroutine] `nonp_lud` + +```fortran +subroutine nonp_lud(xyz, xx) +``` + +*No description provided.* + +--- + +### [Subroutine] `p_lud` + +```fortran +subroutine p_lud(xyz, xx) +``` + +*No description provided.* + +--- + +### [Subroutine] `stdlu` + +```fortran +subroutine stdlu(a, n, l) +``` + +*No description provided.* + +--- + +### [Subroutine] `ptdlu` + +```fortran +subroutine ptdlu(a, n, l, w) +``` + +*No description provided.* + +--- + +### [Subroutine] `rhs1np` + +```fortran +subroutine rhs1np(n, h, x, dx, nd) +``` + +*No description provided.* + +--- + +### [Subroutine] `dfnonp` + +```fortran +subroutine dfnonp(n, h, x, dx, nd, dir) +``` + +*No description provided.* + +--- + +### [Subroutine] `dfp` + +```fortran +subroutine dfp(n, h, x, dx, nd, dir) +``` + +*No description provided.* + +--- + +### [Subroutine] `ptdslv` + +```fortran +subroutine ptdslv(r, n, l, w, nd) +``` + +*No description provided.* + +--- + +### [Subroutine] `d2fp` + +```fortran +subroutine d2fp(n, h, x, dx, nd, dir) +``` + +*No description provided.* + +--- + +### [Subroutine] `tdslv` + +```fortran +subroutine tdslv(r, n, l, nd) +``` + +*No description provided.* + +--- + +### [Subroutine] `d2fnonp` + +```fortran +subroutine d2fnonp(n, h, x, dx, nd, dir) +``` + +*No description provided.* + +--- + diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..05e8fb5 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,38 @@ +# HPC DNS Post-Processing Reference Manual + +> [!NOTE] +> This reference documentation is automatically generated from codebase comments and AST analysis using the literal programming compiler. + +## Project Architecture Overview + +This suite compiles algebraic DSL budget equations, performs high-order compact finite difference calculus, and exports physical terms via MPI-IO. Below is the primary software module pipeline: + +```mermaid +graph TD + A[code_gen.py / DSL Input] -->|AST Compiler Pipeline| B[post.py / Code Gen] + B -->|Generates budget kernels| C[m_calculate.f90] + C -->|LU Tridiagonal Solvers| D[Compact.f90] + C -->|Array allocations| E[m_arrays.f90] + F[post.f90 / Main Driver] -->|Orchestrates calculations| C + F -->|Parallelizes domain| G[m_openmpi.f90] + F -->|Loads run configuration| H[m_parameters.f90] + I[pycompact.py / Bindings] -->|Wraps CPU calculations| C +``` + +## Reference Files Index + +| Document / Code Module | Language | Description | +| --- | --- | --- | +| [Compact.f90](Compact.md) | **Fortran 90** | This module handles the generation of tridiagonal/pentadiagonal matrices, | +| [m_arrays.f90](m_arrays.md) | **Fortran 90** | *No overview description provided.* | +| [m_calculate.f90](m_calculate.md) | **Fortran 90** | This module calculates spatial derivatives (first and second derivatives in X, Y, Z directions) | +| [m_openmpi.f90](m_openmpi.md) | **Fortran 90** | *No overview description provided.* | +| [m_parameters.f90](m_parameters.md) | **Fortran 90** | *No overview description provided.* | +| [post.f90](post.md) | **Fortran 90** | *No overview description provided.* | +| [post_dns.f90](post_dns.md) | **Fortran 90** | *No overview description provided.* | +| [code_gen.py](code_gen.md) | **Python** | Convert the value of `tok` from string to bool, while maintaining line number & column. | +| [post.py](post.md) | **Python** | conversion from tree to python data | +| [pycompact.py](pycompact.md) | **Python** | *No overview description provided.* | + +--- +*Generated dynamically by `build_docs.py`.* \ No newline at end of file diff --git a/docs/code_gen.md b/docs/code_gen.md new file mode 100644 index 0000000..6482047 --- /dev/null +++ b/docs/code_gen.md @@ -0,0 +1,103 @@ +# code_gen.py + +![Language](https://img.shields.io/badge/Language-Python Source-green?style=for-the-badge) + +## Overview + +Convert the value of `tok` from string to bool, while maintaining line number & column. + +## API Index + +- [Function: `tok_to_bool`](#tok_to_bool) +- [Function: `tok_to_int`](#tok_to_int) +- [Function: `tok_to_str`](#tok_to_str) +- [Class: `VersionInfo`](#versioninfo) +- [Function: `test`](#test) +- [Function: `build_info`](#build_info) + +--- + +## API Reference + +### [Function] `tok_to_bool` + +```python +function tok_to_bool(tok) +``` + +Convert the value of `tok` from string to bool, while maintaining line number & column. + +--- + +### [Function] `tok_to_int` + +```python +function tok_to_int(tok) +``` + +Convert the value of `tok` from string to int, while maintaining line number & column. + +--- + +### [Function] `tok_to_str` + +```python +function tok_to_str(tok) +``` + +Convert the value of `tok` from string to string, while maintaining line number & column. + +--- + +### [Class] `VersionInfo(object)` + +*No description provided.* + +#### Methods + +##### `__init__(self, input_raw)` + +*No description provided.* + +##### `fparams(self)` + +*No description provided.* + +--- + +### [Function] `test` + +```python +function test(terms_raw, report, latex) +``` + +Compiles the post-processing term specifications from DSL into targets. + +This compiles the Lark AST through all 4 pipeline stages (Stage 1 to 4) +and outputs the resulting Fortran source code via Jinja2, a LaTeX equation +dictionary, or a code generation IR report. + + +**Arguments:** + +- ` terms_raw ` *(str)*: The raw string contents of the DSL terms specification input file. +- ` report ` *(bool)*: If True, generates and saves the intermediate code generation report. +- ` latex ` *(bool)*: If True, prints LaTeX equations of the averaged terms to stdout. + +--- + +### [Function] `build_info` + +```python +function build_info(terms_raw) +``` + +Generates and prints build information for the current code generation run. + + +**Arguments:** + +- ` terms_raw ` *(str)*: The raw string contents of the DSL terms specification input file. + +--- + diff --git a/docs/m_arrays.md b/docs/m_arrays.md new file mode 100644 index 0000000..59856cd --- /dev/null +++ b/docs/m_arrays.md @@ -0,0 +1,55 @@ +# m_arrays.f90 + +![Language](https://img.shields.io/badge/Language-Fortran Source-blue?style=for-the-badge) + +## Overview + +*No description provided.* + +## API Index + +- [Module: `m_arrays`](#m_arrays) +- [Subroutine: `m_arrays_init`](#m_arrays_init) +- [Subroutine: `m_arrays_finalize`](#m_arrays_finalize) +- [Subroutine: `m_arrays_calculate_instant`](#m_arrays_calculate_instant) + +--- + +## API Reference + +### [Module] `m_arrays` + +*No description provided.* + +--- + +### [Subroutine] `m_arrays_init` + +```fortran +subroutine m_arrays_init() +``` + +*No description provided.* + +--- + +### [Subroutine] `m_arrays_finalize` + +```fortran +subroutine m_arrays_finalize() +``` + +*No description provided.* + +--- + +### [Subroutine] `m_arrays_calculate_instant` + +```fortran +subroutine m_arrays_calculate_instant() +``` + +*No description provided.* + +--- + diff --git a/docs/m_calculate.md b/docs/m_calculate.md new file mode 100644 index 0000000..06c772d --- /dev/null +++ b/docs/m_calculate.md @@ -0,0 +1,229 @@ +# m_calculate.f90 + +![Language](https://img.shields.io/badge/Language-Fortran Source-blue?style=for-the-badge) + +## Overview + +*Author: Google DeepMind Team & Ignis* +@brief DNS post-processing mathematical operations and derivatives. + +This module calculates spatial derivatives (first and second derivatives in X, Y, Z directions) +using high-order compact finite difference schemes. It also calculates chemical reaction rates, +positive/negative component extraction, and threshold operations. + +## API Index + +- [Module: `m_calculate`](#m_calculate) +- [Subroutine: `m_calculate_init`](#m_calculate_init) +- [Subroutine: `m_calculate_finalize`](#m_calculate_finalize) +- [Subroutine: `ddx1d`](#ddx1d) +- [Subroutine: `ddx`](#ddx) +- [Subroutine: `ddy`](#ddy) +- [Subroutine: `ddz`](#ddz) +- [Subroutine: `d2dx1d`](#d2dx1d) +- [Subroutine: `d2dx`](#d2dx) +- [Subroutine: `d2dy`](#d2dy) +- [Subroutine: `d2dz`](#d2dz) +- [Subroutine: `tp`](#tp) +- [Subroutine: `tp2`](#tp2) +- [Function: `rxn_rate`](#rxn_rate) +- [Function: `threshold_min_max`](#threshold_min_max) +- [Function: `positive`](#positive) +- [Function: `negative`](#negative) + +--- + +## API Reference + +### [Module] `m_calculate` + +*Author: Google DeepMind Team & Ignis* +@brief DNS post-processing mathematical operations and derivatives. + +This module calculates spatial derivatives (first and second derivatives in X, Y, Z directions) +using high-order compact finite difference schemes. It also calculates chemical reaction rates, +positive/negative component extraction, and threshold operations. + +--- + +### [Subroutine] `m_calculate_init` + +```fortran +subroutine m_calculate_init() +``` + +Initializes the workspace arrays and matrices. + +Pre-allocates transposed workspace buffers (`xsrc`, `xdst`, `rsrc`, `rdst`) +and performs the LU decomposition setup via `ludcmp` for the tridiagonal compact schemes. + +--- + +### [Subroutine] `m_calculate_finalize` + +```fortran +subroutine m_calculate_finalize() +``` + +*No description provided.* + +--- + +### [Subroutine] `ddx1d` + +```fortran +subroutine ddx1d(dst, src) +``` + +*No description provided.* + +--- + +### [Subroutine] `ddx` + +```fortran +subroutine ddx(dst, src) +``` + +Computes the first-order derivative in the X-direction. + +- ` src `: 3D input scalar field (nxp, nyp, nzp). +- ` dst `: 3D output derivative field (nxp, nyp, nzp). + +--- + +### [Subroutine] `ddy` + +```fortran +subroutine ddy(dst, src) +``` + +Computes the first-order derivative in the Y-direction. + +- ` src `: 3D input scalar field (nxp, nyp, nzp). +- ` dst `: 3D output derivative field (nxp, nyp, nzp). + +--- + +### [Subroutine] `ddz` + +```fortran +subroutine ddz(dst, src) +``` + +Computes the first-order derivative in the Z-direction. + +- ` src `: 3D input scalar field (nxp, nyp, nzp). +- ` dst `: 3D output derivative field (nxp, nyp, nzp). + +--- + +### [Subroutine] `d2dx1d` + +```fortran +subroutine d2dx1d(dst, src) +``` + +*No description provided.* + +--- + +### [Subroutine] `d2dx` + +```fortran +subroutine d2dx(dst, src) +``` + +*No description provided.* + +--- + +### [Subroutine] `d2dy` + +```fortran +subroutine d2dy(dst, src) +``` + +*No description provided.* + +--- + +### [Subroutine] `d2dz` + +```fortran +subroutine d2dz(dst, src) +``` + +*No description provided.* + +--- + +### [Subroutine] `tp` + +```fortran +subroutine tp(a, b, nx) +``` + +*No description provided.* + +--- + +### [Subroutine] `tp2` + +```fortran +subroutine tp2(a, b, n1, n2) +``` + +*No description provided.* + +--- + +### [Function] `rxn_rate` + +```fortran +function rxn_rate(c) +``` + +Computes the chemical reaction rate based on the progress variable c. + +This uses a piecewise exponential/Arrhenius model depending on whether the progress variable +is below c_cut, above c_ref, or intermediate. + +- ` c `: The progress variable (0.0 to 1.0). + +**Returns:** + +The computed reaction rate. + +--- + +### [Function] `threshold_min_max` + +```fortran +function threshold_min_max(c, minc, maxc) +``` + +*No description provided.* + +--- + +### [Function] `positive` + +```fortran +function positive(c) +``` + +*No description provided.* + +--- + +### [Function] `negative` + +```fortran +function negative(c) +``` + +*No description provided.* + +--- + diff --git a/docs/m_openmpi.md b/docs/m_openmpi.md new file mode 100644 index 0000000..727e20e --- /dev/null +++ b/docs/m_openmpi.md @@ -0,0 +1,55 @@ +# m_openmpi.f90 + +![Language](https://img.shields.io/badge/Language-Fortran Source-blue?style=for-the-badge) + +## Overview + +*No description provided.* + +## API Index + +- [Module: `m_openmpi`](#m_openmpi) +- [Subroutine: `m_openmpi_init`](#m_openmpi_init) +- [Subroutine: `m_openmpi_exit`](#m_openmpi_exit) +- [Subroutine: `openmpi_get_command_line`](#openmpi_get_command_line) + +--- + +## API Reference + +### [Module] `m_openmpi` + +*No description provided.* + +--- + +### [Subroutine] `m_openmpi_init` + +```fortran +subroutine m_openmpi_init() +``` + +*No description provided.* + +--- + +### [Subroutine] `m_openmpi_exit` + +```fortran +subroutine m_openmpi_exit() +``` + +*No description provided.* + +--- + +### [Subroutine] `openmpi_get_command_line` + +```fortran +subroutine openmpi_get_command_line() +``` + +*No description provided.* + +--- + diff --git a/docs/m_parameters.md b/docs/m_parameters.md new file mode 100644 index 0000000..df34307 --- /dev/null +++ b/docs/m_parameters.md @@ -0,0 +1,44 @@ +# m_parameters.f90 + +![Language](https://img.shields.io/badge/Language-Fortran Source-blue?style=for-the-badge) + +## Overview + +*No description provided.* + +## API Index + +- [Module: `m_parameters`](#m_parameters) +- [Function: `to_omit`](#to_omit) +- [Subroutine: `read_intro`](#read_intro) + +--- + +## API Reference + +### [Module] `m_parameters` + +*No description provided.* + +--- + +### [Function] `to_omit` + +```fortran +function to_omit(num) +``` + +*No description provided.* + +--- + +### [Subroutine] `read_intro` + +```fortran +subroutine read_intro() +``` + +*No description provided.* + +--- + diff --git a/docs/post.md b/docs/post.md new file mode 100644 index 0000000..633eabe --- /dev/null +++ b/docs/post.md @@ -0,0 +1,694 @@ +# post.py + +![Language](https://img.shields.io/badge/Language-Python Source-green?style=for-the-badge) + +## Overview + +conversion from tree to python data + +## API Index + +- [Class: `LarkToSympy`](#larktosympy) +- [Class: `ArrayFCodePrinter`](#arrayfcodeprinter) +- [Class: `SympyOptimizer`](#sympyoptimizer) +- [Class: `CollectDefinitions`](#collectdefinitions) +- [Class: `ExpInspector`](#expinspector) +- [Class: `ExpToLatex`](#exptolatex) +- [Class: `ExpToCode`](#exptocode) +- [Function: `make_allocate`](#make_allocate) +- [Class: `FieldBase`](#fieldbase) +- [Class: `FieldExporter`](#fieldexporter) +- [Class: `Field`](#field) +- [Class: `FluctuationField`](#fluctuationfield) +- [Class: `PrimaryField`](#primaryfield) +- [Class: `DerivedField`](#derivedfield) +- [Class: `AveragedField`](#averagedfield) +- [Class: `Stage1`](#stage1) +- [Class: `Stage2`](#stage2) +- [Class: `Stage3`](#stage3) +- [Class: `Stage4`](#stage4) +- [Class: `Stage5`](#stage5) +- [Class: `Stage6`](#stage6) + +--- + +## API Reference + +### [Class] `LarkToSympy(Transformer)` + +*No description provided.* + +#### Methods + +##### `__init__(self, fdict)` + +*No description provided.* + +##### `number(self, numeral)` + +*No description provided.* + +##### `env(self, name)` + +*No description provided.* + +##### `paren(self, val)` + +*No description provided.* + +##### `var(self, name)` + +*No description provided.* + +##### `fluc(self, name)` + +*No description provided.* + +##### `dnx(self, partial, b)` + +*No description provided.* + +##### `icall(self, op, val)` + +*No description provided.* + +##### `fcall(self)` + +*No description provided.* + +##### `neg(self, val)` + +*No description provided.* + +##### `add(self, a, b)` + +*No description provided.* + +##### `sub(self, a, b)` + +*No description provided.* + +##### `mul(self, a, b)` + +*No description provided.* + +##### `div(self, a, b)` + +*No description provided.* + +##### `udf(self, a)` + +*No description provided.* + +--- + +### [Class] `ArrayFCodePrinter(FCodePrinter)` + +*No description provided.* + +#### Methods + +##### `__init__(self, settings, array_symbols, avg_symbols)` + +*No description provided.* + +##### `_print_Float(self, expr)` + +*No description provided.* + +##### `_print_Symbol(self, expr)` + +*No description provided.* + +##### `_print_Function(self, expr)` + +*No description provided.* + +--- + +### [Class] `SympyOptimizer` + +*No description provided.* + +#### Methods + +##### `get_instance(cls, fdict)` + +**Decorators:** `@classmethod`
+ +*No description provided.* + +##### `__init__(self, fdict)` + +*No description provided.* + +##### `set_averaged(self, averaged_dict)` + +*No description provided.* + +##### `get_sympy_expr(self, name)` + +*No description provided.* + +##### `calculate_flops_and_heavy(self, expr)` + +*No description provided.* + +##### `count_3d_loads(self, expr, three_d_arrays)` + +*No description provided.* + +##### `optimize_field(self, name, alloc)` + +*No description provided.* + +--- + +### [Class] `CollectDefinitions(Visitor)` + +*No description provided.* + +#### Methods + +##### `__init__(self, primary, derived, averaged)` + +*No description provided.* + +##### `varlist(self, tree)` + +*No description provided.* + +##### `assign_var(self, tree)` + +*No description provided.* + +##### `assign_avg_var(self, tree)` + +*No description provided.* + +--- + +### [Class] `ExpInspector(Visitor)` + +*No description provided.* + +#### Methods + +##### `__init__(self)` + +*No description provided.* + +##### `inspect(cls, tree)` + +**Decorators:** `@classmethod`
+ +*No description provided.* + +##### `__call__(self, tree)` + +*No description provided.* + +##### `fluc(self, tree)` + +*No description provided.* + +##### `var(self, tree)` + +*No description provided.* + +##### `dnx(self, tree)` + +*No description provided.* + +--- + +### [Class] `ExpToLatex(Transformer)` + +*No description provided.* + +#### Methods + +##### `__init__(self, fdict)` + +*No description provided.* + +##### `arithmatic_rooted(self, name)` + +*No description provided.* + +##### `parenthise(self, name)` + +*No description provided.* + +##### `number(self, numeral)` + +*No description provided.* + +##### `env(self, name)` + +*No description provided.* + +##### `paren(self, name)` + +*No description provided.* + +##### `var(self, name)` + +*No description provided.* + +##### `fluc(self, name)` + +*No description provided.* + +##### `dnx(self, partial, b)` + +*No description provided.* + +##### `icall(self, a, b)` + +*No description provided.* + +##### `fcall(self)` + +*No description provided.* + +##### `neg(self, b)` + +*No description provided.* + +##### `add(self, a, b)` + +*No description provided.* + +##### `sub(self, a, b)` + +*No description provided.* + +##### `mul(self, a, b)` + +*No description provided.* + +##### `div(self, a, b)` + +*No description provided.* + +--- + +### [Class] `ExpToCode(Transformer)` + +*No description provided.* + +#### Methods + +##### `__init__(self, fdict)` + +*No description provided.* + +##### `number(self, numeral)` + +*No description provided.* + +##### `env(self, name)` + +*No description provided.* + +##### `paren(self, name)` + +*No description provided.* + +##### `var(self, name)` + +*No description provided.* + +##### `fluc(self, name)` + +*No description provided.* + +##### `dnx(self, partial, b)` + +*No description provided.* + +##### `icall(self, a, b)` + +*No description provided.* + +##### `fcall(self)` + +*No description provided.* + +##### `neg(self, b)` + +*No description provided.* + +##### `add(self, a, b)` + +*No description provided.* + +##### `sub(self, a, b)` + +*No description provided.* + +##### `mul(self, a, b)` + +*No description provided.* + +##### `div(self, a, b)` + +*No description provided.* + +--- + +### [Function] `make_allocate` + +```python +function make_allocate(name, shape, init_zero) +``` + +*No description provided.* + +--- + +### [Class] `FieldBase(object)` + +*No description provided.* + +#### Methods + +##### `__init__(self, name, fdict)` + +*No description provided.* + +##### `depends_on(self, a)` + +*No description provided.* + +##### `is_primary(self)` + +*No description provided.* + +##### `not_primary(self)` + +*No description provided.* + +##### `is_fluctuation(self)` + +*No description provided.* + +##### `export_on(self)` + +*No description provided.* + +##### `__repr__(self)` + +*No description provided.* + +##### `checkFluctuation(self)` + +*No description provided.* + +##### `depClosure(self)` + +*No description provided.* + +##### `code_decl(self)` + +*No description provided.* + +##### `code_alloc(self)` + +*No description provided.* + +##### `code_free(self)` + +*No description provided.* + +--- + +### [Class] `FieldExporter(object)` + +*No description provided.* + +#### Methods + +##### `__init__(self, name, attr, parent)` + +*No description provided.* + +##### `code(self)` + +*No description provided.* + +##### `code_decl(self)` + +*No description provided.* + +##### `code_alloc(self)` + +*No description provided.* + +##### `code_free(self)` + +*No description provided.* + +--- + +### [Class] `Field(FieldBase)` + +*No description provided.* + +#### Methods + +##### `__init__(self, name, attr, exp, fdict)` + +*No description provided.* + +##### `export_on(self)` + +*No description provided.* + +##### `code(self, alloc)` + +*No description provided.* + +--- + +### [Class] `FluctuationField(FieldBase)` + +*No description provided.* + +#### Methods + +##### `__init__(self, w, field, fset, fdict)` + +*No description provided.* + +##### `code(self, alloc)` + +*No description provided.* + +##### `id(cls, w, field)` + +**Decorators:** `@classmethod`
+ +*No description provided.* + +--- + +### [Class] `PrimaryField(FieldBase)` + +*No description provided.* + +#### Methods + +##### `__init__(self, name, fdict)` + +*No description provided.* + +##### `code(self, alloc)` + +*No description provided.* + +##### `code_decl(self)` + +*No description provided.* + +##### `code_alloc(self)` + +*No description provided.* + +##### `code_free(self)` + +*No description provided.* + +--- + +### [Class] `DerivedField(FieldBase)` + +*No description provided.* + +#### Methods + +##### `__init__(self, op, v, fdict)` + +*No description provided.* + +##### `code(self, alloc)` + +*No description provided.* + +--- + +### [Class] `AveragedField(FieldBase)` + +*No description provided.* + +#### Methods + +##### `id(cls, w, tgt)` + +**Decorators:** `@classmethod`
+ +*No description provided.* + +##### `__init__(self, w, tgt, fdict)` + +*No description provided.* + +##### `code(self, alloc)` + +*No description provided.* + +##### `code_avg(self)` + +*No description provided.* + +##### `isWeighted(self)` + +*No description provided.* + +##### `pass1(self)` + +*No description provided.* + +##### `pass2(self)` + +*No description provided.* + +--- + +### [Class] `Stage1` + +conversion from tree to python data + +#### Methods + +##### `__init__(self, raw_tree)` + +*No description provided.* + +##### `__repr__(self)` + +*No description provided.* + +--- + +### [Class] `Stage2` + +expand derivatives and averages + +#### Methods + +##### `__init__(self, src)` + +*No description provided.* + +##### `__repr__(self)` + +*No description provided.* + +##### `dependency(self)` + +*No description provided.* + +--- + +### [Class] `Stage3` + +calculate execution order + +#### Methods + +##### `__init__(self, src)` + +*No description provided.* + +##### `__repr__(self)` + +*No description provided.* + +##### `sort_vars(self, dependency, group)` + +*No description provided.* + +##### `calc_size(self, ordered, remaining)` + +*No description provided.* + +##### `sort_vars_new(self, dependency, group)` + +*No description provided.* + +##### `print_program(self)` + +*No description provided.* + +--- + +### [Class] `Stage4` + +analyze liveness and allocate array + +#### Methods + +##### `__init__(self, src)` + +*No description provided.* + +##### `liveness(self, l1, g)` + +*No description provided.* + +##### `allocate_arr(self, l)` + +*No description provided.* + +##### `work_array_codes(self)` + +*No description provided.* + +##### `write_avg_codes(self, avglist)` + +*No description provided.* + +##### `print_program(self)` + +*No description provided.* + +##### `save_ir(self)` + +*No description provided.* + +--- + +### [Class] `Stage5` + +pass1 and pass2 seperation and calculation ordering + +--- + +### [Class] `Stage6` + +generate fortran code + +--- + diff --git a/docs/post_dns.md b/docs/post_dns.md new file mode 100644 index 0000000..0752c8d --- /dev/null +++ b/docs/post_dns.md @@ -0,0 +1,37 @@ +# post_dns.f90 + +![Language](https://img.shields.io/badge/Language-Fortran Source-blue?style=for-the-badge) + +## Overview + +*No description provided.* + +## API Index + +- [Function: `build_info_length`](#build_info_length) +- [Function: `latex_length`](#latex_length) + +--- + +## API Reference + +### [Function] `build_info_length` + +```fortran +function build_info_length() +``` + +*No description provided.* + +--- + +### [Function] `latex_length` + +```fortran +function latex_length() +``` + +*No description provided.* + +--- + diff --git a/docs/pycompact.md b/docs/pycompact.md new file mode 100644 index 0000000..7495662 --- /dev/null +++ b/docs/pycompact.md @@ -0,0 +1,116 @@ +# pycompact.py + +![Language](https://img.shields.io/badge/Language-Python Source-green?style=for-the-badge) + +## Overview + +*No description provided.* + +## API Index + +- [Class: `CompactScheme`](#compactscheme) +- [Function: `read_old_data`](#read_old_data) +- [Function: `read_data`](#read_data) +- [Function: `validate_trigonometric`](#validate_trigonometric) +- [Function: `test_dns_data`](#test_dns_data) + +--- + +## API Reference + +### [Class] `CompactScheme` + +*No description provided.* + +#### Methods + +##### `__init__(self, nx, ny, nz, px, py, pz, lx, ly, lz)` + +*No description provided.* + +##### `test_ludcmp(self)` + +*No description provided.* + +##### `py_rhs_1_np(self, x)` + +*No description provided.* + +##### `py_tdslv(self, r, l)` + +*No description provided.* + +##### `test_dfnonp(self)` + +*No description provided.* + +##### `verify_nonp_lud1(self)` + +*No description provided.* + +##### `verify_nonp_lud2(self)` + +*No description provided.* + +##### `py_stdlu(self, aa)` + +*No description provided.* + +##### `ddx(self, src)` + +*No description provided.* + +##### `ddy(self, src)` + +*No description provided.* + +##### `ddz(self, src)` + +*No description provided.* + +##### `port_nonp_coef(self)` + +*No description provided.* + +--- + +### [Function] `read_old_data` + +```python +function read_old_data(fname) +``` + +*No description provided.* + +--- + +### [Function] `read_data` + +```python +function read_data(fname) +``` + +*No description provided.* + +--- + +### [Function] `validate_trigonometric` + +```python +function validate_trigonometric() +``` + +*No description provided.* + +--- + +### [Function] `test_dns_data` + +```python +function test_dns_data() +``` + +*No description provided.* + +--- +