# -*- coding: utf-8 -*-
"""This module implements the representation of a multilinear form as
a sum of tensor contractions.
The following possible optimizations are currently not implemented but
might be (re-)implemented in a future version of FFC
1. Factorization of common reference tensors
"""
# Copyright (C) 2007-2014 Anders Logg
#
# This file is part of FFC.
#
# FFC 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.
#
# FFC 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/>.
#
# Modified by Kristian B. Oelgaard, 2010.
# Modified by Martin Sandve Alnæs, 2013
# FFC modules
from ffc.log import info, error
from ffc.representationutils import initialize_integral_ir
# FFC tensor representation modules
from ffc.tensor.monomialextraction import extract_monomial_form
from ffc.tensor.monomialtransformation import transform_monomial_form
from ffc.tensor.referencetensor import ReferenceTensor
from ffc.tensor.geometrytensor import GeometryTensor
from ffc.tensor.tensorreordering import reorder_entries
[docs]def compute_integral_ir(itg_data,
form_data,
form_id,
element_numbers,
classnames,
parameters):
"Compute intermediate represention of integral."
info("Computing tensor representation")
# Extract monomial representation
integrands = [itg.integrand() for itg in itg_data.integrals]
monomial_form = extract_monomial_form(integrands, form_data.function_replace_map)
# Transform monomial form to reference element
transform_monomial_form(monomial_form)
# Get some integral properties
integral_type = itg_data.integral_type
quadrature_degree = itg_data.metadata["quadrature_degree"]
quadrature_rule = itg_data.metadata["quadrature_rule"]
# Get some cell properties
cell = itg_data.domain.ufl_cell()
num_facets = cell.num_facets()
# Helper to simplify code below
compute_terms = lambda i, j: _compute_terms(monomial_form,
i, j,
integral_type,
quadrature_degree,
quadrature_rule,
cell)
# Compute representation of cell tensor
if integral_type == "cell":
# Compute sum of tensor representations
terms = compute_terms(None, None)
elif integral_type == "exterior_facet":
# Compute sum of tensor representations for each facet
terms = [compute_terms(i, None) for i in range(num_facets)]
elif integral_type == "interior_facet":
# Compute sum of tensor representations for each facet-facet pair
terms = [[compute_terms(i, j) for j in range(num_facets)] for i in range(num_facets)]
for i in range(num_facets):
for j in range(num_facets):
reorder_entries(terms[i][j])
else:
error("Unhandled domain type: " + str(integral_type))
# Initialize representation and store terms
ir = initialize_integral_ir("tensor", itg_data, form_data, form_id)
ir["AK"] = terms
return ir
def _compute_terms(monomial_form,
facet0, facet1,
integral_type,
quadrature_degree,
quadrature_rule,
cell):
"Compute list of tensor contraction terms for monomial form."
# Compute terms
terms = []
for integrand in monomial_form:
# Iterate over monomials of integrand
for monomial in integrand.monomials:
# Compute reference tensor
A0 = ReferenceTensor(monomial,
integral_type,
facet0, facet1,
quadrature_degree,
quadrature_rule,
cell)
# Compute geometry tensor
GK = GeometryTensor(monomial)
# Append term
terms.append((A0, GK, None))
return terms