498498Substitutions (subs, deps) = Substitutions (subs, deps, nothing )
499499
500500Base. nameof (sys:: AbstractSystem ) = getfield (sys, :name )
501+ description (sys:: AbstractSystem ) = has_description (sys) ? get_description (sys) : " "
501502
502503# Deprecated
503504function independent_variable (sys:: AbstractSystem )
@@ -999,6 +1000,7 @@ for prop in [:eqs
9991000 :ps
10001001 :tspan
10011002 :name
1003+ :description
10021004 :var_to_name
10031005 :ctrls
10041006 :defaults
@@ -1865,8 +1867,14 @@ function get_or_construct_tearing_state(sys)
18651867 state
18661868end
18671869
1868- # TODO : what about inputs?
1869- function n_extra_equations (sys:: AbstractSystem )
1870+ """
1871+ n_expanded_connection_equations(sys::AbstractSystem)
1872+
1873+ Returns the number of equations that the connections in `sys` expands to.
1874+ Equivalent to `length(equations(expand_connections(sys))) - length(filter(eq -> !(eq.lhs isa Connection), equations(sys)))`.
1875+ """
1876+ function n_expanded_connection_equations (sys:: AbstractSystem )
1877+ # TODO : what about inputs?
18701878 isconnector (sys) && return length (get_unknowns (sys))
18711879 sys, (csets, _) = generate_connection_set (sys)
18721880 ceqs, instream_csets = generate_connection_equations_and_stream_connections (csets)
@@ -1893,84 +1901,89 @@ function n_extra_equations(sys::AbstractSystem)
18931901 nextras = n_outer_stream_variables + length (ceqs)
18941902end
18951903
1896- function Base. show (io:: IO , mime:: MIME"text/plain" , sys:: AbstractSystem )
1897- eqs = equations (sys)
1898- vars = unknowns (sys)
1899- nvars = length (vars)
1900- if eqs isa AbstractArray && eltype (eqs) <: Equation
1901- neqs = count (eq -> ! (eq. lhs isa Connection), eqs)
1902- Base. printstyled (io, " Model $(nameof (sys)) with $neqs " ; bold = true )
1903- nextras = n_extra_equations (sys)
1904- if nextras > 0
1905- Base. printstyled (io, " (" ; bold = true )
1906- Base. printstyled (io, neqs + nextras; bold = true , color = :magenta )
1907- Base. printstyled (io, " ) " ; bold = true )
1908- end
1909- Base. printstyled (io, " equations\n " ; bold = true )
1910- else
1911- Base. printstyled (io, " Model $(nameof (sys)) \n " ; bold = true )
1912- end
1913- # The reduced equations are usually very long. It's not that useful to print
1914- # them.
1915- # Base.print_matrix(io, eqs)
1916- # println(io)
1904+ function Base. show (
1905+ io:: IO , mime:: MIME"text/plain" , sys:: AbstractSystem ; hint = true , bold = true )
1906+ limit = get (io, :limit , false ) # if output should be limited,
1907+ rows = first (displaysize (io)) ÷ 5 # then allocate ≈1/5 of display height to each list
19171908
1918- rows = first (displaysize (io)) ÷ 5
1919- limit = get (io, :limit , false )
1909+ # Print name and description
1910+ desc = description (sys)
1911+ printstyled (io, " Model " , nameof (sys), " :" ; bold)
1912+ ! isempty (desc) && print (io, " " , desc)
19201913
1921- Base. printstyled (io, " Unknowns ($nvars ):" ; bold = true )
1922- nrows = min (nvars, limit ? rows : nvars)
1923- limited = nrows < length (vars)
1924- defs = has_defaults (sys) ? defaults (sys) : nothing
1914+ # Print subsystems
1915+ subs = get_systems (sys)
1916+ nsubs = length (subs)
1917+ nrows = min (nsubs, limit ? rows : nsubs)
1918+ nrows > 0 && printstyled (io, " \n Subsystems ($(nsubs) ):" ; bold)
1919+ nrows > 0 && hint && print (io, " see hierarchy(sys)" )
19251920 for i in 1 : nrows
1926- s = vars[i]
1927- print (io, " \n " , s)
1928-
1929- if defs != = nothing
1930- val = get (defs, s, nothing )
1931- if val != = nothing
1932- print (io, " [defaults to " )
1933- show (
1934- IOContext (io, :compact => true , :limit => true ,
1935- :displaysize => (1 , displaysize (io)[2 ])),
1936- val)
1937- print (io, " ]" )
1938- end
1939- description = getdescription (s)
1940- if description != = nothing && description != " "
1941- print (io, " : " , description)
1921+ sub = subs[i]
1922+ name = String (nameof (sub))
1923+ print (io, " \n " , name)
1924+ desc = description (sub)
1925+ if ! isempty (desc)
1926+ maxlen = displaysize (io)[2 ] - length (name) - 6 # remaining length of line
1927+ if limit && length (desc) > maxlen
1928+ desc = chop (desc, tail = length (desc) - maxlen) * " …" # too long
19421929 end
1930+ print (io, " : " , desc)
19431931 end
19441932 end
1945- limited && print (io, " \n ⋮ " )
1946- println (io)
1933+ limited = nrows < nsubs
1934+ limited && print (io, " \n ⋮ " ) # too many to print
19471935
1948- vars = parameters (sys)
1949- nvars = length (vars)
1950- Base. printstyled (io, " Parameters ($nvars ):" ; bold = true )
1951- nrows = min (nvars, limit ? rows : nvars)
1952- limited = nrows < length (vars)
1953- for i in 1 : nrows
1954- s = vars[i]
1955- print (io, " \n " , s)
1956-
1957- if defs != = nothing
1958- val = get (defs, s, nothing )
1959- if val != = nothing
1960- print (io, " [defaults to " )
1961- show (
1962- IOContext (io, :compact => true , :limit => true ,
1963- :displaysize => (1 , displaysize (io)[2 ])),
1964- val)
1965- print (io, " ]" )
1936+ # Print equations
1937+ eqs = equations (sys)
1938+ if eqs isa AbstractArray && eltype (eqs) <: Equation
1939+ neqs = count (eq -> ! (eq. lhs isa Connection), eqs)
1940+ next = n_expanded_connection_equations (sys)
1941+ ntot = neqs + next
1942+ ntot > 0 && printstyled (io, " \n Equations ($ntot ):" ; bold)
1943+ neqs > 0 && print (io, " \n $neqs standard" , hint ? " : see equations(sys)" : " " )
1944+ next > 0 && print (io, " \n $next connecting" ,
1945+ hint ? " : see equations(expand_connections(sys))" : " " )
1946+ # Base.print_matrix(io, eqs) # usually too long and not useful to print all equations
1947+ end
1948+
1949+ # Print variables
1950+ for varfunc in [unknowns, parameters]
1951+ vars = varfunc (sys)
1952+ nvars = length (vars)
1953+ nvars == 0 && continue # skip
1954+ header = titlecase (String (nameof (varfunc))) # e.g. "Unknowns"
1955+ printstyled (io, " \n $header ($nvars ):" ; bold)
1956+ hint && print (io, " see $(nameof (varfunc)) (sys)" )
1957+ nrows = min (nvars, limit ? rows : nvars)
1958+ defs = has_defaults (sys) ? defaults (sys) : nothing
1959+ for i in 1 : nrows
1960+ s = vars[i]
1961+ print (io, " \n " , s)
1962+ if ! isnothing (defs)
1963+ val = get (defs, s, nothing )
1964+ if ! isnothing (val)
1965+ print (io, " [defaults to " )
1966+ show (
1967+ IOContext (io, :compact => true , :limit => true ,
1968+ :displaysize => (1 , displaysize (io)[2 ])),
1969+ val)
1970+ print (io, " ]" )
1971+ end
1972+ desc = getdescription (s)
19661973 end
1967- description = getdescription (s)
1968- if description != = nothing && description != " "
1969- print (io, " : " , description)
1974+ if ! isnothing (desc) && desc != " "
1975+ print (io, " : " , desc)
19701976 end
19711977 end
1978+ limited = nrows < nvars
1979+ limited && printstyled (io, " \n ⋮" ) # too many variables to print
19721980 end
1973- limited && print (io, " \n ⋮" )
1981+
1982+ # Print observed
1983+ nobs = has_observed (sys) ? length (observed (sys)) : 0
1984+ nobs > 0 && printstyled (io, " \n Observed ($nobs ):" ; bold)
1985+ nobs > 0 && hint && print (io, " see observed(sys)" )
1986+
19741987 return nothing
19751988end
19761989
@@ -2911,12 +2924,23 @@ function Base.showerror(io::IO, e::HybridSystemNotSupportedException)
29112924 print (io, " HybridSystemNotSupportedException: " , e. msg)
29122925end
29132926
2914- function AbstractTrees. children (sys:: ModelingToolkit. AbstractSystem )
2927+ function AbstractTrees. children (sys:: AbstractSystem )
29152928 ModelingToolkit. get_systems (sys)
29162929end
2917- function AbstractTrees. printnode (io:: IO , sys:: ModelingToolkit.AbstractSystem )
2918- print (io, nameof (sys))
2930+ function AbstractTrees. printnode (
2931+ io:: IO , sys:: AbstractSystem ; describe = false , bold = false )
2932+ printstyled (io, nameof (sys); bold)
2933+ describe && ! isempty (description (sys)) && print (io, " : " , description (sys))
29192934end
2935+ """
2936+ hierarchy(sys::AbstractSystem; describe = false, bold = describe, kwargs...)
2937+
2938+ Print a tree of a system's hierarchy of subsystems.
2939+ """
2940+ function hierarchy (sys:: AbstractSystem ; describe = false , bold = describe, kwargs... )
2941+ print_tree (sys; printnode_kw = (describe = describe, bold = bold), kwargs... )
2942+ end
2943+
29202944function Base. IteratorEltype (:: Type{<:TreeIterator{ModelingToolkit.AbstractSystem}} )
29212945 Base. HasEltype ()
29222946end
@@ -2999,12 +3023,13 @@ function extend(sys::AbstractSystem, basesys::AbstractSystem; name::Symbol = nam
29993023 cevs = union (get_continuous_events (basesys), get_continuous_events (sys))
30003024 devs = union (get_discrete_events (basesys), get_discrete_events (sys))
30013025 defs = merge (get_defaults (basesys), get_defaults (sys)) # prefer `sys`
3026+ desc = join (filter (desc -> ! isempty (desc), description .([sys, basesys])), " " ) # concatenate non-empty descriptions with space
30023027 meta = union_nothing (get_metadata (basesys), get_metadata (sys))
30033028 syss = union (get_systems (basesys), get_systems (sys))
30043029 args = length (ivs) == 0 ? (eqs, sts, ps) : (eqs, ivs[1 ], sts, ps)
30053030 kwargs = (parameter_dependencies = dep_ps, observed = obs, continuous_events = cevs,
30063031 discrete_events = devs, defaults = defs, systems = syss, metadata = meta,
3007- name = name, gui_metadata = gui_metadata)
3032+ name = name, description = desc, gui_metadata = gui_metadata)
30083033
30093034 # collect fields specific to some system types
30103035 if basesys isa ODESystem
0 commit comments