faunus
potentials_base.h
1 #pragma once
2 #include "core.h"
3 #include "particle.h"
4 #include "aux/pairmatrix.h"
5 #include <array>
6 
8 namespace Faunus::pairpotential {
9 
11 using TPairMatrix = Eigen::MatrixXd;
12 using TPairMatrixPtr = std::shared_ptr<TPairMatrix>;
13 
16 using TExtractorFunc = std::function<double(const InteractionData&)>;
17 
19 using TCombinatorFunc = std::function<double(double, double)>;
20 
22 using TModifierFunc = std::function<double(double)>;
23 
30 {
31  std::array<AtomData::index_type, 2> atom_id;
32  InteractionData interaction;
33 };
34 
35 void from_json(const json& j, CustomInteractionData& interaction);
36 void to_json(json& j, const CustomInteractionData& interaction);
37 void from_json(const json& j, std::vector<CustomInteractionData>& interactions);
38 
46 {
47  UNDEFINED,
48  ARITHMETIC,
49  GEOMETRIC,
50  LORENTZ_BERTHELOT
51 };
53  {{CombinationRuleType::UNDEFINED, "undefined"},
54  {CombinationRuleType::ARITHMETIC, "arithmetic"},
55  {CombinationRuleType::GEOMETRIC, "geometric"},
56  {CombinationRuleType::LORENTZ_BERTHELOT, "lorentz_berthelot"},
57  {CombinationRuleType::LORENTZ_BERTHELOT, "LB"}})
58 
62 struct PairPotentialException : public std::runtime_error
63 {
64  explicit PairPotentialException(const std::string& msg);
65 };
66 
76 class PairMixer
77 {
79  extractor;
80  TCombinatorFunc combinator;
82  modifier;
83 
84  public:
85  PairMixer(TExtractorFunc extractor, TCombinatorFunc combinator,
86  TModifierFunc modifier = &modIdentity);
87 
89  TPairMatrixPtr createPairMatrix(const std::vector<AtomData>& atoms);
91  TPairMatrixPtr createPairMatrix(const std::vector<AtomData>& atoms,
92  const std::vector<CustomInteractionData>& interactions);
93 
94  enum class CoefficientType
95  {
96  ANY,
97  SIGMA,
98  EPSILON
99  };
100  static TCombinatorFunc getCombinator(CombinationRuleType combination_rule,
101  CoefficientType coefficient = CoefficientType::ANY);
102 
103  // when explicit custom pairs are the only option
104  inline static constexpr double combUndefined(double = 0.0, double = 0.0)
105  {
106  return std::numeric_limits<double>::signaling_NaN();
107  };
108 
109  inline static double combArithmetic(double a, double b) { return 0.5 * (a + b); }
110 
111  inline static double combGeometric(double a, double b) { return std::sqrt(a * b); }
112 
113  inline static double modIdentity(double x) { return x; }
114 
115  inline static double modSquared(double x) { return x * x; }
116 };
117 
132 {
133  private:
134  friend void from_json(const json&, PairPotential&);
135 
136  public:
137  std::string
139  std::string cite;
140  bool isotropic = true;
141  std::function<double(const Particle&)> selfEnergy = nullptr;
142  virtual void to_json(json&) const = 0;
143  virtual void from_json(const json&) = 0;
144  virtual ~PairPotential() = default;
145 
154  [[nodiscard]] virtual Point force(const Particle& a, const Particle& b, double squared_distance,
155  const Point& b_towards_a) const;
156 
165  virtual double operator()(const Particle& particle_a, const Particle& particle_b,
166  double squared_distance, const Point& b_towards_a) const = 0;
167 
168  protected:
169  explicit PairPotential(std::string name = std::string(), std::string cite = std::string(),
170  bool isotropic = true);
171 };
172 
173 void to_json(json& j, const PairPotential& base);
174 void from_json(const json& j, PairPotential& base);
175 
179 template <class T>
180 concept RequirePairPotential = std::derived_from<T, pairpotential::PairPotential>;
181 
183 template <RequirePairPotential T> auto makePairPotential(const json& j)
184 {
185  T pair_potential;
186  pairpotential::from_json(j, pair_potential);
187  return pair_potential;
188 }
189 
199 {
200  protected:
201  CombinationRuleType combination_rule;
202  std::shared_ptr<std::vector<CustomInteractionData>> custom_pairs =
203  std::make_shared<std::vector<CustomInteractionData>>();
205  void init();
206  virtual void
207  initPairMatrices() = 0;
208  virtual void extractorsFromJson(
209  const json&);
210  public:
211  explicit MixerPairPotentialBase(
212  const std::string& name = std::string(), const std::string& cite = std::string(),
213  CombinationRuleType combination_rule = CombinationRuleType::UNDEFINED,
214  bool isotropic = true);
215  ~MixerPairPotentialBase() override = default;
216  void from_json(const json& j) override;
217  void to_json(json& j) const override;
218 };
219 
226 template <RequirePairPotential T1, RequirePairPotential T2>
228 {
229  T1 first;
230  T2 second;
231  explicit CombinedPairPotential(const std::string& name = "")
232  : PairPotential(name) {};
233 
234  inline double operator()(const Particle& particle_a, const Particle& particle_b,
235  const double squared_distance,
236  const Point& b_towards_a = {0, 0, 0}) const override
237  {
238  return first(particle_a, particle_b, squared_distance, b_towards_a) +
239  second(particle_a, particle_b, squared_distance, b_towards_a);
240  }
241 
250  [[nodiscard]] inline Point force(const Particle& particle_a, const Particle& particle_b,
251  const double squared_distance,
252  const Point& b_towards_a) const override
253  {
254  return first.force(particle_a, particle_b, squared_distance, b_towards_a) +
255  second.force(particle_a, particle_b, squared_distance, b_towards_a);
256  }
257 
258  void from_json(const json& j) override
259  {
262  name = first.name + "/" + second.name;
263  if (first.selfEnergy or second.selfEnergy) { // combine self-energies
264  selfEnergy = [u1 = first.selfEnergy, u2 = second.selfEnergy](const Particle& p) {
265  if (u1 and u2) {
266  return u1(p) + u2(p);
267  }
268  if (u1) {
269  return u1(p);
270  }
271  return u2(p);
272  };
273  }
274  else {
275  selfEnergy = nullptr;
276  }
277  }
278 
279  void to_json(json& j) const override
280  {
281  assert(j.is_object());
282  auto& _j = j["default"] = json::array();
283  _j.push_back(first);
284  _j.push_back(second);
285  }
286 };
287 
288 } // namespace Faunus::pairpotential
T1 first
First pair potential of type T1.
Definition: potentials_base.h:229
nlohmann::json json
JSON object.
Definition: json_support.h:10
Eigen::Vector3d Point
3D vector used for positions, velocities, forces etc.
Definition: coordinates.h:7
Exception for handling pair potential initialization.
Definition: potentials_base.h:76
CombinationRuleType
Known named combination rules for parameters of pair potential interaction.
Definition: potentials_base.h:45
Statically combines two pair potentials at compile-time.
Definition: potentials_base.h:227
double T
floating point size
Definition: units.h:73
Eigen::MatrixXd TPairMatrix
type of a matrix containing pair potential coefficients
Definition: potentials_base.h:11
std::function< double(double)> TModifierFunc
type of a function modifying combinator&#39;s output
Definition: potentials_base.h:22
Data for a custom (heterogeneous) interaction between two given atom types.
Definition: potentials_base.h:29
std::function< double(const InteractionData &)> TExtractorFunc
type of a function extracting a potential coefficient from the InteractionData, e.g., sigma or eps
Definition: potentials_base.h:16
std::vector< Faunus::AtomData > atoms
Global instance of atom list.
Definition: atomdata.cpp:242
std::function< double(double, double)> TCombinatorFunc
type of a function defining a combination rule of a heterogeneous pair interaction ...
Definition: potentials_base.h:19
A common ancestor for potentials that use parameter matrices computed from atomic properties and/or c...
Definition: potentials_base.h:198
std::string name
unique name per polymorphic call; used in FunctorPotential::combinePairPotentials ...
Definition: potentials_base.h:138
Particle class for storing positions, id, and other properties.
Definition: particle.h:220
json json_extra_params
pickled extra parameters like a coefficient names mapping
Definition: potentials_base.h:204
concept RequirePairPotential
Concept matching a particle pair potential derived from Potential::PairPotentialBase ...
Definition: potentials_base.h:180
Namespace for particle pair-potentials.
Definition: analysis.h:18
double operator()(const Particle &particle_a, const Particle &particle_b, const double squared_distance, const Point &b_towards_a={0, 0, 0}) const override
Combine pair energy.
Definition: potentials_base.h:234
NLOHMANN_JSON_SERIALIZE_ENUM(SpheroCylinderData::PatchType, {{SpheroCylinderData::PatchType::Invalid, nullptr}, {SpheroCylinderData::PatchType::Full, "full"}, {SpheroCylinderData::PatchType::Capped, "capped"}, {SpheroCylinderData::PatchType::None, "none"}}) class AtomData
General properties for atoms.
Definition: atomdata.h:61
void from_json(const json &j, PairPotential &base)
Serialize any pair potential from json.
Definition: potentials.cpp:258
auto makePairPotential(const json &j)
Convenience function to generate a pair potential initialized from JSON object.
Definition: potentials_base.h:183
Point force(const Particle &particle_a, const Particle &particle_b, const double squared_distance, const Point &b_towards_a) const override
Calculates force on particle a due to another particle, b.
Definition: potentials_base.h:250
Base for all pair-potentials.
Definition: potentials_base.h:131
std::string cite
Typically a short-doi litterature reference.
Definition: potentials_base.h:139
T2 second
Second pair potential of type T2.
Definition: potentials_base.h:230
A stub to hold various parameters of interactions.
Definition: atomdata.h:16