diff --git a/README.md b/README.md index bcb0c513..7d8aa6ca 100644 --- a/README.md +++ b/README.md @@ -13,5 +13,4 @@ DuctAPE is a code for the aerodynamic evaluation of axisymmetric ducted propulso It is strongly influenced by the underlying [theory](https://web.mit.edu/drela/Public/web/dfdc/DFDCtheory12-31.pdf) of Ducted Fan Design Code [(DFDC)](https://web.mit.edu/drela/Public/web/dfdc/), utilizing a linear axisymmetric vortex panel method for duct and center body, blade element lifting line rotor representation, and psuedo wake-screw wake model axisymmetrically smeared onto an elliptic grid for efficient computation. DuctAPE has been developed specifically for applications in gradient-based optimization settings. -The selected solver methods have been chosen to balance code efficiency as well as robustness while simultaneously allowing for efficient automatic differentiation through DuctAPE employing [ImplicitAD.jl](https://flow.byu.edu/ImplicitAD.jl/dev/). -At the same time, the basic functionality of a DFDC-like solve approach has been maintained for the interested user. +The default solver methods have been chosen to balance code efficiency as well as robustness while simultaneously allowing for efficient automatic differentiation through DuctAPE employing [ImplicitAD.jl](https://flow.byu.edu/ImplicitAD.jl/dev/). diff --git a/docs/src/DuctAPE/advanced_usage/outputs.md b/docs/src/DuctAPE/advanced_usage/outputs.md index 540d5106..a12db5f1 100644 --- a/docs/src/DuctAPE/advanced_usage/outputs.md +++ b/docs/src/DuctAPE/advanced_usage/outputs.md @@ -1,7 +1,8 @@ ## Available Outputs The output tuple contains many items. -The [`post_process`](@ref "DuctAPE.post_process") function docstring lists them: +The [`post_process`](@ref "DuctAPE.post_process") function docstring lists them. +The purpose of showing this function here is not for you to manually run the fuction or apply any advanced usage, but simply rather for you to see what the available outputs are, as several of them may apply to advanced usage cases. ```@docs; canonical=false DuctAPE.post_process diff --git a/docs/src/DuctAPE/advanced_usage/precompilation.md b/docs/src/DuctAPE/advanced_usage/precompilation.md index 22e1ff7a..3ca6076c 100644 --- a/docs/src/DuctAPE/advanced_usage/precompilation.md +++ b/docs/src/DuctAPE/advanced_usage/precompilation.md @@ -27,6 +27,50 @@ You may run all these simultaneously using the `initialize_all_caches` function. DuctAPE.initialize_all_caches ``` +As an example of how to run this function, we'll grab [solver options](@ref "Aerodynamics Solvers") and [oaneling constants](@ref "Paneling Constants") from previous examples + +```@julia +# - grab an object of SolverOptionsType defined in a previous example - # +aero_solver_options = DuctAPE.NLsolveOptions(; + algorithm=:newton, + atol=1e-10, + iteration_limite=30, + linesearch_method=LineSearches.BackTracking, #don't include parentheses on method handle + linesearch_kwargs=(; order=3, maxstep=1e6), + additional_kwargs=(; autoscale=false), +) + +# - grab an object of PanelingConstants type from the Getting Started tutorial - # +# number of panels for the duct inlet +nduct_inlet = 30 + +# number of panels for the center body inlet +ncenterbody_inlet = 30 + +# number of panels from: +# - rotor to duct trailing edge +# - duct trailing edge to center body trailing edge +# - center body trailing edge to end of wake +npanels = [30, 1, 30] + +# the duct trailing edge is ahead of the centerbody trailing edge. +dte_minus_cbte = -1.0 + +# number of wake sheets (one more than blade elements to use) +nwake_sheets = 11 + +# non-dimensional wake length aft of rear-most trailing edge +wake_length = 0.8 + +# assemble paneling constants +paneling_constants = DuctAPE.PanelingConstants( + nduct_inlet, ncenterbody_inlet, npanels, dte_minus_cbte, nwake_sheets, wake_length +) + +# - Initialize Caches - # +prepost_container_caching, solve_parameter_caching, solve_container_caching = DuctAPE.initialize_all_caches(aero_solver_options, paneling_constants) +``` + ## How to pass the caches into an analysis The precompiled caches can be passed in via keyword arguments to the analysis functions. If they are not, they are generated as the first step in the analysis. diff --git a/docs/src/DuctAPE/tutorial.md b/docs/src/DuctAPE/tutorial.md index 13075d4f..28ba2bf4 100644 --- a/docs/src/DuctAPE/tutorial.md +++ b/docs/src/DuctAPE/tutorial.md @@ -6,18 +6,17 @@ Pages = ["tutorial.md"] Depth = 5 ``` -The following is a basic tutorial on how to set up the inputs to, and run, an analysis of a ducted fan in DuctAPE. +The following is a basic tutorial on how to set up and run an analysis of a ducted fan in DuctAPE. ```@setup tutorial include("../assets/plots_default.jl") gr() ``` -We begin by loading the package, and optionally create a shorthand name. +We begin by loading the package: ```@example tutorial using DuctAPE -const dt = DuctAPE nothing # hide ``` @@ -31,7 +30,8 @@ DuctAPE.Propulsor ### Body Geometry -We begin by defining a matrix of coordinates for the duct and another for the centerbody geometries, for example: +We begin by defining a matrix of coordinates for the duct and another for the centerbody geometries. +For example: ```@example tutorial duct_coordinates = [ @@ -139,24 +139,24 @@ nothing # hide ``` ```@example tutorial -pg = plot( - duct_coordinates[:, 1], - duct_coordinates[:, 2]; - aspectratio=1, - color=1, - linewidth=2, - label="Duct", - xlabel="z", - ylabel="r", - legend=:left, +pg = plot( # hide + duct_coordinates[:, 1], # hide + duct_coordinates[:, 2]; # hide + aspectratio=1, # hide + color=1, # hide + linewidth=2, # hide + label="Duct", # hide + xlabel="z", # hide + ylabel="r", # hide + legend=:left, # hide ) # hide -plot!( - pg, - centerbody_coordinates[:, 1], - centerbody_coordinates[:, 2]; - color=2, - linewidth=2, - label="Center Body", +plot!( # hide + pg, # hide + centerbody_coordinates[:, 1], # hide + centerbody_coordinates[:, 2]; # hide + color=2, # hide + linewidth=2, # hide + label="Center Body", # hide ) # hide ``` @@ -249,7 +249,7 @@ afparams = DuctAPE.c4b.DFDCairfoil(; airfoils = fill(afparams, length(r)) # specify the airfoil array # assemble rotor parameters -rotorstator_parameters = dt.RotorStatorParameters( +rotorstator_parameters = DuctAPE.RotorStatorParameters( [B], [rotorzloc], r, @@ -265,14 +265,14 @@ nothing # hide ``` ```@example tutorial -plot!( - pg, - rotorzloc * ones(length(r)), - r .* Rtip; - seriestype=:scatter, - markersize=3, - markerstrokewidth=0, - label="Blade Elements", +plot!( # hide + pg, # hide + rotorzloc * ones(length(r)), # hide + r .* Rtip; # hide + seriestype=:scatter, # hide + markersize=3, # hide + markerstrokewidth=0, # hide + label="Blade Elements", # hide ) # hide ``` @@ -302,13 +302,14 @@ RPM = 8000.0 Omega = RPM * pi / 30 # if using RPM, be sure to convert to rad/s # utilizing the constructor function to put things in vector types -operating_point = dt.OperatingPoint(Vinf, rhoinf, muinf, asound, Omega) +operating_point = DuctAPE.OperatingPoint(Vinf, rhoinf, muinf, asound, Omega) nothing # hide ``` ### Paneling Constants The `PanelingConstants` object contains the constants required for DuctAPE to re-panel the provided geometry into a format compatible with the solve structure. +Specifically, the DuctAPE solver makes some assumptions on the relative positioning of the body surfaces relative to the wakes and each other; and this is most easily guarenteed by a re-paneling of the provided body surface geometry. The `PanelingConstants` object is also used to build all of the preallocated caches inside DuctAPE, which can be done up-front if desired. Note that there is some functionality in place for cases when the user wants to keep their own specified geometry, but this functionality should be used with caution and only by users who are certain their provided geometry is in the compatible format. See the [Examples](@ref "Circumventing the Automated Geometry Re-paneling") for an example. @@ -339,7 +340,7 @@ nwake_sheets = 11 wake_length = 0.8 # assemble paneling constants -paneling_constants = dt.PanelingConstants( +paneling_constants = DuctAPE.PanelingConstants( nduct_inlet, ncenterbody_inlet, npanels, dte_minus_cbte, nwake_sheets, wake_length ) nothing # hide @@ -361,17 +362,17 @@ Vref = 50.0 Rref = Rtip # assemble reference parameters -reference_parameters = dt.ReferenceParameters([Vref], [Rref]) +reference_parameters = DuctAPE.ReferenceParameters([Vref], [Rref]) nothing # hide ``` -### All Together +### Assembling the Propulsor We are now posed to construct the `Propulsor` input type. ```@example tutorial # assemble propulsor object -propulsor = dt.Propulsor( +propulsor = DuctAPE.Propulsor( duct_coordinates, centerbody_coordinates, rotorstator_parameters, @@ -391,7 +392,7 @@ DuctAPE.set_options ``` ```@example tutorial -options = dt.set_options() +options = DuctAPE.set_options() ``` For more advanced option selection, see the examples and API reference. @@ -406,13 +407,13 @@ DuctAPE.analyze(::DuctAPE.Propulsor, ::DuctAPE.Options) ``` ```@example tutorial -outs, success_flag = dt.analyze(propulsor, options) +outs, success_flag = DuctAPE.analyze(propulsor, options) nothing # hide ``` ### Single Run Outputs -There are many outputs contained in the named tuple output from the `analyze` function (see the [post_process() docstring](@ref DuctAPE.post_process)), but some that may be of immediate interest include: +There are many outputs contained in the named tuple output from the `analyze` function (see the [post_process docstring](@ref DuctAPE.post_process)), but some that may be of immediate interest include: ```@example tutorial # Total Thrust Coefficient @@ -425,7 +426,7 @@ outs.totals.CQ ## Run a Multi-Point Analysis -In the case that one wants to run the same geometry at several different operating points, for example: for a range of advance ratios, there is another dispatch of the `analyze` function that takes in an input, `multipoint`, that is a vector of operating points. +In the case that one wants to run the same geometry at several different operating points, for example: for a range of advance ratios, there is another dispatch of the `analyze` function that accepts an input, `multipoint`, that is a vector of operating points. ```@docs; canonical=false DuctAPE.analyze(multipoint::AbstractVector{TO},propulsor::Propulsor,options::Options) where TO<:OperatingPoint @@ -455,7 +456,7 @@ nothing #hide There are a few things to note here. 1. We want to make sure that the operating point objects we put into the input vector are unique instances. -2. We need to use the dispatch of `set_options` that takes in the operating point vector to set up the right number of things in the background (like convergence flags for each operating point). +2. We need to use the dispatch of `set_options` that accepts the operating point vector to set up the right number of things in the background (like convergence flags for each operating point). 3. The outputs of the analysis are vectors of the same outputs for a single analysis. ### Multi-point Outputs diff --git a/docs/src/index.md b/docs/src/index.md index e28c7591..ee22d321 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -1,8 +1,8 @@ # DuctAPE.jl [[Duct](#)ed [A](#)xisymmetric [P](#)ropulsor [E](#)valuation] -Authors: Judd Mehr, +Author: Judd Mehr -Contributers: Taylor McDonnell, +Contributer: Taylor McDonnell DuctAPE is a code for the aerodynamic evaluation of axisymmetric ducted propulsors designed for incompressible (low mach) applications. It is strongly influenced by the underlying [theory](https://web.mit.edu/drela/Public/web/dfdc/DFDCtheory12-31.pdf) of Ducted Fan Design Code [(DFDC)](https://web.mit.edu/drela/Public/web/dfdc/), utilizing a linear axisymmetric vortex panel method for duct and center body, blade element lifting line rotor representation, and wake model axisymmetrically smeared onto an elliptic grid for efficient computation. @@ -12,16 +12,16 @@ DuctAPE has been developed specifically for applications in gradient-based optim ### Installation ```julia -pkg> add DuctAPE +pkg> add https://github.com/byuflowlab/DuctAPE.jl.git ``` ### Documentation -- Start with [Getting Started](@ref) to get up and running. -- The Advanced Usage tab includes several pages of additional information for customizing your usage. -- The API tab contains public and private method descriptions. -- The Theory tab contain several pages on the underlying theory of DuctAPE. -- The C$^4$Blade tab contains documentation for the C$^4$Blade submodule used for airfoil/cascade management within DuctAPE as well as state initialization. +- [Getting Started](@ref) will have you up and running quickly. +- The [Advanced Usage](@ref "Advanced Option Selection") tab includes several pages of additional information for customizing your usage. +- The [API](@ref "Public API") tab contains public and private method descriptions. +- The [Theory](@ref) tab contain several pages on the underlying theory of DuctAPE. +- The [C$^4$Blade](@ref "C$^\textrm{4}$Blade [[C](#)ascade [C](#)ompatible [CCBlade](https://flow.byu.edu/CCBlade.jl/stable/)]") tab contains documentation for the C$^4$Blade submodule used for airfoil/cascade management within DuctAPE as well as state initialization. ### Citing diff --git a/src/utilities/caching/allocate_caches.jl b/src/utilities/caching/allocate_caches.jl index 669fb764..42dddad1 100644 --- a/src/utilities/caching/allocate_caches.jl +++ b/src/utilities/caching/allocate_caches.jl @@ -244,7 +244,7 @@ OR - `problem_dimensions::ProblemDimensions` : a ProblemDimensions object # Keyword Arguments -- `fd_chunk_size::Int=12` : chunk size to use for PreallocationTools caches. Note that the automated chuck size for DuctAPE will always be the ForwardDiff threshold of 12 due to the size of the system, so it will be best to leave this at the default unless further development allows for chunk size selection for individual solvers. +- `fd_chunk_size::Int=12` : chunk size to use for PreallocationTools caches. Note that the automated chunk size for DuctAPE will always be the ForwardDiff threshold of 12 due to the size of the system, so it will be best to leave this at the default unless further development allows for chunk size selection for individual solvers. - `levels::Int=1` : levels for nested duals. Note that since ImplicitAD is being used for all solves, there should be no need for more than 1 level. @@ -620,7 +620,7 @@ OR - `problem_dimensions::ProblemDimensions` : a ProblemDimensions object used for sizing # Keyword Arguments -- `fd_chunk_size::Int=12` : chunk size to use for PreallocationTools caches. Note that the automated chuck size for DuctAPE will always be the ForwardDiff threshold of 12 due to the size of the system, so it will be best to leave this at the default unless further development allows for chunk size selection for individual solvers. +- `fd_chunk_size::Int=12` : chunk size to use for PreallocationTools caches. Note that the automated chunk size for DuctAPE will always be the ForwardDiff threshold of 12 due to the size of the system, so it will be best to leave this at the default unless further development allows for chunk size selection for individual solvers. - `levels::Int=1` : levels for nested duals. Note that since ImplicitAD is being used for all solves, there should be no need for more than 1 level. # Returns @@ -1048,7 +1048,7 @@ OR - `problem_dimensions::ProblemDimensions` : a ProblemDimensions object # Keyword Arguments -- `fd_chunk_size::Int=12` : chunk size to use for PreallocationTools caches. Note that the automated chuck size for DuctAPE will always be the ForwardDiff threshold of 12 due to the size of the system, so it will be best to leave this at the default unless further development allows for chunk size selection for individual solvers. +- `fd_chunk_size::Int=12` : chunk size to use for PreallocationTools caches. Note that the automated chunk size for DuctAPE will always be the ForwardDiff threshold of 12 due to the size of the system, so it will be best to leave this at the default unless further development allows for chunk size selection for individual solvers. - `levels::Int=1` : levels for nested duals. Note that since ImplicitAD is being used for all solves, there should be no need for more than 1 level. # Returns diff --git a/src/utilities/caching/caches.jl b/src/utilities/caching/caches.jl index a8fd3266..93447e48 100644 --- a/src/utilities/caching/caches.jl +++ b/src/utilities/caching/caches.jl @@ -8,7 +8,7 @@ Convenience function to initialize all caches before calling analysis. - `paneling_constants::PanelingConstants` : PanelingConstants object upon which all cache sizing depends # Keyword Arguments -- `fd_chunk_size::Int=12` : chunk size to use for PreallocationTools caches. Note that the automated chuck size for DuctAPE will always be the ForwardDiff threshold of 12 due to the size of the system, so it will be best to leave this at the default unless further development allows for chunk size selection for individual solvers. +- `fd_chunk_size::Int=12` : chunk size to use for PreallocationTools caches. Note that the automated chunk size for DuctAPE will always be the ForwardDiff threshold of 12 due to the size of the system, so it will be best to leave this at the default unless further development allows for chunk size selection for individual solvers. - `levels::Int=1` : levels for nested duals. Note that since ImplicitAD is being used for all solves, there should be no need for more than 1 level. diff --git a/src/utilities/inputs.jl b/src/utilities/inputs.jl index 1a798c09..2c68f085 100644 --- a/src/utilities/inputs.jl +++ b/src/utilities/inputs.jl @@ -3,10 +3,6 @@ Propulsor operating point information. -Note that the actual struct requires the inputs to be arrays, but there is a constructor function that will take in scalars and automatically build the array-based struct. - -Also note that even though each field is required to be a vector, only `Omega` should have more than one entry, and only then if there are more than one rotor. The purpose behind having vector rather than constant scalar inputs here is for ease of redefinition in an optimization setting when freestream design variables may be present. - # Arguments - `Vinf::AbstractVector{Float}` : Freestream velocity magnitude (which is only in the axial direction). @@ -113,7 +109,7 @@ Note that the actual struct requires the inputs to be arrays, but there is a con - `twists::AbstractArray{Float}` : Blade element angles, in radians. - `tip_gap::AbstractVector{Float}` : Currently unused, do not set to anything other than zeros. - `airfoils::AbstractArray{AFType}` : Airfoil types describing the airfoil polars for each blade element. Currently only fully tested with `C4Blade.DFDCairfoil` types. -- `fliplift::AbstractVector{Bool}` : flag to indicate if the airfoil lift values should be flipped or not. +- `fliplift::AbstractVector{Bool}` : Flag to indicate if the airfoil lift values should be flipped or not. """ struct RotorStatorParameters{ Tb<:AbstractVector, diff --git a/src/utilities/options.jl b/src/utilities/options.jl index 5919905b..08f9ff42 100644 --- a/src/utilities/options.jl +++ b/src/utilities/options.jl @@ -53,13 +53,13 @@ abstract type IntegrationMethod end #---------------------------------# """ - struct Romberg{TF,TI} <: IntegrationMethod + struct Romberg <: IntegrationMethod Options for Romberg integration method # Fields -- `max_subdivisions::TI = 10` : maximum number of subdivisions. Note, total number of internvals is 2^N, where N is number of subdivisions. -- `atol::TF = 1e-6` : absolute error tolerance. +- `max_subdivisions::Int = 10` : maximum number of subdivisions. Note, total number of internvals is 2^N, where N is number of subdivisions. +- `atol::Float = 1e-6` : absolute error tolerance. """ @kwdef struct Romberg{TF,TI} <: IntegrationMethod max_subdivisions::TI = 10 @@ -67,14 +67,14 @@ Options for Romberg integration method end """ - struct GaussKronrod{TF,TI} <: IntegrationMethod + struct GaussKronrod <: IntegrationMethod Options for Gauss-Kronrod integration method # Fields -- `order::TI = 7` : order of Legendre polynomial to use on each interval -- `maxevales::TI = 10^7` : maximum number of evaluations in the adaptive method -- `atol::TF = 0.0` : absolute error tolerance. (note, if zero, QuadGK uses sqrt(eps()) relative tolerance). +- `order::Int = 7` : order of Legendre polynomial to use on each interval +- `maxevales::Int = 10^7` : maximum number of evaluations in the adaptive method +- `atol::Float = 0.0` : absolute error tolerance. (note, if zero, QuadGK uses sqrt(eps()) relative tolerance). """ @kwdef struct GaussKronrod{TF,TI} <: IntegrationMethod order::TI = 7 @@ -83,13 +83,13 @@ Options for Gauss-Kronrod integration method end """ - struct GaussLegendre{TN,TW} <: IntegrationMethod + struct GaussLegendre <: IntegrationMethod Options for Gauss-Legendre integration method # Fields -- `sample_points::TN` : Sample Points -- `weights::TW` : Gauss weights +- `sample_points::Int` : Sample Points +- `weights::Int` : Gauss weights """ struct GaussLegendre{TN,TW} <: IntegrationMethod sample_points::TN @@ -121,7 +121,7 @@ function GaussLegendre(nsamples=8; silence_warnings=true) end """ - struct IntegrationOptions{TN<:IntegrationMethod,TS<:IntegrationMethod} + struct IntegrationOptions A struct used to hold the integration options for both the nominal and singular cases. @@ -157,29 +157,28 @@ struct Absolute <: ConvergenceType end # - CSOR Options - # """ - struct CSORSolverOptions{TB,TC<:ConvergenceType,TF,TS} <: SolverOptionsType + struct CSORSolverOptions <: SolverOptionsType Type containing all the options for the CSOR (controlled successive over relaxation) solver. Note that the defaults match DFDC with the exception of the relaxation schedule, which is an experimental feature. # Fields -- `var::type` : -- `verbose::TB = false` : flag to print verbose statements -- `iteration_limit::TF = 1e2` : maximum number of iterations -- `nrf::TF = 0.4` : nominal relaxation factor -- `bt1::TF = 0.2` : backtracking factor 1 -- `bt2::TF = 0.6` : backtracking factor 2 -- `pf1::TF = 0.4` : press forward factor 1 -- `pf2::TF = 0.5` : press forward factor 2 -- `btw::TF = 0.6` : backtracking factor for wake -- `pfw::TF = 1.2` : press forward factor for wake +- `verbose::Bool = false` : flag to print verbose statements +- `iteration_limit::Float = 1e2` : maximum number of iterations +- `nrf::Float = 0.4` : nominal relaxation factor +- `bt1::Float = 0.2` : backtracking factor 1 +- `bt2::Float = 0.6` : backtracking factor 2 +- `pf1::Float = 0.4` : press forward factor 1 +- `pf2::Float = 0.5` : press forward factor 2 +- `btw::Float = 0.6` : backtracking factor for wake +- `pfw::Float = 1.2` : press forward factor for wake - `relaxation_schedule::TS = [[0.0;1e-14;1e-13;1e10]), [1.0;1.0;0.0;0.0])]` : values used in spline definition for scaling the relaxation factors (second vector) after various convergence values (first vector). -- `f_circ::TF = 1e-3` : convergence tolerance for rotor circulation -- `f_dgamw::TF = 2e-4` : convergence tolerance for wake vortex strength -- `convergence_type::TC = Relative()` : dispatch for relative or absolute convergence criteria. -- `Vconv::AbstractArray{TF} = [1.0]` : velocity used in relative convergence criteria (should be set to Vref). -- `converged::AbstractArray{TB} = [false]` : flag to track if convergence took place. +- `f_circ::Float = 1e-3` : convergence tolerance for rotor circulation +- `f_dgamw::Float = 2e-4` : convergence tolerance for wake vortex strength +- `convergence_type::ConvergenceType = Relative()` : dispatch for relative or absolute convergence criteria. +- `Vconv::AbstractArray{Float} = [1.0]` : velocity used in relative convergence criteria (should be set to Vref). +- `converged::AbstractArray{Bool} = [false]` : flag to track if convergence took place. """ @kwdef struct CSORSolverOptions{TB,TC<:ConvergenceType,TF,TI,TS} <: SolverOptionsType # Defaults are DFDC hard-coded values @@ -226,16 +225,16 @@ function CSORSolverOptions(multipoint; kwargs...) end """ - struct FixedPointOptions{TB,TF,TI} <: ExternalSolverOptions + struct FixedPointOptions <: ExternalSolverOptions Options for the FixedPoint.jl package solver # Fields -- `iteration_limit::TF = 1000` : maximum number of iterations -- `vel::TF = 0.9` : vel keyword argument, default is package default -- `ep::TF = 0.01` : ep keyword argument, default is package default -- `atol::TF = 1e-12` : absolute convergence tolerance -- `converged::AbstractArray{TB} = [false]` : flag to track if convergence took place. +- `iteration_limit::Int = 1000` : maximum number of iterations +- `vel::Float = 0.9` : vel keyword argument, default is package default +- `ep::Float = 0.01` : ep keyword argument, default is package default +- `atol::Float = 1e-12` : absolute convergence tolerance +- `converged::AbstractArray{Bool} = [false]` : flag to track if convergence took place. """ @kwdef struct FixedPointOptions{TB,TF,TI} <: ExternalSolverOptions iteration_limit::TI = 1000 @@ -247,23 +246,23 @@ Options for the FixedPoint.jl package solver end """ - struct SpeedMappingOptions{TB,TF,TI,TL,TSm,TU} <: ExternalSolverOptions + struct SpeedMappingOptions <: ExternalSolverOptions Options for the SpeedMapping.jl package solver # Fields -- `orders::AbstractArray{TI} = [3, 2] -- `sig_min::TSm = 0` : maybe set to 1? -- `stabilize::TB = false` : stabilizes before extrapolation -- `check_obj::TB = false` : checks for inf's and nan's and starts from previous finite point -- `atol::TF = 1e-10` : absolute convergence tolerance -- `iteration_limit::TF = 1000` : maximum number of iterations -- `time_limit::TF = Inf` : time limit in seconds -- `lower::TL = nothing` : box lower bounds -- `upper::TU = nothing` : box upper bounds -- `buffer::TF = 0.01` : if using bounds, buffer brings x inside bounds by buffer amountd -- `Lp::TF = Inf` : p value for p-norm for convergence criteria -- `converged::AbstractArray{TB} = [false]` : flag to track if convergence took place. +- `orders::AbstractArray{Int} = [3, 2] +- `sig_min::Int = 0` : maybe set to 1? +- `stabilize::Bool = false` : stabilizes before extrapolation +- `check_obj::Bool = false` : checks for inf's and nan's and starts from previous finite point +- `atol::Float = 1e-10` : absolute convergence tolerance +- `iteration_limit::Float = 1000` : maximum number of iterations +- `time_limit::Float = Inf` : time limit in seconds +- `lower::Float = nothing` : box lower bounds +- `upper::Float = nothing` : box upper bounds +- `buffer::Float = 0.01` : if using bounds, buffer brings x inside bounds by buffer amountd +- `Lp::Float = Inf` : p value for p-norm for convergence criteria +- `converged::AbstractArray{Bool} = [false]` : flag to track if convergence took place. """ @kwdef struct SpeedMappingOptions{TB,TF,TI,TL,TSm,TU} <: ExternalSolverOptions orders::AbstractArray{TI} = [3, 2] @@ -284,15 +283,15 @@ end ##### ----- Quasi-Newton Solvers ----- ##### """ - struct MinpackOptions{TB,TF,TI,TSym} <: ExternalSolverOptions + struct MinpackOptions <: ExternalSolverOptions Options for the MINPACK's HYBRJ solver # Fields -- `algorithm::TSym = :hybr` : algorithm to use in MINPACK.jl (hybr is HYBRJ when the jacobian is provided) -- `atol::TF = 1e-12` : absolute convergence tolerance -- `iteration_limit::TF = 100` : maximum number of iterations -- `converged::AbstractArray{TB} = [false]` : flag to track if convergence took place. +- `algorithm::Symbol = :hybr` : algorithm to use in MINPACK.jl (hybr is HYBRJ when the jacobian is provided) +- `atol::FLoat = 1e-12` : absolute convergence tolerance +- `iteration_limit::FLoat = 100` : maximum number of iterations +- `converged::AbstractArray{Bool} = [false]` : flag to track if convergence took place. """ @kwdef struct MinpackOptions{TB,TF,TI,TSym} <: ExternalSolverOptions algorithm::TSym = :hybr @@ -303,18 +302,18 @@ Options for the MINPACK's HYBRJ solver end """ - struct SIAMFANLEOptions{TA,TB,TF,TI,TK} <: ExternalSolverOptions + struct SIAMFANLEOptions <: ExternalSolverOptions Options for the SIAMFANLEquations pacakge solvers # Fields -- `algorithm::TA = SIAMFANLEquations.nsoli` : algorithm to use -- `rtol::TF = 0.0` : relative convergence tolerance -- `atol::TF = 1e-10` : absolute convergence tolerance -- `iteration_limit::TF = 1000` : maximum number of iterations -- `linear_iteration_limit::TF = 5` : maximum number of linear solve iterations (GMRES) -- `additional_kwargs::TK = (;)` : any additional keyword arguments for the solver -- `converged::AbstractArray{TB} = [false]` : flag to track if convergence took place. +- `algorithm::SIAMFANLEquations algorithm = SIAMFANLEquations.nsoli` : algorithm to use +- `rtol::Float = 0.0` : relative convergence tolerance +- `atol::Float = 1e-10` : absolute convergence tolerance +- `iteration_limit::Int = 1000` : maximum number of iterations +- `linear_iteration_limit::Float = 5` : maximum number of linear solve iterations (GMRES) +- `additional_kwargs = (;)` : any additional keyword arguments for the solver +- `converged::AbstractArray{Bool} = [false]` : flag to track if convergence took place. """ @kwdef struct SIAMFANLEOptions{TA,TB,TF,TI,TK} <: ExternalSolverOptions # Options for overall solve @@ -333,16 +332,16 @@ end # NOTE: these also have fixed-point options """ - struct NonlinearSolveOptions{TA,TB,TF,TI,TT} <: ExternalSolverOptions + struct NonlinearSolveOptions <: ExternalSolverOptions Options for the SimpleNonlinearSolve pacakge solvers # Fields -- `algorithm::TA = SimpleNonlinearSolve.SimpleNewtonRaphson` : algorithm to use -- `additional_kwargs::TK = (;)` : any additional keyword arguments for the solver -- `atol::TF = 1e-12` : absolute convergence tolerance -- `iteration_limit::TF = 25` : maximum number of iterations -- `converged::AbstractArray{TB} = [false]` : flag to track if convergence took place. +- `algorithm::SimpleNonlinearSolve algorithm = SimpleNonlinearSolve.SimpleNewtonRaphson` : algorithm to use +- `additional_kwargs = (;)` : any additional keyword arguments for the solver +- `atol::Float = 1e-12` : absolute convergence tolerance +- `iteration_limit::Float = 25` : maximum number of iterations +- `converged::AbstractArray{Bool} = [false]` : flag to track if convergence took place. """ @kwdef struct NonlinearSolveOptions{TA,TB,TF,TI,TK} <: ExternalSolverOptions # Algorithm Options @@ -356,18 +355,18 @@ Options for the SimpleNonlinearSolve pacakge solvers end """ - struct NLsolveOptions{TB,TF,TK,Tls,Tlsk,TSym} <: ExternalSolverOptions + struct NLsolveOptions <: ExternalSolverOptions Options for the NLsolve pacakge solvers # Fields -- `algorithm::TSym = :anderson` : algorithm to use -- `additional_kwargs::TK = (;)` : any additional keyword arguments for the solver -- `atol::TF = 1e-12` : absolute convergence tolerance -- `iteration_limit::TF = 25` : maximum number of iterations -- `linesearch_method::Tls = LineSearches.MoreThuente` : line search method to use -- `linesearch_kwargs::Tlsk = (;)` : any additional lineseach keyword arguments -- `converged::AbstractArray{TB} = [false]` : flag to track if convergence took place. +- `algorithm::Symbol = :anderson` : algorithm to use +- `additional_kwargs = (;)` : any additional keyword arguments for the solver +- `atol::Float = 1e-12` : absolute convergence tolerance +- `iteration_limit::Int = 25` : maximum number of iterations +- `linesearch_method::LineSearches method = LineSearches.MoreThuente` : line search method to use +- `linesearch_kwargs = (;)` : any additional lineseach keyword arguments +- `converged::AbstractArray{Bool} = [false]` : flag to track if convergence took place. """ @kwdef struct NLsolveOptions{TB,TF,TI,Tls,Tlsk,TSym} <: ExternalSolverOptions # Options for overall solve @@ -384,18 +383,16 @@ end ##### ----- Poly-Algorithm Solvers ----- ##### """ - struct CompositeSolverOptions{ - TB,TS<:Union{ExternalSolverOptions,PolyAlgorithmOptions} - } <: PolyAlgorithmOptions + struct CompositeSolverOptions <: PolyAlgorithmOptions Options for Composite Solvers (start with a partial solve of one solve, then finish with another starting where the first left off). # Fields -- `solvers::AbstractArray{TS} = [ +- `solvers::AbstractArray{SolverOptionsType} = [ NLsolveOptions(; algorithm=:newton, iteration_limit=3), NLsolveOptions(; algorithm=:anderson, atol=1e-12), ]' : Vector of solver options to use. -- `converged::AbstractArray{TB} = [false]` : flag to track if convergence took place. +- `converged::AbstractArray{Bool} = [false]` : flag to track if convergence took place. """ @kwdef struct CompositeSolverOptions{ TB,TI,TS<:Union{ExternalSolverOptions,PolyAlgorithmOptions} @@ -409,12 +406,12 @@ Options for Composite Solvers (start with a partial solve of one solve, then fin end """ - struct ChainSolverOptions{TB,TS<:Union{ExternalSolverOptions,PolyAlgorithmOptions}} <:PolyAlgorithmOptions + struct ChainSolverOptions <:PolyAlgorithmOptions Options for Chain Solvers (try one solver, if it doesn't converge, try another) # Fields -- `solvers::AbstractArray{TS} = [ +- `solvers::AbstractArray{SolverOptionsType} = [ NLsolveOptions(; algorithm=:anderson, atol=1e-12), MinpackOptions(; atol=1e-12), NonlinearSolveOptions(; @@ -423,7 +420,7 @@ Options for Chain Solvers (try one solver, if it doesn't converge, try another) additional_kwargs=(; autodiff=SimpleNonlinearSolve.AutoForwardDiff()), ), ] : Vector of solver options to use. -- `converged::AbstractArray{TB} = [false]` : flag to track if convergence took place. +- `converged::AbstractArray{Bool} = [false]` : flag to track if convergence took place. """ @kwdef struct ChainSolverOptions{ TB,TI,TS<:Union{ExternalSolverOptions,PolyAlgorithmOptions} @@ -482,14 +479,14 @@ end # ELLIPTIC GRID SOLVER TYPES # #---------------------------------# """ - struct SLORGridSolverOptions{TB,TF,TI} <: GridSolverOptionsType + struct SLORGridSolverOptions <: GridSolverOptionsType Options for SLOR (successive line over relaxation) elliptic grid solver. # Fields -- `iteration_limit::TI = 100` : maximum number of iterations -- `atol::TF = 1e-9` : absolute convergence tolerance -- `converged::AbstractArray{TB} = [false] +- `iteration_limit::Int = 100` : maximum number of iterations +- `atol::Float = 1e-9` : absolute convergence tolerance +- `converged::AbstractArray{Bool}` = [false] """ @kwdef struct SLORGridSolverOptions{TB,TF,TI} <: GridSolverOptionsType iteration_limit::TI = 200 @@ -499,16 +496,16 @@ Options for SLOR (successive line over relaxation) elliptic grid solver. end """ - struct GridSolverOptions{TB,TF,TI,TSym} <: GridSolverOptionsType + struct GridSolverOptions <: GridSolverOptionsType Options for SLOR + Newton elliptic grid solver. # Fields -- `iteration_limit::TI = 10` : maximum number of iterations -- `atol::TF = 1e-14` : absolute convergence tolerance -- `algorithm::TSym = :newton` : algorithm to use in NLsolve.jl -- `autodiff::TSym = :forward` : differentiation method to use in NLsolve.jl -- `converged::AbstractArray{TB}` = [false] +- `iteration_limit::Int = 10` : maximum number of iterations +- `atol::Float = 1e-14` : absolute convergence tolerance +- `algorithm::Symbol = :newton` : algorithm to use in NLsolve.jl +- `autodiff::Symbol = :forward` : differentiation method to use in NLsolve.jl +- `converged::AbstractArray{Bool}` = [false] """ @kwdef struct GridSolverOptions{TB,TF,TI,TSym} <: GridSolverOptionsType iteration_limit::TI = 20 @@ -524,45 +521,34 @@ end #---------------------------------# """ - struct Options{ - TB, - TBwo, - TF, - TI, - TSf, - TSt, - Tin, - TIo<:IntegrationOptions, - TSo<:SolverOptionsType, - WS<:GridSolverOptionsType, - } + struct Options Type containing (nearly) all the available user options. # Fields ## General Options -- `verbose::TB = false` : flag to print verbose statements -- `silence_warnings::TB = true` : flag to silence warnings -- `multipoint_index::TI = [1]` : holds current index of multi-point solver (no need for user to change this usually) +- `verbose::Bool = false` : flag to print verbose statements +- `silence_warnings::Bool = true` : flag to silence warnings +- `multipoint_index::Int = [1]` : holds current index of multi-point solver (no need for user to change this usually) ## Pre-processing Options -### Geometry ee-interpolation and generation options : -- `finterp::Tin = FLOWMath.akima` : interpolation method used for re-paneling bodies -- `autoshiftduct::TB = true` : flag as to whether duct geometry should be shifted based on rotor tip location -- `lu_decomp_flag::TB = false` : flag indicating if panel method LHS matrix factorization was successful +### Geometry interpolation and generation options : +- `finterp::Interplation Method = FLOWMath.akima` : interpolation method used for re-paneling bodies +- `autoshiftduct::Bool = true` : flag as to whether duct geometry should be shifted based on rotor tip location +- `lu_decomp_flag::Bool = false` : flag indicating if panel method LHS matrix factorization was successful ### paneling options -- `itcpshift::TF = 0.05` : factor for internal trailing edge psuedo-panel placement (default is DFDC hard-coded value) -- `axistol::TF = 1e-15` : tolerance for how close the the axis of rotation should be considered on the axis -- `tegaptol::TF = 1e1 * eps()` : tolerance for how large of a trailing edge gap should be considered a gap +- `itcpshift::Float = 0.05` : factor for internal trailing edge psuedo-panel placement (default is DFDC hard-coded value) +- `axistol::Float = 1e-15` : tolerance for how close the the axis of rotation should be considered on the axis +- `tegaptol::Float = 1e1 * eps()` : tolerance for how large of a trailing edge gap should be considered a gap ## Integration Options -- `integration_options::TIo = IntegrationOptions()` : integration options +- `integration_options::IntegrationOptions type = IntegrationOptions()` : integration options ## Post-processing Options -- `write_outputs::TBwo = [false]` : Bool for whether to write the outputs of the analysis to an external file (slow) -- `outfile::TSf = ["outputs.jl"]` : External output file name (including path information) for files to write -- `checkoutfileexists::TB = false` : Flag for whether to check if file exists before overwriting -- `output_tuple_name::TSt = ["outs"]` : variable name for named tuple written to out file +- `write_outputs::AbstractArray{Bool} = [false]` : Bool for whether to write the outputs of the analysis to an external file (slow) +- `outfile::AbstractArray{String} = ["outputs.jl"]` : External output file name (including path information) for files to write +- `checkoutfileexists::Bool = false` : Flag for whether to check if file exists before overwriting +- `output_tuple_name::AbstractArray{String} = ["outs"]` : variable name for named tuple written to out file ## Solving Options -- `grid_solver_options::WS = GridSolverOptions()` : elliptic grid solver options -- `solver_options::TSo = ChainSolverOptions()` : solver options +- `grid_solver_options::GridSolverOptionsType = GridSolverOptions()` : elliptic grid solver options +- `solver_options::SolverOptionsType = ChainSolverOptions()` : solver options """ @kwdef struct Options{ TB,