From: asl Date: Thu, 22 Sep 2016 11:00:36 +0000 (+0300) Subject: the version delivered by EDF X-Git-Tag: v1.6~23 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=6448be82081a8b9a0d95e6f8c8fe72a275416105;p=modules%2Fhydrosolver.git the version delivered by EDF --- 6448be82081a8b9a0d95e6f8c8fe72a275416105 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..24743af --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.svn +.yamm diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..c63864d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,202 @@ +# 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 . + +CMAKE_MINIMUM_REQUIRED(VERSION 2.8.8 FATAL_ERROR) +PROJECT(SalomeHYDROSOLVER CXX) + +# Ensure a proper linker behavior: +CMAKE_POLICY(SET CMP0003 NEW) + +# Versioning +# =========== +# Project name, upper case +STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UC) + +SET(${PROJECT_NAME_UC}_MAJOR_VERSION 0) +SET(${PROJECT_NAME_UC}_MINOR_VERSION 1) +SET(${PROJECT_NAME_UC}_VERSION + ${${PROJECT_NAME_UC}_MAJOR_VERSION}.${${PROJECT_NAME_UC}_MINOR_VERSION}) +SET(${PROJECT_NAME_UC}_VERSION_DEV 1) + +# Find KERNEL +# =========== +SET(KERNEL_ROOT_DIR $ENV{KERNEL_ROOT_DIR} CACHE PATH "Path to the Salome KERNEL") +IF(EXISTS ${KERNEL_ROOT_DIR}) + LIST(APPEND CMAKE_MODULE_PATH "${KERNEL_ROOT_DIR}/salome_adm/cmake_files") + INCLUDE(SalomeMacros) + FIND_PACKAGE(SalomeKERNEL REQUIRED) +ELSE(EXISTS ${KERNEL_ROOT_DIR}) + MESSAGE(FATAL_ERROR "We absolutely need a Salome KERNEL, please define KERNEL_ROOT_DIR") +ENDIF(EXISTS ${KERNEL_ROOT_DIR}) + +# Platform setup +# ============== +INCLUDE(SalomeSetupPlatform) # From KERNEL +# Always build libraries as shared objects: +SET(BUILD_SHARED_LIBS TRUE) +# Local macros: +LIST(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/adm_local/cmake_files") + +# User options +# ============ +OPTION(SALOME_BUILD_DOC "Generate SALOME HYDROSOLVER documentation" ON) +#OPTION(SALOME_BUILD_TESTS "Build SALOME tests" ON) #for use in the future + +#IF(SALOME_BUILD_TESTS) +# ENABLE_TESTING() +#ENDIF() + +## +## From KERNEL: +## +FIND_PACKAGE(SalomePythonInterp REQUIRED) +FIND_PACKAGE(SalomePythonLibs REQUIRED) +FIND_PACKAGE(SalomeOmniORB REQUIRED) +FIND_PACKAGE(SalomeOmniORBPy REQUIRED) +FIND_PACKAGE(SalomeSWIG REQUIRED) + +# Med and Hdf5 are second order dependencies (deps for Telemac) but since Telemac libraries +# are not linked against them, we need to include them here for the Telemac wrapper +FIND_PACKAGE(SalomeMEDFile REQUIRED) +FIND_PACKAGE(SalomeHDF5 REQUIRED) + +IF(SALOME_BUILD_DOC) + FIND_PACKAGE(SalomeSphinx REQUIRED) +ENDIF() + +# Find GUI +# =========== +SET(GUI_ROOT_DIR $ENV{GUI_ROOT_DIR} CACHE PATH "Path to the Salome GUI") +IF(EXISTS ${GUI_ROOT_DIR}) + LIST(APPEND CMAKE_MODULE_PATH "${GUI_ROOT_DIR}/adm_local/cmake_files") + FIND_PACKAGE(SalomeGUI REQUIRED) + ADD_DEFINITIONS(${GUI_DEFINITIONS}) + INCLUDE_DIRECTORIES(${GUI_INCLUDE_DIRS}) +ELSE(EXISTS ${GUI_ROOT_DIR}) + MESSAGE(FATAL_ERROR "We absolutely need a Salome GUI, please define GUI_ROOT_DIR") +ENDIF(EXISTS ${GUI_ROOT_DIR}) + +## +## From GUI: +## +FIND_PACKAGE(SalomePyQt4 REQUIRED) + +## +## HYDROSOLVER specifics +## + +FIND_PACKAGE(SalomeMascaret REQUIRED) +FIND_PACKAGE(SalomeTelemac REQUIRED) + +# Directories +# (default values taken from KERNEL) +# =========== +SET(SALOME_INSTALL_BINS "${SALOME_INSTALL_BINS}" CACHE PATH "Install path: SALOME binaries") +SET(SALOME_INSTALL_LIBS "${SALOME_INSTALL_LIBS}" CACHE PATH "Install path: SALOME libs") +SET(SALOME_INSTALL_IDLS "${SALOME_INSTALL_IDLS}" CACHE PATH "Install path: SALOME IDL files") +SET(SALOME_INSTALL_HEADERS "${SALOME_INSTALL_HEADERS}" CACHE PATH "Install path: SALOME headers") +SET(SALOME_INSTALL_SCRIPT_SCRIPTS "${SALOME_INSTALL_SCRIPT_SCRIPTS}" CACHE PATH + "Install path: SALOME scripts") +SET(SALOME_INSTALL_SCRIPT_DATA "${SALOME_INSTALL_SCRIPT_DATA}" CACHE PATH + "Install path: SALOME script data") +SET(SALOME_INSTALL_SCRIPT_PYTHON "${SALOME_INSTALL_SCRIPT_PYTHON}" CACHE PATH + "Install path: SALOME Python scripts") +SET(SALOME_INSTALL_APPLISKEL_SCRIPTS "${SALOME_INSTALL_APPLISKEL_SCRIPTS}" CACHE PATH + "Install path: SALOME application skeleton - scripts") +SET(SALOME_INSTALL_APPLISKEL_PYTHON "${SALOME_INSTALL_APPLISKEL_PYTHON}" CACHE PATH + "Install path: SALOME application skeleton - Python") +SET(SALOME_INSTALL_PYTHON "${SALOME_INSTALL_PYTHON}" CACHE PATH "Install path: SALOME Python stuff") +SET(SALOME_INSTALL_PYTHON_SHARED "${SALOME_INSTALL_PYTHON_SHARED}" CACHE PATH + "Install path: SALOME Python shared modules") +SET(SALOME_INSTALL_CMAKE_LOCAL "${SALOME_INSTALL_CMAKE_LOCAL}" CACHE PATH + "Install path: local SALOME CMake files") +SET(SALOME_INSTALL_AMCONFIG_LOCAL "${SALOME_INSTALL_AMCONFIG_LOCAL}" CACHE PATH + "Install path: local SALOME config files (obsolete, to be removed)") +SET(SALOME_INSTALL_RES "${SALOME_INSTALL_RES}" CACHE PATH "Install path: SALOME resources") +SET(SALOME_INSTALL_DOC "${SALOME_INSTALL_DOC}" CACHE PATH "Install path: SALOME documentation") + +# HYDROSOLVER specific: +SET(SALOME_HYDROSOLVER_INSTALL_RES_DATA "${SALOME_INSTALL_RES}/hydrosolver" CACHE PATH "Install path: SALOME HYDROSOLVER specific data") +SET(SALOME_HYDROSOLVER_INSTALL_DOC "${SALOME_INSTALL_DOC}/gui/HYDROSOLVER" CACHE PATH "Install path: SALOME HYDROSOLVER doc") + +MARK_AS_ADVANCED(SALOME_INSTALL_BINS SALOME_INSTALL_LIBS SALOME_INSTALL_IDLS SALOME_INSTALL_HEADERS) +MARK_AS_ADVANCED(SALOME_INSTALL_SCRIPT_SCRIPTS SALOME_INSTALL_SCRIPT_DATA SALOME_INSTALL_SCRIPT_PYTHON) +MARK_AS_ADVANCED(SALOME_INSTALL_APPLISKEL_SCRIPTS SALOME_INSTALL_APPLISKEL_PYTHON SALOME_INSTALL_CMAKE_LOCAL SALOME_INSTALL_RES) +MARK_AS_ADVANCED(SALOME_INSTALL_PYTHON SALOME_INSTALL_PYTHON_SHARED) +MARK_AS_ADVANCED(SALOME_INSTALL_AMCONFIG_LOCAL SALOME_INSTALL_DOC) +MARK_AS_ADVANCED(SALOME_HYDROSOLVER_INSTALL_RES_DATA SALOME_HYDROSOLVER_INSTALL_DOC) + +# Accumulate environment variables for HYDROSOLVER module +SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH NOCHECK ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_BINS}) +SALOME_ACCUMULATE_ENVIRONMENT(LD_LIBRARY_PATH NOCHECK ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_LIBS}) + +# Sources +# ======== + +ADD_SUBDIRECTORY(adm_local) +ADD_SUBDIRECTORY(resources) +ADD_SUBDIRECTORY(src) +ADD_SUBDIRECTORY(idl) +IF(SALOME_BUILD_DOC) + ADD_SUBDIRECTORY(doc) +ENDIF() + +# Configuration export +# (here only the level 1 prerequisites are exposed) +# ==================== +INCLUDE(CMakePackageConfigHelpers) + +# List of targets in this project we want to make visible to the rest of the world. +# They all have to be INSTALL'd with the option "EXPORT ${PROJECT_NAME}TargetGroup" +SET(_${PROJECT_NAME}_exposed_targets + SalomeIDLHYDROSOLVER +) + +# Add all targets to the build-tree export set +EXPORT(TARGETS ${_${PROJECT_NAME}_exposed_targets} + FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake) + +# Create the configuration files: +# - in the build tree: + +# Ensure the variables are always defined for the configure: +SET(GUI_ROOT_DIR "${GUI_ROOT_DIR}") + +SET(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/include" "${PROJECT_BINARY_DIR}/include") + +# Build variables that will be expanded when configuring SalomeConfig.cmake: +# SALOME_CONFIGURE_PREPARE() #For use in the future + +CONFIGURE_PACKAGE_CONFIG_FILE(${PROJECT_NAME}Config.cmake.in + ${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake + INSTALL_DESTINATION "${SALOME_INSTALL_CMAKE_LOCAL}" + PATH_VARS CONF_INCLUDE_DIRS SALOME_INSTALL_CMAKE_LOCAL CMAKE_INSTALL_PREFIX + GUI_ROOT_DIR) + +WRITE_BASIC_PACKAGE_VERSION_FILE(${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake + VERSION ${${PROJECT_NAME_UC}_VERSION} + COMPATIBILITY AnyNewerVersion) + +# Install the CMake configuration files: +INSTALL(FILES + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + DESTINATION "${SALOME_INSTALL_CMAKE_LOCAL}") + +# Install the export set for use with the install-tree +INSTALL(EXPORT ${PROJECT_NAME}TargetGroup DESTINATION "${SALOME_INSTALL_CMAKE_LOCAL}" + FILE ${PROJECT_NAME}Targets.cmake) diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program 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. + + This program 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 this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/SalomeHYDROSOLVERConfig.cmake.in b/SalomeHYDROSOLVERConfig.cmake.in new file mode 100644 index 0000000..defa109 --- /dev/null +++ b/SalomeHYDROSOLVERConfig.cmake.in @@ -0,0 +1,109 @@ +# - Config file for the @PROJECT_NAME@ package +# It defines the following variables. +# Specific to the package @PROJECT_NAME@ itself: +# @PROJECT_NAME_UC@_ROOT_DIR_EXP - the root path of the installation providing this CMake file +# + +############################################################### +# 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 . +############################################################### + +### Initialisation performed by CONFIGURE_PACKAGE_CONFIG_FILE: +@PACKAGE_INIT@ + +# Load the dependencies for the libraries of @PROJECT_NAME@ +# (contains definitions for IMPORTED targets). This is only +# imported if we are not built as a subproject (in this case targets are already there) +IF(NOT TARGET SalomeIDLHYDROSOLVER AND NOT @PROJECT_NAME@_BINARY_DIR) + INCLUDE("@PACKAGE_SALOME_INSTALL_CMAKE_LOCAL@/@PROJECT_NAME@Targets.cmake") +ENDIF() + +# Package root dir: +SET_AND_CHECK(HYDROSOLVER_ROOT_DIR_EXP "@PACKAGE_CMAKE_INSTALL_PREFIX@") + +# Include directories +SET_AND_CHECK(HYDROSOLVER_INCLUDE_DIRS "${HYDROSOLVER_ROOT_DIR_EXP}/@SALOME_INSTALL_HEADERS@") +SET(HYDROSOLVER_INCLUDE_DIRS "${HYDROSOLVER_INCLUDE_DIRS};@_SalomeHYDROSOLVER_EXTRA_HEADERS@") +SET(HYDROSOLVER_DEFINITIONS "@GUI_DEFINITIONS@") + +# Package specific environment variables +@_SalomeHYDROSOLVER_EXTRA_ENV_FULL@ + +#### Now the specificities + +# Options exported by the package: +SET(SALOME_HYDROSOLVER_BUILD_DOC @SALOME_BUILD_DOC@) +#SET(SALOME_HYDROSOLVER_BUILD_TESTS @SALOME_BUILD_TESTS@) +SET(SALOME_LIGHT_ONLY @SALOME_LIGHT_ONLY@) + +# Level 1 prerequisites: +SET_AND_CHECK(GUI_ROOT_DIR_EXP "@PACKAGE_GUI_ROOT_DIR@") + +# For all prerequisites, load the corresponding targets if the package was used +# in CONFIG mode. This ensures dependent projects link correctly +# without having to set LD_LIBRARY_PATH: +SET(_PREREQ @_PREREQ_LIST@) +SET(_PREREQ_CONFIG_DIR @_PREREQ_DIR_LIST@) +SET(_PREREQ_COMPONENTS "@_PREREQ_COMPO_LIST@") +LIST(LENGTH _PREREQ_CONFIG_DIR _list_len) +IF(NOT _list_len EQUAL 0) + # Another CMake stupidity - FOREACH(... RANGE r) generates r+1 numbers ... + MATH(EXPR _range "${_list_len}-1") + FOREACH(_p RANGE ${_range}) + LIST(GET _PREREQ ${_p} _pkg ) + LIST(GET _PREREQ_CONFIG_DIR ${_p} _pkg_dir) + LIST(GET _PREREQ_COMPONENTS ${_p} _pkg_compo) + MESSAGE(STATUS "===> Reloading targets from ${_pkg} ...") + IF(NOT _pkg_compo) + FIND_PACKAGE(${_pkg} REQUIRED NO_MODULE + PATHS "${_pkg_dir}" + NO_DEFAULT_PATH) + ELSE() + STRING(REPLACE "," ";" _compo_lst "${_pkg_compo}") + MESSAGE(STATUS "===> (components: ${_pkg_compo})") + FIND_PACKAGE(${_pkg} REQUIRED NO_MODULE + COMPONENTS ${_compo_lst} + PATHS "${_pkg_dir}" + NO_DEFAULT_PATH) + ENDIF() + ENDFOREACH() +ENDIF() + +# Installation directories +SET(SALOME_INSTALL_BINS "@SALOME_INSTALL_BINS@") +SET(SALOME_INSTALL_LIBS "@SALOME_INSTALL_LIBS@") +SET(SALOME_INSTALL_HEADERS "@SALOME_INSTALL_HEADERS@") +SET(SALOME_INSTALL_SCRIPT_SCRIPTS "@SALOME_INSTALL_SCRIPT_SCRIPTS@") +SET(SALOME_INSTALL_SCRIPT_DATA "@SALOME_INSTALL_SCRIPT_DATA@") +SET(SALOME_INSTALL_SCRIPT_PYTHON "@SALOME_INSTALL_SCRIPT_PYTHON@") +SET(SALOME_INSTALL_APPLISKEL_SCRIPTS "@SALOME_INSTALL_APPLISKEL_SCRIPTS@") +SET(SALOME_INSTALL_APPLISKEL_PYTHON "@SALOME_INSTALL_APPLISKEL_PYTHON@") +SET(SALOME_INSTALL_CMAKE_LOCAL "@SALOME_INSTALL_CMAKE_LOCAL@") +SET(SALOME_INSTALL_PYTHON "@SALOME_INSTALL_PYTHON@") +SET(SALOME_INSTALL_PYTHON_SHARED "@SALOME_INSTALL_PYTHON_SHARED@") +SET(SALOME_INSTALL_RES "@SALOME_INSTALL_RES@") +SET(SALOME_INSTALL_DOC "@SALOME_INSTALL_DOC@") +SET(SALOME_INSTALL_AMCONFIG_LOCAL "@SALOME_INSTALL_AMCONFIG_LOCAL@") + +# Include GUI targets if they were not already loaded: +IF(NOT (TARGET Event)) + INCLUDE("${GUI_ROOT_DIR_EXP}/${SALOME_INSTALL_CMAKE_LOCAL}/SalomeGUITargets.cmake") +ENDIF() + +# Exposed HYDROSOLVER targets: +SET(HYDROSOLVER_SalomeIDLHYDROSOLVER SalomeIDLHYDROSOLVER) diff --git a/adm_local/CMakeLists.txt b/adm_local/CMakeLists.txt new file mode 100644 index 0000000..bfc3c0f --- /dev/null +++ b/adm_local/CMakeLists.txt @@ -0,0 +1,18 @@ +# Copyright (C) 2012-2013 EDF +# +# This file is part of SALOME HYDRO module. +# +# SALOME HYDRO module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SALOME HYDRO module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SALOME HYDRO module. If not, see . + +ADD_SUBDIRECTORY(cmake_files) diff --git a/adm_local/cmake_files/CMakeLists.txt b/adm_local/cmake_files/CMakeLists.txt new file mode 100644 index 0000000..4051084 --- /dev/null +++ b/adm_local/cmake_files/CMakeLists.txt @@ -0,0 +1,29 @@ +# 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 . + +# =============================================================== +# Files to be installed +# =============================================================== + +# These files are data, module or lib files +SET(_adm_data + FindMascaret.cmake + FindSalomeMascaret.cmake + FindTelemac.cmake + FindSalomeTelemac.cmake +) +INSTALL(FILES ${_adm_data} DESTINATION ${SALOME_INSTALL_CMAKE_LOCAL}) diff --git a/adm_local/cmake_files/FindMascaret.cmake b/adm_local/cmake_files/FindMascaret.cmake new file mode 100644 index 0000000..1602e88 --- /dev/null +++ b/adm_local/cmake_files/FindMascaret.cmake @@ -0,0 +1,23 @@ +# Copyright (C) 2012-2013 EDF +# +# This file is part of SALOME HYDRO module. +# +# SALOME HYDRO module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SALOME HYDRO module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SALOME HYDRO module. If not, see . + +FIND_LIBRARY(MASCARET_LIBRARIES mascaret) +FIND_PATH(MASCARET_INCLUDE_DIR apimascaret.h) + +# Handle the standard arguments of the find_package() command: +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Mascaret REQUIRED_VARS MASCARET_LIBRARIES MASCARET_INCLUDE_DIR) diff --git a/adm_local/cmake_files/FindSalomeMascaret.cmake b/adm_local/cmake_files/FindSalomeMascaret.cmake new file mode 100644 index 0000000..fa7c5ce --- /dev/null +++ b/adm_local/cmake_files/FindSalomeMascaret.cmake @@ -0,0 +1,28 @@ +# Copyright (C) 2012-2013 EDF +# +# This file is part of SALOME HYDRO module. +# +# SALOME HYDRO module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SALOME HYDRO module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SALOME HYDRO module. If not, see . + +# 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() diff --git a/adm_local/cmake_files/FindSalomeTelemac.cmake b/adm_local/cmake_files/FindSalomeTelemac.cmake new file mode 100644 index 0000000..291809c --- /dev/null +++ b/adm_local/cmake_files/FindSalomeTelemac.cmake @@ -0,0 +1,38 @@ +# 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 . + +# Telemac detection for Salome +# +# !! Please read the generic detection procedure in SalomeMacros.cmake !! +# +SALOME_FIND_PACKAGE_AND_DETECT_CONFLICTS(Telemac TELEMAC_ROOT_DIR 0) +MARK_AS_ADVANCED(TELEMAC_LIBRARY_api_telemac2d + TELEMAC_LIBRARY_bief + TELEMAC_LIBRARY_damocles + TELEMAC_LIBRARY_parallel + TELEMAC_LIBRARY_sisyphe + TELEMAC_LIBRARY_special + TELEMAC_LIBRARY_telemac2d + TELEMAC_LIBRARY_tomawac + TELEMAC_LIBRARIES + TELEMAC_INCLUDE_DIR + TELEMAC_API_SRC_DIR) + +IF(Telemac_FOUND OR TELEMAC_FOUND) + SALOME_ACCUMULATE_HEADERS(TELEMAC_INCLUDE_DIR) + SALOME_ACCUMULATE_ENVIRONMENT(LD_LIBRARY_PATH ${TELEMAC_LIBRARIES}) +ENDIF() diff --git a/adm_local/cmake_files/FindTelemac.cmake b/adm_local/cmake_files/FindTelemac.cmake new file mode 100644 index 0000000..2a24e19 --- /dev/null +++ b/adm_local/cmake_files/FindTelemac.cmake @@ -0,0 +1,77 @@ +# 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 . + +FIND_LIBRARY(TELEMAC_LIBRARY_api_telemac2d api_telemac2d + PATHS ${TELEMAC_ROOT_DIR}/wrap_api/lib) +FIND_LIBRARY(TELEMAC_LIBRARY_bief bief + PATHS ${TELEMAC_ROOT_DIR}/wrap_api/lib) +FIND_LIBRARY(TELEMAC_LIBRARY_damocles damocles + PATHS ${TELEMAC_ROOT_DIR}/wrap_api/lib) +FIND_LIBRARY(TELEMAC_LIBRARY_parallel parallel + PATHS ${TELEMAC_ROOT_DIR}/wrap_api/lib) +FIND_LIBRARY(TELEMAC_LIBRARY_sisyphe sisyphe + PATHS ${TELEMAC_ROOT_DIR}/wrap_api/lib) +FIND_LIBRARY(TELEMAC_LIBRARY_special special + PATHS ${TELEMAC_ROOT_DIR}/wrap_api/lib) +FIND_LIBRARY(TELEMAC_LIBRARY_telemac2d telemac2d + PATHS ${TELEMAC_ROOT_DIR}/wrap_api/lib) +FIND_LIBRARY(TELEMAC_LIBRARY_tomawac tomawac + PATHS ${TELEMAC_ROOT_DIR}/wrap_api/lib) +# FIND_LIBRARY(TELEMAC_LIBRARY_gretel gretel +# PATHS ${TELEMAC_ROOT_DIR}/wrap_api/lib) +# FIND_LIBRARY(TELEMAC_LIBRARY_partel partel +# PATHS ${TELEMAC_ROOT_DIR}/wrap_api/lib) +FIND_LIBRARY(TELEMAC_LIBRARY_hermes hermes + PATHS ${TELEMAC_ROOT_DIR}/wrap_api/lib) +IF(NOT EXISTS ${TELEMAC_LIBRARY_hermes}) + MESSAGE("Warning: ${TELEMAC_LIBRARY_hermes} does not exist") + SET(TELEMAC_LIBRARY_hermes "") +ENDIF() +FIND_PATH(TELEMAC_INCLUDE_DIR interface_telemac2d.mod + PATHS ${TELEMAC_ROOT_DIR}/wrap_api/include) +FIND_PATH(TELEMAC_API_SRC_DIR api_interface_t2d.f90 + PATHS ${TELEMAC_ROOT_DIR}/wrap_api/src) + +# The order of the libraries is important for the API wrapper compilation +SET(TELEMAC_LIBRARIES ${TELEMAC_LIBRARY_api_telemac2d} + ${TELEMAC_LIBRARY_gretel} + ${TELEMAC_LIBRARY_partel} + ${TELEMAC_LIBRARY_telemac2d} + ${TELEMAC_LIBRARY_sisyphe} + ${TELEMAC_LIBRARY_tomawac} + ${TELEMAC_LIBRARY_bief} + ${TELEMAC_LIBRARY_hermes} + ${TELEMAC_LIBRARY_parallel} + ${TELEMAC_LIBRARY_damocles} + ${TELEMAC_LIBRARY_special} + ) + +# Handle the standard arguments of the find_package() command: +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Telemac REQUIRED_VARS TELEMAC_LIBRARY_api_telemac2d + TELEMAC_LIBRARY_bief + TELEMAC_LIBRARY_damocles + TELEMAC_LIBRARY_parallel + TELEMAC_LIBRARY_sisyphe + TELEMAC_LIBRARY_special + TELEMAC_LIBRARY_telemac2d + TELEMAC_LIBRARY_tomawac +# TELEMAC_LIBRARY_gretel +# TELEMAC_LIBRARY_partel + #TELEMAC_LIBRARY_hermes # Optional + TELEMAC_INCLUDE_DIR + TELEMAC_API_SRC_DIR) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt new file mode 100644 index 0000000..d3de777 --- /dev/null +++ b/doc/CMakeLists.txt @@ -0,0 +1,47 @@ +# 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 . + +SET(RSTFILES + index.rst + basic.rst + advanced.rst +) + +SET(SPHINXOPTS ) +SET(SOURCEDIR ${CMAKE_CURRENT_SOURCE_DIR}) +SET(PAPEROPT_a4 -D latex_paper_size=a4) +SET(ALLSPHINXOPTS -d doctrees ${PAPEROPT_a4} ${SPHINXOPTS} ${SOURCEDIR}) + +# install user's documentation + +SALOME_CONFIGURE_FILE(conf.py.in conf.py) + +SET(HTML_ROOT_FILE html/index.html) + +ADD_CUSTOM_COMMAND(OUTPUT ${HTML_ROOT_FILE} + COMMAND ${CMAKE_COMMAND} -E make_directory html + COMMAND ${CMAKE_COMMAND} -E make_directory doctrees + COMMAND ${SPHINX_EXECUTABLE} -c ${CMAKE_BINARY_DIR}/doc -b html ${ALLSPHINXOPTS} html + DEPENDS ${RSTFILES} +) + +ADD_CUSTOM_TARGET(BUILD_HTML ALL DEPENDS ${HTML_ROOT_FILE}) + +INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/ + DESTINATION ${SALOME_HYDROSOLVER_INSTALL_DOC} + PATTERN ".buildinfo" EXCLUDE +) diff --git a/doc/_static/HYDRO.png b/doc/_static/HYDRO.png new file mode 100644 index 0000000..15e3729 --- /dev/null +++ b/doc/_static/HYDRO.png @@ -0,0 +1 @@ +../../resources/HYDRO.png \ No newline at end of file diff --git a/doc/_static/create_case1d.png b/doc/_static/create_case1d.png new file mode 100644 index 0000000..e7877ae --- /dev/null +++ b/doc/_static/create_case1d.png @@ -0,0 +1 @@ +../../resources/create_case1d.png \ No newline at end of file diff --git a/doc/_static/create_case2d.png b/doc/_static/create_case2d.png new file mode 100644 index 0000000..8f428b4 --- /dev/null +++ b/doc/_static/create_case2d.png @@ -0,0 +1 @@ +../../resources/create_case2d.png \ No newline at end of file diff --git a/doc/_static/create_case_couplage.png b/doc/_static/create_case_couplage.png new file mode 100644 index 0000000..e0d2ce2 --- /dev/null +++ b/doc/_static/create_case_couplage.png @@ -0,0 +1 @@ +../../resources/create_case_couplage.png \ No newline at end of file diff --git a/doc/_static/create_case_pytel.png b/doc/_static/create_case_pytel.png new file mode 100644 index 0000000..cfda381 --- /dev/null +++ b/doc/_static/create_case_pytel.png @@ -0,0 +1 @@ +../../resources/create_case_pytel.png \ No newline at end of file diff --git a/doc/advanced.rst b/doc/advanced.rst new file mode 100644 index 0000000..dd8589f --- /dev/null +++ b/doc/advanced.rst @@ -0,0 +1,125 @@ +.. + 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 . + + +#################### +Advanced usage guide +#################### + +Code coupling +============= + +.. |run_coupling_button| image:: /_static/create_case_couplage.png + :align: middle + +Salome-Hydro offers a service to run coupled Mascaret - Telemac2D cases. First, +you need to create a Mascaret case and a Telemac2D API case. Then, to set up +the coupling, click on the button |run_coupling_button|. A new dialog appears +(the *Eficas* interface) that let you choose the Mascaret and Telemac2D cases, +an output file for the coupling log and another one in CSV format for graph +generation. You must also specify a file to describe the coupling itself. This +file must be a Python file declaring several variables. Here is an example of +such a file:: + + # Time data + # Note that Telemac2D API can't use those values for now, so T2D case must be adapted manually + starttime = 0.0 + endtime = 270300.0 + timestep = 10.0 + + # Tolerances for convergence iterations + eps_Q = 1.0 + eps_Z = 0.01 + + # Maximum number of convergence iterations + maxiter = 5 + + # Border descriptions + upstream_border_mascaret = {"code": "MASCARET", + "position": "upstream", + "section_id": 40, + "loi_id": 2} + + upstream_border_telemac = {"code": "TELEMAC2D", + "position": "downstream", + "points_id": (1, 30), # First point included, last point excluded + "border_id": 1} + + downstream_border_telemac = {"code": "TELEMAC2D", + "position": "upstream", + "points_id": (139, 154), # First point included, last point excluded + "border_id": 3} + + downstream_border_mascaret = {"code": "MASCARET", + "position": "downstream", + "section_id": 41, + "loi_id": 3} + + barrage_border_telemac = {"code": "TELEMAC2D", + "position": "upstream", + "points_id": (82, 101), # First point included, last point excluded + "border_id": 2} + + source_mascaret = {"code": "MASCARET", + "position": "downstream", + "section_id": 1, + "loi_id": 1} + + aval_mascaret = {"code": "MASCARET", + "position": "upstream", + "section_id": 79, + "loi_id": 4} + + borders = [{"name": "amont", + "model1": upstream_border_mascaret, + "model2": upstream_border_telemac}, + {"name": "ecluse", + "model1": downstream_border_telemac, + "model2": downstream_border_mascaret}, + {"name": "barrage", + "model1": barrage_border_telemac, + "model2": None}, + {"name": "source", + "model1": source_mascaret, + "model2": None}, + {"name": "aval", + "model1": aval_mascaret, + "model2": None}] + +In this file, the coupling points (borders) are described by their two adjacent +models, represented by a Python dictionary. In this description, the parameter +"code" indicates which code is used on this side of the border (MASCARET or +TELEMAC2D). The parameter "position" indicates if it is on the upstream or +downstream side of the border. + +The parameter "section_id" for MASCARET indicates the section identifiant of the +coupled point. The parameter "loi_id" for MASCARET indicates the identifiant of +the law used to set values on that point. + +The parameter "points_id" for TELEMAC2D indicates the first and last point of +the border. The parameter "border_id" identifies the liquid boundary. + +When all the desired files are selected, save this coupling description file. It +will appear in Salome object browser. Right-click on the item in the object +browser and select "Open schema in YACS" in the popup menu. YACS interface will +open and show the coupling schema. You can then launch the schema execution +directly in YACS (see YACS documentation for more information about launching +or editing the schema directly). + +**Note**: In case of a crash or errors, check your */tmp* directory to find log +files. diff --git a/doc/basic.rst b/doc/basic.rst new file mode 100644 index 0000000..69df011 --- /dev/null +++ b/doc/basic.rst @@ -0,0 +1,95 @@ +.. + 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 . + + +############ +Simple Usage +############ + +Running a Telemac case +====================== + +.. |run_pytel_button| image:: /_static/create_case_pytel.png + :align: middle + +To run a Telemac case from Salome-Hydro, activate HydroSolver module and click +on the button |run_pytel_button|. A new dialog appears (the *Eficas* interface) +that let you choose the case file, dictionary, geometry file, etc. When all the +desired files are selected, save this case description file. It will appear in +Salome object browser. Right-click on the item in the object browser and select +"Compute case" in the popup menu. Telemac will start the computation and the +execution log will be shown in a terminal. + +**Note**: In case of a crash or errors, check your */tmp* directory to find log +files. + +**Warning**: If you use the *Universal* distribution of Salome-Hydro on a +platform that does not include gfortran 4.4.5 or a compatible version, you will +not be able to use a user fortran file with your Telemac case. + +Running a Telemac 2D case with the API +====================================== + +.. |create_t2d_api_button| image:: /_static/create_case2d.png + :align: middle + +To run a Telemac 2D case through the TELEMAC2D API from Salome-Hydro, activate +HydroSolver module and click on the button |create_t2d_api_button|. A new +dialog appears that let you choose the case file, dictionary, geometry file, +etc. When all the desired files are selected, save this case description file. +It will appear in Salome object browser. Right-click on the item in the object +browser and select "Compute case" in the popup menu. Telemac will start the +computation. + +**Note**: Nothing is shown in the interface for now with this service. Check +your */tmp* directory to find log files. + +**Warning**: If you use the *Universal* distribution of Salome-Hydro on a +platform that does not include gfortran 4.4.5 or a compatible version, you will +not be able to use a user fortran file with your Telemac 2D case. + +**Warning**: Due to a remaining bug, it is mandatory with this service to have a +*CONFIG* file in the same directory as the case file, containing the +declarations for *LU* and *LNG* variables. + +Running a Mascaret case +======================= + +.. |create_mascaret_button| image:: /_static/create_case1d.png + :align: middle + +To run a Mascaret case from Salome-Hydro, activate HydroSolver module and click +on the button |create_mascaret_button|. A new dialog appears that let you +choose the case file, dictionary, geometry file, etc. You can also add several +output variables with the parameter "VARIABLE_SORTIE". The name ("NOM") is +free, but the Mascaret variable ("VARIABLE_MASCARET") must use a specific +syntax inspired by Mascaret API. This syntax is +*Type.NomVar.SubVar(idx1, idx2, idx3)*, where *Type* is "Etat" or "Modele", +*NomVar* and *SubVar* are variables names (*SubVar* is not necessary for all +variables), and *idxX* are indexes if the variable is an array. For instance, +*Etat.Z(1,0,0)* is the water heigth on the first section of the model. + +When all the desired files are selected, save this case description file. It +will appear in Salome object browser. Right-click on the item in the object +browser and select "Compute case" in the popup menu. Mascaret will start the +computation of the case. Unfortunately, Mascaret logs are not available yet +through Mascaret API, so the only output available is the value of the +specified output variables. + +**Note**: In case of a crash or errors, check your */tmp* directory to find log +files. diff --git a/doc/conf.py.in b/doc/conf.py.in new file mode 100644 index 0000000..201288e --- /dev/null +++ b/doc/conf.py.in @@ -0,0 +1,212 @@ +# -*- 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 . + + +# HYDROSOLVER module documentation build configuration file, created by +# sphinx-quickstart. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.append(os.path.abspath('.')) + +# -- General configuration ----------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +#extensions = ['sphinx.ext.extlinks'] + +# Add any paths that contain templates here, relative to this directory. +#templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'HydroSolver module' +copyright = u'2012-2013, EDF' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '@SALOMEHYDROSOLVER_VERSION@' +# The full version, including alpha/beta/rc tags. +release = '@SALOMEHYDROSOLVER_VERSION@' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of documents that shouldn't be included in the build. +#unused_docs = [] + +# List of directories, relative to source directory, that shouldn't be searched +# for source files. +#exclude_trees = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. Major themes that come with +# Sphinx are currently 'default' and 'sphinxdoc'. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_use_modindex = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = '' + +# Output file base name for HTML help builder. +#htmlhelp_basename = 'HYDROSOLVERmoduledoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +# The paper size ('letter' or 'a4'). +#latex_paper_size = 'letter' + +# The font size ('10pt', '11pt' or '12pt'). +#latex_font_size = '10pt' + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +#latex_documents = [ +# ('index', 'HYDROSOLVERmodule.tex', u'HYDROSOLVER module Documentation', +# u'EDF R&D', 'manual'), +#] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# Additional stuff for the LaTeX preamble. +#latex_preamble = '' + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_use_modindex = True diff --git a/doc/index.rst b/doc/index.rst new file mode 100644 index 0000000..5fcd313 --- /dev/null +++ b/doc/index.rst @@ -0,0 +1,40 @@ +.. + 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 . + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +HydroSolver module documentation +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +.. |hydrosolver_module_button| image:: /_static/HYDRO.png + :align: middle + :width: 16pt + :height: 16pt + +This documentation covers the usage of HydroSolver module in Salome. This module +aims at providing services for the usage of Telemac and Mascaret codes. To +activate this module, click on the |hydrosolver_module_button| button in the +toolbar or select "HydroSolver" item in the "SALOME" menu. The first part of +this guide addresses simple use cases (how to run the codes from Salome-Hydro +platform) while the second part presents more advanced topics (code coupling). + +.. toctree:: + :maxdepth: 2 + + basic.rst + advanced.rst diff --git a/idl/CMakeLists.txt b/idl/CMakeLists.txt new file mode 100644 index 0000000..deb544c --- /dev/null +++ b/idl/CMakeLists.txt @@ -0,0 +1,39 @@ +# Copyright (C) 2012-2013 EDF +# +# This file is part of SALOME HYDRO module. +# +# SALOME HYDRO module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SALOME HYDRO module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SALOME HYDRO module. If not, see . + +INCLUDE(UseOmniORB) # Provided by KERNEL + +INCLUDE_DIRECTORIES( + ${OMNIORB_INCLUDE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${KERNEL_INCLUDE_DIRS} +) + +SET(SalomeIDLHYDROSOLVER_IDLSOURCES + HYDROSOLVER.idl +) + +SET(_idl_include_dirs + ${KERNEL_ROOT_DIR}/idl/salome +) + +SET(_idl_link_flags + ${KERNEL_SalomeIDLKernel} +) + +OMNIORB_ADD_MODULE(SalomeIDLHYDROSOLVER "${SalomeIDLHYDROSOLVER_IDLSOURCES}" "${_idl_include_dirs}" "${_idl_link_flags}") +INSTALL(TARGETS SalomeIDLHYDROSOLVER EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS}) diff --git a/idl/HYDROSOLVER.idl b/idl/HYDROSOLVER.idl new file mode 100644 index 0000000..77065ce --- /dev/null +++ b/idl/HYDROSOLVER.idl @@ -0,0 +1,213 @@ +// 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 . + +#ifndef _HYDROSOLVER_IDL_ +#define _HYDROSOLVER_IDL_ + +#include "DSC_Engines.idl" +#include "SALOMEDS.idl" +#include "SALOME_Exception.idl" +#include "SALOME_Component.idl" +#include "SALOME_Comm.idl" +#include "SALOME_Parametric.idl" + + + +module HYDROSOLVER_ORB +{ + struct MascaretFile { + string fileName; + string fileType; + }; + + typedef sequence MascaretFileList; + + typedef sequence stringvec; + typedef sequence 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 + { + + }; + +}; + +#endif diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt new file mode 100644 index 0000000..59a9e8e --- /dev/null +++ b/resources/CMakeLists.txt @@ -0,0 +1,39 @@ +# Copyright (C) 2012-2013 EDF +# +# This file is part of SALOME HYDRO module. +# +# SALOME HYDRO module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SALOME HYDRO module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SALOME HYDRO module. If not, see . + +SET(HYDROSOLVER_RESOURCES_FILES + HYDROSOLVERCatalog.xml + icon_variables.png + HYDRO.png + HYDRO_small.png + case1d.png + case2d.png + case_couplage.png + create_case1d.png + create_case2d.png + create_case_couplage.png + log.png + create_case_pytel.png + case_pytel.png + define_boundary_conditions.png +) + +INSTALL(FILES ${HYDROSOLVER_RESOURCES_FILES} DESTINATION ${SALOME_HYDROSOLVER_INSTALL_RES_DATA}) + +MESSAGE(STATUS "Creation of ${CMAKE_CURRENT_BINARY_DIR}/SalomeApp.xml") +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/SalomeApp.xml.in ${CMAKE_CURRENT_BINARY_DIR}/SalomeApp.xml @ONLY) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/SalomeApp.xml DESTINATION ${SALOME_HYDROSOLVER_INSTALL_RES_DATA}) diff --git a/resources/HYDRO.png b/resources/HYDRO.png new file mode 100644 index 0000000..29ca17c Binary files /dev/null and b/resources/HYDRO.png differ diff --git a/resources/HYDROSOLVERCatalog.xml b/resources/HYDROSOLVERCatalog.xml new file mode 100644 index 0000000..1ddc15f --- /dev/null +++ b/resources/HYDROSOLVERCatalog.xml @@ -0,0 +1,440 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MASCARET + MASCARET + Data + EDF-RD + 1.0 + + 0 + SO + + + MASCARET + + + + + Compute + EDF-RD + 1.0 + + 0 + + + + fileList + HYDROSOLVER_ORB/MascaretFileList + unknown + + + ligFile + string + unknown + + + outputVars + HYDROSOLVER_ORB/stringvec + unknown + + + + + outputValues + HYDROSOLVER_ORB/dblevec + unknown + + + + + + + + Init + EDF-RD + 1.0 + + 0 + + + + studyID + long + + + detCaseEntry + string + + + + + + + + + + + + Exec + EDF-RD + 1.0 + + 0 + + + + paramInput + SALOME_TYPES/ParametricInput + + + + + paramOutput + SALOME_TYPES/ParametricOutput + + + + + + + + + InitBorders + EDF-RD + 1.0 + + 0 + + + + borders + pyobj + + + + + + ExecStep + EDF-RD + 1.0 + + 0 + + + + timeData + pyobj + + + inputData + pyobj + + + + + outputData + pyobj + + + + + + Finalize + EDF-RD + 1.0 + + 0 + + + + + + + + + + + + + + ExecCoupling + EDF-RD + 1.0 + + 0 + + + + inputVarList + HYDROSOLVER_ORB/stringvec + unknown + + + outputVarList + HYDROSOLVER_ORB/stringvec + unknown + + + + + + + + inputValues + CALCIUM_double + T + + + outputValues + CALCIUM_double + T + + + + + + Log + EDF-RD + 1.0 + + 0 + + + + studyID + long + + + inputVarList + HYDROSOLVER_ORB/stringvec + unknown + + + + + + + + inputValues + CALCIUM_double + S + + + + + + + + + + TELEMAC2D + TELEMAC2D + Data + EDF-RD + 1.0 + + 0 + SO + + + TELEMAC2D + + + + + Compute + EDF-RD + 1.0 + + 0 + + + + studyID + long + + + detCaseEntry + string + + + + + + + + + + Init + EDF-RD + 1.0 + + 0 + + + + studyID + long + + + detCaseEntry + string + + + + + + + + + + + + Exec + EDF-RD + 1.0 + + 0 + + + + paramInput + SALOME_TYPES/ParametricInput + + + + + paramOutput + SALOME_TYPES/ParametricOutput + + + + + + + + + InitBorders + EDF-RD + 1.0 + + 0 + + + + borders + pyobj + + + + + + ExecStep + EDF-RD + 1.0 + + 0 + + + + timeData + pyobj + + + inputData + pyobj + + + + + outputData + pyobj + + + + + + Finalize + EDF-RD + 1.0 + + 0 + + + + + + + + + + + + + + + + + + HYDROSOLVER + HYDROSOLVER + Data + EDF-RD + 1.0 + + 0 + SO + + + HYDROSOLVER + + + + + + + + diff --git a/resources/HYDRO_small.png b/resources/HYDRO_small.png new file mode 100644 index 0000000..99c75c4 Binary files /dev/null and b/resources/HYDRO_small.png differ diff --git a/resources/SalomeApp.xml.in b/resources/SalomeApp.xml.in new file mode 100644 index 0000000..023705e --- /dev/null +++ b/resources/SalomeApp.xml.in @@ -0,0 +1,36 @@ + + +
+ + + + + + +
+
+ + +
+
+ + +
+
diff --git a/resources/case1d.png b/resources/case1d.png new file mode 100644 index 0000000..ab9588b Binary files /dev/null and b/resources/case1d.png differ diff --git a/resources/case2d.png b/resources/case2d.png new file mode 100644 index 0000000..2dcc8e6 Binary files /dev/null and b/resources/case2d.png differ diff --git a/resources/case_couplage.png b/resources/case_couplage.png new file mode 100644 index 0000000..c7d402c Binary files /dev/null and b/resources/case_couplage.png differ diff --git a/resources/case_pytel.png b/resources/case_pytel.png new file mode 100644 index 0000000..a97bddb Binary files /dev/null and b/resources/case_pytel.png differ diff --git a/resources/create_case1d.png b/resources/create_case1d.png new file mode 100644 index 0000000..3d9ada3 Binary files /dev/null and b/resources/create_case1d.png differ diff --git a/resources/create_case2d.png b/resources/create_case2d.png new file mode 100644 index 0000000..91fa1b0 Binary files /dev/null and b/resources/create_case2d.png differ diff --git a/resources/create_case_couplage.png b/resources/create_case_couplage.png new file mode 100644 index 0000000..c615db8 Binary files /dev/null and b/resources/create_case_couplage.png differ diff --git a/resources/create_case_pytel.png b/resources/create_case_pytel.png new file mode 100644 index 0000000..715f54e Binary files /dev/null and b/resources/create_case_pytel.png differ diff --git a/resources/define_boundary_conditions.png b/resources/define_boundary_conditions.png new file mode 100644 index 0000000..de8a471 Binary files /dev/null and b/resources/define_boundary_conditions.png differ diff --git a/resources/icon_variables.png b/resources/icon_variables.png new file mode 100644 index 0000000..502dd92 Binary files /dev/null and b/resources/icon_variables.png differ diff --git a/resources/log.png b/resources/log.png new file mode 100644 index 0000000..835b4a2 Binary files /dev/null and b/resources/log.png differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..4554471 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,21 @@ +# 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 . + +ADD_SUBDIRECTORY(HYDRO) +ADD_SUBDIRECTORY(HYDROGUI) +ADD_SUBDIRECTORY(salome_hydro) +ADD_SUBDIRECTORY(mascaret_wrapper) diff --git a/src/HYDRO/CMakeLists.txt b/src/HYDRO/CMakeLists.txt new file mode 100644 index 0000000..e818e78 --- /dev/null +++ b/src/HYDRO/CMakeLists.txt @@ -0,0 +1,28 @@ +# Copyright (C) 2012-2013 EDF +# +# This file is part of SALOME HYDRO module. +# +# SALOME HYDRO module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SALOME HYDRO module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SALOME HYDRO module. If not, see . + +# --- scripts --- + +# scripts / static +SET(_bin_SCRIPTS + HYDROSOLVER.py + MASCARET.py + TELEMAC2D.py +) + +# --- rules --- +SALOME_INSTALL_SCRIPTS("${_bin_SCRIPTS}" ${SALOME_INSTALL_SCRIPT_PYTHON}) diff --git a/src/HYDRO/HYDROSOLVER.py b/src/HYDRO/HYDROSOLVER.py new file mode 100644 index 0000000..1fe370c --- /dev/null +++ b/src/HYDRO/HYDROSOLVER.py @@ -0,0 +1,38 @@ +# 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 . + +import HYDROSOLVER_ORB__POA +import SALOME_ComponentPy +import SALOME_DriverPy + + +class HYDROSOLVER(HYDROSOLVER_ORB__POA.HYDROSOLVER, + SALOME_ComponentPy.SALOME_ComponentPy_i, + SALOME_DriverPy.SALOME_DriverPy_i): + + """ + Pour etre un composant SALOME cette classe Python + doit avoir le nom du composant et heriter de la + classe HYDROSOLVER 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 ): + SALOME_ComponentPy.SALOME_ComponentPy_i.__init__(self, orb, poa, + contID, containerName, instanceName, interfaceName, 0) + SALOME_DriverPy.SALOME_DriverPy_i.__init__(self, interfaceName) diff --git a/src/HYDRO/MASCARET.py b/src/HYDRO/MASCARET.py new file mode 100644 index 0000000..bebfccc --- /dev/null +++ b/src/HYDRO/MASCARET.py @@ -0,0 +1,412 @@ +# Copyright (C) 2012-2013 EDF +# +# This file is part of SALOME HYDRO module. +# +# SALOME HYDRO module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SALOME HYDRO module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SALOME HYDRO module. If not, see . + +import os +import logging +import threading +import inspect +import traceback +import cPickle + +import salome +import HYDROSOLVER_ORB__POA +import SALOME_ComponentPy +import SALOME +import calcium +import dsccalcium + +from salome.kernel.logger import Logger +from salome.kernel import termcolor +logger = Logger("MASCARET", color = termcolor.BLUE) +logger.setLevel(logging.DEBUG) + +from salome.kernel.parametric.compo_utils import \ + create_input_dict, create_normal_parametric_output, create_error_parametric_output + +from salome.hydro.mascaret import Mascaret, MascaretFile +from salome.hydro.study import HydroStudyEditor + +def mascaretFileListCorbaToCpp(file_list_corba): + file_list_cpp = [] + for file_corba in file_list_corba: + file_cpp = MascaretFile() + file_cpp.fileName = file_corba.fileName + file_cpp.fileType = file_corba.fileType + file_list_cpp.append(file_cpp) + return file_list_cpp + + +class MascaretVariable: + + def __init__(self, inst, varstr): + self.inst = inst + par1 = varstr.find("(") + par2 = varstr.find(")") + self.varname = varstr[:par1] + ranges_str = varstr[par1+1:par2].split(",") + if len(ranges_str) != 3: + raise Exception('Invalid variable "%s"' % varstr) + self.ranges = [] + self.valid_for_output = True + for currange in ranges_str: + limits = currange.split("-") + if len(limits) != 1 and len(limits) != 2: + raise Exception('Invalid variable "%s"' % varstr) + limit_inf = int(limits[0]) + if len(limits) == 2: + limit_sup = int(limits[1]) + else: + limit_sup = limit_inf + newrange = range(limit_inf, limit_sup + 1) + if len(newrange) > 1: + self.valid_for_output = False + self.ranges.append(newrange) + + def get_value(self): + if not self.valid_for_output: + raise Exception('Variable "%s" is not valid as an output variable' % self.varname) + logger.debug("Getting value: getDouble(%s, %d, %d, %d)" % + (self.varname, self.ranges[0][0], self.ranges[1][0], self.ranges[2][0])) + return self.inst.getDouble(self.varname, self.ranges[0][0], self.ranges[1][0], self.ranges[2][0]) + + def set_value(self, value): + for x in self.ranges[0]: + for y in self.ranges[1]: + for z in self.ranges[2]: + logger.debug("Setting value: setDouble(%s, %d, %d, %d, %f)" % + (self.varname, x, y, z, value)) + self.inst.setDouble(self.varname, x, y, z, value) + +################################################ + +class MASCARET(HYDROSOLVER_ORB__POA.MASCARET, dsccalcium.PyDSCComponent): + + lock = threading.Lock() + + """ + Pour etre un composant SALOME cette classe Python + doit avoir le nom du composant et heriter de la + classe HYDRO_ORB__POA.MASCARET issue de la compilation de l'idl + par omniidl et de la classe SALOME_ComponentPy_i + qui porte les services generaux d'un composant SALOME + """ + def __init__ ( self, orb, poa, contID, containerName, instanceName, + interfaceName ): + logger.info("__init__: " + containerName + ' ; ' + instanceName) + dsccalcium.PyDSCComponent.__init__(self, orb, poa,contID, + containerName,instanceName,interfaceName) + self.file_list = None + self.lig_file = None + self.inst = None + self.last_start_time = None + self.state_id = None + self.initial_state_id = None + self.input_var_map = None + self.output_var_map = None + + def init_service(self,service): + if service == "ExecCoupling": + # initialization CALCIUM ports IN + calcium.create_calcium_port(self.proxy, "inputValues", "CALCIUM_double", "IN", "T") + # initialization CALCIUM ports OUT + calcium.create_calcium_port(self.proxy, "outputValues", "CALCIUM_double", "OUT", "T") + elif service == "Log": + # initialization CALCIUM ports IN + calcium.create_calcium_port(self.proxy, "inputValues", "CALCIUM_double", "IN", "T") + return service in ("Compute", "Init", "Exec", "Finalize", "ExecCoupling", "Log") + + def _raiseSalomeError(self): + message = "Error in component %s running in container %s." % (self._instanceName, self._containerName) + logger.exception(message) + message += " " + traceback.format_exc() + exc = SALOME.ExceptionStruct(SALOME.INTERNAL_ERROR, message, + inspect.stack()[1][1], inspect.stack()[1][2]) + raise SALOME.SALOME_Exception(exc) + + def Compute(self, fileList, ligFile, outputVars): + try: + self.beginService("MASCARET.Compute") + + # Initialize + inst = Mascaret() + inst.importModel(mascaretFileListCorbaToCpp(fileList)) + inst.initState(ligFile) + + # Compute + inst.compute() + + # Get the output values + output_values = [MascaretVariable(inst, var).get_value() for var in outputVars] + + self.endService("MASCARET.Compute") + return output_values + except: + self._raiseSalomeError() + + def Init(self, studyId, detCaseEntry): + try: + self.beginService("MASCARET.Init") + MASCARET.lock.acquire() + salome.salome_init() + MASCARET.lock.release() + + ed = HydroStudyEditor(studyId) + sobj = ed.editor.study.FindObjectID(detCaseEntry) + (file_list_corba, self.lig_file, input_vars, output_vars) = ed.get_mascaret_params_from_case(sobj) + + self.file_list = mascaretFileListCorbaToCpp(file_list_corba) + + # Initialize Mascaret instance + self.inst = Mascaret() + #self.inst.setPrinting(True) + self.inst.importModel(self.file_list) + self.inst.initState(self.lig_file) + + # Create variable mappings + self.input_var_map = {} + for input_var in input_vars: + name = input_var["NOM"] + if not self.input_var_map.has_key(name): + self.input_var_map[name] = [] + self.input_var_map[name] += [MascaretVariable(self.inst, input_var["VARIABLE_MASCARET"])] + + self.output_var_map = {} + for output_var in output_vars: + masc_output_var = MascaretVariable(self.inst, output_var["VARIABLE_MASCARET"]) + self.output_var_map[output_var["NOM"]] = masc_output_var + + self.endService("MASCARET.Init") + except: + self._raiseSalomeError() + + def Exec(self, paramInput): + try: + self.beginService("MASCARET.Exec") + + if self.initial_state_id is not None: + self.inst.restoreState(self.initial_state_id) + self.initial_state_id = self.inst.saveState() + + logger.debug("inputVarList: %s" % paramInput.inputVarList) + logger.debug("outputVarList: %s" % paramInput.outputVarList) + logger.debug("inputValues: %s" % paramInput.inputValues) + + input_dict = create_input_dict({}, paramInput) + logger.debug("input_dict = %s" % input_dict) + + for (key, value) in input_dict.iteritems(): + for masc_var in self.input_var_map[key]: + masc_var.set_value(value) + + # Compute + self.inst.compute() + + # Get the output values + output_dict = {} + for output_var in paramInput.outputVarList: + output_dict[output_var] = self.output_var_map[output_var].get_value() + + param_output = create_normal_parametric_output(output_dict, paramInput) + logger.debug("outputValues: %s" % param_output.outputValues) + self.endService("MASCARET.Exec") + return param_output + except: + self._raiseSalomeError() + + def InitBorders(self, bordersPickled): + """ + This method initializes the border(s) for coupling + """ + try: + self.beginService("MASCARET.InitBorders") + borders = cPickle.loads(bordersPickled) + self.borders = {} + for border in borders: + if border["model1"] is not None and border["model1"]["code"] == "MASCARET": + self.borders[border["name"]] = border["model1"] + elif border["model2"] is not None and border["model2"]["code"] == "MASCARET": + self.borders[border["name"]] = border["model2"] + self.endService("MASCARET.InitBorders") + except: + self._raiseSalomeError() + + def setData(self, inputData): + if inputData is not None: + for (name, desc) in self.borders.iteritems(): + if name in inputData: + if desc["position"] == "upstream": + if self.froude[name] < 1.0: + Z = inputData[name]["Z"] + self.inst.setDouble("Modele.Lois.Cote", desc["loi_id"], 1, 0, Z) + self.inst.setDouble("Modele.Lois.Cote", desc["loi_id"], 2, 0, Z) + else: + Q = inputData[name]["Q"] + self.inst.setDouble("Modele.Lois.Debit", desc["loi_id"], 1, 0, Q) + self.inst.setDouble("Modele.Lois.Debit", desc["loi_id"], 2, 0, Q) + if self.froude[name] >= 1.0: + Z = inputData[name]["Z"] + self.inst.setDouble("Modele.Lois.Cote", desc["loi_id"], 1, 0, Z) + self.inst.setDouble("Modele.Lois.Cote", desc["loi_id"], 2, 0, Z) + + def ExecStep(self, timeDataPickled, inputDataPickled): + """ + This method computes a single time step + """ + try: + self.beginService("MASCARET.ExecStep") + timeData = cPickle.loads(timeDataPickled) + inputData = cPickle.loads(inputDataPickled) + + if self.last_start_time is not None: + self.inst.restoreState(self.state_id) + # If it's a new time step, we perform a last iteration with + # the last time step to restore the state properly + if self.last_start_time != timeData["start_time"]: + self.setData(inputData) + self.inst.compute(self.last_start_time, timeData["start_time"], timeData["time_step"]) + + self.last_start_time = timeData["start_time"] + self.state_id = self.inst.saveState() + + self.setData(inputData) + + # Computation + self.inst.compute(timeData["start_time"], timeData["end_time"], timeData["time_step"]) + + # Get the output values + outputData = {} + self.froude = {} + for (name, desc) in self.borders.iteritems(): + Z = self.inst.getDouble("Etat.Z", desc["section_id"], 0, 0) + Q1 = self.inst.getDouble("Etat.Q1", desc["section_id"], 0, 0) + S1 = self.inst.getDouble("Etat.S1", desc["section_id"], 0, 0) + V = Q1/S1 + #V = self.inst.getDouble("Etat.V1", desc["section_id"], 0, 0) + Q = self.inst.getDouble("Etat.Q", desc["section_id"], 0, 0) + Froude = self.inst.getDouble("Etat.Froude", desc["section_id"], 0, 0) + outputData[name] = {"Z": Z, "V": V, "Froude": Froude, "Q": Q} + self.froude[name] = Froude + outputDataPickled = cPickle.dumps(outputData, -1) + + self.endService("MASCARET.ExecStep") + return outputDataPickled + except: + self._raiseSalomeError() + + def Finalize(self): + try: + self.beginService("MASCARET.Finalize") + self.file_list = None + self.lig_file = None + self.inst = None + self.last_start_time = None + self.state_id = None + self.input_var_map = None + self.output_var_map = None + self.endService("MASCARET.Finalize") + except: + self._raiseSalomeError() + + def ExecCoupling(self, inputVarList, outputVarList): + try: + self.beginService("MASCARET.ExecCoupling") + component = self.proxy + + # Get time data from model + start_time = self.inst.getDouble("Modele.TempsInitial", 0, 0, 0) + end_time = self.inst.getDouble("Modele.TempsMaximum", 0, 0, 0) + time_step = self.inst.getDouble("Modele.DT", 0, 0, 0) + + # Time loop + current_time = start_time + calcium.cp_cd(component) + while current_time < end_time: + # Send data + if len(outputVarList) > 0: + output_values = [] + for output_var in outputVarList: + masc_var = self.output_var_map[output_var] + value = self.inst.getDouble(*split_var(masc_var)) + output_values += [value] + info = calcium.cp_edb(component, calcium.CP_TEMPS, current_time, 0, "outputValues", + len(outputVarList), output_values) + logger.debug("Instance %s sent %s" % (self._instanceName, zip(outputVarList, output_values))) + if info != 0: + raise Exception("Error in calcium.cp_edb, code = %d" % info) + + # Receive data + input_values = calcium.doubleArray(len(inputVarList)) + if len(inputVarList) > 0: + (info, t, ii, n) = calcium.cp_ldb(component, calcium.CP_TEMPS, + current_time, current_time + 1e-6, + 0, "inputValues", len(inputVarList), input_values) + if info != 0: + raise Exception("Error in calcium.cp_ldb, code = %d" % info) + if n != len(inputVarList): + raise Exception("Wrong number of input values: %d instead of %d" % (n, len(inputVarList))) + logger.debug("Instance %s received %s" % (self._instanceName, zip(inputVarList, input_values))) + + # Update model with received data + for (var, value) in zip(inputVarList, input_values): + for masc_var in self.input_var_map[var]: + self.inst.setDouble(*(split_var(masc_var) + (value,))) + + # Compute + end_step_time = current_time + time_step + self.inst.compute(current_time, end_step_time, time_step) + current_time = end_step_time + + calcium.cp_fin(component, calcium.CP_ARRET) + self.endService("MASCARET.ExecCoupling") + except: + self._raiseSalomeError() + + def Log(self, studyId, inputVarList): + """ + This method is not used anymore. It was used in the context of the calcium coupling test. + """ + try: + self.beginService("MASCARET.Log") + if len(inputVarList) > 0: + log = {} + for var in inputVarList: + log[var] = "" + component = self.proxy + finished = False + calcium.cp_cd(component) + while not finished: + # Receive data + input_values = calcium.doubleArray(len(inputVarList)) + (info, t, ii, n) = calcium.cp_ldb(component, calcium.CP_SEQUENTIEL, + 0, 0, 0, "inputValues", len(inputVarList), input_values) + if info == 33: + finished = True + elif info != 0: + raise Exception("Error in calcium.cp_ldb, code = %d" % info) + elif n != len(inputVarList): + raise Exception("Wrong number of input values: %d instead of %d" % (n, len(inputVarList))) + else: + logger.debug("Instance %s received %s" % (self._instanceName, zip(inputVarList, input_values))) + for (var, value) in zip(inputVarList, input_values): + log[var] += "t = %f, %s = %f\n" % (t, var, value) + calcium.cp_fin(component, calcium.CP_ARRET) + ed = HydroStudyEditor(studyId) + for var in inputVarList: + ed.add_coupling_log(var, log[var]) + self.endService("MASCARET.Log") + except: + self._raiseSalomeError() diff --git a/src/HYDRO/TELEMAC2D.py b/src/HYDRO/TELEMAC2D.py new file mode 100644 index 0000000..beb9f4b --- /dev/null +++ b/src/HYDRO/TELEMAC2D.py @@ -0,0 +1,579 @@ +# Copyright (C) 2012-2013 EDF +# +# This file is part of SALOME HYDRO module. +# +# SALOME HYDRO module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SALOME HYDRO module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SALOME HYDRO module. If not, see . + +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 salome.hydro.telemac2d import Telemac2D +from salome.hydro.telemac2d.polygon import get_list_points_in_polygon +from salome.hydro.study import jdc_to_dict, get_jdc_dict_var_as_tuple, HydroStudyEditor + +################################################ + +class TELEMAC2D(HYDROSOLVER_ORB__POA.TELEMAC2D, dsccalcium.PyDSCComponent): + + lock = threading.Lock() + + """ + Pour etre un composant SALOME cette classe Python + doit avoir le nom du composant et heriter de la + classe HYDRO_ORB__POA.MASCARET issue de la compilation de l'idl + par omniidl et de la classe SALOME_ComponentPy_i + qui porte les services generaux d'un composant SALOME + """ + def __init__ ( self, orb, poa, contID, containerName, instanceName, + interfaceName ): + logger.info("__init__: " + containerName + ' ; ' + instanceName) + dsccalcium.PyDSCComponent.__init__(self, orb, poa,contID, + containerName,instanceName,interfaceName) + self.t2d = None + self.last_start_time = None + self.saved_state = None + + def init_service(self,service): + return service in ("Compute",) + + def _raiseSalomeError(self): + message = "Error in component %s running in container %s." % (self._instanceName, self._containerName) + logger.exception(message) + message += " " + traceback.format_exc() + exc = SALOME.ExceptionStruct(SALOME.INTERNAL_ERROR, message, + inspect.stack()[1][1], inspect.stack()[1][2]) + raise SALOME.SALOME_Exception(exc) + + def Init(self, studyId, detCaseEntry): + try: + self.beginService("TELEMAC2D.Init") + self.jdc_dict = self.get_jdc_dict_from_case(studyId, detCaseEntry) + + # Ugly hack to check if we are in OpenTURNS context or Mascaret coupling context + if "VARIABLE_ENTREE" in self.jdc_dict: + # Create variable mappings for OpenTURNS + self.input_var_map = {} + for input_var in get_jdc_dict_var_as_tuple(self.jdc_dict, "VARIABLE_ENTREE"): + name = input_var["NOM"] + if not self.input_var_map.has_key(name): + self.input_var_map[name] = [] + self.input_var_map[name] += [Telemac2DInputVariable(input_var["VARIABLE_MODELE_T2D"])] + + self.output_var_map = {} + for output_var in get_jdc_dict_var_as_tuple(self.jdc_dict, "VARIABLE_SORTIE"): + t2d_output_var = Telemac2DOutputVariable(output_var["VARIABLE_T2D"]) + self.output_var_map[output_var["NOM"]] = t2d_output_var + + else: + # Initialize before launching the coupling with Mascaret + self.init_t2d_from_jdc_dict(self.jdc_dict) + + self.endService("TELEMAC2D.Init") + except: + self._raiseSalomeError() + + def get_jdc_dict_from_case(self, study_id, case_entry): + TELEMAC2D.lock.acquire() + salome.salome_init() + TELEMAC2D.lock.release() + + # Get filenames from the case in Salome study + ed = HydroStudyEditor(study_id) + sobj = ed.editor.study.FindObjectID(case_entry) + jdcpath = sobj.GetComment() + with open(jdcpath) as jdcfile: + jdc = jdcfile.read() + return jdc_to_dict(jdc, ["TELEMAC2D", "_F"]) + + def init_t2d_from_jdc_dict(self, jdc_dict): + steering_filename = jdc_dict["FICHIER_CAS"] + user_fortran = jdc_dict.get("FICHIER_FORTRAN_UTILISATEUR") + dico_filename = jdc_dict.get("FICHIER_DICO") + geo_filename = jdc_dict.get("FICHIER_GEOMETRIE") + bc_filename = jdc_dict.get("FICHIER_CONDITIONS_LIMITES") + result_filename = jdc_dict.get("RESULTAT") + + logger.debug("Initializing Telemac2D API") + self.t2d = Telemac2D(user_fortran) + logger.debug("Telemac2D API initialization OK") + os.chdir(os.path.dirname(steering_filename)) + self.t2d.run_read_case_t2d(steering_filename, dico_filename) + if bc_filename is not None: + self.t2d.set_string('MODEL.BCFILE', bc_filename) + if geo_filename is not None: + self.t2d.set_string('MODEL.GEOMETRYFILE', geo_filename) + if result_filename is not None: + self.t2d.set_string('MODEL.RESULTFILE', result_filename) + ierr = self.t2d.api.run_allocation_t2d(self.t2d.id) + if ierr != 0: + raise Exception('Error in run_allocation_t2d:', ierr) + ierr = self.t2d.api.run_init_t2d(self.t2d.id) + if ierr != 0: + raise Exception('Error in run_init_t2d:', ierr) + + def Exec(self, paramInput): + try: + self.beginService("TELEMAC2D.Exec") + + # Save / restore state + # Not used yet because time can not be reset + #if self.saved_state is None: + # self.saved_state = self.t2d.save_state() + #else: + # self.t2d.restore_state(self.saved_state) + + # Get id and execution mode + id = "" + exec_mode = "" + for parameter in paramInput.specificParameters: + if parameter.name == "id": + id = parameter.value + if parameter.name == "executionMode": + exec_mode = parameter.value + logger.debug("ID: %s" % id) + logger.debug("Execution mode: %s" % exec_mode) + + # Append id to result file name + result_filename = self.jdc_dict.get("RESULTAT") or "r2d.slf" + (result_filename_wo_ext, ext) = os.path.splitext(result_filename) + current_jdc_dict = self.jdc_dict.copy() + current_jdc_dict["RESULTAT"] = "%s_%s%s" % (result_filename_wo_ext, id, ext) + + # Reload model + self.init_t2d_from_jdc_dict(current_jdc_dict) + + # Set the input values + logger.debug("inputVarList: %s" % paramInput.inputVarList) + logger.debug("outputVarList: %s" % paramInput.outputVarList) + logger.debug("inputValues: %s" % paramInput.inputValues) + + input_dict = create_input_dict({}, paramInput) + logger.debug("input_dict = %s" % input_dict) + + for (key, value) in input_dict.iteritems(): + for t2d_var in self.input_var_map[key]: + t2d_var.set_value(self.t2d, value) + + # Compute + self.t2d.run_all_timesteps() + + # Get the output values + output_dict = {} + for output_var in paramInput.outputVarList: + output_dict[output_var] = self.output_var_map[output_var].get_value(self.t2d) + + param_output = create_normal_parametric_output(output_dict, paramInput) + logger.debug("outputValues: %s" % param_output.outputValues) + + # Finalize T2D + self.t2d.finalize() + self.t2d = None + + self.endService("TELEMAC2D.Exec") + return param_output + except: + self._raiseSalomeError() + + def InitBorders(self, bordersPickled): + """ + This method initializes the border(s) for coupling + """ + try: + self.beginService("TELEMAC2D.InitBorders") + borders = cPickle.loads(bordersPickled) + self.borders = {} + for border in borders: + if border["model1"] is not None and border["model1"]["code"] == "TELEMAC2D": + self.borders[border["name"]] = border["model1"] + elif border["model2"] is not None and border["model2"]["code"] == "TELEMAC2D": + self.borders[border["name"]] = border["model2"] + self.endService("TELEMAC2D.InitBorders") + except: + self._raiseSalomeError() + + def ExecStep(self, timeDataPickled, inputDataPickled): + """ + This method computes a single time step + """ + try: + self.beginService("TELEMAC2D.ExecStep") + timeData = cPickle.loads(timeDataPickled) + inputData = cPickle.loads(inputDataPickled) + + if timeData["start_time"] == self.last_start_time: + # Convergence iteration, restore saved state + self.t2d.restore_state(self.saved_state) + else: + # First iteration of a time step, save state + self.saved_state = self.t2d.save_state(self.saved_state) + + self.last_start_time = timeData["start_time"] + + if inputData is not None: + for (name, desc) in self.borders.iteritems(): + if name in inputData: + z = None + v = None + q = None + if desc["position"] == "upstream": + if inputData[name]["Froude"] < 1.0: # Fluvial + z = inputData[name]["Z"] + else: + v = inputData[name]["V"] + q = inputData[name]["Q"] + if inputData[name]["Froude"] > 1.0: # Torrential + z = inputData[name]["Z"] + self.set_z_on_border(desc, z) + #self.set_v_on_border(desc, v) + self.set_q_on_border(desc, q) + + # Compute + # TODO: Use time values from coupling + ierr = self.t2d.api.run_timestep_t2d(self.t2d.id) + if ierr != 0: + raise Exception('Error in run_timestep_t2d:', ierr) + + # Get the output values + outputData = {} + for (name, desc) in self.borders.iteritems(): + outputData[name] = {} + (outputData[name]["Z"], idx) = self.get_z_on_border(desc) + if idx is None: + outputData[name]["V"] = 0.0 + else: + (outputData[name]["V"], froude) = self.get_v_at_point(idx) + outputData[name]["Q"] = self.get_q_on_border(desc) + outputDataPickled = cPickle.dumps(outputData, -1) + + self.endService("TELEMAC2D.ExecStep") + return outputDataPickled + except: + self._raiseSalomeError() + + def get_z_on_border(self, border): + """ + Find the water elevation (i.e. water height + bottom elevation) on a border. + Return a tuple (water_elevation, index_of_model_point_with_min_water_elevation). + If we use method 2 (compute mean water elevation), index is set to None. + """ + # Method 1: Get point with minimum elevation + """ + idx = -1 + bor_idx = -1 + z_min = sys.float_info.max + (first, after_last) = border["points_id"] + k = first + while k != after_last: + nbor_k = self.t2d.get_integer('MODEL.NBOR', k) + h_k = self.t2d.get_double('MODEL.WATERDEPTH', nbor_k) + z_bottom_k = self.t2d.get_double('MODEL.BOTTOMELEVATION', nbor_k) + z_k = h_k + z_bottom_k + logger.debug("extract z for border point %d, h:%f, zf:%f, z:%f" % (k, h_k, z_bottom_k, z_k)) + if (z_k < z_min): + z_min = z_k + bor_idx = k + idx = nbor_k + k = self.t2d.get_integer('MODEL.KP1BOR', k) + logger.debug("min z for border %d with method 1 is %f at border point %d (model point %d)" % + (border["border_id"], z_min, bor_idx, idx)) + z = z_min + """ + # Method 2: Compute mean elevation, ignoring dry zones (method from PALM coupling) + z_mean = sys.float_info.max + for i in range(10): + h_tot = 0.0 + l_tot = 0.0 + zf_min = sys.float_info.max + (first, after_last) = border["points_id"] + k = first + while k != after_last: + knext = self.t2d.get_integer('MODEL.KP1BOR', k) + nbor_k = self.t2d.get_integer('MODEL.NBOR', k) + nbor_knext = self.t2d.get_integer('MODEL.NBOR', knext) + zf1 = self.t2d.get_double('MODEL.BOTTOMELEVATION', nbor_k) + zf2 = self.t2d.get_double('MODEL.BOTTOMELEVATION', nbor_knext) + zf_min = min(zf_min, zf1) + h1 = self.t2d.get_double('MODEL.WATERDEPTH', nbor_k) + h2 = self.t2d.get_double('MODEL.WATERDEPTH', nbor_knext) + z1 = h1 + zf1 + z2 = h2 + zf2 + x1 = self.t2d.get_double('MODEL.X', nbor_k) + x2 = self.t2d.get_double('MODEL.X', nbor_knext) + y1 = self.t2d.get_double('MODEL.Y', nbor_k) + y2 = self.t2d.get_double('MODEL.Y', nbor_knext) + l = math.sqrt((x1-x2)**2 + (y1-y2)**2) + if zf1 <= z_mean and zf2 <= z_mean: + h_tot += (z1+z2) * 0.5 * l + l_tot += l + k = knext + + new_z_mean = h_tot / l_tot + delta = abs(z_mean - new_z_mean) + z_mean = new_z_mean + if delta < 1.0e-6: + break + + logger.debug("mean z for border %d with method 2 is %f" % (border["border_id"], z_mean)) + z = z_mean + idx = None + + return (z, idx) + + def get_v_at_point(self, idx): + """ + Find the water velocity at the model point idx. + Return a tuple (velocity, froude number) + """ + u_i = self.t2d.get_double('MODEL.VELOCITYU', idx) + v_i = self.t2d.get_double('MODEL.VELOCITYV', idx) + h_i = self.t2d.get_double('MODEL.WATERDEPTH', idx) + v = math.sqrt(u_i**2 + v_i**2) + ##### TODO: Remove that and find the real error + if h_i <= 0.0: + print 'Error: water depth is negative or zero on point', idx + #raise Exception('Null water depth value') + h_i = 0.01 + froude = v / (h_i * 9.81) + return (v, froude) + + def get_q_on_border(self, border): + """ + Find the flow on a border. + The returned value is positive if the flow goes in the natural direction + according to the borders description (from upstream to downstream). + """ + # Method 1: Integrate the flow on the whole border + """ + q = 0.0 + (first, after_last) = border["points_id"] + k = first + while k != after_last: + knext = self.t2d.get_integer('MODEL.KP1BOR', k) + nbor_k = self.t2d.get_integer('MODEL.NBOR', k) + nbor_knext = self.t2d.get_integer('MODEL.NBOR', knext) + h_i = self.t2d.get_double('MODEL.WATERDEPTH', nbor_k) + h_i2 = self.t2d.get_double('MODEL.WATERDEPTH', nbor_knext) + h2d1 = 0.5 * (h_i + h_i2) + if (h2d1 > 0.0): + u_i = self.t2d.get_double('MODEL.VELOCITYU', nbor_k) + u_i2 = self.t2d.get_double('MODEL.VELOCITYU', nbor_knext) + v_i = self.t2d.get_double('MODEL.VELOCITYV', nbor_k) + v_i2 = self.t2d.get_double('MODEL.VELOCITYV', nbor_knext) + v2d1 = 0.5 * (math.sqrt(u_i**2+v_i**2) + math.sqrt(u_i2**2+v_i2**2)) + x2d1 = self.t2d.get_double('MODEL.X', nbor_k) + x2d2 = self.t2d.get_double('MODEL.X', nbor_knext) + y2d1 = self.t2d.get_double('MODEL.Y', nbor_k) + y2d2 = self.t2d.get_double('MODEL.Y', nbor_knext) + q += v2d1 * h2d1 * math.sqrt((x2d1-x2d2)**2 + (y2d1-y2d2)**2) + k = knext + logger.debug("flow for border %d with method 1 is %f" % (border["border_id"], q)) + + # Method 2: Get the flow from Telemac model + q = self.t2d.get_double('MODEL.FLUX_BOUNDARIES', border["border_id"]) + if border["position"] == "downstream": + q = -q + logger.debug("flow for border %d with method 2 is %f" % (border["border_id"], q)) + """ + + # Method 3: Method from PALM coupling + q = 0.0 + (first, after_last) = border["points_id"] + k = first + while k != after_last: + knext = self.t2d.get_integer('MODEL.KP1BOR', k) + nbor_k = self.t2d.get_integer('MODEL.NBOR', k) + nbor_knext = self.t2d.get_integer('MODEL.NBOR', knext) + h_i = self.t2d.get_double('MODEL.WATERDEPTH', nbor_k) + h_i2 = self.t2d.get_double('MODEL.WATERDEPTH', nbor_knext) + u_i = self.t2d.get_double('MODEL.VELOCITYU', nbor_k) + u_i2 = self.t2d.get_double('MODEL.VELOCITYU', nbor_knext) + v_i = self.t2d.get_double('MODEL.VELOCITYV', nbor_k) + v_i2 = self.t2d.get_double('MODEL.VELOCITYV', nbor_knext) + x2d1 = self.t2d.get_double('MODEL.X', nbor_k) + x2d2 = self.t2d.get_double('MODEL.X', nbor_knext) + y2d1 = self.t2d.get_double('MODEL.Y', nbor_k) + y2d2 = self.t2d.get_double('MODEL.Y', nbor_knext) + NX=y2d1-y2d2 + NY=x2d2-x2d1 + UN1=u_i*NX+v_i*NY + UN2=u_i2*NX+v_i2*NY + q += ((h_i+h_i2)*(UN1+UN2)+h_i2*UN2+h_i*UN1)/6.0 + k = knext + if border["position"] == "upstream": + q = -q + logger.debug("flow for border %d with method 3 is %f" % (border["border_id"], q)) + + return q + + def set_z_on_border(self, border, z): + """ + Set the water elevation (i.e. water height + bottom elevation) on a border. + If z is None, then the water elevation for this border is free (not imposed). + """ + # Method 1: Impose water elevation point by point + """ + # Deactivate water level imposition in bord.f (requires a patch in bord.f) + self.t2d.set_double('MODEL.COTE', -1.0, border["border_id"]) + + (first, after_last) = border["points_id"] + k = first + while k != after_last: + if z is None: + self.t2d.set_integer('MODEL.LIHBOR', 4, k) # Free elevation on that border + else: + self.t2d.set_integer('MODEL.LIHBOR', 5, k) # Imposed elevation on that border + nbor_k = self.t2d.get_integer('MODEL.NBOR', k) + bottom_elevation = self.t2d.get_double('MODEL.BOTTOMELEVATION', nbor_k) + hbor_k = max(0.0, z - bottom_elevation) + self.t2d.set_double('MODEL.HBOR', hbor_k, k) + logger.debug("set z for border point %d, h:%f, zf:%f, z:%f" % (k, hbor_k, bottom_elevation, z)) + k = self.t2d.get_integer('MODEL.KP1BOR', k) + """ + + # Method 2: Just tell Telemac what is the imposed elevation for the border + if z is not None: + self.t2d.set_double('MODEL.COTE', z, border["border_id"]) + (first, after_last) = border["points_id"] + k = first + while k != after_last: + if z is None: + self.t2d.set_integer('MODEL.LIHBOR', 4, k) # Free elevation on that border + else: + self.t2d.set_integer('MODEL.LIHBOR', 5, k) # Imposed elevation on that border + k = self.t2d.get_integer('MODEL.KP1BOR', k) + + def set_v_on_border(self, border, v): + """ + Set the water velocity on a border. + If v is None, then the water velocity for this border is free (not imposed). + """ + # This method works only if the water level imposition is deactivated in bord.f + # (requires a patch in bord.f) + (first, after_last) = border["points_id"] + k = first + while k != after_last: + if v is None: + self.t2d.set_integer('MODEL.LIUBOR', 4, k) # Free velocity on that border + self.t2d.set_integer('MODEL.LIVBOR', 4, k) + else: + self.t2d.set_integer('MODEL.LIUBOR', 6, k) # Imposed velocity on that border + self.t2d.set_integer('MODEL.LIVBOR', 6, k) + xnebor_k = self.t2d.get_double('MODEL.XNEBOR', k) + ubor_k = -xnebor_k * v + ynebor_k = self.t2d.get_double('MODEL.YNEBOR', k) + vbor_k = -ynebor_k * v + self.t2d.set_double('MODEL.UBOR', ubor_k, k) + self.t2d.set_double('MODEL.VBOR', vbor_k, k) + k = self.t2d.get_integer('MODEL.KP1BOR', k) + + def set_q_on_border(self, border, q): + """ + Set the water flow on a border. + If q is None, then the water flow for this border is free (not imposed). + """ + if q is not None: + self.t2d.set_double('MODEL.DEBIT', q, border["border_id"]) + logger.debug("flow for border %d is set to %f" % (border["border_id"], q)) + (first, after_last) = border["points_id"] + k = first + while k != after_last: + if q is None: + self.t2d.set_integer('MODEL.LIUBOR', 4, k) # Free velocity on that border + self.t2d.set_integer('MODEL.LIVBOR', 4, k) + else: + self.t2d.set_integer('MODEL.LIUBOR', 5, k) # Imposed discharge on that border + self.t2d.set_integer('MODEL.LIVBOR', 5, k) + k = self.t2d.get_integer('MODEL.KP1BOR', k) + + def Finalize(self): + try: + self.beginService("TELEMAC2D.Finalize") + if self.t2d: + self.t2d.finalize() + self.t2d = None + self.endService("TELEMAC2D.Finalize") + except: + self._raiseSalomeError() + + def Compute(self, studyId, caseEntry): + try: + self.beginService("TELEMAC2D.Compute") + + jdc_dict = self.get_jdc_dict_from_case(studyId, caseEntry) + self.init_t2d_from_jdc_dict(jdc_dict) + + # Compute + self.t2d.run_all_timesteps() + + # Cleanup + self.t2d.finalize() + + self.endService("TELEMAC2D.Compute") + except: + self._raiseSalomeError() + + +class Telemac2DOutputVariable: + + def __init__(self, varstr): + par1 = varstr.find("(") + par2 = varstr.find(")") + self.varname = varstr[:par1] + self.idx = int(varstr[par1+1:par2]) + + def get_value(self, inst): + return inst.get_double(self.varname, self.idx) + + +class Telemac2DInputVariable: + + def __init__(self, vardict): + self.varname = vardict["NOM_VARIABLE_MODELE"] + def_area_dict = vardict["ZONE_DE_DEFINITION"] + self.idx = def_area_dict.get("INDICE") + self.polygon = def_area_dict.get("POLYGONE") + self.points_in_polygon_list = None + + def set_value(self, inst, value): + if self.idx is not None: + inst.set_double(self.varname, value, self.idx) + elif self.polygon is not None: + if self.points_in_polygon_list is None: + self.points_in_polygon_list = get_list_points_in_polygon(inst, self.polygon) + for idx in self.points_in_polygon_list: + inst.set_double(self.varname, value, idx) + else: + raise Exception("Invalid area definition for input variable {0}".format(self.varname)) diff --git a/src/HYDROGUI/CMakeLists.txt b/src/HYDROGUI/CMakeLists.txt new file mode 100644 index 0000000..b6738e5 --- /dev/null +++ b/src/HYDROGUI/CMakeLists.txt @@ -0,0 +1,28 @@ +# Copyright (C) 2012-2013 EDF +# +# This file is part of SALOME HYDRO module. +# +# SALOME HYDRO module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SALOME HYDRO module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SALOME HYDRO module. If not, see . + +# --- Python files --- + +SET(PYFILES + HYDROSOLVERGUI.py +) + +# --- rules --- + +SALOME_INSTALL_SCRIPTS("${PYFILES}" ${SALOME_INSTALL_PYTHON}) + +# The file TextDisplayDialog.ui is not compiled here because it is not used anymore. diff --git a/src/HYDROGUI/HYDROSOLVERGUI.py b/src/HYDROGUI/HYDROSOLVERGUI.py new file mode 100644 index 0000000..43b030f --- /dev/null +++ b/src/HYDROGUI/HYDROSOLVERGUI.py @@ -0,0 +1,437 @@ +# 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 . + +import sys +import os +import traceback +import logging + +from PyQt4 import QtCore, QtGui + +import salome +import SALOME +import SalomePyQt +sgPyQt = SalomePyQt.SalomePyQt() +from salome.kernel.studyedit import getStudyEditor +from salome.kernel.logger import Logger +from salome.kernel import termcolor +logger = Logger("HYDROGUI", color = termcolor.BLUE) +#logger.setLevel(logging.ERROR) + +import HYDROSOLVER_ORB +from salome.hydro.gui_utils import HSGUIException, wait_cursor, get_and_check_selected_file_path +import salome.hydro.study as hydro_study +from salome.hydro.mascaret.eficas.appli import EficasForMascaretAppli +from salome.hydro.telemac2d.eficas.appli import EficasForTelemac2DAppli +from salome.hydro.coupling1d2d.eficas.appli import EficasForCoupling1D2DAppli +import salome.hydro.pytel.gui as pytel_gui +from salome.hydro.boundary_conditions.eficas.appli import EficasForBoundaryConditionsAppli + +################################################ +# GUI context class +# Used to store actions, menus, toolbars, etc... +################################################ + +class GUIcontext: + # menus/toolbars/actions IDs + HYDRO_MENU_ID = 90 + CREATE_MASCARET_CASE_ID = 941 + RUN_MASCARET_ID = 942 + EDIT_MASCARET_CASE_ID = 943 + SHOW_LOG_ID = 944 + CREATE_TELEMAC2D_CASE_ID = 945 + RUN_TELEMAC2D_ID = 946 + EDIT_TELEMAC2D_CASE_ID = 947 + CREATE_COUPLING1D2D_CASE_ID = 948 + EDIT_COUPLING1D2D_CASE_ID = 949 + OPEN_SCHEMA_IN_YACS_ID = 950 + CREATE_PYTEL_CASE_ID = 951 + RUN_PYTEL_ID = 952 + EDIT_PYTEL_CASE_ID = 953 + GENERATE_JOB = 954 + DEFINE_BOUNDARY_CONDITIONS_ID = 955 + + def __init__( self ): + # create top-level menu + mid = sgPyQt.createMenu( "Hydro", -1, GUIcontext.HYDRO_MENU_ID, sgPyQt.defaultMenuGroup() ) + # create toolbar + tid = sgPyQt.createTool( "Hydro" ) + # create actions and fill menu and toolbar with actions + a = sgPyQt.createAction( GUIcontext.DEFINE_BOUNDARY_CONDITIONS_ID, + "Define boundary conditions", "Define boundary conditions", + "Define the boundary conditions for Telemac", + "define_boundary_conditions.png" ) + sgPyQt.createMenu( a, mid ) + sgPyQt.createTool( a, tid ) + + a = sgPyQt.createSeparator() + sgPyQt.createMenu( a, mid ) + sgPyQt.createTool( a, tid ) + + a = sgPyQt.createAction( GUIcontext.CREATE_MASCARET_CASE_ID, + "Create Mascaret case", "Create Mascaret case", + "Create a new Mascaret case", "create_case1d.png" ) + sgPyQt.createMenu( a, mid ) + sgPyQt.createTool( a, tid ) + + a = sgPyQt.createAction( GUIcontext.CREATE_TELEMAC2D_CASE_ID, + "Create Telemac2D case", "Create Telemac2D case", + "Create a new Telemac2D case", "create_case2d.png" ) + sgPyQt.createMenu( a, mid ) + sgPyQt.createTool( a, tid ) + + a = sgPyQt.createAction( GUIcontext.CREATE_COUPLING1D2D_CASE_ID, + "Create 1D / 2D coupling", "Create 1D / 2D coupling", + "Create a new 1D / 2D coupling", "create_case_couplage.png" ) + sgPyQt.createMenu( a, mid ) + sgPyQt.createTool( a, tid ) + + a = sgPyQt.createSeparator() + sgPyQt.createMenu( a, mid ) + sgPyQt.createTool( a, tid ) + + a = sgPyQt.createAction( GUIcontext.CREATE_PYTEL_CASE_ID, + "Create case for Pytel execution", "Create case for Pytel execution", + "Create a new case for Pytel execution", "create_case_pytel.png" ) + sgPyQt.createMenu( a, mid ) + sgPyQt.createTool( a, tid ) + + # the following action are used in context popup + sgPyQt.createAction( GUIcontext.RUN_MASCARET_ID, "Compute case", "Compute case", + "Run Mascaret solver to compute the case" ) + sgPyQt.createAction( GUIcontext.EDIT_MASCARET_CASE_ID, "Edit case", "Edit case", + "Edit the selected Mascaret case" ) + sgPyQt.createAction( GUIcontext.SHOW_LOG_ID, "Show log", "Show log", + "Show the log for the selected variable" ) + + sgPyQt.createAction( GUIcontext.RUN_TELEMAC2D_ID, "Compute case", "Compute case", + "Run Telemac2D solver to compute the case" ) + sgPyQt.createAction( GUIcontext.EDIT_TELEMAC2D_CASE_ID, "Edit case", "Edit case", + "Edit the selected Telemac2D case" ) + + sgPyQt.createAction( GUIcontext.EDIT_COUPLING1D2D_CASE_ID, "Edit coupling", "Edit coupling", + "Edit the selected 1D / 2D coupling" ) + sgPyQt.createAction( GUIcontext.OPEN_SCHEMA_IN_YACS_ID, "Open schema in YACS", "Open schema in YACS", + "Open the selected 1D / 2D coupling schema in YACS" ) + + sgPyQt.createAction( GUIcontext.RUN_PYTEL_ID, "Compute case", "Compute case", + "Run Pytel launcher to compute the case" ) + sgPyQt.createAction( GUIcontext.EDIT_PYTEL_CASE_ID, "Edit case", "Edit case", + "Edit the selected Pytel case" ) + sgPyQt.createAction( GUIcontext.GENERATE_JOB, "Generate batch job", "Generate batch job", + "Generate a batch job to run the selected case") + +################################################ +# Global variables +################################################ + +# study-to-context map +__study2context__ = {} +# current context +__current_context__ = None +# object counter +__objectid__ = 0 + +################################################ +# Internal methods +################################################ + +### +# get active study ID +### +def _getStudyId(): + return sgPyQt.getStudyId() + +### +# get active study +### +def _getStudy(): + studyId = _getStudyId() + study = getStudyManager().GetStudyByID( studyId ) + return study + +### +# returns True if object has children +### +def _hasChildren( sobj ): + if sobj: + study = _getStudy() + iter = study.NewChildIterator( sobj ) + while iter.More(): + name = iter.Value().GetName() + if name: + return True + iter.Next() + pass + pass + return False + +### +# get current GUI context +### +def _getContext(): + global __current_context__ + return __current_context__ + +### +# set and return current GUI context +# study ID is passed as parameter +### +def _setContext( studyID ): + global __study2context__, __current_context__ + if not __study2context__.has_key(studyID): + __study2context__[studyID] = GUIcontext() + pass + __current_context__ = __study2context__[studyID] + return __current_context__ + +### +# increment object counter in the map +### +def _incObjToMap( m, id ): + if id not in m: m[id] = 0 + m[id] += 1 + pass + +################################################ +# Callback functions +################################################ + +# called when module is activated +# returns True if activating is successfull and False otherwise +def activate(): + ctx = _setContext( _getStudyId() ) + return True + +# called when module is deactivated +def deactivate(): + pass + +# called when active study is changed +# active study ID is passed as parameter +def activeStudyChanged( studyID ): + ctx = _setContext( _getStudyId() ) + pass + +# called when popup menu is invoked +# popup menu and menu context are passed as parameters +def createPopupMenu(popup, context): + ed = getStudyEditor() + _setContext(ed.studyId) + if salome.sg.SelectedCount() == 1: + # one object is selected + sobj = ed.study.FindObjectID(salome.sg.getSelected(0)) + selectedType = ed.getTypeId(sobj) + if selectedType == hydro_study.MASCARET_CASE_TYPE_ID: + popup.addAction(sgPyQt.action(GUIcontext.EDIT_MASCARET_CASE_ID)) + popup.addAction(sgPyQt.action(GUIcontext.RUN_MASCARET_ID)) + elif selectedType == hydro_study.TELEMAC2D_CASE_TYPE_ID: + popup.addAction(sgPyQt.action(GUIcontext.EDIT_TELEMAC2D_CASE_ID)) + popup.addAction(sgPyQt.action(GUIcontext.RUN_TELEMAC2D_ID)) + elif selectedType == hydro_study.COUPLING1D2D_CASE_TYPE_ID: + popup.addAction(sgPyQt.action(GUIcontext.EDIT_COUPLING1D2D_CASE_ID)) + popup.addAction(sgPyQt.action(GUIcontext.OPEN_SCHEMA_IN_YACS_ID)) + elif selectedType == hydro_study.LOG_TYPE_ID: + popup.addAction(sgPyQt.action(GUIcontext.SHOW_LOG_ID)) + elif selectedType == hydro_study.PYTEL_CASE_TYPE_ID: + popup.addAction(sgPyQt.action(GUIcontext.EDIT_PYTEL_CASE_ID)) + popup.addAction(sgPyQt.action(GUIcontext.RUN_PYTEL_ID)) + popup.addAction(sgPyQt.action(GUIcontext.GENERATE_JOB)) + +# called when GUI action is activated +# action ID is passed as parameter +def OnGUIEvent( commandID ): + try: + dict_command[commandID]() + except HSGUIException, exc: + QtGui.QMessageBox.critical(sgPyQt.getDesktop(), + QtGui.QApplication.translate("OnGUIEvent", "Error"), + unicode(exc)) + except: + logger.exception("Unhandled exception caught in HYDROSOLVER GUI") + msg = QtGui.QApplication.translate("OnGUIEvent", + "Unhandled error happened in HYDROSOLVER module. Please report a bug on " + 'SALOME bugtracker, ' + 'category "HYDROSOLVER", describing how you got there and including the following traceback:') + msgBox = QtGui.QMessageBox(QtGui.QMessageBox.Critical, + QtGui.QApplication.translate("OnGUIEvent", "Error"), + msg, + parent = sgPyQt.getDesktop()) + msgBox.setDetailedText(traceback.format_exc()) + msgBox.exec_() + +################################################ +# GUI actions implementation +################################################ + +# --------------------------------------------------------------------------------------- # +# Dialog box for text display (deprecated, it was only used in the calcium coupling test) # +# --------------------------------------------------------------------------------------- # +""" +from TextDisplayDialog import Ui_TextDisplayDialog + +class MyTextDisplayDialog(Ui_TextDisplayDialog, QtGui.QDialog): + + def __init__(self, parent = None, modal = 0): + QtGui.QDialog.__init__(self, parent) + Ui_TextDisplayDialog.__init__(self) + self.setupUi(self) + self.connect(self.closeButton, QtCore.SIGNAL("clicked()"), self.close) + + def set_log(self, log): + self.contentTextEdit.setPlainText(log) + self.setWindowTitle("Coupling log") +""" + +### +# Open Eficas for Mascaret to create a new case +### +def create_mascaret_case(): + EficasForMascaretAppli() + +### +# Open Eficas for Mascaret to edit the selected case +### +def edit_mascaret_case(): + EficasForMascaretAppli(get_and_check_selected_file_path()) + +# Run Mascaret on selected case +def run_mascaret(): + try: + with wait_cursor: + ed = hydro_study.HydroStudyEditor() + sobj = ed.editor.study.FindObjectID(salome.sg.getSelected(0)) + (file_list, lig_file, input_vars, output_vars) = ed.get_mascaret_params_from_case(sobj) + var_names = [var["NOM"].strip() for var in output_vars] + mascaret_vars = [var["VARIABLE_MASCARET"].strip() for var in output_vars] + engine = salome.lcc.FindOrLoadComponent("FactoryServer", "MASCARET") + logger.debug("Calling MASCARET.Compute(%s, %s, %s)" % + (file_list, lig_file, mascaret_vars)) + output_values = engine.Compute(file_list, lig_file, mascaret_vars) + ed.add_results_to_mascaret_case(sobj, var_names, output_values) + salome.sg.updateObjBrowser( 0 ) + except SALOME.SALOME_Exception, exc: + salome.sg.updateObjBrowser( 0 ) + msg = unicode(QtGui.QApplication.translate("run_mascaret", + "An error happened while trying to run Mascaret:")) + msg += "\n" + exc.details.text + raise HSGUIException(msg) + +# Display selected log (deprecated, it was only used in the calcium coupling test) +def show_log(): + ed = hydro_study.HydroStudyEditor() + sobj = ed.editor.study.FindObjectID(salome.sg.getSelected(0)) + if sobj is not None: + (found, attr) = getStudyEditor().builder.FindAttribute( + sobj, "AttributeParameter") + log = attr.GetString("log") + dialog = MyTextDisplayDialog(sgPyQt.getDesktop()) + dialog.set_log(log) + dialog.show() + +### +# Open Eficas for Telemac2D to create a new case +### +def create_telemac2d_case(): + EficasForTelemac2DAppli() + +### +# Open Eficas for Telemac2D to edit the selected case +### +def edit_telemac2d_case(): + EficasForTelemac2DAppli(get_and_check_selected_file_path()) + +# Run Telemac2D on selected case +def run_telemac2d(): + engine = None + try: + with wait_cursor: + ed = hydro_study.HydroStudyEditor() + entry = salome.sg.getSelected(0) + engine = salome.lcc.FindOrLoadComponent("Telemac2DContainer", "TELEMAC2D") + engine.Compute(ed.editor.studyId, entry) + # Stop container after execution so that we can use another fortran user file in the next run + engine.GetContainerRef().Shutdown() + except SALOME.SALOME_Exception, exc: + if engine is not None: + engine.GetContainerRef().Shutdown() + msg = unicode(QtGui.QApplication.translate("run_telemac2d", + "An error happened while trying to run Telemac2D:")) + msg += "\n" + exc.details.text + raise HSGUIException(msg) + except Exception, exc: + logger.exception("An error happened in the computation (Telemac2D probably crashed).") + try: + engine.GetContainerRef().Shutdown() + except: + pass + msg = unicode(QtGui.QApplication.translate("run_telemac2d", + "An error happened in the computation (Telemac2D probably crashed, " + "see logs and listing files for more details):")) + msg += "\n" + unicode(exc) + raise HSGUIException(msg) + +### +# Open Eficas for 1D / 2D Coupling to create a new coupling case +### +def create_coupling1d2d_case(): + EficasForCoupling1D2DAppli() + +### +# Open Eficas for 1D / 2D Coupling to edit the selected coupling case +### +def edit_coupling1d2d_case(): + EficasForCoupling1D2DAppli(get_and_check_selected_file_path()) + +def open_schema_in_yacs(): + ed = getStudyEditor() + sobj = ed.study.FindObjectID(salome.sg.getSelected(0)) + filename = sobj.GetComment() + if filename.endswith(".comm"): + filename = filename[:-5] + ".xml" + if not os.path.isfile(filename): + raise HSGUIException(QtGui.QApplication.translate("open_schema_in_yacs", + "Schema file %1 does not exist").arg(filename)) + yg = salome.ImportComponentGUI("YACS") + yg.loadSchema(filename) + +### +# Open Eficas for boundary conditions definition +### +def define_boundary_conditions(): + EficasForBoundaryConditionsAppli() + +### +# Commands dictionary +### +dict_command = { + GUIcontext.CREATE_MASCARET_CASE_ID: create_mascaret_case, + GUIcontext.RUN_MASCARET_ID: run_mascaret, + GUIcontext.EDIT_MASCARET_CASE_ID: edit_mascaret_case, + GUIcontext.SHOW_LOG_ID: show_log, + GUIcontext.CREATE_TELEMAC2D_CASE_ID: create_telemac2d_case, + GUIcontext.RUN_TELEMAC2D_ID: run_telemac2d, + GUIcontext.EDIT_TELEMAC2D_CASE_ID: edit_telemac2d_case, + GUIcontext.CREATE_COUPLING1D2D_CASE_ID: create_coupling1d2d_case, + GUIcontext.EDIT_COUPLING1D2D_CASE_ID: edit_coupling1d2d_case, + GUIcontext.OPEN_SCHEMA_IN_YACS_ID: open_schema_in_yacs, + GUIcontext.CREATE_PYTEL_CASE_ID: pytel_gui.create_case, + GUIcontext.RUN_PYTEL_ID: pytel_gui.run_selected_case, + GUIcontext.EDIT_PYTEL_CASE_ID: pytel_gui.edit_selected_case, + GUIcontext.GENERATE_JOB: pytel_gui.generate_job_for_selected_case, + GUIcontext.DEFINE_BOUNDARY_CONDITIONS_ID: define_boundary_conditions, + } diff --git a/src/HYDROGUI/TextDisplayDialog.ui b/src/HYDROGUI/TextDisplayDialog.ui new file mode 100644 index 0000000..46304ed --- /dev/null +++ b/src/HYDROGUI/TextDisplayDialog.ui @@ -0,0 +1,68 @@ + + + TextDisplayDialog + + + + 0 + 0 + 780 + 560 + + + + Text Display + + + + + + QPlainTextEdit::NoWrap + + + true + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Close + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + diff --git a/src/mascaret_wrapper/CMakeLists.txt b/src/mascaret_wrapper/CMakeLists.txt new file mode 100644 index 0000000..a84cb5b --- /dev/null +++ b/src/mascaret_wrapper/CMakeLists.txt @@ -0,0 +1,67 @@ +# Copyright (C) 2012-2013 EDF +# +# This file is part of SALOME HYDRO module. +# +# SALOME HYDRO module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SALOME HYDRO module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SALOME HYDRO module. If not, see . + +INCLUDE(${SWIG_USE_FILE}) + +# --- options --- + +# additional include directories +INCLUDE_DIRECTORIES( + ${PYTHON_INCLUDE_DIRS} + ${MASCARET_INCLUDE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} +) + +# swig flags +SET_SOURCE_FILES_PROPERTIES(mascaret_swig.i PROPERTIES + CPLUSPLUS ON + SWIG_DEFINITIONS "-shadow") + +# additional preprocessor / compiler flags +ADD_DEFINITIONS( + ${PYTHON_DEFINITIONS} + ) + +# libraries to link to +SET(_link_LIBRARIES + ${PYTHON_LIBRARIES} + ${MASCARET_LIBRARIES} + ) + +# --- sources --- +SET(mascaret_SOURCES + Mascaret.cxx + ) +# --- headers --- +SET(mascaret_HEADERS + Mascaret.hxx + ) + +# --- scripts --- +# scripts / swig wrappings +SET(_swig_SCRIPTS + ${CMAKE_CURRENT_BINARY_DIR}/mascaret_swig.py +) + +# --- rules --- +SWIG_ADD_MODULE(mascaret_swig python mascaret_swig.i ${mascaret_SOURCES}) +SWIG_LINK_LIBRARIES(mascaret_swig "${_link_LIBRARIES}") + +SET(mypkgpythondir ${SALOME_INSTALL_PYTHON}/salome/hydro/mascaret) + +INSTALL(TARGETS ${SWIG_MODULE_mascaret_swig_REAL_NAME} DESTINATION ${mypkgpythondir}) +SALOME_INSTALL_SCRIPTS("${_swig_SCRIPTS}" ${mypkgpythondir}) diff --git a/src/mascaret_wrapper/Mascaret.cxx b/src/mascaret_wrapper/Mascaret.cxx new file mode 100644 index 0000000..db999b0 --- /dev/null +++ b/src/mascaret_wrapper/Mascaret.cxx @@ -0,0 +1,225 @@ +// Copyright (C) 2012-2013 EDF +// +// This file is part of SALOME HYDRO module. +// +// SALOME HYDRO module is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SALOME HYDRO module is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SALOME HYDRO module. If not, see . + +#include +#include +#include +#include + +extern "C" +{ +#include +} + +#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. + +#ifndef MASCARET_HXX_ +#define MASCARET_HXX_ + +#include +#include + +namespace SalomeHydro +{ + +typedef struct MascaretFile +{ + std::string fileName; + std::string fileType; +} MascaretFile; + +typedef std::vector MascaretFileList; + +class MascaretException: public std::runtime_error +{ +public: + + MascaretException(const std::string & msg); + virtual ~MascaretException() throw(); + + const char * __str__() const; + +}; + +class Mascaret +{ +public: + + // Constructor and destructor + Mascaret(); + virtual ~Mascaret(); + + // Get and set printing flag + bool isPrinting(); + void setPrinting(bool printing); + + // Model initialization + void importModel(const MascaretFileList & fileList); + void initState(const std::string & ligFileName); + + // Save / restore state + int saveState(); + void restoreState(int stateId); + + // Computation + void compute(double startTime, double endTime, double timeStep); + void compute(); + + // Model and state edition + int getInt(const std::string & varName, int index1, int index2, int index3); + double getDouble(const std::string & varName, int index1, int index2, int index3); + void setInt(const std::string & varName, int index1, int index2, int index3, int value); + void setDouble(const std::string & varName, int index1, int index2, int index3, double value); + +protected: + + void testMascaretResult(int res, const std::string & functionName); + + int _id; + bool _printing; + +}; + +} + +#endif /* MASCARET_HXX_ */ diff --git a/src/mascaret_wrapper/mascaret_swig.i b/src/mascaret_wrapper/mascaret_swig.i new file mode 100644 index 0000000..08fd1d4 --- /dev/null +++ b/src/mascaret_wrapper/mascaret_swig.i @@ -0,0 +1,43 @@ +// Copyright (C) 2012-2013 EDF +// +// This file is part of SALOME HYDRO module. +// +// SALOME HYDRO module is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SALOME HYDRO module is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SALOME HYDRO module. If not, see . + +%module mascaret_swig + +%include std_string.i + +%include std_vector.i + +%{ +#include "Mascaret.hxx" +%} + +// Instantiate template used by Mascaret +%template(MascaretFileVector) std::vector; + +// 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" diff --git a/src/salome_hydro/CMakeLists.txt b/src/salome_hydro/CMakeLists.txt new file mode 100644 index 0000000..0560891 --- /dev/null +++ b/src/salome_hydro/CMakeLists.txt @@ -0,0 +1,34 @@ +# 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 . + +ADD_SUBDIRECTORY(mascaret) +ADD_SUBDIRECTORY(telemac2d) +ADD_SUBDIRECTORY(pytel) +ADD_SUBDIRECTORY(coupling1d2d) +ADD_SUBDIRECTORY(boundary_conditions) + +# --- Python files --- + +SET(PYFILES + __init__.py + study.py + gui_utils.py +) + +# --- rules --- + +SALOME_INSTALL_SCRIPTS("${PYFILES}" ${SALOME_INSTALL_PYTHON}/salome/hydro) diff --git a/src/salome_hydro/__init__.py b/src/salome_hydro/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/salome_hydro/boundary_conditions/CMakeLists.txt b/src/salome_hydro/boundary_conditions/CMakeLists.txt new file mode 100644 index 0000000..e9fe301 --- /dev/null +++ b/src/salome_hydro/boundary_conditions/CMakeLists.txt @@ -0,0 +1,28 @@ +# Copyright (C) 2012-2013 EDF +# +# This file is part of SALOME HYDRO module. +# +# SALOME HYDRO module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SALOME HYDRO module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SALOME HYDRO module. If not, see . + +ADD_SUBDIRECTORY(eficas) + +# --- Python files --- + +SET(PYFILES + __init__.py +) + +# --- rules --- + +SALOME_INSTALL_SCRIPTS("${PYFILES}" ${SALOME_INSTALL_PYTHON}/salome/hydro/boundary_conditions) diff --git a/src/salome_hydro/boundary_conditions/__init__.py b/src/salome_hydro/boundary_conditions/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/salome_hydro/boundary_conditions/eficas/CMakeLists.txt b/src/salome_hydro/boundary_conditions/eficas/CMakeLists.txt new file mode 100644 index 0000000..9d5d320 --- /dev/null +++ b/src/salome_hydro/boundary_conditions/eficas/CMakeLists.txt @@ -0,0 +1,32 @@ +# 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 . + +# --- Python files --- + +SET(PYFILES + __init__.py + configuration_boundary_conditions.py + prefs_boundary_conditions.py + prefs.py + boundary_conditions_cata.py + appli.py + generator_boundary_conditions.py +) + +# --- rules --- + +SALOME_INSTALL_SCRIPTS("${PYFILES}" ${SALOME_INSTALL_PYTHON}/salome/hydro/boundary_conditions/eficas) diff --git a/src/salome_hydro/boundary_conditions/eficas/__init__.py b/src/salome_hydro/boundary_conditions/eficas/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/salome_hydro/boundary_conditions/eficas/appli.py b/src/salome_hydro/boundary_conditions/eficas/appli.py new file mode 100644 index 0000000..b378329 --- /dev/null +++ b/src/salome_hydro/boundary_conditions/eficas/appli.py @@ -0,0 +1,45 @@ +# 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 . + +import os +import sys + +import SalomePyQt +sgPyQt = SalomePyQt.SalomePyQt() + +import eficasSalome + +class EficasForBoundaryConditionsAppli(eficasSalome.MyEficas): + """ + This class launches Eficas with "boundary_conditions" catalog. + """ + def __init__(self, fichier = None, version = None): + self.codedir = os.path.dirname(__file__) + sys.path[:0] = [self.codedir] + eficasSalome.MyEficas.__init__(self, sgPyQt.getDesktop(), "boundary_conditions", + fichier, version = version) + + def addJdcInSalome(self, jdcPath): + """ + Those files are not added in Salome study tree for now. + """ + pass + + def closeEvent(self, event): + while self.codedir in sys.path: + sys.path.remove(self.codedir) + eficasSalome.MyEficas.closeEvent(self, event) diff --git a/src/salome_hydro/boundary_conditions/eficas/boundary_conditions_cata.py b/src/salome_hydro/boundary_conditions/eficas/boundary_conditions_cata.py new file mode 100644 index 0000000..9bb4796 --- /dev/null +++ b/src/salome_hydro/boundary_conditions/eficas/boundary_conditions_cata.py @@ -0,0 +1,59 @@ +# -*- 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 . + +from Accas import * + +class grma(GEOM): + """ + Class used to define the group on which the boundary condition is defined. + Method __convert__ is redefined to skip the test on the string length. + """ + def __convert__(cls, valeur): + if isinstance(valeur, (str, unicode)): + return valeur.strip() + raise ValueError(_('A string is expected')) + + __convert__ = classmethod(__convert__) + + +JdC = JDC_CATA(regles = (AU_MOINS_UN('BOUNDARY_CONDITION',)), + ) + +BOUNDARY_CONDITION = PROC( + nom = "BOUNDARY_CONDITION", op = None, + fr = u"Définition d'une condition limite pour Telemac2D", + ang = u"Definition of a boundary condition for Telemac2D", + + GROUP = SIMP(statut = "o", typ = grma, + fr = u"Groupe sur lequel la condition limite est définie", + ang = u"Group on which the boundary condition is defined", + ), + LIHBOR = SIMP(statut = "o", typ = "I", + fr = u"Type de condition limite pour la hauteur d'eau", + ang = u"Boundary condition type for the water height", + ), + LIUBOR = SIMP(statut = "o", typ = "I", + fr = u"Type de condition limite pour la composante U de la vitesse", + ang = u"Boundary condition type for the U component of the water velocity", + ), + LIVBOR = SIMP(statut = "o", typ = "I", + fr = u"Type de condition limite pour la composante V de la vitesse", + ang = u"Boundary condition type for the V component of the water velocity", + ), +) diff --git a/src/salome_hydro/boundary_conditions/eficas/configuration_boundary_conditions.py b/src/salome_hydro/boundary_conditions/eficas/configuration_boundary_conditions.py new file mode 100644 index 0000000..ffed4a6 --- /dev/null +++ b/src/salome_hydro/boundary_conditions/eficas/configuration_boundary_conditions.py @@ -0,0 +1,48 @@ +# -*- 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 . + +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("boundary_conditions", + os.path.join(repIni, "boundary_conditions_cata.py"), + file_format = "boundary_conditions"),) + self.lang = 'fr' + self.generator_module = "generator_boundary_conditions" + + def save_params(self): + pass + +def make_config(appli, rep): + return CONFIG(appli, rep) + +def make_config_style(appli, rep): + return None diff --git a/src/salome_hydro/boundary_conditions/eficas/generator_boundary_conditions.py b/src/salome_hydro/boundary_conditions/eficas/generator_boundary_conditions.py new file mode 100644 index 0000000..ea7235d --- /dev/null +++ b/src/salome_hydro/boundary_conditions/eficas/generator_boundary_conditions.py @@ -0,0 +1,57 @@ +# 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 . + +import os +from generator.generator_python import PythonGenerator + +def entryPoint(): + return {'name': 'boundary_conditions', + 'factory': BoundaryConditionsGenerator} + +class BoundaryConditionsGenerator(PythonGenerator): + """ + This generator creates files containing associations between groups and + boundary conditions (.bcd files, for Boundary Conditions Definition). + Those files contain one line per group, each line containing four fields + separated by spaces: LIHBOR LIUBOR LIVBOR GROUP. + LIHBOR, LIUBOR and LIVBOR are integer values, GROUP is a string (the name of + the group). + + Example: + + + """ + + def gener(self, obj, format = 'brut', config = None): + self.group_list = [] + self.text = PythonGenerator.gener(self, obj, format) + return self.text + + def generPROC_ETAPE(self, obj): + group_dict = {} + for keyword in obj.mc_liste: + group_dict[keyword.nom] = keyword.valeur + self.group_list.append(group_dict) + return PythonGenerator.generPROC_ETAPE(self, obj) + + def writeDefault(self, basefilename): + output_filename = os.path.splitext(basefilename)[0] + ".bcd" + f = open(output_filename, 'w') + f.write("%d\n" % len(self.group_list)) + for group_dict in self.group_list: + f.write("%(LIHBOR)d %(LIUBOR)d %(LIVBOR)d %(GROUP)s\n" % group_dict) + f.close() diff --git a/src/salome_hydro/boundary_conditions/eficas/prefs.py b/src/salome_hydro/boundary_conditions/eficas/prefs.py new file mode 100644 index 0000000..8f7d046 --- /dev/null +++ b/src/salome_hydro/boundary_conditions/eficas/prefs.py @@ -0,0 +1,18 @@ +# Copyright (C) 2012-2013 EDF +# +# This file is part of SALOME HYDRO module. +# +# SALOME HYDRO module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SALOME HYDRO module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SALOME HYDRO module. If not, see . + +code = "boundary_conditions" diff --git a/src/salome_hydro/boundary_conditions/eficas/prefs_boundary_conditions.py b/src/salome_hydro/boundary_conditions/eficas/prefs_boundary_conditions.py new file mode 100644 index 0000000..bcf1ef2 --- /dev/null +++ b/src/salome_hydro/boundary_conditions/eficas/prefs_boundary_conditions.py @@ -0,0 +1,21 @@ +# 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 . + +import os + +repIni = os.path.dirname(__file__) +INSTALLDIR = os.getenv("EFICAS_ROOT") diff --git a/src/salome_hydro/coupling1d2d/CMakeLists.txt b/src/salome_hydro/coupling1d2d/CMakeLists.txt new file mode 100644 index 0000000..5274761 --- /dev/null +++ b/src/salome_hydro/coupling1d2d/CMakeLists.txt @@ -0,0 +1,28 @@ +# Copyright (C) 2012-2013 EDF +# +# This file is part of SALOME HYDRO module. +# +# SALOME HYDRO module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SALOME HYDRO module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SALOME HYDRO module. If not, see . + +ADD_SUBDIRECTORY(eficas) + +# --- Python files --- + +SET(PYFILES + __init__.py +) + +# --- rules --- + +SALOME_INSTALL_SCRIPTS("${PYFILES}" ${SALOME_INSTALL_PYTHON}/salome/hydro/coupling1d2d) diff --git a/src/salome_hydro/coupling1d2d/__init__.py b/src/salome_hydro/coupling1d2d/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/salome_hydro/coupling1d2d/eficas/CMakeLists.txt b/src/salome_hydro/coupling1d2d/eficas/CMakeLists.txt new file mode 100644 index 0000000..3fea4fa --- /dev/null +++ b/src/salome_hydro/coupling1d2d/eficas/CMakeLists.txt @@ -0,0 +1,39 @@ +# Copyright (C) 2012-2013 EDF +# +# This file is part of SALOME HYDRO module. +# +# SALOME HYDRO module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SALOME HYDRO module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SALOME HYDRO module. If not, see . + +# --- Python files --- + +SET(PYFILES + __init__.py + configuration_coupling1d2d.py + prefs_coupling1d2d.py + prefs.py + coupling1d2d_cata.py + appli.py + generator_coupling1d2d.py +) + +# --- Data files --- + +SET(DATAFILES + coupling1d2d_template_schema.xml +) + +# --- rules --- + +SALOME_INSTALL_SCRIPTS("${PYFILES}" ${SALOME_INSTALL_PYTHON}/salome/hydro/coupling1d2d/eficas) +INSTALL(FILES ${DATAFILES} DESTINATION ${SALOME_INSTALL_PYTHON}/salome/hydro/coupling1d2d/eficas) diff --git a/src/salome_hydro/coupling1d2d/eficas/__init__.py b/src/salome_hydro/coupling1d2d/eficas/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/salome_hydro/coupling1d2d/eficas/appli.py b/src/salome_hydro/coupling1d2d/eficas/appli.py new file mode 100644 index 0000000..30843c4 --- /dev/null +++ b/src/salome_hydro/coupling1d2d/eficas/appli.py @@ -0,0 +1,113 @@ +# -*- 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 . + +import os +import sys +import re + +from PyQt4.QtGui import QMessageBox + +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] + eficasSalome.MyEficas.__init__(self, sgPyQt.getDesktop(), "coupling1d2d", + fichier, version = version) + sgPyQt.createView("Eficas Coupling 1D/2D", self) + + def selectGroupFromSalome(self, kwType = None, editor=None): + """ + Select an entry from Salome object browser + """ + nbEntries = salome.sg.SelectedCount() + if nbEntries < 1: + msg = u"Veuillez sélectionner une entrée de l'arbre d'étude de Salome" + QMessageBox.information(self, self.tr(u"Sélection depuis Salome"), self.tr(msg)) + return [], msg + elif nbEntries > 1: + msg = u"Une seule entrée doit être sélectionnée dans l'arbre d'étude de Salome" + QMessageBox.information(self, self.tr(u"Sélection depuis Salome"), self.tr(msg)) + return [], msg + else: + try: + value = kwType.get_selected_value(salome.sg.getSelected(0), self.ed.editor) + msg = u"L'entrée de l'arbre d'étude de Salome a été sélectionnée" + return [value], msg + except Exception, e: + QMessageBox.information(self, self.tr(u"Sélection depuis Salome"), self.tr(unicode(e))) + return [], unicode(e) + + def addJdcInSalome(self, jdcPath): + """ + Add the newly created file in Salome study + """ + try: + self.ed.find_or_create_coupling1d2d_case(jdcPath) + except Exception, exc: + msgError = "Can't add file to Salome study tree" + logger.exception(msgError) + QMessageBox.warning(self, self.tr("Warning"), + self.tr("%s. Reason:\n%s\n\nSee logs for more details." % (msgError, exc))) + salome.sg.updateObjBrowser(0) + + def closeEvent(self, event): + while self.codedir in sys.path: + sys.path.remove(self.codedir) + eficasSalome.MyEficas.closeEvent(self, event) diff --git a/src/salome_hydro/coupling1d2d/eficas/configuration_coupling1d2d.py b/src/salome_hydro/coupling1d2d/eficas/configuration_coupling1d2d.py new file mode 100644 index 0000000..503fa36 --- /dev/null +++ b/src/salome_hydro/coupling1d2d/eficas/configuration_coupling1d2d.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2013 EDF +# +# This file is part of SALOME HYDRO module. +# +# SALOME HYDRO module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SALOME HYDRO module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SALOME HYDRO module. If not, see . + +import os + +from Editeur.catadesc import CatalogDescription +from InterfaceQT4.configuration import CONFIG_BASE + +class CONFIG(CONFIG_BASE): + + def __init__(self, appli, repIni): + """ + This class stores the configuration parameters for Eficas + """ + CONFIG_BASE.__init__(self, appli, repIni) + + # Configuration parameters + self.savedir = os.getenv("HOME") + self.catalogues = (CatalogDescription("coupling1d2d", + os.path.join(repIni, "coupling1d2d_cata.py"), + file_format = "coupling1d2d"),) + self.lang = 'fr' + + self.generator_module = "generator_coupling1d2d" + + def save_params(self): + pass + + def get_template_file(self): + return os.path.join(self.repIni, "coupling1d2d_template_schema.xml") + + def get_extension(self): + return ".xml" + +def make_config(appli, rep): + return CONFIG(appli, rep) + +def make_config_style(appli, rep): + return None diff --git a/src/salome_hydro/coupling1d2d/eficas/coupling1d2d_cata.py b/src/salome_hydro/coupling1d2d/eficas/coupling1d2d_cata.py new file mode 100644 index 0000000..b5b1ffe --- /dev/null +++ b/src/salome_hydro/coupling1d2d/eficas/coupling1d2d_cata.py @@ -0,0 +1,46 @@ +# -*- 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 . + +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"), +) diff --git a/src/salome_hydro/coupling1d2d/eficas/coupling1d2d_template_schema.xml b/src/salome_hydro/coupling1d2d/eficas/coupling1d2d_template_schema.xml new file mode 100644 index 0000000..38908ab --- /dev/null +++ b/src/salome_hydro/coupling1d2d/eficas/coupling1d2d_template_schema.xml @@ -0,0 +1,447 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MASCARET + + ExecStep + + + + + + TELEMAC2D + + ExecStep + + + + + MascExecStep ConvergenceController + MascExecStep TelExecStep + TelExecStep ConvergenceController + + ConvergenceController timeData + MascExecStep timeData + + + ConvergenceController timeData + TelExecStep timeData + + + ConvergenceController telemacData + MascExecStep inputData + + + MascExecStep outputData + ConvergenceController mascData + + + MascExecStep outputData + TelExecStep inputData + + + TelExecStep outputData + ConvergenceController telemacData + + + + ConvergenceBloc.ConvergenceController iter + ConvergenceBloc.ConvergenceController iter + + + ConvergenceBloc.ConvergenceController timeData + ConvergenceBloc.ConvergenceController timeData + + + ConvergenceLoop TimeController + + TimeController cont + ConvergenceLoop condition + + + TimeController timeData + ConvergenceLoop.ConvergenceBloc.ConvergenceController timeData + + + TimeController timeData + ConvergenceLoop.ConvergenceBloc.MascExecStep timeData + + + TimeController timeData + ConvergenceLoop.ConvergenceBloc.TelExecStep timeData + + + ConvergenceLoop.ConvergenceBloc.ConvergenceController cont + ConvergenceLoop condition + + + + TimeBloc.TimeController time + TimeBloc.TimeController time + + + + TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.MascExecStep + Init + + + + + + + + + + + + + + + + + + + + + TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.MascExecStep + Finalize + + + TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.TelExecStep + Init + + + + + TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.TelExecStep + Finalize + + + TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.MascExecStep + InitBorders + + + + TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.TelExecStep + InitBorders + + + TimeLoop FinalizeMascaret + TimeLoop FinalizeTelemac + InitMascaret TimeLoop + InitCoupling TimeLoop + InitCoupling InitMascBorders + InitCoupling InitTelBorders + InitTelemac TimeLoop + InitTelemac InitTelBorders + InitMascBorders TimeLoop + InitTelBorders TimeLoop + + InitCoupling starttime + TimeLoop.TimeBloc.TimeController time + + + InitCoupling endtime + TimeLoop.TimeBloc.TimeController endtime + + + InitCoupling timestep + TimeLoop.TimeBloc.TimeController timestep + + + InitCoupling eps_Z + TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.ConvergenceController Z_tol + + + InitCoupling eps_Q + TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.ConvergenceController Q_tol + + + InitCoupling borders + TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.ConvergenceController borders + + + InitCoupling borders + InitMascBorders borders + + + InitCoupling borders + InitTelBorders borders + + + InitCoupling timeData + TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.ConvergenceController timeData + + + InitCoupling timeData + TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.MascExecStep timeData + + + InitCoupling timeData + TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.TelExecStep timeData + + + InitCoupling log + TimeLoop.TimeBloc.TimeController log + + + InitCoupling log + TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.ConvergenceController log + + + InitCoupling maxiter + TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.ConvergenceController maxiter + + + InitCoupling graph + TimeLoop.TimeBloc.TimeController graph + + + InitCoupling graph + TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.ConvergenceController graph + + + TimeLoop.TimeBloc.TimeController cont + TimeLoop condition + + + InitMascaretstudyID + 1 + + + InitMascaretdetCaseEntry + %parse_entry(CAS_MASCARET)% + + + InitCouplingcouplingFile + %FICHIER_COUPLAGE% + + + InitCouplinglogFile + %FICHIER_LOG% + + + InitCouplinggraphFile + %FICHIER_GRAPHIQUE% + + + TimeLoopcondition + true + + + TimeLoop.TimeBloc.ConvergenceLoopcondition + true + + + TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.ConvergenceControlleriter + 1 + + + TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.MascExecStepinputData + N. + + + TimeLoop.TimeBloc.ConvergenceLoop.ConvergenceBloc.TelExecStepinputData + N. + + + InitTelemacstudyID + 1 + + + InitTelemacdetCaseEntry + %parse_entry(CAS_TELEMAC2D)% + + + + + + + + + + + + + + + + + + diff --git a/src/salome_hydro/coupling1d2d/eficas/generator_coupling1d2d.py b/src/salome_hydro/coupling1d2d/eficas/generator_coupling1d2d.py new file mode 100644 index 0000000..4fd1225 --- /dev/null +++ b/src/salome_hydro/coupling1d2d/eficas/generator_coupling1d2d.py @@ -0,0 +1,67 @@ +# Copyright (C) 2012-2013 EDF +# +# This file is part of SALOME HYDRO module. +# +# SALOME HYDRO module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SALOME HYDRO module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SALOME HYDRO module. If not, see . + +import re + +from generator.generator_file_from_template import FileFromTemplateGenerator + +def entryPoint(): + return {'name': 'coupling1d2d', + 'factory' : Coupling1D2DGenerator} + +class Coupling1D2DGenerator(FileFromTemplateGenerator): + """ + This generator is mostly identical to FileFromTemplateGenerator, but it + can also perform replacements using functions. The syntax for this kind + of replacement is %func(KEYWORD)%. The replacement method will call + the function "func" that must be defined in this class with the parameter + KEYWORD. The available function is parse_entry. + """ + + def generate_output_from_template(self): + """ + Generate the output by replacing the keywords and the functions in the + template. + """ + FileFromTemplateGenerator.generate_output_from_template(self) + self.output_text = self.replace_functions(self.output_text) + + def replace_functions(self, template_string): + """ + Replace the functions in the template string. + """ + result = template_string + pattern = "%(.*)\((.*)\)%" + matchObj = re.search(pattern, result) + while matchObj: + (whole_string, func_name, param_keyword) = matchObj.group(0, 1, 2) + param_value = self.kw_dict[param_keyword] + func = eval(func_name) + value = func(param_value) + result = result.replace(whole_string, value) + matchObj = re.search(pattern, result) + return result + +def parse_entry(selected_value): + """ + Find entry if selected_value is something like "name (entry)" + """ + entry = selected_value + match = re.search("\((.*)\)$", entry) + if match is not None: + entry = match.group(1) + return entry diff --git a/src/salome_hydro/coupling1d2d/eficas/prefs.py b/src/salome_hydro/coupling1d2d/eficas/prefs.py new file mode 100644 index 0000000..ddbb7a1 --- /dev/null +++ b/src/salome_hydro/coupling1d2d/eficas/prefs.py @@ -0,0 +1,18 @@ +# Copyright (C) 2012-2013 EDF +# +# This file is part of SALOME HYDRO module. +# +# SALOME HYDRO module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SALOME HYDRO module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SALOME HYDRO module. If not, see . + +code = "coupling1d2d" diff --git a/src/salome_hydro/coupling1d2d/eficas/prefs_coupling1d2d.py b/src/salome_hydro/coupling1d2d/eficas/prefs_coupling1d2d.py new file mode 100644 index 0000000..82d946e --- /dev/null +++ b/src/salome_hydro/coupling1d2d/eficas/prefs_coupling1d2d.py @@ -0,0 +1,22 @@ +# 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 . + +import os +import sys + +repIni = os.path.dirname(__file__) +INSTALLDIR = os.getenv("EFICAS_ROOT") diff --git a/src/salome_hydro/gui_utils.py b/src/salome_hydro/gui_utils.py new file mode 100644 index 0000000..0463e04 --- /dev/null +++ b/src/salome_hydro/gui_utils.py @@ -0,0 +1,61 @@ +# 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 . + +import os +from PyQt4 import QtCore, QtGui + +import salome +from salome.kernel.studyedit import getStudyEditor + + +class HSGUIException(Exception): + """ + Exception class used to display user-friendly messages in a dialog box for + standard errors (missing files, etc.). + """ + pass + + +class OverrideCursorCM: + """ + This class is a context manager that can be used to set an override cursor + in a QT application and automatically restore the base cursor + """ + def __init__(self, cursor): + self.cursor = cursor + + def __enter__(self): + QtGui.QApplication.setOverrideCursor(self.cursor) + + def __exit__(self, exc_type, exc_value, traceback): + QtGui.QApplication.restoreOverrideCursor() + +wait_cursor = OverrideCursorCM(QtGui.QCursor(QtCore.Qt.WaitCursor)) + + +def get_and_check_selected_file_path(): + """ + Get the first selected item in the object browser, check that its "Comment" + attribute contains a valid file path, and return this file path. + """ + ed = getStudyEditor() + sobj = ed.study.FindObjectID(salome.sg.getSelected(0)) + filepath = sobj.GetComment() + if not os.path.isfile(filepath): + raise HSGUIException(QtGui.QApplication.translate("get_and_check_selected_file_path", + "File %1 does not exist").arg(filepath)) + return filepath diff --git a/src/salome_hydro/mascaret/CMakeLists.txt b/src/salome_hydro/mascaret/CMakeLists.txt new file mode 100644 index 0000000..91f7cd3 --- /dev/null +++ b/src/salome_hydro/mascaret/CMakeLists.txt @@ -0,0 +1,28 @@ +# Copyright (C) 2012-2013 EDF +# +# This file is part of SALOME HYDRO module. +# +# SALOME HYDRO module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SALOME HYDRO module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SALOME HYDRO module. If not, see . + +ADD_SUBDIRECTORY(eficas) + +# --- Python files --- + +SET(PYFILES + __init__.py +) + +# --- rules --- + +SALOME_INSTALL_SCRIPTS("${PYFILES}" ${SALOME_INSTALL_PYTHON}/salome/hydro/mascaret) diff --git a/src/salome_hydro/mascaret/__init__.py b/src/salome_hydro/mascaret/__init__.py new file mode 100644 index 0000000..5bccc27 --- /dev/null +++ b/src/salome_hydro/mascaret/__init__.py @@ -0,0 +1,22 @@ +# 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 . + +import mascaret_swig + +Mascaret = mascaret_swig.Mascaret +MascaretFile = mascaret_swig.MascaretFile +MascaretException = mascaret_swig.MascaretException diff --git a/src/salome_hydro/mascaret/eficas/CMakeLists.txt b/src/salome_hydro/mascaret/eficas/CMakeLists.txt new file mode 100644 index 0000000..deb3c65 --- /dev/null +++ b/src/salome_hydro/mascaret/eficas/CMakeLists.txt @@ -0,0 +1,31 @@ +# 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 . + +# --- Python files --- + +SET(PYFILES + __init__.py + appli.py + configuration_mascaret.py + prefs_mascaret.py + prefs.py + mascaret_V7_cata.py +) + +# --- rules --- + +SALOME_INSTALL_SCRIPTS("${PYFILES}" ${SALOME_INSTALL_PYTHON}/salome/hydro/mascaret/eficas) diff --git a/src/salome_hydro/mascaret/eficas/__init__.py b/src/salome_hydro/mascaret/eficas/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/salome_hydro/mascaret/eficas/appli.py b/src/salome_hydro/mascaret/eficas/appli.py new file mode 100644 index 0000000..126a184 --- /dev/null +++ b/src/salome_hydro/mascaret/eficas/appli.py @@ -0,0 +1,75 @@ +# -*- 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 . + +import os +import sys +import re + +from PyQt4.QtGui import QMessageBox + +import salome +import SalomePyQt +sgPyQt = SalomePyQt.SalomePyQt() + +from salome.kernel.logger import Logger +from salome.kernel import termcolor +logger = Logger("salome.hydro.mascaret.eficas.appli", + color = termcolor.GREEN_FG) + +import eficasSalome + +from salome.hydro.study import HydroStudyEditor + +class EficasForMascaretAppli(eficasSalome.MyEficas): + """ + This class launches Eficas and adds entries for the created files in + MASCARET 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] + eficasSalome.MyEficas.__init__(self, sgPyQt.getDesktop(), + "mascaret", + fichier, version = version) + sgPyQt.createView("Eficas Mascaret", self) + + def addJdcInSalome(self, jdcPath): + """ + Add the newly created file in Salome study + """ + try: + self.ed.find_or_create_mascaret_case(jdcPath) + except Exception, exc: + msgError = "Can't add file to Salome study tree" + logger.exception(msgError) + QMessageBox.warning(self, self.tr("Warning"), + self.tr("%s. Reason:\n%s\n\nSee logs for " + "more details." % (msgError, exc))) + salome.sg.updateObjBrowser(0) + + def closeEvent(self, event): + while self.codedir in sys.path: + sys.path.remove(self.codedir) + eficasSalome.MyEficas.closeEvent(self, event) diff --git a/src/salome_hydro/mascaret/eficas/configuration_mascaret.py b/src/salome_hydro/mascaret/eficas/configuration_mascaret.py new file mode 100644 index 0000000..7695ed4 --- /dev/null +++ b/src/salome_hydro/mascaret/eficas/configuration_mascaret.py @@ -0,0 +1,46 @@ +# -*- 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 . + +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("mascaret_V7", + os.path.join(repIni, "mascaret_V7_cata.py")),) + self.lang = 'fr' + + def save_params(self): + pass + +def make_config(appli, rep): + return CONFIG(appli, rep) + +def make_config_style(appli, rep): + return None diff --git a/src/salome_hydro/mascaret/eficas/mascaret_V7_cata.py b/src/salome_hydro/mascaret/eficas/mascaret_V7_cata.py new file mode 100644 index 0000000..3ff4e0a --- /dev/null +++ b/src/salome_hydro/mascaret/eficas/mascaret_V7_cata.py @@ -0,0 +1,106 @@ +# -*- 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 . + +from Accas import * + +JdC = JDC_CATA(regles = (UN_PARMI('MASCARET',)), + ) + +MASCARET = PROC( + nom = "MASCARET", op = None, + fr = u"Définition d'un cas d'étude Mascaret", + ang = u"Definition of a Mascaret study case", + FICHIER_DICO = SIMP(statut = "o", typ = 'Fichier', + fr = u"Fichier Dictionnaire", + ang = u"Dictionary file"), + FICHIER_MOT_CLE = SIMP(statut = "o", + typ = ('Fichier', 'Fichiers CAS (*.cas);;Tous les fichiers (*)',), + fr = u"Fichier Mot Clé", + ang = u"Keyword file"), + FICHIER_GEOMETRIE = SIMP(statut = "f", + typ = ('Fichier', 'Fichiers GEO (*.geo);;Tous les fichiers (*)',), + fr = u"Fichier de géométrie", + ang = u"Geometry file"), + FICHIER_LOI = FACT(statut = 'f', max = '**', + NOM = SIMP(statut = "o", + typ = ('Fichier', 'Fichiers LOI (*.loi);;Tous les fichiers (*)',), + fr = u"Fichier de lois", + ang = u"Laws file"), + ), + FICHIER_ABAQUES = SIMP(statut = "f", + typ = ('Fichier', 'Tous les fichiers (*)',), + fr = u"Fichier abaques", + ang = u"Abacus file"), + FICHIER_CASIER = SIMP(statut = "f", + typ = ('Fichier', 'Tous les fichiers (*)',), + fr = u"Fichier casier", + ang = u"Compartment file"), + FICHIER_DAMOCLE = SIMP(statut = "f", + typ = ('Fichier', 'Tous les fichiers (*)',), + fr = u"Fichier damocle", + ang = u"Damocle file"), + FICHIER_LIG = SIMP(statut = "o", + typ = ('Fichier', 'Fichiers LIG (*.lig);;Tous les fichiers (*)',), + fr = u"Fichier LIG", + ang = u"LIG file"), + LISTING = SIMP(statut = "f", + typ = ('Fichier', 'Tous les fichiers (*)', "Sauvegarde"), + fr = u"Fichier de listing", + ang = u"Listing file"), + LISTING_CASIER = SIMP(statut = "f", + typ = ('Fichier', 'Tous les fichiers (*)', "Sauvegarde"), + fr = u"Fichier de listing casier", + ang = u"Compartment listing file"), + LISTING_LIAISON = SIMP(statut = "f", + typ = ('Fichier', 'Tous les fichiers (*)', "Sauvegarde"), + fr = u"Fichier de listing liaison", + ang = u"Link listing file"), + RESULTAT = SIMP(statut = "f", + typ = ('Fichier', 'Tous les fichiers (*)', "Sauvegarde"), + fr = u"Fichier de résultat", + ang = u"Result file"), + RESULTAT_CASIER = SIMP(statut = "f", + typ = ('Fichier', 'Tous les fichiers (*)', "Sauvegarde"), + fr = u"Fichier de résultat casier", + ang = u"Compartment result file"), + RESULTAT_LIAISON = SIMP(statut = "f", + typ = ('Fichier', 'Tous les fichiers (*)', "Sauvegarde"), + fr = u"Fichier de résultat liaison", + ang = u"Link result file"), + VARIABLE_SORTIE = FACT(statut = 'f', max = '**', + fr = u"Variable de sortie du calcul", + ang = u"Computation output variable", + NOM = SIMP(statut = "o", typ = 'TXM', + fr = u"Nom de la variable", + ang = u"Variable name"), + VARIABLE_MASCARET = SIMP(statut = "o", typ = 'TXM', + fr = u'Variable Mascaret (ex : "Etat.Z(1,0,0)")', + ang = u'Mascaret variable (ex : "Etat.Z(1,0,0)")'), + ), + VARIABLE_ENTREE = FACT(statut = 'f', max = '**', + fr = u"Variable d'entrée du calcul", + ang = u"Computation input variable", + NOM = SIMP(statut = "o", typ = 'TXM', + fr = u"Nom de la variable", + ang = u"Variable name"), + VARIABLE_MASCARET = SIMP(statut = "o", typ = 'TXM', + fr = u'Variable Mascaret (ex : "Modele.Lois.Debit(1,1-2,0)")', + ang = u'Mascaret variable (ex : "Modele.Lois.Debit(1,1-2,0)")'), + ), +) diff --git a/src/salome_hydro/mascaret/eficas/prefs.py b/src/salome_hydro/mascaret/eficas/prefs.py new file mode 100644 index 0000000..d0e8113 --- /dev/null +++ b/src/salome_hydro/mascaret/eficas/prefs.py @@ -0,0 +1,18 @@ +# Copyright (C) 2012-2013 EDF +# +# This file is part of SALOME HYDRO module. +# +# SALOME HYDRO module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SALOME HYDRO module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SALOME HYDRO module. If not, see . + +code = "mascaret" diff --git a/src/salome_hydro/mascaret/eficas/prefs_mascaret.py b/src/salome_hydro/mascaret/eficas/prefs_mascaret.py new file mode 100644 index 0000000..82d946e --- /dev/null +++ b/src/salome_hydro/mascaret/eficas/prefs_mascaret.py @@ -0,0 +1,22 @@ +# 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 . + +import os +import sys + +repIni = os.path.dirname(__file__) +INSTALLDIR = os.getenv("EFICAS_ROOT") diff --git a/src/salome_hydro/pytel/CMakeLists.txt b/src/salome_hydro/pytel/CMakeLists.txt new file mode 100644 index 0000000..ca9b36c --- /dev/null +++ b/src/salome_hydro/pytel/CMakeLists.txt @@ -0,0 +1,44 @@ +# 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 . + +ADD_SUBDIRECTORY(eficas) + +INCLUDE(UsePyQt4) + +# --- Python files --- + +SET(PYFILES + __init__.py + genjob.py + genjobwindow.py + launcher.py + gui.py +) + +# uic files / to be processed by pyuic +SET(UIFILES + genjobwindow.ui +) + +# --- rules --- + +# scripts / pyuic wrappings +PYQT4_WRAP_UIC(PYUICFILES ${UIFILES}) + +SET(ALLPYFILES ${PYFILES} ${PYUICFILES}) + +SALOME_INSTALL_SCRIPTS("${ALLPYFILES}" ${SALOME_INSTALL_PYTHON}/salome/hydro/pytel) diff --git a/src/salome_hydro/pytel/__init__.py b/src/salome_hydro/pytel/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/salome_hydro/pytel/eficas/CMakeLists.txt b/src/salome_hydro/pytel/eficas/CMakeLists.txt new file mode 100644 index 0000000..083540a --- /dev/null +++ b/src/salome_hydro/pytel/eficas/CMakeLists.txt @@ -0,0 +1,31 @@ +# 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 . + +# --- Python files --- + +SET(PYFILES + __init__.py + configuration_pytel.py + prefs_pytel.py + prefs.py + pytel_cata.py + appli.py +) + +# --- rules --- + +SALOME_INSTALL_SCRIPTS("${PYFILES}" ${SALOME_INSTALL_PYTHON}/salome/hydro/pytel/eficas) diff --git a/src/salome_hydro/pytel/eficas/__init__.py b/src/salome_hydro/pytel/eficas/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/salome_hydro/pytel/eficas/appli.py b/src/salome_hydro/pytel/eficas/appli.py new file mode 100644 index 0000000..6963549 --- /dev/null +++ b/src/salome_hydro/pytel/eficas/appli.py @@ -0,0 +1,69 @@ +# 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 . + +import os +import sys + +from PyQt4.QtGui import QMessageBox + +import salome +import SalomePyQt +sgPyQt = SalomePyQt.SalomePyQt() + +from salome.kernel.logger import Logger +from salome.kernel import termcolor +logger = Logger("salome.hydro.pytel.eficas.appli", + color = termcolor.GREEN_FG) + +import eficasSalome + +from salome.hydro.study import HydroStudyEditor + +class EficasForPytelAppli(eficasSalome.MyEficas): + """ + This class launches Eficas and adds entries for the created files in + HYDRO component in the study tree. + + :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] + eficasSalome.MyEficas.__init__(self, sgPyQt.getDesktop(), "pytel", + fichier, version = version) + sgPyQt.createView("Eficas Pytel", self) + + def addJdcInSalome(self, jdcPath): + """ + Add the newly created file in Salome study + """ + try: + self.ed.find_or_create_pytel_case(jdcPath) + except Exception, exc: + msgError = "Can't add file to Salome study tree" + logger.exception(msgError) + QMessageBox.warning(self, self.tr("Warning"), + self.tr("%s. Reason:\n%s\n\nSee logs for more details." % (msgError, exc))) + salome.sg.updateObjBrowser(0) + + def closeEvent(self, event): + while self.codedir in sys.path: + sys.path.remove(self.codedir) + eficasSalome.MyEficas.closeEvent(self, event) diff --git a/src/salome_hydro/pytel/eficas/configuration_pytel.py b/src/salome_hydro/pytel/eficas/configuration_pytel.py new file mode 100644 index 0000000..a1f9708 --- /dev/null +++ b/src/salome_hydro/pytel/eficas/configuration_pytel.py @@ -0,0 +1,43 @@ +# Copyright (C) 2012-2013 EDF +# +# This file is part of SALOME HYDRO module. +# +# SALOME HYDRO module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SALOME HYDRO module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SALOME HYDRO module. If not, see . + +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("pytel", os.path.join(repIni, "pytel_cata.py")),) + self.lang = 'fr' + + def save_params(self): + pass + +def make_config(appli, rep): + return CONFIG(appli, rep) + +def make_config_style(appli, rep): + return None diff --git a/src/salome_hydro/pytel/eficas/prefs.py b/src/salome_hydro/pytel/eficas/prefs.py new file mode 100644 index 0000000..44cf4d7 --- /dev/null +++ b/src/salome_hydro/pytel/eficas/prefs.py @@ -0,0 +1,18 @@ +# Copyright (C) 2012-2013 EDF +# +# This file is part of SALOME HYDRO module. +# +# SALOME HYDRO module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SALOME HYDRO module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SALOME HYDRO module. If not, see . + +code = "pytel" diff --git a/src/salome_hydro/pytel/eficas/prefs_pytel.py b/src/salome_hydro/pytel/eficas/prefs_pytel.py new file mode 100644 index 0000000..82d946e --- /dev/null +++ b/src/salome_hydro/pytel/eficas/prefs_pytel.py @@ -0,0 +1,22 @@ +# 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 . + +import os +import sys + +repIni = os.path.dirname(__file__) +INSTALLDIR = os.getenv("EFICAS_ROOT") diff --git a/src/salome_hydro/pytel/eficas/pytel_cata.py b/src/salome_hydro/pytel/eficas/pytel_cata.py new file mode 100644 index 0000000..e0c0043 --- /dev/null +++ b/src/salome_hydro/pytel/eficas/pytel_cata.py @@ -0,0 +1,53 @@ +# -*- 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 . + +from Accas import * + +codelist = ("artemis", "estel3d", "postel3d", "sisyphe", "stbtel", "telemac2d", "telemac3d", "tomawac") + +JdC = JDC_CATA(regles = (UN_PARMI('PYTEL',)), + ) +PYTEL = PROC( + nom = "PYTEL", op = None, + fr = u"Définition d'un cas pour le lanceur Pytel", + ang = u"Definition of a case for the Pytel launcher", + CODE = SIMP(statut = "o", typ = "TXM", into = codelist, defaut = "telemac2d", + fr = u"Code à exécuter", + ang = u"Code to run"), + FICHIER_CAS = SIMP(statut = "o", typ = 'Fichier', + fr = u"Fichier de description du cas", + ang = u"Case description file"), + REPERTOIRE_TRAVAIL = SIMP(statut = "f", typ = 'Repertoire', + fr = u"Répertoire de travail", + ang = u"Working directory"), + ENTREE_MED = FACT(statut = 'f', max = 1, + FICHIER_MED = SIMP(statut = "o", + typ = ('Fichier', 'Fichiers MED (*.med)',), + fr = u"Fichier de maillage d'entrée au format MED", + ang = u"Input mesh file in MED format"), + FICHIER_BCD = SIMP(statut = "o", + typ = ('Fichier', 'Fichiers BCD (*.bcd)',), + fr = u"Fichier de définition des conditions limites au format BCD", + ang = u"Boundary conditions definition file in BCD format"), + ), + SORTIE_MED = SIMP(statut = "f", + typ = ('Fichier', 'Fichiers MED (*.med)', "Sauvegarde"), + fr = u"Fichier de sortie au format MED", + ang = u"Output file in MED format"), +) diff --git a/src/salome_hydro/pytel/genjob.py b/src/salome_hydro/pytel/genjob.py new file mode 100644 index 0000000..edf5f31 --- /dev/null +++ b/src/salome_hydro/pytel/genjob.py @@ -0,0 +1,85 @@ +# 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 . + +import os +import tempfile +from datetime import datetime +import glob + +import salome + +convertion_script_template = """ +converter.py %(input_file)s -b %(log_file)s -o %(output_file)s +""" + +job_script_template = """#!/bin/sh + +. %(env_file)s +runcode.py %(code)s %(cas)s --ncsize %(nbcore)d +""" + +def generate_job(pytel_params, resource, telemac_root_dir, telemac_env_file, + nbcore, input_data_dir, result_dir): + """ + Create a Launcher job using the parameters specified by the user. + """ + # Generate job script + basename = os.path.basename(pytel_params["FICHIER_CAS"]) + job_script = job_script_template % {"env_file": telemac_env_file, + "code": pytel_params["CODE"], + "cas": basename, + "nbcore": nbcore} + + + (fd, job_script_file) = tempfile.mkstemp(prefix = "job_" + basename + "_", suffix = ".sh") + os.close(fd) + f = open(job_script_file, "w") + f.write(job_script) + f.close() + + # Define job parameters + job_params = salome.JobParameters() + job_params.job_name = basename + job_params.job_type = "command" + job_params.job_file = job_script_file + input_files = glob.glob(os.path.join(input_data_dir, "*")) + [pytel_params["FICHIER_CAS"]] + input_files = list(set(input_files)) # Remove duplicates + job_params.in_files = input_files + job_params.out_files = [] + job_params.result_directory = result_dir + + # Define resource parameters + job_params.resource_required = salome.ResourceParameters() + job_params.resource_required.name = resource + job_params.resource_required.nb_proc = nbcore + + # Generate name for the working directory + res_manager = salome.naming_service.Resolve("/ResourcesManager") + res_definition = res_manager.GetResourceDefinition(resource) + res_work_dir = res_definition.working_directory + if res_work_dir != "": + timestr = datetime.now().ctime() + timestr = timestr.replace('/', '_') + timestr = timestr.replace('-', '_') + timestr = timestr.replace(':', '_') + timestr = timestr.replace(' ', '_') + work_dir = res_work_dir + "/" + job_params.job_name + "_" + timestr + job_params.work_directory = work_dir + + # Create Launcher job + launcher = salome.naming_service.Resolve('/SalomeLauncher') + launcher.createJob(job_params) diff --git a/src/salome_hydro/pytel/genjobwindow.py b/src/salome_hydro/pytel/genjobwindow.py new file mode 100644 index 0000000..5ea6df3 --- /dev/null +++ b/src/salome_hydro/pytel/genjobwindow.py @@ -0,0 +1,71 @@ +# 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 . + +import os +from PyQt4 import QtGui, QtCore + +import salome +from salome.hydro.pytel.genjob import generate_job +from genjobwindow_ui import Ui_GenJobDialog + + +class GenJobDialog(QtGui.QDialog, Ui_GenJobDialog): + + def __init__(self, parent, pytel_params): + QtGui.QDialog.__init__(self, parent) + self.setupUi(self) + self.connect(self.dialogButtonBox, QtCore.SIGNAL("accepted()"), self.validate) + self.connect(self.dialogButtonBox, QtCore.SIGNAL("rejected()"), self.close) + self.connect(self.chooseInputDataDirectoryButton, QtCore.SIGNAL("clicked()"), self.choose_input_dir) + self.connect(self.chooseResultDirectoryButton, QtCore.SIGNAL("clicked()"), self.choose_result_dir) + self.telemacRootDirLE.setText("/home/projets-bgq/systel/V6P2") + self.telemacEnvFileLE.setText("/home/projets-bgq/systel/V6P2/config/pysource.zumbrota.xlf14.sh") + casedir = os.path.dirname(pytel_params["FICHIER_CAS"]) + self.inputDataDirectoryLE.setText(casedir) + self.resultDirectoryLE.setText(casedir) + + # Populate resource combo box + res_manager = salome.naming_service.Resolve("/ResourcesManager") + res_params = salome.ResourceParameters() + res_list = res_manager.GetFittingResources(res_params) + self.resourceCB.addItems(res_list) + + self.pytel_params = pytel_params + + def choose_input_dir(self): + directory = QtGui.QFileDialog.getExistingDirectory(self, + directory = self.inputDataDirectoryLE.text(), + options = QtGui.QFileDialog.ShowDirsOnly) + if not directory.isNull(): + self.inputDataDirectoryLE.setText(directory) + + def choose_result_dir(self): + directory = QtGui.QFileDialog.getExistingDirectory(self, + directory = self.resultDirectoryLE.text(), + options = QtGui.QFileDialog.ShowDirsOnly) + if not directory.isNull(): + self.resultDirectoryLE.setText(directory) + + def validate(self): + generate_job(self.pytel_params, + str(self.resourceCB.currentText()), + str(self.telemacRootDirLE.text()), + str(self.telemacEnvFileLE.text()), + self.nbCoreSB.value(), + str(self.inputDataDirectoryLE.text()), + str(self.resultDirectoryLE.text())) + self.close() diff --git a/src/salome_hydro/pytel/genjobwindow.ui b/src/salome_hydro/pytel/genjobwindow.ui new file mode 100644 index 0000000..31e8633 --- /dev/null +++ b/src/salome_hydro/pytel/genjobwindow.ui @@ -0,0 +1,165 @@ + + + GenJobDialog + + + + 0 + 0 + 636 + 280 + + + + Generate Job + + + + + + + + Resource + + + + + + + + + + Telemac remote root directory + + + + + + + + + + Telemac environment file + + + + + + + + + + Number of cores + + + + + + + 1 + + + 100000 + + + + + + + Input data directory + + + + + + + + + + 0 + 0 + + + + + + + + ... + + + + + + + + + Result directory + + + + + + + + + + 0 + 0 + + + + + + + + ... + + + + + + + + + + + Qt::Vertical + + + + 20 + 43 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + diff --git a/src/salome_hydro/pytel/gui.py b/src/salome_hydro/pytel/gui.py new file mode 100644 index 0000000..096405e --- /dev/null +++ b/src/salome_hydro/pytel/gui.py @@ -0,0 +1,52 @@ +# 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 . + +import SalomePyQt +sgPyQt = SalomePyQt.SalomePyQt() + +from salome.hydro.gui_utils import get_and_check_selected_file_path +from salome.hydro.study import jdc_to_dict + +from salome.hydro.pytel.eficas.appli import EficasForPytelAppli +from launcher import run_pytel +from genjobwindow import GenJobDialog + + +def create_case(): + EficasForPytelAppli() + +def edit_selected_case(): + EficasForPytelAppli(get_and_check_selected_file_path()) + +def get_params_from_selected_case(): + """ + Get the parameters dict from the selected case in Salome study + """ + jdcpath = get_and_check_selected_file_path() + with open(jdcpath) as jdcfile: + jdc = jdcfile.read() + param_dict = jdc_to_dict(jdc, ["PYTEL", "_F"]) + return param_dict + +def run_selected_case(): + param_dict = get_params_from_selected_case() + run_pytel(param_dict) + +def generate_job_for_selected_case(): + param_dict = get_params_from_selected_case() + dialog = GenJobDialog(sgPyQt.getDesktop(), param_dict) + dialog.exec_() diff --git a/src/salome_hydro/pytel/launcher.py b/src/salome_hydro/pytel/launcher.py new file mode 100644 index 0000000..f1d2e32 --- /dev/null +++ b/src/salome_hydro/pytel/launcher.py @@ -0,0 +1,87 @@ +# Copyright (C) 2012-2013 EDF +# +# This file is part of SALOME HYDRO module. +# +# SALOME HYDRO module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SALOME HYDRO module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SALOME HYDRO module. If not, see . + +import os +import subprocess +import tempfile + +from salome.kernel.logger import Logger +from salome.kernel import termcolor +logger = Logger("salome.hydro.pytel.launcher", color = termcolor.BLUE) +#logger.setLevel(logging.ERROR) + +def run_pytel(param_dict): + """ + Run the Python Telemac launching script (pytel), eventually preceded and + followed by data conversion scripts. + """ + interm_files = [] # Intermediate files that can eventually be deleted in the end + + # Get and eventually create working directory + if "REPERTOIRE_TRAVAIL" in param_dict: + wrkdir = param_dict["REPERTOIRE_TRAVAIL"] + if not os.path.exists(wrkdir): + os.makedirs(wrkdir) + else: + wrkdir = tempfile.mkdtemp(prefix = "tel-") + interm_files += [wrkdir] + + # Read original steering file + steering_filepath = param_dict["FICHIER_CAS"] + steering_file_dir = os.path.dirname(steering_filepath) + with open(steering_filepath) as f: + orig_steering = f.read() + orig_steering_lines = orig_steering.split("\n") + + cmd = "set -x ; " + + # Run the code itself + code = param_dict["CODE"] + cmd += "$TELEMAC_DIR/scripts/python27/runcode.py -w %s -r $TELEMAC_DIR %s %s" % \ + (wrkdir, code, steering_filepath) + cmd += " ; rc=$?" + + # Cleanup intermediate files if the computation was successful + cmd += " ; if test $rc -eq 0; then rm -rf %s ; fi" % " ".join(interm_files) + + cmd += ' ; echo "return code is $rc"' + + # Launch the command + logger.debug("Running the following command in xterm: %s" % cmd) + args = ["xterm", "-T", "Execution of Telemac", "-geo", "80x60", "-hold", "-l", "-e", cmd] + if param_dict.has_key('batchExec'): + if param_dict['batchExec'] == True: + args = ["xterm", "-T", "Execution of Telemac", "-geo", "80x60", "+hold", "-l", "-e", cmd] + subprocess.Popen(args, cwd = wrkdir) + +def check_file_or_create_link(filepath, dirpath, interm_file_list = None): + """ + This utility function checks if the file *filepath* is in directory *dirpath*. + If not, it creates a link with a unique name in *dirpath* to the file *filepath* + and it prepends the link path to the list *interm_file_list* if it is not None. + It returns the name of the link if a link was created, or the name of the file + *filepath* otherwise. + """ + filename = os.path.basename(filepath) + if not os.path.samefile(dirpath, os.path.dirname(filepath)): + name_wo_ext, ext = os.path.splitext(filename) + linkpath = tempfile.mktemp(dir = dirpath, prefix = name_wo_ext + "_", suffix = ext) + os.symlink(filepath, linkpath) + filename = os.path.basename(linkpath) + if interm_file_list is not None: + interm_file_list[:0] = [linkpath] + return filename diff --git a/src/salome_hydro/study.py b/src/salome_hydro/study.py new file mode 100644 index 0000000..e081e62 --- /dev/null +++ b/src/salome_hydro/study.py @@ -0,0 +1,207 @@ +# 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 . + +import os +import types + +from salome.kernel.studyedit import getStudyEditor +from salome.kernel.parametric import study_exchange_vars + +import HYDROSOLVER_ORB + +# module constants +MODULE_NAME = "HYDROSOLVER" + +COMPONENT_NAME = "HydroSolver" +COMPONENT_ICON = "HYDRO_small.png" + +MASCARET_FILE_TYPE = "MASCARET_EFICAS_FILE" +MASCARET_ICON = "case1d.png" +MASCARET_CASE_TYPE_ID = 1 + +VARS_ICON = "icon_variables.png" + +LOG_ICON = "log.png" +LOG_TYPE_ID = 2 + +TELEMAC2D_FILE_TYPE = "TELEMAC2D_EFICAS_FILE" +TELEMAC2D_ICON = "case2d.png" +TELEMAC2D_CASE_TYPE_ID = 3 + +COUPLING1D2D_FILE_TYPE = "COUPLING1D2D_EFICAS_FILE" +COUPLING1D2D_ICON = "case_couplage.png" +COUPLING1D2D_CASE_TYPE_ID = 4 + +PYTEL_FILE_TYPE = "PYTEL_EFICAS_FILE" +PYTEL_ICON = "case_pytel.png" +PYTEL_CASE_TYPE_ID = 5 + +# Dictionary used to map Eficas parameters to Mascaret file types +mascaretFileTypeDict = {"FICHIER_ABAQUES" : "abaques", + "FICHIER_DICO" : "dico", + "FICHIER_CASIER" : "casier", + "FICHIER_GEOMETRIE" : "geo", + "FICHIER_LOI" : "loi", + "FICHIER_MOT_CLE" : "cas", + "LISTING" : "listing", + "FICHIER_DAMOCLE" : "damocle", + "RESULTAT" : "res", + "LISTING_CASIER" : "listing_casier", + "LISTING_LIAISON" : "listing_liaison", + "RESULTAT_CASIER" : "res_casier", + "RESULTAT_LIAISON" : "res_liaison" + } + +def jdc_to_dict(jdc, command_list): + """ + This tricky function transforms a JdC with a single command into a + dictionary that can be used more easily from a Python context (thanks to + M. Courtois and G. Boulant). + """ + context = {} + for command in command_list: + context[command] = _args_to_dict + exec "parameters = " + jdc.strip() in context + return context['parameters'] + +def _args_to_dict(**kwargs): + return kwargs + +def get_jdc_dict_var_as_tuple(jdc_dict, varname): + if not jdc_dict.has_key(varname): + return tuple() + elif not isinstance(jdc_dict[varname], types.TupleType): + return (jdc_dict[varname],) + else: + return jdc_dict[varname] + +class HydroStudyEditor: + """ + This class provides utility methods to edit the component "Hydro" in + the study. The parameter `studyId` defines the ID of the study to edit. If + it is :const:`None`, the edited study will be the current study. + """ + def __init__(self, studyId = None): + self.editor = getStudyEditor(studyId) + self.hydroComp = None + + def find_or_create_hydro_component(self): + """ + Find the component "Hydro" or create it if none is found + :return: the SComponent found or created. + """ + if self.hydroComp is None: + self.hydroComp = self.editor.findOrCreateComponent(MODULE_NAME, + COMPONENT_NAME, + COMPONENT_ICON) + return self.hydroComp + + def find_or_create_mascaret_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 = MASCARET_FILE_TYPE, + fileName = filePath, + 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() + itemName = os.path.splitext(os.path.basename(filePath))[0] + sobj = self.editor.findOrCreateItem(self.hydroComp, + name = itemName, + fileType = TELEMAC2D_FILE_TYPE, + fileName = filePath, + icon = TELEMAC2D_ICON, + comment = str(filePath), + typeId = TELEMAC2D_CASE_TYPE_ID) + # Create "Variables" item + with open(filePath) as jdcfile: + jdc = jdcfile.read() + params = jdc_to_dict(jdc, ["TELEMAC2D", "_F"]) + input_vars = get_jdc_dict_var_as_tuple(params, "VARIABLE_ENTREE") + output_vars = get_jdc_dict_var_as_tuple(params, "VARIABLE_SORTIE") + 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 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] + sobj = self.editor.findOrCreateItem(self.hydroComp, + name = itemName, + fileType = PYTEL_FILE_TYPE, + fileName = filePath, + icon = PYTEL_ICON, + comment = str(filePath), + typeId = PYTEL_CASE_TYPE_ID) diff --git a/src/salome_hydro/telemac2d/CMakeLists.txt b/src/salome_hydro/telemac2d/CMakeLists.txt new file mode 100644 index 0000000..f471ac1 --- /dev/null +++ b/src/salome_hydro/telemac2d/CMakeLists.txt @@ -0,0 +1,80 @@ +# 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 . + +ADD_SUBDIRECTORY(eficas) + +# --- Python files --- + +SET(PYFILES + __init__.py + polygon.py +) + +SET(INSTALL_DIR ${SALOME_INSTALL_PYTHON}/salome/hydro/telemac2d) + +# --- rules --- + +SALOME_INSTALL_SCRIPTS("${PYFILES}" ${INSTALL_DIR}) + +# This macro is used to transform the list of libraries against which the +# module is linked into a list of linker flags (-L and -l). If we just use the +# list of libraries in the linker command, the full path of the libraries is +# registered in the module dependencies, so it doesn't work when the installation +# is moved. +MACRO(LIB_LIST_TO_LINKER_FLAGS LINKER_FLAGS_VAR LIB_LIST) + SET(${LINKER_FLAGS_VAR}) + FOREACH(LIB ${LIB_LIST}) + GET_FILENAME_COMPONENT(DIRNAME ${LIB} PATH) + # Get the library filename without the shortest extension. We can't use + # command GET_FILENAME_COMPONENT with option NAME_WE because it returns + # the filename without the longest extension. For example, we need to get + # "libpython2.7" from "libpython2.7.so" and not "libpython2". + GET_FILENAME_COMPONENT(LIBFILENAME ${LIB} NAME) + STRING(FIND ${LIBFILENAME} "." DOTPOS REVERSE) + STRING(SUBSTRING ${LIBFILENAME} 0 ${DOTPOS} FILENAME_WO_EXT) + STRING(SUBSTRING ${FILENAME_WO_EXT} 3 -1 LIBNAME) + LIST(APPEND ${LINKER_FLAGS_VAR} "-L${DIRNAME}" "-l${LIBNAME}") + ENDFOREACH(LIB ${LIB_LIST}) +ENDMACRO(LIB_LIST_TO_LINKER_FLAGS) + +LIB_LIST_TO_LINKER_FLAGS(LINKER_FLAGS "${TELEMAC_LIBRARIES};${HDF5_hdf5_LIBRARY};${MEDFILE_LIBRARIES};${PYTHON_LIBRARY}") + +# Python wrapping for Telemac2D created with f2py +SET(T2D_WRAP_API_LIB _apit2d.so) +SET(T2D_WRAP_API_PYF_FILE apit2d.pyf) +SET(T2D_WRAP_API_SRC_FILES ${TELEMAC_API_SRC_DIR}/api_handle_var_t2d.f90 + ${TELEMAC_API_SRC_DIR}/api_interface_t2d.f90 + ${TELEMAC_API_SRC_DIR}/api_handle_error_t2d.f90) + +# This sed string is used to add necessary definitions to the pyf file +SET(SEDSTRING "s:python module _apit2d ! in:python module _apit2d ! in\\nusercode '''const int nb_var_t2d=100\\;\\n''':") + +ADD_CUSTOM_COMMAND(OUTPUT ${T2D_WRAP_API_LIB} + COMMAND f2py -c ${T2D_WRAP_API_PYF_FILE} -I${TELEMAC_INCLUDE_DIR} ${LINKER_FLAGS} + MAIN_DEPENDENCY ${T2D_WRAP_API_PYF_FILE} + ) + +ADD_CUSTOM_COMMAND(OUTPUT ${T2D_WRAP_API_PYF_FILE} + COMMAND f2py -h ${T2D_WRAP_API_PYF_FILE} -m _apit2d ${T2D_WRAP_API_SRC_FILES} + skip: get_boolean_t2d_d get_double_t2d_d get_integer_t2d_d get_string_t2d_d get_var_size_t2d_d + set_boolean_t2d_d set_double_t2d_d set_integer_t2d_d set_string_t2d_d : + COMMAND sed -i -e \"${SEDSTRING}\" ${T2D_WRAP_API_PYF_FILE} + MAIN_DEPENDENCY ${T2D_WRAP_API_SRC_FILES} + ) + +ADD_CUSTOM_TARGET(BUILD_T2D_WRAP_API_LIB ALL DEPENDS ${T2D_WRAP_API_LIB}) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${T2D_WRAP_API_LIB} DESTINATION ${INSTALL_DIR}) diff --git a/src/salome_hydro/telemac2d/__init__.py b/src/salome_hydro/telemac2d/__init__.py new file mode 100644 index 0000000..2ca0946 --- /dev/null +++ b/src/salome_hydro/telemac2d/__init__.py @@ -0,0 +1,172 @@ +# 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 . + +import sys +import os +import tempfile +from ctypes import cdll + + +class Telemac2D(object): + + _instanciated = False + _api_module = None + + def __new__(cls, *args, **kwargs): + if cls._instanciated: + raise Exception("Telemac2D instance already exists") + instance = super(Telemac2D, cls).__new__(cls, *args, **kwargs) + cls._instanciated = True + return instance + + def __init__(self, user_fortran = None): + self.user_fortran_lib = None + self.user_fortran_lib_path = None + # User Fortran MUST be loaded before apit2d importation + if user_fortran is not None: + self._load_user_fortran(user_fortran) + if Telemac2D._api_module is None: + import salome.hydro.telemac2d._apit2d + Telemac2D._api_module = sys.modules["salome.hydro.telemac2d._apit2d"] + else: + reload(Telemac2D._api_module) + self.api = Telemac2D._api_module.api_interface_t2d + self.errapi = Telemac2D._api_module.api_handle_error_t2d + self.id, ierr = self.api.run_set_config_t2d(6, 2) + self.handle_error("run_set_config_t2d", ierr) + + def __del__(self): + # No way to cleanly unload user fortran lib, so I don't know if it's possible + # to reload and use another one in the same process (to be tested) + if self.user_fortran_lib_path is not None: + os.remove(self.user_fortran_lib_path) + Telemac2D._instanciated = False + + def _load_user_fortran(self, fortran_filename): + basename = os.path.basename(fortran_filename) + root = os.path.splitext(basename)[0] + (fd, self.user_fortran_lib_path) = tempfile.mkstemp(prefix = root + "_", suffix = ".so") + os.close(fd) + python_version = "%d.%d" % (sys.version_info[0], sys.version_info[1]) + t2d_ld_flags = "-L${TELEMAC_DIR}/wrap_api/lib -lapi_telemac2d -ltelemac2d -lsisyphe -ltomawac " + #t2d_ld_flags += "-lbief -lparallel -lpartel -lgretel -lhermes -ldamocles -lspecial " + t2d_ld_flags += "-lbief -lparallel -lhermes -ldamocles -lspecial " + t2d_ld_flags += "-L${MED3HOME}/lib -L${HDF5HOME}/lib -lhdf5 -lmed" + command = "gfortran %s -shared -o %s -L${PYTHONHOME}/lib -lpython%s %s -I${TELEMAC_DIR}/wrap_api/include -fPIC" % \ + (fortran_filename, self.user_fortran_lib_path, python_version, t2d_ld_flags) + ret = os.system(command) + if ret != 0: + raise Exception("Cannot compile user fortran file %s" % fortran_filename) + self.user_fortran_lib = cdll.LoadLibrary(self.user_fortran_lib_path) + + def handle_error(self, funcname, ierr): + if ierr != 0: + raise Exception('Error in function %s:\n Error code: %d\n Error message: %s' % + (funcname, ierr, self.errapi.err_mess.tostring().strip())) + + def run_read_case_t2d(self, steering_filename, dico_filename = None): + if dico_filename is None: + dico_filename = os.path.join(os.getenv("TELEMAC_DIR"), "sources", "telemac2d", "telemac2d.dico") + if not os.path.isfile(steering_filename): + raise Exception("Steering file {0} does not exist".format(steering_filename)) + if not os.path.isfile(dico_filename): + raise Exception("Dictionary file {0} does not exist".format(dico_filename)) + ierr = self.api.run_read_case_t2d(self.id, steering_filename, dico_filename) + self.handle_error("run_read_case_t2d", ierr) + + def get_double(self, varname, *args): + args = list(args) + [0] * (3 - len(args)) # Fill last parameters with 0 + value, ierr = self.api.get_double_t2d(self.id, varname, *args) + self.handle_error("get_double_t2d", ierr) + return value + + def set_double(self, varname, value, *args): + args = list(args) + [0] * (3 - len(args)) # Fill last parameters with 0 + ierr = self.api.set_double_t2d(self.id, varname, value, *args) + self.handle_error("set_double_t2d", ierr) + + def get_integer(self, varname, *args): + args = list(args) + [0] * (3 - len(args)) # Fill last parameters with 0 + value, ierr = self.api.get_integer_t2d(self.id, varname, *args) + self.handle_error("get_integer_t2d", ierr) + return value + + def set_integer(self, varname, value, *args): + args = list(args) + [0] * (3 - len(args)) # Fill last parameters with 0 + ierr = self.api.set_integer_t2d(self.id, varname, value, *args) + self.handle_error("set_integer_t2d", ierr) + + def get_string(self, varname): + value, ierr = self.api.get_string_t2d(self.id, varname, 144) + self.handle_error("get_string_t2d", ierr) + return value.tostring().strip() + + def set_string(self, varname, value): + padded_value = value + " " * (144 - len(value)) # Pad with spaces + ierr = self.api.set_string_t2d(self.id, varname, padded_value, 144) + self.handle_error("set_string_t2d", ierr) + + def run_all_timesteps(self): + ntimesteps = self.get_integer("MODEL.NTIMESTEPS") + for i in xrange(ntimesteps): + ierr = self.api.run_timestep_t2d(self.id) + self.handle_error("run_timestep_t2d", ierr) + + def finalize(self): + ierr = self.api.run_finalize_t2d(self.id) + self.handle_error("run_finalize_t2d", ierr) + + def save_state(self, state = None): + nbpoints = self.get_integer('MODEL.NPOIN') + if state is None: + state = Telemac2DState(nbpoints) + elif state.nbpoints != nbpoints: + raise Exception("Allocated state size (%d) is different from the size " + "of Telemac2D state (%d)" % (state.nbpoints, nbpoints)) + for i in xrange(nbpoints): + #state.h[i] = self.get_double('MODEL.WATERDEPTH', i+1) + #state.u[i] = self.get_double('MODEL.VELOCITYU' , i+1) + #state.v[i] = self.get_double('MODEL.VELOCITYV' , i+1) + # The following lines are an optimization of the previous ones, + # to be replaced by a proper array copy + state.h[i] = self.api.get_double_t2d(self.id, 'MODEL.WATERDEPTH', i+1, 0, 0)[0] + state.u[i] = self.api.get_double_t2d(self.id, 'MODEL.VELOCITYU' , i+1, 0, 0)[0] + state.v[i] = self.api.get_double_t2d(self.id, 'MODEL.VELOCITYV' , i+1, 0, 0)[0] + return state + + def restore_state(self, state): + nbpoints = self.get_integer('MODEL.NPOIN') + if state.nbpoints != nbpoints: + raise Exception("Allocated state size (%d) is different from the size " + "of Telemac2D state (%d)" % (state.nbpoints, nbpoints)) + for i in xrange(nbpoints): + #self.set_double('MODEL.WATERDEPTH', state.h[i], i+1) + #self.set_double('MODEL.VELOCITYU' , state.u[i], i+1) + #self.set_double('MODEL.VELOCITYV' , state.v[i], i+1) + # The following lines are an optimization of the previous ones, + # to be replaced by a proper array copy + self.api.set_double_t2d(self.id, 'MODEL.WATERDEPTH', state.h[i], i+1, 0, 0) + self.api.set_double_t2d(self.id, 'MODEL.VELOCITYU' , state.u[i], i+1, 0, 0) + self.api.set_double_t2d(self.id, 'MODEL.VELOCITYV' , state.v[i], i+1, 0, 0) + + +class Telemac2DState: + def __init__(self, nbpoints): + self.nbpoints = nbpoints + self.h = [0.0] * nbpoints + self.u = [0.0] * nbpoints + self.v = [0.0] * nbpoints diff --git a/src/salome_hydro/telemac2d/eficas/CMakeLists.txt b/src/salome_hydro/telemac2d/eficas/CMakeLists.txt new file mode 100644 index 0000000..f22ca41 --- /dev/null +++ b/src/salome_hydro/telemac2d/eficas/CMakeLists.txt @@ -0,0 +1,31 @@ +# 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 . + +# --- Python files --- + +SET(PYFILES + __init__.py + configuration_telemac2d.py + prefs_telemac2d.py + prefs.py + telemac2d_V6_cata.py + appli.py +) + +# --- rules --- + +SALOME_INSTALL_SCRIPTS("${PYFILES}" ${SALOME_INSTALL_PYTHON}/salome/hydro/telemac2d/eficas) diff --git a/src/salome_hydro/telemac2d/eficas/__init__.py b/src/salome_hydro/telemac2d/eficas/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/salome_hydro/telemac2d/eficas/appli.py b/src/salome_hydro/telemac2d/eficas/appli.py new file mode 100644 index 0000000..0684bf7 --- /dev/null +++ b/src/salome_hydro/telemac2d/eficas/appli.py @@ -0,0 +1,75 @@ +# -*- 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 . + +import os +import sys +import re + +from PyQt4.QtGui import QMessageBox + +import salome +import SalomePyQt +sgPyQt = SalomePyQt.SalomePyQt() + +from salome.kernel.logger import Logger +from salome.kernel import termcolor +logger = Logger("salome.hydro.telemac2d.eficas.appli", + color = termcolor.GREEN_FG) + +import eficasSalome + +from salome.hydro.study import HydroStudyEditor + +class EficasForTelemac2DAppli(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] + eficasSalome.MyEficas.__init__(self, sgPyQt.getDesktop(), + "telemac2d", + fichier, version = version) + sgPyQt.createView("Eficas Telemac2D", self) + + def addJdcInSalome(self, jdcPath): + """ + Add the newly created file in Salome study + """ + try: + self.ed.find_or_create_telemac2d_case(jdcPath) + except Exception, exc: + msgError = "Can't add file to Salome study tree" + logger.exception(msgError) + QMessageBox.warning(self, self.tr("Warning"), + self.tr("%s. Reason:\n%s\n\nSee logs for " + "more details." % (msgError, exc))) + salome.sg.updateObjBrowser(0) + + def closeEvent(self, event): + while self.codedir in sys.path: + sys.path.remove(self.codedir) + eficasSalome.MyEficas.closeEvent(self, event) diff --git a/src/salome_hydro/telemac2d/eficas/configuration_telemac2d.py b/src/salome_hydro/telemac2d/eficas/configuration_telemac2d.py new file mode 100644 index 0000000..7623f91 --- /dev/null +++ b/src/salome_hydro/telemac2d/eficas/configuration_telemac2d.py @@ -0,0 +1,46 @@ +# -*- 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 . + +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("telemac2d_V6", + os.path.join(repIni, "telemac2d_V6_cata.py")),) + self.lang = 'fr' + + def save_params(self): + pass + +def make_config(appli, rep): + return CONFIG(appli, rep) + +def make_config_style(appli, rep): + return None diff --git a/src/salome_hydro/telemac2d/eficas/prefs.py b/src/salome_hydro/telemac2d/eficas/prefs.py new file mode 100644 index 0000000..a156e61 --- /dev/null +++ b/src/salome_hydro/telemac2d/eficas/prefs.py @@ -0,0 +1,18 @@ +# Copyright (C) 2012-2013 EDF +# +# This file is part of SALOME HYDRO module. +# +# SALOME HYDRO module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SALOME HYDRO module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SALOME HYDRO module. If not, see . + +code = "telemac2d" diff --git a/src/salome_hydro/telemac2d/eficas/prefs_telemac2d.py b/src/salome_hydro/telemac2d/eficas/prefs_telemac2d.py new file mode 100644 index 0000000..82d946e --- /dev/null +++ b/src/salome_hydro/telemac2d/eficas/prefs_telemac2d.py @@ -0,0 +1,22 @@ +# 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 . + +import os +import sys + +repIni = os.path.dirname(__file__) +INSTALLDIR = os.getenv("EFICAS_ROOT") diff --git a/src/salome_hydro/telemac2d/eficas/telemac2d_V6_cata.py b/src/salome_hydro/telemac2d/eficas/telemac2d_V6_cata.py new file mode 100644 index 0000000..6d37255 --- /dev/null +++ b/src/salome_hydro/telemac2d/eficas/telemac2d_V6_cata.py @@ -0,0 +1,107 @@ +# -*- 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 . + +import types +from Accas import * + +class Tuple: + def __init__(self,ntuple): + self.ntuple=ntuple + + def __convert__(self,valeur): + if type(valeur) == types.StringType: + return None + if len(valeur) != self.ntuple: + return None + return valeur + + def info(self): + return "Tuple de %s elements" % self.ntuple + + __repr__=info + __str__=info + +JdC = JDC_CATA(regles = (UN_PARMI('TELEMAC2D',)), + ) + +TELEMAC2D = PROC( + nom = "TELEMAC2D", op = None, + fr = u"Définition d'un cas d'étude Telemac2D", + ang = u"Definition of a Telemac2D study case", + FICHIER_CAS = SIMP(statut = "o", typ = 'Fichier', + fr = u"Fichier de description du cas", + ang = u"Case description file"), + FICHIER_GEOMETRIE = SIMP(statut = "f", typ = 'Fichier', + fr = u"Fichier de géométrie", + ang = u"Geometry file"), + FICHIER_CONDITIONS_LIMITES = SIMP(statut = "f", typ = 'Fichier', + fr = u"Fichier de conditions limites", + ang = u"Boundary conditions file"), + FICHIER_DICO = SIMP(statut = "f", typ = 'Fichier', + fr = "Fichier Dico", + ang = u"Dictionary file"), + FICHIER_FORTRAN_UTILISATEUR = SIMP(statut = "f", typ = 'Fichier', + fr = "Fichier Fortran utilisateur", + ang = u"Fortran user file"), + RESULTAT = SIMP(statut = "f", typ = ('Fichier', 'Tous les fichiers (*)', "Sauvegarde"), + fr = u"Fichier de résultat", + ang = u"Result file"), + VARIABLE_SORTIE = FACT(statut = 'f', max = '**', + fr = u"Variable de sortie du calcul", + ang = u"Computation output variable", + NOM = SIMP(statut = "o", typ = 'TXM', + fr = u"Nom de la variable", + ang = u"Variable name"), + VARIABLE_T2D = SIMP(statut = "o", typ = 'TXM', + fr = u'Variable Telemac2D (ex : "MODEL.VELOCITYU(2443)")', + ang = u'Telemac2D variable (ex : "MODEL.VELOCITYU(2443)")'), + ), + VARIABLE_ENTREE = FACT(statut = 'f', max = '**', + fr = u"Variable d'entrée du calcul", + ang = u"Computation input variable", + NOM = SIMP(statut = "o", typ = 'TXM', + fr = u"Nom de la variable", + ang = u"Variable name"), + VARIABLE_MODELE_T2D = FACT(statut = "o", + fr = u'Variable du modèle Telemac2D', + ang = u'Telemac2D model variable', + NOM_VARIABLE_MODELE = SIMP(statut = "o", typ = 'TXM', + fr = u'Nom de la variable du modèle (ex: "MODEL.DEBIT")', + ang = u'Model variable name (ex: "MODEL.DEBIT")'), + ZONE_DE_DEFINITION = FACT(statut = "o", + ang = u'Variable definition area', + fr = u'Zone de définition de la variable', + regles = (UN_PARMI('INDICE', 'POLYGONE')), + INDICE = SIMP(statut = "f", typ = "I", + ang = "Index of the point / border", + fr = u"Indice du point ou de la frontière", + ), + POLYGONE = SIMP(statut = "f", + typ = Tuple(2), + max = '**', + fr = u"Liste des sommets (coordonnées X,Y) du " + u"polygone définissant le contour de la zone", + ang = "List of points (X,Y coordinates) of the " + "polygon defining the border of the area", + validators = VerifTypeTuple(('R', 'R')), + ), + ), + ), + ), +) diff --git a/src/salome_hydro/telemac2d/polygon.py b/src/salome_hydro/telemac2d/polygon.py new file mode 100644 index 0000000..cd2d431 --- /dev/null +++ b/src/salome_hydro/telemac2d/polygon.py @@ -0,0 +1,96 @@ +# Copyright (C) 2012-2015 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 . + +import math +from itertools import izip,cycle + +EPS = 10**-9 + +def is_in_polygon(x,y,poly): + """ + Returns True if the point (x,y) is in the polygon poly + Warning the polygon must be distinct (no indentical points) + """ + angle = -1.0 + while True: + angle += 1.0 + if(angle > 360.0): + # Special case of a point on the contour + return True + a = math.cos(angle*math.pi/180.0) + b = math.sin(angle*math.pi/180.0) + nsect = 0 + # Loop on all the segment of the polygon + # TODO: Pythonize that loop + n = len(poly) + next_angle = False + for i in range(0,n): + xdep,ydep = poly[i] + # next element + xarr,yarr = poly[(i+1) % n] + # Case the point is on the polygon + if (abs(x-xdep)= -EPS and llambda >= -EPS and llambda <= (1.0+EPS)): + nsect += 1 + # If + if not next_angle: + break + + return (nsect % 2) == 1 + +def get_list_points_in_polygon(t2d_inst, poly): + """ + Returns the list of points from the mesh that are in the polygon poly + + t2d_inst : is the Telemac2D instance + poly : is a list of (x,y) coordiantes defining the polygon + """ + # Get the number of point in the mesh + npoin = t2d_inst.get_integer('MODEL.NPOIN') + point_in_polygon = [] + + # Loop on all mesh points + for i in range(1, npoin + 1): + # Get the cooridnates of point i + x = t2d_inst.get_double('MODEL.X', i) + y = t2d_inst.get_double('MODEL.Y', i) + # If point is in polygon add it to the list of points + if is_in_polygon(x,y,poly): + point_in_polygon.append(i) + return point_in_polygon + +if __name__ == "__main__": + l = [(0.0,0.0),(0.0,1.0),(1.0,2.0),(2.0,2.0),(2.0,0.0)] + print is_in_polygon(1.0,1.0,l),True + print is_in_polygon(0.0,0.0,l),True + print is_in_polygon(-1.0,1.0,l),False + print is_in_polygon(2.0,0.0,l),True