Skip to content

Commit

Permalink
Merge branch 'application2' of github.com:sean-engelstad/funtofem int…
Browse files Browse the repository at this point in the history
…o application2
  • Loading branch information
sean-engelstad committed Nov 1, 2023
2 parents 81ce392 + 243152e commit d93a0cb
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 21 deletions.
19 changes: 19 additions & 0 deletions funtofem/driver/funtofem_shape_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,12 @@ def solve_adjoint(self):
super(FuntofemShapeDriver, self).solve_adjoint()

if self.is_paired:
# write a functions file
if self.comm.rank == 0:
print(f"Writing funtofem.out file")
func_file = Remote.paths(self.comm, self.flow_dir).functions_file
self.model.write_functions_file(self.comm, func_file)

write_struct = True
write_aero = True
struct_sensfile = Remote.paths(
Expand Down Expand Up @@ -514,6 +520,19 @@ def _setup_grid_filepaths(self):
grid_filepaths.append(filepath)
# set the grid filepaths into the fun3d aim
self.flow_aim.grid_filepaths = grid_filepaths

# also setup the mapbc files
mapbc_filepaths = []
for scenario in self.model.scenarios:
filepath = os.path.join(
fun3d_dir,
scenario.name,
"Flow",
f"{scenario.fun3d_project_name}.mapbc",
)
mapbc_filepaths.append(filepath)
# set the mapbc filepaths into the fun3d aim
self.flow_aim.mapbc_filepaths = mapbc_filepaths
return

def _move_struct_mesh(self):
Expand Down
13 changes: 13 additions & 0 deletions funtofem/driver/oneway_aero_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,19 @@ def _setup_grid_filepaths(self):
grid_filepaths.append(filepath)
# set the grid filepaths into the fun3d aim
self.flow_aim.grid_filepaths = grid_filepaths

# also setup the mapbc files
mapbc_filepaths = []
for scenario in self.model.scenarios:
filepath = os.path.join(
fun3d_dir,
scenario.name,
"Flow",
f"{scenario.fun3d_project_name}.mapbc",
)
mapbc_filepaths.append(filepath)
# set the mapbc filepaths into the fun3d aim
self.flow_aim.mapbc_filepaths = mapbc_filepaths
return

@property
Expand Down
30 changes: 29 additions & 1 deletion funtofem/interface/caps2fun/fun3d_aim.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ def __init__(self, caps_problem, comm, mesh_morph=False, root=0):
self._aim = None
self._grid_file = None
self._grid_filepaths = []
self._mapbc_file = None
self._mapbc_filepaths = []

self._fun3d_dir = None

Expand Down Expand Up @@ -182,6 +184,16 @@ def grid_filepaths(self, new_filepaths):
self._grid_filepaths = new_filepaths
return

@property
def mapbc_filepaths(self):
return self._mapbc_filepaths

@mapbc_filepaths.setter
def mapbc_filepaths(self, new_filepaths):
"""set the grid filepaths from each fun3d scenario, from the fun3d interface"""
self._mapbc_filepaths = new_filepaths
return

def _move_grid_files(self):
"""
move each of the grid files in the preAnalysis after a new grid is
Expand All @@ -192,10 +204,18 @@ def _move_grid_files(self):
return
else:
self._first_grid_move = False
print(f"copying grid files = {self._first_grid_move}")
if self.comm.rank == 0:
print(f"copying grid files")
src = self.grid_file
for dest in self.grid_filepaths:
shutil.copy(src, dest)

# also move the mapbc files to each scenario from fun3d aim dir
if self.comm.rank == 0:
print(f"copying mapbc files")
src = self.mapbc_file
for dest in self.mapbc_filepaths:
shutil.copy(src, dest)
return

def _move_sens_files(self, src):
Expand Down Expand Up @@ -278,6 +298,14 @@ def grid_file(self):
def grid_file(self, new_grid_file):
self._grid_file = new_grid_file

@property
def mapbc_file(self):
return self._mapbc_file

@mapbc_file.setter
def mapbc_file(self, new_mapbc_file):
self._mapbc_file = new_mapbc_file

@property
def sens_file_path(self):
"""path to fun3d sens file"""
Expand Down
4 changes: 4 additions & 0 deletions funtofem/interface/caps2fun/fun3d_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ def _set_grid_filename(self):
self.fun3d_aim.grid_file = os.path.join(
self.aflr_aim.analysis_dir, "aflr3_0.lb8.ugrid"
)
# also set mapbc file
self.fun3d_aim.mapbc_file = os.path.join(
self.fun3d_aim.analysis_dir, "Flow", self.fun3d_aim.project_name + ".mapbc"
)
return

def _link_aims(self):
Expand Down
45 changes: 30 additions & 15 deletions funtofem/interface/fun3d_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -629,13 +629,17 @@ def post(self, scenario, bodies):
"""

# report warning if flow residual too large
resid = self.get_forward_residual(step=scenario.steps) # step=scenario.steps
resid = self.get_forward_residual(
step=scenario.steps, all=True
) # step=scenario.steps
if self.comm.rank == 0:
print(f"Forward residuals = {resid}")
self._forward_done = True
self._forward_resid = resid
if abs(resid.real) > 1.0e-10:
if abs(np.linalg.norm(resid).real) > self.forward_tolerance:
if self.comm.rank == 0:
print(
f"Warning: fun3d forward flow residual = {resid} > 1.0e-10, is rather large..."
f"\tWarning: fun3d forward flow residual = {resid} > {self.forward_tolerance:.2e}, is rather large..."
)

self.fun3d_flow.post()
Expand Down Expand Up @@ -964,21 +968,23 @@ def post_adjoint(self, scenario, bodies):
"""

# report warning if flow residual too large
resid = self.get_adjoint_residual(step=scenario.steps)
resid = self.get_adjoint_residual(step=scenario.steps, all=True)
if self.comm.rank == 0:
print(f"Adjoint residuals = {resid}")
self._adjoint_done = True
self._adjoint_resid = resid
if abs(resid.real) > 1.0e-10:
if abs(np.linalg.norm(resid).real) > self.adjoint_tolerance:
if self.comm.rank == 0:
print(
f"Warning fun3d adjoint residual = {resid} > 1.0e-10, is rather large..."
f"\tWarning fun3d adjoint residual = {resid} > {self.adjoint_tolerance:.2e}, is rather large..."
)

# solve the initial condition adjoint
self.fun3d_adjoint.post()
os.chdir(self.root_dir)
return

def get_forward_residual(self, step=0):
def get_forward_residual(self, step=0, all=False):
"""
Returns L2 norm of scalar residual norms for each flow state
L2norm([R1,...,R6])
Expand All @@ -987,31 +993,40 @@ def get_forward_residual(self, step=0):
----------
step: int
the time step number
all: bool
whether to return a list of all residuals or just a scalar
"""
if not self._forward_done:
residuals = self.fun3d_flow.get_flow_rms_residual(step)
if self.comm.rank == 0:
print(f"Forward residuals = {residuals}")
return np.linalg.norm(residuals)
else:
return self._forward_resid
residuals = self._forward_resid

if all:
return residuals
else:
return np.linalg.norm(residuals)

def get_adjoint_residual(self, step=0):
def get_adjoint_residual(self, step=0, all=False):
"""
Returns L2 norm of list of scalar adjoint residuals L2norm([R1,...,R6])
Parameters
----------
step: int
the time step number
all: bool
whether to return a list of all residuals or a scalar
"""
if not self._adjoint_done:
residuals = self.fun3d_adjoint.get_flow_rms_residual(step)
if self.comm.rank == 0:
print(f"Adjoint residuals = {residuals}")
return np.linalg.norm(residuals)
else:
return self._adjoint_resid
residuals = self._adjoint_resid

if all:
return residuals
else:
return np.linalg.norm(residuals)

def set_states(self, scenario, bodies, step):
"""
Expand Down
2 changes: 1 addition & 1 deletion funtofem/interface/utils/remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def __init__(
self.output_name = output_name
self.aero_name = aero_name
self.struct_name = struct_name
self._remote_dir = cls.remote_dir(comm, main_dir)
self._remote_dir = self.remote_dir(comm, main_dir)

@classmethod
def paths(cls, comm, main_dir, aero_name="fun3d", struct_name="tacs"):
Expand Down
11 changes: 7 additions & 4 deletions funtofem/model/funtofem_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -875,9 +875,10 @@ def write_functions_file(self, comm, filename, root=0):
This file contains the following information:
Number of functionals
Number of functionals, number of variables
Functional name, value
d(func_name)/d(var_name), value
Parameters
----------
Expand All @@ -889,9 +890,8 @@ def write_functions_file(self, comm, filename, root=0):
The rank of the processor that will write the file
"""

funcs = self.get_functions()
# also add composite functions at the end
funcs += self.composite_functions
funcs = self.get_functions(all=True)
variables = self.get_variables()

if comm.rank == root:
# Write out the number of functionals and number of design variables
Expand All @@ -904,6 +904,9 @@ def write_functions_file(self, comm, filename, root=0):
# Print the function value
data += "{}\n".format(func.value.real)

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

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

Expand Down

0 comments on commit d93a0cb

Please sign in to comment.