mirror of
https://git.gfz-potsdam.de/naaice/poet.git
synced 2025-12-16 12:54:50 +01:00
Merge branch 'implement-field-class' into 'main'
feat: add Field data structure as substitution of field declaration See merge request sec34/port!18
This commit is contained in:
commit
29344a3ff0
@ -17,6 +17,7 @@ options:
|
|||||||
- doc
|
- doc
|
||||||
- chore
|
- chore
|
||||||
- ci
|
- ci
|
||||||
|
- test
|
||||||
commit_groups:
|
commit_groups:
|
||||||
title_maps:
|
title_maps:
|
||||||
feat: Features
|
feat: Features
|
||||||
@ -29,6 +30,7 @@ options:
|
|||||||
doc: Documentation
|
doc: Documentation
|
||||||
chore: Householding and Cleanup
|
chore: Householding and Cleanup
|
||||||
ci: CI
|
ci: CI
|
||||||
|
test: Software Testing
|
||||||
header:
|
header:
|
||||||
pattern: "^(\\w*)\\:\\s(.*)$"
|
pattern: "^(\\w*)\\:\\s(.*)$"
|
||||||
pattern_maps:
|
pattern_maps:
|
||||||
|
|||||||
@ -21,6 +21,7 @@ image: git.gfz-potsdam.de:5000/sec34/port:builder
|
|||||||
stages: # List of stages for jobs, and their order of execution
|
stages: # List of stages for jobs, and their order of execution
|
||||||
- build
|
- build
|
||||||
- release
|
- release
|
||||||
|
- test
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
GIT_SUBMODULE_STRATEGY: recursive
|
GIT_SUBMODULE_STRATEGY: recursive
|
||||||
@ -34,6 +35,13 @@ build-poet: # This job runs in the build stage, which runs first.
|
|||||||
- cmake ..
|
- cmake ..
|
||||||
- make -j$(nproc)
|
- make -j$(nproc)
|
||||||
|
|
||||||
|
test-poet:
|
||||||
|
stage: test
|
||||||
|
script:
|
||||||
|
- mkdir build_test && cd build_test
|
||||||
|
- cmake -DPOET_ENABLE_TESTING=ON ..
|
||||||
|
- make -j$(nproc) check
|
||||||
|
|
||||||
archive-sources: # This job runs in the build stage, which runs first.
|
archive-sources: # This job runs in the build stage, which runs first.
|
||||||
image: python:3
|
image: python:3
|
||||||
stage: release
|
stage: release
|
||||||
|
|||||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -5,3 +5,6 @@
|
|||||||
[submodule "ext/phreeqcrm"]
|
[submodule "ext/phreeqcrm"]
|
||||||
path = ext/phreeqcrm
|
path = ext/phreeqcrm
|
||||||
url = ../../mluebke/phreeqcrm-gfz.git
|
url = ../../mluebke/phreeqcrm-gfz.git
|
||||||
|
[submodule "ext/doctest"]
|
||||||
|
path = ext/doctest
|
||||||
|
url = https://github.com/doctest/doctest.git
|
||||||
|
|||||||
@ -24,9 +24,19 @@ add_subdirectory(data)
|
|||||||
add_subdirectory(app)
|
add_subdirectory(app)
|
||||||
add_subdirectory(bench/dolo_diffu_inner)
|
add_subdirectory(bench/dolo_diffu_inner)
|
||||||
|
|
||||||
|
# as tug will also pull in doctest as a dependency
|
||||||
|
set(TUG_ENABLE_TESTING OFF CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
add_subdirectory(ext/tug EXCLUDE_FROM_ALL)
|
add_subdirectory(ext/tug EXCLUDE_FROM_ALL)
|
||||||
add_subdirectory(ext/phreeqcrm EXCLUDE_FROM_ALL)
|
add_subdirectory(ext/phreeqcrm EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
option(POET_ENABLE_TESTING "Build test suite for POET" OFF)
|
||||||
|
|
||||||
|
if (POET_ENABLE_TESTING)
|
||||||
|
add_subdirectory(ext/doctest EXCLUDE_FROM_ALL)
|
||||||
|
add_subdirectory(test)
|
||||||
|
endif()
|
||||||
|
|
||||||
option(BUILD_DOC "Build documentation with doxygen" OFF)
|
option(BUILD_DOC "Build documentation with doxygen" OFF)
|
||||||
|
|
||||||
if(BUILD_DOC)
|
if(BUILD_DOC)
|
||||||
|
|||||||
1
ext/doctest
Submodule
1
ext/doctest
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 8fdfd113dcb4ad1a31705ff8ddb13a21a505bad8
|
||||||
151
include/poet/Field.hpp
Normal file
151
include/poet/Field.hpp
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
#ifndef FIELD_H_
|
||||||
|
#define FIELD_H_
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <iterator>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace poet {
|
||||||
|
|
||||||
|
using FieldColumn = std::vector<double>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores data for input/output of a module. The class keeps track of all
|
||||||
|
* defined properties with name and import/export to 1D and 2D STL vectors.
|
||||||
|
* Also, it eases the update process of a field with an input from another
|
||||||
|
* field.
|
||||||
|
*
|
||||||
|
* It can be seen as an R-like data frame, but with less access to the members.
|
||||||
|
* Species values are stored as "columns", where column is a STL vector.
|
||||||
|
*/
|
||||||
|
class Field : private std::unordered_map<std::string, FieldColumn> {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a new instance of a field with fixed expected vector size.
|
||||||
|
*
|
||||||
|
* \param vec_s expected vector size of each component/column. \
|
||||||
|
*/
|
||||||
|
Field(uint32_t vec_s) : req_vec_size(vec_s){};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes instance with a 2D vector and according names for each columnn.
|
||||||
|
* There is no check if names were given multiple times. The order of name
|
||||||
|
* vector also defines the ordering of the output.
|
||||||
|
*
|
||||||
|
* \param input 2D vector using STL semantic describing the current state of
|
||||||
|
* the field.
|
||||||
|
* \param prop_vec Name of each vector in the input. Shall match
|
||||||
|
* the count of vectors.
|
||||||
|
*
|
||||||
|
* \exception std::runtime_error If prop_vec size doesn't match input vector
|
||||||
|
* size or column vectors size doesn't match expected vector size.
|
||||||
|
*/
|
||||||
|
void InitFromVec(const std::vector<std::vector<double>> &input,
|
||||||
|
const std::vector<std::string> &prop_vec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes instance with a 1D continious memory vector and according names
|
||||||
|
* for each columnn. There is no check if names were given multiple times. The
|
||||||
|
* order of name vector also defines the ordering of the output.
|
||||||
|
*
|
||||||
|
* \param input 1D vector using STL semantic describing the current state of
|
||||||
|
* the field storing each column starting at index *i times requested vector
|
||||||
|
* size*.
|
||||||
|
* \param prop_vec Name of each vector in the input. Shall match the
|
||||||
|
* count of vectors.
|
||||||
|
*
|
||||||
|
* \exception std::runtime_error If prop_vec size doesn't match input vector
|
||||||
|
* size or column vectors size doesn't match expected vector size.
|
||||||
|
*/
|
||||||
|
void InitFromVec(const std::vector<double> &input,
|
||||||
|
const std::vector<std::string> &prop_vec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a reference to the column vector with given name. Creates a new
|
||||||
|
* vector if prop was not found. The prop name will be added to the end of the
|
||||||
|
* list.
|
||||||
|
*
|
||||||
|
* \param key Name of the prop.
|
||||||
|
*
|
||||||
|
* \return Reference to the column vector.
|
||||||
|
*/
|
||||||
|
FieldColumn &operator[](const std::string &key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the names of all species defined in the instance.
|
||||||
|
*
|
||||||
|
* \return Vector containing all species names in output order.
|
||||||
|
*/
|
||||||
|
auto GetProps() const { return this->props; };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the requested vector size.
|
||||||
|
*
|
||||||
|
* \return Requested vector size set in the instanciation of the object.
|
||||||
|
*/
|
||||||
|
auto GetRequestedVecSize() const { return this->req_vec_size; };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates all species with values from another field. If one element of the
|
||||||
|
* input field doesn't match the names of the calling instance it will get
|
||||||
|
* skipped.
|
||||||
|
*
|
||||||
|
* \param input Field to update the current instance's columns.
|
||||||
|
*/
|
||||||
|
void UpdateFromField(const Field &input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a new 1D vector with the current state of the instance. The output
|
||||||
|
* order is given by the given species name vector set earlier and/or added
|
||||||
|
* values using the [] operator.
|
||||||
|
*
|
||||||
|
* \return 1D STL vector stored each column one after another.
|
||||||
|
*/
|
||||||
|
auto AsVector() const -> FieldColumn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a new 2D vector with the current state of the instance. The output
|
||||||
|
* order is given by the given species name vector set earlier and/or added
|
||||||
|
* values using the [] operator.
|
||||||
|
*
|
||||||
|
* \return 2D STL vector stored each column one after anothe in a new vector
|
||||||
|
* element.
|
||||||
|
*/
|
||||||
|
auto As2DVector() const -> std::vector<FieldColumn>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read in a (previously exported) 1D vector. It has to have the same
|
||||||
|
* dimensions as the current column count times the requested vector size of
|
||||||
|
* this instance. Import order is given by the species name vector.
|
||||||
|
*
|
||||||
|
* \param cont_field 1D field as vector.
|
||||||
|
*
|
||||||
|
* \exception std::runtime_error Input vector does not match the expected
|
||||||
|
* size.
|
||||||
|
*/
|
||||||
|
void SetFromVector(const FieldColumn &cont_field);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read in a (previously exported) 2D vector. It has to have the same
|
||||||
|
* dimensions as the current column count of this instance and each vector
|
||||||
|
* must have the size of the requested vector size. Import order is given by
|
||||||
|
* the species name vector.
|
||||||
|
*
|
||||||
|
* \param cont_field 2D field as vector.
|
||||||
|
*
|
||||||
|
* \exception std::runtime_error Input vector has more or less elements than
|
||||||
|
* the instance or a column vector does not match expected vector size.
|
||||||
|
*/
|
||||||
|
void SetFromVector(const std::vector<FieldColumn> &cont_field);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const uint32_t req_vec_size;
|
||||||
|
|
||||||
|
std::vector<std::string> props;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace poet
|
||||||
|
#endif // FIELD_H_
|
||||||
@ -1,3 +1,5 @@
|
|||||||
|
add_subdirectory(DataStructures)
|
||||||
|
|
||||||
file(GLOB poet_lib_SRC
|
file(GLOB poet_lib_SRC
|
||||||
CONFIGURE_DEPENDS
|
CONFIGURE_DEPENDS
|
||||||
"*.cpp" "*.c")
|
"*.cpp" "*.c")
|
||||||
@ -10,7 +12,7 @@ option(POET_DHT_DEBUG "Build with DHT debug info" OFF)
|
|||||||
add_library(poet_lib ${poet_lib_SRC})
|
add_library(poet_lib ${poet_lib_SRC})
|
||||||
target_include_directories(poet_lib PUBLIC ${PROJECT_SOURCE_DIR}/include)
|
target_include_directories(poet_lib PUBLIC ${PROJECT_SOURCE_DIR}/include)
|
||||||
target_link_libraries(poet_lib PUBLIC
|
target_link_libraries(poet_lib PUBLIC
|
||||||
MPI::MPI_C ${MATH_LIBRARY} ${CRYPTO_LIBRARY} RRuntime tug PhreeqcRM)
|
MPI::MPI_C ${MATH_LIBRARY} ${CRYPTO_LIBRARY} RRuntime tug PhreeqcRM DataStructures)
|
||||||
target_compile_definitions(poet_lib PUBLIC STRICT_R_HEADERS OMPI_SKIP_MPICXX)
|
target_compile_definitions(poet_lib PUBLIC STRICT_R_HEADERS OMPI_SKIP_MPICXX)
|
||||||
|
|
||||||
if(POET_DHT_DEBUG)
|
if(POET_DHT_DEBUG)
|
||||||
|
|||||||
6
src/DataStructures/CMakeLists.txt
Normal file
6
src/DataStructures/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
file(GLOB DataStructures_SRC
|
||||||
|
CONFIGURE_DEPENDS
|
||||||
|
"*.cpp" "*.c")
|
||||||
|
|
||||||
|
add_library(DataStructures ${DataStructures_SRC})
|
||||||
|
target_include_directories(DataStructures PUBLIC ${PROJECT_SOURCE_DIR}/include)
|
||||||
134
src/DataStructures/Field.cpp
Normal file
134
src/DataStructures/Field.cpp
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
#include "poet/Field.hpp"
|
||||||
|
#include <cstdint>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
void poet::Field::InitFromVec(const std::vector<std::vector<double>> &input,
|
||||||
|
const std::vector<std::string> &prop_vec) {
|
||||||
|
if (prop_vec.size() != input.size()) {
|
||||||
|
throw std::runtime_error("Prop vector shall name all elements.");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto name_it = prop_vec.begin();
|
||||||
|
|
||||||
|
for (const auto &in_vec : input) {
|
||||||
|
if (in_vec.size() != req_vec_size) {
|
||||||
|
throw std::runtime_error(
|
||||||
|
"Input vector doesn't match expected vector size.");
|
||||||
|
}
|
||||||
|
this->insert({*(name_it++), in_vec});
|
||||||
|
}
|
||||||
|
|
||||||
|
this->props = prop_vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
void poet::Field::InitFromVec(const std::vector<double> &input,
|
||||||
|
const std::vector<std::string> &prop_vec) {
|
||||||
|
const uint32_t expected_size = prop_vec.size() * req_vec_size;
|
||||||
|
|
||||||
|
if (expected_size != input.size()) {
|
||||||
|
throw std::runtime_error(
|
||||||
|
"Input vector have more (or less) elements than expected.");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto name_it = prop_vec.begin();
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < expected_size; i += req_vec_size) {
|
||||||
|
auto input_pair = std::make_pair(
|
||||||
|
*(name_it++), std::vector<double>(&input[i], &input[i + req_vec_size]));
|
||||||
|
this->insert(input_pair);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->props = prop_vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto poet::Field::AsVector() const -> poet::FieldColumn {
|
||||||
|
const uint32_t min_size = req_vec_size * this->size();
|
||||||
|
|
||||||
|
poet::FieldColumn output;
|
||||||
|
output.reserve(min_size);
|
||||||
|
|
||||||
|
for (const auto &elem : props) {
|
||||||
|
const auto map_it = this->find(elem);
|
||||||
|
|
||||||
|
const auto start = map_it->second.begin();
|
||||||
|
const auto end = map_it->second.end();
|
||||||
|
|
||||||
|
output.insert(output.end(), start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void poet::Field::SetFromVector(const poet::FieldColumn &cont_field) {
|
||||||
|
if (cont_field.size() != this->size() * req_vec_size) {
|
||||||
|
throw std::runtime_error(
|
||||||
|
"Field::SetFromVector: vector does not match expected size");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t vec_p = 0;
|
||||||
|
for (const auto &elem : props) {
|
||||||
|
const auto start = cont_field.begin() + vec_p;
|
||||||
|
const auto end = start + req_vec_size;
|
||||||
|
|
||||||
|
const auto map_it = this->find(elem);
|
||||||
|
|
||||||
|
map_it->second = FieldColumn(start, end);
|
||||||
|
|
||||||
|
vec_p += req_vec_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void poet::Field::SetFromVector(
|
||||||
|
const std::vector<poet::FieldColumn> &cont_field) {
|
||||||
|
if (cont_field.size() != this->size()) {
|
||||||
|
throw std::runtime_error(
|
||||||
|
"Input field contains more or less elements than this container.");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto in_field_it = cont_field.begin();
|
||||||
|
|
||||||
|
for (const auto &elem : props) {
|
||||||
|
if (in_field_it->size() != req_vec_size) {
|
||||||
|
throw std::runtime_error(
|
||||||
|
"One vector contains more or less elements than expected.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto map_it = this->find(elem);
|
||||||
|
|
||||||
|
map_it->second = *(in_field_it++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void poet::Field::UpdateFromField(const poet::Field &input) {
|
||||||
|
for (const auto &input_elem : input) {
|
||||||
|
auto it_self = this->find(input_elem.first);
|
||||||
|
if (it_self == this->end()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
it_self->second = input_elem.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto poet::Field::As2DVector() const -> std::vector<poet::FieldColumn> {
|
||||||
|
std::vector<poet::FieldColumn> output;
|
||||||
|
output.reserve(this->size());
|
||||||
|
|
||||||
|
for (const auto &elem : props) {
|
||||||
|
const auto map_it = this->find(elem);
|
||||||
|
output.push_back(map_it->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
poet::FieldColumn &poet::Field::operator[](const std::string &key) {
|
||||||
|
if (this->find(key) == this->end()) {
|
||||||
|
props.push_back(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::unordered_map<std::string, FieldColumn>::operator[](key);
|
||||||
|
}
|
||||||
11
test/CMakeLists.txt
Normal file
11
test/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
file(GLOB test_SRC
|
||||||
|
CONFIGURE_DEPENDS
|
||||||
|
"*.cpp" "*.c")
|
||||||
|
|
||||||
|
add_executable(testPOET ${test_SRC})
|
||||||
|
target_link_libraries(testPOET doctest poet_lib)
|
||||||
|
|
||||||
|
add_custom_target(check
|
||||||
|
COMMAND $<TARGET_FILE:testPOET>
|
||||||
|
DEPENDS testPOET
|
||||||
|
)
|
||||||
2
test/setup.cpp
Normal file
2
test/setup.cpp
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
|
||||||
|
#include <doctest/doctest.h>
|
||||||
175
test/testDataStructures.cpp
Normal file
175
test/testDataStructures.cpp
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <doctest/doctest.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <poet/Field.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using namespace poet;
|
||||||
|
|
||||||
|
#define CHECK_AND_FAIL_LOOP(val1, val2) \
|
||||||
|
if (val1 != val2) { \
|
||||||
|
FAIL_CHECK("Value differs: ", val1, " != ", val2); \
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Field") {
|
||||||
|
constexpr uint32_t VEC_SIZE = 5;
|
||||||
|
constexpr uint32_t VEC_COUNT = 3;
|
||||||
|
constexpr double INIT_VAL = 1;
|
||||||
|
|
||||||
|
Field dut(VEC_SIZE);
|
||||||
|
|
||||||
|
std::vector<std::string> names = {"C", "Ca", "Na"};
|
||||||
|
std::vector<FieldColumn> init_values(names.size(),
|
||||||
|
FieldColumn(VEC_SIZE, INIT_VAL));
|
||||||
|
|
||||||
|
SUBCASE("Initialize field with 2D vector") {
|
||||||
|
dut.InitFromVec(init_values, names);
|
||||||
|
|
||||||
|
auto props = dut.GetProps();
|
||||||
|
|
||||||
|
CHECK_EQ(names.size(), props.size());
|
||||||
|
|
||||||
|
const auto res = dut["C"];
|
||||||
|
|
||||||
|
CHECK_EQ(res.size(), VEC_SIZE);
|
||||||
|
|
||||||
|
for (const auto &elem : res) {
|
||||||
|
CHECK_AND_FAIL_LOOP(elem, INIT_VAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("Initialize field with 2D vector") {
|
||||||
|
std::vector<double> init_values(VEC_SIZE * VEC_COUNT, 1);
|
||||||
|
dut.InitFromVec(init_values, names);
|
||||||
|
|
||||||
|
auto props = dut.GetProps();
|
||||||
|
|
||||||
|
CHECK_EQ(names.size(), props.size());
|
||||||
|
|
||||||
|
const auto res = dut["C"];
|
||||||
|
|
||||||
|
CHECK_EQ(res.size(), VEC_SIZE);
|
||||||
|
|
||||||
|
for (const auto &elem : res) {
|
||||||
|
CHECK_AND_FAIL_LOOP(elem, INIT_VAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dut.InitFromVec(init_values, names);
|
||||||
|
|
||||||
|
SUBCASE("Return vector") {
|
||||||
|
std::vector<double> output = dut.AsVector();
|
||||||
|
|
||||||
|
CHECK(output.size() == VEC_SIZE * VEC_COUNT);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr double NEW_VAL = 2.;
|
||||||
|
std::vector<double> new_val_vec(VEC_SIZE, NEW_VAL);
|
||||||
|
|
||||||
|
dut["C"] = new_val_vec;
|
||||||
|
|
||||||
|
SUBCASE("Check manipulation of column") {
|
||||||
|
|
||||||
|
auto test_it = new_val_vec.begin();
|
||||||
|
|
||||||
|
for (const auto &val : dut["C"]) {
|
||||||
|
CHECK_EQ(val, *test_it);
|
||||||
|
test_it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("Check correctly manipulated values of 1D vector") {
|
||||||
|
auto out_res = dut.AsVector();
|
||||||
|
auto out_it = out_res.begin();
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < VEC_SIZE; i++, out_it++) {
|
||||||
|
CHECK_AND_FAIL_LOOP(NEW_VAL, *out_it);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; out_it != out_res.end(); out_it++) {
|
||||||
|
CHECK_AND_FAIL_LOOP(INIT_VAL, *out_it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> new_field(VEC_SIZE * VEC_COUNT);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < VEC_COUNT; i++) {
|
||||||
|
for (uint32_t j = 0; j < VEC_SIZE; j++) {
|
||||||
|
new_field[j + (i * VEC_SIZE)] = (double)(i + 1) / (double)(j + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dut.SetFromVector(new_field);
|
||||||
|
|
||||||
|
SUBCASE("SetFromVector return correct field vector") {
|
||||||
|
auto ret_vec = dut.AsVector();
|
||||||
|
|
||||||
|
auto ret_it = ret_vec.begin();
|
||||||
|
auto new_it = new_field.begin();
|
||||||
|
|
||||||
|
for (; ret_it != ret_vec.end(); ret_it++, new_it++) {
|
||||||
|
CHECK_AND_FAIL_LOOP(*ret_it, *new_it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("Get single column with new values") {
|
||||||
|
auto new_it = new_field.begin() + 2 * VEC_SIZE;
|
||||||
|
auto ret_vec = dut["Na"];
|
||||||
|
auto ret_it = ret_vec.begin();
|
||||||
|
|
||||||
|
CHECK_EQ(ret_vec.size(), VEC_SIZE);
|
||||||
|
|
||||||
|
for (; ret_it != ret_vec.end(); ret_it++, new_it++) {
|
||||||
|
CHECK_AND_FAIL_LOOP(*ret_it, *new_it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> mg_vec = {1, 2, 3, 4, 5};
|
||||||
|
dut["Mg"] = mg_vec;
|
||||||
|
|
||||||
|
SUBCASE("Operator creates new element and places it at the end") {
|
||||||
|
|
||||||
|
auto new_props = dut.GetProps();
|
||||||
|
|
||||||
|
CHECK_EQ(new_props.size(), 4);
|
||||||
|
CHECK_EQ(new_props[3], "Mg");
|
||||||
|
|
||||||
|
auto ret_vec = dut.As2DVector();
|
||||||
|
auto mg_vec_it = mg_vec.begin();
|
||||||
|
|
||||||
|
for (const auto &val : ret_vec[3]) {
|
||||||
|
CHECK_AND_FAIL_LOOP(val, *(mg_vec_it++));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset field
|
||||||
|
names = dut.GetProps();
|
||||||
|
dut.SetFromVector(
|
||||||
|
std::vector<FieldColumn>(names.size(), FieldColumn(VEC_SIZE, INIT_VAL)));
|
||||||
|
|
||||||
|
constexpr double SOME_OTHER_VAL = -0.5;
|
||||||
|
Field some_other_field(VEC_SIZE);
|
||||||
|
std::vector<std::string> some_other_props = {"Na", "Cl"};
|
||||||
|
std::vector<double> some_other_values(VEC_SIZE * some_other_props.size(),
|
||||||
|
SOME_OTHER_VAL);
|
||||||
|
|
||||||
|
some_other_field.InitFromVec(some_other_values, some_other_props);
|
||||||
|
|
||||||
|
SUBCASE("Update existing field from another field") {
|
||||||
|
dut.UpdateFromField(some_other_field);
|
||||||
|
|
||||||
|
auto ret_vec = dut.As2DVector();
|
||||||
|
auto ret_it = ret_vec.begin();
|
||||||
|
|
||||||
|
for (const auto &prop : names) {
|
||||||
|
const auto &curr_vec = *(ret_it++);
|
||||||
|
|
||||||
|
for (const auto &val : curr_vec) {
|
||||||
|
CHECK_AND_FAIL_LOOP((prop == "Na" ? SOME_OTHER_VAL : INIT_VAL), val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user