I like the approach Jason outlined though I'm not 100% sure whether
mass_matrix & forcing should be properties or methods. If these
matrices are being formed when you call:
lag.lagrange_equations(simplify=True)
then it seems like they should be properties rather than methods.
However, this opens up the possibility that the user asks for these
properties before lagrange_equations() has been called, in which case
I'm not sure what the best thing to do would be.
How about just returning mass_matrix and forcing matrices as list when
you call lagrange_equations, and getting rid of the mass_matrix and
forcing methods/properties entirely? So it would look like:
M, f = lag.lagrange_equations(simplify=True)
It might even make sense to *always* return the full mass matrix and
forcing vector, and then the user can do whatever they want by simply
slicing away the part they aren't interested in. This would make it
so there is only 1 way to use the class and would make it simpler for
the user to learn and for you to test/maintain/implement.
This would essentially enforce the proper usage.
Also, with regards to Stefan's comment about L being an expression and
having to supply the coordinates as a list, I think it is fine the way
you have it. They typical use case might be something like:
q = dynamicsymbols('q:8')
N = ReferenceFrame('N')
A = N.orientnew('A', 'Axis', [N.z, q[0]])
# more kinematics goes here, making use of q to build the lagrangian expression
lag = Lagrange(lagrangian, coordinates, constraints=con, forces=forces, frame=N)
M, f = lag.lagrange_equations()
Also, to be sure, you should not make any calls to things like
simplify() or trigsimp() in this class unless the user specifically
asks for it like Jason did. In my experience the results vary (both
execution time and the final expression obtained) as
simplify()/trigsimp() evolve and how you formulated the problem. For
toy problems it is usually fine but for anything non-trivial these
function calls simply become too expensive and slow the derivation
down to a crawl and therefore should not be on by default. Having an
optional keyword argument like Jason wrote would be fine though.
Otherwise, I think it looks great! I'm looking forward to seeing it
solve the rolling disc problem -- will that be your unit test case?
~Luke
On Wed, Aug 1, 2012 at 7:31 AM, Jason Moore <[email protected]> wrote:
> I'm of the opinion that you should supply all the necessary information in
> the __init__ method of the Lagrange versus having all the setter methods.
> Stefan points this out too. The __init__ method should require the bare
> minimum arguments (lagrangian, generlized coords) and all the others be
> optional, probably as keyword arguments. It can be handled with something
> like __init__(lagragian, coordinates, **kwargs). This way the user is forced
> to supply all necessary items to the class on it's creation and it is
> immediately useful. I've always found it odd that the current Kane
> formulation calls for you to create and empty useless object and it only
> becomes useful after calling all the extra setter methods.
>
> Following that, the user should call the .lagrange_equations() method with
> no argmuments to do the computation (arguments to this method should reflect
> options for the computation like with or without simplification etc), which
> has the potential to take a long time. Once these equations are stored in
> the class, seems like mass_matrix(), forcing() etc should be methods not
> attributes, as they are doing some computing too, i.e. picking off
> coefficients and parsing Lagrange's equations.
>
> What methods do you plan to use for the rhs method? I could imagine this
> taking arguments for different types of solving methods.
>
> Here is an example of how I imagine the class generation:
>
> # build the object
> lag = Lagrange(lagrangian, coordinates, constraints=con, forces=forces,
> frame=N)
>
> # compute the equations
> lag.lagrange_equations(simplify=True)
>
> # extract the mass matrix
> m = lag.mass_matrix()
>
> # find the right hand side
> rhs = lag.rhs(method=guass)
>
> The preceding seems cleaner to me and more intuitive for the user following
> typical standards from other popular python software.
>
> Jason
>
>
> On Wed, Aug 1, 2012 at 5:21 AM, gadha007 <[email protected]> wrote:
>>
>> I have been working on the addition of lagrangian mechanics to
>> sympy.physics.mechanics and I was hoping to get some input, suggestions or
>> recommendations on it. Equations of motion are generated using Lagrange's
>> equations of the second kind and this is what the procedure looks like-
>>
>> 1.) Upon having done the kinematics and subequently developing a
>> lagrangian, the user initializes the lagrange object where the lagrangian,
>> L, is the argument.
>>
>> l = Lagrange(L)
>>
>> 2.) The user then supplies a list of generalized coordinates using the
>> coords method.
>>
>> l.coords(list_of_gen_coords)
>>
>> 3.) This is followed by a constraints method where the user can supply
>> nonholonomic equations (i.e. velocity constraints) and/or differentiated
>> holonomic equations (i.e. differentiated configuration constraints) if there
>> are any. By default the constraint equations are set to none.
>>
>> l.constraints(list_of_coneqs)
>>
>> 4.) With this done, the user can then call the method
>> 'lagranges_equations' where (s)he can supply the non-conservative forces (or
>> moments due to non-conservative), if any, along with a reference frame. In
>> this way the effect of non-conservative forces such as friction can be
>> accounted for. This generates a column vector of the dynamical equations
>> using lagrange's method.
>>
>> l.lagranges_equations(forcelist, frame)
>>
>> 5.) a.) Following this the user also has the option to either look at the
>> mass matrix (i.e. coeffecients of the acceleration terms in the dynamical
>> equations) and the forcing terms (i.e. all the other terms in the ) from the
>> dynamical equations separately using the 'mass_matrix' and 'forcing'
>> methods.
>>
>> l.mass_matrix
>>
>> l.forcing
>>
>> 5.)b)The user also has the option to look at the mass matrix and forcing
>> matrix augmented with the appropriate parts of the differentiated constraint
>> equations respectively. These methods are called 'mass_matrix_full' and
>> 'forcing_full'.
>>
>> l.mass_matrix_full
>>
>> l.forcing_full
>>
>> 5.)c) And finally the user can call the 'rhs' method which essentially
>> solves the lagrange equations by multiplying the inverse of mass_matrix_full
>> and the forcing_full.
>>
>> l.rhs
>>
>> let me know if you have any recommendations with respect to names of
>> methods or anything else at all.
>>
>> Thanks
>> Angadh
>>
>>
>>
>
>
>
> --
> Personal Website
> Sports Biomechanics Lab, UC Davis
> Davis Bike Collective Minister, Davis, CA
> BikeDavis.info
> Google Voice: +01 530-601-9791
> Home: +01 530-753-0794
> Office: +01 530-752-2163
> Lab: +01 530-752-2235
>
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "sympy" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected].
> For more options, visit this group at
> http://groups.google.com/group/sympy?hl=en.
--
"People call me a perfectionist, but I'm not. I'm a rightist. I do
something until it's right, and then I move on to the next thing."
-- James Cameron
--
You received this message because you are subscribed to the Google Groups
"sympy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sympy?hl=en.