Source code for ffcx.main

# Copyright (C) 2004-2020 Anders Logg, Garth N. Wells and Michal Habera
#
# This file is part of FFCx.(https://www.fenicsproject.org)
#
# SPDX-License-Identifier:    LGPL-3.0-or-later
"""Command-line interface to FFCx.

Parse command-line arguments and generate code from input UFL form files.
"""

import argparse
import cProfile
import logging
import pathlib
import re
import string
from collections.abc import Sequence
from typing import Optional

import ufl

from ffcx import __version__ as FFCX_VERSION
from ffcx import compiler, formatting
from ffcx.options import FFCX_DEFAULT_OPTIONS, get_options

logger = logging.getLogger("ffcx")

parser = argparse.ArgumentParser(
    description="FEniCS Form Compiler (FFCx, https://fenicsproject.org)"
)
parser.add_argument("--version", action="version", version=f"%(prog)s (version {FFCX_VERSION})")
parser.add_argument("-o", "--output-directory", type=str, default=".", help="output directory")
parser.add_argument("--visualise", action="store_true", help="visualise the IR graph")
parser.add_argument("-p", "--profile", action="store_true", help="enable profiling")

# Add all options from FFCx option system
for opt_name, (arg_type, opt_val, opt_desc, choices) in FFCX_DEFAULT_OPTIONS.items():
    if isinstance(opt_val, bool):
        parser.add_argument(
            f"--{opt_name}", action="store_true", help=f"{opt_desc} (default={opt_val})"
        )
    else:
        parser.add_argument(
            f"--{opt_name}", type=arg_type, choices=choices, help=f"{opt_desc} (default={opt_val})"
        )

parser.add_argument("ufl_file", nargs="+", help="UFL file(s) to be compiled")


[docs] def main(args: Optional[Sequence[str]] = None) -> int: """Run ffcx on a UFL file.""" xargs = parser.parse_args(args) # Parse all other options priority_options = {k: v for k, v in xargs.__dict__.items() if v is not None} options = get_options(priority_options) # Call parser and compiler for each file for filename in xargs.ufl_file: file = pathlib.Path(filename) # Remove weird characters (file system allows more than the C # preprocessor) prefix = file.stem prefix = re.subn("[^{}]".format(string.ascii_letters + string.digits + "_"), "!", prefix)[0] prefix = re.subn("!+", "_", prefix)[0] # Turn on profiling if xargs.profile: pr = cProfile.Profile() pr.enable() # Load UFL file ufd = ufl.algorithms.load_ufl_file(filename) # Generate code code_h, code_c = compiler.compile_ufl_objects( ufd.forms + ufd.expressions + ufd.elements, options=options, object_names=ufd.object_names, prefix=prefix, visualise=xargs.visualise, ) # Write to file formatting.write_code(code_h, code_c, prefix, xargs.output_directory) # Turn off profiling and write status to file if xargs.profile: pr.disable() pfn = f"ffcx_{prefix}.profile" pr.dump_stats(pfn) return 0