/[escript]/branches/refine/buckley/src/LeafInfo.cc
ViewVC logotype

Contents of /branches/refine/buckley/src/LeafInfo.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3668 - (show annotations)
Wed Nov 16 01:49:46 2011 UTC (7 years, 10 months ago) by jfenwick
File size: 5084 byte(s)
Stage 1 rename
1 #include <cstring> // for memset
2 #include <cmath>
3 #include <iostream>
4 #include "LeafInfo.h"
5
6
7 #include "FaceConsts.h"
8
9 using namespace buckley;
10 using namespace std;
11
12
13
14
15 LeafInfo::LeafInfo(buckley::OctCell* c)
16 {
17 owner=c;
18 memset(next, 0, sizeof(OctCell*)*6);
19 memset(pmap, 0, sizeof(unkid)*8);
20 }
21
22
23 // The assumption here is that a LeafInfo will always be managed by an OctCell which will deal with any rolling deletes
24
25 LeafInfo::~LeafInfo()
26 {
27 }
28
29
30
31 // The owner of this leafinfo has been split into the cells given in the kids array
32 // Patch all the relevant pointers.
33 // kids are created as: 3 2 7 6
34 // 0 1 4 5
35 void LeafInfo::split(OctCell* kids[8])
36 {
37 // now we form the intra split links
38 kids[0]->leafinfo->next[0]=kids[1]->leafinfo;
39 kids[0]->leafinfo->next[2]=kids[3]->leafinfo;
40 kids[0]->leafinfo->next[4]=kids[4]->leafinfo;
41
42 kids[4]->leafinfo->next[0]=kids[5]->leafinfo;
43 kids[4]->leafinfo->next[2]=kids[7]->leafinfo;
44 kids[4]->leafinfo->next[5]=kids[0]->leafinfo;
45
46 kids[1]->leafinfo->next[1]=kids[0]->leafinfo;
47 kids[1]->leafinfo->next[2]=kids[2]->leafinfo;
48 kids[1]->leafinfo->next[4]=kids[5]->leafinfo;
49
50 kids[5]->leafinfo->next[1]=kids[4]->leafinfo;
51 kids[5]->leafinfo->next[2]=kids[6]->leafinfo;
52 kids[5]->leafinfo->next[5]=kids[1]->leafinfo;
53
54 kids[2]->leafinfo->next[1]=kids[3]->leafinfo;
55 kids[2]->leafinfo->next[3]=kids[1]->leafinfo;
56 kids[2]->leafinfo->next[4]=kids[6]->leafinfo;
57
58 kids[6]->leafinfo->next[1]=kids[7]->leafinfo;
59 kids[6]->leafinfo->next[3]=kids[5]->leafinfo;
60 kids[6]->leafinfo->next[5]=kids[2]->leafinfo;
61
62 kids[3]->leafinfo->next[0]=kids[2]->leafinfo;
63 kids[3]->leafinfo->next[3]=kids[0]->leafinfo;
64 kids[3]->leafinfo->next[4]=kids[7]->leafinfo;
65
66 kids[7]->leafinfo->next[0]=kids[6]->leafinfo;
67 kids[7]->leafinfo->next[3]=kids[4]->leafinfo;
68 kids[7]->leafinfo->next[5]=kids[3]->leafinfo;
69
70
71 for (unsigned short f=0;f<6;++f)
72 {
73 if (next[f]) // if we have neighbours in that direction
74 {
75 if (next[f]->owner->depth > owner->depth) // if this neighbour is already split further than us
76 {
77 OctCell* p=next[f]->owner->parent;
78 // walk each of the new children and link them to their neighbours on the same level
79 // this is just an unrolled for loop
80 kids[faces[f][0]]->leafinfo->next[f] = p->kids[neighbour(faces[f][0], f)]->leafinfo;
81 kids[faces[f][1]]->leafinfo->next[f] = p->kids[neighbour(faces[f][1], f)]->leafinfo;
82 kids[faces[f][2]]->leafinfo->next[f] = p->kids[neighbour(faces[f][2], f)]->leafinfo;
83 kids[faces[f][3]]->leafinfo->next[f] = p->kids[neighbour(faces[f][3], f)]->leafinfo;
84
85 // now the incoming links from neighbours on this face
86 p->kids[neighbour(faces[f][0], f)]->leafinfo->next[oppdir(f)]=kids[faces[f][0]]->leafinfo;
87 p->kids[neighbour(faces[f][1], f)]->leafinfo->next[oppdir(f)]=kids[faces[f][1]]->leafinfo;
88 p->kids[neighbour(faces[f][2], f)]->leafinfo->next[oppdir(f)]=kids[faces[f][2]]->leafinfo;
89 p->kids[neighbour(faces[f][3], f)]->leafinfo->next[oppdir(f)]=kids[faces[f][3]]->leafinfo;
90
91
92 }
93 else // before we split, the neighbour has the same depth as us
94 {
95 OctCell* p=next[f]->owner; // all links point to this single leaf
96
97 kids[faces[f][0]]->leafinfo->next[f] = p->leafinfo;
98 kids[faces[f][1]]->leafinfo->next[f] = p->leafinfo;
99 kids[faces[f][2]]->leafinfo->next[f] = p->leafinfo;
100 kids[faces[f][3]]->leafinfo->next[f] = p->leafinfo;
101
102 p->leafinfo->next[oppdir(f)]=kids[faces[f][0]]->leafinfo; // any child on the face will do
103
104
105 }
106
107 }
108 }
109 }
110
111 // collapse this leaf (and all its siblings) into a single leaf
112 // Warning: When this operation is complete, there will be no outside links (from other leaves) pointing to any
113 // of the siblings but memory management is still the responsibility of the owner
114 void LeafInfo::merge()
115 {
116 OctCell* pcell=owner->parent;
117 if (pcell==0)
118 {
119 return;
120 }
121 LeafInfo* li=new LeafInfo(pcell);
122 // fill in faces for new leafinfo
123 // pick a cell on each face and access its neighbour field
124 for (unsigned short f=0;f<6;++f)
125 {
126 // pick a child on this face
127 unsigned short s=faces[f][0];
128
129 LeafInfo* n=pcell->kids[s]->leafinfo->next[f];
130 if (n) // if we have neighbours in that direction
131 {
132 if (n->owner->depth < owner->depth) // if the neighbour is already shallower than us (prior to merge)
133 {
134 li->next[f]=n;
135 // now to patch the return link
136 n->next[oppdir(f)]=li;
137 }
138 else // neighbour is on the same level as us
139 {
140 li->next[f]=n;
141 // need to patch all the return links on this face
142 n->owner->parent->kids[faces[oppdir(f)][0]]->leafinfo->next[oppdir(f)]=li;
143 n->owner->parent->kids[faces[oppdir(f)][1]]->leafinfo->next[oppdir(f)]=li;
144 n->owner->parent->kids[faces[oppdir(f)][2]]->leafinfo->next[oppdir(f)]=li;
145 n->owner->parent->kids[faces[oppdir(f)][3]]->leafinfo->next[oppdir(f)]=li;
146
147 }
148 }
149
150 }
151 pcell->leafinfo=li;
152 }

  ViewVC Help
Powered by ViewVC 1.1.26