Showing preview only (681K chars total). Download the full file or copy to clipboard to get everything.
Repository: FEniCS/ffcx
Branch: main
Commit: e50672a9778c
Files: 127
Total size: 644.0 KB
Directory structure:
gitextract_d5vvy4xt/
├── .gitattributes
├── .github/
│ ├── FUNDING.yml
│ ├── dependabot.yml
│ └── workflows/
│ ├── build-wheels.yml
│ ├── dolfinx-tests.yml
│ ├── pythonapp.yml
│ └── spack.yml
├── .gitignore
├── AUTHORS
├── CODE_OF_CONDUCT.md
├── COPYING
├── COPYING.LESSER
├── ChangeLog.rst
├── LICENSE
├── MANIFEST.in
├── README.md
├── UNLICENSE
├── _clang-format
├── cmake/
│ ├── CMakeLists.txt
│ ├── ufcx.pc.in
│ └── ufcxConfig.cmake.in
├── demo/
│ ├── BiharmonicHHJ.py
│ ├── BiharmonicRegge.py
│ ├── CellGeometry.py
│ ├── ComplexPoisson.py
│ ├── Components.py
│ ├── Conditional.py
│ ├── ExpressionInterpolation.py
│ ├── FacetIntegrals.py
│ ├── FacetRestrictionAD.py
│ ├── HyperElasticity.py
│ ├── MassAction.py
│ ├── MassDG0.py
│ ├── MassHcurl_2D_1.py
│ ├── MassHdiv_2D_1.py
│ ├── MathFunctions.py
│ ├── MetaData.py
│ ├── Mini.py
│ ├── MixedCoefficient.py
│ ├── MixedPoissonDual.py
│ ├── Normals.py
│ ├── Poisson1D.py
│ ├── PoissonQuad.py
│ ├── ProjectionManifold.py
│ ├── ReactionDiffusion.py
│ ├── SpatialCoordinates.py
│ ├── StabilisedStokes.py
│ ├── Symmetry.py
│ ├── VectorConstant.py
│ ├── VectorPoisson.py
│ └── test_demos.py
├── doc/
│ └── source/
│ ├── conf.py
│ └── index.rst
├── ffcx/
│ ├── __init__.py
│ ├── __main__.py
│ ├── analysis.py
│ ├── codegeneration/
│ │ ├── C/
│ │ │ ├── __init__.py
│ │ │ ├── expression.py
│ │ │ ├── expression_template.py
│ │ │ ├── file.py
│ │ │ ├── file_template.py
│ │ │ ├── form.py
│ │ │ ├── form_template.py
│ │ │ ├── formatter.py
│ │ │ ├── integral.py
│ │ │ └── integral_template.py
│ │ ├── __init__.py
│ │ ├── access.py
│ │ ├── backend.py
│ │ ├── codegeneration.py
│ │ ├── common.py
│ │ ├── definitions.py
│ │ ├── expression_generator.py
│ │ ├── geometry.py
│ │ ├── integral_generator.py
│ │ ├── interface.py
│ │ ├── jit.py
│ │ ├── lnodes.py
│ │ ├── numba/
│ │ │ ├── __init__.py
│ │ │ ├── expression.py
│ │ │ ├── expression_template.py
│ │ │ ├── file.py
│ │ │ ├── file_template.py
│ │ │ ├── form.py
│ │ │ ├── form_template.py
│ │ │ ├── formatter.py
│ │ │ ├── integral.py
│ │ │ └── integral_template.py
│ │ ├── optimizer.py
│ │ ├── symbols.py
│ │ ├── ufcx.h
│ │ └── utils.py
│ ├── compiler.py
│ ├── definitions.py
│ ├── element_interface.py
│ ├── formatting.py
│ ├── ir/
│ │ ├── __init__.py
│ │ ├── analysis/
│ │ │ ├── __init__.py
│ │ │ ├── factorization.py
│ │ │ ├── graph.py
│ │ │ ├── indexing.py
│ │ │ ├── modified_terminals.py
│ │ │ ├── reconstruct.py
│ │ │ ├── valuenumbering.py
│ │ │ └── visualise.py
│ │ ├── elementtables.py
│ │ ├── integral.py
│ │ ├── representation.py
│ │ └── representationutils.py
│ ├── main.py
│ ├── naming.py
│ ├── options.py
│ └── py.typed
├── pyproject.toml
└── test/
├── conftest.py
├── poisson.py
├── test_add_mode.py
├── test_cache.py
├── test_cmdline.py
├── test_custom_data.py
├── test_jit_expression.py
├── test_jit_forms.py
├── test_lnodes.py
├── test_numba.py
├── test_signatures.py
├── test_submesh.py
└── test_tensor_product.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
release.conf export-ignore
.gitignore export-ignore
.gitattributes export-ignore
.mailmap export-ignore
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: FEniCS # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
================================================
FILE: .github/dependabot.yml
================================================
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "github-actions" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
- package-ecosystem: "pip" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
================================================
FILE: .github/workflows/build-wheels.yml
================================================
name: Build wheels
# By default this action does not push to test or production PyPI. The wheels
# are available as an artifact that can be downloaded and tested locally.
on:
workflow_dispatch:
inputs:
ffcx_ref:
description: "FFCx git ref to checkout"
default: "main"
type: string
test_pypi_publish:
description: "Publish to Test PyPi"
default: false
type: boolean
pypi_publish:
description: "Publish to PyPi"
default: false
type: boolean
workflow_call:
inputs:
ffcx_ref:
description: "FFCx git ref to checkout"
default: "main"
type: string
test_pypi_publish:
description: "Publish to Test PyPi"
default: false
type: boolean
pypi_publish:
description: "Publish to PyPi"
default: false
type: boolean
jobs:
build:
name: Build wheels and source distributions
runs-on: ubuntu-latest
steps:
- name: Checkout FFCx
uses: actions/checkout@v6
with:
ref: ${{ github.event.inputs.ffcx_ref }}
- name: Upgrade pip and setuptools
run: python -m pip install setuptools pip build --upgrade
- name: Build sdist and wheel
run: python -m build .
- uses: actions/upload-artifact@v7
with:
path: dist/*
upload_test_pypi:
name: Upload to test PyPI (optional)
if: ${{ github.event.inputs.test_pypi_publish == 'true' }}
needs: [build]
runs-on: ubuntu-latest
environment:
name: testpypi
url: https://test.pypi.org/p/fenics-ffcx
permissions:
id-token: write
steps:
- uses: actions/download-artifact@v8
with:
name: artifact
path: dist
- name: Push to test PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
upload_pypi:
name: Upload to PyPI (optional)
if: ${{ github.event.inputs.pypi_publish == 'true' }}
needs: [build]
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/fenics-ffcx
permissions:
id-token: write
steps:
- uses: actions/download-artifact@v8
with:
name: artifact
path: dist
- name: Push to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
================================================
FILE: .github/workflows/dolfinx-tests.yml
================================================
# This workflow will install Basix, FFCx, DOLFINx and run the DOLFINx unit tests.
name: DOLFINx integration
on:
pull_request:
branches: [main]
merge_group:
branches: [main]
workflow_dispatch:
inputs:
dolfinx_ref:
description: "DOLFINx branch or tag"
default: "main"
type: string
basix_ref:
description: "Basix branch or tag"
default: "main"
type: string
ufl_ref:
description: "UFL branch or tag"
default: "main"
type: string
# Weekly build on Mondays at 8 am
schedule:
- cron: "0 8 * * 1"
jobs:
build:
name: Run DOLFINx tests
runs-on: ubuntu-latest
container: ghcr.io/fenics/test-env:current-openmpi
env:
PETSC_ARCH: linux-gnu-complex64-32
OMPI_ALLOW_RUN_AS_ROOT: 1
OMPI_ALLOW_RUN_AS_ROOT_CONFIRM: 1
PRTE_MCA_rmaps_default_mapping_policy: :oversubscribe # Newer OpenMPI
OMPI_MCA_rmaps_base_oversubscribe: true # Older OpenMPI
steps:
- uses: actions/checkout@v6
- name: Install UFL and Basix (default branches/tags)
if: github.event_name != 'workflow_dispatch'
run: |
python3 -m pip install --break-system-packages git+https://github.com/FEniCS/ufl.git
python3 -m pip install --break-system-packages git+https://github.com/FEniCS/basix.git
- name: Install UFL and Basix (specified branches/tags)
if: github.event_name == 'workflow_dispatch'
run: |
python3 -m pip install --break-system-packages git+https://github.com/FEniCS/ufl.git@${{ github.event.inputs.ufl_ref }}
python3 -m pip install --break-system-packages git+https://github.com/FEniCS/basix.git@${{ github.event.inputs.basix_ref }}
- name: Install FFCx
run: |
pip3 install --break-system-packages .
- name: Get DOLFINx source (default branch/tag)
if: github.event_name != 'workflow_dispatch'
uses: actions/checkout@v6
with:
path: ./dolfinx
repository: FEniCS/dolfinx
ref: main
- name: Get DOLFINx source (specified branch/tag)
if: github.event_name == 'workflow_dispatch'
uses: actions/checkout@v6
with:
path: ./dolfinx
repository: FEniCS/dolfinx
ref: ${{ github.event.inputs.dolfinx_ref }}
- name: Install DOLFINx (C++)
run: |
cmake -G Ninja -DCMAKE_BUILD_TYPE=Developer -DBUILD_TESTING=true -B build -S dolfinx/cpp/
cmake --build build
cmake --install build
- name: Run DOLFINx C++ unit tests
working-directory: build
run: ctest -V --output-on-failure -R unittests
- name: Install DOLFINx (Python)
run: |
python3 -m pip -v install --break-system-packages nanobind scikit-build-core[pyproject]
python3 -m pip -v install --break-system-packages --check-build-dependencies --no-build-isolation dolfinx/python/
- name: Install Python demo/test dependencies
run: python3 -m pip install --break-system-packages matplotlib numba pyamg pytest pytest-xdist scipy pyvista networkx
- name: Run DOLFINx Python unit tests
run: python3 -m pytest -n auto dolfinx/python/test/unit
- name: Run DOLFINx Python demos
run: python3 -m pytest -n=2 -m serial dolfinx/python/demo/test.py
================================================
FILE: .github/workflows/pythonapp.yml
================================================
# This workflow will install Python dependencies, run tests and lint
# with a single version of Python For more information see:
# https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
name: FFCx CI
on:
push:
branches:
- "**"
tags:
- "v*"
pull_request:
branches: [main]
merge_group:
branches: [main]
workflow_dispatch:
# Weekly build on Mondays at 8 am
schedule:
- cron: "0 8 * * 1"
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: ["windows-2022", "ubuntu-latest", "macos-latest"]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
steps:
- name: Checkout FFCx
uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Export GitHub Actions cache environment variables (Windows)
if: runner.os == 'Windows'
uses: actions/github-script@v9
with:
script: |
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
- name: Set up CMake
if: runner.os == 'Windows'
uses: lukka/get-cmake@latest
with:
cmakeVersion: "~3.30.0"
- name: Install dependencies (non-Python, Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get install -y graphviz libgraphviz-dev ninja-build pkg-config libblas-dev liblapack-dev
- name: Install dependencies (non-Python, macOS)
if: runner.os == 'macOS'
run: brew install ninja
- name: Install FEniCS dependencies (Python, Unix)
if: runner.os == 'Linux' || runner.os == 'macOS'
run: |
pip install git+https://github.com/FEniCS/ufl.git
pip install git+https://github.com/FEniCS/basix.git
- name: Install FEniCS dependencies (Python, Windows)
if: runner.os == 'Windows'
env:
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
run: |
pip install git+https://github.com/FEniCS/ufl.git
pip install -v git+https://github.com/FEniCS/basix.git --config-settings=cmake.args=-DINSTALL_RUNTIME_DEPENDENCIES=ON --config-settings=cmake.args=-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake
- name: Install FFCx (Linux, with optional dependencies)
if: runner.os == 'Linux'
run: pip install .[ci,optional]
- name: Install FFCx (macOS, Windows)
if: runner.os != 'Linux'
run: pip install .[ci]
- name: ruff checks
run: |
ruff check .
ruff format --check .
- name: Static check with mypy
run: mypy -p ffcx
- name: Run unit tests
run: >
python -m pytest test/
-n auto
-W error
--cov=ffcx/
--junitxml=junit/test-results-${{ matrix.os }}-${{ matrix.python-version }}.xml
- name: Upload to Coveralls
if: ${{ github.repository == 'FEniCS/ffcx' && github.head_ref == '' && matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12' }}
env:
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
run: coveralls
continue-on-error: true
- name: Upload pytest results
uses: actions/upload-artifact@v7
with:
name: pytest-results-${{ matrix.os }}-${{ matrix.python-version }}
path: junit/test-results-${{ matrix.os }}-${{ matrix.python-version }}.xml
# Use always() to always run this step to publish test results
# when there are test failures
if: always()
- name: Setup cl.exe (Windows)
if: runner.os == 'Windows'
uses: ilammy/msvc-dev-cmd@v1
- name: Run FFCx demos
run: >
pytest demo/test_demos.py
-W error
# -n auto
- name: Build documentation
run: |
cd doc
make html
- name: Upload documentation artifact
uses: actions/upload-artifact@v7
with:
name: doc-${{ matrix.os }}-${{ matrix.python-version }}
path: doc/build/html/
retention-days: 2
if-no-files-found: error
- name: Checkout FEniCS/docs
if: ${{ github.repository == 'FEniCS/ffcx' && ( github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') ) && runner.os == 'Linux' && matrix.python-version == 3.12 }}
uses: actions/checkout@v6
with:
repository: "FEniCS/docs"
path: "docs"
ssh-key: "${{ secrets.SSH_GITHUB_DOCS_PRIVATE_KEY }}"
- name: Set version name
if: ${{ github.repository == 'FEniCS/ffcx' && ( github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') ) && runner.os == 'Linux' && matrix.python-version == 3.12 }}
run: |
echo "VERSION_NAME=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- name: Copy documentation into repository
if: ${{ github.repository == 'FEniCS/ffcx' && ( github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') ) && runner.os == 'Linux' && matrix.python-version == 3.12 }}
run: |
cd docs
git rm -r --ignore-unmatch ffcx/${{ env.VERSION_NAME }}
mkdir -p ffcx/${{ env.VERSION_NAME }}
cp -r ../doc/build/html/* ffcx/${{ env.VERSION_NAME }}
- name: Commit and push documentation to FEniCS/docs
if: ${{ github.repository == 'FEniCS/ffcx' && ( github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') ) && runner.os == 'Linux' && matrix.python-version == 3.12 }}
run: |
cd docs
git config --global user.email "fenics@github.com"
git config --global user.name "FEniCS GitHub Actions"
git add --all
git commit --allow-empty -m "Python FEniCS/ffcx@${{ github.sha }}"
git push
================================================
FILE: .github/workflows/spack.yml
================================================
name: Spack install
on:
# Uncomment the below 'push' to trigger on push
# push:
# branches:
# - "**"
schedule:
# '*' is a special character in YAML, so string must be quoted
- cron: "0 2 * * SUN"
workflow_dispatch:
inputs:
spack_package_repo:
description: "Spack package repository to test"
default: "spack/spack-packages"
type: string
spack_package_ref:
description: "Spack package repository branch/tag to test"
default: "develop"
type: string
ffcx_version:
description: "Spack build tag"
default: "main"
type: string
jobs:
build:
runs-on: ubuntu-latest
container: ubuntu:latest
steps:
- name: Install Spack requirements
run: |
apt-get -y update
apt-get install -y bzip2 curl file git gzip make patch python3-minimal tar xz-utils
apt-get install -y g++ gfortran # compilers
- name: Get Spack
uses: actions/checkout@v6
with:
path: ./spack
repository: spack/spack
- name: Get Spack packages
if: github.event_name == 'workflow_dispatch'
run: |
. ./spack/share/spack/setup-env.sh
spack repo update
spack repo add --name test_pkgs https://github.com/${{ github.event.inputs.spack_package_repo }}.git ~/test_pkgs
spack repo update --branch ${{ github.event.inputs.spack_package_ref }} test_pkgs
spack repo list
spack config get repos
- name: Install FFCx and run tests
if: github.event_name != 'workflow_dispatch'
run: |
. ./spack/share/spack/setup-env.sh
spack env create ffcx-main
spack env activate ffcx-main
spack add py-fenics-ffcx@main
spack install
- name: Install FFCx and run tests
if: github.event_name == 'workflow_dispatch'
run: |
. ./spack/share/spack/setup-env.sh
spack env create ffcx-testing
spack env activate ffcx-testing
spack add py-fenics-ffcx@${{ github.event.inputs.ffcx_version }}
spack install
================================================
FILE: .gitignore
================================================
# Compiled source
*.o
*.Plo
*.Po
*.lo
*.la
*.a
*.os
*.pyc
*.so
*.pc
*.pyc
*.pyd
*.def
*.dll
*.exe
*.dylib
# Files generated by setup
/ffcx/git_commit_hash.py
# CMake and Make files
CMakeCache.txt
CMakeFiles
cmake_install.cmake
cmake_uninstall.cmake
Makefile
install_manifest.txt
/cmake/templates/UFCConfig.cmake
/cmake/templates/UFCConfigVersion.cmake
/cmake/templates/UseUFC.cmake
# Temporaries
*~
# OS X files
.DS_Store
.DS_Store?
# Local build files
/build
/bench/bench.log
/doc/sphinx/build
/doc/sphinx/source/api-doc
# Visual Studio Code project config
.vscode
# c, h and so files due to running demos
demo/*.c
demo/*.h
demo/*.so
test/*.c
test/*.h
test/*.so
# Tests
**/.cache/
__pycache__
test/compile-cache/
test/libffcx_*
test/*.pdf
# setuptools temps
*.egg-info/
# Release
/dist
/release
.*.swp
================================================
FILE: AUTHORS
================================================
Credits for FFC
===============
Main authors:
Anders Logg
email: logg@simula.no
www: http://home.simula.no/~logg/
Kristian B. Ølgaard
email: k.b.oelgaard@gmail.com
Marie Rognes
email: meg@simula.no
Main contributors:
Garth N. Wells
email: gnw20@cam.ac.uk
www: http://www.eng.cam.ac.uk/~gnw20/
Martin Sandve Alnæs
email: martinal@simula.no
Contributors:
Jan Blechta
email: blechta@karlin.mff.cuni.cz
Peter Brune
email: brune@uchicago.edu
Joachim B Haga
email: jobh@broadpark.no
Johan Jansson
email: johanjan@math.chalmers.se
www: http://www.math.chalmers.se/~johanjan/
Robert C. Kirby
email: kirby@cs.uchicago.edu
www: http://people.cs.uchicago.edu/~kirby/
Matthew G. Knepley
email: knepley@mcs.anl.gov
www: http://www-unix.mcs.anl.gov/~knepley/
Dag Lindbo
email: dag@f.kth.se
www: http://www.f.kth.se/~dag/
Ola Skavhaug
email: skavhaug@simula.no
www: http://home.simula.no/~skavhaug/
Andy R. Terrel
email: aterrel@uchicago.edu
www: http://people.cs.uchicago.edu/~aterrel/
Ivan Yashchuk
email: ivan.yashchuk@aalto.fi
Matthew Scroggs
email: matthew.scroggs.14@ucl.ac.uk
www: https://mscroggs.co.uk
Credits for UFC
===============
UFC was merged into FFC 2014-02-18. Below is the list of credits for
UFC at the time of the merge.
Main authors:
Martin Sandve Alnaes <martinal@simula.no>
Anders Logg <logg@simula.no>
Kent-Andre Mardal <kent-and@simula.no
Ola Skavhaug <skavhaug@simula.no>
Hans Petter Langtangen <hpl@simula.no>
Main contributors:
Asmund Odegard <aasmund@simula.no>
Kristian Oelgaard <k.b.oelgaard@tudelft.nl>
Johan Hake <hake@simula.no>
Garth N. Wells <gnw20@cam.ac.uk>
Marie E. Rognes <meg@simula.no>
Johannes Ring <johannr@simula.no>
Credits for UFLACS
==================
UFLACS was merged into FFC 2016-02-16.
Author:
Martin Sandve Alnæs <martinal@simula.no>
Contributors:
Anders Logg <logg@chalmers.se>
Garth N. Wells <gnw20@cam.ac.uk>
Johannes Ring <johannr@simula.no>
Matthias Liertzer <matthias@liertzer.at>
Steffen Müthing <steffen.muething@ipvs.uni-stuttgart.de>
================================================
FILE: CODE_OF_CONDUCT.md
================================================
Code of Conduct
===============
Our Pledge
----------
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our
project and our community a harassment-free experience for everyone,
regardless of age, body size, disability, ethnicity, sex
characteristics, gender identity and expression, level of experience,
education, socio-economic status, nationality, personal appearance,
race, religion, or sexual identity and orientation.
Our Standards
-------------
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others’ private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
Our Responsibilities
--------------------
Project maintainers are responsible for clarifying the standards of
acceptable behavior and are expected to take appropriate and fair
corrective action in response to any instances of unacceptable
behavior.
Project maintainers have the right and responsibility to remove, edit,
or reject comments, commits, code, wiki edits, issues, and other
contributions that are not aligned to this Code of Conduct, or to ban
temporarily or permanently any contributor for other behaviors that
they deem inappropriate, threatening, offensive, or harmful.
Scope
-----
This Code of Conduct applies both within project spaces and in public
spaces when an individual is representing the project or its
community. Examples of representing a project or community include
using an official project e-mail address, posting via an official
social media account, or acting as an appointed representative at an
online or offline event. Representation of a project may be further
defined and clarified by project maintainers.
Enforcement
-----------
Instances of abusive, harassing, or otherwise unacceptable behavior
may be reported by contacting the project team at
fenics-steering-council@googlegroups.com. Alternatively, you may
report individually to one of the members of the Steering
Council. Complaints will be reviewed and investigated and will result
in a response that is deemed necessary and appropriate to the
circumstances. The project team is obligated to maintain
confidentiality with regard to the reporter of an incident. Further
details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct
in good faith may face temporary or permanent repercussions as
determined by other members of the project’s leadership.
If you feel that your report has not been followed up satisfactorily,
then you may contact our parent organisation NumFOCUS at
info@numfocus.org for further redress.
Attribution
-----------
This Code of Conduct is adapted from the Contributor Covenant, version
1.4, available at
https://www.contributor-covenant.org/version/1/4/code-of-conduct.html.
Adaptations
-----------
* Allow reporting to individual Steering Council members
* Added the option to contact NumFOCUS for further redress.
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
================================================
FILE: COPYING
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
================================================
FILE: COPYING.LESSER
================================================
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
================================================
FILE: ChangeLog.rst
================================================
Changelog
=========
0.6.0
-----
See https://github.com/FEniCS/ffcx/compare/v0.5.0...v0.6.0
0.5.0
-----
See: https://github.com/FEniCS/ffcx/compare/v0.5.0...v0.4.0
0.4.0
-----
See: https://github.com/FEniCS/ffcx/compare/v0.4.0...v0.3.0
0.3.0
-----
See: https://github.com/FEniCS/ffcx/compare/v0.3.0...v0.2.0
0.2.0
-----
- No changes
0.1.0
-----
Alpha release of ffcx
2018.2.0.dev0
-------------
- No changes
2018.1.0.dev0 (no release)
--------------------------
- Forked FFCx
2017.2.0 (2017-12-05)
---------------------
- Some fixes for ufc::eval for esoteric element combinations
- Reimplement code generation for all ufc classes with new class
ufc::coordinate_mapping which can map between coordinates, compute
jacobians, etc. for a coordinate mapping parameterized by a specific
finite element.
- New functions in ufc::finite_element:
- evaluate_reference_basis
- evaluate_reference_basis_derivatives
- transform_reference_basis_derivatives
- tabulate_reference_dof_coordinates
- New functions in ufc::dofmap:
- num_global_support_dofs
- num_element_support_dofs
- Improved docstrings for parts of ufc.h
- FFC now accepts Q and DQ finite element families defined on quadrilaterals and hexahedrons
- Some fixes for ufc_geometry.h for quadrilateral and hexahedron cells
2017.1.0.post2 (2017-09-12)
---------------------------
- Change PyPI package name to fenics-ffc.
2017.1.0 (2017-05-09)
---------------------
- Let ffc -O parameter take an optional integer level like -O2, -O0
- Implement blockwise optimizations in uflacs code generation
- Expose uflacs optimization parameters through parameter system
2016.2.0 (2016-11-30)
---------------------
- Jit compiler now compiles elements separately from forms to avoid duplicate work
- Add parameter max_signature_length to optionally shorten signatures in the jit cache
- Move uflacs module into ffc.uflacs
- Remove installation of pkg-config and CMake files (UFC path and
compiler flags are available from ffc module)
- Add dependency on dijitso and remove dependency on instant
- Add experimental Bitbucket pipelines
- Tidy the repo after UFC and UFLACS merge, and general spring cleanup. This
includes removal of instructions how to merge two repos, commit hash
c8389032268041fe94682790cb773663bdf27286.
2016.1.0 (2016-06-23)
---------------------
- Add function get_ufc_include to get path to ufc.h
- Merge UFLACS into FFC
- Generalize ufc interface to non-affine parameterized coordinates
- Add ufc::coordinate_mapping class
- Make ufc interface depend on C++11 features requiring gcc version >= 4.8
- Add function ufc_signature() to the form compiler interface
- Add function git_commit_hash()
1.6.0 (2015-07-28)
------------------
- Rename and modify a number of UFC interface functions. See docstrings in ufc.h for details.
- Bump required SWIG version to 3.0.3
- Disable dual basis (tabulate_coordinates and evaluate_dofs) for enriched
elements until correct implementation is brought up
1.5.0 (2015-01-12)
------------------
- Remove FErari support
- Add support for new integral type custom_integral
- Support for new form compiler backend "uflacs", downloaded separately
1.4.0 (2014-06-02)
------------------
- Add support for integrals that know which coefficients they use
- Many bug fixes for facet integrals over manifolds
- Merge UFC into FFC; ChangeLog for UFC appended below
- Various updates mirroring UFL changes
- Experimental: New custom integral with user defined quadrature points
1.3.0 (2014-01-07)
------------------
- Fix bug with runtime check of SWIG version
- Move DOLFIN wrappers here from DOLFIN
- Add support for new UFL operators cell_avg and facet_avg
- Add new reference data handling system, now data is kept in an external repository
- Fix bugs with ignoring quadrature rule arguments
- Use cpp optimization by default in jit compiler
1.2.0 (2013-03-24)
------------------
- New feature: Add basic support for point integrals on vertices
- New feature: Add general support for m-dimensional cells in n-dimensional space (n >= m, n, m = 1, 2, 3)
1.1.0 (2013-01-07)
------------------
- Fix bug for Conditionals related to DG constant Coefficients. Bug #1082048.
- Fix bug for Conditionals, precedence rules for And and Or. Bug #1075149.
- Changed data structure from list to deque when pop(0) operation is needed, speeding up split_expression operation considerable
- Other minor fixes
1.0.0 (2011-12-07)
------------------
- Issue warning when form integration requires more than 100 points
1.0-rc1 (2011-11-28)
--------------------
- Fix bug with coordinates on facet integrals (intervals). Bug #888682.
- Add support for FacetArea, new geometric quantity in UFL.
- Fix bug in optimised quadrature code, AlgebraOperators demo. Bug #890859.
- Fix bug with undeclared variables in optimised quadrature code. Bug #883202.
1.0-beta2 (2011-10-11)
----------------------
- Added support for bessel functions, bessel_* (I,J,K,Y), in UFL.
- Added support for error function, erf(), new math function in UFL.
- Fix dof map 'need_entities' for Real spaces
- Improve performance for basis function computation
1.0-beta (2011-08-11)
---------------------
- Improve formatting of floats with up to one non-zero decimal place.
- Fix bug involving zeros in products and sums. Bug #804160.
- Fix bug for new conditions '&&', '||' and '!' in UFL. Bug #802560.
- Fix bug involving VectorElement with dim=1. Bug #798578.
- Fix bug with mixed element of symmetric tensor elements. Bug #745646.
- Fix bug when using geometric coordinates with one quadrature point
0.9.10 (2011-05-16)
-------------------
- Change license from GPL v3 or later to LGPL v3 or later
- Add some schemes for low-order simplices
- Request quadrature schemes by polynomial degree (not longer by number
of points in each direction)
- Get quadrature schemes via ffc.quadrature_schemes
- Improved lock handling in JIT compiler
- Include common_cell in form signature
- Add possibility to set swig binary and swig path
0.9.9 (2011-02-23)
------------------
- Add support for generating error control forms with option -e
- Updates for UFC 2.0
- Set minimal degree to 1 in automatic degree selection for expressions
- Add command-line option -f no_ferari
- Add support for plotting of elements
- Add utility function compute_tensor_representation
0.9.4 (2010-09-01)
------------------
- Added memory cache in jit(), for preprocessed forms
- Added support for Conditional and added demo/Conditional.ufl.
- Added support for new geometric quantity Circumradius in UFL.
- Added support for new geometric quantity CellVolume in UFL.
0.9.3 (2010-07-01)
------------------
- Make global_dimension for Real return an int instead of double, bug # 592088
- Add support for facet normal in 1D.
- Expose -feliminate_zeros for quadrature optimisations to give user more
control
- Remove return of form in compile_form
- Remove object_names argument to compile_element
- Rename ElementUnion -> EnrichedElement
- Add support for tan() and inverse trigonometric functions
- Added support for ElementUnion (i.e. span of combinations of elements)
- Added support for Bubble elements
- Added support for UFL.SpatialCoordinate.
0.9.2 (2010-02-17)
------------------
- Bug fix in removal of unused variables in Piola-mapped terms for tensor
representation
0.9.1 (2010-02-15)
------------------
- Add back support for FErari optimizations
- Bug fixes in JIT compiler
0.9.0 (2010-02-02)
------------------
- Updates for FIAT 0.9.0
- Updates for UFC 1.4.0 (now supporting the full interface)
- Automatic selection of representation
- Change quadrature_order --> quadrature_degree
- Split compile() --> compile_form(), compile_element()
- Major cleanup and reorganization of code (flatter directories)
- Updates for changes in UFL: Argument, Coefficient, FormData
0.7.1
-----
- Handle setting quadrature degree when it is set to None in UFL form
- Added demo: HyperElasticity.ufl
0.7.0
-----
- Move contents of TODO to: https://blueprints.launchpad.net/ffc
- Support for restriction of finite elements to only consider facet dofs
- Use quadrature_order from metadata when integrating terms using tensor representation
- Use loop to reset the entries of the local element tensor
- Added new symbolic classes for quadrature optimisation (speed up compilation)
- Added demos: Biharmonic.ufl, div(grad(v)) term;
ReactionDiffusion.ufl, tuple notation;
MetaData.ufl, how to attach metadata to the measure;
ElementRestriction.ufl, restriction of elements to facets
- Tabulate the coordinates of the integration points in the tabulate_tensor() function
- Change command line option '-f split_implementation' -> '-f split'
- Renaming of files and restructuring of the compiler directory
- Added option -q rule (--quadrature-rule rule) to specify which rule to use
for integration of a given integral. (Can also bet set through the metadata
through "quadrature_rule"). No rules have yet been implemented, so default
is the FIAT rule.
- Remove support for old style .form files/format
0.6.2 (2009-04-07)
------------------
- Experimental support for UFL, supporting both .form and .ufl
- Moved configuration and construction of python extension module to ufc_module
0.6.1 (2009-02-18)
------------------
- Initial work on UFL transition
- Minor bug fixes
- The version of ufc and swig is included in the form signature
- Better system configuration for JIT compiled forms
- The JIT compiled python extension module use shared_ptr for all classes
0.6.0 (2009-01-05)
------------------
- Update DOLFIN output format (-l dolfin) for DOLFIN 0.9.0
- Cross-platform fixes for test scripts
- Minor bug fix for quadrature code generation (forms affected by this bug would not be able to compile
- Fix bug with output of ``*.py``.
- Permit dot product bewteen rectangular matrices (Frobenius norm)
0.5.1 (2008-10-20)
------------------
- New operator skew()
- Allow JIT compilation of elements and dof maps
- Rewrite JIT compiler to rely on Instant for caching
- Display flop count for evaluating the element tensor during compilation
- Add arguments language and representation to options dictionary
- Fix installation on Windows
- Add option -f split_implementation for separate .h and .cpp files
0.5.0 (2008-06-23)
------------------
- Remove default restriction +/- for Constant
- Make JIT optimization (-O0 / -O2) optional
- Add in-memory cache to speed up JIT compiler for repeated assembly
- Allow subdomain integrals without needing full range of integrals
- Allow simple subdomain integral specification dx(0), dx(1), ds(0) etc
0.4.5 (2008-04-30)
------------------
- Optimizations in generated quadrature code
- Change formatting of floats from %g to %e, fixes problem with too long integers
- Bug fix for order of values in interpolate_vertex_values, now according to UFC
- Speed up JIT compiler
- Add index ranges to form printing
- Throw runtime error in functions not generated
- Update DOLFIN format for new location of include files
0.4.4 (2008-02-18)
------------------
- RT, BDM, BDFM and Nedelec now working in 2D and 3D
- New element type QuadratureElement
- Add support for 1D elements
- Add experimental support for new Darcy-Stokes element
- Use FIAT transformed spaces instead of mapping in FFC
- Updates for UFC 1.1
- Implement caching of forms/modules in ~/.ffc/cache for JIT compiler
- Add script ffc-clean
- New operators lhs() and rhs()
- Bug fixes in simplify
- Bug fixes for Nedelec and BDFM
- Fix bug in mult()
- Fix bug with restrictions on exterior facet integrals
- Fix bug in grad() for vectors
- Add divergence operator for matrices
0.4.3 (2007-10-23)
------------------
- Require FIAT to use UFC reference cells
- Fix bug in form simplification
- Rename abs --> modulus to avoid conflict with builtin abs
- Fix bug in operators invert, abs, sqrt
- Fix bug in integral tabulation
- Add BDFM and Nedelec elements (nonworking)
- Fix bug in JIT compiler
0.4.2 (2007-08-31)
------------------
- Change license from GPL v2 to GPL v3 or later
- Add JIT (just-in-time) compiler
- Fix bug for constants on interior facets
0.4.1 (2007-06-22)
------------------
- Fix bug in simplification of forms
- Optimize removal of unused terms in code formattting
0.4.0 (2007-06-20)
------------------
- Move to UFC interface for code generation
- Major rewrite, restructure, cleanup
- Add support for Brezzi-Douglas-Marini (BDM) elements
- Add support for Raviart-Thomas (RT) elements
- Add support for Discontinuous Galerkin (DG) methods
- Operators jump() and avg()
- Add quadrature compilation mode (experimental)
- Simplification of forms
- Operators sqrt(), abs() and inverse
- Improved Python interface
- Add flag -f precision=n
- Generate code for basis functions and derivatives
- Use Set from set module for Python2.3 compatibility
0.3.5 (2006-12-01)
------------------
- Bug fixes
- Move from Numeric to numpy
0.3.4 (2006-10-27)
------------------
- Updates for new DOLFIN mesh library
- Add support for evaluation of functionals
- Add operator outer() for outer product of vector-valued functions
- Enable optimization of linear forms (in addition to bilinear forms)
- Remove DOLFIN SWIG format
- Fix bug in ffc -v/--version (thanks to Ola Skavhaug)
- Consolidate DOLFIN and DOLFIN SWIG formats (patch from Johan Jansson)
- Fix bug in optimized compilation (-O) for some forms ("too many values to unpack")
0.3.3 (2006-09-05)
------------------
- Fix bug in operator div()
- Add operation count (number of multiplications) with -d0
- Add hint for printing more informative error messages (flag -d1)
- Modify implementation of vertexeval()
- Add support for boundary integrals (Garth N. Wells)
0.3.2 (2006-04-01)
------------------
- Add support for FErari optimizations, new flag -O
0.3.1 (2006-03-28)
------------------
- Remove verbose output: silence means success
- Generate empty boundary integral eval() to please Intel C++ compiler
- New classes TestFunction and TrialFunction
0.3.0 (2006-03-01)
------------------
- Work on manual, document command-line and user-interfaces
- Name change: u --> U
- Add compilation of elements without form
- Add generation of FiniteElementSpec in DOLFIN formats
- Fix bugs in raw and XML formats
- Fix bug in LaTeX format
- Fix path and predefine tokens to enable import in .form file
- Report number of entries in reference tensor during compilation
0.2.5 (2005-12-28)
------------------
- Add demo Stabilization.form
- Further speedup computation of reference tensor (use ufunc Numeric.add)
0.2.4 (2005-12-05)
------------------
- Report time taken to compute reference tensor
- Restructure computation of reference tensor to use less memory.
As a side effect, the speed has also been improved.
- Update for DOLFIN name change node --> vertex
- Update finite element interface for DOLFIN
- Check for FIAT bug in discontinuous vector Lagrange elements
- Fix signatures for vector-valued elements
0.2.3 (2005-11-28)
------------------
- New fast Numeric/BLAS based algorithm for computing reference tensor
- Bug fix: reassign indices for complete subexpressions
- Bug fix: operator Function * Integral
- Check tensor notation for completeness
- Bug fix: mixed elements with more than two function spaces
- Don't declare unused coefficients (or gcc will complain)
0.2.2 (2005-11-14)
------------------
- Add command-line argument -v / --version
- Add new operator mean() for projection onto piecewise constants
- Add support for projections
- Bug fix for higher order mixed elements: declaration of edge/face_ordering
- Generate code for sub elements of mixed elements
- Add new test form: TensorWeighteLaplacian
- Add new test form: EnergyNorm
- Fix bugs in mult() and vec() (skavhaug)
- Reset correct entries of G for interior in BLAS mode
- Only assign to entries of G that meet nonzero entries of A in BLAS mode
0.2.1 (2005-10-11)
------------------
- Only generate declarations that are needed according to format
- Check for missing options and add missing default options
- Simplify usage of FFC as Python module: from ffc import *
- Fix bug in division with constants
- Generate output for BLAS (with option -f blas)
- Add new XML output format
- Remove command-line option --license (collect in compiler options -f)
- Modify demo Mass.form to use 3:rd order Lagrange on tets
- Fix bug in dofmap() for equal order mixed elements
- Add compiler option -d debuglevel
- Fix Python Numeric bug: vdot --> dot
0.2.0 (2005-09-23)
------------------
- Generate function vertexeval() for evaluation at vertices
- Add support for arbitrary mixed elements
- Add man page
- Work on manual, chapters on form language, quickstart and installation
- Handle exceptions gracefully in command-line interface
- Use new template fenicsmanual.cls for manual
- Add new operators grad, div, rot (curl), D, rank, trace, dot, cross
- Factorize common reference tensors from terms with equal signatures
- Collect small building blocks for form algebra in common module tokens.py
0.1.9 (2005-07-05)
------------------
- Complete support for general order Lagrange elements on triangles and tetrahedra
- Compute reordering of dofs on tets correctly
- Update manual with ordering of dofs
- Break compilation into two phases: build() and write()
- Add new output format ASE (Matt Knepley)
- Improve python interface to FFC
- Remove excessive logging at compilation
- Fix bug in raw output format
0.1.8 (2005-05-17)
------------------
- Access data through map in DOLFIN format
- Experimental support for computation of coordinate maps
- Add first draft of manual
- Experimental support for computation of dof maps
- Allow specification of the number of components for vector Lagrange
- Count the number of zeros dropped
- Fix bug in handling command-line arguments
- Use module sets instead of built-in set (fix for Python 2.3)
- Handle constant indices correctly (bug reported by Garth N. Wells)
0.1.7 (2005-05-02)
------------------
- Write version number to output
- Add command-line option for choosing license
- Display usage if no input is given
- Bug fix for finding correct prefix of file name
- Automatically choose name of output file (if not supplied)
- Use FIAT tabulation mode for vector-valued elements (speedup a factor 5)
- Use FIAT tabulation mode for scalar elements (speedup a factor 1000)
- Fig bug in demo elasticity.form (change order of u and v)
- Make references to constants const in DOLFIN format
- Don't generate code for unused entries of geometry tensor
- Update formats to write numeric constants with full precision
0.1.6 (2005-03-17)
------------------
- Add support for mixing multiple different finite elements
- Add support for division with constants
- Fix index bug (reverse order of multi-indices)
0.1.5 (2005-03-14)
------------------
- Automatically choose the correct quadrature rule for precomputation
- Add test program for verification of FIAT quadrature rules
- Fix bug for derivative of sum
- Improve common interface for debugging: add indentation
- Add support for constants
- Fix bug for sums of more than one term (make copies of references in lists)
- Add '_' in naming of geometry tensor (needed for large dimensions)
- Add example elasticity.form
- Cleanup build_indices()
0.1.4-1 (2005-02-07)
--------------------
- Fix version number and remove build directory from tarball
0.1.4 (2005-02-04)
------------------
- Fix bug for systems, seems to work now
- Add common interface for debugging
- Modify DOLFIN output to initialize functions
- Create unique numbers for each function
- Use namespaces for DOLFIN output instead of class names
- Temporary implementation of dof mapping for vector-valued elements
- Make DOLFIN output format put entries into PETSc block
- Change name of coefficient data: c%d[%d] -> c[%d][%d]
- Change ordering of basis functions (one component at a time)
- Add example poissonsystem.form
- Modifications for new version of FIAT (FIAT-L)
FIAT version 0.1 a factor 5 slower (no memoization)
FIAT version 0.1.1 a little faster, only a factor 2 slower
- Add setup.py script
0.1.3 (2004-12-06)
------------------
- Fix bug in DOLFIN format (missing value when zero)
- Add output of reference tensor to LaTeX format
- Make raw output format print data with full precision
- Add component diagram
- Change order of declaration of basis functions
- Add new output format raw
0.1.2 (2004-11-17)
------------------
- Add command-line interface ffc
- Add support for functions (coefficients)
- Add support for constants
- Allow multiple forms (left- and right-hand side) in same file
- Add test examples: poisson.form, mass.form, navierstokes.form
- Wrap FIAT to create vector-valued finite element spaces
- Check ranks of operands
- Clean up algebra, add base class Element
- Add some documentation (class diagram)
- Add support for LaTeX output
0.1.1-1 (2004-11-10)
--------------------
- Add missing file declaration.py
0.1.1 (2004-11-10)
------------------
- Make output variable names configurable
- Clean up DOLFIN code generation
- Post-process form to create reference, geometry, and element tensors
- Experimental support for general tensor-valued elements
- Clean up and improve index reassignment
- Use string formatting for generation of output
- Change index ordering to access row-wise
0.1.0 (2004-10-22)
------------------
- First iteration of the FEniCS Form Compiler
- Change boost::shared_ptr --> std::shared_ptr
ChangeLog for UFC
=================
UFC was merged into FFC 2014-02-18. Below is the ChangeLog for
UFC at the time of the merge. From this point onward, UFC version
numbering restarts at the same version number as FFC and the rest
of FEniCS.
2.3.0 (2014-01-07)
------------------
- Use std::vector<std::vector<std::size_t> > for topology data
- Remove vertex coordinates from ufc::cell
- Improve detection of compatible Python libraries
- Add current swigversion to the JIT compiled extension module
- Remove dofmap::max_local_dimension()
- Remove cell argument from dofmap::local_dimension()
2.2.0 (2013-03-24)
------------------
- Add new class ufc::point_integral
- Use CMake to configure JIT compilation of forms
- Generate UseUFC.cmake during configuration
- Remove init_mesh(), init_cell(), init_mesh_finalize()
- Remove ufc::mesh and add a vector of num_mesh_entities to global_dimension() and tabulate_dofs().
2.1.0 (2013-01-07)
------------------
- Fix bug introduced by SWIG 2.0.5, which treated uint as Python long
- Add optimization SWIG flags, fixing bug lp:987657
2.0.5 (2011-12-07)
------------------
- Improve configuration of libboost-math
2.0.4 (2011-11-28)
------------------
- Add boost_math_tr1 to library flags when JIT compiling an
extension module
2.0.3 (2011-10-26)
------------------
- CMake config improvements
2.0.2 (2011-08-11)
------------------
- Some tweaks of installation
2.0.1 (2011-05-16)
------------------
- Make SWIG version >= 2.0 a requirement
- Add possibility to set swig binary and swig path
- Add missing const for map_{from,to}_reference_cell
2.0.0 (2011-02-23)
------------------
- Add quadrature version of tabulate_tensor
- Add finite_element::map_{from,to}_reference_cell
- Add finite_element::{topological,geometric}_dimension
- Add dofmap::topological_dimension
- Rename num_foo_integrals --> num_foo_domains
- Rename dof_map --> dofmap
- Add finite_element::create
- Add dofmap::create
1.4.2 (2010-09-01)
------------------
- Move to CMake build system
1.4.1 (2010-07-01)
------------------
- Make functions introduced in UFC 1.1 mandatory (now pure virtual)
- Update templates to allow constructor arguments in form classes
1.4.0 (2010-02-01)
------------------
- Changed behavior of create_foo_integral (returning 0 when integral is 0)
- Bug fixes in installation
1.2.0 (2009-09-23)
------------------
- Add new function ufc::dof_map::max_local_dimension()
- Change ufc::dof_map::local_dimension() to ufc::dof_map::local_dimension(const ufc::cell c)
1.1.2 (2009-04-07)
------------------
- Added configuration and building of python extension module to ufc_utils.build_ufc_module
1.1.1 (2009-02-20)
------------------
- The extension module is now not built, if the conditions for shared_ptr are not met
- Added SCons build system
- The swig generated extension module will be compiled with shared_ptr support if boost is found on system and swig is of version 1.3.35 or higher
- The swig generated extension module is named ufc.py and expose all ufc base classes to python
- Added a swig generated extention module to ufc. UFC now depends on swig
- Changed name of the python utility module from "ufc" to "ufc_utils"
1.1.0 (2008-02-18)
------------------
- Add new function ufc::finite_element::evaluate_dofs
- Add new function ufc::finite_element::evaluate_basis_all
- Add new function ufc::finite_element::evaluate_basis_derivatives_all
- Add new function ufc::dof_map::geometric_dimension
- Add new function ufc::dof_map::num_entity_dofs
- Add new function ufc::dof_map::tabulate_entity_dofs
1.0.0 (2007-06-17)
------------------
- Release of UFC 1.0
================================================
FILE: LICENSE
================================================
The header file ufcx.h is released using the UNLICENSE. See UNLICENSE for the
license text.
------------------------------------------------------------------------------
Other files, unless stated otherwise in their head, are licensed by GNU Lesser
General Public License, version 3, or later. See COPYING and COPYING.LESSER for
the license text.
================================================
FILE: MANIFEST.in
================================================
include AUTHORS
include COPYING
include COPYING.LESSER
include ChangeLog.rst
include INSTALL
include LICENSE
include ffcx/codegeneration/ufcx.h
recursive-include cmake *
recursive-include demo *
recursive-include doc *
recursive-include ffcx *.in
recursive-include libs *
recursive-include test *
global-exclude __pycache__ *.pyc
================================================
FILE: README.md
================================================
# FFCx: The FEniCSx Form Compiler
[](https://github.com/FEniCS/ffcx/actions/workflows/pythonapp.yml)
[](https://github.com/FEniCS/ffcx/actions/workflows/spack.yml)
[](https://coveralls.io/github/FEniCS/ffcx?branch=main)
FFCx is a new version of the FEniCS Form Compiler. It is being actively
developed and is compatible with DOLFINx.
FFCx is a compiler for finite element variational forms. From a
high-level description of the form in the Unified Form Language (UFL),
it generates efficient low-level C code that can be used to assemble the
corresponding discrete operator (tensor). In particular, a bilinear form
may be assembled into a matrix and a linear form may be assembled into a
vector. FFCx may be used either from the command line (by invoking the
`ffcx` command) or as a Python module (`import ffcx`).
FFCx is part of the FEniCS Project. For more information, visit
https://www.fenicsproject.org
## Installation
To install FFCx from PyPI:
```
$ pip install fenics-ffcx
```
To install FFCx from the source directory:
```
$ pip install .
```
## Documentation
Documentation can be viewed at https://docs.fenicsproject.org/ffcx/main
## Interface file installation only
FFCx provides the `ufcx.h` interface header for finite element kernels,
used by DOLFINx. `ufcx.h` is installed by FFCx within the Python site
packages, but it is sometimes helpful to install only the header file.
This can be done using `cmake`:
```
$ cmake -B build-dir -S cmake/
$ cmake --build build-dir
$ cmake --install build-dir
```
## License
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
================================================
FILE: UNLICENSE
================================================
The software in the file ufcx.h is free and unencumbered software released into
the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
commercial or non-commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
this software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <https://unlicense.org>
================================================
FILE: _clang-format
================================================
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: false
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: true
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
BreakBeforeBinaryOperators: All
BreakBeforeBraces: Allman
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '$'
IndentCaseLabels: false
IndentWidth: 2
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 8
UseTab: Never
...
================================================
FILE: cmake/CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.19)
# Development version: x.x.x.0
# Release version: x.x.x
project(ufcx VERSION 0.11.0.0 DESCRIPTION "UFCx interface header for finite element kernels"
LANGUAGES C
HOMEPAGE_URL https://github.com/fenics/ffcx)
include(GNUInstallDirs)
file(SHA1 ${PROJECT_SOURCE_DIR}/../ffcx/codegeneration/ufcx.h UFCX_HASH)
message("Test hash: ${UFCX_HASH}")
add_library(${PROJECT_NAME} INTERFACE)
target_compile_features(${PROJECT_NAME} INTERFACE c_std_17)
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
target_include_directories(${PROJECT_NAME}
INTERFACE $<BUILD_INTERFACE:${${PROJECT_NAME}_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
# Prepare and install CMake target/config files
install(TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}_Targets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
include(CMakePackageConfigHelpers)
write_basic_package_version_file("${PROJECT_NAME}ConfigVersion.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion)
configure_package_config_file("${PROJECT_NAME}Config.cmake.in" "${PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)
install(EXPORT ${PROJECT_NAME}_Targets FILE ${PROJECT_NAME}Targets.cmake
NAMESPACE ${PROJECT_NAME}::
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)
install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)
# Install header file
install(FILES ${PROJECT_SOURCE_DIR}/../ffcx/codegeneration/ufcx.h TYPE INCLUDE)
# Configure and install pkgconfig file
configure_file(ufcx.pc.in ufcx.pc @ONLY)
install(FILES ${PROJECT_BINARY_DIR}/ufcx.pc DESTINATION ${CMAKE_INSTALL_DATADIR}/pkgconfig)
================================================
FILE: cmake/ufcx.pc.in
================================================
prefix="@CMAKE_INSTALL_PREFIX@"
exec_prefix="${prefix}"
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
definitions=@
Name: @PROJECT_NAME@
Description: @CMAKE_PROJECT_DESCRIPTION@
URL: @CMAKE_PROJECT_HOMEPAGE_URL@
Version: @PROJECT_VERSION@
Cflags: -I"${includedir}"
Libs:
================================================
FILE: cmake/ufcxConfig.cmake.in
================================================
@PACKAGE_INIT@
set(UFCX_SIGNATURE @UFCX_HASH@)
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
check_required_components("@PROJECT_NAME@")
================================================
FILE: demo/BiharmonicHHJ.py
================================================
# Copyright (C) 2016 Lizao Li
"""Biharmonis HHJ demo.
The bilinear form a(u, v) and linear form L(v) for Biharmonic equation
in Hellan-Herrmann-Johnson (HHJ) formulation.
"""
import basix.ufl
from ufl import (
Coefficient,
FacetNormal,
FunctionSpace,
Mesh,
TestFunctions,
TrialFunctions,
dot,
dS,
ds,
dx,
grad,
inner,
jump,
)
HHJ = basix.ufl.element("HHJ", "triangle", 2)
P = basix.ufl.element("P", "triangle", 3)
mixed_element = basix.ufl.mixed_element([HHJ, P])
domain = Mesh(basix.ufl.element("P", "triangle", 1, shape=(2,)))
mixed_space = FunctionSpace(domain, mixed_element)
p_space = FunctionSpace(domain, P)
(sigma, u) = TrialFunctions(mixed_space)
(tau, v) = TestFunctions(mixed_space)
f = Coefficient(p_space)
def b(sigma, v):
"""The form b."""
n = FacetNormal(domain)
return (
inner(sigma, grad(grad(v))) * dx
- dot(dot(sigma("+"), n("+")), n("+")) * jump(grad(v), n) * dS
- dot(dot(sigma, n), n) * dot(grad(v), n) * ds
)
a = inner(sigma, tau) * dx - b(tau, u) + b(sigma, v)
L = f * v * dx
================================================
FILE: demo/BiharmonicRegge.py
================================================
# Copyright (C) 2016 Lizao Li
"""Biharmonic Regge demo.
The bilinear form a(u, v) and linear form L(v) for Biharmonic equation in Regge formulation.
"""
import basix.ufl
from ufl import (
Coefficient,
FacetNormal,
FunctionSpace,
Identity,
Mesh,
TestFunctions,
TrialFunctions,
dot,
dS,
ds,
dx,
grad,
inner,
jump,
tr,
)
REG = basix.ufl.element("Regge", "tetrahedron", 1)
P = basix.ufl.element("Lagrange", "tetrahedron", 2)
mixed_element = basix.ufl.mixed_element([REG, P])
domain = Mesh(basix.ufl.element("P", "tetrahedron", 1, shape=(3,)))
mixed_space = FunctionSpace(domain, mixed_element)
p_space = FunctionSpace(domain, P)
(sigma, u) = TrialFunctions(mixed_space)
(tau, v) = TestFunctions(mixed_space)
f = Coefficient(p_space)
def S(mu):
"""The form S."""
return mu - Identity(3) * tr(mu)
def b(mu, v):
"""The form b."""
n = FacetNormal(domain)
return (
inner(S(mu), grad(grad(v))) * dx
- dot(dot(S(mu("+")), n("+")), n("+")) * jump(grad(v), n) * dS
- dot(dot(S(mu), n), n) * dot(grad(v), n) * ds
)
a = inner(S(sigma), S(tau)) * dx - b(tau, u) + b(sigma, v)
L = f * v * dx
================================================
FILE: demo/CellGeometry.py
================================================
# Copyright (C) 2013 Martin S. Alnaes
"""Cell geometry demo.
A functional M involving a bunch of cell geometry quantities.
"""
import basix.ufl
from ufl import (
CellVolume,
Circumradius,
Coefficient,
FacetArea,
FacetNormal,
FunctionSpace,
Mesh,
SpatialCoordinate,
TrialFunction,
ds,
dx,
)
from ufl.geometry import FacetEdgeVectors
V = basix.ufl.element("P", "tetrahedron", 1)
domain = Mesh(basix.ufl.element("P", "tetrahedron", 1, shape=(3,)))
space = FunctionSpace(domain, V)
u = Coefficient(space)
# TODO: Add all geometry for all cell types to this and other demo
# files, need for regression test.
x = SpatialCoordinate(domain)
n = FacetNormal(domain)
vol = CellVolume(domain)
rad = Circumradius(domain)
area = FacetArea(domain)
M = u * (x[0] * vol * rad) * dx + u * (x[0] * vol * rad * area) * ds
# Test some obscure functionality
fev = FacetEdgeVectors(domain)
v = TrialFunction(space)
L = fev[0, 0] * v * ds
================================================
FILE: demo/ComplexPoisson.py
================================================
# Copyright (C) 2023 Chris Richardson
#
# This file is part of FFCx.
#
# FFCx is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FFCx is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FFCx. If not, see <http://www.gnu.org/licenses/>.
"""Complex Poisson demo.
The bilinear form a(u, v) and linear form L(v) for
Poisson's equation using bilinear elements on bilinear mesh geometry.
"""
import basix.ufl
from ufl import Coefficient, FunctionSpace, Mesh, TestFunction, TrialFunction, dx, grad, inner
coords = basix.ufl.element("P", "triangle", 2, shape=(2,))
mesh = Mesh(coords)
dx = dx(mesh)
element = basix.ufl.element("P", mesh.ufl_cell().cellname, 2)
space = FunctionSpace(mesh, element)
u = TrialFunction(space)
v = TestFunction(space)
f = Coefficient(space)
# Test literal complex number in form
k = 3.213 + 1.023j
a = k * inner(grad(u), grad(v)) * dx
L = inner(k * f, v) * dx
================================================
FILE: demo/Components.py
================================================
# Copyright (C) 2011 Garth N. Wells
#
# This file is part of FFCx.
#
# FFCx is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FFCx is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FFCx. If not, see <http://www.gnu.org/licenses/>.
"""Components demo.
This example demonstrates how to create vectors component-wise.
"""
import basix.ufl
from ufl import Coefficient, FunctionSpace, Mesh, TestFunction, as_vector, dx, inner
element = basix.ufl.element("Lagrange", "tetrahedron", 1, shape=(3,))
domain = Mesh(element)
space = FunctionSpace(domain, element)
v = TestFunction(space)
f = Coefficient(space)
# Create vector
v0 = as_vector([v[0], v[1], 0.0])
# Use created vector in linear form
L = inner(f, v0) * dx
================================================
FILE: demo/Conditional.py
================================================
# Copyright (C) 2010-2011 Kristian B. Oelgaard
#
# This file is part of FFCx.
#
# FFCx is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FFCx is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FFCx. If not, see <http://www.gnu.org/licenses/>.
"""Conditional demo.
Illustration on how to use Conditional to define a source term.
"""
import basix.ufl
from ufl import (
And,
Constant,
FunctionSpace,
Mesh,
Not,
Or,
SpatialCoordinate,
TestFunction,
conditional,
dx,
ge,
gt,
inner,
le,
lt,
)
element = basix.ufl.element("Lagrange", "triangle", 2)
domain = Mesh(basix.ufl.element("Lagrange", "triangle", 1, shape=(2,)))
space = FunctionSpace(domain, element)
v = TestFunction(space)
g = Constant(domain)
x = SpatialCoordinate(domain)
c0 = conditional(le((x[0] - 0.33) ** 2 + (x[1] - 0.67) ** 2, 0.015), -1.0, 5.0)
c = conditional(le((x[0] - 0.33) ** 2 + (x[1] - 0.67) ** 2, 0.025), c0, 0.0)
t0 = And(ge(x[0], 0.55), le(x[0], 0.95))
t1 = Or(lt(x[1], 0.05), gt(x[1], 0.45))
t2 = And(t0, Not(t1))
t = conditional(And(ge(x[1] - x[0] - 0.05 + 0.55, 0.0), t2), -1.0, 0.0)
k = conditional(gt(1, 0), g, g + 1)
f = c + t + k
L = inner(f, v) * dx
================================================
FILE: demo/ExpressionInterpolation.py
================================================
# Copyright (C) 2022 Jørgen S. Dokken
#
# This file is part of FFCx.
#
# FFCx is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FFCx is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FFC. If not, see <http://www.gnu.org/licenses/>.
"""Expression interpolation demo.
Defines an Expression which evaluates the several different functions at
a set of interpolation points.
"""
import basix
import basix.ufl
from ufl import Coefficient, FunctionSpace, Mesh, grad
# Define mesh
cell = "triangle"
v_el = basix.ufl.element("Lagrange", cell, 1, shape=(2,))
mesh = Mesh(v_el)
# Define mixed function space
el = basix.ufl.element("P", cell, 2)
el_int = basix.ufl.element("Discontinuous Lagrange", cell, 1, shape=(2,))
me = basix.ufl.mixed_element([el, el_int])
V = FunctionSpace(mesh, me)
u = Coefficient(V)
# Define expressions on each sub-space
du0 = grad(u[0])
du1 = grad(u[1])
# Define an expression using quadrature elements
q_rule = "gauss_jacobi"
q_degree = 3
q_el = basix.ufl.quadrature_element(cell, scheme=q_rule, degree=q_degree)
Q = FunctionSpace(mesh, q_el)
q = Coefficient(Q)
powq = 3 * q**2
# Extract basix cell type
b_cell = basix.CellType[cell]
# Find quadrature points for quadrature element
b_rule = basix.quadrature.string_to_type(q_rule)
quadrature_points, _ = basix.quadrature.make_quadrature(b_cell, q_degree, rule=b_rule)
# Get interpolation points for output space
family = basix.finite_element.string_to_family("Lagrange", cell)
b_element = basix.create_element(
family, b_cell, 4, basix.LagrangeVariant.gll_warped, discontinuous=True
)
interpolation_points = b_element.points
# Create expressions that can be used for interpolation
expressions = [(du0, interpolation_points), (du1, interpolation_points), (powq, quadrature_points)]
================================================
FILE: demo/FacetIntegrals.py
================================================
# Copyright (C) 2009-2010 Anders Logg
#
# This file is part of FFCx.
#
# FFCx is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FFCx is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FFCx. If not, see <http://www.gnu.org/licenses/>.
"""Facet integrals demo.
Simple example of a form defined over exterior and interior facets.
"""
import basix.ufl
from ufl import (
FacetNormal,
FunctionSpace,
Mesh,
TestFunction,
TrialFunction,
avg,
dS,
ds,
grad,
inner,
jump,
)
element = basix.ufl.element("Discontinuous Lagrange", "triangle", 1)
domain = Mesh(basix.ufl.element("Lagrange", "triangle", 1, shape=(2,)))
space = FunctionSpace(domain, element)
u = TrialFunction(space)
v = TestFunction(space)
n = FacetNormal(domain)
a = (
inner(u, v) * ds
+ inner(u("+"), v("-")) * dS
+ inner(jump(u, n), avg(grad(v))) * dS
+ inner(avg(grad(u)), jump(v, n)) * dS
)
================================================
FILE: demo/FacetRestrictionAD.py
================================================
# Copyright (C) 2010 Garth N. Wells
#
# This file is part of FFCx.
#
# FFCx is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FFCx is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FFCx. If not, see <http://www.gnu.org/licenses/>.
"""Facet restriction demo."""
import basix.ufl
from ufl import (
Coefficient,
FunctionSpace,
Mesh,
TestFunction,
TrialFunction,
avg,
derivative,
dS,
dx,
grad,
inner,
)
element = basix.ufl.element("Discontinuous Lagrange", "triangle", 1)
domain = Mesh(basix.ufl.element("Lagrange", "triangle", 1, shape=(2,)))
space = FunctionSpace(domain, element)
v = TestFunction(space)
w = Coefficient(space)
L = inner(grad(w), grad(v)) * dx - inner(avg(grad(w)), avg(grad(v))) * dS
u = TrialFunction(space)
a = derivative(L, w, u)
================================================
FILE: demo/HyperElasticity.py
================================================
# Author: Martin Sandve Alnes
# Date: 2008-12-22
# Modified by Garth N. Wells, 2009
"""Hyper-elasticity demo."""
import basix.ufl
from ufl import (
Coefficient,
Constant,
FacetNormal,
FunctionSpace,
Identity,
Mesh,
SpatialCoordinate,
TestFunction,
TrialFunction,
derivative,
det,
diff,
ds,
dx,
exp,
grad,
inner,
inv,
tetrahedron,
tr,
variable,
)
# Cell and its properties
cell = tetrahedron
d = 3
# Elements
u_element = basix.ufl.element("P", cell.cellname, 2, shape=(3,))
p_element = basix.ufl.element("P", cell.cellname, 1)
A_element = basix.ufl.element("P", cell.cellname, 1, shape=(3, 3))
# Spaces
domain = Mesh(basix.ufl.element("Lagrange", cell.cellname, 1, shape=(3,)))
u_space = FunctionSpace(domain, u_element)
p_space = FunctionSpace(domain, p_element)
A_space = FunctionSpace(domain, A_element)
# Cell properties
N = FacetNormal(domain)
x = SpatialCoordinate(domain)
# Test and trial functions
v = TestFunction(u_space)
w = TrialFunction(u_space)
# Displacement at current and two previous timesteps
u = Coefficient(u_space)
up = Coefficient(u_space)
upp = Coefficient(u_space)
# Time parameters
dt = Constant(domain)
# Fiber field
A = Coefficient(A_space)
# External forces
T = Coefficient(u_space)
p0 = Coefficient(p_space)
# Material parameters FIXME
rho = Constant(domain)
K = Constant(domain)
c00 = Constant(domain)
c11 = Constant(domain)
c22 = Constant(domain)
# Deformation gradient
Ident = Identity(d)
F = Ident + grad(u)
F = variable(F)
Finv = inv(F)
J = det(F)
# Left Cauchy-Green deformation tensor
B = F * F.T
I1_B = tr(B)
I2_B = (I1_B**2 - tr(B * B)) / 2
I3_B = J**2
# Right Cauchy-Green deformation tensor
C = F.T * F
I1_C = tr(C)
I2_C = (I1_C**2 - tr(C * C)) / 2
I3_C = J**2
# Green strain tensor
E = (C - Ident) / 2
# Mapping of strain in fiber directions
Ef = A * E * A.T
# Strain energy function W(Q(Ef))
Q = (
c00 * Ef[0, 0] ** 2 + c11 * Ef[1, 1] ** 2 + c22 * Ef[2, 2] ** 2
) # FIXME: insert some simple law here
W = (K / 2) * (exp(Q) - 1) # + p stuff
# First Piola-Kirchoff stress tensor
P = diff(W, F)
# Acceleration term discretized with finite differences
k = dt / rho
acc = u - 2 * up + upp
# Residual equation # FIXME: Can contain errors, not tested!
a_F = (
inner(acc, v) * dx
+ k * inner(P, grad(v)) * dx
- k * inner(J * Finv * T, v) * ds(0)
- k * inner(J * Finv * p0 * N, v) * ds(1)
)
# Jacobi matrix of residual equation
a_J = derivative(a_F, u, w)
# Export forms
forms = [a_F, a_J]
================================================
FILE: demo/MassAction.py
================================================
# Copyright (C) 2023 Igor A. Baratta
#
# This file is part of FFCx. (https://www.fenicsproject.org)
#
# SPDX-License-Identifier: LGPL-3.0-or-later
"""Mass action demo."""
import basix.ufl
import ufl
P = 3
cell_type = basix.CellType.hexahedron
# create element with tensor product order
element = basix.ufl.wrap_element(
basix.create_tp_element(basix.ElementFamily.P, cell_type, P, basix.LagrangeVariant.gll_warped)
)
coords = basix.ufl.element(basix.ElementFamily.P, cell_type, 1, shape=(3,))
mesh = ufl.Mesh(coords)
V = ufl.FunctionSpace(mesh, element)
x = ufl.SpatialCoordinate(mesh)
v = ufl.TestFunction(V)
u = ufl.TrialFunction(V)
a = ufl.inner(u, v) * ufl.dx
w = ufl.Coefficient(V)
L = ufl.action(a, w)
================================================
FILE: demo/MassDG0.py
================================================
# Copyright (C) 2021 Igor Baratta
#
# This file is part of FFCx.
#
# FFCx is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FFCx is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FFCx. If not, see <http://www.gnu.org/licenses/>.
"""DG mass matrix demo.
The bilinear form for a mass matrix.
"""
import basix.ufl
from ufl import FunctionSpace, Mesh, TestFunction, TrialFunction, dx, inner
element = basix.ufl.element("DG", "tetrahedron", 0)
domain = Mesh(basix.ufl.element("Lagrange", "tetrahedron", 1, shape=(3,)))
space = FunctionSpace(domain, element)
v = TestFunction(space)
u = TrialFunction(space)
a = inner(u, v) * dx
================================================
FILE: demo/MassHcurl_2D_1.py
================================================
# Copyright (C) 2004-2010 Anders Logg
#
# This file is part of FFCx.
#
# FFCx is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FFCx is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FFCx. If not, see <http://www.gnu.org/licenses/>.
"""H(curl) mass matrix demo."""
import basix.ufl
from ufl import FunctionSpace, Mesh, TestFunction, TrialFunction, dx, inner
element = basix.ufl.element("N1curl", "triangle", 1)
domain = Mesh(basix.ufl.element("Lagrange", "triangle", 1, shape=(2,)))
space = FunctionSpace(domain, element)
v = TestFunction(space)
u = TrialFunction(space)
a = inner(u, v) * dx
================================================
FILE: demo/MassHdiv_2D_1.py
================================================
# Copyright (C) 2010 Anders Logg
#
# This file is part of FFCx.
#
# FFCx is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FFCx is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FFCx. If not, see <http://www.gnu.org/licenses/>.
"""H(div) mass matrix demo."""
import basix.ufl
from ufl import FunctionSpace, Mesh, TestFunction, TrialFunction, dx, inner
element = basix.ufl.element("BDM", "triangle", 1)
domain = Mesh(basix.ufl.element("Lagrange", "triangle", 1, shape=(2,)))
space = FunctionSpace(domain, element)
v = TestFunction(space)
u = TrialFunction(space)
a = inner(u, v) * dx
================================================
FILE: demo/MathFunctions.py
================================================
# Copyright (C) 2010 Kristian B. Oelgaard
#
# This file is part of FFCx.
#
# FFCx is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FFCx is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FFCx. If not, see <http://www.gnu.org/licenses/>.
"""Math function demo.
Test all algebra operators on Coefficients.
"""
import basix.ufl
from ufl import (
Coefficient,
FunctionSpace,
Mesh,
acos,
asin,
atan,
bessel_J,
bessel_Y,
cos,
dx,
erf,
exp,
ln,
sin,
sqrt,
tan,
)
element = basix.ufl.element("Lagrange", "triangle", 1)
domain = Mesh(basix.ufl.element("Lagrange", "triangle", 1, shape=(2,)))
space = FunctionSpace(domain, element)
c0 = Coefficient(space)
c1 = Coefficient(space)
s0 = 3 * c0 - c1
p0 = c0 * c1
f0 = c0 / c1
integrand = (
sqrt(c0)
+ sqrt(s0)
+ sqrt(p0)
+ sqrt(f0)
+ exp(c0)
+ exp(s0)
+ exp(p0)
+ exp(f0)
+ ln(c0)
+ ln(s0)
+ ln(p0)
+ ln(f0)
+ cos(c0)
+ cos(s0)
+ cos(p0)
+ cos(f0)
+ sin(c0)
+ sin(s0)
+ sin(p0)
+ sin(f0)
+ tan(c0)
+ tan(s0)
+ tan(p0)
+ tan(f0)
+ acos(c0)
+ acos(s0)
+ acos(p0)
+ acos(f0)
+ asin(c0)
+ asin(s0)
+ asin(p0)
+ asin(f0)
+ atan(c0)
+ atan(s0)
+ atan(p0)
+ atan(f0)
+ erf(c0)
+ erf(s0)
+ erf(p0)
+ erf(f0)
+ bessel_J(1, c0)
+ bessel_J(1, s0)
+ bessel_J(0, p0)
+ bessel_J(0, f0)
+ bessel_Y(1, c0)
+ bessel_Y(1, s0)
+ bessel_Y(0, p0)
+ bessel_Y(0, f0)
)
a = integrand * dx
================================================
FILE: demo/MetaData.py
================================================
# Copyright (C) 2009 Kristian B. Oelgaard
#
# This file is part of FFCx.
#
# FFCx is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FFCx is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FFCx. If not, see <http://www.gnu.org/licenses/>.
"""Metadata demo.
Test form for metadata.
"""
import basix.ufl
from ufl import (
Coefficient,
Constant,
FunctionSpace,
Mesh,
TestFunction,
TrialFunction,
dx,
grad,
inner,
)
element = basix.ufl.element("Lagrange", "triangle", 1)
vector_element = basix.ufl.element("Lagrange", "triangle", 1, shape=(2,))
domain = Mesh(basix.ufl.element("Lagrange", "triangle", 1, shape=(2,)))
space = FunctionSpace(domain, element)
vector_space = FunctionSpace(domain, vector_element)
u = TrialFunction(space)
v = TestFunction(space)
c = Coefficient(vector_space)
c2 = Constant(domain)
# Terms on the same subdomain using different quadrature degree
a = (
inner(grad(u), grad(v)) * dx(0, degree=8)
+ inner(c, c) * inner(grad(u), grad(v)) * dx(1, degree=4)
+ inner(c, c) * inner(grad(u), grad(v)) * dx(1, degree=2)
+ inner(grad(u), grad(v)) * dx(1, degree=-1)
)
L = inner(c2, v) * dx(0, metadata={"precision": 1})
================================================
FILE: demo/Mini.py
================================================
# Copyright (C) 2010 Marie E. Rognes
#
# This file is part of FFCx.
#
# FFCx is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FFCx is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FFCx. If not, see <http://www.gnu.org/licenses/>.
"""Mini element demo.
Illustration of vector sum of elements (EnrichedElement): The
bilinear form a(u, v) for the Stokes equations using a mixed
formulation involving the Mini element. The velocity element is
composed of a P1 element augmented by the cubic bubble function.
"""
import basix.ufl
from ufl import FunctionSpace, Mesh, TestFunctions, TrialFunctions, div, dx, grad, inner
P1 = basix.ufl.element("Lagrange", "triangle", 1)
B = basix.ufl.element("Bubble", "triangle", 3)
V = basix.ufl.blocked_element(basix.ufl.enriched_element([P1, B]), shape=(2,))
Q = basix.ufl.element("P", "triangle", 1)
domain = Mesh(basix.ufl.element("Lagrange", "triangle", 1, shape=(2,)))
Mini = FunctionSpace(domain, basix.ufl.mixed_element([V, Q]))
(u, p) = TrialFunctions(Mini)
(v, q) = TestFunctions(Mini)
a = (inner(grad(u), grad(v)) - inner(p, div(v)) + inner(div(u), q)) * dx
================================================
FILE: demo/MixedCoefficient.py
================================================
# Copyright (C) 2016 Miklós Homolya
#
# This file is part of FFCx.
#
# FFCx is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FFCx is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FFCx. If not, see <http://www.gnu.org/licenses/>.
"""Mixed coefficient demo."""
import basix.ufl
from ufl import Coefficients, FunctionSpace, Mesh, dot, dS, dx
DG = basix.ufl.element("DG", "triangle", 0, shape=(2,))
CG = basix.ufl.element("Lagrange", "triangle", 2)
RT = basix.ufl.element("RT", "triangle", 3)
element = basix.ufl.mixed_element([DG, CG, RT])
domain = Mesh(basix.ufl.element("Lagrange", "triangle", 1, shape=(2,)))
space = FunctionSpace(domain, element)
f, g, h = Coefficients(space)
forms = [dot(f("+"), h("-")) * dS + g * dx]
================================================
FILE: demo/MixedPoissonDual.py
================================================
# Copyright (C) 2014 Jan Blechta
#
# This file is part of FFCx.
#
# DOLFINx is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# DOLFINx is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with DOLFINx. If not, see <http://www.gnu.org/licenses/>.
"""Mixed Poisson dual demo.
The bilinear form a(u, v) and linear form L(v) for a two-field
(mixed) formulation of Poisson's equation.
"""
import basix.ufl
from ufl import Coefficient, FunctionSpace, Mesh, TestFunctions, TrialFunctions, ds, dx, grad, inner
DRT = basix.ufl.element("Discontinuous RT", "triangle", 2)
P = basix.ufl.element("P", "triangle", 3)
W = basix.ufl.mixed_element([DRT, P])
domain = Mesh(basix.ufl.element("Lagrange", "triangle", 1, shape=(2,)))
space = FunctionSpace(domain, W)
(sigma, u) = TrialFunctions(space)
(tau, v) = TestFunctions(space)
P1 = basix.ufl.element("P", "triangle", 1)
space = FunctionSpace(domain, P1)
f = Coefficient(space)
g = Coefficient(space)
a = (inner(sigma, tau) + inner(grad(u), tau) + inner(sigma, grad(v))) * dx
L = -inner(f, v) * dx - inner(g, v) * ds
================================================
FILE: demo/Normals.py
================================================
# Copyright (C) 2009 Peter Brune
#
# This file is part of FFCx.
#
# FFCx is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FFCx is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FFCx. If not, see <http://www.gnu.org/licenses/>.
"""Normals demo.
This example demonstrates how to use the facet normals
Merely project the normal onto a vector section.
"""
import basix.ufl
from ufl import FacetNormal, FunctionSpace, Mesh, TestFunction, TrialFunction, ds, inner, triangle
cell = triangle
element = basix.ufl.element("Lagrange", cell.cellname, 1, shape=(2,))
domain = Mesh(basix.ufl.element("Lagrange", cell.cellname, 1, shape=(2,)))
space = FunctionSpace(domain, element)
n = FacetNormal(domain)
v = TrialFunction(space)
u = TestFunction(space)
a = inner(v, u) * ds
L = inner(n, u) * ds
================================================
FILE: demo/Poisson1D.py
================================================
# Copyright (C) 2004-2007 Anders Logg
#
# This file is part of FFCx.
#
# FFCx is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FFCx is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FFCx. If not, see <http://www.gnu.org/licenses/>.
"""1D Poisson demo.
The bilinear form a(u, v) and linear form L(v) for Poisson's equation.
"""
import basix.ufl
from ufl import Coefficient, FunctionSpace, Mesh, TestFunction, TrialFunction, dx, grad, inner
element = basix.ufl.element("Lagrange", "interval", 1)
domain = Mesh(basix.ufl.element("Lagrange", "interval", 1, shape=(1,)))
space = FunctionSpace(domain, element)
u = TrialFunction(space)
v = TestFunction(space)
f = Coefficient(space)
a = inner(grad(u), grad(v)) * dx
L = inner(f, v) * dx
================================================
FILE: demo/PoissonQuad.py
================================================
# Copyright (C) 2016 Jan Blechta
#
# This file is part of FFCx.
#
# FFCx is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FFCx is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FFCx. If not, see <http://www.gnu.org/licenses/>.
"""Quadrilateral Poisson demo.
The bilinear form a(u, v) and linear form L(v) for
Poisson's equation using bilinear elements on bilinear mesh geometry.
"""
import basix.ufl
from ufl import Coefficient, FunctionSpace, Mesh, TestFunction, TrialFunction, dx, grad, inner
coords = basix.ufl.element("P", "triangle", 2, shape=(2,))
mesh = Mesh(coords)
dx = dx(mesh)
element = basix.ufl.element("P", mesh.ufl_cell().cellname, 2)
space = FunctionSpace(mesh, element)
u = TrialFunction(space)
v = TestFunction(space)
f = Coefficient(space)
a = inner(grad(u), grad(v)) * dx
L = inner(f, v) * dx
================================================
FILE: demo/ProjectionManifold.py
================================================
# Copyright (C) 2012 Marie E. Rognes and David Ham
#
# This file is part of FFCx.
#
# FFCx is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FFCx is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FFCx. If not, see <http://www.gnu.org/licenses/>.
"""Projection manifold demo.
This demo illustrates use of finite element spaces defined over
simplicies embedded in higher dimensions.
"""
import basix.ufl
from ufl import FunctionSpace, Mesh, TestFunctions, TrialFunctions, div, dx, inner
# Define element over this domain
V = basix.ufl.element("RT", "triangle", 1)
Q = basix.ufl.element("DG", "triangle", 0)
element = basix.ufl.mixed_element([V, Q])
domain = Mesh(basix.ufl.element("Lagrange", "triangle", 1, shape=(3,)))
space = FunctionSpace(domain, element)
(u, p) = TrialFunctions(space)
(v, q) = TestFunctions(space)
a = (inner(u, v) + inner(div(u), q) + inner(p, div(v))) * dx
================================================
FILE: demo/ReactionDiffusion.py
================================================
# Copyright (C) 2009 Anders Logg
#
# This file is part of FFCx.
#
# FFCx is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FFCx is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FFCx. If not, see <http://www.gnu.org/licenses/>.
"""Reaction-diffusion demo.
The bilinear form a(u, v) and linear form L(v) for a simple
reaction-diffusion equation using simplified tuple notation.
"""
import basix.ufl
from ufl import Coefficient, FunctionSpace, Mesh, TestFunction, TrialFunction, dx, grad, inner
element = basix.ufl.element("Lagrange", "triangle", 1)
domain = Mesh(basix.ufl.element("Lagrange", "triangle", 1, shape=(2,)))
space = FunctionSpace(domain, element)
u = TrialFunction(space)
v = TestFunction(space)
f = Coefficient(space)
a = (inner(grad(u), grad(v)) + inner(u, v)) * dx
L = inner(f, v) * dx
================================================
FILE: demo/SpatialCoordinates.py
================================================
# Copyright (C) 2010 Kristian B. Oelgaard
#
# This file is part of FFCx.
#
# FFCx is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FFCx is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FFCx. If not, see <http://www.gnu.org/licenses/>.
"""Spatial coordinates demo.
The bilinear form a(u, v) and linear form L(v) for Poisson's equation where
spatial coordinates are used to define the source and boundary flux terms.
"""
import basix.ufl
from ufl import (
FunctionSpace,
Mesh,
SpatialCoordinate,
TestFunction,
TrialFunction,
ds,
dx,
exp,
grad,
inner,
sin,
)
element = basix.ufl.element("Lagrange", "triangle", 2)
domain = Mesh(basix.ufl.element("Lagrange", "triangle", 1, shape=(2,)))
space = FunctionSpace(domain, element)
u = TrialFunction(space)
v = TestFunction(space)
x = SpatialCoordinate(domain)
d_x = x[0] - 0.5
d_y = x[1] - 0.5
f = 10.0 * exp(-(d_x * d_x + d_y * d_y) / 0.02)
g = sin(5.0 * x[0])
a = inner(grad(u), grad(v)) * dx
L = inner(f, v) * dx + inner(g, v) * ds
================================================
FILE: demo/StabilisedStokes.py
================================================
# Copyright (c) 2005-2007 Anders Logg
#
# This file is part of FFCx.
#
# FFCx is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FFCx is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FFCx. If not, see <http://www.gnu.org/licenses/>.
"""Stabilised Stokes demo.
The bilinear form a(u, v) and Linear form L(v) for the Stokes
equations using a mixed formulation (equal-order stabilized).
"""
import basix.ufl
from ufl import (
Coefficient,
FunctionSpace,
Mesh,
TestFunctions,
TrialFunctions,
div,
dot,
dx,
grad,
inner,
)
vector = basix.ufl.element("Lagrange", "triangle", 1, shape=(2,))
scalar = basix.ufl.element("Lagrange", "triangle", 1)
system = basix.ufl.mixed_element([vector, scalar])
domain = Mesh(basix.ufl.element("Lagrange", "triangle", 1, shape=(2,)))
system_space = FunctionSpace(domain, system)
scalar_space = FunctionSpace(domain, scalar)
vector_space = FunctionSpace(domain, vector)
(u, p) = TrialFunctions(system_space)
(v, q) = TestFunctions(system_space)
f = Coefficient(vector_space)
h = Coefficient(scalar_space)
beta = 0.2
delta = beta * h * h
a = (inner(grad(u), grad(v)) - div(v) * p + div(u) * q + delta * dot(grad(p), grad(q))) * dx
L = dot(f, v + delta * grad(q)) * dx
================================================
FILE: demo/Symmetry.py
================================================
"""Symmetry demo."""
import basix.ufl
from ufl import FunctionSpace, Mesh, TestFunction, TrialFunction, dx, grad, inner
P1 = basix.ufl.element("P", "triangle", 1, shape=(2, 2), symmetry=True)
domain = Mesh(basix.ufl.element("Lagrange", "triangle", 1, shape=(2,)))
space = FunctionSpace(domain, P1)
u = TrialFunction(space)
v = TestFunction(space)
a = inner(grad(u), grad(v)) * dx
================================================
FILE: demo/VectorConstant.py
================================================
# Copyright (C) 2016 Jan Blechta
#
# This file is part of FFCx.
#
# FFCx is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FFCx is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FFCx. If not, see <http://www.gnu.org/licenses/>.
"""Vector constant demo.
The bilinear form a(u, v) and linear form L(v) for
Poisson's equation using bilinear elements on bilinear mesh geometry.
"""
import basix.ufl
from ufl import (
Coefficient,
Constant,
FunctionSpace,
Mesh,
TestFunction,
TrialFunction,
dx,
grad,
inner,
)
coords = basix.ufl.element("P", "triangle", 2, shape=(2,))
mesh = Mesh(coords)
dx = dx(mesh)
element = basix.ufl.element("P", mesh.ufl_cell().cellname, 2)
space = FunctionSpace(mesh, element)
u = TrialFunction(space)
v = TestFunction(space)
f = Coefficient(space)
L = inner(f, v) * dx
mu = Constant(mesh, shape=(3,))
theta = -(mu[1] - 2) / mu[0] - (2 * (2 * mu[0] - 2) * (mu[0] - 1)) / (mu[0] * (mu[1] - 2))
a = theta * inner(grad(u), grad(v)) * dx
================================================
FILE: demo/VectorPoisson.py
================================================
# Copyright (C) 2010 Anders Logg
#
# This file is part of FFCx.
#
# FFCx is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FFCx is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FFCx. If not, see <http://www.gnu.org/licenses/>.
"""Vector Poisson demo.
The bilinear form a(u, v) and linear form L(v) for the vector-valued Poisson's equation.
"""
import basix.ufl
from ufl import Coefficient, FunctionSpace, Mesh, TestFunction, TrialFunction, dx, grad, inner
element = basix.ufl.element("Lagrange", "triangle", 1, shape=(2,))
domain = Mesh(element)
space = FunctionSpace(domain, element)
u = TrialFunction(space)
v = TestFunction(space)
f = Coefficient(space)
a = inner(grad(u), grad(v)) * dx
L = inner(f, v) * dx
================================================
FILE: demo/test_demos.py
================================================
"""Test demos."""
import os
import subprocess
import sys
from pathlib import Path
import pytest
demo_dir = Path(__file__).parent
ufl_files = [
f
for f in demo_dir.iterdir()
if f.suffix == ".py" and not f.stem.endswith("_numba") and f != Path(__file__)
]
skip_complex = ["BiharmonicHHJ", "BiharmonicRegge", "StabilisedStokes"]
def skip_unsupported(test):
"""Decorate test case to skip unsupported cases."""
def check_skip(file, scalar_type):
"""Skip scalar_type file combinations not supported."""
if "complex" in scalar_type and file.stem in skip_complex:
pytest.skip(reason="Not implemented for complex types")
elif "Complex" in file.stem and scalar_type in ["float64", "float32"]:
pytest.skip(reason="Not implemented for real types")
return test(file, scalar_type)
return check_skip
@pytest.mark.parametrize("file", ufl_files)
@pytest.mark.parametrize("scalar_type", ["float64", "float32", "complex128", "complex64"])
@skip_unsupported
def test_C(file, scalar_type):
"""Test a demo."""
if sys.platform.startswith("win32") and "complex" in scalar_type:
# Skip complex demos on win32
pytest.skip(reason="_Complex not supported on Windows")
subprocess.run(["ffcx", "--scalar_type", scalar_type, file], cwd=demo_dir, check=True)
if sys.platform.startswith("win32"):
extra_flags = "/std:c17"
for compiler in ["cl.exe", "clang-cl.exe"]:
subprocess.run(
[
compiler,
"/I",
f"{demo_dir.parent / 'ffcx/codegeneration'}",
*extra_flags.split(" "),
"/c",
file.with_suffix(".c"),
],
cwd=demo_dir,
check=True,
)
else:
cc = os.environ.get("CC", "cc")
extra_flags = (
"-std=c17 -Wunused-variable -Werror -fPIC -Wno-error=implicit-function-declaration"
)
subprocess.run(
[
cc,
f"-I{demo_dir.parent / 'ffcx/codegeneration'}",
*extra_flags.split(" "),
"-c",
file.with_suffix(".c"),
],
cwd=demo_dir,
check=True,
)
@pytest.mark.parametrize("file", ufl_files)
@pytest.mark.parametrize("scalar_type", ["float64", "float32", "complex128", "complex64"])
@skip_unsupported
def test_numba(file, scalar_type):
"""Test numba generation."""
opts = f"--language numba --scalar_type {scalar_type}"
subprocess.run(["ffcx", *opts.split(" "), file], cwd=demo_dir, check=True)
subprocess.run(["python", file], cwd=demo_dir, check=True)
================================================
FILE: doc/source/conf.py
================================================
"""Configuration file for the Sphinx documentation builder."""
# This file does only contain a selection of the most common options. For a
# full list see the documentation:
# http://www.sphinx-doc.org/en/stable/config
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
import datetime
import ffcx
# -- Project information -----------------------------------------------------
project = "FEniCS Form Compiler X"
now = datetime.datetime.now()
date = now.date()
copyright = f"{date.year}, FEniCS Project"
author = "FEniCS Project"
# The short X.Y version
version = ffcx.__version__
# The full version, including alpha/beta/rc tags
release = ffcx.__version__
# -- General configuration ---------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.autosummary",
"sphinx.ext.doctest",
"sphinx.ext.todo",
"sphinx.ext.coverage",
"sphinx.ext.mathjax",
"sphinx.ext.napoleon",
"sphinx.ext.viewcode",
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = ".rst"
# The master toctree document.
master_doc = "index"
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path .
exclude_patterns = []
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = "sphinx"
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
# html_theme = 'alabaster'
html_theme = "sphinx_rtd_theme"
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# The default sidebars (for documents that don't match any pattern) are
# defined by theme itself. Builtin themes are using these templates by
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
# 'searchbox.html']``.
#
# html_sidebars = {}
# -- Options for HTMLHelp output ---------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = "FEniCSFormCompilerXdoc"
# -- Options for LaTeX output ------------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(
master_doc,
"FEniCSFormCompilerX.tex",
"FEniCS Form Compiler X Documentation",
"FEniCS Project",
"manual",
),
]
# -- Options for manual page output ------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, "fenicsformcompilerx", "FEniCS Form Compiler X Documentation", [author], 1)
]
# -- Options for Texinfo output ----------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(
master_doc,
"FEniCSFormCompilerX",
"FEniCS Form Compiler X Documentation",
author,
"FEniCSFormCompilerX",
"One line description of project.",
"Miscellaneous",
),
]
# -- Extension configuration -------------------------------------------------
# -- Options for todo extension ----------------------------------------------
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True
autodoc_default_options = {
"members": True,
"show-inheritance": True,
"imported-members": True,
"undoc-members": True,
}
autosummary_generate = True
autoclass_content = "both"
autodoc_default_flags = ["members", "show-inheritance"]
napoleon_numpy_docstring = True
napoleon_google_docstring = True
================================================
FILE: doc/source/index.rst
================================================
FEniCS Form Compiler 'X' documentation
======================================
The is an experimental version of the FEniCS Form Compiler.
It is developed at https://github.com/FEniCS/ffcx.
.. toctree::
:maxdepth: 2
:caption: Contents:
API reference
=============
.. autosummary::
:toctree: _autogenerated
ffcx
ffcx.__main__
ffcx.analysis
ffcx.compiler
ffcx.element_interface
ffcx.formatting
ffcx.main
ffcx.naming
ffcx.codegeneration
ffcx.options
ffcx.ir.representation
ffcx.ir.representationutils
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
================================================
FILE: ffcx/__init__.py
================================================
# Copyright (C) 2009-2018 FEniCS Project
#
# This file is part of FFCx. (https://www.fenicsproject.org)
#
# SPDX-License-Identifier: LGPL-3.0-or-later
"""FEniCS Form Compiler (FFCx).
FFCx compiles finite element variational forms into C code.
"""
import importlib.metadata
import logging
# Import default options
from ffcx.options import get_options # noqa: F401
__version__ = importlib.metadata.version("fenics-ffcx")
logger = logging.getLogger("ffcx")
================================================
FILE: ffcx/__main__.py
================================================
#!/usr/bin/env python
# Copyright (C) 2017-2017 Martin Sandve Alnæs
#
# This file is part of FFCx.(https://www.fenicsproject.org)
#
# SPDX-License-Identifier: LGPL-3.0-or-later
"""Run ffcx on a UFL file."""
from ffcx.main import main
if __name__ == "__main__":
import sys
sys.exit(main())
================================================
FILE: ffcx/analysis.py
================================================
# Copyright (C) 2007-2020 Anders Logg, Martin Alnaes, Kristian B. Oelgaard,
# Michal Habera and others
#
# This file is part of FFCx. (https://www.fenicsproject.org)
#
# SPDX-License-Identifier: LGPL-3.0-or-later
"""Compiler stage 1: Analysis.
This module implements the analysis/preprocessing of variational forms,
including automatic selection of elements, degrees and form
representation type.
"""
from __future__ import annotations
import logging
import typing
if typing.TYPE_CHECKING:
from ufl.algorithms.formdata import FormData
import basix.ufl
import numpy as np
import numpy.typing as npt
import ufl.algorithms
logger = logging.getLogger("ffcx")
class UFLData(typing.NamedTuple):
"""UFL data."""
# Tuple of ufl form data
form_data: tuple[FormData, ...]
# List of unique elements
unique_elements: list[basix.ufl._ElementBase]
# Lookup table from each unique element to its index in `unique_elements`
element_numbers: dict[basix.ufl._ElementBase, int]
# List of unique coordinate elements
unique_coordinate_elements: list[basix.ufl._ElementBase]
# List of ufl Expressions as tuples (expression, points, original_expression)
expressions: list[tuple[ufl.core.expr.Expr, npt.NDArray[np.floating], ufl.core.expr.Expr]]
def analyze_ufl_objects(
ufl_objects: list[
ufl.form.Form
| basix.ufl._ElementBase
| ufl.Mesh
| tuple[ufl.core.expr.Expr, npt.NDArray[np.floating]]
],
scalar_type: npt.DTypeLike,
) -> UFLData:
"""Analyze ufl object(s).
Args:
ufl_objects: UFL objects
scalar_type: Scalar type that should be used for the analysis
Returns:
A data structure holding:
form_datas: Form_data objects
unique_elements: Unique elements across all forms and expressions
element_numbers: Mapping to unique numbers for all elements
unique_coordinate_elements: Unique coordinate elements across all forms and expressions
expressions: List of all expressions after post-processing, with its evaluation points
and the original expression
"""
logger.info(79 * "*")
logger.info("Compiler stage 1: Analyzing UFL objects")
logger.info(79 * "*")
elements: list[basix.ufl._ElementBase] = []
coordinate_elements: list[basix.ufl._ElementBase] = []
# Group objects by types
forms: list[ufl.form.Form] = []
expressions: list[tuple[ufl.core.expr.Expr, npt.NDArray[np.floating]]] = []
processed_expressions: list[
tuple[ufl.core.expr.Expr, npt.NDArray[np.floating], ufl.core.expr.Expr]
] = []
for ufl_object in ufl_objects:
if isinstance(ufl_object, ufl.form.Form):
forms.append(ufl_object)
elif isinstance(ufl_object, ufl.AbstractFiniteElement):
elements.append(ufl_object)
elif isinstance(ufl_object, ufl.Mesh):
coordinate_elements.append(ufl_object.ufl_coordinate_element())
elif isinstance(ufl_object[0], ufl.core.expr.Expr):
original_expression = ufl_object[0]
points = np.asarray(ufl_object[1])
expressions.append((original_expression, points))
else:
raise TypeError("UFL objects not recognised.")
form_data = tuple(_analyze_form(form, scalar_type) for form in forms)
for data in form_data:
elements += data.unique_sub_elements
coordinate_elements += data.coordinate_elements
for original_expression, points in expressions:
elements += ufl.algorithms.extract_elements(original_expression)
processed_expression = _analyze_expression(original_expression, scalar_type)
processed_expressions += [(processed_expression, points, original_expression)]
elements += ufl.algorithms.analysis.extract_sub_elements(elements)
# Sort elements so sub-elements come before mixed elements
unique_elements = ufl.algorithms.sort_elements(set(elements))
unique_coordinate_element_list = sorted(set(coordinate_elements), key=lambda x: repr(x))
for e in unique_elements:
assert isinstance(e, basix.ufl._ElementBase)
# Compute dict (map) from element to index
element_numbers = {element: i for i, element in enumerate(unique_elements)}
return UFLData(
form_data=form_data,
unique_elements=unique_elements,
element_numbers=element_numbers,
unique_coordinate_elements=unique_coordinate_element_list,
expressions=processed_expressions,
)
def _analyze_expression(
expression: ufl.core.expr.Expr, scalar_type: npt.DTypeLike
) -> ufl.core.expr.Expr:
"""Analyzes and preprocesses expressions."""
preserve_geometry_types = (ufl.classes.Jacobian,)
expression = ufl.algorithms.apply_algebra_lowering.apply_algebra_lowering(expression)
expression = ufl.algorithms.apply_derivatives.apply_derivatives(expression)
expression = ufl.algorithms.apply_function_pullbacks.apply_function_pullbacks(expression)
expression = ufl.algorithms.apply_geometry_lowering.apply_geometry_lowering(
expression, preserve_geometry_types
)
expression = ufl.algorithms.apply_derivatives.apply_derivatives(expression)
expression = ufl.algorithms.apply_geometry_lowering.apply_geometry_lowering(
expression, preserve_geometry_types
)
expression = ufl.algorithms.apply_derivatives.apply_derivatives(expression)
# Remove complex nodes if scalar type is real valued
if not np.issubdtype(scalar_type, np.complexfloating):
expression = ufl.algorithms.remove_complex_nodes.remove_complex_nodes(expression)
return expression
def _analyze_form(form: ufl.Form, scalar_type: npt.DTypeLike) -> FormData:
"""Analyzes UFL form and attaches metadata.
Args:
form: forms
scalar_type: Scalar type used for form. This is used to simplify
real valued forms.
Returns:
Form data computed by UFL with metadata attached
Note:
The main workload of this function is extraction of
unique/default metadata from options, integral metadata or
inherited from UFL (in case of quadrature degree).
"""
if form.empty():
raise RuntimeError(f"Form ({form}) seems to be zero: cannot compile it.")
if _has_custom_integrals(form):
raise RuntimeError(f"Form ({form}) contains unsupported custom integrals.")
# Check that coordinate element is based on basix.ufl._ElementBase
for _integral in form._integrals:
assert isinstance(_integral._ufl_domain._ufl_coordinate_element, basix.ufl._ElementBase)
# Check for complex mode
complex_mode = np.issubdtype(scalar_type, np.complexfloating)
# Compute form metadata
form_data: FormData = ufl.algorithms.compute_form_data(
form,
do_apply_function_pullbacks=True,
do_apply_integral_scaling=True,
do_apply_geometry_lowering=True,
preserve_geometry_types=(ufl.classes.Jacobian,),
do_apply_restrictions=True,
do_append_everywhere_integrals=False, # do not add dx integrals to dx(i) in UFL
complex_mode=complex_mode,
)
# Determine unique quadrature degree and quadrature scheme
# per each integral data
for id, integral_data in enumerate(form_data.integral_data):
# Iterate through groups of integral data. There is one integral
# data for all integrals with same domain, itype, subdomain_id
# (but possibly different metadata).
#
# Quadrature degree and quadrature scheme must be the same for
# all integrals in this integral data group, i.e. must be the
# same for for the same (domain, itype, subdomain_id)
for i, integral in enumerate(integral_data.integrals):
metadata = integral.metadata()
# Vertex integrals do not support discontinuous integrands.
if integral.integral_type() == "vertex":
elements = ufl.algorithms.extract_elements(integral)
if any(e.discontinuous for e in elements):
raise TypeError("Vertex integrals not supported for discontinuous elements.")
# If form contains a quadrature element, use the custom
# quadrature scheme
custom_q = None
for e in ufl.algorithms.extract_elements(integral):
if e.has_custom_quadrature:
if custom_q is None:
custom_q = e.custom_quadrature()
else:
p, w = e.custom_quadrature()
assert np.allclose(p, custom_q[0])
assert np.allclose(w, custom_q[1])
if custom_q is None:
# Extract quadrature degree
qd = -1
if "quadrature_degree" in metadata.keys():
qd = metadata["quadrature_degree"]
# Sending in a negative quadrature degree means that we want to be
# able to customize it at a later stage.
if qd < 0:
qd = int(np.max(integral.metadata()["estimated_polynomial_degree"]))
# Extract quadrature rule
qr = integral.metadata().get("quadrature_rule", "default")
logger.info(f"Integral {i}, integral group {id}:")
logger.info(f"--- quadrature rule: {qr}")
logger.info(f"--- quadrature degree: {qd}")
metadata.update({"quadrature_degree": qd, "quadrature_rule": qr})
else:
metadata.update(
{
"quadrature_points": custom_q[0],
"quadrature_weights": custom_q[1],
"quadrature_rule": "custom",
}
)
integral_data.integrals[i] = integral.reconstruct(metadata=metadata)
return form_data
def _has_custom_integrals(
o: ufl.integral.Integral | ufl.classes.Form | list | tuple,
) -> bool:
"""Check for custom integrals."""
if isinstance(o, ufl.integral.Integral):
return o.integral_type() in ufl.custom_integral_types
elif isinstance(o, ufl.classes.Form):
return any(_has_custom_integrals(itg) for itg in o.integrals())
elif isinstance(o, list | tuple):
return any(_has_custom_integrals(itg) for itg in o)
else:
raise NotImplementedError
================================================
FILE: ffcx/codegeneration/C/__init__.py
================================================
"""Generation of C code."""
from typing import TYPE_CHECKING
from ffcx.codegeneration import interface
from ffcx.codegeneration.C import expression, file, form, integral
from .formatter import Formatter
__all__ = [
"Formatter",
"expression",
"file",
"form",
"integral",
]
if TYPE_CHECKING:
# ensure protocol compliance
import numpy as np
_formatter: interface.Formatter = Formatter(np.float64)
_expression: interface.expression_generator = expression.generator
_file: interface.file_generator = file.generator
_form: interface.form_generator = form.generator
_integral: interface.integral_generator = integral.generator
================================================
FILE: ffcx/codegeneration/C/expression.py
================================================
# Copyright (C) 2019 Michal Habera
#
# This file is part of FFCx.(https://www.fenicsproject.org)
#
# SPDX-License-Identifier: LGPL-3.0-or-later
"""Generate UFCx code for an expression."""
from __future__ import annotations
import logging
import numpy as np
from ffcx.codegeneration.backend import FFCXBackend
from ffcx.codegeneration.C import expression_template
from ffcx.codegeneration.C.formatter import Formatter
from ffcx.codegeneration.common import template_keys
from ffcx.codegeneration.expression_generator import ExpressionGenerator
from ffcx.codegeneration.utils import dtype_to_c_type, dtype_to_scalar_dtype
from ffcx.ir.representation import ExpressionIR
logger = logging.getLogger("ffcx")
def generator(ir: ExpressionIR, options):
"""Generate UFCx code for an expression."""
logger.info("Generating code for expression:")
assert len(ir.expression.integrand) == 1, "Expressions only support single quadrature rule"
points = next(iter(ir.expression.integrand))[1].points
logger.info(f"--- points: {points}")
factory_name = ir.expression.name
logger.info(f"--- name: {factory_name}")
# Format declaration
declaration = expression_template.declaration.format(
factory_name=factory_name, name_from_uflfile=ir.name_from_uflfile
)
backend = FFCXBackend(ir, options)
eg = ExpressionGenerator(ir, backend)
d: dict[str, str | int] = {}
d["name_from_uflfile"] = ir.name_from_uflfile
d["factory_name"] = factory_name
parts = eg.generate()
format = Formatter(options["scalar_type"])
d["tabulate_expression"] = format(parts)
if len(ir.original_coefficient_positions) > 0:
d["original_coefficient_positions"] = f"original_coefficient_positions_{factory_name}"
values = ", ".join(str(i) for i in ir.original_coefficient_positions)
sizes = len(ir.original_coefficient_positions)
d["original_coefficient_positions_init"] = (
f"static int original_coefficient_positions_{factory_name}[{sizes}] = {{{values}}};"
)
else:
d["original_coefficient_positions"] = "NULL"
d["original_coefficient_positions_init"] = ""
values = ", ".join(str(p) for p in points.flatten())
sizes = points.size
d["points_init"] = f"static double points_{factory_name}[{sizes}] = {{{values}}};"
d["points"] = f"points_{factory_name}"
if len(ir.expression.shape) > 0:
values = ", ".join(str(i) for i in ir.expression.shape)
sizes = len(ir.expression.shape)
d["value_shape_init"] = f"static int value_shape_{factory_name}[{sizes}] = {{{values}}};"
d["value_shape"] = f"value_shape_{factory_name}"
else:
d["value_shape_init"] = ""
d["value_shape"] = "NULL"
d["num_components"] = len(ir.expression.shape)
d["num_coefficients"] = len(ir.expression.coefficient_numbering)
d["num_constants"] = len(ir.constant_names)
d["num_points"] = points.shape[0]
d["entity_dimension"] = points.shape[1]
d["scalar_type"] = dtype_to_c_type(options["scalar_type"])
d["geom_type"] = dtype_to_c_type(dtype_to_scalar_dtype(options["scalar_type"]))
d["np_scalar_type"] = np.dtype(options["scalar_type"]).name
d["rank"] = len(ir.expression.tensor_shape)
if len(ir.coefficient_names) > 0:
values = ", ".join(f'"{name}"' for name in ir.coefficient_names)
sizes = len(ir.coefficient_names)
d["coefficient_names_init"] = (
f"static const char* coefficient_names_{factory_name}[{sizes}] = {{{values}}};"
)
d["coefficient_names"] = f"coefficient_names_{factory_name}"
else:
d["coefficient_names_init"] = ""
d["coefficient_names"] = "NULL"
if len(ir.constant_names) > 0:
values = ", ".join(f'"{name}"' for name in ir.constant_names)
sizes = len(ir.constant_names)
d["constant_names_init"] = (
f"static const char* constant_names_{factory_name}[{sizes}] = {{{values}}};"
)
d["constant_names"] = f"constant_names_{factory_name}"
else:
d["constant_names_init"] = ""
d["constant_names"] = "NULL"
d["coordinate_element_hash"] = f"UINT64_C({ir.expression.coordinate_element_hash})"
# Format implementation code
assert set(d.keys()) == template_keys(expression_template.factory)
implementation = expression_template.factory.format_map(d)
return declaration, implementation
================================================
FILE: ffcx/codegeneration/C/expression_template.py
================================================
# Copyright (C) 2019 Michal Habera
#
# This file is part of FFCx.(https://www.fenicsproject.org)
#
# SPDX-License-Identifier: LGPL-3.0-or-later
"""Code generation strings for an expression."""
declaration = """
extern ufcx_expression {factory_name};
// Helper used to create expression using name which was given to the
// expression in the UFL file.
// This helper is called in user c++ code.
//
extern ufcx_expression* {name_from_uflfile};
"""
factory = """
// Code for expression {factory_name}
void tabulate_tensor_{factory_name}({scalar_type}* restrict A,
const {scalar_type}* restrict w,
const {scalar_type}* restrict c,
const {geom_type}* restrict coordinate_dofs,
const int* restrict entity_local_index,
const uint8_t* restrict quadrature_permutation,
void* custom_data)
{{
{tabulate_expression}
}}
{points_init}
{value_shape_init}
{original_coefficient_positions_init}
{coefficient_names_init}
{constant_names_init}
ufcx_expression {factory_name} =
{{
.tabulate_tensor_{np_scalar_type} = tabulate_tensor_{factory_name},
.num_coefficients = {num_coefficients},
.num_constants = {num_constants},
.original_coefficient_positions = {original_coefficient_positions},
.coefficient_names = {coefficient_names},
.constant_names = {constant_names},
.num_points = {num_points},
.entity_dimension = {entity_dimension},
.points = {points},
.value_shape = {value_shape},
.num_components = {num_components},
.rank = {rank},
.coordinate_element_hash = {coordinate_element_hash},
}};
// Alias name
ufcx_expression* {name_from_uflfile} = &{factory_name};
// End of code for expression {factory_name}
"""
================================================
FILE: ffcx/codegeneration/C/file.py
================================================
# Copyright (C) 2009-2018 Anders Logg, Martin Sandve Alnæs and Garth N. Wells
#
# This file is part of FFCx.(https://www.fenicsproject.org)
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#
# Note: Most of the code in this file is a direct translation from the
# old implementation in FFC
"""Generate a file."""
import logging
import pprint
import textwrap
import numpy as np
from ffcx import __version__ as FFCX_VERSION
from ffcx.codegeneration import __version__ as UFC_VERSION
from ffcx.codegeneration.C import file_template
suffixes = (".h", ".c")
logger = logging.getLogger("ffcx")
def generator(options):
"""Generate UFCx code for file output."""
logger.info("Generating code for file")
# Attributes
d = {"ffcx_version": FFCX_VERSION, "ufcx_version": UFC_VERSION}
d["options"] = textwrap.indent(pprint.pformat(options), "// ")
extra_c_includes = []
if np.issubdtype(options["scalar_type"], np.complexfloating):
extra_c_includes += ["complex.h"]
d["extra_c_includes"] = "\n".join(f"#include <{header}>" for header in extra_c_includes)
# Format declaration code
code_pre = (
file_template.declaration_pre.format_map(d),
file_template.implementation_pre.format_map(d),
)
# Format implementation code
code_post = (
file_template.declaration_post.format_map(d),
file_template.implementation_post.format_map(d),
)
return code_pre, code_post
================================================
FILE: ffcx/codegeneration/C/file_template.py
================================================
# Code generation format strings for UFCx (Unified Form-assembly Code)
# This code is released into the public domain.
#
# The FEniCS Project (http://www.fenicsproject.org/) 2018.
"""Code generation strings for a file."""
import sys
declaration_pre = """
// This code conforms with the UFCx specification version {ufcx_version}
// and was automatically generated by FFCx version {ffcx_version}.
//
// This code was generated with the following options:
//
{options}
#pragma once
#include <ufcx.h>
#ifdef __cplusplus
extern "C" {{
#endif
"""
declaration_post = """
#ifdef __cplusplus
}}
#endif
"""
implementation_pre = """
// This code conforms with the UFCx specification version {ufcx_version}
// and was automatically generated by FFCx version {ffcx_version}.
//
// This code was generated with the following options:
//
{options}
#include <math.h>
#include <stdalign.h>
#include <stdlib.h>
#include <string.h>
#include <ufcx.h>
{extra_c_includes}
"""
libraries: list[str] = [] if sys.platform.startswith("win32") else ["m"]
implementation_post = ""
================================================
FILE: ffcx/codegeneration/C/form.py
================================================
# Copyright (C) 2009-2017 Anders Logg and Martin Sandve Alnæs
#
# This file is part of FFCx.(https://www.fenicsproject.org)
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#
# Modified by Chris Richardson and Jørgen S. Dokken 2023
#
# Note: Most of the code in this file is a direct translation from the
# old implementation in FFC
"""Generate UFCx code for a form."""
from __future__ import annotations
import logging
from ffcx.codegeneration.C import form_template
from ffcx.codegeneration.common import integral_data, template_keys
from ffcx.ir.representation import FormIR
logger = logging.getLogger("ffcx")
def generator(ir: FormIR, options):
"""Generate UFCx code for a form."""
logger.info("Generating code for form:")
logger.info(f"--- rank: {ir.rank}")
logger.info(f"--- name: {ir.name}")
d: dict[str, int | str] = {}
d["factory_name"] = ir.name
d["name_from_uflfile"] = ir.name_from_uflfile
d["signature"] = f'"{ir.signature}"'
d["rank"] = ir.rank
d["num_coefficients"] = ir.num_coefficients
if len(ir.original_coefficient_positions) > 0:
values = ", ".join(str(i) for i in ir.original_coefficient_positions)
sizes = len(ir.original_coefficient_positions)
d["original_coefficient_position_init"] = (
f"int original_coefficient_position_{ir.name}[{sizes}] = {{{values}}};"
)
d["original_coefficient_positions"] = f"original_coefficient_position_{ir.name}"
else:
d["original_coefficient_position_init"] = ""
d["original_coefficient_positions"] = "NULL"
if len(ir.coefficient_names) > 0:
values = ", ".join(f'"{name}"' for name in ir.coefficient_names)
sizes = len(ir.coefficient_names)
d["coefficient_names_init"] = (
f"static const char* coefficient_names_{ir.name}[{sizes}] = {{{values}}};"
)
d["coefficient_names"] = f"coefficient_names_{ir.name}"
else:
d["coefficient_names_init"] = ""
d["coefficient_names"] = "NULL"
d["num_constants"] = ir.num_constants
if ir.num_constants > 0:
d["constant_ranks_init"] = (
f"static const int constant_ranks_{ir.name}[{ir.num_constants}] = "
f"{{{str(ir.constant_ranks)[1:-1]}}};"
)
d["constant_ranks"] = f"constant_ranks_{ir.name}"
shapes = [
f"static const int constant_shapes_{ir.name}_{i}[{len(shape)}] = "
f"{{{str(shape)[1:-1]}}};"
for i, shape in enumerate(ir.constant_shapes)
if len(shape) > 0
]
names = [f"constant_shapes_{ir.name}_{i}" for i in range(ir.num_constants)]
shapes1 = f"static const int* constant_shapes_{ir.name}[{ir.num_constants}] = " + "{"
for rank, name in zip(ir.constant_ranks, names):
if rank > 0:
shapes1 += f"{name},\n"
else:
shapes1 += "NULL,\n"
shapes1 += "};"
shapes.append(shapes1)
d["constant_shapes_init"] = "\n".join(shapes)
d["constant_shapes"] = f"constant_shapes_{ir.name}"
else:
d["constant_ranks_init"] = ""
d["constant_ranks"] = "NULL"
d["constant_shapes_init"] = ""
d["constant_shapes"] = "NULL"
if len(ir.constant_names) > 0:
values = ", ".join(f'"{name}"' for name in ir.constant_names)
sizes = len(ir.constant_names)
d["constant_names_init"] = (
f"static const char* constant_names_{ir.name}[{sizes}] = {{{values}}};"
)
d["constant_names"] = f"constant_names_{ir.name}"
else:
d["constant_names_init"] = ""
d["constant_names"] = "NULL"
if len(ir.finite_element_hashes) > 0:
d["finite_element_hashes"] = f"finite_element_hashes_{ir.name}"
values = ", ".join(
f"UINT64_C({0 if el is None else el})" for el in ir.finite_element_hashes
)
sizes = len(ir.finite_element_hashes)
d["finite_element_hashes_init"] = (
f"uint64_t finite_element_hashes_{ir.name}[{sizes}] = {{{values}}};"
)
else:
d["finite_element_hashes"] = "NULL"
d["finite_element_hashes_init"] = ""
integrals = integral_data(ir)
if len(integrals.names) > 0:
sizes = sum(len(domains) for domains in integrals.domains)
values = ", ".join(
[
f"&{name}_{domain.name}"
for name, domains in zip(integrals.names, integrals.domains)
for domain in domains
]
)
d["form_integrals_init"] = (
f"static ufcx_integral* form_integrals_{ir.name}[{sizes}] = {{{values}}};"
)
d["form_integrals"] = f"form_integrals_{ir.name}"
values = ", ".join(
f"{i}" for i, domains in zip(integrals.ids, integrals.domains) for _ in domains
)
d["form_integral_ids_init"] = f"int form_integral_ids_{ir.name}[{sizes}] = {{{values}}};"
d["form_integral_ids"] = f"form_integral_ids_{ir.name}"
else:
d["form_integrals_init"] = ""
d["form_integrals"] = "NULL"
d["form_integral_ids_init"] = ""
d["form_integral_ids"] = "NULL"
sizes = len(integrals.offsets)
values = ", ".join(str(i) for i in integrals.offsets)
d["form_integral_offsets_init"] = (
f"int form_integral_offsets_{ir.name}[{sizes}] = {{{values}}};"
)
# Format implementation code
assert set(d.keys()) == template_keys(form_template.factory)
implementation = form_template.factory.format_map(d)
# Format declaration
declaration = form_template.declaration.format(
factory_name=d["factory_name"], name_from_uflfile=d["name_from_uflfile"]
)
return declaration, implementation
================================================
FILE: ffcx/codegeneration/C/form_template.py
================================================
# Code generation format strings for UFCx (Unified Form-assembly Code)
# This code is released into the public domain.
#
# The FEniCS Project (http://www.fenicsproject.org/) 2020.
"""Code generation strings for a form."""
declaration = """
extern ufcx_form {factory_name};
// Helper used to create form using name which was given to the
// form in the UFL file.
// This helper is called in user c++ code.
//
extern ufcx_form* {name_from_uflfile};
"""
factory = """
// Code for form {factory_name}
{original_coefficient_position_init}
{finite_element_hashes_init}
{form_integral_offsets_init}
{form_integrals_init}
{form_integral_ids_init}
{coefficient_names_init}
{constant_names_init}
{constant_ranks_init}
{constant_shapes_init}
ufcx_form {factory_name} =
{{
.signature = {signature},
.rank = {rank},
.num_coefficients = {num_coefficients},
.original_coefficient_positions = {original_coefficient_positions},
.coefficient_name_map = {coefficient_names},
.num_constants = {num_constants},
.constant_ranks = {constant_ranks},
.constant_shapes = {constant_shapes},
.constant_name_map = {constant_names},
.finite_element_hashes = {finite_element_hashes},
.form_integrals = {form_integrals},
.form_integral_ids = {form_integral_ids},
.form_integral_offsets = form_integral_offsets_{factory_name}
}};
// Alias name
ufcx_form* {name_from_uflfile} = &{factory_name};
// End of code for form {factory_name}
"""
================================================
FILE: ffcx/codegeneration/C/formatter.py
================================================
# Copyright (C) 2023-2025 Chris Richardson and Paul T. Kühner
#
# This file is part of FFCx. (https://www.fenicsproject.org)
#
# SPDX-License-Identifier: LGPL-3.0-or-later
"""C implementation."""
import warnings
from functools import singledispatchmethod
import numpy as np
import numpy.typing as npt
import ffcx.codegeneration.lnodes as L
from ffcx.codegeneration.interface import Formatter as FormatterInterface
from ffcx.codegeneration.utils import dtype_to_c_type, dtype_to_scalar_dtype
math_table = {
"float64": {
"sqrt": "sqrt",
"abs": "fabs",
"cos": "cos",
"sin": "sin",
"tan": "tan",
"acos": "acos",
"asin": "asin",
"atan": "atan",
"cosh": "cosh",
"sinh": "sinh",
"tanh": "tanh",
"acosh": "acosh",
"asinh": "asinh",
"atanh": "atanh",
"power": "pow",
"exp": "exp",
"ln": "log",
"erf": "erf",
"atan_2": "atan2",
"min_value": "fmin",
"max_value": "fmax",
"bessel_y": "yn",
"bessel_j": "jn",
},
"float32": {
"sqrt": "sqrtf",
"abs": "fabsf",
"cos": "cosf",
"sin": "sinf",
"tan": "tanf",
"acos": "acosf",
"asin": "asinf",
"atan": "atanf",
"cosh": "coshf",
"sinh": "sinhf",
"tanh": "tanhf",
"acosh": "acoshf",
"asinh": "asinhf",
"atanh": "atanhf",
"power": "powf",
"exp": "expf",
"ln": "logf",
"erf": "erff",
"atan_2": "atan2f",
"min_value": "fminf",
"max_value": "fmaxf",
"bessel_y": "yn",
"bessel_j": "jn",
},
"longdouble": {
"sqrt": "sqrtl",
"abs": "fabsl",
"cos": "cosl",
"sin": "sinl",
"tan": "tanl",
"acos": "acosl",
"asin": "asinl",
"atan": "atanl",
"cosh": "coshl",
"sinh": "sinhl",
"tanh": "tanhl",
"acosh": "acoshl",
"asinh": "asinhl",
"atanh": "atanhl",
"power": "powl",
"exp": "expl",
"ln": "logl",
"erf": "erfl",
"atan_2": "atan2l",
"min_value": "fminl",
"max_value": "fmaxl",
},
"complex128": {
"sqrt": "csqrt",
"abs": "cabs",
"cos": "ccos",
"sin": "csin",
"tan": "ctan",
"acos": "cacos",
"asin": "casin",
"atan": "catan",
"cosh": "ccosh",
"sinh": "csinh",
"tanh": "ctanh",
"acosh": "cacosh",
"asinh": "casinh",
"atanh": "catanh",
"power": "cpow",
"exp": "cexp",
"ln": "clog",
"real": "creal",
"imag": "cimag",
"conj": "conj",
"max_value": "fmax",
"min_value": "fmin",
"bessel_y": "yn",
"bessel_j": "jn",
},
"complex64": {
"sqrt": "csqrtf",
"abs": "cabsf",
"cos": "ccosf",
"sin": "csinf",
"tan": "ctanf",
"acos": "cacosf",
"asin": "casinf",
"atan": "catanf",
"cosh": "ccoshf",
"sinh": "csinhf",
"tanh": "ctanhf",
"acosh": "cacoshf",
"asinh": "casinhf",
"atanh": "catanhf",
"power": "cpowf",
"exp": "cexpf",
"ln": "clogf",
"real": "crealf",
"imag": "cimagf",
"conj": "conjf",
"max_value": "fmaxf",
"min_value": "fminf",
"bessel_y": "yn",
"bessel_j": "jn",
},
}
class Formatter(FormatterInterface):
"""C formatter."""
scalar_type: np.dtype
real_type: np.dtype
def __init__(self, dtype: npt.DTypeLike) -> None:
"""Initialise."""
self.scalar_type = np.dtype(dtype)
self.real_type = dtype_to_scalar_dtype(dtype)
def _dtype_to_name(self, dtype) -> str:
"""Convert dtype to C name."""
if dtype == L.DataType.SCALAR:
return dtype_to_c_type(self.scalar_type)
if dtype == L.DataType.REAL:
return dtype_to_c_type(self.real_type)
if dtype == L.DataType.INT:
return "int"
if dtype == L.DataType.BOOL:
return "bool"
raise ValueError(f"Invalid dtype: {dtype}")
def _format_number(self, x):
"""Format a number."""
# Use 16sf for precision (good for float64 or less)
if isinstance(x, complex):
return f"({x.real:.16}+I*{x.imag:.16})"
elif isinstance(x, float):
return f"{x:.16}"
return str(x)
def _build_initializer_lists(self, values):
"""Build initializer lists."""
arr = "{"
if len(values.shape) == 1:
arr += ", ".join(self._format_number(v) for v in values)
elif len(values.shape) > 1:
arr += ",\n ".join(self._build_initializer_lists(v) for v in values)
arr += "}"
return arr
@singledispatchmethod
def __call__(self, obj: L.LNode) -> str:
"""Format an L Node."""
raise NotImplementedError(f"Can not format object to type {type(obj)}")
@__call__.register
def _(self, slist: L.StatementList) -> str:
"""Format a statement list."""
return "".join(self(s) for s in slist.statements)
@__call__.register
def _(self, section: L.Section) -> str:
"""Format a section."""
# add new line before section
comments = (
f"// ------------------------ \n"
f"// Section: {section.name}\n"
f"// Inputs: {', '.join(w.name for w in section.input)}\n"
f"// Outputs: {', '.join(w.name for w in section.output)}\n"
)
declarations = "".join(self(s) for s in section.declarations)
body = ""
if len(section.statements) > 0:
declarations += "{\n "
body = "".join(self(s) for s in section.statements)
body = body.replace("\n", "\n ")
body = body[:-2] + "}\n"
body += "// ------------------------ \n"
return str(comments + declarations + body)
@__call__.register
def _(self, c: L.Comment) -> str:
"""Format a comment."""
return f"// {c.comment}\n"
@__call__.register
def _(self, arr: L.ArrayDecl) -> str:
"""Format an array declaration."""
dtype = arr.symbol.dtype
typename = self._dtype_to_name(dtype)
symbol = self(arr.symbol)
dims = "".join([f"[{i}]" for i in arr.sizes])
if arr.values is None:
assert arr.const is False
return f"{typename} {symbol}{dims};\n"
vals = self._build_initializer_lists(arr.values)
cstr = "static const " if arr.const else ""
return f"{cstr}{typename} {symbol}{dims} = {vals};\n"
@__call__.register
def _(self, arr: L.ArrayAccess) -> str:
"""Format an array access."""
name = self(arr.array)
indices = f"[{']['.join(self(i) for i in arr.indices)}]"
return f"{name}{indices}"
@__call__.register
def _(self, v: L.VariableDecl) -> str:
"""Format a variable declaration."""
val = self(v.value)
symbol = self(v.symbol)
typename = self._dtype_to_name(v.symbol.dtype)
return f"{typename} {symbol} = {val};\n"
@__call__.register
def _(self, oper: L.NaryOp) -> str:
"""Format an n-ary operation."""
# Format children
args = [self(arg) for arg in oper.args]
# Apply parentheses
for i in range(len(args)):
if oper.args[i].precedence >= oper.precedence:
args[i] = "(" + args[i] + ")"
# Return combined string
return f" {oper.op} ".join(args)
@__call__.register
def _(self, oper: L.BinOp) -> str:
"""Format a binary operation."""
# Format children
lhs = self(oper.lhs)
rhs = self(oper.rhs)
# Apply parentheses
if oper.lhs.precedence >= oper.precedence:
lhs = f"({lhs})"
if oper.rhs.precedence >= oper.precedence:
rhs = f"({rhs})"
# Return combined string
return f"{lhs} {oper.op} {rhs}"
@__call__.register(L.Neg)
@__call__.register(L.Not)
def _(self, oper: L.Neg | L.Not) -> str:
"""Format a unary operation."""
arg = self(oper.arg)
if oper.arg.precedence >= oper.precedence:
return f"{oper.op}({arg})"
return f"{oper.op}{arg}"
@__call__.register
def _(self, val: L.LiteralFloat) -> str:
"""Format a literal float."""
value = self._format_number(val.value)
return f"{value}"
@__call__.register
def _(self, val: L.LiteralInt) -> str:
"""Format a literal int."""
return f"{val.value}"
@__call__.register
def _(self, r: L.ForRange) -> str:
"""Format a for loop over a range."""
begin = self(r.begin)
end = self(r.end)
index = self(r.index)
output = f"for (int {index} = {begin}; {index} < {end}; ++{index})\n"
output += "{\n"
body = self(r.body)
for line in body.split("\n"):
if len(line) > 0:
output += f" {line}\n"
output += "}\n"
return output
@__call__.register
def _(self, s: L.Statement) -> str:
"""Format a statement."""
return self(s.expr)
@__call__.register(L.Assign)
@__call__.register(L.AssignAdd)
def _(self, expr: L.Assign | L.AssignAdd) -> str:
"""Format an assignment."""
rhs = self(expr.rhs)
lhs = self(expr.lhs)
return f"{lhs} {expr.op} {rhs};\n"
@__call__.register
def _(self, s: L.Conditional) -> str:
"""Format a conditional."""
# Format children
c = self(s.condition)
t = self(s.true)
f = self(s.false)
# Apply parentheses
if s.condition.precedence >= s.precedence:
c = "(" + c + ")"
if s.true.precedence >= s.precedence:
t = "(" + t + ")"
if s.false.precedence >= s.precedence:
f = "(" + f + ")"
# Return combined string
return c + " ? " + t + " : " + f
@__call__.register
def _(self, s: L.Symbol) -> str:
"""Format a symbol."""
return f"{s.name}"
@__call__.register
def _(self, mi: L.MultiIndex) -> str:
"""Format a multi-index."""
return self(mi.global_index)
@__call__.register
def _(self, c: L.MathFunction) -> str:
"""Format a mathematical function."""
# Get a table of functions for this type, if available
arg_type = self.scalar_type
if hasattr(c.args[0], "dtype"):
if c.args[0].dtype == L.DataType.REAL:
arg_type = self.real_type
else:
warnings.warn(f"Syntax item without dtype {c.args[0]}")
dtype_math_table = math_table[arg_type.name]
# Get a function from the table, if available, else just use bare name
func = dtype_math_table.get(c.function, c.function)
args = ", ".join(self(arg) for arg in c.args)
return f"{func}({args})"
================================================
FILE: ffcx/codegeneration/C/integral.py
================================================
# Copyright (C) 2015-2021 Martin Sandve Alnæs, Michal Habera, Igor Baratta
#
# This file is part of FFCx. (https://www.fenicsproject.org)
#
# SPDX-License-Identifier: LGPL-3.0-or-later
"""Generate UFCx code for an integral."""
import logging
import sys
import basix
import numpy as np
from numpy import typing as npt
from ffcx.codegeneration.backend import FFCXBackend
from ffcx.codegeneration.C import integral_template as ufcx_integrals
from ffcx.codegeneration.C.formatter import Formatter
from ffcx.codegeneration.integral_generator import IntegralGenerator
from ffcx.codegeneration.utils import dtype_to_c_type, dtype_to_scalar_dtype
from ffcx.ir.representation import IntegralIR
logger = logging.getLogger("ffcx")
def generator(
ir: IntegralIR, domain: basix.CellType, options: dict[str, int | float | npt.DTypeLike]
) -> tuple[str, str]:
"""Generate C code for an integral.
Args:
ir: IR of the integral
domain: basix cell type
options: dict of kernel generation options
Returns:
Tuple of declaration (header) and implementation (source) strings.
"""
logger.info("Generating code for integral:")
logger.info(f"--- type: {ir.expression.integral_type}")
logger.info(f"--- name: {ir.expression.name}")
factory_name = f"{ir.expression.name}_{domain.name}"
# Format declaration
declaration = ufcx_integrals.declaration.format(factory_name=factory_name)
# Create FFCx backend
backend = FFCXBackend(ir, options)
# Configure kernel generator
ig = IntegralGenerator(ir, backend)
# Generate code ast for the tabulate_tensor body
parts = ig.generate(domain)
# Format code as string
format = Formatter(options["scalar_type"]) # type: ignore
body = format(parts)
# Generate generic FFCx code snippets and add specific parts
code = {}
if len(ir.enabled_coefficients) > 0:
values = ", ".join("1" if i else "0" for i in ir.enabled_coefficients)
sizes = len(ir.enabled_coefficients)
code["enabled_coefficients_init"] = (
f"bool enabled_coefficients_{ir.expression.name}_{domain.name}[{sizes}] = {{{values}}};"
)
code["enabled_coefficients"] = f"enabled_coefficients_{ir.expression.name}_{domain.name}"
else:
code["enabled_coefficients_init"] = ""
code["enabled_coefficients"] = "NULL"
code["tabulate_tensor"] = body
code["tabulate_tensor_float32"] = ".tabulate_tensor_float32 = NULL,"
code["tabulate_tensor_float64"] = ".tabulate_tensor_float64 = NULL,"
if sys.platform.startswith("win32"):
code["tabulate_tensor_complex64"] = ""
code["tabulate_tensor_complex128"] = ""
else:
code["tabulate_tensor_complex64"] = ".tabulate_tensor_complex64 = NULL,"
code["tabulate_tensor_complex128"] = ".tabulate_tensor_complex128 = NULL,"
np_scalar_type = np.dtype(options["scalar_type"]).name # type: ignore
code[f"tabulate_tensor_{np_scalar_type}"] = (
f".tabulate_tensor_{np_scalar_type} = tabulate_tensor_{factory_name},"
)
assert ir.expression.coordinate_element_hash is not None
implementation = ufcx_integrals.factory.format(
factory_name=factory_name,
enabled_coefficients=code["enabled_coefficients"],
enabled_coefficients_init=code["enabled_coefficients_init"],
tabulate_tensor=code["tabulate_tensor"],
needs_facet_permutations="true" if ir.expression.needs_facet_permutations else "false",
scalar_type=dtype_to_c_type(options["scalar_type"]), # type: ignore
geom_type=dtype_to_c_type(dtype_to_scalar_dtype(options["scalar_type"])), # type: ignore
coordinate_element_hash=f"UINT64_C({ir.expression.coordinate_element_hash})",
tabulate_tensor_float32=code["tabulate_tensor_float32"],
tabulate_tensor_float64=code["tabulate_tensor_float64"],
tabulate_tensor_complex64=code["tabulate_tensor_complex64"],
tabulate_tensor_complex128=code["tabulate_tensor_complex128"],
domain=int(domain),
)
# TODO: Check that no keys are redundant or have been missed (ref. numba/integrals.py)
# assert set(d.keys()) == template_keys(ufcx_integrals.factory)
return declaration, implementation
=========================
gitextract_d5vvy4xt/
├── .gitattributes
├── .github/
│ ├── FUNDING.yml
│ ├── dependabot.yml
│ └── workflows/
│ ├── build-wheels.yml
│ ├── dolfinx-tests.yml
│ ├── pythonapp.yml
│ └── spack.yml
├── .gitignore
├── AUTHORS
├── CODE_OF_CONDUCT.md
├── COPYING
├── COPYING.LESSER
├── ChangeLog.rst
├── LICENSE
├── MANIFEST.in
├── README.md
├── UNLICENSE
├── _clang-format
├── cmake/
│ ├── CMakeLists.txt
│ ├── ufcx.pc.in
│ └── ufcxConfig.cmake.in
├── demo/
│ ├── BiharmonicHHJ.py
│ ├── BiharmonicRegge.py
│ ├── CellGeometry.py
│ ├── ComplexPoisson.py
│ ├── Components.py
│ ├── Conditional.py
│ ├── ExpressionInterpolation.py
│ ├── FacetIntegrals.py
│ ├── FacetRestrictionAD.py
│ ├── HyperElasticity.py
│ ├── MassAction.py
│ ├── MassDG0.py
│ ├── MassHcurl_2D_1.py
│ ├── MassHdiv_2D_1.py
│ ├── MathFunctions.py
│ ├── MetaData.py
│ ├── Mini.py
│ ├── MixedCoefficient.py
│ ├── MixedPoissonDual.py
│ ├── Normals.py
│ ├── Poisson1D.py
│ ├── PoissonQuad.py
│ ├── ProjectionManifold.py
│ ├── ReactionDiffusion.py
│ ├── SpatialCoordinates.py
│ ├── StabilisedStokes.py
│ ├── Symmetry.py
│ ├── VectorConstant.py
│ ├── VectorPoisson.py
│ └── test_demos.py
├── doc/
│ └── source/
│ ├── conf.py
│ └── index.rst
├── ffcx/
│ ├── __init__.py
│ ├── __main__.py
│ ├── analysis.py
│ ├── codegeneration/
│ │ ├── C/
│ │ │ ├── __init__.py
│ │ │ ├── expression.py
│ │ │ ├── expression_template.py
│ │ │ ├── file.py
│ │ │ ├── file_template.py
│ │ │ ├── form.py
│ │ │ ├── form_template.py
│ │ │ ├── formatter.py
│ │ │ ├── integral.py
│ │ │ └── integral_template.py
│ │ ├── __init__.py
│ │ ├── access.py
│ │ ├── backend.py
│ │ ├── codegeneration.py
│ │ ├── common.py
│ │ ├── definitions.py
│ │ ├── expression_generator.py
│ │ ├── geometry.py
│ │ ├── integral_generator.py
│ │ ├── interface.py
│ │ ├── jit.py
│ │ ├── lnodes.py
│ │ ├── numba/
│ │ │ ├── __init__.py
│ │ │ ├── expression.py
│ │ │ ├── expression_template.py
│ │ │ ├── file.py
│ │ │ ├── file_template.py
│ │ │ ├── form.py
│ │ │ ├── form_template.py
│ │ │ ├── formatter.py
│ │ │ ├── integral.py
│ │ │ └── integral_template.py
│ │ ├── optimizer.py
│ │ ├── symbols.py
│ │ ├── ufcx.h
│ │ └── utils.py
│ ├── compiler.py
│ ├── definitions.py
│ ├── element_interface.py
│ ├── formatting.py
│ ├── ir/
│ │ ├── __init__.py
│ │ ├── analysis/
│ │ │ ├── __init__.py
│ │ │ ├── factorization.py
│ │ │ ├── graph.py
│ │ │ ├── indexing.py
│ │ │ ├── modified_terminals.py
│ │ │ ├── reconstruct.py
│ │ │ ├── valuenumbering.py
│ │ │ └── visualise.py
│ │ ├── elementtables.py
│ │ ├── integral.py
│ │ ├── representation.py
│ │ └── representationutils.py
│ ├── main.py
│ ├── naming.py
│ ├── options.py
│ └── py.typed
├── pyproject.toml
└── test/
├── conftest.py
├── poisson.py
├── test_add_mode.py
├── test_cache.py
├── test_cmdline.py
├── test_custom_data.py
├── test_jit_expression.py
├── test_jit_forms.py
├── test_lnodes.py
├── test_numba.py
├── test_signatures.py
├── test_submesh.py
└── test_tensor_product.py
SYMBOL INDEX (527 symbols across 59 files)
FILE: demo/BiharmonicHHJ.py
function b (line 37) | def b(sigma, v):
FILE: demo/BiharmonicRegge.py
function S (line 38) | def S(mu):
function b (line 43) | def b(mu, v):
FILE: demo/test_demos.py
function skip_unsupported (line 21) | def skip_unsupported(test):
function test_C (line 39) | def test_C(file, scalar_type):
function test_numba (line 83) | def test_numba(file, scalar_type):
FILE: ffcx/analysis.py
class UFLData (line 30) | class UFLData(typing.NamedTuple):
function analyze_ufl_objects (line 45) | def analyze_ufl_objects(
function _analyze_expression (line 128) | def _analyze_expression(
function _analyze_form (line 152) | def _analyze_form(form: ufl.Form, scalar_type: npt.DTypeLike) -> FormData:
function _has_custom_integrals (line 256) | def _has_custom_integrals(
FILE: ffcx/codegeneration/C/expression.py
function generator (line 25) | def generator(ir: ExpressionIR, options):
FILE: ffcx/codegeneration/C/file.py
function generator (line 26) | def generator(options):
FILE: ffcx/codegeneration/C/form.py
function generator (line 24) | def generator(ir: FormIR, options):
FILE: ffcx/codegeneration/C/formatter.py
class Formatter (line 147) | class Formatter(FormatterInterface):
method __init__ (line 153) | def __init__(self, dtype: npt.DTypeLike) -> None:
method _dtype_to_name (line 158) | def _dtype_to_name(self, dtype) -> str:
method _format_number (line 170) | def _format_number(self, x):
method _build_initializer_lists (line 179) | def _build_initializer_lists(self, values):
method __call__ (line 190) | def __call__(self, obj: L.LNode) -> str:
method _ (line 195) | def _(self, slist: L.StatementList) -> str:
method _ (line 200) | def _(self, section: L.Section) -> str:
method _ (line 222) | def _(self, c: L.Comment) -> str:
method _ (line 227) | def _(self, arr: L.ArrayDecl) -> str:
method _ (line 243) | def _(self, arr: L.ArrayAccess) -> str:
method _ (line 250) | def _(self, v: L.VariableDecl) -> str:
method _ (line 258) | def _(self, oper: L.NaryOp) -> str:
method _ (line 272) | def _(self, oper: L.BinOp) -> str:
method _ (line 289) | def _(self, oper: L.Neg | L.Not) -> str:
method _ (line 297) | def _(self, val: L.LiteralFloat) -> str:
method _ (line 303) | def _(self, val: L.LiteralInt) -> str:
method _ (line 308) | def _(self, r: L.ForRange) -> str:
method _ (line 323) | def _(self, s: L.Statement) -> str:
method _ (line 329) | def _(self, expr: L.Assign | L.AssignAdd) -> str:
method _ (line 336) | def _(self, s: L.Conditional) -> str:
method _ (line 355) | def _(self, s: L.Symbol) -> str:
method _ (line 360) | def _(self, mi: L.MultiIndex) -> str:
method _ (line 365) | def _(self, c: L.MathFunction) -> str:
FILE: ffcx/codegeneration/C/integral.py
function generator (line 25) | def generator(
FILE: ffcx/codegeneration/__init__.py
function get_include_path (line 16) | def get_include_path():
function _compute_signature (line 21) | def _compute_signature():
function get_signature (line 32) | def get_signature():
FILE: ffcx/codegeneration/access.py
class FFCXBackendAccess (line 23) | class FFCXBackendAccess:
method __init__ (line 28) | def __init__(self, entity_type: entity_types, integral_type: str, symb...
method get (line 59) | def get(
method coefficient (line 81) | def coefficient(
method constant (line 106) | def constant(
method spatial_coordinate (line 117) | def spatial_coordinate(
method cell_coordinate (line 148) | def cell_coordinate(self, mt, tabledata, num_points):
method facet_coordinate (line 174) | def facet_coordinate(self, mt, tabledata, num_points):
method jacobian (line 210) | def jacobian(self, mt, tabledata, num_points):
method reference_cell_volume (line 216) | def reference_cell_volume(self, mt, tabledata, access):
method reference_facet_volume (line 224) | def reference_facet_volume(self, mt, tabledata, access):
method reference_normal (line 232) | def reference_normal(self, mt, tabledata, access):
method cell_facet_jacobian (line 242) | def cell_facet_jacobian(self, mt, tabledata, num_points):
method cell_ridge_jacobian (line 261) | def cell_ridge_jacobian(self, mt, tabledata, num_points):
method reference_cell_edge_vectors (line 273) | def reference_cell_edge_vectors(self, mt, tabledata, num_points):
method reference_facet_edge_vectors (line 286) | def reference_facet_edge_vectors(self, mt, tabledata, num_points):
method facet_orientation (line 300) | def facet_orientation(self, mt, tabledata, num_points):
method cell_vertices (line 310) | def cell_vertices(self, mt, tabledata, num_points):
method cell_edge_vectors (line 334) | def cell_edge_vectors(self, mt, tabledata, num_points):
method facet_edge_vectors (line 374) | def facet_edge_vectors(self, mt, tabledata, num_points):
method _pass (line 419) | def _pass(self, *args, **kwargs):
method table_access (line 423) | def table_access(
FILE: ffcx/codegeneration/backend.py
class FFCXBackend (line 16) | class FFCXBackend:
method __init__ (line 19) | def __init__(self, ir: IntegralIR | ExpressionIR, options):
FILE: ffcx/codegeneration/codegeneration.py
class CodeBlocks (line 27) | class CodeBlocks(typing.NamedTuple):
function generate_code (line 41) | def generate_code(
FILE: ffcx/codegeneration/common.py
function template_keys (line 19) | def template_keys(template: str) -> set[str]:
class IntegralData (line 24) | class IntegralData(NamedTuple):
function integral_data (line 33) | def integral_data(ir: FormIR) -> IntegralData:
class KernelTensorSizes (line 51) | class KernelTensorSizes(NamedTuple):
function tensor_sizes (line 63) | def tensor_sizes(ir: IntegralIR | ExpressionIR) -> KernelTensorSizes:
function _ (line 69) | def _(ir: IntegralIR) -> KernelTensorSizes:
function _ (line 85) | def _(ir: ExpressionIR) -> KernelTensorSizes:
FILE: ffcx/codegeneration/definitions.py
function create_quadrature_index (line 21) | def create_quadrature_index(quadrature_rule, quadrature_index_symbol):
function create_dof_index (line 36) | def create_dof_index(tabledata, dof_index_symbol):
class FFCXBackendDefinitions (line 50) | class FFCXBackendDefinitions:
method __init__ (line 55) | def __init__(self, entity_type: entity_types, integral_type: str, acce...
method symbols (line 84) | def symbols(self):
method get (line 88) | def get(
method coefficient (line 113) | def coefficient(
method _define_coordinate_dofs_lincomb (line 173) | def _define_coordinate_dofs_lincomb(
method spatial_coordinate (line 229) | def spatial_coordinate(
method jacobian (line 255) | def jacobian(
method pass_through (line 265) | def pass_through(
FILE: ffcx/codegeneration/expression_generator.py
class ExpressionGenerator (line 24) | class ExpressionGenerator:
method __init__ (line 27) | def __init__(self, ir: ExpressionIR, backend: FFCXBackend):
method generate (line 40) | def generate(self):
method generate_geometry_tables (line 62) | def generate_geometry_tables(self):
method generate_element_tables (line 96) | def generate_element_tables(self):
method generate_quadrature_loop (line 120) | def generate_quadrature_loop(self):
method generate_varying_partition (line 146) | def generate_varying_partition(self):
method generate_piecewise_partition (line 159) | def generate_piecewise_partition(self):
method generate_dofblock_partition (line 172) | def generate_dofblock_partition(self):
method generate_block_parts (line 199) | def generate_block_parts(self, blockmap, blockdata):
method get_arg_factors (line 288) | def get_arg_factors(self, blockdata, block_rank, indices):
method new_temp_symbol (line 317) | def new_temp_symbol(self, basename):
method get_var (line 323) | def get_var(self, v):
method generate_partition (line 330) | def generate_partition(self, symbol, F, mode):
FILE: ffcx/codegeneration/geometry.py
function write_table (line 14) | def write_table(tablename, cellname):
function facet_edge_vertices (line 37) | def facet_edge_vertices(tablename, cellname):
function cell_facet_jacobian (line 61) | def cell_facet_jacobian(tablename, cellname):
function cell_ridge_jacobian (line 69) | def cell_ridge_jacobian(tablename, cellname):
function reference_cell_volume (line 77) | def reference_cell_volume(tablename, cellname):
function reference_facet_volume (line 85) | def reference_facet_volume(tablename, cellname):
function reference_cell_edge_vectors (line 96) | def reference_cell_edge_vectors(tablename, cellname):
function reference_facet_edge_vectors (line 107) | def reference_facet_edge_vectors(tablename, cellname):
function reference_normals (line 134) | def reference_normals(tablename, cellname):
function facet_orientation (line 142) | def facet_orientation(tablename, cellname):
FILE: ffcx/codegeneration/integral_generator.py
function extract_dtype (line 30) | def extract_dtype(v, vops: list[Any]):
class IntegralGenerator (line 51) | class IntegralGenerator:
method __init__ (line 54) | def __init__(self, ir: IntegralIR, backend):
method init_scopes (line 79) | def init_scopes(self):
method set_var (line 87) | def set_var(self, quadrature_rule, domain, v, vaccess):
method get_var (line 101) | def get_var(self, quadrature_rule, domain, v):
method new_temp_symbol (line 123) | def new_temp_symbol(self, basename):
method get_temp_symbol (line 129) | def get_temp_symbol(self, tempname, key):
method generate (line 139) | def generate(self, domain: basix.CellType):
method generate_quadrature_tables (line 185) | def generate_quadrature_tables(self, domain: basix.CellType, expressio...
method generate_geometry_tables (line 204) | def generate_geometry_tables(self):
method generate_element_tables (line 236) | def generate_element_tables(self, domain: basix.CellType):
method declare_table (line 265) | def declare_table(self, name, table):
method generate_quadrature_loop (line 276) | def generate_quadrature_loop(self, quadrature_rule: QuadratureRule, do...
method generate_piecewise_partition (line 309) | def generate_piecewise_partition(self, quadrature_rule, domain: basix....
method generate_varying_partition (line 316) | def generate_varying_partition(self, quadrature_rule, domain: basix.Ce...
method generate_partition (line 323) | def generate_partition(self, symbol, F, mode, quadrature_rule, domain):
method generate_dofblock_partition (line 370) | def generate_dofblock_partition(
method get_arg_factors (line 415) | def get_arg_factors(self, blockdata, block_rank, quadrature_rule, doma...
method generate_block_parts (line 446) | def generate_block_parts(
FILE: ffcx/codegeneration/interface.py
class Formatter (line 22) | class Formatter(Protocol):
method __init__ (line 25) | def __init__(self, dtype: npt.DTypeLike) -> None:
method __call__ (line 29) | def __call__(self, obj: L.LNode) -> str:
FILE: ffcx/codegeneration/jit.py
function _compute_option_signature (line 81) | def _compute_option_signature(options):
function get_cached_module (line 86) | def get_cached_module(module_name, object_names, cache_dir, timeout):
function _compilation_signature (line 128) | def _compilation_signature(cffi_extra_compile_args, cffi_debug):
function compile_forms (line 152) | def compile_forms(
function compile_expressions (line 250) | def compile_expressions(
function _compile_objects (line 330) | def _compile_objects(
function _load_objects (line 421) | def _load_objects(cache_dir, module_name, object_names):
FILE: ffcx/codegeneration/lnodes.py
class PRECEDENCE (line 34) | class PRECEDENCE:
function is_zero_lexpr (line 64) | def is_zero_lexpr(lexpr):
function is_one_lexpr (line 71) | def is_one_lexpr(lexpr):
function is_negative_one_lexpr (line 78) | def is_negative_one_lexpr(lexpr):
function float_product (line 85) | def float_product(factors):
class DataType (line 99) | class DataType(Enum):
function merge_dtypes (line 113) | def merge_dtypes(dtypes: list[DataType]):
class LNode (line 129) | class LNode:
method __eq__ (line 132) | def __eq__(self, other):
method __ne__ (line 136) | def __ne__(self, other):
class LExpr (line 141) | class LExpr(LNode):
method __getitem__ (line 149) | def __getitem__(self, indices):
method __neg__ (line 153) | def __neg__(self):
method __add__ (line 161) | def __add__(self, other):
method __radd__ (line 172) | def __radd__(self, other):
method __sub__ (line 183) | def __sub__(self, other):
method __rsub__ (line 196) | def __rsub__(self, other):
method __mul__ (line 207) | def __mul__(self, other):
method __rmul__ (line 226) | def __rmul__(self, other):
method __div__ (line 243) | def __div__(self, other):
method __rdiv__ (line 252) | def __rdiv__(self, other):
class LExprOperator (line 268) | class LExprOperator(LExpr):
class LExprTerminal (line 276) | class LExprTerminal(LExpr):
class LiteralFloat (line 284) | class LiteralFloat(LExprTerminal):
method __init__ (line 291) | def __init__(self, value):
method __eq__ (line 300) | def __eq__(self, other):
method __float__ (line 304) | def __float__(self):
method __repr__ (line 308) | def __repr__(self):
class LiteralInt (line 313) | class LiteralInt(LExprTerminal):
method __init__ (line 318) | def __init__(self, value):
method __eq__ (line 324) | def __eq__(self, other):
method __hash__ (line 328) | def __hash__(self):
method __repr__ (line 332) | def __repr__(self):
class Symbol (line 337) | class Symbol(LExprTerminal):
method __init__ (line 342) | def __init__(self, name: str, dtype):
method __eq__ (line 349) | def __eq__(self, other):
method __hash__ (line 353) | def __hash__(self):
method __repr__ (line 357) | def __repr__(self):
class MultiIndex (line 362) | class MultiIndex(LExpr):
method __init__ (line 367) | def __init__(self, symbols: list, sizes: list):
method dim (line 383) | def dim(self):
method size (line 387) | def size(self):
method local_index (line 391) | def local_index(self, idx):
method intersection (line 396) | def intersection(self, other):
method union (line 408) | def union(self, other):
method difference (line 425) | def difference(self, other):
method __hash__ (line 435) | def __hash__(self):
class PrefixUnaryOp (line 440) | class PrefixUnaryOp(LExprOperator):
method __init__ (line 443) | def __init__(self, arg):
method __eq__ (line 447) | def __eq__(self, other):
class BinOp (line 452) | class BinOp(LExprOperator):
method __init__ (line 457) | def __init__(self, lhs, rhs):
method __eq__ (line 462) | def __eq__(self, other):
method __hash__ (line 466) | def __hash__(self):
method __repr__ (line 470) | def __repr__(self):
class ArithmeticBinOp (line 475) | class ArithmeticBinOp(BinOp):
method __init__ (line 478) | def __init__(self, lhs, rhs):
class NaryOp (line 485) | class NaryOp(LExprOperator):
method __init__ (line 490) | def __init__(self, args):
method __eq__ (line 497) | def __eq__(self, other):
method __repr__ (line 505) | def __repr__(self) -> str:
method __hash__ (line 509) | def __hash__(self):
class Neg (line 514) | class Neg(PrefixUnaryOp):
method __init__ (line 520) | def __init__(self, arg):
class Not (line 526) | class Not(PrefixUnaryOp):
class Add (line 533) | class Add(ArithmeticBinOp):
class Sub (line 540) | class Sub(ArithmeticBinOp):
class Mul (line 547) | class Mul(ArithmeticBinOp):
class Div (line 554) | class Div(ArithmeticBinOp):
class EQ (line 561) | class EQ(BinOp):
class NE (line 568) | class NE(BinOp):
class LT (line 575) | class LT(BinOp):
class GT (line 582) | class GT(BinOp):
class LE (line 589) | class LE(BinOp):
class GE (line 596) | class GE(BinOp):
class And (line 603) | class And(BinOp):
class Or (line 610) | class Or(BinOp):
class Sum (line 617) | class Sum(NaryOp):
class Product (line 624) | class Product(NaryOp):
class MathFunction (line 631) | class MathFunction(LExprOperator):
method __init__ (line 636) | def __init__(self, func, args):
method __eq__ (line 642) | def __eq__(self, other):
class AssignOp (line 652) | class AssignOp(BinOp):
method __init__ (line 658) | def __init__(self, lhs, rhs):
class Assign (line 664) | class Assign(AssignOp):
class AssignAdd (line 670) | class AssignAdd(AssignOp):
class AssignSub (line 676) | class AssignSub(AssignOp):
class AssignMul (line 682) | class AssignMul(AssignOp):
class AssignDiv (line 688) | class AssignDiv(AssignOp):
class ArrayAccess (line 694) | class ArrayAccess(LExprOperator):
method __init__ (line 699) | def __init__(self, array, indices):
method __getitem__ (line 731) | def __getitem__(self, indices):
method __eq__ (line 739) | def __eq__(self, other):
method __hash__ (line 747) | def __hash__(self):
method __repr__ (line 751) | def __repr__(self):
class Conditional (line 756) | class Conditional(LExprOperator):
method __init__ (line 761) | def __init__(self, condition, true, false):
method __eq__ (line 768) | def __eq__(self, other):
function as_lexpr (line 778) | def as_lexpr(node):
class Statement (line 794) | class Statement(LNode):
method __init__ (line 797) | def __init__(self, expr):
method __eq__ (line 801) | def __eq__(self, other):
method __hash__ (line 805) | def __hash__(self) -> int:
function as_statement (line 810) | def as_statement(node):
class Annotation (line 840) | class Annotation(Enum):
class Declaration (line 849) | class Declaration(Statement):
method __init__ (line 852) | def __init__(self, symbol):
method __eq__ (line 856) | def __eq__(self, other):
function is_declaration (line 861) | def is_declaration(node) -> bool:
class Section (line 866) | class Section(LNode):
method __init__ (line 869) | def __init__(
method __eq__ (line 891) | def __eq__(self, other):
class StatementList (line 899) | class StatementList(LNode):
method __init__ (line 902) | def __init__(self, statements):
method __eq__ (line 906) | def __eq__(self, other):
method __hash__ (line 910) | def __hash__(self) -> int:
method __repr__ (line 914) | def __repr__(self):
class Comment (line 919) | class Comment(Statement):
method __init__ (line 922) | def __init__(self, comment: str):
method __eq__ (line 927) | def __eq__(self, other):
function commented_code_list (line 932) | def commented_code_list(code, comments):
class VariableDecl (line 948) | class VariableDecl(Declaration):
method __init__ (line 951) | def __init__(self, symbol, value=None):
method __eq__ (line 961) | def __eq__(self, other):
class ArrayDecl (line 971) | class ArrayDecl(Declaration):
method __init__ (line 982) | def __init__(self, symbol, sizes=None, values=None, const=False):
method __eq__ (line 1007) | def __eq__(self, other):
method __hash__ (line 1014) | def __hash__(self) -> int:
function is_simple_inner_loop (line 1019) | def is_simple_inner_loop(code):
function depth (line 1028) | def depth(code) -> int:
class ForRange (line 1037) | class ForRange(Statement):
method __init__ (line 1040) | def __init__(self, index, begin, end, body):
method as_tuple (line 1049) | def as_tuple(self):
method __eq__ (line 1053) | def __eq__(self, other):
method __hash__ (line 1060) | def __hash__(self) -> int:
function _math_function (line 1065) | def _math_function(op, *args):
function ufl_to_lnodes (line 1125) | def ufl_to_lnodes(operator, *args):
function create_nested_for_loops (line 1134) | def create_nested_for_loops(indices: list[MultiIndex], body):
FILE: ffcx/codegeneration/numba/expression.py
function generator (line 23) | def generator(ir: ExpressionIR, options: dict[str, int | float | npt.DTy...
FILE: ffcx/codegeneration/numba/file.py
function generator (line 28) | def generator(
FILE: ffcx/codegeneration/numba/form.py
function generator (line 22) | def generator(ir: FormIR, options: dict[str, int | float | npt.DTypeLike...
FILE: ffcx/codegeneration/numba/formatter.py
function build_initializer_lists (line 18) | def build_initializer_lists(values: npt.NDArray) -> str:
class Formatter (line 29) | class Formatter(FormatterInterface):
method __init__ (line 35) | def __init__(self, dtype: npt.DTypeLike) -> None:
method _dtype_to_name (line 40) | def _dtype_to_name(self, dtype: L.DataType) -> str:
method __call__ (line 53) | def __call__(self, obj: L.LNode) -> str:
method _ (line 58) | def _(self, section: L.Section) -> str:
method _ (line 77) | def _(self, slist: L.StatementList) -> str:
method _format_comment_str (line 81) | def _format_comment_str(self, comment: str) -> str:
method _ (line 86) | def _(self, c: L.Comment) -> str:
method _ (line 91) | def _(self, arr: L.ArrayDecl) -> str:
method _ (line 106) | def _(self, arr: L.ArrayAccess) -> str:
method _ (line 113) | def _(self, index: L.MultiIndex) -> str:
method _ (line 118) | def _(self, v: L.VariableDecl) -> str:
method _ (line 125) | def _(self, oper: L.NaryOp) -> str:
method _ (line 139) | def _(self, oper: L.BinOp) -> str:
method _ (line 156) | def _(self, oper: L.Not | L.Neg) -> str:
method _ (line 165) | def _(self, oper: L.And | L.Or) -> str:
method _ (line 183) | def _(self, val: L.LiteralFloat) -> str:
method _ (line 188) | def _(self, val: L.LiteralInt) -> str:
method _ (line 193) | def _(self, r: L.ForRange) -> str:
method _ (line 205) | def _(self, s: L.Statement) -> str:
method _ (line 211) | def _(self, expr: L.Assign | L.AssignAdd) -> str:
method _ (line 218) | def _(self, s: L.Conditional) -> str:
method _ (line 237) | def _(self, s: L.Symbol) -> str:
method _ (line 242) | def _(self, f: L.MathFunction) -> str:
FILE: ffcx/codegeneration/numba/integral.py
function generator (line 24) | def generator(
FILE: ffcx/codegeneration/optimizer.py
function optimize (line 9) | def optimize(code: list[L.LNode], quadrature_rule: QuadratureRule) -> li...
function fuse_sections (line 33) | def fuse_sections(code: list[L.LNode], name: str) -> list[L.LNode]:
function fuse_loops (line 77) | def fuse_loops(code: L.Section) -> L.Section:
function get_statements (line 101) | def get_statements(statement: L.Statement | L.StatementList) -> list[L.L...
function check_dependency (line 116) | def check_dependency(statement: L.Statement, index: L.Symbol) -> bool:
function licm (line 144) | def licm(section: L.Section, quadrature_rule: QuadratureRule) -> L.Section:
FILE: ffcx/codegeneration/symbols.py
function ufcx_restriction_postfix (line 18) | def ufcx_restriction_postfix(restriction):
function format_mt_name (line 30) | def format_mt_name(basename, mt):
class FFCXBackendSymbols (line 65) | class FFCXBackendSymbols:
method __init__ (line 68) | def __init__(self, coefficient_numbering, coefficient_offsets, origina...
method entity (line 99) | def entity(self, entity_type: entity_types, restriction):
method argument_loop_index (line 117) | def argument_loop_index(self, iarg):
method weights_table (line 122) | def weights_table(self, quadrature_rule):
method points_table (line 131) | def points_table(self, quadrature_rule):
method x_component (line 135) | def x_component(self, mt):
method J_component (line 139) | def J_component(self, mt):
method domain_dof_access (line 146) | def domain_dof_access(self, dof, component, gdim, num_scalar_dofs, res...
method coefficient_dof_access (line 154) | def coefficient_dof_access(self, coefficient, dof_index):
method coefficient_dof_access_blocked (line 160) | def coefficient_dof_access_blocked(
method coefficient_value (line 171) | def coefficient_value(self, mt):
method constant_index_access (line 176) | def constant_index_access(self, constant, index):
method element_table (line 183) | def element_table(self, tabledata, entity_type: entity_types, restrict...
FILE: ffcx/codegeneration/ufcx.h
type ufcx_integral_type (line 48) | typedef enum
type ufcx_integral (line 134) | typedef struct ufcx_integral
type ufcx_expression (line 151) | typedef struct ufcx_expression
type ufcx_form (line 220) | typedef struct ufcx_form
FILE: ffcx/codegeneration/utils.py
function dtype_to_c_type (line 17) | def dtype_to_c_type(dtype: npt.DTypeLike | str) -> str:
function dtype_to_scalar_dtype (line 43) | def dtype_to_scalar_dtype(dtype: npt.DTypeLike | str) -> np.dtype:
function numba_ufcx_kernel_signature (line 62) | def numba_ufcx_kernel_signature(dtype: npt.DTypeLike, xdtype: npt.DTypeL...
function empty_void_pointer (line 95) | def empty_void_pointer(typingctx):
function get_void_pointer (line 116) | def get_void_pointer(typingctx, arr):
FILE: ffcx/compiler.py
function _print_timing (line 82) | def _print_timing(stage: int, timing: float) -> None:
function compile_ufl_objects (line 86) | def compile_ufl_objects(
FILE: ffcx/element_interface.py
function basix_index (line 15) | def basix_index(indices: tuple[int]) -> int:
function create_quadrature (line 20) | def create_quadrature(
function reference_cell_vertices (line 36) | def reference_cell_vertices(cellname: str) -> npt.NDArray[np.float64]:
function map_facet_points (line 41) | def map_facet_points(
function map_edge_points (line 57) | def map_edge_points(
FILE: ffcx/formatting.py
function format_code (line 23) | def format_code(code_blocks: CodeBlocks) -> list[str]:
function write_code (line 41) | def write_code(code: list[str], prefix: str, suffixes: tuple[str, ...], ...
FILE: ffcx/ir/analysis/factorization.py
function build_argument_indices (line 20) | def build_argument_indices(S):
function graph_insert (line 41) | def graph_insert(F, expr):
function handler (line 56) | def handler(v, fac, sf, F):
function handle_sum (line 69) | def handle_sum(v, fac, sf, F):
function handle_product (line 105) | def handle_product(v, fac, sf, F):
function handle_conj (line 145) | def handle_conj(v, fac, sf, F):
function handle_division (line 160) | def handle_division(v, fac, sf, F):
function handle_conditional (line 181) | def handle_conditional(v, fac, sf, F):
function compute_argument_factorization (line 218) | def compute_argument_factorization(S, rank):
FILE: ffcx/ir/analysis/graph.py
class ExpressionGraph (line 20) | class ExpressionGraph:
method __init__ (line 27) | def __init__(self):
method number_of_nodes (line 35) | def number_of_nodes(self):
method add_node (line 39) | def add_node(self, key, **kwargs):
method add_edge (line 45) | def add_edge(self, node1, node2):
function build_graph_vertices (line 54) | def build_graph_vertices(expressions, skip_terminal_modifiers=False) -> ...
function build_scalar_graph (line 77) | def build_scalar_graph(expression) -> ExpressionGraph:
function rebuild_with_scalar_subexpressions (line 107) | def rebuild_with_scalar_subexpressions(G):
function _count_nodes_with_unique_post_traversal (line 208) | def _count_nodes_with_unique_post_traversal(expressions, skip_terminal_m...
FILE: ffcx/ir/analysis/indexing.py
function map_indexed_arg_components (line 14) | def map_indexed_arg_components(indexed):
function map_component_tensor_arg_components (line 87) | def map_component_tensor_arg_components(tensor):
FILE: ffcx/ir/analysis/modified_terminals.py
class ModifiedTerminal (line 29) | class ModifiedTerminal:
method __init__ (line 32) | def __init__(
method as_tuple (line 90) | def as_tuple(self):
method argument_ordering_key (line 108) | def argument_ordering_key(self):
method __hash__ (line 130) | def __hash__(self):
method __eq__ (line 134) | def __eq__(self, other):
method __str__ (line 138) | def __str__(self):
function is_modified_terminal (line 150) | def is_modified_terminal(v):
function strip_modified_terminal (line 160) | def strip_modified_terminal(v):
function analyse_modified_terminal (line 170) | def analyse_modified_terminal(expr):
FILE: ffcx/ir/analysis/reconstruct.py
function handle_scalar_nary (line 11) | def handle_scalar_nary(o, ops):
function handle_condition (line 19) | def handle_condition(o, ops):
function handle_conditional (line 26) | def handle_conditional(o, ops):
function handle_elementwise_unary (line 41) | def handle_elementwise_unary(o, ops):
function handle_division (line 48) | def handle_division(o, ops):
function handle_sum (line 58) | def handle_sum(o, ops):
function handle_product (line 67) | def handle_product(o, ops):
function handle_index_sum (line 115) | def handle_index_sum(o, ops):
function reconstruct (line 173) | def reconstruct(o, *args):
FILE: ffcx/ir/analysis/valuenumbering.py
class ValueNumberer (line 22) | class ValueNumberer:
method __init__ (line 30) | def __init__(self, G):
method new_symbols (line 51) | def new_symbols(self, n):
method new_symbol (line 58) | def new_symbol(self):
method get_node_symbols (line 64) | def get_node_symbols(self, expr):
method compute_symbols (line 69) | def compute_symbols(self):
method expr (line 93) | def expr(self, v):
method form_argument (line 98) | def form_argument(self, v):
method _modified_terminal (line 125) | def _modified_terminal(self, v):
method indexed (line 198) | def indexed(self, Aii):
method component_tensor (line 214) | def component_tensor(self, A):
method list_tensor (line 227) | def list_tensor(self, v):
method variable (line 234) | def variable(self, v):
FILE: ffcx/ir/analysis/visualise.py
function visualise_graph (line 22) | def visualise_graph(Gx, filename):
FILE: ffcx/ir/elementtables.py
class ModifiedTerminalElement (line 46) | class ModifiedTerminalElement(typing.NamedTuple):
class UniqueTableReferenceT (line 55) | class UniqueTableReferenceT(typing.NamedTuple):
method has_tensor_factorisation (line 72) | def has_tensor_factorisation(self):
method is_piecewise (line 77) | def is_piecewise(self) -> bool:
method is_uniform (line 82) | def is_uniform(self) -> bool:
function equal_tables (line 87) | def equal_tables(a, b, rtol=default_rtol, atol=default_atol):
function clamp_table_small_numbers (line 97) | def clamp_table_small_numbers(
function get_ffcx_table_values (line 108) | def get_ffcx_table_values(
function generate_psi_table_name (line 211) | def generate_psi_table_name(
function get_modified_terminal_element (line 247) | def get_modified_terminal_element(mt) -> ModifiedTerminalElement | None:
function permute_quadrature_interval (line 311) | def permute_quadrature_interval(points, reflections=0):
function permute_quadrature_triangle (line 323) | def permute_quadrature_triangle(points, reflections=0, rotations=0):
function permute_quadrature_quadrilateral (line 337) | def permute_quadrature_quadrilateral(points, reflections=0, rotations=0):
function build_optimized_tables (line 351) | def build_optimized_tables(
function is_zeros_table (line 656) | def is_zeros_table(table, rtol=default_rtol, atol=default_atol):
function is_ones_table (line 663) | def is_ones_table(table, rtol=default_rtol, atol=default_atol):
function is_quadrature_table (line 668) | def is_quadrature_table(table, rtol=default_rtol, atol=default_atol):
function is_permuted_table (line 677) | def is_permuted_table(table, rtol=default_rtol, atol=default_atol):
function is_piecewise_table (line 685) | def is_piecewise_table(table, rtol=default_rtol, atol=default_atol):
function is_uniform_table (line 693) | def is_uniform_table(table, rtol=default_rtol, atol=default_atol):
function analyse_table_type (line 701) | def analyse_table_type(table, rtol=default_rtol, atol=default_atol):
FILE: ffcx/ir/integral.py
class TensorPart (line 43) | class TensorPart(Enum):
method from_str (line 50) | def from_str(cls, value: str):
method __str__ (line 59) | def __str__(self) -> str:
method __int__ (line 68) | def __int__(self) -> int:
class ModifiedArgumentDataT (line 73) | class ModifiedArgumentDataT(typing.NamedTuple):
class BlockDataT (line 80) | class BlockDataT(typing.NamedTuple):
class IntermediateIntegrandIR (line 94) | class IntermediateIntegrandIR(typing.TypedDict):
class IntermediateIntegralIR (line 102) | class IntermediateIntegralIR(typing.TypedDict):
class CommonExpressionIR (line 111) | class CommonExpressionIR(typing.NamedTuple):
function _compute_integral_ir (line 135) | def _compute_integral_ir(
function compute_integral_ir (line 387) | def compute_integral_ir(
function analyse_dependencies (line 467) | def analyse_dependencies(F, mt_unique_table_reference):
function replace_quadratureweight (line 524) | def replace_quadratureweight(expression):
FILE: ffcx/ir/representation.py
function basix_cell_from_string (line 49) | def basix_cell_from_string(string: str) -> basix.CellType:
class FormIR (line 73) | class FormIR(typing.NamedTuple):
class QuadratureIR (line 94) | class QuadratureIR(typing.NamedTuple):
class IntegralIR (line 102) | class IntegralIR(typing.NamedTuple):
class ExpressionIR (line 111) | class ExpressionIR(typing.NamedTuple):
class DataIR (line 121) | class DataIR(typing.NamedTuple):
function _group_integrands_by_quadrature_rule (line 129) | def _group_integrands_by_quadrature_rule(
function compute_ir (line 231) | def compute_ir(
function _compute_integral_ir (line 311) | def _compute_integral_ir(
function _compute_form_ir (line 490) | def _compute_form_ir(
function _compute_expression_ir (line 574) | def _compute_expression_ir(
FILE: ffcx/ir/representationutils.py
class QuadratureRule (line 25) | class QuadratureRule:
method __init__ (line 28) | def __init__(self, points, weights, tensor_factors=None):
method __hash__ (line 36) | def __hash__(self):
method __eq__ (line 43) | def __eq__(self, other):
method id (line 47) | def id(self):
function create_quadrature_points_and_weights (line 57) | def create_quadrature_points_and_weights(
function integral_type_to_entity_dim (line 112) | def integral_type_to_entity_dim(integral_type, tdim):
function map_integral_points (line 131) | def map_integral_points(points, integral_type, cell, entity):
FILE: ffcx/main.py
function main (line 78) | def main(args: Sequence[str] | None = None) -> int:
FILE: ffcx/naming.py
function compute_signature (line 22) | def compute_signature(
function integral_name (line 84) | def integral_name(
function form_name (line 96) | def form_name(original_form: ufl.form.Form, form_id: int, prefix: str) -...
function expression_name (line 102) | def expression_name(
FILE: ffcx/options.py
function _load_options (line 55) | def _load_options() -> tuple[dict, dict]:
function get_options (line 76) | def get_options(
function get_language (line 128) | def get_language(options: dict[str, int | float | npt.DTypeLike]) -> str:
FILE: test/conftest.py
function compile_args (line 14) | def compile_args():
FILE: test/test_add_mode.py
function test_additive_facet_integral (line 41) | def test_additive_facet_integral(dtype, compile_args):
function test_additive_cell_integral (line 117) | def test_additive_cell_integral(dtype, compile_args):
FILE: test/test_cache.py
function test_cache_modes (line 15) | def test_cache_modes(compile_args):
FILE: test/test_cmdline.py
function test_cmdline_simple (line 14) | def test_cmdline_simple():
function test_visualise (line 22) | def test_visualise():
FILE: test/test_custom_data.py
function test_tabulate_tensor_integral_add_values (line 11) | def test_tabulate_tensor_integral_add_values():
FILE: test/test_jit_expression.py
function test_matvec (line 17) | def test_matvec(compile_args):
function test_rank1 (line 88) | def test_rank1(compile_args):
function test_elimiate_zero_tables_tensor (line 158) | def test_elimiate_zero_tables_tensor(compile_args):
function test_grad_constant (line 224) | def test_grad_constant(compile_args):
function test_facet_expression (line 273) | def test_facet_expression(compile_args):
function test_facet_geometry_expressions (line 335) | def test_facet_geometry_expressions(compile_args):
function test_facet_geometry_expressions_3D (line 402) | def test_facet_geometry_expressions_3D(compile_args):
function test_coordinate_free_expression (line 444) | def test_coordinate_free_expression(compile_args):
function test_mixed_mesh_expression (line 487) | def test_mixed_mesh_expression(compile_args):
FILE: test/test_jit_forms.py
function test_laplace_bilinear_form_2d (line 48) | def test_laplace_bilinear_form_2d(dtype, expected_result, compile_args):
function test_mass_bilinear_form_2d (line 165) | def test_mass_bilinear_form_2d(dtype, expected_result, compile_args):
function test_helmholtz_form_2d (line 198) | def test_helmholtz_form_2d(dtype, expected_result, compile_args):
function test_laplace_bilinear_form_3d (line 280) | def test_laplace_bilinear_form_3d(dtype, expected_result, compile_args):
function test_form_coefficient (line 319) | def test_form_coefficient(compile_args):
function test_subdomains (line 360) | def test_subdomains(compile_args):
function test_interior_facet_integral (line 415) | def test_interior_facet_integral(dtype, compile_args):
function test_conditional (line 480) | def test_conditional(dtype, compile_args):
function test_custom_quadrature (line 549) | def test_custom_quadrature(compile_args):
function test_curl_curl (line 601) | def test_curl_curl(compile_args):
function lagrange_triangle_symbolic (line 614) | def lagrange_triangle_symbolic(order, corners=((1, 0), (2, 0), (0, 1)), ...
function test_lagrange_triangle (line 671) | def test_lagrange_triangle(compile_args, order, dtype, sym_fun, ufl_fun):
function lagrange_tetrahedron_symbolic (line 711) | def lagrange_tetrahedron_symbolic(
function test_lagrange_tetrahedron (line 797) | def test_lagrange_tetrahedron(compile_args, order, dtype, sym_fun, ufl_f...
function test_prism (line 839) | def test_prism(compile_args):
function test_complex_operations (line 877) | def test_complex_operations(compile_args):
function test_invalid_function_name (line 944) | def test_invalid_function_name(compile_args):
function test_interval_vertex_quadrature (line 968) | def test_interval_vertex_quadrature(compile_args):
function test_facet_vertex_quadrature (line 1005) | def test_facet_vertex_quadrature(compile_args):
function test_manifold_derivatives (line 1066) | def test_manifold_derivatives(compile_args):
function test_integral_grouping (line 1112) | def test_integral_grouping(compile_args):
function test_derivative_domains (line 1151) | def test_derivative_domains(compile_args):
function test_mixed_dim_form (line 1177) | def test_mixed_dim_form(compile_args, dtype, permutation):
function test_ds_prism (line 1296) | def test_ds_prism(compile_args, dtype):
function test_vertex_integral (line 1456) | def test_vertex_integral(compile_args, geometry, rank, dtype, element_ty...
function test_vertex_mesh (line 1537) | def test_vertex_mesh(compile_args, dtype):
function test_mixed_dim_form_codim2 (line 1586) | def test_mixed_dim_form_codim2(compile_args, dtype, permutation, local_e...
function test_mixed_dim_form_codim2_2D (line 1678) | def test_mixed_dim_form_codim2_2D(compile_args, dtype, local_entity_index):
function test_ridge_integral (line 1778) | def test_ridge_integral(compile_args, dtype, permutation):
function test_diagonal_form (line 1869) | def test_diagonal_form(dtype, compile_args):
function test_diagonal_mixed_form (line 1944) | def test_diagonal_mixed_form(dtype, compile_args):
function test_diagonal_mixed_block (line 2025) | def test_diagonal_mixed_block(dtype, compile_args, shape):
function test_multiple_integrands_same_quadrature (line 2101) | def test_multiple_integrands_same_quadrature(compile_args, dtype):
function test_ufl_complex_extraction (line 2213) | def test_ufl_complex_extraction(
FILE: test/test_lnodes.py
function test_gemm (line 13) | def test_gemm(dtype):
function test_gemv (line 60) | def test_gemv(dtype):
FILE: test/test_numba.py
function wrap_kernel (line 21) | def wrap_kernel(scalar_type, real_type):
function as_C_array (line 26) | def as_C_array(np_array: npt.NDArray):
function test_external_module (line 31) | def test_external_module():
function generate_poisson (line 39) | def generate_poisson() -> None:
function test_integral (line 45) | def test_integral(scalar_type: str, generate_poisson) -> None:
function test_expression (line 98) | def test_expression(scalar_type: str, generate_poisson) -> None:
FILE: test/test_signatures.py
function generate_kernel (line 19) | def generate_kernel(forms, scalar_type, options):
function test_numba_kernel_signature (line 63) | def test_numba_kernel_signature(dtype):
FILE: test/test_submesh.py
function compute_tensor (line 20) | def compute_tensor(forms: list[ufl.form.Form], dtype: str, compile_args:...
function test_multiple_mesh_codim0 (line 71) | def test_multiple_mesh_codim0(dtype, compile_args):
FILE: test/test_tensor_product.py
function cell_to_gdim (line 16) | def cell_to_gdim(cell_type):
function create_tensor_product_element (line 26) | def create_tensor_product_element(cell_type, degree, variant, shape=None):
function generate_kernel (line 37) | def generate_kernel(forms, dtype, options):
function test_bilinear_form (line 64) | def test_bilinear_form(dtype, P, cell_type):
Condensed preview — 127 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (695K chars).
[
{
"path": ".gitattributes",
"chars": 104,
"preview": "release.conf export-ignore\n.gitignore export-ignore\n.gitattributes export-ignore\n.mailmap export-ignore\n"
},
{
"path": ".github/FUNDING.yml",
"chars": 140,
"preview": "# These are supported funding model platforms\n\ngithub: FEniCS # Replace with up to 4 GitHub Sponsors-enabled usernames e"
},
{
"path": ".github/dependabot.yml",
"chars": 695,
"preview": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where "
},
{
"path": ".github/workflows/build-wheels.yml",
"chars": 2410,
"preview": "name: Build wheels\n\n# By default this action does not push to test or production PyPI. The wheels\n# are available as an"
},
{
"path": ".github/workflows/dolfinx-tests.yml",
"chars": 3390,
"preview": "# This workflow will install Basix, FFCx, DOLFINx and run the DOLFINx unit tests.\n\nname: DOLFINx integration\n\non:\n pull"
},
{
"path": ".github/workflows/pythonapp.yml",
"chars": 6039,
"preview": "# This workflow will install Python dependencies, run tests and lint\n# with a single version of Python For more informat"
},
{
"path": ".github/workflows/spack.yml",
"chars": 2165,
"preview": "name: Spack install\n\non:\n # Uncomment the below 'push' to trigger on push\n # push:\n # branches:\n # - \"**\"\n sche"
},
{
"path": ".gitignore",
"chars": 814,
"preview": "# Compiled source\n*.o\n*.Plo\n*.Po\n*.lo\n*.la\n*.a\n*.os\n*.pyc\n*.so\n*.pc\n*.pyc\n*.pyd\n*.def\n*.dll\n*.exe\n*.dylib\n\n# Files gener"
},
{
"path": "AUTHORS",
"chars": 2386,
"preview": "Credits for FFC\n===============\n\nMain authors:\n\n Anders Logg\n email: logg@simula.no\n www: http://home.simula."
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 3748,
"preview": "Code of Conduct\n===============\n\nOur Pledge\n----------\nIn the interest of fostering an open and welcoming environment, w"
},
{
"path": "COPYING",
"chars": 35147,
"preview": " GNU GENERAL PUBLIC LICENSE\n Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
},
{
"path": "COPYING.LESSER",
"chars": 7639,
"preview": "\t\t GNU LESSER GENERAL PUBLIC LICENSE\n Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software"
},
{
"path": "ChangeLog.rst",
"chars": 25212,
"preview": "Changelog\n=========\n\n0.6.0\n-----\nSee https://github.com/FEniCS/ffcx/compare/v0.5.0...v0.6.0\n\n0.5.0\n-----\nSee: https://gi"
},
{
"path": "LICENSE",
"chars": 350,
"preview": "The header file ufcx.h is released using the UNLICENSE. See UNLICENSE for the\nlicense text.\n\n---------------------------"
},
{
"path": "MANIFEST.in",
"chars": 330,
"preview": "include AUTHORS\ninclude COPYING\ninclude COPYING.LESSER\ninclude ChangeLog.rst\ninclude INSTALL\ninclude LICENSE\ninclude ffc"
},
{
"path": "README.md",
"chars": 2451,
"preview": "# FFCx: The FEniCSx Form Compiler\n\n["
},
{
"path": "UNLICENSE",
"chars": 1238,
"preview": "The software in the file ufcx.h is free and unencumbered software released into\nthe public domain.\n\nAnyone is free to co"
},
{
"path": "_clang-format",
"chars": 2805,
"preview": "---\nLanguage: Cpp\n# BasedOnStyle: LLVM\nAccessModifierOffset: -2\nAlignAfterOpenBracket: Align\nAlignConsecutiveAss"
},
{
"path": "cmake/CMakeLists.txt",
"chars": 2064,
"preview": "cmake_minimum_required(VERSION 3.19)\n\n# Development version: x.x.x.0\n# Release version: x.x.x\nproject(ufcx VERSION 0.11."
},
{
"path": "cmake/ufcx.pc.in",
"chars": 273,
"preview": "prefix=\"@CMAKE_INSTALL_PREFIX@\"\nexec_prefix=\"${prefix}\"\nincludedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@\ndefinitions=@\n\nN"
},
{
"path": "cmake/ufcxConfig.cmake.in",
"chars": 156,
"preview": "@PACKAGE_INIT@\n\nset(UFCX_SIGNATURE @UFCX_HASH@)\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake\")\ncheck_r"
},
{
"path": "demo/BiharmonicHHJ.py",
"chars": 1100,
"preview": "# Copyright (C) 2016 Lizao Li\n\"\"\"Biharmonis HHJ demo.\n\nThe bilinear form a(u, v) and linear form L(v) for Biharmonic equ"
},
{
"path": "demo/BiharmonicRegge.py",
"chars": 1193,
"preview": "# Copyright (C) 2016 Lizao Li\n\"\"\"Biharmonic Regge demo.\n\nThe bilinear form a(u, v) and linear form L(v) for Biharmonic e"
},
{
"path": "demo/CellGeometry.py",
"chars": 966,
"preview": "# Copyright (C) 2013 Martin S. Alnaes\n\"\"\"Cell geometry demo.\n\nA functional M involving a bunch of cell geometry quantiti"
},
{
"path": "demo/ComplexPoisson.py",
"chars": 1352,
"preview": "# Copyright (C) 2023 Chris Richardson\n#\n# This file is part of FFCx.\n#\n# FFCx is free software: you can redistribute it "
},
{
"path": "demo/Components.py",
"chars": 1181,
"preview": "# Copyright (C) 2011 Garth N. Wells\n#\n# This file is part of FFCx.\n#\n# FFCx is free software: you can redistribute it an"
},
{
"path": "demo/Conditional.py",
"chars": 1666,
"preview": "# Copyright (C) 2010-2011 Kristian B. Oelgaard\n#\n# This file is part of FFCx.\n#\n# FFCx is free software: you can redistr"
},
{
"path": "demo/ExpressionInterpolation.py",
"chars": 2230,
"preview": "# Copyright (C) 2022 Jørgen S. Dokken\n#\n# This file is part of FFCx.\n#\n# FFCx is free software: you can redistribute it "
},
{
"path": "demo/FacetIntegrals.py",
"chars": 1380,
"preview": "# Copyright (C) 2009-2010 Anders Logg\n#\n# This file is part of FFCx.\n#\n# FFCx is free software: you can redistribute it "
},
{
"path": "demo/FacetRestrictionAD.py",
"chars": 1264,
"preview": "# Copyright (C) 2010 Garth N. Wells\n#\n# This file is part of FFCx.\n#\n# FFCx is free software: you can redistribute it an"
},
{
"path": "demo/HyperElasticity.py",
"chars": 2551,
"preview": "# Author: Martin Sandve Alnes\n# Date: 2008-12-22\n# Modified by Garth N. Wells, 2009\n\"\"\"Hyper-elasticity demo.\"\"\"\n\nimport"
},
{
"path": "demo/MassAction.py",
"chars": 720,
"preview": "# Copyright (C) 2023 Igor A. Baratta\n#\n# This file is part of FFCx. (https://www.fenicsproject.org)\n#\n# SPDX-License-Ide"
},
{
"path": "demo/MassDG0.py",
"chars": 1095,
"preview": "# Copyright (C) 2021 Igor Baratta\n#\n# This file is part of FFCx.\n#\n# FFCx is free software: you can redistribute it and/"
},
{
"path": "demo/MassHcurl_2D_1.py",
"chars": 1063,
"preview": "# Copyright (C) 2004-2010 Anders Logg\n#\n# This file is part of FFCx.\n#\n# FFCx is free software: you can redistribute it "
},
{
"path": "demo/MassHdiv_2D_1.py",
"chars": 1054,
"preview": "# Copyright (C) 2010 Anders Logg\n#\n# This file is part of FFCx.\n#\n# FFCx is free software: you can redistribute it and/o"
},
{
"path": "demo/MathFunctions.py",
"chars": 2032,
"preview": "# Copyright (C) 2010 Kristian B. Oelgaard\n#\n# This file is part of FFCx.\n#\n# FFCx is free software: you can redistribute"
},
{
"path": "demo/MetaData.py",
"chars": 1656,
"preview": "# Copyright (C) 2009 Kristian B. Oelgaard\n#\n# This file is part of FFCx.\n#\n# FFCx is free software: you can redistribute"
},
{
"path": "demo/Mini.py",
"chars": 1573,
"preview": "# Copyright (C) 2010 Marie E. Rognes\n#\n# This file is part of FFCx.\n#\n# FFCx is free software: you can redistribute it a"
},
{
"path": "demo/MixedCoefficient.py",
"chars": 1196,
"preview": "# Copyright (C) 2016 Miklós Homolya\n#\n# This file is part of FFCx.\n#\n# FFCx is free software: you can redistribute it an"
},
{
"path": "demo/MixedPoissonDual.py",
"chars": 1516,
"preview": "# Copyright (C) 2014 Jan Blechta\n#\n# This file is part of FFCx.\n#\n# DOLFINx is free software: you can redistribute it an"
},
{
"path": "demo/Normals.py",
"chars": 1258,
"preview": "# Copyright (C) 2009 Peter Brune\n#\n# This file is part of FFCx.\n#\n# FFCx is free software: you can redistribute it and/o"
},
{
"path": "demo/Poisson1D.py",
"chars": 1204,
"preview": "# Copyright (C) 2004-2007 Anders Logg\n#\n# This file is part of FFCx.\n#\n# FFCx is free software: you can redistribute it "
},
{
"path": "demo/PoissonQuad.py",
"chars": 1287,
"preview": "# Copyright (C) 2016 Jan Blechta\n#\n# This file is part of FFCx.\n#\n# FFCx is free software: you can redistribute it and/o"
},
{
"path": "demo/ProjectionManifold.py",
"chars": 1352,
"preview": "# Copyright (C) 2012 Marie E. Rognes and David Ham\n#\n# This file is part of FFCx.\n#\n# FFCx is free software: you can red"
},
{
"path": "demo/ReactionDiffusion.py",
"chars": 1273,
"preview": "# Copyright (C) 2009 Anders Logg\n#\n# This file is part of FFCx.\n#\n# FFCx is free software: you can redistribute it and/o"
},
{
"path": "demo/SpatialCoordinates.py",
"chars": 1495,
"preview": "# Copyright (C) 2010 Kristian B. Oelgaard\n#\n# This file is part of FFCx.\n#\n# FFCx is free software: you can redistribute"
},
{
"path": "demo/StabilisedStokes.py",
"chars": 1706,
"preview": "# Copyright (c) 2005-2007 Anders Logg\n#\n# This file is part of FFCx.\n#\n# FFCx is free software: you can redistribute it "
},
{
"path": "demo/Symmetry.py",
"chars": 384,
"preview": "\"\"\"Symmetry demo.\"\"\"\n\nimport basix.ufl\nfrom ufl import FunctionSpace, Mesh, TestFunction, TrialFunction, dx, grad, inner"
},
{
"path": "demo/VectorConstant.py",
"chars": 1464,
"preview": "# Copyright (C) 2016 Jan Blechta\n#\n# This file is part of FFCx.\n#\n# FFCx is free software: you can redistribute it and/o"
},
{
"path": "demo/VectorPoisson.py",
"chars": 1184,
"preview": "# Copyright (C) 2010 Anders Logg\n#\n# This file is part of FFCx.\n#\n# FFCx is free software: you can redistribute it and/o"
},
{
"path": "demo/test_demos.py",
"chars": 2753,
"preview": "\"\"\"Test demos.\"\"\"\n\nimport os\nimport subprocess\nimport sys\nfrom pathlib import Path\n\nimport pytest\n\ndemo_dir = Path(__fil"
},
{
"path": "doc/source/conf.py",
"chars": 5813,
"preview": "\"\"\"Configuration file for the Sphinx documentation builder.\"\"\"\n# This file does only contain a selection of the most com"
},
{
"path": "doc/source/index.rst",
"chars": 641,
"preview": "FEniCS Form Compiler 'X' documentation\n======================================\n\nThe is an experimental version of the FEn"
},
{
"path": "ffcx/__init__.py",
"chars": 463,
"preview": "# Copyright (C) 2009-2018 FEniCS Project\n#\n# This file is part of FFCx. (https://www.fenicsproject.org)\n#\n# SPDX-License"
},
{
"path": "ffcx/__main__.py",
"chars": 303,
"preview": "#!/usr/bin/env python\n# Copyright (C) 2017-2017 Martin Sandve Alnæs\n#\n# This file is part of FFCx.(https://www.fenicspro"
},
{
"path": "ffcx/analysis.py",
"chars": 10521,
"preview": "# Copyright (C) 2007-2020 Anders Logg, Martin Alnaes, Kristian B. Oelgaard,\n# Michal Habera and "
},
{
"path": "ffcx/codegeneration/C/__init__.py",
"chars": 674,
"preview": "\"\"\"Generation of C code.\"\"\"\n\nfrom typing import TYPE_CHECKING\n\nfrom ffcx.codegeneration import interface\nfrom ffcx.codeg"
},
{
"path": "ffcx/codegeneration/C/expression.py",
"chars": 4457,
"preview": "# Copyright (C) 2019 Michal Habera\n#\n# This file is part of FFCx.(https://www.fenicsproject.org)\n#\n# SPDX-License-Identi"
},
{
"path": "ffcx/codegeneration/C/expression_template.py",
"chars": 1850,
"preview": "# Copyright (C) 2019 Michal Habera\n#\n# This file is part of FFCx.(https://www.fenicsproject.org)\n#\n# SPDX-License-Identi"
},
{
"path": "ffcx/codegeneration/C/file.py",
"chars": 1455,
"preview": "# Copyright (C) 2009-2018 Anders Logg, Martin Sandve Alnæs and Garth N. Wells\n#\n# This file is part of FFCx.(https://www"
},
{
"path": "ffcx/codegeneration/C/file_template.py",
"chars": 1062,
"preview": "# Code generation format strings for UFCx (Unified Form-assembly Code)\n# This code is released into the public domain.\n#"
},
{
"path": "ffcx/codegeneration/C/form.py",
"chars": 5784,
"preview": "# Copyright (C) 2009-2017 Anders Logg and Martin Sandve Alnæs\n#\n# This file is part of FFCx.(https://www.fenicsproject.o"
},
{
"path": "ffcx/codegeneration/C/form_template.py",
"chars": 1444,
"preview": "# Code generation format strings for UFCx (Unified Form-assembly Code)\n# This code is released into the public domain.\n#"
},
{
"path": "ffcx/codegeneration/C/formatter.py",
"chars": 11181,
"preview": "# Copyright (C) 2023-2025 Chris Richardson and Paul T. Kühner\n#\n# This file is part of FFCx. (https://www.fenicsproject."
},
{
"path": "ffcx/codegeneration/C/integral.py",
"chars": 4281,
"preview": "# Copyright (C) 2015-2021 Martin Sandve Alnæs, Michal Habera, Igor Baratta\n#\n# This file is part of FFCx. (https://www.f"
},
{
"path": "ffcx/codegeneration/C/integral_template.py",
"chars": 1278,
"preview": "# Code generation format strings for UFCx (Unified Form-assembly Code)\n# This code is released into the public domain.\n#"
},
{
"path": "ffcx/codegeneration/__init__.py",
"chars": 894,
"preview": "\"\"\"FFCx code generation.\"\"\"\n\nimport hashlib\nimport os\n\n# Version of FFCx header files\n__author__ = \"FEniCS Project\"\n__li"
},
{
"path": "ffcx/codegeneration/access.py",
"chars": 20372,
"preview": "# Copyright (C) 2011-2017 Martin Sandve Alnæs\n#\n# This file is part of FFCx. (https://www.fenicsproject.org)\n#\n# SPDX-Li"
},
{
"path": "ffcx/codegeneration/backend.py",
"chars": 1319,
"preview": "# Copyright (C) 2011-2017 Martin Sandve Alnæs\n#\n# This file is part of FFCx. (https://www.fenicsproject.org)\n#\n# SPDX-Li"
},
{
"path": "ffcx/codegeneration/codegeneration.py",
"chars": 2235,
"preview": "# Copyright (C) 2009-2017 Anders Logg, Martin Sandve Alnæs, Marie E. Rognes,\n# Kristian B. Oelgaard, and others\n#\n# This"
},
{
"path": "ffcx/codegeneration/common.py",
"chars": 3383,
"preview": "# Copyright (C) 2025 Paul T. Kühner\n#\n# This file is part of FFCx.(https://www.fenicsproject.org)\n#\n# SPDX-License-Ident"
},
{
"path": "ffcx/codegeneration/definitions.py",
"chars": 10100,
"preview": "# Copyright (C) 2011-2023 Martin Sandve Alnæs, Igor A. Baratta\n#\n# This file is part of FFCx. (https://www.fenicsproject"
},
{
"path": "ffcx/codegeneration/expression_generator.py",
"chars": 14744,
"preview": "# Copyright (C) 2019 Michal Habera\n#\n# This file is part of FFCx.(https://www.fenicsproject.org)\n#\n# SPDX-License-Identi"
},
{
"path": "ffcx/codegeneration/geometry.py",
"chars": 5810,
"preview": "# Copyright (C) 2021 Matthew Scroggs\n#\n# This file is part of FFCx.(https://www.fenicsproject.org)\n#\n# SPDX-License-Iden"
},
{
"path": "ffcx/codegeneration/integral_generator.py",
"chars": 23255,
"preview": "# Copyright (C) 2015-2024 Martin Sandve Alnæs, Michal Habera, Igor Baratta, Chris Richardson\n#\n# Modified by Jørgen S. D"
},
{
"path": "ffcx/codegeneration/interface.py",
"chars": 1510,
"preview": "# Copyright (C) 2025 Paul T. Kühner\n#\n# This file is part of FFCx. (https://www.fenicsproject.org)\n#\n# SPDX-License-Iden"
},
{
"path": "ffcx/codegeneration/jit.py",
"chars": 14716,
"preview": "# Copyright (C) 2004-2019 Garth N. Wells\n#\n# This file is part of FFCx.(https://www.fenicsproject.org)\n#\n# SPDX-License-"
},
{
"path": "ffcx/codegeneration/lnodes.py",
"chars": 30674,
"preview": "# Copyright (C) 2013-2023 Martin Sandve Alnæs, Chris Richardson\n#\n# This file is part of FFCx.(https://www.fenicsproject"
},
{
"path": "ffcx/codegeneration/numba/__init__.py",
"chars": 682,
"preview": "\"\"\"Generation of numba code.\"\"\"\n\nfrom typing import TYPE_CHECKING\n\nfrom ffcx.codegeneration import interface\nfrom ffcx.c"
},
{
"path": "ffcx/codegeneration/numba/expression.py",
"chars": 3247,
"preview": "# Copyright (C) 2019-2025 Michal Habera, Chris Richardson and Paul T. Kühner\n#\n# This file is part of FFCx.(https://www."
},
{
"path": "ffcx/codegeneration/numba/expression_template.py",
"chars": 1142,
"preview": "# Copyright (C) 2019-2025 Michal Habera, Chris Richardson and Paul T.Kühner\n#\n# This file is part of FFCx.(https://www.f"
},
{
"path": "ffcx/codegeneration/numba/file.py",
"chars": 1422,
"preview": "# Copyright (C) 2009-2025 Anders Logg, Martin Sandve Alnæs, Garth N. Wells, Chris Richardson and\n# Paul T. Kühner\n#\n# Th"
},
{
"path": "ffcx/codegeneration/numba/file_template.py",
"chars": 891,
"preview": "# Copyright (C) 2025 Chris Richardson and Paul T. Kühner\n#\n# This file is part of FFCx.(https://www.fenicsproject.org)\n#"
},
{
"path": "ffcx/codegeneration/numba/form.py",
"chars": 4828,
"preview": "# Copyright (C) 2009-2025 Anders Logg, Martin Sandve Alnæs, Chris Richardson and Paul T. Kühner\n#\n# This file is part of"
},
{
"path": "ffcx/codegeneration/numba/form_template.py",
"chars": 1129,
"preview": "# Copyright (C) 2025 Chris Richardson\n#\n# This file is part of FFCx. (https://www.fenicsproject.org)\n#\n# SPDX-License-Id"
},
{
"path": "ffcx/codegeneration/numba/formatter.py",
"chars": 8371,
"preview": "# Copyright (C) 2025 Chris Richardson and Paul T. Kühner\n#\n# This file is part of FFCx. (https://www.fenicsproject.org)\n"
},
{
"path": "ffcx/codegeneration/numba/integral.py",
"chars": 3142,
"preview": "# Copyright (C) 2015-2021 Martin Sandve Alnæs, Michal Habera, Igor Baratta, Chris Richardson and\n# Paul T. Kühner\n#\n# Th"
},
{
"path": "ffcx/codegeneration/numba/integral_template.py",
"chars": 752,
"preview": "# Copyright (C) 2025 Chris Richardson and Paul T. Kühner\n#\n# This file is part of FFCx. (https://www.fenicsproject.org)\n"
},
{
"path": "ffcx/codegeneration/optimizer.py",
"chars": 6619,
"preview": "\"\"\"Optimizer.\"\"\"\n\nfrom collections import defaultdict\n\nimport ffcx.codegeneration.lnodes as L\nfrom ffcx.ir.representatio"
},
{
"path": "ffcx/codegeneration/symbols.py",
"chars": 7756,
"preview": "# Copyright (C) 2011-2023 Martin Sandve Alnæs, Igor A. Baratta\n#\n# This file is part of FFCx. (https://www.fenicsproject"
},
{
"path": "ffcx/codegeneration/ufcx.h",
"chars": 9015,
"preview": "/// This is UFCx\n/// This software is released under the terms of the unlicense (see the file\n/// UNLICENSE).\n///\n/// Th"
},
{
"path": "ffcx/codegeneration/utils.py",
"chars": 5352,
"preview": "# Copyright (C) 2020-2024 Michal Habera, Chris Richardson and Garth N. Wells\n#\n# This file is part of FFCx.(https://www."
},
{
"path": "ffcx/compiler.py",
"chars": 3936,
"preview": "# Copyright (C) 2007-2020 Anders Logg and Michal Habera\n#\n# This file is part of FFCx.(https://www.fenicsproject.org)\n#\n"
},
{
"path": "ffcx/definitions.py",
"chars": 257,
"preview": "\"\"\"Module for storing type definitions used in the FFCx code base.\"\"\"\n\nfrom typing import Literal\n\nentity_types = Litera"
},
{
"path": "ffcx/element_interface.py",
"chars": 2363,
"preview": "# Copyright (C) 2021 Matthew W. Scroggs and Chris Richardson\n#\n# This file is part of FFCx.(https://www.fenicsproject.or"
},
{
"path": "ffcx/formatting.py",
"chars": 1309,
"preview": "# Copyright (C) 2009-2018 Anders Logg and Garth N. Wells\n#\n# This file is part of FFCx. (https://www.fenicsproject.org)\n"
},
{
"path": "ffcx/ir/__init__.py",
"chars": 35,
"preview": "\"\"\"Intermediate representation.\"\"\"\n"
},
{
"path": "ffcx/ir/analysis/__init__.py",
"chars": 224,
"preview": "# Copyright (C) 2011-2017 Martin Sandve Alnæs\n#\n# This file is part of FFCx.(https://www.fenicsproject.org)\n#\n# SPDX-Lic"
},
{
"path": "ffcx/ir/analysis/factorization.py",
"chars": 11678,
"preview": "# Copyright (C) 2011-2017 Martin Sandve Alnæs\n#\n# This file is part of FFCx.(https://www.fenicsproject.org)\n#\n# SPDX-Lic"
},
{
"path": "ffcx/ir/analysis/graph.py",
"chars": 8473,
"preview": "# Copyright (C) 2011-2017 Martin Sandve Alnæs\n#\n# This file is part of FFCx.(https://www.fenicsproject.org)\n#\n# SPDX-Lic"
},
{
"path": "ffcx/ir/analysis/indexing.py",
"chars": 4794,
"preview": "# Copyright (C) 2011-2017 Martin Sandve Alnæs\n#\n# This file is part of FFCx.(https://www.fenicsproject.org)\n#\n# SPDX-Lic"
},
{
"path": "ffcx/ir/analysis/modified_terminals.py",
"chars": 10301,
"preview": "# Copyright (C) 2011-2026 Martin Sandve Alnæs, Jørgen S. Dokken\n#\n# This file is part of FFCx.(https://www.fenicsproject"
},
{
"path": "ffcx/ir/analysis/reconstruct.py",
"chars": 6280,
"preview": "# Copyright (C) 2011-2017 Martin Sandve Alnæs and Chris Richardson\n#\n# This file is part of FFCx.(https://www.fenicsproj"
},
{
"path": "ffcx/ir/analysis/valuenumbering.py",
"chars": 8846,
"preview": "# Copyright (C) 2011-2017 Martin Sandve Alnæs\n#\n# This file is part of FFCx.(https://www.fenicsproject.org)\n#\n# SPDX-Lic"
},
{
"path": "ffcx/ir/analysis/visualise.py",
"chars": 2170,
"preview": "# Copyright (C) 2018 Chris Richardson\n#\n# This file is part of FFCx.(https://www.fenicsproject.org)\n#\n# SPDX-License-Ide"
},
{
"path": "ffcx/ir/elementtables.py",
"chars": 28117,
"preview": "# Copyright (C) 2013-2017 Martin Sandve Alnæs\n#\n# This file is part of FFCx. (https://www.fenicsproject.org)\n#\n# SPDX-Li"
},
{
"path": "ffcx/ir/integral.py",
"chars": 20024,
"preview": "# Copyright (C) 2013-2025 Martin Sandve Alnæs, Michal Habera and Jørgen S. Dokken\n#\n# This file is part of FFCx.(https:/"
},
{
"path": "ffcx/ir/representation.py",
"chars": 25963,
"preview": "# Copyright (C) 2009-2026 Anders Logg, Martin Sandve Alnæs, Marie E. Rognes,\n# Kristian B. Oelgaard, Matthew W. Scroggs,"
},
{
"path": "ffcx/ir/representationutils.py",
"chars": 5394,
"preview": "# Copyright (C) 2012-2017 Marie Rognes\n#\n# This file is part of FFCx.(https://www.fenicsproject.org)\n#\n# SPDX-License-Id"
},
{
"path": "ffcx/main.py",
"chars": 4688,
"preview": "# Copyright (C) 2004-2025 Anders Logg, Garth N. Wells and Michal Habera\n#\n# This file is part of FFCx.(https://www.fenic"
},
{
"path": "ffcx/naming.py",
"chars": 3719,
"preview": "# Copyright (C) 2009-2020 Anders Logg and Michal Habera\n#\n# This file is part of FFCx.(https://www.fenicsproject.org)\n#\n"
},
{
"path": "ffcx/options.py",
"chars": 4036,
"preview": "# Copyright (C) 2005-2020 Anders Logg, Michal Habera, Jack S. Hale\n#\n# This file is part of FFCx. (https://www.fenicspro"
},
{
"path": "ffcx/py.typed",
"chars": 0,
"preview": ""
},
{
"path": "pyproject.toml",
"chars": 3120,
"preview": "[build-system]\nrequires = [\"setuptools>=62\", \"wheel\"]\nbuild-backend = \"setuptools.build_meta\"\n\n[project]\nname = \"fenics-"
},
{
"path": "test/conftest.py",
"chars": 401,
"preview": "# Copyright (C) 2020 Michal Habera\n#\n# This file is part of FFCx.(https://www.fenicsproject.org)\n#\n# SPDX-License-Identi"
},
{
"path": "test/poisson.py",
"chars": 1557,
"preview": "# Copyright (C) 2004-2025 Anders Logg and Paul T. Kühner\n#\n# This file is part of FFCx.\n#\n# FFCx is free software: you c"
},
{
"path": "test/test_add_mode.py",
"chars": 5532,
"preview": "# Copyright (C) 2019 Chris Richardson\n#\n# This file is part of FFCx. (https://www.fenicsproject.org)\n#\n# SPDX-License-Id"
},
{
"path": "test/test_cache.py",
"chars": 1196,
"preview": "# Copyright (C) 2019 Chris Richardson\n#\n# This file is part of FFCx. (https://www.fenicsproject.org)\n#\n# SPDX-License-Id"
},
{
"path": "test/test_cmdline.py",
"chars": 728,
"preview": "# Copyright (C) 2018-2025 Chris N. Richardson and Paul T. Kühner\n#\n# This file is part of FFCx. (https://www.fenicsproje"
},
{
"path": "test/test_custom_data.py",
"chars": 4153,
"preview": "# Copyright (C) 2024 Susanne Claus\n#\n# This file is part of FFCx. (https://www.fenicsproject.org)\n#\n# SPDX-License-Ident"
},
{
"path": "test/test_jit_expression.py",
"chars": 18856,
"preview": "# Copyright (C) 2019-2024 Michal Habera and Jørgen S. Dokken\n#\n# This file is part of FFCx.(https://www.fenicsproject.or"
},
{
"path": "test/test_jit_forms.py",
"chars": 77378,
"preview": "# Copyright (C) 2018-2026 Garth N. Wells, Matthew Scroggs, Paul T. Kühner and Jørgen S. Dokken\n#\n# This file is part of "
},
{
"path": "test/test_lnodes.py",
"chars": 3408,
"preview": "import importlib\n\nimport numpy as np\nimport pytest\nfrom cffi import FFI\n\nfrom ffcx.codegeneration import lnodes as L\nfro"
},
{
"path": "test/test_numba.py",
"chars": 4055,
"preview": "# Copyright (C) 2025 Paul T. Kühner\n#\n# This file is part of FFCx.(https://www.fenicsproject.org)\n#\n# SPDX-License-Ident"
},
{
"path": "test/test_signatures.py",
"chars": 2921,
"preview": "# Copyright (C) 2024 Igor A. Baratta\n#\n# This file is part of FFCx. (https://www.fenicsproject.org)\n#\n# SPDX-License-Ide"
},
{
"path": "test/test_submesh.py",
"chars": 2998,
"preview": "# Copyright (C) 2024 Jørgen S. Dokken\n#\n# This file is part of FFCx. (https://www.fenicsproject.org)\n#\n# SPDX-License-Id"
},
{
"path": "test/test_tensor_product.py",
"chars": 4286,
"preview": "# Copyright (C) 2023 Igor A. Baratta\n#\n# This file is part of FFCx. (https://www.fenicsproject.org)\n#\n# SPDX-License-Ide"
}
]
About this extraction
This page contains the full source code of the FEniCS/ffcx GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 127 files (644.0 KB), approximately 168.3k tokens, and a symbol index with 527 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.