Line data Source code
1 : // The libMesh Finite Element Library. 2 : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 3 : 4 : // This library is free software; you can redistribute it and/or 5 : // modify it under the terms of the GNU Lesser General Public 6 : // License as published by the Free Software Foundation; either 7 : // version 2.1 of the License, or (at your option) any later version. 8 : 9 : // This library is distributed in the hope that it will be useful, 10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 : // Lesser General Public License for more details. 13 : 14 : // You should have received a copy of the GNU Lesser General Public 15 : // License along with this library; if not, write to the Free Software 16 : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 : 18 : 19 : 20 : // Local includes 21 : #include "libmesh/quadrature_simpson.h" 22 : #include "libmesh/enum_to_string.h" 23 : 24 : namespace libMesh 25 : { 26 : 27 37061 : void QSimpson::init_3D() 28 : { 29 : #if LIBMESH_DIM == 3 30 : 31 : //----------------------------------------------------------------------- 32 : // 3D quadrature rules 33 37061 : switch (_type) 34 : { 35 : //--------------------------------------------- 36 : // Hex quadrature rules 37 2588 : case HEX8: 38 : case HEX20: 39 : case HEX27: 40 : { 41 : // We compute the 3D quadrature rule as a tensor 42 : // product of the 1D quadrature rule. 43 2788 : QSimpson q1D(1); 44 : 45 2588 : tensor_product_hex( q1D ); 46 : 47 200 : return; 48 : } 49 : 50 : 51 : 52 : //--------------------------------------------- 53 : // Tetrahedral quadrature rules 54 28003 : case TET4: 55 : case TET10: 56 : case TET14: 57 : { 58 : // This rule is created by combining 8 subtets 59 : // which use the trapezoidal rule. The weights 60 : // may seem a bit odd, but they are correct, 61 : // and should add up to 1/6, the volume of the 62 : // reference tet. The points of this rule are 63 : // at the nodal points of the TET10, allowing 64 : // you to generate diagonal element stiffness 65 : // matrices when using quadratic elements. 66 : // It should be able to integrate something 67 : // better than linears, but I'm not sure how 68 : // high. 69 : 70 28003 : _points.resize(10); 71 28003 : _weights.resize(10); 72 : 73 28003 : _points[0](0) = 0.; _points[5](0) = .5; 74 28003 : _points[0](1) = 0.; _points[5](1) = .5; 75 28003 : _points[0](2) = 0.; _points[5](2) = 0.; 76 : 77 28003 : _points[1](0) = 1.; _points[6](0) = 0.; 78 28003 : _points[1](1) = 0.; _points[6](1) = .5; 79 28003 : _points[1](2) = 0.; _points[6](2) = 0.; 80 : 81 28003 : _points[2](0) = 0.; _points[7](0) = 0.; 82 28003 : _points[2](1) = 1.; _points[7](1) = 0.; 83 28003 : _points[2](2) = 0.; _points[7](2) = .5; 84 : 85 28003 : _points[3](0) = 0.; _points[8](0) = .5; 86 28003 : _points[3](1) = 0.; _points[8](1) = 0.; 87 28003 : _points[3](2) = 1.; _points[8](2) = .5; 88 : 89 28003 : _points[4](0) = .5; _points[9](0) = 0.; 90 28003 : _points[4](1) = 0.; _points[9](1) = .5; 91 28003 : _points[4](2) = 0.; _points[9](2) = .5; 92 : 93 : 94 28003 : _weights[0] = Real(1)/192; 95 28003 : _weights[1] = _weights[0]; 96 28003 : _weights[2] = _weights[0]; 97 28003 : _weights[3] = _weights[0]; 98 : 99 28003 : _weights[4] = Real(14)/576; 100 28003 : _weights[5] = _weights[4]; 101 28003 : _weights[6] = _weights[4]; 102 28003 : _weights[7] = _weights[4]; 103 28003 : _weights[8] = _weights[4]; 104 28003 : _weights[9] = _weights[4]; 105 : 106 28003 : return; 107 : } 108 : 109 : 110 : 111 : //--------------------------------------------- 112 : // Prism quadrature rules 113 1436 : case PRISM6: 114 : case PRISM15: 115 : case PRISM18: 116 : case PRISM20: 117 : case PRISM21: 118 : { 119 : // We compute the 3D quadrature rule as a tensor 120 : // product of the 1D quadrature rule and a 2D 121 : // triangle quadrature rule 122 : 123 1540 : QSimpson q1D(1); 124 208 : QSimpson q2D(2); 125 : 126 : // Initialize the 2D rule (1D is pre-initialized) 127 1436 : q2D.init(TRI3, _p_level, /*simple_type_only=*/true); 128 : 129 1436 : tensor_product_prism(q1D, q2D); 130 : 131 104 : return; 132 : } 133 : 134 : 135 : //--------------------------------------------- 136 : // Pyramid quadrature rules 137 5034 : case PYRAMID5: 138 : case PYRAMID13: 139 : case PYRAMID14: 140 : case PYRAMID18: 141 : { 142 5034 : libmesh_error_msg_if(!allow_nodal_pyramid_quadrature, 143 : "Nodal quadrature on Pyramid elements is not allowed by default since\n" 144 : "the Jacobian of the inverse element map is not well-defined at the Pyramid apex.\n" 145 : "Set the QBase::allow_nodal_pyramid_quadrature flag to true to ignore skip this check."); 146 : 147 5034 : _points.resize(14); 148 5034 : _weights.resize(14); 149 : 150 5034 : _points[0](0) = -1.; 151 5034 : _points[0](1) = -1.; 152 5034 : _points[0](2) = 0.; 153 : 154 5034 : _points[1](0) = 1.; 155 5034 : _points[1](1) = -1.; 156 5034 : _points[1](2) = 0.; 157 : 158 5034 : _points[2](0) = 1.; 159 5034 : _points[2](1) = 1.; 160 5034 : _points[2](2) = 0.; 161 : 162 5034 : _points[3](0) = -1.; 163 5034 : _points[3](1) = 1.; 164 5034 : _points[3](2) = 0.; 165 : 166 5034 : _points[4](0) = 0.; 167 5034 : _points[4](1) = 0.; 168 5034 : _points[4](2) = 1.; 169 : 170 5034 : _points[5](0) = 0.; 171 5034 : _points[5](1) = -1.; 172 5034 : _points[5](2) = 0.; 173 : 174 5034 : _points[6](0) = 1.; 175 5034 : _points[6](1) = 0.; 176 5034 : _points[6](2) = 0.; 177 : 178 5034 : _points[7](0) = 0.; 179 5034 : _points[7](1) = 1.; 180 5034 : _points[7](2) = 0.; 181 : 182 5034 : _points[8](0) = -1.; 183 5034 : _points[8](1) = 0.; 184 5034 : _points[8](2) = 0.; 185 : 186 5034 : _points[9](0) = 0.; 187 5034 : _points[9](1) = -0.5; 188 5034 : _points[9](2) = 0.5; 189 : 190 5034 : _points[10](0) = 0.5; 191 5034 : _points[10](1) = 0.; 192 5034 : _points[10](2) = 0.5; 193 : 194 5034 : _points[11](0) = 0.; 195 5034 : _points[11](1) = 0.5; 196 5034 : _points[11](2) = 0.5; 197 : 198 5034 : _points[12](0) = -0.5; 199 5034 : _points[12](1) = 0.; 200 5034 : _points[12](2) = 0.5; 201 : 202 5034 : _points[13](0) = 0.; 203 5034 : _points[13](1) = 0.; 204 5034 : _points[13](2) = 0.; 205 : 206 : // These are of dubious value since we can't integrate on the 207 : // vertex where the mapping Jacobian is ill-defined, and even 208 : // if we could it looks like we'd need negative weight at that 209 : // vertex to give us exact integrals of both z and z^2. So I 210 : // punt and just use QTrap weights. 211 5034 : _weights[0] = 1/Real(4); 212 5034 : _weights[1] = _weights[0]; 213 5034 : _weights[2] = _weights[0]; 214 5034 : _weights[3] = _weights[0]; 215 5034 : _weights[4] = 1/Real(3); 216 5034 : _weights[5] = 0; 217 5034 : _weights[6] = 0; 218 5034 : _weights[7] = 0; 219 5034 : _weights[8] = 0; 220 5034 : _weights[9] = 0; 221 5034 : _weights[10] = 0; 222 5034 : _weights[11] = 0; 223 5034 : _weights[12] = 0; 224 5034 : _weights[13] = 0; 225 : 226 5034 : return; 227 : } 228 : 229 : 230 : //--------------------------------------------- 231 : // Unsupported type 232 0 : default: 233 0 : libmesh_error_msg("ERROR: Unsupported type: " << Utility::enum_to_string(_type)); 234 : } 235 : #endif 236 : } 237 : 238 : } // namespace libMesh