00001 #ifdef CH_LANG_CC
00002
00003
00004
00005
00006
00007
00008
00009 #endif
00010
00011 #ifndef _COMPUTECUTCELLMOMENTSIMPLEM_H_
00012 #define _COMPUTECUTCELLMOMENTSIMPLEM_H_
00013
00014 #if defined(CH_Darwin) && defined(__GNUC__) && ( __GNUC__ == 3 )
00015
00016 #include <unistd.h>
00017 #define _GLIBCPP_USE_C99 1
00018 #endif
00019
00020 #include <cmath>
00021 #include <cstdio>
00022 #include <cstdlib>
00023 #include <fstream>
00024 #include <iostream>
00025 #include <iomanip>
00026 #include <string>
00027
00028 #include "MayDay.H"
00029
00030 #include "NoRefinement.H"
00031 #include "LSProblem.H"
00032
00033 #include "NamespaceHeader.H"
00034
00035
00036 template <int dim> ComputeCutCellMoments<dim>::ComputeCutCellMoments()
00037 {
00038 }
00039
00040
00041 template <int dim> ComputeCutCellMoments<dim>::ComputeCutCellMoments(const ComputeCutCellMoments<dim>& a_computeCutCellMoments)
00042 :m_cutCellMoments(a_computeCutCellMoments.m_cutCellMoments)
00043 {
00044 }
00045
00046
00047 template <int dim> ComputeCutCellMoments<dim>::ComputeCutCellMoments(const IFData<dim>& a_info)
00048 :m_cutCellMoments(a_info)
00049 {
00050 m_cutCellMoments.m_bdCCOn = false;
00051
00052 for (int hilo = 0; hilo < 2; ++hilo)
00053 {
00054 for (int idir = 0; idir < dim; ++idir)
00055 {
00056
00057 Iv2 bdId;
00058 bdId[BDID_DIR] = idir;
00059 bdId[BDID_HILO] = hilo;
00060
00061 #if RECURSIVE_GEOMETRY_GENERATION == 0
00062 IFData<dim-1> reducedInfo(a_info,idir,hilo);
00063 #else
00064 IFData<dim-1> reducedInfo(a_info,a_info.m_maxOrder+1,idir,hilo);
00065 #endif
00066 CutCellMoments<dim-1>bdCutCellMoments(reducedInfo);
00067
00068 m_cutCellMoments.m_bdCutCellMoments[bdId] = bdCutCellMoments;
00069
00070
00071
00072
00073 if (reducedInfo.m_allVerticesOn)
00074 {
00075 m_cutCellMoments.m_bdCCOn = true;
00076 }
00077 }
00078 }
00079 }
00080
00081
00082 template <int dim> ComputeCutCellMoments<dim>::~ComputeCutCellMoments()
00083 {
00084 }
00085
00086 #if RECURSIVE_GEOMETRY_GENERATION == 0
00087 template <int dim> void ComputeCutCellMoments<dim>::computeMoments(const int & a_order,
00088 const int & a_degreeP,
00089 const bool & a_useConstraints,
00090 RefinementCriterion<dim> & a_refinementCriterion,
00091 const int & a_numberOfRefinements)
00092 {
00093 CH_assert(m_cutCellMoments.m_IFData.m_maxOrder >= a_order);
00094
00095 Vector<Real> RNorm(3);
00096 for (int i = 0; i < 3; i++)
00097 {
00098 RNorm[i] = LARGEREALVAL;
00099 }
00100
00101 for (int i = 0; i < a_degreeP + 1; i++)
00102 {
00103 m_cutCellMoments.m_residual.push_back(RNorm);
00104 }
00105
00106 if (m_cutCellMoments.m_IFData.m_allVerticesOut)
00107 {
00108 for (int iDegree = a_degreeP; iDegree >= 0; --iDegree)
00109 {
00110 LSProblem<dim> lsp(iDegree,a_useConstraints);
00111
00112
00113 const PthMomentLoc monDegreeP = lsp.getMonomialLocMapDegreeP();
00114 for (typename PthMomentLoc::const_iterator it = monDegreeP.begin(); it != monDegreeP.end(); ++it)
00115 {
00116 m_cutCellMoments.m_EBmoments[it->first] = 0.0;
00117 }
00118
00119 const PthMomentLoc monDegreePLess1 = lsp.getMonomialLocMapDegreePLess1();
00120 for (typename PthMomentLoc::const_iterator it = monDegreePLess1.begin(); it != monDegreePLess1.end(); ++it)
00121 {
00122 m_cutCellMoments.m_moments[it->first] = 0.0;
00123 }
00124 }
00125 }
00126 else if (m_cutCellMoments.m_IFData.m_allVerticesIn && !m_cutCellMoments.m_bdCCOn)
00127 {
00128 for (int iDegree = a_degreeP; iDegree >= 0; --iDegree)
00129 {
00130 LSProblem<dim> lsp(iDegree,a_useConstraints);
00131
00132
00133 const PthMomentLoc monDegreeP = lsp.getMonomialLocMapDegreeP();
00134 for (typename PthMomentLoc::const_iterator it = monDegreeP.begin(); it != monDegreeP.end(); ++it)
00135 {
00136 m_cutCellMoments.m_EBmoments[it->first] = 0.0;
00137 }
00138
00139 const PthMomentLoc monDegreePLess1 = lsp.getMonomialLocMapDegreePLess1();
00140 for (typename PthMomentLoc::const_iterator it = monDegreePLess1.begin(); it != monDegreePLess1.end(); ++it)
00141 {
00142 m_cutCellMoments.m_moments[it->first] = m_cutCellMoments.fullCellQuadrature(it->first,m_cutCellMoments.m_IFData.m_parentCoord);
00143 }
00144 }
00145 }
00146 else
00147 {
00148 for (typename BdCutCellMoments::iterator it = m_cutCellMoments.m_bdCutCellMoments.begin(); it != m_cutCellMoments.m_bdCutCellMoments.end(); ++it)
00149 {
00150 NoRefinement<dim-1> noRefinement;
00151
00152 ComputeCutCellMoments<dim-1> subProblem(it->second.m_IFData);
00153 subProblem.computeMoments(a_order,a_degreeP+1,a_useConstraints,noRefinement);
00154 it->second = subProblem.m_cutCellMoments;
00155
00156 }
00157
00158 for (int iDegree = a_degreeP; iDegree >= 0; --iDegree)
00159 {
00160
00161 IvDim zeroDerivative = IndexTM<int,dim>::Zero;
00162 LSProblem<dim> lsp(a_order,iDegree,a_useConstraints,m_cutCellMoments.m_IFData.m_normalDerivatives[zeroDerivative]);
00163
00164 Vector<Real> rhs = computeRhs(lsp,a_order);
00165
00166 if (a_useConstraints)
00167 {
00168 lsp.computeBounds(m_cutCellMoments.m_IFData.m_globalCoord.m_dx,m_cutCellMoments);
00169 }
00170
00171
00172
00173 int lsCode = lsp.invertNormalEq(rhs,m_cutCellMoments.m_residual[iDegree]);
00174 if (lsCode != 0)
00175 {
00176 pout() << "Geometry generation least squares problem failed with residual: "
00177 << m_cutCellMoments.m_residual[iDegree]<< endl;
00178 lsp.print(pout());
00179
00180 pout () << endl << "Problem occurred generating geometry for these cut cell moments:\n"
00181 << m_cutCellMoments << endl;
00182
00183
00184 bool status = false;
00185 a_refinementCriterion.setConstrantSuccessStatus(status);
00186 }
00187
00188
00189 m_cutCellMoments.m_numActiveBounds += lsp.numActiveBounds();
00190
00191
00192
00193
00194
00195
00196
00197 const PthMomentLoc monDegreePLess1 = lsp.getMonomialLocMapDegreePLess1();
00198 for (typename PthMomentLoc::const_iterator it = monDegreePLess1.begin();
00199 it != monDegreePLess1.end(); ++it)
00200 {
00201 m_cutCellMoments.m_moments[it->first] = lsp.getUnknown(it->second + lsp.getNumberDegP());
00202 }
00203
00204 const PthMomentLoc monDegreeP = lsp.getMonomialLocMapDegreeP();
00205 for (typename PthMomentLoc::const_iterator it = monDegreeP.begin(); it != monDegreeP.end(); ++it)
00206 {
00207 m_cutCellMoments.m_EBmoments[it->first] = lsp.getUnknown(it->second);
00208 }
00209 }
00210
00211
00212 IndexTM<Real,dim> delta = m_cutCellMoments.m_IFData.m_parentCoord.m_origin;
00213 delta -= m_cutCellMoments.m_IFData.m_localCoord .m_origin;
00214
00215 PthMoment copyMoments = m_cutCellMoments.m_moments;
00216 for (typename PthMoment::const_iterator it = copyMoments.begin();
00217 it != copyMoments.end(); ++it)
00218 {
00219 IvDim mono = it->first;
00220 m_cutCellMoments.m_moments[mono] = m_cutCellMoments.changeMomentCoordinates(copyMoments, mono, delta);
00221 }
00222
00223 PthMoment copyEBMoments = m_cutCellMoments.m_EBmoments;
00224 for (typename PthMoment::const_iterator it = copyEBMoments.begin(); it != copyEBMoments.end(); ++it)
00225 {
00226 IvDim mono = it->first;
00227 m_cutCellMoments.m_EBmoments[mono] = m_cutCellMoments.changeMomentCoordinates(copyEBMoments, mono, delta);
00228 }
00229
00230
00231
00232
00233 for (typename BdCutCellMoments::iterator it = m_cutCellMoments.m_bdCutCellMoments.begin(); it != m_cutCellMoments.m_bdCutCellMoments.end(); ++it)
00234 {
00235 it->second.changeMomentCoordinatesToCellCenter();
00236 }
00237 }
00238
00239 IndexTM<int,dim> refineInDir;
00240
00241 if (!m_cutCellMoments.isCovered() && !m_cutCellMoments.isRegular() && a_refinementCriterion.baseDoRefine(refineInDir,m_cutCellMoments,a_numberOfRefinements))
00242 {
00243
00244
00245 Vector<CutCellMoments<dim> > refinedCCMoms = refine(a_order,a_degreeP,a_useConstraints,a_refinementCriterion,refineInDir,a_numberOfRefinements);
00246
00247
00248
00249 addMomentMaps(refinedCCMoms,a_degreeP,a_useConstraints);
00250
00251
00252 computeResiduals(refinedCCMoms,a_degreeP);
00253
00254
00255
00256 IndexTM<Real,dim> delta = m_cutCellMoments.m_IFData.m_parentCoord .m_origin;
00257 delta -= m_cutCellMoments.m_IFData.m_cellCenterCoord.m_origin;
00258
00259 PthMoment copyMoments = m_cutCellMoments.m_moments;
00260 for (typename PthMoment::const_iterator it = copyMoments.begin();
00261 it != copyMoments.end(); ++it)
00262 {
00263 IvDim mono = it->first;
00264 m_cutCellMoments.m_moments[mono] = m_cutCellMoments.changeMomentCoordinates(copyMoments, mono, delta);
00265 }
00266
00267 PthMoment copyEBMoments = m_cutCellMoments.m_EBmoments;
00268 for (typename PthMoment::const_iterator it = copyEBMoments.begin(); it != copyEBMoments.end(); ++it)
00269 {
00270 IvDim mono = it->first;
00271 m_cutCellMoments.m_EBmoments[mono] = m_cutCellMoments.changeMomentCoordinates(copyEBMoments, mono, delta);
00272 }
00273 }
00274 }
00275 #else
00276
00277 template <int dim> void ComputeCutCellMoments<dim>::computeMoments(const int & a_orderPmax,
00278 const int & a_degreePmax,
00279 const bool & a_useConstraints,
00280 RefinementCriterion<dim> & a_refinementCriterion,
00281 const int & a_numberOfRefinements)
00282 {
00283 int zerothOrderOfAccuracy = 0;
00284 int highestDegree = a_orderPmax + a_degreePmax;
00285
00286 Vector<Real> RNorm(3);
00287 for (int i = 0; i < 3; i++)
00288 {
00289 RNorm[i] = LARGEREALVAL;
00290 }
00291
00292 for (int i = 0; i <= highestDegree; i++)
00293 {
00294 m_cutCellMoments.m_residual.push_back(RNorm);
00295 }
00296
00297 m_boundaryMomentsComputed = false;
00298
00299 computeMomentsRecursively(zerothOrderOfAccuracy,
00300 highestDegree,
00301 a_useConstraints,
00302 a_refinementCriterion,
00303 a_numberOfRefinements);
00304
00305 IndexTM<int,dim> refineInDir;
00306
00307 if (!m_cutCellMoments.isCovered() && !m_cutCellMoments.isRegular() && a_refinementCriterion.doRefine(refineInDir,m_cutCellMoments,a_numberOfRefinements))
00308 {
00309
00310
00311 Vector<CutCellMoments<dim> > refinedCCMoms = refine(a_orderPmax,a_degreePmax,a_useConstraints,a_refinementCriterion,refineInDir,a_numberOfRefinements);
00312
00313
00314
00315 addMomentMaps(refinedCCMoms,a_degreePmax,a_useConstraints);
00316
00317
00318 computeResiduals(refinedCCMoms,a_degreePmax);
00319
00320
00321 IndexTM<Real,dim> delta = m_cutCellMoments.m_IFData.m_parentCoord.m_origin;
00322 delta -= m_cutCellMoments.m_IFData.m_cellCenterCoord .m_origin;
00323
00324 PthMoment copyMoments = m_cutCellMoments.m_moments;
00325 for (typename PthMoment::const_iterator it = copyMoments.begin();
00326 it != copyMoments.end(); ++it)
00327 {
00328 IvDim mono = it->first;
00329 m_cutCellMoments.m_moments[mono] = m_cutCellMoments.changeMomentCoordinates(copyMoments, mono, delta);
00330 }
00331
00332 PthMoment copyEBMoments = m_cutCellMoments.m_EBmoments;
00333 for (typename PthMoment::const_iterator it = copyEBMoments.begin(); it != copyEBMoments.end(); ++it)
00334 {
00335 IvDim mono = it->first;
00336 m_cutCellMoments.m_EBmoments[mono] = m_cutCellMoments.changeMomentCoordinates(copyEBMoments, mono, delta);
00337 }
00338
00339
00340
00341
00342 for (typename BdCutCellMoments::iterator it = m_cutCellMoments.m_bdCutCellMoments.begin(); it != m_cutCellMoments.m_bdCutCellMoments.end(); ++it)
00343 {
00344 it->second.changeMomentCoordinatesToCellCenter();
00345 }
00346 }
00347
00348
00349 IndexTM<Real,dim> delta = m_cutCellMoments.m_IFData.m_parentCoord.m_origin;
00350 delta -= m_cutCellMoments.m_IFData.m_localCoord .m_origin;
00351
00352 PthMoment copyMoments = m_cutCellMoments.m_moments;
00353 for (typename PthMoment::const_iterator it = copyMoments.begin();
00354 it != copyMoments.end(); ++it)
00355 {
00356 IvDim mono = it->first;
00357 m_cutCellMoments.m_moments[mono] = m_cutCellMoments.changeMomentCoordinates(copyMoments, mono, delta);
00358 }
00359
00360 PthMoment copyEBMoments = m_cutCellMoments.m_EBmoments;
00361 for (typename PthMoment::const_iterator it = copyEBMoments.begin(); it != copyEBMoments.end(); ++it)
00362 {
00363 IvDim mono = it->first;
00364 m_cutCellMoments.m_EBmoments[mono] = m_cutCellMoments.changeMomentCoordinates(copyEBMoments, mono, delta);
00365 }
00366 }
00367
00368 template <int dim> void ComputeCutCellMoments<dim>::computeMomentsRecursively(const int & a_orderPmax,
00369 const int & a_degreePmax,
00370 const bool & a_useConstraints,
00371 RefinementCriterion<dim> & a_refinementCriterion,
00372 const int & a_numberOfRefinements)
00373 {
00374 CH_assert(m_cutCellMoments.m_IFData.m_maxOrder >= a_orderPmax);
00375
00376 if (m_cutCellMoments.m_IFData.m_allVerticesOut)
00377 {
00378 for (int iOrder = 0; iOrder <= a_orderPmax; ++iOrder)
00379 {
00380 LSProblem<dim> lsp(iOrder + a_degreePmax, a_useConstraints);
00381
00382
00383 const PthMomentLoc monDegreeP = lsp.getMonomialLocMapDegreeP();
00384 for (typename PthMomentLoc::const_iterator it = monDegreeP.begin(); it != monDegreeP.end(); ++it)
00385 {
00386 m_cutCellMoments.m_EBmoments[it->first] = 0.0;
00387 }
00388
00389 const PthMomentLoc monDegreePLess1 = lsp.getMonomialLocMapDegreePLess1();
00390 for (typename PthMomentLoc::const_iterator it = monDegreePLess1.begin(); it != monDegreePLess1.end(); ++it)
00391 {
00392 m_cutCellMoments.m_moments[it->first] = 0.0;
00393 }
00394 }
00395 }
00396 else if (m_cutCellMoments.m_IFData.m_allVerticesIn && !m_cutCellMoments.m_bdCCOn)
00397 {
00398 for (int iOrder = 0; iOrder <= a_orderPmax; ++iOrder)
00399 {
00400 LSProblem<dim> lsp(iOrder + a_degreePmax, a_useConstraints);
00401
00402
00403 const PthMomentLoc monDegreeP = lsp.getMonomialLocMapDegreeP();
00404 for (typename PthMomentLoc::const_iterator it = monDegreeP.begin(); it != monDegreeP.end(); ++it)
00405 {
00406 m_cutCellMoments.m_EBmoments[it->first] = 0.0;
00407 }
00408
00409 const PthMomentLoc monDegreePLess1 = lsp.getMonomialLocMapDegreePLess1();
00410 for (typename PthMomentLoc::const_iterator it = monDegreePLess1.begin(); it != monDegreePLess1.end(); ++it)
00411 {
00412 m_cutCellMoments.m_moments[it->first] = m_cutCellMoments.fullCellQuadrature(it->first,m_cutCellMoments.m_IFData.m_parentCoord);
00413 }
00414 }
00415 }
00416 else
00417 {
00418
00419
00420 if (!m_boundaryMomentsComputed)
00421 {
00422 for (typename BdCutCellMoments::iterator it = m_cutCellMoments.m_bdCutCellMoments.begin(); it != m_cutCellMoments.m_bdCutCellMoments.end(); ++it)
00423 {
00424 NoRefinement<dim-1> noRefinement;
00425
00426 ComputeCutCellMoments<dim-1> subProblem(it->second.m_IFData);
00427 subProblem.computeMoments(a_orderPmax,a_degreePmax+1,a_useConstraints,noRefinement);
00428 it->second = subProblem.m_cutCellMoments;
00429 }
00430
00431 m_boundaryMomentsComputed = true;
00432 }
00433
00434
00435 IvDim zeroDerivative = IndexTM<int,dim>::Zero;
00436 LSProblem<dim> lsp(a_orderPmax,a_degreePmax,a_useConstraints,m_cutCellMoments.m_IFData.m_normalDerivatives[zeroDerivative]);
00437
00438 Vector<Real> rhs = computeRhs(lsp,a_orderPmax);
00439
00440 if (a_useConstraints)
00441 {
00442 lsp.computeBounds(m_cutCellMoments.m_IFData.m_globalCoord.m_dx,m_cutCellMoments);
00443 }
00444
00445
00446 int lsCode=lsp.invertNormalEq(rhs,m_cutCellMoments.m_residual[a_degreePmax]);
00447 if (lsCode != 0)
00448 {
00449 pout() << "Geometry generation least squares problem failed with residual:"
00450 << m_cutCellMoments.m_residual[a_degreePmax]<< endl;
00451 lsp.print(pout());
00452 pout () << "Problem occurred generating geometry for these cut cell moments: " << m_cutCellMoments << endl;
00453 MayDay::Error("Geometry generation error.[2]");
00454 }
00455
00456
00457
00458 const PthMomentLoc monDegreePLess1 = lsp.getMonomialLocMapDegreePLess1();
00459 for (typename PthMomentLoc::const_iterator it = monDegreePLess1.begin();
00460 it != monDegreePLess1.end(); ++it)
00461 {
00462 m_cutCellMoments.m_moments[it->first] = lsp.getUnknown(it->second + lsp.getNumberDegP());
00463 }
00464
00465 const PthMomentLoc monDegreeP = lsp.getMonomialLocMapDegreeP();
00466 for (typename PthMomentLoc::const_iterator it = monDegreeP.begin(); it != monDegreeP.end(); ++it)
00467 {
00468 m_cutCellMoments.m_EBmoments[it->first] = lsp.getUnknown(it->second);
00469 }
00470
00471 }
00472
00473 if (a_degreePmax > 0)
00474 {
00475 computeMomentsRecursively(a_orderPmax + 1,
00476 a_degreePmax - 1,
00477 a_useConstraints,
00478 a_refinementCriterion,
00479 a_numberOfRefinements);
00480
00481 }
00482 }
00483 #endif
00484
00485 template <int dim> Vector<Real> ComputeCutCellMoments<dim>::computeRhs(LSProblem<dim> & a_lsp,
00486 #if RECURSIVE_GEOMETRY_GENERATION == 0
00487 const int & a_order)
00488 #else
00489 const int & a_orderPmax)
00490 #endif
00491 {
00492
00493 int numEq = dim*a_lsp.getNumberDegP();
00494 Vector<Real> rhs(numEq);
00495
00496
00497
00498 const LocPthMoment& locMap = a_lsp.getLocMonomialMapDegreeP();
00499 for (typename LocPthMoment::const_iterator it = locMap.begin(); it != locMap.end(); ++it)
00500 {
00501 int jth = it->first;
00502 IvDim mono = it->second;
00503
00504 int hiSide = 1;
00505 int loSide = 0;
00506 Iv2 bdId;
00507
00508 for (int idir = 0; idir < dim; ++idir)
00509 {
00510
00511 IndexTM<int,dim-1> mono1Less;
00512 for (int jdir = 0; jdir < dim; ++jdir)
00513 {
00514 if (jdir < idir)
00515 {
00516 mono1Less[jdir] = mono[jdir];
00517 }
00518 else if (jdir > idir)
00519 {
00520 mono1Less[jdir-1] = mono[jdir];
00521 }
00522 }
00523
00524 bdId[0] = idir;
00525 bdId[1] = hiSide;
00526
00527 Real hiMom = m_cutCellMoments.m_bdCutCellMoments[bdId].m_moments[mono1Less];
00528
00529 bdId[1] = loSide;
00530
00531 Real loMom = m_cutCellMoments.m_bdCutCellMoments[bdId].m_moments[mono1Less];
00532 int exponent = it->second[idir];
00533
00534 Real loSideValue;
00535 Real hiSideValue;
00536
00537 loSideValue = m_cutCellMoments.m_IFData.m_localCoord.convertDir(-0.5*m_cutCellMoments.m_IFData.m_cellCenterCoord.m_dx[idir],
00538 m_cutCellMoments.m_IFData.m_cellCenterCoord,
00539 idir);
00540
00541 hiSideValue = m_cutCellMoments.m_IFData.m_localCoord.convertDir( 0.5*m_cutCellMoments.m_IFData.m_cellCenterCoord.m_dx[idir],
00542 m_cutCellMoments.m_IFData.m_cellCenterCoord,
00543 idir);
00544
00545 Real loFactor = pow(loSideValue,exponent);
00546 Real hiFactor = pow(hiSideValue,exponent);
00547
00548 rhs[(dim*jth) + idir] = hiMom*hiFactor - loMom*loFactor;
00549
00550
00551 #if RECURSIVE_GEOMETRY_GENERATION == 0
00552 for (int order = 1; order <= a_order; order++)
00553 #else
00554 for (int order = 1; order <= a_orderPmax; order++)
00555 #endif
00556 {
00557 Vector<IvDim> taylorMonomials;
00558
00559 generateMultiIndices(taylorMonomials,order);
00560
00561 for (int i = 0; i < taylorMonomials.size(); i++)
00562 {
00563 const IvDim & taylorMonomial = taylorMonomials[i];
00564
00565 IvDim totalMonomial = mono + taylorMonomial;
00566
00567 if (m_cutCellMoments.m_EBmoments.find(totalMonomial) !=
00568 m_cutCellMoments.m_EBmoments.end())
00569 {
00570 Real normalDerivative = m_cutCellMoments.m_IFData.m_normalDerivatives[taylorMonomial][idir];
00571 Real fact = factorial(taylorMonomial);
00572
00573 Real moment = m_cutCellMoments.m_EBmoments[totalMonomial];
00574
00575 rhs[(dim*jth) + idir] += normalDerivative * moment / fact;
00576 }
00577 #if RECURSIVE_GEOMETRY_GENERATION != 0
00578 else
00579 {
00580 MayDay::Error("Unable to find needed monomial for Taylor series");
00581 }
00582 #endif
00583 }
00584 }
00585 }
00586 }
00587
00588 return rhs;
00589 }
00590
00591 #if RECURSIVE_GEOMETRY_GENERATION == 0
00592 template <int dim> Vector< CutCellMoments<dim> > ComputeCutCellMoments<dim>::refine(const int & a_order,
00593 const int & a_degreeP,
00594 #else
00595 template <int dim> Vector< CutCellMoments<dim> > ComputeCutCellMoments<dim>::refine(const int & a_orderPmax,
00596 const int & a_degreePmax,
00597 #endif
00598 const bool & a_useConstraints,
00599 RefinementCriterion<dim> & a_refinementCriterion,
00600 const IndexTM<int,dim> & a_refineInDir,
00601 const int & a_numberOfRefinements)
00602 {
00603 Vector<CutCellMoments<dim> > refinedCutCellMoments;
00604
00605
00606
00607 IndexTM<Real,dim> refinedDx = m_cutCellMoments.m_IFData.m_globalCoord.m_dx;
00608
00609
00610 IndexTM<int,dim> curIter;
00611 IndexTM<int,dim> maxIter;
00612
00613 for (int idir = 0; idir < dim; idir++)
00614 {
00615 if (a_refineInDir[idir] != 0)
00616 {
00617
00618 refinedDx[idir] /= 2.0;
00619 maxIter[idir] = 1;
00620 }
00621 else
00622 {
00623
00624 maxIter[idir] = 0;
00625 }
00626
00627
00628 curIter[idir] = 0;
00629 }
00630
00631
00632 while (1)
00633 {
00634
00635 IndexTM<Real,dim> refinedCellCenter = m_cutCellMoments.m_IFData.m_globalCoord.m_origin;
00636
00637 for (int idir = 0; idir < dim; idir++)
00638 {
00639 if (a_refineInDir[idir] != 0)
00640 {
00641 int sign = 2*curIter[idir] - 1;
00642 refinedCellCenter[idir] += sign * 0.5*refinedDx[idir];
00643 }
00644 }
00645
00646
00647
00648
00649 #if RECURSIVE_GEOMETRY_GENERATION == 0
00650 IFData<dim> refinedIFData(m_cutCellMoments.m_IFData.m_function,refinedDx,refinedCellCenter,a_order);
00651 #else
00652 IFData<dim> refinedIFData(m_cutCellMoments.m_IFData.m_function,refinedDx,refinedCellCenter,a_orderPmax);
00653 #endif
00654 #if 0
00655 pout() << "refinedIFData" << "\n";
00656 pout() << refinedIFData<<endl;
00657 #endif
00658
00659 ComputeCutCellMoments<dim> refinedComputeCCMom(refinedIFData);
00660
00661
00662 int numberOfRefinements = a_numberOfRefinements + 1;
00663
00664
00665 #if RECURSIVE_GEOMETRY_GENERATION == 0
00666 refinedComputeCCMom.computeMoments(a_order,a_degreeP,a_useConstraints,a_refinementCriterion,numberOfRefinements);
00667 #else
00668 refinedComputeCCMom.computeMoments(a_orderPmax,a_degreePmax,a_useConstraints,a_refinementCriterion,numberOfRefinements);
00669 #endif
00670 refinedCutCellMoments.push_back(refinedComputeCCMom.m_cutCellMoments);
00671
00672
00673 int idir;
00674 for (idir = 0; idir < dim; idir++)
00675 {
00676 if (curIter[idir] < maxIter[idir])
00677 {
00678
00679 curIter[idir]++;
00680 break;
00681 }
00682 else
00683 {
00684
00685
00686 curIter[idir] = 0;
00687 }
00688 }
00689
00690
00691 if (idir == dim)
00692 {
00693 break;
00694 }
00695 }
00696
00697 return refinedCutCellMoments;
00698 }
00699
00700 template <int dim> void ComputeCutCellMoments<dim>::addMomentMaps(const Vector<CutCellMoments<dim> > & a_refinedCutCellVector,
00701 #if RECURSIVE_GEOMETRY_GENERATION == 0
00702 const int & a_degreeP,
00703 #else
00704 const int & a_degreePmax,
00705 #endif
00706 const bool & a_useConstraints)
00707 {
00708 int numberOfRefinedCC = a_refinedCutCellVector.size();
00709 CH_assert(numberOfRefinedCC>0);
00710
00711 IndexTM<int,2> bdId;
00712
00713
00714
00715
00716 CutCellMoments<dim> cutCell;
00717 int k = 0;
00718
00719 while (k < numberOfRefinedCC && (a_refinedCutCellVector[k].m_IFData.m_allVerticesOut ||
00720 (a_refinedCutCellVector[k].m_IFData.m_allVerticesIn && !m_cutCellMoments.m_bdCCOn)))
00721 {
00722 k++;
00723 }
00724
00725 if (k >= numberOfRefinedCC)
00726 {
00727 MayDay::Abort("Exceeded the number of refined ComputeCutCellMoments in vector");
00728 }
00729
00730 else
00731 {
00732 cutCell = a_refinedCutCellVector[k];
00733 }
00734
00735 m_cutCellMoments.initialize(cutCell);
00736
00737
00738
00739 for (int i = 0; i < numberOfRefinedCC; i++)
00740 {
00741
00742
00743
00744 CutCellMoments<dim> refinedCutCell = a_refinedCutCellVector[i];
00745 IndexTM<int,dim> hilo = LARGEINTVAL*IndexTM<int,dim>::Unit;
00746 IndexTM<Real,dim> refinedCenterDelta = IndexTM<Real,dim>::Zero;
00747
00748 int ii = i;
00749 for (int j = 0; j < dim; ++j)
00750 {
00751 hilo[j] = (ii & 1);
00752 ii = ii >> 1;
00753 }
00754
00755 IndexTM<int,dim> sign = 2*hilo-1;
00756
00757 for (int idir = 0; idir < dim; idir++)
00758 {
00759 refinedCenterDelta[idir] = 0.25*sign[idir]*m_cutCellMoments.m_IFData.m_globalCoord.m_dx[idir];
00760 }
00761
00762
00763 addMoments(m_cutCellMoments.m_moments,refinedCutCell.m_moments,refinedCenterDelta);
00764 addMoments(m_cutCellMoments.m_EBmoments,refinedCutCell.m_EBmoments,refinedCenterDelta);
00765
00766
00767 for (int idir = 0; idir < dim; idir++)
00768 {
00769 bdId[0] = idir;
00770
00771
00772
00773
00774 IndexTM<Real,dim-1> localRefinedCenterDelta;
00775 IndexTM<int,dim-1> localHilo;
00776
00777 for (int jdir = 0; jdir < dim; jdir++)
00778 {
00779 if (jdir < idir)
00780 {
00781 localRefinedCenterDelta[jdir] = refinedCenterDelta[jdir];
00782 localHilo[jdir] = hilo[jdir];
00783 }
00784 else if (jdir > idir)
00785 {
00786 localRefinedCenterDelta[jdir-1] = refinedCenterDelta[jdir];
00787 localHilo[jdir-1] = hilo[jdir];
00788 }
00789 }
00790
00791 if (hilo[idir] != LARGEINTVAL)
00792 {
00793 bdId[1] = hilo[idir];
00794
00795
00796
00797
00798 (refinedCutCell.m_bdCutCellMoments[bdId]).addBdMoments(
00799 m_cutCellMoments.m_bdCutCellMoments[bdId],
00800 refinedCutCell.m_IFData,
00801 #if RECURSIVE_GEOMETRY_GENERATION == 0
00802 a_degreeP,
00803 #else
00804 a_degreePmax,
00805 #endif
00806 a_useConstraints,
00807 localRefinedCenterDelta,
00808 localHilo);
00809 }
00810 else
00811 {
00812 for (int side = 0; side < 2; side++)
00813 {
00814 bdId[1] = side;
00815 (refinedCutCell.m_bdCutCellMoments[bdId]).addBdMoments(
00816 m_cutCellMoments.m_bdCutCellMoments[bdId],
00817 refinedCutCell.m_IFData,
00818 #if RECURSIVE_GEOMETRY_GENERATION == 0
00819 a_degreeP+1,
00820 #else
00821 a_degreePmax+1,
00822 #endif
00823 a_useConstraints,
00824 localRefinedCenterDelta,
00825 localHilo);
00826 }
00827 }
00828 }
00829 }
00830 }
00831
00832 template <int dim> void ComputeCutCellMoments<dim>::addMoments(PthMoment & a_momentMap,
00833 PthMoment & a_refinedMomentMap,
00834 const IndexTM<Real,dim> & a_refinedCenterDelta)
00835 {
00836
00837
00838 for (typename PthMoment::const_iterator it = a_refinedMomentMap.begin(); it != a_refinedMomentMap.end(); ++it)
00839 {
00840 IndexTM<int,dim> monomial = it->first;
00841 Real moment = m_cutCellMoments.changeMomentCoordinates(a_refinedMomentMap,monomial,a_refinedCenterDelta);
00842
00843 a_momentMap[it->first] += moment;
00844 }
00845 }
00846
00847 #if RECURSIVE_GEOMETRY_GENERATION == 0
00848 template <int dim> void ComputeCutCellMoments<dim>::computeResiduals(const int & a_order,
00849 const int & a_degreeP,
00850 #else
00851 template <int dim> void ComputeCutCellMoments<dim>::computeResiduals(const int & a_orderPmax,
00852 const int & a_degreePmax,
00853 #endif
00854 const bool & a_useConstraints)
00855 {
00856 #if RECURSIVE_GEOMETRY_GENERATION == 0
00857 for (int iDegree = a_degreeP; iDegree >= 0; iDegree--)
00858 #else
00859 for (int iDegree = a_degreePmax; iDegree >= 0; iDegree--)
00860 #endif
00861 {
00862
00863 int nNorm = 3;
00864 m_cutCellMoments.m_residual[iDegree].resize(nNorm);
00865
00866 for (int i = 0; i < nNorm; i++)
00867 {
00868 m_cutCellMoments.setResidual(0.0,iDegree,i);
00869 }
00870
00871
00872 IvDim zeroDerivative = IndexTM<int,dim>::Zero;
00873 #if RECURSIVE_GEOMETRY_GENERATION == 0
00874 LSProblem<dim> lsp(a_order,iDegree,a_useConstraints,m_cutCellMoments.m_IFData.m_normalDerivatives[zeroDerivative]);
00875 #else
00876 LSProblem<dim> lsp(a_orderPmax,iDegree,a_useConstraints,m_cutCellMoments.m_IFData.m_normalDerivatives[zeroDerivative]);
00877 #endif
00878
00879
00880
00881 #if RECURSIVE_GEOMETRY_GENERATION == 0
00882 Vector<Real> rhs = computeRhs(lsp,a_order);
00883 #else
00884 Vector<Real> rhs = computeRhs(lsp,a_orderPmax);
00885 #endif
00886
00887
00888 Vector<Real> unknowns(lsp.m_numP+lsp.m_numPLess1);
00889
00890 for (typename PthMomentLoc::const_iterator it = lsp.m_monoLocP.begin(); it != lsp.m_monoLocP.end(); ++it)
00891 {
00892 unknowns[it->second] = m_cutCellMoments.m_EBmoments[it->first];
00893 }
00894
00895 for (typename PthMomentLoc::const_iterator it = lsp.m_monoLocPLess1.begin(); it != lsp.m_monoLocPLess1.end(); ++it)
00896 {
00897 unknowns[it->second + lsp.m_numP] = m_cutCellMoments.m_moments[it->first];
00898 }
00899
00900
00901 Real maxRi = 0.0;
00902
00903 for (int i = 0; i < lsp.m_numP*dim; i++)
00904 {
00905 Real AtimeX = 0.0;
00906
00907 for (int j = 0; j < lsp.m_numP + lsp.m_numPLess1; j++)
00908 {
00909 AtimeX += lsp.m_matrix[i][j] * unknowns[j];
00910 }
00911
00912 Real ri = AtimeX - rhs[i];
00913
00914 if (Abs(ri) > maxRi)
00915 {
00916 m_cutCellMoments.setResidual(Abs(ri),iDegree,0);
00917 maxRi = Abs(ri);
00918 }
00919
00920 m_cutCellMoments.setResidual(m_cutCellMoments.getResidual(iDegree,1) + Abs(ri),iDegree,1);
00921 m_cutCellMoments.setResidual(m_cutCellMoments.getResidual(iDegree,2) + ri * ri,iDegree,2);
00922 }
00923
00924 m_cutCellMoments.setResidual(sqrt(m_cutCellMoments.getResidual(iDegree,2)),iDegree,2);
00925 }
00926 }
00927
00928 template <int dim> void ComputeCutCellMoments<dim>::computeResiduals(const Vector< CutCellMoments<dim> > & a_refinedCCMoms,
00929 #if RECURSIVE_GEOMETRY_GENERATION == 0
00930 const int & a_degreeP)
00931 #else
00932 const int & a_degreePmax)
00933 #endif
00934 {
00935 #if RECURSIVE_GEOMETRY_GENERATION == 0
00936 for (int iDegree = 0; iDegree <= a_degreeP; iDegree++)
00937 #else
00938 for (int iDegree = 0; iDegree <= a_degreePmax; iDegree++)
00939 #endif
00940 {
00941 Real maxRes = 0.0;
00942 Real tempRes2 = 0.0;
00943 Real tempRes1 = 0.0;
00944
00945 for (int i = 0; i < a_refinedCCMoms.size(); i++)
00946 {
00947 Real res0 = a_refinedCCMoms[i].getResidual(iDegree,0);
00948 Real res1 = a_refinedCCMoms[i].getResidual(iDegree,1);
00949 Real res2 = a_refinedCCMoms[i].getResidual(iDegree,2);
00950
00951 if (res0 > maxRes && res0 != LARGEREALVAL)
00952 {
00953 maxRes = res0;
00954 m_cutCellMoments.setResidual(res0,iDegree,0);
00955 }
00956
00957 if (res1 != LARGEREALVAL)
00958 {
00959 tempRes1 += res1;
00960 }
00961
00962 if (res2 != LARGEREALVAL)
00963 {
00964 tempRes2 += res2*res2;
00965 }
00966 }
00967
00968 m_cutCellMoments.setResidual(tempRes1,iDegree,1);
00969
00970 if (tempRes2 != LARGEREALVAL)
00971 {
00972 m_cutCellMoments.setResidual(sqrt(tempRes2),iDegree,2);
00973 }
00974 }
00975 }
00976
00977 template <int dim> void ComputeCutCellMoments<dim>::print(ostream& a_out) const
00978 {
00979 m_cutCellMoments.print(a_out);
00980 }
00981
00982 template <int dim> void ComputeCutCellMoments<dim>::dump() const
00983 {
00984 print(pout());
00985 }
00986
00987
00988 template <int dim> void ComputeCutCellMoments<dim>::operator=(const ComputeCutCellMoments<dim> & a_computeCutCellMoments)
00989 {
00990
00991 if (this != &a_computeCutCellMoments)
00992 {
00993 m_cutCellMoments = a_computeCutCellMoments.m_cutCellMoments;
00994 }
00995 }
00996
00997 template <int dim> ostream& operator<<(ostream & a_out,
00998 const ComputeCutCellMoments<dim> & a_computeCutCellMoments)
00999 {
01000 a_computeCutCellMoments.print(a_out);
01001 return a_out;
01002 }
01003
01004 template <int dim> Real ComputeCutCellMoments<dim>::factorial(const IvDim & a_multiIndex) const
01005 {
01006 Real fact = 1.0;
01007
01008 for (int i = 0; i < dim; i++)
01009 {
01010 for (int j = 2; j <= a_multiIndex[i]; j++)
01011 {
01012 fact *= j;
01013 }
01014 }
01015
01016 return fact;
01017 }
01018
01019 #include "NamespaceFooter.H"
01020
01021 #endif