@@ -223,6 +223,8 @@ class L2TransformedFunctional(AbstractReducedFunctional):
223
223
Functional defining the optimization problem, :math:`J`.
224
224
controls : Control or Sequence[Control]
225
225
Controls. Must be :class:`firedrake.Function` objects.
226
+ space_D : None, WithGeometry, or Sequence[None or WithGeometry]
227
+ DG space containing the control space.
226
228
riesz_map : L2RieszMap or Sequence[L2RieszMap]
227
229
Used for projecting from the DG space onto the control space. Ignored
228
230
for DG controls.
@@ -241,18 +243,27 @@ class L2TransformedFunctional(AbstractReducedFunctional):
241
243
"""
242
244
243
245
@no_annotations
244
- def __init__ (self , functional , controls , * , riesz_map = None , alpha = 0 , tape = None ):
246
+ def __init__ (self , functional , controls , * , space_D = None , riesz_map = None , alpha = 0 , tape = None ):
245
247
if not all (isinstance (control .control , fd .Function ) for control in Enlist (controls )):
246
248
raise TypeError ("controls must be Function objects" )
247
249
248
250
super ().__init__ ()
249
251
self ._J = ReducedFunctional (functional , controls , tape = tape )
252
+
250
253
self ._space = tuple (control .control .function_space ()
251
254
for control in self ._J .controls )
252
- self ._space_D = tuple (map (dg_space , self ._space ))
255
+ if space_D is None :
256
+ space_D = tuple (None for _ in self ._space )
257
+ self ._space_D = Enlist (space_D )
258
+ if len (self ._space_D ) != len (self ._space ):
259
+ raise ValueError ("Invalid length" )
260
+ self ._space_D = tuple (dg_space (space ) if space_D is None else space_D
261
+ for space , space_D in zip (self ._space , self ._space_D ))
262
+
253
263
self ._controls = tuple (Control (fd .Function (space_D ), riesz_map = "l2" )
254
264
for space_D in self ._space_D )
255
265
self ._controls = Enlist (Enlist (controls ).delist (self ._controls ))
266
+
256
267
self ._alpha = alpha
257
268
self ._m_k = None
258
269
0 commit comments