00001 #ifdef CH_LANG_CC
00002
00003
00004
00005
00006
00007
00008
00009 #endif
00010
00011 #ifndef _DIVNORMALREFINEMENTIMPLEM_H_
00012 #define _DIVNORMALREFINEMENTIMPLEM_H_
00013
00014 #include "MayDay.H"
00015
00016 #include "NamespaceHeader.H"
00017
00018 template <int dim> DivNormalRefinement<dim>::DivNormalRefinement()
00019 {
00020 }
00021
00022 template <int dim> DivNormalRefinement<dim>::DivNormalRefinement(const Real & a_maxChangeThreshold,
00023 const int& a_maxNumberOfRefinements)
00024 {
00025 setMaxChangeThreshold(a_maxChangeThreshold);
00026 setMaxNumberOfRefinements(a_maxNumberOfRefinements);
00027 }
00028
00029 template <int dim> DivNormalRefinement<dim>::~DivNormalRefinement()
00030 {
00031 }
00032
00033 template <int dim> bool DivNormalRefinement<dim>::doRefine(IndexTM<int,dim> & a_refineInDir,
00034 const CutCellMoments<dim> & a_ccm,
00035 const int & a_numberOfRefinements)
00036 {
00037 bool retval = false;
00038 a_refineInDir = IndexTM<int,dim>::Zero;
00039
00040 if (a_numberOfRefinements < m_maxNumberOfRefinements)
00041 {
00042 Real changeInNormal = approximateDivNormal(a_ccm);
00043
00044
00045 if (changeInNormal > m_maxChangeThreshold)
00046 {
00047 retval = true;
00048 a_refineInDir = IndexTM<int,dim>::Unit;
00049 }
00050 }
00051
00052 return retval;
00053 }
00054
00055 template <int dim> Real DivNormalRefinement<dim>::approximateDivNormal(const CutCellMoments<dim> & a_ccm)
00056 {
00057 typedef IndexTM<int,dim> IvDim;
00058 typedef IndexTM<Real,dim> RvDim;
00059 typedef IndexTM<int,dim> EdgeIndex;
00060 typedef map<EdgeIndex,Real,LexLT<EdgeIndex> > EdgeIntersections;
00061
00062 Real changeInNormal = 0.0;
00063 const IFData<dim>& edgeData = a_ccm.m_IFData;
00064
00065
00066 const RvDim& normal = edgeData.m_normalDerivatives.find(IndexTM<int,dim>::Zero)->second;
00067
00068
00069 for (typename EdgeIntersections::const_iterator it = edgeData.m_intersections.begin();it != edgeData.m_intersections.end(); ++it)
00070 {
00071 const EdgeIndex& edgeIndex = it->first;
00072 const Real& intercept = it->second;
00073
00074 int varyDir = edgeIndex[0];
00075
00076 RvDim intersectPt = RvDim::Zero;
00077 intersectPt[varyDir] = intercept;
00078
00079 for (int i = 1; i < dim; i++)
00080 {
00081 int curDir;
00082 int loHi;
00083
00084 if (i <= varyDir)
00085 {
00086 curDir = i-1;
00087 }
00088 else
00089 {
00090 curDir = i;
00091 }
00092
00093 loHi = edgeIndex[i];
00094 intersectPt[curDir] = loHi - 0.5;
00095 intersectPt[curDir] *= edgeData.m_globalCoord.m_dx[curDir];
00096 }
00097
00098
00099 NormalDerivative<dim> normalDerivative;
00100 RvDim intersectPtNormal;
00101 for (int idir = 0; idir < dim; idir++)
00102 {
00103 intersectPtNormal[idir] = normalDerivative.evaluate(IndexTM<int,dim>::Zero,
00104 idir,
00105 edgeData.m_globalCoord.convert(intersectPt,edgeData.m_cellCenterCoord),
00106 edgeData.m_function);
00107 }
00108
00109
00110 Real dotProduct = 0.0;
00111 for (int idir = 0; idir < dim; idir++)
00112 {
00113 dotProduct += intersectPtNormal[idir]*normal[idir];
00114 }
00115
00116 if (Abs(dotProduct - 1.0) > changeInNormal)
00117 {
00118 changeInNormal = Abs(dotProduct -1.0);
00119 }
00120 }
00121 return changeInNormal;
00122 }
00123
00124 template <int dim> void DivNormalRefinement<dim>::setMaxChangeThreshold(const Real & a_maxChangeThreshold)
00125 {
00126 if (a_maxChangeThreshold < 0)
00127 {
00128 MayDay::Abort("DivNormalRefinement<dim>::setMaxChangeThreshold - maxChangeThreshold must be >= 0");
00129 }
00130
00131 m_maxChangeThreshold = a_maxChangeThreshold;
00132 }
00133
00134 template <int dim> Real DivNormalRefinement<dim>::getMaxChangeThreshold()
00135 {
00136 return m_maxChangeThreshold;
00137 }
00138
00139 template <int dim> void DivNormalRefinement<dim>::setMaxNumberOfRefinements(const int & a_maxNumberOfRefinements)
00140 {
00141 if (a_maxNumberOfRefinements < 0)
00142 {
00143 MayDay::Abort("DivNormalRefinement<dim>::setMaxNumberOfRefinements - maxNumberOfRefinents must be >= 0");
00144 }
00145
00146 m_maxNumberOfRefinements = a_maxNumberOfRefinements;
00147 }
00148
00149 template <int dim> int DivNormalRefinement<dim>::getMaxNumberOfRefinements()
00150 {
00151 return m_maxNumberOfRefinements;
00152 }
00153
00154 #include "NamespaceFooter.H"
00155
00156 #endif