00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef BOUNDARY_MESH_ASSOCIATION_HPP
00021 #define BOUNDARY_MESH_ASSOCIATION_HPP
00022
00023 #include <map>
00024 #include <ReferenceCounting.hpp>
00025
00026 #include <Problem.hpp>
00027 #include <Boundary.hpp>
00028
00029 #include <BoundarySurfaceMesh.hpp>
00030 #include <BoundaryReferences.hpp>
00031 #include <BoundaryPOVRay.hpp>
00032
00033 #include <BoundaryConditionSet.hpp>
00034 #include <BoundaryMeshAssociation.hpp>
00035
00036 #include <SurfaceMesh.hpp>
00037 #include <SurfaceMeshOfTriangles.hpp>
00038 #include <SurfaceMeshOfQuadrangles.hpp>
00039
00040 #include <MeshExtractor.hpp>
00041
00042 #include <PDESystem.hpp>
00043 #include <VariationalProblem.hpp>
00044
00045 #include <Stringify.hpp>
00046 #include <ErrorHandler.hpp>
00047
00058 class BoundaryMeshAssociation
00059 {
00060 private:
00061 bool __hasPOVReference;
00063 typedef std::map<const Boundary*, ConstReferenceCounting<SurfaceMesh> >
00064 MapBoundaryToMesh;
00065
00066 MapBoundaryToMesh __boundaryMesh;
00076 template <typename MeshType>
00077 void __storesBoundariesAndMeshes(const BoundaryConditionSet& bc,
00078 const MeshType& M)
00079 {
00080 for (size_t i=0; i<bc.nbBoundaryCondition(); ++i) {
00081 if (__boundaryMesh.find(bc[i].boundary())
00082 == __boundaryMesh.end()) {
00083 switch(bc[i].boundary()->type()) {
00084 case Boundary::povRay: {
00085 __boundaryMesh[bc[i].boundary()] = 0;
00086 __hasPOVReference = true;
00087 break;
00088 }
00089 case Boundary::surfaceMesh: {
00090 const BoundarySurfaceMesh& b
00091 = dynamic_cast<const BoundarySurfaceMesh&>(*bc[i].boundary());
00092 const SurfaceMesh* t = b.surfaceMesh();
00093 __boundaryMesh[bc[i].boundary()] = t;
00094 break;
00095 }
00096 case Boundary::references: {
00097 const BoundaryReferences& b
00098 = dynamic_cast<const BoundaryReferences&>(*bc[i].boundary());
00099
00100 MeshExtractor<typename MeshType::BorderMeshType>
00101 extractor(M.borderMesh());
00102
00103 __boundaryMesh[bc[i].boundary()]
00104 = extractor(b.references());
00105 break;
00106 }
00107 default: {
00108 throw ErrorHandler(__FILE__,__LINE__,
00109 "unknown boundary type",
00110 ErrorHandler::unexpected);
00111 }
00112 }
00113 }
00114 }
00115 }
00116
00124 template <typename MeshType>
00125 void __storesBoundariesAndMeshes(const VariationalBorderOperator& borderOperator,
00126 const MeshType& M)
00127 {
00128 if (__boundaryMesh.find(borderOperator.boundary())
00129 == __boundaryMesh.end()) {
00130 switch(borderOperator.boundary()->type()) {
00131 case Boundary::povRay: {
00132 __boundaryMesh[borderOperator.boundary()] = 0;
00133 __hasPOVReference = true;
00134 break;
00135 }
00136 case Boundary::surfaceMesh: {
00137 const BoundarySurfaceMesh& b
00138 = dynamic_cast<const BoundarySurfaceMesh&>(*borderOperator.boundary());
00139 const SurfaceMesh* t = b.surfaceMesh();
00140 __boundaryMesh[borderOperator.boundary()] = t;
00141 break;
00142 }
00143 case Boundary::references: {
00144 const BoundaryReferences& b
00145 = dynamic_cast<const BoundaryReferences&>(*borderOperator.boundary());
00146
00147 MeshExtractor<typename MeshType::BorderMeshType>
00148 extractor(M.borderMesh());
00149
00150 __boundaryMesh[borderOperator.boundary()]
00151 = extractor(b.references());
00152 break;
00153 }
00154 default: {
00155 throw ErrorHandler(__FILE__,__LINE__,
00156 "unknown boundary type",
00157 ErrorHandler::unexpected);
00158 }
00159 }
00160 }
00161 }
00162
00163 public:
00164 typedef MapBoundaryToMesh::const_iterator const_iterator;
00165
00171 const_iterator begin() const
00172 {
00173 return __boundaryMesh.begin();
00174 }
00175
00181 const_iterator end() const
00182 {
00183 return __boundaryMesh.end();
00184 }
00185
00191 const bool& hasPOVReferences() const
00192 {
00193 return __hasPOVReference;
00194 }
00195
00202 void setPOVMeshes(const Domain& omega,
00203 ConstReferenceCounting<SurfaceMeshOfTriangles> mesh)
00204 {
00205 for (MapBoundaryToMesh::iterator i = __boundaryMesh.begin();
00206 i != __boundaryMesh.end(); ++i) {
00207 const Boundary& b = (*(i->first));
00208 if (b.type() == Boundary::povRay) {
00209 ASSERT(i->second == 0);
00210 const BoundaryPOVRay& pov = dynamic_cast<const BoundaryPOVRay&>(b);
00211 std::set<size_t> references;
00212 for (size_t n=0; n<pov.numberOfPOVReferences(); ++n) {
00213 references.insert(omega.reference(pov.povReference(n)));
00214 }
00215 MeshExtractor<SurfaceMeshOfTriangles> extractor(mesh);
00216 __boundaryMesh[i->first] = extractor(references);
00217 }
00218 }
00219 }
00220
00228 ConstReferenceCounting<SurfaceMesh> operator[](const Boundary& b) const
00229 {
00230 MapBoundaryToMesh::const_iterator i = __boundaryMesh.find(&b);
00231 if (i != __boundaryMesh.end()) {
00232 return i->second;
00233 } else {
00234 const std::string errorMsg
00235 = "the boundary "+stringify(b)+" was unexpected\n";
00236 throw ErrorHandler(__FILE__,__LINE__,
00237 errorMsg,
00238 ErrorHandler::normal);
00239 }
00240 }
00241
00248 template <typename MeshType>
00249 BoundaryMeshAssociation(const Problem& P,
00250 MeshType& M)
00251 : __hasPOVReference(false)
00252 {
00253 switch (P.type()) {
00254 case Problem::pde: {
00255 const PDESystem& system = static_cast<const PDESystem&>(P);
00256 for (size_t i=0; i<system.numberOfUnknown(); ++i) {
00257 this->__storesBoundariesAndMeshes(P.boundaryConditionSet(i), M);
00258 }
00259 break;
00260 }
00261 case Problem::variational: {
00262 const VariationalProblem& V = static_cast<const VariationalProblem&>(P);
00263 for (size_t i=0; i<V.numberOfUnknown(); ++i) {
00264 this->__storesBoundariesAndMeshes(P.boundaryConditionSet(i), M);
00265 }
00266 for (VariationalProblem::bilinearBorderOperatorConst_iterator i
00267 = V.beginBilinearBorderOperator();
00268 i != V.endBilinearBorderOperator(); ++i) {
00269 this->__storesBoundariesAndMeshes(**i, M);
00270 }
00271 for (VariationalProblem::linearBorderOperatorConst_iterator i
00272 = V.beginLinearBorderOperator();
00273 i != V.endLinearBorderOperator(); ++i) {
00274 this->__storesBoundariesAndMeshes(**i, M);
00275 }
00276 break;
00277 }
00278 }
00279 }
00280
00285 ~BoundaryMeshAssociation()
00286 {
00287 ;
00288 }
00289 };
00290
00291 #endif // BOUNDARY_MESH_ASSOCIATION_HPP