Skip to content

Conversation

@jtgrasb
Copy link
Contributor

@jtgrasb jtgrasb commented Jul 5, 2022

This PR is meant to add more checks to the user inputs to WEC-Sim. Property validation is added to WEC-Sim objects to restrict input variables by size, type, and other validation functions.

Outside of the property validation itself, some other notes/inclusions in this PR:

  • Doesn’t affect documentation
  • Changes string property label in API to char array because strings and character arrays are different in MATLAB and we use character arrays as defaults (although the input also accepts strings and converts them to character arrays)
  • Changes waves.height and waves.period from ‘NOT DEFINED’ to [] in order to add a validation to ensure the properties are non-negative. Also changes functions in the wave class to account for the new syntax.
  • Adds checkInputs() function to each class in order to check the variables within the structures and perform more specific checks (which cause documentation to fail when done as property validation)
  • Changes cable.length to cable.cableLength because it causes errors with property validation due to length being a function in MATLAB (will need to be updated in WEC-Sim Applications as well)

@kmruehl kmruehl added the SCM source code mangagement and warnings label Jul 6, 2022
@kmruehl kmruehl requested a review from nathanmtom July 6, 2022 14:48
'threshold', 1) % (`structure`) Defines the passive yaw mplementation. ``option`` (`integer`) Flag for passive yaw calculation, Options: 0 (off), 1 (on). Default = ``0``. ``threshold`` (`float`) Yaw position threshold (in degrees) above which excitation coefficients will be interpolated in passive yaw. Default = ``1`` [deg].
centerBuoyancy (:,1) double = [] % (`3x1 float vector`) Body center of buoyancy [m]. Defined in the following format [x y z]. For hydrodynamic bodies this is defined in the h5 file while for nonhydrodynamic bodies this is defined by the user. Default = ``[]``.
centerGravity (:,1) double = [] % (`3x1 float vector`) Body center of gravity [m]. Defined in the following format [x y z]. For hydrodynamic bodies this is defined in the h5 file while for nonhydrodynamic bodies this is defined by the user. Default = ``[]``.
dof (1,1) double {mustBeNonnegative, mustBeInteger} = 6 % (`integer`) Number of degree of freedoms (DOFs). For hydrodynamic bodies this is given in the h5 file. If not defined in the h5 file, Default = ``6``.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jtgrasb This is interesting as I would have expected that if you wrote i = 1 that MATLAB would have assigned it as an integer but it is a float and if you use the isinteger function within MATLAB it will return a 0 logical. Therefore, in the % comment should we change this to float or double to be consistent with what the property validation is actually checking for? What is written the checkinputs is looking for a (1,1) double not a (1,1) integer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nathanmtom I had not checked the fact that it isn't actually considered an integer type by MATLAB - that is interesting. In this case (for body.dof), the mustBeInteger function checks the value to ensure its an integer (even though the type is double). Personally, I think leaving it as integer here provides more info to the user even though its not entirely accurate for variable type. Similarly, I left the term 'float' in the comments as I felt like that was a more common term vs. double is more obscure (although more technically correct). Let me know what you think -- I am open to suggestions here.

cicEndTime (1,:) double {mustBeScalarOrEmpty} = 60 % (`float`) Convolution integral time. Default = ``60`` s
domainSize (1,1) double {mustBePositive} = 200 % (`float`) Size of free surface and seabed. This variable is only used for visualization. Default = ``200`` m
explorer (1,:) char = 'on' % (`char array`) SimMechanics Explorer 'on' or 'off'. Default = ``'on'``
dt (1,1) double {mustBePositive} = 0.1 % (`float`) Simulation time step. Default = ``0.1`` s

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jtgrasb I wanted to verify order of operations in checking the inputs. For dt it appears that MATLAB first checks the (1,1) double before checking {mustBePositive}. Therefore, if I input simu.dt = [-0.1, -0.1] the error will mention the vector needs to be a scale but will not additionally mention the variable needs to be positive. No change is required, but thought this would be relevant to clarify.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nathanmtom That's a good point. Do you think this should be mentioned in documentation somewhere?

saveText (1,1) double = 0 % (`integer`) Flag to save results as ASCII files, Options: 0 (off), 1 (on). Default = ``0``
saveWorkspace (1,1) double = 1 % (`integer`) Flag to save .mat file for each run, Options: 0 (off), 1 (on). Default = ``1``
simMechanicsFile (1,:) char = 'NOT DEFINED' % (`char array`) Simulink/SimMechanics model file. Default = ``'NOT DEFINED'``
solver (1,:) char = 'ode4' % (`char array`) PDE solver used by the Simulink/SimMechanics simulation. Any continuous solver in Simulink possible. Recommended to use 'ode4, 'ode45' for WEC-Sim. Default = ``'ode4'``

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jtgrasb I have been spot checking the "checks", but when I write simu.solver = 1 the checkinputs does not seem to catch this and the error that pops up basically says this is not a valid solver. Therefore, in my opinion it does not seem to be catching this case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nathanmtom It seems the char specification tries to convert the number to a char array, which leads to just an empty char. I am adding a check in simu.checkInputs to ensure the solver is one of Simulink's solvers.

largeXYDisplacement (1,1) struct = struct(... %
'option', 0) %
linearDamping double = zeros(6) % (`6x6 float matrix`) Defines linear damping coefficient matrix. Default = ``zeros(6)``.
mass (1,:) = [] % (`float`) Translational inertia or mass [kg]. Defined by the user or specify 'equilibrium' to set the mass equal to the fluid density times displaced volume. Default = ``[]``.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jtgrasb Another spot check, but if I update the OSWEC example with body(1).mass = [1,1] the simulation runs and errors out at a different point rather than in checking the input file. I realize this is difficult because this variable is either a double or a char array and cover both is challenging. Since the error was caught later this probably is a minor comment, but raises a separate question if we could convert equilibrium to say -1, and so we can keep mass as a (1,1) double and in the code.

Copy link
Contributor Author

@jtgrasb jtgrasb Jul 20, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nathanmtom Yes, covering both is challenging, but changing equilibrium to -1 could be a potential solution. I'll also look into adding a check in the checkInputs.

'rotationMatrix', []) % (`structure`) Defines the orientation axis of the pto. ``z`` (`3x1 float vector`) defines the direciton of the Z-coordinate of the pto, Default = [``0 0 1``]. ``y`` (`3x1 float vector`) defines the direciton of the Y-coordinate of the pto, Default = [``0 1 0``]. ``x`` (`3x1 float vector`) internally calculated vector defining the direction of the X-coordinate for the pto, Default = ``[]``. ``rotationMatrix`` (`3x3 float matrix`) internally calculated rotation matrix to go from standard coordinate orientation to the pto coordinate orientation, Default = ``[]``.
pretension = 0 % (`float`) Linear PTO pretension, N or N-m. Default = `0`.
stiffness = 0 % (`float`) Linear PTO stiffness coefficient. Default = `0`.
damping (1,:) double {mustBeNonnegative} = 0 % (`float`) Linear PTO damping coefficient. Default = `0`.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jtgrasb I believe the size of the damping variable should be (1,1), I just tired with a (1,2) and it passed this session but crashed in Simulink.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nathanmtom The damping, stiffness, waves.height, and waves.stiffness are all part of our MCR workflow which allows users to enter vectors for these variables. If I restrict the size to (1,1), it causes errors with this MCR workflow.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jtgrasb Thanks for the clarification, that makes sense.

@nathanmtom
Copy link

@jtgrasb Thank you for starting this pull request and after my initial review this PR should help users identify issues with the wecSimInputFile.m much quicker. From my preliminary review, I do see many of the variable checks working as expected, while I did work with trying to break the OSWEC Example wecSimInputFile.m and noticed some of the checks you have implemented did not work as desired and have left comments on those I caught. There are a lot of cases to check and we do not have one WEC-Sim model that you can easily check all of the cases quickly, but perhaps we ensure that all of the checks work with the OSWEC and RM3 examples first.

@jtgrasb
Copy link
Contributor Author

jtgrasb commented Jul 20, 2022

@nathanmtom Thanks for all the comments -- they have been helpful to identify areas to improve the PR. There are definitely a lot of cases to check -- I tried to do my best to check where I expected difficulties, but clearly missed a few. I also ran the WEC-Sim Applications tests, which helped me catch some more errors and are all passing now.

@kmruehl kmruehl self-requested a review August 3, 2022 14:36
@jtgrasb
Copy link
Contributor Author

jtgrasb commented Aug 3, 2022

I was doing a bit more testing of some of the validations and came across some unintended issues where the validation was converting things such as character arrays to doubles instead of restricting the input types. This thread gives the details on a similar issue and why it occurs: https://www.mathworks.com/matlabcentral/answers/504887-checking-datatype-instead-typecast-at-property-or-argument-validation
I'm going to update some of the validation to restrict variable types rather than making strange conversions and make pushes today and/or tomorrow.

@jtgrasb
Copy link
Contributor Author

jtgrasb commented Aug 4, 2022

@nathanmtom @kmruehl I've made some updates to this PR:

  • Changed validation to restrict certain data types such as using mustBeNumeric to only accept numeric inputs rather than converting all inputs to doubles
    • Also removes conflicting variable types for validation vs. documentation (somewhat - float is still not technically a variable type in MATLAB, but mustBeNumeric accepts double, single, unit8, etc.)
    • Since the validation no longer specifies char, it may also be beneficial to change the documentation back to string as that may be more intuitive?
  • Changed default name of body class, mcrMatFile, mcrExcelFile to empty character array to allow for use of mustBeText
  • Changed body.mass to allow only doubles and character arrays
    • This restricts uint8 and strings though instead of converting them - maybe I should do this manually?
  • Moved boolean/mustBeMember checks into the validation lines
  • Removed restriction on body.dof to allow for generalized body modes (>6 dof)

Let me know what you guys think about these updates/potential issues.

@nathanmtom
Copy link

@jtgrasb Thank you for all of the updates related to this PR, understandable that there are a lot of potential combinations to check for and generalize. After reviewing all of the latest updates, I have no major comments but responded below to a few of your questions.

  • I think it is fine to define as a float since it indicates the number can have a decimal point which is how we are defining a general number against an integer.
  • I do think that switching back to string definition makes sense as MATLAB's definition of a string is a 1 x n sequence of characters which I believe is how we define all text inputs. This would be the only edit that I think should be implemented.
  • In terms of body.mass we only have the equilibrium option to worry about as a character, so as long as the check is working now then we shouldn't need to modify. That is why I had suggested converting to having the equilibrium condition be -1, but it could be any negative number and rather than comparing a string. I believe WAMIT does something similar with the input files for using a negative number to define the deep water condition.

Since this PR is not affecting the dynamic simulation portion of WEC-Sim, I am in favor of making the string change and then pulling into the development branch. As mentioned earlier, there are a lot of different input combinations that might break some of these checks and we will not be able to check for all of them now.

I'll wait for @kmruehl to provide any comments if they would prefer to wait before merging.

@jtgrasb
Copy link
Contributor Author

jtgrasb commented Aug 24, 2022

@nathanmtom Thanks for the suggestions! I changed "char array" back to "string" for the documentation and also added string as a valid input type for the mass (accepts both "equilibrium" and 'equilibrium').

@kmruehl kmruehl removed their request for review August 24, 2022 14:28
@jtgrasb
Copy link
Contributor Author

jtgrasb commented Aug 24, 2022

Just wanted to update. I am getting this same documentation error when I try to build locally. Not sure of the exact cause.

@jtgrasb
Copy link
Contributor Author

jtgrasb commented Aug 24, 2022

The documentation errors have been fixed and it is working locally. It seems to only "fail" here due to a warning.

@kmruehl
Copy link
Collaborator

kmruehl commented Aug 25, 2022

@jtgrasb thank you. I'll go ahead and merge this. I think we should remove the fail on warnings for docs.

@kmruehl kmruehl merged commit 4ffad89 into WEC-Sim:dev Aug 25, 2022
@kmruehl kmruehl self-assigned this Aug 25, 2022
@jtgrasb jtgrasb deleted the PropertyValidation branch September 6, 2022 18:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

SCM source code mangagement and warnings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants