TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Analyse_Angle.cpp
1/****************************************************************************
2* Copyright (c) 2026, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#include <Analyse_Angle.h>
17#include <Domaine.h>
18#include <Linear_algebra_tools_impl.h>
19
20Implemente_instanciable_32_64(Analyse_Angle_32_64,"Analyse_Angle",Interprete_geometrique_base_32_64<_T_>);
21// XD analyse_angle interprete analyse_angle INHERITS_BRACE Keyword Analyse_angle prints the histogram of the largest
22// XD_CONT angle of each mesh elements of the domain named name_domain. nb_histo is the histogram number of bins. It is
23// XD_CONT called by default during the domain discretization with nb_histo set to 18. Useful to check the number of
24// XD_CONT elements with angles above 90 degrees.
25// XD attr domain_name ref_domaine domain_name REQ Name of domain to resequence.
26// XD attr nb_histo entier nb_histo REQ not_set
27
28// XD analyse_angle_64 analyse_angle analyse_angle_64 INHERITS_BRACE Analyse_angle for big (64b) domain.
29
30template <typename _SIZE_>
32{
33 return os;
34}
35
36template <typename _SIZE_>
38{
39 return is;
40}
41
42
43double largest_angle(const DoubleTab& coords)
44{
45 if (((coords.dimension(0)!=4)&&(coords.dimension(0)!=3))||(coords.dimension(1)!=3))
46 {
47 Cerr<<" case not provided"<<finl;
49 }
50 int nb_face=coords.dimension(0);
51 Vecteur3 normals[4];
52 Vecteur3 edge[2],opp;
53 edge[1].set(0,0,1);
54 for (int n=0; n<nb_face; n++)
55 {
56
57 int prem=0;
58 if (n==0) prem=1;
59 int compteur=0;
60 for (int s=0; s<nb_face; s++)
61 {
62 if ((s!=n) && (s!=prem))
63 {
64 edge[compteur].set(coords(s,0)-coords(prem,0),
65 coords(s,1)-coords(prem,1),
66 coords(s,2)-coords(prem,2));
67 compteur++;
68 }
69 }
70 if (compteur!=nb_face-2) abort();
71 opp.set(coords(n,0)-coords(prem,0),
72 coords(n,1)-coords(prem,1),
73 coords(n,2)-coords(prem,2));
74 Vecteur3::produit_vectoriel(edge[0],edge[1],normals[n]);
75 //normals[n]=edge[0]*edge[1];
76 double l = normals[n].length();
77 normals[n]*=(l>0 ? 1./l : 0);
78 if (Vecteur3::produit_scalaire(normals[n],opp)<0)
79 normals[n]*=-1;
80 }
81 // we have the 4 normals oriented toward the interior
82 double max_pscal=-100;
83 for (int n1=0; n1<nb_face; n1++)
84 for (int n2=n1+1; n2<nb_face; n2++)
85 {
86 double pscal=Vecteur3::produit_scalaire(normals[n1],normals[n2]);
87 //min_pscal=pscal;
88 if (pscal>max_pscal)
89 max_pscal=pscal;
90 }
91 double tet=acos(max_pscal<=1. ? max_pscal : 1.)/acos(-1.)*180; // acos(-1) does not compile with xlC
92
93 tet=180-tet;
94 return tet;
95}
96
97template <typename _SIZE_>
99{
100 this->associer_domaine(is);
101 int nb_histo;
102 is >> nb_histo;
103 histogramme_angle(this->domaine(), Cout, nb_histo);
104 return is;
105}
106
107template <typename _SIZE_>
108void histogramme_angle(const Domaine_32_64<_SIZE_>& dom, Sortie& out, int nb_histo)
109{
110 using IntTab_t = IntTab_T<_SIZE_>;
111 using DoubleTab_t = DoubleTab_T<_SIZE_>;
112 out<<finl<<"Histogram of the largest angle of each element found into the mesh "<<dom.le_nom()<<" :" << finl;
113 Motcle type_elem(dom.type_elem()->que_suis_je());
114 if (((type_elem!="triangle")&& (type_elem!="tetraedre")) || ((type_elem=="triangle") && (Domaine_32_64<_SIZE_>::dimension==3)))
115 {
116 out<<"Not available for "<<type_elem<<" in dimension "<<Domaine_32_64<_SIZE_>::dimension<<finl;
117 return;
118 }
119
120 ArrOfInt histo(nb_histo+1);
121 _SIZE_ nb_elem=dom.nb_elem();
122 const DoubleTab_t& som=dom.les_sommets();
123 const IntTab_t& les_elems=dom.les_elems();
124 int dim_space=(int)som.dimension(1);
125 int nb_som_elem=(int)les_elems.dimension(1);
126 DoubleTab coords(nb_som_elem,3);
127 ToDo_Kokkos("critical");
128 for (_SIZE_ elem=0; elem<nb_elem; elem++)
129 {
130 for (int s=0; s<nb_som_elem; s++)
131 {
132 _SIZE_ sommet=les_elems(elem,s);
133 for (int dir=0; dir<dim_space; dir++)
134 coords(s,dir)=som(sommet,dir);
135 }
136 double teta=largest_angle(coords);
137
138 int test=(int)(teta/180*nb_histo);
139 histo[test]++;
140 if (test==nb_histo)
141 Cerr << "Error, the mesh cell " << elem << " is flat. Fix your mesh." << finl;
142 }
143 if (histo[nb_histo]>0)
145 trustIdType nb_elem_tot = Process::mp_sum(nb_elem);
146 if (nb_elem_tot>0)
147 {
148 double obtuse_cells_proportion=0;
149 for (int h=0; h<nb_histo; h++)
150 {
151 histo[h]=static_cast<int>(Process::mp_sum(histo[h])); // should remain within 'int' range
152 // No angles below 60 necessarily
153 if (180/nb_histo*h>=60)
154 {
155 obtuse_cells_proportion=histo[h]*100./(double)nb_elem_tot;
156 int angle=180/nb_histo*h;
157 out <<"Between "<<angle<<" degrees and " << 180/nb_histo*(h+1)<<" degrees : "<<histo[h]<<" elements ( "<<obtuse_cells_proportion<< " %)"<<finl;
158 }
159 }
160 // Criteria used on the last bin (170-180 degrees)
161 if (obtuse_cells_proportion>20)
162 {
163 Cerr << finl;
164 Cerr << "Warning:" << finl;
165 Cerr << "Your mesh has too much obtuse cells for a TRUST calculation." << finl;
166 Cerr << "Check the mesh requirements." << finl;
167 //Process::exit();
168 }
169 }
170 out << finl;
171}
172
173template class Analyse_Angle_32_64<int>;
174template void histogramme_angle<int>(const Domaine_32_64<int>&, Sortie&, int);
175#if INT_is_64_ == 2
177template void histogramme_angle<trustIdType>(const Domaine_32_64<trustIdType>&, Sortie&, int);
178#endif
Entree & interpreter_(Entree &) override
class Domaine_32_64 A Domain is a mesh composed of a set of geometric elements of the same type.
Definition Domaine.h:62
DoubleTab_t & les_sommets()
Definition Domaine.h:113
IntTab_t & les_elems()
Definition Domaine.h:129
int_t nb_elem() const
Definition Domaine.h:131
const Nom & le_nom() const override
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
Class Interprete_geometrique_base.
A character string (Nom) in uppercase.
Definition Motcle.h:26
friend class Entree
Definition Objet_U.h:71
static int dimension
Definition Objet_U.h:94
const Nom & que_suis_je() const
Returns the string identifying the class.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
Definition Objet_U.cpp:289
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
static double mp_sum(double)
Computes the sum of x over all processors in the current group.
Definition Process.cpp:145
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
Base class for output streams.
Definition Sortie.h:52
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
static double produit_scalaire(const Vecteur3 &x, const Vecteur3 &y)
static void produit_vectoriel(const Vecteur3 &x, const Vecteur3 &y, Vecteur3 &resu)
void set(double x, double y, double z)
Definition Vecteur3.h:36
double length() const
Definition Vecteur3.h:51