1 // Copyright (C) 2007-2020 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
23 medpartitioner --input-file=blade.med --output-file=ttmp1_ --ndomains=2 --dump-cpu-memory --verbose=$verb
24 medpartitioner --input-file=medpartitioner_blade.xml --output-file=ttmp1_ --ndomains=2 --dump-cpu-memory --verbose=$verb
25 medpartitioner --input-file=ttmp1_.xml --output-file=tttmp1_ --ndomains=4 --dump-cpu-memory --verbose=$verb
29 #include "MEDPARTITIONER_Graph.hxx"
30 #include "MEDPARTITIONER_Topology.hxx"
31 #include "MEDPARTITIONER_ParaDomainSelector.hxx"
32 #include "MEDPARTITIONER_MeshCollection.hxx"
33 #include "MEDPARTITIONER_Utils.hxx"
36 #include "MEDPARTITIONER_MeshCollection.hxx"
37 #include "MEDPARTITIONER_ParallelTopology.hxx"
38 #include "MEDPARTITIONER_ParaDomainSelector.hxx"
39 #include "MEDPARTITIONER_Utils.hxx"
48 using namespace MEDPARTITIONER;
50 int main(int argc, char** argv)
52 #if !defined(MED_ENABLE_METIS) && !defined(MED_ENABLE_SCOTCH)
53 std::cout << "Sorry, no one split method is available. Please, compile with METIS or SCOTCH." << std::endl;
58 // by parsing the command line
60 bool split_family=false;
61 bool empty_groups=false;
62 bool mesure_memory=false;
63 bool filter_face=true;
68 string library="metis"; //default
73 MyGlobals::_World_Size=1;
75 MyGlobals::_Create_Boundary_Faces=0;
76 MyGlobals::_Create_Joints=0;
78 // Primitive parsing of command-line options
79 string desc ("Available options of medpartitioner V1.0:\n"
80 "\t--help : produces this help message\n"
81 "\t--verbose : echoes arguments\n"
82 "\t--input-file=<string> : name of the input .med file or .xml master file\n"
83 "\t--output-file=<string> : name of the resulting file (without extension)\n"
84 "\t--ndomains=<number> : number of subdomains in the output file, default is 1\n"
85 #if defined(MED_ENABLE_METIS) && defined(MED_ENABLE_SCOTCH)
87 "\t--split-method=<string> : name of the splitting library (metis/scotch), default is metis\n"
89 "\t--create-boundary-faces : creates boundary faces mesh in the output files\n"
90 "\t--create-joints : creates joints in the output files\n"
91 "\t--dump-cpu-memory : dumps passed CPU time and maximal increase of used memory\n"
96 for (int i = 1; i < argc; i++)
98 if (strlen(argv[i]) < 3)
100 cerr << "bad argument : "<< argv[i] << endl;
104 if (TestArg(argv[i],"--verbose",value))
106 MyGlobals::_Verbose=1;
107 if (value!="") MyGlobals::_Verbose = atoi(value.c_str());
109 else if (TestArg(argv[i],"--help",value)) help=1;
110 // else if (TestArg(argv[i],"--test",value)) test=1;
111 else if (TestArg(argv[i],"--input-file",value)) input=value;
112 else if (TestArg(argv[i],"--output-file",value)) output=value;
113 else if (TestArg(argv[i],"--split-method",value)) library=value;
114 else if (TestArg(argv[i],"--ndomains",value)) ndomains=atoi(value.c_str());
115 else if (TestArg(argv[i],"--create-boundary-faces",value)) MyGlobals::_Create_Boundary_Faces=1;
116 else if (TestArg(argv[i],"--create-joints",value)) MyGlobals::_Create_Joints=1;
117 else if (TestArg(argv[i],"--dump-cpu-memory",value)) mesure_memory=true;
120 cerr << "unknown argument : "<< argv[i] << endl;
125 MyGlobals::_Is0verbose=MyGlobals::_Verbose;
128 #if defined(MED_ENABLE_METIS) && !defined(MED_ENABLE_SCOTCH)
131 #if !defined(MED_ENABLE_METIS) && defined(MED_ENABLE_SCOTCH)
135 #if defined(MED_ENABLE_METIS) && defined(MED_ENABLE_SCOTCH)
136 if ((library!="metis") && (library!="scotch"))
138 cerr << "split-method only available : metis, scotch" << endl;
149 if (MyGlobals::_Is0verbose)
151 cout << "medpartitioner V1.0 :" << endl;
152 cout << " input-file = " << input << endl;
153 cout << " output-file = " << output << endl;
154 cout << " split-method = " << library << endl;
155 cout << " ndomains = " << ndomains << endl;
156 cout << " create_boundary_faces = " << MyGlobals::_Create_Boundary_Faces << endl;
157 cout << " create-joints = " << MyGlobals::_Create_Joints<< endl;
158 cout << " dump-cpu-memory = " << mesure_memory<< endl;
159 cout << " verbose = " << MyGlobals::_Verbose << endl;
161 //testing whether it is possible to write a file at the specified location
162 if (MyGlobals::_Rank==0)
164 string outputtest = output + ".testioms.";
165 ofstream testfile (outputtest.c_str());
168 cerr << "output-file directory does not exist or is in read-only access" << endl;
172 remove(outputtest.c_str());
175 // Beginning of the computation
177 // Loading the mesh collection
178 if (MyGlobals::_Is0verbose) cout << "Reading input files "<<endl;
182 /*MEDPARTITIONER::ParaDomainSelector parallelizer(mesure_memory);
183 MEDPARTITIONER::MeshCollection collection(input,parallelizer);
184 MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology();
185 aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector());
186 //int nbfiles=MyGlobals::_fileMedNames->size(); //nb domains
187 //to have unique valid fields names/pointers/descriptions for partitionning
188 collection.prepareFieldDescriptions();
189 //int nbfields=collection.getFieldDescriptions().size(); //on all domains
190 //cout<<ReprVectorOfString(collection.getFieldDescriptions());
192 if (MyGlobals::_Is0verbose)
194 cout<<"fileNames :"<<endl
195 <<ReprVectorOfString(MyGlobals::_File_Names);
196 cout<<"fieldDescriptions :"<<endl
197 <<ReprFieldDescriptions(collection.getFieldDescriptions()," "); //cvwat07
198 cout<<"familyInfo :\n"
199 <<ReprMapOfStringInt(collection.getFamilyInfo())<<endl;
200 cout<<"groupInfo :\n"
201 <<ReprMapOfStringVectorOfString(collection.getGroupInfo())<<endl;
203 MEDPARTITIONER::ParaDomainSelector parallelizer(mesure_memory);
204 MEDPARTITIONER::MeshCollection collection(input,parallelizer);
205 MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology();
206 aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector());
207 //to have unique valid fields names/pointers/descriptions for partitionning
208 collection.prepareFieldDescriptions();
210 //MEDPARTITIONER::MeshCollection collection(input);
212 //Creating the graph and partitioning it
213 if (MyGlobals::_Is0verbose) cout << "Computing partition with " << library << endl;
215 auto_ptr< MEDPARTITIONER::Topology > new_topo;
216 if (library == "metis")
217 new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::METIS));
219 new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH));
220 parallelizer.evaluateMemory();
222 //Creating a new mesh collection from the partitioning
223 if (MyGlobals::_Is0verbose) cout << "Creating new meshes"<< endl;
224 MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups);
226 if (filter_face) new_collection.filterFaceOnCell();
228 //to get infos on all procs
231 vector<string> finalInformations;
232 vector<string> r1,r2;
233 //r1=AllgathervVectorOfString(MyGlobals::_General_Informations);
234 r1=MyGlobals::_General_Informations;
235 //if (MyGlobals::_Is0verbose>1000) cout << "generalInformations : \n"<<ReprVectorOfString(r1);
236 r2=SelectTagsInVectorOfString(r1,"ioldDomain=");
237 r2=SelectTagsInVectorOfString(r2,"meshName=");
238 if (r2.size()==(collection.getMesh()).size())
240 for (std::size_t i=0; i<r2.size(); i++)
241 r2[i]=EraseTagSerialized(r2[i],"ioldDomain=");
242 r2=DeleteDuplicatesInVectorOfString(r2);
245 string finalMesh="finalMeshName="+ExtractFromDescription(r2[0], "meshName=");
246 finalInformations.push_back(SerializeFromString(finalMesh));
249 if (finalInformations.size()==0)
251 if (MyGlobals::_Rank==0)
252 cerr<<"Problem on final meshName : set at 'Merge'"<<endl;
253 finalInformations.push_back(SerializeFromString("finalMeshName=Merge"));
256 //see field info nbComponents & componentInfo (if fields present)
257 r2=SelectTagsInVectorOfString(r1,"fieldName=");
258 r2=SelectTagsInVectorOfString(r2,"nbComponents=");
259 //may be yes? or not?
260 for (std::size_t i=0; i<r2.size(); i++)
261 r2[i]=EraseTagSerialized(r2[i],"ioldFieldDouble=");
262 r2=DeleteDuplicatesInVectorOfString(r2);
263 for (std::size_t i=0; i<r2.size(); i++)
264 finalInformations.push_back(r2[i]);
266 MyGlobals::_General_Informations=finalInformations;
267 if (MyGlobals::_Is0verbose)
268 cout << "generalInformations : \n"<<ReprVectorOfString(finalInformations);
270 //new_collection.setSubdomainBoundaryCreates(create_boundary_faces);
271 if (MyGlobals::_Is0verbose) cout << "Writing "<<ndomains<<" output files "<<output<<"xx.med"<<" and "<<output<<".xml"<<endl;
272 new_collection.write(output);
274 /*if ( mesure_memory )
275 if ( parallelizer.isOnDifferentHosts() || MyGlobals::_Rank==0 )
277 cout << "Elapsed time = " << parallelizer.getPassedTime()
278 << ", max memory usage = " << parallelizer.evaluateMemory() << " KB"
282 if (MyGlobals::_Is0verbose>0) cout<<"OK END"<< endl;
285 catch(const char *mess)
291 catch(INTERP_KERNEL::Exception& e)
293 cerr<<"INTERP_KERNEL_Exception : "<<e.what()<<endl;
297 catch(std::exception& e)
299 cerr<<"std_Exception : "<<e.what()<<endl;
305 cerr<<"an unknown type exception error has occurred"<<endl;