-
Notifications
You must be signed in to change notification settings - Fork 246
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #12706 from KratosMultiphysics/siapp/add_distance_…
…matrix [SIApp] Add distance matrix
- Loading branch information
Showing
5 changed files
with
245 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
119 changes: 119 additions & 0 deletions
119
applications/SystemIdentificationApplication/custom_utilities/distance_matrix.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
// | / | | ||
// ' / __| _` | __| _ \ __| | ||
// . \ | ( | | ( |\__ ` | ||
// _|\_\_| \__,_|\__|\___/ ____/ | ||
// Multi-Physics | ||
// | ||
// License: SystemIdentificationApplication/license.txt | ||
// | ||
// Main authors: Suneth Warnakulasuriya | ||
// | ||
|
||
// System includes | ||
#include <cmath> | ||
|
||
// External includes | ||
|
||
// Project includes | ||
#include "utilities/parallel_utilities.h" | ||
|
||
// Application includes | ||
|
||
// Include base h | ||
#include "distance_matrix.h" | ||
|
||
namespace Kratos { | ||
///@name Kratos Classes | ||
///@{ | ||
|
||
DistanceMatrix::DistanceMatrix() | ||
: mN(0) | ||
{ | ||
} | ||
|
||
void DistanceMatrix::Update( | ||
std::variant< | ||
ContainerExpression<ModelPart::NodesContainerType>::Pointer, | ||
ContainerExpression<ModelPart::ConditionsContainerType>::Pointer, | ||
ContainerExpression<ModelPart::ElementsContainerType>::Pointer> pDistancesExpression) | ||
{ | ||
KRATOS_TRY | ||
|
||
std::visit([&](const auto& pExp) { | ||
this->mN = pExp->GetContainer().size(); | ||
this->mDistances.resize(this->GetEntriesSize()); | ||
|
||
const auto& r_expression = pExp->GetExpression(); | ||
const auto dimensionality = r_expression.GetItemComponentCount(); | ||
|
||
IndexPartition<IndexType>(this->mDistances.size()).for_each([&](const auto Index) { | ||
const auto& index_pair = GetIndexPair(Index); | ||
|
||
const auto i_index = std::get<0>(index_pair); | ||
const auto i_data_begin = i_index * dimensionality; | ||
const auto j_index = std::get<1>(index_pair); | ||
const auto j_data_begin = j_index * dimensionality; | ||
|
||
double distance = 0.0; | ||
|
||
for (IndexType i_comp = 0; i_comp < dimensionality; ++i_comp) { | ||
const double i_value = r_expression.Evaluate(i_index, i_data_begin, i_comp); | ||
const double j_value = r_expression.Evaluate(j_index, j_data_begin, i_comp); | ||
distance += std::pow(i_value - j_value, 2.0); | ||
} | ||
|
||
mDistances[Index] = std::sqrt(distance); | ||
}); | ||
}, pDistancesExpression); | ||
|
||
KRATOS_CATCH(""); | ||
} | ||
|
||
double DistanceMatrix::GetDistance( | ||
const IndexType iIndex, | ||
const IndexType jIndex) const | ||
{ | ||
auto ordered_i = iIndex; | ||
auto ordered_j = jIndex; | ||
if (ordered_i != ordered_j) { | ||
if (ordered_j < ordered_i) { | ||
std::swap(ordered_i, ordered_j); | ||
} | ||
return mDistances[GetEntryIndex(ordered_i, ordered_j)]; | ||
} else { | ||
return 0.0; | ||
} | ||
} | ||
|
||
double DistanceMatrix::GetDistance(const IndexType EntryIndex) const | ||
{ | ||
return mDistances[EntryIndex]; | ||
} | ||
|
||
IndexType DistanceMatrix::GetEntriesSize() const | ||
{ | ||
return this->mN * (this->mN - 1) / 2; | ||
} | ||
|
||
IndexType DistanceMatrix::GetNumberOfItems() const | ||
{ | ||
return this->mN; | ||
} | ||
|
||
IndexType DistanceMatrix::GetEntryIndex( | ||
const IndexType iIndex, | ||
const IndexType jIndex) const | ||
{ | ||
return this->mN * iIndex + jIndex - ((iIndex + 2) * (iIndex + 1)) / 2; | ||
} | ||
|
||
std::tuple<IndexType, IndexType> DistanceMatrix::GetIndexPair(const IndexType EntryIndex) const | ||
{ | ||
|
||
const IndexType i = static_cast<IndexType>(std::floor(this->mN - 0.5 - std::sqrt(std::pow(this->mN - 0.5, 2) - 2 * EntryIndex))); | ||
const IndexType j = static_cast<IndexType>(EntryIndex - this->mN * i + (i + 1) * (i + 2) / 2); | ||
|
||
return std::make_tuple(i, j); | ||
} | ||
|
||
} /* namespace Kratos.*/ |
88 changes: 88 additions & 0 deletions
88
applications/SystemIdentificationApplication/custom_utilities/distance_matrix.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
// | / | | ||
// ' / __| _` | __| _ \ __| | ||
// . \ | ( | | ( |\__ ` | ||
// _|\_\_| \__,_|\__|\___/ ____/ | ||
// Multi-Physics | ||
// | ||
// License: SystemIdentificationApplication/license.txt | ||
// | ||
// Main authors: Suneth Warnakulasuriya | ||
// | ||
|
||
#pragma once | ||
|
||
// System includes | ||
#include <tuple> | ||
#include <variant> | ||
|
||
// External includes | ||
|
||
// Project includes | ||
#include "includes/define.h" | ||
#include "includes/model_part.h" | ||
#include "expression/container_expression.h" | ||
|
||
// Application includes | ||
|
||
namespace Kratos { | ||
///@name Kratos Classes | ||
///@{ | ||
|
||
class KRATOS_API(SYSTEM_IDENTIFICATION_APPLICATION) DistanceMatrix | ||
{ | ||
public: | ||
///@name Type definitions | ||
///@{ | ||
|
||
using IndexType = std::size_t; | ||
|
||
KRATOS_CLASS_POINTER_DEFINITION(DistanceMatrix); | ||
|
||
///@} | ||
///@name Life cycle | ||
///@{ | ||
|
||
DistanceMatrix(); | ||
|
||
///@} | ||
///@name Public operations | ||
///@{ | ||
|
||
double GetDistance( | ||
const IndexType iIndex, | ||
const IndexType jIndex) const; | ||
|
||
double GetDistance(const IndexType EntryIndex) const; | ||
|
||
IndexType GetEntriesSize() const; | ||
|
||
IndexType GetEntryIndex( | ||
const IndexType iIndex, | ||
const IndexType jIndex) const; | ||
|
||
std::tuple<IndexType, IndexType> GetIndexPair(const IndexType iEntryIndex) const; | ||
|
||
IndexType GetNumberOfItems() const; | ||
|
||
void Update( | ||
std::variant< | ||
ContainerExpression<ModelPart::NodesContainerType>::Pointer, | ||
ContainerExpression<ModelPart::ConditionsContainerType>::Pointer, | ||
ContainerExpression<ModelPart::ElementsContainerType>::Pointer> pDistancesExpression); | ||
|
||
///@} | ||
|
||
private: | ||
///@name Private member variables | ||
///@{ | ||
|
||
std::vector<double> mDistances; | ||
|
||
IndexType mN; | ||
|
||
///@} | ||
}; | ||
|
||
///@} // Kratos Classes | ||
|
||
} /* namespace Kratos.*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
applications/SystemIdentificationApplication/tests/test_distance_matrix.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import KratosMultiphysics as Kratos | ||
import KratosMultiphysics.SystemIdentificationApplication as KratosSI | ||
import KratosMultiphysics.KratosUnittest as UnitTest | ||
|
||
class TestDistanceMatrix(UnitTest.TestCase): | ||
@classmethod | ||
def setUpClass(cls) -> None: | ||
cls.model = Kratos.Model() | ||
cls.model_part = cls.model.CreateModelPart("test") | ||
|
||
for i in range(101): | ||
cls.model_part.CreateNewNode(i + 1, i + 1, i + 2, i + 3) | ||
|
||
cls.distance_matrix = KratosSI.DistanceMatrix() | ||
|
||
exp = Kratos.Expression.NodalExpression(cls.model_part) | ||
Kratos.Expression.NodalPositionExpressionIO.Read(exp, Kratos.Configuration.Initial) | ||
cls.distance_matrix.Update(exp) | ||
|
||
def test_GetDistance1(self) -> None: | ||
for i, node_i in enumerate(self.model_part.Nodes): | ||
for j, node_j in enumerate(self.model_part.Nodes): | ||
distance = ((node_i.X - node_j.X) ** 2 + (node_i.Y - node_j.Y) ** 2 + (node_i.Z - node_j.Z) ** 2) ** (0.5) | ||
self.assertAlmostEqual(self.distance_matrix.GetDistance(i, j), distance) | ||
|
||
if __name__ == '__main__': | ||
UnitTest.main() |