6 #include <range/v3/view/join.hpp> 7 #include <range/v3/view/filter.hpp> 8 #include <range/v3/range/conversion.hpp> 31 using index_type = std::size_t;
45 bool internal =
false;
48 std::vector<index_type>
67 [[maybe_unused]] [[nodiscard]] std::vector<index_type>
71 [[nodiscard]]
bool empty()
const;
72 explicit operator bool()
const;
74 const std::vector<Group>& group_vector)
const;
75 } __attribute__((aligned(32)));
97 using GroupVector = std::vector<GroupType>;
98 using GroupRefVector = std::vector<std::reference_wrapper<Group>>;
99 using ConstGroupRefVector = std::vector<std::reference_wrapper<const Group>>;
100 using ScaleVolumeTrigger = std::function<void(Space&, double, double)>;
101 using ChangeTrigger = std::function<void(Space&, const Change&)>;
102 using SyncTrigger = std::function<void(Space&, const Space&, const Change&)>;
113 std::map<MoleculeData::index_type, std::size_t> implicit_reservoir;
115 std::vector<ChangeTrigger> changeTriggers;
116 std::vector<SyncTrigger>
123 std::vector<ScaleVolumeTrigger>
126 [[nodiscard]]
const std::map<MoleculeData::index_type, std::size_t>&
127 getImplicitReservoir()
const;
128 std::map<MoleculeData::index_type, std::size_t>& getImplicitReservoir();
142 GroupType& addGroup(MoleculeData::index_type molid,
144 GroupVector::iterator findGroupContaining(
146 bool include_inactive =
false);
147 GroupVector::iterator
148 findGroupContaining(AtomData::index_type atom_index);
150 numParticles(Selection selection = Selection::ACTIVE)
const;
153 scaleVolume(
double new_volume,
155 Geometry::VolumeMethod::ISOTROPIC);
157 GroupVector::iterator
158 randomMolecule(MoleculeData::index_type molid,
Random& rand,
159 Selection selection = Selection::ACTIVE);
163 [[nodiscard]] std::size_t
164 getGroupIndex(
const GroupType& group)
const;
165 [[nodiscard]] std::size_t
166 getFirstParticleIndex(
const GroupType& group)
const;
167 [[nodiscard]] std::size_t getFirstActiveParticleIndex(
193 template <std::forward_iterator iterator,
194 class copy_operation = std::function<void(const Particle&, Particle&)>>
196 const iterator begin,
const iterator end, ParticleVector::iterator destination,
197 copy_operation copy_function = [](
const Particle& src,
Particle& dst) { dst = src; })
200 const auto size = std::distance(begin, end);
202 assert(destination >= particles.begin() && destination < particles.end());
203 assert(size <= std::distance(destination, particles.end()));
205 auto affected_groups =
206 groups | std::views::filter([=](
auto& group) {
207 return (group.begin() < destination + size) && (group.end() > destination);
211 std::for_each(begin, end,
212 [&](
const auto& source) { copy_function(source, *destination++); });
214 std::ranges::for_each(affected_groups, [&](
Group& group) {
231 void updateInternalState(
const Change& change);
236 return std::views::transform(particles,
237 [](
auto& particle) ->
const Point& {
return particle.pos; });
243 static std::function<bool(const GroupType&)>
getGroupFilter(MoleculeData::index_type molid,
244 const Selection& selection)
246 auto is_active = [](
const GroupType& group) {
return group.size() == group.capacity(); };
248 auto is_neutral = [](RequireParticleIterator
auto begin, RequireParticleIterator
auto end) {
249 auto charge = std::accumulate(
250 begin, end, 0.0, [](
auto sum,
auto& particle) {
return sum + particle.charge; });
251 return (fabs(charge) < 1e-6);
254 std::function<bool(const GroupType&)> f;
257 case (Selection::ALL):
258 f = []([[maybe_unused]]
auto& group) {
return true; };
260 case (Selection::INACTIVE):
261 f = [=](
auto& group) {
return !is_active(group); };
263 case (Selection::ACTIVE):
264 f = [=](
auto& group) {
return is_active(group); };
266 case (Selection::ALL_NEUTRAL):
267 f = [=](
auto& group) {
return is_neutral(group.begin(), group.trueend()); };
269 case (Selection::INACTIVE_NEUTRAL):
270 f = [=](
auto& group) {
271 return !is_active(group) && is_neutral(group.begin(), group.trueend());
274 case (Selection::ACTIVE_NEUTRAL):
275 f = [=](
auto& group) {
276 return is_active(group) && is_neutral(group.begin(), group.end());
280 return [f, molid](
auto& group) {
return group.id == molid && f(group); };
289 auto findMolecules(MoleculeData::index_type molid, Selection selection = Selection::ACTIVE)
292 return groups | ranges::cpp20::views::filter(group_filter);
295 [[nodiscard]]
auto findMolecules(MoleculeData::index_type molid,
296 Selection selection = Selection::ACTIVE)
const 299 return groups | ranges::cpp20::views::filter(group_filter);
304 return groups | ranges::cpp20::views::join;
309 return groups | ranges::cpp20::views::join;
317 template <std::
integral index_type =
int>
320 auto to_index = [&](
auto& particle) {
321 const auto index = std::addressof(particle) - std::addressof(particles.at(0));
322 if (index < 0 || index >= particles.size()) {
323 throw std::out_of_range(
"particle range outside Space");
325 return static_cast<index_type
>(index);
327 return particle_range | std::views::transform(to_index) | ranges::to_vector;
337 return activeParticles() | std::views::filter([atomid](
const Particle& particle) {
338 return particle.
id == atomid;
347 [[nodiscard]]
auto findAtoms(AtomData::index_type atomid)
const 349 return activeParticles() | std::views::filter([atomid](
const Particle& particle) {
350 return particle.
id == atomid;
354 [[nodiscard]]
size_t countAtoms(AtomData::index_type atomid)
const;
362 template <
unsigned int mask>
auto numMolecules(MoleculeData::index_type molid)
const 364 auto filter = [&](
const GroupType& group) {
365 return (group.id == molid) ? group.template match<mask>() :
false;
367 return std::count_if(groups.begin(), groups.end(), filter);
370 void sync(
const Space& other,
376 void from_json(
const json& j,
Space& spc);
393 static void insertAtomicGroups(
MoleculeData& moldata,
Space& spc,
size_t num_molecules,
394 size_t num_inactive_molecules);
396 static void insertMolecularGroups(
MoleculeData& moldata,
Space& spc,
size_t num_molecules,
397 size_t num_inactive);
399 static void setPositionsForTrailingGroups(
Space& spc,
size_t num_molecules,
402 static void insertImplicitGroups(
const MoleculeData& moldata,
Space& spc,
size_t num_molecules);
405 static size_t getNumberOfMolecules(
const json& j,
double volume,
406 const std::string& molecule_name);
409 static size_t getNumberOfInactiveMolecules(
const json& j,
size_t number_of_molecules);
412 static ParticleVector getExternalPositions(
const json& j,
const std::string& molname);
415 static void insertItem(
const std::string& molname,
const json& properties,
Space& spc);
417 static void reserveMemory(
const json& j,
Space& spc);
420 static void insertMolecules(
const json& j,
Space& spc);
423 namespace SpaceFactory {
425 void makeNaCl(
Space& space,
size_t num_particles,
427 void makeWater(
Space& space,
size_t num_particles,
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
void updateMassCenter(Geometry::BoundaryFunction boundary, const Point &approximate_mass_center)
Calculates mass center.
Definition: group.cpp:135
auto toIndices(const RequireParticles auto &particle_range) const
Get vector of indices of given range of particles.
Definition: space.h:318
BoundaryFunction getBoundaryFunc() const
Lambda for applying boundary conditions on a point.
Definition: geometry.h:121
auto positions()
Mutable iterable range of all particle positions.
Definition: space.h:241
Point pos
Particle position vector.
Definition: particle.h:227
Random number generator.
Definition: random.h:34
Insert molecules into space.
Definition: space.h:390
Geometry class for spheres, cylinders, cuboids, hexagonal prism, truncated octahedron, slits.
Definition: geometry.h:342
bool moved_to_moved_interactions
If several groups are moved, should they interact with each other?
Definition: space.h:35
auto numMolecules(MoleculeData::index_type molid) const
Count number of molecules matching criteria.
Definition: space.h:362
void sanityCheck(const std::vector< Group > &group_vector) const
Sanity check on contained object data.
Definition: space.cpp:64
std::vector< GroupChange > groups
Touched groups by index in group vector.
Definition: space.h:56
void sort()
Sort group indices.
Definition: space.cpp:17
auto touchedGroupIndex() const
List of moved groups (index)
Definition: space.h:61
concept RequireParticles
Concept for a range of particles.
Definition: particle.h:257
static std::function< bool(const GroupType &)> getGroupFilter(MoleculeData::index_type molid, const Selection &selection)
Definition: space.h:243
auto findAtoms(AtomData::index_type atomid) const
Find active atoms of type atomid (complexity: order N)
Definition: space.h:347
bool everything
Everything has changed (particles, groups, volume)
Definition: space.h:32
std::vector< index_type > relative_atom_indices
A subset of particles changed (sorted; empty if all=true)
Definition: space.h:49
bool dNswap
The number of atoms has changed as a result of a swap move.
Definition: space.h:44
bool all
All particles in the group have changed (leave relative_atom_indices empty)
Definition: space.h:46
auto positions() const
Iterable range of all particle positions.
Definition: space.h:234
void updateParticles(const iterator begin, const iterator end, ParticleVector::iterator destination, copy_operation copy_function=[](const Particle &src, Particle &dst) { dst=src;})
Update particles in Space from a source range.
Definition: space.h:195
std::vector< Particle > ParticleVector
Storage type for collections of particles.
Definition: particle.h:253
int id
Particle id/type.
Definition: particle.h:225
General properties for molecules.
Definition: molecule.h:211
auto activeParticles()
Range with all active particles.
Definition: space.h:302
void clear()
Clear all change data.
Definition: space.cpp:22
GeometryType geometry
Container geometry (boundaries, shape, volume)
Definition: space.h:122
Properties of changed groups.
Definition: space.h:40
Particle class for storing positions, id, and other properties.
Definition: particle.h:220
auto activeParticles() const
Range with all active particles.
Definition: space.h:307
index_type group_index
Touched group index.
Definition: space.h:42
bool operator<(const GroupChange &other) const
Comparison operator based on group_index
Definition: space.cpp:12
Cell list class templates.
Definition: actions.cpp:11
bool volume_change
The volume has changed.
Definition: space.h:33
auto findMolecules(MoleculeData::index_type molid, Selection selection=Selection::ACTIVE)
Finds all groups of type molid (complexity: order N)
Definition: space.h:289
End of Group class.
Definition: group.h:177
std::optional< std::pair< index_type, index_type > > singleParticleChange() const
Determines if the change reflects a single particle change.
Definition: space.cpp:90
bool empty() const
Check if change object is empty.
Definition: space.cpp:28
ParticleVector particles
All particles are stored here!
Definition: space.h:120
Specify changes made to a system.
Definition: space.h:29
bool disable_translational_entropy
Force exclusion of translational entropy.
Definition: space.h:37
bool matter_change
The number of atomic or molecular species has changed.
Definition: space.h:34
Placeholder for atoms and molecules.
Definition: space.h:92
std::vector< index_type > touchedParticleIndex(const std::vector< Group > &) const
List of changed atom index relative to first particle in system.
Definition: space.cpp:39
auto findAtoms(AtomData::index_type atomid)
Find active atoms of type atomid (complexity: order N)
Definition: space.h:335
GroupVector groups
All groups are stored here (i.e. molecules)
Definition: space.h:121
std::vector< ScaleVolumeTrigger > scaleVolumeTriggers
Functions triggered whenever the volume is scaled.
Definition: space.h:124
std::function< bool(const Group &)> getGroupFilter()
Get lambda function matching given enum Select mask.
Definition: group.h:380
bool dNatomic
The number of atomic molecules has changed.
Definition: space.h:43
VolumeMethod
Various methods of volume scaling,.
Definition: geometry.h:52