MFEM v2.0
bilininteg.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 Bilinear Form Integrators
00013 
00014 #include "fem.hpp"
00015 #include <math.h>
00016 
00017 void BilinearFormIntegrator::AssembleElementMatrix (
00018    const FiniteElement &el, ElementTransformation &Trans,
00019    DenseMatrix &elmat )
00020 {
00021    mfem_error ("BilinearFormIntegrator::AssembleElementMatrix (...)\n"
00022                "   is not implemented fot this class.");
00023 }
00024 
00025 void BilinearFormIntegrator::AssembleElementMatrix2 (
00026    const FiniteElement &el1, const FiniteElement &el2,
00027    ElementTransformation &Trans, DenseMatrix &elmat )
00028 {
00029    mfem_error ("BilinearFormIntegrator::AssembleElementMatrix2 (...)\n"
00030                "   is not implemented fot this class.");
00031 }
00032 
00033 void BilinearFormIntegrator::AssembleFaceMatrix (
00034    const FiniteElement &el1, const FiniteElement &el2,
00035    FaceElementTransformations &Trans, DenseMatrix &elmat)
00036 {
00037    mfem_error ("BilinearFormIntegrator::AssembleFaceMatrix (...)\n"
00038                "   is not implemented fot this class.");
00039 }
00040 
00041 
00042 void TransposeIntegrator::AssembleElementMatrix (
00043    const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat)
00044 {
00045    bfi -> AssembleElementMatrix (el, Trans, bfi_elmat);
00046    // elmat = bfi_elmat^t
00047    elmat.Transpose (bfi_elmat);
00048 }
00049 
00050 void TransposeIntegrator::AssembleElementMatrix2 (
00051    const FiniteElement &trial_fe, const FiniteElement &test_fe,
00052    ElementTransformation &Trans, DenseMatrix &elmat)
00053 {
00054    bfi -> AssembleElementMatrix2 (test_fe, trial_fe, Trans, bfi_elmat);
00055    // elmat = bfi_elmat^t
00056    elmat.Transpose (bfi_elmat);
00057 }
00058 
00059 void LumpedIntegrator::AssembleElementMatrix (
00060    const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat)
00061 {
00062    bfi -> AssembleElementMatrix (el, Trans, elmat);
00063    elmat.Lump();
00064 }
00065 
00066 
00067 void DiffusionIntegrator::AssembleElementMatrix
00068 ( const FiniteElement &el, ElementTransformation &Trans,
00069   DenseMatrix &elmat )
00070 {
00071    int nd = el.GetDof();
00072    int dim = el.GetDim();
00073    double w;
00074 
00075 #ifdef MFEM_USE_OPENMP
00076    DenseMatrix dshape(nd,dim), dshapedxt(nd,dim), invdfdx(dim);
00077 #else
00078    dshape.SetSize(nd,dim);
00079    dshapedxt.SetSize(nd,dim);
00080    invdfdx.SetSize(dim);
00081 #endif
00082    elmat.SetSize(nd);
00083 
00084    int order;
00085    if (el.Space() == FunctionSpace::Pk)
00086       order = 2*el.GetOrder() - 2;
00087    else
00088       // order = 2*el.GetOrder() - 2;  // <-- this seems to work fine too
00089       order = 2*el.GetOrder() + dim - 1;
00090 
00091    const IntegrationRule *ir;
00092    if (el.Space() == FunctionSpace::rQk)
00093       ir = &RefinedIntRules.Get(el.GetGeomType(), order);
00094    else
00095       ir = &IntRules.Get(el.GetGeomType(), order);
00096 
00097    elmat = 0.0;
00098    for (int i = 0; i < ir->GetNPoints(); i++)
00099    {
00100       const IntegrationPoint &ip = ir->IntPoint(i);
00101       el.CalcDShape(ip, dshape);
00102 
00103       Trans.SetIntPoint (&ip);
00104       CalcInverse(Trans.Jacobian(), invdfdx);
00105       w = Trans.Weight() * ip.weight;
00106       Mult(dshape, invdfdx, dshapedxt);
00107       if (Q)
00108       {
00109          w *= Q->Eval(Trans, ip);
00110          AddMult_a_AAt(w, dshapedxt, elmat);
00111       }
00112       else
00113       {
00114          MQ->Eval(invdfdx, Trans, ip);
00115          invdfdx *= w;
00116          MultABt (dshapedxt, invdfdx, dshape);
00117          AddMultABt(dshape, dshapedxt, elmat);
00118       }
00119    }
00120 }
00121 
00122 void DiffusionIntegrator::ComputeElementFlux
00123 ( const FiniteElement &el, ElementTransformation &Trans,
00124   Vector &u, const FiniteElement &fluxelem, Vector &flux, int wcoef )
00125 {
00126    int i, j, nd, dim, fnd;
00127 
00128    nd = el.GetDof();
00129    dim = el.GetDim();
00130 
00131 #ifdef MFEM_USE_OPENMP
00132    DenseMatrix dshape(nd,dim), invdfdx(dim);
00133 #else
00134    dshape.SetSize(nd,dim);
00135    invdfdx.SetSize(dim);
00136 #endif
00137    vec.SetSize(dim);
00138 
00139    const IntegrationRule &ir = fluxelem.GetNodes();
00140    fnd = ir.GetNPoints();
00141    flux.SetSize( fnd * dim );
00142 
00143    for (i = 0; i < fnd; i++)
00144    {
00145       const IntegrationPoint &ip = ir.IntPoint(i);
00146       el.CalcDShape(ip, dshape);
00147       dshape.MultTranspose(u, vec);
00148 
00149       Trans.SetIntPoint (&ip);
00150       CalcInverse(Trans.Jacobian(), invdfdx);
00151       invdfdx.MultTranspose(vec, pointflux);
00152 
00153       if (wcoef)
00154       {
00155          if (Q)
00156          {
00157             pointflux *= Q->Eval(Trans,ip);
00158             for (j = 0; j < dim; j++)
00159                flux(fnd*j+i) = pointflux(j);
00160          }
00161          else
00162          {
00163             MQ->Eval(invdfdx, Trans, ip);
00164             invdfdx.Mult(pointflux, vec);
00165             for (j = 0; j < dim; j++)
00166                flux(fnd*j+i) = vec(j);
00167          }
00168       }
00169    }
00170 }
00171 
00172 double DiffusionIntegrator::ComputeFluxEnergy
00173 ( const FiniteElement &fluxelem, ElementTransformation &Trans,
00174   Vector &flux)
00175 {
00176    int i, j, k, nd, dim, order;
00177    double energy, co;
00178 
00179    nd = fluxelem.GetDof();
00180    dim = fluxelem.GetDim();
00181 
00182 #ifdef MFEM_USE_OPENMP
00183    DenseMatrix invdfdx;
00184 #endif
00185 
00186    shape.SetSize(nd);
00187    pointflux.SetSize(dim);
00188    if (MQ)
00189    {
00190       invdfdx.SetSize(dim);
00191       vec.SetSize(dim);
00192    }
00193 
00194    order = 2 * fluxelem.GetOrder(); // <--
00195    const IntegrationRule *ir = &IntRules.Get(fluxelem.GetGeomType(), order);
00196 
00197    energy = 0.0;
00198    for (i = 0; i < ir->GetNPoints(); i++)
00199    {
00200       const IntegrationPoint &ip = ir->IntPoint(i);
00201       fluxelem.CalcShape(ip, shape);
00202 
00203       pointflux = 0.0;
00204       for (k = 0; k < dim; k++)
00205          for (j = 0; j < nd; j++)
00206             pointflux(k) += flux(k*nd+j)*shape(j);
00207 
00208       Trans.SetIntPoint (&ip);
00209       co = Trans.Weight() * ip.weight;
00210 
00211       if (Q)
00212          co *= Q->Eval(Trans, ip) * ( pointflux * pointflux );
00213       else
00214       {
00215          MQ->Eval(invdfdx, Trans, ip);
00216          invdfdx.Mult(pointflux, vec);
00217          co *= ( pointflux * vec );
00218       }
00219 
00220       energy += co;
00221    }
00222 
00223    return energy;
00224 }
00225 
00226 
00227 void MassIntegrator::AssembleElementMatrix
00228 ( const FiniteElement &el, ElementTransformation &Trans,
00229   DenseMatrix &elmat )
00230 {
00231    int nd = el.GetDof();
00232    // int dim = el.GetDim();
00233    double w;
00234 
00235    elmat.SetSize(nd);
00236    shape.SetSize(nd);
00237 
00238    const IntegrationRule *ir = IntRule;
00239    if (ir == NULL)
00240    {
00241       // int order = 2 * el.GetOrder();
00242       int order = 2 * el.GetOrder() + Trans.OrderW();
00243 
00244       if (el.Space() == FunctionSpace::rQk)
00245          ir = &RefinedIntRules.Get(el.GetGeomType(), order);
00246       else
00247          ir = &IntRules.Get(el.GetGeomType(), order);
00248    }
00249 
00250    elmat = 0.0;
00251    for (int i = 0; i < ir->GetNPoints(); i++)
00252    {
00253       const IntegrationPoint &ip = ir->IntPoint(i);
00254       el.CalcShape(ip, shape);
00255 
00256       Trans.SetIntPoint (&ip);
00257       w = Trans.Weight() * ip.weight;
00258       if (Q)
00259          w *= Q -> Eval(Trans, ip);
00260 
00261       AddMult_a_VVt(w, shape, elmat);
00262    }
00263 }
00264 
00265 void MassIntegrator::AssembleElementMatrix2(
00266    const FiniteElement &trial_fe, const FiniteElement &test_fe,
00267    ElementTransformation &Trans, DenseMatrix &elmat)
00268 {
00269    int tr_nd = trial_fe.GetDof();
00270    int te_nd = test_fe.GetDof();
00271    // int dim = trial_fe.GetDim();
00272    double w;
00273 
00274    elmat.SetSize (te_nd, tr_nd);
00275    shape.SetSize (tr_nd);
00276    te_shape.SetSize (te_nd);
00277 
00278    const IntegrationRule *ir = IntRule;
00279    if (ir == NULL)
00280    {
00281       int order = trial_fe.GetOrder() + test_fe.GetOrder() + Trans.OrderW();
00282 
00283       ir = &IntRules.Get(trial_fe.GetGeomType(), order);
00284    }
00285 
00286    elmat = 0.0;
00287    for (int i = 0; i < ir->GetNPoints(); i++)
00288    {
00289       const IntegrationPoint &ip = ir->IntPoint(i);
00290       trial_fe.CalcShape(ip, shape);
00291       test_fe.CalcShape(ip, te_shape);
00292 
00293       Trans.SetIntPoint (&ip);
00294       w = Trans.Weight() * ip.weight;
00295       if (Q)
00296          w *= Q -> Eval(Trans, ip);
00297 
00298       te_shape *= w;
00299       AddMultVWt(te_shape, shape, elmat);
00300    }
00301 }
00302 
00303 
00304 void ConvectionIntegrator::AssembleElementMatrix (
00305    const FiniteElement &el, ElementTransformation &Trans,
00306    DenseMatrix &elmat )
00307 {
00308    int nd = el.GetDof();
00309    int dim = el.GetDim();
00310 
00311    elmat.SetSize(nd);
00312    dshape.SetSize(nd,dim);
00313    invdfdx.SetSize(dim);
00314    shape.SetSize(nd);
00315    vec1.SetSize(dim);
00316    vec2.SetSize(dim);
00317    BdFidxT.SetSize(nd);
00318 
00319    int order = 2*el.GetOrder() - 1;  //  <----------
00320    const IntegrationRule *ir = &IntRules.Get(el.GetGeomType(), order);
00321 
00322    elmat = 0.0;
00323    for (int i = 0; i < ir->GetNPoints(); i++)
00324    {
00325       const IntegrationPoint &ip = ir->IntPoint(i);
00326       el.CalcDShape(ip, dshape);
00327       el.CalcShape(ip, shape);
00328 
00329       Trans.SetIntPoint (&ip);
00330       CalcInverse (Trans.Jacobian(), invdfdx);
00331       Q.Eval(vec1, Trans, ip);
00332       vec1 *= Trans.Weight() * ip.weight;
00333 
00334       invdfdx.Mult(vec1, vec2);
00335       dshape.Mult(vec2, BdFidxT);
00336 
00337       AddMultVWt(shape, BdFidxT, elmat);
00338    }
00339 }
00340 
00341 
00342 void VectorMassIntegrator::AssembleElementMatrix
00343 ( const FiniteElement &el, ElementTransformation &Trans,
00344   DenseMatrix &elmat )
00345 {
00346    int nd   = el.GetDof();
00347    int dim  = el.GetDim();
00348    int vdim;
00349 
00350    double norm;
00351 
00352    // Get vdim from the ElementTransformation Trans ?
00353    vdim = (VQ) ? (VQ -> GetVDim()) : ((MQ) ? (MQ -> GetVDim()) : (dim));
00354 
00355    elmat.SetSize(nd*vdim);
00356    shape.SetSize(nd);
00357    partelmat.SetSize(nd);
00358    if (VQ)
00359       vec.SetSize(vdim);
00360    else if (MQ)
00361       mcoeff.SetSize(vdim);
00362 
00363    const IntegrationRule *ir = IntRule;
00364    if (ir == NULL)
00365    {
00366       int order = 2 * el.GetOrder() + Trans.OrderW() + Q_order;
00367 
00368       if (el.Space() == FunctionSpace::rQk)
00369          ir = &RefinedIntRules.Get(el.GetGeomType(), order);
00370       else
00371          ir = &IntRules.Get(el.GetGeomType(), order);
00372    }
00373 
00374    elmat = 0.0;
00375    for (int s = 0; s < ir->GetNPoints(); s++)
00376    {
00377       const IntegrationPoint &ip = ir->IntPoint(s);
00378       el.CalcShape(ip, shape);
00379 
00380       Trans.SetIntPoint (&ip);
00381       norm = ip.weight * Trans.Weight();
00382 
00383       MultVVt(shape, partelmat);
00384 
00385       if (Q)
00386       {
00387          norm *= Q -> Eval (Trans, ip);
00388          partelmat *= norm;
00389          for (int k = 0; k < vdim; k++)
00390             elmat.AddMatrix (partelmat, nd*k, nd*k);
00391       }
00392       else if (VQ)
00393       {
00394          VQ -> Eval (vec, Trans, ip);
00395          for (int k = 0; k < vdim; k++)
00396             elmat.AddMatrix (norm * vec(k), partelmat, nd*k, nd*k);
00397       }
00398       else // (MQ != NULL) -- matrix coefficient
00399       {
00400          MQ -> Eval (mcoeff, Trans, ip);
00401          for (int i = 0; i < vdim; i++)
00402             for (int j = 0; j < vdim; j++)
00403                elmat.AddMatrix (norm * mcoeff(i,j), partelmat, nd*i, nd*j);
00404       }
00405    }
00406 }
00407 
00408 void VectorFEDivergenceIntegrator::AssembleElementMatrix2(
00409    const FiniteElement &trial_fe, const FiniteElement &test_fe,
00410    ElementTransformation &Trans, DenseMatrix &elmat)
00411 {
00412    int trial_nd = trial_fe.GetDof(), test_nd = test_fe.GetDof(), i;
00413 
00414 #ifdef MFEM_USE_OPENMP
00415    Vector divshape(trial_nd), shape(test_nd);
00416 #else
00417    divshape.SetSize(trial_nd);
00418    shape.SetSize(test_nd);
00419 #endif
00420 
00421    elmat.SetSize(test_nd, trial_nd);
00422 
00423    int order = trial_fe.GetOrder() + test_fe.GetOrder() - 1; // <--
00424    const IntegrationRule *ir = &IntRules.Get(trial_fe.GetGeomType(), order);
00425 
00426    elmat = 0.0;
00427    for (i = 0; i < ir->GetNPoints(); i++)
00428    {
00429       const IntegrationPoint &ip = ir->IntPoint(i);
00430       trial_fe.CalcDivShape(ip, divshape);
00431       test_fe.CalcShape(ip, shape);
00432       double w = ip.weight;
00433       if (Q)
00434       {
00435          Trans.SetIntPoint(&ip);
00436          w *= Q->Eval(Trans, ip);
00437       }
00438       shape *= w;
00439       AddMultVWt(shape, divshape, elmat);
00440    }
00441 }
00442 
00443 void VectorFECurlIntegrator::AssembleElementMatrix2(
00444    const FiniteElement &trial_fe, const FiniteElement &test_fe,
00445    ElementTransformation &Trans, DenseMatrix &elmat)
00446 {
00447    int trial_nd = trial_fe.GetDof(), test_nd = test_fe.GetDof(), i;
00448    int dim = trial_fe.GetDim();
00449 
00450 #ifdef MFEM_USE_OPENMP
00451    DenseMatrix curlshapeTrial(trial_nd, dim);
00452    DenseMatrix curlshapeTrial_dFT(trial_nd, dim);
00453    DenseMatrix vshapeTest(test_nd, dim);
00454 #else
00455    curlshapeTrial.SetSize(trial_nd, dim);
00456    curlshapeTrial_dFT.SetSize(trial_nd, dim);
00457    vshapeTest.SetSize(test_nd, dim);
00458 #endif
00459 
00460    elmat.SetSize(test_nd, trial_nd);
00461 
00462    int order = trial_fe.GetOrder() + test_fe.GetOrder() - 1; // <--
00463    const IntegrationRule *ir = &IntRules.Get(trial_fe.GetGeomType(), order);
00464 
00465    elmat = 0.0;
00466    for (i = 0; i < ir->GetNPoints(); i++)
00467    {
00468       const IntegrationPoint &ip = ir->IntPoint(i);
00469       Trans.SetIntPoint(&ip);
00470       trial_fe.CalcCurlShape(ip, curlshapeTrial);
00471       MultABt(curlshapeTrial, Trans.Jacobian(), curlshapeTrial_dFT);
00472       test_fe.CalcVShape(Trans, vshapeTest);
00473       double w = ip.weight;
00474       if (Q)
00475          w *= Q->Eval(Trans, ip);
00476       vshapeTest *= w;
00477       AddMultABt(vshapeTest, curlshapeTrial_dFT, elmat);
00478    }
00479 }
00480 
00481 void DerivativeIntegrator::AssembleElementMatrix2 (
00482    const FiniteElement &trial_fe,
00483    const FiniteElement &test_fe,
00484    ElementTransformation &Trans,
00485    DenseMatrix &elmat)
00486 {
00487    int dim = trial_fe.GetDim();
00488    int trial_nd = trial_fe.GetDof();
00489    int test_nd = test_fe.GetDof();
00490 
00491    int i, l;
00492    double det;
00493 
00494    elmat.SetSize (test_nd,trial_nd);
00495    dshape.SetSize (trial_nd,dim);
00496    dshapedxt.SetSize(trial_nd,dim);
00497    dshapedxi.SetSize(trial_nd);
00498    invdfdx.SetSize(dim);
00499    shape.SetSize (test_nd);
00500 
00501    int order;
00502    if (trial_fe.Space() == FunctionSpace::Pk)
00503       order = trial_fe.GetOrder() + test_fe.GetOrder() - 1;
00504    else
00505       order = trial_fe.GetOrder() + test_fe.GetOrder() + dim;
00506 
00507    const IntegrationRule * ir;
00508    if (trial_fe.Space() == FunctionSpace::rQk)
00509       ir = &RefinedIntRules.Get(trial_fe.GetGeomType(), order);
00510    else
00511       ir = &IntRules.Get(trial_fe.GetGeomType(), order);
00512 
00513    elmat = 0.0;
00514    for(i = 0; i < ir->GetNPoints(); i++) {
00515       const IntegrationPoint &ip = ir->IntPoint(i);
00516 
00517       trial_fe.CalcDShape(ip, dshape);
00518 
00519       Trans.SetIntPoint (&ip);
00520       CalcInverse (Trans.Jacobian(), invdfdx);
00521       det = Trans.Weight();
00522       Mult (dshape, invdfdx, dshapedxt);
00523 
00524       test_fe.CalcShape(ip, shape);
00525 
00526       for (l = 0; l < trial_nd; l++)
00527          dshapedxi(l) = dshapedxt(l,xi);
00528 
00529       shape *= Q.Eval(Trans,ip) * det * ip.weight;
00530       AddMultVWt (shape, dshapedxi, elmat);
00531    }
00532 }
00533 
00534 void CurlCurlIntegrator::AssembleElementMatrix
00535 ( const FiniteElement &el, ElementTransformation &Trans,
00536   DenseMatrix &elmat )
00537 {
00538    int nd = el.GetDof();
00539    int dim = el.GetDim();
00540    double w;
00541 
00542 #ifdef MFEM_USE_OPENMP
00543    DenseMatrix Curlshape(nd,dim), Curlshape_dFt(nd,dim);
00544 #else
00545    Curlshape.SetSize(nd,dim);
00546    Curlshape_dFt.SetSize(nd,dim);
00547 #endif
00548    elmat.SetSize(nd);
00549 
00550    int order;
00551    if (el.Space() == FunctionSpace::Pk)
00552       order = 2*el.GetOrder() - 2;
00553    else
00554       order = 2*el.GetOrder();
00555 
00556    const IntegrationRule &ir = IntRules.Get(el.GetGeomType(), order);
00557 
00558    elmat = 0.0;
00559    for (int i = 0; i < ir.GetNPoints(); i++)
00560    {
00561       const IntegrationPoint &ip = ir.IntPoint(i);
00562       el.CalcCurlShape(ip, Curlshape);
00563 
00564       Trans.SetIntPoint (&ip);
00565 
00566       w = ip.weight / Trans.Weight();
00567 
00568       MultABt(Curlshape, Trans.Jacobian(), Curlshape_dFt);
00569 
00570       if (Q)
00571          w *= Q->Eval(Trans, ip);
00572 
00573       AddMult_a_AAt(w, Curlshape_dFt, elmat);
00574    }
00575 }
00576 
00577 
00578 void VectorFEMassIntegrator::AssembleElementMatrix(
00579    const FiniteElement &el,
00580    ElementTransformation &Trans,
00581    DenseMatrix &elmat)
00582 {
00583    int dof  = el.GetDof();
00584    int dim  = el.GetDim();
00585 
00586    double w;
00587 
00588 #ifdef MFEM_USE_OPENMP
00589    Vector D(VQ ? VQ->GetVDim() : 0);
00590    DenseMatrix vshape(dof, dim);
00591 #else
00592    vshape.SetSize(dof,dim);
00593 #endif
00594 
00595    elmat.SetSize(dof);
00596    elmat = 0.0;
00597 
00598    // int order = 2 * el.GetOrder();
00599    int order = Trans.OrderW() + 2 * el.GetOrder();
00600 
00601    const IntegrationRule &ir = IntRules.Get(el.GetGeomType(), order);
00602 
00603    for (int i = 0; i < ir.GetNPoints(); i++)
00604    {
00605       const IntegrationPoint &ip = ir.IntPoint(i);
00606 
00607       Trans.SetIntPoint (&ip);
00608 
00609       el.CalcVShape(Trans, vshape);
00610 
00611       w = ip.weight * Trans.Weight();
00612       if (VQ)
00613       {
00614          VQ->Eval(D, Trans, ip);
00615          D *= w;
00616          AddMultADAt(vshape, D, elmat);
00617       }
00618       else
00619       {
00620          if (Q)
00621             w *= Q -> Eval (Trans, ip);
00622          AddMult_a_AAt (w, vshape, elmat);
00623       }
00624    }
00625 }
00626 
00627 void VectorFEMassIntegrator::AssembleElementMatrix2(
00628    const FiniteElement &trial_fe, const FiniteElement &test_fe,
00629    ElementTransformation &Trans, DenseMatrix &elmat)
00630 {
00631    // assume test_fe is scalar FE and trial_fe is vector FE
00632    int dim  = test_fe.GetDim();
00633    int trial_dof = trial_fe.GetDof();
00634    int test_dof = test_fe.GetDof();
00635    double w;
00636 
00637    if (VQ)
00638       mfem_error("VectorFEMassIntegrator::AssembleElementMatrix2(...)\n"
00639                  "   is not implemented for vector permeability");
00640 
00641 #ifdef MFEM_USE_OPENMP
00642    DenseMatrix vshape(trial_dof, dim);
00643    Vector shape(test_dof);
00644 #else
00645    vshape.SetSize(trial_dof, dim);
00646    shape.SetSize(test_dof);
00647 #endif
00648 
00649    elmat.SetSize (dim*test_dof, trial_dof);
00650 
00651    int order = (Trans.OrderW() +
00652                 test_fe.GetOrder() + trial_fe.GetOrder());
00653 
00654    const IntegrationRule &ir = IntRules.Get(test_fe.GetGeomType(), order);
00655 
00656    elmat = 0.0;
00657    for (int i = 0; i < ir.GetNPoints(); i++)
00658    {
00659       const IntegrationPoint &ip = ir.IntPoint(i);
00660 
00661       Trans.SetIntPoint (&ip);
00662 
00663       trial_fe.CalcVShape(Trans, vshape);
00664       test_fe.CalcShape(ip, shape);
00665 
00666       w = ip.weight * Trans.Weight();
00667       if (Q)
00668          w *= Q -> Eval (Trans, ip);
00669 
00670       for (int d = 0; d < dim; d++)
00671       {
00672          for (int j = 0; j < test_dof; j++)
00673          {
00674             for (int k = 0; k < trial_dof; k++)
00675             {
00676                elmat(d * test_dof + j, k) += w * shape(j) * vshape(k, d);
00677             }
00678          }
00679       }
00680    }
00681 }
00682 
00683 
00684 void VectorDivergenceIntegrator::AssembleElementMatrix2(
00685    const FiniteElement &trial_fe,
00686    const FiniteElement &test_fe,
00687    ElementTransformation &Trans,
00688    DenseMatrix &elmat)
00689 {
00690    int dim  = trial_fe.GetDim();
00691    int trial_dof = trial_fe.GetDof();
00692    int test_dof = test_fe.GetDof();
00693    double c;
00694 
00695    dshape.SetSize (trial_dof, dim);
00696    gshape.SetSize (trial_dof, dim);
00697    Jadj.SetSize (dim);
00698    divshape.SetSize (dim*trial_dof);
00699    shape.SetSize (test_dof);
00700 
00701    elmat.SetSize (test_dof, dim*trial_dof);
00702 
00703    int order = Trans.OrderGrad(&trial_fe) + test_fe.GetOrder();
00704 
00705    const IntegrationRule *ir;
00706    ir = &IntRules.Get (trial_fe.GetGeomType(), order);
00707 
00708    elmat = 0.0;
00709 
00710    for (int i = 0; i < ir -> GetNPoints(); i++)
00711    {
00712       const IntegrationPoint &ip = ir->IntPoint(i);
00713 
00714       trial_fe.CalcDShape (ip, dshape);
00715       test_fe.CalcShape (ip, shape);
00716 
00717       Trans.SetIntPoint (&ip);
00718       CalcAdjugate(Trans.Jacobian(), Jadj);
00719 
00720       Mult (dshape, Jadj, gshape);
00721 
00722       gshape.GradToDiv (divshape);
00723 
00724       c = ip.weight;
00725       if (Q)
00726          c *= Q -> Eval (Trans, ip);
00727 
00728       // elmat += c * shape * divshape ^ t
00729       shape *= c;
00730       AddMultVWt (shape, divshape, elmat);
00731    }
00732 }
00733 
00734 
00735 void DivDivIntegrator::AssembleElementMatrix(
00736    const FiniteElement &el,
00737    ElementTransformation &Trans,
00738    DenseMatrix &elmat)
00739 {
00740    int dof = el.GetDof();
00741    double c;
00742 
00743 #ifdef MFEM_USE_OPENMP
00744    Vector divshape(dof);
00745 #else
00746    divshape.SetSize(dof);
00747 #endif
00748    elmat.SetSize(dof);
00749 
00750    int order = 2 * el.GetOrder() - 2; // <--- OK for RTk
00751    const IntegrationRule *ir = &IntRules.Get(el.GetGeomType(), order);
00752 
00753    elmat = 0.0;
00754 
00755    for (int i = 0; i < ir -> GetNPoints(); i++)
00756    {
00757       const IntegrationPoint &ip = ir->IntPoint(i);
00758 
00759       el.CalcDivShape (ip, divshape);
00760 
00761       Trans.SetIntPoint (&ip);
00762       c = ip.weight / Trans.Weight();
00763 
00764       if (Q)
00765          c *= Q -> Eval (Trans, ip);
00766 
00767       // elmat += c * divshape * divshape ^ t
00768       AddMult_a_VVt (c, divshape, elmat);
00769    }
00770 }
00771 
00772 
00773 void VectorDiffusionIntegrator::AssembleElementMatrix(
00774    const FiniteElement &el,
00775    ElementTransformation &Trans,
00776    DenseMatrix &elmat)
00777 {
00778    int dim = el.GetDim();
00779    int dof = el.GetDof();
00780 
00781    double norm;
00782 
00783    elmat.SetSize (dim * dof);
00784 
00785    Jinv.  SetSize (dim);
00786    dshape.SetSize (dof, dim);
00787    gshape.SetSize (dof, dim);
00788    pelmat.SetSize (dof);
00789 
00790    // integrant is rational function if det(J) is not constant
00791    int order = 2 * Trans.OrderGrad(&el); // order of the numerator
00792 
00793    const IntegrationRule *ir;
00794    if (el.Space() == FunctionSpace::rQk)
00795       ir = &RefinedIntRules.Get(el.GetGeomType(), order);
00796    else
00797       ir = &IntRules.Get(el.GetGeomType(), order);
00798 
00799    elmat = 0.0;
00800 
00801    for (int i = 0; i < ir -> GetNPoints(); i++)
00802    {
00803       const IntegrationPoint &ip = ir->IntPoint(i);
00804 
00805       el.CalcDShape (ip, dshape);
00806 
00807       Trans.SetIntPoint (&ip);
00808       norm = ip.weight * Trans.Weight();
00809       CalcInverse (Trans.Jacobian(), Jinv);
00810 
00811       Mult (dshape, Jinv, gshape);
00812 
00813       MultAAt (gshape, pelmat);
00814 
00815       if (Q)
00816          norm *= Q -> Eval (Trans, ip);
00817 
00818       pelmat *= norm;
00819 
00820       for (int d = 0; d < dim; d++)
00821       {
00822          for (int k = 0; k < dof; k++)
00823             for (int l = 0; l < dof; l++)
00824                elmat (dof*d+k, dof*d+l) += pelmat (k, l);
00825       }
00826    }
00827 }
00828 
00829 
00830 void ElasticityIntegrator::AssembleElementMatrix(
00831    const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat)
00832 {
00833    int dof  = el.GetDof();
00834    int dim = el.GetDim();
00835    double w, L, M;
00836 
00837 #ifdef MFEM_USE_OPENMP
00838    DenseMatrix dshape(dof, dim), Jinv(dim), gshape(dof, dim), pelmat(dof);
00839    Vector divshape(dim*dof);
00840 #else
00841    Jinv.SetSize(dim);
00842    dshape.SetSize(dof, dim);
00843    gshape.SetSize(dof, dim);
00844    pelmat.SetSize(dof);
00845    divshape.SetSize(dim*dof);
00846 #endif
00847 
00848    elmat.SetSize(dof * dim);
00849 
00850    int order = 2 * Trans.OrderGrad(&el); // correct order?
00851    const IntegrationRule *ir = &IntRules.Get(el.GetGeomType(), order);
00852 
00853    elmat = 0.0;
00854 
00855    for (int i = 0; i < ir -> GetNPoints(); i++)
00856    {
00857       const IntegrationPoint &ip = ir->IntPoint(i);
00858 
00859       el.CalcDShape(ip, dshape);
00860 
00861       Trans.SetIntPoint(&ip);
00862       w = ip.weight * Trans.Weight();
00863       CalcInverse(Trans.Jacobian(), Jinv);
00864       Mult(dshape, Jinv, gshape);
00865       MultAAt(gshape, pelmat);
00866       gshape.GradToDiv (divshape);
00867 
00868       M = mu->Eval(Trans, ip);
00869       if (lambda)
00870          L = lambda->Eval(Trans, ip);
00871       else
00872       {
00873          L = q_lambda * M;
00874          M = q_mu * M;
00875       }
00876 
00877       if (L != 0.0)
00878          AddMult_a_VVt(L * w, divshape, elmat);
00879 
00880       if (M != 0.0)
00881       {
00882          for (int d = 0; d < dim; d++)
00883          {
00884             for (int k = 0; k < dof; k++)
00885                for (int l = 0; l < dof; l++)
00886                   elmat (dof*d+k, dof*d+l) += (M * w) * pelmat(k, l);
00887          }
00888          for (int i = 0; i < dim; i++)
00889             for (int j = 0; j < dim; j++)
00890             {
00891                for (int k = 0; k < dof; k++)
00892                   for (int l = 0; l < dof; l++)
00893                      elmat(dof*i+k, dof*j+l) +=
00894                         (M * w) * gshape(k, j) * gshape(l, i);
00895                // + (L * w) * gshape(k, i) * gshape(l, j)
00896             }
00897       }
00898    }
00899 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines