00001 #ifdef CH_LANG_CC
00002
00003
00004
00005
00006
00007
00008
00009 #endif
00010
00011 #ifndef _MINIMALCCCMIMPLEM_H_
00012 #define _MINIMALCCCMIMPLEM_H_
00013
00014 #include <cmath>
00015 #include <cstdio>
00016 #include <cstdlib>
00017 #include <fstream>
00018 #include <iostream>
00019 #include <iomanip>
00020 #include <string>
00021
00022 #include "MayDay.H"
00023
00024 #include "NoRefinement.H"
00025 #include "LSProblem.H"
00026 #include "Factorial.H"
00027 #include "NamespaceHeader.H"
00028
00029
00030 template <int dim> MinimalCCCM<dim>::MinimalCCCM()
00031 {
00032 }
00033
00034
00035 template <int dim> MinimalCCCM<dim>::MinimalCCCM(const MinimalCCCM<dim>& a_MinimalCCCM)
00036 :m_cutCellMoments(a_MinimalCCCM.m_cutCellMoments)
00037 {
00038 }
00039
00040
00041 template <int dim> MinimalCCCM<dim>::MinimalCCCM(const IFData<dim>& a_info)
00042 :m_cutCellMoments(a_info)
00043 {
00044 m_cutCellMoments.m_bdCCOn = false;
00045
00046 for (int hilo = 0; hilo < 2; ++hilo)
00047 {
00048 for (int idir = 0; idir < dim; ++idir)
00049 {
00050
00051 Iv2 bdId;
00052 bdId[BDID_DIR] = idir;
00053 bdId[BDID_HILO] = hilo;
00054
00055 IFData<dim-1> reducedInfo(a_info,a_info.m_maxOrder+1,idir,hilo);
00056
00057 CutCellMoments<dim-1>bdCutCellMoments(reducedInfo);
00058
00059 m_cutCellMoments.m_bdCutCellMoments[bdId] = bdCutCellMoments;
00060
00061
00062
00063
00064 if (reducedInfo.m_allVerticesOn)
00065 {
00066 m_cutCellMoments.m_bdCCOn = true;
00067 }
00068 }
00069 }
00070 }
00071
00072
00073 template <int dim> MinimalCCCM<dim>::~MinimalCCCM()
00074 {
00075 }
00076
00077
00078
00079 template <int dim> void MinimalCCCM<dim>::computeMoments(const int & a_orderPmax,
00080 const int & a_degreePmax)
00081 {
00082 CH_TIME("computemoments");
00083 int zerothOrderOfAccuracy = 0;
00084 int highestDegree = a_orderPmax + a_degreePmax;
00085
00086 Vector<Real> RNorm(3);
00087 for (int i = 0; i < 3; i++)
00088 {
00089 RNorm[i] = LARGEREALVAL;
00090 }
00091
00092 for (int i = 0; i <= highestDegree; i++)
00093 {
00094 m_cutCellMoments.m_residual.push_back(RNorm);
00095 }
00096
00097 m_boundaryMomentsComputed = false;
00098
00099 computeMomentsRecursively(zerothOrderOfAccuracy,
00100 highestDegree);
00101
00102 IndexTM<int,dim> refineInDir;
00103
00104
00105 IndexTM<Real,dim> delta = m_cutCellMoments.m_IFData.m_parentCoord.m_origin;
00106 delta -= m_cutCellMoments.m_IFData.m_localCoord .m_origin;
00107
00108 PthMoment copyMoments = m_cutCellMoments.m_moments;
00109 for (typename PthMoment::const_iterator it = copyMoments.begin();
00110 it != copyMoments.end(); ++it)
00111 {
00112 IvDim mono = it->first;
00113 m_cutCellMoments.m_moments[mono] = m_cutCellMoments.changeMomentCoordinates(copyMoments, mono, delta);
00114 }
00115
00116 PthMoment copyEBMoments = m_cutCellMoments.m_EBmoments;
00117 for (typename PthMoment::const_iterator it = copyEBMoments.begin(); it != copyEBMoments.end(); ++it)
00118 {
00119 IvDim mono = it->first;
00120 m_cutCellMoments.m_EBmoments[mono] = m_cutCellMoments.changeMomentCoordinates(copyEBMoments, mono, delta);
00121 }
00122
00123
00124
00125
00126 for (typename BdCutCellMoments::iterator it = m_cutCellMoments.m_bdCutCellMoments.begin(); it != m_cutCellMoments.m_bdCutCellMoments.end(); ++it)
00127 {
00128 it->second.changeMomentCoordinatesToCellCenter();
00129 }
00130 }
00131
00132 template <int dim> void MinimalCCCM<dim>::computeMomentsRecursively(const int & a_orderPmax,
00133 const int & a_degreePmax)
00134 {
00135 CH_TIME("computemomentsRecursively");
00136
00137
00138
00139 CH_assert(m_cutCellMoments.m_IFData.m_maxOrder >= a_orderPmax);
00140
00141 if (m_cutCellMoments.m_IFData.m_allVerticesOut)
00142 {
00143 for (int iOrder = 0; iOrder <= a_orderPmax; ++iOrder)
00144 {
00145 LSProblem<dim> lsp(iOrder + a_degreePmax, false);
00146
00147
00148 const PthMomentLoc monDegreeP = lsp.getMonomialLocMapDegreeP();
00149 for (typename PthMomentLoc::const_iterator it = monDegreeP.begin(); it != monDegreeP.end(); ++it)
00150 {
00151 m_cutCellMoments.m_EBmoments[it->first] = 0.0;
00152 }
00153
00154 const PthMomentLoc monDegreePLess1 = lsp.getMonomialLocMapDegreePLess1();
00155 for (typename PthMomentLoc::const_iterator it = monDegreePLess1.begin(); it != monDegreePLess1.end(); ++it)
00156 {
00157 m_cutCellMoments.m_moments[it->first] = 0.0;
00158 }
00159 }
00160 }
00161 else if (m_cutCellMoments.m_IFData.m_allVerticesIn && !m_cutCellMoments.m_bdCCOn)
00162 {
00163 for (int iOrder = 0; iOrder <= a_orderPmax; ++iOrder)
00164 {
00165 LSProblem<dim> lsp(iOrder + a_degreePmax, false);
00166
00167
00168 const PthMomentLoc monDegreeP = lsp.getMonomialLocMapDegreeP();
00169 for (typename PthMomentLoc::const_iterator it = monDegreeP.begin(); it != monDegreeP.end(); ++it)
00170 {
00171 m_cutCellMoments.m_EBmoments[it->first] = 0.0;
00172 }
00173
00174 const PthMomentLoc monDegreePLess1 = lsp.getMonomialLocMapDegreePLess1();
00175 for (typename PthMomentLoc::const_iterator it = monDegreePLess1.begin(); it != monDegreePLess1.end(); ++it)
00176 {
00177 m_cutCellMoments.m_moments[it->first] = m_cutCellMoments.fullCellQuadrature(it->first,m_cutCellMoments.m_IFData.m_parentCoord);
00178 }
00179 }
00180 }
00181 else
00182 {
00183
00184
00185 if (!m_boundaryMomentsComputed)
00186 {
00187 for (typename BdCutCellMoments::iterator it = m_cutCellMoments.m_bdCutCellMoments.begin(); it != m_cutCellMoments.m_bdCutCellMoments.end(); ++it)
00188 {
00189 MinimalCCCM<dim-1> subProblem(it->second.m_IFData);
00190 subProblem.computeMoments(a_orderPmax,a_degreePmax+1);
00191 it->second = subProblem.m_cutCellMoments;
00192 }
00193
00194 m_boundaryMomentsComputed = true;
00195 }
00196
00197
00198 IvDim zeroDerivative = IndexTM<int,dim>::Zero;
00199 LSProblem<dim> lsp(a_orderPmax,a_degreePmax, false,m_cutCellMoments.m_IFData.m_normalDerivatives[zeroDerivative]);
00200
00201 Vector<Real> rhs = computeRhs(lsp,a_orderPmax);
00202
00203
00204 int lsCode=lsp.invertNormalEq(rhs,m_cutCellMoments.m_residual[a_degreePmax]);
00205 if (lsCode != 0)
00206 {
00207 pout() << "Geometry generation least squares problem failed with residual:"
00208 << m_cutCellMoments.m_residual[a_degreePmax]<< endl;
00209 lsp.print(pout());
00210 pout () << "Problem occurred generating geometry for these cut cell moments: " << m_cutCellMoments << endl;
00211 MayDay::Error("Geometry generation error.[2]");
00212 }
00213
00214
00215
00216 const PthMomentLoc monDegreePLess1 = lsp.getMonomialLocMapDegreePLess1();
00217 for (typename PthMomentLoc::const_iterator it = monDegreePLess1.begin();
00218 it != monDegreePLess1.end(); ++it)
00219 {
00220 m_cutCellMoments.m_moments[it->first] = lsp.getUnknown(it->second + lsp.getNumberDegP());
00221 }
00222
00223 const PthMomentLoc monDegreeP = lsp.getMonomialLocMapDegreeP();
00224 for (typename PthMomentLoc::const_iterator it = monDegreeP.begin(); it != monDegreeP.end(); ++it)
00225 {
00226 m_cutCellMoments.m_EBmoments[it->first] = lsp.getUnknown(it->second);
00227 }
00228
00229 }
00230
00231 if (a_degreePmax > 0)
00232 {
00233 computeMomentsRecursively(a_orderPmax + 1,
00234 a_degreePmax - 1);
00235 }
00236 }
00237
00238 template <int dim> Vector<Real> MinimalCCCM<dim>::computeRhs(LSProblem<dim> & a_lsp,
00239 const int & a_orderPmax)
00240 {
00241 CH_TIME("computeRHS");
00242
00243 int numEq = dim*a_lsp.getNumberDegP();
00244 Vector<Real> rhs(numEq);
00245
00246
00247
00248 const LocPthMoment& locMap = a_lsp.getLocMonomialMapDegreeP();
00249 for (typename LocPthMoment::const_iterator it = locMap.begin(); it != locMap.end(); ++it)
00250 {
00251 int jth = it->first;
00252 IvDim mono = it->second;
00253
00254 int hiSide = 1;
00255 int loSide = 0;
00256 Iv2 bdId;
00257
00258 for (int idir = 0; idir < dim; ++idir)
00259 {
00260
00261 IndexTM<int,dim-1> mono1Less;
00262 for (int jdir = 0; jdir < dim; ++jdir)
00263 {
00264 if (jdir < idir)
00265 {
00266 mono1Less[jdir] = mono[jdir];
00267 }
00268 else if (jdir > idir)
00269 {
00270 mono1Less[jdir-1] = mono[jdir];
00271 }
00272 }
00273
00274 bdId[0] = idir;
00275 bdId[1] = hiSide;
00276
00277 Real hiMom = m_cutCellMoments.m_bdCutCellMoments[bdId].m_moments[mono1Less];
00278
00279 bdId[1] = loSide;
00280
00281 Real loMom = m_cutCellMoments.m_bdCutCellMoments[bdId].m_moments[mono1Less];
00282 int exponent = it->second[idir];
00283
00284 Real loSideValue;
00285 Real hiSideValue;
00286
00287 loSideValue = m_cutCellMoments.m_IFData.m_localCoord.convertDir(-0.5*m_cutCellMoments.m_IFData.m_cellCenterCoord.m_dx[idir],
00288 m_cutCellMoments.m_IFData.m_cellCenterCoord,
00289 idir);
00290
00291 hiSideValue = m_cutCellMoments.m_IFData.m_localCoord.convertDir( 0.5*m_cutCellMoments.m_IFData.m_cellCenterCoord.m_dx[idir],
00292 m_cutCellMoments.m_IFData.m_cellCenterCoord,
00293 idir);
00294
00295 Real loFactor = POW(loSideValue,exponent);
00296 Real hiFactor = POW(hiSideValue,exponent);
00297
00298 rhs[(dim*jth) + idir] = hiMom*hiFactor - loMom*loFactor;
00299
00300
00301 for (int order = 1; order <= a_orderPmax; order++)
00302 {
00303 Vector<IvDim> taylorMonomials;
00304
00305 generateMultiIndices(taylorMonomials,order);
00306
00307 for (int i = 0; i < taylorMonomials.size(); i++)
00308 {
00309 const IvDim & taylorMonomial = taylorMonomials[i];
00310
00311 IvDim totalMonomial = mono + taylorMonomial;
00312
00313 if (m_cutCellMoments.m_EBmoments.find(totalMonomial) !=
00314 m_cutCellMoments.m_EBmoments.end())
00315 {
00316 Real normalDerivative = m_cutCellMoments.m_IFData.m_normalDerivatives[taylorMonomial][idir];
00317 Real fact = factorial(taylorMonomial);
00318
00319 Real moment = m_cutCellMoments.m_EBmoments[totalMonomial];
00320
00321 rhs[(dim*jth) + idir] += normalDerivative * moment / fact;
00322 }
00323 else
00324 {
00325 MayDay::Error("Unable to find needed monomial for Taylor series");
00326 }
00327 }
00328 }
00329 }
00330 }
00331
00332 return rhs;
00333 }
00334 template <int dim> void MinimalCCCM<dim>::print(ostream& a_out) const
00335 {
00336 m_cutCellMoments.print(a_out);
00337 }
00338
00339 template <int dim> void MinimalCCCM<dim>::dump() const
00340 {
00341 print(pout());
00342 }
00343
00344
00345 template <int dim> void MinimalCCCM<dim>::operator=(const MinimalCCCM<dim> & a_MinimalCCCM)
00346 {
00347
00348 if (this != &a_MinimalCCCM)
00349 {
00350 m_cutCellMoments = a_MinimalCCCM.m_cutCellMoments;
00351 }
00352 }
00353
00354 template <int dim> ostream& operator<<(ostream & a_out,
00355 const MinimalCCCM<dim> & a_MinimalCCCM)
00356 {
00357 a_MinimalCCCM.print(a_out);
00358 return a_out;
00359 }
00360
00361 template <int dim> Real MinimalCCCM<dim>::factorial(const IvDim & a_multiIndex) const
00362 {
00363 Real fact = 1.0;
00364
00365 for (int i = 0; i < dim; i++)
00366 {
00367 for (int j = 2; j <= a_multiIndex[i]; j++)
00368 {
00369 fact *= j;
00370 }
00371 }
00372
00373 return fact;
00374 }
00375
00376 #include "NamespaceFooter.H"
00377
00378 #endif