Element example#
Description#
This element is for a rigid link utilizing a Lagrange multiplier for enforcing the condition.
Code Listing#
#include <Error_messager.h>
#include <Behavior.h>
#include <External_parameter.h>
#include <P_element.h>
#include <Global_matrix.h>
#include <Mesh.h>
#include <Utility_mesh.h>
#include <Node.h>
#include <Special_vector.h>
#include <GeomSpace.h>
#include <Print.h>
class RIGID_LINK : public D_ELEMENT {
public :
int nb_displ;
virtual int dof_location(int)const;
RIGID_LINK() { }
virtual void setup_dofs(const char* key);
virtual ~RIGID_LINK();
virtual INTEGRATION_RESULT* internal_reaction(bool,VECTOR&,SMATRIX&,bool only_get_tg_matrix=FALSE);
};
INSTALL_ELEMENT(MECHANICAL_MESH,rigid_link,_2D,ST_LINE,RIGID_LINK)
INSTALL_ELEMENT(MECHANICAL_MESH,rigid_link,_3D,ST_LINE,RIGID_LINK)
int RIGID_LINK::dof_location(int idof)const
{ return (idof<nb_displ) ? DOF_NODE_ID : DOF_ELEMENT_ID;
}
void RIGID_LINK::setup_dofs(const char*)
{
size_dofs(!node*geometry->space_dimension()+1);
static DOF_TYPE u_name[3]={DOF::translate("U1",DOF_NODE_ID),
DOF::translate("U2",DOF_NODE_ID),
DOF::translate("U3",DOF_NODE_ID)};
static DOF_TYPE RLF = DOF::translate("RLF",DOF_ELEMENT_ID);
int tot=0;
for(int in=0;in<nb_node();in++) {
for(int idime=0;idime<space_dimension();idime++) {
dof_type[tot] = u_name[idime];
map_dof_to_node[tot] = get_node(in);
tot++;
}
}
nb_displ = tot;
dof_type[tot]=RLF;
map_dof_to_node[tot] = NULL;
}
RIGID_LINK::~RIGID_LINK() {}
INTEGRATION_RESULT* RIGID_LINK::internal_reaction(bool ics,
VECTOR& resi, SMATRIX& stiff,bool check)
{
MATRIX elem_coord;
VECTOR Dof(nb_dof()), dDof(nb_dof());
int end = nb_dof()-1;
get_elem_d_dof_tot(Dof);
double force = Dof[end];
VECTOR x1 = get_node(0)->get_coordw(END_OF_INCREMENT);
VECTOR x2 = get_node(1)->get_coordw(END_OF_INCREMENT);
VECTOR X1 = get_node(0)->get_coordw(BEGINNING_OF_PROBLEM);
VECTOR X2 = get_node(1)->get_coordw(BEGINNING_OF_PROBLEM);
VECTOR dX = X2-X1;
VECTOR dx = x2-x1;
double R0 = sqrt(dX|dX);
double R1 = sqrt(dx|dx);
VECTOR B = dx*(1.0/R1);
SMATRIX dBdX = B^B;
dBdX.add_to_diagonal(1.0);
dBdX *= 1.0/R1;
SMATRIX mdBdX = -1.0*dBdX;
VECTOR subF1, subF2;
int sd=space_dimension();
subF1.reassign(sd,resi,0); subF1= B*(-force);
subF2.reassign(sd,resi,sd); subF2= B*force;
resi[end] = R1 - R0;
if (ics) {
stiff = 0.0;
MATRIX subS11(sd,sd,stiff,0,0); subS11 = mdBdX*(-force);
MATRIX subS12(sd,sd,stiff,0,sd); subS12 = dBdX*(-force);
MATRIX subS21(sd,sd,stiff,sd,0); subS21 = mdBdX*(force);
MATRIX subS22(sd,sd,stiff,sd,sd); subS22 = dBdX*(force);
for (int c=0;c<sd;c++) {
stiff(c, end) = -B[c];
stiff(sd+c,end) = B[c];
stiff(end,c) = (x2[c]-x1[c])*(-1.0/R1);
stiff(end,sd+c) = (x2[c]-x1[c])*(1.0/R1);
}
stiff(end,end) = 0.0;
}
return NULL;
}