1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 /****************************************************************************/
4 /* */
5 /* File: priority.c */
6 /* */
7 /* Purpose: functions for managing priorities of distributed objects */
8 /* */
9 /* Author: Stefan Lang */
10 /* Institut fuer Computeranwendungen III */
11 /* Universitaet Stuttgart */
12 /* Pfaffenwaldring 27 */
13 /* 70550 Stuttgart */
14 /* email: birken@ica3.uni-stuttgart.de */
15 /* */
16 /* History: 980201 sl begin */
17 /* */
18 /* Remarks: */
19 /* */
20 /****************************************************************************/
21
22 #ifdef ModelP
23
24 /****************************************************************************/
25 /* */
26 /* include files */
27 /* system include files */
28 /* application include files */
29 /* */
30 /****************************************************************************/
31
32 #include <config.h>
33 #include <cstdlib>
34
35 #include "parallel.h"
36 #include <dune/uggrid/ugdevices.h>
37 #include <dune/uggrid/gm/evm.h>
38 #include <dune/uggrid/gm/gm.h>
39 #include <dune/uggrid/gm/refine.h>
40 #include <dune/uggrid/gm/shapes.h>
41 #include <dune/uggrid/gm/ugm.h>
42 #include <dune/uggrid/low/debug.h>
43 #include <dune/uggrid/low/namespace.h>
44
45 /* UG namespaces: */
46 USING_UG_NAMESPACES
47
48 /* PPIF namespace: */
49 using namespace PPIF;
50
51
52 /****************************************************************************/
53 /* */
54 /* defines in the following order */
55 /* */
56 /* compile time constants defining static data size (i.e. arrays) */
57 /* other constants */
58 /* macros */
59 /* */
60 /****************************************************************************/
61
62 /* macros for merge new priority with objects existing one */
63 /* valid only for all types of ghost priorities */
64 #define PRIO_CALC(e) ((USED(e) && THEFLAG(e)) ? PrioVHGhost : \
65 (THEFLAG(e)) ? PrioVGhost : (USED(e)) ? \
66 PrioHGhost : (assert(0),0))
67
68 #define SETPRIOPV SETPRIOX
69
70 /* macros for setting object priorities with related objects */
NODE_PRIORITY_SET(DDD::DDDContext & context,GRID * grid,NODE * node,INT prio)71 inline void NODE_PRIORITY_SET(DDD::DDDContext& context, GRID* grid, NODE* node, INT prio)
72 {
73 /* set priorities of node */
74 SETPRIOX(context, node, prio);
75
76 if (VEC_DEF_IN_OBJ_OF_GRID(grid, NODEVEC) and NVECTOR(node) != nullptr)
77 SETPRIOPV(context, NVECTOR(node),prio);
78 }
79
PRIO_SET_EDGE(DDD::DDDContext & context,EDGE * edge,INT prio)80 inline void PRIO_SET_EDGE(DDD::DDDContext& context, EDGE* edge, INT prio)
81 {
82 SETPRIOX(context, edge, prio);
83 }
84
EDGE_PRIORITY_SET(DDD::DDDContext & context,GRID * grid,EDGE * edge,INT prio)85 inline void EDGE_PRIORITY_SET(DDD::DDDContext& context, GRID* grid, EDGE* edge, INT prio)
86 {
87 /* set priorities of node for 3D */
88 PRIO_SET_EDGE(context, edge, prio);
89
90 /* set priority of edge vector */
91 if (VEC_DEF_IN_OBJ_OF_GRID(grid, EDGEVEC) and EDVECTOR(edge) != nullptr)
92 SETPRIOX(context, EDVECTOR(edge),prio);
93 }
94
95
96 /****************************************************************************/
97 /* */
98 /* data structures used in this source file (exported data structures are */
99 /* in the corresponding include file!) */
100 /* */
101 /****************************************************************************/
102
103
104 /****************************************************************************/
105 /* */
106 /* definition of exported global variables */
107 /* */
108 /****************************************************************************/
109
110
111 /****************************************************************************/
112 /* */
113 /* forward declarations of functions used before they are defined */
114 /* */
115 /****************************************************************************/
116
117
118 /*
119 for all PrioMaster-nodes with remote copies, set exactly one
120 to PrioMaster, the other copies to PrioBorder in order to establish
121 the BorderNodeIF. this is done for one grid.
122 */
123
124
125 /****************************************************************************/
126 /*
127 ComputeNodeBorderPrios -
128
129 SYNOPSIS:
130 static int ComputeNodeBorderPrios (DDD_OBJ obj);
131
132 PARAMETERS:
133 . obj -
134
135 DESCRIPTION:
136
137 RETURN VALUE:
138 int
139 */
140 /****************************************************************************/
141
ComputeNodeBorderPrios(DDD::DDDContext & context,DDD_OBJ obj)142 static int ComputeNodeBorderPrios (DDD::DDDContext& context, DDD_OBJ obj)
143 {
144 NODE *node = (NODE *)obj;
145 int *plist = DDD_InfoProcList(context, PARHDR(node));
146 int i, min_proc = context.procs();
147
148 /*
149 minimum processor number will get Master-node,
150 all others get Border-nodes
151 */
152 for(i=0; plist[i]>=0; i+=2)
153 {
154 if (plist[i+1]==PrioMaster && plist[i]<min_proc)
155 min_proc = plist[i];
156 }
157
158 if (min_proc == context.procs())
159 return(0);
160
161 if (context.me() != min_proc)
162 SETPRIO(context, node, PrioBorder);
163 return 0;
164 }
165
166
167 /****************************************************************************/
168 /*
169 ComputeVectorBorderPrios -
170
171 SYNOPSIS:
172 static int ComputeVectorBorderPrios (DDD_OBJ obj);
173
174 PARAMETERS:
175 . obj -
176
177 DESCRIPTION:
178
179 RETURN VALUE:
180 int
181 */
182 /****************************************************************************/
183
ComputeVectorBorderPrios(DDD::DDDContext & context,DDD_OBJ obj)184 static int ComputeVectorBorderPrios (DDD::DDDContext& context, DDD_OBJ obj)
185 {
186 VECTOR *vector = (VECTOR *)obj;
187 int *plist = DDD_InfoProcList(context, PARHDR(vector));
188 int i, min_proc = context.procs();
189
190 /*
191 minimum processor number will get Master-node,
192 all others get Border-nodes
193 */
194 for(i=0; plist[i]>=0; i+=2)
195 {
196 if (plist[i+1]==PrioMaster && plist[i]<min_proc)
197 min_proc = plist[i];
198 }
199
200 if (min_proc == context.procs())
201 return(0);
202
203 if (context.me() != min_proc)
204 SETPRIO(context, vector, PrioBorder);
205 return 0;
206 }
207
208
209
210 /****************************************************************************/
211 /*
212 ComputeEdgeBorderPrios -
213
214 SYNOPSIS:
215 static int ComputeEdgeBorderPrios (DDD_OBJ obj);
216
217 PARAMETERS:
218 . obj -
219
220 DESCRIPTION:
221
222 RETURN VALUE:
223 void
224 */
225 /****************************************************************************/
226
ComputeEdgeBorderPrios(DDD::DDDContext & context,DDD_OBJ obj)227 static int ComputeEdgeBorderPrios (DDD::DDDContext& context, DDD_OBJ obj)
228 {
229 EDGE *edge = (EDGE *)obj;
230 int *plist = DDD_InfoProcList(context, PARHDR(edge));
231 int i, min_proc = context.procs();
232
233 /*
234 minimum processor number will get Master-node,
235 all others get Border-nodes
236 */
237 for(i=0; plist[i]>=0; i+=2)
238 {
239 if (plist[i+1]==PrioMaster && plist[i]<min_proc)
240 min_proc = plist[i];
241 }
242
243 if (min_proc == context.procs())
244 return(0);
245
246 if (context.me() != min_proc)
247 SETPRIO(context, edge, PrioBorder);
248 return 0;
249 }
250
251
252 /****************************************************************************/
253 /*
254 SetGhostObjectPriorities -
255
256 SYNOPSIS:
257 void SetGhostObjectPriorities (GRID *theGrid);
258
259 PARAMETERS:
260 . theGrid
261
262 DESCRIPTION:
263
264 RETURN VALUE:
265 void
266 */
267 /****************************************************************************/
268
SetGhostObjectPriorities(GRID * theGrid)269 void NS_DIM_PREFIX SetGhostObjectPriorities (GRID *theGrid)
270 {
271 ELEMENT *theElement,*theNeighbor,*SonList[MAX_SONS];
272 NODE *theNode;
273 EDGE *theEdge;
274 VECTOR *theVector;
275 INT i,prio,hghost,vghost;
276
277 auto& context = theGrid->dddContext();
278 const auto& me = context.me();
279
280 /* reset USED flag for objects of ghostelements */
281 for (theElement=PFIRSTELEMENT(theGrid);
282 theElement!=NULL;
283 theElement=SUCCE(theElement))
284 {
285 SETUSED(theElement,0); SETTHEFLAG(theElement,0);
286 for (i=0; i<EDGES_OF_ELEM(theElement); i++)
287 {
288 theEdge = GetEdge(CORNER(theElement,CORNER_OF_EDGE(theElement,i,0)),
289 CORNER(theElement,CORNER_OF_EDGE(theElement,i,1)));
290 ASSERT(theEdge != NULL);
291 SETUSED(theEdge,0); SETTHEFLAG(theEdge,0);
292 }
293 if (VEC_DEF_IN_OBJ_OF_GRID(theGrid,SIDEVEC))
294 for (i=0; i<SIDES_OF_ELEM(theElement); i++)
295 {
296 theVector = SVECTOR(theElement,i);
297 if (theVector != NULL) {
298 SETUSED(theVector,0);
299 SETTHEFLAG(theVector,0);
300 }
301 }
302 }
303 /* to reset also nodes which are at corners of the boundary */
304 /* reset of nodes need to be done through the node list */
305 for (theNode=PFIRSTNODE(theGrid); theNode!=NULL; theNode=SUCCN(theNode))
306 {
307 SETUSED(theNode,0); SETTHEFLAG(theNode,0);
308 SETMODIFIED(theNode,0);
309 }
310
311 /* set FLAG for objects of horizontal and vertical overlap */
312 for (theElement=PFIRSTELEMENT(theGrid);
313 theElement!=NULL;
314 theElement=SUCCE(theElement))
315 {
316 if (PARTITION(theElement) == me) continue;
317
318 /* check for horizontal ghost */
319 hghost = 0;
320 for (i=0; i<SIDES_OF_ELEM(theElement); i++)
321 {
322 theNeighbor = NBELEM(theElement,i);
323 if (theNeighbor == NULL) continue;
324
325 if (PARTITION(theNeighbor) == me)
326 {
327 hghost = 1;
328 break;
329 }
330 }
331
332 /* check for vertical ghost */
333 vghost = 0;
334 GetAllSons(theElement,SonList);
335 for (i=0; SonList[i]!=NULL; i++)
336 {
337 if (PARTITION(SonList[i]) == me)
338 {
339 vghost = 1;
340 break;
341 }
342 }
343
344 /* one or both of vghost and hghost should be true here */
345 /* except for elements which will be disposed during Xfer */
346
347 if (vghost) SETTHEFLAG(theElement,1);
348 if (hghost) SETUSED(theElement,1);
349 for (i=0; i<CORNERS_OF_ELEM(theElement); i++)
350 {
351 theNode = CORNER(theElement,i);
352 if (vghost) SETTHEFLAG(theNode,1);
353 if (hghost) SETUSED(theNode,1);
354 }
355 for (i=0; i<EDGES_OF_ELEM(theElement); i++)
356 {
357 theEdge = GetEdge(CORNER_OF_EDGE_PTR(theElement,i,0),
358 CORNER_OF_EDGE_PTR(theElement,i,1));
359 ASSERT(theEdge != NULL);
360 if (vghost) SETTHEFLAG(theEdge,1);
361 if (hghost) SETUSED(theEdge,1);
362 }
363 if (VEC_DEF_IN_OBJ_OF_GRID(theGrid,SIDEVEC))
364 for (i=0; i<SIDES_OF_ELEM(theElement); i++)
365 {
366 theVector = SVECTOR(theElement,i);
367 if (theVector != NULL) {
368 if (vghost) SETTHEFLAG(theVector,1);
369 if (hghost) SETUSED(theVector,1);
370 }
371 }
372 }
373
374 /* set USED flag for objects of master elements */
375 /* reset FLAG for objects of master elements */
376 for (theElement=PFIRSTELEMENT(theGrid);
377 theElement!=NULL;
378 theElement=SUCCE(theElement))
379 {
380 if (PARTITION(theElement) != me) continue;
381
382 SETUSED(theElement,0); SETTHEFLAG(theElement,0);
383 for (i=0; i<CORNERS_OF_ELEM(theElement); i++)
384 {
385 theNode = CORNER(theElement,i);
386 SETUSED(theNode,0); SETTHEFLAG(theNode,0);
387 SETMODIFIED(theNode,1);
388 }
389 for (i=0; i<EDGES_OF_ELEM(theElement); i++)
390 {
391 theEdge = GetEdge(CORNER_OF_EDGE_PTR(theElement,i,0),
392 CORNER_OF_EDGE_PTR(theElement,i,1));
393 ASSERT(theEdge != NULL);
394 SETUSED(theEdge,0); SETTHEFLAG(theEdge,0);
395 }
396 if (VEC_DEF_IN_OBJ_OF_GRID(theGrid,SIDEVEC))
397 for (i=0; i<SIDES_OF_ELEM(theElement); i++)
398 {
399 theVector = SVECTOR(theElement,i);
400 if (theVector != NULL) {
401 SETUSED(theVector,0);
402 SETTHEFLAG(theVector,0);
403 }
404 }
405 }
406
407 /* set object priorities for ghostelements */
408 for (theElement=PFIRSTELEMENT(theGrid);
409 theElement!=NULL;
410 theElement=SUCCE(theElement))
411 {
412 if (PARTITION(theElement) == me) continue;
413
414 if (USED(theElement) || THEFLAG(theElement))
415 {
416 prio = PRIO_CALC(theElement);
417 PRINTDEBUG(gm,1,("SetGhostObjectPriorities(): e=" EID_FMTX " new prio=%d\n",
418 EID_PRTX(theElement),prio))
419 SETEPRIOX(context, theElement, prio);
420
421 if (VEC_DEF_IN_OBJ_OF_GRID(theGrid,ELEMVEC))
422 {
423 theVector = EVECTOR(theElement);
424 if (theVector != NULL)
425 SETPRIOX(context, theVector,prio);
426 }
427 }
428
429 /* set edge priorities */
430 for (i=0; i<EDGES_OF_ELEM(theElement); i++)
431 {
432
433 theEdge = GetEdge(CORNER(theElement,CORNER_OF_EDGE(theElement,i,0)),
434 CORNER(theElement,CORNER_OF_EDGE(theElement,i,1)));
435 ASSERT(theEdge != NULL);
436
437 if (USED(theEdge) || THEFLAG(theEdge))
438 {
439 PRINTDEBUG(dddif,3,(PFMT " dddif_SetGhostObjectPriorities():"
440 " downgrade edge=" EDID_FMTX " from=%d to PrioHGhost\n",
441 me,EDID_PRTX(theEdge),prio));
442
443 EDGE_PRIORITY_SET(context, theGrid,theEdge,PRIO_CALC(theEdge));
444 }
445 else
446 EDGE_PRIORITY_SET(context, theGrid,theEdge,PrioMaster);
447 }
448
449 #ifdef __THREEDIM__
450 /* if one(all) of the side nodes is (are) a hghost (vghost) node */
451 /* then its a hghost (vghost) side vector */
452 if (VEC_DEF_IN_OBJ_OF_GRID(theGrid,SIDEVEC))
453 for (i=0; i<SIDES_OF_ELEM(theElement); i++)
454 {
455 if (USED(theVector) || THEFLAG(theVector))
456 SETPRIOX(context, theVector,PRIO_CALC(theVector));
457 }
458 #endif
459
460 }
461 /* to set also nodes which are at corners of the boundary */
462 /* set them through the node list */
463 for (theNode=PFIRSTNODE(theGrid); theNode!=NULL; theNode=SUCCN(theNode))
464 {
465 /* check if its a master node */
466 if (USED(theNode) || THEFLAG(theNode))
467 {
468 PRINTDEBUG(dddif,3,(PFMT " dddif_SetGhostObjectPriorities():"
469 " downgrade node=" ID_FMTX " from=%d to PrioHGhost\n",
470 me,ID_PRTX(theNode),prio));
471
472 /* set node priorities of node to ghost */
473 NODE_PRIORITY_SET(context, theGrid,theNode,PRIO_CALC(theNode));
474 }
475 else if (MODIFIED(theNode) == 0)
476 {
477 /* this is a node of the boundary without connection to master elements */
478 NODE_PRIORITY_SET(context, theGrid,theNode,PrioHGhost);
479 }
480 /* this is needed only for consistency after refinement */
481 /* ghost nodes which belong after refinement to master */
482 /* elements have to be upgraded explicitly (980126 s.l.)*/
483 else if (MODIFIED(theNode) == 1)
484 {
485 NODE_PRIORITY_SET(context, theGrid,theNode,PrioMaster);
486 }
487 }
488 }
489
490
491 /****************************************************************************/
492 /*
493 SetBorderPriorities -
494
495 SYNOPSIS:
496 INT SetBorderPriorities (GRID *theGrid);
497
498 PARAMETERS:
499 . theGrid
500
501 DESCRIPTION:
502
503 RETURN VALUE:
504 INT
505 */
506 /****************************************************************************/
507
SetBorderPriorities(GRID * theGrid)508 INT NS_DIM_PREFIX SetBorderPriorities (GRID *theGrid)
509 {
510 auto& context = theGrid->dddContext();
511 const auto& dddctrl = ddd_ctrl(context);
512
513 DDD_IFAExecLocal(context,
514 dddctrl.BorderNodeSymmIF,GRID_ATTR(theGrid),
515 ComputeNodeBorderPrios);
516
517 /* TODO: distinguish two cases:
518 1. only nodevectors then setting of vector prios can
519 be done in ComputeNodeBorderPrios without extra communiction
520 2. with other vectortypes (side and/or edgevectors) use
521 ComputeVectorBorderPrios
522 */
523 DDD_IFAExecLocal(context,
524 dddctrl.BorderVectorSymmIF,GRID_ATTR(theGrid),
525 ComputeVectorBorderPrios);
526
527 DDD_IFAExecLocal(context,
528 dddctrl.BorderEdgeSymmIF,GRID_ATTR(theGrid),
529 ComputeEdgeBorderPrios);
530
531 return(GM_OK);
532 }
533
534
535 /****************************************************************************/
536 /*
537 SetGridBorderPriorities -
538
539 SYNOPSIS:
540 INT SetGridBorderPriorities (GRID *theGrid);
541
542 PARAMETERS:
543 . theGrid
544
545 DESCRIPTION:
546
547 RETURN VALUE:
548 INT
549 */
550 /****************************************************************************/
551
552
SetGridBorderPriorities(GRID * theGrid)553 INT NS_DIM_PREFIX SetGridBorderPriorities (GRID *theGrid)
554 {
555 /* set border priorities on next higher level */
556 if (SetBorderPriorities(UPGRID(theGrid)) != GM_OK) return(GM_FATAL);
557
558 return(GM_OK);
559 }
560
561 #endif
562