@@ -337,14 +337,49 @@ def __init__(
337337 subdomain : VolumeSubdomain | None = None ,
338338 checkpoint : bool = False ,
339339 ):
340- def expression (T , reactants , products ):
340+
341+ reactant_names = [reactant .name for reactant in reaction .reactant ]
342+ if isinstance (reaction .product , list ):
343+ product_names = [product .name for product in reaction .product ]
344+ else :
345+ product_names = [reaction .product .name ]
346+
347+ def expression (T , ** kwargs ):
348+ _reactant_names = [kwargs [name ] for name in reactant_names ]
349+ _product_names = [kwargs [name ] for name in product_names ]
341350 k = reaction .k_0 * ufl .exp (- reaction .E_k / (_k_B * T ))
342351 if reaction .p_0 and reaction .E_p :
343352 p = reaction .p_0 * ufl .exp (- reaction .E_p / (_k_B * T ))
344353 elif reaction .p_0 :
345354 p = reaction .p_0
346-
347- return k * ufl .product (reactants ) - p * ufl .product (products )
355+ else :
356+ p = 0.0
357+
358+ return k * ufl .product (_reactant_names ) - p * ufl .product (_product_names )
359+
360+ # generate the __signature__ of the expression function so that it has the
361+ # correct arguments for the user-provided expression.
362+ # This is needed as set_dolfinx_expression() checks
363+ # the arguments of expression and it would otherwise look for kwargs
364+ sig_params = [inspect .Parameter ("T" , inspect .Parameter .POSITIONAL_OR_KEYWORD )]
365+ # Use dict.fromkeys to preserve order and remove duplicates
366+ for name in dict .fromkeys (reactant_names + product_names ):
367+ sig_params .append (
368+ inspect .Parameter (name , inspect .Parameter .POSITIONAL_OR_KEYWORD )
369+ )
370+ expression .__signature__ = inspect .Signature (sig_params )
371+
372+ assert inspect .signature (expression ).parameters .keys () == {
373+ "T" ,
374+ * reactant_names ,
375+ * product_names ,
376+ }, (
377+ "The expression for the reaction rate is automatically generated based on the "
378+ "reaction provided. The arguments of the expression must be T (temperature) and "
379+ "the names of the reactants and products. The current expression has arguments "
380+ f"{ inspect .signature (expression ).parameters .keys ()} but should have arguments "
381+ f"T and { reactant_names + product_names } ."
382+ )
348383
349384 super ().__init__ (
350385 filename = filename ,
0 commit comments