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