#!/usr/bin/env python
# -*- coding: utf-8 -*-

#***************************************************************************
#*   Copyright (C) 2009 by Oliver Borm                                     *
#*  oli.borm@web.de                                                        *
#*                                                                         *
#*   This program is free software; you can redistribute it and/or modify  *
#*   it under the terms of the GNU General Public License as published by  *
#*   the Free Software Foundation; either version 3 of the License, or     *
#*   (at your option) any later version.                                   *
#*                                                                         *
#*   This program is distributed in the hope that it will be useful,       *
#*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
#*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
#*   GNU General Public License for more details.                          *
#*                                                                         *
#*   You should have received a copy of the GNU General Public License     *
#*   along with this program; if not, write to the                         *
#*   Free Software Foundation, Inc.,                                       *
#*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
#***************************************************************************

# Author: Oliver Borm
# Date: May 2009

from CGNS import CGNS

#Definition of globals

cell_dim = 3
phys_dim = 3
numberZones = 1

NVertexR = 5
NVertexZ = 15
NVertexdepth = 3

length = 2.0
width = 1.0
depth = 0.5

debug = 2

dateiName = "abc0.cgns"
blockName = "block_"

#########################################

numberNodes = NVertexZ*NVertexR*NVertexdepth

sizeZones = cell_dim*phys_dim

filePointer = CGNS.intp()
ier = CGNS.cg_open(dateiName, CGNS.CG_MODE_WRITE, filePointer)
fileValue = filePointer.value()
b = CGNS.intp()
ier = CGNS.cg_base_write ( fileValue, "Base", cell_dim, phys_dim, b )
ier = CGNS.cg_close ( filePointer.value() )

##############

filePointer = CGNS.intp()
bPointer = CGNS.intp()
bPointer.assign(1)
bValue = bPointer.value()

ier = CGNS.cg_open ( dateiName, CGNS.CG_MODE_MODIFY, filePointer)
fileValue = filePointer.value()
ier = CGNS.cg_goto ( fileValue, bValue, "end" )

#//! Creates Subknot of Typ 'Zone_t' (Kap. 6.2)
zoneArrayp= CGNS.intArray(sizeZones)
#vertex size
zoneArrayp[0] = NVertexdepth #X-Coordinate
zoneArrayp[1] = NVertexR #Y-Coordinate
zoneArrayp[2] = NVertexZ #Z-Coordinate
#cell size
zoneArrayp[3] = zoneArrayp[0]-1
zoneArrayp[4] = zoneArrayp[1]-1
zoneArrayp[5] = zoneArrayp[2]-1
#boundary vertex size (always zero for structured grids)
zoneArrayp[6] = 0
zoneArrayp[7] = 0
zoneArrayp[8] = 0

if debug >=2:
	for i in range(sizeZones):
		print zoneArrayp[i]

#//! Writes Coordinates (Kap. 11.1)
CoordX= CGNS.doubleArray(numberNodes)
CoordY= CGNS.doubleArray(numberNodes)
CoordZ= CGNS.doubleArray(numberNodes)

sol_dichte= CGNS.doubleArray(numberNodes)

n = 0
for i in range(NVertexZ):
	for j in range(NVertexR):
		for k in range(NVertexdepth):
			if NVertexdepth > 1:
				CoordX[n] = depth/(NVertexdepth-1)*k
			else:
				CoordX[n] = 0.0
				
			CoordY[n] = width/(NVertexR-1)*j
			CoordZ[n] = length/(NVertexZ-1)*i
			
			sol_dichte[n] = .125*n
			
			n += 1

if debug >=3:
	for n in range(numberNodes):
		print CoordX[n], CoordY[n], CoordZ[n]
	

zoneSizep = CGNS.intp()
ier = CGNS.cg_zone_write ( fileValue, bValue, blockName+str(bValue) , zoneArrayp, CGNS.Structured, zoneSizep )

zoneSizepValue = zoneSizep.value()

if debug >=2: print "Write Coordinates"

C = CGNS.intp()

ier = CGNS.cg_coord_write ( fileValue, bValue, zoneSizepValue, CGNS.RealDouble, "CoordinateX", CoordX, C )
if debug >=2: print ier, C.value()

ier = CGNS.cg_coord_write ( fileValue, bValue, zoneSizepValue, CGNS.RealDouble, "CoordinateY", CoordY, C )
if debug >=2: print ier, C.value()

ier = CGNS.cg_coord_write ( fileValue, bValue, zoneSizepValue, CGNS.RealDouble, "CoordinateZ", CoordZ, C )
if debug >=2: print ier, C.value()

if debug >=2: print "Write Solution"

S = CGNS.intp()

#//! Writes FlowSolution
ier = CGNS.cg_sol_write ( fileValue, bValue, zoneSizepValue, "FlowSolution", CGNS.Vertex, S ) #// (Kap. 12.1)
if debug >=2 and ier!=0: print ier

## Does not work yet
#ier = CGNS.cg_gridlocation_write ( CGNS.Vertex ) # // (Kap. 9.1)
#if debug >=2 and ier!=0: print ier

ier = CGNS.cg_goto ( fileValue, bValue, "Zone_t", zoneSizepValue, "FlowSolution_t", S.value(), "end" )
if debug >=2 and ier!=0: print ier

sValue = S.value()

if debug >=2: print "Write Solutionfields"

F = CGNS.intp()

#//! SIDS-compliant FlowSolution // (Kap. 12.1)
ier = CGNS.cg_field_write ( fileValue, bValue, zoneSizepValue, sValue, CGNS.RealDouble, "Density", sol_dichte, F )
if debug >=2: print ier
#ier = cg_field_write ( fileValue, bValue, zoneSizepValue, sValue, CGNS.RealDouble, "Pressure", sol_p, F )
#ier = cg_field_write ( fileValue, bValue, zoneSizepValue, sValue, CGNS.RealDouble, "Temperature", sol_T, F )
#ier = cg_field_write ( fileValue, bValue, zoneSizepValue, sValue, CGNS.RealDouble, "Entropy", sol_entropie, F )
#ier = cg_field_write ( fileValue, bValue, zoneSizepValue, sValue, CGNS.RealDouble, "VelocityX", sol_Vu, F )
#ier = cg_field_write ( fileValue, bValue, zoneSizepValue, sValue, CGNS.RealDouble, "VelocityY", sol_Vr, F )
#ier = cg_field_write ( fileValue, bValue, zoneSizepValue, sValue, CGNS.RealDouble, "VelocityZ", sol_Vz, F )
#ier = cg_field_write ( fileValue, bValue, zoneSizepValue, sValue, CGNS.RealDouble, "VelocitySound", sol_a, F )

#//! Reference
ier = CGNS.cg_goto ( fileValue, bValue, "end" )
ier = CGNS.cg_state_write ( "Dimensional" ) # // (Kap. 10.1)
ier = CGNS.cg_close ( fileValue )

##########################################

filePointer = CGNS.intp()
ier = CGNS.cg_open ( dateiName, CGNS.CG_MODE_MODIFY, filePointer)
fileValue = filePointer.value()

bPointer = CGNS.intp()
bPointer.assign(1)
bValue = bPointer.value()

ier = CGNS.cg_goto ( fileValue, bValue, "end" )
ier = CGNS.cg_dataclass_write ( CGNS.Dimensional )
ier = CGNS.cg_units_write ( CGNS.Kilogram, CGNS.Meter, CGNS.Second, CGNS.Kelvin, CGNS.Radian )

nzones = CGNS.intp()
nsolutions = CGNS.intp()
nfields = CGNS.intp()

exp = CGNS.doubleArray(5)
dataType = CGNS.DataType_tp()
dataFieldName = CGNS.charp()

ier = CGNS.cg_nzones ( fileValue, bValue, nzones )

for Z in range(1,nzones.value()+1):
	
	ier = CGNS.cg_nsols ( fileValue, bValue, Z, nsolutions )
	
	for S in range(1,nsolutions.value()+1):
			
		ier = CGNS.cg_nfields ( fileValue, bValue, Z, S, nfields )
		
		for F in range(1,nfields.value()+1):
			
			ier = CGNS.cg_field_info ( fileValue, bValue, Z, S, F, dataType.cast(), dataFieldName )
			
			if CGNS.charP2String(dataFieldName) == "Density":
				if debug >=2: print CGNS.charP2String(dataFieldName)
				exp[0] = 1.0
				exp[1] = -3.0
				exp[2] = 0.0
				exp[3] = 0.0
				exp[4] = 0.0
			
			if debug >=3:
				for i in range(5):
					print exp[i]
			
			print fileValue, bValue, Z, S, F
			
			ier = CGNS.cg_goto ( fileValue, bValue, "Zone_t", Z, "FlowSolution_t", S, "DataArray_t", F, "end" )
			#print ier
			## Does not work yet.
			## ier = 3 --> CG_INCORRECT_PATH
			ier = CGNS.cg_exponents_write ( CGNS.RealDouble, exp )
			#ier = CGNS.cg_expfull_write ( CGNS.RealDouble, exp )
			if debug >=2 and ier!=0: print ier


##//! Closes CGNS file (Kap. 3.1)
ier = CGNS.cg_close ( fileValue )
