Salome HOME
83381beb18617dc10f45a51e53cb941c3db00f62
[samples/genericsolver.git] / src / GENERICSOLVER / DEVIATION.py
1 #  Copyright (C) 2009-2010 EDF R&D
2 #
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.
7 #
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.
12 #
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
16 #
17 #  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 #
19 #  $Id$
20 #
21
22 import logging
23 import threading
24 import inspect
25 import traceback
26
27 import salome
28 import GENERICSOLVER_ORB__POA
29 import SALOME_ComponentPy
30 import SALOME_DriverPy
31 import SALOME
32
33 from pal.logger import Logger
34 from pal import termcolor
35 logger = Logger("DEVIATION", color = termcolor.RED_FG)
36 logger.setLevel(logging.INFO)
37
38 VARIABLE_ID = 1030
39
40 ###
41 # Retrieve data from selected case
42 ###
43 def GetDataFromCase( studyId, caseEntry ):
44     theCase = {}
45     study = salome.myStudyManager.GetStudyByID( studyId )
46     case = study.FindObjectID( caseEntry )
47     builder = study.NewBuilder()
48     # Get the values of the variables and make them a list
49     for name in ("E", "F", "L", "I"):
50         var = getSubSObjectByName( studyId, case, name )
51         if var == None:
52             logger.error("GENERICSOLVER.GetDataFromCase : ERROR! no variable '%s'" % name)
53             break
54         theCase[ name ] = getValueOfVariable( builder, var )
55     return theCase
56
57 ###
58 # Plays with study
59 ###
60
61 def getValueOfVariable( builder, varobj ):
62     attr = builder.FindOrCreateAttribute( varobj, "AttributeLocalID" )
63     objid = attr.Value()
64     if (objid == VARIABLE_ID):
65         attr = builder.FindOrCreateAttribute( varobj, "AttributeReal" )
66         return attr.Value()
67     else:
68         attr = builder.FindOrCreateAttribute( varobj, "AttributeName" )
69         QMessageBox.information( sgPyQt.getDesktop(), 'Info', "Object '%s' isn't a variable. Can't set value." % attr.Value() )
70     return 0.
71
72 def getSubSObjectByName( studyId, sobjFather, childName ):
73     logger.debug("GENERICSOLVER.getSubSObjectByName Looking for sobjet named " + childName)
74     study = salome.myStudyManager.GetStudyByID( studyId )
75     iter = study.NewChildIterator( sobjFather )
76     #builder = study.NewBuilder()
77     while iter.More():
78         sobj = iter.Value()
79         logger.debug("GENERICSOLVER.getSubSObjectByName Got sobjet named " + sobj.GetName())
80         if sobj.GetName() == childName:
81             return sobj
82         iter.Next()
83         pass
84     return None
85
86 ################################################
87
88 class DEVIATION(GENERICSOLVER_ORB__POA.DEVIATION_Gen,
89                 SALOME_ComponentPy.SALOME_ComponentPy_i,
90                 SALOME_DriverPy.SALOME_DriverPy_i):
91     
92     lock = threading.Lock()
93     
94     """
95         Pour etre un composant SALOME cette classe Python
96         doit avoir le nom du composant et heriter de la
97         classe DEVIATION_Gen issue de la compilation de l'idl
98         par omniidl et de la classe SALOME_ComponentPy_i
99         qui porte les services generaux d'un composant SALOME
100     """
101     def __init__ ( self, orb, poa, contID, containerName, instanceName, 
102                    interfaceName ):
103         logger.info("DEVIATION.__init__: " + containerName + ' ; ' + instanceName)
104         SALOME_ComponentPy.SALOME_ComponentPy_i.__init__(self, orb, poa,
105                     contID, containerName, instanceName, interfaceName, 0)
106         SALOME_DriverPy.SALOME_DriverPy_i.__init__(self, interfaceName)
107         # On stocke dans l'attribut _naming_service, une reference sur
108         # le Naming Service CORBA
109         self._naming_service = SALOME_ComponentPy.SALOME_NamingServicePy_i( self._orb )
110         self.inputVarList = None
111         self.outputVarList = None
112         self.evalPoint = None
113
114 ######################################################################
115 # This is the Wrapper part of the GENERICSOLVER module, ie
116 # the three following methods are used by generic controlling
117 # modules like OpenTURNS in order to launch a computation.
118 # The interface is declared in GENERICSOLVER_Gen.idl. The methods
119 # are free to call the legacy interface (see below).
120 ######################################################################
121
122     def _raiseSalomeError(self):
123         message = "Error in component %s running in container %s." % (self._instanceName, self._containerName)
124         logger.exception(message)
125         message += " " + traceback.format_exc()
126         exc = SALOME.ExceptionStruct(SALOME.INTERNAL_ERROR, message,
127                                      inspect.stack()[1][1], inspect.stack()[1][2])
128         raise SALOME.SALOME_Exception(exc)
129
130     def Init(self, inputVarList, outputVarList, studyId, caseEntry):
131         """
132         This method is an example for the initialization of a computation component for
133         use with OpenTURNS in SALOME 5.1.5 and later (for YACS integration)
134         """
135         try:
136             logger.info("DEVIATION.Init: " + self._containerName +
137                         ' ; ' + self._instanceName)
138             self.inputVarList = inputVarList
139             self.outputVarList = outputVarList
140             self.evalPoint = GetDataFromCase(studyId, caseEntry)
141             logger.debug("inputVarList: %s" % self.inputVarList)
142             logger.debug("outputVarList: %s" % self.outputVarList)
143             logger.debug("evalPoint: %s" % self.evalPoint)
144         except:
145             self._raiseSalomeError()
146
147     def Exec(self, inPoint):
148         """
149         This method is an example for the execution of a computation component for
150         use with OpenTURNS in SALOME 5.1.5 and later (for YACS integration)
151         """
152         try:
153             logger.info("DEVIATION.Exec: " + self._containerName +
154                         ' ; ' + self._instanceName)
155             if self.inputVarList is None:
156                 raise Exception("Init not run")
157             if len(inPoint) != len(self.inputVarList):
158                 raise Exception("Size mismatch between inputVarList and point to evaluate")
159
160             logger.debug("DEVIATION.Exec (1): inPoint  = %s" % inPoint)
161             for i in range(len(self.inputVarList)):
162                 self.evalPoint[self.inputVarList[i]] = inPoint[i]
163             logger.debug("evalPoint = %s" % self.evalPoint)
164
165             resDict = {}
166             resDict["dev"] = self.BeamModel(**self.evalPoint)
167
168             outPoint = []
169             for outputVar in self.outputVarList:
170                 outPoint.append(resDict[outputVar])
171             logger.debug("DEVIATION.Exec (2): outPoint = %s" % outPoint)
172             return outPoint
173         except:
174             self._raiseSalomeError()
175
176     def Finalize(self):
177         """
178         This method is an implementation for the DEVIATION interface.
179         It cleans everything set so far.
180         """
181         try:
182             logger.info("DEVIATION.Finalize: " + self._containerName + ' ; ' + self._instanceName)
183         except:
184             self._raiseSalomeError()
185         
186 ######################################################################
187 # This is the computation part of the GENERICSOLVER module, ie
188 # the following method realizes what the solver is intended to do.
189 # The interface of this method (and maybe other ones) is absolutely
190 # free and depends on the module (legacy interface).
191 ######################################################################
192
193     def BeamModel(self, E, F, L, I):
194        """
195        This method implements a beam bending model based on the following formula:
196        deviation = ( Force * Length^3 ) / ( 3 * YoungModulus * InertiaSection )
197        """
198        d = (F * L * L * L) / (3. * E * I)
199        logger.debug("DEVIATION.BeamModel (E=%g, F=%g, L=%g, I=%g) = %g" % (E, F, L, I, d))
200        return d