Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Backofen, Rainer
amdis
Commits
f96caf23
Commit
f96caf23
authored
Jun 29, 2010
by
Thomas Witkowski
Browse files
Fixed a very special refinement bug occured only in parallel computations.
parent
067ba67d
Changes
15
Hide whitespace changes
Inline
Side-by-side
AMDiS/src/DOFMatrix.h
View file @
f96caf23
...
...
@@ -49,10 +49,10 @@ namespace AMDiS {
{
public:
/// Type of scalars in the underlying matrix
typedef
double
value_type
;
typedef
double
value_type
;
/// Type of underlying matrix
typedef
mtl
::
compressed2D
<
value_type
>
base_matrix_type
;
typedef
mtl
::
compressed2D
<
value_type
>
base_matrix_type
;
/// Type of inserter for the base matrix;
typedef
mtl
::
matrix
::
inserter
<
base_matrix_type
,
mtl
::
operations
::
update_plus
<
value_type
>
>
inserter_type
;
...
...
AMDiS/src/Debug.cc
View file @
f96caf23
...
...
@@ -62,11 +62,11 @@ namespace AMDiS {
}
void
writeElementIndexMesh
(
FiniteElemSpace
*
feSpace
,
std
::
string
filename
)
void
writeElementIndexMesh
(
Mesh
*
mesh
,
std
::
string
filename
)
{
std
::
map
<
int
,
double
>
vec
;
TraverseStack
stack
;
ElInfo
*
elInfo
=
stack
.
traverseFirst
(
feSpace
->
getM
esh
()
,
-
1
,
Mesh
::
CALL_LEAF_EL
);
ElInfo
*
elInfo
=
stack
.
traverseFirst
(
m
esh
,
-
1
,
Mesh
::
CALL_LEAF_EL
);
while
(
elInfo
)
{
int
index
=
elInfo
->
getElement
()
->
getIndex
();
...
...
@@ -74,16 +74,15 @@ namespace AMDiS {
elInfo
=
stack
.
traverseNext
(
elInfo
);
}
ElementFileWriter
::
writeFile
(
vec
,
feSpace
,
filename
);
ElementFileWriter
::
writeFile
(
vec
,
mesh
,
filename
);
}
void
highlightElementIndexMesh
(
FiniteElemSpace
*
feSpace
,
int
idx
,
std
::
string
filename
)
void
highlightElementIndexMesh
(
Mesh
*
mesh
,
int
idx
,
std
::
string
filename
)
{
std
::
map
<
int
,
double
>
vec
;
TraverseStack
stack
;
ElInfo
*
elInfo
=
stack
.
traverseFirst
(
feSpace
->
getM
esh
()
,
-
1
,
Mesh
::
CALL_LEAF_EL
);
ElInfo
*
elInfo
=
stack
.
traverseFirst
(
m
esh
,
-
1
,
Mesh
::
CALL_LEAF_EL
);
while
(
elInfo
)
{
int
index
=
elInfo
->
getElement
()
->
getIndex
();
...
...
@@ -91,7 +90,7 @@ namespace AMDiS {
elInfo
=
stack
.
traverseNext
(
elInfo
);
}
ElementFileWriter
::
writeFile
(
vec
,
feSpace
,
filename
);
ElementFileWriter
::
writeFile
(
vec
,
mesh
,
filename
);
}
...
...
AMDiS/src/Debug.h
View file @
f96caf23
...
...
@@ -72,10 +72,9 @@ namespace AMDiS {
* \param[in] feSpace The FE space to be used.
* \param[in] filename Name of the file.
*/
void
writeElementIndexMesh
(
FiniteElemSpace
*
feSpace
,
std
::
string
filename
);
void
writeElementIndexMesh
(
Mesh
*
mesh
,
std
::
string
filename
);
void
highlightElementIndexMesh
(
FiniteElemSpace
*
feSpace
,
int
idx
,
std
::
string
filename
);
void
highlightElementIndexMesh
(
Mesh
*
mesh
,
int
idx
,
std
::
string
filename
);
void
colorDofVectorByLocalElementDofs
(
DOFVector
<
double
>&
vec
,
Element
*
el
);
...
...
AMDiS/src/ElementFileWriter.cc
View file @
f96caf23
...
...
@@ -7,7 +7,7 @@
namespace
AMDiS
{
ElementFileWriter
::
ElementFileWriter
(
std
::
string
name_
,
const
FiniteElemSpace
*
feSpace
_
,
Mesh
*
mesh
_
,
std
::
map
<
int
,
double
>
&
mapvec
)
:
name
(
name_
),
tecplotExt
(
".plt"
),
...
...
@@ -21,8 +21,7 @@ namespace AMDiS {
indexDecimals
(
3
),
tsModulo
(
1
),
timestepNumber
(
-
1
),
mesh
(
feSpace_
->
getMesh
()),
feSpace
(
feSpace_
),
mesh
(
mesh_
),
vec
(
mapvec
)
{
if
(
name
!=
""
)
{
...
...
@@ -93,10 +92,10 @@ namespace AMDiS {
void
ElementFileWriter
::
writeFile
(
std
::
map
<
int
,
double
>
&
vec
,
const
FiniteElemSpace
*
feSpace
,
Mesh
*
mesh
,
std
::
string
filename
)
{
ElementFileWriter
efw
(
""
,
feSpace
,
vec
);
ElementFileWriter
efw
(
""
,
mesh
,
vec
);
efw
.
writeVtkValues
(
filename
);
}
...
...
AMDiS/src/ElementFileWriter.h
View file @
f96caf23
...
...
@@ -22,7 +22,7 @@ namespace AMDiS {
public:
/// Constructor.
ElementFileWriter
(
std
::
string
name
,
const
FiniteElemSpace
*
feSpace
,
Mesh
*
mesh
,
std
::
map
<
int
,
double
>
&
vec
);
/// Implementation of FileWriterInterface::writeFiles().
...
...
@@ -33,7 +33,7 @@ namespace AMDiS {
/// Simple writing procedure for one element map.
static
void
writeFile
(
std
::
map
<
int
,
double
>
&
vec
,
const
FiniteElemSpace
*
feSpace
,
Mesh
*
mesh
,
std
::
string
filename
);
protected:
...
...
@@ -101,9 +101,6 @@ namespace AMDiS {
/// Mesh used for output.
Mesh
*
mesh
;
/// fespace used for output.
const
FiniteElemSpace
*
feSpace
;
/// Vector that stores the solution.
std
::
map
<
int
,
double
>
vec
;
};
...
...
AMDiS/src/ProblemScal.cc
View file @
f96caf23
...
...
@@ -620,6 +620,7 @@ namespace AMDiS {
createPrecon
();
}
void
ProblemScal
::
writeResidualMesh
(
AdaptInfo
*
adaptInfo
,
std
::
string
name
)
{
FUNCNAME
(
"ProblemScal::writeResidualMesh()"
);
...
...
@@ -634,10 +635,11 @@ namespace AMDiS {
elInfo
=
stack
.
traverseNext
(
elInfo
);
}
ElementFileWriter
fw
(
name
,
this
->
get
FeSpace
(),
vec
);
ElementFileWriter
fw
(
name
,
this
->
get
Mesh
(),
vec
);
fw
.
writeFiles
(
adaptInfo
,
true
);
}
void
ProblemScal
::
createPrecon
()
{
std
::
string
preconType
(
"no"
);
...
...
@@ -646,15 +648,16 @@ namespace AMDiS {
CreatorInterface
<
ITL_BasePreconditioner
>
*
preconCreator
=
CreatorMap
<
ITL_BasePreconditioner
>::
getCreator
(
preconType
);
solver
->
setLeftPrecon
(
preconCreator
->
create
(
systemMatrix
->
getBaseMatrix
())
);
solver
->
setLeftPrecon
(
preconCreator
->
create
(
systemMatrix
->
getBaseMatrix
()));
preconType
=
"no"
;
GET_PARAMETER
(
0
,
name
+
"->solver->right precon"
,
&
preconType
);
preconCreator
=
CreatorMap
<
ITL_BasePreconditioner
>::
getCreator
(
preconType
);
solver
->
setRightPrecon
(
preconCreator
->
create
(
systemMatrix
->
getBaseMatrix
())
);
solver
->
setRightPrecon
(
preconCreator
->
create
(
systemMatrix
->
getBaseMatrix
()));
}
void
ProblemScal
::
serialize
(
std
::
ostream
&
out
)
{
FUNCNAME
(
"ProblemScal::serialize()"
);
...
...
@@ -663,6 +666,7 @@ namespace AMDiS {
solution
->
serialize
(
out
);
}
void
ProblemScal
::
deserialize
(
std
::
istream
&
in
)
{
FUNCNAME
(
"ProblemScal::deserialize()"
);
...
...
AMDiS/src/ProblemVec.cc
View file @
f96caf23
...
...
@@ -1538,7 +1538,7 @@ namespace AMDiS {
elInfo
=
stack
.
traverseNext
(
elInfo
);
}
ElementFileWriter
::
writeFile
(
vec
,
this
->
get
FeSpace
(
comp
),
name
);
ElementFileWriter
::
writeFile
(
vec
,
this
->
get
Mesh
(
comp
),
name
);
}
...
...
AMDiS/src/RCNeighbourList.cc
View file @
f96caf23
...
...
@@ -259,6 +259,7 @@ namespace AMDiS {
}
}
void
RCNeighbourList
::
removeDOFParent
(
int
index
)
{
Tetrahedron
*
el
=
dynamic_cast
<
Tetrahedron
*>
(
rclist
[
index
]
->
el
);
...
...
@@ -297,6 +298,7 @@ namespace AMDiS {
}
}
RCNeighbourList
*
RCNeighbourList
::
periodicSplit
(
DegreeOfFreedom
*
edge
[
2
],
DegreeOfFreedom
*
nextEdge
[
2
],
int
*
n_neigh
,
...
...
AMDiS/src/RefinementManager2d.cc
View file @
f96caf23
...
...
@@ -12,10 +12,11 @@
#include "Projection.h"
#include "LeafData.h"
#include "VertexVector.h"
#include "Debug.h"
namespace
AMDiS
{
ElInfo
*
RefinementManager2d
::
refineFunction
(
ElInfo
*
el
_i
nfo
)
ElInfo
*
RefinementManager2d
::
refineFunction
(
ElInfo
*
el
I
nfo
)
{
FUNCNAME
(
"RefinementManager::refineFunction()"
);
...
...
@@ -23,41 +24,38 @@ namespace AMDiS {
DegreeOfFreedom
*
edge
[
2
];
RCNeighbourList
*
refineList
=
new
RCNeighbourList
(
2
);
if
(
el
_i
nfo
->
getElement
()
->
getMark
()
<=
0
)
{
if
(
el
I
nfo
->
getElement
()
->
getMark
()
<=
0
)
{
delete
refineList
;
// Element may not be refined.
return
el
_i
nfo
;
return
el
I
nfo
;
}
refineList
->
setElement
(
0
,
el
_i
nfo
->
getElement
());
refineList
->
setElement
(
0
,
el
I
nfo
->
getElement
());
int
n_neigh
=
1
;
if
(
el
_i
nfo
->
getProjection
(
0
)
&&
el
_i
nfo
->
getProjection
(
0
)
->
getType
()
==
VOLUME_PROJECTION
)
if
(
el
I
nfo
->
getProjection
(
0
)
&&
el
I
nfo
->
getProjection
(
0
)
->
getType
()
==
VOLUME_PROJECTION
)
newCoords
=
true
;
// === Give the refinement edge the right orientation. ===
if
(
el
_i
nfo
->
getElement
()
->
getDOF
(
0
,
0
)
<
el
_i
nfo
->
getElement
()
->
getDOF
(
1
,
0
))
{
edge
[
0
]
=
const_cast
<
int
*>
(
el
_i
nfo
->
getElement
()
->
getDOF
(
0
));
edge
[
1
]
=
const_cast
<
int
*>
(
el
_i
nfo
->
getElement
()
->
getDOF
(
1
));
if
(
el
I
nfo
->
getElement
()
->
getDOF
(
0
,
0
)
<
el
I
nfo
->
getElement
()
->
getDOF
(
1
,
0
))
{
edge
[
0
]
=
const_cast
<
int
*>
(
el
I
nfo
->
getElement
()
->
getDOF
(
0
));
edge
[
1
]
=
const_cast
<
int
*>
(
el
I
nfo
->
getElement
()
->
getDOF
(
1
));
}
else
{
edge
[
1
]
=
const_cast
<
int
*>
(
el
_i
nfo
->
getElement
()
->
getDOF
(
0
));
edge
[
0
]
=
const_cast
<
int
*>
(
el
_i
nfo
->
getElement
()
->
getDOF
(
1
));
edge
[
1
]
=
const_cast
<
int
*>
(
el
I
nfo
->
getElement
()
->
getDOF
(
0
));
edge
[
0
]
=
const_cast
<
int
*>
(
el
I
nfo
->
getElement
()
->
getDOF
(
1
));
}
// === Get the refinement patch. ===
if
(
getRefinePatch
(
&
el_info
,
edge
,
0
,
refineList
,
&
n_neigh
))
{
// Domain's boundary was reached while looping around the refinement edge.
getRefinePatch
(
&
el_info
,
edge
,
1
,
refineList
,
&
n_neigh
);
bound
=
true
;
}
getRefinePatch
(
&
elInfo
,
edge
,
0
,
refineList
,
&
n_neigh
);
// === Check for periodic boundary ===
DegreeOfFreedom
*
next_edge
[
2
];
DegreeOfFreedom
*
next_edge
[
2
]
=
{
NULL
,
NULL
}
;
DegreeOfFreedom
*
first_edge
[
2
]
=
{
edge
[
0
],
edge
[
1
]};
DegreeOfFreedom
*
last_edge
[
2
]
=
{
NULL
,
NULL
};
int
n_neigh_periodic
;
...
...
@@ -121,25 +119,25 @@ namespace AMDiS {
delete
refineList
;
return
el
_i
nfo
;
return
el
I
nfo
;
}
void
RefinementManager2d
::
newCoordsFct
(
ElInfo
*
el
_i
nfo
)
void
RefinementManager2d
::
newCoordsFct
(
ElInfo
*
el
I
nfo
)
{
Element
*
el
=
el
_i
nfo
->
getElement
();
Element
*
el
=
el
I
nfo
->
getElement
();
int
dow
=
Global
::
getGeo
(
WORLD
);
Projection
*
projector
=
el
_i
nfo
->
getProjection
(
0
);
Projection
*
projector
=
el
I
nfo
->
getProjection
(
0
);
if
(
!
projector
||
projector
->
getType
()
!=
VOLUME_PROJECTION
)
projector
=
el
_i
nfo
->
getProjection
(
2
);
projector
=
el
I
nfo
->
getProjection
(
2
);
if
(
el
->
getFirstChild
()
&&
projector
&&
(
!
el
->
isNewCoordSet
()))
{
WorldVector
<
double
>
*
new_coord
=
new
WorldVector
<
double
>
;
for
(
int
j
=
0
;
j
<
dow
;
j
++
)
(
*
new_coord
)[
j
]
=
(
el
_i
nfo
->
getCoord
(
0
)[
j
]
+
el
_i
nfo
->
getCoord
(
1
)[
j
])
*
0.5
;
(
*
new_coord
)[
j
]
=
(
el
I
nfo
->
getCoord
(
0
)[
j
]
+
el
I
nfo
->
getCoord
(
1
)[
j
])
*
0.5
;
projector
->
project
(
*
new_coord
);
el
->
setNewCoord
(
new_coord
);
...
...
@@ -235,10 +233,10 @@ namespace AMDiS {
void
RefinementManager2d
::
bisectTriangle
(
Triangle
*
el
,
DegreeOfFreedom
*
newDOFs
[
3
])
{
FUNCNAME
(
"RefinementManager2d::bisectTriangle()"
);
TEST_EXIT_DBG
(
mesh
)(
"no mesh!
\n
"
);
Triangle
*
child
[
2
];
child
[
0
]
=
dynamic_cast
<
Triangle
*>
(
mesh
->
createNewElement
(
el
));
child
[
1
]
=
dynamic_cast
<
Triangle
*>
(
mesh
->
createNewElement
(
el
));
...
...
@@ -302,36 +300,47 @@ namespace AMDiS {
}
int
RefinementManager2d
::
getRefinePatch
(
ElInfo
**
el
_i
nfo
,
void
RefinementManager2d
::
getRefinePatch
(
ElInfo
**
el
I
nfo
,
DegreeOfFreedom
*
edge
[
2
],
int
dir
,
RCNeighbourList
*
refineList
,
int
*
n_neigh
)
{
FUNCNAME
(
"RefinementManager2d::getRefinePatch()"
);
if
((
*
el
_i
nfo
)
->
getNeighbour
(
2
)
&&
(
*
el
_i
nfo
)
->
getOppVertex
(
2
)
!=
2
)
{
if
((
*
el
I
nfo
)
->
getNeighbour
(
2
)
&&
(
*
el
I
nfo
)
->
getOppVertex
(
2
)
!=
2
)
{
// Neighbour is not compatible devisible; refine neighbour first, store the
// opp_vertex to traverse back to el.
int
opp_vertex
=
(
*
el
_i
nfo
)
->
getOppVertex
(
2
);
int
opp_vertex
=
(
*
el
I
nfo
)
->
getOppVertex
(
2
);
ElInfo
*
neigh_info
=
stack
->
traverseNeighbour2d
(
*
el
_i
nfo
,
2
);
ElInfo
*
neigh_info
=
stack
->
traverseNeighbour2d
(
*
el
I
nfo
,
2
);
neigh_info
->
getElement
()
->
setMark
(
max
(
neigh_info
->
getElement
()
->
getMark
(),
1
));
neigh_info
=
refineFunction
(
neigh_info
);
// Now go back to the original element and refine the patch.
*
el_info
=
neigh_info
=
stack
->
traverseNeighbour2d
(
neigh_info
,
opp_vertex
);
// === Now go back to the original element and refine the patch. ===
// In Debug mode we test if traverNeighbour2d returns the expected element.
#if (DEBUG != 0)
int
testIndex
=
neigh_info
->
getNeighbour
(
opp_vertex
)
->
getIndex
();
#endif
*
elInfo
=
neigh_info
=
stack
->
traverseNeighbour2d
(
neigh_info
,
opp_vertex
);
TEST_EXIT_DBG
(
testIndex
==
(
*
elInfo
)
->
getElement
()
->
getIndex
())
(
"Got wrong neighbour! Should be %d, but is %d!
\n
"
,
testIndex
,
(
*
elInfo
)
->
getElement
()
->
getIndex
());
TEST_EXIT_DBG
(
neigh_info
->
getElement
()
==
dynamic_cast
<
Triangle
*>
(
const_cast
<
Element
*>
((
*
el
_i
nfo
)
->
getElement
())))
dynamic_cast
<
Triangle
*>
(
const_cast
<
Element
*>
((
*
el
I
nfo
)
->
getElement
())))
(
"invalid traverse_neighbour1
\n
"
);
}
if
(
refineList
->
setElement
(
1
,
(
*
el
_i
nfo
)
->
getNeighbour
(
2
)))
{
TEST_EXIT_DBG
((
*
el
_i
nfo
)
->
getOppVertex
(
2
)
==
2
)
if
(
refineList
->
setElement
(
1
,
(
*
el
I
nfo
)
->
getNeighbour
(
2
)))
{
TEST_EXIT_DBG
((
*
el
I
nfo
)
->
getOppVertex
(
2
)
==
2
)
(
"no compatible ref. edge after recursive refinement of neighbour
\n
"
);
*
n_neigh
=
2
;
}
return
0
;
}
}
AMDiS/src/RefinementManager2d.h
View file @
f96caf23
...
...
@@ -54,15 +54,16 @@ namespace AMDiS {
* get_refine_patch returns 1 if the domain's boundary is reached while
* looping around the refinement edge, otherwise 0
*/
int
getRefinePatch
(
ElInfo
**
el
_i
nfo
,
DegreeOfFreedom
*
edge
[
2
],
int
dir
,
RCNeighbourList
*
refineList
,
int
*
n_neigh
);
void
getRefinePatch
(
ElInfo
**
el
I
nfo
,
DegreeOfFreedom
*
edge
[
2
],
int
dir
,
RCNeighbourList
*
refineList
,
int
*
n_neigh
);
/// Refines all elements in the patch.
DegreeOfFreedom
refinePatch
(
DegreeOfFreedom
*
edge
[
2
],
RCNeighbourList
*
refineList
,
DegreeOfFreedom
refinePatch
(
DegreeOfFreedom
*
edge
[
2
],
RCNeighbourList
*
refineList
,
int
n_neigh
,
bool
bound
);
/// Implements RefinementManager::refineFunction.
ElInfo
*
refineFunction
(
ElInfo
*
el
_i
nfo
);
ElInfo
*
refineFunction
(
ElInfo
*
el
I
nfo
);
/// Refines one Triangle.
void
bisectTriangle
(
Triangle
*
el
,
DegreeOfFreedom
*
newDofs
[
3
]);
...
...
AMDiS/src/Traverse.cc
View file @
f96caf23
...
...
@@ -135,9 +135,8 @@ namespace AMDiS {
currentMacro
=
traverse_mesh
->
firstMacroElement
();
while
(((
*
currentMacro
)
->
getIndex
()
%
maxThreads
!=
myThreadId
)
&&
(
currentMacro
!=
traverse_mesh
->
endOfMacroElements
()))
{
currentMacro
++
;
}
currentMacro
!=
traverse_mesh
->
endOfMacroElements
())
currentMacro
++
;
if
(
currentMacro
==
traverse_mesh
->
endOfMacroElements
())
return
NULL
;
...
...
@@ -349,13 +348,8 @@ namespace AMDiS {
int
fillIthChild
=
info_stack
[
stack_used
];
info_stack
[
stack_used
]
++
;
if
(
traverse_fill_flag
.
isSet
(
Mesh
::
CALL_REVERSE_MODE
))
{
if
(
fillIthChild
==
0
)
fillIthChild
=
1
;
else
fillIthChild
=
0
;
}
if
(
traverse_fill_flag
.
isSet
(
Mesh
::
CALL_REVERSE_MODE
))
fillIthChild
=
1
-
fillIthChild
;
elinfo_stack
[
stack_used
+
1
]
->
fillElInfo
(
fillIthChild
,
elinfo_stack
[
stack_used
]);
stack_used
++
;
...
...
@@ -450,7 +444,8 @@ namespace AMDiS {
case
3
:
return
traverseNeighbour3d
(
elinfo_old
,
neighbour
);
break
;
default:
ERROR_EXIT
(
"invalid dim
\n
"
);
default:
ERROR_EXIT
(
"invalid dim
\n
"
);
}
return
NULL
;
}
...
...
@@ -461,11 +456,12 @@ namespace AMDiS {
FUNCNAME
(
"TraverseStackLLtraverseNeighbour3d()"
);
Element
*
el2
;
ElInfo
*
old_elinfo
,
*
elinfo
,
*
elinfo2
;
ElInfo
*
elinfo2
;
const
DegreeOfFreedom
*
dof
;
int
i
,
nb
,
opp_vertex
,
stack2_used
,
typ
=
0
;
int
sav_index
,
sav_neighbour
=
neighbour
;
int
stack2_used
;
int
sav_neighbour
=
neighbour
;
// father.neigh[coarse_nb[i][j]] == child[i-1].neigh[j]
static
int
coarse_nb
[
3
][
3
][
4
]
=
{{{
-
2
,
-
2
,
-
2
,
-
2
},
{
-
1
,
2
,
3
,
1
},
{
-
1
,
3
,
2
,
0
}},
{{
-
2
,
-
2
,
-
2
,
-
2
},
{
-
1
,
2
,
3
,
1
},
{
-
1
,
2
,
3
,
0
}},
{{
-
2
,
-
2
,
-
2
,
-
2
},
{
-
1
,
2
,
3
,
1
},
{
-
1
,
2
,
3
,
0
}}};
...
...
@@ -473,26 +469,29 @@ namespace AMDiS {
TEST_EXIT_DBG
(
stack_used
>
0
)(
"no current element
\n
"
);
Parametric
*
parametric
=
traverse_mesh
->
getParametric
();
if
(
parametric
)
elinfo_old
=
parametric
->
removeParametricInfo
(
elinfo_old
);
TEST_EXIT_DBG
(
elinfo_old
==
elinfo_stack
[
stack_used
])
(
"invalid old elinfo
\n
"
);
TEST_EXIT_DBG
(
elinfo_old
==
elinfo_stack
[
stack_used
])(
"invalid old elinfo
\n
"
);
TEST_EXIT_DBG
(
elinfo_stack
[
stack_used
]
->
getFillFlag
().
isSet
(
Mesh
::
FILL_NEIGH
))
(
"FILL_NEIGH not set"
);
Element
*
el
=
elinfo_stack
[
stack_used
]
->
getElement
();
sav_index
=
el
->
getIndex
();
int
sav_index
=
el
->
getIndex
();
/* first, goto to leaf level, if necessary... */
if
((
traverse_fill_flag
&
Mesh
::
CALL_LEAF_EL
).
isAnySet
())
{
if
(
(
el
->
getChild
(
0
)
)
&&
(
neighbour
<
2
)
)
{
if
(
el
->
getChild
(
0
)
&&
neighbour
<
2
)
{
if
(
stack_used
>=
stack_size
-
1
)
enlargeTraverseStack
();
i
=
1
-
neighbour
;
int
i
=
1
-
neighbour
;
elinfo_stack
[
stack_used
+
1
]
->
fillElInfo
(
i
,
elinfo_stack
[
stack_used
]);
info_stack
[
stack_used
]
=
i
+
1
;
if
(
traverse_fill_flag
.
isSet
(
Mesh
::
CALL_REVERSE_MODE
))
info_stack
[
stack_used
]
=
(
i
==
0
?
2
:
1
);
else
info_stack
[
stack_used
]
=
i
+
1
;
stack_used
++
;
info_stack
[
stack_used
]
=
0
;
neighbour
=
3
;
...
...
@@ -502,30 +501,43 @@ namespace AMDiS {
/* save information about current element and its position in the tree */
save_traverse_mel
=
traverse_mel
;
save_stack_used
=
stack_used
;
for
(
int
i
=
stack_used
;
i
<=
save_stack_used
;
i
++
)
{
save_info_stack
[
i
]
=
info_stack
[
i
];
*
(
save_elinfo_stack
[
i
])
=
*
(
elinfo_stack
[
i
]);
}
ElInfo
*
old_elinfo
=
save_elinfo_stack
[
save_stack_used
];
int
opp_vertex
=
old_elinfo
->
getOppVertex
(
neighbour
);
nb
=
neighbour
;
// === First phase (see 2D). ===
int
nb
=
neighbour
;
while
(
stack_used
>
1
)
{
/* go up in tree until we can go down again */
stack_used
--
;
typ
=
elinfo_stack
[
stack_used
]
->
getType
();
nb
=
coarse_nb
[
typ
][
info_stack
[
stack_used
]][
nb
];
int
typ
=
elinfo_stack
[
stack_used
]
->
getType
();
int
elIsIthChild
=
info_stack
[
stack_used
];
if
(
traverse_fill_flag
.
isSet
(
Mesh
::
CALL_REVERSE_MODE
)
&&
elIsIthChild
!=
0
)
elIsIthChild
=
(
elIsIthChild
==
1
?
2
:
1
);
TEST_EXIT_DBG
(
!
elinfo_stack
[
stack_used
+
1
]
->
getParent
()
||
elinfo_stack
[
stack_used
+
1
]
->
getParent
()
->
getChild
(
elIsIthChild
-
1
)
==
elinfo_stack
[
stack_used
+
1
]
->
getElement
())
(
"Should not happen!
\n
"
);
nb
=
coarse_nb
[
typ
][
elIsIthChild
][
nb
];
if
(
nb
==
-
1
)
break
;
TEST_EXIT_DBG
(
nb
>=
0
)(
"invalid coarse_nb %d
\n
"
,
nb
);
}
/* save hierarchy information about current element */
for
(
i
=
stack_used
;
i
<=
save_stack_used
;
i
++
)
{
save_info_stack
[
i
]
=
info_stack
[
i
];
*
(
save_elinfo_stack
[
i
])
=
*
(
elinfo_stack
[
i
]);
}
old_elinfo
=
save_elinfo_stack
[
save_stack_used
];
opp_vertex
=
old_elinfo
->
getOppVertex
(
neighbour
);
if
(
nb
>=
0
)
{
// Go to macro element
neighbour
.
if
(
nb
>=
0
)
{
/* go to macro element neighbour */
i
=
traverse_mel
->
getOppVertex
(
nb
);
int
i
=
traverse_mel
->
getOppVertex
(
nb
);
traverse_mel
=
traverse_mel
->
getNeighbour
(
nb
);
if
(
traverse_mel
==
NULL
)
return
NULL
;
...
...
@@ -541,7 +553,9 @@ namespace AMDiS {
elinfo_stack
[
stack_used
]
->
fillMacroInfo
(
traverse_mel
);
info_stack
[
stack_used
]
=
0
;
nb
=
i
;
}
else
{
/* goto other child */
}
else
{
// Goto other child.
stack2_used
=
stack_used
+
1
;
if
(
save_stack_used
>
stack2_used
)
stack2_used
++
;
/* go down one level in OLD hierarchy */
...
...
@@ -551,24 +565,37 @@ namespace AMDiS {
if
(
stack_used
>=
stack_size
-
1
)
enlargeTraverseStack
();
i
=
2
-
info_stack
[
stack_used
];
info_stack
[
stack_used
]
=
i
+
1
;
elinfo_stack
[
stack_used
+
1
]
->
fillElInfo
(
i
,
elinfo_stack
[
stack_used
]);
int
i
=
2
-
info_stack
[
stack_used
];
info_stack
[
stack_used
]
=
i
+
1
;
int
fillIthChild
=
i
;
if
(
traverse_fill_flag
.
isSet
(
Mesh
::
CALL_REVERSE_MODE
))
fillIthChild
=
1
-
fillIthChild
;
elinfo_stack
[
stack_used
+
1
]
->
fillElInfo
(
fillIthChild
,
elinfo_stack
[
stack_used
]);
stack_used
++
;
info_stack
[
stack_used
]
=
0
;
nb
=
0
;
}
elinfo
=
elinfo_stack
[
stack_used
];
// === Second phase. ===
ElInfo
*
elinfo
=
elinfo_stack
[
stack_used
];
el
=
elinfo
->
getElement
();
while
(
el
->
getChild
(
0
))
{
if
(
nb
<
2
)
{
/* go down one level in hierarchy */
if
(
stack_used
>=
stack_size
-
1
)
while
(
el
->
getChild
(
0
))
{
if
(
nb
<
2
)
{
// Go down one level in hierarchy.
if
(
stack_used
>=
stack_size
-
1
)
enlargeTraverseStack
();
info_stack
[
stack_used
]
=
2
-
nb
;
elinfo_stack
[
stack_used
+
1
]
->
fillElInfo
(
1
-
nb
,
elinfo_stack
[
stack_used
]);
info_stack
[
stack_used
]
=
2
-
nb
;
int
fillIthChild
=
1
-
nb
;
if
(
traverse_fill_flag
.
isSet
(
Mesh
::
CALL_REVERSE_MODE
))
fillIthChild
=
1
-
fillIthChild
;
elinfo_stack
[
stack_used
+
1
]
->
fillElInfo
(
fillIthChild
,
elinfo_stack
[
stack_used
]);
stack_used
++
;
info_stack
[
stack_used
]
=
0
;
elinfo
=
elinfo_stack
[
stack_used
];
...
...
@@ -576,9 +603,12 @@ namespace AMDiS {
nb
=
3
;