From 854e82c737ef505ec58fd06f22d2a65c04211306 Mon Sep 17 00:00:00 2001
From: Francois Henrotte <francois.henrotte@ulg.ac.be>
Date: Wed, 28 Mar 2012 12:10:58 +0000
Subject: [PATCH] Step<0 in onelab, MinMax plugin computes also the argmin

---
 Common/GmshSocket.h                |  8 +--
 Fltk/onelabWindow.cpp              | 69 +++++++++++++++++------
 Plugin/MinMax.cpp                  | 88 ++++++++++++++++++++++--------
 Solver/elasticitySolver.h          |  3 +-
 utils/api_demos/mainElasticity.cpp |  5 +-
 utils/api_demos/simpleBeam.dat     | 16 +++++-
 6 files changed, 143 insertions(+), 46 deletions(-)

diff --git a/Common/GmshSocket.h b/Common/GmshSocket.h
index 82f56e9eb4..22673e2035 100644
--- a/Common/GmshSocket.h
+++ b/Common/GmshSocket.h
@@ -320,6 +320,7 @@ class GmshServer : public GmshSocket{
   virtual ~GmshServer(){}
   virtual int NonBlockingSystemCall(const char *str) = 0;
   virtual int NonBlockingWait(int socket, double waitint, double timeout) = 0;
+
   int Start(const char *command, const char *sockname, double timeout)
   {
     if(!sockname) throw "Invalid (null) socket name";
@@ -385,11 +386,10 @@ class GmshServer : public GmshSocket{
       }
     }
 
+    char cmd[1024];
     if(command && strlen(command)){
-      // we assume that the command line always ends with the socket name
-      std::string cmd(command);
-      cmd += " " + _sockname;
-      NonBlockingSystemCall(cmd.c_str()); // start the solver
+      sprintf(cmd,command,_sockname.c_str());
+      NonBlockingSystemCall(cmd); // starts the solver
     }
     else{
       timeout = 0.; // no command launched: don't set a timeout
diff --git a/Fltk/onelabWindow.cpp b/Fltk/onelabWindow.cpp
index b03af6f7ff..55f2ab7cb9 100644
--- a/Fltk/onelabWindow.cpp
+++ b/Fltk/onelabWindow.cpp
@@ -203,13 +203,22 @@ bool onelab::localNetworkClient::run()
       std::string checkCommand = (ps.empty() ? "" : ps[0].getValue());
       get(ps, getName() + "/9ComputeCommand");
       std::string computeCommand = (ps.empty() ? "" : ps[0].getValue());
+    /*
       if(action == "check")
         command += " " + modelName + " " + checkCommand;
       else if(action == "compute")
         command += " " + modelName + " " + computeCommand;
+    */
+    if(action == "check")
+      command.append(" " + modelName + " " + checkCommand) ;
+    else if(action == "compute")
+      command.append(" " + modelName + " " + computeCommand);
     }
+    /*
     // append "-onelab" command line argument
     command += " " + _socketSwitch + " \"" + getName() + "\"";
+    */
+    command.append(" " + getSocketSwitch() + " " + getName() + " %s");
   }
   else{
     Msg::Info("Listening on socket '%s'", sockname.c_str());
@@ -448,16 +457,25 @@ static void initializeLoop(const std::string &level)
   onelab::server::instance()->get(numbers);
   for(unsigned int i = 0; i < numbers.size(); i++){
     if(numbers[i].getAttribute("Loop") == level){
+
       if(numbers[i].getChoices().size() > 1){
         numbers[i].setValue(numbers[i].getChoices()[0]);
         onelab::server::instance()->set(numbers[i]);
         changed = true;
       }
-      else if(numbers[i].getMin() != -onelab::parameter::maxNumber() &&
-              numbers[i].getStep()){
-        numbers[i].setValue(numbers[i].getMin());
-        onelab::server::instance()->set(numbers[i]);
-        changed = true;
+      else if(numbers[i].getStep()>0){
+	if(numbers[i].getMin() != -onelab::parameter::maxNumber()){
+	  numbers[i].setValue(numbers[i].getMin());
+	  onelab::server::instance()->set(numbers[i]);
+	  changed = true;
+	}
+      }
+      else if(numbers[i].getStep()<0){
+	if(numbers[i].getMax() != onelab::parameter::maxNumber()){
+	  numbers[i].setValue(numbers[i].getMax());
+	  onelab::server::instance()->set(numbers[i]);
+	  changed = true;
+	}
       }
     }
   }
@@ -476,6 +494,7 @@ static bool incrementLoop(const std::string &level)
   for(unsigned int i = 0; i < numbers.size(); i++){
     if(numbers[i].getAttribute("Loop") == level){
       loop = true;
+
       if(numbers[i].getChoices().size() > 1){
         // FIXME should store loopVariable attribute in the parameter
         // -- the following test will loop forever if 2 values are
@@ -492,14 +511,25 @@ static bool incrementLoop(const std::string &level)
           }
         }
       }
-      else if(numbers[i].getMax() != onelab::parameter::maxNumber() &&
-              numbers[i].getValue() < numbers[i].getMax() &&
-              numbers[i].getStep()){
-        numbers[i].setValue(numbers[i].getValue() + numbers[i].getStep());
-        onelab::server::instance()->set(numbers[i]);
-        Msg::Info("Recomputing with new step %s=%g",
-                  numbers[i].getName().c_str(), numbers[i].getValue());
-        recompute = true;
+      else if(numbers[i].getStep()>0){
+	if(numbers[i].getMax() != onelab::parameter::maxNumber() &&
+	   numbers[i].getValue() < numbers[i].getMax()){
+	  numbers[i].setValue(numbers[i].getValue() + numbers[i].getStep());
+	  onelab::server::instance()->set(numbers[i]);
+	  Msg::Info("Recomputing with new step %s=%g",
+		    numbers[i].getName().c_str(), numbers[i].getValue());
+	  recompute = true;
+	}
+      }
+      else if(numbers[i].getStep()<0){
+	if(numbers[i].getMin() != -onelab::parameter::maxNumber() &&
+	   numbers[i].getValue() > numbers[i].getMin()){
+	  numbers[i].setValue(numbers[i].getValue() + numbers[i].getStep());
+	  onelab::server::instance()->set(numbers[i]);
+	  Msg::Info("Recomputing with new step %s=%g",
+		    numbers[i].getName().c_str(), numbers[i].getValue());
+	  recompute = true;
+	}
       }
     }
   }
@@ -536,13 +566,20 @@ static bool incrementLoop()
 static std::vector<double> getRange(onelab::number &p)
 {
   std::vector<double> v;
+
   if(p.getChoices().size()){
     v = p.getChoices();
   }
   else if(p.getMin() != -onelab::parameter::maxNumber() &&
-          p.getMax() != onelab::parameter::maxNumber() && p.getStep()){
-    for(double d = p.getMin(); d <= p.getMax(); d += p.getStep())
-      v.push_back(d);
+          p.getMax() != onelab::parameter::maxNumber()){
+    if(p.getStep()>0){
+      for(double d = p.getMin(); d <= p.getMax(); d += p.getStep())
+	v.push_back(d);
+    }
+    else if(p.getStep()<0){
+      for(double d = p.getMin(); d <= p.getMax(); d -= p.getStep())
+	v.push_back(d);
+    }
   }
   return v;
 }
diff --git a/Plugin/MinMax.cpp b/Plugin/MinMax.cpp
index 0a4d912233..95e43e71b6 100644
--- a/Plugin/MinMax.cpp
+++ b/Plugin/MinMax.cpp
@@ -8,7 +8,8 @@
 
 StringXNumber MinMaxOptions_Number[] = {
   {GMSH_FULLRC, "View", NULL, -1.},
-  {GMSH_FULLRC, "OverTime", NULL, 0}
+  {GMSH_FULLRC, "OverTime", NULL, 0},
+  {GMSH_FULLRC, "Argument", NULL, 0}
 };
 
 extern "C"
@@ -23,7 +24,8 @@ std::string GMSH_MinMaxPlugin::getHelp() const
 {
   return "Plugin(MinMax) computes the min/max of a view.\n\n"
     "If `View' < 0, the plugin is run on the current view.\n\n"
-    "If `OverTime' = 1, calculates the min-max over space AND time\n\n"
+    "If `OverTime' = 1, calculates the min/max over space AND time\n\n"
+    "If `Argument' = 1, calculates the min/max AND the argmin/argmax\n\n"
     "Plugin(MinMax) creates two new views.";
 }
 
@@ -41,6 +43,7 @@ PView *GMSH_MinMaxPlugin::execute(PView * v)
 {
   int iView = (int)MinMaxOptions_Number[0].def;
   int overTime = (int)MinMaxOptions_Number[1].def;
+  int argument = (int)MinMaxOptions_Number[2].def;
   
   PView *v1 = getView(iView, v);
   if(!v1) return v;
@@ -51,42 +54,82 @@ PView *GMSH_MinMaxPlugin::execute(PView * v)
   PViewDataList *dataMin = getDataList(vMin);
   PViewDataList *dataMax = getDataList(vMax);
   
-  double x = data1->getBoundingBox().center().x();
-  double y = data1->getBoundingBox().center().y();
-  double z = data1->getBoundingBox().center().z();
-  dataMin->SP.push_back(x); dataMin->SP.push_back(y); dataMin->SP.push_back(z);
-  dataMax->SP.push_back(x); dataMax->SP.push_back(y); dataMax->SP.push_back(z);
+  if(!argument){
+    double x = data1->getBoundingBox().center().x();
+    double y = data1->getBoundingBox().center().y();
+    double z = data1->getBoundingBox().center().z();
+    dataMin->SP.push_back(x); dataMin->SP.push_back(y); dataMin->SP.push_back(z);
+    dataMax->SP.push_back(x); dataMax->SP.push_back(y); dataMax->SP.push_back(z);
+    dataMin->NbSP = 1;
+    dataMax->NbSP = 1;
+  }
+
+  double minView=VAL_INF, maxView=-VAL_INF, min=VAL_INF, max=-VAL_INF, timeMin=0, timeMax=0;
+  double xmin, ymin, zmin, xmax, ymax, zmax;
 
-  double minView, maxView, min=1E200, max=-1E200, timeMin=0, timeMax=0;
   for(int step = 0; step < data1->getNumTimeSteps(); step++){
     if(data1->hasTimeStep(step)){
-      minView=data1->getMin(step);
-      maxView=data1->getMax(step);
-      if(minView<min){
-	min=minView;
-	timeMin = data1->getTime(step);
+
+      //minView=data1->getMin(step); 
+      //maxView=data1->getMax(step);
+ 
+      for(int ent = 0; ent < data1->getNumEntities(step); ent++){
+	for(int ele = 0; ele < data1->getNumElements(step, ent); ele++){
+	  for(int nod = 0; nod < data1->getNumNodes(step, ent, ele); nod++){
+	    double val;
+	    data1->getScalarValue(step, ent, ele, nod, val);
+	    if(val<minView){
+	      data1->getNode(step, ent, ele, nod, xmin, ymin, zmin);
+	      minView=val;
+	    }
+	    if(val>maxView){
+	      data1->getNode(step, ent, ele, nod, xmax, ymax, zmax);
+	      maxView=val;
+	    }
+	  }
+	}
       }
-      if(maxView>max){ 
-	max=maxView;
-	timeMax = data1->getTime(step);
+      if(!overTime){ 
+	// one stores min/max and at each time step 
+	if(argument){
+	  dataMin->SP.push_back(xmin); dataMin->SP.push_back(ymin); dataMin->SP.push_back(zmin);
+	  dataMax->SP.push_back(xmax); dataMax->SP.push_back(ymax); dataMax->SP.push_back(zmax);
+	  (dataMin->NbSP)++;
+	  (dataMax->NbSP)++;
+	}
+	dataMin->SP.push_back(minView);
+	dataMax->SP.push_back(maxView);
+	double time = data1->getTime(step);
+	dataMin->Time.push_back(time);//?
+	dataMax->Time.push_back(time);//?
       }
-      if(!overTime){
-	dataMin->SP.push_back(data1->getMin(step));
-	dataMax->SP.push_back(data1->getMax(step));
+      else{
+	if(minView<min){
+	  min=minView;
+	  timeMin = data1->getTime(step);
+	}
+	if(maxView>max){ 
+	  max=maxView;
+	  timeMax = data1->getTime(step);
+	} 
       }
     }
   }
-  if(overTime){
+
+  if(overTime){ 
     dataMin->SP.push_back(min);
     dataMax->SP.push_back(max);
+    dataMin->Time.push_back(timeMin);//?
+    dataMax->Time.push_back(timeMax);//?
   }
 
-  dataMin->NbSP = 1;
-  dataMax->NbSP = 1;
+  // dataMin->NbSP = 1;
+  // dataMax->NbSP = 1;
 
   vMin->getOptions()->intervalsType = PViewOptions::Numeric;
   vMax->getOptions()->intervalsType = PViewOptions::Numeric;
   
+  /*
   for(int step = 0; step < data1->getNumTimeSteps(); step++){
     if(data1->hasTimeStep(step)){
       if(overTime){
@@ -100,6 +143,7 @@ PView *GMSH_MinMaxPlugin::execute(PView * v)
       }
     }
   }
+  */
 
   dataMin->setName(data1->getName() + "_Min");
   dataMin->setFileName(data1->getName() + "_Min.pos");
diff --git a/Solver/elasticitySolver.h b/Solver/elasticitySolver.h
index 7b4f7e683e..90a49b19bf 100644
--- a/Solver/elasticitySolver.h
+++ b/Solver/elasticitySolver.h
@@ -65,7 +65,8 @@ class elasticitySolver
   FunctionSpace<double> *LagrangeMultiplierSpace;
 
   // young modulus and poisson coefficient per physical
-  std::vector<elasticField> elasticFields;
+  std::vector<elasticField> elasticFields; 
+
   std::vector<LagrangeMultiplierField> LagrangeMultiplierFields;
   // neumann BC
   std::vector<neumannBC> allNeumann;
diff --git a/utils/api_demos/mainElasticity.cpp b/utils/api_demos/mainElasticity.cpp
index 802c1feae1..68236fcddd 100644
--- a/utils/api_demos/mainElasticity.cpp
+++ b/utils/api_demos/mainElasticity.cpp
@@ -73,7 +73,7 @@ void GetSetFixations (elasticitySolver &e) {
 }
 */
 
-void WhatToDoNow(int argc, char *argv[], int &solve, std::string &modelName)
+void WhatToDoNow(int argc, char *argv[], int &solve, std::string &fileName)
 {
   int i =  1;
   solve = 1;
@@ -123,7 +123,8 @@ void WhatToDoNow(int argc, char *argv[], int &solve, std::string &modelName)
       }
     }
     else {
-      modelName = std::string(argv[i]);
+      std::string modelName = std::string(argv[i]);
+      fileName=modelName.substr(0,modelName.find_last_of("."));  // remove extension
       //      if (modelName)
       //      modelName = modelName + std::string(".fuk");
       i++;
diff --git a/utils/api_demos/simpleBeam.dat b/utils/api_demos/simpleBeam.dat
index bf2a61e8c7..3fa76c673d 100644
--- a/utils/api_demos/simpleBeam.dat
+++ b/utils/api_demos/simpleBeam.dat
@@ -1,4 +1,18 @@
-ElasticDomain 7 100.e9 0.3
+onelab.number Material1.Create(1);
+onelab.string Material.Add(Material1); Material.Add(Material2); Material.Add(Material3);
+
+onelab.iftrue(Material1)
+onelab.number E.Create(100.e9); Nu.Create(0.3); 
+onelab.endif
+onelab.iftrue(Material2)
+onelab.number E.Create(200.e9); Nu.Create(0.25); 
+onelab.endif
+onelab.iftrue(Material3)
+onelab.number E.Create(80.e9); Nu.Create(0.5); 
+onelab.endif
+
+
+ElasticDomain 7  onelab.getValue(E) onelab.getValue(Nu);
 EdgeDisplacement 8 0 0
 EdgeDisplacement 8 1 0
 EdgeDisplacement 8 2 0
-- 
GitLab