bool TriangleMesherInterface :: meshPSLG(const Triangle_PSLG &pslg, const IntArray &outside, const IntArray &inside, std :: vector< FloatArray > &nodes, std :: vector< IntArray > &n_markers, std :: vector< IntArray > &triangles, IntArray &t_markers, std :: vector< IntArray > &segments, IntArray &s_markers) const { #ifdef __TRIANGLE_MODULE // 1. Fill the struct for triangle; struct triangulateio mesh; clearTriangulateIO(mesh); // 1.a. Copy over the node data. mesh.numberofpoints = pslg.nx.giveSize(); mesh.pointlist = new REAL [ mesh.numberofpoints * 2 ]; //mesh.pointmarkerlist = new REAL[mesh.numberofpoints]; for ( int i = 0; i < mesh.numberofpoints; ++i ) { mesh.pointlist [ i * 2 ] = pslg.nx(i); mesh.pointlist [ i * 2 + 1 ] = pslg.ny(i); //mesh.pointmarkerlist[i] = pslg.n_marker(i); } // 1.b. Copy over the segment data printf("Copying segment data\n"); mesh.numberofsegments = pslg.segment_a.giveSize(); mesh.segmentlist = new int [ mesh.numberofsegments * 2 ]; for ( int i = 0; i < mesh.numberofsegments; ++i ) { mesh.segmentlist [ i * 2 ] = pslg.segment_a(i); mesh.segmentlist [ i * 2 + 1 ] = pslg.segment_b(i); } if ( pslg.segment_marker.giveSize() > 0 ) { mesh.segmentmarkerlist = new int [ mesh.numberofsegments ]; for ( int i = 0; i < mesh.numberofsegments; ++i ) { mesh.segmentmarkerlist [ i ] = pslg.segment_marker(i); } } // 2. Triangulate char options [ 100 ]; // Note: Not sure if -A is necessary when using the library interface. sprintf(options, "-p -q %f -a%f %s -A", this->minAngle, this->maxArea, this->quadratic ? "-o2" : ""); struct triangulateio output; clearTriangulateIO(output); custom_triangulate( options, & mesh, & output, NULL, outside.givePointer(), inside.givePointer() ); // 3. Copy back nodes.resize(output.numberofpoints); //n_markers.resize(output.numberofpoints); for ( int i = 0; i < output.numberofpoints; ++i ) { nodes [ i ].resize(2); nodes [ i ].at(1) = output.pointlist [ i * 2 ]; nodes [ i ].at(2) = output.pointlist [ i * 2 + 1 ]; //n_markers(i) = output.pointmarkerlist[i]; // Not enough. } triangles.resize(output.numberoftriangles); t_markers.resize(output.numberoftriangles); for ( int i = 0; i < output.numberoftriangles; ++i ) { IntArray &triangle = triangles [ i ]; triangle.resize(output.numberofcorners); for ( int j = 0; j < 3; j++ ) { // First three triangle(j) = output.trianglelist [ i * output.numberofcorners + j ]; } // Rearrange the strange ordering of the edge nodes. if ( output.numberofcorners == 6 ) { triangle(3) = output.trianglelist [ i * output.numberofcorners + 5 ]; triangle(4) = output.trianglelist [ i * output.numberofcorners + 3 ]; triangle(5) = output.trianglelist [ i * output.numberofcorners + 4 ]; } t_markers.at(i + 1) = ( int ) round(output.triangleattributelist [ i ]); } // A somewhat annoying missing feature of triangle, it won't make the segments quadratic. std :: set< std :: size_t > *node_triangle = NULL; if ( this->quadratic ) { node_triangle = new std :: set< std :: size_t > [ output.numberofpoints ]; for ( std :: size_t i = 0; i < triangles.size(); ++i ) { IntArray &triangle = triangles [ i ]; for ( int j = 1; j <= 3; ++j ) { node_triangle [ triangle.at(j) - 1 ].insert(i); } } } segments.resize(output.numberofsegments); s_markers.resize(output.numberofsegments); for ( int i = 0; i < output.numberofsegments; ++i ) { IntArray &segment = segments [ i ]; segment.resize(this->quadratic ? 3 : 2); segment.at(1) = output.segmentlist [ i * 2 + 0 ]; segment.at(2) = output.segmentlist [ i * 2 + 1 ]; //segment->at(3) = output.segmentlist[i*3 + 2]; // Quadratic meshes only, not for segments. if ( this->quadratic ) { int a, b, c; std :: set< std :: size_t >tris = node_triangle [ segment.at(1) - 1 ]; // Now look up any triangle with the other point included. for ( auto tri: tris ) { IntArray &triangle = triangles [ tri ]; if ( ( b = triangle.findFirstIndexOf( segment.at(2) ) ) > 0 ) { a = triangle.findFirstIndexOf( segment.at(1) ); if ( a + b == 3 ) { c = 4; } else if ( a + b == 5 ) { c = 5; } else { c = 6; } segment.at(3) = triangle.at(c); break; } } } s_markers.at(i + 1) = output.segmentmarkerlist [ i ]; } if ( this->quadratic ) { delete[] node_triangle; } this->fixNodeMarkers(nodes, n_markers, triangles, t_markers, segments, s_markers); // Deleting old memory delete[] mesh.pointlist; //delete[] mesh.pointattributelist; //delete[] mesh.pointmarkerlist; //delete[] mesh.trianglelist; //delete[] mesh.triangleattributelist; //delete[] mesh.trianglearealist; delete[] mesh.segmentlist; delete[] mesh.segmentmarkerlist; //if (mesh.holelist) { delete[] mesh.holelist; } //if (mesh.regionlist) { delete[] mesh.regionlist; } // Holes and regions are referenced in both. free(output.pointlist); //free(output.pointattributelist); free(output.pointmarkerlist); free(output.trianglelist); free(output.triangleattributelist); //free(output.trianglearealist); free(output.segmentlist); free(output.segmentmarkerlist); //free(output.holelist); //free(output.regionlist); #else OOFEM_ERROR("OOFEM is not compiled with support for triangle."); #endif return true; }
void NRSolver :: applyConstraintsToStiffness(SparseMtrx *k) { if ( this->smConstraintVersion == k->giveVersion() ) { return; } #if 0 #ifdef __PETSC_MODULE if ( solverType == ST_Petsc ) { PetscScalar diagVal = 1.0; if ( k->giveType() != SMT_PetscMtrx ) { OOFEM_ERROR("NRSolver :: applyConstraintsToStiffness: PetscSparseMtrx Expected"); } PetscSparseMtrx *lhs = ( PetscSparseMtrx * ) k; if ( !prescribedEgsIS_defined ) { IntArray eqs; #ifdef __PARALLEL_MODE Natural2GlobalOrdering *n2lpm = engngModel->givePetscContext(1)->giveN2Gmap(); int s = prescribedEqs.giveSize(); eqs.resize(s); for ( int i = 1; i <= s; i++ ) { eqs.at(i) = n2lpm->giveNewEq( prescribedEqs.at(i) ); } ISCreateGeneral(PETSC_COMM_WORLD, s, eqs.givePointer(), & prescribedEgsIS); //ISView(prescribedEgsIS,PETSC_VIEWER_STDOUT_WORLD); #else eqs.resize(numberOfPrescribedDofs); for ( int i = 1; i <= numberOfPrescribedDofs; i++ ) { eqs.at(i) = prescribedEqs.at(i) - 1; } ISCreateGeneral(PETSC_COMM_SELF, numberOfPrescribedDofs, eqs.givePointer(), & prescribedEgsIS); //ISView(prescribedEgsIS,PETSC_VIEWER_STDOUT_SELF); #endif prescribedEgsIS_defined = true; } //MatView(*(lhs->giveMtrx()),PETSC_VIEWER_STDOUT_WORLD); MatZeroRows(* ( lhs->giveMtrx() ), prescribedEgsIS, & diagVal); //MatView(*(lhs->giveMtrx()),PETSC_VIEWER_STDOUT_WORLD); if ( numberOfPrescribedDofs ) { this->smConstraintVersion = k->giveVersion(); } return; } #endif // __PETSC_MODULE #else #ifdef __PETSC_MODULE if ( solverType == ST_Petsc ) { if ( k->giveType() != SMT_PetscMtrx ) { OOFEM_ERROR("NRSolver :: applyConstraintsToStiffness: PetscSparseMtrx Expected"); } PetscSparseMtrx *lhs = ( PetscSparseMtrx * ) k; Vec diag; PetscScalar *ptr; int eq; PetscContext *parallel_context = engngModel->givePetscContext(this->domain->giveNumber()); parallel_context->createVecGlobal(& diag); MatGetDiagonal(* lhs->giveMtrx(), diag); VecGetArray(diag, & ptr); for ( int i = 1; i <= numberOfPrescribedDofs; i++ ) { eq = prescribedEqs.at(i) - 1; MatSetValue(* ( lhs->giveMtrx() ), eq, eq, ptr [ eq ] * 1.e6, INSERT_VALUES); } MatAssemblyBegin(* lhs->giveMtrx(), MAT_FINAL_ASSEMBLY); MatAssemblyEnd(* lhs->giveMtrx(), MAT_FINAL_ASSEMBLY); VecRestoreArray(diag, & ptr); VecDestroy(&diag); if ( numberOfPrescribedDofs ) { this->smConstraintVersion = k->giveVersion(); } return; } #endif // __PETSC_MODULE #endif for ( int i = 1; i <= numberOfPrescribedDofs; i++ ) { k->at( prescribedEqs.at(i), prescribedEqs.at(i) ) *= 1.e6; } if ( numberOfPrescribedDofs ) { this->smConstraintVersion = k->giveVersion(); } }