/usr/lib/python2.7/dist-packages/dolfin/fem/form.py is in python-dolfin 1.3.0+dfsg-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | """This module defines a Form class that wraps FFC forms and UFC forms
into a cpp.Form (dolfin::Form)."""
# Copyright (C) 2008 Johan Hake
#
# This file is part of DOLFIN.
#
# DOLFIN 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.
#
# DOLFIN 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 DOLFIN. If not, see <http://www.gnu.org/licenses/>.
#
# Modified by Anders Logg, 2008-2011
# Modified by Marie E. Rognes, 2011
#
# First added: 2008-12-04
# Last changed: 2009-12-11
__all__ = ["Form"]
# Import SWIG-generated extension module (DOLFIN C++)
import dolfin.cpp as cpp
# Import ufl and ufc
import ufl, ufc
# Import JIT compiler
from dolfin.compilemodules.jit import jit
# Note that we need to store _compiled_form and _compiled_coefficients
# to prevent Python from garbage-collecting these while still in use.
# FIXME: Figure out how to solve this with shared_ptr
class Form(cpp.Form):
def __init__(self, form,
function_spaces=None,
coefficients=None,
subdomains=None,
form_compiler_parameters=None,
common_cell=None):
"Create JIT-compiled form from any given form (compiled or not)."
# Check form argument
if isinstance(form, ufl.Form):
self._compiled_form, module, self.form_data, prefix \
= jit(form, form_compiler_parameters,
common_cell)
elif isinstance(form, ufc.form):
self._compiled_form = form
self.form_data = None
elif isinstance(form, cpp.Form):
self._compiled_form = form._compiled_form
self.form_data = form.form_data
else:
cpp.dolfin_error("form.py",
"creating dolfin.Form",
"Expected a ufl.Form, ufc.form or a dolfin.Form")
# Extract function spaces
self.function_spaces = _extract_function_spaces(self.form_data,
self._compiled_form,
function_spaces)
# Extract coefficients
(self.coefficients, self._compiled_coefficients) = \
_extract_coefficients(self.form_data, coefficients)
# Initialize base class
cpp.Form.__init__(self, self._compiled_form,
self.function_spaces, self.coefficients)
# Extract subdomains from form_data, override if given explicitly
self.subdomains = _extract_subdomains(self.form_data, subdomains)
# Attach subdomains if we have them
subdomains = self.subdomains.get("cell")
if subdomains is not None:
self.set_cell_domains(subdomains)
subdomains = self.subdomains.get("exterior_facet")
if subdomains is not None:
self.set_exterior_facet_domains(subdomains)
subdomains = self.subdomains.get("interior_facet")
if subdomains is not None:
self.set_interior_facet_domains(subdomains)
def _extract_function_spaces(form_data, compiled_form, given_function_spaces):
"Extract list of test spaces."
# Note: Most of this function is error checking,
# look for 'function_spaces' to see where stuff happens
function_space_error = "Error while extracting test and/or trial spaces. "
function_spaces = []
r = compiled_form.rank()
if given_function_spaces:
# Given function spaces are necessary for assembling pure UFC forms,
# and possibly also convenient for other rare scenarios.
if isinstance(given_function_spaces, cpp.FunctionSpace):
if r > 0:
# Repeat a single given space
function_spaces = [given_function_spaces]*r
else:
raise ValueError(function_space_error +
"Superfluous test spaces given for a functional.")
elif isinstance(given_function_spaces, (list,tuple)):
if all(isinstance(fs, cpp.FunctionSpace) for fs in given_function_spaces):
# Take given list of spaces
function_spaces = list(given_function_spaces)
else:
raise ValueError(function_space_error +
"Invalid given test spaces.")
else:
raise ValueError(function_space_error +
"Expecting given_function_spaces to be one or more function spaces.")
else:
# No given function spaces is the norm in pydolfin, which means
# they are to be extracted from the ufl form
if hasattr(form_data, 'original_arguments'):
# Get spaces from Arguments found in ufl form
function_spaces = [func.function_space() for func in form_data.original_arguments]
elif r == 0:
# No given spaces, no form_data, but this is a functional, so no spaces needed
function_spaces = []
else:
raise ValueError(function_space_error +
"Missing data about basis functions in form data.")
# Consistency checks
if len(function_spaces) != r:
raise ValueError(function_space_error +
" Wrong number of test spaces (should be %d)." % r)
if not all(isinstance(fs, cpp.FunctionSpace) for fs in function_spaces):
raise ValueError(function_space_error +
" Invalid type of test spaces.")
return function_spaces
def _extract_coefficients(form_data, given_coefficients):
"Extract list of coefficients."
# Note: Most of this function is error checking,
# look for 'coefficients' and '_compiled_coefficients' to see where stuff happens
coefficient_error = "Error while extracting coefficients. "
coefficients = []
_compiled_coefficients = []
if given_coefficients:
# Type checking given coefficients
error_info = "Provide a 'list' with cpp.GenericFunctions"
if not isinstance(given_coefficients, list):
raise TypeError(coefficient_error + error_info)
if not all(isinstance(c, cpp.GenericFunction) for c in given_coefficients):
raise TypeError(coefficient_error)
# Just use the given list
coefficients = list(given_coefficients)
_compiled_coefficients = list(given_coefficients)
elif form_data is None:
# Nothing to extract
coefficients = []
_compiled_coefficients = []
else:
# Type checking form data
if not hasattr(form_data, "original_coefficients"):
raise TypeError(coefficient_error +
"Missing data about coefficients in form data.")
if not all(isinstance(c, cpp.GenericFunction) for c in form_data.original_coefficients):
raise TypeError(coefficient_error +
"Either provide a dict of cpp.GenericFunctions, " +
"or use Function to define your form.")
# Just use the list from form data
coefficients = list(form_data.original_coefficients)
_compiled_coefficients = [] # Is this correct? No need to store double references.
return (coefficients, _compiled_coefficients)
def _extract_subdomains(form_data, override_subdomains):
"Extract list of subdomains."
override_subdomains = override_subdomains or {}
if form_data is None:
return override_subdomains
domain_types = ("cell", "exterior_facet", "interior_facet")
additional_keys = set(override_subdomains.keys()) - set(domain_types)
if additional_keys:
raise TypeError, "Invalid keys in domain_types: %s" % additional_keys
subdomains = {}
for domain in domain_types:
domains = override_subdomains.get(domain)
if domains is None:
domains = form_data.domain_data.get(domain)
# FIXME: Add test for MeshFunctions here.
# Like this?
#if (domains is not None) and (not isinstance(domains, MeshFunction)):
# raise TypeError, "Invalid subdomains type %s" % type(domains)
subdomains[domain] = domains
return subdomains
|