forked from OpenFAST/openfast
-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathexecuteFASTFarmRegressionCase.py
More file actions
172 lines (146 loc) · 7.22 KB
/
Copy pathexecuteFASTFarmRegressionCase.py
File metadata and controls
172 lines (146 loc) · 7.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#
# Copyright 2017 National Renewable Energy Laboratory
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""
This program executes FASTFarm and a regression test for a single test case.
The test data is contained in a git submodule, r-test, which must be initialized
prior to running. See the r-test README or OpenFAST documentation for more info.
Get usage with: `executeFASTFarmRegressionCase.py -h`
"""
import os
import sys
basepath = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.sep.join([basepath, "lib"]))
import argparse
import numpy as np
import shutil
import subprocess
import rtestlib as rtl
import openfastDrivers
import pass_fail
from errorPlotting import exportCaseSummary
##### Helper functions
excludeExt=['.out','.outb','.ech','.yaml','.sum','.log']
##### Main program
### Store the python executable for future python calls
pythonCommand = sys.executable
### Verify input arguments
parser = argparse.ArgumentParser(description="Executes OpenFAST and a regression test for a single test case.")
parser.add_argument("caseName", metavar="Case-Name", type=str, nargs=1, help="The name of the test case.")
parser.add_argument("executable", metavar="OpenFAST", type=str, nargs=1, help="The path to the OpenFAST executable.")
parser.add_argument("sourceDirectory", metavar="path/to/openfast_repo", type=str, nargs=1, help="The path to the OpenFAST repository.")
parser.add_argument("buildDirectory", metavar="path/to/openfast_repo/build", type=str, nargs=1, help="The path to the OpenFAST repository build directory.")
parser.add_argument("rtol", metavar="Relative-Tolerance", type=float, nargs=1, help="Relative tolerance to allow the solution to deviate; expressed as order of magnitudes less than baseline.")
parser.add_argument("atol", metavar="Absolute-Tolerance", type=float, nargs=1, help="Absolute tolerance to allow small values to pass; expressed as order of magnitudes less than baseline.")
parser.add_argument("-p", "-plot", dest="plot", action='store_true', help="bool to include plots in failed cases")
parser.add_argument("-n", "-no-exec", dest="noExec", action='store_true', help="bool to prevent execution of the test cases")
parser.add_argument("-v", "-verbose", dest="verbose", action='store_true', help="bool to include verbose system output")
parser.add_argument("-compFile", dest="compFile", metavar="comparison-file", type=str, nargs='?', const='arg_was_not_given', help="File to use for comparison (no extension)")
args = parser.parse_args()
caseName = args.caseName[0]
executable = args.executable[0]
sourceDirectory = args.sourceDirectory[0]
buildDirectory = args.buildDirectory[0]
rtol = args.rtol[0]
atol = args.atol[0]
plotError = args.plot
noExec = args.noExec
verbose = args.verbose
# file to use for comparison (ending not included)
if args.compFile is None:
compFile = caseName
elif args.compFile == 'arg_was_not_given':
compFile = caseName
else:
compFile = args.compFile
# validate inputs
rtl.validateExeOrExit(executable)
rtl.validateDirOrExit(sourceDirectory)
if not os.path.isdir(buildDirectory):
os.makedirs(buildDirectory, exist_ok=True)
### Build the filesystem navigation variables for running openfast on the test case
regtests = os.path.join(sourceDirectory, "reg_tests")
lib = os.path.join(regtests, "lib")
rtest = os.path.join(regtests, "r-test")
moduleDirectory = os.path.join(rtest, "glue-codes", "fast-farm")
inputsDirectory = os.path.join(moduleDirectory, caseName)
targetOutputDirectory = os.path.join(inputsDirectory)
testBuildDirectory = os.path.join(buildDirectory, caseName)
# verify all the required directories exist
if not os.path.isdir(rtest):
rtl.exitWithError("The test data directory, {}, does not exist. If you haven't already, run `git submodule update --init --recursive`".format(rtest))
if not os.path.isdir(targetOutputDirectory):
rtl.exitWithError("The test data outputs directory, {}, does not exist. Try running `git submodule update`".format(targetOutputDirectory))
if not os.path.isdir(inputsDirectory):
rtl.exitWithError("The test data inputs directory, {}, does not exist. Verify your local repository is up to date.".format(inputsDirectory))
# create the local copy of the common files for FAST.Farm cases
dst = os.path.join(buildDirectory, "5MW_Baseline")
src = os.path.join(moduleDirectory, "5MW_Baseline")
if not os.path.isdir(dst):
rtl.copyTree(src, dst, excludeExt=excludeExt)
else:
names = os.listdir(src)
for name in names:
if name == "ServoData":
continue
srcname = os.path.join(src, name)
dstname = os.path.join(dst, name)
if os.path.isdir(srcname):
if not os.path.isdir(dstname):
rtl.copyTree(srcname, dstname, excludeExt=excludeExt)
else:
shutil.copy2(srcname, dstname)
# create the local output directory for the turbulence library.
dst = os.path.join(buildDirectory, "WAT_MannBoxDB")
src = os.path.join(moduleDirectory, "WAT_MannBoxDB")
if not os.path.isdir(dst):
rtl.copyTree(src, dst, excludeExt=excludeExt)
# create the local output directory if it does not already exist
if not os.path.isdir(testBuildDirectory):
rtl.copyTree(inputsDirectory, testBuildDirectory, excludeExt=excludeExt)
caseName='FAST.Farm' # for ease of comparison
### Run openfast on the test case
if not noExec:
caseInputFile = os.path.join(testBuildDirectory, caseName + ".fstf")
returnCode = openfastDrivers.runOpenfastCase(caseInputFile, executable, verbose=verbose)
if returnCode != 0:
sys.exit(returnCode*10)
### Build the filesystem navigation variables for running the regression test
localOutFile = os.path.join(testBuildDirectory, compFile + ".out")
baselineOutFile = os.path.join(targetOutputDirectory, compFile + ".out")
rtl.validateFileOrExit(localOutFile)
rtl.validateFileOrExit(baselineOutFile)
testData, testInfo, _ = pass_fail.readFASTOut(localOutFile)
baselineData, baselineInfo, _ = pass_fail.readFASTOut(baselineOutFile)
passing_channels = pass_fail.passing_channels(testData.T, baselineData.T, rtol, atol)
passing_channels = passing_channels.T
norms = pass_fail.calculateNorms(testData, baselineData)
# export all case summaries
channel_names = testInfo["attribute_names"]
exportCaseSummary(testBuildDirectory, caseName, channel_names, passing_channels, norms)
# passing case
if np.all(passing_channels):
sys.exit(0)
# failing case
if plotError:
from errorPlotting import finalizePlotDirectory, plotOpenfastError
for channel in testInfo["attribute_names"]:
try:
plotOpenfastError(localOutFile, baselineOutFile, channel, rtol, atol)
except:
error = sys.exc_info()[1]
print("Error generating plots: {}".format(error))
finalizePlotDirectory(localOutFile, testInfo["attribute_names"], caseName)
sys.exit(1)