Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add print summary for oneway aero driver, fix grid naming in FUN3D model (relevant to shape change) #354

Draft
wants to merge 14 commits into
base: master
Choose a base branch
from
37 changes: 23 additions & 14 deletions funtofem/driver/_funtofem_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@ def solve_adjoint(self):
if scenario.steady:
fail = self._solve_steady_adjoint(scenario)
if fail != 0:
print(
f"Fail flag detected after _solve_steady_adjoint!", flush=True
)
return fail
else:
fail = self._solve_unsteady_adjoint(scenario)
Expand Down Expand Up @@ -369,23 +372,29 @@ def _solve_steady_adjoint(self, scenario):
def _solve_unsteady_adjoint(self, scenario):
return 1

def print_summary(self, print_model=False, print_comm=False):
def print_summary(self, comm=None, print_model=False, print_comm=False):
"""
Print out a summary of the FUNtoFEM driver for inspection.
"""

print("==========================================================")
print("|| FUNtoFEM Driver Summary ||")
print("==========================================================")
print(self)

self._print_transfer(print_comm=print_comm)

if print_model:
print(
"\nPrinting abbreviated model summary. For details print model summary directly."
)
self.model.print_summary(print_level=-1, ignore_rigid=True)
print_here = True
if comm is not None:
comm.Barrier()
if comm.rank != 0:
print_here = False

if print_here:
print("==========================================================")
print("|| FUNtoFEM Driver Summary ||")
print("==========================================================")
print(self)

self._print_transfer(print_comm=print_comm)

if print_model:
print(
"\nPrinting abbreviated model summary. For details print model summary directly."
)
self.model.print_summary(print_level=-1, ignore_rigid=True)

return

Expand Down
37 changes: 30 additions & 7 deletions funtofem/driver/funtofem_shape_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ def aero_morph(
struct_nprocs=48,
forward_flow_post_analysis=False,
reload_funtofem_states=False,
struct_callback=None,
tacs_inertial=False,
):
"""
Build a FuntofemShapeDriver object with FUN3D mesh morphing or with no fun3dAIM
Expand All @@ -85,6 +87,8 @@ def aero_morph(
struct_nprocs=struct_nprocs,
forward_flow_post_analysis=forward_flow_post_analysis,
reload_funtofem_states=reload_funtofem_states,
struct_callback=struct_callback,
tacs_inertial=tacs_inertial,
)

@classmethod
Expand Down Expand Up @@ -154,6 +158,8 @@ def __init__(
struct_nprocs=48,
forward_flow_post_analysis=False,
reload_funtofem_states=False,
struct_callback=None,
tacs_inertial=False,
):
"""
The FUNtoFEM driver for the Nonlinear Block Gauss-Seidel
Expand Down Expand Up @@ -197,6 +203,9 @@ def __init__(
]
self.forward_flow_post_analysis = forward_flow_post_analysis

self.struct_callback = struct_callback
self.tacs_inertial = tacs_inertial

# make sure the solver interfaces are TACS and FUN3D
if not (self.change_shape) and self.is_remote:
raise AssertionError(
Expand Down Expand Up @@ -501,13 +510,27 @@ def solve_forward(self):
# to system call FUN3D, please don't put shape variables in the analysis file
# make the new tacs interface of the structural geometry
if self.uses_tacs:
self.solvers.structural = TacsInterface.create_from_bdf(
model=self.model,
comm=self.comm,
nprocs=self.struct_nprocs,
bdf_file=self.struct_aim.root_dat_file,
output_dir=self.struct_aim.root_analysis_dir,
)
if self.tacs_inertial:
self.solvers.structural = (
TacsSteadyInterface.create_from_bdf_inertial(
model=self.model,
comm=self.comm,
nprocs=self.struct_nprocs,
bdf_file=self.struct_aim.root_dat_file,
prefix=self.struct_aim.root_analysis_dir,
callback=self.struct_callback,
panel_length_dv_index=0,
panel_width_dv_index=5,
)
)
else:
self.solvers.structural = TacsInterface.create_from_bdf(
model=self.model,
comm=self.comm,
nprocs=self.struct_nprocs,
bdf_file=self.struct_aim.root_dat_file,
output_dir=self.struct_aim.root_analysis_dir,
)

# update the structural part of transfer scheme due to remeshing
self._update_struct_transfer()
Expand Down
84 changes: 81 additions & 3 deletions funtofem/driver/oneway_aero_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,9 @@ def solve_forward(self):
sens_file_src = None
if self.uses_fun3d and self.is_paired:
sens_file_src = self.remote.aero_sens_file
print(f"Remote aero sens file src: {sens_file_src}", flush=True)

# run the tacs aim postAnalysis to compute the chain rule product
# run the flow aim postAnalysis to compute the chain rule product
self.flow_aim.post_analysis(sens_file_src)

# get the analysis function values
Expand Down Expand Up @@ -495,9 +496,13 @@ def _solve_steady_adjoint(self, scenario, bodies):
# initialize, run, and do post adjoint
self.solvers.flow.initialize_adjoint(scenario, bodies)
# one extra call to match step 0 call (see fully coupled driver)
for step in range(1, steps + 2):
for step in range(1, steps + 1):
self.solvers.flow.iterate_adjoint(scenario, bodies, step=step)
self._extract_coordinate_derivatives(scenario, bodies, step=0)

# get the current step to extract derivatives
istep = scenario.adjoint_steps * scenario.adjoint_coupling_frequency

self._extract_coordinate_derivatives(scenario, bodies, step=steps)
self.solvers.flow.post_adjoint(scenario, bodies, coupled_residuals=False)

# call get function gradients to store the gradients w.r.t. aero DVs from FUN3D
Expand Down Expand Up @@ -636,6 +641,79 @@ def _get_shape_derivatives(self, scenario):

return

def print_summary(self, print_model=False, print_comm=False):
"""
Print out a summary of the FUNtoFEM driver for inspection.
"""

print("\n\n==========================================================")
print("|| FUNtoFEM Driver Summary ||")
print("==========================================================")
print(self)

self._print_shape_change()
self._print_transfer(print_comm=print_comm)

if print_model:
print(
"\nPrinting abbreviated model summary. For details print model summary directly."
)
self.model.print_summary(print_level=-1, ignore_rigid=True)

return

def _print_transfer(self, print_comm=False):
print("\n---------------------")
print("| Transfer Settings |")
print("---------------------")

print(f" Elastic scheme: {self.transfer_settings.elastic_scheme}")
print(f" No. points: {self.transfer_settings.npts}")
print(f" Beta: {self.transfer_settings.beta}")
print(f" Thermal scheme: {self.transfer_settings.thermal_scheme}")
print(f" No. points: {self.transfer_settings.thermal_npts}")
print(f" Beta: {self.transfer_settings.thermal_beta}\n")

if print_comm:
print(self.comm_manager)

return

def _print_shape_change(self):
_num_shape_vars = len(self.shape_variables)
print("\n--------------------")
print("| Shape Change |")
print("--------------------")

print(f" No. shape variables: {_num_shape_vars}")
print(f" Aerodynamic shape change: {self.aero_shape}")
print(f" Structural shape change: {self.struct_shape}")

print(f" Meshing:", end=" ")
if self.is_paired:
# Remeshing
print(f" RE-MESH")
if self.change_shape:
print(f" Remote is meshing.")
else:
print(f" Analysis script is meshing.")
else:
# Morphing
print(f" MORPH")

return

def __str__(self):
line1 = f"Driver (<Type>): {self.__class__.__qualname__}"
line2 = f" Using remote: {self.is_remote}"
line3 = f" Flow solver type: {self._flow_solver_type}"
line4 = f" Structural solver type: {self._struct_solver_type}"
line5 = f" No. structural procs: {self.struct_nprocs}"

output = (line1, line2, line3, line4, line5)

return "\n".join(output)

# @classmethod
# def prime_disps(cls, funtofem_driver):
# """
Expand Down
15 changes: 15 additions & 0 deletions funtofem/interface/caps2fun/fun3d_aim.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ def _move_grid_files(self, include_mapbc=False):
def _move_sens_files(self, src):
"""move sens files from the fun3d_dir to the fun3d AIM workdir"""
dest = self.sens_file_path
print(f"Destination: {dest}", flush=True)
if self.root_proc:
shutil.copy(src, dest)
return
Expand Down Expand Up @@ -299,6 +300,7 @@ def pre_analysis(self):
def post_analysis(self, sens_file_src=None):
if self.root_proc:
# move sens files if need be from fun3d dir to fun3d workdir
print(f"Attempting to move sens file.", flush=True)
if sens_file_src is not None:
self._move_sens_files(src=sens_file_src)
self.aim.postAnalysis()
Expand Down Expand Up @@ -345,3 +347,16 @@ def _make_hc_surface_file(self):
@property
def is_handcrafted(self) -> bool:
return self.handcrafted_mesh_morph is not None

def print_summary(self):
if self.root_proc:
print("==========================================================")
print("|| FUN3D AIM Summary ||")
print("==========================================================")

self._print_file_locs(self)

return

def _print_file_locs(self):
return
2 changes: 1 addition & 1 deletion funtofem/interface/caps2fun/fun3d_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def setup(self):

def _set_grid_filename(self):
if isinstance(self.mesh_aim.volume_aim, Aflr3Aim):
filename = "aflr3_0.lb8.ugrid"
filename = self.project_name + ".lb8.ugrid"
elif isinstance(self.mesh_aim.volume_aim, PointwiseAIM):
filename = "caps.GeomTomesh.lb8.ugrid"

Expand Down
Loading
Loading