1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #ifndef __PolyhedronIntersectorP1P0Bary_TXX__
20 #define __PolyhedronIntersectorP1P0Bary_TXX__
22 #include "PolyhedronIntersectorP1P0Bary.hxx"
23 #include "Intersector3DP1P0Bary.txx"
24 #include "MeshUtils.hxx"
26 #include "SplitterTetra.txx"
28 namespace INTERP_KERNEL
32 * Constructor creating object from target cell global number
33 * The constructor first calculates the necessary nodes,
34 * (depending on the splitting policy) and then splits the hexahedron into
35 * tetrahedra, placing these in the internal vector _tetra.
37 * @param targetMesh mesh containing the target elements
38 * @param srcMesh mesh containing the source elements
39 * @param policy splitting policy to be used
41 * WARNING : in _split attribute, sourceMesh and targetMesh are switched in order to fit intersectCells feature.
43 template<class MyMeshType, class MyMatrix>
44 PolyhedronIntersectorP1P0Bary<MyMeshType,MyMatrix>::PolyhedronIntersectorP1P0Bary(const MyMeshType& targetMesh,
45 const MyMeshType& srcMesh,
46 SplittingPolicy policy)
47 :Intersector3DP1P0Bary<MyMeshType,MyMatrix>(targetMesh,srcMesh),_split(targetMesh,srcMesh,policy)
50 // "Limitation. For the P1P0 barycentric improvement only triangle source cells in 2D and
51 // tetrahedrons in 3D will be supported by interpolators. If a non
52 // triangle/tetrahedron source cell is detected an INTERP_KERNEL::Exception should be thrown."
54 // Check types of source elements here rather than in intersectCells() since a wrong type can be
55 // found late after a long time of calculation.
57 const unsigned long numSrcElems = srcMesh.getNumberOfElements();
58 for(unsigned long i = 0 ; i < numSrcElems ; ++i)
59 if ( srcMesh.getTypeOfElement( OTT<ConnType,numPol>::indFC(i) ) != NORM_TETRA4 )
60 throw INTERP_KERNEL::Exception("P1P0 barycentric algorithm works only with tetrahedral source meshes");
65 * Liberates the SplitterTetra objects and potential sub-node points that have been allocated.
68 template<class MyMeshType, class MyMatrix>
69 PolyhedronIntersectorP1P0Bary<MyMeshType,MyMatrix>::~PolyhedronIntersectorP1P0Bary()
74 template<class MyMeshType, class MyMatrix>
75 void PolyhedronIntersectorP1P0Bary<MyMeshType,MyMatrix>::releaseArrays()
77 for(typename std::vector< SplitterTetra<MyMeshType>* >::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter)
79 _split.releaseArrays();
83 //================================================================================
85 * \brief This method computes a value per each node of source cell for each target cell.
86 * \param srcCell - a source tetrahedron
87 * \param tgtCells - target elements
88 * \param res - matrix to fill in
90 //================================================================================
92 template<class MyMeshType, class MyMatrix>
93 void PolyhedronIntersectorP1P0Bary<MyMeshType,MyMatrix>::intersectCells(ConnType tgtCell,
94 const std::vector<ConnType>& srcCells,
97 typename MyMatrix::value_type& resRow=res[tgtCell];
99 int nbOfNodesT=Intersector3D<MyMeshType,MyMatrix>::_target_mesh.getNumberOfNodesOfElement(OTT<ConnType,numPol>::indFC(tgtCell));
101 _split.splitTargetCell(tgtCell,nbOfNodesT,_tetra);
103 for(typename std::vector<ConnType>::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++)
105 // intersect a source tetrahedron with each target tetrahedron: get intersection volume and barycenter
106 double baryCentre[SPACEDIM], total_baryCentre[3] = { 0., 0., 0.};
107 double interVolume = 0;
108 for(typename std::vector<SplitterTetra<MyMeshType>*>::iterator iterTetraT = _tetra.begin(); iterTetraT != _tetra.end(); ++iterTetraT)
110 SplitterTetra<MyMeshType> *tmp=*iterTetraT;
111 tmp->clearVolumesCache();
112 double volume = tmp->intersectSourceCell(*iterCellS, baryCentre);
115 interVolume += volume;
116 for ( int i = 0; i < SPACEDIM; ++i )
117 total_baryCentre[i] += baryCentre[i]*volume;
122 for ( int i = 0; i < SPACEDIM; ++i )
123 total_baryCentre[i] /= interVolume;
125 // coordinates of the source tetrahedron
126 std::vector<const double*> srcCellCoords(4);
127 for ( int n = 0; n < 4; ++n )
128 srcCellCoords[ n ] = getCoordsOfNode( n, *iterCellS, Intersector3D<MyMeshType,MyMatrix>::_src_mesh );
130 // compute barycentric coordinates
131 double baryCoords[4];
132 barycentric_coords( srcCellCoords, total_baryCentre, baryCoords);
134 // store coeffs of each node of the source tetrahedron
135 const ConnType *srcCellNodes=Intersector3D<MyMeshType,MyMatrix>::_src_mesh.getConnectivityPtr()+OTT<ConnType,numPol>::conn2C(Intersector3D<MyMeshType,MyMatrix>::_src_mesh.getConnectivityIndexPtr()[*iterCellS]);
136 for ( int n = 0; n < 4; ++n )
138 double val = baryCoords[n] * interVolume;
139 ConnType curNodeS = srcCellNodes[n];
140 typename MyMatrix::value_type::const_iterator iterRes=resRow.find(curNodeS);
141 if(iterRes!=resRow.end())
143 val += iterRes->second;
144 resRow.erase( curNodeS );
146 resRow.insert(std::make_pair(curNodeS,val));