Skip to content

Conversation

Ishanned
Copy link
Contributor

@Ishanned Ishanned commented Aug 2, 2023

References to other Issues or PRs

Brief description of what is fixed or changed

Implemented the solve method for the cable class. For point loads, this method computes the tensions in the segments of the cable, the reaction forces at the supports and updates the length. For distributed load, this method computes the tension at each point using tension_at() method, and the reaction forces at the supports.

Other comments

Release Notes

  • physics.continuum_mechanics
    • solve method implemented in the cable class

@sympy-bot
Copy link

sympy-bot commented Aug 2, 2023

Hi, I am the SymPy bot. I'm here to help you write a release notes entry. Please read the guide on how to write release notes.

Your release notes are in good order.

Here is what the release notes will look like:

This will be added to https://github.com/sympy/sympy/wiki/Release-Notes-for-1.13.

Click here to see the pull request description that was parsed.
<!-- Your title above should be a short description of what
was changed. Do not include the issue number in the title. -->

#### References to other Issues or PRs
<!-- If this pull request fixes an issue, write "Fixes #NNNN" in that exact
format, e.g. "Fixes #1234" (see
https://tinyurl.com/auto-closing for more information). Also, please
write a comment on that issue linking back to this pull request once it is
open. -->


#### Brief description of what is fixed or changed
Implemented the solve method for the cable class. For point loads, this method computes the tensions in the segments of the cable, the reaction forces at the supports and updates the length. For distributed load, this method computes the tension at each point using tension_at() method, and the reaction forces at the supports.

#### Other comments


#### Release Notes

<!-- Write the release notes for this release below between the BEGIN and END
statements. The basic format is a bulleted list with the name of the subpackage
and the release note for this PR. For example:

* solvers
  * Added a new solver for logarithmic equations.

* functions
  * Fixed a bug with log of integers. Formerly, `log(-x)` incorrectly gave `-log(x)`.

* physics.units
  * Corrected a semantical error in the conversion between volt and statvolt which
    reported the volt as being larger than the statvolt.

or if no release note(s) should be included use:

NO ENTRY

See https://github.com/sympy/sympy/wiki/Writing-Release-Notes for more
information on how to write release notes. The bot will check your release
notes automatically to see if they are formatted correctly. -->

<!-- BEGIN RELEASE NOTES -->
* physics.continuum_mechanics
   * solve method implemented in the cable class
<!-- END RELEASE NOTES -->

Update

The release notes on the wiki have been updated.

@Ishanned
Copy link
Contributor Author

Ishanned commented Aug 2, 2023

@Psycho-Pirate @AdvaitPote please have a look

x1 = self._left_support[0]
y1 = self._left_support[1]

theta = -atan((y2 - y1)/(x2 - x1))
Copy link
Member

Choose a reason for hiding this comment

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

Try changing the name of this variable to a more descriptive one

@Ishanned Ishanned changed the title [GSoC] solve method for point loads in cable class [GSoC] solve method for cable class Aug 26, 2023
@AdvaitPote AdvaitPote closed this Feb 25, 2024
@AdvaitPote AdvaitPote reopened this Feb 25, 2024
@AdvaitPote
Copy link
Member

Just closed and reopened to run the tests again.

@JebronLames32
Copy link
Contributor

Hello @Ishanned @AdvaitPote
I have a few doubts about what has been coded here. While creating a point load, we are mentioning the positions at which the point loads are acting.

x = sympify(load[1])
y = sympify(load[2])

However, I feel this should not be done and the force should just be given an x coordinate as the attribute with an optional y attribute. This is because the user will then be allowed to create cases which will be practally wrong. For example, the case:
image
should not be technically possible. We should return errors when such inputs are provided. I think we should allow only one of the y coordinates of the loads to be given as inputs and calculate the location of the y coordinates of the remaining loads ourselves.

Another thing I noticed is that while calculating the tension and reaction forces for the uniformly distributed load, we are taking the coordinates of the lowest point of the cable as inputs and later checking if the lowest point is consistent with the supports.

lowest_x = sympify(args[0])
lowest_y = sympify(args[1])
self._lowest_x_global = lowest_x

I feel we could be only taking the length of sag of the cable (y coordinate) as input and calculate the x coordinate ourselves with something like the code:

from sympy import sqrt

lowest_y = sympify(args[0])
x1 = self._left_support[0]
y1 = self._left_support[1]
x2 = self._right_support[0]
y2 = self._right_support[1]
lowest_x = self.length / (sqrt( (y1 - lowest_y) / (y2 - lowest_y) ) + 1)

I have solved for the tensions and reaction forces myself using vectors (sympy.physics.vector) instead of plain trigonometry. For representing the tension caused due to point loads, I have used the (Piecewise) function. The reason I tried using vectors is because I felt they looked more understandable and could be more flexibly applied to calculate certain other properties of the cable in the future. I did want to clarify the above doubts before I made a pull request for you to view my code as I felt these were important points.

@AdvaitPote
Copy link
Member

@Ishanned Let's prioritize closing/merging this PR before the GSoC coding period starts.

Also, @JebronLames32 your points are valid. @Ishanned kindly see if you can add those changes as well.

@Ishanned
Copy link
Contributor Author

Hey @AdvaitPote, I'll soon take care of the precision errors that are causing the tests to fail.
Also, I am a bit occupied currently, so I might not be able to make the changes that @JebronLames32 has suggested. If @JebronLames32 wishes, you can make a new PR for this issue once we have sorted this one. Else, maybe @shishir-11 can take up this issue since he is going to be working on this sub-module over the summer. Let me know whoever wants to take this up, I would certainly be taking part in the discussions.

@shishir-11
Copy link
Contributor

shishir-11 commented May 18, 2024

I have a few questions about calculating the y coordinates for distributed loads . Can we guess the shape of the cable or its equation. If its y coordinates form a quadratic equation we would not need to pass a lowest y coordinate on our own.

We might be able to use or some similar formula

$$ y_{1} = ax_{1}^{2} + bx_{1}+c $$

$$ y_{2} = ax_{2}^{2} + bx_{2}+c $$

$$ length = \sqrt{1+(\frac{dy}{dx})^{2}} $$

We would be able to calculate the coordinates of the lowest point. Please correct me if I'm wrong.
Also Since we already have the tensions in each segment , at each X coordinate where forces are applied we can use

$$ T_{1}\sin\theta_{1} - T_{2}\sin\theta_{2} + F_{x} = 0 $$

$$ T_{1}\cos\theta_{1} + T_{2}\cos\theta_{2} + F_{y} = 0 $$

Where $\theta$ is the angle of cable with vertical. We can use these angles to find the y positions of each force ? Any thought on this @AdvaitPote @Ishanned

@shishir-11
Copy link
Contributor

Another thing I noticed is that while calculating the tension and reaction forces for the uniformly distributed load, we are taking the coordinates of the lowest point of the cable as inputs and later checking if the lowest point is consistent with the supports.

Since we aren't taking the length of the cable from the user for calculation , The current code works fine. I'm unable to find a method to implement what @JebronLames32 initially asked for , so i would like to request if there is any content or formula present to achieve it.

Copy link

Benchmark results from GitHub Actions

Lower numbers are good, higher numbers are bad. A ratio less than 1
means a speed up and greater than 1 means a slowdown. Green lines
beginning with + are slowdowns (the PR is slower then master or
master is slower than the previous release). Red lines beginning
with - are speedups.

Significantly changed benchmark results (PR vs master)

Significantly changed benchmark results (master vs previous release)

| Change   | Before [a36a8b23]    | After [2eb826cd]    |   Ratio | Benchmark (Parameter)                                                |
|----------|----------------------|---------------------|---------|----------------------------------------------------------------------|
| -        | 69.7±1ms             | 43.5±0.07ms         |    0.62 | integrate.TimeIntegrationRisch02.time_doit(10)                       |
| -        | 67.5±0.8ms           | 42.7±0.3ms          |    0.63 | integrate.TimeIntegrationRisch02.time_doit_risch(10)                 |
| +        | 19.0±0.2μs           | 30.4±0.3μs          |    1.6  | integrate.TimeIntegrationRisch03.time_doit(1)                        |
| -        | 5.47±0.05ms          | 2.88±0.03ms         |    0.53 | logic.LogicSuite.time_load_file                                      |
| -        | 73.7±0.4ms           | 28.8±0.3ms          |    0.39 | polys.TimeGCD_GaussInt.time_op(1, 'dense')                           |
| -        | 26.3±0.3ms           | 17.0±0.08ms         |    0.65 | polys.TimeGCD_GaussInt.time_op(1, 'expr')                            |
| -        | 74.0±0.3ms           | 28.7±0.1ms          |    0.39 | polys.TimeGCD_GaussInt.time_op(1, 'sparse')                          |
| -        | 262±1ms              | 125±0.5ms           |    0.48 | polys.TimeGCD_GaussInt.time_op(2, 'dense')                           |
| -        | 257±2ms              | 123±0.5ms           |    0.48 | polys.TimeGCD_GaussInt.time_op(2, 'sparse')                          |
| -        | 675±5ms              | 370±2ms             |    0.55 | polys.TimeGCD_GaussInt.time_op(3, 'dense')                           |
| -        | 660±1ms              | 369±0.7ms           |    0.56 | polys.TimeGCD_GaussInt.time_op(3, 'sparse')                          |
| -        | 495±9μs              | 287±0.8μs           |    0.58 | polys.TimeGCD_LinearDenseQuadraticGCD.time_op(1, 'dense')            |
| -        | 1.79±0.03ms          | 1.08±0.01ms         |    0.6  | polys.TimeGCD_LinearDenseQuadraticGCD.time_op(2, 'dense')            |
| -        | 5.89±0.09ms          | 3.06±0.02ms         |    0.52 | polys.TimeGCD_LinearDenseQuadraticGCD.time_op(3, 'dense')            |
| -        | 445±2μs              | 231±2μs             |    0.52 | polys.TimeGCD_QuadraticNonMonicGCD.time_op(1, 'dense')               |
| -        | 1.48±0.02ms          | 678±2μs             |    0.46 | polys.TimeGCD_QuadraticNonMonicGCD.time_op(2, 'dense')               |
| -        | 4.88±0.01ms          | 1.68±0.02ms         |    0.35 | polys.TimeGCD_QuadraticNonMonicGCD.time_op(3, 'dense')               |
| -        | 377±0.4μs            | 205±1μs             |    0.54 | polys.TimeGCD_SparseGCDHighDegree.time_op(1, 'dense')                |
| -        | 2.44±0.02ms          | 1.24±0.01ms         |    0.51 | polys.TimeGCD_SparseGCDHighDegree.time_op(3, 'dense')                |
| -        | 10.00±0.03ms         | 4.37±0.08ms         |    0.44 | polys.TimeGCD_SparseGCDHighDegree.time_op(5, 'dense')                |
| -        | 359±3μs              | 168±0.9μs           |    0.47 | polys.TimeGCD_SparseNonMonicQuadratic.time_op(1, 'dense')            |
| -        | 2.49±0.01ms          | 896±5μs             |    0.36 | polys.TimeGCD_SparseNonMonicQuadratic.time_op(3, 'dense')            |
| -        | 9.52±0.08ms          | 2.66±0.03ms         |    0.28 | polys.TimeGCD_SparseNonMonicQuadratic.time_op(5, 'dense')            |
| -        | 1.04±0.01ms          | 426±2μs             |    0.41 | polys.TimePREM_LinearDenseQuadraticGCD.time_op(3, 'dense')           |
| -        | 1.75±0.01ms          | 505±1μs             |    0.29 | polys.TimePREM_LinearDenseQuadraticGCD.time_op(3, 'sparse')          |
| -        | 5.90±0.03ms          | 1.81±0.02ms         |    0.31 | polys.TimePREM_LinearDenseQuadraticGCD.time_op(5, 'dense')           |
| -        | 8.48±0.06ms          | 1.47±0.01ms         |    0.17 | polys.TimePREM_LinearDenseQuadraticGCD.time_op(5, 'sparse')          |
| -        | 289±0.9μs            | 64.9±0.4μs          |    0.22 | polys.TimePREM_QuadraticNonMonicGCD.time_op(1, 'sparse')             |
| -        | 3.42±0.02ms          | 391±6μs             |    0.11 | polys.TimePREM_QuadraticNonMonicGCD.time_op(3, 'dense')              |
| -        | 3.96±0.03ms          | 281±3μs             |    0.07 | polys.TimePREM_QuadraticNonMonicGCD.time_op(3, 'sparse')             |
| -        | 6.98±0.05ms          | 1.28±0.01ms         |    0.18 | polys.TimePREM_QuadraticNonMonicGCD.time_op(5, 'dense')              |
| -        | 8.76±0.07ms          | 839±3μs             |    0.1  | polys.TimePREM_QuadraticNonMonicGCD.time_op(5, 'sparse')             |
| -        | 5.02±0.01ms          | 3.00±0.03ms         |    0.6  | polys.TimeSUBRESULTANTS_LinearDenseQuadraticGCD.time_op(2, 'sparse') |
| -        | 12.0±0.1ms           | 6.58±0.03ms         |    0.55 | polys.TimeSUBRESULTANTS_LinearDenseQuadraticGCD.time_op(3, 'dense')  |
| -        | 22.6±0.2ms           | 9.03±0.05ms         |    0.4  | polys.TimeSUBRESULTANTS_LinearDenseQuadraticGCD.time_op(3, 'sparse') |
| -        | 5.29±0.03ms          | 865±4μs             |    0.16 | polys.TimeSUBRESULTANTS_QuadraticNonMonicGCD.time_op(1, 'sparse')    |
| -        | 12.7±0.1ms           | 6.99±0.01ms         |    0.55 | polys.TimeSUBRESULTANTS_QuadraticNonMonicGCD.time_op(2, 'sparse')    |
| -        | 103±2ms              | 25.8±0.09ms         |    0.25 | polys.TimeSUBRESULTANTS_QuadraticNonMonicGCD.time_op(3, 'dense')     |
| -        | 166±1ms              | 53.9±0.2ms          |    0.32 | polys.TimeSUBRESULTANTS_QuadraticNonMonicGCD.time_op(3, 'sparse')    |
| -        | 176±0.3μs            | 112±0.9μs           |    0.64 | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(1, 'dense')      |
| -        | 362±2μs              | 217±0.9μs           |    0.6  | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(1, 'sparse')     |
| -        | 4.30±0.01ms          | 836±4μs             |    0.19 | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(3, 'dense')      |
| -        | 5.29±0.05ms          | 381±2μs             |    0.07 | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(3, 'sparse')     |
| -        | 20.2±0.3ms           | 2.80±0.01ms         |    0.14 | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(5, 'dense')      |
| -        | 23.0±0.05ms          | 626±2μs             |    0.03 | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(5, 'sparse')     |
| -        | 480±2μs              | 134±0.8μs           |    0.28 | polys.TimeSUBRESULTANTS_SparseNonMonicQuadratic.time_op(1, 'sparse') |
| -        | 4.66±0.02ms          | 609±7μs             |    0.13 | polys.TimeSUBRESULTANTS_SparseNonMonicQuadratic.time_op(3, 'dense')  |
| -        | 5.41±0.06ms          | 141±0.7μs           |    0.03 | polys.TimeSUBRESULTANTS_SparseNonMonicQuadratic.time_op(3, 'sparse') |
| -        | 13.8±0.2ms           | 1.27±0ms            |    0.09 | polys.TimeSUBRESULTANTS_SparseNonMonicQuadratic.time_op(5, 'dense')  |
| -        | 14.2±0.07ms          | 142±2μs             |    0.01 | polys.TimeSUBRESULTANTS_SparseNonMonicQuadratic.time_op(5, 'sparse') |
| -        | 137±1μs              | 76.1±0.4μs          |    0.56 | solve.TimeMatrixOperations.time_rref(3, 0)                           |
| -        | 258±2μs              | 90.5±0.8μs          |    0.35 | solve.TimeMatrixOperations.time_rref(4, 0)                           |
| -        | 24.6±0.1ms           | 10.3±0.03ms         |    0.42 | solve.TimeSolveLinSys189x49.time_solve_lin_sys                       |
| -        | 28.6±0.1ms           | 15.4±0.06ms         |    0.54 | solve.TimeSparseSystem.time_linsolve_Aaug(20)                        |
| -        | 55.4±0.2ms           | 24.8±0.1ms          |    0.45 | solve.TimeSparseSystem.time_linsolve_Aaug(30)                        |
| -        | 28.3±0.2ms           | 15.2±0.07ms         |    0.54 | solve.TimeSparseSystem.time_linsolve_Ab(20)                          |
| -        | 55.5±0.4ms           | 24.4±0.08ms         |    0.44 | solve.TimeSparseSystem.time_linsolve_Ab(30)                          |

Full benchmark results can be found as artifacts in GitHub Actions
(click on checks at the top of the PR).

@Ishanned
Copy link
Contributor Author

@AdvaitPote have a look. Also thanks @shishir-11 for helping me fix the precision error :)

@AdvaitPote
Copy link
Member

Cool. It has already been discussed that the priority should be to merge this PR so that @shishir-11 can get started with his project.
Any bugs or potential changes mentioned by @JebronLames32 can be added in the future as an extended goal.

@AdvaitPote AdvaitPote merged commit 8c94201 into sympy:master May 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants