Documentation for OpenFLUID 2.2.0
Binding.hpp
Go to the documentation of this file.
1 /*
2 
3  This file is part of OpenFLUID software
4  Copyright(c) 2007, INRA - Montpellier SupAgro
5 
6 
7  == GNU General Public License Usage ==
8 
9  OpenFLUID is free software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  OpenFLUID is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with OpenFLUID. If not, see <http://www.gnu.org/licenses/>.
21 
22 
23  == Other Usage ==
24 
25  Other Usage means a use of OpenFLUID that is inconsistent with the GPL
26  license, and requires a written agreement between You and INRA.
27  Licensees for Other Usage of OpenFLUID may use this file in accordance
28  with the terms contained in the written agreement between You and INRA.
29 
30 */
31 
32 /**
33  @file Binding.hpp
34 
35  @author Jean-Christophe FABRE <jean-christophe.fabre@inra.fr>
36 */
37 
38 
39 #ifndef __OPENFLUID_UTILS_BINDING_HPP__
40 #define __OPENFLUID_UTILS_BINDING_HPP__
41 
42 
43 #include <clocale>
44 
45 #include <openfluid/config.hpp>
46 #include <openfluid/base/Init.hpp>
71 
72 
73 // =====================================================================
74 // =====================================================================
75 
76 
77 #define STRING_TO_ALLOCATED_CARRAY(str,carray) \
78  char* carray = (char*)malloc((str.length()+1)*sizeof(char)); \
79  strcpy(carray,str.c_str());
80 
81 
82 /**
83  Macro to use for definition and initialization of the static part of the openfluid::utils::Binding class.
84  It must be called in the C or C++ code of the binding wrapper.
85  @param[in] erroutclass The class definition for the standard output and errors,
86  derived from the openfluid::utils::BindingAbstractOutErr class.
87 */
88 #define OPENFLUID_BINDING_DEFINE(erroutclass)\
89  bool openfluid::utils::Binding::m_Initialized = false; \
90  std::string openfluid::utils::Binding::m_LastErrorMsg = ""; \
91  const openfluid::utils::BindingAbstractOutErr* openfluid::utils::Binding::mp_OutErr = new erroutclass();
92 
93 
94 // =====================================================================
95 // =====================================================================
96 
97 
98 // OpenFLUID:stylecheck:!incs
99 
100 
101 namespace openfluid { namespace utils {
102 
103 /**
104  @brief Class for easier binding with other programming languages.
105 
106  Class for easier binding of OpenFLUID with other programming languages, such as Python, R, JavaScript, ...
107  This class provides common methods to open datasets, add wares paths, modify parameters and attributes,
108  run simulations and many more. All of these methods have parameters and return values in plain old types
109  for better interoperability with other languages, excepted for internal data usually handled as "external pointers"
110  in bindings.
111 
112  To use this header-only class
113  @li the header <openfluid/utils/Binding.hpp> must be included in the C or C++ wrapper code
114  specifically developped for the binded language,
115  @li a class derived from the openfluid::utils::BindingAbstractOutErr class must be defined in order to process
116  the standard and error console streams,
117  @li the #OPENFLUID_BINDING_DEFINE macro must be called in the C or C++ wrapper code,
118  with the previous derived class as a parameter.
119 
120  <i>Example</i>
121  @snippet misc/bindings.cpp bindings
122 */
123 class Binding
124 {
125  private:
126 
127  static bool m_Initialized;
128 
129  static std::string m_LastErrorMsg;
130 
131  static const BindingAbstractOutErr* mp_OutErr;
132 
134 
135  bool m_IsProject = false;
136  bool m_IsDataset = false;
137 
138  std::string m_SourcePath = "";
139  std::string m_OutputDir = "";
140 
141  bool m_IsSimulationRun = false;
142 
143 
144  // =====================================================================
145  // =====================================================================
146 
147 
148  Binding()
149  { }
150 
151 
152  // =====================================================================
153  // =====================================================================
154 
155 
156  ~Binding()
157  { }
158 
159 
160  // =====================================================================
161  // =====================================================================
162 
163 
164  static void unloadAllWares()
165  {
166  openfluid::machine::SimulatorRegistry::instance()->clear();
167  openfluid::machine::ObserverRegistry::instance()->clear();
168  openfluid::machine::SimulatorPluginsManager::instance()->unloadAll();
169  openfluid::machine::ObserverPluginsManager::instance()->unloadAll();
170  }
171 
172 
173  // =====================================================================
174  // =====================================================================
175 
176 
177  std::map<openfluid::core::UnitsClass_t,unsigned int> getUnitsCountByClasses()
178  {
179  std::map<openfluid::core::UnitsClass_t,unsigned int> RetMap;
180 
181  for (const auto& UnitsByClass : m_FluidXDesc.spatialDomain().spatialUnits())
182  {
183  RetMap[UnitsByClass.first] = UnitsByClass.second.size();
184  }
185 
186  return RetMap;
187  }
188 
189 
190  // =====================================================================
191  // =====================================================================
192 
193 
194  public:
195 
196  /**
197  Static initialization of the binding. Muste be called at least once.
198  */
199  static void init()
200  {
201  if (m_Initialized)
202  {
203  return;
204  }
205 
207 
208  // reset locale for "LC_NUMERIC" To "C"
209  // to prevent changing locale on init
210  std::setlocale(LC_NUMERIC,"C");
211 
212  m_Initialized = true;
213  }
214 
215 
216  // =====================================================================
217  // =====================================================================
218 
219 
220  /**
221  Returns a new instance
222  @return The newly created instance
223  */
224  static Binding* make()
225  {
226  return (new Binding());
227  }
228 
229 
230  // =====================================================================
231  // =====================================================================
232 
233 
234  /**
235  Deletes a given instance
236  @param[in] B The instance to delete
237  */
238  static void destroy(Binding* B)
239  {
240  delete B;
241  }
242 
243 
244  // =====================================================================
245  // =====================================================================
246 
247 
248  /**
249  Returns the OpenFLUID version
250  */
251  static const char* getVersion()
252  {
253  STRING_TO_ALLOCATED_CARRAY(openfluid::config::VERSION_FULL,CStr);
254  return CStr;
255  }
256 
257 
258  // =====================================================================
259  // =====================================================================
260 
261 
262  /**
263  Returns the last error message
264  */
265  static const char* getLastError()
266  {
267  return m_LastErrorMsg.c_str();
268  }
269 
270 
271  // =====================================================================
272  // =====================================================================
273 
274 
275  /**
276  Add supplementary paths to search for simulators when running simulations
277  @param[in] Paths The paths to add using the path separator used on the current system
278  @see openfluid::base::Environment::addExtraSimulatorsDirs
279  */
280  static void addExtraSimulatorsPaths(const char* Paths)
281  {
283  }
284 
285 
286  // =====================================================================
287  // =====================================================================
288 
289 
290  /**
291  Resets the list of supplementary paths to search for simulators
292  */
294  {
296  }
297 
298 
299  // =====================================================================
300  // =====================================================================
301 
302 
303  /**
304  Returns the number of default paths to search for simulators
305  @return the number of paths
306  */
307  static unsigned int getSimulatorsPathsCount()
308  {
310  }
311 
312 
313  // =====================================================================
314  // =====================================================================
315 
316 
317  /**
318  Returns the default paths to search for simulators
319  @return the paths list
320  */
321  static char** getSimulatorsPaths()
322  {
323  std::vector<std::string> SimsPaths = openfluid::base::Environment::getSimulatorsDirs();
324 
325  const unsigned int Count = SimsPaths.size();
326 
327  char** Paths = (char**)malloc(Count*sizeof(char*));
328 
329  for (unsigned int i=0;i<Count;i++)
330  {
331  Paths[i] = (char*)malloc(SimsPaths[i].size()+1);
332  std::copy(SimsPaths[i].begin(), SimsPaths[i].end(), Paths[i]);
333  Paths[i][SimsPaths[i].size()] = '\0';
334  }
335 
336  return Paths;
337  }
338 
339 
340  // =====================================================================
341  // =====================================================================
342 
343 
344  /**
345  Returns the number of supplementary paths to search for simulators
346  @return the number of paths
347  */
348  static unsigned int getExtraSimulatorsPathsCount()
349  {
351  }
352 
353 
354  // =====================================================================
355  // =====================================================================
356 
357 
358  /**
359  Returns the supplementary paths to search for simulators
360  @return the paths list
361  */
362  static char** getExtraSimulatorsPaths()
363  {
364  std::vector<std::string> ExtraSimsPaths = openfluid::base::Environment::getExtraSimulatorsDirs();
365 
366  const unsigned int Count = ExtraSimsPaths.size();
367 
368  char** Paths = (char**)malloc(Count*sizeof(char*));
369 
370  for (unsigned int i=0;i<Count;i++)
371  {
372  Paths[i] = (char*)malloc(ExtraSimsPaths[i].size()+1);
373  std::copy(ExtraSimsPaths[i].begin(), ExtraSimsPaths[i].end(), Paths[i]);
374  Paths[i][ExtraSimsPaths[i].size()] = '\0';
375  }
376 
377  return Paths;
378  }
379 
380 
381  // =====================================================================
382  // =====================================================================
383 
384 
385  /**
386  Add supplementary paths to search for observers when running simulations
387  @param[in] Paths the paths to add using the path separator used on the current system
388  @see openfluid::base::Environment::addExtraObserversDirs
389  */
390  static void addExtraObserversPaths(const char* Paths)
391  {
393  }
394 
395 
396  // =====================================================================
397  // =====================================================================
398 
399 
400  /**
401  Resets the list of supplementary paths to search for observers
402  */
404  {
406  }
407 
408 
409  // =====================================================================
410  // =====================================================================
411 
412 
413  /**
414  Returns the number of default paths to search for observers
415  @return The number of paths
416  */
417  static unsigned int getObserversPathsCount()
418  {
420  }
421 
422 
423  // =====================================================================
424  // =====================================================================
425 
426 
427  /**
428  Returns the default paths to search for observers
429  @return The paths list
430  */
431  static char** getObserversPaths()
432  {
433  std::vector<std::string> ObsPaths = openfluid::base::Environment::getObserversDirs();
434 
435  const unsigned int Count = ObsPaths.size();
436 
437  char** Paths = (char**)malloc(Count*sizeof(char*));
438 
439  for (unsigned int i=0;i<Count;i++)
440  {
441  Paths[i] = (char*)malloc(ObsPaths[i].size()+1);
442  std::copy(ObsPaths[i].begin(), ObsPaths[i].end(), Paths[i]);
443  Paths[i][ObsPaths[i].size()] = '\0';
444  }
445 
446  return Paths;
447  }
448 
449 
450  // =====================================================================
451  // =====================================================================
452 
453 
454  /**
455  Returns the number of supplementary paths to search for observers
456  @return The number of paths
457  */
458  static unsigned int getExtraObserversPathsCount()
459  {
461  }
462 
463 
464  // =====================================================================
465  // =====================================================================
466 
467 
468  /**
469  Returns the supplementary paths to search for observers
470  @return The paths list
471  */
472  static char** getExtraObserversPaths()
473  {
474  std::vector<std::string> ExtraObsPaths = openfluid::base::Environment::getExtraObserversDirs();
475 
476  const unsigned int Count = ExtraObsPaths.size();
477 
478  char** Paths = (char**)malloc(Count*sizeof(char*));
479 
480  for (unsigned int i=0;i<Count;i++)
481  {
482  Paths[i] = (char*)malloc(ExtraObsPaths[i].size()+1);
483  std::copy(ExtraObsPaths[i].begin(), ExtraObsPaths[i].end(), Paths[i]);
484  Paths[i][ExtraObsPaths[i].size()] = '\0';
485  }
486 
487  return Paths;
488  }
489 
490 
491  // =====================================================================
492  // =====================================================================
493 
494 
495  /**
496  Sets the current output path used by default
497  @param[in] Path The output path to use
498  */
499  static void setCurrentOutputDir(const char* Path)
500  {
501  openfluid::base::RunContextManager::instance()->setOutputDir(std::string(Path));
502  }
503 
504 
505  // =====================================================================
506  // =====================================================================
507 
508 
509  /**
510  Opens an OpenFLUID dataset given by its path
511  @param[in] Path The path to the dataset
512  @returns an instance of the Binding for the opened dataset, NULL if an error occured
513  */
514  static Binding* openDataset(const char* Path)
515  {
516  Binding* Data = new Binding();
517 
518  try
519  {
520  init();
521 
522  openfluid::base::IOListener FluidXListener;
523 
524  openfluid::base::RunContextManager::instance()->setInputDir(std::string(Path));
525  Data->m_FluidXDesc = openfluid::fluidx::FluidXIO(&FluidXListener)
526  .loadFromDirectory(openfluid::base::RunContextManager::instance()->getInputDir());
527 
528  Data->m_IsSimulationRun = false;
529  Data->m_IsDataset = true;
530  Data->m_SourcePath = openfluid::base::RunContextManager::instance()->getInputDir();
531 
532 
533  return Data;
534  }
535  catch (openfluid::base::Exception& E)
536  {
537  m_LastErrorMsg = "OpenFLUID ERROR: " + std::string(E.what()) +"\n";
538  }
539  catch (std::bad_alloc& E)
540  {
541  m_LastErrorMsg = "MEMORY ALLOCATION ERROR: " + std::string(E.what()) +
542  ". Possibly not enough memory available\n";
543  }
544  catch (std::exception& E)
545  {
546  m_LastErrorMsg = "SYSTEM ERROR: " + std::string(E.what()) +"\n";
547  }
548  catch (...)
549  {
550  m_LastErrorMsg = "UNKNOWN ERROR\n";
551  }
552 
553  Data->m_IsProject = false;
554  Data->m_IsDataset = false;
555  Data->m_SourcePath = "";
556 
557  delete Data;
558 
559  return nullptr;
560  }
561 
562 
563  // =====================================================================
564  // =====================================================================
565 
566 
567  /**
568  Opens an OpenFLUID project given by its path
569  @param[in] Path The path to the project
570  @returns an instance of the Binding for the opened project, NULL if an error occured
571  */
572  static Binding* openProject(const char* Path)
573  {
574  Binding* Data = new Binding();
575 
576  try
577  {
578  init();
579 
580  openfluid::base::IOListener FluidXListener;
581 
582  if (!openfluid::base::RunContextManager::instance()->openProject(std::string(Path)))
583  {
586  std::string(Path) + " is not a correct project path");
587  }
588 
589  Data->m_FluidXDesc = openfluid::fluidx::FluidXIO(&FluidXListener)
590  .loadFromDirectory(openfluid::base::RunContextManager::instance()->getInputDir());
591 
592  Data->m_IsSimulationRun = false;
593  Data->m_IsProject = true;
594  Data->m_SourcePath = openfluid::base::RunContextManager::instance()->getProjectPath();
595 
596  return Data;
597 
598  }
599  catch (openfluid::base::Exception& E)
600  {
601  m_LastErrorMsg = "OpenFLUID ERROR: " + std::string(E.what()) +"\n";
602  }
603  catch (std::bad_alloc& E)
604  {
605  m_LastErrorMsg = "MEMORY ALLOCATION ERROR: " + std::string(E.what()) +
606  ". Possibly not enough memory available\n";
607  }
608  catch (std::exception& E)
609  {
610  m_LastErrorMsg = "SYSTEM ERROR: " + std::string(E.what()) +"\n";
611  }
612  catch (...)
613  {
614  m_LastErrorMsg = "UNKNOWN ERROR\n";
615  }
616 
617  delete Data;
618 
619  return nullptr;
620  }
621 
622 
623  // =====================================================================
624  // =====================================================================
625 
626 
627  /**
628  Writes an OpenFLUID dataset to disk, optionaly with copy of external data from the original dataset
629  @param[in] Path The path to the dataset to write
630  @param[in] WithOriginData optional parameter to enable the copy of external data from the original dataset.
631  Default is false
632  @returns 1 if succeded, 0 if failed
633  */
634  int writeDataset(const char* Path, bool WithOriginData = false)
635  {
636  try
637  {
638  if (WithOriginData && !m_SourcePath.empty())
639  {
640  openfluid::tools::Filesystem::copyDirectory(m_SourcePath, std::string(Path),false,true);
641 
642  auto FluidXToRemove = openfluid::tools::Filesystem::findFilesByExtension(std::string(Path),"fluidx",true);
643 
644  for (const auto& F : FluidXToRemove)
645  {
647  }
648  }
649 
650  openfluid::base::IOListener FluidXListener;
651 
652  openfluid::fluidx::FluidXIO(&FluidXListener).writeToManyFiles(m_FluidXDesc,std::string(Path));
653 
654  return 1;
655  }
656  catch (openfluid::base::Exception& E)
657  {
658  m_LastErrorMsg = "OpenFLUID ERROR: " + std::string(E.what()) +"\n";
659  }
660  catch (std::bad_alloc& E)
661  {
662  m_LastErrorMsg = "MEMORY ALLOCATION ERROR: " + std::string(E.what()) +
663  ". Possibly not enough memory available\n";
664  }
665  catch (std::exception& E)
666  {
667  m_LastErrorMsg = "SYSTEM ERROR: " + std::string(E.what()) +"\n";
668  }
669  catch (...)
670  {
671  m_LastErrorMsg = "UNKNOWN ERROR\n";
672  }
673 
674  return 0;
675  }
676 
677 
678  // =====================================================================
679  // =====================================================================
680 
681 
682  /**
683  Runs a simulation based on the current configuration for simulation.
684  @param[in] IsVerbose Set to true to enable verbosity (false by default).
685  */
686  unsigned short int runSimulation(int IsVerbose = false)
687  {
688  unsigned short int RetValue = 0;
689 
690  try
691  {
692  init();
693  unloadAllWares();
694 
695 
698  std::unique_ptr<openfluid::machine::MachineListener> Listener;
699 
700 
701  if (IsVerbose)
702  {
703  Listener = std::make_unique<BindingVerboseMachineListener>(mp_OutErr);
704  }
705  else
706  {
707  Listener = std::make_unique<openfluid::machine::MachineListener>();
708  }
709 
710 
711  // ===== spatial domain and run config
712 
713  if (IsVerbose)
714  {
715  mp_OutErr->printfOut("%s","Building spatial domain...");
716  }
717 
719 
720  if (IsVerbose)
721  {
722  static_cast<BindingVerboseMachineListener*>(Listener.get())->
724  }
725 
726 
727  // ===== model instance
728 
729  if (IsVerbose)
730  {
731  mp_OutErr->printfOut("%s","Building model instance...");
732  }
733 
734  openfluid::machine::ModelInstance Model(SimBlob,Listener.get());
735 
737 
738  if (IsVerbose)
739  {
740  static_cast<BindingVerboseMachineListener*>(Listener.get())->
742  }
743 
744 
745  // ===== monitoring instance
746 
747  if (IsVerbose)
748  {
749  mp_OutErr->printfOut("%s","Building monitoring instance...");
750  }
751 
752  openfluid::machine::MonitoringInstance Monitoring(SimBlob);
753 
755  Monitoring);
756 
757  if (IsVerbose)
758  {
759  static_cast<BindingVerboseMachineListener*>(Listener.get())->
761  }
762 
763 
764  // ===== simulation
765 
766  m_OutputDir = openfluid::base::RunContextManager::instance()->getOutputDir();
767 
768  Engine = new openfluid::machine::Engine(SimBlob, Model, Monitoring, Listener.get());
769 
770  Engine->initialize();
771 
772  Engine->initParams();
773  Engine->prepareData();
774  Engine->checkConsistency();
775  Engine->run();
776 
777  Engine->finalize();
778 
779  delete Engine;
780 
781  m_IsSimulationRun = true;
782 
783  RetValue = 1;
784  }
785  catch (openfluid::base::Exception& E)
786  {
787  m_LastErrorMsg = "OpenFLUID ERROR: " + std::string(E.what()) +"\n";
788  }
789  catch (std::bad_alloc& E)
790  {
791  m_LastErrorMsg = "MEMORY ALLOCATION ERROR: " + std::string(E.what()) +
792  ". Possibly not enough memory available\n";
793  }
794  catch (std::exception& E)
795  {
796  m_LastErrorMsg = "SYSTEM ERROR: " + std::string(E.what()) +"\n";
797  }
798  catch (...)
799  {
800  m_LastErrorMsg = "UNKNOWN ERROR\n";
801  }
802 
803  unloadAllWares();
804 
805  return RetValue;
806  }
807 
808 
809  // =====================================================================
810  // =====================================================================
811 
812 
813  /**
814  Prints informations about simulation configuration (spatial domain, processes model, ...)
815  */
817  {
818  // Spatial domain
819 
820  mp_OutErr->printfOut("Spatial domain is made of %i spatial units\n",
821  m_FluidXDesc.spatialDomain().getUnitsCount());
822 
823  for (const auto& UnitsClass : m_FluidXDesc.spatialDomain().spatialUnits())
824  {
825  mp_OutErr->printfOut(" - %i units of class %s\n",UnitsClass.second.size(),UnitsClass.first.c_str());
826  }
827 
828 
829  // Model
830 
831  mp_OutErr->printfOut("Model is made of %i simulation items\n",m_FluidXDesc.model().items().size());
832 
833  for (const auto& ModelInfos : m_FluidXDesc.model().items())
834  {
835  mp_OutErr->printfOut(" - ");
836 
837  if (ModelInfos->isType(openfluid::ware::WareType::SIMULATOR))
838  {
839  mp_OutErr->printfOut("%s simulator\n",
840  ((openfluid::fluidx::SimulatorDescriptor*)(ModelInfos))->getID().c_str());
841  }
842 
843  if (ModelInfos->isType(openfluid::ware::WareType::GENERATOR))
844  {
846 
848  {
849  mp_OutErr->printfOut("fixed");
850  }
851 
853  {
854  mp_OutErr->printfOut("random");
855  }
856 
858  {
859  mp_OutErr->printfOut("interp");
860  }
861 
863  {
864  mp_OutErr->printfOut("inject");
865  }
866 
867  mp_OutErr->printfOut(" generator for variable %s on units %s\n",
868  pGenDesc->getVariableName().c_str(),pGenDesc->getUnitsClass().c_str());
869  }
870  }
871 
872  // Time period
873 
874  mp_OutErr->printfOut("Simulation period from %s to %s\n",
875  m_FluidXDesc.runConfiguration().getBeginDate().getAsISOString().c_str(),
876  m_FluidXDesc.runConfiguration().getEndDate().getAsISOString().c_str());
877 
878  // Time step
879 
880  mp_OutErr->printfOut("Simulation time step : %i\n",m_FluidXDesc.runConfiguration().getDeltaT());
881 
882  }
883 
884 
885  // =====================================================================
886  // =====================================================================
887 
888 
889  /**
890  Returns the simulation output directory
891  @return The path to the output directory
892  */
894  {
895  STRING_TO_ALLOCATED_CARRAY(m_OutputDir,CStr);
896  return CStr;
897  }
898 
899 
900  // =====================================================================
901  // =====================================================================
902 
903 
904  /**
905  Returns the default delta T for the current simulation
906  @return The delta T
907  */
909  {
910  return m_FluidXDesc.runConfiguration().getDeltaT();
911  }
912 
913 
914  // =====================================================================
915  // =====================================================================
916 
917 
918  /**
919  Sets the default delta T for the current simulation
920  @param[in] DeltaT The delta T to set
921  */
922  void setDefaultDeltaT(int DeltaT)
923  {
924  m_FluidXDesc.runConfiguration().setDeltaT(DeltaT);
925  }
926 
927 
928  // =====================================================================
929  // =====================================================================
930 
931 
932  /**
933  Returns the begin date for the simulation period,
934  as an ISO date-time string (with a space instead of a T letter, e.g. : 2008-01-02 11:13:00)
935  @return The begin date as a string
936  */
937  const char* getPeriodBeginDate()
938  {
939  std::string DateStr = m_FluidXDesc.runConfiguration().getBeginDate().getAsString("%Y-%m-%d %H:%M:%S");
940  STRING_TO_ALLOCATED_CARRAY(DateStr,CStr);
941 
942  return CStr;
943  }
944 
945 
946  // =====================================================================
947  // =====================================================================
948 
949 
950  /**
951  Returns the end date for the simulation period,
952  as an ISO date-time string (with a space instead of a T letter, e.g. : 2011-08-06 15:00:00)
953  @return The end date as a string
954  */
955  const char* getPeriodEndDate()
956  {
957  std::string DateStr = m_FluidXDesc.runConfiguration().getEndDate().getAsString("%Y-%m-%d %H:%M:%S");
958  STRING_TO_ALLOCATED_CARRAY(DateStr,CStr);
959 
960  return CStr;
961  }
962 
963 
964  // =====================================================================
965  // =====================================================================
966 
967 
968  /**
969  Sets the simulation period with begin and end dates. The dates are given as ISO date-time strings
970  (with a space instead of a T letter, e.g. : 2008-01-02 11:13:00, 2011-08-06 15:00:00)
971  @param[in] BeginDate The begin date as a string
972  @param[in] EndDate The end date as a string
973  */
974  void setPeriod(const char* BeginDate, const char* EndDate)
975  {
976  std::string StrBeginDate(BeginDate);
977  std::string StrEndDate(EndDate);
978  openfluid::core::DateTime DateToSet;
979 
980  if (!StrBeginDate.empty() && DateToSet.setFromISOString(StrBeginDate))
981  {
982  m_FluidXDesc.runConfiguration().setBeginDate(DateToSet);
983  }
984 
985  if (!StrEndDate.empty() && DateToSet.setFromISOString(StrEndDate))
986  {
987  m_FluidXDesc.runConfiguration().setEndDate(DateToSet);
988  }
989  }
990 
991 
992  // =====================================================================
993  // =====================================================================
994 
995 
996  /**
997  Returns the IDs list of the simulators used in the current model, as a semicolon separated list.
998  @return The list of IDs
999  */
1000  const char* getSimulatorsIDs()
1001  {
1002  std::string SimIDsStr("");
1003  std::ostringstream ssSimIDs;
1004  std::string sep = "";
1005  openfluid::fluidx::CoupledModelDescriptor ModDesc(m_FluidXDesc.model());
1006 
1007  for (const auto& Item : ModDesc.items())
1008  {
1009  if (Item->isType(openfluid::ware::WareType::SIMULATOR))
1010  {
1011  ssSimIDs << sep << ModDesc.getID(Item);
1012  sep = ";";
1013  }
1014  }
1015 
1016  SimIDsStr = ssSimIDs.str();
1017  STRING_TO_ALLOCATED_CARRAY(SimIDsStr,CStr);
1018  return CStr;
1019  }
1020 
1021 
1022  // =====================================================================
1023  // =====================================================================
1024 
1025 
1026  /**
1027  Returns the list of the parameters names for a given simulator, as a semicolon separated list.
1028  @param[in] SimID The ID of the simulator
1029  @return The list of parameters names
1030  */
1031  const char* getSimulatorParamNames(const char* SimID)
1032  {
1033  std::string SimIDStr(SimID);
1034  std::string ParamNamesStr("");
1035  std::ostringstream ssParamNames;
1036  std::string sep = "";
1037  openfluid::fluidx::CoupledModelDescriptor ModDesc(m_FluidXDesc.model());
1038  int ItemIndex = ModDesc.findFirstItem(SimIDStr);
1039 
1040  if (ItemIndex < 0)
1041  {
1042  return "";
1043  }
1044 
1045  openfluid::fluidx::ModelItemDescriptor Item = ModDesc.itemAt(ItemIndex);
1047  {
1048  return "";
1049  }
1050 
1051  for (const auto& Param : Item.parameters())
1052  {
1053  ssParamNames << sep << Param.first;
1054  sep = ";";
1055  }
1056 
1057  ParamNamesStr = ssParamNames.str();
1058  STRING_TO_ALLOCATED_CARRAY(ParamNamesStr,CStr);
1059  return CStr;
1060 
1061  }
1062 
1063 
1064  // =====================================================================
1065  // =====================================================================
1066 
1067 
1068  /**
1069  Returns the value of a given simulator parameter, an empty string if not found.
1070  @param[in] SimID The ID of the simulator
1071  @param[in] ParamName The name of the parameter
1072  @return The value of the parameter, as a string
1073  */
1074  const char* getSimulatorParam(const char* SimID, const char* ParamName)
1075  {
1076  std::string ParamValStr("");
1077  std::string SimIDStr(SimID);
1078  std::string ParamNameStr(ParamName);
1079 
1080  for (const auto& ModelInfos : m_FluidXDesc.model().items())
1081  {
1082  if (ModelInfos->isType(openfluid::ware::WareType::SIMULATOR) &&
1083  ((openfluid::fluidx::SimulatorDescriptor*)ModelInfos)->getID() == SimIDStr)
1084  {
1085  openfluid::ware::WareParams_t Params = ModelInfos->getParameters();
1086  openfluid::ware::WareParams_t::iterator ItParam = Params.find(ParamNameStr);
1087 
1088  if (ItParam != Params.end())
1089  {
1090  ParamValStr = (*ItParam).second;
1091  STRING_TO_ALLOCATED_CARRAY(ParamValStr,CStr);
1092  return CStr;
1093  }
1094  }
1095  }
1096 
1097  STRING_TO_ALLOCATED_CARRAY(ParamValStr,CStr);
1098  return CStr;
1099  }
1100 
1101 
1102  // =====================================================================
1103  // =====================================================================
1104 
1105 
1106  /**
1107  Sets the value of a given simulator parameter.
1108  @param[in] SimID The ID of the simulator
1109  @param[in] ParamName The name of the parameter
1110  @param[in] ParamVal The new value for the parameter
1111  */
1112  void setSimulatorParam(const char* SimID, const char* ParamName, const char* ParamVal)
1113  {
1114  std::string SimIDStr(SimID);
1115  std::string ParamNameStr(ParamName);
1116  std::string ParamValStr(ParamVal);
1117 
1118  for (auto& ModelInfos : m_FluidXDesc.model().items())
1119  {
1120  if (ModelInfos->isType(openfluid::ware::WareType::SIMULATOR) &&
1121  ((openfluid::fluidx::SimulatorDescriptor*)ModelInfos)->getID() == SimIDStr)
1122  {
1123  ModelInfos->setParameter(ParamNameStr,ParamValStr);
1124  }
1125  }
1126  }
1127 
1128 
1129  // =====================================================================
1130  // =====================================================================
1131 
1132 
1133  /**
1134  Removes a given simulator parameter.
1135  @param[in] SimID The ID of the simulator
1136  @param[in] ParamName The name of the parameter
1137  */
1138  void removeSimulatorParam(const char* SimID, const char* ParamName)
1139  {
1140  std::string SimIDStr(SimID);
1141  std::string ParamNameStr(ParamName);
1142 
1143  for (auto& ModelInfos : m_FluidXDesc.model().items())
1144  {
1145  if (ModelInfos->isType(openfluid::ware::WareType::SIMULATOR) &&
1146  ((openfluid::fluidx::SimulatorDescriptor*)ModelInfos)->getID() == SimIDStr)
1147  {
1148  ModelInfos->eraseParameter(ParamNameStr);
1149  }
1150  }
1151  }
1152 
1153 
1154  // =====================================================================
1155  // =====================================================================
1156 
1157 
1158  /**
1159  Returns the list of the parameters names for a given generator, as a semicolon separated list.
1160  @param[in] UnitsClass The name of the spatial units class
1161  @param[in] VarName The name of the generated variable
1162  @return The list of parameters names
1163  */
1164  const char* getGeneratorParamNames(const char* UnitsClass, const char* VarName)
1165  {
1166  std::string VarNameStr(VarName);
1167  std::string UnitsClassStr(UnitsClass);
1168  std::string ParamNamesStr("");
1169  std::ostringstream ssParamNames;
1170  std::string sep = "";
1171 
1172  for (const auto& Item : m_FluidXDesc.model().items())
1173  {
1174  if ( (Item->isType(openfluid::ware::WareType::GENERATOR))
1175  && (((openfluid::fluidx::GeneratorDescriptor*)Item)->getVariableName() == VarNameStr)
1176  && (((openfluid::fluidx::GeneratorDescriptor*)Item)->getUnitsClass() == UnitsClassStr) )
1177  {
1178  for (const auto& Param : Item->parameters())
1179  {
1180  ssParamNames << sep << Param.first;
1181  sep = ";";
1182  }
1183  break;
1184  }
1185  }
1186 
1187  ParamNamesStr = ssParamNames.str();
1188  STRING_TO_ALLOCATED_CARRAY(ParamNamesStr,CStr);
1189  return CStr;
1190 
1191  }
1192 
1193 
1194  // =====================================================================
1195  // =====================================================================
1196 
1197 
1198  /**
1199  Returns the value of a given generator parameter, an empty string if not found.
1200  @param[in] UnitsClass The name of the spatial units class
1201  @param[in] VarName The name of the generated variable
1202  @param[in] ParamName The name of the parameter
1203  @return The value of the parameter, as a string
1204  */
1205  const char* getGeneratorParam(const char* UnitsClass, const char* VarName, const char* ParamName)
1206  {
1207  std::string UnitsClassStr(UnitsClass);
1208  std::string VarNameStr(VarName);
1209  std::string ParamNameStr(ParamName);
1210  std::string ParamValStr("");
1211 
1212  for (const auto& ModelInfos : m_FluidXDesc.model().items())
1213  {
1214  if (ModelInfos->isType(openfluid::ware::WareType::GENERATOR) &&
1215  ((openfluid::fluidx::GeneratorDescriptor*)ModelInfos)->getUnitsClass() == UnitsClassStr &&
1216  ((openfluid::fluidx::GeneratorDescriptor*)ModelInfos)->getVariableName() == VarNameStr)
1217  {
1218  const openfluid::ware::WareParams_t& Params = ModelInfos->getParameters();
1219  openfluid::ware::WareParams_t::const_iterator ItParam = Params.find(ParamNameStr);
1220 
1221  if (ItParam != Params.end())
1222  {
1223  ParamValStr = (*ItParam).second;
1224  STRING_TO_ALLOCATED_CARRAY(ParamValStr,CStr);
1225  return CStr;
1226  }
1227 
1228  }
1229  }
1230 
1231  STRING_TO_ALLOCATED_CARRAY(ParamValStr,CStr);
1232  return CStr;
1233  }
1234 
1235 
1236  // =====================================================================
1237  // =====================================================================
1238 
1239 
1240  /**
1241  Sets the value for a given generator parameter, an empty string if not found.
1242  @param[in] UnitsClass The name of the spatial units class
1243  @param[in] VarName The name of the generated variable
1244  @param[in] ParamName The name of the parameter
1245  @param[in] ParamVal The new value for the parameter
1246  */
1247  void setGeneratorParam(const char* UnitsClass, const char* VarName, const char* ParamName, const char* ParamVal)
1248  {
1249  std::string UnitsClassStr(UnitsClass);
1250  std::string VarNameStr(VarName);
1251  std::string ParamNameStr(ParamName);
1252  std::string ParamValStr(ParamVal);
1253 
1254  for (auto& ItModelInfos : m_FluidXDesc.model().items())
1255  {
1256  if (ItModelInfos->isType(openfluid::ware::WareType::GENERATOR) &&
1257  ((openfluid::fluidx::GeneratorDescriptor*)ItModelInfos)->getUnitsClass() == UnitsClassStr &&
1258  ((openfluid::fluidx::GeneratorDescriptor*)ItModelInfos)->getVariableName() == VarNameStr)
1259  {
1260  ItModelInfos->setParameter(ParamNameStr,ParamValStr);
1261  }
1262  }
1263  }
1264 
1265 
1266  // =====================================================================
1267  // =====================================================================
1268 
1269 
1270  /**
1271  Returns the list of the variables produced by generators on a given spatial units class,
1272  as a semicolon separated list.
1273  @param[in] UnitsClass The spatial units class
1274  @return The list of produced variables
1275  */
1276  const char* getGeneratorsVarNames(const char* UnitsClass)
1277  {
1278  std::string VarNamesStr("");
1279  std::string UnitsClassStr(UnitsClass);
1280  std::ostringstream ssVarNames;
1281  std::string sep = "";
1282 
1283  for (const auto& Item : m_FluidXDesc.model().items())
1284  {
1285  if ( (Item->isType(openfluid::ware::WareType::GENERATOR))
1286  && (((openfluid::fluidx::GeneratorDescriptor*)Item)->getUnitsClass() == UnitsClassStr) )
1287  {
1288  ssVarNames << sep << ((openfluid::fluidx::GeneratorDescriptor*)Item)->getVariableName();
1289  sep = ";";
1290  }
1291  }
1292 
1293  VarNamesStr = ssVarNames.str();
1294  STRING_TO_ALLOCATED_CARRAY(VarNamesStr,CStr);
1295  return CStr;
1296 
1297  }
1298 
1299 
1300  // =====================================================================
1301  // =====================================================================
1302 
1303 
1304  /**
1305  Returns the list of the global parameters for the current model, as a semicolon separated list.
1306  @return The list of parameters names
1307  */
1309  {
1310  std::string ParamNamesStr("");
1311  std::ostringstream ssParamNames;
1312  std::string sep = "";
1313 
1314  for (const auto& Param : m_FluidXDesc.model().getGlobalParameters())
1315  {
1316  ssParamNames << sep << Param.first;
1317  sep = ";";
1318  }
1319 
1320  ParamNamesStr = ssParamNames.str();
1321  STRING_TO_ALLOCATED_CARRAY(ParamNamesStr,CStr);
1322  return CStr;
1323  }
1324 
1325 
1326  // =====================================================================
1327  // =====================================================================
1328 
1329 
1330  /**
1331  Returns the value of a given global parameter for the current model.
1332  @param[in] ParamName The name of the parameter
1333  @return The value of the parameter, as a string
1334  */
1335  const char* getModelGlobalParam(const char* ParamName)
1336  {
1337  std::string ParamNameStr(ParamName);
1338  std::string ParamValStr("");
1339 
1340  openfluid::ware::WareParams_t Params = m_FluidXDesc.model().getGlobalParameters();
1341  openfluid::ware::WareParams_t::const_iterator ItParam = Params.find(ParamNameStr);
1342 
1343  if (ItParam != Params.end())
1344  {
1345  ParamValStr = (*ItParam).second;
1346  STRING_TO_ALLOCATED_CARRAY(ParamValStr,CStr);
1347  return CStr;
1348  }
1349 
1350  STRING_TO_ALLOCATED_CARRAY(ParamValStr,CStr);
1351  return CStr;
1352  }
1353 
1354 
1355  // =====================================================================
1356  // =====================================================================
1357 
1358 
1359  /**
1360  Sets the value of a given global parameter for the current model.
1361  @param[in] ParamName The name of the parameter
1362  @param[in] ParamVal The new value for the parameter
1363  */
1364  void setModelGlobalParam(const char* ParamName, const char* ParamVal)
1365  {
1366  std::string ParamNameStr(ParamName);
1367  std::string ParamValStr(ParamVal);
1368 
1369  m_FluidXDesc.model().setGlobalParameter(ParamNameStr,ParamValStr);
1370  }
1371 
1372 
1373  // =====================================================================
1374  // =====================================================================
1375 
1376 
1377  /**
1378  Removes a given global parameter for the current model.
1379  @param[in] ParamName The name of the parameter
1380  */
1381  void removeModelGlobalParam(const char* ParamName)
1382  {
1383  std::string ParamNameStr(ParamName);
1384 
1385  m_FluidXDesc.model().eraseGlobalParameter(ParamNameStr);
1386  }
1387 
1388 
1389  // =====================================================================
1390  // =====================================================================
1391 
1392 
1393  /**
1394  Returns the IDs list of the observers used in the current model, as a semicolon separated list.
1395  @return The list of IDs
1396  */
1397  const char* getObserversIDs()
1398  {
1399  std::string ObsIDsStr("");
1400  std::ostringstream ssObsIDs;
1401  std::string sep = "";
1402  const openfluid::fluidx::MonitoringDescriptor& MonDesc = m_FluidXDesc.monitoring();
1403 
1404  for (auto& ItItem : MonDesc.items())
1405  {
1406  ssObsIDs << sep << MonDesc.getID(ItItem);
1407  sep = ";";
1408  }
1409 
1410  ObsIDsStr = ssObsIDs.str();
1411  STRING_TO_ALLOCATED_CARRAY(ObsIDsStr,CStr);
1412  return CStr;
1413  }
1414 
1415 
1416  // =====================================================================
1417  // =====================================================================
1418 
1419 
1420  /**
1421  Returns the list of the parameters names for a given observer, as a semicolon separated list.
1422  @param[in] ObsID The ID of the observer
1423  @return The list of parameters names
1424  */
1425  const char* getObserverParamNames(const char* ObsID)
1426  {
1427  std::string ObsIDStr(ObsID);
1428  std::string ParamNamesStr("");
1429  std::ostringstream ssParamNames;
1430  std::string sep = "";
1431  const openfluid::fluidx::MonitoringDescriptor& MonDesc = m_FluidXDesc.monitoring();
1432 
1433  int ItemIndex = MonDesc.findFirstItem(ObsIDStr);
1434  if (ItemIndex < 0)
1435  {
1436  return "";
1437  }
1438 
1439  openfluid::fluidx::ObserverDescriptor Item = MonDesc.itemAt(ItemIndex);
1441  {
1442  return "";
1443  }
1444 
1445  for (const auto& Param : Item.parameters())
1446  {
1447  ssParamNames << sep << Param.first;
1448  sep = ";";
1449  }
1450 
1451  ParamNamesStr = ssParamNames.str();
1452  STRING_TO_ALLOCATED_CARRAY(ParamNamesStr,CStr);
1453  return CStr;
1454 
1455  }
1456 
1457 
1458  // =====================================================================
1459  // =====================================================================
1460 
1461 
1462  /**
1463  Returns the value of a given observer parameter, an empty string if not found.
1464  @param[in] ObsID The ID of the observer
1465  @param[in] ParamName The name of the parameter
1466  @return The value of the parameter, as a string
1467  */
1468  const char* getObserverParam(const char* ObsID, const char* ParamName)
1469  {
1470  std::string ParamValStr("");
1471  std::string ObsIDStr(ObsID);
1472  std::string ParamNameStr(ParamName);
1473 
1474  for (const auto& ObsInfos : m_FluidXDesc.monitoring().items())
1475  {
1476  if (ObsInfos->isType(openfluid::ware::WareType::OBSERVER) &&
1477  ((openfluid::fluidx::ObserverDescriptor*)ObsInfos)->getID() == ObsIDStr)
1478  {
1479  openfluid::ware::WareParams_t Params = ObsInfos->getParameters();
1480  openfluid::ware::WareParams_t::const_iterator ItParam = Params.find(ParamNameStr);
1481 
1482  if (ItParam != Params.end())
1483  {
1484  ParamValStr = (*ItParam).second;
1485  STRING_TO_ALLOCATED_CARRAY(ParamValStr,CStr);
1486  return CStr;
1487  }
1488  }
1489  }
1490 
1491  STRING_TO_ALLOCATED_CARRAY(ParamValStr,CStr);
1492  return CStr;
1493  }
1494 
1495 
1496  // =====================================================================
1497  // =====================================================================
1498 
1499 
1500  /**
1501  Sets the value of a given observer parameter.
1502  @param[in] ObsID The ID of the observer
1503  @param[in] ParamName The name of the parameter
1504  @param[in] ParamVal The new value for the parameter
1505  */
1506  void setObserverParam(const char* ObsID, const char* ParamName, const char* ParamVal)
1507  {
1508  std::string ObsIDStr(ObsID);
1509  std::string ParamNameStr(ParamName);
1510  std::string ParamValStr(ParamVal);
1511 
1512  for (auto& ObsInfos : m_FluidXDesc.monitoring().items())
1513  {
1514  if (ObsInfos->isType(openfluid::ware::WareType::OBSERVER) &&
1515  ((openfluid::fluidx::ObserverDescriptor*)ObsInfos)->getID() == ObsIDStr)
1516  {
1517  ObsInfos->setParameter(ParamNameStr,ParamValStr);
1518  }
1519  }
1520  }
1521 
1522 
1523  // =====================================================================
1524  // =====================================================================
1525 
1526 
1527  /**
1528  Removes a given observer parameter.
1529  @param[in] ObsID The ID of the observer
1530  @param[in] ParamName The name of the parameter
1531  */
1532  void removeObserverParam(const char* ObsID, const char* ParamName)
1533  {
1534  std::string ObsIDStr(ObsID);
1535  std::string ParamNameStr(ParamName);
1536 
1537  for (auto& ObsInfos : m_FluidXDesc.monitoring().items())
1538  {
1539  if (ObsInfos->isType(openfluid::ware::WareType::OBSERVER) &&
1540  ((openfluid::fluidx::ObserverDescriptor*)ObsInfos)->getID() == ObsIDStr)
1541  {
1542  ObsInfos->eraseParameter(ParamNameStr);
1543  }
1544  }
1545  }
1546 
1547 
1548  // =====================================================================
1549  // =====================================================================
1550 
1551 
1552  /**
1553  Returns the spatial units classes names as a list of strings.
1554  @return The list of spatial units classes
1555  */
1557  {
1558  std::map<openfluid::core::UnitsClass_t,unsigned int> UnitsCountByClasses;
1559  UnitsCountByClasses = getUnitsCountByClasses();
1560 
1561  const unsigned int Count = UnitsCountByClasses.size();
1562 
1563  char** Classes = (char**)malloc(Count*sizeof(char*));
1564 
1565  unsigned int i=0;
1566  for (auto& ItUCC : UnitsCountByClasses)
1567  {
1568  Classes[i] = (char*)malloc(ItUCC.first.size()+1);
1569  std::copy(ItUCC.first.begin(), ItUCC.first.end(), Classes[i]);
1570  Classes[i][ItUCC.first.size()] = '\0';
1571  i++;
1572  }
1573 
1574  return Classes;
1575 
1576  }
1577 
1578 
1579  // =====================================================================
1580  // =====================================================================
1581 
1582 
1583  /**
1584  Returns the number of spatial units classes names.
1585  @return The number of spatial units classes
1586  */
1587  unsigned int getUnitsClassesCount()
1588  {
1589  return getUnitsCountByClasses().size();
1590  }
1591 
1592 
1593  // =====================================================================
1594  // =====================================================================
1595 
1596 
1597  /**
1598  Returns the spatial units IDs for a given spatial units class, as a list of integers.
1599  @return The list of spatial units IDs
1600  */
1601  int* getUnitsIDs(const char* UnitsClass)
1602  {
1603  int* IDs = NULL;
1604 
1605  if (m_FluidXDesc.spatialDomain().isClassNameExists(UnitsClass))
1606  {
1607  const auto IDsOfClass = m_FluidXDesc.spatialDomain().getIDsOfClass(UnitsClass);
1608 
1609  IDs = (int*)malloc(IDsOfClass.size()*sizeof(int));
1610  unsigned int i=0;
1611  for (const auto& ID : IDsOfClass)
1612  {
1613  IDs[i] = ID;
1614  i++;
1615  }
1616 
1617  }
1618 
1619  return IDs;
1620  }
1621 
1622 
1623  // =====================================================================
1624  // =====================================================================
1625 
1626 
1627  /**
1628  Returns the number of spatial units IDs for a given spatial units class.
1629  @return The number of spatial units IDs
1630  */
1631  unsigned int getUnitsIDsCount(const char* UnitsClass)
1632  {
1633  if (m_FluidXDesc.spatialDomain().isClassNameExists(UnitsClass))
1634  {
1635  return m_FluidXDesc.spatialDomain().getUnitsCount(UnitsClass);
1636  }
1637 
1638  return 0;
1639  }
1640 
1641 
1642  // =====================================================================
1643  // =====================================================================
1644 
1645 
1646  /**
1647  Returns the list of the attributes names for a given spatial units class, as a semicolon separated list.
1648  @param[in] UnitsClass The units class
1649  @return The list of attributes names
1650  */
1651  const char* getAttributesNames(const char* UnitsClass)
1652  {
1653  std::string UnitClassStr(UnitsClass);
1654  std::string AttrNamesStr("");
1655  std::ostringstream ssAttrNames;
1656  std::string sep = "";
1657 
1658  for (const auto& Name : m_FluidXDesc.spatialDomain().getAttributesNames(UnitsClass))
1659  {
1660  ssAttrNames << sep << Name;
1661  sep = ";";
1662  }
1663 
1664  AttrNamesStr = ssAttrNames.str();
1665  STRING_TO_ALLOCATED_CARRAY(AttrNamesStr,CStr);
1666  return CStr;
1667  }
1668 
1669 
1670  // =====================================================================
1671  // =====================================================================
1672 
1673 
1674  /**
1675  Creates an attribute for all spatial units of a given class, with a default value for this attribute.
1676  @param[in] UnitsClass The spatial units class
1677  @param[in] AttrName The name of the attribute
1678  @param[in] AttrVal The default value for this attribute
1679  */
1680  void createAttribute(const char* UnitsClass, const char* AttrName, const char* AttrVal)
1681  {
1682  std::string UnitsClassStr(UnitsClass);
1683  std::string AttrNameStr(AttrName);
1684  std::string AttrValStr(AttrVal);
1685 
1686  if (m_FluidXDesc.spatialDomain().isClassNameExists(UnitsClassStr))
1687  {
1688  m_FluidXDesc.spatialDomain().addAttribute(UnitsClass,AttrNameStr,AttrValStr);
1689  }
1690  }
1691 
1692 
1693  // =====================================================================
1694  // =====================================================================
1695 
1696 
1697  /**
1698  Returns the value of an attribute of a spatial unit.
1699  @param[in] UnitsClass The spatial units class
1700  @param[in] UnitID The spatial unit ID
1701  @param[in] AttrName The name of the attribute
1702  @return The value of the attribute, as a string
1703  */
1704  const char* getAttribute(const char* UnitsClass, int UnitID, const char* AttrName)
1705  {
1706  std::string UnitClassStr(UnitsClass);
1707  std::string AttrNameStr(AttrName);
1708  std::string AttrValStr("");
1709 
1710  try
1711  {
1712  AttrValStr = m_FluidXDesc.spatialDomain().getAttribute(UnitClassStr,UnitID,AttrNameStr);
1713  }
1715  {
1716  // do nothing
1717  }
1718 
1719  STRING_TO_ALLOCATED_CARRAY(AttrValStr,CStr);
1720  return CStr;
1721  }
1722 
1723 
1724  // =====================================================================
1725  // =====================================================================
1726 
1727 
1728  /**
1729  Sets an attribute value for a given spatial unit.
1730  @param[in] UnitsClass The spatial units class
1731  @param[in] UnitID The spatial unit ID
1732  @param[in] AttrName The name of the attribute
1733  @param[in] AttrVal The new value for this attribute
1734  */
1735  void setAttribute(const char* UnitsClass, int UnitID, const char* AttrName, const char* AttrVal)
1736  {
1737  std::string UnitClassStr(UnitsClass);
1738  std::string AttrNameStr(AttrName);
1739  std::string AttrValStr(AttrVal);
1740 
1741  try
1742  {
1743  m_FluidXDesc.spatialDomain().setAttribute(UnitClassStr,UnitID,AttrNameStr,AttrValStr);
1744  }
1746  {
1747  // do nothing
1748  }
1749  }
1750 
1751 
1752  // =====================================================================
1753  // =====================================================================
1754 
1755 
1756  /**
1757  Removes an attribute for all spatial units of a given class.
1758  @param[in] UnitsClass The spatial units class
1759  @param[in] AttrName The name of the attribute
1760  */
1761  void removeAttribute(const char* UnitsClass, const char* AttrName)
1762  {
1763  std::string UnitClassStr(UnitsClass);
1764  std::string AttrNameStr(AttrName);
1765 
1766  try
1767  {
1768  m_FluidXDesc.spatialDomain().deleteAttribute(UnitClassStr,AttrNameStr);
1769  }
1771  {
1772  // do nothing
1773  }
1774  }
1775 
1776 
1777  // =====================================================================
1778  // =====================================================================
1779 
1780 
1781  /**
1782  Adds simulation variable to be automatically exported using CSV format.
1783  @param[in] BindingName The name used as an identifier in output files names
1784  @param[in] UnitsClass The name of the spatial units class
1785  @param[in] UnitsIDs The semicolon separated list of spatial units IDs, can be '*' for all spatial units
1786  @param[in] VarName The name of the variable
1787  @param[in] Precision The floating precision to use for floating point representation,
1788  default precision is used if this parameter is less or equal to 0
1789  */
1790  void addVariablesExportAsCSV(const char* BindingName,
1791  const char* UnitsClass, const char* UnitsIDs,
1792  const char* VarName, int Precision)
1793  {
1794  std::string BindingNameStr(BindingName);
1795  std::string UnitsClassStr(UnitsClass);
1796  std::string UnitsIDsStr(UnitsIDs);
1797  std::string VarNameStr(VarName);
1798  openfluid::fluidx::MonitoringDescriptor& MonDesc = m_FluidXDesc.monitoring();
1799 
1800  // 1. add CSV observer if not present
1801 
1802  if (MonDesc.findFirstItem("export.vars.files.csv") < 0)
1803  {
1804  MonDesc.appendItem(new openfluid::fluidx::ObserverDescriptor("export.vars.files.csv"));
1805  }
1806 
1807  openfluid::fluidx::ObserverDescriptor& ObsDesc = MonDesc.itemAt(MonDesc.findFirstItem("export.vars.files.csv"));
1808 
1809  // 2. add format for binding
1810  ObsDesc.setParameter("format."+BindingNameStr+".header",openfluid::core::StringValue("colnames-as-data"));
1811  ObsDesc.setParameter("format."+BindingNameStr+".date",openfluid::core::StringValue("%Y%m%d-%H%M%S"));
1812  ObsDesc.setParameter("format."+BindingNameStr+".colsep",openfluid::core::StringValue(" "));
1813  if (Precision > 0)
1814  {
1815  std::ostringstream ssPrec;
1816  ssPrec << Precision;
1817  std::string PrecStr(ssPrec.str());
1818  ObsDesc.setParameter("format."+BindingNameStr+".precision",openfluid::core::StringValue(PrecStr));
1819  }
1820 
1821  // 3. add binding output set
1822  ObsDesc.setParameter("set."+BindingNameStr+UnitsClassStr+".unitsclass",
1823  openfluid::core::StringValue(UnitsClassStr));
1824  ObsDesc.setParameter("set."+BindingNameStr+UnitsClassStr+".unitsIDs",
1825  openfluid::core::StringValue(UnitsIDsStr));
1826  ObsDesc.setParameter("set."+BindingNameStr+UnitsClassStr+".vars",
1827  openfluid::core::StringValue(VarNameStr));
1828  ObsDesc.setParameter("set."+BindingNameStr+UnitsClassStr+".format",
1829  openfluid::core::StringValue(BindingNameStr));
1830  }
1831 
1832 };
1833 
1834 
1835 } } // namespaces
1836 
1837 
1838 #endif /* __OPENFLUID_UTILS_BINDING_HPP__ */
#define STRING_TO_ALLOCATED_CARRAY(str, carray)
Definition: Binding.hpp:77
#define INIT_OPENFLUID_APPLICATION()
Definition: Init.hpp:55
Definition: ApplicationException.hpp:51
static ExceptionContext computeContext(const std::string &AppName)
Definition: ApplicationException.hpp:76
static void resetExtraSimulatorsDirs()
static std::vector< std::string > getObserversDirs()
static void addExtraSimulatorsDirs(const std::string &Paths)
static std::vector< std::string > getSimulatorsDirs()
static std::vector< std::string > getExtraObserversDirs()
Definition: Environment.hpp:391
static void addExtraObserversDirs(const std::string &Paths)
static void resetExtraObserversDirs()
static std::vector< std::string > getExtraSimulatorsDirs()
Definition: Environment.hpp:348
Definition: Exception.hpp:53
const char * what() const
Definition: Exception.hpp:87
Definition: FrameworkException.hpp:51
Definition: IOListener.hpp:53
Class for management of date and time information.
Definition: DateTime.hpp:88
std::string getAsISOString() const
bool setFromISOString(const std::string &DateTimeStr)
std::string getAsString(const std::string &Format) const
Definition: StringValue.hpp:83
Definition: CoupledModelDescriptor.hpp:53
openfluid::ware::WareID_t getID(const ModelItemDescriptor *Item) const
Definition: FluidXDescriptor.hpp:60
openfluid::fluidx::SpatialDomainDescriptor & spatialDomain()
Definition: FluidXDescriptor.hpp:91
openfluid::fluidx::MonitoringDescriptor & monitoring()
Definition: FluidXDescriptor.hpp:121
openfluid::fluidx::CoupledModelDescriptor & model()
Definition: FluidXDescriptor.hpp:81
openfluid::fluidx::RunConfigurationDescriptor & runConfiguration()
Definition: FluidXDescriptor.hpp:101
Definition: FluidXIO.hpp:55
FluidXDescriptor loadFromDirectory(const std::string &DirPath)
void writeToManyFiles(const FluidXDescriptor &Desc, const std::string &DirPath) const
Definition: GeneratorDescriptor.hpp:56
GeneratorMethod getGeneratorMethod() const
openfluid::core::UnitsClass_t getUnitsClass() const
openfluid::core::VariableName_t getVariableName() const
Definition: ModelItemDescriptor.hpp:52
Definition: MonitoringDescriptor.hpp:53
openfluid::ware::WareID_t getID(const ObserverDescriptor *Item) const
Definition: ObserverDescriptor.hpp:51
openfluid::core::DateTime getEndDate() const
Definition: RunConfigurationDescriptor.hpp:91
void setEndDate(const openfluid::core::DateTime EndDate)
Definition: RunConfigurationDescriptor.hpp:96
openfluid::core::DateTime getBeginDate() const
Definition: RunConfigurationDescriptor.hpp:81
void setDeltaT(const int DeltaT)
Definition: RunConfigurationDescriptor.hpp:106
int getDeltaT() const
Definition: RunConfigurationDescriptor.hpp:101
void setBeginDate(const openfluid::core::DateTime BeginDate)
Definition: RunConfigurationDescriptor.hpp:86
Definition: SimulatorDescriptor.hpp:52
bool isClassNameExists(const openfluid::core::UnitsClass_t &ClassName) const
std::string getAttribute(const openfluid::core::UnitsClass_t &ClassName, const openfluid::core::UnitID_t &ID, const openfluid::core::AttributeName_t &AttrName) const
SpatialUnitsByIDByClass_t & spatialUnits()
Definition: SpatialDomainDescriptor.hpp:101
std::set< std::string > getAttributesNames(const openfluid::core::UnitsClass_t &ClassName) const
void addAttribute(const openfluid::core::UnitsClass_t &ClassName, const std::string &AttrName, const std::string &DefaultValue, bool Check=true)
void setAttribute(const openfluid::core::UnitsClass_t &ClassName, const openfluid::core::UnitID_t &ID, const openfluid::core::AttributeName_t &AttrName, const std::string &AttrValue)
void deleteAttribute(const openfluid::core::UnitsClass_t &ClassName, const std::string &AttrName)
std::set< int > getIDsOfClass(const openfluid::core::UnitsClass_t &ClassName) const
openfluid::ware::WareParams_t & parameters()
openfluid::ware::WareParams_t getParameters() const
bool isType(openfluid::ware::WareType MIType) const
void setParameter(const openfluid::ware::WareParamKey_t &Key, const openfluid::ware::WareParamValue_t &Value)
void eraseParameter(const openfluid::ware::WareParamKey_t &Key)
int findFirstItem(const openfluid::ware::WareID_t &ID) const
Definition: WareSetDescriptor.hpp:321
T & itemAt(unsigned int Index) const
Definition: WareSetDescriptor.hpp:198
openfluid::ware::WareParams_t getGlobalParameters() const
Definition: WareSetDescriptor.hpp:136
void eraseGlobalParameter(const openfluid::ware::WareParamKey_t &Key)
Definition: WareSetDescriptor.hpp:146
void setGlobalParameter(const openfluid::ware::WareParamKey_t &Key, const openfluid::ware::WareParamValue_t &Value)
Definition: WareSetDescriptor.hpp:110
void appendItem(T *Item)
Definition: WareSetDescriptor.hpp:156
SetDescription_t & items()
Definition: WareSetDescriptor.hpp:90
Definition: Engine.hpp:79
static void buildMonitoringInstanceFromDescriptor(const openfluid::fluidx::MonitoringDescriptor &MonDesc, MonitoringInstance &MonInstance)
static void buildSimulationBlobFromDescriptors(const openfluid::fluidx::FluidXDescriptor &FluidXDesc, SimulationBlob &SimBlob)
static void buildModelInstanceFromDescriptor(const openfluid::fluidx::CoupledModelDescriptor &ModelDesc, ModelInstance &MInstance)
Definition: ModelInstance.hpp:66
Definition: MonitoringInstance.hpp:59
Definition: SimulationBlob.hpp:54
Definition: FilesystemPath.hpp:62
bool removeFile(const std::string &Path="", std::error_code &ErrorCode=DefaultErrorCode) const
static std::vector< std::string > findFilesByExtension(const std::string &Path, const std::string &Ext, bool WithPath=false, bool ExtIncludeDot=false)
static bool copyDirectory(const std::string &SrcPath, const std::string &DestPath, bool WithBaseDir=false, bool RemoveExisting=false)
Definition: BindingAbstractOutErr.hpp:50
virtual void printfOut(const char *fmt,...) const =0
Definition: BindingVerboseMachineListener.hpp:51
Class for easier binding with other programming languages.
Definition: Binding.hpp:124
static const char * getVersion()
Definition: Binding.hpp:251
const char * getModelGlobalParam(const char *ParamName)
Definition: Binding.hpp:1335
const char * getSimulationOutputDir()
Definition: Binding.hpp:893
static void resetExtraSimulatorsPaths()
Definition: Binding.hpp:293
static Binding * openDataset(const char *Path)
Definition: Binding.hpp:514
void removeModelGlobalParam(const char *ParamName)
Definition: Binding.hpp:1381
void setGeneratorParam(const char *UnitsClass, const char *VarName, const char *ParamName, const char *ParamVal)
Definition: Binding.hpp:1247
const char * getSimulatorParam(const char *SimID, const char *ParamName)
Definition: Binding.hpp:1074
const char * getPeriodBeginDate()
Definition: Binding.hpp:937
static unsigned int getExtraSimulatorsPathsCount()
Definition: Binding.hpp:348
const char * getPeriodEndDate()
Definition: Binding.hpp:955
const char * getAttributesNames(const char *UnitsClass)
Definition: Binding.hpp:1651
const char * getAttribute(const char *UnitsClass, int UnitID, const char *AttrName)
Definition: Binding.hpp:1704
static void init()
Definition: Binding.hpp:199
static unsigned int getSimulatorsPathsCount()
Definition: Binding.hpp:307
static void addExtraSimulatorsPaths(const char *Paths)
Definition: Binding.hpp:280
void setDefaultDeltaT(int DeltaT)
Definition: Binding.hpp:922
void setAttribute(const char *UnitsClass, int UnitID, const char *AttrName, const char *AttrVal)
Definition: Binding.hpp:1735
static void setCurrentOutputDir(const char *Path)
Definition: Binding.hpp:499
unsigned int getUnitsClassesCount()
Definition: Binding.hpp:1587
const char * getGeneratorParamNames(const char *UnitsClass, const char *VarName)
Definition: Binding.hpp:1164
static Binding * make()
Definition: Binding.hpp:224
const char * getObserverParamNames(const char *ObsID)
Definition: Binding.hpp:1425
const char * getGeneratorParam(const char *UnitsClass, const char *VarName, const char *ParamName)
Definition: Binding.hpp:1205
static void resetExtraObserversPaths()
Definition: Binding.hpp:403
const char * getSimulatorParamNames(const char *SimID)
Definition: Binding.hpp:1031
unsigned int getUnitsIDsCount(const char *UnitsClass)
Definition: Binding.hpp:1631
void removeObserverParam(const char *ObsID, const char *ParamName)
Definition: Binding.hpp:1532
char ** getUnitsClasses()
Definition: Binding.hpp:1556
const char * getObserversIDs()
Definition: Binding.hpp:1397
void setPeriod(const char *BeginDate, const char *EndDate)
Definition: Binding.hpp:974
static char ** getSimulatorsPaths()
Definition: Binding.hpp:321
const char * getModelGlobalParamNames()
Definition: Binding.hpp:1308
void setModelGlobalParam(const char *ParamName, const char *ParamVal)
Definition: Binding.hpp:1364
void removeAttribute(const char *UnitsClass, const char *AttrName)
Definition: Binding.hpp:1761
static const char * getLastError()
Definition: Binding.hpp:265
static void addExtraObserversPaths(const char *Paths)
Definition: Binding.hpp:390
int getDefaultDeltaT()
Definition: Binding.hpp:908
static Binding * openProject(const char *Path)
Definition: Binding.hpp:572
static char ** getObserversPaths()
Definition: Binding.hpp:431
void setSimulatorParam(const char *SimID, const char *ParamName, const char *ParamVal)
Definition: Binding.hpp:1112
int writeDataset(const char *Path, bool WithOriginData=false)
Definition: Binding.hpp:634
void createAttribute(const char *UnitsClass, const char *AttrName, const char *AttrVal)
Definition: Binding.hpp:1680
void printSimulationInfo()
Definition: Binding.hpp:816
const char * getObserverParam(const char *ObsID, const char *ParamName)
Definition: Binding.hpp:1468
static void destroy(Binding *B)
Definition: Binding.hpp:238
const char * getSimulatorsIDs()
Definition: Binding.hpp:1000
static char ** getExtraSimulatorsPaths()
Definition: Binding.hpp:362
static unsigned int getObserversPathsCount()
Definition: Binding.hpp:417
unsigned short int runSimulation(int IsVerbose=false)
Definition: Binding.hpp:686
const char * getGeneratorsVarNames(const char *UnitsClass)
Definition: Binding.hpp:1276
static unsigned int getExtraObserversPathsCount()
Definition: Binding.hpp:458
void removeSimulatorParam(const char *SimID, const char *ParamName)
Definition: Binding.hpp:1138
void setObserverParam(const char *ObsID, const char *ParamName, const char *ParamVal)
Definition: Binding.hpp:1506
static char ** getExtraObserversPaths()
Definition: Binding.hpp:472
void addVariablesExportAsCSV(const char *BindingName, const char *UnitsClass, const char *UnitsIDs, const char *VarName, int Precision)
Definition: Binding.hpp:1790
int * getUnitsIDs(const char *UnitsClass)
Definition: Binding.hpp:1601
FilesystemPath Path
Definition: FilesystemPath.hpp:308
std::map< WareParamKey_t, WareParamValue_t > WareParams_t
Definition: TypeDefs.hpp:146
Definition: ApplicationException.hpp:47