Loading [MathJax]/extensions/TeX/AMSmath.js
ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages Concepts
ObservableStat.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2013-2022 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "config/config.hpp"
21
22#include "ObservableStat.hpp"
23
26
28
29#include <cstddef>
30#include <span>
31#include <string>
32#include <vector>
33
34namespace ScriptInterface {
35namespace Analysis {
36
37/**
38 * @brief Generate an observable summary.
39 * @param[in] system The system to analyze.
40 * @param[in] obs The observable handle.
41 * @param[in] calc_sp Whether to compute a scalar pressure.
42 */
44 Observable_stat const &obs, bool const calc_sp) {
45 auto const obs_dim = obs.get_chunk_size();
46
47 auto const get_obs_contribs = [obs_dim,
48 calc_sp](std::span<double> const &views) {
49 if (obs_dim == 1ul) {
50 return std::vector<Variant>(views.begin(), views.end());
51 }
52 assert(obs_dim == 9ul);
53 assert(views.size() % 9ul == 0ul);
54 std::vector<Variant> out;
55 for (std::size_t i = 0ul; i < views.size() / 9ul; ++i) {
56 auto const view = views.subspan(i * 9ul, 9ul);
57 if (calc_sp) {
58 auto const trace = view[0ul] + view[4ul] + view[8ul];
59 out.emplace_back(trace / 3.);
60 } else {
61 auto const flat_matrix = std::vector<double>(view.begin(), view.end());
62 out.emplace_back(flat_matrix);
63 }
64 }
65 return out;
66 };
67
68 auto const get_obs_contrib =
69 [&get_obs_contribs](std::span<double> const &views) -> Variant {
70 return get_obs_contribs(views)[0ul];
71 };
72
73 std::unordered_map<std::string, Variant> dict;
74 dict["kinetic_lin"] = get_obs_contrib(obs.kinetic_lin);
75 dict["kinetic_rot"] = get_obs_contrib(obs.kinetic_rot);
76 dict["external_fields"] = get_obs_contrib(obs.external_fields);
77 if (is_type<double>(dict["kinetic_lin"])) {
78 dict["kinetic"] = get_value<double>(dict["kinetic_lin"]) +
79 get_value<double>(dict["kinetic_rot"]);
80 } else {
81 auto const v1 = get_value<std::vector<double>>(dict["kinetic_lin"]);
82 auto const v2 = get_value<std::vector<double>>(dict["kinetic_rot"]);
83 std::vector<double> value{};
84 for (auto i = 0u; i < 9u; ++i) {
85 value.emplace_back(v1[i] + v2[i]);
86 }
87 dict["kinetic"] = value;
88 }
89
90 {
91 auto values = std::vector<double>(obs_dim);
92 for (std::size_t i = 0ul; i < obs_dim; ++i) {
93 values[i] = obs.accumulate(0., i);
94 }
95 dict["total"] = get_obs_contrib({values.data(), obs_dim});
96 }
97
98 auto const n_bonds = static_cast<int>(system.bonded_ias->get_next_key());
99 for (int bond_id = 0; bond_id < n_bonds; ++bond_id) {
100 if (system.bonded_ias->get_zero_based_type(bond_id) != 0) {
101 dict["bonded," + std::to_string(bond_id)] =
102 get_obs_contrib(obs.bonded_contribution(bond_id));
103 }
104 }
105
106 auto const n_nonbonded =
107 system.nonbonded_ias->get_max_seen_particle_type() + 1;
108 for (int i = 0; i < n_nonbonded; ++i) {
109 for (int j = i; j < n_nonbonded; ++j) {
110 auto const indices = std::to_string(i) + "," + std::to_string(j);
111 dict["non_bonded_intra," + indices] =
112 get_obs_contrib(obs.non_bonded_intra_contribution(i, j));
113 dict["non_bonded_inter," + indices] =
114 get_obs_contrib(obs.non_bonded_inter_contribution(i, j));
115 }
116 }
117
118#ifdef ELECTROSTATICS
119 {
120 auto const values = get_obs_contribs(obs.coulomb);
121 for (std::size_t i = 0ul; i < values.size(); ++i) {
122 dict["coulomb," + std::to_string(i)] = values[i];
123 }
124 }
125#endif // ELECTROSTATICS
126
127#ifdef DIPOLES
128 {
129 auto const values = get_obs_contribs(obs.dipolar);
130 for (std::size_t i = 0ul; i < values.size(); ++i) {
131 dict["dipolar," + std::to_string(i)] = values[i];
132 }
133 }
134#endif // DIPOLES
135
136#ifdef VIRTUAL_SITES
137 {
138 auto const values = get_obs_contribs(obs.virtual_sites);
139 for (std::size_t i = 0ul; i < values.size(); ++i) {
140 dict["virtual_sites," + std::to_string(i)] = values[i];
141 }
142 }
143#endif // VIRTUAL_SITES
144
145#ifdef DPD
146 {
147 auto const values = get_obs_contribs(obs.dpd);
148 for (std::size_t i = 0ul; i < values.size(); ++i) {
149 dict["dpd," + std::to_string(i)] = values[i];
150 }
151 }
152#endif // DPD
153
154 return dict;
155}
156
158 VariantMap const &parameters) {
159 auto &system = get_system();
160 if (name == "calculate_energy") {
161 auto const obs = system.calculate_energy();
162 return get_summary(system, *obs, false);
163 }
164 if (name == "calculate_scalar_pressure") {
165 auto const obs = system.calculate_pressure();
166 return get_summary(system, *obs, true);
167 }
168 if (name == "calculate_pressure_tensor") {
169 auto const obs = system.calculate_pressure();
170 return get_summary(system, *obs, false);
171 }
172 return {};
173}
174
175} // namespace Analysis
176} // namespace ScriptInterface
Data structures for bonded interactions.
Observable for the pressure and energy.
Variant do_call_method(std::string const &name, VariantMap const &parameters) override
boost::string_ref name() const
Main system class.
This file contains the defaults for ESPResSo.
static auto get_summary(::System::System const &system, Observable_stat const &obs, bool const calc_sp)
Generate an observable summary.
T get_value(Variant const &v)
Extract value of specific type T from a Variant.
std::unordered_map< std::string, Variant > VariantMap
Definition Variant.hpp:69
boost::make_recursive_variant< None, bool, int, std::size_t, double, std::string, ObjectRef, Utils::Vector3b, Utils::Vector3i, Utils::Vector2d, Utils::Vector3d, Utils::Vector4d, std::vector< int >, std::vector< double >, std::vector< boost::recursive_variant_ >, std::unordered_map< int, boost::recursive_variant_ >, std::unordered_map< std::string, boost::recursive_variant_ > >::type Variant
Possible types for parameters.
Definition Variant.hpp:67
Various procedures concerning interactions between particles.