From a0d5ecb51ed1d4a299f13f85b7160179db0d3f24 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Fri, 23 Nov 2012 10:27:33 +0000
Subject: [PATCH] solver_batch_cb to run onelab in batch mode

---
 Common/Gmsh.cpp      |  5 ++++
 Fltk/onelabGroup.cpp | 69 +++++++++++++++++++++++++++++++++++++++-----
 Fltk/onelabGroup.h   |  1 +
 3 files changed, 68 insertions(+), 7 deletions(-)

diff --git a/Common/Gmsh.cpp b/Common/Gmsh.cpp
index 098b16b274..6ff89e50e2 100644
--- a/Common/Gmsh.cpp
+++ b/Common/Gmsh.cpp
@@ -201,6 +201,11 @@ int GmshBatch()
     CreateOutputFile(name, CTX::instance()->mesh.fileFormat);
   }
 
+#if defined(HAVE_FLTK) // FIXME this actually does not require the GUI
+  // launch solver (if requested)
+  solver_batch_cb(0, (void*)CTX::instance()->launchSolverAtStartup);
+#endif
+
   time_t now;
   time(&now);
   std::string currtime = ctime(&now);
diff --git a/Fltk/onelabGroup.cpp b/Fltk/onelabGroup.cpp
index 28f32cf06f..d225546689 100644
--- a/Fltk/onelabGroup.cpp
+++ b/Fltk/onelabGroup.cpp
@@ -81,7 +81,7 @@ class onelabGmshServer : public GmshServer{
           onelab_cb(0, (void*)"refresh");
         }
         // wait at most waitint seconds and respond to FLTK events
-        FlGui::instance()->wait(waitint);
+        if(FlGui::available()) FlGui::instance()->wait(waitint);
       }
       else if(ret > 0){
         return 0; // data is there!
@@ -193,8 +193,9 @@ bool onelab::localNetworkClient::run()
         else if(type == "number"){
           onelab::number p; p.fromChar(message); set(p);
           if(p.getName() == getName() + "/Progress")
-            FlGui::instance()->setProgress(p.getLabel().c_str(), p.getValue(),
-                                           p.getMin(), p.getMax());
+            if(FlGui::available())
+              FlGui::instance()->setProgress(p.getLabel().c_str(), p.getValue(),
+                                             p.getMin(), p.getMax());
         }
         else if(type == "string"){
           onelab::string p; p.fromChar(message); set(p);
@@ -302,7 +303,7 @@ bool onelab::localNetworkClient::run()
         MergePostProcessingFile(message, CTX::instance()->solver.autoShowLastStep,
                                 CTX::instance()->solver.autoHideNewViews, true);
         drawContext::global()->draw();
-        if(n != PView::list.size()){
+        if(FlGui::available() && n != PView::list.size()){
           FlGui::instance()->rebuildTree();
           FlGui::instance()->openModule("Post-processing");
         }
@@ -320,7 +321,8 @@ bool onelab::localNetworkClient::run()
       {
         int n = PView::list.size();
         PView::fillVertexArray(this, length, &message[0], swap);
-        FlGui::instance()->updateViews(n != (int)PView::list.size());
+        if(FlGui::available())
+          FlGui::instance()->updateViews(n != (int)PView::list.size());
         drawContext::global()->draw();
       }
       break;
@@ -363,7 +365,7 @@ static void initializeLoops()
   onelabUtils::initializeLoop("2");
   onelabUtils::initializeLoop("3");
 
-  if(onelab::server::instance()->getChanged())
+  if(FlGui::available() && onelab::server::instance()->getChanged())
     FlGui::instance()->rebuildTree();
 }
 
@@ -374,7 +376,7 @@ static bool incrementLoops()
   else if(onelabUtils::incrementLoop("2")) ret = true;
   else if(onelabUtils::incrementLoop("1")) ret = true;
 
-  if(onelab::server::instance()->getChanged())
+  if(FlGui::available() && onelab::server::instance()->getChanged())
     FlGui::instance()->rebuildTree();
 
   return ret;
@@ -1568,6 +1570,59 @@ void solver_cb(Fl_Widget *w, void *data)
   CTX::instance()->launchSolverAtStartup = -1;
 }
 
+void solver_batch_cb(Fl_Widget *w, void *data)
+{
+  int num = (intptr_t)data;
+  if(num < 0) return;
+  std::string name = opt_solver_name(num, GMSH_GET, "");
+  std::string exe = opt_solver_executable(num, GMSH_GET, "");
+  std::string host = opt_solver_remote_login(num, GMSH_GET, "");
+  if(exe.empty()){
+    Msg::Error("Solver executable name not provided");
+    return;
+  }
+
+  // create client
+  onelab::localNetworkClient *c = new onelab::localNetworkClient(name, exe, host);
+  c->setIndex(num);
+  onelab::string o(c->getName() + "/Action");
+
+  // initialize
+  onelabUtils::runGmshClient("initalize", CTX::instance()->solver.autoMesh);
+  o.setValue("initialize");
+  onelab::server::instance()->set(o);
+  c->run();
+
+  // load db
+  if(CTX::instance()->solver.autoSaveDatabase){
+    std::string db = SplitFileName(GModel::current()->getFileName())[0] + "onelab.db";
+    if(!StatFile(db)) loadDb(db);
+  }
+
+  // check
+  onelabUtils::runGmshClient("check", CTX::instance()->solver.autoMesh);
+  o.setValue("check");
+  onelab::server::instance()->set(o);
+  c->run();
+
+  // compute
+  initializeLoops();
+  do{
+    onelabUtils::runGmshClient("compute", CTX::instance()->solver.autoMesh);
+    onelabUtils::guessModelName(c);
+    o.setValue("compute");
+    onelab::server::instance()->set(o);
+    c->run();
+  } while(incrementLoops());
+
+  if(CTX::instance()->solver.autoSaveDatabase ||
+     CTX::instance()->solver.autoArchiveOutputFiles){
+    std::string db = SplitFileName(GModel::current()->getFileName())[0] + "onelab.db";
+    if(CTX::instance()->solver.autoArchiveOutputFiles) archiveOutputFiles(db);
+    if(CTX::instance()->solver.autoSaveDatabase) saveDb(db);
+  }
+}
+
 void flgui_wait_cb(double time)
 {
   FlGui::instance()->wait(time);
diff --git a/Fltk/onelabGroup.h b/Fltk/onelabGroup.h
index 1871036579..401beec1a5 100644
--- a/Fltk/onelabGroup.h
+++ b/Fltk/onelabGroup.h
@@ -83,6 +83,7 @@ class onelabGroup : public Fl_Group{
 
 void onelab_cb(Fl_Widget *w, void *data);
 void solver_cb(Fl_Widget *w, void *data);
+void solver_batch_cb(Fl_Widget *w, void *data);
 int metamodel_cb(const std::string &name, const std::string &action="");
 
 #endif
-- 
GitLab