Mesh Oriented datABase  (version 5.6.0)
An array-based unstructured mesh library
Application Management

Functions for registering and managing application instances. More...

+ Collaboration diagram for Application Management:

Functions

ErrCode iMOAB_RegisterApplication (const iMOAB_String app_name, MPI_Comm *comm, int *compid, iMOAB_AppID pid)
 Register a new application instance with iMOAB. More...
 
ErrCode iMOAB_RegisterApplicationFortran (const iMOAB_String app_name, int *comm, int *compid, iMOAB_AppID pid)
 Fortran-compatible wrapper for iMOAB_RegisterApplication. More...
 
ErrCode iMOAB_DeregisterApplication (iMOAB_AppID pid)
 Deregister an application instance and cleanup associated resources. More...
 
ErrCode iMOAB_DeregisterApplicationFortran (iMOAB_AppID pid)
 Fortran-compatible wrapper for iMOAB_DeregisterApplication. More...
 

Detailed Description

Functions for registering and managing application instances.

Function Documentation

◆ iMOAB_DeregisterApplication()

ErrCode iMOAB_DeregisterApplication ( iMOAB_AppID  pid)

Deregister an application instance and cleanup associated resources.

De-Register application: delete mesh (set) associated with the application ID.

Removes application from iMOAB, deletes mesh entities, frees parallel communicator, and cleans up all associated data structures. Must be called before iMOAB_Finalize().

Cleanup Process:
  1. Validate application ID exists
  2. Delete all mesh entities in application's file set
  3. Delete communication graphs (ParCommGraph instances)
  4. Delete parallel communicator if MPI enabled
  5. Delete TempestRemap objects if present
  6. Delete application's mesh set
  7. Remove application from global context maps
Parameters
[in]pidApplication ID to deregister
Precondition
Application must have been registered via iMOAB_RegisterApplication
Postcondition
All mesh data deleted
Parallel communicator deleted
Application ID invalid and cannot be reused
Warning
Do not access application ID after deregistration
Note
Safe to deregister in any order relative to other applications
Returns
moab::MB_SUCCESS on success, moab::MB_FAILURE if application not found
See also
iMOAB_RegisterApplication()

Definition at line 559 of file iMOAB.cpp.

560 {
561  // Look up application in global context
562  auto appIterator = context.appDatas.find( *pid );
563 
564  // Validate application exists before attempting deletion
565  if( appIterator == context.appDatas.end() ) return MB_FAILURE;
566 
567  // we found the application
568  appData& data = appIterator->second;
569  int rankHere = 0;
570 #ifdef MOAB_HAVE_MPI
571  rankHere = data.pcomm->rank();
572 #endif
573  if( !rankHere )
574  std::cout << " application with ID: " << *pid << " global id: " << data.global_id << " name: " << data.name
575  << " is de-registered now \n";
576 
577  EntityHandle fileSet = data.file_set;
578  // get all entities part of the file set
579  Range fileents;
580  MB_CHK_SET_ERR( context.MBI->get_entities_by_handle( fileSet, fileents, /*recursive */ true ),
581  "can't get file entities" );
582  fileents.insert( fileSet );
584  "can't get file entities" ); // append all mesh sets
585 
586 #ifdef MOAB_HAVE_TEMPESTREMAP
587  if( data.tempestData.remapper ) delete data.tempestData.remapper;
588  if( data.tempestData.weightMaps.size() ) data.tempestData.weightMaps.clear();
589 #endif
590 
591 #ifdef MOAB_HAVE_MPI
592  // NOTE: we could get the pco also with the following workflow.
593  // ParallelComm * pcomm = ParallelComm::get_pcomm(context.MBI, *pid);
594 
595  auto& pargs = data.pgraph;
596  // free the parallel comm graphs associated with this app
597  for( auto mt = pargs.begin(); mt != pargs.end(); ++mt )
598  {
599  ParCommGraph* pgr = mt->second;
600  if( pgr != nullptr )
601  {
602  delete pgr;
603  pgr = nullptr;
604  }
605  }
606  // now free the ParallelComm resources
607  if( data.pcomm )
608  {
609  delete data.pcomm;
610  data.pcomm = nullptr;
611  }
612 #endif
613 
614  // delete first all except vertices
615  Range vertices = fileents.subset_by_type( MBVERTEX );
616  Range noverts = subtract( fileents, vertices );
617 
618  MB_CHK_SET_ERR( context.MBI->delete_entities( noverts ), "can't delete entities" );
619  // now retrieve connected elements that still exist (maybe in other sets, pids?)
620  Range adj_ents_left;
621  MB_CHK_SET_ERR( context.MBI->get_adjacencies( vertices, 1, false, adj_ents_left, Interface::UNION ),
622  "can't get 1D adjacencies" );
623  MB_CHK_SET_ERR( context.MBI->get_adjacencies( vertices, 2, false, adj_ents_left, Interface::UNION ),
624  "can't get 2D adjacencies" );
625  MB_CHK_SET_ERR( context.MBI->get_adjacencies( vertices, 3, false, adj_ents_left, Interface::UNION ),
626  "can't get 3D adjacencies" );
627 
628  if( !adj_ents_left.empty() )
629  {
630  Range conn_verts;
631  MB_CHK_SET_ERR( context.MBI->get_connectivity( adj_ents_left, conn_verts ), "can't get connectivity" );
632  vertices = subtract( vertices, conn_verts );
633  }
634 
635  MB_CHK_SET_ERR( context.MBI->delete_entities( vertices ), "can't delete vertices" );
636 
637  for( auto mit = context.appIdMap.begin(); mit != context.appIdMap.end(); ++mit )
638  {
639  if( *pid == mit->second )
640  {
641 #ifdef MOAB_HAVE_MPI
642  if( data.pcomm )
643  {
644  delete data.pcomm;
645  data.pcomm = nullptr;
646  }
647 #endif
648  context.appIdMap.erase( mit );
649  break;
650  }
651  }
652 
653  // now we can finally delete the application data itself
654  context.appDatas.erase( appIterator );
655 
656  return moab::MB_SUCCESS;
657 }

References GlobalContext::appDatas, GlobalContext::appIdMap, context, moab::Interface::delete_entities(), moab::Range::empty(), appData::file_set, moab::Interface::get_adjacencies(), moab::Interface::get_connectivity(), moab::Interface::get_entities_by_handle(), moab::Interface::get_entities_by_type(), appData::global_id, moab::Range::insert(), MB_CHK_SET_ERR, MB_SUCCESS, MBENTITYSET, GlobalContext::MBI, MBVERTEX, appData::name, appData::pcomm, appData::pgraph, moab::ParallelComm::rank(), moab::Range::subset_by_type(), moab::subtract(), and moab::Interface::UNION.

Referenced by iMOAB_DeregisterApplicationFortran().

◆ iMOAB_DeregisterApplicationFortran()

ErrCode iMOAB_DeregisterApplicationFortran ( iMOAB_AppID  pid)

Fortran-compatible wrapper for iMOAB_DeregisterApplication.

De-Register the Fortran based application: delete mesh (set) associated with the application ID.

Deregisters application from Fortran code by clearing Fortran flag and calling C-style deregistration.

Parameters
[in]pidApplication ID to deregister
Returns
moab::MB_SUCCESS on success, moab::MB_FAILURE if application not found
See also
iMOAB_DeregisterApplication()

Definition at line 672 of file iMOAB.cpp.

673 {
674  // Clear Fortran-specific flag before passing to C-style deregistration
675  context.appDatas[*pid].is_fortran = false;
676 
677  // Release all data structure allocations via C-style function
678  return iMOAB_DeregisterApplication( pid );
679 }

References GlobalContext::appDatas, context, and iMOAB_DeregisterApplication().

◆ iMOAB_RegisterApplication()

ErrCode iMOAB_RegisterApplication ( const iMOAB_String  app_name,
MPI_Comm *  comm,
int *  compid,
iMOAB_AppID  pid 
)

Register a new application instance with iMOAB.

Creates a new application context with unique ID, allocates a mesh set for data storage, and sets up parallel communicator if MPI is enabled. Each application represents a distinct component in a coupled simulation (e.g., atmosphere, ocean, land).

Registration Process:
  1. Validate application name is unique (not already registered)
  2. Generate unique application ID using FNV hash of name + component ID
  3. Create MOAB mesh set for storing application's mesh data
  4. Initialize application data structure (appData) with default values
  5. Create ParallelComm instance for parallel operations if MPI enabled
  6. Store application context in global map indexed by application ID
Parameters
[in]app_nameUnique name for this application instance
[in]commMPI communicator for this application (MPI builds only)
[in]compidExternal component ID (must be positive)
[out]pidGenerated application ID (output parameter)
Precondition
iMOAB_Initialize must have been called
app_name must be unique (not already registered)
compid must be positive
Postcondition
Application registered and ready for mesh loading
Application ID stored in pid
Mesh set created and stored in context.appDatas[pid]
ParallelComm created if MPI enabled
Note
Application ID is computed as hash(app_name, compid) for uniqueness
Fortran interface should use iMOAB_RegisterApplicationFortran()
Returns
moab::MB_SUCCESS on success, moab::MB_FAILURE if already registered or compid invalid
See also
iMOAB_DeregisterApplication()

Definition at line 394 of file iMOAB.cpp.

400 {
401  IMOAB_CHECKPOINTER( app_name, 1 );
402 #ifdef MOAB_HAVE_MPI
403  IMOAB_CHECKPOINTER( comm, 2 );
404  IMOAB_CHECKPOINTER( compid, 3 );
405 #else
406  IMOAB_CHECKPOINTER( compid, 2 );
407 #endif
408 
409  // will create a parallel comm for this application too, so there will be a
410  // mapping from *pid to file set and to parallel comm instances
411  std::string name( app_name );
412 
413  if( context.appIdMap.find( name ) != context.appIdMap.end() )
414  {
415  std::cout << " application " << name << " already registered \n";
416  return moab::MB_FAILURE;
417  }
418 
419  // trivial hash: just use the id that the user provided and assume it is unique
420  // *pid = *compid;
421  // hash: compute a unique hash as a combination of the appname and the component id
422  *pid = apphash( app_name, *compid );
423  // store map of application name and the ID we just generated
424  context.appIdMap[name] = *pid;
425  int rankHere = 0;
426 #ifdef MOAB_HAVE_MPI
427  MPI_Comm_rank( *comm, &rankHere );
428 #endif
429  if( !rankHere )
430  std::cout << " application " << name << " with ID = " << *pid << " and external id: " << *compid
431  << " is registered now \n";
432  if( *compid <= 0 )
433  {
434  std::cout << " convention for external application is to have its id positive \n";
435  return moab::MB_FAILURE;
436  }
437 
438  // create now the file set that will be used for loading the model in
439  EntityHandle file_set;
440  MB_CHK_SET_ERR( context.MBI->create_meshset( MESHSET_SET, file_set ), "can't create file set" );
441 
442  appData app_data;
443  app_data.file_set = file_set;
444  app_data.global_id = *compid; // will be used mostly for par comm graph
445  app_data.name = name; // save the name of application
446 
447 #ifdef MOAB_HAVE_TEMPESTREMAP
448  app_data.tempestData.remapper = nullptr; // Only allocate as needed
449  app_data.tempestData.num_src_ghost_layers = 0;
450  app_data.tempestData.num_tgt_ghost_layers = 0;
451 #endif
452 
453  // set some default values
454  app_data.num_ghost_layers = 0;
455  app_data.point_cloud = false;
456  app_data.is_fortran = false;
457 #ifdef MOAB_HAVE_TEMPESTREMAP
458  app_data.secondary_file_set = app_data.file_set;
459 #endif
460 
461 #ifdef MOAB_HAVE_MPI
462  if( *comm ) app_data.pcomm = new ParallelComm( context.MBI, *comm );
463 #endif
464  context.appDatas[*pid] = app_data; // Store application data indexed by generated ID
465  return moab::MB_SUCCESS;
466 }

References GlobalContext::appDatas, apphash(), GlobalContext::appIdMap, context, moab::Interface::create_meshset(), appData::file_set, appData::global_id, IMOAB_CHECKPOINTER, appData::is_fortran, MB_CHK_SET_ERR, MB_SUCCESS, GlobalContext::MBI, MESHSET_SET, appData::name, appData::num_ghost_layers, appData::pcomm, and appData::point_cloud.

Referenced by iMOAB_RegisterApplicationFortran().

◆ iMOAB_RegisterApplicationFortran()

ErrCode iMOAB_RegisterApplicationFortran ( const iMOAB_String  app_name,
int *  comm,
int *  compid,
iMOAB_AppID  pid 
)

Fortran-compatible wrapper for iMOAB_RegisterApplication.

Registers application from Fortran code by converting Fortran MPI communicator to C and calling C-style registration. Sets is_fortran flag to enable proper MPI handle conversions.

Parameters
[in]app_nameUnique name for this application instance
[in]commFortran MPI communicator (integer handle, MPI builds only)
[in]compidExternal component ID (must be positive)
[out]pidGenerated application ID (output parameter)
Note
Automatically converts Fortran MPI_Comm to C MPI_Comm using MPI_Comm_f2c
Sets is_fortran flag in application data for future MPI handle conversions
Returns
moab::MB_SUCCESS on success, moab::MB_FAILURE otherwise
See also
iMOAB_RegisterApplication(), MPI_Comm_f2c()

Definition at line 487 of file iMOAB.cpp.

493 {
494  IMOAB_CHECKPOINTER( app_name, 1 );
495 #ifdef MOAB_HAVE_MPI
496  IMOAB_CHECKPOINTER( comm, 2 );
497  IMOAB_CHECKPOINTER( compid, 3 );
498 #else
499  IMOAB_CHECKPOINTER( compid, 2 );
500 #endif
501 
502  ErrCode err;
503  assert( app_name != nullptr );
504  std::string name( app_name );
505 
506 #ifdef MOAB_HAVE_MPI
507  MPI_Comm ccomm;
508  if( comm )
509  {
510  // Convert from Fortran communicator (integer) to C communicator
511  // See MPI standard: http://www.mpi-forum.org/docs/mpi-2.2/mpi22-report/node361.htm
512  ccomm = MPI_Comm_f2c( (MPI_Fint)*comm );
513  }
514 #endif
515 
516  // Call C-style registration function with converted communicator
517  err = iMOAB_RegisterApplication( app_name,
518 #ifdef MOAB_HAVE_MPI
519  &ccomm,
520 #endif
521  compid, pid );
522 
523  // Mark application as Fortran-based for proper MPI handle conversions in future calls
524  context.appDatas[*pid].is_fortran = true;
525 
526  return err;
527 }

References GlobalContext::appDatas, context, ErrCode, IMOAB_CHECKPOINTER, iMOAB_RegisterApplication(), and MOAB_HAVE_MPI.