void StVKHessianTensor::AddCubicTermsContribution(double * u, double * du, SparseMatrix * dK, int elementLow, int elementHigh) { if (elementLow < 0) elementLow = 0; if (elementHigh < 0) elementHigh = volumetricMesh->getNumElements(); int ** row_, ** column_; stVKStiffnessMatrix->GetMatrixAccelerationIndices(&row_, &column_); int * vertices = (int*) malloc (sizeof(int) * numElementVertices); void * elIter; precomputedIntegrals->AllocateElementIterator(&elIter); double ** dataHandle = dK->GetDataHandle(); for(int el=elementLow; el < elementHigh; el++) { precomputedIntegrals->PrepareElement(el, elIter); int * row = row_[el]; int * column = column_[el]; for(int ver=0; ver<numElementVertices ;ver++) vertices[ver] = volumetricMesh->getVertexIndex(el, ver); double lambda = lambdaLame[el]; double mu = muLame[el]; for (int c=0; c<numElementVertices; c++) // over all vertices of the voxel { int rowc = 3*row[c]; int c8 = numElementVertices*c; for (int e=0; e<numElementVertices; e++) // compute contribution to block (c,e) of dK { double matrix[9]; memset(matrix, 0, sizeof(double) * 9); for(int f=0; f<numElementVertices; f++) { double qf[3] = { du[3*vertices[f]+0], du[3*vertices[f]+1], du[3*vertices[f]+2] }; for(int a=0; a<numElementVertices; a++) { double qa[3] = { u[3*vertices[a]+0], u[3*vertices[a]+1], u[3*vertices[a]+2] }; // qa tensor qf double qaqf[9]; qaqf[0] = qa[0] * qf[0]; qaqf[1] = qa[0] * qf[1]; qaqf[2] = qa[0] * qf[2]; qaqf[3] = qa[1] * qf[0]; qaqf[4] = qa[1] * qf[1]; qaqf[5] = qa[1] * qf[2]; qaqf[6] = qa[2] * qf[0]; qaqf[7] = qa[2] * qf[1]; qaqf[8] = qa[2] * qf[2]; double D0 = lambda * precomputedIntegrals->D(elIter,f,c,a,e) + mu * (precomputedIntegrals->D(elIter,f,e,a,c) + precomputedIntegrals->D(elIter,f,a,c,e)); matrix[0] += D0 * qaqf[0]; matrix[1] += D0 * qaqf[3]; matrix[2] += D0 * qaqf[6]; matrix[3] += D0 * qaqf[1]; matrix[4] += D0 * qaqf[4]; matrix[5] += D0 * qaqf[7]; matrix[6] += D0 * qaqf[2]; matrix[7] += D0 * qaqf[5]; matrix[8] += D0 * qaqf[8]; double D1 = lambda * precomputedIntegrals->D(elIter,a,c,f,e) + mu * (precomputedIntegrals->D(elIter,a,e,f,c) + precomputedIntegrals->D(elIter,a,f,c,e)); matrix[0] += D1 * qaqf[0]; matrix[1] += D1 * qaqf[1]; matrix[2] += D1 * qaqf[2]; matrix[3] += D1 * qaqf[3]; matrix[4] += D1 * qaqf[4]; matrix[5] += D1 * qaqf[5]; matrix[6] += D1 * qaqf[6]; matrix[7] += D1 * qaqf[7]; matrix[8] += D1 * qaqf[8]; double D2 = lambda * precomputedIntegrals->D(elIter,f,a,c,e) + mu * (precomputedIntegrals->D(elIter,f,c,a,e) + precomputedIntegrals->D(elIter,a,c,f,e)); // qf dot qa double dotp = D2 * (qf[0]*qa[0] + qf[1]*qa[1] + qf[2]*qa[2]); matrix[0] += dotp; matrix[4] += dotp; matrix[8] += dotp; } } int k,l; ADD_MATRIX_BLOCK(e); } } } free(vertices); precomputedIntegrals->ReleaseElementIterator(elIter); }
void StVKStiffnessMatrix::AddCubicTermsContribution(double * vertexDisplacements, SparseMatrix * sparseMatrix, int elementLow, int elementHigh) { if (elementLow < 0) elementLow = 0; if (elementHigh < 0) elementHigh = volumetricMesh->getNumElements(); int * vertices = (int*) malloc (sizeof(int) * numElementVertices); void * elIter; precomputedIntegrals->AllocateElementIterator(&elIter); double ** dataHandle = sparseMatrix->GetDataHandle(); for(int el=elementLow; el < elementHigh; el++) { precomputedIntegrals->PrepareElement(el, elIter); int * row = row_[el]; int * column = column_[el]; for(int ver=0; ver<numElementVertices; ver++) vertices[ver] = volumetricMesh->getVertexIndex(el, ver); double lambda = lambdaLame[el]; double mu = muLame[el]; for (int c=0; c<numElementVertices; c++) // over all vertices of the voxel, computing derivative on force on vertex c { int rowc = 3*row[c]; int c8 = numElementVertices*c; // cubic terms for (int e=0; e<numElementVertices; e++) // compute contribution to block (c,e) of the stiffness matrix { double matrix[9]; memset(matrix, 0, sizeof(double) * 9); for(int a=0; a<numElementVertices; a++) { int va = vertices[a]; double * qa = &(vertexDisplacements[3*va]); for(int b=0; b<numElementVertices; b++) { int vb = vertices[b]; double * qb = &(vertexDisplacements[3*vb]); double D0 = lambda * precomputedIntegrals->D(elIter,a,c,b,e) + mu * ( precomputedIntegrals->D(elIter,a,e,b,c) + precomputedIntegrals->D(elIter,a,b,c,e) ); matrix[0] += D0 * qa[0] * qb[0]; matrix[1] += D0 * qa[0] * qb[1]; matrix[2] += D0 * qa[0] * qb[2]; matrix[3] += D0 * qa[1] * qb[0]; matrix[4] += D0 * qa[1] * qb[1]; matrix[5] += D0 * qa[1] * qb[2]; matrix[6] += D0 * qa[2] * qb[0]; matrix[7] += D0 * qa[2] * qb[1]; matrix[8] += D0 * qa[2] * qb[2]; double D1 = 0.5 * lambda * precomputedIntegrals->D(elIter,a,b,c,e) + mu * precomputedIntegrals->D(elIter,a,c,b,e); double dotpD = D1 * (qa[0] * qb[0] + qa[1] * qb[1] + qa[2] * qb[2]); matrix[0] += dotpD; matrix[4] += dotpD; matrix[8] += dotpD; } } int k,l; ADD_MATRIX_BLOCK(e); } } } free(vertices); precomputedIntegrals->ReleaseElementIterator(elIter); }
void StVKHessianTensor::AddQuadraticTermsContribution(double * u, double * du, SparseMatrix * dK, int elementLow, int elementHigh) { if (elementLow < 0) elementLow = 0; if (elementHigh < 0) elementHigh = volumetricMesh->getNumElements(); int ** row_, ** column_; stVKStiffnessMatrix->GetMatrixAccelerationIndices(&row_, &column_); int * vertices = (int*) malloc (sizeof(int) * numElementVertices); void * elIter; precomputedIntegrals->AllocateElementIterator(&elIter); double ** dataHandle = dK->GetDataHandle(); for(int el=elementLow; el < elementHigh; el++) { precomputedIntegrals->PrepareElement(el, elIter); int * row = row_[el]; int * column = column_[el]; for(int ver=0; ver<numElementVertices ;ver++) vertices[ver] = volumetricMesh->getVertexIndex(el, ver); double lambda = lambdaLame[el]; double mu = muLame[el]; for (int c=0; c<numElementVertices; c++) // over all vertices of the voxel { int rowc = 3*row[c]; int c8 = numElementVertices*c; for (int e=0; e<numElementVertices; e++) // compute contribution to block (c,e) of dK { double matrix[9]; memset(matrix, 0, sizeof(double) * 9); for(int f=0; f<numElementVertices; f++) { double qf[3] = { du[3*vertices[f]+0], du[3*vertices[f]+1], du[3*vertices[f]+2] }; Vec3d C0v = lambda * precomputedIntegrals->C(elIter,c,f,e) + mu * (precomputedIntegrals->C(elIter,e,f,c) + precomputedIntegrals->C(elIter,f,e,c)); double C0[3] = {C0v[0], C0v[1], C0v[2]}; // C0 tensor qf matrix[0] += C0[0] * qf[0]; matrix[1] += C0[0] * qf[1]; matrix[2] += C0[0] * qf[2]; matrix[3] += C0[1] * qf[0]; matrix[4] += C0[1] * qf[1]; matrix[5] += C0[1] * qf[2]; matrix[6] += C0[2] * qf[0]; matrix[7] += C0[2] * qf[1]; matrix[8] += C0[2] * qf[2]; Vec3d C1v = lambda * precomputedIntegrals->C(elIter,e,f,c) + mu * (precomputedIntegrals->C(elIter,c,e,f) + precomputedIntegrals->C(elIter,f,e,c)); double C1[3] = {C1v[0], C1v[1], C1v[2]}; // qf tensor C1 matrix[0] += qf[0] * C1[0]; matrix[1] += qf[0] * C1[1]; matrix[2] += qf[0] * C1[2]; matrix[3] += qf[1] * C1[0]; matrix[4] += qf[1] * C1[1]; matrix[5] += qf[1] * C1[2]; matrix[6] += qf[2] * C1[0]; matrix[7] += qf[2] * C1[1]; matrix[8] += qf[2] * C1[2]; Vec3d C2v = lambda * precomputedIntegrals->C(elIter,f,e,c) + mu * (precomputedIntegrals->C(elIter,c,f,e) + precomputedIntegrals->C(elIter,e,f,c)); double C2[3] = {C2v[0], C2v[1], C2v[2]}; // qf dot C2 double dotp = qf[0]*C2[0] + qf[1]*C2[1] + qf[2]*C2[2]; matrix[0] += dotp; matrix[4] += dotp; matrix[8] += dotp; } int k,l; ADD_MATRIX_BLOCK(e); } } } precomputedIntegrals->ReleaseElementIterator(elIter); free(vertices); }
void StVKStiffnessMatrix::AddQuadraticTermsContribution(double * vertexDisplacements, SparseMatrix * sparseMatrix, int elementLow, int elementHigh) { if (elementLow < 0) elementLow = 0; if (elementHigh < 0) elementHigh = volumetricMesh->getNumElements(); int * vertices = (int*) malloc (sizeof(int) * numElementVertices); void * elIter; precomputedIntegrals->AllocateElementIterator(&elIter); double ** dataHandle = sparseMatrix->GetDataHandle(); for(int el=elementLow; el < elementHigh; el++) { precomputedIntegrals->PrepareElement(el, elIter); int * row = row_[el]; int * column = column_[el]; for(int ver=0; ver<numElementVertices; ver++) vertices[ver] = volumetricMesh->getVertexIndex(el, ver); double lambda = lambdaLame[el]; double mu = muLame[el]; for (int c=0; c<numElementVertices; c++) // over all vertices of the voxel, computing row of vertex c { int rowc = 3*row[c]; int c8 = numElementVertices*c; // quadratic terms for (int e=0; e<numElementVertices; e++) // compute contribution to block (c,e) of the stiffness matrix { double matrix[9]; memset(matrix, 0, sizeof(double) * 9); for(int a=0; a<numElementVertices; a++) { double qa[3] = { vertexDisplacements[3*vertices[a]+0], vertexDisplacements[3*vertices[a]+1], vertexDisplacements[3*vertices[a]+2] }; Vec3d C0v = lambda * precomputedIntegrals->C(elIter,c,a,e) + mu * (precomputedIntegrals->C(elIter,e,a,c) + precomputedIntegrals->C(elIter,a,e,c)); double C0[3] = {C0v[0], C0v[1], C0v[2]}; // C0 tensor qa matrix[0] += C0[0] * qa[0]; matrix[1] += C0[0] * qa[1]; matrix[2] += C0[0] * qa[2]; matrix[3] += C0[1] * qa[0]; matrix[4] += C0[1] * qa[1]; matrix[5] += C0[1] * qa[2]; matrix[6] += C0[2] * qa[0]; matrix[7] += C0[2] * qa[1]; matrix[8] += C0[2] * qa[2]; Vec3d C1v = lambda * precomputedIntegrals->C(elIter,e,a,c) + mu * (precomputedIntegrals->C(elIter,c,e,a) + precomputedIntegrals->C(elIter,a,e,c)); double C1[3] = {C1v[0], C1v[1], C1v[2]}; // qa tensor C1 matrix[0] += qa[0] * C1[0]; matrix[1] += qa[0] * C1[1]; matrix[2] += qa[0] * C1[2]; matrix[3] += qa[1] * C1[0]; matrix[4] += qa[1] * C1[1]; matrix[5] += qa[1] * C1[2]; matrix[6] += qa[2] * C1[0]; matrix[7] += qa[2] * C1[1]; matrix[8] += qa[2] * C1[2]; Vec3d C2v = lambda * precomputedIntegrals->C(elIter,a,e,c) + mu * (precomputedIntegrals->C(elIter,c,a,e) + precomputedIntegrals->C(elIter,e,a,c)); double C2[3] = {C2v[0], C2v[1], C2v[2]}; // qa dot C2 double dotp = qa[0]*C2[0] + qa[1]*C2[1] + qa[2]*C2[2]; matrix[0] += dotp; matrix[4] += dotp; matrix[8] += dotp; } int k,l; ADD_MATRIX_BLOCK(e); } } } free(vertices); precomputedIntegrals->ReleaseElementIterator(elIter); }