00001 #ifdef CH_LANG_CC 00002 /* 00003 * _______ __ 00004 * / ___/ / ___ __ _ / / ___ 00005 * / /__/ _ \/ _ \/ V \/ _ \/ _ \ 00006 * \___/_//_/\___/_/_/_/_.__/\___/ 00007 * Please refer to Copyright.txt, in Chombo's root directory. 00008 */ 00009 #endif 00010 00011 #ifndef _LEVELFLUXREGISTEREDGE_H_ 00012 #define _LEVELFLUXREGISTEREDGE_H_ 00013 00014 #include "REAL.H" 00015 #include "Vector.H" 00016 #include "FluxBox.H" 00017 #include "EdgeDataBox.H" 00018 #include "IntVectSet.H" 00019 #include "CFStencil.H" 00020 #include "LoHiSide.H" 00021 #include "LevelData.H" 00022 #include "LayoutData.H" 00023 00024 #include "NamespaceHeader.H" 00025 00026 ///LevelFluxRegisterEdge -- Flux register for constrained-transport applications 00027 /** 00028 A LevelFluxRegisterEdge manages the coarse-fine fixup for a face-centered 00029 field which is defined as a curl of an edge-centered field, performing 00030 the "reflux-curl" operation described in Balsara(2001) to preserve the 00031 divergence-free magnetic field in the presence of coarse-fine interfaces. 00032 00033 This class performs a reflux-curl of edge-centered fluxes to correct a 00034 face-centered field. This is in contrast to the regular LevelFluxRegister 00035 class, which performs a reflux-divergence of face-centered fluxes to 00036 correct a cell-centered field. 00037 */ 00038 class LevelFluxRegisterEdge 00039 { 00040 public: 00041 00042 /// 00043 /** 00044 Default constructor. Creates an uninitialized LevelFluxRegisterEdge. 00045 */ 00046 LevelFluxRegisterEdge(); 00047 00048 /// 00049 /** 00050 Full constructor. Calls the define function which creates 00051 a levels worth of flux registers. 00052 */ 00053 LevelFluxRegisterEdge( 00054 const DisjointBoxLayout& a_dbl, 00055 const DisjointBoxLayout& a_dblCoarse, 00056 const Box& a_dProblem, 00057 int a_nRefine, 00058 int a_nComp); 00059 00060 /// 00061 /** 00062 Full constructor. Calls the define function which creates 00063 a levels worth of flux registers. 00064 */ 00065 LevelFluxRegisterEdge( 00066 const DisjointBoxLayout& a_dbl, 00067 const DisjointBoxLayout& a_dblCoarse, 00068 const ProblemDomain& a_dProblem, 00069 int a_nRefine, 00070 int a_nComp); 00071 00072 /// 00073 ~LevelFluxRegisterEdge(); 00074 00075 /// 00076 /** 00077 Full define function. Creates a levels worth of flux registers. 00078 The values in the flux registers are still undefined, however. 00079 To zero the fluxregisters, you must call setToZero(). 00080 */ 00081 void define( 00082 const DisjointBoxLayout& a_dbl, 00083 const DisjointBoxLayout& a_dblCoarse, 00084 const Box& a_dProblem, 00085 int a_nRefine, 00086 int a_nComp); 00087 00088 00089 /// 00090 /** 00091 Full define function. Creates a levels worth of flux registers. 00092 The values in the flux registers are still undefined, however. 00093 To zero the fluxregisters, you must call setToZero(). 00094 */ 00095 void define( 00096 const DisjointBoxLayout& a_dbl, 00097 const DisjointBoxLayout& a_dblCoarse, 00098 const ProblemDomain& a_dProblem, 00099 int a_nRefine, 00100 int a_nComp); 00101 00102 /// 00103 /** 00104 Modifies this LevelFluxRegisterEdge so that it is returned to the 00105 uninitialized state. User must now call the full define() before 00106 using it. 00107 00108 */ 00109 void 00110 undefine(); 00111 00112 /// 00113 /** 00114 Initialize values of registers to zero. 00115 */ 00116 void setToZero(); 00117 00118 /// 00119 /** 00120 increments the register with data from coarseFlux, multiplied by scale. 00121 coarseFlux must contain the edge-centered (in 3d, node centered in 00122 2d) coarse fluxes in the dir direction 00123 for the grid m_coarseLayout[coarseDataIndex]. 00124 By convention, only the low side flux is used to 00125 avoid double-counting at coarse-fine interfaces. 00126 This operation is local. 00127 */ 00128 void incrementCoarse( 00129 FArrayBox& a_coarseFlux, 00130 Real a_scale, 00131 const DataIndex& a_coarseDataIndex, 00132 const Interval& a_srcInterval, 00133 const Interval& a_dstInterval); 00134 00135 /// 00136 /** 00137 increments the register with data from fineFlux (which is edge-centered 00138 in 3d, node-centered in 2d), multiplied by scale, for all coarse-fine 00139 face directions associated with the grid box m_fineLayout[fineDataIndex] 00140 This operation is local. 00141 */ 00142 void incrementFine( 00143 FArrayBox& a_fineFlux, 00144 Real a_scale, 00145 const DataIndex& a_fineDataIndex, 00146 const Interval& a_srcInterval, 00147 const Interval& a_dstInterval); 00148 00149 00150 /// 00151 /** 00152 increments the register with data from fineFlux (which is edge-centered 00153 in 3d, node-centered in 2d), multiplied by scale. 00154 a_dir is the normal of the coarse-fine interface, and a_sd determines 00155 whether we're looking at the high-side or the low-side 00156 for the grid box m_fineLayout[fineDataIndex] 00157 This operation is local. 00158 */ 00159 void incrementFine( 00160 FArrayBox& a_fineFlux, 00161 Real a_scale, 00162 const DataIndex& a_fineDataIndex, 00163 const Interval& a_srcInterval, 00164 const Interval& a_dstInterval, 00165 int a_dir, 00166 Side::LoHiSide a_sd); 00167 00168 /// 00169 /** 00170 increments uCoarse with the reflux "CURL" of the 00171 contents of the flux register. 00172 Note that there is no srccomp etc here. 00173 this is done for all components so uCoarse has 00174 to have the same number of components as input nComp. 00175 This operation is global and blocking. 00176 */ 00177 void refluxCurl( 00178 LevelData<FluxBox>& a_uCoarse, 00179 Real a_scale); 00180 00181 /// 00182 /** 00183 has full define function been called? return true if so. 00184 */ 00185 bool isDefined() const; 00186 00187 //write the contents of all the registers 00188 void dump(); 00189 00190 //spew the contents of all the low coar registers 00191 void dumpLoCoar(int idir); 00192 00193 //spew the contents of all the high coar registers 00194 void dumpHiCoar(int idir); 00195 00196 //spew the contents of all the low fine registers 00197 void dumpLoFine(int idir); 00198 00199 //spew the contents of all the high fine registers 00200 void dumpHiFine(int idir); 00201 protected: 00202 00203 static int index(int dir, Side::LoHiSide side); 00204 00205 static int getRegComp(const int& faceDir, const int& edgeDir); 00206 00207 //internal use only 00208 void setDefaultValues(); 00209 00210 // both fabCoarse and fabFine have FluxBoxes that are 00211 // defined in the coarse index space. fabCoarse 00212 // can ONLY be indexed into by the DataIndex stored in 00213 // coarToCoarMap. fabFine is indexed by the same indexing 00214 // used in the fine DisjointBoxLayout. 00215 LevelData<EdgeDataBox> m_regCoarse; 00216 LevelData<FluxBox> m_fabFine[SpaceDim*2]; 00217 00218 // in an attempt to speed things up in the periodic case especially, 00219 // precompute copiers used to copy from fabFine to coarse-level-indexed 00220 // fabs 00221 Vector<Copier> m_crseCopiers; 00222 00223 /**: reflux locations -- need SpaceDim of these to account 00224 for the different face directions, which explains the extra 00225 Vector */ 00226 LayoutData<Vector<Vector<IntVectSet> > > m_refluxLocations[SpaceDim*2]; 00227 LayoutData<Vector<DataIndex> > m_coarToCoarMap[SpaceDim*2]; 00228 00229 bool m_isDefined; 00230 00231 ///number of components in register 00232 int m_nComp; 00233 00234 ///refinement ratio between levels 00235 int m_nRefine; 00236 00237 /// domain at the coarse grid resolution 00238 ProblemDomain m_domainCoarse; 00239 00240 private: 00241 00242 ///there is no operator= for this class 00243 void operator= (const LevelFluxRegisterEdge&); 00244 ///there is no copy constructor for this class 00245 LevelFluxRegisterEdge(const LevelFluxRegisterEdge&); 00246 }; 00247 00248 #include "NamespaceFooter.H" 00249 00250 #endif