15template<
typename T = std::
size_t>
16std::tuple<std::vector<T>, std::vector<T>, std::vector<T>> generate_cartesian_product(std::size_t low_nx, std::size_t up_nx,
17 std::size_t low_ny, std::size_t up_ny,
18 std::size_t low_nz, std::size_t up_nz){
19 std::size_t list_size = (up_nx - low_nx + 1) * (up_ny - low_ny + 1) * (up_nz - low_nz + 1);
20 std::vector<T> i_list(list_size);
21 std::vector<T> j_list(list_size);
22 std::vector<T> k_list(list_size);
23 std::size_t index = 0;
24 for (std::size_t k_index = low_nz; k_index <= up_nz; k_index++)
26 for (std::size_t j_index = low_ny; j_index <= up_ny; j_index++)
28 for (std::size_t i_index = low_nx; i_index <= up_nx; i_index++)
30 i_list[index] = i_index;
31 j_list[index] = j_index;
32 k_list[index] = k_index;
37 return std::make_tuple(i_list, j_list, k_list);
42template <
typename T =
double>
43std::tuple<std::array<T,4>, std::array<T,4>, std::array<T,4>>
44appendNode(
const std::array<T,3>& X,
const std::array<T,3>& Y,
const std::array<T,3>& Z,
45 const T& xc,
const T& yc,
const T& zc)
50 std::copy(X.begin(), X.end(), tX.begin());
52 std::copy(Y.begin(), Y.end(), tY.begin());
54 std::copy(Z.begin(), Z.end(), tZ.begin());
56 return std::make_tuple(tX,tY,tZ);
60template <
typename T,
typename Operation>
61std::vector<T> vectorOperation(
const std::vector<T>& vecA,
const std::vector<T>& vecB, Operation op) {
62 if (vecA.size() != vecB.size()) {
63 throw std::invalid_argument(
"Error: Vectors must have the same size!");
65 std::vector<T> result;
66 result.reserve(vecA.size());
68 std::transform(vecA.begin(), vecA.end(), vecB.begin(), std::back_inserter(result), op);
73template <
typename T,
typename Operation>
74std::vector<T> vectorScalarOperation(
const std::vector<T>& vecA,
const T& scalar, Operation op) {
75 std::vector<T> result;
76 result.reserve(vecA.size());
78 std::transform(vecA.begin(), vecA.end(), std::back_inserter(result),
79 [&scalar, &op](
const T& a) { return op(scalar, a); });
84template <
typename T,
typename Operation>
85std::vector<T> scalarVectorOperation(
const T& scalar,
const std::vector<T>& vecA, Operation op) {
86 std::vector<T> result;
87 result.reserve(vecA.size());
89 std::transform(vecA.begin(), vecA.end(), std::back_inserter(result),
90 [&scalar, &op](
const T& a) { return op(a, scalar); });
95template <
typename T,
typename Operation>
96void scalarVectorOperation(
const T& scalar, std::vector<T>& vecA, Operation op) {
97 std::transform(vecA.begin(), vecA.end(), vecA.begin(),
98 [&scalar, &op](
const T& a) { return op(a, scalar); });
102std::tuple<std::array<double,4>, std::array<double,4>, std::array<double,4>>
103appendNode(
const std::array<double,3>&,
const std::array<double,3>&,
104 const std::array<double,3>&,
const double&,
const double&,
108std::vector<T> filterArray(
const std::vector<T>& X,
const std::vector<int>& ind){
109 std::vector<T> filtered_vectorX(ind.size(),0);
110 for (std::size_t index = 0; index < ind.size(); index++) {
111 filtered_vectorX[index] = X[ind[index]];
113 return filtered_vectorX;
117std::vector<T> filterArray(
const std::vector<std::size_t>& X,
const std::vector<int>& ind){
118 std::vector<T> filtered_vectorX(ind.size(),0);
119 for (std::size_t index = 0; index < ind.size(); index++) {
120 filtered_vectorX[index] = X[ind[index]];
122 return filtered_vectorX;
128template <
typename T,
typename Rout,
typename Rin = std::size_t,
typename Method,
typename... Args>
129std::vector<Rout> callMethodForEachInputOnObject(
const T& obj, Method mtd,
const std::vector<Rin>& input_vector, Args&&... args) {
130 std::vector<Rout> result;
132 result.reserve(input_vector.size());
134 for (
const auto& element : input_vector) {
135 Rout value = (obj.*mtd)(element, std::forward<Args>(args)...);
136 result.push_back(std::move(value));
144std::tuple<std::vector<T>,std::vector<T>, std::vector<T>> splitXYZ(std::vector<std::array<T,3>>& input_vector ){
145std::vector<T> X, Y, Z;
146 X.reserve(input_vector.size());
147 Y.reserve(input_vector.size());
148 Z.reserve(input_vector.size());
149 for (
auto& element : input_vector) {
150 X.push_back(std::move(element[0]));
151 Y.push_back(std::move(element[1]));
152 Z.push_back(std::move(element[2]));
154 return std::make_tuple(X,Y,Z);
158template <
typename T,
typename Rout,
typename Rin = std::size_t,
typename Method,
typename... Args>
159auto callMethodForEachInputOnObjectXYZ(
const T& obj, Method mtd,
const std::vector<Rin>& input_vector, Args&&... args) {
160 using X =
typename Rout::value_type;
161 auto result = callMethodForEachInputOnObject<T, Rout, Rin, Method, Args...>(obj, mtd, input_vector, std::forward<Args>(args)...);
162 return splitXYZ<X>(result);