TrioCFD 1.9.8
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 // on a les 4 normals orientes vers l'interieur
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) ne compile pas avec 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 // Pas d'angles en dessous de 60 forcement
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
classe Domaine_32_64 un Domaine est un maillage compose d'un ensemble d'elements geometriques de meme...
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
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
classe Interprete_geometrique_base .
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
friend class Entree
Definition Objet_U.h:76
static int dimension
Definition Objet_U.h:99
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
static double mp_sum(double)
Calcule la somme de x sur tous les processeurs du groupe courant.
Definition Process.cpp:146
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Classe de base des flux de sortie.
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