Salome HOME
1b9a6ffdf42f2e0b0ed603591c191a0c2362f728
[modules/homard.git] / src / FrontTrack / FrontTrack.cxx
1 // File      : FrontTrack.cxx
2 // Created   : Tue Apr 25 17:20:28 2017
3 // Author    : Edward AGAPOV (eap)
4
5 #include "FrontTrack.hxx"
6 #include "FrontTrack_NodeGroups.hxx"
7 #include "FrontTrack_Utils.hxx"
8
9 #include <MCAuto.hxx>
10 #include <MEDCouplingMemArray.hxx>
11 #include <MEDFileMesh.hxx>
12
13 #include <XAO_Xao.hxx>
14 #include <XAO_BrepGeometry.hxx>
15
16 #include <stdexcept>
17
18 #include <OSD_Parallel.hxx>
19
20 /*!
21  * \brief Relocate nodes to lie on geometry
22  *  \param [in] theInputMedFile - a MED file holding a mesh including nodes that will be
23  *         moved onto the geometry
24  *  \param [in] theOutputMedFile - a MED file to create, that will hold a modified mesh
25  *  \param [in] theInputNodeFiles - an array of names of files describing groups of nodes that
26  *         will be moved onto the geometry
27  *  \param [in] theXaoFileName - a path to a file in XAO format holding the geometry and
28  *         the geometrical groups.
29  *  \param [in] theIsParallel - if \c true, all processors are used to treat boundary shapes
30  *          in parallel.
31  */
32 void FrontTrack::track( const std::string&                 theInputMedFile,
33                         const std::string&                 theOutputMedFile,
34                         const std::vector< std::string > & theInputNodeFiles,
35                         const std::string&                 theXaoFileName,
36                         bool                               theIsParallel )
37 {
38   // check arguments
39 #ifdef _DEBUG_
40   std::cout << "FrontTrack::track" << std::endl;
41 #endif
42
43   if ( theInputNodeFiles.empty() )
44     return;
45
46 #ifdef _DEBUG_
47   std::cout << "Input MED file: " << theInputMedFile << std::endl;
48 #endif
49   if ( !FT_Utils::fileExists( theInputMedFile ))
50     throw std::invalid_argument( "Input MED file does not exist: " + theInputMedFile );
51
52 #ifdef _DEBUG_
53   std::cout << "Output MED file: " << theOutputMedFile << std::endl;
54 #endif
55   if ( !FT_Utils::canWrite( theOutputMedFile ))
56     throw std::invalid_argument( "Can't create the output MED file: " + theOutputMedFile );
57
58   std::vector< std::string > theNodeFiles ;
59   for ( size_t i = 0; i < theInputNodeFiles.size(); ++i )
60   {
61 #ifdef _DEBUG_
62     std::cout << "Initial input node file #"<<i<<": " << theInputNodeFiles[i] << std::endl;
63 #endif
64     if ( !FT_Utils::fileExists( theInputNodeFiles[i] ))
65       throw std::invalid_argument( "Input node file does not exist: " + theInputNodeFiles[i] );
66     // the name of the groupe on line #1, then the numbers of nodes on line #>1
67     // keep only files with more than 1 line:
68     std::ifstream fichier(theInputNodeFiles[i].c_str());
69     std::string s;
70     unsigned int nb_lines = 0;
71     while(std::getline(fichier,s)) ++nb_lines;
72 //     std::cout << ". nb_lines: " << nb_lines << std::endl;
73     if ( nb_lines >= 2 ) { theNodeFiles.push_back( theInputNodeFiles[i] ); }
74   }
75 #ifdef _DEBUG_
76   for ( size_t i = 0; i < theNodeFiles.size(); ++i )
77   { std::cout << "Valid input node file #"<<i<<": " << theNodeFiles[i] << std::endl; }
78 #endif
79
80 #ifdef _DEBUG_
81   std::cout << "XAO file: " << theXaoFileName << std::endl;
82 #endif
83   if ( !FT_Utils::fileExists( theXaoFileName ))
84     throw std::invalid_argument( "Input XAO file does not exist: " + theXaoFileName );
85
86   // read a mesh
87
88 #ifdef _DEBUG_
89   std::cout << "Lecture du maillage" << std::endl;
90 #endif
91   MEDCoupling::MCAuto< MEDCoupling::MEDFileUMesh >
92     mfMesh( MEDCoupling::MEDFileUMesh::New( theInputMedFile ));
93   if ( mfMesh.isNull() )
94     throw std::invalid_argument( "Failed to read the input MED file: " + theInputMedFile );
95
96   MEDCoupling::DataArrayDouble * nodeCoords = mfMesh->getCoords();
97   if ( !nodeCoords || nodeCoords->empty() )
98     throw std::invalid_argument( "No nodes in the input mesh" );
99
100
101   // read a geometry
102
103 #ifdef _DEBUG_
104   std::cout << "Lecture de la geometrie" << std::endl;
105 #endif
106   XAO::Xao xao;
107   if ( !xao.importXAO( theXaoFileName ) || !xao.getGeometry() )
108     throw std::invalid_argument( "Failed to read the XAO input file: " + theXaoFileName );
109
110 #ifdef _DEBUG_
111   std::cout << "Conversion en BREP" << std::endl;
112 #endif
113   XAO::BrepGeometry* xaoGeom = dynamic_cast<XAO::BrepGeometry*>( xao.getGeometry() );
114   if ( !xaoGeom || xaoGeom->getTopoDS_Shape().IsNull() )
115     throw std::invalid_argument( "Failed to get a BREP shape from the XAO input file" );
116
117
118   // read groups of nodes and associate them with boundary shapes using names (no projection so far)
119
120 #ifdef _DEBUG_
121   std::cout << "Lecture des groupes" << std::endl;
122 #endif
123   FT_NodeGroups nodeGroups;
124   nodeGroups.read( theNodeFiles, &xao, nodeCoords );
125 #ifdef _DEBUG_
126   std::cout << "Nombre de groupes : " << nodeGroups.nbOfGroups() << std::endl;
127 #endif
128
129   // project nodes to the boundary shapes and change their coordinates
130
131 #ifdef _DEBUG_
132   std::cout << "Projection des noeuds, theIsParallel=" << theIsParallel << std::endl;
133 #endif
134   OSD_Parallel::For( 0, nodeGroups.nbOfGroups(), nodeGroups, !theIsParallel );
135
136   // save the modified mesh
137
138 #ifdef _DEBUG_
139   std::cout << "Ecriture du maillage" << std::endl;
140 #endif
141   const int erase = 2;
142   mfMesh->write( theOutputMedFile, /*mode=*/erase );
143
144   if ( !nodeGroups.isOK() )
145     throw std::runtime_error("Unable to project some nodes");
146 }