Esempio n. 1
0
const Matrix &
	Truss2::getInitialStiff(void)
{
	if (L == 0.0) { // - problem in setDomain() no further warnings
		theMatrix->Zero();
		return *theMatrix;
	}

	double E = theMaterial->getInitialTangent();

	// come back later and redo this if too slow
	Matrix &stiff = *theMatrix;

	int numDOF2 = numDOF/2;
	double temp;
	double EAoverL = E*A/L;
	for (int i = 0; i < dimension; i++) {
		for (int j = 0; j < dimension; j++) {
			temp = cosX[i]*cosX[j]*EAoverL;
			stiff(i,j) = temp;
			stiff(i+numDOF2,j) = -temp;
			stiff(i,j+numDOF2) = -temp;
			stiff(i+numDOF2,j+numDOF2) = temp;
		}
	}

	return *theMatrix;
}
Esempio n. 2
0
const Matrix &
ZeroLengthND::getTangentStiff(void)
{
	// Compute material strains
	this->computeStrain();

	// Set trial strain for NDMaterial
	theNDMaterial->setTrialStrain(*v);

	// Get NDMaterial tangent, the element basic stiffness
	const Matrix &kb = theNDMaterial->getTangent();

	// Set some references to make the syntax nicer
	Matrix &stiff = *K;
	const Matrix &tran = *A;

	stiff.Zero();

	double E;

	// Compute element stiffness ... K = A^*kb*A
	for (int k = 0; k < order; k++) {
		for (int l = 0; l < order; l++) {
			E = kb(k,l);
			for (int i = 0; i < numDOF; i++)
				for (int j = 0; j < i+1; j++)
					stiff(i,j) +=  tran(k,i) * E * tran(l,j);
		}
	}

	if (the1DMaterial != 0) {

		// Set trial strain for UniaxialMaterial
		the1DMaterial->setTrialStrain(e);

		// Get UniaxialMaterial tangent, the element basic stiffness
		E = the1DMaterial->getTangent();

		// Compute element stiffness ... K = A^*kb*A
		for (int i = 0; i < numDOF; i++)
			for (int j = 0; j < i+1; j++)
				stiff(i,j) +=  tran(2,i) * E * tran(2,j);
	}

    // Complete symmetric stiffness matrix
    for (int i = 0; i < numDOF; i++)
		for(int j = 0; j < i; j++)
		    stiff(j,i) = stiff(i,j);

	return stiff;
}
Esempio n. 3
0
const Matrix &
CoupledZeroLength::getInitialStiff(void)
{
    double E;

    E = theMaterial->getInitialTangent();

    Matrix& stiff = *theMatrix;
    stiff.Zero();

    int numNodeDof = numDOF/2;
    int dirn1b = dirn1+numNodeDof;
    int dirn2b = dirn2+numNodeDof;

    stiff(dirn1,dirn1)   = E;
    stiff(dirn1b,dirn1b) = E;      
    stiff(dirn1,dirn1b)  = -E;
    stiff(dirn1b,dirn1)  = -E;      

    stiff(dirn2,dirn2)   = E;
    stiff(dirn2b,dirn2b) = E;      
    stiff(dirn2,dirn2b)  = -E;
    stiff(dirn2b,dirn2)  = -E;      

    return stiff;
}
Esempio n. 4
0
const Matrix &
TPB1D::getTangentStiff(void)
{
    double E;

    // stiff is a reference to the matrix holding the stiffness matrix
    Matrix& stiff = *theMatrix;
    
    // zero stiffness matrix
    stiff.Zero();
    
    E = theMaterial->getTangent();
    
    // compute contribution of material to tangent matrix
    stiff(direction, direction) = E;
    stiff(direction, direction+numDOF/2) = -E;
    stiff(direction+numDOF/2, direction) = -E;
    stiff(direction+numDOF/2, direction+numDOF/2) = E;

    return stiff;
}
Esempio n. 5
0
const Matrix &
	Truss2::getKiSensitivity(int gradNumber)
{
	Matrix &stiff = *theMatrix;
	stiff.Zero();

	if (parameterID == 0) {
	}
	else if (parameterID == 1) {
		// If cross sectional area is random
		double E = theMaterial->getInitialTangent();

		int numDOF2 = numDOF/2;
		double temp;
		double EoverL = E/L;
		for (int i = 0; i < dimension; i++) {
			for (int j = 0; j < dimension; j++) {
				temp = cosX[i]*cosX[j]*EoverL;
				stiff(i,j) = temp;
				stiff(i+numDOF2,j) = -temp;
				stiff(i,j+numDOF2) = -temp;
				stiff(i+numDOF2,j+numDOF2) = temp;
			}
		}
	}
	else if (parameterID == 2) {
		// Nothing here when 'rho' is random
	}
	else {
		double Esens = theMaterial->getInitialTangentSensitivity(gradNumber);

		int numDOF2 = numDOF/2;
		double temp;
		double EAoverL = Esens*A/L;
		for (int i = 0; i < dimension; i++) {
			for (int j = 0; j < dimension; j++) {
				temp = cosX[i]*cosX[j]*EAoverL;
				stiff(i,j) = temp;
				stiff(i+numDOF2,j) = -temp;
				stiff(i,j+numDOF2) = -temp;
				stiff(i+numDOF2,j+numDOF2) = temp;
			}
		}
	}

	return stiff;
}
Esempio n. 6
0
const Matrix &
TrussSection::getInitialStiff(void)
{
    if (L == 0.0) { // - problem in setDomain() no further warnings
	theMatrix->Zero();
	return *theMatrix;
    }
    
    int order = theSection->getOrder();
    const ID &code = theSection->getType();
	
    const Matrix &k = theSection->getInitialTangent();
    double AE = 0.0;
    int i;
    for (i = 0; i < order; i++) {
      if (code(i) == SECTION_RESPONSE_P)
	AE += k(i,i);
    }

    // come back later and redo this if too slow
    Matrix &stiff = *theMatrix;

    int numDOF2 = numDOF/2;
    double temp;
    AE /= L;
    for (i = 0; i < dimension; i++) {
      for (int j = 0; j < dimension; j++) {
	temp = cosX[i]*cosX[j]*AE;
	stiff(i,j) = temp;
	stiff(i+numDOF2,j) = -temp;
	stiff(i,j+numDOF2) = -temp;
	stiff(i+numDOF2,j+numDOF2) = temp;
      }
    }

    return *theMatrix;
}
Esempio n. 7
0
const Matrix &
N4BiaxialTruss::getInitialStiff(void)
{
	if (L == 0.0) { // - problem in setDomain() no further warnings
		return *theMatrix;
		theMatrix->Zero();
	}
	
	double E1 = theMaterial_1->getInitialTangent();
	double E2 = theMaterial_2->getInitialTangent();

	// come back later and redo this if too slow
	Matrix &stiff = *theMatrix;
	stiff.Zero();    

	int numDOF2 = numDOF/4;
	double temp, temp2;
	double EAoverL = E1*A*oneOverL;
	double EAoverL2 = E2*A*oneOverL;
	
	for (int i = 0; i < dimension; i++) {
		for (int j = 0; j < dimension; j++) {
			temp = cosX[i]*cosX[j]*EAoverL;
			temp2 = cosX2[i]*cosX2[j]*EAoverL2;
			stiff(i,		j)		   = temp;
			stiff(i+numDOF2,j)	       = -temp;
			stiff(i,		j+numDOF2) = -temp;
			stiff(i+numDOF2,j+numDOF2) = temp;
			stiff(i+2*numDOF2,j+2*numDOF2) = temp2;
			stiff(i+3*numDOF2,j+2*numDOF2) = -temp2;
			stiff(i+2*numDOF2,j+3*numDOF2) = -temp2;
			stiff(i+3*numDOF2,j+3*numDOF2) = temp2;
		}
	}
	
	return stiff;
}
Esempio n. 8
0
//*********************************************************************
//form residual and tangent
void  BbarBrick::formResidAndTangent( int tang_flag )
{

  //strains ordered : eps11, eps22, eps33, 2*eps12, 2*eps23, 2*eps31

  static const int ndm = 3 ;

  static const int ndf = 3 ;

  static const int nstress = 6 ;

  static const int numberNodes = 8 ;

  static const int numberGauss = 8 ;

  static const int nShape = 4 ;

  int i, j, k, p, q ;
  int jj, kk ;

  int success ;

  static double volume ;

  static double xsj ;  // determinant jacaobian matrix

  static double dvol[numberGauss] ; //volume element

  static double gaussPoint[ndm] ;

  static Vector strain(nstress) ;  //strain

  static double shp[nShape][numberNodes] ;  //shape functions at a gauss point

  static double Shape[nShape][numberNodes][numberGauss] ; //all the shape functions

  static double shpBar[nShape][numberNodes] ;  //mean value of shape functions

  static Vector residJ(ndf) ; //nodeJ residual

  static Matrix stiffJK(ndf,ndf) ; //nodeJK stiffness

  static Vector stress(nstress) ;  //stress

  static Matrix dd(nstress,nstress) ;  //material tangent


  //---------B-matrices------------------------------------

    static Matrix BJ(nstress,ndf) ;      // B matrix node J

    static Matrix BJtran(ndf,nstress) ;

    static Matrix BK(nstress,ndf) ;      // B matrix node k

    static Matrix BJtranD(ndf,nstress) ;

  //-------------------------------------------------------


  //zero stiffness and residual
  stiff.Zero( ) ;
  resid.Zero( ) ;

  //compute basis vectors and local nodal coordinates
  computeBasis( ) ;


  //zero mean shape functions
  for ( p = 0; p < nShape; p++ ) {
    for ( q = 0; q < numberNodes; q++ )
      shpBar[p][q] = 0.0 ;
  } // end for p

  //zero volume
  volume = 0.0 ;


  //gauss loop to compute and save shape functions
  int count = 0 ;

  for ( i = 0; i < 2; i++ ) {
    for ( j = 0; j < 2; j++ ) {
      for ( k = 0; k < 2; k++ ) {

        gaussPoint[0] = sg[i] ;
	gaussPoint[1] = sg[j] ;
	gaussPoint[2] = sg[k] ;

	//get shape functions
	shp3d( gaussPoint, xsj, shp, xl ) ;

	//save shape functions
	for ( p = 0; p < nShape; p++ ) {
	  for ( q = 0; q < numberNodes; q++ )
	    Shape[p][q][count] = shp[p][q] ;
	} // end for p

	//volume element to also be saved
	dvol[count] = wg[count] * xsj ;

        //add to volume
	volume += dvol[count] ;

	//add to mean shape functions
	for ( p = 0; p < nShape; p++ ) {
	  for ( q = 0; q < numberNodes; q++ )
	    shpBar[p][q] += ( dvol[count] * shp[p][q] ) ;
	} // end for p

	count++ ;

      } //end for k
    } //end for j
  } // end for i


  //mean value of shape functions
  for ( p = 0; p < nShape; p++ ) {
    for ( q = 0; q < numberNodes; q++ )
      shpBar[p][q] /= volume ;
  } // end for p


  //gauss loop
  for ( i = 0; i < numberGauss; i++ ) {

    //extract shape functions from saved array
    for ( p = 0; p < nShape; p++ ) {
       for ( q = 0; q < numberNodes; q++ )
	  shp[p][q]  = Shape[p][q][i] ;
    } // end for p


    //zero the strains
    strain.Zero( ) ;


    // j-node loop to compute strain
    for ( j = 0; j < numberNodes; j++ )  {

      //compute B matrix

      BJ = computeBbar( j, shp, shpBar ) ;

      //nodal displacements
      const Vector &ul = nodePointers[j]->getTrialDisp( ) ;

      //compute the strain
      //strain += (BJ*ul) ;
      strain.addMatrixVector(1.0,  BJ,ul,1.0 ) ;

    } // end for j



    //send the strain to the material
    success = materialPointers[i]->setTrialStrain( strain ) ;

    //compute the stress
    stress = materialPointers[i]->getStress( ) ;


    //multiply by volume element
    stress  *= dvol[i] ;

    if ( tang_flag == 1 ) {
      dd = materialPointers[i]->getTangent( ) ;
      dd *= dvol[i] ;
    } //end if tang_flag


    //residual and tangent calculations node loops

    jj = 0 ;
    for ( j = 0; j < numberNodes; j++ ) {

      BJ = computeBbar( j, shp, shpBar ) ;

      //transpose
      //BJtran = transpose( nstress, ndf, BJ ) ;
      for (p=0; p<ndf; p++) {
	for (q=0; q<nstress; q++)
	  BJtran(p,q) = BJ(q,p) ;
      }//end for p


      //residual
      //residJ = BJtran * stress ;
      residJ.addMatrixVector(0.0,  BJtran,stress,1.0);

      //residual
      for ( p = 0; p < ndf; p++ ) {
        resid( jj + p ) += residJ(p)  ;
		if (applyLoad == 0) {
	    	resid( jj + p ) -= dvol[i]*b[p]*shp[3][j];
		} else {
			resid( jj + p ) -= dvol[i]*appliedB[p]*shp[3][j];
		}
      }

      if ( tang_flag == 1 ) {

	//BJtranD = BJtran * dd ;
	BJtranD.addMatrixProduct(0.0,  BJtran,dd,1.0);

         kk = 0 ;
         for ( k = 0; k < numberNodes; k++ ) {

            BK = computeBbar( k, shp, shpBar ) ;


            //stiffJK =  BJtranD * BK  ;
	    stiffJK.addMatrixProduct(0.0,  BJtranD,BK,1.0) ;

            for ( p = 0; p < ndf; p++ )  {
               for ( q = 0; q < ndf; q++ )
                  stiff( jj+p, kk+q ) += stiffJK( p, q ) ;
            } //end for p

            kk += ndf ;
          } // end for k loop

      } // end if tang_flag

      jj += ndf ;
    } // end for j loop


  } //end for i gauss loop


  return ;
}
void  ZeroLengthContact3D::formResidAndTangent( int tang_flag ) 

{



	// trial displacement vectors

 	Vector DispTrialS(3); // trial disp for slave node

	Vector DispTrialM(3); // trial disp for master node

	// trial frictional force vectors (in local coordinate)

    Vector t_trial(2);

    double TtrNorm;



    // Coulomb friction law surface

	double Phi;     



    int i, j;



    //zero stiffness and residual 

    stiff.Zero( ) ;

    resid.Zero( ) ;

   

	// detect contact and set flag

    ContactFlag = contactDetect(); 



	//opserr<<this->getTag()<< " ZeroLengthContact3D::ContactFlag=" << ContactFlag<<endln;





	if (ContactFlag == 1) // contacted

	{  

       // contact presure;

		pressure = Kn*gap;   // Kn : normal penalty

  

		DispTrialS=nodePointers[0]->getTrialDisp();

        DispTrialM=nodePointers[1]->getTrialDisp();



       //nodal displacements 

        double ul[6];



		ul[0]=DispTrialS(0);

		ul[1]=DispTrialS(1);

		ul[2]=DispTrialS(2);

		ul[3]=DispTrialM(0);

		ul[4]=DispTrialM(1);

		ul[5]=DispTrialM(2);



		t_trial.Zero();

        xi.Zero();	



		for (i=0; i<6; i++){

			xi(0) += T1(i)*ul[i];

			xi(1) += T2(i)*ul[i];

		}



		// Compute trial shear force

		for (i=0; i<2; i++)  t_trial(i)=Kt * (xi(i)-stickPt(i));  //Kt: tangential penalty

        TtrNorm=t_trial.Norm();



        // Coulomb friction law, trial state

		Phi = TtrNorm - (fs * pressure + cohesion);   // add cohesion

		

		if (Phi <= 0 ) { // stick case

  		//opserr<< "stick ...." << endln;



 			if ( tang_flag == 1 ) {

		    // stiff

				for (i=0; i<6; i++) {

					for (j=0; j<6; j++) {

						stiff(i,j) = Kn*(N(i)*N(j)) + Kt*(T1(i)*T1(j)+T2(i)*T2(j));	

					}

				}

			} //endif tang_flag

			// force

			for (i=0; i<6; i++) 

				 resid(i)= (-1*pressure)*N(i) + t_trial(0)*T1(i) + t_trial(1)*T2(i) ;

			//	 resid(i)= (-1*pressure)*N(i) - t_trial(0)*T1(i) - t_trial(1)*T2(i) ;



		} // end if stick

		else {              // slide case, non-symmetric stiff

            ContactFlag=2;  // set the contactFlag for sliding



		//	opserr<< "sliding ...." << endln;



            if ( tang_flag == 1 ) {

				// stiff

				double Pt1, Pt2;

				Pt1=t_trial(0)/TtrNorm;

				Pt2=t_trial(1)/TtrNorm;

				double C1=fs*Kn;

				double C2=Kt*(fs*pressure+cohesion)/TtrNorm;  // add cohesion, sept. 7, 2005



				for (i=0; i<6; i++) {

					for (j=0; j<6; j++) {

						stiff(i,j) = Kn*(N(i)*N(j)) - C1*(Pt1*T1(i)*N(j)+Pt2*T2(i)*N(j))

							    + C2*( (1-Pt1*Pt1)*T1(i)*T1(j) -    Pt1*Pt2 *T1(i)*T2(j)

					            - Pt1*Pt2 *T2(i)*T1(j) + (1-Pt1*Pt2)*T2(i)*T2(j)  );

					} //endfor i

				} //endfor j

			} // endif tang_flag

		

			// force

			double t1, t2;

			t1 = (fs*pressure+cohesion) * t_trial(0)/TtrNorm;  // add cohesion

            t2 = (fs*pressure+cohesion) * t_trial(1)/TtrNorm;  // add cohesion



			//opserr<<"gap=" << gap <<endln;

			//opserr<<"pressure= "<<pressure <<endln;



			for (i=0; i<6; i++) {

				resid(i) = (-1*pressure)*N(i)+t1*T1(i)+t2*T2(i) ;

			//	resid(i) = (-1*pressure)*N(i)-t1*T1(i)-t2*T2(i) ;

			}

		} //endif slide



	}  // endif ContactFlag



	// for NOT contact, do nothing, stiff and resid are zeroes



}
Esempio n. 10
0
void  
NineNodeMixedQuad::formResidAndTangent( int tang_flag ) 
{

  //strains ordered : eps11, eps22, eps33, 2*eps12 
  //volumtric strains projected onto {1, \xi, \eta} natural coordinates

  static const int ndm = 2 ;

  static const int ndf = 2 ; 

  static const int nstress = 4 ;
 
  static const int numberNodes = 9 ;

  static const int numberGauss = 9 ;

  static const int nShape = 3 ;

  static const int nMixed = 3 ;

  int i, j, k, p, q, r, s ;
  int jj, kk ;

  int success ;
  
  static double volume ;

  static double xsj ;  // determinant jacaobian matrix 

  static double dvol[numberGauss] ; //volume element

  static double gaussPoint[ndm] ;

  static double natCoorArray[ndm][numberGauss] ;

  static Vector strain(nstress) ;  //strain

  static double shp[nShape][numberNodes] ;  //shape functions at a gauss point

  static double Shape[nShape][numberNodes][numberGauss] ; //all the shape functions

  static double shpBar[nShape][numberNodes][nMixed] ; //mean value of shape functions

  static double rightHandSide[nShape][numberNodes][nMixed] ;

  static Vector residJ(ndf) ; //nodeJ residual 

  static Matrix stiffJK(ndf,ndf) ; //nodeJK stiffness 

  static Vector stress(nstress) ;  //stress

  static Matrix dd(nstress,nstress) ;  //material tangent

  static double interp[nMixed] ;

  static Matrix Proj(3,3) ;   //projection matrix 
  static Matrix ProjInv(3,3) ;

  static Matrix Iden(3,3) ;
  Iden(0,0) = 1.0 ;
  Iden(1,1) = 1.0 ;
  Iden(2,2) = 1.0 ;

  //---------B-matrices------------------------------------

    static Matrix BJ(nstress,ndf) ;      // B matrix node J

    static Matrix BJtran(ndf,nstress) ;

    static Matrix BK(nstress,ndf) ;      // B matrix node k

    static Matrix BJtranD(ndf,nstress) ;

  //-------------------------------------------------------

  
  //zero stiffness and residual 
  stiff.Zero( ) ;
  resid.Zero( ) ;

  //node coordinates
  computeBasis() ;

  //zero mean shape functions
  for ( p=0; p<nShape; p++ ) {
    for ( q=0; q<numberNodes; q++ ) {

      for (r=0; r<nMixed; r++ ) {
	shpBar[p][q][r] = 0.0 ;
	rightHandSide[p][q][r] = 0.0 ;
      }

    }//end for q
  } // end for p


  //zero volume
  volume = 0.0 ;

  //zero projection matrix  
  Proj.Zero( ) ;
  ProjInv.Zero( ) ;


  //gauss loop to compute and save shape functions 
  int count = 0 ;

  for ( i = 0; i < 3; i++ ) {
    for ( j = 0; j < 3; j++ ) {

        gaussPoint[0] = sg[i] ;        
	gaussPoint[1] = sg[j] ;        


	//save gauss point locations
	natCoorArray[0][count] = gaussPoint[0] ;
	natCoorArray[1][count] = gaussPoint[1] ;


	//get shape functions    
	shape2dNine( gaussPoint, xl, shp, xsj ) ;


	//save shape functions
	for ( p=0; p<nShape; p++ ) {
	  for ( q=0; q<numberNodes; q++ )
	    Shape[p][q][count] = shp[p][q] ;
	} // end for p

	
	//volume element to also be saved
	dvol[count] = ( wg[i]*wg[j] ) * xsj ;  


        //add to projection matrix
	interp[0] = 1.0 ;
	interp[1] = gaussPoint[0] ;
	interp[2] = gaussPoint[1] ;
	
	for ( r=0; r<nMixed; r++ ) {
	  for ( s=0; s<nMixed; s++ ) 
	    Proj(r,s) += ( interp[r]*interp[s] * dvol[count] ) ;
	}//end for r

	volume += dvol[count] ;
	
	
	//add to mean shape functions
	for ( p=0; p<nShape; p++ ) {
	  for ( q=0; q<numberNodes; q++ ) {

	    for ( s=0; s<nMixed; s++ ) 
	      rightHandSide[p][q][s] += ( shp[p][q] * interp[s] * dvol[count] ) ;

	  }//end for q 
	} // end for p


	//increment gauss point counter
	count++ ;

    } //end for j
  } // end for i 
  


  //invert projection matrix
  //int Solve(const Matrix &M, Matrix &res) const;
  Proj.Solve( Iden, ProjInv ) ;
  
  //mean value of shape functions
  for ( p=0; p<nShape; p++ ) {
    for ( q=0; q<numberNodes; q++ ) {

      for (r=0; r<nMixed; r++ ) {
	for (s=0; s<nMixed; s++ ) 
	  shpBar[p][q][r] += ( ProjInv(r,s) * rightHandSide[p][q][s] ) ;
      }//end for r

    }//end for q
  }//end for p


  //gauss loop 
  for ( i=0; i<numberGauss; i++ ) {
    
    //extract gauss point location
    gaussPoint[0] = natCoorArray[0][i] ;
    gaussPoint[1] = natCoorArray[1][i] ;

    //extract shape functions from saved array
    for ( p=0; p<nShape; p++ ) {
       for ( q=0; q<numberNodes; q++ )
	  shp[p][q]  = Shape[p][q][i] ;
    } // end for p


    //zero the strains
    strain.Zero( ) ;

    // j-node loop to compute strain 
    for ( j=0; j<numberNodes; j++ )  {

      //compute B matrix 

      BJ = computeBbar( j, gaussPoint, shp, shpBar ) ;
      
      //nodal displacements 
      const Vector &ul = nodePointers[j]->getTrialDisp( ) ;

      //compute the strain
      //strain += (BJ*ul) ; 
      strain.addMatrixVector(1.0,  BJ,ul,1.0 ) ;

    } // end for j
  


    //send the strain to the material 
    success = materialPointers[i]->setTrialStrain( strain ) ;

    //compute the stress
    stress = materialPointers[i]->getStress( ) ;


    //multiply by volume element
    stress  *= dvol[i] ;

    if ( tang_flag == 1 ) {
      dd = materialPointers[i]->getTangent( ) ;
      dd *= dvol[i] ;
    } //end if tang_flag


    //residual and tangent calculations node loops

    jj = 0 ;
    for ( j=0; j<numberNodes; j++ ) {

      BJ = computeBbar( j, gaussPoint, shp, shpBar ) ;
   
      //transpose 
      //BJtran = transpose( nstress, ndf, BJ ) ;
      for (p=0; p<ndf; p++) {
	for (q=0; q<nstress; q++) 
	  BJtran(p,q) = BJ(q,p) ;
      }//end for p


      //residual
      //residJ = BJtran * stress ;
      residJ.addMatrixVector(0.0,  BJtran,stress,1.0);

      //residual 
      for ( p=0; p<ndf; p++ )
        resid( jj + p ) += residJ(p)  ;


      if ( tang_flag == 1 ) {

	//BJtranD = BJtran * dd ;
	BJtranD.addMatrixProduct(0.0,  BJtran,dd,1.0);

         kk = 0 ;
         for ( k=0; k<numberNodes; k++ ) {

            BK = computeBbar( k, gaussPoint, shp, shpBar ) ;
  
 
            //stiffJK =  BJtranD * BK  ;
	    stiffJK.addMatrixProduct(0.0,  BJtranD,BK,1.0) ;

            for ( p=0; p<ndf; p++ )  {
               for ( q=0; q<ndf; q++ )
                  stiff( jj+p, kk+q ) += stiffJK( p, q ) ;
            } //end for p

            kk += ndf ;
	 }//end for k loop

      }//end if tang_flag 

      jj += ndf ;
    }//end for j loop


  }//end for i gauss loop 

  
  return ;
}
const Matrix&  TwentyEightNodeBrickUP::getStiff( int flag )

{

	if (flag != 0 && flag != 1) {

		opserr << "FATAL TwentyEightNodeBrickUP::getStiff() - illegal use\n";

		exit(-1);

	}



	if (flag == 0 && Ki != 0)

		return *Ki;



	int i, j ;



	static double xsj ;  // determinant jacaobian matrix

	double volume = 0.;

	//-------------------------------------------------------

	int j3, j3m1, j3m2, ik, ib, jk, jb;

	static Matrix B(6,nenu*3);

	static Matrix BTDB(nenu*3,nenu*3);

	static Matrix D(6, 6);

	B.Zero();

	BTDB.Zero();

	stiff.Zero();



	//compute basis vectors and local nodal coordinates

	computeBasis( ) ;



	for( i = 0; i < nintu; i++ ) {

		// compute Jacobian and global shape functions

		Jacobian3d(i, xsj, 0);

		//volume element to also be saved

		dvolu[i] = wu[i] * xsj ;

		volume += dvolu[i];

	} // end for i

    //printf("volume = %f\n", volume);



//	for( i = 0; i < nintu; i++ ) {

//		for(int j = 0; j < nenu; j++ ) {

//			printf("%5d %5d %15.6e %15.6e %15.6e %15.6e\n", i,j,

//				shgu[0][j][i], shgu[1][j][i], shgu[2][j][i], shgu[3][j][i]);

//		}

//	}

//	exit(-1);



	// Loop over the integration points

	for (i = 0; i < nintu; i++) {



		// Get the material tangent

		if( flag == 0 )

			D = materialPointers[i]->getInitialTangent();

		else

			D = materialPointers[i]->getTangent();

		//const Matrix &D = materialPointers[i]->getTangent();





		for (j=0; j<nenu; j++) {



			j3   = 3*j+2;

			j3m1 = j3 - 1;

			j3m2 = j3 - 2;



			B(0,j3m2) = shgu[0][j][i];

			B(0,j3m1) = 0.;

			B(0,j3  ) = 0.;



			B(1,j3m2) = 0.;

			B(1,j3m1) = shgu[1][j][i];

			B(1,j3  ) = 0.;



			B(2,j3m2) = 0.;

			B(2,j3m1) = 0.;

			B(2,j3  ) = shgu[2][j][i];



			B(3,j3m2) = shgu[1][j][i];

			B(3,j3m1) = shgu[0][j][i];

			B(3,j3  ) = 0.;



			B(4,j3m2) = 0.;

			B(4,j3m1) = shgu[2][j][i];

			B(4,j3  ) = shgu[1][j][i];



			B(5,j3m2) = shgu[2][j][i];

			B(5,j3m1) = 0.;

			B(5,j3  ) = shgu[0][j][i];



		}



		// Perform numerical integration

		//K = K + (B^ D * B) * intWt(i) * detJ;

		BTDB.addMatrixTripleProduct(1.0, B, D, dvolu[i]);

	}



	for (i = 0; i < nenu; i++) {

		if (i<nenp)

			ik = i*4;

		else

			ik = nenp*4 + (i-nenp)*3;

		ib = i*3;



		for (j = 0; j < nenu; j++) {

			if (j<nenp)

				jk = j*4;

			else

				jk = nenp*4 + (j-nenp)*3;

			jb = j*3;

			for( int i1 = 0; i1 < 3; i1++)

				for(int j1 = 0; j1 < 3; j1++) {

					stiff(ik+i1, jk+j1) = BTDB(ib+i1,jb+j1);

				}

		}

	}

	if( flag == 1) {

		return stiff;

	}

	Ki = new Matrix(stiff);

	if (Ki == 0) {

		opserr << "FATAL TwentyEightNodeBrickUP::getStiff() -";

		opserr << "ran out of memory\n";

		exit(-1);

	}



	return *Ki;

}
int main (void)
{   double t0=omp_get_wtime();
    // Open I/O for business!
    ifp = fopen(INPUT, "r"); // Open input file for reading
    ofp = fopen(OUTPUT, "w"); // Open output file for writing

    // Verify that I/O files are open
    if (ifp != 0) {
         printf("Input file is open\n");
    } else {
        printf("***ERROR*** Unable to open the input file\n");
        getchar();
        return 0;
    }
    if (ofp != 0) {
        printf("Output file is open\n");
    } else {
        printf("***ERROR*** Unable to open the output file\n");
        getchar();
        return 0;
    }

    // Read in number of elements, joints from input file
    fscanf(ifp, "%d,%d\n", &ne, &nj);
    fprintf(ofp, "Control Variables:\n\tNumber of Elements: %d\n", ne);
    fprintf(ofp, "\tNumber of Joints: %d\n\n", nj);

    /*
    Associate pointers with base address of arrays in function calls: parea = area;
        Note: in this context "&" can be omitted to obtain "&area[0]"
        Note: previous remark only works for 1D arrays: px=&x[0][0]
    */

    // Define secondary variables which DO NOT depend upon neq
    double x[3][nj];							// Current joint coordinates
    int mcode[6][ne], jcode[3][nj], minc[2][ne];// Member incidence and constraint data
    double emod[ne];							// Element material properties
	double eleng[ne], deflen[ne], elong[ne];	// Element length, deformed length, and elongation
    double area[ne];							// Element cross-sectional properties
    double c1[ne], c2[ne], c3[ne];				// Direction cosines
    double qi, dqi;								// Current and incremental load proportionality factor
    double qimax;								// Maximum allowable load proportionality factor
    
	// Convergence parameters
    double tolfor, tolener;						// Tolerances on force and energy
    double intener1;							// Internal energy from first equilibrium iteration
    int inconv;									// Flag for convergence test
    int itecnt, itemax;							// Iteration counter and max number of iterations
    int errchk;									// Error check variable on user defined functions
    int i;										// Counter variable
    int csrflag=0;
    // Pass control to struc function
    errchk = struc(&jcode[0][0], &minc[0][0]);

    // Terminate program if errors encountered
    if (errchk == 1) {
        fprintf(ofp, "\n\nSolution failed\n");
        printf("Solution failed, see output file\n");

        // Close the I/O
        if (fclose(ifp) != 0) {
            printf("***ERROR*** Unable to close the input file\n");
        } else {
            printf("Input file is closed\n");
        }
        if (fclose(ofp) != 0) {
            printf("***ERROR*** Unable to close the output file\n");
        } else {
            printf("Output file is closed\n");
        }
        getchar();
        return 0;
    }

    // Pass control to codes function
    codes (&mcode[0][0], &jcode[0][0], &minc[0][0]);
    printf("number of equations: %d\n", neq);
    // Define secondary variables which DO depend upon neq
    double q[neq];						// Reference load vector
    double qtot[neq];					// Total load vector, i.e. qi * q[neq]
    double d[neq], dd[neq];				// Total and incremental nodal displacement vectors
    double f[neq];						// Internal force vector
    double fp[neq];						// Internal force vector from previous load increment
    double fpi[neq];					// Internal force vector from previous iteration
    double r[neq];						// Residual force vector, i.e. qtot - f
    int maxa[neq + 1], kht[neq], lss;	// Skyline storage parameters for stiffness matrix

    // Pass control to skylin function
    skylin (kht, maxa, &mcode[0][0], &lss);
    printf("size of stiffness matrix as a 1D element: %d\n",lss);
    // Define secondary variable which depends upon lss (the size of the stiffness marix as a 1D array)
    double *ss= (double *)malloc(lss*sizeof(double));						// Tangent stiffness matrix stored as an array

    // Pass control to prop function
    prop (&x[0][0], area, emod, eleng, c1, c2, c3, &minc[0][0]);

    // Pass control to load function
    errchk = load (q, &jcode[0][0]);

    // Terminate program if errors encountered
    if (errchk == 1) {
        fprintf(ofp, "\n\nSolution failed\n");
        printf("Solution failed, see output file\n");

        // Close the I/O
        if (fclose(ifp) != 0) {
            printf("***ERROR*** Unable to close the input file\n");
        } else {
            printf("Input file is closed\n");
        }
        if (fclose(ofp) != 0) {
            printf("***ERROR*** Unable to close the output file\n");
        } else {
            printf("Output file is closed\n");
        }
        getchar();
        return 0;
    }

    // Read in solver parameters from input file
    fscanf(ifp, "%lf,%lf,%lf\n", &qimax, &qi, &dqi);
    fscanf(ifp, "%d\n", &itemax);
    fscanf(ifp, "%lf,%lf\n", &tolfor, &tolener);

    // Print layout for output of results
    fprintf(ofp, "\nNonlinear Equilibrium Path:\n\tLambda\t");
    for (i = 0; i <= neq - 1; ++i) {
        fprintf(ofp, "\tDOF %d\t", i + 1);
    }

    // Initialize generalized nodal displacement and internal force vectors
    for (i = 0; i <= neq - 1; ++i) {
        d[i] = 0;
        f[i] = 0;
    }

    // Initialize element length and elongation variables
    for (i = 0; i <= ne - 1; ++i) {
        deflen[i] = eleng[i];
        elong[i] = 0;
    }

    /* Begin load incrementation; load will be incremented until load proportionality
       factor is equal to user specified maximum */
    do {
        /* Compute the generalized joint total load vector, store generalized internal
           force vector from previous configuration and re-initialize */
        for (i = 0; i <= neq - 1; ++i) {
            qtot[i] = q[i] * qi;
            fp[i] = f[i];
            f[i] = 0;
        }

        // Pass control to forces function
        forces (f, area, emod, c1, c2, c3, elong, eleng, &mcode[0][0]);

        itecnt = 1;  // Re-initialize iteration counter at the start of each increment
	
        /* Start of each equilibrium iteration within load increment; iterations will
           continue until convergence is reached or iteration count exceeds user
           specified maximum */
        do {
	    printf("iteration: %d\n", itecnt);
	    //printf("iteration count: %d \n", itecnt);
            // Compute residual force vector for use in evaluating displacement increment
            for (i = 0; i <= neq - 1; ++i) {
                r[i] = qtot[i] - f[i];
            }

            // Pass control to stiff function
            stiff (ss, area, emod, eleng, c1, c2, c3, elong, maxa, &mcode[0][0], &lss);
	    if (csrflag==1){
	    	write_array_double("asky", lss, ss);
	    	write_array_int("maxa", neq+1, maxa);
            	write_array_double("r", neq, r);
	    }
		// Solve the system for incremental displacements
            if (lss == 1) {
                // Carry out computation of incremental displacement directly for lss = 1
                dd[0] = r[0] / ss[0];
            } else {
                // Pass control to solve function
                errchk = solve (ss, r, dd, maxa);
	
	        if (csrflag==1){
	   		write_array_double("dd", neq, dd);    
	        }
		++csrflag;
                // Terminate program if errors encountered
                if (errchk == 1) {
                    fprintf(ofp, "\n\nSolution failed\n");
                    printf("Solution failed, see output file\n");

                    // Close the I/O
                    if (fclose(ifp) != 0) {
                        printf("***ERROR*** Unable to close the input file\n");
                    } else {
                        printf("Input file is closed\n");
                    }
                    if (fclose(ofp) != 0) {
                        printf("***ERROR*** Unable to close the output file\n");
                    } else {
                        printf("Output file is closed\n");
                    }
                    getchar();
                    return 0;
                }
            }

            /* Update generalized nodal displacement vector, store generalized internal
               force vector from previous iteration, and re-initialize generalized
               internal force vector */
            for (i = 0; i <= neq - 1; ++i) {
                d[i] += dd[i];
                fpi[i] = f[i];
                f[i] = 0;
            }

            // Pass control to forces function
            updatc (&x[0][0], dd, c1, c2, c3, elong, eleng, deflen, &minc[0][0],
                &jcode[0][0]);

            // Pass control to forces function
            forces (f, area, emod, c1, c2, c3, elong, eleng, &mcode[0][0]);

            if (itecnt == 1) {
                // Compute internal energy from first iteration
                intener1 = 0;
            	for (i = 0; i <= neq - 1; ++i) {
            		intener1 += dd[i] * (qtot[i] - fp[i]);
            	}
            }

            // Pass control to test function
            test (f, fp, qtot, dd, fpi, &intener1, &inconv, &neq, &tolfor, &tolener);

            itecnt ++; // Advance solution counter

        } while (inconv != 0 && itecnt <= itemax);

        // Store generalized internal force vector from current configuration
        for (i = 0; i <= neq - 1; ++i) {
            fp[i] = f[i];
        }

        if (inconv != 0) {
            fprintf(ofp, "\n\n***ERROR*** Convergence not reached within specified");
            fprintf(ofp, " number of iterations (INCONV = %d)", inconv);
            fprintf(ofp, "\n\nSolution failed\n");
            printf("Solution failed, see output file\n");

            // Close the I/O
            if (fclose(ifp) != 0) {
                printf("***ERROR*** Unable to close the input file\n");
            } else {
                printf("Input file is closed\n");
            }
            if (fclose(ofp) != 0) {
                printf("***ERROR*** Unable to close the output file\n");
            } else {
                printf("Output file is closed\n");
            }
            getchar();
            return 0;
        }

        // Output model response
        fprintf(ofp, "\n\t%lf", qi);
        for (i = 0; i <= neq - 1; ++i) {
            fprintf(ofp, "\t%lf", d[i]);
        }

        qi += dqi; // Increment load proportionality factor

    } while (qi <= qimax);

    if (qi >= qimax && inconv == 0) {
        fprintf(ofp, "\n\nSolution successful\n");
        printf("Solution successful\n");
    }

    // Close the I/O
    if (fclose(ifp) != 0) {
        printf("***ERROR*** Unable to close the input file\n");
    } else {
        printf("Input file is closed\n");
    }
    if (fclose(ofp) != 0) {
        printf("***ERROR*** Unable to close the output file\n");
    } else {
        printf("Output file is closed\n");
    }
    getchar(); 
    double t1 = omp_get_wtime();
    printf("Total time spent (IO+computation): %g\n",t1-t0);
    return 0;
}
Esempio n. 13
0
//return secant matrix 
const Matrix& 
NineNodeMixedQuad::getInitialStiff( ) 
{
  if (Ki != 0)
    return *Ki;

  static const int ndm = 2 ;

  static const int ndf = 2 ; 

  static const int nstress = 4 ;
 
  static const int numberNodes = 9 ;

  static const int numberGauss = 9 ;

  static const int nShape = 3 ;

  static const int nMixed = 3 ;

  int i, j, k, p, q, r, s ;
  int jj, kk ;

  static double volume ;

  static double xsj ;  // determinant jacaobian matrix 

  static double dvol[numberGauss] ; //volume element

  static double gaussPoint[ndm] ;

  static double natCoorArray[ndm][numberGauss] ;

  static Vector strain(nstress) ;  //strain

  static double shp[nShape][numberNodes] ;  //shape functions at a gauss point

  static double Shape[nShape][numberNodes][numberGauss] ; //all the shape functions

  static double shpBar[nShape][numberNodes][nMixed] ; //mean value of shape functions

  static double rightHandSide[nShape][numberNodes][nMixed] ;

  static Vector residJ(ndf) ; //nodeJ residual 

  static Matrix stiffJK(ndf,ndf) ; //nodeJK stiffness 

  static Vector stress(nstress) ;  //stress

  static Matrix dd(nstress,nstress) ;  //material tangent

  static double interp[nMixed] ;

  static Matrix Proj(3,3) ;   //projection matrix 
  static Matrix ProjInv(3,3) ;

  static Matrix Iden(3,3) ;
  Iden(0,0) = 1.0 ;
  Iden(1,1) = 1.0 ;
  Iden(2,2) = 1.0 ;

  //---------B-matrices------------------------------------

    static Matrix BJ(nstress,ndf) ;      // B matrix node J

    static Matrix BJtran(ndf,nstress) ;

    static Matrix BK(nstress,ndf) ;      // B matrix node k

    static Matrix BJtranD(ndf,nstress) ;

  //-------------------------------------------------------

  
  //zero stiffness and residual 
  stiff.Zero( ) ;

  //node coordinates
  computeBasis() ;

  //zero mean shape functions
  for ( p=0; p<nShape; p++ ) {
    for ( q=0; q<numberNodes; q++ ) {

      for (r=0; r<nMixed; r++ ) {
	shpBar[p][q][r] = 0.0 ;
	rightHandSide[p][q][r] = 0.0 ;
      }

    }//end for q
  } // end for p


  //zero volume
  volume = 0.0 ;

  //zero projection matrix  
  Proj.Zero( ) ;
  ProjInv.Zero( ) ;

  //gauss loop to compute and save shape functions 
  int count = 0 ;

  for ( i = 0; i < 3; i++ ) {
    for ( j = 0; j < 3; j++ ) {

        gaussPoint[0] = sg[i] ;        
	gaussPoint[1] = sg[j] ;        


	//save gauss point locations
	natCoorArray[0][count] = gaussPoint[0] ;
	natCoorArray[1][count] = gaussPoint[1] ;


	//get shape functions    
	shape2dNine( gaussPoint, xl, shp, xsj ) ;


	//save shape functions
	for ( p=0; p<nShape; p++ ) {
	  for ( q=0; q<numberNodes; q++ )
	    Shape[p][q][count] = shp[p][q] ;
	} // end for p

	
	//volume element to also be saved
	dvol[count] = ( wg[i]*wg[j] ) * xsj ;  


        //add to projection matrix
	interp[0] = 1.0 ;
	interp[1] = gaussPoint[0] ;
	interp[2] = gaussPoint[1] ;
	
	for ( r=0; r<nMixed; r++ ) {
	  for ( s=0; s<nMixed; s++ ) 
	    Proj(r,s) += ( interp[r]*interp[s] * dvol[count] ) ;
	}//end for r

	volume += dvol[count] ;
	
	
	//add to mean shape functions
	for ( p=0; p<nShape; p++ ) {
	  for ( q=0; q<numberNodes; q++ ) {

	    for ( s=0; s<nMixed; s++ ) 
	      rightHandSide[p][q][s] += ( shp[p][q] * interp[s] * dvol[count] ) ;

	  }//end for q 
	} // end for p


	//increment gauss point counter
	count++ ;

    } //end for j
  } // end for i 
  


  //invert projection matrix
  //int Solve(const Matrix &M, Matrix &res) const;
  Proj.Solve( Iden, ProjInv ) ;
  
  //mean value of shape functions
  for ( p=0; p<nShape; p++ ) {
    for ( q=0; q<numberNodes; q++ ) {

      for (r=0; r<nMixed; r++ ) {
	for (s=0; s<nMixed; s++ ) 
	  shpBar[p][q][r] += ( ProjInv(r,s) * rightHandSide[p][q][s] ) ;
      }//end for r

    }//end for q
  }//end for p


  //gauss loop 
  for ( i=0; i<numberGauss; i++ ) {
    
    //extract gauss point location
    gaussPoint[0] = natCoorArray[0][i] ;
    gaussPoint[1] = natCoorArray[1][i] ;

    //extract shape functions from saved array
    for ( p=0; p<nShape; p++ ) {
       for ( q=0; q<numberNodes; q++ )
	  shp[p][q]  = Shape[p][q][i] ;
    } // end for p

    dd = materialPointers[i]->getInitialTangent( ) ;
    dd *= dvol[i] ;


    //residual and tangent calculations node loops

    jj = 0 ;
    for ( j=0; j<numberNodes; j++ ) {

      BJ = computeBbar( j, gaussPoint, shp, shpBar ) ;
   
      //transpose 
      //BJtran = transpose( nstress, ndf, BJ ) ;
      for (p=0; p<ndf; p++) {
	for (q=0; q<nstress; q++) 
	  BJtran(p,q) = BJ(q,p) ;
      }//end for p


      //BJtranD = BJtran * dd ;
      BJtranD.addMatrixProduct(0.0,  BJtran,dd,1.0);

      kk = 0 ;
      for ( k=0; k<numberNodes; k++ ) {
	
	BK = computeBbar( k, gaussPoint, shp, shpBar ) ;
  
	
	//stiffJK =  BJtranD * BK  ;
	stiffJK.addMatrixProduct(0.0,  BJtranD,BK,1.0) ;

	for ( p=0; p<ndf; p++ )  {
	  for ( q=0; q<ndf; q++ )
	    stiff( jj+p, kk+q ) += stiffJK( p, q ) ;
	} //end for p
	
	kk += ndf ;
      }//end for k loop

      jj += ndf ;
    }//end for j loop
  }//end for i gauss loop 

  Ki = new Matrix(stiff);

  return stiff;
}
Esempio n. 14
0
//form residual and tangent
void  
ShellMITC9::formResidAndTangent( int tang_flag ) 
{
  //
  //  six(6) nodal dof's ordered :
  //
  //    -        - 
  //   |    u1    |   <---plate membrane
  //   |    u2    |
  //   |----------|
  //   |  w = u3  |   <---plate bending
  //   |  theta1  | 
  //   |  theta2  | 
  //   |----------|
  //   |  theta3  |   <---drill 
  //    -        -  
  //
  // membrane strains ordered :
  //
  //            strain(0) =   eps00     i.e.   (11)-strain
  //            strain(1) =   eps11     i.e.   (22)-strain
  //            strain(2) =   gamma01   i.e.   (12)-shear
  //
  // curvatures and shear strains ordered  :
  //
  //            strain(3) =     kappa00  i.e.   (11)-curvature
  //            strain(4) =     kappa11  i.e.   (22)-curvature
  //            strain(5) =   2*kappa01  i.e. 2*(12)-curvature 
  //
  //            strain(6) =     gamma02  i.e.   (13)-shear
  //            strain(7) =     gamma12  i.e.   (23)-shear
  //
  //  same ordering for moments/shears but no 2 
  //  
  //  Then, 
  //              epsilon00 = -z * kappa00      +    eps00_membrane
  //              epsilon11 = -z * kappa11      +    eps11_membrane
  //  gamma01 = 2*epsilon01 = -z * (2*kappa01)  +  gamma01_membrane 
  //
  //  Shear strains gamma02, gamma12 constant through cross section
  //

  static const int ndf = 6 ; //two membrane plus three bending plus one drill

  static const int nstress = 8 ; //three membrane, three moment, two shear

  static const int ngauss = 9 ;

  static const int numnodes = 9 ;

  int i,  j,  k, p, q ;
  int jj, kk ;
  int node ;

  int success ;
  
  double volume = 0.0 ;

  static double xsj ;  // determinant jacaobian matrix 

  static double dvol[ngauss] ; //volume element

  static Vector strain(nstress) ;  //strain

  static double shp[3][numnodes] ;  //shape functions at a gauss point

  static Vector residJ(ndf) ; //nodeJ residual 

  static Matrix stiffJK(ndf,ndf) ; //nodeJK stiffness 

  static Vector stress(nstress) ;  //stress resultants

  static Matrix dd(nstress,nstress) ;  //material tangent

  double epsDrill = 0.0 ;  //drilling "strain"

  double tauDrill = 0.0 ; //drilling "stress"

  //---------B-matrices------------------------------------

    static Matrix BJ(nstress,ndf) ;      // B matrix node J

    static Matrix BJtran(ndf,nstress) ;

    static Matrix BK(nstress,ndf) ;      // B matrix node k

    static Matrix BJtranD(ndf,nstress) ;


    static Matrix Bbend(3,3) ;  // bending B matrix

    static Matrix Bshear(2,3) ; // shear B matrix

    static Matrix Bmembrane(3,2) ; // membrane B matrix


    static double BdrillJ[ndf] ; //drill B matrix

    static double BdrillK[ndf] ;  

    double *drillPointer ;

    static double saveB[nstress][ndf][numnodes] ;

  //-------------------------------------------------------

    

  //zero stiffness and residual 
  stiff.Zero( ) ;
  resid.Zero( ) ;

  //compute Jacobian and inverse at center
  double L1 = 0.0 ;
  double L2 = 0.0 ;
  
  //gauss loop 
  for ( i = 0; i < ngauss; i++ ) {

    //get shape functions
    shape2d( sg[i], tg[i], xl, shp, xsj ) ;

    //volume element to also be saved
    dvol[i] = wg[i] * xsj ;
	volume += dvol[i] ;

    //zero the strains
    strain.Zero( ) ;
    epsDrill = 0.0 ;

    // j-node loop to compute strain 
    for ( j = 0; j < numnodes; j++ )  {

      //compute B matrix 

      Bmembrane = computeBmembrane( j, shp ) ;

      Bbend = computeBbend( j, shp ) ;

	  Bshear = computeBshear( j, shp ) ;
	  
      BJ = assembleB( Bmembrane, Bbend, Bshear ) ;

	  //save the B-matrix
	  for (p=0; p<nstress; p++) {
		for (q=0; q<ndf; q++ ) {
		  saveB[p][q][j] = BJ(p,q) ;
		}//end for q
	  }//end for p

      //nodal "displacements" 
      const Vector &ul = nodePointers[j]->getTrialDisp( ) ;

      //compute the strain
      //strain += (BJ*ul) ; 
      strain.addMatrixVector(1.0, BJ,ul,1.0 ) ;

      //drilling B matrix
      drillPointer = computeBdrill( j, shp ) ;
      for (p=0; p<ndf; p++ ) {
	    //BdrillJ[p] = *drillPointer++ ;
	    BdrillJ[p] = *drillPointer ; //set p-th component
	    drillPointer++ ;             //pointer arithmetic
      }//end for p

      //drilling "strain" 
      for ( p = 0; p < ndf; p++ )
	    epsDrill +=  BdrillJ[p]*ul(p) ;
	} // end for j
  

    //send the strain to the material 
    success = materialPointers[i]->setTrialSectionDeformation( strain ) ;

    //compute the stress
    stress = materialPointers[i]->getStressResultant( ) ;

    //drilling "stress" 
    tauDrill = Ktt * epsDrill ;

    //multiply by volume element
    stress   *= dvol[i] ;
    tauDrill *= dvol[i] ;

    if ( tang_flag == 1 ) {
      dd = materialPointers[i]->getSectionTangent( ) ;
      dd *= dvol[i] ;
    } //end if tang_flag


    //residual and tangent calculations node loops
    jj = 0 ;
    for ( j = 0; j < numnodes; j++ ) {

      //extract BJ
      for (p=0; p<nstress; p++) {
	    for (q=0; q<ndf; q++ )
	      BJ(p,q) = saveB[p][q][j]   ;
      }//end for p

      //multiply bending terms by (-1.0) for correct statement
      // of equilibrium  
      for ( p = 3; p < 6; p++ ) {
	    for ( q = 3; q < 6; q++ ) 
	      BJ(p,q) *= (-1.0) ;
      } //end for p

      //transpose 
      //BJtran = transpose( 8, ndf, BJ ) ;
      for (p=0; p<ndf; p++) {
	    for (q=0; q<nstress; q++) 
	      BJtran(p,q) = BJ(q,p) ;
      }//end for p

      //residJ = BJtran * stress ;
      residJ.addMatrixVector(0.0, BJtran,stress,1.0 ) ;

      //drilling B matrix
      drillPointer = computeBdrill( j, shp ) ;
      for (p=0; p<ndf; p++ ) {
	    BdrillJ[p] = *drillPointer ;
	    drillPointer++ ;
      }//end for p

      //residual including drill
      for ( p = 0; p < ndf; p++ )
        resid( jj + p ) += ( residJ(p) + BdrillJ[p]*tauDrill ) ;

      if ( tang_flag == 1 ) {

        //BJtranD = BJtran * dd ;
	    BJtranD.addMatrixProduct(0.0, BJtran,dd,1.0 ) ;
        
	    for (p=0; p<ndf; p++) {
	      BdrillJ[p] *= ( Ktt*dvol[i] ) ;
        }//end for p

        kk = 0 ;
        for ( k = 0; k < numnodes; k++ ) {
          //extract BK
	      for (p=0; p<nstress; p++) {
	        for (q=0; q<ndf; q++ ){
	          BK(p,q) = saveB[p][q][k];
              
			}//end for q
		  }//end for p
	  
    	  //drilling B matrix
	      drillPointer = computeBdrill( k, shp ) ;
	      for (p=0; p<ndf; p++ ) {
	        BdrillK[p] = *drillPointer ;
	        drillPointer++ ;
		  }//end for p
  
          //stiffJK = BJtranD * BK  ;
	      // +  transpose( 1,ndf,BdrillJ ) * BdrillK ; 
	      stiffJK.addMatrixProduct(0.0, BJtranD,BK,1.0 ) ;

          for ( p = 0; p < ndf; p++ )  {
	        for ( q = 0; q < ndf; q++ ) {
	           stiff( jj+p, kk+q ) += stiffJK(p,q)
		                 + ( BdrillJ[p]*BdrillK[q] ) ;
			}//end for q
		  }//end for p
          kk += ndf ;
		} // end for k loop
	  } // end if tang_flag 
      jj += ndf ;
    } // end for j loop
  } //end for i gauss loop

  return ;
}
Esempio n. 15
0
const Matrix &
CoupledZeroLength::getTangentStiff(void)
{
    double E;

    // stiff is a reference to the matrix holding the stiffness matrix
    Matrix& stiff = *theMatrix;
    
    // zero stiffness matrix
    stiff.Zero();

    E = theMaterial->getTangent();    

    int numNodeDof = numDOF/2;
    int dirn1b = dirn1+numNodeDof;
    int dirn2b = dirn2+numNodeDof;

    double strain = sqrt(dX*dX + dY*dY);
    double L = strain;

    stiff(dirn1,dirn1)   = E;
    stiff(dirn1b,dirn1b) = E;      
    stiff(dirn1,dirn1b)  = -E;
    stiff(dirn1b,dirn1)  = -E;      
    
    stiff(dirn2,dirn2)   = E;
    stiff(dirn2b,dirn2b) = E;      
    stiff(dirn2,dirn2b)  = -E;
    stiff(dirn2b,dirn2)  = -E;      
    
    /*
    } else {

      double cs = dX/L;
      double sn = dY/L;

      stiff(dirn1,dirn1)  = cs*cs*E;
      stiff(dirn2,dirn1)  = cs*sn*E;
      stiff(dirn1b,dirn1) = -cs*cs*E;
      stiff(dirn2b,dirn1) = -sn*cs*E;

      stiff(dirn1,dirn2)  = cs*sn*E;
      stiff(dirn2,dirn2)  = sn*sn*E;
      stiff(dirn1b,dirn2) = -cs*sn*E;
      stiff(dirn2b,dirn2) = -sn*sn*E;

      stiff(dirn1,dirn1b)  = -cs*cs*E;
      stiff(dirn2,dirn1b)  = -cs*sn*E;
      stiff(dirn1b,dirn1b) = cs*cs*E;
      stiff(dirn2b,dirn1b) = sn*cs*E;

      stiff(dirn1,dirn2b)  = -cs*sn*E;
      stiff(dirn2,dirn2b)  = -sn*sn*E;
      stiff(dirn1b,dirn2b) = cs*sn*E;
      stiff(dirn2b,dirn2b) = sn*sn*E;
    }
    */
    //      opserr << "dX: " << dX << " dY: " << dY << "strain: " << theMaterial->getStrain() << endln;
    //      opserr << "CoupledZeroLength::getTangentStiff(void): E:" << E << "\n" << stiff;
  return stiff;
}
Esempio n. 16
0
//return stiffness matrix
const Matrix&  BbarBrick::getInitialStiff( )
{
  if (Ki != 0)
    return *Ki;

  //strains ordered : eps11, eps22, eps33, 2*eps12, 2*eps23, 2*eps31

  static const int ndm = 3 ;

  static const int ndf = 3 ;

  static const int nstress = 6 ;

  static const int numberNodes = 8 ;

  static const int numberGauss = 8 ;

  static const int nShape = 4 ;

  int i, j, k, p, q ;
  int jj, kk ;

  static double volume ;

  static double xsj ;  // determinant jacaobian matrix

  static double dvol[numberGauss] ; //volume element

  static double gaussPoint[ndm] ;

  static Vector strain(nstress) ;  //strain

  static double shp[nShape][numberNodes] ;  //shape functions at a gauss point

  static double Shape[nShape][numberNodes][numberGauss] ; //all the shape functions

  static double shpBar[nShape][numberNodes] ;  //mean value of shape functions

  static Matrix stiffJK(ndf,ndf) ; //nodeJK stiffness

  static Matrix dd(nstress,nstress) ;  //material tangent


  //---------B-matrices------------------------------------

    static Matrix BJ(nstress,ndf) ;      // B matrix node J

    static Matrix BJtran(ndf,nstress) ;

    static Matrix BK(nstress,ndf) ;      // B matrix node k

    static Matrix BJtranD(ndf,nstress) ;

  //-------------------------------------------------------


  //zero stiffness and residual
  stiff.Zero( ) ;


  //compute basis vectors and local nodal coordinates
  computeBasis( ) ;

  //zero mean shape functions
  for ( p = 0; p < nShape; p++ ) {
    for ( q = 0; q < numberNodes; q++ )
      shpBar[p][q] = 0.0 ;
  } // end for p

  //zero volume
  volume = 0.0 ;


  //gauss loop to compute and save shape functions
  int count = 0 ;

  for ( i = 0; i < 2; i++ ) {
    for ( j = 0; j < 2; j++ ) {
      for ( k = 0; k < 2; k++ ) {

        gaussPoint[0] = sg[i] ;
	gaussPoint[1] = sg[j] ;
	gaussPoint[2] = sg[k] ;

	//get shape functions
	shp3d( gaussPoint, xsj, shp, xl ) ;

	//save shape functions
	for ( p = 0; p < nShape; p++ ) {
	  for ( q = 0; q < numberNodes; q++ )
	    Shape[p][q][count] = shp[p][q] ;
	} // end for p

	//volume element to also be saved
	dvol[count] = wg[count] * xsj ;

        //add to volume
	volume += dvol[count] ;

	//add to mean shape functions
	for ( p = 0; p < nShape; p++ ) {
	  for ( q = 0; q < numberNodes; q++ )
	    shpBar[p][q] += ( dvol[count] * shp[p][q] ) ;
	} // end for p

	count++ ;

      } //end for k
    } //end for j
  } // end for i


  //mean value of shape functions
  for ( p = 0; p < nShape; p++ ) {
    for ( q = 0; q < numberNodes; q++ )
      shpBar[p][q] /= volume ;
  } // end for p


  //gauss loop
  for ( i = 0; i < numberGauss; i++ ) {

    //extract shape functions from saved array
    for ( p = 0; p < nShape; p++ ) {
       for ( q = 0; q < numberNodes; q++ )
	  shp[p][q]  = Shape[p][q][i] ;
    } // end for p

    dd = materialPointers[i]->getInitialTangent( ) ;
    dd *= dvol[i] ;

    //residual and tangent calculations node loops

    jj = 0 ;
    for ( j = 0; j < numberNodes; j++ ) {

      BJ = computeBbar( j, shp, shpBar ) ;

      //transpose
      //BJtran = transpose( nstress, ndf, BJ ) ;
      for (p=0; p<ndf; p++) {
	for (q=0; q<nstress; q++)
	  BJtran(p,q) = BJ(q,p) ;
      }//end for p

      //BJtranD = BJtran * dd ;
      BJtranD.addMatrixProduct(0.0,  BJtran,dd,1.0);

      kk = 0 ;
      for ( k = 0; k < numberNodes; k++ ) {

	BK = computeBbar( k, shp, shpBar ) ;

	//stiffJK =  BJtranD * BK  ;
	stiffJK.addMatrixProduct(0.0,  BJtranD,BK,1.0) ;

	for ( p = 0; p < ndf; p++ )  {
	  for ( q = 0; q < ndf; q++ )
	    stiff( jj+p, kk+q ) += stiffJK( p, q ) ;
	} //end for p

	kk += ndf ;
      } // end for k loop

      jj += ndf ;

    } // end for j loop
  } //end for i gauss loop

  Ki = new Matrix(stiff);

  return stiff ;
}
Esempio n. 17
0
void  ZeroLengthInterface2D::formLocalResidAndTangent( int tang_flag , int slave, int master1, int master2, int stage)
{
	// trial frictional force vectors (in local coordinate)
    double t_trial;
    double TtrNorm;
    // Coulomb friction law surface
	double Phi;
	int i, j;

	// set the first value to zero
	pressure(slave) = 0;
    t_trial=0;

	// int IsContact;
	// detect contact and set flag
    ContactFlag = contactDetect(slave,master1,master2, stage);

	if (ContactFlag == 1) // contacted
	{
	    // create a vector for converting local matrix to global
        GlobalResidAndTangentOrder(slave, master1, master2);

		// contact presure;
	    pressure(slave) = Kn * normal_gap(slave);  // pressure is positive if in contact

	    double ng = normal_gap(slave);

		t_trial = Kt * (shear_gap(slave) - stored_shear_gap(slave));  // trial shear force

        // Coulomb friction law, trial state
		//TtrNorm=t_trial.Norm();
		TtrNorm = sqrt(t_trial * t_trial);
		Phi = TtrNorm - fc * pressure(slave);

		if (Phi <= 0 ) { // stick case
 			if ( tang_flag == 1 ) {
		    // stiff
				for (i = 0; i < 6; i++) {
					for (j = 0; j < 6; j++) {
                        stiff(loctoglob[i],loctoglob[j]) +=   Kn * (N(i) * N(j)) + Kt * (T(i) * T(j));	//2D
					}
				}
			} //endif tang_flag
			// force
			for (i = 0; i < 6; i++) resid(loctoglob[i]) += pressure(slave) * N(i) + t_trial * T(i);    //2D
		} // end if stick
		else {           // slide case, non-symmetric stiff
            ContactFlag=2;  // set the contactFlag for sliding
            if ( tang_flag == 1 ) {
				// stiff
				for (i = 0; i < 6; i++) {
					for (j = 0; j < 6; j++) {
					stiff(loctoglob[i],loctoglob[j]) += Kn * (N(i) * N(j)) - fc * Kn * (t_trial / TtrNorm) * T(i) * N(j); //2D
					} //endfor i
				} //endfor j
   			    // force
			} // endif tang_flag
            double shear = fc * pressure(slave) * (t_trial/TtrNorm);
			for (i = 0; i < 6; i++) resid(loctoglob[i]) += (pressure(slave) * N(i)) + (shear * T(i)) ;      //2D
		} //endif slide
	}  // endif ContactFlag==1
}
Esempio n. 18
0
void  ZeroLengthContact2D::formResidAndTangent( int tang_flag )
{

	//opserr<<this->getTag()<< " ZeroLengthContact2D:: formResidAndTangent()" <<endln;


	// trial displacement vectors
 	Vector DispTrialS(2); // trial disp for slave node
	Vector DispTrialM(2); // trial disp for master node
	// trial frictional force vectors (in local coordinate)
    double t_trial;
    double TtrNorm;

    // Coulomb friction law surface
	double Phi;

    int i, j;

    //zero stiffness and residual
    stiff.Zero( ) ;
    resid.Zero( ) ;

	pressure = 0;
    t_trial=0;

	//int IsContact;
	// detect contact and set flag
    ContactFlag = contactDetect();

	//opserr<<this->getTag()<< " ZeroLengthContact2D::ContactFlag=" << ContactFlag<<endln;

	if (ContactFlag == 1) // contacted
	//if (gap >= 0) // contacted
    //if ((lambda + Kn*gap) >= 0)  // changed for augmented lagrange
	{
       // contact presure;
	    pressure = Kn*gap ;  // pressure is positive if in contact
       // pressure = Kn*gap + lambda;  // changed for augmented lagrange

		DispTrialS=nodePointers[0]->getTrialDisp();
        DispTrialM=nodePointers[1]->getTrialDisp();

        //opserr<<"DispTrialS " << DispTrialS;
        //opserr<<"DispTrialM " << DispTrialM;

       //nodal displacements
        double ul[4];

		ul[0]=DispTrialS(0);
		ul[1]=DispTrialS(1);
 		ul[2]=DispTrialM(0);
		ul[3]=DispTrialM(1);

		t_trial = 0;
        xi=0;


		// relative slide displacement
		// xi = T_tran * u    eq. (3.5)
		for (i=0; i<4; i++){
			xi  += T (i)*ul[i];
		}

		//for (i=0; i<2; i++){ t_trial(i)=Kt * (xi(i)-stickPt(i));}  //3D

		 t_trial=Kt*(xi-stickPt);  // trial shear force
         /// t_trial=Kt*(xi);  // no update of stickPt, updated Jan 26, 2004

        // Coulomb friction law, trial state

		//TtrNorm=t_trial.Norm();

		TtrNorm=sqrt(t_trial*t_trial);

		Phi = TtrNorm - fs * pressure;


		if (Phi <= 0 ) { // stick case
  		//opserr<< "stick ...." << endln;

 			if ( tang_flag == 1 ) {
		    // stiff
				for (i=0; i<4; i++) {
					for (j=0; j<4; j++) {
						//stiff(i,j) = Kn*(N(i)*N(j)) + Kt*(T(i)*T1(j)+T2(i)*T2(j));// 3D
                        stiff(i,j) =   Kn*(N(i)*N(j)) + Kt*(T(i)*T(j));	//2D
					}
				}
			} //endif tang_flag
			// force
			for (i=0; i<4; i++)
				 resid(i)= (-1*pressure)*N(i) + t_trial*T(i);    //2D
			//	 resid(i)= (-1*pressure)*N(i) + t_trial(0)*T1(i) + t_trial(1)*T2(i) ;%3D

		} // end if stick
		else {           // slide case, non-symmetric stiff
            ContactFlag=2;  // set the contactFlag for sliding

		 	//opserr<< "sliding ...." << endln;


            if ( tang_flag == 1 ) {
				// stiff
				for (i=0; i<4; i++) {
					for (j=0; j<4; j++) {
					// 3D
					//	define: Pt1=t_trial(0)/TtrNorm;
				    //  define: Pt2=t_trial(1)/TtrNorm;
					//	define: C1=fs*Kn;
                    //  C2 term will be zero in two dimensional formulation
					// stiff(i,j) = Kn*(N(i)*N(j)) - C1*(Pt1*T1(i)*N(j)+Pt2*T2(i)*N(j))
					//	    + C2*( (1-Pt1*Pt1)*T1(i)*T1(j) -    Pt1*Pt2 *T1(i)*T2(j)
					//      - Pt1*Pt2 *T2(i)*T1(j) + (1-Pt1*Pt2)*T2(i)*T2(j)  );  //3D

					// 2D                 ???? - or + ????
					stiff(i,j) = Kn*(N(i)*N(j)) - fs*Kn* (t_trial/TtrNorm)*T(i)*N(j); //2D
					} //endfor i
				} //endfor j
			} // endif tang_flag

			// force
			double shear=fs*pressure* (t_trial/TtrNorm);

			for (i=0; i<4; i++) {
				resid(i) = (-1*pressure)*N(i) + shear *T (i) ;      //2D
			//	resid(i) = (-1*pressure)*N(i) + t1*T1(i)+t2*T2(i) ; //3D
			}
		} //endif slide

	}  // endif ContactFlag==1



	//opserr<<"gap=" << gap <<endln;
    //opserr<<"pressure= "<<pressure <<endln;
    //opserr<<"lambda=   "<<lambda <<endln;
	//opserr<<"t_trial= "<<t_trial <<endln;
    //opserr<<"stickPt= "<<stickPt <<endln;
	//opserr<<"residue= "<<resid <<endln;

	// for NOT contact, do nothing, stiff and resid are zeroes




    /* my notes:
	   the direction of residual force is always confusing ...
	      R=KU-Fext
	   is defined as the resisting force that could provided by the element


       Let p,shear be absolute value of pressure and shear force, always positive

       thus,

                                Rx(1)=p*(-n)
                                 ||
							    \||/
						      ___\/____
						     /         \       /\
             Rx(1)     ---\ /    (1)    \     /||\n    Note: (t,n) follows RightHand rule
	         =shear*t  ---/ \   slave   /      ||
							 \_________/       ||_____\t
						-----------------------*------/
                        |                      |
                        |                      |
						|    (2) Master        |/---- Rx(2) = shear*(-t)
						|                      |\----
						------------------------
                                  /\
								 /||\
                                  ||
								 Rx(2)=pn

     Denote :  N={n; -n}; T={t; -t}; arrange resid={R(1); R(2)}

     Finally,  resid(i) = (- p)*N(i) + shear *T (i) ;


  */

}
//form residual and tangent
void ConstantPressureVolumeQuad ::  formResidAndTangent( int tang_flag ) 
{
  // strains ordered  00, 11, 22, 01  
  //            i.e.  11, 22, 33, 12 
  //
  //            strain(0) =   eps_00
  //            strain(1) =   eps_11
  //            strain(2) =   eps_22
  //            strain(3) = 2*eps_01
  //
  //  same ordering for stresses but no 2 

  int i,  j,  k, l, p, q ;
  int jj, kk ;
  
  static double tmp_shp[3][4] ; //shape functions

  static double shp[3][4][4] ; //shape functions at each gauss point

  static double vol_avg_shp[3][4] ; // volume averaged shape functions

  double xsj ;  // determinant jacaobian matrix 

  static Matrix sx(2,2) ; // inverse jacobian matrix 

  double dvol[4] ; //volume elements

  double volume = 0.0 ; //volume of element

  double pressure = 0.0 ; //constitutive pressure  

  static Vector strain(4) ; //strain in vector form 

  // static Vector sigBar(4) ; //stress in vector form
  static Vector sig(4) ; //mixed stress in vector form

  double trace = 0.0 ; //trace of the strain 

  static Matrix BJtran(2,4) ; 
  static Matrix BK(4,2) ;

  static Matrix littleBJtran(2,1) ;
  static Matrix littleBK(1,2) ; 

  static Matrix stiffJK(2,2) ; //nodeJ-nodeK 2x2 stiffness
  static Vector residJ(2) ; //nodeJ residual 
  
  static Vector one(4) ; //rank 2 identity as a vector
  
  static Matrix Pdev(4,4) ; //deviator projector

  //  static Matrix dd(4,4) ;  //material tangent

  static Matrix ddPdev(4,4) ;
  static Matrix PdevDD(4,4) ;

  static double Pdev_dd_Pdev_data[16];
  static double Pdev_dd_one_data[4]; 
  static double one_dd_Pdev_data[4];
  static Matrix Pdev_dd_Pdev(Pdev_dd_Pdev_data, 4, 4);
  static Matrix Pdev_dd_one(Pdev_dd_one_data, 4, 1); 
  static Matrix one_dd_Pdev(one_dd_Pdev_data, 1,4) ;

  double bulk ;
  static Matrix BJtranD(2,4) ;
  static Matrix BJtranDone(2,1) ;

  static Matrix littleBJoneD(2,4) ;
  static Matrix littleBJtranBulk(2,1) ;
  
  //zero stiffness and residual 
  if ( tang_flag == 1 ) 
    stiff.Zero();
  else
    resid.Zero();

  //one vector
  one(0) = 1.0 ;
  one(1) = 1.0 ;
  one(2) = 1.0 ;
  one(3) = 0.0 ;

  //Pdev matrix
  Pdev.Zero( ) ;

  Pdev(0,0) =  two3 ;
  Pdev(0,1) = -one3 ;
  Pdev(0,2) = -one3 ;

  Pdev(1,0) = -one3 ;
  Pdev(1,1) =  two3 ;
  Pdev(1,2) = -one3 ;

  Pdev(2,0) = -one3 ;
  Pdev(2,1) = -one3 ;
  Pdev(2,2) =  two3 ;

  Pdev(3,3) = 1.0 ;

  //zero stuff
  volume = 0.0 ;

  for ( k = 0; k < 3; k++ ){
    for ( l = 0; l < 4; l++ ) 
        vol_avg_shp[k][l] = 0.0 ; 
  } //end for k


  //gauss loop to compute volume averaged shape functions

  for ( i = 0; i < 4; i++ ){
    
    shape2d( sg[i], tg[i], xl, tmp_shp, xsj, sx ) ;

    dvol[i] = wg[i] * xsj ;  // multiply by radius for axisymmetry 

    volume += dvol[i] ;

    for ( k = 0; k < 3; k++ ){
      for ( l = 0; l < 4; l++ ) {

	shp[k][l][i] = tmp_shp[k][l] ;

        vol_avg_shp[k][l] += tmp_shp[k][l] * dvol[i] ;

      } // end for l
    } //end for k

  } //end for i 


  //compute volume averaged shape functions
  for ( k = 0; k < 3; k++ ){
    for ( l = 0; l < 4; l++ ) 
        vol_avg_shp[k][l] /= volume ; 
  } //end for k

  //compute pressure if residual calculation
  if (tang_flag != 1) {
    pressure = 0.0 ;
    for ( i = 0; i < 4; i++ ) {

      const Vector &sigBar = materialPointers[i]->getStress( ) ;

      pressure +=  one3 * ( sigBar(0) + sigBar(1) + sigBar(2) ) * dvol[i] ;
      
    } // end for i

    pressure /= volume ;
  } // end if != tang_flag

  //residual and tangent calculations gauss loop
  
  for ( i = 0; i < 4; i++ ) {

    if ( tang_flag == 1 ) {    // compute matrices for stiffness calculation
      
      static Matrix dd(4,4);
      dd = materialPointers[i]->getTangent( ) ;
      
      dd *= dvol[i] ;
      
      //Pdev_dd_Pdev = Pdev * dd * Pdev ;
      Pdev_dd_Pdev.addMatrixTripleProduct(0.0,
					  Pdev,
					  dd,
					  1.0) ;
      
      //Pdev_dd_one  = one3 * ( Pdev * dd * oneMatrix ) ;
      PdevDD.addMatrixProduct(0.0, Pdev, dd, 1.0) ;
      Pdev_dd_one(0,0) = one3 * (PdevDD(0,0) + PdevDD(0,1) + PdevDD(0,2));
      Pdev_dd_one(1,0) = one3 * (PdevDD(1,0) + PdevDD(1,1) + PdevDD(1,2));
      Pdev_dd_one(2,0) = one3 * (PdevDD(2,0) + PdevDD(2,1) + PdevDD(2,2));
      Pdev_dd_one(3,0) = one3 * (PdevDD(3,0) + PdevDD(3,1) + PdevDD(3,2));
      
      //one_dd_Pdev  = one3 * ( oneTran * dd * Pdev ) ;
      ddPdev.addMatrixProduct(0.0, dd, Pdev, 1.0) ;
      one_dd_Pdev(0,0) = one3 * (ddPdev(0,0) + ddPdev(1,0) + ddPdev(2,0));
      one_dd_Pdev(0,1) = one3 * (ddPdev(0,1) + ddPdev(1,1) + ddPdev(2,1));
      one_dd_Pdev(0,2) = one3 * (ddPdev(0,2) + ddPdev(1,2) + ddPdev(2,2));
      one_dd_Pdev(0,3) = one3 * (ddPdev(0,3) + ddPdev(1,3) + ddPdev(2,3));
      
      bulk = one9 * ( dd(0,0) + dd(0,1) + dd(0,2)  
		      + dd(1,0) + dd(1,1) + dd(1,2) 
		      + dd(2,0) + dd(2,1) + dd(2,2) ) ;
      
    } else { // compute stress for residual calculation
      //stress for equilibrium
      const Vector &sigBar = materialPointers[i]->getStress( ) ; 
      trace = sigBar(0) + sigBar(1) + sigBar(2) ;
      sig  = sigBar ;

      //sig -= (one3*trace)*one ;
      sig.addVector(1.0,  one, -one3*trace ) ;
      sig.addVector(1.0,  one, pressure ) ;
      
      //multilply by volume elements and compute 
      sig *= dvol[i] ;
    }
        
    //residual and tangent loop over nodes
    jj = 0 ;
    for ( j = 0; j < 4; j++ ) {

      /********** expanding for efficiency the matrix operations that use these
      BJ.Zero( );
      BJ(0,0) = shp[0][j][i] ;
      BJ(1,1) = shp[1][j][i] ; 

      // BJ(2,0) for axi-symmetry 

      BJ(3,0) = shp[1][j][i]  ;
      BJ(3,1) = shp[0][j][i]  ;

      littleBJ(0,0) = vol_avg_shp[0][j] ;
      littleBJ(0,1) = vol_avg_shp[1][j] ;

      // BJtran = this->transpose( 4, 2, BJ ) ;
      for (p=0; p<2; p++) {
	for (q=0; q<4; q++) 
	  BJtran(p,q) = BJ(q,p) ;
      }//end for p

      for (p=0; p<2; p++) {
        for (q=0; q<1; q++) 
          littleBJtran(p,q) = littleBJ(q,p) ;
      }//end for p

      **********************************************************************/


      double BJ00 = shp[0][j][i];
      double BJ11 = shp[1][j][i]; 
      double BJ30 = shp[1][j][i];
      double BJ31 = shp[0][j][i];

      BJtran.Zero( );
      BJtran(0,0) = shp[0][j][i] ;
      BJtran(1,1) = shp[1][j][i] ; 

      // BJ(2,0) for axi-symmetry 

      BJtran(0,3) = shp[1][j][i]  ;
      BJtran(1,3) = shp[0][j][i]  ;

      //compute residual 

      if ( tang_flag == 1 ) { //stiffness matrix

	double ltBJ00 = vol_avg_shp[0][j] ;
	double ltBJ01 = vol_avg_shp[1][j] ;

	//BJtranD          =  BJtran * Pdev_dd_Pdev ;
	// BJtranD.addMatrixProduct(0.0,  BJtran, Pdev_dd_Pdev, 1.0);

	//littleBJoneD     =  littleBJtran * one_dd_Pdev ;
	// littleBJoneD.addMatrixProduct(0.0,  littleBJtran, one_dd_Pdev, 1.0);

	static double Adata[8];
	static Matrix A(Adata, 2, 4);

	// A = BJtranD;
	// A += littleBJoneD;

	for (int colA = 0, loc = 0, colPdev = 0; colA<4; colA++, colPdev += 4) {
	  double data3colA = Pdev_dd_Pdev_data[3+colPdev];
	  Adata[loc++] = BJ00*Pdev_dd_Pdev_data[colPdev] + BJ30*data3colA + ltBJ00*one_dd_Pdev_data[colA];
	  Adata[loc++] = BJ11*Pdev_dd_Pdev_data[1+colPdev] + BJ31*data3colA + ltBJ01*one_dd_Pdev_data[colA];
	}

        //BJtranDone       =  BJtran * Pdev_dd_one ;
	// BJtranDone.addMatrixProduct(0.0,  BJtran, Pdev_dd_one, 1.0);

	//littleBJtranBulk =  bulk * littleBJtran ;
	// littleBJtranBulk = littleBJtran ;
	// littleBJtranBulk *= bulk ;

	double B1, B2;
	// B1 = BJtranDone(0,0) + littleBJtranBulk(0,0);
	// B2 = BJtranDone(1,0) + littleBJtranBulk(1,0);

	B1 = BJ00*Pdev_dd_one_data[0] + BJ30*Pdev_dd_one_data[3] + ltBJ00 *bulk;
	B2 = BJ11*Pdev_dd_one_data[1] + BJ31*Pdev_dd_one_data[3] + ltBJ01 *bulk;

	int colkk, colkkP1;
	for ( k = 0, kk=0, colkk =0, colkkP1 =8; 
	      k < 4; 
	      k++, kk += 2, colkk += 16, colkkP1 += 16 ) {

	  /**************************************************************
	   REPLACING THESE LINES WITH THE 4 BELOW COMMENT FOR EFFICIENCY
	   BK.Zero( );
	   BK(0,0) = shp[0][k][i];
	   BK(1,1) = shp[1][k][i];
	   
	   // BK(2,0) for axi-symmetry 
	   
	   BK(3,0) = shp[1][k][i];
	   BK(3,1) = shp[0][k][i];
	  **************************************************************/

	  double BK00 = shp[0][k][i];
	  double BK11 = shp[1][k][i];
	  double BK30 = shp[1][k][i];
	  double BK31 = shp[0][k][i];

	  double littleBK00 = vol_avg_shp[0][k];
	  double littleBK01 = vol_avg_shp[1][k];

	  //compute stiffness matrix
        
	  // stiffJK =  ( BJtranD + littleBJoneD ) * BK
	  //        +  ( BJtranDone + littleBJtranBulk ) * littleBK ; 

	  /**************************************************************
	    REPLACING THESE LINES WITH THE 4 BELOW COMMENT FOR EFFICIENCY
	  //stiffJK.addMatrixProduct(0.0, A, BK, 1.0);

	  //stiff( jj,   kk   ) += stiffJK(0,0) + B1 * littleBK00;
	  //stiff( jj+1, kk   ) += stiffJK(1,0) + B2 * littleBK00;
	  //stiff( jj,   kk+1 ) += stiffJK(0,1) + B1 * littleBK01;
	  //stiff( jj+1, kk+1 ) += stiffJK(1,1) + B2 * littleBK01;	  
	  ***************************************************************/

	  // matrixData[  colkk +   jj] += Adata[0]*BK00 + Adata[6]*BK30 + B1 * littleBK00;
	  // matrixData[  colkk + jj+1] += Adata[1]*BK00 + Adata[7]*BK30 + B2 * littleBK00;
	  // matrixData[colkkP1 +   jj] += Adata[2]*BK11 + Adata[6]*BK31 + B1 * littleBK01;
	  // matrixData[colkkP1 + jj+1] += Adata[3]*BK11 + Adata[7]*BK31 + B2 * littleBK01;
	  stiff( jj,   kk   ) += Adata[0]*BK00 + Adata[6]*BK30 + B1 * littleBK00;
	  stiff( jj+1, kk   ) += Adata[1]*BK00 + Adata[7]*BK30 + B2 * littleBK00;
	  stiff( jj,   kk+1 ) += Adata[2]*BK11 + Adata[6]*BK31 + B1 * littleBK01;
	  stiff( jj+1, kk+1 ) += Adata[3]*BK11 + Adata[7]*BK31 + B2 * littleBK01;

	} // end for k

      } else { // residual calculation
	
	//residJ = BJtran * sig; 
	residJ.addMatrixVector(0.0,  BJtran, sig, 1.0);
	resid( jj   ) += residJ(0);
	resid( jj+1 ) += residJ(1);
      }
      
      jj += 2 ;
    } // end for j 

  } //end for i

  
  return ;
}
const Matrix& ConstantPressureVolumeQuad :: getInitialStiff( ) 
{
  int i,  j,  k, l, p, q ;
  int jj, kk ;
  
  static double tmp_shp[3][4] ; //shape functions

  static double shp[3][4][4] ; //shape functions at each gauss point

  static double vol_avg_shp[3][4] ; // volume averaged shape functions

  double xsj ;  // determinant jacaobian matrix 

  static Matrix sx(2,2) ; // inverse jacobian matrix 

  double dvol[4] ; //volume elements

  double volume = 0.0 ; //volume of element

  double pressure = 0.0 ; //constitutive pressure  

  static Vector strain(4) ; //strain in vector form 

  // static Vector sigBar(4) ; //stress in vector form
  static Vector sig(4) ; //mixed stress in vector form

  double trace = 0.0 ; //trace of the strain 

  static Matrix BJtran(2,4) ; 
  static Matrix BK(4,2) ;

  static Matrix littleBJtran(2,1) ;
  static Matrix littleBK(1,2) ; 

  static Matrix stiffJK(2,2) ; //nodeJ-nodeK 2x2 stiffness
  static Vector residJ(2) ; //nodeJ residual 
  
  static Vector one(4) ; //rank 2 identity as a vector
  
  static Matrix Pdev(4,4) ; //deviator projector

  //  static Matrix dd(4,4) ;  //material tangent

  static Matrix ddPdev(4,4) ;
  static Matrix PdevDD(4,4) ;

  static double Pdev_dd_Pdev_data[16];
  static double Pdev_dd_one_data[4]; 
  static double one_dd_Pdev_data[4];
  static Matrix Pdev_dd_Pdev(Pdev_dd_Pdev_data, 4, 4);
  static Matrix Pdev_dd_one(Pdev_dd_one_data, 4, 1); 
  static Matrix one_dd_Pdev(one_dd_Pdev_data, 1,4) ;

  double bulk ;
  static Matrix BJtranD(2,4) ;
  static Matrix BJtranDone(2,1) ;

  static Matrix littleBJoneD(2,4) ;
  static Matrix littleBJtranBulk(2,1) ;
  
  //zero stiffness and residual 
  stiff.Zero();

  //one vector
  one(0) = 1.0 ;
  one(1) = 1.0 ;
  one(2) = 1.0 ;
  one(3) = 0.0 ;

  //Pdev matrix
  Pdev.Zero( ) ;

  Pdev(0,0) =  two3 ;
  Pdev(0,1) = -one3 ;
  Pdev(0,2) = -one3 ;

  Pdev(1,0) = -one3 ;
  Pdev(1,1) =  two3 ;
  Pdev(1,2) = -one3 ;

  Pdev(2,0) = -one3 ;
  Pdev(2,1) = -one3 ;
  Pdev(2,2) =  two3 ;

  Pdev(3,3) = 1.0 ;

  //zero stuff
  volume = 0.0 ;

  for ( k = 0; k < 3; k++ ){
    for ( l = 0; l < 4; l++ ) 
        vol_avg_shp[k][l] = 0.0 ; 
  } //end for k


  //gauss loop to compute volume averaged shape functions

  for ( i = 0; i < 4; i++ ){
    
    shape2d( sg[i], tg[i], xl, tmp_shp, xsj, sx ) ;

    dvol[i] = wg[i] * xsj ;  // multiply by radius for axisymmetry 

    volume += dvol[i] ;

    for ( k = 0; k < 3; k++ ){
      for ( l = 0; l < 4; l++ ) {

	shp[k][l][i] = tmp_shp[k][l] ;

        vol_avg_shp[k][l] += tmp_shp[k][l] * dvol[i] ;

      } // end for l
    } //end for k

  } //end for i 


  //compute volume averaged shape functions
  for ( k = 0; k < 3; k++ ){
    for ( l = 0; l < 4; l++ ) 
        vol_avg_shp[k][l] /= volume ; 
  } //end for k

  //residual and tangent calculations gauss loop
  for ( i = 0; i < 4; i++ ) {

    static Matrix dd(4,4);

    dd = materialPointers[i]->getInitialTangent( ) ;

    dd *= dvol[i] ;
    
    //Pdev_dd_Pdev = Pdev * dd * Pdev ;
    Pdev_dd_Pdev.addMatrixTripleProduct(0.0,
					Pdev,
					dd,
					1.0) ;
      
    //Pdev_dd_one  = one3 * ( Pdev * dd * oneMatrix ) ;
    PdevDD.addMatrixProduct(0.0, Pdev, dd, 1.0) ;
    Pdev_dd_one(0,0) = one3 * (PdevDD(0,0) + PdevDD(0,1) + PdevDD(0,2));
    Pdev_dd_one(1,0) = one3 * (PdevDD(1,0) + PdevDD(1,1) + PdevDD(1,2));
    Pdev_dd_one(2,0) = one3 * (PdevDD(2,0) + PdevDD(2,1) + PdevDD(2,2));
    Pdev_dd_one(3,0) = one3 * (PdevDD(3,0) + PdevDD(3,1) + PdevDD(3,2));
    
    //one_dd_Pdev  = one3 * ( oneTran * dd * Pdev ) ;
    ddPdev.addMatrixProduct(0.0, dd, Pdev, 1.0) ;
    one_dd_Pdev(0,0) = one3 * (ddPdev(0,0) + ddPdev(1,0) + ddPdev(2,0));
    one_dd_Pdev(0,1) = one3 * (ddPdev(0,1) + ddPdev(1,1) + ddPdev(2,1));
    one_dd_Pdev(0,2) = one3 * (ddPdev(0,2) + ddPdev(1,2) + ddPdev(2,2));
    one_dd_Pdev(0,3) = one3 * (ddPdev(0,3) + ddPdev(1,3) + ddPdev(2,3));
    
    bulk = one9 * ( dd(0,0) + dd(0,1) + dd(0,2)  
		    + dd(1,0) + dd(1,1) + dd(1,2) 
		    + dd(2,0) + dd(2,1) + dd(2,2) ) ;
    
    jj = 0 ;
    for ( j = 0; j < 4; j++ ) {
      
      double BJ00 = shp[0][j][i];
      double BJ11 = shp[1][j][i]; 
      double BJ30 = shp[1][j][i];
      double BJ31 = shp[0][j][i];
      
      BJtran.Zero( );
      BJtran(0,0) = shp[0][j][i] ;
      BJtran(1,1) = shp[1][j][i] ; 
      
      // BJ(2,0) for axi-symmetry 
      
      BJtran(0,3) = shp[1][j][i]  ;
      BJtran(1,3) = shp[0][j][i]  ;
      
      //compute residual 
      
      double ltBJ00 = vol_avg_shp[0][j] ;
      double ltBJ01 = vol_avg_shp[1][j] ;
      
      //BJtranD          =  BJtran * Pdev_dd_Pdev ;
      // BJtranD.addMatrixProduct(0.0,  BJtran, Pdev_dd_Pdev, 1.0);
      
      //littleBJoneD     =  littleBJtran * one_dd_Pdev ;
      // littleBJoneD.addMatrixProduct(0.0,  littleBJtran, one_dd_Pdev, 1.0);
      
      static double Adata[8];
      static Matrix A(Adata, 2, 4);
      
      // A = BJtranD;
      // A += littleBJoneD;
      
      for (int colA = 0, loc = 0, colPdev = 0; colA<4; colA++, colPdev += 4) {
	double data3colA = Pdev_dd_Pdev_data[3+colPdev];
	Adata[loc++] = BJ00*Pdev_dd_Pdev_data[colPdev] + BJ30*data3colA + ltBJ00*one_dd_Pdev_data[colA];
	Adata[loc++] = BJ11*Pdev_dd_Pdev_data[1+colPdev] + BJ31*data3colA + ltBJ01*one_dd_Pdev_data[colA];
      }
      
      //BJtranDone       =  BJtran * Pdev_dd_one ;
      // BJtranDone.addMatrixProduct(0.0,  BJtran, Pdev_dd_one, 1.0);
      
      //littleBJtranBulk =  bulk * littleBJtran ;
      // littleBJtranBulk = littleBJtran ;
      // littleBJtranBulk *= bulk ;
      
      double B1, B2;
      // B1 = BJtranDone(0,0) + littleBJtranBulk(0,0);
      // B2 = BJtranDone(1,0) + littleBJtranBulk(1,0);
      
      B1 = BJ00*Pdev_dd_one_data[0] + BJ30*Pdev_dd_one_data[3] + ltBJ00 *bulk;
      B2 = BJ11*Pdev_dd_one_data[1] + BJ31*Pdev_dd_one_data[3] + ltBJ01 *bulk;
      
      int colkk, colkkP1;
      for ( k = 0, kk=0, colkk =0, colkkP1 =8; 
	    k < 4; 
	    k++, kk += 2, colkk += 16, colkkP1 += 16 ) {
	
	double BK00 = shp[0][k][i];
	double BK11 = shp[1][k][i];
	double BK30 = shp[1][k][i];
	double BK31 = shp[0][k][i];
	
	double littleBK00 = vol_avg_shp[0][k];
	double littleBK01 = vol_avg_shp[1][k];

	//compute stiffness matrix
        
	stiff( jj,   kk   ) += Adata[0]*BK00 + Adata[6]*BK30 + B1 * littleBK00;
	stiff( jj+1, kk   ) += Adata[1]*BK00 + Adata[7]*BK30 + B2 * littleBK00;
	stiff( jj,   kk+1 ) += Adata[2]*BK11 + Adata[6]*BK31 + B1 * littleBK01;
	stiff( jj+1, kk+1 ) += Adata[3]*BK11 + Adata[7]*BK31 + B2 * littleBK01;
	
      } // end for k
      
      jj += 2 ;
    } // end for j 
  } //end for i

  return stiff ;
}    
Esempio n. 21
0
// compute stiffness matrix
const XC::Matrix&  XC::Twenty_Node_Brick::getStiff(int flag) const
{
        if(flag != 0 && flag != 1) {
                std::cerr << "FATAL XC::Twenty_Node_Brick::getStiff() - illegal use\n";
                exit(-1);
        }

        if(flag == 0 && Ki != 0)
                return *Ki;

        int i, j ;

        static double xsj ;  // determinant jacaobian matrix
        double volume = 0.;
        //-------------------------------------------------------
        int j3, j3m1, j3m2;
        static XC::Matrix B(6,nenu*3);
        static XC::Matrix BTDB(nenu*3,nenu*3);
        static XC::Matrix D(6, 6);
        B.Zero();
        BTDB.Zero();
        stiff.Zero();
//                FILE *fp;
//                fp = fopen("stiff.dat","w");

        //compute basis vectors and local nodal coordinates
        computeBasis( ) ;

        for( i = 0; i < nintu; i++ ) {
                // compute Jacobian and global shape functions
                Jacobian3d(i, xsj, 0);
                //volume element to also be saved
                dvolu[i] = wu[i] * xsj ;
                volume += dvolu[i];
        } // end for i
    //printf("volume = %f\n", volume);

//        for( i = 0; i < nintu; i++ ) {
//                for(int j = 0; j < nenu; j++ ) {
//                        printf("%5d %5d %15.6e %15.6e %15.6e %15.6e\n", i,j,
//                                shgu[0][j][i], shgu[1][j][i], shgu[2][j][i], shgu[3][j][i]);
//                }
//        }
//        exit(-1);

        // Loop over the integration points
        for(i = 0; i < nintu; i++) {

                // Get the material tangent
                if( flag == 0 )
                        D = physicalProperties[i]->getInitialTangent();
                else
                        D = physicalProperties[i]->getTangent();
                //const Matrix &D = physicalProperties[i]->getTangent();


                for(j=0; j<nenu; j++) {

                        j3   = 3*j+2;
                        j3m1 = j3 - 1;
                        j3m2 = j3 - 2;

                        B(0,j3m2) = shgu[0][j][i];
                        B(0,j3m1) = 0.;
                        B(0,j3  ) = 0.;

                        B(1,j3m2) = 0.;
                        B(1,j3m1) = shgu[1][j][i];
                        B(1,j3  ) = 0.;

                        B(2,j3m2) = 0.;
                        B(2,j3m1) = 0.;
                        B(2,j3  ) = shgu[2][j][i];

                        B(3,j3m2) = shgu[1][j][i];
                        B(3,j3m1) = shgu[0][j][i];
                        B(3,j3  ) = 0.;

                        B(4,j3m2) = 0.;
                        B(4,j3m1) = shgu[2][j][i];
                        B(4,j3  ) = shgu[1][j][i];

                        B(5,j3m2) = shgu[2][j][i];
                        B(5,j3m1) = 0.;
                        B(5,j3  ) = shgu[0][j][i];

                }

                // Perform numerical integration
                //K = K + (B^ D * B) * intWt(i) * detJ;
                BTDB.addMatrixTripleProduct(1.0, B, D, dvolu[i]);
        }
    for( i = 0; i < 60; i++)
                for( j = 0; j < 60; j++)
                        stiff(i,j) = BTDB(i,j);

        if( flag == 1) {
                return stiff;
        }
        Ki = new Matrix(stiff);
        if(Ki == 0) {
                std::cerr << "FATAL XC::Twenty_Node_Brick::getStiff() -";
                std::cerr << "ran out of memory\n";
                exit(-1);
        }

        return *Ki;
}
Esempio n. 22
0
//return secant matrix 
const Matrix&  ShellMITC9::getInitialStiff( ) 
{
  if (Ki != 0)
    return *Ki;

  static const int ndf = 6 ; //two membrane plus three bending plus one drill

  static const int nstress = 8 ; //three membrane, three moment, two shear

  static const int ngauss = 9 ; 

  static const int numnodes = 9 ;

  int i,  j,  k, p, q ;
  int jj, kk ;
  int node ;

  double volume = 0.0 ;

  static double xsj ;  // determinant jacaobian matrix 

  static double dvol[ngauss] ; //volume element

  static double shp[3][numnodes] ;  //shape functions at a gauss point

  static Matrix stiffJK(ndf,ndf) ; //nodeJK stiffness 

  static Matrix dd(nstress,nstress) ;  //material tangent

  //static Matrix J0(2,2) ;  //Jacobian at center
 
  //static Matrix J0inv(2,2) ; //inverse of Jacobian at center

  //---------B-matrices------------------------------------

    static Matrix BJ(nstress,ndf) ;      // B matrix node J

    static Matrix BJtran(ndf,nstress) ;

    static Matrix BK(nstress,ndf) ;      // B matrix node k

    static Matrix BJtranD(ndf,nstress) ;


    static Matrix Bbend(3,3) ;  // bending B matrix

    static Matrix Bshear(2,3) ; // shear B matrix

    static Matrix Bmembrane(3,2) ; // membrane B matrix


    static double BdrillJ[ndf] ; //drill B matrix

    static double BdrillK[ndf] ;  

    double *drillPointer ;

    static double saveB[nstress][ndf][numnodes] ;

  //-------------------------------------------------------

  stiff.Zero( ) ;


  //compute Jacobian and inverse at center
  double L1 = 0.0 ;
  double L2 = 0.0 ;
  //computeJacobian( L1, L2, xl, J0, J0inv ) ; 

  //gauss loop 
  for ( i = 0; i < ngauss; i++ ) {

    //get shape functions
    shape2d( sg[i], tg[i], xl, shp, xsj ) ;

    //volume element to also be saved
    dvol[i] = wg[i] * xsj ;  

    volume += dvol[i] ;

    // j-node loop to compute strain 
    for ( j = 0; j < numnodes; j++ )  {

      //compute B matrix 

      Bmembrane = computeBmembrane( j, shp ) ;

      Bbend = computeBbend( j, shp ) ;

	  Bshear = computeBshear( j, shp ) ;

      BJ = assembleB( Bmembrane, Bbend, Bshear ) ;

      //save the B-matrix
      for (p=0; p<nstress; p++) {
	    for (q=0; q<ndf; q++ )
	    saveB[p][q][j] = BJ(p,q) ;
      }//end for p

      //drilling B matrix
      drillPointer = computeBdrill( j, shp ) ;
      for (p=0; p<ndf; p++ ) {
	    //BdrillJ[p] = *drillPointer++ ;
	    BdrillJ[p] = *drillPointer ; //set p-th component
	    drillPointer++ ;             //pointer arithmetic
	  }//end for p
    } // end for j
  

    dd = materialPointers[i]->getInitialTangent( ) ;
    dd *= dvol[i] ;

    //residual and tangent calculations node loops

    jj = 0 ;
    for ( j = 0; j < numnodes; j++ ) {

      //extract BJ
      for (p=0; p<nstress; p++) {
	    for (q=0; q<ndf; q++ )
	      BJ(p,q) = saveB[p][q][j]   ;
      }//end for p

      //multiply bending terms by (-1.0) for correct statement
      // of equilibrium  
      for ( p = 3; p < 6; p++ ) {
	    for ( q = 3; q < 6; q++ ) 
	      BJ(p,q) *= (-1.0) ;
      } //end for p


      //transpose 
      //BJtran = transpose( 8, ndf, BJ ) ;
      for (p=0; p<ndf; p++) {
	    for (q=0; q<nstress; q++) 
	      BJtran(p,q) = BJ(q,p) ;
      }//end for p

      //drilling B matrix
      drillPointer = computeBdrill( j, shp ) ;
      for (p=0; p<ndf; p++ ) {
	    BdrillJ[p] = *drillPointer ;
	    drillPointer++ ;
      }//end for p

      //BJtranD = BJtran * dd ;
      BJtranD.addMatrixProduct(0.0, BJtran,dd,1.0 ) ;
	  

      for (p=0; p<ndf; p++) 
	    BdrillJ[p] *= ( Ktt*dvol[i] ) ;


      kk = 0 ;
      for ( k = 0; k < numnodes; k++ ) {
	
	    //extract BK
	    for (p=0; p<nstress; p++) {
	      for (q=0; q<ndf; q++ )
	        BK(p,q) = saveB[p][q][k]   ;
		}//end for p
	
	    //drilling B matrix
	    drillPointer = computeBdrill( k, shp ) ;
	    for (p=0; p<ndf; p++ ) {
	      BdrillK[p] = *drillPointer ;
	      drillPointer++ ;
		}//end for p
	
	    //stiffJK = BJtranD * BK  ;
	    // +  transpose( 1,ndf,BdrillJ ) * BdrillK ; 
	    stiffJK.addMatrixProduct(0.0, BJtranD,BK,1.0 ) ;
	
	    for ( p = 0; p < ndf; p++ )  {
	      for ( q = 0; q < ndf; q++ ) {
	        stiff( jj+p, kk+q ) += stiffJK(p,q) 
	          + ( BdrillJ[p]*BdrillK[q] ) ;
		  }//end for q
		}//end for p
	    kk += ndf ;
	  } // end for k loop
      jj += ndf ;
    } // end for j loop
  } //end for i gauss loop 
  Ki = new Matrix(stiff);
  return stiff ;
}