Skip to content
Snippets Groups Projects
Field.cpp 68.5 KiB
Newer Older
Christophe Geuzaine's avatar
Christophe Geuzaine committed
// Gmsh - Copyright (C) 1997-2013 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
Christophe Geuzaine's avatar
Christophe Geuzaine committed
// bugs and problems to the public mailing list <gmsh@geuz.org>.
//
// Contributor(s):
//   Jonathan Lambrechts
//
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed

#include <stdlib.h>
#include <list>
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
#include <math.h>
#include <fstream>
#include <string>
#include <string.h>
#include <sstream>
#include "Context.h"
#include "Field.h"
#include "GeoInterpolation.h"
#include "GModel.h"
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
#include "mathEvaluator.h"
#include "BackgroundMesh.h"
#include "CenterlineField.h"
#include "STensor3.h"
Christophe Geuzaine's avatar
Christophe Geuzaine committed
#include "meshMetric.h"
#if defined(HAVE_POST)
#include "PView.h"
#include "OctreePost.h"
#include "PViewDataList.h"
#include "MVertex.h"
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed

Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
#if defined(HAVE_ANN)
#include "ANN/ANN.h"
#endif

Christophe Geuzaine's avatar
Christophe Geuzaine committed
Field::~Field()
{
  for(std::map<std::string, FieldOption*>::iterator it = options.begin();
      it != options.end(); ++it)
    delete it->second;
Christophe Geuzaine's avatar
Christophe Geuzaine committed
  for(std::map<std::string, FieldCallback*>::iterator it = callbacks.begin();
      it != callbacks.end(); ++it)
    delete it->second;
}

FieldOption *Field::getOption(const std::string optionName)
{
  std::map<std::string, FieldOption*>::iterator it = options.find(optionName);
  if (it == options.end()) {
    Msg::Error("field option :%s does not exist", optionName.c_str());
    return NULL;
  }
  return it->second;
}

Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
void FieldManager::reset()
{
  for(std::map<int, Field *>::iterator it = begin(); it != end(); it++) {
    delete it->second;
  }
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
Field *FieldManager::get(int id)
{
  iterator it = find(id);
  if(it == end()) return NULL;
  return it->second;
}
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed

Field *FieldManager::newField(int id, std::string type_name)
Jean-François Remacle's avatar
Jean-François Remacle committed
  if(find(id) != end()) {
Christophe Geuzaine's avatar
pp  
Christophe Geuzaine committed
    Msg::Error("Field id %i is already defined", id);
Jean-François Remacle's avatar
Jean-François Remacle committed
  }
  if(map_type_name.find(type_name) == map_type_name.end()) {
Christophe Geuzaine's avatar
pp  
Christophe Geuzaine committed
    Msg::Error("Unknown field type \"%s\"", type_name.c_str());
Jean-François Remacle's avatar
Jean-François Remacle committed
  }
  Field *f = (*map_type_name[type_name]) ();
  if(!f)
Jean-François Remacle's avatar
Jean-François Remacle committed
  f->id = id;
  (*this)[id] = f;
int FieldManager::newId()
Jean-François Remacle's avatar
Jean-François Remacle committed
{
  int i = 0;
  iterator it = begin();
  while(1) {
    i++;
    while(it != end() && it->first < i)
      it++;
    if(it == end() || it->first != i)
      break;
  }
  return std::max(i, 1);
int FieldManager::maxId()
Jean-François Remacle's avatar
Jean-François Remacle committed
{
  if(!empty())
    return rbegin()->first;
  else
    return 0;
void FieldManager::deleteField(int id)
Jean-François Remacle's avatar
Jean-François Remacle committed
{
  iterator it = find(id);
  if(it == end()) {
Christophe Geuzaine's avatar
pp  
Christophe Geuzaine committed
    Msg::Error("Cannot delete field id %i, it does not exist", id);
Jean-François Remacle's avatar
Jean-François Remacle committed
    return;
  }
  delete it->second;
  erase(it);
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
// StructuredField
class StructuredField : public Field
  double o[3], d[3];
  int n[3];
  double *data;
Jean-François Remacle's avatar
Jean-François Remacle committed
  bool error_status;
  bool text_format, outside_value_set;
  double outside_value;
Jean-François Remacle's avatar
Jean-François Remacle committed
  std::string file_name;
 public:
  StructuredField()
Jean-François Remacle's avatar
Jean-François Remacle committed
  {
    options["FileName"] = new FieldOptionPath
      (file_name, "Name of the input file", &update_needed);
      (text_format, "True for ASCII input files, false for binary files (4 bite "
Christophe Geuzaine's avatar
Christophe Geuzaine committed
       "signed integers for n, double precision floating points for v, D and O)",
    options["SetOutsideValue"] = new FieldOptionBool(outside_value_set, "True to use the \"OutsideValue\" option. If False, the last values of the grid are used.");
    options["OutsideValue"] = new FieldOptionDouble(outside_value, "Value of the field outside the grid (only used if the \"SetOutsideValue\" option is true).");
Jean-François Remacle's avatar
Jean-François Remacle committed
  }
  std::string getDescription()
    return "Linearly interpolate between data provided on a 3D rectangular "
      "structured grid.\n\n"
      "The format of the input file is:\n\n"
      "  Ox Oy Oz \n"
      "  Dx Dy Dz \n"
      "  nx ny nz \n"
      "  v(0,0,0) v(0,0,1) v(0,0,2) ... \n"
      "  v(0,1,0) v(0,1,1) v(0,1,2) ... \n"
      "  v(0,2,0) v(0,2,1) v(0,2,2) ... \n"
      "  ...      ...      ... \n"
      "  v(1,0,0) ...      ... \n\n"
      "where O are the coordinates of the first node, D are the distances "
      "between nodes in each direction, n are the numbers of nodes in each "
      "direction, and v are the values on each node.";
  const char *getName()
Jean-François Remacle's avatar
Jean-François Remacle committed
  {
    return "Structured";
  }
  virtual ~StructuredField()
  {
    if(data) delete[]data;
Jean-François Remacle's avatar
Jean-François Remacle committed
  }
  double operator() (double x, double y, double z, GEntity *ge=0)
Jean-François Remacle's avatar
Jean-François Remacle committed
  {
    if(update_needed) {
      error_status = false;
      try {
        std::ifstream input;
        if(text_format)
          input.open(file_name.c_str());
        else
          input.open(file_name.c_str(),std::ios::binary);
Jean-François Remacle's avatar
Jean-François Remacle committed
        if(!input.is_open())
          throw(1);
        input.
          exceptions(std::ifstream::eofbit | std::ifstream::failbit | std::
                     ifstream::badbit);
        if(!text_format) {
          input.read((char *)o, 3 * sizeof(double));
          input.read((char *)d, 3 * sizeof(double));
          input.read((char *)n, 3 * sizeof(int));
          int nt = n[0] * n[1] * n[2];
          if(data)
            delete[]data;
          data = new double[nt];
          input.read((char *)data, nt * sizeof(double));
        }
        else {
Loading
Loading full blame...