コード例 #1
0
ファイル: MinMax.cpp プロジェクト: glickenstein/geocam
double FE(double deltaEta, int index)
{
   Approximator* app = new EulerApprox( (sysdiffeq) Yamabe, "r3");
   Eta* eta = Eta::At(Triangulation::edgeTable[index]);
   double curEta = eta->getValue();
   eta->setValue(curEta + deltaEta);
   vector<double> radii;
   vector<double> curvs;
   double initRadii[Triangulation::vertexTable.size()];

   double dt = 0.030;
   double precision = 0.000000001;
   
   getRadii(initRadii);
   app->run(precision, dt);
   double result = F();
   eta->setValue(curEta);
   setRadii(initRadii);
   return result;
}
コード例 #2
0
ファイル: plot_main.cpp プロジェクト: cbrunschen/MorphPlot
int main(int argc, char * const argv[]) {
  bool steps = false;
  string stepPrefix = "/tmp/steps";
  bool approximate = false;
  string approximationFilename;

  typedef uint8_t C;
  typedef ColorImage<C> ColorImage;
  typedef shared_ptr<ColorImage> ColorImageRef;
  typedef RGBPixel<C> RGBPixel;
  typedef GreyImage<C> GreyImage;
  typedef shared_ptr<GreyImage> GreyImageRef;
  typedef PenColor<C> PenColor;
  typedef Pen<C> Pen;
  typedef Carousel<C> Carousel;

  Carousel carousel;
  list< Output<Pen>* > outputs;
  int argn = 1;
  size_t equals = string::npos;
  Rotation rotation = None;
  int offsetX = 0, offsetY = 0;
  double scale = 1.0;
  bool dither = true;
  int threads = 1;

  for (; argn < argc && argv[argn][0] == '-' && strlen(argv[argn]) > 1; argn++) {
    string arg(argv[argn]);
    D(cerr << "arg[" << argn << "] == '" << arg << "'" << endl << flush);
    string penSpec;
    if (0 == arg.find("-pen")) {
      Pen pen;
      if (4 == arg.find("=")) {
        penSpec = arg.substr(5);
      } else {
        ++argn;
        if (!(argn < argc)) {
          cerr << "missing argument to '-pen'" << endl << flush;
          exit(1);
        }
        penSpec = argv[argn];
      }
      size_t start = 0;
      while (start != string::npos) {
        D(cerr << "start=" << start << endl << flush);
        size_t comma = penSpec.find(',', start);
        string part;
        if (comma != string::npos) {
          part = penSpec.substr(start, comma - start);
          start = comma + 1;
        } else {
          part = penSpec.substr(start);
          start = string::npos;
        }
        D(cerr << "part='" << part << "'" << endl << flush);

        if ((equals = part.find('=')) == string::npos) {
          cerr << "pen specification part '" << part << "' missing '='" << endl << flush;
          exit(1);
        } else {
          string name = part.substr(0, equals);
          string value = part.substr(equals + 1);
          D(cerr << "name='" << name << "', value='" << value << "'" << endl << flush);
          switch(name[0]) {
            case 'c': // colour
              pen.color() = PenColor::parse(value);
              break;

            case 'r': // radius
              pen.r() = getInt(value);
              break;

            case 'm': // minimum size that can be drawn
              pen.rMin() = getInt(value);
              break;

            case 'i': // HPGL Index
              pen.hpglIndex() = getInt(value);
              break;

            case 'a': // hatch angle
              pen.hatchAngle() = getDouble(value);
              break;

            case 'p': // hatch phase
              pen.hatchPhase() = getDouble(value);
              break;
          }
        }
      }

      // now add this pen to the carousel
      carousel.addPen(pen);
    } else if (0 == arg.find("-rotate")) {
      string rotationSpec;
      if (7 == arg.find("=")) {
        rotationSpec = arg.substr(8);
      } else {
        ++argn;
        if (!(argn < argc)) {
          cerr << "missing argument to '-rotate'" << endl << flush;
          exit(1);
        }
        rotationSpec = argv[argn];
      }

      switch (rotationSpec[0]) {
        case 'l':
        case 'L':
          rotation = Left;
          break;
        case 'r':
        case 'R':
          rotation = Right;
          break;
        case 'u':
        case 'U':
          rotation = UpsideDown;
          break;
        default:
          cerr << "unrecognized rotation '" << arg << "'" << endl << flush;
          exit(1);
      }
    } else if (0 == arg.find("-offset")) {
      string offset;
      if (7 == arg.find("=")) {
        offset = arg.substr(8);
      } else {
        ++argn;
        if (!(argn < argc)) {
          cerr << "missing argument to '-offset'" << endl << flush;
          exit(1);
        }
        offset = argv[argn];
      }
      size_t delim = offset.find_first_of("x,");
      if (delim == string::npos) {
        // no delimiter - offset both x & y by the same amount
        offsetX = offsetY = getInt(offset);
      } else {
        offsetX = getInt(offset.substr(0, delim));
        offsetY = getInt(offset.substr(delim+1));
      }
    } else if (0 == arg.find("-steps")) {
      steps = true;
      if (6 == arg.find("=")) {
        stepPrefix = arg.substr(7);
      }
    } else if (0 == arg.find("-approx")) {
      approximate = true;
      if (7 == arg.find("=")) {
        approximationFilename = arg.substr(8);
      } else {
        approximationFilename = "approximation.png";
      }
    } else if (0 == arg.find("-nodither")) {
      dither = false;
    } else if (0 == arg.find("-out")) {
      size_t eqPos;
      string outputFile;
      if (string::npos != (eqPos = arg.find("="))) {
        outputFile = arg.substr(eqPos + 1);
        arg = arg.substr(0, eqPos);
      } else {
        ++argn;
        if (!(argn < argc)) {
          cerr << "missing argument to '" << arg << "'" << endl << flush;
          exit(1);
        }
        outputFile = argv[argn];
      }
      string outputType = arg.substr(4);
      if (0 == outputType.length()) {
        outputType = "ha"; // HPGL, absolute coordinates
      }
      std::transform(outputType.begin(), outputType.end(), outputType.begin(), ::tolower);
      outputs.push_back(makeOutput<Pen>(outputType, outputFile));
    } else if (0 == arg.find("-scale")) {
      string scaleString;
      if (6 == arg.find("=")) {
        scaleString = arg.substr(7);
      } else {
        ++argn;
        if (!(argn < argc)) {
          cerr << "missing argument to '-scale'" << endl << flush;
          exit(1);
        }
        scaleString = argv[argn];
      }
      scale = getDouble(scaleString);
    } else if (0 == arg.find("-threads")) {
      string threadsArg;
      if (8 == arg.find("=")) {
        threadsArg = arg.substr(9);
      } else {
        ++argn;
        if (!(argn < argc)) {
          cerr << "missing argument to '-threads'" << endl << flush;
          exit(1);
        }
        threadsArg = argv[argn];
      }
      threads = getInt(threadsArg);
    } else {
      cerr << "Unrecognized argument '" << arg << "'" << endl << flush;
      exit(1);
    }
  }

  string inputFile;

  if (argn == argc - 1) {
    inputFile = argv[argn];
  } else if (argn == argc) {
    // default: is
    inputFile = "-";
  } else {
    cerr << "Extra arguments after input file '" << argv[argn] << "'!";
    cerr << endl << flush;
    exit(1);
  }

  // If there's no specified carousel, use a default one.
  if (carousel.size() == 0) {
    cerr << "No pens specified, using default carousel" << endl << flush;
    // populate the carousel with a default set of pens:
    // black, red, green blue, cyan, magenta, yellow, orange;
    // each at 0.35 mm diameter = 0.175 mm radius = 7 units radius
    Pen black(1.0, 1.0, 1.0, 3); black.hpglIndex() = 1; black.hatchAngle() = 1.0 / 25.0;
    Pen red(0.0, 1.0, 1.0, 3); red.hpglIndex() = 2; red.hatchAngle() = 4.0 / 25.0;
    Pen green(1.0, 0.0, 1.0, 3); green.hpglIndex() = 3; green.hatchAngle() = 7.0 / 25.0;
    Pen blue(1.0, 1.0, 0.0, 3); blue.hpglIndex() = 4; blue.hatchAngle() = 10.0 / 25.0;
    Pen orange(0.0, 0.5, 1.0, 3); orange.hpglIndex() = 8; orange.hatchAngle() = 13.0 / 25.0;
    Pen cyan(1.0, 0.0, 0.0, 3); cyan.hpglIndex() = 5; cyan.hatchAngle() = 16.0 / 25.0;
    Pen magenta(0.0, 1.0, 0.0, 3); magenta.hpglIndex() = 6; magenta.hatchAngle() = 19.0 / 25.0;
    Pen yellow(0.0, 0.0, 1.0, 3); yellow.hpglIndex() = 7; yellow.hatchAngle() = 22.0 / 25.0;

    // put the pens into the carousel in a suitable order
    carousel.addPen(black);
    carousel.addPen(orange);
    carousel.addPen(red);
    carousel.addPen(green);
    carousel.addPen(blue);
    carousel.addPen(cyan);
    carousel.addPen(magenta);
    carousel.addPen(yellow);
  }

  // if there's no output specified, use a default one.
  if (outputs.size() == 0) {
    cerr << "No output specified, writing HPGL to standard output" << endl << flush;
    outputs.push_back(new HPGLAbsoluteOutput<Pen>(cout));
  }

  FILE *f;
  if ("-" == inputFile) {
    cerr << "* Reading image from standard input" << endl << flush;
    f = stdin;
  } else {
    cerr << "* Reading image '" << inputFile << "'" << endl << flush;

    f = fopen(inputFile.c_str(), "r");
    if (f == NULL) {
      cerr << "unable to open input file '" << inputFile << "'!" << endl << flush;
      exit(1);
    }
  }
  ColorImageRef colored(ColorImage::readPng(f));
  if (scale != 1.0) {
    colored = scaleImage(colored, scale);
  }
  Approximator *approximator = NULL;

  if (approximate) {
    approximator = new Approximator(colored->width(), colored->height());
    approximator->approximation().copyRes(colored);
    RGBPixel whitePixel(1.0, 1.0, 1.0);
    approximator->approximation().setAll(whitePixel);
  }

  map<Pen, Chains> ditheredByPen;

  double dTheta = 1.0 / carousel.size();
  double theta = 0.1;

  PlotterPathExtractor extractor;
  shared_ptr<Workers> workers = make_shared<Workers>(threads);
  extractor.setOut(&cerr);
  extractor.setDither(dither);
  extractor.setWorkers(workers);
  Stepper *stepper;
  if (steps) {
    extractor.setStepper(stepper = new Stepper(stepPrefix));
  }
  if (approximate) {
    extractor.setApproximator(approximator);
  }

  int p = 0;
  for (Carousel::iterator c = carousel.begin(); c != carousel.end(); ++c) {
    const PenColor &color = *c;
    cerr << "- Separating out colour " << color << endl;
    GreyImageRef separated = colored->separateAndSubtract(color);
    if (steps) {
      cerr << "  . writing separation" << endl;
      separated->writePng(stepper->makeName("separation.png", color.unparse().c_str()));
    }

    if (approximate) {
      approximator->setPenColor(color);
    }

    list<Pen> &pens = carousel.pensWithColor(color);
    extractor.outlineHatchThinDither(separated, pens, ditheredByPen);

    ++p;
    theta += dTheta;
  }

  IMatrix transform = IMatrix::identity();

  cerr << "initial transform: " << transform << endl << flush;

  cerr << "offsetX = " << offsetX << ", offsetY = " << offsetY << endl << flush;
  if (offsetX != 0 || offsetY != 0) {
    transform = transform.concat(IMatrix::translate(offsetX, offsetY));
  }
  cerr << "after offset: " << transform << endl << flush;

  cerr << "rotation = " << rotation << endl << flush;
  if (rotation == Left) {
    transform = transform.concat(IMatrix::pageLeft(colored->width(), colored->height()));
  } else if (rotation == Right) {
    transform = transform.concat(IMatrix::pageRight(colored->width(), colored->height()));
  } else if (rotation == UpsideDown) {
    transform = transform.concat(IMatrix::pageUpsideDown(colored->width(), colored->height()));
  }
  cerr << "after rotation: " << transform << endl << flush;

  int maxX = numeric_limits<int>::min(), maxY = numeric_limits<int>::min();
  int minX = numeric_limits<int>::max(), minY = numeric_limits<int>::max();
  for (int x = 0; x < colored->width(); x += colored->width()-1) {
    for (int y = 0; y < colored->height(); y += colored->height()-1) {
      IPoint p(x, y);
      p.transform(transform);
      minX = min(p.x(), minX);
      maxX = max(p.x(), maxX);
      minY = min(p.y(), minY);
      maxY = max(p.y(), maxY);
    }
  }

  cerr << "minX = " << minX << ", minY = " << minY << ", maxX = " << maxX << ", maxY = " << maxY << endl << flush;

  // Finally, adjust for the top-to-bottom Y of our bitmaps
  // vs the bottom-to-top Y of our output devices
  IMatrix adjustment(1, 0, 0, -1, 0, colored->height());
  transform = transform.concat(adjustment);
  cerr << "after adjustment: " << transform << endl << flush;

  for (list< Output<Pen>* >::const_iterator outIter = outputs.begin();
       outIter != outputs.end(); ++outIter) {
    cerr << "Writing " << (**outIter) << endl << flush;
    (*outIter)->open();
    (*outIter)->beginPage(maxX + 1, maxY + 1);
  }

  for (map<Pen, Chains>::iterator di = ditheredByPen.begin(); di != ditheredByPen.end(); ++di) {
    const Pen &pen = di->first;
    Chains &dithered = di->second;

    if (transform != IMatrix::identity()) {
      cerr << "- applying transform " << transform << endl << flush;
      dithered.transform(transform);
    } else {
      cerr << "-  skipping identity transform " << transform << endl << flush;
    }

    for (list< Output<Pen>* >::const_iterator outIter = outputs.begin();
         outIter != outputs.end(); ++outIter) {
      (*outIter)->setPen(pen);
      (*outIter)->outputChains(dithered);
    }
  }

  for (list< Output<Pen>* >::const_iterator outIter = outputs.begin();
       outIter != outputs.end(); ++outIter) {
    (*outIter)->endPage();
    (*outIter)->close();
    delete (*outIter);
  }
  outputs.clear();

  if (approximate) {
    cerr << "    . drawing final approximation" << endl;
    approximator->approximation().writePng(approximationFilename.c_str());

    delete approximator;
    approximator = NULL;
  }
}
コード例 #3
0
int ribi::tapx::MenuDialog::ExecuteSpecific(const std::vector<std::string>& /*argv*/) noexcept
{
  //Use Boost.Units to thoroughly check if Approximation is a good template:
  //If it even compiles with Boost.Units, it probably is
  {
    typedef boost::units::quantity<boost::units::si::time> Time;
    typedef boost::units::quantity<boost::units::si::velocity> Velocity;
    Approximator<Time,Velocity> a;
    a.Add(0.0 * boost::units::si::second,0.0 * boost::units::si::meters_per_second);
    a.Add(2.0 * boost::units::si::second,2.0 * boost::units::si::meters_per_second);
    #ifndef NDEBUG
    const Velocity v = a.Approximate(1.0 * boost::units::si::second);
    assert(v >= 0.99 * boost::units::si::meters_per_second
        && v <= 1.01 * boost::units::si::meters_per_second);
    #endif
  }

  typedef Approximator<double,int> Approximator_t;
  Approximator_t a;
  a.Add(20, 5);
  a.Add(30,15);
  a.Add(40, 5);
  a.Add(50,15);

  const int max_x = 78;
  const int max_y = 20;
  DrawCanvas c(
    max_x,
    max_y,
    CanvasColorSystem::invert,
    CanvasCoordinatSystem::graph
  );
  c.DrawLine(0.0,0.0,max_x,0.0);
  c.DrawLine(0.0,0.0,0.0,max_y);

  //Plot values (note: these won't be visible in Canvas)
  {
    std::vector<double> xs;
    std::vector<double> ys;
    for (const auto& p: a.Get())
    {
      c.DrawDot(
        static_cast<double>(p.first),
        static_cast<double>(p.second)
      );
    }
  }

  //Plot approximation
  {
    for (int t=0; t != max_x; ++t)
    {
      try
      {
        const double x = static_cast<double>(t);
        const double y = a.Approximate(x);
        c.DrawDot(x,y);
      }
      catch (ExceptionNoExtrapolation<Approximator_t::key_type>& e)
      {
        //X value not in range. OK not to plot then...
      }
    }
  }
  std::cout << c << std::endl;
  return 0;
}
コード例 #4
0
ファイル: uniformize.cpp プロジェクト: glickenstein/geocam
int main(int argc, char** argv) {
   map<int, Vertex>::iterator vit;
   map<int, Edge>::iterator eit;
   map<int, Face>::iterator fit;
        
   vector<int> edges;
   vector<int> faces;
    
   
   time_t start, end;
   
   // File to read in triangulation from.
   char from[] = "Data/2DManifolds/LutzFormat/domain2.txt";
   // File to convert to proper format.
   char to[] = "Data/2DManifolds/StandardFormat/domain2.txt";
   // Convert, then read in triangulation.
   makeTriangulationFile(from, to);
   readTriangulationFileWithData(to);
writeTriangulationFile("fudge.txt");
   int vertSize = Triangulation::vertexTable.size();
   int edgeSize = Triangulation::edgeTable.size();
   int faceSize = Triangulation::faceTable.size();
   
   
   // Set the radii and alphas
   for(int i = 1; i <= vertSize; i++) {
      Radius::At(Triangulation::vertexTable[i])->setValue(1.0 ) ;        
      Alpha::At(Triangulation::vertexTable[i])->setValue(0.0 );
        printf("alph= %f\n",Alpha::valueAt(Triangulation::vertexTable[i]));
   }
   Radius::At(Triangulation::vertexTable[6])->setValue(1.0 ) ;
   Radius::At(Triangulation::vertexTable[7])->setValue(1.0 ) ;
   Radius::At(Triangulation::vertexTable[8])->setValue(1.2 ) ;
   Radius::At(Triangulation::vertexTable[9])->setValue(90.0 ) ;
   Alpha::At(Triangulation::vertexTable[9])->setValue(1.0 ) ;
   // Set the etas
  // for(int i = 1; i <= edgeSize; i++) {
//   if ((Triangulation::edgeTable[i]).isAdjVertex(9)) {
//       Eta::At(Triangulation::edgeTable[i])->setValue(-1.0);}
//       else {
//       Eta::At(Triangulation::edgeTable[i])->setValue(1.0);}
//   printf("%f\n",Eta::valueAt(Triangulation::edgeTable[i]));
//   }

for(int i = 1; i <= edgeSize; i++) {
   if ((Triangulation::edgeTable[i]).isAdjVertex(9)) {
       Eta::At(Triangulation::edgeTable[i])->setValue(0.0);}
       else {
       Eta::At(Triangulation::edgeTable[i])->setValue(1.0);}
}
  Eta::At(Triangulation::edgeTable[2])->setValue(0.5);
Eta::At(Triangulation::edgeTable[3])->setValue(0.5);
Eta::At(Triangulation::edgeTable[5])->setValue(0.5);
Eta::At(Triangulation::edgeTable[7])->setValue(0.5);
Eta::At(Triangulation::edgeTable[8])->setValue(4.5);
Eta::At(Triangulation::edgeTable[9])->setValue(2.5);
Eta::At(Triangulation::edgeTable[10])->setValue(2.0);
Eta::At(Triangulation::edgeTable[13])->setValue(4.5);
Eta::At(Triangulation::edgeTable[14])->setValue(5.0);
Eta::At(Triangulation::edgeTable[15])->setValue(2.0);
Eta::At(Triangulation::edgeTable[16])->setValue(0.5);

   // Construct an Approximator object that uses the Euler method and Ricci flow while
   // recording radii, curvatures.
   for(int i = 1; i <= faceSize; i++) {
   if ((Triangulation::faceTable[i]).isAdjVertex(9)) {
       (Triangulation::faceTable[i]).setNegativity(true); printf("hi");}
       }
 writeTriangulationFileWithData("initdata.txt"); 
 printf("degree of 1 =%d\n",(Triangulation::vertexTable[1]).getDegree());
   Approximator *app = new EulerApprox((sysdiffeq) Ricci, "rfnew");

   // Run the flow with precision and accuracy bounds of 0.0001 and stepsize of 0.01
   app->run(6000, 0.001);
 writeTriangulationFileWithData("trydata.txt");
   // Print out radii, curvatures and volumes
  printResultsStep("./ODE Result.txt", &(app->radiiHistory), &(app->curvHistory));
   system("Pause");
   return 0;
}
void ribi::QtToolTestMultiApproximatorMainDialog::Plot() noexcept
{
  //Plot multi approximation
  {
    //Plot raw data
    {
      std::vector<double> xs;
      std::vector<double> ys;
      for (const auto p: m_multi_approximator.GetContainer())
      {
        xs.push_back( static_cast<double>(p.first) );
        ys.push_back( static_cast<double>(p.second) );
      }
      assert(m_curve_multi_values);
      #if QWT_VERSION >= 0x060000
      m_curve_multi_values->setData(new QwtPointArrayData(&xs[0],&ys[0],xs.size()));
      #else
      m_curve_values->setData(&xs[0],&y[0],xs.size());
      #endif
    }

    const double min_x = static_cast<double>(ui->box_int_x->minimum());
    const double max_x = static_cast<double>(ui->box_int_x->maximum());

    //Plot approximation
    {
      std::vector<double> xs;
      std::vector<double> ys;
      for (double t=min_x; t < max_x; t+=0.5)
      {
        try
        {
          const double x = static_cast<double>(t);
          const MultiApproximator_t::value_type y = m_multi_approximator.Approximate(x);
          ys.push_back(y);
          xs.push_back(x);
        }
        catch (ExceptionNoExtrapolation<MultiApproximator_t::key_type>& e)
        {

        }
      }
      assert(m_curve_multi_approximation);
      #if QWT_VERSION >= 0x060000
      m_curve_multi_approximation->setData(new QwtPointArrayData(&xs[0],&ys[0],xs.size()));
      #else
      m_curve_multi_approximation->setData(&xs[0],&y[0],xs.size());
      #endif
    }
    assert(m_multi_plot);
    m_multi_plot->replot();
  }
  //Plot (non-multi)approximation
  {
    const Approximator<Key,Value,Container> approximator
      = ToApproximator<Key,Value,MultiContainer,Container>(m_multi_approximator);
    //Plot raw data
    {
      std::vector<double> xs;
      std::vector<double> ys;
      for (const auto p: approximator.Get())
      {
        xs.push_back( static_cast<double>(p.first) );
        ys.push_back( static_cast<double>(p.second) );
      }
      assert(m_curve_values);
      #if QWT_VERSION >= 0x060000
      m_curve_values->setData(new QwtPointArrayData(&xs[0],&ys[0],xs.size()));
      #else
      m_curve_values->setData(&xs[0],&y[0],xs.size());
      #endif
    }

    const double min_x = static_cast<double>(ui->box_int_x->minimum());
    const double max_x = static_cast<double>(ui->box_int_x->maximum());

    //Plot approximation
    {
      std::vector<double> xs;
      std::vector<double> ys;
      for (double t=min_x; t < max_x; t+=0.5)
      {
        try
        {
          const double x = static_cast<double>(t);
          const Approximator_t::value_type y = approximator.Approximate(x);
          ys.push_back(y);
          xs.push_back(x);
        }
        catch (ExceptionNoExtrapolation<Approximator_t::key_type>& e)
        {

        }
      }
      assert(m_curve_approximation);
      #if QWT_VERSION >= 0x060000
      m_curve_approximation->setData(new QwtPointArrayData(&xs[0],&ys[0],xs.size()));
      #else
      m_curve_approximation->setData(&xs[0],&y[0],xs.size());
      #endif
    }
    assert(m_plot);
    m_plot->replot();
  }
}
コード例 #6
0
ファイル: MinMax.cpp プロジェクト: glickenstein/geocam
void MinMax(double deltaEta, double b, double a)
{
   Approximator* app = new EulerApprox( (sysdiffeq) Yamabe, "r3");                
   char results[] = "Triangulation Files/ODE Result.txt";
   FILE* result = fopen(results, "w");
   map<int, double> deltaFE;
   map<int, Edge>::iterator eit;
   map<int, Tetra>::iterator tit;
   double initRadii[Triangulation::vertexTable.size()];

   double dt = 0.030;
   double precision = 0.000000001;


   for(eit = Triangulation::edgeTable.begin(); eit != Triangulation::edgeTable.end(); eit++) {
       deltaFE.insert(pair<int, double>(eit->first, 0));
   }
   map<int, double>::iterator dfit;
   
   app->run(precision, dt);
   printf("F = %.10f\n", F());
   calcDeltaFE(&deltaFE, deltaEta);
   double length = 0;
   for(dfit = (deltaFE).begin(); dfit != (deltaFE).end(); dfit++)
   {
//      printf("MinMax FE: Index = %3d, Value = %.10f\n", dfit->first, dfit->second);
      length += pow(dfit->second, 2);
   }
     length = sqrt(length);
     printf("\nGradient Length: %.10f\n", length);
   printf("\n");
   updateEtas(&deltaFE, b, a);
   printData(result);
   
while(true) {
       for(eit = Triangulation::edgeTable.begin(); eit != Triangulation::edgeTable.end(); eit++)
                {
                printf("Edge %3d: %.10f\n", eit->first, Eta::valueAt(eit->second));
                } 
      double totalvolume=0;
      for(tit = Triangulation::tetraTable.begin(); tit != Triangulation::tetraTable.end(); tit++)
      {
              printf("Tetrahedron %d: %.10f\n", tit->first, Volume::valueAt(tit->second));
              totalvolume += Volume::valueAt(tit->second) ;
              }
              printf("Total Volume = %.10f\n", totalvolume);
                          
      //updateEtas(&deltaFE, b);
      //printData(result);
      //updateEtas(&deltaFE, b);
      getRadii(initRadii);
      printf("\n*** *** *** *** *** *** *** *** *** *** ***\n");
      app->run(precision, dt);
      printf("\nF = %.10f\n", F());
      printData(result);
      
          
      map<int, Vertex>::iterator vvvit;
      for(vvvit = Triangulation::vertexTable.begin(); vvvit != Triangulation::vertexTable.end(); vvvit++)
   {
       double curv = Curvature3D::valueAt(vvvit->second);
       printf("vertex %3d: %f\t%.10f\n", vvvit->first, Radius::valueAt(vvvit->second), curv/(Radius::valueAt(vvvit->second)));
           }
      
      
      
      calcDeltaFE(&deltaFE, deltaEta);
      updateEtas(&deltaFE, b, a);

      printf("\n");
   }
}