1 # Copyright (C) 2009-2015 EDF R&D
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License.
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # Lesser General Public License for more details.
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
29 from salome.gui.helper import sgPyQt
30 from salome.kernel import termcolor
31 from salome.kernel.logger import Logger
32 from salome.kernel.parametric.compo_utils import \
33 create_input_dict, create_normal_parametric_output, create_error_parametric_output
34 import GENERICSOLVER_ORB__POA
36 import SALOME_ComponentPy
37 import SALOME_DriverPy
42 logger = Logger("DEVIATION", color=termcolor.RED_FG)
43 logger.setLevel(logging.INFO)
49 # Retrieve data from selected case
51 def GetDataFromCase( studyId, caseEntry ):
53 study = salome.myStudyManager.GetStudyByID( studyId )
54 case = study.FindObjectID( caseEntry )
55 builder = study.NewBuilder()
56 # Get the values of the variables and make them a list
57 for name in ("E", "F", "L", "I"):
58 var = getSubSObjectByName( studyId, case, name )
60 raise Exception('No variable "%s" was found in case "%s" (entry %s). '
61 'It is probably not a case for the code DEVIATION.' %
62 (name, case.GetName(), caseEntry))
63 theCase[ name ] = getValueOfVariable( builder, var )
70 def getValueOfVariable( builder, varobj ):
71 attr = builder.FindOrCreateAttribute( varobj, "AttributeLocalID" )
73 if (objid == VARIABLE_ID):
74 attr = builder.FindOrCreateAttribute( varobj, "AttributeReal" )
77 attr = builder.FindOrCreateAttribute( varobj, "AttributeName" )
78 QMessageBox.information( sgPyQt.getDesktop(), 'Info', "Object '%s' isn't a variable. Can't set value." % attr.Value() )
81 def getSubSObjectByName( studyId, sobjFather, childName ):
82 logger.debug("GENERICSOLVER.getSubSObjectByName Looking for sobjet named " + childName)
83 study = salome.myStudyManager.GetStudyByID( studyId )
84 iterator = study.NewChildIterator(sobjFather)
85 #builder = study.NewBuilder()
86 while iterator.More():
87 sobj = iterator.Value()
88 logger.debug("GENERICSOLVER.getSubSObjectByName Got sobjet named " + sobj.GetName())
89 if sobj.GetName() == childName:
95 ################################################
97 class DEVIATION(GENERICSOLVER_ORB__POA.DEVIATION_Gen,
98 SALOME_ComponentPy.SALOME_ComponentPy_i,
99 SALOME_DriverPy.SALOME_DriverPy_i):
101 lock = threading.Lock()
104 Pour etre un composant SALOME cette classe Python
105 doit avoir le nom du composant et heriter de la
106 classe DEVIATION_Gen issue de la compilation de l'idl
107 par omniidl et de la classe SALOME_ComponentPy_i
108 qui porte les services generaux d'un composant SALOME
110 def __init__ ( self, orb, poa, contID, containerName, instanceName,
112 logger.info("__init__: " + containerName + ' ; ' + instanceName)
113 SALOME_ComponentPy.SALOME_ComponentPy_i.__init__(self, orb, poa,
114 contID, containerName, instanceName, interfaceName, False)
115 SALOME_DriverPy.SALOME_DriverPy_i.__init__(self, interfaceName)
116 # On stocke dans l'attribut _naming_service, une reference sur
117 # le Naming Service CORBA
118 self._naming_service = SALOME_ComponentPy.SALOME_NamingServicePy_i( self._orb )
119 self.deterministicValues = {}
121 ######################################################################
122 # This is the Wrapper part of the GENERICSOLVER module, ie
123 # the three following methods are used by generic controlling
124 # modules like OpenTURNS in order to launch a computation.
125 # The interface is declared in GENERICSOLVER_Gen.idl. The methods
126 # are free to call the legacy interface (see below).
127 ######################################################################
129 def _raiseSalomeError(self):
130 message = "Error in component %s running in container %s." % (self._instanceName, self._containerName)
131 logger.exception(message)
132 message += " " + traceback.format_exc()
133 exc = SALOME.ExceptionStruct(SALOME.INTERNAL_ERROR, message,
134 inspect.stack()[1][1], inspect.stack()[1][2])
135 raise SALOME.SALOME_Exception(exc)
137 def _getIdMessage(self):
138 return "%s in container %s running on %s, process %d, thread %d" % \
139 (self._instanceName, self._containerName,
140 platform.node(), os.getpid(), _thread.get_ident())
142 def Init(self, studyId, detCaseEntry):
144 This method is an example for the initialization of a computation component for
145 use with OpenTURNS in SALOME 5.1.5 and later (for YACS integration)
148 logger.info("Init: " + self._getIdMessage())
149 DEVIATION.lock.acquire()
151 DEVIATION.lock.release()
153 self.deterministicValues = GetDataFromCase(studyId, detCaseEntry)
154 logger.debug("deterministic values: %s" % self.deterministicValues)
156 self._raiseSalomeError()
158 def Exec(self, paramInput):
160 This method is an example for the execution of a computation component for
161 use with OpenTURNS in SALOME 5.1.5 and later (for YACS integration)
164 logger.info("Exec: " + self._getIdMessage())
165 logger.debug("inputVarList: %s" % paramInput.inputVarList)
166 logger.debug("outputVarList: %s" % paramInput.outputVarList)
167 logger.debug("inputValues: %s" % paramInput.inputValues)
169 # Get id and execution mode
172 for parameter in paramInput.specificParameters:
173 if parameter.name == "id":
175 if parameter.name == "executionMode":
176 exec_mode = parameter.value
177 logger.debug("ID: %s" % id)
178 logger.debug("Execution mode: %s" % exec_mode)
180 inputDict = create_input_dict(self.deterministicValues, paramInput)
181 logger.debug("inputDict = %s" % inputDict)
183 # Test for an invalid parameter and return an error in this case
184 if inputDict["L"] <= 0:
185 return create_error_parametric_output("Invalid value: L must be positive")
188 outputDict["dev"] = self.BeamModel(**inputDict)
190 paramOutput = create_normal_parametric_output(outputDict, paramInput)
191 logger.debug("outputValues: %s" % paramOutput.outputValues)
194 self._raiseSalomeError()
198 This method is an implementation for the DEVIATION interface.
199 It cleans everything set so far.
202 logger.info("Finalize: " + self._getIdMessage())
204 self._raiseSalomeError()
206 def GetFilesToTransfer(self, studyId, detCaseEntry):
208 This method can be used to specify files to transfer to the
209 computation resource. It is not useful for DEVIATION since it only
210 uses values from Salome study.
213 logger.info("GetFilesToTransfer: " + self._getIdMessage())
216 return (inputFiles, outputFiles)
218 self._raiseSalomeError()
220 ######################################################################
221 # This is the computation part of the GENERICSOLVER module, ie
222 # the following method realizes what the solver is intended to do.
223 # The interface of this method (and maybe other ones) is absolutely
224 # free and depends on the module (legacy interface).
225 ######################################################################
227 def BeamModel(self, E, F, L, I):
229 This method implements a beam bending model based on the following formula:
230 deviation = ( Force * Length^3 ) / ( 3 * YoungModulus * InertiaSection )
232 d = (F * L * L * L) / (3. * E * I)
233 logger.debug("BeamModel (E=%g, F=%g, L=%g, I=%g) = %g" % (E, F, L, I, d))