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

Update SSW branch #275

Merged
merged 4 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,10 @@ jobs:
cd $F2F_DIR;
mkdir extern
cd $F2F_DIR/extern/
wget https://acdl.mit.edu/ESP/PreBuilts/ESP123-linux-x86_64.tgz
tar -xvf ESP123-linux-x86_64.tgz
export ESP_ROOT=${F2F_DIR}/extern/ESP123/EngSketchPad
export CASROOT=${F2F_DIR}/extern/ESP123/OpenCASCADE-7.7.0
wget https://acdl.mit.edu/ESP/PreBuilts/ESP124-linux-x86_64.tgz
tar -xvf ESP124-linux-x86_64.tgz
export ESP_ROOT=${F2F_DIR}/extern/ESP124/EngSketchPad
export CASROOT=${F2F_DIR}/extern/ESP124/OpenCASCADE-7.7.0
export CASARCH=
export PATH=$PATH:$CASROOT/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CASROOT/lib
Expand All @@ -125,7 +125,7 @@ jobs:
source $ESP_ROOT/../ESPenv.sh
cd ./src/CAPS/aim
make
cd $F2F_DIR/extern/ESP123/
cd $F2F_DIR/extern/ESP124/
# remove all ESP/CAPS unit test files with recursive delete
find . -name "test*" -type f -delete
cd $F2F_DIR
Expand All @@ -136,7 +136,7 @@ jobs:
echo "Running Tests";
echo "=============================================================";
if [[ ${{ matrix.NAME }} == 'Real' ]]; then
source ${F2F_DIR}/extern/ESP123/ESPenv.sh
source ${F2F_DIR}/extern/ESP124/ESPenv.sh
fi
testflo ${GITHUB_WORKSPACE}/tests/unit_tests/;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ def get_function_gradients(self, scenario, bodies, offset):
if vartype == "aerodynamic":
for i, var in enumerate(scenario.variables[vartype]):
if var.active and "force" in var.name:
scenario.derivatives[vartype][offset + func][
i
] = -np.sum(self.fixed_step_psi_A)
scenario.derivatives[vartype][offset + func][i] = (
-np.sum(self.fixed_step_psi_A)
)

return 0
Original file line number Diff line number Diff line change
Expand Up @@ -533,26 +533,28 @@ def get_function_gradients(self, scenario, bodies, offset):
for i, var in enumerate(scenario.variables[vartype]):
if var.name == "alpha0" and var.active:
if self.comm.rank == 0:
scenario.derivatives[vartype][offset + ifunc][
i
] = self.dfdx[1]

scenario.derivatives[vartype][offset + ifunc][
i
] = self.comm.bcast(
scenario.derivatives[vartype][offset + ifunc][i], root=0
scenario.derivatives[vartype][offset + ifunc][i] = (
self.dfdx[1]
)

scenario.derivatives[vartype][offset + ifunc][i] = (
self.comm.bcast(
scenario.derivatives[vartype][offset + ifunc][i],
root=0,
)
)

if var.name == "struct_dt" and var.active:
if self.comm.rank == 0:
scenario.derivatives[vartype][offset + ifunc][
i
] = self.dfdx[0]

scenario.derivatives[vartype][offset + ifunc][
i
] = self.comm.bcast(
scenario.derivatives[vartype][offset + ifunc][i], root=0
scenario.derivatives[vartype][offset + ifunc][i] = (
self.dfdx[0]
)

scenario.derivatives[vartype][offset + ifunc][i] = (
self.comm.bcast(
scenario.derivatives[vartype][offset + ifunc][i],
root=0,
)
)

def eval_func(self, x, name="dt"):
Expand Down
53 changes: 52 additions & 1 deletion funtofem/driver/_funtofem_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import numpy as np
from mpi4py import MPI
from funtofem import TransferScheme
from .transfer_settings import TransferSettings

try:
from .hermes_transfer import HermesTransfer
Expand Down Expand Up @@ -68,6 +69,10 @@ def __init__(
comm_manager = solvers.comm_manager
self.comm_manager = comm_manager

if transfer_settings is None:
transfer_settings = TransferSettings()
self.transfer_settings = transfer_settings

# communicator
self.comm = comm_manager.master_comm
self.aero_comm = comm_manager.aero_comm
Expand Down Expand Up @@ -113,7 +118,7 @@ def __init__(
self.struct_root,
self.aero_comm,
self.aero_root,
transfer_settings=transfer_settings,
transfer_settings=self.transfer_settings,
)

# Initialize the shape parameterization
Expand Down Expand Up @@ -327,3 +332,49 @@ def _solve_steady_adjoint(self, scenario):

def _solve_unsteady_adjoint(self, scenario):
return 1

def print_summary(self, 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)

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 __str__(self):
line1 = f"Driver (<Type>): {self.__class__.__qualname__}"
line2 = f" Model: {self.model.name}"
line3 = f" Number of scenarios: {len(self.model.scenarios)}"

output = (line1, line2, line3)

return "\n".join(output)
85 changes: 70 additions & 15 deletions funtofem/driver/funtofem_shape_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ def __init__(
solvers, comm_manager, transfer_settings, model
)

self.transfer_settings = transfer_settings
self.remote = remote
self.is_paired = is_paired
self.struct_nprocs = struct_nprocs
Expand Down Expand Up @@ -364,16 +363,16 @@ def solve_forward(self):
root=0,
)

if not (self.is_remote) and self.change_shape:
# case where analysis script does the meshing and the remote does not.
# need to read new shape variable values before doing the meshing
self.model.read_design_variables_file(
self.comm,
filename=Remote.paths(self.comm, self.flow_dir).design_file,
root=0,
)

if not (self.is_remote) and self.is_paired:
if self.change_shape:
# case where analysis script does the meshing and the remote does not.
# need to read new shape variable values before doing the meshing
self.model.read_design_variables_file(
self.comm,
filename=Remote.paths(self.comm, self.flow_dir).design_file,
root=0,
)

# remove the _functions_file so remote will fail
if self.comm.rank == 0:
analysis_functions_file = Remote.paths(
Expand Down Expand Up @@ -709,11 +708,11 @@ def solve_adjoint(self):
# not sure if this barrier is necessary here but just in case
self.comm.Barrier()

if not self.is_remote:
# delete struct interface to free up memory in shape change
# self.solvers.structural._deallocate()
del self.solvers.structural
self.comm.Barrier()
# if not self.is_remote:
# # delete struct interface to free up memory in shape change
# # self.solvers.structural._deallocate()
# del self.solvers.structural
# self.comm.Barrier()

self.comm.Barrier()
start_time = time.time()
Expand Down Expand Up @@ -1067,3 +1066,59 @@ def remote_meshing(self) -> bool:
@property
def tacs_model(self):
return self.model.structural

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_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)
8 changes: 5 additions & 3 deletions funtofem/driver/oneway_struct_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -545,9 +545,11 @@ def solve_adjoint(self):
# write the sensitivity file for the tacs AIM
self.model.write_sensitivity_file(
comm=self.comm,
filename=self.struct_aim.root_sens_file
if not self.fun3d_dir
else self.analysis_sens_file,
filename=(
self.struct_aim.root_sens_file
if not self.fun3d_dir
else self.analysis_sens_file
),
discipline="structural",
)

Expand Down
11 changes: 6 additions & 5 deletions funtofem/interface/caps2fun/aflr_aim.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,13 @@ def _setDictOptions(self):
"""
Set AFLR3 and AFLR4 options via dictionaries.
"""
dictOptions = self._dictOptions
if self.root_proc:
dictOptions = self._dictOptions

for ind, option in enumerate(dictOptions["aflr4AIM"]):
self.surface_aim.input[option].value = dictOptions["aflr4AIM"][option]
for ind, option in enumerate(dictOptions["aflr4AIM"]):
self.surface_aim.input[option].value = dictOptions["aflr4AIM"][option]

for ind, option in enumerate(dictOptions["aflr3AIM"]):
self.volume_aim.input[option].value = dictOptions["aflr3AIM"][option]
for ind, option in enumerate(dictOptions["aflr3AIM"]):
self.volume_aim.input[option].value = dictOptions["aflr3AIM"][option]

return self
36 changes: 15 additions & 21 deletions funtofem/interface/caps2fun/fun3d_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,25 @@ def build(
verbosity=0,
):
"""
make a pyCAPS problem with the tacsAIM and egadsAIM on serial / root proc
Make a pyCAPS problem with the tacsAIM and egadsAIM on serial / root proc
Parameters
---------------------------------
csm_file : filepath
filename / full path of ESP/CAPS Constructive Solid Model or .CSM file
Filename / full path of ESP/CAPS Constructive Solid Model or .CSM file.
comm : MPI.COMM
MPI communicator
MPI communicator.
project_name : str
Name of the case that is passed to the flow side, e.g., what is used to name the FUN3D input files.
problem_name : str
CAPS problem name, internal name used to define the CAPS problem and determines the name of the directory
that is created by CAPS to build the fluid mesh, geometry, sensitivity files, etc.
mesh_morph : bool
Turn mesh morphing on or off for use with shape variables that alter the fluid geometry
(e.g., when using mesh deformation rather than remeshing).
root : int
The rank of the processor that will control this process.
verbosity : int
Parameter passed directly to pyCAPS to determine output level.
"""
caps_problem = None
if comm.rank == root:
Expand All @@ -55,24 +67,6 @@ def build(
comm.Barrier()
return cls(fun3d_aim, aflr_aim, comm, project_name, root=root)

@classmethod
def build_morph(
cls,
csm_file,
comm,
project_name="fun3d_CAPS",
root: int = 0,
problem_name: str = "capsFluid",
):
return cls.build(
csm_file=csm_file,
comm=comm,
project_name=project_name,
problem_name=problem_name,
root=root,
mesh_morph=True,
)

@property
def root_proc(self) -> bool:
return self.fun3d_aim.root_proc
Expand Down
12 changes: 12 additions & 0 deletions funtofem/interface/solver_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ def __init__(
self.aero_comm = master_comm
self.aero_root = aero_root

def __str__(self):
line0 = f"CommManager"
line1 = f" Master comm: {self.master_comm}"
line2 = f" Aero comm: {self.aero_comm}"
line3 = f" Aero root: {self.aero_root}"
line4 = f" Struct comm: {self.struct_comm}"
line5 = f" Struct root: {self.struct_root}"

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

return "\n".join(output)


class SolverManager:
def __init__(self, comm, use_flow: bool = True, use_struct: bool = True):
Expand Down
Loading
Loading