ADflow  v1.0
ADflow is a finite volume RANS solver tailored for gradient-based aerodynamic design optimization.
autoEditReverseFast.py
Go to the documentation of this file.
1 #! /usr/bin/env python
2 """
3 autoEdit - A Python tool to automatically edit a set of files
4  according to the specified user rules:
5 G. Kenway
6 """
7 
8 # Import modules
9 import os
10 import re
11 import sys
12 
13 # Specify file extension
14 EXT = "_fast_b.f90"
15 
16 DIR_ORI = sys.argv[1]
17 DIR_MOD = sys.argv[2]
18 
19 # Specify the list of LINE ID's to find, what to replace and with what
20 patt_modules = re.compile(r"(\s*use\s*\w*)(_b)\s*")
21 patt_module = re.compile(r"\s*module\s\w*")
22 patt_module_start = re.compile("(\s*module\s)(\w*)(_b)\s*")
23 patt_module_end = re.compile("(\s*end module\s)(\w*)(_b)\s*")
24 del_patterns = [
25  re.compile(r"(\s*call pushreal8)"),
26  re.compile(r"(\s*call popreal8)"),
27  re.compile(r"(\s*call pushinteger4)"),
28  re.compile(r"(\s*call popinteger4)"),
29 ]
30 patt_pushcontrol1b = re.compile(r"(\s*call pushcontrol1b\‍()(.*)\‍)")
31 patt_popcontrol1b = re.compile(r"(\s*call popcontrol1b\‍()(.*)\‍)")
32 patt_subroutine = re.compile(r"\s*subroutine\s\w*")
33 patt_subend = re.compile(r"\s*end\s*subroutine")
34 patt_comment = re.compile(r"\s*!.*")
35 patt_inttype = re.compile(r"\s*integer\*4\s\w*")
36 
37 print("Directory of input source files :", DIR_ORI)
38 print("Directory of output source files :", DIR_MOD)
39 
40 useful_modules = [
41  "bcpointers_fast_b",
42  "bcroutines_fast_b",
43  "flowutils_fast_b",
44  "fluxes_fast_b",
45  "initializeflow_fast_b",
46  "residuals_fast_b",
47  "sa_fast_b",
48  "solverutils_fast_b",
49  "surfaceintegrations_fast_b",
50  "turbbcroutines_fast_b",
51  "turbutils_fast_b",
52  "utils_fast_b",
53  "walldistance_fast_b",
54 ]
55 
56 FILE_IGNORE = [
57  "adjointExtra_fast_b.f90",
58  "BCData_fast_b.f90",
59  "oversetUtilities_fast_b.f90",
60  "zipperIntegrations_fast_b.f90",
61  "actuatorRegion_fast_b.f90",
62 ]
63 
64 for f in os.listdir(DIR_ORI):
65  if f not in FILE_IGNORE and f.endswith(EXT):
66  # open original file in read mode
67  file_object_ori = open(os.path.join(DIR_ORI, f), "r")
68  print("\nParsing input file", file_object_ori.name)
69 
70  # read to whole file to string and reposition the pointer
71  # at the first byte for future reading
72  file_object_ori.seek(0)
73 
74  # First we want to dertmine if it is a 'useful' module or a
75  # 'useless' module. A useful module is one that has
76  # subroutines in it.
77  isModule = False
78  hasSubroutine = False
79  for line in file_object_ori:
80  line = line.lower()
81  if patt_module.match(line):
82  isModule = True
83  if patt_subroutine.match(line):
84  hasSubroutine = True
85 
86  # If we have a module, close the input and cycle to next file.
87  if isModule and not hasSubroutine:
88  file_object_ori.close()
89  continue
90  elif isModule and hasSubroutine:
91  # We need to change the name of the module file:
92  f = f.replace("_b", "_b")
93 
94  # open modified file in write mode
95  file_object_mod = open(os.path.join(DIR_MOD, f), "w")
96 
97  # read the original file, line-by-line
98  addedModule = False
99 
100  # Go back to the beginning
101  file_object_ori.seek(0)
102  inSubroutine = False
103 
104  for line in file_object_ori:
105  # Just deal with lower case string
106  line = line.lower()
107 
108  # Replace _cb on calls
109  if "_cb" in line:
110  line = line.replace("_cb", "")
111 
112  # Replace _fast_b modules with normal -- except for the useful
113  # ones.
114  m = patt_modules.match(line)
115  if m:
116  found = False
117  for m in useful_modules:
118  if m in line:
119  found = True
120  if found:
121  line = line.replace("_b", "_b", 1)
122  else:
123  line = line.replace("_fast_b", "")
124 
125  # Push control 1b's
126  m = patt_pushcontrol1b.match(line)
127  if m:
128  num = m.group(2)
129  line = "myIntPtr = myIntPtr + 1\n myIntStack(myIntPtr) = %s\n" % num
130 
131  # Pop control 1b's
132  m = patt_popcontrol1b.match(line)
133  if m:
134  num = m.group(2)
135  line = "%s = myIntStack(myIntPtr)\n myIntPtr = myIntPtr - 1\n" % num
136 
137  # Tapenade is using nonstandard type declaration incompatible with f2008
138  # Remove for now and depend on compiler kind default, which should be in
139  # almost all cases 4-bytes
140  m = patt_inttype.match(line)
141  if m:
142  line = line.replace("integer*4", "integer")
143 
144  # # See if we need to modify the line
145  # m = patt_module_start.match(line)
146  # if m:
147  # line = "module %s_fast_b\n" % m.group(2)
148 
149  # m = patt_module_end.match(line)
150  # if m:
151  # line = "end module %s_fast_b\n" % m.group(2)
152 
153  # Delete patterns
154  if not f.lower() == "bcroutines_b.f90":
155  for p in del_patterns:
156  if p.match(line):
157  line = ""
158 
159  # Tapenade misses one function in inviscidupwindflux_fast_b and we need to add it manually
160  if patt_subroutine.match(line) and "inviscidupwindflux_fast_b" in line:
161  inSubroutine = True
162 
163  # If within the subroutine we just search for a very specific string append
164  if inSubroutine and "use flowutils_fast_b, only : etot" in line:
165  line = line.strip("\n") + ", etot_fast_b\n"
166 
167  if patt_subend.match(line):
168  inSubroutine = False
169 
170  # write the modified line to new file
171  file_object_mod.write(line)
172 
173  # close the files
174  file_object_ori.close()
175  file_object_mod.close()
176 
177  # success message
178  print(" Modified file saved", file_object_mod.name)