Skip to content

Logics of Reaction Assignment

mkraska edited this page Sep 22, 2021 · 18 revisions

How do we detect which force or moment matches what support or connection?

In Meclib, a proximity check is made for active forces (start and end point) and active moments (center point).

For isolated supports, this is sufficient for matchmaking.

Ambiguities arise in the case that multiple supports apply to a single point, e.g. the nodes of a truss or multiple ropes or bars.

The ambiguity can be reduced by

  • checking for parallelity condition (this won't help in a truss with parallel bars at the same node)
  • name checking (is the name of the support part of the reaction name? Is the number of a bar or rope equal to the index of a force?). This would require appropriate naming schemes, which would not be an artificial requirement)
  • one could demand both points of a force being on the element to be replaced (artificial limitation, specific to Meclib)

Implementation by:

  • Maxima function matchByName()
  • Maxima function matchByParallel()

These functions would reduce the force index lists in the names response.

matchByParallel()

Takes the objects and names list and returns a reduced names list. The list is reduced such that indices are removed for loads which are not parallel to the item they replace. Loads of items, where parallelity can't be established, are kept.

matchByParallel(o,n):=block([res, llist],res: [],
    /* for all objects */
    for i:1 thru length(o) do (
        /* if names entry is not a list, copy it to result */
        if (not listp(n[i])) then res: endcons(n[i], res) else (
            /* either a nondirectional item or parallel to the force */
            display(i, n[i]),
            llist: sublist(n[i], 
                lambda([x], 
                    member(o[i][1], [ "fix12, fix123", "circle"]) or
                    parallelp(o[i], o[x] )
                )
            ),
            res: endcons(llist, res)
        )
    ),
    return(res)
);

Helper functions

direction(object)

returns a direction vector for objects which have a direction or false otherwise

direction(o):=block([v, a0, le, r1, r2, a1],
    if member(o[1], ["bar", "force", "dashpot", "springt", "springc"]) then return(o[4]-o[3]),
    if member(o[1], ["fix1"]) then return([-sin(o[4]*%pi/180), cos(o[4]*%pi/180)]),
    if member(o[1], ["rope"]) then (
        /* same math as in meclib */
        v: o[5]-o[3], le: cabs(v[1]+%i*v[2]), a0: carg(v[1]+%i*v[2]),
        r1: o[4], r2: o[6], a1: acos((r1-r2)/le),
        return(float(v+[(r2-r1)*cos(a0-a1), (r2-r1)*sin(a0-a1)]))
    )
);

parrallelp(obj1, obj2)

returns true if two objects are parallel or false otherwise

parallelp(a,b):= block([da,db],
    da: direction(a), db: direction(b),
    if listp(da) and listp(db) then 
        return(is (abs(da[1]*db[2]-da[2]*db[1])<0.05) )
);

Tryout Space

In order to try code snippets in jsfiddle,

  1. copy the code from the wiki page to the clipboard
  2. follow the link for the JSXGraph version you want to try
  3. Replace the code in the HTML section (contents of <p hidden id="init">) with the content of the clipboard
Clone this wiki locally