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     (if not contributing author is listed, this file has been contributed
36     by the core developer)
37 
38     Copyright 2012-     DCS Computing GmbH, Linz
39     Copyright 2009-2012 JKU Linz
40 ------------------------------------------------------------------------- */
41 
42 #include <cmath>
43 #include <stdlib.h>
44 #include <string.h>
45 #include "atom.h"
46 #include "modify.h"
47 #include "memory.h"
48 #include "error.h"
49 #include "comm.h"
50 #include "force.h"
51 #include "cfd_datacoupling.h"
52 #include "fix_cfd_coupling.h"
53 #include "pair_gran.h"
54 
55 using namespace LAMMPS_NS;
56 
57 #define MAXLENGTH 30
58 
59 /* ---------------------------------------------------------------------- */
60 
CfdDatacoupling(class LAMMPS * lmp,int jarg,int,char **,class FixCfdCoupling *)61 CfdDatacoupling::CfdDatacoupling(class LAMMPS *lmp, int jarg, int, char **, class FixCfdCoupling*) :
62     Pointers(lmp)
63 {
64       iarg_ = jarg;
65       this->fc_ = fc_;
66       is_parallel = true;
67 
68       npull_ = 0;
69       npush_ = 0;
70       nvalues_max_ = 0;
71 
72       pullnames_ = NULL;
73       pulltypes_ = NULL;
74       pushnames_ = NULL;
75       pushtypes_ = NULL;
76       pushinvoked_ = NULL;
77       pullinvoked_ = NULL;
78 
79       properties_ = 0;
80 
81       grow_();
82 }
83 
84 /* ---------------------------------------------------------------------- */
85 
~CfdDatacoupling()86 CfdDatacoupling::~CfdDatacoupling()
87 {
88         memory->destroy(pullnames_);
89         memory->destroy(pulltypes_);
90         memory->destroy(pushnames_);
91         memory->destroy(pushtypes_);
92         memory->destroy(pushinvoked_);
93         memory->destroy(pullinvoked_);
94 }
95 
96 /* ---------------------------------------------------------------------- */
97 
init()98 void CfdDatacoupling::init()
99 {
100     properties_ = atom->get_properties();
101 
102     // empty list of requested properties
103     // models do their init afterwards so list will be filled
104     for(int i = 0; i < nvalues_max_; i++)
105       pushinvoked_[i] = pullinvoked_[i] = 0;
106 }
107 
108 /* ---------------------------------------------------------------------- */
109 
grow_()110 void CfdDatacoupling::grow_()
111 {
112     nvalues_max_ +=10;
113     memory->grow(pullnames_,nvalues_max_,MAXLENGTH,"FixCfdCoupling:valnames");
114     memory->grow(pulltypes_,nvalues_max_,MAXLENGTH,"FixCfdCoupling:valtypes");
115     memory->grow(pushinvoked_,MAXLENGTH,"FixCfdCoupling:pushinvoked_");
116 
117     memory->grow(pushnames_,nvalues_max_,MAXLENGTH,"FixCfdCoupling:pushnames_");
118     memory->grow(pushtypes_,nvalues_max_,MAXLENGTH,"FixCfdCoupling:pushtypes_");
119     memory->grow(pullinvoked_,MAXLENGTH,"FixCfdCoupling:pullinvoked_");
120 }
121 
122 /* ----------------------------------------------------------------------
123    pull property from other code
124 ------------------------------------------------------------------------- */
125 
pull(const char * name,const char * type,void * &,const char *)126 void CfdDatacoupling::pull(const char *name, const char *type, void *&, const char *)
127 {
128     // for MPI this is called by the library interface
129     // check if the requested property was registered by a LIGGGHTS model
130     // ie this checks if the model settings of OF and LIGGGHTS fit together
131     int found = 0;
132     for(int i = 0; i < npull_; i++)
133     {
134         // both name and type matches - ok
135         if(strcmp(name,pullnames_[i]) == 0 && strcmp(type,pulltypes_[i]) == 0)
136         {
137             found = 1;
138             pullinvoked_[i] = 1;
139         }
140         // name matches, but type not
141         else if(strcmp(name,pullnames_[i]) == 0)
142         {
143             if(comm->me == 0 && screen)
144                 fprintf(screen,"LIGGGHTS could find property %s requested by calling program, type %s is requested, but type set in LIGGGHTS is %s?\n",
145                         name,type,pulltypes_[i]);
146             error->all(FLERR,"This error is fatal");
147         }
148     }
149     if(!found)
150     {
151         if(comm->me == 0 && screen)
152             fprintf(screen,"LIGGGHTS could not find property %s requested by calling program. Check your model settings in LIGGGHTS.\n",name);
153         error->all(FLERR,"This error is fatal");
154     }
155 }
156 
157 /* ----------------------------------------------------------------------
158    push property to other code
159 ------------------------------------------------------------------------- */
160 
push(const char * name,const char * type,void * &,const char *)161 void CfdDatacoupling::push(const char *name, const char *type, void *&, const char *)
162 {
163     // for MPI this is called by the library interface
164     // check if the requested property was registered by a LIGGGHTS model
165     // ie this checks if the model settings of OF and LIGGGHTS fit together
166     int found = 0;
167     for(int i = 0; i < npush_; i++)
168     {
169         if(strcmp(name,pushnames_[i]) == 0 && strcmp(type,pushtypes_[i]) == 0)
170         {
171             found = 1;
172             pushinvoked_[i] = 1;
173         }
174         // name matches, but type not
175         else if(strcmp(name,pushnames_[i]) == 0)
176         {
177             if(comm->me == 0 && screen)
178                 fprintf(screen,"LIGGGHTS could find property %s requested by calling program, but type %s is wrong, did you mean %s?\n",
179                         name,type,pushtypes_[i]);
180             error->all(FLERR,"This error is fatal");
181         }
182     }
183     if(!found && error_push())
184     {
185         if(comm->me == 0 && screen)
186             fprintf(screen,"LIGGGHTS could not find property %s requested by calling program. Check your model settings in LIGGGHTS.\n",name);
187         lmp->error->all(FLERR,"This error is fatal");
188     }
189 }
190 
191 /* ----------------------------------------------------------------------
192    check if all properties that were requested are actually communicated
193 ------------------------------------------------------------------------- */
194 
check_datatransfer()195 void CfdDatacoupling::check_datatransfer()
196 {
197     for(int i = 0; i < npull_; i++)
198     {
199        if(!pullinvoked_[i])
200        {
201             if(comm->me == 0 && screen)
202                 fprintf(screen,"Communication of property %s from OF to LIGGGHTS was not invoked, but needed by "
203                                 "a LIGGGHTS model. Check your model settings in OF.\n",pullnames_[i]);
204             lmp->error->all(FLERR,"This error is fatal");
205        }
206     }
207 
208     for(int i = 0; i < npush_; i++)
209     {
210        if(!pushinvoked_[i] && error_push())
211        {
212             if(comm->me == 0 && screen)
213                 fprintf(screen,"Communication of property %s from LIGGGHTS to OF was not invoked, but needed by "
214                                 "a LIGGGHTS model. Check your model settings in OF.\n",pushnames_[i]);
215             lmp->error->all(FLERR,"This error is fatal");
216        }
217     }
218 }
219 
220 /* ----------------------------------------------------------------------
221    request a property to be pulled. called by models that implement physics
222 ------------------------------------------------------------------------- */
223 
add_pull_property(const char * name,const char * type)224 void CfdDatacoupling::add_pull_property(const char *name, const char *type)
225 {
226 
227     if(strlen(name) >= MAXLENGTH) error->all(FLERR,"Fix couple/cfd: Maximum string length for a variable exceeded");
228     if(npull_ >= nvalues_max_) grow_();
229 
230     for(int i = 0; i < npull_; i++)
231     {
232         if(strcmp(pullnames_[i],name) == 0 && strcmp(pulltypes_[i],type) == 0)
233             return;
234         if(strcmp(pullnames_[i],name) == 0 && strcmp(pulltypes_[i],type))
235             error->all(FLERR,"Properties added via CfdDatacoupling::add_pull_property are inconsistent");
236     }
237 
238     // test if property is available
239 
240     int len1,len2;
241     void *ptr = find_pull_property(name,type,len1,len2);
242     if (atom->nlocal && (!ptr || len1 < 0 || len2 < 0))
243     {
244         if(screen) fprintf(screen,"Property %s added via CfdDatacoupling::add_pull_property not found.\n",name);
245         error->one(FLERR,"This is fatal");
246     }
247 
248     strcpy(pullnames_[npull_],name);
249     strcpy(pulltypes_[npull_],type);
250     npull_++;
251 }
252 
253 /* ----------------------------------------------------------------------
254    request a property to be pushed. called by models that implement physics
255 ------------------------------------------------------------------------- */
256 
add_push_property(const char * name,const char * type)257 void CfdDatacoupling::add_push_property(const char *name, const char *type)
258 {
259 
260     if(strlen(name) >= MAXLENGTH)
261         error->all(FLERR,"Fix couple/cfd: Maximum string length for a variable exceeded");
262     if(npush_ >= nvalues_max_) grow_();
263 
264     for(int i = 0; i < npush_; i++)
265     {
266         if(strcmp(pushnames_[i],name) == 0 && strcmp(pushtypes_[i],type) == 0)
267             return;
268         if(strcmp(pushnames_[i],name) == 0 && strcmp(pushtypes_[i],type))
269             error->all(FLERR,"Properties added via CfdDatacoupling::add_push_property are inconsistent");
270     }
271 
272     // test if property is available
273 
274     int len1,len2;
275     void *ptr = find_push_property(name,type,len1,len2);
276     if (atom->nlocal && (!ptr || len1 < 0 || len2 < 0))
277     {
278         if(screen) fprintf(screen,"Property %s added via CfdDatacoupling::add_push_property not found.\n",name);
279         error->one(FLERR,"This is fatal");
280     }
281 
282     strcpy(pushnames_[npush_],name);
283     strcpy(pushtypes_[npush_],type);
284     npush_++;
285 }
286 
287 /* ----------------------------------------------------------------------
288    find a property that was requested
289    called from data exchange model
290    property may come from atom class, from a fix property, or fix rigid
291    last 2 args are the data length and are used for all data
292 ------------------------------------------------------------------------- */
293 
find_pull_property(const char * name,const char * type,int & len1,int & len2)294 void* CfdDatacoupling::find_pull_property(const char *name, const char *type, int &len1, int &len2)
295 {
296     return properties_->find_property(name,type,len1,len2);
297 }
298 
299 /* ---------------------------------------------------------------------- */
300 
find_push_property(const char * name,const char * type,int & len1,int & len2)301 void* CfdDatacoupling::find_push_property(const char *name, const char *type, int &len1, int &len2)
302 {
303     return properties_->find_property(name,type,len1,len2);
304 }
305 
306 /* ----------------------------------------------------------------------
307    find a property that was requested
308    called from data exchange model
309    property may come from atom class, from a fix property, or fix rigid
310    last 2 args are the data length and are used for all data
311 ------------------------------------------------------------------------- */
312 
allocate_external(int ** &,int,int,int)313 void CfdDatacoupling::allocate_external(int**&, int, int, int)
314 {
315     error->all(FLERR,"CFD datacoupling setting used in LIGGGHTS is incompatible with setting in OF");
316 }
317 
318 /* ---------------------------------------------------------------------- */
319 
allocate_external(double ** &,int,int,double)320 void CfdDatacoupling::allocate_external(double**&, int, int, double)
321 {
322     error->all(FLERR,"CFD datacoupling setting used in LIGGGHTS is incompatible with setting in OF");
323 }
324 
325 /* ---------------------------------------------------------------------- */
326 
allocate_external(int ** &,int,const char *,int)327 void CfdDatacoupling::allocate_external(int**&, int, const char *, int)
328 {
329     error->all(FLERR,"CFD datacoupling setting used in LIGGGHTS is incompatible with setting in OF");
330 }
331 
332 /* ---------------------------------------------------------------------- */
333 
allocate_external(double ** &,int,const char *,double)334 void CfdDatacoupling::allocate_external(double**&, int, const char*, double)
335 {
336     error->all(FLERR,"CFD datacoupling setting used in LIGGGHTS is incompatible with setting in OF");
337 }
338