00001 #ifdef CH_LANG_CC
00002
00003
00004
00005
00006
00007
00008
00009 #endif
00010
00011 #ifndef _COEFFICIENTINTERPOLATOR_H__
00012 #define _COEFFICIENTINTERPOLATOR_H__
00013
00014 #include "LevelData.H"
00015 #include "DataIterator.H"
00016 #include "DebugOut.H"
00017 #include "BoxIterator.H"
00018 #include "NamespaceHeader.H"
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 template <typename LevelData_, typename SolutionLevelData_ = LevelData_>
00029 class CoefficientInterpolator
00030 {
00031 public:
00032
00033 typedef LevelData_ LevelDataType;
00034 typedef SolutionLevelData_ SolutionLevelDataType;
00035
00036
00037
00038 explicit CoefficientInterpolator(int a_numComps);
00039
00040
00041 virtual ~CoefficientInterpolator();
00042
00043
00044 int numComps() const;
00045
00046
00047
00048
00049
00050 virtual void interpolate(LevelDataType& a_result,
00051 Real a_time);
00052
00053
00054
00055
00056
00057
00058
00059
00060 virtual void interpolate(LevelDataType& a_result,
00061 const SolutionLevelDataType& a_solution,
00062 Real a_time);
00063
00064
00065
00066
00067
00068 virtual bool dependsUponSolution() const;
00069
00070
00071
00072
00073
00074
00075 virtual void interpolatePrime(LevelDataType& a_prime,
00076 const SolutionLevelDataType& a_solution,
00077 Real a_time);
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 virtual void solve(SolutionLevelDataType& a_phi,
00088 const SolutionLevelDataType& a_f,
00089 Real a_time,
00090 const SolutionLevelDataType& a_phi0,
00091 Real a_tolerance);
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 void NewtonRaphson(SolutionLevelDataType& a_phi,
00104 const SolutionLevelDataType& a_f,
00105 Real a_time,
00106 const SolutionLevelDataType& a_phi0,
00107 Real a_tolerance);
00108
00109 private:
00110
00111
00112 int m_numComps;
00113
00114
00115 bool m_inCall;
00116
00117
00118 CoefficientInterpolator();
00119 CoefficientInterpolator(const CoefficientInterpolator&);
00120 CoefficientInterpolator& operator=(const CoefficientInterpolator&);
00121 };
00122
00123
00124 template <typename LevelData_, typename SolutionLevelData_>
00125 CoefficientInterpolator<LevelData_, SolutionLevelData_>::
00126 CoefficientInterpolator(int a_numComps)
00127 :m_numComps(a_numComps),
00128 m_inCall(false)
00129 {
00130 }
00131
00132
00133
00134 template <typename LevelData_, typename SolutionLevelData_>
00135 CoefficientInterpolator<LevelData_, SolutionLevelData_>::
00136 ~CoefficientInterpolator()
00137 {
00138 }
00139
00140
00141
00142 template <typename LevelData_, typename SolutionLevelData_>
00143 int
00144 CoefficientInterpolator<LevelData_, SolutionLevelData_>::
00145 numComps() const
00146 {
00147 return m_numComps;
00148 }
00149
00150
00151
00152 template <typename LevelData_, typename SolutionLevelData_>
00153 bool
00154 CoefficientInterpolator<LevelData_, SolutionLevelData_>::
00155 dependsUponSolution() const
00156 {
00157 return false;
00158 }
00159
00160
00161
00162 template <typename LevelData_, typename SolutionLevelData_>
00163 void
00164 CoefficientInterpolator<LevelData_, SolutionLevelData_>::
00165 interpolate(LevelData_& a_result,
00166 Real a_time)
00167 {
00168 if (dependsUponSolution())
00169 {
00170 MayDay::Error("The solution must be passed to this interpolator!");
00171 }
00172 if (m_inCall)
00173 {
00174 MayDay::Error("Neither the solution-independent nor -dependent interpolate method has\n"
00175 "been defined for this subclass.");
00176 }
00177
00178
00179 m_inCall = true;
00180 SolutionLevelData_ phoneyBaloney(a_result.disjointBoxLayout(), 1, a_result.ghostVect());
00181 interpolate(a_result, phoneyBaloney, a_time);
00182 m_inCall = false;
00183 }
00184
00185
00186
00187 template <typename LevelData_, typename SolutionLevelData_>
00188 void
00189 CoefficientInterpolator<LevelData_, SolutionLevelData_>::
00190 interpolate(LevelData_& a_result,
00191 const SolutionLevelData_& a_solution,
00192 Real a_time)
00193 {
00194 if (m_inCall)
00195 {
00196 MayDay::Error("Neither the solution-independent nor -dependent interpolate method has\n"
00197 "been defined for this subclass.");
00198 }
00199 if (!dependsUponSolution())
00200 {
00201 m_inCall = true;
00202 interpolate(a_result, a_time);
00203 m_inCall = false;
00204 }
00205 else
00206 {
00207 MayDay::Error("The solution-dependent interpolate method has not been defined for this subclass.");
00208 }
00209 }
00210
00211
00212
00213 template <typename LevelData_, typename SolutionLevelData_>
00214 void
00215 CoefficientInterpolator<LevelData_, SolutionLevelData_>::
00216 interpolatePrime(LevelData_& a_prime,
00217 const SolutionLevelData_& a_solution,
00218 Real a_time)
00219 {
00220 if (!dependsUponSolution())
00221 {
00222 for (DataIterator dit = a_prime.disjointBoxLayout().dataIterator(); dit.ok(); ++dit)
00223 a_prime[dit()].setVal(0.0);
00224 }
00225 else
00226 MayDay::Error("The derivative w.r.t. the solution has not been implemented for this subclass.");
00227 }
00228
00229
00230
00231 template <typename LevelData_, typename SolutionLevelData_>
00232 void
00233 CoefficientInterpolator<LevelData_, SolutionLevelData_>::
00234 solve(SolutionLevelData_& a_phi,
00235 const SolutionLevelData_& a_f,
00236 Real a_time,
00237 const SolutionLevelData_& a_phi0,
00238 Real a_tolerance)
00239 {
00240 MayDay::Error("CoefficientInterpolator::solve() must be implemented for this subclass!");
00241 }
00242
00243
00244
00245 template <typename LevelData_, typename SolutionLevelData_>
00246 void
00247 CoefficientInterpolator<LevelData_, SolutionLevelData_>::
00248 NewtonRaphson(SolutionLevelData_& a_phi,
00249 const SolutionLevelData_& a_f,
00250 Real a_time,
00251 const SolutionLevelData_& a_phi0,
00252 Real a_tolerance)
00253 {
00254
00255 Real maxError = -FLT_MAX;
00256 LevelData_ F(a_phi0.disjointBoxLayout(), a_phi0.nComp()),
00257 A(a_phi0.disjointBoxLayout(), a_phi0.nComp());
00258 interpolate(A, a_phi0, a_time);
00259 for (DataIterator dit = a_phi0.dataIterator(); dit.ok(); ++dit)
00260 {
00261 a_phi[dit()].copy(a_phi0[dit()]);
00262 F[dit()].copy(A[dit()]);
00263 F[dit()] *= a_phi[dit()];
00264 F[dit()] -= a_f[dit()];
00265 maxError = Max(Abs(F[dit()].max()), Abs(F[dit()].min()));
00266 }
00267 if (maxError < a_tolerance)
00268 return;
00269
00270 LevelData_ Aprime(a_phi.disjointBoxLayout(), a_phi.nComp());
00271 while (maxError > a_tolerance)
00272 {
00273
00274
00275 interpolatePrime(Aprime, a_phi, a_time);
00276 for (DataIterator dit = a_phi.dataIterator(); dit.ok(); ++dit)
00277 {
00278 Box box = a_phi.disjointBoxLayout().get(dit());
00279 const FArrayBox& a = A[dit()];
00280 const FArrayBox& aprime = Aprime[dit()];
00281 const FArrayBox& f = F[dit()];
00282 FArrayBox& phi = a_phi[dit()];
00283 for (BoxIterator bit(box); bit.ok(); ++bit)
00284 {
00285 IntVect i = bit();
00286 for (int n = 0; n < F.nComp(); ++n)
00287 {
00288 if (Abs(f(i, n)) > a_tolerance)
00289 {
00290 Real fprime = aprime(i, n) * phi(i, n) + a(i, n);
00291 phi(i, n) -= f(i, n) / fprime;
00292 }
00293 }
00294 }
00295 }
00296
00297
00298 interpolate(A, a_phi, a_time);
00299 for (DataIterator dit = a_phi.dataIterator(); dit.ok(); ++dit)
00300 {
00301
00302 F[dit()].copy(A[dit()]);
00303 F[dit()] *= a_phi[dit()];
00304 F[dit()] -= a_f[dit()];
00305
00306
00307 maxError = Max(Abs(F[dit()].max()), Abs(F[dit()].min()));
00308 }
00309 }
00310 }
00311
00312
00313 #include "NamespaceFooter.H"
00314
00315 #endif