Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

ParamML: Fetching Results

All results available through the OpenBrIM app are also accessible in ParamML documents through result extraction functions. That means results can be used just like any other parameter in your ParamML document. Keep in mind that if there are not analysis results available (results have been reset or analysis have not yet been run), these parameters will evaluate to zero.

For example, <P N="x" V="disp(SW, N1)" /> defines a new parameter named x whose value is the return of the disp() function. disp() function takes in the name/ID of the load case (first argument, SW) and the name/id of the node (second argument, N1) and returns the displacements on the node.

If you are interested in forces (reactions) on the node, then you can use force() function. It takes the same input as disp() function and returns the reactions on the node.

force() function can be used to read forces from finite elements as well, you just need to pass the name of the finite element along with the zero based node index specifying on which node of the element the forces will be reported.

<P N="y1" V="force(SW, BEAM1, 0)" />

The value of y is the return value of the force() function, which in this case is the forces at the start node of BEAM1 for analysis case SW.

<P N="y2" V="force(SW, BEAM1, 1)" />

The value of y is the return value of the force() function, which in this case is the forces at the end node of BEAM1 for analysis case SW.

disp() and force() functions return a list containing 6 numbers, each number representing displacement/force at one degree of freedom on the specified node.

For example, the return value [0, 0, -2, 0, 0.002, 0] of disp() function says that there is 2 unit of displacement in negative translation z direction and 0.002 unit of rotation about the y axis. all other displacement and rotations on this node for this analysis case are zero.

If you are interested in a displacement at only one degree of freedom on the node, you can simply write:

<P N="dz1" V="disp(SW, N1)[2]" />

Given that the returned list of disp() function is zero based (all lists are zero based in OpenBrIM), you can use [2] to access the third number in the list which represent the displacement in z direction.

Results on DOFs

In the above example, While you are getting displacement for only translation z, keep in mind that this method actually fetches displacements on all 6 dofs and then picks the translation z from the returned list. In most cases this may be OK, but OpenBrIM is built on lazy computation principal. The analysis engine will perform the core calculations (computing displacements and element states) but actual reported forces are only computed/fetched when they are needed in real-time.

To avoid unnecessary computations, you may want to avoid fetching results for all the dofs on that node and fetch just the dof you are interested. The following function are more specific for that purpose:

dispTx(), dispTy(), dispTz(), dispRx(), dispRy() and dispRz() for displacements. 
forceFx(), forceFy(), forceFz(), forceMx(), forceMy() and forceMz() for forces.

These functions are used the same way as the disp() and force() functions except that they will return the result of only the dof specified in the name of the function. So the return value of these functions would be a number (not a list of numbers).

<P N="dz2" V="dispTz(SW, N1)" />

The value of dz2 is same as dz1 -- both fetches the displacement in translation z on node N1 for analysis case SW.

Negative/Positive Effects

Certain analysis cases provide results separately for negative and positive displacements/forces. For example, influence based live load analysis cases provide results that maximizes negative moment and/or positive moment on a beam. Or an enveloped case that is setup to pick the maximum separately for negative and positive force effects.

If such analysis case is provided to the aforementioned functions, the returned result may be for negative or positive depending on which one is larger in magnitude. Internally, OpenBrIM fetches the results for both positive and negative and then picks the absolute maximum.

If you specifically interested in negative displacement/force or positive displacement/force effect, you can specify that by using the following even more specific functions:

dispTxPos(), dispTxNeg(), dispTyPos(), dispTyNeg()  dispRzNeg() and dispRzPos(). 
forceFxPos(), forceFxNeg(), forceFyPos(), forceFyNeg()  forceMzNeg() and forceMzPos().

Nodal Results by Coordinate

If you don't have direct access to the node object, you can pass in a coordinate as a list of 3 numbers (this only applies to nodes, will not work for finite element). OpenBrIM will find the node that is closest to the specified coordinate and return the results.

<P N="dz9" V="dispTz(SW, [0,10,2])" />

Above call to dispTz() function returns the displacement tz on the node that is closes to coordinate x=0, y=10 and z=2.

More on Referencing Objects

In most cases, analysis objects are not defined directly in the project but come as part of a library object. Projects may contain multiple instances of library objects -- for example, a 3 span bridge may contain 2 instances of pier library object and 2 instances of abutment library object. That means if you have a node N1 defined in pier library object, your project now contains 2 nodes with name N1 in it, which would cause confusion when looking at reports or extracting results. Same effect would be caused by putting node N1 inside a repeat -- which would mean there would be many N1s in the project based on how Repeat is setup.

In order to avoid these issues, OpenBrIM creates/updates an analytical model as part of your project every time a change to the model is detected. During this process, all analysis objects found in library objects of the project are brought directly into the project under a new group named "FEA". At this point, all FEMesh objects create their mesh objects and all parametric expressions, Repeats and Guards are resolved. Also, all object connectivities are handled. The goal of the process is to create a raw non-ambiguous FE model that can be directly and quickly analyzed by the internal OpenBrIM analysis engine or an external analysis engine of your choice.

Analytical model re-organizes analysis object names to avoid ambiguity. Given the above example with node N1 and two pier library objects named Pier1 and Pier2 in the project. The names of the nodes will be changed to Pier1.N1 and Pier2.N1. You can always open up your project in OpenBrIM app and see the assigned names for the analysis objects on FEA view spreadsheets.

For example, if you want to get the displacement Tz on a node of pier Pier1, you can make the call as:

<P N="dz3" V="dispTz(SW, 'Pier1.N1')" />

If node N1 is inside repeat statements, you can also specify which repetition of N1 you are interested by specifying the name of the repeat and the repetition control parameter value. Let's assume that in Pier1, node N1 is embedded inside a repetition object named Rep1 that goes from 0 to 4 (5 repetition). And we want the first repetition of N1.

<P N="dz4" V="dispTz(SW, 'Pier1.Rep1[0].N1')" />

You can also use nested repetitions. The following example, get the displacement from node N1 of Pier1 contained in 2 repetitions, Rep1 and Rep2 respectively.

<P N="dz5" V="dispTz(SW, 'Pier1.Rep1[0].Rep2[0].N1')" />

In certain cases, you may not know the exact string you need to send to disp or force functions. For example, you may be creating a library object that uses an input parameter to determine from which pier it will be getting the node. In such cases, constructing the string, while possible, may get tedious. You can use feobj() to get the object and then send it to the result extraction functions.

feobj() function takes in an instance of library object (or library object name) and the name of the analysis object you would like to get and returns the object back. The following is equivalent to dz3 parameter defined above.

<P N="dz6" V="dispTz(SW, feobj(Pier1, 'N1'))" />

and the following is equivalent to dz5:

<P N="dz7" V="dispTz(SW, feobj(Pier1, 'N1', 'Rep1', 0, 'Rep2', 0))" />

Note that, feobj() function will work for all analysis objects: nodes, finite elements, coordinate systems, analysis cases. If you want to extract displacements on node N1 defined in Pier1 for an analysis case named CASE1 defined in a library object instance named Loading1:

<P N="dz8" V="dispTz(feobj(Loading1,'CASE1'), feobj(Pier1, 'N1'))" />

Composite Forces

Instead of getting forces on a particular finite element, in certain cases, you may be interested in getting sum of forces of multiple elements. OpenBrIM calls these composite forces. Given a set of finite elements, composite force procedure computes a geometric centroid formed by the elements and then transform the forces in the elements to this centroid, sum and report as composite force.

One common use case for composite forces is to get composite forces acting on a girder where the girder and the deck is modeled using separate finite elements. In such case, rather than the forces in the individual finite elements, you would be interested in composite forces formed by the elements of the girder and the contributing deck over the girder.

The recommended way of accessing composite forces is to create an FEComposite object (explained in the next section), but you can also directly call force() function with a list of finite elements (nodes are not supported).

<P N="dz10" V="dispTz(SW, [L1,L2,L3])" />

The composite forces procedure assumes a virtual composite 2-node element made up of the provided finite elements to the force() function. The returned composite results will be by default two lists -- one for each end of the virtual composite 2-node element. You can pass a third argument to force() function to get the start (send 0) or end (send 1) of the virtual element

  • No labels