Skip to content
Snippets Groups Projects
Extract.cpp 7.77 KiB
Newer Older
Christophe Geuzaine's avatar
Christophe Geuzaine committed
// Gmsh - Copyright (C) 1997-2009 C. Geuzaine, J.-F. Remacle
Christophe Geuzaine's avatar
Christophe Geuzaine committed
//
Christophe Geuzaine's avatar
Christophe Geuzaine committed
// See the LICENSE.txt file for license information. Please report all
// bugs and problems to <gmsh@geuz.org>.
Christophe Geuzaine's avatar
Christophe Geuzaine committed

Christophe Geuzaine's avatar
Christophe Geuzaine committed
#include "Extract.h"
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
#include "mathEvaluator.h"
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed

Christophe Geuzaine's avatar
Christophe Geuzaine committed
StringXNumber ExtractOptions_Number[] = {
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  {GMSH_FULLRC, "TimeStep", NULL, -1.},
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  {GMSH_FULLRC, "iView", NULL, -1.}
};

StringXString ExtractOptions_String[] = {
Christophe Geuzaine's avatar
Christophe Geuzaine committed
  {GMSH_FULLRC, "Expression0", NULL, "Sqrt(v0^2+v1^2+v2^2)"},
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  {GMSH_FULLRC, "Expression1", NULL, ""},
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  {GMSH_FULLRC, "Expression2", NULL, ""},
  {GMSH_FULLRC, "Expression3", NULL, ""},
  {GMSH_FULLRC, "Expression4", NULL, ""},
  {GMSH_FULLRC, "Expression5", NULL, ""},
  {GMSH_FULLRC, "Expression6", NULL, ""},
  {GMSH_FULLRC, "Expression7", NULL, ""},
  {GMSH_FULLRC, "Expression8", NULL, ""}
Christophe Geuzaine's avatar
Christophe Geuzaine committed
};

extern "C"
{
  GMSH_Plugin *GMSH_RegisterExtractPlugin()
  {
    return new GMSH_ExtractPlugin();
  }
}

std::string GMSH_ExtractPlugin::getHelp() const
Christophe Geuzaine's avatar
Christophe Geuzaine committed
{
  return "Plugin(Extract) extracts a combination of\n"
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
         "components from the `TimeStep'th time step\n"
         "in the view `iView'. If only `Expression0' is\n"
         "given (and `Expression1', ..., `Expression8' are\n"
         "all empty), the plugin creates a scalar view.\n"
         "If `Expression0', `Expression1' and/or\n"
         "`Expression2' are given (and `Expression3',\n"
         "..., `Expression8' are all empty) the plugin\n"
         "creates a vector view. Otherwise the plugin\n"
         "creates a tensor view. In addition to the usual\n"
         "mathematical functions (Exp, Log, Sqrt, Sin, Cos,\n"
         "Fabs, etc.) and operators (+, -, *, /, ^), all\n"
         "expressions can contain the symbols v0, v1, v2,\n"
         " ..., vn, which represent the n components of the\n"
         "field, and the symbols x, y and z, which represent\n"
         "the three spatial coordinates. If `TimeStep' < 0,\n"
         "the plugin extracts data from all the time steps\n"
         "in the view. If `iView' < 0, the plugin is run on\n"
         "the current view.\n"
         "\n"
         "Plugin(Extract) creates one new view.\n";
Christophe Geuzaine's avatar
Christophe Geuzaine committed
}

int GMSH_ExtractPlugin::getNbOptions() const
{
  return sizeof(ExtractOptions_Number) / sizeof(StringXNumber);
}

StringXNumber *GMSH_ExtractPlugin::getOption(int iopt)
{
  return &ExtractOptions_Number[iopt];
}

Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
int GMSH_ExtractPlugin::getNbOptionsStr() const
{
  return sizeof(ExtractOptions_String) / sizeof(StringXString);
}

StringXString *GMSH_ExtractPlugin::getOptionStr(int iopt)
{
  return &ExtractOptions_String[iopt];
}

static std::vector<double> *incrementList(PViewDataList *data, int numComp, 
Christophe Geuzaine's avatar
Christophe Geuzaine committed
{
    if     (numComp == 1){ data->NbSP++; return &data->SP; }
    else if(numComp == 3){ data->NbVP++; return &data->VP; }
    else if(numComp == 9){ data->NbTP++; return &data->TP; }
    if     (numComp == 1){ data->NbSL++; return &data->SL; }
    else if(numComp == 3){ data->NbVL++; return &data->VL; }
    else if(numComp == 9){ data->NbTL++; return &data->TL; }
    if     (numComp == 1){ data->NbST++; return &data->ST; }
    else if(numComp == 3){ data->NbVT++; return &data->VT; }
    else if(numComp == 9){ data->NbTT++; return &data->TT; }
    if     (numComp == 1){ data->NbSQ++; return &data->SQ; }
    else if(numComp == 3){ data->NbVQ++; return &data->VQ; }
    else if(numComp == 9){ data->NbTQ++; return &data->TQ; }
    if     (numComp == 1){ data->NbSS++; return &data->SS; }
    else if(numComp == 3){ data->NbVS++; return &data->VS; }
    else if(numComp == 9){ data->NbTS++; return &data->TS; }
    if     (numComp == 1){ data->NbSH++; return &data->SH; }
    else if(numComp == 3){ data->NbVH++; return &data->VH; }
    else if(numComp == 9){ data->NbTH++; return &data->TH; }
    if     (numComp == 1){ data->NbSI++; return &data->SI; }
    else if(numComp == 3){ data->NbVI++; return &data->VI; }
    else if(numComp == 9){ data->NbTI++; return &data->TI; }
    if     (numComp == 1){ data->NbSY++; return &data->SY; }
    else if(numComp == 3){ data->NbVY++; return &data->VY; }
    else if(numComp == 9){ data->NbTY++; return &data->TY; }
Christophe Geuzaine's avatar
Christophe Geuzaine committed

PView *GMSH_ExtractPlugin::execute(PView *view)
{
  int timeStep = (int)ExtractOptions_Number[0].def;
  int iView = (int)ExtractOptions_Number[1].def;
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  std::vector<std::string> expr(9);
  for(int i = 0; i < 9; i++) expr[i] = ExtractOptions_String[i].def;
  
  PView *v1 = getView(iView, view);
  if(!v1) return view;
  PViewData *data1 = v1->getData();

  if(data1->hasMultipleMeshes()){
    Msg::Error("Extract plugin cannot be applied to multi-mesh views");
    return view;
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  if(expr[3].size() || expr[4].size() || expr[5].size() || 
     expr[6].size() || expr[7].size() || expr[8].size()){
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
    for(int i = 0; i < 9; i++)
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
      if(expr[i].empty()) expr[i] = "0";
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  }
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  else if(expr[1].size() || expr[2].size()){
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
    for(int i = 0; i < 3; i++)
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
      if(expr[i].empty()) expr[i] = "0";
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  }
  else{
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  }
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  expr.resize(numComp2);

  const char *names[] = 
    { "x", "y", "z", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8" };
  unsigned int numVariables = sizeof(names) / sizeof(names[0]);
  std::vector<std::string> variables(numVariables);
  for(unsigned int i = 0; i < numVariables; i++) variables[i] = names[i];
  mathEvaluator f(expr, variables);
  if(expr.empty()) return view;
  std::vector<double> values(numVariables), res(numComp2);
          
  PView *v2 = new PView();
  PViewDataList *data2 = getDataList(v2);

  if(timeStep < 0){
    timeStep = - data1->getNumTimeSteps();
  }
  else if(timeStep > data1->getNumTimeSteps() - 1){
    Msg::Error("Invalid time step (%d) in View[%d]: using all steps instead",
               timeStep, v1->getIndex());
    timeStep = - data1->getNumTimeSteps();
  }
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed

  for(int ent = 0; ent < data1->getNumEntities(0); ent++){
    for(int ele = 0; ele < data1->getNumElements(0, ent); ele++){
      if(data1->skipElement(0, ent, ele)) continue;
      int numNodes = data1->getNumNodes(0, ent, ele);
      int numComp = data1->getNumComponents(0, ent, ele);
      std::vector<double> *out = incrementList(data2, numComp2, type);
      std::vector<double> x(numNodes), y(numNodes), z(numNodes);
      for(int nod = 0; nod < numNodes; nod++)
        data1->getNode(0, ent, ele, nod, x[nod], y[nod], z[nod]);
      for(int nod = 0; nod < numNodes; nod++) out->push_back(x[nod]); 
      for(int nod = 0; nod < numNodes; nod++) out->push_back(y[nod]); 
      for(int nod = 0; nod < numNodes; nod++) out->push_back(z[nod]); 
      int timeBeg = (timeStep < 0) ? 0 : timeStep;
      int timeEnd = (timeStep < 0) ? -timeStep : timeStep + 1;
      for(int step = timeBeg; step < timeEnd; step++){
        for(int nod = 0; nod < numNodes; nod++){
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
          std::vector<double> v(std::max(9, numComp), 0.);
          for(int comp = 0; comp < numComp; comp++)
            data1->getValue(step, ent, ele, nod, comp, v[comp]);
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
          values[0] = x[nod]; values[1] = y[nod]; values[2] = z[nod];
          for(int i = 0; i < 9; i++) values[3 + i] = v[i];
          if(f.eval(values, res))
            for(int i = 0; i < numComp2; i++)
              out->push_back(res[i]);
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
        }
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
      }
    }
Christophe Geuzaine's avatar
Christophe Geuzaine committed
  }
  
  if(timeStep < 0){
    for(int i = 0; i < data1->getNumTimeSteps(); i++)
      data2->Time.push_back(data1->getTime(i));
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  }
  else
    data2->Time.push_back(data1->getTime(timeStep));
        
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  data2->setName(data1->getName() + "_Extract");
  data2->setFileName(data1->getName() + "_Extract.pos");
  data2->finalize();

Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  return v2;
Christophe Geuzaine's avatar
Christophe Geuzaine committed
}