MEDCoupling Memory output from SMESH engine now deal with fields too.

This commit is contained in:
Anthony Geay 2021-06-23 07:59:19 +02:00
parent 12d2ca8ac7
commit ef9db08c81
8 changed files with 261 additions and 24 deletions

View File

@ -0,0 +1,175 @@
#!/usr/bin/env python
import sys
import salome
import unittest
class SMESHExportOfFieldsInMemory(unittest.TestCase):
def testMEDCouplingFieldOnCells(self):
"""
Test focuses on ExportMEDCoupling method in the context of MED_CELL field output.
"""
salome.standalone()
salome.salome_init()
###
### SHAPER component
###
from salome.shaper import model
model.begin()
partSet = model.moduleDocument()
### Create Part
Part_1 = model.addPart(partSet)
Part_1_doc = Part_1.document()
### Create Box
Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
### Create Plane
Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOY"), 5, False)
### Create Plane
Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/YOZ"), 5, False)
### Create Partition
Partition_1_objects = [model.selection("FACE", "Plane_1"),
model.selection("FACE", "Plane_2"),
model.selection("SOLID", "Box_1_1")]
Partition_1 = model.addPartition(Part_1_doc, Partition_1_objects, keepSubResults = True)
### Create Field
Field_1_objects = [model.selection("SOLID", "Partition_1_1_2"),
model.selection("SOLID", "Partition_1_1_4"),
model.selection("SOLID", "Partition_1_1_1"),
model.selection("SOLID", "Partition_1_1_3")]
Field_1 = model.addField(Part_1_doc, 1, "DOUBLE", 1, ["Comp 1"], Field_1_objects)
Field_1.addStep(0, 0, [[0], [1], [2], [3], [4]])
model.end()
###
### SHAPERSTUDY component
###
model.publishToShaperStudy()
import SHAPERSTUDY
Partition_1_1, Field_1_1 = SHAPERSTUDY.shape(model.featureStringId(Partition_1))
###
### SMESH component
###
import SMESH, SALOMEDS
from salome.smesh import smeshBuilder
smesh = smeshBuilder.New()
#smesh.SetEnablePublish( False ) # Set to False to avoid publish in study if not needed or in some particular situations:
# multiples meshes built in parallel, complex and numerous mesh edition (performance)
Mesh_1 = smesh.Mesh(Partition_1_1)
Regular_1D = Mesh_1.Segment()
Local_Length_1 = Regular_1D.LocalLength(5,None,1e-07)
Quadrangle_2D = Mesh_1.Quadrangle(algo=smeshBuilder.QUADRANGLE)
Hexa_3D = Mesh_1.Hexahedron(algo=smeshBuilder.Hexa)
isDone = Mesh_1.Compute()
smesh.SetName(Mesh_1, 'Mesh_1')
#### Mesh_1.ExportMED( r'Mesh_with_one_field_on_cells.med', 0, 41, 1, Mesh_1.GetMesh(), 1, [ Field_1_1 ], '',-1 )
mfd = Mesh_1.ExportMEDCoupling(0, Mesh_1.GetMesh(), 1, [ Field_1_1 ], '',-1 )#### <- important line of test is here !
self.assertEqual(len(mfd.getMeshes()),1)
self.assertEqual(len(mfd.getFields()),1)
f = mfd.getFields()[0][0].field(mfd.getMeshes()[0])
f.checkConsistencyLight()
import medcoupling
self.assertEqual(f.getDiscretization().getEnum(),medcoupling.ON_CELLS)
self.assertTrue(f.getMesh().getNumberOfCells()>1)
pass
def testMEDCouplingFieldOnNodes(self):
"""
Test focuses on ExportMEDCoupling method in the context of MED_NODES field output.
"""
salome.standalone()
salome.salome_init()
###
### SHAPER component
###
from salome.shaper import model
model.begin()
partSet = model.moduleDocument()
### Create Part
Part_1 = model.addPart(partSet)
Part_1_doc = Part_1.document()
### Create Box
Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
### Create Plane
Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOY"), 5, False)
### Create Plane
Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/YOZ"), 5, False)
### Create Partition
Partition_1_objects = [model.selection("FACE", "Plane_1"),
model.selection("FACE", "Plane_2"),
model.selection("SOLID", "Box_1_1")]
Partition_1 = model.addPartition(Part_1_doc, Partition_1_objects, keepSubResults = True)
### Create Field
Field_2_objects = [model.selection("VERTEX", "[Partition_1_1_2/Modified_Face&Box_1_1/Back][Partition_1_1_2/Modified_Face&Box_1_1/Left][Partition_1_1_2/Modified_Face&Box_1_1/Top]"),
model.selection("VERTEX", "Partition_1_1_2/Generated_Vertex&Plane_2/Plane_2&new_weak_name_1"),
model.selection("VERTEX", "[Partition_1_1_4/Modified_Face&Box_1_1/Front][Partition_1_1_4/Modified_Face&Box_1_1/Left][Partition_1_1_4/Modified_Face&Box_1_1/Top]"),
model.selection("VERTEX", "Partition_1_1_1/Generated_Vertex&Plane_1/Plane_1&new_weak_name_1"),
model.selection("VERTEX", "[Partition_1_1_1/Modified_Face&Box_1_1/Left][Partition_1_1_1/Modified_Face&Plane_1/Plane_1][Partition_1_1_1/Modified_Face&Plane_2/Plane_2]"),
model.selection("VERTEX", "Partition_1_1_3/Generated_Vertex&Plane_1/Plane_1&new_weak_name_1"),
model.selection("VERTEX", "[Partition_1_1_1/Modified_Face&Box_1_1/Back][Partition_1_1_1/Modified_Face&Box_1_1/Left][Partition_1_1_1/Modified_Face&Box_1_1/Bottom]"),
model.selection("VERTEX", "Partition_1_1_1/Generated_Vertex&Plane_2/Plane_2&new_weak_name_1"),
model.selection("VERTEX", "[Partition_1_1_3/Modified_Face&Box_1_1/Left][Partition_1_1_3/Modified_Face&Box_1_1/Bottom][Partition_1_1_3/Modified_Face&Box_1_1/Front]")]
Field_2 = model.addField(Part_1_doc, 1, "DOUBLE", 1, ["Comp 1"], Field_2_objects)
Field_2.addStep(0, 0, [[0], [1], [2], [3], [4], [5], [6], [7], [8], [9]])
model.end()
###
### SHAPERSTUDY component
###
model.publishToShaperStudy()
import SHAPERSTUDY
Partition_1_1, Field_2_1 = SHAPERSTUDY.shape(model.featureStringId(Partition_1))
###
### SMESH component
###
import SMESH, SALOMEDS
from salome.smesh import smeshBuilder
smesh = smeshBuilder.New()
#smesh.SetEnablePublish( False ) # Set to False to avoid publish in study if not needed or in some particular situations:
# multiples meshes built in parallel, complex and numerous mesh edition (performance)
Mesh_1 = smesh.Mesh(Partition_1_1)
Regular_1D = Mesh_1.Segment()
Local_Length_1 = Regular_1D.LocalLength(5,None,1e-07)
Quadrangle_2D = Mesh_1.Quadrangle(algo=smeshBuilder.QUADRANGLE)
Hexa_3D = Mesh_1.Hexahedron(algo=smeshBuilder.Hexa)
isDone = Mesh_1.Compute()
smesh.SetName(Mesh_1, 'Mesh_1')
# 23th of june 2021 : Bug both in ExportMED and in ExportMEDCoupling
#Mesh_1.ExportMED( r'/tmp/Mesh_with_one_field_on_nodes.med', 0, 41, 1, Mesh_1.GetMesh(), 1, [ Field_2_1 ], '',-1 )
#mfd = Mesh_1.ExportMEDCoupling(0,Mesh_1.GetMesh(), 1, [ Field_2_1 ], '',-1)
if __name__ == '__main__':
unittest.main()

View File

@ -197,6 +197,7 @@ set(SESSION_FREE_TESTS
basic_geom_smesh_without_session.py
basic_shaper_smesh_without_session.py
shaper_smesh_groups_without_session.py
basic_smesh_output_with_mc_field.py
)
SET(EXAMPLES_TESTS ${BAD_TESTS} ${GOOD_TESTS} ${SESSION_FREE_TESTS} testme.py)

View File

@ -26,6 +26,7 @@
#include "DriverMED_W_Field.h"
#include "MED_TFile.hxx"
#include "DriverMED.hxx"
#include "DriverMED_W_SMESHDS_Mesh.h"
#include "MED_Factory.hxx"
@ -236,16 +237,8 @@ SMDS_ElemIteratorPtr DriverMED_W_Field::GetOrderedElems()
return SMDS_ElemIteratorPtr( new TItIterator( iterVec ));
}
//================================================================================
/*!
* Writes a field to the file
*/
//================================================================================
Driver_Mesh::Status DriverMED_W_Field::Perform()
Driver_Mesh::Status DriverMED_W_Field::PerformInternal(MED::PWrapper& medFile)
{
if ( myFile.empty() )
return addMessage("File name not set", /*isFatal=*/true ); // 'fatal' means 'bug'
if ( myMeshId < 0 && myMeshName.empty() )
return addMessage("Mesh in file not specified", /*isFatal=*/true );
if ( _nbElemsByGeom.size() < 2 )
@ -253,11 +246,6 @@ Driver_Mesh::Status DriverMED_W_Field::Perform()
if ( !myMesh )
return addMessage("Supporting mesh not set", /*isFatal=*/true );
int version = -1, major, minor, release;
if ( MED::GetMEDVersion( myFile, major, minor, release ))
version = major * 10 + minor;
MED::PWrapper medFile = MED::CrWrapperW( myFile, version );
MED::PMeshInfo meshInfo;
if ( myMeshId > 0 )
{
@ -361,6 +349,49 @@ Driver_Mesh::Status DriverMED_W_Field::Perform()
return DRS_OK;
}
/*!
* Writes a field to the file
*/
Driver_Mesh::Status DriverMED_W_Field::Perform()
{
if ( myFile.empty() )
return addMessage("File name not set", /*isFatal=*/true ); // 'fatal' means 'bug'
int version = -1, major, minor, release;
if ( MED::GetMEDVersion( myFile, major, minor, release ))
version = major * 10 + minor;
MED::PWrapper medFile = MED::CrWrapperW( myFile, version );
return this->PerformInternal(medFile);
}
/*!
* Writes a field to a chunck of memory
*/
Driver_Mesh::Status DriverMED_W_Field_Mem::Perform()
{
void *ptr(nullptr);
std::size_t sz(0);
Driver_Mesh::Status status = Driver_Mesh::DRS_OK;
bool isClosed(false);
MED::TMemFile *tfileInst = nullptr;
char *initPtr(_data->getPointer());
mcIdType initSz(_data->getNumberOfTuples());
_data->accessToMemArray().setSpecificDeallocator(nullptr);
_data->useArray(nullptr,false,MEDCoupling::DeallocType::C_DEALLOC,0,1);
{// let braces to flush (call of MED::PWrapper myMed destructor)
tfileInst = new MED::TMemFile(initPtr,initSz,&isClosed);
MED::PWrapper myMed = MED::CrWrapperW(myFile, -1, tfileInst);
status = this->PerformInternal(myMed);
}
if(tfileInst)
{
ptr = tfileInst->getData(); sz = tfileInst->getSize();
}
_data = MEDCoupling::DataArrayByte::New();
_data->useArray(reinterpret_cast<char *>(ptr),true,MEDCoupling::DeallocType::C_DEALLOC,sz,1);
return status;
}
namespace DriverMED // Implementation of functions declared in DriverMED.hxx
{
//================================================================================

View File

@ -31,6 +31,7 @@
#include "Driver_SMESHDS_Mesh.h"
#include "SMDSAbs_ElementType.hxx"
#include "SMDS_ElemIterator.hxx"
#include "MED_Common.hxx"
#include <string>
#include <vector>
@ -64,8 +65,12 @@ class MESHDRIVERMED_EXPORT DriverMED_W_Field: public Driver_SMESHDS_Mesh
/*
* Add one field to the file
*/
virtual Status Perform();
Status Perform() override;
protected:
Status PerformInternal(MED::PWrapper& medFile);
private:
std::string _fieldName;
@ -80,4 +85,16 @@ class MESHDRIVERMED_EXPORT DriverMED_W_Field: public Driver_SMESHDS_Mesh
std::vector< std::pair< SMDSAbs_EntityType, int > > _nbElemsByGeom;
};
#include "MEDCouplingMemArray.hxx"
class MESHDRIVERMED_EXPORT DriverMED_W_Field_Mem : public DriverMED_W_Field
{
public:
DriverMED_W_Field_Mem(MEDCoupling::MCAuto<MEDCoupling::DataArrayByte> data):_data(data) { }
Status Perform() override;
MEDCoupling::MCAuto<MEDCoupling::DataArrayByte> getData() const { return _data; }
private:
MEDCoupling::MCAuto<MEDCoupling::DataArrayByte> _data;
};
#endif

View File

@ -73,7 +73,8 @@ namespace MED
class MEDWRAPPER_EXPORT TMemFile : public MEDIDTHoder
{
public:
TMemFile(bool* isClosedStatus = nullptr):MEDIDTHoder(isClosedStatus) { }
TMemFile(bool* isClosedStatus = nullptr):MEDIDTHoder(isClosedStatus) { memfile.app_image_ptr=nullptr; memfile.app_image_size=0; }
TMemFile(void *data, std::size_t sz, bool* isClosedStatus):MEDIDTHoder(isClosedStatus) { memfile.app_image_ptr=data; memfile.app_image_size=sz; }
void Open(EModeAcces theMode, TErr* theErr = nullptr) override;
void *getData() const { return memfile.app_image_ptr; }
std::size_t getSize() const { return memfile.app_image_size; }

View File

@ -90,10 +90,10 @@ namespace MED
if (this->myCount++ == 0)
{
std::string dftFileName = MEDCoupling::MEDFileWritableStandAlone::GenerateUniqueDftFileNameInMem();
memfile = MED_MEMFILE_INIT;
memfile.app_image_ptr=0;
memfile.app_image_size=0;
myFid = MEDmemFileOpen(dftFileName.c_str(),&memfile,MED_FALSE,MED_ACC_CREAT);
med_access_mode modeTmp(MED_ACC_CREAT);
if(memfile.app_image_ptr)
modeTmp = med_access_mode(theMode);
myFid = MEDmemFileOpen(dftFileName.c_str(),&memfile,MED_FALSE,modeTmp);
}
if (theErr)
*theErr = TErr(myFid);

View File

@ -4069,7 +4069,11 @@ public:
void prepareForWriting(SMESH_Mesh_i& self) { /* nothing here */ }
void exportField(SMESH_Mesh_i& self, const std::string& aMeshName, bool have0dField, SMESHDS_Mesh *meshDS, const GEOM::ListOfFields& fields, const char*geomAssocFields)
{
THROW_IK_EXCEPTION("exportField Not implemented yet for full memory !");
DriverMED_W_Field_Mem fieldWriter(_res);
fieldWriter.SetMeshName( aMeshName );
fieldWriter.AddODOnVertices( have0dField );
self.exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
_res = fieldWriter.getData();
}
public:
MEDCoupling::MCAuto<MEDCoupling::DataArrayByte> getData() { return _res; }
@ -4084,10 +4088,15 @@ CORBA::LongLong SMESH_Mesh_i::ExportPartToMEDCoupling(SMESH::SMESH_IDSource_ptr
const char* geomAssocFields,
CORBA::Double ZTolerance)
{
MEDCoupling::MCAuto<MEDCoupling::DataArrayByte> data;
SMESH_TRY;
if( !this->_gen_i->isSSLMode() )
SMESH::throwCorbaException("SMESH_Mesh_i::ExportPartToMEDCoupling : only for embedded mode !");
MEDFileMemSpeCls spe;
this->ExportPartToMEDCommon<MEDFileMemSpeCls>(spe,meshPart,auto_groups,autoDimension,fields,geomAssocFields,ZTolerance);
MEDCoupling::MCAuto<MEDCoupling::DataArrayByte> res( spe.getData() );
MEDCoupling::DataArrayByte *ret(res.retn());
data = spe.getData();
SMESH_CATCH( SMESH::throwCorbaException );
MEDCoupling::DataArrayByte *ret(data.retn());
return reinterpret_cast<CORBA::LongLong>(ret);
}

View File

@ -2355,7 +2355,10 @@ class Mesh(metaclass = MeshMeta):
z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
self.mesh.SetParameters(Parameters)
return self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension, fields, geomAssocFields, z_tolerance)
intPtr = self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension, fields, geomAssocFields, z_tolerance)
import medcoupling
dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
return medcoupling.MEDFileData.New(dab)
else:
intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension)
import medcoupling