<commit_before>//===----------------------------------------------------------------------===//
//
//                         PelotonDB
//
// aggregate_test.cpp
//
// Identification: tests/executor/aggregate_test.cpp
//
// Copyright (c) 2015, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include <memory>
#include <set>
#include <string>
#include <vector>

#include "gmock/gmock.h"
#include "gtest/gtest.h"

#include "backend/common/types.h"
#include "backend/common/value.h"
#include "backend/executor/logical_tile.h"
#include "backend/executor/aggregate_executor.h"
#include "backend/executor/logical_tile_factory.h"
#include "backend/expression/expression_util.h"
#include "backend/planner/abstract_plan_node.h"
#include "backend/planner/aggregateV2_node.h"
#include "backend/storage/data_table.h"

#include "executor/executor_tests_util.h"
#include "executor/mock_executor.h"
#include "harness.h"

using ::testing::NotNull;
using ::testing::Return;

namespace peloton {
namespace test {

TEST(AggregateTests, DistinctTest) {

  /*
   * SELECT d, a, b, c FROM table GROUP BY a, b, c, d;
   */

  const int tuple_count = TESTS_TUPLES_PER_TILEGROUP;

  // Create a table and wrap it in logical tiles
  std::unique_ptr<storage::DataTable> data_table(
      ExecutorTestsUtil::CreateTable(tuple_count, false));
  ExecutorTestsUtil::PopulateTable(data_table.get(), 2*tuple_count, false, false, true);

  std::unique_ptr<executor::LogicalTile> source_logical_tile1(
      executor::LogicalTileFactory::WrapTileGroup(data_table->GetTileGroup(0)));

  std::unique_ptr<executor::LogicalTile> source_logical_tile2(
      executor::LogicalTileFactory::WrapTileGroup(data_table->GetTileGroup(1)));

  // (1-5) Setup plan node

  // 1) Set up group-by columns
  std::vector<oid_t> group_by_columns = { 0, 1, 2, 3 };

  // 2) Set up project info
  planner::ProjectInfo::DirectMapList direct_map_list = { { 0, { 0, 3 } }, { 1,
      { 0, 0 } }, { 2, { 0, 1 } }, { 3, { 0, 2 } } };
  auto proj_info = new planner::ProjectInfo(planner::ProjectInfo::TargetList(),
                                            std::move(direct_map_list));

  // 3) Set up unique aggregates (empty)
  std::vector<planner::AggregateV2Node::AggTerm> agg_terms;

  // 4) Set up predicate (empty)
  expression::AbstractExpression* predicate = nullptr;

  // 5) Create output table schema
  auto data_table_schema = data_table.get()->GetSchema();
  std::vector<oid_t> set = { 3, 0, 1, 2 };
  std::vector<catalog::Column> columns;
  for (auto column_index : set) {
    columns.push_back(data_table_schema->GetColumn(column_index));
  }

  auto output_table_schema = new catalog::Schema(columns);

  // OK) Create the plan node
  planner::AggregateV2Node node(proj_info, predicate, std::move(agg_terms),
                                std::move(group_by_columns),
                                output_table_schema);

  // Create and set up executor
  auto &txn_manager = concurrency::TransactionManager::GetInstance();
  auto txn = txn_manager.BeginTransaction();
  std::unique_ptr<executor::ExecutorContext> context(
      new executor::ExecutorContext(txn));

  executor::AggregateExecutor executor(&node, context.get());
  MockExecutor child_executor;
  executor.AddChild(&child_executor);

  EXPECT_CALL(child_executor, DInit()).WillOnce(Return(true));

  EXPECT_CALL(child_executor, DExecute()).WillOnce(Return(true)).WillOnce(
      Return(true)).WillOnce(Return(false));

  EXPECT_CALL(child_executor, GetOutput()).WillOnce(
      Return(source_logical_tile1.release())).WillOnce(
      Return(source_logical_tile2.release()));

  EXPECT_TRUE(executor.Init());

  EXPECT_TRUE(executor.Execute());
  txn_manager.CommitTransaction(txn);
}

TEST(AggregateTests, SumGroupByTest) {
  /*
   * SELECT a, SUM(b) from table GROUP BY a;
   */
  const int tuple_count = TESTS_TUPLES_PER_TILEGROUP;

  // Create a table and wrap it in logical tiles
  std::unique_ptr<storage::DataTable> data_table(
      ExecutorTestsUtil::CreateTable(tuple_count, false));
  ExecutorTestsUtil::PopulateTable(data_table.get(), 2*tuple_count, false,
  false,
                                   true);

  std::unique_ptr<executor::LogicalTile> source_logical_tile1(
      executor::LogicalTileFactory::WrapTileGroup(data_table->GetTileGroup(0)));

  std::unique_ptr<executor::LogicalTile> source_logical_tile2(
      executor::LogicalTileFactory::WrapTileGroup(data_table->GetTileGroup(1)));

  // (1-5) Setup plan node

  // 1) Set up group-by columns
  std::vector<oid_t> group_by_columns = { 0 };

  // 2) Set up project info
  planner::ProjectInfo::DirectMapList direct_map_list = { { 0, { 0, 0 } }, { 1,
      { 1, 0 } } };

  auto proj_info = new planner::ProjectInfo(planner::ProjectInfo::TargetList(),
                                            std::move(direct_map_list));

  // 3) Set up unique aggregates
  std::vector<planner::AggregateV2Node::AggTerm> agg_terms;
  planner::AggregateV2Node::AggTerm sumb = std::make_pair(
      EXPRESSION_TYPE_AGGREGATE_SUM, expression::TupleValueFactory(0, 1));
  agg_terms.push_back(sumb);

  // 4) Set up predicate (empty)
  expression::AbstractExpression* predicate = nullptr;

  // 5) Create output table schema
  auto data_table_schema = data_table.get()->GetSchema();
  std::vector<oid_t> set = { 0, 1 };
  std::vector<catalog::Column> columns;
  for (auto column_index : set) {
    columns.push_back(data_table_schema->GetColumn(column_index));
  }
  auto output_table_schema = new catalog::Schema(columns);

  // OK) Create the plan node
  planner::AggregateV2Node node(proj_info, predicate, std::move(agg_terms),
                                std::move(group_by_columns),
                                output_table_schema);

  // Create and set up executor
  auto &txn_manager = concurrency::TransactionManager::GetInstance();
  auto txn = txn_manager.BeginTransaction();
  std::unique_ptr<executor::ExecutorContext> context(
      new executor::ExecutorContext(txn));

  executor::AggregateExecutor executor(&node, context.get());
  MockExecutor child_executor;
  executor.AddChild(&child_executor);

  EXPECT_CALL(child_executor, DInit()).WillOnce(Return(true));

  EXPECT_CALL(child_executor, DExecute()).WillOnce(Return(true)).WillOnce(
      Return(true)).WillOnce(Return(false));

  EXPECT_CALL(child_executor, GetOutput()).WillOnce(
      Return(source_logical_tile1.release())).WillOnce(
      Return(source_logical_tile2.release()));

  EXPECT_TRUE(executor.Init());

  EXPECT_TRUE(executor.Execute());

  txn_manager.CommitTransaction(txn);
}

TEST(AggregateTests, SumMaxGroupByTest) {
  /*
   * SELECT a, SUM(b), MAX(c) from table GROUP BY a;
   */
  const int tuple_count = TESTS_TUPLES_PER_TILEGROUP;

  // Create a table and wrap it in logical tiles
  std::unique_ptr<storage::DataTable> data_table(
      ExecutorTestsUtil::CreateTable(tuple_count, false));
  ExecutorTestsUtil::PopulateTable(data_table.get(), 2 * tuple_count, false,
  false,
                                   true);

  std::unique_ptr<executor::LogicalTile> source_logical_tile1(
      executor::LogicalTileFactory::WrapTileGroup(data_table->GetTileGroup(0)));

  std::unique_ptr<executor::LogicalTile> source_logical_tile2(
      executor::LogicalTileFactory::WrapTileGroup(data_table->GetTileGroup(1)));

  // (1-5) Setup plan node

  // 1) Set up group-by columns
  std::vector<oid_t> group_by_columns = { 0 };

  // 2) Set up project info
  planner::ProjectInfo::DirectMapList direct_map_list = { { 0, { 0, 0 } }, { 1,
      { 1, 0 } }, { 2, { 1, 1 } } };

  auto proj_info = new planner::ProjectInfo(planner::ProjectInfo::TargetList(),
                                            std::move(direct_map_list));

  // 3) Set up unique aggregates
  std::vector<planner::AggregateV2Node::AggTerm> agg_terms;
  planner::AggregateV2Node::AggTerm sumb = std::make_pair(
      EXPRESSION_TYPE_AGGREGATE_SUM, expression::TupleValueFactory(0, 1));
  planner::AggregateV2Node::AggTerm maxc = std::make_pair(
      EXPRESSION_TYPE_AGGREGATE_MAX, expression::TupleValueFactory(0, 2));
  agg_terms.push_back(sumb);
  agg_terms.push_back(maxc);

  // 4) Set up predicate (empty)
  expression::AbstractExpression* predicate = nullptr;

  // 5) Create output table schema
  auto data_table_schema = data_table.get()->GetSchema();
  std::vector<oid_t> set = { 0, 1, 2 };
  std::vector<catalog::Column> columns;
  for (auto column_index : set) {
    columns.push_back(data_table_schema->GetColumn(column_index));
  }
  auto output_table_schema = new catalog::Schema(columns);

  // OK) Create the plan node
  planner::AggregateV2Node node(proj_info, predicate, std::move(agg_terms),
                                std::move(group_by_columns),
                                output_table_schema);

  // Create and set up executor
  auto &txn_manager = concurrency::TransactionManager::GetInstance();
  auto txn = txn_manager.BeginTransaction();
  std::unique_ptr<executor::ExecutorContext> context(
      new executor::ExecutorContext(txn));

  executor::AggregateExecutor executor(&node, context.get());
  MockExecutor child_executor;
  executor.AddChild(&child_executor);

  EXPECT_CALL(child_executor, DInit()).WillOnce(Return(true));

  EXPECT_CALL(child_executor, DExecute()).WillOnce(Return(true)).WillOnce(
      Return(true)).WillOnce(Return(false));

  EXPECT_CALL(child_executor, GetOutput()).WillOnce(
      Return(source_logical_tile1.release())).WillOnce(
      Return(source_logical_tile2.release()));

  EXPECT_TRUE(executor.Init());

  EXPECT_TRUE(executor.Execute());

  txn_manager.CommitTransaction(txn);
}

/*
 TEST(AggregateTests, AggregateTest) {
 const int tuple_count = TESTS_TUPLES_PER_TILEGROUP;

 // Create a table and wrap it in logical tiles
 std::unique_ptr<storage::DataTable> data_table(
 ExecutorTestsUtil::CreateTable(tuple_count, false));
 ExecutorTestsUtil::PopulateTable(data_table.get(), 2 * tuple_count, false,
 false, true);

 std::unique_ptr<executor::LogicalTile> source_logical_tile1(
 executor::LogicalTileFactory::WrapTileGroup(data_table->GetTileGroup(0)));

 std::unique_ptr<executor::LogicalTile> source_logical_tile2(
 executor::LogicalTileFactory::WrapTileGroup(data_table->GetTileGroup(1)));

 // Setup plan node

 std::vector<oid_t> group_by_columns = {0, 1};
 std::map<oid_t, oid_t> pass_through_columns_map;

 // Input tuple column index -> Output tuple column index
 pass_through_columns_map[0] = 0;
 pass_through_columns_map[1] = 1;

 // Aggregates
 std::vector<oid_t> aggregate_columns = {2, 2};
 std::map<oid_t, oid_t> aggregate_columns_map;

 // Input tuple column index -> Output tuple column index
 aggregate_columns_map[0] = 2;
 aggregate_columns_map[1] = 3;

 std::vector<ExpressionType> aggregate_types;
 aggregate_types.push_back(EXPRESSION_TYPE_AGGREGATE_SUM);
 aggregate_types.push_back(EXPRESSION_TYPE_AGGREGATE_AVG);

 // More complex schema construction
 auto data_table_schema = data_table.get()->GetSchema();
 std::vector<oid_t> set = {0, 1, 2, 2};
 std::vector<catalog::Column> columns;
 for (auto column_index : set) {
 columns.push_back(data_table_schema->GetColumn(column_index));
 }

 auto output_table_schema = new catalog::Schema(columns);

 // Create the plan node
 planner::AggregateNode node(
 aggregate_columns, aggregate_columns_map, group_by_columns, nullptr,
 pass_through_columns_map, aggregate_types, output_table_schema);

 // Create and set up executor
 auto &txn_manager = concurrency::TransactionManager::GetInstance();
 auto txn = txn_manager.BeginTransaction();
 std::unique_ptr<executor::ExecutorContext> context(
 new executor::ExecutorContext(txn));

 executor::AggregateExecutor executor(&node, context.get());
 MockExecutor child_executor;
 executor.AddChild(&child_executor);

 EXPECT_CALL(child_executor, DInit()).WillOnce(Return(true));

 EXPECT_CALL(child_executor, DExecute())
 .WillOnce(Return(true))
 .WillOnce(Return(true))
 .WillOnce(Return(false));

 EXPECT_CALL(child_executor, GetOutput())
 .WillOnce(Return(source_logical_tile1.release()))
 .WillOnce(Return(source_logical_tile2.release()));

 EXPECT_TRUE(executor.Init());

 EXPECT_TRUE(executor.Execute());

 std::unique_ptr<executor::LogicalTile> logical_tile(executor.GetOutput());
 EXPECT_TRUE(logical_tile.get() != nullptr);

 EXPECT_TRUE(logical_tile.get()->GetValue(0, 2) ==
 ValueFactory::GetDoubleValue(110));
 EXPECT_TRUE(logical_tile.get()->GetValue(1, 2) ==
 ValueFactory::GetDoubleValue(360));
 EXPECT_TRUE(logical_tile.get()->GetValue(0, 3) ==
 ValueFactory::GetDoubleValue(22));
 EXPECT_TRUE(logical_tile.get()->GetValue(1, 3) ==
 ValueFactory::GetDoubleValue(72));

 txn_manager.CommitTransaction(txn);
 }

 */

}  // namespace test
}  // namespace peloton
<commit_msg>Add EXPECT_TRUE in aggregate_test.<commit_after>//===----------------------------------------------------------------------===//
//
//                         PelotonDB
//
// aggregate_test.cpp
//
// Identification: tests/executor/aggregate_test.cpp
//
// Copyright (c) 2015, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include <memory>
#include <set>
#include <string>
#include <vector>

#include "gmock/gmock.h"
#include "gtest/gtest.h"

#include "backend/common/types.h"
#include "backend/common/value.h"
#include "backend/executor/logical_tile.h"
#include "backend/executor/aggregate_executor.h"
#include "backend/executor/logical_tile_factory.h"
#include "backend/expression/expression_util.h"
#include "backend/planner/abstract_plan_node.h"
#include "backend/planner/aggregateV2_node.h"
#include "backend/storage/data_table.h"

#include "executor/executor_tests_util.h"
#include "executor/mock_executor.h"
#include "harness.h"

using ::testing::NotNull;
using ::testing::Return;

namespace peloton {
namespace test {

TEST(AggregateTests, DistinctTest) {

  /*
   * SELECT d, a, b, c FROM table GROUP BY a, b, c, d;
   */

  const int tuple_count = TESTS_TUPLES_PER_TILEGROUP;

  // Create a table and wrap it in logical tiles
  std::unique_ptr<storage::DataTable> data_table(
      ExecutorTestsUtil::CreateTable(tuple_count, false));
  ExecutorTestsUtil::PopulateTable(data_table.get(), 2*tuple_count, false, false, true);

  std::unique_ptr<executor::LogicalTile> source_logical_tile1(
      executor::LogicalTileFactory::WrapTileGroup(data_table->GetTileGroup(0)));

  std::unique_ptr<executor::LogicalTile> source_logical_tile2(
      executor::LogicalTileFactory::WrapTileGroup(data_table->GetTileGroup(1)));

  // (1-5) Setup plan node

  // 1) Set up group-by columns
  std::vector<oid_t> group_by_columns = { 0, 1, 2, 3 };

  // 2) Set up project info
  planner::ProjectInfo::DirectMapList direct_map_list = { { 0, { 0, 3 } }, { 1,
      { 0, 0 } }, { 2, { 0, 1 } }, { 3, { 0, 2 } } };
  auto proj_info = new planner::ProjectInfo(planner::ProjectInfo::TargetList(),
                                            std::move(direct_map_list));

  // 3) Set up unique aggregates (empty)
  std::vector<planner::AggregateV2Node::AggTerm> agg_terms;

  // 4) Set up predicate (empty)
  expression::AbstractExpression* predicate = nullptr;

  // 5) Create output table schema
  auto data_table_schema = data_table.get()->GetSchema();
  std::vector<oid_t> set = { 3, 0, 1, 2 };
  std::vector<catalog::Column> columns;
  for (auto column_index : set) {
    columns.push_back(data_table_schema->GetColumn(column_index));
  }

  auto output_table_schema = new catalog::Schema(columns);

  // OK) Create the plan node
  planner::AggregateV2Node node(proj_info, predicate, std::move(agg_terms),
                                std::move(group_by_columns),
                                output_table_schema);

  // Create and set up executor
  auto &txn_manager = concurrency::TransactionManager::GetInstance();
  auto txn = txn_manager.BeginTransaction();
  std::unique_ptr<executor::ExecutorContext> context(
      new executor::ExecutorContext(txn));

  executor::AggregateExecutor executor(&node, context.get());
  MockExecutor child_executor;
  executor.AddChild(&child_executor);

  EXPECT_CALL(child_executor, DInit()).WillOnce(Return(true));

  EXPECT_CALL(child_executor, DExecute()).WillOnce(Return(true)).WillOnce(
      Return(true)).WillOnce(Return(false));

  EXPECT_CALL(child_executor, GetOutput()).WillOnce(
      Return(source_logical_tile1.release())).WillOnce(
      Return(source_logical_tile2.release()));

  EXPECT_TRUE(executor.Init());

  EXPECT_TRUE(executor.Execute());
  txn_manager.CommitTransaction(txn);

  /* Verify result */
  std::unique_ptr<executor::LogicalTile> result_tile(executor.GetOutput());
  EXPECT_TRUE(result_tile.get() != nullptr);

  EXPECT_TRUE(result_tile->GetValue(0, 2).OpEquals(ValueFactory::GetIntegerValue(1)).IsTrue());
  EXPECT_TRUE(result_tile->GetValue(0, 3).OpEquals(ValueFactory::GetDoubleValue(2)).IsTrue());
  EXPECT_TRUE(result_tile->GetValue(5, 2).OpEquals(ValueFactory::GetIntegerValue(51)).IsTrue());
  EXPECT_TRUE(result_tile->GetValue(5, 3).OpEquals(ValueFactory::GetDoubleValue(52)).IsTrue());

}

TEST(AggregateTests, SumGroupByTest) {
  /*
   * SELECT a, SUM(b) from table GROUP BY a;
   */
  const int tuple_count = TESTS_TUPLES_PER_TILEGROUP;

  // Create a table and wrap it in logical tiles
  std::unique_ptr<storage::DataTable> data_table(
      ExecutorTestsUtil::CreateTable(tuple_count, false));
  ExecutorTestsUtil::PopulateTable(data_table.get(), 2*tuple_count, false,
  false,
                                   true);

  std::unique_ptr<executor::LogicalTile> source_logical_tile1(
      executor::LogicalTileFactory::WrapTileGroup(data_table->GetTileGroup(0)));

  std::unique_ptr<executor::LogicalTile> source_logical_tile2(
      executor::LogicalTileFactory::WrapTileGroup(data_table->GetTileGroup(1)));

  // (1-5) Setup plan node

  // 1) Set up group-by columns
  std::vector<oid_t> group_by_columns = { 0 };

  // 2) Set up project info
  planner::ProjectInfo::DirectMapList direct_map_list = { { 0, { 0, 0 } }, { 1,
      { 1, 0 } } };

  auto proj_info = new planner::ProjectInfo(planner::ProjectInfo::TargetList(),
                                            std::move(direct_map_list));

  // 3) Set up unique aggregates
  std::vector<planner::AggregateV2Node::AggTerm> agg_terms;
  planner::AggregateV2Node::AggTerm sumb = std::make_pair(
      EXPRESSION_TYPE_AGGREGATE_SUM, expression::TupleValueFactory(0, 1));
  agg_terms.push_back(sumb);

  // 4) Set up predicate (empty)
  expression::AbstractExpression* predicate = nullptr;

  // 5) Create output table schema
  auto data_table_schema = data_table.get()->GetSchema();
  std::vector<oid_t> set = { 0, 1 };
  std::vector<catalog::Column> columns;
  for (auto column_index : set) {
    columns.push_back(data_table_schema->GetColumn(column_index));
  }
  auto output_table_schema = new catalog::Schema(columns);

  // OK) Create the plan node
  planner::AggregateV2Node node(proj_info, predicate, std::move(agg_terms),
                                std::move(group_by_columns),
                                output_table_schema);

  // Create and set up executor
  auto &txn_manager = concurrency::TransactionManager::GetInstance();
  auto txn = txn_manager.BeginTransaction();
  std::unique_ptr<executor::ExecutorContext> context(
      new executor::ExecutorContext(txn));

  executor::AggregateExecutor executor(&node, context.get());
  MockExecutor child_executor;
  executor.AddChild(&child_executor);

  EXPECT_CALL(child_executor, DInit()).WillOnce(Return(true));

  EXPECT_CALL(child_executor, DExecute()).WillOnce(Return(true)).WillOnce(
      Return(true)).WillOnce(Return(false));

  EXPECT_CALL(child_executor, GetOutput()).WillOnce(
      Return(source_logical_tile1.release())).WillOnce(
      Return(source_logical_tile2.release()));

  EXPECT_TRUE(executor.Init());

  EXPECT_TRUE(executor.Execute());

  txn_manager.CommitTransaction(txn);

  /* Verify result */
  std::unique_ptr<executor::LogicalTile> result_tile(executor.GetOutput());
  EXPECT_TRUE(result_tile.get() != nullptr);
  EXPECT_TRUE(result_tile->GetValue(0, 0).OpEquals(ValueFactory::GetIntegerValue(0)).IsTrue());
  EXPECT_TRUE(result_tile->GetValue(0, 1).OpEquals(ValueFactory::GetIntegerValue(460)).IsTrue());
}

TEST(AggregateTests, SumMaxGroupByTest) {
  /*
   * SELECT a, SUM(b), MAX(c) from table GROUP BY a;
   */
  const int tuple_count = TESTS_TUPLES_PER_TILEGROUP;

  // Create a table and wrap it in logical tiles
  std::unique_ptr<storage::DataTable> data_table(
      ExecutorTestsUtil::CreateTable(tuple_count, false));
  ExecutorTestsUtil::PopulateTable(data_table.get(), 2 * tuple_count, false,
  false,
                                   true);

  std::unique_ptr<executor::LogicalTile> source_logical_tile1(
      executor::LogicalTileFactory::WrapTileGroup(data_table->GetTileGroup(0)));

  std::unique_ptr<executor::LogicalTile> source_logical_tile2(
      executor::LogicalTileFactory::WrapTileGroup(data_table->GetTileGroup(1)));

  // (1-5) Setup plan node

  // 1) Set up group-by columns
  std::vector<oid_t> group_by_columns = { 0 };

  // 2) Set up project info
  planner::ProjectInfo::DirectMapList direct_map_list = { { 0, { 0, 0 } }, { 1,
      { 1, 0 } }, { 2, { 1, 1 } } };

  auto proj_info = new planner::ProjectInfo(planner::ProjectInfo::TargetList(),
                                            std::move(direct_map_list));

  // 3) Set up unique aggregates
  std::vector<planner::AggregateV2Node::AggTerm> agg_terms;
  planner::AggregateV2Node::AggTerm sumb = std::make_pair(
      EXPRESSION_TYPE_AGGREGATE_SUM, expression::TupleValueFactory(0, 1));
  planner::AggregateV2Node::AggTerm maxc = std::make_pair(
      EXPRESSION_TYPE_AGGREGATE_MAX, expression::TupleValueFactory(0, 2));
  agg_terms.push_back(sumb);
  agg_terms.push_back(maxc);

  // 4) Set up predicate (empty)
  expression::AbstractExpression* predicate = nullptr;

  // 5) Create output table schema
  auto data_table_schema = data_table.get()->GetSchema();
  std::vector<oid_t> set = { 0, 1, 2 };
  std::vector<catalog::Column> columns;
  for (auto column_index : set) {
    columns.push_back(data_table_schema->GetColumn(column_index));
  }
  auto output_table_schema = new catalog::Schema(columns);

  // OK) Create the plan node
  planner::AggregateV2Node node(proj_info, predicate, std::move(agg_terms),
                                std::move(group_by_columns),
                                output_table_schema);

  // Create and set up executor
  auto &txn_manager = concurrency::TransactionManager::GetInstance();
  auto txn = txn_manager.BeginTransaction();
  std::unique_ptr<executor::ExecutorContext> context(
      new executor::ExecutorContext(txn));

  executor::AggregateExecutor executor(&node, context.get());
  MockExecutor child_executor;
  executor.AddChild(&child_executor);

  EXPECT_CALL(child_executor, DInit()).WillOnce(Return(true));

  EXPECT_CALL(child_executor, DExecute()).WillOnce(Return(true)).WillOnce(
      Return(true)).WillOnce(Return(false));

  EXPECT_CALL(child_executor, GetOutput()).WillOnce(
      Return(source_logical_tile1.release())).WillOnce(
      Return(source_logical_tile2.release()));

  EXPECT_TRUE(executor.Init());

  EXPECT_TRUE(executor.Execute());

  txn_manager.CommitTransaction(txn);

  /* Verify result */
  std::unique_ptr<executor::LogicalTile> result_tile(executor.GetOutput());
  EXPECT_TRUE(result_tile.get() != nullptr);
  EXPECT_TRUE(result_tile->GetValue(0, 0).OpEquals(ValueFactory::GetIntegerValue(0)).IsTrue());
  EXPECT_TRUE(result_tile->GetValue(0, 1).OpEquals(ValueFactory::GetIntegerValue(460)).IsTrue());
  EXPECT_TRUE(result_tile->GetValue(0, 2).OpEquals(ValueFactory::GetDoubleValue(92)).IsTrue());
}

}  // namespace test
}  // namespace peloton
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015-2016 Pavel Dolgov
 *
 * See the LICENSE file for terms of use.
 */

#include <bits/stdc++.h>

struct Foo {
public:
    Foo() {
        std::cout << "Foo's constructor." << std::endl;
    }

    ~Foo() {
        std::cout << "Foo's destructor." << std::endl;
    }
};

template<typename T>
class SharedPtr {
private:
    struct Storage {
        int counter;
        T* obj;
    };

    Storage* storage_;

public:
    SharedPtr():
        storage_(0) {
        reset();
    }

    explicit SharedPtr(T* obj):
        storage_(0) {
        reset(obj);
    }

    SharedPtr(const SharedPtr& ptr):
        storage_(0) {
        reset(ptr);
    }

    ~SharedPtr() {
        reset();
    }

    bool empty() {
        return storage_ == 0;
    }

    void reset() {
        if (storage_ != 0) {
            storage_->counter -= 1;
            if (storage_->counter == 0) {
                delete storage_->obj;
                delete storage_;
            }
            storage_ = 0;
        }
    }

    void reset(T* t) {
        reset();
        if (t != 0) {
            storage_ = new Storage();
            storage_->obj = t;
            storage_->counter = 1;
        }
    }

    void reset(const SharedPtr& ptr) {
        reset();
        if (ptr.storage_ != 0) {
            storage_ = ptr.storage_;
            storage_->counter += 1;
        }
    }

    SharedPtr& operator=(const SharedPtr& ptr) {
        reset(ptr);
        return *this;
    }
};

int main() {
    std::cout << "zer0main's shared pointer" << std::endl;
    SharedPtr<Foo> foo_ptr = SharedPtr<Foo>(new Foo());
    std::cout << "foo_ptr is empty: " << foo_ptr.empty() << std::endl;
    SharedPtr<Foo> foo_ptr2 = foo_ptr;
    std::cout << "foo_ptr is empty: " << foo_ptr.empty() << std::endl;
    foo_ptr.reset();
    std::cout << "foo_ptr is empty: " << foo_ptr.empty() << std::endl;
    foo_ptr.reset(new Foo());
    std::cout << "foo_ptr is empty: " << foo_ptr.empty() << std::endl;
    foo_ptr.reset(foo_ptr2);
    SharedPtr<Foo> foo_ptr3;
    std::cout << "foo_ptr3 is empty: " << foo_ptr3.empty() << std::endl;
    foo_ptr3 = foo_ptr2;
    std::cout << "foo_ptr3 is empty: " << foo_ptr3.empty() << std::endl;
    return 0;
}
<commit_msg>makeShared() function<commit_after>/*
 * Copyright (C) 2015-2016 Pavel Dolgov
 *
 * See the LICENSE file for terms of use.
 */

#include <bits/stdc++.h>

struct Foo {
public:
    Foo() {
        std::cout << "Foo's constructor." << std::endl;
    }

    Foo(int n) {
        std::cout << "Foo's int constructor." << std::endl;
    }

    ~Foo() {
        std::cout << "Foo's destructor." << std::endl;
    }
};

template<typename T>
class SharedPtr {
private:
    struct Storage {
        int counter;
        T* obj;
    };

    Storage* storage_;

public:
    SharedPtr():
        storage_(0) {
        reset();
    }

    explicit SharedPtr(T* obj):
        storage_(0) {
        reset(obj);
    }

    SharedPtr(const SharedPtr& ptr):
        storage_(0) {
        reset(ptr);
    }

    ~SharedPtr() {
        reset();
    }

    bool empty() {
        return storage_ == 0;
    }

    void reset() {
        if (storage_ != 0) {
            storage_->counter -= 1;
            if (storage_->counter == 0) {
                delete storage_->obj;
                delete storage_;
            }
            storage_ = 0;
        }
    }

    void reset(T* t) {
        reset();
        if (t != 0) {
            storage_ = new Storage();
            storage_->obj = t;
            storage_->counter = 1;
        }
    }

    void reset(const SharedPtr& ptr) {
        reset();
        if (ptr.storage_ != 0) {
            storage_ = ptr.storage_;
            storage_->counter += 1;
        }
    }

    SharedPtr& operator=(const SharedPtr& ptr) {
        reset(ptr);
        return *this;
    }
};

template<typename D>
SharedPtr<D> makeShared(int arg) {
    SharedPtr<D> ptr = SharedPtr<Foo>(new D(arg));
    return ptr;
}

int main() {
    std::cout << "zer0main's shared pointer" << std::endl;
    SharedPtr<Foo> foo_ptr = SharedPtr<Foo>(new Foo());
    std::cout << "foo_ptr is empty: " << foo_ptr.empty() << std::endl;
    SharedPtr<Foo> foo_ptr2 = foo_ptr;
    std::cout << "foo_ptr is empty: " << foo_ptr.empty() << std::endl;
    foo_ptr.reset();
    std::cout << "foo_ptr is empty: " << foo_ptr.empty() << std::endl;
    foo_ptr.reset(new Foo());
    std::cout << "foo_ptr is empty: " << foo_ptr.empty() << std::endl;
    foo_ptr.reset(foo_ptr2);
    SharedPtr<Foo> foo_ptr3;
    std::cout << "foo_ptr3 is empty: " << foo_ptr3.empty() << std::endl;
    foo_ptr3 = foo_ptr2;
    std::cout << "foo_ptr3 is empty: " << foo_ptr3.empty() << std::endl;
    SharedPtr<Foo> foo_ptr4 = makeShared<Foo>(2);
    std::cout << "foo_ptr4 is empty: " << foo_ptr4.empty() << std::endl;
    return 0;
}
<|endoftext|>


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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkFEMElement_test.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "itkFEMElement_test.h"
#include "itkFEMCell.h"

namespace itk {
namespace fem {

void FEMElement::LinkDOFs(void)
{
  // Release any existing dofs that the element may be using.
  ClearDOFs();

  // Step over all elements in the neighborhood.
  for(int el=0;el<2;el++) // FIXME: we need to change this to use proper functions
  {
    // c should be set so that it points to a cell object in the neighborhood
    FEMCell<2>* c=0;

    // Same thing except that here we store a pointer to an Element
    // object.This is to limit the the use of dynamic_cast operator.
    FEMElement* e=dynamic_cast<FEMElement*>(c);

    // Cast this pointer to FEMCell. If it doesn't work, somebody used the wrong elements...
    FEMCell<2>* this_cell=dynamic_cast<FEMCell<2>*>(this);

    if( e==0 ) // Check if the cell object was of corerct class.
    {
      throw; // Nope. Start yelling...
    }

    // Find the shared point in the neighboring object
    for( int i=0;i<this_cell->GetNumberOfPoints();i++ ) // Step over all points in current cell
    {
      // check if point j of the neighboring cell is shared with the point i of the current cell
      for( int j=0;j<c->GetNumberOfPoints();j++ ) // Step over all points in the neighbor cell
      {
        if( this_cell->GetPoint(i) == c->GetPoint(j) )
        {
          // Yes. Copy the DOFs from the neighboring cell's point
          // since they have to be the same. Note that neighboring point
          // may contain more or less DOFs. If it has more, we simply ignore
          // the rest, if it has less, we'll get invalid DOF id from GetDOF
          // function.
          for(unsigned int d=0;d<this->NumberOfDegreesOfFreedom();d++)
          {
            // get the DOF from the point at neighboring element
            DOFType dof = e->GetDOFatPoint(j,d);

            // set the corresponding DOF in current element
            this->SetDOF(i,dof);

          } // end for d

          // once we find one valid shared point, we  can exit the loop over points of the neighbor cell
          break;

        } // end if

      } // end for j

      // Now all DOFs in current object for point i are matched with those
      // in the neghboring elements. However, if none of the neighboring
      // objects defines these DOFs, we need to create them.
      for(unsigned int d=0;d<NumberOfDegreesOfFreedom();d++) // step over all DOFs at point i
      {
        if(this->GetDOF(d)<0)
        {
          /*
           * Found a undefined DOF. We need either to create a new DOF object,
           * or obtain a unique id, which we'll set with the SetDOF function.
           */
          SetDOF(d,1 /* new dof id */);
        }

      }

    } // end for i

  } // end for el

}

}} // end namespace itk::fem
<commit_msg>enh: minor changes<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkFEMElement_test.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "itkFEMElement_test.h"
#include "itkFEMCell.h"

namespace itk {
namespace fem {

void FEMElement::LinkDOFs(void)
{
  // Release any existing dofs that the element may be using.
  ClearDOFs();

  // Step over all elements in the neighborhood.
  for(int el=0;el<2;el++) // FIXME: we need to change this to use proper functions
  {
    // c should be set so that it points to a cell object in the neighborhood
    FEMCell<2>* c=0;

    // Same thing except that here we store a pointer to an Element
    // object.This is to limit the the use of dynamic_cast operator.
    FEMElement* e=dynamic_cast<FEMElement*>(c);

    // Cast this pointer to FEMCell. If it doesn't work, somebody used the wrong elements...
    FEMCell<2>* this_cell=dynamic_cast<FEMCell<2>*>(this);

    if( e==0 ) // Check if the cell object was of corerct class.
    {
      throw; // Nope. Start yelling...
    }

    // Find the shared point in the neighboring object
    for( int i=0;i<this_cell->GetNumberOfPoints();i++ ) // Step over all points in current cell
    {
      // check if point j of the neighboring cell is shared with the point i of the current cell
      for( int j=0;j<c->GetNumberOfPoints();j++ ) // Step over all points in the neighbor cell
      {
        if( this_cell->GetPoint(i) == c->GetPoint(j) )
        {
          // Yes. Copy the DOFs from the neighboring cell's point
          // since they have to be the same. Note that neighboring point
          // may contain more or less DOFs. If it has more, we simply ignore
          // the rest, if it has less, we'll get invalid DOF id from GetDOFatPoint
          // function.
          for(unsigned int d=0;d<this->NumberOfDegreesOfFreedom();d++)
          {
            // get the DOF from the point at neighboring element
            DOFType dof = e->GetDOFatPoint(j,d);

            // set the corresponding DOF in current element
            this->SetDOF(i,dof);

          } // end for d

          // once we find one valid shared point, we  can exit the loop over points of the neighbor cell
          break;

        } // end if

      } // end for j

      // Now all DOFs in current object for point i are matched with those
      // in the neghboring elements. However, if none of the neighboring
      // objects defines these DOFs, we need to create them.
      for(unsigned int d=0;d<NumberOfDegreesOfFreedom();d++) // step over all DOFs at point i
      {
        if(this->GetDOF(d)<0)
        {
          /*
           * Found a undefined DOF. We need either to create a new DOF object,
           * or obtain a unique id, which we'll set with the SetDOF function.
           */
          SetDOF(d,1 /* new dof id */);
        }

      }

    } // end for i

  } // end for el

}

}} // end namespace itk::fem
<|endoftext|>


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

#include <string>

#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/test/test_server.h"

namespace {

const FilePath::CharType kDocRoot[] = FILE_PATH_LITERAL("chrome/test/data");

}  // namespace

typedef UITest CollectedCookiesTest;

// Crashing on Windows, see http://crbug.com/79331
#if defined(OS_WINDOWS)
#define MAYBE_DoubleDisplay DISABLED_DoubleDisplay
#else
#define MAYBE_DoubleDisplay DoubleDisplay
#endif
TEST_F(CollectedCookiesTest, MAYBE_DoubleDisplay) {
  net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  scoped_refptr<TabProxy> tab(browser->GetTab(0));
  ASSERT_TRUE(tab.get());

  // Disable cookies.
  ASSERT_TRUE(browser->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_COOKIES,
                                                CONTENT_SETTING_BLOCK));

  // Load a page with cookies.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("files/cookie1.html")));

  // Click on the info link twice.
  ASSERT_TRUE(tab->ShowCollectedCookiesDialog());
  ASSERT_TRUE(tab->ShowCollectedCookiesDialog());
}

// Crashing on Windows, see http://crbug.com/79331
#if defined(OS_WINDOWS)
#define MAYBE_NavigateAway DISABLED_NavigateAway
#else
#define MAYBE_NavigateAway NavigateAway
#endif
TEST_F(CollectedCookiesTest, MAYBE_NavigateAway) {
  net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  scoped_refptr<TabProxy> tab(browser->GetTab(0));
  ASSERT_TRUE(tab.get());

  // Disable cookies.
  ASSERT_TRUE(browser->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_COOKIES,
                                                CONTENT_SETTING_BLOCK));

  // Load a page with cookies.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("files/cookie1.html")));

  // Click on the info link.
  ASSERT_TRUE(tab->ShowCollectedCookiesDialog());

  // Navigate to another page.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("files/cookie2.html")));
}
<commit_msg>Fix errant #ifdef from previous change to really disable tests on Windows.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>

#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/test/test_server.h"

namespace {

const FilePath::CharType kDocRoot[] = FILE_PATH_LITERAL("chrome/test/data");

}  // namespace

typedef UITest CollectedCookiesTest;

// Crashing on Windows, see http://crbug.com/79331
#if defined(OS_WIN)
#define MAYBE_DoubleDisplay DISABLED_DoubleDisplay
#else
#define MAYBE_DoubleDisplay DoubleDisplay
#endif
TEST_F(CollectedCookiesTest, MAYBE_DoubleDisplay) {
  net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  scoped_refptr<TabProxy> tab(browser->GetTab(0));
  ASSERT_TRUE(tab.get());

  // Disable cookies.
  ASSERT_TRUE(browser->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_COOKIES,
                                                CONTENT_SETTING_BLOCK));

  // Load a page with cookies.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("files/cookie1.html")));

  // Click on the info link twice.
  ASSERT_TRUE(tab->ShowCollectedCookiesDialog());
  ASSERT_TRUE(tab->ShowCollectedCookiesDialog());
}

// Crashing on Windows, see http://crbug.com/79331
#if defined(OS_WIN)
#define MAYBE_NavigateAway DISABLED_NavigateAway
#else
#define MAYBE_NavigateAway NavigateAway
#endif
TEST_F(CollectedCookiesTest, MAYBE_NavigateAway) {
  net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  scoped_refptr<TabProxy> tab(browser->GetTab(0));
  ASSERT_TRUE(tab.get());

  // Disable cookies.
  ASSERT_TRUE(browser->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_COOKIES,
                                                CONTENT_SETTING_BLOCK));

  // Load a page with cookies.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("files/cookie1.html")));

  // Click on the info link.
  ASSERT_TRUE(tab->ShowCollectedCookiesDialog());

  // Navigate to another page.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("files/cookie2.html")));
}
<|endoftext|>


<commit_before>//
// Created by Rui Wang on 16-4-30.
//

#include "gtest/gtest.h"
#include "harness.h"

#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include <chrono>
#include <iostream>
#include <ctime>
#include <cassert>
#include <backend/planner/hybrid_scan_plan.h>
#include <backend/executor/hybrid_scan_executor.h>

#include "backend/catalog/manager.h"
#include "backend/catalog/schema.h"
#include "backend/concurrency/transaction.h"
#include "backend/concurrency/transaction_manager_factory.h"
#include "backend/common/timer.h"
#include "backend/executor/abstract_executor.h"
#include "backend/executor/insert_executor.h"
#include "backend/index/index_factory.h"
#include "backend/planner/insert_plan.h"
#include "backend/storage/tile.h"
#include "backend/storage/tile_group.h"
#include "backend/storage/data_table.h"
#include "backend/storage/table_factory.h"
#include "backend/expression/expression_util.h"
#include "backend/expression/abstract_expression.h"
#include "backend/expression/constant_value_expression.h"
#include "backend/expression/tuple_value_expression.h"
#include "backend/expression/comparison_expression.h"
#include "backend/expression/conjunction_expression.h"

#include "backend/index/index_factory.h"

namespace peloton {
namespace test {

class HybridIndexTests : public PelotonTest {};

static double projectivity = 1.0;
static int columncount = 4;
static size_t tuples_per_tile_group = 10;
static size_t tile_group = 10;

void CreateTable(std::unique_ptr<storage::DataTable>& hyadapt_table, bool indexes) {
  oid_t column_count = projectivity * columncount;

  const oid_t col_count = column_count + 1;
  const bool is_inlined = true;

  // Create schema first
  std::vector<catalog::Column> columns;

  for (oid_t col_itr = 0; col_itr < col_count; col_itr++) {
    auto column =
      catalog::Column(VALUE_TYPE_INTEGER, GetTypeSize(VALUE_TYPE_INTEGER),
                      "" + std::to_string(col_itr), is_inlined);

    columns.push_back(column);
  }

  catalog::Schema *table_schema = new catalog::Schema(columns);
  std::string table_name("HYADAPTTABLE");

  /////////////////////////////////////////////////////////
  // Create table.
  /////////////////////////////////////////////////////////

  bool own_schema = true;
  bool adapt_table = true;
  hyadapt_table.reset(storage::TableFactory::GetDataTable(
    INVALID_OID, INVALID_OID, table_schema, table_name,
    tuples_per_tile_group, own_schema, adapt_table));

  // PRIMARY INDEX
  if (indexes == true) {
    std::vector<oid_t> key_attrs;

    auto tuple_schema = hyadapt_table->GetSchema();
    catalog::Schema *key_schema;
    index::IndexMetadata *index_metadata;
    bool unique;

    key_attrs = {0};
    key_schema = catalog::Schema::CopySchema(tuple_schema, key_attrs);
    key_schema->SetIndexedColumns(key_attrs);

    unique = true;

    index_metadata = new index::IndexMetadata(
      "primary_index", 123, INDEX_TYPE_BTREE,
      INDEX_CONSTRAINT_TYPE_PRIMARY_KEY, tuple_schema, key_schema, unique);

    index::Index *pkey_index = index::IndexFactory::GetInstance(index_metadata);
    hyadapt_table->AddIndex(pkey_index);
  }
}

void LoadTable(std::unique_ptr<storage::DataTable>& hyadapt_table) {
  oid_t column_count = projectivity * columncount;
  const oid_t col_count = column_count + 1;
  const int tuple_count = tile_group * tuples_per_tile_group;

  auto table_schema = hyadapt_table->GetSchema();

  /////////////////////////////////////////////////////////
  // Load in the data
  /////////////////////////////////////////////////////////

  // Insert tuples into tile_group.
  auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
  const bool allocate = true;
  auto txn = txn_manager.BeginTransaction();
  std::unique_ptr<VarlenPool> pool(new VarlenPool(BACKEND_TYPE_MM));

  int rowid;
  for (rowid = 0; rowid < tuple_count; rowid++) {
    int populate_value = rowid;

    storage::Tuple tuple(table_schema, allocate);

    for (oid_t col_itr = 0; col_itr < col_count; col_itr++) {
      auto value = ValueFactory::GetIntegerValue(populate_value);
      tuple.SetValue(col_itr, value, pool.get());
    }

    ItemPointer tuple_slot_id = hyadapt_table->InsertTuple(&tuple);
    assert(tuple_slot_id.block != INVALID_OID);
    assert(tuple_slot_id.offset != INVALID_OID);
    txn->RecordInsert(tuple_slot_id);
  }

  txn_manager.CommitTransaction();
}

expression::AbstractExpression *CreatePredicate(const int lower_bound) {
  // ATTR0 >= LOWER_BOUND

  // First, create tuple value expression.
  expression::AbstractExpression *tuple_value_expr =
    expression::ExpressionUtil::TupleValueFactory(0, 0);

  // Second, create constant value expression.
  Value constant_value = ValueFactory::GetIntegerValue(lower_bound);

  expression::AbstractExpression *constant_value_expr =
    expression::ExpressionUtil::ConstantValueFactory(constant_value);

  // Finally, link them together using an greater than expression.
  expression::AbstractExpression *predicate =
    expression::ExpressionUtil::ComparisonFactory(
      EXPRESSION_TYPE_COMPARE_GREATERTHANOREQUALTO, tuple_value_expr,
      constant_value_expr);

  return predicate;
}

void GenerateSequence(std::vector<oid_t>& hyadapt_column_ids, oid_t column_count) {
  // Reset sequence
  hyadapt_column_ids.clear();

  // Generate sequence
  for (oid_t column_id = 1; column_id <= column_count; column_id++)
    hyadapt_column_ids.push_back(column_id);

  std::random_shuffle(hyadapt_column_ids.begin(), hyadapt_column_ids.end());
}

void ExecuteTest(executor::AbstractExecutor *executor,
                        std::vector<double> columns_accessed, double cost) {
  Timer<> timer;

  timer.Start();
  bool status = false;

  status = executor->Init();
  if (status == false) throw Exception("Init failed");

  std::vector<std::unique_ptr<executor::LogicalTile>> result_tiles;

  while (executor->Execute() == true) {
      std::unique_ptr<executor::LogicalTile> result_tile(
        executor->GetOutput());
      result_tiles.emplace_back(result_tile.release());
  }

  // Execute stuff
  executor->Execute();

  timer.Stop();
  double time_per_transaction = timer.GetDuration();
  LOG_INFO("%f", time_per_transaction);
}

TEST_F(HybridIndexTests, SeqScanTest) {
  std::unique_ptr<storage::DataTable> hyadapt_table;
  CreateTable(hyadapt_table, false);

  LOG_INFO("%s", hyadapt_table->GetInfo().c_str());

  const int lower_bound = 30;
  const bool is_inlined = true;
  auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();

  auto txn = txn_manager.BeginTransaction();

  /////////////////////////////////////////////////////////
  // SEQ SCAN + PREDICATE
  /////////////////////////////////////////////////////////

  std::unique_ptr<executor::ExecutorContext> context(
  new executor::ExecutorContext(txn));

  // Column ids to be added to logical tile after scan.
  std::vector<oid_t> column_ids;
//  oid_t column_count = state.projectivity * state.column_count;
  oid_t column_count = projectivity * columncount;
  std::vector<oid_t> hyadapt_column_ids;

  GenerateSequence(hyadapt_column_ids, column_count);

  for (oid_t col_itr = 0; col_itr < column_count; col_itr++) {
    column_ids.push_back(hyadapt_column_ids[col_itr]);
  }

  // Create and set up seq scan executor
  auto predicate = CreatePredicate(lower_bound);
  planner::HybridScanPlan hybrid_scan_node(hyadapt_table.get(), predicate, column_ids);

  executor::HybridScanExecutor Hybrid_scan_executor(&hybrid_scan_node, context.get());

  ExecuteTest(&Hybrid_scan_executor, columns_accessed, cost);

  txn_manager.CommitTransaction();

  LOG_INFO("%s", table->GetInfo().c_str());
}

}  // namespace tet
}  // namespace peloton
<commit_msg>Hybrid seq scan test pass<commit_after>//
// Created by Rui Wang on 16-4-30.
//

#include "gtest/gtest.h"
#include "harness.h"

#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include <chrono>
#include <iostream>
#include <ctime>
#include <cassert>
#include <backend/planner/hybrid_scan_plan.h>
#include <backend/executor/hybrid_scan_executor.h>

#include "backend/catalog/manager.h"
#include "backend/catalog/schema.h"
#include "backend/concurrency/transaction.h"
#include "backend/concurrency/transaction_manager_factory.h"
#include "backend/common/timer.h"
#include "backend/executor/abstract_executor.h"
#include "backend/executor/insert_executor.h"
#include "backend/index/index_factory.h"
#include "backend/planner/insert_plan.h"
#include "backend/storage/tile.h"
#include "backend/storage/tile_group.h"
#include "backend/storage/data_table.h"
#include "backend/storage/table_factory.h"
#include "backend/expression/expression_util.h"
#include "backend/expression/abstract_expression.h"
#include "backend/expression/constant_value_expression.h"
#include "backend/expression/tuple_value_expression.h"
#include "backend/expression/comparison_expression.h"
#include "backend/expression/conjunction_expression.h"

#include "backend/index/index_factory.h"

namespace peloton {
namespace test {

class HybridIndexTests : public PelotonTest {};

static double projectivity = 1.0;
static int columncount = 4;
static size_t tuples_per_tile_group = 10;
static size_t tile_group = 10;

void CreateTable(std::unique_ptr<storage::DataTable>& hyadapt_table, bool indexes) {
  oid_t column_count = projectivity * columncount;

  const oid_t col_count = column_count + 1;
  const bool is_inlined = true;

  // Create schema first
  std::vector<catalog::Column> columns;

  for (oid_t col_itr = 0; col_itr < col_count; col_itr++) {
    auto column =
      catalog::Column(VALUE_TYPE_INTEGER, GetTypeSize(VALUE_TYPE_INTEGER),
                      "" + std::to_string(col_itr), is_inlined);

    columns.push_back(column);
  }

  catalog::Schema *table_schema = new catalog::Schema(columns);
  std::string table_name("HYADAPTTABLE");

  /////////////////////////////////////////////////////////
  // Create table.
  /////////////////////////////////////////////////////////

  bool own_schema = true;
  bool adapt_table = true;
  hyadapt_table.reset(storage::TableFactory::GetDataTable(
    INVALID_OID, INVALID_OID, table_schema, table_name,
    tuples_per_tile_group, own_schema, adapt_table));

  // PRIMARY INDEX
  if (indexes == true) {
    std::vector<oid_t> key_attrs;

    auto tuple_schema = hyadapt_table->GetSchema();
    catalog::Schema *key_schema;
    index::IndexMetadata *index_metadata;
    bool unique;

    key_attrs = {0};
    key_schema = catalog::Schema::CopySchema(tuple_schema, key_attrs);
    key_schema->SetIndexedColumns(key_attrs);

    unique = true;

    index_metadata = new index::IndexMetadata(
      "primary_index", 123, INDEX_TYPE_BTREE,
      INDEX_CONSTRAINT_TYPE_PRIMARY_KEY, tuple_schema, key_schema, unique);

    index::Index *pkey_index = index::IndexFactory::GetInstance(index_metadata);
    hyadapt_table->AddIndex(pkey_index);
  }
}

void LoadTable(std::unique_ptr<storage::DataTable>& hyadapt_table) {
  oid_t column_count = projectivity * columncount;
  const oid_t col_count = column_count + 1;
  const int tuple_count = tile_group * tuples_per_tile_group;

  auto table_schema = hyadapt_table->GetSchema();

  /////////////////////////////////////////////////////////
  // Load in the data
  /////////////////////////////////////////////////////////

  // Insert tuples into tile_group.
  auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
  const bool allocate = true;
  auto txn = txn_manager.BeginTransaction();
  std::unique_ptr<VarlenPool> pool(new VarlenPool(BACKEND_TYPE_MM));

  int rowid;
  for (rowid = 0; rowid < tuple_count; rowid++) {
    int populate_value = rowid;

    storage::Tuple tuple(table_schema, allocate);

    for (oid_t col_itr = 0; col_itr < col_count; col_itr++) {
      auto value = ValueFactory::GetIntegerValue(populate_value);
      tuple.SetValue(col_itr, value, pool.get());
    }

    ItemPointer tuple_slot_id = hyadapt_table->InsertTuple(&tuple);
    assert(tuple_slot_id.block != INVALID_OID);
    assert(tuple_slot_id.offset != INVALID_OID);
    txn->RecordInsert(tuple_slot_id);
  }

  txn_manager.CommitTransaction();
}

expression::AbstractExpression *CreatePredicate(const int lower_bound) {
  // ATTR0 >= LOWER_BOUND

  // First, create tuple value expression.
  expression::AbstractExpression *tuple_value_expr =
    expression::ExpressionUtil::TupleValueFactory(0, 0);

  // Second, create constant value expression.
  Value constant_value = ValueFactory::GetIntegerValue(lower_bound);

  expression::AbstractExpression *constant_value_expr =
    expression::ExpressionUtil::ConstantValueFactory(constant_value);

  // Finally, link them together using an greater than expression.
  expression::AbstractExpression *predicate =
    expression::ExpressionUtil::ComparisonFactory(
      EXPRESSION_TYPE_COMPARE_GREATERTHANOREQUALTO, tuple_value_expr,
      constant_value_expr);

  return predicate;
}

void GenerateSequence(std::vector<oid_t>& hyadapt_column_ids, oid_t column_count) {
  // Reset sequence
  hyadapt_column_ids.clear();

  // Generate sequence
  for (oid_t column_id = 1; column_id <= column_count; column_id++)
    hyadapt_column_ids.push_back(column_id);

  std::random_shuffle(hyadapt_column_ids.begin(), hyadapt_column_ids.end());
}

void ExecuteTest(executor::AbstractExecutor *executor) {
  Timer<> timer;

  timer.Start();
  bool status = false;

  status = executor->Init();
  if (status == false) throw Exception("Init failed");

  std::vector<std::unique_ptr<executor::LogicalTile>> result_tiles;

  while (executor->Execute() == true) {
      std::unique_ptr<executor::LogicalTile> result_tile(
        executor->GetOutput());
      result_tiles.emplace_back(result_tile.release());
  }

  // Execute stuff
  executor->Execute();

  timer.Stop();
  double time_per_transaction = timer.GetDuration();
  LOG_INFO("%f", time_per_transaction);
}

TEST_F(HybridIndexTests, SeqScanTest) {
  std::unique_ptr<storage::DataTable> hyadapt_table;
  CreateTable(hyadapt_table, false);

  LOG_INFO("%s", hyadapt_table->GetInfo().c_str());

  const int lower_bound = 30;
  auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();

  auto txn = txn_manager.BeginTransaction();

  /////////////////////////////////////////////////////////
  // SEQ SCAN + PREDICATE
  /////////////////////////////////////////////////////////

  std::unique_ptr<executor::ExecutorContext> context(
  new executor::ExecutorContext(txn));

  // Column ids to be added to logical tile after scan.
  std::vector<oid_t> column_ids;
//  oid_t column_count = state.projectivity * state.column_count;
  oid_t column_count = projectivity * columncount;
  std::vector<oid_t> hyadapt_column_ids;

  GenerateSequence(hyadapt_column_ids, column_count);

  for (oid_t col_itr = 0; col_itr < column_count; col_itr++) {
    column_ids.push_back(hyadapt_column_ids[col_itr]);
  }

  // Create and set up seq scan executor
  auto predicate = CreatePredicate(lower_bound);
  planner::HybridScanPlan hybrid_scan_node(hyadapt_table.get(), predicate, column_ids);

  executor::HybridScanExecutor Hybrid_scan_executor(&hybrid_scan_node, context.get());

  ExecuteTest(&Hybrid_scan_executor);

  txn_manager.CommitTransaction();
}

}  // namespace tet
}  // namespace peloton
<|endoftext|>


<commit_before>#include <libmesh/libmesh.h>
#include <libmesh/distributed_mesh.h>
#include <libmesh/elem.h>
#include <libmesh/mesh_generation.h>
#include <libmesh/mesh_tools.h>
#include <libmesh/replicated_mesh.h>

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

using namespace libMesh;

class MeshGenerationTest : public CppUnit::TestCase
{
  /**
   * The goal of this test is to verify proper operation of
   * MeshGeneration functions, as well as to indirectly verify the
   * MeshBase functions they rely on.
   */
public:
  CPPUNIT_TEST_SUITE( MeshGenerationTest );

  CPPUNIT_TEST( buildLineEdge2 );
  CPPUNIT_TEST( buildLineEdge3 );
  CPPUNIT_TEST( buildLineEdge4 );
#if LIBMESH_DIM > 1
  CPPUNIT_TEST( buildSquareTri3 );
  CPPUNIT_TEST( buildSquareTri6 );
  CPPUNIT_TEST( buildSquareQuad4 );
  CPPUNIT_TEST( buildSquareQuad8 );
  CPPUNIT_TEST( buildSquareQuad9 );
#endif
#if LIBMESH_DIM > 2
  CPPUNIT_TEST( buildCubeTet4 );
  CPPUNIT_TEST( buildCubeTet10 );
  CPPUNIT_TEST( buildCubeHex8 );
  CPPUNIT_TEST( buildCubeHex20 );
  CPPUNIT_TEST( buildCubeHex27 );
  CPPUNIT_TEST( buildCubePrism6 );
  CPPUNIT_TEST( buildCubePrism15 );
  CPPUNIT_TEST( buildCubePrism18 );
  CPPUNIT_TEST( buildCubePyramid5 );
  CPPUNIT_TEST( buildCubePyramid13 );
  CPPUNIT_TEST( buildCubePyramid14 );
#endif

  CPPUNIT_TEST_SUITE_END();

protected:
  std::unique_ptr<UnstructuredMesh> new_mesh (bool is_replicated)
  {
    if (is_replicated)
      return libmesh_make_unique<ReplicatedMesh>(*TestCommWorld);
    return libmesh_make_unique<DistributedMesh>(*TestCommWorld);
  }

public:
  void setUp() {}

  void tearDown() {}

  void testBuildLine(UnstructuredMesh & mesh, unsigned int n, ElemType type)
  {
    MeshTools::Generation::build_line (mesh, n, -1.0, 2.0, type);
    CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n));
    CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                         cast_int<dof_id_type>((Elem::type_to_n_nodes_map[type]-1)*n + 1));

    BoundingBox bbox = MeshTools::create_bounding_box(mesh);
    CPPUNIT_ASSERT_EQUAL(bbox.min()(0), Real(-1.0));
    CPPUNIT_ASSERT_EQUAL(bbox.max()(0), Real(2.0));
  }

  void testBuildSquare(UnstructuredMesh & mesh, unsigned int n, ElemType type)
  {
    MeshTools::Generation::build_square (mesh, n, n, -2.0, 3.0, -4.0, 5.0, type);
    if (Elem::type_to_n_sides_map[type] == 4)
      CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n));
    else
      CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*2));

    const unsigned int n_nodes = Elem::type_to_n_nodes_map[type];

    switch (n_nodes)
      {
      case 3: // First-order elements
      case 4:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((n+1)*(n+1)));
        break;
      case 6: // Second-order elements
      case 9:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)));
        break;
      default: // QUAD8
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1) - n*n));
      }

    // Our bounding boxes can be loose on higher order elements, but
    // we can at least assert that they're not too tight
    BoundingBox bbox = MeshTools::create_bounding_box(mesh);
    CPPUNIT_ASSERT(bbox.min()(0) <= Real(-2.0));
    CPPUNIT_ASSERT(bbox.max()(0) >= Real(3.0));
    CPPUNIT_ASSERT(bbox.min()(1) <= Real(-4.0));
    CPPUNIT_ASSERT(bbox.max()(1) >= Real(5.0));
  }

  void testBuildCube(UnstructuredMesh & mesh, unsigned int n, ElemType type)
  {
    MeshTools::Generation::build_cube (mesh, n, n, n, -2.0, 3.0, -4.0, 5.0, -6.0, 7.0, type);
    switch (Elem::type_to_n_sides_map[type])
      {
      case 4: // tets
        CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*n*24));
        break;
      case 5: // prisms, pyramids
        if (type == PRISM6 || type == PRISM15 || type == PRISM18)
          CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*n*2));
        else
          CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*n*6));
        break;
      case 6: // hexes
        CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*n));
        break;
      default:
        libmesh_error();
      }

    switch (Elem::type_to_n_nodes_map[type])
      {
      case 4: // First-order tets
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((n+1)*(n+1)*(n+1) + n*n*n + 3*(n+1)*n*n));
        break;
      case 6: // First-order prisms and hexes use the same nodes
      case 8:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((n+1)*(n+1)*(n+1)));
        break;
      case 10: // Second-order tets
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) + 14*n*n*n + 4*3*(n+1)*n*n));
        break;
      case 18: // Second-order prisms and hexes use the same nodes
      case 27:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1)));
        break;
      case 20:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) - n*n*n - 3*(n+1)*n*n));
        break;
      case 15: // weird partial order prism
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) - n*n*n - 2*(n+1)*n*n));
        break;
      case 5: // pyramids
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((n+1)*(n+1)*(n+1) + n*n*n));
        break;
      case 13:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) + 8*n*n*n - 3*(n+1)*n*n));
        break;
      case 14:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) + 8*n*n*n));
        break;
      default:
        libmesh_error();
      }

    // Our bounding boxes can be loose on higher order elements, but
    // we can at least assert that they're not too tight
    BoundingBox bbox = MeshTools::create_bounding_box(mesh);
    CPPUNIT_ASSERT(bbox.min()(0) <= Real(-2.0));
    CPPUNIT_ASSERT(bbox.max()(0) >= Real(3.0));
    CPPUNIT_ASSERT(bbox.min()(1) <= Real(-4.0));
    CPPUNIT_ASSERT(bbox.max()(1) >= Real(5.0));
    CPPUNIT_ASSERT(bbox.min()(2) <= Real(-6.0));
    CPPUNIT_ASSERT(bbox.max()(2) >= Real(7.0));
  }

  typedef void (MeshGenerationTest::*Builder)(UnstructuredMesh&, unsigned int, ElemType);

  void tester(Builder f, unsigned int n, ElemType type)
  {
    for (int is_replicated = 0; is_replicated != 2; ++is_replicated)
      {
        for (int skip_renumber = 0 ; skip_renumber != 2; ++skip_renumber)
          {
            std::unique_ptr<UnstructuredMesh> mesh =
              new_mesh(is_replicated);
            mesh->allow_renumbering(!skip_renumber);
            (this->*f)(*mesh, n, type);
          }
      }
  }

  void buildLineEdge2 ()     { tester(&MeshGenerationTest::testBuildLine, 5, EDGE2); }
  void buildLineEdge3 ()     { tester(&MeshGenerationTest::testBuildLine, 5, EDGE3); }
  void buildLineEdge4 ()     { tester(&MeshGenerationTest::testBuildLine, 5, EDGE4); }

  void buildSquareTri3 ()    { tester(&MeshGenerationTest::testBuildSquare, 3, TRI3); }
  void buildSquareTri6 ()    { tester(&MeshGenerationTest::testBuildSquare, 4, TRI6); }
  void buildSquareQuad4 ()   { tester(&MeshGenerationTest::testBuildSquare, 4, QUAD4); }
  void buildSquareQuad8 ()   { tester(&MeshGenerationTest::testBuildSquare, 4, QUAD8); }
  void buildSquareQuad9 ()   { tester(&MeshGenerationTest::testBuildSquare, 4, QUAD9); }

  void buildCubeTet4 ()      { tester(&MeshGenerationTest::testBuildCube, 2, TET4); }
  void buildCubeTet10 ()     { tester(&MeshGenerationTest::testBuildCube, 2, TET10); }
  void buildCubeHex8 ()      { tester(&MeshGenerationTest::testBuildCube, 2, HEX8); }
  void buildCubeHex20 ()     { tester(&MeshGenerationTest::testBuildCube, 2, HEX20); }
  void buildCubeHex27 ()     { tester(&MeshGenerationTest::testBuildCube, 2, HEX27); }
  void buildCubePrism6 ()    { tester(&MeshGenerationTest::testBuildCube, 2, PRISM6); }
  void buildCubePrism15 ()   { tester(&MeshGenerationTest::testBuildCube, 2, PRISM15); }
  void buildCubePrism18 ()   { tester(&MeshGenerationTest::testBuildCube, 2, PRISM18); }
  void buildCubePyramid5 ()  { tester(&MeshGenerationTest::testBuildCube, 2, PYRAMID5); }
  void buildCubePyramid13 () { tester(&MeshGenerationTest::testBuildCube, 2, PYRAMID13); }
  void buildCubePyramid14 () { tester(&MeshGenerationTest::testBuildCube, 2, PYRAMID14); }
};

CPPUNIT_TEST_SUITE_REGISTRATION( MeshGenerationTest );
<commit_msg>Unit tests for MeshModification::build_sphere()<commit_after>#include <libmesh/libmesh.h>
#include <libmesh/distributed_mesh.h>
#include <libmesh/elem.h>
#include <libmesh/mesh_generation.h>
#include <libmesh/mesh_tools.h>
#include <libmesh/replicated_mesh.h>

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

using namespace libMesh;

class MeshGenerationTest : public CppUnit::TestCase
{
  /**
   * The goal of this test is to verify proper operation of
   * MeshGeneration functions, as well as to indirectly verify the
   * MeshBase functions they rely on.
   */
public:
  CPPUNIT_TEST_SUITE( MeshGenerationTest );

  CPPUNIT_TEST( buildLineEdge2 );
  CPPUNIT_TEST( buildLineEdge3 );
  CPPUNIT_TEST( buildLineEdge4 );
#  ifdef LIBMESH_ENABLE_AMR
  CPPUNIT_TEST( buildSphereEdge2 );
  CPPUNIT_TEST( buildSphereEdge3 );
// CPPUNIT_TEST( buildSphereEdge4 ); Doesn't work with AMR yet
#  endif

#if LIBMESH_DIM > 1
  CPPUNIT_TEST( buildSquareTri3 );
  CPPUNIT_TEST( buildSquareTri6 );
  CPPUNIT_TEST( buildSquareQuad4 );
  CPPUNIT_TEST( buildSquareQuad8 );
  CPPUNIT_TEST( buildSquareQuad9 );
#  ifdef LIBMESH_ENABLE_AMR
  CPPUNIT_TEST( buildSphereTri3 );
  CPPUNIT_TEST( buildSphereQuad4 );
#  endif
#endif
#if LIBMESH_DIM > 2
  CPPUNIT_TEST( buildCubeTet4 );
  CPPUNIT_TEST( buildCubeTet10 );
  CPPUNIT_TEST( buildCubeHex8 );
  CPPUNIT_TEST( buildCubeHex20 );
  CPPUNIT_TEST( buildCubeHex27 );
  CPPUNIT_TEST( buildCubePrism6 );
  CPPUNIT_TEST( buildCubePrism15 );
  CPPUNIT_TEST( buildCubePrism18 );
  CPPUNIT_TEST( buildCubePyramid5 );
  CPPUNIT_TEST( buildCubePyramid13 );
  CPPUNIT_TEST( buildCubePyramid14 );
#  ifdef LIBMESH_ENABLE_AMR
  CPPUNIT_TEST( buildSphereHex8 );
//  CPPUNIT_TEST( buildSphereHex27 );
#  endif
#endif

  CPPUNIT_TEST_SUITE_END();

protected:
  std::unique_ptr<UnstructuredMesh> new_mesh (bool is_replicated)
  {
    if (is_replicated)
      return libmesh_make_unique<ReplicatedMesh>(*TestCommWorld);
    return libmesh_make_unique<DistributedMesh>(*TestCommWorld);
  }

public:
  void setUp() {}

  void tearDown() {}

  void testBuildLine(UnstructuredMesh & mesh, unsigned int n, ElemType type)
  {
    MeshTools::Generation::build_line (mesh, n, -1.0, 2.0, type);
    CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n));
    CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                         cast_int<dof_id_type>((Elem::type_to_n_nodes_map[type]-1)*n + 1));

    BoundingBox bbox = MeshTools::create_bounding_box(mesh);
    CPPUNIT_ASSERT_EQUAL(bbox.min()(0), Real(-1.0));
    CPPUNIT_ASSERT_EQUAL(bbox.max()(0), Real(2.0));
  }

  void testBuildSquare(UnstructuredMesh & mesh, unsigned int n, ElemType type)
  {
    MeshTools::Generation::build_square (mesh, n, n, -2.0, 3.0, -4.0, 5.0, type);
    if (Elem::type_to_n_sides_map[type] == 4)
      CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n));
    else
      CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*2));

    const unsigned int n_nodes = Elem::type_to_n_nodes_map[type];

    switch (n_nodes)
      {
      case 3: // First-order elements
      case 4:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((n+1)*(n+1)));
        break;
      case 6: // Second-order elements
      case 9:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)));
        break;
      default: // QUAD8
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1) - n*n));
      }

    // Our bounding boxes can be loose on higher order elements, but
    // we can at least assert that they're not too tight
    BoundingBox bbox = MeshTools::create_bounding_box(mesh);
    CPPUNIT_ASSERT(bbox.min()(0) <= Real(-2.0));
    CPPUNIT_ASSERT(bbox.max()(0) >= Real(3.0));
    CPPUNIT_ASSERT(bbox.min()(1) <= Real(-4.0));
    CPPUNIT_ASSERT(bbox.max()(1) >= Real(5.0));
  }

  void testBuildCube(UnstructuredMesh & mesh, unsigned int n, ElemType type)
  {
    MeshTools::Generation::build_cube (mesh, n, n, n, -2.0, 3.0, -4.0, 5.0, -6.0, 7.0, type);
    switch (Elem::type_to_n_sides_map[type])
      {
      case 4: // tets
        CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*n*24));
        break;
      case 5: // prisms, pyramids
        if (type == PRISM6 || type == PRISM15 || type == PRISM18)
          CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*n*2));
        else
          CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*n*6));
        break;
      case 6: // hexes
        CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*n));
        break;
      default:
        libmesh_error();
      }

    switch (Elem::type_to_n_nodes_map[type])
      {
      case 4: // First-order tets
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((n+1)*(n+1)*(n+1) + n*n*n + 3*(n+1)*n*n));
        break;
      case 6: // First-order prisms and hexes use the same nodes
      case 8:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((n+1)*(n+1)*(n+1)));
        break;
      case 10: // Second-order tets
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) + 14*n*n*n + 4*3*(n+1)*n*n));
        break;
      case 18: // Second-order prisms and hexes use the same nodes
      case 27:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1)));
        break;
      case 20:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) - n*n*n - 3*(n+1)*n*n));
        break;
      case 15: // weird partial order prism
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) - n*n*n - 2*(n+1)*n*n));
        break;
      case 5: // pyramids
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((n+1)*(n+1)*(n+1) + n*n*n));
        break;
      case 13:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) + 8*n*n*n - 3*(n+1)*n*n));
        break;
      case 14:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) + 8*n*n*n));
        break;
      default:
        libmesh_error();
      }

    // Our bounding boxes can be loose on higher order elements, but
    // we can at least assert that they're not too tight
    BoundingBox bbox = MeshTools::create_bounding_box(mesh);
    CPPUNIT_ASSERT(bbox.min()(0) <= Real(-2.0));
    CPPUNIT_ASSERT(bbox.max()(0) >= Real(3.0));
    CPPUNIT_ASSERT(bbox.min()(1) <= Real(-4.0));
    CPPUNIT_ASSERT(bbox.max()(1) >= Real(5.0));
    CPPUNIT_ASSERT(bbox.min()(2) <= Real(-6.0));
    CPPUNIT_ASSERT(bbox.max()(2) >= Real(7.0));
  }

  void testBuildSphere(unsigned int n_ref, ElemType type)
  {
    ReplicatedMesh rmesh(*TestCommWorld);
    MeshTools::Generation::build_sphere (rmesh, 2.0, n_ref, type);

    DistributedMesh dmesh(*TestCommWorld);
    dmesh.allow_renumbering(false);
    MeshTools::Generation::build_sphere (dmesh, 2.0, n_ref, type);
  }

  typedef void (MeshGenerationTest::*Builder)(UnstructuredMesh&, unsigned int, ElemType);

  void tester(Builder f, unsigned int n, ElemType type)
  {
    for (int is_replicated = 0; is_replicated != 2; ++is_replicated)
      {
        for (int skip_renumber = 0 ; skip_renumber != 2; ++skip_renumber)
          {
            std::unique_ptr<UnstructuredMesh> mesh =
              new_mesh(is_replicated);
            mesh->allow_renumbering(!skip_renumber);
            (this->*f)(*mesh, n, type);
          }
      }
  }

  void buildLineEdge2 ()     { tester(&MeshGenerationTest::testBuildLine, 5, EDGE2); }
  void buildLineEdge3 ()     { tester(&MeshGenerationTest::testBuildLine, 5, EDGE3); }
  void buildLineEdge4 ()     { tester(&MeshGenerationTest::testBuildLine, 5, EDGE4); }

  void buildSphereEdge2 ()     { testBuildSphere(2, EDGE2); }
  void buildSphereEdge3 ()     { testBuildSphere(2, EDGE3); }
  void buildSphereEdge4 ()     { testBuildSphere(2, EDGE4); }

  void buildSquareTri3 ()    { tester(&MeshGenerationTest::testBuildSquare, 3, TRI3); }
  void buildSquareTri6 ()    { tester(&MeshGenerationTest::testBuildSquare, 4, TRI6); }
  void buildSquareQuad4 ()   { tester(&MeshGenerationTest::testBuildSquare, 4, QUAD4); }
  void buildSquareQuad8 ()   { tester(&MeshGenerationTest::testBuildSquare, 4, QUAD8); }
  void buildSquareQuad9 ()   { tester(&MeshGenerationTest::testBuildSquare, 4, QUAD9); }

  void buildSphereTri3 ()     { testBuildSphere(2, TRI3); }
  void buildSphereQuad4 ()     { testBuildSphere(2, QUAD4); }

  void buildCubeTet4 ()      { tester(&MeshGenerationTest::testBuildCube, 2, TET4); }
  void buildCubeTet10 ()     { tester(&MeshGenerationTest::testBuildCube, 2, TET10); }
  void buildCubeHex8 ()      { tester(&MeshGenerationTest::testBuildCube, 2, HEX8); }
  void buildCubeHex20 ()     { tester(&MeshGenerationTest::testBuildCube, 2, HEX20); }
  void buildCubeHex27 ()     { tester(&MeshGenerationTest::testBuildCube, 2, HEX27); }
  void buildCubePrism6 ()    { tester(&MeshGenerationTest::testBuildCube, 2, PRISM6); }
  void buildCubePrism15 ()   { tester(&MeshGenerationTest::testBuildCube, 2, PRISM15); }
  void buildCubePrism18 ()   { tester(&MeshGenerationTest::testBuildCube, 2, PRISM18); }
  void buildCubePyramid5 ()  { tester(&MeshGenerationTest::testBuildCube, 2, PYRAMID5); }
  void buildCubePyramid13 () { tester(&MeshGenerationTest::testBuildCube, 2, PYRAMID13); }
  void buildCubePyramid14 () { tester(&MeshGenerationTest::testBuildCube, 2, PYRAMID14); }

  void buildSphereHex8 ()     { testBuildSphere(2, HEX8); }
  void buildSphereHex27 ()     { testBuildSphere(2, HEX27); }
};

CPPUNIT_TEST_SUITE_REGISTRATION( MeshGenerationTest );
<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

// This one has to come first (includes the config.h)!
#include <dune/stuff/test/test_common.hh>

#include <memory>
#include <utility>

#if HAVE_ALUGRID_SERIAL_H || HAVE_ALUGRID_PARALLEL_H
#define ENABLE_ALUGRID 1
#include <dune/stuff/common/disable_warnings.hh>
#include <dune/grid/alugrid.hh>
#include <dune/stuff/common/reenable_warnings.hh>
#else
#error "This test requires alugrid!"
#endif

#include <dune/stuff/common/exceptions.hh>
#include <dune/stuff/grid/provider/cube.hh>
#include <dune/stuff/la/container.hh>
#include <dune/stuff/functions/expression.hh>
#include <dune/stuff/functions/combined.hh>

#include <dune/gdt/spaces/tools.hh>
#include <dune/gdt/spaces/continuouslagrange/fem.hh>
#include <dune/gdt/playground/spaces/finitevolume/default.hh>
#include <dune/gdt/discretefunction/default.hh>
#include <dune/gdt/operators/darcy.hh>
#include <dune/gdt/operators/projections.hh>
#include <dune/gdt/products/l2.hh>
#include <dune/gdt/products/h1.hh>

class errors_are_not_as_expected : public Dune::Exception
{
};

// +----------------------------------------------------------------------------+
// | 1st we define all the test structs that do something at the end of the day |
// +----------------------------------------------------------------------------+

template <class SpaceTypes>
class Darcy_Operator : public ::testing::Test
{
  typedef typename SpaceTypes::first_type SourceSpaceType;
  typedef typename SpaceTypes::second_type RangeSpaceType;

  typedef typename RangeSpaceType::GridViewType GridViewType;
  typedef typename GridViewType::Grid GridType;
  typedef Dune::Stuff::Grid::Providers::Cube<GridType> GridProviderType;
  typedef typename GridViewType::template Codim<0>::Entity EntityType;
  typedef typename GridViewType::ctype DomainFieldType;
  static const unsigned int dimDomain = SourceSpaceType::dimDomain;
  typedef double RangeFieldType;

#if HAVE_EIGEN
  typedef Dune::Stuff::LA::EigenDenseVector<RangeFieldType> VectorType;
#elif HAVE_DUNE_ISTL
  typedef Dune::Stuff::LA::IstlDenseVector<RangeFieldType> VectorType;
#else
  typedef Dune::Stuff::LA::CommonDenseVector<RangeFieldType> VectorType;
#endif

public:
  void produces_correct_results() const
  {
    using namespace Dune;
    using namespace GDT;

    GridProviderType grid_provider(0.0, 1.0, 4);
    auto grid = grid_provider.grid();
    grid->globalRefine(1);

    typedef Stuff::Functions::Expression<EntityType, DomainFieldType, dimDomain, RangeFieldType, 1> FunctionType;
    const FunctionType source("x", "x[0] * x[1]", 2, "source", {{"x[1]", "x[0]"}});

    const RangeSpaceType range_space(SpaceTools::GridPartView<RangeSpaceType>::create_leaf(*grid));
    VectorType range_vector(range_space.mapper().size());
    DiscreteFunction<RangeSpaceType, VectorType> range(range_space, range_vector);

    const FunctionType function("x", "-1.0", 0);
    const Operators::Darcy<GridViewType, FunctionType> darcy_operator(*(range_space.grid_view()), function);
    darcy_operator.apply(source, range);

    const Stuff::Functions::Expression<EntityType, DomainFieldType, dimDomain, RangeFieldType, dimDomain>
        desired_output(
            "x", std::vector<std::string>({"x[1]", "x[0]"}), 1, "desired output", {{"0.0", "1.0"}, {"1.0", "0.0"}});

    const Products::L2<GridViewType> l2_product(*(range_space.grid_view()));
    const RangeFieldType l2_error          = l2_product.induced_norm(desired_output - range);
    const RangeFieldType l2_error_expected = expected_result_("l2", desired_output, range_space.grid_view());
    if (l2_error > l2_error_expected)
      DUNE_THROW_COLORFULLY(errors_are_not_as_expected, l2_error << " vs. " << l2_error_expected);

    const Products::H1SemiGeneric<GridViewType> h1_semi_product(*(range_space.grid_view()));
    const RangeFieldType h1_error          = h1_semi_product.induced_norm(desired_output - range);
    const RangeFieldType h1_error_expected = expected_result_("h1", desired_output, range_space.grid_view());
    if (h1_error > h1_error_expected)
      DUNE_THROW_COLORFULLY(errors_are_not_as_expected, h1_error << " vs. " << h1_error_expected);
  } // ... produces_correct_results()

private:
  template <class FunctionType, class GV>
  RangeFieldType expected_result_(const std::string type, const FunctionType& desired_output,
                                  const std::shared_ptr<const GV>& grid_view_ptr) const
  {
    typedef typename Dune::GDT::SpaceTools::LeafGridPartView<GridType, RangeSpaceType::needs_grid_view>::Type GPV;
    if (std::is_base_of<Dune::GDT::Spaces::ContinuousLagrange::FemBased<GPV, 1, RangeFieldType, dimDomain>,
                        RangeSpaceType>::value) {
      if (type == "l2")
        return 2.18e-16;
      else if (type == "h1")
        return 3.12e-15;
      else
        DUNE_THROW_COLORFULLY(Dune::Stuff::Exceptions::internal_error, type);
    } else if (std::is_base_of<Dune::GDT::Spaces::RaviartThomas::PdelabBased<GPV, 0, RangeFieldType, dimDomain>,
                               RangeSpaceType>::value) {
      typedef Dune::GDT::Spaces::FiniteVolume::Default<GV, RangeFieldType, dimDomain> FvSpaceType;
      const FvSpaceType fv_space(grid_view_ptr);
      VectorType fv_desired_output_vector(fv_space.mapper().size());
      Dune::GDT::DiscreteFunction<FvSpaceType, VectorType> fv_desired_output(fv_space, fv_desired_output_vector);
      const Dune::GDT::Operators::L2Projection<GV> l2_projection(*grid_view_ptr);
      l2_projection.apply(desired_output, fv_desired_output);
      const Dune::GDT::Products::L2<GV> l2_product(*grid_view_ptr);
      const Dune::GDT::Products::H1SemiGeneric<GV> h1_semi_product(*grid_view_ptr);
      if (type == "l2")
        return 2.0 * l2_product.induced_norm(desired_output - fv_desired_output);
      else if (type == "h1")
        return h1_semi_product.induced_norm(desired_output - fv_desired_output);
      else
        DUNE_THROW_COLORFULLY(Dune::Stuff::Exceptions::internal_error, type);
    } else
      DUNE_THROW_COLORFULLY(Dune::Stuff::Exceptions::internal_error, type);
  } // ... expected_result_(...)
}; // class Darcy_Operator

// +----------------------------------------------------------------------------+
// | 2nd we define all arguments the above test structs are to be compiled with |
// +----------------------------------------------------------------------------+

typedef Dune::ALUConformGrid<2, 2> AluConform2dGridType;
typedef typename Dune::GDT::SpaceTools::LeafGridPartView<AluConform2dGridType, true>::Type AluConform2dLeafGridViewType;
typedef
    typename Dune::GDT::SpaceTools::LeafGridPartView<AluConform2dGridType, false>::Type AluConform2dLeafGridPartType;

typedef testing::
    Types</*std::pair< Dune::GDT::Spaces::ContinuousLagrange::FemBased< AluConform2dLeafGridPartType, 1, double, 1 >,
                                   Dune::GDT::Spaces::ContinuousLagrange::FemBased< AluConform2dLeafGridPartType, 1, double, 2 > >
                      ,*/ std::
              pair<Dune::GDT::Spaces::ContinuousLagrange::FemBased<AluConform2dLeafGridPartType, 1, double, 1>,
                   Dune::GDT::Spaces::RaviartThomas::PdelabBased<AluConform2dLeafGridViewType, 0, double, 2>>>
        SpaceTypes;

// +--------------------------------------------------------------------------------------+
// | 3rd we combine all test structs with their appropriate arguments to create the tests |
// | (comment out the following lines if you do not want a test to run)                   |
// +--------------------------------------------------------------------------------------+

TYPED_TEST_CASE(Darcy_Operator, SpaceTypes);
TYPED_TEST(Darcy_Operator, produces_correct_results)
{
  this->produces_correct_results();
}

// +--------------------------------------------------------------------------------------+
// | 4th we run all the tests                                                             |
// | (run the resulting executable with '--gtest_catch_exceptions=0' to see an exception) |
// +--------------------------------------------------------------------------------------+

int main(int argc, char** argv)
{
  try {
    test_init(argc, argv);
    return RUN_ALL_TESTS();
  } catch (Dune::Exception& e) {
    std::cerr << "\nDune reported error: " << e.what() << std::endl;
    std::abort();
  } catch (std::exception& e) {
    std::cerr << "\n" << e.what() << std::endl;
    std::abort();
  } catch (...) {
    std::cerr << "Unknown exception thrown!" << std::endl;
    std::abort();
  } // try
} // ... main(...)
<commit_msg>[tests.operator_reconstructions] use ALUGrid instead of deprecated AluConformGrid<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

// This one has to come first (includes the config.h)!
#include <dune/stuff/test/test_common.hh>

#include <memory>
#include <utility>

#if HAVE_ALUGRID_SERIAL_H || HAVE_ALUGRID_PARALLEL_H
#define ENABLE_ALUGRID 1
#include <dune/stuff/common/disable_warnings.hh>
#include <dune/grid/alugrid.hh>
#include <dune/stuff/common/reenable_warnings.hh>
#else
#error "This test requires alugrid!"
#endif

#include <dune/stuff/common/exceptions.hh>
#include <dune/stuff/grid/provider/cube.hh>
#include <dune/stuff/la/container.hh>
#include <dune/stuff/functions/expression.hh>
#include <dune/stuff/functions/combined.hh>

#include <dune/gdt/spaces/tools.hh>
#include <dune/gdt/spaces/continuouslagrange/fem.hh>
#include <dune/gdt/playground/spaces/finitevolume/default.hh>
#include <dune/gdt/discretefunction/default.hh>
#include <dune/gdt/operators/darcy.hh>
#include <dune/gdt/operators/projections.hh>
#include <dune/gdt/products/l2.hh>
#include <dune/gdt/products/h1.hh>

class errors_are_not_as_expected : public Dune::Exception
{
};

// +----------------------------------------------------------------------------+
// | 1st we define all the test structs that do something at the end of the day |
// +----------------------------------------------------------------------------+

template <class SpaceTypes>
class Darcy_Operator : public ::testing::Test
{
  typedef typename SpaceTypes::first_type SourceSpaceType;
  typedef typename SpaceTypes::second_type RangeSpaceType;

  typedef typename RangeSpaceType::GridViewType GridViewType;
  typedef typename GridViewType::Grid GridType;
  typedef Dune::Stuff::Grid::Providers::Cube<GridType> GridProviderType;
  typedef typename GridViewType::template Codim<0>::Entity EntityType;
  typedef typename GridViewType::ctype DomainFieldType;
  static const unsigned int dimDomain = SourceSpaceType::dimDomain;
  typedef double RangeFieldType;

#if HAVE_EIGEN
  typedef Dune::Stuff::LA::EigenDenseVector<RangeFieldType> VectorType;
#elif HAVE_DUNE_ISTL
  typedef Dune::Stuff::LA::IstlDenseVector<RangeFieldType> VectorType;
#else
  typedef Dune::Stuff::LA::CommonDenseVector<RangeFieldType> VectorType;
#endif

public:
  void produces_correct_results() const
  {
    using namespace Dune;
    using namespace GDT;

    GridProviderType grid_provider(0.0, 1.0, 4);
    auto grid = grid_provider.grid();
    grid->globalRefine(1);

    typedef Stuff::Functions::Expression<EntityType, DomainFieldType, dimDomain, RangeFieldType, 1> FunctionType;
    const FunctionType source("x", "x[0] * x[1]", 2, "source", {{"x[1]", "x[0]"}});

    const RangeSpaceType range_space(SpaceTools::GridPartView<RangeSpaceType>::create_leaf(*grid));
    VectorType range_vector(range_space.mapper().size());
    DiscreteFunction<RangeSpaceType, VectorType> range(range_space, range_vector);

    const FunctionType function("x", "-1.0", 0);
    const Operators::Darcy<GridViewType, FunctionType> darcy_operator(*(range_space.grid_view()), function);
    darcy_operator.apply(source, range);

    const Stuff::Functions::Expression<EntityType, DomainFieldType, dimDomain, RangeFieldType, dimDomain>
        desired_output(
            "x", std::vector<std::string>({"x[1]", "x[0]"}), 1, "desired output", {{"0.0", "1.0"}, {"1.0", "0.0"}});

    const Products::L2<GridViewType> l2_product(*(range_space.grid_view()));
    const RangeFieldType l2_error          = l2_product.induced_norm(desired_output - range);
    const RangeFieldType l2_error_expected = expected_result_("l2", desired_output, range_space.grid_view());
    if (l2_error > l2_error_expected)
      DUNE_THROW_COLORFULLY(errors_are_not_as_expected, l2_error << " vs. " << l2_error_expected);

    const Products::H1SemiGeneric<GridViewType> h1_semi_product(*(range_space.grid_view()));
    const RangeFieldType h1_error          = h1_semi_product.induced_norm(desired_output - range);
    const RangeFieldType h1_error_expected = expected_result_("h1", desired_output, range_space.grid_view());
    if (h1_error > h1_error_expected)
      DUNE_THROW_COLORFULLY(errors_are_not_as_expected, h1_error << " vs. " << h1_error_expected);
  } // ... produces_correct_results()

private:
  template <class FunctionType, class GV>
  RangeFieldType expected_result_(const std::string type, const FunctionType& desired_output,
                                  const std::shared_ptr<const GV>& grid_view_ptr) const
  {
    typedef typename Dune::GDT::SpaceTools::LeafGridPartView<GridType, RangeSpaceType::needs_grid_view>::Type GPV;
    if (std::is_base_of<Dune::GDT::Spaces::ContinuousLagrange::FemBased<GPV, 1, RangeFieldType, dimDomain>,
                        RangeSpaceType>::value) {
      if (type == "l2")
        return 2.18e-16;
      else if (type == "h1")
        return 3.12e-15;
      else
        DUNE_THROW_COLORFULLY(Dune::Stuff::Exceptions::internal_error, type);
    } else if (std::is_base_of<Dune::GDT::Spaces::RaviartThomas::PdelabBased<GPV, 0, RangeFieldType, dimDomain>,
                               RangeSpaceType>::value) {
      typedef Dune::GDT::Spaces::FiniteVolume::Default<GV, RangeFieldType, dimDomain> FvSpaceType;
      const FvSpaceType fv_space(grid_view_ptr);
      VectorType fv_desired_output_vector(fv_space.mapper().size());
      Dune::GDT::DiscreteFunction<FvSpaceType, VectorType> fv_desired_output(fv_space, fv_desired_output_vector);
      const Dune::GDT::Operators::L2Projection<GV> l2_projection(*grid_view_ptr);
      l2_projection.apply(desired_output, fv_desired_output);
      const Dune::GDT::Products::L2<GV> l2_product(*grid_view_ptr);
      const Dune::GDT::Products::H1SemiGeneric<GV> h1_semi_product(*grid_view_ptr);
      if (type == "l2")
        return 2.0 * l2_product.induced_norm(desired_output - fv_desired_output);
      else if (type == "h1")
        return h1_semi_product.induced_norm(desired_output - fv_desired_output);
      else
        DUNE_THROW_COLORFULLY(Dune::Stuff::Exceptions::internal_error, type);
    } else
      DUNE_THROW_COLORFULLY(Dune::Stuff::Exceptions::internal_error, type);
  } // ... expected_result_(...)
}; // class Darcy_Operator

// +----------------------------------------------------------------------------+
// | 2nd we define all arguments the above test structs are to be compiled with |
// +----------------------------------------------------------------------------+

typedef Dune::ALUGrid<2, 2, Dune::simplex, Dune::conforming> AluConform2dGridType;
typedef typename Dune::GDT::SpaceTools::LeafGridPartView<AluConform2dGridType, true>::Type AluConform2dLeafGridViewType;
typedef
    typename Dune::GDT::SpaceTools::LeafGridPartView<AluConform2dGridType, false>::Type AluConform2dLeafGridPartType;

typedef testing::
    Types</*std::pair< Dune::GDT::Spaces::ContinuousLagrange::FemBased< AluConform2dLeafGridPartType, 1, double, 1 >,
                                   Dune::GDT::Spaces::ContinuousLagrange::FemBased< AluConform2dLeafGridPartType, 1, double, 2 > >
                      ,*/ std::
              pair<Dune::GDT::Spaces::ContinuousLagrange::FemBased<AluConform2dLeafGridPartType, 1, double, 1>,
                   Dune::GDT::Spaces::RaviartThomas::PdelabBased<AluConform2dLeafGridViewType, 0, double, 2>>>
        SpaceTypes;

// +--------------------------------------------------------------------------------------+
// | 3rd we combine all test structs with their appropriate arguments to create the tests |
// | (comment out the following lines if you do not want a test to run)                   |
// +--------------------------------------------------------------------------------------+

TYPED_TEST_CASE(Darcy_Operator, SpaceTypes);
TYPED_TEST(Darcy_Operator, produces_correct_results)
{
  this->produces_correct_results();
}

// +--------------------------------------------------------------------------------------+
// | 4th we run all the tests                                                             |
// | (run the resulting executable with '--gtest_catch_exceptions=0' to see an exception) |
// +--------------------------------------------------------------------------------------+

int main(int argc, char** argv)
{
  try {
    test_init(argc, argv);
    return RUN_ALL_TESTS();
  } catch (Dune::Exception& e) {
    std::cerr << "\nDune reported error: " << e.what() << std::endl;
    std::abort();
  } catch (std::exception& e) {
    std::cerr << "\n" << e.what() << std::endl;
    std::abort();
  } catch (...) {
    std::cerr << "Unknown exception thrown!" << std::endl;
    std::abort();
  } // try
} // ... main(...)
<|endoftext|>