00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef BOUNDARY_CONDITION_DISCRETIZATION_PENALTY_HPP
00022 #define BOUNDARY_CONDITION_DISCRETIZATION_PENALTY_HPP
00023
00024 #include <BoundaryConditionFDMDiscretization.hpp>
00025
00026 #include <FiniteElementTraits.hpp>
00027 #include <SurfaceMesh.hpp>
00028
00029 #include <UnAssembledMatrix.hpp>
00030
00031 #include <ErrorHandler.hpp>
00032
00033
00034 template<typename MeshType,
00035 ScalarDiscretizationTypeBase::Type TypeOfDiscretization>
00036 class BoundaryConditionDiscretizationPenalty
00037 : public BoundaryConditionFDMDiscretization<MeshType,
00038 TypeOfDiscretization>
00039 {
00040 public:
00041 typedef
00042 typename MeshType::CellType
00043 CellType;
00046 typedef
00047 typename FiniteElementTraits<CellType, TypeOfDiscretization>::Type
00048 FiniteElement;
00050 typedef
00051 typename FiniteElementTraits<CellType, TypeOfDiscretization>::Transformation
00052 ConformTransformation;
00054 private:
00055 const real_t __epsilon;
00056 public:
00057 void getDiagonal (BaseVector& Z) const
00058 {
00059 Vector<real_t>& z = dynamic_cast<Vector<real_t>&>(Z);
00060
00061
00062 BoundaryConditionFDMDiscretization<MeshType,
00063 TypeOfDiscretization>
00064 ::__StandardGetDiagonalVariationalBorderBilinearOperator(*this,
00065 z);
00066 const BoundaryConditionSurfaceMeshAssociation& bcMeshAssociation = *(this->__bcMeshAssociation);
00067
00068 for (size_t i=0; i<this->problem().numberOfUnknown(); ++i) {
00069 for (BoundaryConditionSurfaceMeshAssociation
00070 ::DirichletMeshAssociation
00071 ::const_iterator ibcMesh = bcMeshAssociation.bc(i).begin();
00072 ibcMesh != bcMeshAssociation.bc(i).end();
00073 ++ibcMesh) {
00074 const Dirichlet& D = *(*ibcMesh).first;
00075 const SurfaceMesh& surfMesh = *(*ibcMesh).second;
00076
00077 BoundaryConditionFDMDiscretization<MeshType,
00078 TypeOfDiscretization>
00079 ::__meshWrapper(surfMesh,
00080 typename BoundaryConditionDiscretizationPenalty
00081 ::template __GetDiagonalDirichletBoundaryConditions<Vector<real_t> >(D,
00082 i,
00083 z,
00084 *this));
00085
00086 }
00087 }
00088 }
00089
00090
00091 void setMatrix (ReferenceCounting<BaseMatrix> givenA,
00092 ReferenceCounting<BaseVector> b) const
00093 {
00094 switch((*givenA).type()) {
00095 case BaseMatrix::doubleHashedMatrix: {
00096 DoubleHashedMatrix& A = dynamic_cast<DoubleHashedMatrix&>(*givenA);
00097
00098 const BoundaryConditionSurfaceMeshAssociation& bcMeshAssociation = *(this->__bcMeshAssociation);
00099
00100
00101 BoundaryConditionFDMDiscretization<MeshType,
00102 TypeOfDiscretization>
00103 ::__StandardVariationalBorderBilinearOperator(*this,
00104 A);
00105
00106
00107 for (size_t i=0; i<this->problem().numberOfUnknown(); ++i) {
00108 for (BoundaryConditionSurfaceMeshAssociation
00109 ::DirichletMeshAssociation
00110 ::const_iterator ibcMesh = bcMeshAssociation.bc(i).begin();
00111 ibcMesh != bcMeshAssociation.bc(i).end();
00112 ++ibcMesh) {
00113 const Dirichlet& D = *(*ibcMesh).first;
00114 const SurfaceMesh& surfMesh = *(*ibcMesh).second;
00115
00116 BoundaryConditionFDMDiscretization<MeshType,
00117 TypeOfDiscretization>
00118 ::__meshWrapper(surfMesh,
00119 __SetMatrixDirichletBoundaryConditions<DoubleHashedMatrix>(D, i, __epsilon,
00120 A, *this));
00121 }
00122 }
00123
00124 break;
00125 }
00126 case BaseMatrix::unAssembled: {
00127 UnAssembledMatrix& A = dynamic_cast<UnAssembledMatrix&>(*givenA);
00128 A.setBoundaryConditions(this);
00129 break;
00130 }
00131 default: {
00132 throw ErrorHandler(__FILE__,__LINE__,
00133 "unexpected matrix type",
00134 ErrorHandler::unexpected);
00135 }
00136 }
00137 }
00138
00139 void setSecondMember (ReferenceCounting<BaseMatrix> givenA,
00140 ReferenceCounting<BaseVector> givenB) const
00141 {
00142 Vector<real_t>& b = dynamic_cast<Vector<real_t>&>(*givenB);
00143
00145 BoundaryConditionFDMDiscretization<MeshType,
00146 TypeOfDiscretization>::
00147 __StandardVariationalBorderLinearOperator(*this,
00148 b);
00149
00150 const BoundaryConditionSurfaceMeshAssociation& bcMeshAssociation = *(this->__bcMeshAssociation);
00151
00152
00153 for (size_t i=0; i<this->problem().numberOfUnknown(); ++i) {
00154 for (BoundaryConditionSurfaceMeshAssociation
00155 ::DirichletMeshAssociation
00156 ::const_iterator ibcMesh = bcMeshAssociation.bc(i).begin();
00157 ibcMesh != bcMeshAssociation.bc(i).end();
00158 ++ibcMesh) {
00159 const Dirichlet& D = *(*ibcMesh).first;
00160 const SurfaceMesh& surfMesh = *(*ibcMesh).second;
00161
00162 BoundaryConditionFDMDiscretization<MeshType,
00163 TypeOfDiscretization>
00164 ::__meshWrapper(surfMesh,__SetSecondMemberDirichlet<Vector<real_t> >(D, i, b,*this));
00165 }
00166 }
00167 }
00168
00169 void timesX(const BaseVector& X, BaseVector& Z) const
00170 {
00171 const Vector<real_t>& x = dynamic_cast<const Vector<real_t>&>(X);
00172 Vector<real_t>& z = dynamic_cast<Vector<real_t>&>(Z);
00173
00174
00175 BoundaryConditionFDMDiscretization<MeshType,
00176 TypeOfDiscretization>::
00177 __StandardVariationalBorderBilinearOperatorTimesX(*this,
00178 x, z);
00179 const BoundaryConditionSurfaceMeshAssociation& bcMeshAssociation = *(this->__bcMeshAssociation);
00180
00181 for (size_t i=0; i<this->problem().numberOfUnknown(); ++i) {
00182 for (BoundaryConditionSurfaceMeshAssociation
00183 ::DirichletMeshAssociation
00184 ::const_iterator ibcMesh = bcMeshAssociation.bc(i).begin();
00185 ibcMesh != bcMeshAssociation.bc(i).end();
00186 ++ibcMesh) {
00187 const Dirichlet& D = *(*ibcMesh).first;
00188 const SurfaceMesh& surfMesh = *(*ibcMesh).second;
00189
00190 BoundaryConditionFDMDiscretization<MeshType,
00191 TypeOfDiscretization>
00192 ::__meshWrapper(surfMesh,
00193 typename BoundaryConditionDiscretizationPenalty
00194 ::template __TimesXDirichlet<Vector<real_t> >(D, i,
00195 x, z,
00196 *this));
00197 }
00198 }
00199 }
00200
00201 void transposedTimesX(const BaseVector& X, BaseVector& Z) const
00202 {
00203 const Vector<real_t>& x = dynamic_cast<const Vector<real_t>&>(X);
00204 Vector<real_t>& z = dynamic_cast<Vector<real_t>&>(Z);
00205
00206
00207 BoundaryConditionFDMDiscretization<MeshType,
00208 TypeOfDiscretization>::
00209 __StandardVariationalBorderBilinearOperatorTransposedTimesX(*this,
00210 x, z);
00211 const BoundaryConditionSurfaceMeshAssociation& bcMeshAssociation = *(this->__bcMeshAssociation);
00212
00213 for (size_t i=0; i<this->problem().numberOfUnknown(); ++i) {
00214 for (BoundaryConditionSurfaceMeshAssociation
00215 ::DirichletMeshAssociation
00216 ::const_iterator ibcMesh = bcMeshAssociation.bc(i).begin();
00217 ibcMesh != bcMeshAssociation.bc(i).end();
00218 ++ibcMesh) {
00219 const Dirichlet& D = *(*ibcMesh).first;
00220 const SurfaceMesh& surfMesh = *(*ibcMesh).second;
00221
00222 BoundaryConditionFDMDiscretization<MeshType,
00223 TypeOfDiscretization>
00224 ::__meshWrapper(surfMesh,
00225 typename BoundaryConditionDiscretizationPenalty
00226 ::template __TransposedTimesXDirichlet<Vector<real_t> >(D, i,
00227 x, z,
00228 *this));
00229 }
00230 }
00231 }
00232
00233 BoundaryConditionDiscretizationPenalty(const Problem& problem,
00234 const MeshType& mesh,
00235 const DegreeOfFreedomSet& dof,
00236 const real_t epsilon)
00237 : BoundaryConditionFDMDiscretization<MeshType,
00238 TypeOfDiscretization>(problem, mesh, dof),
00239 __epsilon(epsilon)
00240 {
00241 ;
00242 }
00243
00244 ~BoundaryConditionDiscretizationPenalty()
00245 {
00246 ;
00247 }
00248
00250 private:
00251
00252 template<typename MatrixType>
00253 class __SetMatrixDirichletBoundaryConditions
00254 {
00255 private:
00256 const Dirichlet& __dirichlet;
00257
00258 const size_t __equationNumber;
00259 const real_t __epsilon;
00260
00261 MatrixType& __A;
00262
00263 const BoundaryConditionDiscretizationPenalty<MeshType,
00264 TypeOfDiscretization>& __bc;
00265
00266 public:
00267
00268 template <typename SurfaceMeshType>
00269 void eval(const SurfaceMeshType& surfMesh) const
00270 {
00271 typedef typename SurfaceMeshType::CellType BoundaryCellType;
00272
00273 typedef
00274 typename FiniteElementTraits<BoundaryCellType,
00275 TypeOfDiscretization>::Transformation
00276 BoundaryConformTransformation;
00277
00278 typedef
00279 typename FiniteElementTraits<BoundaryCellType,
00280 TypeOfDiscretization>::Type
00281 BoundaryFiniteElement;
00282
00283 typedef
00284 typename BoundaryFiniteElement::QuadratureType
00285 BoundaryQuadratureType;
00286
00287 const FiniteElement& finiteElement
00288 = FiniteElement::instance();
00289
00290 const BoundaryQuadratureType& referenceBoundaryQuadrature
00291 = BoundaryQuadratureType::instance();
00292
00293 const ScalarDegreeOfFreedomPositionsSet& dofPositions
00294 = __bc.__degreeOfFreedomSet.positionsSet(0);
00295
00296 AutoPointer<ConformTransformation> pT;
00297
00298 const CellType* lastCell = 0;
00299
00300 for (typename SurfaceMeshType::const_iterator iface(surfMesh);
00301 not(iface.end()); ++iface) {
00302 const typename SurfaceMeshType::CellType& face = *iface;
00303 const BoundaryConformTransformation boundaryT(face);
00304
00305 const CellType& cell
00306 = static_cast<const CellType&>(face.mother());
00307
00308 if(lastCell != &cell) {
00309 pT = new ConformTransformation(cell);
00310 lastCell = &cell;
00311 }
00312
00313 const size_t cellNumber = __bc.mesh().cellNumber(cell);
00314
00315 const ConformTransformation& T = *pT;
00316
00317 for (size_t k=0; k<BoundaryQuadratureType::numberOfQuadraturePoints;
00318 k++) {
00319
00320 TinyVector<3, real_t> q;
00321 boundaryT.value(referenceBoundaryQuadrature[k], q);
00322
00323 const real_t weight
00324 = referenceBoundaryQuadrature.weight(k)
00325 * face.volume();
00326
00327 TinyVector<3> coordinates;
00328 T.invertT(q, coordinates);
00329
00330 typename FiniteElement::ElementaryVector W;
00331 for (size_t l=0; l<FiniteElement::numberOfDegreesOfFreedom; l++)
00332 W[l] = finiteElement.W(l,coordinates);
00333
00334 typename FiniteElement::ElementaryMatrix WiWj;
00335
00336 for (size_t l=0; l<FiniteElement::numberOfDegreesOfFreedom; l++)
00337 for (size_t m=0; m<FiniteElement::numberOfDegreesOfFreedom; m++)
00338 WiWj(l,m) = W[l] * W[m];
00339
00340 size_t indices[FiniteElement::numberOfDegreesOfFreedom];
00341 for (size_t l=0; l<FiniteElement::numberOfDegreesOfFreedom; ++l) {
00342 indices[l] = __bc.__degreeOfFreedomSet(__equationNumber,
00343 dofPositions(cellNumber,l));
00344 }
00345
00346 for (size_t l=0; l<FiniteElement::numberOfDegreesOfFreedom; l++) {
00347 const size_t I = indices[l];
00348 for (size_t m=0; m<FiniteElement::numberOfDegreesOfFreedom; m++) {
00349 const size_t J = indices[m];
00350 __A(I,J) += weight * WiWj(l,m) / __epsilon;
00351 }
00352 }
00353 }
00354 }
00355 }
00356
00357 __SetMatrixDirichletBoundaryConditions(const Dirichlet& D,
00358 const size_t& equationNumber,
00359 const real_t& epsilon,
00360 MatrixType& A,
00361 const BoundaryConditionDiscretizationPenalty<MeshType,
00362 TypeOfDiscretization>& bc)
00363 : __dirichlet(D),
00364 __equationNumber(equationNumber),
00365 __epsilon(epsilon),
00366 __A(A),
00367 __bc(bc)
00368 {
00369 ;
00370 }
00371
00372 __SetMatrixDirichletBoundaryConditions(const __SetMatrixDirichletBoundaryConditions& S)
00373 : __dirichlet(S.__dirichlet),
00374 __equationNumber(S.__equationNumber),
00375 __epsilon(S.__epsilon),
00376 __A(S.__A),
00377 __bc(S.__bc)
00378 {
00379 ;
00380 }
00381
00382 ~__SetMatrixDirichletBoundaryConditions()
00383 {
00384 ;
00385 }
00386 };
00387
00388 template <typename VectorType>
00389 class __GetDiagonalDirichletBoundaryConditions
00390 {
00391 private:
00392 const Dirichlet& __dirichlet;
00393
00394 const size_t __equationNumber;
00395
00396 VectorType& __z;
00397
00398 const BoundaryConditionDiscretizationPenalty<MeshType,
00399 TypeOfDiscretization>& __bc;
00400
00401 public:
00402
00403 template <typename SurfaceMeshType>
00404 void eval(const SurfaceMeshType& surfaceMesh) const
00405 {
00406 typedef typename SurfaceMeshType::CellType BoundaryCellType;
00407
00408 typedef
00409 typename FiniteElementTraits<BoundaryCellType,
00410 TypeOfDiscretization>::Transformation
00411 BoundaryConformTransformation;
00412
00413 typedef
00414 typename FiniteElementTraits<BoundaryCellType,
00415 TypeOfDiscretization>::Type
00416 BoundaryFiniteElement;
00417
00418 typedef
00419 typename BoundaryFiniteElement::QuadratureType
00420 BoundaryQuadratureType;
00421
00422 const FiniteElement& finiteElement = FiniteElement::instance();
00423
00424 const BoundaryQuadratureType& referenceBoundaryQuadrature
00425 = BoundaryQuadratureType::instance();
00426
00427 const ScalarDegreeOfFreedomPositionsSet& dofPositions
00428 = __bc.__degreeOfFreedomSet.positionsSet(0);
00429
00430 AutoPointer<ConformTransformation> pT;
00431
00432 const CellType* lastCell = 0;
00433
00434 for (typename SurfaceMeshType::const_iterator iface(surfaceMesh);
00435 not(iface.end()); ++iface) {
00436 const typename SurfaceMeshType::CellType& face = *iface;
00437 const BoundaryConformTransformation boundaryT(face);
00438
00439 const CellType& cell
00440 = static_cast<const CellType&>(face.mother());
00441
00442 if(lastCell != &cell) {
00443 pT = new ConformTransformation(cell);
00444 lastCell = &cell;
00445 }
00446
00447 const size_t cellNumber = __bc.mesh().cellNumber(cell);
00448
00449 const ConformTransformation& T = *pT;
00450
00451 for (size_t k=0; k<BoundaryQuadratureType::numberOfQuadraturePoints;
00452 k++) {
00453
00454 TinyVector<3, real_t> q;
00455 boundaryT.value(referenceBoundaryQuadrature[k], q);
00456
00457 const real_t weight
00458 = referenceBoundaryQuadrature.weight(k)
00459 * face.volume();
00460
00461 TinyVector<3> coordinates;
00462 T.invertT(q, coordinates);
00463
00464 typename FiniteElement::ElementaryVector W;
00465 for (size_t l=0; l<FiniteElement::numberOfDegreesOfFreedom; l++)
00466 W[l] = finiteElement.W(l,coordinates);
00467
00468 size_t indices[FiniteElement::numberOfDegreesOfFreedom];
00469 for (size_t l=0; l<FiniteElement::numberOfDegreesOfFreedom; ++l) {
00470 indices[l] = __bc.__degreeOfFreedomSet(__equationNumber,
00471 dofPositions(cellNumber,l));
00472 }
00473
00474 for (size_t l=0; l<FiniteElement::numberOfDegreesOfFreedom; l++) {
00475 const size_t& I = indices[l];
00476 __z[I] += W[l] * W[l] * weight / __bc.__epsilon;
00477 }
00478 }
00479 }
00480 }
00481
00482
00483 __GetDiagonalDirichletBoundaryConditions(const Dirichlet& D,
00484 const size_t equationNumber,
00485 VectorType& z,
00486 const BoundaryConditionDiscretizationPenalty& bc)
00487 : __dirichlet(D),
00488 __equationNumber(equationNumber),
00489 __z(z),
00490 __bc(bc)
00491 {
00492 ;
00493 }
00494
00495 __GetDiagonalDirichletBoundaryConditions(const __GetDiagonalDirichletBoundaryConditions& G)
00496 : __dirichlet(G.__dirichlet),
00497 __equationNumber(G.__equationNumber),
00498 __z(G.__z),
00499 __bc(G.__bc)
00500 {
00501 ;
00502 }
00503
00504 ~__GetDiagonalDirichletBoundaryConditions()
00505 {
00506 ;
00507 }
00508 };
00509
00510 template <typename VectorType>
00511 class __TimesXDirichlet
00512 {
00513 private:
00514 const Dirichlet& __dirichlet;
00515
00516 const size_t __equationNumber;
00517
00518 const VectorType& __x;
00519
00520 VectorType& __z;
00521
00522 const BoundaryConditionDiscretizationPenalty<MeshType,
00523 TypeOfDiscretization>& __bc;
00524
00525 public:
00526
00527 template <typename SurfaceMeshType>
00528 void eval(const SurfaceMeshType& surfaceMesh) const
00529 {
00530 typedef typename SurfaceMeshType::CellType BoundaryCellType;
00531
00532 typedef
00533 typename FiniteElementTraits<BoundaryCellType,
00534 TypeOfDiscretization>::Transformation
00535 BoundaryConformTransformation;
00536
00537 typedef
00538 typename FiniteElementTraits<BoundaryCellType,
00539 TypeOfDiscretization>::Type
00540 BoundaryFiniteElement;
00541
00542 typedef
00543 typename BoundaryFiniteElement::QuadratureType
00544 BoundaryQuadratureType;
00545
00546 const FiniteElement& finiteElement = FiniteElement::instance();
00547
00548 const BoundaryQuadratureType& referenceBoundaryQuadrature
00549 = BoundaryQuadratureType::instance();
00550
00551 const ScalarDegreeOfFreedomPositionsSet& dofPositions
00552 = __bc.__degreeOfFreedomSet.positionsSet(0);
00553
00554 AutoPointer<ConformTransformation> pT;
00555
00556 const CellType* lastCell = 0;
00557
00558 for (typename SurfaceMeshType::const_iterator iface(surfaceMesh);
00559 not(iface.end()); ++iface) {
00560 const typename SurfaceMeshType::CellType& face = *iface;
00561 const BoundaryConformTransformation boundaryT(face);
00562
00563 const CellType& cell
00564 = static_cast<const CellType&>(face.mother());
00565
00566 if(lastCell != &cell) {
00567 pT = new ConformTransformation(cell);
00568 lastCell = &cell;
00569 }
00570
00571 const size_t cellNumber = __bc.mesh().cellNumber(cell);
00572
00573 const ConformTransformation& T = *pT;
00574
00575 for (size_t k=0; k<BoundaryQuadratureType::numberOfQuadraturePoints;
00576 k++) {
00577
00578 TinyVector<3, real_t> q;
00579 boundaryT.value(referenceBoundaryQuadrature[k], q);
00580
00581 const real_t weight
00582 = referenceBoundaryQuadrature.weight(k)
00583 * face.volume();
00584
00585 TinyVector<3> coordinates;
00586 T.invertT(q, coordinates);
00587
00588 typename FiniteElement::ElementaryVector W;
00589 for (size_t l=0; l<FiniteElement::numberOfDegreesOfFreedom; l++)
00590 W[l] = finiteElement.W(l,coordinates);
00591
00592 typename FiniteElement::ElementaryMatrix WiWj;
00593
00594 for (size_t l=0; l<FiniteElement::numberOfDegreesOfFreedom; l++)
00595 for (size_t m=0; m<FiniteElement::numberOfDegreesOfFreedom; m++)
00596 WiWj(l,m) = W[l] * W[m];
00597
00598 size_t indices[FiniteElement::numberOfDegreesOfFreedom];
00599 for (size_t l=0; l<FiniteElement::numberOfDegreesOfFreedom; ++l) {
00600 indices[l] = __bc.__degreeOfFreedomSet(__equationNumber,
00601 dofPositions(cellNumber, l));
00602 }
00603
00604 for (size_t l=0; l<FiniteElement::numberOfDegreesOfFreedom; l++) {
00605 const size_t I = indices[l];
00606 if (not(__bc.__dirichletList[I])) {
00607 for (size_t m=0; m<FiniteElement::numberOfDegreesOfFreedom; m++) {
00608 const size_t J = indices[m];
00609 if (not(__bc.__dirichletList[J])) {
00610 __z[J] += WiWj(l,m) * weight * __x[I] / __bc.__epsilon;
00611 }
00612 }
00613 }
00614 }
00615 }
00616 }
00617 }
00618
00619 __TimesXDirichlet(const Dirichlet& dirichlet,
00620 const size_t equationNumber,
00621 const VectorType& x,
00622 VectorType& z,
00623 const BoundaryConditionDiscretizationPenalty<MeshType,
00624 TypeOfDiscretization>& bc)
00625 : __dirichlet(dirichlet),
00626 __equationNumber(equationNumber),
00627 __x(x),
00628 __z(z),
00629 __bc(bc)
00630 {
00631 ;
00632 }
00633
00634 __TimesXDirichlet(const __TimesXDirichlet& T)
00635 : __dirichlet(T.__dirichlet),
00636 __equationNumber(T.__equationNumber),
00637 __x(T.__x),
00638 __z(T.__z),
00639 __bc(T.__bc)
00640 {
00641 ;
00642 }
00643
00644 ~__TimesXDirichlet()
00645 {
00646 ;
00647 }
00648 };
00649
00650 template <typename VectorType>
00651 class __TransposedTimesXDirichlet
00652 {
00653 private:
00654 const Dirichlet& __dirichlet;
00655
00656 const size_t __equationNumber;
00657
00658 const VectorType& __x;
00659
00660 VectorType& __z;
00661
00662 const BoundaryConditionDiscretizationPenalty<MeshType,
00663 TypeOfDiscretization>& __bc;
00664
00665 public:
00666
00667 template <typename SurfaceMeshType>
00668 void eval(const SurfaceMeshType& surfaceMesh) const
00669 {
00670 typedef typename SurfaceMeshType::CellType BoundaryCellType;
00671
00672 typedef
00673 typename FiniteElementTraits<BoundaryCellType,
00674 TypeOfDiscretization>::Transformation
00675 BoundaryConformTransformation;
00676
00677 typedef
00678 typename FiniteElementTraits<BoundaryCellType,
00679 TypeOfDiscretization>::Type
00680 BoundaryFiniteElement;
00681
00682 typedef
00683 typename BoundaryFiniteElement::QuadratureType
00684 BoundaryQuadratureType;
00685
00686 const FiniteElement& finiteElement = FiniteElement::instance();
00687
00688 const BoundaryQuadratureType& referenceBoundaryQuadrature
00689 = BoundaryQuadratureType::instance();
00690
00691 const ScalarDegreeOfFreedomPositionsSet& dofPositions
00692 = __bc.__degreeOfFreedomSet.positionsSet(0);
00693
00694 AutoPointer<ConformTransformation> pT;
00695
00696 const CellType* lastCell = 0;
00697
00698 for (typename SurfaceMeshType::const_iterator iface(surfaceMesh);
00699 not(iface.end()); ++iface) {
00700 const typename SurfaceMeshType::CellType& face = *iface;
00701 const BoundaryConformTransformation boundaryT(face);
00702
00703 const CellType& cell
00704 = static_cast<const CellType&>(face.mother());
00705
00706 if(lastCell != &cell) {
00707 pT = new ConformTransformation(cell);
00708 lastCell = &cell;
00709 }
00710
00711 const size_t cellNumber = __bc.mesh().cellNumber(cell);
00712
00713 const ConformTransformation& T = *pT;
00714
00715 for (size_t k=0; k<BoundaryQuadratureType::numberOfQuadraturePoints;
00716 k++) {
00717
00718 TinyVector<3, real_t> q;
00719 boundaryT.value(referenceBoundaryQuadrature[k], q);
00720
00721 const real_t weight
00722 = referenceBoundaryQuadrature.weight(k)
00723 * face.volume();
00724
00725 TinyVector<3> coordinates;
00726 T.invertT(q, coordinates);
00727
00728 typename FiniteElement::ElementaryVector W;
00729 for (size_t l=0; l<FiniteElement::numberOfDegreesOfFreedom; l++)
00730 W[l] = finiteElement.W(l,coordinates);
00731
00732 typename FiniteElement::ElementaryMatrix WiWj;
00733
00734 for (size_t l=0; l<FiniteElement::numberOfDegreesOfFreedom; l++)
00735 for (size_t m=0; m<FiniteElement::numberOfDegreesOfFreedom; m++)
00736 WiWj(l,m) = W[l] * W[m];
00737
00738 size_t indices[FiniteElement::numberOfDegreesOfFreedom];
00739 for (size_t l=0; l<FiniteElement::numberOfDegreesOfFreedom; ++l) {
00740 indices[l] = __bc.__degreeOfFreedomSet(__equationNumber,
00741 dofPositions(cellNumber, l));
00742 }
00743
00744 for (size_t l=0; l<FiniteElement::numberOfDegreesOfFreedom; l++) {
00745 const size_t I = indices[l];
00746 if (not(__bc.__dirichletList[I])) {
00747 for (size_t m=0; m<FiniteElement::numberOfDegreesOfFreedom; m++) {
00748 const size_t J = indices[m];
00749 if (not(__bc.__dirichletList[J])) {
00750 __z[I] += WiWj(l,m) * weight * __x[J] / __bc.__epsilon;
00751 }
00752 }
00753 }
00754 }
00755 }
00756 }
00757 }
00758
00759 __TransposedTimesXDirichlet(const Dirichlet& dirichlet,
00760 const size_t equationNumber,
00761 const VectorType& x,
00762 VectorType& z,
00763 const BoundaryConditionDiscretizationPenalty<MeshType,
00764 TypeOfDiscretization>& bc)
00765 : __dirichlet(dirichlet),
00766 __equationNumber(equationNumber),
00767 __x(x),
00768 __z(z),
00769 __bc(bc)
00770 {
00771 ;
00772 }
00773
00774 __TransposedTimesXDirichlet(const __TransposedTimesXDirichlet& T)
00775 : __dirichlet(T.__dirichlet),
00776 __equationNumber(T.__equationNumber),
00777 __x(T.__x),
00778 __z(T.__z),
00779 __bc(T.__bc)
00780 {
00781 ;
00782 }
00783
00784 ~__TransposedTimesXDirichlet()
00785 {
00786 ;
00787 }
00788 };
00789
00790 template <typename VectorType>
00791 class __SetSecondMemberDirichlet
00792 {
00793 private:
00794 const Dirichlet& __dirichlet;
00795
00796 const size_t __equationNumber;
00797
00798 VectorType& __b;
00799
00800 const BoundaryConditionDiscretizationPenalty<MeshType,
00801 TypeOfDiscretization>& __bc;
00802
00803 public:
00804
00805 template <typename SurfaceMeshType>
00806 void eval(const SurfaceMeshType& surfaceMesh) const
00807 {
00808 typedef typename SurfaceMeshType::CellType BoundaryCellType;
00809
00810 typedef
00811 typename FiniteElementTraits<BoundaryCellType,
00812 TypeOfDiscretization>::Transformation
00813 BoundaryConformTransformation;
00814
00815 typedef
00816 typename FiniteElementTraits<BoundaryCellType,
00817 TypeOfDiscretization>::Type
00818 BoundaryFiniteElement;
00819
00820 typedef
00821 typename BoundaryFiniteElement::QuadratureType
00822 BoundaryQuadratureType;
00823
00824 const FiniteElement& finiteElement = FiniteElement::instance();
00825
00826 const BoundaryQuadratureType& referenceBoundaryQuadrature
00827 = BoundaryQuadratureType::instance();
00828
00829 const ScalarDegreeOfFreedomPositionsSet& dofPositions
00830 = __bc.__degreeOfFreedomSet.positionsSet(0);
00831
00832 AutoPointer<ConformTransformation> pT;
00833
00834 const CellType* lastCell = 0;
00835
00836 for (typename SurfaceMeshType::const_iterator iface(surfaceMesh);
00837 not(iface.end()); ++iface) {
00838 const typename SurfaceMeshType::CellType& face = *iface;
00839 const BoundaryConformTransformation boundaryT(face);
00840
00841 const CellType& cell
00842 = static_cast<const CellType&>(face.mother());
00843
00844 if(lastCell != &cell) {
00845 pT = new ConformTransformation(cell);
00846 lastCell = &cell;
00847 }
00848
00849 const ConformTransformation T = *pT;
00850
00851 const size_t cellNumber = __bc.mesh().cellNumber(cell);
00852
00853 for (size_t k=0; k<BoundaryQuadratureType::numberOfQuadraturePoints;
00854 k++) {
00855
00856 TinyVector<3, real_t> q;
00857 boundaryT.value(referenceBoundaryQuadrature[k], q);
00858
00859 const real_t weight
00860 = referenceBoundaryQuadrature.weight(k)
00861 * face.volume();
00862
00863 TinyVector<3> coordinates;
00864 T.invertT(q, coordinates);
00865
00866 const real_t GValue = __dirichlet.g(q);
00867
00868 typename FiniteElement::ElementaryVector W;
00869 for (size_t l=0; l<FiniteElement::numberOfDegreesOfFreedom; l++)
00870 W[l] = finiteElement.W(l,coordinates);
00871
00872 size_t indices[FiniteElement::numberOfDegreesOfFreedom];
00873 for (size_t l=0; l<FiniteElement::numberOfDegreesOfFreedom; ++l) {
00874 indices[l] = dofPositions(cellNumber, l);
00875 }
00876
00877 for (size_t l=0; l<FiniteElement::numberOfDegreesOfFreedom; l++) {
00878 const size_t I = __bc.__degreeOfFreedomSet(__equationNumber,
00879 indices[l]);
00880
00881 __b[I] += W[l] * weight * GValue / __bc.__epsilon;
00882 }
00883 }
00884 }
00885 }
00886
00887 __SetSecondMemberDirichlet(const Dirichlet& dirichlet,
00888 const size_t equationNumber,
00889 VectorType& b,
00890 const BoundaryConditionDiscretizationPenalty<MeshType,
00891 TypeOfDiscretization>& bc)
00892 : __dirichlet(dirichlet),
00893 __equationNumber(equationNumber),
00894 __b(b),
00895 __bc(bc)
00896 {
00897 ;
00898 }
00899
00900 __SetSecondMemberDirichlet(const __SetSecondMemberDirichlet& S)
00901 : __dirichlet(S.__dirichlet),
00902 __equationNumber(S.__equationNumber),
00903 __b(S.__b),
00904 __bc(S.__bc)
00905 {
00906 ;
00907 }
00908
00909 ~__SetSecondMemberDirichlet()
00910 {
00911 ;
00912 }
00913 };
00914
00915 };
00916
00917 #endif // BOUNDARY_CONDITION_DISCRETIZATION_PENALTY_HPP
00918