@@ -325,11 +325,8 @@ def __init__(
325325 self ._quantities : list [dict [str , Any ]] = []
326326 self ._params : dict [str , str ] = {} # even numerical values are stored as str
327327 self ._inputs : dict [str , list [tuple [float , float ]]] = {}
328- # _outputs values are str before simulate(), but they can be
329- # np.float64 after simulate().
330- self ._outputs : dict [str , Any ] = {}
331- # same for _continuous
332- self ._continuous : dict [str , Any ] = {}
328+ self ._outputs : dict [str , np .float64 ] = {} # numpy.float64 as it allows to define None values
329+ self ._continuous : dict [str , np .float64 ] = {} # numpy.float64 as it allows to define None values
333330 self ._simulate_options : dict [str , str ] = {}
334331 self ._override_variables : dict [str , str ] = {}
335332 self ._simulate_options_override : dict [str , str ] = {}
@@ -629,11 +626,11 @@ def _xmlparse(self, xml_file: OMCPath):
629626 else :
630627 self ._params [scalar ["name" ]] = scalar ["start" ]
631628 if scalar ["variability" ] == "continuous" :
632- self ._continuous [scalar ["name" ]] = scalar ["start" ]
629+ self ._continuous [scalar ["name" ]] = np . float64 ( scalar ["start" ])
633630 if scalar ["causality" ] == "input" :
634631 self ._inputs [scalar ["name" ]] = scalar ["start" ]
635632 if scalar ["causality" ] == "output" :
636- self ._outputs [scalar ["name" ]] = scalar ["start" ]
633+ self ._outputs [scalar ["name" ]] = np . float64 ( scalar ["start" ])
637634
638635 self ._quantities .append (scalar )
639636
@@ -694,15 +691,104 @@ def getQuantities(self, names: Optional[str | list[str]] = None) -> list[dict]:
694691
695692 raise ModelicaSystemError ("Unhandled input for getQuantities()" )
696693
694+ def getContinuousInitial (
695+ self ,
696+ names : Optional [str | list [str ]] = None ,
697+ ) -> dict [str , np .float64 ] | list [np .float64 ]:
698+ """
699+ Get (initial) values of continuous signals.
700+
701+ Args:
702+ names: Either None (default), a string with the continuous signal
703+ name, or a list of signal name strings.
704+ Returns:
705+ If `names` is None, a dict in the format
706+ {signal_name: signal_value} is returned.
707+ If `names` is a string, a single element list [signal_value] is
708+ returned.
709+ If `names` is a list, a list with one value for each signal name
710+ in names is returned: [signal1_value, signal2_value, ...].
711+
712+ Examples:
713+ >>> mod.getContinuousInitial()
714+ {'x': '1.0', 'der(x)': None, 'y': '-0.4'}
715+ >>> mod.getContinuousInitial("y")
716+ ['-0.4']
717+ >>> mod.getContinuousInitial(["y","x"])
718+ ['-0.4', '1.0']
719+ """
720+ if names is None :
721+ return self ._continuous
722+ if isinstance (names , str ):
723+ return [self ._continuous [names ]]
724+ if isinstance (names , list ):
725+ return [self ._continuous [x ] for x in names ]
726+
727+ raise ModelicaSystemError ("Unhandled input for getContinousInitial()" )
728+
729+ def getContinuousFinal (
730+ self ,
731+ names : Optional [str | list [str ]] = None ,
732+ ) -> dict [str , np .float64 ] | list [np .float64 ]:
733+ """
734+ Get (final) values of continuous signals (at stopTime).
735+
736+ Args:
737+ names: Either None (default), a string with the continuous signal
738+ name, or a list of signal name strings.
739+ Returns:
740+ If `names` is None, a dict in the format
741+ {signal_name: signal_value} is returned.
742+ If `names` is a string, a single element list [signal_value] is
743+ returned.
744+ If `names` is a list, a list with one value for each signal name
745+ in names is returned: [signal1_value, signal2_value, ...].
746+
747+ Examples:
748+ >>> mod.getContinuousFinal()
749+ {'x': np.float64(0.68), 'der(x)': np.float64(-0.24), 'y': np.float64(-0.24)}
750+ >>> mod.getContinuousFinal("x")
751+ [np.float64(0.68)]
752+ >>> mod.getContinuousFinal(["y","x"])
753+ [np.float64(-0.24), np.float64(0.68)]
754+ """
755+ if not self ._simulated :
756+ raise ModelicaSystemError ("Please use getContinuousInitial() before the simulation was started!" )
757+
758+ def get_continuous_solution (name_list : list [str ]) -> None :
759+ for name in name_list :
760+ if name in self ._continuous :
761+ value = self .getSolutions (name )
762+ self ._continuous [name ] = np .float64 (value [0 ][- 1 ])
763+ else :
764+ raise KeyError (f"{ names } is not continuous" )
765+
766+ if names is None :
767+ get_continuous_solution (name_list = list (self ._continuous .keys ()))
768+ return self ._continuous
769+
770+ if isinstance (names , str ):
771+ get_continuous_solution (name_list = [names ])
772+ return [self ._continuous [names ]]
773+
774+ if isinstance (names , list ):
775+ get_continuous_solution (name_list = names )
776+ values = []
777+ for name in names :
778+ values .append (self ._continuous [name ])
779+ return values
780+
781+ raise ModelicaSystemError ("Unhandled input for getContinousFinal()" )
782+
697783 def getContinuous (
698784 self ,
699785 names : Optional [str | list [str ]] = None ,
700- ) -> dict [str , str | numbers . Real ] | list [str | numbers . Real ]:
786+ ) -> dict [str , np . float64 ] | list [np . float64 ]:
701787 """Get values of continuous signals.
702788
703- If called before simulate(), the initial values are returned as
704- strings (or None). If called after simulate(), the final values (at
705- stopTime) are returned as numpy.float64.
789+ If called before simulate(), the initial values are returned.
790+ If called after simulate(), the final values (at stopTime) are returned.
791+ The return format is always numpy.float64.
706792
707793 Args:
708794 names: Either None (default), a string with the continuous signal
@@ -729,45 +815,13 @@ def getContinuous(
729815 {'x': np.float64(0.68), 'der(x)': np.float64(-0.24), 'y': np.float64(-0.24)}
730816 >>> mod.getContinuous("x")
731817 [np.float64(0.68)]
732- >>> mod.getOutputs (["y","x"])
818+ >>> mod.getContinuous (["y","x"])
733819 [np.float64(-0.24), np.float64(0.68)]
734820 """
735821 if not self ._simulated :
736- if names is None :
737- return self ._continuous
738- if isinstance (names , str ):
739- return [self ._continuous [names ]]
740- if isinstance (names , list ):
741- return [self ._continuous [x ] for x in names ]
742-
743- if names is None :
744- for name in self ._continuous :
745- try :
746- value = self .getSolutions (name )
747- self ._continuous [name ] = value [0 ][- 1 ]
748- except (OMCSessionException , ModelicaSystemError ) as ex :
749- raise ModelicaSystemError (f"{ name } could not be computed" ) from ex
750- return self ._continuous
751-
752- if isinstance (names , str ):
753- if names in self ._continuous :
754- value = self .getSolutions (names )
755- self ._continuous [names ] = value [0 ][- 1 ]
756- return [self ._continuous [names ]]
757- raise ModelicaSystemError (f"{ names } is not continuous" )
758-
759- if isinstance (names , list ):
760- valuelist = []
761- for name in names :
762- if name in self ._continuous :
763- value = self .getSolutions (name )
764- self ._continuous [name ] = value [0 ][- 1 ]
765- valuelist .append (value [0 ][- 1 ])
766- else :
767- raise ModelicaSystemError (f"{ name } is not continuous" )
768- return valuelist
822+ return self .getContinuousInitial (names = names )
769823
770- raise ModelicaSystemError ( "Unhandled input for getContinous()" )
824+ return self . getContinuousFinal ( names = names )
771825
772826 def getParameters (
773827 self ,
@@ -840,15 +894,103 @@ def getInputs(
840894
841895 raise ModelicaSystemError ("Unhandled input for getInputs()" )
842896
897+ def getOutputsInitial (
898+ self ,
899+ names : Optional [str | list [str ]] = None ,
900+ ) -> dict [str , np .float64 ] | list [np .float64 ]:
901+ """
902+ Get (initial) values of output signals.
903+
904+ Args:
905+ names: Either None (default), a string with the output name,
906+ or a list of output name strings.
907+ Returns:
908+ If `names` is None, a dict in the format
909+ {output_name: output_value} is returned.
910+ If `names` is a string, a single element list [output_value] is
911+ returned.
912+ If `names` is a list, a list with one value for each output name
913+ in names is returned: [output1_value, output2_value, ...].
914+
915+ Examples:
916+ >>> mod.getOutputsInitial()
917+ {'out1': '-0.4', 'out2': '1.2'}
918+ >>> mod.getOutputsInitial("out1")
919+ ['-0.4']
920+ >>> mod.getOutputsInitial(["out1","out2"])
921+ ['-0.4', '1.2']
922+ """
923+ if names is None :
924+ return self ._outputs
925+ if isinstance (names , str ):
926+ return [self ._outputs [names ]]
927+ if isinstance (names , list ):
928+ return [self ._outputs [x ] for x in names ]
929+
930+ raise ModelicaSystemError ("Unhandled input for getOutputsInitial()" )
931+
932+ def getOutputsFinal (
933+ self ,
934+ names : Optional [str | list [str ]] = None ,
935+ ) -> dict [str , np .float64 ] | list [np .float64 ]:
936+ """Get (final) values of output signals (at stopTime).
937+
938+ Args:
939+ names: Either None (default), a string with the output name,
940+ or a list of output name strings.
941+ Returns:
942+ If `names` is None, a dict in the format
943+ {output_name: output_value} is returned.
944+ If `names` is a string, a single element list [output_value] is
945+ returned.
946+ If `names` is a list, a list with one value for each output name
947+ in names is returned: [output1_value, output2_value, ...].
948+
949+ Examples:
950+ >>> mod.getOutputsFinal()
951+ {'out1': np.float64(-0.1234), 'out2': np.float64(2.1)}
952+ >>> mod.getOutputsFinal("out1")
953+ [np.float64(-0.1234)]
954+ >>> mod.getOutputsFinal(["out1","out2"])
955+ [np.float64(-0.1234), np.float64(2.1)]
956+ """
957+ if not self ._simulated :
958+ raise ModelicaSystemError ("Please use getOuputsInitial() before the simulation was started!" )
959+
960+ def get_outputs_solution (name_list : list [str ]) -> None :
961+ for name in name_list :
962+ if name in self ._outputs :
963+ value = self .getSolutions (name )
964+ self ._outputs [name ] = np .float64 (value [0 ][- 1 ])
965+ else :
966+ raise KeyError (f"{ names } is not a valid output" )
967+
968+ if names is None :
969+ get_outputs_solution (name_list = list (self ._outputs .keys ()))
970+ return self ._outputs
971+
972+ if isinstance (names , str ):
973+ get_outputs_solution (name_list = [names ])
974+ return [self ._outputs [names ]]
975+
976+ if isinstance (names , list ):
977+ get_outputs_solution (name_list = names )
978+ values = []
979+ for name in names :
980+ values .append (self ._outputs [name ])
981+ return values
982+
983+ raise ModelicaSystemError ("Unhandled input for getOutputs()" )
984+
843985 def getOutputs (
844986 self ,
845987 names : Optional [str | list [str ]] = None ,
846- ) -> dict [str , str | numbers . Real ] | list [str | numbers . Real ]:
988+ ) -> dict [str , np . float64 ] | list [np . float64 ]:
847989 """Get values of output signals.
848990
849- If called before simulate(), the initial values are returned as
850- strings. If called after simulate(), the final values (at stopTime)
851- are returned as numpy.float64.
991+ If called before simulate(), the initial values are returned.
992+ If called after simulate(), the final values (at stopTime) are returned.
993+ The return format is always numpy.float64.
852994
853995 Args:
854996 names: Either None (default), a string with the output name,
@@ -879,37 +1021,9 @@ def getOutputs(
8791021 [np.float64(-0.1234), np.float64(2.1)]
8801022 """
8811023 if not self ._simulated :
882- if names is None :
883- return self ._outputs
884- if isinstance (names , str ):
885- return [self ._outputs [names ]]
886- return [self ._outputs [x ] for x in names ]
887-
888- if names is None :
889- for name in self ._outputs :
890- value = self .getSolutions (name )
891- self ._outputs [name ] = value [0 ][- 1 ]
892- return self ._outputs
1024+ return self .getOutputsInitial (names = names )
8931025
894- if isinstance (names , str ):
895- if names in self ._outputs :
896- value = self .getSolutions (names )
897- self ._outputs [names ] = value [0 ][- 1 ]
898- return [self ._outputs [names ]]
899- raise KeyError (names )
900-
901- if isinstance (names , list ):
902- valuelist = []
903- for name in names :
904- if name in self ._outputs :
905- value = self .getSolutions (name )
906- self ._outputs [name ] = value [0 ][- 1 ]
907- valuelist .append (value [0 ][- 1 ])
908- else :
909- raise KeyError (name )
910- return valuelist
911-
912- raise ModelicaSystemError ("Unhandled input for getOutputs()" )
1026+ return self .getOutputsFinal (names = names )
9131027
9141028 def getSimulationOptions (
9151029 self ,
0 commit comments