/* ----------------------------------------------------------------------------
 * This file was automatically generated by SWIG (http://www.swig.org).
 * Version 4.0.2
 *
 * Do not make changes to this file unless you know what you are doing--modify
 * the SWIG interface file instead.
 * ----------------------------------------------------------------------------- */

package org.opensim.modeling;

/**
 *  This class serves as a serializable ForceVelocityInverseCurve for use in<br>
 *     equilibrium muscle models. The inverse force-velocity curve is<br>
 *     dimensionless: force is normalized to maximum isometric force and velocity<br>
 *     is normalized to the maximum muscle contraction velocity (vmax), where vmax<br>
 *     is expressed in units of optimal_fiber_lengths per second. Negative<br>
 *     normalized velocities correspond to concentric contraction (i.e.,<br>
 *     shortening). The inverse force-velocity curve is constructed from 8<br>
 *     properties, which are identical to those used to construct the<br>
 *     corresponding force-velocity curve. See ForceVelocityCurve for descriptions<br>
 *     of these parameters.<br>
 * <br>
 *     <br>
 * <br>
 *     <img src=fig_ForceVelocityInverseCurve.png/><br>
 *     <br><br>
 *     <img src=fig_ForceVelocityCurve.png/><br>
 * <br>
 *     <b>Conditions</b><br>
 *     {@literal 
    1a)  0 < concentricSlopeAtVmax < 1
    1b)  concentricSlopeAtVmax < concentricSlopeNearVmax < 1
    2a)  1 < isometricSlope
    2b)  (maxEccentricVelocityForceMultiplier-1)/1 < isometricSlope
     3)  0 < eccentricSlopeAtVmax < (maxEccentricVelocityForceMultiplier-1)/1
     4)  1 < maxEccentricVelocityForceMultiplier
     5)  0 <= concentricCurviness <= 1
     6)  0 <= eccentricCurviness <= 1
    }<br>
 * <br>
 *     <b>Default Parameter Values</b><br>
 *     {@literal 
    concentricSlopeAtVmax .................. 0.1
    concentricSlopeNearVmax ................ 0.25
    isometricSlope ......................... 5.0
    eccentricSlopeAtVmax ................... 0.1
    eccentricSlopeNearVmax ................. 0.15
    maxEccentricVelocityForceMultiplier .... 1.4
    concentricCurviness .................... 0.6
    eccentricCurviness ..................... 0.9
    }<br>
 * <br>
 *     <b>Example</b><br>
 *     {@code 
        ForceVelocityInverseCurve fvInvCurve(0.1, 0.25, 5.0, 0.1, 0.15, 1.4, 0.6, 0.9);
        double fvInvVal  = fvInvCurve.calcValue(1.0);
        double dfvInvVal = fvInvCurve.calcDerivative(1.0, 1);
    }<br>
 * <br>
 *     Note that this object should be updated through the set methods provided.<br>
 *     These set methods will take care of rebuilding the curve correctly. If you<br>
 *     modify the properties directly, the curve will not be rebuilt, and upon<br>
 *     calling a function like calcValue, calcDerivative, or printCurveToCSVFile,<br>
 *     an exception will be thrown because the curve is out-of-date with its<br>
 *     properties.<br>
 * <br>
 *     @author Matt Millard
 */
public class ForceVelocityInverseCurve extends Function {
  private transient long swigCPtr;

  public ForceVelocityInverseCurve(long cPtr, boolean cMemoryOwn) {
    super(opensimSimulationJNI.ForceVelocityInverseCurve_SWIGUpcast(cPtr), cMemoryOwn);
    swigCPtr = cPtr;
  }

  public static long getCPtr(ForceVelocityInverseCurve obj) {
    return (obj == null) ? 0 : obj.swigCPtr;
  }

  @SuppressWarnings("deprecation")
  protected void finalize() {
    delete();
  }

  public synchronized void delete() {
    if (swigCPtr != 0) {
      if (swigCMemOwn) {
        swigCMemOwn = false;
        opensimSimulationJNI.delete_ForceVelocityInverseCurve(swigCPtr);
      }
      swigCPtr = 0;
    }
    super.delete();
  }

  public static ForceVelocityInverseCurve safeDownCast(OpenSimObject obj) {
    long cPtr = opensimSimulationJNI.ForceVelocityInverseCurve_safeDownCast(OpenSimObject.getCPtr(obj), obj);
    return (cPtr == 0) ? null : new ForceVelocityInverseCurve(cPtr, false);
  }

  public void assign(OpenSimObject aObject) {
    opensimSimulationJNI.ForceVelocityInverseCurve_assign(swigCPtr, this, OpenSimObject.getCPtr(aObject), aObject);
  }

  public static String getClassName() {
    return opensimSimulationJNI.ForceVelocityInverseCurve_getClassName();
  }

  public OpenSimObject clone() {
    long cPtr = opensimSimulationJNI.ForceVelocityInverseCurve_clone(swigCPtr, this);
    return (cPtr == 0) ? null : new ForceVelocityInverseCurve(cPtr, true);
  }

  public String getConcreteClassName() {
    return opensimSimulationJNI.ForceVelocityInverseCurve_getConcreteClassName(swigCPtr, this);
  }

  public void copyProperty_concentric_slope_at_vmax(ForceVelocityInverseCurve source) {
    opensimSimulationJNI.ForceVelocityInverseCurve_copyProperty_concentric_slope_at_vmax(swigCPtr, this, ForceVelocityInverseCurve.getCPtr(source), source);
  }

  public double get_concentric_slope_at_vmax(int i) {
    return opensimSimulationJNI.ForceVelocityInverseCurve_get_concentric_slope_at_vmax__SWIG_0(swigCPtr, this, i);
  }

  public SWIGTYPE_p_double upd_concentric_slope_at_vmax(int i) {
    return new SWIGTYPE_p_double(opensimSimulationJNI.ForceVelocityInverseCurve_upd_concentric_slope_at_vmax__SWIG_0(swigCPtr, this, i), false);
  }

  public void set_concentric_slope_at_vmax(int i, double value) {
    opensimSimulationJNI.ForceVelocityInverseCurve_set_concentric_slope_at_vmax__SWIG_0(swigCPtr, this, i, value);
  }

  public int append_concentric_slope_at_vmax(double value) {
    return opensimSimulationJNI.ForceVelocityInverseCurve_append_concentric_slope_at_vmax(swigCPtr, this, value);
  }

  public void constructProperty_concentric_slope_at_vmax(double initValue) {
    opensimSimulationJNI.ForceVelocityInverseCurve_constructProperty_concentric_slope_at_vmax(swigCPtr, this, initValue);
  }

  public double get_concentric_slope_at_vmax() {
    return opensimSimulationJNI.ForceVelocityInverseCurve_get_concentric_slope_at_vmax__SWIG_1(swigCPtr, this);
  }

  public SWIGTYPE_p_double upd_concentric_slope_at_vmax() {
    return new SWIGTYPE_p_double(opensimSimulationJNI.ForceVelocityInverseCurve_upd_concentric_slope_at_vmax__SWIG_1(swigCPtr, this), false);
  }

  public void set_concentric_slope_at_vmax(double value) {
    opensimSimulationJNI.ForceVelocityInverseCurve_set_concentric_slope_at_vmax__SWIG_1(swigCPtr, this, value);
  }

  public void copyProperty_concentric_slope_near_vmax(ForceVelocityInverseCurve source) {
    opensimSimulationJNI.ForceVelocityInverseCurve_copyProperty_concentric_slope_near_vmax(swigCPtr, this, ForceVelocityInverseCurve.getCPtr(source), source);
  }

  public double get_concentric_slope_near_vmax(int i) {
    return opensimSimulationJNI.ForceVelocityInverseCurve_get_concentric_slope_near_vmax__SWIG_0(swigCPtr, this, i);
  }

  public SWIGTYPE_p_double upd_concentric_slope_near_vmax(int i) {
    return new SWIGTYPE_p_double(opensimSimulationJNI.ForceVelocityInverseCurve_upd_concentric_slope_near_vmax__SWIG_0(swigCPtr, this, i), false);
  }

  public void set_concentric_slope_near_vmax(int i, double value) {
    opensimSimulationJNI.ForceVelocityInverseCurve_set_concentric_slope_near_vmax__SWIG_0(swigCPtr, this, i, value);
  }

  public int append_concentric_slope_near_vmax(double value) {
    return opensimSimulationJNI.ForceVelocityInverseCurve_append_concentric_slope_near_vmax(swigCPtr, this, value);
  }

  public void constructProperty_concentric_slope_near_vmax(double initValue) {
    opensimSimulationJNI.ForceVelocityInverseCurve_constructProperty_concentric_slope_near_vmax(swigCPtr, this, initValue);
  }

  public double get_concentric_slope_near_vmax() {
    return opensimSimulationJNI.ForceVelocityInverseCurve_get_concentric_slope_near_vmax__SWIG_1(swigCPtr, this);
  }

  public SWIGTYPE_p_double upd_concentric_slope_near_vmax() {
    return new SWIGTYPE_p_double(opensimSimulationJNI.ForceVelocityInverseCurve_upd_concentric_slope_near_vmax__SWIG_1(swigCPtr, this), false);
  }

  public void set_concentric_slope_near_vmax(double value) {
    opensimSimulationJNI.ForceVelocityInverseCurve_set_concentric_slope_near_vmax__SWIG_1(swigCPtr, this, value);
  }

  public void copyProperty_isometric_slope(ForceVelocityInverseCurve source) {
    opensimSimulationJNI.ForceVelocityInverseCurve_copyProperty_isometric_slope(swigCPtr, this, ForceVelocityInverseCurve.getCPtr(source), source);
  }

  public double get_isometric_slope(int i) {
    return opensimSimulationJNI.ForceVelocityInverseCurve_get_isometric_slope__SWIG_0(swigCPtr, this, i);
  }

  public SWIGTYPE_p_double upd_isometric_slope(int i) {
    return new SWIGTYPE_p_double(opensimSimulationJNI.ForceVelocityInverseCurve_upd_isometric_slope__SWIG_0(swigCPtr, this, i), false);
  }

  public void set_isometric_slope(int i, double value) {
    opensimSimulationJNI.ForceVelocityInverseCurve_set_isometric_slope__SWIG_0(swigCPtr, this, i, value);
  }

  public int append_isometric_slope(double value) {
    return opensimSimulationJNI.ForceVelocityInverseCurve_append_isometric_slope(swigCPtr, this, value);
  }

  public void constructProperty_isometric_slope(double initValue) {
    opensimSimulationJNI.ForceVelocityInverseCurve_constructProperty_isometric_slope(swigCPtr, this, initValue);
  }

  public double get_isometric_slope() {
    return opensimSimulationJNI.ForceVelocityInverseCurve_get_isometric_slope__SWIG_1(swigCPtr, this);
  }

  public SWIGTYPE_p_double upd_isometric_slope() {
    return new SWIGTYPE_p_double(opensimSimulationJNI.ForceVelocityInverseCurve_upd_isometric_slope__SWIG_1(swigCPtr, this), false);
  }

  public void set_isometric_slope(double value) {
    opensimSimulationJNI.ForceVelocityInverseCurve_set_isometric_slope__SWIG_1(swigCPtr, this, value);
  }

  public void copyProperty_eccentric_slope_at_vmax(ForceVelocityInverseCurve source) {
    opensimSimulationJNI.ForceVelocityInverseCurve_copyProperty_eccentric_slope_at_vmax(swigCPtr, this, ForceVelocityInverseCurve.getCPtr(source), source);
  }

  public double get_eccentric_slope_at_vmax(int i) {
    return opensimSimulationJNI.ForceVelocityInverseCurve_get_eccentric_slope_at_vmax__SWIG_0(swigCPtr, this, i);
  }

  public SWIGTYPE_p_double upd_eccentric_slope_at_vmax(int i) {
    return new SWIGTYPE_p_double(opensimSimulationJNI.ForceVelocityInverseCurve_upd_eccentric_slope_at_vmax__SWIG_0(swigCPtr, this, i), false);
  }

  public void set_eccentric_slope_at_vmax(int i, double value) {
    opensimSimulationJNI.ForceVelocityInverseCurve_set_eccentric_slope_at_vmax__SWIG_0(swigCPtr, this, i, value);
  }

  public int append_eccentric_slope_at_vmax(double value) {
    return opensimSimulationJNI.ForceVelocityInverseCurve_append_eccentric_slope_at_vmax(swigCPtr, this, value);
  }

  public void constructProperty_eccentric_slope_at_vmax(double initValue) {
    opensimSimulationJNI.ForceVelocityInverseCurve_constructProperty_eccentric_slope_at_vmax(swigCPtr, this, initValue);
  }

  public double get_eccentric_slope_at_vmax() {
    return opensimSimulationJNI.ForceVelocityInverseCurve_get_eccentric_slope_at_vmax__SWIG_1(swigCPtr, this);
  }

  public SWIGTYPE_p_double upd_eccentric_slope_at_vmax() {
    return new SWIGTYPE_p_double(opensimSimulationJNI.ForceVelocityInverseCurve_upd_eccentric_slope_at_vmax__SWIG_1(swigCPtr, this), false);
  }

  public void set_eccentric_slope_at_vmax(double value) {
    opensimSimulationJNI.ForceVelocityInverseCurve_set_eccentric_slope_at_vmax__SWIG_1(swigCPtr, this, value);
  }

  public void copyProperty_eccentric_slope_near_vmax(ForceVelocityInverseCurve source) {
    opensimSimulationJNI.ForceVelocityInverseCurve_copyProperty_eccentric_slope_near_vmax(swigCPtr, this, ForceVelocityInverseCurve.getCPtr(source), source);
  }

  public double get_eccentric_slope_near_vmax(int i) {
    return opensimSimulationJNI.ForceVelocityInverseCurve_get_eccentric_slope_near_vmax__SWIG_0(swigCPtr, this, i);
  }

  public SWIGTYPE_p_double upd_eccentric_slope_near_vmax(int i) {
    return new SWIGTYPE_p_double(opensimSimulationJNI.ForceVelocityInverseCurve_upd_eccentric_slope_near_vmax__SWIG_0(swigCPtr, this, i), false);
  }

  public void set_eccentric_slope_near_vmax(int i, double value) {
    opensimSimulationJNI.ForceVelocityInverseCurve_set_eccentric_slope_near_vmax__SWIG_0(swigCPtr, this, i, value);
  }

  public int append_eccentric_slope_near_vmax(double value) {
    return opensimSimulationJNI.ForceVelocityInverseCurve_append_eccentric_slope_near_vmax(swigCPtr, this, value);
  }

  public void constructProperty_eccentric_slope_near_vmax(double initValue) {
    opensimSimulationJNI.ForceVelocityInverseCurve_constructProperty_eccentric_slope_near_vmax(swigCPtr, this, initValue);
  }

  public double get_eccentric_slope_near_vmax() {
    return opensimSimulationJNI.ForceVelocityInverseCurve_get_eccentric_slope_near_vmax__SWIG_1(swigCPtr, this);
  }

  public SWIGTYPE_p_double upd_eccentric_slope_near_vmax() {
    return new SWIGTYPE_p_double(opensimSimulationJNI.ForceVelocityInverseCurve_upd_eccentric_slope_near_vmax__SWIG_1(swigCPtr, this), false);
  }

  public void set_eccentric_slope_near_vmax(double value) {
    opensimSimulationJNI.ForceVelocityInverseCurve_set_eccentric_slope_near_vmax__SWIG_1(swigCPtr, this, value);
  }

  public void copyProperty_max_eccentric_velocity_force_multiplier(ForceVelocityInverseCurve source) {
    opensimSimulationJNI.ForceVelocityInverseCurve_copyProperty_max_eccentric_velocity_force_multiplier(swigCPtr, this, ForceVelocityInverseCurve.getCPtr(source), source);
  }

  public double get_max_eccentric_velocity_force_multiplier(int i) {
    return opensimSimulationJNI.ForceVelocityInverseCurve_get_max_eccentric_velocity_force_multiplier__SWIG_0(swigCPtr, this, i);
  }

  public SWIGTYPE_p_double upd_max_eccentric_velocity_force_multiplier(int i) {
    return new SWIGTYPE_p_double(opensimSimulationJNI.ForceVelocityInverseCurve_upd_max_eccentric_velocity_force_multiplier__SWIG_0(swigCPtr, this, i), false);
  }

  public void set_max_eccentric_velocity_force_multiplier(int i, double value) {
    opensimSimulationJNI.ForceVelocityInverseCurve_set_max_eccentric_velocity_force_multiplier__SWIG_0(swigCPtr, this, i, value);
  }

  public int append_max_eccentric_velocity_force_multiplier(double value) {
    return opensimSimulationJNI.ForceVelocityInverseCurve_append_max_eccentric_velocity_force_multiplier(swigCPtr, this, value);
  }

  public void constructProperty_max_eccentric_velocity_force_multiplier(double initValue) {
    opensimSimulationJNI.ForceVelocityInverseCurve_constructProperty_max_eccentric_velocity_force_multiplier(swigCPtr, this, initValue);
  }

  public double get_max_eccentric_velocity_force_multiplier() {
    return opensimSimulationJNI.ForceVelocityInverseCurve_get_max_eccentric_velocity_force_multiplier__SWIG_1(swigCPtr, this);
  }

  public SWIGTYPE_p_double upd_max_eccentric_velocity_force_multiplier() {
    return new SWIGTYPE_p_double(opensimSimulationJNI.ForceVelocityInverseCurve_upd_max_eccentric_velocity_force_multiplier__SWIG_1(swigCPtr, this), false);
  }

  public void set_max_eccentric_velocity_force_multiplier(double value) {
    opensimSimulationJNI.ForceVelocityInverseCurve_set_max_eccentric_velocity_force_multiplier__SWIG_1(swigCPtr, this, value);
  }

  public void copyProperty_concentric_curviness(ForceVelocityInverseCurve source) {
    opensimSimulationJNI.ForceVelocityInverseCurve_copyProperty_concentric_curviness(swigCPtr, this, ForceVelocityInverseCurve.getCPtr(source), source);
  }

  public double get_concentric_curviness(int i) {
    return opensimSimulationJNI.ForceVelocityInverseCurve_get_concentric_curviness__SWIG_0(swigCPtr, this, i);
  }

  public SWIGTYPE_p_double upd_concentric_curviness(int i) {
    return new SWIGTYPE_p_double(opensimSimulationJNI.ForceVelocityInverseCurve_upd_concentric_curviness__SWIG_0(swigCPtr, this, i), false);
  }

  public void set_concentric_curviness(int i, double value) {
    opensimSimulationJNI.ForceVelocityInverseCurve_set_concentric_curviness__SWIG_0(swigCPtr, this, i, value);
  }

  public int append_concentric_curviness(double value) {
    return opensimSimulationJNI.ForceVelocityInverseCurve_append_concentric_curviness(swigCPtr, this, value);
  }

  public void constructProperty_concentric_curviness(double initValue) {
    opensimSimulationJNI.ForceVelocityInverseCurve_constructProperty_concentric_curviness(swigCPtr, this, initValue);
  }

  public double get_concentric_curviness() {
    return opensimSimulationJNI.ForceVelocityInverseCurve_get_concentric_curviness__SWIG_1(swigCPtr, this);
  }

  public SWIGTYPE_p_double upd_concentric_curviness() {
    return new SWIGTYPE_p_double(opensimSimulationJNI.ForceVelocityInverseCurve_upd_concentric_curviness__SWIG_1(swigCPtr, this), false);
  }

  public void set_concentric_curviness(double value) {
    opensimSimulationJNI.ForceVelocityInverseCurve_set_concentric_curviness__SWIG_1(swigCPtr, this, value);
  }

  public void copyProperty_eccentric_curviness(ForceVelocityInverseCurve source) {
    opensimSimulationJNI.ForceVelocityInverseCurve_copyProperty_eccentric_curviness(swigCPtr, this, ForceVelocityInverseCurve.getCPtr(source), source);
  }

  public double get_eccentric_curviness(int i) {
    return opensimSimulationJNI.ForceVelocityInverseCurve_get_eccentric_curviness__SWIG_0(swigCPtr, this, i);
  }

  public SWIGTYPE_p_double upd_eccentric_curviness(int i) {
    return new SWIGTYPE_p_double(opensimSimulationJNI.ForceVelocityInverseCurve_upd_eccentric_curviness__SWIG_0(swigCPtr, this, i), false);
  }

  public void set_eccentric_curviness(int i, double value) {
    opensimSimulationJNI.ForceVelocityInverseCurve_set_eccentric_curviness__SWIG_0(swigCPtr, this, i, value);
  }

  public int append_eccentric_curviness(double value) {
    return opensimSimulationJNI.ForceVelocityInverseCurve_append_eccentric_curviness(swigCPtr, this, value);
  }

  public void constructProperty_eccentric_curviness(double initValue) {
    opensimSimulationJNI.ForceVelocityInverseCurve_constructProperty_eccentric_curviness(swigCPtr, this, initValue);
  }

  public double get_eccentric_curviness() {
    return opensimSimulationJNI.ForceVelocityInverseCurve_get_eccentric_curviness__SWIG_1(swigCPtr, this);
  }

  public SWIGTYPE_p_double upd_eccentric_curviness() {
    return new SWIGTYPE_p_double(opensimSimulationJNI.ForceVelocityInverseCurve_upd_eccentric_curviness__SWIG_1(swigCPtr, this), false);
  }

  public void set_eccentric_curviness(double value) {
    opensimSimulationJNI.ForceVelocityInverseCurve_set_eccentric_curviness__SWIG_1(swigCPtr, this, value);
  }

  /**
   *  The default constructor creates an inverse force-velocity curve using<br>
   *     the default property values and assigns a default name. 
   */
  public ForceVelocityInverseCurve() {
    this(opensimSimulationJNI.new_ForceVelocityInverseCurve__SWIG_0(), true);
  }

  /**
   *  Constructs an inverse force-velocity curve using the provided parameters<br>
   *     and assigns a default name. 
   */
  public ForceVelocityInverseCurve(double concentricSlopeAtVmax, double concentricSlopeNearVmax, double isometricSlope, double eccentricSlopeAtVmax, double eccentricSlopeNearVmax, double maxEccentricVelocityForceMultiplier, double concentricCurviness, double eccentricCurviness) {
    this(opensimSimulationJNI.new_ForceVelocityInverseCurve__SWIG_1(concentricSlopeAtVmax, concentricSlopeNearVmax, isometricSlope, eccentricSlopeAtVmax, eccentricSlopeNearVmax, maxEccentricVelocityForceMultiplier, concentricCurviness, eccentricCurviness), true);
  }

  /**
   *  @return The slope of the force-velocity curve at a normalized velocity<br>
   *     of -1, which is the minimum slope of the concentric side of the<br>
   *     force-velocity curve. 
   */
  public double getConcentricSlopeAtVmax() {
    return opensimSimulationJNI.ForceVelocityInverseCurve_getConcentricSlopeAtVmax(swigCPtr, this);
  }

  /**
   *  @return The slope of the force-velocity curve near the maximum<br>
   *     normalized concentric (shortening) contraction velocity (between<br>
   *     approximately -0.8 and -1). 
   */
  public double getConcentricSlopeNearVmax() {
    return opensimSimulationJNI.ForceVelocityInverseCurve_getConcentricSlopeNearVmax(swigCPtr, this);
  }

  /**
   *  @return The slope of the force-velocity curve at a normalized velocity<br>
   *     of 0, which is the maximum slope of the force-velocity curve. 
   */
  public double getIsometricSlope() {
    return opensimSimulationJNI.ForceVelocityInverseCurve_getIsometricSlope(swigCPtr, this);
  }

  /**
   *  @return The slope of the force-velocity curve at a normalized velocity<br>
   *     of 1, which is the minimum slope of the eccentric side of the force-velocity<br>
   *     curve. 
   */
  public double getEccentricSlopeAtVmax() {
    return opensimSimulationJNI.ForceVelocityInverseCurve_getEccentricSlopeAtVmax(swigCPtr, this);
  }

  /**
   *  @return The slope of the force-velocity curve near the maximum<br>
   *     normalized eccentric (lengthening) contraction velocity (between<br>
   *     approximately 0.8 and 1). 
   */
  public double getEccentricSlopeNearVmax() {
    return opensimSimulationJNI.ForceVelocityInverseCurve_getEccentricSlopeNearVmax(swigCPtr, this);
  }

  /**
   *  @return The value of the force-velocity curve (i.e., the force-velocity<br>
   *     multiplier) at the maximum eccentric contraction velocity. 
   */
  public double getMaxEccentricVelocityForceMultiplier() {
    return opensimSimulationJNI.ForceVelocityInverseCurve_getMaxEccentricVelocityForceMultiplier(swigCPtr, this);
  }

  /**
   *  @return A dimensionless parameter between 0 and 1 that describes the<br>
   *     shape of the concentric branch of the force-velocity curve: a value of 0<br>
   *     indicates that the curve is very close to a straight line segment and a<br>
   *     value of 1 indicates a curve that smoothly fills the corner formed by the<br>
   *     linear extrapolation of 'concentricSlopeNearVmax' and 'isometricSlope', as<br>
   *     shown in the figure in the class description. 
   */
  public double getConcentricCurviness() {
    return opensimSimulationJNI.ForceVelocityInverseCurve_getConcentricCurviness(swigCPtr, this);
  }

  /**
   *  @return A dimensionless parameter between 0 and 1 that describes the<br>
   *     shape of the eccentric branch of the force-velocity curve: a value of 0<br>
   *     indicates that the curve is very close to a straight line segment and a<br>
   *     value of 1 indicates a curve that smoothly fills the corner formed by the<br>
   *     linear extrapolation of 'isometricSlope' and 'eccentricSlopeNearVmax', as<br>
   *     shown in the figure in the class description. 
   */
  public double getEccentricCurviness() {
    return opensimSimulationJNI.ForceVelocityInverseCurve_getEccentricCurviness(swigCPtr, this);
  }

  /**
   *     @param aConcentricSlopeAtVmax<br>
   *         The slope of the force-velocity curve at a normalized velocity of -1,<br>
   *         which is the minimum slope of the concentric side of the force-velocity<br>
   *         curve.<br>
   *     @param aConcentricSlopeNearVmax<br>
   *         The slope of the force-velocity curve near the maximum normalized<br>
   *         concentric (shortening) contraction velocity (between approximately<br>
   *         -0.8 and -1).<br>
   *     @param aIsometricSlope<br>
   *         The slope of the force-velocity curve at a normalized velocity of 0,<br>
   *         which is the maximum slope of the force-velocity curve.<br>
   *     @param aEccentricSlopeAtVmax<br>
   *         The slope of the force-velocity curve at a normalized velocity of 1,<br>
   *         which is the minimum slope of the eccentric side of the force-velocity<br>
   *         curve.<br>
   *     @param aEccentricSlopeNearVmax<br>
   *         The slope of the force-velocity curve near the maximum normalized<br>
   *         eccentric (lengthening) contraction velocity (between approximately 0.8<br>
   *         and 1).<br>
   *     @param aMaxForceMultiplier<br>
   *         The value of the force-velocity curve (i.e., the force-velocity<br>
   *         multiplier) at the maximum eccentric contraction velocity.<br>
   * <br>
   *     <b>Conditions</b><br>
   *     {@literal 
      1a)  0 < concentricSlopeAtVmax < 1
      1b)  concentricSlopeAtVmax < concentricSlopeNearVmax < 1
      2a)  1 < isometricSlope
      2b)  (maxEccentricVelocityForceMultiplier-1)/1 < isometricMaxSlope
      3a)  0 < eccentricSlopeAtVmax < (maxEccentricVelocityForceMultiplier-1)/1
      3b)  eccentricSlopeAtVmax < eccentricSlopeNearVmax < (maxEccentricVelocityForceMultiplier-1)/1
       4)  1 < maxEccentricVelocityForceMultiplier
      }
   */
  public void setCurveShape(double aConcentricSlopeAtVmax, double aConcentricSlopeNearVmax, double aIsometricSlope, double aEccentricSlopeAtVmax, double aEccentricSlopeNearVmax, double aMaxForceMultiplier) {
    opensimSimulationJNI.ForceVelocityInverseCurve_setCurveShape(swigCPtr, this, aConcentricSlopeAtVmax, aConcentricSlopeNearVmax, aIsometricSlope, aEccentricSlopeAtVmax, aEccentricSlopeNearVmax, aMaxForceMultiplier);
  }

  /**
   *     @param aConcentricCurviness<br>
   *         A dimensionless parameter between 0 and 1 that describes the shape of<br>
   *         the concentric branch of the force-velocity curve: a value of 0<br>
   *         indicates that the curve is very close to a straight line segment and a<br>
   *         value of 1 indicates a curve that smoothly fills the corner formed by<br>
   *         the linear extrapolation of 'concentricSlopeNearVmax' and<br>
   *         'isometricSlope', as shown in the figure in the class description.<br>
   * <br>
   *     <b>Conditions</b><br>
   *     {@literal 
      0 <= concentricCurviness <= 1
      }
   */
  public void setConcentricCurviness(double aConcentricCurviness) {
    opensimSimulationJNI.ForceVelocityInverseCurve_setConcentricCurviness(swigCPtr, this, aConcentricCurviness);
  }

  /**
   *     @param aEccentricCurviness<br>
   *         A dimensionless parameter between 0 and 1 that describes the shape of<br>
   *         the eccentric branch of the force-velocity curve: a value of 0 indicates<br>
   *         that the curve is very close to a straight line segment and a value of 1<br>
   *         indicates a curve that smoothly fills the corner formed by the linear<br>
   *         extrapolation of 'isometricSlope' and 'eccentricSlopeNearVmax', as shown<br>
   *         in the figure in the class description.<br>
   * <br>
   *     <b>Conditions</b><br>
   *     {@literal 
      0 <= eccentricCurviness <= 1
      }
   */
  public void setEccentricCurviness(double aEccentricCurviness) {
    opensimSimulationJNI.ForceVelocityInverseCurve_setEccentricCurviness(swigCPtr, this, aEccentricCurviness);
  }

  /**
   *  Implement the generic OpenSim::Function interface *
   */
  public double calcValue(Vector x) {
    return opensimSimulationJNI.ForceVelocityInverseCurve_calcValue__SWIG_0(swigCPtr, this, Vector.getCPtr(x), x);
  }

  /**
   *  Evaluates the inverse force-velocity curve at a force-velocity<br>
   *     multiplier value of 'aForceVelocityMultiplier'. 
   */
  public double calcValue(double aForceVelocityMultiplier) {
    return opensimSimulationJNI.ForceVelocityInverseCurve_calcValue__SWIG_1(swigCPtr, this, aForceVelocityMultiplier);
  }

  /**
   *  Calculates the derivative of the inverse force-velocity curve with<br>
   *     respect to the force-velocity multiplier.<br>
   *     @param aForceVelocityMultiplier<br>
   *         The force-velocity multiplier value.<br>
   *     @param order<br>
   *         The order of the derivative. Only values of 0, 1, and 2 are acceptable.<br>
   *     @return <br>
   *         The derivative of the inverse force-velocity curve with respect to the<br>
   *         force-velocity multiplier.
   */
  public double calcDerivative(double aForceVelocityMultiplier, int order) {
    return opensimSimulationJNI.ForceVelocityInverseCurve_calcDerivative__SWIG_0(swigCPtr, this, aForceVelocityMultiplier, order);
  }

  /**
   *  If possible, use the simpler overload above.
   */
  public double calcDerivative(StdVectorInt derivComponents, Vector x) {
    return opensimSimulationJNI.ForceVelocityInverseCurve_calcDerivative__SWIG_1(swigCPtr, this, StdVectorInt.getCPtr(derivComponents), derivComponents, Vector.getCPtr(x), x);
  }

  /**
   *  Returns a SimTK::Vec2 containing the lower (0th element) and upper (1st<br>
   *     element) bounds on the domain of the curve. Outside this domain, the curve<br>
   *     is approximated using linear extrapolation.<br>
   *     @return <br>
   *         The minimum and maximum value of the domain, x, of the curve y(x).<br>
   *         Within this range, y(x) is a curve; outside this range, the function<br>
   *         y(x) is a C2-continuous linear extrapolation.
   */
  public Vec2 getCurveDomain() {
    return new Vec2(opensimSimulationJNI.ForceVelocityInverseCurve_getCurveDomain(swigCPtr, this), true);
  }

  /**
   *  Generates a .csv file with a name that matches the curve name (e.g.,<br>
   *     "bicepsfemoris_ForceVelocityInverseCurve.csv"). This function is not const<br>
   *     to permit the curve to be rebuilt if it is out-of-date with its properties.<br>
   *     @param path<br>
   *         The full destination path. Note that forward slashes ('/') must be used<br>
   *         and there should not be a slash after the last folder.<br>
   * <br>
   *     The file will contain the following data:<br>
   *     {@literal 
      column: 1 | 2 |     3 |       4
        data: x | y | dy/dx | d2y/dx2
      }<br>
   * <br>
   *     Samples will be taken from the concentric linear extrapolation region (the<br>
   *     region with normalized fiber velocities &lt; -1), through the curve, out to the<br>
   *     eccentric linear extrapolation region (the region with normalized fiber<br>
   *     velocities &gt; 1). The width of each linear extrapolation region is 10% of the<br>
   *     curve domain, or 0.1*(x1-x0). The curve is sampled quite densely: the<br>
   *     inverse force-velocity .csv file will have 200+20 rows.<br>
   * <br>
   *     <b>Example</b><br>
   *     To read the .csv file into Matlab, you need to set csvread to ignore the<br>
   *     header row. Since csvread is 0-indexed, the following example will begin<br>
   *     reading the .csv file from the first column of the second row:<br>
   *     {@literal 
      data = csvread('bicepsfemoris_ForceVelocityInverseCurve.csv', 1, 0);
      }
   */
  public void printMuscleCurveToCSVFile(String path) {
    opensimSimulationJNI.ForceVelocityInverseCurve_printMuscleCurveToCSVFile(swigCPtr, this, path);
  }

  public void ensureCurveUpToDate() {
    opensimSimulationJNI.ForceVelocityInverseCurve_ensureCurveUpToDate(swigCPtr, this);
  }

}
