Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
pyCGNS - CGNS Python binding Release 2.0 Marc Poinot Feb. 29, 2004 ONERA DSNA/ELSA BP 72, 29 avenue de la Division Leclerc F-92322 CHATILLON CEDEX France E-mail: [email protected] c 2001, 2002, 2003, 2004 ONERA, France Copyright All rights reserved. Abstract The pyCGNS package is a Python binding to the CGNS libraries. These libraries are dedicated to the management of a standardized Computational Fluid Dynamics database format. The package includes both a wrapper on top of the ADF libraries and a wrapper on top of the MLL (i.e. Mid-LeveL) libraries. There is a set of tests, demos and tools, all written in Python and using pyCGNS. CONTENTS 1 Introduction 1.1 About CGNS . . . . 1.2 Scope of the binding 1.3 Installation . . . . . 1.4 Package description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1 2 2 3 CGNS package classes 2.1 Quick start . . . . 2.2 Using ADF class . 2.3 Using MLL class . 2.4 Using SIDS classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 7 8 10 11 3 Tools 3.1 cgp: parsing trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Stampnode tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3 cgl: listing files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 15 16 16 4 Other demos and tests 4.1 Code examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 User’s Guide to CGNS examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3 Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 19 20 20 2 . . . . A pyADF class 21 B pyCGNS class B.1 Dictionnaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.2 Class methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 23 24 C User’s Guide to CGNS examples C.1 write grid str.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C.2 read grid str.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 41 42 D Passing arrays from/to fortran or C code D.1 Solver pre-processing example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D.2 Solver post-processing example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D.3 An integrated solver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 43 43 43 Index 45 i ii CHAPTER ONE Introduction This package is released under the GNU Public License. 1.1 About CGNS CGNS is a data format for Computational Fluid Dynamics. The data structures and their semantic are described into the SIDS document. The storage format is ADF, that is a non-proprietary and portable file format. A CGNS file is called a CGNS database, and its structure is a tree of valued nodes. The nodes have several predefined attributes used to store informational data (such as a text describing some sub-tree) or actual CFD data (such as a very large array of float numbers). Some special nodes, called links, can refer to another CGNS database, thus allowing the reuse of data shared amongst trees. fig/cgnstree.eps Figure 1.1: CGNS database tree The following acronyms are used: • CGNS CFD General Notation System • CFD Computational Fluid Dynamics • ADF Advanced Data Format • MLL Mid-level library • OOL Object-oriented library • SIDS Standard Interface Data Specification 1 The CGNS library provide the developper with a mapping of the SIDS to the ADF file format, either with a C language binding or a Fortran language binding. The MLL is a set of creation function, that enforce a correct mapping of the data to the ADF trees. CGNS is in the process of being an ISO standard. The CGNS web site is http://www.cgns.org, it contains documentation, source and binary versions of the libraries. 1.2 Scope of the binding The official CGNS bindings are Fortran and C. This package is a proposal for a Python binding. The low level binding is a simple wrap of the CGNS and ADF C fonctions, using an arbitrary mapping between the C language data structure and Python data structures1 . An upper level binding is a Python object oriented mapping to CGNS. That is a set of classes and methods that matches the SIDS representation. In this package, this upper level binding is still an experimental one, as there is no official proposal for an object oriented binding of the SIDS. Such a binding requires a team work, the creation of an object-oriented SIDS by a single people may lead to an application oriented way of using objects. However, the pyCGNS package SIDS could be a start point, and is waiting for your criticisms. The pyCGNS binding allows the quick development of tools and trees. Migration tools, translation, search, tree manipulation tools can be realized with Python. The demos and tools of this package mainly are tree manipulation, and you can see by yourself how easy it is to recursively parse a tree and build lists of results, using the Python language. The package can also be used to learn CGNS, how to handle mid-level and ADF layers together, make some experiments on tree structures such as creating and handling links, adding specialized nodes, translating tree structures into another one... Now, you may also note that the data array representation is the Numerical Python array. This means that array I/O from or to the pyCGNS interface is done through PyArray type, which is a usual way to exchange data for scientific Python applications2 . For example, you have an application, such as a Fortran solver, and you want this application to use the pyCGNS package, then you have to use the PyArray facilities, exchanging the data arrays in memory through Python objects. The new numarray package is now used, this is an incompatible change. Then, old pyCGNS v1.x would not work with pyCGNS v2.x versions. 1.3 Installation The package comes as a standard Python package. It uses the Distutils tool for the build and the install steps. The use of the tool is very simple, as you have already installed a standard Python distribution. 1.3.1 Requirements • You have to install a standard Python distribution. Such a distribution can be found at http://www.python.org for a very wide set of platforms. We experienced the port of Python on Cray and on vectorial computers such as NEC or Fujitsu. The Python version we need is v2.0 (or later, tested with 2.3.3). • The binding we propose here for CGNS uses the Numerical Python arrays. This allow array manipulation using Python, which is very valuable for pre and post processing of data. We suggest you take time to have a look to the powerfull services of the Numerical Python package. This package can be found in the Python web site, in the scientific topics. The exact package name is numarray with 0.8 version. • The CGNS libraries have to be available. We require the libcgns.a librarie for the host platform you have, and the cgnslib.h and ADF.h C header files. Note that the include search path we are looking for ADF.h and not for adf/ADF.h (but this can be changed in the setup.py file). 1 For example, the number of dimensions and the dimension array can be gathered into a single tuple of dimensions. The user can have the dimension number using the length of the tuple. 2 The PyArray does not copy its memory data, it refers to an already allocated zone of memory, and handle it. 2 Chapter 1. Introduction The librarie version we need is v2.2, and the v2.3.2 has also been tested. 1.3.2 Standard installation steps The first step is to uncompress and extract the source tree: gzip -d pyCGNS-vx.y.tar.gz tar xvf pyCGNS-vx.y.tar The source tree is now extracted in a pyCGNS-vx.y directory. You set a shell variable CGNSLIBHOME to the directory containing the CGNS installation. Now you can go into this directory and use the Python installation tool... python setup.py install 1.4 Package description The main directory of the package is pyCGNS/CGNS, which contains the C langage source code for the modules to the ADF libraries (pyCGNS/CGNS/adf) and to the mid-level libraries (pyCGNS/CGNS/cgns). The file pyCGNS/CGNS/wrap.py is a simple Python wrapper on top of the previous modules, it makes some checks or add some attributes or methods. The file pyCGNS/CGNS/sidstech.py is the experimental OO Python interface for CGNS. The other directories are containing Python scripts, all using the wrap modules. The directory names are explicits (demo, test, tools). The documentation stands into pyCGNS/Doc and requires the use of the Python documentation system (styles and tools). The code embedded documentation is available as HTML pages. It is extracted using the Happydoc tool (http://HappyDoc.sourceforge.net). 1.4.1 About float values If you want to use the float values for display purpose (string manipulation, tree parse, etc...), you may obtain values that look bad. This is a number representation problem, we give you some examples here but a good explanation can be found at http://www.python.org/doc/current/tut/node14.html The common example is the CGNS library version: >>> import CGNS >>> a=CGNS.pyCGNS(’foo.cgns’,CGNS.MODE_WRITE) >>> a <pyCGNS instance from "foo.cgns"> >>> a.libversion() 2.2999999523162842 You see the 2.3 value cannot be displayed in a way which looks correct for human being. It is difficult to get a nice display with a single call to functions. 1.4. Package description 3 >>> "%g"%a.libversion() ’2.3’ >>> float("%g"%a.libversion()) 2.2999999999999998 >>> print a.libversion() 2.29999995232 You can use the following bizarre translation process: >>> b=2.3 >>> b 2.2999999999999998 >>> print b 2.3 >>> print float("%g"%a.libversion()) 2.3 The CGNS.utils module contains some pretty printers for floats, list, tuples, arrays of heterogeneous data containing floats. For example: >>> import CGNS.utils as U >>> a=[2.3, 6.8, 3.14] >>> a [2.2999999999999998, 6.7999999999999998, 3.1400000000000001] >>> U.pnice(a) ’[2.3, 6.8, 3.14]’ >>> This returns a string, and the use would be limited to pretty print of values. There is a way to set a particular print method in numarray, or to set the existing print method. Refer to numarray documentation. For example, if you want to print even a very large array, you have to tell to numarray. Use the following method call: import numarray.arrayprint numarray.arrayprint.summary_off() 1.4.2 About dimension order As you may know, the Fortran and C langages usually have different indices ordering when handling arrays. For example, if you have an array x with dimensions [i,j,k], and you use Python functions handling this array, you’ll have [i,j,k] loops with the pattern: for i in range(x.shape[0]): for j in range(x.shape[1]): for k in range(x.shape[2]): ... The indices are parsed with the C order, that is [i,j,k]. Now if you use a pre or post processing which uses Fortran, the loops in this langage are: 4 Chapter 1. Introduction for k in range(x.shape[0]): for j in range(x.shape[1]): for i in range(x.shape[2]): ... Then you have to transpose you array. You can do this using the transpose method in numarray. The parse is done using a [k,j,i] order. Python, numarray and CGNS are not checking this order. As far as you have a compliant data size for the data array (i.e. i*j*k), no error will be raised. Keep this in mind if you see some very strange results on your screen... 1.4. Package description 5 6 CHAPTER TWO CGNS package classes The package contains several classes and dictionnaries definitions. The pyADF class represents a connection to an ADF database. The pyCGNS class is a connection to a SIDS compliant database, one would say it is a connection allowing only SIDS compliant creations of sub-trees through the MLL functions. This pyCGNS Python package allows the use of ADF functions and MLL functions at the same time. This feature is described at the end of this chapter. 2.1 Quick start In the section below, we are describing Python scripts, these are files with Python programs you can run by typing the following in your shell command line: python myfile.py But, as Python is an interpreter, you can also use your script as a single executable file on Unix. • Add the interpreter call as the first line of your script, without any leading space: #!/usr/bin/env python • Change the file access mode of the script to executable to make it usable as a command from your shell: chmod u+x myfile.py You can also run the Python interpreter, just type in python, and feed Python the the command lines you’d like to execute. For more informations, please refer to the helpfull Python tutorial. Now, you want to use the pyCGNS services, you have to import these services. The import is something which loads the module or package into your interpreter. You can reuse any module you would like to, using the import statement. For our purpose, we are importing several modules. This has to be done in every script files where you call or use a pyCGNS declaration or variable. A way to import the required modules is to add the following lines at the head of your script file: import CGNS import numarray The CGNS module imports the actual C extensions modules for our interpreter and some Python files required to have the pyADF and pyCGNS classes. You have to do the numarray import if you want to handle variables containing PyArray values. 7 2.2 Using ADF class Now we can go on and create an ADF database. You may read this part to have an idea of the use of pyCGNS, and we also suggest you refer to the code examples in the test, tools and demo directories. 2.2.1 Create a subtree First step is to open a CGNS file, the mode NEW indicates the file has to be created. a=CGNS.pyADF("myfirstadfdatabase.adf",CGNS.NEW,CGNS.NATIVE) The variable a is now a reference to a pyADF object. In other words, a object is a database connection. The subsequent calls to the database will be done by applying a method to this connection. a.database_close() Well, the database is now closed. You can note the method we applied to the object has the same name that the ADF C language function. You just have to remove the ADF prefix and put all the method name in lowercase. We can create a set of nodes using the create method, add some label. The root method is used to get the root id of the database. The NEW and NATIVE variable actually contains the required strings of the same name, i.e. "NEW"and "NATIVE", see the next section about that kind of variable use. import CGNS a=CGNS.pyADF("myfirstadfdatabase.adf",CGNS.NEW,CGNS.NATIVE) rootid=a.root() baseid=a.create(rootid,"Base") dataid=a.create(baseid,"Data") a.database_close() The CGNS database is closed. 2.2.2 Read an write data We add some data to the previous tree, using the numarray package array type. We store a dummy array of float, and we get it back into a new array. import numarray as N dim=(65,33,2) x=N.ones(dim,’d’) a.put_dimension_information(dataid,"R8",dim) a.write_all_data(dataid,x) The dimension information is stored into a tuple. We do not need to pass the dimension size, because the interface uses the tuple size. The datatype cannot be a constant, because of ADF specification of such a data type string definition, which could be a compound type. Reading the data returns a numarray array, it can be used as described into the documentation of this package. z=a.read_all_data(dataid) print z[2] 8 Chapter 2. CGNS package classes 2.2.3 Parsing a tree We want now to parse a tree, get a child list for a node and go on. The children list is returned as a Python list. If we have a node Coord with three children X,Y and Z, the returned list can be used as in the following lines: parentid=a.get_node_id(a.root(),’Coord’) cnamelist=a.children_names(parentid) cidlist=[] for c in cnamelist: cidlist.append(a.get_node_id(parentid,c)) We get the id of the parent node and then the list of children name, which is [’X’,’Y’,’Z’]. We initialize to empty a storage list for the ids we want to retrieve, we call it cidlist. Then we have a loop on each child name, and for each we get the id and we add it in the storage list. Now we can apply the same set of lines for each of the children ids. The best is to make a function and recall it, this is recursion. To stop the recursion, we must not call the function if the child list is empty. To start the recursion we have to call the function with a given starting node id. 2.2.4 Using links The links are a very powerfull and consistent capapility of the ADF layer. The link refers to another node into another CGNS database. Here is a complete example, we use a createSubTree(filename) function with the file names SubTreeOne and SubTreeTwo. We create the node ’N3’ in ’SubTreeTwo’ to make it refer to the node ’N2’ node of ’SubTreeOne’. def createSubTree(filename): a=CGNS.pyADF(filename,CGNS.NEW,CGNS.NATIVE) t=a.create(a.root(),’top’) n1=a.create(t,’N1’) n2=a.create(t,’N2’) a.database_close() createSubTree(’SubTreeOne’) createSubTree(’SubTreeTwo’) a=CGNS.pyADF(’SubTreeTwo’,CGNS.OLD,CGNS.NATIVE) a.link(a.get_node_id(a.root(),’/top’),’N3’,’SubTreeOne’,’/top/N2’) del a We use del statement to remove the a object. This deletion calls the database close method, but also removes the variable a. 2.2.5 Constants The enumerates and strings constants defined by the CGNS library headers are declared as variables into the pyCGNS package. You can have a lighter source code manipulating these variable instead of actual values of strings or integers. Moreover, a typo in a string cannot be detected by the Python interpreter, but a typo in a variable name is detected. Your code is safer and the readability is better. Another point is that you can identify which constant are yours and which are not, you use the cgns scope set at import time. You can also use some specific dictionnaries to find out the possible values of a given parameter. For example, the OLD variable contains the string ’OLD’ and you can find out the possible values for the database open status using the ADF OPENSTATUS dictionnary. A more complete example is given in the next section, about the constants related to the mid-level library. 2.2. Using ADF class 9 2.3 Using MLL class The mid-level interface (MLL) is an upper level of abstraction. Instead of dealing with anonymous nodes, we have now typed nodes and dedicated sub-trees of such nodes. Types, structure and semantics are those described into the mid-level library and SIDS documents. We are not explaining here the use of CGNS, but rather the specifics of the Python binding. The are some MLL examples at the end of this manual. These are some User’s guide to CGNS examples, translated into Python. 2.3.1 Function and data mapping The function names are the same than the MLL API with the C language. Most MLL functions I/O are scalar data (i.e. integer, real...) or arrays of data. The pyCGNS methods are a straightforward mapping of the C langage API, with some modifications for data I/O. We are using tuples when possible, as in the example below: z=CGNS.zoneread(baseid,zoneid) print ’zone name: %s - id: %d’%(z[2],z[1]) The zoneread return is a tuple, that is an ordered set of four values in this case. The third value is the name, the second is the zone id. This latter has already been given as argument, we are returning it back to allow the user to have a more re-usable tuple. In many cases, the user will need to store both identifiers and returned values, such as name, data etc... 2.3.2 Dictionnaries of enumerate values Many methods are using the dictionnaries based enumerates. The dictionnaries have the name enumerate when the CGNS C language enumerate itself has the name enumerate t (with case sensitivity). Then, when the expected type is GridLocation, this means the value is taken from the GridLocation t C enumerate. The way to match it in the Python module is to manipulate variables that contains the actual value of the enumerate. The name of the variable is the string value declared in the CGNS header file. See the next example: s=db.solwrite(base,zone,’Solution002a’,CGNS.Vertex) To get all the values, one can use: for v in CGNS.GridLocation.keys(): print v, CGNS.GridLocation[v] The reverse dictionnary, with the enumerate integer as key and the string name as value, is in the dictionnary with the name enumerate (e.g. GridLocation ). 2.3.3 Using both ADF and MLL It is possible to use both ADF and MLL classes. Moreover, it is possible to use a MLL object as an ADF one. In other word, one can build the CGNS tree with the MLL interface, then use the ADF interface to add some specific nodes or other not-compliant information to the CGNS tree. While all the mecanisms are available in the pyADF and pyCGNS classes, these have been hidden. The capabilities of node generalization has been reserved to the SIDS classes. There is an example. First we open an MLL file, le MLL connection object is used to get actual ADF ids of the tree root, or specific nodes: 10 Chapter 2. CGNS package classes a=CGNS.pyCGNS(’alreadyExistingBase.cgns’,CGNS.MODE_MODIFY) print a.root print a.id(1,[(CGNS.Zone_t,1),(CGNS.FlowSolution_t,2)]) print a.baseid(1) print a.zoneid(1,2) print a.coordid(1,2,1) print a.solid(1,2,1) print a.fieldid(1,2,1,1) print a.one2oneid(1,2,1) print a.bcid(1,1,1) We can also use the nodeAsDict method, which returns all the available informations for an ADF node. In the case, we have to ask for an explicit ADF connection. This is done by passing the MLL connection object itself to the ADF connection constructor: b=CGNS.pyADF(a.root,"","") print b.nodeAsDict(a.solid(1,2,1)) print b.nodeAsDict(a.fieldid(1,2,1,1)) Here, a is a MLL connection, b is an ADF connection to the same in memory ADF structures. You can close the ADF connection, without loosing the MLL connection: b.database_close() 2.4 Using SIDS classes This part is still experimental, that is interface could change. The idea of the SIDS classes in pyCGNS package, is to provide the user with a more natural way of using the CGNS tree. This set of classes is nothing more than a layer on top on pyADF and pyCGNS classes, together with a set of utilities classes. Maybe the best way to persuade you is to give you some examples. 2.4.1 Examples of use Let say we have some CGNS files, with meshes, solutions, boundary conditions and so on. We want to manipulate them for some pre/post processing purpose. We won’t go deep into each example, you would better read the SIDS classes description if you want more details. Moreover, we bet that Python is so easy to understand that you wouldn’t need comments... Get zones We are looking for the zones of a given tree. Some engineer sent us a CGNS tree with some work on mesh splitting, we have to find back where are the GridCoordinates to get back the meshes. Here, Path is a SIDS class. dbtree=pyCGNS("Case-02132.cgns") mypath=Path("/.*/.*/GridCoordinates",dbtree) print mypath.asListOfPath() 2.4. Using SIDS classes 11 The path given as argument contains some wildcards, or more exactly these are regular expressions. The asListOfPath is looking for possible pathes into the CGNS tree. Actually, it parses this tree using some MLL or ADF function calls. We are printing the result, which could lead to an output like: [’/Case-02132/Zone-001/GridCoordinates’, ’/Case-02132/Zone-002/GridCoordinates’,’/Case-02132/Zone-011/GridCoordinates’, ’/Case-02132/Zone-015/GridCoordinates’] This implies we have only four zones, which names can be retrieved using some Python functions manipulation strings. Or we go further with the Path class and ask a mll goto-like translation. mypath=Path("/.*/.*/GridCoordinates",dbtree) for zonegridname in mypath.asListOfPath(): zonegridpath=Path(zonegridname,dbtree) print zonegridpath.asGoto() Which parse the CGNS file to get the type and its index for each node in the path. This returns: [1, [1, [1, [1, [ [ [ [ (’Zone_t’, (’Zone_t’, (’Zone_t’, (’Zone_t’, 1), 1), 1), 1), (’GridCoordinates_t’, (’GridCoordinates_t’, (’GridCoordinates_t’, (’GridCoordinates_t’, 1) 2) 3) 4) ]] ]] ]] ]] This is the information required for the goto function. One can also use the jump method of the Path class, this uses a string path and actually performs the goto. In the next example, for demonstration reason only, we want the X and Z coordinates of zones with a name starting with Zone-L- in the Case-02132 base. mypath=Path("/Case-02132/Zone-L-.*/GridCoordinates/Coordinate[XZ]",dbtree) for resultname in mypath.asListOfPath(): resultpath=Path(resultname,dbtree) resultpath.jump() # do some stuff on current node Looking single precision data Now we want to check if there is no single precision data in the tree. Well, it looks like there is somewhere a legacy code which do not want to understant the single precision reals. We are parsing all the nodes and we are looking for a single precision DataType. We get the node id of a given node, we aks for the pyADF corresponding connection to the opened pyCGNS. Then, any call to pyADF is possible, using any valid node ids, such a those obtained by extract. In these example line codes, we assume that nodename is a valid path string to a node, dbtree is a pyCGNS object. We get the node ids using extract and we are using the last id, using the second member of the last (-1) element of the result of extract. This id the id of the leaf node of our path. Each element of extract result is a tuple: (node-name:S, node-id:D, node-type:S). nodepath = Path(nodename,dbtree) adf = nodepath.getADF() nodeleaf = nodepath.extract()[-1] nodeid = nodeleaf[1] datatype = adf.get_data_type(nodeid) 12 Chapter 2. CGNS package classes This example is a very important one: we are using both mid-level and adf calls in the same script. As a matter of fact, we can say that any node of a CGNS tree is an adf node. Such a factorization of behavior can be modelized using the object-oriented techniques. Python provides us with many OO mechanisms, we are going to use this for our SIDS classes in the next sections. 2.4.2 Class Path The Path class makes it possible to use node names and path names instead of node ids or indexes. The tree is manipulated using the names of the nodes. SIDST pop Removes the tail element of the path None=pop() → If the path is empty and it is absolute, returns a ’/’otherwise raises SIDS X PATHISEMPTY jump Goto the current path name None=jump() → Actually calls the Mid-level library goto. asGoto Get a MLL goto like list of values for this path [base-idx:I,[(node-type:S, node-idx:I)]]=’sGot → Returns the Node list corresponding to the path extract [(node-name:S, node-id:D, node-type:S)]=’xtrac → Create a new path, empty or with the argument string path init Path(path:S,database:pyCGNS) → database must be a pyCGNS object. If omitted, only not connectedpath functions can be used. asListOfPath Search and returns the list of matching names [path-name:S]=’sListOfPat → Similar to asListOfTree, but only returns the matchingpaths, not the intermediate ones. split Returns the string list of path string elements (name:S)=’pli asListOfTree → Search and returns the list of matching names [path-name:S]=’sListOfTre → Patterns are regular expressions (used re)- A list of all parsed paths is returned, it includesall the sub-paths used. The asListOfPath methodreturns the matching paths without intermediatesub-path getADF Gets the pyADF connection to the pyCGNS base connection:pyADF=getADF() isAbsolute → Returns true if Path is absolute true-if-absolute:I=isAbsolute() → 2.4.3 Class Node The Node class offers no specific services compared to the pyADF services. It contains a reference to a given node and allow the ADF-like functions calls. Here is an example of use. 2.4. Using SIDS classes 13 dbtree= pyCGNS("SquaredNozzle-05.cgns") mypath= Path("/Base",bdtree) dbadf = mypath.getADF() nodeid= mypath.extract()[0][1] node = Node(nodeid,dbadf.get_root_id(nodeid)) print print print print print print print node.id node.name node.label node.ndim node.vdim node.type node.children del mypath dbtree.close() del dbtree In that case, an output would be something like: 2.04345703128 Base CGNSBase_t 1 (2,) I4 (’Zone-001’, ’Zone-002’, ’Zone-003’, ’Zone-004’, ’Zone-005’, ’Zone-006’, ’Zone-007’, ’Zone-008’, ’Attributes’) 14 Chapter 2. CGNS package classes CHAPTER THREE Tools If you want to use the tools, you just have to type its name like any other Unix tool, as far has you have the correct search path. The Python installation has a bin directory where it puts the tools. 3.1 cgp: parsing trees The cgp is the parse tree tool. It parses a ADF file, using pyADF, and prints a text representation of the ADF tree. The tool is not written as a programming example for the package, but it is good for a first level look at an ADF tree. The options we have are: • x Output format is ADF XML • t Output format is free text • p Shows all the paths of the tree (CGNS) • P Shows all the paths of the tree (ADF) • z Display the contents of arrays • l Follow links The following command displays an XML ouput of the tree, but without displaying the float/integer data arrays: cgp -x "naca0012.cgns" You obtain this kind of output example (truncated): <NODE name=’ADF MotherNode’ label=’Root Node of ADF File’> <DATA type=’MT’ /> <DIMENSIONS total=’0’> </DIMENSIONS> <VALUES> </VALUES> <NODE name=’top’ label=’Base’> <DATA type=’MT’ /> <DIMENSIONS total=’0’> </DIMENSIONS> ... The default behavior is to produce a textual tree, with information about types, labels, dimensions... Some options of the tool allow to have some more compact display of the tree. The following command simply displays the name tree, or path tree, for the same database as in the previous example: 15 >parseTree.py -p "myData.cgns" /ADF MotherNode /ADF MotherNode/top /ADF MotherNode/top/coordinates /ADF MotherNode/top/coordinates/x /ADF MotherNode/top/coordinates/y /ADF MotherNode/top/description /ADF MotherNode/top/dimensions /ADF MotherNode/top/dimensions/i /ADF MotherNode/top/dimensions/j You can also tell the parser to follow links. In the case of the path display, the link doesn’t appear. You have a list of all possibles paths without any distinction between real or link nodes. But if you use the text or XML ouput, the link appears as a node, the label contains the destination file and destination node. 3.2 Stampnode tool This tool can create specific node in a given tree. The nodes are called stamps as they are used to mark a father node with a date or a keyword. Say we want to stamp some solution node with an attribute giving the quality of the result, time CPU on a specific host, the version of solver with which it was created, etc... The date stamp can be automatic, or given as an argument. The keyword stamp has to be taken from a fixed (user defined) table of keyword/value. The sub-tree to stamp is specified using a regular expression1 . The result of the stamp process can be seen using the parse tree tool. The first command line stamps all the flow solution nodes with the date of the creation. The second one adds a keyword to coordinates nodes X and Z. stampnode.py -c ’.date’ -d ’2001.08.30.15.21.43’ -n ’.*/FlowSolution’grid.cgns stampnode.py -c ’archived’ -k ’cdrom’ -n ’.*/Coordinate[X,Z]’ grid.cgns The stamp tool is an example on how the selectively parse a tree subset, based on the criteria of the path string. This tool does not follow links. 3.3 cgl: listing files The cgl tool filters CGNS files and gives some information about the file itself and its contents. The contents taken into account are special attributes. Thus, the use of such a tool is reserved to people adding such attributes, unless you modify cgl to fit your needs. Attributes are searched into /.*/Attributes nodes, i.e. in nodes named Attributes below any base node. The attributes are descriptors, and the cgl tool expects hard coded attributes such as: .Classification, .Origin, .Topology, .Config... Again, this tools is more a demo than an actually usable tool for everybody. Many informations can be retrieved without specific attributes (topology, number of zones...). 1 Such a use could be argued, as we could use the path specification of an XML tree. However, the simple tool can be efficient and usable without the XML machinery, and this is a plus. 16 Chapter 3. Tools > cgl -h usage: cgl [options] [files] options: -a -x -o -c -T -s -u -d -m Alias for options -m -x -o -c Classification Origin Configuration Title File size File owner (no group) File date (modification) origin mesh file(s) name(s) >cgl -oTcsxd * ? ? ? 8 * unknown ? ? 60 * ONERA ? ? ? 8 * unknown 3.3. cgl: listing files 122880 491520 626688 491520 5042176 2281472 5910528 110592 348160 176128 389120 Nov Nov Nov Nov Nov Nov Nov Nov Nov Nov Nov 07 14 14 14 07 07 14 14 14 07 14 16:11:14 17:40:28 17:40:32 17:11:01 16:12:07 16:11:33 17:01:50 17:01:50 17:01:50 16:11:38 17:11:01 5blocks.cgns SquaredNozzle-05-I.cgns SquaredNozzle-05-R.cgns SquaredNozzle-05.cgns bump.cgns jet.cgns m6.cgns naca0012.cgns sphere_cube.cgns tut21.cgns z234 M6 Wing Squared Nozzle 17 18 CHAPTER FOUR Other demos and tests If you just want to have a look at the source code, you can go into your Python installation and edit the files. If you want to run the tests, you have to import the given test in a script file, or in the Python command line, such as: import CGNS.test.ADFextensive Now, let’s look what we have there to make you use pyCGNS in less than half an hour. 4.1 Code examples 4.1.1 NACA0012 demo The demo builds an ADF tree using pyADF for the NACA0012 profile. The exemple is not SIDS compliant, and is just there to show how to call the Python classes and methods. In this demo, the floating point values of the mesh are stored into the script itself, into float arrays. Then, these arrays are copied into the CGNS database. This is a way of feeding the database with a large amount of data, but a practical use of the array should require some C or Fortran tools for the array creation. 4.1.2 Links demo The gridlink.py script creates three separate databases and makes some links between them. You may use the parser tool to have a look at the result trees. This very simple demo aims at being extended. So far, we can create links with the ADF layer, but this requires a open/close on the CGNS database on which you are working with the mid-level library. The hydro.py also is an example of link use. 4.1.3 ToasterGrid It generates a grid with structured and unstructured zones. The is no connectivity. You can find in there the dropVersion function, which is used to silently change the version number of CGNS lib for some tools. Of course, if you do so, you may have some backward problems with either MLL or another CGNS tool... 4.1.4 Two D This demo is provided by William A. Perkins, the code shows a 2D base. 19 4.2 User’s Guide to CGNS examples The demo directory contains some pyCGNS translation of the User’s Guide to CGNS examples. Some of the source code can be found at the end of this manual. The examples are as close as possible to the original examples in fortran, but one can find some slight changes. These changes has been done when we wanted to emphasize a specific Python pattern, or when it was not relevant with pyCGNS. 4.3 Testing Most tests are trying to be extensive tests for the package itself. These are shaking the interface, without some real test strategy. ADFextensive.py a set of tests on all ADF routines, with attempts to force errors. SIDSextensive.py same kind of test for CGNS routines. MLextensive.py contains MLL tests. 20 Chapter 4. Other demos and tests APPENDIX A PyADF class The convention for the method signature arguments are <value-name>:<type>, with type: S D I * A stands for a string stands for a double float stands for a integer (Python integers are C long integers) repeat the previous type stands for a Numerical Python array Dictionnaries: ADF OPENSTATUS READ ONLY OLD NEW SCRATCH UNKNOWN ADF OPENFORMAT NATIVE IEEE BIG IEEE LITTLE CRAY An instance of this class is a connection to a CGNS database (with ADF layer). The single constructor for the class is: pyADF(file-name:S, status:S, format:S) The close of the database is done through the class destructor. One should keep in mind that the del statement of Python is decrementing the reference counter to the object. Thus, the actual destructor if the class is called when there is zero references to the object. In other word, the database is closed when all references to it are deleted. The next table gives the pyADF class methods signatures, with the form: function-or-attribute-name . arguments-contents-and-type return-contents-and-type 21 delete (file-name:S) . database get format . database set format (root-id:D) database-format:S (root-id:D,database-format:S) . database garbage collection (node-id:D) . database version . get root id . create . delete (root-id:D) (version:S,create-date:S,modif-date:S) (node-id:D) root-id:D (parent-id:D, node-name:S) node-id:D (parent-id:D, node-id:D) . put name (parent-id:D, node-id:D, node-name:S) . get name . children names . move child (node-id:D) node-name:S (parent-id:D) (children-name,*) (parent-id:D, node-id:D, new-parent-id:D) . set label (node-id:D,node-label:S) . get data type . get number of dimensions . get dimension values . put dimension information (node-id:D) data-type:S (node-id:D) number-of-dimensions:int (node-id:D) (dimension:I,*) (node-id:D,data-type:S,dimensions:(I,*)) . is link . link . get link path . read all data . write all data (node-id:D) path-length:I (parent-id:D, node-name:S, link-to-file:S, link-to-node:S) node-id:D (node-id:D) file:S,node:S) (node-id:D) data:A (node-id:D,data:A) . error message . set error state (error-code:I) error-message:S (state:I) . flush to disk (node-id:D) . number of children . get node id . get label . 22 (node-id:D) number-of-children:I (parent-id:D,node-name:S) node-id:D (node-id:D) node-label:S Appendix A. pyADF class APPENDIX B PyCGNS class Most pyCGNS methods are using the name of the enumerate as actual parameter values, instead of the integer. The translation is done in the wrapper itself. Checking can be done on the name of the enumerate value, before its translation. B.1 Dictionnaries This variables are dictionnaries of enumerate names and enumerate values defined by CGNS. For example, the Dictionnary TimeUnits contains the names of the enumerate, in your code, you can use TimeUnits[Second] instead of finding out the corresponding integer for this enumerate. Actually, the variable TimeUnits[’Second’] contains this integer, but using a variable name is much more secure. Every dictionnary as an inverse dictionnay with the same name but with a tail. To sumarize, dictionnaries have names, the keys are the integer enumerates and the values are the string names. The inverse dictionnaries have the string name as key and the integer enumerate as value. All string names can be found in variables with the same name, at the module scope. There are some lines showing how to use the dictionnaries variables as kind of keyword instead of the actual strings or integer values: >>>import CGNS >>>CGNS.CoordinateX ’CoordinateX’ >>>CGNS.SpecificHeatPressure ’SpecificHeatPressure’ >>>CGNS.GridLocation[CGNS.Vertex] 2 >>>CGNS.TimeUnits {’Second’: 2, ’Null’: 0, ’UserDefined’: 1} >>>CGNS.TimeUnits[’Second’] 2 >>>CGNS.TimeUnits_[2] ’Second’ >>>CGNS.TimeUnits[CGNS.Second] 2 >>>CGNS.TimeUnits_[CGNS.TimeUnits[CGNS.Second]] ’Second’ >>> The proposed use of these dictionnaries is to pass the enumerate name like in the next example (without any name scope prefixes). We suppose coordxarray has been defined. 23 from CGNS import * a=pyCGNS(’file.cgns’,MODE_WRITE) a.basewrite(’Base’,3,3) a.zonewrite(1,’Zone 01’,[3,5,7],Structured) a.coordwrite(1,1,RealDouble,CoordinateX,coordxarray) The names of the enumerate dictionnaries are the same as the enumerate name in cgnslib.h but without the trailing t. The one would use TimeUnits instead of TimeUnits t. B.2 Class methods An instance of the pyCGNS class is a connection to a CGNS database (with mid-level library layer). The single constructor for the class is: pyCGNS(file-name:S, mode:S) To close the database, see remarks in previous the pyADF class section. The next table gives the pyCGNS class methods signatures. Please note the attributes also are listed in the next table. B.2.1 pyCGNS functions (pyCGNS) adfroot Get ADF root id root-id:D=adfroot() → The ’root’ attribute has the same contents. name Get file name filename:S=name() → The ’name’ attribute has the same contents. close Close the current CGNS file None=close() → Close is performed by *del* if not already (explicitely) done. lasterror Get the current error (error-code:I,error-message:S)=lasterror() → The ’error’ attribute has the same contents. id Get the ADF id of a given node node-id:D=id(base-id:I,path:((node-type:S,node-id:I),...)) → Uses the same syntax as ’goto’, but doesn’t set the current node.This id call is not trustable, it has not beeen tested and probablyhas a destructive effect on cgnslib global variables...See ’goto’ remarks init Creates a CGNS database pyCGNS(file-name:S,file-mode:I) → The file mode is an enumerate. It can have the values:MODE READ, MODE WRITE, MODE MODIFY libversion Get library version version:D=libversion() → The ’version’ attribute has the same contents. 24 Appendix B. pyCGNS class Arbitrary Grid Motion arbitrarymotionwrite Create a new arbitrary motion node arbitrary-motion-id:I=arbitrarymotionwrite(base-id:I,zoneid:I,name:S,type:I) → type:ArbitraryGridMotionType arbitrarymotionread Get info about an arbitrary motion node return-tuple=arbitrarymotionread(base-id:I,zone-id:I,motion-id:I) → The returned tuple contains: (name:S,ArbitraryGridMotionType:I) narbitrarymotions Get number of arbitrary motion nodes number-of-motion:I=narbitrarymotions(base-id:I,zone-id:I) → No Comment Auxiliary Data gravityread Get the gravity vector (gravity-vector:(D,...))=gravityread(base-id:I) → Size depends on physical dimension of base. gravitywrite Set the gravity vector None=gravitywrite(base-id:I,gravity-vector:(D,...)) → Size depends on physical dimension of base. Axisymmetry axisymwrite Set the axisymmetry parameters None=axisymwrite(base-id:I,reference-point:(D,D),axis-vector:(D,D)) → Should be 2D. axisymread Get the axisymmetry parameters (reference-point:(D,D),axis-vector:(D,D))=axisymread(base-id:I) → Should be 2D. Base bases Count number of bases nbases:I=bases() → The ’nbases’ attribute has the same contents. baseread Get infos about a given base (base-idx:I,base-name:S,cell-dim:I,phys-dim:I)=baseread(base-idx:I) → Arg is base id, returns a tuple with base information. basewrite Create a new base in an existing CGNS file base-idx:I=basewrite(base-name:S,cell-dim:I,phys-dim:I) → Args are base name, cell and physical dimensions.Returns the new id of the created base B.2. Class methods 25 Boundary Condition bcareawrite Set the area parameters None=bcareawrite(base-id:I,zone-id:I,bc-id:I,type:I,surf:D,region:S) → Type is AreaType bcdatasetwrite Write the dataset set of a given BC dset-id:I=bcdatasetwrite(base-id:I,zone-id:I,bc-id:I,dset-name:S,dsettype:I) → dset-type:BCType bcwrite Create a new BC bc-id:I=bcwrite(base-id:I,zone-id:I,args...) → The trailing arguments are the following, in that order.The ’bc-name:S’, ’bc-type:I’, ’bc-point-settype:I’, the’point-set-list:((I,I,I),...)’.The number of points in the point set list is deduced fromthe length of the point list, except if the point set type isPointRange. In that case, the number of points is forced to 2. bcread Read point and normal lists from a given BC (point-list:A,normal-list:A)=bcread(base-id:I,zone-id:I,bc-id:I) → Comment bcnormalwrite Write the normals of a given BC None=bcnormalwrite(base-id:I,zone-id:I,bc-id:I,args...) → The trailing args are the following, in this order.The ’normal-index:(I,I,I)’, ’normal-flag:I’, ’datatype:I’,’normal-list:((D,D,D),...).Caution: normal-flag is forced to FALSE, normal-list is not takeninto account. bcwallfunctionread Get the type of BC wallfunction WallFunctionType:I=bcwallfunctionread(base-id:I,zone-id:I,bc-id:I) → Comment nbc Get the count of BC number-of-bc:I=nbc(base-id:I,zone-id:I) → No comment bcinfo Get info from a given BC return-tuple=bcinfo(base-id:I,zone-id:I,bc-id:I) → The result tuple has the following members, in that order.The ’name:S’ of the node, its ’bc-type:I’ and its ’point-set-type:I’.The ’number-of-points:I’, the ’normal-index:(I,I,I)’,the ’data-type:I’ for the normals, the ’normal-flag:I’ and the’number-of-bc-data-set:I’. bcwallfunctionwrite Set the type of BC wallfunction None=bcwallfunctionwrite(base-id:I,zone-id:I,bc-id:I,type:I) → Type is WallFunctionType bcdatasetread Read the dataset set of a given BC return-tuple=bcdatasetread(base-id:I,zone-id:I,bc-id:I,dset-id:I) → The return tuple is the following.(dset-name:S,bc-data-type:I,dir-flag:I,neu-flag:I) bcdatawrite Write the data in a BC dataset None=bcdatawrite(base-id:I,zone-id:I,bc-id:I,dset-id:I,bc-datatype:I) → bc-data-type:BCDataType bcarearead Get the area parameters (region:S,type:I,surf:D)=bcarearead(base-id:I,zone-id:I,bc-id:I) → Type is AreaType Convergence convergencewrite Craete of update a convergence node None=convergencewrite(number-of-iteration:I,node-name:S) → Uses the current node. Should return the node id. convergenceread Get the convergence under current node (number-of-iteration:I,node-name:S)=convergenceread() → No args, current node is used. 26 Appendix B. pyCGNS class Coordinates coordwrite Create a coordinate array node coord-id:I=coordwrite(base-id:I,zone-id:I,data-type:S,nodename:S,data-array:A) → data-type:DataType ncoords Count coordinates nodes in the zone number-of-coords:I=ncoords(base-id:I,zone-id:I) → See ’nzones’ remarks. coordinfo Get infos about a given coordinate (data-type:S,node-name:S)=coordinfo(base-id:I,zone-id:I,coord-id:I) → See ’coordwrite’ remarks. coordread Read the coordinate array coord-array:A=coordread(base-id:I,zone-id:I,coord-name:S,readmode:I) → The returned array is a ’pyArray’ containing the data with therequired format. Unfair-remark: a zone name is required, but allrequests to nodes are done using integer ids.The read mode is default to 0, that is a C-like read (i,j,k).The mode=1 is fortran like read (k,j,i).Please, take care of the dimensions in that case, see the ’zoneread’ remarks. Data Array arrayread Get the array data data-array:A=arrayread(array-id:I) → The array id its index under the current node.See ’arrayinfo’ remarks. narrays Count arrays under the current node number-of-arrays:I=narrays() → Use ’goto’ to set the current node. arraywrite Create or update a new array array-id:I=arraywrite(array-name:S,d-type:S,d-dim:I,dvector:(I,...),d-array:A) → All *type*, *dim* *vector* are refering to the *array* of dataitself. See also ’arrayinfo’ remarks. arrayinfo Get infos about a given array (array-name:S,data-type:S,data-dim:I,datavector:(I,...))=arrayinfo(array-id:I) → The current node is the parent node of the requested array.The data-type enumerate can be found using the cross dictionnary.There is redondancy of ’data-dim’ and ’data-vector’, first can bededuced from the second. Descriptor descriptorread Get the descriptor contents (desc-name:S,desc-text:S)=descriptorread(desc-id:I) → The current node is used. descriptorwrite Create or update a descriptor under the current node None=descriptorwrite(desc-name:S,desc-test:S) → Unfair-remark: We should get the descriptor id as returned argument. descriptors Count number of descriptors ndescriptor:I=descriptors() → The ’ndescriptor’ attribute has the same contents. B.2. Class methods 27 Discrete Data discretewrite Create a new discrete data node dics-id:I=discretewrite(base-id:I,zone-id:I,disc-name:S) → No Comment ndiscrete Get count of discrete node number-of-discrete:I=ndiscrete(base-id:I,zone-id:I) → No Comment discreteread Get the name of discrete node disc-name:S=discreteread(base-id:I,zone-id:I,disc-id:I) → No Comment Element Connectivity sectionread Get infos about a given section return-tuple=sectionread(base-id:I,zone-id:I,section-id:I) → Returns a tuple containing ’name:S’ of the section, its ’type:I’’start:I’ and ’end:I’, ’last-bndindex:I’, ’parent-flag:I’. nsections Get lower range index section-index:I=nsections(base-id:I,zone-id:I) → The lower range is (imin, jmin, kmin) elementsread Get elements of a section (elements:A,parents:A)=elementsread(base-id:I,zone-id:I,sectionid:I) → Returns two arrays of I sectionwrite Write a section section-id=sectionwrite(base-id:I,zone-id:I,section-name:S,args...) → The trailing args are the ’type:I’ of the section elementsthe ’start:I’ and ’end:I’ indices, ’last-bndindex:I’index and at last the ’elements:A’ array itself (of type ’type). elementdatasize Get the number of elements for this section number:I=elementdatasize(base-id:I,zone-id:I,section-id:I) → See ’section-write’ parentdatawrite Write the parent data in a section None=parentdatawrite(base-id:I,zone-id:I,section-id:I,parent-data:A) → No return npe Get the number of nodes for an element type number:I=npe(element-type:I) → element-type is an enumerate. 28 Appendix B. pyCGNS class Families familywrite Create a new family node fam-id:I=familywrite(base-id:I,fam-name:S) → No Comment familyread Get info about a given family (fam-name:S,number-of-fam-bc:I,number-of-geo:I)=familyread(baseid:I,fam-id:I) → No Comment nfamilies Count families in the base number-of-families:I=nfamilies(base-id:I) → No Comment georead Get geometry info (geo-name:S,file:S,CAD:S,parts:I)=georead(base-id:I,fam-id:I,geoid:I) → No Comment familynameread Get name of current node family fam-name:S=familynameread() → No Comment familybocoread Get name of current node family for a given BC (bc-name:S,bc-type:I)=familybocoread(base-id:I,fam-id:I,bc-id:I) → No Comment partwrite Create part info part-id:I=partwrite(base-id:I,fam-id:I,geo-id:I,part-name:S) → No Comment geowrite Creates geometry info geo-id:I=geowrite(base-id:I,fam-id:I,geo-name:S,file:S,CAD:S) → No Comment familynamewrite Creates name of current node family None=familynamewrite(fam-name:S) → No Comment familybocowrite Create name of current node family for a given BC bc-id:I=familyboconamewrite(base-id:I,fam-id:I,bc-name:S,bc-type:I) → No Comment partread Get part info part-name:S=partread(base-id:I,fam-id:I,geo-id:I,part-id:I) → No Comment B.2. Class methods 29 Flow Equation Set equationsetchemistryread Read chemistry flags equation-flags:(I,I)=equationsetchemistryread() → No Comment simulationtypewrite Set simulation type info None=simulationtypewrite(base-id:I,simulation-type:I) → No Comment simulationtyperead Get simulation type info simulation-type:I=simulationtyperead(base-id:I) → No Comment diffusionwrite Set diffusion info None=diffusionwrite(I,I,I,I,I) → No Comment statewrite Set state info None=statewrite(state-description:S) → No Comment equationsetwrite Set equation set info None=equationsetwrite(equation-dim:I) → No Comment stateread Get state info state-description:S=stateread() → No Comment equationsetread Get equation set info equation-dim:(I,I,I,I,I)=equationsetread() → No Comment modelread Get model info (model-name:S,model-type:I)=modelread(nodel-name:S) → No Comment governingwrite Set governing equations info None=governingwrite(governing-eq-type:I) → No Comment diffusionread Get diffusion info (I,I,I,I,I)=diffusionread() → No Comment governingread Get governing equations info governing-eq-type:I=governingread() → No Comment modelwrite Set model info None=modelwrite(model-name:S,model-type:I) → No Comment 30 Appendix B. pyCGNS class Flow Solution fieldwrite Create a data array for a solution field field-id:I=fieldwrite(base-id:I,zone-id:I,sol-id:I,args...) → The trailing args are ’data-type:S’, ’field-name:S’ and thearray of data ’data-array:A’. See also ’coordwrite’ remarks. fieldread Get the data array of a given solution field data-array:A=fieldread(base-id:I,zone-id:I,sol-id:I,fieldname:S,args...) → The trailing args are ’data-type:S’ and tuplesof indices: ’i-min:(I,I,I)’ ’i-max:(I,I,I)’. These ’imin’ and ’imax’tuples are forced to 3D, but only relevantvalues are used. Other values can be set to zero.Unfair-remark: field name is required. solinfo Get infos about a given solution (grid-location:S,sol-name:S)=solinfo(base-id:I,zone-id:I,sol-id:I) → See ’solwrite’ remarks. nsols Get count of solutions number-of-solutions:I=nsols(base-id:I,zone-id:I) → No Comment nfields Count fields in the solution number-of-fields:I=nfields(base-id:I,zone-id:I,sol-id:I) → See ’nzones’ remarks. solwrite Create a new solution sold-id:I=solwrite(base-id:I,zone-id:I,sol-name:S,grid-location:S) → The grid location is a string. The corresponding enumerate can befound using the cross dictionnary. fieldinfo Get infos about a given solution field (data-type:S,field-name:S)=fieldinfo(base-id:I,zone-id:I,solid:I,field-id:I) → See ’coordwrite’ remarks. Grid gridlocationread Get the grid location info grid-location:I=gridlocationread() → Under current node gridwrite Create a new grid node grid-id:I=function(base-id:I,zone-id:I,grid-name:S) → Comment rindread Get the rind indices under current node (imin:I,imax:I,jmin:I,jmax:I,kmin,kmax:I)=rindread() → See ’rindwrite’ comment. gridlocationwrite Set the grid location info None=gridlocationwrite(grid-location:I) → Under current node rindwrite Create of update the rind indices under current node None=rindwrite((imin:I,imax:I,jmin:I,jmax:I,kmin,kmax:I)) → Uses the current node. Tuple depends on dimensions, J or K couldbe unused in the case of 1D, 2D. Always give 6 integers, setthem to zero if you are not 3D ngrids Count the number of grids number-of-grids:I=ngrids(base-id:I,zone-id:I) → Comment gridread Get the grid name grid-name:S=gridread(base-id:I,zone-id:I,grid-id:I) → Comment B.2. Class methods 31 Grid Connectivity nconns Get number of generalized connectivities number:I=nconns(base-id:I,zone-id:I) → No comment. connread Get generalized connectivity points return-tuple=connread(base-id:I,zone-id:I,connect-id:I) → The tuple contains two arrays of integers ’target-interface-points:A’and ’donor-interface-oints:A’. connwrite Create a generalized connectivity node connect-id:I=connwrite(args) → The arguments are defining (in this order) the’base-id:I’,’zone-id:I’ of the new node, its ’name:S’, the’gridlocation:I’, ’gridconnectivitytype:I’ and ’point-set-type:I’of the current (target) node interface. The ’number-of-points:I’ and’interface-points:A’ which is an array of integers.Then the ’donor-name:S’, its ’zonetype:I’, ’point-set-type:I’ and’data-type:I’, the ’number-of-donorpoints:I’ and the actual arrayof points ’donor-points:A’.Note the ’DataType’ is force to ’Integer’. none2oneglobal Count the one2one nodes for the whole base number-of-one2one:I=none2oneglobal(base-id:I) → Comment none2one Count the one2one nodes number-of-one2one:I=none2one(base-id:I,zone-id:I) → Comment one2onewrite Create a 1to1 connectivity node one2one-id:I=one2onewrite(base-id:I,zone-id:I,args...) → The trailing arguments are the following, in that order. The’name:S’ of the node, the ’donorname:S’, the ’range’ tuple andthe ’donor-range’ tuple which are both six-integer tuples. Thenthe ’transform’ tuple is a three-integer tuple. one2oneread Get the one2one node informations return-tuple=one2oneread(base-id:I,zone-id:I,one2one-id:I) → The return tuple has the following members, in that order. The’name:S’ of the node, the ’donorname:S’, the ’range’ tuple andthe ’donor-range’ tuple which are both six-integer tuples. Thenthe ’transform’ tuple is a three-integer tuple. conninfo Get information about generalized connect node return-tuple=conninfo(base-id:I,zone-id:I,connect-id:I) → The return tuple contains: ’connect-name:S’, ’gridlocation:I’,’gridconnectivity:I’, ’pointsettype:I’, ’number-of-points:I’,’donor-name:S’, ’donor-zone-type:I’, donor-point-set-type:I’,’donordata-type:I’ and ’donor-number-of-points:I’ one2onereadglobal Get the one2one node informations for whole base return-list=one2onereadglobal(base-id:I) → The return is a list of tuples, each tupletuple has the following members, in that order. The’name:S’ of the node, the ’zone:S’ name for which the conectivityinformation is related, the ’donor-name:S’, the ’range’ tuple andthe ’donor-range’ tuple which are both six-integer tuples. Thenthe ’transform’ tuple is a three-integer tuple. Integral Data integralwrite Create a new integral node integral-id:I=integralwrite(integral-name:S) → Under current node. integralread Get the name of integral node integral-name:S=integralread(integral-id:I) → Under current node. nintegrals Get count of integral data nodes number-of-integral=nintegrals() → Counts under current node 32 Appendix B. pyCGNS class Iterative Data ziterwrite Create zone iterative data None=ziterwrite(base-id:I,zone-id:I,name:S) → No Comment ziterread Get the name of the iterative data zone name:S=ziterread(base-id:I,zone-id:I) → No Comment biterwrite Create base iterative data None=biterwrite(base-id:I,name:S,iteration:I) → No Comment biterread Get the name of the iterative data base (name:S,number-of-it:I)=biterread(base-id:I) → No Comment Link islink Test if current node is a link true-if-is-link:I=islink() → Uses current node. linkwrite Create a link None=linkwrite(source-name:S,file-name:S,target-name:S) → Args are the link name, the destination file, destination nodename. Returns None. linkread Get infos about a given link (file-name:S,target-name:S))=linkread() → Uses the current node as argument node previously set by’goto’ call. Node deletenode Delete the given node None=delenode(name:S) → Removes the current node (and its children). goto Set the current node node-id:D=goto(base-id:I,path:((node-type:S,node-id:I),...)) → The ’goto’ sets the current node to the leaf of the given path.The path itself is a list of tuples. Each tuple contains thenode type a first argument, its index as second arg.Note the returned id is not (yet) trustable. Ordinal ordinalwrite Create or update an ordinal node under current node None=ordinalwrite(ordinal:I) → Comment ordinalread Get the ordinal under current node ordinal:I=ordinalread() → Comment B.2. Class methods 33 Overset Holes holewrite Create a new overset hole node hole-id:I=holewrite(base-id:I,zone-id:I,hole-name:S,glocation:S,point-array:A) → The grid location is a string. The corresponding enumerate can befound using the cross dictionnary. holeinfo Get info from a given overset hole node return-tuple=holeinfo(base-id:I,zone-id:I,hole-id:I) → Returns a tuple containing ’name:S’ of the overset hole,’grid-location:I’ of the returned set(s) of points,the ’point-set-type:I’, the ’number-of-point-sets:I’ and the/number-of-points-per-pointset:I’.Should be called before *holeread* in order to have array dimensionsbefore allocation. nholes Get the count of overset holes number-of-holes:I=nholes(base-id:I,zone-id:I) → Returns the number of overset holes in the current zone holeread Get info from a given overset hole node point-array:A’=holeread(base-id:I,zone-id:I,hole-id:I) → Gets the array containing the points. Dimensions depenson the PointSetType (see *holeinfo*). Rigid Grid Motion rigidmotionread Get info about a rigid motion node return-tuple=rigidmotionread(base-id:I,zone-id:I,motion-id:I) → The returned tuple contains: (name:S,RigidGridMotionType:I) rigidmotionwrite Create a new rigid motion node rigid-motion-id:I=rigidmotionwrite(base-id:I,zone-id:I,name:S,type:I) → type:RigidGridMotionType nrigidmotions Get number of rigid motion nodes number-of-motion:I=nrigidmotions(base-id:I,zone-id:I) → No Comment Rotating Coordinates rotatingread Get the rotation parameters (rate-vector:(D,...),center:(D,...))=rotatingread() → The ’(D,...)’ have the base physical dimension (i.e. 2 in2D and 3 in 3d). rotatingwrite Set the rotation parameters None=rotatingwrite(rate-vector:(D,...),center:(D,...)) → See ’rotatingread’ Special Grid Connectivity connaveragewrite Set special connect properties None=connaveragewrite(base-id:I,zone-id:I,connect-id:I,averatetype:I) → The type is ’AverageInterfaceType’. connperiodicwrite Set special connect properties None=connperiodicwrite(base-id:I,zone-id:I,connect-id:I,args...) → the trailing args are ’rot-center:A’, ’rot-angle:A’ , ’translation:A’.The size of these arrays is the base physical dimension. connperiodicread Get special connect properties return-tuple=connperiodicread(base-id:I,zone-id:I,connect-id:I) → The size of arrays is the base physical dimension. The reurn-tuple is’(rot-center:A,rotangle:A,translation:A)’. connaverageread Get special connect properties averate-type:I=connaverageread(base-id:I,zone-id:I,connect-id:I) → The type is ’AverageInterfaceType’. 34 Appendix B. pyCGNS class Units and Dimensionals conversionwrite Create or update the conversion factors None=conversionwrite(data-type:I,(D,D)) → Conversion values are: scale, offset exponentswrite Create or update the exponents None=exponentswrite(data-type:I,(D,D,D,D,D)) → Exponents values are: Mass, Length, Time, Temperature, Angle. conversionread Get the conversion values (D,D)=conversionread() → See ’conversionwrite’ remarks. unitsread Get the units under current node (mass-u:S,length-u:S,time-u:S,temp-u:S,angle-u:S)=unitsread() → See ’unitswrite’ remarks. dataclasswrite Create or update the dataclass under current node None=dataclasswrite(data-class:I) → The ’data-class’ is a ’DataClass’ enumerate. exponentsinfo Get the exponents datatype datatype:I=exponentsinfo() → Python only handles double. Beware at write time, youcan have double/single. dataclassread Get the dataclass under current node data-class:I=dataclassread() → See ’dataclasswrite’ remarks. unitswrite Create or update a units set under current node None=unitswrite(mass-u:S,length-u:S,time-u:S,temp-u:S,angle-u:S) → See remarks about the constants dictionnary, one can either use thedefined strings, variables or their enumerates.*should be much more documented/checked here* exponentsread Get the exponents values (D,D,D,D,D)=exponentsread() → See ’exponentswrite’ remarks. conversioninfo Get the conversion datatype datatype:I=conversioninfo() → Python only handles double. Beware at write time, youcan have double/single. User Data nuserdata Count number of user data number-of-userdata:I=nuserdata() → Under current node. userdatawrite Create a new userdata node userdata-id:I=userdatawrite(userdata-name:S) → Under current node. userdataread Get name of the given user data id (userdata-id:i,userdata-name:S)=userdataread(userdata-id:I) → Under current node. B.2. Class methods 35 Zone zoneread Get infos about a given zone (base-id:I,zone-id:I,zone-name:S,size-tuple(I,...)=zoneread(baseid:I,zone-id:I) → The tuple returns a useful informatinos, including arguments ids.The dimension tuple size depends on the zone size. To get thistuple size, use the ’len’ function. nzones Count zones in the base number-of-zones:I=nzones(base-id:I) → The zone count is a max, the zone ids are starting from 1 (one).Thus, using ’nzones’ with a ’range’ functionshould be done with ’range(1,file.nzones(base)+1)’ zonewrite Create a new zone zone-id:I=zonewrite(base-id:I,zone-name:S,size-tuple:(I,...),zonetype:S) → See ’zonetype’ remarks. zonetype Get the type of a given zone zone-type:S=zonetype(base-id:I,zone-id:I) → The returned string can be used as entry key into ZoneTypedictionnary, in order to get the actual integer value for thecorresponding enumerate. undocumented MLL one2oneid Get the ADF id of a one2one node one2one-id:D=one2oneid(base-id:I,zone-id:I,one2one-id:I) → Comment fieldid Get the ADF id of a solution field field-id:D=fieldid(base-id:I,zone-id:I,sol-id:I,field-id:I) → See ’baseid’ remarks. zoneid Get the ADF id of a zone zone-id:D=zoneid(base-id:I,zone-id:I) → See ’baseid’ remarks. bcid Get the BC ADF id bc-id:D=bcid(base-id:I,zone-id:I,bc-id:I) → Used for ADF functions coordid Get the ADF id of a coordinate coord-id:D=coordid(base-id:I,zone-id:I,coord-id:I) → See ’baseid’ remarks. solid Get the ADF id of a solution sol-id:D=solid(base-id:I,zone-id:I,sol-id:I) → See ’baseid’ remarks. baseid Get the ADF id of a base base-id:D=baseid(base-id:I) → The argument is the MLL id, the return value is the ADF id, itis a double float value. Such an id cannot be obtained if theCGNS/ADF file has been open as write only. B.2.2 pyCGNS constants The following tables are listing the dictionnaries for enumerates and string values. The Enumerates dictionnary AngleUnits Null, UserDefined, Degree, Radian ArbitraryGridMotionType Null, UserDefined, NonDeformingGrid, DeformingGrid AreaType Null, UserDefined, BleedArea, CaptureArea 36 Appendix B. pyCGNS class AverageInterfaceType Null, UserDefined, AverageAll, AverageCircumferential, AverageRadial, AverageI, AverageJ, AverageK BCDataType Null, UserDefined, Dirichlet, Neumann BCType Null, UserDefined, BCAxisymmetricWedge, BCDegenerateLine, BCDegeneratePoint, BCDirichlet, BCExtrapolate, BCFarfield, BCGeneral, BCInflow, BCInflowSubsonic, BCInflowSupersonic, BCNeumann, BCOutflow, BCOutflowSubsonic, BCOutflowSupersonic, BCSymmetryPlane, BCSymmetryPolar, BCTunnelInflow, BCTunnelOutflow, BCWall, BCWallInviscid, BCWallViscous, BCWallViscousHeatFlux, BCWallViscousIsothermal, FamilySpecified ChemicalKineticsModelType Null, UserDefined, Frozen, ChemicalEquilibCurveFit, ChemicalEquilibMinimization, ChemicalNonequilib DataClass Null, UserDefined, Dimensional, NormalizedByDimensional, NormalizedByUnknownDimensional, NondimensionalParameter, DimensionlessConstant DataType Null, UserDefined, Integer, RealSingle, RealDouble, Character ElementType Null, UserDefined, NODE, BAR 2, BAR 3, TRI 3, TRI 6, QUAD 4, QUAD 8, QUAD 9, TETRA 4, TETRA 10, PYRA 5, PYRA 14, PENTA 6, PENTA 15, PENTA 18, HEXA 8, HEXA 20, HEXA 27, MIXED, NGON n ErrorCode ALL OK, ERROR, NODE NOT FOUND, INCORRECT PATH GasModelType Null, UserDefined, Ideal, VanderWaals, CaloricallyPerfect, ThermallyPerfect, ConstantDensity, RedlichKwong GoverningEquationsType Null, UserDefined, FullPotential, Euler, NSLaminar, NSTurbulent, NSLaminarIncompressible, NSTurbulentIncompressible GridConnectivityType Null, UserDefined, Overset, Abutting, Abutting1to1 GridLocation Null, UserDefined, Vertex, CellCenter, FaceCenter, IFaceCenter, JFaceCenter, KFaceCenter, EdgeCenter LengthUnits Null, UserDefined, Meter, Centimeter, Millimeter, Foot, Inch MassUnits Null, UserDefined, Kilogram, Gram, Slug, PoundMass ModelType Null, UserDefined, Ideal, VanderWaals, Constant, PowerLaw, SutherlandLaw, ConstantPrandtl, EddyViscosity, ReynoldsStress, ReynoldsStressAlgebraic, Algebraic BaldwinLomax, Algebraic CebeciSmith, HalfEquation JohnsonKing, OneEquation BaldwinBarth, OneEquation SpalartAllmaras, TwoEquation JonesLaunder, TwoEquation MenterSST, TwoEquation Wilcox, CaloricallyPerfect, ThermallyPerfect, ConstantDensity, RedlichKwong, Frozen, ThermalEquilib, ThermalNonequilib, ChemicalEquilibCurveFit, ChemicalEquilibMinimization, ChemicalNonequilib OpenMode MODE READ, MODE WRITE, MODE CLOSED, MODE MODIFY B.2. Class methods 37 PointSetType Null, UserDefined, PointList, PointListDonor, PointRange, PointRangeDonor, ElementRange, ElementList, CellListDonor RigidGridMotionType Null, UserDefined, ConstantRate, VariableRate SimulationType Null, UserDefined, TimeAccurate, NonTimeAccurate TemperatureUnits Null, UserDefined, Kelvin, Celcius, Rankine, Fahrenheit ThermalConductivityModelType Null, UserDefined, Constant, PowerLaw, SutherlandLaw, ConstantPrandtl ThermalRelaxationModelType Null, UserDefined, ThermalNonequilib, ThermalEquilib, Frozen TimeUnits Null, UserDefined, Second TurbulenceClosureType Null, UserDefined, ReynoldsStressAlgebraic, EddyViscosity, ReynoldsStress TurbulenceModelType Null, UserDefined, Algebraic BaldwinLomax, Algebraic CebeciSmith, HalfEquation JohnsonKing, OneEquation BaldwinBarth, OneEquation SpalartAllmaras, TwoEquation JonesLaunder, TwoEquation MenterSST, TwoEquation Wilcox ViscosityModelType Null, UserDefined, Constant, PowerLaw, SutherlandLaw WallFunctionType Null, UserDefined, Generic ZoneType Null, UserDefined, Structured, Unstructured The LabelString dictionnary LabelString ArbitraryGridMotion t, BCDataSet t, BCData t, BC t, BaseIterativeData t, CGNSBase t, CGNSLibraryVersion t, ChemicalKineticsModel t, ConvergenceHistory t, DataArray t, DataClass t, DataConversion t, Descriptor t, DimensionalExponents t, DimensionalUnits t, DiscreteData t, Elements t, FamilyBC t, FamilyName t, Family t, FlowEquationSet t, FlowSolution t, GasModel t, GeometryEntity t, GeometryFile t, GeometryFormat t, GeometryReference t, GoverningEquations t, GridConnectivity1to1 t, GridConnectivityType t, GridConnectivity t, GridCoordinates t, GridLocation t, IndexArray t, IndexRange t, IntegralData t, InwardNormalList t, Ordinal t, OversetHoles t, ReferenceState t, RigidGridMotion t, Rind t, SimulationType t, ThermalConductivityModel t, ThermalRelaxationModel t, TurbulenceClosure t, TurbulenceModel t, UserDefinedData t, ViscosityModel t, ZoneBC t, ZoneGridConnectivity t, ZoneIterativeData t, ZoneType t, Zone t 38 Appendix B. pyCGNS class The Names dictionnary Names % A C D E F G H I L M N O P R S T V Z %sMagnitude, %sNormal, %sPhi, %sTangential, %sTheta, %sX, %sY, %sZ, Acoustic, ArbitraryGridMotionPointers, CharacteristicAcousticMinus, CharacteristicAcousticPlus, CharacteristicEntropy, CharacteristicVorticity1, CharacteristicVorticity2, CoefDrag, CoefLift, CoefMomentEta, CoefMomentPhi, CoefMomentR, CoefMomentTheta, CoefMomentX, CoefMomentXi, CoefMomentY, CoefMomentZ, CoefMomentZeta, CoefPressure, CoefSkinFrictionX, CoefSkinFrictionY, CoefSkinFrictionZ, Coef Area, Coef Length, Coef PressureDynamic, Coef PressureReference, CoordinateEta, CoordinateNormal, CoordinatePhi, CoordinateR, CoordinateTangential, CoordinateTheta, CoordinateTransform, CoordinateX, CoordinateXi, CoordinateY, CoordinateZ, CoordinateZeta, Density, DensityStagnation, Drag, ElementConnectivity, EnergyInternal, EnergyKinetic, EnergyStagnation, EnergyStagnationDensity, Enthalpy, EnthalpyStagnation, Entropy, EntropyApprox, FamilyPointers, FlowSolutionsPointers, ForcePhi, ForceR, ForceTheta, ForceX, ForceY, ForceZ, FuelAirRatio, GridCoordinatesPointers, GridVelocityEta, GridVelocityPhi, GridVelocityR, GridVelocityTheta, GridVelocityX, GridVelocityXi, GridVelocityY, GridVelocityZ, GridVelocityZeta, HeatOfFormation, HeatOfFormation%s, IdealGasConstant, InterpolantsDonor, IterationValues, LaminarViscosity, LaminarViscosity%s, LengthReference, Lift, Mach, Mach Velocity, Mach VelocitySound, MassFlow, MassFraction, MassFraction%s, MoleFraction, MoleFraction%s, MolecularWeight, MolecularWeight%s, MomentEta, MomentPhi, MomentR, MomentTheta, MomentX, MomentXi, MomentY, MomentZ, MomentZeta, Moment CenterX, Moment CenterY, Moment CenterZ, MomentumMagnitude, MomentumX, MomentumY, MomentumZ, NumberOfFamilies, NumberOfZones, OriginLocation, ParentData, Potential, PowerLawExponent, Prandtl, PrandtlTurbulent, Prandtl SpecificHeatPressure, Prandtl ThermalConductivity, Prandtl ViscosityMolecular, Pressure, PressureDynamic, PressureStagnation, Reynolds, ReynoldsStressXX, ReynoldsStressXY, ReynoldsStressXZ, ReynoldsStressYY, ReynoldsStressYZ, ReynoldsStressZZ, Reynolds Length, Reynolds Velocity, Reynolds ViscosityKinematic, RiemannInvariantMinus, RiemannInvariantPlus, RigidGridMotionPointers, RigidRotationAngle, RigidRotationRate, RigidVelocity, SkinFrictionMagnitude, SkinFrictionX, SkinFrictionY, SkinFrictionZ, SpecificHeatPressure, SpecificHeatRatio, SpecificHeatRatio Pressure, SpecificHeatRatio Volume, SpecificHeatVolume, StreamFunction, SutherlandLawConstant, Temperature, TemperatureReference, TemperatureStagnation, ThermalConductivity, ThermalConductivity%s, ThermalConductivityReference, TimeValues, TurbulentBBReynolds, TurbulentDissipation, TurbulentDissipationRate, TurbulentDistance, TurbulentEnergyKinetic, TurbulentSANuTilde, VelocityAngleX, VelocityAngleY, VelocityAngleZ, VelocityMagnitude, VelocityNormal, VelocityPhi, VelocityR, VelocitySound, VelocitySoundStagnation, VelocityTangential, VelocityTheta, VelocityUnitVectorX, VelocityUnitVectorY, VelocityUnitVectorZ, VelocityX, VelocityY, VelocityZ, VibrationalElectronEnergy, VibrationalElectronTemperature, ViscosityEddy, ViscosityEddyDynamic, ViscosityKinematic, ViscosityMolecular, ViscosityMolecularReference, VorticityMagnitude, VorticityX, VorticityY, VorticityZ, ZonePointers B.2. Class methods 39 40 APPENDIX C User’s Guide to CGNS examples C.1 write grid str.py #!/usr/bin/env python # User’s Guide to CGNS - C.L.Rumsey et al. examples translation # import CGNS from numarray import * (imax,jmax,kmax)=(21,17,9) x=array(ones((imax,jmax,kmax),Float)) y=array(ones((imax,jmax,kmax),Float)) z=array(ones((imax,jmax,kmax),Float)) isize=range(9) for k in range(kmax): for j in range(jmax): for i in range(imax): x[i,j,k]=(i-1)*1.0 y[i,j,k]=(j-1)*1.0 z[i,j,k]=(k-1)*1.0 file=CGNS.pyCGNS(’grid.cgns’,CGNS.MODE_WRITE) basename=’Base’ icelldim,iphysdim=(3,3) index_base=file.basewrite(basename,icelldim,iphysdim) zonename=’Zone 1’ isize[0]=21 isize[1]=17 isize[2]=9 isize[3]=isize[0]-1 isize[4]=isize[1]-1 isize[5]=isize[2]-1 isize[6]=0 isize[7]=0 isize[8]=0 # vertex size # cell size # boundary vertex size (zero for structured grids) index_zone=file.zonewrite(index_base,zonename,isize,CGNS.Structured) file.coordwrite(index_base,index_zone,CGNS.RealDouble,CGNS.CoordinateX,x) file.coordwrite(index_base,index_zone,CGNS.RealDouble,CGNS.CoordinateY,y) file.coordwrite(index_base,index_zone,CGNS.RealDouble,CGNS.CoordinateZ,z) file.close() 41 C.2 read grid str.py #!/usr/bin/env python # # User’s Guide to CGNS - C.L.Rumsey et al. examples translation # ## read_grid_str.py # This is an example translation, this is a not straight word-to-word # translation, it also tryes to emphasize some Python constructs # import CGNS from Numeric import * (imax,jmax,kmax)=(21,17,9) # open CGNS file for read-only file=CGNS.pyCGNS(’grid.cgns’,CGNS.MODE_READ) # we know there is only one base and zone (real working code would check!) (index_base,index_zone)=(1,1) # get zone size (and name - although not needed here) (base_index,index_zone,zonename,isize)=file.zoneread(index_base,index_zone) # lower range index irmin=[1,1,1] # upper range index of vertices irmax=[isize[0],isize[1],isize[2]] # read grid coordinates (min/max not used) x=file.coordread(index_base,index_zone,CGNS.CoordinateX) y=file.coordread(index_base,index_zone,CGNS.CoordinateY) z=file.coordread(index_base,index_zone,CGNS.CoordinateZ) # close CGNS file file.close() 42 Appendix C. User’s Guide to CGNS examples APPENDIX D Passing arrays from/to fortran or C code These demos can be found in the demo directory of the package. The PyArray type allows the developper to user an already allocated memory zone for your data. If you want to use the package with your code, either fortran or C (C++), you have to use the PyArray library, create an object of this type and set the memory zone with yours. Let us see how to make this in details, imagine your own software is what we are calling now the solver. As a matter of fact, these examples are not dealing with pyCGNS, but rather with the Numerical Python arrays. These arrays are the preferred way to exchange data between the Python interpreter and any other entity. The scenario and code examples are a way of doing things. You can use other techniques, packages, design choices to do the same things. The Python interpreter is very powerful at allowing extension or embedded processing, make your own mind. D.1 Solver pre-processing example The scenario is the following: you want a pyCGNS pre-processing, with a Python script. Then read a CGNS file, use the numerical Python functions on some arrays and now, you want to pass this array to your C solver without memory duplication. This is a C langage example. D.2 Solver post-processing example This part is not completed The scenario is almost the same as the previous one. Now, we have a fortran solver, that produces a large data array. We want to retrieve it in the Python memory and post-process it with numerical Python, then we use pyCGNS to store the result. This is a fortran example. D.3 An integrated solver This part is not completed Now we mix all that together. We have a solver, calling a Python script, creating Python objects. We are retrieving them to manage them in the solver. Your whole solver can be seen as a new Package. 43 44 INDEX Symbols init 2D, 19 (module), 13, 24 A adfroot (module), 24 arbitrarymotionread (module), 25 arbitrarymotionwrite (module), 25 arrayinfo (module), 27 arrayread (module), 27 arraywrite (module), 27 asGoto (module), 13 asListOfPath (module), 13 asListOfTree (module), 13 axisymread (module), 25 axisymwrite (module), 25 B baseid (module), 36 baseread (module), 25 bases (module), 25 basewrite (module), 25 bcarearead (module), 26 bcareawrite (module), 26 bcdatasetread (module), 26 bcdatasetwrite (module), 26 bcdatawrite (module), 26 bcid (module), 36 bcinfo (module), 26 bcnormalwrite (module), 26 bcread (module), 26 bcwallfunctionread (module), 26 bcwallfunctionwrite (module), 26 bcwrite (module), 26 biterread (module), 33 biterwrite (module), 33 C close (module), 24 connaverageread (module), 34 connaveragewrite (module), 34 conninfo (module), 32 connperiodicread (module), 34 connperiodicwrite (module), 34 connread (module), 32 connwrite (module), 32 convergenceread (module), 26 convergencewrite (module), 26 conversioninfo (module), 35 conversionread (module), 35 conversionwrite (module), 35 coordid (module), 36 coordinfo (module), 27 coordread (module), 27 coordwrite (module), 27 D dataclassread (module), 35 dataclasswrite (module), 35 deletenode (module), 33 descriptorread (module), 27 descriptors (module), 27 descriptorwrite (module), 27 diffusionread (module), 30 diffusionwrite (module), 30 discreteread (module), 28 discretewrite (module), 28 E elementdatasize (module), 28 elementsread (module), 28 equationsetchemistryread (module), 30 equationsetread (module), 30 equationsetwrite (module), 30 exponentsinfo (module), 35 exponentsread (module), 35 exponentswrite (module), 35 extract (module), 13 F familybocoread (module), 29 familybocowrite (module), 29 familynameread (module), 29 familynamewrite (module), 29 familyread (module), 29 familywrite (module), 29 fieldid (module), 36 fieldinfo (module), 31 fieldread (module), 31 fieldwrite (module), 31 45 G georead (module), 29 geowrite (module), 29 getADF (module), 13 goto (module), 33 governingread (module), 30 governingwrite (module), 30 gravityread (module), 25 gravitywrite (module), 25 gridlocationread (module), 31 gridlocationwrite (module), 31 gridread (module), 31 gridwrite (module), 31 H nsections (module), 28 nsols (module), 31 nuserdata (module), 35 nzones (module), 36 O one2oneid (module), 36 one2oneread (module), 32 one2onereadglobal (module), 32 one2onewrite (module), 32 ordinalread (module), 33 ordinalwrite (module), 33 P holeinfo (module), 34 holeread (module), 34 holewrite (module), 34 parentdatawrite (module), 28 partread (module), 29 partwrite (module), 29 pop (module), 13 I R id (module), 24 integralread (module), 32 integralwrite (module), 32 isAbsolute (module), 13 islink (module), 33 rigidmotionread (module), 34 rigidmotionwrite (module), 34 rindread (module), 31 rindwrite (module), 31 rotatingread (module), 34 rotatingwrite (module), 34 J jump (module), 13 L lasterror (module), 24 libversion (module), 24 linkread (module), 33 links, 19 linkwrite (module), 33 M modelread (module), 30 modelwrite (module), 30 N name (module), 24 narbitrarymotions (module), 25 narrays (module), 27 nbc (module), 26 nconns (module), 32 ncoords (module), 27 ndiscrete (module), 28 nfamilies (module), 29 nfields (module), 31 ngrids (module), 31 nholes (module), 34 nintegrals (module), 32 none2one (module), 32 none2oneglobal (module), 32 npe (module), 28 nrigidmotions (module), 34 46 S sectionread (module), 28 sectionwrite (module), 28 simulationtyperead (module), 30 simulationtypewrite (module), 30 solid (module), 36 solinfo (module), 31 solwrite (module), 31 split (module), 13 stateread (module), 30 statewrite (module), 30 structured, 19 U unitsread (module), 35 unitswrite (module), 35 unstructured, 19 userdataread (module), 35 userdatawrite (module), 35 Z ziterread (module), 33 ziterwrite (module), 33 zoneid (module), 36 zoneread (module), 36 zonetype (module), 36 zonewrite (module), 36 Index