<commit_before>#include <libmesh/dirichlet_boundaries.h>
#include <libmesh/dof_map.h>
#include <libmesh/elem.h>
#include <libmesh/equation_systems.h>
#include <libmesh/exodusII_io.h>
#include <libmesh/function_base.h>
#include <libmesh/linear_implicit_system.h>
#include <libmesh/mesh.h>
#include <libmesh/numeric_vector.h>
#include <libmesh/periodic_boundary.h>
#include <libmesh/quadrature_gauss.h>
#include <libmesh/sparse_matrix.h>
#include <libmesh/wrapped_function.h>

#include "test_comm.h"
#include "libmesh_cppunit.h"

using namespace libMesh;

Number quadratic_solution (const Point& p,
                           const Parameters&,
                           const std::string&,
                           const std::string&)
{
  const Real & y = LIBMESH_DIM > 1 ? p(1) : 0;

  // Discontinuity at y=1 from the forcing function there.
  // Periodic on -3 < y < 2
  return (y > 1) ? (y-3)*(y-3) : (y+1)*(y+1);
}

struct PeriodicQuadFunction : public FunctionBase<Number>
{
  PeriodicQuadFunction() = default;

  virtual std::unique_ptr<FunctionBase<Number>> clone () const
  { return libmesh_make_unique<PeriodicQuadFunction>(); }

  // We only really need the vector-valued output for projections
  virtual Number operator() (const Point &,
                             const Real /*time*/ = 0.) override
  { libmesh_error(); }

  virtual void operator() (const Point & p,
                           const Real time,
                           DenseVector<Number> & output) override
  {
    libmesh_assert_equal_to(output.size(), 1);
    Parameters params;
    output(0) = quadratic_solution(p, params, "", "");
  }

  Number component (unsigned int i,
                    const Point & p,
                    Real /* time */) override
  {
    Parameters params;
    switch (i) {
    case 0:
      return quadratic_solution(p, params, "", "");
    default:
      libmesh_error();
    }
    return 0;
  }
};

void periodic_bc_test_poisson(EquationSystems& es,
                              const std::string& system_name)
{
  const MeshBase& mesh = es.get_mesh();
  LinearImplicitSystem& system = es.get_system<LinearImplicitSystem>("PBCSys");
  const DofMap& dof_map = system.get_dof_map();

  // Interior FE to integrate smooth part of poisson problem
  FEType fe_type = dof_map.variable_type(0);
  std::unique_ptr<FEBase> fe (FEBase::build(2, fe_type));
  QGauss qrule (2, fe_type.default_quadrature_order());
  fe->attach_quadrature_rule(&qrule);

  const std::vector<Real> & JxW = fe->get_JxW();
  const std::vector<std::vector<Real>> & phi = fe->get_phi();
  const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();

  // Face FE to integrate delta function part of forcing
  std::unique_ptr<FEBase> fe_face (FEBase::build(2, fe_type));
  QGauss qface (1, fe_type.default_quadrature_order());
  fe_face->attach_quadrature_rule(&qface);

  const std::vector<Real> & JxW_face = fe_face->get_JxW();
  const std::vector<std::vector<Real>> & phi_face = fe_face->get_phi();
  std::unique_ptr<const Elem> elem_side;

  DenseMatrix<Number> Ke;
  DenseVector<Number> Fe;

  std::vector<dof_id_type> dof_indices;

  for (const Elem * elem : mesh.active_local_element_ptr_range())
    {
      dof_map.dof_indices (elem, dof_indices);
      const unsigned int n_dofs = dof_indices.size();

      Ke.resize (n_dofs, n_dofs);
      Fe.resize (n_dofs);

      fe->reinit (elem);

      // Integrate the poisson problem over the element interior, where we have
      // a nice f=2 forcing function aside from the discontinuity
      for (unsigned int qp=0; qp<qrule.n_points(); qp++)
        {
          for (unsigned int i=0; i != n_dofs; i++)
            {
              for (unsigned int j=0; j != n_dofs; j++)
                Ke(i,j) += -JxW[qp]*(dphi[i][qp]*dphi[j][qp]);

              Fe(i) += JxW[qp]*phi[i][qp]*2;
            }
        }

      for(unsigned int s=0; s != elem->n_sides(); ++s)
      {
        elem->build_side_ptr(elem_side, s);
        Point centroid = elem_side->centroid();
        if (std::abs(centroid(1) - 1) < TOLERANCE)
          {
            fe_face->reinit(elem, s);

            for (unsigned int qp=0; qp<qface.n_points(); qp++)
              {
                // delta function divided by 2 since we hit it from
                // both sides
                for (unsigned int i=0; i != n_dofs; i++)
                  Fe(i) += JxW_face[qp]*phi_face[i][qp]*(-4);
              }
          }
      }

      dof_map.heterogenously_constrain_element_matrix_and_vector(Ke, Fe, dof_indices);
      system.matrix->add_matrix (Ke, dof_indices);
      system.rhs->add_vector    (Fe, dof_indices);
    }

  system.rhs->close();
  system.matrix->close();
}

const boundary_id_type top_id    = 50;
const boundary_id_type bottom_id = 60;
const boundary_id_type side_id   = 70;

class PeriodicBCTest : public CppUnit::TestCase {
public:
  CPPUNIT_TEST_SUITE( PeriodicBCTest );

#if LIBMESH_DIM > 1
#if defined(LIBMESH_HAVE_SOLVER) && defined(LIBMESH_HAVE_EXODUS_API)
  CPPUNIT_TEST( testPeriodicLagrange2 );
#endif
#endif // LIBMESH_DIM > 1

  CPPUNIT_TEST_SUITE_END();

private:

  void testPeriodicBC (FEType fe_type)
  {
    Mesh mesh(*TestCommWorld);
    BoundaryInfo & boundary = mesh.get_boundary_info();

    EquationSystems es(mesh);
    LinearImplicitSystem &sys =
      es.add_system<LinearImplicitSystem> ("PBCSys");

    // We need to change around BCIDs and set up the periodic BC first
    mesh.allow_remote_element_removal(false);

    mesh.read("meshes/shark_tooth_tri6.xda.gz");

    // Add some BCIDs on top and bottom for our periodic boundary
    for (const Elem * elem : mesh.active_element_ptr_range())
      {
        for (unsigned int s=0; s != 3; ++s)
          if (!elem->neighbor_ptr(s))
            {
              unsigned v2 = (s+1)%3;
              // Left-running edges are on bottom, because this xda
              // has a flipped mesh
              if (elem->point(s)(0) - elem->point(v2)(0) < -.1)
                boundary.add_side(elem, s, top_id);

              // Right-running edges are on top
              else if (elem->point(s)(0) - elem->point(v2)(0) > .1)
                boundary.add_side(elem, s, bottom_id);

              // Vertical edges are Dirichlet
              else
                boundary.add_side(elem, s, side_id);
            }
      }

    PeriodicBoundary vert(RealVectorValue(0., 4.0));
    vert.myboundary = bottom_id;
    vert.pairedboundary = top_id;
    sys.get_dof_map().add_periodic_boundary(vert);

    // Okay, *now* the mesh knows to save periodic neighbors
    mesh.allow_remote_element_removal(true);
    mesh.delete_remote_elements();

    const unsigned int u_var = sys.add_variable("u", fe_type);
    sys.attach_assemble_function (periodic_bc_test_poisson);

    std::set<boundary_id_type> side_bdy { side_id };
    std::vector<unsigned int> all_vars (1, u_var);
    WrappedFunction<Number> exact_val(sys, quadratic_solution);
    DirichletBoundary exact_bc(side_bdy, all_vars, exact_val);
    sys.get_dof_map().add_dirichlet_boundary(exact_bc);

    es.init();

    sys.solve();

    ExodusII_IO(mesh).write_equation_systems("periodic.e", es);

    Parameters params;

    for (Real x = 0.1; x < 10; x += 0.2)
      for (Real ya = -2.9; ya < 1; ya += 0.2)
        {
          // Integrate the sharktooth shape
          const Real offset = 1-std::abs(std::fmod(x,2)-1);
          const Real y = ya + offset;
          Point p{x,y};
          const Number exact = quadratic_solution(p,params,"","");
          const Number approx = sys.point_value(0,p);
          LIBMESH_ASSERT_FP_EQUAL(libmesh_real(exact),
                                  libmesh_real(approx),
                                  TOLERANCE*TOLERANCE*10);
        }
  }

  void testPeriodicLagrange2() { testPeriodicBC(FEType(SECOND, LAGRANGE)); }
};

CPPUNIT_TEST_SUITE_REGISTRATION( PeriodicBCTest );
<commit_msg>Don't try to open gz meshes w/o gzstream support<commit_after>#include <libmesh/dirichlet_boundaries.h>
#include <libmesh/dof_map.h>
#include <libmesh/elem.h>
#include <libmesh/equation_systems.h>
#include <libmesh/exodusII_io.h>
#include <libmesh/function_base.h>
#include <libmesh/linear_implicit_system.h>
#include <libmesh/mesh.h>
#include <libmesh/numeric_vector.h>
#include <libmesh/periodic_boundary.h>
#include <libmesh/quadrature_gauss.h>
#include <libmesh/sparse_matrix.h>
#include <libmesh/wrapped_function.h>

#include "test_comm.h"
#include "libmesh_cppunit.h"

using namespace libMesh;

Number quadratic_solution (const Point& p,
                           const Parameters&,
                           const std::string&,
                           const std::string&)
{
  const Real & y = LIBMESH_DIM > 1 ? p(1) : 0;

  // Discontinuity at y=1 from the forcing function there.
  // Periodic on -3 < y < 2
  return (y > 1) ? (y-3)*(y-3) : (y+1)*(y+1);
}

struct PeriodicQuadFunction : public FunctionBase<Number>
{
  PeriodicQuadFunction() = default;

  virtual std::unique_ptr<FunctionBase<Number>> clone () const
  { return libmesh_make_unique<PeriodicQuadFunction>(); }

  // We only really need the vector-valued output for projections
  virtual Number operator() (const Point &,
                             const Real /*time*/ = 0.) override
  { libmesh_error(); }

  virtual void operator() (const Point & p,
                           const Real time,
                           DenseVector<Number> & output) override
  {
    libmesh_assert_equal_to(output.size(), 1);
    Parameters params;
    output(0) = quadratic_solution(p, params, "", "");
  }

  Number component (unsigned int i,
                    const Point & p,
                    Real /* time */) override
  {
    Parameters params;
    switch (i) {
    case 0:
      return quadratic_solution(p, params, "", "");
    default:
      libmesh_error();
    }
    return 0;
  }
};

void periodic_bc_test_poisson(EquationSystems& es,
                              const std::string& system_name)
{
  const MeshBase& mesh = es.get_mesh();
  LinearImplicitSystem& system = es.get_system<LinearImplicitSystem>("PBCSys");
  const DofMap& dof_map = system.get_dof_map();

  // Interior FE to integrate smooth part of poisson problem
  FEType fe_type = dof_map.variable_type(0);
  std::unique_ptr<FEBase> fe (FEBase::build(2, fe_type));
  QGauss qrule (2, fe_type.default_quadrature_order());
  fe->attach_quadrature_rule(&qrule);

  const std::vector<Real> & JxW = fe->get_JxW();
  const std::vector<std::vector<Real>> & phi = fe->get_phi();
  const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();

  // Face FE to integrate delta function part of forcing
  std::unique_ptr<FEBase> fe_face (FEBase::build(2, fe_type));
  QGauss qface (1, fe_type.default_quadrature_order());
  fe_face->attach_quadrature_rule(&qface);

  const std::vector<Real> & JxW_face = fe_face->get_JxW();
  const std::vector<std::vector<Real>> & phi_face = fe_face->get_phi();
  std::unique_ptr<const Elem> elem_side;

  DenseMatrix<Number> Ke;
  DenseVector<Number> Fe;

  std::vector<dof_id_type> dof_indices;

  for (const Elem * elem : mesh.active_local_element_ptr_range())
    {
      dof_map.dof_indices (elem, dof_indices);
      const unsigned int n_dofs = dof_indices.size();

      Ke.resize (n_dofs, n_dofs);
      Fe.resize (n_dofs);

      fe->reinit (elem);

      // Integrate the poisson problem over the element interior, where we have
      // a nice f=2 forcing function aside from the discontinuity
      for (unsigned int qp=0; qp<qrule.n_points(); qp++)
        {
          for (unsigned int i=0; i != n_dofs; i++)
            {
              for (unsigned int j=0; j != n_dofs; j++)
                Ke(i,j) += -JxW[qp]*(dphi[i][qp]*dphi[j][qp]);

              Fe(i) += JxW[qp]*phi[i][qp]*2;
            }
        }

      for(unsigned int s=0; s != elem->n_sides(); ++s)
      {
        elem->build_side_ptr(elem_side, s);
        Point centroid = elem_side->centroid();
        if (std::abs(centroid(1) - 1) < TOLERANCE)
          {
            fe_face->reinit(elem, s);

            for (unsigned int qp=0; qp<qface.n_points(); qp++)
              {
                // delta function divided by 2 since we hit it from
                // both sides
                for (unsigned int i=0; i != n_dofs; i++)
                  Fe(i) += JxW_face[qp]*phi_face[i][qp]*(-4);
              }
          }
      }

      dof_map.heterogenously_constrain_element_matrix_and_vector(Ke, Fe, dof_indices);
      system.matrix->add_matrix (Ke, dof_indices);
      system.rhs->add_vector    (Fe, dof_indices);
    }

  system.rhs->close();
  system.matrix->close();
}

const boundary_id_type top_id    = 50;
const boundary_id_type bottom_id = 60;
const boundary_id_type side_id   = 70;

class PeriodicBCTest : public CppUnit::TestCase {
public:
  CPPUNIT_TEST_SUITE( PeriodicBCTest );

#if LIBMESH_DIM > 1
#if defined(LIBMESH_HAVE_SOLVER) && defined(LIBMESH_HAVE_EXODUS_API) && defined(LIBMESH_HAVE_GZSTREAM)
  CPPUNIT_TEST( testPeriodicLagrange2 );
#endif
#endif // LIBMESH_DIM > 1

  CPPUNIT_TEST_SUITE_END();

private:

  void testPeriodicBC (FEType fe_type)
  {
    Mesh mesh(*TestCommWorld);
    BoundaryInfo & boundary = mesh.get_boundary_info();

    EquationSystems es(mesh);
    LinearImplicitSystem &sys =
      es.add_system<LinearImplicitSystem> ("PBCSys");

    // We need to change around BCIDs and set up the periodic BC first
    mesh.allow_remote_element_removal(false);

    mesh.read("meshes/shark_tooth_tri6.xda.gz");

    // Add some BCIDs on top and bottom for our periodic boundary
    for (const Elem * elem : mesh.active_element_ptr_range())
      {
        for (unsigned int s=0; s != 3; ++s)
          if (!elem->neighbor_ptr(s))
            {
              unsigned v2 = (s+1)%3;
              // Left-running edges are on bottom, because this xda
              // has a flipped mesh
              if (elem->point(s)(0) - elem->point(v2)(0) < -.1)
                boundary.add_side(elem, s, top_id);

              // Right-running edges are on top
              else if (elem->point(s)(0) - elem->point(v2)(0) > .1)
                boundary.add_side(elem, s, bottom_id);

              // Vertical edges are Dirichlet
              else
                boundary.add_side(elem, s, side_id);
            }
      }

    PeriodicBoundary vert(RealVectorValue(0., 4.0));
    vert.myboundary = bottom_id;
    vert.pairedboundary = top_id;
    sys.get_dof_map().add_periodic_boundary(vert);

    // Okay, *now* the mesh knows to save periodic neighbors
    mesh.allow_remote_element_removal(true);
    mesh.delete_remote_elements();

    const unsigned int u_var = sys.add_variable("u", fe_type);
    sys.attach_assemble_function (periodic_bc_test_poisson);

    std::set<boundary_id_type> side_bdy { side_id };
    std::vector<unsigned int> all_vars (1, u_var);
    WrappedFunction<Number> exact_val(sys, quadratic_solution);
    DirichletBoundary exact_bc(side_bdy, all_vars, exact_val);
    sys.get_dof_map().add_dirichlet_boundary(exact_bc);

    es.init();

    sys.solve();

    ExodusII_IO(mesh).write_equation_systems("periodic.e", es);

    Parameters params;

    for (Real x = 0.1; x < 10; x += 0.2)
      for (Real ya = -2.9; ya < 1; ya += 0.2)
        {
          // Integrate the sharktooth shape
          const Real offset = 1-std::abs(std::fmod(x,2)-1);
          const Real y = ya + offset;
          Point p{x,y};
          const Number exact = quadratic_solution(p,params,"","");
          const Number approx = sys.point_value(0,p);
          LIBMESH_ASSERT_FP_EQUAL(libmesh_real(exact),
                                  libmesh_real(approx),
                                  TOLERANCE*TOLERANCE*10);
        }
  }

  void testPeriodicLagrange2() { testPeriodicBC(FEType(SECOND, LAGRANGE)); }
};

CPPUNIT_TEST_SUITE_REGISTRATION( PeriodicBCTest );
<|endoftext|>


<commit_before> /*
* Copyright (C) 2007-2013 German Aerospace Center (DLR/SC)
*
* Created: 2013-05-28 Martin Siggel <Martin.Siggel@dlr.de>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "test.h"
#include "tigl.h"

#include "CCPACSConfigurationManager.h"
#include "CCPACSWing.h"
#include "CCPACSWingCell.h"
#include "CCPACSWingComponentSegment.h"
#include "CCPACSWingRibsDefinition.h"
#include "CCPACSWingRibsPositioning.h"
#include "CCPACSWingSegment.h"

using namespace tigl;

typedef std::pair<double, double> DP;

/******************************************************************************/

class WingCellSpar : public ::testing::Test
{
protected:
    static void SetUpTestCase()
    {
        const char* filename = "TestData/cell_test_spars.xml";
        ReturnCode tixiRet;
        TiglReturnCode tiglRet;

        tiglHandle = -1;
        tixiHandle = -1;

        tixiRet = tixiOpenDocument(filename, &tixiHandle);
        ASSERT_EQ(SUCCESS, tixiRet);
        tiglRet = tiglOpenCPACSConfiguration(tixiHandle, "model", &tiglHandle);
        ASSERT_EQ(TIGL_SUCCESS, tiglRet);
    }

    static void TearDownTestCase()
    {
        ASSERT_EQ(TIGL_SUCCESS, tiglCloseCPACSConfiguration(tiglHandle));
        ASSERT_EQ(SUCCESS, tixiCloseDocument(tixiHandle));
        tiglHandle = -1;
        tixiHandle = -1;
    }

    void SetUp() OVERRIDE {}
    void TearDown() OVERRIDE {}

    static TixiDocumentHandle           tixiHandle;
    static TiglCPACSConfigurationHandle tiglHandle;
};

TixiDocumentHandle WingCellSpar::tixiHandle = 0;
TiglCPACSConfigurationHandle WingCellSpar::tiglHandle = 0;

class WingCellRibSpar : public ::testing::Test
{
protected:
    static void SetUpTestCase()
    {
        const char* filename = "TestData/cell_rib_spar_test.xml";
        ReturnCode tixiRet;
        TiglReturnCode tiglRet;

        tiglHandle = -1;
        tixiHandle = -1;

        tixiRet = tixiOpenDocument(filename, &tixiHandle);
        ASSERT_EQ(SUCCESS, tixiRet);
        tiglRet = tiglOpenCPACSConfiguration(tixiHandle, "model", &tiglHandle);
        ASSERT_EQ(TIGL_SUCCESS, tiglRet);
    }

    static void TearDownTestCase()
    {
        ASSERT_EQ(TIGL_SUCCESS, tiglCloseCPACSConfiguration(tiglHandle));
        ASSERT_EQ(SUCCESS, tixiCloseDocument(tixiHandle));
        tiglHandle = -1;
        tixiHandle = -1;
    }

    void SetUp() OVERRIDE {}
    void TearDown() OVERRIDE {}

    static TixiDocumentHandle           tixiHandle;
    static TiglCPACSConfigurationHandle tiglHandle;
};

TixiDocumentHandle WingCellRibSpar::tixiHandle = 0;
TiglCPACSConfigurationHandle WingCellRibSpar::tiglHandle = 0;

/******************************************************************************/

TEST(WingCell, IsInner)
{
    tigl::CCPACSWingCell cell(NULL, NULL);
    cell.SetLeadingEdgeInnerPoint (0,0);
    cell.SetLeadingEdgeOuterPoint (1,0);
    cell.SetTrailingEdgeInnerPoint(0,1);
    cell.SetTrailingEdgeOuterPoint(1,1);

    // test inner lying points
    ASSERT_TRUE(cell.IsInside(0.5, 0.5));
    ASSERT_TRUE(cell.IsInside(0.2, 0.0));
    ASSERT_TRUE(cell.IsInside(0.1, 0.9));

    // test points on border
    ASSERT_TRUE(cell.IsInside(0.5, 0.0));
    ASSERT_TRUE(cell.IsInside(1.0, 0.5));
    ASSERT_TRUE(cell.IsInside(0.5, 1.0));
    ASSERT_TRUE(cell.IsInside(0.0, 0.5));

    // test points on corners
    ASSERT_TRUE(cell.IsInside(0.0, 0.0));
    ASSERT_TRUE(cell.IsInside(1.0, 0.0));
    ASSERT_TRUE(cell.IsInside(1.0, 1.0));
    ASSERT_TRUE(cell.IsInside(0.0, 1.0));

    ASSERT_FALSE(cell.IsInside(0.3, -0.4));
    ASSERT_FALSE(cell.IsInside(1.3, -0.2));
    ASSERT_FALSE(cell.IsInside(1.2, 0.5));
    ASSERT_FALSE(cell.IsInside(1.1, 1.3));
    ASSERT_FALSE(cell.IsInside(0.5, 1.6));
    ASSERT_FALSE(cell.IsInside(-0.2, 1.2));
    ASSERT_FALSE(cell.IsInside(-0.1, 0.3));
    ASSERT_FALSE(cell.IsInside(-0.2, -0.5));
}

TEST(WingCell, IsInner_NonConvex)
{
    tigl::CCPACSWingCell cell(NULL, NULL);
    cell.SetLeadingEdgeInnerPoint (0,0);
    cell.SetLeadingEdgeOuterPoint (1,0);
    cell.SetTrailingEdgeInnerPoint(0,1);
    cell.SetTrailingEdgeOuterPoint(0.3, 0.3);

    ASSERT_TRUE(cell.IsInside(0.3, 0.2));
    ASSERT_TRUE(cell.IsInside(0.2, 0.3));

    ASSERT_FALSE(cell.IsInside(0.4, 0.3));
    ASSERT_FALSE(cell.IsInside(0.4, 0.4));
    ASSERT_FALSE(cell.IsInside(0.3, 0.4));
    ASSERT_FALSE(cell.IsInside(1.0, 1.0));
}

TEST(WingCell, IsConvex)
{
    tigl::CCPACSWingCell cell(NULL, NULL);
    cell.SetLeadingEdgeInnerPoint (0,0);
    cell.SetLeadingEdgeOuterPoint (1,0);
    cell.SetTrailingEdgeInnerPoint(0,1);
    cell.SetTrailingEdgeOuterPoint(1,1);

    ASSERT_TRUE(cell.IsConvex());

    cell.SetTrailingEdgeOuterPoint(0.3, 0.3);
    ASSERT_FALSE(cell.IsConvex());

    cell.SetTrailingEdgeOuterPoint(0.499, 0.4999);
    ASSERT_FALSE(cell.IsConvex());

    cell.SetTrailingEdgeOuterPoint(0.5001, 0.5001);
    ASSERT_TRUE(cell.IsConvex());

    cell.SetTrailingEdgeOuterPoint(0.5, 0.5);
    ASSERT_TRUE(cell.IsConvex());
}

TEST(WingCell, area)
{
    WingCellInternal::Point2D p1, p2, p3;
    p1.x = 1.; p1.y = 1.;
    p2.x = 2.; p2.y = 1.;
    p3.x = 1.7; p3.y = 2.;

    ASSERT_NEAR(0.5, WingCellInternal::area(p1,p2,p3), 1e-7);
    ASSERT_NEAR(0.5, WingCellInternal::area(p2,p3,p1), 1e-7);
    ASSERT_NEAR(0.5, WingCellInternal::area(p3,p1,p2), 1e-7);
}

TEST_F(WingCellSpar, sparCellXsi) {
    // See: cell_test_spars.png for placement of cells

    const std::pair<double, double> arr[] = { DP(0.2, 0.25), DP(0.35, 0.4), DP(0.3, 0.43), DP(0.275, 0.4), DP(0.47, 0.4), DP(0.5, 0.3) };
    std::vector< std::pair<double, double> > expectedXsis(arr, arr + sizeof(arr) / sizeof(arr[0]));

    // get Component Segment
    tigl::CCPACSConfigurationManager & manager = tigl::CCPACSConfigurationManager::GetInstance();
    tigl::CCPACSConfiguration & config = manager.GetConfiguration(tiglHandle);
    tigl::CCPACSWing& wing = config.GetWing(1);
    tigl::CCPACSWingComponentSegment& componentSegment = static_cast<tigl::CCPACSWingComponentSegment&>(wing.GetComponentSegment(1));

    int cellIndex = 1;
    std::vector< std::pair<double, double> >::const_iterator it;
    for (it = expectedXsis.begin(); it != expectedXsis.end(); ++it) {
        double xsi1Exp = it->first;
        double xsi2Exp = it->second;

        tigl::CCPACSWingCell& cell = componentSegment.GetStructure()->GetUpperShell().GetCell(cellIndex++);
        double xsi1, xsi2, dummy;
        cell.GetLeadingEdgeInnerPoint(&dummy, &xsi1);
        cell.GetLeadingEdgeOuterPoint(&dummy, &xsi2);
        ASSERT_NEAR(xsi1, xsi1Exp, 1e-7);
        ASSERT_NEAR(xsi2, xsi2Exp, 1e-7);
    }
}

namespace {
    void checkCellEtaXsis(const tigl::CCPACSWingCell& cell, const std::vector< std::pair<double, double> >& expectedEtaXsi, double precision = 1e-7) {
        double eta, xsi;
        int etaXsiIndex = 0;
        cell.GetLeadingEdgeInnerPoint(&eta, &xsi);
        ASSERT_NEAR(eta, expectedEtaXsi[etaXsiIndex].first, precision);
        ASSERT_NEAR(xsi, expectedEtaXsi[etaXsiIndex].second, precision);
        ++etaXsiIndex;
        cell.GetLeadingEdgeOuterPoint(&eta, &xsi);
        ASSERT_NEAR(eta, expectedEtaXsi[etaXsiIndex].first, precision);
        ASSERT_NEAR(xsi, expectedEtaXsi[etaXsiIndex].second, precision);
        ++etaXsiIndex;
        cell.GetTrailingEdgeInnerPoint(&eta, &xsi);
        ASSERT_NEAR(eta, expectedEtaXsi[etaXsiIndex].first, precision);
        ASSERT_NEAR(xsi, expectedEtaXsi[etaXsiIndex].second, precision);
        ++etaXsiIndex;
        cell.GetTrailingEdgeOuterPoint(&eta, &xsi);
        ASSERT_NEAR(eta, expectedEtaXsi[etaXsiIndex].first, precision);
        ASSERT_NEAR(xsi, expectedEtaXsi[etaXsiIndex].second, precision);
    }
}

TEST_F(WingCellRibSpar, etaXsi) {
    // See: cell_rib_spar_test.png for placement of cells

    // next compute the expected XSI values on the spar
    const std::pair<double, double> arr[] = { DP(0.2, 0.3), DP(0.95, 0.4), DP(0.2, 0.8), DP(0.95, 1.0) };
    std::vector< std::pair<double, double> > expectedEtaXsi (arr, arr + sizeof(arr) / sizeof(arr[0]));

    // get Component Segment
    tigl::CCPACSConfigurationManager & manager = tigl::CCPACSConfigurationManager::GetInstance();
    tigl::CCPACSConfiguration & config = manager.GetConfiguration(tiglHandle);
    tigl::CCPACSWing& wing = config.GetWing(1);
    tigl::CCPACSWingComponentSegment& componentSegment = static_cast<tigl::CCPACSWingComponentSegment&>(wing.GetComponentSegment(1));
    tigl::CCPACSWingCSStructure& structure = *componentSegment.GetStructure();

    tigl::CCPACSWingCell& cell = componentSegment.GetStructure()->GetUpperShell().GetCell(1);
    checkCellEtaXsis(cell, expectedEtaXsi);

    // now we change the rib definition and watch whether the cell is correctly updated
    structure.GetRibsDefinition(1).GetRibsPositioning_choice1()->SetEtaEnd(0.8);
    const std::pair<double, double> arr2[] = { DP(0.2, 0.3), DP(0.8, 0.48), DP(0.2, 0.8), DP(0.8, 1.0) };
    expectedEtaXsi = std::vector< std::pair<double, double> > (arr2, arr2 + sizeof(arr2) / sizeof(arr2[0]));
    checkCellEtaXsis(cell, expectedEtaXsi);

    // next we change the z-rotation of the rib
    // See: cell_rib_spar_test_2.png for placement of cells
    structure.GetRibsDefinition(1).GetRibsPositioning_choice1()->GetRibRotation().SetZ(75);
    const std::pair<double, double> arr3[] = { DP(0.16, 0.28), DP(0.74, 0.47), DP(0.09, 0.8), DP(0.67, 1.0) };
    expectedEtaXsi = std::vector< std::pair<double, double> > (arr3, arr3 + sizeof(arr3) / sizeof(arr3[0]));
    // precision at 1E-2 since expected values are estimated based on geometric inspection
    checkCellEtaXsis(cell, expectedEtaXsi, 1.E-2);
}
<commit_msg>Added test to compute simple cell geometry<commit_after> /*
* Copyright (C) 2007-2013 German Aerospace Center (DLR/SC)
*
* Created: 2013-05-28 Martin Siggel <Martin.Siggel@dlr.de>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "test.h"
#include "tigl.h"

#include "CCPACSConfigurationManager.h"
#include "CCPACSWing.h"
#include "CCPACSWingCell.h"
#include "CCPACSWingComponentSegment.h"
#include "CCPACSWingRibsDefinition.h"
#include "CCPACSWingRibsPositioning.h"
#include "CCPACSWingSegment.h"

#include <BRepTools.hxx>

using namespace tigl;

typedef std::pair<double, double> DP;

/******************************************************************************/

class WingCellSpar : public ::testing::Test
{
protected:
    static void SetUpTestCase()
    {
        const char* filename = "TestData/cell_test_spars.xml";
        ReturnCode tixiRet;
        TiglReturnCode tiglRet;

        tiglHandle = -1;
        tixiHandle = -1;

        tixiRet = tixiOpenDocument(filename, &tixiHandle);
        ASSERT_EQ(SUCCESS, tixiRet);
        tiglRet = tiglOpenCPACSConfiguration(tixiHandle, "model", &tiglHandle);
        ASSERT_EQ(TIGL_SUCCESS, tiglRet);
    }

    static void TearDownTestCase()
    {
        ASSERT_EQ(TIGL_SUCCESS, tiglCloseCPACSConfiguration(tiglHandle));
        ASSERT_EQ(SUCCESS, tixiCloseDocument(tixiHandle));
        tiglHandle = -1;
        tixiHandle = -1;
    }

    void SetUp() OVERRIDE {}
    void TearDown() OVERRIDE {}

    static TixiDocumentHandle           tixiHandle;
    static TiglCPACSConfigurationHandle tiglHandle;
};

TixiDocumentHandle WingCellSpar::tixiHandle = 0;
TiglCPACSConfigurationHandle WingCellSpar::tiglHandle = 0;

class WingCellRibSpar : public ::testing::Test
{
protected:
    static void SetUpTestCase()
    {
        const char* filename = "TestData/cell_rib_spar_test.xml";
        ReturnCode tixiRet;
        TiglReturnCode tiglRet;

        tiglHandle = -1;
        tixiHandle = -1;

        tixiRet = tixiOpenDocument(filename, &tixiHandle);
        ASSERT_EQ(SUCCESS, tixiRet);
        tiglRet = tiglOpenCPACSConfiguration(tixiHandle, "model", &tiglHandle);
        ASSERT_EQ(TIGL_SUCCESS, tiglRet);
    }

    static void TearDownTestCase()
    {
        ASSERT_EQ(TIGL_SUCCESS, tiglCloseCPACSConfiguration(tiglHandle));
        ASSERT_EQ(SUCCESS, tixiCloseDocument(tixiHandle));
        tiglHandle = -1;
        tixiHandle = -1;
    }

    void SetUp() OVERRIDE {}
    void TearDown() OVERRIDE {}

    static TixiDocumentHandle           tixiHandle;
    static TiglCPACSConfigurationHandle tiglHandle;
};

TixiDocumentHandle WingCellRibSpar::tixiHandle = 0;
TiglCPACSConfigurationHandle WingCellRibSpar::tiglHandle = 0;

/******************************************************************************/

TEST(WingCell, IsInner)
{
    tigl::CCPACSWingCell cell(NULL, NULL);
    cell.SetLeadingEdgeInnerPoint (0,0);
    cell.SetLeadingEdgeOuterPoint (1,0);
    cell.SetTrailingEdgeInnerPoint(0,1);
    cell.SetTrailingEdgeOuterPoint(1,1);

    // test inner lying points
    ASSERT_TRUE(cell.IsInside(0.5, 0.5));
    ASSERT_TRUE(cell.IsInside(0.2, 0.0));
    ASSERT_TRUE(cell.IsInside(0.1, 0.9));

    // test points on border
    ASSERT_TRUE(cell.IsInside(0.5, 0.0));
    ASSERT_TRUE(cell.IsInside(1.0, 0.5));
    ASSERT_TRUE(cell.IsInside(0.5, 1.0));
    ASSERT_TRUE(cell.IsInside(0.0, 0.5));

    // test points on corners
    ASSERT_TRUE(cell.IsInside(0.0, 0.0));
    ASSERT_TRUE(cell.IsInside(1.0, 0.0));
    ASSERT_TRUE(cell.IsInside(1.0, 1.0));
    ASSERT_TRUE(cell.IsInside(0.0, 1.0));

    ASSERT_FALSE(cell.IsInside(0.3, -0.4));
    ASSERT_FALSE(cell.IsInside(1.3, -0.2));
    ASSERT_FALSE(cell.IsInside(1.2, 0.5));
    ASSERT_FALSE(cell.IsInside(1.1, 1.3));
    ASSERT_FALSE(cell.IsInside(0.5, 1.6));
    ASSERT_FALSE(cell.IsInside(-0.2, 1.2));
    ASSERT_FALSE(cell.IsInside(-0.1, 0.3));
    ASSERT_FALSE(cell.IsInside(-0.2, -0.5));
}

TEST(WingCell, IsInner_NonConvex)
{
    tigl::CCPACSWingCell cell(NULL, NULL);
    cell.SetLeadingEdgeInnerPoint (0,0);
    cell.SetLeadingEdgeOuterPoint (1,0);
    cell.SetTrailingEdgeInnerPoint(0,1);
    cell.SetTrailingEdgeOuterPoint(0.3, 0.3);

    ASSERT_TRUE(cell.IsInside(0.3, 0.2));
    ASSERT_TRUE(cell.IsInside(0.2, 0.3));

    ASSERT_FALSE(cell.IsInside(0.4, 0.3));
    ASSERT_FALSE(cell.IsInside(0.4, 0.4));
    ASSERT_FALSE(cell.IsInside(0.3, 0.4));
    ASSERT_FALSE(cell.IsInside(1.0, 1.0));
}

TEST(WingCell, IsConvex)
{
    tigl::CCPACSWingCell cell(NULL, NULL);
    cell.SetLeadingEdgeInnerPoint (0,0);
    cell.SetLeadingEdgeOuterPoint (1,0);
    cell.SetTrailingEdgeInnerPoint(0,1);
    cell.SetTrailingEdgeOuterPoint(1,1);

    ASSERT_TRUE(cell.IsConvex());

    cell.SetTrailingEdgeOuterPoint(0.3, 0.3);
    ASSERT_FALSE(cell.IsConvex());

    cell.SetTrailingEdgeOuterPoint(0.499, 0.4999);
    ASSERT_FALSE(cell.IsConvex());

    cell.SetTrailingEdgeOuterPoint(0.5001, 0.5001);
    ASSERT_TRUE(cell.IsConvex());

    cell.SetTrailingEdgeOuterPoint(0.5, 0.5);
    ASSERT_TRUE(cell.IsConvex());
}

TEST(WingCell, area)
{
    WingCellInternal::Point2D p1, p2, p3;
    p1.x = 1.; p1.y = 1.;
    p2.x = 2.; p2.y = 1.;
    p3.x = 1.7; p3.y = 2.;

    ASSERT_NEAR(0.5, WingCellInternal::area(p1,p2,p3), 1e-7);
    ASSERT_NEAR(0.5, WingCellInternal::area(p2,p3,p1), 1e-7);
    ASSERT_NEAR(0.5, WingCellInternal::area(p3,p1,p2), 1e-7);
}

TEST_F(WingCellSpar, sparCellXsi) {
    // See: cell_test_spars.png for placement of cells

    const std::pair<double, double> arr[] = { DP(0.2, 0.25), DP(0.35, 0.4), DP(0.3, 0.43), DP(0.275, 0.4), DP(0.47, 0.4), DP(0.5, 0.3) };
    std::vector< std::pair<double, double> > expectedXsis(arr, arr + sizeof(arr) / sizeof(arr[0]));

    // get Component Segment
    tigl::CCPACSConfigurationManager & manager = tigl::CCPACSConfigurationManager::GetInstance();
    tigl::CCPACSConfiguration & config = manager.GetConfiguration(tiglHandle);
    tigl::CCPACSWing& wing = config.GetWing(1);
    tigl::CCPACSWingComponentSegment& componentSegment = static_cast<tigl::CCPACSWingComponentSegment&>(wing.GetComponentSegment(1));

    int cellIndex = 1;
    std::vector< std::pair<double, double> >::const_iterator it;
    for (it = expectedXsis.begin(); it != expectedXsis.end(); ++it) {
        double xsi1Exp = it->first;
        double xsi2Exp = it->second;

        tigl::CCPACSWingCell& cell = componentSegment.GetStructure()->GetUpperShell().GetCell(cellIndex++);
        double xsi1, xsi2, dummy;
        cell.GetLeadingEdgeInnerPoint(&dummy, &xsi1);
        cell.GetLeadingEdgeOuterPoint(&dummy, &xsi2);
        ASSERT_NEAR(xsi1, xsi1Exp, 1e-7);
        ASSERT_NEAR(xsi2, xsi2Exp, 1e-7);
    }
}

namespace {
    void checkCellEtaXsis(const tigl::CCPACSWingCell& cell, const std::vector< std::pair<double, double> >& expectedEtaXsi, double precision = 1e-7) {
        double eta, xsi;
        int etaXsiIndex = 0;
        cell.GetLeadingEdgeInnerPoint(&eta, &xsi);
        ASSERT_NEAR(eta, expectedEtaXsi[etaXsiIndex].first, precision);
        ASSERT_NEAR(xsi, expectedEtaXsi[etaXsiIndex].second, precision);
        ++etaXsiIndex;
        cell.GetLeadingEdgeOuterPoint(&eta, &xsi);
        ASSERT_NEAR(eta, expectedEtaXsi[etaXsiIndex].first, precision);
        ASSERT_NEAR(xsi, expectedEtaXsi[etaXsiIndex].second, precision);
        ++etaXsiIndex;
        cell.GetTrailingEdgeInnerPoint(&eta, &xsi);
        ASSERT_NEAR(eta, expectedEtaXsi[etaXsiIndex].first, precision);
        ASSERT_NEAR(xsi, expectedEtaXsi[etaXsiIndex].second, precision);
        ++etaXsiIndex;
        cell.GetTrailingEdgeOuterPoint(&eta, &xsi);
        ASSERT_NEAR(eta, expectedEtaXsi[etaXsiIndex].first, precision);
        ASSERT_NEAR(xsi, expectedEtaXsi[etaXsiIndex].second, precision);
    }
}

TEST_F(WingCellRibSpar, etaXsi) {
    // See: cell_rib_spar_test.png for placement of cells

    // next compute the expected XSI values on the spar
    const std::pair<double, double> arr[] = { DP(0.2, 0.3), DP(0.95, 0.4), DP(0.2, 0.8), DP(0.95, 1.0) };
    std::vector< std::pair<double, double> > expectedEtaXsi (arr, arr + sizeof(arr) / sizeof(arr[0]));

    // get Component Segment
    tigl::CCPACSConfigurationManager & manager = tigl::CCPACSConfigurationManager::GetInstance();
    tigl::CCPACSConfiguration & config = manager.GetConfiguration(tiglHandle);
    tigl::CCPACSWing& wing = config.GetWing(1);
    tigl::CCPACSWingComponentSegment& componentSegment = static_cast<tigl::CCPACSWingComponentSegment&>(wing.GetComponentSegment(1));
    tigl::CCPACSWingCSStructure& structure = *componentSegment.GetStructure();

    tigl::CCPACSWingCell& cell = componentSegment.GetStructure()->GetUpperShell().GetCell(1);
    checkCellEtaXsis(cell, expectedEtaXsi);

    // now we change the rib definition and watch whether the cell is correctly updated
    structure.GetRibsDefinition(1).GetRibsPositioning_choice1()->SetEtaEnd(0.8);
    const std::pair<double, double> arr2[] = { DP(0.2, 0.3), DP(0.8, 0.48), DP(0.2, 0.8), DP(0.8, 1.0) };
    expectedEtaXsi = std::vector< std::pair<double, double> > (arr2, arr2 + sizeof(arr2) / sizeof(arr2[0]));
    checkCellEtaXsis(cell, expectedEtaXsi);

    // next we change the z-rotation of the rib
    // See: cell_rib_spar_test_2.png for placement of cells
    structure.GetRibsDefinition(1).GetRibsPositioning_choice1()->GetRibRotation().SetZ(75);
    const std::pair<double, double> arr3[] = { DP(0.16, 0.28), DP(0.74, 0.47), DP(0.09, 0.8), DP(0.67, 1.0) };
    expectedEtaXsi = std::vector< std::pair<double, double> > (arr3, arr3 + sizeof(arr3) / sizeof(arr3[0]));
    // precision at 1E-2 since expected values are estimated based on geometric inspection
    checkCellEtaXsis(cell, expectedEtaXsi, 1.E-2);
}

TEST_F(WingCellRibSpar, computeGeometry) {
    // See: cell_rib_spar_test.png for placement of cells

    // next compute the expected XSI values on the spar
    const std::pair<double, double> arr[] = { DP(0.2, 0.3), DP(0.95, 0.4), DP(0.2, 0.8), DP(0.95, 1.0) };
    std::vector< std::pair<double, double> > expectedEtaXsi (arr, arr + sizeof(arr) / sizeof(arr[0]));

    // get Component Segment
    tigl::CCPACSConfigurationManager & manager = tigl::CCPACSConfigurationManager::GetInstance();
    tigl::CCPACSConfiguration & config = manager.GetConfiguration(tiglHandle);
    tigl::CCPACSWing& wing = config.GetWing(1);
    tigl::CCPACSWingComponentSegment& componentSegment = static_cast<tigl::CCPACSWingComponentSegment&>(wing.GetComponentSegment(1));
    tigl::CCPACSWingCSStructure& structure = *componentSegment.GetStructure();

    tigl::CCPACSWingCell& cell = componentSegment.GetStructure()->GetUpperShell().GetCell(1);
    TopoDS_Shape cellGeom = cell.GetCellSkinGeometry();
    BRepTools::Write(cellGeom, "TestData/export/WingCellRibSpar_CellGeometry.brep");
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: test_string.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: obo $ $Date: 2007-01-22 14:37:52 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_testshl2.hxx"
#include <iostream>
#include <string>
#include <rtl/string.hxx>

using namespace std;

const char* g_cSeparatorList = " \t,;:#";

std::string trim(std::string const& _sStringToTrim)
{
    rtl::OString sStr(_sStringToTrim.c_str());
    sStr = sStr.trim();
    return std::string(sStr.getStr());
}

bool isInCurrentEnvironment(std::string const& _sString)
{
    int nSpace = 0;
    std::string sSearchString = _sString;
    bool bEnd = false;
    // run through the hole given string,
    std::string sEnv;

    do {
        nSpace = sSearchString.find_first_of(g_cSeparatorList);
        if (nSpace < 0)
        {
            sEnv = sSearchString;
            bEnd = true;
        }
        else
        {
            sEnv = sSearchString.substr(0, nSpace);
            sSearchString = sSearchString.substr(nSpace + 1);
        }
        if (sEnv.length() > 0)
        {
            cout << sEnv << endl;
#ifdef LINUX
            int nLinux = sEnv.find("unxlng");
            if (nLinux >= 0)
            {
                // found unxlng
                return true;
            }
#endif
#ifdef SOLARIS
            int nSolaris = sEnv.find("unxsol");
            if (nSolaris >= 0)
            {
                // found unxsol
                return true;
            }
#endif
#ifdef WNT
            int nWindows = sEnv.find("wnt");
            if (nWindows >= 0)
            {
                // found wnt
                return true;
            }
#endif
        }
    } while ( !bEnd );
    return false;
}

// ----------------------------------- Main -----------------------------------
#if (defined UNX) || (defined OS2)
int main( int /* argc */, char* /* argv */ [] )
#else
    int _cdecl main( int /* argc */ , char* /* argv */ [] )
#endif
{
    string sLine1 = "osl_Socket.ctor.ctors_001";
    string sLine = "osl_Socket.ctor.ctors_001 unxlngi5.pro unxsols4.pro wntmsci   ";

    int nSpace = sLine.find_first_of(g_cSeparatorList);
    cout << "Space: " << nSpace << endl;
    std::string sTest;

    if (nSpace > 0)
    {
        sLine = trim(sLine);
        // check environment
        sTest = sLine.substr(0, nSpace);
        std::string sRest = sLine.substr(nSpace + 1);
        if (isInCurrentEnvironment(sRest))
        {
            cout << "new string: " << sTest << endl;
        }
    }
    else
    {
        // every environment
        cout << "new string: " << sLine << endl;
    }

    // cout << "rest string: " << sRest << endl;

    int nCount = 10;
    do {
        cout << nCount << endl;
        nCount --;
    }
    while (nCount >= 0);
    cout << nCount << endl;
}
<commit_msg>INTEGRATION: CWS changefileheader (1.4.38); FILE MERGED 2008/03/31 13:06:10 rt 1.4.38.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: test_string.cxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_testshl2.hxx"
#include <iostream>
#include <string>
#include <rtl/string.hxx>

using namespace std;

const char* g_cSeparatorList = " \t,;:#";

std::string trim(std::string const& _sStringToTrim)
{
    rtl::OString sStr(_sStringToTrim.c_str());
    sStr = sStr.trim();
    return std::string(sStr.getStr());
}

bool isInCurrentEnvironment(std::string const& _sString)
{
    int nSpace = 0;
    std::string sSearchString = _sString;
    bool bEnd = false;
    // run through the hole given string,
    std::string sEnv;

    do {
        nSpace = sSearchString.find_first_of(g_cSeparatorList);
        if (nSpace < 0)
        {
            sEnv = sSearchString;
            bEnd = true;
        }
        else
        {
            sEnv = sSearchString.substr(0, nSpace);
            sSearchString = sSearchString.substr(nSpace + 1);
        }
        if (sEnv.length() > 0)
        {
            cout << sEnv << endl;
#ifdef LINUX
            int nLinux = sEnv.find("unxlng");
            if (nLinux >= 0)
            {
                // found unxlng
                return true;
            }
#endif
#ifdef SOLARIS
            int nSolaris = sEnv.find("unxsol");
            if (nSolaris >= 0)
            {
                // found unxsol
                return true;
            }
#endif
#ifdef WNT
            int nWindows = sEnv.find("wnt");
            if (nWindows >= 0)
            {
                // found wnt
                return true;
            }
#endif
        }
    } while ( !bEnd );
    return false;
}

// ----------------------------------- Main -----------------------------------
#if (defined UNX) || (defined OS2)
int main( int /* argc */, char* /* argv */ [] )
#else
    int _cdecl main( int /* argc */ , char* /* argv */ [] )
#endif
{
    string sLine1 = "osl_Socket.ctor.ctors_001";
    string sLine = "osl_Socket.ctor.ctors_001 unxlngi5.pro unxsols4.pro wntmsci   ";

    int nSpace = sLine.find_first_of(g_cSeparatorList);
    cout << "Space: " << nSpace << endl;
    std::string sTest;

    if (nSpace > 0)
    {
        sLine = trim(sLine);
        // check environment
        sTest = sLine.substr(0, nSpace);
        std::string sRest = sLine.substr(nSpace + 1);
        if (isInCurrentEnvironment(sRest))
        {
            cout << "new string: " << sTest << endl;
        }
    }
    else
    {
        // every environment
        cout << "new string: " << sLine << endl;
    }

    // cout << "rest string: " << sRest << endl;

    int nCount = 10;
    do {
        cout << nCount << endl;
        nCount --;
    }
    while (nCount >= 0);
    cout << nCount << endl;
}
<|endoftext|>


<commit_before>/******************************************************************************

  This source file is part of the tomviz project.

  Copyright Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

******************************************************************************/

#include "SetTiltAnglesOperator.h"

#include "DataSource.h"
#include "EditOperatorWidget.h"

#include <vtkFieldData.h>
#include <vtkDataArray.h>
#include <vtkDataObject.h>
#include <vtkDoubleArray.h>
#include <vtkImageData.h>
#include <vtkNew.h>
#include <vtkTypeInt8Array.h>

#include <QHBoxLayout>
#include <QGridLayout>
#include <QSpinBox>
#include <QDoubleSpinBox>
#include <QLabel>
#include <QTabWidget>
#include <QTableWidget>
#include <QTableWidgetItem>
#include <QPointer>

namespace
{
class SetTiltAnglesWidget : public tomviz::EditOperatorWidget
{
  Q_OBJECT
public:
  SetTiltAnglesWidget(tomviz::SetTiltAnglesOperator *op, vtkSmartPointer<vtkDataObject> dataObject, QWidget *p)
    : EditOperatorWidget(p), Op(op)
  {
    QMap<size_t, double> tiltAngles = this->Op->tiltAngles();
    QHBoxLayout *baseLayout = new QHBoxLayout;
    this->setLayout(baseLayout);
    this->tabWidget = new QTabWidget;
    baseLayout->addWidget(this->tabWidget);

    QWidget *setAutomaticPanel = new QWidget;

    QGridLayout *layout = new QGridLayout;

    QString description_string =
      "A tomographic \"tilt series\" is a set of projection images taken while rotating"
      " (\"tilting\") the specimen.  Setting the correct angles is needed for accurate"
      " reconstruction.\n  Set a linearly spaced range of angles by specifying the start"
      " and end tilt index and start and end angles.  Note, tilt angles can also be set"
      " in the \"Data Properties\" panel or within Python.";

    vtkImageData *image = vtkImageData::SafeDownCast(dataObject);
    Q_ASSERT(image);

    int extent[6];
    image->GetExtent(extent);
    int totalSlices = extent[5] - extent[4] + 1;
    this->previousTiltAngles.resize(totalSlices);
    double angleIncrement = 1.0;
    if (totalSlices < 60)
    {
      angleIncrement = 3.0;
    }
    else if (totalSlices < 80)
    {
      angleIncrement = 2.0;
    }
    else if (totalSlices < 120)
    {
      angleIncrement = 1.5;
    }

    double startAngleValue = -(totalSlices - 1) * angleIncrement / 2.0;
    double endAngleValue = startAngleValue + (totalSlices - 1) * angleIncrement;

    if (tiltAngles.contains(0) && tiltAngles.contains(totalSlices -1))
    {
      startAngleValue = tiltAngles[0];
      endAngleValue = tiltAngles[totalSlices - 1];
    }

    QLabel *descriptionLabel = new QLabel(description_string);
    descriptionLabel->setWordWrap(true);
    layout->addWidget(descriptionLabel, 0, 0, 1, 4, Qt::AlignCenter);
    layout->addWidget(new QLabel("Start Image #: "), 1, 0, 1, 1, Qt::AlignCenter);
    this->startTilt = new QSpinBox;
    startTilt->setRange(0,totalSlices-1);
    startTilt->setValue(0);
    layout->addWidget(startTilt, 1, 1, 1, 1, Qt::AlignCenter);
    layout->addWidget(new QLabel("End Image #: "), 2, 0, 1, 1, Qt::AlignCenter);
    this->endTilt = new QSpinBox;
    endTilt->setRange(0,totalSlices-1);
    endTilt->setValue(totalSlices-1);
    layout->addWidget(endTilt, 2, 1, 1, 1, Qt::AlignCenter);
    layout->addWidget(new QLabel("Set Start Angle: "), 1, 2, 1, 1, Qt::AlignCenter);
    this->startAngle = new QDoubleSpinBox;
    startAngle->setRange(-360.0, 360.0);
    startAngle->setValue(startAngleValue);
    layout->addWidget(startAngle, 1, 3, 1, 1, Qt::AlignCenter);
    layout->addWidget(new QLabel("Set End Angle: "), 2, 2, 1, 1, Qt::AlignCenter);
    this->endAngle = new QDoubleSpinBox;
    endAngle->setRange(-360.0, 360.0);
    endAngle->setValue(endAngleValue);
    layout->addWidget(endAngle, 2, 3, 1, 1, Qt::AlignCenter);

    setAutomaticPanel->setLayout(layout);

    QWidget *setFromTablePanel = new QWidget;
    QHBoxLayout *tablePanelLayout = new QHBoxLayout;
    this->tableWidget = new QTableWidget;
    this->tableWidget->setRowCount(totalSlices);
    this->tableWidget->setColumnCount(1);
    tablePanelLayout->addWidget(this->tableWidget);

    vtkFieldData *fd = dataObject->GetFieldData();
    vtkDataArray *tiltArray = nullptr;
    if (fd)
    {
      tiltArray = fd->GetArray("tilt_angles");
    }
    for (vtkIdType i = 0; i < totalSlices; ++i)
    {
      QTableWidgetItem *item = new QTableWidgetItem;
      double angle;
      // Make sure to set the previous angles
      if (tiltArray && i < tiltArray->GetNumberOfTuples())
      {
        angle = tiltArray->GetTuple1(i);
        this->previousTiltAngles[i] = angle;
      }
      else
      {
        angle = 0;
        this->previousTiltAngles[i] = 0;
      }
      // deliberate non-else-if.  We want to override with the previous value from
      // the operator, but we need the previousTiltAngles array set correctly, so the
      // above condition has to be separate.
      if (tiltAngles.contains(i))
      {
        angle = tiltAngles[i];
      }
      item->setData(Qt::DisplayRole, QString::number(angle));
      this->tableWidget->setItem(i, 0, item);
    }

    setFromTablePanel->setLayout(tablePanelLayout);

    this->tabWidget->addTab(setAutomaticPanel, "Set by Range");
    this->tabWidget->addTab(setFromTablePanel, "Set Individually");
  }

  void applyChangesToOperator() override
  {
    if (this->tabWidget->currentIndex() == 0)
    {
      QMap<size_t, double> tiltAngles = this->Op->tiltAngles();
      int start = startTilt->value();
      int end = endTilt->value();
      if (end == start)
      {
        tiltAngles[start] = startAngle->value();
      }
      else
      {
        double delta = (endAngle->value() - startAngle->value()) / (end - start);
        double baseAngle = startAngle->value();
        if (delta < 0)
        {
          int temp = start;
          start = end;
          end = temp;
          baseAngle = endAngle->value();
        }
        for (int i = 0; start + i <= end; ++i)
        {
          tiltAngles.insert(start + i,  baseAngle + delta * i);
          this->tableWidget->item(i, 0)->setData(Qt::DisplayRole, QString::number(tiltAngles[start + i]));
        }
      }
      this->Op->setTiltAngles(tiltAngles);
    }
    else
    {
      QMap<size_t, double> tiltAngles;
      for (vtkIdType i = 0; i < this->tableWidget->rowCount(); ++i)
      {
        QTableWidgetItem *item = this->tableWidget->item(i, 0);
        double val = item->data(Qt::DisplayRole).toDouble();
        if (val != this->previousTiltAngles[i])
        {
          tiltAngles[i] = val;
        }
      }
      this->Op->setTiltAngles(tiltAngles);
    }
  }

private:
  QSpinBox *startTilt;
  QSpinBox *endTilt;
  QDoubleSpinBox *startAngle;
  QDoubleSpinBox *endAngle;
  QTableWidget *tableWidget;
  QTabWidget *tabWidget;

  QPointer<tomviz::SetTiltAnglesOperator> Op;
  QVector<double> previousTiltAngles;
};

#include "SetTiltAnglesOperator.moc"

}

namespace tomviz
{

SetTiltAnglesOperator::SetTiltAnglesOperator(QObject *p)
  : Operator(p)
{
}

SetTiltAnglesOperator::~SetTiltAnglesOperator()
{
}

QIcon SetTiltAnglesOperator::icon() const
{
  return QIcon();
}

Operator *SetTiltAnglesOperator::clone() const
{
  SetTiltAnglesOperator *op =  new SetTiltAnglesOperator;
  op->setTiltAngles(this->TiltAngles);
  return op;
}

bool SetTiltAnglesOperator::serialize(pugi::xml_node& ns) const
{
  for (auto itr = std::begin(this->TiltAngles); itr != std::end(this->TiltAngles); ++itr)
  {
    pugi::xml_node angleNode = ns.append_child("Angle");
    angleNode.append_attribute("index").set_value((unsigned long long)itr.key());
    angleNode.append_attribute("angle").set_value(itr.value());
  }
  return true;
}

bool SetTiltAnglesOperator::deserialize(const pugi::xml_node& ns)
{
  for (auto node = ns.child("Angle"); node; node = node.next_sibling("Angle"))
  {
    this->TiltAngles.insert(node.attribute("index").as_ullong(),
        node.attribute("angle").as_double());
  }
  return true;
}

EditOperatorWidget *SetTiltAnglesOperator::getEditorContentsWithData(QWidget *p,
    vtkSmartPointer<vtkImageData> dataObject)
{
  return new SetTiltAnglesWidget(this, dataObject, p);
}

void SetTiltAnglesOperator::setTiltAngles(const QMap<size_t, double>& newAngles)
{
  this->TiltAngles = newAngles;
  emit this->transformModified();
}

bool SetTiltAnglesOperator::applyTransform(vtkDataObject *dataObject)
{
  vtkImageData *image = vtkImageData::SafeDownCast(dataObject);
  if (!image)
  {
    return false;
  }
  int extent[6];
  image->GetExtent(extent);
  int totalSlices = extent[5] - extent[4] + 1;
  vtkFieldData *fd = dataObject->GetFieldData();
  // Make sure the data is marked as a tilt series
  vtkTypeInt8Array *dataType = vtkTypeInt8Array::SafeDownCast(fd->GetArray("tomviz_data_source_type"));
  if (!dataType)
  {
    vtkNew<vtkTypeInt8Array> array;
    array->SetNumberOfTuples(1);
    array->SetName("tomviz_data_source_type");
    fd->AddArray(array.Get());
    dataType = array.Get();
  }
  // It should already be this value...
  dataType->SetTuple1(0, DataSource::TiltSeries);
  // Set the tilt angles
  vtkDataArray *dataTiltAngles = fd->GetArray("tilt_angles");
  if (!dataTiltAngles)
  {
    vtkNew<vtkDoubleArray> angles;
    angles->SetNumberOfTuples(totalSlices);
    angles->SetName("tilt_angles");
    fd->AddArray(angles.Get());
    dataTiltAngles = angles.Get();
  }
  for (auto itr = std::begin(this->TiltAngles); itr != std::end(this->TiltAngles); ++itr)
  {
    dataTiltAngles->SetTuple(itr.key(), &itr.value());
  }
  return true;
}
}
<commit_msg>Ensure tilt angles array is long enough before writing to it<commit_after>/******************************************************************************

  This source file is part of the tomviz project.

  Copyright Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

******************************************************************************/

#include "SetTiltAnglesOperator.h"

#include "DataSource.h"
#include "EditOperatorWidget.h"

#include <vtkFieldData.h>
#include <vtkDataArray.h>
#include <vtkDataObject.h>
#include <vtkDoubleArray.h>
#include <vtkImageData.h>
#include <vtkNew.h>
#include <vtkTypeInt8Array.h>

#include <QHBoxLayout>
#include <QGridLayout>
#include <QSpinBox>
#include <QDoubleSpinBox>
#include <QLabel>
#include <QTabWidget>
#include <QTableWidget>
#include <QTableWidgetItem>
#include <QPointer>

namespace
{
class SetTiltAnglesWidget : public tomviz::EditOperatorWidget
{
  Q_OBJECT
public:
  SetTiltAnglesWidget(tomviz::SetTiltAnglesOperator *op, vtkSmartPointer<vtkDataObject> dataObject, QWidget *p)
    : EditOperatorWidget(p), Op(op)
  {
    QMap<size_t, double> tiltAngles = this->Op->tiltAngles();
    QHBoxLayout *baseLayout = new QHBoxLayout;
    this->setLayout(baseLayout);
    this->tabWidget = new QTabWidget;
    baseLayout->addWidget(this->tabWidget);

    QWidget *setAutomaticPanel = new QWidget;

    QGridLayout *layout = new QGridLayout;

    QString description_string =
      "A tomographic \"tilt series\" is a set of projection images taken while rotating"
      " (\"tilting\") the specimen.  Setting the correct angles is needed for accurate"
      " reconstruction.\n  Set a linearly spaced range of angles by specifying the start"
      " and end tilt index and start and end angles.  Note, tilt angles can also be set"
      " in the \"Data Properties\" panel or within Python.";

    vtkImageData *image = vtkImageData::SafeDownCast(dataObject);
    Q_ASSERT(image);

    int extent[6];
    image->GetExtent(extent);
    int totalSlices = extent[5] - extent[4] + 1;
    this->previousTiltAngles.resize(totalSlices);
    double angleIncrement = 1.0;
    if (totalSlices < 60)
    {
      angleIncrement = 3.0;
    }
    else if (totalSlices < 80)
    {
      angleIncrement = 2.0;
    }
    else if (totalSlices < 120)
    {
      angleIncrement = 1.5;
    }

    double startAngleValue = -(totalSlices - 1) * angleIncrement / 2.0;
    double endAngleValue = startAngleValue + (totalSlices - 1) * angleIncrement;

    if (tiltAngles.contains(0) && tiltAngles.contains(totalSlices -1))
    {
      startAngleValue = tiltAngles[0];
      endAngleValue = tiltAngles[totalSlices - 1];
    }

    QLabel *descriptionLabel = new QLabel(description_string);
    descriptionLabel->setWordWrap(true);
    layout->addWidget(descriptionLabel, 0, 0, 1, 4, Qt::AlignCenter);
    layout->addWidget(new QLabel("Start Image #: "), 1, 0, 1, 1, Qt::AlignCenter);
    this->startTilt = new QSpinBox;
    startTilt->setRange(0,totalSlices-1);
    startTilt->setValue(0);
    layout->addWidget(startTilt, 1, 1, 1, 1, Qt::AlignCenter);
    layout->addWidget(new QLabel("End Image #: "), 2, 0, 1, 1, Qt::AlignCenter);
    this->endTilt = new QSpinBox;
    endTilt->setRange(0,totalSlices-1);
    endTilt->setValue(totalSlices-1);
    layout->addWidget(endTilt, 2, 1, 1, 1, Qt::AlignCenter);
    layout->addWidget(new QLabel("Set Start Angle: "), 1, 2, 1, 1, Qt::AlignCenter);
    this->startAngle = new QDoubleSpinBox;
    startAngle->setRange(-360.0, 360.0);
    startAngle->setValue(startAngleValue);
    layout->addWidget(startAngle, 1, 3, 1, 1, Qt::AlignCenter);
    layout->addWidget(new QLabel("Set End Angle: "), 2, 2, 1, 1, Qt::AlignCenter);
    this->endAngle = new QDoubleSpinBox;
    endAngle->setRange(-360.0, 360.0);
    endAngle->setValue(endAngleValue);
    layout->addWidget(endAngle, 2, 3, 1, 1, Qt::AlignCenter);

    setAutomaticPanel->setLayout(layout);

    QWidget *setFromTablePanel = new QWidget;
    QHBoxLayout *tablePanelLayout = new QHBoxLayout;
    this->tableWidget = new QTableWidget;
    this->tableWidget->setRowCount(totalSlices);
    this->tableWidget->setColumnCount(1);
    tablePanelLayout->addWidget(this->tableWidget);

    vtkFieldData *fd = dataObject->GetFieldData();
    vtkDataArray *tiltArray = nullptr;
    if (fd)
    {
      tiltArray = fd->GetArray("tilt_angles");
    }
    for (vtkIdType i = 0; i < totalSlices; ++i)
    {
      QTableWidgetItem *item = new QTableWidgetItem;
      double angle;
      // Make sure to set the previous angles
      if (tiltArray && i < tiltArray->GetNumberOfTuples())
      {
        angle = tiltArray->GetTuple1(i);
        this->previousTiltAngles[i] = angle;
      }
      else
      {
        angle = 0;
        this->previousTiltAngles[i] = 0;
      }
      // deliberate non-else-if.  We want to override with the previous value from
      // the operator, but we need the previousTiltAngles array set correctly, so the
      // above condition has to be separate.
      if (tiltAngles.contains(i))
      {
        angle = tiltAngles[i];
      }
      item->setData(Qt::DisplayRole, QString::number(angle));
      this->tableWidget->setItem(i, 0, item);
    }

    setFromTablePanel->setLayout(tablePanelLayout);

    this->tabWidget->addTab(setAutomaticPanel, "Set by Range");
    this->tabWidget->addTab(setFromTablePanel, "Set Individually");
  }

  void applyChangesToOperator() override
  {
    if (this->tabWidget->currentIndex() == 0)
    {
      QMap<size_t, double> tiltAngles = this->Op->tiltAngles();
      int start = startTilt->value();
      int end = endTilt->value();
      if (end == start)
      {
        tiltAngles[start] = startAngle->value();
      }
      else
      {
        double delta = (endAngle->value() - startAngle->value()) / (end - start);
        double baseAngle = startAngle->value();
        if (delta < 0)
        {
          int temp = start;
          start = end;
          end = temp;
          baseAngle = endAngle->value();
        }
        for (int i = 0; start + i <= end; ++i)
        {
          tiltAngles.insert(start + i,  baseAngle + delta * i);
          this->tableWidget->item(i, 0)->setData(Qt::DisplayRole, QString::number(tiltAngles[start + i]));
        }
      }
      this->Op->setTiltAngles(tiltAngles);
    }
    else
    {
      QMap<size_t, double> tiltAngles;
      for (vtkIdType i = 0; i < this->tableWidget->rowCount(); ++i)
      {
        QTableWidgetItem *item = this->tableWidget->item(i, 0);
        double val = item->data(Qt::DisplayRole).toDouble();
        if (val != this->previousTiltAngles[i])
        {
          tiltAngles[i] = val;
        }
      }
      this->Op->setTiltAngles(tiltAngles);
    }
  }

private:
  QSpinBox *startTilt;
  QSpinBox *endTilt;
  QDoubleSpinBox *startAngle;
  QDoubleSpinBox *endAngle;
  QTableWidget *tableWidget;
  QTabWidget *tabWidget;

  QPointer<tomviz::SetTiltAnglesOperator> Op;
  QVector<double> previousTiltAngles;
};

#include "SetTiltAnglesOperator.moc"

}

namespace tomviz
{

SetTiltAnglesOperator::SetTiltAnglesOperator(QObject *p)
  : Operator(p)
{
}

SetTiltAnglesOperator::~SetTiltAnglesOperator()
{
}

QIcon SetTiltAnglesOperator::icon() const
{
  return QIcon();
}

Operator *SetTiltAnglesOperator::clone() const
{
  SetTiltAnglesOperator *op =  new SetTiltAnglesOperator;
  op->setTiltAngles(this->TiltAngles);
  return op;
}

bool SetTiltAnglesOperator::serialize(pugi::xml_node& ns) const
{
  for (auto itr = std::begin(this->TiltAngles); itr != std::end(this->TiltAngles); ++itr)
  {
    pugi::xml_node angleNode = ns.append_child("Angle");
    angleNode.append_attribute("index").set_value((unsigned long long)itr.key());
    angleNode.append_attribute("angle").set_value(itr.value());
  }
  return true;
}

bool SetTiltAnglesOperator::deserialize(const pugi::xml_node& ns)
{
  for (auto node = ns.child("Angle"); node; node = node.next_sibling("Angle"))
  {
    this->TiltAngles.insert(node.attribute("index").as_ullong(),
        node.attribute("angle").as_double());
  }
  return true;
}

EditOperatorWidget *SetTiltAnglesOperator::getEditorContentsWithData(QWidget *p,
    vtkSmartPointer<vtkImageData> dataObject)
{
  return new SetTiltAnglesWidget(this, dataObject, p);
}

void SetTiltAnglesOperator::setTiltAngles(const QMap<size_t, double>& newAngles)
{
  this->TiltAngles = newAngles;
  emit this->transformModified();
}

bool SetTiltAnglesOperator::applyTransform(vtkDataObject *dataObject)
{
  vtkImageData *image = vtkImageData::SafeDownCast(dataObject);
  if (!image)
  {
    return false;
  }
  int extent[6];
  image->GetExtent(extent);
  int totalSlices = extent[5] - extent[4] + 1;
  vtkFieldData *fd = dataObject->GetFieldData();
  // Make sure the data is marked as a tilt series
  vtkTypeInt8Array *dataType = vtkTypeInt8Array::SafeDownCast(fd->GetArray("tomviz_data_source_type"));
  if (!dataType)
  {
    vtkNew<vtkTypeInt8Array> array;
    array->SetNumberOfTuples(1);
    array->SetName("tomviz_data_source_type");
    fd->AddArray(array.Get());
    dataType = array.Get();
  }
  // It should already be this value...
  dataType->SetTuple1(0, DataSource::TiltSeries);
  // Set the tilt angles
  vtkDataArray *dataTiltAngles = fd->GetArray("tilt_angles");
  if (!dataTiltAngles)
  {
    vtkNew<vtkDoubleArray> angles;
    angles->SetNumberOfTuples(totalSlices);
    angles->SetName("tilt_angles");
    fd->AddArray(angles.Get());
    dataTiltAngles = angles.Get();
  }
  else if (dataTiltAngles->GetNumberOfTuples() < totalSlices)
  {
    dataTiltAngles->SetNumberOfTuples(totalSlices);
  }
  for (auto itr = std::begin(this->TiltAngles); itr != std::end(this->TiltAngles); ++itr)
  {
    dataTiltAngles->SetTuple(itr.key(), &itr.value());
  }
  return true;
}
}
<|endoftext|>


<commit_before>/*******************************************************************************
 * test/construction_test.cpp
 *
 * Copyright (C) 2017 Florian Kurpicz <florian.kurpicz@tu-dortmund.de>
 * Copyright (C) 2017 Marvin Löbel <loebel.marvin@gmail.com>
 *
 * All rights reserved. Published under the BSD-2 license in the LICENSE file.
 ******************************************************************************/

#include <gtest/gtest.h>

#include "util/util.hpp"

#include "benchmark/algorithm.hpp"
#include "huffman/huff_codes.hpp"
#include "huffman/huff_decode.hpp"
#include "huffman/huff_level_sizes_builder.hpp"
#include "util/alphabet_util.hpp"
#include "util/common.hpp"
#include "util/decode.hpp"
#include "util/file_util.hpp"

TEST(wavelet_construction, smoketest) {
  auto& algo_list = algorithm_list::get_algorithm_list();
  for (const auto& a : algo_list) {
    if (a->word_width() == 1 && !a->is_huffman_shaped()) {
      a->print_info();
      test::roundtrip_batch([&](const std::string& s){
        auto vec = std::vector<uint8_t>(s.begin(), s.end());
        uint64_t levels = no_reduction_alphabet(vec);
        wavelet_structure bvz = a->compute_bitvector(&vec, vec.size() , levels);
        if (a->is_tree()) {
          auto decoded_s = decode_wt(bvz.bvs(), vec.size());
          ASSERT_EQ(s, decoded_s) << "Failure (Algorithm): " << a->name();
        } else {
          auto decoded_s = decode_wm(bvz.bvs(), bvz.zeros(), vec.size());
          ASSERT_EQ(s, decoded_s) << "Failure (Algorithm): " << a->name();
        }
      });
    }
  }
}

TEST(huffman_shaped_wavelet_construction, smoketest) {
  auto& algo_list = algorithm_list::get_algorithm_list();
  for (const auto& a : algo_list) {
    if (a->word_width() == 1 && a->is_huffman_shaped()) {
      a->print_info();
      test::roundtrip_batch([&](const std::string& s){
        auto vec = std::vector<uint8_t>(s.begin(), s.end());
        uint64_t levels = no_reduction_alphabet(vec);
        auto bvz = a->compute_bitvector(&vec, vec.size() , levels);
        histogram<uint8_t> hist { vec.data(), vec.size() };
        level_sizes_builder<uint8_t> builder { std::move(hist) };
        if (a->is_tree()) {
          const auto codes =
            canonical_huff_codes<uint8_t, true>(builder);
          auto decoded_s = decode_wt_huff(bvz.bvs(), codes);
          ASSERT_EQ(s, decoded_s) << "Failure (Algorithm): " << a->name();
        } else {
          const auto codes =
            canonical_huff_codes<uint8_t, false>(builder);
          auto decoded_s = decode_wm_huff(bvz.bvs(), codes);
          ASSERT_EQ(s, decoded_s) << "Failure (Algorithm): " << a->name();
        }
      });
    }
  }
}

/******************************************************************************/
<commit_msg>fix huffman construction test<commit_after>/*******************************************************************************
 * test/construction_test.cpp
 *
 * Copyright (C) 2017 Florian Kurpicz <florian.kurpicz@tu-dortmund.de>
 * Copyright (C) 2017 Marvin Löbel <loebel.marvin@gmail.com>
 *
 * All rights reserved. Published under the BSD-2 license in the LICENSE file.
 ******************************************************************************/

#include <gtest/gtest.h>

#include "util/util.hpp"

#include "benchmark/algorithm.hpp"
#include "huffman/huff_codes.hpp"
#include "huffman/huff_decode.hpp"
#include "huffman/huff_level_sizes_builder.hpp"
#include "util/alphabet_util.hpp"
#include "util/common.hpp"
#include "util/decode.hpp"
#include "util/file_util.hpp"

TEST(wavelet, no_alphabet_reduction) {
  auto& algo_list = algorithm_list::get_algorithm_list();
  for (const auto& a : algo_list) {
    if (a->word_width() == 1 && !a->is_huffman_shaped()) {
      a->print_info();
      test::roundtrip_batch([&](const std::string& s){
        auto vec = std::vector<uint8_t>(s.begin(), s.end());
        uint64_t levels = no_reduction_alphabet(vec);
        wavelet_structure bvz = a->compute_bitvector(&vec, vec.size() , levels);
        if (a->is_tree()) {
          auto decoded_s = decode_wt(bvz.bvs(), vec.size());
          ASSERT_EQ(s, decoded_s) << "Failure (Algorithm): " << a->name();
        } else {
          auto decoded_s = decode_wm(bvz.bvs(), bvz.zeros(), vec.size());
          ASSERT_EQ(s, decoded_s) << "Failure (Algorithm): " << a->name();
        }
      });
    }
  }
}

/*
TODO: Broken due to levels == 0 corner case

TEST(construction, wavelet_alphabet_reduction) {
  auto& algo_list = algorithm_list::get_algorithm_list();
  for (const auto& a : algo_list) {
    if (a->word_width() == 1 && !a->is_huffman_shaped()) {
      a->print_info();
      test::roundtrip_batch([&](const std::string& s){
        auto vec = std::vector<uint8_t>(s.begin(), s.end());
        auto max_char = reduce_alphabet(vec);
        uint64_t levels = levels_for_max_char(max_char);
        wavelet_structure bvz = a->compute_bitvector(&vec, vec.size() , levels);
        if (a->is_tree()) {
          auto decoded_s = decode_wt(bvz.bvs(), vec.size());
          auto decoded_vec = std::vector<uint8_t>(decoded_s.begin(), decoded_s.end());
          ASSERT_EQ(vec, decoded_vec) << "Failure (Algorithm): " << a->name();
        } else {
          auto decoded_s = decode_wm(bvz.bvs(), bvz.zeros(), vec.size());
          auto decoded_vec = std::vector<uint8_t>(decoded_s.begin(), decoded_s.end());
          ASSERT_EQ(vec, decoded_vec) << "Failure (Algorithm): " << a->name();
        }
      });
    }
  }
}
*/

TEST(huffman_shaped_wavelet, alphabet_reduction) {
  auto& algo_list = algorithm_list::get_algorithm_list();
  for (const auto& a : algo_list) {
    if (a->word_width() == 1 && a->is_huffman_shaped()) {
      a->print_info();
      test::roundtrip_batch([&](const std::string& s){
        auto vec = std::vector<uint8_t>(s.begin(), s.end());
        auto max_char = reduce_alphabet(vec);
        uint64_t levels = levels_for_max_char(max_char);
        auto bvz = a->compute_bitvector(&vec, vec.size() , levels);
        histogram<uint8_t> hist { vec.data(), vec.size() };
        level_sizes_builder<uint8_t> builder { std::move(hist) };
        if (a->is_tree()) {
          const auto codes =
            canonical_huff_codes<uint8_t, true>(builder);
          auto decoded_s = decode_wt_huff(bvz.bvs(), codes);
          auto decoded_vec = std::vector<uint8_t>(decoded_s.begin(), decoded_s.end());
          ASSERT_EQ(vec, decoded_vec) << "Failure (Algorithm): " << a->name();
        } else {
          const auto codes =
            canonical_huff_codes<uint8_t, false>(builder);
          auto decoded_s = decode_wm_huff(bvz.bvs(), codes);
          auto decoded_vec = std::vector<uint8_t>(decoded_s.begin(), decoded_s.end());
          ASSERT_EQ(vec, decoded_vec) << "Failure (Algorithm): " << a->name();
        }
      });
    }
  }
}

/******************************************************************************/
<|endoftext|>


<commit_before>// #define _GCL_DEBUG

// static tests

#include <gcl/mp/mp.hpp>
#include <gcl/cx/cx.hpp>
#include <gcl/compile_time_constant/ctc.hpp>

// dynamic tests

#include <gcl/serialization.hpp>

void tmp()
{	// only for gcl_v2 WIP
    gcl::serialization::p1::test();
    gcl::serialization::p5::test();
}

#include <stdexcept>
#include <iostream>

auto main(int, char const*[]) -> int
{
    try
    {
        tmp();
        // gcl::signals::initialize();
        // gcl::test::proceed();
    }
    catch (const std::exception& ex)
    {
        std::cerr << "Error : " << ex.what() << std::endl;
    }
    catch (...)
    {
        std::cerr << "Error : unknown" << std::endl;
    }

    return 0;
}<commit_msg>[mp::container::range_map/interval_map] add to runtime test<commit_after>// #define _GCL_DEBUG

// static tests

#include <gcl/mp/mp.hpp>
#include <gcl/cx/cx.hpp>
#include <gcl/compile_time_constant/ctc.hpp>

// dynamic tests

#include <gcl/serialization.hpp>
#include <gcl/container/interval_map.hpp>

void tmp()
{	// only for gcl_v2 WIP
    gcl::serialization::p1::test();
    gcl::serialization::p5::test();
}

#include <stdexcept>
#include <iostream>

auto main(int, char const*[]) -> int
{
    try
    {
        // tmp();
        // gcl::signals::initialize();
        // gcl::test::proceed();
        gcl::container::test::interval_map::test();
    }
    catch (const std::exception& ex)
    {
        std::cerr << "Error : " << ex.what() << std::endl;
    }
    catch (...)
    {
        std::cerr << "Error : unknown" << std::endl;
    }

    return 0;
}<|endoftext|>


<commit_before>// SolLimTests.cpp
#include <deque>
#include <map>
#include <gtest/gtest.h>

#include "SolLim.h"
#include "NuclideModel.h"
#include "CycException.h"
#include "Material.h"

using namespace std;

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
class SolLimTest : public ::testing::Test {
  protected:
    CompMapPtr test_comp_;
    mat_rsrc_ptr test_mat_;
    int one_mol_;
    int u235_, am241_;
    int u_;
    double test_size_;
    Radius r_four_, r_five_;
    Length len_five_;
    point_t origin_;
    int time_;
    double K_d_;

    virtual void SetUp(){
      // composition set up
      u235_=92235;
      u_=92;
      one_mol_=1.0;
      test_comp_= CompMapPtr(new CompMap(MASS));
      (*test_comp_)[u235_] = one_mol_;
      test_size_=10.0;
      // material creation
      test_mat_ = mat_rsrc_ptr(new Material(test_comp_));
      test_mat_->setQuantity(test_size_);
      // useful numbers
      K_d_ = 0.001;
    }
    virtual void TearDown() {
    }
};

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_f){
  double V_f, V_s, m_T;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=10.*i;
    EXPECT_FLOAT_EQ(m_T/(1+K_d_*(V_s/V_f)), SolLim::m_f(m_T, K_d_, V_s, V_f));
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_s){
  double V_f, V_s, m_T;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    EXPECT_FLOAT_EQ((K_d_*(V_s/V_f))*m_T/(1+K_d_*(V_s/V_f)), SolLim::m_s(m_T, K_d_, V_s, V_f));
    EXPECT_FLOAT_EQ((K_d_*(V_s/V_f))*SolLim::m_f(m_T, K_d_,V_s, V_f), SolLim::m_s(m_T, K_d_, V_s, V_f));
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_ds){
  double V_f, V_s, m_T, d;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    d=0.1*i;
    EXPECT_FLOAT_EQ(d*(K_d_*(V_s/V_f))*m_T/(1+K_d_*(V_s/V_f)), SolLim::m_ds(m_T, K_d_, V_s, V_f, d));
    EXPECT_FLOAT_EQ(d*(K_d_*(V_s/V_f))*SolLim::m_f(m_T, K_d_,V_s, V_f), SolLim::m_ds(m_T, K_d_, V_s, V_f, d));
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_ms){
  double V_f, V_s, m_T, d;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    d=0.1*i;
    EXPECT_FLOAT_EQ((1-d)*(K_d_*(V_s/V_f))*m_T/(1+K_d_*(V_s/V_f)), SolLim::m_ms(m_T, K_d_, V_s, V_f, d));
    EXPECT_FLOAT_EQ((1-d)*(K_d_*(V_s/V_f))*SolLim::m_f(m_T, K_d_,V_s, V_f), SolLim::m_ms(m_T, K_d_, V_s, V_f, d));
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_ff){
  double V_f, V_s, m_T, d;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    d=0.1*i;
    EXPECT_FLOAT_EQ(d*m_T/(1+K_d_*(V_s/V_f)), SolLim::m_ff(m_T, K_d_, V_s, V_f, d));
    EXPECT_FLOAT_EQ(d*SolLim::m_f(m_T, K_d_,V_s, V_f), SolLim::m_ff(m_T, K_d_, V_s, V_f, d));
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_mf){
  double V_f, V_s, m_T, d;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    d=0.1*i;
    EXPECT_FLOAT_EQ((1-d)*m_T/(1+K_d_*(V_s/V_f)), SolLim::m_mf(m_T, K_d_, V_s, V_f, d));
    EXPECT_FLOAT_EQ((1-d)*SolLim::m_f(m_T, K_d_,V_s, V_f), SolLim::m_mf(m_T, K_d_, V_s, V_f, d));
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_aff){
  double V_f, V_s, m_T, d;
  double C_sol = 0.001;
  double expected, mff;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    d=0.1*i;
    mff= SolLim::m_ff(m_T, K_d_, V_s, V_f, d);
    EXPECT_FLOAT_EQ(0, SolLim::m_aff(mff, V_f, 0));
    expected = min(C_sol*V_f,(1-d)*m_T/(1+K_d_*(V_s/V_f)));
    EXPECT_FLOAT_EQ(expected, SolLim::m_aff(mff, V_f, C_sol));
    EXPECT_GT(mff, SolLim::m_aff(mff, V_f, C_sol));
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_ps){
  double V_f, V_s, m_T, d;
  double C_sol = 0.001;
  double expected;
  double m_ff;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    d=0.1*i;
    EXPECT_FLOAT_EQ(0, SolLim::m_ps(m_T, K_d_, V_s, V_f, d, 10000));
    m_ff = (d)*m_T/(1+K_d_*(V_s/V_f));
    expected = m_ff - min(C_sol*V_f, m_ff);
    EXPECT_FLOAT_EQ(expected, SolLim::m_ps(m_T, K_d_, V_s, V_f, d, C_sol));
    EXPECT_FLOAT_EQ(expected, SolLim::m_ps(m_T, K_d_, V_s, V_f, d, C_sol));
  }
}

<commit_msg> adds nonsorbing solubility limited m_aff test<commit_after>// SolLimTests.cpp
#include <deque>
#include <map>
#include <gtest/gtest.h>

#include "SolLim.h"
#include "NuclideModel.h"
#include "CycException.h"
#include "Material.h"

using namespace std;

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
class SolLimTest : public ::testing::Test {
  protected:
    CompMapPtr test_comp_;
    mat_rsrc_ptr test_mat_;
    int one_mol_;
    int u235_, am241_;
    int u_;
    double test_size_;
    Radius r_four_, r_five_;
    Length len_five_;
    point_t origin_;
    int time_;
    double K_d_;

    virtual void SetUp(){
      // composition set up
      u235_=92235;
      u_=92;
      one_mol_=1.0;
      test_comp_= CompMapPtr(new CompMap(MASS));
      (*test_comp_)[u235_] = one_mol_;
      test_size_=10.0;
      // material creation
      test_mat_ = mat_rsrc_ptr(new Material(test_comp_));
      test_mat_->setQuantity(test_size_);
      // useful numbers
      K_d_ = 0.001;
    }
    virtual void TearDown() {
    }
};

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_f){
  double V_f, V_s, m_T;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=10.*i;
    EXPECT_FLOAT_EQ(m_T/(1+K_d_*(V_s/V_f)), SolLim::m_f(m_T, K_d_, V_s, V_f));
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_s){
  double V_f, V_s, m_T;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    EXPECT_FLOAT_EQ((K_d_*(V_s/V_f))*m_T/(1+K_d_*(V_s/V_f)), SolLim::m_s(m_T, K_d_, V_s, V_f));
    EXPECT_FLOAT_EQ((K_d_*(V_s/V_f))*SolLim::m_f(m_T, K_d_,V_s, V_f), SolLim::m_s(m_T, K_d_, V_s, V_f));
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_ds){
  double V_f, V_s, m_T, d;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    d=0.1*i;
    EXPECT_FLOAT_EQ(d*(K_d_*(V_s/V_f))*m_T/(1+K_d_*(V_s/V_f)), SolLim::m_ds(m_T, K_d_, V_s, V_f, d));
    EXPECT_FLOAT_EQ(d*(K_d_*(V_s/V_f))*SolLim::m_f(m_T, K_d_,V_s, V_f), SolLim::m_ds(m_T, K_d_, V_s, V_f, d));
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_ms){
  double V_f, V_s, m_T, d;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    d=0.1*i;
    EXPECT_FLOAT_EQ((1-d)*(K_d_*(V_s/V_f))*m_T/(1+K_d_*(V_s/V_f)), SolLim::m_ms(m_T, K_d_, V_s, V_f, d));
    EXPECT_FLOAT_EQ((1-d)*(K_d_*(V_s/V_f))*SolLim::m_f(m_T, K_d_,V_s, V_f), SolLim::m_ms(m_T, K_d_, V_s, V_f, d));
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_ff){
  double V_f, V_s, m_T, d;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    d=0.1*i;
    EXPECT_FLOAT_EQ(d*m_T/(1+K_d_*(V_s/V_f)), SolLim::m_ff(m_T, K_d_, V_s, V_f, d));
    EXPECT_FLOAT_EQ(d*SolLim::m_f(m_T, K_d_,V_s, V_f), SolLim::m_ff(m_T, K_d_, V_s, V_f, d));
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_mf){
  double V_f, V_s, m_T, d;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    d=0.1*i;
    EXPECT_FLOAT_EQ((1-d)*m_T/(1+K_d_*(V_s/V_f)), SolLim::m_mf(m_T, K_d_, V_s, V_f, d));
    EXPECT_FLOAT_EQ((1-d)*SolLim::m_f(m_T, K_d_,V_s, V_f), SolLim::m_mf(m_T, K_d_, V_s, V_f, d));
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_aff){
  double V_f, V_ff, V_s, m_T, d;
  double C_sol;
  double expected, mff;
  for(int c = 0; c<100; c++){
    C_sol = 0.1/c;
    for(int i=1; i<10; i++){
      V_f=0.1*i;
      V_s=0.1*i;
      m_T=0.1*i;
      d=0.1*i;
      V_ff=V_f*d;
      mff= SolLim::m_ff(m_T, K_d_, V_s, V_f, d);
      EXPECT_FLOAT_EQ(0, SolLim::m_aff(mff, V_ff, 0));
      expected = min(C_sol*V_ff, d*m_T/(1+K_d_*(V_s/V_f)));
      EXPECT_FLOAT_EQ(expected, SolLim::m_aff(mff, V_ff, C_sol));
      EXPECT_GE(mff, SolLim::m_aff(mff, V_ff, C_sol));
    }
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_aff_kd0){
  double V_f, V_ff, V_s, m_T, d;
  double C_sol;
  double expected, mff;
  for(int c = 0; c<100; c++){
    C_sol = 0.1/c;
    for(int i=1; i<10; i++){
      V_f=0.1*i;
      V_s=0.1*i;
      m_T=0.1*i;
      d=0.1*i;
      V_ff=V_f*d;
      mff= SolLim::m_ff(m_T, 0, V_s, V_f, d);
      EXPECT_FLOAT_EQ(0, SolLim::m_aff(mff, V_ff, 0));
      expected = min(C_sol*V_ff, d*m_T/(1+0*(V_s/V_f)));
      EXPECT_FLOAT_EQ(expected, SolLim::m_aff(mff, V_ff, C_sol));
      EXPECT_GE(mff, SolLim::m_aff(mff, V_ff, C_sol));
    }
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_ps){
  double V_f, V_s, m_T, d;
  double C_sol = 0.001;
  double expected;
  double m_ff;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    d=0.1*i;
    EXPECT_FLOAT_EQ(0, SolLim::m_ps(m_T, K_d_, V_s, V_f, d, 10000));
    m_ff = (d)*m_T/(1+K_d_*(V_s/V_f));
    expected = m_ff - min(C_sol*V_f, m_ff);
    EXPECT_FLOAT_EQ(expected, SolLim::m_ps(m_T, K_d_, V_s, V_f, d, C_sol));
    EXPECT_FLOAT_EQ(expected, SolLim::m_ps(m_T, K_d_, V_s, V_f, d, C_sol));
  }
}

<|endoftext|>