@@ -223,6 +223,8 @@ class L2TransformedFunctional(AbstractReducedFunctional):
223223 Functional defining the optimization problem, :math:`J`.
224224 controls : Control or Sequence[Control]
225225 Controls. Must be :class:`firedrake.Function` objects.
226+ space_D : None, WithGeometry, or Sequence[None or WithGeometry]
227+ DG space containing the control space.
226228 riesz_map : L2RieszMap or Sequence[L2RieszMap]
227229 Used for projecting from the DG space onto the control space. Ignored
228230 for DG controls.
@@ -241,18 +243,27 @@ class L2TransformedFunctional(AbstractReducedFunctional):
241243 """
242244
243245 @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 ):
245247 if not all (isinstance (control .control , fd .Function ) for control in Enlist (controls )):
246248 raise TypeError ("controls must be Function objects" )
247249
248250 super ().__init__ ()
249251 self ._J = ReducedFunctional (functional , controls , tape = tape )
252+
250253 self ._space = tuple (control .control .function_space ()
251254 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+
253263 self ._controls = tuple (Control (fd .Function (space_D ), riesz_map = "l2" )
254264 for space_D in self ._space_D )
255265 self ._controls = Enlist (Enlist (controls ).delist (self ._controls ))
266+
256267 self ._alpha = alpha
257268 self ._m_k = None
258269
0 commit comments