You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/systems/callbacks.jl
+39-39Lines changed: 39 additions & 39 deletions
Original file line number
Diff line number
Diff line change
@@ -77,25 +77,29 @@ end
77
77
`MutatingFunctionalAffect` is a helper for writing affect functions that will compute observed values and
78
78
ensure that modified values are correctly written back into the system. The affect function `f` needs to have
79
79
one of four signatures:
80
-
* `f(modified::ComponentArray)` if the function only writes values (unknowns or parameters) to the system,
81
-
* `f(modified::ComponentArray, observed::ComponentArray)` if the function also reads observed values from the system,
82
-
* `f(modified::ComponentArray, observed::ComponentArray, ctx)` if the function needs the user-defined context,
83
-
* `f(modified::ComponentArray, observed::ComponentArray, ctx, integrator)` if the function needs the low-level integrator.
80
+
* `f(modified::NamedTuple)::NamedTuple` if the function only writes values (unknowns or parameters) to the system,
81
+
* `f(modified::NamedTuple, observed::NamedTuple)::NamedTuple` if the function also reads observed values from the system,
82
+
* `f(modified::NamedTuple, observed::NamedTuple, ctx)::NamedTuple` if the function needs the user-defined context,
83
+
* `f(modified::NamedTuple, observed::NamedTuple, ctx, integrator)::NamedTuple` if the function needs the low-level integrator.
84
84
These will be checked in reverse order (that is, the four-argument version first, than the 3, etc).
85
85
86
-
The function `f` will be called with `observed` and `modified` `ComponentArray`s that are derived from their respective `NamedTuple` definitions.
87
-
Each `NamedTuple` should map an expression to a symbol; for example if we pass `observed=(; x = a + b)` this will alias the result of executing `a+b` in the system as `x`
86
+
The function `f` will be called with `observed` and `modified` `NamedTuple`s that are derived from their respective `NamedTuple` definitions.
87
+
Each declaration`NamedTuple` should map an expression to a symbol; for example if we pass `observed=(; x = a + b)` this will alias the result of executing `a+b` in the system as `x`
88
88
so the value of `a + b` will be accessible as `observed.x` in `f`. `modified` currently restricts symbolic expressions to only bare variables, so only tuples of the form
89
89
`(; x = y)` or `(; x)` (which aliases `x` as itself) are allowed.
90
90
91
-
Both `observed` and `modified` will be automatically populated with the current values of their corresponding expressions on function entry.
92
-
The values in `modified` will be written back to the system after `f` returns. For example, if we want to update the value of `x` to be the result of `x + y` we could write
91
+
The argument NamedTuples (for instance `(;x=y)`) will be populated with the declared values on function entry; if we require `(;x=y)` in `observed` and `y=2`, for example,
92
+
then the NamedTuple `(;x=2)` will be passed as `observed` to the affect function `f`.
93
+
94
+
The NamedTuple returned from `f` includes the values to be written back to the system after `f` returns. For example, if we want to update the value of `x` to be the result of `x + y` we could write
93
95
94
96
MutatingFunctionalAffect(observed=(; x_plus_y = x + y), modified=(; x)) do m, o
95
-
m.x = o.x_plus_y
97
+
@set! m.x = o.x_plus_y
96
98
end
97
99
98
-
The affect function updates the value at `x` in `modified` to be the result of evaluating `x + y` as passed in the observed values.
100
+
Where we use Setfield to copy the tuple `m` with a new value for `x`, then return the modified value of `m`. All values updated by the tuple must have names originally declared in
101
+
`modified`; a runtime error will be produced if a value is written that does not appear in `modified`. The user can dynamically decide not to write a value back by not including it
102
+
in the returned tuple, in which case the associated field will not be updated.
99
103
"""
100
104
@kwdefstruct MutatingFunctionalAffect
101
105
f::Any
@@ -983,6 +987,18 @@ function unassignable_variables(sys, expr)
983
987
x ->!any(isequal(x), assignable_syms), written)
984
988
end
985
989
990
+
@generatedfunction_generated_writeback(integ, setters::NamedTuple{NS1,<:Tuple}, values::NamedTuple{NS2, <:Tuple}) where {NS1, NS2}
991
+
setter_exprs = []
992
+
for name in NS2
993
+
if!(name in NS1)
994
+
missing_name ="Tried to write back to $name from affect; only declared states ($NS1) may be written to."
Copy file name to clipboardExpand all lines: src/systems/diffeqs/odesystem.jl
+5-5Lines changed: 5 additions & 5 deletions
Original file line number
Diff line number
Diff line change
@@ -429,6 +429,7 @@ Options not otherwise specified are:
429
429
* `op = Operator` sets the recursion terminator for the walk done by `vars` to identify the variables that appear in `ts`. See the documentation for `vars` for more detail.
430
430
* `throw = true` if true, throw an error when generating a function for `ts` that reference variables that do not exist
431
431
* `drop_expr` is deprecated.
432
+
* `array_type`; only used if the output is an array (that is, `!isscalar(ts)`). If `:array`, then it will generate an array, if `:tuple` then it will generate a tuple.
432
433
"""
433
434
functionbuild_explicit_observed_function(sys, ts;
434
435
inputs =nothing,
@@ -442,7 +443,8 @@ function build_explicit_observed_function(sys, ts;
442
443
return_inplace =false,
443
444
param_only =false,
444
445
op = Operator,
445
-
throw =true)
446
+
throw =true,
447
+
array_type=:array)
446
448
if (isscalar =symbolic_type(ts) !==NotSymbolic())
447
449
ts = [ts]
448
450
end
@@ -587,12 +589,10 @@ function build_explicit_observed_function(sys, ts;
0 commit comments