Skip to content

Commit 50a3154

Browse files
Merge pull request #125 from vincentcasseau/main
Converter: force CGNS convention when using I8/R8 (see #88)
2 parents 574f5e1 + ff4e717 commit 50a3154

File tree

2 files changed

+76
-33
lines changed

2 files changed

+76
-33
lines changed

Cassiopee/Converter/Converter/Internal.py

+39-15
Original file line numberDiff line numberDiff line change
@@ -227,24 +227,26 @@ def isChild2(start, node):
227227
def setValue(node, value=None):
228228
"""Set given value in node."""
229229
if node[3] == 'CGNSLibraryVersion_t':
230-
if isinstance(value, int) or isinstance(value, float): node[1] = numpy.array([value], 'f')
230+
if isinstance(value, (int, float)): node[1] = numpy.array([value], 'f')
231231
elif isinstance(value, numpy.ndarray): node[1] = numpy.array(value, 'f')
232232
else: raise TypeError("setValue: CGNSLibraryVersion node value should be a float.")
233233
else:
234234
if value is None: node[1] = None
235235
elif isinstance(value, numpy.ndarray):
236236
if value.flags.f_contiguous: node[1] = value
237237
else: node[1] = numpy.asfortranarray(value)
238-
elif isinstance(value, int) or isinstance(value, numpy.int32) or isinstance(value,numpy.int64) or isinstance(value,numpy.intc): node[1] = numpy.array([value], dtype=E_NpyInt)
239-
elif isinstance(value, float) or isinstance(value, numpy.float32) or isinstance(value, numpy.float64): node[1] = numpy.array([value], dtype=numpy.float64)
238+
elif isinstance(value, (int, numpy.integer)):
239+
node[1] = numpy.array([value], dtype=E_NpyInt)
240+
elif isinstance(value, (float, numpy.floating)):
241+
node[1] = numpy.array([value], dtype=numpy.float64)
240242
elif isinstance(value, str):
241243
node[1] = numpy.array([c for c in value], 'c')
242244
elif isinstance(value, list):
243245
testValue = value
244246
while isinstance(testValue, list): testValue = testValue[0]
245-
if isinstance(testValue, float) or isinstance(testValue, numpy.float32) or isinstance(testValue, numpy.float64):
247+
if isinstance(testValue, (float, numpy.floating)):
246248
node[1] = numpy.array(value, dtype=numpy.float64, order='F')
247-
elif isinstance(testValue, int) or isinstance(testValue, numpy.int32) or isinstance(testValue, numpy.int64) or isinstance(testValue,numpy.intc):
249+
elif isinstance(testValue, (int, numpy.integer)):
248250
node[1] = numpy.array(value, dtype=E_NpyInt, order='F')
249251
elif isinstance(testValue, str):
250252
if isinstance(value[0], str):
@@ -271,9 +273,9 @@ def setValue(node, value=None):
271273
elif isinstance(value, tuple):
272274
testValue = value
273275
while isinstance(testValue, tuple): testValue = testValue[0]
274-
if isinstance(testValue, float) or isinstance(testValue, numpy.float32) or isinstance(testValue, numpy.float64):
276+
if isinstance(testValue, (float, numpy.floating)):
275277
node[1] = numpy.array(value, dtype=numpy.float64, order='F')
276-
elif isinstance(testValue, int) or isinstance(testValue, numpy.int32) or isinstance(testValue, numpy.int64):
278+
elif isinstance(testValue, (int, numpy.integer)):
277279
node[1] = numpy.array(value, dtype=E_NpyInt, order='F')
278280
elif isinstance(testValue, str):
279281
if isinstance(value[0], str):
@@ -439,7 +441,7 @@ def _createNodesFromPath(t, path):
439441

440442
# -- Create a CGNS version node
441443
def createCGNSVersionNode():
442-
version = numpy.array([4.0], dtype=numpy.float32)
444+
version = numpy.array([4.0], dtype=numpy.float32) # force R4
443445
return ['CGNSLibraryVersion', version, [], 'CGNSLibraryVersion_t']
444446

445447
# -- Cree le noeud root de l'arbre
@@ -450,8 +452,7 @@ def createRootNode(name='CGNSTree', children=None):
450452
# -- Create base node named name with dim
451453
# cellDim=2 (cells surfaciques), cellDim=3 (cells volumiques)
452454
def createBaseNode(name, cellDim):
453-
a = numpy.empty((2), dtype=E_NpyInt)
454-
#a = numpy.empty((2), dtype=numpy.int32)
455+
a = numpy.empty((2), dtype=numpy.int32) # force I4
455456
a[0] = cellDim; a[1] = 3
456457
return [name, a, [], 'CGNSBase_t']
457458

@@ -639,6 +640,7 @@ def newOrdinal(value=0, parent=None):
639640
node = createNode('Ordinal', 'Ordinal_t', value=value)
640641
else: node = createUniqueChild(parent, 'Ordinal',
641642
'Ordinal_t', value=value)
643+
node[1] = node[1].astype(numpy.int32) # force I4
642644
return node
643645

644646
# -- newDiscreteData
@@ -668,6 +670,7 @@ def newElements(name='Elements', etype='UserDefined',
668670
node = createNode(name, 'Elements_t', value=[etp,eboundary])
669671
else:
670672
node = createUniqueChild(parent, name, 'Elements_t', value=[etp,eboundary])
673+
#node[1] = node[1].astype(numpy.int32) # force I4
671674
newDataArray('ElementConnectivity', econnectivity, parent=node)
672675
#if erange is None: erange = numpy.ones(2, dtype=numpy.int32)
673676
newPointRange('ElementRange', erange, parent=node)
@@ -865,7 +868,7 @@ def newAverageInterface(value='Null', parent=None):
865868

866869
# -- newZoneSubRegion
867870
def newZoneSubRegion(name='SubRegion', pointRange=None, pointList=None,
868-
bcName=None, gcName=None, gridLocation=None, parent=None):
871+
bcName=None, gcName=None, gridLocation=None, parent=None):
869872
"""Create a new ZoneSubRegion node."""
870873
if parent is None:
871874
node = createNode(name, 'ZoneSubRegion_t')
@@ -1072,7 +1075,8 @@ def newBaseIterativeData(name='BaseIterativeData', nsteps=0,
10721075
node = createNode(name, 'BaseIterativeData_t', value=nsteps)
10731076
else: node = createUniqueChild(parent, name, 'BaseIterativeData_t',
10741077
value=nsteps)
1075-
newDataArray(itype, value=numpy.arange(1,nsteps+1, dtype=E_NpyInt), parent=node)
1078+
newDataArray(itype, value=numpy.arange(1,nsteps+1, dtype=numpy.int32),
1079+
parent=node) # force I4
10761080
return node
10771081

10781082
# -- newZoneIterativeData
@@ -1125,6 +1129,7 @@ def newConvergenceHistory(name='GlobalConvergenceHistory',
11251129
node = createNode(name, 'ConvergenceHistory_t', value=value)
11261130
else: node = createUniqueChild(parent, name, 'ConvergenceHistory_t',
11271131
value=value)
1132+
node[1] = node[1].astype(numpy.int32) # force I4
11281133
return node
11291134

11301135
# -- newFamily (zones)
@@ -2615,7 +2620,7 @@ def getSizeOf(a):
26152620
# -- Conversion zones, bases, listes de zones <-> tree + noms + ranges --
26162621
#==============================================================================
26172622

2618-
# -- Converti un noeud zone, liste de zones, base, liste de bases,
2623+
# -- Convertit un noeud zone, liste de zones, base, liste de bases,
26192624
# tree en pyTree (avec les memes adresses)
26202625
# Retourne (t, ntype) avec ntype=1 (zone), 2 (liste de zones), 3 (tree),
26212626
# 4 (base), 5 (liste de bases)
@@ -2642,7 +2647,7 @@ def node2PyTree(node):
26422647
else: t = node
26432648
return t, ntype
26442649

2645-
# -- Converti un pyTree en noeud de type fourni (avec les memes adresses)
2650+
# -- Convertit un pyTree en noeud de type fourni (avec les memes adresses)
26462651
# IN: type=1 (zone), 2 (liste de zones), 3 (tree), 4 (base), 5 (liste de bases)
26472652
def pyTree2Node(t, type):
26482653
if type == 1: # zone: renvoie une zone ou une liste de zones
@@ -2971,6 +2976,7 @@ def createZoneNode(name, array, array2=[],
29712976
neltstot = 0
29722977
for c in range(len(etype)):
29732978
i = numpy.empty((2), dtype=E_NpyInt); i[0] = etype[c]; i[1] = 0
2979+
#i = numpy.empty((2), dtype=numpy.int32); i[0] = etype[c]; i[1] = 0 # force I4
29742980
if etype[c] == 22: # Faces->Nodes and Elements->Faces connectivities (NGON array)
29752981
if isinstance(array[2], list): # Array2 or array3
29762982
setElementConnectivity2(zone, array)
@@ -3962,6 +3968,7 @@ def setElementConnectivity(z, array):
39623968
etype, stype = eltName2EltNo(array[3])
39633969
GENodes = getElementNodes(z)
39643970
i = numpy.empty((2), dtype=E_NpyInt); i[0] = etype; i[1] = 0
3971+
#i = numpy.empty((2), dtype=numpy.int32); i[0] = etype; i[1] = 0 # force I4
39653972
if GENodes == []:
39663973
if etype != 22 and etype != 23: # Elements->Nodes connectivities
39673974
z[2].append(['GridElements', i, [], 'Elements_t'])
@@ -3993,6 +4000,7 @@ def setElementConnectivity(z, array):
39934000
# Creation du noeud NFACE_n: connectivite Elements->Faces
39944001
etype,stype = eltName2EltNo('NFACE')
39954002
i2 = numpy.empty((2), E_NpyInt); i2[0] = etype; i2[1] = 0
4003+
#i2 = numpy.empty((2), numpy.int32); i2[0] = etype; i2[1] = 0 # force I4
39964004
info.append(['NFaceElements', i2, [], 'Elements_t'])
39974005
info2 = info[len(info)-1][2]
39984006
# Size of ElementRange
@@ -4045,6 +4053,7 @@ def setElementConnectivity(z, array):
40454053
# Creation du noeud NFACE_n : connectivite Elements->Faces
40464054
etype, stype = eltName2EltNo('NFACE')
40474055
i2 = numpy.empty((2), E_NpyInt); i2[0] = etype; i2[1] = 0
4056+
#i2 = numpy.empty((2), numpy.int32); i2[0] = etype; i2[1] = 0 # force I4
40484057
info.append(['NFaceElements', i2, [], 'Elements_t'])
40494058
info2 = info[len(info)-1][2]
40504059
# Size of ElementRange
@@ -4074,6 +4083,7 @@ def setElementConnectivity2(z, array):
40744083
for nc, gc in enumerate(array[2]):
40754084
etype, stype = eltName2EltNo(estring[nc])
40764085
i = numpy.empty((2), E_NpyInt); i[0] = etype; i[1] = 0
4086+
#i = numpy.empty((2), numpy.int32); i[0] = etype; i[1] = 0 # force I4
40774087
if nc in cnames: cname = cnames[nc]
40784088
elif nc == 0: cname = 'GridElements'
40794089
else: cname = 'GridElements%d'%nc
@@ -4085,6 +4095,7 @@ def setElementConnectivity2(z, array):
40854095
_updateElementRange(z)
40864096
else: # Faces->Nodes and Elements->Faces connectivities (NGON or NFACE)
40874097
i = numpy.empty((2), E_NpyInt); i[0] = etype0; i[1] = 0
4098+
#i = numpy.empty((2), numpy.int32); i[0] = etype0; i[1] = 0 # force I4
40884099
info = z[2]
40894100
# Creation du noeud NGON_n: connectivite Faces->Noeuds
40904101
info.append(['NGonElements', i, [], 'Elements_t'])
@@ -4105,6 +4116,7 @@ def setElementConnectivity2(z, array):
41054116
# Creation du noeud NFACE_n: connectivite Elements->Faces
41064117
etype,stype = eltName2EltNo('NFACE')
41074118
i2 = numpy.empty((2), E_NpyInt); i2[0] = etype; i2[1] = 0
4119+
#i2 = numpy.empty((2), numpy.int32); i2[0] = etype; i2[1] = 0 # force I4
41084120
info.append(['NFaceElements', i2, [], 'Elements_t'])
41094121
info2 = info[len(info)-1][2]
41104122
# Size of ElementRange
@@ -4275,6 +4287,7 @@ def _adaptPE2NFace(t, remove=True):
42754287
cFE = parentElt[1]
42764288
cNFace, off, nelts = converter.adaptPE2NFace(cFE, api)
42774289
p = createUniqueChild(z, 'NFaceElements', 'Elements_t', value=[23,0])
4290+
#p[1] = p[1].astype(numpy.int32) # force I4
42784291
createUniqueChild(p, 'ElementRange', 'IndexRange_t', value=[1,nelts])
42794292
createUniqueChild(p, 'ElementConnectivity', 'DataArray_t', value=cNFace)
42804293
if api < 3: createUniqueChild(p, 'ElementIndex', 'DataArray_t', value=off)
@@ -4465,16 +4478,19 @@ def _adaptBCFace2BCC(t, remove=True):
44654478
(BAR,TRI,QUAD) = converter.adaptBCFace2BCC(a1[1], connect[1], dims[3])
44664479
if BAR.size > 0:
44674480
n = createNode('Bnd_BAR', 'Elements_t', value=[2,BAR.size])
4481+
#n[1] = n[1].astype(numpy.int32) # force I4
44684482
_addChild(z, n)
44694483
createChild(n, 'ElementRange', 'IndexRange_t', value=[1,BAR.size])
44704484
createChild(n, 'ElementConnectivity', 'DataArray_t', value=BAR)
44714485
if TRI.size > 0:
44724486
n = createNode('Bnd_TRI', 'Elements_t', value=[3,TRI.size])
4487+
#n[1] = n[1].astype(numpy.int32) # force I4
44734488
_addChild(z, n)
44744489
createChild(n, 'ElementRange', 'IndexRange_t', value=[1,TRI.size])
44754490
createChild(n, 'ElementConnectivity', 'DataArray_t', value=TRI)
44764491
if QUAD.size > 0:
44774492
n = createNode('Bnd_QUAD', 'Elements_t', value=[4,QUAD.size])
4493+
#n[1] = n[1].astype(numpy.int32) # force I4
44784494
_addChild(z, n)
44794495
createChild(n, 'ElementRange', 'IndexRange_t', value=[1,QUAD.size])
44804496
createChild(n, 'ElementConnectivity', 'DataArray_t', value=QUAD)
@@ -4627,6 +4643,7 @@ def _fixNGon(t, remove=False, breakBE=True, convertMIXED=True, addNFace=True):
46274643
cFE = cFE.reshape((sh[0]//2,2), order='F'); parentElt[1] = cFE
46284644
cNFace, off, nelts = converter.adaptPE2NFace(cFE, api)
46294645
p = createUniqueChild(z, 'NFaceElements', 'Elements_t', value=[23,0])
4646+
#p[1] = p[1].astype(numpy.int32) # force I4
46304647
createUniqueChild(p, 'ElementRange', 'IndexRange_t', value=[1,nelts])
46314648
createUniqueChild(p, 'ElementConnectivity', 'DataArray_t', value=cNFace)
46324649
if api < 3: createUniqueChild(p, 'ElementIndex', 'DataArray_t', value=off)
@@ -5489,6 +5506,12 @@ def getGlob2Loc(z):
54895506
if b is not None: b = getValue(b)
54905507
return b, a
54915508

5509+
# Edit the type of the value for each node
5510+
def _adaptValueType(nodes, newType):
5511+
if nodes is not None:
5512+
for n in nodes:
5513+
n[1] = n[1].astype(newType)
5514+
54925515
# change les numpy R4 en R8 et les numpy i8 en i4
54935516
# dans FlowSolution/Coordinates et Elements_t
54945517
def _adaptTypes(t, convertR42R8=True, convertI82I4=True, convertR82R4=False, convertI42I8=False):
@@ -5561,7 +5584,8 @@ def _adaptTypes(t, convertR42R8=True, convertI82I4=True, convertR82R4=False, con
55615584
pt2[:] = pt1[:]
55625585
nodes = getNodesFromType1(z, 'Elements_t')
55635586
for no in nodes:
5564-
if no[1] is not None and no[1].dtype == numpy.int32:
5587+
# Elements_t forced to I4
5588+
if no[1] is not None and no[1].dtype == numpy.int32: # TODO comment out this paragraph
55655589
pt1 = no[1].ravel('k')
55665590
no[1] = numpy.empty(no[1].shape, dtype=numpy.int64, order='F')
55675591
pt2 = no[1].ravel('k')

Cassiopee/Converter/Converter/PyTree.py

+37-18
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,7 @@ def _rmNodes(z, name):
938938
# Upgrade tree (applique apres lecture)
939939
def _upgradeTree(t, uncompress=True, oldcompress=False):
940940
#Internal._adaptTypes(t)
941+
_relaxCGNSProfile__(t)
941942
Internal._correctPyTree(t, level=10) # force CGNS names
942943
Internal._correctPyTree(t, level=2) # force unique name
943944
Internal._correctPyTree(t, level=7) # create familyNames
@@ -1162,27 +1163,45 @@ def checkLinks__(links, t):
11621163

11631164
# Force periodic nodes to be R4 (old CGNS norm)
11641165
def _forceR4PeriodicNodes__(t):
1165-
nodes = Internal.getNodesFromName(t, "RotationCenter")
1166-
nodes += Internal.getNodesFromName(t, "RotationAngle")
1167-
nodes += Internal.getNodesFromName(t, "RotationRateVector")
1168-
nodes += Internal.getNodesFromName(t, "Translation")
1169-
for n in nodes:
1170-
n[1] = n[1].astype(numpy.float32)
1166+
periodicNodeNames = ["RotationCenter", "RotationAngle", "RotationRateVector",
1167+
"Translation"]
1168+
for name in periodicNodeNames:
1169+
nodes = Internal.getNodesFromName(t, name)
1170+
Internal._adaptValueType(nodes, numpy.float32)
11711171
return None
11721172

1173-
# Force specific type nodes imposed by v4 CGNS norm
1173+
# Force type of specific nodes as prescribed by v4 CGNS norm
11741174
def _forceCGNSProfile__(t):
1175-
# version node (R4)
1176-
n = Internal.getNodeFromName1(t, "CGNSVersion")
1175+
# CGNS version (R4)
1176+
n = Internal.getNodeFromType1(t, "CGNSVersion_t")
11771177
if n is not None: n[1] = n[1].astype(numpy.float32)
1178-
# base node (I4)
1179-
nodes = Internal.getNodesFromName1(t, "CGNSBase_t")
1180-
for n in nodes:
1181-
n[1] = n[1].astype(numpy.int32)
1182-
# Elements_t (i4)
1183-
nodes = Internal.getNodesFromName2(t, "Elements_t")
1184-
for n in nodes:
1185-
n[1] = n[1].astype(numpy.int32)
1178+
#if FORCER4PERIODIC: _forceR4PeriodicNodes__(t)
1179+
1180+
# CGNSBase_t, Elements_t, Rind_t, BaseIterativeData_t, Ordinal_t,
1181+
# ConvergenceHistory_t (I4)
1182+
nodes = Internal.getNodesFromType1(t, "CGNSBase_t")
1183+
if nodes is not None:
1184+
for n in nodes: n[1] = n[1].astype(numpy.int32)
1185+
nodeTypes2 = ["Elements_t", "BaseIterativeData_t", "ConvergenceHistory_t"]
1186+
for ntype in nodeTypes2:
1187+
nodes = Internal.getNodesFromType2(t, ntype)
1188+
Internal._adaptValueType(nodes, numpy.int32)
1189+
zones = Internal.getZones(t)
1190+
for z in zones:
1191+
#nodes = Internal.getNodesFromType1(z, "Rind_t")
1192+
#Internal._adaptValueType(nodes, numpy.int32)
1193+
nodes = Internal.getNodesFromType(z, "Ordinal_t")
1194+
Internal._adaptValueType(nodes, numpy.int32)
1195+
return None
1196+
1197+
# Relax type of specific nodes as prescribed by v4 CGNS norm
1198+
def _relaxCGNSProfile__(t):
1199+
if Internal.E_NpyInt == numpy.int32: return None
1200+
# Rind_t cannot be forced to I4 internally
1201+
zones = Internal.getZones(t)
1202+
for z in zones:
1203+
nodes = Internal.getNodesFromType1(z, "Rind_t")
1204+
Internal._adaptValueType(nodes, Internal.E_NpyInt)
11861205
return None
11871206

11881207
# -- convertPyTree2File
@@ -1191,7 +1210,6 @@ def convertPyTree2File(t, fileName, format=None, isize=4, rsize=8,
11911210
"""Write a pyTree to a file.
11921211
Usage: convertPyTree2File(t, fileName, format, options)"""
11931212
if t == []: print('Warning: convertPyTree2File: nothing to write.'); return
1194-
#if FORCER4PERIODIC: _forceR4PeriodicNodes__(t)
11951213
if links is not None: links = checkLinks__(links, t)
11961214
if format is None:
11971215
format = Converter.convertExt2Format__(fileName)
@@ -1200,6 +1218,7 @@ def convertPyTree2File(t, fileName, format=None, isize=4, rsize=8,
12001218
tp, ntype = Internal.node2PyTree(t)
12011219
Internal._adaptZoneNamesForSlash(tp)
12021220
Internal._correctBaseZonesDim(t, splitBases=False)
1221+
_forceCGNSProfile__(tp)
12031222
Converter.converter.convertPyTree2File(tp[2], fileName, format, links)
12041223
elif format == 'bin_pickle':
12051224
try: import cPickle as pickle

0 commit comments

Comments
 (0)