-// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2020 CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
// File : DriverCGNS_Read.cxx
// Created : Thu Jun 30 10:33:31 2011
// Author : Edward AGAPOV (eap)
+//#define _DEBUG_
+#include <utilities.h>
#include "DriverCGNS_Read.hxx"
#include "SMESHDS_Group.hxx"
#include "SMESHDS_Mesh.hxx"
#include "SMESH_Comment.hxx"
+#include "SMESH_TypeDefs.hxx"
#include <gp_XYZ.hxx>
#include <map>
+
#if CGNS_VERSION < 3100
# define cgsize_t int
#endif
}
bool IsStructured() const { return ( _type == CGNS_ENUMV( Structured )); }
int IndexSize() const { return IsStructured() ? _meshDim : 1; }
- string ReadZonesConnection(int file, int base, const map< string, TZoneData >& zonesByName);
+ string ReadZonesConnection(int file, int base,
+ const map< string, TZoneData >& zonesByName,
+ SMESHDS_Mesh* mesh);
void ReplaceNodes( cgsize_t* ids, int nbIds, int idShift = 0 ) const;
// Methods for a structured zone
ids[2] = ids[0] + _sizeX + 1;
ids[3] = ids[0] + ( k==_sizeZ ? _sizeX : 1);
}
- void IEdgeNodes( int i, int j, int k, cgsize_t* ids ) const // edge perpendiculaire to X (2D)
+ void IEdgeNodes( int i, int j, int /*k*/, cgsize_t* ids ) const // edge perpendiculaire to X (2D)
{
ids[0] = NodeID( i, j, 0 );
ids[1] = ids[0] + _sizeX;
}
- void JEdgeNodes( int i, int j, int k, cgsize_t* ids ) const
+ void JEdgeNodes( int i, int j, int /*k*/, cgsize_t* ids ) const
{
ids[0] = NodeID( i, j, 0 );
ids[1] = ids[0] + 1;
int _beg[3], _end[3], _cur[3], _dir[3], _dim;
bool _more;
public:
- TPointRangeIterator( const cgsize_t* range, int dim ):_dim(dim)
+ TPointRangeIterator( const cgsize_t* range, int dim ):
+ _beg{0,0,0}, _end{0,0,0}, _cur{0,0,0}, _dir{0,0,0}, _dim(dim), _more(false)
{
- _more = false;
for ( int i = 0; i < dim; ++i )
{
_beg[i] = range[i];
if ( _end[i] - _beg[i] )
_more = true;
}
-// for ( int i = dim; i < 3; ++i )
-// _cur[i] = _beg[i] = _end[i] = _dir[i] = 0;
}
bool More() const
{
//gp_XYZ End() const { return gp_XYZ( _end[0]-1, _end[1]-1, _end[2]-1 ); }
};
+ //================================================================================
+ /*!
+ * \brief Checks if the two arrays of node IDs describe nodes with equal coordinates
+ */
+ //================================================================================
+
+ bool isEqualNodes( const int* nIds1, const int* nIds2, int nbNodes, SMESHDS_Mesh* mesh )
+ {
+ if ( nbNodes > 0 )
+ {
+ SMESH_TNodeXYZ nn1[2], nn2[2];
+ nn1[0] = mesh->FindNode( nIds1[0] );
+ nn2[0] = mesh->FindNode( nIds2[0] );
+ if ( !nn1[0]._node || !nn2[0]._node )
+ return false;
+ double dist1 = ( nn1[0] - nn2[0] ).Modulus();
+ double dist2 = 0, tol = 1e-7;
+ if ( nbNodes > 1 )
+ {
+ nn1[1] = mesh->FindNode( nIds1[1] );
+ nn2[1] = mesh->FindNode( nIds2[1] );
+ if ( !nn1[1]._node || !nn2[1]._node )
+ return false;
+ dist2 = ( nn1[1] - nn2[1] ).Modulus();
+ tol = 1e-5 * ( nn1[0] - nn1[1] ).Modulus();
+ }
+ return ( dist1 < tol && dist2 < tol );
+ }
+ return false;
+ }
+
//================================================================================
/*!
* \brief Reads zone interface connectivity
string TZoneData::ReadZonesConnection( int file,
int base,
- const map< string, TZoneData >& zonesByName)
+ const map< string, TZoneData >& zonesByName,
+ SMESHDS_Mesh* mesh)
{
string error;
continue; // this interface already read
}
}
+ // check if range and donorRange describe the same nodes
+ {
+ int ids1[2], ids2[2], nbN = 0;
+ TPointRangeIterator rangeIt1bis( range, _meshDim );
+ index1 = rangeIt1bis.Next();
+ index2 = T * ( index1 - begin1 ) + begin2;
+ ids1[0] = NodeID( index1 );
+ ids2[0] = zone2.NodeID( index2 );
+ ++nbN;
+ if ( rangeIt1bis.More() )
+ {
+ index1 = rangeIt1bis.Next();
+ index2 = T * ( index1 - begin1 ) + begin2;
+ ids1[1] = NodeID( index1 );
+ ids2[1] = zone2.NodeID( index2 );
+ ++nbN;
+ }
+ if ( !isEqualNodes( &ids1[0], &ids2[0], nbN, mesh ))
+ continue;
+ }
while ( rangeIt1.More() )
{
index1 = rangeIt1.Next();
{
for ( int isThisZone = 0; isThisZone < 2; ++isThisZone )
{
- const TZoneData& zone = isThisZone ? *this : zone2;
+ const TZoneData& zone = isThisZone ? *this : zone2;
CGNS_ENUMT(PointSetType_t) type = isThisZone ? ptype : donorPtype;
vector< cgsize_t >& points = isThisZone ? ids : donorIds;
if ( type == CGNS_ENUMV( PointRange ))
points[i] += zone._nodeIdShift;
}
}
- for ( size_t i = 0; i < ids.size() && i < donorIds.size(); ++i )
- _nodeReplacementMap.insert( make_pair( ids[i], donorIds[i] ));
+ size_t nbN = std::min( ids.size(), donorIds.size());
+ if ( isEqualNodes( &ids[0], &donorIds[0], nbN, mesh ))
+ for ( size_t i = 0; i < nbN; ++i )
+ _nodeReplacementMap.insert( make_pair( ids[i], donorIds[i] ));
}
else
{
if ( !_nodeReplacementMap.empty() )
{
map< int, int >::const_iterator it, end = _nodeReplacementMap.end();
- for ( size_t i = 0; i < nbIds; ++i )
+ for ( int i = 0; i < nbIds; ++i )
if (( it = _nodeReplacementMap.find( ids[i] + idShift)) != end )
ids[i] = it->second;
else
}
else if ( idShift )
{
- for ( size_t i = 0; i < nbIds; ++i )
+ for ( int i = 0; i < nbIds; ++i )
ids[i] += idShift;
}
}
Driver_Mesh::Status DriverCGNS_Read::Perform()
{
+ MESSAGE("DriverCGNS_Read::Perform");
myErrorMessages.clear();
Status aResult;
// read nb of meshes (CGNSBase_t)
if ( myMeshId < 0 || myMeshId >= GetNbMeshes(aResult))
return addMessage( SMESH_Comment("Invalid mesh index :") << myMeshId );
+ MESSAGE("NbMeshes: " << GetNbMeshes(aResult));
// read a name and a dimension of the mesh
const int cgnsBase = myMeshId + 1;
<< " in mesh '" << meshName << "'");
myMeshName = meshName;
+ MESSAGE("myMeshName: " << myMeshName);
+
// read nb of domains (Zone_t) in the mesh
int nbZones = 0;
if ( nbZones < 1 )
return addMessage( SMESH_Comment("Empty mesh: '") << meshName << "'");
+ MESSAGE("nbZones: " << nbZones);
// read the domains (zones)
// ------------------------
zone._nodeIdShift = meshInfo.NbNodes();
zone._elemIdShift = meshInfo.NbElements();
zone.SetSizeAndDim( sizes, meshDim );
+ MESSAGE(" zone name: " << name);
// mesh type of the zone
if ( cg_zone_type ( _fn, cgnsBase, iZone, &zone._type) != CG_OK) {
switch ( zone._type )
{
case CGNS_ENUMV( Unstructured ):
+ MESSAGE(" zone type: unstructured");
+ break;
case CGNS_ENUMV( Structured ):
+ MESSAGE(" zone type: structured");
break;
case CGNS_ENUMV( ZoneTypeNull ):
addMessage( "Meshes with ZoneTypeNull are not supported");
// -----------
// Read nodes
// -----------
-
+ MESSAGE(" Read nodes");
if ( cg_ncoords( _fn, cgnsBase, iZone, &spaceDim) != CG_OK ) {
addMessage( cg_get_error() );
continue;
}
// read coordinates
+ MESSAGE(" Read coordinates");
cgsize_t rmin[3] = {1,1,1}; // range of nodes to read
cgsize_t rmax[3] = {1,1,1};
int nbNodes = rmax[0] = zone._sizes[0];
coords[ c-1 ].resize( nbNodes, 0.0 );
// create nodes
+ MESSAGE(" create nodes");
try {
for ( int i = 0; i < nbNodes; ++i )
myMesh->AddNodeWithID( coords[0][i], coords[1][i], coords[2][i], i+1+zone._nodeIdShift );
}
// Read connectivity between zones. Nodes of the zone interface will be
- // replaced withing the zones read later
- string err = zone.ReadZonesConnection( _fn, cgnsBase, zonesByName );
+ // replaced within the zones read later
+ string err = zone.ReadZonesConnection( _fn, cgnsBase, zonesByName, myMesh );
if ( !err.empty() )
addMessage( err );
// --------------
// Read elements
// --------------
+ MESSAGE(" read elements");
if ( zone.IsStructured())
{
int nbI = zone._sizeX - 1, nbJ = zone._sizeY - 1, nbK = zone._sizeZ - 1;
// read element data
+ MESSAGE(" read element data");
CGNS_ENUMT( ElementType_t ) elemType;
cgsize_t start, end; // range of ids of elements of a zone
cgsize_t eDataSize = 0;
int nbBnd, parent_flag;
for ( int iSec = 1; iSec <= nbSections; ++iSec )
{
+ MESSAGE(" section " << iSec << " of " << nbSections);
if ( cg_section_read( _fn, cgnsBase, iZone, iSec, name, &elemType,
&start, &end, &nbBnd, &parent_flag) != CG_OK ||
cg_ElementDataSize( _fn, cgnsBase, iZone, iSec, &eDataSize ) != CG_OK )
}
// store elements
+ MESSAGE(" store elements");
int pos = 0, cgnsNbNodes = 0, elemID = start + zone._elemIdShift;
cg_npe( elemType, &cgnsNbNodes ); // get nb nodes by element type
curAddElemFun = addElemFuns[ elemType ];
{
const bool reverse = ( elemData[ pos-1 ] < 0 );
const int iQuad = face->IsQuadratic() ? 1 : 0;
- SMDS_ElemIteratorPtr nIter = face->interlacedNodesElemIterator();
+ SMDS_NodeIteratorPtr nIter = face->interlacedNodesIterator();
faceNodes.assign( SMDS_MeshElement::iterator( nIter ),
SMDS_MeshElement::iterator());
if ( iQuad && reverse )
// -------------------------------------------
// Read Boundary Conditions into SMESH groups
// -------------------------------------------
+
+ MESSAGE(" read Boundary Conditions");
int nbBC = 0;
if ( cg_nbocos( _fn, cgnsBase, iZone, &nbBC) == CG_OK )
{
CGNS_ENUMT( DataType_t ) normDataType;
cgsize_t nbPnt, normFlag;
int normIndex[3], nbDS;
+ MESSAGE(" nbBC: " << nbBC);
for ( int iBC = 1; iBC <= nbBC; ++iBC )
{
+ MESSAGE(" iBC: " << iBC);
if ( cg_boco_info( _fn, cgnsBase, iZone, iBC, name, &bcType, &psType,
&nbPnt, normIndex, &normFlag, &normDataType, &nbDS ) != CG_OK )
{
addMessage( cg_get_error() );
continue;
}
+ MESSAGE(" iBC info OK: " << iBC);
vector< cgsize_t > ids( nbPnt * zone.IndexSize() );
CGNS_ENUMT( GridLocation_t ) location;
if ( cg_boco_read( _fn, cgnsBase, iZone, iBC, &ids[0], NULL ) != CG_OK ||
if ( zone.IsStructured() )
{
int axis = 0; // axis perpendiculaire to which boundary elements are oriented
- if ( ids.size() >= meshDim * 2 )
+ if ( (int) ids.size() >= meshDim * 2 )
{
for ( ; axis < meshDim; ++axis )
if ( ids[axis] - ids[axis+meshDim] == 0 )
PGetNodesFun getNodesFun = 0;
if ( elemType == SMDSAbs_Face && meshDim == 3 )
switch ( axis ) {
- case 0: getNodesFun = & TZoneData::IFaceNodes;
- case 1: getNodesFun = & TZoneData::JFaceNodes;
- case 2: getNodesFun = & TZoneData::KFaceNodes;
+ case 0: getNodesFun = & TZoneData::IFaceNodes; break;
+ case 1: getNodesFun = & TZoneData::JFaceNodes; break;
+ case 2: getNodesFun = & TZoneData::KFaceNodes; break;
}
else if ( elemType == SMDSAbs_Edge && meshDim == 2 )
switch ( axis ) {
- case 0: getNodesFun = & TZoneData::IEdgeNodes;
- case 1: getNodesFun = & TZoneData::JEdgeNodes;
+ case 0: getNodesFun = & TZoneData::IEdgeNodes; break;
+ case 1: getNodesFun = & TZoneData::JEdgeNodes; break;
}
if ( !getNodesFun )
{
PGetNodesFun getNodesFun = 0;
if ( elemType == SMDSAbs_Face )
switch ( axis ) {
- case 0: getNodesFun = & TZoneData::IFaceNodes;
- case 1: getNodesFun = & TZoneData::JFaceNodes;
- case 2: getNodesFun = & TZoneData::KFaceNodes;
+ case 0: getNodesFun = & TZoneData::IFaceNodes; break;
+ case 1: getNodesFun = & TZoneData::JFaceNodes; break;
+ case 2: getNodesFun = & TZoneData::KFaceNodes; break;
}
else if ( elemType == SMDSAbs_Edge && meshDim == 2 )
switch ( axis ) {
- case 0: getNodesFun = & TZoneData::IEdgeNodes;
- case 1: getNodesFun = & TZoneData::JEdgeNodes;
+ case 0: getNodesFun = & TZoneData::IEdgeNodes; break;
+ case 1: getNodesFun = & TZoneData::JEdgeNodes; break;
}
if ( !getNodesFun )
{
PAddElemFun addElemFun = 0;
switch ( meshDim ) {
- case 1: addElemFun = & add_BAR_2;
- case 2: addElemFun = & add_QUAD_4;
- case 3: addElemFun = & add_HEXA_8;
+ case 1: addElemFun = & add_BAR_2; break;
+ case 2: addElemFun = & add_QUAD_4; break;
+ case 3: addElemFun = & add_HEXA_8; break;
}
int elemID = meshInfo.NbElements();
const SMDS_MeshElement* elem = 0;
if ( psType == CGNS_ENUMV( PointRange ) && ids.size() == 2 )
{
- for ( size_t i = ids[0]; i <= ids[1]; ++i )
+ for ( cgsize_t i = ids[0]; i <= ids[1]; ++i )
if ( const SMDS_MeshElement* e = myMesh->FindElement( i ))
groupDS.Add( e );
}
} // loop on BCs of the zone
}
- else
+ else addMessage( cg_get_error() );
+
+
+ MESSAGE(" read flow solutions");
+ int nsols = 0;
+ if ( cg_nsols( _fn, cgnsBase, iZone, &nsols) == CG_OK )
{
- addMessage( cg_get_error() );
+ MESSAGE(" nb flow solutions: " << nsols);
+ }
+ else addMessage( cg_get_error() );
+
+ MESSAGE(" read discrete data");
+ int nbdiscrete = 0;
+ if ( cg_ndiscrete( _fn, cgnsBase, iZone, &nbdiscrete) == CG_OK )
+ {
+ MESSAGE(" nb discrete data: " << nbdiscrete);
+ char nameDiscrete[CGNS_NAME_SIZE];
+ for (int idisc = 1; idisc <= nbdiscrete; idisc++)
+ {
+ if ( cg_discrete_read( _fn, cgnsBase, iZone, idisc, nameDiscrete) == CG_OK )
+ {
+ MESSAGE(" discrete data #"<< idisc << " name: " << nameDiscrete);
+ PointSetType_t ptset_type;
+ cgsize_t npnts;
+ if ( cg_discrete_ptset_info( _fn, cgnsBase, iZone, idisc, &ptset_type, &npnts) == CG_OK )
+ {
+ MESSAGE(" discrete data #"<< idisc << " npnts: " << npnts);
+ }
+ else addMessage( cg_get_error() );
+ }
+ else addMessage( cg_get_error() );
+ }
+ }
+ else addMessage( cg_get_error() );
+
+
+ MESSAGE(" read subregions");
+ int nbSubrg = 0;
+ if ( cg_nsubregs( _fn, cgnsBase, iZone, &nbSubrg) == CG_OK )
+ {
+ MESSAGE(" nb subregions: " << nbSubrg);
}
+ else addMessage( cg_get_error() );
+
+ MESSAGE(" end zone");
} // loop on the zones of a mesh
+ MESSAGE("read families");
+ int nbFam = 0;
+ if ( cg_nfamilies( _fn, cgnsBase, &nbFam) == CG_OK )
+ {
+ MESSAGE("nb families: " << nbFam);
+ }
+ else addMessage( cg_get_error() );
+
+
// ------------------------------------------------------------------------
// Make groups for multiple zones and remove free nodes at zone interfaces
map< string, TZoneData >::iterator nameZoneIt = zonesByName.begin();
for ( ; nameZoneIt != zonesByName.end(); ++nameZoneIt )
{
+ MESSAGE("nameZone: " << nameZoneIt->first);
TZoneData& zone = nameZoneIt->second;
if ( zone._nbElems == 0 ) continue;
if ( zone._nbElems == meshInfo.NbElements() ) break; // there is only one non-empty zone
aResult = myErrorMessages.empty() ? DRS_OK : DRS_WARN_SKIP_ELEM;
+ myMesh->Modified();
+ myMesh->CompactMesh();
+ MESSAGE("end perform");
return aResult;
}