diff --git a/docs/src/DuctAPE/advanced_usage/outputs.md b/docs/src/DuctAPE/advanced_usage/outputs.md index 64831a34..21a8dd4c 100644 --- a/docs/src/DuctAPE/advanced_usage/outputs.md +++ b/docs/src/DuctAPE/advanced_usage/outputs.md @@ -22,5 +22,5 @@ Sometimes, it may be desireable to return the pre-process objects, including: In this case, we can use the `return_inputs` keyword argument when calling the `analyze` function to return a named tuple containing those pre-process objects. ```julia -outs, ins, success_flag = dt.analyze(ducted_rotor; return_inputs=true) +outs, ins, success_flag = dt.analyze(ducted_rotor, operating_point, reference_parameters; return_inputs=true) ``` diff --git a/docs/src/DuctAPE/advanced_usage/precompilation.md b/docs/src/DuctAPE/advanced_usage/precompilation.md index bcfa8b36..2614b261 100644 --- a/docs/src/DuctAPE/advanced_usage/precompilation.md +++ b/docs/src/DuctAPE/advanced_usage/precompilation.md @@ -78,5 +78,7 @@ The precompiled caches can be passed in via keyword arguments to the analysis fu ```@docs; canonical=false DuctAPE.analyze( ducted_rotor::DuctedRotor, + operating_point::OperatingPoint, + reference_parameters::ReferenceParameters, options::Options=set_options()) ``` diff --git a/docs/src/DuctAPE/api/private_utilities.md b/docs/src/DuctAPE/api/private_utilities.md index e0371658..52a80ef9 100644 --- a/docs/src/DuctAPE/api/private_utilities.md +++ b/docs/src/DuctAPE/api/private_utilities.md @@ -1,7 +1,6 @@ ## Utility Functions ```@docs DuctAPE.promote_ducted_rotor_type -DuctAPE.update_operating_point! DuctAPE.isscalar DuctAPE.dot DuctAPE.norm diff --git a/docs/src/DuctAPE/api/public_api.md b/docs/src/DuctAPE/api/public_api.md index 060613c0..3be70f40 100644 --- a/docs/src/DuctAPE/api/public_api.md +++ b/docs/src/DuctAPE/api/public_api.md @@ -7,10 +7,10 @@ Depth = 5 ## Input Types ```@docs -DuctAPE.DuctedRotor +DuctAPE.PanelingConstants DuctAPE.Rotor +DuctAPE.DuctedRotor DuctAPE.OperatingPoint -DuctAPE.PanelingConstants DuctAPE.ReferenceParameters ``` diff --git a/docs/src/DuctAPE/tutorial.md b/docs/src/DuctAPE/tutorial.md index 49c3dbcc..70c88b36 100644 --- a/docs/src/DuctAPE/tutorial.md +++ b/docs/src/DuctAPE/tutorial.md @@ -282,30 +282,6 @@ plot!( # hide In addition there are untested cascade types with similar structure to CCBlades airfoil types called `DTCascade`. Furthermore, there is an experimental actuator disk model implemented via the `ADM` airfoil type in C4Blade. -### Operating Point - -Next we will assemble the operating point which contains information about the freestream as well as the rotor rotation rate(s). - -```@docs; canonical=false -DuctAPE.OperatingPoint -``` - -```@example tutorial -# Freestream -Vinf = 0.0 # hover condition -rhoinf = 1.226 -asound = 340.0 -muinf = 1.78e-5 - -# Rotation Rate -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 = 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. @@ -345,6 +321,44 @@ paneling_constants = DuctAPE.PanelingConstants( ) nothing # hide ``` +### Assembling the DuctedRotor + +We are now posed to construct the `DuctedRotor` input type. + +```@example tutorial +# assemble ducted_rotor object +ducted_rotor = DuctAPE.DuctedRotor( + duct_coordinates, + centerbody_coordinates, + rotor, + paneling_constants, +) +nothing # hide +``` + +### Operating Point + +Next we will assemble the operating point which contains information about the freestream as well as the rotor rotation rate(s). + +```@docs; canonical=false +DuctAPE.OperatingPoint +``` + +```@example tutorial +# Freestream +Vinf = 0.0 # hover condition +rhoinf = 1.226 +asound = 340.0 +muinf = 1.78e-5 + +# Rotation Rate +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 = DuctAPE.OperatingPoint(Vinf, rhoinf, muinf, asound, Omega) +nothing # hide +``` ### Reference Parameters @@ -366,22 +380,6 @@ reference_parameters = DuctAPE.ReferenceParameters([Vref], [Rref]) nothing # hide ``` -### Assembling the DuctedRotor - -We are now posed to construct the `DuctedRotor` input type. - -```@example tutorial -# assemble ducted_rotor object -ducted_rotor = DuctAPE.DuctedRotor( - duct_coordinates, - centerbody_coordinates, - rotor, - operating_point, - paneling_constants, - reference_parameters, -) -nothing # hide -``` ## Set Options @@ -403,11 +401,11 @@ With the ducted_rotor input build, and the options selected, we are now ready to This is done simply with the `analyze` function which dispatches the appropriate analysis, solve, and post-processing functions based on the selected options. ```@docs; canonical=false -DuctAPE.analyze(::DuctAPE.DuctedRotor, ::DuctAPE.Options) +DuctAPE.analyze(::DuctAPE.DuctedRotor, ::DuctAPE.OperatingPoint, ::DuctAPE.ReferenceParameters, ::DuctAPE.Options) ``` ```@example tutorial -outs, success_flag = DuctAPE.analyze(ducted_rotor, options) +outs, success_flag = DuctAPE.analyze(ducted_rotor, operating_point, reference_parameters, options) nothing # hide ``` @@ -429,7 +427,7 @@ outs.totals.CQ 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},ducted_rotor::DuctedRotor,options::Options) where TO<:OperatingPoint +DuctAPE.analyze(ducted_rotor::DuctedRotor,operating_point::AbstractVector{TO},reference_parameters::ReferenceParameters,options::Options) where TO<:OperatingPoint ``` Running a multi-point analysis on the example geometry given there, it might look something like this: @@ -444,13 +442,13 @@ n = RPM / 60.0 # rotation rate in revolutions per second Vinfs = Js * n * D # - Set Operating Points - # -ops = [deepcopy(operating_point) for i in 1:length(Vinfs)] +operating_points = [deepcopy(operating_point) for i in 1:length(Vinfs)] for (iv, v) in enumerate(Vinfs) - ops[iv].Vinf[] = v + operating_points[iv].Vinf[] = v end # - Run Multi-point Analysis - # -outs_vec, success_flags = DuctAPE.analyze(ops, ducted_rotor, DuctAPE.set_options(ops)) +outs_vec, success_flags = DuctAPE.analyze(ducted_rotor, operating_points, reference_parameters, DuctAPE.set_options(operating_points)) nothing #hide ``` @@ -516,6 +514,7 @@ nothing #hide And then we can plot the data to compare DFDC and DuctAPE. ```@example tutorial +using Plots # set up efficiency plot pe = plot(; xlabel="Advance Ratio", ylabel="Efficiency") diff --git a/src/analysis/setup.jl b/src/analysis/setup.jl index 063d00d9..fcfeda1c 100644 --- a/src/analysis/setup.jl +++ b/src/analysis/setup.jl @@ -117,8 +117,8 @@ function setup_analysis( ) # copy over operating point - for f in fieldnames(typeof(ducted_rotor.operating_point)) - solve_parameter_tuple.operating_point[f] .= getfield(ducted_rotor.operating_point, f) + for f in fieldnames(typeof(operating_point)) + solve_parameter_tuple.operating_point[f] .= getfield(operating_point, f) end ##### ----- PERFORM PREPROCESSING COMPUTATIONS ----- ##### @@ -134,6 +134,7 @@ function setup_analysis( solve_parameter_tuple.linsys, solve_parameter_tuple.wakeK, ducted_rotor, + operating_point, prepost_containers, problem_dimensions; grid_solver_options=options.grid_solver_options, diff --git a/src/preprocess/preprocess.jl b/src/preprocess/preprocess.jl index a135d80a..0cd93924 100644 --- a/src/preprocess/preprocess.jl +++ b/src/preprocess/preprocess.jl @@ -1129,7 +1129,8 @@ end """ precompute_parameters( - ducted_rotor; + ducted_rotor, + operating_point; grid_solver_options=GridSolverOptions(), integration_options=IntegrationOptions(), autoshiftduct=true, @@ -1144,7 +1145,8 @@ end Out of place main pre-processing function that computes all the required parameters for the solve. # Arguments -- `ducted_rotor::DuctedRotor` : A Propuslor object +- `ducted_rotor::DuctedRotor` : A DuctedRotor object +- `operating_point::OperatingPoint` : A OperatingPoint object # Keyword Arguments - `grid_solver_options::GridSolverOptionsType=GridSolverOptions()` : A GridSolverOptionsType object @@ -1181,7 +1183,8 @@ Out of place main pre-processing function that computes all the required paramet - `problem_dimensions::ProblemDimensions` : A ProblemDimensions object """ function precompute_parameters( - ducted_rotor; + ducted_rotor, + operating_point; grid_solver_options=GridSolverOptions(), integration_options=IntegrationOptions(), autoshiftduct=true, @@ -1388,6 +1391,7 @@ end linsys, wakeK, ducted_rotor, + operating_point, prepost_containers, problem_dimensions; grid_solver_options=GridSolverOptions(), @@ -1410,6 +1414,7 @@ function precompute_parameters!( linsys, wakeK, ducted_rotor, + operating_point, prepost_containers, problem_dimensions; grid_solver_options=GridSolverOptions(), @@ -1429,7 +1434,6 @@ function precompute_parameters!( centerbody_coordinates, rotor, paneling_constants, - operating_point, ) = ducted_rotor # - Unpack preprocess containers - # diff --git a/src/utilities/inputs.jl b/src/utilities/inputs.jl index ce553048..f90c6590 100644 --- a/src/utilities/inputs.jl +++ b/src/utilities/inputs.jl @@ -157,7 +157,7 @@ function Rotor( end """ - DuctedRotor(duct_coordinates, centerbody_coordinates, rotor, operating_point, paneling_constants, reference_parameters) + DuctedRotor(duct_coordinates, centerbody_coordinates, rotor, paneling_constants) # Arguments @@ -169,10 +169,8 @@ end struct DuctedRotor{ Td<:AbstractMatrix, Tcb<:AbstractMatrix, - Top<:OperatingPoint, Tpc<:PanelingConstants, Trp<:Rotor, - Tref<:ReferenceParameters, } duct_coordinates::Td centerbody_coordinates::Tcb diff --git a/test/data/basic_two_rotor_for_test_NEW.jl b/test/data/basic_two_rotor_for_test_NEW.jl index c0faa045..650cb905 100644 --- a/test/data/basic_two_rotor_for_test_NEW.jl +++ b/test/data/basic_two_rotor_for_test_NEW.jl @@ -48,26 +48,5 @@ ducted_rotor = dt.DuctedRotor( duct_coordinates, centerbody_coordinates, rotor, - operating_point, paneling_constants, - reference_parameters, ) -# -# -# -# -# -# plot( -# duct_coordinates[:, 1], -# duct_coordinates[:, 2] .- 0.75; -# aspectratio=1, -# marker=true, -# label="", -# ) -# plot!(hub_coordinates[:, 1], hub_coordinates[:, 2]; marker=true, label="") - -# for i in 1:length(rotorzloc) -# plot!([rotorzloc[i], rotorzloc[i]], [Rhub, Rtip]; marker=true, label="", color=3) -# end -# plot!() - diff --git a/test/iteration_step_tests.jl b/test/iteration_step_tests.jl index 5757aec8..274e4cbb 100644 --- a/test/iteration_step_tests.jl +++ b/test/iteration_step_tests.jl @@ -25,9 +25,7 @@ println("\nITERATION STEP THROUGH TESTS") rp_duct_coordinates, rp_centerbody_coordinates, rotor, - operating_point, paneling_constants, - reference_parameters, ) options = dt.DFDC_options(; @@ -97,8 +95,8 @@ println("\nITERATION STEP THROUGH TESTS") ) # copy over operating point - for f in fieldnames(typeof(ducted_rotor.operating_point)) - solve_parameter_tuple.operating_point[f] .= getfield(ducted_rotor.operating_point, f) + for f in fieldnames(typeof(operating_point)) + solve_parameter_tuple.operating_point[f] .= getfield(operating_point, f) end # generate inputs diff --git a/test/pre_processing_tests.jl b/test/pre_processing_tests.jl index 78fe2b80..9c24eb44 100644 --- a/test/pre_processing_tests.jl +++ b/test/pre_processing_tests.jl @@ -350,7 +350,59 @@ end end @testset "Rotor/Wake Aero Initialization" begin - include("data/basic_two_rotor_for_test_NEW.jl") +r1 = [0.25; 0.5; 0.75; 1.0] +Rtip = [1.0, 1.0] +rnondim1 = r1 ./ Rtip[1] +rnondim = [rnondim1 rnondim1] +afparams1 = dt.c4b.DFDCairfoil() +rotorzloc = [0.25, 0.75] +r = rnondim +chords = 0.1 * ones(size(rnondim)) +twists = 20.0 * pi / 180.0 * ones(size(rnondim)) +airfoils = fill(afparams1, 4, 2) +Rhub = [0.25, 0.25] +Rtip = Rtip +tip_gap = [0.0, 0.0] +B = [2, 4] +fliplift = [0.0, 0.0] + +rotor = dt.Rotor( + B, rotorzloc, r, Rhub, Rtip, chords, twists, tip_gap, airfoils, fliplift +) + +ncenterbody_inlet = 1 +nduct_inlet = 1 +nwake_sheets = 3 +wake_length = 1.0 +npanels = [2, 1, 4] +dte_minus_cbte = 0 + +paneling_constants = dt.PanelingConstants( + nduct_inlet, ncenterbody_inlet, npanels, dte_minus_cbte, nwake_sheets, wake_length +) + +Vinf = [10.0] +rhoinf = [1.226] +muinf = [1.78e-5] +asound = [340.0] +Omega = [5000.0, 0.0] * pi / 30 # convert from RPM to rad/s + +operating_point = dt.OperatingPoint(Vinf, rhoinf, muinf, asound, Omega) + +Vref = [10.0] +Rref = [Rtip] +reference_parameters = dt.ReferenceParameters(Vref, Rref) + +duct_coordinates = [1.0 2.0; 0.5 1.5; 0.0 2.0; 0.5 2.5; 1.0 2.0] +centerbody_coordinates = [0.0 0.0; 0.5 0.5; 1.0 0.0] + +ducted_rotor = dt.DuctedRotor( + duct_coordinates, + centerbody_coordinates, + rotor, + paneling_constants, +) + options = dt.set_options() # - Get Problem Dimensions - # @@ -401,8 +453,8 @@ end ) # copy over operating point - for f in fieldnames(typeof(ducted_rotor.operating_point)) - solve_parameter_tuple.operating_point[f] .= getfield(ducted_rotor.operating_point, f) + for f in fieldnames(typeof(operating_point)) + solve_parameter_tuple.operating_point[f] .= getfield(operating_point, f) end # - Do preprocessutations - # @@ -420,6 +472,7 @@ end solve_parameter_tuple.linsys, solve_parameter_tuple.wakeK, ducted_rotor, + operating_point, prepost_containers, problem_dimensions; grid_solver_options=options.grid_solver_options, @@ -512,8 +565,8 @@ end ) # copy over operating point - for f in fieldnames(typeof(ducted_rotor.operating_point)) - solve_parameter_tuple.operating_point[f] .= getfield(ducted_rotor.operating_point, f) + for f in fieldnames(typeof(operating_point)) + solve_parameter_tuple.operating_point[f] .= getfield(operating_point, f) end # - Do preprocessutations - # @@ -531,6 +584,7 @@ end solve_parameter_tuple.linsys, solve_parameter_tuple.wakeK, ducted_rotor, + operating_point, prepost_containers, problem_dimensions; grid_solver_options=options.grid_solver_options,