RVector calcGBounds( const std::vector< RVector3 > & pos, const Mesh & mesh, const RVector & model ){ /*! Ensure neighbourInfos() */ RMatrix Jacobian( pos.size(), mesh.cellCount() ); Jacobian *= 0.; for ( uint i = 0; i < pos.size(); i ++ ){ for ( std::vector< Boundary * >::const_iterator it = mesh.boundaries().begin(); it != mesh.boundaries().end(); it ++ ){ Boundary *b = *it; double Z = lineIntegraldGdz( b->node( 0 ).pos() - pos[ i ], b->node( 1 ).pos() - pos[ i ] ); if ( b->leftCell() ) Jacobian[ i ][ b->leftCell()->id() ] = Jacobian[ i ][ b->leftCell()->id() ] - Z; if ( b->rightCell() ) Jacobian[ i ][ b->rightCell()->id() ] = Jacobian[ i ][ b->rightCell()->id() ] + Z; } } return Jacobian * model * 2.0 * 6.67384e-11 * 1e5; }
Boundary * findCommonBoundary(const Cell & c1, const Cell & c2){ for (Index i = 0; i < c1.boundaryCount(); i ++){ Boundary * b = findBoundary(c1.boundaryNodes(i)); if ((b->leftCell() == &c1 && b->rightCell() == &c2) || (b->leftCell() == &c2 && b->rightCell() == &c1)){ return b; } } return NULL; }
bool addTriangleBoundary(Mesh & mesh, double xBoundary, double yBoundary, int cellMarker, bool save){ int boundMarker = -5; mesh.createNeighbourInfos(true); Boundary *b = NULL; for (std::vector < Boundary * >::const_iterator it = mesh.boundaries().begin(); it != mesh.boundaries().end(); it ++){ b = (*it); if (! b->leftCell() || ! b->rightCell()) { if (b->marker() != MARKER_BOUND_HOMOGEN_NEUMANN){ b->setMarker(boundMarker); } } } std::vector < Boundary * > markedBoundaries(mesh.findBoundaryByMarker(boundMarker)); Boundary *start(markedBoundaries.front()); std::list < Node * > boundNodes; boundNodes.push_back(& start->node(0)); Boundary * thisBoundary = start; while (thisBoundary != NULL){ Node * thisNode = boundNodes.back(); Boundary * nextBoundary = NULL; for (std::set < Boundary * >::iterator it = thisNode->boundSet().begin(); it != thisNode->boundSet().end(); it++){ if ((*it)->marker() == boundMarker && (*it) != thisBoundary){ nextBoundary = (*it); break; } } if (nextBoundary){ Node * nextNode = NULL; if (&nextBoundary->node(0) != thisNode){ nextNode = &nextBoundary->node(0); } else { nextNode = &nextBoundary->node(1); } //** Check closed polygones here if (find(boundNodes.begin(), boundNodes.end(), nextNode) == boundNodes.end()) { boundNodes.push_back(nextNode); } else { break; } } thisBoundary = nextBoundary; } boundNodes.push_front(& start->node(1)); thisBoundary = start; while (thisBoundary != NULL){ Node * thisNode = boundNodes.front(); Boundary * nextBoundary = NULL; for (std::set < Boundary * >::iterator it = thisNode->boundSet().begin(); it != thisNode->boundSet().end(); it++){ if ((*it)->marker() == boundMarker && (*it) != thisBoundary){ nextBoundary = (*it); break; } } if (nextBoundary){ Node * nextNode = NULL; if (& nextBoundary->node(0) != thisNode){ nextNode = & nextBoundary->node(0); } else { nextNode = & nextBoundary->node(1); } //** Check closed polygones here if (find(boundNodes.begin(), boundNodes.end(), nextNode) == boundNodes.end()) { boundNodes.push_front(nextNode); } else { break; } } thisBoundary = nextBoundary; } Mesh poly; std::vector < Node * > innerBound; for (std::list < Node * >::iterator it = boundNodes.begin(); it != boundNodes.end(); it ++){ innerBound.push_back(poly.createNode((*it)->pos())); } //** looking for polygon ends Node * upperLeftSurface = innerBound.front(); Node * upperRightSurface = innerBound.back(); if (upperLeftSurface->pos()[0] > upperRightSurface->pos()[0]){ upperLeftSurface = innerBound.back(); upperRightSurface = innerBound.front(); } std::vector < Node * > outerBound; outerBound.push_back(upperLeftSurface); Node *n1 = poly.createNode(upperLeftSurface->pos() - RVector3(xBoundary, 0.0)); Node *n2 = poly.createNode(upperLeftSurface->pos() - RVector3(xBoundary, - mesh.ymin() + yBoundary)); Node *n3 = poly.createNode(upperRightSurface->pos() - RVector3(-xBoundary, - mesh.ymin() + yBoundary)); Node *n4 = poly.createNode(upperRightSurface->pos() - RVector3(-xBoundary, 0.0)); outerBound.push_back(upperLeftSurface); RVector dx(increasingRange(4.0, xBoundary, 20)); for (uint i = 1; i < dx.size()-1; i ++) { outerBound.push_back(poly.createNode(upperLeftSurface->pos() + RVector3(-dx[i], 0))); } outerBound.push_back(n1); for (uint i = 0; i < 9; i ++) { outerBound.push_back(poly.createNode(n1->pos() + (n2->pos() - n1->pos()) / 10 * (i + 1))); } outerBound.push_back(n2); for (uint i = 0; i < 9; i ++) { outerBound.push_back(poly.createNode(n2->pos() + (n3->pos() - n2->pos()) / 10 * (i + 1))); } outerBound.push_back(n3); for (uint i = 0; i < 9; i ++) { outerBound.push_back(poly.createNode(n3->pos() + (n4->pos() - n3->pos()) / 10 * (i + 1))); } outerBound.push_back(n4); for (uint i = dx.size()-2; i > 0; i --) { outerBound.push_back(poly.createNode(upperRightSurface->pos() + RVector3(dx[i], 0))); } outerBound.push_back(upperRightSurface); for (uint i = 0; i < outerBound.size() -1; i ++){ poly.createEdge(*outerBound[i], *outerBound[i + 1], -1); } for (uint i = 0; i < innerBound.size() -1; i ++){ poly.createEdge(*innerBound[i], *innerBound[i + 1], boundMarker); } Mesh boundaryMesh; TriangleWrapper(poly, boundaryMesh, "-YpzeAfaq" + str(33)); std::vector < Boundary * > markedBoundaries2(boundaryMesh.findBoundaryByMarker(boundMarker)); if (markedBoundaries.size() == markedBoundaries2.size()){ for (std::vector < Cell * >::const_iterator it = boundaryMesh.cells().begin(); it != boundaryMesh.cells().end(); it ++){ mesh.copyCell(*(*it))->setMarker(cellMarker); } } else { return false; mesh.save("inMesh"); boundaryMesh.save("boundaryMesh"); throwError(1, WHERE_AM_I + " Sorry!! Boundary mesh is not consistent to input mesh boundary. " + toStr(markedBoundaries.size()) + " != " + toStr(markedBoundaries2.size())); } if (save){ mesh.save("shortFOPinMesh"); boundaryMesh.save("shortFOPboundaryMesh"); } //** Fix boundary marker mesh.createNeighbourInfos(true); b = NULL; for (std::vector < Boundary * >::const_iterator it = mesh.boundaries().begin(); it != mesh.boundaries().end(); it ++){ b = (*it); if (! b->leftCell() || ! b->rightCell()) { if (b->center().y() == mesh.ymax()){ b->setMarker(MARKER_BOUND_HOMOGEN_NEUMANN); } else { b->setMarker(MARKER_BOUND_MIXED); } } } return true; }