Code_TYMPAN  4.4.0
Industrial site acoustic simulation
TYCalculManager.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) <2012-2024> <EDF-DTG> <FRANCE>
3  * This file is part of Code_TYMPAN (R).
4  * Code_TYMPAN (R) is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  * Code_TYMPAN (R) 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.
11  * See the GNU General Public License for more details.
12  * You should have received a copy of the GNU General Public License along
13  * with Code_TYMPAN (R). If not, see <https://www.gnu.org/licenses/>.
14  */
15 
22 #include <qcursor.h>
23 #include <qmessagebox.h>
24 #include <QTemporaryFile>
25 
26 #include "Tympan/core/config.h"
27 #include "Tympan/core/chrono.h"
28 #include "Tympan/core/defines.h"
32 #include "Tympan/gui/app/os.h"
40 #include "TYCalculManager.h"
41 
42 #define TR(id) OLocalizator::getString("TYCalculManager", (id))
43 
44 // using namespace tympan;
45 
47 {
48  _pCurrentCalcul = NULL;
49 }
50 
52 {
53  _pCurrentCalcul = NULL;
54 }
55 
57 {
58  _pCurrentCalcul = pCalcul;
59 }
60 
62 {
63  return launch(_pCurrentCalcul);
64 }
65 
67 {
68  if (!pCalcul)
69  {
70  return false;
71  }
72 
73  if (pCalcul->getState() == TYCalcul::Locked)
74  {
75  OMessageManager::get()->info("+++ UN RESULTAT MESURE NE PEUX FAIRE L'OBJET D'UN CALCUL +++");
76  return true; // Si le calcul est bloque, il ne peut etre execute
77  }
78  // Keep track of old objects in order to clean them at best
79  // Issue #226
80  LPTYProjet oldProjet = pCalcul->getProjet();
81  LPTYSiteNode oldSite = oldProjet->getSite();
82  LPTYCalcul oldCalcul = oldProjet->getCurrentCalcul();
83 
84  TYProjet* pProject = pCalcul->getProjet();
85 
86  // Clear "calcul" result data before computing (avoid problems when removing some elements)
87  pCalcul->clearResult();
88 
90 
91  // Is the debug option "TYMPAN_DEBUG=keep_tmp_files" enabled?
92  bool keep_tmp_files = must_keep_tmp_files();
93  // Temporary XML files to give the current acoustic problem to the python
94  // script and get the results
95  QTemporaryFile problemfile;
96  problemfile.setFileTemplate(QDir::tempPath() + QString("/XXXXXX.xml"));
97  QTemporaryFile resultfile;
98  resultfile.setFileTemplate(QDir::tempPath() + QString("/XXXXXX.xml"));
99 
100  QFileInfo fileInfo(getTYApp()->getCurrentFileName());
101  QString meshFilePath =
102  fileInfo.path().replace("\\", "/") + "/" + fileInfo.completeBaseName() + "." + "ply";
103 
104  if (!init_tmp_file(problemfile, keep_tmp_files) || !init_tmp_file(resultfile, keep_tmp_files))
105  {
106  logger.error(
107  "Creation de fichier temporaire impossible. Veuillez verifier l'espace disque disponible.");
108  return false;
109  }
110  // Serialize current project
111  try
112  {
113  tympan::save_project(problemfile.fileName().toUtf8().data(), pProject);
114  }
115  catch (const tympan::invalid_data& exc)
116  {
117  std::ostringstream msg;
118  msg << boost::diagnostic_information(exc);
119  logger.error("Could not export current project. Computation won't be done");
120  logger.debug(msg.str().c_str());
121  return false;
122  }
123  if (keep_tmp_files)
124  {
125  logger.debug("Le calcul va s'executer en mode debug.\nLes fichiers temporaires ne seront pas "
126  "supprimes une fois le calcul termine.\nProjet courant non calcule: %s. Projet avec les "
127  "resultats du calcul: %s. Mesh de l'altimetrie au format ply: %s",
128  problemfile.fileName().toStdString().c_str(),
129  resultfile.fileName().toStdString().c_str());
130  }
131 
132  // Call python script "solve_tympan_project.py" with: the name of the file
133  // containing the problem, the name of the file where to record
134  // the result and the directory containing the solver plugin to use
135  // to solve the acoustic problem
136  QStringList args;
137  QString absolute_plugins_path(QCoreApplication::applicationDirPath());
138  absolute_plugins_path.append("/");
139  absolute_plugins_path.append(PLUGINS_PATH);
140  QString absolute_pyscript_path(QCoreApplication::applicationDirPath());
141  absolute_pyscript_path.append("/");
142  absolute_pyscript_path.append(SOLVE_PYSCRIPT);
143  args << absolute_pyscript_path << problemfile.fileName() << resultfile.fileName() << meshFilePath
144  << absolute_plugins_path;
145 
146  // Altimetry parameters
147 
148  QString parameters = pCalcul->solverParams;
149  QRegularExpression altimetry_size_criterion_reg("(MeshElementSizeMax\\s?=\\s?)([0-9]+.[0-9]*)");
150  QRegularExpression altimetry_refine_mesh_reg("(RefineMesh\\s?=\\s?)(True|False)");
151  QRegularExpression altimetry_use_volumes_landtakes_reg("(UseVolumesLandtake\\s?=\\s?)(True|False)");
152  QRegularExpressionMatch match_size = altimetry_size_criterion_reg.match(parameters);
153  QRegularExpressionMatch match_refi = altimetry_refine_mesh_reg.match(parameters);
154  QRegularExpressionMatch match_land = altimetry_use_volumes_landtakes_reg.match(parameters);
155 
156  bool altiIsOK = oldSite->getAltimetry()->isUpToDate();
157 
158  if (match_size.hasMatch() && match_refi.hasMatch() && match_land.hasMatch())
159  {
160  QString altimetry_size_criterion = match_size.captured(2);
161  QString altimetry_refine_mesh = match_refi.captured(2);
162  QString altimetry_use_volumes_landtakes = match_land.captured(2);
163  QString altimetry_update = (altiIsOK) ? QString("False") : QString("True");
164 
165  args << altimetry_size_criterion << altimetry_refine_mesh << altimetry_use_volumes_landtakes
166  << altimetry_update;
167  }
168  logger.info(TR("id_msg_go_calcul"));
169 
170  if (!python_gui(args))
171  {
172  return false;
173  }
174  // Then read the result to update the internal model
175  LPTYProjet result;
176  try
177  {
178  // Before loading result project, set current working directory of the application to working
179  // directory to ensure correct loading of topographic file.
181  result = tympan::load_project(resultfile.fileName().toUtf8().data());
182  }
183  catch (const tympan::invalid_data& exc)
184  {
185  std::ostringstream msg;
186  msg << boost::diagnostic_information(exc);
187  logger.error("Could not import computed project. No results available.");
188  logger.debug(msg.str().c_str());
189  QMessageBox msgBox;
190  msgBox.setText("Le fichier de resultats n'a pas pu etre lu.");
191  msgBox.exec();
192  return false;
193  }
194  // Update the current project with the results of the current acoustic
195  // problem
196  pProject = result.getRealPointer();
197  pCalcul = pProject->getCurrentCalcul();
198  getTYApp()->setCurProjet(result);
199  getTYMainWnd()->getProjetFrame()->setProjet(pProject);
200  // Update site altimetry with the mesh retrieved from the ply file
201  LPTYSiteNode pSite = pProject->getSite();
202  std::deque<OPoint3D> points;
203  std::deque<OTriangle> triangles;
204  std::deque<LPTYSol> materials;
205  pSite->readMesh(points, triangles, materials, meshFilePath);
206  pSite->setMeshFilePath(meshFilePath);
207  pSite->getAltimetry()->plugBackTriangulation(points, triangles, materials);
208  // If altimetry was already up to date, it is loaded from .ply
209  if (!altiIsOK)
210  {
211  // One global altimetry update for all the sites
212  pSite->updateAltimetrie(meshFilePath);
213  }
214  pSite->getAltimetry()->setIsUpToDate(true);
215  pSite->updateAltiInfra();
216  pSite->updateAcoustique();
217  pProject->updateAltiRecepteurs();
218  // Update graphics
219  pCalcul->getParent()->updateGraphicTree();
220  pCalcul->updateGraphicTree();
221 
222  // Update modeler frames after computation
224 
225  // Clean at best old project, site and calcul by removing references on them
226  oldCalcul->setSite(NULL);
227  oldSite->setProjet(NULL);
228  oldProjet->remAllCalcul();
229  oldProjet->remAllMaillage();
230  oldProjet->remAllPointControl();
231  oldProjet->unsetSite();
232 
233  getTYMainWnd()->updateModelers(false, false);
235  // Update projet frame
237  // Reset ActionManager
238  // TODO Reset ActionManager for all modelers
239  if (getTYMainWnd()->getCurrentModeler())
241  // Computation achieved with success
242  logger.info(TR("id_msg_calcul_done"));
243  return true;
244 }
245 
247 {
248  bool ret = true;
249  TYCalcul* pCalcul = NULL;
250  TYProjet* pProjet = getTYApp()->getCurProjet().getRealPointer();
251  if (pProjet)
252  {
253  pCalcul = pProjet->getCurrentCalcul();
254  }
255  else
256  {
257  return true;
258  }
259 
260  if (pCalcul)
261  {
262  ret = true;
264 
265  /*// Question
266  int del = QMessageBox::Yes;
267  if (pCalcul->getIsAcousticModified())
268  {
269  del = QMessageBox::warning(getTYMainWnd(), getTYMainWnd()->windowTitle(),
270  TR("id_msg_del_resultat"), QMessageBox::Yes, QMessageBox::No);
271  }
272  if (del == QMessageBox::Yes)
273  {
274  // Ok pour effacer les resultats (uniquement si c'est un resultat calcule);
275  if (pCalcul->getState() == TYCalcul::Actif)
276  {
277  // Reset du resultat
278  pCalcul->getResultat()->purge();
279  for (unsigned int i=0 ; i<pProjet->getPointsControl().size() ; i++)
280  {
281  pProjet->getPointsControl()[i]->purge(pCalcul);
282  }
283 
284  pCalcul->setIsAcousticModified(false); // La calcul est a jour
285  }
286 
287  ret = true;
288  }
289  else
290  {
291  ret = false;
292  }*/
293  }
294 
295  return ret;
296 }
297 
299 {
300  bool ret = false;
301  TYSiteNode* pSite = dynamic_cast<TYSiteNode*>(pElement);
302  if (pSite != nullptr)
303  {
304  pSite->updateAcoustique();
305  }
306  LPTYAcousticVolumeNode pAccVolNode = dynamic_cast<TYAcousticVolumeNode*>(pElement);
307  if (pAccVolNode._pObj != nullptr)
308  {
309  TYMessageManager::get()->info(TR("id_msg_go_updateacoustic"));
310 
311  TYApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
312 
313  // Calcul acoustique
314  ret = pAccVolNode->updateAcoustic();
315 
316  if (ret)
317  {
318  TYMessageManager::get()->info(TR("id_msg_updateacoustic_done"));
319  }
320  else
321  {
322  TYMessageManager::get()->info(TR("id_msg_updateacoustic_failed"));
323  }
324 
325  // MaJ graphique
326  pAccVolNode->getGraphicObject()->update(true);
327  getTYMainWnd()->updateModelers(false, false);
328 
329  TYApplication::restoreOverrideCursor();
330  }
331  else
332  {
333  LPTYAcousticLine pLine = dynamic_cast<TYAcousticLine*>(pElement);
334  if (pLine._pObj != nullptr)
335  {
336  TYMessageManager::get()->info(TR("id_msg_go_updateacoustic"));
337 
338  TYApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
339 
340  // Calcul acoustique
341  ret = pLine->updateAcoustic();
342 
343  if (ret)
344  {
345  TYMessageManager::get()->info(TR("id_msg_updateacoustic_done"));
346  }
347  else
348  {
349  TYMessageManager::get()->info(TR("id_msg_updateacoustic_failed"));
350  }
351 
352  // MaJ graphique
353  pLine->getGraphicObject()->update(true);
354  getTYMainWnd()->updateModelers(false, false);
355 
356  TYApplication::restoreOverrideCursor();
357  }
358  }
359 
360  return ret;
361 }
TYApplication * getTYApp()
Retourne le pointeur sur l'application.
TYMainWindow * getTYMainWnd()
Retourne le pointeur sur la fenetre principale.
pour l'application Tympan (fichier header)
#define TR(id)
Gestionnaire des calculs acoustiques. Il fait l'interface entre l'IHM et le gestionnaire de donnees p...
Fenetre principale de l'application Tympan (fichier header)
utilitaire pour la gestion des messages dans Tympan (fichier header)
Classe generique pour une fenetre de modeleur (fichier header)
Frame pour la gestion de projet (fichier header)
Frame pour la gestion de site (fichier header)
Classe Modeler specialisee pour l'edition des sites (fichier header)
virtual void debug(const char *message,...)
Definition: logging.cpp:151
virtual void error(const char *message,...)
Definition: logging.cpp:127
static OMessageManager * get()
Definition: logging.cpp:108
virtual void info(const char *message,...)
Definition: logging.cpp:143
T * getRealPointer()
Definition: smartptr.h:291
T * _pObj
The real pointer, must derived IRefCount.
Definition: smartptr.h:307
virtual bool updateAcoustic(const bool &force=false)
void reset()
Reinitialise l'historique.
bool isUpToDate() const
Definition: TYAltimetrie.h:176
void plugBackTriangulation(const std::deque< OPoint3D > &points, std::deque< OTriangle > &triangles, const std::deque< LPTYSol > &materials)
plug back triangulation providfed by the TYTopographie
void setIsUpToDate(bool isUpToDate)
static void setCurrentQtDir()
Indique Ã&#160; Qt le chemin du répertoire courant.
LPTYProjet getCurProjet()
Set/Get du projet courant.
void setCurProjet(LPTYProjet pProjet)
Set/Get du projet courant.
virtual ~TYCalculManager()
Destructeur.
bool launchCurrent()
Execute le calcul courant.
bool updateAcoustic(TYElement *pElement)
Appelle la methode de calcul acoustique du volume node passe.
bool askForResetResultat()
Previent l'utilisateur que le resultat va etre efface, si celui-ci est valide.
bool launch(LPTYCalcul pCalcul)
Execute un calcul.
LPTYCalcul _pCurrentCalcul
Le Calcul courant.
void setCurrent(LPTYCalcul pCalcul)
Set du Calcul et Projet courant.
TYCalculManager()
Constructeur par defaut.
Calculation program.
Definition: TYCalcul.h:50
void clearResult()
Definition: TYCalcul.cpp:845
int getState()
Get calculation state.
Definition: TYCalcul.h:416
void setSite(LPTYSiteNode pSite)
Definition of the site on which the calculation will be done.
Definition: TYCalcul.cpp:868
@ Locked
Definition: TYCalcul.h:62
QString solverParams
Definition: TYCalcul.h:482
TYProjet * getProjet()
Definition: TYCalcul.cpp:67
TYElement * getParent() const
Definition: TYElement.h:706
static void setIsSavedOk(const bool &toSave)
Definition: TYElement.h:914
void updateModelersAfterComputation(LPTYProjet &result)
TYProjetFrame * getProjetFrame()
Definition: TYMainWindow.h:73
void updateModelers(bool clipping=true, bool axesAndGrid=true, bool displayList=true)
TYModelerFrame * getCurrentModeler()
Definition: TYMainWindow.h:68
TYActionManager * getActionManager()
void setCalculDone(bool state)
void setProjet(LPTYProjet pProjet)
classe de definition d'un projet.
Definition: TYProjet.h:45
bool remAllPointControl()
Definition: TYProjet.cpp:497
bool updateAltiRecepteurs()
Definition: TYProjet.cpp:643
bool remAllMaillage()
Suppression de tous les maillages.
Definition: TYProjet.cpp:909
LPTYSiteNode getSite()
Get du site.
Definition: TYProjet.h:169
void unsetSite()
Supprime la liaison avec le site.
Definition: TYProjet.cpp:566
LPTYCalcul getCurrentCalcul()
Set/Get du pointeur du Calcul courant.
Definition: TYProjet.h:426
void remAllCalcul()
Suppression de tous les elements.
Definition: TYProjet.cpp:561
void setProjet(const LPTYProjet pProjet)
Definition: TYSiteNode.cpp:560
LPTYAltimetrie getAltimetry() const
bool readMesh(std::deque< OPoint3D > &points, std::deque< OTriangle > &triangles, std::deque< LPTYSol > &materials, const QString &meshFilePath)
Definition: TYSiteNode.cpp:734
virtual void updateAcoustique(const bool &force=false)
void setMeshFilePath(const QString &path)
Definition: TYSiteNode.cpp:64
virtual bool updateAltimetrie(QString resultMeshFilePath)
Definition: TYSiteNode.cpp:628
virtual void updateAltiInfra()
Definition: TYSiteNode.cpp:784
void save_project(const char *filename, const LPTYProjet &project)
save a project into an XML file
LPTYProjet load_project(const char *filename)
load an XML project file
bool python_gui(QStringList args)
Launch a Python-driven computation with a GUI progress dialog.
Definition: os.cpp:45
Utilities for interactions between the GUI and the operating system (headers).
The base exception class for errors due to invalid data.
Definition: exceptions.h:75
bool must_keep_tmp_files()
Tell whether temporary files should be preserved (debug mode).
bool init_tmp_file(QTemporaryFile &tmp_file, bool keep_file)
Create and initialize a QTemporaryFile according to the current policy.
Utilities to interact with Python subprocesses from the Tympan application.
Utilities to load a project and a solver.