<commit_before>#include "cmbNucMainWindow.h"

#include "ui_qNucMainWindow.h"
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkCompositePolyDataMapper2.h>
#include <QFileDialog>
#include <QStringList>
#include <QDebug>
#include <QDockWidget>

#include "cmbNucAssembly.h"
#include "cmbNucCore.h"
#include "cmbNucInputPropertiesWidget.h"
#include "cmbNucInputListWidget.h"

#include "vtkAxesActor.h"
#include "vtkProperty.h"
#include "vtkCompositeDataDisplayAttributes.h"
#include "vtkDataObjectTreeIterator.h"
#include "vtkInformation.h"
#include "vtkCompositeDataPipeline.h"
#include "vtkAlgorithm.h"
#include "vtkNew.h"

// Constructor
cmbNucMainWindow::cmbNucMainWindow()
{
  // vtkNew<vtkCompositeDataPipeline> compositeExec;
  // vtkAlgorithm::SetDefaultExecutivePrototype(compositeExec.GetPointer());

  this->ui = new Ui_qNucMainWindow;
  this->ui->setupUi(this);
  this->NuclearCore = new cmbNucCore();

  this->initPanels();

  // VTK/Qt wedded
  this->Renderer = vtkSmartPointer<vtkRenderer>::New();
  this->ui->qvtkWidget->GetRenderWindow()->AddRenderer(this->Renderer);
  this->Mapper = vtkSmartPointer<vtkCompositePolyDataMapper2>::New();
  this->Actor = vtkSmartPointer<vtkActor>::New();
  this->Actor->SetMapper(this->Mapper.GetPointer());
  this->Actor->GetProperty()->SetShading(1);
  this->Actor->GetProperty()->SetInterpolationToPhong();
//  this->Actor->GetProperty()->EdgeVisibilityOn();
  this->Renderer->AddActor(this->Actor);

  vtkCompositeDataDisplayAttributes *attributes = vtkCompositeDataDisplayAttributes::New();
  this->Mapper->SetCompositeDataDisplayAttributes(attributes);
  attributes->Delete();

  // add axes actor
  vtkAxesActor *axesActor = vtkAxesActor::New();
  this->Renderer->AddActor(axesActor);
  axesActor->Delete();

  // Set up action signals and slots
  connect(this->ui->actionExit, SIGNAL(triggered()), this, SLOT(onExit()));
  connect(this->ui->actionOpenFile, SIGNAL(triggered()), this, SLOT(onFileOpen()));
  connect(this->ui->actionSaveFile, SIGNAL(triggered()), this, SLOT(onFileSave()));
  connect(this->ui->actionNew, SIGNAL(triggered()), this, SLOT(onFileNew()));

  // Hardcoded duct colors
  this->MaterialColors.insert("g1", QColor::fromRgbF(1, 1, 1, 0.3));
  this->MaterialColors.insert("c1", QColor::fromRgbF(0.6, 0.4, 0.2, 0.5));
  this->MaterialColors.insert("m3", QColor::fromRgbF(0.8, 0.4, 0.0, 0.7));

  // pin color
  this->MaterialColors.insert("pin", QColor::fromRgbF(1.0, 0.4, 0.0));

}

cmbNucMainWindow::~cmbNucMainWindow()
{
  this->PropertyWidget->setObject(NULL, NULL);
  this->PropertyWidget->setAssembly(NULL);
  this->InputsWidget->setCore(NULL);
  delete this->NuclearCore;
}

void cmbNucMainWindow::initPanels()
{
  this->InputsWidget = new cmbNucInputListWidget(this);
  this->PropertyWidget = new cmbNucInputPropertiesWidget(this);
  this->ui->InputsDock->setWidget(this->InputsWidget);
  this->ui->PropertyDock->setWidget(this->PropertyWidget);
  this->ui->PropertyDock->setEnabled(0);
  this->InputsWidget->setEnabled(0);

  this->InputsWidget->setCore(this->NuclearCore);

  QObject::connect(this->InputsWidget,
    SIGNAL(objectSelected(AssyPartObj*, const char*)), this,
    SLOT(onObjectSelected(AssyPartObj*, const char*)));
  QObject::connect(this->InputsWidget,
    SIGNAL(objectRemoved()), this,
    SLOT(onObjectModified()));

  QObject::connect(this->PropertyWidget,
    SIGNAL(currentObjectModified(AssyPartObj*)), this,
    SLOT(onObjectModified(AssyPartObj*)));
}

void cmbNucMainWindow::onObjectSelected(AssyPartObj* selObj,
  const char* name)
{
  if(!selObj)
    {
    this->ui->PropertyDock->setEnabled(0);
    return;
    }
  this->ui->PropertyDock->setEnabled(1);
  this->PropertyWidget->setAssembly(this->InputsWidget->getCurrentAssembly());
  this->PropertyWidget->setObject(selObj, name);
}

void cmbNucMainWindow::onObjectModified(AssyPartObj* obj)
{
  // update material colors
  this->updateMaterialColors();

  if(obj && obj->GetType() == CMBNUC_CORE)
    {
    this->Renderer->ResetCamera();
    }
  // render
  this->ui->qvtkWidget->update();
}

void cmbNucMainWindow::onExit()
{
  qApp->exit();
}

void cmbNucMainWindow::onFileNew()
{
  this->PropertyWidget->setObject(NULL, NULL);
  this->PropertyWidget->setAssembly(NULL);
  this->InputsWidget->onNewAssembly();
  this->Renderer->ResetCamera();
  this->Renderer->Render();
}

void cmbNucMainWindow::onFileOpen()
{
  QStringList fileNames =
    QFileDialog::getOpenFileNames(this,
                                 "Open Assygen File...",
                                 QDir::homePath(),
                                 "INP Files (*.inp)");
  if(fileNames.count()==0)
    {
    return;
    }
  this->setCursor(Qt::BusyCursor);
  // clear old assembly
  this->PropertyWidget->setObject(NULL, NULL);
  this->PropertyWidget->setAssembly(NULL);
  int numExistingAssy = this->NuclearCore->GetNumberOfAssemblies();
  int numNewAssy = 0;
  QList<cmbNucAssembly*> assemblies;
  foreach(QString fileName, fileNames)
    {
    if(!fileName.isEmpty())
      {
      cmbNucAssembly* assy = this->openFile(fileName);
      assemblies.append(assy);
      numNewAssy++;
      }
    }
  // the very first time
  if(numExistingAssy == 0)
    {
    this->NuclearCore->SetDimensions(numNewAssy, numNewAssy);
    for(int i=0; i<numNewAssy ; i++)
      {
      this->NuclearCore->SetAssemblyLabel(i, 0, assemblies.at(i)->label);
      for(int j=1; j<numNewAssy ; j++)
        {
        this->NuclearCore->SetAssemblyLabel(i, j, "xx");
        }
      }
    }
  // update data colors
  this->updateMaterialColors();
  // render
  this->Renderer->ResetCamera();
  this->Renderer->Render();
  this->InputsWidget->updateUI(numExistingAssy==0 && numNewAssy>1);

  this->unsetCursor();
}

cmbNucAssembly* cmbNucMainWindow::openFile(const QString &fileName)
{
  // read file and create new assembly
  cmbNucAssembly* assembly = new cmbNucAssembly;
  assembly->label = QString("Assembly").append(
    QString::number(this->NuclearCore->GetNumberOfAssemblies()+1)).toStdString();
  this->NuclearCore->AddAssembly(assembly);
  assembly->ReadFile(fileName.toStdString());
  return assembly;
}

void cmbNucMainWindow::onFileSave()
{
  QString fileName =
    QFileDialog::getSaveFileName(this,
                                 "Save Assygen File...",
                                 QDir::homePath(),
                                 "INP Files (*.inp)");
  if(!fileName.isEmpty())
    {
    this->setCursor(Qt::BusyCursor);
    this->saveFile(fileName);
    this->unsetCursor();
    }
}

void cmbNucMainWindow::saveFile(const QString &fileName)
{
  if(!this->InputsWidget->getCurrentAssembly())
    {
    qDebug() << "no assembly to save";
    return;
    }

  this->InputsWidget->getCurrentAssembly()->WriteFile(fileName.toStdString());
}

void cmbNucMainWindow::updateMaterialColors()
{
  // regenerate core and assembly view
  vtkSmartPointer<vtkMultiBlockDataSet> coredata = this->NuclearCore->GetData();
  this->Mapper->SetInputDataObject(coredata);
  if(!coredata)
  {
  return;
  }
  unsigned int numCoreBlocks = coredata->GetNumberOfBlocks();
  vtkCompositeDataDisplayAttributes *attributes =
    this->Mapper->GetCompositeDataDisplayAttributes();

  //vtkDataObjectTreeIterator *coreiter = coredata->NewTreeIterator();
  //coreiter->SetSkipEmptyNodes(false);
  unsigned int realflatidx=0;
  for(unsigned int block=0; block<numCoreBlocks; block++)
    {
    realflatidx++;
    if(!coredata->GetBlock(block))
      {
      continue;
      }
    vtkMultiBlockDataSet* data = vtkMultiBlockDataSet::SafeDownCast(coredata->GetBlock(block));
    if(!data)
      {
      continue;
      }
    // for each assembly
    if(coredata->GetMetaData(block)->Has(vtkCompositeDataSet::NAME()))
      {
      std::string assyLabel = coredata->GetMetaData(block)->Get(
        vtkCompositeDataSet::NAME());
      cmbNucAssembly* assy = this->NuclearCore->GetAssembly(assyLabel);
      if(!assy)
        {
        qCritical() << "no specified assembly to found in core: " << assyLabel.c_str();
        return;
        }

      std::pair<int, int> dimensions = assy->AssyLattice.GetDimensions();
      int pins = dimensions.first * dimensions.second;

//      vtkDataObjectTreeIterator *iter = data->NewTreeIterator();
//      iter->SetSkipEmptyNodes(false);
      int pin_count = 0;

//      while(!iter->IsDoneWithTraversal())
      int numAssyBlocks = data->GetNumberOfBlocks();
      for(unsigned int idx=0; idx<numAssyBlocks; idx++)
        {
        realflatidx++;
        if(pin_count < pins)
          {
          int i = realflatidx;
          QColor pinColor = this->MaterialColors["pin"];
          double color[] = { pinColor.redF(), pinColor.greenF(), pinColor.blueF() };
          attributes->SetBlockColor(i, color);
          attributes->SetBlockOpacity(i, pinColor.alphaF());
          pin_count++;
          }
        else // ducts need to color by layers
          {
          if(vtkMultiBlockDataSet* ductBlock =
            vtkMultiBlockDataSet::SafeDownCast(data->GetBlock(idx)))
            {
            unsigned int numBlocks = ductBlock->GetNumberOfBlocks();
            for(unsigned int b=0; b<numBlocks; b++)
              {
              int iKey = b%3;
              std::string strKey = "m3";
              if(iKey == 1)
                {
                strKey = "c1";
                }
              else if(iKey == 2)
                {
                strKey = "g1";
                }
              int i = ++realflatidx;
              QColor matColor = this->MaterialColors.value(strKey.c_str());
              double color[] = { matColor.redF(), matColor.greenF(), matColor.blueF() };
              attributes->SetBlockColor(i, color);
              attributes->SetBlockOpacity(i, matColor.alphaF());
              }
            }
          }
        }
      }
    }
}
<commit_msg>ENH:Changed default colors<commit_after>#include "cmbNucMainWindow.h"

#include "ui_qNucMainWindow.h"
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkCompositePolyDataMapper2.h>
#include <QFileDialog>
#include <QStringList>
#include <QDebug>
#include <QDockWidget>

#include "cmbNucAssembly.h"
#include "cmbNucCore.h"
#include "cmbNucInputPropertiesWidget.h"
#include "cmbNucInputListWidget.h"

#include "vtkAxesActor.h"
#include "vtkProperty.h"
#include "vtkCompositeDataDisplayAttributes.h"
#include "vtkDataObjectTreeIterator.h"
#include "vtkInformation.h"
#include "vtkCompositeDataPipeline.h"
#include "vtkAlgorithm.h"
#include "vtkNew.h"

// Constructor
cmbNucMainWindow::cmbNucMainWindow()
{
  // vtkNew<vtkCompositeDataPipeline> compositeExec;
  // vtkAlgorithm::SetDefaultExecutivePrototype(compositeExec.GetPointer());

  this->ui = new Ui_qNucMainWindow;
  this->ui->setupUi(this);
  this->NuclearCore = new cmbNucCore();

  this->initPanels();

  // VTK/Qt wedded
  this->Renderer = vtkSmartPointer<vtkRenderer>::New();
  this->ui->qvtkWidget->GetRenderWindow()->AddRenderer(this->Renderer);
  this->Mapper = vtkSmartPointer<vtkCompositePolyDataMapper2>::New();
  this->Actor = vtkSmartPointer<vtkActor>::New();
  this->Actor->SetMapper(this->Mapper.GetPointer());
  this->Actor->GetProperty()->SetShading(1);
  this->Actor->GetProperty()->SetInterpolationToPhong();
//  this->Actor->GetProperty()->EdgeVisibilityOn();
  this->Renderer->AddActor(this->Actor);

  vtkCompositeDataDisplayAttributes *attributes = vtkCompositeDataDisplayAttributes::New();
  this->Mapper->SetCompositeDataDisplayAttributes(attributes);
  attributes->Delete();

  // add axes actor
  vtkAxesActor *axesActor = vtkAxesActor::New();
  this->Renderer->AddActor(axesActor);
  axesActor->Delete();

  // Set up action signals and slots
  connect(this->ui->actionExit, SIGNAL(triggered()), this, SLOT(onExit()));
  connect(this->ui->actionOpenFile, SIGNAL(triggered()), this, SLOT(onFileOpen()));
  connect(this->ui->actionSaveFile, SIGNAL(triggered()), this, SLOT(onFileSave()));
  connect(this->ui->actionNew, SIGNAL(triggered()), this, SLOT(onFileNew()));

  // Hardcoded duct colors
  this->MaterialColors.insert("g1", QColor::fromRgbF(.7, .7, .7, 1.0));
  this->MaterialColors.insert("c1", QColor::fromRgbF(0.3, 0.5, 1.0, 1.0));
  this->MaterialColors.insert("m3", QColor::fromRgbF(0.8, 0.4, 0.0, 1.0));

  // pin color
  this->MaterialColors.insert("pin", QColor::fromRgbF(1.0, 0.1, 0.1));

}

cmbNucMainWindow::~cmbNucMainWindow()
{
  this->PropertyWidget->setObject(NULL, NULL);
  this->PropertyWidget->setAssembly(NULL);
  this->InputsWidget->setCore(NULL);
  delete this->NuclearCore;
}

void cmbNucMainWindow::initPanels()
{
  this->InputsWidget = new cmbNucInputListWidget(this);
  this->PropertyWidget = new cmbNucInputPropertiesWidget(this);
  this->ui->InputsDock->setWidget(this->InputsWidget);
  this->ui->PropertyDock->setWidget(this->PropertyWidget);
  this->ui->PropertyDock->setEnabled(0);
  this->InputsWidget->setEnabled(0);

  this->InputsWidget->setCore(this->NuclearCore);

  QObject::connect(this->InputsWidget,
    SIGNAL(objectSelected(AssyPartObj*, const char*)), this,
    SLOT(onObjectSelected(AssyPartObj*, const char*)));
  QObject::connect(this->InputsWidget,
    SIGNAL(objectRemoved()), this,
    SLOT(onObjectModified()));

  QObject::connect(this->PropertyWidget,
    SIGNAL(currentObjectModified(AssyPartObj*)), this,
    SLOT(onObjectModified(AssyPartObj*)));
}

void cmbNucMainWindow::onObjectSelected(AssyPartObj* selObj,
  const char* name)
{
  if(!selObj)
    {
    this->ui->PropertyDock->setEnabled(0);
    return;
    }
  this->ui->PropertyDock->setEnabled(1);
  this->PropertyWidget->setAssembly(this->InputsWidget->getCurrentAssembly());
  this->PropertyWidget->setObject(selObj, name);
}

void cmbNucMainWindow::onObjectModified(AssyPartObj* obj)
{
  // update material colors
  this->updateMaterialColors();

  if(obj && obj->GetType() == CMBNUC_CORE)
    {
    this->Renderer->ResetCamera();
    }
  // render
  this->ui->qvtkWidget->update();
}

void cmbNucMainWindow::onExit()
{
  qApp->exit();
}

void cmbNucMainWindow::onFileNew()
{
  this->PropertyWidget->setObject(NULL, NULL);
  this->PropertyWidget->setAssembly(NULL);
  this->InputsWidget->onNewAssembly();
  this->Renderer->ResetCamera();
  this->Renderer->Render();
}

void cmbNucMainWindow::onFileOpen()
{
  QStringList fileNames =
    QFileDialog::getOpenFileNames(this,
                                 "Open Assygen File...",
                                 QDir::homePath(),
                                 "INP Files (*.inp)");
  if(fileNames.count()==0)
    {
    return;
    }
  this->setCursor(Qt::BusyCursor);
  // clear old assembly
  this->PropertyWidget->setObject(NULL, NULL);
  this->PropertyWidget->setAssembly(NULL);
  int numExistingAssy = this->NuclearCore->GetNumberOfAssemblies();
  int numNewAssy = 0;
  QList<cmbNucAssembly*> assemblies;
  foreach(QString fileName, fileNames)
    {
    if(!fileName.isEmpty())
      {
      cmbNucAssembly* assy = this->openFile(fileName);
      assemblies.append(assy);
      numNewAssy++;
      }
    }
  // the very first time
  if(numExistingAssy == 0)
    {
    this->NuclearCore->SetDimensions(numNewAssy, numNewAssy);
    for(int i=0; i<numNewAssy ; i++)
      {
      this->NuclearCore->SetAssemblyLabel(i, 0, assemblies.at(i)->label);
      for(int j=1; j<numNewAssy ; j++)
        {
        this->NuclearCore->SetAssemblyLabel(i, j, "xx");
        }
      }
    }
  // update data colors
  this->updateMaterialColors();
  // render
  this->Renderer->ResetCamera();
  this->Renderer->Render();
  this->InputsWidget->updateUI(numExistingAssy==0 && numNewAssy>1);

  this->unsetCursor();
}

cmbNucAssembly* cmbNucMainWindow::openFile(const QString &fileName)
{
  // read file and create new assembly
  cmbNucAssembly* assembly = new cmbNucAssembly;
  assembly->label = QString("Assembly").append(
    QString::number(this->NuclearCore->GetNumberOfAssemblies()+1)).toStdString();
  this->NuclearCore->AddAssembly(assembly);
  assembly->ReadFile(fileName.toStdString());
  return assembly;
}

void cmbNucMainWindow::onFileSave()
{
  QString fileName =
    QFileDialog::getSaveFileName(this,
                                 "Save Assygen File...",
                                 QDir::homePath(),
                                 "INP Files (*.inp)");
  if(!fileName.isEmpty())
    {
    this->setCursor(Qt::BusyCursor);
    this->saveFile(fileName);
    this->unsetCursor();
    }
}

void cmbNucMainWindow::saveFile(const QString &fileName)
{
  if(!this->InputsWidget->getCurrentAssembly())
    {
    qDebug() << "no assembly to save";
    return;
    }

  this->InputsWidget->getCurrentAssembly()->WriteFile(fileName.toStdString());
}

void cmbNucMainWindow::updateMaterialColors()
{
  // regenerate core and assembly view
  vtkSmartPointer<vtkMultiBlockDataSet> coredata = this->NuclearCore->GetData();
  this->Mapper->SetInputDataObject(coredata);
  if(!coredata)
  {
  return;
  }
  unsigned int numCoreBlocks = coredata->GetNumberOfBlocks();
  vtkCompositeDataDisplayAttributes *attributes =
    this->Mapper->GetCompositeDataDisplayAttributes();

  //vtkDataObjectTreeIterator *coreiter = coredata->NewTreeIterator();
  //coreiter->SetSkipEmptyNodes(false);
  unsigned int realflatidx=0;
  for(unsigned int block=0; block<numCoreBlocks; block++)
    {
    realflatidx++;
    if(!coredata->GetBlock(block))
      {
      continue;
      }
    vtkMultiBlockDataSet* data = vtkMultiBlockDataSet::SafeDownCast(coredata->GetBlock(block));
    if(!data)
      {
      continue;
      }
    // for each assembly
    if(coredata->GetMetaData(block)->Has(vtkCompositeDataSet::NAME()))
      {
      std::string assyLabel = coredata->GetMetaData(block)->Get(
        vtkCompositeDataSet::NAME());
      cmbNucAssembly* assy = this->NuclearCore->GetAssembly(assyLabel);
      if(!assy)
        {
        qCritical() << "no specified assembly to found in core: " << assyLabel.c_str();
        return;
        }

      std::pair<int, int> dimensions = assy->AssyLattice.GetDimensions();
      int pins = dimensions.first * dimensions.second;

//      vtkDataObjectTreeIterator *iter = data->NewTreeIterator();
//      iter->SetSkipEmptyNodes(false);
      int pin_count = 0;

//      while(!iter->IsDoneWithTraversal())
      int numAssyBlocks = data->GetNumberOfBlocks();
      for(unsigned int idx=0; idx<numAssyBlocks; idx++)
        {
        realflatidx++;
        if(pin_count < pins)
          {
          int i = realflatidx;
          QColor pinColor = this->MaterialColors["pin"];
          double color[] = { pinColor.redF(), pinColor.greenF(), pinColor.blueF() };
          attributes->SetBlockColor(i, color);
          attributes->SetBlockOpacity(i, pinColor.alphaF());
          pin_count++;
          }
        else // ducts need to color by layers
          {
          if(vtkMultiBlockDataSet* ductBlock =
            vtkMultiBlockDataSet::SafeDownCast(data->GetBlock(idx)))
            {
            unsigned int numBlocks = ductBlock->GetNumberOfBlocks();
            for(unsigned int b=0; b<numBlocks; b++)
              {
              int iKey = b%3;
              std::string strKey = "m3";
              if(iKey == 1)
                {
                strKey = "c1";
                }
              else if(iKey == 2)
                {
                strKey = "g1";
                }
              int i = ++realflatidx;
              QColor matColor = this->MaterialColors.value(strKey.c_str());
              double color[] = { matColor.redF(), matColor.greenF(), matColor.blueF() };
              attributes->SetBlockColor(i, color);
              attributes->SetBlockOpacity(i, matColor.alphaF());
              }
            }
          }
        }
      }
    }
}
<|endoftext|>


<commit_before>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//
// Contributors: Kirsten Weber

#ifndef DUNE_STUFF_FUNCTIONS_EXPRESSION_HH
#define DUNE_STUFF_FUNCTIONS_EXPRESSION_HH

#include <vector>
#include <limits>

#include <dune/common/fvector.hh>

#include <dune/stuff/common/configuration.hh>
#include <dune/stuff/common/exceptions.hh>

#include "expression/base.hh"
#include "interfaces.hh"
#include "default.hh"
#include "constant.hh"

namespace Dune {
namespace Stuff {
namespace Functions {

/**
 *  \attention  If you add the create() and default_config() method, do not forget to enable the matrix valued
 *              versions in test/function_expression.cc
 */
template< class EntityImp, class DomainFieldImp, size_t domainDim, class RangeFieldImp, size_t rangeDim, size_t rangeDimCols = 1 >
class Expression
  : public LocalizableFunctionInterface< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols >
{
  typedef LocalizableFunctionInterface
      < EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols >               BaseType;
  typedef Expression< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols > ThisType;
  typedef MathExpressionBase
      < DomainFieldImp, domainDim, RangeFieldImp, rangeDim*rangeDimCols > MathExpressionFunctionType;

  class Localfunction
    : public LocalfunctionInterface< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols >
  {
    typedef LocalfunctionInterface< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols > BaseType;
  public:
    typedef typename BaseType::EntityType EntityType;

    typedef typename BaseType::DomainType     DomainType;
    typedef typename BaseType::RangeFieldType RangeFieldType;
    static const size_t                       dimRange = BaseType::dimRange;
    static const size_t                       dimRangeCols = BaseType::dimRangeCols;
    typedef typename BaseType::RangeType      RangeType;

    typedef typename BaseType::JacobianRangeType JacobianRangeType;

    Localfunction(const EntityType& ent,
                  const std::shared_ptr< const MathExpressionFunctionType >& function,
                  const size_t ord)
      : BaseType(ent)
      , function_(function)
      , order_(ord)
      , tmp_vector_(0)
    {}

    Localfunction(const Localfunction& /*other*/) = delete;

    Localfunction& operator=(const Localfunction& /*other*/) = delete;

    virtual size_t order() const override
    {
      return order_;
    }

    virtual void evaluate(const DomainType& xx, RangeType& ret) const override
    {
      function_->evaluate(this->entity().geometry().global(xx), tmp_vector_);
      for (size_t ii = 0; ii < dimRange; ++ii) {
        auto& retRow = ret[ii];
        for (size_t jj = 0; jj < dimRangeCols; ++jj) {
          retRow[jj] = tmp_vector_[ii*dimRange + jj];
        }
      }
    } // ... evaluate(...)

    virtual void jacobian(const DomainType& /*xx*/, JacobianRangeType& /*ret*/) const override
    {
      DUNE_THROW(NotImplemented,
                 "Once we decided on the JacobianRangeType of matrix valued functions we have to implement "
                 << "gradients for this function!");
    }

  private:
    const std::shared_ptr< const MathExpressionFunctionType > function_;
    const size_t order_;
    mutable FieldVector< RangeFieldType, dimRange*dimRangeCols > tmp_vector_;
  }; // class Localfunction

public:
  typedef typename BaseType::EntityType         EntityType;
  typedef typename BaseType::LocalfunctionType  LocalfunctionType;

  static std::string static_id()
  {
    return BaseType::static_id() + ".expression";
  }

  Expression(const std::string variable,
             const std::string expression,
             const size_t ord = 0,
             const std::string nm = static_id())
    : function_(new MathExpressionFunctionType(variable, expression))
    , order_(ord)
    , name_(nm)
  {}

  Expression(const std::string variable,
             const std::vector< std::string > expressions,
             const size_t ord = 0,
             const std::string nm = static_id())
    : function_(new MathExpressionFunctionType(variable, expressions))
    , order_(ord)
    , name_(nm)
  {}

  Expression(const ThisType& other) = default;

  ThisType& operator=(const ThisType& other)
  {
    if (this != &other) {
      function_ = other.function_;
      order_ = other.order_;
      name_ = other.name_;
    }
    return *this;
  }

  virtual std::string type() const override final
  {
    return BaseType::static_id() + ".expression";
  }

  virtual std::string name() const override
  {
    return name_;
  }

  virtual std::unique_ptr< LocalfunctionType > local_function(const EntityType& entity) const override
  {
    return std::unique_ptr< Localfunction >(new Localfunction(entity, function_, order_));
  }

private:
  std::shared_ptr< const MathExpressionFunctionType > function_;
  size_t order_;
  std::string name_;
}; // class Expression

template< class EntityImp, class DomainFieldImp, size_t domainDim, class RangeFieldImp, size_t rangeDim >
class Expression< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, 1 >
  : public GlobalFunctionInterface< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim >
{
  typedef GlobalFunctionInterface< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim > BaseType;
  typedef Expression< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, 1 > ThisType;
  typedef MathExpressionBase < DomainFieldImp, domainDim, RangeFieldImp, rangeDim > MathExpressionFunctionType;
  typedef MathExpressionBase < DomainFieldImp, domainDim, RangeFieldImp, domainDim > MathExpressionGradientType;

public:
  typedef typename BaseType::EntityType         EntityType;
  typedef typename BaseType::LocalfunctionType  LocalfunctionType;

  static const size_t                   dimDomain = BaseType::dimDomain;
  typedef typename BaseType::DomainType DomainType;

  static const size_t                   dimRange = BaseType::dimRange;
  typedef typename BaseType::RangeType  RangeType;

  typedef typename BaseType::JacobianRangeType JacobianRangeType;

  static const bool available = true;

  static std::string static_id()
  {
    return BaseType::static_id() + ".expression";
  }

  static Common::Configuration default_config(const std::string sub_name = "")
  {
    Common::Configuration config;
    config["variable"] = "x";
    config["expression"] = "[x[0] sin(x[0]) exp(x[0])]";
    config["order"] = "3";
    config["name"] = static_id();
    if (sub_name.empty())
      return config;
    else {
      Common::Configuration tmp;
      tmp.add(config, sub_name);
      return tmp;
    }
  } // ... default_config(...)

  static std::unique_ptr< ThisType > create(const Common::Configuration config = default_config(), const std::string sub_name = static_id())
  {
    // get correct config
    const Common::Configuration cfg = config.has_sub(sub_name) ? config.sub(sub_name) : config;
    const Common::Configuration default_cfg = default_config();
    // create
    return cfg.has_key("gradient")
        ? Common::make_unique< ThisType >(
            cfg.get("variable",   default_cfg.get< std::string >("variable")),
            cfg.get("expression", default_cfg.get< std::vector< std::string > >("expression")),
            cfg.get("order",      default_cfg.get< size_t >("order")),
            cfg.get("name",       default_cfg.get< std::string >("name")),
            cfg.get< Dune::FieldMatrix< std::string, dimRange, dimDomain > >("gradient"))
        : Common::make_unique< ThisType >(
            cfg.get("variable",   default_cfg.get< std::string >("variable")),
            cfg.get("expression", default_cfg.get< std::vector< std::string > >("expression")),
            cfg.get("order",      default_cfg.get< size_t >("order")),
            cfg.get("name",       default_cfg.get< std::string >("name")),
            Dune::FieldMatrix< std::string, 0, 0 >());
  } // ... create(...)

  // constructors taking a std::vector< std::vector< std::string > > for the jacobian
  Expression(const std::string variable,
             const std::string expression,
             const size_t ord = default_config().get< size_t >("order"),
             const std::string nm = static_id(),
             const std::vector< std::vector< std::string > > gradient_expressions
                = std::vector< std::vector< std::string > >())
    : function_(new MathExpressionFunctionType(variable, expression))
    , order_(ord)
    , name_(nm)
  {
    build_gradients(variable, gradient_expressions);
  }

  Expression(const std::string variable,
             const std::vector< std::string > expressions,
             const size_t ord = default_config().get< size_t >("order"),
             const std::string nm = static_id(),
             const std::vector< std::vector< std::string > > gradient_expressions
                = std::vector< std::vector< std::string > >())
    : function_(new MathExpressionFunctionType(variable, expressions))
    , order_(ord)
    , name_(nm)
  {
    build_gradients(variable, gradient_expressions);
  }

  // constructors taking a FieldMatrix for the jacobian
  template< int rows, int cols >
  Expression(const std::string variable,
             const std::string expression,
             const size_t ord = default_config().get< size_t >("order"),
             const std::string nm = static_id(),
             const Dune::FieldMatrix< std::string, rows, cols > jacobian
                = Dune::FieldMatrix< std::string, 0, 0 >())
    : function_(new MathExpressionFunctionType(variable, expression))
    , order_(ord)
    , name_(nm)
  {
    build_gradients(variable, jacobian);
  }

  template< int rows, int cols >
  Expression(const std::string variable,
             const std::vector< std::string > expressions,
             const size_t ord = default_config().get< size_t >("order"),
             const std::string nm = static_id(),
             const Dune::FieldMatrix< std::string, rows, cols > jacobian
                = Dune::FieldMatrix< std::string, 0, 0 >())
    : function_(new MathExpressionFunctionType(variable, expressions))
    , order_(ord)
    , name_(nm)
  {
    build_gradients(variable, jacobian);
  }

  virtual std::string name() const override
  {
    return name_;
  }

  virtual size_t order() const override
  {
    return order_;
  }

  virtual void evaluate(const DomainType& xx, RangeType& ret) const override
  {
    function_->evaluate(xx, ret);
#ifndef NDEBUG
# ifndef DUNE_STUFF_FUNCTIONS_EXPRESSION_DISABLE_CHECKS
    bool failure = false;
    std::string type;
    if (std::isnan(ret[0])) {
      failure = true;
      type = "NaN";
    } else if (std::isinf(ret[0])) {
      failure = true;
      type = "inf";
    } else if (std::abs(ret[0]) > (0.9 * std::numeric_limits< double >::max())) {
      failure = true;
      type = "an unlikely value";
    }
    if (failure)
      DUNE_THROW(Stuff::Exceptions::internal_error,
                 "evaluating this function yielded " << type << "!\n"
                 << "The variable of this function is:     " << function_->variable() << "\n"
                 << "The expression of this functional is: " << function_->expression().at(0) << "\n"
                 << "You tried to evaluate it with:   xx = " << xx << "\n"
                 << "The result was:                       " << ret << "\n\n"
                 << "You can disable this check by defining DUNE_STUFF_FUNCTIONS_EXPRESSION_DISABLE_CHECKS\n");
# endif // DUNE_STUFF_FUNCTIONS_EXPRESSION_DISABLE_CHECKS
#endif // NDEBUG
  }

  virtual void jacobian(const DomainType& xx, JacobianRangeType& ret) const override
  {
    if (gradients_.size() == 0)
      DUNE_THROW(NotImplemented, "This function does not provide any gradients!");
    assert(gradients_.size() == dimRange);
    for (size_t ii = 0; ii < dimRange; ++ii) {
      gradients_[ii]->evaluate(xx, ret[ii]);
    }
  } // ... jacobian(...)
private:
  void build_gradients(const std::string variable,
                       const std::vector< std::vector< std::string > >& gradient_expressions)
  {
    assert(gradient_expressions.size() == 0 || gradient_expressions.size() >= dimRange);
    if (gradient_expressions.size() > 0)
      for (size_t rr = 0; rr < dimRange; ++rr) {
        const auto& gradient_expression = gradient_expressions[rr];
        assert(gradient_expression.size() >= dimDomain);
        gradients_.emplace_back(new MathExpressionGradientType(variable, gradient_expression));
      }
  } // ... build_gradients(...)

  template< int rows, int cols >
  void build_gradients(const std::string variable,
                       Dune::FieldMatrix< std::string, rows, cols > jacobian)
  {
    assert(jacobian.rows == 0 || jacobian.rows >= dimRange);
    assert(jacobian.cols == 0 || jacobian.cols >= dimDomain);
    if (jacobian.rows > 0 && jacobian.cols > 0)
      for (size_t rr = 0; rr < dimRange; ++rr) {
        std::vector< std::string > gradient_expression;
        for (size_t cc = 0; cc < dimDomain; ++cc)
          gradient_expression.emplace_back(jacobian[rr][cc]);
        gradients_.emplace_back(new MathExpressionGradientType(variable, gradient_expression));
      }
  } // ... build_gradients(...)

  std::shared_ptr< const MathExpressionFunctionType > function_;
  size_t order_;
  std::string name_;
  std::vector< std::shared_ptr< const MathExpressionGradientType > > gradients_;
}; // class Expression< ..., 1 >

} // namespace Functions
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_FUNCTIONS_EXPRESSION_HH
<commit_msg>[functions.expression] remove default arguments<commit_after>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//
// Contributors: Kirsten Weber

#ifndef DUNE_STUFF_FUNCTIONS_EXPRESSION_HH
#define DUNE_STUFF_FUNCTIONS_EXPRESSION_HH

#include <vector>
#include <limits>

#include <dune/common/fvector.hh>

#include <dune/stuff/common/configuration.hh>
#include <dune/stuff/common/exceptions.hh>

#include "expression/base.hh"
#include "interfaces.hh"
#include "default.hh"
#include "constant.hh"

namespace Dune {
namespace Stuff {
namespace Functions {

/**
 *  \attention  If you add the create() and default_config() method, do not forget to enable the matrix valued
 *              versions in test/function_expression.cc
 */
template< class EntityImp, class DomainFieldImp, size_t domainDim, class RangeFieldImp, size_t rangeDim, size_t rangeDimCols = 1 >
class Expression
  : public LocalizableFunctionInterface< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols >
{
  typedef LocalizableFunctionInterface
      < EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols >               BaseType;
  typedef Expression< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols > ThisType;
  typedef MathExpressionBase
      < DomainFieldImp, domainDim, RangeFieldImp, rangeDim*rangeDimCols > MathExpressionFunctionType;

  class Localfunction
    : public LocalfunctionInterface< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols >
  {
    typedef LocalfunctionInterface< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols > BaseType;
  public:
    typedef typename BaseType::EntityType EntityType;

    typedef typename BaseType::DomainType     DomainType;
    typedef typename BaseType::RangeFieldType RangeFieldType;
    static const size_t                       dimRange = BaseType::dimRange;
    static const size_t                       dimRangeCols = BaseType::dimRangeCols;
    typedef typename BaseType::RangeType      RangeType;

    typedef typename BaseType::JacobianRangeType JacobianRangeType;

    Localfunction(const EntityType& ent,
                  const std::shared_ptr< const MathExpressionFunctionType >& function,
                  const size_t ord)
      : BaseType(ent)
      , function_(function)
      , order_(ord)
      , tmp_vector_(0)
    {}

    Localfunction(const Localfunction& /*other*/) = delete;

    Localfunction& operator=(const Localfunction& /*other*/) = delete;

    virtual size_t order() const override
    {
      return order_;
    }

    virtual void evaluate(const DomainType& xx, RangeType& ret) const override
    {
      function_->evaluate(this->entity().geometry().global(xx), tmp_vector_);
      for (size_t ii = 0; ii < dimRange; ++ii) {
        auto& retRow = ret[ii];
        for (size_t jj = 0; jj < dimRangeCols; ++jj) {
          retRow[jj] = tmp_vector_[ii*dimRange + jj];
        }
      }
    } // ... evaluate(...)

    virtual void jacobian(const DomainType& /*xx*/, JacobianRangeType& /*ret*/) const override
    {
      DUNE_THROW(NotImplemented,
                 "Once we decided on the JacobianRangeType of matrix valued functions we have to implement "
                 << "gradients for this function!");
    }

  private:
    const std::shared_ptr< const MathExpressionFunctionType > function_;
    const size_t order_;
    mutable FieldVector< RangeFieldType, dimRange*dimRangeCols > tmp_vector_;
  }; // class Localfunction

public:
  typedef typename BaseType::EntityType         EntityType;
  typedef typename BaseType::LocalfunctionType  LocalfunctionType;

  static std::string static_id()
  {
    return BaseType::static_id() + ".expression";
  }

  Expression(const std::string variable,
             const std::string expression,
             const size_t ord = 0,
             const std::string nm = static_id())
    : function_(new MathExpressionFunctionType(variable, expression))
    , order_(ord)
    , name_(nm)
  {}

  Expression(const std::string variable,
             const std::vector< std::string > expressions,
             const size_t ord = 0,
             const std::string nm = static_id())
    : function_(new MathExpressionFunctionType(variable, expressions))
    , order_(ord)
    , name_(nm)
  {}

  Expression(const ThisType& other) = default;

  ThisType& operator=(const ThisType& other)
  {
    if (this != &other) {
      function_ = other.function_;
      order_ = other.order_;
      name_ = other.name_;
    }
    return *this;
  }

  virtual std::string type() const override final
  {
    return BaseType::static_id() + ".expression";
  }

  virtual std::string name() const override
  {
    return name_;
  }

  virtual std::unique_ptr< LocalfunctionType > local_function(const EntityType& entity) const override
  {
    return std::unique_ptr< Localfunction >(new Localfunction(entity, function_, order_));
  }

private:
  std::shared_ptr< const MathExpressionFunctionType > function_;
  size_t order_;
  std::string name_;
}; // class Expression

template< class EntityImp, class DomainFieldImp, size_t domainDim, class RangeFieldImp, size_t rangeDim >
class Expression< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, 1 >
  : public GlobalFunctionInterface< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim >
{
  typedef GlobalFunctionInterface< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim > BaseType;
  typedef Expression< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, 1 > ThisType;
  typedef MathExpressionBase < DomainFieldImp, domainDim, RangeFieldImp, rangeDim > MathExpressionFunctionType;
  typedef MathExpressionBase < DomainFieldImp, domainDim, RangeFieldImp, domainDim > MathExpressionGradientType;

public:
  typedef typename BaseType::EntityType         EntityType;
  typedef typename BaseType::LocalfunctionType  LocalfunctionType;

  static const size_t                   dimDomain = BaseType::dimDomain;
  typedef typename BaseType::DomainType DomainType;

  static const size_t                   dimRange = BaseType::dimRange;
  typedef typename BaseType::RangeType  RangeType;

  typedef typename BaseType::JacobianRangeType JacobianRangeType;

  static const bool available = true;

  static std::string static_id()
  {
    return BaseType::static_id() + ".expression";
  }

  static Common::Configuration default_config(const std::string sub_name = "")
  {
    Common::Configuration config;
    config["variable"] = "x";
    config["expression"] = "[x[0] sin(x[0]) exp(x[0])]";
    config["order"] = "3";
    config["name"] = static_id();
    if (sub_name.empty())
      return config;
    else {
      Common::Configuration tmp;
      tmp.add(config, sub_name);
      return tmp;
    }
  } // ... default_config(...)

  static std::unique_ptr< ThisType > create(const Common::Configuration config = default_config(), const std::string sub_name = static_id())
  {
    // get correct config
    const Common::Configuration cfg = config.has_sub(sub_name) ? config.sub(sub_name) : config;
    const Common::Configuration default_cfg = default_config();
    // create
    return cfg.has_key("gradient")
        ? Common::make_unique< ThisType >(
            cfg.get("variable",   default_cfg.get< std::string >("variable")),
            cfg.get("expression", default_cfg.get< std::vector< std::string > >("expression")),
            cfg.get("order",      default_cfg.get< size_t >("order")),
            cfg.get("name",       default_cfg.get< std::string >("name")),
            cfg.get< Dune::FieldMatrix< std::string, dimRange, dimDomain > >("gradient"))
        : Common::make_unique< ThisType >(
            cfg.get("variable",   default_cfg.get< std::string >("variable")),
            cfg.get("expression", default_cfg.get< std::vector< std::string > >("expression")),
            cfg.get("order",      default_cfg.get< size_t >("order")),
            cfg.get("name",       default_cfg.get< std::string >("name")),
            Dune::FieldMatrix< std::string, 0, 0 >());
  } // ... create(...)

  // constructors taking a std::vector< std::vector< std::string > > for the jacobian
  Expression(const std::string variable,
             const std::string expression,
             const size_t ord = default_config().get< size_t >("order"),
             const std::string nm = static_id(),
             const std::vector< std::vector< std::string > > gradient_expressions
                = std::vector< std::vector< std::string > >())
    : function_(new MathExpressionFunctionType(variable, expression))
    , order_(ord)
    , name_(nm)
  {
    build_gradients(variable, gradient_expressions);
  }

  Expression(const std::string variable,
             const std::vector< std::string > expressions,
             const size_t ord = default_config().get< size_t >("order"),
             const std::string nm = static_id(),
             const std::vector< std::vector< std::string > > gradient_expressions
                = std::vector< std::vector< std::string > >())
    : function_(new MathExpressionFunctionType(variable, expressions))
    , order_(ord)
    , name_(nm)
  {
    build_gradients(variable, gradient_expressions);
  }

  // constructors taking a FieldMatrix for the jacobian
  template< int rows, int cols >
  Expression(const std::string variable,
             const std::string expression,
             const size_t ord,
             const std::string nm,
             const Dune::FieldMatrix< std::string, rows, cols > jacobian)
    : function_(new MathExpressionFunctionType(variable, expression))
    , order_(ord)
    , name_(nm)
  {
    build_gradients(variable, jacobian);
  }

  template< int rows, int cols >
  Expression(const std::string variable,
             const std::vector< std::string > expressions,
             const size_t ord,
             const std::string nm,
             const Dune::FieldMatrix< std::string, rows, cols > jacobian)
    : function_(new MathExpressionFunctionType(variable, expressions))
    , order_(ord)
    , name_(nm)
  {
    build_gradients(variable, jacobian);
  }

  virtual std::string name() const override
  {
    return name_;
  }

  virtual size_t order() const override
  {
    return order_;
  }

  virtual void evaluate(const DomainType& xx, RangeType& ret) const override
  {
    function_->evaluate(xx, ret);
#ifndef NDEBUG
# ifndef DUNE_STUFF_FUNCTIONS_EXPRESSION_DISABLE_CHECKS
    bool failure = false;
    std::string type;
    if (std::isnan(ret[0])) {
      failure = true;
      type = "NaN";
    } else if (std::isinf(ret[0])) {
      failure = true;
      type = "inf";
    } else if (std::abs(ret[0]) > (0.9 * std::numeric_limits< double >::max())) {
      failure = true;
      type = "an unlikely value";
    }
    if (failure)
      DUNE_THROW(Stuff::Exceptions::internal_error,
                 "evaluating this function yielded " << type << "!\n"
                 << "The variable of this function is:     " << function_->variable() << "\n"
                 << "The expression of this functional is: " << function_->expression().at(0) << "\n"
                 << "You tried to evaluate it with:   xx = " << xx << "\n"
                 << "The result was:                       " << ret << "\n\n"
                 << "You can disable this check by defining DUNE_STUFF_FUNCTIONS_EXPRESSION_DISABLE_CHECKS\n");
# endif // DUNE_STUFF_FUNCTIONS_EXPRESSION_DISABLE_CHECKS
#endif // NDEBUG
  }

  virtual void jacobian(const DomainType& xx, JacobianRangeType& ret) const override
  {
    if (gradients_.size() == 0)
      DUNE_THROW(NotImplemented, "This function does not provide any gradients!");
    assert(gradients_.size() == dimRange);
    for (size_t ii = 0; ii < dimRange; ++ii) {
      gradients_[ii]->evaluate(xx, ret[ii]);
    }
  } // ... jacobian(...)
private:
  void build_gradients(const std::string variable,
                       const std::vector< std::vector< std::string > >& gradient_expressions)
  {
    assert(gradient_expressions.size() == 0 || gradient_expressions.size() >= dimRange);
    if (gradient_expressions.size() > 0)
      for (size_t rr = 0; rr < dimRange; ++rr) {
        const auto& gradient_expression = gradient_expressions[rr];
        assert(gradient_expression.size() >= dimDomain);
        gradients_.emplace_back(new MathExpressionGradientType(variable, gradient_expression));
      }
  } // ... build_gradients(...)

  template< int rows, int cols >
  void build_gradients(const std::string variable,
                       Dune::FieldMatrix< std::string, rows, cols > jacobian)
  {
    assert(jacobian.rows == 0 || jacobian.rows >= dimRange);
    assert(jacobian.cols == 0 || jacobian.cols >= dimDomain);
    if (jacobian.rows > 0 && jacobian.cols > 0)
      for (size_t rr = 0; rr < dimRange; ++rr) {
        std::vector< std::string > gradient_expression;
        for (size_t cc = 0; cc < dimDomain; ++cc)
          gradient_expression.emplace_back(jacobian[rr][cc]);
        gradients_.emplace_back(new MathExpressionGradientType(variable, gradient_expression));
      }
  } // ... build_gradients(...)

  std::shared_ptr< const MathExpressionFunctionType > function_;
  size_t order_;
  std::string name_;
  std::vector< std::shared_ptr< const MathExpressionGradientType > > gradients_;
}; // class Expression< ..., 1 >

} // namespace Functions
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_FUNCTIONS_EXPRESSION_HH
<|endoftext|>


<commit_before>/*
Copyright (c) 2007, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of Rasterbar Software nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef LIBTORRENT_BUFFER_HPP
#define LIBTORRENT_BUFFER_HPP

#include <memory>
#include <cstring>
#include "libtorrent/invariant_check.hpp"
#include "libtorrent/assert.hpp"

namespace libtorrent {

class buffer
{
public:
	struct interval
	{
	   interval(char* begin, char* end)
		  : begin(begin)
		  , end(end)
		{}

		char operator[](int index) const
		{
			TORRENT_ASSERT(begin + index < end);
			return begin[index];
		}

		int left() const { TORRENT_ASSERT(end >= begin); return end - begin; }

		char* begin;
		char* end;
	};

	struct const_interval
	{
	   const_interval(char const* begin, char const* end)
		  : begin(begin)
		  , end(end)
		{}

		char operator[](int index) const
		{
			TORRENT_ASSERT(begin + index < end);
			return begin[index];
		}

		bool operator==(const const_interval& p_interval)
		{
			return (begin == p_interval.begin
				&& end == p_interval.end);
		}

		int left() const { TORRENT_ASSERT(end >= begin); return end - begin; }

		char const* begin;
		char const* end;
	};

	buffer(std::size_t n = 0)
		: m_begin(0)
		, m_end(0)
		, m_last(0)
	{
		if (n) resize(n);
	}

	buffer(buffer const& b)
		: m_begin(0)
		, m_end(0)
		, m_last(0)
	{
		if (b.size() == 0) return;
		resize(b.size());
		std::memcpy(m_begin, b.begin(), b.size());
	}

	buffer& operator=(buffer const& b)
	{
		resize(b.size());
		std::memcpy(m_begin, b.begin(), b.size());
		return *this;
	}

	~buffer()
	{
		::operator delete (m_begin);
	}

	buffer::interval data() { return interval(m_begin, m_end); }
	buffer::const_interval data() const { return const_interval(m_begin, m_end); }

	void resize(std::size_t n)
	{
		reserve(n);
		m_end = m_begin + n;
	}

	void insert(char* point, char const* first, char const* last)
	{
		std::size_t p = point - m_begin;
		if (point == m_end)
		{
			resize(size() + last - first);
			std::memcpy(m_begin + p, first, last - first);
			return;
		}

		resize(size() + last - first);
		std::memmove(m_begin + p + (last - first), m_begin + p, last - first);
		std::memcpy(m_begin + p, first, last - first);
	}

	void erase(char* begin, char* end)
	{
		TORRENT_ASSERT(end <= m_end);
		TORRENT_ASSERT(begin >= m_begin);
		TORRENT_ASSERT(begin <= end);
	 	if (end == m_end)
		{
			resize(begin - m_begin);
			return;
		}
		std::memmove(begin, end, m_end - end);
		m_end = begin + (m_end - end);
	 }

	void clear() { m_end = m_begin; }
	std::size_t size() const { return m_end - m_begin; }
	std::size_t capacity() const { return m_last - m_begin; }
	void reserve(std::size_t n)
	{
		if (n <= capacity()) return;
		TORRENT_ASSERT(n > 0);

		char* buf = (char*)::operator new(n);
		std::size_t s = size();
		std::memcpy(buf, m_begin, s);
		::operator delete (m_begin);
		m_begin = buf;
		m_end = buf + s;
		m_last = m_begin + n;
	}

	bool empty() const { return m_begin == m_end; }
	char& operator[](std::size_t i) { TORRENT_ASSERT(i >= 0 && i < size()); return m_begin[i]; }
	char const& operator[](std::size_t i) const { TORRENT_ASSERT(i >= 0 && i < size()); return m_begin[i]; }

	char* begin() { return m_begin; }
	char const* begin() const { return m_begin; }
	char* end() { return m_end; }
	char const* end() const { return m_end; }

	void swap(buffer& b)
	{
		using std::swap;
		swap(m_begin, b.m_begin);
		swap(m_end, b.m_end);
		swap(m_last, b.m_last);
	}
private:
	char* m_begin; // first
	char* m_end; // one passed end of size
	char* m_last; // one passed end of allocation
};

}

#endif // LIBTORRENT_BUFFER_HPP

<commit_msg>fixed warning in intel-9.0<commit_after>/*
Copyright (c) 2007, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of Rasterbar Software nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef LIBTORRENT_BUFFER_HPP
#define LIBTORRENT_BUFFER_HPP

#include <memory>
#include <cstring>
#include "libtorrent/invariant_check.hpp"
#include "libtorrent/assert.hpp"

namespace libtorrent {

class buffer
{
public:
	struct interval
	{
	   interval(char* begin, char* end)
		  : begin(begin)
		  , end(end)
		{}

		char operator[](int index) const
		{
			TORRENT_ASSERT(begin + index < end);
			return begin[index];
		}

		int left() const { TORRENT_ASSERT(end >= begin); return end - begin; }

		char* begin;
		char* end;
	};

	struct const_interval
	{
	   const_interval(char const* begin, char const* end)
		  : begin(begin)
		  , end(end)
		{}

		char operator[](int index) const
		{
			TORRENT_ASSERT(begin + index < end);
			return begin[index];
		}

		bool operator==(const const_interval& p_interval)
		{
			return (begin == p_interval.begin
				&& end == p_interval.end);
		}

		int left() const { TORRENT_ASSERT(end >= begin); return end - begin; }

		char const* begin;
		char const* end;
	};

	buffer(std::size_t n = 0)
		: m_begin(0)
		, m_end(0)
		, m_last(0)
	{
		if (n) resize(n);
	}

	buffer(buffer const& b)
		: m_begin(0)
		, m_end(0)
		, m_last(0)
	{
		if (b.size() == 0) return;
		resize(b.size());
		std::memcpy(m_begin, b.begin(), b.size());
	}

	buffer& operator=(buffer const& b)
	{
		resize(b.size());
		std::memcpy(m_begin, b.begin(), b.size());
		return *this;
	}

	~buffer()
	{
		::operator delete (m_begin);
	}

	buffer::interval data() { return interval(m_begin, m_end); }
	buffer::const_interval data() const { return const_interval(m_begin, m_end); }

	void resize(std::size_t n)
	{
		reserve(n);
		m_end = m_begin + n;
	}

	void insert(char* point, char const* first, char const* last)
	{
		std::size_t p = point - m_begin;
		if (point == m_end)
		{
			resize(size() + last - first);
			std::memcpy(m_begin + p, first, last - first);
			return;
		}

		resize(size() + last - first);
		std::memmove(m_begin + p + (last - first), m_begin + p, last - first);
		std::memcpy(m_begin + p, first, last - first);
	}

	void erase(char* begin, char* end)
	{
		TORRENT_ASSERT(end <= m_end);
		TORRENT_ASSERT(begin >= m_begin);
		TORRENT_ASSERT(begin <= end);
	 	if (end == m_end)
		{
			resize(begin - m_begin);
			return;
		}
		std::memmove(begin, end, m_end - end);
		m_end = begin + (m_end - end);
	 }

	void clear() { m_end = m_begin; }
	std::size_t size() const { return m_end - m_begin; }
	std::size_t capacity() const { return m_last - m_begin; }
	void reserve(std::size_t n)
	{
		if (n <= capacity()) return;
		TORRENT_ASSERT(n > 0);

		char* buf = (char*)::operator new(n);
		std::size_t s = size();
		std::memcpy(buf, m_begin, s);
		::operator delete (m_begin);
		m_begin = buf;
		m_end = buf + s;
		m_last = m_begin + n;
	}

	bool empty() const { return m_begin == m_end; }
	char& operator[](std::size_t i) { TORRENT_ASSERT(i < size()); return m_begin[i]; }
	char const& operator[](std::size_t i) const { TORRENT_ASSERT(i < size()); return m_begin[i]; }

	char* begin() { return m_begin; }
	char const* begin() const { return m_begin; }
	char* end() { return m_end; }
	char const* end() const { return m_end; }

	void swap(buffer& b)
	{
		using std::swap;
		swap(m_begin, b.m_begin);
		swap(m_end, b.m_end);
		swap(m_last, b.m_last);
	}
private:
	char* m_begin; // first
	char* m_end; // one passed end of size
	char* m_last; // one passed end of allocation
};

}

#endif // LIBTORRENT_BUFFER_HPP

<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ppapi/shared_impl/audio_impl.h"

#include "base/atomicops.h"
#include "base/logging.h"

using base::subtle::Atomic32;

namespace ppapi {

AudioImpl::AudioImpl()
    : playing_(false),
      shared_memory_size_(0),
      callback_(NULL),
      user_data_(NULL) {
}

AudioImpl::~AudioImpl() {
  // Closing the socket causes the thread to exit - wait for it.
  if (socket_.get())
    socket_->Close();
  if (audio_thread_.get()) {
    audio_thread_->Join();
    audio_thread_.reset();
  }
}

::ppapi::thunk::PPB_Audio_API* AudioImpl::AsPPB_Audio_API() {
  return this;
}

void AudioImpl::SetCallback(PPB_Audio_Callback callback, void* user_data) {
  callback_ = callback;
  user_data_ = user_data;
}

void AudioImpl::SetStartPlaybackState() {
  DCHECK(!playing_);
  DCHECK(!audio_thread_.get());

  // If the socket doesn't exist, that means that the plugin has started before
  // the browser has had a chance to create all the shared memory info and
  // notify us. This is a common case. In this case, we just set the playing_
  // flag and the playback will automatically start when that data is available
  // in SetStreamInfo.
  if (callback_ && socket_.get())
    StartThread();
  playing_ = true;
}

void AudioImpl::SetStopPlaybackState() {
  DCHECK(playing_);

  if (audio_thread_.get()) {
    audio_thread_->Join();
    audio_thread_.reset();
  }
  playing_ = false;
}

void AudioImpl::SetStreamInfo(base::SharedMemoryHandle shared_memory_handle,
                              size_t shared_memory_size,
                              base::SyncSocket::Handle socket_handle) {
  socket_.reset(new base::SyncSocket(socket_handle));
  shared_memory_.reset(new base::SharedMemory(shared_memory_handle, false));
  shared_memory_size_ = shared_memory_size;

  if (callback_) {
    shared_memory_->Map(shared_memory_size_);

    // In common case StartPlayback() was called before StreamCreated().
    if (playing_)
      StartThread();
  }
}

void AudioImpl::StartThread() {
  DCHECK(callback_);
  DCHECK(!audio_thread_.get());
  audio_thread_.reset(new base::DelegateSimpleThread(
      this, "plugin_audio_thread"));
  audio_thread_->Start();
}

// PPB_AudioBuffersState defines the type of an audio buffer state structure
// sent when requesting to fill the audio buffer with data.
typedef struct {
  int pending_bytes;
  int hardware_delay_bytes;
  uint64_t timestamp;
} PPB_AudioBuffersState;
PP_COMPILE_ASSERT_SIZE_IN_BYTES(PPB_AudioBuffersState, 16);

void AudioImpl::Run() {
  PPB_AudioBuffersState buffer_state;

  for (;;) {
    int bytes_received = socket_->Receive(&buffer_state, sizeof(buffer_state));
    if (bytes_received == sizeof(int)) {
      // Accoding to C++ Standard, address of structure == address of its first
      // member, so it is safe to use buffer_state.bytes_received when we
      // receive just one int.
      COMPILE_ASSERT(
          offsetof(PPB_AudioBuffersState, pending_bytes) == 0,
          pending_bytes_should_be_first_member_of_PPB_AudioBuffersState);
      if (buffer_state.pending_bytes < 0)
        break;
      callback_(shared_memory_->memory(), shared_memory_size_, user_data_);
    } else if (bytes_received == sizeof(buffer_state)) {
      if (buffer_state.pending_bytes + buffer_state.hardware_delay_bytes < 0)
        break;

      // Assert that shared memory is properly aligned, so we can cast pointer
      // to the pointer to Atomic32.
      DCHECK_EQ(0u, reinterpret_cast<size_t>(shared_memory_->memory()) & 3);

      // TODO(enal): Instead of address arithmetics use functions that
      // encapsulate internal buffer structure. They should be moved somewhere
      // into ppapi, right now they are defined in media/audio/audio_util.h.
      uint32 data_size = shared_memory_size_ - sizeof(Atomic32);
      callback_(static_cast<char*>(shared_memory_->memory()) + sizeof(Atomic32),
                data_size,
                user_data_);
      base::subtle::Release_Store(
          static_cast<volatile Atomic32*>(shared_memory_->memory()),
          data_size);
    } else {
      break;
    }
  }
}

}  // namespace ppapi
<commit_msg>Revert "Prepare ppapi for chrome audio changes..."<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ppapi/shared_impl/audio_impl.h"

#include "base/logging.h"

namespace ppapi {

AudioImpl::AudioImpl()
    : playing_(false),
      shared_memory_size_(0),
      callback_(NULL),
      user_data_(NULL) {
}

AudioImpl::~AudioImpl() {
  // Closing the socket causes the thread to exit - wait for it.
  if (socket_.get())
    socket_->Close();
  if (audio_thread_.get()) {
    audio_thread_->Join();
    audio_thread_.reset();
  }
}

::ppapi::thunk::PPB_Audio_API* AudioImpl::AsPPB_Audio_API() {
  return this;
}

void AudioImpl::SetCallback(PPB_Audio_Callback callback, void* user_data) {
  callback_ = callback;
  user_data_ = user_data;
}

void AudioImpl::SetStartPlaybackState() {
  DCHECK(!playing_);
  DCHECK(!audio_thread_.get());

  // If the socket doesn't exist, that means that the plugin has started before
  // the browser has had a chance to create all the shared memory info and
  // notify us. This is a common case. In this case, we just set the playing_
  // flag and the playback will automatically start when that data is available
  // in SetStreamInfo.
  if (callback_ && socket_.get())
    StartThread();
  playing_ = true;
}

void AudioImpl::SetStopPlaybackState() {
  DCHECK(playing_);

  if (audio_thread_.get()) {
    audio_thread_->Join();
    audio_thread_.reset();
  }
  playing_ = false;
}

void AudioImpl::SetStreamInfo(base::SharedMemoryHandle shared_memory_handle,
                              size_t shared_memory_size,
                              base::SyncSocket::Handle socket_handle) {
  socket_.reset(new base::SyncSocket(socket_handle));
  shared_memory_.reset(new base::SharedMemory(shared_memory_handle, false));
  shared_memory_size_ = shared_memory_size;

  if (callback_) {
    shared_memory_->Map(shared_memory_size_);

    // In common case StartPlayback() was called before StreamCreated().
    if (playing_)
      StartThread();
  }
}

void AudioImpl::StartThread() {
  DCHECK(callback_);
  DCHECK(!audio_thread_.get());
  audio_thread_.reset(new base::DelegateSimpleThread(
      this, "plugin_audio_thread"));
  audio_thread_->Start();
}

void AudioImpl::Run() {
  int pending_data;
  void* buffer = shared_memory_->memory();

  while (sizeof(pending_data) ==
      socket_->Receive(&pending_data, sizeof(pending_data)) &&
      pending_data >= 0) {
    callback_(buffer, shared_memory_size_, user_data_);
  }
}

}  // namespace ppapi
<|endoftext|>


<commit_before>/* -------------------------------------------------------------------------- *
 *                           OpenSim:  forward.cpp                            *
 * -------------------------------------------------------------------------- *
 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
 * OpenSim is developed at Stanford University and supported by the US        *
 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
 * through the Warrior Web program.                                           *
 *                                                                            *
 * Copyright (c) 2005-2012 Stanford University and the Authors                *
 * Author(s): Frank C. Anderson                                               *
 *                                                                            *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
 * not use this file except in compliance with the License. You may obtain a  *
 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
 *                                                                            *
 * Unless required by applicable law or agreed to in writing, software        *
 * distributed under the License is distributed on an "AS IS" BASIS,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied    *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 * -------------------------------------------------------------------------- */

// INCLUDE
#include <string>
#include <iostream>
#include <OpenSim/version.h>
#include <OpenSim/Common/IO.h>
#include <OpenSim/Common/LoadOpenSimLibrary.h>
#include <OpenSim/Simulation/Model/Model.h>
#include <OpenSim/Simulation/Model/BodySet.h>
#include <OpenSim/Actuators/Schutte1993Muscle_Deprecated.h>
#include <OpenSim/Tools/ForwardTool.h>
#include "SimTKsimbody.h"

#include <ctime>  // clock(), clock_t, CLOCKS_PER_SEC

using namespace OpenSim;
using namespace std;

static void PrintUsage(const char *aProgName, ostream &aOStream);

//_____________________________________________________________________________
/**
 * Main routine for executing a forward integration and running a set of
 * analyses during the forward integration.
 */
int main(int argc,char **argv)
{

	//----------------------
	// Surrounding try block
	//----------------------
	try {
	//----------------------

	//LoadOpenSimLibrary("osimSdfastEngine");

	// PARSE COMMAND LINE
	int i;
	string option = "";
	string setupFileName = "";
	if(argc<2) {
		PrintUsage(argv[0], cout);
		return(-1);
	}
	// Load libraries first
	LoadOpenSimLibraries(argc,argv);
	for(i=1;i<argc;i++) {
		option = argv[i];

		// PRINT THE USAGE OPTIONS
		if((option=="-help")||(option=="-h")||(option=="-Help")||(option=="-H")||
		(option=="-usage")||(option=="-u")||(option=="-Usage")||(option=="-U")) {

			PrintUsage(argv[0], cout);
			return(0);

		// PRINT A DEFAULT SETUP FILE FOR THIS INVESTIGATION
		} else if((option=="-PrintSetup")||(option=="-PS")) {
			ForwardTool *tool = new ForwardTool();
			tool->setName("default");
			Object::setSerializeAllDefaults(true);
			tool->print("default_Setup_Forward.xml");
			Object::setSerializeAllDefaults(false);
			cout << "Created file default_Setup_Forward.xml with default setup" << endl;
			return(0);

		// IDENTIFY SETUP FILE
		} else if((option=="-Setup")||(option=="-S")) {
			if((i+1)<argc) setupFileName = argv[i+1];
			break;

		// PRINT PROPERTY INFO
		} else if((option=="-PropertyInfo")||(option=="-PI")) {
			if((i+1)>=argc) {
				Object::PrintPropertyInfo(cout,"");

			} else {
				char *compoundName = argv[i+1];
				if(compoundName[0]=='-') {
					Object::PrintPropertyInfo(cout,"");
				} else {
					Object::PrintPropertyInfo(cout,compoundName);
				}
			}
			return(0);
		}

	}
	// ERROR CHECK
	if(setupFileName=="") {
		cout<<"\n\nforward.exe: ERROR- A setup file must be specified.\n";
		PrintUsage(argv[0], cout);
		return(-1);
	}

	/*
	  ISSUE: need to explicitly laod the library osimActuators.
    */
	LoadOpenSimLibrary("osimActuators");

	// CONSTRUCT
	cout<<"Constructing tool from setup file "<<setupFileName<<".\n\n";
	ForwardTool forward(setupFileName);
	//forward.print("check.xml");

	// PRINT MODEL INFORMATION
	Model& model = forward.getModel();

	cout<<"-----------------------------------------------------------------------"<<endl;
	cout<<"Loaded library\n";
	cout<<"-----------------------------------------------------------------------"<<endl;
	cout<<"-----------------------------------------------------------------------"<<endl<<endl;

	// start timing
	std::clock_t startTime = std::clock();

	// RUN
	forward.run();

	std::cout << "Forward simulation time = " << 1.e3*(std::clock()-startTime)/CLOCKS_PER_SEC << "ms\n" << endl;

	//----------------------------
	// Catch any thrown exceptions
	//----------------------------
	} catch(const std::exception& x) {
        cout << "Exception in forward: " << x.what() << endl;
		return -1;
	}
	//----------------------------

	return(0);
}

//_____________________________________________________________________________
/**
 * Print the usage for this application
 */
void PrintUsage(const char *aProgName, ostream &aOStream)
{
	string progName=IO::GetFileNameFromURI(aProgName);
	aOStream<<"\n\n"<<progName<<":\n"<<GetVersionAndDate()<<"\n\n";
	aOStream<<"Option              Argument         Action / Notes\n";
	aOStream<<"------              --------         --------------\n";
	aOStream<<"-Help, -H                            Print the command-line options for forward.exe.\n";
	aOStream<<"-PrintSetup, -PS                     Print a default setup file for forward.exe (default_forward.xml).\n";
	aOStream<<"-Setup, -S          SetupFileName    Specify the name of the XML setup file to use for this forward tool.\n";
	aOStream<<"-PropertyInfo, -PI                   Print help information for properties in setup files.\n";

	//aOStream<<"\nThe input to the -PropertyInfo option is the name of the class to which a property\n";
	//aOStream<<"belongs, followed by a '.', followed by the name of the property.  If a class name\n";
	//aOStream<<"is not specified, a list of all registered classes is printed. If a class name is\n";
	//aOStream<<"specified, but a property is not, a list of all properties in that class is printed.\n";
}

<commit_msg>Remove misleading debugging line from froward<commit_after>/* -------------------------------------------------------------------------- *
 *                           OpenSim:  forward.cpp                            *
 * -------------------------------------------------------------------------- *
 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
 * OpenSim is developed at Stanford University and supported by the US        *
 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
 * through the Warrior Web program.                                           *
 *                                                                            *
 * Copyright (c) 2005-2012 Stanford University and the Authors                *
 * Author(s): Frank C. Anderson                                               *
 *                                                                            *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
 * not use this file except in compliance with the License. You may obtain a  *
 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
 *                                                                            *
 * Unless required by applicable law or agreed to in writing, software        *
 * distributed under the License is distributed on an "AS IS" BASIS,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied    *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 * -------------------------------------------------------------------------- */

// INCLUDE
#include <string>
#include <iostream>
#include <OpenSim/version.h>
#include <OpenSim/Common/IO.h>
#include <OpenSim/Common/LoadOpenSimLibrary.h>
#include <OpenSim/Simulation/Model/Model.h>
#include <OpenSim/Simulation/Model/BodySet.h>
#include <OpenSim/Actuators/Schutte1993Muscle_Deprecated.h>
#include <OpenSim/Tools/ForwardTool.h>
#include "SimTKsimbody.h"

#include <ctime>  // clock(), clock_t, CLOCKS_PER_SEC

using namespace OpenSim;
using namespace std;

static void PrintUsage(const char *aProgName, ostream &aOStream);

//_____________________________________________________________________________
/**
 * Main routine for executing a forward integration and running a set of
 * analyses during the forward integration.
 */
int main(int argc,char **argv)
{

	//----------------------
	// Surrounding try block
	//----------------------
	try {
	//----------------------

	//LoadOpenSimLibrary("osimSdfastEngine");

	// PARSE COMMAND LINE
	int i;
	string option = "";
	string setupFileName = "";
	if(argc<2) {
		PrintUsage(argv[0], cout);
		return(-1);
	}
	// Load libraries first
	LoadOpenSimLibraries(argc,argv);
	for(i=1;i<argc;i++) {
		option = argv[i];

		// PRINT THE USAGE OPTIONS
		if((option=="-help")||(option=="-h")||(option=="-Help")||(option=="-H")||
		(option=="-usage")||(option=="-u")||(option=="-Usage")||(option=="-U")) {

			PrintUsage(argv[0], cout);
			return(0);

		// PRINT A DEFAULT SETUP FILE FOR THIS INVESTIGATION
		} else if((option=="-PrintSetup")||(option=="-PS")) {
			ForwardTool *tool = new ForwardTool();
			tool->setName("default");
			Object::setSerializeAllDefaults(true);
			tool->print("default_Setup_Forward.xml");
			Object::setSerializeAllDefaults(false);
			cout << "Created file default_Setup_Forward.xml with default setup" << endl;
			return(0);

		// IDENTIFY SETUP FILE
		} else if((option=="-Setup")||(option=="-S")) {
			if((i+1)<argc) setupFileName = argv[i+1];
			break;

		// PRINT PROPERTY INFO
		} else if((option=="-PropertyInfo")||(option=="-PI")) {
			if((i+1)>=argc) {
				Object::PrintPropertyInfo(cout,"");

			} else {
				char *compoundName = argv[i+1];
				if(compoundName[0]=='-') {
					Object::PrintPropertyInfo(cout,"");
				} else {
					Object::PrintPropertyInfo(cout,compoundName);
				}
			}
			return(0);
		}

	}
	// ERROR CHECK
	if(setupFileName=="") {
		cout<<"\n\nforward.exe: ERROR- A setup file must be specified.\n";
		PrintUsage(argv[0], cout);
		return(-1);
	}

	/*
	  ISSUE: need to explicitly laod the library osimActuators.
    */
	LoadOpenSimLibrary("osimActuators");

	// CONSTRUCT
	cout<<"Constructing tool from setup file "<<setupFileName<<".\n\n";
	ForwardTool forward(setupFileName);

	// PRINT MODEL INFORMATION
	Model& model = forward.getModel();

	cout<<"-----------------------------------------------------------------------"<<endl;

	// start timing
	std::clock_t startTime = std::clock();

	// RUN
	forward.run();

	std::cout << "Forward simulation time = " << 1.e3*(std::clock()-startTime)/CLOCKS_PER_SEC << "ms\n" << endl;

	//----------------------------
	// Catch any thrown exceptions
	//----------------------------
	} catch(const std::exception& x) {
        cout << "Exception in forward: " << x.what() << endl;
		return -1;
	}
	//----------------------------

	return(0);
}

//_____________________________________________________________________________
/**
 * Print the usage for this application
 */
void PrintUsage(const char *aProgName, ostream &aOStream)
{
	string progName=IO::GetFileNameFromURI(aProgName);
	aOStream<<"\n\n"<<progName<<":\n"<<GetVersionAndDate()<<"\n\n";
	aOStream<<"Option              Argument         Action / Notes\n";
	aOStream<<"------              --------         --------------\n";
	aOStream<<"-Help, -H                            Print the command-line options for forward.exe.\n";
	aOStream<<"-PrintSetup, -PS                     Print a default setup file for forward.exe (default_forward.xml).\n";
	aOStream<<"-Setup, -S          SetupFileName    Specify the name of the XML setup file to use for this forward tool.\n";
	aOStream<<"-PropertyInfo, -PI                   Print help information for properties in setup files.\n";

	//aOStream<<"\nThe input to the -PropertyInfo option is the name of the class to which a property\n";
	//aOStream<<"belongs, followed by a '.', followed by the name of the property.  If a class name\n";
	//aOStream<<"is not specified, a list of all registered classes is printed. If a class name is\n";
	//aOStream<<"specified, but a property is not, a list of all properties in that class is printed.\n";
}

<|endoftext|>


<commit_before>//
// Copyright (C) 2011-15 DyND Developers
// BSD 2-Clause License, see LICENSE.txt
//

#pragma once

#include <Python.h>

#include <dynd/type_registry.hpp>

#include "pyobject_type.hpp"

using namespace dynd;

// Unpack and convert a single element to a PyObject.
template <typename T>
inline std::enable_if_t<std::is_signed<T>::value && std::numeric_limits<T>::max() <= INT64_MAX, PyObject *>
unpack_single(const char *data)
{
    return PyLong_FromLongLong(*reinterpret_cast<const T *>(data));
}

template <typename T>
inline std::enable_if_t<std::is_unsigned<T>::value && std::numeric_limits<T>::max() <= UINT64_MAX, PyObject *>
unpack_single(const char *data)
{
    return PyLong_FromUnsignedLongLong(*reinterpret_cast<const T *>(data));
}

template <typename T>
inline std::enable_if_t<std::is_same<T, bool1>::value, PyObject *>
unpack_single(const char *data)
{
    return PyBool_FromLong(*reinterpret_cast<const T *>(data));
}

template <typename T>
inline std::enable_if_t<std::is_same<T, float64>::value, PyObject *>
unpack_single(const char *data)
{
    return PyFloat_FromDouble(*reinterpret_cast<const T *>(data));
}

template <typename T>
inline std::enable_if_t<std::is_same<T, complex128>::value, PyObject *>
unpack_single(const char *data)
{
    complex128 c = *reinterpret_cast<const T *>(data);
    return PyComplex_FromDoubles(c.real(), c.imag());
}

template <typename T>
inline std::enable_if_t<std::is_same<T, std::string>::value, PyObject *>
unpack_single(const char *data)
{
    const std::string &s = *reinterpret_cast<const T *>(data);
    return PyUnicode_FromString(s.data());
}

template <typename T>
inline std::enable_if_t<std::is_same<T, ndt::type>::value, PyObject *>
unpack_single(const char *data)
{
    return pydynd::type_from_cpp(*reinterpret_cast<const T *>(data));
}

// Convert a single element to a PyObject.
template <typename T>
inline std::enable_if_t<std::is_signed<T>::value && std::numeric_limits<T>::max() <= INT64_MAX, PyObject *>
convert_single(T value)
{
    return PyLong_FromLongLong(value);
}

template <typename T>
inline std::enable_if_t<std::is_unsigned<T>::value && std::numeric_limits<T>::max() <= UINT64_MAX, PyObject *>
convert_single(T value)
{
    return PyLong_FromUnsignedLongLong(value);
}

template <typename T>
inline std::enable_if_t<std::is_same<T, bool1>::value, PyObject *>
convert_single(T value)
{
    return PyBool_FromLong(value);
}

template <typename T>
inline std::enable_if_t<std::is_same<T, float64>::value, PyObject *>
convert_single(T value)
{
    return PyFloat_FromDouble(value);
}

template <typename T>
inline std::enable_if_t<std::is_same<T, complex128>::value, PyObject *>
convert_single(T value)
{
    return PyComplex_FromDoubles(value.real(), value.imag());
}

template <typename T>
inline std::enable_if_t<std::is_same<T, std::string>::value, PyObject *>
convert_single(const T &value)
{
    return PyUnicode_FromString(value.data());
}

template <typename T>
inline std::enable_if_t<std::is_same<T, ndt::type>::value, PyObject *>
convert_single(const T &value)
{
    return pydynd::type_from_cpp(value);
}

template <typename T>
PyObject *unpack_vector(const char *data)
{
    auto &vec = *reinterpret_cast<const std::vector<T> *>(data);
    PyObject *lst, *item;

    lst = PyList_New(vec.size());
    if (lst == NULL) {
        return NULL;
    }

    for (size_t i = 0; i < vec.size(); ++i) {
        item = convert_single<T>(vec[i]);
        if (item == NULL) {
            Py_DECREF(lst);
            return NULL;
        }
        PyList_SET_ITEM(lst, i, item);
    }

    return lst;
}

template <typename T>
inline PyObject *unpack(bool is_vector, const char *data)
{
    if (is_vector) {
        return unpack_vector<T>(data);
    }
    else {
        return unpack_single<T>(data);
    }
}

PyObject *from_type_property(const std::pair<ndt::type, const char *> &pair)
{
  type_id_t id = pair.first.get_id();
  bool is_vector = false;

  if (id == fixed_dim_id) {
    id = pair.first.get_dtype().get_id();
    is_vector = true;
  }

  switch (id) {
  case bool_id:
    return unpack<bool1>(is_vector, pair.second);
  case int8_id:
    return unpack<int8>(is_vector, pair.second);
  case int16_id:
    return unpack<int16>(is_vector, pair.second);
  case int32_id:
    return unpack<int32>(is_vector, pair.second);
  case int64_id:
    return unpack<int64>(is_vector, pair.second);
  case uint8_id:
    return unpack<uint8>(is_vector, pair.second);
  case uint16_id:
    return unpack<uint16>(is_vector, pair.second);
  case uint32_id:
    return unpack<uint32>(is_vector, pair.second);
  case uint64_id:
    return unpack<uint64>(is_vector, pair.second);
  case float64_id:
    return unpack<float64>(is_vector, pair.second);
  case complex_float64_id:
    return unpack<complex128>(is_vector, pair.second);
  case type_id:
    return unpack<ndt::type>(is_vector, pair.second);
  case string_id:
    return unpack<std::string>(is_vector, pair.second);
  default:
    throw std::runtime_error("invalid type property");
  }
}

<commit_msg>Add include.<commit_after>//
// Copyright (C) 2011-15 DyND Developers
// BSD 2-Clause License, see LICENSE.txt
//

#pragma once

#include <Python.h>

#include <dynd/type_registry.hpp>
#include <type_traits>

#include "pyobject_type.hpp"

using namespace dynd;

// Unpack and convert a single element to a PyObject.
template <typename T>
inline std::enable_if_t<std::is_signed<T>::value && std::numeric_limits<T>::max() <= INT64_MAX, PyObject *>
unpack_single(const char *data)
{
    return PyLong_FromLongLong(*reinterpret_cast<const T *>(data));
}

template <typename T>
inline std::enable_if_t<std::is_unsigned<T>::value && std::numeric_limits<T>::max() <= UINT64_MAX, PyObject *>
unpack_single(const char *data)
{
    return PyLong_FromUnsignedLongLong(*reinterpret_cast<const T *>(data));
}

template <typename T>
inline std::enable_if_t<std::is_same<T, bool1>::value, PyObject *>
unpack_single(const char *data)
{
    return PyBool_FromLong(*reinterpret_cast<const T *>(data));
}

template <typename T>
inline std::enable_if_t<std::is_same<T, float64>::value, PyObject *>
unpack_single(const char *data)
{
    return PyFloat_FromDouble(*reinterpret_cast<const T *>(data));
}

template <typename T>
inline std::enable_if_t<std::is_same<T, complex128>::value, PyObject *>
unpack_single(const char *data)
{
    complex128 c = *reinterpret_cast<const T *>(data);
    return PyComplex_FromDoubles(c.real(), c.imag());
}

template <typename T>
inline std::enable_if_t<std::is_same<T, std::string>::value, PyObject *>
unpack_single(const char *data)
{
    const std::string &s = *reinterpret_cast<const T *>(data);
    return PyUnicode_FromString(s.data());
}

template <typename T>
inline std::enable_if_t<std::is_same<T, ndt::type>::value, PyObject *>
unpack_single(const char *data)
{
    return pydynd::type_from_cpp(*reinterpret_cast<const T *>(data));
}

// Convert a single element to a PyObject.
template <typename T>
inline std::enable_if_t<std::is_signed<T>::value && std::numeric_limits<T>::max() <= INT64_MAX, PyObject *>
convert_single(T value)
{
    return PyLong_FromLongLong(value);
}

template <typename T>
inline std::enable_if_t<std::is_unsigned<T>::value && std::numeric_limits<T>::max() <= UINT64_MAX, PyObject *>
convert_single(T value)
{
    return PyLong_FromUnsignedLongLong(value);
}

template <typename T>
inline std::enable_if_t<std::is_same<T, bool1>::value, PyObject *>
convert_single(T value)
{
    return PyBool_FromLong(value);
}

template <typename T>
inline std::enable_if_t<std::is_same<T, float64>::value, PyObject *>
convert_single(T value)
{
    return PyFloat_FromDouble(value);
}

template <typename T>
inline std::enable_if_t<std::is_same<T, complex128>::value, PyObject *>
convert_single(T value)
{
    return PyComplex_FromDoubles(value.real(), value.imag());
}

template <typename T>
inline std::enable_if_t<std::is_same<T, std::string>::value, PyObject *>
convert_single(const T &value)
{
    return PyUnicode_FromString(value.data());
}

template <typename T>
inline std::enable_if_t<std::is_same<T, ndt::type>::value, PyObject *>
convert_single(const T &value)
{
    return pydynd::type_from_cpp(value);
}

template <typename T>
PyObject *unpack_vector(const char *data)
{
    auto &vec = *reinterpret_cast<const std::vector<T> *>(data);
    PyObject *lst, *item;

    lst = PyList_New(vec.size());
    if (lst == NULL) {
        return NULL;
    }

    for (size_t i = 0; i < vec.size(); ++i) {
        item = convert_single<T>(vec[i]);
        if (item == NULL) {
            Py_DECREF(lst);
            return NULL;
        }
        PyList_SET_ITEM(lst, i, item);
    }

    return lst;
}

template <typename T>
inline PyObject *unpack(bool is_vector, const char *data)
{
    if (is_vector) {
        return unpack_vector<T>(data);
    }
    else {
        return unpack_single<T>(data);
    }
}

PyObject *from_type_property(const std::pair<ndt::type, const char *> &pair)
{
  type_id_t id = pair.first.get_id();
  bool is_vector = false;

  if (id == fixed_dim_id) {
    id = pair.first.get_dtype().get_id();
    is_vector = true;
  }

  switch (id) {
  case bool_id:
    return unpack<bool1>(is_vector, pair.second);
  case int8_id:
    return unpack<int8>(is_vector, pair.second);
  case int16_id:
    return unpack<int16>(is_vector, pair.second);
  case int32_id:
    return unpack<int32>(is_vector, pair.second);
  case int64_id:
    return unpack<int64>(is_vector, pair.second);
  case uint8_id:
    return unpack<uint8>(is_vector, pair.second);
  case uint16_id:
    return unpack<uint16>(is_vector, pair.second);
  case uint32_id:
    return unpack<uint32>(is_vector, pair.second);
  case uint64_id:
    return unpack<uint64>(is_vector, pair.second);
  case float64_id:
    return unpack<float64>(is_vector, pair.second);
  case complex_float64_id:
    return unpack<complex128>(is_vector, pair.second);
  case type_id:
    return unpack<ndt::type>(is_vector, pair.second);
  case string_id:
    return unpack<std::string>(is_vector, pair.second);
  default:
    throw std::runtime_error("invalid type property");
  }
}

<|endoftext|>