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