$extrastylesheet
00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 00003 00004 // This library is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public 00006 // License as published by the Free Software Foundation; either 00007 // version 2.1 of the License, or (at your option) any later version. 00008 00009 // This library is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // Lesser General Public License for more details. 00013 00014 // You should have received a copy of the GNU Lesser General Public 00015 // License along with this library; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 #include "libmesh/fe_interface.h" 00019 #include "libmesh/h1_fe_transformation.h" 00020 #include "libmesh/tensor_value.h" 00021 00022 namespace libMesh 00023 { 00024 template< typename OutputShape > 00025 void H1FETransformation<OutputShape>::map_phi( const unsigned int dim, 00026 const Elem* const elem, 00027 const std::vector<Point>& qp, 00028 const FEGenericBase<OutputShape>& fe, 00029 std::vector<std::vector<OutputShape> >& phi ) const 00030 { 00031 switch(dim) 00032 { 00033 case 0: 00034 { 00035 for (unsigned int i=0; i<phi.size(); i++) 00036 { 00037 libmesh_assert_equal_to ( qp.size(), phi[i].size() ); 00038 for (unsigned int p=0; p<phi[i].size(); p++) 00039 FEInterface::shape<OutputShape>(0, fe.get_fe_type(), elem, i, qp[p], phi[i][p]); 00040 } 00041 break; 00042 } 00043 case 1: 00044 { 00045 for (unsigned int i=0; i<phi.size(); i++) 00046 { 00047 libmesh_assert_equal_to ( qp.size(), phi[i].size() ); 00048 for (unsigned int p=0; p<phi[i].size(); p++) 00049 FEInterface::shape<OutputShape>(1, fe.get_fe_type(), elem, i, qp[p], phi[i][p]); 00050 } 00051 break; 00052 } 00053 case 2: 00054 { 00055 for (unsigned int i=0; i<phi.size(); i++) 00056 { 00057 libmesh_assert_equal_to ( qp.size(), phi[i].size() ); 00058 for (unsigned int p=0; p<phi[i].size(); p++) 00059 FEInterface::shape<OutputShape>(2, fe.get_fe_type(), elem, i, qp[p], phi[i][p]); 00060 } 00061 break; 00062 } 00063 case 3: 00064 { 00065 for (unsigned int i=0; i<phi.size(); i++) 00066 { 00067 libmesh_assert_equal_to ( qp.size(), phi[i].size() ); 00068 for (unsigned int p=0; p<phi[i].size(); p++) 00069 FEInterface::shape<OutputShape>(3, fe.get_fe_type(), elem, i, qp[p], phi[i][p]); 00070 } 00071 break; 00072 } 00073 00074 default: 00075 libmesh_error_msg("Invalid dim = " << dim); 00076 } 00077 } 00078 00079 00080 template< typename OutputShape > 00081 void H1FETransformation<OutputShape>::map_dphi( const unsigned int dim, 00082 const Elem* const, 00083 const std::vector<Point>&, 00084 const FEGenericBase<OutputShape>& fe, 00085 std::vector<std::vector<typename FEGenericBase<OutputShape>::OutputGradient> >& dphi, 00086 std::vector<std::vector<OutputShape> >& dphidx, 00087 std::vector<std::vector<OutputShape> >& dphidy, 00088 std::vector<std::vector<OutputShape> >& dphidz ) const 00089 { 00090 switch(dim) 00091 { 00092 case 0: // No derivatives in 0D 00093 { 00094 for (unsigned int i=0; i<dphi.size(); i++) 00095 for (unsigned int p=0; p<dphi[i].size(); p++) 00096 { 00097 dphi[i][p] = 0.; 00098 } 00099 break; 00100 } 00101 00102 case 1: 00103 { 00104 const std::vector<std::vector<OutputShape> >& dphidxi = fe.get_dphidxi(); 00105 00106 const std::vector<Real>& dxidx_map = fe.get_fe_map().get_dxidx(); 00107 #if LIBMESH_DIM>1 00108 const std::vector<Real>& dxidy_map = fe.get_fe_map().get_dxidy(); 00109 #endif 00110 #if LIBMESH_DIM>2 00111 const std::vector<Real>& dxidz_map = fe.get_fe_map().get_dxidz(); 00112 #endif 00113 00114 for (unsigned int i=0; i<dphi.size(); i++) 00115 for (unsigned int p=0; p<dphi[i].size(); p++) 00116 { 00117 // dphi/dx = (dphi/dxi)*(dxi/dx) 00118 dphi[i][p].slice(0) = dphidx[i][p] = dphidxi[i][p]*dxidx_map[p]; 00119 00120 #if LIBMESH_DIM>1 00121 dphi[i][p].slice(1) = dphidy[i][p] = dphidxi[i][p]*dxidy_map[p]; 00122 #endif 00123 #if LIBMESH_DIM>2 00124 dphi[i][p].slice(2) = dphidz[i][p] = dphidxi[i][p]*dxidz_map[p]; 00125 #endif 00126 } 00127 00128 break; 00129 } 00130 00131 case 2: 00132 { 00133 const std::vector<std::vector<OutputShape> >& dphidxi = fe.get_dphidxi(); 00134 const std::vector<std::vector<OutputShape> >& dphideta = fe.get_dphideta(); 00135 00136 const std::vector<Real>& dxidx_map = fe.get_fe_map().get_dxidx(); 00137 const std::vector<Real>& dxidy_map = fe.get_fe_map().get_dxidy(); 00138 #if LIBMESH_DIM > 2 00139 const std::vector<Real>& dxidz_map = fe.get_fe_map().get_dxidz(); 00140 #endif 00141 00142 const std::vector<Real>& detadx_map = fe.get_fe_map().get_detadx(); 00143 const std::vector<Real>& detady_map = fe.get_fe_map().get_detady(); 00144 #if LIBMESH_DIM > 2 00145 const std::vector<Real>& detadz_map = fe.get_fe_map().get_detadz(); 00146 #endif 00147 00148 for (unsigned int i=0; i<dphi.size(); i++) 00149 for (unsigned int p=0; p<dphi[i].size(); p++) 00150 { 00151 // dphi/dx = (dphi/dxi)*(dxi/dx) + (dphi/deta)*(deta/dx) 00152 dphi[i][p].slice(0) = dphidx[i][p] = (dphidxi[i][p]*dxidx_map[p] + 00153 dphideta[i][p]*detadx_map[p]); 00154 00155 // dphi/dy = (dphi/dxi)*(dxi/dy) + (dphi/deta)*(deta/dy) 00156 dphi[i][p].slice(1) = dphidy[i][p] = (dphidxi[i][p]*dxidy_map[p] + 00157 dphideta[i][p]*detady_map[p]); 00158 00159 #if LIBMESH_DIM > 2 00160 // dphi/dz = (dphi/dxi)*(dxi/dz) + (dphi/deta)*(deta/dz) 00161 dphi[i][p].slice(2) = dphidz[i][p] = (dphidxi[i][p]*dxidz_map[p] + 00162 dphideta[i][p]*detadz_map[p]); 00163 #endif 00164 } 00165 00166 break; 00167 } 00168 00169 case 3: 00170 { 00171 const std::vector<std::vector<OutputShape> >& dphidxi = fe.get_dphidxi(); 00172 const std::vector<std::vector<OutputShape> >& dphideta = fe.get_dphideta(); 00173 const std::vector<std::vector<OutputShape> >& dphidzeta = fe.get_dphidzeta(); 00174 00175 const std::vector<Real>& dxidx_map = fe.get_fe_map().get_dxidx(); 00176 const std::vector<Real>& dxidy_map = fe.get_fe_map().get_dxidy(); 00177 const std::vector<Real>& dxidz_map = fe.get_fe_map().get_dxidz(); 00178 00179 const std::vector<Real>& detadx_map = fe.get_fe_map().get_detadx(); 00180 const std::vector<Real>& detady_map = fe.get_fe_map().get_detady(); 00181 const std::vector<Real>& detadz_map = fe.get_fe_map().get_detadz(); 00182 00183 const std::vector<Real>& dzetadx_map = fe.get_fe_map().get_dzetadx(); 00184 const std::vector<Real>& dzetady_map = fe.get_fe_map().get_dzetady(); 00185 const std::vector<Real>& dzetadz_map = fe.get_fe_map().get_dzetadz(); 00186 00187 for (unsigned int i=0; i<dphi.size(); i++) 00188 for (unsigned int p=0; p<dphi[i].size(); p++) 00189 { 00190 // dphi/dx = (dphi/dxi)*(dxi/dx) + (dphi/deta)*(deta/dx) + (dphi/dzeta)*(dzeta/dx); 00191 dphi[i][p].slice(0) = dphidx[i][p] = (dphidxi[i][p]*dxidx_map[p] + 00192 dphideta[i][p]*detadx_map[p] + 00193 dphidzeta[i][p]*dzetadx_map[p]); 00194 00195 // dphi/dy = (dphi/dxi)*(dxi/dy) + (dphi/deta)*(deta/dy) + (dphi/dzeta)*(dzeta/dy); 00196 dphi[i][p].slice(1) = dphidy[i][p] = (dphidxi[i][p]*dxidy_map[p] + 00197 dphideta[i][p]*detady_map[p] + 00198 dphidzeta[i][p]*dzetady_map[p]); 00199 00200 // dphi/dz = (dphi/dxi)*(dxi/dz) + (dphi/deta)*(deta/dz) + (dphi/dzeta)*(dzeta/dz); 00201 dphi[i][p].slice(2) = dphidz[i][p] = (dphidxi[i][p]*dxidz_map[p] + 00202 dphideta[i][p]*detadz_map[p] + 00203 dphidzeta[i][p]*dzetadz_map[p]); 00204 } 00205 break; 00206 } 00207 00208 default: 00209 libmesh_error_msg("Invalid dim = " << dim); 00210 } // switch(dim) 00211 } 00212 00213 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 00214 template< typename OutputShape > 00215 void H1FETransformation<OutputShape>::map_d2phi( const unsigned int dim, 00216 const Elem* const elem, 00217 const std::vector<Point>&, 00218 const FEGenericBase<OutputShape>& fe, 00219 std::vector<std::vector<typename FEGenericBase<OutputShape>::OutputTensor> >& d2phi, 00220 std::vector<std::vector<OutputShape> >& d2phidx2, 00221 std::vector<std::vector<OutputShape> >& d2phidxdy, 00222 std::vector<std::vector<OutputShape> >& d2phidxdz, 00223 std::vector<std::vector<OutputShape> >& d2phidy2, 00224 std::vector<std::vector<OutputShape> >& d2phidydz, 00225 std::vector<std::vector<OutputShape> >& d2phidz2 ) const 00226 { 00227 libmesh_do_once( 00228 if (!elem->has_affine_map()) 00229 { 00230 libMesh::err << "WARNING: Second derivatives are not currently " 00231 << "correctly calculated on non-affine elements!" 00232 << std::endl; 00233 } 00234 ); 00235 00236 00237 switch (dim) 00238 { 00239 case 0: // No derivatives in 0D 00240 { 00241 for (unsigned int i=0; i<d2phi.size(); i++) 00242 for (unsigned int p=0; p<d2phi[i].size(); p++) 00243 { 00244 d2phi[i][p] = 0.; 00245 } 00246 00247 break; 00248 } 00249 00250 case 1: 00251 { 00252 const std::vector<std::vector<OutputShape> >& d2phidxi2 = fe.get_d2phidxi2(); 00253 00254 const std::vector<Real>& dxidx_map = fe.get_fe_map().get_dxidx(); 00255 #if LIBMESH_DIM>1 00256 const std::vector<Real>& dxidy_map = fe.get_fe_map().get_dxidy(); 00257 #endif 00258 #if LIBMESH_DIM>2 00259 const std::vector<Real>& dxidz_map = fe.get_fe_map().get_dxidz(); 00260 #endif 00261 00262 for (unsigned int i=0; i<d2phi.size(); i++) 00263 for (unsigned int p=0; p<d2phi[i].size(); p++) 00264 { 00265 d2phi[i][p].slice(0).slice(0) = d2phidx2[i][p] = 00266 d2phidxi2[i][p]*dxidx_map[p]*dxidx_map[p]; 00267 #if LIBMESH_DIM>1 00268 d2phi[i][p].slice(0).slice(1) = 00269 d2phi[i][p].slice(1).slice(0) = d2phidxdy[i][p] = 00270 d2phidxi2[i][p]*dxidx_map[p]*dxidy_map[p]; 00271 00272 d2phi[i][p].slice(1).slice(1) = d2phidy2[i][p] = 00273 d2phidxi2[i][p]*dxidy_map[p]*dxidy_map[p]; 00274 #endif 00275 #if LIBMESH_DIM>2 00276 d2phi[i][p].slice(0).slice(2) = 00277 d2phi[i][p].slice(2).slice(0) = d2phidxdz[i][p] = 00278 d2phidxi2[i][p]*dxidx_map[p]*dxidz_map[p]; 00279 00280 d2phi[i][p].slice(1).slice(2) = 00281 d2phi[i][p].slice(2).slice(1) = d2phidydz[i][p] = 00282 d2phidxi2[i][p]*dxidy_map[p]*dxidz_map[p]; 00283 00284 d2phi[i][p].slice(2).slice(2) = d2phidz2[i][p] = 00285 d2phidxi2[i][p]*dxidz_map[p]*dxidz_map[p]; 00286 #endif 00287 } 00288 break; 00289 } 00290 00291 case 2: 00292 { 00293 const std::vector<std::vector<OutputShape> >& d2phidxi2 = fe.get_d2phidxi2(); 00294 const std::vector<std::vector<OutputShape> >& d2phidxideta = fe.get_d2phidxideta(); 00295 const std::vector<std::vector<OutputShape> >& d2phideta2 = fe.get_d2phideta2(); 00296 00297 const std::vector<Real>& dxidx_map = fe.get_fe_map().get_dxidx(); 00298 const std::vector<Real>& dxidy_map = fe.get_fe_map().get_dxidy(); 00299 #if LIBMESH_DIM > 2 00300 const std::vector<Real>& dxidz_map = fe.get_fe_map().get_dxidz(); 00301 #endif 00302 00303 const std::vector<Real>& detadx_map = fe.get_fe_map().get_detadx(); 00304 const std::vector<Real>& detady_map = fe.get_fe_map().get_detady(); 00305 #if LIBMESH_DIM > 2 00306 const std::vector<Real>& detadz_map = fe.get_fe_map().get_detadz(); 00307 #endif 00308 00309 for (unsigned int i=0; i<d2phi.size(); i++) 00310 for (unsigned int p=0; p<d2phi[i].size(); p++) 00311 { 00312 d2phi[i][p].slice(0).slice(0) = d2phidx2[i][p] = 00313 d2phidxi2[i][p]*dxidx_map[p]*dxidx_map[p] + 00314 2*d2phidxideta[i][p]*dxidx_map[p]*detadx_map[p] + 00315 d2phideta2[i][p]*detadx_map[p]*detadx_map[p]; 00316 00317 d2phi[i][p].slice(0).slice(1) = 00318 d2phi[i][p].slice(1).slice(0) = d2phidxdy[i][p] = 00319 d2phidxi2[i][p]*dxidx_map[p]*dxidy_map[p] + 00320 d2phidxideta[i][p]*dxidx_map[p]*detady_map[p] + 00321 d2phideta2[i][p]*detadx_map[p]*detady_map[p] + 00322 d2phidxideta[i][p]*detadx_map[p]*dxidy_map[p]; 00323 00324 d2phi[i][p].slice(1).slice(1) = d2phidy2[i][p] = 00325 d2phidxi2[i][p]*dxidy_map[p]*dxidy_map[p] + 00326 2*d2phidxideta[i][p]*dxidy_map[p]*detady_map[p] + 00327 d2phideta2[i][p]*detady_map[p]*detady_map[p]; 00328 00329 #if LIBMESH_DIM > 2 00330 d2phi[i][p].slice(0).slice(2) = 00331 d2phi[i][p].slice(2).slice(0) = d2phidxdz[i][p] = 00332 d2phidxi2[i][p]*dxidx_map[p]*dxidz_map[p] + 00333 d2phidxideta[i][p]*dxidx_map[p]*detadz_map[p] + 00334 d2phideta2[i][p]*detadx_map[p]*detadz_map[p] + 00335 d2phidxideta[i][p]*detadx_map[p]*dxidz_map[p]; 00336 00337 d2phi[i][p].slice(1).slice(2) = 00338 d2phi[i][p].slice(2).slice(1) = d2phidydz[i][p] = 00339 d2phidxi2[i][p]*dxidy_map[p]*dxidz_map[p] + 00340 d2phidxideta[i][p]*dxidy_map[p]*detadz_map[p] + 00341 d2phideta2[i][p]*detady_map[p]*detadz_map[p] + 00342 d2phidxideta[i][p]*detady_map[p]*dxidz_map[p]; 00343 00344 d2phi[i][p].slice(2).slice(2) = d2phidz2[i][p] = 00345 d2phidxi2[i][p]*dxidz_map[p]*dxidz_map[p] + 00346 2*d2phidxideta[i][p]*dxidz_map[p]*detadz_map[p] + 00347 d2phideta2[i][p]*detadz_map[p]*detadz_map[p]; 00348 #endif 00349 } 00350 00351 break; 00352 } 00353 00354 case 3: 00355 { 00356 const std::vector<std::vector<OutputShape> >& d2phidxi2 = fe.get_d2phidxi2(); 00357 const std::vector<std::vector<OutputShape> >& d2phidxideta = fe.get_d2phidxideta(); 00358 const std::vector<std::vector<OutputShape> >& d2phideta2 = fe.get_d2phideta2(); 00359 const std::vector<std::vector<OutputShape> >& d2phidxidzeta = fe.get_d2phidxidzeta(); 00360 const std::vector<std::vector<OutputShape> >& d2phidetadzeta = fe.get_d2phidetadzeta(); 00361 const std::vector<std::vector<OutputShape> >& d2phidzeta2 = fe.get_d2phidzeta2(); 00362 00363 const std::vector<Real>& dxidx_map = fe.get_fe_map().get_dxidx(); 00364 const std::vector<Real>& dxidy_map = fe.get_fe_map().get_dxidy(); 00365 const std::vector<Real>& dxidz_map = fe.get_fe_map().get_dxidz(); 00366 00367 const std::vector<Real>& detadx_map = fe.get_fe_map().get_detadx(); 00368 const std::vector<Real>& detady_map = fe.get_fe_map().get_detady(); 00369 const std::vector<Real>& detadz_map = fe.get_fe_map().get_detadz(); 00370 00371 const std::vector<Real>& dzetadx_map = fe.get_fe_map().get_dzetadx(); 00372 const std::vector<Real>& dzetady_map = fe.get_fe_map().get_dzetady(); 00373 const std::vector<Real>& dzetadz_map = fe.get_fe_map().get_dzetadz(); 00374 00375 for (unsigned int i=0; i<d2phi.size(); i++) 00376 for (unsigned int p=0; p<d2phi[i].size(); p++) 00377 { 00378 d2phi[i][p].slice(0).slice(0) = d2phidx2[i][p] = 00379 d2phidxi2[i][p]*dxidx_map[p]*dxidx_map[p] + 00380 2*d2phidxideta[i][p]*dxidx_map[p]*detadx_map[p] + 00381 2*d2phidxidzeta[i][p]*dxidx_map[p]*dzetadx_map[p] + 00382 2*d2phidetadzeta[i][p]*detadx_map[p]*dzetadx_map[p] + 00383 d2phideta2[i][p]*detadx_map[p]*detadx_map[p] + 00384 d2phidzeta2[i][p]*dzetadx_map[p]*dzetadx_map[p]; 00385 00386 d2phi[i][p].slice(0).slice(1) = 00387 d2phi[i][p].slice(1).slice(0) = d2phidxdy[i][p] = 00388 d2phidxi2[i][p]*dxidx_map[p]*dxidy_map[p] + 00389 d2phidxideta[i][p]*dxidx_map[p]*detady_map[p] + 00390 d2phidxidzeta[i][p]*dxidx_map[p]*dzetady_map[p] + 00391 d2phideta2[i][p]*detadx_map[p]*detady_map[p] + 00392 d2phidxideta[i][p]*detadx_map[p]*dxidy_map[p] + 00393 d2phidetadzeta[i][p]*detadx_map[p]*dzetady_map[p] + 00394 d2phidzeta2[i][p]*dzetadx_map[p]*dzetady_map[p] + 00395 d2phidxidzeta[i][p]*dzetadx_map[p]*dxidy_map[p] + 00396 d2phidetadzeta[i][p]*dzetadx_map[p]*detady_map[p]; 00397 00398 d2phi[i][p].slice(0).slice(2) = 00399 d2phi[i][p].slice(2).slice(0) = d2phidy2[i][p] = 00400 d2phidxi2[i][p]*dxidx_map[p]*dxidz_map[p] + 00401 d2phidxideta[i][p]*dxidx_map[p]*detadz_map[p] + 00402 d2phidxidzeta[i][p]*dxidx_map[p]*dzetadz_map[p] + 00403 d2phideta2[i][p]*detadx_map[p]*detadz_map[p] + 00404 d2phidxideta[i][p]*detadx_map[p]*dxidz_map[p] + 00405 d2phidetadzeta[i][p]*detadx_map[p]*dzetadz_map[p] + 00406 d2phidzeta2[i][p]*dzetadx_map[p]*dzetadz_map[p] + 00407 d2phidxidzeta[i][p]*dzetadx_map[p]*dxidz_map[p] + 00408 d2phidetadzeta[i][p]*dzetadx_map[p]*detadz_map[p]; 00409 00410 d2phi[i][p].slice(1).slice(1) = d2phidxdz[i][p] = 00411 d2phidxi2[i][p]*dxidy_map[p]*dxidy_map[p] + 00412 2*d2phidxideta[i][p]*dxidy_map[p]*detady_map[p] + 00413 2*d2phidxidzeta[i][p]*dxidy_map[p]*dzetady_map[p] + 00414 2*d2phidetadzeta[i][p]*detady_map[p]*dzetady_map[p] + 00415 d2phideta2[i][p]*detady_map[p]*detady_map[p] + 00416 d2phidzeta2[i][p]*dzetady_map[p]*dzetady_map[p]; 00417 00418 d2phi[i][p].slice(1).slice(2) = 00419 d2phi[i][p].slice(2).slice(1) = d2phidydz[i][p] = 00420 d2phidxi2[i][p]*dxidy_map[p]*dxidz_map[p] + 00421 d2phidxideta[i][p]*dxidy_map[p]*detadz_map[p] + 00422 d2phidxidzeta[i][p]*dxidy_map[p]*dzetadz_map[p] + 00423 d2phideta2[i][p]*detady_map[p]*detadz_map[p] + 00424 d2phidxideta[i][p]*detady_map[p]*dxidz_map[p] + 00425 d2phidetadzeta[i][p]*detady_map[p]*dzetadz_map[p] + 00426 d2phidzeta2[i][p]*dzetady_map[p]*dzetadz_map[p] + 00427 d2phidxidzeta[i][p]*dzetady_map[p]*dxidz_map[p] + 00428 d2phidetadzeta[i][p]*dzetady_map[p]*detadz_map[p]; 00429 00430 d2phi[i][p].slice(2).slice(2) = d2phidz2[i][p] = 00431 d2phidxi2[i][p]*dxidz_map[p]*dxidz_map[p] + 00432 2*d2phidxideta[i][p]*dxidz_map[p]*detadz_map[p] + 00433 2*d2phidxidzeta[i][p]*dxidz_map[p]*dzetadz_map[p] + 00434 2*d2phidetadzeta[i][p]*detadz_map[p]*dzetadz_map[p] + 00435 d2phideta2[i][p]*detadz_map[p]*detadz_map[p] + 00436 d2phidzeta2[i][p]*dzetadz_map[p]*dzetadz_map[p]; 00437 } 00438 00439 break; 00440 } 00441 00442 default: 00443 libmesh_error_msg("Invalid dim = " << dim); 00444 } // switch(dim) 00445 } 00446 #endif //LIBMESH_ENABLE_SECOND_DERIVATIVES 00447 00448 template< > 00449 void H1FETransformation<Real>::map_curl( const unsigned int, 00450 const Elem* const, 00451 const std::vector<Point>&, 00452 const FEGenericBase<Real>&, 00453 std::vector<std::vector<Real> >& ) const 00454 { 00455 libmesh_error_msg("Computing the curl of a shape function only \nmakes sense for vector-valued elements."); 00456 } 00457 00458 template< > 00459 void H1FETransformation<RealGradient>::map_curl( const unsigned int dim, 00460 const Elem* const, 00461 const std::vector<Point>&, 00462 const FEGenericBase<RealGradient>& fe, 00463 std::vector<std::vector<RealGradient> >& curl_phi ) const 00464 { 00465 switch (dim) 00466 { 00467 case 0: 00468 case 1: 00469 libmesh_error_msg("The curl only make sense in 2D and 3D"); 00470 00471 case 2: 00472 { 00473 const std::vector<std::vector<RealGradient> >& dphidxi = fe.get_dphidxi(); 00474 const std::vector<std::vector<RealGradient> >& dphideta = fe.get_dphideta(); 00475 00476 const std::vector<Real>& dxidx_map = fe.get_fe_map().get_dxidx(); 00477 const std::vector<Real>& dxidy_map = fe.get_fe_map().get_dxidy(); 00478 #if LIBMESH_DIM > 2 00479 const std::vector<Real>& dxidz_map = fe.get_fe_map().get_dxidz(); 00480 #endif 00481 00482 const std::vector<Real>& detadx_map = fe.get_fe_map().get_detadx(); 00483 const std::vector<Real>& detady_map = fe.get_fe_map().get_detady(); 00484 #if LIBMESH_DIM > 2 00485 const std::vector<Real>& detadz_map = fe.get_fe_map().get_detadz(); 00486 #endif 00487 00488 /* 00489 For 2D elements in 3D space: 00490 00491 curl = ( -dphi_y/dz, dphi_x/dz, dphi_y/dx - dphi_x/dy ) 00492 */ 00493 for (unsigned int i=0; i<curl_phi.size(); i++) 00494 for (unsigned int p=0; p<curl_phi[i].size(); p++) 00495 { 00496 00497 Real dphiy_dx = (dphidxi[i][p].slice(1))*dxidx_map[p] 00498 + (dphideta[i][p].slice(1))*detadx_map[p]; 00499 00500 Real dphix_dy = (dphidxi[i][p].slice(0))*dxidy_map[p] 00501 + (dphideta[i][p].slice(0))*detady_map[p]; 00502 00503 curl_phi[i][p].slice(2) = dphiy_dx - dphix_dy; 00504 00505 #if LIBMESH_DIM > 2 00506 Real dphiy_dz = (dphidxi[i][p].slice(1))*dxidz_map[p] 00507 + (dphideta[i][p].slice(1))*detadz_map[p]; 00508 00509 Real dphix_dz = (dphidxi[i][p].slice(0))*dxidz_map[p] 00510 + (dphideta[i][p].slice(0))*detadz_map[p]; 00511 00512 curl_phi[i][p].slice(0) = -dphiy_dz; 00513 curl_phi[i][p].slice(1) = dphix_dz; 00514 #endif 00515 } 00516 00517 break; 00518 } 00519 case 3: 00520 { 00521 const std::vector<std::vector<RealGradient> >& dphidxi = fe.get_dphidxi(); 00522 const std::vector<std::vector<RealGradient> >& dphideta = fe.get_dphideta(); 00523 const std::vector<std::vector<RealGradient> >& dphidzeta = fe.get_dphidzeta(); 00524 00525 const std::vector<Real>& dxidx_map = fe.get_fe_map().get_dxidx(); 00526 const std::vector<Real>& dxidy_map = fe.get_fe_map().get_dxidy(); 00527 const std::vector<Real>& dxidz_map = fe.get_fe_map().get_dxidz(); 00528 00529 const std::vector<Real>& detadx_map = fe.get_fe_map().get_detadx(); 00530 const std::vector<Real>& detady_map = fe.get_fe_map().get_detady(); 00531 const std::vector<Real>& detadz_map = fe.get_fe_map().get_detadz(); 00532 00533 const std::vector<Real>& dzetadx_map = fe.get_fe_map().get_dzetadx(); 00534 const std::vector<Real>& dzetady_map = fe.get_fe_map().get_dzetady(); 00535 const std::vector<Real>& dzetadz_map = fe.get_fe_map().get_dzetadz(); 00536 00537 /* 00538 In 3D: curl = ( dphi_z/dy - dphi_y/dz, dphi_x/dz - dphi_z/dx, dphi_y/dx - dphi_x/dy ) 00539 */ 00540 for (unsigned int i=0; i<curl_phi.size(); i++) 00541 for (unsigned int p=0; p<curl_phi[i].size(); p++) 00542 { 00543 Real dphiz_dy = (dphidxi[i][p].slice(2))*dxidy_map[p] 00544 + (dphideta[i][p].slice(2))*detady_map[p] 00545 + (dphidzeta[i][p].slice(2))*dzetady_map[p]; 00546 00547 Real dphiy_dz = (dphidxi[i][p].slice(1))*dxidz_map[p] 00548 + (dphideta[i][p].slice(1))*detadz_map[p] 00549 + (dphidzeta[i][p].slice(1))*dzetadz_map[p]; 00550 00551 Real dphix_dz = (dphidxi[i][p].slice(0))*dxidz_map[p] 00552 + (dphideta[i][p].slice(0))*detadz_map[p] 00553 + (dphidzeta[i][p].slice(0))*dzetadz_map[p]; 00554 00555 Real dphiz_dx = (dphidxi[i][p].slice(2))*dxidx_map[p] 00556 + (dphideta[i][p].slice(2))*detadx_map[p] 00557 + (dphidzeta[i][p].slice(2))*dzetadx_map[p]; 00558 00559 Real dphiy_dx = (dphidxi[i][p].slice(1))*dxidx_map[p] 00560 + (dphideta[i][p].slice(1))*detadx_map[p] 00561 + (dphidzeta[i][p].slice(1))*dzetadx_map[p]; 00562 00563 Real dphix_dy = (dphidxi[i][p].slice(0))*dxidy_map[p] 00564 + (dphideta[i][p].slice(0))*detady_map[p] 00565 + (dphidzeta[i][p].slice(0))*dzetady_map[p]; 00566 00567 curl_phi[i][p].slice(0) = dphiz_dy - dphiy_dz; 00568 00569 curl_phi[i][p].slice(1) = dphix_dz - dphiz_dx; 00570 00571 curl_phi[i][p].slice(2) = dphiy_dx - dphix_dy; 00572 } 00573 00574 break; 00575 } 00576 default: 00577 libmesh_error_msg("Invalid dim = " << dim); 00578 } 00579 } 00580 00581 00582 template< > 00583 void H1FETransformation<Real>::map_div 00584 (const unsigned int, 00585 const Elem* const, 00586 const std::vector<Point>&, 00587 const FEGenericBase<Real>&, 00588 std::vector<std::vector<FEGenericBase<Real>::OutputDivergence> >& ) const 00589 { 00590 libmesh_error_msg("Computing the divergence of a shape function only \nmakes sense for vector-valued elements."); 00591 } 00592 00593 00594 template<> 00595 void H1FETransformation<RealGradient>::map_div 00596 (const unsigned int dim, 00597 const Elem* const, 00598 const std::vector<Point>&, 00599 const FEGenericBase<RealGradient>& fe, 00600 std::vector<std::vector<FEGenericBase<RealGradient>::OutputDivergence> >& div_phi) const 00601 { 00602 switch (dim) 00603 { 00604 case 0: 00605 case 1: 00606 libmesh_error_msg("The divergence only make sense in 2D and 3D"); 00607 00608 case 2: 00609 { 00610 const std::vector<std::vector<RealGradient> >& dphidxi = fe.get_dphidxi(); 00611 const std::vector<std::vector<RealGradient> >& dphideta = fe.get_dphideta(); 00612 00613 const std::vector<Real>& dxidx_map = fe.get_fe_map().get_dxidx(); 00614 const std::vector<Real>& dxidy_map = fe.get_fe_map().get_dxidy(); 00615 00616 const std::vector<Real>& detadx_map = fe.get_fe_map().get_detadx(); 00617 const std::vector<Real>& detady_map = fe.get_fe_map().get_detady(); 00618 00619 /* 00620 In 2D: div = dphi_x/dx + dphi_y/dy 00621 */ 00622 for (unsigned int i=0; i<div_phi.size(); i++) 00623 for (unsigned int p=0; p<div_phi[i].size(); p++) 00624 { 00625 00626 Real dphix_dx = (dphidxi[i][p].slice(0))*dxidx_map[p] 00627 + (dphideta[i][p].slice(0))*detadx_map[p]; 00628 00629 Real dphiy_dy = (dphidxi[i][p].slice(1))*dxidy_map[p] 00630 + (dphideta[i][p].slice(1))*detady_map[p]; 00631 00632 div_phi[i][p] = dphix_dx + dphiy_dy; 00633 } 00634 break; 00635 } 00636 case 3: 00637 { 00638 const std::vector<std::vector<RealGradient> >& dphidxi = fe.get_dphidxi(); 00639 const std::vector<std::vector<RealGradient> >& dphideta = fe.get_dphideta(); 00640 const std::vector<std::vector<RealGradient> >& dphidzeta = fe.get_dphidzeta(); 00641 00642 const std::vector<Real>& dxidx_map = fe.get_fe_map().get_dxidx(); 00643 const std::vector<Real>& dxidy_map = fe.get_fe_map().get_dxidy(); 00644 const std::vector<Real>& dxidz_map = fe.get_fe_map().get_dxidz(); 00645 00646 const std::vector<Real>& detadx_map = fe.get_fe_map().get_detadx(); 00647 const std::vector<Real>& detady_map = fe.get_fe_map().get_detady(); 00648 const std::vector<Real>& detadz_map = fe.get_fe_map().get_detadz(); 00649 00650 const std::vector<Real>& dzetadx_map = fe.get_fe_map().get_dzetadx(); 00651 const std::vector<Real>& dzetady_map = fe.get_fe_map().get_dzetady(); 00652 const std::vector<Real>& dzetadz_map = fe.get_fe_map().get_dzetadz(); 00653 00654 /* 00655 In 3D: div = dphi_x/dx + dphi_y/dy + dphi_z/dz 00656 */ 00657 for (unsigned int i=0; i<div_phi.size(); i++) 00658 for (unsigned int p=0; p<div_phi[i].size(); p++) 00659 { 00660 Real dphix_dx = (dphidxi[i][p].slice(0))*dxidx_map[p] 00661 + (dphideta[i][p].slice(0))*detadx_map[p] 00662 + (dphidzeta[i][p].slice(0))*dzetadx_map[p]; 00663 00664 Real dphiy_dy = (dphidxi[i][p].slice(1))*dxidy_map[p] 00665 + (dphideta[i][p].slice(1))*detady_map[p] 00666 + (dphidzeta[i][p].slice(1))*dzetady_map[p]; 00667 00668 Real dphiz_dz = (dphidxi[i][p].slice(2))*dxidz_map[p] 00669 + (dphideta[i][p].slice(2))*detadz_map[p] 00670 + (dphidzeta[i][p].slice(2))*dzetadz_map[p]; 00671 00672 div_phi[i][p] = dphix_dx + dphiy_dy + dphiz_dz; 00673 } 00674 00675 break; 00676 } 00677 00678 default: \ 00679 libmesh_error_msg("Invalid dim = " << dim); \ 00680 } // switch(dim) 00681 00682 return; 00683 } 00684 00685 // Explicit Instantations 00686 template class H1FETransformation<Real>; 00687 template class H1FETransformation<RealGradient>; 00688 00689 } //namespace libMesh