float QuadDice::scale_factor(SubPatch& sub, EdgeFactors& ef, int Mu, int Mv) { /* estimate area as 4x largest of 4 quads */ float3 P[3][3]; for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++) P[i][j] = eval_projected(sub, i*0.5f, j*0.5f); float A1 = quad_area(P[0][0], P[1][0], P[0][1], P[1][1]); float A2 = quad_area(P[1][0], P[2][0], P[1][1], P[2][1]); float A3 = quad_area(P[0][1], P[1][1], P[0][2], P[1][2]); float A4 = quad_area(P[1][1], P[2][1], P[1][2], P[2][2]); float Apatch = max(A1, max(A2, max(A3, A4)))*4.0f; /* solve for scaling factor */ float Atri = dicing_rate*dicing_rate*0.5f; float Ntris = Apatch/Atri; // XXX does the -sqrt solution matter // XXX max(D, 0.0) is highly suspicious, need to test cases // where D goes negative float N = 0.5f*(Ntris - (ef.tu0 + ef.tu1 + ef.tv0 + ef.tv1)); float D = 4.0f*N*Mu*Mv + (Mu + Mv)*(Mu + Mv); float S = (Mu + Mv + sqrtf(max(D, 0.0f)))/(2*Mu*Mv); return S; }
void CThinshellElementFEM::_initElements( const CMeMaterialProperty &mtl, const Vector3d &p0, const Vector3d &p1, const Vector3d &p2, const Vector3d &p3, const Vector3d &p4, const Vector3d &p5, const double& thickness) { //compute volume for each triangle, each truss edge m_area0 = fabs(quad_area(p0, p1, p2, p3)); m_area1 = fabs(quad_area(p0, p4, p5, p1)); //right hand rule m_thickness = thickness; //construct the world/local transform matrix for the two triangles double3x3 rot; Vector3d N0, N1; const Vector3d q1=p1-p0, q2=p2-p0, q3=p3-p0, q4=p4-p0, q5=p5-p0; getReferencePlanesForQuadPair(q1, q2, q3, q4, q5, N0, N1, rot, m_len0); const Vector3d qq1(m_len0, 0, 0); const Vector3d qq2 = rot*q2; const Vector3d qq3 = rot*q3; const Vector3d qq4 = rot*q4; const Vector3d qq5 = rot*q5; m_qq2 = qq2; m_qq3 = qq3; m_qq4 = qq4; m_qq5 = qq5; const double DELTA = m_len0*HEIGHT_DELTA; const Vector3d qq2u = rot*(q2+DELTA*N0); const Vector3d qq3u = rot*(q3+DELTA*N0); const Vector3d qq4u = rot*(q4+DELTA*N1); const Vector3d qq5u = rot*(q5+DELTA*N1); //derivitive pF/pX copyVectorsToColumns(qq1, qq2, qq2u, m_XInv0); copyVectorsToColumns(qq1, qq3, qq3u, m_XInv1); copyVectorsToColumns(qq1, qq4, qq4u, m_XInv2); copyVectorsToColumns(qq1, qq5, qq5u, m_XInv3); m_XInv0.Invert(); m_XInv1.Invert(); m_XInv2.Invert(); m_XInv3.Invert(); //stiffness const int NSTIFF=12; double3x3 jac[NSTIFF], *ppJacobian[NSTIFF]; for (int i=0; i<NSTIFF; i++) ppJacobian[i]=&jac[i]; const double E = mtl.getYoung()*m_thickness*0.5; computeStiffnessMat(m_XInv0, -E*m_area0, ppJacobian); computeStiffnessMat(m_XInv1, -E*m_area0, ppJacobian+3); computeStiffnessMat(m_XInv2, -E*m_area1, ppJacobian+6); computeStiffnessMat(m_XInv3, -E*m_area1, ppJacobian+9); double *pstiff = &m_stiffness[0].x; for (int i=0; i<NSTIFF; i++) pstiff[i]=jac[i].x[0]; //m_strain0.ZeroMatrix(); //m_strain1.ZeroMatrix(); }
//================================================== //-0.5 -0.5 -0.5 //0.5 -0.5 -0.5 //-0.5 0.5 -0.5 //0.5 0.5 -0.5 //-0.5 -0.5 0.5 //0.5 -0.5 0.5 //-0.5 0.5 0.5 //0.5 0.5 0.5 //element node seq: 1 2 4 3 5 6 8 7 //================================================== void CHexshellElement::init( const CMeMaterialProperty& mtl, const int *nodeid, const Vector3d &p0, const Vector3d &p1, const Vector3d &p2, const Vector3d &p3, const Vector3d &p4, const Vector3d &p5, const Vector3d &p6, const Vector3d &p7) { for (int i=0; i<8; i++) m_nodeID[i]=nodeid[i]; //total volume Vector3d v[8] = {p0, p1, p2, p3, p4, p5, p6, p7}; Vector8i hexelm(0,1,2,3,4,5,6,7); const double vol = computeHexahedronVolume(v, hexelm); //total area const double a0 = fabs(quad_area(p0, p1, p2, p3)); const double a1 = fabs(quad_area(p0, p1, p5, p4)); const double a2 = fabs(quad_area(p1, p2, p6, p5)); const double a3 = fabs(quad_area(p2, p3, p7, p6)); const double a4 = fabs(quad_area(p3, p0, p4, p7)); const double a5 = fabs(quad_area(p4, p5, p6, p7)); const double sumarea = a0+a1+a2+a3+a4+a5; // const double th = vol/sumarea; _initElement(mtl, th, p0, p1, p2, p3, p4, p5, p6, p7); }
void CThinshell2Element::init(const int isstatic, const int nodeid, //the center vertex id const Vector3d *p, //vertex position buffer const Vector3d *wpnorm, //weighted polygon normal array const int *surfpoly, //buffer of the whole surface polygons const int nv_per_elm, //number of vertices for each surface polygon const int *polyfanid, //the polyfan around the center vertex, input IDs only const int n1RingPoly, //valence of the center vertex, also length of poylfanid const double& thickness) { double plyvolume[MAX_NODE_VALENCE+1], edgevolume[MAX_NODE_VALENCE+1]; int i, k; m_n1RingPoly = n1RingPoly; m_nCenterID = nodeid; for (i=0; i<n1RingPoly; i++) m_n1RingPolyID[i]=polyfanid[i]; //Find all the fan polygons, store in tri buffer set<int> nodeset; nodeset.clear(); for (i=0; i<n1RingPoly; i++){ const int plyid = polyfanid[i]; const int *ppoly = &surfpoly[plyid*nv_per_elm]; _searchNodeInPolygon(nodeid, ppoly, nv_per_elm, nodeset); if (nv_per_elm==3){ Vector3i tri(ppoly[0], ppoly[1], ppoly[2]); plyvolume[i] = triangle_area(p[tri.x], p[tri.y], p[tri.z]); } else{ ASSERT0(nv_per_elm==4); Vector4i tri(ppoly[0], ppoly[1], ppoly[2], ppoly[3]); plyvolume[i] = quad_area(p[tri.x], p[tri.y], p[tri.z], p[tri.w]); } } //use the fan polygons to find the truss vertices set<int>::iterator itr = nodeset.begin(); k = 0; while(itr!=nodeset.end()){ m_nNodeID[k] = *itr; itr++, k++; } m_nRod = k; assert(m_nRod>0); if (m_nRod>MAX_NODE_VALENCE){ printf("ALERT: node valence buffer is too small, increase to %d!!\n", m_nRod); m_nRod = MAX_NODE_VALENCE; } //find truss edge volume for (i=0; i<m_n1RingPoly; i++) plyvolume[i]*= thickness/nv_per_elm; for (i=0; i<m_nRod; i++) edgevolume[i]=0; for (i=0; i<m_n1RingPoly; i++){ const double vol = plyvolume[i]; const int plyid = polyfanid[i]; const int *ppoly = &surfpoly[plyid*nv_per_elm]; for (int j=0; j<nv_per_elm; j++){ const int id = ppoly[j]; for (k=0; k<m_nRod; k++){ if (m_nNodeID[k]==id) break; } if (k<m_nRod) edgevolume[k]+=vol; } } _initShearElements(isstatic, p, wpnorm, edgevolume); }
void CThinshellElementFEM::_initElements( const CMeMaterialProperty &mtl, const Vector3d &p0, const Vector3d &p1, const Vector3d &p2, const Vector3d &p3, const Vector3d &p4, const Vector3d &p5, const double& thickness) { //compute volume for each triangle, each truss edge m_area0 = fabs(quad_area(p0, p1, p2, p3)); m_area1 = fabs(quad_area(p0, p4, p5, p1)); //right hand rule m_thickness = thickness; //construct the world/local transform matrix for the two triangles double3x3 rot; Vector3d N0, N1; const Vector3d p00=(p0+p1)*0.5; const Vector3d q1=p1-p00, q2=p2-p00, q3=p3-p00, q4=p4-p00, q5=p5-p00; //const Vector3d q1=p1-p0, q2=p2-p0, q3=p3-p0, q4=p4-p0, q5=p5-p0; getReferencePlanesForQuadPair(q1, q2, q3, q4, q5, N0, N1, rot, m_len0); const Vector3d qq0(-m_len0, 0, 0); const Vector3d qq1(m_len0, 0, 0); const Vector3d qq2 = rot*q2; const Vector3d qq3 = rot*q3; const Vector3d qq4 = rot*q4; const Vector3d qq5 = rot*q5; m_qq2 = qq2; m_qq3 = qq3; m_qq4 = qq4; m_qq5 = qq5; const double DELTA = m_len0*HEIGHT_DELTA; const Vector3d qq2u = rot*(q2+DELTA*N0); const Vector3d qq3u = rot*(q3+DELTA*N0); const Vector3d qq4u = rot*(q4+DELTA*N1); const Vector3d qq5u = rot*(q5+DELTA*N1); //derivitive pF/pX Vector3d *derivA = (Vector3d *)(&m_XInv0.x[0]); Vector3d *derivB = (Vector3d *)(&m_XInv1.x[0]); computeQuadDeriv(qq0, qq1, qq2, qq3, qq2u, qq3u, derivA); computeQuadDeriv(qq1, qq1, qq4, qq5, qq4u, qq5u, derivB); //stiffness const int NSTIFFMAT=20; double3x3 jac[NSTIFFMAT], *ppJacobian[NSTIFFMAT]; for (int i=0; i<NSTIFFMAT; i++) ppJacobian[i]=&jac[i]; const double E = mtl.getYoung()*m_thickness; computeStiffnessMat(derivA, -E*m_area0, ppJacobian); computeStiffnessMat(derivB, -E*m_area1, ppJacobian+(NSTIFFMAT>>1)); m_A11 = jac[0].x[0]; m_A12 = jac[1].x[0]; m_A13 = jac[2].x[0]; m_A14 = jac[3].x[0]; m_A22 = jac[4].x[0]; m_A23 = jac[5].x[0]; m_A24 = jac[6].x[0]; m_A33 = jac[7].x[0]; m_A34 = jac[8].x[0]; m_A44 = jac[9].x[0]; m_B11 = jac[10].x[0]; m_B12 = jac[11].x[0]; m_B13 = jac[12].x[0]; m_B14 = jac[13].x[0]; m_B22 = jac[14].x[0]; m_B23 = jac[15].x[0]; m_B24 = jac[16].x[0]; m_B33 = jac[17].x[0]; m_B34 = jac[18].x[0]; m_B44 = jac[19].x[0]; m_strain0.ZeroMatrix(); m_strain1.ZeroMatrix(); }