Sign in to follow this  

Truss Bridges

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

If you intended to correct an error in the post then please contact us.

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[i].x != 0 || Joints[i].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[i].MetalListPos; i++)
	{
		//get stiffness matrix for each member
		double L = Members[i].Length;
		double c = (Joints[Members[i].ToJoint].x - Joints[Members[i].FromJoint].x) / L;
		double s = (Joints[Members[i].ToJoint].y - Joints[Members[i].FromJoint].y) / L;
		double EAOverL = (Members[i].Elasticity / Members[i].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[i].FromJoint)
			{
				One = x; Two = x + 1;
			}
		}

		for (int x = 0; x < nGlobalDegreesFreedom; x+=2)
		{
			if (GlobalDOF[x] == Members[i].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[i] = 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[i].MetalListPos; i++)
	{
		int nActualSize =  GetDiameter(Members[i].SizeListPos);

		if (Members[i].MetalListPos == 1 && Members[i].TypeListPos == 1)
		{
			Weight += 0.00785 * Members[i].Length * pow(nActualSize,2) * 4.905;
		}
		else if (Members[i].MetalListPos == 1 && Members[i].TypeListPos == 2)
		{
			Weight += 0.0014915 * Members[i].Length * pow(nActualSize,2)* 4.905;
		}
		else if (Members[i].MetalListPos == 2 && Members[i].TypeListPos == 1)
		{
			Weight += 0.00785 * Members[i].Length * pow(nActualSize,2)* 4.905;
		}
		else if (Members[i].MetalListPos == 2 && Members[i].TypeListPos == 2)
		{
			Weight += 0.0014915 * Members[i].Length * pow(nActualSize,2)* 4.905;
		}
		else if (Members[i].MetalListPos == 3 && Members[i].TypeListPos == 1)
		{
			Weight += 0.00785 * Members[i].Length * pow(nActualSize,2)* 4.905;
		}
		else if (Members[i].MetalListPos == 3 && Members[i].TypeListPos == 2)
		{
			Weight += 0.0014915 * Members[i].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[i][k];
				Ks[i][k] = 0.0;
				for (j = 0 ; j < nColumns ; ++j)
					Ks[i][j] = Ks[i][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[i] = 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][i];
		}
		d[i] = Tracker;
	}

	OutputDebugString("\n");

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


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

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

		for (int x = 0; x < nGlobalDegreesFreedom; x+=2)
		{
			if (GlobalDOF[x] == Members[i].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 this post


Link to post
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 this post


Link to post
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[i].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[i].FromJoint)
{
FromJoint = x;
}
if (GlobalDOF[x] == Members[i].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 this post


Link to post
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.

Thanks in advance



Dev578

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

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this