<commit_before>#include <config.h>
#include "righthandside_assembler.hh"

#include <dune/multiscale/tools/misc.hh>
#include <dune/multiscale/hmm/cell_problem_numbering.hh>
#include <dune/multiscale/hmm/cell_problem_solver.hh>
#include <dune/multiscale/msfem/localproblems/localsolutionmanager.hh>
#include <dune/multiscale/common/dirichletconstraints.hh>
#include <dune/multiscale/msfem/localproblems/subgrid-list.hh>
#include <dune/multiscale/problems/selector.hh>
#include <dune/stuff/fem/functions/checks.hh>
#include <dune/stuff/common/logging.hh>
#include <dune/stuff/functions/interfaces.hh>

void Dune::Multiscale::RightHandSideAssembler::assemble(const Dune::Multiscale::CommonTraits::FirstSourceType &f, Dune::Multiscale::RightHandSideAssembler::DiscreteFunctionType &rhsVector) {
  rhsVector.clear();
  for (const auto& entity : rhsVector.space()) {
    const auto& geometry = entity.geometry();
    auto elementOfRHS = rhsVector.localFunction(entity);
    const auto baseSet = rhsVector.space().basisFunctionSet(entity);
    const auto quadrature = make_quadrature(entity, rhsVector.space(), quadratureOrder);
    const auto numDofs = elementOfRHS.numDofs();
    for (auto quadraturePoint : DSC::valueRange(quadrature.nop())) {
      // the return values:
      RangeType f_x;
      std::vector<RangeType> phi_x(numDofs);
      // to save: A \nabla PHI_H * \nabla phi_h;
      const auto det = geometry.integrationElement(quadrature.point(quadraturePoint));

      f.evaluate(geometry.global(quadrature.point(quadraturePoint)), f_x);
      baseSet.evaluateAll(quadrature[quadraturePoint], phi_x);

      for (int i = 0; i < numDofs; ++i) {
        elementOfRHS[i] += det * quadrature.weight(quadraturePoint) * (f_x * phi_x[i]);
      }
    }
  }
}

void Dune::Multiscale::RightHandSideAssembler::assemble(const Dune::Multiscale::CommonTraits::FirstSourceType &f, const Dune::Multiscale::CommonTraits::DiffusionType &A, const Dune::Multiscale::RightHandSideAssembler::DiscreteFunctionType &dirichlet_extension, const Dune::Multiscale::CommonTraits::NeumannBCType &neumann_bc, Dune::Multiscale::RightHandSideAssembler::DiscreteFunctionType &rhsVector) {
  rhsVector.clear();

  for (const auto& entity : rhsVector.space()) {

    const auto& geometry = entity.geometry();
    auto elementOfRHS = rhsVector.localFunction(entity);
    const auto baseSet = rhsVector.space().basisFunctionSet(entity);

    const int numDofs = elementOfRHS.numDofs();

    std::vector<RangeType> phi_x(numDofs);
    // gradient of base function and gradient of old_u_H
    std::vector<JacobianRangeType> grad_phi_x(numDofs);

    const auto loc_dirichlet_extension = dirichlet_extension.localFunction(entity);
    const auto quadrature = make_quadrature(entity, rhsVector.space(), quadratureOrder);

    const auto& lagrangePointSet = rhsVector.space().lagrangePointSet(entity);

    for (const auto& intersection : DSC::intersectionRange(rhsVector.space().gridPart(), entity)) {
      if (Problem::isNeumannBoundary(intersection)) {
        const auto face = intersection.indexInInside();
        const auto faceQuadrature = make_quadrature(intersection, rhsVector.space(), quadratureOrder);
        const auto numFaceQuadraturePoints = faceQuadrature.nop();

        for (auto faceQuadraturePoint : DSC::valueRange(numFaceQuadraturePoints)) {
          baseSet.evaluateAll(faceQuadrature[faceQuadraturePoint], phi_x);
          baseSet.jacobianAll(faceQuadrature[faceQuadraturePoint], grad_phi_x);

          const auto local_point_entity = faceQuadrature.point(faceQuadraturePoint);
          const auto global_point = geometry.global(local_point_entity);
          const auto local_point_face = intersection.geometry().local(global_point);

          RangeType neumann_value(0.0);
          neumann_bc.evaluate(global_point, neumann_value);

          const double face_weight = intersection.geometry().integrationElement(local_point_face) *
                                     faceQuadrature.weight(faceQuadraturePoint);

          for (const auto& lp : DSC::lagrangePointSetRange(lagrangePointSet, face)) {
            elementOfRHS[lp] += neumann_value * face_weight * phi_x[lp];
          }
        }
      }
    }

    // the return values:
    RangeType f_x;

    JacobianRangeType gradient_dirichlet_extension;
    JacobianRangeType diffusive_flux_in_gradient_dirichlet_extension;

    for (auto quadraturePoint : DSC::valueRange(quadrature.nop())) {
      // local (barycentric) coordinates (with respect to entity)
      const auto& local_point = quadrature.point(quadraturePoint);
      const auto global_point = geometry.global(local_point);

      const double weight = geometry.integrationElement(local_point) * quadrature.weight(quadraturePoint);
      // evaluate the Right Hand Side Function f at the current quadrature point and save its value in 'f_y':
      f.evaluate(global_point, f_x);
      // evaluate the current base function at the current quadrature point and save its value in 'z':
      baseSet.evaluateAll(quadrature[quadraturePoint], phi_x); // i = i'te Basisfunktion;
      // evaluate the gradient of the current base function at the current quadrature point and save its value in
      // 'returnGradient':
      baseSet.jacobianAll(quadrature[quadraturePoint], grad_phi_x);
      // get gradient of dirichlet extension:
      loc_dirichlet_extension.jacobian(quadrature[quadraturePoint], gradient_dirichlet_extension);
      A.diffusiveFlux(global_point, gradient_dirichlet_extension, diffusive_flux_in_gradient_dirichlet_extension);

      for (int i = 0; i < numDofs; ++i) {
        elementOfRHS[i] += weight * (f_x * phi_x[i]);
        elementOfRHS[i] -= weight * (diffusive_flux_in_gradient_dirichlet_extension[0] * grad_phi_x[i][0]);
      }
    }
  }
}

void Dune::Multiscale::RightHandSideAssembler::assemble_for_MsFEM_symmetric(const Dune::Multiscale::CommonTraits::FirstSourceType &f, Dune::Multiscale::MsFEM::MacroMicroGridSpecifier &specifier, Dune::Multiscale::MsFEM::SubGridList &subgrid_list, Dune::Multiscale::RightHandSideAssembler::DiscreteFunctionType &rhsVector) {

  // gather some problem data
  auto diffusionPtr = Problem::getDiffusion();
  const auto& diffusion = *diffusionPtr;
  auto neumannDataPtr = Problem::getNeumannData();
  const auto& neumannData = *neumannDataPtr;

  DiscreteFunctionType dirichletExtension("Dirichlet Extension", specifier.fineSpace());
  dirichletExtension.clear();
  Dune::Multiscale::projectDirichletValues(rhsVector.space(), dirichletExtension);

  // set rhsVector to zero:
  rhsVector.clear();
  const auto& coarseGridLeafIndexSet = specifier.coarseSpace().gridPart().grid().leafIndexSet();
  RangeType f_x;
  for (const auto& coarse_grid_entity : rhsVector.space()) {
    const auto coarseEntityIndex = coarseGridLeafIndexSet.index(coarse_grid_entity);

    const auto& coarseGeometry = coarse_grid_entity.geometry();
    auto rhsLocalFunction = rhsVector.localFunction(coarse_grid_entity);
    const auto numLocalBaseFunctions = rhsLocalFunction.numDofs();
    const auto& coarse_grid_baseSet = specifier.coarseSpace().basisFunctionSet(coarse_grid_entity);

    // --------- add standard contribution of right hand side -------------------------
    {
      //!\TODO warum +5 ???
      const auto quadrature = make_quadrature(coarse_grid_entity, rhsVector.space(), quadratureOrder + 5);
      std::vector<RangeType> phi_x_vec(numLocalBaseFunctions);
      const auto numQuadraturePoints = quadrature.nop();
      for (size_t quadraturePoint = 0; quadraturePoint < numQuadraturePoints; ++quadraturePoint) {
        const double det = coarseGeometry.integrationElement(quadrature.point(quadraturePoint));
        // evaluate the Right Hand Side Function f at the current quadrature point and save its value in 'f_y':
        f.evaluate(coarseGeometry.global(quadrature.point(quadraturePoint)), f_x);
        coarse_grid_baseSet.evaluateAll(quadrature[quadraturePoint], phi_x_vec);
        for (int i = 0; i < numLocalBaseFunctions; ++i) {
          rhsLocalFunction[i] += det * quadrature.weight(quadraturePoint) * (f_x * phi_x_vec[i]);
        }
      }
    }
    // ----------------------------------------------------------------------------------

    // --------- add corrector contribution of right hand side --------------------------
    // Load local solutions
    MsFEM::LocalSolutionManager localSolutionManager(coarse_grid_entity, subgrid_list, specifier);
    localSolutionManager.loadLocalSolutions();
    auto& localSolutions = localSolutionManager.getLocalSolutions();
    assert(localSolutions.size() > 0);

    // iterator for the micro grid ( grid for the reference element T_0 )
    const auto& subGrid = subgrid_list.getSubGrid(coarse_grid_entity);
    for (const auto& localEntity : DSC::viewRange(subGrid.leafView())) {
      const auto& hostCell = subGrid.template getHostEntity<0>(localEntity);
      const auto enclosingCoarseCellIndex = subgrid_list.getEnclosingMacroCellIndex(hostCell);
      auto dirichletExtensionLF = dirichletExtension.localFunction(*hostCell);
      if (enclosingCoarseCellIndex == coarseEntityIndex) {
        // higher order quadrature, since A^{\epsilon} is highly variable
        const auto localQuadrature =
            make_quadrature(localEntity, localSolutionManager.getLocalDiscreteFunctionSpace());

        // evaluate all local solutions and their jacobians in all quadrature points
        std::vector<std::vector<RangeType>> allLocalSolutionEvaluations(
                                              localSolutions.size(), std::vector<RangeType>(localQuadrature.nop(), 0.0));
        std::vector<std::vector<JacobianRangeType>> allLocalSolutionJacobians(
                                                      localSolutions.size(), std::vector<JacobianRangeType>(localQuadrature.nop(), JacobianRangeType(0.0)));
        for (auto lsNum : DSC::valueRange(localSolutions.size())) {
          auto localFunction = localSolutions[lsNum]->localFunction(localEntity);
          // this evaluates the local solutions in all quadrature points...
          localFunction.evaluateQuadrature(localQuadrature, allLocalSolutionEvaluations[lsNum]);
          // while this automatically evaluates their jacobians.
          localFunction.evaluateQuadrature(localQuadrature, allLocalSolutionJacobians[lsNum]);

          const auto& subGridPart = localSolutionManager.getSubGridPart();
          for (const auto& intersection : DSC::intersectionRange(subGridPart.grid().leafView(), localEntity)) {
            if (Problem::isNeumannBoundary(intersection)) {
              const int orderOfIntegrand = (polynomialOrder - 1) + 2 * (polynomialOrder + 1);
              const int quadOrder = std::ceil((orderOfIntegrand + 1) / 2);
              // get type of face quadrature. Is done in this scope because Patricks methods use another type.
              const auto faceQuad = make_quadrature(intersection, localSolutions[lsNum]->space(), quadOrder);
              RangeType neumannValue(0.0);
              const auto numQuadPoints = faceQuad.nop();
              // loop over all quadrature points

              std::vector<RangeType> phi_x_vec(numLocalBaseFunctions);
              std::vector<RangeType> localSolutionOnFace(numLocalBaseFunctions);
              localFunction.evaluateQuadrature(faceQuad, localSolutionOnFace);

              for (unsigned int iqP = 0; iqP < numQuadPoints; ++iqP) {
                // get local coordinate of quadrature point
                const auto& xLocal = faceQuad.localPoint(iqP);
                const auto& faceGeometry = intersection.geometry();

                // the following does not work because subgrid does not implement geometryInInside()
                // const auto& insideGeometry    = intersection.geometryInInside();
                // const typename FaceQuadratureType::CoordinateType& xInInside = insideGeometry.global(xLocal);
                // therefore, we have to do stupid things:
                const auto& xGlobal = faceGeometry.global(xLocal);
                const auto& xInCoarseLocal = coarse_grid_entity.geometry().local(xGlobal);
                const double factor = faceGeometry.integrationElement(xLocal) * faceQuad.weight(iqP);

                neumannData.evaluate(xGlobal, neumannValue);
                coarse_grid_baseSet.evaluateAll(xInCoarseLocal, phi_x_vec);
                for (auto i : DSC::valueRange(numLocalBaseFunctions)) {
                  assert((long long)i < (long long)phi_x_vec.size());
                  assert(iqP < localSolutionOnFace.size());
                  rhsLocalFunction[i] += factor * (neumannValue * (phi_x_vec[i] + localSolutionOnFace[iqP]));
                }
              }
            }
          }
        }

        const auto& localGeometry = localEntity.geometry();
        RangeType corrector_phi_x;
        for (size_t qP = 0; qP < localQuadrature.nop(); ++qP) {
          // local (barycentric) coordinates (with respect to entity)
          const auto& quadPoint = localQuadrature.point(qP);
          const auto quadPointGlobal = localGeometry.global(quadPoint);

          const double quadWeight = localQuadrature.weight(qP) * localGeometry.integrationElement(quadPoint);

          for (int coarseBF = 0; coarseBF < numLocalBaseFunctions; ++coarseBF) {
            JacobianRangeType diffusive_flux(0.0);

            // evaluate gradient of basis function
            const auto quadPointLocalInCoarse = coarseGeometry.local(quadPointGlobal);
            std::vector<JacobianRangeType> gradient_Phi_vec(numLocalBaseFunctions);
            coarse_grid_baseSet.jacobianAll(quadPointLocalInCoarse, gradient_Phi_vec);

            JacobianRangeType reconstructionGradPhi(gradient_Phi_vec[coarseBF]);

            if (specifier.simplexCoarseGrid()) {
              assert(localSolutions.size() == GridSelector::dimgrid + localSolutionManager.numBoundaryCorrectors());
              DUNE_THROW(NotImplemented, "Boundary values are not implemented for simplex grids yet!");
            } else {
              assert(localSolutions.size() == numLocalBaseFunctions + localSolutionManager.numBoundaryCorrectors());
              // local corrector for coarse base func
              corrector_phi_x = allLocalSolutionEvaluations[coarseBF][qP];
              // element part of boundary conditions
              JacobianRangeType directionOfFlux(0.0);
              //! @attention At this point we assume, that the quadrature points on the subgrid and hostgrid
              //! are the same (dirichletExtensionLF is a localfunction on the hostgrid, quadPoint stems from
              //! a quadrature on the subgrid)!!
              dirichletExtensionLF.jacobian(quadPoint, directionOfFlux);
              // add dirichlet-corrector
              directionOfFlux += allLocalSolutionJacobians[numLocalBaseFunctions + 1][qP];
              // subtract neumann-corrector
              // directionOfFlux -= allLocalSolutionJacobians[numLocalBaseFunctions][qP];

              diffusion.diffusiveFlux(quadPointGlobal, directionOfFlux, diffusive_flux);
              reconstructionGradPhi += allLocalSolutionJacobians[coarseBF][qP];
            }
            f.evaluate(quadPointGlobal, f_x);
            double val = quadWeight * (f_x * corrector_phi_x);
            rhsLocalFunction[coarseBF] += val;
            val = quadWeight * (diffusive_flux[0] * reconstructionGradPhi[0]);
            rhsLocalFunction[coarseBF] -= val;
          }
        }
      }
    }
  }

  // set dirichlet dofs to zero
  Dune::Multiscale::getConstraintsCoarse(rhsVector.space()).setValue(0.0, rhsVector);
}
<commit_msg>Removed "debug" code<commit_after>#include <config.h>
#include "righthandside_assembler.hh"

#include <dune/multiscale/tools/misc.hh>
#include <dune/multiscale/hmm/cell_problem_numbering.hh>
#include <dune/multiscale/hmm/cell_problem_solver.hh>
#include <dune/multiscale/msfem/localproblems/localsolutionmanager.hh>
#include <dune/multiscale/common/dirichletconstraints.hh>
#include <dune/multiscale/msfem/localproblems/subgrid-list.hh>
#include <dune/multiscale/problems/selector.hh>
#include <dune/stuff/fem/functions/checks.hh>
#include <dune/stuff/common/logging.hh>
#include <dune/stuff/functions/interfaces.hh>

void Dune::Multiscale::RightHandSideAssembler::assemble(const Dune::Multiscale::CommonTraits::FirstSourceType &f, Dune::Multiscale::RightHandSideAssembler::DiscreteFunctionType &rhsVector) {
  rhsVector.clear();
  for (const auto& entity : rhsVector.space()) {
    const auto& geometry = entity.geometry();
    auto elementOfRHS = rhsVector.localFunction(entity);
    const auto baseSet = rhsVector.space().basisFunctionSet(entity);
    const auto quadrature = make_quadrature(entity, rhsVector.space(), quadratureOrder);
    const auto numDofs = elementOfRHS.numDofs();
    for (auto quadraturePoint : DSC::valueRange(quadrature.nop())) {
      // the return values:
      RangeType f_x;
      std::vector<RangeType> phi_x(numDofs);
      // to save: A \nabla PHI_H * \nabla phi_h;
      const auto det = geometry.integrationElement(quadrature.point(quadraturePoint));

      f.evaluate(geometry.global(quadrature.point(quadraturePoint)), f_x);
      baseSet.evaluateAll(quadrature[quadraturePoint], phi_x);

      for (int i = 0; i < numDofs; ++i) {
        elementOfRHS[i] += det * quadrature.weight(quadraturePoint) * (f_x * phi_x[i]);
      }
    }
  }
}

void Dune::Multiscale::RightHandSideAssembler::assemble(const Dune::Multiscale::CommonTraits::FirstSourceType &f, const Dune::Multiscale::CommonTraits::DiffusionType &A, const Dune::Multiscale::RightHandSideAssembler::DiscreteFunctionType &dirichlet_extension, const Dune::Multiscale::CommonTraits::NeumannBCType &neumann_bc, Dune::Multiscale::RightHandSideAssembler::DiscreteFunctionType &rhsVector) {
  rhsVector.clear();

  for (const auto& entity : rhsVector.space()) {

    const auto& geometry = entity.geometry();
    auto elementOfRHS = rhsVector.localFunction(entity);
    const auto baseSet = rhsVector.space().basisFunctionSet(entity);

    const int numDofs = elementOfRHS.numDofs();

    std::vector<RangeType> phi_x(numDofs);
    // gradient of base function and gradient of old_u_H
    std::vector<JacobianRangeType> grad_phi_x(numDofs);

    const auto loc_dirichlet_extension = dirichlet_extension.localFunction(entity);
    const auto quadrature = make_quadrature(entity, rhsVector.space(), quadratureOrder);

    const auto& lagrangePointSet = rhsVector.space().lagrangePointSet(entity);

    for (const auto& intersection : DSC::intersectionRange(rhsVector.space().gridPart(), entity)) {
      if (Problem::isNeumannBoundary(intersection)) {
        const auto face = intersection.indexInInside();
        const auto faceQuadrature = make_quadrature(intersection, rhsVector.space(), quadratureOrder);
        const auto numFaceQuadraturePoints = faceQuadrature.nop();

        for (auto faceQuadraturePoint : DSC::valueRange(numFaceQuadraturePoints)) {
          baseSet.evaluateAll(faceQuadrature[faceQuadraturePoint], phi_x);
          baseSet.jacobianAll(faceQuadrature[faceQuadraturePoint], grad_phi_x);

          const auto local_point_entity = faceQuadrature.point(faceQuadraturePoint);
          const auto global_point = geometry.global(local_point_entity);
          const auto local_point_face = intersection.geometry().local(global_point);

          RangeType neumann_value(0.0);
          neumann_bc.evaluate(global_point, neumann_value);

          const double face_weight = intersection.geometry().integrationElement(local_point_face) *
                                     faceQuadrature.weight(faceQuadraturePoint);

          for (const auto& lp : DSC::lagrangePointSetRange(lagrangePointSet, face)) {
            elementOfRHS[lp] += neumann_value * face_weight * phi_x[lp];
          }
        }
      }
    }

    // the return values:
    RangeType f_x;

    JacobianRangeType gradient_dirichlet_extension;
    JacobianRangeType diffusive_flux_in_gradient_dirichlet_extension;

    for (auto quadraturePoint : DSC::valueRange(quadrature.nop())) {
      // local (barycentric) coordinates (with respect to entity)
      const auto& local_point = quadrature.point(quadraturePoint);
      const auto global_point = geometry.global(local_point);

      const double weight = geometry.integrationElement(local_point) * quadrature.weight(quadraturePoint);
      // evaluate the Right Hand Side Function f at the current quadrature point and save its value in 'f_y':
      f.evaluate(global_point, f_x);
      // evaluate the current base function at the current quadrature point and save its value in 'z':
      baseSet.evaluateAll(quadrature[quadraturePoint], phi_x); // i = i'te Basisfunktion;
      // evaluate the gradient of the current base function at the current quadrature point and save its value in
      // 'returnGradient':
      baseSet.jacobianAll(quadrature[quadraturePoint], grad_phi_x);
      // get gradient of dirichlet extension:
      loc_dirichlet_extension.jacobian(quadrature[quadraturePoint], gradient_dirichlet_extension);
      A.diffusiveFlux(global_point, gradient_dirichlet_extension, diffusive_flux_in_gradient_dirichlet_extension);

      for (int i = 0; i < numDofs; ++i) {
        elementOfRHS[i] += weight * (f_x * phi_x[i]);
        elementOfRHS[i] -= weight * (diffusive_flux_in_gradient_dirichlet_extension[0] * grad_phi_x[i][0]);
      }
    }
  }
}

void Dune::Multiscale::RightHandSideAssembler::assemble_for_MsFEM_symmetric(const Dune::Multiscale::CommonTraits::FirstSourceType &f, Dune::Multiscale::MsFEM::MacroMicroGridSpecifier &specifier, Dune::Multiscale::MsFEM::SubGridList &subgrid_list, Dune::Multiscale::RightHandSideAssembler::DiscreteFunctionType &rhsVector) {

  // gather some problem data
  auto diffusionPtr = Problem::getDiffusion();
  const auto& diffusion = *diffusionPtr;
  auto neumannDataPtr = Problem::getNeumannData();
  const auto& neumannData = *neumannDataPtr;

  DiscreteFunctionType dirichletExtension("Dirichlet Extension", specifier.fineSpace());
  dirichletExtension.clear();
  Dune::Multiscale::projectDirichletValues(rhsVector.space(), dirichletExtension);

  // set rhsVector to zero:
  rhsVector.clear();
  const auto& coarseGridLeafIndexSet = specifier.coarseSpace().gridPart().grid().leafIndexSet();
  RangeType f_x;
  for (const auto& coarse_grid_entity : rhsVector.space()) {
    const auto coarseEntityIndex = coarseGridLeafIndexSet.index(coarse_grid_entity);

    const auto& coarseGeometry = coarse_grid_entity.geometry();
    auto rhsLocalFunction = rhsVector.localFunction(coarse_grid_entity);
    const auto numLocalBaseFunctions = rhsLocalFunction.numDofs();
    const auto& coarse_grid_baseSet = specifier.coarseSpace().basisFunctionSet(coarse_grid_entity);

    // --------- add standard contribution of right hand side -------------------------
    {
      const auto quadrature = make_quadrature(coarse_grid_entity, rhsVector.space(), quadratureOrder);
      std::vector<RangeType> phi_x_vec(numLocalBaseFunctions);
      const auto numQuadraturePoints = quadrature.nop();
      for (size_t quadraturePoint = 0; quadraturePoint < numQuadraturePoints; ++quadraturePoint) {
        const double det = coarseGeometry.integrationElement(quadrature.point(quadraturePoint));
        // evaluate the Right Hand Side Function f at the current quadrature point and save its value in 'f_y':
        f.evaluate(coarseGeometry.global(quadrature.point(quadraturePoint)), f_x);
        coarse_grid_baseSet.evaluateAll(quadrature[quadraturePoint], phi_x_vec);
        for (int i = 0; i < numLocalBaseFunctions; ++i) {
          rhsLocalFunction[i] += det * quadrature.weight(quadraturePoint) * (f_x * phi_x_vec[i]);
        }
      }
    }
    // ----------------------------------------------------------------------------------

    // --------- add corrector contribution of right hand side --------------------------
    // Load local solutions
    MsFEM::LocalSolutionManager localSolutionManager(coarse_grid_entity, subgrid_list, specifier);
    localSolutionManager.loadLocalSolutions();
    auto& localSolutions = localSolutionManager.getLocalSolutions();
    assert(localSolutions.size() > 0);

    // iterator for the micro grid ( grid for the reference element T_0 )
    const auto& subGrid = subgrid_list.getSubGrid(coarse_grid_entity);
    for (const auto& localEntity : DSC::viewRange(subGrid.leafView())) {
      const auto& hostCell = subGrid.template getHostEntity<0>(localEntity);
      const auto enclosingCoarseCellIndex = subgrid_list.getEnclosingMacroCellIndex(hostCell);
      auto dirichletExtensionLF = dirichletExtension.localFunction(*hostCell);
      if (enclosingCoarseCellIndex == coarseEntityIndex) {
        // higher order quadrature, since A^{\epsilon} is highly variable
        const auto localQuadrature =
            make_quadrature(localEntity, localSolutionManager.getLocalDiscreteFunctionSpace());

        // evaluate all local solutions and their jacobians in all quadrature points
        std::vector<std::vector<RangeType>> allLocalSolutionEvaluations(
                                              localSolutions.size(), std::vector<RangeType>(localQuadrature.nop(), 0.0));
        std::vector<std::vector<JacobianRangeType>> allLocalSolutionJacobians(
                                                      localSolutions.size(), std::vector<JacobianRangeType>(localQuadrature.nop(), JacobianRangeType(0.0)));
        for (auto lsNum : DSC::valueRange(localSolutions.size())) {
          auto localFunction = localSolutions[lsNum]->localFunction(localEntity);
          // this evaluates the local solutions in all quadrature points...
          localFunction.evaluateQuadrature(localQuadrature, allLocalSolutionEvaluations[lsNum]);
          // while this automatically evaluates their jacobians.
          localFunction.evaluateQuadrature(localQuadrature, allLocalSolutionJacobians[lsNum]);

          const auto& subGridPart = localSolutionManager.getSubGridPart();
          for (const auto& intersection : DSC::intersectionRange(subGridPart.grid().leafView(), localEntity)) {
            if (Problem::isNeumannBoundary(intersection)) {
              const int orderOfIntegrand = (polynomialOrder - 1) + 2 * (polynomialOrder + 1);
              const int quadOrder = std::ceil((orderOfIntegrand + 1) / 2);
              // get type of face quadrature. Is done in this scope because Patricks methods use another type.
              const auto faceQuad = make_quadrature(intersection, localSolutions[lsNum]->space(), quadOrder);
              RangeType neumannValue(0.0);
              const auto numQuadPoints = faceQuad.nop();
              // loop over all quadrature points

              std::vector<RangeType> phi_x_vec(numLocalBaseFunctions);
              std::vector<RangeType> localSolutionOnFace(numLocalBaseFunctions);
              localFunction.evaluateQuadrature(faceQuad, localSolutionOnFace);

              for (unsigned int iqP = 0; iqP < numQuadPoints; ++iqP) {
                // get local coordinate of quadrature point
                const auto& xLocal = faceQuad.localPoint(iqP);
                const auto& faceGeometry = intersection.geometry();

                // the following does not work because subgrid does not implement geometryInInside()
                // const auto& insideGeometry    = intersection.geometryInInside();
                // const typename FaceQuadratureType::CoordinateType& xInInside = insideGeometry.global(xLocal);
                // therefore, we have to do stupid things:
                const auto& xGlobal = faceGeometry.global(xLocal);
                const auto& xInCoarseLocal = coarse_grid_entity.geometry().local(xGlobal);
                const double factor = faceGeometry.integrationElement(xLocal) * faceQuad.weight(iqP);

                neumannData.evaluate(xGlobal, neumannValue);
                coarse_grid_baseSet.evaluateAll(xInCoarseLocal, phi_x_vec);
                for (auto i : DSC::valueRange(numLocalBaseFunctions)) {
                  assert((long long)i < (long long)phi_x_vec.size());
                  assert(iqP < localSolutionOnFace.size());
                  rhsLocalFunction[i] += factor * (neumannValue * (phi_x_vec[i] + localSolutionOnFace[iqP]));
                }
              }
            }
          }
        }

        const auto& localGeometry = localEntity.geometry();
        RangeType corrector_phi_x;
        for (size_t qP = 0; qP < localQuadrature.nop(); ++qP) {
          // local (barycentric) coordinates (with respect to entity)
          const auto& quadPoint = localQuadrature.point(qP);
          const auto quadPointGlobal = localGeometry.global(quadPoint);

          const double quadWeight = localQuadrature.weight(qP) * localGeometry.integrationElement(quadPoint);

          for (int coarseBF = 0; coarseBF < numLocalBaseFunctions; ++coarseBF) {
            JacobianRangeType diffusive_flux(0.0);

            // evaluate gradient of basis function
            const auto quadPointLocalInCoarse = coarseGeometry.local(quadPointGlobal);
            std::vector<JacobianRangeType> gradient_Phi_vec(numLocalBaseFunctions);
            coarse_grid_baseSet.jacobianAll(quadPointLocalInCoarse, gradient_Phi_vec);

            JacobianRangeType reconstructionGradPhi(gradient_Phi_vec[coarseBF]);

            if (specifier.simplexCoarseGrid()) {
              assert(localSolutions.size() == GridSelector::dimgrid + localSolutionManager.numBoundaryCorrectors());
              DUNE_THROW(NotImplemented, "Boundary values are not implemented for simplex grids yet!");
            } else {
              assert(localSolutions.size() == numLocalBaseFunctions + localSolutionManager.numBoundaryCorrectors());
              // local corrector for coarse base func
              corrector_phi_x = allLocalSolutionEvaluations[coarseBF][qP];
              // element part of boundary conditions
              JacobianRangeType directionOfFlux(0.0);
              //! @attention At this point we assume, that the quadrature points on the subgrid and hostgrid
              //! are the same (dirichletExtensionLF is a localfunction on the hostgrid, quadPoint stems from
              //! a quadrature on the subgrid)!!
              dirichletExtensionLF.jacobian(quadPoint, directionOfFlux);
              // add dirichlet-corrector
              directionOfFlux += allLocalSolutionJacobians[numLocalBaseFunctions + 1][qP];
              // subtract neumann-corrector
              // directionOfFlux -= allLocalSolutionJacobians[numLocalBaseFunctions][qP];

              diffusion.diffusiveFlux(quadPointGlobal, directionOfFlux, diffusive_flux);
              reconstructionGradPhi += allLocalSolutionJacobians[coarseBF][qP];
            }
            f.evaluate(quadPointGlobal, f_x);
            double val = quadWeight * (f_x * corrector_phi_x);
            rhsLocalFunction[coarseBF] += val;
            val = quadWeight * (diffusive_flux[0] * reconstructionGradPhi[0]);
            rhsLocalFunction[coarseBF] -= val;
          }
        }
      }
    }
  }

  // set dirichlet dofs to zero
  Dune::Multiscale::getConstraintsCoarse(rhsVector.space()).setValue(0.0, rhsVector);
}
<|endoftext|>


<commit_before>/***********************************************************************************************************************
**
** Copyright (c) 2011, 2014 ETH Zurich
** 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 the ETH Zurich 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 HOLDER 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.
**
***********************************************************************************************************************/

#include "DebugConnector.h"

#include "Protocol.h"
#include "Reply.h"
#include "Command.h"

#include "reply/VersionInfo.h"

namespace OODebug {

DebugConnector::DebugConnector()
{
	QObject::connect(tcpSocket_, static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)>(&QTcpSocket::error),
						  this, &DebugConnector::handleSocketError);
}

DebugConnector::~DebugConnector()
{
	tcpSocket_->abort();
	delete tcpSocket_;
}

void DebugConnector::connect(QString vmHostName, int vmHostPort)
{
	if (tcpSocket_->isOpen())
		tcpSocket_->close();
	// The connection setup is handled here:
	// First when we are connected we have to send the handshake. For receiving the hanshake reply,
	// we use a dedicated function which disconnects itself and connects the actual read function
	// to the readyRead slot. In this way we don't have the handshake handling in the normal read function.
	QObject::connect(tcpSocket_, &QTcpSocket::readyRead, this, &DebugConnector::readHandshake);
	QObject::connect(tcpSocket_, &QTcpSocket::connected, this, &DebugConnector::sendHandshake);
	tcpSocket_->connectToHost(vmHostName, vmHostPort);
}

void DebugConnector::handleSocketError(QAbstractSocket::SocketError socketError)
{
	qDebug() << "ERROR: " << socketError;
	qWarning() << socketError;
}

void DebugConnector::read()
{
	QByteArray read =	tcpSocket_->readAll();
	// If we still have a part of a packet add it here.
	if (!incompleteData_.isEmpty()) {
		read.prepend(incompleteData_);
		incompleteData_ = QByteArray();
	}
	// If we haven't read enough retry later
	if (read.size() < int(sizeof(qint32))) {
		incompleteData_ = read;
		return;
	}
	// check if the packet is complete
	QDataStream inStream(read);
	qint32 len;
	inStream >> len;
	if (len > read.length()) {
		incompleteData_ = read;
		return;
	}
	// We have read the whole data for this message so handle it.
	qint32 id;
	inStream >> id;
	handlePacket(id, read);
}

void DebugConnector::sendCommand(Command& c, HandleFunction handler)
{
	handlingMap_[c.id()] = handler;
	QByteArray raw;
	QDataStream stream(&raw, QIODevice::ReadWrite);
	stream << c;
	tcpSocket_->write(raw);
}

void DebugConnector::readHandshake()
{
	QByteArray read =	tcpSocket_->readAll();
	if (read == Protocol::handshake)
	{
		QObject::disconnect(tcpSocket_, &QTcpSocket::readyRead, this, &DebugConnector::readHandshake);
		QObject::connect(tcpSocket_, &QTcpSocket::readyRead, this, &DebugConnector::read);
		// TODO: This is just for testing now
		sendVersionRequest();
	}
	else
	{
		qWarning() << "Handshake not received: " << read;
	}
}

void DebugConnector::sendHandshake()
{
	tcpSocket_->write(Protocol::handshake.toLatin1());
}

void DebugConnector::handlePacket(qint32 id, QByteArray data)
{
	auto handlingFun = handlingMap_.take(id);
	if (handlingFun) // We received a reply
	{
		// check for an error
		auto r = makeReply<Reply>(data);
		if (Protocol::Error::NONE == r.error())
		{
			handlingFun(*this, data);
		}
		else
		{
			// TODO: handle this better
			qWarning() << "Error received: " << static_cast<int>(r.error());
		}
	}
	else // We received a command
	{
		// TODO: handle commands
		qWarning() << "Command received ";
	}
}

void DebugConnector::sendVersionRequest()
{
	Command c(nextId(), Protocol::CommandSet::VirtualMachine, Protocol::VirtualMachineCommands::Version);
	sendCommand(c, &DebugConnector::handleVersion);
}

void DebugConnector::handleVersion(QByteArray data)
{
	auto info = makeReply<VersionInfo>(data);
	qDebug() << "VM-INFO: " << info.jdwpMajor() << info.jdwpMinor();
}

} /* namespace OODebug */
<commit_msg>Add message length when sending a command<commit_after>/***********************************************************************************************************************
**
** Copyright (c) 2011, 2014 ETH Zurich
** 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 the ETH Zurich 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 HOLDER 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.
**
***********************************************************************************************************************/

#include "DebugConnector.h"

#include "Protocol.h"
#include "Reply.h"
#include "Command.h"

#include "reply/VersionInfo.h"

namespace OODebug {

DebugConnector::DebugConnector()
{
	QObject::connect(tcpSocket_, static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)>(&QTcpSocket::error),
						  this, &DebugConnector::handleSocketError);
}

DebugConnector::~DebugConnector()
{
	tcpSocket_->abort();
	delete tcpSocket_;
}

void DebugConnector::connect(QString vmHostName, int vmHostPort)
{
	if (tcpSocket_->isOpen())
		tcpSocket_->close();
	// The connection setup is handled here:
	// First when we are connected we have to send the handshake. For receiving the hanshake reply,
	// we use a dedicated function which disconnects itself and connects the actual read function
	// to the readyRead slot. In this way we don't have the handshake handling in the normal read function.
	QObject::connect(tcpSocket_, &QTcpSocket::readyRead, this, &DebugConnector::readHandshake);
	QObject::connect(tcpSocket_, &QTcpSocket::connected, this, &DebugConnector::sendHandshake);
	tcpSocket_->connectToHost(vmHostName, vmHostPort);
}

void DebugConnector::handleSocketError(QAbstractSocket::SocketError socketError)
{
	qDebug() << "ERROR: " << socketError;
	qWarning() << socketError;
}

void DebugConnector::read()
{
	QByteArray read =	tcpSocket_->readAll();
	// If we still have a part of a packet add it here.
	if (!incompleteData_.isEmpty()) {
		read.prepend(incompleteData_);
		incompleteData_ = QByteArray();
	}
	// If we haven't read enough retry later
	if (read.size() < int(sizeof(qint32))) {
		incompleteData_ = read;
		return;
	}
	// check if the packet is complete
	QDataStream inStream(read);
	qint32 len;
	inStream >> len;
	if (len > read.length()) {
		incompleteData_ = read;
		return;
	}
	// We have read the whole data for this message so handle it.
	qint32 id;
	inStream >> id;
	handlePacket(id, read);
}

void DebugConnector::sendCommand(Command& c, HandleFunction handler)
{
	handlingMap_[c.id()] = handler;
	QByteArray raw;
	QDataStream stream(&raw, QIODevice::ReadWrite);
	stream << c;
	// Insert the length, it is always at position 0
	QByteArray len;
	qint32 dataLen = raw.length();
	QDataStream lenStream(&len, QIODevice::ReadWrite);
	lenStream << dataLen;
	raw.replace(0, len.length(), len);
	tcpSocket_->write(raw);
}

void DebugConnector::readHandshake()
{
	QByteArray read =	tcpSocket_->readAll();
	if (read == Protocol::handshake)
	{
		QObject::disconnect(tcpSocket_, &QTcpSocket::readyRead, this, &DebugConnector::readHandshake);
		QObject::connect(tcpSocket_, &QTcpSocket::readyRead, this, &DebugConnector::read);
		// TODO: This is just for testing now
		sendVersionRequest();
	}
	else
	{
		qWarning() << "Handshake not received: " << read;
	}
}

void DebugConnector::sendHandshake()
{
	tcpSocket_->write(Protocol::handshake.toLatin1());
}

void DebugConnector::handlePacket(qint32 id, QByteArray data)
{
	auto handlingFun = handlingMap_.take(id);
	if (handlingFun) // We received a reply
	{
		// check for an error
		auto r = makeReply<Reply>(data);
		if (Protocol::Error::NONE == r.error())
		{
			handlingFun(*this, data);
		}
		else
		{
			// TODO: handle this better
			qWarning() << "Error received: " << static_cast<int>(r.error());
		}
	}
	else // We received a command
	{
		// TODO: handle commands
		qWarning() << "Command received" << data.toHex();
	}
}

void DebugConnector::sendVersionRequest()
{
	Command c(nextId(), Protocol::CommandSet::VirtualMachine, Protocol::VirtualMachineCommands::Version);
	sendCommand(c, &DebugConnector::handleVersion);
}

void DebugConnector::handleVersion(QByteArray data)
{
	auto info = makeReply<VersionInfo>(data);
	qDebug() << "VM-INFO: " << info.jdwpMajor() << info.jdwpMinor();
}

} /* namespace OODebug */
<|endoftext|>


<commit_before>/*
 * File:   main.cpp
 * Author: krr428
 *
 * Created on October 30, 2014, 7:36 PM
 */

#include <cstdlib>
#include <fstream>
#include <iostream>
#include "secali.h"
#include <vector>
#include <string>

void get_reads_from_file(const std::string& fileReads, std::vector<std::string>& reads)
{
    std::ifstream ifile(fileReads);
    while (ifile)
    {
        std::string line;
        std::getline(ifile, line);
        if (line != "\n" && line != "")
        {
            reads.push_back(line);
        }
    }
    ifile.close();
    std::cout << "Finished reading input file." << std::endl;
}

void compute_overlap_matrix(const std::vector<std::string>& reads, std::vector<int_fast16_t>& output_matrix)
{
    uint_least64_t row = 0;
    for (std::string readA : reads)
    {
        for (std::string readB : reads)
        {
            int_fast16_t score = get_score(readA, readB, 2);
            output_matrix.push_back(score);
        }
        if (row % 1 == 0)
        {
            std::cout << "Handled " << row << " of " << reads.size() << std::endl;
        }
        row += 1;

    }
}

void write_matrix(const std::string& outfile, std::vector<int_fast16_t>& output_matrix, int num_cols)
{
    int i = 0;
    std::ofstream ofile(outfile);
    for (int_fast16_t n : output_matrix)
    {
        ofile << n << ' ';
        if (i++ == num_cols)
        {
            ofile << std::endl;
            i = 0;
        }
    }
    ofile.close();
}

/*
 *
 */
int main(int argc, char** argv)
{
//    const std::string input_file = "../Fasta/real.error.large.fasta.txt";
//    const std::string input_file = "../Fasta/test.txt";
    const std::string input_file(argv[1]);

    std::vector<int_fast16_t> output_matrix;
    std::vector<std::string> reads;

    get_reads_from_file(input_file, reads);
    compute_overlap_matrix(reads, output_matrix);
    write_matrix(std::string(argv[2]), output_matrix, reads.at(0).size());

    return 0;
}

<commit_msg>Every row is now written out in real time.<commit_after>/*
 * File:   main.cpp
 * Author: krr428
 *
 * Created on October 30, 2014, 7:36 PM
 */

#include <cstdlib>
#include <fstream>
#include <iostream>
#include "secali.h"
#include <vector>
#include <string>

void get_reads_from_file(const std::string& fileReads, std::vector<std::string>& reads)
{
    std::ifstream ifile(fileReads);
    while (ifile)
    {
        std::string line;
        std::getline(ifile, line);
        if (line != "\n" && line != "")
        {
            reads.push_back(line);
        }
    }
    ifile.close();
    std::cout << "Finished reading input file." << std::endl;
}

void compute_overlap_matrix(const std::vector<std::string>& reads, const std::string& output_file)
{
    uint_least64_t row = 0;
    std::ofstream ofile(output_file);

    for (std::string readA : reads)
    {
        std::vector<int_fast16_t> output_row;
        for (std::string readB : reads)
        {
            int_fast16_t score = get_score(readA, readB, 2);
            output_row.push_back(score);
        }
        for (int_fast16_t n: output_row)
        {
            ofile << n << '\t';
        }
        ofile << std::endl;
        std::cout << "Handled " << ++row << " of " << reads.size() << std::endl;

    }

    ofile.close();
}

//void write_matrix(const std::string& outfile, std::vector<int_fast16_t>& output_matrix, int num_cols)
//{
//    int i = 0;
//    std::ofstream ofile(outfile);
//    for (int_fast16_t n : output_matrix)
//    {
//        ofile << n << ' ';
//        if (i++ == num_cols)
//        {
//            ofile << std::endl;
//            i = 0;
//        }
//    }
//    ofile.close();
//}

/*
 *
 */
int main(int argc, char** argv)
{
//    const std::string input_file = "../Fasta/real.error.large.fasta.txt";
//    const std::string input_file = "../Fasta/test.txt";
    const std::string input_file(argv[1]);

    std::vector<int_fast16_t> output_matrix;
    std::vector<std::string> reads;

    get_reads_from_file(input_file, reads);
    compute_overlap_matrix(reads, argv[2]);

    return 0;
}

<|endoftext|>


<commit_before>#include <config.h>
#include <assert.h>
#include <dune/common/exceptions.hh>
#include <dune/multiscale/problems/selector.hh>
#include <dune/stuff/common/ranges.hh>
#include <memory>

#include "dune/multiscale/common/traits.hh"
#include "dune/multiscale/common/dirichletconstraints.hh"
#include "dune/multiscale/msfem/msfem_grid_specifier.hh"
#include "dune/multiscale/msfem/localproblems/subgrid-list.hh"
#include "dune/multiscale/msfem/localproblems/localsolutionmanager.hh"
#include "righthandside_assembler.hh"

void Dune::Multiscale::RightHandSideAssembler::assemble(const Dune::Multiscale::CommonTraits::FirstSourceType &f, Dune::Multiscale::RightHandSideAssembler::DiscreteFunctionType &rhsVector) {
  rhsVector.clear();
  for (const auto& entity : rhsVector.space()) {
    const auto& geometry = entity.geometry();
    auto elementOfRHS = rhsVector.localFunction(entity);
    const auto baseSet = rhsVector.space().basisFunctionSet(entity);
    const auto quadrature = make_quadrature(entity, rhsVector.space(), quadratureOrder);
    const auto numDofs = elementOfRHS.numDofs();
    for (auto quadraturePoint : DSC::valueRange(quadrature.nop())) {
      // the return values:
      RangeType f_x;
      std::vector<RangeType> phi_x(numDofs);
      // to save: A \nabla PHI_H * \nabla phi_h;
      const auto det = geometry.integrationElement(quadrature.point(quadraturePoint));

      f.evaluate(geometry.global(quadrature.point(quadraturePoint)), f_x);
      baseSet.evaluateAll(quadrature[quadraturePoint], phi_x);

      for (int i = 0; i < numDofs; ++i) {
        elementOfRHS[i] += det * quadrature.weight(quadraturePoint) * (f_x * phi_x[i]);
      }
    }
  }
}

void Dune::Multiscale::RightHandSideAssembler::assemble(
    const Dune::Multiscale::CommonTraits::FirstSourceType &f,
    const Dune::Multiscale::CommonTraits::DiffusionType &A,
    const Dune::Multiscale::RightHandSideAssembler::DiscreteFunctionType &
        dirichlet_extension,
    const Dune::Multiscale::CommonTraits::NeumannBCType &neumann_bc,
    Dune::Multiscale::RightHandSideAssembler::DiscreteFunctionType &rhsVector) {
  rhsVector.clear();

  for (const auto& entity : rhsVector.space()) {

    const auto& geometry = entity.geometry();
    auto elementOfRHS = rhsVector.localFunction(entity);
    const auto baseSet = rhsVector.space().basisFunctionSet(entity);

    const int numDofs = elementOfRHS.numDofs();

    std::vector<RangeType> phi_x(numDofs);
    // gradient of base function and gradient of old_u_H
    std::vector<JacobianRangeType> grad_phi_x(numDofs);

    const auto loc_dirichlet_extension = dirichlet_extension.localFunction(entity);
    const auto quadrature = make_quadrature(entity, rhsVector.space(), quadratureOrder);

    const auto& lagrangePointSet = rhsVector.space().lagrangePointSet(entity);

    for (const auto& intersection : DSC::intersectionRange(rhsVector.space().gridPart(), entity)) {
      if (Problem::isNeumannBoundary(intersection)) {
        const auto face = intersection.indexInInside();
        const auto faceQuadrature = make_quadrature(intersection, rhsVector.space(), quadratureOrder);
        const auto numFaceQuadraturePoints = faceQuadrature.nop();

        for (auto faceQuadraturePoint : DSC::valueRange(numFaceQuadraturePoints)) {
          baseSet.evaluateAll(faceQuadrature[faceQuadraturePoint], phi_x);
          baseSet.jacobianAll(faceQuadrature[faceQuadraturePoint], grad_phi_x);

          const auto local_point_entity = faceQuadrature.point(faceQuadraturePoint);
          const auto global_point = geometry.global(local_point_entity);
          const auto local_point_face = intersection.geometry().local(global_point);

          RangeType neumann_value(0.0);
          neumann_bc.evaluate(global_point, neumann_value);

          const double face_weight = intersection.geometry().integrationElement(local_point_face) *
                                     faceQuadrature.weight(faceQuadraturePoint);

          for (const auto& lp : DSC::lagrangePointSetRange(lagrangePointSet, face)) {
            elementOfRHS[lp] += neumann_value * face_weight * phi_x[lp];
          }
        }
      }
    }

    // the return values:
    RangeType f_x;

    JacobianRangeType gradient_dirichlet_extension;
    JacobianRangeType diffusive_flux_in_gradient_dirichlet_extension;

    for (auto quadraturePoint : DSC::valueRange(quadrature.nop())) {
      // local (barycentric) coordinates (with respect to entity)
      const auto& local_point = quadrature.point(quadraturePoint);
      const auto global_point = geometry.global(local_point);

      const double weight = geometry.integrationElement(local_point) * quadrature.weight(quadraturePoint);
      // evaluate the Right Hand Side Function f at the current quadrature point and save its value in 'f_y':
      f.evaluate(global_point, f_x);
      // evaluate the current base function at the current quadrature point and save its value in 'z':
      baseSet.evaluateAll(quadrature[quadraturePoint], phi_x); // i = i'te Basisfunktion;
      // evaluate the gradient of the current base function at the current quadrature point and save its value in
      // 'returnGradient':
      baseSet.jacobianAll(quadrature[quadraturePoint], grad_phi_x);
      // get gradient of dirichlet extension:
      loc_dirichlet_extension.jacobian(quadrature[quadraturePoint], gradient_dirichlet_extension);
      A.diffusiveFlux(global_point, gradient_dirichlet_extension, diffusive_flux_in_gradient_dirichlet_extension);

      for (int i = 0; i < numDofs; ++i) {
        elementOfRHS[i] += weight * (f_x * phi_x[i]);
        elementOfRHS[i] -= weight * (diffusive_flux_in_gradient_dirichlet_extension[0] * grad_phi_x[i][0]);
      }
    }
  }
}

void Dune::Multiscale::RightHandSideAssembler::assemble_for_MsFEM_symmetric(const Dune::Multiscale::CommonTraits::FirstSourceType &f, Dune::Multiscale::MsFEM::MacroMicroGridSpecifier &specifier, Dune::Multiscale::MsFEM::SubGridList &subgrid_list, Dune::Multiscale::RightHandSideAssembler::DiscreteFunctionType &rhsVector) {

  // gather some problem data
  auto diffusionPtr = Problem::getDiffusion();
  const auto& diffusion = *diffusionPtr;
  auto neumannDataPtr = Problem::getNeumannData();
  const auto& neumannData = *neumannDataPtr;

  DiscreteFunctionType dirichletExtension("Dirichlet Extension", specifier.fineSpace());
  dirichletExtension.clear();
  Dune::Multiscale::projectDirichletValues(rhsVector.space(), dirichletExtension);

  // set rhsVector to zero:
  rhsVector.clear();
  const auto& coarseGridLeafIndexSet = specifier.coarseSpace().gridPart().grid().leafIndexSet();
  RangeType f_x;
  for (const auto& coarse_grid_entity : rhsVector.space()) {
    const auto coarseEntityIndex = coarseGridLeafIndexSet.index(coarse_grid_entity);

    const auto& coarseGeometry = coarse_grid_entity.geometry();
    auto rhsLocalFunction = rhsVector.localFunction(coarse_grid_entity);
    const auto numLocalBaseFunctions = rhsLocalFunction.numDofs();
    const auto& coarse_grid_baseSet = specifier.coarseSpace().basisFunctionSet(coarse_grid_entity);

    // --------- add standard contribution of right hand side -------------------------
    {
      const auto quadrature = make_quadrature(coarse_grid_entity, rhsVector.space(), quadratureOrder);
      std::vector<RangeType> phi_x_vec(numLocalBaseFunctions);
      const auto numQuadraturePoints = quadrature.nop();
      for (size_t quadraturePoint = 0; quadraturePoint < numQuadraturePoints; ++quadraturePoint) {
        const double det = coarseGeometry.integrationElement(quadrature.point(quadraturePoint));
        // evaluate the Right Hand Side Function f at the current quadrature point and save its value in 'f_y':
        f.evaluate(coarseGeometry.global(quadrature.point(quadraturePoint)), f_x);
        coarse_grid_baseSet.evaluateAll(quadrature[quadraturePoint], phi_x_vec);
        for (int i = 0; i < numLocalBaseFunctions; ++i) {
          rhsLocalFunction[i] += det * quadrature.weight(quadraturePoint) * (f_x * phi_x_vec[i]);
        }
      }
    }
    // ----------------------------------------------------------------------------------

    // --------- add corrector contribution of right hand side --------------------------
    // Load local solutions
    MsFEM::LocalSolutionManager localSolutionManager(coarse_grid_entity, subgrid_list, specifier);
    localSolutionManager.loadLocalSolutions();
    auto& localSolutions = localSolutionManager.getLocalSolutions();
    assert(localSolutions.size() > 0);

    // iterator for the micro grid ( grid for the reference element T_0 )
    const auto& subGrid = subgrid_list.getSubGrid(coarse_grid_entity);
    for (const auto& localEntity : DSC::viewRange(subGrid.leafView())) {
      const auto& hostCell = subGrid.getHostEntity<0>(localEntity);
      const auto enclosingCoarseCellIndex = subgrid_list.getEnclosingMacroCellIndex(hostCell);
      auto dirichletExtensionLF = dirichletExtension.localFunction(*hostCell);
      if (enclosingCoarseCellIndex == coarseEntityIndex) {
        // higher order quadrature, since A^{\epsilon} is highly variable
        const auto localQuadrature =
            make_quadrature(localEntity, localSolutionManager.getLocalDiscreteFunctionSpace());

        // evaluate all local solutions and their jacobians in all quadrature points
        std::vector<std::vector<RangeType>> allLocalSolutionEvaluations(
                                              localSolutions.size(), std::vector<RangeType>(localQuadrature.nop(), 0.0));
        std::vector<std::vector<JacobianRangeType>> allLocalSolutionJacobians(
                                                      localSolutions.size(), std::vector<JacobianRangeType>(localQuadrature.nop(), JacobianRangeType(0.0)));
        for (auto lsNum : DSC::valueRange(localSolutions.size())) {
          auto localFunction = localSolutions[lsNum]->localFunction(localEntity);
          // this evaluates the local solutions in all quadrature points...
          localFunction.evaluateQuadrature(localQuadrature, allLocalSolutionEvaluations[lsNum]);
          // while this automatically evaluates their jacobians.
          localFunction.evaluateQuadrature(localQuadrature, allLocalSolutionJacobians[lsNum]);

          const auto& subGridPart = localSolutionManager.getSubGridPart();
          for (const auto& intersection : DSC::intersectionRange(subGridPart.grid().leafView(), localEntity)) {
            if (Problem::isNeumannBoundary(intersection)) {
              const int orderOfIntegrand = (polynomialOrder - 1) + 2 * (polynomialOrder + 1);
              const int quadOrder = std::ceil((orderOfIntegrand + 1) / 2);
              // get type of face quadrature. Is done in this scope because Patricks methods use another type.
              const auto faceQuad = make_quadrature(intersection, localSolutions[lsNum]->space(), quadOrder);
              RangeType neumannValue(0.0);
              const auto numQuadPoints = faceQuad.nop();
              // loop over all quadrature points

              std::vector<RangeType> phi_x_vec(numLocalBaseFunctions);
              std::vector<RangeType> localSolutionOnFace(numLocalBaseFunctions);
              localFunction.evaluateQuadrature(faceQuad, localSolutionOnFace);

              for (unsigned int iqP = 0; iqP < numQuadPoints; ++iqP) {
                // get local coordinate of quadrature point
                const auto& xLocal = faceQuad.localPoint(iqP);
                const auto& faceGeometry = intersection.geometry();

                // the following does not work because subgrid does not implement geometryInInside()
                // const auto& insideGeometry    = intersection.geometryInInside();
                // const typename FaceQuadratureType::CoordinateType& xInInside = insideGeometry.global(xLocal);
                // therefore, we have to do stupid things:
                const auto& xGlobal = faceGeometry.global(xLocal);
                const auto& xInCoarseLocal = coarse_grid_entity.geometry().local(xGlobal);
                const double factor = faceGeometry.integrationElement(xLocal) * faceQuad.weight(iqP);

                neumannData.evaluate(xGlobal, neumannValue);
                coarse_grid_baseSet.evaluateAll(xInCoarseLocal, phi_x_vec);
                for (auto i : DSC::valueRange(numLocalBaseFunctions)) {
                  assert((long long)i < (long long)phi_x_vec.size());
                  assert(iqP < localSolutionOnFace.size());
                  rhsLocalFunction[i] += factor * (neumannValue * (phi_x_vec[i] + localSolutionOnFace[iqP]));
                }
              }
            }
          }
        }

        const auto& localGeometry = localEntity.geometry();
        RangeType corrector_phi_x;
        for (size_t qP = 0; qP < localQuadrature.nop(); ++qP) {
          // local (barycentric) coordinates (with respect to entity)
          const auto& quadPoint = localQuadrature.point(qP);
          const auto quadPointGlobal = localGeometry.global(quadPoint);

          const double quadWeight = localQuadrature.weight(qP) * localGeometry.integrationElement(quadPoint);

          for (int coarseBF = 0; coarseBF < numLocalBaseFunctions; ++coarseBF) {
            JacobianRangeType diffusive_flux(0.0);

            // evaluate gradient of basis function
            const auto quadPointLocalInCoarse = coarseGeometry.local(quadPointGlobal);
            std::vector<JacobianRangeType> gradient_Phi_vec(numLocalBaseFunctions);
            coarse_grid_baseSet.jacobianAll(quadPointLocalInCoarse, gradient_Phi_vec);

            JacobianRangeType reconstructionGradPhi(gradient_Phi_vec[coarseBF]);

            if (specifier.simplexCoarseGrid()) {
              assert(localSolutions.size() == GridSelector::dimgrid + localSolutionManager.numBoundaryCorrectors());
              DUNE_THROW(NotImplemented, "Boundary values are not implemented for simplex grids yet!");
            } else {
              assert(localSolutions.size() == numLocalBaseFunctions + localSolutionManager.numBoundaryCorrectors());
              // local corrector for coarse base func
              corrector_phi_x = allLocalSolutionEvaluations[coarseBF][qP];
              // element part of boundary conditions
              JacobianRangeType directionOfFlux(0.0);
              //! @attention At this point we assume, that the quadrature points on the subgrid and hostgrid
              //! are the same (dirichletExtensionLF is a localfunction on the hostgrid, quadPoint stems from
              //! a quadrature on the subgrid)!!
              dirichletExtensionLF.jacobian(quadPoint, directionOfFlux);
              // add dirichlet-corrector
              directionOfFlux += allLocalSolutionJacobians[numLocalBaseFunctions + 1][qP];
              // subtract neumann-corrector
              // directionOfFlux -= allLocalSolutionJacobians[numLocalBaseFunctions][qP];

              diffusion.diffusiveFlux(quadPointGlobal, directionOfFlux, diffusive_flux);
              reconstructionGradPhi += allLocalSolutionJacobians[coarseBF][qP];
            }
            f.evaluate(quadPointGlobal, f_x);
            double val = quadWeight * (f_x * corrector_phi_x);
            rhsLocalFunction[coarseBF] += val;
            val = quadWeight * (diffusive_flux[0] * reconstructionGradPhi[0]);
            rhsLocalFunction[coarseBF] -= val;
          }
        }
      }
    }
  }

  // set dirichlet dofs to zero
  Dune::Multiscale::getConstraintsCoarse(rhsVector.space()).setValue(0.0, rhsVector);
}
<commit_msg>Rearranging loops to improve performance<commit_after>#include <config.h>
#include <assert.h>
#include <dune/common/exceptions.hh>
#include <dune/multiscale/problems/selector.hh>
#include <dune/stuff/common/ranges.hh>
#include <memory>

#include "dune/multiscale/common/traits.hh"
#include "dune/multiscale/common/dirichletconstraints.hh"
#include "dune/multiscale/msfem/msfem_grid_specifier.hh"
#include "dune/multiscale/msfem/localproblems/subgrid-list.hh"
#include "dune/multiscale/msfem/localproblems/localsolutionmanager.hh"
#include "righthandside_assembler.hh"

void Dune::Multiscale::RightHandSideAssembler::assemble(const Dune::Multiscale::CommonTraits::FirstSourceType &f, Dune::Multiscale::RightHandSideAssembler::DiscreteFunctionType &rhsVector) {
  rhsVector.clear();
  for (const auto& entity : rhsVector.space()) {
    const auto& geometry = entity.geometry();
    auto elementOfRHS = rhsVector.localFunction(entity);
    const auto baseSet = rhsVector.space().basisFunctionSet(entity);
    const auto quadrature = make_quadrature(entity, rhsVector.space(), quadratureOrder);
    const auto numDofs = elementOfRHS.numDofs();
    for (auto quadraturePoint : DSC::valueRange(quadrature.nop())) {
      // the return values:
      RangeType f_x;
      std::vector<RangeType> phi_x(numDofs);
      // to save: A \nabla PHI_H * \nabla phi_h;
      const auto det = geometry.integrationElement(quadrature.point(quadraturePoint));

      f.evaluate(geometry.global(quadrature.point(quadraturePoint)), f_x);
      baseSet.evaluateAll(quadrature[quadraturePoint], phi_x);

      for (int i = 0; i < numDofs; ++i) {
        elementOfRHS[i] += det * quadrature.weight(quadraturePoint) * (f_x * phi_x[i]);
      }
    }
  }
}

void Dune::Multiscale::RightHandSideAssembler::assemble(
    const Dune::Multiscale::CommonTraits::FirstSourceType &f,
    const Dune::Multiscale::CommonTraits::DiffusionType &A,
    const Dune::Multiscale::RightHandSideAssembler::DiscreteFunctionType &
        dirichlet_extension,
    const Dune::Multiscale::CommonTraits::NeumannBCType &neumann_bc,
    Dune::Multiscale::RightHandSideAssembler::DiscreteFunctionType &rhsVector) {
  rhsVector.clear();

  for (const auto& entity : rhsVector.space()) {

    const auto& geometry = entity.geometry();
    auto elementOfRHS = rhsVector.localFunction(entity);
    const auto baseSet = rhsVector.space().basisFunctionSet(entity);

    const int numDofs = elementOfRHS.numDofs();

    std::vector<RangeType> phi_x(numDofs);
    // gradient of base function and gradient of old_u_H
    std::vector<JacobianRangeType> grad_phi_x(numDofs);

    const auto loc_dirichlet_extension = dirichlet_extension.localFunction(entity);
    const auto quadrature = make_quadrature(entity, rhsVector.space(), quadratureOrder);

    const auto& lagrangePointSet = rhsVector.space().lagrangePointSet(entity);

    for (const auto& intersection : DSC::intersectionRange(rhsVector.space().gridPart(), entity)) {
      if (Problem::isNeumannBoundary(intersection)) {
        const auto face = intersection.indexInInside();
        const auto faceQuadrature = make_quadrature(intersection, rhsVector.space(), quadratureOrder);
        const auto numFaceQuadraturePoints = faceQuadrature.nop();

        for (auto faceQuadraturePoint : DSC::valueRange(numFaceQuadraturePoints)) {
          baseSet.evaluateAll(faceQuadrature[faceQuadraturePoint], phi_x);
          baseSet.jacobianAll(faceQuadrature[faceQuadraturePoint], grad_phi_x);

          const auto local_point_entity = faceQuadrature.point(faceQuadraturePoint);
          const auto global_point = geometry.global(local_point_entity);
          const auto local_point_face = intersection.geometry().local(global_point);

          RangeType neumann_value(0.0);
          neumann_bc.evaluate(global_point, neumann_value);

          const double face_weight = intersection.geometry().integrationElement(local_point_face) *
                                     faceQuadrature.weight(faceQuadraturePoint);

          for (const auto& lp : DSC::lagrangePointSetRange(lagrangePointSet, face)) {
            elementOfRHS[lp] += neumann_value * face_weight * phi_x[lp];
          }
        }
      }
    }

    // the return values:
    RangeType f_x;

    JacobianRangeType gradient_dirichlet_extension;
    JacobianRangeType diffusive_flux_in_gradient_dirichlet_extension;

    for (auto quadraturePoint : DSC::valueRange(quadrature.nop())) {
      // local (barycentric) coordinates (with respect to entity)
      const auto& local_point = quadrature.point(quadraturePoint);
      const auto global_point = geometry.global(local_point);

      const double weight = geometry.integrationElement(local_point) * quadrature.weight(quadraturePoint);
      // evaluate the Right Hand Side Function f at the current quadrature point and save its value in 'f_y':
      f.evaluate(global_point, f_x);
      // evaluate the current base function at the current quadrature point and save its value in 'z':
      baseSet.evaluateAll(quadrature[quadraturePoint], phi_x); // i = i'te Basisfunktion;
      // evaluate the gradient of the current base function at the current quadrature point and save its value in
      // 'returnGradient':
      baseSet.jacobianAll(quadrature[quadraturePoint], grad_phi_x);
      // get gradient of dirichlet extension:
      loc_dirichlet_extension.jacobian(quadrature[quadraturePoint], gradient_dirichlet_extension);
      A.diffusiveFlux(global_point, gradient_dirichlet_extension, diffusive_flux_in_gradient_dirichlet_extension);

      for (int i = 0; i < numDofs; ++i) {
        elementOfRHS[i] += weight * (f_x * phi_x[i]);
        elementOfRHS[i] -= weight * (diffusive_flux_in_gradient_dirichlet_extension[0] * grad_phi_x[i][0]);
      }
    }
  }
}

void Dune::Multiscale::RightHandSideAssembler::assemble_for_MsFEM_symmetric(const Dune::Multiscale::CommonTraits::FirstSourceType &f, Dune::Multiscale::MsFEM::MacroMicroGridSpecifier &specifier, Dune::Multiscale::MsFEM::SubGridList &subgrid_list, Dune::Multiscale::RightHandSideAssembler::DiscreteFunctionType &rhsVector) {

  // gather some problem data
  auto diffusionPtr = Problem::getDiffusion();
  const auto& diffusion = *diffusionPtr;
  auto neumannDataPtr = Problem::getNeumannData();
  const auto& neumannData = *neumannDataPtr;

  DiscreteFunctionType dirichletExtension("Dirichlet Extension", specifier.fineSpace());
  dirichletExtension.clear();
  Dune::Multiscale::projectDirichletValues(rhsVector.space(), dirichletExtension);

  // set rhsVector to zero:
  rhsVector.clear();
  const auto& coarseGridLeafIndexSet = specifier.coarseSpace().gridPart().grid().leafIndexSet();
  RangeType f_x;
  for (const auto& coarse_grid_entity : rhsVector.space()) {
    const auto coarseEntityIndex = coarseGridLeafIndexSet.index(coarse_grid_entity);

    const auto& coarseGeometry = coarse_grid_entity.geometry();
    auto rhsLocalFunction = rhsVector.localFunction(coarse_grid_entity);
    const auto numLocalBaseFunctions = rhsLocalFunction.numDofs();
    const auto& coarse_grid_baseSet = specifier.coarseSpace().basisFunctionSet(coarse_grid_entity);

    // --------- add standard contribution of right hand side -------------------------
    {
      const auto quadrature = make_quadrature(coarse_grid_entity, rhsVector.space(), quadratureOrder);
      std::vector<RangeType> phi_x_vec(numLocalBaseFunctions);
      const auto numQuadraturePoints = quadrature.nop();
      for (size_t quadraturePoint = 0; quadraturePoint < numQuadraturePoints; ++quadraturePoint) {
        const double det = coarseGeometry.integrationElement(quadrature.point(quadraturePoint));
        // evaluate the Right Hand Side Function f at the current quadrature point and save its value in 'f_y':
        f.evaluate(coarseGeometry.global(quadrature.point(quadraturePoint)), f_x);
        coarse_grid_baseSet.evaluateAll(quadrature[quadraturePoint], phi_x_vec);
        for (int i = 0; i < numLocalBaseFunctions; ++i) {
          rhsLocalFunction[i] += det * quadrature.weight(quadraturePoint) * (f_x * phi_x_vec[i]);
        }
      }
    }
    // ----------------------------------------------------------------------------------

    // --------- add corrector contribution of right hand side --------------------------
    // Load local solutions
    MsFEM::LocalSolutionManager localSolutionManager(coarse_grid_entity, subgrid_list, specifier);
    localSolutionManager.loadLocalSolutions();
    auto& localSolutions = localSolutionManager.getLocalSolutions();
    assert(localSolutions.size() > 0);

    // iterator for the micro grid ( grid for the reference element T_0 )
    const auto& subGrid = subgrid_list.getSubGrid(coarse_grid_entity);
    for (const auto& localEntity : DSC::viewRange(subGrid.leafView())) {
      const auto& hostCell = subGrid.getHostEntity<0>(localEntity);
      const auto enclosingCoarseCellIndex = subgrid_list.getEnclosingMacroCellIndex(hostCell);
      auto dirichletExtensionLF = dirichletExtension.localFunction(*hostCell);
      if (enclosingCoarseCellIndex == coarseEntityIndex) {
        // higher order quadrature, since A^{\epsilon} is highly variable
        const auto localQuadrature =
            make_quadrature(localEntity, localSolutionManager.getLocalDiscreteFunctionSpace());

        // evaluate all local solutions and their jacobians in all quadrature points
        std::vector<std::vector<RangeType>> allLocalSolutionEvaluations(
                                              localSolutions.size(), std::vector<RangeType>(localQuadrature.nop(), 0.0));
        std::vector<std::vector<JacobianRangeType>> allLocalSolutionJacobians(
                                                      localSolutions.size(), std::vector<JacobianRangeType>(localQuadrature.nop(), JacobianRangeType(0.0)));
        for (auto lsNum : DSC::valueRange(localSolutions.size())) {
          auto localFunction = localSolutions[lsNum]->localFunction(localEntity);
          // this evaluates the local solutions in all quadrature points...
          localFunction.evaluateQuadrature(localQuadrature, allLocalSolutionEvaluations[lsNum]);
          // while this automatically evaluates their jacobians.
          localFunction.evaluateQuadrature(localQuadrature, allLocalSolutionJacobians[lsNum]);

          const auto& subGridPart = localSolutionManager.getSubGridPart();
          for (const auto& intersection : DSC::intersectionRange(subGridPart.grid().leafView(), localEntity)) {
            if (Problem::isNeumannBoundary(intersection)) {
              const int orderOfIntegrand = (polynomialOrder - 1) + 2 * (polynomialOrder + 1);
              const int quadOrder = std::ceil((orderOfIntegrand + 1) / 2);
              // get type of face quadrature. Is done in this scope because Patricks methods use another type.
              const auto faceQuad = make_quadrature(intersection, localSolutions[lsNum]->space(), quadOrder);
              RangeType neumannValue(0.0);
              const auto numQuadPoints = faceQuad.nop();
              // loop over all quadrature points

              std::vector<RangeType> phi_x_vec(numLocalBaseFunctions);
              std::vector<RangeType> localSolutionOnFace(numLocalBaseFunctions);
              localFunction.evaluateQuadrature(faceQuad, localSolutionOnFace);

              for (unsigned int iqP = 0; iqP < numQuadPoints; ++iqP) {
                // get local coordinate of quadrature point
                const auto& xLocal = faceQuad.localPoint(iqP);
                const auto& faceGeometry = intersection.geometry();

                // the following does not work because subgrid does not implement geometryInInside()
                // const auto& insideGeometry    = intersection.geometryInInside();
                // const typename FaceQuadratureType::CoordinateType& xInInside = insideGeometry.global(xLocal);
                // therefore, we have to do stupid things:
                const auto& xGlobal = faceGeometry.global(xLocal);
                const auto& xInCoarseLocal = coarse_grid_entity.geometry().local(xGlobal);
                const double factor = faceGeometry.integrationElement(xLocal) * faceQuad.weight(iqP);

                neumannData.evaluate(xGlobal, neumannValue);
                coarse_grid_baseSet.evaluateAll(xInCoarseLocal, phi_x_vec);
                for (auto i : DSC::valueRange(numLocalBaseFunctions)) {
                  assert((long long)i < (long long)phi_x_vec.size());
                  assert(iqP < localSolutionOnFace.size());
                  rhsLocalFunction[i] += factor * (neumannValue * (phi_x_vec[i] + localSolutionOnFace[iqP]));
                }
              }
            }
          }
        }

        const auto& localGeometry = localEntity.geometry();
        RangeType corrector_phi_x;
        for (size_t qP = 0; qP < localQuadrature.nop(); ++qP) {
          // local (barycentric) coordinates (with respect to entity)
          const auto& quadPoint = localQuadrature.point(qP);
          const auto quadPointGlobal = localGeometry.global(quadPoint);

          const double quadWeight = localQuadrature.weight(qP) * localGeometry.integrationElement(quadPoint);

          // evaluate gradient of basis function
          const auto quadPointLocalInCoarse = coarseGeometry.local(quadPointGlobal);
          std::vector<JacobianRangeType> gradient_Phi_vec(numLocalBaseFunctions);
          coarse_grid_baseSet.jacobianAll(quadPointLocalInCoarse, gradient_Phi_vec);

          for (int coarseBF = 0; coarseBF < numLocalBaseFunctions; ++coarseBF) {
            JacobianRangeType diffusive_flux(0.0);

            JacobianRangeType reconstructionGradPhi(gradient_Phi_vec[coarseBF]);

            if (specifier.simplexCoarseGrid()) {
              assert(localSolutions.size() == GridSelector::dimgrid + localSolutionManager.numBoundaryCorrectors());
              DUNE_THROW(NotImplemented, "Boundary values are not implemented for simplex grids yet!");
            } else {
              assert(localSolutions.size() == numLocalBaseFunctions + localSolutionManager.numBoundaryCorrectors());
              // local corrector for coarse base func
              corrector_phi_x = allLocalSolutionEvaluations[coarseBF][qP];
              // element part of boundary conditions
              JacobianRangeType directionOfFlux(0.0);
              //! @attention At this point we assume, that the quadrature points on the subgrid and hostgrid
              //! are the same (dirichletExtensionLF is a localfunction on the hostgrid, quadPoint stems from
              //! a quadrature on the subgrid)!!
              dirichletExtensionLF.jacobian(quadPoint, directionOfFlux);
              // add dirichlet-corrector
              directionOfFlux += allLocalSolutionJacobians[numLocalBaseFunctions + 1][qP];
              // subtract neumann-corrector
              // directionOfFlux -= allLocalSolutionJacobians[numLocalBaseFunctions][qP];

              diffusion.diffusiveFlux(quadPointGlobal, directionOfFlux, diffusive_flux);
              reconstructionGradPhi += allLocalSolutionJacobians[coarseBF][qP];
            }
            f.evaluate(quadPointGlobal, f_x);
            double val = quadWeight * (f_x * corrector_phi_x);
            rhsLocalFunction[coarseBF] += val;
            val = quadWeight * (diffusive_flux[0] * reconstructionGradPhi[0]);
            rhsLocalFunction[coarseBF] -= val;
          }
        }
      }
    }
  }

  // set dirichlet dofs to zero
  Dune::Multiscale::getConstraintsCoarse(rhsVector.space()).setValue(0.0, rhsVector);
}
<|endoftext|>


<commit_before>#include "platform.h"
#include <stdlib.h>
#include <boost/filesystem.hpp>
#include <iostream>

#if defined(WIN32)
	#include <codecvt>
#elif define(__linux__)
	#include <unistd.h>
	#include <sys/reboot.h>
#endif

std::string getConfigDirectory()
{
    boost::filesystem::path path;
#ifdef _WIN32
#include <windows.h>
#include <shlobj.h>
    CHAR my_documents[MAX_PATH];
    SHGetFolderPath(NULL, CSIDL_PRESONAL, NULL, SHGFP_TYPE_CURRENT, my_documents);
    path = boost::filesystem::path(my_documents) / "EmulationStation";
#elif __APPLE__ && !defined(USE_XDG_OSX)
    const char* homePath = getenv("HOME");
    path = boost::filesystem::path(homePath);
    path /= "Library" / "Application Support" / "org.emulationstation.EmulationStation" ;
#else
    const char* envXdgConfig = getenv("XDG_CONFIG_HOME");
    if(envXdgConfig){
        path = boost::filesystem::path(envXdgConfig);
    } else {
        const char* homePath = getenv("HOME");
        path = boost::filesystem::path(homePath);
        path /= boost::filesystem::path(".config");
    }
    path /= boost::filesystem::path("emulationstation");
#endif
    return path.generic_string();
}

std::string getHomePath()
{
	std::string homePath;

	// this should give you something like "/home/YOUR_USERNAME" on Linux and "C:\Users\YOUR_USERNAME\" on Windows
	const char * envHome = getenv("HOME");
	if(envHome != nullptr)
	{
		homePath = envHome;
	}

#ifdef WIN32
	// but does not seem to work for Windows XP or Vista, so try something else
	if (homePath.empty()) {
		const char * envDir = getenv("HOMEDRIVE");
		const char * envPath = getenv("HOMEPATH");
		if (envDir != nullptr && envPath != nullptr) {
			homePath = envDir;
			homePath += envPath;

			for(unsigned int i = 0; i < homePath.length(); i++)
				if(homePath[i] == '\\')
					homePath[i] = '/';
		}
	}
#endif

	// convert path to generic directory seperators
	boost::filesystem::path genericPath(homePath);
	return genericPath.generic_string();
}

int runShutdownCommand()
{
#if defined(WIN32)
	return system("shutdown -s -t 0");
#elif defined(__linux__)
	sync();
	return reboot(RB_POWER_OFF);
#else
	return system("sudo shutdown -h now");
#endif
}

int runRestartCommand()
{
#if defined(WIN32)
	return system("shutdown -r -t 0");
#elif defined(__linux__)
	sync();
	return reboot(RB_AUTOBOOT);
#else
	return system("sudo shutdown -r now");
#endif
}

int runSystemCommand(const std::string& cmd_utf8)
{
#ifdef WIN32
	// on Windows we use _wsystem to support non-ASCII paths
	// which requires converting from utf8 to a wstring
	typedef std::codecvt_utf8<wchar_t> convert_type;
	std::wstring_convert<convert_type, wchar_t> converter;
	std::wstring wchar_str = converter.from_bytes(cmd_utf8);
	return _wsystem(wchar_str.c_str());
#else
	return system(cmd_utf8.c_str());
#endif
}
<commit_msg>Fixed Linux Build<commit_after>#include "platform.h"
#include <stdlib.h>
#include <boost/filesystem.hpp>
#include <iostream>

#if defined(WIN32)
	#include <codecvt>
#elif defined(__linux__)
	#include <unistd.h>
	#include <sys/reboot.h>
#endif

std::string getConfigDirectory()
{
    boost::filesystem::path path;
#ifdef _WIN32
#include <windows.h>
#include <shlobj.h>
    CHAR my_documents[MAX_PATH];
    SHGetFolderPath(NULL, CSIDL_PRESONAL, NULL, SHGFP_TYPE_CURRENT, my_documents);
    path = boost::filesystem::path(my_documents) / "EmulationStation";
#elif __APPLE__ && !defined(USE_XDG_OSX)
    const char* homePath = getenv("HOME");
    path = boost::filesystem::path(homePath);
    path /= "Library" / "Application Support" / "org.emulationstation.EmulationStation" ;
#else
    const char* envXdgConfig = getenv("XDG_CONFIG_HOME");
    if(envXdgConfig){
        path = boost::filesystem::path(envXdgConfig);
    } else {
        const char* homePath = getenv("HOME");
        path = boost::filesystem::path(homePath);
        path /= boost::filesystem::path(".config");
    }
    path /= boost::filesystem::path("emulationstation");
#endif
    return path.generic_string();
}

std::string getHomePath()
{
	std::string homePath;

	// this should give you something like "/home/YOUR_USERNAME" on Linux and "C:\Users\YOUR_USERNAME\" on Windows
	const char * envHome = getenv("HOME");
	if(envHome != nullptr)
	{
		homePath = envHome;
	}

#ifdef WIN32
	// but does not seem to work for Windows XP or Vista, so try something else
	if (homePath.empty()) {
		const char * envDir = getenv("HOMEDRIVE");
		const char * envPath = getenv("HOMEPATH");
		if (envDir != nullptr && envPath != nullptr) {
			homePath = envDir;
			homePath += envPath;

			for(unsigned int i = 0; i < homePath.length(); i++)
				if(homePath[i] == '\\')
					homePath[i] = '/';
		}
	}
#endif

	// convert path to generic directory seperators
	boost::filesystem::path genericPath(homePath);
	return genericPath.generic_string();
}

int runShutdownCommand()
{
#if defined(WIN32)
	return system("shutdown -s -t 0");
#elif defined(__linux__)
	sync();
	return reboot(RB_POWER_OFF);
#else
	return system("sudo shutdown -h now");
#endif
}

int runRestartCommand()
{
#if defined(WIN32)
	return system("shutdown -r -t 0");
#elif defined(__linux__)
	sync();
	return reboot(RB_AUTOBOOT);
#else
	return system("sudo shutdown -r now");
#endif
}

int runSystemCommand(const std::string& cmd_utf8)
{
#ifdef WIN32
	// on Windows we use _wsystem to support non-ASCII paths
	// which requires converting from utf8 to a wstring
	typedef std::codecvt_utf8<wchar_t> convert_type;
	std::wstring_convert<convert_type, wchar_t> converter;
	std::wstring wchar_str = converter.from_bytes(cmd_utf8);
	return _wsystem(wchar_str.c_str());
#else
	return system(cmd_utf8.c_str());
#endif
}
<|endoftext|>


<commit_before>#include <QGuiApplication>
#include <QQuickView>
#include <QQmlEngine>
#include <QQmlContext>
#include <QTimer>
#include <QPalette>
#include <QFontDatabase>
#include "Comms.h"
#include "Video_Decoder.h"
#include "QMLMenus.h"
#include "QMLVideoSurface.h"
#include "QMLTelemetry.h"

//#include "Menu_System.h"
//#include "Splash_Menu_Page.h"

//#include "Main_Menu_Page.h"

#include "utils/Clock.h"
#include "HAL.h"

namespace silk
{

int s_version_major = 1;
int s_version_minor = 0;

std::string s_program_path;

silk::HAL s_hal;

}

///////////////////////////////////////////////////////////////////////////////////////////////////

//This prints an "Assertion failed" message and aborts.
void __assert_fail(const char *__assertion, const char *__file, unsigned int __line, const char *__function)
{
    QASSERT_MSG(false, "assert: {}:{}: {}: {}", __file, __line, __function, __assertion);
}

///////////////////////////////////////////////////////////////////////////////////////////////////

void signal_callback_handler(int signum)
{
   printf("Caught signal %d\n", signum);
   silk::s_hal.shutdown();
   exit(signum);
}

///////////////////////////////////////////////////////////////////////////////////////////////////

int main(int argc, char *argv[])
{
    q::logging::add_logger(q::logging::Logger_uptr(new q::logging::Console_Logger()));
    q::logging::set_decorations(q::logging::Decorations(q::logging::Decoration::TIMESTAMP, q::logging::Decoration::LEVEL, q::logging::Decoration::TOPIC));

    //    boost::shared_ptr<asio::io_service::work> work(new asio::io_service::work(s_async_io_service));
    //    std::thread_group worker_threads;
    //    for(int x = 0; x < 4; ++x)
    //    {
    //        worker_threads.create_thread(boost::bind(&asio::io_service::run, &s_async_io_service));
    //    }

    signal(SIGHUP, signal_callback_handler);
    signal(SIGINT, signal_callback_handler);
    signal(SIGCONT, signal_callback_handler);
    signal(SIGTERM, signal_callback_handler);

    silk::s_program_path = argv[0];
    size_t off = silk::s_program_path.find_last_of('/');
    if (off != std::string::npos)
    {
        silk::s_program_path = silk::s_program_path.substr(0, off);
    }
    QLOGI("Program path: {}.", silk::s_program_path);

    silk::HAL& hal = silk::s_hal;
    ts::Result<void> result = hal.init();
    if (result != ts::success)
    {
        QLOGE("Cannot init hal: {}.", result.error().what());
        exit(1);
    }

    Q_INIT_RESOURCE(res);

    QGuiApplication app(argc, argv);

    QCoreApplication::setOrganizationName("Silkopter");
    QCoreApplication::setOrganizationDomain("silkopter.com");
    QCoreApplication::setApplicationName("Silkopter");

    QFontDatabase::addApplicationFont(":/fonts/Play-Bold.ttf");
    int id = QFontDatabase::addApplicationFont(":/fonts/Play-Regular.ttf");
    QString family = QFontDatabase::applicationFontFamilies(id).at(0);
    QFont font(family);
    QGuiApplication::setFont(font);

    app.setQuitOnLastWindowClosed(true);

    QPalette palette = app.palette();
    palette.setColor(QPalette::Window, QColor(53,53,53));
    palette.setColor(QPalette::WindowText, QColor(0xECF0F1));
    palette.setColor(QPalette::Base, QColor(25,25,25));
    palette.setColor(QPalette::AlternateBase, QColor(53,53,53));
    palette.setColor(QPalette::ToolTipBase, QColor(0xECF0F1));
    palette.setColor(QPalette::ToolTipText, QColor(0xECF0F1));
    palette.setColor(QPalette::Text, QColor(0xECF0F1));
    palette.setColor(QPalette::Button, QColor(53,53,53));
    palette.setColor(QPalette::ButtonText, QColor(0xECF0F1));
    palette.setColor(QPalette::BrightText, Qt::white);
    palette.setColor(QPalette::Link, QColor(42, 130, 218));

    palette.setColor(QPalette::Highlight, QColor(42, 130, 218));
    palette.setColor(QPalette::HighlightedText, Qt::black);

    app.setPalette(palette);

    QQuickView view;

    QMLMenus menus;
    menus.init(view);

    QMLTelemetry telemetry;

    qmlRegisterType<QMLTelemetry>("com.silk.Telemetry", 1, 0, "Telemetry");
    view.engine()->rootContext()->setContextProperty("s_telemetry", &telemetry);
    view.engine()->rootContext()->setContextProperty("s_menus", &menus);
    qmlRegisterType<QMLVideoSurface>("com.silk.VideoSurface", 0, 1, "VideoSurface");

    Video_Decoder decoder;

    size_t render_frames = 0;

    QObject::connect(&view, &QQuickView::frameSwapped, [&render_frames, &decoder]()
    {
        decoder.release_buffers();
        render_frames++;
    });

    QObject::connect(&view, &QQuickView::sceneGraphInitialized, [&decoder]()
    {
        decoder.init();
        QMLVideoSurface::init(decoder);
    });

    std::vector<uint8_t> video_data;
    math::vec2u16 resolution;
    QObject::connect(&view, &QQuickView::beforeRendering, [&video_data, &resolution, &decoder]()
    {
        decoder.decode_data(video_data.data(), video_data.size(), resolution);
        video_data.clear();
        QMLVideoSurface::setResolution(resolution);
    });

    QSurfaceFormat format = view.format();
    format.setAlphaBufferSize(0);
    format.setRedBufferSize(8);
    format.setGreenBufferSize(8);
    format.setBlueBufferSize(8);
    format.setSamples(1);
    format.setSwapBehavior(QSurfaceFormat::TripleBuffer);
    format.setSwapInterval(0);
    view.setFormat(format);

    view.setClearBeforeRendering(false);
    view.resize(800, 480);
    view.setResizeMode(QQuickView::SizeRootObjectToView);
    view.setPersistentOpenGLContext(true);
    view.create();
    view.show();

    menus.push("Splash.qml");

    hal.get_comms().get_video_streamer().on_data_received = [&video_data, &resolution](void const* data, size_t size, math::vec2u16 const& res)
    {
        size_t offset = video_data.size();
        video_data.resize(offset + size);
        memcpy(video_data.data() + offset, data, size);
        resolution = res;
    };

    q::Clock::time_point last_tp = q::Clock::now();
    size_t process_frames = 0;

    while (true)
    {
        hal.process();
        app.processEvents();

        telemetry.setData(hal.get_comms().get_multirotor_state(), silk::stream::IMultirotor_Commands::Value());

        process_frames++;
        if (q::Clock::now() - last_tp >= std::chrono::seconds(1))
        {
            last_tp = q::Clock::now();
            QLOGI("P FPS: {}, R FPS: {}", process_frames, render_frames);
            process_frames = 0;
            render_frames = 0;
        }

        //std::this_thread::sleep_for(std::chrono::microseconds(1));
    }

    hal.shutdown();

    return 0;
}
<commit_msg>Added HUD<commit_after>#include <QGuiApplication>
#include <QQuickView>
#include <QQmlEngine>
#include <QQmlContext>
#include <QTimer>
#include <QPalette>
#include <QFontDatabase>
#include "Comms.h"
#include "Video_Decoder.h"
#include "QMLMenus.h"
#include "QMLVideoSurface.h"
#include "QMLHUD.h"

//#include "Menu_System.h"
//#include "Splash_Menu_Page.h"

//#include "Main_Menu_Page.h"

#include "utils/Clock.h"
#include "HAL.h"

namespace silk
{

int s_version_major = 1;
int s_version_minor = 0;

std::string s_program_path;

silk::HAL s_hal;

}

///////////////////////////////////////////////////////////////////////////////////////////////////

//This prints an "Assertion failed" message and aborts.
void __assert_fail(const char *__assertion, const char *__file, unsigned int __line, const char *__function)
{
    QASSERT_MSG(false, "assert: {}:{}: {}: {}", __file, __line, __function, __assertion);
}

///////////////////////////////////////////////////////////////////////////////////////////////////

void signal_callback_handler(int signum)
{
   printf("Caught signal %d\n", signum);
   silk::s_hal.shutdown();
   exit(signum);
}

///////////////////////////////////////////////////////////////////////////////////////////////////

int main(int argc, char *argv[])
{
    q::logging::add_logger(q::logging::Logger_uptr(new q::logging::Console_Logger()));
    q::logging::set_decorations(q::logging::Decorations(q::logging::Decoration::TIMESTAMP, q::logging::Decoration::LEVEL, q::logging::Decoration::TOPIC));

    //    boost::shared_ptr<asio::io_service::work> work(new asio::io_service::work(s_async_io_service));
    //    std::thread_group worker_threads;
    //    for(int x = 0; x < 4; ++x)
    //    {
    //        worker_threads.create_thread(boost::bind(&asio::io_service::run, &s_async_io_service));
    //    }

    signal(SIGHUP, signal_callback_handler);
    signal(SIGINT, signal_callback_handler);
    signal(SIGCONT, signal_callback_handler);
    signal(SIGTERM, signal_callback_handler);

    silk::s_program_path = argv[0];
    size_t off = silk::s_program_path.find_last_of('/');
    if (off != std::string::npos)
    {
        silk::s_program_path = silk::s_program_path.substr(0, off);
    }
    QLOGI("Program path: {}.", silk::s_program_path);

    silk::HAL& hal = silk::s_hal;
    ts::Result<void> result = hal.init();
    if (result != ts::success)
    {
        QLOGE("Cannot init hal: {}.", result.error().what());
        exit(1);
    }

    Q_INIT_RESOURCE(res);

    QGuiApplication app(argc, argv);

    QCoreApplication::setOrganizationName("Silkopter");
    QCoreApplication::setOrganizationDomain("silkopter.com");
    QCoreApplication::setApplicationName("Silkopter");

    QFontDatabase::addApplicationFont(":/fonts/Play-Bold.ttf");
    int id = QFontDatabase::addApplicationFont(":/fonts/Play-Regular.ttf");
    QString family = QFontDatabase::applicationFontFamilies(id).at(0);
    QFont font(family);
    QGuiApplication::setFont(font);

    app.setQuitOnLastWindowClosed(true);

    QPalette palette = app.palette();
    palette.setColor(QPalette::Window, QColor(53,53,53));
    palette.setColor(QPalette::WindowText, QColor(0xECF0F1));
    palette.setColor(QPalette::Base, QColor(25,25,25));
    palette.setColor(QPalette::AlternateBase, QColor(53,53,53));
    palette.setColor(QPalette::ToolTipBase, QColor(0xECF0F1));
    palette.setColor(QPalette::ToolTipText, QColor(0xECF0F1));
    palette.setColor(QPalette::Text, QColor(0xECF0F1));
    palette.setColor(QPalette::Button, QColor(53,53,53));
    palette.setColor(QPalette::ButtonText, QColor(0xECF0F1));
    palette.setColor(QPalette::BrightText, Qt::white);
    palette.setColor(QPalette::Link, QColor(42, 130, 218));

    palette.setColor(QPalette::Highlight, QColor(42, 130, 218));
    palette.setColor(QPalette::HighlightedText, Qt::black);

    app.setPalette(palette);

    QQuickView view;

    QMLMenus menus;
    menus.init(view);

    QMLHUD hud;
    hud.init(hal);

    qmlRegisterType<QMLHUD>("com.silk.HUD", 1, 0, "HUD");
    view.engine()->rootContext()->setContextProperty("s_hud", &hud);
    view.engine()->rootContext()->setContextProperty("s_menus", &menus);
    qmlRegisterType<QMLVideoSurface>("com.silk.VideoSurface", 0, 1, "VideoSurface");

    Video_Decoder decoder;

    size_t render_frames = 0;

    q::Clock::time_point last_swapped_tp = q::Clock::now();
    QObject::connect(&view, &QQuickView::frameSwapped, [&render_frames, &decoder, &last_swapped_tp]()
    {
//        std::chrono::duration<float> dt = q::Clock::now() - last_swapped_tp;
//        last_swapped_tp = q::Clock::now();
//        QLOGI("Frame DT: {}", dt.count());

        decoder.release_buffers();
        render_frames++;
    });

    QObject::connect(&view, &QQuickView::sceneGraphInitialized, [&decoder]()
    {
        decoder.init();
        QMLVideoSurface::init(decoder);
    });

    std::vector<uint8_t> video_data;
    math::vec2u16 resolution;
    QObject::connect(&view, &QQuickView::beforeRendering, [&video_data, &resolution, &decoder]()
    {
        decoder.decode_data(video_data.data(), video_data.size(), resolution);
        video_data.clear();
        QMLVideoSurface::setResolution(resolution);
    });

    QSurfaceFormat format = view.format();
    format.setAlphaBufferSize(0);
    format.setRedBufferSize(8);
    format.setGreenBufferSize(8);
    format.setBlueBufferSize(8);
    format.setSamples(1);
    format.setSwapBehavior(QSurfaceFormat::TripleBuffer);
    //format.setSwapInterval(0);
    view.setFormat(format);

    view.setClearBeforeRendering(false);
    view.resize(800, 480);
    view.setResizeMode(QQuickView::SizeRootObjectToView);
    view.setPersistentOpenGLContext(true);
    view.create();
    view.show();

    menus.push("HUD.qml");

    hal.get_comms().get_video_streamer().on_data_received = [&video_data, &resolution](void const* data, size_t size, math::vec2u16 const& res)
    {
        size_t offset = video_data.size();
        video_data.resize(offset + size);
        memcpy(video_data.data() + offset, data, size);
        resolution = res;
    };

    q::Clock::time_point last_tp = q::Clock::now();
    size_t process_frames = 0;

    while (true)
    {
        hal.process();
        hud.process();
        app.processEvents();

        process_frames++;
        if (q::Clock::now() - last_tp >= std::chrono::seconds(1))
        {
            last_tp = q::Clock::now();
            QLOGI("P FPS: {}, R FPS: {}", process_frames, render_frames);
            process_frames = 0;
            render_frames = 0;
        }

        //std::this_thread::sleep_for(std::chrono::microseconds(1));
    }

    hal.shutdown();

    return 0;
}
<|endoftext|>