Skip to content

Commit 7a683f1

Browse files
committed
small update
1 parent 0050ca3 commit 7a683f1

File tree

2 files changed

+326
-31
lines changed

2 files changed

+326
-31
lines changed

design/Inc_Turbulent_Bend_Wallfunctions/optimization.py

Lines changed: 109 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,104 @@
1-
# FADO script: Shape Optimization with Species Variance OF
1+
# FADO script: Shape Optimization with pressure drop minimization
22

33
from FADO import *
4+
from timeit import default_timer as timer
45
import glob
56
import time
67
import os
7-
8+
import subprocess
89
# get the path to su2 executable
910
su2_run= os.environ["SU2_RUN"] + "/"
1011
print("SU2 executable obtained from ", su2_run)
1112

12-
# Define a few often used variables
13+
# Some settings that depend on the case
14+
15+
# nr of cores for mpi
16+
ncores="8"
17+
1318
configMaster="sudo.cfg"
1419
meshName="sudo_coarse_FFD.su2"
1520
# inlet BC file
1621
inletName="inlet.dat"
1722
restartAdjName="solution_adj_dp.csv"
1823

24+
configCopy = "config.cfg"
25+
# first, copy sudo.cfg to a copy config.cfg that is allowed to be altered.
26+
copy_command = ['cp', configMaster, configCopy]
27+
subprocess.run(copy_command)
28+
1929
# Design variables ----------------------------------------------------- #
2030

2131
# important, this has to match the nr of variables
2232
# 6 x 6 x 6 = 216
23-
# x,y = 432
2433
# x,y,z = 648
25-
#minus the 6x6=36 nodes of the symmetry plane
26-
nDV = 648-36-36
27-
# nr of cores for mpi
28-
ncores="8"
34+
NDIM = 3
35+
DX = 6
36+
nDV = DX * DX * DX * NDIM
2937

3038
# define the objective
3139
objective = 'Surface_Pressure_Drop'
3240

33-
#########################################################################################################
34-
ffd = InputVariable(0.0,PreStringHandler("DV_VALUE="),nDV)
41+
# start the time!
42+
start = timer()
3543

3644
#
3745
# Note that the last two numbers are the bounds, reduce if you want to limit the maximum deformation
3846
#########################################################################################################
3947
ffd = InputVariable(np.zeros((nDV,)),ArrayLabelReplacer("__FFD_PTS__"), 0, np.ones(nDV), -0.10,0.10)
4048
#########################################################################################################
4149

42-
# Parameters ----------------------------------------------------------- #
4350

44-
# The master config `configMaster.cfg` serves as an SU2 adjoint regression test.
45-
# For a correct gradient validation we need to exchange some options
51+
# ##### create string for DV_KIND ##### #
52+
s = "FFD_CONTROL_POINT"
53+
ffd_string = s
54+
for i in range((DX**NDIM)*NDIM - 1):
55+
ffd_string = ffd_string + ", " + s
56+
57+
58+
# ##### create string for DV_PARAM ##### #
59+
60+
dv_param_string=""
61+
for idim in range(NDIM):
62+
xdim = ydim = zdim = "0.0"
63+
if (idim==0): xdim="1.0"
64+
elif (idim==1): ydim="1.0"
65+
elif (idim==2): zdim="1.0"
66+
for k in range(DX):
67+
for j in range(DX):
68+
for i in range(DX):
69+
s = "( BOX, " + str(i) + ", " + str(j) + ", " + str(k) + ", " + xdim + ", " + ydim + ", " + zdim + " );"
70+
dv_param_string += s
71+
72+
# remove last semicolon
73+
dv_param_string = dv_param_string[:-1]
74+
75+
76+
# do not move FFD box nodes in vertical direction (bottom face with j=0 only )
77+
# we remove 6*6=36 d.o.f.
78+
nDV = nDV - 2*DX*DX
79+
ffd_string.replace(s+", ","",2*DX*DX)
80+
81+
82+
# for bottom plane (j=0 and j=1) remove the entries that have (0.0,1.0,0.0) d.o.f.
83+
jlist = [0,1]
84+
dof = "0.0, 1.0, 0.0"
85+
86+
for j in jlist:
87+
for k in range(DX):
88+
for i in range(DX):
89+
remove_dof = "( BOX, " + str(i) + ", " + str(j) + ", " + str(k) + ", " + dof + " )"
90+
print("removing ", remove_dof)
91+
dv_param_string = dv_param_string.replace(remove_dof+";", "", 1)
92+
# in case the plane is at the end, the string does not have a semicolon
93+
dv_param_string = dv_param_string.replace(remove_dof, "", 1)
94+
95+
96+
replace_dv_kind = Parameter([ffd_string], LabelReplacer("__FFD_CTRL_PTS__"))
97+
replace_dv_param =Parameter([dv_param_string], LabelReplacer("__FFD_PARAM__"))
98+
99+
ffd = InputVariable(np.zeros((nDV,)),ArrayLabelReplacer("__FFD_PTS__"), 0, np.ones(nDV), -0.10,0.10)
100+
101+
# Parameters ----------------------------------------------------------- #
46102

47103
# switch from direct to adjoint mode and adapt settings.
48104
enable_direct = Parameter([""], LabelReplacer("%__DIRECT__"))
@@ -55,58 +111,76 @@
55111
if objective == 'Uniformity':
56112
print("1. set parameter for Uniformity")
57113
enable_obj = Parameter(["SURFACE_UNIFORMITY"], LabelReplacer("__OBJ_FUNC__"))
114+
objstring="uniformity"
58115

59116
elif objective == 'Surface_Pressure_Drop':
60117
print("1. set parameter for Surface_Pressure_Drop")
61118
enable_obj = Parameter(["SURFACE_PRESSURE_DROP"], LabelReplacer("__OBJ_FUNC__"))
119+
objstring = "dp"
62120

63121
else:
64122
raise Exception("no valid objective found.")
65123

124+
125+
66126
print(" ")
67127
print("Running validation for", objective)
68128

129+
# after the first iteration, we switch from restart=no to restart=yes, then update original cfg file
130+
restart_yes="sed -i 's/RESTART_SOL= NO/RESTART_SOL= YES/' config.cfg && cp " + configCopy + " ../../"
69131

70132
# Evaluations ---------------------------------------------------------- #
71133

72-
def_command = "mpirun -n " + ncores + " " + su2_run + "SU2_DEF " + configMaster
73-
cfd_command = "mpirun -n " + ncores + " " + su2_run + "SU2_CFD " + configMaster + "; pwd; cp restart.csv ../../restart.csv"
74-
cfd_ad_command = "mpirun -n " + ncores + " " + su2_run + "SU2_CFD_AD " + configMaster
75-
dot_ad_command = "mpirun -n " + ncores + " " + su2_run + "SU2_DOT_AD " + configMaster
134+
def_command = "mpirun -n " + ncores + " " + su2_run + "SU2_DEF " + configCopy
135+
cfd_command = "mpirun -n " + ncores + " " + su2_run + "SU2_CFD " + configCopy
136+
cfd_ad_command = "mpirun -n " + ncores + " " + su2_run + "SU2_CFD_AD " + configCopy
137+
cfd_command = "mpirun -n " + ncores + " " + su2_run + "SU2_CFD " + configCopy + " && cp restart.csv ../../solution.csv"
138+
cfd_ad_command = "mpirun -n " + ncores + " " + su2_run + "SU2_CFD_AD " + configCopy + " && cp restart_adj_" + objstring + ".csv ../../solution_adj_"+objstring+".csv"
139+
dot_ad_command = "mpirun -n " + ncores + " " + su2_run + "SU2_DOT_AD " + configCopy
140+
141+
# global iteration
142+
global_iter = 0
143+
76144

77145
max_tries = 1
78146

79-
# mesh deformation
147+
# mesh deformation, running in subdirectory DEFORM
80148
deform = ExternalRun("DEFORM",def_command,True) # True means sym links are used for addData
81149
deform.setMaxTries(max_tries)
82-
deform.addConfig(configMaster)
150+
deform.addConfig(configCopy)
83151
deform.addData(meshName)
84152
deform.addData(inletName)
85153
deform.addExpected("mesh_out.su2")
154+
deform.addParameter(replace_dv_kind)
155+
deform.addParameter(replace_dv_param)
86156
deform.addParameter(enable_def)
87157
deform.addParameter(enable_obj)
88158

89-
# direct run
159+
# direct run, running in subdirectory DIRECT
90160
direct = ExternalRun("DIRECT",cfd_command,True)
91161
direct.setMaxTries(max_tries)
92-
direct.addConfig(configMaster)
162+
direct.addConfig(configCopy)
93163
direct.addData("DEFORM/mesh_out.su2",destination=meshName)
94164
direct.addData(inletName)
95165
direct.addData("solution.csv")
96166
direct.addExpected("restart.csv")
167+
direct.addParameter(replace_dv_kind)
168+
direct.addParameter(replace_dv_param)
97169
direct.addParameter(enable_direct)
98170
direct.addParameter(enable_not_def)
99171
direct.addParameter(enable_obj)
100172

101-
# adjoint run
173+
# adjoint run, running in subdorectory ADJOINT
102174
adjoint = ExternalRun("ADJOINT",cfd_ad_command,True)
103175
adjoint.setMaxTries(max_tries)
104-
adjoint.addConfig(configMaster)
176+
adjoint.addConfig(configCopy)
105177
adjoint.addData("DEFORM/mesh_out.su2", destination=meshName)
106178
adjoint.addData(inletName)
107179
adjoint.addData(restartAdjName)
108180
# add primal solution file
109181
adjoint.addData("DIRECT/restart.csv", destination="solution.csv")
182+
adjoint.addParameter(replace_dv_kind)
183+
adjoint.addParameter(replace_dv_param)
110184

111185
if objective == 'Uniformity':
112186
print("2. set adjoint for Uniformity")
@@ -123,12 +197,14 @@
123197
adjoint.addParameter(enable_not_def)
124198
adjoint.addParameter(enable_obj)
125199

126-
# gradient projection
200+
# gradient projection, running in subdirectory DOT
127201
dot = ExternalRun("DOT",dot_ad_command,True)
128202
dot.setMaxTries(max_tries)
129-
dot.addConfig(configMaster)
203+
dot.addConfig(configCopy)
130204
dot.addData("DEFORM/mesh_out.su2", destination=meshName)
131205
dot.addData(inletName)
206+
dot.addParameter(replace_dv_kind)
207+
dot.addParameter(replace_dv_param)
132208
print("Objective = ",objective)
133209

134210
if objective == 'Uniformity':
@@ -147,9 +223,8 @@
147223
dot.addParameter(enable_obj) # necessary for correct file extension
148224

149225
# update restart file
150-
#update_restart = ExternalRun(".",update_restart_command,False) # True means sym links are used for addData
151-
152-
226+
update_restart = ExternalRun("UPDATE_RESTART",restart_yes,False) # True means sym links are used for addData
227+
update_restart.addData(configCopy)
153228

154229
# Functions ------------------------------------------------------------ #
155230
#
@@ -168,6 +243,7 @@
168243
func_surfdp.addValueEvalStep(deform)
169244
func_surfdp.addValueEvalStep(direct)
170245
func_surfdp.addGradientEvalStep(adjoint)
246+
func_surfdp.addGradientEvalStep(update_restart)
171247
func_surfdp.addGradientEvalStep(dot)
172248
func_surfdp.setDefaultValue(0.0)
173249

@@ -205,7 +281,7 @@
205281
# SOFT = if func eval fails, just the default val will be taken
206282
driver.setFailureMode("SOFT")
207283

208-
# file containing the objective values per design iteration
284+
# Define the filename containing the objective values per design iteration
209285
his = open("optim.csv","w",1)
210286
driver.setHistorian(his)
211287

@@ -217,9 +293,9 @@
217293
x = driver.getInitial()
218294

219295
# disp:True prints convergence messages
220-
# maxiter: int limits the optimization to maxiter number of iterations
296+
# maxiter: number of (true) design iterations that will be run
221297
# ftol: precision tolerance goal for the value of f in the stopping criterion
222-
options = {'disp': True, 'ftol': 1e-10, 'maxiter': 10}
298+
options = {'disp': True, 'ftol': 1e-10, 'maxiter': 5}
223299

224300
# Use Sequential Least Squares Programming SLSQP
225301
optimum = scipy.optimize.minimize(driver.fun, x, method="SLSQP", jac=driver.grad,\
@@ -230,3 +306,5 @@
230306

231307
print(" +--- Finished")
232308

309+
end = timer()
310+
print("total time: ",end-start," seconds, ",(end-start)/60.0," minutes.")

0 commit comments

Comments
 (0)