refactor: introduce registries for OCP compliance (Phase 1)
All checks were successful
CI Test Suite / run-tests (push) Successful in 1m14s
Deploy Documentation / build-and-deploy (push) Successful in 53s

This commit is contained in:
ignis 2026-06-04 01:08:18 +00:00
parent 2b3362a927
commit 56996691d8

View file

@ -29,6 +29,73 @@ from jinja2 import Template
import sympy
from sympy.printing.fortran import FCodePrinter
# --- Registries for SOLID (OCP) Compliance ---
class FunctionRegistry:
def __init__(self):
self._sympy_registry = {}
self._latex_registry = {}
def register_sympy(self, name, sympy_builder):
self._sympy_registry[name] = sympy_builder
def register_latex(self, name, latex_builder):
self._latex_registry[name] = latex_builder
def to_sympy(self, name, *args):
if name in self._sympy_registry:
return self._sympy_registry[name](*args)
return sympy.Function(name)(*args)
def to_latex(self, name, *args):
if name in self._latex_registry:
return self._latex_registry[name](*args)
b = ", ".join(args)
if name.startswith("\\"):
return r"{}{{({})}}".format(name, b)
return r"\mathrm{{{}}}({})".format(name, b)
function_registry = FunctionRegistry()
# Register standard mathematical functions
function_registry.register_sympy("sqrt", lambda *args: sympy.sqrt(args[0]))
function_registry.register_sympy("abs", lambda *args: sympy.Abs(args[0]))
function_registry.register_sympy("log", lambda *args: sympy.log(args[0]))
function_registry.register_sympy("exp", lambda *args: sympy.exp(args[0]))
function_registry.register_sympy("rxn_rate", lambda *args: sympy.Function("rxn_rate")(args[0]))
function_registry.register_latex("sqrt", lambda *args: r"\sqrt{{{}}}".format(", ".join(args)))
function_registry.register_latex("abs", lambda *args: r"\left| {} \right|".format(", ".join(args)))
function_registry.register_latex(r"\log", lambda *args: r"\log{{({})}}".format(", ".join(args)))
function_registry.register_latex(r"\exp", lambda *args: r"\exp{{({})}}".format(", ".join(args)))
function_registry.register_latex(r"\omega", lambda *args: r"\omega{{({})}}".format(", ".join(args)))
class DifferentialOperatorRegistry:
def __init__(self):
self._operators = {}
def register(self, op_name, latex_symbol):
self._operators[op_name] = latex_symbol
def get_latex_symbol(self, op_name):
if op_name in self._operators:
return self._operators[op_name]
# Fallback to dynamic parsing matching original code
fmt = r"\partial_{{{}}}"
coord = op_name[-1] if op_name else ""
return fmt.format(coord + coord if len(op_name) > 3 else coord)
differential_operator_registry = DifferentialOperatorRegistry()
# Register standard derivative operators
differential_operator_registry.register("ddx", r"\partial_{x}")
differential_operator_registry.register("d2dx", r"\partial_{xx}")
differential_operator_registry.register("ddy", r"\partial_{y}")
differential_operator_registry.register("d2dy", r"\partial_{yy}")
differential_operator_registry.register("ddz", r"\partial_{z}")
differential_operator_registry.register("d2dz", r"\partial_{zz}")
@v_args(inline=True)
class LarkToSympy(Transformer):
"""Lark AST의 수학적 노드들을 SymPy 기호 수식 객체로 변환하는 Transformer 클래스입니다.
@ -81,19 +148,9 @@ class LarkToSympy(Transformer):
# 내장 수학 함수(sqrt, exp, log, abs, rxn_rate) 또는 사용자 정의 UDF들을 SymPy 함수 노드로 매핑
a = args[0]
func_name = a.value if hasattr(a, 'value') else str(a)
if func_name == "sqrt":
return sympy.sqrt(args[1])
elif func_name == "exp":
return sympy.exp(args[1])
elif func_name == "log":
return sympy.log(args[1])
elif func_name == "abs":
return sympy.Abs(args[1])
elif func_name == "rxn_rate":
return sympy.Function("rxn_rate")(args[1])
elif func_name == "udf":
return sympy.Function(a.value)(*args[1:])
return sympy.Function(func_name)(*args[1:])
if func_name == "udf":
return sympy.Function(a.value if hasattr(a, 'value') else str(a))(*args[1:])
return function_registry.to_sympy(func_name, *args[1:])
def neg(self, val):
return -val
@ -574,19 +631,8 @@ class ExpToLatex(Transformer):
def fcall (self, *args):
a = args[0]
b = ", ".join(args[1:])
if a == 'sqrt':
fcode = r"\sqrt{{{}}}".format(b)
return fcode
elif a == 'abs':
fcode = r"\left| {} \right|".format(b)
return fcode
elif a.startswith("\\"):
fcode = r"{}{{({})}}".format(a, b)
return fcode
else:
fcode = r"\mathrm{{{}}}({})".format(a, b)
return fcode
func_name = a.value if hasattr(a, 'value') else str(a)
return function_registry.to_latex(func_name, *args[1:])
def neg(self, b):
fcode = "(-{})".format(b)
@ -1129,10 +1175,7 @@ class DerivedField (FieldBase):
self.v = v
self.dep = set([v])
fmt = r"\partial_{{{}}}"
coord = op[-1]
partial = fmt.format(coord + coord if len(op) > 3 else coord)
partial = differential_operator_registry.get_latex_symbol(op)
self.latex = partial + "(" + fdict[v].latex + ")"
def code (self, alloc=None):