/* $Id: elements2.cc,v 1.5 1996/11/19 09:51:31 bzferdma Exp $ (C)opyright 1996 by Konrad-Zuse-Center, Berlin All rights reserved. Part of the Kaskade distribution */ #include "elements1.h" #include "elements2.h" #include "numerics.h" #include "triang.h" #include "triangA.h" #include "materials.h" #include "integ.h" //------------------------------------------------------------------------- static double TriangleSf1(double x, double y) { return 1-x-y; } static double TriangleSf2(double x, double /*y*/) { return x; } static double TriangleSf3(double /*x*/, double y) { return y; } static double TriangleSf1dx(double /*x*/, double /*y*/) { return -1.; } static double TriangleSf1dy(double /*x*/, double /*y*/) { return -1.; } static double TriangleSf2dx(double /*x*/, double /*y*/) { return 1.; } static double TriangleSf2dy(double /*x*/, double /*y*/) { return 0.; } static double TriangleSf3dx(double /*x*/, double /*y*/) { return 0.; } static double TriangleSf3dy(double /*x*/, double /*y*/) { return 1.; } static double HQuadTriangleSf1(double x, double y) { return 1-x-y; } static double HQuadTriangleSf2(double x, double /*y*/) { return x; } static double HQuadTriangleSf3(double /*x*/, double y) { return y; } static double HQuadTriangleSf1dx(double /*x*/, double /*y*/) { return -1.; } static double HQuadTriangleSf1dy(double /*x*/, double /*y*/) { return -1.; } static double HQuadTriangleSf2dx(double /*x*/, double /*y*/) { return 1.; } static double HQuadTriangleSf2dy(double /*x*/, double /*y*/) { return 0.; } static double HQuadTriangleSf3dx(double /*x*/, double /*y*/) { return 0.; } static double HQuadTriangleSf3dy(double /*x*/, double /*y*/) { return 1.; } static double HQuadTriangleSf4 (double x, double y) { return 4.*x*y; } static double HQuadTriangleSf4dx(double /*x*/, double y) { return 4.*y; } static double HQuadTriangleSf4dy(double x, double /*y*/) { return 4.*x; } static double HQuadTriangleSf5 (double x, double y) { return 4.*y*(1-x-y); } static double HQuadTriangleSf5dx(double /*x*/, double y) { return -4.*y; } static double HQuadTriangleSf5dy(double x, double y) { return 4.*(1-x-2*y); } static double HQuadTriangleSf6 (double x, double y) { return 4.*x*(1-x-y); } static double HQuadTriangleSf6dx(double x, double y) { return 4.*(1-2*x-y); } static double HQuadTriangleSf6dy(double x, double /*y*/) { return -4.*x; } static double LQuadTriangleSf1(double x, double y) { return 2.*(1.-x-y)*(0.5-x-y); } static double LQuadTriangleSf1dx(double x, double y) { return 4.*(x+y)-3.; } static double LQuadTriangleSf1dy(double x, double y) { return 4.*(x+y)-3.; } static double LQuadTriangleSf2(double x, double /*y*/) { return x*(2.*x-1.); } static double LQuadTriangleSf2dx(double x, double /*y*/) { return 4.*x-1.; } static double LQuadTriangleSf2dy(double /*x*/, double /*y*/) { return 0.; } static double LQuadTriangleSf3(double /*x*/, double y) { return y*(2.*y-1.); } static double LQuadTriangleSf3dx(double /*x*/, double /*y*/) { return 0.; } static double LQuadTriangleSf3dy(double /*x*/, double y) { return 4.*y-1.; } static double LQuadTriangleSf4(double x, double y) { return 4.*x*y; } static double LQuadTriangleSf4dx(double /*x*/, double y) { return 4.*y; } static double LQuadTriangleSf4dy(double x, double /*y*/) { return 4.*x; } static double LQuadTriangleSf5(double x, double y) { return 4.*y*(1.-x-y); } static double LQuadTriangleSf5dx(double /*x*/, double y) { return -4.*y; } static double LQuadTriangleSf5dy(double x, double y) { return 4.*(1-x-2.*y); } static double LQuadTriangleSf6(double x, double y) { return 4.*x*(1.-x-y); } static double LQuadTriangleSf6dx(double x, double y) { return 4.*(1-2.*x-y); } static double LQuadTriangleSf6dy(double x, double /*y*/) { return -4.*x; } //----------------------------- Triangles ------------------------------ Triangle:: Triangle(Material* material0) : StdElement() { material = material0; basicInit(); setShapeFunctionsAtIPs(); compConstantMatrices(); setPatterns(); } //------------------------------------------------------------------------- void Triangle:: basicInit() { const int nnodes = NoOfNodes(); const int dim = SpaceDim(); IF = new GaussForm(dim,1); // GaussTriOrder1; IFMass = new GaussForm(dim,3); // GaussTriOrder3; IFLumpedMass = new LumpedForm(dim,1,"LumpedTriOrder1"); InfoIntegFormulas("Triangle"); edgeElement = new Line(material); faceElement = edgeElement; tmp_nodes = new Vector(faceElement->NoOfNodes()+1); tmp_Ell = new Matrix(dim,dim); tmp_dN = new Matrix(nnodes,dim); tmp_u = new Vector(dim); tmp_x = new Vector(dim); tmp_xBnd = new Vector(dim+1); sf[1] = TriangleSf1; sf[2] = TriangleSf2; sf[3] = TriangleSf3; dsf[1][1] = TriangleSf1dx; dsf[1][2] = TriangleSf1dy; dsf[2][1] = TriangleSf2dx; dsf[2][2] = TriangleSf2dy; dsf[3][1] = TriangleSf3dx; dsf[3][2] = TriangleSf3dy; } //------------------------------------------------------------------------- HQuadTriangleFast:: HQuadTriangleFast(Material* material0) : HQuadTriangle() { material = material0; basicInit(); setShapeFunctionsAtIPs(); compConstantMatrices(); setPatterns(); } //------------------------------------------------------------------------- void HQuadTriangleFast:: basicInit() { const int nnodes = NoOfNodes(); const int dim = SpaceDim(); IF = new GaussForm(dim,2, "GaussTriOrder2OnEdges"); IFMass = new GaussForm(dim,5); IFLumpedMass = new LumpedForm(dim,2,"LumpedTriOrder2"); InfoIntegFormulas("HQuadTriangleFast"); edgeElement = new HQuadLine(material); faceElement = edgeElement; tmp_nodes = new Vector(faceElement->NoOfNodes()+1); tmp_Ell = new Matrix(dim,dim); tmp_dN = new Matrix(nnodes,dim); tmp_u = new Vector(dim); tmp_x = new Vector(dim); tmp_xBnd = new Vector(dim+1); tmp_matE = new Vector(IF->NoOfIPoints()); HQsf[1] = HQuadTriangleSf1; HQsf[2] = HQuadTriangleSf2; HQsf[3] = HQuadTriangleSf3; HQsf[4] = HQuadTriangleSf4; HQsf[5] = HQuadTriangleSf5; HQsf[6] = HQuadTriangleSf6; dHQsf[1][1] = HQuadTriangleSf1dx; dHQsf[1][2] = HQuadTriangleSf1dy; dHQsf[2][1] = HQuadTriangleSf2dx; dHQsf[2][2] = HQuadTriangleSf2dy; dHQsf[3][1] = HQuadTriangleSf3dx; dHQsf[3][2] = HQuadTriangleSf3dy; dHQsf[4][1] = HQuadTriangleSf4dx; dHQsf[4][2] = HQuadTriangleSf4dy; dHQsf[5][1] = HQuadTriangleSf5dx; dHQsf[5][2] = HQuadTriangleSf5dy; dHQsf[6][1] = HQuadTriangleSf6dx; dHQsf[6][2] = HQuadTriangleSf6dy; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- // the basic matrices for constant coefficients (S1, S2, S3, M, B ...) // are chosen due to Schwarz's conventions: void Triangle:: compConstantMatrices() { int i,k,ip, noIP; const int nbnodes = NoOfBaseNodes(); S1 = new Matrix(nbnodes,nbnodes); S2 = new Matrix(nbnodes,nbnodes); S3 = new Matrix(nbnodes,nbnodes); C1 = new Matrix(nbnodes,nbnodes); C2 = new Matrix(nbnodes,nbnodes); M = new Matrix(nbnodes,nbnodes); B = new Vector(nbnodes); for (i=1; i<=nbnodes; ++i) { for (k=1; k<=nbnodes; ++k) (*S1)(i,k) = (*S2)(i,k) = (*S3)(i,k) = (*C1)(i,k) = (*C2)(i,k) = (*M)(i,k) = 0.0; (*B)[i] = 0.0; } // partial stiffness matrices: noIP = IF->NoOfIPoints(); for (ip=1; ip<=noIP; ++ip) for (i=1; i<=nbnodes; ++i) for (k=1; k<=i; ++k) { (*S1)(i,k) += IF->Weight(ip) * (*dNU)(ip,i,1)*(*dNU)(ip,k,1); (*S2)(i,k) += IF->Weight(ip) *((*dNU)(ip,i,1)*(*dNU)(ip,k,2) + (*dNU)(ip,i,2)*(*dNU)(ip,k,1)); (*S3)(i,k) += IF->Weight(ip) * (*dNU)(ip,i,2)*(*dNU)(ip,k,2); } // mass matrix and source vector: noIP = IFMass->NoOfIPoints(); for (ip=1; ip<=IFMass->NoOfIPoints(); ++ip) for (i=1; i<=nbnodes; ++i) { (*B)[i] += IFMass->Weight(ip) * (*NMass)(ip,i); for (k=1; k<=i; ++k) (*M)(i,k) += IFMass->Weight(ip) * (*NMass)(ip,i) * (*NMass)(ip,k); } for (i=1; i<=nbnodes; ++i) // upper triangles for (k=1; kNoOfIPoints(); for (ip=1; ip<=noIP; ++ip) for (i=1; i<=nbnodes; ++i) for (k=1; k<=nbnodes; ++k) { (*C1)(i,k) += IF->Weight(ip) * (*N)(ip,i)*(*dNU)(ip,k,1); (*C2)(i,k) += IF->Weight(ip) * (*N)(ip,i)*(*dNU)(ip,k,2); } } //------------------------------------------------------------------------- Bool HQuadTriangleFast:: assembleEllip(const PATCH& patch, Matrix& A, const Jacobian& Jac, const Matrix* pattern) const { int i, k, ip, noIP; const int nnodes = NoOfNodes(); const int dim = SpaceDim(); Real fact, Jabs, sum; Real sumA, sumB, d, dx, dy, n1, n2, p; if (!material->EllipticTerm(patch.Class())) return False; if (pattern == 0) pattern = symPattern; if (material->constEllipticTerm(patch.Class())) // ident. to HQuadTriangle { assembleConstEllip(patch, A, Jac, pattern); } else { // we have to use the integration formulae GaussTriOrder2OnEdges Matrix& dN = *tmp_dN; Vector& u = *tmp_u; Vector& x = *tmp_x; Vector& matE = *tmp_matE; if (material->isAnisotropic()) { cout << "\n*** HQuadTriangleFast:: assembleConstEllip: " "anisotropic material not yet implemented \n"; cout.flush(); abort(); } else if (!material->isIsotropic()) { cout << "\n*** HQuadTriangleFast:: assembleConstEllip: no materialtype specified \n"; cout.flush(); abort(); } Jabs = Abs(Jac.detJ); noIP = IF->NoOfIPoints(); for (ip=1; ip<=noIP; ++ip) { transformDerivDN(dN, ip, Jac); IF->Coordinates(ip,u); patch.realCoordinates(u,x); // location x in real space matE[ip] = material->E(patch.Class(), &x); fact = Jabs * IF->Weight(ip) * matE[ip]; for (i=1; i<=nnodes; ++i) { if ((*pattern)(i,i)) { sum = 0.0; for (k=1; k<=dim; ++k) sum += dN(i,k) * dN(i,k); A(i,i) += sum * fact; } } } // -- Line integration for normal components: const Matrix& JJ = Jac.J; const Vector& eds = patch.getEdges(); d = 2.0/(3.0*Jac.detJ); // ( JJ(1,1)*JJ(2,2) - JJ(1,2)*JJ(2,1) ); if ( !(eds[1]->isDirichlet()) ) { dx = JJ(2,1) - JJ(1,1); dy = JJ(2,2) - JJ(1,2); p = matE[1]; // value on edge 1 n1 = dy*p; n2 = -dx*p; sumA = n1*JJ(2,2)-n2*JJ(2,1); sumB = n2*JJ(1,1)-n1*JJ(1,2); A(4,1) += (-d)*(sumA+sumB); A(4,2) += d*sumA; A(4,3) += d*sumB; } if ( !(eds[2]->isDirichlet()) ) { dx = -JJ(2,1); dy = -JJ(2,2); p = matE[2]; // value on edge 2 n1 = dy*p; n2 = -dx*p; sumA = n1*JJ(2,2)-n2*JJ(2,1); sumB = n2*JJ(1,1)-n1*JJ(1,2); A(5,1) += (-d)*(sumA+sumB); A(5,2) += d*sumA; A(5,3) += d*sumB; } if ( !(eds[3]->isDirichlet()) ) { dx = JJ(1,1); dy = JJ(1,2); p = matE[3]; // value on edge 3 n1 = dy*p; n2 = -dx*p; sumA = n1*JJ(2,2)-n2*JJ(2,1); sumB = n2*JJ(1,1)-n1*JJ(1,2); A(6,1) += (-d)*(sumA+sumB); A(6,2) += d*sumA; A(6,3) += d*sumB; } } return True; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- HQuadTriangle:: HQuadTriangle(Material* material0) : Triangle() { material = material0; basicInit(); setShapeFunctionsAtIPs(); compConstantMatrices(); setPatterns(); } //------------------------------------------------------------------------- void HQuadTriangle:: basicInit() { const int nnodes = NoOfNodes(); const int dim = SpaceDim(); IF = new GaussForm(dim,3); IFMass = new GaussForm(dim,5); IFLumpedMass = new LumpedForm(dim,2,"LumpedTriOrder2"); InfoIntegFormulas("HQuadTriangle"); edgeElement = new HQuadLine(material); faceElement = edgeElement; tmp_nodes = new Vector(faceElement->NoOfNodes()+1); tmp_Ell = new Matrix(dim,dim); tmp_dN = new Matrix(nnodes,dim); tmp_u = new Vector(dim); tmp_x = new Vector(dim); tmp_xBnd = new Vector(dim+1); HQsf[1] = HQuadTriangleSf1; HQsf[2] = HQuadTriangleSf2; HQsf[3] = HQuadTriangleSf3; HQsf[4] = HQuadTriangleSf4; HQsf[5] = HQuadTriangleSf5; HQsf[6] = HQuadTriangleSf6; dHQsf[1][1] = HQuadTriangleSf1dx; dHQsf[1][2] = HQuadTriangleSf1dy; dHQsf[2][1] = HQuadTriangleSf2dx; dHQsf[2][2] = HQuadTriangleSf2dy; dHQsf[3][1] = HQuadTriangleSf3dx; dHQsf[3][2] = HQuadTriangleSf3dy; dHQsf[4][1] = HQuadTriangleSf4dx; dHQsf[4][2] = HQuadTriangleSf4dy; dHQsf[5][1] = HQuadTriangleSf5dx; dHQsf[5][2] = HQuadTriangleSf5dy; dHQsf[6][1] = HQuadTriangleSf6dx; dHQsf[6][2] = HQuadTriangleSf6dy; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- LQuadTriangle:: LQuadTriangle(Material* material0) : HQuadTriangle() { material = material0; basicInit(); setShapeFunctionsAtIPs(); compConstantMatrices(); setPatterns(); } //------------------------------------------------------------------------- void LQuadTriangle:: basicInit() { const int nnodes = NoOfNodes(); const int dim = SpaceDim(); IF = new GaussForm(dim,3); IFMass = new GaussForm(dim,5); IFLumpedMass = new LumpedForm(dim,2,"LumpedTriOrder2"); InfoIntegFormulas("LQuadTriangle"); edgeElement = new LQuadLine(material); faceElement = edgeElement; tmp_nodes = new Vector(faceElement->NoOfNodes()+1); tmp_Ell = new Matrix(dim,dim); tmp_dN = new Matrix(nnodes,dim); tmp_u = new Vector(dim); tmp_x = new Vector(dim); tmp_xBnd = new Vector(dim+1); LQsf[1] = LQuadTriangleSf1; LQsf[2] = LQuadTriangleSf2; LQsf[3] = LQuadTriangleSf3; LQsf[4] = LQuadTriangleSf4; LQsf[5] = LQuadTriangleSf5; LQsf[6] = LQuadTriangleSf6; dLQsf[1][1] = LQuadTriangleSf1dx; dLQsf[1][2] = LQuadTriangleSf1dy; dLQsf[2][1] = LQuadTriangleSf2dx; dLQsf[2][2] = LQuadTriangleSf2dy; dLQsf[3][1] = LQuadTriangleSf3dx; dLQsf[3][2] = LQuadTriangleSf3dy; dLQsf[4][1] = LQuadTriangleSf4dx; dLQsf[4][2] = LQuadTriangleSf4dy; dLQsf[5][1] = LQuadTriangleSf5dx; dLQsf[5][2] = LQuadTriangleSf5dy; dLQsf[6][1] = LQuadTriangleSf6dx; dLQsf[6][2] = LQuadTriangleSf6dy; } //------------------------------------------------------------------------- void Triangle:: getLocalFaceNodes(int faceNo, Vector& nodes) const { if (faceNo == 1) { nodes[1] = 2; nodes[2] = 3; } else if (faceNo == 2) { nodes[1] = 3; nodes[2] = 1; } else if (faceNo == 3) { nodes[1] = 1; nodes[2] = 2; } else { cout << "\n*** Triangle:: getLocalFaceNodes: wrong face number: " << faceNo << "\n"; cout.flush(); abort(); } } //------------------------------------------------------------------------- void HQuadTriangle:: getLocalFaceNodes(int faceNo, Vector& nodes) const { if (faceNo == 1) { nodes[1] = 2; nodes[2] = 3; nodes[3] = 4; } else if (faceNo == 2) { nodes[1] = 3; nodes[2] = 1; nodes[3] = 5; } else if (faceNo == 3) { nodes[1] = 1; nodes[2] = 2; nodes[3] = 6; } else { cout << "\n*** HQuadTriangle:: getLocalFaceNodes: wrong face number: " << faceNo << "\n"; cout.flush(); abort(); } } //------------------------------------------------------------------------- void HQuadTriangle:: setPatterns() { int i, k; const int nnodes = NoOfNodes(); StdElement::setPatterns(); // -- set the assembly pattern for DLY: DLYPattern = new Matrix(nnodes,nnodes); FORALL_ROWS(*DLYPattern,i) FORALL_COLUMNS(*symPattern,k) (*DLYPattern)(i,k) = False; for (i=4; i<=nnodes; ++i) { (*DLYPattern)(i,i) = True; for (k=1; k<=3; ++k) (*DLYPattern)(i,k) = True; } }