• 12
• 9
• 9
• 13
• 10

# Truss Bridges

This topic is 4433 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I am using the direct stiffness method to [hopefully/eventually] find all the internal member forces in a truss bridge. I am having problems getting all the forces into my force vector. The force vector is an array with the size of the number of global degrees of freedom on the truss bridge. I can't figure out how to put in the weight of the truss itself. Does it work to find the total weight of the truss, and then distribute evenly among the base joints? Nothing I do seems to be giving me the right values. Here is my function currently, if you want to look at it:
int CBridge::GetMemberForce(BOOL* bTension, BOOL* bCompression)
{
char TestString[512];
//the number of global degrees of freedom
int nGlobalDegreesFreedom = 0;
//global degrees of freedom array, the array position is the degree of freedom number,
//the value at that position is the joint, currently all x's will be even, y's odd
int GlobalDOF[MAX_JOINTS*2];
//used to track GlobalDOF position
int Tracker = 0;
//cycle through all the joints
for (int i = 0; Joints.x != 0 || Joints.y != 0 || i == 0; i++)
{
//continue only if the joint is not restrained, by an abutment or pier
if (m_nRestrainedJoints[0] != i && m_nRestrainedJoints[1] != i && m_nRestrainedJoints[2] != i &&
m_nRestrainedJoints[3] != i && m_nRestrainedJoints[4] != i)
{
GlobalDOF[Tracker] = i;
GlobalDOF[Tracker+1] = i;
Tracker+=2;
}
}

//set the number of global degrees of freedom to the value of tracker
nGlobalDegreesFreedom = Tracker;

//a fancy way of making a two dimensional array of unknown size
//structural stiffness matrix Ks[nGlobalDegreesFreedom][nGlobalDegreesFreedom]
double** Ks = new double*[nGlobalDegreesFreedom];
for ( int n = 0; n < nGlobalDegreesFreedom; n++ )
Ks[n] = new double[nGlobalDegreesFreedom];

//initialize all members of the Ks matrix to 0
for (int Ksx = 0; Ksx < nGlobalDegreesFreedom; Ksx++)
{
for (int Ksy = 0; Ksy < nGlobalDegreesFreedom; Ksy++)
{
Ks[Ksx][Ksy] = 0.00;
}
}

//cycle through each member
for (int i = 0; Members.MetalListPos; i++)
{
//get stiffness matrix for each member
double L = Members.Length;
double c = (Joints[Members.ToJoint].x - Joints[Members.FromJoint].x) / L;
double s = (Joints[Members.ToJoint].y - Joints[Members.FromJoint].y) / L;
double EAOverL = (Members.Elasticity / Members.CrossSectionalArea) / L;

double K[4][4];
K[0][0] = (c * c) * EAOverL; K[1][0] = (c * s) * EAOverL; K[2][0] = -1 * (c*c) * EAOverL;
K[3][0] = -1 * (c*s) * EAOverL; K[0][1] = (c * s) * EAOverL; K[1][1] = (s * s) * EAOverL;
K[2][1] = -1 * (c * s) * EAOverL; K[3][1] = -1 * (s * s) * EAOverL; K[0][2] = -1 * (c * c) * EAOverL;
K[1][2] = -1 * (c * s) * EAOverL; K[2][2] = (c * c) * EAOverL; K[3][2] = (c * s) * EAOverL;
K[0][3] = -1 * (c * s) * EAOverL; K[1][3] = -1 * (s * s) * EAOverL; K[2][3] = (c * s) * EAOverL;
K[3][3] = (s * s) * EAOverL;

//the global degree of freedom number
int One=-1, Two=-1, Thr=-1, Fou=-1;

for (int x = 0; x < nGlobalDegreesFreedom; x+=2)
{
if (GlobalDOF[x] == Members.FromJoint)
{
One = x; Two = x + 1;
}
}

for (int x = 0; x < nGlobalDegreesFreedom; x+=2)
{
if (GlobalDOF[x] == Members.ToJoint)
{
Thr = x; Fou = x + 1;
}
}

sprintf(TestString,"Member: %i  Global DOF: (%i %i) (%i %i)\n",i,One,Two,Thr,Fou);
OutputDebugString(TestString);

if (One != -1 && Two != -1 && Thr != -1 && Fou != -1)
{
Ks[One][One] += K[0][0]; Ks[One][Two] += K[1][0]; Ks[One][Thr] += K[2][0]; Ks[One][Fou] += K[3][0];
Ks[Two][One] += K[0][1]; Ks[Two][Two] += K[1][1]; Ks[Two][Thr] += K[2][1]; Ks[Two][Fou] += K[3][1];
Ks[Thr][One] += K[0][2]; Ks[Thr][Two] += K[1][2]; Ks[Thr][Thr] += K[2][2]; Ks[Thr][Fou] += K[3][2];
Ks[Fou][One] += K[0][3]; Ks[Fou][Two] += K[1][3]; Ks[Fou][Thr] += K[2][3]; Ks[Fou][Fou] += K[3][3];
}
else if (One != -1 && Two != -1)
{
Ks[One][One] += K[0][0]; Ks[One][Two] += K[1][0];
Ks[Two][One] += K[0][1]; Ks[Two][Two] += K[1][1];
}
else if (Thr != -1 && Fou != -1)
{
Ks[Thr][Thr] += K[2][2]; Ks[Thr][Fou] += K[3][2];
Ks[Fou][Thr] += K[2][3]; Ks[Fou][Fou] += K[3][3];
}
}

char KsString[512];
sprintf(KsString,"Ks:");
OutputDebugString(KsString);
for (int Ksy = 0; Ksy < nGlobalDegreesFreedom; Ksy++)
{
OutputDebugString("\n");
for (int Ksx = 0; Ksx < nGlobalDegreesFreedom; Ksx++)
{
sprintf(KsString,"%0.4f ",Ks[Ksx][Ksy]);
OutputDebugString(KsString);
}
}

//now find the force vector
double *p = new double[nGlobalDegreesFreedom];
//init the vector to 0
for (int i = 0; i < nGlobalDegreesFreedom; i++)
p = 0;

//somehow fill out the p vector, according to global degrees of freedom
//THIS IS WHERE I AM HAVING TROUBLE
//it needs to hold the weight of the bridge itself, a car, and the road surface

double Weight = 0.0;
for (int i = 0; Members.MetalListPos; i++)
{
int nActualSize =  GetDiameter(Members.SizeListPos);

if (Members.MetalListPos == 1 && Members.TypeListPos == 1)
{
Weight += 0.00785 * Members.Length * pow(nActualSize,2) * 4.905;
}
else if (Members.MetalListPos == 1 && Members.TypeListPos == 2)
{
Weight += 0.0014915 * Members.Length * pow(nActualSize,2)* 4.905;
}
else if (Members.MetalListPos == 2 && Members.TypeListPos == 1)
{
Weight += 0.00785 * Members.Length * pow(nActualSize,2)* 4.905;
}
else if (Members.MetalListPos == 2 && Members.TypeListPos == 2)
{
Weight += 0.0014915 * Members.Length * pow(nActualSize,2)* 4.905;
}
else if (Members.MetalListPos == 3 && Members.TypeListPos == 1)
{
Weight += 0.00785 * Members.Length * pow(nActualSize,2)* 4.905;
}
else if (Members.MetalListPos == 3 && Members.TypeListPos == 2)
{
Weight += 0.0014915 * Members.Length * pow(nActualSize,2)* 4.905;
}
}

//currently hardcoded, just for testing
//distribute the weight among the base joints
p[1] = -Weight/5;
p[3] = -Weight/5 - 1.75*180000*(2.5);  //1.75*180000*(2.5) is the weight of the truck including dynamic load allowance
p[5] = -Weight/5 - 1.75*180000*(2.5);
p[7] = -Weight/5;

//invert ks, then mult by p to get d
double	e;
int nColumns = nGlobalDegreesFreedom;

//this next chunk of code inverts Ks, or it is supposed to anyway
for (int k = 0 ; k < nColumns; ++k)
{
e = Ks[k][k];
Ks[k][k] = 1.0;
if (e == 0.0)
break;
for (int j = 0 ; j < nColumns ; ++j)
Ks[k][j] = Ks[k][j] / e;
for (int i = 0 ; i < nColumns ; ++i)
{
if (i != k)
{
e = Ks[k];
Ks[k] = 0.0;
for (j = 0 ; j < nColumns ; ++j)
Ks[j] = Ks[j] - e * Ks[k][j];
}
}
}

//the displacement vector
double *d = new double[nGlobalDegreesFreedom];
//init it to all 0's
for (int i = 0; i < nGlobalDegreesFreedom; i++)
d = 0;

//this should multiply the now inverted Ks by p to get the d vector
for (int i = 0; i < nGlobalDegreesFreedom; i++)
{
double Tracker = 0.0;
for (int i2 = 0; i2 < nGlobalDegreesFreedom; i2++)
{
Tracker += p[i2] * Ks[i2];
}
d = Tracker;
}

OutputDebugString("\n");

//cycle through all members
for (int i = 0; Members.MetalListPos; i++)
{
double L = Members.Length;
double c = (Joints[Members.ToJoint].x - Joints[Members.FromJoint].x) / L;
double s = (Joints[Members.ToJoint].y - Joints[Members.FromJoint].y) / L;
double EAOverL = (Members.Elasticity / Members.CrossSectionalArea) / L;

int One=-1, Two=-1, Three=-1, Four=-1;

for (int x = 0; x < nGlobalDegreesFreedom; x+=2)
{
if (GlobalDOF[x] == Members.FromJoint)
{
One = x; Two = x + 1;
}
}

for (int x = 0; x < nGlobalDegreesFreedom; x+=2)
{
if (GlobalDOF[x] == Members.ToJoint)
{
Three = x; Four = x + 1;
}
}

//find n, the internal member force
double DOne = 0, DTwo = 0, DThr = 0, DFou = 0;
if (One != -1) DOne = d[One]; else DOne = 0;
if (Two != -1) DTwo = d[Two]; else DTwo = 0;
if (Three != -1) DThr = d[Three]; else DThr = 0;
if (Four != -1) DFou = d[Four]; else DFou = 0;
double n = EAOverL*(c*(DThr-DOne) + s*(DFou - DTwo));

//find weather it is in tension or compression
char * TorC = "";
if (n < 0)
TorC = "compression";
else if (n > 0)
TorC = "tension";
else
TorC = "neither";

//output the members and the internal member force
char TempString[512];
sprintf(TempString,"Member:  %i   IMF:  %0.1f %s\n",i+1,abs(n)/1000,TorC);
OutputDebugString(TempString);
}
return 0;
}


These are the values I am getting: Member: 1 IMF: 481.3 compression Member: 2 IMF: 331.4 tension Member: 3 IMF: 299.7 tension Member: 4 IMF: 331.4 tension Member: 5 IMF: 481.3 compression Member: 6 IMF: 838.0 compression Member: 7 IMF: 1682.4 compression Member: 8 IMF: 838.0 compression Member: 9 IMF: 1185.1 compression Member: 10 IMF: 838.0 tension Member: 11 IMF: 1149.4 compression Member: 12 IMF: 781.0 tension Member: 13 IMF: 44.8 tension Member: 14 IMF: 44.8 tension Member: 15 IMF: 781.0 tension Member: 16 IMF: 1149.4 compression Member: 17 IMF: 838.0 tension Member: 18 IMF: 1185.1 compression These are the correct values: Member: 1 IMF: 1219.0 tension Member: 2 IMF: 1790.6 tension Member: 3 IMF: 1642.3 tension Member: 4 IMF: 1790.6 tension Member: 5 IMF: 1219.0 tension Member: 6 IMF: 1219.0 compression Member: 7 IMF: 1938.8 compression Member: 8 IMF: 1219.0 compression Member: 9 IMF: 1723.9 compression Member: 10 IMF: 1192.7 tension Member: 11 IMF: 1075.6 compression Member: 12 IMF: 567.5 tension Member: 13 IMF: 60.0 compression 340.9 tension (because they apply the truck at different intervals along the bridge and store the max of tension and compression) Member: 14 IMF: 60.0 compression 340.9 tension Member: 15 IMF: 567.5 tension Member: 16 IMF: 1075.6 compression Member: 17 IMF: 1192.7 tension Member: 18 IMF: 1723.9 compression All values are in kN. If anyone could help me out, I would appreciate it so much. This is the hardest thing I have ever done programming. Once I get this though, I will have one awesome simulation, but I have been stuck on this for awile. Your help would be GREATLY appreciated. Thank you, Dev578 [Edited by - dev578 on January 29, 2006 10:05:03 AM]

##### Share on other sites
Where do you have the correct results from?
I think you should distribute each member of the bridge evenly on its ends. This is how our assigned "Statics and Dynamics" textbook dictates to handle the problem.

##### Share on other sites
Thank you for the reply:) I am using West Point Bridge Designer to get the values, because it is for educational use, so they tell you values and everything. They also use the direct stiffness method. I figure if I can get their values, then I have done it right. As of now, I am pretty far off, so I know I am wrong somehow. The member forces that are equal in WPBD are equal in my values, my values are just off. They say they find the total load like this:

Total Load = 1.25Ws + 1.5Ww + 1.75T(1+ DLA)

Ws = weight of the structure, including the deck and all structural components
Ww = weight of the asphalt wearing surface
T = weight of the AASHTO Truck Loading (Two trucks in opposite directions on two lanes 180000N on each axle 4m apart)
DLA = Dynamic Load Allowance = 1.5

I don't know what the weight of the deck and asphault wearing surface are. If I am ballparkish though, it shouldn't matter too much on the values? Though that is the least of my concern right now, my values are no where close.

I just tried distributing the weight of each member half at each of its joints.

double Weight = 0.0;	for (int i = 0; Members.MetalListPos; i++)	{		//get Weight in KG of the current member, this is verified and correct		int FromJoint = -1, ToJoint = -1; //to get the global DOF numbers		for (int x = 1; x < nGlobalDegreesFreedom; x+=2)		{			if (GlobalDOF[x] == Members.FromJoint)			{				FromJoint = x;			}			if (GlobalDOF[x] == Members.ToJoint)			{				ToJoint = x;			}		}		if (FromJoint != -1)		{			//10000 is for the deck weight in kg, 4.905 to get Newtons, and to divide by 2			p[FromJoint] -= (Weight+10000)*4.905*1.25;		}		if (ToJoint != -1)		{			p[ToJoint] -= (Weight+10000)*4.905*1.25;		}	}	//distribute weight among the base joints	p[1] -= (10000*1.5); //10000 for AWS Newtons	p[3] -= (10000*1.5) + 180000*1.75*2.5; //apply the trucks on the middle joints	p[5] -= (10000*1.5) + 180000*1.75*2.5;	p[7] -= (10000*1.5);

Values produced by this:

Member: 1 IMF: 873.3 compression
Member: 2 IMF: 559.9 tension
Member: 3 IMF: 626.9 tension
Member: 4 IMF: 559.9 tension
Member: 5 IMF: 873.3 compression
Member: 6 IMF: 1937.7 compression
Member: 7 IMF: 3303.8 compression
Member: 8 IMF: 1937.7 compression
Member: 9 IMF: 2740.3 compression
Member: 10 IMF: 1727.4 tension
Member: 11 IMF: 2026.8 compression
Member: 12 IMF: 1148.8 tension
Member: 13 IMF: 94.8 compression
Member: 14 IMF: 94.8 compression
Member: 15 IMF: 1148.8 tension
Member: 16 IMF: 2026.8 compression
Member: 17 IMF: 1727.4 tension
Member: 18 IMF: 2740.3 compression

I verified the rest of my function. It is taking the inverse correctly, and multiplying correctly, the only thing I know isn't right is the force vector. That is one problem anyway, but I don't know why it is off so much. If anyone could help, I would greatly appreciate it. I have been trying to figure this out for some time now, and I am out of ideas.

Thank you,

Dev578

##### Share on other sites
Ok, interesting find. I found this on the web. I made a bridge in that software, and programmed the same one in my application. I applied forces manually into my force vector and made the corresponding forces on the web software. All of the non-base members were correct (such a nice feeling), but all the base members were wrong (they were too low, but if two or more base members were supposed to have the same member force, then my values did, they were just low). I really don't see why. Urgh. This is turning out to be the hardest thing I have ever done. Rating++ to everyone in this thread when I figure this out. I am just out of ideas! By now I've probably done everything to the function there is to do, except the thing that will make it work. Your help would be greatly appreciated.

Dev578

[Edited by - dev578 on January 28, 2006 5:55:36 PM]

##### Share on other sites
Ok, I got my values to match up correctly, I was not using the global degree of freedom on the horizontal rolling joint correctly. Now for West Point Bridge Designer. I am still having no luck filling in the force vector. I was thinking though, maybe knowing the structural stiffness matrix (Ks), and the internal member forces in each of the members, I could reverse to find the force vector that must have been used to get there.

Internal Member Force:
double n = EAOverL*(c*(D[GlobalDOFX FromJoint]-D[GlobalDOFY FromJoint]) + s*(D[GlobalDOFX ToJoint]-D[GlobalDOFY ToJoint]));

D = Ks/force vector

I keep ending up with too many unknowns though, because D was generated using the values from the force vector. The values are still not close. I am dividing the weight of each member evenly among the two joints it connects, I am applying the truck wheels on the two center joints, I am distributing the weight of the deck and asphault wearing surface evenly among all base joints, but I am not even ballpark-ish. Well... eventually I might figure it out.

-Dev578