Skip to content
Closed
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: 12 additions & 0 deletions .github/workflows/format-and-lint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: Format and Lint

on:
push:
branches: [main]
tags:
- v*.*.*
pull_request:

jobs:
pre-commit:
uses: mdolab/.github/.github/workflows/format-and-lint.yaml@ruffConfig
50 changes: 48 additions & 2 deletions adflow/mphys/mphys_adflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

# Set this to true to print out the name of the function being called and the class it's being called from along with
# printing messages when node coordinates and states are updated from OpenMDAO inputs and outputs.
DEBUG_LOGGING = False
DEBUG_LOGGING = True


X_AERO0 = MPhysVariables.Aerodynamics.Surface.COORDINATES_INITIAL
Expand All @@ -23,7 +23,6 @@
F_AERO = MPhysVariables.Aerodynamics.Surface.LOADS
Q_AERO = MPhysVariables.Aerodynamics.Surface.HEAT_FLOW


def print_func_call(component):
"""Prints the name of the class and function being. Useful for debugging when you want to see what order OpenMDAO
is calling things in.
Expand Down Expand Up @@ -499,24 +498,67 @@ def _setup_vectors(self, root_vectors):
self.set_val("adflow_states", self.solver.getStates())

def apply_nonlinear(self, inputs, outputs, residuals):
if DEBUG_LOGGING:
print_func_call(self)
solver = self.solver
ap = self.ap
setAeroProblem(solver, ap, self.ap_vars, inputs=inputs, outputs=outputs, print_dict=False)

# flow residuals
residuals["adflow_states"] = solver.getResidual(ap)

def printStatesRange(self, states):
stateNames = ["density", "velocityX", "velocityY", "velocityZ", "Energy", "Turb"]
for ii, stateName in enumerate(stateNames):
singleState = states[ii::6]
minState = self.comm.allreduce(np.min(singleState), op=MPI.MIN)
maxState = self.comm.allreduce(np.max(singleState), op=MPI.MAX)
if self.comm.rank == 0:
print(f"{stateName}: min = {minState:.11e}, max = {maxState:.11e}")

def solve_nonlinear(self, inputs, outputs):
if DEBUG_LOGGING:
print_func_call(self)
solver = self.solver
ap = self.ap

if self._do_solve:

setAeroProblem(solver, ap, self.ap_vars, inputs=inputs, outputs=outputs, print_dict=False)
ap.solveFailed = False # might need to clear this out?
ap.fatalFail = False

# For some reason, the ADflow solver will randomly NaN in the first iteration of a solve when starting from a state and mesh that it has already converged successfully. I have tried many things to debug this but nothing has worked:
# - Explicitly setting state before solve
# - compiling with `-O1 -xCORE-AVX2`
# - Compiling with `-fp-model=precise`
# - Compiling with only `-O2`
# - Disabling blockettes
# - running with a different number of procs
# - Running on `cas_ait` instead of `sky_ele` nodes
# - As above but setting slightly perturbed states
# - Running on a different mesh
# - Running on stampede

# The thing I have found to work is:
# - Set the OpenMDAO inputs and outputs
# - Evaluate the residual
# - If there is a NaN in the residual, call `resetFlow` and set the same OpenMDAO inputs and outputs again
# - Run the solver
res = solver.getResidual(ap)

nanInResidual = self.comm.allreduce(any(np.isnan(res)), op=MPI.LOR)
if self.comm.rank == 0:
if nanInResidual:
print("NaN present in residual")
else:
print("No NaNs in residual")

if nanInResidual:
# Reset the solution then set the inputs and states again, somehow this fixes the issue
solver.resetFlow(ap)
setAeroProblem(solver, ap, self.ap_vars, inputs=inputs, outputs=outputs, print_dict=False)

# do not write solution files inside the solver loop
solver(ap, writeSolution=False)

Expand All @@ -529,6 +571,10 @@ def solve_nonlinear(self, inputs, outputs):
print("# Solve Fatal Fail. Analysis Error")
print("###############################################################")

# write the solution so that we can diagnose
solver.writeSolution(baseName=fail_name, number=self.solution_counter)
self.solution_counter += 1

raise AnalysisError("ADFLOW Solver Fatal Fail")

if ap.solveFailed:
Expand Down
8 changes: 8 additions & 0 deletions ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
extend-exclude =[
"src/build/fort_depend.py",
"src/adjoint/autoEdit/autoEdit*.py",
"src_cs/build/complexify.py",
"adflow/pyWeightAndBalance.py",
"adflow/pyWingCG.py",
"adflow/om_*.py",
]
Loading