diff --git a/kratos/includes/kratos_parameters.h b/kratos/includes/kratos_parameters.h index 9b774fe2b1a6..67f1178be503 100644 --- a/kratos/includes/kratos_parameters.h +++ b/kratos/includes/kratos_parameters.h @@ -592,6 +592,12 @@ class KRATOS_API(KRATOS_CORE) Parameters */ Vector GetVector() const; + /** + * @brief This method returns the vector of vectors contained in the current Parameter + * @return The vector of vectors value + */ + std::vector GetVectorArray() const; + /** * @brief This method returns the matrix contained in the current Parameter * @return The matrix value diff --git a/kratos/sources/kratos_parameters.cpp b/kratos/sources/kratos_parameters.cpp index c1074bdc1697..9bc5c0cc83d1 100644 --- a/kratos/sources/kratos_parameters.cpp +++ b/kratos/sources/kratos_parameters.cpp @@ -720,6 +720,45 @@ Vector Parameters::GetVector() const return aux_V; } +/***********************************************************************************/ +/***********************************************************************************/ + +std::vector Parameters::GetVectorArray() const +{ + KRATOS_ERROR_IF_NOT(mpValue->is_array()) << "Argument must be an array of arrays (a json list of lists)" << std::endl; + + const SizeType n_vectors = mpValue->size(); + if (n_vectors == 0) { + return {}; + } + + // Check the size of the first vector + const auto& first_row = (*mpValue)[0]; + KRATOS_ERROR_IF_NOT(first_row.is_array()) << "Entry 0 is not an array!" << std::endl; + const SizeType n_components = first_row.size(); + + std::vector aux_VA; + aux_VA.reserve(n_vectors); + + for (IndexType i = 0; i < n_vectors; ++i) { + const auto& row = (*mpValue)[i]; + KRATOS_ERROR_IF_NOT(row.is_array()) << "Entry " << i << " is not an array!" << std::endl; + KRATOS_ERROR_IF_NOT(row.size() == n_components) + << "All inner arrays must have the same size. Entry 0 has size " << n_components + << ", but entry " << i << " has size " << row.size() << std::endl; + + Vector v(n_components); + for (IndexType j = 0; j < n_components; ++j) { + KRATOS_ERROR_IF_NOT(row[j].is_number()) << "Entry (" << i << "," << j << ") is not a number!" << std::endl; + v(j) = row[j].get(); + } + aux_VA.push_back(std::move(v)); + } + + return aux_VA; +} + + /***********************************************************************************/ /***********************************************************************************/ diff --git a/kratos/tests/cpp_tests/sources/test_kratos_parameters.cpp b/kratos/tests/cpp_tests/sources/test_kratos_parameters.cpp index 86294e61f71d..c6daa098d972 100644 --- a/kratos/tests/cpp_tests/sources/test_kratos_parameters.cpp +++ b/kratos/tests/cpp_tests/sources/test_kratos_parameters.cpp @@ -884,6 +884,88 @@ KRATOS_TEST_CASE_IN_SUITE(KratosParametersVectorInterface, KratosCoreFastSuite) KRATOS_EXPECT_VECTOR_EQ(V2,vec); } +KRATOS_TEST_CASE_IN_SUITE(KratosParametersGetVectorArrayInterface, KratosCoreFastSuite) +{ + // Valid input: 3D vectors + Parameters tmp(R"({ + "not_array":{}, + "empty_vectors": [], + "not_vectors": 5, + "first_not_array": [ + 1.0, + [2.0, 3.0] + ], + "vectors3D": [ + [1.0, 2.0, 3.0], + [4.0, 5.0, 6.0], + [7.0, 8.0, 9.0] + ], + "vectors2D": [ + [1.0, 2.0], + [3.0, 4.0] + ], + "bad_size": [ + [1.0, 2.0, 3.0], + [4.0, 5.0] + ], + "inner_not_array": [ + [1.0, 2.0, 3.0], + 5.0 + ], + "not_number": [ + [1.0, 2.0, "foo"], + [4.0, 5.0, 6.0] + ] + })"); + + const auto vectors3D = tmp["vectors3D"].GetVectorArray(); + KRATOS_EXPECT_EQ(vectors3D.size(), 3); + for (std::size_t i = 0; i < vectors3D.size(); ++i) { + KRATOS_EXPECT_EQ(vectors3D[i].size(), 3); + for (std::size_t j = 0; j < 3; ++j) { + KRATOS_EXPECT_DOUBLE_EQ(vectors3D[i][j], 3.0 * i + j + 1.0); + } + } + + const auto vectors2D = tmp["vectors2D"].GetVectorArray(); + KRATOS_EXPECT_EQ(vectors2D.size(), 2); + for (std::size_t i = 0; i < vectors2D.size(); ++i) { + KRATOS_EXPECT_EQ(vectors2D[i].size(), 2); + } + + KRATOS_EXPECT_EQ(tmp["empty_vectors"].GetVectorArray().size(), 0); + + KRATOS_EXPECT_EXCEPTION_IS_THROWN( + tmp["not_array"].GetVectorArray(), + "Argument must be an array of arrays" + ); + + KRATOS_EXPECT_EXCEPTION_IS_THROWN( + tmp["not_vectors"].GetVectorArray(), + "Argument must be an array of arrays" +); + + KRATOS_EXPECT_EXCEPTION_IS_THROWN( + tmp["first_not_array"].GetVectorArray(), + "Entry 0 is not an array" + ); + + KRATOS_EXPECT_EXCEPTION_IS_THROWN( + tmp["bad_size"].GetVectorArray(), + "All inner arrays must have the same size" + ); + + KRATOS_EXPECT_EXCEPTION_IS_THROWN( + tmp["inner_not_array"].GetVectorArray(), + "Entry 1 is not an array" + ); + + KRATOS_EXPECT_EXCEPTION_IS_THROWN( + tmp["not_number"].GetVectorArray(), + "Entry (0,2) is not a number" + ); +} + KRATOS_TEST_CASE_IN_SUITE(KratosParametersMatrixInterface, KratosCoreFastSuite) { // Read and check Matrices from a Parameters-Object