Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change signs in thermodynamic force update and apply #37

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions mrmd/action/ThermodynamicForce.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ void ThermodynamicForce::update(const real_t& smoothingSigma, const real_t& smoo
auto smoothedDensityGradient = data::gradient(smoothedDensityProfile, usePeriodicity_);
smoothedDensityGradient.scale(forceFactor_);

force_ += smoothedDensityGradient;
force_ -= smoothedDensityGradient;

// reset sampling data
Kokkos::deep_copy(densityProfile_.data, 0_r);
Expand All @@ -125,7 +125,7 @@ void ThermodynamicForce::apply(const data::Atoms& atoms) const
{
MRMD_DEVICE_ASSERT_LESS(atomsType(idx), forceHistogram.numHistograms);
MRMD_DEVICE_ASSERT(!std::isnan(forceHistogram.data(bin, atomsType(idx))));
atomsForce(idx, 0) -= forceHistogram.data(bin, atomsType(idx));
atomsForce(idx, 0) += forceHistogram.data(bin, atomsType(idx));
}
};
Kokkos::parallel_for("ThermodynamicForce::apply", policy, kernel);
Expand All @@ -150,7 +150,7 @@ void ThermodynamicForce::apply(const data::Atoms& atoms, const weighting_functio
{
MRMD_DEVICE_ASSERT_LESS(atomsType(idx), forceHistogram.numHistograms);
MRMD_DEVICE_ASSERT(!std::isnan(forceHistogram.data(bin, atomsType(idx))));
atomsForce(idx, 0) -= forceHistogram.data(bin, atomsType(idx));
atomsForce(idx, 0) += forceHistogram.data(bin, atomsType(idx));
}
};
Kokkos::parallel_for("ThermodynamicForce::apply", policy, kernel);
Expand Down Expand Up @@ -178,7 +178,7 @@ void ThermodynamicForce::apply(const data::Atoms& atoms,
{
MRMD_DEVICE_ASSERT_LESS(atomsType(idx), forceHistogram.numHistograms);
MRMD_DEVICE_ASSERT(!std::isnan(forceHistogram.data(bin, atomsType(idx))));
atomsForce(idx, 0) -= forceHistogram.data(bin, atomsType(idx));
atomsForce(idx, 0) += forceHistogram.data(bin, atomsType(idx));
}
};
Kokkos::parallel_for("ThermodynamicForce::apply", policy, kernel);
Expand Down
37 changes: 12 additions & 25 deletions mrmd/data/MultiHistogram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,35 +35,22 @@ ScalarView::HostMirror MultiHistogram::createGrid() const

MultiHistogram& MultiHistogram::operator+=(const MultiHistogram& rhs)
{
if (numBins != rhs.numBins) exit(EXIT_FAILURE);
assert(min == rhs.min);
assert(max == rhs.max);

auto lhs = data;
auto policy = Kokkos::MDRangePolicy<Kokkos::Rank<2>>({0, 0}, {numBins, numHistograms});
auto kernel = KOKKOS_LAMBDA(const idx_t idx, const idx_t jdx)
{
lhs(idx, jdx) += rhs.data(idx, jdx);
};
Kokkos::parallel_for("MultiHistogram::operator+=", policy, kernel);
Kokkos::fence();
transform(*this, rhs, *this, bin_op::Add());
return *this;
}
MultiHistogram& MultiHistogram::operator-=(const MultiHistogram& rhs)
{
transform(*this, rhs, *this, bin_op::Sub());
return *this;
}
MultiHistogram& MultiHistogram::operator*=(const MultiHistogram& rhs)
{
transform(*this, rhs, *this, bin_op::Mul());
return *this;
}

MultiHistogram& MultiHistogram::operator/=(const MultiHistogram& rhs)
{
if (numBins != rhs.numBins) exit(EXIT_FAILURE);
assert(min == rhs.min);
assert(max == rhs.max);

auto lhs = data;
auto policy = Kokkos::MDRangePolicy<Kokkos::Rank<2>>({0, 0}, {numBins, numHistograms});
auto kernel = KOKKOS_LAMBDA(const idx_t idx, const idx_t jdx)
{
lhs(idx, jdx) /= rhs.data(idx, jdx);
};
Kokkos::parallel_for("MultiHistogram::operator/=", policy, kernel);
Kokkos::fence();
transform(*this, rhs, *this, bin_op::Div());
return *this;
}

Expand Down
43 changes: 43 additions & 0 deletions mrmd/data/MultiHistogram.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@

#include "assert/assert.hpp"
#include "datatypes.hpp"
#include "functional.hpp"

namespace mrmd
{
namespace data
{

struct MultiHistogram
{
MultiHistogram(const std::string& label,
Expand Down Expand Up @@ -81,7 +83,10 @@ struct MultiHistogram
MultiView data;

MultiHistogram& operator+=(const MultiHistogram& rhs);
MultiHistogram& operator-=(const MultiHistogram& rhs);
MultiHistogram& operator*=(const MultiHistogram& rhs);
MultiHistogram& operator/=(const MultiHistogram& rhs);

void scale(const real_t& scalingFactor);
void scale(const ScalarView& scalingFactor);
void makeSymmetric();
Expand Down Expand Up @@ -123,5 +128,43 @@ data::MultiHistogram smoothen(data::MultiHistogram& input,
const real_t& range,
const bool periodic = false);

/**
* Applies a binary operation to corresponding elements of two input MultiHistograms and stores
* the result in an output MultiHistogram.
*
* @tparam BinaryOp The type of the binary operation to be applied.
* @param input1 The first input MultiHistogram.
* @param input2 The second input MultiHistogram.
* @param output The MultiHistogram where the result of the binary operation will be stored.
* @param binary_op The binary operation to apply to the elements of input1 and input2.
*
* @pre The dimensions (numBins and numHistograms) of input1, input2, and output must match.
*/

template <class BinaryOp>
void transform(const MultiHistogram& input1,
const MultiHistogram& input2,
MultiHistogram& output,
const BinaryOp& binary_op)
{
MRMD_HOST_CHECK_EQUAL(input1.numHistograms, input2.numHistograms);
MRMD_HOST_CHECK_EQUAL(input1.numHistograms, output.numHistograms);
MRMD_HOST_CHECK_EQUAL(input1.numBins, input2.numBins);
MRMD_HOST_CHECK_EQUAL(input1.numBins, output.numBins);

auto input1Data = input1.data;
auto input2Data = input2.data;
auto outputData = output.data;

auto policy =
Kokkos::MDRangePolicy<Kokkos::Rank<2>>({0, 0}, {input1.numBins, input1.numHistograms});
auto kernel = KOKKOS_LAMBDA(const idx_t idx, const idx_t jdx)
{
outputData(idx, jdx) = binary_op(input1Data(idx, jdx), input2Data(idx, jdx));
};
Kokkos::parallel_for("MultiHistogram::transform", policy, kernel);
Kokkos::fence();
}

} // namespace data
} // namespace mrmd
50 changes: 50 additions & 0 deletions mrmd/data/MultiHistogram.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,56 @@ TEST(MultiHistogram, op_plusequal)
}
}

TEST(MultiHistogram, op_minusequal)
{
MultiHistogram histogram("histogram", 0_r, 10_r, 11, 2);
auto h_data = Kokkos::create_mirror_view(histogram.data);
h_data(5, 0) = 10_r;
h_data(5, 1) = 5_r;
Kokkos::deep_copy(histogram.data, h_data);

MultiHistogram histogram2("histogram", 0_r, 10_r, 11, 2);
auto h_data2 = Kokkos::create_mirror_view(histogram2.data);
h_data2(5, 0) = 8_r;
h_data2(5, 1) = 1_r;
Kokkos::deep_copy(histogram2.data, h_data2);

histogram -= histogram2;

Kokkos::deep_copy(h_data, histogram.data);

for (auto idx = 0; idx < 10; ++idx)
{
EXPECT_FLOAT_EQ(h_data(idx, 0), idx == 5 ? 2_r : 0_r);
EXPECT_FLOAT_EQ(h_data(idx, 1), idx == 5 ? 4_r : 0_r);
}
}

TEST(MultiHistogram, op_mulequal)
{
MultiHistogram histogram("histogram", 0_r, 10_r, 11, 2);
auto h_data = Kokkos::create_mirror_view(histogram.data);
h_data(5, 0) = 10_r;
h_data(5, 1) = 5_r;
Kokkos::deep_copy(histogram.data, h_data);

MultiHistogram histogram2("histogram", 0_r, 10_r, 11, 2);
auto h_data2 = Kokkos::create_mirror_view(histogram2.data);
h_data2(5, 0) = 8_r;
h_data2(5, 1) = 2_r;
Kokkos::deep_copy(histogram2.data, h_data2);

histogram *= histogram2;

Kokkos::deep_copy(h_data, histogram.data);

for (auto idx = 0; idx < 10; ++idx)
{
EXPECT_FLOAT_EQ(h_data(idx, 0), idx == 5 ? 80_r : 0_r);
EXPECT_FLOAT_EQ(h_data(idx, 1), idx == 5 ? 10_r : 0_r);
}
}

TEST(MultiHistogram, op_divequal)
{
MultiHistogram histogram("histogram", 0_r, 10_r, 11, 2);
Expand Down
40 changes: 40 additions & 0 deletions mrmd/functional.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright 2024 Sebastian Eibl
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include "datatypes.hpp"

namespace mrmd
{
namespace bin_op
{
struct Add
{
KOKKOS_INLINE_FUNCTION real_t operator()(real_t x, real_t y) const { return x + y; }
};
struct Sub
{
KOKKOS_INLINE_FUNCTION real_t operator()(real_t x, real_t y) const { return x - y; }
};
struct Mul
{
KOKKOS_INLINE_FUNCTION real_t operator()(real_t x, real_t y) const { return x * y; }
};
struct Div
{
KOKKOS_INLINE_FUNCTION real_t operator()(real_t x, real_t y) const { return x / y; }
};
} // namespace bin_op
} // namespace mrmd