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_ELIMINATION_HPP
00022 #define BOUNDARY_CONDITION_DISCRETIZATION_ELIMINATION_HPP
00023
00024 #include <BoundaryConditionFDMDiscretization.hpp>
00025 #include <UnAssembledMatrix.hpp>
00026
00027 template<typename MeshType,
00028 ScalarDiscretizationTypeBase::Type TypeOfDiscretization>
00029 class BoundaryConditionDiscretizationElimination
00030 : public BoundaryConditionFDMDiscretization<MeshType,
00031 TypeOfDiscretization>
00032 {
00033 public:
00035 typedef typename MeshType::CellType CellType;
00036
00038 typedef typename FiniteElementTraits<CellType,
00039 TypeOfDiscretization>::Type FiniteElement;
00040
00041 private:
00042 class __SetSecondMemberDirichlet
00043 {
00044 private:
00045 const Dirichlet& __dirichlet;
00046
00047 const size_t __equationNumber;
00048
00049 const BoundaryConditionDiscretizationElimination<MeshType,
00050 TypeOfDiscretization>& __bc;
00051
00052 public:
00053
00054 template <typename SurfaceMeshType>
00055 void eval(const SurfaceMeshType& surfMesh) const
00056 {
00057 typedef typename SurfaceMeshType::CellType BoundaryCellType;
00058
00059 typedef
00060 typename FiniteElementTraits<BoundaryCellType,
00061 TypeOfDiscretization>::Transformation
00062 BoundaryConformTransformation;
00063
00064 typedef
00065 typename FiniteElementTraits<BoundaryCellType,
00066 TypeOfDiscretization>::Type
00067 BoundaryFiniteElement;
00068
00069 typedef
00070 typename BoundaryFiniteElement::QuadratureType
00071 BoundaryQuadratureType;
00072
00073 const BoundaryQuadratureType& referenceBoundaryQuadrature
00074 = BoundaryQuadratureType::instance();
00075
00076 fferr(1) << __FILE__ << ":" << __LINE__
00077 << "\n########################################################\n"
00078 << "Implementation not finished! use of dofPosition required\n"
00079 << "########################################################\n";
00080
00081 for (typename SurfaceMeshType::const_iterator icell(surfMesh);
00082 not(icell.end()); ++icell) {
00083 const BoundaryCellType& cell = *icell;
00084
00085 const BoundaryConformTransformation boundaryT(cell);
00086
00087 for (size_t k=0; k<BoundaryQuadratureType::numberOfQuadraturePoints;
00088 k++) {
00089
00090 TinyVector<3, real_t> q;
00091 boundaryT.value(referenceBoundaryQuadrature[k], q);
00092
00093
00094 #warning Use of Index is not necessary
00095 const Index& iv = __bc.mesh().vertexIndex(q);
00096 const Vertex& V = __bc.mesh().vertex(iv);
00097
00098 const real_t GValue = __dirichlet.g(V);
00099
00100 const size_t I = __bc.__degreeOfFreedomSet(__equationNumber,
00101 __bc.mesh().vertexNumber(V));
00102 __bc.__dirichletValues[I] = GValue;
00103 __bc.__dirichletList[I] = true;
00104 }
00105 }
00106 }
00107
00108 __SetSecondMemberDirichlet(const Dirichlet &D ,
00109 const size_t equationNumber,
00110 const BoundaryConditionDiscretizationElimination<MeshType,
00111 TypeOfDiscretization>& bc)
00112 : __dirichlet(D),
00113 __equationNumber(equationNumber),
00114 __bc(bc)
00115 {
00116 ;
00117 }
00118
00119 __SetSecondMemberDirichlet(const __SetSecondMemberDirichlet& s)
00120 : __dirichlet(s.__dirichlet),
00121 __equationNumber(s.__equationNumber),
00122 __bc(s.__bc)
00123 {
00124 ;
00125 }
00126
00127 ~__SetSecondMemberDirichlet()
00128 {
00129 ;
00130 }
00131 };
00132
00133
00134 template <typename MatrixType,
00135 typename VectorType>
00136 static void
00137 __DirichletBorderLinearOperator(const BoundaryConditionDiscretizationElimination<MeshType,
00138 TypeOfDiscretization>& bc,
00139 MatrixType& A,
00140 VectorType& b)
00141 {
00142 bc.__dirichletValues.resize(bc.__degreeOfFreedomSet.size());
00143 bc.__dirichletValues = 0;
00144 const BoundaryConditionSurfaceMeshAssociation& bcMeshAssociation = *bc.__bcMeshAssociation;
00145
00146
00147 for (size_t i=0; i<bc.problem().numberOfUnknown(); ++i) {
00148 for (BoundaryConditionSurfaceMeshAssociation
00149 ::DirichletMeshAssociation
00150 ::const_iterator ibcMesh = bcMeshAssociation.bc(i).begin();
00151 ibcMesh != bcMeshAssociation.bc(i).end();
00152 ++ibcMesh) {
00153 const Dirichlet& D = *ibcMesh->first;
00154 const SurfaceMesh& surfMesh = *ibcMesh->second;
00155
00156 BoundaryConditionDiscretizationElimination<MeshType,
00157 TypeOfDiscretization>
00158 ::__meshWrapper(surfMesh,
00159 typename BoundaryConditionDiscretizationElimination<MeshType,
00160 TypeOfDiscretization>
00161 ::__SetSecondMemberDirichlet(D, i, bc));
00162 }
00163 }
00164
00166 Vector<bool> temp = bc.__dirichletList;
00167 bc.__dirichletList = false;
00168 Vector<real_t> y (bc.__dirichletValues.size());
00169 A.timesX(bc.__dirichletValues,y);
00170 b -= y;
00171 bc.__dirichletList = temp;
00172
00173 for (size_t i=0; i<b.size(); ++i) {
00174 if (bc.__dirichletList[i]) {
00175 b[i] = bc.__dirichletValues[i];
00176 }
00177 }
00178 }
00179
00180 public:
00181 void getDiagonal (BaseVector& Z) const
00182 {
00183 Vector<real_t>& z = dynamic_cast<Vector<real_t>&>(Z);
00184
00185
00186 BoundaryConditionFDMDiscretization<MeshType,TypeOfDiscretization>
00187 ::__StandardGetDiagonalVariationalBorderBilinearOperator(*this, z);
00188
00189 BoundaryConditionFDMDiscretization<MeshType,TypeOfDiscretization>
00190 ::__StandardGetDiagonalDirichletBorderBilinearOperator(*this, z);
00191 }
00192
00193 void setMatrix (ReferenceCounting<BaseMatrix> givenA,
00194 ReferenceCounting<BaseVector> b) const
00195 {
00196 switch(givenA->type()) {
00197 case BaseMatrix::doubleHashedMatrix: {
00198
00199 DoubleHashedMatrix& A = dynamic_cast<DoubleHashedMatrix&>(*givenA);
00200
00201
00202 BoundaryConditionFDMDiscretization<MeshType,TypeOfDiscretization>
00203 ::__StandardVariationalBorderBilinearOperator(*this, A);
00204
00205
00206 BoundaryConditionFDMDiscretization<MeshType,TypeOfDiscretization>
00207 ::__StandardDirichletBorderBilinearOperator(*this, A);
00208 break;
00209 }
00210 case BaseMatrix::unAssembled: {
00211 UnAssembledMatrix& A = dynamic_cast<UnAssembledMatrix&>(*givenA);
00212 A.setBoundaryConditions(this);
00213 break;
00214 }
00215 default: {
00216 throw ErrorHandler(__FILE__,__LINE__,
00217 "unexpected matrix type",
00218 ErrorHandler::unexpected);
00219 }
00220 }
00221 }
00222
00223 void setSecondMember (ReferenceCounting<BaseMatrix> givenA,
00224 ReferenceCounting<BaseVector> givenB) const
00225 {
00226 Vector<real_t>& b = dynamic_cast<Vector<real_t>&>(*givenB);
00227 BaseMatrix& A = *givenA;
00228
00230 BoundaryConditionFDMDiscretization<MeshType,TypeOfDiscretization>::
00231 __StandardVariationalBorderLinearOperator(*this, b);
00232
00234 BoundaryConditionDiscretizationElimination<MeshType,TypeOfDiscretization>::
00235 __DirichletBorderLinearOperator(*this, A, b);
00236 }
00237
00238 void timesX(const BaseVector& X, BaseVector& Z) const
00239 {
00240 const Vector<real_t>& x = dynamic_cast<const Vector<real_t>&>(X);
00241 Vector<real_t>& z = dynamic_cast<Vector<real_t>&>(Z);
00242
00243
00244 BoundaryConditionFDMDiscretization<MeshType,TypeOfDiscretization>::
00245 __StandardVariationalBorderBilinearOperatorTimesX(*this,
00246 x, z);
00247
00248
00249 BoundaryConditionFDMDiscretization<MeshType,TypeOfDiscretization>::
00250 __StandardDirichletBorderBilinearOperatorTimesX(*this,
00251 x, z);
00252 }
00253
00254 void transposedTimesX(const BaseVector& X, BaseVector& Z) const
00255 {
00256 const Vector<real_t>& x = dynamic_cast<const Vector<real_t>&>(X);
00257 Vector<real_t>& z = dynamic_cast<Vector<real_t>&>(Z);
00258
00259
00260 BoundaryConditionFDMDiscretization<MeshType,TypeOfDiscretization>::
00261 __StandardVariationalBorderBilinearOperatorTransposedTimesX(*this,
00262 x, z);
00263
00264
00265 BoundaryConditionFDMDiscretization<MeshType,TypeOfDiscretization>::
00266 __StandardDirichletBorderBilinearOperatorTransposedTimesX(*this,
00267 x, z);
00268 }
00269
00270 BoundaryConditionDiscretizationElimination(const Problem& problem,
00271 const MeshType& mesh,
00272 const DegreeOfFreedomSet& dof)
00273 : BoundaryConditionFDMDiscretization<MeshType,
00274 TypeOfDiscretization>(problem, mesh, dof)
00275 {
00276 ;
00277 }
00278
00279 ~BoundaryConditionDiscretizationElimination()
00280 {
00281 ;
00282 }
00283 };
00284
00285 #endif // BOUNDARY_CONDITION_DISCRETIZATION_ELIMINATION_HPP
00286