39
33
tensor=None, backend=None, return_dofmaps=False):
40
34
"Assemble form over mesh and return tensor"
42
37
# Create empty list of coefficients, filled below
43
_coefficients = ArrayFunctionPtr()
38
coefficients_ = ArrayFunctionPtr()
45
40
# Check if we need to compile the form (JIT)
46
41
if hasattr(form, "create_cell_integral"):
47
42
# UFC form, no need to compile
50
45
# Extract coefficients
51
46
if not coefficients is None:
52
# Compile all strings as dolfin::Function
53
string_expressions = []
54
for c in coefficients:
55
# Note: To allow tuples of floats or ints below, this logic becomes more involved...
56
if isinstance(c, (tuple, str)):
57
string_expressions.append(c)
58
if string_expressions:
59
compiled_functions = compile_functions(string_expressions, mesh)
60
compiled_functions.reverse()
62
# Build list of coefficients
63
for c in coefficients:
64
# Note: We could generalize this to support more objects
65
# like sympy expressions, tuples for constant vectors, etc...
47
for c in coefficients:
48
# Note: We could generalize this to support more objects like sympy expressions, tuples for constant vectors, etc...
66
49
if isinstance(c, (float, int)):
67
50
c = cpp_Function(mesh, float(c))
68
elif isinstance(c, (tuple, str)):
69
c = compiled_functions.pop()
70
_coefficients.push_back(c)
51
coefficients_.push_back(c)
72
53
# FFC form, call JIT compile
73
optimize = dolfin_get("optimize form") or dolfin_get("optimize")
74
(compiled_form, module, form_data) = jit(form, optimize=optimize)
54
(compiled_form, module, form_data) = jit(form)
76
56
# Extract coefficients
77
57
for c in form_data.coefficients:
78
_coefficients.push_back(c.f)
80
# FIXME: do we need these lines now? None works fine with Assembler
81
# Create dummy arguments for domains (not yet supported in Python)
58
coefficients_.push_back(c.f)
60
# Create dummy arguments for domains (not yet supported in Python) FIXME: do we need these lines now? None works fine with Assembler.
82
61
if cell_domains is None:
83
62
cell_domains = MeshFunction("uint")
84
63
if exterior_facet_domains is None:
85
64
exterior_facet_domains = MeshFunction("uint")
86
65
if interior_facet_domains is None:
87
66
interior_facet_domains = MeshFunction("uint")
89
68
# Create dof map set
90
dof_maps = _create_dof_map_set(form, compiled_form, mesh, dof_maps)
70
dof_maps = DofMapSet(compiled_form, mesh)
93
74
rank = compiled_form.rank()
94
(tensor, reset_tensor) = _create_tensor(form, rank, backend, tensor, reset_tensor)
96
# Set default value for reset_tensor if not specified
97
if reset_tensor is None:
79
if backend: tensor = backend.createVector()
80
else: tensor = Vector()
82
if backend: tensor = backend.createMatrix()
83
else: tensor = Matrix()
85
raise RuntimeError, "Unable to create tensors of rank %d." % rank
100
87
# Assemble tensor from compiled form
101
cpp_assemble(tensor, compiled_form, mesh, _coefficients, dof_maps,
102
cell_domains, exterior_facet_domains, interior_facet_domains, reset_tensor)
88
cpp_assemble(tensor, compiled_form, mesh, coefficients_, dof_maps,
89
cell_domains, exterior_facet_domains, interior_facet_domains, True)
104
91
# Convert to float for scalars
114
def _create_dof_map_set(form, compiled_form, mesh, dof_maps):
115
"Create dof map set for form"
117
# Check if dof map set is supplied by user
121
# Check if we should use the cache
122
use_cache = dolfin_get("optimize use dof map cache") or dolfin_get("optimize")
123
if use_cache and form in _dof_map_cache:
124
return _dof_map_cache[form]
127
dof_maps = DofMapSet(compiled_form, mesh)
131
_dof_map_cache[form] = dof_maps
135
def _create_tensor(form, rank, backend, tensor, reset_tensor):
136
"Create tensor for form"
138
# Check if tensor is supplied by user
140
return (tensor, reset_tensor)
142
# Decide if we should reset the tensor
143
use_cache = dolfin_get("optimize use tensor cache") or dolfin_get("optimize")
144
if use_cache and reset_tensor is None:
145
reset_tensor = not form in _tensor_cache
147
# Check if we should use the cache
148
if use_cache and form in _tensor_cache:
149
return (_tensor_cache[form], reset_tensor)
155
if backend: tensor = backend.createVector()
156
else: tensor = Vector()
158
if backend: tensor = backend.createMatrix()
159
else: tensor = Matrix()
161
raise RuntimeError, "Unable to create tensors of rank %d." % rank
165
_tensor_cache[form] = tensor
167
return (tensor, reset_tensor)
169
101
# Rename FFC Function
170
102
ffc_Function = Function