Skip to content

Commit

Permalink
send aerodynamic derivatives through functions_file and remote
Browse files Browse the repository at this point in the history
  • Loading branch information
sean-engelstad committed Nov 1, 2023
1 parent 87109d4 commit 2ddb615
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 23 deletions.
14 changes: 13 additions & 1 deletion funtofem/driver/funtofem_shape_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,12 @@ def solve_adjoint(self):
# call funtofem adjoint analysis for non-remote driver
super(FuntofemShapeDriver, self).solve_adjoint()

# write analysis functions file in analysis or system call
if self.is_paired:
self.model.write_functions_file(
self.comm, Remote.paths(self.comm, self.flow_dir).functions_file
)

if self.is_paired:
write_struct = True
write_aero = True
Expand Down Expand Up @@ -503,6 +509,10 @@ def solve_adjoint(self):
for scenario in self.model.scenarios:
self._get_aero_shape_derivatives(scenario)

# get any remaining aero, struct derivatives from the funtofem.out file (only for analysis functions)
if self.is_remote and self.is_paired:
self.model.read_functions_file(self.comm, self.remote.functions_file)

# evaluate the composite functions
self.model.evaluate_composite_functions(compute_grad=True)

Expand Down Expand Up @@ -665,7 +675,9 @@ def _get_aero_shape_derivatives(self, scenario):
var_name = (
var.name if var.analysis_type == "shape" else var.full_name
)
if var.analysis_type in ["shape", "aerodynamic"]:
# get aerodynamic derivatives from the funtofem.out files instead of Fun3dAim since
# it is kind of buggy to create Aerodynamic Analysis DVs currently
if var.analysis_type in ["shape"]: # ["shape", "aerodynamic"]
derivative = direct_flow_aim.dynout[func.full_name].deriv(
var_name
)
Expand Down
5 changes: 2 additions & 3 deletions funtofem/driver/oneway_struct_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def __init__(
location of fun3d directory, used in an analysis file for FuntofemShapeDriver
external_shape: bool
whether the tacs aim shape analysis is performed outside the class
init_aero_load_transfer:
init_aero_load_transfer:
"""
self.solvers = solvers
self.comm = solvers.comm
Expand Down Expand Up @@ -222,7 +222,7 @@ def prime_loads_from_file(
nprocs,
transfer_settings,
external_shape=False,
init_transfer=False
init_transfer=False,
):
"""
Used to prime aero loads for optimization over tacs analysis with shape change and tacs aim
Expand Down Expand Up @@ -282,7 +282,6 @@ def prime_loads_from_file(
if init_transfer:
tacs_driver._transfer_fixed_aero_loads()
return tacs_driver


@property
def manager(self, hot_start: bool = False):
Expand Down
48 changes: 29 additions & 19 deletions funtofem/model/funtofem_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,9 @@ def _send_flow_variables(self, base):
# not in Fun3dAim for now...

# add aerodynamic variable names to varnames
for var in aero_variables:
if var.active:
active_aero_vars.append(var)
# for var in aero_variables:
# if var.active:
# active_aero_vars.append(var)

# input the design parameters into the Fun3dModel and Fun3dAim
self.flow.set_variables(active_shape_vars, active_aero_vars)
Expand Down Expand Up @@ -823,7 +823,7 @@ def write_design_variables_file(self, comm, filename, root=0):

return

def read_functions_file(self, comm, filename, root=0):
def read_functions_file(self, comm, filename, root=0, **kwargs):
"""
Read the functions variables file funtofem.out
Expand All @@ -843,6 +843,7 @@ def read_functions_file(self, comm, filename, root=0):
"""

functions_dict = None
gradients_dict = None
if comm.rank == root: # read the file in on the root processor
functions_dict = {}

Expand All @@ -852,24 +853,37 @@ def read_functions_file(self, comm, filename, root=0):

for line in lines:
chunks = line.split(" ")
if len(chunks) == 2:
func_name = chunks[0]
func_value = chunks[1]
if len(chunks) == 3: # func values
func_name = chunks[1]
func_value = chunks[2].strip()

# only real numbers are read in from the file
functions_dict[func_name] = float(func_value)
gradients_dict[func_name] = {}
if len(chunks) == 2: # derivative
var_name = chunks[0].strip()
derivative = chunks[1].strip()

# only real numbers are read in from the file
gradients_dict[func_name][var_name] = float(derivative)

# broadcast the dictionary to the root processor
functions_dict = comm.bcast(functions_dict, root=root)
gradients_dict = comm.bcast(gradients_dict, root=root)

# update the variable values on each processor
for func in self.get_functions():
if func.name in functions_dict:
func.value = functions_dict[func.name]
# only updates the analysis functions
for func in self.get_functions(kwargs):
if func.full_name in functions_dict:
func.value = functions_dict[func.full_name]
for var in self.get_variables():
c_gradients = gradients_dict[func.full_name]
if var.full_name in c_gradients:
func.derivatives[var] = c_gradients[var.full_name]

return

def write_functions_file(self, comm, filename, root=0):
def write_functions_file(self, comm, filename, root=0, **kwargs):
"""
Write the functions file funtofem.out
Expand All @@ -890,7 +904,7 @@ def write_functions_file(self, comm, filename, root=0):
The rank of the processor that will write the file
"""

funcs = self.get_functions(optim=True)
funcs = self.get_functions(kwargs)
variables = self.get_variables()

if comm.rank == root:
Expand All @@ -899,15 +913,11 @@ def write_functions_file(self, comm, filename, root=0):

for n, func in enumerate(funcs):
# Print the function name
data += "{}\n".format(func.full_name)

# Print the function value
data += "{}\n".format(
func.value.real if func.value is not None else None
)
func_value = func.value.real if func.value is not None else None
data += f"func {func.full_name} = {func_value:.5e}\n"

for var in variables:
data += f"\td{func.full_name}/d{var.full_name} = {func.derivatives[var]}\n"
data += f"\t{var.full_name} = {func.derivatives[var]}\n"

with open(filename, "w") as fp:
fp.write(data)
Expand Down

0 comments on commit 2ddb615

Please sign in to comment.