@@ -711,3 +711,118 @@ def _exec(self, value_input, **kwargs):
711711
712712 """
713713 return self .base .simulate (value_input = value_input , ** kwargs )
714+
715+
716+ class FMUFieldFunction (ot .FieldFunction ):
717+ """
718+ Define a FieldFunction from a FMU file.
719+
720+ Parameters
721+ ----------
722+ path_fmu : str, path to the FMU file.
723+
724+ input_mesh : :class:`openturns.Mesh`, default=None
725+ Time grid of the input variables, has to be included in the start/final time defined in the FMU.
726+
727+ output_mesh : :class:`openturns.Mesh`, default=None
728+ Time grid of the output variables, has to be included in the start/final time defined in the FMU.
729+
730+ inputs_fmu : Sequence of str, default=None
731+ Names of the variable from the fmu to be used as input variables.
732+ By default assigns variables with FMI causality INPUT.
733+
734+ outputs_fmu : Sequence of str, default=None
735+ Names of the variable from the fmu to be used as output variables.
736+ By default assigns variables with FMI causality OUTPUT.
737+
738+ initialization_script : str, default=None
739+ Path to the initialization script.
740+
741+ kind : str, default=None
742+ Either "ME" (model exchange) or "CS" (co-simulation)
743+ Select a kind of FMU if both are available.
744+ Note:
745+ Contrary to pyfmi, the default here is "CS" (co-simulation). The
746+ rationale behind this choice is that co-simulation may be used to
747+ impose a solver not available in pyfmi.
748+
749+ start_time : float, default=None
750+ The FMU simulation start time.
751+ The default behavior is to use the default start time defined the FMU.
752+
753+ final_time : float, default=None
754+ The FMU simulation stop time.
755+ The default behavior is to use the default stop time defined the FMU.
756+
757+ """
758+
759+ def __new__ (
760+ self ,
761+ path_fmu ,
762+ input_mesh = None ,
763+ output_mesh = None ,
764+ inputs_fmu = None ,
765+ outputs_fmu = None ,
766+ kind = None ,
767+ initialization_script = None ,
768+ start_time = None ,
769+ final_time = None ,
770+ ):
771+ lowlevel = OpenTURNSFMUFieldFunction (
772+ path_fmu = path_fmu ,
773+ input_mesh = input_mesh ,
774+ output_mesh = output_mesh ,
775+ inputs_fmu = inputs_fmu ,
776+ outputs_fmu = outputs_fmu ,
777+ kind = kind ,
778+ initialization_script = initialization_script ,
779+ start_time = start_time ,
780+ final_time = final_time ,
781+ )
782+
783+ highlevel = ot .FieldFunction (lowlevel )
784+ # highlevel._model = lowlevel.model
785+ return highlevel
786+
787+
788+ class OpenTURNSFMUFieldFunction (ot .OpenTURNSPythonFieldFunction ):
789+ """Define a FieldFunction from a FMU file."""
790+
791+ def __init__ (
792+ self ,
793+ path_fmu ,
794+ input_mesh = None ,
795+ output_mesh = None ,
796+ inputs_fmu = None ,
797+ outputs_fmu = None ,
798+ initialization_script = None ,
799+ kind = None ,
800+ start_time = None ,
801+ final_time = None ,
802+ ** kwargs
803+ ):
804+ self .base = _FMUBaseFunction (path_fmu , kind = kind ,
805+ inputs_fmu = inputs_fmu , outputs_fmu = outputs_fmu ,
806+ start_time = start_time , final_time = final_time ,
807+ initialization_script = initialization_script ,
808+ field_input = True , input_mesh = input_mesh ,
809+ output_mesh = output_mesh , field_output = True )
810+
811+ super ().__init__ (
812+ self .base .get_input_mesh (), len (self .base .get_inputs_fmu ()),
813+ self .base .get_output_mesh (), len (self .base .get_outputs_fmu ())
814+ )
815+ self .setInputDescription (self .base .get_inputs_fmu ())
816+ self .setOutputDescription (self .base .get_outputs_fmu ())
817+
818+ def _exec (self , value_input , ** kwargs ):
819+ """Simulate the FMU for a given set of input values.
820+
821+ Parameters
822+ ----------
823+ value_input : Vector or array-like with time steps as rows.
824+
825+ See the 'simulate' method for additional keyword arguments.
826+
827+ """
828+ return self .base .simulate (value_input = value_input , ** kwargs )
0 commit comments