Skip to content

Commit

Permalink
Merge branch 'master' into tempering_update
Browse files Browse the repository at this point in the history
to update temper branch
  • Loading branch information
IVinterbladh committed Jul 15, 2024
2 parents f87b6be + 5b552da commit 831f0fb
Show file tree
Hide file tree
Showing 104 changed files with 11,859 additions and 6,278 deletions.
24 changes: 13 additions & 11 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
Expand All @@ -21,31 +21,32 @@ AlwaysBreakTemplateDeclarations: MultiLine
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterClass: true
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterEnum: true
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterStruct: true
AfterCaseLabel: true
AfterUnion: true
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeCatch: true
BeforeElse: true
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 120
ColumnLimit: 100
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
Expand Down Expand Up @@ -94,8 +95,9 @@ PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Left
ReflowComments: true
SeparateDefinitionBlocks: Always
SortIncludes: false
SortUsingDeclarations: true
SortUsingDeclarations: false
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
Expand Down
12 changes: 6 additions & 6 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
Checks: '*,-fuchsia-*,-google-*,-zircon-*,-abseil-*,-modernize-use-trailing-return-type,-llvm-*,-modernize-use-nodiscard,-llvmlibc-callee-namespace,-cppcoreguidelines-avoid-magic-numbers,-readability-magic-numbers'
Checks: '*,-fuchsia-*,-google-*,-zircon-*,-abseil-*,-modernize-use-trailing-return-type,-llvm-*,-modernize-use-nodiscard,-llvmlibc-callee-namespace,-cppcoreguidelines-avoid-magic-numbers,-readability-magic-numbers,readability-identifier-naming'
WarningsAsErrors: '*'
HeaderFilterRegex: ''
FormatStyle: file
Expand All @@ -10,17 +10,17 @@ CheckOptions:
- { key: readability-identifier-naming.ClassCase, value: CamelCase }
- { key: readability-identifier-naming.StructCase, value: CamelCase }
- { key: readability-identifier-naming.VariableCase, value: lower_case}
- { key: readability-identifier-naming.VariableIgnoredRegexp, value: 'TEST.*'}
- { key: readability-identifier-naming.LocalVariableCase, value: lower_case}
- { key: readability-identifier-naming.FunctionCase, value: lower_case}
- { key: readability-identifier-naming.FunctionIgnoredRegexp, value: '^to_json$|^from_json$'}
- { key: readability-identifier-naming.FunctionIgnoredRegexp, value: 'TEST_.*'}
- { key: readability-identifier-naming.ClassMethodCase, value: lower_case}
- { key: readability-identifier-naming.ClassMethodIgnoredRegexp, value: '^to_json$|^from_json$'}
- { key: readability-identifier-naming.ClassIgnoredRegexp, value: 'TEST_.*'}
- { key: readability-identifier-naming.ParameterCase, value: lower_case}
- { key: readability-identifier-naming.ParameterIgnoredRegexp, value: '^j$'}
- { key: readability-identifier-naming.EnumCase, value: CamelCase}
- { key: readability-identifier-naming.EnumConstantCase, value: CamelCase}
- { key: readability-identifier-naming.ConstantParameterCase, value: lower_case}
- { key: readability-identifier-naming.ConstexprVariableCase,, value: UPPER_CASE}
- { key: readability-identifier-naming.ConstantParameterIgnoredRegexp, value: lower_case}
- { key: readability-identifier-naming.ConstexprVariableCase, value: UPPER_CASE}
- { key: readability-identifier-naming.TypedefCase, value: CamelCase}
- { key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic, value: 'true'}

11 changes: 11 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Run this command to always ignore formatting commits in `git blame`
#
# ~~~
# git config blame.ignoreRevsFile .git-blame-ignore-revs
# ~~~
#
# See: https://www.stefanjudis.com/today-i-learned/how-to-exclude-commits-from-git-blame/

# Apply clang-format (17-jun-2024)
62b6a50d47f6687d8a2e39d562e04c7b3fab0411

10 changes: 0 additions & 10 deletions .idea/inspectionProfiles/Project_Default.xml

This file was deleted.

6 changes: 5 additions & 1 deletion docs/_docs/moves.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,15 @@ Upon MC movement, the mean squared displacement will be tracked.
`molecule` | Molecule name to operate on
`dir=[1,1,1]` | Translational directions
`energy_resolution` | If set to a non-zero value (kT), an energy histogram will be generated.
`dp=0` | Default translational displacement parameter (Å)
`dprot=0` | Default rotational displacement parameter (radians)

As `moltransrot` but instead of operating on the molecular mass center, this translates
and rotates individual atoms in the group. The repeat is set to the number of atoms in the specified group and the
and rotates individual atoms in the group.
The repeat is set to the number of atoms in the specified group and the
displacement parameters `dp` and `dprot` for the individual atoms are taken from
the atom properties defined in the [topology](topology).
If `dp` and `dprot` are not defined for an atom, the default values for the move are used.
Atomic _rotation_ affects only anisotropic particles such as dipoles, spherocylinders, quadrupoles etc.

An energy histogram of each participating species will be written to disk if the `energy_resolution`
Expand Down
4 changes: 2 additions & 2 deletions docs/_docs/topology.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ Atoms are the smallest possible particle entities with properties defined below.
`activity=0` | Chemical activity for grand canonical MC [mol/l]
`pactivity` | −log10 of chemical activity (will be converted to activity)
`alphax=0` | Excess polarizability (unit-less)
`dp=0` | Translational displacement parameter [Å]
`dprot=0` | Rotational displacement parameter [radians]
`dp` | Translational displacement parameter [Å] (optional)
`dprot` | Rotational displacement parameter [radians] (optional)
`eps=0` | Lennard-Jones/WCA energy parameter [kJ/mol]
`mu=[0,0,0]` | Dipole moment vector [eÅ]
`mulen=|mu|` | Dipole moment scalar [eÅ]
Expand Down
2 changes: 2 additions & 0 deletions docs/schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,8 @@ properties:
minItems: 3
maxItems: 3
default: [1,1,1]
dp: {type: number, minimum: 0.0, description: "default translational displacement", default: 0.0}
dprot: {type: number, minimum: 0.0, description: "default rotational displacement", default: 0.0}
required: [molecule]
additionalProperties: false
type: object
Expand Down
115 changes: 73 additions & 42 deletions src/actions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
#include "io.h"
#include "aux/arange.h"
#include <progress_tracker.h>
#include <ranges>
#include <range/v3/view/concat.hpp>

namespace Faunus {

AngularScan::AngularScan(const json& j, const Space& spc) {
AngularScan::AngularScan(const json& j, const Space& spc)
{
const auto angular_resolution = j.at("angular_resolution").get<double>();
angles = Geometry::TwobodyAnglesState(angular_resolution);
max_energy = j.value("max_energy", pc::infty) * 1.0_kJmol;
Expand All @@ -20,83 +22,98 @@ AngularScan::AngularScan(const json& j, const Space& spc) {

if (j.contains("traj")) {
trajectory = std::make_unique<XTCWriter>(j["traj"]);
if (angles.size() > 1e5) {
faunus_logger->warn("{}: large trajectory with {} frames will be generated", name, angles.size());
if (angles.size() > 10000) {
faunus_logger->warn("{}: large trajectory with {} frames will be generated", NAME,
angles.size());
}
}

stream = IO::openCompressedOutputStream(j.value("file", "poses.gz"s), true);
*stream << fmt::format("# Δ⍺ = {:.1f}° -> {} x {} x {} = {} poses 💃🏽🕺🏼\n", angular_resolution / 1.0_deg,
angles.quaternions_1.size(), angles.quaternions_2.size(), angles.dihedrals.size(),
angles.size())
<< fmt::format("# Mass center separation range along z: [{}, {}) with dz = {} Å\n", zmin, zmax, dz)
*stream << fmt::format("# Δ⍺ = {:.1f}° -> {} x {} x {} = {} poses 💃🏽🕺🏼\n",
angular_resolution / 1.0_deg, angles.quaternions_1.size(),
angles.quaternions_2.size(), angles.dihedrals.size(), angles.size())
<< fmt::format("# Mass center separation range along z: [{}, {}) with dz = {} Å\n",
zmin, zmax, dz)
<< fmt::format("# Max energy threshold: {} kJ/mol\n", max_energy / 1.0_kJmol)
<< "# Column 0-3: Quaternion for molecule 1 (x y z w)\n"
<< "# Column 4-7: Quaternion for molecule 2 (x y z w)\n"
<< "# Column 8: Mass center z displacement of molecule 2\n"
<< "# Column 9: Energy (kJ/mol)\n";

faunus_logger->info("{}: COM distance range = [{:.1f}, {:.1f}) max energy = {:.1f} kJ/mol", name, zmin, zmax,
max_energy / 1.0_kJmol);
faunus_logger->info("{}: COM distance range = [{:.1f}, {:.1f}) max energy = {:.1f} kJ/mol",
NAME, zmin, zmax, max_energy / 1.0_kJmol);
}

/**
* @brief Set molecular index; back up original positions, centered on the origin; save reference structure to disk
* @brief Set molecular index; back up original positions, centered on the origin; save reference
* structure to disk
*/
void AngularScan::Molecule::initialize(const Space::GroupVector& groups, int molecule_index) {
namespace rv = ranges::cpp20::views;
void AngularScan::Molecule::initialize(const Space::GroupVector& groups, int molecule_index)
{
namespace rv = std::views;
index = molecule_index;
const auto& group = groups.at(index);
if (group.isAtomic()) {
throw ConfigurationError("{}: group {} is not molecular", name, index);
throw ConfigurationError("{}: group {} is not molecular", NAME, index);
}
auto as_centered_position = [&](auto& particle) -> Point { return particle.pos - group.mass_center; };
auto as_centered_position = [&](auto& particle) -> Point {
return particle.pos - group.mass_center;
};
ref_positions = group | rv::transform(as_centered_position) | ranges::to_vector;
XYZWriter().save(fmt::format("molecule{}_reference.xyz", index), group.begin(), group.end(), Point::Zero());
XYZWriter().save(fmt::format("molecule{}_reference.xyz", index), group.begin(), group.end(),
Point::Zero());
}

ParticleVector AngularScan::Molecule::getRotatedReference(const Space::GroupVector& groups,
const Eigen::Quaterniond& q) {
namespace rv = ranges::cpp20::views;
const Eigen::Quaterniond& q)
{
namespace rv = std::views;
const auto& group = groups.at(index);
auto particles = ParticleVector(group.begin(), group.end()); // copy particles from Space
auto positions = ref_positions | rv::transform([&](const auto& pos) -> Point { return q * pos; });
std::copy(positions.begin(), positions.end(), (particles | rv::transform(&Particle::pos)).begin());
auto positions =
ref_positions | rv::transform([&](const auto& pos) -> Point { return q * pos; });
std::copy(positions.begin(), positions.end(),
(particles | rv::transform(&Particle::pos)).begin());
return particles;
}

void AngularScan::report(const Group& group1, const Group& group2, const Eigen::Quaterniond& q1,
const Eigen::Quaterniond& q2, Energy::NonbondedBase& nonbonded) {
const Eigen::Quaterniond& q2, Energy::NonbondedBase& nonbonded)
{
const auto energy = nonbonded.groupGroupEnergy(group1, group2);
if (energy >= max_energy) {
return;
}

auto format = [](const auto& q) { return fmt::format("{:8.4f}{:8.4f}{:8.4f}{:8.4f}", q.x(), q.y(), q.z(), q.w()); };
auto format = [](const auto& q) {
return fmt::format("{:8.4f}{:8.4f}{:8.4f}{:8.4f}", q.x(), q.y(), q.z(), q.w());
};

#pragma omp critical
{
energy_analysis.add(energy);
*stream << format(q1) << format(q2)
<< fmt::format("{:8.4f} {:>10.3E}\n", group2.mass_center.z(), energy / 1.0_kJmol);
if (trajectory) {
auto positions = ranges::views::concat(group1, group2) | ranges::cpp20::views::transform(&Particle::pos);
auto positions = ranges::views::concat(group1, group2) |
std::views::transform(&Particle::pos);
trajectory->writeNext({500, 500, 500}, positions.begin(), positions.end());
}
}
}

void AngularScan::operator()(Space& spc, Energy::Hamiltonian& hamiltonian) {
void AngularScan::operator()(Space& spc, Energy::Hamiltonian& hamiltonian)
{
auto nonbonded = hamiltonian.findFirstOf<Energy::NonbondedBase>();
if (!nonbonded) {
throw ConfigurationError("{}: at least one nonbonded energy term required", name);
throw ConfigurationError("{}: at least one nonbonded energy term required", NAME);
}

for (const auto z_pos : arange(zmin, zmax, dz)) {
faunus_logger->info("{}: separation = {}", name, z_pos);
faunus_logger->info("{}: separation = {}", NAME, z_pos);
auto translate = [=](auto& particle) { particle.pos.z() += z_pos; };
auto progress_tracker =
std::make_unique<ProgressIndicator::ProgressBar>(angles.quaternions_1.size() * angles.quaternions_2.size());
auto progress_tracker = std::make_unique<ProgressIndicator::ProgressBar>(
angles.quaternions_1.size() * angles.quaternions_2.size());
assert(progress_tracker);
energy_analysis.clear();

Expand All @@ -108,9 +125,10 @@ void AngularScan::operator()(Space& spc, Energy::Hamiltonian& hamiltonian) {

for (const auto& q_body2 : angles.quaternions_2) {
for (const auto& q_dihedral : angles.dihedrals) {
const auto q2 = q_dihedral * q_body2; // simulataneous rotations (noncummutative)
const auto q2 =
q_dihedral * q_body2; // simultaneous rotations (non-commutative)
auto particles2 = molecules.second.getRotatedReference(spc.groups, q2);
ranges::cpp20::for_each(particles2, translate);
std::ranges::for_each(particles2, translate);
auto group2 = Group(0, particles2.begin(), particles2.end());
group2.mass_center = {0.0, 0.0, z_pos};
report(group1, group2, q1, q2, *nonbonded);
Expand All @@ -125,18 +143,21 @@ void AngularScan::operator()(Space& spc, Energy::Hamiltonian& hamiltonian) {
} // separation loop
}

std::unique_ptr<SystemAction> createAction(std::string_view name, const json& j, Space& spc) {
std::unique_ptr<SystemAction> createAction(std::string_view name, const json& j, Space& spc)
{
try {
if (name == "angular_scan") {
return std::make_unique<AngularScan>(j, spc);
}
throw ConfigurationError("'{}' unknown", name);
} catch (std::exception& e) {
}
catch (std::exception& e) {
throw std::runtime_error("error creating action -> "s + e.what());
}
}

std::vector<std::unique_ptr<SystemAction>> createActionList(const json& input, Space& spc) {
std::vector<std::unique_ptr<SystemAction>> createActionList(const json& input, Space& spc)
{
if (!input.is_array()) {
throw ConfigurationError("json array expected");
}
Expand All @@ -147,33 +168,43 @@ std::vector<std::unique_ptr<SystemAction>> createActionList(const json& input, S
try {
const auto& [name, params] = jsonSingleItem(j);
actions.emplace_back(createAction(name, params, spc));
} catch (std::exception& e) {
}
catch (std::exception& e) {
throw ConfigurationError("actions: {}", e.what()).attachJson(j);
}
}
return actions;
}

void AngularScan::EnergyAnalysis::clear() {
void AngularScan::EnergyAnalysis::clear()
{
mean_exp_energy.clear();
partition_sum = 0;
energy_sum = 0;
partition_sum = 0.0;
energy_sum = 0.0;
}

void AngularScan::EnergyAnalysis::add(const double energy) {
void AngularScan::EnergyAnalysis::add(const double energy)
{
const auto exp_energy = std::exp(-energy);
mean_exp_energy += exp_energy;
partition_sum += exp_energy;
energy_sum += energy * exp_energy;
}

double AngularScan::EnergyAnalysis::getFreeEnergy() const { return -std::log(mean_exp_energy.avg()); }
double AngularScan::EnergyAnalysis::getFreeEnergy() const
{
return -std::log(mean_exp_energy.avg());
}

double AngularScan::EnergyAnalysis::getMeanEnergy() const { return energy_sum / partition_sum; }
double AngularScan::EnergyAnalysis::getMeanEnergy() const
{
return energy_sum / partition_sum;
}

void AngularScan::EnergyAnalysis::printLog() const {
faunus_logger->info("{}: free energy <w/kT> = {:.3f} mean energy <u/kT> = {:.3f}", name, getFreeEnergy(),
getMeanEnergy());
void AngularScan::EnergyAnalysis::printLog() const
{
faunus_logger->info("{}: free energy <w/kT> = {:.3f} mean energy <u/kT> = {:.3f}", NAME,
getFreeEnergy(), getMeanEnergy());
}

} // namespace Faunus
Loading

0 comments on commit 831f0fb

Please sign in to comment.