1#!/usr/local/bin/python3.8
2# The major purpose of EvalTank.py is to set up the $x$ and $\varphi $ locations for
3# four common usages of FEMTank.py and generally make life easier.
4# It utilizes Dakota friendly input/output via text files
5
6# Usage: this is called from the command line or script.
7# python EvalTank.py input_file_name summary_file_name data_file_name
8
9
10# Arguments:
11## inputFileName - gives the parameter values (in dprepro format).
12## summaryFileName - results file to be written (in a format suitable for Dakota)
13## dataFileName - writes out detailed simulation results, in plain text
14##   this can be large. This is optional, if nothing is passed, no datafile is written.
15##   if an empty string "" is passed, no datafile is written
16
17
18# The inputFile must have the following inputs: P Gamma_Chi H E Nu L R T meshID resultStyle
19##  the names MUST be consistent, but the ordering does not matter
20##  The first 9 inputs are described in FEMTank.py
21##  Note that if either Gamma_Chi OR H is ommitted, they will both be set to 0 (pressure only scenario)
22
23# resultStyle is used to select from four predetermined sets of responses
24##  It selects the location inputs X_vec and Phi_vec, and sets flags to produce speciallized summaryFiles
25##
26##  resultStyle 1
27###  Set up a fine grid of $x$ and $\varphi $,
28###  This is suitable for visualizing the model responses, but takes longer to run
29###  Normal reporting in summaryFile and dataFile
30##
31##  resultStyle 2
32###  Set up a nonuniform grid of $x$ and $\varphi $, finest near the centerline and the support.
33###  This is suitable for searching for the max von Mises stress, with less computational expense
34###  Normal reporting in summaryFile and dataFile
35##
36##  resultStyle 3
37###  Set $x$ and $\varphi $ to the nominal locations corresponding to Dataset 5 - Pressure only loading tests. See the problem statement.
38###  Print only the four displacements to the summaryFile. No dataFile is written.
39##
40##  resultStyle 4
41###  Set $x$and $\varphi $ to the nominal locations corresponding to Dataset 6 - Pressure and Liquid loading tests. See the problem statement.
42###  Print only the 20 displacements to the summaryFile. No dataFile is written.
43##
44##  If other locations are required, use FEMTank.py directly.
45
46from sys import argv
47from subprocess import call
48from math import pi
49
50def main():
51  if len(argv) < 3:
52    print('Usage: EvalTank.py input_file_name summary_file_name [data_file_name]')
53    return 1
54  elif len(argv) < 4:
55    dataFileName = ''
56  else:
57    dataFileName = argv[3]
58  inputFileName = argv[1]
59  summaryFileName = argv[2]
60
61# Read inputs
62  inputDict = {}
63  with open(inputFileName, "r") as f:
64    for line in f:
65      if line.strip().split('#')[0].strip('\n'): # only parse non-empty lines, and ignore comments (#)
66        tempLine = line.split('#')[0]
67        if not ( 'DVV_' in tempLine or 'ASV_' in tempLine or tempLine.startswith('#')): # Dakota adds some extra information to the I/O files
68          (valueString, name) = tempLine.split()
69          name = name.strip()
70          value = float(valueString) #fails if valueString is not a string of numbers... currently have no validation
71          inputDict[name] = value
72    f.close()
73
74  Length = inputDict.get('L') #inches
75  Thickness = inputDict.get('T') #inches
76  Radius = inputDict.get('R') #inches
77
78  E = inputDict.get('E') #Young's modulus (lb_f / inches ^2)
79  Nu = inputDict.get('Nu') #Poisson's ratio
80
81  Pressure = inputDict.get('P') #Internal Pressure (lb_f/in^2 gage)
82  if (inputDict.get('H') != None) and (inputDict.get('Gamma_Chi') != None):
83    LiqHeight = inputDict.get('H') #height of liquid (inches)
84    Gamma_Chi = inputDict.get('Gamma_Chi') #liquid specific weight (lb_f / inches^3)
85  else:
86    LiqHeight = 0
87    Gamma_Chi = 0
88
89  meshID = inputDict.get('meshID')
90  if meshID == 24: #flag to run "untanked" cylinder, must also specify M,N
91    if (inputDict.get('N') != None) and (inputDict.get('M') != None):
92      N = inputDict.get('N')
93      M = inputDict.get('M')
94    else:
95      print('When using special meshID flag, you must specify M and N values')
96      return 24
97
98  resultStyle = inputDict.get('resultStyle')
99
100# Observations
101  # x=0 is at the centerline
102  if resultStyle == 1: #high fidelity, for plotting, etc.
103    nX=101
104    dx=Length/(nX-1)/2 # Half-plane symmetry
105    X_vec = [idx*dx for idx in range(0,nX)]
106    nPhi=91
107    dPhi=pi/(nPhi-1)
108    Phi_vec = [idx*dPhi for idx in range(0,nPhi)]
109    if dataFileName == '':
110      dataFileName = summaryFileName + '.data'
111
112  elif resultStyle == 2: # balance run time and accuracy of the max statistic
113    nX=51
114    dx=Length/(nX-1)/2 # Half-plane symmetry
115    X_vec = [idx*dx for idx in range(0,int(nX*1/8))]+[idx*dx for idx in range(int(nX*5/8),nX)] #all the action is at the end or near the middle.
116    nX=len(X_vec)
117    nPhi=61
118    dPhi=pi/(nPhi-1)
119    Phi_vec = [idx*dPhi for idx in range(0,int(nPhi*5/6))] #exclude the top 5 inches
120    nX=len(X_vec)
121
122  elif resultStyle == 3: # for Pressure Only Tests
123    X_vec = [0, 27, 28, 29]
124    nX=len(X_vec)
125    Phi_vec = [pi/6, pi/2, pi/4, 3*pi/4]
126    nPhi=len(Phi_vec)
127    dataFileName = 'DisplacementsDataOnDiagonal'
128
129  elif resultStyle == 4: # for Validation tests
130    X_vec = [0, 15, 20, 25]
131    nX=len(X_vec)
132    Phi_vec = [pi/6, pi/3, pi/2, 2*pi/3, 5*pi/6]
133    nPhi=len(Phi_vec)
134    dataFileName = 'DisplacementsDataFullGrid'
135
136  else:
137    print("resultStyle must be 1, 2, 3, or 4")
138    return 404
139
140  import FEMTank
141  if (meshID != 24):
142    # Run the tank (skewed cylinder)
143    FEMTank.main(X_vec, Phi_vec, Pressure, Gamma_Chi, LiqHeight, E, Nu, Length, Radius, Thickness, meshID, summaryFileName, dataFileName)
144  else:
145    # Run the cylinder
146    FEMTank.cylinder(X_vec, Phi_vec, Pressure, Gamma_Chi, LiqHeight, E, Nu, Length, Radius, Thickness, M, N, summaryFileName, dataFileName)
147
148if __name__ == "__main__":
149  main()
150