1 /* ----------------------------------------------------------------------
2 This is the
3
4 ██╗ ██╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗████████╗███████╗
5 ██║ ██║██╔════╝ ██╔════╝ ██╔════╝ ██║ ██║╚══██╔══╝██╔════╝
6 ██║ ██║██║ ███╗██║ ███╗██║ ███╗███████║ ██║ ███████╗
7 ██║ ██║██║ ██║██║ ██║██║ ██║██╔══██║ ██║ ╚════██║
8 ███████╗██║╚██████╔╝╚██████╔╝╚██████╔╝██║ ██║ ██║ ███████║
9 ╚══════╝╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝®
10
11 DEM simulation engine, released by
12 DCS Computing Gmbh, Linz, Austria
13 http://www.dcs-computing.com, office@dcs-computing.com
14
15 LIGGGHTS® is part of CFDEM®project:
16 http://www.liggghts.com | http://www.cfdem.com
17
18 Core developer and main author:
19 Christoph Kloss, christoph.kloss@dcs-computing.com
20
21 LIGGGHTS® is open-source, distributed under the terms of the GNU Public
22 License, version 2 or later. It is distributed in the hope that it will
23 be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
24 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You should have
25 received a copy of the GNU General Public License along with LIGGGHTS®.
26 If not, see http://www.gnu.org/licenses . See also top-level README
27 and LICENSE files.
28
29 LIGGGHTS® and CFDEM® are registered trade marks of DCS Computing GmbH,
30 the producer of the LIGGGHTS® software and the CFDEM®coupling software
31 See http://www.cfdem.com/terms-trademark-policy for details.
32
33 -------------------------------------------------------------------------
34 Contributing author and copyright for this file:
35
36 Christoph Kloss (DCS Computing GmbH, Linz)
37 Christoph Kloss (JKU Linz)
38 Richard Berger (JKU Linz)
39 Arno Mayrhofer (CFDEMresearch GmbH, Linz)
40
41 Copyright 2012- DCS Computing GmbH, Linz
42 Copyright 2009-2012 JKU Linz
43 Copyright 2016- CFDEMresearch GmbH, Linz
44 ------------------------------------------------------------------------- */
45
46 #include <mpi.h>
47 #include "ctype.h"
48 #include "float.h"
49 #include "limits.h"
50 #include <cmath>
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <string.h>
54 #include "pair.h"
55 #include "atom.h"
56 #include "neighbor.h"
57 #include "neigh_list.h"
58 #include "domain.h"
59 #include "comm.h"
60 #include "force.h"
61 #include "kspace.h"
62 #include "update.h"
63 #include "accelerator_cuda.h"
64 #include "suffix.h"
65 #include "atom_masks.h"
66 #include "memory.h"
67 #include "error.h"
68 #include "utils.h"
69
70 #include <string>
71 #include <iostream>
72 #include "contact_models.h"
73
74 namespace LIGGGHTS {
75 namespace ContactModels {
76
Factory()77 Factory::Factory() {
78 // register contact model string to contact mappings
79 #define SURFACE_MODEL(identifier,str,constant) \
80 addSurfaceModel(#str, identifier);
81 #include "style_surface_model.h"
82 #undef SURFACE_MODEL
83
84 addNormalModel("off", NORMAL_OFF);
85 #define NORMAL_MODEL(identifier,str,constant) \
86 addNormalModel(#str, identifier);
87 #include "style_normal_model.h"
88 #undef NORMAL_MODEL
89
90 addTangentialModel("off", TANGENTIAL_OFF);
91 #define TANGENTIAL_MODEL(identifier,str,constant) \
92 addTangentialModel(#str, identifier);
93 #include "style_tangential_model.h"
94 #undef TANGENTIAL_MODEL
95
96 addCohesionModel("off", COHESION_OFF);
97 #define COHESION_MODEL(identifier,str,constant) \
98 addCohesionModel(#str, identifier);
99 #include "style_cohesion_model.h"
100 #undef COHESION_MODEL
101
102 addRollingModel("off", ROLLING_OFF);
103 #define ROLLING_MODEL(identifier,str,constant) \
104 addRollingModel(#str, identifier);
105 #include "style_rolling_model.h"
106 #undef ROLLING_MODEL
107 }
108
instance()109 Factory & Factory::instance() {
110 static Factory _instance;
111 return _instance;
112 }
113
addNormalModel(const std::string & name,int identifier)114 void Factory::addNormalModel(const std::string & name, int identifier) {
115 normal_models[name] = identifier;
116 }
117
addTangentialModel(const std::string & name,int identifier)118 void Factory::addTangentialModel(const std::string & name, int identifier){
119 tangential_models[name] = identifier;
120 }
121
addCohesionModel(const std::string & name,int identifier)122 void Factory::addCohesionModel(const std::string & name, int identifier) {
123 cohesion_models[name] = identifier;
124 }
125
addRollingModel(const std::string & name,int identifier)126 void Factory::addRollingModel(const std::string & name, int identifier) {
127 rolling_models[name] = identifier;
128 }
129
addSurfaceModel(const std::string & name,int identifier)130 void Factory::addSurfaceModel(const std::string & name, int identifier) {
131 surface_models[name] = identifier;
132 }
133
getNormalModelId(const std::string & name)134 int Factory::getNormalModelId(const std::string & name) {
135 return normal_models[name];
136 }
137
getTangentialModelId(const std::string & name)138 int Factory::getTangentialModelId(const std::string & name) {
139 return tangential_models[name];
140 }
141
getCohesionModelId(const std::string & name)142 int Factory::getCohesionModelId(const std::string & name) {
143 return cohesion_models[name];
144 }
145
getRollingModelId(const std::string & name)146 int Factory::getRollingModelId(const std::string & name) {
147 return rolling_models[name];
148 }
149
getSurfaceModelId(const std::string & name)150 int Factory::getSurfaceModelId(const std::string & name) {
151 return surface_models[name];
152 }
153
select(int & narg,char ** & args,Custom_contact_models ccm)154 int64_t Factory::select(int & narg, char ** & args,Custom_contact_models ccm) {
155 return instance().select_model(narg, args,ccm);
156 }
157
select_model(int & narg,char ** & args,Custom_contact_models ccm)158 int64_t Factory::select_model(int & narg, char ** & args, Custom_contact_models ccm)
159 {
160 // this method will consume arguments to determine which granular contact model is active
161
162 // default configuration
163 int model = NORMAL_OFF;
164 int tangential = TANGENTIAL_OFF;
165 int cohesion = COHESION_OFF;
166 int rolling = ROLLING_OFF;
167 int surface = SURFACE_DEFAULT;
168
169 // select normal model
170 if (narg > 1 && strcmp(args[0], "model") == 0)
171 {
172 if (normal_models.find(args[1]) != normal_models.end())
173 model = normal_models[args[1]];
174 else if (0 == strcmp(args[1],"custom"))
175 {
176 if (normal_models.find(ccm.custom_normal_model) != normal_models.end())
177 model = normal_models[ccm.custom_normal_model];
178 else
179 model = -1;
180 }
181 else
182 model = -1;
183
184 if(narg > 2)
185 args = &args[2];
186 narg -= 2;
187 }
188
189 // OPTIONAL: select tangential model
190 if (narg > 1 && strcmp(args[0], "tangential") == 0)
191 {
192 if (tangential_models.find(args[1]) != tangential_models.end())
193 tangential = tangential_models[args[1]];
194 else if (0 == strcmp(args[1],"custom"))
195 {
196 if (tangential_models.find(ccm.custom_tangential_model) != tangential_models.end())
197 tangential = tangential_models[ccm.custom_tangential_model];
198 else
199 tangential = -1;
200 }
201 else
202 tangential = -1;
203
204 if(narg > 2)
205 args = &args[2];
206 narg -= 2;
207 }
208
209 // OPTIONAL: select cohesion model
210 if (narg > 1 && strcmp(args[0], "cohesion") == 0)
211 {
212 if (cohesion_models.find(args[1]) != cohesion_models.end())
213 cohesion = cohesion_models[args[1]];
214 else if (0 == strcmp(args[1],"custom"))
215 {
216 if (cohesion_models.find(ccm.custom_cohesion_model) != cohesion_models.end())
217 cohesion = cohesion_models[ccm.custom_cohesion_model];
218 else
219 cohesion = -1;
220 }
221 else
222 cohesion = -1;
223
224 if(narg > 2)
225 args = &args[2];
226 narg -= 2;
227 }
228
229 // OPTIONAL: select rolling model
230 if (narg > 1 && strcmp(args[0], "rolling_friction") == 0)
231 {
232 if (rolling_models.find(args[1]) != rolling_models.end())
233 rolling = rolling_models[args[1]];
234 else if (0 == strcmp(args[1],"custom"))
235 {
236 if (rolling_models.find(ccm.custom_rolling_model) != rolling_models.end())
237 rolling = rolling_models[ccm.custom_rolling_model];
238 else
239 rolling = -1;
240 }
241 else
242 rolling = -1;
243
244 if(narg > 2)
245 args = &args[2];
246 narg -= 2;
247 }
248
249 // OPTIONAL: select surface model
250 if (narg > 1 && strcmp(args[0], "surface") == 0)
251 {
252 if (surface_models.find(args[1]) != surface_models.end())
253 surface = surface_models[args[1]];
254 else if (0 == strcmp(args[1],"custom"))
255 {
256 if (surface_models.find(ccm.custom_surface_model) != surface_models.end())
257 surface = surface_models[ccm.custom_surface_model];
258 else
259 surface = -1;
260 }
261 else
262 surface = -1;
263
264 if(narg > 2)
265 args = &args[2];
266 narg -= 2;
267 }
268
269 if((model != -1 && tangential != -1 && cohesion != -1 && rolling != -1 && surface != -1) &&
270 !(model == NORMAL_OFF && tangential == TANGENTIAL_OFF && cohesion == COHESION_OFF && rolling == ROLLING_OFF))
271 return Utils::generate_gran_hashcode(model, tangential, cohesion, rolling, surface);
272 return -1;
273 }
274
get_history_offset(const string hname)275 int ContactModelBase::get_history_offset(const string hname)
276 {
277 std::map<std::string, int>::iterator it = history_offsets.find(hname);
278 if (it != history_offsets.end())
279 return it->second;
280 return -1;
281 }
282
add_history_offset(const string hname,const int offset,const bool overwrite)283 void ContactModelBase::add_history_offset(const string hname, const int offset, const bool overwrite)
284 {
285 std::map<std::string, int>::iterator it = history_offsets.find(hname);
286 if (it == history_offsets.end() || overwrite)
287 {
288
289 history_offsets[hname] = offset;
290 }
291 else
292 error->one(FLERR, "Could not add history offset as key exists already and overwrite is not set");
293 return;
294 }
295
296 } // ContactModels
297 } // LIGGGHTS
298