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; }
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; }
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; }
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; }
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; }
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; }
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; }
//********************************************************************* //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 }
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; }
//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; }
//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 ; }
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; }
//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 ; }
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 }
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 ; }
// 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; }
//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 ; }