suanPan
🧮 An Open Source, Parallel and Heterogeneous Finite Element Analysis Framework
Loading...
Searching...
No Matches
MolecularDynamics.h
Go to the documentation of this file.
1/*******************************************************************************
2 * Copyright (C) 2017-2026 Theodore Chang
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 ******************************************************************************/
29#ifndef MOLECULARDYNAMICS_H
30#define MOLECULARDYNAMICS_H
31
32#include "Constraint.h"
33
35#include <Domain/Factory.hpp>
36#include <Element/Element.h>
37
38template<unsigned DIM, bool ROTATION> class MolecularDynamics : public Constraint {
39 uvec interaction_tags;
40 std::vector<shared_ptr<Interaction>> interactions;
41
42protected:
43 std::vector<shared_ptr<Element>> elements;
44 double space = 0.;
45
46 void apply_interaction(const bool full, const shared_ptr<Element>& element) const {
47 for(auto&& interaction : interactions) interaction->apply(full, element);
48 }
49
50 void apply_interaction(const bool full, const shared_ptr<InteractionPair>& pair) const {
51 pair->set_dimension(DIM);
52 pair->set_inertial(ROTATION);
53 for(auto&& interaction : interactions) interaction->apply(full, pair);
54 }
55
56 [[nodiscard]] virtual int process_impl(const shared_ptr<DomainBase>&, bool) = 0;
57
58 int process_entrypoint(const shared_ptr<DomainBase>& D, const bool full) {
59 suanpan::for_all(D->get_element_pool(), [&](const shared_ptr<Element>& element) { apply_interaction(full, element); });
60 return process_impl(D, full);
61 }
62
63public:
64 MolecularDynamics(const unsigned T, uvec&& IT)
65 : Constraint(T, 0, ROTATION ? suanpan::mechanical(DIM) : suanpan::translational(DIM), {}, 0)
66 , interaction_tags(std::move(IT)) {}
67
68 int initialize(const shared_ptr<DomainBase>& D) override {
69 if(const auto t_scheme = D->get_factory()->get_storage_scheme(); StorageScheme::FULL != t_scheme && StorageScheme::SPARSE != t_scheme && StorageScheme::SPARSESYMM != t_scheme) {
70 suanpan_warning("The full or sparse matrix storage scheme is required.\n");
71 return SUANPAN_FAIL;
72 }
73
74 interactions.clear();
75 for(auto&& item : D->get<Interaction>(interaction_tags))
76 if(item && item->is_active()) interactions.emplace_back(item);
77
78 elements.clear();
79 for(auto&& item : D->get_element_pool())
80 if(item && item->is_active() && item->type() == Element::Type::DEM) elements.emplace_back(item);
81
82 space = 2. * std::transform_reduce(elements.cbegin(), elements.cend(), 0., [](const double a, const double b) { return std::max(a, b); }, [](const std::shared_ptr<Element>& element) { return element->get(Element::Parameter::RADIUS); });
83
85
86 if(!validate_node(D)) return SUANPAN_FAIL;
87
88 return SUANPAN_SUCCESS;
89 }
90
91 int process(const shared_ptr<DomainBase>& D) override { return process_entrypoint(D, true); }
92
93 int process_resistance(const shared_ptr<DomainBase>& D) override { return process_entrypoint(D, false); }
94};
95
96class MolecularDynamics2D final : public MolecularDynamics<2u, false> {
97 struct CellList {
98 int x = 0, y = 0;
99 unsigned tag = 0;
100
101 CellList(const int in_x, const int in_y, const unsigned in_tag)
102 : x(in_x)
103 , y(in_y)
104 , tag(in_tag) {}
105 };
106
107 int process_impl(const shared_ptr<DomainBase>& D, const bool full) override {
108 auto& W = D->get_factory();
109
111 list.reserve(elements.size());
112
113 suanpan::for_all(elements, [&](const shared_ptr<Element>& element) {
114 if(norm(element->get_trial_velocity().head(2)) * W->get_incre_time() > space) suanpan_warning("The nodal speed seems to be too large.\n");
115 const vec new_pos = element->get_coordinate(2).t() + element->get_trial_displacement().head(2);
116 list.emplace_back(static_cast<int>(floor(new_pos(0) / space)), static_cast<int>(floor(new_pos(1) / space)), element->get_tag());
117 });
118
119 suanpan_sort(list.begin(), list.end(), [](const CellList& a, const CellList& b) { return a.x < b.x || a.x == b.x && a.y < b.y; });
120
121 suanpan::for_each(list.size(), [&](const size_t I) {
122 for(auto J = I + 1; J < list.size(); ++J) {
123 const auto diff_x = list[J].x - list[I].x;
124 if(diff_x > 1) break;
125 const auto diff_y = list[J].y - list[I].y;
126 if(diff_x == 1 && diff_y > 1) break;
127 if(std::abs(diff_y) > 1) continue;
128 apply_interaction(full, std::make_unique<InteractionPair>(D->get<Element>(list[I].tag), D->get<Element>(list[J].tag)));
129 }
130 });
131
132 return SUANPAN_SUCCESS;
133 }
134
135public:
137};
138
139class MolecularDynamics3D final : public MolecularDynamics<3u, false> {
140 struct CellList {
141 int x = 0, y = 0, z = 0;
142 unsigned tag = 0;
143
144 CellList(const int in_x, const int in_y, const int in_z, const unsigned in_tag)
145 : x(in_x)
146 , y(in_y)
147 , z(in_z)
148 , tag(in_tag) {}
149 };
150
151 int process_impl(const shared_ptr<DomainBase>& D, const bool full) override {
152 auto& W = D->get_factory();
153
155 list.reserve(elements.size());
156
157 suanpan::for_all(elements, [&](const shared_ptr<Element>& element) {
158 if(norm(element->get_trial_velocity().head(3)) * W->get_incre_time() > space) suanpan_warning("The nodal speed seems to be too large.\n");
159 const vec new_pos = element->get_coordinate(3).t() + element->get_trial_displacement().head(3);
160 list.emplace_back(static_cast<int>(floor(new_pos(0) / space)), static_cast<int>(floor(new_pos(1) / space)), static_cast<int>(floor(new_pos(2) / space)), element->get_tag());
161 });
162
163 suanpan_sort(list.begin(), list.end(), [](const CellList& a, const CellList& b) { return a.x < b.x || a.x == b.x && a.y < b.y || a.x == b.x && a.y == b.y && a.z < b.z; });
164
165 suanpan::for_each(list.size(), [&](const size_t I) {
166 for(auto J = I + 1; J < list.size(); ++J) {
167 const auto diff_x = list[J].x - list[I].x;
168 if(diff_x > 1) break;
169 const auto diff_y = list[J].y - list[I].y;
170 const auto diff_z = list[J].z - list[I].z;
171 if(diff_x == 1 && (diff_y > 1 || diff_z > 1)) break;
172 if(std::abs(diff_y) > 1 || std::abs(diff_z) > 1) continue;
173 apply_interaction(full, std::make_unique<InteractionPair>(D->get<Element>(list[I].tag), D->get<Element>(list[J].tag)));
174 }
175 });
176
177 return SUANPAN_SUCCESS;
178 }
179
180public:
182};
183
184#endif
185
virtual int initialize(const shared_ptr< DomainBase > &)
Definition ConditionalModifier.cpp:85
bool validate_node(const shared_ptr< DomainBase > &) const
Definition ConditionalModifier.cpp:25
A Constraint class.
Definition Constraint.h:36
Definition Interaction.h:65
Definition MolecularDynamics.h:96
Definition MolecularDynamics.h:139
A MolecularDynamics class.
Definition MolecularDynamics.h:38
int initialize(const shared_ptr< DomainBase > &D) override
Definition MolecularDynamics.h:68
double space
Definition MolecularDynamics.h:44
int process_resistance(const shared_ptr< DomainBase > &D) override
Process and update resistance.
Definition MolecularDynamics.h:93
int process_entrypoint(const shared_ptr< DomainBase > &D, const bool full)
Definition MolecularDynamics.h:58
void apply_interaction(const bool full, const shared_ptr< Element > &element) const
Definition MolecularDynamics.h:46
std::vector< shared_ptr< Element > > elements
Definition MolecularDynamics.h:43
int process(const shared_ptr< DomainBase > &D) override
Process and update both stiffness and resistance.
Definition MolecularDynamics.h:91
virtual int process_impl(const shared_ptr< DomainBase > &, bool)=0
MolecularDynamics(const unsigned T, uvec &&IT)
Definition MolecularDynamics.h:64
void apply_interaction(const bool full, const shared_ptr< InteractionPair > &pair) const
Definition MolecularDynamics.h:50
Definition SparseMatMAGMA.hpp:43
std::vector< T > vector
Definition container.h:53
void for_all(Container &target, Handler &&func)
Definition suanPan.h:363
void for_each(const IT start, const IT end, F &&FN)
Definition utility.h:31
constexpr auto SUANPAN_SUCCESS
Definition suanPan.h:166
#define suanpan_warning(...)
Definition suanPan.h:348
#define suanpan_sort
Definition suanPan.h:180
constexpr auto SUANPAN_FAIL
Definition suanPan.h:167