const Matrix & PressureIndependMultiYield::getTangent (void) { int loadStage = loadStagex[matN]; int ndm = ndmx[matN]; if (ndmx[matN] == 0) ndm = 3; if (loadStage == 1 && e2p == 0) elast2Plast(); if (loadStage!=1) { //linear elastic for (int i=0;i<6;i++) for (int j=0;j<6;j++) { theTangent(i,j) = 0.; if (i==j) theTangent(i,j) += refShearModulus; if (i<3 && j<3 && i==j) theTangent(i,j) += refShearModulus; if (i<3 && j<3) theTangent(i,j) += (refBulkModulus - 2.*refShearModulus/3.); } } else { double coeff; static Vector devia(6); /*if (committedActiveSurf > 0) { //devia = currentStress.deviator()-committedSurfaces[committedActiveSurf].center(); devia = currentStress.deviator(); devia -= committedSurfaces[committedActiveSurf].center(); double size = committedSurfaces[committedActiveSurf].size(); double plastModul = committedSurfaces[committedActiveSurf].modulus(); coeff = 6.*refShearModulus*refShearModulus/(2.*refShearModulus+plastModul)/size/size; }*/ if (activeSurfaceNum > 0) { //devia = currentStress.deviator()-committedSurfaces[committedActiveSurf].center(); devia = trialStress.deviator(); devia -= theSurfaces[activeSurfaceNum].center(); double size = theSurfaces[activeSurfaceNum].size(); double plastModul = theSurfaces[activeSurfaceNum].modulus(); coeff = 6.*refShearModulus*refShearModulus/(2.*refShearModulus+plastModul)/size/size; } else coeff = 0.; for (int i=0;i<6;i++) for (int j=0;j<6;j++) { theTangent(i,j) = - coeff*devia[i]*devia[j]; if (i==j) theTangent(i,j) += refShearModulus; if (i<3 && j<3 && i==j) theTangent(i,j) += refShearModulus; if (i<3 && j<3) theTangent(i,j) += (refBulkModulus - 2.*refShearModulus/3.); } } if (ndm==3) return theTangent; else { static Matrix workM(3,3); workM(0,0) = theTangent(0,0); workM(0,1) = theTangent(0,1); workM(0,2) = theTangent(0,3); workM(1,0) = theTangent(1,0); workM(1,1) = theTangent(1,1); workM(1,2) = theTangent(1,3); workM(2,0) = theTangent(3,0); workM(2,1) = theTangent(3,1); workM(2,2) = theTangent(3,3); return workM; } }
const Matrix & PressureIndependMultiYield::getInitialTangent (void) { int ndm = ndmx[matN]; if (ndmx[matN] == 0) ndm = 3; for (int i=0;i<6;i++) for (int j=0;j<6;j++) { theTangent(i,j) = 0.; if (i==j) theTangent(i,j) += refShearModulus; if (i<3 && j<3 && i==j) theTangent(i,j) += refShearModulus; if (i<3 && j<3) theTangent(i,j) += (refBulkModulus - 2.*refShearModulus/3.); } if (ndm==3) return theTangent; else { static Matrix workM(3,3); workM(0,0) = theTangent(0,0); workM(0,1) = theTangent(0,1); workM(0,2) = theTangent(0,3); workM(1,0) = theTangent(1,0); workM(1,1) = theTangent(1,1); workM(1,2) = theTangent(1,3); workM(2,0) = theTangent(3,0); workM(2,1) = theTangent(3,1); workM(2,2) = theTangent(3,3); return workM; } }
const Vector & TransformationFE::getC_Force(const Vector &accel, double fact) { this->FE_Element::zeroTangent(); this->FE_Element::addCtoTang(); const Matrix &theTangent = this->FE_Element::getTangent(0); static ID numDOFs(dofData, 1); numDOFs.setData(dofData, numGroups); // DO THE SP STUFF TO THE TANGENT // get the transformation matrix from each dof group & number of local dof // for original node. int numNode = numGroups; for (int a = 0; a<numNode; a++) { Matrix *theT = theDOFs[a]->getT(); theTransformations[a] = theT; if (theT != 0) numDOFs[a] = theT->noRows(); // T^ else numDOFs[a] = theDOFs[a]->getNumDOF(); } // perform Tt K T -- as T is block diagonal do T(i)^T K(i,j) T(j) // where blocks are of size equal to num ele dof at a node int startRow = 0; int noRowsTransformed = 0; int noRowsOriginal = 0; static Matrix localK; // foreach block row, for each block col do for (int i=0; i<numNode; i++) { int startCol = 0; int numDOFi = numDOFs[i]; int noColsOriginal = 0; for (int j=0; j<numNode; j++) { const Matrix *Ti = theTransformations[i]; const Matrix *Tj = theTransformations[j]; int numDOFj = numDOFs[j]; localK.setData(localKbuffer, numDOFi, numDOFj); // copy K(i,j) into localK matrix // CHECK SIZE OF BUFFFER for (int a=0; a<numDOFi; a++) for (int b=0; b<numDOFj; b++) localK(a,b) = theTangent(noRowsOriginal+a, noColsOriginal+b); // now perform the matrix computation T(i)^T localK T(j) // note: if T == 0 then the Identity is assumed int noColsTransformed = 0; static Matrix localTtKT; if (Ti != 0 && Tj != 0) { noRowsTransformed = Ti->noCols(); noColsTransformed = Tj->noCols(); // CHECK SIZE OF BUFFFER localTtKT.setData(dataBuffer, noRowsTransformed, noColsTransformed); //localTtKT = (*Ti) ^ localK * (*Tj); localTtKT.addMatrixTripleProduct(0.0, *Ti, localK, *Tj, 1.0); } else if (Ti == 0 && Tj != 0) { noRowsTransformed = numDOFi; noColsTransformed = Tj->noCols(); // CHECK SIZE OF BUFFFER localTtKT.setData(dataBuffer, noRowsTransformed, noColsTransformed); // localTtKT = localK * (*Tj); localTtKT.addMatrixProduct(0.0, localK, *Tj, 1.0); } else if (Ti != 0 && Tj == 0) { noRowsTransformed = Ti->noCols(); noColsTransformed = numDOFj; // CHECK SIZE OF BUFFFER localTtKT.setData(dataBuffer, noRowsTransformed, noColsTransformed); //localTtKT = (*Ti) ^ localK; localTtKT.addMatrixTransposeProduct(0.0, *Ti, localK, 1.0); } else { noRowsTransformed = numDOFi; noColsTransformed = numDOFj; localTtKT.setData(dataBuffer, noRowsTransformed, noColsTransformed); localTtKT = localK; } // now copy into modTangent the T(i)^t K(i,j) T(j) product for (int c=0; c<noRowsTransformed; c++) for (int d=0; d<noColsTransformed; d++) (*modTangent)(startRow+c, startCol+d) = localTtKT(c,d); startCol += noColsTransformed; noColsOriginal += numDOFj; } noRowsOriginal += numDOFi; startRow += noRowsTransformed; } // get the components we need out of the vector // and place in a temporary vector Vector tmp(numTransformedDOF); for (int j=0; j<numTransformedDOF; j++) { int dof = (*modID)(j); if (dof >= 0) tmp(j) = accel(dof); else tmp(j) = 0.0; } modResidual->addMatrixVector(0.0, *modTangent, tmp, 1.0); return *modResidual; }