00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "ParFUM.h"
00012 #include "ParFUM_internals.h"
00013 #include "import.h"
00014
00015 #include <map>
00016 #include <set>
00017 #include <utility>
00018 #include <cmath>
00019
00020 #define CORNER_ANGLE_CUTOFF (3.0/4.0*3.14159)
00021
00022
00023 using namespace std;
00024
00025 CLINKAGE void
00026 FEM_Mesh_detect_features(int fem_mesh) {
00027 const char *caller="FEM_Mesh_detect_features"; FEMAPI(caller);
00028 FEM_Mesh *m=FEM_Mesh_lookup(fem_mesh,caller);
00029 m->detectFeatures();
00030 }
00031 FORTRAN_AS_C(FEM_MESH_DETECT_FEATURES,
00032 FEM_Mesh_detect_features,
00033 fem_mesh_detect_features,
00034 (int *fem_mesh), (*fem_mesh))
00035
00036
00037
00043 void FEM_Mesh::detectFeatures() {
00044 CkPrintf("detectFeatures() has been called\n");
00045
00046 int rank;
00047 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
00048
00049
00053 std::set<std::pair<int,int> > edgesOnBoundaryWithGhosts;
00054
00055
00056
00057 int nodesPerElem = elem[0].getNodesPer();
00058 CkAssert(nodesPerElem==3);
00059
00060
00061
00062 elem[0].allocateValid();
00063 node.allocateValid();
00064
00065 CkPrintf("%d: %d Nodes, %d Ghost Nodes\n", rank, node.size(), node.ghost->size());
00066 CkPrintf("%d: %d Elem, %d Ghost Elem\n", rank, elem[0].size(), elem[0].ghost->size());
00067
00068
00069 for(int n=0; n<node.size(); n++){
00070
00071 double x,y;
00072
00073 node.get_coord(n,x,y);
00074 CkPrintf("Node %d is at %.1lf,%.1lf\n", n, x, y);
00075 }
00076
00077
00078
00079 for (int ele=0;ele<elem[0].size();ele++) {
00080
00081 if (elem[0].is_valid(ele)) {
00082
00083 const int *conn = elem[0].connFor(ele);
00084
00085 int n1 = conn[0];
00086 int n2 = conn[1];
00087 int n3 = conn[2];
00088
00089 int numElementsOnEdge;
00090
00091 numElementsOnEdge = countElementsOnEdge(n1,n2);
00092 if (numElementsOnEdge==1) {
00093 edgesOnBoundaryWithGhosts.insert(std::make_pair(n1,n2));
00094 }
00095
00096 numElementsOnEdge = countElementsOnEdge(n2,n3);
00097 if (numElementsOnEdge==1) {
00098 edgesOnBoundaryWithGhosts.insert(std::make_pair(n2,n3));
00099 }
00100
00101 numElementsOnEdge = countElementsOnEdge(n3,n1);
00102 if (numElementsOnEdge==1) {
00103 edgesOnBoundaryWithGhosts.insert(std::make_pair(n3,n1));
00104 }
00105
00106 }
00107 }
00108
00109
00110 for (int ele=0;ele<elem[0].ghost->size();ele++) {
00111
00112 if (elem[0].ghost->is_valid(ele)) {
00113
00114 FEM_Elem *ghosts = (FEM_Elem*)elem[0].ghost;
00115 const int *conn = ghosts->connFor(ele);
00116
00117 int n1 = conn[0];
00118 int n2 = conn[1];
00119 int n3 = conn[2];
00120
00121 int numElementsOnEdge;
00122
00123 numElementsOnEdge = countElementsOnEdge(n1,n2);
00124 if (numElementsOnEdge==1) {
00125 edgesOnBoundaryWithGhosts.insert(std::make_pair(n1,n2));
00126 }
00127
00128 numElementsOnEdge = countElementsOnEdge(n2,n3);
00129 if (numElementsOnEdge==1) {
00130 edgesOnBoundaryWithGhosts.insert(std::make_pair(n2,n3));
00131 }
00132
00133 numElementsOnEdge = countElementsOnEdge(n3,n1);
00134 if (numElementsOnEdge==1) {
00135 edgesOnBoundaryWithGhosts.insert(std::make_pair(n3,n1));
00136 }
00137
00138 }
00139 }
00140
00141
00142
00143
00144
00145 for(std::set<std::pair<int,int> >::iterator iter=edgesOnBoundaryWithGhosts.begin(); iter!=edgesOnBoundaryWithGhosts.end(); ++iter){
00146 int n1 = (*iter).first;
00147
00148 int n2 = (*iter).second;
00149
00150
00151 if(n1>=0 || n2>=0){
00152 edgesOnBoundary.insert(make_pair(n1,n2));
00153 verticesOnBoundary.insert(n1);
00154 verticesOnBoundary.insert(n2);
00155 }
00156
00157 }
00158
00159
00160 CkPrintf("%d: Found a total of %d edges(with at least one local node) on boundary of mesh: ", rank, edgesOnBoundary.size());
00161 for(std::set<std::pair<int,int> >::iterator iter=edgesOnBoundary.begin();iter!=edgesOnBoundary.end();++iter){
00162 int n1 = (*iter).first;
00163 int n2 = (*iter).second;
00164 double x1,y1,x2,y2;
00165 node.get_coord(n1,x1,y1);
00166 node.get_coord(n2,x2,y2);
00167 CkPrintf(" %.2lf,%.2lf---%.2lf,%.2lf", x1,y1, x2,y2);
00168 }
00169 CkPrintf("\n");
00170
00171
00172
00173 CkPrintf("%d: Found a total of %d nodes on boundary described earlier:", rank, verticesOnBoundary.size());
00174 for(std::set<int>::iterator iter=verticesOnBoundary.begin();iter!=verticesOnBoundary.end();++iter){
00175 int n = (*iter);
00176 double x,y;
00177 node.get_coord(n,x,y);
00178 CkPrintf(" %.2lf,%.2lf ", x,y);
00179 }
00180 CkPrintf("\n");
00181
00182
00183
00184
00185
00186 double COS_CORNER_ANGLE_CUTOFF = cos(CORNER_ANGLE_CUTOFF);
00187
00188
00189
00190
00191
00192
00193 std::map<int,std::pair<int,int> > vertexToAdjacentBoundaryVertices;
00194
00195 for(std::set<std::pair<int,int> >::iterator iter=edgesOnBoundaryWithGhosts.begin();iter!=edgesOnBoundaryWithGhosts.end();++iter){
00196 int n1 = (*iter).first;
00197 int n2 = (*iter).second;
00198
00199
00200 if(n1>=0){
00201
00202 std::map<int,std::pair<int,int> >::iterator v = vertexToAdjacentBoundaryVertices.find(n1);
00203 if( v == vertexToAdjacentBoundaryVertices.end() ){
00204
00205 vertexToAdjacentBoundaryVertices[n1] = make_pair( n2, -1 );
00206 }
00207 else if((*v).first == n2){
00208
00209 }
00210 else{
00211
00212
00213 CkAssert((*v).second.second==-1);
00214 (*v).second.second = n2;
00215 }
00216 }
00217
00218
00219
00220 if(n2>=0){
00221 std::map<int,std::pair<int,int> >::iterator v = vertexToAdjacentBoundaryVertices.find(n1);
00222 v = vertexToAdjacentBoundaryVertices.find(n2);
00223 if( v == vertexToAdjacentBoundaryVertices.end() ){
00224
00225 vertexToAdjacentBoundaryVertices[n2] = make_pair( n1, -1 );
00226
00227 }
00228 else if((*v).first == n1){
00229
00230 }
00231 else{
00232
00233
00234 CkAssert((*v).second.second==-1);
00235 (*v).second.second = n1;
00236 }
00237 }
00238
00239 }
00240
00241
00242
00243 for(std::set<int>::iterator iter=verticesOnBoundary.begin();iter!=verticesOnBoundary.end();iter++){
00244 int n = *iter;
00245
00246
00247
00248 if(n>=0){
00249
00250
00251 int n1 = vertexToAdjacentBoundaryVertices[n].first;
00252 int n2 = vertexToAdjacentBoundaryVertices[n].second;
00253
00254
00255 double x1,y1,x2,y2,x,y;
00256
00257 node.get_coord(n,x,y);
00258 node.get_coord(n1,x1,y1);
00259 node.get_coord(n2,x2,y2);
00260
00261
00262
00263 double v1x = x1-x;
00264 double v1y = y1-y;
00265
00266 double v2x = x2-x;
00267 double v2y = y2-y;
00268
00269 double cos_theta = (v1x*v2x+v1y*v2y)/(sqrt(v1x*v1x+v1y*v1y) * sqrt(v2x*v2x+v2y*v2y) );
00270
00271
00272 CkPrintf("nodes (%.2lf,%.2lf) (%.2lf,%.2lf) (%.2lf,%.2lf) form angle cos=%.3lf\n", x,y,x1,y1,x2,y2, cos_theta);
00273
00274
00275
00276 if(cos_theta > COS_CORNER_ANGLE_CUTOFF) {
00277
00278 cornersOnBoundary.insert(n);
00279 }
00280 }
00281
00282 }
00283
00284 CkPrintf("Found a total of %d corner nodes on boundary of mesh:\n", cornersOnBoundary.size());
00285
00286 for(std::set<int>::iterator iter=cornersOnBoundary.begin();iter!=cornersOnBoundary.end();++iter){
00287 int n = (*iter);
00288 double x,y;
00289 node.get_coord(n,x,y);
00290 CkPrintf(" %d=(%.2lf,%.2lf)", n, x,y);
00291 }
00292 CkPrintf("\n");
00293
00294
00295 }
00296
00297
00298
00299