@@ -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 ] = {}
@@ -630,11 +627,11 @@ def _xmlparse(self, xml_file: OMCPath):
630627 else :
631628 self ._params [scalar ["name" ]] = scalar ["start" ]
632629 if scalar ["variability" ] == "continuous" :
633- self ._continuous [scalar ["name" ]] = scalar ["start" ]
630+ self ._continuous [scalar ["name" ]] = np . float64 ( scalar ["start" ])
634631 if scalar ["causality" ] == "input" :
635632 self ._inputs [scalar ["name" ]] = scalar ["start" ]
636633 if scalar ["causality" ] == "output" :
637- self ._outputs [scalar ["name" ]] = scalar ["start" ]
634+ self ._outputs [scalar ["name" ]] = np . float64 ( scalar ["start" ])
638635
639636 self ._quantities .append (scalar )
640637
@@ -695,15 +692,104 @@ def getQuantities(self, names: Optional[str | list[str]] = None) -> list[dict]:
695692
696693 raise ModelicaSystemError ("Unhandled input for getQuantities()" )
697694
695+ def getContinuousInitial (
696+ self ,
697+ names : Optional [str | list [str ]] = None ,
698+ ) -> dict [str , np .float64 ] | list [np .float64 ]:
699+ """
700+ Get (initial) values of continuous signals.
701+
702+ Args:
703+ names: Either None (default), a string with the continuous signal
704+ name, or a list of signal name strings.
705+ Returns:
706+ If `names` is None, a dict in the format
707+ {signal_name: signal_value} is returned.
708+ If `names` is a string, a single element list [signal_value] is
709+ returned.
710+ If `names` is a list, a list with one value for each signal name
711+ in names is returned: [signal1_value, signal2_value, ...].
712+
713+ Examples:
714+ >>> mod.getContinuousInitial()
715+ {'x': '1.0', 'der(x)': None, 'y': '-0.4'}
716+ >>> mod.getContinuousInitial("y")
717+ ['-0.4']
718+ >>> mod.getContinuousInitial(["y","x"])
719+ ['-0.4', '1.0']
720+ """
721+ if names is None :
722+ return self ._continuous
723+ if isinstance (names , str ):
724+ return [self ._continuous [names ]]
725+ if isinstance (names , list ):
726+ return [self ._continuous [x ] for x in names ]
727+
728+ raise ModelicaSystemError ("Unhandled input for getContinousInitial()" )
729+
730+ def getContinuousFinal (
731+ self ,
732+ names : Optional [str | list [str ]] = None ,
733+ ) -> dict [str , np .float64 ] | list [np .float64 ]:
734+ """
735+ Get (final) values of continuous signals (at stopTime).
736+
737+ Args:
738+ names: Either None (default), a string with the continuous signal
739+ name, or a list of signal name strings.
740+ Returns:
741+ If `names` is None, a dict in the format
742+ {signal_name: signal_value} is returned.
743+ If `names` is a string, a single element list [signal_value] is
744+ returned.
745+ If `names` is a list, a list with one value for each signal name
746+ in names is returned: [signal1_value, signal2_value, ...].
747+
748+ Examples:
749+ >>> mod.getContinuousFinal()
750+ {'x': np.float64(0.68), 'der(x)': np.float64(-0.24), 'y': np.float64(-0.24)}
751+ >>> mod.getContinuousFinal("x")
752+ [np.float64(0.68)]
753+ >>> mod.getContinuousFinal(["y","x"])
754+ [np.float64(-0.24), np.float64(0.68)]
755+ """
756+ if not self ._simulated :
757+ raise ModelicaSystemError ("Please use getContinuousInitial() before the simulation was started!" )
758+
759+ def get_continuous_solution (name_list : list [str ]) -> None :
760+ for name in name_list :
761+ if name in self ._continuous :
762+ value = self .getSolutions (name )
763+ self ._continuous [name ] = np .float64 (value [0 ][- 1 ])
764+ else :
765+ raise ModelicaSystemError (f"{ names } is not continuous" )
766+
767+ if names is None :
768+ get_continuous_solution (name_list = list (self ._continuous .keys ()))
769+ return self ._continuous
770+
771+ if isinstance (names , str ):
772+ get_continuous_solution (name_list = [names ])
773+ return [self ._continuous [names ]]
774+
775+ if isinstance (names , list ):
776+ get_continuous_solution (name_list = names )
777+ values = []
778+ for name in names :
779+ values .append (self ._continuous [name ])
780+ return values
781+
782+ raise ModelicaSystemError ("Unhandled input for getContinousFinal()" )
783+
698784 def getContinuous (
699785 self ,
700786 names : Optional [str | list [str ]] = None ,
701- ) -> dict [str , str | numbers . Real ] | list [str | numbers . Real ]:
787+ ) -> dict [str , np . float64 ] | list [np . float64 ]:
702788 """Get values of continuous signals.
703789
704- If called before simulate(), the initial values are returned as
705- strings (or None). If called after simulate(), the final values (at
706- stopTime) are returned as numpy.float64.
790+ If called before simulate(), the initial values are returned.
791+ If called after simulate(), the final values (at stopTime) are returned.
792+ The return format is always numpy.float64.
707793
708794 Args:
709795 names: Either None (default), a string with the continuous signal
@@ -734,41 +820,9 @@ def getContinuous(
734820 [np.float64(-0.24), np.float64(0.68)]
735821 """
736822 if not self ._simulated :
737- if names is None :
738- return self ._continuous
739- if isinstance (names , str ):
740- return [self ._continuous [names ]]
741- if isinstance (names , list ):
742- return [self ._continuous [x ] for x in names ]
743-
744- if names is None :
745- for name in self ._continuous :
746- try :
747- value = self .getSolutions (name )
748- self ._continuous [name ] = value [0 ][- 1 ]
749- except (OMCSessionException , ModelicaSystemError ) as ex :
750- raise ModelicaSystemError (f"{ name } could not be computed" ) from ex
751- return self ._continuous
823+ return self .getContinuousInitial (names = names )
752824
753- if isinstance (names , str ):
754- if names in self ._continuous :
755- value = self .getSolutions (names )
756- self ._continuous [names ] = value [0 ][- 1 ]
757- return [self ._continuous [names ]]
758- raise ModelicaSystemError (f"{ names } is not continuous" )
759-
760- if isinstance (names , list ):
761- valuelist = []
762- for name in names :
763- if name in self ._continuous :
764- value = self .getSolutions (name )
765- self ._continuous [name ] = value [0 ][- 1 ]
766- valuelist .append (value [0 ][- 1 ])
767- else :
768- raise ModelicaSystemError (f"{ name } is not continuous" )
769- return valuelist
770-
771- raise ModelicaSystemError ("Unhandled input for getContinous()" )
825+ return self .getContinuousFinal (names = names )
772826
773827 def getParameters (
774828 self ,
@@ -841,15 +895,103 @@ def getInputs(
841895
842896 raise ModelicaSystemError ("Unhandled input for getInputs()" )
843897
898+ def getOutputsInitial (
899+ self ,
900+ names : Optional [str | list [str ]] = None ,
901+ ) -> dict [str , np .float64 ] | list [np .float64 ]:
902+ """
903+ Get (initial) values of output signals.
904+
905+ Args:
906+ names: Either None (default), a string with the output name,
907+ or a list of output name strings.
908+ Returns:
909+ If `names` is None, a dict in the format
910+ {output_name: output_value} is returned.
911+ If `names` is a string, a single element list [output_value] is
912+ returned.
913+ If `names` is a list, a list with one value for each output name
914+ in names is returned: [output1_value, output2_value, ...].
915+
916+ Examples:
917+ >>> mod.getOutputsInitial()
918+ {'out1': '-0.4', 'out2': '1.2'}
919+ >>> mod.getOutputsInitial("out1")
920+ ['-0.4']
921+ >>> mod.getOutputsInitial(["out1","out2"])
922+ ['-0.4', '1.2']
923+ """
924+ if names is None :
925+ return self ._outputs
926+ if isinstance (names , str ):
927+ return [self ._outputs [names ]]
928+ if isinstance (names , list ):
929+ return [self ._outputs [x ] for x in names ]
930+
931+ raise ModelicaSystemError ("Unhandled input for getOutputsInitial()" )
932+
933+ def getOutputsFinal (
934+ self ,
935+ names : Optional [str | list [str ]] = None ,
936+ ) -> dict [str , np .float64 ] | list [np .float64 ]:
937+ """Get (final) values of output signals (at stopTime).
938+
939+ Args:
940+ names: Either None (default), a string with the output name,
941+ or a list of output name strings.
942+ Returns:
943+ If `names` is None, a dict in the format
944+ {output_name: output_value} is returned.
945+ If `names` is a string, a single element list [output_value] is
946+ returned.
947+ If `names` is a list, a list with one value for each output name
948+ in names is returned: [output1_value, output2_value, ...].
949+
950+ Examples:
951+ >>> mod.getOutputsFinal()
952+ {'out1': np.float64(-0.1234), 'out2': np.float64(2.1)}
953+ >>> mod.getOutputsFinal("out1")
954+ [np.float64(-0.1234)]
955+ >>> mod.getOutputsFinal(["out1","out2"])
956+ [np.float64(-0.1234), np.float64(2.1)]
957+ """
958+ if not self ._simulated :
959+ raise ModelicaSystemError ("Please use getOuputsInitial() before the simulation was started!" )
960+
961+ def get_outputs_solution (name_list : list [str ]) -> None :
962+ for name in name_list :
963+ if name in self ._outputs :
964+ value = self .getSolutions (name )
965+ self ._outputs [name ] = np .float64 (value [0 ][- 1 ])
966+ else :
967+ raise ModelicaSystemError (f"{ names } is not a valid output" )
968+
969+ if names is None :
970+ get_outputs_solution (name_list = list (self ._outputs .keys ()))
971+ return self ._outputs
972+
973+ if isinstance (names , str ):
974+ get_outputs_solution (name_list = [names ])
975+ return [self ._outputs [names ]]
976+
977+ if isinstance (names , list ):
978+ get_outputs_solution (name_list = names )
979+ values = []
980+ for name in names :
981+ values .append (self ._outputs [name ])
982+ return values
983+
984+ raise ModelicaSystemError ("Unhandled input for getOutputs()" )
985+
844986 def getOutputs (
845987 self ,
846988 names : Optional [str | list [str ]] = None ,
847- ) -> dict [str , str | numbers . Real ] | list [str | numbers . Real ]:
989+ ) -> dict [str , np . float64 ] | list [np . float64 ]:
848990 """Get values of output signals.
849991
850- If called before simulate(), the initial values are returned as
851- strings. If called after simulate(), the final values (at stopTime)
852- are returned as numpy.float64.
992+ If called before simulate(), the initial values are returned.
993+ If called after simulate(), the final values (at stopTime) are returned.
994+ The return format is always numpy.float64.
853995
854996 Args:
855997 names: Either None (default), a string with the output name,
@@ -880,37 +1022,9 @@ def getOutputs(
8801022 [np.float64(-0.1234), np.float64(2.1)]
8811023 """
8821024 if not self ._simulated :
883- if names is None :
884- return self ._outputs
885- if isinstance (names , str ):
886- return [self ._outputs [names ]]
887- return [self ._outputs [x ] for x in names ]
888-
889- if names is None :
890- for name in self ._outputs :
891- value = self .getSolutions (name )
892- self ._outputs [name ] = value [0 ][- 1 ]
893- return self ._outputs
1025+ return self .getOutputsInitial (names = names )
8941026
895- if isinstance (names , str ):
896- if names in self ._outputs :
897- value = self .getSolutions (names )
898- self ._outputs [names ] = value [0 ][- 1 ]
899- return [self ._outputs [names ]]
900- raise KeyError (names )
901-
902- if isinstance (names , list ):
903- valuelist = []
904- for name in names :
905- if name in self ._outputs :
906- value = self .getSolutions (name )
907- self ._outputs [name ] = value [0 ][- 1 ]
908- valuelist .append (value [0 ][- 1 ])
909- else :
910- raise KeyError (name )
911- return valuelist
912-
913- raise ModelicaSystemError ("Unhandled input for getOutputs()" )
1027+ return self .getOutputsFinal (names = names )
9141028
9151029 def getSimulationOptions (
9161030 self ,
0 commit comments