-
Thomas Witkowski authoredThomas Witkowski authored
DualTraverse.h 5.14 KiB
// ============================================================================
// == ==
// == AMDiS - Adaptive multidimensional simulations ==
// == ==
// == http://www.amdis-fem.org ==
// == ==
// ============================================================================
//
// Software License for AMDiS
//
// Copyright (c) 2010 Dresden University of Technology
// All rights reserved.
// Authors: Simon Vey, Thomas Witkowski et al.
//
// This file is part of AMDiS
//
// See also license.opensource.txt in the distribution.
/** \file DualTraverse.h */
#ifndef AMDIS_DUALTRAVERSE_H
#define AMDIS_DUALTRAVERSE_H
#include "Traverse.h"
#include "Flag.h"
#include "AMDiS_fwd.h"
namespace AMDiS {
/** \brief
* Stores the four pointers to element info structures, that are required for the
* dual mesh traverse.
*/
struct DualElInfo
{
ElInfo *rowElInfo;
ElInfo *colElInfo;
ElInfo *smallElInfo;
ElInfo *largeElInfo;
};
/// Parallel traversal of two meshes.
class DualTraverse
{
public:
DualTraverse()
: fillSubElemMat(false),
basisFcts(NULL)
{}
virtual ~DualTraverse() {}
/// Start dual traversal
bool traverseFirst(Mesh *mesh1,
Mesh *mesh2,
int level1,
int level2,
Flag flag1,
Flag flag2,
ElInfo **elInfo1,
ElInfo **elInfo2,
ElInfo **elInfoSmall,
ElInfo **elInfoLarge);
/// Alternative use for starting dual traversal.
inline bool traverseFirst(Mesh *mesh1, Mesh *mesh2,
int level1, int level2,
Flag flag1, Flag flag2,
DualElInfo &dualElInfo)
{
return traverseFirst(mesh1, mesh2, level1, level2, flag1, flag2,
&(dualElInfo.rowElInfo),
&(dualElInfo.colElInfo),
&(dualElInfo.smallElInfo),
&(dualElInfo.largeElInfo));
}
/// Get next ElInfo combination
bool traverseNext(ElInfo **elInfoNext1,
ElInfo **elInfoNext2,
ElInfo **elInfoSmall,
ElInfo **elInfoLarge);
/// Alternative use for getting the next elements in the dual traversal.
inline bool traverseNext(DualElInfo &dualElInfo)
{
return traverseNext(&(dualElInfo.rowElInfo),
&(dualElInfo.colElInfo),
&(dualElInfo.smallElInfo),
&(dualElInfo.largeElInfo));
}
bool check(ElInfo **elInfo1,
ElInfo **elInfo2,
ElInfo **elInfoSmall,
ElInfo **elInfoLarge)
{
prepareNextStep(elInfo1, elInfo2, elInfoSmall, elInfoLarge);
return true;
}
virtual bool skipEl1(ElInfo *elInfo)
{
return false;
}
virtual bool skipEl2(ElInfo *elInfo)
{
return false;
}
inline void setFillSubElemMat(bool b, const BasisFunction *fcts)
{
fillSubElemMat = b;
basisFcts = fcts;
}
/** \brief
* Checks if the small element has an edge/face which is part of a given edge/face
* of the large element. If this is the case, it returns the local number of the
* small edge/face, and -1 otherwise.
*
* \param[in] dualElInfo Dual element info with large and small element infos.
* \param[in] largeFace A local edge/face number on the large element.
*/
static int getFace(DualElInfo *dualElInfo, int largeFace);
protected:
/** \brief
* Determines smaller and larger element, determines which element(s) has to
* be incremented in the next step
*/
void prepareNextStep(ElInfo **elInfo1,
ElInfo **elInfo2,
ElInfo **elInfoSmall,
ElInfo **elInfoLarge);
void fillSubElInfo(ElInfo *elInfo1,
ElInfo *elInfo2,
ElInfo *elInfoSmall,
ElInfo *elInfoLarge);
protected:
/// Stack for mesh 1
TraverseStack stack1;
/// Stack for mesh 2
TraverseStack stack2;
/** \brief
* used to determine whether all small elements belonging to the large
* element are traversed.
*/
double rest;
/// true if element 1 should be incremented (set in prepareNextStep())
bool inc1;
/// true if element 2 should be incremented (set in prepareNextStep())
bool inc2;
/// for level traverse of mesh 1
int level1_;
/// for level traverse of mesh 2
int level2_;
/// for leaf element level traverse of mesh 1
bool callLeafElLevel1_;
/// for leaf element level traverse of mesh 2
bool callLeafElLevel2_;
/** \brief
* If true, during dual mesh traverse for the smaller element the transformation
* matrix will be computed. This matrix defines the transformation mapping for
* points defined on the larger element to the coordinates of the smaller element.
*/
bool fillSubElemMat;
/** \brief
* If \ref fillSubElemMat is set to true, the corresponding transformation
* matrices are computed. These depend on the basis functions that are used.
*/
const BasisFunction *basisFcts;
};
}
#endif