00001 #ifdef CH_LANG_CC
00002
00003
00004
00005
00006
00007
00008
00009 #endif
00010
00011 #ifndef _NORMALDERIVATIVEIMPLEM_H_
00012 #define _NORMALDERIVATIVEIMPLEM_H_
00013
00014 #include "NamespaceHeader.H"
00015
00016
00017 template <int dim> NormalDerivative<dim>::NormalDerivative()
00018 {
00019 }
00020
00021
00022 template <int dim> NormalDerivative<dim>::~NormalDerivative()
00023 {
00024 }
00025
00026
00027 template <int dim> Real NormalDerivative<dim>::evaluate(const IvDim & a_multiIndex,
00028 const int & a_direction,
00029 const RvDim & a_point,
00030 const IFSlicer<dim> * a_implicitFunction)
00031 {
00032
00033
00034 DerivativeProduct gradientComponent;
00035 gradientComponent[BASISV_TM<int,dim>(a_direction)] = 1;
00036
00037
00038
00039
00040 int magnitudeOfGradientPower = 1;
00041 PartialDerivativeTerm normalComponent(gradientComponent,
00042 magnitudeOfGradientPower);
00043
00044
00045 m_magnitudeOfGradient = 0.0;
00046
00047 for (int idir = 0; idir < dim; idir++)
00048 {
00049 Real firstPartial = a_implicitFunction->value(BASISV_TM<int,dim>(idir),a_point);
00050 m_magnitudeOfGradient += firstPartial*firstPartial;
00051 }
00052
00053 m_magnitudeOfGradient = sqrt(m_magnitudeOfGradient);
00054
00055 Real value = expand(a_multiIndex,
00056 normalComponent,
00057 a_point,
00058 a_implicitFunction);
00059
00060 return value;
00061 }
00062
00063
00064 template <int dim> Real NormalDerivative<dim>::getMagnitudeOfGradient()
00065 {
00066 return m_magnitudeOfGradient;
00067 }
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 template <int dim> Real NormalDerivative<dim>::expand(const IvDim & a_multiIndex,
00078 const PartialDerivativeTerm & a_term,
00079 const RvDim & a_point,
00080 const IFSlicer<dim> * a_implicitFunction) const
00081 {
00082 Real value;
00083
00084 int firstNonZero;
00085 for (firstNonZero = 0; firstNonZero < dim; firstNonZero++)
00086 {
00087 if (a_multiIndex[firstNonZero] != 0)
00088 {
00089 break;
00090 }
00091 }
00092
00093
00094 if (firstNonZero == dim)
00095 {
00096 value = 1.0;
00097
00098
00099
00100 const DerivativeProduct& curDerivativeProduct = a_term.first;
00101
00102 for (typename DerivativeProduct::const_iterator it=curDerivativeProduct.begin();
00103 it != curDerivativeProduct.end();
00104 ++it)
00105 {
00106 const IvDim& curMultiIndex = it->first;
00107 const int& curExponent = it->second;
00108
00109
00110 Real curValue = pow(a_implicitFunction->value(curMultiIndex,a_point),curExponent);
00111
00112 value *= curValue;
00113 }
00114
00115 if (m_magnitudeOfGradient != 0.0)
00116 {
00117
00118 int curExponent = a_term.second;
00119 value /= pow(m_magnitudeOfGradient,curExponent);
00120 }
00121 }
00122 else
00123 {
00124 value = 0.0;
00125
00126
00127
00128 IvDim curPartialDerivative = BASISV_TM<int,dim>(firstNonZero);
00129
00130
00131 IvDim reducedMultiIndex = a_multiIndex;
00132 reducedMultiIndex[firstNonZero]--;
00133
00134
00135
00136 const DerivativeProduct& curDerivativeProduct = a_term.first;
00137 int curExponentOfMagnitudeOfGradient = a_term.second;
00138
00139
00140 for (typename DerivativeProduct::const_iterator it=curDerivativeProduct.begin();
00141 it != curDerivativeProduct.end();
00142 ++it)
00143 {
00144
00145 const IvDim& curMultiIndex = it->first;
00146 const int& curExponent = it->second;
00147
00148
00149
00150
00151 DerivativeProduct newDerivativeProduct = curDerivativeProduct;
00152
00153
00154 Real multiplier = curExponent;
00155
00156 if (curExponent == 1)
00157 {
00158
00159 newDerivativeProduct.erase(curMultiIndex);
00160 }
00161 else
00162 {
00163
00164 newDerivativeProduct[curMultiIndex] -= 1;
00165 }
00166
00167
00168 IvDim newMultiIndex = curMultiIndex;
00169 newMultiIndex += curPartialDerivative;
00170
00171
00172 newDerivativeProduct[newMultiIndex] += 1;
00173
00174
00175 PartialDerivativeTerm newTerm(newDerivativeProduct,
00176 curExponentOfMagnitudeOfGradient);
00177
00178
00179 Real curValue = multiplier * expand(reducedMultiIndex,
00180 newTerm,
00181 a_point,
00182 a_implicitFunction);
00183
00184
00185 value += curValue;
00186 }
00187
00188
00189
00190
00191
00192
00193 for (int idir = 0; idir < dim; idir++)
00194 {
00195
00196 DerivativeProduct newDerivativeProduct = curDerivativeProduct;
00197
00198
00199 IvDim firstPartial = BASISV_TM<int,dim>(idir);
00200 IvDim secondPartial = firstPartial + curPartialDerivative;
00201
00202
00203 newDerivativeProduct[firstPartial] += 1;
00204 newDerivativeProduct[secondPartial] += 1;
00205
00206
00207 int newExponentOfMagnitudeOfGradient = curExponentOfMagnitudeOfGradient + 2;
00208
00209
00210 Real multiplier = -curExponentOfMagnitudeOfGradient;
00211
00212
00213 PartialDerivativeTerm newTerm(newDerivativeProduct,
00214 newExponentOfMagnitudeOfGradient);
00215
00216
00217 Real curValue = multiplier * expand(reducedMultiIndex,
00218 newTerm,
00219 a_point,
00220 a_implicitFunction);
00221
00222
00223 value += curValue;
00224 }
00225 }
00226
00227 return value;
00228 }
00229
00230 #include "NamespaceFooter.H"
00231
00232 #endif