$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 00019 // C++ inlcludes 00020 00021 // Local includes 00022 #include "libmesh/fe.h" 00023 #include "libmesh/elem.h" 00024 00025 00026 00027 00028 // Anonymous namespace for persistant variables. 00029 // This allows us to determine when the centroid needs 00030 // to be recalculated. 00031 namespace 00032 { 00033 using namespace libMesh; 00034 00035 static dof_id_type old_elem_id = DofObject::invalid_id; 00036 static Point centroid; 00037 static Point max_distance; 00038 } 00039 00040 00041 namespace libMesh 00042 { 00043 00044 00045 template <> 00046 Real FE<3,XYZ>::shape(const ElemType, 00047 const Order, 00048 const unsigned int, 00049 const Point&) 00050 { 00051 libmesh_error_msg("XYZ polynomials require the element because the centroid is needed."); 00052 return 0.; 00053 } 00054 00055 00056 00057 template <> 00058 Real FE<3,XYZ>::shape(const Elem* elem, 00059 const Order libmesh_dbg_var(order), 00060 const unsigned int i, 00061 const Point& point_in) 00062 { 00063 #if LIBMESH_DIM == 3 00064 libmesh_assert(elem); 00065 00066 // Only recompute the centroid if the element 00067 // has changed from the last one we computed. 00068 // This avoids repeated centroid calculations 00069 // when called in succession with the same element. 00070 if (elem->id() != old_elem_id) 00071 { 00072 centroid = elem->centroid(); 00073 old_elem_id = elem->id(); 00074 max_distance = Point(0.,0.,0.); 00075 for (unsigned int p = 0; p < elem->n_nodes(); p++) 00076 for (unsigned int d = 0; d < 3; d++) 00077 { 00078 const Real distance = std::abs(centroid(d) - elem->point(p)(d)); 00079 max_distance(d) = std::max(distance, max_distance(d)); 00080 } 00081 } 00082 00083 // Using static globals for old_elem_id, etc. will fail 00084 // horribly with more than one thread. 00085 libmesh_assert_equal_to (libMesh::n_threads(), 1); 00086 00087 const Real x = point_in(0); 00088 const Real y = point_in(1); 00089 const Real z = point_in(2); 00090 const Real xc = centroid(0); 00091 const Real yc = centroid(1); 00092 const Real zc = centroid(2); 00093 const Real distx = max_distance(0); 00094 const Real disty = max_distance(1); 00095 const Real distz = max_distance(2); 00096 const Real dx = (x - xc)/distx; 00097 const Real dy = (y - yc)/disty; 00098 const Real dz = (z - zc)/distz; 00099 00100 #ifndef NDEBUG 00101 // totalorder is only used in the assertion below, so 00102 // we avoid declaring it when asserts are not active. 00103 const unsigned int totalorder = order + elem->p_level(); 00104 #endif 00105 libmesh_assert_less (i, (static_cast<unsigned int>(totalorder)+1)* 00106 (static_cast<unsigned int>(totalorder)+2)* 00107 (static_cast<unsigned int>(totalorder)+3)/6); 00108 00109 // monomials. since they are hierarchic we only need one case block. 00110 switch (i) 00111 { 00112 // constant 00113 case 0: 00114 return 1.; 00115 00116 // linears 00117 case 1: 00118 return dx; 00119 00120 case 2: 00121 return dy; 00122 00123 case 3: 00124 return dz; 00125 00126 // quadratics 00127 case 4: 00128 return dx*dx; 00129 00130 case 5: 00131 return dx*dy; 00132 00133 case 6: 00134 return dy*dy; 00135 00136 case 7: 00137 return dx*dz; 00138 00139 case 8: 00140 return dz*dy; 00141 00142 case 9: 00143 return dz*dz; 00144 00145 // cubics 00146 case 10: 00147 return dx*dx*dx; 00148 00149 case 11: 00150 return dx*dx*dy; 00151 00152 case 12: 00153 return dx*dy*dy; 00154 00155 case 13: 00156 return dy*dy*dy; 00157 00158 case 14: 00159 return dx*dx*dz; 00160 00161 case 15: 00162 return dx*dy*dz; 00163 00164 case 16: 00165 return dy*dy*dz; 00166 00167 case 17: 00168 return dx*dz*dz; 00169 00170 case 18: 00171 return dy*dz*dz; 00172 00173 case 19: 00174 return dz*dz*dz; 00175 00176 // quartics 00177 case 20: 00178 return dx*dx*dx*dx; 00179 00180 case 21: 00181 return dx*dx*dx*dy; 00182 00183 case 22: 00184 return dx*dx*dy*dy; 00185 00186 case 23: 00187 return dx*dy*dy*dy; 00188 00189 case 24: 00190 return dy*dy*dy*dy; 00191 00192 case 25: 00193 return dx*dx*dx*dz; 00194 00195 case 26: 00196 return dx*dx*dy*dz; 00197 00198 case 27: 00199 return dx*dy*dy*dz; 00200 00201 case 28: 00202 return dy*dy*dy*dz; 00203 00204 case 29: 00205 return dx*dx*dz*dz; 00206 00207 case 30: 00208 return dx*dy*dz*dz; 00209 00210 case 31: 00211 return dy*dy*dz*dz; 00212 00213 case 32: 00214 return dx*dz*dz*dz; 00215 00216 case 33: 00217 return dy*dz*dz*dz; 00218 00219 case 34: 00220 return dz*dz*dz*dz; 00221 00222 default: 00223 unsigned int o = 0; 00224 for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { } 00225 unsigned int i2 = i - (o*(o+1)*(o+2)/6); 00226 unsigned int block=o, nz = 0; 00227 for (; block < i2; block += (o-nz+1)) { nz++; } 00228 const unsigned int nx = block - i2; 00229 const unsigned int ny = o - nx - nz; 00230 Real val = 1.; 00231 for (unsigned int index=0; index != nx; index++) 00232 val *= dx; 00233 for (unsigned int index=0; index != ny; index++) 00234 val *= dy; 00235 for (unsigned int index=0; index != nz; index++) 00236 val *= dz; 00237 return val; 00238 } 00239 00240 #endif 00241 00242 libmesh_error_msg("We'll never get here!"); 00243 return 0.; 00244 } 00245 00246 00247 00248 template <> 00249 Real FE<3,XYZ>::shape_deriv(const ElemType, 00250 const Order, 00251 const unsigned int, 00252 const unsigned int, 00253 const Point&) 00254 { 00255 libmesh_error_msg("XYZ polynomials require the element \nbecause the centroid is needed."); 00256 return 0.; 00257 } 00258 00259 00260 00261 template <> 00262 Real FE<3,XYZ>::shape_deriv(const Elem* elem, 00263 const Order libmesh_dbg_var(order), 00264 const unsigned int i, 00265 const unsigned int j, 00266 const Point& point_in) 00267 { 00268 #if LIBMESH_DIM == 3 00269 00270 libmesh_assert(elem); 00271 libmesh_assert_less (j, 3); 00272 00273 // Only recompute the centroid if the element 00274 // has changed from the last one we computed. 00275 // This avoids repeated centroid calculations 00276 // when called in succession with the same element. 00277 if (elem->id() != old_elem_id) 00278 { 00279 centroid = elem->centroid(); 00280 old_elem_id = elem->id(); 00281 max_distance = Point(0.,0.,0.); 00282 for (unsigned int p = 0; p < elem->n_nodes(); p++) 00283 for (unsigned int d = 0; d < 3; d++) 00284 { 00285 const Real distance = std::abs(centroid(d) - elem->point(p)(d)); 00286 max_distance(d) = std::max(distance, max_distance(d)); 00287 } 00288 } 00289 00290 // Using static globals for old_elem_id, etc. will fail 00291 // horribly with more than one thread. 00292 libmesh_assert_equal_to (libMesh::n_threads(), 1); 00293 00294 const Real x = point_in(0); 00295 const Real y = point_in(1); 00296 const Real z = point_in(2); 00297 const Real xc = centroid(0); 00298 const Real yc = centroid(1); 00299 const Real zc = centroid(2); 00300 const Real distx = max_distance(0); 00301 const Real disty = max_distance(1); 00302 const Real distz = max_distance(2); 00303 const Real dx = (x - xc)/distx; 00304 const Real dy = (y - yc)/disty; 00305 const Real dz = (z - zc)/distz; 00306 00307 #ifndef NDEBUG 00308 // totalorder is only used in the assertion below, so 00309 // we avoid declaring it when asserts are not active. 00310 const unsigned int totalorder = static_cast<Order>(order + elem->p_level()); 00311 #endif 00312 libmesh_assert_less (i, (static_cast<unsigned int>(totalorder)+1)* 00313 (static_cast<unsigned int>(totalorder)+2)* 00314 (static_cast<unsigned int>(totalorder)+3)/6); 00315 00316 switch (j) 00317 { 00318 // d()/dx 00319 case 0: 00320 { 00321 switch (i) 00322 { 00323 // constant 00324 case 0: 00325 return 0.; 00326 00327 // linear 00328 case 1: 00329 return 1./distx; 00330 00331 case 2: 00332 return 0.; 00333 00334 case 3: 00335 return 0.; 00336 00337 // quadratic 00338 case 4: 00339 return 2.*dx/distx; 00340 00341 case 5: 00342 return dy/distx; 00343 00344 case 6: 00345 return 0.; 00346 00347 case 7: 00348 return dz/distx; 00349 00350 case 8: 00351 return 0.; 00352 00353 case 9: 00354 return 0.; 00355 00356 // cubic 00357 case 10: 00358 return 3.*dx*dx/distx; 00359 00360 case 11: 00361 return 2.*dx*dy/distx; 00362 00363 case 12: 00364 return dy*dy/distx; 00365 00366 case 13: 00367 return 0.; 00368 00369 case 14: 00370 return 2.*dx*dz/distx; 00371 00372 case 15: 00373 return dy*dz/distx; 00374 00375 case 16: 00376 return 0.; 00377 00378 case 17: 00379 return dz*dz/distx; 00380 00381 case 18: 00382 return 0.; 00383 00384 case 19: 00385 return 0.; 00386 00387 // quartics 00388 case 20: 00389 return 4.*dx*dx*dx/distx; 00390 00391 case 21: 00392 return 3.*dx*dx*dy/distx; 00393 00394 case 22: 00395 return 2.*dx*dy*dy/distx; 00396 00397 case 23: 00398 return dy*dy*dy/distx; 00399 00400 case 24: 00401 return 0.; 00402 00403 case 25: 00404 return 3.*dx*dx*dz/distx; 00405 00406 case 26: 00407 return 2.*dx*dy*dz/distx; 00408 00409 case 27: 00410 return dy*dy*dz/distx; 00411 00412 case 28: 00413 return 0.; 00414 00415 case 29: 00416 return 2.*dx*dz*dz/distx; 00417 00418 case 30: 00419 return dy*dz*dz/distx; 00420 00421 case 31: 00422 return 0.; 00423 00424 case 32: 00425 return dz*dz*dz/distx; 00426 00427 case 33: 00428 return 0.; 00429 00430 case 34: 00431 return 0.; 00432 00433 default: 00434 unsigned int o = 0; 00435 for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { } 00436 unsigned int i2 = i - (o*(o+1)*(o+2)/6); 00437 unsigned int block=o, nz = 0; 00438 for (; block < i2; block += (o-nz+1)) { nz++; } 00439 const unsigned int nx = block - i2; 00440 const unsigned int ny = o - nx - nz; 00441 Real val = nx; 00442 for (unsigned int index=1; index < nx; index++) 00443 val *= dx; 00444 for (unsigned int index=0; index != ny; index++) 00445 val *= dy; 00446 for (unsigned int index=0; index != nz; index++) 00447 val *= dz; 00448 return val/distx; 00449 } 00450 } 00451 00452 00453 // d()/dy 00454 case 1: 00455 { 00456 switch (i) 00457 { 00458 // constant 00459 case 0: 00460 return 0.; 00461 00462 // linear 00463 case 1: 00464 return 0.; 00465 00466 case 2: 00467 return 1./disty; 00468 00469 case 3: 00470 return 0.; 00471 00472 // quadratic 00473 case 4: 00474 return 0.; 00475 00476 case 5: 00477 return dx/disty; 00478 00479 case 6: 00480 return 2.*dy/disty; 00481 00482 case 7: 00483 return 0.; 00484 00485 case 8: 00486 return dz/disty; 00487 00488 case 9: 00489 return 0.; 00490 00491 // cubic 00492 case 10: 00493 return 0.; 00494 00495 case 11: 00496 return dx*dx/disty; 00497 00498 case 12: 00499 return 2.*dx*dy/disty; 00500 00501 case 13: 00502 return 3.*dy*dy/disty; 00503 00504 case 14: 00505 return 0.; 00506 00507 case 15: 00508 return dx*dz/disty; 00509 00510 case 16: 00511 return 2.*dy*dz/disty; 00512 00513 case 17: 00514 return 0.; 00515 00516 case 18: 00517 return dz*dz/disty; 00518 00519 case 19: 00520 return 0.; 00521 00522 // quartics 00523 case 20: 00524 return 0.; 00525 00526 case 21: 00527 return dx*dx*dx/disty; 00528 00529 case 22: 00530 return 2.*dx*dx*dy/disty; 00531 00532 case 23: 00533 return 3.*dx*dy*dy/disty; 00534 00535 case 24: 00536 return 4.*dy*dy*dy/disty; 00537 00538 case 25: 00539 return 0.; 00540 00541 case 26: 00542 return dx*dx*dz/disty; 00543 00544 case 27: 00545 return 2.*dx*dy*dz/disty; 00546 00547 case 28: 00548 return 3.*dy*dy*dz/disty; 00549 00550 case 29: 00551 return 0.; 00552 00553 case 30: 00554 return dx*dz*dz/disty; 00555 00556 case 31: 00557 return 2.*dy*dz*dz/disty; 00558 00559 case 32: 00560 return 0.; 00561 00562 case 33: 00563 return dz*dz*dz/disty; 00564 00565 case 34: 00566 return 0.; 00567 00568 default: 00569 unsigned int o = 0; 00570 for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { } 00571 unsigned int i2 = i - (o*(o+1)*(o+2)/6); 00572 unsigned int block=o, nz = 0; 00573 for (; block < i2; block += (o-nz+1)) { nz++; } 00574 const unsigned int nx = block - i2; 00575 const unsigned int ny = o - nx - nz; 00576 Real val = ny; 00577 for (unsigned int index=0; index != nx; index++) 00578 val *= dx; 00579 for (unsigned int index=1; index < ny; index++) 00580 val *= dy; 00581 for (unsigned int index=0; index != nz; index++) 00582 val *= dz; 00583 return val/disty; 00584 } 00585 } 00586 00587 00588 // d()/dz 00589 case 2: 00590 { 00591 switch (i) 00592 { 00593 // constant 00594 case 0: 00595 return 0.; 00596 00597 // linear 00598 case 1: 00599 return 0.; 00600 00601 case 2: 00602 return 0.; 00603 00604 case 3: 00605 return 1./distz; 00606 00607 // quadratic 00608 case 4: 00609 return 0.; 00610 00611 case 5: 00612 return 0.; 00613 00614 case 6: 00615 return 0.; 00616 00617 case 7: 00618 return dx/distz; 00619 00620 case 8: 00621 return dy/distz; 00622 00623 case 9: 00624 return 2.*dz/distz; 00625 00626 // cubic 00627 case 10: 00628 return 0.; 00629 00630 case 11: 00631 return 0.; 00632 00633 case 12: 00634 return 0.; 00635 00636 case 13: 00637 return 0.; 00638 00639 case 14: 00640 return dx*dx/distz; 00641 00642 case 15: 00643 return dx*dy/distz; 00644 00645 case 16: 00646 return dy*dy/distz; 00647 00648 case 17: 00649 return 2.*dx*dz/distz; 00650 00651 case 18: 00652 return 2.*dy*dz/distz; 00653 00654 case 19: 00655 return 3.*dz*dz/distz; 00656 00657 // quartics 00658 case 20: 00659 return 0.; 00660 00661 case 21: 00662 return 0.; 00663 00664 case 22: 00665 return 0.; 00666 00667 case 23: 00668 return 0.; 00669 00670 case 24: 00671 return 0.; 00672 00673 case 25: 00674 return dx*dx*dx/distz; 00675 00676 case 26: 00677 return dx*dx*dy/distz; 00678 00679 case 27: 00680 return dx*dy*dy/distz; 00681 00682 case 28: 00683 return dy*dy*dy/distz; 00684 00685 case 29: 00686 return 2.*dx*dx*dz/distz; 00687 00688 case 30: 00689 return 2.*dx*dy*dz/distz; 00690 00691 case 31: 00692 return 2.*dy*dy*dz/distz; 00693 00694 case 32: 00695 return 3.*dx*dz*dz/distz; 00696 00697 case 33: 00698 return 3.*dy*dz*dz/distz; 00699 00700 case 34: 00701 return 4.*dz*dz*dz/distz; 00702 00703 default: 00704 unsigned int o = 0; 00705 for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { } 00706 unsigned int i2 = i - (o*(o+1)*(o+2)/6); 00707 unsigned int block=o, nz = 0; 00708 for (; block < i2; block += (o-nz+1)) { nz++; } 00709 const unsigned int nx = block - i2; 00710 const unsigned int ny = o - nx - nz; 00711 Real val = nz; 00712 for (unsigned int index=0; index != nx; index++) 00713 val *= dx; 00714 for (unsigned int index=0; index != ny; index++) 00715 val *= dy; 00716 for (unsigned int index=1; index < nz; index++) 00717 val *= dz; 00718 return val/distz; 00719 } 00720 } 00721 00722 00723 default: 00724 libmesh_error_msg("Invalid j = " << j); 00725 } 00726 00727 #endif 00728 00729 libmesh_error_msg("We'll never get here!"); 00730 return 0.; 00731 } 00732 00733 00734 00735 template <> 00736 Real FE<3,XYZ>::shape_second_deriv(const ElemType, 00737 const Order, 00738 const unsigned int, 00739 const unsigned int, 00740 const Point&) 00741 { 00742 libmesh_error_msg("XYZ polynomials require the element \nbecause the centroid is needed."); 00743 return 0.; 00744 } 00745 00746 00747 00748 template <> 00749 Real FE<3,XYZ>::shape_second_deriv(const Elem* elem, 00750 const Order libmesh_dbg_var(order), 00751 const unsigned int i, 00752 const unsigned int j, 00753 const Point& point_in) 00754 { 00755 #if LIBMESH_DIM == 3 00756 00757 libmesh_assert(elem); 00758 libmesh_assert_less (j, 6); 00759 00760 // Only recompute the centroid if the element 00761 // has changed from the last one we computed. 00762 // This avoids repeated centroid calculations 00763 // when called in succession with the same element. 00764 if (elem->id() != old_elem_id) 00765 { 00766 centroid = elem->centroid(); 00767 old_elem_id = elem->id(); 00768 max_distance = Point(0.,0.,0.); 00769 for (unsigned int p = 0; p < elem->n_nodes(); p++) 00770 for (unsigned int d = 0; d < 3; d++) 00771 { 00772 const Real distance = std::abs(centroid(d) - elem->point(p)(d)); 00773 max_distance(d) = std::max(distance, max_distance(d)); 00774 } 00775 } 00776 00777 // Using static globals for old_elem_id, etc. will fail 00778 // horribly with more than one thread. 00779 libmesh_assert_equal_to (libMesh::n_threads(), 1); 00780 00781 const Real x = point_in(0); 00782 const Real y = point_in(1); 00783 const Real z = point_in(2); 00784 const Real xc = centroid(0); 00785 const Real yc = centroid(1); 00786 const Real zc = centroid(2); 00787 const Real distx = max_distance(0); 00788 const Real disty = max_distance(1); 00789 const Real distz = max_distance(2); 00790 const Real dx = (x - xc)/distx; 00791 const Real dy = (y - yc)/disty; 00792 const Real dz = (z - zc)/distz; 00793 const Real dist2x = pow(distx,2.); 00794 const Real dist2y = pow(disty,2.); 00795 const Real dist2z = pow(distz,2.); 00796 const Real distxy = distx * disty; 00797 const Real distxz = distx * distz; 00798 const Real distyz = disty * distz; 00799 00800 #ifndef NDEBUG 00801 // totalorder is only used in the assertion below, so 00802 // we avoid declaring it when asserts are not active. 00803 const unsigned int totalorder = static_cast<Order>(order + elem->p_level()); 00804 #endif 00805 libmesh_assert_less (i, (static_cast<unsigned int>(totalorder)+1)* 00806 (static_cast<unsigned int>(totalorder)+2)* 00807 (static_cast<unsigned int>(totalorder)+3)/6); 00808 00809 // monomials. since they are hierarchic we only need one case block. 00810 switch (j) 00811 { 00812 // d^2()/dx^2 00813 case 0: 00814 { 00815 switch (i) 00816 { 00817 // constant 00818 case 0: 00819 00820 // linear 00821 case 1: 00822 case 2: 00823 case 3: 00824 return 0.; 00825 00826 // quadratic 00827 case 4: 00828 return 2./dist2x; 00829 00830 case 5: 00831 case 6: 00832 case 7: 00833 case 8: 00834 case 9: 00835 return 0.; 00836 00837 // cubic 00838 case 10: 00839 return 6.*dx/dist2x; 00840 00841 case 11: 00842 return 2.*dy/dist2x; 00843 00844 case 12: 00845 case 13: 00846 return 0.; 00847 00848 case 14: 00849 return 2.*dz/dist2x; 00850 00851 case 15: 00852 case 16: 00853 case 17: 00854 case 18: 00855 case 19: 00856 return 0.; 00857 00858 // quartics 00859 case 20: 00860 return 12.*dx*dx/dist2x; 00861 00862 case 21: 00863 return 6.*dx*dy/dist2x; 00864 00865 case 22: 00866 return 2.*dy*dy/dist2x; 00867 00868 case 23: 00869 case 24: 00870 return 0.; 00871 00872 case 25: 00873 return 6.*dx*dz/dist2x; 00874 00875 case 26: 00876 return 2.*dy*dz/dist2x; 00877 00878 case 27: 00879 case 28: 00880 return 0.; 00881 00882 case 29: 00883 return 2.*dz*dz/dist2x; 00884 00885 case 30: 00886 case 31: 00887 case 32: 00888 case 33: 00889 case 34: 00890 return 0.; 00891 00892 default: 00893 unsigned int o = 0; 00894 for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { } 00895 unsigned int i2 = i - (o*(o+1)*(o+2)/6); 00896 unsigned int block=o, nz = 0; 00897 for (; block < i2; block += (o-nz+1)) { nz++; } 00898 const unsigned int nx = block - i2; 00899 const unsigned int ny = o - nx - nz; 00900 Real val = nx * (nx - 1); 00901 for (unsigned int index=2; index < nx; index++) 00902 val *= dx; 00903 for (unsigned int index=0; index != ny; index++) 00904 val *= dy; 00905 for (unsigned int index=0; index != nz; index++) 00906 val *= dz; 00907 return val/dist2x; 00908 } 00909 } 00910 00911 00912 // d^2()/dxdy 00913 case 1: 00914 { 00915 switch (i) 00916 { 00917 // constant 00918 case 0: 00919 00920 // linear 00921 case 1: 00922 case 2: 00923 case 3: 00924 return 0.; 00925 00926 // quadratic 00927 case 4: 00928 return 0.; 00929 00930 case 5: 00931 return 1./distxy; 00932 00933 case 6: 00934 case 7: 00935 case 8: 00936 case 9: 00937 return 0.; 00938 00939 // cubic 00940 case 10: 00941 return 0.; 00942 00943 case 11: 00944 return 2.*dx/distxy; 00945 00946 case 12: 00947 return 2.*dy/distxy; 00948 00949 case 13: 00950 case 14: 00951 return 0.; 00952 00953 case 15: 00954 return dz/distxy; 00955 00956 case 16: 00957 case 17: 00958 case 18: 00959 case 19: 00960 return 0.; 00961 00962 // quartics 00963 case 20: 00964 return 0.; 00965 00966 case 21: 00967 return 3.*dx*dx/distxy; 00968 00969 case 22: 00970 return 4.*dx*dy/distxy; 00971 00972 case 23: 00973 return 3.*dy*dy/distxy; 00974 00975 case 24: 00976 case 25: 00977 return 0.; 00978 00979 case 26: 00980 return 2.*dx*dz/distxy; 00981 00982 case 27: 00983 return 2.*dy*dz/distxy; 00984 00985 case 28: 00986 case 29: 00987 return 0.; 00988 00989 case 30: 00990 return dz*dz/distxy; 00991 00992 case 31: 00993 case 32: 00994 case 33: 00995 case 34: 00996 return 0.; 00997 00998 default: 00999 unsigned int o = 0; 01000 for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { } 01001 unsigned int i2 = i - (o*(o+1)*(o+2)/6); 01002 unsigned int block=o, nz = 0; 01003 for (; block < i2; block += (o-nz+1)) { nz++; } 01004 const unsigned int nx = block - i2; 01005 const unsigned int ny = o - nx - nz; 01006 Real val = nx * ny; 01007 for (unsigned int index=1; index < nx; index++) 01008 val *= dx; 01009 for (unsigned int index=1; index < ny; index++) 01010 val *= dy; 01011 for (unsigned int index=0; index != nz; index++) 01012 val *= dz; 01013 return val/distxy; 01014 } 01015 } 01016 01017 01018 // d^2()/dy^2 01019 case 2: 01020 { 01021 switch (i) 01022 { 01023 // constant 01024 case 0: 01025 01026 // linear 01027 case 1: 01028 case 2: 01029 case 3: 01030 return 0.; 01031 01032 // quadratic 01033 case 4: 01034 case 5: 01035 return 0.; 01036 01037 case 6: 01038 return 2./dist2y; 01039 01040 case 7: 01041 case 8: 01042 case 9: 01043 return 0.; 01044 01045 // cubic 01046 case 10: 01047 case 11: 01048 return 0.; 01049 01050 case 12: 01051 return 2.*dx/dist2y; 01052 case 13: 01053 return 6.*dy/dist2y; 01054 01055 case 14: 01056 case 15: 01057 return 0.; 01058 01059 case 16: 01060 return 2.*dz/dist2y; 01061 01062 case 17: 01063 case 18: 01064 case 19: 01065 return 0.; 01066 01067 // quartics 01068 case 20: 01069 case 21: 01070 return 0.; 01071 01072 case 22: 01073 return 2.*dx*dx/dist2y; 01074 01075 case 23: 01076 return 6.*dx*dy/dist2y; 01077 01078 case 24: 01079 return 12.*dy*dy/dist2y; 01080 01081 case 25: 01082 case 26: 01083 return 0.; 01084 01085 case 27: 01086 return 2.*dx*dz/dist2y; 01087 01088 case 28: 01089 return 6.*dy*dz/dist2y; 01090 01091 case 29: 01092 case 30: 01093 return 0.; 01094 01095 case 31: 01096 return 2.*dz*dz/dist2y; 01097 01098 case 32: 01099 case 33: 01100 case 34: 01101 return 0.; 01102 01103 default: 01104 unsigned int o = 0; 01105 for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { } 01106 unsigned int i2 = i - (o*(o+1)*(o+2)/6); 01107 unsigned int block=o, nz = 0; 01108 for (; block < i2; block += (o-nz+1)) { nz++; } 01109 const unsigned int nx = block - i2; 01110 const unsigned int ny = o - nx - nz; 01111 Real val = ny * (ny - 1); 01112 for (unsigned int index=0; index != nx; index++) 01113 val *= dx; 01114 for (unsigned int index=2; index < ny; index++) 01115 val *= dy; 01116 for (unsigned int index=0; index != nz; index++) 01117 val *= dz; 01118 return val/dist2y; 01119 } 01120 } 01121 01122 01123 // d^2()/dxdz 01124 case 3: 01125 { 01126 switch (i) 01127 { 01128 // constant 01129 case 0: 01130 01131 // linear 01132 case 1: 01133 case 2: 01134 case 3: 01135 return 0.; 01136 01137 // quadratic 01138 case 4: 01139 case 5: 01140 case 6: 01141 return 0.; 01142 01143 case 7: 01144 return 1./distxz; 01145 01146 case 8: 01147 case 9: 01148 return 0.; 01149 01150 // cubic 01151 case 10: 01152 case 11: 01153 case 12: 01154 case 13: 01155 return 0.; 01156 01157 case 14: 01158 return 2.*dx/distxz; 01159 01160 case 15: 01161 return dy/distxz; 01162 01163 case 16: 01164 return 0.; 01165 01166 case 17: 01167 return 2.*dz/distxz; 01168 01169 case 18: 01170 case 19: 01171 return 0.; 01172 01173 // quartics 01174 case 20: 01175 case 21: 01176 case 22: 01177 case 23: 01178 case 24: 01179 return 0.; 01180 01181 case 25: 01182 return 3.*dx*dx/distxz; 01183 01184 case 26: 01185 return 2.*dx*dy/distxz; 01186 01187 case 27: 01188 return dy*dy/distxz; 01189 01190 case 28: 01191 return 0.; 01192 01193 case 29: 01194 return 4.*dx*dz/distxz; 01195 01196 case 30: 01197 return 2.*dy*dz/distxz; 01198 01199 case 31: 01200 return 0.; 01201 01202 case 32: 01203 return 3.*dz*dz/distxz; 01204 01205 case 33: 01206 case 34: 01207 return 0.; 01208 01209 default: 01210 unsigned int o = 0; 01211 for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { } 01212 unsigned int i2 = i - (o*(o+1)*(o+2)/6); 01213 unsigned int block=o, nz = 0; 01214 for (; block < i2; block += (o-nz+1)) { nz++; } 01215 const unsigned int nx = block - i2; 01216 const unsigned int ny = o - nx - nz; 01217 Real val = nx * nz; 01218 for (unsigned int index=1; index < nx; index++) 01219 val *= dx; 01220 for (unsigned int index=0; index != ny; index++) 01221 val *= dy; 01222 for (unsigned int index=1; index < nz; index++) 01223 val *= dz; 01224 return val/distxz; 01225 } 01226 } 01227 01228 // d^2()/dydz 01229 case 4: 01230 { 01231 switch (i) 01232 { 01233 // constant 01234 case 0: 01235 01236 // linear 01237 case 1: 01238 case 2: 01239 case 3: 01240 return 0.; 01241 01242 // quadratic 01243 case 4: 01244 case 5: 01245 case 6: 01246 case 7: 01247 return 0.; 01248 01249 case 8: 01250 return 1./distyz; 01251 01252 case 9: 01253 return 0.; 01254 01255 // cubic 01256 case 10: 01257 case 11: 01258 case 12: 01259 case 13: 01260 case 14: 01261 return 0.; 01262 01263 case 15: 01264 return dx/distyz; 01265 01266 case 16: 01267 return 2.*dy/distyz; 01268 01269 case 17: 01270 return 0.; 01271 01272 case 18: 01273 return 2.*dz/distyz; 01274 01275 case 19: 01276 return 0.; 01277 01278 // quartics 01279 case 20: 01280 case 21: 01281 case 22: 01282 case 23: 01283 case 24: 01284 case 25: 01285 return 0.; 01286 01287 case 26: 01288 return dx*dx/distyz; 01289 01290 case 27: 01291 return 2.*dx*dy/distyz; 01292 01293 case 28: 01294 return 3.*dy*dy/distyz; 01295 01296 case 29: 01297 return 0.; 01298 01299 case 30: 01300 return 2.*dx*dz/distyz; 01301 01302 case 31: 01303 return 4.*dy*dz/distyz; 01304 01305 case 32: 01306 return 0.; 01307 01308 case 33: 01309 return 3.*dz*dz/distyz; 01310 01311 case 34: 01312 return 0.; 01313 01314 default: 01315 unsigned int o = 0; 01316 for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { } 01317 unsigned int i2 = i - (o*(o+1)*(o+2)/6); 01318 unsigned int block=o, nz = 0; 01319 for (; block < i2; block += (o-nz+1)) { nz++; } 01320 const unsigned int nx = block - i2; 01321 const unsigned int ny = o - nx - nz; 01322 Real val = ny * nz; 01323 for (unsigned int index=0; index != nx; index++) 01324 val *= dx; 01325 for (unsigned int index=1; index < ny; index++) 01326 val *= dy; 01327 for (unsigned int index=1; index < nz; index++) 01328 val *= dz; 01329 return val/distyz; 01330 } 01331 } 01332 01333 01334 // d^2()/dz^2 01335 case 5: 01336 { 01337 switch (i) 01338 { 01339 // constant 01340 case 0: 01341 01342 // linear 01343 case 1: 01344 case 2: 01345 case 3: 01346 return 0.; 01347 01348 // quadratic 01349 case 4: 01350 case 5: 01351 case 6: 01352 case 7: 01353 case 8: 01354 return 0.; 01355 01356 case 9: 01357 return 2./dist2z; 01358 01359 // cubic 01360 case 10: 01361 case 11: 01362 case 12: 01363 case 13: 01364 case 14: 01365 case 15: 01366 case 16: 01367 return 0.; 01368 01369 case 17: 01370 return 2.*dx/dist2z; 01371 01372 case 18: 01373 return 2.*dy/dist2z; 01374 01375 case 19: 01376 return 6.*dz/dist2z; 01377 01378 // quartics 01379 case 20: 01380 case 21: 01381 case 22: 01382 case 23: 01383 case 24: 01384 case 25: 01385 case 26: 01386 case 27: 01387 case 28: 01388 return 0.; 01389 01390 case 29: 01391 return 2.*dx*dx/dist2z; 01392 01393 case 30: 01394 return 2.*dx*dy/dist2z; 01395 01396 case 31: 01397 return 2.*dy*dy/dist2z; 01398 01399 case 32: 01400 return 6.*dx*dz/dist2z; 01401 01402 case 33: 01403 return 6.*dy*dz/dist2z; 01404 01405 case 34: 01406 return 12.*dz*dz/dist2z; 01407 01408 default: 01409 unsigned int o = 0; 01410 for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { } 01411 unsigned int i2 = i - (o*(o+1)*(o+2)/6); 01412 unsigned int block=o, nz = 0; 01413 for (; block < i2; block += (o-nz+1)) { nz++; } 01414 const unsigned int nx = block - i2; 01415 const unsigned int ny = o - nx - nz; 01416 Real val = nz * (nz - 1); 01417 for (unsigned int index=0; index != nx; index++) 01418 val *= dx; 01419 for (unsigned int index=0; index != ny; index++) 01420 val *= dy; 01421 for (unsigned int index=2; index < nz; index++) 01422 val *= dz; 01423 return val/dist2z; 01424 } 01425 } 01426 01427 01428 default: 01429 libmesh_error_msg("Invalid j = " << j); 01430 } 01431 01432 #endif 01433 01434 libmesh_error_msg("We'll never get here!"); 01435 return 0.; 01436 } 01437 01438 } // namespace libMesh