MFEM v2.0
|
00001 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at 00002 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights 00003 // reserved. See file COPYRIGHT for details. 00004 // 00005 // This file is part of the MFEM library. For more information and source code 00006 // availability see http://mfem.googlecode.com. 00007 // 00008 // MFEM is free software; you can redistribute it and/or modify it under the 00009 // terms of the GNU Lesser General Public License (as published by the Free 00010 // Software Foundation) version 2.1 dated February 1999. 00011 00012 // Implementation of IntegrationRule(s) classes 00013 00014 // Acknowledgment: Some of the high-precision triangular and tetrahedral 00015 // quadrature rules below were obtained from the Encyclopaedia of Cubature 00016 // Formulas at http://nines.cs.kuleuven.be/research/ecf/ecf.html 00017 00018 #include <math.h> 00019 #include "fem.hpp" 00020 00021 IntegrationRule::IntegrationRule(int NP) 00022 { 00023 NPoints = NP; 00024 IntPoints = new IntegrationPoint[NP]; 00025 } 00026 00027 IntegrationRule::IntegrationRule(IntegrationRule &irx, IntegrationRule &iry) 00028 { 00029 int i, j, nx, ny; 00030 00031 nx = irx.GetNPoints(); 00032 ny = iry.GetNPoints(); 00033 NPoints = nx * ny; 00034 IntPoints = new IntegrationPoint[NPoints]; 00035 00036 for (j = 0; j < ny; j++) 00037 { 00038 IntegrationPoint &ipy = iry.IntPoint(j); 00039 for (i = 0; i < nx; i++) 00040 { 00041 IntegrationPoint &ipx = irx.IntPoint(i); 00042 IntegrationPoint &ip = IntPoints[j*nx+i]; 00043 00044 ip.x = ipx.x; 00045 ip.y = ipy.x; 00046 ip.weight = ipx.weight * ipy.weight; 00047 } 00048 } 00049 } 00050 00051 void IntegrationRule::GaussianRule() 00052 { 00053 int n = NPoints; 00054 int m = (n+1)/2; 00055 int i, j; 00056 double p1, p2, p3; 00057 double pp, z; 00058 for (i = 1; i <= m; i++) 00059 { 00060 z = cos(M_PI * (i - 0.25) / (n + 0.5)); 00061 00062 while(1) 00063 { 00064 p1 = 1; 00065 p2 = 0; 00066 for (j = 1; j <= n; j++) 00067 { 00068 p3 = p2; 00069 p2 = p1; 00070 p1 = ((2 * j - 1) * z * p2 - (j - 1) * p3) / j; 00071 } 00072 // p1 is Legendre polynomial 00073 00074 pp = n * (z*p1-p2) / (z*z - 1); 00075 00076 if (fabs(p1/pp) < 2e-16) break; 00077 00078 z = z - p1/pp; 00079 } 00080 00081 z = ((1 - z) + p1/pp)/2; 00082 00083 IntPoints[i-1].x = z; 00084 IntPoints[n-i].x = 1 - z; 00085 IntPoints[i-1].weight = 00086 IntPoints[n-i].weight = 1./(4*z*(1 - z)*pp*pp); 00087 } 00088 } 00089 00090 void IntegrationRule::UniformRule() 00091 { 00092 int i; 00093 double h; 00094 00095 h = 1.0 / (NPoints - 1); 00096 for (i = 0; i < NPoints; i++) 00097 { 00098 IntPoints[i].x = double(i) / (NPoints - 1); 00099 IntPoints[i].weight = h; 00100 } 00101 IntPoints[0].weight = 0.5 * h; 00102 IntPoints[NPoints-1].weight = 0.5 * h; 00103 } 00104 00105 void IntegrationRule::GrundmannMollerTetrahedronRule(int s) 00106 { 00107 const int n = 3; 00108 const int d = 2*s + 1; 00109 Vector fact(d + n + 1); 00110 Array<int> beta(n), sums(n); 00111 00112 fact(0) = 1.; 00113 for (int i = 1; i < fact.Size(); i++) 00114 fact(i) = fact(i - 1)*i; 00115 00116 // number of points is \binom{n + s + 1}{n + 1} 00117 int np = 1, f = 1; 00118 for (int i = 0; i <= n; i++) 00119 np *= (s + i + 1), f *= (i + 1); 00120 np /= f; 00121 if (NPoints != np) 00122 { 00123 delete [] IntPoints; 00124 IntPoints = new IntegrationPoint[NPoints = np]; 00125 } 00126 00127 int pt = 0; 00128 for (int i = 0; i <= s; i++) 00129 { 00130 double weight; 00131 00132 weight = pow(2., -2*s)*pow(d + n - 2*i, d)/fact(i)/fact(d + n - i); 00133 if (i%2) 00134 weight = -weight; 00135 00136 // loop over all beta : beta_0 + ... + beta_{n-1} <= s - i 00137 int k = s - i; 00138 beta = 0; 00139 sums = 0; 00140 while (true) 00141 { 00142 IntegrationPoint &ip = IntPoints[pt++]; 00143 ip.weight = weight; 00144 ip.x = double(2*beta[0] + 1)/(d + n - 2*i); 00145 ip.y = double(2*beta[1] + 1)/(d + n - 2*i); 00146 ip.z = double(2*beta[2] + 1)/(d + n - 2*i); 00147 00148 int j = 0; 00149 while (sums[j] == k) 00150 { 00151 beta[j++] = 0; 00152 if (j == n) 00153 goto done_beta; 00154 } 00155 beta[j]++; 00156 sums[j]++; 00157 for (j--; j >= 0; j--) 00158 sums[j] = sums[j+1]; 00159 } 00160 done_beta: 00161 ; 00162 } 00163 } 00164 00165 IntegrationRule::~IntegrationRule() 00166 { 00167 delete [] IntPoints; 00168 } 00169 00170 00171 IntegrationRules IntRules(0); 00172 00173 IntegrationRules RefinedIntRules(1); 00174 00175 IntegrationRules::IntegrationRules(int refined) 00176 { 00177 if (refined < 0) { own_rules = 0; return; } 00178 00179 own_rules = 1; 00180 PointIntegrationRules(); 00181 SegmentIntegrationRules(refined); 00182 TriangleIntegrationRules(0); 00183 SquareIntegrationRules(); 00184 TetrahedronIntegrationRules(0); 00185 CubeIntegrationRules(); 00186 } 00187 00188 const IntegrationRule &IntegrationRules::Get(int GeomType, int Order) 00189 { 00190 Array<IntegrationRule *> *ir_array; 00191 00192 switch (GeomType) 00193 { 00194 case Geometry::POINT: ir_array = &PointIntRules; break; 00195 case Geometry::SEGMENT: ir_array = &SegmentIntRules; break; 00196 case Geometry::TRIANGLE: ir_array = &TriangleIntRules; break; 00197 case Geometry::SQUARE: ir_array = &SquareIntRules; break; 00198 case Geometry::TETRAHEDRON: ir_array = &TetrahedronIntRules; break; 00199 case Geometry::CUBE: ir_array = &CubeIntRules; break; 00200 default: 00201 #ifdef MFEM_DEBUG 00202 mfem_error ("IntegrationRules::Get(...)"); 00203 #endif 00204 ; 00205 } 00206 if (Order >= ir_array->Size() || (*ir_array)[Order] == NULL) 00207 { 00208 cerr << "\nIntegration rule of order " << Order << " on " 00209 << Geometry::Name[GeomType] << " is not defined!\n" << endl; 00210 mfem_error(); 00211 } 00212 return *(*ir_array)[Order]; 00213 } 00214 00215 void IntegrationRules::Set(int GeomType, int Order, IntegrationRule &IntRule) 00216 { 00217 Array<IntegrationRule *> *ir_array; 00218 00219 switch (GeomType) 00220 { 00221 case Geometry::POINT: ir_array = &PointIntRules; break; 00222 case Geometry::SEGMENT: ir_array = &SegmentIntRules; break; 00223 case Geometry::TRIANGLE: ir_array = &TriangleIntRules; break; 00224 case Geometry::SQUARE: ir_array = &SquareIntRules; break; 00225 case Geometry::TETRAHEDRON: ir_array = &TetrahedronIntRules; break; 00226 case Geometry::CUBE: ir_array = &CubeIntRules; break; 00227 default: 00228 #ifdef MFEM_DEBUG 00229 mfem_error("IntegrationRules::Set(...)"); 00230 #endif 00231 ; 00232 } 00233 00234 if (ir_array->Size() <= Order) 00235 { 00236 int i = ir_array->Size(); 00237 00238 ir_array->SetSize(Order + 1); 00239 00240 for ( ; i < Order; i++) 00241 (*ir_array)[i] = NULL; 00242 } 00243 00244 (*ir_array)[Order] = &IntRule; 00245 } 00246 00247 void IntegrationRules::DeleteIntRuleArray(Array<IntegrationRule *> &ir_array) 00248 { 00249 int i; 00250 IntegrationRule *ir; 00251 00252 for (i = 0, ir = NULL; i < ir_array.Size(); i++) 00253 if (ir_array[i] != ir) 00254 delete (ir = ir_array[i]); 00255 } 00256 00257 IntegrationRules::~IntegrationRules() 00258 { 00259 if (!own_rules) return; 00260 00261 DeleteIntRuleArray(PointIntRules); 00262 DeleteIntRuleArray(SegmentIntRules); 00263 DeleteIntRuleArray(TriangleIntRules); 00264 DeleteIntRuleArray(SquareIntRules); 00265 DeleteIntRuleArray(TetrahedronIntRules); 00266 DeleteIntRuleArray(CubeIntRules); 00267 } 00268 00269 // Integration rules for a point 00270 void IntegrationRules::PointIntegrationRules() 00271 { 00272 PointIntRules.SetSize(2); 00273 00274 PointIntRules[0] = new IntegrationRule (1); 00275 PointIntRules[0] -> IntPoint(0).x = .0; 00276 PointIntRules[0] -> IntPoint(0).weight = 1.; 00277 00278 PointIntRules[1] = PointIntRules[0]; 00279 } 00280 00281 // Integration rules for line segment [0,1] 00282 void IntegrationRules::SegmentIntegrationRules(int refined) 00283 { 00284 int i, j; 00285 00286 SegmentIntRules.SetSize(32); 00287 SegmentIntRules = NULL; 00288 00289 if (refined) 00290 { 00291 int n; 00292 IntegrationRule *tmp, *ir; 00293 for (i = 1; i < SegmentIntRules.Size(); i += 2) 00294 { 00295 n = i/2+1; tmp = new IntegrationRule(n); tmp->GaussianRule(); 00296 SegmentIntRules[i-1] = 00297 SegmentIntRules[i] = ir = new IntegrationRule(2*n); 00298 for (j = 0; j < n; j++) 00299 { 00300 ir->IntPoint(j).x = tmp->IntPoint(j).x/2.0; 00301 ir->IntPoint(j).weight = tmp->IntPoint(j).weight/2.0; 00302 ir->IntPoint(j+n).x = 0.5 + tmp->IntPoint(j).x/2.0; 00303 ir->IntPoint(j+n).weight = tmp->IntPoint(j).weight/2.0; 00304 } 00305 delete tmp; 00306 } 00307 return; 00308 } 00309 00310 // 1 point - 1 degree 00311 SegmentIntRules[0] = SegmentIntRules[1] = new IntegrationRule (1); 00312 SegmentIntRules[0] -> IntPoint(0).x = .5; 00313 SegmentIntRules[0] -> IntPoint(0).weight = 1.; 00314 00315 // 2 point - 3 degree 00316 SegmentIntRules[2] = SegmentIntRules[3] = new IntegrationRule (2); 00317 SegmentIntRules[2] -> IntPoint(0).x = 0.21132486540518711775; 00318 SegmentIntRules[2] -> IntPoint(0).weight = .5; 00319 SegmentIntRules[2] -> IntPoint(1).x = 0.78867513459481288225; 00320 SegmentIntRules[2] -> IntPoint(1).weight = .5; 00321 00322 // 3 point - 5 degree 00323 SegmentIntRules[4] = SegmentIntRules[5] = new IntegrationRule (3); 00324 SegmentIntRules[4] -> IntPoint(0).x = 0.11270166537925831148; 00325 SegmentIntRules[4] -> IntPoint(0).weight = 5./18.; 00326 SegmentIntRules[4] -> IntPoint(1).x = 0.5; 00327 SegmentIntRules[4] -> IntPoint(1).weight = 4./9.; 00328 SegmentIntRules[4] -> IntPoint(2).x = 0.88729833462074168852; 00329 SegmentIntRules[4] -> IntPoint(2).weight = 5./18.; 00330 00331 for (i = 7; i < SegmentIntRules.Size(); i += 2) 00332 { 00333 SegmentIntRules[i-1] = SegmentIntRules[i] = new IntegrationRule (i/2+1); 00334 SegmentIntRules[i] -> GaussianRule(); 00335 } 00336 } 00337 00338 // Integration rules for reference triangle {[0,0],[1,0],[0,1]} 00339 void IntegrationRules::TriangleIntegrationRules(int refined) 00340 { 00341 IntegrationRule *ir; 00342 00343 TriangleIntRules.SetSize(26); 00344 00345 if (refined) 00346 mfem_error ("Refined TriangleIntegrationRules are not implemented!"); 00347 00348 TriangleIntRules = NULL; 00349 00350 // 1 point - 0 degree 00351 TriangleIntRules[0] = TriangleIntRules[1] = new IntegrationRule (1); 00352 TriangleIntRules[0]->AddTriMidPoint(0, 0.5); 00353 00354 /* 00355 // 3 point - 1 degree (vertices) 00356 TriangleIntRules[1] = new IntegrationRule (3); 00357 TriangleIntRules[1]->AddTriPoints3(0, 0.0, 1./6.); 00358 */ 00359 00360 // 3 point - 2 degree 00361 TriangleIntRules[2] = new IntegrationRule (3); 00362 // midpoints of the edges 00363 // TriangleIntRules[2]->AddTriPoints3(0, 0.5, 1./6.); 00364 // interior points 00365 TriangleIntRules[2]->AddTriPoints3(0, 1./6., 1./6.); 00366 00367 // 4 point - 3 degree (has one negative weight) 00368 TriangleIntRules[3] = ir = new IntegrationRule (4); 00369 ir->AddTriMidPoint(0, -0.28125); // -9./32. 00370 ir->AddTriPoints3(1, 0.2, 25./96.); 00371 00372 // 6 point - 4 degree 00373 TriangleIntRules[4] = ir = new IntegrationRule (6); 00374 ir->AddTriPoints3(0, 0.091576213509770743460, 0.054975871827660933819); 00375 ir->AddTriPoints3(3, 0.44594849091596488632, 0.11169079483900573285); 00376 00377 // 7 point - 5 degree 00378 TriangleIntRules[5] = ir = new IntegrationRule (7); 00379 ir->AddTriMidPoint(0, 0.1125); 00380 ir->AddTriPoints3(1, 0.10128650732345633880, 0.062969590272413576298); 00381 ir->AddTriPoints3(4, 0.47014206410511508977, 0.066197076394253090369); 00382 00383 // 12 point - 6 degree 00384 TriangleIntRules[6] = ir = new IntegrationRule (12); 00385 ir->AddTriPoints3(0, 0.063089014491502228340, 0.025422453185103408460); 00386 ir->AddTriPoints3(3, 0.24928674517091042129, 0.058393137863189683013); 00387 ir->AddTriPoints6(6, 0.053145049844816947353, 0.31035245103378440542, 00388 0.041425537809186787597); 00389 00390 // 12 point - degree 7 00391 TriangleIntRules[7] = ir = new IntegrationRule(12); 00392 ir->AddTriPoints3R(0, 0.062382265094402118174, 0.067517867073916085443, 00393 0.026517028157436251429); 00394 ir->AddTriPoints3R(3, 0.055225456656926611737, 0.32150249385198182267, 00395 0.043881408714446055037); 00396 // slightly better with explicit 3rd area coordinate 00397 ir->AddTriPoints3R(6, 0.034324302945097146470, 0.66094919618673565761, 00398 0.30472650086816719592, 0.028775042784981585738); 00399 ir->AddTriPoints3R(9, 0.51584233435359177926, 0.27771616697639178257, 00400 0.20644149867001643817, 0.067493187009802774463); 00401 00402 // 16 point - 8 degree 00403 TriangleIntRules[8] = ir = new IntegrationRule(16); 00404 ir->AddTriMidPoint(0, 0.0721578038388935841255455552445323); 00405 ir->AddTriPoints3(1, 0.170569307751760206622293501491464, 00406 0.0516086852673591251408957751460645); 00407 ir->AddTriPoints3(4, 0.0505472283170309754584235505965989, 00408 0.0162292488115990401554629641708902); 00409 ir->AddTriPoints3(7, 0.459292588292723156028815514494169, 00410 0.0475458171336423123969480521942921); 00411 // ir->AddTriPoints3b(7, 0.081414823414553687942, 00412 // 0.0475458171336423123969480521942921); 00413 ir->AddTriPoints6(10, 0.008394777409957605337213834539296, 00414 0.263112829634638113421785786284643, 00415 0.0136151570872174971324223450369544); 00416 00417 // 19 point - 9 degree 00418 TriangleIntRules[9] = ir = new IntegrationRule(19); 00419 ir->AddTriMidPoint(0, 0.0485678981413994169096209912536443); 00420 ir->AddTriPoints3b(1, 0.020634961602524744433, 00421 0.0156673501135695352684274156436046); 00422 ir->AddTriPoints3b(4, 0.12582081701412672546, 00423 0.0389137705023871396583696781497019); 00424 ir->AddTriPoints3(7, 0.188203535619032730240961280467335, 00425 0.0398238694636051265164458871320226); 00426 ir->AddTriPoints3(10, 0.0447295133944527098651065899662763, 00427 0.0127888378293490156308393992794999); 00428 ir->AddTriPoints6(13, 0.0368384120547362836348175987833851, 00429 0.2219629891607656956751025276931919, 00430 0.0216417696886446886446886446886446); 00431 00432 // 25 point - 10 degree 00433 TriangleIntRules[10] = ir = new IntegrationRule(25); 00434 ir->AddTriMidPoint(0, 0.0454089951913767900476432975500142); 00435 ir->AddTriPoints3b(1, 0.028844733232685245264984935583748, 00436 0.0183629788782333523585030359456832); 00437 ir->AddTriPoints3(4, 0.109481575485037054795458631340522, 00438 0.0226605297177639673913028223692986); 00439 ir->AddTriPoints6(7, 0.141707219414879954756683250476361, 00440 0.307939838764120950165155022930631, 00441 0.0363789584227100543021575883096803); 00442 ir->AddTriPoints6(13, 0.025003534762686386073988481007746, 00443 0.246672560639902693917276465411176, 00444 0.0141636212655287424183685307910495); 00445 ir->AddTriPoints6(19, 0.0095408154002994575801528096228873, 00446 0.0668032510122002657735402127620247, 00447 4.71083348186641172996373548344341E-03); 00448 00449 // 28 point -- 11 degree 00450 TriangleIntRules[11] = ir = new IntegrationRule(28); 00451 ir->AddTriPoints6(0, 0.0, 00452 0.141129718717363295960826061941652, 00453 3.68119189165027713212944752369032E-03); 00454 ir->AddTriMidPoint(6, 0.0439886505811161193990465846607278); 00455 ir->AddTriPoints3(7, 0.0259891409282873952600324854988407, 00456 4.37215577686801152475821439991262E-03); 00457 ir->AddTriPoints3(10, 0.0942875026479224956305697762754049, 00458 0.0190407859969674687575121697178070); 00459 ir->AddTriPoints3b(13, 0.010726449965572372516734795387128, 00460 9.42772402806564602923839129555767E-03); 00461 ir->AddTriPoints3(16, 0.207343382614511333452934024112966, 00462 0.0360798487723697630620149942932315); 00463 ir->AddTriPoints3b(19, 0.122184388599015809877869236727746, 00464 0.0346645693527679499208828254519072); 00465 ir->AddTriPoints6(22, 0.0448416775891304433090523914688007, 00466 0.2772206675282791551488214673424523, 00467 0.0205281577146442833208261574536469); 00468 00469 // 33 point - 12 degree 00470 TriangleIntRules[12] = ir = new IntegrationRule(33); 00471 ir->AddTriPoints3b(0, 2.35652204523900E-02, 1.28655332202275E-02); 00472 ir->AddTriPoints3b(3, 1.20551215411079E-01, 2.18462722690190E-02); 00473 ir->AddTriPoints3(6, 2.71210385012116E-01, 3.14291121089425E-02); 00474 ir->AddTriPoints3(9, 1.27576145541586E-01, 1.73980564653545E-02); 00475 ir->AddTriPoints3(12, 2.13173504532100E-02, 3.08313052577950E-03); 00476 ir->AddTriPoints6(15, 1.15343494534698E-01, 2.75713269685514E-01, 00477 2.01857788831905E-02); 00478 ir->AddTriPoints6(21, 2.28383322222570E-02, 2.81325580989940E-01, 00479 1.11783866011515E-02); 00480 ir->AddTriPoints6(27, 2.57340505483300E-02, 1.16251915907597E-01, 00481 8.65811555432950E-03); 00482 00483 #if 0 00484 // 37 point - 13 degree 00485 TriangleIntRules[13] = ir = new IntegrationRule(37); 00486 ir->AddTriMidPoint(0, 2.62604617004010E-02); 00487 ir->AddTriPoints3b(1, 9.90363012059100E-03, 5.64007260466500E-03); 00488 ir->AddTriPoints3b(4, 6.25667297808520E-02, 1.57117591812270E-02); 00489 ir->AddTriPoints3b(7, 1.70957326397447E-01, 2.35362512520970E-02); 00490 ir->AddTriPoints3(10, 2.29399572042831E-01, 2.36817932681775E-02); 00491 ir->AddTriPoints3(13, 1.14424495196330E-01, 1.55837645228970E-02); 00492 ir->AddTriPoints3(16, 2.48113913634590E-02, 3.98788573253700E-03); 00493 ir->AddTriPoints6(19, 9.48538283795790E-02, 2.68794997058761E-01, 00494 1.84242013643660E-02); 00495 ir->AddTriPoints6(25, 1.81007732788070E-02, 2.91730066734288E-01, 00496 8.70073165191100E-03); 00497 ir->AddTriPoints6(31, 2.22330766740900E-02, 1.26357385491669E-01, 00498 7.76089341952250E-03); 00499 #else 00500 // 37 point - 13 degree 00501 TriangleIntRules[13] = ir = new IntegrationRule(37); 00502 ir->AddTriPoints3b(0, 0.0, 00503 2.67845189554543044455908674650066E-03); 00504 ir->AddTriMidPoint(3, 0.0293480398063595158995969648597808); 00505 ir->AddTriPoints3(4, 0.0246071886432302181878499494124643, 00506 3.92538414805004016372590903990464E-03); 00507 ir->AddTriPoints3b(7, 0.159382493797610632566158925635800, 00508 0.0253344765879434817105476355306468); 00509 ir->AddTriPoints3(10, 0.227900255506160619646298948153592, 00510 0.0250401630452545330803738542916538); 00511 ir->AddTriPoints3(13, 0.116213058883517905247155321839271, 00512 0.0158235572961491595176634480481793); 00513 ir->AddTriPoints3b(16, 0.046794039901841694097491569577008, 00514 0.0157462815379843978450278590138683); 00515 ir->AddTriPoints6(19, 0.0227978945382486125477207592747430, 00516 0.1254265183163409177176192369310890, 00517 // 0.851775587145410469734660003794168, 00518 7.90126610763037567956187298486575E-03); 00519 ir->AddTriPoints6(25, 0.0162757709910885409437036075960413, 00520 0.2909269114422506044621801030055257, 00521 // 0.692797317566660854594116289398433, 00522 7.99081889046420266145965132482933E-03); 00523 ir->AddTriPoints6(31, 0.0897330604516053590796290561145196, 00524 0.2723110556841851025078181617634414, 00525 // 0.637955883864209538412552782122039, 00526 0.0182757511120486476280967518782978); 00527 #endif 00528 00529 // 42 point - 14 degree 00530 TriangleIntRules[14] = ir = new IntegrationRule(42); 00531 ir->AddTriPoints3b(0, 2.20721792756430E-02, 1.09417906847145E-02); 00532 ir->AddTriPoints3b(3, 1.64710561319092E-01, 1.63941767720625E-02); 00533 ir->AddTriPoints3(6, 2.73477528308839E-01, 2.58870522536460E-02); 00534 ir->AddTriPoints3(9, 1.77205532412543E-01, 2.10812943684965E-02); 00535 ir->AddTriPoints3(12, 6.17998830908730E-02, 7.21684983488850E-03); 00536 ir->AddTriPoints3(15, 1.93909612487010E-02, 2.46170180120000E-03); 00537 ir->AddTriPoints6(18, 5.71247574036480E-02, 1.72266687821356E-01, 00538 1.23328766062820E-02); 00539 ir->AddTriPoints6(24, 9.29162493569720E-02, 3.36861459796345E-01, 00540 1.92857553935305E-02); 00541 ir->AddTriPoints6(30, 1.46469500556540E-02, 2.98372882136258E-01, 00542 7.21815405676700E-03); 00543 ir->AddTriPoints6(36, 1.26833093287200E-03, 1.18974497696957E-01, 00544 2.50511441925050E-03); 00545 00546 // 54 point - 15 degree 00547 TriangleIntRules[15] = ir = new IntegrationRule(54); 00548 ir->AddTriPoints3b(0, 0.0834384072617499333, 0.016330909424402645); 00549 ir->AddTriPoints3b(3, 0.192779070841738867, 0.01370640901568218); 00550 ir->AddTriPoints3(6, 0.293197167913025367, 0.01325501829935165); 00551 ir->AddTriPoints3(9, 0.146467786942772933, 0.014607981068243055); 00552 ir->AddTriPoints3(12, 0.0563628676656034333, 0.005292304033121995); 00553 ir->AddTriPoints3(15, 0.0165751268583703333, 0.0018073215320460175); 00554 ir->AddTriPoints6(18, 0.0099122033092248, 0.239534554154794445, 00555 0.004263874050854718); 00556 ir->AddTriPoints6(24, 0.015803770630228, 0.404878807318339958, 00557 0.006958088258345965); 00558 ir->AddTriPoints6(30, 0.00514360881697066667, 0.0950021131130448885, 00559 0.0021459664703674175); 00560 ir->AddTriPoints6(36, 0.0489223257529888, 0.149753107322273969, 00561 0.008117664640887445); 00562 ir->AddTriPoints6(42, 0.0687687486325192, 0.286919612441334979, 00563 0.012803670460631195); 00564 ir->AddTriPoints6(48, 0.1684044181246992, 0.281835668099084562, 00565 0.016544097765822835); 00566 00567 // 61 point - 17 degree (used for 16 as well) 00568 TriangleIntRules[16] = TriangleIntRules[17] = ir = new IntegrationRule(61); 00569 ir->AddTriMidPoint(0, 1.67185996454015E-02); 00570 ir->AddTriPoints3b(1, 5.65891888645200E-03, 2.54670772025350E-03); 00571 ir->AddTriPoints3b(4, 3.56473547507510E-02, 7.33543226381900E-03); 00572 ir->AddTriPoints3b(7, 9.95200619584370E-02, 1.21754391768360E-02); 00573 ir->AddTriPoints3b(10, 1.99467521245206E-01, 1.55537754344845E-02); 00574 ir->AddTriPoints3 (13, 2.52141267970953E-01, 1.56285556093100E-02); 00575 ir->AddTriPoints3 (16, 1.62047004658461E-01, 1.24078271698325E-02); 00576 ir->AddTriPoints3 (19, 7.58758822607460E-02, 7.02803653527850E-03); 00577 ir->AddTriPoints3 (22, 1.56547269678220E-02, 1.59733808688950E-03); 00578 ir->AddTriPoints6 (25, 1.01869288269190E-02, 3.34319867363658E-01, 00579 4.05982765949650E-03); 00580 ir->AddTriPoints6 (31, 1.35440871671036E-01, 2.92221537796944E-01, 00581 1.34028711415815E-02); 00582 ir->AddTriPoints6 (37, 5.44239242905830E-02, 3.19574885423190E-01, 00583 9.22999660541100E-03); 00584 ir->AddTriPoints6 (43, 1.28685608336370E-02, 1.90704224192292E-01, 00585 4.23843426716400E-03); 00586 ir->AddTriPoints6 (49, 6.71657824135240E-02, 1.80483211648746E-01, 00587 9.14639838501250E-03); 00588 ir->AddTriPoints6 (55, 1.46631822248280E-02, 8.07113136795640E-02, 00589 3.33281600208250E-03); 00590 00591 // 73 point - 19 degree (used for 18 as well) 00592 TriangleIntRules[18] = TriangleIntRules[19] = ir = new IntegrationRule(73); 00593 ir->AddTriMidPoint(0, 0.0164531656944595); 00594 ir->AddTriPoints3b(1, 0.020780025853987, 0.005165365945636); 00595 ir->AddTriPoints3b(4, 0.090926214604215, 0.011193623631508); 00596 ir->AddTriPoints3b(7, 0.197166638701138, 0.015133062934734); 00597 ir->AddTriPoints3 (10, 0.255551654403098, 0.015245483901099); 00598 ir->AddTriPoints3 (13, 0.17707794215213, 0.0120796063708205); 00599 ir->AddTriPoints3 (16, 0.110061053227952, 0.0080254017934005); 00600 ir->AddTriPoints3 (19, 0.05552862425184, 0.004042290130892); 00601 ir->AddTriPoints3 (22, 0.012621863777229, 0.0010396810137425); 00602 ir->AddTriPoints6 (25, 0.003611417848412, 0.395754787356943, 00603 0.0019424384524905); 00604 ir->AddTriPoints6 (31, 0.13446675453078, 0.307929983880436, 00605 0.012787080306011); 00606 ir->AddTriPoints6 (37, 0.014446025776115, 0.26456694840652, 00607 0.004440451786669); 00608 ir->AddTriPoints6 (43, 0.046933578838178, 0.358539352205951, 00609 0.0080622733808655); 00610 ir->AddTriPoints6 (49, 0.002861120350567, 0.157807405968595, 00611 0.0012459709087455); 00612 ir->AddTriPoints6 (55, 0.075050596975911, 0.223861424097916, 00613 0.0091214200594755); 00614 ir->AddTriPoints6 (61, 0.03464707481676, 0.142421601113383, 00615 0.0051292818680995); 00616 ir->AddTriPoints6 (67, 0.065494628082938, 0.010161119296278, 00617 0.001899964427651); 00618 00619 // 85 point - 20 degree 00620 TriangleIntRules[20] = ir = new IntegrationRule(85); 00621 ir->AddTriMidPoint(0, 0.01380521349884976); 00622 ir->AddTriPoints3b(1, 0.001500649324429, 0.00088951477366337); 00623 ir->AddTriPoints3b(4, 0.0941397519389508667, 0.010056199056980585); 00624 ir->AddTriPoints3b(7, 0.2044721240895264, 0.013408923629665785); 00625 ir->AddTriPoints3(10, 0.264500202532787333, 0.012261566900751005); 00626 ir->AddTriPoints3(13, 0.211018964092076767, 0.008197289205347695); 00627 ir->AddTriPoints3(16, 0.107735607171271333, 0.0073979536993248); 00628 ir->AddTriPoints3(19, 0.0390690878378026667, 0.0022896411388521255); 00629 ir->AddTriPoints3(22, 0.0111743797293296333, 0.0008259132577881085); 00630 ir->AddTriPoints6(25, 0.00534961818733726667, 0.0635496659083522206, 00631 0.001174585454287792); 00632 ir->AddTriPoints6(31, 0.00795481706619893333, 0.157106918940706982, 00633 0.0022329628770908965); 00634 ir->AddTriPoints6(37, 0.0104223982812638, 0.395642114364374018, 00635 0.003049783403953986); 00636 ir->AddTriPoints6(43, 0.0109644147961233333, 0.273167570712910522, 00637 0.0034455406635941015); 00638 ir->AddTriPoints6(49, 0.0385667120854623333, 0.101785382485017108, 00639 0.0039987375362390815); 00640 ir->AddTriPoints6(55, 0.0355805078172182, 0.446658549176413815, 00641 0.003693067142668012); 00642 ir->AddTriPoints6(61, 0.0496708163627641333, 0.199010794149503095, 00643 0.00639966593932413); 00644 ir->AddTriPoints6(67, 0.0585197250843317333, 0.3242611836922827, 00645 0.008629035587848275); 00646 ir->AddTriPoints6(73, 0.121497787004394267, 0.208531363210132855, 00647 0.009336472951467735); 00648 ir->AddTriPoints6(79, 0.140710844943938733, 0.323170566536257485, 00649 0.01140911202919763); 00650 00651 // 126 point - 25 degree (used also for derees from 21 to 24) 00652 TriangleIntRules[21] = TriangleIntRules[22] = TriangleIntRules[23] = 00653 TriangleIntRules[24] = TriangleIntRules[25] = 00654 ir = new IntegrationRule(126); 00655 ir->AddTriPoints3b(0, 0.0279464830731742, 0.0040027909400102085); 00656 ir->AddTriPoints3b(3, 0.131178601327651467, 0.00797353841619525); 00657 ir->AddTriPoints3b(6, 0.220221729512072267, 0.006554570615397765); 00658 ir->AddTriPoints3 (9, 0.298443234019804467, 0.00979150048281781); 00659 ir->AddTriPoints3(12, 0.2340441723373718, 0.008235442720768635); 00660 ir->AddTriPoints3(15, 0.151468334609017567, 0.00427363953704605); 00661 ir->AddTriPoints3(18, 0.112733893545993667, 0.004080942928613246); 00662 ir->AddTriPoints3(21, 0.0777156920915263, 0.0030605732699918895); 00663 ir->AddTriPoints3(24, 0.034893093614297, 0.0014542491324683325); 00664 ir->AddTriPoints3(27, 0.00725818462093236667, 0.00034613762283099815); 00665 ir->AddTriPoints6(30, 0.0012923527044422, 0.227214452153364077, 00666 0.0006241445996386985); 00667 ir->AddTriPoints6(36, 0.0053997012721162, 0.435010554853571706, 00668 0.001702376454401511); 00669 ir->AddTriPoints6(42, 0.006384003033975, 0.320309599272204437, 00670 0.0016798271630320255); 00671 ir->AddTriPoints6(48, 0.00502821150199306667, 0.0917503222800051889, 00672 0.000858078269748377); 00673 ir->AddTriPoints6(54, 0.00682675862178186667, 0.0380108358587243835, 00674 0.000740428158357803); 00675 ir->AddTriPoints6(60, 0.0100161996399295333, 0.157425218485311668, 00676 0.0017556563053643425); 00677 ir->AddTriPoints6(66, 0.02575781317339, 0.239889659778533193, 00678 0.003696775074853242); 00679 ir->AddTriPoints6(72, 0.0302278981199158, 0.361943118126060531, 00680 0.003991543738688279); 00681 ir->AddTriPoints6(78, 0.0305049901071620667, 0.0835519609548285602, 00682 0.0021779813065790205); 00683 ir->AddTriPoints6(84, 0.0459565473625693333, 0.148443220732418205, 00684 0.003682528350708916); 00685 ir->AddTriPoints6(90, 0.0674428005402775333, 0.283739708727534955, 00686 0.005481786423209775); 00687 ir->AddTriPoints6(96, 0.0700450914159106, 0.406899375118787573, 00688 0.00587498087177056); 00689 ir->AddTriPoints6(102, 0.0839115246401166, 0.194113987024892542, 00690 0.005007800356899285); 00691 ir->AddTriPoints6(108, 0.120375535677152667, 0.32413434700070316, 00692 0.00665482039381434); 00693 ir->AddTriPoints6(114, 0.148066899157366667, 0.229277483555980969, 00694 0.00707722325261307); 00695 ir->AddTriPoints6(120, 0.191771865867325067, 0.325618122595983752, 00696 0.007440689780584005); 00697 } 00698 00699 // Integration rules for unit square 00700 void IntegrationRules::SquareIntegrationRules() 00701 { 00702 SquareIntRules.SetSize(22); 00703 00704 for (int i = 1; i < SquareIntRules.Size(); i += 2) 00705 { 00706 SquareIntRules[i-1] = SquareIntRules[i] = 00707 new IntegrationRule(*SegmentIntRules[i], *SegmentIntRules[i]); 00708 } 00709 } 00710 00713 void IntegrationRules::TetrahedronIntegrationRules(int refined) 00714 { 00715 IntegrationRule *ir; 00716 00717 TetrahedronIntRules.SetSize(22); 00718 00719 if (refined) 00720 mfem_error ("Refined TetrahedronIntegrationRules are not implemented!"); 00721 00722 TetrahedronIntRules = NULL; 00723 00724 // 1 point - degree 1 00725 TetrahedronIntRules[0] = 00726 TetrahedronIntRules[1] = ir = new IntegrationRule (1); 00727 ir->AddTetMidPoint(0, 1./6.); 00728 00729 // 4 points - degree 2 00730 TetrahedronIntRules[2] = ir = new IntegrationRule (4); 00731 // ir->AddTetPoints4(0, 0.13819660112501051518, 1./24.); 00732 ir->AddTetPoints4b(0, 0.58541019662496845446, 1./24.); 00733 00734 // 5 points - degree 3 (negative weight) 00735 TetrahedronIntRules[3] = ir = new IntegrationRule (5); 00736 ir->AddTetMidPoint(0, -2./15.); 00737 ir->AddTetPoints4b(1, 0.5, 0.075); 00738 00739 // 11 points - degree 4 (negative weight) 00740 TetrahedronIntRules[4] = ir = new IntegrationRule (11); 00741 ir->AddTetPoints4(0, 1./14., 343./45000.); 00742 ir->AddTetMidPoint(4, -74./5625.); 00743 ir->AddTetPoints6(5, 0.10059642383320079500, 28./1125.); 00744 00745 // 14 points - degree 5 00746 TetrahedronIntRules[5] = ir = new IntegrationRule (14); 00747 ir->AddTetPoints6(0, 0.045503704125649649492, 7.0910034628469110730E-03); 00748 ir->AddTetPoints4(6, 0.092735250310891226402, 0.012248840519393658257); 00749 ir->AddTetPoints4b(10, 0.067342242210098170608, 0.018781320953002641800); 00750 00751 // 24 points - degree 6 00752 TetrahedronIntRules[6] = ir = new IntegrationRule (24); 00753 ir->AddTetPoints4(0, 0.21460287125915202929, 6.6537917096945820166E-03); 00754 ir->AddTetPoints4(4, 0.040673958534611353116, 1.6795351758867738247E-03); 00755 ir->AddTetPoints4b(8, 0.032986329573173468968, 9.2261969239424536825E-03); 00756 ir->AddTetPoints12(12, 0.063661001875017525299, 0.26967233145831580803, 00757 8.0357142857142857143E-03); 00758 00759 // 31 points - degree 7 (negative weight) 00760 TetrahedronIntRules[7] = ir = new IntegrationRule (31); 00761 ir->AddTetPoints6(0, 0.0, 9.7001763668430335097E-04); 00762 ir->AddTetMidPoint(6, 0.018264223466108820291); 00763 ir->AddTetPoints4(7, 0.078213192330318064374, 0.010599941524413686916); 00764 ir->AddTetPoints4(11, 0.12184321666390517465, -0.062517740114331851691); 00765 ir->AddTetPoints4b(15, 2.3825066607381275412E-03, 4.8914252630734993858E-03); 00766 ir->AddTetPoints12(19, 0.1, 0.2, 0.027557319223985890653); 00767 00768 // 43 points - degree 8 (negative weight) 00769 TetrahedronIntRules[8] = ir = new IntegrationRule (43); 00770 ir->AddTetPoints4(0, 5.7819505051979972532E-03, 1.6983410909288737984E-04); 00771 ir->AddTetPoints4(4, 0.082103588310546723091, 1.9670333131339009876E-03); 00772 ir->AddTetPoints12(8, 0.036607749553197423679, 0.19048604193463345570, 00773 2.1405191411620925965E-03); 00774 ir->AddTetPoints6(20, 0.050532740018894224426, 4.5796838244672818007E-03); 00775 ir->AddTetPoints12(26, 0.22906653611681113960, 0.035639582788534043717, 00776 5.7044858086819185068E-03); 00777 ir->AddTetPoints4(38, 0.20682993161067320408, 0.014250305822866901248); 00778 ir->AddTetMidPoint(42, -0.020500188658639915841); 00779 00780 // orders 9 and higher -- Grundmann-Moller rules 00781 TetrahedronIntRules[9] = new IntegrationRule; 00782 TetrahedronIntRules[9]->GrundmannMollerTetrahedronRule(4); 00783 00784 for (int i = 11; i < TetrahedronIntRules.Size(); i += 2) 00785 { 00786 TetrahedronIntRules[i-1] = TetrahedronIntRules[i] = new IntegrationRule; 00787 TetrahedronIntRules[i]->GrundmannMollerTetrahedronRule(i/2); 00788 } 00789 } 00790 00792 void IntegrationRules::CubeIntegrationRules() 00793 { 00794 int i, k, l, m, np; 00795 00796 CubeIntRules.SetSize(22); 00797 CubeIntRules = NULL; 00798 00799 for (i = 1; i < CubeIntRules.Size(); i += 2) 00800 { 00801 np = SegmentIntRules[i] -> GetNPoints(); 00802 CubeIntRules[i-1] = CubeIntRules[i] = new IntegrationRule(np*np*np); 00803 for (k = 0; k < np; k++) 00804 for (l = 0; l < np; l++) 00805 for (m = 0; m < np; m++) 00806 { 00807 CubeIntRules[i] -> IntPoint((k*np+l)*np+m).x = 00808 SegmentIntRules[i] -> IntPoint(k).x; 00809 00810 CubeIntRules[i] -> IntPoint((k*np+l)*np+m).y = 00811 SegmentIntRules[i] -> IntPoint(l).x; 00812 00813 CubeIntRules[i] -> IntPoint((k*np+l)*np+m).z = 00814 SegmentIntRules[i] -> IntPoint(m).x; 00815 00816 CubeIntRules[i] -> IntPoint((k*np+l)*np+m).weight = 00817 SegmentIntRules[i] -> IntPoint(k).weight * 00818 SegmentIntRules[i] -> IntPoint(l).weight * 00819 SegmentIntRules[i] -> IntPoint(m).weight; 00820 } 00821 } 00822 00823 }