X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FINTERP_KERNEL%2FPolyhedronIntersectorP1P0.txx;h=57c93bf155705c4ad1d4850f9b39114adf2604e8;hb=b832b15337be013a56e0976170e5e235b89fcb03;hp=441f53f166b029aedc7292476f0408d5d8cf4ffe;hpb=5da72d398d0eb1820c3ce6dd90b8579b6b14edf5;p=tools%2Fmedcoupling.git diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.txx b/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.txx index 441f53f16..57c93bf15 100644 --- a/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.txx +++ b/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D +// Copyright (C) 2007-2024 CEA, EDF // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -66,6 +66,23 @@ namespace INTERP_KERNEL _tetra.clear(); } + template + void AddContributionInRow(RowType& row, ConnType colId, double value) + { + if(value != 0.) + { + typename RowType::const_iterator iterRes=row.find(colId); + if(iterRes==row.end()) + row.insert(std::make_pair(colId,value)); + else + { + double val=(*iterRes).second+value; + row.erase(colId); + row.insert(std::make_pair(colId,val)); + } + } + } + /** * Calculates the volume of intersection of an element in the source mesh and the target element * represented by the object. @@ -80,37 +97,52 @@ namespace INTERP_KERNEL template void PolyhedronIntersectorP1P0::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) { - SplitterTetra* subTetras[24]; typename MyMatrix::value_type& resRow=res[targetCell]; + INTERP_KERNEL::SplittingPolicy sp( _split.getSplittingPolicy() ); + if( sp == GENERAL_48 ) + THROW_IK_EXCEPTION("GENERAL_28 spliting is not supported for P1P0 interpolation"); + SplitterTetra* subTetras[24]; for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) + { + releaseArrays(); + ConnType nbOfNodesS=this->_src_mesh.getNumberOfNodesOfElement(OTT::indFC(*iterCellS)); + _split.splitTargetCell(*iterCellS,nbOfNodesS,_tetra); + INTERP_KERNEL::NormalizedCellType srcType = this->_src_mesh.getTypeOfElement( OTT::indFC(*iterCellS) ); + if( srcType == NORM_TETRA4 || (srcType == NORM_HEXA8 && sp != GENERAL_24 )) { - releaseArrays(); - int nbOfNodesS=Intersector3D::_src_mesh.getNumberOfNodesOfElement(OTT::indFC(*iterCellS)); - _split.splitTargetCell(*iterCellS,nbOfNodesS,_tetra); - for(typename std::vector*>::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) + for(typename std::vector*>::const_iterator iter = _tetra.cbegin(); iter != _tetra.cend(); ++iter) { (*iter)->splitIntoDualCells(subTetras); + double vol2 = 0.; for(int i=0;i<24;i++) { SplitterTetra *tmp=subTetras[i]; double volume = tmp->intersectSourceCell(targetCell); + vol2 += volume; ConnType sourceNode=tmp->getId(0); - if(volume!=0.) - { - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(sourceNode)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(sourceNode),volume)); - else - { - double val=(*iterRes).second+volume; - resRow.erase(OTT::indFC(sourceNode)); - resRow.insert(std::make_pair(OTT::indFC(sourceNode),val)); - } - } + AddContributionInRow(resRow,OTT::indFC(sourceNode),volume); delete tmp; } } } + else + {// for HEXA and GENERAL_24 no need to use subsplitting into dual mesh + for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) + { + releaseArrays(); + ConnType nbOfNodesS=Intersector3D::_src_mesh.getNumberOfNodesOfElement(OTT::indFC(*iterCellS)); + _split.splitTargetCell2(*iterCellS,_tetra); + for(typename std::vector*>::const_iterator iter = _tetra.cbegin(); iter != _tetra.cend(); ++iter) + { + double volume = std::abs( (*iter)->intersectSourceCell(targetCell) ); + // node #0 is for internal node node #1 is for the node at the middle of the face + ConnType sourceNode0( (*iter)->getId(0) ), sourceNode1( (*iter)->getId(1) ); + AddContributionInRow(resRow,OTT::indFC(sourceNode0),volume/2.); + AddContributionInRow(resRow,OTT::indFC(sourceNode1),volume/2.); + } + } + } + } } }