]> SALOME platform Git repositories - modules/hydrosolver.git/commitdiff
Salome HOME
Revert "Merge branch 'yan/V8_3_BR' into pre/V8_3_BR"
authorPaul RASCLE <paul.rascle@edf.fr>
Thu, 20 Jul 2017 13:58:07 +0000 (15:58 +0200)
committerPaul RASCLE <paul.rascle@edf.fr>
Thu, 20 Jul 2017 13:58:07 +0000 (15:58 +0200)
This reverts commit 859dac6d961b1b9918f10e057eab185b18ca0a53, reversing
changes made to 133608acdd6339df431d784728ef64615eacb65c.

30 files changed:
CMakeLists.txt
adm_local/cmake_files/CMakeLists.txt
adm_local/cmake_files/FindMascaret.cmake [new file with mode: 0644]
adm_local/cmake_files/FindSalomeMascaret.cmake [new file with mode: 0644]
adm_local/cmake_files/FindSalomeTelemac.cmake
adm_local/cmake_files/FindTelemac.cmake
idl/HYDROSOLVER.idl
src/CMakeLists.txt
src/HYDRO/CMakeLists.txt
src/HYDRO/MASCARET.py [new file with mode: 0644]
src/HYDRO/TELEMAC2D.py [new file with mode: 0644]
src/mascaret_wrapper/CMakeLists.txt [new file with mode: 0644]
src/mascaret_wrapper/Mascaret.cxx [new file with mode: 0644]
src/mascaret_wrapper/Mascaret.hxx [new file with mode: 0644]
src/mascaret_wrapper/mascaret_swig.i [new file with mode: 0644]
src/salome_hydro/CMakeLists.txt
src/salome_hydro/coupling1d2d/CMakeLists.txt [new file with mode: 0644]
src/salome_hydro/coupling1d2d/__init__.py [new file with mode: 0644]
src/salome_hydro/coupling1d2d/eficas/CMakeLists.txt [new file with mode: 0644]
src/salome_hydro/coupling1d2d/eficas/__init__.py [new file with mode: 0644]
src/salome_hydro/coupling1d2d/eficas/appli.py [new file with mode: 0644]
src/salome_hydro/coupling1d2d/eficas/configuration_coupling1d2d.py [new file with mode: 0644]
src/salome_hydro/coupling1d2d/eficas/coupling1d2d_cata.py [new file with mode: 0644]
src/salome_hydro/coupling1d2d/eficas/coupling1d2d_template_schema.xml [new file with mode: 0644]
src/salome_hydro/coupling1d2d/eficas/generator_coupling1d2d.py [new file with mode: 0644]
src/salome_hydro/coupling1d2d/eficas/prefs.py [new file with mode: 0644]
src/salome_hydro/coupling1d2d/eficas/prefs_coupling1d2d.py [new file with mode: 0644]
src/salome_hydro/mascaret/__init__.py
src/salome_hydro/pytel/eficas/pytel_cata.py
src/salome_hydro/study.py

index 9f2147321ede3e7288e1aeda81d25fd7f1279580..c9829ed9c48b9cb081aa22acd3e780889a75c703 100644 (file)
@@ -109,6 +109,7 @@ FIND_PACKAGE(SalomePyQt5 REQUIRED)
 ## HYDROSOLVER specifics
 ##
 
+FIND_PACKAGE(SalomeMascaret REQUIRED)
 FIND_PACKAGE(SalomeTelemac REQUIRED)
 
 # Directories
index 489d80f1eff9df8780208732fc20c7ecefa52f0f..40510843b4b800bbf9c1e4d2b564c989619a25b8 100644 (file)
@@ -21,6 +21,8 @@
 
 # These files are data, module or lib files
 SET(_adm_data
+  FindMascaret.cmake
+  FindSalomeMascaret.cmake
   FindTelemac.cmake
   FindSalomeTelemac.cmake
 )
diff --git a/adm_local/cmake_files/FindMascaret.cmake b/adm_local/cmake_files/FindMascaret.cmake
new file mode 100644 (file)
index 0000000..1602e88
--- /dev/null
@@ -0,0 +1,23 @@
+#  Copyright (C) 2012-2013 EDF
+#
+#  This file is part of SALOME HYDRO module.
+#
+#  SALOME HYDRO module is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation, either version 3 of the License, or
+#  (at your option) any later version.
+#
+#  SALOME HYDRO module is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with SALOME HYDRO module.  If not, see <http://www.gnu.org/licenses/>.
+
+FIND_LIBRARY(MASCARET_LIBRARIES mascaret)
+FIND_PATH(MASCARET_INCLUDE_DIR apimascaret.h)
+
+# Handle the standard arguments of the find_package() command:
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Mascaret REQUIRED_VARS MASCARET_LIBRARIES MASCARET_INCLUDE_DIR)
diff --git a/adm_local/cmake_files/FindSalomeMascaret.cmake b/adm_local/cmake_files/FindSalomeMascaret.cmake
new file mode 100644 (file)
index 0000000..fa7c5ce
--- /dev/null
@@ -0,0 +1,28 @@
+#  Copyright (C) 2012-2013 EDF
+#
+#  This file is part of SALOME HYDRO module.
+#
+#  SALOME HYDRO module is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation, either version 3 of the License, or
+#  (at your option) any later version.
+#
+#  SALOME HYDRO module is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with SALOME HYDRO module.  If not, see <http://www.gnu.org/licenses/>.
+
+# Mascaret detection for Salome
+#
+#  !! Please read the generic detection procedure in SalomeMacros.cmake !!
+#
+SALOME_FIND_PACKAGE_AND_DETECT_CONFLICTS(Mascaret MASCARET_ROOT_DIR 0)
+MARK_AS_ADVANCED(MASCARET_LIBRARIES MASCARET_INCLUDE_DIR)
+
+IF(Mascaret_FOUND OR MASCARET_FOUND)
+  SALOME_ACCUMULATE_HEADERS(MASCARET_INCLUDE_DIR)
+  SALOME_ACCUMULATE_ENVIRONMENT(LD_LIBRARY_PATH ${MASCARET_LIBRARIES})
+ENDIF()
index c1b3b531b20da39d4e7e55dc6655075dba701b17..c16a2cb904ac236b4e5b9c768084ca7f5b7d198c 100644 (file)
@@ -27,7 +27,6 @@ MARK_AS_ADVANCED(TELEMAC_LIBRARY_api
                  TELEMAC_LIBRARY_sisyphe
                  TELEMAC_LIBRARY_special
                  TELEMAC_LIBRARY_telemac2d
-                 TELEMAC_LIBRARY_mascaret
                  TELEMAC_LIBRARY_tomawac
                  TELEMAC_LIBRARY_gretel
                  TELEMAC_LIBRARY_partel
index 4920ae315c15f8b46d86fd2d1165324011819912..6be9348af1ff54c776641300c464564c8c9dffd7 100644 (file)
 #  You should have received a copy of the GNU General Public License
 #  along with SALOME HYDRO module.  If not, see <http://www.gnu.org/licenses/>.
 
-FIND_LIBRARY(TELEMAC_LIBRARY_mascaret mascaret
-             PATHS ${TELEMAC_ROOT_DIR}/builds/salomeHPC/wrap_api/lib)
 FIND_LIBRARY(TELEMAC_LIBRARY_api api
-             PATHS ${TELEMAC_ROOT_DIR}/builds/salomeHPC/wrap_api/lib)
+             PATHS ${TELEMAC_ROOT_DIR}/builds/salome/wrap_api/lib)
 FIND_LIBRARY(TELEMAC_LIBRARY_bief bief
-             PATHS ${TELEMAC_ROOT_DIR}/builds/salomeHPC/wrap_api/lib)
+             PATHS ${TELEMAC_ROOT_DIR}/builds/salome/wrap_api/lib)
 FIND_LIBRARY(TELEMAC_LIBRARY_damocles damocles
-             PATHS ${TELEMAC_ROOT_DIR}/builds/salomeHPC/wrap_api/lib)
+             PATHS ${TELEMAC_ROOT_DIR}/builds/salome/wrap_api/lib)
 FIND_LIBRARY(TELEMAC_LIBRARY_parallel parallel
-             PATHS ${TELEMAC_ROOT_DIR}/builds/salomeHPC/wrap_api/lib)
+             PATHS ${TELEMAC_ROOT_DIR}/builds/salome/wrap_api/lib)
 FIND_LIBRARY(TELEMAC_LIBRARY_sisyphe sisyphe
-             PATHS ${TELEMAC_ROOT_DIR}/builds/salomeHPC/wrap_api/lib)
+             PATHS ${TELEMAC_ROOT_DIR}/builds/salome/wrap_api/lib)
 FIND_LIBRARY(TELEMAC_LIBRARY_special special
-             PATHS ${TELEMAC_ROOT_DIR}/builds/salomeHPC/wrap_api/lib)
+             PATHS ${TELEMAC_ROOT_DIR}/builds/salome/wrap_api/lib)
 FIND_LIBRARY(TELEMAC_LIBRARY_telemac2d telemac2d
-             PATHS ${TELEMAC_ROOT_DIR}/builds/salomeHPC/wrap_api/lib)
+             PATHS ${TELEMAC_ROOT_DIR}/builds/salome/wrap_api/lib)
 FIND_LIBRARY(TELEMAC_LIBRARY_tomawac tomawac
-             PATHS ${TELEMAC_ROOT_DIR}/builds/salomeHPC/wrap_api/lib)
+             PATHS ${TELEMAC_ROOT_DIR}/builds/salome/wrap_api/lib)
 FIND_LIBRARY(TELEMAC_LIBRARY_gretel gretel
-             PATHS ${TELEMAC_ROOT_DIR}/builds/salomeHPC/wrap_api/lib)
+             PATHS ${TELEMAC_ROOT_DIR}/builds/salome/wrap_api/lib)
 FIND_LIBRARY(TELEMAC_LIBRARY_partel partel
-             PATHS ${TELEMAC_ROOT_DIR}/builds/salomeHPC/wrap_api/lib)
+             PATHS ${TELEMAC_ROOT_DIR}/builds/salome/wrap_api/lib)
 FIND_LIBRARY(TELEMAC_LIBRARY_hermes hermes
-             PATHS ${TELEMAC_ROOT_DIR}/builds/salomeHPC/wrap_api/lib)
+             PATHS ${TELEMAC_ROOT_DIR}/builds/salome/wrap_api/lib)
 FIND_PATH(TELEMAC_INCLUDE_DIR interface_telemac2d.mod
-          PATHS ${TELEMAC_ROOT_DIR}/builds/salomeHPC/wrap_api/include)
+          PATHS ${TELEMAC_ROOT_DIR}/builds/salome/wrap_api/include)
 
 # Handle the standard arguments of the find_package() command:
 INCLUDE(FindPackageHandleStandardArgs)
@@ -51,7 +49,6 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(Telemac REQUIRED_VARS TELEMAC_LIBRARY_api
                                                         TELEMAC_LIBRARY_sisyphe
                                                         TELEMAC_LIBRARY_special
                                                         TELEMAC_LIBRARY_telemac2d
-                                                        TELEMAC_LIBRARY_mascaret
                                                         TELEMAC_LIBRARY_tomawac
                                                         TELEMAC_LIBRARY_gretel
                                                         TELEMAC_LIBRARY_partel
index 5abddcf8722dd616116eb359c1fc03ecbc3bfcee..77065ce0c2f581c76ae472db4adb5c40a9567523 100644 (file)
 
 module HYDROSOLVER_ORB
 {
+  struct MascaretFile {
+    string fileName;
+    string fileType;
+  };
+
+  typedef sequence<MascaretFile> MascaretFileList;
+
   typedef sequence<string> stringvec;
   typedef sequence<double> dblevec;
 
+  interface MASCARET: Engines::Superv_Component
+  {
+    /**
+     * @brief Execute a computation of a complete Mascaret case.
+     *
+     * The Compute method realizes the computation with the files specified in input. The
+     * variables outputVars are extracted in output and returned in outputValues.
+     *
+     * @param fileList the list of Mascaret files describing the case to compute
+     * @param ligFile the file containing the initial water line
+     * @param outputVars the list of the output variables to extract
+     * @param outputValues the extracted values
+     */
+    void Compute(in MascaretFileList fileList, in string ligFile,
+                 in stringvec outputVars, out dblevec outputValues)
+      raises (SALOME::SALOME_Exception);
+
+    /**
+     * @brief Initialize the component with the Mascaret case.
+     *
+     * The Init method prepares the component for a series of computation with
+     * the method Exec or ExecStep. It extracts the deterministic data from Salome study and
+     * stores this data along with the lists of input and output variables to
+     * identify them in future calls to Exec.
+     *
+     * @param studyID        the identifier of the study containing the deterministic data
+     * @param detCaseEntry   the identifier of the deterministic case within the study
+     */
+    void Init(in long studyID, in SALOMEDS::ID detCaseEntry)
+      raises (SALOME::SALOME_Exception);
+
+    /**
+     * @brief Execute a computation with a given sample of variables.
+     *
+     * The Exec method realizes the computation with the probabilistic variables
+     * described in paramInput and the deterministic variables set previously with
+     * the Init method. The result is put in paramOutput in the order specified by
+     * paramInput.outputVarList.
+     *
+     * @param paramInput   a structure describing the probabilistic variables and the order
+     *                     of the output variables.
+     * @param paramOutput  a structure containing the result of the computation
+     */
+    void Exec(in SALOME_TYPES::ParametricInput paramInput,
+              out SALOME_TYPES::ParametricOutput paramOutput)
+      raises (SALOME::SALOME_Exception);
+
+    /**
+     * @brief Initialize the border(s) for coupling
+     *
+     * @param borders structure describing the borders
+     */
+    void InitBorders(in Engines::fileBlock borders)
+      raises (SALOME::SALOME_Exception);
+
+    /**
+     * @brief Compute a single time step
+     *
+     * @param timeData  the data describing the time step to execute
+     * @param inputData the state data coming from the coupled code
+     * @param outputData the data to send to the coupled code
+     */
+    void ExecStep(in Engines::fileBlock timeData,
+                  in Engines::fileBlock inputData,
+                  out Engines::fileBlock outputData)
+      raises (SALOME::SALOME_Exception);
+
+    /**
+     * @brief Cleanup everything that was previously set
+     *
+     * The Finalize method is in charge of cleaning everything that what set hitherto.
+     * It may be empty.
+     */
+    void Finalize()
+      raises (SALOME::SALOME_Exception);
+
+    /**
+     * @brief Old coupling method with datastream.
+     */
+    void ExecCoupling(in stringvec inputVarList, in stringvec outputVarList)
+      raises (SALOME::SALOME_Exception);
+
+    /**
+     * @brief Old method to log values from datastream coupling.
+     */
+    void Log(in long studyID, in stringvec inputVarList)
+      raises (SALOME::SALOME_Exception);
+
+  };
+
+  interface TELEMAC2D: Engines::Superv_Component
+  {
+    /**
+     * @brief Execute a computation of a complete Telemac2D case.
+     *
+     * The Compute method realizes the computation of the case specified in input.
+     *
+     * @param studyID   the identifier of the study containing Telemac2D case data
+     * @param caseEntry the identifier of the Telemac2D case within the study
+     */
+    void Compute(in long studyID, in SALOMEDS::ID caseEntry)
+      raises (SALOME::SALOME_Exception);
+
+    /**
+     * @brief Initialize the component with the Telemac2D case.
+     *
+     * The Init method prepares the component for a series of computation with
+     * the method Exec or ExecStep. It extracts the deterministic data from Salome study and
+     * stores this data along with the lists of input and output variables to
+     * identify them in future calls to Exec.
+     *
+     * @param studyID   the identifier of the study containing Telemac2D case data
+     * @param caseEntry the identifier of the Telemac2D case within the study
+     */
+    void Init(in long studyID, in SALOMEDS::ID detCaseEntry)
+      raises (SALOME::SALOME_Exception);
+
+    /**
+     * @brief Execute a computation with a given sample of variables.
+     *
+     * The Exec method realizes the computation with the probabilistic variables
+     * described in paramInput and the deterministic variables set previously with
+     * the Init method. The result is put in paramOutput in the order specified by
+     * paramInput.outputVarList.
+     *
+     * @param paramInput   a structure describing the probabilistic variables and the order
+     *                     of the output variables.
+     * @param paramOutput  a structure containing the result of the computation
+     */
+    void Exec(in SALOME_TYPES::ParametricInput paramInput,
+              out SALOME_TYPES::ParametricOutput paramOutput)
+      raises (SALOME::SALOME_Exception);
+
+    /**
+     * @brief Initialize the border(s) for coupling
+     *
+     * @param borders structure describing the borders
+     */
+    void InitBorders(in Engines::fileBlock borders)
+      raises (SALOME::SALOME_Exception);
+
+    /**
+     * @brief Compute a single time step
+     *
+     * @param timeData  the data describing the time step to execute
+     * @param inputData the state data coming from the coupled code
+     * @param outputData the data to send to the coupled code
+     */
+    void ExecStep(in Engines::fileBlock timeData,
+                  in Engines::fileBlock inputData,
+                  out Engines::fileBlock outputData)
+      raises (SALOME::SALOME_Exception);
+
+    /**
+     * @brief Cleanup everything that was previously set
+     *
+     * The Finalize method is in charge of cleaning everything that what set hitherto.
+     * It may be empty.
+     */
+    void Finalize()
+      raises (SALOME::SALOME_Exception);
+
+  };
+
   interface HYDROSOLVER: Engines::EngineComponent, SALOMEDS::Driver
   {
 
index 7cbaee0e9dd882f98e4f2c9a22385fd359f38dc4..ef4e69ceff6119cfac57af90147f6fc738d26f2e 100644 (file)
@@ -19,3 +19,4 @@ ADD_SUBDIRECTORY(HYDRO)
 ADD_SUBDIRECTORY(HYDROGUI)
 ADD_SUBDIRECTORY(HYDROTools)
 ADD_SUBDIRECTORY(salome_hydro)
+ADD_SUBDIRECTORY(mascaret_wrapper)
index 1cc5dccd3855982f858577fec697ed3fe9bd3142..e818e784af3a6c39cde41735cf4908097fea19a8 100644 (file)
@@ -20,6 +20,8 @@
 # scripts / static
 SET(_bin_SCRIPTS
   HYDROSOLVER.py
+  MASCARET.py
+  TELEMAC2D.py
 )
 
 # --- rules ---
diff --git a/src/HYDRO/MASCARET.py b/src/HYDRO/MASCARET.py
new file mode 100644 (file)
index 0000000..bebfccc
--- /dev/null
@@ -0,0 +1,412 @@
+#  Copyright (C) 2012-2013 EDF
+#
+#  This file is part of SALOME HYDRO module.
+#
+#  SALOME HYDRO module is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation, either version 3 of the License, or
+#  (at your option) any later version.
+#
+#  SALOME HYDRO module is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with SALOME HYDRO module.  If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import logging
+import threading
+import inspect
+import traceback
+import cPickle
+
+import salome
+import HYDROSOLVER_ORB__POA
+import SALOME_ComponentPy
+import SALOME
+import calcium
+import dsccalcium
+
+from salome.kernel.logger import Logger
+from salome.kernel import termcolor
+logger = Logger("MASCARET", color = termcolor.BLUE)
+logger.setLevel(logging.DEBUG)
+
+from salome.kernel.parametric.compo_utils import \
+    create_input_dict, create_normal_parametric_output, create_error_parametric_output
+
+from salome.hydro.mascaret import Mascaret, MascaretFile
+from salome.hydro.study import HydroStudyEditor
+
+def mascaretFileListCorbaToCpp(file_list_corba):
+    file_list_cpp = []
+    for file_corba in file_list_corba:
+        file_cpp = MascaretFile()
+        file_cpp.fileName = file_corba.fileName
+        file_cpp.fileType = file_corba.fileType
+        file_list_cpp.append(file_cpp)
+    return file_list_cpp
+
+
+class MascaretVariable:
+
+    def __init__(self, inst, varstr):
+        self.inst = inst
+        par1 = varstr.find("(")
+        par2 = varstr.find(")")
+        self.varname = varstr[:par1]
+        ranges_str = varstr[par1+1:par2].split(",")
+        if len(ranges_str) != 3:
+            raise Exception('Invalid variable "%s"' % varstr)
+        self.ranges = []
+        self.valid_for_output = True
+        for currange in ranges_str:
+            limits = currange.split("-")
+            if len(limits) != 1 and len(limits) != 2:
+                raise Exception('Invalid variable "%s"' % varstr)
+            limit_inf = int(limits[0])
+            if len(limits) == 2:
+                limit_sup = int(limits[1])
+            else:
+                limit_sup = limit_inf
+            newrange = range(limit_inf, limit_sup + 1)
+            if len(newrange) > 1:
+                self.valid_for_output = False
+            self.ranges.append(newrange)
+
+    def get_value(self):
+        if not self.valid_for_output:
+            raise Exception('Variable "%s" is not valid as an output variable' % self.varname)
+        logger.debug("Getting value: getDouble(%s, %d, %d, %d)" %
+                     (self.varname, self.ranges[0][0], self.ranges[1][0], self.ranges[2][0]))
+        return self.inst.getDouble(self.varname, self.ranges[0][0], self.ranges[1][0], self.ranges[2][0])
+
+    def set_value(self, value):
+        for x in self.ranges[0]:
+            for y in self.ranges[1]:
+                for z in self.ranges[2]:
+                    logger.debug("Setting value: setDouble(%s, %d, %d, %d, %f)" %
+                                 (self.varname, x, y, z, value))
+                    self.inst.setDouble(self.varname, x, y, z, value)
+
+################################################
+
+class MASCARET(HYDROSOLVER_ORB__POA.MASCARET, dsccalcium.PyDSCComponent):
+    
+    lock = threading.Lock()
+    
+    """
+        Pour etre un composant SALOME cette classe Python
+        doit avoir le nom du composant et heriter de la
+        classe HYDRO_ORB__POA.MASCARET issue de la compilation de l'idl
+        par omniidl et de la classe SALOME_ComponentPy_i
+        qui porte les services generaux d'un composant SALOME
+    """
+    def __init__ ( self, orb, poa, contID, containerName, instanceName, 
+                   interfaceName ):
+        logger.info("__init__: " + containerName + ' ; ' + instanceName)
+        dsccalcium.PyDSCComponent.__init__(self, orb, poa,contID,
+                                           containerName,instanceName,interfaceName)
+        self.file_list = None
+        self.lig_file = None
+        self.inst = None
+        self.last_start_time = None
+        self.state_id = None
+        self.initial_state_id = None
+        self.input_var_map = None
+        self.output_var_map = None
+
+    def init_service(self,service):
+        if service == "ExecCoupling":
+            # initialization CALCIUM ports IN
+            calcium.create_calcium_port(self.proxy, "inputValues", "CALCIUM_double", "IN", "T")
+            # initialization CALCIUM ports OUT
+            calcium.create_calcium_port(self.proxy, "outputValues", "CALCIUM_double", "OUT", "T")
+        elif service == "Log":
+            # initialization CALCIUM ports IN
+            calcium.create_calcium_port(self.proxy, "inputValues", "CALCIUM_double", "IN", "T")
+        return service in ("Compute", "Init", "Exec", "Finalize", "ExecCoupling", "Log")
+
+    def _raiseSalomeError(self):
+        message = "Error in component %s running in container %s." % (self._instanceName, self._containerName)
+        logger.exception(message)
+        message += " " + traceback.format_exc()
+        exc = SALOME.ExceptionStruct(SALOME.INTERNAL_ERROR, message,
+                                     inspect.stack()[1][1], inspect.stack()[1][2])
+        raise SALOME.SALOME_Exception(exc)
+    
+    def Compute(self, fileList, ligFile, outputVars):
+        try:
+            self.beginService("MASCARET.Compute")
+      
+            # Initialize
+            inst = Mascaret()
+            inst.importModel(mascaretFileListCorbaToCpp(fileList))
+            inst.initState(ligFile)
+            
+            # Compute
+            inst.compute()
+            
+            # Get the output values
+            output_values = [MascaretVariable(inst, var).get_value() for var in outputVars]
+
+            self.endService("MASCARET.Compute")
+            return output_values
+        except:
+            self._raiseSalomeError()
+
+    def Init(self, studyId, detCaseEntry):
+        try:
+            self.beginService("MASCARET.Init")
+            MASCARET.lock.acquire()
+            salome.salome_init()
+            MASCARET.lock.release()
+            
+            ed = HydroStudyEditor(studyId)
+            sobj = ed.editor.study.FindObjectID(detCaseEntry)
+            (file_list_corba, self.lig_file, input_vars, output_vars) = ed.get_mascaret_params_from_case(sobj)
+
+            self.file_list = mascaretFileListCorbaToCpp(file_list_corba)
+
+            # Initialize Mascaret instance
+            self.inst = Mascaret()
+            #self.inst.setPrinting(True)
+            self.inst.importModel(self.file_list)
+            self.inst.initState(self.lig_file)
+
+            # Create variable mappings
+            self.input_var_map = {}
+            for input_var in input_vars:
+                name = input_var["NOM"]
+                if not self.input_var_map.has_key(name):
+                    self.input_var_map[name] = []
+                self.input_var_map[name] += [MascaretVariable(self.inst, input_var["VARIABLE_MASCARET"])]
+
+            self.output_var_map = {}
+            for output_var in output_vars:
+                masc_output_var = MascaretVariable(self.inst, output_var["VARIABLE_MASCARET"])
+                self.output_var_map[output_var["NOM"]] = masc_output_var
+
+            self.endService("MASCARET.Init")
+        except:
+            self._raiseSalomeError()
+
+    def Exec(self, paramInput):
+        try:
+            self.beginService("MASCARET.Exec")
+
+            if self.initial_state_id is not None:
+                self.inst.restoreState(self.initial_state_id)
+            self.initial_state_id = self.inst.saveState()
+
+            logger.debug("inputVarList: %s" % paramInput.inputVarList)
+            logger.debug("outputVarList: %s" % paramInput.outputVarList)
+            logger.debug("inputValues: %s" % paramInput.inputValues)
+
+            input_dict = create_input_dict({}, paramInput)
+            logger.debug("input_dict = %s" % input_dict)
+            
+            for (key, value) in input_dict.iteritems():
+                for masc_var in self.input_var_map[key]:
+                    masc_var.set_value(value)
+
+            # Compute
+            self.inst.compute()
+
+            # Get the output values
+            output_dict = {}
+            for output_var in paramInput.outputVarList:
+                output_dict[output_var] = self.output_var_map[output_var].get_value()
+
+            param_output = create_normal_parametric_output(output_dict, paramInput)
+            logger.debug("outputValues: %s" % param_output.outputValues)
+            self.endService("MASCARET.Exec")
+            return param_output
+        except:
+            self._raiseSalomeError()
+
+    def InitBorders(self, bordersPickled):
+        """
+        This method initializes the border(s) for coupling
+        """
+        try:
+            self.beginService("MASCARET.InitBorders")
+            borders = cPickle.loads(bordersPickled)
+            self.borders = {}
+            for border in borders:
+                if border["model1"] is not None and border["model1"]["code"] == "MASCARET":
+                    self.borders[border["name"]] = border["model1"]
+                elif border["model2"] is not None and border["model2"]["code"] == "MASCARET":
+                    self.borders[border["name"]] = border["model2"]
+            self.endService("MASCARET.InitBorders")
+        except:
+            self._raiseSalomeError()
+
+    def setData(self, inputData):
+        if inputData is not None:
+            for (name, desc) in self.borders.iteritems():
+              if name in inputData:
+                if desc["position"] == "upstream":
+                    if self.froude[name] < 1.0:
+                        Z = inputData[name]["Z"]
+                        self.inst.setDouble("Modele.Lois.Cote", desc["loi_id"], 1, 0, Z)
+                        self.inst.setDouble("Modele.Lois.Cote", desc["loi_id"], 2, 0, Z)
+                else:
+                    Q = inputData[name]["Q"]
+                    self.inst.setDouble("Modele.Lois.Debit", desc["loi_id"], 1, 0, Q)
+                    self.inst.setDouble("Modele.Lois.Debit", desc["loi_id"], 2, 0, Q)
+                    if self.froude[name] >= 1.0:
+                        Z = inputData[name]["Z"]
+                        self.inst.setDouble("Modele.Lois.Cote", desc["loi_id"], 1, 0, Z)
+                        self.inst.setDouble("Modele.Lois.Cote", desc["loi_id"], 2, 0, Z)
+
+    def ExecStep(self, timeDataPickled, inputDataPickled):
+        """
+        This method computes a single time step
+        """
+        try:
+            self.beginService("MASCARET.ExecStep")
+            timeData = cPickle.loads(timeDataPickled)
+            inputData = cPickle.loads(inputDataPickled)
+            
+            if self.last_start_time is not None:
+                self.inst.restoreState(self.state_id)
+                # If it's a new time step, we perform a last iteration with
+                # the last time step to restore the state properly
+                if self.last_start_time != timeData["start_time"]:
+                    self.setData(inputData)
+                    self.inst.compute(self.last_start_time, timeData["start_time"], timeData["time_step"])
+
+            self.last_start_time = timeData["start_time"]
+            self.state_id = self.inst.saveState()
+
+            self.setData(inputData)
+
+            # Computation            
+            self.inst.compute(timeData["start_time"], timeData["end_time"], timeData["time_step"])
+
+            # Get the output values
+            outputData = {}
+            self.froude = {}
+            for (name, desc) in self.borders.iteritems():
+                Z = self.inst.getDouble("Etat.Z", desc["section_id"], 0, 0)
+                Q1 = self.inst.getDouble("Etat.Q1", desc["section_id"], 0, 0)
+                S1 = self.inst.getDouble("Etat.S1", desc["section_id"], 0, 0)
+                V = Q1/S1
+                #V = self.inst.getDouble("Etat.V1", desc["section_id"], 0, 0)
+                Q = self.inst.getDouble("Etat.Q", desc["section_id"], 0, 0)
+                Froude = self.inst.getDouble("Etat.Froude", desc["section_id"], 0, 0)
+                outputData[name] = {"Z": Z, "V": V, "Froude": Froude, "Q": Q}
+                self.froude[name] = Froude
+            outputDataPickled = cPickle.dumps(outputData, -1)
+            
+            self.endService("MASCARET.ExecStep")
+            return outputDataPickled
+        except:
+            self._raiseSalomeError()
+
+    def Finalize(self):
+        try:
+            self.beginService("MASCARET.Finalize")
+            self.file_list = None
+            self.lig_file = None
+            self.inst = None
+            self.last_start_time = None
+            self.state_id = None
+            self.input_var_map = None
+            self.output_var_map = None
+            self.endService("MASCARET.Finalize")
+        except:
+            self._raiseSalomeError()
+
+    def ExecCoupling(self, inputVarList, outputVarList):
+        try:
+            self.beginService("MASCARET.ExecCoupling")
+            component = self.proxy
+
+            # Get time data from model
+            start_time = self.inst.getDouble("Modele.TempsInitial", 0, 0, 0)
+            end_time = self.inst.getDouble("Modele.TempsMaximum", 0, 0, 0)
+            time_step = self.inst.getDouble("Modele.DT", 0, 0, 0)
+            
+            # Time loop
+            current_time = start_time
+            calcium.cp_cd(component)
+            while current_time < end_time:
+                # Send data
+                if len(outputVarList) > 0:
+                    output_values = []
+                    for output_var in outputVarList:
+                        masc_var = self.output_var_map[output_var]
+                        value = self.inst.getDouble(*split_var(masc_var))
+                        output_values += [value]
+                    info = calcium.cp_edb(component, calcium.CP_TEMPS, current_time, 0, "outputValues",
+                                          len(outputVarList), output_values)
+                    logger.debug("Instance %s sent %s" % (self._instanceName, zip(outputVarList, output_values)))
+                    if info != 0:
+                        raise Exception("Error in calcium.cp_edb, code = %d" % info)
+    
+                # Receive data
+                input_values = calcium.doubleArray(len(inputVarList))
+                if len(inputVarList) > 0:
+                    (info, t, ii, n) = calcium.cp_ldb(component, calcium.CP_TEMPS,
+                                                      current_time, current_time + 1e-6,
+                                                      0, "inputValues", len(inputVarList), input_values)
+                    if info != 0:
+                        raise Exception("Error in calcium.cp_ldb, code = %d" % info)
+                    if n != len(inputVarList):
+                        raise Exception("Wrong number of input values: %d instead of %d" % (n, len(inputVarList)))
+                    logger.debug("Instance %s received %s" % (self._instanceName, zip(inputVarList, input_values)))
+
+                # Update model with received data
+                for (var, value) in zip(inputVarList, input_values):
+                    for masc_var in self.input_var_map[var]:
+                        self.inst.setDouble(*(split_var(masc_var) + (value,)))
+
+                # Compute
+                end_step_time = current_time + time_step
+                self.inst.compute(current_time, end_step_time, time_step)
+                current_time = end_step_time
+
+            calcium.cp_fin(component, calcium.CP_ARRET)
+            self.endService("MASCARET.ExecCoupling")
+        except:
+            self._raiseSalomeError()
+
+    def Log(self, studyId, inputVarList):
+        """
+        This method is not used anymore. It was used in the context of the calcium coupling test.
+        """
+        try:
+            self.beginService("MASCARET.Log")
+            if len(inputVarList) > 0:
+                log = {}
+                for var in inputVarList:
+                    log[var] = ""
+                component = self.proxy
+                finished = False
+                calcium.cp_cd(component)
+                while not finished:
+                    # Receive data
+                    input_values = calcium.doubleArray(len(inputVarList))
+                    (info, t, ii, n) = calcium.cp_ldb(component, calcium.CP_SEQUENTIEL,
+                                                      0, 0, 0, "inputValues", len(inputVarList), input_values)
+                    if info == 33:
+                        finished = True
+                    elif info != 0:
+                        raise Exception("Error in calcium.cp_ldb, code = %d" % info)
+                    elif n != len(inputVarList):
+                        raise Exception("Wrong number of input values: %d instead of %d" % (n, len(inputVarList)))
+                    else:
+                        logger.debug("Instance %s received %s" % (self._instanceName, zip(inputVarList, input_values)))
+                        for (var, value) in zip(inputVarList, input_values):
+                            log[var] += "t = %f, %s = %f\n" % (t, var, value)                        
+                calcium.cp_fin(component, calcium.CP_ARRET)
+                ed = HydroStudyEditor(studyId)
+                for var in inputVarList:
+                    ed.add_coupling_log(var, log[var])
+            self.endService("MASCARET.Log")
+        except:
+            self._raiseSalomeError()
diff --git a/src/HYDRO/TELEMAC2D.py b/src/HYDRO/TELEMAC2D.py
new file mode 100644 (file)
index 0000000..85f1f01
--- /dev/null
@@ -0,0 +1,579 @@
+#  Copyright (C) 2012-2013 EDF
+#
+#  This file is part of SALOME HYDRO module.
+#
+#  SALOME HYDRO module is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation, either version 3 of the License, or
+#  (at your option) any later version.
+#
+#  SALOME HYDRO module is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with SALOME HYDRO module.  If not, see <http://www.gnu.org/licenses/>.
+
+import sys
+import os
+import logging
+import threading
+import inspect
+import traceback
+import cPickle
+import math
+import types
+
+import salome
+import HYDROSOLVER_ORB__POA
+import SALOME_ComponentPy
+import SALOME
+import calcium
+import dsccalcium
+
+from salome.kernel.logger import Logger
+from salome.kernel import termcolor
+logger = Logger("TELEMAC2D", color = termcolor.BLUE)
+logger.setLevel(logging.DEBUG)
+
+from salome.kernel.parametric.compo_utils import \
+    create_input_dict, create_normal_parametric_output, create_error_parametric_output
+
+from TelApy.api.t2d import Telemac2D
+from TelApy.tools.polygon import get_list_points_in_polygon
+from salome.hydro.study import jdc_to_dict, get_jdc_dict_var_as_tuple, HydroStudyEditor
+
+################################################
+
+class TELEMAC2D(HYDROSOLVER_ORB__POA.TELEMAC2D, dsccalcium.PyDSCComponent):
+
+    lock = threading.Lock()
+
+    """
+        Pour etre un composant SALOME cette classe Python
+        doit avoir le nom du composant et heriter de la
+        classe HYDRO_ORB__POA.MASCARET issue de la compilation de l'idl
+        par omniidl et de la classe SALOME_ComponentPy_i
+        qui porte les services generaux d'un composant SALOME
+    """
+    def __init__ ( self, orb, poa, contID, containerName, instanceName,
+                   interfaceName ):
+        logger.info("__init__: " + containerName + ' ; ' + instanceName)
+        dsccalcium.PyDSCComponent.__init__(self, orb, poa,contID,
+                                           containerName,instanceName,interfaceName)
+        self.t2d = None
+        self.last_start_time = None
+        self.saved_state = None
+
+    def init_service(self,service):
+        return service in ("Compute",)
+
+    def _raiseSalomeError(self):
+        message = "Error in component %s running in container %s." % (self._instanceName, self._containerName)
+        logger.exception(message)
+        message += " " + traceback.format_exc()
+        exc = SALOME.ExceptionStruct(SALOME.INTERNAL_ERROR, message,
+                                     inspect.stack()[1][1], inspect.stack()[1][2])
+        raise SALOME.SALOME_Exception(exc)
+
+    def Init(self, studyId, detCaseEntry):
+      try:
+        self.beginService("TELEMAC2D.Init")
+        self.jdc_dict = self.get_jdc_dict_from_case(studyId, detCaseEntry)
+
+        # Ugly hack to check if we are in OpenTURNS context or Mascaret coupling context
+        if "VARIABLE_ENTREE" in self.jdc_dict:
+          # Create variable mappings for OpenTURNS
+          self.input_var_map = {}
+          for input_var in get_jdc_dict_var_as_tuple(self.jdc_dict, "VARIABLE_ENTREE"):
+            name = input_var["NOM"]
+            if not self.input_var_map.has_key(name):
+              self.input_var_map[name] = []
+            self.input_var_map[name] += [Telemac2DInputVariable(input_var["VARIABLE_MODELE_T2D"])]
+
+          self.output_var_map = {}
+          for output_var in get_jdc_dict_var_as_tuple(self.jdc_dict, "VARIABLE_SORTIE"):
+            t2d_output_var = Telemac2DOutputVariable(output_var["VARIABLE_T2D"])
+            self.output_var_map[output_var["NOM"]] = t2d_output_var
+
+        else:
+          # Initialize before launching the coupling with Mascaret
+          self.init_t2d_from_jdc_dict(self.jdc_dict)
+
+        self.endService("TELEMAC2D.Init")
+      except:
+        self._raiseSalomeError()
+
+    def get_jdc_dict_from_case(self, study_id, case_entry):
+      TELEMAC2D.lock.acquire()
+      salome.salome_init()
+      TELEMAC2D.lock.release()
+
+      # Get filenames from the case in Salome study
+      ed = HydroStudyEditor(study_id)
+      sobj = ed.editor.study.FindObjectID(case_entry)
+      jdcpath = sobj.GetComment()
+      with open(jdcpath) as jdcfile:
+        jdc = jdcfile.read()
+      return jdc_to_dict(jdc, ["TELEMAC2D", "_F"])
+
+    def init_t2d_from_jdc_dict(self, jdc_dict):
+      steering_filename = jdc_dict["FICHIER_CAS"]
+      user_fortran = jdc_dict.get("FICHIER_FORTRAN_UTILISATEUR")
+      dico_filename = jdc_dict.get("FICHIER_DICO")
+      geo_filename = jdc_dict.get("FICHIER_GEOMETRIE")
+      bc_filename = jdc_dict.get("FICHIER_CONDITIONS_LIMITES")
+      result_filename = jdc_dict.get("RESULTAT")
+
+      logger.debug("Initializing Telemac2D API")
+      self.t2d = Telemac2D(user_fortran)
+      logger.debug("Telemac2D API initialization OK")
+      os.chdir(os.path.dirname(steering_filename))
+      self.t2d.run_read_case_t2d(steering_filename, dico_filename)
+      if bc_filename is not None:
+        self.t2d.set_string('MODEL.BCFILE', bc_filename)
+      if geo_filename is not None:
+        self.t2d.set_string('MODEL.GEOMETRYFILE', geo_filename)
+      if result_filename is not None:
+        self.t2d.set_string('MODEL.RESULTFILE', result_filename)
+      ierr = self.t2d.api.run_allocation_t2d(self.t2d.id)
+      if ierr != 0:
+        raise Exception('Error in run_allocation_t2d:', ierr)
+      ierr = self.t2d.api.run_init_t2d(self.t2d.id)
+      if ierr != 0:
+        raise Exception('Error in run_init_t2d:', ierr)
+
+    def Exec(self, paramInput):
+      try:
+        self.beginService("TELEMAC2D.Exec")
+
+        # Save / restore state
+        # Not used yet because time can not be reset
+        #if self.saved_state is None:
+        #  self.saved_state = self.t2d.save_state()
+        #else:
+        #  self.t2d.restore_state(self.saved_state)
+
+        # Get id and execution mode
+        id = ""
+        exec_mode = ""
+        for parameter in paramInput.specificParameters:
+            if parameter.name == "id":
+                id = parameter.value
+            if parameter.name == "executionMode":
+                exec_mode = parameter.value
+        logger.debug("ID: %s" % id)
+        logger.debug("Execution mode: %s" % exec_mode)
+
+        # Append id to result file name
+        result_filename = self.jdc_dict.get("RESULTAT") or "r2d.slf"
+        (result_filename_wo_ext, ext) = os.path.splitext(result_filename)
+        current_jdc_dict = self.jdc_dict.copy()
+        current_jdc_dict["RESULTAT"] = "%s_%s%s" % (result_filename_wo_ext, id, ext)
+
+        # Reload model
+        self.init_t2d_from_jdc_dict(current_jdc_dict)
+
+        # Set the input values
+        logger.debug("inputVarList: %s" % paramInput.inputVarList)
+        logger.debug("outputVarList: %s" % paramInput.outputVarList)
+        logger.debug("inputValues: %s" % paramInput.inputValues)
+
+        input_dict = create_input_dict({}, paramInput)
+        logger.debug("input_dict = %s" % input_dict)
+
+        for (key, value) in input_dict.iteritems():
+          for t2d_var in self.input_var_map[key]:
+            t2d_var.set_value(self.t2d, value)
+
+        # Compute
+        self.t2d.run_all_timesteps()
+
+        # Get the output values
+        output_dict = {}
+        for output_var in paramInput.outputVarList:
+          output_dict[output_var] = self.output_var_map[output_var].get_value(self.t2d)
+
+        param_output = create_normal_parametric_output(output_dict, paramInput)
+        logger.debug("outputValues: %s" % param_output.outputValues)
+
+        # Finalize T2D
+        self.t2d.finalize()
+        self.t2d = None
+
+        self.endService("TELEMAC2D.Exec")
+        return param_output
+      except:
+        self._raiseSalomeError()
+
+    def InitBorders(self, bordersPickled):
+        """
+        This method initializes the border(s) for coupling
+        """
+        try:
+            self.beginService("TELEMAC2D.InitBorders")
+            borders = cPickle.loads(bordersPickled)
+            self.borders = {}
+            for border in borders:
+                if border["model1"] is not None and border["model1"]["code"] == "TELEMAC2D":
+                    self.borders[border["name"]] = border["model1"]
+                elif border["model2"] is not None and border["model2"]["code"] == "TELEMAC2D":
+                    self.borders[border["name"]] = border["model2"]
+            self.endService("TELEMAC2D.InitBorders")
+        except:
+            self._raiseSalomeError()
+
+    def ExecStep(self, timeDataPickled, inputDataPickled):
+        """
+        This method computes a single time step
+        """
+        try:
+            self.beginService("TELEMAC2D.ExecStep")
+            timeData = cPickle.loads(timeDataPickled)
+            inputData = cPickle.loads(inputDataPickled)
+
+            if timeData["start_time"] == self.last_start_time:
+                # Convergence iteration, restore saved state
+                self.t2d.restore_state(self.saved_state)
+            else:
+                # First iteration of a time step, save state
+                self.saved_state = self.t2d.save_state(self.saved_state)
+
+            self.last_start_time = timeData["start_time"]
+
+            if inputData is not None:
+              for (name, desc) in self.borders.iteritems():
+                if name in inputData:
+                  z = None
+                  v = None
+                  q = None
+                  if desc["position"] == "upstream":
+                    if inputData[name]["Froude"] < 1.0: # Fluvial
+                      z = inputData[name]["Z"]
+                  else:
+                    v = inputData[name]["V"]
+                    q = inputData[name]["Q"]
+                    if inputData[name]["Froude"] > 1.0: # Torrential
+                      z = inputData[name]["Z"]
+                  self.set_z_on_border(desc, z)
+                  #self.set_v_on_border(desc, v)
+                  self.set_q_on_border(desc, q)
+
+            # Compute
+            # TODO: Use time values from coupling
+            ierr = self.t2d.api.run_timestep_t2d(self.t2d.id)
+            if ierr != 0:
+              raise Exception('Error in run_timestep_t2d:', ierr)
+
+            # Get the output values
+            outputData = {}
+            for (name, desc) in self.borders.iteritems():
+              outputData[name] = {}
+              (outputData[name]["Z"], idx) = self.get_z_on_border(desc)
+              if idx is None:
+                outputData[name]["V"] = 0.0
+              else:
+                (outputData[name]["V"], froude) = self.get_v_at_point(idx)
+              outputData[name]["Q"] = self.get_q_on_border(desc)
+            outputDataPickled = cPickle.dumps(outputData, -1)
+
+            self.endService("TELEMAC2D.ExecStep")
+            return outputDataPickled
+        except:
+            self._raiseSalomeError()
+
+    def get_z_on_border(self, border):
+      """
+      Find the water elevation (i.e. water height + bottom elevation) on a border.
+      Return a tuple (water_elevation, index_of_model_point_with_min_water_elevation).
+      If we use method 2 (compute mean water elevation), index is set to None.
+      """
+      # Method 1: Get point with minimum elevation
+      """
+      idx = -1
+      bor_idx = -1
+      z_min = sys.float_info.max
+      (first, after_last) = border["points_id"]
+      k = first
+      while k != after_last:
+        nbor_k = self.t2d.get_integer('MODEL.NBOR', k)
+        h_k = self.t2d.get_double('MODEL.WATERDEPTH', nbor_k)
+        z_bottom_k = self.t2d.get_double('MODEL.BOTTOMELEVATION', nbor_k)
+        z_k = h_k + z_bottom_k
+        logger.debug("extract z for border point %d, h:%f, zf:%f, z:%f" % (k, h_k, z_bottom_k, z_k))
+        if (z_k < z_min):
+          z_min = z_k
+          bor_idx = k
+          idx = nbor_k
+        k = self.t2d.get_integer('MODEL.KP1BOR', k)
+      logger.debug("min z for border %d with method 1 is %f at border point %d (model point %d)" %
+                   (border["border_id"], z_min, bor_idx, idx))
+      z = z_min
+      """
+      # Method 2: Compute mean elevation, ignoring dry zones (method from PALM coupling)
+      z_mean = sys.float_info.max
+      for i in range(10):
+        h_tot = 0.0
+        l_tot = 0.0
+        zf_min = sys.float_info.max
+        (first, after_last) = border["points_id"]
+        k = first
+        while k != after_last:
+          knext = self.t2d.get_integer('MODEL.KP1BOR', k)
+          nbor_k = self.t2d.get_integer('MODEL.NBOR', k)
+          nbor_knext = self.t2d.get_integer('MODEL.NBOR', knext)
+          zf1 = self.t2d.get_double('MODEL.BOTTOMELEVATION', nbor_k)
+          zf2 = self.t2d.get_double('MODEL.BOTTOMELEVATION', nbor_knext)
+          zf_min = min(zf_min, zf1)
+          h1 = self.t2d.get_double('MODEL.WATERDEPTH', nbor_k)
+          h2 = self.t2d.get_double('MODEL.WATERDEPTH', nbor_knext)
+          z1 = h1 + zf1
+          z2 = h2 + zf2
+          x1 = self.t2d.get_double('MODEL.X', nbor_k)
+          x2 = self.t2d.get_double('MODEL.X', nbor_knext)
+          y1 = self.t2d.get_double('MODEL.Y', nbor_k)
+          y2 = self.t2d.get_double('MODEL.Y', nbor_knext)
+          l = math.sqrt((x1-x2)**2 + (y1-y2)**2)
+          if zf1 <= z_mean and zf2 <= z_mean:
+            h_tot += (z1+z2) * 0.5 * l
+            l_tot += l
+          k = knext
+
+        new_z_mean = h_tot / l_tot
+        delta = abs(z_mean - new_z_mean)
+        z_mean = new_z_mean
+        if delta < 1.0e-6:
+          break
+
+      logger.debug("mean z for border %d with method 2 is %f" % (border["border_id"], z_mean))
+      z = z_mean
+      idx = None
+
+      return (z, idx)
+
+    def get_v_at_point(self, idx):
+      """
+      Find the water velocity at the model point idx.
+      Return a tuple (velocity, froude number)
+      """
+      u_i = self.t2d.get_double('MODEL.VELOCITYU', idx)
+      v_i = self.t2d.get_double('MODEL.VELOCITYV', idx)
+      h_i = self.t2d.get_double('MODEL.WATERDEPTH', idx)
+      v = math.sqrt(u_i**2 + v_i**2)
+      ##### TODO: Remove that and find the real error
+      if h_i <= 0.0:
+        print 'Error: water depth is negative or zero on point', idx
+        #raise Exception('Null water depth value')
+        h_i = 0.01
+      froude = v / (h_i * 9.81)
+      return (v, froude)
+
+    def get_q_on_border(self, border):
+      """
+      Find the flow on a border.
+      The returned value is positive if the flow goes in the natural direction
+      according to the borders description (from upstream to downstream).
+      """
+      # Method 1: Integrate the flow on the whole border
+      """
+      q = 0.0
+      (first, after_last) = border["points_id"]
+      k = first
+      while k != after_last:
+        knext = self.t2d.get_integer('MODEL.KP1BOR', k)
+        nbor_k = self.t2d.get_integer('MODEL.NBOR', k)
+        nbor_knext = self.t2d.get_integer('MODEL.NBOR', knext)
+        h_i = self.t2d.get_double('MODEL.WATERDEPTH', nbor_k)
+        h_i2 = self.t2d.get_double('MODEL.WATERDEPTH', nbor_knext)
+        h2d1 = 0.5 * (h_i + h_i2)
+        if (h2d1 > 0.0):
+          u_i = self.t2d.get_double('MODEL.VELOCITYU', nbor_k)
+          u_i2 = self.t2d.get_double('MODEL.VELOCITYU', nbor_knext)
+          v_i = self.t2d.get_double('MODEL.VELOCITYV', nbor_k)
+          v_i2 = self.t2d.get_double('MODEL.VELOCITYV', nbor_knext)
+          v2d1 = 0.5 * (math.sqrt(u_i**2+v_i**2) + math.sqrt(u_i2**2+v_i2**2))
+          x2d1 = self.t2d.get_double('MODEL.X', nbor_k)
+          x2d2 = self.t2d.get_double('MODEL.X', nbor_knext)
+          y2d1 = self.t2d.get_double('MODEL.Y', nbor_k)
+          y2d2 = self.t2d.get_double('MODEL.Y', nbor_knext)
+          q += v2d1 * h2d1 * math.sqrt((x2d1-x2d2)**2 + (y2d1-y2d2)**2)
+        k = knext
+      logger.debug("flow for border %d with method 1 is %f" % (border["border_id"], q))
+
+      # Method 2: Get the flow from Telemac model
+      q = self.t2d.get_double('MODEL.FLUX_BOUNDARIES', border["border_id"])
+      if border["position"] == "downstream":
+        q = -q
+      logger.debug("flow for border %d with method 2 is %f" % (border["border_id"], q))
+      """
+
+      # Method 3: Method from PALM coupling
+      q = 0.0
+      (first, after_last) = border["points_id"]
+      k = first
+      while k != after_last:
+        knext = self.t2d.get_integer('MODEL.KP1BOR', k)
+        nbor_k = self.t2d.get_integer('MODEL.NBOR', k)
+        nbor_knext = self.t2d.get_integer('MODEL.NBOR', knext)
+        h_i = self.t2d.get_double('MODEL.WATERDEPTH', nbor_k)
+        h_i2 = self.t2d.get_double('MODEL.WATERDEPTH', nbor_knext)
+        u_i = self.t2d.get_double('MODEL.VELOCITYU', nbor_k)
+        u_i2 = self.t2d.get_double('MODEL.VELOCITYU', nbor_knext)
+        v_i = self.t2d.get_double('MODEL.VELOCITYV', nbor_k)
+        v_i2 = self.t2d.get_double('MODEL.VELOCITYV', nbor_knext)
+        x2d1 = self.t2d.get_double('MODEL.X', nbor_k)
+        x2d2 = self.t2d.get_double('MODEL.X', nbor_knext)
+        y2d1 = self.t2d.get_double('MODEL.Y', nbor_k)
+        y2d2 = self.t2d.get_double('MODEL.Y', nbor_knext)
+        NX=y2d1-y2d2
+        NY=x2d2-x2d1
+        UN1=u_i*NX+v_i*NY
+        UN2=u_i2*NX+v_i2*NY
+        q += ((h_i+h_i2)*(UN1+UN2)+h_i2*UN2+h_i*UN1)/6.0
+        k = knext
+      if border["position"] == "upstream":
+        q = -q
+      logger.debug("flow for border %d with method 3 is %f" % (border["border_id"], q))
+
+      return q
+
+    def set_z_on_border(self, border, z):
+      """
+      Set the water elevation (i.e. water height + bottom elevation) on a border.
+      If z is None, then the water elevation for this border is free (not imposed).
+      """
+      # Method 1: Impose water elevation point by point
+      """
+      # Deactivate water level imposition in bord.f (requires a patch in bord.f)
+      self.t2d.set_double('MODEL.COTE', -1.0, border["border_id"])
+
+      (first, after_last) = border["points_id"]
+      k = first
+      while k != after_last:
+        if z is None:
+          self.t2d.set_integer('MODEL.LIHBOR', 4, k) # Free elevation on that border
+        else:
+          self.t2d.set_integer('MODEL.LIHBOR', 5, k) # Imposed elevation on that border
+          nbor_k = self.t2d.get_integer('MODEL.NBOR', k)
+          bottom_elevation = self.t2d.get_double('MODEL.BOTTOMELEVATION', nbor_k)
+          hbor_k = max(0.0, z - bottom_elevation)
+          self.t2d.set_double('MODEL.HBOR', hbor_k, k)
+          logger.debug("set z for border point %d, h:%f, zf:%f, z:%f" % (k, hbor_k, bottom_elevation, z))
+        k = self.t2d.get_integer('MODEL.KP1BOR', k)
+      """
+
+      # Method 2: Just tell Telemac what is the imposed elevation for the border
+      if z is not None:
+        self.t2d.set_double('MODEL.COTE', z, border["border_id"])
+      (first, after_last) = border["points_id"]
+      k = first
+      while k != after_last:
+        if z is None:
+          self.t2d.set_integer('MODEL.LIHBOR', 4, k) # Free elevation on that border
+        else:
+          self.t2d.set_integer('MODEL.LIHBOR', 5, k) # Imposed elevation on that border
+        k = self.t2d.get_integer('MODEL.KP1BOR', k)
+
+    def set_v_on_border(self, border, v):
+      """
+      Set the water velocity on a border.
+      If v is None, then the water velocity for this border is free (not imposed).
+      """
+      # This method works only if the water level imposition is deactivated in bord.f
+      # (requires a patch in bord.f)
+      (first, after_last) = border["points_id"]
+      k = first
+      while k != after_last:
+        if v is None:
+          self.t2d.set_integer('MODEL.LIUBOR', 4, k) # Free velocity on that border
+          self.t2d.set_integer('MODEL.LIVBOR', 4, k)
+        else:
+          self.t2d.set_integer('MODEL.LIUBOR', 6, k) # Imposed velocity on that border
+          self.t2d.set_integer('MODEL.LIVBOR', 6, k)
+          xnebor_k = self.t2d.get_double('MODEL.XNEBOR', k)
+          ubor_k = -xnebor_k * v
+          ynebor_k = self.t2d.get_double('MODEL.YNEBOR', k)
+          vbor_k = -ynebor_k * v
+          self.t2d.set_double('MODEL.UBOR', ubor_k, k)
+          self.t2d.set_double('MODEL.VBOR', vbor_k, k)
+        k = self.t2d.get_integer('MODEL.KP1BOR', k)
+
+    def set_q_on_border(self, border, q):
+      """
+      Set the water flow on a border.
+      If q is None, then the water flow for this border is free (not imposed).
+      """
+      if q is not None:
+        self.t2d.set_double('MODEL.DEBIT', q, border["border_id"])
+        logger.debug("flow for border %d is set to %f" % (border["border_id"], q))
+      (first, after_last) = border["points_id"]
+      k = first
+      while k != after_last:
+        if q is None:
+          self.t2d.set_integer('MODEL.LIUBOR', 4, k) # Free velocity on that border
+          self.t2d.set_integer('MODEL.LIVBOR', 4, k)
+        else:
+          self.t2d.set_integer('MODEL.LIUBOR', 5, k) # Imposed discharge on that border
+          self.t2d.set_integer('MODEL.LIVBOR', 5, k)
+        k = self.t2d.get_integer('MODEL.KP1BOR', k)
+
+    def Finalize(self):
+      try:
+        self.beginService("TELEMAC2D.Finalize")
+        if self.t2d:
+          self.t2d.finalize()
+          self.t2d = None
+        self.endService("TELEMAC2D.Finalize")
+      except:
+        self._raiseSalomeError()
+
+    def Compute(self, studyId, caseEntry):
+        try:
+            self.beginService("TELEMAC2D.Compute")
+
+            jdc_dict = self.get_jdc_dict_from_case(studyId, caseEntry)
+            self.init_t2d_from_jdc_dict(jdc_dict)
+
+            # Compute
+            self.t2d.run_all_timesteps()
+
+            # Cleanup
+            self.t2d.finalize()
+
+            self.endService("TELEMAC2D.Compute")
+        except:
+            self._raiseSalomeError()
+
+
+class Telemac2DOutputVariable:
+
+  def __init__(self, varstr):
+    par1 = varstr.find("(")
+    par2 = varstr.find(")")
+    self.varname = varstr[:par1]
+    self.idx = int(varstr[par1+1:par2])
+
+  def get_value(self, inst):
+    return inst.get_double(self.varname, self.idx)
+
+
+class Telemac2DInputVariable:
+
+  def __init__(self, vardict):
+    self.varname = vardict["NOM_VARIABLE_MODELE"]
+    def_area_dict = vardict["ZONE_DE_DEFINITION"]
+    self.idx = def_area_dict.get("INDICE")
+    self.polygon = def_area_dict.get("POLYGONE")
+    self.points_in_polygon_list = None
+
+  def set_value(self, inst, value):
+    if self.idx is not None:
+      inst.set_double(self.varname, value, self.idx)
+    elif self.polygon is not None:
+      if self.points_in_polygon_list is None:
+        self.points_in_polygon_list = get_list_points_in_polygon(inst, self.polygon)
+      for idx in self.points_in_polygon_list:
+        inst.set_double(self.varname, value, idx)
+    else:
+      raise Exception("Invalid area definition for input variable {0}".format(self.varname))
diff --git a/src/mascaret_wrapper/CMakeLists.txt b/src/mascaret_wrapper/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a84cb5b
--- /dev/null
@@ -0,0 +1,67 @@
+#  Copyright (C) 2012-2013 EDF
+#
+#  This file is part of SALOME HYDRO module.
+#
+#  SALOME HYDRO module is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation, either version 3 of the License, or
+#  (at your option) any later version.
+#
+#  SALOME HYDRO module is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with SALOME HYDRO module.  If not, see <http://www.gnu.org/licenses/>.
+
+INCLUDE(${SWIG_USE_FILE})
+
+# --- options ---
+
+# additional include directories
+INCLUDE_DIRECTORIES(
+  ${PYTHON_INCLUDE_DIRS}
+  ${MASCARET_INCLUDE_DIR}
+  ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+# swig flags
+SET_SOURCE_FILES_PROPERTIES(mascaret_swig.i PROPERTIES
+                            CPLUSPLUS ON
+                            SWIG_DEFINITIONS "-shadow")
+
+# additional preprocessor / compiler flags
+ADD_DEFINITIONS(
+  ${PYTHON_DEFINITIONS}
+  )
+
+# libraries to link to
+SET(_link_LIBRARIES
+  ${PYTHON_LIBRARIES}
+  ${MASCARET_LIBRARIES}
+  )
+
+# --- sources ---
+SET(mascaret_SOURCES
+  Mascaret.cxx
+  )
+# --- headers ---
+SET(mascaret_HEADERS
+  Mascaret.hxx
+  )
+
+# --- scripts ---
+# scripts / swig wrappings
+SET(_swig_SCRIPTS
+  ${CMAKE_CURRENT_BINARY_DIR}/mascaret_swig.py
+)
+
+# --- rules ---
+SWIG_ADD_MODULE(mascaret_swig python mascaret_swig.i ${mascaret_SOURCES})
+SWIG_LINK_LIBRARIES(mascaret_swig "${_link_LIBRARIES}")
+
+SET(mypkgpythondir ${SALOME_INSTALL_PYTHON}/salome/hydro/mascaret)
+
+INSTALL(TARGETS ${SWIG_MODULE_mascaret_swig_REAL_NAME} DESTINATION ${mypkgpythondir})
+SALOME_INSTALL_SCRIPTS("${_swig_SCRIPTS}" ${mypkgpythondir})
diff --git a/src/mascaret_wrapper/Mascaret.cxx b/src/mascaret_wrapper/Mascaret.cxx
new file mode 100644 (file)
index 0000000..db999b0
--- /dev/null
@@ -0,0 +1,225 @@
+//  Copyright (C) 2012-2013 EDF
+//
+//  This file is part of SALOME HYDRO module.
+//
+//  SALOME HYDRO module is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  SALOME HYDRO module is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with SALOME HYDRO module.  If not, see <http://www.gnu.org/licenses/>.
+
+#include <cstdlib>
+#include <cstring>
+#include <map>
+#include <sstream>
+
+extern "C"
+{
+#include <apimascaret.h>
+}
+
+#include "Mascaret.hxx"
+
+using namespace std;
+
+namespace SalomeHydro
+{
+
+char * createPChar(const string & str)
+{
+  char * data = new char[str.size() + 1];
+  strcpy(data, str.c_str());
+  return data;
+}
+
+
+class CString
+{
+public:
+
+  CString(const string & str)
+  {
+    _data = createPChar(str);
+  }
+
+  virtual ~CString()
+  {
+    delete[] _data;
+  }
+
+  operator char *()
+  {
+    return _data;
+  }
+
+private:
+  char * _data;
+};
+
+
+MascaretException::MascaretException(const std::string & msg)
+  : runtime_error(msg)
+{
+}
+
+MascaretException::~MascaretException() throw()
+{
+}
+
+const char * MascaretException::__str__() const
+{
+  return what();
+}
+
+Mascaret::Mascaret()
+  : _id(-1),
+    _printing(false)
+{
+  // Initialize model
+  int res = C_CREATE_MASCARET(&_id);
+  testMascaretResult(res, "C_CREATE_MASCARET");
+}
+
+
+Mascaret::~Mascaret()
+{
+  // Delete the model
+  int res = C_DELETE_MASCARET(_id);
+  testMascaretResult(res, "C_DELETE_MASCARET");
+}
+
+
+void Mascaret::testMascaretResult(int res, const string & functionName)
+{
+  if (res != 0)
+  {
+    char * mascErrorMsg;
+    C_GET_ERREUR_MASCARET(_id, &mascErrorMsg);
+    ostringstream msg;
+    msg << "Mascaret error:" << endl;
+    msg << "  Function: " << functionName << endl;
+    msg << "  Message: " << mascErrorMsg;
+    free(mascErrorMsg);
+    throw MascaretException(msg.str());
+  }
+}
+
+
+bool Mascaret::isPrinting()
+{
+  return _printing;
+}
+
+
+void Mascaret::setPrinting(bool printing)
+{
+  _printing = printing;
+}
+
+
+void Mascaret::importModel(const MascaretFileList & fileList)
+{
+  // Create arrays of C strings fileArray and typeArray
+  char** fileArray = new char*[fileList.size()];
+  char** typeArray = new char*[fileList.size()];
+  for (int i=0 ; i<fileList.size() ; i++)
+  {
+    fileArray[i] = createPChar(fileList[i].fileName);
+    typeArray[i] = createPChar(fileList[i].fileType);
+  }
+
+  // Import model
+  int res = C_IMPORT_MODELE_MASCARET(_id, fileArray, typeArray, fileList.size(), _printing);
+  testMascaretResult(res, "C_IMPORT_MODELE_MASCARET");
+
+  // Free arrays of C strings
+  for (int i=0 ; i<fileList.size() ; i++)
+  {
+    delete[] fileArray[i];
+    delete[] typeArray[i];
+  }
+  delete[] fileArray;
+  delete[] typeArray;
+}
+
+
+void Mascaret::initState(const string & ligFileName)
+{
+  int res = C_INIT_ETAT_MASCARET(_id, CString(ligFileName), _printing);
+  testMascaretResult(res, "C_INIT_ETAT_MASCARET");
+}
+
+
+void Mascaret::compute(double startTime, double endTime, double timeStep)
+{
+  int res = C_CALCUL_MASCARET(_id, startTime, endTime, timeStep, _printing);
+  testMascaretResult(res, "C_CALCUL_MASCARET");
+}
+
+
+void Mascaret::compute()
+{
+  // Read startTime, endTime and timeStep from model
+  double startTime = getDouble("Modele.TempsInitial", 0, 0, 0);
+  double endTime = getDouble("Modele.TempsMaximum", 0, 0, 0);
+  double timeStep = getDouble("Modele.DT", 0, 0, 0);
+
+  // Calculation
+  compute(startTime, endTime, timeStep);
+}
+
+
+int Mascaret::getInt(const string & varName, int index1, int index2, int index3)
+{
+  int retVal;
+  int res = C_GET_INT_MASCARET(_id, CString(varName), index1, index2, index3, &retVal);
+  testMascaretResult(res, "C_GET_INT_MASCARET");
+  return retVal;
+}
+
+
+double Mascaret::getDouble(const string & varName, int index1, int index2, int index3)
+{
+  double retVal;
+  int res = C_GET_DOUBLE_MASCARET(_id, CString(varName), index1, index2, index3, &retVal);
+  testMascaretResult(res, "C_GET_DOUBLE_MASCARET");
+  return retVal;
+}
+
+
+void Mascaret::setInt(const std::string & varName, int index1, int index2, int index3, int value)
+{
+  int res = C_SET_INT_MASCARET(_id, CString(varName), index1, index2, index3, value);
+  testMascaretResult(res, "C_SET_INT_MASCARET");
+}
+
+
+void Mascaret::setDouble(const std::string & varName, int index1, int index2, int index3, double value)
+{
+  int res = C_SET_DOUBLE_MASCARET(_id, CString(varName), index1, index2, index3, value);
+  testMascaretResult(res, "C_SET_DOUBLE_MASCARET");
+}
+
+int Mascaret::saveState()
+{
+  int stateId;
+  int res = C_SAVE_ETAT_MASCARET(_id, &stateId);
+  testMascaretResult(res, "C_SAVE_ETAT_MASCARET");
+  return stateId;
+  return 0;
+}
+
+void Mascaret::restoreState(int stateId)
+{
+  int res = C_SET_ETAT_MASCARET(_id, stateId);
+  testMascaretResult(res, "C_SET_ETAT_MASCARET");
+}
+
+}
diff --git a/src/mascaret_wrapper/Mascaret.hxx b/src/mascaret_wrapper/Mascaret.hxx
new file mode 100644 (file)
index 0000000..8a56508
--- /dev/null
@@ -0,0 +1,87 @@
+//  Copyright (C) 2012-2013 EDF
+//
+//  This file is part of SALOME HYDRO module.
+//
+//  SALOME HYDRO module is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  SALOME HYDRO module is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with SALOME HYDRO module.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef MASCARET_HXX_
+#define MASCARET_HXX_
+
+#include <stdexcept>
+#include <vector>
+
+namespace SalomeHydro
+{
+
+typedef struct MascaretFile
+{
+  std::string fileName;
+  std::string fileType;
+} MascaretFile;
+
+typedef std::vector<MascaretFile> MascaretFileList;
+
+class MascaretException: public std::runtime_error
+{
+public:
+
+  MascaretException(const std::string & msg);
+  virtual ~MascaretException() throw();
+
+  const char * __str__() const;
+
+};
+
+class Mascaret
+{
+public:
+
+  // Constructor and destructor
+  Mascaret();
+  virtual ~Mascaret();
+
+  // Get and set printing flag
+  bool isPrinting();
+  void setPrinting(bool printing);
+
+  // Model initialization
+  void importModel(const MascaretFileList & fileList);
+  void initState(const std::string & ligFileName);
+
+  // Save / restore state
+  int saveState();
+  void restoreState(int stateId);
+
+  // Computation
+  void compute(double startTime, double endTime, double timeStep);
+  void compute();
+
+  // Model and state edition
+  int getInt(const std::string & varName, int index1, int index2, int index3);
+  double getDouble(const std::string & varName, int index1, int index2, int index3);
+  void setInt(const std::string & varName, int index1, int index2, int index3, int value);
+  void setDouble(const std::string & varName, int index1, int index2, int index3, double value);
+
+protected:
+
+  void testMascaretResult(int res, const std::string & functionName);
+
+  int _id;
+  bool _printing;
+
+};
+
+}
+
+#endif /* MASCARET_HXX_ */
diff --git a/src/mascaret_wrapper/mascaret_swig.i b/src/mascaret_wrapper/mascaret_swig.i
new file mode 100644 (file)
index 0000000..08fd1d4
--- /dev/null
@@ -0,0 +1,43 @@
+//  Copyright (C) 2012-2013 EDF
+//
+//  This file is part of SALOME HYDRO module.
+//
+//  SALOME HYDRO module is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  SALOME HYDRO module is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with SALOME HYDRO module.  If not, see <http://www.gnu.org/licenses/>.
+
+%module mascaret_swig
+
+%include std_string.i
+
+%include std_vector.i
+
+%{
+#include "Mascaret.hxx"
+%}
+
+// Instantiate template used by Mascaret
+%template(MascaretFileVector) std::vector<SalomeHydro::MascaretFile>;
+
+// Exception handling
+%catches(SalomeHydro::MascaretException, ...) SalomeHydro::Mascaret::Mascaret();
+%catches(SalomeHydro::MascaretException, ...) SalomeHydro::Mascaret::~Mascaret();
+%catches(SalomeHydro::MascaretException, ...) SalomeHydro::Mascaret::importModel(const MascaretFileList & fileList);
+%catches(SalomeHydro::MascaretException, ...) SalomeHydro::Mascaret::initState(const std::string & ligFileName);
+%catches(SalomeHydro::MascaretException, ...) SalomeHydro::Mascaret::compute(double startTime, double endTime, double timeStep);
+%catches(SalomeHydro::MascaretException, ...) SalomeHydro::Mascaret::compute();
+%catches(SalomeHydro::MascaretException, ...) SalomeHydro::Mascaret::getInt(const std::string & varName, int index1, int index2, int index3);
+%catches(SalomeHydro::MascaretException, ...) SalomeHydro::Mascaret::getDouble(const std::string & varName, int index1, int index2, int index3);
+%catches(SalomeHydro::MascaretException, ...) SalomeHydro::Mascaret::setInt(const std::string & varName, int index1, int index2, int index3, int value);
+%catches(SalomeHydro::MascaretException, ...) SalomeHydro::Mascaret::setDouble(const std::string & varName, int index1, int index2, int index3, double value);
+
+%include "Mascaret.hxx"
index a6c8307698090c959deb6d47941f5b945c0bc03f..530024021a1566d4b4ee209239e167b49bc20736 100644 (file)
@@ -18,6 +18,7 @@
 ADD_SUBDIRECTORY(mascaret)
 ADD_SUBDIRECTORY(telemac2d)
 ADD_SUBDIRECTORY(pytel)
+ADD_SUBDIRECTORY(coupling1d2d)
 ADD_SUBDIRECTORY(boundary_conditions)
 
 # --- Python files ---
diff --git a/src/salome_hydro/coupling1d2d/CMakeLists.txt b/src/salome_hydro/coupling1d2d/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5274761
--- /dev/null
@@ -0,0 +1,28 @@
+#  Copyright (C) 2012-2013 EDF
+#
+#  This file is part of SALOME HYDRO module.
+#
+#  SALOME HYDRO module is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation, either version 3 of the License, or
+#  (at your option) any later version.
+#
+#  SALOME HYDRO module is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with SALOME HYDRO module.  If not, see <http://www.gnu.org/licenses/>.
+
+ADD_SUBDIRECTORY(eficas)
+
+# --- Python files ---
+
+SET(PYFILES
+  __init__.py
+)
+
+# --- rules ---
+
+SALOME_INSTALL_SCRIPTS("${PYFILES}" ${SALOME_INSTALL_PYTHON}/salome/hydro/coupling1d2d)
diff --git a/src/salome_hydro/coupling1d2d/__init__.py b/src/salome_hydro/coupling1d2d/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/salome_hydro/coupling1d2d/eficas/CMakeLists.txt b/src/salome_hydro/coupling1d2d/eficas/CMakeLists.txt
new file mode 100644 (file)
index 0000000..3fea4fa
--- /dev/null
@@ -0,0 +1,39 @@
+#  Copyright (C) 2012-2013 EDF
+#
+#  This file is part of SALOME HYDRO module.
+#
+#  SALOME HYDRO module is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation, either version 3 of the License, or
+#  (at your option) any later version.
+#
+#  SALOME HYDRO module is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with SALOME HYDRO module.  If not, see <http://www.gnu.org/licenses/>.
+
+# --- Python files ---
+
+SET(PYFILES
+  __init__.py
+  configuration_coupling1d2d.py
+  prefs_coupling1d2d.py
+  prefs.py
+  coupling1d2d_cata.py
+  appli.py
+  generator_coupling1d2d.py
+)
+
+# --- Data files ---
+
+SET(DATAFILES
+  coupling1d2d_template_schema.xml
+)
+
+# --- rules ---
+
+SALOME_INSTALL_SCRIPTS("${PYFILES}" ${SALOME_INSTALL_PYTHON}/salome/hydro/coupling1d2d/eficas)
+INSTALL(FILES ${DATAFILES} DESTINATION ${SALOME_INSTALL_PYTHON}/salome/hydro/coupling1d2d/eficas)
diff --git a/src/salome_hydro/coupling1d2d/eficas/__init__.py b/src/salome_hydro/coupling1d2d/eficas/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/salome_hydro/coupling1d2d/eficas/appli.py b/src/salome_hydro/coupling1d2d/eficas/appli.py
new file mode 100644 (file)
index 0000000..e9c576c
--- /dev/null
@@ -0,0 +1,118 @@
+# -*- coding: utf-8 -*-
+#
+#  Copyright (C) 2012-2013 EDF
+#
+#  This file is part of SALOME HYDRO module.
+#
+#  SALOME HYDRO module is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation, either version 3 of the License, or
+#  (at your option) any later version.
+#
+#  SALOME HYDRO module is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with SALOME HYDRO module.  If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import sys
+import re
+
+from PyQt5.QtWidgets import QMessageBox , QScrollArea, QGridLayout
+
+import salome
+import SalomePyQt
+sgPyQt = SalomePyQt.SalomePyQt()
+
+from salome.kernel.logger import Logger
+from salome.kernel import termcolor
+logger = Logger("salome.hydro.coupling1d2d.eficas.appli",
+                color = termcolor.GREEN_FG)
+
+import eficasSalome
+
+from salome.hydro.study import HydroStudyEditor
+
+class SalomeEntry:
+    
+    enable_salome_selection = True
+    help_message = u"Une entrée de l'arbre d'étude de Salome est attendue"
+    
+    def __init__(self, entryStr):
+        self._entry = entryStr
+    
+    @staticmethod
+    def __convert__(entryStr):
+        return SalomeEntry(entryStr)
+    
+    @staticmethod
+    def get_selected_value(selected_entry, study_editor):
+        sobj = study_editor.study.FindObjectID(selected_entry)
+        name = sobj.GetName()
+        return "%s (%s)" % (name, selected_entry)
+
+class EficasForCoupling1D2DAppli(eficasSalome.MyEficas):
+    """
+    This class launches Eficas and adds entries for the created files in
+    HYDRO component in the study tree. The messages in this class are in
+    french because they are displayed in Eficas interface.
+
+    :type  fichier: string
+    :param fichier: path of an Eficas file to open
+
+    """
+    def __init__(self, fichier = None, version = None):
+        self.ed = HydroStudyEditor()
+        self.codedir = os.path.dirname(__file__)
+        sys.path[:0] = [self.codedir]
+        area = QScrollArea(SalomePyQt.SalomePyQt().getDesktop());
+        eficasSalome.MyEficas.__init__(self, area, "coupling1d2d",
+                                       fichier, version = version)
+        gridLayout = QGridLayout(area)
+        gridLayout.addWidget(self)
+        area.setWidgetResizable(1)
+
+        sgPyQt.createView("Eficas Coupling 1D/2D", self)
+
+    def selectGroupFromSalome(self, kwType = None, editor=None):
+        """
+        Select an entry from Salome object browser
+        """
+        nbEntries = salome.sg.SelectedCount()
+        if nbEntries < 1:
+            msg = u"Veuillez sélectionner une entrée de l'arbre d'étude de Salome"
+            QMessageBox.information(self, self.tr(u"Sélection depuis Salome"), self.tr(msg))
+            return [], msg
+        elif nbEntries > 1:
+            msg = u"Une seule entrée doit être sélectionnée dans l'arbre d'étude de Salome"
+            QMessageBox.information(self, self.tr(u"Sélection depuis Salome"), self.tr(msg))
+            return [], msg
+        else:
+            try:
+                value = kwType.get_selected_value(salome.sg.getSelected(0), self.ed.editor)
+                msg = u"L'entrée de l'arbre d'étude de Salome a été sélectionnée"
+                return [value], msg
+            except Exception, e:
+                QMessageBox.information(self, self.tr(u"Sélection depuis Salome"), self.tr(unicode(e)))
+                return [], unicode(e)
+
+    def addJdcInSalome(self, jdcPath):
+        """
+        Add the newly created file in Salome study
+        """
+        try:
+            self.ed.find_or_create_coupling1d2d_case(jdcPath)
+        except Exception, exc:
+            msgError = "Can't add file to Salome study tree"
+            logger.exception(msgError)
+            QMessageBox.warning(self, self.tr("Warning"),
+                                self.tr("%s. Reason:\n%s\n\nSee logs for more details." % (msgError, exc)))
+        salome.sg.updateObjBrowser(0)
+
+    def closeEvent(self, event):
+        while self.codedir in sys.path:
+            sys.path.remove(self.codedir)
+        eficasSalome.MyEficas.closeEvent(self, event)
diff --git a/src/salome_hydro/coupling1d2d/eficas/configuration_coupling1d2d.py b/src/salome_hydro/coupling1d2d/eficas/configuration_coupling1d2d.py
new file mode 100644 (file)
index 0000000..503fa36
--- /dev/null
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+#
+#  Copyright (C) 2012-2013 EDF
+#
+#  This file is part of SALOME HYDRO module.
+#
+#  SALOME HYDRO module is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation, either version 3 of the License, or
+#  (at your option) any later version.
+#
+#  SALOME HYDRO module is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with SALOME HYDRO module.  If not, see <http://www.gnu.org/licenses/>.
+
+import os
+
+from Editeur.catadesc import CatalogDescription
+from InterfaceQT4.configuration import CONFIG_BASE
+
+class CONFIG(CONFIG_BASE):
+
+    def __init__(self, appli, repIni):
+        """
+        This class stores the configuration parameters for Eficas
+        """
+        CONFIG_BASE.__init__(self, appli, repIni)
+
+        # Configuration parameters
+        self.savedir    = os.getenv("HOME")
+        self.catalogues = (CatalogDescription("coupling1d2d",
+                                              os.path.join(repIni, "coupling1d2d_cata.py"),
+                                              file_format = "coupling1d2d"),)
+        self.lang = 'fr'
+
+        self.generator_module = "generator_coupling1d2d"
+
+    def save_params(self):
+        pass
+
+    def get_template_file(self):
+        return os.path.join(self.repIni, "coupling1d2d_template_schema.xml")
+
+    def get_extension(self):
+        return ".xml"
+
+def make_config(appli, rep):
+    return CONFIG(appli, rep)
+
+def make_config_style(appli, rep):
+    return None
diff --git a/src/salome_hydro/coupling1d2d/eficas/coupling1d2d_cata.py b/src/salome_hydro/coupling1d2d/eficas/coupling1d2d_cata.py
new file mode 100644 (file)
index 0000000..1fad998
--- /dev/null
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+#
+#  Copyright (C) 2012-2013 EDF
+#
+#  This file is part of SALOME HYDRO module.
+#
+#  SALOME HYDRO module is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation, either version 3 of the License, or
+#  (at your option) any later version.
+#
+#  SALOME HYDRO module is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with SALOME HYDRO module.  If not, see <http://www.gnu.org/licenses/>.
+
+from salome.hydro.coupling1d2d.eficas.appli import SalomeEntry
+from Accas import *
+
+JdC = JDC_CATA(regles = (UN_PARMI('COUPLAGE1D2D',)),
+                        )
+
+COUPLAGE1D2D = PROC(
+    nom = "COUPLAGE1D2D", op = None,
+    fr = u"Définition d'un couplage Mascaret / Telemac2D",
+    ang = u"Definition of a Mascaret / Telemac2D coupling",
+    CAS_MASCARET = SIMP(statut = "o", typ = SalomeEntry,
+                        fr = u"Entrée Salome contenant le cas d'étude Mascaret",
+                        ang = u"Salome entry containing Mascaret study case"),
+    CAS_TELEMAC2D = SIMP(statut = "o", typ = SalomeEntry,
+                         fr = u"Entrée Salome contenant le cas d'étude Telemac2D",
+                         ang = u"Salome entry containing Telemac2D study case"),
+    FICHIER_COUPLAGE = SIMP(statut = "o", typ = ('Fichier', 'Fichiers Python (*.py);;Tous les fichiers (*)',),
+                            fr = u"Fichier de description du couplage",
+                            ang = u"Coupling description file"),
+    FICHIER_LOG = SIMP(statut = "o", typ = ('Fichier', 'Tous les fichiers (*)', "Sauvegarde"),
+                       fr = "Fichier de log",
+                       ang = u"Log file"),
+    FICHIER_GRAPHIQUE = SIMP(statut = "o",
+                             typ = ('Fichier', 'Fichiers CSV (*.csv);;Tous les fichiers (*)', "Sauvegarde"),
+                             fr = u"Fichier de données pour la génération du graphique",
+                             ang = u"Data file for the graphics generation"),
+)
+TEXTE_NEW_JDC="COUPLAGE1D2D()"
diff --git a/src/salome_hydro/coupling1d2d/eficas/coupling1d2d_template_schema.xml b/src/salome_hydro/coupling1d2d/eficas/coupling1d2d_template_schema.xml
new file mode 100644 (file)
index 0000000..38908ab
--- /dev/null
@@ -0,0 +1,447 @@
+<?xml version='1.0' encoding='iso-8859-1' ?>
+<proc name="newSchema_1">
+   <property name="DefaultStudyID" value="1"/>
+   <type name="string" kind="string"/>
+   <struct name="Engines/dataref">
+      <member name="ref" type="string"/>
+   </struct>
+   <type name="bool" kind="bool"/>
+   <sequence name="boolvec" content="bool"/>
+   <type name="double" kind="double"/>
+   <sequence name="dblevec" content="double"/>
+   <objref name="file" id="file"/>
+   <type name="int" kind="int"/>
+   <sequence name="intvec" content="int"/>
+   <struct name="stringpair">
+      <member name="name" type="string"/>
+      <member name="value" type="string"/>
+   </struct>
+   <sequence name="propvec" content="stringpair"/>
+   <objref name="pyobj" id="python:obj:1.0"/>
+   <sequence name="seqboolvec" content="boolvec"/>
+   <sequence name="seqdblevec" content="dblevec"/>
+   <sequence name="seqintvec" content="intvec"/>
+   <sequence name="stringvec" content="string"/>
+   <sequence name="seqstringvec" content="stringvec"/>
+   <container name="DefaultContainer">
+      <property name="container_name" value="FactoryServer"/>
+      <property name="name" value="localhost"/>
+   </container>
+   <container name="mascaret_container">
+      <property name="container_name" value=""/>
+      <property name="name" value="localhost"/>
+   </container>
+   <container name="telemac_container">
+      <property name="name" value="localhost"/>
+   </container>
+   <while name="TimeLoop">
+      <bloc name="TimeBloc">
+         <inline name="TimeController">
+            <script><code><![CDATA[time += timestep
+cont = (time + timestep/2 < endtime) # Add half timestep to avoid rounding issues
+timeData = {}
+timeData["start_time"] = time
+timeData["end_time"] = time + timestep
+timeData["time_step"] = timestep
+
+if cont:
+    log.write("time: %f\n" % timeData["end_time"])
+else:
+    log.close()
+    graph.close()
+]]></code></script>
+            <inport name="time" type="double"/>
+            <inport name="endtime" type="double"/>
+            <inport name="timestep" type="double"/>
+            <inport name="log" type="pyobj"/>
+            <inport name="graph" type="pyobj"/>
+            <outport name="cont" type="bool"/>
+            <outport name="time" type="double"/>
+            <outport name="timeData" type="pyobj"/>
+         </inline>
+         <while name="ConvergenceLoop">
+            <bloc name="ConvergenceBloc">
+               <inline name="ConvergenceController">
+                  <script><code><![CDATA[telborders = set(telemacData.keys())
+mascborders = set(mascData.keys())
+border_names = telborders | mascborders
+
+if iter == 1:
+    log.write("ITER ")
+    for name in border_names:
+        if name in mascData:
+            nbvar = len(mascData[name])
+            formatlen = nbvar * 10 - 5
+            log.write("MASC %-*s" % (formatlen, name))
+        if name in telemacData:
+            nbvar = len(telemacData[name])
+            formatlen = nbvar * 10 - 5
+            log.write("T2D  %-*s" % (formatlen, name))
+    log.write("\n")
+    log.write("ITER ")
+    for name in border_names:
+        if name in mascData:
+            keys = sorted(mascData[name].iterkeys())
+            for key in keys:
+                log.write("%9s " % key)
+        if name in telemacData:
+            keys = sorted(telemacData[name].iterkeys())
+            for key in keys:
+                log.write("%9s " % key)
+    log.write("\n")
+
+log.write("%4d " % iter)
+for name in border_names:
+    if name in mascData:
+        keys = sorted(mascData[name].iterkeys())
+        for key in keys:
+            log.write("%9.3f " % mascData[name][key])
+    if name in telemacData:
+        keys = sorted(telemacData[name].iterkeys())
+        for key in keys:
+            log.write("%9.3f " % telemacData[name][key])
+log.write("\n")
+log.flush()
+
+convergence = True
+for name in border_names:
+    if name in mascData and name in telemacData:
+        if abs(mascData[name]["Z"] - telemacData[name]["Z"]) > Z_tol:
+            convergence = False
+        if abs(mascData[name]["Q"] - telemacData[name]["Q"]) > Q_tol:
+            convergence = False
+
+cont = True
+if convergence:
+    log.write("Convergence reached\n")
+    cont = False
+
+iter += 1
+if iter > maxiter:
+    log.write("Max iterations reached\n")
+    cont = False
+
+if not cont:
+    iter = 1
+
+    if timeData["start_time"] == 0.0:
+        graph.write("Time,")
+        for name in border_names:
+            if name in mascData:
+                keys = sorted(mascData[name].iterkeys())
+                for key in keys:
+                    graph.write("MASC %s %s," % (name, key))
+            if name in telemacData:
+                keys = sorted(telemacData[name].iterkeys())
+                for key in keys:
+                    graph.write("T2D %s %s," % (name, key))
+        graph.write("\n")
+
+    graph.write("%f," % timeData["end_time"])
+    for name in border_names:
+        if name in mascData:
+            keys = sorted(mascData[name].iterkeys())
+            for key in keys:
+                graph.write("%f," % mascData[name][key])
+        if name in telemacData:
+            keys = sorted(telemacData[name].iterkeys())
+            for key in keys:
+                graph.write("%f," % telemacData[name][key])
+    graph.write("\n")
+    graph.flush()
+]]></code></script>
+                  <inport name="mascData" type="pyobj"/>
+                  <inport name="telemacData" type="pyobj"/>
+                  <inport name="Z_tol" type="double"/>
+                  <inport name="Q_tol" type="double"/>
+                  <inport name="iter" type="int"/>
+                  <inport name="borders" type="pyobj"/>
+                  <inport name="log" type="pyobj"/>
+                  <inport name="maxiter" type="int"/>
+                  <inport name="timeData" type="pyobj"/>
+                  <inport name="graph" type="pyobj"/>
+                  <outport name="cont" type="bool"/>
+                  <outport name="iter" type="int"/>
+                  <outport name="timeData" type="pyobj"/>
+                  <outport name="mascData" type="pyobj"/>
+                  <outport name="telemacData" type="pyobj"/>
+               </inline>
+               <service name="MascExecStep">
+                  <component>MASCARET</component>
+                  <load container="mascaret_container"/>
+                  <method>ExecStep</method>
+                  <inport name="timeData" type="pyobj"/>
+                  <inport name="inputData" type="pyobj"/>
+                  <outport name="outputData" type="pyobj"/>
+               </service>
+               <service name="TelExecStep">
+                  <component>TELEMAC2D</component>
+                  <load container="telemac_container"/>
+                  <method>ExecStep</method>
+                  <inport name="timeData" type="pyobj"/>
+                  <inport name="inputData" type="pyobj"/>
+                  <outport name="outputData" type="pyobj"/>
+               </service>
+               <control> <fromnode>MascExecStep</fromnode> <tonode>ConvergenceController</tonode> </control>
+               <control> <fromnode>MascExecStep</fromnode> <tonode>TelExecStep</tonode> </control>
+               <control> <fromnode>TelExecStep</fromnode> <tonode>ConvergenceController</tonode> </control>
+               <datalink control="false">
+                  <fromnode>ConvergenceController</fromnode> <fromport>timeData</fromport>
+                  <tonode>MascExecStep</tonode> <toport>timeData</toport>
+               </datalink>
+               <datalink control="false">
+                  <fromnode>ConvergenceController</fromnode> <fromport>timeData</fromport>
+                  <tonode>TelExecStep</tonode> <toport>timeData</toport>
+               </datalink>
+               <datalink control="false">
+                  <fromnode>ConvergenceController</fromnode> <fromport>telemacData</fromport>
+                  <tonode>MascExecStep</tonode> <toport>inputData</toport>
+               </datalink>
+               <datalink control="false">
+                  <fromnode>MascExecStep</fromnode> <fromport>outputData</fromport>
+                  <tonode>ConvergenceController</tonode> <toport>mascData</toport>
+               </datalink>
+               <datalink control="false">
+                  <fromnode>MascExecStep</fromnode> <fromport>outputData</fromport>
+                  <tonode>TelExecStep</tonode> <toport>inputData</toport>
+               </datalink>
+               <datalink control="false">
+                  <fromnode>TelExecStep</fromnode> <fromport>outputData</fromport>
+                  <tonode>ConvergenceController</tonode> <toport>telemacData</toport>
+               </datalink>
+            </bloc>
+            <datalink control="false">
+               <fromnode>ConvergenceBloc.ConvergenceController</fromnode> <fromport>iter</fromport>
+               <tonode>ConvergenceBloc.ConvergenceController</tonode> <toport>iter</toport>
+            </datalink>
+            <datalink control="false">
+               <fromnode>ConvergenceBloc.ConvergenceController</fromnode> <fromport>timeData</fromport>
+               <tonode>ConvergenceBloc.ConvergenceController</tonode> <toport>timeData</toport>
+            </datalink>
+         </while>
+         <control> <fromnode>ConvergenceLoop</fromnode> <tonode>TimeController</tonode> </control>
+         <datalink control="false">
+            <fromnode>TimeController</fromnode> <fromport>cont</fromport>
+            <tonode>ConvergenceLoop</tonode> <toport>condition</toport>
+         </datalink>
+         <datalink control="false">
+            <fromnode>TimeController</fromnode> <fromport>timeData</fromport>
+            <tonode>ConvergenceLoop.ConvergenceBloc.ConvergenceController</tonode> <toport>timeData</toport>
+         </datalink>
+         <datalink control="false">
+            <fromnode>TimeController</fromnode> <fromport>timeData</fromport>
+            <tonode>ConvergenceLoop.ConvergenceBloc.MascExecStep</tonode> <toport>timeData</toport>
+         </datalink>
+         <datalink control="false">
+            <fromnode>TimeController</fromnode> <fromport>timeData</fromport>
+            <tonode>ConvergenceLoop.ConvergenceBloc.TelExecStep</tonode> <toport>timeData</toport>
+         </datalink>
+         <datalink control="false">
+            <fromnode>ConvergenceLoop.ConvergenceBloc.ConvergenceController</fromnode> <fromport>cont</fromport>
+            <tonode>ConvergenceLoop</tonode> <toport>condition</toport>
+         </datalink>
+      </bloc>
+      <datalink control="false">
+         <fromnode>TimeBloc.TimeController</fromnode> <fromport>time</fromport>
+         <tonode>TimeBloc.TimeController</tonode> <toport>time</toport>
+      </datalink>
+   </while>
+   <service name="InitMascaret">
+      <node>TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.MascExecStep</node>
+      <method>Init</method>
+      <inport name="studyID" type="int"/>
+      <inport name="detCaseEntry" type="string"/>
+   </service>
+   <inline name="InitCoupling">
+      <script><code><![CDATA[execfile(couplingFile)
+
+timeData = {}
+timeData["start_time"] = starttime
+timeData["end_time"] = starttime + timestep
+timeData["time_step"] = timestep
+timeData["save_state_flag"] = True
+
+log = open(logFile, "w")
+graph = open(graphFile, "w")
+]]></code></script>
+      <inport name="couplingFile" type="string"/>
+      <inport name="logFile" type="string"/>
+      <inport name="graphFile" type="string"/>
+      <outport name="starttime" type="double"/>
+      <outport name="endtime" type="double"/>
+      <outport name="timestep" type="double"/>
+      <outport name="eps_Z" type="double"/>
+      <outport name="eps_Q" type="double"/>
+      <outport name="borders" type="pyobj"/>
+      <outport name="timeData" type="pyobj"/>
+      <outport name="log" type="pyobj"/>
+      <outport name="maxiter" type="int"/>
+      <outport name="graph" type="pyobj"/>
+   </inline>
+   <service name="FinalizeMascaret">
+      <node>TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.MascExecStep</node>
+      <method>Finalize</method>
+   </service>
+   <service name="InitTelemac">
+      <node>TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.TelExecStep</node>
+      <method>Init</method>
+      <inport name="studyID" type="int"/>
+      <inport name="detCaseEntry" type="string"/>
+   </service>
+   <service name="FinalizeTelemac">
+      <node>TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.TelExecStep</node>
+      <method>Finalize</method>
+   </service>
+   <service name="InitMascBorders">
+      <node>TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.MascExecStep</node>
+      <method>InitBorders</method>
+      <inport name="borders" type="pyobj"/>
+   </service>
+   <service name="InitTelBorders">
+      <node>TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.TelExecStep</node>
+      <method>InitBorders</method>
+      <inport name="borders" type="pyobj"/>
+   </service>
+   <control> <fromnode>TimeLoop</fromnode> <tonode>FinalizeMascaret</tonode> </control>
+   <control> <fromnode>TimeLoop</fromnode> <tonode>FinalizeTelemac</tonode> </control>
+   <control> <fromnode>InitMascaret</fromnode> <tonode>TimeLoop</tonode> </control>
+   <control> <fromnode>InitCoupling</fromnode> <tonode>TimeLoop</tonode> </control>
+   <control> <fromnode>InitCoupling</fromnode> <tonode>InitMascBorders</tonode> </control>
+   <control> <fromnode>InitCoupling</fromnode> <tonode>InitTelBorders</tonode> </control>
+   <control> <fromnode>InitTelemac</fromnode> <tonode>TimeLoop</tonode> </control>
+   <control> <fromnode>InitTelemac</fromnode> <tonode>InitTelBorders</tonode> </control>
+   <control> <fromnode>InitMascBorders</fromnode> <tonode>TimeLoop</tonode> </control>
+   <control> <fromnode>InitTelBorders</fromnode> <tonode>TimeLoop</tonode> </control>
+   <datalink control="false">
+      <fromnode>InitCoupling</fromnode> <fromport>starttime</fromport>
+      <tonode>TimeLoop.TimeBloc.TimeController</tonode> <toport>time</toport>
+   </datalink>
+   <datalink control="false">
+      <fromnode>InitCoupling</fromnode> <fromport>endtime</fromport>
+      <tonode>TimeLoop.TimeBloc.TimeController</tonode> <toport>endtime</toport>
+   </datalink>
+   <datalink control="false">
+      <fromnode>InitCoupling</fromnode> <fromport>timestep</fromport>
+      <tonode>TimeLoop.TimeBloc.TimeController</tonode> <toport>timestep</toport>
+   </datalink>
+   <datalink control="false">
+      <fromnode>InitCoupling</fromnode> <fromport>eps_Z</fromport>
+      <tonode>TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.ConvergenceController</tonode> <toport>Z_tol</toport>
+   </datalink>
+   <datalink control="false">
+      <fromnode>InitCoupling</fromnode> <fromport>eps_Q</fromport>
+      <tonode>TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.ConvergenceController</tonode> <toport>Q_tol</toport>
+   </datalink>
+   <datalink control="false">
+      <fromnode>InitCoupling</fromnode> <fromport>borders</fromport>
+      <tonode>TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.ConvergenceController</tonode> <toport>borders</toport>
+   </datalink>
+   <datalink control="false">
+      <fromnode>InitCoupling</fromnode> <fromport>borders</fromport>
+      <tonode>InitMascBorders</tonode> <toport>borders</toport>
+   </datalink>
+   <datalink control="false">
+      <fromnode>InitCoupling</fromnode> <fromport>borders</fromport>
+      <tonode>InitTelBorders</tonode> <toport>borders</toport>
+   </datalink>
+   <datalink control="false">
+      <fromnode>InitCoupling</fromnode> <fromport>timeData</fromport>
+      <tonode>TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.ConvergenceController</tonode> <toport>timeData</toport>
+   </datalink>
+   <datalink control="false">
+      <fromnode>InitCoupling</fromnode> <fromport>timeData</fromport>
+      <tonode>TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.MascExecStep</tonode> <toport>timeData</toport>
+   </datalink>
+   <datalink control="false">
+      <fromnode>InitCoupling</fromnode> <fromport>timeData</fromport>
+      <tonode>TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.TelExecStep</tonode> <toport>timeData</toport>
+   </datalink>
+   <datalink control="false">
+      <fromnode>InitCoupling</fromnode> <fromport>log</fromport>
+      <tonode>TimeLoop.TimeBloc.TimeController</tonode> <toport>log</toport>
+   </datalink>
+   <datalink control="false">
+      <fromnode>InitCoupling</fromnode> <fromport>log</fromport>
+      <tonode>TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.ConvergenceController</tonode> <toport>log</toport>
+   </datalink>
+   <datalink control="false">
+      <fromnode>InitCoupling</fromnode> <fromport>maxiter</fromport>
+      <tonode>TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.ConvergenceController</tonode> <toport>maxiter</toport>
+   </datalink>
+   <datalink control="false">
+      <fromnode>InitCoupling</fromnode> <fromport>graph</fromport>
+      <tonode>TimeLoop.TimeBloc.TimeController</tonode> <toport>graph</toport>
+   </datalink>
+   <datalink control="false">
+      <fromnode>InitCoupling</fromnode> <fromport>graph</fromport>
+      <tonode>TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.ConvergenceController</tonode> <toport>graph</toport>
+   </datalink>
+   <datalink control="false">
+      <fromnode>TimeLoop.TimeBloc.TimeController</fromnode> <fromport>cont</fromport>
+      <tonode>TimeLoop</tonode> <toport>condition</toport>
+   </datalink>
+   <parameter>
+      <tonode>InitMascaret</tonode><toport>studyID</toport>
+      <value><int>1</int></value>
+   </parameter>
+   <parameter>
+      <tonode>InitMascaret</tonode><toport>detCaseEntry</toport>
+      <value><string>%parse_entry(CAS_MASCARET)%</string></value>
+   </parameter>
+   <parameter>
+      <tonode>InitCoupling</tonode><toport>couplingFile</toport>
+      <value><string>%FICHIER_COUPLAGE%</string></value>
+   </parameter>
+   <parameter>
+      <tonode>InitCoupling</tonode><toport>logFile</toport>
+      <value><string>%FICHIER_LOG%</string></value>
+   </parameter>
+   <parameter>
+      <tonode>InitCoupling</tonode><toport>graphFile</toport>
+      <value><string>%FICHIER_GRAPHIQUE%</string></value>
+   </parameter>
+   <parameter>
+      <tonode>TimeLoop</tonode><toport>condition</toport>
+      <value><boolean>true</boolean></value>
+   </parameter>
+   <parameter>
+      <tonode>TimeLoop.TimeBloc.ConvergenceLoop</tonode><toport>condition</toport>
+      <value><boolean>true</boolean></value>
+   </parameter>
+   <parameter>
+      <tonode>TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.ConvergenceController</tonode><toport>iter</toport>
+      <value><int>1</int></value>
+   </parameter>
+   <parameter>
+      <tonode>TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.MascExecStep</tonode><toport>inputData</toport>
+      <value><objref>N.</objref></value>
+   </parameter>
+   <parameter>
+      <tonode>TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.TelExecStep</tonode><toport>inputData</toport>
+      <value><objref>N.</objref></value>
+   </parameter>
+   <parameter>
+      <tonode>InitTelemac</tonode><toport>studyID</toport>
+      <value><int>1</int></value>
+   </parameter>
+   <parameter>
+      <tonode>InitTelemac</tonode><toport>detCaseEntry</toport>
+      <value><string>%parse_entry(CAS_TELEMAC2D)%</string></value>
+   </parameter>
+   <presentation name="InitMascaret" x="166" y="32" width="158" height="90" expanded="1" expx="166" expy="32" expWidth="158" expHeight="90" shownState="0"/>
+   <presentation name="TimeLoop" x="450.5" y="32" width="760" height="764.5" expanded="1" expx="450.5" expy="32" expWidth="760" expHeight="764.5" shownState="0"/>
+   <presentation name="TimeLoop.TimeBloc" x="4" y="60" width="752" height="700.5" expanded="1" expx="4" expy="60" expWidth="752" expHeight="700.5" shownState="0"/>
+   <presentation name="TimeLoop.TimeBloc.TimeController" x="590" y="56" width="158" height="171" expanded="1" expx="590" expy="56" expWidth="158" expHeight="171" shownState="0"/>
+   <presentation name="TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.ConvergenceController" x="330.5" y="32" width="158" height="306" expanded="1" expx="330.5" expy="32" expWidth="158" expHeight="306" shownState="0"/>
+   <presentation name="TimeLoop.TimeBloc.ConvergenceLoop" x="4" y="291.5" width="503" height="405" expanded="1" expx="4" expy="291.5" expWidth="503" expHeight="405" shownState="0"/>
+   <presentation name="TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc" x="6.5" y="59" width="492.5" height="342" expanded="1" expx="6.5" expy="59" expWidth="492.5" expHeight="342" shownState="0"/>
+   <presentation name="TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.MascExecStep" x="42" y="32" width="158" height="90" expanded="1" expx="42" expy="32" expWidth="158" expHeight="90" shownState="0"/>
+   <presentation name="InitCoupling" x="3.5" y="355.5" width="158" height="306" expanded="1" expx="3.5" expy="355.5" expWidth="158" expHeight="306" shownState="0"/>
+   <presentation name="TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.TelExecStep" x="86" y="168.5" width="158" height="90" expanded="1" expx="86" expy="168.5" expWidth="158" expHeight="90" shownState="0"/>
+   <presentation name="FinalizeMascaret" x="1308" y="32" width="158" height="36" expanded="1" expx="1308" expy="32" expWidth="158" expHeight="36" shownState="0"/>
+   <presentation name="InitTelemac" x="4" y="138.5" width="158" height="90" expanded="1" expx="4" expy="138.5" expWidth="158" expHeight="90" shownState="0"/>
+   <presentation name="FinalizeTelemac" x="1308" y="89" width="158" height="36" expanded="1" expx="1308" expy="89" expWidth="158" expHeight="36" shownState="0"/>
+   <presentation name="InitMascBorders" x="184" y="273.5" width="158" height="63" expanded="1" expx="184" expy="273.5" expWidth="158" expHeight="63" shownState="0"/>
+   <presentation name="InitTelBorders" x="185" y="169" width="158" height="63" expanded="1" expx="185" expy="169" expWidth="158" expHeight="63" shownState="0"/>
+   <presentation name="__ROOT__" x="0" y="0" width="1470" height="800.5" expanded="1" expx="0" expy="0" expWidth="1470" expHeight="800.5" shownState="0"/>
+</proc>
diff --git a/src/salome_hydro/coupling1d2d/eficas/generator_coupling1d2d.py b/src/salome_hydro/coupling1d2d/eficas/generator_coupling1d2d.py
new file mode 100644 (file)
index 0000000..4fd1225
--- /dev/null
@@ -0,0 +1,67 @@
+#  Copyright (C) 2012-2013 EDF
+#
+#  This file is part of SALOME HYDRO module.
+#
+#  SALOME HYDRO module is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation, either version 3 of the License, or
+#  (at your option) any later version.
+#
+#  SALOME HYDRO module is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with SALOME HYDRO module.  If not, see <http://www.gnu.org/licenses/>.
+
+import re
+
+from generator.generator_file_from_template import FileFromTemplateGenerator
+
+def entryPoint():
+    return {'name': 'coupling1d2d',
+            'factory' : Coupling1D2DGenerator}
+
+class Coupling1D2DGenerator(FileFromTemplateGenerator):
+    """
+    This generator is mostly identical to FileFromTemplateGenerator, but it
+    can also perform replacements using functions. The syntax for this kind
+    of replacement is %func(KEYWORD)%. The replacement method will call
+    the function "func" that must be defined in this class with the parameter
+    KEYWORD. The available function is parse_entry.
+    """
+
+    def generate_output_from_template(self):
+        """
+        Generate the output by replacing the keywords and the functions in the
+        template.
+        """
+        FileFromTemplateGenerator.generate_output_from_template(self)
+        self.output_text = self.replace_functions(self.output_text)
+
+    def replace_functions(self, template_string):
+        """
+        Replace the functions in the template string.
+        """
+        result = template_string
+        pattern = "%(.*)\((.*)\)%"
+        matchObj = re.search(pattern, result)
+        while matchObj:
+            (whole_string, func_name, param_keyword) = matchObj.group(0, 1, 2)
+            param_value = self.kw_dict[param_keyword]
+            func = eval(func_name)
+            value = func(param_value)
+            result = result.replace(whole_string, value)
+            matchObj = re.search(pattern, result)
+        return result
+
+def parse_entry(selected_value):
+    """
+    Find entry if selected_value is something like "name (entry)"
+    """
+    entry = selected_value
+    match = re.search("\((.*)\)$", entry)
+    if match is not None:
+        entry = match.group(1)
+    return entry
diff --git a/src/salome_hydro/coupling1d2d/eficas/prefs.py b/src/salome_hydro/coupling1d2d/eficas/prefs.py
new file mode 100644 (file)
index 0000000..ddbb7a1
--- /dev/null
@@ -0,0 +1,18 @@
+#  Copyright (C) 2012-2013 EDF
+#
+#  This file is part of SALOME HYDRO module.
+#
+#  SALOME HYDRO module is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation, either version 3 of the License, or
+#  (at your option) any later version.
+#
+#  SALOME HYDRO module is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with SALOME HYDRO module.  If not, see <http://www.gnu.org/licenses/>.
+
+code = "coupling1d2d"
diff --git a/src/salome_hydro/coupling1d2d/eficas/prefs_coupling1d2d.py b/src/salome_hydro/coupling1d2d/eficas/prefs_coupling1d2d.py
new file mode 100644 (file)
index 0000000..ed30a09
--- /dev/null
@@ -0,0 +1,28 @@
+#  Copyright (C) 2012-2013 EDF
+#
+#  This file is part of SALOME HYDRO module.
+#
+#  SALOME HYDRO module is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation, either version 3 of the License, or
+#  (at your option) any later version.
+#
+#  SALOME HYDRO module is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with SALOME HYDRO module.  If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import sys
+
+repIni = os.path.dirname(__file__)
+INSTALLDIR = os.getenv("EFICAS_ROOT")
+closeAutreCommande=True
+closeFrameRechercheCommande=True
+closeArbre=True
+closeCopier=True
+suiteTelemac=True
+
index e4b3bfd9e5c303405062197cb647ac5b45a7dc96..5bccc2752485d7f46e6046834b1c0716955f88b7 100644 (file)
@@ -14,3 +14,9 @@
 #
 #  You should have received a copy of the GNU General Public License
 #  along with SALOME HYDRO module.  If not, see <http://www.gnu.org/licenses/>.
+
+import mascaret_swig
+
+Mascaret = mascaret_swig.Mascaret
+MascaretFile = mascaret_swig.MascaretFile
+MascaretException = mascaret_swig.MascaretException
index 50f0c43c25654949fa57f7c1c0a69a98e3743e97..db77f20b493e4a6fde07d954569386d640376420 100644 (file)
@@ -19,7 +19,7 @@
 
 from Accas import *
 
-codelist = ("artemis", "estel3d", "postel3d", "sisyphe", "stbtel", "telemac2d", "telemac3d", "tomawac", "mascaret")
+codelist = ("artemis", "estel3d", "postel3d", "sisyphe", "stbtel", "telemac2d", "telemac3d", "tomawac")
 
 JdC = JDC_CATA(regles = (UN_PARMI('PYTEL',)),
                         )
index 550a189ccf373e3b0d4061282b0aa64873e61955..f045f9b77d0a6d93d4b37bc5a0806cfc50280939 100644 (file)
@@ -42,6 +42,10 @@ TELEMAC2D_FILE_TYPE = "TELEMAC2D_EFICAS_FILE"
 TELEMAC2D_ICON = "case2d.png"
 TELEMAC2D_CASE_TYPE_ID = 3
 
+COUPLING1D2D_FILE_TYPE = "COUPLING1D2D_EFICAS_FILE"
+COUPLING1D2D_ICON = "case_couplage.png"
+COUPLING1D2D_CASE_TYPE_ID = 4
+
 PYTEL_FILE_TYPE = "PYTEL_EFICAS_FILE"
 PYTEL_ICON = "case_pytel.png"
 PYTEL_CASE_TYPE_ID = 5
@@ -116,6 +120,45 @@ class HydroStudyEditor:
                                             icon = MASCARET_ICON,
                                             comment = str(filePath),
                                             typeId = MASCARET_CASE_TYPE_ID)
+        # Create "Variables" item
+        (file_list, lig_file, input_vars, output_vars) = self.get_mascaret_params_from_case(sobj)
+        input_varname_list = [var["NOM"].strip() for var in input_vars]
+        # Remove duplicates
+        input_varname_list = list(set(input_varname_list))
+        input_var_list = [study_exchange_vars.Variable(varname) for varname in input_varname_list]
+        output_var_list = [study_exchange_vars.Variable(var["NOM"].strip()) for var in output_vars]
+        exchange_vars = study_exchange_vars.ExchangeVariables(input_var_list, output_var_list)
+        study_exchange_vars.createSObjectForExchangeVariables(sobj, exchange_vars, icon = VARS_ICON)
+
+    def get_mascaret_params_from_case(self, sobj):
+        jdcpath = sobj.GetComment()
+        with open(jdcpath) as jdcfile:
+            jdc = jdcfile.read()
+        params = jdc_to_dict(jdc, ["MASCARET", "_F"])
+        input_vars = get_jdc_dict_var_as_tuple(params, "VARIABLE_ENTREE")
+        output_vars = get_jdc_dict_var_as_tuple(params, "VARIABLE_SORTIE")
+        file_list = []
+        for (key, value) in params.iteritems():
+            if key == "FICHIER_LOI":
+                file_list += [HYDROSOLVER_ORB.MascaretFile(f["NOM"], mascaretFileTypeDict[key]) for f in value]
+            elif key != "FICHIER_LIG" and key != "VARIABLE_SORTIE" and key != "VARIABLE_ENTREE":
+                file_list.append(HYDROSOLVER_ORB.MascaretFile(value, mascaretFileTypeDict[key]))
+        return (file_list, params["FICHIER_LIG"], input_vars, output_vars)
+
+    def add_results_to_mascaret_case(self, sobj, output_variables, output_values):
+        results = self.editor.createItem(sobj, "Results")
+        for (var, value) in zip(output_variables, output_values):
+            self.editor.createItem(results, var, comment = unicode(value))
+
+    def add_coupling_log(self, varname, log):
+        self.find_or_create_hydro_component()
+        sObj = self.editor.createItem(self.hydroComp,
+                                      name = varname,
+                                      icon = LOG_ICON,
+                                      typeId = LOG_TYPE_ID)
+        attr = self.editor.builder.FindOrCreateAttribute(sObj,
+                                                         "AttributeParameter")
+        attr.SetString("log", log)
 
     def find_or_create_telemac2d_case(self, filePath):
         self.find_or_create_hydro_component()
@@ -171,6 +214,17 @@ class HydroStudyEditor:
         # Writting to file
         yacs_scheme.saveSchema(yacs_file)
 
+    def find_or_create_coupling1d2d_case(self, filePath):
+        self.find_or_create_hydro_component()
+        itemName = os.path.splitext(os.path.basename(filePath))[0]
+        sobj = self.editor.findOrCreateItem(self.hydroComp,
+                                            name = itemName,
+                                            fileType = COUPLING1D2D_FILE_TYPE,
+                                            fileName = filePath,
+                                            icon = COUPLING1D2D_ICON,
+                                            comment = str(filePath),
+                                            typeId = COUPLING1D2D_CASE_TYPE_ID)
+
     def find_or_create_pytel_case(self, filePath):
         self.find_or_create_hydro_component()
         itemName = os.path.splitext(os.path.basename(filePath))[0]