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 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 }