gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
onelabUtils.cpp
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 
6 #include "GmshConfig.h"
7 
8 #if defined(HAVE_ONELAB)
9 
10 #include "GmshDefines.h"
11 #include "GModel.h"
12 #include "Context.h"
13 #include "Options.h"
14 #include "OS.h"
15 #include "OpenFile.h"
16 #include "CreateFile.h"
17 #include "StringUtils.h"
18 #include "gmshLocalNetworkClient.h"
19 #include "onelabUtils.h"
20 
21 #if defined(HAVE_POST)
22 #include "PView.h"
23 #include "PViewData.h"
24 #include "PViewOptions.h"
25 #endif
26 
27 #if defined(HAVE_FLTK)
28 #include "FlGui.h"
29 #include "onelabGroup.h"
30 #include "drawContext.h"
31 #endif
32 
33 namespace onelabUtils {
34 
35  // get command line arguments for the client if "UseCommandLine" is set for
36  // this client
37  std::vector<std::string> getCommandLine(onelab::client *c)
38  {
39  std::vector<std::string> args;
40  std::string name(c->getName());
41  std::vector<onelab::number> n;
42  c->get(n, name + "/Use command line");
43  if(n.size() && n[0].getValue()) {
44  std::vector<onelab::string> ps;
45  c->get(ps, name + "/Action");
46  std::string action = (ps.empty() ? "" : ps[0].getValue());
47  c->get(ps, name + "/Model name");
48  std::string modelName = (ps.empty() ? "" : ps[0].getValue());
49  c->get(ps, name + "/9CheckCommand");
50  std::string checkCommand = (ps.empty() ? "" : ps[0].getValue());
51  c->get(ps, name + "/9ComputeCommand");
52  std::string computeCommand = (ps.empty() ? "" : ps[0].getValue());
53  if(modelName.size()) args.push_back(" \"" + modelName + "\"");
54  if(action == "check")
55  args.push_back(" " + checkCommand);
56  else if(action == "compute")
57  args.push_back(" " + computeCommand);
58  // Propagate -setnumber/-setnumber gmsh option to the client. (Is this a
59  // good idea?)
60  std::ostringstream sstream;
61  sstream.precision(16);
62  std::map<std::string, std::vector<double> > cln(
64  for(auto it =
65  cln.begin();
66  it != cln.end(); it++) {
67  if(it->second.size() == 1) {
68  sstream << " -setnumber " << it->first << " " << it->second[0];
69  }
70  else {
71  sstream << " -setlistofnumbers " << it->first;
72  for(std::size_t i = 0; i < it->second.size(); i++)
73  sstream << " " << it->second[i];
74  }
75  }
76  std::map<std::string, std::string> cls(Msg::GetCommandLineStrings());
77  for(auto it = cls.begin();
78  it != cls.end(); it++)
79  sstream << " -setstring " << it->first << " " << it->second;
80  args.push_back(sstream.str());
81  }
82  return args;
83  }
84 
85  std::string getMshFileName(onelab::client *c)
86  {
87  std::string name;
88  std::vector<onelab::string> ps;
89  c->get(ps, "Gmsh/MshFileName");
90  if(ps.size()) {
91  name = ps[0].getValue();
92  }
93  else {
94  name = CTX::instance()->outputFileName;
95  if(name.empty()) {
96  if(CTX::instance()->mesh.fileFormat == FORMAT_AUTO)
98  else
100  }
101  onelab::string o("Gmsh/MshFileName", name, "Mesh name");
102  o.setKind("file");
103  o.setAttribute("Closed", "1");
104  if(!CTX::instance()->showModuleMenu)
105  o.setVisible(false);
106  c->set(o);
107  }
108  // we could keep track of mesh file name in "Output files" so we could
109  // archive the mesh automatically:
110  /*
111  onelab::string copy("Gmsh/9Output files", name, "Mesh name");
112  copy.setKind("file");
113  copy.setVisible(false);
114  c->set(copy);
115  */
116  return name;
117  }
118 
120  {
121  std::string geo = GModel::current()->getFileName();
122  std::vector<onelab::number> n;
123  c->get(n, c->getName() + "/Guess model name");
124  if(n.size() && n[0].getValue()) {
125  std::vector<onelab::string> ps;
126  c->get(ps, c->getName() + "/Model name");
127  if(ps.empty()) {
128  std::vector<std::string> split = SplitFileName(geo);
129  std::string ext = "";
130  onelab::server::instance()->get(ps, c->getName() + "/File extension");
131  if(ps.size()) ext = ps[0].getValue();
132  std::string name(split[0] + split[1] + ext);
133  onelab::string o(c->getName() + "/Model name", name);
134  o.setKind("file");
135  o.setAttribute("Persistent", "1");
136  c->set(o);
137  geo += std::string(" - ") + name;
138  }
139  else {
140  geo += std::string(" - ") + ps[0].getValue();
141  }
142  }
143  Msg::SetWindowTitle(geo);
144  }
145 
146  void initializeLoop(const std::string &level)
147  {
148  bool changed = false;
149  std::vector<onelab::number> numbers;
150  onelab::server::instance()->get(numbers);
151  for(std::size_t i = 0; i < numbers.size(); i++) {
152  if(numbers[i].getAttribute("Loop") == level) {
153  if(numbers[i].getChoices().size() > 1) {
154  numbers[i].setIndex(0);
155  numbers[i].setValue(numbers[i].getChoices()[0]);
156  onelab::server::instance()->set(numbers[i]);
157  changed = true;
158  }
159  else if(numbers[i].getStep() > 0) {
160  if(numbers[i].getMin() != -onelab::parameter::maxNumber()) {
161  numbers[i].setValue(numbers[i].getMin());
162  numbers[i].setIndex(0); // indicates we are in a loop
163  std::vector<double> choices;
164  numbers[0].setChoices(choices);
165  onelab::server::instance()->set(numbers[i]);
166  changed = true;
167  }
168  }
169  else if(numbers[i].getStep() < 0) {
170  if(numbers[i].getMax() != onelab::parameter::maxNumber()) {
171  numbers[i].setIndex(0); // indicates we are in a loop
172  std::vector<double> choices;
173  numbers[0].setChoices(choices);
174  numbers[i].setValue(numbers[i].getMax());
175  onelab::server::instance()->set(numbers[i]);
176  changed = true;
177  }
178  }
179  }
180  }
181 
182  // force this to make sure that we remesh, even if a mesh exists on disk
183  if(changed) setFirstComputationFlag(false);
184  }
185 
186  bool incrementLoop(const std::string &level)
187  {
188  const double eps = 1.e-15; // for roundoff
189  // called at the end of the do{...} while(incrementLoops);
190  bool recompute = false, loop = false;
191  std::vector<onelab::number> numbers;
192  onelab::server::instance()->get(numbers);
193  for(std::size_t i = 0; i < numbers.size(); i++) {
194  if(numbers[i].getAttribute("Loop") == level) {
195  loop = true;
196 
197  if(numbers[i].getChoices().size() > 1) {
198  int j = numbers[i].getIndex() + 1;
199  if((j >= 0) && (j < (int)numbers[i].getChoices().size())) {
200  numbers[i].setValue(numbers[i].getChoices()[j]);
201  numbers[i].setIndex(j);
202  onelab::server::instance()->set(numbers[i]);
203  Msg::Info("Recomputing with %dth choice %s=%g", j,
204  numbers[i].getName().c_str(), numbers[i].getValue());
205  recompute = true;
206  }
207  }
208  else if(numbers[i].getStep() > 0) {
209  int j = numbers[i].getIndex() + 1;
210  double val = numbers[i].getValue() + numbers[i].getStep();
211  if(numbers[i].getMax() != onelab::parameter::maxNumber() &&
212  val <= numbers[i].getMax() * (1 + eps)) {
213  numbers[i].setValue(val);
214  numbers[i].setIndex(j);
215  onelab::server::instance()->set(numbers[i]);
216  Msg::Info("Recomputing with new step %s=%g",
217  numbers[i].getName().c_str(), numbers[i].getValue());
218  recompute = true;
219  }
220  else
221  numbers[i].setIndex(numbers[i].getMax()); // FIXME makes sense?
222  }
223  else if(numbers[i].getStep() < 0) {
224  int j = numbers[i].getIndex() + 1;
225  double val = numbers[i].getValue() + numbers[i].getStep();
226  if(numbers[i].getMin() != -onelab::parameter::maxNumber() &&
227  val >= numbers[i].getMin() * (1 - eps)) {
228  numbers[i].setValue(val);
229  numbers[i].setIndex(j);
230  onelab::server::instance()->set(numbers[i]);
231  Msg::Info("Recomputing with new step %s=%g",
232  numbers[i].getName().c_str(), numbers[i].getValue());
233  recompute = true;
234  }
235  else
236  numbers[i].setIndex(numbers[i].getMin()); // FIXME makes sense?
237  }
238  }
239  }
240 
241  if(loop && !recompute) // end of this loop level
242  initializeLoop(level);
243 
244  return recompute;
245  }
246 
247  std::vector<double> getRange(onelab::number &p)
248  {
249  const double eps = 1.e-15; // for roundoff
250  std::vector<double> v;
251  if(p.getChoices().size()) {
252  v = p.getChoices();
253  }
254  else if(p.getMin() != -onelab::parameter::maxNumber() &&
256  if(p.getStep() > 0) {
257  for(double d = p.getMin(); d <= p.getMax() * (1 + eps);
258  d += p.getStep())
259  v.push_back(d);
260  }
261  else if(p.getStep() < 0) {
262  for(double d = p.getMin(); d <= p.getMax() * (1 + eps);
263  d -= p.getStep())
264  v.push_back(d);
265  }
266  }
267  return v;
268  }
269 
270  bool updateGraph(const std::string &graphNum)
271  {
272  bool changed = false;
273 #if defined(HAVE_POST)
274  PView *view = nullptr;
275 
276  for(std::size_t i = 0; i < PView::list.size(); i++) {
277  if(PView::list[i]->getData()->getFileName() == "ONELAB" + graphNum) {
278  view = PView::list[i];
279  break;
280  }
281  }
282 
283  int num = atoi(graphNum.c_str());
284  std::vector<double> x, y;
285  std::string xName, yName;
286  int graphType = 3;
287  std::vector<onelab::number> numbers;
288  onelab::server::instance()->get(numbers);
289  for(std::size_t i = 0; i < numbers.size(); i++) {
290  std::string v = numbers[i].getAttribute("Graph");
291  v.resize(36, '0');
292  if(v[2 * num] != '0') {
293  x = getRange(numbers[i]);
294  xName = numbers[i].getShortName();
295  }
296  if(v[2 * num + 1] != '0') {
297  y = getRange(numbers[i]);
298  yName = numbers[i].getShortName();
299  char t = v[2 * num + 1];
300  graphType =
301  (t == '1') ? 1 : (t == '2') ? 2 : (t == '3') ? 3 : (t == '4') ? 4 : 3;
302  }
303  }
304  if(x.empty()) {
305  xName.clear();
306  for(std::size_t i = 0; i < y.size(); i++) x.push_back(i);
307  }
308  if(x.size() && y.size()) {
309  if(x.size() != y.size())
310  Msg::Info("X-Y data series have different length (%d != %d)",
311  (int)x.size(), (int)y.size());
312  if(view) {
313  view->getData()->setXY(x, y);
314  view->getData()->setName(yName);
315  view->getOptions()->axesLabel[0] = xName;
316  view->setChanged(true);
317  }
318  else {
319  view = new PView(xName, yName, x, y);
320  view->getData()->setFileName("ONELAB" + graphNum);
321  view->getOptions()->intervalsType = graphType;
322  view->getOptions()->autoPosition = num / 2 + 2;
323  }
324  changed = true;
325  }
326  else if(view) {
327  delete view;
328  changed = true;
329  }
330 #endif
331  return changed;
332  }
333 
334  static bool _firstComputation = true;
335  void setFirstComputationFlag(bool val) { _firstComputation = val; }
336  bool getFirstComputationFlag() { return _firstComputation; }
337  bool runGmshClient(const std::string &action, int meshAuto)
338  {
339  bool redraw = false;
340 
341  auto it = onelab::server::instance()->findClient("Gmsh");
342  if(it == onelab::server::instance()->lastClient()) return redraw;
343 
344  // do nothing in case of a metamodel
345  std::vector<onelab::number> pn;
346  onelab::server::instance()->get(pn, "IsPyMetamodel");
347  if(pn.size() && pn[0].getValue()) return redraw;
348  onelab::server::instance()->get(pn, "IsMetamodel");
349  if(pn.size() && pn[0].getValue()) return redraw;
350 
351  // do nothing if there is no file name associated with the model (e.g. when
352  // Gmsh is run interactively through the API and no model file is opened)
353  if(GModel::current()->getFileName().empty()) return redraw;
354 
355  onelab::client *c = *it;
356  std::string mshFileName = onelabUtils::getMshFileName(c);
357 
358  int changed = onelab::server::instance()->getChanged("Gmsh");
359  // if = 0: do nothing
360  // = 1: only save mesh (e.g. if physiscals changed)
361  // = 2: mesh and save mesh (e.g. if char length changed)
362  // > 2: reload geometry, mesh and save mesh (other things have changed)
363 
364  if(meshAuto < 0) { // the geometry creates the mesh
365  meshAuto = 0;
366  if(changed) changed = 3;
367  }
368 
369  Msg::SetOnelabAction(action);
370 
371  if(action == "initialize") {
372  // nothing to do
373  }
374  else if(action == "reset") {
376  // nothing more to do: "check" will be called right afterwards
377  }
378  else if(action == "check_always") {
379  redraw = true;
380  OpenProject(GModel::current()->getFileName());
382  }
383  else if(action == "check") {
384  if(changed > 2) {
385  redraw = true;
386  OpenProject(GModel::current()->getFileName());
388  }
389  }
390  else if(action == "compute") {
391  if(changed) {
392  redraw = true;
393  if(changed > 2) {
394  OpenProject(GModel::current()->getFileName());
395  }
396  if(getFirstComputationFlag() && !StatFile(mshFileName) &&
397  meshAuto != 2) {
398  Msg::Info("Skipping mesh generation: assuming '%s' is up-to-date "
399  "(use Solver.AutoMesh=2 to force mesh generation)",
400  mshFileName.c_str());
401  }
402  else if(!GModel::current()->empty() && meshAuto) {
403  if(changed > 1 || StatFile(mshFileName) ||
404  (!StatFile(mshFileName) && GModel::current()->getMeshStatus() <
405  GModel::current()->getDim())) {
407  GModel::current()->mesh(3);
408  }
409  CreateOutputFile(mshFileName, CTX::instance()->mesh.fileFormat);
410  }
411  }
412  else if(StatFile(mshFileName)) {
413  // mesh+save if the mesh file does not exist
414  if(meshAuto) {
415  redraw = true;
416  if(changed > 1 ||
417  GModel::current()->getMeshStatus() < GModel::current()->getDim()) {
419  GModel::current()->mesh(3);
420  }
421  CreateOutputFile(mshFileName, CTX::instance()->mesh.fileFormat);
422  }
423  }
425  onelab::server::instance()->setChanged(0, "Gmsh");
426  }
427 
429 
430  return redraw;
431  }
432 
433  void runClient(const std::string &name, const std::string &command)
434  {
435  if(name.size()) {
436  // try to run as a subclient of Gmsh; or if not as a new client
438  dynamic_cast<onelab::remoteNetworkClient *>(Msg::GetOnelabClient());
439  if(c) {
440  c->runSubClient(name, command);
441  }
442  else {
443  gmshLocalNetworkClient client(name, command, "", true);
444  client.run();
445  }
446  }
447  else {
448  // try to run a client that might have been selected previously, e.g. by
449  // opening a file with known client extension (like ".pro")
451  std::string name, exe, host;
452  if(num == -1) {
453  // no client to run
454  return;
455  }
456  else if(num == -2) {
457  // just run local Gmsh client
458  }
459  else if(num >= 0) {
460  // run local Gmsh client + solver num
461  name = opt_solver_name(num, GMSH_GET, "");
462  exe = opt_solver_executable(num, GMSH_GET, "");
463  host = opt_solver_remote_login(num, GMSH_GET, "");
464  if(exe.empty()) {
465  Msg::Error("Solver executable name not provided");
466  return;
467  }
468  }
469  else {
470  Msg::Error("Unknown client to run in batch mode (%d)", num);
471  return;
472  }
473 
474  onelab::number n("0Metamodel/Batch", CTX::instance()->batch);
475  n.setVisible(false);
477 
478  // create client
479  onelab::localNetworkClient *c = nullptr;
480  onelab::string o;
481  if(name.size()) {
482  c = new gmshLocalNetworkClient(name, exe, host);
483  c->setIndex(num);
484  o = c->getName() + "/Action";
485  }
486 
487  // initialize
488  onelabUtils::runGmshClient("initialize",
489  CTX::instance()->solver.autoMesh);
490  if(c) {
491  o.setValue("initialize");
493  c->run();
494  }
495 
496  // load db
497  if(CTX::instance()->solver.autoLoadDatabase) {
498  std::vector<std::string> split =
499  SplitFileName(GModel::current()->getFileName());
500  std::string db = split[0] + split[1] + ".db";
501  if(!StatFile(db)) loadDb(db);
502  }
503 
504  // check
506  if(c) {
508  o.setValue("check");
510  c->run();
511  }
512 
513  // compute
514  initializeLoops();
515  do {
516  onelabUtils::runGmshClient("compute", CTX::instance()->solver.autoMesh);
517  if(c) {
519  o.setValue("compute");
521  c->run();
522  onelab::server::instance()->setChanged(0, c->getName());
523  }
524  } while(incrementLoops());
525 
526  if(CTX::instance()->solver.autoSaveDatabase ||
528  std::vector<std::string> split =
529  SplitFileName(GModel::current()->getFileName());
530  std::string db = split[0] + split[1] + ".db";
532  archiveOutputFiles(db);
533  if(CTX::instance()->solver.autoSaveDatabase) saveDb(db);
534  }
535  }
536  }
537 
538  // update x using y, giving priority to any settings in x that can be set in
539  // the GUI. The value of x is only changed if y is read-only.
541  const bool readOnlyRange)
542  {
543  bool noRange = true, noChoices = true, noLoop = true;
544  bool noGraph = true, noClosed = true;
545 
546  if(y.getReadOnly()) {
547  x.setValue(y.getValue());
548  x.setReadOnly(true);
549  }
550  double val = x.getValue();
551 
552  // keep track of these attributes, which can be changed server-side (unless,
553  // for the range/choices, when explicitly setting these attributes as
554  // ReadOnly)
555  if(!readOnlyRange) {
556  if(x.getMin() != -onelab::parameter::maxNumber() ||
557  x.getMax() != onelab::parameter::maxNumber() || x.getStep() != 0.)
558  noRange = false;
559  if(x.getChoices().size()) noChoices = false;
560  }
561  if(x.getAttribute("Loop").size()) noLoop = false;
562  if(x.getAttribute("Graph").size()) noGraph = false;
563  if(x.getAttribute("Closed").size()) noClosed = false;
564 
565  if(noRange) {
566  bool noRangeEither = true;
567  if(y.getMin() != -onelab::parameter::maxNumber() ||
568  y.getMax() != onelab::parameter::maxNumber() || y.getStep() != 0.)
569  noRangeEither = false;
570  if(!noRangeEither) {
571  x.setMin(y.getMin());
572  x.setMax(y.getMax());
573  }
574  else {
575  // if no range/min/max/step info is provided, try to compute a
576  // reasonnable range and step (this makes the GUI much nicer to use)
577  bool isInteger = (floor(val) == val);
578  double fact = isInteger ? 5. : 20.;
579  if(val > 0) {
580  x.setMin(val / fact);
581  x.setMax(val * fact);
582  x.setStep((x.getMax() - x.getMin()) / 100.);
583  }
584  else if(val < 0) {
585  x.setMin(val * fact);
586  x.setMax(val / fact);
587  x.setStep((x.getMax() - x.getMin()) / 100.);
588  }
589  if(val && isInteger) {
590  x.setMin((int)x.getMin());
591  x.setMax((int)x.getMax());
592  x.setStep((int)x.getStep());
593  }
594  }
595  }
596  if(noChoices) {
597  x.setChoices(y.getChoices());
599  }
600  if(noLoop) x.setAttribute("Loop", y.getAttribute("Loop"));
601  if(noGraph) x.setAttribute("Graph", y.getAttribute("Graph"));
602  if(noClosed) x.setAttribute("Closed", y.getAttribute("Closed"));
603  return val;
604  }
605 
606  bool haveSolverToRun()
607  {
608  for(auto it = onelab::server::instance()->firstClient();
609  it != onelab::server::instance()->lastClient(); it++) {
610  onelab::client *c = *it;
611  if(c->getName() != "Gmsh" && c->getName() != "Listen" &&
612  c->getName() != "GmshRemote" &&
613  c->getName().find("NoAutoRun") == std::string::npos)
614  return true;
615  }
616  return false;
617  }
618 
619  // update x using y, giving priority to any settings in x that can be set in
620  // the GUI. The value of x is only changed if y is read-only.
621  std::string updateString(onelab::string &x, onelab::string &y)
622  {
623  bool noChoices = true, noClosed = true, noMultipleSelection = true;
624 
625  if(y.getReadOnly()) {
626  x.setValue(y.getValue());
627  x.setReadOnly(true);
628  }
629  std::string val = x.getValue();
630 
631  // keep track of these attributes, which can be changed server-side
632  if(x.getChoices().size()) noChoices = false;
633  if(x.getAttribute("Closed").size()) noClosed = false;
634  if(x.getAttribute("MultipleSelection").size()) noMultipleSelection = false;
635 
636  // if(copt.count("Kind")) ps[0].setKind(copt["Kind"][0]);
637  if(noChoices) x.setChoices(y.getChoices());
638  if(noClosed) x.setAttribute("Closed", y.getAttribute("Closed"));
639  if(noMultipleSelection)
640  x.setAttribute("MultipleSelection", y.getAttribute("MultipleSelection"));
641 
642  return val;
643  }
644 
645  void initializeLoops()
646  {
650 
651 #if defined(HAVE_FLTK)
652  if(FlGui::available() && onelab::server::instance()->getChanged())
653  FlGui::instance()->rebuildTree(false);
654 #endif
655  }
656 
657  bool incrementLoops()
658  {
659  bool ret = false;
661  ret = true;
662  else if(onelabUtils::incrementLoop("2"))
663  ret = true;
664  else if(onelabUtils::incrementLoop("1"))
665  ret = true;
666 
667  // Define ONELAB parameter indicating whether or not in a loop
668  onelab::number n("0Metamodel/Loop", ret ? 1 : 0);
669  n.setVisible(false);
671 
672 #if defined(HAVE_FLTK)
673  if(FlGui::available() && onelab::server::instance()->getChanged())
674  FlGui::instance()->rebuildTree(false);
675 #endif
676  return ret;
677  }
678 
679  void updateGraphs()
680  {
681  bool redraw = false;
682  for(int i = 0; i < 18; i++) {
683  std::ostringstream tmp;
684  tmp << i;
685  bool ret = onelabUtils::updateGraph(tmp.str());
686  redraw = redraw || ret;
687  }
688  if(redraw) {
689  // don't delete the widgets, as this is called in widget callbacks
690 #if defined(HAVE_FLTK)
691  FlGui::instance()->updateViews(true, false);
693 #endif
694  }
695  }
696 
697  std::string timeStamp()
698  {
699  time_t now;
700  time(&now);
701  tm *t = localtime(&now);
702  char stamp[73];
703  // stamp.size() is always 20
704  sprintf(stamp, "_%04d-%02d-%02d_%02d-%02d-%02d", 1900 + t->tm_year,
705  1 + t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
706  return std::string(stamp);
707  }
708 
709  void saveDb(const std::string &fileName)
710  {
711  FILE *fp = Fopen(fileName.c_str(), "wb");
712  if(fp) {
713  Msg::StatusBar(true, "Saving database '%s'...", fileName.c_str());
715  fclose(fp);
716  Msg::StatusBar(true, "Done saving database '%s'", fileName.c_str());
717  }
718  else
719  Msg::Error("Could not save database '%s'", fileName.c_str());
720 
721 #if 0
722  fp = Fopen((fileName + ".json").c_str(), "wb");
723  if(fp){
724  std::string json;
725  onelab::server::instance()->toJSON(json, "Gmsh");
726  fwrite(json.c_str(), sizeof(char), json.size(), fp);
727  fclose(fp);
728  }
729 #endif
730  }
731 
732  void archiveOutputFiles(const std::string &fileName)
733  {
734  std::string stamp;
735  std::vector<onelab::string> ps;
736  onelab::server::instance()->get(ps, "0Metamodel/9Tag");
737  if(ps.size() && ps[0].getValue().size())
738  stamp.assign(timeStamp() + "_" + ps[0].getValue());
739  else
740  stamp.assign(timeStamp());
741 
742  // add time stamp in all output files in the db, and rename them on disk
743  std::vector<onelab::string> strings;
744  onelab::server::instance()->get(strings);
745  for(std::size_t i = 0; i < strings.size(); i++) {
746  if(strings[i].getName().find("9Output files") != std::string::npos) {
747  std::vector<std::string> names = strings[i].getChoices();
748  names.push_back(strings[i].getValue());
749  for(std::size_t j = 0; j < names.size(); j++) {
750  std::vector<std::string> split = SplitFileName(names[j]);
751  int n = split[1].size();
752  // if name is not already stamped
753  if(n < 18 || split[1][n - 3] != '-' || split[1][n - 6] != '-' ||
754  split[1][n - 9] != '_') {
755  std::string old = names[j];
756  CreateSingleDir(split[0] + "archive/");
757  names[j] = split[0] + "archive/" + split[1] + stamp + split[2];
758  Msg::Info("Renaming '%s' into '%s'", old.c_str(), names[j].c_str());
759  rename(old.c_str(), names[j].c_str());
760  }
761  }
762  strings[i].setValue(names.back());
763  names.pop_back();
764  strings[i].setChoices(names);
765  onelab::server::instance()->set(strings[i]);
766  }
767  }
768 
769  // save stamped db
770  {
771  std::vector<std::string> split = SplitFileName(fileName);
772  CreateSingleDir(split[0] + "archive/");
773  saveDb(split[0] + "archive/" + split[1] + stamp + split[2]);
774  }
775 
776 #if defined(HAVE_FLTK)
777  FlGui::instance()->rebuildTree(true);
778 #endif
779  }
780 
781  void archiveSolutionFiles(const std::string &fileName)
782  {
783  // extract tag from db fileName, use fileName as tag otherwise
784  std::vector<std::string> split = SplitFileName(fileName);
785  std::string dir = split[0] + "archive/";
786  std::string tag = split[1];
787  if(!tag.compare(0, 6, "onelab"))
788  tag.assign(tag.substr(6)); // cut off 'onelab' if present
789 
790  // add tag to all solution files in the db, and rename them on disk
791  std::vector<onelab::string> strings;
792  onelab::server::instance()->get(strings, "0Metamodel/9Solution files");
793  if(strings.size()) {
794  std::vector<std::string> names = strings[0].getChoices();
795  if(names.size()) {
796  for(std::size_t j = 0; j < names.size(); j++) {
797  std::vector<std::string> split = SplitFileName(names[j]);
798  std::string old = names[j];
799  CreateSingleDir(dir);
800  names[j] = dir + split[1] + tag + split[2];
801  Msg::Info("Renaming '%s' into '%s'", old.c_str(), names[j].c_str());
802  rename(old.c_str(), names[j].c_str());
803  }
804  strings[0].setValue(names[0]);
805  strings[0].setChoices(names);
806  onelab::server::instance()->set(strings[0]);
807 #if defined(HAVE_FLTK)
808  FlGui::instance()->rebuildTree(true);
809 #endif
810  }
811  }
812  }
813 
814  void loadDb(const std::string &name)
815  {
816  Msg::StatusBar(true, "Loading database '%s'...", name.c_str());
817  FILE *fp = Fopen(name.c_str(), "rb");
818  if(fp) {
820  fclose(fp);
821  Msg::StatusBar(true, "Done loading database '%s'", name.c_str());
822  }
823  else
824  Msg::Error("Could not load database '%s'", name.c_str());
825  }
826 
827  void resetDb(bool runGmshClient)
828  {
829  Msg::Info("Resetting database");
830 
831  // clear everything except persistent parameters
832  std::vector<onelab::number> allNumbers, persistentNumbers;
833  std::vector<onelab::string> allStrings, persistentStrings;
834  onelab::server::instance()->get(allNumbers);
835  onelab::server::instance()->get(allStrings);
836  bool ismetamodel = false;
837  for(std::size_t i = 0; i < allNumbers.size(); i++) {
838  if(allNumbers[i].getAttribute("Persistent") == "1")
839  persistentNumbers.push_back(allNumbers[i]);
840  // these 2 should always be persistent
841  if(allNumbers[i].getName() == "IsMetamodel" ||
842  allNumbers[i].getName() == "IsPyMetamodel"){
843  ismetamodel = allNumbers[i].getValue() ? true : false;
844  persistentNumbers.push_back(allNumbers[i]);
845  }
846  }
847  for(std::size_t i = 0; i < allStrings.size(); i++) {
848  if(allStrings[i].getAttribute("Persistent") == "1")
849  persistentStrings.push_back(allStrings[i]);
850  }
851 
852  // clear the db
854 
855  // run Gmsh client for non-metamodels (we need to check ismetamodel here
856  // since the db has been cleared and the check cannot work in
857  // runGmshClient!)
858  if(runGmshClient && !ismetamodel){
860  }
861 
862  for(std::size_t i = 0; i < persistentNumbers.size(); i++) {
863  Msg::Debug("Restoring persistent parameter %s",
864  persistentNumbers[i].getName().c_str());
865  onelab::server::instance()->set(persistentNumbers[i]);
866  }
867  for(std::size_t i = 0; i < persistentStrings.size(); i++) {
868  Msg::Debug("Restoring persistent parameter %s",
869  persistentStrings[i].getName().c_str());
870  onelab::server::instance()->set(persistentStrings[i]);
871  }
872 
873  // mark all parameters as changed
875  }
876 
877 } // namespace onelabUtils
878 
879 #endif
onelab::server::instance
static server * instance(const std::string &address="")
Definition: onelab.h:1309
onelab::string
Definition: onelab.h:678
opt_solver_name
std::string opt_solver_name(OPT_ARGS_STR)
Definition: Options.cpp:1450
onelab::string::setValue
void setValue(const std::string &value)
Definition: onelab.h:695
CreateFile.h
onelabUtils::updateString
std::string updateString(onelab::string &x, onelab::string &y)
Msg::SetOnelabAction
static void SetOnelabAction(const std::string &action)
Definition: GmshMessage.cpp:1213
SplitFileName
std::vector< std::string > SplitFileName(const std::string &fileName)
Definition: StringUtils.cpp:93
PView
Definition: PView.h:27
GModel::getFileName
std::string getFileName() const
Definition: GModel.h:333
onelabUtils::updateGraph
bool updateGraph(const std::string &graphNum)
GMSH_GET
#define GMSH_GET
Definition: Options.h:13
Msg::GetCommandLineStrings
static std::map< std::string, std::string > & GetCommandLineStrings()
Definition: GmshMessage.cpp:297
gmshLocalNetworkClient.h
onelab::server::thresholdChanged
void thresholdChanged(int value, const std::string &client="")
Definition: onelab.h:1353
onelab::server::clear
void clear(const std::string &name="", const std::string &client="")
Definition: onelab.h:1315
Msg::Info
static void Info(const char *fmt,...)
Definition: GmshMessage.cpp:587
CTX::fileFormat
int fileFormat
Definition: Context.h:319
OS.h
onelab::number::setStep
void setStep(double step)
Definition: onelab.h:462
Msg::Debug
static void Debug(const char *fmt,...)
Definition: GmshMessage.cpp:752
c
static double c(int i, int j, fullMatrix< double > &CA, const std::vector< SPoint3 > &P, const std::vector< SPoint3 > &Q)
Definition: discreteFrechetDistance.cpp:15
onelabUtils::getFirstComputationFlag
bool getFirstComputationFlag()
onelabUtils::getMshFileName
std::string getMshFileName(onelab::client *c)
CreateOutputFile
void CreateOutputFile(const std::string &fileName, int format, bool status)
Definition: CreateFile.cpp:290
onelabUtils::timeStamp
std::string timeStamp()
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
Msg::StatusBar
static void StatusBar(bool log, const char *fmt,...)
Definition: GmshMessage.cpp:686
onelabUtils::resetDb
void resetDb(bool runGmshClient)
onelabUtils::archiveSolutionFiles
void archiveSolutionFiles(const std::string &fileName)
onelabUtils::haveSolverToRun
bool haveSolverToRun()
onelab::number::setMin
void setMin(double min)
Definition: onelab.h:460
onelabUtils::setFirstComputationFlag
void setFirstComputationFlag(bool val)
CTX::solver
struct CTX::@1 solver
PView.h
onelab::number::setMax
void setMax(double max)
Definition: onelab.h:461
onelabUtils::getCommandLine
std::vector< std::string > getCommandLine(onelab::client *c)
onelab::string::getValue
const std::string & getValue() const
Definition: onelab.h:707
PViewData.h
PViewData::setFileName
virtual void setFileName(const std::string &val)
Definition: PViewData.h:75
onelab::parameter::maxNumber
static double maxNumber()
Definition: onelab.h:204
onelab::number::getValueLabels
const std::map< double, std::string > & getValueLabels() const
Definition: onelab.h:499
drawContext::global
static drawContextGlobal * global()
Definition: drawContext.cpp:85
onelab::remoteNetworkClient
Definition: onelab.h:1519
Fopen
FILE * Fopen(const char *f, const char *mode)
Definition: OS.cpp:273
GetDefaultFileName
std::string GetDefaultFileName(int format)
Definition: CreateFile.cpp:165
PView::setChanged
void setChanged(bool val)
Definition: PView.cpp:241
onelab::number::setValueLabels
void setValueLabels(const std::map< double, std::string > &valueLabels)
Definition: onelab.h:472
onelab::number
Definition: onelab.h:432
drawContextGlobal::draw
virtual void draw(bool rateLimited=true)
Definition: drawContext.h:97
onelab::server::get
bool get(std::vector< T > &ps, const std::string &name="", const std::string &client="")
Definition: onelab.h:1324
opt_solver_remote_login
std::string opt_solver_remote_login(OPT_ARGS_STR)
Definition: Options.cpp:1621
CTX::instance
static CTX * instance()
Definition: Context.cpp:122
CTX::autoArchiveOutputFiles
int autoArchiveOutputFiles
Definition: Context.h:334
onelabUtils::updateNumber
double updateNumber(onelab::number &x, onelab::number &y, const bool readOnlyRange=false)
onelab::server::getChanged
int getChanged(const std::string &client="")
Definition: onelab.h:1349
FORMAT_MSH
#define FORMAT_MSH
Definition: GmshDefines.h:10
onelab::server::findClient
citer findClient(const std::string &name)
Definition: onelab.h:1333
onelabUtils::loadDb
void loadDb(const std::string &name)
CreateSingleDir
int CreateSingleDir(const std::string &dirName)
Definition: OS.cpp:502
OpenProject
void OpenProject(const std::string &fileName, bool errorIfMissing)
Definition: OpenFile.cpp:718
onelab::string::getChoices
const std::vector< std::string > & getChoices() const
Definition: onelab.h:717
onelab::number::getMax
double getMax() const
Definition: onelab.h:495
CTX::autoMesh
int autoMesh
Definition: Context.h:334
PView::getData
PViewData * getData(bool useAdaptiveIfAvailable=false)
Definition: PView.cpp:233
PViewOptions::intervalsType
int intervalsType
Definition: PViewOptions.h:54
onelab::number::getValue
double getValue() const
Definition: onelab.h:481
PViewOptions.h
Msg::SetWindowTitle
static void SetWindowTitle(const std::string &title)
Definition: GmshMessage.cpp:743
CTX::outputFileName
std::string outputFileName
Definition: Context.h:141
GmshDefines.h
onelab::number::getStep
double getStep() const
Definition: onelab.h:496
onelabUtils::guessModelName
void guessModelName(onelab::client *c)
onelabUtils.h
PViewData::setName
virtual void setName(const std::string &val)
Definition: PViewData.h:71
onelabUtils::archiveOutputFiles
void archiveOutputFiles(const std::string &fileName)
onelab::number::getMin
double getMin() const
Definition: onelab.h:494
CTX::autoSaveDatabase
int autoSaveDatabase
Definition: Context.h:333
onelab::localNetworkClient
Definition: onelab.h:1471
GModel::deleteMesh
void deleteMesh()
Definition: GModel.cpp:236
onelab::server::toFile
bool toFile(FILE *fp, const std::string &client="")
Definition: onelab.h:1372
onelabUtils::updateGraphs
void updateGraphs()
onelab::parameter::setAttribute
void setAttribute(const std::string &key, const std::string &value)
Definition: onelab.h:111
StatFile
int StatFile(const std::string &fileName)
Definition: OS.cpp:489
onelabUtils
Definition: onelabUtils.h:14
onelab::parameter::setReadOnly
void setReadOnly(bool readOnly)
Definition: onelab.h:110
onelabUtils::incrementLoops
bool incrementLoops()
StringUtils.h
onelab::number::setValue
void setValue(double value)
Definition: onelab.h:454
onelab::server::toJSON
bool toJSON(std::string &json, const std::string &client="")
Definition: onelab.h:1382
Msg::GetCommandLineNumbers
static std::map< std::string, std::vector< double > > & GetCommandLineNumbers()
Definition: GmshMessage.cpp:292
Context.h
PViewOptions::autoPosition
int autoPosition
Definition: PViewOptions.h:40
onelabUtils::runGmshClient
bool runGmshClient(const std::string &action, int meshAuto)
onelab::parameter::getReadOnly
bool getReadOnly() const
Definition: onelab.h:191
onelabUtils::saveDb
void saveDb(const std::string &fileName)
onelab::server::fromFile
bool fromFile(FILE *fp, const std::string &client="")
Definition: onelab.h:1376
PView::getOptions
PViewOptions * getOptions()
Definition: PView.h:81
FORMAT_AUTO
#define FORMAT_AUTO
Definition: GmshDefines.h:18
onelab::server::lastClient
citer lastClient()
Definition: onelab.h:1331
GModel::mesh
int mesh(int dimension)
Definition: GModel.cpp:1066
Options.h
CTX::launchSolverAtStartup
int launchSolverAtStartup
Definition: Context.h:155
onelabUtils::runClient
void runClient(const std::string &name="", const std::string &command="")
GModel.h
onelab::string::setChoices
void setChoices(const std::vector< std::string > &choices)
Definition: onelab.h:702
onelab::client
Definition: onelab.h:1201
onelabUtils::initializeLoops
void initializeLoops()
PView::list
static std::vector< PView * > list
Definition: PView.h:112
onelab::parameter::getAttribute
std::string getAttribute(const std::string &key) const
Definition: onelab.h:192
PViewOptions::axesLabel
std::string axesLabel[3]
Definition: PViewOptions.h:45
onelab::server::set
bool set(const T &p, const std::string &client="")
Definition: onelab.h:1319
onelab::number::getChoices
const std::vector< double > & getChoices() const
Definition: onelab.h:498
PViewData::setXY
virtual void setXY(std::vector< double > &x, std::vector< double > &y)
Definition: PViewData.h:272
OpenFile.h
CTX::autoLoadDatabase
int autoLoadDatabase
Definition: Context.h:333
onelab::server::setChanged
void setChanged(int changed, const std::string &client="")
Definition: onelab.h:1345
GModel::current
static GModel * current(int index=-1)
Definition: GModel.cpp:136
onelabUtils::getRange
std::vector< double > getRange(onelab::number &p)
opt_solver_executable
std::string opt_solver_executable(OPT_ARGS_STR)
Definition: Options.cpp:1564
onelabUtils::incrementLoop
bool incrementLoop(const std::string &level)
onelabUtils::initializeLoop
void initializeLoop(const std::string &level)
onelab::number::setChoices
void setChoices(const std::vector< double > &choices)
Definition: onelab.h:464
drawContext.h