MFEM v2.0
intrules.cpp
Go to the documentation of this file.
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 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines