1 // Copyright (C) 2007-2015 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, or (at your option) any later version.
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 // Author : Anthony Geay (EDF R&D)
21 #include "DiameterCalculator.hxx"
22 #include "InterpKernelException.hxx"
23 #include "CellModel.hxx"
29 using namespace INTERP_KERNEL;
31 NormalizedCellType DiameterCalulatorTRI3S2::TYPE=NORM_TRI3;
33 NormalizedCellType DiameterCalulatorTRI3S3::TYPE=NORM_TRI3;
35 NormalizedCellType DiameterCalulatorQUAD4S2::TYPE=NORM_QUAD4;
37 NormalizedCellType DiameterCalulatorQUAD4S3::TYPE=NORM_QUAD4;
39 NormalizedCellType DiameterCalulatorTETRA4::TYPE=NORM_TETRA4;
41 NormalizedCellType DiameterCalulatorHEXA8::TYPE=NORM_HEXA8;
43 NormalizedCellType DiameterCalulatorPENTA6::TYPE=NORM_PENTA6;
45 NormalizedCellType DiameterCalulatorPYRA5::TYPE=NORM_PYRA5;
47 inline double SqNormV2(const double tab[2])
49 return tab[0]*tab[0]+tab[1]*tab[1];
52 inline void DiffV2(const double a[2], const double b[2], double c[2])
58 inline double SqNormV3(const double tab[3])
60 return tab[0]*tab[0]+tab[1]*tab[1]+tab[2]*tab[2];
63 inline void DiffV3(const double a[3], const double b[3], double c[3])
70 template<class Evaluator>
71 void ComputeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr)
74 NormalizedCellType ct(Evaluator::TYPE);
76 for(const int *it=bgIds;it!=endIds;it++)
78 int offset(indPtr[*it]);
79 if(connPtr[offset]==cti)
80 resPtr[*it]=evtor.computeForOneCellInternal(connPtr+offset+1,connPtr+indPtr[(*it)+1],coordsPtr);
83 std::ostringstream oss; oss << "DiameterCalculator::computeForListOfCellIdsUMeshFrmt : invalid nodal connectivity format at cell # " << *it << " !";
84 throw Exception(oss.str().c_str());
89 template<class Evaluator>
90 void ComputeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr)
93 NormalizedCellType ct(Evaluator::TYPE);
95 for(int it=bgId;it<endId;it++)
97 int offset(indPtr[it]);
98 if(connPtr[offset]==cti)
99 resPtr[it]=evtor.computeForOneCellInternal(connPtr+offset+1,connPtr+indPtr[it+1],coordsPtr);
102 std::ostringstream oss; oss << "DiameterCalculator::computeForListOfCellIdsUMeshFrmt : invalid nodal connectivity format at cell # " << it << " !";
103 throw Exception(oss.str().c_str());
108 template<class Evaluator>
109 void ComputeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr)
112 NormalizedCellType ct(Evaluator::TYPE);
113 const CellModel& cm(CellModel::GetCellModel(ct));
114 unsigned nbNodes(cm.getNumberOfNodes());
115 const int *ptr(connPtr);
116 for(int i=0;i<nbOfCells;i++,ptr+=nbNodes,resPtr++)
117 *resPtr=evtor.computeForOneCellInternal(ptr,ptr+nbNodes,coordsPtr);
120 double DiameterCalulatorTRI3S2::computeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) const
122 if(std::distance(bg,endd)==3)
124 const double *a(coordsPtr+2*bg[0]),*b(coordsPtr+2*bg[1]),*c(coordsPtr+2*bg[2]);
125 double l0[2],l1[2],l2[2];
129 double res(std::max(SqNormV2(l0),SqNormV2(l1)));
130 res=std::max(res,SqNormV2(l2));
131 return std::sqrt(res);
134 throw Exception("DiameterCalulatorTRI3S2::computeForOneCellInternal : input connectivity must be of size 3 !");
137 void DiameterCalulatorTRI3S2::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const
139 ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorTRI3S2>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr);
142 void DiameterCalulatorTRI3S2::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const
144 ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorTRI3S2>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr);
147 void DiameterCalulatorTRI3S2::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const
149 ComputeFor1SGTUMeshFrmt<DiameterCalulatorTRI3S2>(nbOfCells,connPtr,coordsPtr,resPtr);
152 double DiameterCalulatorTRI3S3::computeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) const
154 if(std::distance(bg,endd)==3)
156 const double *a(coordsPtr+3*bg[0]),*b(coordsPtr+3*bg[1]),*c(coordsPtr+3*bg[2]);
157 double l0[3],l1[3],l2[3];
161 double res(std::max(SqNormV3(l0),SqNormV3(l1)));
162 res=std::max(res,SqNormV3(l2));
163 return std::sqrt(res);
166 throw Exception("DiameterCalulatorTRI3S2::computeForOneCellInternal : input connectivity must be of size 3 !");
169 void DiameterCalulatorTRI3S3::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const
171 ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorTRI3S3>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr);
174 void DiameterCalulatorTRI3S3::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const
176 ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorTRI3S3>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr);
179 void DiameterCalulatorTRI3S3::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const
181 ComputeFor1SGTUMeshFrmt<DiameterCalulatorTRI3S3>(nbOfCells,connPtr,coordsPtr,resPtr);
184 double DiameterCalulatorQUAD4S2::computeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) const
186 if(std::distance(bg,endd)==4)
188 const double *a(coordsPtr+2*bg[0]),*b(coordsPtr+2*bg[1]),*c(coordsPtr+2*bg[2]),*d(coordsPtr+2*bg[3]);
192 return std::sqrt(std::max(SqNormV2(l0),SqNormV2(l1)));
195 throw Exception("DiameterCalulatorQUAD4S2::computeForOneCellInternal : input connectivity must be of size 4 !");
198 void DiameterCalulatorQUAD4S2::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const
200 ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorQUAD4S2>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr);
203 void DiameterCalulatorQUAD4S2::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const
205 ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorQUAD4S2>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr);
208 void DiameterCalulatorQUAD4S2::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const
210 ComputeFor1SGTUMeshFrmt<DiameterCalulatorQUAD4S2>(nbOfCells,connPtr,coordsPtr,resPtr);
213 double DiameterCalulatorQUAD4S3::computeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) const
215 if(std::distance(bg,endd)==4)
217 const double *a(coordsPtr+3*bg[0]),*b(coordsPtr+3*bg[1]),*c(coordsPtr+3*bg[2]),*d(coordsPtr+3*bg[3]);
221 return std::sqrt(std::max(SqNormV3(l0),SqNormV3(l1)));
224 throw Exception("DiameterCalulatorQUAD4S3::computeForOneCellInternal : input connectivity must be of size 4 !");
227 void DiameterCalulatorQUAD4S3::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const
229 ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorQUAD4S3>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr);
232 void DiameterCalulatorQUAD4S3::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const
234 ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorQUAD4S3>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr);
237 void DiameterCalulatorQUAD4S3::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const
239 ComputeFor1SGTUMeshFrmt<DiameterCalulatorQUAD4S3>(nbOfCells,connPtr,coordsPtr,resPtr);
242 double DiameterCalulatorTETRA4::computeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) const
244 if(std::distance(bg,endd)==4)
246 const double *a(coordsPtr+3*bg[0]),*b(coordsPtr+3*bg[1]),*c(coordsPtr+3*bg[2]),*d(coordsPtr+3*bg[3]);
247 double l0[3],l1[3],l2[3],l3[3],l4[3],l5[3];
255 tmp[0]=SqNormV3(l0); tmp[1]=SqNormV3(l1); tmp[2]=SqNormV3(l2); tmp[3]=SqNormV3(l3); tmp[4]=SqNormV3(l4); tmp[5]=SqNormV3(l5);
256 return std::sqrt(*std::max_element(tmp,tmp+6));
259 throw Exception("DiameterCalulatorTETRA4::computeForOneCellInternal : input connectivity must be of size 4 !");
262 void DiameterCalulatorTETRA4::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const
264 ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorTETRA4>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr);
267 void DiameterCalulatorTETRA4::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const
269 ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorTETRA4>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr);
272 void DiameterCalulatorTETRA4::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const
274 ComputeFor1SGTUMeshFrmt<DiameterCalulatorTETRA4>(nbOfCells,connPtr,coordsPtr,resPtr);
277 double DiameterCalulatorHEXA8::computeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) const
279 if(std::distance(bg,endd)==8)
281 const double *p0(coordsPtr+3*bg[0]),*p1(coordsPtr+3*bg[1]),*p2(coordsPtr+3*bg[2]),*p3(coordsPtr+3*bg[3]),*p4(coordsPtr+3*bg[4]),*p5(coordsPtr+3*bg[5]),*p6(coordsPtr+3*bg[6]),*p7(coordsPtr+3*bg[7]);
282 double l0[3],l1[3],l2[3],l3[3];
288 tmp[0]=SqNormV3(l0); tmp[1]=SqNormV3(l1); tmp[2]=SqNormV3(l2); tmp[3]=SqNormV3(l3);
289 return std::sqrt(*std::max_element(tmp,tmp+4));
292 throw Exception("DiameterCalulatorHEXA8::computeForOneCellInternal : input connectivity must be of size 8 !");
295 void DiameterCalulatorHEXA8::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const
297 ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorHEXA8>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr);
300 void DiameterCalulatorHEXA8::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const
302 ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorHEXA8>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr);
305 void DiameterCalulatorHEXA8::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const
307 ComputeFor1SGTUMeshFrmt<DiameterCalulatorHEXA8>(nbOfCells,connPtr,coordsPtr,resPtr);
310 double DiameterCalulatorPENTA6::computeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) const
312 if(std::distance(bg,endd)==6)
314 const double *p0(coordsPtr+3*bg[0]),*p1(coordsPtr+3*bg[1]),*p2(coordsPtr+3*bg[2]),*p3(coordsPtr+3*bg[3]),*p4(coordsPtr+3*bg[4]),*p5(coordsPtr+3*bg[5]);
315 double l0[3],l1[3],l2[3],l3[3],l4[3],l5[3];
323 tmp[0]=SqNormV3(l0); tmp[1]=SqNormV3(l1); tmp[2]=SqNormV3(l2); tmp[3]=SqNormV3(l3); tmp[4]=SqNormV3(l4); tmp[5]=SqNormV3(l5);
324 return std::sqrt(*std::max_element(tmp,tmp+6));
327 throw Exception("DiameterCalulatorPENTA6::computeForOneCellInternal : input connectivity must be of size 6 !");
330 void DiameterCalulatorPENTA6::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const
332 ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorPENTA6>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr);
335 void DiameterCalulatorPENTA6::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const
337 ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorPENTA6>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr);
340 void DiameterCalulatorPENTA6::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const
342 ComputeFor1SGTUMeshFrmt<DiameterCalulatorPENTA6>(nbOfCells,connPtr,coordsPtr,resPtr);
345 double DiameterCalulatorPYRA5::computeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) const
347 if(std::distance(bg,endd)==5)
349 const double *p0(coordsPtr+3*bg[0]),*p1(coordsPtr+3*bg[1]),*p2(coordsPtr+3*bg[2]),*p3(coordsPtr+3*bg[3]),*p4(coordsPtr+3*bg[4]);
350 double l0[3],l1[3],l2[3],l3[3],l4[3],l5[3];
358 tmp[0]=SqNormV3(l0); tmp[1]=SqNormV3(l1); tmp[2]=SqNormV3(l2); tmp[3]=SqNormV3(l3); tmp[4]=SqNormV3(l4); tmp[5]=SqNormV3(l5);
359 return std::sqrt(*std::max_element(tmp,tmp+6));
362 throw Exception("DiameterCalulatorPYRA5::computeForOneCellInternal : input connectivity must be of size 5 !");
365 void DiameterCalulatorPYRA5::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const
367 ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorPYRA5>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr);
370 void DiameterCalulatorPYRA5::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const
372 ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorPYRA5>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr);
375 void DiameterCalulatorPYRA5::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const
377 ComputeFor1SGTUMeshFrmt<DiameterCalulatorPYRA5>(nbOfCells,connPtr,coordsPtr,resPtr);