<commit_before>//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// EGLChooseConfigTest.cpp:
//   Tests of proper default-value semantics for eglChooseConfig

#include <gtest/gtest.h>

#include "test_utils/ANGLETest.h"
#include "test_utils/angle_test_configs.h"
#include "util/EGLWindow.h"

using namespace angle;

namespace angle
{
class EGLChooseConfigTest : public ANGLETest
{
  protected:
    EGLChooseConfigTest() {}
};

// Test that the EGL_COLOR_BUFFER_TYPE is defaulted to EGL_RGB_BUFFER
TEST_P(EGLChooseConfigTest, Defaults)
{
    EGLDisplay display = getEGLWindow()->getDisplay();

    EGLint nConfigs       = 0;
    EGLint allConfigCount = 0;
    ASSERT_EGL_TRUE(eglGetConfigs(display, nullptr, 0, &nConfigs));
    ASSERT_NE(nConfigs, 0);

    std::vector<EGLConfig> allConfigs(nConfigs);
    ASSERT_EGL_TRUE(eglGetConfigs(display, allConfigs.data(), nConfigs, &allConfigCount));
    ASSERT_EQ(nConfigs, allConfigCount);

    // Choose configs that have the default attribute values:
    const EGLint defaultConfigAttributes[] = {EGL_NONE};
    EGLint defaultConfigCount;
    std::vector<EGLConfig> defaultConfigs(allConfigCount);
    ASSERT_EGL_TRUE(eglChooseConfig(display, defaultConfigAttributes, defaultConfigs.data(),
                                    defaultConfigs.size(), &defaultConfigCount));
    ASSERT_EGL_SUCCESS();
    ASSERT_LE(defaultConfigCount, allConfigCount);

    // Check that the default configs all have the default attribute values we care about:
    for (EGLConfig config : defaultConfigs)
    {
        EGLint colorBufferType, level, renderableType, surfaceType, transparentType;
        EGLint colorComponentType;

        eglGetConfigAttrib(display, config, EGL_COLOR_BUFFER_TYPE, &colorBufferType);
        ASSERT_EQ(colorBufferType, EGL_RGB_BUFFER);

        eglGetConfigAttrib(display, config, EGL_LEVEL, &level);
        ASSERT_EQ(level, 0);

        eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &renderableType);
        ASSERT_EQ(renderableType & EGL_OPENGL_ES_BIT, EGL_OPENGL_ES_BIT);

        eglGetConfigAttrib(display, config, EGL_SURFACE_TYPE, &surfaceType);
        ASSERT_EQ(surfaceType & EGL_WINDOW_BIT, EGL_WINDOW_BIT);

        eglGetConfigAttrib(display, config, EGL_TRANSPARENT_TYPE, &transparentType);
        ASSERT_EQ(transparentType, EGL_NONE);

        if (IsEGLDisplayExtensionEnabled(display, "EGL_EXT_pixel_format_float"))
        {
            eglGetConfigAttrib(display, config, EGL_COLOR_COMPONENT_TYPE_EXT, &colorComponentType);
            ASSERT_EQ(colorComponentType, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT);
        }
    }

    // Check that all of the configs that have the default attribute values are are defaultConfigs,
    // and all that don't aren't:
    for (EGLConfig config : allConfigs)
    {
        EGLint colorBufferType, level, renderableType, surfaceType, transparentType;
        EGLint colorComponentType = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;

        eglGetConfigAttrib(display, config, EGL_COLOR_BUFFER_TYPE, &colorBufferType);
        eglGetConfigAttrib(display, config, EGL_LEVEL, &level);
        eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &renderableType);
        eglGetConfigAttrib(display, config, EGL_SURFACE_TYPE, &surfaceType);
        eglGetConfigAttrib(display, config, EGL_TRANSPARENT_TYPE, &transparentType);
        if (IsEGLDisplayExtensionEnabled(display, "EGL_EXT_pixel_format_float"))
        {
            eglGetConfigAttrib(display, config, EGL_COLOR_COMPONENT_TYPE_EXT, &colorComponentType);
        }

        bool isADefault =
            ((colorBufferType == EGL_RGB_BUFFER) && (level == 0) &&
             ((renderableType & EGL_OPENGL_ES_BIT) == EGL_OPENGL_ES_BIT) &&
             ((surfaceType & EGL_WINDOW_BIT) == EGL_WINDOW_BIT) && (transparentType == EGL_NONE) &&
             (colorComponentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT));
        EGLint thisConfigID;
        eglGetConfigAttrib(display, config, EGL_CONFIG_ID, &thisConfigID);
        bool foundInDefaultConfigs = false;
        // Attempt to find this config ID in defaultConfigs:
        for (EGLConfig defaultConfig : defaultConfigs)
        {
            EGLint defaultConfigID;
            eglGetConfigAttrib(display, defaultConfig, EGL_CONFIG_ID, &defaultConfigID);
            if (defaultConfigID == thisConfigID)
            {
                foundInDefaultConfigs = true;
            }
        }
        ASSERT_EQ(isADefault, foundInDefaultConfigs);
    }
}

}  // namespace angle

ANGLE_INSTANTIATE_TEST(EGLChooseConfigTest,
                       ES2_D3D11(),
                       ES2_D3D9(),
                       ES2_METAL(),
                       ES2_OPENGL(),
                       ES2_OPENGLES(),
                       ES2_VULKAN());
<commit_msg>Vulkan: Resize the result vector in EGLChooseConfigTest end2end test<commit_after>//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// EGLChooseConfigTest.cpp:
//   Tests of proper default-value semantics for eglChooseConfig

#include <gtest/gtest.h>

#include "test_utils/ANGLETest.h"
#include "test_utils/angle_test_configs.h"
#include "util/EGLWindow.h"

using namespace angle;

namespace angle
{
class EGLChooseConfigTest : public ANGLETest
{
  protected:
    EGLChooseConfigTest() {}
};

// Test that the EGL_COLOR_BUFFER_TYPE is defaulted to EGL_RGB_BUFFER
TEST_P(EGLChooseConfigTest, Defaults)
{
    EGLDisplay display = getEGLWindow()->getDisplay();

    EGLint nConfigs       = 0;
    EGLint allConfigCount = 0;
    ASSERT_EGL_TRUE(eglGetConfigs(display, nullptr, 0, &nConfigs));
    ASSERT_NE(nConfigs, 0);

    std::vector<EGLConfig> allConfigs(nConfigs);
    ASSERT_EGL_TRUE(eglGetConfigs(display, allConfigs.data(), nConfigs, &allConfigCount));
    ASSERT_EQ(nConfigs, allConfigCount);

    // Choose configs that have the default attribute values:
    const EGLint defaultConfigAttributes[] = {EGL_NONE};
    EGLint defaultConfigCount;
    std::vector<EGLConfig> defaultConfigs(allConfigCount);
    ASSERT_EGL_TRUE(eglChooseConfig(display, defaultConfigAttributes, defaultConfigs.data(),
                                    defaultConfigs.size(), &defaultConfigCount));
    ASSERT_EGL_SUCCESS();
    ASSERT_LE(defaultConfigCount, allConfigCount);
    defaultConfigs.resize(defaultConfigCount);

    // Check that the default configs all have the default attribute values we care about:
    for (EGLConfig config : defaultConfigs)
    {
        EGLint colorBufferType, level, renderableType, surfaceType, transparentType;
        EGLint colorComponentType;

        eglGetConfigAttrib(display, config, EGL_COLOR_BUFFER_TYPE, &colorBufferType);
        ASSERT_EQ(colorBufferType, EGL_RGB_BUFFER);

        eglGetConfigAttrib(display, config, EGL_LEVEL, &level);
        ASSERT_EQ(level, 0);

        eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &renderableType);
        ASSERT_EQ(renderableType & EGL_OPENGL_ES_BIT, EGL_OPENGL_ES_BIT);

        eglGetConfigAttrib(display, config, EGL_SURFACE_TYPE, &surfaceType);
        ASSERT_EQ(surfaceType & EGL_WINDOW_BIT, EGL_WINDOW_BIT);

        eglGetConfigAttrib(display, config, EGL_TRANSPARENT_TYPE, &transparentType);
        ASSERT_EQ(transparentType, EGL_NONE);

        if (IsEGLDisplayExtensionEnabled(display, "EGL_EXT_pixel_format_float"))
        {
            eglGetConfigAttrib(display, config, EGL_COLOR_COMPONENT_TYPE_EXT, &colorComponentType);
            ASSERT_EQ(colorComponentType, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT);
        }
    }

    // Check that all of the configs that have the default attribute values are are defaultConfigs,
    // and all that don't aren't:
    for (EGLConfig config : allConfigs)
    {
        EGLint colorBufferType, level, renderableType, surfaceType, transparentType;
        EGLint colorComponentType = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;

        eglGetConfigAttrib(display, config, EGL_COLOR_BUFFER_TYPE, &colorBufferType);
        eglGetConfigAttrib(display, config, EGL_LEVEL, &level);
        eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &renderableType);
        eglGetConfigAttrib(display, config, EGL_SURFACE_TYPE, &surfaceType);
        eglGetConfigAttrib(display, config, EGL_TRANSPARENT_TYPE, &transparentType);
        if (IsEGLDisplayExtensionEnabled(display, "EGL_EXT_pixel_format_float"))
        {
            eglGetConfigAttrib(display, config, EGL_COLOR_COMPONENT_TYPE_EXT, &colorComponentType);
        }

        bool isADefault =
            ((colorBufferType == EGL_RGB_BUFFER) && (level == 0) &&
             ((renderableType & EGL_OPENGL_ES_BIT) == EGL_OPENGL_ES_BIT) &&
             ((surfaceType & EGL_WINDOW_BIT) == EGL_WINDOW_BIT) && (transparentType == EGL_NONE) &&
             (colorComponentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT));
        EGLint thisConfigID;
        eglGetConfigAttrib(display, config, EGL_CONFIG_ID, &thisConfigID);
        bool foundInDefaultConfigs = false;
        // Attempt to find this config ID in defaultConfigs:
        for (EGLConfig defaultConfig : defaultConfigs)
        {
            EGLint defaultConfigID;
            eglGetConfigAttrib(display, defaultConfig, EGL_CONFIG_ID, &defaultConfigID);
            if (defaultConfigID == thisConfigID)
            {
                foundInDefaultConfigs = true;
            }
        }
        ASSERT_EQ(isADefault, foundInDefaultConfigs);
    }
}

}  // namespace angle

ANGLE_INSTANTIATE_TEST(EGLChooseConfigTest,
                       ES2_D3D11(),
                       ES2_D3D9(),
                       ES2_METAL(),
                       ES2_OPENGL(),
                       ES2_OPENGLES(),
                       ES2_VULKAN());
<|endoftext|>


<commit_before>#include "GlQuadTreeLODCalculator.h"
#include "Utils.h"
#include "QuadTree.h"
#include "GlEntity.h"
#include "GlLayer.h"

#ifdef _OPENMP
#include <omp.h>
#endif

#include <tulip/Matrix.h>
#include <tulip/LayoutProperty.h>
#include <tulip/PropertyInterface.h>

using namespace std;
using namespace tlp;

GlQuadTreeLODCalculator::GlQuadTreeLODCalculator() : _nodesQuadTree(NULL), _edgesQuadTree(NULL), _haveToCompute(true) {
#ifdef __EMSCRIPTEN__
  _haveToCompute = false;
#endif
}

GlQuadTreeLODCalculator::~GlQuadTreeLODCalculator() {
  std::map<GlLayer*, QuadTreeNode<GlEntity*> *>::iterator it = _glEntitiesQuadTree.begin();
  for (; it != _glEntitiesQuadTree.end() ; ++it) {
    delete it->second;
  }
  delete _nodesQuadTree;
  delete _edgesQuadTree;
}

void GlQuadTreeLODCalculator::setGraph(tlp::Graph *graph, GlGraphRenderingParameters *renderingParameters) {
  _haveToCompute = true;
  GlCPULODCalculator::setGraph(graph, renderingParameters);
}

void GlQuadTreeLODCalculator::initQuadTree() {
  std::map<GlLayer*, QuadTreeNode<GlEntity*> *>::iterator it = _glEntitiesQuadTree.begin();
  for (; it != _glEntitiesQuadTree.end() ; ++it) {
    delete it->second;
  }
  _glEntitiesQuadTree.clear();
  delete _nodesQuadTree;
  delete _edgesQuadTree;

  _nodesQuadTree = new QuadTreeNode<node>(_sceneBoundingBox);
  _edgesQuadTree = new QuadTreeNode<edge>(_sceneBoundingBox);
}

void GlQuadTreeLODCalculator::clear() {
  GlCPULODCalculator::clear();
  initQuadTree();
}

void GlQuadTreeLODCalculator::setSceneBoundingBox(const tlp::BoundingBox &sceneBoundingBox) {
  GlCPULODCalculator::setSceneBoundingBox(sceneBoundingBox);
  initQuadTree();
}

void GlQuadTreeLODCalculator::addGlEntity(GlLayer *layer, GlEntity *glEntity) {
  if (_sceneBoundingBox.isValid() && _glEntitiesQuadTree.find(layer) == _glEntitiesQuadTree.end()) {
    _glEntitiesQuadTree[layer] = new QuadTreeNode<GlEntity*>(_sceneBoundingBox);
  }
  if (_sceneBoundingBox.isValid() && _glEntitiesQuadTree[layer]->getCellForElement(glEntity) == NULL) {
    _glEntitiesQuadTree[layer]->insert(glEntity->getBoundingBox(), glEntity);
  }
  GlCPULODCalculator::addGlEntity(layer, glEntity);
}

void GlQuadTreeLODCalculator::removeGlEntity(GlLayer *layer, GlEntity *glEntity) {
  if (_glEntitiesQuadTree.find(layer) != _glEntitiesQuadTree.end()) {
    _glEntitiesQuadTree[layer]->remove(glEntity);
  }
}

void GlQuadTreeLODCalculator::removeLayer(GlLayer *layer) {
  if (_glEntitiesQuadTree.find(layer) != _glEntitiesQuadTree.end()) {
    delete _glEntitiesQuadTree[layer];
    _glEntitiesQuadTree.erase(layer);
  }
}

void GlQuadTreeLODCalculator::addNode(const tlp::node n) {
  GlCPULODCalculator::addNode(n);
  insertNodeInQuadTree(_nodesLODVector.back().boundingBox, n);
}

void GlQuadTreeLODCalculator::addEdge(const tlp::edge e) {
  GlCPULODCalculator::addEdge(e);
  insertEdgeInQuadTree(_edgesLODVector.back().boundingBox, e);
}

void GlQuadTreeLODCalculator::insertNodeInQuadTree(const tlp::BoundingBox &nodeBoundingBox, const tlp::node n) {
  _nodesQuadTree->insert(nodeBoundingBox, n);
}

void GlQuadTreeLODCalculator::insertEdgeInQuadTree(BoundingBox edgeBoundingBox, const tlp::edge e) {
  // This code is here to expand edge bounding box when we have an edge with direction (0,0,x)
  if(edgeBoundingBox[0][0] == edgeBoundingBox[1][0] && edgeBoundingBox[0][1] == edgeBoundingBox[1][1]) {
    edgeBoundingBox.expand(edgeBoundingBox[1]+Coord(0.01,0.01,0));
  }
  _edgesQuadTree->insert(edgeBoundingBox, e);
}

void GlQuadTreeLODCalculator::computeFor3DCamera(const Coord &eye, const Matrix<float, 4> &transformMatrix,
                                                 const Vector<int,4>& globalViewport, const Vector<int,4>& currentViewport) {

  // aX,aY : rotation on the camera in x and y
  Coord eyeCenter=camera->getCenter()-camera->getEyes();
  double aX=atan(eyeCenter[1]/eyeCenter[2]);
  double aY=atan(eyeCenter[0]/eyeCenter[2]);

  _glEntitiesLODVector.clear();
  _nodesLODVector.clear();
  _edgesLODVector.clear();

  MatrixGL invTransformMatrix(transformMatrix);
  invTransformMatrix.inverse();
  Coord pSrc = projectPoint(Coord(0,0,0), transformMatrix, globalViewport);

  Vector<int,4> transformedViewport=currentViewport;
  transformedViewport[1]=globalViewport[3]-(currentViewport[1]+currentViewport[3]);
  BoundingBox cameraBoundingBox;

  // Project camera bounding box to known visible part of the quadtree
  pSrc[0] = transformedViewport[0];
  pSrc[1] = (globalViewport[1] + globalViewport[3]) - (transformedViewport[1] + transformedViewport[3]);
  cameraBoundingBox.expand(unprojectPoint(pSrc, invTransformMatrix, globalViewport));
  pSrc[1] = transformedViewport[1]+transformedViewport[3];
  cameraBoundingBox.expand(unprojectPoint(pSrc, invTransformMatrix, globalViewport));
  pSrc[0] = transformedViewport[0]+transformedViewport[2];
  cameraBoundingBox.expand(unprojectPoint(pSrc, invTransformMatrix, globalViewport));
  pSrc[1] = transformedViewport[1];
  cameraBoundingBox.expand(unprojectPoint(pSrc, invTransformMatrix, globalViewport));

  // Get result of quadtrees
#ifdef _OPENMP
#pragma omp parallel
#endif
  {
#ifdef _OPENMP
#pragma omp sections nowait
#endif
    {
#ifdef _OPENMP
#pragma omp section
#endif
      {
        if((_renderingEntitiesFlag & RenderingGlEntities)!=0) {
          std::map<GlLayer*, QuadTreeNode<GlEntity*> *>::iterator it = _glEntitiesQuadTree.begin();
          for (; it != _glEntitiesQuadTree.end() ; ++it) {
            vector<GlEntity*> resGlEntities;
            if(aX==0 && aY==0) {
              it->second->getElements(cameraBoundingBox,resGlEntities);
            }
            else {
              it->second->getElements(resGlEntities);
            }

            for(size_t i = 0 ; i < resGlEntities.size() ; ++i) {
              _glEntitiesLODVector[it->first].push_back(GlEntityLODUnit(resGlEntities[i]));
            }
          }
        }
      }
#ifdef _OPENMP
#pragma omp section
#endif
      {
        if(_graph && (_renderingEntitiesFlag & RenderingNodes)!=0) {
          vector<node> resNodes;
          resNodes.reserve(_graph->numberOfNodes());
          if(aX==0 && aY==0) {
            if(_nodesQuadTree)
              _nodesQuadTree->getElements(cameraBoundingBox,resNodes);
          }
          else {
            if(_nodesQuadTree)
              _nodesQuadTree->getElements(resNodes);
          }

          _nodesLODVector.reserve(resNodes.size());

          for(size_t i = 0 ; i < resNodes.size() ; ++i) {
            _nodesLODVector.push_back(NodeEntityLODUnit(resNodes[i], _nodesBBCache[resNodes[i]]));
          }
        }
      }
#ifdef _OPENMP
#pragma omp section
#endif
      {
        if(_graph && (_renderingEntitiesFlag & RenderingEdges)!=0) {
          vector<edge> resEdges;
          resEdges.reserve(_graph->numberOfEdges());
          if(aX==0 && aY==0) {
            if(_edgesQuadTree)
              _edgesQuadTree->getElements(cameraBoundingBox,resEdges);
          }
          else {
            if(_edgesQuadTree)
              _edgesQuadTree->getElements(resEdges);
          }

          for(size_t i = 0 ; i < resEdges.size() ; ++i) {
            _edgesLODVector.push_back(EdgeEntityLODUnit(resEdges[i], _edgesBBCache[resEdges[i]]));
          }
        }
      }
    }
  }

  GlCPULODCalculator::computeFor3DCamera(eye,transformMatrix,globalViewport,currentViewport);
}

<commit_msg>fix GlQuadTreeLODCalculator implementation after last commit<commit_after>#include "GlQuadTreeLODCalculator.h"
#include "Utils.h"
#include "QuadTree.h"
#include "GlEntity.h"
#include "GlLayer.h"

#ifdef _OPENMP
#include <omp.h>
#endif

#include <tulip/Matrix.h>
#include <tulip/LayoutProperty.h>
#include <tulip/PropertyInterface.h>

using namespace std;
using namespace tlp;

GlQuadTreeLODCalculator::GlQuadTreeLODCalculator() : _nodesQuadTree(NULL), _edgesQuadTree(NULL), _haveToCompute(true) {
#ifdef __EMSCRIPTEN__
  _haveToCompute = false;
#endif
}

GlQuadTreeLODCalculator::~GlQuadTreeLODCalculator() {
  std::map<GlLayer*, QuadTreeNode<GlEntity*> *>::iterator it = _glEntitiesQuadTree.begin();
  for (; it != _glEntitiesQuadTree.end() ; ++it) {
    delete it->second;
  }
  delete _nodesQuadTree;
  delete _edgesQuadTree;
}

void GlQuadTreeLODCalculator::setGraph(tlp::Graph *graph, GlGraphRenderingParameters *renderingParameters) {
  _haveToCompute = true;
  GlCPULODCalculator::setGraph(graph, renderingParameters);
}

void GlQuadTreeLODCalculator::initQuadTree() {
  std::map<GlLayer*, QuadTreeNode<GlEntity*> *>::iterator it = _glEntitiesQuadTree.begin();
  for (; it != _glEntitiesQuadTree.end() ; ++it) {
    delete it->second;
  }
  _glEntitiesQuadTree.clear();
  delete _nodesQuadTree;
  delete _edgesQuadTree;

  _nodesQuadTree = new QuadTreeNode<node>(_sceneBoundingBox);
  _edgesQuadTree = new QuadTreeNode<edge>(_sceneBoundingBox);
}

void GlQuadTreeLODCalculator::clear() {
  GlCPULODCalculator::clear();
  initQuadTree();
}

void GlQuadTreeLODCalculator::setSceneBoundingBox(const tlp::BoundingBox &sceneBoundingBox) {
  GlCPULODCalculator::setSceneBoundingBox(sceneBoundingBox);
  initQuadTree();
}

void GlQuadTreeLODCalculator::addGlEntity(GlLayer *layer, GlEntity *glEntity) {
  if (_sceneBoundingBox.isValid() && _glEntitiesQuadTree.find(layer) == _glEntitiesQuadTree.end()) {
    _glEntitiesQuadTree[layer] = new QuadTreeNode<GlEntity*>(_sceneBoundingBox);
  }
  if (_sceneBoundingBox.isValid() && _glEntitiesQuadTree[layer]->getCellForElement(glEntity) == NULL) {
    _glEntitiesQuadTree[layer]->insert(glEntity->getBoundingBox(), glEntity);
  }
  GlCPULODCalculator::addGlEntity(layer, glEntity);
}

void GlQuadTreeLODCalculator::removeGlEntity(GlLayer *layer, GlEntity *glEntity) {
  if (_glEntitiesQuadTree.find(layer) != _glEntitiesQuadTree.end()) {
    _glEntitiesQuadTree[layer]->remove(glEntity);
  }
}

void GlQuadTreeLODCalculator::removeLayer(GlLayer *layer) {
  if (_glEntitiesQuadTree.find(layer) != _glEntitiesQuadTree.end()) {
    delete _glEntitiesQuadTree[layer];
    _glEntitiesQuadTree.erase(layer);
  }
}

void GlQuadTreeLODCalculator::addNode(const tlp::node n) {
  GlCPULODCalculator::addNode(n);
  insertNodeInQuadTree(_nodesLODVector.back().boundingBox, n);
}

void GlQuadTreeLODCalculator::addEdge(const tlp::edge e) {
  GlCPULODCalculator::addEdge(e);
  insertEdgeInQuadTree(_edgesLODVector.back().boundingBox, e);
}

void GlQuadTreeLODCalculator::insertNodeInQuadTree(const tlp::BoundingBox &nodeBoundingBox, const tlp::node n) {
  _nodesQuadTree->insert(nodeBoundingBox, n);
}

void GlQuadTreeLODCalculator::insertEdgeInQuadTree(BoundingBox edgeBoundingBox, const tlp::edge e) {
  // This code is here to expand edge bounding box when we have an edge with direction (0,0,x)
  if(edgeBoundingBox[0][0] == edgeBoundingBox[1][0] && edgeBoundingBox[0][1] == edgeBoundingBox[1][1]) {
    edgeBoundingBox.expand(edgeBoundingBox[1]+Coord(0.01,0.01,0));
  }
  _edgesQuadTree->insert(edgeBoundingBox, e);
}

void GlQuadTreeLODCalculator::computeFor3DCamera(const Coord &eye, const Matrix<float, 4> &transformMatrix,
                                                 const Vector<int,4>& globalViewport, const Vector<int,4>& currentViewport) {

  // aX,aY : rotation on the camera in x and y
  Coord eyeCenter=camera->getCenter()-camera->getEyes();
  double aX=atan(eyeCenter[1]/eyeCenter[2]);
  double aY=atan(eyeCenter[0]/eyeCenter[2]);

  _glEntitiesLODVector.clear();
  _nodesLODVector.clear();
  _edgesLODVector.clear();

  MatrixGL invTransformMatrix(transformMatrix);
  invTransformMatrix.inverse();
  Coord pSrc = projectPoint(Coord(0,0,0), transformMatrix, globalViewport);

  BoundingBox cameraBoundingBox;

  // Project camera bounding box to known visible part of the quadtree
  pSrc[0] = currentViewport[0];
  pSrc[1] = (globalViewport[1] + globalViewport[3]) - (currentViewport[1] + currentViewport[3]);
  cameraBoundingBox.expand(unprojectPoint(pSrc, invTransformMatrix, globalViewport));
  pSrc[1] = currentViewport[1]+currentViewport[3];
  cameraBoundingBox.expand(unprojectPoint(pSrc, invTransformMatrix, globalViewport));
  pSrc[0] = currentViewport[0]+currentViewport[2];
  cameraBoundingBox.expand(unprojectPoint(pSrc, invTransformMatrix, globalViewport));
  pSrc[1] = currentViewport[1];
  cameraBoundingBox.expand(unprojectPoint(pSrc, invTransformMatrix, globalViewport));

  // Get result of quadtrees
#ifdef _OPENMP
#pragma omp parallel
#endif
  {
#ifdef _OPENMP
#pragma omp sections nowait
#endif
    {
#ifdef _OPENMP
#pragma omp section
#endif
      {
        if((_renderingEntitiesFlag & RenderingGlEntities)!=0) {
          std::map<GlLayer*, QuadTreeNode<GlEntity*> *>::iterator it = _glEntitiesQuadTree.begin();
          for (; it != _glEntitiesQuadTree.end() ; ++it) {
            vector<GlEntity*> resGlEntities;
            if(aX==0 && aY==0) {
              it->second->getElements(cameraBoundingBox,resGlEntities);
            }
            else {
              it->second->getElements(resGlEntities);
            }

            for(size_t i = 0 ; i < resGlEntities.size() ; ++i) {
              _glEntitiesLODVector[it->first].push_back(GlEntityLODUnit(resGlEntities[i]));
            }
          }
        }
      }
#ifdef _OPENMP
#pragma omp section
#endif
      {
        if(_graph && (_renderingEntitiesFlag & RenderingNodes)!=0) {
          vector<node> resNodes;
          resNodes.reserve(_graph->numberOfNodes());
          if(aX==0 && aY==0) {
            if(_nodesQuadTree)
              _nodesQuadTree->getElements(cameraBoundingBox,resNodes);
          }
          else {
            if(_nodesQuadTree)
              _nodesQuadTree->getElements(resNodes);
          }

          _nodesLODVector.reserve(resNodes.size());

          for(size_t i = 0 ; i < resNodes.size() ; ++i) {
            _nodesLODVector.push_back(NodeEntityLODUnit(resNodes[i], _nodesBBCache[resNodes[i]]));
          }
        }
      }
#ifdef _OPENMP
#pragma omp section
#endif
      {
        if(_graph && (_renderingEntitiesFlag & RenderingEdges)!=0) {
          vector<edge> resEdges;
          resEdges.reserve(_graph->numberOfEdges());
          if(aX==0 && aY==0) {
            if(_edgesQuadTree)
              _edgesQuadTree->getElements(cameraBoundingBox,resEdges);
          }
          else {
            if(_edgesQuadTree)
              _edgesQuadTree->getElements(resEdges);
          }

          for(size_t i = 0 ; i < resEdges.size() ; ++i) {
            _edgesLODVector.push_back(EdgeEntityLODUnit(resEdges[i], _edgesBBCache[resEdges[i]]));
          }
        }
      }
    }
  }

  GlCPULODCalculator::computeFor3DCamera(eye,transformMatrix,globalViewport,currentViewport);
}

<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.
 */
#if !defined(XALANLOCATOR_HEADER_GUARD_1357924680)
#define XALANLOCATOR_HEADER_GUARD_1357924680

// Base include file.  Must be first.
#include <xalanc/PlatformSupport/PlatformSupportDefinitions.hpp>

#include <xercesc/sax/Locator.hpp>

XALAN_CPP_NAMESPACE_BEGIN

XALAN_USING_XERCES(Locator)

/**
 * This class defines a base class for Locator derivations in Xalan.  It was defined
 * because Xerces made changes in their Locator class which caused turbulence.
 */
class XALAN_PLATFORMSUPPORT_EXPORT XalanLocator : public Locator
{
public:

    typedef Locator     ParentType;

    XalanLocator() {}

    virtual
    ~XalanLocator() {}

    virtual const XMLCh*
    getPublicId() const = 0;

    virtual const XMLCh*
    getSystemId() const = 0;

    virtual XalanFileLoc
    getLineNumber() const = 0;

    virtual XalanFileLoc
    getColumnNumber() const = 0;

    static const XalanDOMChar*
    getPublicId(
            const Locator*          theLocator,
            const XalanDOMChar*     theAlternateId = &s_dczero)
    {
        return theLocator == 0 ? theAlternateId : (theLocator->getPublicId() ?
            theLocator->getPublicId() : theAlternateId);
    }

    static const XalanDOMChar*
    getSystemId(
            const Locator*          theLocator,
            const XalanDOMChar*     theAlternateId = &s_dczero)
    {
        return theLocator == 0 ? theAlternateId : (theLocator->getSystemId() ?
            theLocator->getPublicId() : theAlternateId);
    }

    static XalanFileLoc
    getLineNumber(const ParentType*     theLocator)
    {
        return theLocator == 0 ? getUnknownValue() : theLocator->getLineNumber();
    }

    static XalanFileLoc
    getColumnNumber(const ParentType*   theLocator)
    {
        return theLocator == 0 ? getUnknownValue() : theLocator->getColumnNumber();
    }

    static XalanFileLoc
    getUnknownValue()
    {
        // The parser reports the maximum value of the XalanFileLoc
        // type for an unknown value.
        return ~static_cast<XalanFileLoc>(0);
    }

    static XalanFileLoc
    getUnknownDisplayValue()
    {
        // The parser reports the maximum value of the XalanFileLoc
        // type for an unknown value, but that is really non-sensical
        // for display purposes, so we use 0 instead.
        return static_cast<XalanFileLoc>(0);
    }

    static bool
    isUnknownValue(XalanFileLoc     theLocation)
    {
        return theLocation == getUnknownValue();
    }

private:

    // Not defined...
    XalanLocator(const XalanLocator&);

    XalanLocator&
    operator=(const XalanLocator&);

    const static XalanDOMChar s_dczero = 0;
};

XALAN_CPP_NAMESPACE_END

#endif  // PREFIXRESOLVER_HEADER_GUARD_1357924680
<commit_msg>XALANC-733 Ensure that XalanLocator::getSystemId() and getPublicId() do not return NULL<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.
 */
#if !defined(XALANLOCATOR_HEADER_GUARD_1357924680)
#define XALANLOCATOR_HEADER_GUARD_1357924680

// Base include file.  Must be first.
#include <xalanc/PlatformSupport/PlatformSupportDefinitions.hpp>

#include <xercesc/sax/Locator.hpp>

XALAN_CPP_NAMESPACE_BEGIN

XALAN_USING_XERCES(Locator)

/**
 * This class defines a base class for Locator derivations in Xalan.  It was defined
 * because Xerces made changes in their Locator class which caused turbulence.
 */
class XALAN_PLATFORMSUPPORT_EXPORT XalanLocator : public Locator
{
public:

    typedef Locator     ParentType;

    XalanLocator() {}

    virtual
    ~XalanLocator() {}

    virtual const XMLCh*
    getPublicId() const = 0;

    virtual const XMLCh*
    getSystemId() const = 0;

    virtual XalanFileLoc
    getLineNumber() const = 0;

    virtual XalanFileLoc
    getColumnNumber() const = 0;

    /**
     * Get the public identifier from a locator object.
     * @param theLocator  A locator object inherited from Xerces.
     * @param theAlternateId  A default name for a public identifier.
     * @return a null terminated XalanDOMChar string.
     */
    static const XalanDOMChar*
    getPublicId(
            const Locator*          theLocator,
            const XalanDOMChar*     theAlternateId = getEmptyPtr())
    {
        return theLocator == 0 ? theAlternateId : (theLocator->getPublicId() ?
            theLocator->getPublicId() : theAlternateId);
    }

    /**
     * Get the system identifier from a locator object.
     * @param theLocator  A locator object inherited from Xerces.
     * @param theAlternateId  A default name for a public identifier.
     * @return a null terminated XalanDOMChar string.
     */
    static const XalanDOMChar*
    getSystemId(
            const Locator*          theLocator,
            const XalanDOMChar*     theAlternateId = getEmptyPtr())
    {
        return theLocator == 0 ? theAlternateId : (theLocator->getSystemId() ?
            theLocator->getPublicId() : theAlternateId);
    }

    /**
     * Get the line number from a locator object.
     */
    static XalanFileLoc
    getLineNumber(const ParentType*     theLocator)
    {
        return theLocator == 0 ? getUnknownValue() : theLocator->getLineNumber();
    }

    /**
     * Get the column number from a locator object.
     */
    static XalanFileLoc
    getColumnNumber(const ParentType*   theLocator)
    {
        return theLocator == 0 ? getUnknownValue() : theLocator->getColumnNumber();
    }

    static XalanFileLoc
    getUnknownValue()
    {
        // The parser reports the maximum value of the XalanFileLoc
        // type for an unknown value.
        return ~static_cast<XalanFileLoc>(0);
    }

    static XalanFileLoc
    getUnknownDisplayValue()
    {
        // The parser reports the maximum value of the XalanFileLoc
        // type for an unknown value, but that is really non-sensical
        // for display purposes, so we use 0 instead.
        return static_cast<XalanFileLoc>(0);
    }

    static bool
    isUnknownValue(XalanFileLoc     theLocation)
    {
        return theLocation == getUnknownValue();
    }

private:

    // Not defined...
    XalanLocator(const XalanLocator&);

    XalanLocator&
    operator=(const XalanLocator&);

    /**
     * Return static pointer to null XalanDOMChar.
     * This is crafted to overcome issues with compilers/linkers that
     * have problems initializing static integer members within a class.
     *
     * Replaces:    static const int s_zero = 0;
     * Reference:   &s_zero;
     */
    static const XalanDOMChar * getEmptyPtr()
    {
        static const XalanDOMChar theZero = 0;
        static const XalanDOMChar * theEmpty = &theZero;
        return theEmpty;
    }
};

XALAN_CPP_NAMESPACE_END

#endif  // PREFIXRESOLVER_HEADER_GUARD_1357924680
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2020 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "size_tiered_compaction_strategy.hh"
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>

namespace sstables {

size_tiered_compaction_strategy_options::size_tiered_compaction_strategy_options(const std::map<sstring, sstring>& options) {
    using namespace cql3::statements;

    auto tmp_value = compaction_strategy_impl::get_value(options, MIN_SSTABLE_SIZE_KEY);
    min_sstable_size = property_definitions::to_long(MIN_SSTABLE_SIZE_KEY, tmp_value, DEFAULT_MIN_SSTABLE_SIZE);

    tmp_value = compaction_strategy_impl::get_value(options, BUCKET_LOW_KEY);
    bucket_low = property_definitions::to_double(BUCKET_LOW_KEY, tmp_value, DEFAULT_BUCKET_LOW);

    tmp_value = compaction_strategy_impl::get_value(options, BUCKET_HIGH_KEY);
    bucket_high = property_definitions::to_double(BUCKET_HIGH_KEY, tmp_value, DEFAULT_BUCKET_HIGH);

    tmp_value = compaction_strategy_impl::get_value(options, COLD_READS_TO_OMIT_KEY);
    cold_reads_to_omit = property_definitions::to_double(COLD_READS_TO_OMIT_KEY, tmp_value, DEFAULT_COLD_READS_TO_OMIT);
}

size_tiered_compaction_strategy_options::size_tiered_compaction_strategy_options() {
    min_sstable_size = DEFAULT_MIN_SSTABLE_SIZE;
    bucket_low = DEFAULT_BUCKET_LOW;
    bucket_high = DEFAULT_BUCKET_HIGH;
    cold_reads_to_omit = DEFAULT_COLD_READS_TO_OMIT;
}

std::vector<std::pair<sstables::shared_sstable, uint64_t>>
size_tiered_compaction_strategy::create_sstable_and_length_pairs(const std::vector<sstables::shared_sstable>& sstables) {

    std::vector<std::pair<sstables::shared_sstable, uint64_t>> sstable_length_pairs;
    sstable_length_pairs.reserve(sstables.size());

    for(auto& sstable : sstables) {
        auto sstable_size = sstable->data_size();
        assert(sstable_size != 0);

        sstable_length_pairs.emplace_back(sstable, sstable_size);
    }

    return sstable_length_pairs;
}

std::vector<std::vector<sstables::shared_sstable>>
size_tiered_compaction_strategy::get_buckets(const std::vector<sstables::shared_sstable>& sstables, size_tiered_compaction_strategy_options options) {
    // sstables sorted by size of its data file.
    auto sorted_sstables = create_sstable_and_length_pairs(sstables);

    std::sort(sorted_sstables.begin(), sorted_sstables.end(), [] (auto& i, auto& j) {
        return i.second < j.second;
    });

    using bucket_type = std::vector<sstables::shared_sstable>;
    std::vector<bucket_type> bucket_list;
    std::vector<double> bucket_average_size_list;

    for (auto& pair : sorted_sstables) {
        size_t size = pair.second;

        // look for a bucket containing similar-sized files:
        // group in the same bucket if it's w/in (bucket_low, bucket_high) of the average for this bucket,
        // or this file and the bucket are all considered "small" (less than `minSSTableSize`)
        if (!bucket_list.empty()) {
            auto& bucket_average_size = bucket_average_size_list.back();

            if ((size > (bucket_average_size * options.bucket_low) && size < (bucket_average_size * options.bucket_high)) ||
                    (size < options.min_sstable_size && bucket_average_size < options.min_sstable_size)) {
                auto& bucket = bucket_list.back();
                auto total_size = bucket.size() * bucket_average_size;
                auto new_average_size = (total_size + size) / (bucket.size() + 1);
                auto smallest_sstable_in_bucket = bucket[0]->data_size();

                // SSTables are added in increasing size order so the bucket's
                // average might drift upwards.
                // Don't let it drift too high, to a point where the smallest
                // SSTable might fall out of range.
                if (size < options.min_sstable_size || smallest_sstable_in_bucket > new_average_size * options.bucket_low) {
                // FIXME: reindent
                bucket.push_back(pair.first);
                bucket_average_size = new_average_size;
                continue;
                }
            }
        }

        // no similar bucket found; put it in a new one
        bucket_type new_bucket = {pair.first};
        bucket_list.push_back(std::move(new_bucket));
        bucket_average_size_list.push_back(size);
    }

    return bucket_list;
}

std::vector<std::vector<sstables::shared_sstable>>
size_tiered_compaction_strategy::get_buckets(const std::vector<sstables::shared_sstable>& sstables) const {
    return get_buckets(sstables, _options);
}

std::vector<sstables::shared_sstable>
size_tiered_compaction_strategy::most_interesting_bucket(std::vector<std::vector<sstables::shared_sstable>> buckets,
        unsigned min_threshold, unsigned max_threshold)
{
    std::vector<std::pair<std::vector<sstables::shared_sstable>, uint64_t>> pruned_buckets_and_hotness;
    pruned_buckets_and_hotness.reserve(buckets.size());

    // FIXME: add support to get hotness for each bucket.

    for (auto& bucket : buckets) {
        // FIXME: the coldest sstables will be trimmed to meet the threshold, so we must add support to this feature
        // by converting SizeTieredCompactionStrategy::trimToThresholdWithHotness.
        // By the time being, we will only compact buckets that meet the threshold.
        bucket.resize(std::min(bucket.size(), size_t(max_threshold)));
        if (is_bucket_interesting(bucket, min_threshold)) {
            auto avg = avg_size(bucket);
            pruned_buckets_and_hotness.push_back({ std::move(bucket), avg });
        }
    }

    if (pruned_buckets_and_hotness.empty()) {
        return std::vector<sstables::shared_sstable>();
    }

    // NOTE: Compacting smallest sstables first, located at the beginning of the sorted vector.
    auto& min = *std::min_element(pruned_buckets_and_hotness.begin(), pruned_buckets_and_hotness.end(), [] (auto& i, auto& j) {
        // FIXME: ignoring hotness by the time being.

        return i.second < j.second;
    });
    auto hottest = std::move(min.first);

    return hottest;
}

compaction_descriptor
size_tiered_compaction_strategy::get_sstables_for_compaction(column_family& cfs, std::vector<sstables::shared_sstable> candidates) {
    // make local copies so they can't be changed out from under us mid-method
    int min_threshold = cfs.min_compaction_threshold();
    int max_threshold = cfs.schema()->max_compaction_threshold();
    auto gc_before = gc_clock::now() - cfs.schema()->gc_grace_seconds();

    // TODO: Add support to filter cold sstables (for reference: SizeTieredCompactionStrategy::filterColdSSTables).

    auto buckets = get_buckets(candidates);

    if (is_any_bucket_interesting(buckets, min_threshold)) {
        std::vector<sstables::shared_sstable> most_interesting = most_interesting_bucket(std::move(buckets), min_threshold, max_threshold);
        return sstables::compaction_descriptor(std::move(most_interesting), cfs.get_sstable_set(), service::get_local_compaction_priority());
    }

    // If we are not enforcing min_threshold explicitly, try any pair of SStables in the same tier.
    if (!cfs.compaction_enforce_min_threshold() && is_any_bucket_interesting(buckets, 2)) {
        std::vector<sstables::shared_sstable> most_interesting = most_interesting_bucket(std::move(buckets), 2, max_threshold);
        return sstables::compaction_descriptor(std::move(most_interesting), cfs.get_sstable_set(), service::get_local_compaction_priority());
    }

    // if there is no sstable to compact in standard way, try compacting single sstable whose droppable tombstone
    // ratio is greater than threshold.
    // prefer oldest sstables from biggest size tiers because they will be easier to satisfy conditions for
    // tombstone purge, i.e. less likely to shadow even older data.
    for (auto&& sstables : buckets | boost::adaptors::reversed) {
        // filter out sstables which droppable tombstone ratio isn't greater than the defined threshold.
        auto e = boost::range::remove_if(sstables, [this, &gc_before] (const sstables::shared_sstable& sst) -> bool {
            return !worth_dropping_tombstones(sst, gc_before);
        });
        sstables.erase(e, sstables.end());
        if (sstables.empty()) {
            continue;
        }
        // find oldest sstable from current tier
        auto it = std::min_element(sstables.begin(), sstables.end(), [] (auto& i, auto& j) {
            return i->get_stats_metadata().min_timestamp < j->get_stats_metadata().min_timestamp;
        });
        return sstables::compaction_descriptor({ *it }, cfs.get_sstable_set(), service::get_local_compaction_priority());
    }
    return sstables::compaction_descriptor();
}

int64_t size_tiered_compaction_strategy::estimated_pending_compactions(const std::vector<sstables::shared_sstable>& sstables,
        int min_threshold, int max_threshold, size_tiered_compaction_strategy_options options) {
    int64_t n = 0;
    for (auto& bucket : get_buckets(sstables, options)) {
        if (bucket.size() >= size_t(min_threshold)) {
            n += std::ceil(double(bucket.size()) / max_threshold);
        }
    }
    return n;
}

int64_t size_tiered_compaction_strategy::estimated_pending_compactions(column_family& cf) const {
    int min_threshold = cf.min_compaction_threshold();
    int max_threshold = cf.schema()->max_compaction_threshold();
    std::vector<sstables::shared_sstable> sstables;

    sstables.reserve(cf.sstables_count());
    for (auto all_sstables = cf.get_sstables(); auto& entry : *all_sstables) {
        sstables.push_back(entry);
    }

    return estimated_pending_compactions(sstables, min_threshold, max_threshold, _options);
}

std::vector<sstables::shared_sstable>
size_tiered_compaction_strategy::most_interesting_bucket(const std::vector<sstables::shared_sstable>& candidates,
        int min_threshold, int max_threshold, size_tiered_compaction_strategy_options options) {
    size_tiered_compaction_strategy cs(options);

    auto buckets = cs.get_buckets(candidates);

    std::vector<sstables::shared_sstable> most_interesting = cs.most_interesting_bucket(std::move(buckets),
        min_threshold, max_threshold);

    return most_interesting;
}

compaction_descriptor
size_tiered_compaction_strategy::get_reshaping_job(std::vector<shared_sstable> input, schema_ptr schema, const ::io_priority_class& iop, reshape_mode mode)
{
    size_t offstrategy_threshold = std::max(schema->min_compaction_threshold(), 4);
    size_t max_sstables = std::max(schema->max_compaction_threshold(), int(offstrategy_threshold));

    if (mode == reshape_mode::relaxed) {
        offstrategy_threshold = max_sstables;
    }

    for (auto& bucket : get_buckets(input)) {
        if (bucket.size() >= offstrategy_threshold) {
            // reshape job can work on #max_sstables sstables at once, so by reshaping sstables with the smallest tokens first,
            // token contiguity is preserved iff sstables are disjoint.
            if (bucket.size() > max_sstables) {
                std::partial_sort(bucket.begin(), bucket.begin() + max_sstables, bucket.end(), [&schema](const sstables::shared_sstable& a, const sstables::shared_sstable& b) {
                    return a->get_first_decorated_key().tri_compare(*schema, b->get_first_decorated_key()) <= 0;
                });
                bucket.resize(max_sstables);
            }
            compaction_descriptor desc(std::move(bucket), std::optional<sstables::sstable_set>(), iop);
            desc.options = compaction_options::make_reshape();
            return desc;
        }
    }

    return compaction_descriptor();
}

}
<commit_msg>compaction: size_tiered_compaction_strategy: get_buckets: fixup indentation<commit_after>/*
 * Copyright (C) 2020 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "size_tiered_compaction_strategy.hh"
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>

namespace sstables {

size_tiered_compaction_strategy_options::size_tiered_compaction_strategy_options(const std::map<sstring, sstring>& options) {
    using namespace cql3::statements;

    auto tmp_value = compaction_strategy_impl::get_value(options, MIN_SSTABLE_SIZE_KEY);
    min_sstable_size = property_definitions::to_long(MIN_SSTABLE_SIZE_KEY, tmp_value, DEFAULT_MIN_SSTABLE_SIZE);

    tmp_value = compaction_strategy_impl::get_value(options, BUCKET_LOW_KEY);
    bucket_low = property_definitions::to_double(BUCKET_LOW_KEY, tmp_value, DEFAULT_BUCKET_LOW);

    tmp_value = compaction_strategy_impl::get_value(options, BUCKET_HIGH_KEY);
    bucket_high = property_definitions::to_double(BUCKET_HIGH_KEY, tmp_value, DEFAULT_BUCKET_HIGH);

    tmp_value = compaction_strategy_impl::get_value(options, COLD_READS_TO_OMIT_KEY);
    cold_reads_to_omit = property_definitions::to_double(COLD_READS_TO_OMIT_KEY, tmp_value, DEFAULT_COLD_READS_TO_OMIT);
}

size_tiered_compaction_strategy_options::size_tiered_compaction_strategy_options() {
    min_sstable_size = DEFAULT_MIN_SSTABLE_SIZE;
    bucket_low = DEFAULT_BUCKET_LOW;
    bucket_high = DEFAULT_BUCKET_HIGH;
    cold_reads_to_omit = DEFAULT_COLD_READS_TO_OMIT;
}

std::vector<std::pair<sstables::shared_sstable, uint64_t>>
size_tiered_compaction_strategy::create_sstable_and_length_pairs(const std::vector<sstables::shared_sstable>& sstables) {

    std::vector<std::pair<sstables::shared_sstable, uint64_t>> sstable_length_pairs;
    sstable_length_pairs.reserve(sstables.size());

    for(auto& sstable : sstables) {
        auto sstable_size = sstable->data_size();
        assert(sstable_size != 0);

        sstable_length_pairs.emplace_back(sstable, sstable_size);
    }

    return sstable_length_pairs;
}

std::vector<std::vector<sstables::shared_sstable>>
size_tiered_compaction_strategy::get_buckets(const std::vector<sstables::shared_sstable>& sstables, size_tiered_compaction_strategy_options options) {
    // sstables sorted by size of its data file.
    auto sorted_sstables = create_sstable_and_length_pairs(sstables);

    std::sort(sorted_sstables.begin(), sorted_sstables.end(), [] (auto& i, auto& j) {
        return i.second < j.second;
    });

    using bucket_type = std::vector<sstables::shared_sstable>;
    std::vector<bucket_type> bucket_list;
    std::vector<double> bucket_average_size_list;

    for (auto& pair : sorted_sstables) {
        size_t size = pair.second;

        // look for a bucket containing similar-sized files:
        // group in the same bucket if it's w/in (bucket_low, bucket_high) of the average for this bucket,
        // or this file and the bucket are all considered "small" (less than `minSSTableSize`)
        if (!bucket_list.empty()) {
            auto& bucket_average_size = bucket_average_size_list.back();

            if ((size > (bucket_average_size * options.bucket_low) && size < (bucket_average_size * options.bucket_high)) ||
                    (size < options.min_sstable_size && bucket_average_size < options.min_sstable_size)) {
                auto& bucket = bucket_list.back();
                auto total_size = bucket.size() * bucket_average_size;
                auto new_average_size = (total_size + size) / (bucket.size() + 1);
                auto smallest_sstable_in_bucket = bucket[0]->data_size();

                // SSTables are added in increasing size order so the bucket's
                // average might drift upwards.
                // Don't let it drift too high, to a point where the smallest
                // SSTable might fall out of range.
                if (size < options.min_sstable_size || smallest_sstable_in_bucket > new_average_size * options.bucket_low) {
                    bucket.push_back(pair.first);
                    bucket_average_size = new_average_size;
                    continue;
                }
            }
        }

        // no similar bucket found; put it in a new one
        bucket_type new_bucket = {pair.first};
        bucket_list.push_back(std::move(new_bucket));
        bucket_average_size_list.push_back(size);
    }

    return bucket_list;
}

std::vector<std::vector<sstables::shared_sstable>>
size_tiered_compaction_strategy::get_buckets(const std::vector<sstables::shared_sstable>& sstables) const {
    return get_buckets(sstables, _options);
}

std::vector<sstables::shared_sstable>
size_tiered_compaction_strategy::most_interesting_bucket(std::vector<std::vector<sstables::shared_sstable>> buckets,
        unsigned min_threshold, unsigned max_threshold)
{
    std::vector<std::pair<std::vector<sstables::shared_sstable>, uint64_t>> pruned_buckets_and_hotness;
    pruned_buckets_and_hotness.reserve(buckets.size());

    // FIXME: add support to get hotness for each bucket.

    for (auto& bucket : buckets) {
        // FIXME: the coldest sstables will be trimmed to meet the threshold, so we must add support to this feature
        // by converting SizeTieredCompactionStrategy::trimToThresholdWithHotness.
        // By the time being, we will only compact buckets that meet the threshold.
        bucket.resize(std::min(bucket.size(), size_t(max_threshold)));
        if (is_bucket_interesting(bucket, min_threshold)) {
            auto avg = avg_size(bucket);
            pruned_buckets_and_hotness.push_back({ std::move(bucket), avg });
        }
    }

    if (pruned_buckets_and_hotness.empty()) {
        return std::vector<sstables::shared_sstable>();
    }

    // NOTE: Compacting smallest sstables first, located at the beginning of the sorted vector.
    auto& min = *std::min_element(pruned_buckets_and_hotness.begin(), pruned_buckets_and_hotness.end(), [] (auto& i, auto& j) {
        // FIXME: ignoring hotness by the time being.

        return i.second < j.second;
    });
    auto hottest = std::move(min.first);

    return hottest;
}

compaction_descriptor
size_tiered_compaction_strategy::get_sstables_for_compaction(column_family& cfs, std::vector<sstables::shared_sstable> candidates) {
    // make local copies so they can't be changed out from under us mid-method
    int min_threshold = cfs.min_compaction_threshold();
    int max_threshold = cfs.schema()->max_compaction_threshold();
    auto gc_before = gc_clock::now() - cfs.schema()->gc_grace_seconds();

    // TODO: Add support to filter cold sstables (for reference: SizeTieredCompactionStrategy::filterColdSSTables).

    auto buckets = get_buckets(candidates);

    if (is_any_bucket_interesting(buckets, min_threshold)) {
        std::vector<sstables::shared_sstable> most_interesting = most_interesting_bucket(std::move(buckets), min_threshold, max_threshold);
        return sstables::compaction_descriptor(std::move(most_interesting), cfs.get_sstable_set(), service::get_local_compaction_priority());
    }

    // If we are not enforcing min_threshold explicitly, try any pair of SStables in the same tier.
    if (!cfs.compaction_enforce_min_threshold() && is_any_bucket_interesting(buckets, 2)) {
        std::vector<sstables::shared_sstable> most_interesting = most_interesting_bucket(std::move(buckets), 2, max_threshold);
        return sstables::compaction_descriptor(std::move(most_interesting), cfs.get_sstable_set(), service::get_local_compaction_priority());
    }

    // if there is no sstable to compact in standard way, try compacting single sstable whose droppable tombstone
    // ratio is greater than threshold.
    // prefer oldest sstables from biggest size tiers because they will be easier to satisfy conditions for
    // tombstone purge, i.e. less likely to shadow even older data.
    for (auto&& sstables : buckets | boost::adaptors::reversed) {
        // filter out sstables which droppable tombstone ratio isn't greater than the defined threshold.
        auto e = boost::range::remove_if(sstables, [this, &gc_before] (const sstables::shared_sstable& sst) -> bool {
            return !worth_dropping_tombstones(sst, gc_before);
        });
        sstables.erase(e, sstables.end());
        if (sstables.empty()) {
            continue;
        }
        // find oldest sstable from current tier
        auto it = std::min_element(sstables.begin(), sstables.end(), [] (auto& i, auto& j) {
            return i->get_stats_metadata().min_timestamp < j->get_stats_metadata().min_timestamp;
        });
        return sstables::compaction_descriptor({ *it }, cfs.get_sstable_set(), service::get_local_compaction_priority());
    }
    return sstables::compaction_descriptor();
}

int64_t size_tiered_compaction_strategy::estimated_pending_compactions(const std::vector<sstables::shared_sstable>& sstables,
        int min_threshold, int max_threshold, size_tiered_compaction_strategy_options options) {
    int64_t n = 0;
    for (auto& bucket : get_buckets(sstables, options)) {
        if (bucket.size() >= size_t(min_threshold)) {
            n += std::ceil(double(bucket.size()) / max_threshold);
        }
    }
    return n;
}

int64_t size_tiered_compaction_strategy::estimated_pending_compactions(column_family& cf) const {
    int min_threshold = cf.min_compaction_threshold();
    int max_threshold = cf.schema()->max_compaction_threshold();
    std::vector<sstables::shared_sstable> sstables;

    sstables.reserve(cf.sstables_count());
    for (auto all_sstables = cf.get_sstables(); auto& entry : *all_sstables) {
        sstables.push_back(entry);
    }

    return estimated_pending_compactions(sstables, min_threshold, max_threshold, _options);
}

std::vector<sstables::shared_sstable>
size_tiered_compaction_strategy::most_interesting_bucket(const std::vector<sstables::shared_sstable>& candidates,
        int min_threshold, int max_threshold, size_tiered_compaction_strategy_options options) {
    size_tiered_compaction_strategy cs(options);

    auto buckets = cs.get_buckets(candidates);

    std::vector<sstables::shared_sstable> most_interesting = cs.most_interesting_bucket(std::move(buckets),
        min_threshold, max_threshold);

    return most_interesting;
}

compaction_descriptor
size_tiered_compaction_strategy::get_reshaping_job(std::vector<shared_sstable> input, schema_ptr schema, const ::io_priority_class& iop, reshape_mode mode)
{
    size_t offstrategy_threshold = std::max(schema->min_compaction_threshold(), 4);
    size_t max_sstables = std::max(schema->max_compaction_threshold(), int(offstrategy_threshold));

    if (mode == reshape_mode::relaxed) {
        offstrategy_threshold = max_sstables;
    }

    for (auto& bucket : get_buckets(input)) {
        if (bucket.size() >= offstrategy_threshold) {
            // reshape job can work on #max_sstables sstables at once, so by reshaping sstables with the smallest tokens first,
            // token contiguity is preserved iff sstables are disjoint.
            if (bucket.size() > max_sstables) {
                std::partial_sort(bucket.begin(), bucket.begin() + max_sstables, bucket.end(), [&schema](const sstables::shared_sstable& a, const sstables::shared_sstable& b) {
                    return a->get_first_decorated_key().tri_compare(*schema, b->get_first_decorated_key()) <= 0;
                });
                bucket.resize(max_sstables);
            }
            compaction_descriptor desc(std::move(bucket), std::optional<sstables::sstable_set>(), iop);
            desc.options = compaction_options::make_reshape();
            return desc;
        }
    }

    return compaction_descriptor();
}

}
<|endoftext|>


<commit_before>#ifndef STAN_MATH_REV_CORE_AUTODIFFSTACKSTORAGE_HPP
#define STAN_MATH_REV_CORE_AUTODIFFSTACKSTORAGE_HPP

#include <stan/math/memory/stack_alloc.hpp>
#include <vector>

namespace stan {
namespace math {

/**
 * Provides a thread_local singleton if needed. Read warnings below!
 * For performance reasons the singleton is a global static for the
 * case of no threading which is returned by a function. This design
 * should allow the compiler to apply necessary inlining to get
 * maximal performance. However, this design suffers from "the static
 * init order fiasco"[0].  Anywhere this is used, we must be
 * absolutely positive that it doesn't matter when the singleton will
 * get initialized relative to other static variables.  In exchange,
 * we get a more performant singleton pattern for the non-threading
 * case. In the threading case we use the defacto standard C++11
 * singleton pattern relying on a function wrapping a static local
 * variable. This standard pattern is expected to be well supported
 * by the major compilers (as its standard), but it does incur some
 * performance penalty.  There has been some discussion on this; see
 * [1] and [2] and the discussions those PRs link to as well.
 *
 * These are thread_local only if the user asks for it with
 * -DSTAN_THREADS. This is primarily because Apple clang compilers
 * before 2016 don't support thread_local and the additional
 * performance cost. We have proposed removing support for those[3],
 * and at that time we should evaluate the performance of a switch to
 * thread_local.  If there is no loss in performance, we can remove
 * this ifdef.
 *
 * [0] https://isocpp.org/wiki/faq/ctors#static-init-order
 * [1] https://github.com/stan-dev/math/pull/840
 * [2] https://github.com/stan-dev/math/pull/826
 * [3]
 * http://discourse.mc-stan.org/t/potentially-dropping-support-for-older-versions-of-apples-version-of-clang/3780/
 */
template <typename ChainableT, typename ChainableAllocT>
struct AutodiffStackSingleton {
  typedef AutodiffStackSingleton<ChainableT, ChainableAllocT>
      AutodiffStackSingleton_t;

  struct AutodiffStackStorage {
    AutodiffStackStorage &operator=(const AutodiffStackStorage &) = delete;

    std::vector<ChainableT *> var_stack_;
    std::vector<ChainableT *> var_nochain_stack_;
    std::vector<ChainableAllocT *> var_alloc_stack_;
    stack_alloc memalloc_;

    // nested positions
    std::vector<size_t> nested_var_stack_sizes_;
    std::vector<size_t> nested_var_nochain_stack_sizes_;
    std::vector<size_t> nested_var_alloc_stack_starts_;
  };

  AutodiffStackSingleton() = delete;
  explicit AutodiffStackSingleton(AutodiffStackSingleton_t const &) = delete;
  AutodiffStackSingleton &operator=(const AutodiffStackSingleton_t &) = delete;

  static inline AutodiffStackStorage &instance() {
#ifdef STAN_THREADS
    thread_local static AutodiffStackStorage instance_;
    return instance_;
#else
    return *instance_;
#endif
  }

#ifndef STAN_THREADS

 private:
  static AutodiffStackStorage* instance_;
#endif
};

#ifndef STAN_THREADS
template <typename ChainableT, typename ChainableAllocT>
typename AutodiffStackSingleton<ChainableT,
                                ChainableAllocT>::AutodiffStackStorage*
    AutodiffStackSingleton<ChainableT, ChainableAllocT>::instance_
    = new typename AutodiffStackSingleton<ChainableT,
                                ChainableAllocT>::AutodiffStackStorage;
#endif

}  // namespace math
}  // namespace stan
#endif
<commit_msg>[Jenkins] auto-formatting by clang-format version 5.0.2-svn328729-1~exp1~20180509124008.99 (branches/release_50)<commit_after>#ifndef STAN_MATH_REV_CORE_AUTODIFFSTACKSTORAGE_HPP
#define STAN_MATH_REV_CORE_AUTODIFFSTACKSTORAGE_HPP

#include <stan/math/memory/stack_alloc.hpp>
#include <vector>

namespace stan {
namespace math {

/**
 * Provides a thread_local singleton if needed. Read warnings below!
 * For performance reasons the singleton is a global static for the
 * case of no threading which is returned by a function. This design
 * should allow the compiler to apply necessary inlining to get
 * maximal performance. However, this design suffers from "the static
 * init order fiasco"[0].  Anywhere this is used, we must be
 * absolutely positive that it doesn't matter when the singleton will
 * get initialized relative to other static variables.  In exchange,
 * we get a more performant singleton pattern for the non-threading
 * case. In the threading case we use the defacto standard C++11
 * singleton pattern relying on a function wrapping a static local
 * variable. This standard pattern is expected to be well supported
 * by the major compilers (as its standard), but it does incur some
 * performance penalty.  There has been some discussion on this; see
 * [1] and [2] and the discussions those PRs link to as well.
 *
 * These are thread_local only if the user asks for it with
 * -DSTAN_THREADS. This is primarily because Apple clang compilers
 * before 2016 don't support thread_local and the additional
 * performance cost. We have proposed removing support for those[3],
 * and at that time we should evaluate the performance of a switch to
 * thread_local.  If there is no loss in performance, we can remove
 * this ifdef.
 *
 * [0] https://isocpp.org/wiki/faq/ctors#static-init-order
 * [1] https://github.com/stan-dev/math/pull/840
 * [2] https://github.com/stan-dev/math/pull/826
 * [3]
 * http://discourse.mc-stan.org/t/potentially-dropping-support-for-older-versions-of-apples-version-of-clang/3780/
 */
template <typename ChainableT, typename ChainableAllocT>
struct AutodiffStackSingleton {
  typedef AutodiffStackSingleton<ChainableT, ChainableAllocT>
      AutodiffStackSingleton_t;

  struct AutodiffStackStorage {
    AutodiffStackStorage &operator=(const AutodiffStackStorage &) = delete;

    std::vector<ChainableT *> var_stack_;
    std::vector<ChainableT *> var_nochain_stack_;
    std::vector<ChainableAllocT *> var_alloc_stack_;
    stack_alloc memalloc_;

    // nested positions
    std::vector<size_t> nested_var_stack_sizes_;
    std::vector<size_t> nested_var_nochain_stack_sizes_;
    std::vector<size_t> nested_var_alloc_stack_starts_;
  };

  AutodiffStackSingleton() = delete;
  explicit AutodiffStackSingleton(AutodiffStackSingleton_t const &) = delete;
  AutodiffStackSingleton &operator=(const AutodiffStackSingleton_t &) = delete;

  static inline AutodiffStackStorage &instance() {
#ifdef STAN_THREADS
    thread_local static AutodiffStackStorage instance_;
    return instance_;
#else
    return *instance_;
#endif
  }

#ifndef STAN_THREADS

 private:
  static AutodiffStackStorage *instance_;
#endif
};

#ifndef STAN_THREADS
template <typename ChainableT, typename ChainableAllocT>
typename AutodiffStackSingleton<ChainableT,
                                ChainableAllocT>::AutodiffStackStorage
    *AutodiffStackSingleton<ChainableT, ChainableAllocT>::instance_
    = new
    typename AutodiffStackSingleton<ChainableT,
                                    ChainableAllocT>::AutodiffStackStorage;
#endif

}  // namespace math
}  // namespace stan
#endif
<|endoftext|>


<commit_before>#include "Elk.h"
#include "MooseFactory.h"

// misc
#include "BodyForceRZ.h"
#include "CoefDiffusion.h"
#include "Convection.h"
#include "InternalVolume.h"
#include "InternalVolumeRZ.h"
#include "NeumannRZ.h"

// heat_conduction
#include "HeatConduction.h"
#include "HeatConductionRZ.h"
#include "HeatConductionImplicitEuler.h"
#include "HeatConductionImplicitEulerRZ.h"
#include "HeatConductionMaterial.h"

// navier_stokes
#include "MassInviscidFlux.h"
#include "MomentumInviscidFlux.h"
#include "MomentumViscousFlux.h"
#include "EnergyInviscidFlux.h"
#include "EnergyViscousFlux.h"
#include "GravityPower.h"
#include "GravityForce.h"
#include "PressureNeumannBC.h"
#include "ThermalBC.h"
#include "VelocityAux.h"

// linear_elasticity
#include "SolidMechX.h"
#include "SolidMechY.h"
#include "SolidMechZ.h"
#include "SolidMechImplicitEuler.h"
#include "SolidMechTempCoupleX.h"
#include "SolidMechTempCoupleY.h"
#include "SolidMechTempCoupleZ.h"

// solid_mechanics
#include "CLSHPlasticMaterial.h"
#include "Elastic.h"
#include "Gravity.h"
#include "GravityRZ.h"
#include "LinearIsotropicMaterial.h"
#include "LinearStrainHardening.h"
#include "LSHPlasticMaterial.h"
#include "LSHPlasticMaterialRZ.h"
#include "MaterialTensorAux.h"
#include "PLC_LSH.h"
#include "PowerLawCreepMaterial.h"
#include "PowerLawCreep.h"
#include "PlenumPressure.h"
#include "PlenumPressureRZ.h"
#include "Pressure.h"
#include "PressureRZ.h"
#include "PLSHPlasticMaterial.h"
#include "ElasticEnergyAux.h"
#include "StressDivergence.h"
#include "StressDivergenceRZ.h"

// phase_field
#include "AC.h"
#include "ACBulk.h"
#include "ACInterface.h"
#include "CHBulk.h"
#include "CHSplit1.h"
#include "CHSplit2LaPl.h"
#include "CHSplit2ChemPot.h"
#include "CHInterface.h"
#include "CrossIC.h"
#include "SmoothCircleIC.h"
#include "RndSmoothCircleIC.h"
#include "RndBoundingBoxIC.h"

// contact
#include "ContactMaster.h"
#include "SlaveConstraint.h"

void
Elk::registerObjects()
{
  // misc
  registerKernel(BodyForceRZ);
  registerKernel(CoefDiffusion);
  registerKernel(Convection);
  registerPostprocessor(InternalVolume);
  registerPostprocessor(InternalVolumeRZ);
  registerBoundaryCondition(NeumannRZ);

  // heat_conduction
  registerKernel(HeatConduction);
  registerKernel(HeatConductionRZ);
  registerKernel(HeatConductionImplicitEuler);
  registerKernel(HeatConductionImplicitEulerRZ);
  registerNamedMaterial(HeatConductionMaterial, "HeatConduction");

  // navier_stokes
  registerKernel(MassInviscidFlux);
  registerKernel(MomentumInviscidFlux);
  registerKernel(MomentumViscousFlux);
  registerKernel(EnergyInviscidFlux);
  registerKernel(EnergyViscousFlux);
  registerKernel(GravityPower);
  registerKernel(GravityForce);
  registerBoundaryCondition(PressureNeumannBC);
  registerBoundaryCondition(ThermalBC);
  registerAux(VelocityAux);

  // linear_elasticity
  registerKernel(SolidMechX);
  registerKernel(SolidMechY);
  registerKernel(SolidMechZ);
  registerKernel(SolidMechImplicitEuler);
  registerKernel(SolidMechTempCoupleX);
  registerKernel(SolidMechTempCoupleY);
  registerKernel(SolidMechTempCoupleZ);

  // solid_mechanics
  registerMaterial(CLSHPlasticMaterial);
  registerMaterial(Elastic);
  registerKernel(Gravity);
  registerKernel(GravityRZ);
  registerNamedMaterial(LinearIsotropicMaterial, "LinearIsotropic");
  registerNamedMaterial(LinearIsotropicMaterialRZ, "LinearIsotropicRZ");
  registerMaterial(LinearStrainHardening);
  registerMaterial(LSHPlasticMaterial);
  registerMaterial(LSHPlasticMaterialRZ);
  registerAux(MaterialTensorAux);
  registerMaterial(PLC_LSH);
  registerMaterial(PLSHPlasticMaterial);
  registerMaterial(PowerLawCreepMaterial);
  registerMaterial(PowerLawCreep);
  registerBoundaryCondition(PlenumPressure);
  registerBoundaryCondition(PlenumPressureRZ);
  registerBoundaryCondition(Pressure);
  registerBoundaryCondition(PressureRZ);
  registerAux(ElasticEnergyAux);
  registerKernel(StressDivergence);
  registerKernel(StressDivergenceRZ);

  // phase_field
  registerKernel(AC);
  registerKernel(ACBulk);
  registerKernel(ACInterface);
  registerKernel(CHBulk);
  registerKernel(CHSplit1);
  registerKernel(CHSplit2LaPl);
  registerKernel(CHSplit2ChemPot);
  registerKernel(CHInterface);
  registerInitialCondition(CrossIC);
  registerInitialCondition(SmoothCircleIC);
  registerInitialCondition(RndSmoothCircleIC);
  registerInitialCondition(RndBoundingBoxIC);

  // contact
  registerDiracKernel(ContactMaster);
  registerDiracKernel(SlaveConstraint);
}
<commit_msg>New test for anisotropic elasticity<commit_after>#include "Elk.h"
#include "MooseFactory.h"

// misc
#include "BodyForceRZ.h"
#include "CoefDiffusion.h"
#include "Convection.h"
#include "InternalVolume.h"
#include "InternalVolumeRZ.h"
#include "NeumannRZ.h"

// heat_conduction
#include "HeatConduction.h"
#include "HeatConductionRZ.h"
#include "HeatConductionImplicitEuler.h"
#include "HeatConductionImplicitEulerRZ.h"
#include "HeatConductionMaterial.h"

// navier_stokes
#include "MassInviscidFlux.h"
#include "MomentumInviscidFlux.h"
#include "MomentumViscousFlux.h"
#include "EnergyInviscidFlux.h"
#include "EnergyViscousFlux.h"
#include "GravityPower.h"
#include "GravityForce.h"
#include "PressureNeumannBC.h"
#include "ThermalBC.h"
#include "VelocityAux.h"

// linear_elasticity
#include "SolidMechX.h"
#include "SolidMechY.h"
#include "SolidMechZ.h"
#include "SolidMechImplicitEuler.h"
#include "SolidMechTempCoupleX.h"
#include "SolidMechTempCoupleY.h"
#include "SolidMechTempCoupleZ.h"

// solid_mechanics
#include "CLSHPlasticMaterial.h"
#include "Elastic.h"
#include "Gravity.h"
#include "GravityRZ.h"
#include "LinearAnisotropicMaterial.h"
#include "LinearIsotropicMaterial.h"
#include "LinearIsotropicMaterialRZ.h"
#include "LinearStrainHardening.h"
#include "LSHPlasticMaterial.h"
#include "LSHPlasticMaterialRZ.h"
#include "MaterialTensorAux.h"
#include "PLC_LSH.h"
#include "PowerLawCreepMaterial.h"
#include "PowerLawCreep.h"
#include "PlenumPressure.h"
#include "PlenumPressureRZ.h"
#include "Pressure.h"
#include "PressureRZ.h"
#include "PLSHPlasticMaterial.h"
#include "ElasticEnergyAux.h"
#include "StressDivergence.h"
#include "StressDivergenceRZ.h"

// phase_field
#include "AC.h"
#include "ACBulk.h"
#include "ACInterface.h"
#include "CHBulk.h"
#include "CHSplit1.h"
#include "CHSplit2LaPl.h"
#include "CHSplit2ChemPot.h"
#include "CHInterface.h"
#include "CrossIC.h"
#include "SmoothCircleIC.h"
#include "RndSmoothCircleIC.h"
#include "RndBoundingBoxIC.h"

// contact
#include "ContactMaster.h"
#include "SlaveConstraint.h"

void
Elk::registerObjects()
{
  // misc
  registerKernel(BodyForceRZ);
  registerKernel(CoefDiffusion);
  registerKernel(Convection);
  registerPostprocessor(InternalVolume);
  registerPostprocessor(InternalVolumeRZ);
  registerBoundaryCondition(NeumannRZ);

  // heat_conduction
  registerKernel(HeatConduction);
  registerKernel(HeatConductionRZ);
  registerKernel(HeatConductionImplicitEuler);
  registerKernel(HeatConductionImplicitEulerRZ);
  registerNamedMaterial(HeatConductionMaterial, "HeatConduction");

  // navier_stokes
  registerKernel(MassInviscidFlux);
  registerKernel(MomentumInviscidFlux);
  registerKernel(MomentumViscousFlux);
  registerKernel(EnergyInviscidFlux);
  registerKernel(EnergyViscousFlux);
  registerKernel(GravityPower);
  registerKernel(GravityForce);
  registerBoundaryCondition(PressureNeumannBC);
  registerBoundaryCondition(ThermalBC);
  registerAux(VelocityAux);

  // linear_elasticity
  registerKernel(SolidMechX);
  registerKernel(SolidMechY);
  registerKernel(SolidMechZ);
  registerKernel(SolidMechImplicitEuler);
  registerKernel(SolidMechTempCoupleX);
  registerKernel(SolidMechTempCoupleY);
  registerKernel(SolidMechTempCoupleZ);

  // solid_mechanics
  registerMaterial(CLSHPlasticMaterial);
  registerMaterial(Elastic);
  registerKernel(Gravity);
  registerKernel(GravityRZ);
  registerNamedMaterial(LinearAnisotropicMaterial, "LinearAnisotropic");
  registerNamedMaterial(LinearIsotropicMaterial, "LinearIsotropic");
  registerNamedMaterial(LinearIsotropicMaterialRZ, "LinearIsotropicRZ");
  registerMaterial(LinearStrainHardening);
  registerMaterial(LSHPlasticMaterial);
  registerMaterial(LSHPlasticMaterialRZ);
  registerAux(MaterialTensorAux);
  registerMaterial(PLC_LSH);
  registerMaterial(PLSHPlasticMaterial);
  registerMaterial(PowerLawCreepMaterial);
  registerMaterial(PowerLawCreep);
  registerBoundaryCondition(PlenumPressure);
  registerBoundaryCondition(PlenumPressureRZ);
  registerBoundaryCondition(Pressure);
  registerBoundaryCondition(PressureRZ);
  registerAux(ElasticEnergyAux);
  registerKernel(StressDivergence);
  registerKernel(StressDivergenceRZ);

  // phase_field
  registerKernel(AC);
  registerKernel(ACBulk);
  registerKernel(ACInterface);
  registerKernel(CHBulk);
  registerKernel(CHSplit1);
  registerKernel(CHSplit2LaPl);
  registerKernel(CHSplit2ChemPot);
  registerKernel(CHInterface);
  registerInitialCondition(CrossIC);
  registerInitialCondition(SmoothCircleIC);
  registerInitialCondition(RndSmoothCircleIC);
  registerInitialCondition(RndBoundingBoxIC);

  // contact
  registerDiracKernel(ContactMaster);
  registerDiracKernel(SlaveConstraint);
}
<|endoftext|>


<commit_before>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// GRINS - General Reacting Incompressible Navier-Stokes
//
// Copyright (C) 2014-2015 Paul T. Bauman, Roy H. Stogner
// Copyright (C) 2010-2013 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-

#include "grins_config.h"

#include <iostream>

// GRINS
#include "grins/simulation.h"
#include "grins/simulation_builder.h"

// GRVY
#ifdef HAVE_GRVY
#include "grvy.h"
#endif

// libMesh
#include "libmesh/parallel.h"
#include "libmesh/exact_solution.h"

// Function for getting initial temperature field
libMesh::Real
initial_values( const libMesh::Point& p, const libMesh::Parameters &params,
		const std::string& system_name, const std::string& unknown_name );

int run( int argc, char* argv[], const GetPot& input );

int main(int argc, char* argv[])
{
#ifdef USE_GRVY_TIMERS
  GRVY::GRVY_Timer_Class grvy_timer;
  grvy_timer.Init("GRINS Timer");
#endif

  // Check command line count.
  if( argc < 3 )
    {
      // TODO: Need more consistent error handling.
      std::cerr << "Error: Must specify libMesh input file and exact solution file." << std::endl;
      exit(1); // TODO: something more sophisticated for parallel runs?
    }

  // libMesh input file should be first argument
  std::string libMesh_input_filename = argv[1];

  // Create our GetPot object.
  GetPot libMesh_inputfile( libMesh_input_filename );

  int return_flag = 0;

  std::string chem_lib = libMesh_inputfile("Physics/ReactingLowMachNavierStokes/thermochemistry_library", "DIE!");

  if( chem_lib == std::string("cantera") )
    {
#ifdef GRINS_HAVE_CANTERA
      return_flag = run(argc,argv,libMesh_inputfile);
#else
      return_flag = 77;
#endif
    }
  else if( chem_lib == std::string("antioch") )
    {
#ifdef GRINS_HAVE_ANTIOCH
      return_flag = run(argc,argv,libMesh_inputfile);
#else
      return_flag = 77;
#endif
    }
  else
    {
      return_flag = 1;
    }

  return return_flag;
}

int run( int argc, char* argv[], const GetPot& input )
{
#ifdef USE_GRVY_TIMERS
  grvy_timer.BeginTimer("Initialize Solver");
#endif

  // Initialize libMesh library.
  libMesh::LibMeshInit libmesh_init(argc, argv);

  GRINS::SimulationBuilder sim_builder;

  GRINS::Simulation grins( input,
			   sim_builder,
                           libmesh_init.comm() );

  //FIXME: We need to move this to within the Simulation object somehow...
  std::string restart_file = input( "restart-options/restart_file", "none" );

  if( restart_file == "none" )
    {
      // Asssign initial temperature value
      std::string system_name = input( "screen-options/system_name", "GRINS" );
      GRINS::SharedPtr<libMesh::EquationSystems> es = grins.get_equation_system();
      const libMesh::System& system = es->get_system(system_name);

      libMesh::Parameters &params = es->parameters;

      libMesh::Real& w_N2 = params.set<libMesh::Real>( "w_N2" );
      w_N2 = input( "Physics/ReactingLowMachNavierStokes/bound_species_3", 0.0, 0 );

      libMesh::Real& w_N = params.set<libMesh::Real>( "w_N" );
      w_N = input( "Physics/ReactingLowMachNavierStokes/bound_species_3", 0.0, 1 );

      system.project_solution( initial_values, NULL, params );
    }

#ifdef USE_GRVY_TIMERS
  grvy_timer.EndTimer("Initialize Solver");

  // Attach GRVY timer to solver
  grins.attach_grvy_timer( &grvy_timer );
#endif

  grins.run();

#ifdef USE_GRVY_TIMERS
  grvy_timer.Finalize();

  if( Parallel::Communicator_World.rank() == 0 ) grvy_timer.Summarize();
#endif

  // Get equation systems to create ExactSolution object
  GRINS::SharedPtr<libMesh::EquationSystems>
    es = grins.get_equation_system();

  //es->write("foobar.xdr");

  // Create Exact solution object and attach exact solution quantities
  libMesh::ExactSolution exact_sol(*es);

  libMesh::EquationSystems es_ref( es->get_mesh() );

  // Filename of file where comparison solution is stashed
  std::string solution_file = std::string(argv[2]);
  es_ref.read( solution_file );

  exact_sol.attach_reference_solution( &es_ref );

  // Compute error and get it in various norms
  exact_sol.compute_error("GRINS", "u");
  exact_sol.compute_error("GRINS", "v");

  if( (es->get_mesh()).mesh_dimension() == 3 )
    exact_sol.compute_error("GRINS", "w");

  exact_sol.compute_error("GRINS", "p");
  exact_sol.compute_error("GRINS", "T");
  exact_sol.compute_error("GRINS", "w_N2");
  exact_sol.compute_error("GRINS", "w_N");

  double u_l2error = exact_sol.l2_error("GRINS", "u");
  double u_h1error = exact_sol.h1_error("GRINS", "u");

  double v_l2error = exact_sol.l2_error("GRINS", "v");
  double v_h1error = exact_sol.h1_error("GRINS", "v");

  double p_l2error = exact_sol.l2_error("GRINS", "p");
  double p_h1error = exact_sol.h1_error("GRINS", "p");

  double T_l2error = exact_sol.l2_error("GRINS", "T");
  double T_h1error = exact_sol.h1_error("GRINS", "T");

  double wN_l2error = exact_sol.l2_error("GRINS", "w_N");
  double wN_h1error = exact_sol.h1_error("GRINS", "w_N");

  double wN2_l2error = exact_sol.l2_error("GRINS", "w_N2");
  double wN2_h1error = exact_sol.h1_error("GRINS", "w_N2");

  double w_l2error = 0.0,
         w_h1error = 0.0;

  if( (es->get_mesh()).mesh_dimension() == 3 )
    {
      w_l2error = exact_sol.l2_error("GRINS", "w");
      w_h1error = exact_sol.h1_error("GRINS", "w");
    }

  int return_flag = 0;

  double tol = 1.5e-8;

  if( u_l2error > tol   || u_h1error > tol   ||
      v_l2error > tol   || v_h1error > tol   ||
      w_l2error > tol   || w_h1error > tol   ||
      p_l2error > tol   || p_h1error > tol   ||
      T_l2error > tol   || T_h1error > tol   ||
      wN_l2error > tol  || wN_h1error > tol  ||
      wN2_l2error > tol || wN2_h1error > tol    )
    {
      return_flag = 1;

      std::cout << "Tolerance exceeded for thermally driven flow test." << std::endl
		<< "tolerance     = " << tol << std::endl
		<< "u l2 error    = " << u_l2error << std::endl
		<< "u h1 error    = " << u_h1error << std::endl
		<< "v l2 error    = " << v_l2error << std::endl
		<< "v h1 error    = " << v_h1error << std::endl
		<< "w l2 error    = " << w_l2error << std::endl
		<< "w h1 error    = " << w_h1error << std::endl
		<< "p l2 error    = " << p_l2error << std::endl
		<< "p h1 error    = " << p_h1error << std::endl
		<< "T l2 error    = " << T_l2error << std::endl
		<< "T h1 error    = " << T_h1error << std::endl
		<< "w_N l2 error  = " << wN_l2error << std::endl
		<< "w_N h1 error  = " << wN_h1error << std::endl
		<< "w_N2 l2 error = " << wN2_l2error << std::endl
		<< "w_N2 h1 error = " << wN2_h1error << std::endl;
    }

  return return_flag;
}

libMesh::Real
initial_values( const libMesh::Point& p, const libMesh::Parameters &params,
		const std::string& , const std::string& unknown_name )
{
  libMesh::Real value = 0.0;

  if( unknown_name == "w_N2" )
    value = params.get<libMesh::Real>("w_N2");

  else if( unknown_name == "w_N" )
    value = params.get<libMesh::Real>("w_N");

  else if( unknown_name == "T" )
    value = 300;

  else if( unknown_name == "u" )
    {
      const libMesh::Real y = p(1);
      value = 1.0*(-y*y+1);
    }

  else
    value = 0.0;

  return value;
}
<commit_msg>Use PhysicsFactoryHelper::parse_thermochemistry_model in test<commit_after>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// GRINS - General Reacting Incompressible Navier-Stokes
//
// Copyright (C) 2014-2015 Paul T. Bauman, Roy H. Stogner
// Copyright (C) 2010-2013 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-

#include "grins_config.h"

#include <iostream>

// GRINS
#include "grins/simulation.h"
#include "grins/simulation_builder.h"
#include "grins/physics_factory_helper.h"

// GRVY
#ifdef HAVE_GRVY
#include "grvy.h"
#endif

// libMesh
#include "libmesh/parallel.h"
#include "libmesh/exact_solution.h"

// Function for getting initial temperature field
libMesh::Real
initial_values( const libMesh::Point& p, const libMesh::Parameters &params,
		const std::string& system_name, const std::string& unknown_name );

int run( int argc, char* argv[], const GetPot& input );

int main(int argc, char* argv[])
{
#ifdef USE_GRVY_TIMERS
  GRVY::GRVY_Timer_Class grvy_timer;
  grvy_timer.Init("GRINS Timer");
#endif

  // Check command line count.
  if( argc < 3 )
    {
      // TODO: Need more consistent error handling.
      std::cerr << "Error: Must specify libMesh input file and exact solution file." << std::endl;
      exit(1); // TODO: something more sophisticated for parallel runs?
    }

  // libMesh input file should be first argument
  std::string libMesh_input_filename = argv[1];

  // Create our GetPot object.
  GetPot libMesh_inputfile( libMesh_input_filename );

  int return_flag = 0;

  std::string chem_lib;
  GRINS::PhysicsFactoryHelper::parse_thermochemistry_model( libMesh_inputfile,
                                                            GRINS::reacting_low_mach_navier_stokes,
                                                            chem_lib );

  if( chem_lib == std::string("cantera") )
    {
#ifdef GRINS_HAVE_CANTERA
      return_flag = run(argc,argv,libMesh_inputfile);
#else
      return_flag = 77;
#endif
    }
  else if( chem_lib == std::string("antioch") )
    {
#ifdef GRINS_HAVE_ANTIOCH
      return_flag = run(argc,argv,libMesh_inputfile);
#else
      return_flag = 77;
#endif
    }
  else
    {
      std::cerr << "ERROR: Invalid thermochemistry library!" << std::endl;
      return_flag = 1;
    }

  return return_flag;
}

int run( int argc, char* argv[], const GetPot& input )
{
#ifdef USE_GRVY_TIMERS
  grvy_timer.BeginTimer("Initialize Solver");
#endif

  // Initialize libMesh library.
  libMesh::LibMeshInit libmesh_init(argc, argv);

  GRINS::SimulationBuilder sim_builder;

  GRINS::Simulation grins( input,
			   sim_builder,
                           libmesh_init.comm() );

  //FIXME: We need to move this to within the Simulation object somehow...
  std::string restart_file = input( "restart-options/restart_file", "none" );

  if( restart_file == "none" )
    {
      // Asssign initial temperature value
      std::string system_name = input( "screen-options/system_name", "GRINS" );
      GRINS::SharedPtr<libMesh::EquationSystems> es = grins.get_equation_system();
      const libMesh::System& system = es->get_system(system_name);

      libMesh::Parameters &params = es->parameters;

      libMesh::Real& w_N2 = params.set<libMesh::Real>( "w_N2" );
      w_N2 = input( "Physics/ReactingLowMachNavierStokes/bound_species_3", 0.0, 0 );

      libMesh::Real& w_N = params.set<libMesh::Real>( "w_N" );
      w_N = input( "Physics/ReactingLowMachNavierStokes/bound_species_3", 0.0, 1 );

      system.project_solution( initial_values, NULL, params );
    }

#ifdef USE_GRVY_TIMERS
  grvy_timer.EndTimer("Initialize Solver");

  // Attach GRVY timer to solver
  grins.attach_grvy_timer( &grvy_timer );
#endif

  grins.run();

#ifdef USE_GRVY_TIMERS
  grvy_timer.Finalize();

  if( Parallel::Communicator_World.rank() == 0 ) grvy_timer.Summarize();
#endif

  // Get equation systems to create ExactSolution object
  GRINS::SharedPtr<libMesh::EquationSystems>
    es = grins.get_equation_system();

  //es->write("foobar.xdr");

  // Create Exact solution object and attach exact solution quantities
  libMesh::ExactSolution exact_sol(*es);

  libMesh::EquationSystems es_ref( es->get_mesh() );

  // Filename of file where comparison solution is stashed
  std::string solution_file = std::string(argv[2]);
  es_ref.read( solution_file );

  exact_sol.attach_reference_solution( &es_ref );

  // Compute error and get it in various norms
  exact_sol.compute_error("GRINS", "u");
  exact_sol.compute_error("GRINS", "v");

  if( (es->get_mesh()).mesh_dimension() == 3 )
    exact_sol.compute_error("GRINS", "w");

  exact_sol.compute_error("GRINS", "p");
  exact_sol.compute_error("GRINS", "T");
  exact_sol.compute_error("GRINS", "w_N2");
  exact_sol.compute_error("GRINS", "w_N");

  double u_l2error = exact_sol.l2_error("GRINS", "u");
  double u_h1error = exact_sol.h1_error("GRINS", "u");

  double v_l2error = exact_sol.l2_error("GRINS", "v");
  double v_h1error = exact_sol.h1_error("GRINS", "v");

  double p_l2error = exact_sol.l2_error("GRINS", "p");
  double p_h1error = exact_sol.h1_error("GRINS", "p");

  double T_l2error = exact_sol.l2_error("GRINS", "T");
  double T_h1error = exact_sol.h1_error("GRINS", "T");

  double wN_l2error = exact_sol.l2_error("GRINS", "w_N");
  double wN_h1error = exact_sol.h1_error("GRINS", "w_N");

  double wN2_l2error = exact_sol.l2_error("GRINS", "w_N2");
  double wN2_h1error = exact_sol.h1_error("GRINS", "w_N2");

  double w_l2error = 0.0,
         w_h1error = 0.0;

  if( (es->get_mesh()).mesh_dimension() == 3 )
    {
      w_l2error = exact_sol.l2_error("GRINS", "w");
      w_h1error = exact_sol.h1_error("GRINS", "w");
    }

  int return_flag = 0;

  double tol = 1.5e-8;

  if( u_l2error > tol   || u_h1error > tol   ||
      v_l2error > tol   || v_h1error > tol   ||
      w_l2error > tol   || w_h1error > tol   ||
      p_l2error > tol   || p_h1error > tol   ||
      T_l2error > tol   || T_h1error > tol   ||
      wN_l2error > tol  || wN_h1error > tol  ||
      wN2_l2error > tol || wN2_h1error > tol    )
    {
      return_flag = 1;

      std::cout << "Tolerance exceeded for thermally driven flow test." << std::endl
		<< "tolerance     = " << tol << std::endl
		<< "u l2 error    = " << u_l2error << std::endl
		<< "u h1 error    = " << u_h1error << std::endl
		<< "v l2 error    = " << v_l2error << std::endl
		<< "v h1 error    = " << v_h1error << std::endl
		<< "w l2 error    = " << w_l2error << std::endl
		<< "w h1 error    = " << w_h1error << std::endl
		<< "p l2 error    = " << p_l2error << std::endl
		<< "p h1 error    = " << p_h1error << std::endl
		<< "T l2 error    = " << T_l2error << std::endl
		<< "T h1 error    = " << T_h1error << std::endl
		<< "w_N l2 error  = " << wN_l2error << std::endl
		<< "w_N h1 error  = " << wN_h1error << std::endl
		<< "w_N2 l2 error = " << wN2_l2error << std::endl
		<< "w_N2 h1 error = " << wN2_h1error << std::endl;
    }

  return return_flag;
}

libMesh::Real
initial_values( const libMesh::Point& p, const libMesh::Parameters &params,
		const std::string& , const std::string& unknown_name )
{
  libMesh::Real value = 0.0;

  if( unknown_name == "w_N2" )
    value = params.get<libMesh::Real>("w_N2");

  else if( unknown_name == "w_N" )
    value = params.get<libMesh::Real>("w_N");

  else if( unknown_name == "T" )
    value = 300;

  else if( unknown_name == "u" )
    {
      const libMesh::Real y = p(1);
      value = 1.0*(-y*y+1);
    }

  else
    value = 0.0;

  return value;
}
<|endoftext|>