# Generates code containing quadrature rules for the Gauss-Lobatto from quadpy import c1 from pathlib import Path import sys # Include all lower-order rules up to a maximum value, then power of two after that LOWER_ORDER_MAX = 32 higher_order_set = [2**i for i in range(6, 10)] n_set = list(range(2, LOWER_ORDER_MAX + 1)) + higher_order_set file_template = r"""//! Code generated by %filename%. //! Do not change this file directly. Instead, modify the codegen script. use crate::Rule; %functions% // Documentation for this function is provided in the outer (non-codegen) function. pub fn try_gauss_lobatto(n: usize) -> Option> { match n { %cases% _ => None, } } """ fn_template = r"""#[rustfmt::skip] pub fn gauss_lobatto_%n%() -> Rule<1> { let weights = vec![ %weights% ]; let points = vec![ %points% ]; (weights, points) }""" def build_gauss_lobatto_code(n): scheme = c1.gauss_lobatto(n) indent = " " * 8 weights_str = "\n".join([indent + str(w) + "," for w in scheme.weights]) points_str = "\n".join([indent + "[" + str(xi) + "]," for xi in scheme.points]) fn = fn_template.replace('%n%', str(n)).replace('%weights%', weights_str).replace('%points%', points_str) return fn def build_gauss_lobatto_case(n): indent = " " * 8 return f"{indent}{n} => Some(gauss_lobatto_{n}())," function_codes = "\n\n".join([build_gauss_lobatto_code(n) for n in n_set]) cases = "\n".join([build_gauss_lobatto_case(n) for n in n_set]) script_filename = Path(__file__).name file_str = file_template \ .replace('%filename%', "tools/" + script_filename) \ .replace('%functions%', function_codes) \ .replace('%cases%', cases) codegen_dir_name = "src/codegen" codegen_dir = Path(__file__).parent.parent.joinpath(codegen_dir_name) # Generate a doc stub that will be included in the manual docs (generated so things don't get out of sync). higher_order_set_str = ", ".join([str(n) for n in higher_order_set]) doc_stub = f"""Rules are provided for all lower-order rules up to `n <= {LOWER_ORDER_MAX}`, plus `n = ..., {higher_order_set_str}`. """ if codegen_dir.exists(): filepath = codegen_dir.joinpath("gauss_lobatto_rules.rs") print(f"Writing generated code to {filepath}...") with open(filepath, 'w') as f: f.write(file_str) print("Successfully wrote generated code.") docpath = codegen_dir.joinpath("gauss_lobatto_rules_doc_stub.md") print(f"Writing doc stub to {docpath}...") with open(docpath, 'w') as f: f.write(doc_stub) print(f"Successfully wrote doc stub.") else: print(f"{codegen_dir_name} does not exist") sys.exit(1)