## HYDROSOLVER specifics
##
+FIND_PACKAGE(SalomeMascaret REQUIRED)
FIND_PACKAGE(SalomeTelemac REQUIRED)
# Directories
# These files are data, module or lib files
SET(_adm_data
+ FindMascaret.cmake
+ FindSalomeMascaret.cmake
FindTelemac.cmake
FindSalomeTelemac.cmake
)
--- /dev/null
+# 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)
--- /dev/null
+# 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()
TELEMAC_LIBRARY_sisyphe
TELEMAC_LIBRARY_special
TELEMAC_LIBRARY_telemac2d
- TELEMAC_LIBRARY_mascaret
TELEMAC_LIBRARY_tomawac
TELEMAC_LIBRARY_gretel
TELEMAC_LIBRARY_partel
# 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)
TELEMAC_LIBRARY_sisyphe
TELEMAC_LIBRARY_special
TELEMAC_LIBRARY_telemac2d
- TELEMAC_LIBRARY_mascaret
TELEMAC_LIBRARY_tomawac
TELEMAC_LIBRARY_gretel
TELEMAC_LIBRARY_partel
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
{
ADD_SUBDIRECTORY(HYDROGUI)
ADD_SUBDIRECTORY(HYDROTools)
ADD_SUBDIRECTORY(salome_hydro)
+ADD_SUBDIRECTORY(mascaret_wrapper)
# scripts / static
SET(_bin_SCRIPTS
HYDROSOLVER.py
+ MASCARET.py
+ TELEMAC2D.py
)
# --- rules ---
--- /dev/null
+# 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()
--- /dev/null
+# 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))
--- /dev/null
+# 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})
--- /dev/null
+// 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");
+}
+
+}
--- /dev/null
+// 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_ */
--- /dev/null
+// 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"
ADD_SUBDIRECTORY(mascaret)
ADD_SUBDIRECTORY(telemac2d)
ADD_SUBDIRECTORY(pytel)
+ADD_SUBDIRECTORY(coupling1d2d)
ADD_SUBDIRECTORY(boundary_conditions)
# --- Python files ---
--- /dev/null
+# 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)
--- /dev/null
+# 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)
--- /dev/null
+# -*- 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)
--- /dev/null
+# -*- 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
--- /dev/null
+# -*- 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()"
--- /dev/null
+<?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>
--- /dev/null
+# 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
--- /dev/null
+# 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"
--- /dev/null
+# 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
+
#
# 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
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',)),
)
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
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()
# 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]