MOAB: Mesh Oriented datABase
(version 5.4.1)
|
#include "moab/MOABConfig.h"
#include "moab/iMOAB.h"
#include "TestUtil.hpp"
#include "moab/CpuTimer.hpp"
#include "moab/ProgOptions.hpp"
#include <iostream>
#include <iomanip>
Go to the source code of this file.
Defines | |
#define | CHECKIERR(ierr, message) |
#define | ENABLE_ATMLND_COUPLING |
Functions | |
int | main (int argc, char *argv[]) |
if( 0 != ( ierr ) ) \ { \ printf( "%s", message ); \ return 1; \ }
Definition at line 15 of file imoab_remap.cpp.
Referenced by main().
#define ENABLE_ATMLND_COUPLING |
Definition at line 22 of file imoab_remap.cpp.
int main | ( | int | argc, |
char * | argv[] | ||
) |
Definition at line 24 of file imoab_remap.cpp.
References ProgOptions::addOpt(), atmFilename, CHECKIERR, DENSE_DOUBLE, DENSE_INTEGER, ErrCode, ierr, iMOAB_AppID, iMOAB_DefineTagStorage(), iMOAB_DeregisterApplication(), iMOAB_Finalize(), iMOAB_GetDoubleTagStorage(), iMOAB_GetIntTagStorage(), iMOAB_GetMeshInfo(), iMOAB_Initialize(), iMOAB_LoadMesh(), iMOAB_RegisterApplication(), iMOAB_WriteMesh(), MPI_COMM_WORLD, and ProgOptions::parseCommandLine().
{ ErrCode ierr; std::string atmFilename, ocnFilename, lndFilename, mapFilename; atmFilename = TestDir + "unittest/wholeATM_T.h5m"; ocnFilename = TestDir + "unittest/recMeshOcn.h5m"; #ifdef ENABLE_ATMLND_COUPLING lndFilename = TestDir + "unittest/wholeLnd.h5m"; #endif // mapFilename = TestDir + "unittest/outCS5ICOD5_map.nc"; ProgOptions opts; opts.addOpt< std::string >( "atmosphere,t", "atm mesh filename (source)", &atmFilename ); opts.addOpt< std::string >( "ocean,m", "ocean mesh filename (target)", &ocnFilename ); #ifdef ENABLE_ATMLND_COUPLING opts.addOpt< std::string >( "land,l", "land mesh filename (target)", &lndFilename ); #endif bool gen_baseline = false; opts.addOpt< void >( "genbase,g", "generate baseline 1", &gen_baseline ); bool no_test_against_baseline = false; opts.addOpt< void >( "no_testbase,t", "do not test against baseline 1", &no_test_against_baseline ); std::string baseline = TestDir + "unittest/baseline1.txt"; opts.parseCommandLine( argc, argv ); { std::cout << " atm file: " << atmFilename << "\n ocn file: " << ocnFilename #ifdef ENABLE_ATMLND_COUPLING << "\n lnd file: " << lndFilename #endif << "\n"; } #ifdef MOAB_HAVE_MPI MPI_Init( &argc, &argv ); MPI_Comm comm = MPI_COMM_WORLD; #endif /* * MOAB needs to be initialized; A MOAB instance will be created, and will be used by each * application in this framework. There is no parallel context yet. */ ierr = iMOAB_Initialize( argc, argv ); CHECKIERR( ierr, "failed to initialize MOAB" ); int atmAppID, ocnAppID, lndAppID, atmocnAppID, atmlndAppID, lndatmAppID; iMOAB_AppID atmPID = &atmAppID; iMOAB_AppID ocnPID = &ocnAppID; iMOAB_AppID lndPID = &lndAppID; iMOAB_AppID atmocnPID = &atmocnAppID; iMOAB_AppID atmlndPID = &atmlndAppID; iMOAB_AppID lndatmPID = &lndatmAppID; /* * Each application has to be registered once. A mesh set and a parallel communicator will be * associated with each application. A unique application id will be returned, and will be used * for all future mesh operations/queries. */ int atmCompID = 10, ocnCompID = 20, lndCompID = 30, atmocnCompID = 100, atmlndCompID = 102, lndatmCompID = 103; ierr = iMOAB_RegisterApplication( "ATM-APP", #ifdef MOAB_HAVE_MPI &comm, #endif &atmCompID, atmPID ); CHECKIERR( ierr, "failed to register application1" ); ierr = iMOAB_RegisterApplication( "OCN-APP", #ifdef MOAB_HAVE_MPI &comm, #endif &ocnCompID, ocnPID ); CHECKIERR( ierr, "failed to register application2" ); #ifdef ENABLE_ATMLND_COUPLING ierr = iMOAB_RegisterApplication( "LND-APP", #ifdef MOAB_HAVE_MPI &comm, #endif &lndCompID, lndPID ); CHECKIERR( ierr, "failed to register application3" ); #endif ierr = iMOAB_RegisterApplication( "ATM-OCN-CPL", #ifdef MOAB_HAVE_MPI &comm, #endif &atmocnCompID, atmocnPID ); CHECKIERR( ierr, "failed to register application4" ); #ifdef ENABLE_ATMLND_COUPLING ierr = iMOAB_RegisterApplication( "ATM-LND-CPL", #ifdef MOAB_HAVE_MPI &comm, #endif &atmlndCompID, atmlndPID ); CHECKIERR( ierr, "failed to register application5" ); ierr = iMOAB_RegisterApplication( "LND-ATM-CPL", #ifdef MOAB_HAVE_MPI &comm, #endif &lndatmCompID, lndatmPID ); CHECKIERR( ierr, "failed to register application5" ); #endif const char* read_opts = ""; int num_ghost_layers = 0; /* * Loading the mesh is a parallel IO operation. Ghost layers can be exchanged too, and default * MOAB sets are augmented with ghost elements. By convention, blocks correspond to MATERIAL_SET * sets, side sets with NEUMANN_SET sets, node sets with DIRICHLET_SET sets. Each element and * vertex entity should have a GLOBAL ID tag in the file, which will be available for visible * entities */ ierr = iMOAB_LoadMesh( atmPID, atmFilename.c_str(), read_opts, &num_ghost_layers ); CHECKIERR( ierr, "failed to load mesh" ); ierr = iMOAB_LoadMesh( ocnPID, ocnFilename.c_str(), read_opts, &num_ghost_layers ); CHECKIERR( ierr, "failed to load mesh" ); #ifdef ENABLE_ATMLND_COUPLING ierr = iMOAB_LoadMesh( lndPID, lndFilename.c_str(), read_opts, &num_ghost_layers ); CHECKIERR( ierr, "failed to load mesh" ); #endif int nverts[3], nelem[3]; /* * Each process in the communicator will have access to a local mesh instance, which will * contain the original cells in the local partition and ghost entities. Number of vertices, * primary cells, visible blocks, number of sidesets and nodesets boundary conditions will be * returned in size 3 arrays, for local, ghost and total numbers. */ ierr = iMOAB_GetMeshInfo( atmPID, nverts, nelem, 0, 0, 0 ); CHECKIERR( ierr, "failed to get mesh info" ); printf( "Atmosphere Component Mesh: %d vertices and %d elements\n", nverts[0], nelem[0] ); ierr = iMOAB_GetMeshInfo( ocnPID, nverts, nelem, 0, 0, 0 ); CHECKIERR( ierr, "failed to get mesh info" ); printf( "Ocean Component Mesh: %d vertices and %d elements\n", nverts[0], nelem[0] ); #ifdef ENABLE_ATMLND_COUPLING ierr = iMOAB_GetMeshInfo( lndPID, nverts, nelem, 0, 0, 0 ); CHECKIERR( ierr, "failed to get mesh info" ); printf( "Land Component Mesh: %d vertices and %d elements\n", nverts[0], nelem[0] ); #endif /* * The 2 tags used in this example exist in the file, already. * If a user needs a new tag, it can be defined with the same call as this one * this method, iMOAB_DefineTagStorage, will return a local index for the tag. * The name of the tag is case sensitive. * This method is collective. */ // int disc_orders[2] = {1, 1}; // const char* disc_methods[2] = {"fv", "fv"}; // const char* dof_tag_names[2] = {"GLOBAL_ID", "GLOBAL_ID"}; int disc_orders[3] = { 4, 1, 1 }; int fMonotoneTypeID = 0, fVolumetric = 0, fValidate = 1, fNoConserve = 0, fNoBubble = 1, fInverseDistanceMap = 0; const std::string disc_methods[3] = { "cgll", "fv", "pcloud" }; const std::string dof_tag_names[3] = { "GLOBAL_DOFS", "GLOBAL_ID", "GLOBAL_ID" }; const std::string weights_identifiers[3] = { "scalar", "scalar_pointcloud", "scalar_conservative" }; const std::string bottomTempField = "a2oTbot"; const std::string bottomTempFieldATM = "a2oTbotATM"; const std::string bottomTempProjectedField = "a2oTbot_proj"; const std::string bottomTempProjectedNCField = "a2oTbot_projnocons"; // Attributes for tag data storage int tagIndex[4]; // int entTypes[2] = {1, 1}; /* both on elements; */ int tagTypes[2] = { DENSE_DOUBLE, DENSE_DOUBLE }; int atmCompNDoFs = disc_orders[0] * disc_orders[0], ocnCompNDoFs = 1 /*FV*/; ierr = iMOAB_DefineTagStorage( atmPID, bottomTempField.c_str(), &tagTypes[0], &atmCompNDoFs, &tagIndex[0] ); CHECKIERR( ierr, "failed to define the field tag on ATM" ); ierr = iMOAB_DefineTagStorage( atmPID, bottomTempFieldATM.c_str(), &tagTypes[0], &atmCompNDoFs, &tagIndex[0] ); CHECKIERR( ierr, "failed to define the field tag on ATM" ); ierr = iMOAB_DefineTagStorage( ocnPID, bottomTempProjectedField.c_str(), &tagTypes[1], &ocnCompNDoFs, &tagIndex[1] ); CHECKIERR( ierr, "failed to define the field tag on OCN" ); ierr = iMOAB_DefineTagStorage( ocnPID, bottomTempProjectedNCField.c_str(), &tagTypes[1], &ocnCompNDoFs, &tagIndex[2] ); CHECKIERR( ierr, "failed to define the field tag on OCN" ); #ifdef ENABLE_ATMLND_COUPLING ierr = iMOAB_DefineTagStorage( lndPID, bottomTempProjectedField.c_str(), &tagTypes[1], &ocnCompNDoFs, &tagIndex[3] ); CHECKIERR( ierr, "failed to define the field tag on LND" ); #endif /* Next compute the mesh intersection on the sphere between the source (ATM) and target (OCN) * meshes */ ierr = iMOAB_ComputeMeshIntersectionOnSphere( atmPID, ocnPID, atmocnPID ); CHECKIERR( ierr, "failed to compute mesh intersection between ATM and OCN" ); #ifdef ENABLE_ATMLND_COUPLING /* Next compute the mesh intersection on the sphere between the source (ATM) and target (LND) * meshes */ ierr = iMOAB_ComputePointDoFIntersection( atmPID, lndPID, atmlndPID ); CHECKIERR( ierr, "failed to compute point-cloud mapping ATM-LND" ); /* Next compute the mesh intersection on the sphere between the source (LND) and target (ATM) * meshes */ ierr = iMOAB_ComputePointDoFIntersection( lndPID, atmPID, lndatmPID ); CHECKIERR( ierr, "failed to compute point-cloud mapping LND-ATM" ); #endif /* We have the mesh intersection now. Let us compute the remapping weights */ fNoConserve = 0; /* Compute the weights to preoject the solution from ATM component to OCN compoenent */ ierr = iMOAB_ComputeScalarProjectionWeights( atmocnPID, weights_identifiers[0].c_str(), disc_methods[0].c_str(), &disc_orders[0], disc_methods[1].c_str(), &disc_orders[1], &fNoBubble, &fMonotoneTypeID, &fVolumetric, &fInverseDistanceMap, &fNoConserve, &fValidate, dof_tag_names[0].c_str(), dof_tag_names[1].c_str() ); CHECKIERR( ierr, "failed to compute remapping projection weights for ATM-OCN scalar " "non-conservative field" ); // Let us now write the map file to disk and then read it back to test the I/O API in iMOAB #ifdef MOAB_HAVE_NETCDF { const std::string atmocn_map_file_name = "atm_ocn_map.nc"; ierr = iMOAB_WriteMappingWeightsToFile( atmocnPID, weights_identifiers[0].c_str(), atmocn_map_file_name.c_str() ); CHECKIERR( ierr, "failed to write map file to disk" ); const std::string intx_from_file_identifier = "map-from-file"; // use old reader, coupler PID is -1 int dummyCpl = -1; int dummy_rowcol = -1; int dummyType = 0; ierr = iMOAB_LoadMappingWeightsFromFile( atmocnPID, &dummyCpl, &dummy_rowcol, &dummyType, intx_from_file_identifier.c_str(), atmocn_map_file_name.c_str() ); CHECKIERR( ierr, "failed to load map file from disk" ); } #endif #ifdef ENABLE_ATMLND_COUPLING fValidate = 0; /* Compute the weights to preoject the solution from ATM component to LND compoenent */ ierr = iMOAB_ComputeScalarProjectionWeights( atmlndPID, weights_identifiers[1].c_str(), disc_methods[0].c_str(), &disc_orders[0], disc_methods[2].c_str(), &disc_orders[2], &fNoBubble, &fMonotoneTypeID, &fVolumetric, &fInverseDistanceMap, &fNoConserve, &fValidate, dof_tag_names[0].c_str(), dof_tag_names[2].c_str() ); CHECKIERR( ierr, "failed to compute remapping projection weights for ATM-LND scalar " "non-conservative field" ); /* Compute the weights to preoject the solution from ATM component to LND compoenent */ ierr = iMOAB_ComputeScalarProjectionWeights( lndatmPID, weights_identifiers[1].c_str(), disc_methods[2].c_str(), &disc_orders[2], disc_methods[0].c_str(), &disc_orders[0], &fNoBubble, &fMonotoneTypeID, &fVolumetric, &fInverseDistanceMap, &fNoConserve, &fValidate, dof_tag_names[2].c_str(), dof_tag_names[0].c_str() ); CHECKIERR( ierr, "failed to compute remapping projection weights for LND-ATM scalar " "non-conservative field" ); #endif /* We have the mesh intersection now. Let us compute the remapping weights */ fNoConserve = 0; ierr = iMOAB_ComputeScalarProjectionWeights( atmocnPID, weights_identifiers[2].c_str(), disc_methods[0].c_str(), &disc_orders[0], disc_methods[1].c_str(), &disc_orders[1], &fNoBubble, &fMonotoneTypeID, &fVolumetric, &fInverseDistanceMap, &fNoConserve, &fValidate, dof_tag_names[0].c_str(), dof_tag_names[1].c_str() ); CHECKIERR( ierr, "failed to compute remapping projection weights for scalar conservative field" ); /* We have the remapping weights now. Let us apply the weights onto the tag we defined on the srouce mesh and get the projection on the target mesh */ ierr = iMOAB_ApplyScalarProjectionWeights( atmocnPID, weights_identifiers[0].c_str(), bottomTempField.c_str(), bottomTempProjectedNCField.c_str() ); CHECKIERR( ierr, "failed to apply projection weights for scalar non-conservative field" ); /* We have the remapping weights now. Let us apply the weights onto the tag we defined on the srouce mesh and get the projection on the target mesh */ ierr = iMOAB_ApplyScalarProjectionWeights( atmocnPID, weights_identifiers[2].c_str(), bottomTempField.c_str(), bottomTempProjectedField.c_str() ); CHECKIERR( ierr, "failed to apply projection weights for scalar conservative field" ); if( gen_baseline ) { // get temp field on ocean, from conservative, the global ids, and dump to the baseline file // first get GlobalIds from ocn, and fields: ierr = iMOAB_GetMeshInfo( ocnPID, nverts, nelem, 0, 0, 0 ); CHECKIERR( ierr, "failed to get ocn mesh info" ); std::vector< int > gidElems; gidElems.resize( nelem[2] ); std::vector< double > tempElems; tempElems.resize( nelem[2] ); // get global id storage const std::string GidStr = "GLOBAL_ID"; // hard coded too int tag_type = DENSE_INTEGER, ncomp = 1, tagInd = 0; // we should not have to define global id tag, it is always defined ierr = iMOAB_DefineTagStorage( ocnPID, GidStr.c_str(), &tag_type, &ncomp, &tagInd ); CHECKIERR( ierr, "failed to define global id tag" ); int ent_type = 1; ierr = iMOAB_GetIntTagStorage( ocnPID, GidStr.c_str(), &nelem[2], &ent_type, &gidElems[0] ); CHECKIERR( ierr, "failed to get global ids" ); ierr = iMOAB_GetDoubleTagStorage( ocnPID, bottomTempProjectedField.c_str(), &nelem[2], &ent_type, &tempElems[0] ); CHECKIERR( ierr, "failed to get temperature field" ); std::fstream fs; fs.open( baseline.c_str(), std::fstream::out ); fs << std::setprecision( 15 ); // maximum precision for doubles for( int i = 0; i < nelem[2]; i++ ) fs << gidElems[i] << " " << tempElems[i] << "\n"; fs.close(); } if( !no_test_against_baseline ) { // get temp field on ocean, from conservative, the global ids, and dump to the baseline file // first get GlobalIds from ocn, and fields: ierr = iMOAB_GetMeshInfo( ocnPID, nverts, nelem, 0, 0, 0 ); CHECKIERR( ierr, "failed to get ocn mesh info" ); std::vector< int > gidElems; gidElems.resize( nelem[2] ); std::vector< double > tempElems; tempElems.resize( nelem[2] ); // get global id storage const std::string GidStr = "GLOBAL_ID"; // hard coded too int tag_type = DENSE_INTEGER, ncomp = 1, tagInd = 0; ierr = iMOAB_DefineTagStorage( ocnPID, GidStr.c_str(), &tag_type, &ncomp, &tagInd ); CHECKIERR( ierr, "failed to define global id tag" ); int ent_type = 1; ierr = iMOAB_GetIntTagStorage( ocnPID, GidStr.c_str(), &nelem[2], &ent_type, &gidElems[0] ); CHECKIERR( ierr, "failed to get global ids" ); ierr = iMOAB_GetDoubleTagStorage( ocnPID, bottomTempProjectedField.c_str(), &nelem[2], &ent_type, &tempElems[0] ); CHECKIERR( ierr, "failed to get temperature field" ); int err_code = 1; check_baseline_file( baseline, gidElems, tempElems, 1.e-9, err_code ); if( 0 == err_code ) std::cout << " passed baseline test 1\n"; } #ifdef ENABLE_ATMLND_COUPLING /* We have the remapping weights now. Let us apply the weights onto the tag we defined on the srouce mesh and get the projection on the target mesh */ ierr = iMOAB_ApplyScalarProjectionWeights( atmlndPID, weights_identifiers[1].c_str(), bottomTempField.c_str(), bottomTempProjectedField.c_str() ); CHECKIERR( ierr, "failed to apply projection weights for ATM-LND scalar field" ); /* We have the remapping weights now. Let us apply the weights onto the tag we defined on the srouce mesh and get the projection on the target mesh */ ierr = iMOAB_ApplyScalarProjectionWeights( lndatmPID, weights_identifiers[1].c_str(), bottomTempProjectedField.c_str(), bottomTempFieldATM.c_str() ); CHECKIERR( ierr, "failed to apply projection weights for LND-ATM scalar field" ); #endif /* * the file can be written in parallel, and it will contain additional tags defined by the user * we may extend the method to write only desired tags to the file */ { // free allocated data #ifdef ENABLE_ATMLND_COUPLING char outputFileAtmTgt[] = "fIntxAtmTarget.h5m"; #endif char outputFileOcnTgt[] = "fIntxOcnTarget.h5m"; #ifdef ENABLE_ATMLND_COUPLING char outputFileLndTgt[] = "fIntxLndTarget.h5m"; #endif char writeOptions[] = ""; // Write out all the component meshes to disk for verification ierr = iMOAB_WriteMesh( ocnPID, outputFileOcnTgt, writeOptions ); CHECKIERR( ierr, "failed to write OCN mesh and data" ); #ifdef ENABLE_ATMLND_COUPLING ierr = iMOAB_WriteMesh( lndPID, outputFileLndTgt, writeOptions ); CHECKIERR( ierr, "failed to write LND mesh and data" ); ierr = iMOAB_WriteMesh( atmPID, outputFileAtmTgt, writeOptions ); CHECKIERR( ierr, "failed to write ATM mesh and data" ); #endif } /* * deregistering application will delete all mesh entities associated with the application and * will free allocated tag storage. */ #ifdef ENABLE_ATMLND_COUPLING ierr = iMOAB_DeregisterApplication( lndPID ); CHECKIERR( ierr, "failed to de-register application3" ); #endif ierr = iMOAB_DeregisterApplication( ocnPID ); CHECKIERR( ierr, "failed to de-register application2" ); ierr = iMOAB_DeregisterApplication( atmPID ); CHECKIERR( ierr, "failed to de-register application1" ); /* * this method will delete MOAB instance */ ierr = iMOAB_Finalize(); CHECKIERR( ierr, "failed to finalize MOAB" ); #ifdef MOAB_HAVE_MPI MPI_Finalize(); #endif return 0; }