Skip to content

Commit

Permalink
Add dictionary input for setting aflr4AIM options. (smdogroup#236)
Browse files Browse the repository at this point in the history
* Add dictionary input for setting aflr4AIM options.

* Check for aflr mesher

* Add option to use dictionaries for AIM settings

* Run _set_dict_options on root proc

* Add option to change verbosity of CAPS
  • Loading branch information
bburke38 authored Jul 28, 2023
1 parent 8040a6e commit 2ca603e
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 11 deletions.
54 changes: 46 additions & 8 deletions tacs/caps2tacs/aflr_aim.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
class AflrAim:
def __init__(self, caps_problem, comm, root=0):
"""
MPI wrapper class for AflrAIM from ESP/CAPS
Requires use of ESPbeta at the moment
MPI wrapper class for AflrAIM from ESP/CAPS.
"""

self.caps_problem = caps_problem
Expand All @@ -15,6 +14,8 @@ def __init__(self, caps_problem, comm, root=0):
# holds aflr4 aim
self._aim = None

self._dictOptions = None

self._build_aim()
return

Expand All @@ -40,18 +41,55 @@ def _build_aim(self):
self._aim = self.caps_problem.analysis.create(aim="aflr4AIM", name="aflr4")
return

def set_mesh(
self, ff_growth=1.4, min_scale=0.05, max_scale=0.5, use_quad=False, no_prox=True
):
# set surface mesh properties
def set_mesh(self, min_scale=0.05, max_scale=0.5, AFLR4_Quad=False, no_prox=True):
"""
Set mesh properties for AFLR4 AIM. A few options are available in this routine.
To set other options for AFLR4, use the save_dict_options routine.
Parameters
----------
min_scale: Relative scale of minimum spacing to reference length.
The relative scale of minimum spacing to reference length (ref_len) controls
the minimum spacing that can be set on any component/body surface.
max_scale: Relative scale of maximum spacing to reference length.
The relative scale of maximum spacing to reference length (ref_len) controls
the maximum spacing that can be set on any component/body surface.
AFLR4_Quad: Generate a mixed quad/tria-face grid.
no_prox: Disable proximity checking.
Proximity checking is automatically disabled if there is only one component/body defined.
"""

if self.root_proc:
self.aim.input.ff_cdfr = ff_growth
self.aim.input.min_scale = min_scale
self.aim.input.max_scale = max_scale
self.aim.input.AFLR4_Quad = use_quad
self.aim.input.AFLR4_Quad = AFLR4_Quad
self._aim.input.no_prox = no_prox
return self

def save_dict_options(self, dictOptions: dict = None):
"""
Optional method to set AFLR4 mesh settings using dictionaries.
Call this before setting up the TACS model. The dictionary should take
the form of, e.g.:
dictOptions['aflr4AIM']['myOption'] = myValue
"""
self._dictOptions = dictOptions

return self

def _set_dict_options(self):
"""
Set AFLR4 options via dictionaries.
"""
dictOptions = self._dictOptions

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

return self

def register_to(self, tacs_aim):
"""
cascade method to register the egads aim to the tacs aim wrapper class
Expand Down
27 changes: 27 additions & 0 deletions tacs/caps2tacs/egads_aim.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ class EgadsAim:

def __init__(self, caps_problem, comm):
self.comm = comm

self._dictOptions = None

if comm is None or comm.rank == 0:
self._aim = caps_problem.analysis.create(aim="egadsTessAIM")
self._is_setup = False
Expand Down Expand Up @@ -43,6 +46,30 @@ def set_mesh(
self._is_setup = True
return self

def save_dict_options(self, dictOptions: dict = None):
"""
Optional method to set EGADS mesh settings using dictionaries.
Call this before setting up the TACS model. The dictionary should take
the form of, e.g.:
dictOptions['egadsTessAIM']['myOption'] = myValue
"""
self._dictOptions = dictOptions

return self

def _set_dict_options(self):
"""
Set EGADS options via dictionaries.
"""
dictOptions = self._dictOptions

if self.root_proc:
for ind, option in enumerate(dictOptions["egadsTessAIM"]):
self.aim.input[option].value = dictOptions["egadsTessAIM"][option]

return self

@property
def is_setup(self) -> bool:
return self._is_setup
Expand Down
30 changes: 30 additions & 0 deletions tacs/caps2tacs/tacs_aim.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ def __init__(self, caps_problem, comm=None):
self._design_variables = []
self._mesh_aim = None

self._dict_options = None

# build flags
self._setup = False
self._first_setup = True
Expand Down Expand Up @@ -179,6 +181,9 @@ def setup_aim(
dv.name: dv.DV_dictionary for dv in self._design_variables
}

if self._dict_options is not None:
self._set_dict_options()

# end of serial or root proc section

# note that setup is finished now
Expand Down Expand Up @@ -302,6 +307,31 @@ def update_properties(self):

return

def save_dict_options(self, aimOptions: dict = None):
"""
Optional method to set tacsAIM settings using dictionaries. Settings specified
through dictionaries take precedence over other methods. The dictionary should
take the form of, e.g.:
aimOptions['tacsAIM']['myOption'] = myValue
"""

self._dict_options = aimOptions

return self

@root_proc
def _set_dict_options(self):
"""
Set any options that were specified through dictionaries.
"""
aimOptions = self._dict_options

for ind, option in enumerate(aimOptions["tacsAim"]):
self.aim.input[option].value = aimOptions["tacsAim"][option]

return self

@root_proc
def pre_analysis(self):
"""
Expand Down
10 changes: 7 additions & 3 deletions tacs/caps2tacs/tacs_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def tacs_aim(self) -> TacsAim:
return self._tacs_aim

@property
def mesh_aim(self):
def mesh_aim(self) -> AflrAim:
return self._mesh_aim

@property
Expand All @@ -45,7 +45,7 @@ def uses_aflr(self):
return isinstance(self.mesh_aim, AflrAim)

@classmethod
def build(cls, csm_file, comm=None, mesh="egads", problem_name: str = "capsStruct"):
def build(cls, csm_file, comm=None, mesh="egads", problem_name: str = "capsStruct", verbosity=1):
"""
make a pyCAPS problem with the tacsAIM and egadsAIM on serial / root proc
Expand All @@ -61,7 +61,7 @@ def build(cls, csm_file, comm=None, mesh="egads", problem_name: str = "capsStruc
assert mesh in cls.MESH_AIMS
if comm is None or comm.rank == 0:
caps_problem = pyCAPS.Problem(
problemName=problem_name, capsFile=csm_file, outLevel=1
problemName=problem_name, capsFile=csm_file, outLevel=verbosity
)
tacs_aim = TacsAim(caps_problem, comm)
mesh_aim = None
Expand Down Expand Up @@ -117,6 +117,10 @@ def setup(self, include_aim: bool = True):
if include_aim:
self.tacs_aim.setup_aim()

# Set additional options for meshing AIM through dictionaries
if self.mesh_aim._dictOptions is not None:
self.mesh_aim._set_dict_options()

# go ahead and generate the first input files and mesh for TACS
if not self.tacs_aim.change_shape:
self.tacs_aim.pre_analysis()
Expand Down

0 comments on commit 2ca603e

Please sign in to comment.