@@ -72,6 +72,36 @@ struct AnalysisPoint
7272 these are all `RealInput` connectors.
7373 """
7474 outputs:: Union{Nothing, Vector{Any}}
75+
76+ function AnalysisPoint (input, name:: Symbol , outputs; verbose = true )
77+ # input to analysis point should be an output variable
78+ if verbose && input != = nothing
79+ var = ap_var (input)
80+ isoutput (var) || ap_warning (1 , name, true )
81+ end
82+ # outputs of analysis points should be input variables
83+ if verbose && outputs != = nothing
84+ for (i, output) in enumerate (outputs)
85+ var = ap_var (output)
86+ isinput (var) || ap_warning (2 + i, name, false )
87+ end
88+ end
89+
90+ return new (input, name, outputs)
91+ end
92+ end
93+
94+ function ap_warning (arg:: Int , name:: Symbol , should_be_output)
95+ causality = should_be_output ? " output" : " input"
96+ @warn """
97+ The $(arg) -th argument to analysis point $(name) was not a $causality . This is supported in \
98+ order to handle inverse models, but may not be what you intended.
99+
100+ If you are building a forward mode (causal), you may want to swap this argument with \
101+ one on the opposite side of the name of the analysis point provided to `connect`. \
102+ Learn more about the causality of analysis points in the docstring for `AnalysisPoint`. \
103+ Silence this message using `connect(out, :name, in...; warn = false)`.
104+ """
75105end
76106
77107AnalysisPoint () = AnalysisPoint (nothing , Symbol (), nothing )
@@ -133,8 +163,8 @@ function renamespace(sys, ap::AnalysisPoint)
133163end
134164
135165# create analysis points via `connect`
136- function Symbolics. connect (in, ap:: AnalysisPoint , outs... )
137- return AnalysisPoint () ~ AnalysisPoint (in, ap. name, collect (outs))
166+ function Symbolics. connect (in, ap:: AnalysisPoint , outs... ; verbose = true )
167+ return AnalysisPoint () ~ AnalysisPoint (in, ap. name, collect (outs); verbose )
138168end
139169
140170"""
@@ -161,15 +191,21 @@ connect(P.input, :plant_input, C.output)
161191
162192typically is not (unless the model is an inverse model).
163193
164- # Arguments:
194+ # Arguments
195+
196+ - `output_connector`: An output connector
197+ - `input_connector`: An input connector
198+ - `ap`: An explicitly created [`AnalysisPoint`](@ref)
199+ - `ap_name`: If a name is given, an [`AnalysisPoint`](@ref) with the given name will be
200+ created automatically.
201+
202+ # Keyword arguments
165203
166- - `output_connector`: An output connector
167- - `input_connector`: An input connector
168- - `ap`: An explicitly created [`AnalysisPoint`](@ref)
169- - `ap_name`: If a name is given, an [`AnalysisPoint`](@ref) with the given name will be created automatically.
204+ - `verbose`: Warn if an input is connected to an output (reverse causality). Silence this
205+ warning if you are analyzing an inverse model.
170206"""
171- function Symbolics. connect (in:: AbstractSystem , name:: Symbol , out, outs... )
172- return AnalysisPoint () ~ AnalysisPoint (in, name, [out; collect (outs)])
207+ function Symbolics. connect (in:: AbstractSystem , name:: Symbol , out, outs... ; verbose = true )
208+ return AnalysisPoint () ~ AnalysisPoint (in, name, [out; collect (outs)]; verbose )
173209end
174210
175211"""
0 commit comments