Salome HOME
MeshFormatWriter and MeshFormaReader are in MEDCOUPLING namespace
[modules/smesh.git] / src / SMESHGUI / MG_ADAPT.cxx
index 641c0f0c24b1a5fed4c7b75f1d7e5c970daf4ff4..3a1f568326fa1899737d915d267b26bf5912bc29 100644 (file)
@@ -17,7 +17,7 @@
 // License along with this library; if not, write to the Free Software
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/
 // file : MG_ADAPT.cxx
 
 #include "MG_ADAPT.hxx"
 #include <unistd.h>
 #include <TCollection_AsciiString.hxx>
 #include <cstring>
+#include <cstdlib>
 #include <boost/filesystem.hpp>
 
+static std::string removeFile(std::string fileName, int& notOk)
+{
+       std::string errStr;
+       notOk = std::remove(fileName.c_str());
+       if (notOk) errStr = ToComment(" \n error while removing file : ")
+                 << fileName;
+    else errStr= ToComment("\n file : ")<< fileName << " succesfully deleted! \n ";      
+    
+    return errStr; 
+}
 namespace
 {
 struct GET_DEFAULT // struct used to get default value from GetOptionValue()
@@ -429,8 +440,8 @@ bool MgAdapt::setAll()
     }
 
     setSizeMapFile(mapfile);
-    int rank;
-    int tmst;
+    med_int rank;
+    med_int tmst;
     if (data->myUseNoTimeStep)
     {
         rank = MED_NO_IT;
@@ -446,7 +457,7 @@ bool MgAdapt::setAll()
         rank = data->myRank;
         tmst  = data->myTimeStep;
     }
-    setRankTimeStep(tmst, rank);
+    setRankTimeStep((int)tmst, (int)rank);
 
     /* Advanced options */
     setWorkingDir(data->myWorkingDir);
@@ -484,7 +495,9 @@ throw (std::invalid_argument)
 
     if (op_val->second != optionValue)
     {
-        const char* ptr = optionValue.c_str();
+               
+               std::string lowerOptionValue = toLowerStr(optionValue);
+        const char* ptr = lowerOptionValue.c_str();
         // strip white spaces
         while (ptr[0] == ' ')
             ptr++;
@@ -497,7 +510,7 @@ throw (std::invalid_argument)
         if (i == 0) {
             // empty string
         } else if (_charOptions.count(optionName)) {
-            // do not check strings
+            // do not check strings 
         } else if (_doubleOptions.count(optionName)) {
             // check if value is double
             toDbl(ptr, &typeOk);
@@ -581,6 +594,18 @@ throw (std::invalid_argument)
     return val;
 }
 //================================================================================
+/*!
+ * \brief Converts a string to a lower 
+ */
+//================================================================================
+std::string MgAdapt::toLowerStr(const std::string& str)
+{
+    std::string s = str;
+       for ( size_t i = 0; i <= s.size(); ++i )
+        s[i] = tolower( s[i] );
+    return s;
+}
+//================================================================================
 /*!
  * \brief Converts a string to a bool
  */
@@ -662,7 +687,7 @@ std::string MgAdapt::getCommandToRun(MgAdapt* hyp)
 
 int MgAdapt::compute(std::string& errStr)
 {
-    std::string cmd= getCommandToRun();
+    std::string cmd = getCommandToRun();
     int err = 0;
     execCmd( cmd.c_str(), err ); // run
 
@@ -675,6 +700,7 @@ int MgAdapt::compute(std::string& errStr)
     {
         convertMeshFile(meshFormatOutputMesh, solFormatOutput);
     }
+    //~if (!err) cleanUp();
     return err;
 }
 
@@ -682,8 +708,19 @@ void MgAdapt::execCmd( const char* cmd, int& err)
 {
     err = 1;
     std::array <char, 128> buffer;
-    std:: ofstream logStream;
-    logStream.open(logFile);
+    std::streambuf* buf;
+       outFileStream fileStream;
+    if (printLogInFile)
+    {
+               fileStream.open(logFile);
+               buf = fileStream.rdbuf();
+       }
+       else
+       {
+          buf = std::cout.rdbuf();     
+       }
+       std::ostream logStream(buf);
+       
     std::unique_ptr <FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose );
     if(!pipe)
     {
@@ -693,9 +730,34 @@ void MgAdapt::execCmd( const char* cmd, int& err)
     {
         logStream<<buffer.data() ;
     }
-    logStream.close();
     err = 0;
 }
+
+void MgAdapt::cleanUp()
+{
+       int notOk;
+       std::string errStr;
+       if(removeOnSuccess) tmpFilesToBeDeleted.push_back(logFile);
+       
+       std::vector< std::string>::iterator it = tmpFilesToBeDeleted.begin();
+       for (; it!=tmpFilesToBeDeleted.end(); ++it)
+       {
+               errStr=removeFile(*it, notOk);
+               if (notOk)
+               {
+                       appendMsgToLogFile(errStr);
+               }
+               
+       }
+}
+
+void MgAdapt::appendMsgToLogFile(std::string& msg)
+{
+       std::ofstream logStream;        
+       logStream.open(logFile, std::ofstream::out | std::ofstream::app);
+       logStream<< msg;
+    logStream.close(); 
+}
 //================================================================================
 /*!
  * \brief Return command to run MG-Tetra mesher excluding file prefix (-f)
@@ -717,6 +779,8 @@ std::string MgAdapt::getCommandToRun()
         errStr = ToComment(" failed to find .mesh or .sol file from converter ")<< strerror( errno );
         return errStr;
     }
+    tmpFilesToBeDeleted.push_back(meshIn);
+    tmpFilesToBeDeleted.push_back(solFileIn);
     if(useBackgroundMap && !isFileExist(sizeMapIn))
     {
 
@@ -724,23 +788,32 @@ std::string MgAdapt::getCommandToRun()
         return errStr;
 
     }
-    meshFormatOutputMesh = meshIn;
-    solFormatOutput.push_back(solFileIn);
+
 
     cmd+= " --in "+ meshIn;
     meshFormatOutputMesh = getFileName()+".mesh";
     cmd+= " --out "+ meshFormatOutputMesh;
-    if (useLocalMap) cmd+= " --sizemap "+ solFileIn;
-    else if (useBackgroundMap)
+    if (useLocalMap || useConstantValue) cmd+= " --sizemap "+ solFileIn;
+    else //  (useBackgroundMap)
     {
         cmd+= " --background_mesh "+ sizeMapIn ;
         cmd+= " --background_sizemap "+ solFileIn;
+               tmpFilesToBeDeleted.push_back(sizeMapIn);
     }
-    else
+    //~else
+    //~{
+        //~// constant value TODO
+    //~}
+    /* sizemap file is not adapted in case of only surface adaptation see MeshGems docs */
+    std::string adapOp   = "adaptation";
+    std::string adpOpVal = getOptionValue(adapOp);
+    std::string surfaceAdapt = "surface";
+    if(surfaceAdapt != adpOpVal )
     {
-        // constant value TODO
-    }
-
+               std::string solFileOut = getFileName()+".sol";
+        cmd+= " --write_sizemap "+ solFileOut;
+               solFormatOutput.push_back(solFileOut);
+       } 
     if (verbosityLevel != defaultVerboseLevel())
     {
 
@@ -1032,7 +1105,7 @@ void MgAdapt::convertMedFile(std::string& meshFormatMeshFileName, std::string& s
 {
 
     std::vector<std::string> fieldFileNames;
-    MeshFormatWriter writer;
+    MEDCoupling::MeshFormatWriter writer;
     MEDCoupling::MCAuto<MEDCoupling::MEDFileData> mfd = MEDCoupling::MEDFileData::New(medFileIn);
     MEDCoupling::MEDFileMeshes* meshes = mfd->getMeshes();
     MEDCoupling::MEDFileMesh* fileMesh = meshes->getMeshAtPos(0); // ok only one mesh in file!
@@ -1048,25 +1121,7 @@ void MgAdapt::convertMedFile(std::string& meshFormatMeshFileName, std::string& s
 
         meshFormatsizeMapFile = getFileName();
         meshFormatsizeMapFile += ".mesh";
-        MEDCoupling::MCAuto<MEDCoupling::MEDFileData> tmpMfd = MEDCoupling::MEDFileData::New(sizeMapFile);
-        MEDCoupling::MEDFileFields* tmpFields = tmpMfd->getFields();
-        MEDCoupling::MEDFileAnyTypeFieldMultiTS* fts = tmpFields->getFieldWithName(fieldName);
-        MEDCoupling::MCAuto<MEDCoupling::MEDFileFieldMultiTS>  fts1 = dynamic_cast<MEDCoupling::MEDFileFieldMultiTS *>(fts);
-        MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeField1TS> f = fts1->getTimeStep(timeStep, rank);
-        MEDCoupling::MCAuto<MEDCoupling::MEDFileFieldMultiTS> tmFts = MEDCoupling::MEDFileFieldMultiTS::New();
-        tmFts->pushBackTimeStep(f);
-
-        MEDCoupling::MCAuto<MEDCoupling::MEDFileFields> tmp_fields = MEDCoupling::MEDFileFields::New();
-        tmp_fields->pushField(tmFts);
-
-
-        tmpMfd->setFields( tmp_fields );
-        MeshFormatWriter tmpWriter;
-        tmpWriter.setMeshFileName(meshFormatsizeMapFile);
-        tmpWriter.setFieldFileNames( fieldFileNames);
-        tmpWriter.setMEDFileDS(tmpMfd);
-        tmpWriter.write();
-
+           buildBackGroundMeshAndSolFiles(fieldFileNames, meshFormatsizeMapFile);
 
     }
     else if(useLocalMap)
@@ -1084,19 +1139,12 @@ void MgAdapt::convertMedFile(std::string& meshFormatMeshFileName, std::string& s
 
     else
     {
-        MEDCoupling::MEDCouplingMesh* mesh = fileMesh->getMeshAtLevel(1); // nodes mesh
-        MEDCoupling::MEDCouplingFieldDouble* fieldOnNodes=MEDCoupling::MEDCouplingFieldDouble::New(MEDCoupling::ON_NODES,MEDCoupling::NO_TIME);
-        fieldOnNodes->setName("MyScalarFieldOnNodeNoTime");
-        fieldOnNodes->setMesh(mesh);
-        mesh->decrRef(); // no more need of mesh because mesh has been attached to fieldOnNodes
-        MEDCoupling::DataArrayDouble *array=MEDCoupling::DataArrayDouble::New();
-        array->alloc(fieldOnNodes->getMesh()->getNumberOfNodes(),1);//Implicitly fieldOnNodes will be a 1 component field.
-        array->fillWithValue(constantValue);
-        fieldOnNodes->setArray(array);
-        array->decrRef();
-        // fieldOnNodes is now usable
-        // ...
-        // fieldOnNodes is no more useful h
+        MEDCoupling::MCAuto<MEDCoupling::MEDCouplingMesh> mesh = fileMesh->getMeshAtLevel(1); // nodes mesh
+        MEDCoupling::MCAuto<MEDCoupling::MEDCouplingUMesh> umesh = mesh->buildUnstructured(); // nodes mesh
+        int dim  =  umesh->getSpaceDimension();
+        int version =  sizeof(double) < 8 ? 1 : 2;
+        mcIdType nbNodes =  umesh->getNumberOfNodes();
+        buildConstantSizeMapSolFile(solFormatFieldFileName, dim, version, nbNodes);
 
     }
 
@@ -1111,7 +1159,7 @@ void MgAdapt::convertMedFile(std::string& meshFormatMeshFileName, std::string& s
 
 void MgAdapt::convertMeshFile(std::string& meshFormatIn, std::vector< std::string>& solFieldFileNames) const
 {
-    MeshFormatReader reader(meshFormatIn, solFieldFileNames);
+    MEDCoupling::MeshFormatReader reader(meshFormatIn, solFieldFileNames);
 
     MEDCoupling::MCAuto<MEDCoupling::MEDFileData> mfd = reader.loadInMedFileDS();
     // write MED
@@ -1178,7 +1226,8 @@ void MgAdapt::restorefams(MEDCoupling::MEDFileMesh* fileMesh) const
     {  
                try  // safety : FAMILY could be lost P2-->P1
         {
-                       std::string givenFamNameFromMeshGemConverter = fileMesh->getFamilyNameGivenId( fIt->_famId );
+                       std::string givenFamNameFromMeshGemConverter = fileMesh->getFamilyNameGivenId( std::abs(fIt->_famId) );
+            fileMesh->changeFamilyId(std::abs(fIt->_famId), fIt->_famId);
             fileMesh->changeFamilyName(givenFamNameFromMeshGemConverter, fIt->_famName);
         }
         catch (const std::exception& e)
@@ -1200,6 +1249,43 @@ void MgAdapt::restoreGroups(MEDCoupling::MEDFileMesh* fileMesh) const
 
     fileMesh->setGroupInfo(info);
 }
+
+void MgAdapt::buildConstantSizeMapSolFile(const std::string& solFormatFieldFileName, const int dim, const int version, const mcIdType nbNodes) const
+{
+       MeshFormat::Localizer loc;
+    MeshFormat::MeshFormatParser writer;
+    int fileId = writer.GmfOpenMesh( solFormatFieldFileName.c_str(), GmfWrite, version, dim);
+    int typTab[] = {GmfSca};
+    writer.GmfSetKwd(fileId, MeshFormat::GmfSolAtVertices, (int)nbNodes, 1, typTab);
+    for (mcIdType i = 0; i<nbNodes; i++) 
+    {
+               double valTab[1] = {constantValue};
+               writer.GmfSetLin( fileId, MeshFormat::GmfSolAtVertices, valTab);
+       }
+    writer.GmfCloseMesh(fileId);
+}
+
+void MgAdapt::buildBackGroundMeshAndSolFiles(const std::vector<std::string>& fieldFileNames, const std::string& meshFormatsizeMapFile) const
+{
+    MEDCoupling::MCAuto<MEDCoupling::MEDFileData> tmpMfd = MEDCoupling::MEDFileData::New(sizeMapFile);
+       MEDCoupling::MEDFileFields* tmpFields = tmpMfd->getFields();
+       MEDCoupling::MEDFileAnyTypeFieldMultiTS* fts = tmpFields->getFieldWithName(fieldName);
+       MEDCoupling::MCAuto<MEDCoupling::MEDFileFieldMultiTS>  fts1 = dynamic_cast<MEDCoupling::MEDFileFieldMultiTS *>(fts);
+       MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeField1TS> f = fts1->getTimeStep(timeStep, rank);
+       MEDCoupling::MCAuto<MEDCoupling::MEDFileFieldMultiTS> tmFts = MEDCoupling::MEDFileFieldMultiTS::New();
+       tmFts->pushBackTimeStep(f);
+
+       MEDCoupling::MCAuto<MEDCoupling::MEDFileFields> tmp_fields = MEDCoupling::MEDFileFields::New();
+       tmp_fields->pushField(tmFts);
+
+
+       tmpMfd->setFields( tmp_fields );
+       MEDCoupling::MeshFormatWriter tmpWriter;
+       tmpWriter.setMeshFileName(meshFormatsizeMapFile);
+       tmpWriter.setFieldFileNames( fieldFileNames);
+       tmpWriter.setMEDFileDS(tmpMfd);
+       tmpWriter.write();      
+}
 // =======================================================================
 med_idt MgAdapt::openMedFile(const std::string aFile)
 // =======================================================================
@@ -1233,13 +1319,13 @@ MgAdapt::Status MgAdapt::addMessage(const std::string& msg,
 
 
 // =======================================================================
-void MgAdapt::getTimeStepInfos(std::string aFile, int& numdt, int& numit)
+void MgAdapt::getTimeStepInfos(std::string aFile, med_int& numdt, med_int& numit)
 // =======================================================================
 {
 // Il faut voir si plusieurs maillages
 
 
-    med_err erreur = 0 ;
+    herr_t erreur = 0 ;
     med_idt medIdt ;
 
 
@@ -1278,7 +1364,7 @@ void MgAdapt::getTimeStepInfos(std::string aFile, int& numdt, int& numit)
     }
 
     med_float dt;
-    int tmp_numdt, tmp_numit;
+    med_int tmp_numdt, tmp_numit;
 
     med_int step = data->myUseLastTimeStep ? nbofcstp : data->myTimeStep+1;
     //~myPrint("step ", step);
@@ -1286,7 +1372,8 @@ void MgAdapt::getTimeStepInfos(std::string aFile, int& numdt, int& numit)
     if ( erreur < 0 )
     {
 
-        //~addMessage( ToComment(" error: error while reading field last time step ") << nomcha << " in file " << aFile , /*fatal=*/true );
+        //~addMessage( ToComment(" error: error while reading field ") << nomcha << "step (numdt, numit) = " <<"("<< numdt<< ", " \
+        numit<< ")" <<" in file " << aFile , /*fatal=*/true );
         return;
     }