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:	  identify.c													*/
6 /*																			*/
7 /* Purpose:   identification of distributed ug objects                                  */
8 /*																			*/
9 /* Author:	  Stefan Lang                                                                                   */
10 /*			  Institut fuer Computeranwendungen III                                                 */
11 /*			  Universitaet Stuttgart										*/
12 /*			  Pfaffenwaldring 27											*/
13 /*			  70550 Stuttgart												*/
14 /*			  email: ug@ica3.uni-stuttgart.de								*/
15 /*																			*/
16 /* History:   26.11.96 begin, first version extracted from refine.c			*/
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 <cstdio>
34 
35 #include <dune/uggrid/ugdevices.h>
36 
37 #include <dune/uggrid/gm/gm.h>
38 #include <dune/uggrid/gm/refine.h>
39 #include <dune/uggrid/gm/rm.h>
40 #include <dune/uggrid/gm/ugm.h>
41 #include <dune/uggrid/low/debug.h>
42 #include <dune/uggrid/low/ugtypes.h>
43 
44 #include <dune/uggrid/parallel/ddd/include/ddd.h>
45 #include "identify.h"
46 #include "parallel.h"
47 
48 /* UG namespaces: */
49 USING_UG_NAMESPACES
50 
51 /* PPIF namespace: */
52 using namespace PPIF;
53 
54 /****************************************************************************/
55 /*																			*/
56 /* defines in the following order											*/
57 /*																			*/
58 /*		  compile time constants defining static data size (i.e. arrays)	*/
59 /*		  other constants													*/
60 /*		  macros															*/
61 /*																			*/
62 /****************************************************************************/
63 
64 /* flags for identification */
65 enum {CLEAR = 0,
66       IDENT = 1};
67 
68 /* maximum count of objects for identification */
69 #define MAX_OBJECT      3
70 
71 /* maximum count of tokens for identification */
72 #define MAX_TOKEN       10
73 
74 /* determine the ddd header for identification of a node */
75 #define NIDENT_HDR(node) ( (CORNERTYPE(node)) ? \
76                            PARHDR((NODE *)NFATHER(node)) : PARHDR(node) )
77 
78 /* mapping of flags used for identification */
79 #define NIDENT(p)                     THEFLAG(p)
80 #define SETNIDENT(p,n)                SETTHEFLAG(p,n)
81 
82 #define EDIDENT(p)                    THEFLAG(p)
83 #define SETEDIDENT(p,n)               SETTHEFLAG(p,n)
84 
85 /* strong checking of identification (0=off 1==on) */
86 #define NIDENTASSERT    1
87 #define EDIDENTASSERT   1
88 
89 /****************************************************************************/
90 /*																			*/
91 /* data structures used in this source file (exported data structures are	*/
92 /*		  in the corresponding include file!)								*/
93 /*																			*/
94 /****************************************************************************/
95 
96 
97 
98 /****************************************************************************/
99 /*																			*/
100 /* definition of exported global variables									*/
101 /*																			*/
102 /****************************************************************************/
103 
104 INT NS_DIM_PREFIX ident_mode = IDENT_OFF;
105 
106 /****************************************************************************/
107 /*																			*/
108 /* definition of variables global to this source file only (static!)		*/
109 /*																			*/
110 /****************************************************************************/
111 
112 
113 /* this function is called for low level identification */
114 static INT (*Ident_FctPtr)(DDD::DDDContext& context, DDD_HDR *IdentObjectHdr, INT nobject,
115                            const int *proclist, int skiptag, DDD_HDR *IdentHdr, INT nident) = NULL;
116 
117 static int check_nodetype = 0;
118 
119 #ifdef Debug
120 static INT debug = 0;
121 static INT identlevel = 0;
122 #endif
123 
124 /****************************************************************************/
125 /*																			*/
126 /* forward declarations of functions used before they are defined			*/
127 /*																			*/
128 /****************************************************************************/
129 
130 
131 /****************************************************************************/
132 /*
133    ResetIdentFlags -
134 
135    SYNOPSIS:
136    static void ResetIdentFlags (GRID *UpGrid);
137 
138    PARAMETERS:
139    .  UpGrid
140 
141    DESCRIPTION:
142 
143    RETURN VALUE:
144    void
145  */
146 /****************************************************************************/
147 
ResetIdentFlags(GRID * Grid)148 static void ResetIdentFlags (GRID *Grid)
149 {
150   NODE *theNode;
151   EDGE *theEdge;
152   LINK *theLink;
153 
154   /* clear all IDENT flags */
155   for (theNode=FIRSTNODE(Grid); theNode!=NULL; theNode=SUCCN(theNode))
156   {
157     SETNIDENT(theNode,CLEAR);
158     SETUSED(theNode,0);
159 
160     for (theLink=START(theNode); theLink!=NULL; theLink=NEXT(theLink))
161     {
162       theEdge = MYEDGE(theLink);
163       SETEDIDENT(theEdge,CLEAR);
164     }
165   }
166 
167 }
168 
169 #ifdef Debug
170 
171 
172 /****************************************************************************/
173 /*
174    Print_Identify_ObjectList -
175 
176    SYNOPSIS:
177    static INT Print_Identify_ObjectList (DDD_HDR *IdentObjectHdr, INT nobject,
178                                 const int *proclist, int skiptag, DDD_HDR *IdentHdr, INT nident);
179 
180    PARAMETERS:
181    .  IdentObjectHdr
182    .  nobject
183    .  proclist
184    .  skiptag
185    .  IdentHdr
186    .  nident
187 
188    DESCRIPTION:
189 
190    RETURN VALUE:
191    INT
192  */
193 /****************************************************************************/
194 
Print_Identify_ObjectList(DDD_HDR * IdentObjectHdr,INT nobject,const int * proclist,int skiptag,DDD_HDR * IdentHdr,INT nident)195 static INT Print_Identify_ObjectList (DDD_HDR *IdentObjectHdr, INT nobject,
196                                       const int *proclist, int skiptag, DDD_HDR *IdentHdr, INT nident)
197 {
198   INT i;
199 
200   ASSERT(nobject>0);
201   ASSERT(nident>0);
202   ASSERT(*proclist!=-1);
203 
204   /* print the interesting call parameters */
205   PrintDebug ("%d:    Print_Identify_ObjectList(): nobject=%d nident=%d"
206               " skiptag=%d\n",me,nobject,nident,skiptag);
207 
208   /* print line prefix */
209   PrintDebug ("%d: l=%d",me,identlevel);
210 
211   /* print the objects used for identify */
212   PrintDebug ("    IdentHdr:");
213   for (i=0; i<nident; i++)
214     PrintDebug (" %d",DDD_InfoGlobalId(IdentHdr[i]));
215 
216   /* print type of objects to identify */
217   PrintDebug ("    IdentObjectType:");
218   for (i=0; i<nobject; i++)
219     PrintDebug (" %d",DDD_InfoType(IdentObjectHdr[i]));
220 
221   /* print the proclist to identify to */
222   PrintDebug ("    ProcList: %d",me);
223   while (*proclist != -1)
224   {
225     if (*(proclist+1) == skiptag)
226     {
227       proclist += 2;
228       continue;
229     }
230 
231     PrintDebug (" %d",*proclist);
232     proclist += 2;
233   }
234 
235   /* print my processor number */
236   PrintDebug ("    me:%d",me);
237 
238   /* print the objects to identify */
239   PrintDebug ("    IdentObjectHdr:");
240   for (i=0; i<nobject; i++)
241     PrintDebug (" %d",DDD_InfoGlobalId(IdentObjectHdr[i]));
242 
243   PrintDebug ("\n");
244 
245   return(0);
246 
247 }
248 #endif
249 
250 #ifdef Debug
251 
252 
253 /****************************************************************************/
254 /*
255    Print_Identified_ObjectList -
256 
257    SYNOPSIS:
258    static INT Print_Identified_ObjectList (DDD_HDR *IdentObjectHdr, INT nobject, int *proclist, int skiptag, DDD_HDR *IdentHdr, INT nident);
259 
260    PARAMETERS:
261    .  IdentObjectHdr
262    .  nobject
263    .  proclist
264    .  skiptag
265    .  IdentHdr
266 
267    DESCRIPTION:
268 
269    RETURN VALUE:
270    INT
271  */
272 /****************************************************************************/
273 
Print_Identified_ObjectList(DDD_HDR * IdentObjectHdr,INT nobject,int * proclist,int skiptag,DDD_HDR * IdentHdr,INT nident)274 static INT Print_Identified_ObjectList (DDD_HDR *IdentObjectHdr, INT nobject,
275                                         int *proclist, int skiptag, DDD_HDR *IdentHdr, INT nident)
276 {
277   INT i;
278 
279   ASSERT(nobject>0);
280   ASSERT(nident>0);
281   ASSERT(*proclist!=-1);
282 
283   /* print the interesting call parameters */
284   PrintDebug ("%d:    Print_Identified_ObjectList(): nobject=%d nident=%d"
285               " skiptag=%d\n",me,nobject,nident,skiptag);
286 
287   /* print the objects to identify */
288   PrintDebug ("%d: l=%d   IdentObjectHdr:",me,identlevel);
289   for (i=0; i<nobject; i++)
290     PrintDebug (" %d",DDD_InfoGlobalId(IdentObjectHdr[i]));
291 
292   /* print the objects used for identify */
293   PrintDebug ("    IdentHdr:");
294   for (i=0; i<nident; i++)
295     PrintDebug (" %d",DDD_InfoGlobalId(IdentHdr[i]));
296 
297   /* print the proclist to identify to */
298   PrintDebug ("    ProcList: %d",me);
299   while (*proclist != -1)
300   {
301     if (*(proclist+1) == skiptag)
302     {
303       proclist += 2;
304       continue;
305     }
306 
307     PrintDebug (" %d",*proclist);
308     proclist += 2;
309   }
310 
311   /* print my processor number */
312   PrintDebug ("    me:%d",me);
313 
314   /* print type of objects to identify */
315   PrintDebug ("    IdentObjectType:");
316   for (i=0; i<nobject; i++)
317     PrintDebug (" %d",DDD_InfoType(IdentObjectHdr[i]));
318 
319   PrintDebug ("\n");
320 
321   return(0);
322 }
323 #endif
324 
325 
326 
327 /****************************************************************************/
328 /*
329    Identify_by_ObjectList -
330 
331    SYNOPSIS:
332    static INT Identify_by_ObjectList (DDD_HDR *IdentObjectHdr, INT nobject,
333                                 int *proclist, int skiptag, DDD_HDR *IdentHdr, INT nident);
334 
335    PARAMETERS:
336    .  IdentObjectHdr
337    .  nobject
338    .  proclist
339    .  skiptag
340    .  IdentHdr
341    .  nident
342 
343    DESCRIPTION:
344 
345    RETURN VALUE:
346    INT
347  */
348 /****************************************************************************/
349 
Identify_by_ObjectList(DDD::DDDContext & context,DDD_HDR * IdentObjectHdr,INT nobject,const int * proclist,int skiptag,DDD_HDR * IdentHdr,INT nident)350 static INT Identify_by_ObjectList (DDD::DDDContext& context, DDD_HDR *IdentObjectHdr, INT nobject,
351                                    const int *proclist, int skiptag, DDD_HDR *IdentHdr, INT nident)
352 {
353   INT i,j,n;
354 
355   ASSERT(nobject>0);
356   ASSERT(nident>0);
357   ASSERT(*proclist!=-1);
358 
359 #ifdef Debug
360   IFDEBUG(dddif,1)
361   Print_Identify_ObjectList(IdentObjectHdr,nobject,proclist,skiptag,
362                             IdentHdr,nident);
363   ENDDEBUG
364 #endif
365 
366   n = 0;
367   while (*proclist != -1)
368   {
369     ASSERT(n < context.procs());
370 
371     if (*(proclist+1) == skiptag)
372     {
373       proclist += 2;
374       continue;
375     }
376 
377     /* identify the object */
378     for (j=0; j<nobject; j++)
379     {
380       for (i=0; i<nident; i++)
381       {
382         PRINTDEBUG(dddif,5,("%d: Identify_by_ObjectList(): Type=%d"
383                             " IdentObjectHdr=%08x proclist=%d IdentHdr=%08x me=%d\n",
384                             me,DDD_InfoType(IdentObjectHdr[j]),
385                             DDD_InfoGlobalId(IdentObjectHdr[j]),
386                             *proclist,DDD_InfoGlobalId(IdentHdr[i]),me));
387 
388         /* hand identification hdr to ddd */
389         DDD_IdentifyObject(context, IdentObjectHdr[j], *proclist, IdentHdr[i]);
390       }
391     }
392 
393     n++;
394     assert(n < context.procs());
395     proclist += 2;
396   }
397 
398   /* identification should occur to at least one other proc */
399   ASSERT(n>0);
400 
401   return 0;
402 }
403 
404 #ifdef __THREEDIM__
405 
406 
IdentifySideVector(DDD::DDDContext & context,ELEMENT * theElement,ELEMENT * theNeighbor,ELEMENT * Son,INT SonSide)407 static void IdentifySideVector (DDD::DDDContext& context, ELEMENT* theElement, ELEMENT *theNeighbor,
408                                ELEMENT *Son, INT SonSide)
409 {
410   INT k,nident;
411   DDD_HDR IdentObjectHdr[MAX_OBJECT];
412   DDD_HDR IdentHdr[MAX_TOKEN];
413   int *proclist;
414   NODE *theNode;
415 
416   nident = 0;
417 
418   IdentObjectHdr[0] = PARHDR(SVECTOR(Son,SonSide));
419 
420   proclist = DDD_InfoProcList(context, PARHDRE(theNeighbor));
421 
422   /* identify using corner nodes */
423   for (k=0; k<CORNERS_OF_SIDE(Son,SonSide); k++)
424   {
425     theNode = CORNER(Son,CORNER_OF_SIDE(Son,SonSide,k));
426     if (CORNERTYPE(theNode))
427       IdentHdr[nident++] = PARHDR((NODE *)NFATHER(theNode));
428     else
429       IdentHdr[nident++] = PARHDR(theNode);
430   }
431 
432   proclist = DDD_InfoProcList(context, PARHDRE(theNeighbor));
433 
434   Ident_FctPtr(context, IdentObjectHdr,1,proclist+2,PrioHGhost,IdentHdr,nident);
435 
436 }
437 #endif
438 
439 
440 /****************************************************************************/
441 /*
442    IdentifyNode -
443 
444    SYNOPSIS:
445    static void IdentifyNode (ELEMENT *theNeighbor, NODE *theNode,
446                                 NODE *Nodes[MAX_SIDE_NODES], INT node, INT ncorners, INT Vec);
447 
448    PARAMETERS:
449    .  theNeighbor
450    .  theNode
451    .  Nodes[MAX_SIDE_NODES]
452    .  node
453    .  ncorners
454    .  Vec
455 
456    DESCRIPTION:
457 
458    RETURN VALUE:
459    void
460  */
461 /****************************************************************************/
462 
IdentifyNode(GRID * theGrid,ELEMENT * theNeighbor,NODE * theNode,NODE * Nodes[MAX_SIDE_NODES],INT node,INT ncorners,INT Vec)463 static void IdentifyNode (GRID *theGrid, ELEMENT *theNeighbor, NODE *theNode,
464                           NODE *Nodes[MAX_SIDE_NODES], INT node, INT ncorners, INT Vec)
465 {
466   auto& context = theGrid->dddContext();
467 
468   INT nobject,nident;
469   DDD_HDR IdentObjectHdr[MAX_OBJECT];
470   DDD_HDR IdentHdr[MAX_TOKEN];
471 
472   nobject = nident = 0;
473 
474   /* is this node identified? */
475         #ifdef Debug
476   if (debug == 1) {
477     if (NIDENT(theNode) == CLEAR) return;
478   }
479   else
480         #endif
481 
482   /* return if not needed any more */
483   if (!USED(theNode)) return;
484 
485   /* return if already identified */
486   if (NIDENT(theNode) == IDENT) return;
487 
488   /* only new created nodes are identified */
489   if (!NEW_NIDENT(theNode)) return;
490 
491   if (Vec)
492     if (GetVectorSize(theGrid,NODEVEC,(GEOM_OBJECT *)theNode) == 0)
493       Vec = 0;
494 
495   switch (NTYPE(theNode))
496   {
497     int *proclist;
498 
499   case (CORNER_NODE) :
500 
501     /* identification of cornernodes is done */
502     /* in Identify_SonNodes()     */
503     return;
504 
505     PRINTDEBUG(dddif,1,("%d: Identify CORNERNODE gid=%08x node=%d "
506                         "vec=%d\n",
507                         me, DDD_InfoGlobalId(PARHDR(theNode)), node, Vec));
508 
509     IdentObjectHdr[nobject++] = PARHDR(theNode);
510     if (Vec)
511       IdentObjectHdr[nobject++] = PARHDR(NVECTOR(theNode));
512 
513     /* identify to proclist of node */
514     proclist = DDD_InfoProcList(context, PARHDR((NODE *)NFATHER(theNode)));
515 
516     /* identify using father node */
517     IdentHdr[nident++] = PARHDR((NODE *)NFATHER(theNode));
518 
519     Ident_FctPtr(context, IdentObjectHdr, nobject,
520                  proclist+2, PrioHGhost, IdentHdr, nident);
521 
522     break;
523 
524   case (MID_NODE) :
525   {
526                         #ifdef __TWODIM__
527     NODE **EdgeNodes;
528     EdgeNodes = Nodes;
529                         #endif
530 
531     EDGE *theEdge;
532                         #ifdef __THREEDIM__
533     NODE *EdgeNodes[MAX_SIDE_NODES];
534 
535     /* identification of cornernodes is done */
536     /* in Identify_SonEdges()     */
537     return;
538 
539     EdgeNodes[0] = Nodes[node-ncorners];
540     EdgeNodes[1] = Nodes[(node-ncorners+1)%ncorners];
541     EdgeNodes[2] = theNode;
542                         #endif
543 
544     ASSERT(EdgeNodes[0]!=NULL);
545     ASSERT(EdgeNodes[1]!=NULL);
546     ASSERT(EdgeNodes[2]!=NULL);
547 
548     PRINTDEBUG(dddif,1,("%d: Identify MIDNODE gid=%08x node=%d Vec=%d\n",
549                         me, DDD_InfoGlobalId(PARHDR(theNode)), node, Vec));
550 
551     /* identify midnode, vertex, vector */
552     IdentObjectHdr[nobject++] = PARHDR(theNode);
553     IdentObjectHdr[nobject++] = PARHDRV(MYVERTEX(theNode));
554     if (Vec)
555       IdentObjectHdr[nobject++] = PARHDR(NVECTOR(theNode));
556 
557                         #ifdef __TWODIM__
558     if (!NEW_NIDENT(theNode)) break;
559                         #endif
560 
561     /* Identify to proclist of edge */
562     theEdge = GetEdge((NODE *)NFATHER(EdgeNodes[0]),
563                       (NODE *)NFATHER(EdgeNodes[1]));
564     ASSERT(theEdge!=NULL);
565 
566     proclist = DDD_InfoProcList(context, PARHDR(theEdge));
567 
568     /* identify using edge nodes */
569     IdentHdr[nident++] = PARHDR((NODE *)NFATHER(EdgeNodes[0]));
570     IdentHdr[nident++] = PARHDR((NODE *)NFATHER(EdgeNodes[1]));
571 
572     /* this is the buggy case
573                             IdentHdr[nident++] = PARHDR(EdgeNodes[0]);
574                             IdentHdr[nident++] = PARHDR(EdgeNodes[1]);
575      */
576 
577     Ident_FctPtr(context, IdentObjectHdr, nobject,
578                  proclist+2, PrioHGhost, IdentHdr, nident);
579 
580     break;
581   }
582 
583                 #ifdef __THREEDIM__
584   case (SIDE_NODE) :
585   {
586     INT i;
587 
588     PRINTDEBUG(dddif,1,("%d: Identify SIDENODE gid=%08x node=%d "
589                         "Vec=%d\n",me,DDD_InfoGlobalId(PARHDR(theNode)),node,Vec));
590 
591     /* identify sidenode, vertex and vector */
592     IdentObjectHdr[nobject++] = PARHDR(theNode);
593     IdentObjectHdr[nobject++] = PARHDRV(MYVERTEX(theNode));
594     if (Vec)
595       IdentObjectHdr[nobject++] = PARHDR(NVECTOR(theNode));
596 
597     /* identify to proclist of neighbor element */
598     proclist = DDD_InfoProcList(context, PARHDRE(theNeighbor));
599 
600     /* identify using corner nodes of side */
601     for (i=0; i<ncorners; i++)
602       IdentHdr[nident++] = PARHDR((NODE *)NFATHER(Nodes[i]));
603 
604     /* identify side node */
605     Ident_FctPtr(context, IdentObjectHdr, nobject,
606                  proclist+2, PrioHGhost, IdentHdr, nident);
607 
608     break;
609   }
610                 #endif
611   default :
612     ASSERT(0);
613     break;
614   }
615 
616         #ifdef Debug
617   if (debug == 1) {
618     SETNIDENT(theNode,CLEAR);
619   }
620   else
621         #endif
622   /* lock this node for identification */
623   SETNIDENT(theNode,IDENT);
624 
625   return;
626 }
627 
628 
629 
630 /****************************************************************************/
631 /*
632    IdentifySideEdge - idenify edge shared only between two neighbor elements
633 
634    SYNOPSIS:
635    static INT IdentifySideEdge (GRID *theGrid, EDGE *theEdge, ELEMENT *theElement, ELEMENT *theNeighbor, INT Vec);
636 
637    PARAMETERS:
638    .  theGrid
639    .  theNeighbor
640    .  theEdge
641    .  Vec
642 
643    DESCRIPTION:
644 
645    RETURN VALUE:
646    INT
647  */
648 /****************************************************************************/
649 
IdentifySideEdge(GRID * theGrid,EDGE * theEdge,ELEMENT * theElement,ELEMENT * theNeighbor,INT Vec)650 static INT IdentifySideEdge (GRID *theGrid, EDGE *theEdge, ELEMENT *theElement, ELEMENT *theNeighbor, INT Vec)
651 {
652   INT nobject,nident;
653   int *proclist;
654   DDD_HDR IdentObjectHdr[MAX_OBJECT];
655   DDD_HDR IdentHdr[MAX_TOKEN];
656   NODE   *theNode0,*theNode1;
657   auto& context = theGrid->dddContext();
658 
659   nobject = nident = 0;
660 
661         #ifdef __TWODIM__
662   /* no identfication to nonrefined neighbors */
663   if (MARK(theNeighbor) == NO_REFINEMENT) return(0);
664         #endif
665 
666         #ifdef __THREEDIM__
667   /* identification of sonedges is done in Identify_SonEdges() */
668   {
669     EDGE *FatherEdge;
670     FatherEdge = GetFatherEdge(theEdge);
671     if (FatherEdge != NULL) return(0);
672   }
673         #endif
674 
675   /* only newly created edges are identified */
676   if (!NEW_EDIDENT(theEdge)) return(0);
677 
678   /* edge unlocked -> no debugging occurs */
679         #ifdef Debug
680   if (debug == 1) {
681     if (EDIDENT(theEdge) == CLEAR) return(0);
682   }
683   else
684         #endif
685 
686   /* edge locked -> already identified */
687   if (EDIDENT(theEdge) == IDENT) return(0);
688 
689         #ifdef __THREEDIM__
690   IdentObjectHdr[nobject++] = PARHDR(theEdge);
691         #endif
692   if (Vec)
693   {
694     if (GetVectorSize(theGrid,EDGEVEC,(GEOM_OBJECT *)theEdge) > 0)
695       if (EDVECTOR(theEdge) != NULL)
696         IdentObjectHdr[nobject++] = PARHDR(EDVECTOR(theEdge));
697   }
698 
699   /* identify to proclist of neighbor */
700   proclist = DDD_InfoProcList(context, PARHDRE(theNeighbor));
701 
702   /* now choose identificator objects */
703   theNode0 = NBNODE(LINK0(theEdge));
704   theNode1 = NBNODE(LINK1(theEdge));
705   ASSERT(!CENTERTYPE(theNode0));
706   ASSERT(!CENTERTYPE(theNode1));
707 
708   if (CORNERTYPE(theNode0))
709   {
710     ASSERT(NFATHER(theNode0)!=NULL);
711     IdentHdr[nident++] = PARHDR((NODE *)NFATHER(theNode0));
712   }
713         #ifdef __THREEDIM__
714   /* since midnodes are identified later in Debug case */
715   /* choose fatheredge here (s.l. 980227)              */
716   else if (MIDTYPE(theNode0))
717   {
718     ASSERT(NFATHER(theNode0)!=NULL);
719     IdentHdr[nident++] = PARHDR((EDGE *)NFATHER(theNode0));
720   }
721         #endif
722   else
723   {
724     /* side node */
725                 #ifdef __THREEDIM__
726     ASSERT(SIDETYPE(theNode0));
727                 #endif
728     IdentHdr[nident++] = PARHDR(theNode0);
729   }
730 
731   if (CORNERTYPE(theNode1))
732   {
733     ASSERT(NFATHER(theNode1)!=NULL);
734     IdentHdr[nident++] = PARHDR((NODE *)NFATHER(theNode1));
735   }
736         #ifdef __THREEDIM__
737   /* since midnodes are identified later in Debug case */
738   /* choose fatheredge here (s.l. 980227)              */
739   else if (MIDTYPE(theNode1))
740   {
741     ASSERT(NFATHER(theNode1)!=NULL);
742     IdentHdr[nident++] = PARHDR((EDGE *)NFATHER(theNode1));
743   }
744         #endif
745   else
746   {
747     /* side node */
748                 #ifdef __THREEDIM__
749     ASSERT(SIDETYPE(theNode1));
750                 #endif
751     IdentHdr[nident++] = PARHDR(theNode1);
752   }
753 
754   if (nobject > 0)
755     Ident_FctPtr(context, IdentObjectHdr, nobject,
756                  proclist+2, PrioHGhost, IdentHdr, nident);
757 
758   /* debugging unlocks the edge */
759         #ifdef Debug
760   if (debug == 1) {
761     SETEDIDENT(theEdge,CLEAR);
762   }
763   else
764         #endif
765   /* lock this edge for identification */
766   SETEDIDENT(theEdge,IDENT);
767 
768   return(0);
769 }
770 
771 /****************************************************************************/
772 /*
773    IdentifyEdge -
774 
775    SYNOPSIS:
776    static INT IdentifyEdge (ELEMENT *theElement, ELEMENT *theNeighbor,
777                         NODE **SideNodes, INT ncorners, ELEMENT *Son, INT SonSide, INT edgeofside, INT Vec);
778 
779    PARAMETERS:
780    .  theElement
781    .  theNeighbor
782    .  SideNodes
783    .  ncorners
784    .  Son
785    .  SonSide
786    .  edgeofside
787    .  Vec
788 
789    DESCRIPTION:
790 
791    RETURN VALUE:
792    INT
793  */
794 /****************************************************************************/
795 
IdentifyEdge(GRID * theGrid,ELEMENT * theElement,ELEMENT * theNeighbor,NODE ** SideNodes,INT ncorners,ELEMENT * Son,INT SonSide,INT edgeofside,INT Vec)796 static INT IdentifyEdge (GRID *theGrid,
797                          ELEMENT *theElement, ELEMENT *theNeighbor,
798                          NODE **SideNodes, INT ncorners, ELEMENT *Son,
799                          INT SonSide, INT edgeofside, INT Vec)
800 {
801   NODE *Nodes[2];
802   EDGE *theEdge;
803   INT nobject,nident;
804         #ifdef __THREEDIM__
805   INT edge,corner0,corner1;
806         #endif
807   int *proclist;
808   DDD_HDR IdentObjectHdr[MAX_OBJECT];
809   DDD_HDR IdentHdr[MAX_TOKEN];
810   auto& context = theGrid->dddContext();
811 
812   nobject = nident = 0;
813 
814         #ifdef __TWODIM__
815   Nodes[0] = CORNER(Son,CORNER_OF_EDGE(Son,SonSide,0));
816   Nodes[1] = CORNER(Son,CORNER_OF_EDGE(Son,SonSide,1));
817         #endif
818 
819         #ifdef __THREEDIM__
820   edge = EDGE_OF_SIDE(Son,SonSide,edgeofside);
821   corner0 = CORNER_OF_EDGE(Son,edge,0);
822   corner1 = CORNER_OF_EDGE(Son,edge,1);
823 
824   Nodes[0] = CORNER(Son,corner0);
825   Nodes[1] = CORNER(Son,corner1);
826   PRINTDEBUG(dddif,5,("%4d: edge=%d corner0=%d corner1=%d Nodes[0]=%d "
827                       "Nodes[1]=%d\n",
828                       me,edge, corner0, corner1, ID(Nodes[0]), ID(Nodes[1])));
829         #endif
830 
831   ASSERT(Nodes[0]!=NULL);
832   ASSERT(Nodes[1]!=NULL);
833 
834   theEdge = GetEdge(Nodes[0],Nodes[1]);
835   ASSERT(theEdge!=NULL);
836 
837         #ifdef __TWODIM__
838   /* no identfication to nonrefined neighbors */
839   if (MARK(theNeighbor) == NO_REFINEMENT) return(0);
840         #endif
841 
842         #ifdef __THREEDIM__
843   /* identification of sonedges is done in Identify_SonEdges() */
844   if (0)
845     if (CORNERTYPE(Nodes[0]) && CORNERTYPE(Nodes[1]))
846     {
847       [[maybe_unused]] EDGE *FatherEdge;
848       FatherEdge = GetEdge((NODE *)NFATHER(Nodes[0]),(NODE *)NFATHER(Nodes[1]));
849       ASSERT(FatherEdge != NULL);
850       return(0);
851       /*
852               if (FatherEdge != NULL) return(0);
853        */
854     }
855   {
856     EDGE *FatherEdge;
857     FatherEdge = GetFatherEdge(theEdge);
858     if (FatherEdge != NULL) return(0);
859   }
860         #endif
861 
862   /* only newly created edges are identified */
863   if (!NEW_EDIDENT(theEdge)) return(0);
864 
865   /* edge unlocked -> no debugging occurs */
866         #ifdef Debug
867   if (debug == 1) {
868     if (EDIDENT(theEdge) == CLEAR) return(0);
869   }
870   else
871         #endif
872 
873   /* edge locked -> already identified */
874   if (EDIDENT(theEdge) == IDENT) return(0);
875 
876   PRINTDEBUG(dddif,1,("%d: Identify EDGE edgeofside=%d pe=%08x/%x eID=%d"
877                       " ntype0=%d  ntype1=%d Vec=%d\n",me,edgeofside,
878                       DDD_InfoGlobalId(PARHDRE(Son)),Son,ID(Son),
879                       NTYPE(Nodes[0]), NTYPE(Nodes[1]), Vec))
880 
881         #ifdef __THREEDIM__
882   IdentObjectHdr[nobject++] = PARHDR(theEdge);
883         #endif
884   if (Vec)
885     if (GetVectorSize(theGrid,EDGEVEC,(GEOM_OBJECT *)theEdge) > 0)
886       if (EDVECTOR(theEdge) != NULL)
887         IdentObjectHdr[nobject++] = PARHDR(EDVECTOR(theEdge));
888 
889         #ifdef __TWODIM__
890   /* identify to proclist of neighbor */
891   proclist = DDD_InfoProcList(context, PARHDRE(theNeighbor));
892         #endif
893 
894   /* identify to proclist of father edge or neighbor*/
895         #ifdef __THREEDIM__
896   if (0)
897   {
898     EDGE *fatherEdge = NULL;
899 
900     /* check whether edge inside the side of the element */
901     fatherEdge = FatherEdge(SideNodes,ncorners,Nodes,theEdge);
902 
903     if (fatherEdge != NULL)
904       proclist = DDD_InfoProcList(context, PARHDR(fatherEdge));
905     else
906       proclist = DDD_InfoProcList(context, PARHDRE(theNeighbor));
907   }
908   proclist = DDD_InfoProcList(context, PARHDRE(theNeighbor));
909         #endif
910 
911   if (CORNERTYPE(Nodes[0]))
912     IdentHdr[nident++] = PARHDR((NODE *)NFATHER(Nodes[0]));
913         #ifdef __THREEDIM__
914   /* since midnodes are identified later in Debug case */
915   /* choose fatheredge here (s.l. 980227)              */
916   else if (MIDTYPE(Nodes[0]))
917     IdentHdr[nident++] = PARHDR((EDGE *)NFATHER(Nodes[0]));
918         #endif
919   else
920     IdentHdr[nident++] = PARHDR(Nodes[0]);
921 
922   if (CORNERTYPE(Nodes[1]))
923     IdentHdr[nident++] = PARHDR((NODE *)NFATHER(Nodes[1]));
924         #ifdef __THREEDIM__
925   /* since midnodes are identified later in Debug case */
926   /* choose fatheredge here (s.l. 980227)              */
927   else if (MIDTYPE(Nodes[1]))
928     IdentHdr[nident++] = PARHDR((EDGE *)NFATHER(Nodes[1]));
929         #endif
930   else
931     IdentHdr[nident++] = PARHDR(Nodes[1]);
932 
933   if (nobject > 0)
934     Ident_FctPtr(context, IdentObjectHdr, nobject,
935                  proclist+2, PrioHGhost, IdentHdr, nident);
936 
937   /* debugging unlocks the edge */
938         #ifdef Debug
939   if (debug == 1) {
940     SETEDIDENT(theEdge,CLEAR);
941   }
942   else
943         #endif
944   /* lock this edge for identification */
945   SETEDIDENT(theEdge,IDENT);
946 
947   return(0);
948 }
949 
950 
951 /****************************************************************************/
952 /*
953    IdentifyObjectsOfElementSide -
954 
955    SYNOPSIS:
956    static INT IdentifyObjectsOfElementSide(GRID *theGrid, ELEMENT *theElement,
957                                                 INT i, ELEMENT *theNeighbor);
958 
959    PARAMETERS:
960    .  theGrid
961    .  theElement
962    .  i
963    .  theNeighbor
964 
965    DESCRIPTION:
966 
967    RETURN VALUE:
968    INT
969  */
970 /****************************************************************************/
971 
IdentifyObjectsOfElementSide(GRID * theGrid,ELEMENT * theElement,INT i,ELEMENT * theNeighbor)972 static INT IdentifyObjectsOfElementSide(GRID *theGrid, ELEMENT *theElement,
973                                         INT i, ELEMENT *theNeighbor)
974 {
975   INT nodes,j,n;
976   NODE *SideNodes[MAX_SIDE_NODES];
977   INT ncorners;
978   NODE *theNode;
979 
980   GetSonSideNodes(theElement,i,&nodes,SideNodes,0);
981   ncorners = CORNERS_OF_SIDE(theElement,i);
982   n = 0;
983 
984   PRINTDEBUG(dddif,1,("%d: IdentifyObjectsOfElementSide():identify NODES "
985                       "ncorners=%d nodes=%d\n",me,ncorners,nodes));
986 
987   /* identify nodes, vertices and node vectors of son elements */
988   for (j=0; j<MAX_SIDE_NODES; j++)
989   {
990     theNode = SideNodes[j];
991     if (theNode == NULL) continue;
992 
993     /* identify new node including its vector and vertex        */
994     IdentifyNode(theGrid,theNeighbor, theNode, SideNodes, j, ncorners,
995                  VEC_DEF_IN_OBJ_OF_GRID(theGrid,NODEVEC));
996     n++;
997   }
998   ASSERT(n == nodes);
999 
1000   /* identify edge vectors (2D); edges, edge and side vectors (3D) */
1001   if (VEC_DEF_IN_OBJ_OF_GRID(theGrid,EDGEVEC) || DIM==3)
1002   {
1003     ELEMENT *SonList[MAX_SONS];
1004     INT SonsOfSide,SonSides[MAX_SONS];
1005     INT j;
1006 
1007     PRINTDEBUG(dddif,1,("%d: IdentifyObjectsOfElementSide(): identify "
1008                         "EDGES and VECTORS\n",me));
1009 
1010     if (Get_Sons_of_ElementSide(theElement,i,&SonsOfSide,
1011                                 SonList,SonSides,1,0)!=GM_OK)
1012       RETURN(GM_FATAL);
1013 
1014     for (j=0; j<SonsOfSide; j++) {
1015 
1016       if (VEC_DEF_IN_OBJ_OF_GRID(theGrid,EDGEVEC) || DIM==3)
1017       {
1018         INT edgeofside;
1019         INT nedges = EDGES_OF_SIDE(SonList[j],SonSides[j]);
1020 
1021         /* identify the edge and vector */
1022         for (edgeofside=0; edgeofside<nedges; edgeofside++) {
1023           EDGE *theEdge;
1024           INT edge = EDGE_OF_SIDE(SonList[j],SonSides[j],edgeofside);
1025 
1026           theEdge = GetEdge(CORNER_OF_EDGE_PTR(SonList[j],edge,0),
1027                             CORNER_OF_EDGE_PTR(SonList[j],edge,1));
1028           ASSERT(theEdge!=NULL);
1029 
1030           IdentifySideEdge(theGrid, theEdge, theElement, theNeighbor,
1031                            VEC_DEF_IN_OBJ_OF_GRID(theGrid,EDGEVEC));
1032         }
1033       }
1034 
1035                         #ifdef __THREEDIM__
1036       if (VEC_DEF_IN_OBJ_OF_GRID(theGrid,SIDEVEC))
1037       {
1038         auto& context = theGrid->dddContext();
1039         IdentifySideVector(context, theElement,theNeighbor,SonList[j],SonSides[j]);
1040       }
1041                         #endif
1042     }
1043   }
1044 
1045   return(GM_OK);
1046 }
1047 
1048 
1049 
1050 /****************************************************************************/
1051 /*
1052    IdentifyDistributedObjects -
1053 
1054    SYNOPSIS:
1055    INT	IdentifyDistributedObjects (MULTIGRID *theMG, INT FromLevel, INT ToLevel);
1056 
1057    PARAMETERS:
1058    .  theMG
1059    .  FromLevel
1060    .  ToLevel
1061 
1062    DESCRIPTION:
1063 
1064    RETURN VALUE:
1065    INT
1066  */
1067 /****************************************************************************/
1068 
IdentifyDistributedObjects(MULTIGRID * theMG,INT FromLevel,INT ToLevel)1069 static INT IdentifyDistributedObjects (MULTIGRID *theMG, INT FromLevel, INT ToLevel)
1070 {
1071   INT l,i,prio;
1072   ELEMENT *theElement,*theNeighbor;
1073   GRID *theGrid;
1074 
1075   PRINTDEBUG(dddif,1,("%d: IdentifyDistributedObjects(): FromLevel=%d "
1076                       "ToLevel=%d\n",me,FromLevel,ToLevel));
1077 
1078   /* identify distributed objects */
1079   for (l=FromLevel; l<ToLevel; l++)
1080   {
1081     PRINTDEBUG(dddif,1,("%d: IdentifyDistributedObjects(): identification "
1082                         "level=%d\n",me,l));
1083 
1084     theGrid = GRID_ON_LEVEL(theMG,l);
1085 
1086                 #ifdef Debug
1087     identlevel = l;
1088                 #endif
1089 
1090     /* check control word flags for ident on upper level */
1091                 #ifdef Debug
1092     if (debug != 1)
1093                 #endif
1094     ResetIdentFlags(GRID_ON_LEVEL(theMG,l+1));
1095 
1096     for (theElement=PFIRSTELEMENT(theGrid); theElement!=NULL;
1097          theElement=SUCCE(theElement))
1098     {
1099       prio = EPRIO(theElement);
1100 
1101       if (!IS_REFINED(theElement) || EGHOSTPRIO(prio)) continue;
1102 
1103       for (i=0; i<SIDES_OF_ELEM(theElement); i++)
1104       {
1105         theNeighbor = NBELEM(theElement,i);
1106         if (theNeighbor == NULL) continue;
1107 
1108         /* TODO: change for full dynamic element distribution */
1109         prio = EPRIO(theNeighbor);
1110         if (!HGHOSTPRIO(prio) || NSONS(theNeighbor)!=0) continue;
1111 
1112         PRINTDEBUG(dddif,1,("%d: Identify element: pe=%08x/%x eID=%d "
1113                             "side=%d\n",me,DDD_InfoGlobalId(PARHDRE(theElement)),
1114                             theElement,ID(theElement),i));
1115 
1116         IdentifyObjectsOfElementSide(theGrid,theElement,i,theNeighbor);
1117 
1118       }
1119     }
1120   }
1121 
1122   return(GM_OK);
1123 }
1124 
1125 
1126 #ifdef IDENT_ONLY_NEW
Gather_NewNodeInfo(DDD::DDDContext &,DDD_OBJ obj,void * data,DDD_PROC proc,DDD_PRIO prio)1127 static int Gather_NewNodeInfo (DDD::DDDContext&, DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio)
1128 {
1129   NODE *theNode = (NODE *)obj;
1130   NODE *SonNode = SONNODE(theNode);
1131 
1132   /* identification is only done between master objects */
1133   ASSERT(identlevel-1 == LEVEL(theNode));
1134 
1135   if (SonNode!=NULL && NEW_NIDENT(SonNode))
1136   {
1137     IFDEBUG(dddif,1)
1138     UserWriteF("new son node=" ID_FMTX  "node=" ID_FMTX "\n",
1139                ID_PRTX(SonNode),ID_PRTX(theNode));
1140     ENDDEBUG
1141     *((int *)data) = 1;
1142   }
1143   else
1144     *((int *)data) = 0;
1145 
1146   return(0);
1147 }
1148 
Scatter_NewNodeInfo(DDD::DDDContext &,DDD_OBJ obj,void * data,DDD_PROC proc,DDD_PRIO prio)1149 static int Scatter_NewNodeInfo (DDD::DDDContext&, DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio)
1150 {
1151   NODE    *theNode        = (NODE *)obj;
1152   NODE    *SonNode        = SONNODE(theNode);
1153   int has_newsonnode  = *((int *)data);
1154 
1155   /* identification is only done between master objects */
1156   ASSERT(identlevel-1 == LEVEL(theNode));
1157 
1158   if (SonNode!=NULL && has_newsonnode) SETNEW_NIDENT(SonNode,1);
1159 
1160   return(0);
1161 }
1162 
1163 /*************************/
1164 
Gather_NodeInfo(DDD::DDDContext &,DDD_OBJ obj,void * data,DDD_PROC proc,DDD_PRIO prio)1165 static int Gather_NodeInfo (DDD::DDDContext&, DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio)
1166 {
1167   NODE *theNode = (NODE *)obj;
1168 
1169   ASSERT(identlevel == LEVEL(theNode));
1170 
1171   if (!(NTYPE(theNode)==check_nodetype))
1172   {
1173     *((int *)data) = 0;
1174     return(0);
1175   }
1176 
1177   *((int *)data) = NEW_NIDENT(theNode);
1178 
1179   return(0);
1180 }
1181 
Scatter_NodeInfo(DDD::DDDContext &,DDD_OBJ obj,void * data,DDD_PROC proc,DDD_PRIO prio)1182 static int Scatter_NodeInfo (DDD::DDDContext&, DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio)
1183 {
1184   NODE    *theNode = (NODE *)obj;
1185   int nprop    = *((int *)data);
1186 
1187   ASSERT(identlevel == LEVEL(theNode));
1188 
1189   if (!(NTYPE(theNode)==check_nodetype)) return(0);
1190 
1191   if (NIDENTASSERT) if (NEW_NIDENT(theNode)) assert(NFATHER(theNode) != NULL);
1192 
1193   if (nprop)
1194   {
1195     if (0) SETNEW_NIDENT(theNode,1);
1196     if (NFATHER(theNode) == NULL)
1197     {
1198       UserWriteF("isolated node=" ID_FMTX "\n",
1199                  ID_PRTX(theNode));
1200       if (NIDENTASSERT) assert(0);
1201     }
1202     if (NIDENTASSERT) assert(NFATHER(theNode) != NULL);
1203   }
1204 
1205   return(0);
1206 }
1207 
1208 /*************************/
1209 
Gather_TestNodeInfo(DDD::DDDContext &,DDD_OBJ obj,void * data,DDD_PROC proc,DDD_PRIO prio)1210 static int Gather_TestNodeInfo (DDD::DDDContext&, DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio)
1211 {
1212   NODE *theNode = (NODE *)obj;
1213 
1214   ASSERT(identlevel == LEVEL(theNode));
1215 
1216   ((int *)data)[0] = NEW_NIDENT(theNode);
1217   if (NEW_NIDENT(theNode)) assert(NFATHER(theNode) != NULL);
1218 
1219   return(0);
1220 }
1221 
Scatter_TestNodeInfo(DDD::DDDContext &,DDD_OBJ obj,void * data,DDD_PROC proc,DDD_PRIO prio)1222 static int Scatter_TestNodeInfo (DDD::DDDContext&, DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio)
1223 {
1224   NODE    *theNode        = (NODE *)obj;
1225   int nprop   = *((int *)data);
1226 
1227   ASSERT(identlevel == LEVEL(theNode));
1228 
1229   if (NEW_NIDENT(theNode) != nprop)
1230   {
1231     UserWriteF("nprop wrong mynprop=%d hisnprop=%d theNode=" ID_FMTX " LEVEL=%d PROC=%d PRIO=%d\n",
1232                NEW_NIDENT(theNode),nprop,ID_PRTX(theNode),LEVEL(theNode),proc,prio);
1233     fflush(stdout);
1234     assert(0);
1235   }
1236 
1237   return(0);
1238 }
1239 
1240 /*************************/
1241 
Gather_IdentSonNode(DDD::DDDContext &,DDD_OBJ obj,void * data,DDD_PROC proc,DDD_PRIO prio)1242 static int Gather_IdentSonNode (DDD::DDDContext&, DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio)
1243 {
1244   NODE *theNode = (NODE *)obj;
1245   NODE *SonNode = SONNODE(theNode);
1246 
1247   /* identification is only done between master objects */
1248   ASSERT(identlevel-1 == LEVEL(theNode));
1249 
1250   ((int *)data)[0] = 0;
1251   ((int *)data)[1] = 0;
1252 
1253   if (SonNode != NULL)
1254   {
1255     ((int *)data)[0] = 1;
1256     ((int *)data)[1] = NEW_NIDENT(SonNode);
1257   }
1258 
1259   return(0);
1260 }
1261 
Scatter_IdentSonNode(DDD::DDDContext & context,DDD_OBJ obj,void * data,DDD_PROC proc,DDD_PRIO prio)1262 static int Scatter_IdentSonNode (DDD::DDDContext& context, DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio)
1263 {
1264   NODE    *theNode        = (NODE *)obj;
1265   NODE    *SonNode        = SONNODE(theNode);
1266   int sonnode         = ((int *)data)[0];
1267   int newsonnode      = ((int *)data)[1];
1268 
1269   /* identification is only done between master objects */
1270   ASSERT(identlevel-1 == LEVEL(theNode));
1271 
1272   if (SonNode!=NULL)
1273   {
1274     /*
1275             if (1 || NEW_NIDENT(SonNode))
1276      */
1277     if (NEW_NIDENT(SonNode))
1278     {
1279       if(sonnode)
1280       {
1281         if (!newsonnode)
1282         {
1283           UserWriteF("theNode=" ID_FMTX " LEVEL=%d PROC=%d PRIO=%d sonnprop=%d\n",
1284                      ID_PRTX(theNode),LEVEL(theNode),proc,prio,NEW_NIDENT(SonNode));
1285           fflush(stdout);
1286           assert(0);
1287         }
1288 
1289         DDD_IdentifyObject(context, PARHDR(SonNode),proc,PARHDR(theNode));
1290         if (ddd_ctrl(context).nodeData && NVECTOR(SonNode)!=NULL)
1291           DDD_IdentifyObject(context, PARHDR(NVECTOR(SonNode)),proc,PARHDR(theNode));
1292       }
1293     }
1294     else
1295     {
1296       if (newsonnode)
1297       {
1298         UserWriteF("theNode=" ID_FMTX " LEVEL=%d PROC=%d PRIO=%d sonnprop=%d\n",
1299                    ID_PRTX(theNode),LEVEL(theNode),proc,prio,NEW_NIDENT(SonNode));
1300         fflush(stdout);
1301         assert(0);
1302       }
1303     }
1304   }
1305 
1306   return(0);
1307 }
1308 
1309 /* callback functions for edge identification */
Gather_NewObjectInfo(DDD::DDDContext &,DDD_OBJ obj,void * data,DDD_PROC proc,DDD_PRIO prio)1310 static int Gather_NewObjectInfo (DDD::DDDContext&, DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio)
1311 {
1312   INT ident_needed;
1313   EDGE *theEdge   = (EDGE *)obj;
1314   EDGE *SonEdges[MAX_SON_EDGES];
1315   NODE *MidNode   = MIDNODE(theEdge);
1316 
1317   /* identification is only done between master objects */
1318   ASSERT(identlevel-1 == LEVEL(theEdge));
1319 
1320   *((int *)data) = 0;
1321 
1322   GetSonEdges(theEdge,SonEdges);
1323 
1324   /* identification is done if one objects of MidNode and the one */
1325   /* or two sonedge have NEW_XXIDENT flags set.                   */
1326   ident_needed = ((MidNode!=NULL && NEW_NIDENT(MidNode)) ||
1327                   (SonEdges[0]!=NULL && NEW_EDIDENT(SonEdges[0])) ||
1328                   (SonEdges[1]!=NULL && NEW_EDIDENT(SonEdges[1])));
1329 
1330   if (ident_needed)
1331   {
1332     /* send number of objects that need identification */
1333     /* must be equal on all procs                      */
1334     if (MidNode!=NULL && NEW_NIDENT(MidNode)) ((int *)data)[0] = 1;
1335     if (SonEdges[0]!=NULL && NEW_EDIDENT(SonEdges[0])) ((int *)data)[0] += 2;
1336     if (SonEdges[1]!=NULL && NEW_EDIDENT(SonEdges[1])) ((int *)data)[0] += 4;
1337   }
1338 
1339   return(0);
1340 }
1341 
Scatter_NewObjectInfo(DDD::DDDContext &,DDD_OBJ obj,void * data,DDD_PROC proc,DDD_PRIO prio)1342 static int Scatter_NewObjectInfo (DDD::DDDContext&, DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio)
1343 {
1344   int newsonobjects   = *((int *)data);
1345   EDGE    *theEdge                = (EDGE *)obj;
1346   EDGE    *SonEdges[MAX_SON_EDGES];
1347   NODE    *MidNode        = MIDNODE(theEdge);
1348 
1349   /* identification is only done between master objects */
1350   ASSERT(identlevel-1 == LEVEL(theEdge));
1351 
1352   GetSonEdges(theEdge,SonEdges);
1353 
1354   if (newsonobjects)
1355   {
1356     if (MidNode == NULL)
1357     {
1358       if (SonEdges[0]!=NULL)
1359         if (newsonobjects & 0x2) SETNEW_EDIDENT(SonEdges[0],1);
1360     }
1361     else
1362     {
1363       if (newsonobjects & 0x1)
1364         SETNEW_NIDENT(MidNode,1);
1365       if (SonEdges[0]!=NULL)
1366         if (newsonobjects & 0x2)
1367           SETNEW_EDIDENT(SonEdges[0],1);
1368       if (SonEdges[1]!=NULL)
1369         if (newsonobjects & 0x4)
1370           SETNEW_EDIDENT(SonEdges[1],1);
1371     }
1372   }
1373 
1374   return(0);
1375 }
1376 
1377 /*************************/
1378 
Gather_EdgeInfo(DDD::DDDContext &,DDD_OBJ obj,void * data,DDD_PROC proc,DDD_PRIO prio)1379 static int Gather_EdgeInfo (DDD::DDDContext&, DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio)
1380 {
1381   EDGE *theEdge = (EDGE *)obj;
1382 
1383   ASSERT(identlevel == LEVEL(theEdge));
1384 
1385   if (GetFatherEdge(theEdge) == NULL)
1386   {
1387     *((int *)data) = 0;
1388     return(0);
1389   }
1390 
1391   *((int *)data) = NEW_EDIDENT(theEdge);
1392 
1393   return(0);
1394 }
1395 
Scatter_EdgeInfo(DDD::DDDContext &,DDD_OBJ obj,void * data,DDD_PROC proc,DDD_PRIO prio)1396 static int Scatter_EdgeInfo (DDD::DDDContext&, DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio)
1397 {
1398   EDGE    *theEdge = (EDGE *)obj;
1399   int nprop    = *((int *)data);
1400   NODE *theNode0 = NBNODE(LINK0(theEdge));
1401   NODE *theNode1 = NBNODE(LINK1(theEdge));
1402 
1403   ASSERT(identlevel == LEVEL(theEdge));
1404 
1405   if (!CORNERTYPE(theNode0) && !CORNERTYPE(theNode1)) return(0);
1406 
1407   if (nprop)
1408   {
1409     if (0) SETNEW_EDIDENT(theEdge,1);
1410     if (GetFatherEdge(theEdge) == NULL)
1411     {
1412       UserWriteF("isolated edge=" ID_FMTX "\n",
1413                  ID_PRTX(theEdge));
1414       if (EDIDENTASSERT) assert(0);
1415     }
1416     if (EDIDENTASSERT) assert(GetFatherEdge(theEdge) != NULL);
1417   }
1418 
1419   return(0);
1420 }
1421 
1422 /*************************/
1423 
Gather_TestEdgeInfo(DDD::DDDContext &,DDD_OBJ obj,void * data,DDD_PROC proc,DDD_PRIO prio)1424 static int Gather_TestEdgeInfo (DDD::DDDContext&, DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio)
1425 {
1426   EDGE *theEdge = (EDGE *)obj;
1427 
1428   ASSERT(identlevel == LEVEL(theEdge));
1429 
1430   ((int *)data)[0] = NEW_EDIDENT(theEdge);
1431   if (NEW_EDIDENT(theEdge)) assert(GetFatherEdge(theEdge) != NULL);
1432 
1433   return(0);
1434 }
1435 
Scatter_TestEdgeInfo(DDD::DDDContext &,DDD_OBJ obj,void * data,DDD_PROC proc,DDD_PRIO prio)1436 static int Scatter_TestEdgeInfo (DDD::DDDContext&, DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio)
1437 {
1438   EDGE    *theEdge        = (EDGE *)obj;
1439   int nprop   = *((int *)data);
1440 
1441   ASSERT(identlevel == LEVEL(theEdge));
1442 
1443   if (NEW_EDIDENT(theEdge) != nprop)
1444   {
1445     UserWriteF("nprop wrong mynprop=%d hisnprop=%d theEdge=" ID_FMTX " LEVEL=%d PROC=%d PRIO=%d\n",
1446                NEW_EDIDENT(theEdge),nprop,ID_PRTX(theEdge),LEVEL(theEdge),proc,prio);
1447     fflush(stdout);
1448     assert(0);
1449   }
1450 
1451   return(0);
1452 }
1453 
1454 /*************************/
1455 
Gather_IdentSonEdge(DDD::DDDContext &,DDD_OBJ obj,void * data,DDD_PROC proc,DDD_PRIO prio)1456 static int Gather_IdentSonEdge (DDD::DDDContext&, DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio)
1457 {
1458   EDGE *theEdge = (EDGE *)obj;
1459   EDGE *SonEdge = GetSonEdge(theEdge);
1460 
1461   /* identification is only done between master objects */
1462   ASSERT(identlevel-1 == LEVEL(theEdge));
1463 
1464   ((int *)data)[0] = 0;
1465   ((int *)data)[1] = 0;
1466 
1467   if (SonEdge != NULL)
1468   {
1469     ((int *)data)[0] = 1;
1470     ((int *)data)[1] = NEW_EDIDENT(SonEdge);
1471   }
1472 
1473   return(0);
1474 }
1475 
Scatter_IdentSonEdge(DDD::DDDContext & context,DDD_OBJ obj,void * data,DDD_PROC proc,DDD_PRIO prio)1476 static int Scatter_IdentSonEdge (DDD::DDDContext& context, DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio)
1477 {
1478   EDGE    *theEdge        = (EDGE *)obj;
1479   EDGE    *SonEdge;
1480   int sonedge         = ((int *)data)[0];
1481   int newsonedge      = ((int *)data)[1];
1482 
1483   /* identification is only done between master objects */
1484   ASSERT(identlevel-1 == LEVEL(theEdge));
1485 
1486   if (SonEdge!=NULL)
1487   {
1488     /*
1489             if (1 || NEW_EDIDENT(SonEdge))
1490      */
1491     if (NEW_EDIDENT(SonEdge))
1492     {
1493       if(sonedge)
1494       {
1495         if (!newsonedge)
1496         {
1497           UserWriteF("theEdge=" ID_FMTX " LEVEL=%d PROC=%d PRIO=%d sonnprop=%d\n",
1498                      ID_PRTX(theEdge),LEVEL(theEdge),proc,prio,NEW_EDIDENT(SonEdge));
1499           fflush(stdout);
1500           assert(0);
1501         }
1502 
1503         DDD_IdentifyObject(context, PARHDR(SonEdge),proc,PARHDR(theEdge));
1504         if (ddd_ctrl(context).edgeData && EDVECTOR(SonEdge)!=NULL)
1505           DDD_IdentifyObject(context, PARHDR(EDVECTOR(SonEdge)),proc,PARHDR(theEdge));
1506       }
1507     }
1508     else
1509     {
1510       if (newsonedge)
1511       {
1512         UserWriteF("theEdge=" ID_FMTX " LEVEL=%d PROC=%d PRIO=%d sonnprop=%d\n",
1513                    ID_PRTX(theEdge),LEVEL(theEdge),proc,prio,NEW_EDIDENT(SonEdge));
1514         fflush(stdout);
1515         assert(0);
1516       }
1517     }
1518   }
1519 
1520   return(0);
1521 }
1522 
1523 /*************************/
1524 
Gather_IdentSonObjects(DDD::DDDContext &,DDD_OBJ obj,void * data,DDD_PROC proc,DDD_PRIO prio)1525 static int Gather_IdentSonObjects (DDD::DDDContext&, DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio)
1526 {
1527   INT ident_needed;
1528   EDGE *theEdge   = (EDGE *)obj;
1529   EDGE *SonEdges[2];
1530   NODE *MidNode   = MIDNODE(theEdge);
1531 
1532   /* identification is only done between master objects */
1533   ASSERT(identlevel-1 == LEVEL(theEdge));
1534 
1535   ((int *)data)[0] = 0;
1536 
1537   GetSonEdges(theEdge, SonEdges);
1538 
1539   /* identification is done if one objects of MidNode and the one */
1540   /* or two sonedge have NEW_XXIDENT flags set.                   */
1541   ident_needed = ((MidNode!=NULL && NEW_NIDENT(MidNode)) ||
1542                   (SonEdges[0]!=NULL && NEW_EDIDENT(SonEdges[0])) ||
1543                   (SonEdges[1]!=NULL && NEW_EDIDENT(SonEdges[1])));
1544 
1545   if (ident_needed)
1546   {
1547     /* send number of objects that need identification */
1548     /* must be equal on all procs                      */
1549     if (MidNode!=NULL && NEW_NIDENT(MidNode)) ((int *)data)[0] = 1;
1550     if (SonEdges[0]!=NULL && NEW_EDIDENT(SonEdges[0])) ((int *)data)[0] += 2;
1551     if (SonEdges[1]!=NULL && NEW_EDIDENT(SonEdges[1])) ((int *)data)[0] += 4;
1552   }
1553 
1554   return(0);
1555 }
1556 
Scatter_IdentSonObjects(DDD::DDDContext & context,DDD_OBJ obj,void * data,DDD_PROC proc,DDD_PRIO prio)1557 static int Scatter_IdentSonObjects (DDD::DDDContext& context, DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio)
1558 {
1559   int newsonobjects   = *((int *)data);
1560   EDGE    *theEdge                = (EDGE *)obj;
1561   EDGE    *SonEdges[2];
1562   NODE    *MidNode        = MIDNODE(theEdge);
1563   NODE    *SonNode0,*SonNode1,*IdentNode;
1564   NODE    *Node0,*Node1;
1565 
1566   /* identification is only done between master objects */
1567   ASSERT(identlevel-1 == LEVEL(theEdge));
1568 
1569   [[maybe_unused]] INT nedges = GetSonEdges(theEdge,SonEdges);
1570 
1571   if (newsonobjects)
1572   {
1573     if (0)
1574       ASSERT((MidNode==NULL && nedges!=2)  ||
1575              (MidNode!=NULL && nedges==2));
1576 
1577     if (MidNode==NULL)
1578     {
1579       if (SonEdges[0]!=NULL &&  NEW_EDIDENT(SonEdges[0]))
1580       {
1581         ASSERT(newsonobjects & 0x2);
1582 
1583         DDD_IdentifyObject(context, PARHDR(SonEdges[0]),proc,PARHDR(theEdge));
1584         if (ddd_ctrl(context).edgeData && EDVECTOR(SonEdges[0])!=NULL)
1585           DDD_IdentifyObject(context, PARHDR(EDVECTOR(SonEdges[0])),proc,PARHDR(theEdge));
1586       }
1587     }
1588     else
1589     {
1590 
1591       /* identify midnode */
1592       if (MidNode!=NULL && NEW_NIDENT(MidNode))
1593       {
1594         ASSERT(newsonobjects & 0x1);
1595         if (0) {
1596           ASSERT(MidNode!=NULL && SonEdges[0]!=NULL && SonEdges[1]!=NULL);
1597           ASSERT(nedges==2);
1598         }
1599 
1600         if (1)
1601         {
1602           DDD_IdentifyObject(context, PARHDR(MidNode),proc,PARHDR(theEdge));
1603           DDD_IdentifyObject(context, PARHDRV(MYVERTEX(MidNode)),proc,PARHDR(theEdge));
1604           if (ddd_ctrl(context).nodeData && NVECTOR(MidNode)!=NULL)
1605             DDD_IdentifyObject(context, PARHDR(NVECTOR(MidNode)),proc,PARHDR(theEdge));
1606         }
1607         else
1608         {
1609           Node0 = NBNODE(LINK0(theEdge));
1610           Node1 = NBNODE(LINK1(theEdge));
1611           DDD_IdentifyObject(context, PARHDR(MidNode),proc,PARHDR(Node0));
1612           DDD_IdentifyObject(context, PARHDR(MidNode),proc,PARHDR(Node1));
1613           DDD_IdentifyObject(context, PARHDRV(MYVERTEX(MidNode)),proc,PARHDR(Node0));
1614           DDD_IdentifyObject(context, PARHDRV(MYVERTEX(MidNode)),proc,PARHDR(Node1));
1615           if (ddd_ctrl(context).nodeData && NVECTOR(MidNode)!=NULL)
1616           {
1617             DDD_IdentifyObject(context, PARHDR(NVECTOR(MidNode)),proc,PARHDR(Node0));
1618             DDD_IdentifyObject(context, PARHDR(NVECTOR(MidNode)),proc,PARHDR(Node1));
1619           }
1620         }
1621       }
1622 
1623       if (SonEdges[0]!=NULL &&  NEW_EDIDENT(SonEdges[0]) && (newsonobjects & 0x2))
1624       {
1625         if (0) {
1626           ASSERT(MidNode!=NULL && SonEdges[0]!=NULL && SonEdges[1]!=NULL);
1627           ASSERT(nedges==2);
1628         }
1629         /* identify edge0 */
1630         SonNode0 = NBNODE(LINK0(SonEdges[0]));
1631         SonNode1 = NBNODE(LINK1(SonEdges[0]));
1632         if (CORNERTYPE(SonNode0))
1633         {
1634           ASSERT(NFATHER(SonNode0)!=NULL);
1635           IdentNode = SonNode0;
1636         }
1637         else
1638         {
1639           ASSERT(CORNERTYPE(SonNode1));
1640           ASSERT(NFATHER(SonNode1)!=NULL);
1641           IdentNode = SonNode1;
1642         }
1643         DDD_IdentifyObject(context, PARHDR(SonEdges[0]),proc,PARHDR(theEdge));
1644         DDD_IdentifyObject(context, PARHDR(SonEdges[0]),proc,PARHDR((NODE *)NFATHER(IdentNode)));
1645         if (ddd_ctrl(context).edgeData && EDVECTOR(SonEdges[0])!=NULL)
1646         {
1647           DDD_IdentifyObject(context, PARHDR(EDVECTOR(SonEdges[0])),proc,PARHDR(theEdge));
1648           DDD_IdentifyObject(context, PARHDR(EDVECTOR(SonEdges[0])),proc,PARHDR((NODE *)NFATHER(IdentNode)));
1649         }
1650       }
1651 
1652       if (SonEdges[1]!=NULL &&  NEW_EDIDENT(SonEdges[1]) && (newsonobjects & 0x4))
1653       {
1654         if (0) {
1655           ASSERT(MidNode!=NULL && SonEdges[0]!=NULL && SonEdges[1]!=NULL);
1656           ASSERT(nedges==2);
1657         }
1658         /* identify edge1 */
1659         SonNode0 = NBNODE(LINK0(SonEdges[1]));
1660         SonNode1 = NBNODE(LINK1(SonEdges[1]));
1661         if (CORNERTYPE(SonNode0))
1662         {
1663           ASSERT(NFATHER(SonNode0)!=NULL);
1664           IdentNode = SonNode0;
1665         }
1666         else
1667         {
1668           ASSERT(CORNERTYPE(SonNode1));
1669           ASSERT(NFATHER(SonNode1)!=NULL);
1670           IdentNode = SonNode1;
1671         }
1672         DDD_IdentifyObject(context, PARHDR(SonEdges[1]),proc,PARHDR(theEdge));
1673         DDD_IdentifyObject(context, PARHDR(SonEdges[1]),proc,PARHDR((NODE *)NFATHER(IdentNode)));
1674         if (ddd_ctrl(context).edgeData && EDVECTOR(SonEdges[1])!=NULL)
1675         {
1676           DDD_IdentifyObject(context, PARHDR(EDVECTOR(SonEdges[1])),proc,PARHDR(theEdge));
1677           DDD_IdentifyObject(context, PARHDR(EDVECTOR(SonEdges[1])),proc,PARHDR((NODE *)NFATHER(IdentNode)));
1678         }
1679       }
1680     }
1681   }
1682 
1683   return(0);
1684 }
1685 
1686 #endif
1687 
1688 
1689 
1690 #ifndef IDENT_ONLY_NEW
1691 
1692 /****************************************************************************/
1693 /*
1694    Gather_SonNodeInfo -
1695 
1696    SYNOPSIS:
1697    static int Gather_SonNodeInfo (DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio);
1698 
1699    PARAMETERS:
1700    .  obj
1701    .  data
1702    .  proc
1703    .  prio
1704 
1705    DESCRIPTION:
1706 
1707    RETURN VALUE:
1708    int
1709  */
1710 /****************************************************************************/
1711 
Gather_SonNodeInfo(DDD::DDDContext &,DDD_OBJ obj,void * data,DDD_PROC proc,DDD_PRIO prio)1712 static int Gather_SonNodeInfo (DDD::DDDContext&, DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio)
1713 {
1714   NODE *theNode = (NODE *)obj;
1715 
1716   /* identification is only done between master objects */
1717   ASSERT(identlevel-1 == LEVEL(theNode));
1718 
1719   if (SONNODE(theNode) != NULL)
1720     *((int *)data) = 1;
1721   else
1722     *((int *)data) = 0;
1723 
1724   return(0);
1725 }
1726 
1727 /****************************************************************************/
1728 /*
1729    Scatter_SonNodeInfo -
1730 
1731    SYNOPSIS:
1732    static int Scatter_SonNodeInfo (DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio);
1733 
1734    PARAMETERS:
1735    .  obj
1736    .  data
1737    .  proc
1738    .  prio
1739 
1740    DESCRIPTION:
1741 
1742    RETURN VALUE:
1743    int
1744  */
1745 /****************************************************************************/
1746 
Scatter_SonNodeInfo(DDD::DDDContext & context,DDD_OBJ obj,void * data,DDD_PROC proc,DDD_PRIO prio)1747 static int Scatter_SonNodeInfo (DDD::DDDContext& context, DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio)
1748 {
1749   NODE    *theNode        = (NODE *)obj;
1750   NODE    *SonNode        = SONNODE(theNode);
1751   INT has_sonnode     = *((int *)data);
1752 
1753   /* identification is only done between master objects */
1754   ASSERT(identlevel-1 == LEVEL(theNode));
1755 
1756   if (SonNode != NULL)
1757   {
1758     if (has_sonnode)
1759     {
1760       DDD_IdentifyObject(context, PARHDR(SonNode),proc,PARHDR(theNode));
1761       if (ddd_ctrl(context).nodeData && NVECTOR(SonNode)!=NULL)
1762         DDD_IdentifyObject(context, PARHDR(NVECTOR(SonNode)),proc,PARHDR(theNode));
1763       IFDEBUG(dddif,1)
1764       if (ddd_ctrl(context).nodeData && NVECTOR(SonNode)!=NULL)
1765         PrintDebug ("l=%d IdentHdr: %d Proc: %d me:%d IdentObjectHdr: %d %d\n",
1766                     identlevel,GID(theNode),proc,me,GID(SonNode),GID(EDVECTOR(SonNode)));
1767       else
1768         PrintDebug ("l=%d IdentHdr: %d Proc: %d me:%d IdentObjectHdr: %d\n",
1769                     identlevel,GID(theNode),proc,me,GID(SonNode));
1770       ENDDEBUG
1771     }
1772   }
1773 
1774   return(0);
1775 }
1776 
1777 
1778 #ifdef __THREEDIM__
1779 
1780 /****************************************************************************/
1781 /*
1782    Gather_SonEdgeInfo  -
1783 
1784    SYNOPSIS:
1785    static int Gather_SonEdgeInfo (DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio);
1786 
1787    PARAMETERS:
1788    .  obj
1789    .  data
1790    .  proc
1791    .  prio
1792 
1793    DESCRIPTION:
1794 
1795    RETURN VALUE:
1796    int
1797  */
1798 /****************************************************************************/
1799 
Gather_SonEdgeInfo(DDD::DDDContext &,DDD_OBJ obj,void * data,DDD_PROC proc,DDD_PRIO prio)1800 static int Gather_SonEdgeInfo (DDD::DDDContext&, DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio)
1801 {
1802   EDGE *theEdge = (EDGE *)obj;
1803   EDGE *SonEdge;
1804 
1805   /* identification has to be done between all copies of an objects */
1806   /* otherwise this can result in unsymmetric interfaces            */
1807   ASSERT(identlevel-1 == LEVEL(theEdge));
1808 
1809   SonEdge = GetSonEdge(theEdge);
1810   if (SonEdge != NULL)
1811     *((int *)data) = 1;
1812   else
1813     *((int *)data) = 0;
1814 
1815   return(0);
1816 }
1817 
1818 
1819 /****************************************************************************/
1820 /*
1821    Scatter_SonEdgeInfo -
1822 
1823    SYNOPSIS:
1824    static int Scatter_SonEdgeInfo (DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio);
1825 
1826    PARAMETERS:
1827    .  obj
1828    .  data
1829    .  proc
1830    .  prio
1831 
1832    DESCRIPTION:
1833 
1834    RETURN VALUE:
1835    int
1836  */
1837 /****************************************************************************/
1838 
Scatter_SonEdgeInfo(DDD::DDDContext & context,DDD_OBJ obj,void * data,DDD_PROC proc,DDD_PRIO prio)1839 static int Scatter_SonEdgeInfo (DDD::DDDContext& context, DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio)
1840 {
1841   EDGE    *theEdge        = (EDGE *)obj;
1842   EDGE    *SonEdge;
1843   INT has_sonedge     = *((int *)data);
1844 
1845   /* identification has to be done between all copies of an objects */
1846   /* otherwise this can result in unsymmetric interfaces            */
1847   ASSERT(identlevel-1 == LEVEL(theEdge));
1848 
1849   SonEdge = GetSonEdge(theEdge);
1850   if (SonEdge != NULL)
1851   {
1852     if (has_sonedge)
1853     {
1854       DDD_IdentifyObject(context, PARHDR(SonEdge),proc,PARHDR(theEdge));
1855       if (ddd_ctrl(context).edgeData && EDVECTOR(SonEdge)!=NULL)
1856         DDD_IdentifyObject(context, PARHDR(EDVECTOR(SonEdge)),proc,PARHDR(theEdge));
1857       IFDEBUG(dddif,1)
1858       if (ddd_ctrl(context).edgeData && EDVECTOR(SonEdge)!=NULL)
1859         PrintDebug ("l=%d IdentHdr: %d Proc: %d me:%d IdentObjectHdr: %d %d\n",
1860                     identlevel,GID(theEdge),proc,me,GID(SonEdge),GID(EDVECTOR(SonEdge)));
1861       else
1862         PrintDebug ("l=%d IdentHdr: %d Proc: %d me:%d IdentObjectHdr: %d\n",
1863                     identlevel,GID(theEdge),proc,me,GID(SonEdge));
1864       ENDDEBUG
1865     }
1866   }
1867 
1868   return(0);
1869 }
1870 #endif
1871 #endif
1872 
1873 /****************************************************************************/
1874 /*
1875    Identify_SonNodes - identify son nodes (type CORNERNODE)
1876 
1877    SYNOPSIS:
1878    INT Identify_SonNodes (GRID *theGrid);
1879 
1880    PARAMETERS:
1881    .  theGrid
1882 
1883    DESCRIPTION:
1884 
1885    RETURN VALUE:
1886    INT
1887  */
1888 /****************************************************************************/
1889 
Identify_SonNodes(GRID * theGrid)1890 static INT Identify_SonNodes (GRID *theGrid)
1891 {
1892   auto& context = theGrid->dddContext();
1893   const auto& dddctrl = ddd_ctrl(context);
1894 
1895 #ifdef IDENT_ONLY_NEW
1896   DDD_IFAOnewayX(context,
1897                  dddctrl.NodeAllIF,GRID_ATTR(theGrid),IF_FORWARD,sizeof(int),
1898                  Gather_NewNodeInfo,Scatter_NewNodeInfo);
1899 
1900   if (UPGRID(theGrid) != NULL)
1901   {
1902     check_nodetype = CORNER_NODE;
1903     if (NIDENTASSERT)
1904       DDD_IFAOnewayX(context,
1905                      dddctrl.NodeAllIF,GRID_ATTR(UPGRID(theGrid)),IF_FORWARD,sizeof(int),
1906                      Gather_NodeInfo,Scatter_NodeInfo);
1907     if (0)
1908       DDD_IFAOnewayX(context,
1909                      dddctrl.NodeAllIF,GRID_ATTR(UPGRID(theGrid)),IF_FORWARD,sizeof(int),
1910                      Gather_TestNodeInfo,Scatter_TestNodeInfo);
1911   }
1912 
1913   DDD_IFAOnewayX(context,
1914                  dddctrl.NodeAllIF,GRID_ATTR(theGrid),IF_FORWARD,2*sizeof(int),
1915                  Gather_IdentSonNode,Scatter_IdentSonNode);
1916 
1917 #else
1918 
1919   DDD_IFAOnewayX(context,
1920                  dddctrl.NodeAllIF,GRID_ATTR(theGrid),IF_FORWARD,sizeof(int),
1921                  Gather_SonNodeInfo,Scatter_SonNodeInfo);
1922 
1923 #endif
1924   return(GM_OK);
1925 }
1926 
1927 
1928 /****************************************************************************/
1929 /*
1930    Identify_SonEdges - identify son edges
1931 
1932    SYNOPSIS:
1933    INT Identify_SonEdges (GRID *theGrid);
1934 
1935    PARAMETERS:
1936    .  theGrid
1937 
1938    DESCRIPTION:
1939 
1940    RETURN VALUE:
1941    INT
1942  */
1943 /****************************************************************************/
1944 
Identify_SonEdges(GRID * theGrid)1945 INT Identify_SonEdges (GRID *theGrid)
1946 {
1947   auto& context = theGrid->dddContext();
1948   const auto& dddctrl = ddd_ctrl(context);
1949 
1950 #ifdef IDENT_ONLY_NEW
1951 
1952   DDD_IFAOnewayX(context,
1953                  dddctrl.EdgeSymmVHIF,GRID_ATTR(theGrid),IF_FORWARD,sizeof(int),
1954                  Gather_NewObjectInfo,Scatter_NewObjectInfo);
1955 
1956   if (UPGRID(theGrid) != NULL)
1957   {
1958     check_nodetype = MID_NODE;
1959     DDD_IFAOnewayX(context,
1960                    dddctrl.NodeAllIF,GRID_ATTR(UPGRID(theGrid)),IF_FORWARD,sizeof(int),
1961                    Gather_NodeInfo,Scatter_NodeInfo);
1962     if (EDIDENTASSERT)
1963       DDD_IFAOnewayX(context,
1964                      dddctrl.EdgeSymmVHIF,GRID_ATTR(UPGRID(theGrid)),IF_FORWARD,sizeof(int),
1965                      Gather_EdgeInfo,Scatter_EdgeInfo);
1966     if (0)
1967       DDD_IFAOnewayX(context,
1968                      dddctrl.EdgeSymmVHIF,GRID_ATTR(UPGRID(theGrid)),IF_FORWARD,sizeof(int),
1969                      Gather_TestEdgeInfo,Scatter_TestEdgeInfo);
1970   }
1971 
1972   DDD_IFAOnewayX(context,
1973                  dddctrl.EdgeSymmVHIF,GRID_ATTR(theGrid),IF_FORWARD,sizeof(int),
1974                  Gather_IdentSonObjects,Scatter_IdentSonObjects);
1975 
1976 #else
1977 
1978   /* identify the sonedges */
1979   DDD_IFAOnewayX(context,
1980                  dddctrl.EdgeSymmVHIF,GRID_ATTR(theGrid),IF_FORWARD,sizeof(int),
1981                  Gather_SonEdgeInfo,Scatter_SonEdgeInfo);
1982 
1983 #endif
1984 
1985   return(GM_OK);
1986 }
1987 
1988 
1989 /****************************************************************************/
1990 /*
1991    Identify_SonObjects - identify son objects
1992 
1993    SYNOPSIS:
1994    INT Identify_SonObjects (GRID *theGrid);
1995 
1996    PARAMETERS:
1997    .  theGrid
1998 
1999    DESCRIPTION:
2000    This function identifies all objects which are not symmetrically created
2001    during grid adaption. These are edges and nodes of the type used by
2002    yellow elements, son nodes of type CORNERNODE and son edges.
2003 
2004    RETURN VALUE:
2005    INT
2006  */
2007 /****************************************************************************/
2008 
2009 #define NODESFIRST 1
2010 
Identify_SonObjects(GRID * theGrid)2011 INT NS_DIM_PREFIX Identify_SonObjects (GRID *theGrid)
2012 {
2013     #ifdef Debug
2014   identlevel = GLEVEL(theGrid)+1;
2015         #endif
2016 
2017   if (NODESFIRST)
2018   {
2019     if (Identify_SonNodes (theGrid) != GM_OK) RETURN(GM_ERROR);
2020   }
2021   else
2022   {
2023     if (Identify_SonEdges (theGrid) != GM_OK) RETURN(GM_ERROR);
2024   }
2025 
2026   if (IDENT_IN_STEPS)
2027   {
2028     DDD_IdentifyEnd(theGrid->dddContext());
2029     DDD_IdentifyBegin(theGrid->dddContext());
2030   }
2031 
2032 
2033   if (!NODESFIRST)
2034   {
2035     if (Identify_SonNodes (theGrid) != GM_OK) RETURN(GM_ERROR);
2036   }
2037   else
2038   {
2039     if (Identify_SonEdges (theGrid) != GM_OK) RETURN(GM_ERROR);
2040   }
2041 
2042   return (GM_OK);
2043 }
2044 
2045 /****************************************************************************/
2046 /*
2047    Identify_Objects_of_ElementSide -
2048 
2049    SYNOPSIS:
2050    INT Identify_Objects_of_ElementSide(GRID *theGrid, ELEMENT *theElement, INT i);
2051 
2052    PARAMETERS:
2053    .  theGrid
2054    .  theElement
2055    .  i
2056 
2057    DESCRIPTION:
2058 
2059    RETURN VALUE:
2060    INT
2061  */
2062 /****************************************************************************/
2063 
Identify_Objects_of_ElementSide(GRID * theGrid,ELEMENT * theElement,INT i)2064 INT NS_DIM_PREFIX Identify_Objects_of_ElementSide(GRID *theGrid, ELEMENT *theElement, INT i)
2065 {
2066   INT prio;
2067   ELEMENT *theNeighbor;
2068 
2069   theNeighbor = NBELEM(theElement,i);
2070   if (theNeighbor == NULL) return(GM_OK);
2071 
2072   prio = EPRIO(theNeighbor);
2073   /* identification is only needed if theNeighbor removed his refinement  */
2074   /* or was not refined before, thus has NSONS==0, if NSONS>0 the objects */
2075   /* shared between the element sides are already identified and no new   */
2076   /* objects are created for this element side which need identification  */
2077   /* (980217 s.l.)                                                        */
2078   /*
2079           if (!EHGHOSTPRIO(prio) || NSONS(theNeighbor)!=0) return(GM_OK);
2080    */
2081   if (!EHGHOSTPRIO(prio) || !MARKED(theNeighbor)) return(GM_OK);
2082 
2083         #ifdef Debug
2084   identlevel = GLEVEL(theGrid);
2085         #endif
2086   if (IdentifyObjectsOfElementSide(theGrid,theElement,i,theNeighbor)) RETURN(GM_FATAL);
2087 
2088   return(GM_OK);
2089 }
2090 
2091 
2092 /****************************************************************************/
2093 /*
2094     IdentifyInit-
2095 
2096    SYNOPSIS:
2097    void IdentifyInit (MULTIGRID *theMG);
2098 
2099    PARAMETERS:
2100    .  theMG
2101 
2102    DESCRIPTION:
2103 
2104    RETURN VALUE:
2105    void
2106  */
2107 /****************************************************************************/
2108 
IdentifyInit(MULTIGRID * theMG)2109 void NS_DIM_PREFIX IdentifyInit (MULTIGRID *theMG)
2110 {
2111   INT i;
2112 
2113         #ifdef Debug
2114   debug = 0;
2115         #endif
2116 
2117   /* allocate a control word entry to lock nodes */
2118   if (AllocateControlEntry(NODE_CW,NEW_NIDENT_LEN,&ce_NEW_NIDENT) != GM_OK)
2119     assert(0);
2120 
2121   /* allocate a control word entry to lock edges */
2122   if (AllocateControlEntry(EDGE_CW,NEW_EDIDENT_LEN,&ce_NEW_EDIDENT) != GM_OK)
2123     assert(0);
2124 
2125   for (i=0; i<=TOPLEVEL(theMG); i++)
2126     ResetIdentFlags(GRID_ON_LEVEL(theMG,i));
2127 
2128   /* set Ident_FctPtr to identification mode */
2129   Ident_FctPtr = Identify_by_ObjectList;
2130 
2131 }
2132 
2133 
2134 /****************************************************************************/
2135 /*
2136    IdentifyExit -
2137 
2138    SYNOPSIS:
2139    void IdentifyExit (void);
2140 
2141    PARAMETERS:
2142    .  void
2143 
2144    DESCRIPTION:
2145 
2146    RETURN VALUE:
2147    void
2148  */
2149 /****************************************************************************/
2150 
IdentifyExit(void)2151 void NS_DIM_PREFIX IdentifyExit (void)
2152 {
2153   FreeControlEntry(ce_NEW_NIDENT);
2154   FreeControlEntry(ce_NEW_EDIDENT);
2155 }
2156 
2157 #endif /* end ModelP */
2158