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