Salome HOME
Removed dependency on PAL module
[samples/genericsolver.git] / src / GENERICSOLVER / GENERICSOLVER.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 salome.kernel.logger import Logger
34 from salome.kernel import termcolor
35 logger = Logger("GENERICSOLVER", color = termcolor.BLUE_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 # Add some variable to the case
59 ###
60 def AddDataToCase( studyId, caseEntry, varName, varValue ):
61     study = salome.myStudyManager.GetStudyByID( studyId )
62     case = study.FindObjectID( caseEntry )
63     builder = study.NewBuilder()
64     var = addObjectInStudy( builder, case, varName, VARIABLE_ID )
65     setValueToVariable( builder, var, varValue )
66     sg.updateObjBrowser( True )
67     pass
68
69 ###
70 # Plays with study
71 ###
72 def addObjectInStudy( builder, father, objname, objid ):
73     obj = getSubSObjectByName( father, objname )
74     if obj is None:
75         obj  = builder.NewObject( father )
76         attr = builder.FindOrCreateAttribute( obj, "AttributeName" )
77         attr.SetValue( objname )
78         attr = builder.FindOrCreateAttribute( obj, "AttributeLocalID" )
79         attr.SetValue( objid )
80     return obj
81
82 def setValueToVariable( builder, varobj, value ):
83     attr = builder.FindOrCreateAttribute( varobj, "AttributeLocalID" )
84     objid = attr.Value()
85     if (objid == VARIABLE_ID):
86         attr = builder.FindOrCreateAttribute( varobj, "AttributeReal" )
87         attr.SetValue( value )
88     else:
89         attr = builder.FindOrCreateAttribute( varobj, "AttributeName" )
90         QMessageBox.information( sgPyQt.getDesktop(), 'Info', "Object '%s' isn't a variable. Can't set value." % attr.Value() )
91     pass
92
93 def getValueOfVariable( builder, varobj ):
94     attr = builder.FindOrCreateAttribute( varobj, "AttributeLocalID" )
95     objid = attr.Value()
96     if (objid == VARIABLE_ID):
97         attr = builder.FindOrCreateAttribute( varobj, "AttributeReal" )
98         return attr.Value()
99     else:
100         attr = builder.FindOrCreateAttribute( varobj, "AttributeName" )
101         QMessageBox.information( sgPyQt.getDesktop(), 'Info', "Object '%s' isn't a variable. Can't set value." % attr.Value() )
102     return 0.
103
104 def getSubSObjectByName( studyId, sobjFather, childName ):
105     logger.debug("GENERICSOLVER.getSubSObjectByName Looking for sobjet named " + childName)
106     study = salome.myStudyManager.GetStudyByID( studyId )
107     iter = study.NewChildIterator( sobjFather )
108     #builder = study.NewBuilder()
109     while iter.More():
110         sobj = iter.Value()
111         logger.debug("GENERICSOLVER.getSubSObjectByName Got sobjet named " + sobj.GetName())
112         if sobj.GetName() == childName:
113             return sobj
114         iter.Next()
115         pass
116     return None
117
118 ################################################
119
120 class GENERICSOLVER(GENERICSOLVER_ORB__POA.GENERICSOLVER_Gen,
121                     SALOME_ComponentPy.SALOME_ComponentPy_i,
122                     SALOME_DriverPy.SALOME_DriverPy_i):
123     
124     lock = threading.Lock()
125     
126     """
127         Pour etre un composant SALOME cette classe Python
128         doit avoir le nom du composant et heriter de la
129         classe GENERICSOLVER_Gen issue de la compilation de l'idl
130         par omniidl et de la classe SALOME_ComponentPy_i
131         qui porte les services generaux d'un composant SALOME
132     """
133     def __init__ ( self, orb, poa, contID, containerName, instanceName, 
134                    interfaceName ):
135         logger.info("GENERICSOLVER.__init__: " + containerName + ' ; ' + instanceName)
136         SALOME_ComponentPy.SALOME_ComponentPy_i.__init__(self, orb, poa,
137                     contID, containerName, instanceName, interfaceName, 0)
138         SALOME_DriverPy.SALOME_DriverPy_i.__init__(self, interfaceName)
139         # On stocke dans l'attribut _naming_service, une reference sur
140         # le Naming Service CORBA
141         self._naming_service = SALOME_ComponentPy.SALOME_NamingServicePy_i( self._orb )
142         self.case = None
143         self.wrapperDescription = ""
144
145 ######################################################################
146 # This is the Wrapper part of the GENERICSOLVER module, ie
147 # the three following methods are used by generic controlling
148 # modules like OpenTURNS in order to launch a computation.
149 # The interface is declared in GENERICSOLVER_Gen.idl. The methods
150 # are free to call the legacy interface (see below).
151 ######################################################################
152
153     def _raiseSalomeError(self):
154         message = "Error in component %s running in container %s." % (self._instanceName, self._containerName)
155         logger.exception(message)
156         message += " " + traceback.format_exc()
157         exc = SALOME.ExceptionStruct(SALOME.INTERNAL_ERROR, message,
158                                      inspect.stack()[1][1], inspect.stack()[1][2])
159         raise SALOME.SALOME_Exception(exc)
160
161     def Init ( self, studyId, caseEntry, wrapperDescription ):
162         """
163         This method is an implementation for the GENERICSOLVER interface.
164         It sets the component with some deterministic parametrization.
165         """
166         try:
167             logger.info("GENERICSOLVER.Init: " + self._containerName + ' ; ' + self._instanceName)
168             logger.debug("GENERICSOLVER.Init : enter")
169             logger.debug("GENERICSOLVER.Init : studyId = %d - caseEntry = %s - wrapperDescription = %s" % ( studyId, caseEntry, wrapperDescription ))
170             self.wrapperDescription = wrapperDescription
171             GENERICSOLVER.lock.acquire()
172             salome.salome_init()
173             GENERICSOLVER.lock.release()
174         
175             self.case = GetDataFromCase( studyId, caseEntry )
176             if self.case is None:
177                 return 1
178             logger.debug("GENERICSOLVER.Init : exit")
179             return 0
180         except:
181             self._raiseSalomeError()
182
183     def Exec ( self , inPoint ):
184         """
185         This method is an implementation for the GENERICSOLVER interface.
186         It runs the component with some new parameters compared with the deterministic ones.
187         """
188         try:
189             logger.info("GENERICSOLVER.Exec: " + self._containerName + ' ; ' + self._instanceName)
190             if self.case is None :
191                 logger.error("GENERICSOLVER.Exec : Init not run")
192                 return 1, None
193         
194             logger.debug("GENERICSOLVER.Exec (1): inPoint  = %s" % inPoint)
195             case = dict( self.case )
196             if self.wrapperDescription != "":
197                 import sys
198                 logger.debug("sys.path = %s" % sys.path)
199                 import openturns.wrapper
200                 wrapper = openturns.wrapper.WrapperFile.BuildWrapperFromStream( self.wrapperDescription )
201                 data = wrapper.getWrapperData()
202                 variableList = data.getVariableList()
203                 i = 0
204                 for idx in range( variableList.getSize() ):
205                     variable = variableList[ idx ]
206                     if variable.type_ == 0:
207                         logger.debug("variable %s <-> index %d" % ( variable.id_, i ))
208                         case[ variable.id_ ] = inPoint[ i ]
209                         i += 1
210
211             logger.debug("Case = %s" % case)
212             logger.info("Evaluating case by component %s in container %s" %
213                         (self._instanceName, self._containerName))
214             outPoint = self.BeamModel( **case )
215
216             logger.debug("GENERICSOLVER.Exec (2): inPoint  = %s" % inPoint)
217             logger.debug("GENERICSOLVER.Exec (2): outPoint = %s" % outPoint)
218             return 0, outPoint
219
220         except:
221             self._raiseSalomeError()
222
223     def Finalize ( self ):
224         """
225         This method is an implementation for the GENERICSOLVER interface.
226         It cleans everything set so far.
227         """
228         try:
229             logger.info("GENERICSOLVER.Finalize: " + self._containerName + ' ; ' + self._instanceName)
230             logger.debug("GENERICSOLVER.Finalize : enter")
231             logger.debug("GENERICSOLVER.Finalize : exit")
232             return 0
233         except:
234             self._raiseSalomeError()
235         
236 ######################################################################
237 # This is the computation part of the GENERICSOLVER module, ie
238 # the following method realizes what the solver is intended to do.
239 # The interface of this method (and maybe other ones) is absolutely
240 # free and depends on the module (legacy interface).
241 ######################################################################
242
243     def BeamModel ( self , E=1., F=0., L=0., I=1. ):
244        """
245        This method implements a beam bending model based on the following formula:
246        deviation = ( Force * Length^3 ) / ( 3 * YoungModulus * InertiaSection )
247        """
248        d = ( F * L*L*L ) / ( 3. * E * I )
249        logger.debug("GENERICSOLVER.BeamModel (E=%g, F=%g, L=%g, I=%g) = %g" % (E,F,L,I,d))
250
251        return (d,)