Python & In-memory CGNS trees
Using CGNS trees for Code-coupling

Marc Poinot
Computational Fliud Dynamics and Aeroacoustics Dept.
ONERA
France

Code life cycle

Python

pyCGNS

Python/CGNS tree

   ['Transform',(1, 2, 3),[],'int[IndexDimension]'],
   ['PointRange',((1, 1, 1), (1, 9, 9)),[],'IndexRange_t'],
   ['PointRangeDonor',((21, 1, 1), (21, 9, 9)),[],'IndexRange_t']

File and memory

File and memory workflow

Diagram of file and memory workflow

pyCGNS example

   import CGNS
   import numarray as N

   x=y=z=N.zeros((3,5,7),'d')

   a=CGNS.pyCGNS("newfile.cgns",CGNS.MODE_WRITE)

   print a.error

   idb=a.basewrite("Base",3,3)
   idz=a.zonewrite(idb,"Zone 01",[3,5,7],CGNS.Structured)

   a.coordwrite(idb,idz,CGNS.RealDouble,CGNS.CoordinateX,x)
   a.coordwrite(idb,idz,CGNS.RealDouble,CGNS.CoordinateY,y)
   a.coordwrite(idb,idz,CGNS.RealDouble,CGNS.CoordinateZ,z)

   a.close()

Scripting example: Prototypes

   import CGNS
   
   f=CGNS.pyCGNS("hydro-result.cgns",CGNS.MODE_WRITE)
   
   f.basewrite("MASS2",3,3)
   f.zonewrite(1,"Block01",(2,3,4,1,2,3,0,0,0),CGNS.Structured)
   f.solwrite(1,1,"07-01-1944 06:00:00",CGNS.CellCenter)
   f.fieldwrite(1,1,1,CGNS.RealDouble,"sediment",w)
   f.goto(1,[(CGNS.Zone_t,1),(CGNS.FlowSolution_t,1),(CGNS.DataArray_t,1)])
   f.descriptorwrite("Description","Text here")
   f.descriptorwrite("Units","Text here")
   
   f.close()

Scripting example: post-processing

   from CGNS import *
   
   a=pyCGNS("result-001.cgns",MODE_MODIFY)
   
   a.goto(1,[(Zone_t,1)])
   a.linkwrite("GridCoordinates","grid.cgns","/Base/Zone/GridCoordinates")
   
   a.close()

Scripting example: pre-processing

Diagram of pre-processing scripting example

Code-coupling

Code-coupling CGNS tree

Diagram of CGNS node tree with code-coupling

Scripting example: code-coupling

   import MpCCI

   pathB="/FlatPlate/Fluid/ZoneBC/Wall:Heat/DataSet#01/NeumannData"
   pathI=pathB+"/Temperature"
   pathO=pathB+"/NormalHeatFlux"
   it=E.iteration()

   fqx=mcci.Parameter_info("Simulation_Fluid_2_Therm_Ratio",MpCCI.CCI_INT)

   xp=xw.get(E.RUNTIME_TREE)
   xf=X.retrieve(pathO,xp)
   if ( xf and ((it % fqx ) == 0 )):
       sd1=mcci.Parameter_info("Fluid_Private_Synchro_ID",MpCCI.CCI_INT)
       ZID=mcci.Parameter_info("Global_Mesh_ID",MpCCI.CCI_INT)
       BID=1
       nnodes=len(xf[1].flat)
       if ( (it % fqx ) == 0 ):
         mcci.Put_nodes(ZID,BID,171,1,nnodes,0,None,MpCCI.CCI_DOUBLE,xf)
         mcci.Reach_sync_point(sd1)

   (rC,nC)=mcci.Get_nodes(ZoneID,BoundaryID,154,1,nnodes,0,None,MpCCI.CCI_DOUBLE)
   ...
   E.update((E.RUNTIME_TREE,rt)

Scripting example: parallel

   import elsApy    as E
   from Scientific  import MPI

   communicator=MPI.world.duplicate()
   id = communicator.rank
   if   ( id == 0 ): remoteId=1
   elif ( id == 1 ): remoteId=0

   datatree=E.get(E.RUNTIME_TREE)
   temp=pickle.dumps(datatree)
   communicator.nonblocking_send(temp, remoteId, id)
   return,rank,tag=communicator.receiveString(None,None)
   result=pickle.loads(return)

   for l in result:
     if (l[0] == "RunTimeTree"):
       for ll in l[2]:
         if (ll[0] == "Rotor#Output"):  ll[0]="Stator#Input"
         if (ll[0] == "Stator#Output"): ll[0]="Rotor#Input"

   E.update(E.RUNTIME_TREE,result)

In-memory issues

Python/CGNS Tree interface

   T=CGNSTree()
   base=newBase(T,"Base",3,3)
   print T
   getChildrenNameByPath(T,"/Base/Zone-002/GridCoordinates")

   [['CGNSLibraryVersion', 2.4, [], 'CGNSLibraryVersion_t'],
    ['Base', array([3, 3]), [], 'CGNSBase_t']
   ]

Script example: Python/CGNS tree

   T=C.newCGNS()

   base=C.newBase(T,"Base",3,3)
   size=(20,10,5)

   z1=C.newZone(base,"Zone-001",size)
   C.newCoordinates(z1,"CoordinatesX",x)
   C.newCoordinates(z1,"CoordinatesY",y)

   f=open("T01.py","w+")
   f.write(str(T))
   f.close()

   clist=C.getChildrenNameByPath(T,"/Base/Zone-002/GridCoordinates")
   for c in clist:
     n=C.getByExactPath(T,"/Base/Zone-002/GridCoordinates/"+c)
     print C.nodeName(n)
     v=C.nodeValue(n)

   print C.getChildrenType(T,"CGNSBase_t")
   print C.getAllTreePath(T)
   print C.getAllTreeType(T,"Zone_t")
   print C.getAllTreeType(T,"DataArray_t")

Workflow pre/post processing

More than float arrays...