sympy / sympy

A computer algebra system written in pure Python
https://sympy.org/
Other
12.49k stars 4.32k forks source link

Enable Calculation of Reaction Forces with Specified Supports #26567

Closed mvg2002 closed 3 weeks ago

mvg2002 commented 3 weeks ago

References to other Issues or PRs

Brief description of what is fixed or changed

Small change to the .solve_for_reaction_loads() method in the Beam class for it to be able to solve for reaction forces using specified supports. This prevents users from having to specify reaction symbols and applying reaction loads.

Other comments

This change doesn't affect the original functionality of the .solve_for_reaction_loads() method. It adds the option for users to calculate reaction forces based on specified supports. This can be an easier and more intuitive way to find reaction forces. If the symbol of the reaction force is necessary in later calculations for the user the original way of solving for reaction forces should be used.

Release Notes

sympy-bot commented 3 weeks ago

:white_check_mark:

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. #### References to other Issues or PRs #### Brief description of what is fixed or changed Small change to the ``.solve_for_reaction_loads()`` method in the Beam class for it to be able to solve for reaction forces using specified supports. This prevents users from having to specify reaction symbols and applying reaction loads. #### Other comments This change doesn't affect the original functionality of the ``.solve_for_reaction_loads()`` method. It adds the option for users to calculate reaction forces based on specified supports. This can be an easier and more intuitive way to find reaction forces. If the symbol of the reaction force is necessary in later calculations for the user the original way of solving for reaction forces should be used. #### Release Notes * physics.continuum_mechanics * Added possibility to calculate reaction forces in beams using specified supports.

moorepants commented 3 weeks ago

Here is the code for apply_support():

    def apply_support(self, loc, type="fixed"):
        """
        This method applies support to a particular beam object.

        Parameters
        ==========
        loc : Sympifyable
            Location of point at which support is applied.
        type : String
            Determines type of Beam support applied. To apply support structure
            with
            - zero degree of freedom, type = "fixed"
            - one degree of freedom, type = "pin"
            - two degrees of freedom, type = "roller"

        Examples
        ========
        There is a beam of length 30 meters. A moment of magnitude 120 Nm is
        applied in the clockwise direction at the end of the beam. A pointload
        of magnitude 8 N is applied from the top of the beam at the starting
        point. There are two simple supports below the beam. One at the end
        and another one at a distance of 10 meters from the start. The
        deflection is restricted at both the supports.

        Using the sign convention of upward forces and clockwise moment
        being positive.

        >>> from sympy.physics.continuum_mechanics.beam import Beam
        >>> from sympy import symbols
        >>> E, I = symbols('E, I')
        >>> b = Beam(30, E, I)
        >>> b.apply_support(10, 'roller')
        >>> b.apply_support(30, 'roller')
        >>> b.apply_load(-8, 0, -1)
        >>> b.apply_load(120, 30, -2)
        >>> R_10, R_30 = symbols('R_10, R_30')
        >>> b.solve_for_reaction_loads(R_10, R_30)
        >>> b.load
        -8*SingularityFunction(x, 0, -1) + 6*SingularityFunction(x, 10, -1)
        + 120*SingularityFunction(x, 30, -2) + 2*SingularityFunction(x, 30, -1)
        >>> b.slope()
        (-4*SingularityFunction(x, 0, 2) + 3*SingularityFunction(x, 10, 2)
            + 120*SingularityFunction(x, 30, 1) + SingularityFunction(x, 30, 2) + 4000/3)/(E*I)
        """
        loc = sympify(loc)
        self._applied_supports.append((loc, type))
        if type in ("pin", "roller"):
            reaction_load = Symbol('R_'+str(loc))
            self.apply_load(reaction_load, loc, -1)
            self.bc_deflection.append((loc, 0))
        else:
            reaction_load = Symbol('R_'+str(loc))
            reaction_moment = Symbol('M_'+str(loc))
            self.apply_load(reaction_load, loc, -1)
            self.apply_load(reaction_moment, loc, -2)
            self.bc_deflection.append((loc, 0))
            self.bc_slope.append((loc, 0))
            self._support_as_loads.append((reaction_moment, loc, -2, None))

        self._support_as_loads.append((reaction_load, loc, -1, None))

When you apply a support it creates a symbol for the unknown reaction forces and moments internally automatically. The docstring then shows that you'd have to essentially guess what the symbols are and pass them into solve_reaction_loads() for it to work. There are two general issues: 1) the reaction symbols are not readily accessible or returned to the user after running apply_support() and 2) You don't know what the symbols are to pass into solve_reaction_loads(). Given this design, I think this PR makes things better than it was, but you are still left with the 1) issue. For example, you don't have the symbol to extract the expression from the solution dictionary. Maybe this is how apply_support() should work:

>>> reaction = beam.apply_support(10, 'roller')
>>> print(reaction)
R_10
moorepants commented 3 weeks ago

Have a look at this open PR: https://github.com/sympy/sympy/pull/26296

I think I like that solution better.

mvg2002 commented 3 weeks ago

Thank you for your reaction. I agree that this is a better solution for the same problem. I have implemented the solution and wrote documentation and tests. The new pull request is #26569.