3D Cube Validation test case

References

K. Sedighi et. al. (2006) .Three dimensional study of vortical structure around a cubic bluff bofy in a channel. Facta Universitadis Mechanical Engineering vol.(2), no.(1), pp.1-16

Martinuzzi and Tropea (1993).The flow around surface mounted, prismatic obstacles placed in a fully developed channel.Journal of Fluids Engineering. Vol 115

Define case name

This is the solver case to be analysed


In [1]:
case_name = 'cube'

Define Data Location

For remote data the interaction will use ssh to securely interact with the data
This uses the reverse connection capability in paraview so that the paraview server can be submitted to a job scheduler
Note: The default paraview server connection will use port 11111


In [2]:
remote_data = True

#data_dir='/gpfs/asrc/home/acimpoeru/cube_JA/CUBE'

#data_dir='/gpfs/asrc/home/acimpoeru/Cube/zCFDInterface/zCFDInterface'
data_dir='/gpfs/asrc/home/acimpoeru/cube_fine_mesh'
#data_dir='/gpfs/asrc/home/acimpoeru/cube_kO_sst/Cube_Spalart_OF/cube/VTK'
data_host='acimpoeru@login02'

remote_server_auto = True

paraview_cmd='mpiexec /gpfs/thirdparty/zenotech/home/jappa/apps/Paraview/bin/pvserver -rc --client-host=localhost -sp=11115'
if not remote_server_auto:
    paraview_cmd=None

if not remote_data:
    data_host='localhost'
    paraview_cmd=None

Initialise Environment


In [3]:
%pylab inline
from paraview.simple import *
paraview.simple._DisableFirstRenderCameraReset()
import pylab as pl
import math
import numpy as np


Populating the interactive namespace from numpy and matplotlib
paraview version 4.1.0

Data Connection

This starts paraview server on remote host and connects


In [4]:
from zutil.post import pvserver_connect
if remote_data:
    pvserver_connect(data_host=data_host,data_dir=data_dir,paraview_cmd=paraview_cmd,paraview_remote_port=11115)


[acimpoeru@login02] Executing task 'pvserver'
[acimpoeru@login02] run: sleep 2;mpiexec /gpfs/thirdparty/zenotech/home/jappa/apps/Paraview/bin/pvserver -rc --client-host=localhost -sp=11115&>/dev/null
[acimpoeru@login02] out: 
[acimpoeru@login02] out: 		   _____ ______ __  __  _____ 
[acimpoeru@login02] out: 		  / ____|  ____|  \/  |/ ____|
[acimpoeru@login02] out: 		 | |    | |__  | \  / | (___  
[acimpoeru@login02] out: 		 | |    |  __| | |\/| |\___ \ 
[acimpoeru@login02] out: 		 | |____| |    | |  | |____) |
[acimpoeru@login02] out: 		  \_____|_|    |_|  |_|_____/ 
[acimpoeru@login02] out:                               
[acimpoeru@login02] out:                               
[acimpoeru@login02] out: 
[acimpoeru@login02] out: ++++++++++++++++++++++++++++: System Data :++++++++++++++++++++++++++++
[acimpoeru@login02] out: + Hostname = login02
[acimpoeru@login02] out: + Kernel = 2.6.32-358.el6.x86_64
[acimpoeru@login02] out: + RHEL Release = Red Hat Enterprise Linux Server release 6.4 (Santiago)
[acimpoeru@login02] out: + Uptime = 09:10:38 up 98 days, 20:54, 38 users,
[acimpoeru@login02] out: + CPU = 2x Intel Xeon X5570 @ 2.93GHz
[acimpoeru@login02] out: + Memory = 49415076 kB
[acimpoeru@login02] out: ++++++++++++++++++++++++++++: User Data :++++++++++++++++++++++++++++++
[acimpoeru@login02] out: + Username = acimpoeru
[acimpoeru@login02] out: +++++++++++++++++++++++: Contact Information :+++++++++++++++++++++++++
[acimpoeru@login02] out: + in case of any problems, contact: support@cfms.org.uk
[acimpoeru@login02] out: + for feedback, contact: feedback@cfms.org.uk 
[acimpoeru@login02] out: +++++++++++++++++++++: Maintenance Information :+++++++++++++++++++++++
[acimpoeru@login02] out: + There is no planned maintenance for the cluster
[acimpoeru@login02] out: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
[acimpoeru@login02] out: 
[acimpoeru@login02] out: 

Get control dictionary


In [5]:
from zutil.post import get_case_parameters,print_html_parameters
parameters=get_case_parameters(case_name,data_host=data_host,data_dir=data_dir)

Get status file


In [6]:
from zutil.post import get_status_dict
status=get_status_dict(case_name,data_host=data_host,data_dir=data_dir)
num_procs = str(status['num processor'])

Define test conditions


In [7]:
alpha = 0.0 # degrees
beta  = 0.0 # degrees
Re = 0.04e06 # Reynolds number 
reference_area = 1.0 # frontal areas in metres^2
reference_length = 1.0 # metres
U_inf = 10.0 # reference velocity
pressure = 101325.0 # Pa
temperature = 288.15 # i.e. 15 degrees celcius
gas_constant = 287.0
density  = pressure/(gas_constant * temperature) # kg/m^3 - check
gamma = 1.4
speed_of_sound = math.sqrt(gamma * gas_constant * temperature) # m/s

mach = U_inf/speed_of_sound      # Mach number of the case 

from IPython.display import HTML
HTML(print_html_parameters(parameters))


Out[7]:
pressure101325.0
temperature287.15
Reynolds No40000.0
Ref length1.0
Speed10.0
Mach No0.0

Read experimental data of Martinuzzi


In [9]:
import zutil
import zutil.post as post
reload(zutil)
reload(post)
#from zutil.post import get_csv_data

data = zutil.post.get_csv_data("/gpfs/asrc/home/acimpoeru/cube_JA/CUBE/data.csv",header=True,remote=True,delim=',')
#print data.keys()
#print data['y/H'], data['U/Ub']

y_exp = data['y/H']
vel_exp = data['U/Ub']

#print y_exp, vel_exp

Read the LES Data


In [11]:
import zutil
import zutil.post as post
reload(zutil)
reload(post)
#from zutil.post import get_csv_data

les = zutil.post.get_csv_data("/gpfs/asrc/home/acimpoeru/cube_JA/CUBE/les.csv",header=True,remote=True,delim=',')
print les.keys()
#print data['y/H'], data['U/Ub']


['Height', 'U']

import OpenFoam data


In [13]:
import zutil
import zutil.post as post
reload(zutil)
reload(post)
#from zutil.post import get_csv_data

OF = zutil.post.get_csv_data("/gpfs/asrc/home/acimpoeru/cube_kO_sst/Cube_Spalart_OF/cube/VTK/Open_Foam.csv",header=True,remote=True,delim=',')
print OF.keys()


['"p"', '"nut"', '"k"', '"omega"', '"U:0"', '"U:1"', '"U:2"', '"Points:0"', '"Points:1"', '"Points:2"']

In [14]:
from zutil.post import for_each

def plot_velocity_profile(ax,file_root,full_path=False):
    
    if full_path:
        sym = PVDReader( FileName=file_root )
    else:
        sym = PVDReader( FileName=file_root+'.pvd' )
    sym.UpdatePipeline()
    
   # clip = Clip( ClipType="Plane", Input=sym )
   # clip.ClipType.Normal = [0.0, 1.0, 0.0]
   # clip.ClipType.Origin = [0, -0.01, 0  
   # clip.UpdatePipeline()

    slice1 = Slice(SliceType = 'Plane',Input=sym) 
    slice1.SliceType.Normal = [0.0 , 1.0 , 0.0]
    slice1.SliceType.Origin = [0.0 , 0.0 , 0.0]
    slice1.UpdatePipeline()
    
    
    slice2 = Slice(SliceType = "Plane",Input = slice1)
    slice2.SliceType.Normal = [1.0 , 0.0 , 0.0]
    slice2.SliceType.Origin = [0.5 , 0.0 , 0.0]
    slice2.UpdatePipeline()
    
    
    #clip2 = Clip( ClipType="Plane", Input=clip )
    #clip2.ClipType.Normal = [0.0, 0.0, -1.0]
    #clip2.ClipType.Origin = [0, 0.0, 0.8]    
    #clip2.UpdatePipeline()

    point_data = CellDatatoPointData(Input=slice2)
    point_data.PassCellData = 0
    point_data.UpdatePipeline()
    print point_data
    point_client = servermanager.Fetch(point_data)
    for_each(point_client,func=plot_array,axis=ax)
    
def plot_array(data_array,pts_array,**kwargs):
    ax = kwargs['axis']
    data = []
    count = 0
    u_vel = data_array.GetPointData()['V'][:,0]
    for p in pts_array.GetPoints()[:,0]:
        data.append(float(u_vel[count])/10.0)
        count+=1 
    ax.plot(data, pts_array.GetPoints()[:,2], color='g',marker='o',label='zCFD')

Velocity profiles y=0


In [15]:
from zutil.post import get_case_root
#zcfd_cp_data = get_cp_profile(get_case_root(case_name,num_procs))
fig = pl.figure(figsize=(20, 10),dpi=600, facecolor='w', edgecolor='k')
fig.suptitle('3D wall mounted cube Velocity profiles', fontsize=20, fontweight='bold')
ax = fig.add_subplot(1,1,1)
ax.grid(True)
ax.set_xlabel('U/U_ref')
ax.set_ylabel('z/H')
#ax.axis([-1.6,0.8,0,0.8])
#ax.plot(zcfd_cp_data['x'],zcfd_cp_data['z'], color='grey',linestyle='-',marker='None',markersize=5)
#ax.plot(profile_array['x'],profile_array['z'], color='grey', label='station',linestyle='none',marker='.',markersize=1)
#ax.plot(profile_array['delta'],profile_array['z'], color='b', label='Expt U',marker='o',linestyle='none',fillstyle='none')
plot_velocity_profile(ax,get_case_root(case_name,num_procs))
#plot_velocity_profile(ax,'/gpfs/asrc/home/acimpoeru/cube_kO_sst/Cube_Spalart_OF/cube/VTK/cube_14000.vtk',True)
ax.plot(data['U/Ub'], data['y/H'], color='r', label='exp')
ax.plot(les['U'], les['Height'], color='k', label='LES')
ax.plot(OF['"U:0"']/0.584, OF['"Points:2"'], color='b', label='Open Foam')
ax.legend(loc='upper right', shadow=True)
fig.savefig("cube.pdf")
#from IPython.display import FileLink, display 
#display(FileLink('images/ahmed_vel_profile.pdf'))
show()


<paraview.servermanager.CellDatatoPointData object at 0x110572a10>
use append poly data filter

In [16]:
## Calculate the RMS Error

interpolate using numpy.....See reference guide

Convergence


In [17]:
from zutil.post import residual_plot, get_case_report
residual_plot(get_case_report(case_name))
show()


Cleaning up


In [18]:
if remote_data:
    #print 'Disconnecting from remote paraview server connection'
    Disconnect()
    pass