Computation of the element forces and addition of those to the result struct.
This commit is contained in:
parent
a3443cfe66
commit
03f3fe2e52
|
|
@ -1,11 +1,11 @@
|
||||||
/*!
|
/*!
|
||||||
* \file containers.h
|
* \file containers.h
|
||||||
*
|
*
|
||||||
* \author Ryan Latture
|
* \author Ryan Latture
|
||||||
* \date 8-12-15
|
* \date 8-12-15
|
||||||
*
|
*
|
||||||
* Contains the structs used to organize the job, BCs, and ties for 3D beam FEA.
|
* Contains the structs used to organize the job, BCs, and ties for 3D beam FEA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Copyright 2015. All rights reserved.
|
// Copyright 2015. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
@ -35,346 +35,392 @@
|
||||||
#ifndef FEA_CONTAINERS_H
|
#ifndef FEA_CONTAINERS_H
|
||||||
#define FEA_CONTAINERS_H
|
#define FEA_CONTAINERS_H
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <Eigen/Core>
|
#include <Eigen/Core>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace fea {
|
namespace fea {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convenience enumerator for specifying the active degree of freedom in
|
||||||
|
* a constraint.
|
||||||
|
*/
|
||||||
|
enum DOF {
|
||||||
|
/**
|
||||||
|
* Displacement along the global x-axis.
|
||||||
|
*/
|
||||||
|
DISPLACEMENT_X,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displacement along the global y-axis.
|
||||||
|
*/
|
||||||
|
DISPLACEMENT_Y,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displacement along the global z-axis.
|
||||||
|
*/
|
||||||
|
DISPLACEMENT_Z,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotation about the global x-axis.
|
||||||
|
*/
|
||||||
|
ROTATION_X,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotation about the global y-axis.
|
||||||
|
*/
|
||||||
|
ROTATION_Y,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotation about the global z-axis.
|
||||||
|
*/
|
||||||
|
ROTATION_Z,
|
||||||
|
/**
|
||||||
|
* Number of degrees of freedom per node.
|
||||||
|
*/
|
||||||
|
NUM_DOFS
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A node that describes a mesh. Uses Eigen's predefined Vector class for
|
||||||
|
* added functionality.
|
||||||
|
* @details See the Eigen documentation on the Vector3d class for more options
|
||||||
|
* of what can be done with `Nodes`. \n Examples of constucting a `Node` at
|
||||||
|
* \f$(x, y, z)=(0,1,2)\f$:
|
||||||
|
* @code
|
||||||
|
* // specify values on constuction
|
||||||
|
* fea::Node n1(1.0, 2.0, 3.0);
|
||||||
|
*
|
||||||
|
* // construct a Node then insert values
|
||||||
|
* fea::Node n2;
|
||||||
|
* n2 << 0.0, 1.0, 2.0;
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
typedef Eigen::Vector3d Node;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A boundary condition to enforce.
|
||||||
|
* @details Set by specifying the node to constrain, which degree of freedom,
|
||||||
|
* and the value to hold the node at.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* // define the node number to constrain
|
||||||
|
* unsigned int nn1 = 0;
|
||||||
|
* // define the value to hold the nodal DOF at
|
||||||
|
* double value = 0.0;
|
||||||
|
* fea::BC bc(nn1, fea::DOF::DISPLACEMENT_X, value);
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
struct BC {
|
||||||
|
unsigned int node; /**<The index of the node to constrain*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index of the dof to constrain. The fea::DOF enum can be used for
|
||||||
|
* specification or the integer values can be used directly `0==d_x`,
|
||||||
|
* `1==d_y`, ...
|
||||||
|
*/
|
||||||
|
unsigned int dof;
|
||||||
|
|
||||||
|
double value; /**<The value to hold the dof at.*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Default Constructor
|
||||||
|
* @details All values are set to zero.
|
||||||
|
*/
|
||||||
|
BC() : node(0), dof(0), value(0){};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
* @param[in] node `unsigned int`. The index of the node.
|
||||||
|
* @param[in] dof `unsigned int`. Degree of freedom to constrain (See
|
||||||
|
* fea::DOF).
|
||||||
|
* @param[in] value `double`. The prescribed value for the boundary condition.
|
||||||
|
*/
|
||||||
|
BC(unsigned int _node, unsigned int _dof, double _value)
|
||||||
|
: node(_node), dof(_dof), value(_value) {
|
||||||
|
assert(dof < DOF::NUM_DOFS);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A nodal force to enforce.
|
||||||
|
* @details Set by specifying the node where the force will be applied, which
|
||||||
|
* degree of freedom will be affected, and the value to apply.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* // define the node number to constrain
|
||||||
|
* unsigned int nn1 = 0;
|
||||||
|
* // define the value to hold the nodal DOF at
|
||||||
|
* double value = 0.0;
|
||||||
|
* fea::Force force(nn1, fea::DOF::DISPLACEMENT_X, value);
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
struct Force {
|
||||||
|
unsigned int node; /**<The index of the node to apply the force*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index of the dof to constrain. The fea::DOF enum can be used for
|
||||||
|
* specification or the integer values can be used directly `0==d_x`,
|
||||||
|
* `1==d_y`, ...
|
||||||
|
*/
|
||||||
|
unsigned int dof;
|
||||||
|
|
||||||
|
double value; /**<The value of the force to apply.*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Default Constructor
|
||||||
|
* @details All values are set to zero.
|
||||||
|
*/
|
||||||
|
Force() : node(0), dof(0), value(0){};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
* @param[in] node `unsigned int`. The index of the node.
|
||||||
|
* @param[in] dof `unsigned int`. Degree of freedom to constrain (See
|
||||||
|
* fea::DOF).
|
||||||
|
* @param[in] value `double`. The prescribed value for the force.
|
||||||
|
*/
|
||||||
|
Force(unsigned int _node, unsigned int _dof, double _value)
|
||||||
|
: node(_node), dof(_dof), value(_value) {
|
||||||
|
assert(dof < DOF::NUM_DOFS);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The set of properties associated with an element.
|
||||||
|
* @details The properties must define the extensional stiffness, \f$EA\f$,
|
||||||
|
* bending stiffness parallel to the local z-axis \f$EI_{z}\f$, bending
|
||||||
|
* stiffness parallel to the local y-axis\f$EI_{y}\f$, the torsional stiffness,
|
||||||
|
* \f$GJ\f$, and a vector pointing along the beam elements local y-axis.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* double EA = 1000.0;
|
||||||
|
* double EIz = 100.0;
|
||||||
|
* double EIy = 100.0;
|
||||||
|
* double GJ = 200.0;
|
||||||
|
* std::vector<double> normal_vec = {0.0, 0.0, 1.0};
|
||||||
|
* fea::Props props(EA, EIz, EIy, GJ, normal_vec);
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
struct Props {
|
||||||
|
double EA; /**<Extensional stiffness.*/
|
||||||
|
double EIz; /**<Bending stiffness parallel to local z-axis.*/
|
||||||
|
double EIy; /**<Bending stiffness parallel to local y-axis.*/
|
||||||
|
double GJ; /**<Torsional stiffness.*/
|
||||||
|
Eigen::Vector3d
|
||||||
|
normal_vec; /**<Vector normal to element (size==3). Direction should be
|
||||||
|
parallel to the beam element's local y-axis.*/
|
||||||
|
|
||||||
|
Props() : EA(0), EIz(0), EIy(0), GJ(0){}; /**<Default constuctor*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
* @details Allows properties to be set upon initialization.
|
||||||
|
*
|
||||||
|
* @param[in] EA double. Extensional stiffness.
|
||||||
|
* @param[in] EIz double. Bending stiffness parallel to z-axis.
|
||||||
|
* @param[in] EIy double. Bending stiffness parallel to y-axis.
|
||||||
|
* @param[in] GJ double. Torsional stiffness.
|
||||||
|
* @param[in] normal_vec std::vector<double>. Vector normal to element
|
||||||
|
* (`normal_vec.size()==3`). Direction should be parallel to the beam
|
||||||
|
* element's local y-axis.
|
||||||
|
*/
|
||||||
|
Props(double _EA, double _EIz, double _EIy, double _GJ,
|
||||||
|
const std::vector<double> &_normal_vec)
|
||||||
|
: EA(_EA), EIz(_EIz), EIy(_EIy), GJ(_GJ) {
|
||||||
|
normal_vec << _normal_vec[0], _normal_vec[1], _normal_vec[2];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Places linear springs between all degrees of freedom of 2 nodes.
|
||||||
|
* @details To form a tie specify the 2 nodes that will be linked as well as the
|
||||||
|
* spring constants for translational and rotational degrees of freedom. All
|
||||||
|
* translational degrees of freedom will be assigned the same spring constant.
|
||||||
|
* The same is true for rotational degrees of freedom, although the spring
|
||||||
|
* constant does not have to be the same as that used for the translational
|
||||||
|
* DOFs.
|
||||||
|
* @code
|
||||||
|
* // create the tie between node2 and node3
|
||||||
|
* unsigned int nn1 = 1; // i.e. the second node in the node list
|
||||||
|
* unsigned int nn2 = 2; // i.e. the third node in the node list
|
||||||
|
*
|
||||||
|
* // define the spring constant for x, y, and z translational DOFs
|
||||||
|
* double lmult = 100.0;
|
||||||
|
*
|
||||||
|
* // define the spring constant for x, y, and z rotational DOFs
|
||||||
|
* double rmult = 100.0;
|
||||||
|
*
|
||||||
|
* // form the tie
|
||||||
|
* fea::Tie tie1(nn1, nn2, lmult, rmult);
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
struct Tie {
|
||||||
|
unsigned int
|
||||||
|
node_number_1; /**<The first element's index involved in the constraint.*/
|
||||||
|
unsigned int node_number_2; /**<The second element's index involved in the
|
||||||
|
constraint.*/
|
||||||
|
double lmult; /**<multiplier for the linear spring.*/
|
||||||
|
double rmult; /**<multiplier for the rotational spring.*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Default Constructor
|
||||||
|
* @details All member variables are set to 0.
|
||||||
|
*/
|
||||||
|
Tie() : node_number_1(0), node_number_2(0), lmult(0), rmult(0){};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
* @param[in] node_number_1 `unsigned int`. Index of the first node.
|
||||||
|
* @param[in] node_number_2 `unsigned int`. Index of the second node.
|
||||||
|
* @param[in] lmult `double`. Spring constant for the translational degrees of
|
||||||
|
* freedom.
|
||||||
|
* @param[in] rmult `double`. Spring constant for the rotational degrees of
|
||||||
|
* freedom.
|
||||||
|
*/
|
||||||
|
Tie(unsigned int _node_number_1, unsigned int _node_number_2, double _lmult,
|
||||||
|
double _rmult)
|
||||||
|
: node_number_1(_node_number_1), node_number_2(_node_number_2),
|
||||||
|
lmult(_lmult), rmult(_rmult){};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A linear multipoint constraint.
|
||||||
|
* @details Equation constraints are defined by a series of terms that
|
||||||
|
* sum to zero, e.g. `t1 + t2 + t3 ... = 0`, where `tn` is the `n`th term.
|
||||||
|
* Each term specifies the node number, degree of freedom and coefficient.
|
||||||
|
* The node number and degree of freedom specify which nodal variable
|
||||||
|
* (either nodal displacement or rotation) is involved with the equation
|
||||||
|
* constraint, and coefficient is multiplied by the specified nodal variable
|
||||||
|
* when forming the equation. Note, the equation sums to zero, so in order
|
||||||
|
* to specify that 2 nodal degrees of freedom are equal their coefficients
|
||||||
|
* should be equal and opposite.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* // Create an empty equation
|
||||||
|
* fea::Equation eqn;
|
||||||
|
*
|
||||||
|
* // Stipulate that the x and y displacement for the first node must be equal
|
||||||
|
* unsigned int node_number = 0;
|
||||||
|
* eqn.terms.push_back(fea::Equation::Term(node_number,
|
||||||
|
* fea::DOF::DISPLACEMENT_X, 1.0));
|
||||||
|
* eqn.terms.push_back(fea::Equation::Term(node_number,
|
||||||
|
* fea::DOF::DISPLACEMENT_Y, -1.0);
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
struct Equation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A single term in the equation constraint.
|
||||||
|
* @details Each term defines the node number, degree of freedom and
|
||||||
|
* coefficient.
|
||||||
|
*/
|
||||||
|
struct Term {
|
||||||
|
unsigned int node_number; /**<Index of the node in the node list.*/
|
||||||
|
unsigned int dof; /**<Degree of freedom. @sa fea::DOF*/
|
||||||
|
double coefficient; /**<Coefficient to multiply the nodal variable by.*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A node that describes a mesh. Uses Eigen's predefined Vector class for added functionality.
|
* Default constructor
|
||||||
* @details See the Eigen documentation on the Vector3d class for more options of what can be done with `Nodes`. \n
|
|
||||||
* Examples of constucting a `Node` at \f$(x, y, z)=(0,1,2)\f$:
|
|
||||||
* @code
|
|
||||||
* // specify values on constuction
|
|
||||||
* fea::Node n1(1.0, 2.0, 3.0);
|
|
||||||
*
|
|
||||||
* // construct a Node then insert values
|
|
||||||
* fea::Node n2;
|
|
||||||
* n2 << 0.0, 1.0, 2.0;
|
|
||||||
* @endcode
|
|
||||||
*/
|
*/
|
||||||
typedef Eigen::Vector3d Node;
|
Term() : node_number(0), dof(0), coefficient(0){};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A boundary condition to enforce.
|
* @brief Constructor
|
||||||
* @details Set by specifying the node to constrain, which degree of freedom, and the value to hold the node at.
|
* @param node_number. `unsigned int`. Index of the node within the node
|
||||||
*
|
* list.
|
||||||
* @code
|
* @param dof. `unsigned int`. Degree of freedom for the specified node.
|
||||||
* // define the node number to constrain
|
* @param coefficient. `double`. coefficient to multiply the corresponding
|
||||||
* unsigned int nn1 = 0;
|
* nodal variable by.
|
||||||
* // define the value to hold the nodal DOF at
|
|
||||||
* double value = 0.0;
|
|
||||||
* fea::BC bc(nn1, fea::DOF::DISPLACEMENT_X, value);
|
|
||||||
* @endcode
|
|
||||||
*/
|
*/
|
||||||
struct BC {
|
Term(unsigned int _node_number, unsigned int _dof, double _coefficient)
|
||||||
unsigned int node;/**<The index of the node to constrain*/
|
: node_number(_node_number), dof(_dof), coefficient(_coefficient){};
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
std::vector<Term> terms; /**<A list of terms that sum to zero.*/
|
||||||
* The index of the dof to constrain. The fea::DOF enum can be used for specification or the integer
|
|
||||||
* values can be used directly `0==d_x`, `1==d_y`, ...
|
|
||||||
*/
|
|
||||||
unsigned int dof;
|
|
||||||
|
|
||||||
double value;/**<The value to hold the dof at.*/
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*/
|
||||||
|
Equation() : terms(0){};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Default Constructor
|
* @brief Constructor
|
||||||
* @details All values are set to zero.
|
* @param terms. `std::vector<Term>`. A list of terms that sum to zero.k
|
||||||
*/
|
*/
|
||||||
BC() : node(0), dof(0), value(0) { };
|
Equation(const std::vector<Term> &_terms) : terms(_terms){};
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constructor
|
* @brief An element of the mesh. Contains the indices of the two `fea::Node`'s
|
||||||
* @param[in] node `unsigned int`. The index of the node.
|
* that form the element as well as the properties of the element given by the
|
||||||
* @param[in] dof `unsigned int`. Degree of freedom to constrain (See fea::DOF).
|
* `fea::Props` struct.
|
||||||
* @param[in] value `double`. The prescribed value for the boundary condition.
|
*/
|
||||||
*/
|
struct Elem {
|
||||||
BC(unsigned int _node, unsigned int _dof, double _value) : node(_node), dof(_dof), value(_value) { };
|
Eigen::Vector2i
|
||||||
};
|
node_numbers; /**<The indices of the node list that define the element.*/
|
||||||
|
Props props; /**<The set of properties to associate with the element.*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A nodal force to enforce.
|
* @brief Default Constructor
|
||||||
* @details Set by specifying the node where the force will be applied, which degree of freedom will be affected,
|
*/
|
||||||
* and the value to apply.
|
Elem(){};
|
||||||
*
|
|
||||||
* @code
|
|
||||||
* // define the node number to constrain
|
|
||||||
* unsigned int nn1 = 0;
|
|
||||||
* // define the value to hold the nodal DOF at
|
|
||||||
* double value = 0.0;
|
|
||||||
* fea::Force force(nn1, fea::DOF::DISPLACEMENT_X, value);
|
|
||||||
* @endcode
|
|
||||||
*/
|
|
||||||
struct Force {
|
|
||||||
unsigned int node;/**<The index of the node to apply the force*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The index of the dof to constrain. The fea::DOF enum can be used for specification or the integer
|
* @brief Constructor
|
||||||
* values can be used directly `0==d_x`, `1==d_y`, ...
|
* @details Constructor if the node indices are passed independently. Assumes
|
||||||
*/
|
* 2 nodes per element.
|
||||||
unsigned int dof;
|
*
|
||||||
|
* @param[in] node1 unsigned int. The indices of first node associate with the
|
||||||
|
* element.
|
||||||
|
* @param[in] node2 unsigned int. The indices of second node associate with
|
||||||
|
* the element.
|
||||||
|
* @param[in] props Props. The element's properties.
|
||||||
|
*/
|
||||||
|
Elem(unsigned int node1, unsigned int node2, const Props &_props)
|
||||||
|
: props(_props) {
|
||||||
|
node_numbers << node1, node2;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
double value;/**<The value of the force to apply.*/
|
/**
|
||||||
|
* @brief Contains a node list, element list, and the properties of each
|
||||||
|
* element.
|
||||||
|
*/
|
||||||
|
struct Job {
|
||||||
|
std::vector<Node> nodes; /**<A vector of Node objects that define the mesh.*/
|
||||||
|
std::vector<Eigen::Vector2i> elems; /**<A 2D vector of ints that defines the
|
||||||
|
connectivity of the node list.*/
|
||||||
|
std::vector<Props>
|
||||||
|
props; /**<A vector that contains the properties of each element.*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Default Constructor
|
* @brief Default constructor
|
||||||
* @details All values are set to zero.
|
*/
|
||||||
*/
|
Job() : nodes(0), elems(0), props(0){};
|
||||||
Force() : node(0), dof(0), value(0) { };
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constructor
|
* @brief Constructor
|
||||||
* @param[in] node `unsigned int`. The index of the node.
|
* @details Takes an list of nodes and elements as inputs. The elements are
|
||||||
* @param[in] dof `unsigned int`. Degree of freedom to constrain (See fea::DOF).
|
* deconstructed into an array holding the connectivity list and an array
|
||||||
* @param[in] value `double`. The prescribed value for the force.
|
* holding the properties.
|
||||||
*/
|
*
|
||||||
Force(unsigned int _node, unsigned int _dof, double _value) : node(_node), dof(_dof), value(_value) { };
|
* @param[in] nodes std::vector<Node>. The node list that defines the mesh.
|
||||||
};
|
* @param[in] elems std::vector<Elem>. The elements that define the mesh.
|
||||||
|
* An element is defined by the connectivity list and the
|
||||||
|
* associated properties.
|
||||||
|
*/
|
||||||
|
Job(const std::vector<Node> &_nodes, const std::vector<Elem> _elems)
|
||||||
|
: nodes(_nodes) {
|
||||||
|
unsigned int num_elems = _elems.size();
|
||||||
|
elems.reserve(num_elems);
|
||||||
|
props.reserve(num_elems);
|
||||||
|
|
||||||
/**
|
for (unsigned int i = 0; i < num_elems; i++) {
|
||||||
* @brief The set of properties associated with an element.
|
elems.push_back(_elems[i].node_numbers);
|
||||||
* @details The properties must define the extensional stiffness, \f$EA\f$, bending stiffness parallel to the local z-axis \f$EI_{z}\f$,
|
props.push_back(_elems[i].props);
|
||||||
* bending stiffness parallel to the local y-axis\f$EI_{y}\f$, the torsional stiffness, \f$GJ\f$, and a vector pointing along the beam elements local y-axis.
|
}
|
||||||
*
|
};
|
||||||
* @code
|
};
|
||||||
* double EA = 1000.0;
|
|
||||||
* double EIz = 100.0;
|
|
||||||
* double EIy = 100.0;
|
|
||||||
* double GJ = 200.0;
|
|
||||||
* std::vector<double> normal_vec = {0.0, 0.0, 1.0};
|
|
||||||
* fea::Props props(EA, EIz, EIy, GJ, normal_vec);
|
|
||||||
* @endcode
|
|
||||||
*/
|
|
||||||
struct Props {
|
|
||||||
double EA;/**<Extensional stiffness.*/
|
|
||||||
double EIz;/**<Bending stiffness parallel to local z-axis.*/
|
|
||||||
double EIy;/**<Bending stiffness parallel to local y-axis.*/
|
|
||||||
double GJ;/**<Torsional stiffness.*/
|
|
||||||
Eigen::Vector3d normal_vec;/**<Vector normal to element (size==3). Direction should be parallel to the beam element's local y-axis.*/
|
|
||||||
|
|
||||||
Props() : EA(0), EIz(0), EIy(0), GJ(0) { };/**<Default constuctor*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Constructor
|
|
||||||
* @details Allows properties to be set upon initialization.
|
|
||||||
*
|
|
||||||
* @param[in] EA double. Extensional stiffness.
|
|
||||||
* @param[in] EIz double. Bending stiffness parallel to z-axis.
|
|
||||||
* @param[in] EIy double. Bending stiffness parallel to y-axis.
|
|
||||||
* @param[in] GJ double. Torsional stiffness.
|
|
||||||
* @param[in] normal_vec std::vector<double>. Vector normal to element (`normal_vec.size()==3`). Direction should be parallel to the beam element's local y-axis.
|
|
||||||
*/
|
|
||||||
Props(double _EA, double _EIz, double _EIy, double _GJ, const std::vector<double> &_normal_vec)
|
|
||||||
: EA(_EA), EIz(_EIz), EIy(_EIy), GJ(_GJ) {
|
|
||||||
normal_vec << _normal_vec[0], _normal_vec[1], _normal_vec[2];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Places linear springs between all degrees of freedom of 2 nodes.
|
|
||||||
* @details To form a tie specify the 2 nodes that will be linked as well as the spring constants for translational and rotational degrees of freedom.
|
|
||||||
* All translational degrees of freedom will be assigned the same spring constant.
|
|
||||||
* The same is true for rotational degrees of freedom, although the spring constant does not have to be the same as that used for the translational DOFs.
|
|
||||||
* @code
|
|
||||||
* // create the tie between node2 and node3
|
|
||||||
* unsigned int nn1 = 1; // i.e. the second node in the node list
|
|
||||||
* unsigned int nn2 = 2; // i.e. the third node in the node list
|
|
||||||
*
|
|
||||||
* // define the spring constant for x, y, and z translational DOFs
|
|
||||||
* double lmult = 100.0;
|
|
||||||
*
|
|
||||||
* // define the spring constant for x, y, and z rotational DOFs
|
|
||||||
* double rmult = 100.0;
|
|
||||||
*
|
|
||||||
* // form the tie
|
|
||||||
* fea::Tie tie1(nn1, nn2, lmult, rmult);
|
|
||||||
* @endcode
|
|
||||||
*/
|
|
||||||
struct Tie {
|
|
||||||
unsigned int node_number_1;/**<The first element's index involved in the constraint.*/
|
|
||||||
unsigned int node_number_2;/**<The second element's index involved in the constraint.*/
|
|
||||||
double lmult;/**<multiplier for the linear spring.*/
|
|
||||||
double rmult; /**<multiplier for the rotational spring.*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Default Constructor
|
|
||||||
* @details All member variables are set to 0.
|
|
||||||
*/
|
|
||||||
Tie() : node_number_1(0), node_number_2(0), lmult(0), rmult(0) { };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Constructor
|
|
||||||
* @param[in] node_number_1 `unsigned int`. Index of the first node.
|
|
||||||
* @param[in] node_number_2 `unsigned int`. Index of the second node.
|
|
||||||
* @param[in] lmult `double`. Spring constant for the translational degrees of freedom.
|
|
||||||
* @param[in] rmult `double`. Spring constant for the rotational degrees of freedom.
|
|
||||||
*/
|
|
||||||
Tie(unsigned int _node_number_1, unsigned int _node_number_2, double _lmult, double _rmult) :
|
|
||||||
node_number_1(_node_number_1), node_number_2(_node_number_2), lmult(_lmult), rmult(_rmult) { };
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief A linear multipoint constraint.
|
|
||||||
* @details Equation constraints are defined by a series of terms that
|
|
||||||
* sum to zero, e.g. `t1 + t2 + t3 ... = 0`, where `tn` is the `n`th term.
|
|
||||||
* Each term specifies the node number, degree of freedom and coefficient.
|
|
||||||
* The node number and degree of freedom specify which nodal variable
|
|
||||||
* (either nodal displacement or rotation) is involved with the equation
|
|
||||||
* constraint, and coefficient is multiplied by the specified nodal variable
|
|
||||||
* when forming the equation. Note, the equation sums to zero, so in order
|
|
||||||
* to specify that 2 nodal degrees of freedom are equal their coefficients
|
|
||||||
* should be equal and opposite.
|
|
||||||
*
|
|
||||||
* @code
|
|
||||||
* // Create an empty equation
|
|
||||||
* fea::Equation eqn;
|
|
||||||
*
|
|
||||||
* // Stipulate that the x and y displacement for the first node must be equal
|
|
||||||
* unsigned int node_number = 0;
|
|
||||||
* eqn.terms.push_back(fea::Equation::Term(node_number, fea::DOF::DISPLACEMENT_X, 1.0));
|
|
||||||
* eqn.terms.push_back(fea::Equation::Term(node_number, fea::DOF::DISPLACEMENT_Y, -1.0);
|
|
||||||
* @endcode
|
|
||||||
*/
|
|
||||||
struct Equation {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief A single term in the equation constraint.
|
|
||||||
* @details Each term defines the node number, degree of freedom and
|
|
||||||
* coefficient.
|
|
||||||
*/
|
|
||||||
struct Term {
|
|
||||||
unsigned int node_number;/**<Index of the node in the node list.*/
|
|
||||||
unsigned int dof;/**<Degree of freedom. @sa fea::DOF*/
|
|
||||||
double coefficient;/**<Coefficient to multiply the nodal variable by.*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor
|
|
||||||
*/
|
|
||||||
Term() : node_number(0), dof(0), coefficient(0) {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Constructor
|
|
||||||
* @param node_number. `unsigned int`. Index of the node within the node list.
|
|
||||||
* @param dof. `unsigned int`. Degree of freedom for the specified node.
|
|
||||||
* @param coefficient. `double`. coefficient to multiply the corresponding nodal variable by.
|
|
||||||
*/
|
|
||||||
Term(unsigned int _node_number, unsigned int _dof, double _coefficient) :
|
|
||||||
node_number(_node_number), dof(_dof), coefficient(_coefficient) {};
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<Term> terms;/**<A list of terms that sum to zero.*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor
|
|
||||||
*/
|
|
||||||
Equation() : terms(0) {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Constructor
|
|
||||||
* @param terms. `std::vector<Term>`. A list of terms that sum to zero.k
|
|
||||||
*/
|
|
||||||
Equation(const std::vector<Term> &_terms) : terms(_terms) {};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief An element of the mesh. Contains the indices of the two `fea::Node`'s that form the element as well
|
|
||||||
* as the properties of the element given by the `fea::Props` struct.
|
|
||||||
*/
|
|
||||||
struct Elem {
|
|
||||||
Eigen::Vector2i node_numbers;/**<The indices of the node list that define the element.*/
|
|
||||||
Props props;/**<The set of properties to associate with the element.*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Default Constructor
|
|
||||||
*/
|
|
||||||
Elem() { };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Constructor
|
|
||||||
* @details Constructor if the node indices are passed independently. Assumes 2 nodes per element.
|
|
||||||
*
|
|
||||||
* @param[in] node1 unsigned int. The indices of first node associate with the element.
|
|
||||||
* @param[in] node2 unsigned int. The indices of second node associate with the element.
|
|
||||||
* @param[in] props Props. The element's properties.
|
|
||||||
*/
|
|
||||||
Elem(unsigned int node1, unsigned int node2, const Props &_props) : props(_props) {
|
|
||||||
node_numbers << node1, node2;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Contains a node list, element list, and the properties of each element.
|
|
||||||
*/
|
|
||||||
struct Job {
|
|
||||||
std::vector<Node> nodes;/**<A vector of Node objects that define the mesh.*/
|
|
||||||
std::vector<Eigen::Vector2i> elems;/**<A 2D vector of ints that defines the connectivity of the node list.*/
|
|
||||||
std::vector<Props> props;/**<A vector that contains the properties of each element.*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Default constructor
|
|
||||||
*/
|
|
||||||
Job() : nodes(0), elems(0), props(0) { };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Constructor
|
|
||||||
* @details Takes an list of nodes and elements as inputs. The elements are deconstructed into
|
|
||||||
* an array holding the connectivity list and an array holding the properties.
|
|
||||||
*
|
|
||||||
* @param[in] nodes std::vector<Node>. The node list that defines the mesh.
|
|
||||||
* @param[in] elems std::vector<Elem>. The elements that define the mesh.
|
|
||||||
* An element is defined by the connectivity list and the associated properties.
|
|
||||||
*/
|
|
||||||
Job(const std::vector<Node> &_nodes, const std::vector<Elem> _elems) : nodes(_nodes) {
|
|
||||||
unsigned int num_elems = _elems.size();
|
|
||||||
elems.reserve(num_elems);
|
|
||||||
props.reserve(num_elems);
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < num_elems; i++) {
|
|
||||||
elems.push_back(_elems[i].node_numbers);
|
|
||||||
props.push_back(_elems[i].props);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Convenience enumerator for specifying the active degree of freedom in a constraint.
|
|
||||||
*/
|
|
||||||
enum DOF {
|
|
||||||
/**
|
|
||||||
* Displacement along the global x-axis.
|
|
||||||
*/
|
|
||||||
DISPLACEMENT_X,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Displacement along the global y-axis.
|
|
||||||
*/
|
|
||||||
DISPLACEMENT_Y,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Displacement along the global z-axis.
|
|
||||||
*/
|
|
||||||
DISPLACEMENT_Z,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rotation about the global x-axis.
|
|
||||||
*/
|
|
||||||
ROTATION_X,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rotation about the global y-axis.
|
|
||||||
*/
|
|
||||||
ROTATION_Y,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rotation about the global z-axis.
|
|
||||||
*/
|
|
||||||
ROTATION_Z,
|
|
||||||
/**
|
|
||||||
* Number of degrees of freedom per node.
|
|
||||||
*/
|
|
||||||
NUM_DOFS
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace fea
|
} // namespace fea
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,122 +31,129 @@
|
||||||
|
|
||||||
namespace fea {
|
namespace fea {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Contains the results of an analysis after calling `fea::solve`.
|
* @brief Contains the results of an analysis after calling `fea::solve`.
|
||||||
*/
|
*/
|
||||||
struct Summary {
|
struct Summary {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor
|
* Default constructor
|
||||||
*/
|
*/
|
||||||
Summary();
|
Summary();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns a message containing the results of the analysis.
|
* @brief Returns a message containing the results of the analysis.
|
||||||
*/
|
*/
|
||||||
std::string FullReport() const;
|
std::string FullReport() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The total time of the FE analysis.
|
* The total time of the FE analysis.
|
||||||
*/
|
*/
|
||||||
long long total_time_in_ms;
|
long long total_time_in_ms;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The time it took to assemble the global stiffness matrix.
|
* The time it took to assemble the global stiffness matrix.
|
||||||
*/
|
*/
|
||||||
long long assembly_time_in_ms;
|
long long assembly_time_in_ms;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The time to reorder the nonzero elements of the the global stiffness matrix,
|
* The time to reorder the nonzero elements of the the global stiffness
|
||||||
* such that the factorization step creates less fill-in.
|
* matrix, such that the factorization step creates less fill-in.
|
||||||
*/
|
*/
|
||||||
long long preprocessing_time_in_ms;
|
long long preprocessing_time_in_ms;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The time to compute the factors of the coefficient matrix.
|
* The time to compute the factors of the coefficient matrix.
|
||||||
*/
|
*/
|
||||||
long long factorization_time_in_ms;
|
long long factorization_time_in_ms;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The time to compute the solution of the linear system.
|
* The time to compute the solution of the linear system.
|
||||||
*/
|
*/
|
||||||
long long solve_time_in_ms;
|
long long solve_time_in_ms;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The time to compute the nodal forces.
|
* The time to compute the nodal forces.
|
||||||
*/
|
*/
|
||||||
long long nodal_forces_solve_time_in_ms;
|
long long nodal_forces_solve_time_in_ms;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The time to compute the nodal forces.
|
* The time to compute the nodal forces.
|
||||||
*/
|
*/
|
||||||
long long tie_forces_solve_time_in_ms;
|
long long tie_forces_solve_time_in_ms;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The time to compute the nodal forces.
|
* The time to compute the nodal forces.
|
||||||
* Does not include the time to save the summary itself if `Options::save_report == true` since all data must be
|
* Does not include the time to save the summary itself if
|
||||||
* computed prior to saving the report.
|
* `Options::save_report == true` since all data must be computed prior to
|
||||||
*/
|
* saving the report.
|
||||||
long long file_save_time_in_ms;
|
*/
|
||||||
|
long long file_save_time_in_ms;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of nodes in the analysis.
|
* The number of nodes in the analysis.
|
||||||
*/
|
*/
|
||||||
unsigned long num_nodes;
|
unsigned long num_nodes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of elements in the analysis.
|
* The number of elements in the analysis.
|
||||||
*/
|
*/
|
||||||
unsigned long num_elems;
|
unsigned long num_elems;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of boundary conditions in the analysis.
|
* The number of boundary conditions in the analysis.
|
||||||
*/
|
*/
|
||||||
unsigned long num_bcs;
|
unsigned long num_bcs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of prescribed forces in the analysis.
|
* The number of prescribed forces in the analysis.
|
||||||
*/
|
*/
|
||||||
unsigned long num_forces;
|
unsigned long num_forces;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of tie constraints in the analysis.
|
* The number of tie constraints in the analysis.
|
||||||
*/
|
*/
|
||||||
unsigned long num_ties;
|
unsigned long num_ties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of equation constraints in the analysis.
|
* The number of equation constraints in the analysis.
|
||||||
*/
|
*/
|
||||||
unsigned long num_eqns;
|
unsigned long num_eqns;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The resultant nodal displacement from the FE analysis.
|
* The resultant nodal displacement from the FE analysis.
|
||||||
* `nodal_displacements` is a 2D vector where each row
|
* `nodal_displacements` is a 2D vector where each row
|
||||||
* correspond to a node, and the columns correspond to
|
* correspond to a node, and the columns correspond to
|
||||||
* `[d_x, d_y, d_z, theta_x, theta_y, theta_z]`
|
* `[d_x, d_y, d_z, theta_x, theta_y, theta_z]`
|
||||||
*/
|
*/
|
||||||
std::vector<std::vector<double> > nodal_displacements;
|
std::vector<std::vector<double>> nodal_displacements;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The resultant nodal forces from the FE analysis.
|
* The resultant nodal forces from the FE analysis.
|
||||||
* `nodal_displacements` is a 2D vector where each row
|
* `nodal_displacements` is a 2D vector where each row
|
||||||
* correspond to a node, and the columns correspond to
|
* correspond to a node, and the columns correspond to
|
||||||
* `[f_x, f_y, f_z, m_x, m_y, m_z]`
|
* `[f_x, f_y, f_z, m_x, m_y, m_z]`
|
||||||
*/
|
*/
|
||||||
std::vector<std::vector<double> > nodal_forces;
|
std::vector<std::vector<double>> nodal_forces;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The resultant forces associated with ties between nodes.
|
* The resultant forces associated with ties between nodes.
|
||||||
* `tie_forces` is a 2D vector where each row
|
* `tie_forces` is a 2D vector where each row
|
||||||
* correspond to a tie, and the columns correspond to
|
* correspond to a tie, and the columns correspond to
|
||||||
* `[f_x, f_y, f_z, f_rot_x, f_rot_y, f_rot_z]`
|
* `[f_x, f_y, f_z, f_rot_x, f_rot_y, f_rot_z]`
|
||||||
*/
|
*/
|
||||||
std::vector<std::vector<double> > tie_forces;
|
std::vector<std::vector<double>> tie_forces;
|
||||||
|
|
||||||
};
|
/**
|
||||||
|
* The resultant forces associated each element.
|
||||||
|
* `element_forces` is a 2D vector where each row
|
||||||
|
* correspond to an element, and the columns correspond to
|
||||||
|
* `[f1_x, f1_y, f1_z, f1_rot_x, f1_rot_y, f1_rot_z,
|
||||||
|
* f2_x, f2_y, f2_z, f2_rot_x, f2_rot_y, f2_rot_z]`
|
||||||
|
*/
|
||||||
|
std::vector<std::vector<double>> element_forces;
|
||||||
|
};
|
||||||
|
|
||||||
} //namespace fea
|
} // namespace fea
|
||||||
|
|
||||||
|
#endif // THREEDBEAMFEA_SUMMARY_H
|
||||||
|
|
||||||
#endif //THREEDBEAMFEA_SUMMARY_H
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
/*!
|
/*!
|
||||||
* \file threed_beam_fea.h
|
* \file threed_beam_fea.h
|
||||||
*
|
*
|
||||||
* \author Ryan Latture
|
* \author Ryan Latture
|
||||||
* \date 8-12-15
|
* \date 8-12-15
|
||||||
*
|
*
|
||||||
* Contains declarations for 3D beam FEA functions.
|
* Contains declarations for 3D beam FEA functions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Copyright 2015. All rights reserved.
|
// Copyright 2015. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
@ -46,192 +46,228 @@
|
||||||
#include <Eigen/SparseCore>
|
#include <Eigen/SparseCore>
|
||||||
|
|
||||||
#include "containers.h"
|
#include "containers.h"
|
||||||
|
#include "csv_parser.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "summary.h"
|
#include "summary.h"
|
||||||
#include "csv_parser.h"
|
|
||||||
|
|
||||||
namespace fea {
|
namespace fea {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dense global stiffness matrix
|
* Dense global stiffness matrix
|
||||||
*/
|
*/
|
||||||
typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> GlobalStiffMatrix;
|
typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> GlobalStiffMatrix;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An elemental matrix in local coordinates. Will either be the elemental stiffness matrix or the global-to-local rotation matrix
|
* An elemental matrix in local coordinates. Will either be the elemental
|
||||||
*/
|
* stiffness matrix or the global-to-local rotation matrix
|
||||||
typedef Eigen::Matrix<double, 12, 12, Eigen::RowMajor> LocalMatrix;
|
*/
|
||||||
|
typedef Eigen::Matrix<double, 12, 12, Eigen::RowMajor> LocalMatrix;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vector that stores the nodal forces, i.e. the variable \f$[F]\f$ in \f$[K][Q]=[F]\f$,
|
* Vector that stores the nodal forces, i.e. the variable \f$[F]\f$ in
|
||||||
* where \f$[K]\f$ is the global stiffness matrix and \f$[Q]\f$ contains the nodal displacements
|
* \f$[K][Q]=[F]\f$, where \f$[K]\f$ is the global stiffness matrix and
|
||||||
*/
|
* \f$[Q]\f$ contains the nodal displacements
|
||||||
typedef Eigen::Matrix<double, Eigen::Dynamic, 1> ForceVector;
|
*/
|
||||||
|
typedef Eigen::Matrix<double, Eigen::Dynamic, 1> ForceVector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sparse matrix that is used internally to hold the global stiffness matrix
|
* Sparse matrix that is used internally to hold the global stiffness matrix
|
||||||
*/
|
*/
|
||||||
typedef Eigen::SparseMatrix<double> SparseMat;
|
typedef Eigen::SparseMatrix<double> SparseMat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Calculates the distance between 2 nodes.
|
* @brief Calculates the distance between 2 nodes.
|
||||||
* @details Calculates the original Euclidean distance between 2 nodes in the x-y plane.
|
* @details Calculates the original Euclidean distance between 2 nodes in the
|
||||||
*
|
* x-y plane.
|
||||||
* @param[in] n1 `fea::Node`. Nodal coordinates of first point.
|
*
|
||||||
* @param[in] n2 `fea::Node`. Nodal coordinates of second point.
|
* @param[in] n1 `fea::Node`. Nodal coordinates of first point.
|
||||||
*
|
* @param[in] n2 `fea::Node`. Nodal coordinates of second point.
|
||||||
* @return <B>Distance</B> `double`. The distance between the nodes.
|
*
|
||||||
*/
|
* @return <B>Distance</B> `double`. The distance between the nodes.
|
||||||
inline double norm(const Node &n1, const Node &n2);
|
*/
|
||||||
|
inline double norm(const Node &n1, const Node &n2);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Assembles the global stiffness matrix.
|
* @brief Assembles the global stiffness matrix.
|
||||||
*/
|
*/
|
||||||
class GlobalStiffAssembler {
|
class GlobalStiffAssembler {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Default constructor.
|
||||||
|
* @details Initializes all entries in member matrices to 0.0.
|
||||||
|
*/
|
||||||
|
GlobalStiffAssembler() {
|
||||||
|
Kelem.setZero();
|
||||||
|
Klocal.setZero();
|
||||||
|
Aelem.setZero();
|
||||||
|
AelemT.setZero();
|
||||||
|
SparseKelem.resize(12, 12);
|
||||||
|
SparseKelem.reserve(40);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Default constructor.
|
* @brief Assembles the global stiffness matrix.
|
||||||
* @details Initializes all entries in member matrices to 0.0.
|
* @details The input stiffness matrix is modified in place to contain the
|
||||||
*/
|
* correct values for the given job. Assumes that the input stiffness matrix
|
||||||
GlobalStiffAssembler() {
|
* has the correct dimensions and all values are initially set to zero.
|
||||||
Kelem.setZero();
|
*
|
||||||
Klocal.setZero();
|
* @param Kg `fea::GlobalStiffMatrix`. Modified in place. After evaluation, Kg
|
||||||
Aelem.setZero();
|
* contains the correct values for the global stiffness matrix due to the
|
||||||
AelemT.setZero();
|
* input Job.
|
||||||
SparseKelem.resize(12, 12);
|
* @param[in] job `fea::Job`. Current Job to analyze contains node, element,
|
||||||
SparseKelem.reserve(40);
|
* and property lists.
|
||||||
};
|
* @param[in] ties `std::vector<fea::Tie>`. Vector of ties that apply to
|
||||||
|
* attach springs of specified stiffness to all nodal degrees of freedom
|
||||||
|
* between each set of nodes indicated.
|
||||||
|
*/
|
||||||
|
void operator()(SparseMat &Kg, const Job &job, const std::vector<Tie> &ties);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Assembles the global stiffness matrix.
|
* @brief Updates the elemental stiffness matrix for the `ith` element.
|
||||||
* @details The input stiffness matrix is modified in place to contain the correct values for the given job.
|
*
|
||||||
* Assumes that the input stiffness matrix has the correct dimensions and all values are initially set to zero.
|
* @param[in] i `unsigned int`. Specifies the ith element for which the
|
||||||
*
|
* elemental stiffness matrix is calculated.
|
||||||
* @param Kg `fea::GlobalStiffMatrix`. Modified in place. After evaluation, Kg contains the correct values for
|
* @param[in] job `Job`. Current `fea::Job` to analyze contains node, element,
|
||||||
* the global stiffness matrix due to the input Job.
|
* and property lists.
|
||||||
* @param[in] job `fea::Job`. Current Job to analyze contains node, element, and property lists.
|
*/
|
||||||
* @param[in] ties `std::vector<fea::Tie>`. Vector of ties that apply to attach springs of specified stiffness to
|
void calcKelem(unsigned int i, const Job &job);
|
||||||
* all nodal degrees of freedom between each set of nodes indicated.
|
|
||||||
*/
|
|
||||||
void operator()(SparseMat &Kg, const Job &job, const std::vector<Tie> &ties);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Updates the elemental stiffness matrix for the `ith` element.
|
* @brief Updates the rotation and transposed rotation matrices.
|
||||||
*
|
* @details The rotation matrices `Aelem` and `AelemT` are updated based on
|
||||||
* @param[in] i `unsigned int`. Specifies the ith element for which the elemental stiffness matrix is calculated.
|
* the 2 specified unit normal vectors along the local x and y directions.
|
||||||
* @param[in] job `Job`. Current `fea::Job` to analyze contains node, element, and property lists.
|
*
|
||||||
*/
|
* @param[in] nx `Eigen::Matrix3d`. Unit normal vector in global space
|
||||||
void calcKelem(unsigned int i, const Job &job);
|
* parallel to the beam element's local x-direction.
|
||||||
|
* @param[in] ny `Eigen::Matrix3d`. Unit normal vector in global space
|
||||||
|
* parallel to the beam element's local y-direction.
|
||||||
|
*/
|
||||||
|
void calcAelem(const Eigen::Vector3d &nx, const Eigen::Vector3d &nz);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Updates the rotation and transposed rotation matrices.
|
* @brief Returns the currently stored elemental stiffness matrix.
|
||||||
* @details The rotation matrices `Aelem` and `AelemT` are updated based on the 2 specified unit
|
* @return <B>Elemental stiffness matrix</B> `fea::LocalMatrix`.
|
||||||
* normal vectors along the local x and y directions.
|
*/
|
||||||
*
|
LocalMatrix getKelem() { return Kelem; }
|
||||||
* @param[in] nx `Eigen::Matrix3d`. Unit normal vector in global space parallel to the beam element's local x-direction.
|
|
||||||
* @param[in] ny `Eigen::Matrix3d`. Unit normal vector in global space parallel to the beam element's local y-direction.
|
|
||||||
*/
|
|
||||||
void calcAelem(const Eigen::Vector3d &nx, const Eigen::Vector3d &nz);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the currently stored elemental stiffness matrix.
|
* @brief Returns the currently stored rotation matrix.
|
||||||
* @return <B>Elemental stiffness matrix</B> `fea::LocalMatrix`.
|
* @return <B>Rotation matrix</B> `fea::LocalMatrix`.
|
||||||
*/
|
*/
|
||||||
LocalMatrix getKelem() {
|
LocalMatrix getAelem() { return Aelem; }
|
||||||
return Kelem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
std::vector<LocalMatrix> getPerElemKlocalAelem() const;
|
||||||
* @brief Returns the currently stored rotation matrix.
|
|
||||||
* @return <B>Rotation matrix</B> `fea::LocalMatrix`.
|
|
||||||
*/
|
|
||||||
LocalMatrix getAelem() {
|
|
||||||
return Aelem;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LocalMatrix Kelem;
|
LocalMatrix Kelem;
|
||||||
/**<Elemental stiffness matrix in global coordinate system.*/
|
/**<Elemental stiffness matrix in global coordinate system.*/
|
||||||
LocalMatrix Klocal;
|
LocalMatrix Klocal;
|
||||||
/**<Elemental stiffness matrix in local coordinate system (used as temporary variable).*/
|
/**<Elemental stiffness matrix in local coordinate system (used as temporary
|
||||||
LocalMatrix Aelem;
|
* variable).*/
|
||||||
/**<Rotation matrix. Transforms `Klocal` to global coorinate system (`Kelem`).*/
|
LocalMatrix Aelem;
|
||||||
LocalMatrix AelemT;
|
/**<Rotation matrix. Transforms `Klocal` to global coorinate system
|
||||||
/**<Transposed rotation matrix.*/
|
* (`Kelem`).*/
|
||||||
SparseMat SparseKelem;/**<Sparse representation of elemental stiffness matrix.*/
|
LocalMatrix AelemT;
|
||||||
};
|
/**<Transposed rotation matrix.*/
|
||||||
|
SparseMat
|
||||||
|
SparseKelem; /**<Sparse representation of elemental stiffness matrix.*/
|
||||||
|
|
||||||
/**
|
std::vector<LocalMatrix>
|
||||||
* @brief Loads the boundary conditions into the global stiffness matrix and force vector.
|
perElemKlocalAelem; //[i] holds the local stiffness matrix of the ith beam
|
||||||
* @details Boundary conditions are enforced via Lagrange multipliers. The reaction force
|
// element times the transformation matrix from local
|
||||||
* due to imposing the boundary condition will be appended directly onto the returned
|
// to global. This is used after the simulation in
|
||||||
* nodal displacements in the order the boundary conditions were specified.
|
// order to find the per element forces
|
||||||
*
|
};
|
||||||
* @param Kg `fea::GlobalStiffnessMatrix`. Coefficients are modified in place to reflect Lagrange multipliers.
|
|
||||||
* Assumes `Kg` has the correct dimensions.
|
|
||||||
* @param force_vec `fea::ForceVector`. Right hand side of the \f$[K][Q]=[F]\f$ equation of the FE analysis.
|
|
||||||
* @param[in] BCs `std::vector<fea::BC>`. Vector of `BC`'s to apply to the current analysis.
|
|
||||||
* @param[in] num_nodes `unsigned int`. The number of nodes in the current job being analyzed.
|
|
||||||
* Used to calculate the position to insert border coefficients associated
|
|
||||||
* with enforcing boundary conditions via Langrange multipliers.
|
|
||||||
*/
|
|
||||||
void loadBCs(SparseMat &Kg, ForceVector &force_vec, const std::vector<BC> &BCs, unsigned int num_nodes);
|
|
||||||
|
|
||||||
void loadEquations(SparseMat &Kg, const std::vector<Equation> &equations, unsigned int num_nodes, unsigned int num_bcs);
|
/**
|
||||||
|
* @brief Loads the boundary conditions into the global stiffness matrix and
|
||||||
|
* force vector.
|
||||||
|
* @details Boundary conditions are enforced via Lagrange multipliers. The
|
||||||
|
* reaction force due to imposing the boundary condition will be appended
|
||||||
|
* directly onto the returned nodal displacements in the order the boundary
|
||||||
|
* conditions were specified.
|
||||||
|
*
|
||||||
|
* @param Kg `fea::GlobalStiffnessMatrix`. Coefficients are modified in place to
|
||||||
|
* reflect Lagrange multipliers. Assumes `Kg` has the correct dimensions.
|
||||||
|
* @param force_vec `fea::ForceVector`. Right hand side of the \f$[K][Q]=[F]\f$
|
||||||
|
* equation of the FE analysis.
|
||||||
|
* @param[in] BCs `std::vector<fea::BC>`. Vector of `BC`'s to apply to the
|
||||||
|
* current analysis.
|
||||||
|
* @param[in] num_nodes `unsigned int`. The number of nodes in the current job
|
||||||
|
* being analyzed. Used to calculate the position to insert border coefficients
|
||||||
|
* associated with enforcing boundary conditions via Langrange multipliers.
|
||||||
|
*/
|
||||||
|
void loadBCs(SparseMat &Kg, ForceVector &force_vec, const std::vector<BC> &BCs,
|
||||||
|
unsigned int num_nodes);
|
||||||
|
|
||||||
/**
|
void loadEquations(SparseMat &Kg, const std::vector<Equation> &equations,
|
||||||
* @brief Loads any tie constraints into the set of triplets that will become the global stiffness matrix.
|
unsigned int num_nodes, unsigned int num_bcs);
|
||||||
* @details Tie constraints are enforced via linear springs between the 2 specified
|
|
||||||
* nodes. The `lmult` member variable is used as the spring constant for displacement degrees
|
|
||||||
* of freedom, e.g. 0, 1, and 2. `rmult` is used for rotational degrees of freedom, e.g. 3, 4, and 5.
|
|
||||||
*
|
|
||||||
* @param triplets `std::vector< Eigen::Triplet< double > >`. A vector of triplets that store data in the
|
|
||||||
* form (i, j, value) that will be become the sparse global stiffness matrix.
|
|
||||||
* @param[in] ties `std::vector<fea::Tie>`. Vector of `Tie`'s to apply to the current analysis.
|
|
||||||
*/
|
|
||||||
void loadTies(std::vector<Eigen::Triplet<double> > &triplets, const std::vector<Tie> &ties);
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Loads any tie constraints into the set of triplets that will become
|
||||||
|
* the global stiffness matrix.
|
||||||
|
* @details Tie constraints are enforced via linear springs between the 2
|
||||||
|
* specified nodes. The `lmult` member variable is used as the spring constant
|
||||||
|
* for displacement degrees of freedom, e.g. 0, 1, and 2. `rmult` is used for
|
||||||
|
* rotational degrees of freedom, e.g. 3, 4, and 5.
|
||||||
|
*
|
||||||
|
* @param triplets `std::vector< Eigen::Triplet< double > >`. A vector of
|
||||||
|
* triplets that store data in the form (i, j, value) that will be become the
|
||||||
|
* sparse global stiffness matrix.
|
||||||
|
* @param[in] ties `std::vector<fea::Tie>`. Vector of `Tie`'s to apply to the
|
||||||
|
* current analysis.
|
||||||
|
*/
|
||||||
|
void loadTies(std::vector<Eigen::Triplet<double>> &triplets,
|
||||||
|
const std::vector<Tie> &ties);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Computes the forces in the tie elements based on the nodal displacements of the FE
|
* @brief Computes the forces in the tie elements based on the nodal
|
||||||
* analysis and the spring constants provided in `ties`.
|
* displacements of the FE analysis and the spring constants provided in `ties`.
|
||||||
*
|
*
|
||||||
* @param[in] ties `std::vector<Tie>`. Vector of `fea::Tie`'s to applied to the current analysis.
|
* @param[in] ties `std::vector<Tie>`. Vector of `fea::Tie`'s to applied to the
|
||||||
* @param[in] nodal_displacements `std::vector < std::vector < double > >`. The resultant nodal displacements of the analysis.
|
* current analysis.
|
||||||
* @return Tie forces. `std::vector < std::vector < double > >`
|
* @param[in] nodal_displacements `std::vector < std::vector < double > >`. The
|
||||||
*/
|
* resultant nodal displacements of the analysis.
|
||||||
std::vector<std::vector<double> > computeTieForces(const std::vector<Tie> &ties,
|
* @return Tie forces. `std::vector < std::vector < double > >`
|
||||||
const std::vector<std::vector<double> > &nodal_displacements);
|
*/
|
||||||
|
std::vector<std::vector<double>>
|
||||||
|
computeTieForces(const std::vector<Tie> &ties,
|
||||||
|
const std::vector<std::vector<double>> &nodal_displacements);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Loads the prescribed forces into the force vector.
|
* @brief Loads the prescribed forces into the force vector.
|
||||||
*
|
*
|
||||||
* @param force_vec `ForceVector`. Right hand side of the \f$[K][Q]=[F]\f$ equation of the FE analysis.
|
* @param force_vec `ForceVector`. Right hand side of the \f$[K][Q]=[F]\f$
|
||||||
* @param[in] forces std::vector<Force>. Vector of prescribed forces to apply to the current analysis.
|
* equation of the FE analysis.
|
||||||
*/
|
* @param[in] forces std::vector<Force>. Vector of prescribed forces to apply to
|
||||||
void loadForces(SparseMat &force_vec, const std::vector<Force> &forces);
|
* the current analysis.
|
||||||
|
*/
|
||||||
|
void loadForces(SparseMat &force_vec, const std::vector<Force> &forces);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Solves the finite element analysis defined by the input Job, boundary conditions, and prescribed nodal forces.
|
* @brief Solves the finite element analysis defined by the input Job, boundary
|
||||||
* @details Solves \f$[K][Q]=[F]\f$ for \f$[Q]\f$, where \f$[K]\f$ is the global stiffness matrix,
|
* conditions, and prescribed nodal forces.
|
||||||
* \f$[Q]\f$ contains the nodal displacements, and \f$[Q]\f$ contains the nodal forces.
|
* @details Solves \f$[K][Q]=[F]\f$ for \f$[Q]\f$, where \f$[K]\f$ is the global
|
||||||
*
|
* stiffness matrix, \f$[Q]\f$ contains the nodal displacements, and \f$[Q]\f$
|
||||||
* @param[in] job `fea::Job`. Contains the node, element, and property lists for the mesh.
|
* contains the nodal forces.
|
||||||
* @param[in] BCs `std::vector<fea::BC>`. Vector of boundary conditions to apply to the nodal degrees of freedom contained in the job.
|
*
|
||||||
* @param[in] forces `std::vector<fea::Force>`. Vector of prescribed forces to apply to the nodal degrees of freedom contained in the job.
|
* @param[in] job `fea::Job`. Contains the node, element, and property lists for
|
||||||
* @param[in] ties `std::vector<fea::Tie>`. Vector of ties that apply to attach springs of specified stiffness to
|
* the mesh.
|
||||||
* all nodal degrees of freedom between each set of nodes indicated.
|
* @param[in] BCs `std::vector<fea::BC>`. Vector of boundary conditions to apply
|
||||||
*
|
* to the nodal degrees of freedom contained in the job.
|
||||||
* @return <B>Summary</B> `fea::Summary`. Summary containing the results of the analysis.
|
* @param[in] forces `std::vector<fea::Force>`. Vector of prescribed forces to
|
||||||
*/
|
* apply to the nodal degrees of freedom contained in the job.
|
||||||
Summary solve(const Job &job,
|
* @param[in] ties `std::vector<fea::Tie>`. Vector of ties that apply to attach
|
||||||
const std::vector<BC> &BCs,
|
* springs of specified stiffness to all nodal degrees of freedom between each
|
||||||
const std::vector<Force> &forces,
|
* set of nodes indicated.
|
||||||
const std::vector<Tie> &ties,
|
*
|
||||||
const std::vector<Equation> &equations,
|
* @return <B>Summary</B> `fea::Summary`. Summary containing the results of the
|
||||||
const Options &options);
|
* analysis.
|
||||||
|
*/
|
||||||
|
Summary solve(const Job &job, const std::vector<BC> &BCs,
|
||||||
|
const std::vector<Force> &forces, const std::vector<Tie> &ties,
|
||||||
|
const std::vector<Equation> &equations, const Options &options);
|
||||||
} // namespace fea
|
} // namespace fea
|
||||||
|
|
||||||
#endif // THREED_BEAM_FEA_H
|
#endif // THREED_BEAM_FEA_H
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue