moab
|
00001 #include "moab/Core.hpp" 00002 #include "moab/CpuTimer.hpp" 00003 #include "DataCoupler.hpp" 00004 #include "ElemUtil.hpp" 00005 #include "iMesh.h" 00006 #include "MBiMesh.hpp" 00007 00008 #include <iostream> 00009 #include <iomanip> 00010 #include <sstream> 00011 #include <assert.h> 00012 00013 #ifdef USE_MPI 00014 #include "moab/ParallelComm.hpp" 00015 #include "MBParallelConventions.h" 00016 #endif 00017 00018 using namespace moab; 00019 00020 #define STRINGIFY_(A) #A 00021 #define STRINGIFY(A) STRINGIFY_(A) 00022 #ifdef MESHDIR 00023 std::string TestDir( STRINGIFY(MESHDIR) ); 00024 #else 00025 std::string TestDir("."); 00026 #endif 00027 00028 #define RRA(a) if (MB_SUCCESS != result) {\ 00029 std::string tmp_str; mbImpl->get_last_error(tmp_str);\ 00030 tmp_str.append("\n"); tmp_str.append(a);\ 00031 dynamic_cast<Core*>(mbImpl)->get_error_handler()->set_last_error(tmp_str.c_str()); \ 00032 return result;} 00033 00034 #define PRINT_LAST_ERROR \ 00035 if (MB_SUCCESS != result) {\ 00036 std::string tmp_str;\ 00037 std::cout << "Failure; message:" << std::endl;\ 00038 mbImpl->get_last_error(tmp_str);\ 00039 std::cout << tmp_str << std::endl;\ 00040 MPI_Abort(MPI_COMM_WORLD, result); \ 00041 return result;\ 00042 } 00043 00044 #define PRINT_LAST_ERR \ 00045 if (iBase_SUCCESS != err) {\ 00046 std::string tmp_str;\ 00047 std::cout << "Failure; message:" << std::endl;\ 00048 mbImpl->get_last_error(tmp_str);\ 00049 std::cout << tmp_str << std::endl;\ 00050 MPI_Abort(MPI_COMM_WORLD, result); \ 00051 return result;\ 00052 } 00053 00054 void print_usage(char **argv); 00055 00056 ErrorCode get_file_options(int argc, char **argv, 00057 std::vector<std::string> &meshFiles, 00058 DataCoupler::Method &method, 00059 std::string &interpTag, 00060 std::string &gNormTag, 00061 std::string &ssNormTag, 00062 std::vector<const char *> &ssTagNames, 00063 std::vector<const char *> &ssTagValues, 00064 std::string &readOpts, 00065 std::string &outFile, 00066 std::string &writeOpts, 00067 std::string &dbgFile, 00068 bool &help, 00069 double & epsilon); 00070 00071 // ErrorCode get_file_options(int argc, char **argv, 00072 // std::vector<const char *> &filenames, 00073 // std::string &tag_name, 00074 // std::string &out_fname, 00075 // std::string &opts); 00076 00077 #ifdef USE_MPI 00078 ErrorCode report_iface_ents(Interface *mbImpl, 00079 std::vector<ParallelComm *> &pcs, 00080 bool print_results); 00081 #endif 00082 00083 ErrorCode test_interpolation(Interface *mbImpl, 00084 DataCoupler::Method method, 00085 std::string &interpTag, 00086 std::string &gNormTag, 00087 std::string &ssNormTag, 00088 std::vector<const char *> &ssTagNames, 00089 std::vector<const char *> &ssTagValues, 00090 iBase_EntitySetHandle *roots, 00091 std::vector<ParallelComm *> &pcs, 00092 double &instant_time, 00093 double &pointloc_time, 00094 double &interp_time, 00095 double &gnorm_time, 00096 double &ssnorm_time, 00097 double & toler); 00098 00099 void reduceMax(double &v){ 00100 double buf; 00101 00102 MPI_Barrier(MPI_COMM_WORLD); 00103 MPI_Allreduce( &v, &buf, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); 00104 00105 v=buf; 00106 } 00107 00108 00109 int main(int argc, char **argv) 00110 { 00111 00112 int err; 00113 00114 #ifdef USE_MPI 00115 // need to init MPI first, to tell how many procs and rank 00116 err = MPI_Init(&argc, &argv); 00117 #endif 00118 00119 std::vector<const char *> ssTagNames, ssTagValues; 00120 std::vector<std::string> meshFiles; 00121 std::string interpTag, gNormTag, ssNormTag, readOpts, outFile, writeOpts, dbgFile; 00122 DataCoupler::Method method = DataCoupler::CONSTANT; 00123 00124 ErrorCode result = MB_SUCCESS; 00125 bool help = false; 00126 double toler = 5.e-10; 00127 result = get_file_options(argc, argv, meshFiles, method, interpTag, 00128 gNormTag, ssNormTag, ssTagNames, ssTagValues, 00129 readOpts, outFile, writeOpts, dbgFile, help, toler); 00130 00131 if (result != MB_SUCCESS || help) { 00132 print_usage(argv); 00133 #ifdef USE_MPI 00134 err = MPI_Finalize(); 00135 #endif 00136 return 1; 00137 } 00138 00139 int nprocs = 1, rank = 0; 00140 00141 #ifdef USE_MPI 00142 err = MPI_Comm_size(MPI_COMM_WORLD, &nprocs); 00143 err = MPI_Comm_rank(MPI_COMM_WORLD, &rank); 00144 std::vector<ParallelComm *> pcs(meshFiles.size()); 00145 #endif 00146 00147 // redirect stdout and stderr if dbgFile is not null 00148 if (!dbgFile.empty()) { 00149 std::stringstream dfname; 00150 dfname << dbgFile << rank << ".txt"; 00151 if (!std::freopen(dfname.str().c_str(), "a", stdout)) return false; 00152 if (!std::freopen(dfname.str().c_str(), "a", stderr)) return false; 00153 } 00154 00155 // create MOAB instance based on that 00156 Interface *mbImpl = new Core(); 00157 if (NULL == mbImpl) return 1; 00158 00159 iMesh_Instance iMeshInst = reinterpret_cast<iMesh_Instance>( new MBiMesh(mbImpl) ); 00160 00161 // read in mesh(es) 00162 00163 // Create root sets for each mesh using the iMesh API. Then pass these 00164 // to the load_file functions to be populated. 00165 iBase_EntitySetHandle *roots = (iBase_EntitySetHandle *) malloc(sizeof(iBase_EntitySetHandle) * meshFiles.size()); 00166 00167 for (unsigned int i = 0; i < meshFiles.size(); i++) { 00168 std::string newReadopts; 00169 std::ostringstream extraOpt; 00170 #ifdef USE_MPI 00171 pcs[i] = new ParallelComm(mbImpl, MPI_COMM_WORLD); 00172 int index = pcs[i]->get_id(); 00173 extraOpt << ";PARALLEL_COMM=" << index; 00174 newReadopts = readOpts+extraOpt.str(); 00175 #endif 00176 00177 iMesh_createEntSet(iMeshInst, 0, &(roots[i]), &err); 00178 result = mbImpl->load_file( meshFiles[i].c_str(), (EntityHandle *)&roots[i], newReadopts.c_str() ); 00179 PRINT_LAST_ERROR; 00180 } 00181 00182 #ifdef USE_MPI 00183 result = report_iface_ents(mbImpl, pcs, true); 00184 PRINT_LAST_ERROR; 00185 #endif 00186 00187 double instant_time=0.0, pointloc_time=0.0, interp_time=0.0, gnorm_time=0.0, ssnorm_time=0.0; 00188 // test interpolation and global normalization and subset normalization 00189 00190 result = test_interpolation(mbImpl, method, interpTag, gNormTag, ssNormTag, 00191 ssTagNames, ssTagValues, roots, pcs, 00192 instant_time, pointloc_time, interp_time, 00193 gnorm_time, ssnorm_time, toler); 00194 PRINT_LAST_ERROR; 00195 00196 00197 reduceMax(instant_time); 00198 reduceMax(pointloc_time); 00199 reduceMax(interp_time); 00200 00201 if(0==rank) 00202 printf("\nMax time : %g %g %g (inst loc interp -- %d procs )\n", instant_time, 00203 pointloc_time, interp_time, nprocs); 00204 00205 // output mesh 00206 if (!outFile.empty()) { 00207 Range partSets; 00208 // only save the target mesh 00209 partSets.insert((EntityHandle)roots[1]); 00210 std::string newwriteOpts = writeOpts; 00211 std::ostringstream extraOpt; 00212 #ifdef USE_MPI 00213 extraOpt << ";PARALLEL_COMM=" << 1; 00214 newwriteOpts += extraOpt.str(); 00215 #endif 00216 result = mbImpl->write_file(outFile.c_str(), NULL, newwriteOpts.c_str(), partSets); 00217 PRINT_LAST_ERROR; 00218 std::cout << "Wrote " << outFile << std::endl; 00219 std::cout << "mbcoupler_test complete." << std::endl; 00220 } 00221 00222 #ifdef USE_MPI 00223 for (unsigned int i = 0; i < meshFiles.size(); i++) { 00224 delete pcs[i]; 00225 } 00226 #endif 00227 00228 delete mbImpl; 00229 //may be leaking iMeshInst, don't care since it's end of program. Remove above deletes? 00230 00231 #ifdef USE_MPI 00232 err = MPI_Finalize(); 00233 #endif 00234 00235 return 0; 00236 } 00237 00238 #ifdef USE_MPI 00239 ErrorCode report_iface_ents(Interface *mbImpl, 00240 std::vector<ParallelComm *> &pcs, 00241 const bool print_results) 00242 { 00243 Range iface_ents[6]; 00244 ErrorCode result = MB_SUCCESS, tmp_result; 00245 00246 // now figure out which vertices are shared 00247 for (unsigned int p = 0; p < pcs.size(); p++) { 00248 for (int i = 0; i < 4; i++) { 00249 tmp_result = pcs[p]->get_iface_entities(-1, i, iface_ents[i]); 00250 00251 if (MB_SUCCESS != tmp_result) { 00252 std::cerr << "get_iface_entities returned error on proc " 00253 << pcs[p]->proc_config().proc_rank() << "; message: " << std::endl; 00254 std::string last_error; 00255 result = mbImpl->get_last_error(last_error); 00256 if (last_error.empty()) std::cerr << "(none)" << std::endl; 00257 else std::cerr << last_error << std::endl; 00258 result = tmp_result; 00259 } 00260 if (0 != i) iface_ents[4].merge(iface_ents[i]); 00261 } 00262 } 00263 00264 // report # iface entities 00265 result = mbImpl->get_adjacencies(iface_ents[4], 0, false, iface_ents[5], 00266 Interface::UNION); 00267 00268 int rank; 00269 MPI_Comm_rank(MPI_COMM_WORLD, &rank); 00270 00271 if (print_results || iface_ents[0].size() != iface_ents[5].size()) { 00272 std::cerr << "Proc " << rank << " iface entities: " << std::endl; 00273 for (int i = 0; i < 4; i++) 00274 std::cerr << " " << iface_ents[i].size() << " " 00275 << i << "d iface entities." << std::endl; 00276 std::cerr << " (" << iface_ents[5].size() 00277 << " verts adj to other iface ents)" << std::endl; 00278 } 00279 00280 return result; 00281 } 00282 #endif 00283 00284 // Print usage 00285 void print_usage(char **argv) { 00286 std::cerr << "Usage: "; 00287 std::cerr << argv[0] << " -meshes <source_mesh> <target_mesh> -itag <interp_tag> [-gnorm <gnorm_tag>] [-ssnorm <ssnorm_tag> <ssnorm_selection>] [-ropts <roptions>] [-outfile <out_file> [-wopts <woptions>]] [-dbgout [<dbg_file>]]" << std::endl; 00288 std::cerr << " -meshes" << std::endl; 00289 std::cerr << " Read in mesh files <source_mesh> and <target_mesh>." << std::endl; 00290 std::cerr << " -itag" << std::endl; 00291 std::cerr << " Interpolate tag <interp_tag> from source mesh to target mesh." << std::endl; 00292 std::cerr << " -gnorm" << std::endl; 00293 std::cerr << " Normalize the value of tag <gnorm_tag> over then entire mesh and save to" << std::endl; 00294 std::cerr << " tag \"<gnorm_tag>_normf\" on the mesh set. Do this for all meshes." << std::endl; 00295 std::cerr << " -ssnorm" << std::endl; 00296 std::cerr << " Normalize the value of tag <ssnorm_tag> over subsets of a mesh and save to" << std::endl; 00297 std::cerr << " tag \"<ssnorm_tag>_normf\" on the Entity Set for each subset. Subsets are selected" << std::endl; 00298 std::cerr << " using criteria in <ssnorm_selection>. Do this for all meshes." << std::endl; 00299 std::cerr << " -ropts" << std::endl; 00300 std::cerr << " Read in the mesh files using options in <roptions>." << std::endl; 00301 std::cerr << " -outfile" << std::endl; 00302 std::cerr << " Write out target mesh to <out_file>." << std::endl; 00303 std::cerr << " -wopts" << std::endl; 00304 std::cerr << " Write out mesh files using options in <woptions>." << std::endl; 00305 std::cerr << " -dbgout" << std::endl; 00306 std::cerr << " Write stdout and stderr streams to the file \'<dbg_file>.txt\'." << std::endl; 00307 std::cerr << " -eps" << std::endl; 00308 std::cerr << " epsilon" << std::endl; 00309 std::cerr << " -meth <method> (0=CONSTANT, 1=LINEAR_FE, 2=QUADRATIC_FE, 3=SPECTRAL)" << std::endl; 00310 } 00311 00312 // Check first character for a '-'. 00313 // Return true if one is found. False otherwise. 00314 bool check_for_flag(const char *str) { 00315 if (str[0] == '-') 00316 return true; 00317 else 00318 return false; 00319 } 00320 00321 // New get_file_options() function with added possibilities for mbcoupler_test. 00322 ErrorCode get_file_options(int argc, char **argv, 00323 std::vector<std::string> &meshFiles, 00324 DataCoupler::Method &method, 00325 std::string &interpTag, 00326 std::string &gNormTag, 00327 std::string &ssNormTag, 00328 std::vector<const char *> &ssTagNames, 00329 std::vector<const char *> &ssTagValues, 00330 std::string &readOpts, 00331 std::string &outFile, 00332 std::string &writeOpts, 00333 std::string &dbgFile, 00334 bool &help, 00335 double & epsilon) 00336 { 00337 // Initialize some of the outputs to null values indicating not present 00338 // in the argument list. 00339 gNormTag = ""; 00340 ssNormTag = ""; 00341 readOpts = "PARALLEL=READ_PART;PARTITION=PARALLEL_PARTITION;PARTITION_DISTRIBUTE;PARALLEL_RESOLVE_SHARED_ENTS;PARALLEL_GHOSTS=3.0.1;CPUTIME"; 00342 outFile = ""; 00343 writeOpts = "PARALLEL=WRITE_PART;CPUTIME"; 00344 dbgFile = ""; 00345 std::string defaultDbgFile = argv[0]; // The executable name will be the default debug output file. 00346 00347 // These will indicate if we've gotten our required parameters at the end of parsing. 00348 bool haveMeshes = false; 00349 bool haveInterpTag = false; 00350 00351 // Loop over the values in argv pulling out an parsing each one 00352 int npos = 1; 00353 00354 if (argc > 1 && argv[1] == std::string("-h")) { 00355 help = true; 00356 return MB_SUCCESS; 00357 } 00358 00359 while (npos < argc) { 00360 if (argv[npos] == std::string("-meshes")) { 00361 // Parse out the mesh filenames 00362 npos++; 00363 int numFiles = 2; 00364 meshFiles.resize(numFiles); 00365 for (int i = 0; i < numFiles; i++) { 00366 if ((npos < argc) && (!check_for_flag(argv[npos]))) 00367 meshFiles[i] = argv[npos++]; 00368 else { 00369 std::cerr << " ERROR - missing correct number of mesh filenames" << std::endl; 00370 return MB_FAILURE; 00371 } 00372 } 00373 00374 haveMeshes = true; 00375 } 00376 else if (argv[npos] == std::string("-itag")) { 00377 // Parse out the interpolation tag 00378 npos++; 00379 if ((npos < argc) && (!check_for_flag(argv[npos]))) 00380 interpTag = argv[npos++]; 00381 else { 00382 std::cerr << " ERROR - missing <interp_tag>" << std::endl; 00383 return MB_FAILURE; 00384 } 00385 00386 haveInterpTag = true; 00387 } 00388 else if (argv[npos] == std::string("-meth")) { 00389 // Parse out the interpolation tag 00390 npos++; 00391 if (argv[npos][0] == '0') method = DataCoupler::CONSTANT; 00392 else if (argv[npos][0] == '1') method = DataCoupler::LINEAR_FE; 00393 else if (argv[npos][0] == '2') method = DataCoupler::QUADRATIC_FE; 00394 else if (argv[npos][0] == '3') method = DataCoupler::SPECTRAL; 00395 else { 00396 std::cerr << " ERROR - unrecognized method number " << method << std::endl; 00397 return MB_FAILURE; 00398 } 00399 npos++; 00400 } 00401 else if (argv[npos] == std::string("-eps")) { 00402 // Parse out the tolerance 00403 npos++; 00404 if ((npos < argc) && (!check_for_flag(argv[npos]))) 00405 epsilon = atof(argv[npos++]); 00406 else { 00407 std::cerr << " ERROR - missing <epsilon>" << std::endl; 00408 return MB_FAILURE; 00409 } 00410 } 00411 else if (argv[npos] == std::string("-gnorm")) { 00412 // Parse out the global normalization tag 00413 npos++; 00414 if ((npos < argc) && (!check_for_flag(argv[npos]))) 00415 gNormTag = argv[npos++]; 00416 else { 00417 std::cerr << " ERROR - missing <gnorm_tag>" << std::endl; 00418 return MB_FAILURE; 00419 } 00420 } 00421 else if (argv[npos] == std::string("-ssnorm")) { 00422 // Parse out the subset normalization tag and selection criteria 00423 npos++; 00424 if ((npos < argc) && (!check_for_flag(argv[npos]))) 00425 ssNormTag = argv[npos++]; 00426 else { 00427 std::cerr << " ERROR - missing <ssnorm_tag>" << std::endl; 00428 return MB_FAILURE; 00429 } 00430 00431 if ((npos < argc) && (!check_for_flag(argv[npos]))) { 00432 char* opts = argv[npos++]; 00433 char sep1[1] = {';'}; 00434 char sep2[1] = {'='}; 00435 bool end_vals_seen = false; 00436 std::vector<char *> tmpTagOpts; 00437 00438 // first get the options 00439 for (char* i = strtok(opts, sep1); i; i = strtok(0, sep1)) { 00440 tmpTagOpts.push_back(i); 00441 } 00442 00443 // parse out the name and val or just name. 00444 for (unsigned int j = 0; j < tmpTagOpts.size(); j++) { 00445 char* e = strtok(tmpTagOpts[j], sep2); 00446 ssTagNames.push_back(e); 00447 e = strtok(0, sep2); 00448 if (e != NULL) { 00449 // We have a value 00450 if (end_vals_seen) { 00451 // ERROR we should not have a value after none are seen 00452 std::cerr << " ERROR - new value seen after end of values in <ssnorm_selection>" << std::endl; 00453 return MB_FAILURE; 00454 } 00455 // Otherwise get the value string from e and convert it to an int 00456 int *valp = new int; 00457 *valp = atoi(e); 00458 ssTagValues.push_back((const char *) valp); 00459 } 00460 else { 00461 // Otherwise there is no '=' so push a null on the list 00462 end_vals_seen = true; 00463 ssTagValues.push_back((const char *) 0); 00464 } 00465 } 00466 } 00467 else { 00468 std::cerr << " ERROR - missing <ssnorm_selection>" << std::endl; 00469 return MB_FAILURE; 00470 } 00471 } 00472 else if (argv[npos] == std::string("-ropts")) { 00473 // Parse out the mesh file read options 00474 npos++; 00475 if ((npos < argc) && (!check_for_flag(argv[npos]))) 00476 readOpts = argv[npos++]; 00477 else { 00478 std::cerr << " ERROR - missing <roptions>" << std::endl; 00479 return MB_FAILURE; 00480 } 00481 } 00482 else if (argv[npos] == std::string("-outfile")) { 00483 // Parse out the output file name 00484 npos++; 00485 if ((npos < argc) && (!check_for_flag(argv[npos]))) 00486 outFile = argv[npos++]; 00487 else { 00488 std::cerr << " ERROR - missing <out_file>" << std::endl; 00489 return MB_FAILURE; 00490 } 00491 } 00492 else if (argv[npos] == std::string("-wopts")) { 00493 // Parse out the output file write options 00494 npos++; 00495 if ((npos < argc) && (!check_for_flag(argv[npos]))) 00496 writeOpts = argv[npos++]; 00497 else { 00498 std::cerr << " ERROR - missing <woptions>" << std::endl; 00499 return MB_FAILURE; 00500 } 00501 } 00502 else if (argv[npos] == std::string("-dbgout")) { 00503 // Parse out the debug output file name. 00504 // If no name then use the default. 00505 npos++; 00506 if ((npos < argc) && (!check_for_flag(argv[npos]))) 00507 dbgFile = argv[npos++]; 00508 else 00509 dbgFile = defaultDbgFile; 00510 } 00511 else { 00512 // Unrecognized parameter. Skip it and move along. 00513 std::cerr << " ERROR - Unrecognized parameter:" << argv[npos] << std::endl; 00514 std::cerr << " Skipping..." << std::endl; 00515 npos++; 00516 } 00517 } 00518 00519 if (!haveMeshes) { 00520 meshFiles.resize(2); 00521 meshFiles[0] = std::string(TestDir + "/64bricks_1khex.h5m"); 00522 meshFiles[1] = std::string(TestDir + "/64bricks_12ktet.h5m"); 00523 std::cout << "Mesh files not entered; using default files " 00524 << meshFiles[0] << " and " << meshFiles[1] << std::endl; 00525 } 00526 00527 if (!haveInterpTag) { 00528 interpTag = "vertex_field"; 00529 std::cout << "Interpolation field name not given, using default of " << interpTag << std::endl; 00530 } 00531 00532 #ifdef HDF5_FILE 00533 if (1 == argc) { 00534 std::cout << "No arguments given; using output file dum.h5m." << std::endl; 00535 outFile = "dum.h5m"; 00536 } 00537 #endif 00538 00539 return MB_SUCCESS; 00540 } 00541 00542 00543 // End new get_file_options() 00544 00545 00546 ErrorCode test_interpolation(Interface *mbImpl, 00547 DataCoupler::Method method, 00548 std::string &interpTag, 00549 std::string &/*gNormTag*/, 00550 std::string &/*ssNormTag*/, 00551 std::vector<const char *> &/*ssTagNames*/, 00552 std::vector<const char *> &/*ssTagValues*/, 00553 iBase_EntitySetHandle */*roots*/, 00554 std::vector<ParallelComm *> &pcs, 00555 double &instant_time, 00556 double &pointloc_time, 00557 double &interp_time, 00558 double &/*gnorm_time*/, 00559 double &/*ssnorm_time*/, 00560 double & toler) 00561 { 00562 assert(method >= DataCoupler::CONSTANT && method <= DataCoupler::SPECTRAL); 00563 00564 // source is 1st mesh, target is 2nd 00565 Range src_elems, targ_elems, targ_verts; 00566 ErrorCode result = pcs[0]->get_part_entities(src_elems, 3); 00567 PRINT_LAST_ERROR; 00568 00569 CpuTimer timer; 00570 00571 // instantiate a coupler, which also initializes the tree 00572 DataCoupler dc(mbImpl, src_elems, 0, pcs[0]); 00573 00574 // initialize spectral elements, if they exist 00575 // bool specSou=false, specTar = false; 00576 // result = mbc.initialize_spectral_elements((EntityHandle)roots[0], (EntityHandle)roots[1], specSou, specTar); 00577 00578 instant_time = timer.time_since_birth(); 00579 00580 // get points from the target mesh to interpolate 00581 // we have to treat differently the case when the target is a spectral mesh 00582 // in that case, the points of interest are the GL points, not the vertex nodes 00583 std::vector<double> vpos; // this will have the positions we are interested in 00584 int numPointsOfInterest = 0; 00585 #ifdef USE_MPI 00586 result = pcs[1]->get_part_entities(targ_elems, 3); 00587 #else 00588 result = mbImpl->get_entities_by_dimension((EntityHandle)roots[1], 3); 00589 #endif 00590 PRINT_LAST_ERROR; 00591 00592 // first get all vertices adj to partition entities in target mesh 00593 if (DataCoupler::CONSTANT == method) 00594 targ_verts = targ_elems; 00595 else 00596 result = mbImpl->get_adjacencies(targ_elems, 0, false, targ_verts, 00597 Interface::UNION); 00598 PRINT_LAST_ERROR; 00599 00600 #ifdef USE_MPI 00601 // then get non-owned verts and subtract 00602 Range tmp_verts; 00603 result = pcs[1]->get_pstatus_entities(0, PSTATUS_NOT_OWNED, tmp_verts); 00604 PRINT_LAST_ERROR; 00605 targ_verts = subtract( targ_verts, tmp_verts); 00606 #endif 00607 // get position of these entities; these are the target points 00608 numPointsOfInterest = (int)targ_verts.size(); 00609 vpos.resize(3*targ_verts.size()); 00610 result = mbImpl->get_coords(targ_verts, &vpos[0]); 00611 PRINT_LAST_ERROR; 00612 00613 // locate those points in the source mesh 00614 #ifdef USE_MPI 00615 std::cout << "rank "<< pcs[0]->proc_config().proc_rank(); 00616 #endif 00617 std::cout << " points of interest: " << numPointsOfInterest << "\n"; 00618 result = dc.locate_points(&vpos[0], numPointsOfInterest, toler); 00619 PRINT_LAST_ERROR; 00620 00621 pointloc_time = timer.time_elapsed(); 00622 00623 // now interpolate tag onto target points 00624 std::vector<double> field(numPointsOfInterest); 00625 00626 result = dc.interpolate(method, interpTag, &field[0]); 00627 PRINT_LAST_ERROR; 00628 00629 interp_time = timer.time_elapsed(); 00630 00631 /* 00632 // do global normalization if specified 00633 if (!gNormTag.empty()) { 00634 int err; 00635 00636 // Normalize the source mesh 00637 err = dc.normalize_mesh(roots[0], gNormTag.c_str(), DataCoupler::VOLUME, 4); 00638 PRINT_LAST_ERR; 00639 00640 // Normalize the target mesh 00641 err = dc.normalize_mesh(roots[1], gNormTag.c_str(), DataCoupler::VOLUME, 4); 00642 PRINT_LAST_ERR; 00643 } 00644 00645 gnorm_time = timer.time_elapsed(); 00646 00647 // do subset normalization if specified 00648 00649 if (!ssNormTag.empty()) { 00650 int err; 00651 00652 err = dc.normalize_subset(roots[0], 00653 ssNormTag.c_str(), 00654 &ssTagNames[0], 00655 ssTagNames.size(), 00656 &ssTagValues[0], 00657 DataCoupler::VOLUME, 00658 4); 00659 PRINT_LAST_ERR; 00660 00661 err = dc.normalize_subset(roots[1], 00662 ssNormTag.c_str(), 00663 &ssTagNames[0], 00664 ssTagNames.size(), 00665 &ssTagValues[0], 00666 DataCoupler::VOLUME, 00667 4); 00668 PRINT_LAST_ERR; 00669 } 00670 00671 ssnorm_time = timer.time_elapsed(); 00672 */ 00673 // set field values as tag on target vertices 00674 // use original tag 00675 Tag tag; 00676 result = mbImpl->tag_get_handle(interpTag.c_str(), 1, MB_TYPE_DOUBLE, tag); PRINT_LAST_ERROR; 00677 result = mbImpl->tag_set_data(tag, targ_verts, &field[0]); 00678 PRINT_LAST_ERROR; 00679 00680 // done 00681 return MB_SUCCESS; 00682 }