void Line2SurfaceTension :: computeLoadVector(FloatArray &answer, ValueModeType mode, TimeStep *tStep) { ///@todo Support axisymm. //domainType dt = this->giveDomain()->giveDomainType(); IntegrationRule *iRule = this->integrationRulesArray [ 0 ]; double t = 1, gamma_s; ///@todo Should i use this? Not used in FM module (but perhaps it should?) / Mikael. //t = this->giveDomain()->giveCrossSection(1)->give(CS_Thickness); gamma_s = this->giveMaterial()->give('g', NULL); FloatMatrix xy(2, 3); Node *node; for ( int i = 1; i <= 3; i++ ) { node = giveNode(i); xy.at(1, i) = node->giveCoordinate(1); xy.at(2, i) = node->giveCoordinate(2); } FloatArray A; FloatArray dNdxi(3); FloatArray es(2); // tangent vector to curve FloatMatrix BJ(2, 6); BJ.zero(); answer.resize(6); answer.zero(); for ( int k = 0; k < iRule->getNumberOfIntegrationPoints(); k++ ) { GaussPoint *gp = iRule->getIntegrationPoint(k); //interpolation.evaldNdx(dN, domain, dofManArray, * gp->giveCoordinates(), 0.0); double xi = gp->giveCoordinate(1); // Some simplifications can be performed, since the mapping J is a scalar. dNdxi.at(1) = -0.5 + xi; dNdxi.at(2) = 0.5 + xi; dNdxi.at(3) = -2.0 * xi; es.beProductOf(xy, dNdxi); double J = es.computeNorm(); es.times(1 / J); //es.normalize(); // dNds = dNdxi/J // B.at(1,1) = dNds.at(1); and so on. BJ.at(1, 1) = BJ.at(2, 2) = dNdxi.at(1); BJ.at(1, 3) = BJ.at(2, 4) = dNdxi.at(2); BJ.at(1, 5) = BJ.at(2, 6) = dNdxi.at(3); A.beTProductOf(BJ, es); answer.add( - gamma_s * t * gp->giveWeight(), A); // Note! Negative sign! } }
double FEI3dTetQuad :: surfaceEvalNormal(FloatArray &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) { IntArray snodes(3); FloatArray a,b; this->computeLocalSurfaceMapping(snodes, isurf); double l1, l2, l3; l1 = lcoords.at(1); l2 = lcoords.at(2); l3 = 1.0 - l1 - l2; FloatArray dNdxi(6), dNdeta(6); dNdxi(0) = 4.0 * l1 - 1.0; dNdxi(1) = 0.0; dNdxi(2) = -1.0 * ( 4.0 * l3 - 1.0 ); dNdxi(3) = 4.0 * l2; dNdxi(4) = -4.0 * l2; dNdxi(5) = 4.0 * l3 - 4.0 * l1; dNdeta(0) = 0.0; dNdeta(1) = 4.0 * l2 - 1.0; dNdeta(2) = -1.0 * ( 4.0 * l3 - 1.0 ); dNdeta(3) = 4.0 * l1; dNdeta(4) = 4.0 * l3 - 4.0 * l2; dNdeta(5) = -4.0 * l1; for (int i = 0; i < 6; ++i) { a.add(dNdxi(i), *cellgeo.giveVertexCoordinates(snodes(i))); b.add(dNdeta(i), *cellgeo.giveVertexCoordinates(snodes(i))); } answer.beVectorProductOf(a, b); double J = answer.computeNorm(); answer.times(1/J); return J; }
void FEI2dTrQuad :: edgeEvaldNds(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) { // I think it at least should return both dNds and J. Both are almost always needed. // In fact, dxdxi is also needed sometimes (surface tension) #if 0 IntArray edgeNodes; FloatArray dNdxi(3); FloatArray dxdxi(2); double xi = lcoords.at(1); this->computeLocalEdgeMapping(edgeNodes, iedge); dNdxi.at(1) = xi - 0.5; dNdxi.at(2) = xi + 0.5; dNdxi.at(3) = -2 * xi; dxdxi.at(1) = dNdxi.at(1) * cellgeo.giveVertexCoordinates( edgeNodes.at(1) )->at(xind) + dNdxi.at(2) * cellgeo.giveVertexCoordinates( edgeNodes.at(2) )->at(xind) + dNdxi.at(3) * cellgeo.giveVertexCoordinates( edgeNodes.at(3) )->at(xind); dxdxi.at(2) = dNdxi.at(1) * cellgeo.giveVertexCoordinates( edgeNodes.at(1) )->at(yind) + dNdxi.at(2) * cellgeo.giveVertexCoordinates( edgeNodes.at(2) )->at(yind) + dNdxi.at(3) * cellgeo.giveVertexCoordinates( edgeNodes.at(3) )->at(yind); double J = dxdxi.computeNorm(); answer = dNdxi; answer.times(1 / J); return J; #endif double xi = lcoords.at(1); double J = edgeGiveTransformationJacobian(iedge, lcoords, cellgeo); answer = { ( xi - 0.5 ) / J, ( xi + 0.5 ) / J, -2 * xi / J }; }
void Line2SurfaceTension :: computeTangent(FloatMatrix &answer, TimeStep *tStep) { #if 1 answer.resize(6, 6); answer.zero(); #else ///@todo Support axisymm. domainType dt = this->giveDomain()->giveDomainType(); if (dt == _3dAxisymmMode) { OOFEM_ERROR("Line2SurfaceTension :: computeTangent - Axisymm not implemented"); } IntegrationRule *iRule = this->integrationRulesArray [ 0 ]; double t = 1, gamma_s; ///@todo Should i use this? Not that meaningful for flow problems. //t = this->giveDomain()->giveCrossSection(1)->give(CS_Thickness); gamma_s = this->giveMaterial()->give('g', NULL); FloatMatrix xy(2,3); Node *node; for (int i = 1; i <= 3; i++) { node = giveNode(i); xy.at(1,i) = node->giveCoordinate(1); xy.at(2,i) = node->giveCoordinate(2); } FloatArray A; FloatArray dNdxi(3); FloatArray es(2); // tangent vector to curve FloatMatrix BJ(2,6); BJ.zero(); FloatMatrix temp1,temp2; answer.resize(6,6); answer.zero(); for (int k = 0; k < iRule->getNumberOfIntegrationPoints(); k++ ) { GaussPoint *gp = iRule->getIntegrationPoint(k); double xi = gp->giveCoordinate(1); dNdxi.at(1) = -0.5+xi; dNdxi.at(2) = 0.5+xi; dNdxi.at(3) = -2.0*xi; es.beProductOf(xy,dNdxi); double J = es.computeNorm(); es.times(1/J); //es.normalize(); BJ.at(1,1) = BJ.at(2,2) = dNdxi.at(1); BJ.at(1,3) = BJ.at(2,4) = dNdxi.at(2); BJ.at(1,5) = BJ.at(2,6) = dNdxi.at(3); A.beTProductOf(BJ,es); temp1.beTProductOf(BJ,BJ); temp2.beDyadicProductOf(A,A); temp1.subtract(temp2); temp1.times(t*gp->giveWeight()/J*(tStep->giveTimeIncrement())); answer.add(temp1); } answer.times(gamma_s); #endif }