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 _NORMALDERIVATIVE_H_ 00012 #define _NORMALDERIVATIVE_H_ 00013 00014 #include "MayDay.H" 00015 00016 #include "Notation.H" 00017 #include "IFSlicer.H" 00018 00019 #include "NamespaceHeader.H" 00020 00021 /// This computes the derivatives of the normal of a sliced implicit function 00022 /** 00023 This computes the derivatives of the normal of a sliced implicit function 00024 */ 00025 template <int dim> class NormalDerivative 00026 { 00027 public: 00028 typedef IndexTM<int,dim> IvDim; 00029 typedef IndexTM<Real,dim> RvDim; 00030 00031 // This represents a product of partial derivatives of a function. Each 00032 // unique partial derivative is represented by a "IvDim" which specifies the 00033 // number of partial derivatives taken in each coordinate direction. Each 00034 // entry in the map is one such term and the map's value for the entry is 00035 // the exponent of the entry. The product is simply the product of all the 00036 // entries each with this exponent. 00037 typedef map<IvDim,int,LexLT<IvDim> > DerivativeProduct; 00038 00039 // This represents the product of partial derivatives of a function (given 00040 // by the first term) times another function to a power (given by the second 00041 // term). The second function is the reciprocal of the magnitude of the 00042 // gradient of the original function. This second function (to various 00043 // powers) appears in the normal and all it's derivatives. Further, the 00044 // normal and all its derivatives can be written as a sum of terms of this 00045 // form. 00046 typedef pair<DerivativeProduct,int> PartialDerivativeTerm; 00047 00048 /// Null constructor 00049 /** 00050 Null constructor 00051 */ 00052 NormalDerivative(); 00053 00054 /// Destructor 00055 /** 00056 Destructor 00057 */ 00058 virtual ~NormalDerivative(); 00059 00060 /// Evaluate derivatives of the normal of an IFSlicer class 00061 /** 00062 Evaluate a derivative of the normal, a_multiIndex specifies how many 00063 derivatives to take in each coordinate direction, a_direction specifies 00064 which component of the normal use, a_point is the point in space to 00065 evaluate the derivative, and a_ifSlicer is a sliced function whose 00066 gradient is the normal. 00067 */ 00068 virtual Real evaluate(const IvDim & a_multiIndex, 00069 const int & a_direction, 00070 const RvDim & a_point, 00071 const IFSlicer<dim> * a_ifSlicer); 00072 00073 Real getMagnitudeOfGradient(); 00074 00075 protected: 00076 // Expand and evaluate the multi-index partial derivative of a 00077 // PartialDerivativeTerm recursively. If the multi-index is zero (i.e., no 00078 // further derivatives) then simply evaluate the PartialDerivateTerm at 00079 // "a_point" using the implicit function. If the multi-index isn't zerom, 00080 // explicitly compute one partial derivative which is a sum of 00081 // PartialDerivativeTerm's and call "expand" with each of these terms and a 00082 // reduced multi-index (which will eventually be zero). The sum the results 00083 // and return that sum. 00084 Real expand(const IvDim & a_multiIndex, 00085 const PartialDerivativeTerm & a_term, 00086 const RvDim & a_point, 00087 const IFSlicer<dim> * a_ifSlicer) const; 00088 00089 // The value of the magnitude of the gradient of the function at "a_point" 00090 Real m_magnitudeOfGradient; 00091 00092 00093 private: 00094 NormalDerivative(const NormalDerivative& a_input) 00095 { 00096 MayDay::Abort("NormalDerivativeIF doesn't allow copy construction"); 00097 } 00098 00099 void operator=(const NormalDerivative& a_input) 00100 { 00101 MayDay::Abort("NormalDerivativeIF doesn't allow assignment"); 00102 } 00103 }; 00104 00105 /// This computes the derivatives of the normal of a sliced implicit function 00106 /** 00107 This computes the derivatives of the normal of a sliced implicit function. 00108 Specialization so an additional method can be defined. 00109 */ 00110 template <> class NormalDerivative<GLOBALDIM> 00111 { 00112 public: 00113 typedef IndexTM<int,GLOBALDIM> IvDim; 00114 typedef IndexTM<Real,GLOBALDIM> RvDim; 00115 00116 // This represents a product of partial derivatives of a function. Each 00117 // unique partial derivative is represented by a "IvDim" which specifies the 00118 // number of partial derivatives taken in each coordinate direction. Each 00119 // entry in the map is one such term and the map's value for the entry is 00120 // the exponent of the entry. The product is simply the product of all the 00121 // entries each with this exponent. 00122 typedef map<IvDim,int,LexLT<IvDim> > DerivativeProduct; 00123 00124 // This represents the product of partial derivatives of a function (given 00125 // by the first term) times another function to a power (given by the second 00126 // term). The second function is the reciprocal of the magnitude of the 00127 // gradient of the original function. This second function (to various 00128 // powers) appears in the normal and all it's derivatives. Further, the 00129 // normal and all its derivatives can be written as a sum of terms of this 00130 // form. 00131 typedef pair<DerivativeProduct,int> PartialDerivativeTerm; 00132 00133 /// Null constructor 00134 /** 00135 Null constructor 00136 */ 00137 NormalDerivative(); 00138 00139 /// Destructor 00140 /** 00141 Destructor 00142 */ 00143 virtual ~NormalDerivative(); 00144 00145 /// Evaluate derivatives of the normal of a BaseIF subclass 00146 /** 00147 Evaluate a derivative of the normal, a_multiIndex specifies how many 00148 derivatives to take in each coordinate direction, a_direction specifies 00149 which component of the normal use, a_point is the point in space to 00150 evaluate the derivative, and a_impFunc is a function whose gradient 00151 is the normal. 00152 */ 00153 virtual Real evaluate(const IvDim & a_multiIndex, 00154 const int & a_direction, 00155 const RvDim & a_point, 00156 const BaseIF & a_impFunc); 00157 00158 /// Evaluate derivatives of the normal of an IFSlicer class 00159 /** 00160 Evaluate a derivative of the normal, a_multiIndex specifies how many 00161 derivatives to take in each coordinate direction, a_direction specifies 00162 which component of the normal use, a_point is the point in space to 00163 evaluate the derivative, and a_ifSlicer is a sliced function whose 00164 gradient is the normal. 00165 */ 00166 virtual Real evaluate(const IvDim & a_multiIndex, 00167 const int & a_direction, 00168 const RvDim & a_point, 00169 const IFSlicer<GLOBALDIM> * a_ifSlicer); 00170 00171 Real getMagnitudeOfGradient(); 00172 protected: 00173 // Expand and evaluate the multi-index partial derivative of a 00174 // PartialDerivativeTerm recursively. If the multi-index is zero (i.e., no 00175 // further derivatives) then simply evaluate the PartialDerivateTerm at 00176 // "a_point" using the implicit function. If the multi-index isn't zerom, 00177 // explicitly compute one partial derivative which is a sum of 00178 // PartialDerivativeTerm's and call "expand" with each of these terms and a 00179 // reduced multi-index (which will eventually be zero). The sum the results 00180 // and return that sum. 00181 Real expand(const IvDim & a_multiIndex, 00182 const PartialDerivativeTerm & a_term, 00183 const RvDim & a_point, 00184 const IFSlicer<GLOBALDIM> * a_ifSlicer) const; 00185 00186 // The value of the magnitude of the gradient of the function at "a_point" 00187 Real m_magnitudeOfGradient; 00188 00189 00190 private: 00191 NormalDerivative(const NormalDerivative& a_input) 00192 { 00193 MayDay::Abort("NormalDerivativeIF doesn't allow copy construction"); 00194 } 00195 00196 void operator=(const NormalDerivative& a_input) 00197 { 00198 MayDay::Abort("NormalDerivativeIF doesn't allow assignment"); 00199 } 00200 }; 00201 00202 #include "NamespaceFooter.H" 00203 00204 #include "NormalDerivativeImplem.H" 00205 00206 #endif