From a03c45f6f046a9d5efed94a540caa0429b6c1a79 Mon Sep 17 00:00:00 2001 From: a-jp Date: Wed, 9 Oct 2019 17:23:39 +0100 Subject: [PATCH 01/72] I think (?) this is a typo and should be pm-> not the apf mesh m-> --- test/constructThenGhost.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/constructThenGhost.cc b/test/constructThenGhost.cc index 4caafe06a..56cdb85e2 100644 --- a/test/constructThenGhost.cc +++ b/test/constructThenGhost.cc @@ -59,7 +59,7 @@ int main(int argc, char** argv) pMeshIter it = pm->begin(mdim); pMeshEnt e; double v = 0; - while ((e = m->iterate(it))) + while ((e = pm->iterate(it))) pumi_node_setField(f,e,0,&v); pm->end(it); @@ -71,7 +71,7 @@ int main(int argc, char** argv) it = pm->begin(mdim); v = 1; - while ((e = m->iterate(it))) { + while ((e = pm->iterate(it))) { if (!pumi_ment_isGhost(e)) pumi_node_setField(f,e,0,&v); } From 2fe2ed027ddd3b1d9fce595920b4788cb75acf12 Mon Sep 17 00:00:00 2001 From: a-jp Date: Wed, 9 Oct 2019 17:24:36 +0100 Subject: [PATCH 02/72] ignore vscode settings.json file --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 378eac25d..916fce7b8 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ build +settings.json \ No newline at end of file From d90f613691294ff82de325605d47a0d41cfa3b05 Mon Sep 17 00:00:00 2001 From: a-jp Date: Wed, 9 Oct 2019 17:25:55 +0100 Subject: [PATCH 03/72] cgns reading, working, but still have problems converting the apf mesh to a pumi mesh --- CMakeLists.txt | 27 ++- cmake/FindCGNS.cmake | 43 ++++ cmake/bob.cmake | 11 + mds/CMakeLists.txt | 6 + mds/apfMDS.h | 2 + mds/mdsCGNS.cc | 468 ++++++++++++++++++++++++++++++++++++++++++ mds/pkg_tribits.cmake | 1 + test/CMakeLists.txt | 3 + test/cgns.cc | 234 +++++++++++++++++++++ test/testing.cmake | 44 ++++ 10 files changed, 838 insertions(+), 1 deletion(-) create mode 100644 cmake/FindCGNS.cmake create mode 100644 mds/mdsCGNS.cc create mode 100644 test/cgns.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 207ca93f2..683995a70 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,10 @@ if(USE_XSDK_DEFAULTS) xsdk_compiler_flags() endif() +# require c++17 +option(ENABLE_CGNS "Enable the CGNS reader: requires c++17 extensions" OFF) +message(STATUS "ENABLE_CGNS: ${ENABLE_CGNS}") + # Set some default compiler flags that should always be used if(NOT USE_XSDK_DEFAULTS) bob_set_shared_libs() @@ -29,7 +33,15 @@ if(NOT USE_XSDK_DEFAULTS) bob_end_cxx_flags() set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS}") if(SCOREC_ENABLE_CXX11) - bob_cxx11_flags() + if(ENABLE_CGNS) + bob_cxx17_flags() + else() + bob_cxx11_flags() + endif() + else() + if(ENABLE_CGNS) + bob_cxx17_flags() + endif() endif() endif() message(STATUS "CMAKE_CXX_FLAGS = ${CMAKE_CXX_FLAGS}") @@ -91,6 +103,7 @@ option(ENABLE_SIMMETRIX "Build with Simmetrix support" OFF) message(STATUS "ENABLE_SIMMETRIX: ${ENABLE_SIMMETRIX}") option(ENABLE_OMEGA_H "Enable the Omega_h interface" OFF) message(STATUS "ENABLE_OMEGA_H: ${ENABLE_OMEGA_H}") + if(ENABLE_SIMMETRIX) add_definitions(-DHAVE_SIMMETRIX) endif() @@ -117,6 +130,15 @@ if(ENABLE_OMEGA_H) bob_public_dep(Omega_h) endif() +if(ENABLE_CGNS) + find_package(CGNS) + include_directories(SYSTEM ${CGNS_INCLUDE_DIR}) + # + find_package(HDF5) + # + add_definitions(-DHAVE_CGNS) +endif() + # Include the SCOREC project packages add_subdirectory(lion) add_subdirectory(pcu) @@ -142,6 +164,9 @@ add_subdirectory(omega_h) # this INTERFACE target bundles all the enabled libraries together add_library(core INTERFACE) target_link_libraries(core INTERFACE ${SCOREC_EXPORTED_TARGETS}) +if(ENABLE_CGNS) + target_link_libraries(core INTERFACE ${CGNS_LIBRARIES} ${HDF5_LIBRARIES} ${HDF5_HL_LIBRARIES}) +endif() scorec_export_library(core) if(BUILD_EXES) diff --git a/cmake/FindCGNS.cmake b/cmake/FindCGNS.cmake new file mode 100644 index 000000000..b3803b4d6 --- /dev/null +++ b/cmake/FindCGNS.cmake @@ -0,0 +1,43 @@ + + +# +# Find the native CGNS includes and library +# +# CGNS_INCLUDE_DIR - where to find cgns.h, etc. +# CGNS_LIBRARIES - List of fully qualified libraries to link against when using CGNS. +# CGNS_FOUND - Do not attempt to use CGNS if "no" or undefined. + +find_path(CGNS_INCLUDE_DIR cgnslib.h + /usr/local/include + /usr/include +) + +find_library(CGNS_LIBRARY cgns + /usr/local/lib + /usr/lib +) + +set(CGNS_FOUND "NO") +if(CGNS_INCLUDE_DIR) + if(CGNS_LIBRARY) + set( CGNS_LIBRARIES ${CGNS_LIBRARY} ) + set( CGNS_FOUND "YES" ) + endif() +endif() + +if(CGNS_FIND_REQUIRED AND NOT CGNS_FOUND) + message(SEND_ERROR "Unable to find the requested CGNS libraries.") +endif() + +# handle the QUIETLY and REQUIRED arguments and set CGNS_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(CGNS DEFAULT_MSG CGNS_LIBRARY CGNS_INCLUDE_DIR) + + +mark_as_advanced( + CGNS_INCLUDE_DIR + CGNS_LIBRARY +) + + diff --git a/cmake/bob.cmake b/cmake/bob.cmake index 90be9078b..278ed7a9a 100644 --- a/cmake/bob.cmake +++ b/cmake/bob.cmake @@ -86,6 +86,17 @@ function(bob_cxx11_flags) set(CMAKE_CXX_FLAGS "${FLAGS}" PARENT_SCOPE) endfunction(bob_cxx11_flags) +function(bob_cxx17_flags) + set(FLAGS "${CMAKE_CXX_FLAGS}") + set(FLAGS "${FLAGS} --std=c++17") + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + if (${PROJECT_NAME}_CXX_WARNINGS) + set(FLAGS "${FLAGS} -Wno-c++98-compat-pedantic -Wno-c++98-compat") + endif() + endif() + set(CMAKE_CXX_FLAGS "${FLAGS}" PARENT_SCOPE) +endfunction(bob_cxx17_flags) + function(bob_end_cxx_flags) set(${PROJECT_NAME}_CXX_FLAGS "" CACHE STRING "Override all C++ compiler flags") set(${PROJECT_NAME}_EXTRA_CXX_FLAGS "" CACHE STRING "Extra C++ compiler flags") diff --git a/mds/CMakeLists.txt b/mds/CMakeLists.txt index 785246c03..1cf883ef7 100644 --- a/mds/CMakeLists.txt +++ b/mds/CMakeLists.txt @@ -28,6 +28,7 @@ set(SOURCES apfBox.cc mdsANSYS.cc mdsGmsh.cc + mdsCGNS.cc mdsUgrid.cc ) @@ -59,6 +60,11 @@ target_link_libraries(mds apf ) +if(ENABLE_CGNS) + message(STATUS ${CGNS_LIBRARIES}) + target_link_libraries(mds PRIVATE ${CGNS_LIBRARIES} ${HDF5_LIBRARIES} ${HDF5_HL_LIBRARIES}) +endif() + scorec_export_library(mds) bob_end_subdir() diff --git a/mds/apfMDS.h b/mds/apfMDS.h index ef745e576..1dba7b496 100644 --- a/mds/apfMDS.h +++ b/mds/apfMDS.h @@ -192,6 +192,8 @@ int getMdsIndex(Mesh2* in, MeshEntity* e); so call apf::reorderMdsMesh after any mesh modification. */ MeshEntity* getMdsEntity(Mesh2* in, int dimension, int index); +Mesh2* loadMdsFromCGNS(const char* filename); + Mesh2* loadMdsFromGmsh(gmi_model* g, const char* filename); Mesh2* loadMdsFromUgrid(gmi_model* g, const char* filename); diff --git a/mds/mdsCGNS.cc b/mds/mdsCGNS.cc new file mode 100644 index 000000000..b4dc6b353 --- /dev/null +++ b/mds/mdsCGNS.cc @@ -0,0 +1,468 @@ +/* Author: Dr Andrew Parker (2019) - FGE Ltd + + Notes: these functions have been exclusively developed using meshes from Salome + +*/ + +#include "apf.h" +#include "apfMDS.h" +#include "apfMesh2.h" +#include "apfShape.h" +#include "gmi.h" /* this is for gmi_getline... */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef HAVE_CGNS +// +#include +#include +#include +#include +#include +#include +#include +// +#include +#include +// +#endif + +namespace +{ +#ifdef DEBUG +static constexpr bool debugOutput = true; +#else +static constexpr bool debugOutput = false; +#endif + +static std::string CGNSElementTypeToString(const CGNS_ENUMT(ElementType_t) & elementType) +{ + if (elementType == CGNS_ENUMV(NODE)) + return "NODE"; + else if (elementType == CGNS_ENUMV(BAR_2)) + return "BAR_2"; + else if (elementType == CGNS_ENUMV(QUAD_4)) + return "QUAD_4"; + else if (elementType == CGNS_ENUMV(TRI_3)) + return "TRI_3"; + else if (elementType == CGNS_ENUMV(HEXA_8)) + return "HEXA_8"; + else if (elementType == CGNS_ENUMV(TETRA_4)) + return "TETRA_4"; + else if (elementType == CGNS_ENUMV(PYRA_5)) + return "PYRA_5"; + else if (elementType == CGNS_ENUMV(PENTA_6)) + return "PENTA_6"; + else + { + std::cout << __LINE__ << " " + << "No known element type " + << " " << cg_ElementTypeName(elementType) << std::endl; + return ""; + } +} + +template +void DebugParallelPrinter(std::ostream &out, Arg &&arg, Args &&... args) +{ + if constexpr (debugOutput) + { + for (int i = 0; i < PCU_Comm_Peers(); i++) + { + if (i == PCU_Comm_Self()) + { + out << "Rank [" << i << "] " << std::forward(arg); + ((out << ", " << std::forward(args)), ...); + out << "\n"; + out << std::flush; + } + PCU_Barrier(); + } + } +} + +void Kill() +{ + if (PCU_Comm_Initialized()) + { + // Finalize the MPI environment. + PCU_Comm_Free(); + MPI_Finalize(); + exit(EXIT_FAILURE); + } + else + { + exit(EXIT_FAILURE); + } +} + +auto ReadCGNSCoords(int cgid, int base, int zone, int ncoords, int nverts, const std::vector &, const apf::GlobalToVert &globalToVert) +{ + // Read all + // const int lowest = 1; + // const int highest = nverts; + + // Read min required as defined by consecutive range + // make one based as ReadElements makes zero based + // const int lowest = *std::min_element(vertexIDs.begin(), vertexIDs.end()) + 1; + // const int highest = *std::max_element(vertexIDs.begin(), vertexIDs.end()) + 1; + // DebugParallelPrinter(std::cout, "From vertexIDs ", lowest, highest, nverts); + + // Read min required as defined by consecutive range + // make one based as ReadElements makes zero based + const int lowest = globalToVert.begin()->first + 1; + const int highest = globalToVert.rbegin()->first + 1; + DebugParallelPrinter(std::cout, "From globalToVert ", lowest, highest, nverts); + + cgsize_t range_min[3]; + range_min[0] = lowest; + range_min[1] = lowest; + range_min[2] = lowest; + cgsize_t range_max[3]; + range_max[0] = highest; + range_max[1] = highest; + range_max[2] = highest; + + std::vector> ordinates(3); + const auto numToRead = range_max[0] - range_min[0] + 1; + ordinates[0].resize(numToRead, 0.0); + ordinates[1].resize(numToRead, 0.0); + ordinates[2].resize(numToRead, 0.0); + + std::vector coord_names(3); + coord_names[0].resize(CGIO_MAX_NAME_LENGTH + 1, ' '); + coord_names[1].resize(CGIO_MAX_NAME_LENGTH + 1, ' '); + coord_names[2].resize(CGIO_MAX_NAME_LENGTH + 1, ' '); + + for (int d = 0; d < ncoords; d++) + { + CGNS_ENUMT(DataType_t) + datatype = CGNS_ENUMV(DataTypeNull); + + if (cg_coord_info(cgid, base, zone, d + 1, &datatype, &coord_names[d][0])) + { + std::cout << __LINE__ << " CGNS is dead " << std::endl; + Kill(); + } + const auto coord_name = std::string(coord_names[d].c_str()); + //boost::algorithm::trim(coord_name); // can't be bothered including boost + + auto &ordinate = ordinates[d]; + if (cgp_coord_read_data(cgid, base, zone, d + 1, &range_min[0], &range_max[0], + ordinate.data())) + { + std::cout << __LINE__ << " CGNS is dead " << std::endl; + Kill(); + } + } + // to be clear, indices passed back are global, zero based + std::map> points; + int counter = lowest; + for (int i = 0; i < numToRead; i++) + { + int zeroBased = counter - 1; + points.insert(std::make_pair(zeroBased, std::array{{ordinates[0][i], ordinates[1][i], ordinates[2][i]}})); + counter++; + } + + return points; +} + +void SimpleElementPartition(std::vector &numberToReadPerProc, std::vector &startingIndex, int el_start /* one based */, int el_end, int numElements) +{ + numberToReadPerProc.resize(PCU_Comm_Peers(), 0); + const cgsize_t blockSize = static_cast( + std::floor(static_cast(numElements) / + static_cast(PCU_Comm_Peers()))); + + DebugParallelPrinter(std::cout, "BlockSize", blockSize, "numElements", numElements, "comms Size", PCU_Comm_Peers()); + + cgsize_t counter = 0; + if (blockSize == 0 && numElements > 0) + numberToReadPerProc[0] = numElements; + else + { + bool keepGoing = true; + while (keepGoing) + { + for (int p = 0; p < PCU_Comm_Peers() && keepGoing; p++) + { + if (counter + blockSize <= numElements) + { + counter += blockSize; + numberToReadPerProc[p] += blockSize; + } + else + { + const auto &delta = numElements - counter; + counter += delta; + numberToReadPerProc[p] += delta; + keepGoing = false; + } + } + } + } + DebugParallelPrinter(std::cout, "Sanity check: Counter", counter, "numElements", numElements); + + DebugParallelPrinter(std::cout, "numberToReadPerProc for rank", PCU_Comm_Self(), "is:", numberToReadPerProc[PCU_Comm_Self()]); + + startingIndex.resize(PCU_Comm_Peers(), 0); + startingIndex[0] = el_start; + for (std::size_t i = 1; i < numberToReadPerProc.size(); i++) + { + if (numberToReadPerProc[i] > 0) + startingIndex[i] = startingIndex[i - 1] + numberToReadPerProc[i - 1]; + } + + DebugParallelPrinter(std::cout, "Element start, end, numElements ", el_start, + el_end, numElements); + + DebugParallelPrinter(std::cout, "startingIndex for rank", PCU_Comm_Self(), "is:", startingIndex[PCU_Comm_Self()]); + + DebugParallelPrinter(std::cout, "Returning from SimpleElementPartition \n"); +} + +auto ReadElements(int cgid, int base, int zone, int section, int el_start /* one based */, int el_end, int numElements, int verticesPerElement) +{ + std::vector numberToReadPerProc; + std::vector startingIndex; + SimpleElementPartition(numberToReadPerProc, startingIndex, el_start, el_end, numElements); + + std::vector vertexIDs; + if (numberToReadPerProc[PCU_Comm_Self()] > 0) + vertexIDs.resize(numberToReadPerProc[PCU_Comm_Self()] * verticesPerElement, + -1234567); + + const auto start = startingIndex[PCU_Comm_Self()]; + const auto end = startingIndex[PCU_Comm_Self()] + numberToReadPerProc[PCU_Comm_Self()] - 1; + DebugParallelPrinter(std::cout, "Range", start, "to", end, numberToReadPerProc[PCU_Comm_Self()]); + // + cgp_elements_read_data(cgid, base, zone, section, start, + end, vertexIDs.data()); + + // remove CGNS one-based offset + // to be clear these are the node ids defining the elements, not element ids + for (auto &i : vertexIDs) + { + i = i - 1; + } + + return std::make_tuple(vertexIDs, numberToReadPerProc[PCU_Comm_Self()]); +} + +apf::Mesh2 *DoIt(const std::string &fname, int readDim = 0) +{ + int cgid = -1; + auto comm = PCU_Get_Comm(); + cgp_mpi_comm(comm); + cgp_pio_mode(CGNS_ENUMV(CGP_INDEPENDENT)); + cgp_open(fname.c_str(), CGNS_ENUMV(CG_MODE_READ), &cgid); + + int nbases = -1; + cg_nbases(cgid, &nbases); + if (nbases > 1) + { + std::cout << __LINE__ << " CGNS is dead " << std::endl; + Kill(); + } + + std::string basename; + basename.resize(CGIO_MAX_NAME_LENGTH + 1, ' '); + + int cellDim = -1; + int physDim = -1; + const int base = 1; + cg_base_read(cgid, base, &basename[0], &cellDim, &physDim); + if (readDim == 0) + readDim = cellDim; + + // Salome cgns is a bit on the piss: cellDim, physDim, ncoords are not always consistent + gmi_register_mesh(); + gmi_register_null(); + gmi_model *g = gmi_load(".null"); + apf::Mesh2 *mesh = apf::makeEmptyMdsMesh(g, cellDim, false); + apf::GlobalToVert globalToVert; + + int nzones = -1; + cg_nzones(cgid, base, &nzones); + basename = std::string(basename.c_str()); + + int nfam = -1; + cg_nfamilies(cgid, base, &nfam); + + for (int zone = 1; zone <= nzones; ++zone) + { + std::string zoneName; + zoneName.resize(CGIO_MAX_NAME_LENGTH + 1, ' '); + + /* + 3D unstructured: NVertex, NCell3D, NBoundVertex + 2D unstructured: NVertex, NCell2D, NBoundVertex + */ + std::array sizes; + cg_zone_read(cgid, base, zone, &zoneName[0], sizes.data()); + + zoneName = std::string(zoneName.c_str()); + + int ngrids = -1; + cg_ngrids(cgid, base, zone, &ngrids); + if (ngrids > 1) + { + std::cout << __LINE__ << " CGNS is dead " << std::endl; + Kill(); + } + int ncoords = -1; + cg_ncoords(cgid, base, zone, &ncoords); + + CGNS_ENUMT(ZoneType_t) + zonetype = CGNS_ENUMV(ZoneTypeNull); + cg_zone_type(cgid, base, zone, &zonetype); + + int nsections = -1; + if (zonetype == CGNS_ENUMV(Unstructured)) + { + cg_nsections(cgid, base, zone, &nsections); + } + else + { + std::cout << __LINE__ << " CGNS is dead " << std::endl; + Kill(); + } + + int nBocos = -1; + cg_nbocos(cgid, base, zone, &nBocos); + + for (int section = 1; section <= nsections; section++) + { + std::string sectionName; + sectionName.resize(CGIO_MAX_NAME_LENGTH + 1, ' '); + + CGNS_ENUMT(ElementType_t) + elementType = CGNS_ENUMV(ElementTypeNull); + cgsize_t el_start = -1; + cgsize_t el_end = -1; + int num_bndry = -1; + int parent_flag = -1; + cgsize_t numElements = -1; + int verticesPerElement = -1; + + cg_section_read(cgid, base, zone, section, §ionName[0], + &elementType, &el_start, &el_end, + &num_bndry, &parent_flag); + + CGNSElementTypeToString(elementType); + numElements = el_end - el_start + 1; + + cg_npe(elementType, &verticesPerElement); + + const auto readElementsAndVerts = [&](const apf::Mesh::Type &type) { + const auto &ret = ReadElements(cgid, base, zone, section, el_start, el_end, numElements, verticesPerElement); + if (std::get<1>(ret) > 0) + { + const std::vector vertexIDs = std::get<0>(ret); + //apf::construct(mesh, vertexIDs.data(), std::get<1>(ret), type, globalToVert); + apf::assemble(mesh, vertexIDs.data(), std::get<1>(ret), type, globalToVert); // corresponding finalize below + + const auto nverts = sizes[0]; + const auto ordinates = ReadCGNSCoords(cgid, base, zone, ncoords, nverts, vertexIDs, globalToVert); + + for (const auto &p : globalToVert) + { + const auto pp = ordinates.at(p.first); + apf::Vector3 point(pp[0], pp[1], pp[2]); + mesh->setPoint(globalToVert[p.first], 0, point); + } + } + }; + + if (elementType == CGNS_ENUMV(BAR_2)) + { + if (readDim == 1) + readElementsAndVerts(apf::Mesh::EDGE); + } + else if (elementType == CGNS_ENUMV(QUAD_4)) + { + if (readDim == 2) + readElementsAndVerts(apf::Mesh::QUAD); + } + else if (elementType == CGNS_ENUMV(TRI_3)) + { + if (readDim == 2) + readElementsAndVerts(apf::Mesh::TRIANGLE); + } + else if (elementType == CGNS_ENUMV(TETRA_4)) + { + if (readDim == 3) + readElementsAndVerts(apf::Mesh::TET); + } + else if (elementType == CGNS_ENUMV(PYRA_5)) + { + if (readDim == 3) + readElementsAndVerts(apf::Mesh::PYRAMID); + } + else if (elementType == CGNS_ENUMV(HEXA_8)) + { + if (readDim == 3) + readElementsAndVerts(apf::Mesh::HEX); + } + else + { + std::cout << __LINE__ << " CGNS is dead " + << " " << CGNSElementTypeToString(elementType) << std::endl; + Kill(); + } + } + } + cgp_close(cgid); + + apf::finalise(mesh, globalToVert); + apf::alignMdsRemotes(mesh); + apf::deriveMdsModel(mesh); + mesh->acceptChanges(); + apf::verify(mesh, true); + { + apf::GlobalNumbering *gn = nullptr; + gn = apf::makeGlobal(apf::numberOwnedNodes(mesh, "vertex Indices")); + apf::synchronize(gn); + } + // no synchronize call + // https://github.com/SNLComputation/Albany/blob/master/src/disc/pumi/Albany_APFDiscretization.cpp @ various place throughout file + // https://github.com/SCOREC/core/issues/249 + { + apf::GlobalNumbering *gn = nullptr; + gn = apf::makeGlobal(apf::numberElements(mesh, "element Indices")); + } + + return mesh; +} +} // namespace + +namespace apf +{ + +// caller needs to bring up and pull down mpi/pcu: mpi/pcu is required and assumed. +Mesh2 *loadMdsFromCGNS(const char *fname) +{ +#ifdef HAVE_CGNS + Mesh2 *m = DoIt(fname); + return m; +#else + Mesh2 *m = nullptr; + PCU_ALWAYS_ASSERT_VERBOSE(m != nullptr, + "Build with ENABLE_CGNS to allow this functionality."); + exit(EXIT_FAILURE); + return m; +#endif +} + +} // namespace apf diff --git a/mds/pkg_tribits.cmake b/mds/pkg_tribits.cmake index b885dc256..eb66734a8 100644 --- a/mds/pkg_tribits.cmake +++ b/mds/pkg_tribits.cmake @@ -20,6 +20,7 @@ set(MDS_SOURCES apfBox.cc mdsANSYS.cc mdsGmsh.cc + mdsCGNS.cc mdsUgrid.cc) set(MDS_HEADERS diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a19e4fd56..709492f91 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -43,6 +43,9 @@ util_exe_func(extrude extrude.cc) # Mesh conversion/formatting utilities util_exe_func(from_gmsh gmsh.cc) +if(ENABLE_CGNS) + util_exe_func(from_cgns cgns.cc) +endif() util_exe_func(from_ansys ansys.cc) util_exe_func(from_neper neper.cc) util_exe_func(from_ugrid ugrid.cc) diff --git a/test/cgns.cc b/test/cgns.cc new file mode 100644 index 000000000..632a22abd --- /dev/null +++ b/test/cgns.cc @@ -0,0 +1,234 @@ +/* Author: Dr Andrew Parker (2019) - FGE Ltd */ + +#include +#include +#include +#include +#include +#include +#include +#include +// +#include +// +#include +#include +#include +#include + +//https://github.com/SCOREC/core/blob/4b854ae996cb261a22f6ee6b704569b78866004c/test/repartition.cc +// balance appears to delete the vertex and element numbering +void balance(apf::Mesh2 *m) +{ + bool fineStats = false; // set to true for per part stats + Parma_PrintPtnStats(m, "preRefine", fineStats); //FIXME + + apf::MeshTag *weights = m->createDoubleTag("zoltan_weight", 1); + { + apf::MeshIterator *it = m->begin(m->getDimension()); + apf::MeshEntity *e; + double value = 1.0; + while ((e = m->iterate(it))) + m->setDoubleTag(e, weights, &value); + m->end(it); + } + apf::Balancer *b = apf::makeZoltanBalancer(m, apf::RCB, apf::REPARTITION, false); + b->balance(weights, 1.1); + m->destroyTag(weights); + delete b; + + Parma_PrintPtnStats(m, ""); +} + +//https://github.com/SCOREC/core/blob/4b854ae996cb261a22f6ee6b704569b78866004c/test/reorder.cc +void reorder(apf::Mesh2 *m) +{ + //apf::MeshTag *order = Parma_BfsReorder(m); + //apf::reorderMdsMesh(m, order); + apf::reorderMdsMesh(m); +} + +// https://gist.github.com/bgranzow/98087114166956646da684ed98acab02 +apf::MeshTag *create_int_tag(apf::Mesh *m, int dim) +{ + apf::MeshTag *tag = m->createIntTag("my_tag", 1); // 1 is size of tag + apf::MeshEntity *elem; + apf::MeshIterator *it = m->begin(dim); + int vals[1]; + vals[0] = PCU_Comm_Self(); + while ((elem = m->iterate(it))) + m->setIntTag(elem, tag, vals); + m->end(it); + return tag; +} + +//https://github.com/CEED/PUMI/blob/master/ma/maDBG.cc +apf::Field *convert_tag_doubleField(apf::Mesh *m, apf::MeshTag *t, int dim) +{ + apf::MeshEntity *elem; + apf::MeshIterator *it = m->begin(dim); + apf::Field *f = nullptr; + const auto fieldName = "my_field"; + if (dim == 0) + f = apf::createFieldOn(m, fieldName, apf::SCALAR); + else + f = apf::createField(m, fieldName, apf::SCALAR, apf::getConstant(dim)); + + int vals[1]; + while ((elem = m->iterate(it))) + { + m->getIntTag(elem, t, vals); + double dval[1]; + dval[0] = vals[0]; + apf::setComponents(f, elem, 0, dval); + } + m->end(it); + return f; +} + +void additional(gmi_model *g, apf::Mesh2 *mesh) +{ + std::cout << mesh << std::endl; + { + balance(mesh); + const std::string name = "output_balance_" + std::to_string(PCU_Comm_Peers()) + "procs"; + apf::writeVtkFiles(name.c_str(), mesh); + } + { + reorder(mesh); + const auto dim = mesh->getDimension(); + convert_tag_doubleField(mesh, create_int_tag(mesh, dim), dim); + + { + apf::GlobalNumbering *gn = nullptr; + gn = apf::makeGlobal(apf::numberOwnedNodes(mesh, "vertex Indices_postreorder")); + apf::synchronize(gn); + } + // no synchronize call + // https://github.com/SNLComputation/Albany/blob/master/src/disc/pumi/Albany_APFDiscretization.cpp @ various place throughout file + // https://github.com/SCOREC/core/issues/249 + { + apf::GlobalNumbering *gn = nullptr; + gn = apf::makeGlobal(apf::numberElements(mesh, "element Indices_postreorder")); + } + const std::string name = "output_balance_reorder_" + std::to_string(PCU_Comm_Peers()) + "procs"; + apf::writeVtkFiles(name.c_str(), mesh); + } + + { + //create the pumi instance + pumi::instance()->model = new gModel(g); + pMesh pm = pumi_mesh_load(mesh); + std::cout << pm << std::endl; + pumi_mesh_verify(pm); + + // //create an element field + // const int mdim = pumi_mesh_getDim(pm); + // pShape s = pumi_shape_getConstant(mdim); + // const int dofPerElm = 1; + // pField f = pumi_field_create(pm, "elmField", dofPerElm, PUMI_PACKED, s); + + // pMeshIter it = pm->begin(mdim); + // pMeshEnt e; + // double v = 0; + // while ((e = pm->iterate(it))) + // pumi_node_setField(f, e, 0, &v); + // pm->end(it); + + // const int ghost = mdim; + // const int bridge = ghost - 1; + // const int numLayers = 1; + // const int ghostAcrossCopies = 1; + // pumi_ghost_createLayer(pm, bridge, ghost, numLayers, ghostAcrossCopies); + + // it = pm->begin(mdim); + // v = 1; + // while ((e = pm->iterate(it))) + // { + // if (!pumi_ment_isGhost(e)) + // pumi_node_setField(f, e, 0, &v); + // } + // pm->end(it); + + // // only the owned elements will have a elmField value of 1 + // pumi_mesh_write(pm, "beforeSync", "vtk"); + + // pumi_field_synchronize(f); + + // // owned and ghosted elements will have a elmField value of 1 + // pumi_mesh_write(pm, "afterSync", "vtk"); + + // // clean-up + // pumi_field_delete(f); + // pumi_ghost_delete(pm); + // pumi_mesh_delete(pm); + } +} + +int main(int argc, char **argv) +{ +#ifdef HAVE_CGNS + MPI_Init(&argc, &argv); + PCU_Comm_Init(); + lion_set_verbosity(1); + bool additionalTests = false; + if (argc < 3) + { + if (!PCU_Comm_Self()) + printf("Usage: %s \n", argv[0]); + MPI_Finalize(); + exit(EXIT_FAILURE); + return -1; + } + else if (argc == 4) + { + if (std::string(argv[3]) == "additional") + additionalTests = true; + else + { + if (!PCU_Comm_Self()) + printf("Usage: %s additional\n", argv[0]); + MPI_Finalize(); + exit(EXIT_FAILURE); + return -1; + } + } + else if (argc > 4) + { + if (!PCU_Comm_Self()) + printf("Usage: %s \n", argv[0]); + MPI_Finalize(); + exit(EXIT_FAILURE); + return -1; + } + + gmi_register_null(); + gmi_register_mesh(); + gmi_model *g = gmi_load(".null"); + apf::Mesh2 *m = apf::loadMdsFromCGNS(argv[1]); + m->verify(); + // + m->writeNative(argv[2]); + // so we can see the result + const std::string path = argv[1]; + std::size_t found = path.find_last_of("/\\"); + const auto name = path.substr(found + 1) + std::string("_toVTK"); + std::cout << path << " " << found << " " << name << std::endl; + apf::writeVtkFiles(name.c_str(), m); + + // main purpose is to call additional tests through the test harness testing.cmake + if (additionalTests) + additional(g, m); + + m->destroyNative(); + apf::destroyMesh(m); + PCU_Comm_Free(); + MPI_Finalize(); + return 0; +#else + PCU_ALWAYS_ASSERT_VERBOSE(true == false, + "Build with ENABLE_CGNS to allow this functionality."); + exit(EXIT_FAILURE); + return -1; +#endif +} diff --git a/test/testing.cmake b/test/testing.cmake index e0d368fee..b0eb2b8ed 100644 --- a/test/testing.cmake +++ b/test/testing.cmake @@ -450,6 +450,50 @@ if(ENABLE_ZOLTAN) "4" "rib" "reptn" "1" ) endif() + +if(ENABLE_CGNS) +# +# sort of an arbitrary choice +set(numProcs 4) +# +set(CGNSDIR ${MESHES}/cgns) +# +# 2D +mpi_test(cgns_2d_1 ${numProcs} + ./from_cgns + "${CGNSDIR}/2D/4quads.adf.hdf.cgns" + 4quads.smb + additional) +mpi_test(cgns_2d_2 ${numProcs} + ./from_cgns + "${CGNSDIR}/2D/5quad1Tri.adf.hdf.cgns" + 5quad1Tri.smb + additional) +mpi_test(cgns_2d_3 ${numProcs} + ./from_cgns + "${CGNSDIR}/2D/5quad2Tri.adf.hdf.cgns" + 5quad2Tri.smb + additional) +mpi_test(cgns_2d_4 ${numProcs} + ./from_cgns + "${CGNSDIR}/2D/9tris.adf.hdf.cgns" + 9tris.smb + additional) +# +# 3D +# +mpi_test(cgns_3d_1 ${numProcs} + ./from_cgns + "${CGNSDIR}/3D/tets_pyra.adf.hdf.cgns" + tets_pyra.smb + additional) +mpi_test(cgns_3d_2 ${numProcs} + ./from_cgns + "${CGNSDIR}/3D/hexs.adf.hdf.cgns" + hexs.smb + additional) +endif() + mpi_test(construct 4 ./construct "${MDIR}/cube.dmg" From 90dbe79cba5bbb225e3ff12f02378b34b4433b46 Mon Sep 17 00:00:00 2001 From: a-jp Date: Tue, 15 Oct 2019 15:01:45 +0100 Subject: [PATCH 04/72] api should take model --- mds/apfMDS.h | 2 +- mds/mdsCGNS.cc | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/mds/apfMDS.h b/mds/apfMDS.h index 1dba7b496..a6ec63866 100644 --- a/mds/apfMDS.h +++ b/mds/apfMDS.h @@ -192,7 +192,7 @@ int getMdsIndex(Mesh2* in, MeshEntity* e); so call apf::reorderMdsMesh after any mesh modification. */ MeshEntity* getMdsEntity(Mesh2* in, int dimension, int index); -Mesh2* loadMdsFromCGNS(const char* filename); +Mesh2* loadMdsFromCGNS(gmi_model* g, const char* filename); Mesh2* loadMdsFromGmsh(gmi_model* g, const char* filename); diff --git a/mds/mdsCGNS.cc b/mds/mdsCGNS.cc index b4dc6b353..2584a66b8 100644 --- a/mds/mdsCGNS.cc +++ b/mds/mdsCGNS.cc @@ -260,7 +260,7 @@ auto ReadElements(int cgid, int base, int zone, int section, int el_start /* one return std::make_tuple(vertexIDs, numberToReadPerProc[PCU_Comm_Self()]); } -apf::Mesh2 *DoIt(const std::string &fname, int readDim = 0) +apf::Mesh2 *DoIt(gmi_model* g, const std::string &fname, int readDim = 0) { int cgid = -1; auto comm = PCU_Get_Comm(); @@ -287,9 +287,6 @@ apf::Mesh2 *DoIt(const std::string &fname, int readDim = 0) readDim = cellDim; // Salome cgns is a bit on the piss: cellDim, physDim, ncoords are not always consistent - gmi_register_mesh(); - gmi_register_null(); - gmi_model *g = gmi_load(".null"); apf::Mesh2 *mesh = apf::makeEmptyMdsMesh(g, cellDim, false); apf::GlobalToVert globalToVert; @@ -451,10 +448,10 @@ namespace apf { // caller needs to bring up and pull down mpi/pcu: mpi/pcu is required and assumed. -Mesh2 *loadMdsFromCGNS(const char *fname) +Mesh2 *loadMdsFromCGNS(gmi_model* g, const char *fname) { #ifdef HAVE_CGNS - Mesh2 *m = DoIt(fname); + Mesh2 *m = DoIt(g, fname); return m; #else Mesh2 *m = nullptr; From dbea6c2bdf07ba73b6113ec44dd99aa4d2f6206b Mon Sep 17 00:00:00 2001 From: a-jp Date: Tue, 15 Oct 2019 15:02:04 +0100 Subject: [PATCH 05/72] cleaner testing plus bug fix and api changes --- test/cgns.cc | 229 +++++++++++++++++++++++++++------------------------ 1 file changed, 120 insertions(+), 109 deletions(-) diff --git a/test/cgns.cc b/test/cgns.cc index 632a22abd..41a7c3d4e 100644 --- a/test/cgns.cc +++ b/test/cgns.cc @@ -16,42 +16,10 @@ #include #include -//https://github.com/SCOREC/core/blob/4b854ae996cb261a22f6ee6b704569b78866004c/test/repartition.cc -// balance appears to delete the vertex and element numbering -void balance(apf::Mesh2 *m) -{ - bool fineStats = false; // set to true for per part stats - Parma_PrintPtnStats(m, "preRefine", fineStats); //FIXME - - apf::MeshTag *weights = m->createDoubleTag("zoltan_weight", 1); - { - apf::MeshIterator *it = m->begin(m->getDimension()); - apf::MeshEntity *e; - double value = 1.0; - while ((e = m->iterate(it))) - m->setDoubleTag(e, weights, &value); - m->end(it); - } - apf::Balancer *b = apf::makeZoltanBalancer(m, apf::RCB, apf::REPARTITION, false); - b->balance(weights, 1.1); - m->destroyTag(weights); - delete b; - - Parma_PrintPtnStats(m, ""); -} - -//https://github.com/SCOREC/core/blob/4b854ae996cb261a22f6ee6b704569b78866004c/test/reorder.cc -void reorder(apf::Mesh2 *m) -{ - //apf::MeshTag *order = Parma_BfsReorder(m); - //apf::reorderMdsMesh(m, order); - apf::reorderMdsMesh(m); -} - // https://gist.github.com/bgranzow/98087114166956646da684ed98acab02 -apf::MeshTag *create_int_tag(apf::Mesh *m, int dim) +apf::MeshTag *create_int_tag(const std::string &name, apf::Mesh *m, int dim) { - apf::MeshTag *tag = m->createIntTag("my_tag", 1); // 1 is size of tag + apf::MeshTag *tag = m->createIntTag(name.c_str(), 1); // 1 is size of tag apf::MeshEntity *elem; apf::MeshIterator *it = m->begin(dim); int vals[1]; @@ -63,12 +31,12 @@ apf::MeshTag *create_int_tag(apf::Mesh *m, int dim) } //https://github.com/CEED/PUMI/blob/master/ma/maDBG.cc -apf::Field *convert_tag_doubleField(apf::Mesh *m, apf::MeshTag *t, int dim) +apf::Field *convert_tag_doubleField(const std::string &name, apf::Mesh *m, apf::MeshTag *t, int dim) { apf::MeshEntity *elem; apf::MeshIterator *it = m->begin(dim); apf::Field *f = nullptr; - const auto fieldName = "my_field"; + const auto fieldName = name.c_str(); if (dim == 0) f = apf::createFieldOn(m, fieldName, apf::SCALAR); else @@ -86,82 +54,121 @@ apf::Field *convert_tag_doubleField(apf::Mesh *m, apf::MeshTag *t, int dim) return f; } -void additional(gmi_model *g, apf::Mesh2 *mesh) +void balance(const std::string &prefix, const apf::ZoltanMethod& method, apf::Mesh2 *m) +{ + const auto dim = m->getDimension(); + convert_tag_doubleField("procID_prebalance", m, create_int_tag("procID_prebalance", m, dim), dim); + + apf::MeshTag *weights = Parma_WeighByMemory(m); + apf::Balancer *balancer = makeZoltanBalancer(m, method, apf::REPARTITION); + balancer->balance(weights, 1.10); + delete balancer; + apf::removeTagFromDimension(m, weights, m->getDimension()); + Parma_PrintPtnStats(m, ""); + m->destroyTag(weights); + + const std::string name = prefix + "_balance_" + std::to_string(PCU_Comm_Peers()) + "procs"; + apf::writeVtkFiles(name.c_str(), m); +} + +//https://github.com/SCOREC/core/blob/4b854ae996cb261a22f6ee6b704569b78866004c/test/reorder.cc +void simpleReorder(const std::string &prefix, apf::Mesh2 *m) { - std::cout << mesh << std::endl; { - balance(mesh); - const std::string name = "output_balance_" + std::to_string(PCU_Comm_Peers()) + "procs"; - apf::writeVtkFiles(name.c_str(), mesh); + apf::GlobalNumbering *gn = nullptr; + gn = apf::makeGlobal(apf::numberOwnedNodes(m, "vertex Indices_prereorder")); + apf::synchronize(gn); } + // no synchronize call + // https://github.com/SNLComputation/Albany/blob/master/src/disc/pumi/Albany_APFDiscretization.cpp @ various place throughout file + // https://github.com/SCOREC/core/issues/249 { - reorder(mesh); - const auto dim = mesh->getDimension(); - convert_tag_doubleField(mesh, create_int_tag(mesh, dim), dim); + apf::GlobalNumbering *gn = nullptr; + gn = apf::makeGlobal(apf::numberElements(m, "element Indices_prereorder")); + } - { - apf::GlobalNumbering *gn = nullptr; - gn = apf::makeGlobal(apf::numberOwnedNodes(mesh, "vertex Indices_postreorder")); - apf::synchronize(gn); - } - // no synchronize call - // https://github.com/SNLComputation/Albany/blob/master/src/disc/pumi/Albany_APFDiscretization.cpp @ various place throughout file - // https://github.com/SCOREC/core/issues/249 - { - apf::GlobalNumbering *gn = nullptr; - gn = apf::makeGlobal(apf::numberElements(mesh, "element Indices_postreorder")); - } - const std::string name = "output_balance_reorder_" + std::to_string(PCU_Comm_Peers()) + "procs"; - apf::writeVtkFiles(name.c_str(), mesh); + //apf::MeshTag *order = Parma_BfsReorder(m); + //apf::reorderMdsMesh(m, order); + apf::reorderMdsMesh(m); + + { + apf::GlobalNumbering *gn = nullptr; + gn = apf::makeGlobal(apf::numberOwnedNodes(m, "vertex Indices_postreorder")); + apf::synchronize(gn); + } + // no synchronize call + // https://github.com/SNLComputation/Albany/blob/master/src/disc/pumi/Albany_APFDiscretization.cpp @ various place throughout file + // https://github.com/SCOREC/core/issues/249 + { + apf::GlobalNumbering *gn = nullptr; + gn = apf::makeGlobal(apf::numberElements(m, "element Indices_postreorder")); } + const std::string name = prefix + "_reorder_" + std::to_string(PCU_Comm_Peers()) + "procs"; + apf::writeVtkFiles(name.c_str(), m); +} + +pMesh toPumi(const std::string &prefix, gmi_model *g, apf::Mesh2 *mesh) +{ + //create the pumi instance + pumi::instance()->model = new gModel(g); + pMesh pm = pumi_mesh_load(mesh); + std::cout << pm << std::endl; + pumi_mesh_verify(pm); + const std::string name = prefix + "_toPUMI_" + std::to_string(PCU_Comm_Peers()) + "procs"; + pumi_mesh_write(pm, name.c_str(), "vtk"); + return pm; +} + +void additional(const std::string &prefix, gmi_model *g, apf::Mesh2 *mesh) +{ + // seems essential to make pm first before calling balance or reorder... + auto pm = toPumi(prefix, g, mesh); + balance(prefix, apf::RCB, pm); + simpleReorder(prefix, pm); + { - //create the pumi instance - pumi::instance()->model = new gModel(g); - pMesh pm = pumi_mesh_load(mesh); - std::cout << pm << std::endl; - pumi_mesh_verify(pm); - - // //create an element field - // const int mdim = pumi_mesh_getDim(pm); - // pShape s = pumi_shape_getConstant(mdim); - // const int dofPerElm = 1; - // pField f = pumi_field_create(pm, "elmField", dofPerElm, PUMI_PACKED, s); - - // pMeshIter it = pm->begin(mdim); - // pMeshEnt e; - // double v = 0; - // while ((e = pm->iterate(it))) - // pumi_node_setField(f, e, 0, &v); - // pm->end(it); - - // const int ghost = mdim; - // const int bridge = ghost - 1; - // const int numLayers = 1; - // const int ghostAcrossCopies = 1; - // pumi_ghost_createLayer(pm, bridge, ghost, numLayers, ghostAcrossCopies); - - // it = pm->begin(mdim); - // v = 1; - // while ((e = pm->iterate(it))) - // { - // if (!pumi_ment_isGhost(e)) - // pumi_node_setField(f, e, 0, &v); - // } - // pm->end(it); - - // // only the owned elements will have a elmField value of 1 - // pumi_mesh_write(pm, "beforeSync", "vtk"); - - // pumi_field_synchronize(f); - - // // owned and ghosted elements will have a elmField value of 1 - // pumi_mesh_write(pm, "afterSync", "vtk"); - - // // clean-up - // pumi_field_delete(f); - // pumi_ghost_delete(pm); - // pumi_mesh_delete(pm); + //create an element field + const int mdim = pumi_mesh_getDim(pm); + pShape s = pumi_shape_getConstant(mdim); + const int dofPerElm = 1; + pField f = pumi_field_create(pm, "elmField", dofPerElm, PUMI_PACKED, s); + + pMeshIter it = pm->begin(mdim); + pMeshEnt e; + double v = 0; + while ((e = pm->iterate(it))) + pumi_node_setField(f, e, 0, &v); + pm->end(it); + + const int ghost = mdim; + const int bridge = ghost - 1; + const int numLayers = 1; + const int ghostAcrossCopies = 1; + pumi_ghost_createLayer(pm, bridge, ghost, numLayers, ghostAcrossCopies); + + it = pm->begin(mdim); + v = 1; + while ((e = pm->iterate(it))) + { + if (!pumi_ment_isGhost(e)) + pumi_node_setField(f, e, 0, &v); + } + pm->end(it); + + const std::string name = prefix + "_toPUMI_" + std::to_string(PCU_Comm_Peers()) + "procs"; + // only the owned elements will have a elmField value of 1 + pumi_mesh_write(pm, (name + "_beforeSync").c_str(), "vtk"); + + pumi_field_synchronize(f); + + // owned and ghosted elements will have a elmField value of 1 + pumi_mesh_write(pm, (name + "_afterSync").c_str(), "vtk"); + + // clean-up + pumi_field_delete(f); + pumi_ghost_delete(pm); + pumi_mesh_delete(pm); } } @@ -205,23 +212,27 @@ int main(int argc, char **argv) gmi_register_null(); gmi_register_mesh(); gmi_model *g = gmi_load(".null"); - apf::Mesh2 *m = apf::loadMdsFromCGNS(argv[1]); + apf::Mesh2 *m = apf::loadMdsFromCGNS(g, argv[1]); m->verify(); // m->writeNative(argv[2]); // so we can see the result const std::string path = argv[1]; std::size_t found = path.find_last_of("/\\"); - const auto name = path.substr(found + 1) + std::string("_toVTK"); + const auto prefix = path.substr(found + 1); + const auto name = prefix + std::string("_toVTK"); std::cout << path << " " << found << " " << name << std::endl; apf::writeVtkFiles(name.c_str(), m); // main purpose is to call additional tests through the test harness testing.cmake if (additionalTests) - additional(g, m); + additional(prefix, g, m); - m->destroyNative(); - apf::destroyMesh(m); + if (!additionalTests) + { + m->destroyNative(); + apf::destroyMesh(m); + } PCU_Comm_Free(); MPI_Finalize(); return 0; From a90d29c01b79d9bddb7ae42fc4e696e9d2779b11 Mon Sep 17 00:00:00 2001 From: a-jp Date: Tue, 15 Oct 2019 16:22:50 +0100 Subject: [PATCH 06/72] changes to tests for bcs testing --- test/testing.cmake | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/test/testing.cmake b/test/testing.cmake index b0eb2b8ed..04dd8432d 100644 --- a/test/testing.cmake +++ b/test/testing.cmake @@ -456,7 +456,7 @@ if(ENABLE_CGNS) # sort of an arbitrary choice set(numProcs 4) # -set(CGNSDIR ${MESHES}/cgns) +set(CGNSDIR ${MESHES}/cgns/basic) # # 2D mpi_test(cgns_2d_1 ${numProcs} @@ -492,6 +492,18 @@ mpi_test(cgns_3d_2 ${numProcs} "${CGNSDIR}/3D/hexs.adf.hdf.cgns" hexs.smb additional) +# +# BCS tests +# +set(numProcs 5) +# +set(CGNSDIR ${MESHES}/cgns/withBCS) +# +mpi_test(cgns_bcs_1 ${numProcs} + ./from_cgns + "${CGNSDIR}/Mesh_3.adf.hdf.cgns" + bcs1.smb + additional) endif() mpi_test(construct 4 From 5c75493c1f7faa38b086f4c423de156d01123cb7 Mon Sep 17 00:00:00 2001 From: a-jp Date: Wed, 16 Oct 2019 13:24:47 +0100 Subject: [PATCH 07/72] more work on testing bcs --- mds/mdsCGNS.cc | 311 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 281 insertions(+), 30 deletions(-) diff --git a/mds/mdsCGNS.cc b/mds/mdsCGNS.cc index 2584a66b8..ea05f0e24 100644 --- a/mds/mdsCGNS.cc +++ b/mds/mdsCGNS.cc @@ -22,16 +22,17 @@ #include #include -#ifdef HAVE_CGNS -// #include #include #include #include #include #include +#include #include // +#ifdef HAVE_CGNS +// #include #include // @@ -39,13 +40,13 @@ namespace { -#ifdef DEBUG +#ifndef NDEBUG // debug, cmake double negative static constexpr bool debugOutput = true; -#else +#else // optimised static constexpr bool debugOutput = false; #endif -static std::string CGNSElementTypeToString(const CGNS_ENUMT(ElementType_t) & elementType) +static std::string SupportedCGNSElementTypeToString(const CGNS_ENUMT(ElementType_t) & elementType) { if (elementType == CGNS_ENUMV(NODE)) return "NODE"; @@ -86,38 +87,55 @@ void DebugParallelPrinter(std::ostream &out, Arg &&arg, Args &&... args) out << "\n"; out << std::flush; } - PCU_Barrier(); + // removed this: can't guarantee this is collectively called, order not ensured therefore. + //PCU_Barrier(); } } } -void Kill() +template +void Kill(const int fid, Args &&... args) { + DebugParallelPrinter(std::cout, args...); + if (PCU_Comm_Initialized()) { + cgp_close(fid); // Finalize the MPI environment. PCU_Comm_Free(); MPI_Finalize(); + cgp_error_exit(); exit(EXIT_FAILURE); } else { + cg_close(fid); + cg_error_exit(); exit(EXIT_FAILURE); } } -auto ReadCGNSCoords(int cgid, int base, int zone, int ncoords, int nverts, const std::vector &, const apf::GlobalToVert &globalToVert) +void Kill(const int fid) { - // Read all - // const int lowest = 1; - // const int highest = nverts; - - // Read min required as defined by consecutive range - // make one based as ReadElements makes zero based - // const int lowest = *std::min_element(vertexIDs.begin(), vertexIDs.end()) + 1; - // const int highest = *std::max_element(vertexIDs.begin(), vertexIDs.end()) + 1; - // DebugParallelPrinter(std::cout, "From vertexIDs ", lowest, highest, nverts); + if (PCU_Comm_Initialized()) + { + cgp_close(fid); + // Finalize the MPI environment. + PCU_Comm_Free(); + MPI_Finalize(); + cgp_error_exit(); + exit(EXIT_FAILURE); + } + else + { + cg_close(fid); + cg_error_exit(); + exit(EXIT_FAILURE); + } +} +auto ReadCGNSCoords(int cgid, int base, int zone, int ncoords, int nverts, const std::vector &, const apf::GlobalToVert &globalToVert) +{ // Read min required as defined by consecutive range // make one based as ReadElements makes zero based const int lowest = globalToVert.begin()->first + 1; @@ -152,7 +170,7 @@ auto ReadCGNSCoords(int cgid, int base, int zone, int ncoords, int nverts, const if (cg_coord_info(cgid, base, zone, d + 1, &datatype, &coord_names[d][0])) { std::cout << __LINE__ << " CGNS is dead " << std::endl; - Kill(); + Kill(cgid); } const auto coord_name = std::string(coord_names[d].c_str()); //boost::algorithm::trim(coord_name); // can't be bothered including boost @@ -162,7 +180,7 @@ auto ReadCGNSCoords(int cgid, int base, int zone, int ncoords, int nverts, const ordinate.data())) { std::cout << __LINE__ << " CGNS is dead " << std::endl; - Kill(); + Kill(cgid); } } // to be clear, indices passed back are global, zero based @@ -260,7 +278,231 @@ auto ReadElements(int cgid, int base, int zone, int section, int el_start /* one return std::make_tuple(vertexIDs, numberToReadPerProc[PCU_Comm_Self()]); } -apf::Mesh2 *DoIt(gmi_model* g, const std::string &fname, int readDim = 0) +struct CGNSBCMeta +{ + std::string bocoName; + CGNS_ENUMT(BCType_t) + bocoType = CGNS_ENUMV(BCTypeNull); + CGNS_ENUMT(PointSetType_t) + ptsetType = CGNS_ENUMV(PointSetTypeNull); + cgsize_t npnts = -1; + std::vector normalindices; + cgsize_t normalListSize = -1; + CGNS_ENUMT(DataType_t) + normalDataType = CGNS_ENUMV(DataTypeNull); + int ndataset = -1; + CGNS_ENUMT(GridLocation_t) + location = CGNS_ENUMV(GridLocationNull); + std::string locationName; + cgsize_t minElementId = -1; + cgsize_t maxElementId = -1; + std::vector bcElementIds; + + void Info() const + { + std::cout << "BC named: " << bocoName << ", located on: " << locationName << std::endl; + std::cout << "\tHas " << npnts << " elements on the bc stored as a " << cg_PointSetTypeName(ptsetType) << std::endl; + std::cout << "\tThe min and max Element Ids for this bcs are: " << minElementId << " " << maxElementId << std::endl; + if constexpr (debugOutput) + { + std::cout << "\tThe element Ids that are tagged with this bcs are: "; + for (const auto &i : bcElementIds) + std::cout << i << " "; + std::cout << std::endl; + } + } +}; + +struct BCInfo +{ + std::string bcName; // user provided + std::string cgnsLocation; // for debug + std::unordered_set vertexIds; +}; + +void ReadBCInfo(const int cgid, const int base, const int zone, const int nBocos, const int physDim, const int cellDim, const int nsections) +{ + // Read the BCS. + std::vector bcMetas(nBocos); + std::vector bcInfos(nBocos); + // + for (int boco = 1; boco <= nBocos; boco++) + { + auto &bcInfo = bcInfos[boco - 1]; + auto &bcMeta = bcMetas[boco - 1]; + bcMeta.normalindices.resize(physDim); + + bcMeta.bocoName.resize(CGIO_MAX_NAME_LENGTH + 1, ' '); + bool pointRange = false; + + if (cg_boco_info(cgid, base, zone, boco, &bcMeta.bocoName[0], &bcMeta.bocoType, + &bcMeta.ptsetType, &bcMeta.npnts, bcMeta.normalindices.data(), &bcMeta.normalListSize, + &bcMeta.normalDataType, &bcMeta.ndataset)) + Kill(cgid, "Failed cg_boco_info"); + + if (bcMeta.ptsetType == CGNS_ENUMV(PointList) || (bcMeta.ptsetType == CGNS_ENUMV(PointRange))) + { + bcMeta.bocoName = std::string(bcMeta.bocoName.c_str()); + //boost::algorithm::trim(bcMeta.bocoName); // can't be bothered including boost + + if (cg_boco_gridlocation_read(cgid, base, zone, boco, &bcMeta.location)) + Kill(cgid, "Failed cg_boco_gridlocation_read"); + + bcMeta.locationName = cg_GridLocationName(bcMeta.location); + + if (bcMeta.ptsetType == CGNS_ENUMV(PointRange)) + pointRange = true; + } + else + { + Kill(cgid, + "TODO: Can only work with " + "PointList and PointRange BC " + "types at the moment"); + } + + bcMeta.minElementId = -1; + bcMeta.maxElementId = -1; + bcMeta.bcElementIds.resize(bcMeta.npnts, -1); + + // here I read say elements with bcs as: 5, 3, 7, 9, and then read below ALL elements from 3->9, + // but I only need, 3, 5, 7, 9, so don't need elements 4, 6, 8 + { + if (bcMeta.locationName == "Vertex") // && cellDim == 1) + { + if (cg_boco_read(cgid, base, zone, boco, bcMeta.bcElementIds.data(), NULL)) + Kill(cgid, "Failed cg_boco_read"); + } + else if (bcMeta.locationName == "EdgeCenter") // && cellDim == 2) + { + if (cg_boco_read(cgid, base, zone, boco, bcMeta.bcElementIds.data(), NULL)) + Kill(cgid, "Failed cg_boco_read"); + } + else if (bcMeta.locationName == "FaceCenter") // && cellDim == 3) + { + if (cg_boco_read(cgid, base, zone, boco, bcMeta.bcElementIds.data(), NULL)) + Kill(cgid, "Failed cg_boco_read"); + } + else if (bcMeta.locationName == "CellCenter") // && cellDim == 3) + { + if (cg_boco_read(cgid, base, zone, boco, bcMeta.bcElementIds.data(), NULL)) + Kill(cgid, "Failed cg_boco_read"); + } + else + Kill(cgid, "Failed Location test for BC Type", bcMeta.locationName, + cellDim); + + if (pointRange) + { + // Check this is correct, I'm just trying to fill a contiguous range from [start, end] + PCU_ALWAYS_ASSERT_VERBOSE(bcMeta.bcElementIds.size() == 2, "wrong size"); + const auto start = bcMeta.bcElementIds[0]; + const auto end = bcMeta.bcElementIds[1]; + const auto size = end - start + 1; + bcMeta.bcElementIds.resize(size, -1); + std::iota(std::begin(bcMeta.bcElementIds), std::end(bcMeta.bcElementIds), start); + } + + bcMeta.minElementId = *std::min_element(bcMeta.bcElementIds.begin(), bcMeta.bcElementIds.end()); + bcMeta.maxElementId = *std::max_element(bcMeta.bcElementIds.begin(), bcMeta.bcElementIds.end()); + bcMeta.Info(); + bcInfo.bcName = bcMeta.bocoName; + bcInfo.cgnsLocation = bcMeta.locationName; + } + + std::vector vertexIDs; + if (bcMeta.locationName != "Vertex") + { + std::unordered_set elementsToConsider; + for (const auto &j : bcMeta.bcElementIds) + elementsToConsider.insert(j); + + for (int section = 1; section <= nsections; section++) + { + std::string sectionName; + sectionName.resize(CGIO_MAX_NAME_LENGTH + 1, ' '); + + CGNS_ENUMT(ElementType_t) + elementType = CGNS_ENUMV(ElementTypeNull); + cgsize_t el_start = -1; + cgsize_t el_end = -1; + int num_bndry = -1; + int parent_flag = -1; + cgsize_t numElements = -1; + int verticesPerElement = -1; + + cg_section_read(cgid, base, zone, section, §ionName[0], + &elementType, &el_start, &el_end, + &num_bndry, &parent_flag); + + numElements = el_end - el_start + 1; + + cg_npe(elementType, &verticesPerElement); + + const cgsize_t es = el_start; + const cgsize_t ee = el_end; + + cgsize_t range_min = bcMeta.minElementId; + cgsize_t range_max = bcMeta.maxElementId; + + bool doRead = true; + if (es < bcMeta.minElementId && ee < bcMeta.minElementId) + doRead = false; + if (es > bcMeta.maxElementId && es > bcMeta.maxElementId) + doRead = false; + + if (doRead) + { + if (es < bcMeta.minElementId && ee < bcMeta.minElementId) // clip lower + range_max = ee; + + if (es < bcMeta.maxElementId && ee > bcMeta.maxElementId) // clip higher + range_min = es; + + range_min = std::max(es, bcMeta.minElementId); + range_max = std::min(ee, bcMeta.maxElementId); + const cgsize_t range_num = range_max - range_min + 1; + + vertexIDs.resize(range_num * verticesPerElement, + -1234567); + + cg_elements_partial_read(cgid, base, zone, section, range_min, + range_max, vertexIDs.data(), nullptr); + + cgsize_t counter = range_min; + for (size_t i = 0; i < vertexIDs.size(); i += verticesPerElement) + { + if (elementsToConsider.count(counter)) + { + auto last = std::min(vertexIDs.size(), i + verticesPerElement); + std::vector vec(vertexIDs.begin() + i, vertexIDs.begin() + last); + // std::cout << counter << " "; + // for (const auto &j : vec) + // std::cout << j << " "; + // std::cout << std::endl; + + for (const auto &k : vec) + bcInfo.vertexIds.insert(k); + } + counter++; + } + } + } + } + else + { + vertexIDs = bcMeta.bcElementIds; + // std::cout << "Vertex BCS: "; + // for (const auto &j : vertexIDs) + // std::cout << j << " "; + // std::cout << std::endl; + for (const auto &k : vertexIDs) + bcInfo.vertexIds.insert(k); + } + } +} + +apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname) { int cgid = -1; auto comm = PCU_Get_Comm(); @@ -273,7 +515,7 @@ apf::Mesh2 *DoIt(gmi_model* g, const std::string &fname, int readDim = 0) if (nbases > 1) { std::cout << __LINE__ << " CGNS is dead " << std::endl; - Kill(); + Kill(cgid); } std::string basename; @@ -283,8 +525,7 @@ apf::Mesh2 *DoIt(gmi_model* g, const std::string &fname, int readDim = 0) int physDim = -1; const int base = 1; cg_base_read(cgid, base, &basename[0], &cellDim, &physDim); - if (readDim == 0) - readDim = cellDim; + const int readDim = cellDim; // Salome cgns is a bit on the piss: cellDim, physDim, ncoords are not always consistent apf::Mesh2 *mesh = apf::makeEmptyMdsMesh(g, cellDim, false); @@ -316,7 +557,7 @@ apf::Mesh2 *DoIt(gmi_model* g, const std::string &fname, int readDim = 0) if (ngrids > 1) { std::cout << __LINE__ << " CGNS is dead " << std::endl; - Kill(); + Kill(cgid); } int ncoords = -1; cg_ncoords(cgid, base, zone, &ncoords); @@ -333,12 +574,19 @@ apf::Mesh2 *DoIt(gmi_model* g, const std::string &fname, int readDim = 0) else { std::cout << __LINE__ << " CGNS is dead " << std::endl; - Kill(); + Kill(cgid); } int nBocos = -1; cg_nbocos(cgid, base, zone, &nBocos); + if (nBocos > 0) + { + std::cout << "Attempting to read BCS info " + << " " << nBocos << std::endl; + ReadBCInfo(cgid, base, zone, nBocos, physDim, cellDim, nsections); + } + for (int section = 1; section <= nsections; section++) { std::string sectionName; @@ -357,7 +605,6 @@ apf::Mesh2 *DoIt(gmi_model* g, const std::string &fname, int readDim = 0) &elementType, &el_start, &el_end, &num_bndry, &parent_flag); - CGNSElementTypeToString(elementType); numElements = el_end - el_start + 1; cg_npe(elementType, &verticesPerElement); @@ -415,12 +662,16 @@ apf::Mesh2 *DoIt(gmi_model* g, const std::string &fname, int readDim = 0) else { std::cout << __LINE__ << " CGNS is dead " - << " " << CGNSElementTypeToString(elementType) << std::endl; - Kill(); + << " " << SupportedCGNSElementTypeToString(elementType) << std::endl; + Kill(cgid); } } } - cgp_close(cgid); + + if (PCU_Comm_Initialized()) + cgp_close(cgid); + else + cg_close(cgid); apf::finalise(mesh, globalToVert); apf::alignMdsRemotes(mesh); @@ -448,7 +699,7 @@ namespace apf { // caller needs to bring up and pull down mpi/pcu: mpi/pcu is required and assumed. -Mesh2 *loadMdsFromCGNS(gmi_model* g, const char *fname) +Mesh2 *loadMdsFromCGNS(gmi_model *g, const char *fname) { #ifdef HAVE_CGNS Mesh2 *m = DoIt(g, fname); From 634af4e2580e33a00ac9d59577de68603beb2c71 Mon Sep 17 00:00:00 2001 From: a-jp Date: Wed, 16 Oct 2019 15:28:30 +0100 Subject: [PATCH 08/72] be consistent with meshes repo --- test/testing.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testing.cmake b/test/testing.cmake index 04dd8432d..e7aba1205 100644 --- a/test/testing.cmake +++ b/test/testing.cmake @@ -497,7 +497,7 @@ mpi_test(cgns_3d_2 ${numProcs} # set(numProcs 5) # -set(CGNSDIR ${MESHES}/cgns/withBCS) +set(CGNSDIR ${MESHES}/cgns/withBCS/3D) # mpi_test(cgns_bcs_1 ${numProcs} ./from_cgns From 23c1313f70c42c20f22ff1006c48843bdef1e496 Mon Sep 17 00:00:00 2001 From: a-jp Date: Wed, 16 Oct 2019 15:28:55 +0100 Subject: [PATCH 09/72] fixes to bc tag gen --- mds/mdsCGNS.cc | 117 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 94 insertions(+), 23 deletions(-) diff --git a/mds/mdsCGNS.cc b/mds/mdsCGNS.cc index ea05f0e24..39a39143c 100644 --- a/mds/mdsCGNS.cc +++ b/mds/mdsCGNS.cc @@ -88,7 +88,7 @@ void DebugParallelPrinter(std::ostream &out, Arg &&arg, Args &&... args) out << std::flush; } // removed this: can't guarantee this is collectively called, order not ensured therefore. - //PCU_Barrier(); + //PCU_Barrier(); } } } @@ -96,7 +96,7 @@ void DebugParallelPrinter(std::ostream &out, Arg &&arg, Args &&... args) template void Kill(const int fid, Args &&... args) { - DebugParallelPrinter(std::cout, args...); + DebugParallelPrinter(std::cout, "***** CGNS ERROR", args...); if (PCU_Comm_Initialized()) { @@ -315,16 +315,61 @@ struct CGNSBCMeta struct BCInfo { - std::string bcName; // user provided - std::string cgnsLocation; // for debug - std::unordered_set vertexIds; + std::string bcName; // user provided + std::string cgnsLocation; // for debug + std::unordered_set vertexIds; // zero-based global to relate to GlobalToVert + apf::MeshTag *tag = nullptr; + apf::Field *field = nullptr; + + void TagVertices(const int cgid, apf::Mesh *m, apf::GlobalToVert &globalToVert) + { + tag = m->createIntTag(bcName.c_str(), 1); // 1 is size of tag + apf::MeshEntity *elem = nullptr; + apf::MeshIterator *it = m->begin(0); + int vals[1]; + vals[0] = 0; + while ((elem = m->iterate(it))) + m->setIntTag(elem, tag, vals); + m->end(it); + + for (const auto &v : vertexIds) + { + auto iter = globalToVert.find(v); + if (iter != globalToVert.end()) + { + apf::MeshEntity *elem = iter->second; + vals[0] = 1; + m->setIntTag(elem, tag, vals); + } + else + { + Kill(cgid, "GlobalToVert lookup problem", v); + } + } + + { + apf::MeshEntity *elem; + apf::MeshIterator *it = m->begin(0); + field = apf::createFieldOn(m, bcName.c_str(), apf::SCALAR); + + int vals[1]; + while ((elem = m->iterate(it))) + { + m->getIntTag(elem, tag, vals); + double dval[1]; + dval[0] = vals[0]; + apf::setComponents(field, elem, 0, dval); + } + m->end(it); + } + } }; -void ReadBCInfo(const int cgid, const int base, const int zone, const int nBocos, const int physDim, const int cellDim, const int nsections) +void ReadBCInfo(const int cgid, const int base, const int zone, const int nBocos, const int physDim, const int cellDim, const int nsections, std::vector &bcInfos, const apf::GlobalToVert &globalToVert) { // Read the BCS. std::vector bcMetas(nBocos); - std::vector bcInfos(nBocos); + bcInfos.resize(nBocos); // for (int boco = 1; boco <= nBocos; boco++) { @@ -470,6 +515,7 @@ void ReadBCInfo(const int cgid, const int base, const int zone, const int nBocos range_max, vertexIDs.data(), nullptr); cgsize_t counter = range_min; + for (size_t i = 0; i < vertexIDs.size(); i += verticesPerElement) { if (elementsToConsider.count(counter)) @@ -482,7 +528,12 @@ void ReadBCInfo(const int cgid, const int base, const int zone, const int nBocos // std::cout << std::endl; for (const auto &k : vec) - bcInfo.vertexIds.insert(k); + { + const auto zb = k - 1; // make zero-based + auto iter = globalToVert.find(zb); + if (iter != globalToVert.end()) + bcInfo.vertexIds.insert(zb); + } } counter++; } @@ -497,7 +548,12 @@ void ReadBCInfo(const int cgid, const int base, const int zone, const int nBocos // std::cout << j << " "; // std::cout << std::endl; for (const auto &k : vertexIDs) - bcInfo.vertexIds.insert(k); + { + const auto zb = k - 1; // make zero-based + auto iter = globalToVert.find(zb); + if (iter != globalToVert.end()) + bcInfo.vertexIds.insert(zb); + } } } } @@ -527,7 +583,7 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname) cg_base_read(cgid, base, &basename[0], &cellDim, &physDim); const int readDim = cellDim; - // Salome cgns is a bit on the piss: cellDim, physDim, ncoords are not always consistent + // Salome cgns is a bit on the odd side: cellDim, physDim, ncoords are not always consistent apf::Mesh2 *mesh = apf::makeEmptyMdsMesh(g, cellDim, false); apf::GlobalToVert globalToVert; @@ -538,6 +594,8 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname) int nfam = -1; cg_nfamilies(cgid, base, &nfam); + std::vector bcInfos; + for (int zone = 1; zone <= nzones; ++zone) { std::string zoneName; @@ -580,13 +638,6 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname) int nBocos = -1; cg_nbocos(cgid, base, zone, &nBocos); - if (nBocos > 0) - { - std::cout << "Attempting to read BCS info " - << " " << nBocos << std::endl; - ReadBCInfo(cgid, base, zone, nBocos, physDim, cellDim, nsections); - } - for (int section = 1; section <= nsections; section++) { std::string sectionName; @@ -624,7 +675,15 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname) { const auto pp = ordinates.at(p.first); apf::Vector3 point(pp[0], pp[1], pp[2]); - mesh->setPoint(globalToVert[p.first], 0, point); + auto iter = globalToVert.find(p.first); + if (iter != globalToVert.end()) + { + mesh->setPoint(iter->second, 0, point); + } + else + { + Kill(cgid, "GlobalToVert lookup problem"); + } } } }; @@ -666,12 +725,14 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname) Kill(cgid); } } - } - if (PCU_Comm_Initialized()) - cgp_close(cgid); - else - cg_close(cgid); + if (nBocos > 0) + { + std::cout << "Attempting to read BCS info " + << " " << nBocos << std::endl; + ReadBCInfo(cgid, base, zone, nBocos, physDim, cellDim, nsections, bcInfos, globalToVert); + } + } apf::finalise(mesh, globalToVert); apf::alignMdsRemotes(mesh); @@ -691,6 +752,16 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname) gn = apf::makeGlobal(apf::numberElements(mesh, "element Indices")); } + for (auto &bc : bcInfos) + { + bc.TagVertices(cgid, mesh, globalToVert); + } + + if (PCU_Comm_Initialized()) + cgp_close(cgid); + else + cg_close(cgid); + return mesh; } } // namespace From 7d106e16ea54509623604969e8f92f82afe77166 Mon Sep 17 00:00:00 2001 From: a-jp Date: Thu, 17 Oct 2019 10:52:00 +0100 Subject: [PATCH 10/72] drop to c++14 from c++17 as I suspect I'll not get away with it... --- CMakeLists.txt | 10 +++++----- cmake/bob.cmake | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 683995a70..21880f4e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,8 +22,8 @@ if(USE_XSDK_DEFAULTS) xsdk_compiler_flags() endif() -# require c++17 -option(ENABLE_CGNS "Enable the CGNS reader: requires c++17 extensions" OFF) +# require c++14 +option(ENABLE_CGNS "Enable the CGNS reader: requires c++14 extensions" OFF) message(STATUS "ENABLE_CGNS: ${ENABLE_CGNS}") # Set some default compiler flags that should always be used @@ -34,13 +34,13 @@ if(NOT USE_XSDK_DEFAULTS) set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS}") if(SCOREC_ENABLE_CXX11) if(ENABLE_CGNS) - bob_cxx17_flags() + bob_cxx14_flags() else() - bob_cxx11_flags() + bob_cxx14_flags() endif() else() if(ENABLE_CGNS) - bob_cxx17_flags() + bob_cxx14_flags() endif() endif() endif() diff --git a/cmake/bob.cmake b/cmake/bob.cmake index 278ed7a9a..cc426ea97 100644 --- a/cmake/bob.cmake +++ b/cmake/bob.cmake @@ -86,16 +86,16 @@ function(bob_cxx11_flags) set(CMAKE_CXX_FLAGS "${FLAGS}" PARENT_SCOPE) endfunction(bob_cxx11_flags) -function(bob_cxx17_flags) +function(bob_cxx14_flags) set(FLAGS "${CMAKE_CXX_FLAGS}") - set(FLAGS "${FLAGS} --std=c++17") + set(FLAGS "${FLAGS} --std=c++14") if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") if (${PROJECT_NAME}_CXX_WARNINGS) set(FLAGS "${FLAGS} -Wno-c++98-compat-pedantic -Wno-c++98-compat") endif() endif() set(CMAKE_CXX_FLAGS "${FLAGS}" PARENT_SCOPE) -endfunction(bob_cxx17_flags) +endfunction(bob_cxx14_flags) function(bob_end_cxx_flags) set(${PROJECT_NAME}_CXX_FLAGS "" CACHE STRING "Override all C++ compiler flags") From cc4c3d2fe0baf38a0b87e9ebfa95096585f9387b Mon Sep 17 00:00:00 2001 From: a-jp Date: Thu, 17 Oct 2019 10:54:40 +0100 Subject: [PATCH 11/72] don't use c++17 features --- mds/mdsCGNS.cc | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/mds/mdsCGNS.cc b/mds/mdsCGNS.cc index 39a39143c..2e1035d92 100644 --- a/mds/mdsCGNS.cc +++ b/mds/mdsCGNS.cc @@ -40,10 +40,12 @@ namespace { -#ifndef NDEBUG // debug, cmake double negative -static constexpr bool debugOutput = true; -#else // optimised -static constexpr bool debugOutput = false; +#ifndef NDEBUG // debug settings, cmake double negative.... +const bool debugOutput = true; // probably will not get away with c++17 +//static constexpr bool debugOutput = true; // probably will not get away with c++17 +#else // optimised setting +const bool debugOutput = false; // probably will not get away with c++17 +//static constexpr bool debugOutput = false; // probably will not get away with c++17 #endif static std::string SupportedCGNSElementTypeToString(const CGNS_ENUMT(ElementType_t) & elementType) @@ -76,14 +78,17 @@ static std::string SupportedCGNSElementTypeToString(const CGNS_ENUMT(ElementType template void DebugParallelPrinter(std::ostream &out, Arg &&arg, Args &&... args) { - if constexpr (debugOutput) + // if constexpr (debugOutput) // probably will not get away with c++17 + if (debugOutput) { for (int i = 0; i < PCU_Comm_Peers(); i++) { if (i == PCU_Comm_Self()) { out << "Rank [" << i << "] " << std::forward(arg); - ((out << ", " << std::forward(args)), ...); + //((out << ", " << std::forward(args)), ...); // probably will not get away with c++17 + using expander = int[]; + (void)expander{0, (void(out << ", " << std::forward(args)), 0)...}; out << "\n"; out << std::flush; } @@ -303,7 +308,8 @@ struct CGNSBCMeta std::cout << "BC named: " << bocoName << ", located on: " << locationName << std::endl; std::cout << "\tHas " << npnts << " elements on the bc stored as a " << cg_PointSetTypeName(ptsetType) << std::endl; std::cout << "\tThe min and max Element Ids for this bcs are: " << minElementId << " " << maxElementId << std::endl; - if constexpr (debugOutput) + if (debugOutput) + //if constexpr (debugOutput)// probably will not get away with c++17 { std::cout << "\tThe element Ids that are tagged with this bcs are: "; for (const auto &i : bcElementIds) @@ -347,8 +353,11 @@ struct BCInfo } } + if (debugOutput) + //if constexpr (debugOutput) // probably will not get away with c++17 { - apf::MeshEntity *elem; + // for debug output, tags aren't written to vtk... + apf::MeshEntity *elem = nullptr; apf::MeshIterator *it = m->begin(0); field = apf::createFieldOn(m, bcName.c_str(), apf::SCALAR); From 9e06849ce022c52d9ebe79634af73b06966634cf Mon Sep 17 00:00:00 2001 From: a-jp Date: Thu, 17 Oct 2019 10:55:05 +0100 Subject: [PATCH 12/72] ensure ptrs are null initialised --- test/cgns.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cgns.cc b/test/cgns.cc index 41a7c3d4e..05fa9721e 100644 --- a/test/cgns.cc +++ b/test/cgns.cc @@ -20,7 +20,7 @@ apf::MeshTag *create_int_tag(const std::string &name, apf::Mesh *m, int dim) { apf::MeshTag *tag = m->createIntTag(name.c_str(), 1); // 1 is size of tag - apf::MeshEntity *elem; + apf::MeshEntity *elem = nullptr; apf::MeshIterator *it = m->begin(dim); int vals[1]; vals[0] = PCU_Comm_Self(); @@ -33,7 +33,7 @@ apf::MeshTag *create_int_tag(const std::string &name, apf::Mesh *m, int dim) //https://github.com/CEED/PUMI/blob/master/ma/maDBG.cc apf::Field *convert_tag_doubleField(const std::string &name, apf::Mesh *m, apf::MeshTag *t, int dim) { - apf::MeshEntity *elem; + apf::MeshEntity *elem = nullptr; apf::MeshIterator *it = m->begin(dim); apf::Field *f = nullptr; const auto fieldName = name.c_str(); From 894dc7a70418d1c36fd5777311863623b82461b8 Mon Sep 17 00:00:00 2001 From: a-jp Date: Thu, 17 Oct 2019 11:35:43 +0100 Subject: [PATCH 13/72] fix bugs when cgns is not enabled --- mds/CMakeLists.txt | 7 +++++-- mds/pkg_tribits.cmake | 5 ++++- test/testing.cmake | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/mds/CMakeLists.txt b/mds/CMakeLists.txt index 1cf883ef7..528c92525 100644 --- a/mds/CMakeLists.txt +++ b/mds/CMakeLists.txt @@ -28,10 +28,13 @@ set(SOURCES apfBox.cc mdsANSYS.cc mdsGmsh.cc - mdsCGNS.cc mdsUgrid.cc ) +if(ENABLE_CGNS) + set(SOURCES ${SOURCES} mdsCGNS.cc) +endif(ENABLE_CGNS) + # Package headers set(HEADERS apfMDS.h @@ -63,7 +66,7 @@ target_link_libraries(mds if(ENABLE_CGNS) message(STATUS ${CGNS_LIBRARIES}) target_link_libraries(mds PRIVATE ${CGNS_LIBRARIES} ${HDF5_LIBRARIES} ${HDF5_HL_LIBRARIES}) -endif() +endif(ENABLE_CGNS) scorec_export_library(mds) diff --git a/mds/pkg_tribits.cmake b/mds/pkg_tribits.cmake index eb66734a8..07211c87b 100644 --- a/mds/pkg_tribits.cmake +++ b/mds/pkg_tribits.cmake @@ -20,9 +20,12 @@ set(MDS_SOURCES apfBox.cc mdsANSYS.cc mdsGmsh.cc - mdsCGNS.cc mdsUgrid.cc) +if(ENABLE_CGNS) + set(MDS_SOURCES ${MDS_SOURCES} mdsCGNS.cc) +endif(ENABLE_CGNS) + set(MDS_HEADERS apfMDS.h apfBox.h diff --git a/test/testing.cmake b/test/testing.cmake index e7aba1205..68de6746b 100644 --- a/test/testing.cmake +++ b/test/testing.cmake @@ -504,7 +504,7 @@ mpi_test(cgns_bcs_1 ${numProcs} "${CGNSDIR}/Mesh_3.adf.hdf.cgns" bcs1.smb additional) -endif() +endif(ENABLE_CGNS) mpi_test(construct 4 ./construct From a3578f6816b2f18f623fcd55dc8b83ffa31dd98a Mon Sep 17 00:00:00 2001 From: a-jp Date: Thu, 17 Oct 2019 13:35:53 +0100 Subject: [PATCH 14/72] append release/debug on output files to ensure both compile modes don't overwrite debugging files --- test/cgns.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test/cgns.cc b/test/cgns.cc index 05fa9721e..52d9db738 100644 --- a/test/cgns.cc +++ b/test/cgns.cc @@ -219,8 +219,14 @@ int main(int argc, char **argv) // so we can see the result const std::string path = argv[1]; std::size_t found = path.find_last_of("/\\"); - const auto prefix = path.substr(found + 1); - const auto name = prefix + std::string("_toVTK"); + +#ifndef NDEBUG // debug settings, cmake double negative.... + const auto prefix = path.substr(found + 1) + "_debug"; +#else // optimised setting + const auto prefix = path.substr(found + 1) + "_release"; +#endif + + const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK"); std::cout << path << " " << found << " " << name << std::endl; apf::writeVtkFiles(name.c_str(), m); From 3379f97aa3bc018e335a8f878dfbfae77773772c Mon Sep 17 00:00:00 2001 From: a-jp Date: Thu, 17 Oct 2019 13:42:29 +0100 Subject: [PATCH 15/72] expose cgns bc map to user and require this be passed in --- mds/apfMDS.h | 10 +++++++++- test/cgns.cc | 5 +++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/mds/apfMDS.h b/mds/apfMDS.h index a6ec63866..1f150fb6f 100644 --- a/mds/apfMDS.h +++ b/mds/apfMDS.h @@ -41,6 +41,7 @@ class Mesh2; class MeshTag; class MeshEntity; class Migration; +class Field; /** \brief a map from global ids to vertex objects */ typedef std::map GlobalToVert; @@ -192,7 +193,14 @@ int getMdsIndex(Mesh2* in, MeshEntity* e); so call apf::reorderMdsMesh after any mesh modification. */ MeshEntity* getMdsEntity(Mesh2* in, int dimension, int index); -Mesh2* loadMdsFromCGNS(gmi_model* g, const char* filename); +// Key [String] = Vertex/EdgeCenter/FaceCenter/CellCenter +// Value [vector of Pairs per Key]; Pairs = cgns_bc_name, field value. +// Field value holds [0, 1] as a +// marker to indicate mesh_entities +// within bc group 1="in group", 0="not in group" +// Fields set on vertices, edges, faces, and cells +using CGNSBCMap = std::map>>; +Mesh2* loadMdsFromCGNS(gmi_model* g, const char* filename, CGNSBCMap& cgnsBCMap); Mesh2* loadMdsFromGmsh(gmi_model* g, const char* filename); diff --git a/test/cgns.cc b/test/cgns.cc index 52d9db738..f21a52718 100644 --- a/test/cgns.cc +++ b/test/cgns.cc @@ -54,7 +54,7 @@ apf::Field *convert_tag_doubleField(const std::string &name, apf::Mesh *m, apf:: return f; } -void balance(const std::string &prefix, const apf::ZoltanMethod& method, apf::Mesh2 *m) +void balance(const std::string &prefix, const apf::ZoltanMethod &method, apf::Mesh2 *m) { const auto dim = m->getDimension(); convert_tag_doubleField("procID_prebalance", m, create_int_tag("procID_prebalance", m, dim), dim); @@ -212,7 +212,8 @@ int main(int argc, char **argv) gmi_register_null(); gmi_register_mesh(); gmi_model *g = gmi_load(".null"); - apf::Mesh2 *m = apf::loadMdsFromCGNS(g, argv[1]); + apf::CGNSBCMap cgnsBCMap; + apf::Mesh2 *m = apf::loadMdsFromCGNS(g, argv[1], cgnsBCMap); m->verify(); // m->writeNative(argv[2]); From b99dc988d3a4640009b12881229d4b7670b2d2a9 Mon Sep 17 00:00:00 2001 From: a-jp Date: Thu, 17 Oct 2019 14:00:51 +0100 Subject: [PATCH 16/72] require cgnsBCMap to be passed around --- mds/mdsCGNS.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mds/mdsCGNS.cc b/mds/mdsCGNS.cc index 2e1035d92..c9c83ef23 100644 --- a/mds/mdsCGNS.cc +++ b/mds/mdsCGNS.cc @@ -567,7 +567,7 @@ void ReadBCInfo(const int cgid, const int base, const int zone, const int nBocos } } -apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname) +apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCMap) { int cgid = -1; auto comm = PCU_Get_Comm(); @@ -779,10 +779,10 @@ namespace apf { // caller needs to bring up and pull down mpi/pcu: mpi/pcu is required and assumed. -Mesh2 *loadMdsFromCGNS(gmi_model *g, const char *fname) +Mesh2 *loadMdsFromCGNS(gmi_model *g, const char *fname, apf::CGNSBCMap &cgnsBCMap) { #ifdef HAVE_CGNS - Mesh2 *m = DoIt(g, fname); + Mesh2 *m = DoIt(g, fname, cgnsBCMap); return m; #else Mesh2 *m = nullptr; From f650acd8e6e10d42dd0904ac4a7f3ea8eab8e931 Mon Sep 17 00:00:00 2001 From: a-jp Date: Thu, 17 Oct 2019 14:02:21 +0100 Subject: [PATCH 17/72] tag vertices, edges, faces, cells with a field named by the user defined cgns BC name indicating whether or not those mesh entities are within those BC groups --- mds/mdsCGNS.cc | 457 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 454 insertions(+), 3 deletions(-) diff --git a/mds/mdsCGNS.cc b/mds/mdsCGNS.cc index c9c83ef23..d836b3cfa 100644 --- a/mds/mdsCGNS.cc +++ b/mds/mdsCGNS.cc @@ -45,7 +45,7 @@ const bool debugOutput = true; // probably will not get away with c++17 //static constexpr bool debugOutput = true; // probably will not get away with c++17 #else // optimised setting const bool debugOutput = false; // probably will not get away with c++17 -//static constexpr bool debugOutput = false; // probably will not get away with c++17 + //static constexpr bool debugOutput = false; // probably will not get away with c++17 #endif static std::string SupportedCGNSElementTypeToString(const CGNS_ENUMT(ElementType_t) & elementType) @@ -327,6 +327,14 @@ struct BCInfo apf::MeshTag *tag = nullptr; apf::Field *field = nullptr; + void Clean(apf::Mesh *m) + { + m->removeField(field); + apf::destroyField(field); + apf::removeTagFromDimension(m, tag, 0); + m->destroyTag(tag); + } + void TagVertices(const int cgid, apf::Mesh *m, apf::GlobalToVert &globalToVert) { tag = m->createIntTag(bcName.c_str(), 1); // 1 is size of tag @@ -362,17 +370,455 @@ struct BCInfo field = apf::createFieldOn(m, bcName.c_str(), apf::SCALAR); int vals[1]; + double dval[1]; while ((elem = m->iterate(it))) { m->getIntTag(elem, tag, vals); - double dval[1]; dval[0] = vals[0]; apf::setComponents(field, elem, 0, dval); } m->end(it); } + + // Notes: + // I do not exchange the tag values (even if that can be done). + // I'm assuming in parallel all partition that need the vertex that + // falls within a given group mark that vertex accordingly. + // I assume therefore that vertices on a processor boundary, are marked + // by all procs that share it. + // TODO: generate test that proves this works } -}; + + /** + * Meanings/concept follows: https://cgns.github.io/CGNS_docs_current/sids/misc.html section 12.4 + +---------------+--------------+--------------+--------------+-------------------------+ + | | GridLocation | GridLocation | GridLocation | GridLocation | + +---------------+--------------+--------------+--------------+-------------------------+ + | CellDimension | Vertex | EdgeCenter | *FaceCenter | CellCenter | + | 1 | vertices | - | - | cells (line elements) | + | 2 | vertices | edges | - | cells (area elements) | + | 3 | vertices | edges | faces | cells (volume elements) | + +---------------+--------------+--------------+--------------+-------------------------+ + **/ + void TagBCEntities(const int cgid, apf::Mesh *m, apf::CGNSBCMap &cgnsBCMap) + { + if (m->getDimension() == 3) // working with a 3D mesh + { + if (cgnsLocation == "Vertex") + { + apf::Field *field = nullptr; + const std::string fieldName = "VertBC_" + bcName; + field = apf::createFieldOn(m, fieldName.c_str(), apf::SCALAR); + + double dval[1]; + dval[0] = 0.0; + apf::MeshIterator *vertIter = m->begin(0); + apf::MeshEntity *vert = nullptr; + while ((vert = m->iterate(vertIter))) + { + apf::setComponents(field, vert, 0, dval); + } + m->end(vertIter); + + int vals[1]; + vertIter = m->begin(0); + while ((vert = m->iterate(vertIter))) + { + bool allTagged = true; + m->getIntTag(vert, tag, vals); + if (vals[0] == 0) + allTagged = false; + + if (allTagged) + { + std::cout << "Flagged vertices " << 1 << " " << allTagged << std::endl; + dval[0] = 1.0; + apf::setComponents(field, vert, 0, dval); + } + } + auto iter = cgnsBCMap["Vertex"]; + iter.push_back(std::make_pair(fieldName, field)); + } + else if (cgnsLocation == "EdgeCenter") + { + apf::Field *field = nullptr; + const std::string fieldName = "EdgeBC_" + bcName; + field = apf::createField(m, fieldName.c_str(), apf::SCALAR, apf::getConstant(1)); + + double dval[1]; + dval[0] = 0.0; + apf::MeshIterator *edgeIter = m->begin(1); + apf::MeshEntity *edge = nullptr; + while ((edge = m->iterate(edgeIter))) + { + apf::setComponents(field, edge, 0, dval); + } + m->end(edgeIter); + + apf::Downward verts; + int vals[1]; + edgeIter = m->begin(1); + while ((edge = m->iterate(edgeIter))) + { + const auto numVerts = m->getDownward(edge, 0, verts); + bool allTagged = true; + for (int i = 0; i < numVerts; i++) + { + m->getIntTag(verts[i], tag, vals); + if (vals[0] == 0) + allTagged = false; + } + if (allTagged) + { + //std::cout << "Flagged edges " << numVerts << " " << allTagged << std::endl; + dval[0] = 1.0; + apf::setComponents(field, edge, 0, dval); + } + } + auto iter = cgnsBCMap["EdgeCenter"]; + iter.push_back(std::make_pair(fieldName, field)); + } + else if (cgnsLocation == "FaceCenter") + { + apf::Field *field = nullptr; + const std::string fieldName = "FaceBC_" + bcName; + field = apf::createField(m, fieldName.c_str(), apf::SCALAR, apf::getConstant(2)); + + double dval[1]; + dval[0] = 0.0; + apf::MeshIterator *faceIter = m->begin(2); + apf::MeshEntity *face = nullptr; + while ((face = m->iterate(faceIter))) + { + apf::setComponents(field, face, 0, dval); + } + m->end(faceIter); + + apf::Downward verts; + faceIter = m->begin(2); + int vals[1]; + while ((face = m->iterate(faceIter))) + { + const auto numVerts = m->getDownward(face, 0, verts); + bool allTagged = true; + for (int i = 0; i < numVerts; i++) + { + m->getIntTag(verts[i], tag, vals); + if (vals[0] == 0) + allTagged = false; + } + if (allTagged) + { + //std::cout << "Flagged faces " << numVerts << " " << allTagged << std::endl; + dval[0] = 1.0; + apf::setComponents(field, face, 0, dval); + } + } + auto iter = cgnsBCMap["FaceCenter"]; + iter.push_back(std::make_pair(fieldName, field)); + } + else if (cgnsLocation == "CellCenter") + { + { + apf::Field *field = nullptr; + const std::string fieldName = "CellBC_" + bcName; + field = apf::createField(m, fieldName.c_str(), apf::SCALAR, apf::getConstant(3)); + + double dval[1]; + dval[0] = 0.0; + apf::MeshIterator *cellIter = m->begin(3); + apf::MeshEntity *cell = nullptr; + while ((cell = m->iterate(cellIter))) + { + apf::setComponents(field, cell, 0, dval); + } + m->end(cellIter); + + apf::Downward verts; + cellIter = m->begin(3); + int vals[1]; + while ((cell = m->iterate(cellIter))) + { + const auto numVerts = m->getDownward(cell, 0, verts); + bool allTagged = true; + for (int i = 0; i < numVerts; i++) + { + m->getIntTag(verts[i], tag, vals); + if (vals[0] == 0) + allTagged = false; + } + if (allTagged) + { + //std::cout << "Flagged cells " << numVerts << " " << allTagged << std::endl; + dval[0] = 1.0; + apf::setComponents(field, cell, 0, dval); + } + } + auto iter = cgnsBCMap["CellCenter"]; + iter.push_back(std::make_pair(fieldName, field)); + } + // { // more verbose example of iterating the mesh + // apf::Field *field = nullptr; + // const std::string fieldName = "CellBC_other_" + bcName; + // field = apf::createField(m, fieldName.c_str(), apf::SCALAR, apf::getConstant(3)); + + // double dval[1]; + // dval[0] = 0.0; + // apf::MeshIterator *cellIter = m->begin(3); + // apf::MeshEntity *cell = nullptr; + // while ((cell = m->iterate(cellIter))) + // { + // apf::setComponents(field, cell, 0, dval); + // } + // m->end(cellIter); + + // apf::Downward faces; + // apf::Downward edges; + // apf::Downward verts; + // cellIter = m->begin(3); + // int vals[1]; + // while ((cell = m->iterate(cellIter))) + // { + // bool allTagged = true; + // const auto numFaces = m->getDownward(cell, 2, faces); + // for (int f = 0; f < numFaces; f++) + // { + // const auto numEdges = m->getDownward(faces[f], 1, edges); + // for (int e = 0; e < numEdges; e++) + // { + // const auto numVerts = m->getDownward(edges[e], 0, verts); + // for (int i = 0; i < numVerts; i++) + // { + // m->getIntTag(verts[i], tag, vals); + // if (vals[0] == 0) + // allTagged = false; + // } + // } + // } + // if (allTagged) + // { + // std::cout << "Flagged cells " << allTagged << std::endl; + // dval[0] = 1.0; + // apf::setComponents(field, cell, 0, dval); + // } + // } + // auto iter = cgnsBCMap["CellCenter"]; + // iter.push_back(std::make_pair(fieldName, field)); + // } + } + else + Kill(cgid, "Unknown BC Type", cgnsLocation); + } + else if (m->getDimension() == 2) // working with a 2D mesh + { + if (cgnsLocation == "Vertex") + { + apf::Field *field = nullptr; + const std::string fieldName = "VertBC_" + bcName; + field = apf::createFieldOn(m, fieldName.c_str(), apf::SCALAR); + + double dval[1]; + dval[0] = 0.0; + apf::MeshIterator *vertIter = m->begin(0); + apf::MeshEntity *vert = nullptr; + while ((vert = m->iterate(vertIter))) + { + apf::setComponents(field, vert, 0, dval); + } + m->end(vertIter); + + int vals[1]; + vertIter = m->begin(0); + while ((vert = m->iterate(vertIter))) + { + bool allTagged = true; + m->getIntTag(vert, tag, vals); + if (vals[0] == 0) + allTagged = false; + + if (allTagged) + { + std::cout << "Flagged vertices " << 1 << " " << allTagged << std::endl; + dval[0] = 1.0; + apf::setComponents(field, vert, 0, dval); + } + } + auto iter = cgnsBCMap["Vertex"]; + iter.push_back(std::make_pair(fieldName, field)); + } + else if (cgnsLocation == "EdgeCenter") + { + apf::Field *field = nullptr; + const std::string fieldName = "EdgeBC_" + bcName; + field = apf::createField(m, fieldName.c_str(), apf::SCALAR, apf::getConstant(1)); + + double dval[1]; + dval[0] = 0.0; + apf::MeshIterator *edgeIter = m->begin(1); + apf::MeshEntity *edge = nullptr; + while ((edge = m->iterate(edgeIter))) + { + apf::setComponents(field, edge, 0, dval); + } + m->end(edgeIter); + + apf::Downward verts; + int vals[1]; + edgeIter = m->begin(1); + while ((edge = m->iterate(edgeIter))) + { + const auto numVerts = m->getDownward(edge, 0, verts); + bool allTagged = true; + for (int i = 0; i < numVerts; i++) + { + m->getIntTag(verts[i], tag, vals); + if (vals[0] == 0) + allTagged = false; + } + if (allTagged) + { + //std::cout << "Flagged edges " << numVerts << " " << allTagged << std::endl; + dval[0] = 1.0; + apf::setComponents(field, edge, 0, dval); + } + } + auto iter = cgnsBCMap["EdgeCenter"]; + iter.push_back(std::make_pair(fieldName, field)); + } + else if (cgnsLocation == "FaceCenter") + { + PCU_ALWAYS_ASSERT_VERBOSE(true == false, "Can't have a FaceCenter BC in a 2D mesh"); + } + else if (cgnsLocation == "CellCenter") + { + apf::Field *field = nullptr; + const std::string fieldName = "CellBC_" + bcName; + field = apf::createField(m, fieldName.c_str(), apf::SCALAR, apf::getConstant(2)); + + double dval[1]; + dval[0] = 0.0; + apf::MeshIterator *cellIter = m->begin(2); + apf::MeshEntity *cell = nullptr; + while ((cell = m->iterate(cellIter))) + { + apf::setComponents(field, cell, 0, dval); + } + m->end(cellIter); + + apf::Downward verts; + cellIter = m->begin(2); + int vals[1]; + while ((cell = m->iterate(cellIter))) + { + const auto numVerts = m->getDownward(cell, 0, verts); + bool allTagged = true; + for (int i = 0; i < numVerts; i++) + { + m->getIntTag(verts[i], tag, vals); + if (vals[0] == 0) + allTagged = false; + } + if (allTagged) + { + //std::cout << "Flagged cells " << numVerts << " " << allTagged << std::endl; + dval[0] = 1.0; + apf::setComponents(field, cell, 0, dval); + } + } + auto iter = cgnsBCMap["CellCenter"]; + iter.push_back(std::make_pair(fieldName, field)); + } + } + else if (m->getDimension() == 1) // working with a 1D mesh + { + if (cgnsLocation == "Vertex") + { + apf::Field *field = nullptr; + const std::string fieldName = "VertBC_" + bcName; + field = apf::createFieldOn(m, fieldName.c_str(), apf::SCALAR); + + double dval[1]; + dval[0] = 0.0; + apf::MeshIterator *vertIter = m->begin(0); + apf::MeshEntity *vert = nullptr; + while ((vert = m->iterate(vertIter))) + { + apf::setComponents(field, vert, 0, dval); + } + m->end(vertIter); + + int vals[1]; + vertIter = m->begin(0); + while ((vert = m->iterate(vertIter))) + { + bool allTagged = true; + m->getIntTag(vert, tag, vals); + if (vals[0] == 0) + allTagged = false; + + if (allTagged) + { + std::cout << "Flagged vertices " << 1 << " " << allTagged << std::endl; + dval[0] = 1.0; + apf::setComponents(field, vert, 0, dval); + } + } + auto iter = cgnsBCMap["Vertex"]; + iter.push_back(std::make_pair(fieldName, field)); + } + else if (cgnsLocation == "EdgeCenter") + { + PCU_ALWAYS_ASSERT_VERBOSE(true == false, "Can't have a EdgeCenter BC in a 1D mesh"); + } + else if (cgnsLocation == "FaceCenter") + { + PCU_ALWAYS_ASSERT_VERBOSE(true == false, "Can't have a FaceCenter BC in a 1D mesh"); + } + else if (cgnsLocation == "CellCenter") + { + apf::Field *field = nullptr; + const std::string fieldName = "CellBC_" + bcName; + field = apf::createField(m, fieldName.c_str(), apf::SCALAR, apf::getConstant(1)); + + double dval[1]; + dval[0] = 0.0; + apf::MeshIterator *cellIter = m->begin(1); + apf::MeshEntity *cell = nullptr; + while ((cell = m->iterate(cellIter))) + { + apf::setComponents(field, cell, 0, dval); + } + m->end(cellIter); + + apf::Downward verts; + cellIter = m->begin(1); + int vals[1]; + while ((cell = m->iterate(cellIter))) + { + const auto numVerts = m->getDownward(cell, 0, verts); + bool allTagged = true; + for (int i = 0; i < numVerts; i++) + { + m->getIntTag(verts[i], tag, vals); + if (vals[0] == 0) + allTagged = false; + } + if (allTagged) + { + //std::cout << "Flagged cells " << numVerts << " " << allTagged << std::endl; + dval[0] = 1.0; + apf::setComponents(field, cell, 0, dval); + } + } + auto iter = cgnsBCMap["CellCenter"]; + iter.push_back(std::make_pair(fieldName, field)); + } + } + + if (!debugOutput) + Clean(m); + } +}; // namespace void ReadBCInfo(const int cgid, const int base, const int zone, const int nBocos, const int physDim, const int cellDim, const int nsections, std::vector &bcInfos, const apf::GlobalToVert &globalToVert) { @@ -766,6 +1212,11 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM bc.TagVertices(cgid, mesh, globalToVert); } + for (auto &bc : bcInfos) + { + bc.TagBCEntities(cgid, mesh, cgnsBCMap); + } + if (PCU_Comm_Initialized()) cgp_close(cgid); else From bea636eef84cc20f72f27a7951a77578e7ad1e6d Mon Sep 17 00:00:00 2001 From: a-jp Date: Thu, 17 Oct 2019 14:30:46 +0100 Subject: [PATCH 18/72] include additional bcs test --- test/testing.cmake | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/test/testing.cmake b/test/testing.cmake index 68de6746b..3f7db10d7 100644 --- a/test/testing.cmake +++ b/test/testing.cmake @@ -458,7 +458,8 @@ set(numProcs 4) # set(CGNSDIR ${MESHES}/cgns/basic) # -# 2D +# 2D tests including for mixed cells +# mpi_test(cgns_2d_1 ${numProcs} ./from_cgns "${CGNSDIR}/2D/4quads.adf.hdf.cgns" @@ -480,7 +481,7 @@ mpi_test(cgns_2d_4 ${numProcs} 9tris.smb additional) # -# 3D +# 3D tests including for mixed cells # mpi_test(cgns_3d_1 ${numProcs} ./from_cgns @@ -493,7 +494,7 @@ mpi_test(cgns_3d_2 ${numProcs} hexs.smb additional) # -# BCS tests +# 3D BCS tests # set(numProcs 5) # @@ -504,6 +505,31 @@ mpi_test(cgns_bcs_1 ${numProcs} "${CGNSDIR}/Mesh_3.adf.hdf.cgns" bcs1.smb additional) +# +# 2D BCS tests +# +set(numProcs 4) +# +set(CGNSDIR ${MESHES}/cgns/withBCS/2D) +# +mpi_test(cgns_bcs_2 ${numProcs} + ./from_cgns + "${CGNSDIR}/Mesh_4.adf.hdf.cgns" + bcs2.smb + additional) +# +# 1D BCS tests +# +set(numProcs 3) +# +set(CGNSDIR ${MESHES}/cgns/withBCS/1D) +# +mpi_test(cgns_bcs_3 ${numProcs} + ./from_cgns + "${CGNSDIR}/Mesh_5.adf.hdf.cgns" + bcs3.smb + additional) + endif(ENABLE_CGNS) mpi_test(construct 4 From 66168b1ff0a885166d92deb24ae3fd6fd553ab7c Mon Sep 17 00:00:00 2001 From: a-jp Date: Thu, 17 Oct 2019 15:49:17 +0100 Subject: [PATCH 19/72] write lower dimensional data --- test/cgns.cc | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/test/cgns.cc b/test/cgns.cc index f21a52718..86b03393d 100644 --- a/test/cgns.cc +++ b/test/cgns.cc @@ -227,9 +227,26 @@ int main(int argc, char **argv) const auto prefix = path.substr(found + 1) + "_release"; #endif - const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK"); - std::cout << path << " " << found << " " << name << std::endl; - apf::writeVtkFiles(name.c_str(), m); + const auto dim = m->getDimension(); + if (dim == 3) + { + { + const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK_cellMesh"); + apf::writeVtkFiles(name.c_str(), m, 3); + } + { + const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK_faceMesh"); + apf::writeVtkFiles(name.c_str(), m, 2); + } + { + const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK_edgeMesh"); + apf::writeVtkFiles(name.c_str(), m, 1); + } + { + const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK_vertexMesh"); + apf::writeVtkFiles(name.c_str(), m, 0); + } + } // main purpose is to call additional tests through the test harness testing.cmake if (additionalTests) From 116da26c2c4f2ee00f45fbf82f5c0070f042cd15 Mon Sep 17 00:00:00 2001 From: a-jp Date: Fri, 18 Oct 2019 10:21:14 +0100 Subject: [PATCH 20/72] be consistent: use Mesh2 not Mesh --- mds/mdsCGNS.cc | 20 ++++++++++---------- test/cgns.cc | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/mds/mdsCGNS.cc b/mds/mdsCGNS.cc index d836b3cfa..825620a98 100644 --- a/mds/mdsCGNS.cc +++ b/mds/mdsCGNS.cc @@ -327,7 +327,7 @@ struct BCInfo apf::MeshTag *tag = nullptr; apf::Field *field = nullptr; - void Clean(apf::Mesh *m) + void Clean(apf::Mesh2 *m) { m->removeField(field); apf::destroyField(field); @@ -335,7 +335,7 @@ struct BCInfo m->destroyTag(tag); } - void TagVertices(const int cgid, apf::Mesh *m, apf::GlobalToVert &globalToVert) + void TagVertices(const int cgid, apf::Mesh2 *m, apf::GlobalToVert &globalToVert) { tag = m->createIntTag(bcName.c_str(), 1); // 1 is size of tag apf::MeshEntity *elem = nullptr; @@ -400,7 +400,7 @@ struct BCInfo | 3 | vertices | edges | faces | cells (volume elements) | +---------------+--------------+--------------+--------------+-------------------------+ **/ - void TagBCEntities(const int cgid, apf::Mesh *m, apf::CGNSBCMap &cgnsBCMap) + void TagBCEntities(const int cgid, apf::Mesh2 *m, apf::CGNSBCMap &cgnsBCMap) { if (m->getDimension() == 3) // working with a 3D mesh { @@ -1115,7 +1115,7 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM cg_npe(elementType, &verticesPerElement); - const auto readElementsAndVerts = [&](const apf::Mesh::Type &type) { + const auto readElementsAndVerts = [&](const apf::Mesh2::Type &type) { const auto &ret = ReadElements(cgid, base, zone, section, el_start, el_end, numElements, verticesPerElement); if (std::get<1>(ret) > 0) { @@ -1146,32 +1146,32 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM if (elementType == CGNS_ENUMV(BAR_2)) { if (readDim == 1) - readElementsAndVerts(apf::Mesh::EDGE); + readElementsAndVerts(apf::Mesh2::EDGE); } else if (elementType == CGNS_ENUMV(QUAD_4)) { if (readDim == 2) - readElementsAndVerts(apf::Mesh::QUAD); + readElementsAndVerts(apf::Mesh2::QUAD); } else if (elementType == CGNS_ENUMV(TRI_3)) { if (readDim == 2) - readElementsAndVerts(apf::Mesh::TRIANGLE); + readElementsAndVerts(apf::Mesh2::TRIANGLE); } else if (elementType == CGNS_ENUMV(TETRA_4)) { if (readDim == 3) - readElementsAndVerts(apf::Mesh::TET); + readElementsAndVerts(apf::Mesh2::TET); } else if (elementType == CGNS_ENUMV(PYRA_5)) { if (readDim == 3) - readElementsAndVerts(apf::Mesh::PYRAMID); + readElementsAndVerts(apf::Mesh2::PYRAMID); } else if (elementType == CGNS_ENUMV(HEXA_8)) { if (readDim == 3) - readElementsAndVerts(apf::Mesh::HEX); + readElementsAndVerts(apf::Mesh2::HEX); } else { diff --git a/test/cgns.cc b/test/cgns.cc index 86b03393d..7a3f2baf5 100644 --- a/test/cgns.cc +++ b/test/cgns.cc @@ -17,7 +17,7 @@ #include // https://gist.github.com/bgranzow/98087114166956646da684ed98acab02 -apf::MeshTag *create_int_tag(const std::string &name, apf::Mesh *m, int dim) +apf::MeshTag *create_int_tag(const std::string &name, apf::Mesh2 *m, int dim) { apf::MeshTag *tag = m->createIntTag(name.c_str(), 1); // 1 is size of tag apf::MeshEntity *elem = nullptr; @@ -31,7 +31,7 @@ apf::MeshTag *create_int_tag(const std::string &name, apf::Mesh *m, int dim) } //https://github.com/CEED/PUMI/blob/master/ma/maDBG.cc -apf::Field *convert_tag_doubleField(const std::string &name, apf::Mesh *m, apf::MeshTag *t, int dim) +apf::Field *convert_tag_doubleField(const std::string &name, apf::Mesh2 *m, apf::MeshTag *t, int dim) { apf::MeshEntity *elem = nullptr; apf::MeshIterator *it = m->begin(dim); From 4ee59def9f68440fe741d571b7c5c388daa15fb1 Mon Sep 17 00:00:00 2001 From: a-jp Date: Fri, 18 Oct 2019 10:45:33 +0100 Subject: [PATCH 21/72] better cleanup --- test/cgns.cc | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/test/cgns.cc b/test/cgns.cc index 7a3f2baf5..7bbc61c61 100644 --- a/test/cgns.cc +++ b/test/cgns.cc @@ -120,14 +120,13 @@ pMesh toPumi(const std::string &prefix, gmi_model *g, apf::Mesh2 *mesh) return pm; } -void additional(const std::string &prefix, gmi_model *g, apf::Mesh2 *mesh) +auto additional(const std::string &prefix, gmi_model *g, apf::Mesh2 *mesh) { // seems essential to make pm first before calling balance or reorder... auto pm = toPumi(prefix, g, mesh); balance(prefix, apf::RCB, pm); simpleReorder(prefix, pm); - { //create an element field const int mdim = pumi_mesh_getDim(pm); pShape s = pumi_shape_getConstant(mdim); @@ -165,11 +164,13 @@ void additional(const std::string &prefix, gmi_model *g, apf::Mesh2 *mesh) // owned and ghosted elements will have a elmField value of 1 pumi_mesh_write(pm, (name + "_afterSync").c_str(), "vtk"); + const auto clean = [&pm, &f]() { // clean-up pumi_field_delete(f); pumi_ghost_delete(pm); pumi_mesh_delete(pm); - } + }; + return clean; } int main(int argc, char **argv) @@ -249,14 +250,17 @@ int main(int argc, char **argv) } // main purpose is to call additional tests through the test harness testing.cmake + std::function cleanUp; + if (additionalTests) + cleanUp = additional(prefix, g, m); + // + // if (additionalTests) - additional(prefix, g, m); + cleanUp(); - if (!additionalTests) - { m->destroyNative(); apf::destroyMesh(m); - } + // PCU_Comm_Free(); MPI_Finalize(); return 0; From 9988d171832ab7a11971a0aa7521e4f1ca091b1b Mon Sep 17 00:00:00 2001 From: a-jp Date: Fri, 18 Oct 2019 11:12:50 +0100 Subject: [PATCH 22/72] seems to cause memory leak --- test/cgns.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/cgns.cc b/test/cgns.cc index 7bbc61c61..da9dd2a56 100644 --- a/test/cgns.cc +++ b/test/cgns.cc @@ -256,10 +256,14 @@ int main(int argc, char **argv) // // if (additionalTests) - cleanUp(); - + { + //cleanUp(); + } + else if (!additionalTests) + { m->destroyNative(); apf::destroyMesh(m); + } // PCU_Comm_Free(); MPI_Finalize(); From 5dd96c5c49c44b8663e027e70de956ab3291d7b5 Mon Sep 17 00:00:00 2001 From: a-jp Date: Mon, 21 Oct 2019 14:11:27 +0100 Subject: [PATCH 23/72] protect build from cgns --- apf/CMakeLists.txt | 10 ++++++++++ apf/pkg_tribits.cmake | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/apf/CMakeLists.txt b/apf/CMakeLists.txt index 881a9fe65..ed2bb2140 100644 --- a/apf/CMakeLists.txt +++ b/apf/CMakeLists.txt @@ -49,6 +49,10 @@ set(SOURCES apfMIS.cc ) +if(ENABLE_CGNS) + set(SOURCES ${SOURCES} apfCGNS.cc) +endif(ENABLE_CGNS) + # Package headers set(HEADERS apf.h @@ -94,6 +98,12 @@ target_link_libraries(apf mth ) + +if(ENABLE_CGNS) + message(STATUS ${CGNS_LIBRARIES}) + target_link_libraries(apf PRIVATE ${CGNS_LIBRARIES} ${HDF5_LIBRARIES} ${HDF5_HL_LIBRARIES}) +endif(ENABLE_CGNS) + scorec_export_library(apf) bob_end_subdir() diff --git a/apf/pkg_tribits.cmake b/apf/pkg_tribits.cmake index a0c6cff0c..9e2d3d048 100644 --- a/apf/pkg_tribits.cmake +++ b/apf/pkg_tribits.cmake @@ -51,6 +51,10 @@ set(APF_SOURCES apfFile.cc ) +if(ENABLE_CGNS) + set(APF_SOURCES ${APF_SOURCES} apfCGNS.cc) +endif(ENABLE_CGNS) + set(APF_HEADERS apf.h apfMesh.h From ea7fe9e93800faed78d0fcaba39e64fe735e0827 Mon Sep 17 00:00:00 2001 From: a-jp Date: Mon, 21 Oct 2019 14:11:45 +0100 Subject: [PATCH 24/72] more build flags --- cmake/bob.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/bob.cmake b/cmake/bob.cmake index cc426ea97..6a5d6e556 100644 --- a/cmake/bob.cmake +++ b/cmake/bob.cmake @@ -88,7 +88,7 @@ endfunction(bob_cxx11_flags) function(bob_cxx14_flags) set(FLAGS "${CMAKE_CXX_FLAGS}") - set(FLAGS "${FLAGS} --std=c++14") + set(FLAGS "${FLAGS} --std=c++14 -Wall -Wextra -Wpedantic -Werror -Werror=return-stack-address -Werror=mismatched-tags -Wno-extra-semi -Werror=unused-parameter -Wno-error=deprecated-declarations") if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") if (${PROJECT_NAME}_CXX_WARNINGS) set(FLAGS "${FLAGS} -Wno-c++98-compat-pedantic -Wno-c++98-compat") From ce77904d88345a55762607ff9ae33a0a4bbc030e Mon Sep 17 00:00:00 2001 From: a-jp Date: Mon, 21 Oct 2019 14:12:49 +0100 Subject: [PATCH 25/72] write out lower dimension entities for 2D and 1D --- test/cgns.cc | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/test/cgns.cc b/test/cgns.cc index da9dd2a56..d9d2b2066 100644 --- a/test/cgns.cc +++ b/test/cgns.cc @@ -248,6 +248,32 @@ int main(int argc, char **argv) apf::writeVtkFiles(name.c_str(), m, 0); } } + else if(dim == 2) + { + { + const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK_cellMesh"); + apf::writeVtkFiles(name.c_str(), m, 2); + } + { + const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK_edgeMesh"); + apf::writeVtkFiles(name.c_str(), m, 1); + } + { + const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK_vertexMesh"); + apf::writeVtkFiles(name.c_str(), m, 0); + } + } + else if(dim == 1) + { + { + const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK_cellMesh"); + apf::writeVtkFiles(name.c_str(), m, 1); + } + { + const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK_vertexMesh"); + apf::writeVtkFiles(name.c_str(), m, 0); + } + } // main purpose is to call additional tests through the test harness testing.cmake std::function cleanUp; From 6a5ca5df847dcdbbbe059e2cf872b4d1ac60601c Mon Sep 17 00:00:00 2001 From: a-jp Date: Mon, 21 Oct 2019 15:39:07 +0100 Subject: [PATCH 26/72] initial cgns writer in parallel --- apf/apf.h | 10 ++ apf/apfCGNS.cc | 382 +++++++++++++++++++++++++++++++++++++++++++++++++ test/cgns.cc | 61 ++++---- 3 files changed, 423 insertions(+), 30 deletions(-) create mode 100644 apf/apfCGNS.cc diff --git a/apf/apf.h b/apf/apf.h index 1ab3ee30f..401e50f2b 100644 --- a/apf/apf.h +++ b/apf/apf.h @@ -13,6 +13,7 @@ #include "apfDynamicArray.h" #include +#include #include /** \file apf.h @@ -629,6 +630,15 @@ for (t::iterator i = (w).begin(); \ for (t::const_iterator i = (w).begin(); \ (i) != (w).end(); ++(i)) +/** \brief Write a CGNS file + * + * CGNSBCMap type is already defined in apfMDS.h. + * Would be better if there were a base include that this and apfMDS.h could include + * to stop this type being defined twice in two includes... +*/ +using CGNSBCMap = std::map>>; +void writeCGNS(const char* prefix, Mesh* m, const CGNSBCMap& cgnsBCMap); + /** \brief Write a set of parallel VTK Unstructured Mesh files from an apf::Mesh * with binary (base64) encoding and zlib compression (if LION_COMPRESS=ON) * \details Nodal fields whose shape differs from the mesh shape will diff --git a/apf/apfCGNS.cc b/apf/apfCGNS.cc new file mode 100644 index 000000000..0a14517f2 --- /dev/null +++ b/apf/apfCGNS.cc @@ -0,0 +1,382 @@ +/* + * Author: Dr Andrew Parker (2019) - FGE Ltd + * + * This work is open source software, licensed under the terms of the + * BSD license as described in the LICENSE file in the top-level directory. + */ + +#include +#include "apfMesh.h" +#include "apfNumbering.h" +#include "apfNumberingClass.h" +#include "apfShape.h" +#include "apfFieldData.h" +#include +#include +// +#include +#include +#include +#include +#include +#include +#include +#include + +// === includes for safe_mkdir === +#include +#include /*required for mode_t for mkdir on some systems*/ +#include /*using POSIX mkdir call for SMB "foo/" path*/ +#include /* for checking the error from mkdir */ +// =============================== + +#ifdef HAVE_CGNS +// +#include +#include +// +#endif + +namespace +{ +//https://proteustoolkit.org/capi/html/_parallel_mesh_converter_8cpp_source.html +static auto count(apf::Mesh *m, int dim) +{ + const int local = apf::countOwned(m, dim); + int total = local; + PCU_Add_Ints(&total, 1); // size of total array + return std::make_pair(total, local); +} + +// void ShowNumbering(apf::Mesh *m) +// { +// { +// apf::GlobalNumbering *gvn = nullptr; +// gvn = apf::makeGlobal(apf::numberOwnedNodes(m, "node-nums")); +// apf::synchronize(gvn); + +// for (int i = 0; i < PCU_Comm_Peers(); ++i) +// { +// if (i == PCU_Comm_Self()) +// { +// apf::MeshIterator *vertIter = m->begin(0); +// apf::MeshEntity *vert = nullptr; +// while ((vert = m->iterate(vertIter))) +// { +// if (m->isOwned(vert) && m->getOwner(vert) == i) +// { +// const auto n = apf::getNumber(gvn, vert, 0); +// std::cout << "Rank [vertex]: " << i << " " << n << " " << m->isOwned(vert) << " " << m->getOwner(vert) << std::endl; +// } +// } +// m->end(vertIter); + +// destroyGlobalNumbering(gvn); +// } +// PCU_Barrier(); +// } +// } +// std::cout << std::endl; +// PCU_Barrier(); +// { +// apf::GlobalNumbering *gcn = nullptr; +// gcn = apf::makeGlobal(apf::numberElements(m, "element-nums")); + +// for (int i = 0; i < PCU_Comm_Peers(); ++i) +// { +// if (i == PCU_Comm_Self()) +// { +// apf::MeshIterator *cellIter = m->begin(m->getDimension()); +// apf::MeshEntity *cell = nullptr; +// while ((cell = m->iterate(cellIter))) +// { +// if (m->isOwned(cell)) +// { +// const auto n = apf::getNumber(gcn, cell, 0); +// std::cout << "Rank [element]: " << i << " " << n << " " << m->isOwned(cell) << " " << m->getOwner(cell) << std::endl; +// } +// } +// m->end(cellIter); + +// destroyGlobalNumbering(gcn); +// } +// PCU_Barrier(); +// } +// } +// } + +void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap& cgnsBCMap) +{ + std::cout << &cgnsBCMap << std::endl; + + //ShowNumbering(m); + + // std::cout << prefix << " " << cellDimToWrite << std::endl; + const auto myRank = PCU_Comm_Self(); + const auto vertexCount = count(m, 0); + const auto edgeCount = count(m, 1); + const auto faceCount = count(m, 2); + const auto cell_dim = m->getDimension(); + const auto cellCount = count(m, cell_dim); + // for (int i = 0; i < PCU_Comm_Peers(); ++i) + // { + // if (i == PCU_Comm_Self()) + // { + // std::cout << "*******Local Mesh Stats******************\n"; + // std::cout << "Rank: " << myRank << ": Number of cells " << cellCount.second << "\n"; + // std::cout << "Rank: " << myRank << ": Number of vertices " << vertexCount.second << "\n"; + // std::cout << "Rank: " << myRank << ": Number of faces " << faceCount.second << "\n"; + // std::cout << "Rank: " << myRank << ": Number of edges " << edgeCount.second << "\n"; + // std::cout << "*****************************************\n"; + // } + // PCU_Barrier(); + // } + + PCU_Barrier(); + if (myRank == 0) + { + std::cout << "*******Global Mesh Stats*****************\n"; + std::cout << ": Number of cells " << cellCount.first << "\n"; + std::cout << ": Number of vertices " << vertexCount.first << "\n"; + std::cout << ": Number of faces " << faceCount.first << "\n"; + std::cout << ": Number of edges " << edgeCount.first << "\n"; + std::cout << "*****************************************\n"; + } + + std::array sizes; + sizes[0] = vertexCount.first; + sizes[1] = cellCount.first; + sizes[2] = 0; // nodes are unsorted. + + // Copy communicator + auto communicator = PCU_Get_Comm(); + cgp_mpi_comm(communicator); + // + cgp_pio_mode(CGNS_ENUMV(CGP_INDEPENDENT)); + + int index = -1; + if (cgp_open(prefix, CGNS_ENUMV(CG_MODE_WRITE), &index)) + cgp_error_exit(); + + int base = -1; + const int phys_dim = 3; + { + std::string baseName("Base_" + std::to_string(1)); + if (cg_base_write(index, baseName.c_str(), cell_dim, phys_dim, &base)) + cg_error_exit(); + } + // Write the default units at the top. + if (cg_goto(index, base, "end")) + cg_error_exit(); + + if (cg_units_write(CGNS_ENUMV(Kilogram), CGNS_ENUMV(Meter), CGNS_ENUMV(Second), CGNS_ENUMV(Kelvin), + CGNS_ENUMV(Degree))) + cg_error_exit(); + + if (cg_dataclass_write(CGNS_ENUMV(Dimensional))) + cg_error_exit(); + + int zone = -1; + { + std::string zoneName("Zone_" + std::to_string(1)); + if (cg_zone_write(index, base, zoneName.c_str(), sizes.data(), CGNS_ENUMV(Unstructured), &zone)) + cg_error_exit(); + } + + static_assert(std::is_same::value, "cgsize_t not compiled as int"); + + int Cx = -1; + int Cy = -1; + int Cz = -1; + + if (phys_dim > 0) + { + if (cgp_coord_write(index, base, zone, CGNS_ENUMV(RealDouble), "CoordinateX", &Cx)) + cgp_error_exit(); + } + if (phys_dim > 1) + { + if (cgp_coord_write(index, base, zone, CGNS_ENUMV(RealDouble), "CoordinateY", &Cy)) + cgp_error_exit(); + } + if (phys_dim > 2) + { + if (cgp_coord_write(index, base, zone, CGNS_ENUMV(RealDouble), "CoordinateZ", &Cz)) + cgp_error_exit(); + } + + std::array, 3> coords; + + apf::GlobalNumbering *gvn = nullptr; + gvn = apf::makeGlobal(apf::numberOwnedNodes(m, "node-nums")); + apf::synchronize(gvn); + + cgsize_t rmin[3]; + cgsize_t rmax[3]; + rmin[0] = std::numeric_limits::max(); + rmax[0] = 0; + + { + apf::Vector3 point; + for (int i = 0; i < PCU_Comm_Peers(); ++i) + { + if (i == PCU_Comm_Self()) + { + apf::MeshIterator *vertIter = m->begin(0); + apf::MeshEntity *vert = nullptr; + while ((vert = m->iterate(vertIter))) + { + if (m->isOwned(vert) && m->getOwner(vert) == i) + { + const cgsize_t n = static_cast(apf::getNumber(gvn, vert, 0) + 1); // one based + rmin[0] = std::min(rmin[0], n); + rmax[0] = std::max(rmax[0], n); + + m->getPoint(vert, 0, point); + coords[0].push_back(point[0]); + coords[1].push_back(point[1]); + coords[2].push_back(point[2]); + } + } + m->end(vertIter); + } + } + } + + // oddness of the api + rmin[1] = rmin[0]; + rmin[2] = rmin[0]; + rmax[1] = rmax[0]; + rmax[2] = rmax[0]; + + if (phys_dim > 0) + { + if (cgp_coord_write_data(index, base, zone, Cx, &rmin[0], &rmax[0], coords[0].data())) + cgp_error_exit(); + } + if (phys_dim > 1) + { + if (cgp_coord_write_data(index, base, zone, Cy, &rmin[0], &rmax[0], coords[1].data())) + cgp_error_exit(); + } + if (phys_dim > 2) + { + if (cgp_coord_write_data(index, base, zone, Cz, &rmin[0], &rmax[0], coords[2].data())) + cgp_error_exit(); + } + + apf::GlobalNumbering *gcn = nullptr; + gcn = apf::makeGlobal(apf::numberElements(m, "element-nums")); + + std::vector apfElementOrder; + apfElementOrder.push_back(apf::Mesh::HEX); + apfElementOrder.push_back(apf::Mesh::TET); + apfElementOrder.push_back(apf::Mesh::PYRAMID); + apfElementOrder.push_back(apf::Mesh::QUAD); + apfElementOrder.push_back(apf::Mesh::TRIANGLE); + apfElementOrder.push_back(apf::Mesh::EDGE); + + std::vector cgnsElementOrder; + cgnsElementOrder.push_back(CGNS_ENUMV(HEXA_8)); + cgnsElementOrder.push_back(CGNS_ENUMV(TETRA_4)); + cgnsElementOrder.push_back(CGNS_ENUMV(PYRA_5)); + cgnsElementOrder.push_back(CGNS_ENUMV(QUAD_4)); + cgnsElementOrder.push_back(CGNS_ENUMV(TRI_3)); + cgnsElementOrder.push_back(CGNS_ENUMV(BAR_2)); + + std::vector globalNumbersByElementType(apfElementOrder.size(), 0); + std::vector numbersByElementType(apfElementOrder.size(), 0); + for (std::size_t o = 0; o < apfElementOrder.size(); o++) + { + apf::MeshIterator *cellIter = m->begin(cell_dim); + apf::MeshEntity *cell = nullptr; + int counter = 0; + while ((cell = m->iterate(cellIter))) + { + if (m->getType(cell) == apfElementOrder[o] && m->isOwned(cell)) + { + counter++; + } + } + m->end(cellIter); + numbersByElementType[o] = counter; + int total = counter; + PCU_Add_Ints(&total, 1); // size of total array + globalNumbersByElementType[o] = total; + } + cgsize_t allTotal = std::accumulate(globalNumbersByElementType.begin(), globalNumbersByElementType.end(), 0); + PCU_ALWAYS_ASSERT_VERBOSE(allTotal == cellCount.first, ("Must be equal " + std::to_string(allTotal) + " " + std::to_string(cellCount.first)).c_str()); + + int globalStart = 1; // one-based + for (std::size_t o = 0; o < apfElementOrder.size(); o++) + { + std::vector elements; + apf::MeshIterator *cellIter = m->begin(cell_dim); + apf::MeshEntity *cell = nullptr; + apf::Downward verts; + + while ((cell = m->iterate(cellIter))) + { + if (m->getType(cell) == apfElementOrder[o] && m->isOwned(cell)) + { + const auto numVerts = m->getDownward(cell, 0, verts); + for (int i = 0; i < numVerts; i++) + { + const auto n = apf::getNumber(gvn, verts[i], 0); + elements.push_back(n + 1); // one-based + } + } + } + m->end(cellIter); + + if (globalNumbersByElementType[o] > 0) + { + const int globalEnd = globalStart + globalNumbersByElementType[o] - 1; // one-based stuff + // + int sectionNumber = -1; + if (cgp_section_write(index, base, zone, (std::string(cg_ElementTypeName(cgnsElementOrder[o])) + " " + std::to_string(globalStart) + "->" + std::to_string(globalEnd)).c_str(), cgnsElementOrder[o], globalStart, + globalEnd, 0, §ionNumber)) // global start, end within the file for that element type + cgp_error_exit(); + + std::vector allNumbersForThisType(PCU_Comm_Peers(), 0); + MPI_Allgather(&numbersByElementType[o], 1, MPI_INT, allNumbersForThisType.data(), 1, + MPI_INT, PCU_Get_Comm()); + + cgsize_t num = 0; + for(int i = 0; i < PCU_Comm_Self(); i++) + num+= allNumbersForThisType[i]; + + cgsize_t elStart = globalStart + num; + cgsize_t elEnd = elStart + numbersByElementType[o] -1; // one-based stuff + if (cgp_elements_write_data(index, base, zone, sectionNumber, elStart, elEnd, // per processor within the range[start, end] + elements.data())) + cgp_error_exit(); + + //std::cout << "RANK: " << PCU_Comm_Self() << " ==> " << globalStart << " " << globalEnd << " elStart " << elStart << " elEnd " << elEnd << " numbersByElementType[o] " << numbersByElementType[o] << std::endl; + + globalStart += globalNumbersByElementType[o]; + } + } + + destroyGlobalNumbering(gvn); + destroyGlobalNumbering(gcn); + // + cgp_close(index); +} +} // namespace + +namespace apf +{ + +void writeCGNS(const char *prefix, Mesh *m, const apf::CGNSBCMap& cgnsBCMap) +{ +#ifdef HAVE_CGNS + WriteCGNS(prefix, m, cgnsBCMap); +#else + PCU_ALWAYS_ASSERT_VERBOSE(true == false, + "Build with ENABLE_CGNS to allow this functionality."); + exit(EXIT_FAILURE); +#endif +} + +} // namespace apf diff --git a/test/cgns.cc b/test/cgns.cc index d9d2b2066..06d5f56b4 100644 --- a/test/cgns.cc +++ b/test/cgns.cc @@ -127,42 +127,42 @@ auto additional(const std::string &prefix, gmi_model *g, apf::Mesh2 *mesh) balance(prefix, apf::RCB, pm); simpleReorder(prefix, pm); - //create an element field - const int mdim = pumi_mesh_getDim(pm); - pShape s = pumi_shape_getConstant(mdim); - const int dofPerElm = 1; - pField f = pumi_field_create(pm, "elmField", dofPerElm, PUMI_PACKED, s); + //create an element field + const int mdim = pumi_mesh_getDim(pm); + pShape s = pumi_shape_getConstant(mdim); + const int dofPerElm = 1; + pField f = pumi_field_create(pm, "elmField", dofPerElm, PUMI_PACKED, s); - pMeshIter it = pm->begin(mdim); - pMeshEnt e; - double v = 0; - while ((e = pm->iterate(it))) - pumi_node_setField(f, e, 0, &v); - pm->end(it); + pMeshIter it = pm->begin(mdim); + pMeshEnt e; + double v = 0; + while ((e = pm->iterate(it))) + pumi_node_setField(f, e, 0, &v); + pm->end(it); - const int ghost = mdim; - const int bridge = ghost - 1; - const int numLayers = 1; - const int ghostAcrossCopies = 1; - pumi_ghost_createLayer(pm, bridge, ghost, numLayers, ghostAcrossCopies); + const int ghost = mdim; + const int bridge = ghost - 1; + const int numLayers = 1; + const int ghostAcrossCopies = 1; + pumi_ghost_createLayer(pm, bridge, ghost, numLayers, ghostAcrossCopies); - it = pm->begin(mdim); - v = 1; - while ((e = pm->iterate(it))) - { - if (!pumi_ment_isGhost(e)) - pumi_node_setField(f, e, 0, &v); - } - pm->end(it); + it = pm->begin(mdim); + v = 1; + while ((e = pm->iterate(it))) + { + if (!pumi_ment_isGhost(e)) + pumi_node_setField(f, e, 0, &v); + } + pm->end(it); - const std::string name = prefix + "_toPUMI_" + std::to_string(PCU_Comm_Peers()) + "procs"; - // only the owned elements will have a elmField value of 1 - pumi_mesh_write(pm, (name + "_beforeSync").c_str(), "vtk"); + const std::string name = prefix + "_toPUMI_" + std::to_string(PCU_Comm_Peers()) + "procs"; + // only the owned elements will have a elmField value of 1 + pumi_mesh_write(pm, (name + "_beforeSync").c_str(), "vtk"); - pumi_field_synchronize(f); + pumi_field_synchronize(f); - // owned and ghosted elements will have a elmField value of 1 - pumi_mesh_write(pm, (name + "_afterSync").c_str(), "vtk"); + // owned and ghosted elements will have a elmField value of 1 + pumi_mesh_write(pm, (name + "_afterSync").c_str(), "vtk"); const auto clean = [&pm, &f]() { // clean-up @@ -280,6 +280,7 @@ int main(int argc, char **argv) if (additionalTests) cleanUp = additional(prefix, g, m); // + apf::writeCGNS((prefix + "_outputFile.cgns").c_str(), m, cgnsBCMap); // if (additionalTests) { From c39793370248b8b131c3c7c7b2b8a9ed6dc7a731 Mon Sep 17 00:00:00 2001 From: a-jp Date: Mon, 21 Oct 2019 16:32:58 +0100 Subject: [PATCH 27/72] remove unused function and needless test --- apf/apfCGNS.cc | 64 +++----------------------------------------------- 1 file changed, 3 insertions(+), 61 deletions(-) diff --git a/apf/apfCGNS.cc b/apf/apfCGNS.cc index 0a14517f2..347a8af84 100644 --- a/apf/apfCGNS.cc +++ b/apf/apfCGNS.cc @@ -48,70 +48,10 @@ static auto count(apf::Mesh *m, int dim) return std::make_pair(total, local); } -// void ShowNumbering(apf::Mesh *m) -// { -// { -// apf::GlobalNumbering *gvn = nullptr; -// gvn = apf::makeGlobal(apf::numberOwnedNodes(m, "node-nums")); -// apf::synchronize(gvn); - -// for (int i = 0; i < PCU_Comm_Peers(); ++i) -// { -// if (i == PCU_Comm_Self()) -// { -// apf::MeshIterator *vertIter = m->begin(0); -// apf::MeshEntity *vert = nullptr; -// while ((vert = m->iterate(vertIter))) -// { -// if (m->isOwned(vert) && m->getOwner(vert) == i) -// { -// const auto n = apf::getNumber(gvn, vert, 0); -// std::cout << "Rank [vertex]: " << i << " " << n << " " << m->isOwned(vert) << " " << m->getOwner(vert) << std::endl; -// } -// } -// m->end(vertIter); - -// destroyGlobalNumbering(gvn); -// } -// PCU_Barrier(); -// } -// } -// std::cout << std::endl; -// PCU_Barrier(); -// { -// apf::GlobalNumbering *gcn = nullptr; -// gcn = apf::makeGlobal(apf::numberElements(m, "element-nums")); - -// for (int i = 0; i < PCU_Comm_Peers(); ++i) -// { -// if (i == PCU_Comm_Self()) -// { -// apf::MeshIterator *cellIter = m->begin(m->getDimension()); -// apf::MeshEntity *cell = nullptr; -// while ((cell = m->iterate(cellIter))) -// { -// if (m->isOwned(cell)) -// { -// const auto n = apf::getNumber(gcn, cell, 0); -// std::cout << "Rank [element]: " << i << " " << n << " " << m->isOwned(cell) << " " << m->getOwner(cell) << std::endl; -// } -// } -// m->end(cellIter); - -// destroyGlobalNumbering(gcn); -// } -// PCU_Barrier(); -// } -// } -// } - void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap& cgnsBCMap) { - std::cout << &cgnsBCMap << std::endl; - //ShowNumbering(m); - // std::cout << prefix << " " << cellDimToWrite << std::endl; const auto myRank = PCU_Comm_Self(); const auto vertexCount = count(m, 0); const auto edgeCount = count(m, 1); @@ -226,7 +166,7 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap& cgnsBCMap apf::MeshEntity *vert = nullptr; while ((vert = m->iterate(vertIter))) { - if (m->isOwned(vert) && m->getOwner(vert) == i) + if (m->isOwned(vert)) { const cgsize_t n = static_cast(apf::getNumber(gvn, vert, 0) + 1); // one based rmin[0] = std::min(rmin[0], n); @@ -357,6 +297,8 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap& cgnsBCMap globalStart += globalNumbersByElementType[o]; } } + // + std::cout << &cgnsBCMap << std::endl; destroyGlobalNumbering(gvn); destroyGlobalNumbering(gcn); From 3c5f4a619bbd34a0b37a6f6b495b9678cc70a211 Mon Sep 17 00:00:00 2001 From: a-jp Date: Tue, 22 Oct 2019 11:48:55 +0100 Subject: [PATCH 28/72] notes --- apf/apf.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/apf/apf.h b/apf/apf.h index 401e50f2b..c4a816176 100644 --- a/apf/apf.h +++ b/apf/apf.h @@ -635,9 +635,17 @@ for (t::const_iterator i = (w).begin(); \ * CGNSBCMap type is already defined in apfMDS.h. * Would be better if there were a base include that this and apfMDS.h could include * to stop this type being defined twice in two includes... + +// Key [String] = Vertex/EdgeCenter/FaceCenter/CellCenter +// Value [vector of Pairs per Key]; Pairs = cgns_bc_name, field value. +// Field value holds [0, 1] as a +// marker to indicate mesh_entities +// within bc group 1="in group", 0="not in group" +// Fields set on vertices, edges, faces, and cells + */ using CGNSBCMap = std::map>>; -void writeCGNS(const char* prefix, Mesh* m, const CGNSBCMap& cgnsBCMap); +void writeCGNS(const char *prefix, Mesh *m, const CGNSBCMap &cgnsBCMap); /** \brief Write a set of parallel VTK Unstructured Mesh files from an apf::Mesh * with binary (base64) encoding and zlib compression (if LION_COMPRESS=ON) From 85d5914a09d189530e43c88fc827636c21000e0c Mon Sep 17 00:00:00 2001 From: a-jp Date: Tue, 22 Oct 2019 11:49:34 +0100 Subject: [PATCH 29/72] more work on writer plus take map --- apf/apfCGNS.cc | 54 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/apf/apfCGNS.cc b/apf/apfCGNS.cc index 347a8af84..d131129d9 100644 --- a/apf/apfCGNS.cc +++ b/apf/apfCGNS.cc @@ -48,7 +48,7 @@ static auto count(apf::Mesh *m, int dim) return std::make_pair(total, local); } -void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap& cgnsBCMap) +void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap) { //ShowNumbering(m); @@ -246,7 +246,7 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap& cgnsBCMap } cgsize_t allTotal = std::accumulate(globalNumbersByElementType.begin(), globalNumbersByElementType.end(), 0); PCU_ALWAYS_ASSERT_VERBOSE(allTotal == cellCount.first, ("Must be equal " + std::to_string(allTotal) + " " + std::to_string(cellCount.first)).c_str()); - + int globalStart = 1; // one-based for (std::size_t o = 0; o < apfElementOrder.size(); o++) { @@ -280,14 +280,14 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap& cgnsBCMap std::vector allNumbersForThisType(PCU_Comm_Peers(), 0); MPI_Allgather(&numbersByElementType[o], 1, MPI_INT, allNumbersForThisType.data(), 1, - MPI_INT, PCU_Get_Comm()); - + MPI_INT, PCU_Get_Comm()); + cgsize_t num = 0; - for(int i = 0; i < PCU_Comm_Self(); i++) - num+= allNumbersForThisType[i]; + for (int i = 0; i < PCU_Comm_Self(); i++) + num += allNumbersForThisType[i]; cgsize_t elStart = globalStart + num; - cgsize_t elEnd = elStart + numbersByElementType[o] -1; // one-based stuff + cgsize_t elEnd = elStart + numbersByElementType[o] - 1; // one-based stuff if (cgp_elements_write_data(index, base, zone, sectionNumber, elStart, elEnd, // per processor within the range[start, end] elements.data())) cgp_error_exit(); @@ -299,7 +299,45 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap& cgnsBCMap } // std::cout << &cgnsBCMap << std::endl; + if (cell_dim == 3) + { + auto iter = cgnsBCMap.find("Vertex"); + if (iter != cgnsBCMap.end()) + { + for (const auto &p : iter->second) + { + std::cout << iter->first << " " << p.first << " " << p.second << std::endl; + } + } + iter = cgnsBCMap.find("EdgeCenter"); + if (iter != cgnsBCMap.end()) + { + for (const auto &p : iter->second) + { + std::cout << iter->first << " " << p.first << " " << p.second << std::endl; + } + } + iter = cgnsBCMap.find("FaceCenter"); + if (iter != cgnsBCMap.end()) + { + for (const auto &p : iter->second) + { + std::cout << iter->first << " " << p.first << " " << p.second << std::endl; + auto* field = m->findField(p.first.c_str()); + std::cout << field << " " << p.second << std::endl; + } + } + iter = cgnsBCMap.find("CellCenter"); + if (iter != cgnsBCMap.end()) + { + for (const auto &p : iter->second) + { + std::cout << iter->first << " " << p.first << " " << p.second << std::endl; + } + } + } + // destroyGlobalNumbering(gvn); destroyGlobalNumbering(gcn); // @@ -310,7 +348,7 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap& cgnsBCMap namespace apf { -void writeCGNS(const char *prefix, Mesh *m, const apf::CGNSBCMap& cgnsBCMap) +void writeCGNS(const char *prefix, Mesh *m, const apf::CGNSBCMap &cgnsBCMap) { #ifdef HAVE_CGNS WriteCGNS(prefix, m, cgnsBCMap); From 4efc204f3d0c82d405b424ebde0113a4aff26972 Mon Sep 17 00:00:00 2001 From: a-jp Date: Tue, 22 Oct 2019 11:49:53 +0100 Subject: [PATCH 30/72] bug fixes to map insertion --- mds/mdsCGNS.cc | 116 ++++++++++++++++++++----------------------------- 1 file changed, 46 insertions(+), 70 deletions(-) diff --git a/mds/mdsCGNS.cc b/mds/mdsCGNS.cc index 825620a98..f3d0be6f4 100644 --- a/mds/mdsCGNS.cc +++ b/mds/mdsCGNS.cc @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -382,7 +383,7 @@ struct BCInfo // Notes: // I do not exchange the tag values (even if that can be done). - // I'm assuming in parallel all partition that need the vertex that + // I'm assuming in parallel all partitions that need the vertex that // falls within a given group mark that vertex accordingly. // I assume therefore that vertices on a processor boundary, are marked // by all procs that share it. @@ -402,6 +403,20 @@ struct BCInfo **/ void TagBCEntities(const int cgid, apf::Mesh2 *m, apf::CGNSBCMap &cgnsBCMap) { + const auto Add = [&cgnsBCMap](const std::string &location, const std::string &fieldName, apf::Field *field) { + auto iter = cgnsBCMap.find(location); + if (iter != cgnsBCMap.end()) + { + iter->second.push_back(std::make_pair(fieldName, field)); + } + else + { + std::vector> pair; + pair.push_back(std::make_pair(fieldName, field)); + cgnsBCMap.insert(std::make_pair(location, pair)); + } + }; + if (m->getDimension() == 3) // working with a 3D mesh { if (cgnsLocation == "Vertex") @@ -431,13 +446,14 @@ struct BCInfo if (allTagged) { - std::cout << "Flagged vertices " << 1 << " " << allTagged << std::endl; + //std::cout << "Flagged vertices " << 1 << " " << allTagged << std::endl; dval[0] = 1.0; apf::setComponents(field, vert, 0, dval); } } - auto iter = cgnsBCMap["Vertex"]; - iter.push_back(std::make_pair(fieldName, field)); + m->end(vertIter); + + Add("Vertex", fieldName, field); } else if (cgnsLocation == "EdgeCenter") { @@ -475,8 +491,9 @@ struct BCInfo apf::setComponents(field, edge, 0, dval); } } - auto iter = cgnsBCMap["EdgeCenter"]; - iter.push_back(std::make_pair(fieldName, field)); + m->end(edgeIter); + + Add("EdgeCenter", fieldName, field); } else if (cgnsLocation == "FaceCenter") { @@ -514,8 +531,9 @@ struct BCInfo apf::setComponents(field, face, 0, dval); } } - auto iter = cgnsBCMap["FaceCenter"]; - iter.push_back(std::make_pair(fieldName, field)); + m->end(faceIter); + + Add("FaceCenter", fieldName, field); } else if (cgnsLocation == "CellCenter") { @@ -554,57 +572,10 @@ struct BCInfo apf::setComponents(field, cell, 0, dval); } } - auto iter = cgnsBCMap["CellCenter"]; - iter.push_back(std::make_pair(fieldName, field)); + m->end(cellIter); + + Add("CellCenter", fieldName, field); } - // { // more verbose example of iterating the mesh - // apf::Field *field = nullptr; - // const std::string fieldName = "CellBC_other_" + bcName; - // field = apf::createField(m, fieldName.c_str(), apf::SCALAR, apf::getConstant(3)); - - // double dval[1]; - // dval[0] = 0.0; - // apf::MeshIterator *cellIter = m->begin(3); - // apf::MeshEntity *cell = nullptr; - // while ((cell = m->iterate(cellIter))) - // { - // apf::setComponents(field, cell, 0, dval); - // } - // m->end(cellIter); - - // apf::Downward faces; - // apf::Downward edges; - // apf::Downward verts; - // cellIter = m->begin(3); - // int vals[1]; - // while ((cell = m->iterate(cellIter))) - // { - // bool allTagged = true; - // const auto numFaces = m->getDownward(cell, 2, faces); - // for (int f = 0; f < numFaces; f++) - // { - // const auto numEdges = m->getDownward(faces[f], 1, edges); - // for (int e = 0; e < numEdges; e++) - // { - // const auto numVerts = m->getDownward(edges[e], 0, verts); - // for (int i = 0; i < numVerts; i++) - // { - // m->getIntTag(verts[i], tag, vals); - // if (vals[0] == 0) - // allTagged = false; - // } - // } - // } - // if (allTagged) - // { - // std::cout << "Flagged cells " << allTagged << std::endl; - // dval[0] = 1.0; - // apf::setComponents(field, cell, 0, dval); - // } - // } - // auto iter = cgnsBCMap["CellCenter"]; - // iter.push_back(std::make_pair(fieldName, field)); - // } } else Kill(cgid, "Unknown BC Type", cgnsLocation); @@ -638,13 +609,14 @@ struct BCInfo if (allTagged) { - std::cout << "Flagged vertices " << 1 << " " << allTagged << std::endl; + //std::cout << "Flagged vertices " << 1 << " " << allTagged << std::endl; dval[0] = 1.0; apf::setComponents(field, vert, 0, dval); } } - auto iter = cgnsBCMap["Vertex"]; - iter.push_back(std::make_pair(fieldName, field)); + m->end(vertIter); + + Add("Vertex", fieldName, field); } else if (cgnsLocation == "EdgeCenter") { @@ -682,8 +654,9 @@ struct BCInfo apf::setComponents(field, edge, 0, dval); } } - auto iter = cgnsBCMap["EdgeCenter"]; - iter.push_back(std::make_pair(fieldName, field)); + m->end(edgeIter); + + Add("EdgeCenter", fieldName, field); } else if (cgnsLocation == "FaceCenter") { @@ -725,8 +698,9 @@ struct BCInfo apf::setComponents(field, cell, 0, dval); } } - auto iter = cgnsBCMap["CellCenter"]; - iter.push_back(std::make_pair(fieldName, field)); + m->end(cellIter); + + Add("CellCenter", fieldName, field); } } else if (m->getDimension() == 1) // working with a 1D mesh @@ -758,13 +732,14 @@ struct BCInfo if (allTagged) { - std::cout << "Flagged vertices " << 1 << " " << allTagged << std::endl; + //std::cout << "Flagged vertices " << 1 << " " << allTagged << std::endl; dval[0] = 1.0; apf::setComponents(field, vert, 0, dval); } } - auto iter = cgnsBCMap["Vertex"]; - iter.push_back(std::make_pair(fieldName, field)); + m->end(vertIter); + + Add("Vertex", fieldName, field); } else if (cgnsLocation == "EdgeCenter") { @@ -810,8 +785,9 @@ struct BCInfo apf::setComponents(field, cell, 0, dval); } } - auto iter = cgnsBCMap["CellCenter"]; - iter.push_back(std::make_pair(fieldName, field)); + m->end(cellIter); + + Add("CellCenter", fieldName, field); } } From f439a8fcc1fa8ef4d0f8853e92e824dc3c48faae Mon Sep 17 00:00:00 2001 From: a-jp Date: Tue, 22 Oct 2019 15:14:49 +0100 Subject: [PATCH 31/72] flip bc marker in CgnsBCMap to an integer tag from a double field, assoicated changes --- apf/apf.h | 11 +- apf/apfCGNS.cc | 2 +- mds/apfMDS.h | 10 +- mds/mdsCGNS.cc | 476 +++++++++++++++++-------------------------------- 4 files changed, 173 insertions(+), 326 deletions(-) diff --git a/apf/apf.h b/apf/apf.h index c4a816176..85a9cd9eb 100644 --- a/apf/apf.h +++ b/apf/apf.h @@ -35,6 +35,7 @@ class Field; class Element; class Mesh; class MeshEntity; +class MeshTag; class VectorElement; /** \brief Mesh Elements represent the mesh coordinate vector field. */ typedef VectorElement MeshElement; @@ -637,14 +638,14 @@ for (t::const_iterator i = (w).begin(); \ * to stop this type being defined twice in two includes... // Key [String] = Vertex/EdgeCenter/FaceCenter/CellCenter -// Value [vector of Pairs per Key]; Pairs = cgns_bc_name, field value. -// Field value holds [0, 1] as a +// Value [vector of Pairs per Key]; Pairs = cgns_bc_name, tag value. +// Tag value holds [0, 1] as a // marker to indicate mesh_entities -// within bc group 1="in group", 0="not in group" -// Fields set on vertices, edges, faces, and cells +// within bc group. 1="in group", 0="not in group" +// Tags set on vertices, edges, faces, and cells */ -using CGNSBCMap = std::map>>; +using CGNSBCMap = std::map>>; void writeCGNS(const char *prefix, Mesh *m, const CGNSBCMap &cgnsBCMap); /** \brief Write a set of parallel VTK Unstructured Mesh files from an apf::Mesh diff --git a/apf/apfCGNS.cc b/apf/apfCGNS.cc index d131129d9..fd086cc4e 100644 --- a/apf/apfCGNS.cc +++ b/apf/apfCGNS.cc @@ -323,7 +323,7 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap for (const auto &p : iter->second) { std::cout << iter->first << " " << p.first << " " << p.second << std::endl; - auto* field = m->findField(p.first.c_str()); + auto* field = m->findTag(p.first.c_str()); std::cout << field << " " << p.second << std::endl; } diff --git a/mds/apfMDS.h b/mds/apfMDS.h index 1f150fb6f..9005b5161 100644 --- a/mds/apfMDS.h +++ b/mds/apfMDS.h @@ -194,12 +194,12 @@ int getMdsIndex(Mesh2* in, MeshEntity* e); MeshEntity* getMdsEntity(Mesh2* in, int dimension, int index); // Key [String] = Vertex/EdgeCenter/FaceCenter/CellCenter -// Value [vector of Pairs per Key]; Pairs = cgns_bc_name, field value. -// Field value holds [0, 1] as a +// Value [vector of Pairs per Key]; Pairs = cgns_bc_name, tag value. +// Tag value holds [0, 1] as a // marker to indicate mesh_entities -// within bc group 1="in group", 0="not in group" -// Fields set on vertices, edges, faces, and cells -using CGNSBCMap = std::map>>; +// within bc group. 1="in group", 0="not in group" +// Tags set on vertices, edges, faces, and cells +using CGNSBCMap = std::map>>; Mesh2* loadMdsFromCGNS(gmi_model* g, const char* filename, CGNSBCMap& cgnsBCMap); Mesh2* loadMdsFromGmsh(gmi_model* g, const char* filename); diff --git a/mds/mdsCGNS.cc b/mds/mdsCGNS.cc index f3d0be6f4..e7750df0f 100644 --- a/mds/mdsCGNS.cc +++ b/mds/mdsCGNS.cc @@ -387,7 +387,7 @@ struct BCInfo // falls within a given group mark that vertex accordingly. // I assume therefore that vertices on a processor boundary, are marked // by all procs that share it. - // TODO: generate test that proves this works + // TODO: generate test that proves this works. Done: for quads tested 4-way } /** @@ -403,179 +403,187 @@ struct BCInfo **/ void TagBCEntities(const int cgid, apf::Mesh2 *m, apf::CGNSBCMap &cgnsBCMap) { - const auto Add = [&cgnsBCMap](const std::string &location, const std::string &fieldName, apf::Field *field) { + const auto Add = [&cgnsBCMap](const std::string &location, const std::string &tagName, apf::MeshTag *field) { auto iter = cgnsBCMap.find(location); if (iter != cgnsBCMap.end()) { - iter->second.push_back(std::make_pair(fieldName, field)); + iter->second.push_back(std::make_pair(tagName, field)); } else { - std::vector> pair; - pair.push_back(std::make_pair(fieldName, field)); + std::vector> pair; + pair.push_back(std::make_pair(tagName, field)); cgnsBCMap.insert(std::make_pair(location, pair)); } }; - if (m->getDimension() == 3) // working with a 3D mesh - { - if (cgnsLocation == "Vertex") + const auto VertexLoop = [&m](const std::string &tagName, apf::MeshTag *vertexTag) { + apf::MeshTag *bcTag = nullptr; + bcTag = m->createIntTag(tagName.c_str(), 1); // 1 is size of tag + + apf::MeshIterator *vertIter = m->begin(0); + apf::MeshEntity *vert = nullptr; + int vals[1]; + vals[0] = 0; + while ((vert = m->iterate(vertIter))) + { + m->setIntTag(vert, bcTag, vals); + } + m->end(vertIter); + + vertIter = m->begin(0); + while ((vert = m->iterate(vertIter))) { - apf::Field *field = nullptr; - const std::string fieldName = "VertBC_" + bcName; - field = apf::createFieldOn(m, fieldName.c_str(), apf::SCALAR); - - double dval[1]; - dval[0] = 0.0; - apf::MeshIterator *vertIter = m->begin(0); - apf::MeshEntity *vert = nullptr; - while ((vert = m->iterate(vertIter))) + bool allTagged = true; + m->getIntTag(vert, vertexTag, vals); + if (vals[0] == 0) + allTagged = false; + + if (allTagged) { - apf::setComponents(field, vert, 0, dval); + vals[0] = 1; + m->setIntTag(vert, bcTag, vals); } - m->end(vertIter); + } + m->end(vertIter); + return bcTag; + }; + + const auto EdgeLoop = [&m](const std::string &tagName, apf::MeshTag *vertexTag) { + apf::MeshTag *bcTag = nullptr; + bcTag = m->createIntTag(tagName.c_str(), 1); // 1 is size of tag + + apf::MeshIterator *edgeIter = m->begin(1); + apf::MeshEntity *edge = nullptr; + int vals[1]; + vals[0] = 0; + while ((edge = m->iterate(edgeIter))) + { + m->setIntTag(edge, bcTag, vals); + } + m->end(edgeIter); - int vals[1]; - vertIter = m->begin(0); - while ((vert = m->iterate(vertIter))) + apf::Downward verts; + edgeIter = m->begin(1); + while ((edge = m->iterate(edgeIter))) + { + const auto numVerts = m->getDownward(edge, 0, verts); + bool allTagged = true; + for (int i = 0; i < numVerts; i++) { - bool allTagged = true; - m->getIntTag(vert, tag, vals); + m->getIntTag(verts[i], vertexTag, vals); if (vals[0] == 0) allTagged = false; - - if (allTagged) - { - //std::cout << "Flagged vertices " << 1 << " " << allTagged << std::endl; - dval[0] = 1.0; - apf::setComponents(field, vert, 0, dval); - } } - m->end(vertIter); + if (allTagged) + { + vals[0] = 1; + m->setIntTag(edge, bcTag, vals); + } + } + m->end(edgeIter); + return bcTag; + }; - Add("Vertex", fieldName, field); + const auto FaceLoop = [&m](const std::string &tagName, apf::MeshTag *vertexTag) { + apf::MeshTag *bcTag = nullptr; + bcTag = m->createIntTag(tagName.c_str(), 1); // 1 is size of tag + + apf::MeshIterator *faceIter = m->begin(2); + apf::MeshEntity *face = nullptr; + int vals[1]; + vals[0] = 0; + while ((face = m->iterate(faceIter))) + { + m->setIntTag(face, bcTag, vals); } - else if (cgnsLocation == "EdgeCenter") + m->end(faceIter); + + apf::Downward verts; + faceIter = m->begin(2); + while ((face = m->iterate(faceIter))) { - apf::Field *field = nullptr; - const std::string fieldName = "EdgeBC_" + bcName; - field = apf::createField(m, fieldName.c_str(), apf::SCALAR, apf::getConstant(1)); - - double dval[1]; - dval[0] = 0.0; - apf::MeshIterator *edgeIter = m->begin(1); - apf::MeshEntity *edge = nullptr; - while ((edge = m->iterate(edgeIter))) + const auto numVerts = m->getDownward(face, 0, verts); + bool allTagged = true; + for (int i = 0; i < numVerts; i++) { - apf::setComponents(field, edge, 0, dval); + m->getIntTag(verts[i], vertexTag, vals); + if (vals[0] == 0) + allTagged = false; } - m->end(edgeIter); - - apf::Downward verts; - int vals[1]; - edgeIter = m->begin(1); - while ((edge = m->iterate(edgeIter))) + if (allTagged) { - const auto numVerts = m->getDownward(edge, 0, verts); - bool allTagged = true; - for (int i = 0; i < numVerts; i++) - { - m->getIntTag(verts[i], tag, vals); - if (vals[0] == 0) - allTagged = false; - } - if (allTagged) - { - //std::cout << "Flagged edges " << numVerts << " " << allTagged << std::endl; - dval[0] = 1.0; - apf::setComponents(field, edge, 0, dval); - } + vals[0] = 1; + m->setIntTag(face, bcTag, vals); } - m->end(edgeIter); + } + m->end(faceIter); + + return bcTag; + }; + + const auto CellLoop = [&m](const std::string &tagName, apf::MeshTag *vertexTag, int dim) { + apf::MeshTag *bcTag = nullptr; + bcTag = m->createIntTag(tagName.c_str(), 1); // 1 is size of tag - Add("EdgeCenter", fieldName, field); + apf::MeshIterator *cellIter = m->begin(dim); + apf::MeshEntity *cell = nullptr; + int vals[1]; + vals[0] = 0; + while ((cell = m->iterate(cellIter))) + { + m->setIntTag(cell, bcTag, vals); } - else if (cgnsLocation == "FaceCenter") + m->end(cellIter); + + apf::Downward verts; + cellIter = m->begin(dim); + while ((cell = m->iterate(cellIter))) { - apf::Field *field = nullptr; - const std::string fieldName = "FaceBC_" + bcName; - field = apf::createField(m, fieldName.c_str(), apf::SCALAR, apf::getConstant(2)); - - double dval[1]; - dval[0] = 0.0; - apf::MeshIterator *faceIter = m->begin(2); - apf::MeshEntity *face = nullptr; - while ((face = m->iterate(faceIter))) + const auto numVerts = m->getDownward(cell, 0, verts); + bool allTagged = true; + for (int i = 0; i < numVerts; i++) { - apf::setComponents(field, face, 0, dval); + m->getIntTag(verts[i], vertexTag, vals); + if (vals[0] == 0) + allTagged = false; } - m->end(faceIter); - - apf::Downward verts; - faceIter = m->begin(2); - int vals[1]; - while ((face = m->iterate(faceIter))) + if (allTagged) { - const auto numVerts = m->getDownward(face, 0, verts); - bool allTagged = true; - for (int i = 0; i < numVerts; i++) - { - m->getIntTag(verts[i], tag, vals); - if (vals[0] == 0) - allTagged = false; - } - if (allTagged) - { - //std::cout << "Flagged faces " << numVerts << " " << allTagged << std::endl; - dval[0] = 1.0; - apf::setComponents(field, face, 0, dval); - } + vals[0] = 1; + m->setIntTag(cell, bcTag, vals); } - m->end(faceIter); + } + m->end(cellIter); - Add("FaceCenter", fieldName, field); + return bcTag; + }; + + if (m->getDimension() == 3) // working with a 3D mesh + { + if (cgnsLocation == "Vertex") + { + const std::string tagName = "VertBC_" + bcName; + apf::MeshTag *bcTag = VertexLoop(tagName, tag); + Add("Vertex", tagName, bcTag); + } + else if (cgnsLocation == "EdgeCenter") + { + const std::string tagName = "EdgeBC_" + bcName; + apf::MeshTag *bcTag = EdgeLoop(tagName, tag); + Add("EdgeCenter", tagName, bcTag); + } + else if (cgnsLocation == "FaceCenter") + { + const std::string tagName = "FaceBC_" + bcName; + apf::MeshTag *bcTag = FaceLoop(tagName, tag); + Add("FaceCenter", tagName, bcTag); } else if (cgnsLocation == "CellCenter") { - { - apf::Field *field = nullptr; - const std::string fieldName = "CellBC_" + bcName; - field = apf::createField(m, fieldName.c_str(), apf::SCALAR, apf::getConstant(3)); - - double dval[1]; - dval[0] = 0.0; - apf::MeshIterator *cellIter = m->begin(3); - apf::MeshEntity *cell = nullptr; - while ((cell = m->iterate(cellIter))) - { - apf::setComponents(field, cell, 0, dval); - } - m->end(cellIter); - - apf::Downward verts; - cellIter = m->begin(3); - int vals[1]; - while ((cell = m->iterate(cellIter))) - { - const auto numVerts = m->getDownward(cell, 0, verts); - bool allTagged = true; - for (int i = 0; i < numVerts; i++) - { - m->getIntTag(verts[i], tag, vals); - if (vals[0] == 0) - allTagged = false; - } - if (allTagged) - { - //std::cout << "Flagged cells " << numVerts << " " << allTagged << std::endl; - dval[0] = 1.0; - apf::setComponents(field, cell, 0, dval); - } - } - m->end(cellIter); - - Add("CellCenter", fieldName, field); - } + const std::string tagName = "CellBC_" + bcName; + apf::MeshTag *bcTag = CellLoop(tagName, tag, m->getDimension()); + Add("CellCenter", tagName, bcTag); } else Kill(cgid, "Unknown BC Type", cgnsLocation); @@ -584,79 +592,15 @@ struct BCInfo { if (cgnsLocation == "Vertex") { - apf::Field *field = nullptr; - const std::string fieldName = "VertBC_" + bcName; - field = apf::createFieldOn(m, fieldName.c_str(), apf::SCALAR); - - double dval[1]; - dval[0] = 0.0; - apf::MeshIterator *vertIter = m->begin(0); - apf::MeshEntity *vert = nullptr; - while ((vert = m->iterate(vertIter))) - { - apf::setComponents(field, vert, 0, dval); - } - m->end(vertIter); - - int vals[1]; - vertIter = m->begin(0); - while ((vert = m->iterate(vertIter))) - { - bool allTagged = true; - m->getIntTag(vert, tag, vals); - if (vals[0] == 0) - allTagged = false; - - if (allTagged) - { - //std::cout << "Flagged vertices " << 1 << " " << allTagged << std::endl; - dval[0] = 1.0; - apf::setComponents(field, vert, 0, dval); - } - } - m->end(vertIter); - - Add("Vertex", fieldName, field); + const std::string tagName = "VertBC_" + bcName; + apf::MeshTag *bcTag = VertexLoop(tagName, tag); + Add("Vertex", tagName, bcTag); } else if (cgnsLocation == "EdgeCenter") { - apf::Field *field = nullptr; - const std::string fieldName = "EdgeBC_" + bcName; - field = apf::createField(m, fieldName.c_str(), apf::SCALAR, apf::getConstant(1)); - - double dval[1]; - dval[0] = 0.0; - apf::MeshIterator *edgeIter = m->begin(1); - apf::MeshEntity *edge = nullptr; - while ((edge = m->iterate(edgeIter))) - { - apf::setComponents(field, edge, 0, dval); - } - m->end(edgeIter); - - apf::Downward verts; - int vals[1]; - edgeIter = m->begin(1); - while ((edge = m->iterate(edgeIter))) - { - const auto numVerts = m->getDownward(edge, 0, verts); - bool allTagged = true; - for (int i = 0; i < numVerts; i++) - { - m->getIntTag(verts[i], tag, vals); - if (vals[0] == 0) - allTagged = false; - } - if (allTagged) - { - //std::cout << "Flagged edges " << numVerts << " " << allTagged << std::endl; - dval[0] = 1.0; - apf::setComponents(field, edge, 0, dval); - } - } - m->end(edgeIter); - - Add("EdgeCenter", fieldName, field); + const std::string tagName = "EdgeBC_" + bcName; + apf::MeshTag *bcTag = EdgeLoop(tagName, tag); + Add("EdgeCenter", tagName, bcTag); } else if (cgnsLocation == "FaceCenter") { @@ -664,82 +608,18 @@ struct BCInfo } else if (cgnsLocation == "CellCenter") { - apf::Field *field = nullptr; - const std::string fieldName = "CellBC_" + bcName; - field = apf::createField(m, fieldName.c_str(), apf::SCALAR, apf::getConstant(2)); - - double dval[1]; - dval[0] = 0.0; - apf::MeshIterator *cellIter = m->begin(2); - apf::MeshEntity *cell = nullptr; - while ((cell = m->iterate(cellIter))) - { - apf::setComponents(field, cell, 0, dval); - } - m->end(cellIter); - - apf::Downward verts; - cellIter = m->begin(2); - int vals[1]; - while ((cell = m->iterate(cellIter))) - { - const auto numVerts = m->getDownward(cell, 0, verts); - bool allTagged = true; - for (int i = 0; i < numVerts; i++) - { - m->getIntTag(verts[i], tag, vals); - if (vals[0] == 0) - allTagged = false; - } - if (allTagged) - { - //std::cout << "Flagged cells " << numVerts << " " << allTagged << std::endl; - dval[0] = 1.0; - apf::setComponents(field, cell, 0, dval); - } - } - m->end(cellIter); - - Add("CellCenter", fieldName, field); + const std::string tagName = "CellBC_" + bcName; + apf::MeshTag *bcTag = CellLoop(tagName, tag, m->getDimension()); + Add("CellCenter", tagName, bcTag); } } else if (m->getDimension() == 1) // working with a 1D mesh { if (cgnsLocation == "Vertex") { - apf::Field *field = nullptr; - const std::string fieldName = "VertBC_" + bcName; - field = apf::createFieldOn(m, fieldName.c_str(), apf::SCALAR); - - double dval[1]; - dval[0] = 0.0; - apf::MeshIterator *vertIter = m->begin(0); - apf::MeshEntity *vert = nullptr; - while ((vert = m->iterate(vertIter))) - { - apf::setComponents(field, vert, 0, dval); - } - m->end(vertIter); - - int vals[1]; - vertIter = m->begin(0); - while ((vert = m->iterate(vertIter))) - { - bool allTagged = true; - m->getIntTag(vert, tag, vals); - if (vals[0] == 0) - allTagged = false; - - if (allTagged) - { - //std::cout << "Flagged vertices " << 1 << " " << allTagged << std::endl; - dval[0] = 1.0; - apf::setComponents(field, vert, 0, dval); - } - } - m->end(vertIter); - - Add("Vertex", fieldName, field); + const std::string tagName = "VertBC_" + bcName; + apf::MeshTag *bcTag = VertexLoop(tagName, tag); + Add("Vertex", tagName, bcTag); } else if (cgnsLocation == "EdgeCenter") { @@ -751,43 +631,9 @@ struct BCInfo } else if (cgnsLocation == "CellCenter") { - apf::Field *field = nullptr; - const std::string fieldName = "CellBC_" + bcName; - field = apf::createField(m, fieldName.c_str(), apf::SCALAR, apf::getConstant(1)); - - double dval[1]; - dval[0] = 0.0; - apf::MeshIterator *cellIter = m->begin(1); - apf::MeshEntity *cell = nullptr; - while ((cell = m->iterate(cellIter))) - { - apf::setComponents(field, cell, 0, dval); - } - m->end(cellIter); - - apf::Downward verts; - cellIter = m->begin(1); - int vals[1]; - while ((cell = m->iterate(cellIter))) - { - const auto numVerts = m->getDownward(cell, 0, verts); - bool allTagged = true; - for (int i = 0; i < numVerts; i++) - { - m->getIntTag(verts[i], tag, vals); - if (vals[0] == 0) - allTagged = false; - } - if (allTagged) - { - //std::cout << "Flagged cells " << numVerts << " " << allTagged << std::endl; - dval[0] = 1.0; - apf::setComponents(field, cell, 0, dval); - } - } - m->end(cellIter); - - Add("CellCenter", fieldName, field); + const std::string tagName = "CellBC_" + bcName; + apf::MeshTag *bcTag = CellLoop(tagName, tag, m->getDimension()); + Add("CellCenter", tagName, bcTag); } } From fc6e4d9a2524366e9d549280739b785060e8561c Mon Sep 17 00:00:00 2001 From: a-jp Date: Wed, 23 Oct 2019 16:26:34 +0100 Subject: [PATCH 32/72] remove penta6 as apf does not support that cell type --- mds/mdsCGNS.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mds/mdsCGNS.cc b/mds/mdsCGNS.cc index e7750df0f..3f504661d 100644 --- a/mds/mdsCGNS.cc +++ b/mds/mdsCGNS.cc @@ -65,13 +65,11 @@ static std::string SupportedCGNSElementTypeToString(const CGNS_ENUMT(ElementType return "TETRA_4"; else if (elementType == CGNS_ENUMV(PYRA_5)) return "PYRA_5"; - else if (elementType == CGNS_ENUMV(PENTA_6)) - return "PENTA_6"; else { std::cout << __LINE__ << " " - << "No known element type " - << " " << cg_ElementTypeName(elementType) << std::endl; + << "Element type " + << " " << cg_ElementTypeName(elementType) << " not supported by apf/PUMI " << std::endl; return ""; } } From 085097b360ee64ec792ca4c760fd16826b79d406 Mon Sep 17 00:00:00 2001 From: a-jp Date: Fri, 25 Oct 2019 15:37:48 +0100 Subject: [PATCH 33/72] comment out field conversion to tag, is only there for debugging --- mds/mdsCGNS.cc | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/mds/mdsCGNS.cc b/mds/mdsCGNS.cc index 3f504661d..c1a442536 100644 --- a/mds/mdsCGNS.cc +++ b/mds/mdsCGNS.cc @@ -324,19 +324,19 @@ struct BCInfo std::string cgnsLocation; // for debug std::unordered_set vertexIds; // zero-based global to relate to GlobalToVert apf::MeshTag *tag = nullptr; - apf::Field *field = nullptr; + // apf::Field *field = nullptr; // debug, outputting to vtk void Clean(apf::Mesh2 *m) { - m->removeField(field); - apf::destroyField(field); + // m->removeField(field); + // apf::destroyField(field); apf::removeTagFromDimension(m, tag, 0); m->destroyTag(tag); } void TagVertices(const int cgid, apf::Mesh2 *m, apf::GlobalToVert &globalToVert) { - tag = m->createIntTag(bcName.c_str(), 1); // 1 is size of tag + tag = m->createIntTag(("marker_"+bcName).c_str(), 1); // 1 is size of tag apf::MeshEntity *elem = nullptr; apf::MeshIterator *it = m->begin(0); int vals[1]; @@ -360,24 +360,24 @@ struct BCInfo } } - if (debugOutput) - //if constexpr (debugOutput) // probably will not get away with c++17 - { - // for debug output, tags aren't written to vtk... - apf::MeshEntity *elem = nullptr; - apf::MeshIterator *it = m->begin(0); - field = apf::createFieldOn(m, bcName.c_str(), apf::SCALAR); - - int vals[1]; - double dval[1]; - while ((elem = m->iterate(it))) - { - m->getIntTag(elem, tag, vals); - dval[0] = vals[0]; - apf::setComponents(field, elem, 0, dval); - } - m->end(it); - } + // if (debugOutput) + // //if constexpr (debugOutput) // probably will not get away with c++17 + // { + // // for debug output, tags aren't written to vtk... + // apf::MeshEntity *elem = nullptr; + // apf::MeshIterator *it = m->begin(0); + // field = apf::createFieldOn(m, bcName.c_str(), apf::SCALAR); + + // int vals[1]; + // double dval[1]; + // while ((elem = m->iterate(it))) + // { + // m->getIntTag(elem, tag, vals); + // dval[0] = vals[0]; + // apf::setComponents(field, elem, 0, dval); + // } + // m->end(it); + // } // Notes: // I do not exchange the tag values (even if that can be done). From 166143e155f743cb70972e56b2a42b1b92091800 Mon Sep 17 00:00:00 2001 From: a-jp Date: Fri, 25 Oct 2019 15:38:20 +0100 Subject: [PATCH 34/72] don't modify user given bc names, restart will be wrong if so --- mds/mdsCGNS.cc | 45 ++++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/mds/mdsCGNS.cc b/mds/mdsCGNS.cc index c1a442536..77dbb5223 100644 --- a/mds/mdsCGNS.cc +++ b/mds/mdsCGNS.cc @@ -561,27 +561,23 @@ struct BCInfo { if (cgnsLocation == "Vertex") { - const std::string tagName = "VertBC_" + bcName; - apf::MeshTag *bcTag = VertexLoop(tagName, tag); - Add("Vertex", tagName, bcTag); + apf::MeshTag *bcTag = VertexLoop(bcName, tag); + Add("Vertex", bcName, bcTag); } else if (cgnsLocation == "EdgeCenter") { - const std::string tagName = "EdgeBC_" + bcName; - apf::MeshTag *bcTag = EdgeLoop(tagName, tag); - Add("EdgeCenter", tagName, bcTag); + apf::MeshTag *bcTag = EdgeLoop(bcName, tag); + Add("EdgeCenter", bcName, bcTag); } else if (cgnsLocation == "FaceCenter") { - const std::string tagName = "FaceBC_" + bcName; - apf::MeshTag *bcTag = FaceLoop(tagName, tag); - Add("FaceCenter", tagName, bcTag); + apf::MeshTag *bcTag = FaceLoop(bcName, tag); + Add("FaceCenter", bcName, bcTag); } else if (cgnsLocation == "CellCenter") { - const std::string tagName = "CellBC_" + bcName; - apf::MeshTag *bcTag = CellLoop(tagName, tag, m->getDimension()); - Add("CellCenter", tagName, bcTag); + apf::MeshTag *bcTag = CellLoop(bcName, tag, m->getDimension()); + Add("CellCenter", bcName, bcTag); } else Kill(cgid, "Unknown BC Type", cgnsLocation); @@ -590,15 +586,13 @@ struct BCInfo { if (cgnsLocation == "Vertex") { - const std::string tagName = "VertBC_" + bcName; - apf::MeshTag *bcTag = VertexLoop(tagName, tag); - Add("Vertex", tagName, bcTag); + apf::MeshTag *bcTag = VertexLoop(bcName, tag); + Add("Vertex", bcName, bcTag); } else if (cgnsLocation == "EdgeCenter") { - const std::string tagName = "EdgeBC_" + bcName; - apf::MeshTag *bcTag = EdgeLoop(tagName, tag); - Add("EdgeCenter", tagName, bcTag); + apf::MeshTag *bcTag = EdgeLoop(bcName, tag); + Add("EdgeCenter", bcName, bcTag); } else if (cgnsLocation == "FaceCenter") { @@ -606,18 +600,16 @@ struct BCInfo } else if (cgnsLocation == "CellCenter") { - const std::string tagName = "CellBC_" + bcName; - apf::MeshTag *bcTag = CellLoop(tagName, tag, m->getDimension()); - Add("CellCenter", tagName, bcTag); + apf::MeshTag *bcTag = CellLoop(bcName, tag, m->getDimension()); + Add("CellCenter", bcName, bcTag); } } else if (m->getDimension() == 1) // working with a 1D mesh { if (cgnsLocation == "Vertex") { - const std::string tagName = "VertBC_" + bcName; - apf::MeshTag *bcTag = VertexLoop(tagName, tag); - Add("Vertex", tagName, bcTag); + apf::MeshTag *bcTag = VertexLoop(bcName, tag); + Add("Vertex", bcName, bcTag); } else if (cgnsLocation == "EdgeCenter") { @@ -629,9 +621,8 @@ struct BCInfo } else if (cgnsLocation == "CellCenter") { - const std::string tagName = "CellBC_" + bcName; - apf::MeshTag *bcTag = CellLoop(tagName, tag, m->getDimension()); - Add("CellCenter", tagName, bcTag); + apf::MeshTag *bcTag = CellLoop(bcName, tag, m->getDimension()); + Add("CellCenter", bcName, bcTag); } } From c120d225e32decd966fc808ff8d8b991118da304 Mon Sep 17 00:00:00 2001 From: a-jp Date: Fri, 25 Oct 2019 15:38:33 +0100 Subject: [PATCH 35/72] write out boundary conditions --- apf/apfCGNS.cc | 417 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 352 insertions(+), 65 deletions(-) diff --git a/apf/apfCGNS.cc b/apf/apfCGNS.cc index fd086cc4e..a428df579 100644 --- a/apf/apfCGNS.cc +++ b/apf/apfCGNS.cc @@ -145,70 +145,72 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap cgp_error_exit(); } - std::array, 3> coords; + apf::GlobalNumbering *gcn = nullptr; + gcn = apf::makeGlobal(apf::numberElements(m, "element-nums")); apf::GlobalNumbering *gvn = nullptr; gvn = apf::makeGlobal(apf::numberOwnedNodes(m, "node-nums")); apf::synchronize(gvn); - cgsize_t rmin[3]; - cgsize_t rmax[3]; - rmin[0] = std::numeric_limits::max(); - rmax[0] = 0; - { - apf::Vector3 point; - for (int i = 0; i < PCU_Comm_Peers(); ++i) + std::array, 3> coords; + + cgsize_t rmin[3]; + cgsize_t rmax[3]; + rmin[0] = std::numeric_limits::max(); + rmax[0] = 0; + { - if (i == PCU_Comm_Self()) + apf::Vector3 point; + for (int i = 0; i < PCU_Comm_Peers(); ++i) { - apf::MeshIterator *vertIter = m->begin(0); - apf::MeshEntity *vert = nullptr; - while ((vert = m->iterate(vertIter))) + if (i == PCU_Comm_Self()) { - if (m->isOwned(vert)) + apf::MeshIterator *vertIter = m->begin(0); + apf::MeshEntity *vert = nullptr; + while ((vert = m->iterate(vertIter))) { - const cgsize_t n = static_cast(apf::getNumber(gvn, vert, 0) + 1); // one based - rmin[0] = std::min(rmin[0], n); - rmax[0] = std::max(rmax[0], n); - - m->getPoint(vert, 0, point); - coords[0].push_back(point[0]); - coords[1].push_back(point[1]); - coords[2].push_back(point[2]); + if (m->isOwned(vert)) + { + const cgsize_t n = static_cast(apf::getNumber(gvn, vert, 0) + 1); // one based + rmin[0] = std::min(rmin[0], n); + rmax[0] = std::max(rmax[0], n); + + m->getPoint(vert, 0, point); + coords[0].push_back(point[0]); + coords[1].push_back(point[1]); + coords[2].push_back(point[2]); + } } + m->end(vertIter); } - m->end(vertIter); } } - } - // oddness of the api - rmin[1] = rmin[0]; - rmin[2] = rmin[0]; - rmax[1] = rmax[0]; - rmax[2] = rmax[0]; + // oddness of the api + rmin[1] = rmin[0]; + rmin[2] = rmin[0]; + rmax[1] = rmax[0]; + rmax[2] = rmax[0]; - if (phys_dim > 0) - { - if (cgp_coord_write_data(index, base, zone, Cx, &rmin[0], &rmax[0], coords[0].data())) - cgp_error_exit(); - } - if (phys_dim > 1) - { - if (cgp_coord_write_data(index, base, zone, Cy, &rmin[0], &rmax[0], coords[1].data())) - cgp_error_exit(); - } - if (phys_dim > 2) - { - if (cgp_coord_write_data(index, base, zone, Cz, &rmin[0], &rmax[0], coords[2].data())) - cgp_error_exit(); + if (phys_dim > 0) + { + if (cgp_coord_write_data(index, base, zone, Cx, &rmin[0], &rmax[0], coords[0].data())) + cgp_error_exit(); + } + if (phys_dim > 1) + { + if (cgp_coord_write_data(index, base, zone, Cy, &rmin[0], &rmax[0], coords[1].data())) + cgp_error_exit(); + } + if (phys_dim > 2) + { + if (cgp_coord_write_data(index, base, zone, Cz, &rmin[0], &rmax[0], coords[2].data())) + cgp_error_exit(); + } } - apf::GlobalNumbering *gcn = nullptr; - gcn = apf::makeGlobal(apf::numberElements(m, "element-nums")); - - std::vector apfElementOrder; + std::vector apfElementOrder; apfElementOrder.push_back(apf::Mesh::HEX); apfElementOrder.push_back(apf::Mesh::TET); apfElementOrder.push_back(apf::Mesh::PYRAMID); @@ -224,6 +226,14 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap cgnsElementOrder.push_back(CGNS_ENUMV(TRI_3)); cgnsElementOrder.push_back(CGNS_ENUMV(BAR_2)); + std::map apf2cgns; + apf2cgns.insert(std::make_pair(apf::Mesh::HEX, CGNS_ENUMV(HEXA_8))); + apf2cgns.insert(std::make_pair(apf::Mesh::TET, CGNS_ENUMV(TETRA_4))); + apf2cgns.insert(std::make_pair(apf::Mesh::PYRAMID, CGNS_ENUMV(PYRA_5))); + apf2cgns.insert(std::make_pair(apf::Mesh::QUAD, CGNS_ENUMV(QUAD_4))); + apf2cgns.insert(std::make_pair(apf::Mesh::TRIANGLE, CGNS_ENUMV(TRI_3))); + apf2cgns.insert(std::make_pair(apf::Mesh::EDGE, CGNS_ENUMV(BAR_2))); + std::vector globalNumbersByElementType(apfElementOrder.size(), 0); std::vector numbersByElementType(apfElementOrder.size(), 0); for (std::size_t o = 0; o < apfElementOrder.size(); o++) @@ -298,43 +308,320 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap } } // - std::cout << &cgnsBCMap << std::endl; + + const auto EdgeLoop = [&m](const auto &lambda, apf::MeshTag *edgeTag) { + apf::MeshIterator *edgeIter = m->begin(1); + apf::MeshEntity *edge = nullptr; + int vals[1]; + vals[0] = -1; + + while ((edge = m->iterate(edgeIter))) + { + m->getIntTag(edge, edgeTag, vals); + if (vals[0] == 1 && m->isOwned(edge)) + { + lambda(edge); + } + } + m->end(edgeIter); + }; + + const auto FaceLoop = [&m](const auto &lambda, apf::MeshTag *faceTag) { + apf::MeshIterator *faceIter = m->begin(2); + apf::MeshEntity *face = nullptr; + int vals[1]; + vals[0] = -1; + + while ((face = m->iterate(faceIter))) + { + m->getIntTag(face, faceTag, vals); + if (vals[0] == 1 && m->isOwned(face)) + { + lambda(face); + } + } + m->end(faceIter); + }; + + const auto BCEntityAdder = [&apf2cgns, &m, &index, &zone, &base, &gvn](const auto &Looper, const auto &bcGroup, int &startingLocation) { + std::map> bcEntTypes; + for (const auto &r : apf2cgns) + bcEntTypes.insert(std::make_pair(r.first, std::vector())); + + const auto lambda = [&m, &bcEntTypes](apf::MeshEntity *entity) { + const auto type = m->getType(entity); + auto iter = bcEntTypes.find(type); + if (iter != bcEntTypes.end()) + { + iter->second.push_back(entity); + } + else + { + PCU_ALWAYS_ASSERT_VERBOSE(true == false, "must not come in here"); + } + }; + // + Looper(lambda, bcGroup.second); + // + const int cacheStart = startingLocation + 1; + int cacheEnd = -1; + for (const auto &bc : bcEntTypes) + { + int startOfBCBlock = startingLocation + 1; + const int number = bc.second.size(); + int total = number; + PCU_Add_Ints(&total, 1); // size of total array + if (total > 0) + { + const auto allEnd = startOfBCBlock + total - 1; //one-based + int sectionNumber = -1; + const std::string name = bcGroup.first + " " + std::to_string(startOfBCBlock) + "->" + std::to_string(allEnd); //cg_ElementTypeName(apf2cgns[bc.first]); + if (cgp_section_write(index, base, zone, name.c_str(), apf2cgns[bc.first], startOfBCBlock, allEnd, 0, + §ionNumber)) + cgp_error_exit(); + + std::vector elements; + for (std::size_t e = 0; e < bc.second.size(); e++) + { + apf::Downward verts; + const auto numVerts = m->getDownward(bc.second[e], 0, verts); + for (int i = 0; i < numVerts; i++) + { + const auto n = apf::getNumber(gvn, verts[i], 0); + elements.push_back(n + 1); // one-based + } + } + + std::vector allNumbersForThisType(PCU_Comm_Peers(), 0); + MPI_Allgather(&number, 1, MPI_INT, allNumbersForThisType.data(), 1, + MPI_INT, PCU_Get_Comm()); + + cgsize_t num = 0; + for (int i = 0; i < PCU_Comm_Self(); i++) + num += allNumbersForThisType[i]; + + cgsize_t elStart = startOfBCBlock + num; + cgsize_t elEnd = elStart + number - 1; // one-based stuff + + if (number == 0) + { + if (cgp_elements_write_data(index, base, zone, sectionNumber, elStart, elEnd, nullptr)) + cgp_error_exit(); + } + else + { + if (cgp_elements_write_data(index, base, zone, sectionNumber, elStart, elEnd, + elements.data())) + cgp_error_exit(); + } + + // Not parallel correct + startingLocation = allEnd; + cacheEnd = allEnd; + } + } + std::vector cacheStarts(PCU_Comm_Peers(), 0); + MPI_Allgather(&cacheStart, 1, MPI_INT, cacheStarts.data(), 1, + MPI_INT, PCU_Get_Comm()); + std::vector cacheEnds(PCU_Comm_Peers(), 0); + MPI_Allgather(&cacheEnd, 1, MPI_INT, cacheEnds.data(), 1, + MPI_INT, PCU_Get_Comm()); + return std::make_pair(cacheStarts, cacheEnds); + }; + + const auto globalElementList = [](const std::vector &bcList, std::vector &allElements) { + std::vector sizes(PCU_Comm_Peers(), 0); // important initialiser + const int l = bcList.size(); + MPI_Allgather(&l, 1, MPI_INT, sizes.data(), 1, + MPI_INT, PCU_Get_Comm()); + + int totalLength = 0; + for (const auto &i : sizes) + totalLength += i; + + std::vector displacement(PCU_Comm_Peers(), -1); + displacement[0] = 0; + for (std::size_t i = 1; i < displacement.size(); i++) + displacement[i] = displacement[i - 1] + sizes[i - 1]; + + allElements.resize(totalLength); + MPI_Allgatherv(bcList.data(), bcList.size(), MPI_INT, allElements.data(), + sizes.data(), displacement.data(), MPI_INT, + PCU_Get_Comm()); + }; + + const auto doVertexBC = [&](const auto &iter) { + for (const auto &p : iter->second) + { + std::vector bcList; + apf::MeshIterator *vertIter = m->begin(0); + apf::MeshEntity *vert = nullptr; + int vals[1]; + vals[0] = -1; + + while ((vert = m->iterate(vertIter))) + { + m->getIntTag(vert, p.second, vals); + if (vals[0] == 1 && m->isOwned(vert)) + { + const auto n = apf::getNumber(gvn, vert, 0); + bcList.push_back(n + 1); // one-based + } + } + m->end(vertIter); + + std::vector allElements; + globalElementList(bcList, allElements); + + int bcIndex = -1; + if (cg_boco_write(index, base, zone, p.first.c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointList), allElements.size(), + allElements.data(), &bcIndex)) + cg_error_exit(); + + CGNS_ENUMT(GridLocation_t) + location = CGNS_ENUMV(Vertex); + if (cg_boco_gridlocation_write(index, base, zone, bcIndex, location)) + cg_error_exit(); + } + }; + + const auto doEdgeBC = [&](const auto &iter, int& startingLocation) { + for (const auto &p : iter->second) + { + const auto se = BCEntityAdder(EdgeLoop, p, startingLocation); + for (int i = 0; i < PCU_Comm_Peers(); i++) + { + PCU_ALWAYS_ASSERT_VERBOSE(se.first[i] == se.first[0], "Must all be the same "); + PCU_ALWAYS_ASSERT_VERBOSE(se.second[i] == se.second[0], "Must all be the same "); + } + + const std::array bcRange = {{se.first[0], se.second[0]}}; + int bcIndex = -1; + if (cg_boco_write(index, base, zone, p.first.c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointRange), 2, + bcRange.data(), &bcIndex)) + cg_error_exit(); + + CGNS_ENUMT(GridLocation_t) + location = CGNS_ENUMV(EdgeCenter); + if (cg_boco_gridlocation_write(index, base, zone, bcIndex, location)) + cg_error_exit(); + } + }; + + const auto doFaceBC = [&](const auto &iter, int& startingLocation) { + for (const auto &p : iter->second) + { + const auto se = BCEntityAdder(FaceLoop, p, startingLocation); + + for (int i = 0; i < PCU_Comm_Peers(); i++) + { + PCU_ALWAYS_ASSERT_VERBOSE(se.first[i] == se.first[0], "Must all be the same "); + PCU_ALWAYS_ASSERT_VERBOSE(se.second[i] == se.second[0], "Must all be the same "); + } + const std::array bcRange = {{se.first[0], se.second[0]}}; + int bcIndex = -1; + if (cg_boco_write(index, base, zone, p.first.c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointRange), 2, + bcRange.data(), &bcIndex)) + cg_error_exit(); + + CGNS_ENUMT(GridLocation_t) + location = CGNS_ENUMV(FaceCenter); + if (cg_boco_gridlocation_write(index, base, zone, bcIndex, location)) + cg_error_exit(); + } + }; + + const auto doCellBC = [&](const auto &iter, const int& dim) { + for (const auto &p : iter->second) + { + std::vector bcList; + apf::MeshIterator *cellIter = m->begin(dim); + apf::MeshEntity *cell = nullptr; + int vals[1]; + vals[0] = -1; + + while ((cell = m->iterate(cellIter))) + { + m->getIntTag(cell, p.second, vals); + if (vals[0] == 1 && m->isOwned(cell)) + { + const auto n = apf::getNumber(gcn, cell, 0); + bcList.push_back(n + 1); // one-based + } + } + m->end(cellIter); + + std::vector allElements; + globalElementList(bcList, allElements); + + int bcIndex = -1; + if (cg_boco_write(index, base, zone, p.first.c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointList), allElements.size(), + allElements.data(), &bcIndex)) + cg_error_exit(); + + CGNS_ENUMT(GridLocation_t) + location = CGNS_ENUMV(CellCenter); + if (cg_boco_gridlocation_write(index, base, zone, bcIndex, location)) + cg_error_exit(); + } + }; + if (cell_dim == 3) { + int startingLocation = cellCount.first; + auto iter = cgnsBCMap.find("Vertex"); if (iter != cgnsBCMap.end()) { - for (const auto &p : iter->second) - { - std::cout << iter->first << " " << p.first << " " << p.second << std::endl; - } + doVertexBC(iter); } iter = cgnsBCMap.find("EdgeCenter"); if (iter != cgnsBCMap.end()) { - for (const auto &p : iter->second) - { - std::cout << iter->first << " " << p.first << " " << p.second << std::endl; - } + doEdgeBC(iter, startingLocation); } iter = cgnsBCMap.find("FaceCenter"); if (iter != cgnsBCMap.end()) { - for (const auto &p : iter->second) - { - std::cout << iter->first << " " << p.first << " " << p.second << std::endl; - auto* field = m->findTag(p.first.c_str()); - std::cout << field << " " << p.second << std::endl; + doFaceBC(iter, startingLocation); + } + iter = cgnsBCMap.find("CellCenter"); + if (iter != cgnsBCMap.end()) + { + doCellBC(iter, 3); + } + } + else if (cell_dim == 2) + { + int startingLocation = cellCount.first; - } + auto iter = cgnsBCMap.find("Vertex"); + if (iter != cgnsBCMap.end()) + { + doVertexBC(iter); + } + iter = cgnsBCMap.find("EdgeCenter"); + if (iter != cgnsBCMap.end()) + { + doEdgeBC(iter, startingLocation); } iter = cgnsBCMap.find("CellCenter"); if (iter != cgnsBCMap.end()) { - for (const auto &p : iter->second) - { - std::cout << iter->first << " " << p.first << " " << p.second << std::endl; - } + doCellBC(iter, 2); + } + } + else if (cell_dim == 1) + { + auto iter = cgnsBCMap.find("Vertex"); + if (iter != cgnsBCMap.end()) + { + doVertexBC(iter); + } + iter = cgnsBCMap.find("CellCenter"); + if (iter != cgnsBCMap.end()) + { + doCellBC(iter, 1); } } // From 28bb5637f42084e9a3c8979f68da60766ce6f653 Mon Sep 17 00:00:00 2001 From: a-jp Date: Wed, 30 Oct 2019 16:07:11 +0000 Subject: [PATCH 36/72] starting the writing of tags and fields --- apf/apfCGNS.cc | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/apf/apfCGNS.cc b/apf/apfCGNS.cc index a428df579..17129ca32 100644 --- a/apf/apfCGNS.cc +++ b/apf/apfCGNS.cc @@ -485,7 +485,7 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap } }; - const auto doEdgeBC = [&](const auto &iter, int& startingLocation) { + const auto doEdgeBC = [&](const auto &iter, int &startingLocation) { for (const auto &p : iter->second) { const auto se = BCEntityAdder(EdgeLoop, p, startingLocation); @@ -508,7 +508,7 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap } }; - const auto doFaceBC = [&](const auto &iter, int& startingLocation) { + const auto doFaceBC = [&](const auto &iter, int &startingLocation) { for (const auto &p : iter->second) { const auto se = BCEntityAdder(FaceLoop, p, startingLocation); @@ -531,7 +531,7 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap } }; - const auto doCellBC = [&](const auto &iter, const int& dim) { + const auto doCellBC = [&](const auto &iter, const int &dim) { for (const auto &p : iter->second) { std::vector bcList; @@ -588,7 +588,7 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap iter = cgnsBCMap.find("CellCenter"); if (iter != cgnsBCMap.end()) { - doCellBC(iter, 3); + doCellBC(iter, 3); } } else if (cell_dim == 2) @@ -608,7 +608,7 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap iter = cgnsBCMap.find("CellCenter"); if (iter != cgnsBCMap.end()) { - doCellBC(iter, 2); + doCellBC(iter, 2); } } else if (cell_dim == 1) @@ -621,13 +621,41 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap iter = cgnsBCMap.find("CellCenter"); if (iter != cgnsBCMap.end()) { - doCellBC(iter, 1); + doCellBC(iter, 1); } } + // destroyGlobalNumbering(gvn); destroyGlobalNumbering(gcn); // + + + apf::DynamicArray tags; + m->getTags(tags); + for (std::size_t i = 0; i < tags.getSize(); ++i) + { + apf::MeshTag *t = tags[i]; + // create a new tag on the outMesh + int tagType = m->getTagType(t); + int tagSize = m->getTagSize(t); + const char *tagName = m->getTagName(t); + + apf::MeshEntity *e; + apf::MeshIterator *it = m->begin(m->getDimension()); + bool keepGoing = true; + while ( (e = m->iterate(it)) && keepGoing ) + { + if (m->hasTag(e, t)) + { + std::cout << "Cell tags " << tagName << " " << tagType << " " << tagSize << std::endl; + keepGoing = false; + } + } + m->end(it); + } + + cgp_close(index); } } // namespace From 15ff4559b556452d341a89931f9ccc9d446405a0 Mon Sep 17 00:00:00 2001 From: a-jp Date: Mon, 4 Nov 2019 13:38:43 +0000 Subject: [PATCH 37/72] reduce name length to stick within cgns defined 32 char limit --- test/cgns.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/cgns.cc b/test/cgns.cc index 06d5f56b4..44a1c4636 100644 --- a/test/cgns.cc +++ b/test/cgns.cc @@ -76,7 +76,7 @@ void simpleReorder(const std::string &prefix, apf::Mesh2 *m) { { apf::GlobalNumbering *gn = nullptr; - gn = apf::makeGlobal(apf::numberOwnedNodes(m, "vertex Indices_prereorder")); + gn = apf::makeGlobal(apf::numberOwnedNodes(m, "vert Idx_preOrder")); apf::synchronize(gn); } // no synchronize call @@ -84,7 +84,7 @@ void simpleReorder(const std::string &prefix, apf::Mesh2 *m) // https://github.com/SCOREC/core/issues/249 { apf::GlobalNumbering *gn = nullptr; - gn = apf::makeGlobal(apf::numberElements(m, "element Indices_prereorder")); + gn = apf::makeGlobal(apf::numberElements(m, "elem Idx_preOrder")); } //apf::MeshTag *order = Parma_BfsReorder(m); @@ -93,7 +93,7 @@ void simpleReorder(const std::string &prefix, apf::Mesh2 *m) { apf::GlobalNumbering *gn = nullptr; - gn = apf::makeGlobal(apf::numberOwnedNodes(m, "vertex Indices_postreorder")); + gn = apf::makeGlobal(apf::numberOwnedNodes(m, "vert Idx_pstOrder")); apf::synchronize(gn); } // no synchronize call @@ -101,7 +101,7 @@ void simpleReorder(const std::string &prefix, apf::Mesh2 *m) // https://github.com/SCOREC/core/issues/249 { apf::GlobalNumbering *gn = nullptr; - gn = apf::makeGlobal(apf::numberElements(m, "element Indices_postreorder")); + gn = apf::makeGlobal(apf::numberElements(m, "elem Idx_pstOrder")); } const std::string name = prefix + "_reorder_" + std::to_string(PCU_Comm_Peers()) + "procs"; From 536be4b935c7e4adbe23b5fb4ebc4fc0b5988802 Mon Sep 17 00:00:00 2001 From: a-jp Date: Mon, 4 Nov 2019 13:39:33 +0000 Subject: [PATCH 38/72] mainly debug output --- mds/mdsCGNS.cc | 131 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 106 insertions(+), 25 deletions(-) diff --git a/mds/mdsCGNS.cc b/mds/mdsCGNS.cc index 77dbb5223..3aeac2dc4 100644 --- a/mds/mdsCGNS.cc +++ b/mds/mdsCGNS.cc @@ -324,19 +324,20 @@ struct BCInfo std::string cgnsLocation; // for debug std::unordered_set vertexIds; // zero-based global to relate to GlobalToVert apf::MeshTag *tag = nullptr; - // apf::Field *field = nullptr; // debug, outputting to vtk + apf::Field *field = nullptr; // debug, outputting to vtk void Clean(apf::Mesh2 *m) { - // m->removeField(field); - // apf::destroyField(field); + m->removeField(field); + apf::destroyField(field); apf::removeTagFromDimension(m, tag, 0); m->destroyTag(tag); } void TagVertices(const int cgid, apf::Mesh2 *m, apf::GlobalToVert &globalToVert) { - tag = m->createIntTag(("marker_"+bcName).c_str(), 1); // 1 is size of tag + // tm = tag marker for that bcName, fm = field marker for that bcName + tag = m->createIntTag(("tm_" + bcName).c_str(), 1); // 1 is size of tag apf::MeshEntity *elem = nullptr; apf::MeshIterator *it = m->begin(0); int vals[1]; @@ -360,24 +361,24 @@ struct BCInfo } } - // if (debugOutput) - // //if constexpr (debugOutput) // probably will not get away with c++17 - // { - // // for debug output, tags aren't written to vtk... - // apf::MeshEntity *elem = nullptr; - // apf::MeshIterator *it = m->begin(0); - // field = apf::createFieldOn(m, bcName.c_str(), apf::SCALAR); - - // int vals[1]; - // double dval[1]; - // while ((elem = m->iterate(it))) - // { - // m->getIntTag(elem, tag, vals); - // dval[0] = vals[0]; - // apf::setComponents(field, elem, 0, dval); - // } - // m->end(it); - // } + if (debugOutput) + //if constexpr (debugOutput) // probably will not get away with c++17 + { + // for debug output, tags aren't written to vtk... + apf::MeshEntity *elem = nullptr; + apf::MeshIterator *it = m->begin(0); + field = apf::createFieldOn(m, ("fm_" + bcName).c_str(), apf::SCALAR); + + int vals[1]; + double dval[1]; + while ((elem = m->iterate(it))) + { + m->getIntTag(elem, tag, vals); + dval[0] = vals[0]; + apf::setComponents(field, elem, 0, dval); + } + m->end(it); + } // Notes: // I do not exchange the tag values (even if that can be done). @@ -444,6 +445,26 @@ struct BCInfo } } m->end(vertIter); + + if (debugOutput) + //if constexpr (debugOutput) // probably will not get away with c++17 + { + // for debug output, tags aren't written to vtk... + apf::MeshEntity *elem = nullptr; + apf::MeshIterator *it = m->begin(0); + auto* field = apf::createFieldOn(m, ("debug_" + tagName).c_str(), apf::SCALAR); + + int vals[1]; + double dval[1]; + while ((elem = m->iterate(it))) + { + m->getIntTag(elem, bcTag, vals); + dval[0] = vals[0]; + apf::setComponents(field, elem, 0, dval); + } + m->end(it); + } + return bcTag; }; @@ -480,6 +501,26 @@ struct BCInfo } } m->end(edgeIter); + + if (debugOutput) + //if constexpr (debugOutput) // probably will not get away with c++17 + { + // for debug output, tags aren't written to vtk... + apf::MeshEntity *elem = nullptr; + apf::MeshIterator *it = m->begin(1); + auto* field = apf::createField(m, ("debug_" + tagName).c_str(), apf::SCALAR, apf::getConstant(1)); + + int vals[1]; + double dval[1]; + while ((elem = m->iterate(it))) + { + m->getIntTag(elem, bcTag, vals); + dval[0] = vals[0]; + apf::setComponents(field, elem, 0, dval); + } + m->end(it); + } + return bcTag; }; @@ -517,13 +558,32 @@ struct BCInfo } m->end(faceIter); + if (debugOutput) + //if constexpr (debugOutput) // probably will not get away with c++17 + { + // for debug output, tags aren't written to vtk... + apf::MeshEntity *elem = nullptr; + apf::MeshIterator *it = m->begin(2); + auto* field = apf::createField(m, ("debug_" + tagName).c_str(), apf::SCALAR, apf::getConstant(2)); + + int vals[1]; + double dval[1]; + while ((elem = m->iterate(it))) + { + m->getIntTag(elem, bcTag, vals); + dval[0] = vals[0]; + apf::setComponents(field, elem, 0, dval); + } + m->end(it); + } + return bcTag; }; const auto CellLoop = [&m](const std::string &tagName, apf::MeshTag *vertexTag, int dim) { apf::MeshTag *bcTag = nullptr; bcTag = m->createIntTag(tagName.c_str(), 1); // 1 is size of tag - + apf::MeshIterator *cellIter = m->begin(dim); apf::MeshEntity *cell = nullptr; int vals[1]; @@ -554,6 +614,25 @@ struct BCInfo } m->end(cellIter); + if (debugOutput) + //if constexpr (debugOutput) // probably will not get away with c++17 + { + // for debug output, tags aren't written to vtk... + apf::MeshEntity *elem = nullptr; + apf::MeshIterator *it = m->begin(dim); + auto* field = apf::createField(m, ("debug_" + tagName).c_str(), apf::SCALAR, apf::getConstant(dim)); + + int vals[1]; + double dval[1]; + while ((elem = m->iterate(it))) + { + m->getIntTag(elem, bcTag, vals); + dval[0] = vals[0]; + apf::setComponents(field, elem, 0, dval); + } + m->end(it); + } + return bcTag; }; @@ -826,6 +905,8 @@ void ReadBCInfo(const int cgid, const int base, const int zone, const int nBocos apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCMap) { + static_assert(std::is_same::value, "cgsize_t not compiled as int"); + int cgid = -1; auto comm = PCU_Get_Comm(); cgp_mpi_comm(comm); @@ -1007,7 +1088,7 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM apf::verify(mesh, true); { apf::GlobalNumbering *gn = nullptr; - gn = apf::makeGlobal(apf::numberOwnedNodes(mesh, "vertex Indices")); + gn = apf::makeGlobal(apf::numberOwnedNodes(mesh, "vert Idx")); apf::synchronize(gn); } // no synchronize call @@ -1015,7 +1096,7 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM // https://github.com/SCOREC/core/issues/249 { apf::GlobalNumbering *gn = nullptr; - gn = apf::makeGlobal(apf::numberElements(mesh, "element Indices")); + gn = apf::makeGlobal(apf::numberElements(mesh, "elem Idx")); } for (auto &bc : bcInfos) From 514057a975f2c543af139f3c78536fcdcec5d835 Mon Sep 17 00:00:00 2001 From: a-jp Date: Mon, 4 Nov 2019 13:39:52 +0000 Subject: [PATCH 39/72] bug fixes --- apf/apfCGNS.cc | 225 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 184 insertions(+), 41 deletions(-) diff --git a/apf/apfCGNS.cc b/apf/apfCGNS.cc index 17129ca32..0ce2b35de 100644 --- a/apf/apfCGNS.cc +++ b/apf/apfCGNS.cc @@ -50,6 +50,8 @@ static auto count(apf::Mesh *m, int dim) void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap) { + static_assert(std::is_same::value, "cgsize_t not compiled as int"); + //ShowNumbering(m); const auto myRank = PCU_Comm_Self(); @@ -84,9 +86,9 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap } std::array sizes; - sizes[0] = vertexCount.first; - sizes[1] = cellCount.first; - sizes[2] = 0; // nodes are unsorted. + sizes[0] = vertexCount.first; // global + sizes[1] = cellCount.first; // global + sizes[2] = 0; // nodes are unsorted, as defined by api // Copy communicator auto communicator = PCU_Get_Comm(); @@ -123,8 +125,6 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap cg_error_exit(); } - static_assert(std::is_same::value, "cgsize_t not compiled as int"); - int Cx = -1; int Cy = -1; int Cz = -1; @@ -153,12 +153,12 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap apf::synchronize(gvn); { + cgsize_t vertexMin[3]; + cgsize_t vertexMax[3]; std::array, 3> coords; - cgsize_t rmin[3]; - cgsize_t rmax[3]; - rmin[0] = std::numeric_limits::max(); - rmax[0] = 0; + vertexMin[0] = std::numeric_limits::max(); + vertexMax[0] = 0; { apf::Vector3 point; @@ -173,8 +173,8 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap if (m->isOwned(vert)) { const cgsize_t n = static_cast(apf::getNumber(gvn, vert, 0) + 1); // one based - rmin[0] = std::min(rmin[0], n); - rmax[0] = std::max(rmax[0], n); + vertexMin[0] = std::min(vertexMin[0], n); + vertexMax[0] = std::max(vertexMax[0], n); m->getPoint(vert, 0, point); coords[0].push_back(point[0]); @@ -188,24 +188,24 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap } // oddness of the api - rmin[1] = rmin[0]; - rmin[2] = rmin[0]; - rmax[1] = rmax[0]; - rmax[2] = rmax[0]; + vertexMin[1] = vertexMin[0]; + vertexMin[2] = vertexMin[0]; + vertexMax[1] = vertexMax[0]; + vertexMax[2] = vertexMax[0]; if (phys_dim > 0) { - if (cgp_coord_write_data(index, base, zone, Cx, &rmin[0], &rmax[0], coords[0].data())) + if (cgp_coord_write_data(index, base, zone, Cx, &vertexMin[0], &vertexMax[0], coords[0].data())) cgp_error_exit(); } if (phys_dim > 1) { - if (cgp_coord_write_data(index, base, zone, Cy, &rmin[0], &rmax[0], coords[1].data())) + if (cgp_coord_write_data(index, base, zone, Cy, &vertexMin[0], &vertexMax[0], coords[1].data())) cgp_error_exit(); } if (phys_dim > 2) { - if (cgp_coord_write_data(index, base, zone, Cz, &rmin[0], &rmax[0], coords[2].data())) + if (cgp_coord_write_data(index, base, zone, Cz, &vertexMin[0], &vertexMax[0], coords[2].data())) cgp_error_exit(); } } @@ -258,6 +258,7 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap PCU_ALWAYS_ASSERT_VERBOSE(allTotal == cellCount.first, ("Must be equal " + std::to_string(allTotal) + " " + std::to_string(cellCount.first)).c_str()); int globalStart = 1; // one-based + std::vector orderedElements; for (std::size_t o = 0; o < apfElementOrder.size(); o++) { std::vector elements; @@ -275,6 +276,7 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap const auto n = apf::getNumber(gvn, verts[i], 0); elements.push_back(n + 1); // one-based } + orderedElements.push_back(cell); } } m->end(cellIter); @@ -625,39 +627,180 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap } } - // - destroyGlobalNumbering(gvn); - destroyGlobalNumbering(gcn); - // + const auto loopTags = [&m](const std::vector &orderedEnts, const int &solIndex, const auto &inner, const auto &post, apf::GlobalNumbering *numbering) { + apf::DynamicArray tags; + m->getTags(tags); + for (std::size_t i = 0; i < tags.getSize(); ++i) + { + apf::MeshTag *t = tags[i]; + const int tagType = m->getTagType(t); + const int tagSize = m->getTagSize(t); + std::string tagName(m->getTagName(t)); + tagName.resize(32); // daft api + //std::cout << i << " " << tagName << " " << m->getTagName(t) << std::endl; + + // boring... replace with variant + std::vector idata; + std::vector ddata; + std::vector ldata; + + if (tagSize != 1) + { + std::cout << "Not finished yet, can't be that hard..." << std::endl; + exit(-1); + } + + cgsize_t rmin[3]; + cgsize_t rmax[3]; + + rmin[0] = std::numeric_limits::max(); + rmax[0] = 0; + + for (const auto &e: orderedEnts) + { + if (m->hasTag(e, t) && m->isOwned(e)) + { + //std::cout << "Tags for dim " << dim << " " << tagName << " " << tagType << " " << tagSize << std::endl; + inner(e, t, idata, ddata, ldata, tagType); + const cgsize_t n = static_cast(apf::getNumber(numbering, e, 0) + 1); // one based + rmin[0] = std::min(rmin[0], n); + rmax[0] = std::max(rmax[0], n); + } + } + + // oddness of the api + rmin[1] = rmin[0]; + rmin[2] = rmin[0]; + rmax[1] = rmax[0]; + rmax[2] = rmax[0]; + post(solIndex, tagName, idata, ddata, ldata, rmin, rmax); + } + }; + + const auto postLambda = [&index, &base, &zone](const int &solIndex, const std::string &name, std::vector &idata, std::vector &ddata, std::vector &ldata, const cgsize_t *rmin, const cgsize_t *rmax) { + if (!ddata.empty()) + { + int fieldIndex = -1; + + if (cgp_field_write(index, base, zone, solIndex, CGNS_ENUMV(RealDouble), name.c_str(), &fieldIndex)) + cgp_error_exit(); + + if (cgp_field_write_data(index, base, zone, solIndex, fieldIndex, &rmin[0], &rmax[0], + ddata.data())) + cgp_error_exit(); + } + else if (!idata.empty()) + { + int fieldIndex = -1; + + if (cgp_field_write(index, base, zone, solIndex, CGNS_ENUMV(Integer), name.c_str(), &fieldIndex)) + cgp_error_exit(); + + if (cgp_field_write_data(index, base, zone, solIndex, fieldIndex, &rmin[0], &rmax[0], + idata.data())) + cgp_error_exit(); + } + else if (!ldata.empty()) + { + int fieldIndex = -1; + + if (cgp_field_write(index, base, zone, solIndex, CGNS_ENUMV(LongInteger), name.c_str(), &fieldIndex)) + cgp_error_exit(); + + if (cgp_field_write_data(index, base, zone, solIndex, fieldIndex, &rmin[0], &rmax[0], + ldata.data())) + cgp_error_exit(); + } + }; + + const auto innerLambda = [&m](apf::MeshEntity *elem, apf::MeshTag *tag, std::vector &idata, std::vector &ddata, std::vector &ldata, const int &tagType) { + if (tagType == apf::Mesh::TagType::DOUBLE) + { + double vals = -1; + m->getDoubleTag(elem, tag, &vals); + ddata.push_back(vals); + } + else if (tagType == apf::Mesh::TagType::INT) + { + int vals = -1; + m->getIntTag(elem, tag, &vals); + idata.push_back(vals); + } + else if (tagType == apf::Mesh::TagType::LONG) + { + long vals = -1; + m->getLongTag(elem, tag, &vals); + ldata.push_back(vals); + } + else + { + std::cout << "Strange" << std::endl; + exit(-1); + } + }; + + int solIndex = -1; - apf::DynamicArray tags; - m->getTags(tags); - for (std::size_t i = 0; i < tags.getSize(); ++i) { - apf::MeshTag *t = tags[i]; - // create a new tag on the outMesh - int tagType = m->getTagType(t); - int tagSize = m->getTagSize(t); - const char *tagName = m->getTagName(t); - - apf::MeshEntity *e; - apf::MeshIterator *it = m->begin(m->getDimension()); - bool keepGoing = true; - while ( (e = m->iterate(it)) && keepGoing ) - { - if (m->hasTag(e, t)) + if (cg_sol_write(index, base, zone, "Vertex Data", CGNS_ENUMV(Vertex), &solIndex)) + cg_error_exit(); + + std::vector orderedVertices; + apf::MeshIterator *vertIter = m->begin(0); + apf::MeshEntity *vert = nullptr; + while ((vert = m->iterate(vertIter))) + { + if (m->isOwned(vert)) { - std::cout << "Cell tags " << tagName << " " << tagType << " " << tagSize << std::endl; - keepGoing = false; + orderedVertices.push_back(vert); } } - m->end(it); + m->end(vertIter); + + loopTags(orderedVertices, solIndex, innerLambda, postLambda, gvn); } + { + if (cg_sol_write(index, base, zone, "Cell Data", CGNS_ENUMV(CellCenter), &solIndex)) + cg_error_exit(); + + loopTags(orderedElements, solIndex, innerLambda, postLambda, gcn); + } + + const auto loopFields = [&m](int dim) { + for (int i = 0; i < m->countFields(); ++i) + { + apf::Field *f = m->getField(i); + int fieldType = f->getScalarType(); + int fieldSize = f->countComponents(); + const char *fieldName = f->getName(); + + apf::MeshEntity *e; + apf::MeshIterator *it = m->begin(dim); + bool keepGoing = true; + apf::FieldData *fd = f->getData(); + while ((e = m->iterate(it)) && keepGoing) + { + if (fd->hasEntity(e)) + { + std::cout << "Fields for dim " << dim << " " << fieldName << " " << fieldType << " " << fieldSize << std::endl; + keepGoing = false; + } + } + m->end(it); + } + }; + + for (int i = 0; i <= m->getDimension(); i++) + loopFields(i); + // + destroyGlobalNumbering(gvn); + destroyGlobalNumbering(gcn); + // cgp_close(index); -} +} // namespace } // namespace namespace apf From 46b1c361797b8ffecdfe16274bf78a67c04e3495 Mon Sep 17 00:00:00 2001 From: a-jp Date: Fri, 15 Nov 2019 12:14:13 +0000 Subject: [PATCH 40/72] append debug to field and tag names --- mds/mdsCGNS.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mds/mdsCGNS.cc b/mds/mdsCGNS.cc index 3aeac2dc4..418ffb7d5 100644 --- a/mds/mdsCGNS.cc +++ b/mds/mdsCGNS.cc @@ -336,8 +336,8 @@ struct BCInfo void TagVertices(const int cgid, apf::Mesh2 *m, apf::GlobalToVert &globalToVert) { - // tm = tag marker for that bcName, fm = field marker for that bcName - tag = m->createIntTag(("tm_" + bcName).c_str(), 1); // 1 is size of tag + // tm = "tag marker" for that bcName, fm = "field marker" for that bcName + tag = m->createIntTag(("debug_tm_" + bcName).c_str(), 1); // 1 is size of tag apf::MeshEntity *elem = nullptr; apf::MeshIterator *it = m->begin(0); int vals[1]; @@ -367,7 +367,7 @@ struct BCInfo // for debug output, tags aren't written to vtk... apf::MeshEntity *elem = nullptr; apf::MeshIterator *it = m->begin(0); - field = apf::createFieldOn(m, ("fm_" + bcName).c_str(), apf::SCALAR); + field = apf::createFieldOn(m, ("debug_fm_" + bcName).c_str(), apf::SCALAR); int vals[1]; double dval[1]; @@ -383,7 +383,7 @@ struct BCInfo // Notes: // I do not exchange the tag values (even if that can be done). // I'm assuming in parallel all partitions that need the vertex that - // falls within a given group mark that vertex accordingly. + // falls within a given group will mark that vertex accordingly. // I assume therefore that vertices on a processor boundary, are marked // by all procs that share it. // TODO: generate test that proves this works. Done: for quads tested 4-way From 5465bae8f77842a1dafc8566953efa585c3d45e6 Mon Sep 17 00:00:00 2001 From: a-jp Date: Fri, 15 Nov 2019 12:14:37 +0000 Subject: [PATCH 41/72] write todo to screen as work should feature as part of regression test --- test/cgns.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/cgns.cc b/test/cgns.cc index 44a1c4636..e44f37dd3 100644 --- a/test/cgns.cc +++ b/test/cgns.cc @@ -280,7 +280,7 @@ int main(int argc, char **argv) if (additionalTests) cleanUp = additional(prefix, g, m); // - apf::writeCGNS((prefix + "_outputFile.cgns").c_str(), m, cgnsBCMap); + apf::writeCGNS((prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + "_outputFile.cgns").c_str(), m, cgnsBCMap); // if (additionalTests) { @@ -292,6 +292,8 @@ int main(int argc, char **argv) apf::destroyMesh(m); } // + std::cout << "TODO: Must read in newly created mesh, and check that it can perform same functions as initial mesh: see if I can diff the two" << std::endl; + // PCU_Comm_Free(); MPI_Finalize(); return 0; From d58e35838ce848fb8b4ec4ca7f633c6998539f57 Mon Sep 17 00:00:00 2001 From: a-jp Date: Fri, 15 Nov 2019 12:14:59 +0000 Subject: [PATCH 42/72] write tags and fields for vertices and cells to main base in mesh --- apf/apfCGNS.cc | 873 +++++++++++++++++++++++++++---------------------- 1 file changed, 491 insertions(+), 382 deletions(-) diff --git a/apf/apfCGNS.cc b/apf/apfCGNS.cc index 0ce2b35de..348c643a5 100644 --- a/apf/apfCGNS.cc +++ b/apf/apfCGNS.cc @@ -40,7 +40,8 @@ namespace { //https://proteustoolkit.org/capi/html/_parallel_mesh_converter_8cpp_source.html -static auto count(apf::Mesh *m, int dim) +using Count = std::pair; +static Count count(apf::Mesh *m, int dim) { const int local = apf::countOwned(m, dim); int total = local; @@ -48,269 +49,273 @@ static auto count(apf::Mesh *m, int dim) return std::make_pair(total, local); } -void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap) +struct CGNS { - static_assert(std::is_same::value, "cgsize_t not compiled as int"); + int index = -1; + int base = -1; + int zone = -1; + const int phys_dim = 3; +}; - //ShowNumbering(m); +void WriteTagsToMainBase(const CGNS &cgns, const std::vector &orderedEnts, apf::Mesh *m, apf::GlobalNumbering *gvn, apf::GlobalNumbering *gcn) +{ + const auto loopTags = [&m](const auto &orderedEnts, const int &solIndex, const auto &inner, const auto &post, apf::GlobalNumbering *numbering) { + apf::DynamicArray tags; + m->getTags(tags); + for (std::size_t i = 0; i < tags.getSize(); ++i) + { + apf::MeshTag *t = tags[i]; + const int tagType = m->getTagType(t); + const int tagSize = m->getTagSize(t); + std::string tagName(m->getTagName(t)); + tagName.resize(32); // daft api + //std::cout << i << " " << tagName << " " << m->getTagName(t) << std::endl; - const auto myRank = PCU_Comm_Self(); - const auto vertexCount = count(m, 0); - const auto edgeCount = count(m, 1); - const auto faceCount = count(m, 2); - const auto cell_dim = m->getDimension(); - const auto cellCount = count(m, cell_dim); - // for (int i = 0; i < PCU_Comm_Peers(); ++i) - // { - // if (i == PCU_Comm_Self()) - // { - // std::cout << "*******Local Mesh Stats******************\n"; - // std::cout << "Rank: " << myRank << ": Number of cells " << cellCount.second << "\n"; - // std::cout << "Rank: " << myRank << ": Number of vertices " << vertexCount.second << "\n"; - // std::cout << "Rank: " << myRank << ": Number of faces " << faceCount.second << "\n"; - // std::cout << "Rank: " << myRank << ": Number of edges " << edgeCount.second << "\n"; - // std::cout << "*****************************************\n"; - // } - // PCU_Barrier(); - // } + // boring... replace with variant + std::vector idata; + std::vector ddata; + std::vector ldata; - PCU_Barrier(); - if (myRank == 0) - { - std::cout << "*******Global Mesh Stats*****************\n"; - std::cout << ": Number of cells " << cellCount.first << "\n"; - std::cout << ": Number of vertices " << vertexCount.first << "\n"; - std::cout << ": Number of faces " << faceCount.first << "\n"; - std::cout << ": Number of edges " << edgeCount.first << "\n"; - std::cout << "*****************************************\n"; - } + if (tagSize != 1) + { + std::cout << "Not finished yet, can't be that hard..." << tagSize << std::endl; + // one assumes just a loop over components + exit(-1); + } - std::array sizes; - sizes[0] = vertexCount.first; // global - sizes[1] = cellCount.first; // global - sizes[2] = 0; // nodes are unsorted, as defined by api + cgsize_t rmin[3]; + cgsize_t rmax[3]; - // Copy communicator - auto communicator = PCU_Get_Comm(); - cgp_mpi_comm(communicator); - // - cgp_pio_mode(CGNS_ENUMV(CGP_INDEPENDENT)); + rmin[0] = std::numeric_limits::max(); + rmax[0] = 0; - int index = -1; - if (cgp_open(prefix, CGNS_ENUMV(CG_MODE_WRITE), &index)) - cgp_error_exit(); + for (const auto &e : orderedEnts) + { + if (m->hasTag(e, t) && m->isOwned(e)) + { + //std::cout << "Tags for dim " << dim << " " << tagName << " " << tagType << " " << tagSize << std::endl; + inner(e, t, idata, ddata, ldata, tagType); + const cgsize_t n = static_cast(apf::getNumber(numbering, e, 0) + 1); // one based + rmin[0] = std::min(rmin[0], n); + rmax[0] = std::max(rmax[0], n); + } + } - int base = -1; - const int phys_dim = 3; - { - std::string baseName("Base_" + std::to_string(1)); - if (cg_base_write(index, baseName.c_str(), cell_dim, phys_dim, &base)) - cg_error_exit(); - } - // Write the default units at the top. - if (cg_goto(index, base, "end")) - cg_error_exit(); + // ensure collectives are called by all, even if local has no data + int isize = idata.size(); + PCU_Add_Ints(&isize, 1); // size of total array - if (cg_units_write(CGNS_ENUMV(Kilogram), CGNS_ENUMV(Meter), CGNS_ENUMV(Second), CGNS_ENUMV(Kelvin), - CGNS_ENUMV(Degree))) - cg_error_exit(); + int dsize = ddata.size(); + PCU_Add_Ints(&dsize, 1); // size of total array - if (cg_dataclass_write(CGNS_ENUMV(Dimensional))) - cg_error_exit(); - int zone = -1; - { - std::string zoneName("Zone_" + std::to_string(1)); - if (cg_zone_write(index, base, zoneName.c_str(), sizes.data(), CGNS_ENUMV(Unstructured), &zone)) - cg_error_exit(); - } + int lsize = ldata.size(); + PCU_Add_Ints(&lsize, 1); // size of total array - int Cx = -1; - int Cy = -1; - int Cz = -1; + // oddness of the api + rmin[1] = rmin[0]; + rmin[2] = rmin[0]; + rmax[1] = rmax[0]; + rmax[2] = rmax[0]; - if (phys_dim > 0) - { - if (cgp_coord_write(index, base, zone, CGNS_ENUMV(RealDouble), "CoordinateX", &Cx)) - cgp_error_exit(); - } - if (phys_dim > 1) - { - if (cgp_coord_write(index, base, zone, CGNS_ENUMV(RealDouble), "CoordinateY", &Cy)) - cgp_error_exit(); - } - if (phys_dim > 2) - { - if (cgp_coord_write(index, base, zone, CGNS_ENUMV(RealDouble), "CoordinateZ", &Cz)) - cgp_error_exit(); - } + post(solIndex, tagName, idata, ddata, ldata, rmin, rmax, isize, dsize, lsize); + } + }; - apf::GlobalNumbering *gcn = nullptr; - gcn = apf::makeGlobal(apf::numberElements(m, "element-nums")); + const auto postLambda = [&cgns](const int &solIndex, const std::string &name, std::vector &idata, std::vector &ddata, std::vector &ldata, const cgsize_t *rmin, const cgsize_t *rmax, const int isize, const int dsize, const int lsize) { + if (dsize > 0) + { + int fieldIndex = -1; - apf::GlobalNumbering *gvn = nullptr; - gvn = apf::makeGlobal(apf::numberOwnedNodes(m, "node-nums")); - apf::synchronize(gvn); + if (cgp_field_write(cgns.index, cgns.base, cgns.zone, solIndex, CGNS_ENUMV(RealDouble), name.c_str(), &fieldIndex)) + cgp_error_exit(); - { - cgsize_t vertexMin[3]; - cgsize_t vertexMax[3]; - std::array, 3> coords; + if (cgp_field_write_data(cgns.index, cgns.base, cgns.zone, solIndex, fieldIndex, &rmin[0], &rmax[0], + ddata.data())) + cgp_error_exit(); + } + else if (isize > 0) + { + int fieldIndex = -1; - vertexMin[0] = std::numeric_limits::max(); - vertexMax[0] = 0; + if (cgp_field_write(cgns.index, cgns.base, cgns.zone, solIndex, CGNS_ENUMV(Integer), name.c_str(), &fieldIndex)) + cgp_error_exit(); + if (cgp_field_write_data(cgns.index, cgns.base, cgns.zone, solIndex, fieldIndex, &rmin[0], &rmax[0], + idata.data())) + cgp_error_exit(); + } + else if (lsize > 0) { - apf::Vector3 point; - for (int i = 0; i < PCU_Comm_Peers(); ++i) - { - if (i == PCU_Comm_Self()) - { - apf::MeshIterator *vertIter = m->begin(0); - apf::MeshEntity *vert = nullptr; - while ((vert = m->iterate(vertIter))) - { - if (m->isOwned(vert)) - { - const cgsize_t n = static_cast(apf::getNumber(gvn, vert, 0) + 1); // one based - vertexMin[0] = std::min(vertexMin[0], n); - vertexMax[0] = std::max(vertexMax[0], n); + int fieldIndex = -1; + if (cgp_field_write(cgns.index, cgns.base, cgns.zone, solIndex, CGNS_ENUMV(LongInteger), name.c_str(), &fieldIndex)) + cgp_error_exit(); - m->getPoint(vert, 0, point); - coords[0].push_back(point[0]); - coords[1].push_back(point[1]); - coords[2].push_back(point[2]); - } - } - m->end(vertIter); - } - } + if (cgp_field_write_data(cgns.index, cgns.base, cgns.zone, solIndex, fieldIndex, &rmin[0], &rmax[0], + ldata.data())) + cgp_error_exit(); } + }; - // oddness of the api - vertexMin[1] = vertexMin[0]; - vertexMin[2] = vertexMin[0]; - vertexMax[1] = vertexMax[0]; - vertexMax[2] = vertexMax[0]; - - if (phys_dim > 0) + const auto innerLambda = [&m](apf::MeshEntity *elem, apf::MeshTag *tag, std::vector &idata, std::vector &ddata, std::vector &ldata, const int &tagType) { + if (tagType == apf::Mesh::TagType::DOUBLE) { - if (cgp_coord_write_data(index, base, zone, Cx, &vertexMin[0], &vertexMax[0], coords[0].data())) - cgp_error_exit(); + double vals = -1; + m->getDoubleTag(elem, tag, &vals); + ddata.push_back(vals); } - if (phys_dim > 1) + else if (tagType == apf::Mesh::TagType::INT) { - if (cgp_coord_write_data(index, base, zone, Cy, &vertexMin[0], &vertexMax[0], coords[1].data())) - cgp_error_exit(); + int vals = -1; + m->getIntTag(elem, tag, &vals); + idata.push_back(vals); } - if (phys_dim > 2) + else if (tagType == apf::Mesh::TagType::LONG) { - if (cgp_coord_write_data(index, base, zone, Cz, &vertexMin[0], &vertexMax[0], coords[2].data())) - cgp_error_exit(); + long vals = -1; + m->getLongTag(elem, tag, &vals); + ldata.push_back(vals); } - } - - std::vector apfElementOrder; - apfElementOrder.push_back(apf::Mesh::HEX); - apfElementOrder.push_back(apf::Mesh::TET); - apfElementOrder.push_back(apf::Mesh::PYRAMID); - apfElementOrder.push_back(apf::Mesh::QUAD); - apfElementOrder.push_back(apf::Mesh::TRIANGLE); - apfElementOrder.push_back(apf::Mesh::EDGE); - - std::vector cgnsElementOrder; - cgnsElementOrder.push_back(CGNS_ENUMV(HEXA_8)); - cgnsElementOrder.push_back(CGNS_ENUMV(TETRA_4)); - cgnsElementOrder.push_back(CGNS_ENUMV(PYRA_5)); - cgnsElementOrder.push_back(CGNS_ENUMV(QUAD_4)); - cgnsElementOrder.push_back(CGNS_ENUMV(TRI_3)); - cgnsElementOrder.push_back(CGNS_ENUMV(BAR_2)); + else + { + std::cout << "Strange" << std::endl; + exit(-1); + } + }; - std::map apf2cgns; - apf2cgns.insert(std::make_pair(apf::Mesh::HEX, CGNS_ENUMV(HEXA_8))); - apf2cgns.insert(std::make_pair(apf::Mesh::TET, CGNS_ENUMV(TETRA_4))); - apf2cgns.insert(std::make_pair(apf::Mesh::PYRAMID, CGNS_ENUMV(PYRA_5))); - apf2cgns.insert(std::make_pair(apf::Mesh::QUAD, CGNS_ENUMV(QUAD_4))); - apf2cgns.insert(std::make_pair(apf::Mesh::TRIANGLE, CGNS_ENUMV(TRI_3))); - apf2cgns.insert(std::make_pair(apf::Mesh::EDGE, CGNS_ENUMV(BAR_2))); + int solIndex = -1; - std::vector globalNumbersByElementType(apfElementOrder.size(), 0); - std::vector numbersByElementType(apfElementOrder.size(), 0); - for (std::size_t o = 0; o < apfElementOrder.size(); o++) { - apf::MeshIterator *cellIter = m->begin(cell_dim); - apf::MeshEntity *cell = nullptr; - int counter = 0; - while ((cell = m->iterate(cellIter))) + if (cg_sol_write(cgns.index, cgns.base, cgns.zone, "Vertex Tag Data", CGNS_ENUMV(Vertex), &solIndex)) + cg_error_exit(); + + std::set orderedVertices; + apf::Downward verts; + for (auto &e : orderedEnts) { - if (m->getType(cell) == apfElementOrder[o] && m->isOwned(cell)) + const auto numVerts = m->getDownward(e, 0, verts); + for (int i = 0; i < numVerts; i++) { - counter++; + auto *vert = verts[i]; + if (m->isOwned(vert)) + { + orderedVertices.insert(vert); + } } } - m->end(cellIter); - numbersByElementType[o] = counter; - int total = counter; - PCU_Add_Ints(&total, 1); // size of total array - globalNumbersByElementType[o] = total; + + loopTags(orderedVertices, solIndex, innerLambda, postLambda, gvn); } - cgsize_t allTotal = std::accumulate(globalNumbersByElementType.begin(), globalNumbersByElementType.end(), 0); - PCU_ALWAYS_ASSERT_VERBOSE(allTotal == cellCount.first, ("Must be equal " + std::to_string(allTotal) + " " + std::to_string(cellCount.first)).c_str()); - int globalStart = 1; // one-based - std::vector orderedElements; - for (std::size_t o = 0; o < apfElementOrder.size(); o++) { - std::vector elements; - apf::MeshIterator *cellIter = m->begin(cell_dim); - apf::MeshEntity *cell = nullptr; - apf::Downward verts; + if (cg_sol_write(cgns.index, cgns.base, cgns.zone, "Cell Tag Data", CGNS_ENUMV(CellCenter), &solIndex)) + cg_error_exit(); - while ((cell = m->iterate(cellIter))) + loopTags(orderedEnts, solIndex, innerLambda, postLambda, gcn); + } +} + +// This is a horrible abuse of code-reuse, you should be ashamed of yourself... +void WriteFieldsToMainBase(const CGNS &cgns, const std::vector &orderedEnts, apf::Mesh *m, apf::GlobalNumbering *gvn, apf::GlobalNumbering *gcn) +{ + const auto writeField = [&m](apf::Field *f, const auto &orderedEnts, const int &solIndex, const auto &inner, const auto &post, const int &numComponents, const std::string &fieldName, apf::GlobalNumbering *numbering) { + std::vector data; + if (numComponents != 1) { - if (m->getType(cell) == apfElementOrder[o] && m->isOwned(cell)) + std::cout << "Not finished yet, can't be that hard..." << numComponents << std::endl; + // one assumes just a loop over components + exit(-1); + } + + cgsize_t rmin[3]; + cgsize_t rmax[3]; + + rmin[0] = std::numeric_limits::max(); + rmax[0] = 0; + + apf::FieldDataOf* fieldData = f->getData(); + for (const auto &e : orderedEnts) + { + if (fieldData->hasEntity(e) && m->isOwned(e)) { - const auto numVerts = m->getDownward(cell, 0, verts); - for (int i = 0; i < numVerts; i++) - { - const auto n = apf::getNumber(gvn, verts[i], 0); - elements.push_back(n + 1); // one-based - } - orderedElements.push_back(cell); + inner(e, fieldData, data); + const cgsize_t n = static_cast(apf::getNumber(numbering, e, 0) + 1); // one based + rmin[0] = std::min(rmin[0], n); + rmax[0] = std::max(rmax[0], n); } } - m->end(cellIter); - if (globalNumbersByElementType[o] > 0) + // oddness of the api + rmin[1] = rmin[0]; + rmin[2] = rmin[0]; + rmax[1] = rmax[0]; + rmax[2] = rmax[0]; + + post(solIndex, fieldName, data, rmin, rmax); + }; + + const auto loopFields = [&m, &writeField](const auto &orderedEnts, const int &solIndex, const auto &inner, const auto &post, apf::GlobalNumbering *numbering) { + for (int i = 0; i < m->countFields(); ++i) { - const int globalEnd = globalStart + globalNumbersByElementType[o] - 1; // one-based stuff - // - int sectionNumber = -1; - if (cgp_section_write(index, base, zone, (std::string(cg_ElementTypeName(cgnsElementOrder[o])) + " " + std::to_string(globalStart) + "->" + std::to_string(globalEnd)).c_str(), cgnsElementOrder[o], globalStart, - globalEnd, 0, §ionNumber)) // global start, end within the file for that element type - cgp_error_exit(); + apf::Field *f = m->getField(i); + const int numComponents = f->countComponents(); + std::string fieldName(f->getName()); + fieldName.resize(32); // daft api + writeField(f, orderedEnts, solIndex, inner, post, numComponents, fieldName, numbering); + } + }; - std::vector allNumbersForThisType(PCU_Comm_Peers(), 0); - MPI_Allgather(&numbersByElementType[o], 1, MPI_INT, allNumbersForThisType.data(), 1, - MPI_INT, PCU_Get_Comm()); + const auto postLambda = [&cgns](const int &solIndex, const std::string &name, std::vector &ddata, const cgsize_t *rmin, const cgsize_t *rmax) { + int fieldIndex = -1; - cgsize_t num = 0; - for (int i = 0; i < PCU_Comm_Self(); i++) - num += allNumbersForThisType[i]; + if (cgp_field_write(cgns.index, cgns.base, cgns.zone, solIndex, CGNS_ENUMV(RealDouble), name.c_str(), &fieldIndex)) + cgp_error_exit(); - cgsize_t elStart = globalStart + num; - cgsize_t elEnd = elStart + numbersByElementType[o] - 1; // one-based stuff - if (cgp_elements_write_data(index, base, zone, sectionNumber, elStart, elEnd, // per processor within the range[start, end] - elements.data())) - cgp_error_exit(); + if (cgp_field_write_data(cgns.index, cgns.base, cgns.zone, solIndex, fieldIndex, &rmin[0], &rmax[0], + ddata.data())) + cgp_error_exit(); + }; - //std::cout << "RANK: " << PCU_Comm_Self() << " ==> " << globalStart << " " << globalEnd << " elStart " << elStart << " elEnd " << elEnd << " numbersByElementType[o] " << numbersByElementType[o] << std::endl; + const auto innerLambda = [](apf::MeshEntity *elem, apf::FieldDataOf* fieldData, std::vector &ddata) { + double vals = -1; + fieldData->get(elem, &vals); + ddata.push_back(vals); + }; - globalStart += globalNumbersByElementType[o]; + int solIndex = -1; + + { + if (cg_sol_write(cgns.index, cgns.base, cgns.zone, "Vertex Field Data", CGNS_ENUMV(Vertex), &solIndex)) + cg_error_exit(); + + std::set orderedVertices; + apf::Downward verts; + for (auto &e : orderedEnts) + { + const auto numVerts = m->getDownward(e, 0, verts); + for (int i = 0; i < numVerts; i++) + { + auto *vert = verts[i]; + if (m->isOwned(vert)) + { + orderedVertices.insert(vert); + } + } } + + loopFields(orderedVertices, solIndex, innerLambda, postLambda, gvn); } - // + { + if (cg_sol_write(cgns.index, cgns.base, cgns.zone, "Cell Field Data", CGNS_ENUMV(CellCenter), &solIndex)) + cg_error_exit(); + + loopFields(orderedEnts, solIndex, innerLambda, postLambda, gcn); + } +} + +void AddBocosToMainBase(const CGNS &cgns, const int &cellCount, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap, const std::map &apf2cgns, apf::GlobalNumbering *gvn, apf::GlobalNumbering *gcn) +{ const auto EdgeLoop = [&m](const auto &lambda, apf::MeshTag *edgeTag) { apf::MeshIterator *edgeIter = m->begin(1); apf::MeshEntity *edge = nullptr; @@ -345,7 +350,7 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap m->end(faceIter); }; - const auto BCEntityAdder = [&apf2cgns, &m, &index, &zone, &base, &gvn](const auto &Looper, const auto &bcGroup, int &startingLocation) { + const auto BCEntityAdder = [&apf2cgns, &m, &cgns, &gvn](const auto &Looper, const auto &bcGroup, int &startingLocation) { std::map> bcEntTypes; for (const auto &r : apf2cgns) bcEntTypes.insert(std::make_pair(r.first, std::vector())); @@ -378,7 +383,7 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap const auto allEnd = startOfBCBlock + total - 1; //one-based int sectionNumber = -1; const std::string name = bcGroup.first + " " + std::to_string(startOfBCBlock) + "->" + std::to_string(allEnd); //cg_ElementTypeName(apf2cgns[bc.first]); - if (cgp_section_write(index, base, zone, name.c_str(), apf2cgns[bc.first], startOfBCBlock, allEnd, 0, + if (cgp_section_write(cgns.index, cgns.base, cgns.zone, name.c_str(), apf2cgns.at(bc.first), startOfBCBlock, allEnd, 0, §ionNumber)) cgp_error_exit(); @@ -407,12 +412,12 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap if (number == 0) { - if (cgp_elements_write_data(index, base, zone, sectionNumber, elStart, elEnd, nullptr)) + if (cgp_elements_write_data(cgns.index, cgns.base, cgns.zone, sectionNumber, elStart, elEnd, nullptr)) cgp_error_exit(); } else { - if (cgp_elements_write_data(index, base, zone, sectionNumber, elStart, elEnd, + if (cgp_elements_write_data(cgns.index, cgns.base, cgns.zone, sectionNumber, elStart, elEnd, elements.data())) cgp_error_exit(); } @@ -476,13 +481,13 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap globalElementList(bcList, allElements); int bcIndex = -1; - if (cg_boco_write(index, base, zone, p.first.c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointList), allElements.size(), + if (cg_boco_write(cgns.index, cgns.base, cgns.zone, p.first.c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointList), allElements.size(), allElements.data(), &bcIndex)) cg_error_exit(); CGNS_ENUMT(GridLocation_t) location = CGNS_ENUMV(Vertex); - if (cg_boco_gridlocation_write(index, base, zone, bcIndex, location)) + if (cg_boco_gridlocation_write(cgns.index, cgns.base, cgns.zone, bcIndex, location)) cg_error_exit(); } }; @@ -499,13 +504,13 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap const std::array bcRange = {{se.first[0], se.second[0]}}; int bcIndex = -1; - if (cg_boco_write(index, base, zone, p.first.c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointRange), 2, + if (cg_boco_write(cgns.index, cgns.base, cgns.zone, p.first.c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointRange), 2, bcRange.data(), &bcIndex)) cg_error_exit(); CGNS_ENUMT(GridLocation_t) location = CGNS_ENUMV(EdgeCenter); - if (cg_boco_gridlocation_write(index, base, zone, bcIndex, location)) + if (cg_boco_gridlocation_write(cgns.index, cgns.base, cgns.zone, bcIndex, location)) cg_error_exit(); } }; @@ -522,13 +527,13 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap } const std::array bcRange = {{se.first[0], se.second[0]}}; int bcIndex = -1; - if (cg_boco_write(index, base, zone, p.first.c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointRange), 2, + if (cg_boco_write(cgns.index, cgns.base, cgns.zone, p.first.c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointRange), 2, bcRange.data(), &bcIndex)) cg_error_exit(); CGNS_ENUMT(GridLocation_t) location = CGNS_ENUMV(FaceCenter); - if (cg_boco_gridlocation_write(index, base, zone, bcIndex, location)) + if (cg_boco_gridlocation_write(cgns.index, cgns.base, cgns.zone, bcIndex, location)) cg_error_exit(); } }; @@ -557,20 +562,21 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap globalElementList(bcList, allElements); int bcIndex = -1; - if (cg_boco_write(index, base, zone, p.first.c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointList), allElements.size(), + if (cg_boco_write(cgns.index, cgns.base, cgns.zone, p.first.c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointList), allElements.size(), allElements.data(), &bcIndex)) cg_error_exit(); CGNS_ENUMT(GridLocation_t) location = CGNS_ENUMV(CellCenter); - if (cg_boco_gridlocation_write(index, base, zone, bcIndex, location)) + if (cg_boco_gridlocation_write(cgns.index, cgns.base, cgns.zone, bcIndex, location)) cg_error_exit(); } }; + const auto cell_dim = m->getDimension(); if (cell_dim == 3) { - int startingLocation = cellCount.first; + int startingLocation = cellCount; auto iter = cgnsBCMap.find("Vertex"); if (iter != cgnsBCMap.end()) @@ -595,212 +601,315 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap } else if (cell_dim == 2) { - int startingLocation = cellCount.first; + int startingLocation = cellCount; + + auto iter = cgnsBCMap.find("Vertex"); + if (iter != cgnsBCMap.end()) + { + doVertexBC(iter); + } + iter = cgnsBCMap.find("EdgeCenter"); + if (iter != cgnsBCMap.end()) + { + doEdgeBC(iter, startingLocation); + } + iter = cgnsBCMap.find("CellCenter"); + if (iter != cgnsBCMap.end()) + { + doCellBC(iter, 2); + } + } + else if (cell_dim == 1) + { + auto iter = cgnsBCMap.find("Vertex"); + if (iter != cgnsBCMap.end()) + { + doVertexBC(iter); + } + iter = cgnsBCMap.find("CellCenter"); + if (iter != cgnsBCMap.end()) + { + doCellBC(iter, 1); + } + } +} + +void Write3DFaces(apf::Mesh *m, const Count& faceCount) +{ + +} + +// Todo split this out into a list of calls to local functions to show process/work flow +void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap) +{ + static_assert(std::is_same::value, "cgsize_t not compiled as int"); + + //ShowNumbering(m); + + const auto myRank = PCU_Comm_Self(); + const Count vertexCount = count(m, 0); + const Count edgeCount = count(m, 1); + const Count faceCount = count(m, 2); + const auto cell_dim = m->getDimension(); + const Count cellCount = count(m, cell_dim); + // for (int i = 0; i < PCU_Comm_Peers(); ++i) + // { + // if (i == PCU_Comm_Self()) + // { + // std::cout << "*******Local Mesh Stats******************\n"; + // std::cout << "Rank: " << myRank << ": Number of cells " << cellCount.second << "\n"; + // std::cout << "Rank: " << myRank << ": Number of vertices " << vertexCount.second << "\n"; + // std::cout << "Rank: " << myRank << ": Number of faces " << faceCount.second << "\n"; + // std::cout << "Rank: " << myRank << ": Number of edges " << edgeCount.second << "\n"; + // std::cout << "*****************************************\n"; + // } + // PCU_Barrier(); + // } + + PCU_Barrier(); + if (myRank == 0) + { + std::cout << "*******Global Mesh Stats*****************\n"; + std::cout << ": Number of cells " << cellCount.first << "\n"; + std::cout << ": Number of vertices " << vertexCount.first << "\n"; + std::cout << ": Number of faces " << faceCount.first << "\n"; + std::cout << ": Number of edges " << edgeCount.first << "\n"; + std::cout << "*****************************************\n"; + } + + std::array sizes; + sizes[0] = vertexCount.first; // global + sizes[1] = cellCount.first; // global + sizes[2] = 0; // nodes are unsorted, as defined by api + + // Copy communicator + auto communicator = PCU_Get_Comm(); + cgp_mpi_comm(communicator); + // + cgp_pio_mode(CGNS_ENUMV(CGP_INDEPENDENT)); + + CGNS cgns; + if (cgp_open(prefix, CGNS_ENUMV(CG_MODE_WRITE), &cgns.index)) + cgp_error_exit(); + + { + std::string baseName("Base_" + std::to_string(1)); + if (cg_base_write(cgns.index, baseName.c_str(), cell_dim, cgns.phys_dim, &cgns.base)) + cg_error_exit(); + } + // Write the default units at the top. + if (cg_goto(cgns.index, cgns.base, "end")) + cg_error_exit(); + + if (cg_units_write(CGNS_ENUMV(Kilogram), CGNS_ENUMV(Meter), CGNS_ENUMV(Second), CGNS_ENUMV(Kelvin), + CGNS_ENUMV(Degree))) + cg_error_exit(); + + if (cg_dataclass_write(CGNS_ENUMV(Dimensional))) + cg_error_exit(); + + { + std::string zoneName("Zone_" + std::to_string(1)); + if (cg_zone_write(cgns.index, cgns.base, zoneName.c_str(), sizes.data(), CGNS_ENUMV(Unstructured), &cgns.zone)) + cg_error_exit(); + } - auto iter = cgnsBCMap.find("Vertex"); - if (iter != cgnsBCMap.end()) - { - doVertexBC(iter); - } - iter = cgnsBCMap.find("EdgeCenter"); - if (iter != cgnsBCMap.end()) - { - doEdgeBC(iter, startingLocation); - } - iter = cgnsBCMap.find("CellCenter"); - if (iter != cgnsBCMap.end()) - { - doCellBC(iter, 2); - } + int Cx = -1; + int Cy = -1; + int Cz = -1; + + if (cgns.phys_dim > 0) + { + if (cgp_coord_write(cgns.index, cgns.base, cgns.zone, CGNS_ENUMV(RealDouble), "CoordinateX", &Cx)) + cgp_error_exit(); } - else if (cell_dim == 1) + if (cgns.phys_dim > 1) { - auto iter = cgnsBCMap.find("Vertex"); - if (iter != cgnsBCMap.end()) - { - doVertexBC(iter); - } - iter = cgnsBCMap.find("CellCenter"); - if (iter != cgnsBCMap.end()) - { - doCellBC(iter, 1); - } + if (cgp_coord_write(cgns.index, cgns.base, cgns.zone, CGNS_ENUMV(RealDouble), "CoordinateY", &Cy)) + cgp_error_exit(); + } + if (cgns.phys_dim > 2) + { + if (cgp_coord_write(cgns.index, cgns.base, cgns.zone, CGNS_ENUMV(RealDouble), "CoordinateZ", &Cz)) + cgp_error_exit(); } - const auto loopTags = [&m](const std::vector &orderedEnts, const int &solIndex, const auto &inner, const auto &post, apf::GlobalNumbering *numbering) { - apf::DynamicArray tags; - m->getTags(tags); - for (std::size_t i = 0; i < tags.getSize(); ++i) - { - apf::MeshTag *t = tags[i]; - const int tagType = m->getTagType(t); - const int tagSize = m->getTagSize(t); - std::string tagName(m->getTagName(t)); - tagName.resize(32); // daft api - //std::cout << i << " " << tagName << " " << m->getTagName(t) << std::endl; - - // boring... replace with variant - std::vector idata; - std::vector ddata; - std::vector ldata; + apf::GlobalNumbering *gcn = nullptr; + gcn = apf::makeGlobal(apf::numberElements(m, "element-nums")); - if (tagSize != 1) - { - std::cout << "Not finished yet, can't be that hard..." << std::endl; - exit(-1); - } + apf::GlobalNumbering *gvn = nullptr; + gvn = apf::makeGlobal(apf::numberOwnedNodes(m, "node-nums")); + apf::synchronize(gvn); - cgsize_t rmin[3]; - cgsize_t rmax[3]; + { + cgsize_t vertexMin[3]; + cgsize_t vertexMax[3]; + std::array, 3> coords; - rmin[0] = std::numeric_limits::max(); - rmax[0] = 0; + vertexMin[0] = std::numeric_limits::max(); + vertexMax[0] = 0; - for (const auto &e: orderedEnts) + { + apf::Vector3 point; + for (int i = 0; i < PCU_Comm_Peers(); ++i) { - if (m->hasTag(e, t) && m->isOwned(e)) + if (i == PCU_Comm_Self()) { - //std::cout << "Tags for dim " << dim << " " << tagName << " " << tagType << " " << tagSize << std::endl; - inner(e, t, idata, ddata, ldata, tagType); - const cgsize_t n = static_cast(apf::getNumber(numbering, e, 0) + 1); // one based - rmin[0] = std::min(rmin[0], n); - rmax[0] = std::max(rmax[0], n); + apf::MeshIterator *vertIter = m->begin(0); + apf::MeshEntity *vert = nullptr; + while ((vert = m->iterate(vertIter))) + { + if (m->isOwned(vert)) + { + const cgsize_t n = static_cast(apf::getNumber(gvn, vert, 0) + 1); // one based + vertexMin[0] = std::min(vertexMin[0], n); + vertexMax[0] = std::max(vertexMax[0], n); + + m->getPoint(vert, 0, point); + coords[0].push_back(point[0]); + coords[1].push_back(point[1]); + coords[2].push_back(point[2]); + } + } + m->end(vertIter); } } - - // oddness of the api - rmin[1] = rmin[0]; - rmin[2] = rmin[0]; - rmax[1] = rmax[0]; - rmax[2] = rmax[0]; - - post(solIndex, tagName, idata, ddata, ldata, rmin, rmax); } - }; - - const auto postLambda = [&index, &base, &zone](const int &solIndex, const std::string &name, std::vector &idata, std::vector &ddata, std::vector &ldata, const cgsize_t *rmin, const cgsize_t *rmax) { - if (!ddata.empty()) - { - int fieldIndex = -1; - if (cgp_field_write(index, base, zone, solIndex, CGNS_ENUMV(RealDouble), name.c_str(), &fieldIndex)) - cgp_error_exit(); + // oddness of the api + vertexMin[1] = vertexMin[0]; + vertexMin[2] = vertexMin[0]; + vertexMax[1] = vertexMax[0]; + vertexMax[2] = vertexMax[0]; - if (cgp_field_write_data(index, base, zone, solIndex, fieldIndex, &rmin[0], &rmax[0], - ddata.data())) + if (cgns.phys_dim > 0) + { + if (cgp_coord_write_data(cgns.index, cgns.base, cgns.zone, Cx, &vertexMin[0], &vertexMax[0], coords[0].data())) cgp_error_exit(); } - else if (!idata.empty()) + if (cgns.phys_dim > 1) { - int fieldIndex = -1; - - if (cgp_field_write(index, base, zone, solIndex, CGNS_ENUMV(Integer), name.c_str(), &fieldIndex)) - cgp_error_exit(); - - if (cgp_field_write_data(index, base, zone, solIndex, fieldIndex, &rmin[0], &rmax[0], - idata.data())) + if (cgp_coord_write_data(cgns.index, cgns.base, cgns.zone, Cy, &vertexMin[0], &vertexMax[0], coords[1].data())) cgp_error_exit(); } - else if (!ldata.empty()) + if (cgns.phys_dim > 2) { - int fieldIndex = -1; - - if (cgp_field_write(index, base, zone, solIndex, CGNS_ENUMV(LongInteger), name.c_str(), &fieldIndex)) - cgp_error_exit(); - - if (cgp_field_write_data(index, base, zone, solIndex, fieldIndex, &rmin[0], &rmax[0], - ldata.data())) + if (cgp_coord_write_data(cgns.index, cgns.base, cgns.zone, Cz, &vertexMin[0], &vertexMax[0], coords[2].data())) cgp_error_exit(); } - }; + } - const auto innerLambda = [&m](apf::MeshEntity *elem, apf::MeshTag *tag, std::vector &idata, std::vector &ddata, std::vector &ldata, const int &tagType) { - if (tagType == apf::Mesh::TagType::DOUBLE) - { - double vals = -1; - m->getDoubleTag(elem, tag, &vals); - ddata.push_back(vals); - } - else if (tagType == apf::Mesh::TagType::INT) - { - int vals = -1; - m->getIntTag(elem, tag, &vals); - idata.push_back(vals); - } - else if (tagType == apf::Mesh::TagType::LONG) - { - long vals = -1; - m->getLongTag(elem, tag, &vals); - ldata.push_back(vals); - } - else - { - std::cout << "Strange" << std::endl; - exit(-1); - } - }; + std::vector apfElementOrder; + apfElementOrder.push_back(apf::Mesh::HEX); + apfElementOrder.push_back(apf::Mesh::TET); + apfElementOrder.push_back(apf::Mesh::PYRAMID); + apfElementOrder.push_back(apf::Mesh::QUAD); + apfElementOrder.push_back(apf::Mesh::TRIANGLE); + apfElementOrder.push_back(apf::Mesh::EDGE); - int solIndex = -1; + std::vector cgnsElementOrder; + cgnsElementOrder.push_back(CGNS_ENUMV(HEXA_8)); + cgnsElementOrder.push_back(CGNS_ENUMV(TETRA_4)); + cgnsElementOrder.push_back(CGNS_ENUMV(PYRA_5)); + cgnsElementOrder.push_back(CGNS_ENUMV(QUAD_4)); + cgnsElementOrder.push_back(CGNS_ENUMV(TRI_3)); + cgnsElementOrder.push_back(CGNS_ENUMV(BAR_2)); - { - if (cg_sol_write(index, base, zone, "Vertex Data", CGNS_ENUMV(Vertex), &solIndex)) - cg_error_exit(); + std::map apf2cgns; + apf2cgns.insert(std::make_pair(apf::Mesh::HEX, CGNS_ENUMV(HEXA_8))); + apf2cgns.insert(std::make_pair(apf::Mesh::TET, CGNS_ENUMV(TETRA_4))); + apf2cgns.insert(std::make_pair(apf::Mesh::PYRAMID, CGNS_ENUMV(PYRA_5))); + apf2cgns.insert(std::make_pair(apf::Mesh::QUAD, CGNS_ENUMV(QUAD_4))); + apf2cgns.insert(std::make_pair(apf::Mesh::TRIANGLE, CGNS_ENUMV(TRI_3))); + apf2cgns.insert(std::make_pair(apf::Mesh::EDGE, CGNS_ENUMV(BAR_2))); - std::vector orderedVertices; - apf::MeshIterator *vertIter = m->begin(0); - apf::MeshEntity *vert = nullptr; - while ((vert = m->iterate(vertIter))) + std::vector globalNumbersByElementType(apfElementOrder.size(), 0); + std::vector numbersByElementType(apfElementOrder.size(), 0); + for (std::size_t o = 0; o < apfElementOrder.size(); o++) + { + apf::MeshIterator *cellIter = m->begin(cell_dim); + apf::MeshEntity *cell = nullptr; + int counter = 0; + while ((cell = m->iterate(cellIter))) { - if (m->isOwned(vert)) + if (m->getType(cell) == apfElementOrder[o] && m->isOwned(cell)) { - orderedVertices.push_back(vert); + counter++; } } - m->end(vertIter); - - loopTags(orderedVertices, solIndex, innerLambda, postLambda, gvn); + m->end(cellIter); + numbersByElementType[o] = counter; + int total = counter; + PCU_Add_Ints(&total, 1); // size of total array + globalNumbersByElementType[o] = total; } + cgsize_t allTotal = std::accumulate(globalNumbersByElementType.begin(), globalNumbersByElementType.end(), 0); + PCU_ALWAYS_ASSERT_VERBOSE(allTotal == cellCount.first, ("Must be equal " + std::to_string(allTotal) + " " + std::to_string(cellCount.first)).c_str()); + int globalStart = 1; // one-based + std::vector orderedElements; + for (std::size_t o = 0; o < apfElementOrder.size(); o++) { - if (cg_sol_write(index, base, zone, "Cell Data", CGNS_ENUMV(CellCenter), &solIndex)) - cg_error_exit(); - - loopTags(orderedElements, solIndex, innerLambda, postLambda, gcn); - } + std::vector elements; + apf::MeshIterator *cellIter = m->begin(cell_dim); + apf::MeshEntity *cell = nullptr; + apf::Downward verts; - const auto loopFields = [&m](int dim) { - for (int i = 0; i < m->countFields(); ++i) + while ((cell = m->iterate(cellIter))) { - apf::Field *f = m->getField(i); - int fieldType = f->getScalarType(); - int fieldSize = f->countComponents(); - const char *fieldName = f->getName(); - - apf::MeshEntity *e; - apf::MeshIterator *it = m->begin(dim); - bool keepGoing = true; - apf::FieldData *fd = f->getData(); - while ((e = m->iterate(it)) && keepGoing) + if (m->getType(cell) == apfElementOrder[o] && m->isOwned(cell)) { - if (fd->hasEntity(e)) + const auto numVerts = m->getDownward(cell, 0, verts); + for (int i = 0; i < numVerts; i++) { - std::cout << "Fields for dim " << dim << " " << fieldName << " " << fieldType << " " << fieldSize << std::endl; - keepGoing = false; + const auto n = apf::getNumber(gvn, verts[i], 0); + elements.push_back(n + 1); // one-based } + orderedElements.push_back(cell); } - m->end(it); } - }; + m->end(cellIter); + + if (globalNumbersByElementType[o] > 0) + { + const int globalEnd = globalStart + globalNumbersByElementType[o] - 1; // one-based stuff + // + int sectionNumber = -1; + if (cgp_section_write(cgns.index, cgns.base, cgns.zone, (std::string(cg_ElementTypeName(cgnsElementOrder[o])) + " " + std::to_string(globalStart) + "->" + std::to_string(globalEnd)).c_str(), cgnsElementOrder[o], globalStart, + globalEnd, 0, §ionNumber)) // global start, end within the file for that element type + cgp_error_exit(); + + std::vector allNumbersForThisType(PCU_Comm_Peers(), 0); + MPI_Allgather(&numbersByElementType[o], 1, MPI_INT, allNumbersForThisType.data(), 1, + MPI_INT, PCU_Get_Comm()); + + cgsize_t num = 0; + for (int i = 0; i < PCU_Comm_Self(); i++) + num += allNumbersForThisType[i]; + + cgsize_t elStart = globalStart + num; + cgsize_t elEnd = elStart + numbersByElementType[o] - 1; // one-based stuff + if (cgp_elements_write_data(cgns.index, cgns.base, cgns.zone, sectionNumber, elStart, elEnd, // per processor within the range[start, end] + elements.data())) + cgp_error_exit(); - for (int i = 0; i <= m->getDimension(); i++) - loopFields(i); + //std::cout << "RANK: " << PCU_Comm_Self() << " ==> " << globalStart << " " << globalEnd << " elStart " << elStart << " elEnd " << elEnd << " numbersByElementType[o] " << numbersByElementType[o] << std::endl; + globalStart += globalNumbersByElementType[o]; + } + } + // + AddBocosToMainBase(cgns, cellCount.first, m, cgnsBCMap, apf2cgns, gvn, gcn); + // + WriteTagsToMainBase(cgns, orderedElements, m, gvn, gcn); + // + WriteFieldsToMainBase(cgns, orderedElements, m, gvn, gcn); // destroyGlobalNumbering(gvn); destroyGlobalNumbering(gcn); // - cgp_close(index); -} // namespace + cgp_close(cgns.index); +} } // namespace namespace apf From cea0c84498f1827ac461fd26aae20a5462db44f1 Mon Sep 17 00:00:00 2001 From: a-jp Date: Tue, 19 Nov 2019 11:02:29 +0000 Subject: [PATCH 43/72] initial edge and face mesh and tags and fields --- apf/apfCGNS.cc | 641 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 417 insertions(+), 224 deletions(-) diff --git a/apf/apfCGNS.cc b/apf/apfCGNS.cc index 348c643a5..bff825b47 100644 --- a/apf/apfCGNS.cc +++ b/apf/apfCGNS.cc @@ -57,9 +57,9 @@ struct CGNS const int phys_dim = 3; }; -void WriteTagsToMainBase(const CGNS &cgns, const std::vector &orderedEnts, apf::Mesh *m, apf::GlobalNumbering *gvn, apf::GlobalNumbering *gcn) +void WriteTags(const CGNS &cgns, const std::vector> &orderedEnts, const std::vector> &ranges, const std::vector &orderedVertices, const int &vStart, const int &vEnd, apf::Mesh *m, apf::GlobalNumbering *gvn, apf::GlobalNumbering *gcn) { - const auto loopTags = [&m](const auto &orderedEnts, const int &solIndex, const auto &inner, const auto &post, apf::GlobalNumbering *numbering) { + const auto loopVertexTags = [&m](const auto &orderedEnts, const int &solIndex, const auto &inner, const auto &post, apf::GlobalNumbering *numbering, const int &start, const int &end) { apf::DynamicArray tags; m->getTags(tags); for (std::size_t i = 0; i < tags.getSize(); ++i) @@ -69,7 +69,6 @@ void WriteTagsToMainBase(const CGNS &cgns, const std::vector const int tagSize = m->getTagSize(t); std::string tagName(m->getTagName(t)); tagName.resize(32); // daft api - //std::cout << i << " " << tagName << " " << m->getTagName(t) << std::endl; // boring... replace with variant std::vector idata; @@ -79,25 +78,22 @@ void WriteTagsToMainBase(const CGNS &cgns, const std::vector if (tagSize != 1) { std::cout << "Not finished yet, can't be that hard..." << tagSize << std::endl; - // one assumes just a loop over components + // one assumes this just needs to be a loop over components exit(-1); } cgsize_t rmin[3]; cgsize_t rmax[3]; - rmin[0] = std::numeric_limits::max(); - rmax[0] = 0; - + rmin[0] = start; + rmax[0] = end; + //std::cout << start << " " << end << std::endl; + int fieldIndex = -1; for (const auto &e : orderedEnts) { if (m->hasTag(e, t) && m->isOwned(e)) { - //std::cout << "Tags for dim " << dim << " " << tagName << " " << tagType << " " << tagSize << std::endl; inner(e, t, idata, ddata, ldata, tagType); - const cgsize_t n = static_cast(apf::getNumber(numbering, e, 0) + 1); // one based - rmin[0] = std::min(rmin[0], n); - rmax[0] = std::max(rmax[0], n); } } @@ -108,7 +104,6 @@ void WriteTagsToMainBase(const CGNS &cgns, const std::vector int dsize = ddata.size(); PCU_Add_Ints(&dsize, 1); // size of total array - int lsize = ldata.size(); PCU_Add_Ints(&lsize, 1); // size of total array @@ -117,29 +112,93 @@ void WriteTagsToMainBase(const CGNS &cgns, const std::vector rmin[2] = rmin[0]; rmax[1] = rmax[0]; rmax[2] = rmax[0]; - - post(solIndex, tagName, idata, ddata, ldata, rmin, rmax, isize, dsize, lsize); + post(solIndex, tagName, idata, ddata, ldata, rmin, rmax, isize, dsize, lsize, fieldIndex); } }; - const auto postLambda = [&cgns](const int &solIndex, const std::string &name, std::vector &idata, std::vector &ddata, std::vector &ldata, const cgsize_t *rmin, const cgsize_t *rmax, const int isize, const int dsize, const int lsize) { - if (dsize > 0) + const auto loopCellTags = [&m](const auto &orderedEnts, const int &solIndex, const auto &inner, const auto &post, apf::GlobalNumbering *numbering, const auto &ranges) { + apf::DynamicArray tags; + m->getTags(tags); + for (std::size_t i = 0; i < tags.getSize(); ++i) { + apf::MeshTag *t = tags[i]; + const int tagType = m->getTagType(t); + const int tagSize = m->getTagSize(t); + std::string tagName(m->getTagName(t)); + tagName.resize(32); // daft api + + if (tagSize != 1) + { + std::cout << "Not finished yet, can't be that hard..." << tagSize << std::endl; + // one assumes this just needs to a loop over components + exit(-1); + } + int fieldIndex = -1; + for (std::size_t e = 0; e < orderedEnts.size(); e++) + { - if (cgp_field_write(cgns.index, cgns.base, cgns.zone, solIndex, CGNS_ENUMV(RealDouble), name.c_str(), &fieldIndex)) - cgp_error_exit(); + // boring... replace with variant + std::vector idata; + std::vector ddata; + std::vector ldata; + + cgsize_t rmin[3]; + cgsize_t rmax[3]; + rmin[0] = ranges[e].first; + rmax[0] = ranges[e].second; + + for (const auto &elm : orderedEnts[e]) + { + if (m->hasTag(elm, t) && m->isOwned(elm)) + { + inner(elm, t, idata, ddata, ldata, tagType); + } + } + + // ensure collectives are called by all, even if local has no data + int isize = idata.size(); + PCU_Add_Ints(&isize, 1); // size of total array + + int dsize = ddata.size(); + PCU_Add_Ints(&dsize, 1); // size of total array + + int lsize = ldata.size(); + PCU_Add_Ints(&lsize, 1); // size of total array + + // oddness of the api + rmin[1] = rmin[0]; + rmin[2] = rmin[0]; + rmax[1] = rmax[0]; + rmax[2] = rmax[0]; + + if (isize > 0 || dsize > 0 || lsize > 0) + post(solIndex, tagName, idata, ddata, ldata, rmin, rmax, isize, dsize, lsize, fieldIndex); + } + } + }; + + const auto postLambda = [&cgns](const int &solIndex, const std::string &name, std::vector &idata, std::vector &ddata, std::vector &ldata, const cgsize_t *rmin, const cgsize_t *rmax, const int isize, const int dsize, const int lsize, int &fieldIndex) { + + if (dsize > 0) + { + if (fieldIndex == -1) + { + if (cgp_field_write(cgns.index, cgns.base, cgns.zone, solIndex, CGNS_ENUMV(RealDouble), name.c_str(), &fieldIndex)) + cgp_error_exit(); + } if (cgp_field_write_data(cgns.index, cgns.base, cgns.zone, solIndex, fieldIndex, &rmin[0], &rmax[0], ddata.data())) cgp_error_exit(); } else if (isize > 0) { - int fieldIndex = -1; - - if (cgp_field_write(cgns.index, cgns.base, cgns.zone, solIndex, CGNS_ENUMV(Integer), name.c_str(), &fieldIndex)) - cgp_error_exit(); + if (fieldIndex == -1) + { + if (cgp_field_write(cgns.index, cgns.base, cgns.zone, solIndex, CGNS_ENUMV(Integer), name.c_str(), &fieldIndex)) + cgp_error_exit(); + } if (cgp_field_write_data(cgns.index, cgns.base, cgns.zone, solIndex, fieldIndex, &rmin[0], &rmax[0], idata.data())) @@ -147,10 +206,11 @@ void WriteTagsToMainBase(const CGNS &cgns, const std::vector } else if (lsize > 0) { - int fieldIndex = -1; - if (cgp_field_write(cgns.index, cgns.base, cgns.zone, solIndex, CGNS_ENUMV(LongInteger), name.c_str(), &fieldIndex)) - cgp_error_exit(); - + if (fieldIndex == -1) + { + if (cgp_field_write(cgns.index, cgns.base, cgns.zone, solIndex, CGNS_ENUMV(LongInteger), name.c_str(), &fieldIndex)) + cgp_error_exit(); + } if (cgp_field_write_data(cgns.index, cgns.base, cgns.zone, solIndex, fieldIndex, &rmin[0], &rmax[0], ldata.data())) cgp_error_exit(); @@ -189,36 +249,20 @@ void WriteTagsToMainBase(const CGNS &cgns, const std::vector if (cg_sol_write(cgns.index, cgns.base, cgns.zone, "Vertex Tag Data", CGNS_ENUMV(Vertex), &solIndex)) cg_error_exit(); - std::set orderedVertices; - apf::Downward verts; - for (auto &e : orderedEnts) - { - const auto numVerts = m->getDownward(e, 0, verts); - for (int i = 0; i < numVerts; i++) - { - auto *vert = verts[i]; - if (m->isOwned(vert)) - { - orderedVertices.insert(vert); - } - } - } - - loopTags(orderedVertices, solIndex, innerLambda, postLambda, gvn); + loopVertexTags(orderedVertices, solIndex, innerLambda, postLambda, gvn, vStart, vEnd); } { if (cg_sol_write(cgns.index, cgns.base, cgns.zone, "Cell Tag Data", CGNS_ENUMV(CellCenter), &solIndex)) cg_error_exit(); - loopTags(orderedEnts, solIndex, innerLambda, postLambda, gcn); + loopCellTags(orderedEnts, solIndex, innerLambda, postLambda, gcn, ranges); } } -// This is a horrible abuse of code-reuse, you should be ashamed of yourself... -void WriteFieldsToMainBase(const CGNS &cgns, const std::vector &orderedEnts, apf::Mesh *m, apf::GlobalNumbering *gvn, apf::GlobalNumbering *gcn) +void WriteFields(const CGNS &cgns, const std::vector> &orderedEnts, const std::vector> &ranges, const std::vector &orderedVertices, const int &vStart, const int &vEnd, apf::Mesh *m, apf::GlobalNumbering *gvn, apf::GlobalNumbering *gcn) { - const auto writeField = [&m](apf::Field *f, const auto &orderedEnts, const int &solIndex, const auto &inner, const auto &post, const int &numComponents, const std::string &fieldName, apf::GlobalNumbering *numbering) { + const auto writeField = [&m, &cgns](apf::Field *f, const auto &orderedEnts, const int &solIndex, const auto &inner, const auto &post, const int &numComponents, const std::string &fieldName, apf::GlobalNumbering *numbering, const int &start, const int &end, int &fieldIndex) { std::vector data; if (numComponents != 1) { @@ -230,53 +274,75 @@ void WriteFieldsToMainBase(const CGNS &cgns, const std::vector::max(); - rmax[0] = 0; + rmin[0] = start; + rmax[0] = end; - apf::FieldDataOf* fieldData = f->getData(); + apf::FieldDataOf *fieldData = f->getData(); for (const auto &e : orderedEnts) { if (fieldData->hasEntity(e) && m->isOwned(e)) { inner(e, fieldData, data); - const cgsize_t n = static_cast(apf::getNumber(numbering, e, 0) + 1); // one based - rmin[0] = std::min(rmin[0], n); - rmax[0] = std::max(rmax[0], n); } } + int size = data.size(); + PCU_Add_Ints(&size, 1); // size of total array + // oddness of the api rmin[1] = rmin[0]; rmin[2] = rmin[0]; rmax[1] = rmax[0]; rmax[2] = rmax[0]; + if (size > 0) + { + if (fieldIndex == -1) + { + if (cgp_field_write(cgns.index, cgns.base, cgns.zone, solIndex, CGNS_ENUMV(RealDouble), fieldName.c_str(), &fieldIndex)) + cgp_error_exit(); + } - post(solIndex, fieldName, data, rmin, rmax); + post(solIndex, fieldName, data, rmin, rmax, size, fieldIndex); + } }; - const auto loopFields = [&m, &writeField](const auto &orderedEnts, const int &solIndex, const auto &inner, const auto &post, apf::GlobalNumbering *numbering) { + const auto loopCellFields = [&m, &writeField](const auto &orderedEnts, const int &solIndex, const auto &inner, const auto &post, apf::GlobalNumbering *numbering, const auto &ranges) { for (int i = 0; i < m->countFields(); ++i) { apf::Field *f = m->getField(i); const int numComponents = f->countComponents(); std::string fieldName(f->getName()); fieldName.resize(32); // daft api - writeField(f, orderedEnts, solIndex, inner, post, numComponents, fieldName, numbering); + int fieldIndex = -1; + for (std::size_t e = 0; e < orderedEnts.size(); e++) + { + writeField(f, orderedEnts[e], solIndex, inner, post, numComponents, fieldName, numbering, ranges[e].first, ranges[e].second, fieldIndex); + } } }; - const auto postLambda = [&cgns](const int &solIndex, const std::string &name, std::vector &ddata, const cgsize_t *rmin, const cgsize_t *rmax) { - int fieldIndex = -1; - - if (cgp_field_write(cgns.index, cgns.base, cgns.zone, solIndex, CGNS_ENUMV(RealDouble), name.c_str(), &fieldIndex)) - cgp_error_exit(); + const auto loopVertexFields = [&m, &writeField](const auto &orderedEnts, const int &solIndex, const auto &inner, const auto &post, apf::GlobalNumbering *numbering, const int &vStart, const int &vEnd) { + for (int i = 0; i < m->countFields(); ++i) + { + apf::Field *f = m->getField(i); + const int numComponents = f->countComponents(); + std::string fieldName(f->getName()); + fieldName.resize(32); // daft api + int fieldIndex = -1; + writeField(f, orderedEnts, solIndex, inner, post, numComponents, fieldName, numbering, vStart, vEnd, fieldIndex); + } + }; - if (cgp_field_write_data(cgns.index, cgns.base, cgns.zone, solIndex, fieldIndex, &rmin[0], &rmax[0], - ddata.data())) - cgp_error_exit(); + const auto postLambda = [&cgns](const int &solIndex, const std::string &name, std::vector &ddata, const cgsize_t *rmin, const cgsize_t *rmax, const int &globalSize, const int &fieldIndex) { + if (globalSize > 0) + { + if (cgp_field_write_data(cgns.index, cgns.base, cgns.zone, solIndex, fieldIndex, &rmin[0], &rmax[0], + ddata.data())) + cgp_error_exit(); + } }; - const auto innerLambda = [](apf::MeshEntity *elem, apf::FieldDataOf* fieldData, std::vector &ddata) { + const auto innerLambda = [](apf::MeshEntity *elem, apf::FieldDataOf *fieldData, std::vector &ddata) { double vals = -1; fieldData->get(elem, &vals); ddata.push_back(vals); @@ -288,29 +354,14 @@ void WriteFieldsToMainBase(const CGNS &cgns, const std::vector orderedVertices; - apf::Downward verts; - for (auto &e : orderedEnts) - { - const auto numVerts = m->getDownward(e, 0, verts); - for (int i = 0; i < numVerts; i++) - { - auto *vert = verts[i]; - if (m->isOwned(vert)) - { - orderedVertices.insert(vert); - } - } - } - - loopFields(orderedVertices, solIndex, innerLambda, postLambda, gvn); + loopVertexFields(orderedVertices, solIndex, innerLambda, postLambda, gvn, vStart, vEnd); } { if (cg_sol_write(cgns.index, cgns.base, cgns.zone, "Cell Field Data", CGNS_ENUMV(CellCenter), &solIndex)) cg_error_exit(); - loopFields(orderedEnts, solIndex, innerLambda, postLambda, gcn); + loopCellFields(orderedEnts, solIndex, innerLambda, postLambda, gcn, ranges); } } @@ -387,7 +438,7 @@ void AddBocosToMainBase(const CGNS &cgns, const int &cellCount, apf::Mesh *m, co §ionNumber)) cgp_error_exit(); - std::vector elements; + std::vector elementVertices; for (std::size_t e = 0; e < bc.second.size(); e++) { apf::Downward verts; @@ -395,7 +446,7 @@ void AddBocosToMainBase(const CGNS &cgns, const int &cellCount, apf::Mesh *m, co for (int i = 0; i < numVerts; i++) { const auto n = apf::getNumber(gvn, verts[i], 0); - elements.push_back(n + 1); // one-based + elementVertices.push_back(n + 1); // one-based } } @@ -418,7 +469,7 @@ void AddBocosToMainBase(const CGNS &cgns, const int &cellCount, apf::Mesh *m, co else { if (cgp_elements_write_data(cgns.index, cgns.base, cgns.zone, sectionNumber, elStart, elEnd, - elements.data())) + elementVertices.data())) cgp_error_exit(); } @@ -634,86 +685,8 @@ void AddBocosToMainBase(const CGNS &cgns, const int &cellCount, apf::Mesh *m, co } } -void Write3DFaces(apf::Mesh *m, const Count& faceCount) -{ - -} - -// Todo split this out into a list of calls to local functions to show process/work flow -void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap) +auto WriteVertices(const CGNS &cgns, apf::Mesh *m, apf::GlobalNumbering *gvn) { - static_assert(std::is_same::value, "cgsize_t not compiled as int"); - - //ShowNumbering(m); - - const auto myRank = PCU_Comm_Self(); - const Count vertexCount = count(m, 0); - const Count edgeCount = count(m, 1); - const Count faceCount = count(m, 2); - const auto cell_dim = m->getDimension(); - const Count cellCount = count(m, cell_dim); - // for (int i = 0; i < PCU_Comm_Peers(); ++i) - // { - // if (i == PCU_Comm_Self()) - // { - // std::cout << "*******Local Mesh Stats******************\n"; - // std::cout << "Rank: " << myRank << ": Number of cells " << cellCount.second << "\n"; - // std::cout << "Rank: " << myRank << ": Number of vertices " << vertexCount.second << "\n"; - // std::cout << "Rank: " << myRank << ": Number of faces " << faceCount.second << "\n"; - // std::cout << "Rank: " << myRank << ": Number of edges " << edgeCount.second << "\n"; - // std::cout << "*****************************************\n"; - // } - // PCU_Barrier(); - // } - - PCU_Barrier(); - if (myRank == 0) - { - std::cout << "*******Global Mesh Stats*****************\n"; - std::cout << ": Number of cells " << cellCount.first << "\n"; - std::cout << ": Number of vertices " << vertexCount.first << "\n"; - std::cout << ": Number of faces " << faceCount.first << "\n"; - std::cout << ": Number of edges " << edgeCount.first << "\n"; - std::cout << "*****************************************\n"; - } - - std::array sizes; - sizes[0] = vertexCount.first; // global - sizes[1] = cellCount.first; // global - sizes[2] = 0; // nodes are unsorted, as defined by api - - // Copy communicator - auto communicator = PCU_Get_Comm(); - cgp_mpi_comm(communicator); - // - cgp_pio_mode(CGNS_ENUMV(CGP_INDEPENDENT)); - - CGNS cgns; - if (cgp_open(prefix, CGNS_ENUMV(CG_MODE_WRITE), &cgns.index)) - cgp_error_exit(); - - { - std::string baseName("Base_" + std::to_string(1)); - if (cg_base_write(cgns.index, baseName.c_str(), cell_dim, cgns.phys_dim, &cgns.base)) - cg_error_exit(); - } - // Write the default units at the top. - if (cg_goto(cgns.index, cgns.base, "end")) - cg_error_exit(); - - if (cg_units_write(CGNS_ENUMV(Kilogram), CGNS_ENUMV(Meter), CGNS_ENUMV(Second), CGNS_ENUMV(Kelvin), - CGNS_ENUMV(Degree))) - cg_error_exit(); - - if (cg_dataclass_write(CGNS_ENUMV(Dimensional))) - cg_error_exit(); - - { - std::string zoneName("Zone_" + std::to_string(1)); - if (cg_zone_write(cgns.index, cgns.base, zoneName.c_str(), sizes.data(), CGNS_ENUMV(Unstructured), &cgns.zone)) - cg_error_exit(); - } - int Cx = -1; int Cy = -1; int Cz = -1; @@ -734,47 +707,53 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap cgp_error_exit(); } - apf::GlobalNumbering *gcn = nullptr; - gcn = apf::makeGlobal(apf::numberElements(m, "element-nums")); - - apf::GlobalNumbering *gvn = nullptr; - gvn = apf::makeGlobal(apf::numberOwnedNodes(m, "node-nums")); - apf::synchronize(gvn); - + std::vector orderedVertices; + cgsize_t vertexMin[3]; + cgsize_t vertexMax[3]; + cgsize_t contigRange = -1; { - cgsize_t vertexMin[3]; - cgsize_t vertexMax[3]; std::array, 3> coords; vertexMin[0] = std::numeric_limits::max(); vertexMax[0] = 0; + apf::Vector3 point; + apf::MeshIterator *vertIter = m->begin(0); + apf::MeshEntity *vert = nullptr; + while ((vert = m->iterate(vertIter))) { - apf::Vector3 point; - for (int i = 0; i < PCU_Comm_Peers(); ++i) + if (m->isOwned(vert)) { - if (i == PCU_Comm_Self()) + const cgsize_t n = static_cast(apf::getNumber(gvn, vert, 0) + 1); // one based + if (contigRange == -1) { - apf::MeshIterator *vertIter = m->begin(0); - apf::MeshEntity *vert = nullptr; - while ((vert = m->iterate(vertIter))) + contigRange = n; + } + else + { + const auto predict = contigRange + 1; + + if (n != predict) { - if (m->isOwned(vert)) - { - const cgsize_t n = static_cast(apf::getNumber(gvn, vert, 0) + 1); // one based - vertexMin[0] = std::min(vertexMin[0], n); - vertexMax[0] = std::max(vertexMax[0], n); - - m->getPoint(vert, 0, point); - coords[0].push_back(point[0]); - coords[1].push_back(point[1]); - coords[2].push_back(point[2]); - } + //std::cout << std::string("Range must be contigious for vertices ") + std::to_string(n) + " " + std::to_string(contigRange) << std::endl; + PCU_ALWAYS_ASSERT_VERBOSE(true == false, (std::string("Range must be contigious for vertices ") + std::to_string(n) + " " + std::to_string(contigRange)).c_str()); } - m->end(vertIter); + else + contigRange = predict; // == n } + + vertexMin[0] = std::min(vertexMin[0], n); + vertexMax[0] = std::max(vertexMax[0], n); + + m->getPoint(vert, 0, point); + coords[0].push_back(point[0]); + coords[1].push_back(point[1]); + coords[2].push_back(point[2]); + + orderedVertices.push_back(vert); } } + m->end(vertIter); // oddness of the api vertexMin[1] = vertexMin[0]; @@ -798,31 +777,11 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap cgp_error_exit(); } } + return std::make_tuple(orderedVertices, vertexMin[0], vertexMax[0]); +} - std::vector apfElementOrder; - apfElementOrder.push_back(apf::Mesh::HEX); - apfElementOrder.push_back(apf::Mesh::TET); - apfElementOrder.push_back(apf::Mesh::PYRAMID); - apfElementOrder.push_back(apf::Mesh::QUAD); - apfElementOrder.push_back(apf::Mesh::TRIANGLE); - apfElementOrder.push_back(apf::Mesh::EDGE); - - std::vector cgnsElementOrder; - cgnsElementOrder.push_back(CGNS_ENUMV(HEXA_8)); - cgnsElementOrder.push_back(CGNS_ENUMV(TETRA_4)); - cgnsElementOrder.push_back(CGNS_ENUMV(PYRA_5)); - cgnsElementOrder.push_back(CGNS_ENUMV(QUAD_4)); - cgnsElementOrder.push_back(CGNS_ENUMV(TRI_3)); - cgnsElementOrder.push_back(CGNS_ENUMV(BAR_2)); - - std::map apf2cgns; - apf2cgns.insert(std::make_pair(apf::Mesh::HEX, CGNS_ENUMV(HEXA_8))); - apf2cgns.insert(std::make_pair(apf::Mesh::TET, CGNS_ENUMV(TETRA_4))); - apf2cgns.insert(std::make_pair(apf::Mesh::PYRAMID, CGNS_ENUMV(PYRA_5))); - apf2cgns.insert(std::make_pair(apf::Mesh::QUAD, CGNS_ENUMV(QUAD_4))); - apf2cgns.insert(std::make_pair(apf::Mesh::TRIANGLE, CGNS_ENUMV(TRI_3))); - apf2cgns.insert(std::make_pair(apf::Mesh::EDGE, CGNS_ENUMV(BAR_2))); - +auto WriteElements(const CGNS &cgns, apf::Mesh *m, apf::GlobalNumbering *gvn, const int cell_dim, const Count &cellCount, const std::vector &apfElementOrder, const std::vector &cgnsElementOrder) +{ std::vector globalNumbersByElementType(apfElementOrder.size(), 0); std::vector numbersByElementType(apfElementOrder.size(), 0); for (std::size_t o = 0; o < apfElementOrder.size(); o++) @@ -832,7 +791,7 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap int counter = 0; while ((cell = m->iterate(cellIter))) { - if (m->getType(cell) == apfElementOrder[o] && m->isOwned(cell)) + if (m->getType(cell) == apfElementOrder[o] && m->isOwned(cell)) // must be same test as below { counter++; } @@ -847,25 +806,26 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap PCU_ALWAYS_ASSERT_VERBOSE(allTotal == cellCount.first, ("Must be equal " + std::to_string(allTotal) + " " + std::to_string(cellCount.first)).c_str()); int globalStart = 1; // one-based - std::vector orderedElements; + std::vector> orderedElements(apfElementOrder.size()); + std::vector> ranges(apfElementOrder.size()); for (std::size_t o = 0; o < apfElementOrder.size(); o++) { - std::vector elements; + std::vector elementVertices; apf::MeshIterator *cellIter = m->begin(cell_dim); apf::MeshEntity *cell = nullptr; apf::Downward verts; while ((cell = m->iterate(cellIter))) { - if (m->getType(cell) == apfElementOrder[o] && m->isOwned(cell)) + if (m->getType(cell) == apfElementOrder[o] && m->isOwned(cell)) // must be same test as above { const auto numVerts = m->getDownward(cell, 0, verts); for (int i = 0; i < numVerts; i++) { const auto n = apf::getNumber(gvn, verts[i], 0); - elements.push_back(n + 1); // one-based + elementVertices.push_back(n + 1); // one-based } - orderedElements.push_back(cell); + orderedElements[o].push_back(cell); } } m->end(cellIter); @@ -890,20 +850,253 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap cgsize_t elStart = globalStart + num; cgsize_t elEnd = elStart + numbersByElementType[o] - 1; // one-based stuff if (cgp_elements_write_data(cgns.index, cgns.base, cgns.zone, sectionNumber, elStart, elEnd, // per processor within the range[start, end] - elements.data())) + elementVertices.data())) cgp_error_exit(); - //std::cout << "RANK: " << PCU_Comm_Self() << " ==> " << globalStart << " " << globalEnd << " elStart " << elStart << " elEnd " << elEnd << " numbersByElementType[o] " << numbersByElementType[o] << std::endl; + //std::cout << std::flush << "RANK: " << PCU_Comm_Self() << " ==> " << globalStart << " " << globalEnd << " elStart " << elStart << " elEnd " << elEnd << " numbersByElementType[o] " << numbersByElementType[o] << " of " << std::string(cg_ElementTypeName(cgnsElementOrder[o])) << std::flush << std::endl; globalStart += globalNumbersByElementType[o]; + + ranges[o] = std::make_pair(elStart, elEnd); } + else + ranges[o] = std::make_pair(-1, -1); + } + return std::make_tuple(orderedElements, ranges); +} + +// copy is deliberate +void Write3DFaces(CGNS cgns, apf::Mesh *m, const Count &faceCount, const Count &vertexCount, apf::GlobalNumbering *gvn) +{ + std::array sizes; + sizes[0] = vertexCount.first; // global + sizes[1] = faceCount.first; // global + sizes[2] = 0; // nodes are unsorted, as defined by api + + { + std::string baseName("FaceMeshBase"); + if (cg_base_write(cgns.index, baseName.c_str(), 2, cgns.phys_dim, &cgns.base)) + cg_error_exit(); } + // Write the default units at the top. + if (cg_goto(cgns.index, cgns.base, "end")) + cg_error_exit(); + + if (cg_units_write(CGNS_ENUMV(Kilogram), CGNS_ENUMV(Meter), CGNS_ENUMV(Second), CGNS_ENUMV(Kelvin), + CGNS_ENUMV(Degree))) + cg_error_exit(); + + if (cg_dataclass_write(CGNS_ENUMV(Dimensional))) + cg_error_exit(); + + { + std::string zoneName("FaceMeshZone"); + if (cg_zone_write(cgns.index, cgns.base, zoneName.c_str(), sizes.data(), CGNS_ENUMV(Unstructured), &cgns.zone)) + cg_error_exit(); + } + + // Stupid api why in the name would you have to repeat ALL vertices again.... + auto &&vertResult = WriteVertices(cgns, m, gvn); + // + std::vector apfElementOrder; + apfElementOrder.push_back(apf::Mesh::QUAD); + apfElementOrder.push_back(apf::Mesh::TRIANGLE); + + std::vector cgnsElementOrder; + cgnsElementOrder.push_back(CGNS_ENUMV(QUAD_4)); + cgnsElementOrder.push_back(CGNS_ENUMV(TRI_3)); + // + auto &&cellResult = WriteElements(cgns, m, gvn, 2, faceCount, apfElementOrder, cgnsElementOrder); + + apf::GlobalNumbering *gcn = nullptr; + gcn = apf::makeGlobal( + apf::numberOwnedDimension(m, "2D element-nums", 2)); + synchronize(gcn); + // + WriteTags(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m, gvn, gcn); + // + WriteFields(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m, gvn, gcn); + + destroyGlobalNumbering(gcn); +} + +// copy is deliberate +void Write2DEdges(CGNS cgns, apf::Mesh *m, const Count &edgeCount, const Count &vertexCount, apf::GlobalNumbering *gvn) +{ + std::array sizes; + sizes[0] = vertexCount.first; // global + sizes[1] = edgeCount.first; // global + sizes[2] = 0; // nodes are unsorted, as defined by api + + { + std::string baseName("EdgeMeshBase"); + if (cg_base_write(cgns.index, baseName.c_str(), 1, cgns.phys_dim, &cgns.base)) + cg_error_exit(); + } + // Write the default units at the top. + if (cg_goto(cgns.index, cgns.base, "end")) + cg_error_exit(); + + if (cg_units_write(CGNS_ENUMV(Kilogram), CGNS_ENUMV(Meter), CGNS_ENUMV(Second), CGNS_ENUMV(Kelvin), + CGNS_ENUMV(Degree))) + cg_error_exit(); + + if (cg_dataclass_write(CGNS_ENUMV(Dimensional))) + cg_error_exit(); + + { + std::string zoneName("EdgeMeshZone"); + if (cg_zone_write(cgns.index, cgns.base, zoneName.c_str(), sizes.data(), CGNS_ENUMV(Unstructured), &cgns.zone)) + cg_error_exit(); + } + + // Stupid api why in the name would you have to repeat ALL vertices again.... + auto &&vertResult = WriteVertices(cgns, m, gvn); + // + std::vector apfElementOrder; + apfElementOrder.push_back(apf::Mesh::EDGE); + + std::vector cgnsElementOrder; + cgnsElementOrder.push_back(CGNS_ENUMV(BAR_2)); + // + auto &&cellResult = WriteElements(cgns, m, gvn, 1, edgeCount, apfElementOrder, cgnsElementOrder); + + apf::GlobalNumbering *gcn = nullptr; + gcn = apf::makeGlobal( + apf::numberOwnedDimension(m, "1D element-nums", 1)); + synchronize(gcn); + // + WriteTags(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m, gvn, gcn); + // + WriteFields(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m, gvn, gcn); + + destroyGlobalNumbering(gcn); +} + +// Todo split this out into a list of calls to local functions to show process/work flow +void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap) +{ + static_assert(std::is_same::value, "cgsize_t not compiled as int"); + + const auto myRank = PCU_Comm_Self(); + const Count vertexCount = count(m, 0); + const Count edgeCount = count(m, 1); + const Count faceCount = count(m, 2); + const auto cell_dim = m->getDimension(); + const Count cellCount = count(m, cell_dim); + // for (int i = 0; i < PCU_Comm_Peers(); ++i) + // { + // if (i == PCU_Comm_Self()) + // { + // std::cout << "*******Local Mesh Stats******************\n"; + // std::cout << "Rank: " << myRank << ": Number of cells " << cellCount.second << "\n"; + // std::cout << "Rank: " << myRank << ": Number of vertices " << vertexCount.second << "\n"; + // std::cout << "Rank: " << myRank << ": Number of faces " << faceCount.second << "\n"; + // std::cout << "Rank: " << myRank << ": Number of edges " << edgeCount.second << "\n"; + // std::cout << "*****************************************\n"; + // } + // PCU_Barrier(); + // } + + PCU_Barrier(); + if (myRank == 0) + { + std::cout << "*******Global Mesh Stats*****************\n"; + std::cout << ": Number of cells " << cellCount.first << "\n"; + std::cout << ": Number of vertices " << vertexCount.first << "\n"; + std::cout << ": Number of faces " << faceCount.first << "\n"; + std::cout << ": Number of edges " << edgeCount.first << "\n"; + std::cout << "*****************************************\n"; + } + + std::array sizes; + sizes[0] = vertexCount.first; // global + sizes[1] = cellCount.first; // global + sizes[2] = 0; // nodes are unsorted, as defined by api + + // Copy communicator + auto communicator = PCU_Get_Comm(); + cgp_mpi_comm(communicator); + // + cgp_pio_mode(CGNS_ENUMV(CGP_INDEPENDENT)); + + CGNS cgns; + if (cgp_open(prefix, CGNS_ENUMV(CG_MODE_WRITE), &cgns.index)) + cgp_error_exit(); + + { + std::string baseName("VolumeMeshBase"); + if (cg_base_write(cgns.index, baseName.c_str(), cell_dim, cgns.phys_dim, &cgns.base)) + cg_error_exit(); + } + // Write the default units at the top. + if (cg_goto(cgns.index, cgns.base, "end")) + cg_error_exit(); + + if (cg_units_write(CGNS_ENUMV(Kilogram), CGNS_ENUMV(Meter), CGNS_ENUMV(Second), CGNS_ENUMV(Kelvin), + CGNS_ENUMV(Degree))) + cg_error_exit(); + + if (cg_dataclass_write(CGNS_ENUMV(Dimensional))) + cg_error_exit(); + + { + std::string zoneName("VolumeMeshZone"); + if (cg_zone_write(cgns.index, cgns.base, zoneName.c_str(), sizes.data(), CGNS_ENUMV(Unstructured), &cgns.zone)) + cg_error_exit(); + } + + apf::GlobalNumbering *gvn = nullptr; + gvn = apf::makeGlobal(apf::numberOwnedNodes(m, "node-nums")); + apf::synchronize(gvn); + // + auto &&vertResult = WriteVertices(cgns, m, gvn); + // + std::vector apfElementOrder; + apfElementOrder.push_back(apf::Mesh::HEX); + apfElementOrder.push_back(apf::Mesh::TET); + apfElementOrder.push_back(apf::Mesh::PYRAMID); + apfElementOrder.push_back(apf::Mesh::QUAD); + apfElementOrder.push_back(apf::Mesh::TRIANGLE); + apfElementOrder.push_back(apf::Mesh::EDGE); + + std::vector cgnsElementOrder; + cgnsElementOrder.push_back(CGNS_ENUMV(HEXA_8)); + cgnsElementOrder.push_back(CGNS_ENUMV(TETRA_4)); + cgnsElementOrder.push_back(CGNS_ENUMV(PYRA_5)); + cgnsElementOrder.push_back(CGNS_ENUMV(QUAD_4)); + cgnsElementOrder.push_back(CGNS_ENUMV(TRI_3)); + cgnsElementOrder.push_back(CGNS_ENUMV(BAR_2)); + // + auto &&cellResult = WriteElements(cgns, m, gvn, m->getDimension(), cellCount, apfElementOrder, cgnsElementOrder); + // + apf::GlobalNumbering *gcn = nullptr; + gcn = apf::makeGlobal(apf::numberElements(m, "3D element-nums")); + // Could be a boco at any dim + std::map apf2cgns; + apf2cgns.insert(std::make_pair(apf::Mesh::HEX, CGNS_ENUMV(HEXA_8))); + apf2cgns.insert(std::make_pair(apf::Mesh::TET, CGNS_ENUMV(TETRA_4))); + apf2cgns.insert(std::make_pair(apf::Mesh::PYRAMID, CGNS_ENUMV(PYRA_5))); + apf2cgns.insert(std::make_pair(apf::Mesh::QUAD, CGNS_ENUMV(QUAD_4))); + apf2cgns.insert(std::make_pair(apf::Mesh::TRIANGLE, CGNS_ENUMV(TRI_3))); + apf2cgns.insert(std::make_pair(apf::Mesh::EDGE, CGNS_ENUMV(BAR_2))); // AddBocosToMainBase(cgns, cellCount.first, m, cgnsBCMap, apf2cgns, gvn, gcn); // - WriteTagsToMainBase(cgns, orderedElements, m, gvn, gcn); + WriteTags(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m, gvn, gcn); + // + WriteFields(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m, gvn, gcn); // - WriteFieldsToMainBase(cgns, orderedElements, m, gvn, gcn); + if (cell_dim == 3) + { + Write3DFaces(cgns, m, faceCount, vertexCount, gvn); + // + Write2DEdges(cgns, m, edgeCount, vertexCount, gvn); + } + else if (cell_dim == 2) + { + Write2DEdges(cgns, m, edgeCount, vertexCount, gvn); + } // destroyGlobalNumbering(gvn); destroyGlobalNumbering(gcn); From 62d25e826c960686ca5e14e246606124d01dbbd7 Mon Sep 17 00:00:00 2001 From: a-jp Date: Tue, 19 Nov 2019 13:47:31 +0000 Subject: [PATCH 44/72] unused args --- apf/apfCGNS.cc | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/apf/apfCGNS.cc b/apf/apfCGNS.cc index bff825b47..2462c75f0 100644 --- a/apf/apfCGNS.cc +++ b/apf/apfCGNS.cc @@ -57,9 +57,9 @@ struct CGNS const int phys_dim = 3; }; -void WriteTags(const CGNS &cgns, const std::vector> &orderedEnts, const std::vector> &ranges, const std::vector &orderedVertices, const int &vStart, const int &vEnd, apf::Mesh *m, apf::GlobalNumbering *gvn, apf::GlobalNumbering *gcn) +void WriteTags(const CGNS &cgns, const std::vector> &orderedEnts, const std::vector> &ranges, const std::vector &orderedVertices, const int &vStart, const int &vEnd, apf::Mesh *m) { - const auto loopVertexTags = [&m](const auto &orderedEnts, const int &solIndex, const auto &inner, const auto &post, apf::GlobalNumbering *numbering, const int &start, const int &end) { + const auto loopVertexTags = [&m](const auto &orderedEnts, const int &solIndex, const auto &inner, const auto &post, const int &start, const int &end) { apf::DynamicArray tags; m->getTags(tags); for (std::size_t i = 0; i < tags.getSize(); ++i) @@ -116,7 +116,7 @@ void WriteTags(const CGNS &cgns, const std::vector tags; m->getTags(tags); for (std::size_t i = 0; i < tags.getSize(); ++i) @@ -249,20 +249,20 @@ void WriteTags(const CGNS &cgns, const std::vector> &orderedEnts, const std::vector> &ranges, const std::vector &orderedVertices, const int &vStart, const int &vEnd, apf::Mesh *m, apf::GlobalNumbering *gvn, apf::GlobalNumbering *gcn) +void WriteFields(const CGNS &cgns, const std::vector> &orderedEnts, const std::vector> &ranges, const std::vector &orderedVertices, const int &vStart, const int &vEnd, apf::Mesh *m) { - const auto writeField = [&m, &cgns](apf::Field *f, const auto &orderedEnts, const int &solIndex, const auto &inner, const auto &post, const int &numComponents, const std::string &fieldName, apf::GlobalNumbering *numbering, const int &start, const int &end, int &fieldIndex) { + const auto writeField = [&m, &cgns](apf::Field *f, const auto &orderedEnts, const int &solIndex, const auto &inner, const auto &post, const int &numComponents, const std::string &fieldName, const int &start, const int &end, int &fieldIndex) { std::vector data; if (numComponents != 1) { @@ -302,11 +302,11 @@ void WriteFields(const CGNS &cgns, const std::vectorcountFields(); ++i) { apf::Field *f = m->getField(i); @@ -316,12 +316,12 @@ void WriteFields(const CGNS &cgns, const std::vectorcountFields(); ++i) { apf::Field *f = m->getField(i); @@ -329,11 +329,11 @@ void WriteFields(const CGNS &cgns, const std::vectorgetName()); fieldName.resize(32); // daft api int fieldIndex = -1; - writeField(f, orderedEnts, solIndex, inner, post, numComponents, fieldName, numbering, vStart, vEnd, fieldIndex); + writeField(f, orderedEnts, solIndex, inner, post, numComponents, fieldName, vStart, vEnd, fieldIndex); } }; - const auto postLambda = [&cgns](const int &solIndex, const std::string &name, std::vector &ddata, const cgsize_t *rmin, const cgsize_t *rmax, const int &globalSize, const int &fieldIndex) { + const auto postLambda = [&cgns](const int &solIndex, std::vector &ddata, const cgsize_t *rmin, const cgsize_t *rmax, const int &globalSize, const int &fieldIndex) { if (globalSize > 0) { if (cgp_field_write_data(cgns.index, cgns.base, cgns.zone, solIndex, fieldIndex, &rmin[0], &rmax[0], @@ -354,14 +354,14 @@ void WriteFields(const CGNS &cgns, const std::vector(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m, gvn, gcn); + WriteTags(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m); // - WriteFields(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m, gvn, gcn); + WriteFields(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m); destroyGlobalNumbering(gcn); } @@ -966,9 +966,9 @@ void Write2DEdges(CGNS cgns, apf::Mesh *m, const Count &edgeCount, const Count & apf::numberOwnedDimension(m, "1D element-nums", 1)); synchronize(gcn); // - WriteTags(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m, gvn, gcn); + WriteTags(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m); // - WriteFields(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m, gvn, gcn); + WriteFields(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m); destroyGlobalNumbering(gcn); } @@ -1083,9 +1083,9 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap // AddBocosToMainBase(cgns, cellCount.first, m, cgnsBCMap, apf2cgns, gvn, gcn); // - WriteTags(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m, gvn, gcn); + WriteTags(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m); // - WriteFields(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m, gvn, gcn); + WriteFields(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m); // if (cell_dim == 3) { From a3acff6b2b9f60f7fce8b08eb9373394a2b17391 Mon Sep 17 00:00:00 2001 From: a-jp Date: Tue, 19 Nov 2019 14:51:24 +0000 Subject: [PATCH 45/72] add some dummy vectors and write them out --- apf/apfCGNS.cc | 209 ++++++++++++++++++++++++++----------------------- test/cgns.cc | 34 +++++++- 2 files changed, 142 insertions(+), 101 deletions(-) diff --git a/apf/apfCGNS.cc b/apf/apfCGNS.cc index 2462c75f0..c8b3bdbae 100644 --- a/apf/apfCGNS.cc +++ b/apf/apfCGNS.cc @@ -68,51 +68,55 @@ void WriteTags(const CGNS &cgns, const std::vectorgetTagType(t); const int tagSize = m->getTagSize(t); std::string tagName(m->getTagName(t)); - tagName.resize(32); // daft api + + if (tagName.size() > 32) + tagName.resize(32); // daft api // boring... replace with variant std::vector idata; std::vector ddata; std::vector ldata; - if (tagSize != 1) + for (int ti = 0; ti < tagSize; ti++) { - std::cout << "Not finished yet, can't be that hard..." << tagSize << std::endl; - // one assumes this just needs to be a loop over components - exit(-1); - } + cgsize_t rmin[3]; + cgsize_t rmax[3]; - cgsize_t rmin[3]; - cgsize_t rmax[3]; + rmin[0] = start; + rmax[0] = end; + //std::cout << start << " " << end << std::endl; + int fieldIndex = -1; + auto tagNameNew = tagName; + if (tagSize > 0) + tagNameNew += "[" + std::to_string(ti) + "]"; - rmin[0] = start; - rmax[0] = end; - //std::cout << start << " " << end << std::endl; - int fieldIndex = -1; - for (const auto &e : orderedEnts) - { - if (m->hasTag(e, t) && m->isOwned(e)) + for (const auto &e : orderedEnts) { - inner(e, t, idata, ddata, ldata, tagType); + if (m->hasTag(e, t) && m->isOwned(e)) + { + inner(e, t, tagSize, ti, idata, ddata, ldata, tagType); + } } - } - // ensure collectives are called by all, even if local has no data - int isize = idata.size(); - PCU_Add_Ints(&isize, 1); // size of total array + // ensure collectives are called by all, even if local has no data + int isize = idata.size(); + PCU_Add_Ints(&isize, 1); // size of total array + + int dsize = ddata.size(); + PCU_Add_Ints(&dsize, 1); // size of total array - int dsize = ddata.size(); - PCU_Add_Ints(&dsize, 1); // size of total array + int lsize = ldata.size(); + PCU_Add_Ints(&lsize, 1); // size of total array - int lsize = ldata.size(); - PCU_Add_Ints(&lsize, 1); // size of total array + // oddness of the api + rmin[1] = rmin[0]; + rmin[2] = rmin[0]; + rmax[1] = rmax[0]; + rmax[2] = rmax[0]; - // oddness of the api - rmin[1] = rmin[0]; - rmin[2] = rmin[0]; - rmax[1] = rmax[0]; - rmax[2] = rmax[0]; - post(solIndex, tagName, idata, ddata, ldata, rmin, rmax, isize, dsize, lsize, fieldIndex); + if (isize > 0 || dsize > 0 || lsize > 0) + post(solIndex, tagNameNew, idata, ddata, ldata, rmin, rmax, isize, dsize, lsize, fieldIndex); + } } }; @@ -125,62 +129,62 @@ void WriteTags(const CGNS &cgns, const std::vectorgetTagType(t); const int tagSize = m->getTagSize(t); std::string tagName(m->getTagName(t)); - tagName.resize(32); // daft api - if (tagSize != 1) - { - std::cout << "Not finished yet, can't be that hard..." << tagSize << std::endl; - // one assumes this just needs to a loop over components - exit(-1); - } + if (tagName.size() > 32) + tagName.resize(32); // daft api - int fieldIndex = -1; - for (std::size_t e = 0; e < orderedEnts.size(); e++) + for (int ti = 0; ti < tagSize; ti++) { + int fieldIndex = -1; + auto tagNameNew = tagName; + if (tagSize > 0) + tagNameNew += "[" + std::to_string(ti) + "]"; - // boring... replace with variant - std::vector idata; - std::vector ddata; - std::vector ldata; + for (std::size_t e = 0; e < orderedEnts.size(); e++) + { + // boring... replace with variant + std::vector idata; + std::vector ddata; + std::vector ldata; - cgsize_t rmin[3]; - cgsize_t rmax[3]; + cgsize_t rmin[3]; + cgsize_t rmax[3]; - rmin[0] = ranges[e].first; - rmax[0] = ranges[e].second; + rmin[0] = ranges[e].first; + rmax[0] = ranges[e].second; - for (const auto &elm : orderedEnts[e]) - { - if (m->hasTag(elm, t) && m->isOwned(elm)) + for (const auto &elm : orderedEnts[e]) { - inner(elm, t, idata, ddata, ldata, tagType); + if (m->hasTag(elm, t) && m->isOwned(elm)) + { + inner(elm, t, tagSize, ti, idata, ddata, ldata, tagType); + } } - } - // ensure collectives are called by all, even if local has no data - int isize = idata.size(); - PCU_Add_Ints(&isize, 1); // size of total array + // ensure collectives are called by all, even if local has no data + int isize = idata.size(); + PCU_Add_Ints(&isize, 1); // size of total array - int dsize = ddata.size(); - PCU_Add_Ints(&dsize, 1); // size of total array + int dsize = ddata.size(); + PCU_Add_Ints(&dsize, 1); // size of total array - int lsize = ldata.size(); - PCU_Add_Ints(&lsize, 1); // size of total array + int lsize = ldata.size(); + PCU_Add_Ints(&lsize, 1); // size of total array - // oddness of the api - rmin[1] = rmin[0]; - rmin[2] = rmin[0]; - rmax[1] = rmax[0]; - rmax[2] = rmax[0]; - - if (isize > 0 || dsize > 0 || lsize > 0) - post(solIndex, tagName, idata, ddata, ldata, rmin, rmax, isize, dsize, lsize, fieldIndex); + // oddness of the api + rmin[1] = rmin[0]; + rmin[2] = rmin[0]; + rmax[1] = rmax[0]; + rmax[2] = rmax[0]; + + if (isize > 0 || dsize > 0 || lsize > 0) + post(solIndex, tagNameNew, idata, ddata, ldata, rmin, rmax, isize, dsize, lsize, fieldIndex); + } } } }; const auto postLambda = [&cgns](const int &solIndex, const std::string &name, std::vector &idata, std::vector &ddata, std::vector &ldata, const cgsize_t *rmin, const cgsize_t *rmax, const int isize, const int dsize, const int lsize, int &fieldIndex) { - if (dsize > 0) { if (fieldIndex == -1) @@ -217,24 +221,24 @@ void WriteTags(const CGNS &cgns, const std::vector &idata, std::vector &ddata, std::vector &ldata, const int &tagType) { + const auto innerLambda = [&m](apf::MeshEntity *elem, apf::MeshTag *tag, const int &tagSize, const int &ti, std::vector &idata, std::vector &ddata, std::vector &ldata, const int &tagType) { if (tagType == apf::Mesh::TagType::DOUBLE) { - double vals = -1; - m->getDoubleTag(elem, tag, &vals); - ddata.push_back(vals); + std::vector vals(tagSize, -12345); + m->getDoubleTag(elem, tag, vals.data()); + ddata.push_back(vals[ti]); } else if (tagType == apf::Mesh::TagType::INT) { - int vals = -1; - m->getIntTag(elem, tag, &vals); - idata.push_back(vals); + std::vector vals(tagSize, -12345); + m->getIntTag(elem, tag, vals.data()); + idata.push_back(vals[ti]); } else if (tagType == apf::Mesh::TagType::LONG) { - long vals = -1; - m->getLongTag(elem, tag, &vals); - ldata.push_back(vals); + std::vector vals(tagSize, -12345); + m->getLongTag(elem, tag, vals.data()); + ldata.push_back(vals[ti]); } else { @@ -262,14 +266,8 @@ void WriteTags(const CGNS &cgns, const std::vector> &orderedEnts, const std::vector> &ranges, const std::vector &orderedVertices, const int &vStart, const int &vEnd, apf::Mesh *m) { - const auto writeField = [&m, &cgns](apf::Field *f, const auto &orderedEnts, const int &solIndex, const auto &inner, const auto &post, const int &numComponents, const std::string &fieldName, const int &start, const int &end, int &fieldIndex) { + const auto writeField = [&m, &cgns](apf::Field *f, const auto &orderedEnts, const int &solIndex, const auto &inner, const auto &post, const int &numComponents, const int &component, const std::string &fieldName, const int &start, const int &end, int &fieldIndex) { std::vector data; - if (numComponents != 1) - { - std::cout << "Not finished yet, can't be that hard..." << numComponents << std::endl; - // one assumes just a loop over components - exit(-1); - } cgsize_t rmin[3]; cgsize_t rmax[3]; @@ -282,7 +280,7 @@ void WriteFields(const CGNS &cgns, const std::vectorhasEntity(e) && m->isOwned(e)) { - inner(e, fieldData, data); + inner(e, fieldData, data, numComponents, component); } } @@ -312,11 +310,20 @@ void WriteFields(const CGNS &cgns, const std::vectorgetField(i); const int numComponents = f->countComponents(); std::string fieldName(f->getName()); - fieldName.resize(32); // daft api - int fieldIndex = -1; - for (std::size_t e = 0; e < orderedEnts.size(); e++) + if (fieldName.size() > 32) + fieldName.resize(32); // daft api + + for (int component = 0; component < numComponents; component++) { - writeField(f, orderedEnts[e], solIndex, inner, post, numComponents, fieldName, ranges[e].first, ranges[e].second, fieldIndex); + int fieldIndex = -1; + auto fieldNameNew = fieldName; + if (numComponents > 0) + fieldNameNew += "[" + std::to_string(component) + "]"; + + for (std::size_t e = 0; e < orderedEnts.size(); e++) + { + writeField(f, orderedEnts[e], solIndex, inner, post, numComponents, component, fieldNameNew, ranges[e].first, ranges[e].second, fieldIndex); + } } } }; @@ -327,9 +334,17 @@ void WriteFields(const CGNS &cgns, const std::vectorgetField(i); const int numComponents = f->countComponents(); std::string fieldName(f->getName()); - fieldName.resize(32); // daft api - int fieldIndex = -1; - writeField(f, orderedEnts, solIndex, inner, post, numComponents, fieldName, vStart, vEnd, fieldIndex); + if (fieldName.size() > 32) + fieldName.resize(32); // daft api + + for (int component = 0; component < numComponents; component++) + { + int fieldIndex = -1; + auto fieldNameNew = fieldName; + if (numComponents > 0) + fieldNameNew += "[" + std::to_string(component) + "]"; + writeField(f, orderedEnts, solIndex, inner, post, numComponents, component, fieldNameNew, vStart, vEnd, fieldIndex); + } } }; @@ -342,10 +357,10 @@ void WriteFields(const CGNS &cgns, const std::vector *fieldData, std::vector &ddata) { - double vals = -1; - fieldData->get(elem, &vals); - ddata.push_back(vals); + const auto innerLambda = [](apf::MeshEntity *elem, apf::FieldDataOf *fieldData, std::vector &ddata, const int &numComponents, const int &component) { + std::vector vals(numComponents, -12345); + fieldData->get(elem, vals.data()); + ddata.push_back(vals[component]); }; int solIndex = -1; diff --git a/test/cgns.cc b/test/cgns.cc index e44f37dd3..ebcf1111c 100644 --- a/test/cgns.cc +++ b/test/cgns.cc @@ -122,6 +122,32 @@ pMesh toPumi(const std::string &prefix, gmi_model *g, apf::Mesh2 *mesh) auto additional(const std::string &prefix, gmi_model *g, apf::Mesh2 *mesh) { + // add dummy vector to mesh + const auto addVector = [&mesh](const int &dim) { + apf::Field *field = nullptr; + const std::string name = "DummyVector_" + std::to_string(dim); + if (dim != 0) + field = apf::createField(mesh, name.c_str(), apf::VECTOR, apf::getConstant(dim)); + else if (dim == 0) + field = apf::createFieldOn(mesh, name.c_str(), apf::VECTOR); + std::cout << "*************************** "<< dim << std::endl; + apf::MeshIterator *it = mesh->begin(dim); + apf::MeshEntity *elm = nullptr; + while ((elm = mesh->iterate(it))) + { + apf::Vector3 v; + v[0] = 1.0; + v[1] = 2.0; + v[2] = 3.0; + apf::setVector(field, elm, 0, v); + } + mesh->end(it); + //apf::destroyField(field); + }; + + for(int i = 0; i <= mesh->getDimension(); i++) + addVector(i); + // seems essential to make pm first before calling balance or reorder... auto pm = toPumi(prefix, g, mesh); balance(prefix, apf::RCB, pm); @@ -248,7 +274,7 @@ int main(int argc, char **argv) apf::writeVtkFiles(name.c_str(), m, 0); } } - else if(dim == 2) + else if (dim == 2) { { const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK_cellMesh"); @@ -261,9 +287,9 @@ int main(int argc, char **argv) { const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK_vertexMesh"); apf::writeVtkFiles(name.c_str(), m, 0); - } + } } - else if(dim == 1) + else if (dim == 1) { { const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK_cellMesh"); @@ -272,7 +298,7 @@ int main(int argc, char **argv) { const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK_vertexMesh"); apf::writeVtkFiles(name.c_str(), m, 0); - } + } } // main purpose is to call additional tests through the test harness testing.cmake From 05a786573edf3955ec24c9f447960cacacf1e87d Mon Sep 17 00:00:00 2001 From: a-jp Date: Wed, 20 Nov 2019 09:29:26 +0000 Subject: [PATCH 46/72] bugs --- apf/apfCGNS.cc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/apf/apfCGNS.cc b/apf/apfCGNS.cc index c8b3bdbae..1b1e65c35 100644 --- a/apf/apfCGNS.cc +++ b/apf/apfCGNS.cc @@ -87,7 +87,7 @@ void WriteTags(const CGNS &cgns, const std::vector 0) + if (tagSize > 1) tagNameNew += "[" + std::to_string(ti) + "]"; for (const auto &e : orderedEnts) @@ -137,7 +137,7 @@ void WriteTags(const CGNS &cgns, const std::vector 0) + if (tagSize > 1) tagNameNew += "[" + std::to_string(ti) + "]"; for (std::size_t e = 0; e < orderedEnts.size(); e++) @@ -317,11 +317,12 @@ void WriteFields(const CGNS &cgns, const std::vector 0) + if (numComponents > 1) fieldNameNew += "[" + std::to_string(component) + "]"; for (std::size_t e = 0; e < orderedEnts.size(); e++) { + //std::cout << fieldNameNew << " " << fieldName << " " << component << " " << numComponents << " " << e << std::endl; writeField(f, orderedEnts[e], solIndex, inner, post, numComponents, component, fieldNameNew, ranges[e].first, ranges[e].second, fieldIndex); } } @@ -341,8 +342,9 @@ void WriteFields(const CGNS &cgns, const std::vector 0) + if (numComponents > 1) fieldNameNew += "[" + std::to_string(component) + "]"; + //std::cout << fieldNameNew << " " << fieldName << " " << component << " " << numComponents << std::endl; writeField(f, orderedEnts, solIndex, inner, post, numComponents, component, fieldNameNew, vStart, vEnd, fieldIndex); } } @@ -850,8 +852,9 @@ auto WriteElements(const CGNS &cgns, apf::Mesh *m, apf::GlobalNumbering *gvn, co const int globalEnd = globalStart + globalNumbersByElementType[o] - 1; // one-based stuff // int sectionNumber = -1; - if (cgp_section_write(cgns.index, cgns.base, cgns.zone, (std::string(cg_ElementTypeName(cgnsElementOrder[o])) + " " + std::to_string(globalStart) + "->" + std::to_string(globalEnd)).c_str(), cgnsElementOrder[o], globalStart, - globalEnd, 0, §ionNumber)) // global start, end within the file for that element type + const std::string name = std::string(cg_ElementTypeName(cgnsElementOrder[o])) + " " + std::to_string(globalStart) + "->" + std::to_string(globalEnd); + //std::cout << "Section Name " << name << std::endl; + if (cgp_section_write(cgns.index, cgns.base, cgns.zone, name.c_str(), cgnsElementOrder[o], globalStart, globalEnd, 0, §ionNumber)) // global start, end within the file for that element type cgp_error_exit(); std::vector allNumbersForThisType(PCU_Comm_Peers(), 0); From e71a5fb4246778b999ba40f450184c8b76d35c50 Mon Sep 17 00:00:00 2001 From: a-jp Date: Wed, 20 Nov 2019 09:29:45 +0000 Subject: [PATCH 47/72] move test vector/scalar --- test/cgns.cc | 78 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 26 deletions(-) diff --git a/test/cgns.cc b/test/cgns.cc index ebcf1111c..29d5fcf96 100644 --- a/test/cgns.cc +++ b/test/cgns.cc @@ -122,32 +122,6 @@ pMesh toPumi(const std::string &prefix, gmi_model *g, apf::Mesh2 *mesh) auto additional(const std::string &prefix, gmi_model *g, apf::Mesh2 *mesh) { - // add dummy vector to mesh - const auto addVector = [&mesh](const int &dim) { - apf::Field *field = nullptr; - const std::string name = "DummyVector_" + std::to_string(dim); - if (dim != 0) - field = apf::createField(mesh, name.c_str(), apf::VECTOR, apf::getConstant(dim)); - else if (dim == 0) - field = apf::createFieldOn(mesh, name.c_str(), apf::VECTOR); - std::cout << "*************************** "<< dim << std::endl; - apf::MeshIterator *it = mesh->begin(dim); - apf::MeshEntity *elm = nullptr; - while ((elm = mesh->iterate(it))) - { - apf::Vector3 v; - v[0] = 1.0; - v[1] = 2.0; - v[2] = 3.0; - apf::setVector(field, elm, 0, v); - } - mesh->end(it); - //apf::destroyField(field); - }; - - for(int i = 0; i <= mesh->getDimension(); i++) - addVector(i); - // seems essential to make pm first before calling balance or reorder... auto pm = toPumi(prefix, g, mesh); balance(prefix, apf::RCB, pm); @@ -306,6 +280,58 @@ int main(int argc, char **argv) if (additionalTests) cleanUp = additional(prefix, g, m); // + if(additionalTests) + { + // add dummy vector to mesh + const auto addVector = [](apf::Mesh2 *mesh, const int &dim) { + apf::Field *field = nullptr; + const std::string name = "DummyVector_" + std::to_string(dim); + if (dim != 0) + field = apf::createField(mesh, name.c_str(), apf::VECTOR, apf::getConstant(dim)); + else if (dim == 0) + field = apf::createFieldOn(mesh, name.c_str(), apf::VECTOR); + //std::cout << "*************************** "<< dim << std::endl; + apf::MeshIterator *it = mesh->begin(dim); + apf::MeshEntity *elm = nullptr; + while ((elm = mesh->iterate(it))) + { + apf::Vector3 v; + v[0] = 1.0; + v[1] = 2.0; + v[2] = 3.0; + apf::setComponents(field, elm, 0, &v[0]); + } + mesh->end(it); + //apf::destroyField(field); + }; + + for(int i = 0; i <= m->getDimension(); i++) + addVector(m, i); + + // add dummy vector to mesh + const auto addScalar = [](apf::Mesh2 *mesh, const int &dim) { + apf::Field *field = nullptr; + const std::string name = "DummyScalar_" + std::to_string(dim); + if (dim != 0) + field = apf::createField(mesh, name.c_str(), apf::SCALAR, apf::getConstant(dim)); + else if (dim == 0) + field = apf::createFieldOn(mesh, name.c_str(), apf::SCALAR); + //std::cout << "*************************** "<< dim << std::endl; + apf::MeshIterator *it = mesh->begin(dim); + apf::MeshEntity *elm = nullptr; + while ((elm = mesh->iterate(it))) + { + double v = 1.0; + apf::setComponents(field, elm, 0, &v); + } + mesh->end(it); + //apf::destroyField(field); + }; + + for(int i = 0; i <= m->getDimension(); i++) + addScalar(m, i); + + } apf::writeCGNS((prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + "_outputFile.cgns").c_str(), m, cgnsBCMap); // if (additionalTests) From c683a7c427ac5dd9e417a06f5542c44527a798ea Mon Sep 17 00:00:00 2001 From: a-jp Date: Wed, 20 Nov 2019 10:45:54 +0000 Subject: [PATCH 48/72] if compiling cgns and omega_h bump c++ version to 2014 --- omega_h/CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/omega_h/CMakeLists.txt b/omega_h/CMakeLists.txt index 9a80399a1..750fa0538 100644 --- a/omega_h/CMakeLists.txt +++ b/omega_h/CMakeLists.txt @@ -17,7 +17,11 @@ set(HEADERS # Add the apf_omega_h library add_library(apf_omega_h ${SOURCES}) -target_compile_options(apf_omega_h PUBLIC "-std=c++11") +if(ENABLE_CGNS) + target_compile_options(apf_omega_h PUBLIC "-std=c++14") +else() + target_compile_options(apf_omega_h PUBLIC "-std=c++11") +endif() # Include directories target_include_directories(apf_omega_h INTERFACE From 7ff6be5279e4586c11e6b9802ccb6af5093cd86c Mon Sep 17 00:00:00 2001 From: a-jp Date: Wed, 20 Nov 2019 15:37:58 +0000 Subject: [PATCH 49/72] allow reader to open files with more than one base, only base one is read though --- mds/mdsCGNS.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mds/mdsCGNS.cc b/mds/mdsCGNS.cc index 418ffb7d5..ef027c893 100644 --- a/mds/mdsCGNS.cc +++ b/mds/mdsCGNS.cc @@ -917,8 +917,7 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM cg_nbases(cgid, &nbases); if (nbases > 1) { - std::cout << __LINE__ << " CGNS is dead " << std::endl; - Kill(cgid); + std::cout << "CGNS file has " << nbases << " nbases, only used base=1" << std::endl; } std::string basename; From c72a353c0983f7a39aa5f590c742a779241cf144 Mon Sep 17 00:00:00 2001 From: a-jp Date: Wed, 20 Nov 2019 15:38:24 +0000 Subject: [PATCH 50/72] increase regression testing by reading cgns file just written --- test/cgns.cc | 117 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 68 insertions(+), 49 deletions(-) diff --git a/test/cgns.cc b/test/cgns.cc index 29d5fcf96..b403eee0f 100644 --- a/test/cgns.cc +++ b/test/cgns.cc @@ -173,59 +173,29 @@ auto additional(const std::string &prefix, gmi_model *g, apf::Mesh2 *mesh) return clean; } -int main(int argc, char **argv) +std::string doit(const std::string& argv1, const std::string& argv2, const bool& additionalTests) { -#ifdef HAVE_CGNS - MPI_Init(&argc, &argv); - PCU_Comm_Init(); - lion_set_verbosity(1); - bool additionalTests = false; - if (argc < 3) - { - if (!PCU_Comm_Self()) - printf("Usage: %s \n", argv[0]); - MPI_Finalize(); - exit(EXIT_FAILURE); - return -1; - } - else if (argc == 4) - { - if (std::string(argv[3]) == "additional") - additionalTests = true; - else - { - if (!PCU_Comm_Self()) - printf("Usage: %s additional\n", argv[0]); - MPI_Finalize(); - exit(EXIT_FAILURE); - return -1; - } - } - else if (argc > 4) - { - if (!PCU_Comm_Self()) - printf("Usage: %s \n", argv[0]); - MPI_Finalize(); - exit(EXIT_FAILURE); - return -1; - } - gmi_register_null(); gmi_register_mesh(); gmi_model *g = gmi_load(".null"); apf::CGNSBCMap cgnsBCMap; - apf::Mesh2 *m = apf::loadMdsFromCGNS(g, argv[1], cgnsBCMap); + apf::Mesh2 *m = apf::loadMdsFromCGNS(g, argv1.c_str(), cgnsBCMap); m->verify(); // - m->writeNative(argv[2]); + m->writeNative(argv2.c_str()); // so we can see the result - const std::string path = argv[1]; - std::size_t found = path.find_last_of("/\\"); + const std::string path = argv1.c_str(); + const std::size_t found = path.find_last_of("/\\"); + std::size_t index = found + 1; + if(found > path.size()) + index = 0; + + //std::cout << "FOUND " << found << " " << path.size() << " " << path << " " << index << std::endl; #ifndef NDEBUG // debug settings, cmake double negative.... - const auto prefix = path.substr(found + 1) + "_debug"; + const auto prefix = path.substr(index) + "_debug"; #else // optimised setting - const auto prefix = path.substr(found + 1) + "_release"; + const auto prefix = path.substr(index) + "_release"; #endif const auto dim = m->getDimension(); @@ -280,7 +250,7 @@ int main(int argc, char **argv) if (additionalTests) cleanUp = additional(prefix, g, m); // - if(additionalTests) + if (additionalTests) { // add dummy vector to mesh const auto addVector = [](apf::Mesh2 *mesh, const int &dim) { @@ -305,7 +275,7 @@ int main(int argc, char **argv) //apf::destroyField(field); }; - for(int i = 0; i <= m->getDimension(); i++) + for (int i = 0; i <= m->getDimension(); i++) addVector(m, i); // add dummy vector to mesh @@ -326,13 +296,13 @@ int main(int argc, char **argv) } mesh->end(it); //apf::destroyField(field); - }; + }; - for(int i = 0; i <= m->getDimension(); i++) + for (int i = 0; i <= m->getDimension(); i++) addScalar(m, i); - } - apf::writeCGNS((prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + "_outputFile.cgns").c_str(), m, cgnsBCMap); + std::string cgnsOutputName = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + "_outputFile.cgns"; + apf::writeCGNS(cgnsOutputName.c_str(), m, cgnsBCMap); // if (additionalTests) { @@ -344,7 +314,56 @@ int main(int argc, char **argv) apf::destroyMesh(m); } // - std::cout << "TODO: Must read in newly created mesh, and check that it can perform same functions as initial mesh: see if I can diff the two" << std::endl; + return cgnsOutputName; +} + +int main(int argc, char **argv) +{ +#ifdef HAVE_CGNS + MPI_Init(&argc, &argv); + PCU_Comm_Init(); + lion_set_verbosity(1); + bool additionalTests = false; + if (argc < 3) + { + if (!PCU_Comm_Self()) + printf("Usage: %s \n", argv[0]); + MPI_Finalize(); + exit(EXIT_FAILURE); + return -1; + } + else if (argc == 4) + { + if (std::string(argv[3]) == "additional") + additionalTests = true; + else + { + if (!PCU_Comm_Self()) + printf("Usage: %s additional\n", argv[0]); + MPI_Finalize(); + exit(EXIT_FAILURE); + return -1; + } + } + else if (argc > 4) + { + if (!PCU_Comm_Self()) + printf("Usage: %s \n", argv[0]); + MPI_Finalize(); + exit(EXIT_FAILURE); + return -1; + } + + // Phase 1 + std::string cgnsOutputName; + { + cgnsOutputName = doit(argv[1], argv[2], additionalTests); + } + // Phase 2 + if (additionalTests) + { + doit(cgnsOutputName.c_str(), "tempy.smb", false); + } // PCU_Comm_Free(); MPI_Finalize(); From ff54530efffe81deca6e6b5e0da579e31e6b89fc Mon Sep 17 00:00:00 2001 From: a-jp Date: Wed, 20 Nov 2019 15:38:42 +0000 Subject: [PATCH 51/72] fix volume boco bug --- apf/apfCGNS.cc | 391 +++++++++++++++++++++++++------------------------ 1 file changed, 199 insertions(+), 192 deletions(-) diff --git a/apf/apfCGNS.cc b/apf/apfCGNS.cc index 1b1e65c35..86d283564 100644 --- a/apf/apfCGNS.cc +++ b/apf/apfCGNS.cc @@ -382,7 +382,189 @@ void WriteFields(const CGNS &cgns, const std::vector &apf2cgns, apf::GlobalNumbering *gvn, apf::GlobalNumbering *gcn) +auto WriteVertices(const CGNS &cgns, apf::Mesh *m, apf::GlobalNumbering *gvn) +{ + int Cx = -1; + int Cy = -1; + int Cz = -1; + + if (cgns.phys_dim > 0) + { + if (cgp_coord_write(cgns.index, cgns.base, cgns.zone, CGNS_ENUMV(RealDouble), "CoordinateX", &Cx)) + cgp_error_exit(); + } + if (cgns.phys_dim > 1) + { + if (cgp_coord_write(cgns.index, cgns.base, cgns.zone, CGNS_ENUMV(RealDouble), "CoordinateY", &Cy)) + cgp_error_exit(); + } + if (cgns.phys_dim > 2) + { + if (cgp_coord_write(cgns.index, cgns.base, cgns.zone, CGNS_ENUMV(RealDouble), "CoordinateZ", &Cz)) + cgp_error_exit(); + } + + std::vector orderedVertices; + cgsize_t vertexMin[3]; + cgsize_t vertexMax[3]; + cgsize_t contigRange = -1; + { + std::array, 3> coords; + + vertexMin[0] = std::numeric_limits::max(); + vertexMax[0] = 0; + + apf::Vector3 point; + apf::MeshIterator *vertIter = m->begin(0); + apf::MeshEntity *vert = nullptr; + while ((vert = m->iterate(vertIter))) + { + if (m->isOwned(vert)) + { + const cgsize_t n = static_cast(apf::getNumber(gvn, vert, 0) + 1); // one based + if (contigRange == -1) + { + contigRange = n; + } + else + { + const auto predict = contigRange + 1; + + if (n != predict) + { + //std::cout << std::string("Range must be contigious for vertices ") + std::to_string(n) + " " + std::to_string(contigRange) << std::endl; + PCU_ALWAYS_ASSERT_VERBOSE(true == false, (std::string("Range must be contigious for vertices ") + std::to_string(n) + " " + std::to_string(contigRange)).c_str()); + } + else + contigRange = predict; // == n + } + + vertexMin[0] = std::min(vertexMin[0], n); + vertexMax[0] = std::max(vertexMax[0], n); + + m->getPoint(vert, 0, point); + coords[0].push_back(point[0]); + coords[1].push_back(point[1]); + coords[2].push_back(point[2]); + + orderedVertices.push_back(vert); + } + } + m->end(vertIter); + + // oddness of the api + vertexMin[1] = vertexMin[0]; + vertexMin[2] = vertexMin[0]; + vertexMax[1] = vertexMax[0]; + vertexMax[2] = vertexMax[0]; + + if (cgns.phys_dim > 0) + { + if (cgp_coord_write_data(cgns.index, cgns.base, cgns.zone, Cx, &vertexMin[0], &vertexMax[0], coords[0].data())) + cgp_error_exit(); + } + if (cgns.phys_dim > 1) + { + if (cgp_coord_write_data(cgns.index, cgns.base, cgns.zone, Cy, &vertexMin[0], &vertexMax[0], coords[1].data())) + cgp_error_exit(); + } + if (cgns.phys_dim > 2) + { + if (cgp_coord_write_data(cgns.index, cgns.base, cgns.zone, Cz, &vertexMin[0], &vertexMax[0], coords[2].data())) + cgp_error_exit(); + } + } + return std::make_tuple(orderedVertices, vertexMin[0], vertexMax[0]); +} + +using CellElementReturn = std::tuple>, std::vector>>; +CellElementReturn WriteElements(const CGNS &cgns, apf::Mesh *m, apf::GlobalNumbering *gvn, const int cell_dim, const Count &cellCount, const std::vector &apfElementOrder, const std::vector &cgnsElementOrder) +{ + std::vector globalNumbersByElementType(apfElementOrder.size(), 0); + std::vector numbersByElementType(apfElementOrder.size(), 0); + for (std::size_t o = 0; o < apfElementOrder.size(); o++) + { + apf::MeshIterator *cellIter = m->begin(cell_dim); + apf::MeshEntity *cell = nullptr; + int counter = 0; + while ((cell = m->iterate(cellIter))) + { + if (m->getType(cell) == apfElementOrder[o] && m->isOwned(cell)) // must be same test as below + { + counter++; + } + } + m->end(cellIter); + numbersByElementType[o] = counter; + int total = counter; + PCU_Add_Ints(&total, 1); // size of total array + globalNumbersByElementType[o] = total; + } + cgsize_t allTotal = std::accumulate(globalNumbersByElementType.begin(), globalNumbersByElementType.end(), 0); + PCU_ALWAYS_ASSERT_VERBOSE(allTotal == cellCount.first, ("Must be equal " + std::to_string(allTotal) + " " + std::to_string(cellCount.first)).c_str()); + + int globalStart = 1; // one-based + std::vector> orderedElements(apfElementOrder.size()); + std::vector> ranges(apfElementOrder.size()); + for (std::size_t o = 0; o < apfElementOrder.size(); o++) + { + std::vector elementVertices; + apf::MeshIterator *cellIter = m->begin(cell_dim); + apf::MeshEntity *cell = nullptr; + apf::Downward verts; + + while ((cell = m->iterate(cellIter))) + { + if (m->getType(cell) == apfElementOrder[o] && m->isOwned(cell)) // must be same test as above + { + const auto numVerts = m->getDownward(cell, 0, verts); + for (int i = 0; i < numVerts; i++) + { + const auto n = apf::getNumber(gvn, verts[i], 0); + elementVertices.push_back(n + 1); // one-based + } + orderedElements[o].push_back(cell); + } + } + m->end(cellIter); + + if (globalNumbersByElementType[o] > 0) + { + const int globalEnd = globalStart + globalNumbersByElementType[o] - 1; // one-based stuff + // + int sectionNumber = -1; + const std::string name = std::string(cg_ElementTypeName(cgnsElementOrder[o])) + " " + std::to_string(globalStart) + "->" + std::to_string(globalEnd); + //std::cout << "Section Name " << name << std::endl; + if (cgp_section_write(cgns.index, cgns.base, cgns.zone, name.c_str(), cgnsElementOrder[o], globalStart, globalEnd, 0, §ionNumber)) // global start, end within the file for that element type + cgp_error_exit(); + + std::vector allNumbersForThisType(PCU_Comm_Peers(), 0); + MPI_Allgather(&numbersByElementType[o], 1, MPI_INT, allNumbersForThisType.data(), 1, + MPI_INT, PCU_Get_Comm()); + + cgsize_t num = 0; + for (int i = 0; i < PCU_Comm_Self(); i++) + num += allNumbersForThisType[i]; + + cgsize_t elStart = globalStart + num; + cgsize_t elEnd = elStart + numbersByElementType[o] - 1; // one-based stuff + if (cgp_elements_write_data(cgns.index, cgns.base, cgns.zone, sectionNumber, elStart, elEnd, // per processor within the range[start, end] + elementVertices.data())) + cgp_error_exit(); + + //std::cout << std::flush << "RANK: " << PCU_Comm_Self() << " ==> " << globalStart << " " << globalEnd << " elStart " << elStart << " elEnd " << elEnd << " numbersByElementType[o] " << numbersByElementType[o] << " of " << std::string(cg_ElementTypeName(cgnsElementOrder[o])) << std::flush << std::endl; + + globalStart += globalNumbersByElementType[o]; + + ranges[o] = std::make_pair(elStart, elEnd); + } + else + ranges[o] = std::make_pair(-1, -1); + } + return std::make_tuple(orderedElements, ranges); +} + +void AddBocosToMainBase(const CGNS &cgns, const CellElementReturn &cellResults, const int &cellCount, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap, const std::map &apf2cgns, apf::GlobalNumbering *gvn) { const auto EdgeLoop = [&m](const auto &lambda, apf::MeshTag *edgeTag) { apf::MeshIterator *edgeIter = m->begin(1); @@ -545,6 +727,7 @@ void AddBocosToMainBase(const CGNS &cgns, const int &cellCount, apf::Mesh *m, co } m->end(vertIter); + // Annoying that the API requires this! std::vector allElements; globalElementList(bcList, allElements); @@ -606,26 +789,31 @@ void AddBocosToMainBase(const CGNS &cgns, const int &cellCount, apf::Mesh *m, co } }; - const auto doCellBC = [&](const auto &iter, const int &dim) { + const auto doCellBC = [&](const auto &iter, const int &) { for (const auto &p : iter->second) { std::vector bcList; - apf::MeshIterator *cellIter = m->begin(dim); - apf::MeshEntity *cell = nullptr; int vals[1]; vals[0] = -1; - while ((cell = m->iterate(cellIter))) + const auto &elements = std::get<0>(cellResults); + const auto &ranges = std::get<1>(cellResults); + + for (std::size_t e = 0; e < elements.size(); e++) { - m->getIntTag(cell, p.second, vals); - if (vals[0] == 1 && m->isOwned(cell)) + std::size_t counter = ranges[e].first; + for (const auto &elm : elements[e]) { - const auto n = apf::getNumber(gcn, cell, 0); - bcList.push_back(n + 1); // one-based + m->getIntTag(elm, p.second, vals); + if (vals[0] == 1 && m->isOwned(elm)) + { + bcList.push_back(counter); + } + counter++; } } - m->end(cellIter); + // Annoying that the API requires this! std::vector allElements; globalElementList(bcList, allElements); @@ -702,187 +890,6 @@ void AddBocosToMainBase(const CGNS &cgns, const int &cellCount, apf::Mesh *m, co } } -auto WriteVertices(const CGNS &cgns, apf::Mesh *m, apf::GlobalNumbering *gvn) -{ - int Cx = -1; - int Cy = -1; - int Cz = -1; - - if (cgns.phys_dim > 0) - { - if (cgp_coord_write(cgns.index, cgns.base, cgns.zone, CGNS_ENUMV(RealDouble), "CoordinateX", &Cx)) - cgp_error_exit(); - } - if (cgns.phys_dim > 1) - { - if (cgp_coord_write(cgns.index, cgns.base, cgns.zone, CGNS_ENUMV(RealDouble), "CoordinateY", &Cy)) - cgp_error_exit(); - } - if (cgns.phys_dim > 2) - { - if (cgp_coord_write(cgns.index, cgns.base, cgns.zone, CGNS_ENUMV(RealDouble), "CoordinateZ", &Cz)) - cgp_error_exit(); - } - - std::vector orderedVertices; - cgsize_t vertexMin[3]; - cgsize_t vertexMax[3]; - cgsize_t contigRange = -1; - { - std::array, 3> coords; - - vertexMin[0] = std::numeric_limits::max(); - vertexMax[0] = 0; - - apf::Vector3 point; - apf::MeshIterator *vertIter = m->begin(0); - apf::MeshEntity *vert = nullptr; - while ((vert = m->iterate(vertIter))) - { - if (m->isOwned(vert)) - { - const cgsize_t n = static_cast(apf::getNumber(gvn, vert, 0) + 1); // one based - if (contigRange == -1) - { - contigRange = n; - } - else - { - const auto predict = contigRange + 1; - - if (n != predict) - { - //std::cout << std::string("Range must be contigious for vertices ") + std::to_string(n) + " " + std::to_string(contigRange) << std::endl; - PCU_ALWAYS_ASSERT_VERBOSE(true == false, (std::string("Range must be contigious for vertices ") + std::to_string(n) + " " + std::to_string(contigRange)).c_str()); - } - else - contigRange = predict; // == n - } - - vertexMin[0] = std::min(vertexMin[0], n); - vertexMax[0] = std::max(vertexMax[0], n); - - m->getPoint(vert, 0, point); - coords[0].push_back(point[0]); - coords[1].push_back(point[1]); - coords[2].push_back(point[2]); - - orderedVertices.push_back(vert); - } - } - m->end(vertIter); - - // oddness of the api - vertexMin[1] = vertexMin[0]; - vertexMin[2] = vertexMin[0]; - vertexMax[1] = vertexMax[0]; - vertexMax[2] = vertexMax[0]; - - if (cgns.phys_dim > 0) - { - if (cgp_coord_write_data(cgns.index, cgns.base, cgns.zone, Cx, &vertexMin[0], &vertexMax[0], coords[0].data())) - cgp_error_exit(); - } - if (cgns.phys_dim > 1) - { - if (cgp_coord_write_data(cgns.index, cgns.base, cgns.zone, Cy, &vertexMin[0], &vertexMax[0], coords[1].data())) - cgp_error_exit(); - } - if (cgns.phys_dim > 2) - { - if (cgp_coord_write_data(cgns.index, cgns.base, cgns.zone, Cz, &vertexMin[0], &vertexMax[0], coords[2].data())) - cgp_error_exit(); - } - } - return std::make_tuple(orderedVertices, vertexMin[0], vertexMax[0]); -} - -auto WriteElements(const CGNS &cgns, apf::Mesh *m, apf::GlobalNumbering *gvn, const int cell_dim, const Count &cellCount, const std::vector &apfElementOrder, const std::vector &cgnsElementOrder) -{ - std::vector globalNumbersByElementType(apfElementOrder.size(), 0); - std::vector numbersByElementType(apfElementOrder.size(), 0); - for (std::size_t o = 0; o < apfElementOrder.size(); o++) - { - apf::MeshIterator *cellIter = m->begin(cell_dim); - apf::MeshEntity *cell = nullptr; - int counter = 0; - while ((cell = m->iterate(cellIter))) - { - if (m->getType(cell) == apfElementOrder[o] && m->isOwned(cell)) // must be same test as below - { - counter++; - } - } - m->end(cellIter); - numbersByElementType[o] = counter; - int total = counter; - PCU_Add_Ints(&total, 1); // size of total array - globalNumbersByElementType[o] = total; - } - cgsize_t allTotal = std::accumulate(globalNumbersByElementType.begin(), globalNumbersByElementType.end(), 0); - PCU_ALWAYS_ASSERT_VERBOSE(allTotal == cellCount.first, ("Must be equal " + std::to_string(allTotal) + " " + std::to_string(cellCount.first)).c_str()); - - int globalStart = 1; // one-based - std::vector> orderedElements(apfElementOrder.size()); - std::vector> ranges(apfElementOrder.size()); - for (std::size_t o = 0; o < apfElementOrder.size(); o++) - { - std::vector elementVertices; - apf::MeshIterator *cellIter = m->begin(cell_dim); - apf::MeshEntity *cell = nullptr; - apf::Downward verts; - - while ((cell = m->iterate(cellIter))) - { - if (m->getType(cell) == apfElementOrder[o] && m->isOwned(cell)) // must be same test as above - { - const auto numVerts = m->getDownward(cell, 0, verts); - for (int i = 0; i < numVerts; i++) - { - const auto n = apf::getNumber(gvn, verts[i], 0); - elementVertices.push_back(n + 1); // one-based - } - orderedElements[o].push_back(cell); - } - } - m->end(cellIter); - - if (globalNumbersByElementType[o] > 0) - { - const int globalEnd = globalStart + globalNumbersByElementType[o] - 1; // one-based stuff - // - int sectionNumber = -1; - const std::string name = std::string(cg_ElementTypeName(cgnsElementOrder[o])) + " " + std::to_string(globalStart) + "->" + std::to_string(globalEnd); - //std::cout << "Section Name " << name << std::endl; - if (cgp_section_write(cgns.index, cgns.base, cgns.zone, name.c_str(), cgnsElementOrder[o], globalStart, globalEnd, 0, §ionNumber)) // global start, end within the file for that element type - cgp_error_exit(); - - std::vector allNumbersForThisType(PCU_Comm_Peers(), 0); - MPI_Allgather(&numbersByElementType[o], 1, MPI_INT, allNumbersForThisType.data(), 1, - MPI_INT, PCU_Get_Comm()); - - cgsize_t num = 0; - for (int i = 0; i < PCU_Comm_Self(); i++) - num += allNumbersForThisType[i]; - - cgsize_t elStart = globalStart + num; - cgsize_t elEnd = elStart + numbersByElementType[o] - 1; // one-based stuff - if (cgp_elements_write_data(cgns.index, cgns.base, cgns.zone, sectionNumber, elStart, elEnd, // per processor within the range[start, end] - elementVertices.data())) - cgp_error_exit(); - - //std::cout << std::flush << "RANK: " << PCU_Comm_Self() << " ==> " << globalStart << " " << globalEnd << " elStart " << elStart << " elEnd " << elEnd << " numbersByElementType[o] " << numbersByElementType[o] << " of " << std::string(cg_ElementTypeName(cgnsElementOrder[o])) << std::flush << std::endl; - - globalStart += globalNumbersByElementType[o]; - - ranges[o] = std::make_pair(elStart, elEnd); - } - else - ranges[o] = std::make_pair(-1, -1); - } - return std::make_tuple(orderedElements, ranges); -} - // copy is deliberate void Write3DFaces(CGNS cgns, apf::Mesh *m, const Count &faceCount, const Count &vertexCount, apf::GlobalNumbering *gvn) { @@ -1099,7 +1106,7 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap apf2cgns.insert(std::make_pair(apf::Mesh::TRIANGLE, CGNS_ENUMV(TRI_3))); apf2cgns.insert(std::make_pair(apf::Mesh::EDGE, CGNS_ENUMV(BAR_2))); // - AddBocosToMainBase(cgns, cellCount.first, m, cgnsBCMap, apf2cgns, gvn, gcn); + AddBocosToMainBase(cgns, cellResult, cellCount.first, m, cgnsBCMap, apf2cgns, gvn); // WriteTags(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m); // From 4bbad48b51fb790b8e63b89fb44b0d6569ebd091 Mon Sep 17 00:00:00 2001 From: a-jp Date: Tue, 26 Nov 2019 15:02:43 +0000 Subject: [PATCH 52/72] small changes --- test/cgns.cc | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/test/cgns.cc b/test/cgns.cc index b403eee0f..799f42835 100644 --- a/test/cgns.cc +++ b/test/cgns.cc @@ -173,7 +173,7 @@ auto additional(const std::string &prefix, gmi_model *g, apf::Mesh2 *mesh) return clean; } -std::string doit(const std::string& argv1, const std::string& argv2, const bool& additionalTests) +std::string doit(const std::string &argv1, const std::string &argv2, const bool &additionalTests) { gmi_register_null(); gmi_register_mesh(); @@ -187,10 +187,10 @@ std::string doit(const std::string& argv1, const std::string& argv2, const bool& const std::string path = argv1.c_str(); const std::size_t found = path.find_last_of("/\\"); std::size_t index = found + 1; - if(found > path.size()) - index = 0; - - //std::cout << "FOUND " << found << " " << path.size() << " " << path << " " << index << std::endl; + if (found == std::string::npos) + index = 0; + + //std::cout << "FOUND " << found << " " << path.size() << " " << path << " " << index << std::endl; #ifndef NDEBUG // debug settings, cmake double negative.... const auto prefix = path.substr(index) + "_debug"; @@ -252,6 +252,29 @@ std::string doit(const std::string& argv1, const std::string& argv2, const bool& // if (additionalTests) { + // add dummy matrix to mesh + const auto addMatrix = [](apf::Mesh2 *mesh, const int &dim) { + apf::Field *field = nullptr; + const std::string name = "DummyMatrix_" + std::to_string(dim); + if (dim != 0) + field = apf::createField(mesh, name.c_str(), apf::MATRIX, apf::getConstant(dim)); + else if (dim == 0) + field = apf::createFieldOn(mesh, name.c_str(), apf::MATRIX); + //std::cout << "*************************** "<< dim << std::endl; + apf::MeshIterator *it = mesh->begin(dim); + apf::MeshEntity *elm = nullptr; + while ((elm = mesh->iterate(it))) + { + apf::Matrix3x3 m(11, 12, 13, 21, 22, 23, 31, 32, 33); + apf::setMatrix(field, elm, 0, m); + } + mesh->end(it); + //apf::destroyField(field); + }; + + for (int i = 0; i <= m->getDimension(); i++) + addMatrix(m, i); + // add dummy vector to mesh const auto addVector = [](apf::Mesh2 *mesh, const int &dim) { apf::Field *field = nullptr; @@ -269,7 +292,7 @@ std::string doit(const std::string& argv1, const std::string& argv2, const bool& v[0] = 1.0; v[1] = 2.0; v[2] = 3.0; - apf::setComponents(field, elm, 0, &v[0]); + apf::setVector(field, elm, 0, v); } mesh->end(it); //apf::destroyField(field); @@ -278,7 +301,7 @@ std::string doit(const std::string& argv1, const std::string& argv2, const bool& for (int i = 0; i <= m->getDimension(); i++) addVector(m, i); - // add dummy vector to mesh + // add dummy scalar to mesh const auto addScalar = [](apf::Mesh2 *mesh, const int &dim) { apf::Field *field = nullptr; const std::string name = "DummyScalar_" + std::to_string(dim); @@ -292,7 +315,7 @@ std::string doit(const std::string& argv1, const std::string& argv2, const bool& while ((elm = mesh->iterate(it))) { double v = 1.0; - apf::setComponents(field, elm, 0, &v); + apf::setScalar(field, elm, 0, v); } mesh->end(it); //apf::destroyField(field); From a813ba2fc1abc77cad636fb2e5a5238c16100199 Mon Sep 17 00:00:00 2001 From: a-jp Date: Tue, 3 Dec 2019 15:47:44 +0000 Subject: [PATCH 53/72] report name of tag that fails look up --- mds/apfMDS.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mds/apfMDS.cc b/mds/apfMDS.cc index 3e8dddd94..121027d43 100644 --- a/mds/apfMDS.cc +++ b/mds/apfMDS.cc @@ -410,7 +410,7 @@ class MeshMDS : public Mesh2 MeshTag* createIntTag(const char* name, int size) { mds_tag* tag; - PCU_ALWAYS_ASSERT(!mds_find_tag(&mesh->tags, name)); + PCU_ALWAYS_ASSERT_VERBOSE(!mds_find_tag(&mesh->tags, name), name); tag = mds_create_tag(&(mesh->tags),name, sizeof(int)*size, Mesh::INT); return reinterpret_cast(tag); From 8d9e09c63b4f10f2e760eb5159d06c3de332b7d9 Mon Sep 17 00:00:00 2001 From: a-jp Date: Tue, 3 Dec 2019 15:47:58 +0000 Subject: [PATCH 54/72] report name of field that fails look up --- apf/apf.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apf/apf.cc b/apf/apf.cc index ceefdf53f..bd7259483 100644 --- a/apf/apf.cc +++ b/apf/apf.cc @@ -69,7 +69,7 @@ Field* makeField( FieldShape* shape, FieldData* data) { - PCU_ALWAYS_ASSERT( ! m->findField(name)); + PCU_ALWAYS_ASSERT_VERBOSE( ! m->findField(name), name); Field* f = 0; if (valueType == SCALAR) f = new ScalarField(); From 6daff663d96e184ad9dd0ffb3f42af88fe712a37 Mon Sep 17 00:00:00 2001 From: a-jp Date: Tue, 3 Dec 2019 15:48:36 +0000 Subject: [PATCH 55/72] return newly built elements from assemble --- apf/apfConstruct.cc | 15 +++++++++------ apf/apfConvert.h | 5 +++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/apf/apfConstruct.cc b/apf/apfConstruct.cc index f0f3f9b65..8a96b2b00 100644 --- a/apf/apfConstruct.cc +++ b/apf/apfConstruct.cc @@ -20,19 +20,21 @@ static void constructVerts( result[conn[i]] = m->createVert_(interior); } -static void constructElements( +static NewElements constructElements( Mesh2* m, const Gid* conn, int nelem, int etype, GlobalToVert& globalToVert) { ModelEntity* interior = m->findModelEntity(m->getDimension(), 0); int nev = apf::Mesh::adjacentCount[etype][0]; + NewElements newElements; for (int i = 0; i < nelem; ++i) { Downward verts; int offset = i * nev; for (int j = 0; j < nev; ++j) verts[j] = globalToVert[conn[j + offset]]; - buildElement(m, interior, etype, verts); + newElements.push_back(buildElement(m, interior, etype, verts)); } + return newElements; } static Gid getMax(const GlobalToVert& globalToVert) @@ -144,11 +146,11 @@ static void constructRemotes(Mesh2* m, GlobalToVert& globalToVert) } } -void assemble(Mesh2* m, const int* conn, int nelem, int etype, +NewElements assemble(Mesh2* m, const int* conn, int nelem, int etype, GlobalToVert& globalToVert) { constructVerts(m, conn, nelem, etype, globalToVert); - constructElements(m, conn, nelem, etype, globalToVert); + return constructElements(m, conn, nelem, etype, globalToVert); } void finalise(Mesh2* m, GlobalToVert& globalToVert) @@ -159,11 +161,12 @@ void finalise(Mesh2* m, GlobalToVert& globalToVert) m->acceptChanges(); } -void construct(Mesh2* m, const int* conn, int nelem, int etype, +NewElements construct(Mesh2* m, const int* conn, int nelem, int etype, GlobalToVert& globalToVert) { - assemble(m, conn, nelem, etype, globalToVert); + const auto& newElements = assemble(m, conn, nelem, etype, globalToVert); finalise(m, globalToVert); + return newElements; } void setCoords(Mesh2* m, const double* coords, int nverts, diff --git a/apf/apfConvert.h b/apf/apfConvert.h index e5209522b..710d2048b 100644 --- a/apf/apfConvert.h +++ b/apf/apfConvert.h @@ -19,6 +19,7 @@ class Mesh; class Mesh2; class ModelEntity; class MeshEntity; +using NewElements = std::vector; /** \brief convert one mesh data structure to another \details this function will fill in a structure that fully @@ -36,7 +37,7 @@ typedef std::map GlobalToVert; assemble and finalise. The premise of assemble being that it is called multiple times for a given cell type, across several different cell types in the input mesh. */ -void assemble(Mesh2* m, const int* conn, int nelem, int etype, +NewElements assemble(Mesh2* m, const int* conn, int nelem, int etype, GlobalToVert& globalToVert); /** \brief finalise construction of a mixed-cell-type mesh from just a connectivity array @@ -63,7 +64,7 @@ void finalise(Mesh2* m, GlobalToVert& globalToVert); Note that all vertices will have zero coordinates, so it is often good to use apf::setCoords after this. */ -void construct(Mesh2* m, const int* conn, int nelem, int etype, +NewElements construct(Mesh2* m, const int* conn, int nelem, int etype, GlobalToVert& globalToVert); /** \brief Assign coordinates to the mesh From 08458a33d18fedad502bfe4599e55982f8111264 Mon Sep 17 00:00:00 2001 From: a-jp Date: Tue, 3 Dec 2019 15:49:35 +0000 Subject: [PATCH 56/72] disable but retain tag writer until odd field->tag naming problem resolved --- apf/apfCGNS.cc | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/apf/apfCGNS.cc b/apf/apfCGNS.cc index 86d283564..d2c91c148 100644 --- a/apf/apfCGNS.cc +++ b/apf/apfCGNS.cc @@ -57,6 +57,8 @@ struct CGNS const int phys_dim = 3; }; +/* +* Disable this until I find out why all tags get an _tet_ or _pyr_ fieldname, makes the output file super messy, and fields seem duplicated in tags void WriteTags(const CGNS &cgns, const std::vector> &orderedEnts, const std::vector> &ranges, const std::vector &orderedVertices, const int &vStart, const int &vEnd, apf::Mesh *m) { const auto loopVertexTags = [&m](const auto &orderedEnts, const int &solIndex, const auto &inner, const auto &post, const int &start, const int &end) { @@ -88,7 +90,7 @@ void WriteTags(const CGNS &cgns, const std::vector 1) - tagNameNew += "[" + std::to_string(ti) + "]"; + tagNameNew += "_[" + std::to_string(ti) + "]"; for (const auto &e : orderedEnts) { @@ -138,7 +140,7 @@ void WriteTags(const CGNS &cgns, const std::vector 1) - tagNameNew += "[" + std::to_string(ti) + "]"; + tagNameNew += "_[" + std::to_string(ti) + "]"; for (std::size_t e = 0; e < orderedEnts.size(); e++) { @@ -263,7 +265,7 @@ void WriteTags(const CGNS &cgns, const std::vector> &orderedEnts, const std::vector> &ranges, const std::vector &orderedVertices, const int &vStart, const int &vEnd, apf::Mesh *m) { const auto writeField = [&m, &cgns](apf::Field *f, const auto &orderedEnts, const int &solIndex, const auto &inner, const auto &post, const int &numComponents, const int &component, const std::string &fieldName, const int &start, const int &end, int &fieldIndex) { @@ -296,6 +298,7 @@ void WriteFields(const CGNS &cgns, const std::vector 1) - fieldNameNew += "[" + std::to_string(component) + "]"; + fieldNameNew += "_[" + std::to_string(component) + "]"; for (std::size_t e = 0; e < orderedEnts.size(); e++) { - //std::cout << fieldNameNew << " " << fieldName << " " << component << " " << numComponents << " " << e << std::endl; + //std::cout << "CELL " << fieldNameNew << " " << fieldName << " " << component << " " << numComponents << " " << e << std::endl; writeField(f, orderedEnts[e], solIndex, inner, post, numComponents, component, fieldNameNew, ranges[e].first, ranges[e].second, fieldIndex); } } @@ -343,8 +346,9 @@ void WriteFields(const CGNS &cgns, const std::vector 1) - fieldNameNew += "[" + std::to_string(component) + "]"; - //std::cout << fieldNameNew << " " << fieldName << " " << component << " " << numComponents << std::endl; + fieldNameNew += "_[" + std::to_string(component) + "]"; + + //std::cout << "VERTEX " << fieldNameNew << " " << fieldName << " " << component << " " << numComponents << std::endl; writeField(f, orderedEnts, solIndex, inner, post, numComponents, component, fieldNameNew, vStart, vEnd, fieldIndex); } } @@ -938,7 +942,7 @@ void Write3DFaces(CGNS cgns, apf::Mesh *m, const Count &faceCount, const Count & apf::numberOwnedDimension(m, "2D element-nums", 2)); synchronize(gcn); // - WriteTags(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m); + //WriteTags(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m); // WriteFields(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m); @@ -991,7 +995,7 @@ void Write2DEdges(CGNS cgns, apf::Mesh *m, const Count &edgeCount, const Count & apf::numberOwnedDimension(m, "1D element-nums", 1)); synchronize(gcn); // - WriteTags(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m); + //WriteTags(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m); // WriteFields(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m); @@ -1108,7 +1112,7 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap // AddBocosToMainBase(cgns, cellResult, cellCount.first, m, cgnsBCMap, apf2cgns, gvn); // - WriteTags(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m); + //WriteTags(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m); // WriteFields(cgns, std::get<0>(cellResult), std::get<1>(cellResult), std::get<0>(vertResult), std::get<1>(vertResult), std::get<2>(vertResult), m); // From 01cbd4a104c76de3e0edd9dac633b88b65d94136 Mon Sep 17 00:00:00 2001 From: a-jp Date: Tue, 3 Dec 2019 15:50:37 +0000 Subject: [PATCH 57/72] some tidy up, write vtk debug files after additional tests to compare with cgns. allow vector of field names to be provided to the reader --- mds/apfMDS.h | 3 +++ test/cgns.cc | 70 +++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 67 insertions(+), 6 deletions(-) diff --git a/mds/apfMDS.h b/mds/apfMDS.h index 9005b5161..fdd64f6fc 100644 --- a/mds/apfMDS.h +++ b/mds/apfMDS.h @@ -202,6 +202,9 @@ MeshEntity* getMdsEntity(Mesh2* in, int dimension, int index); using CGNSBCMap = std::map>>; Mesh2* loadMdsFromCGNS(gmi_model* g, const char* filename, CGNSBCMap& cgnsBCMap); +// names of mesh data to read from file: (VERTEX, VelocityX; CellCentre, Pressure) +Mesh2* loadMdsFromCGNS(gmi_model* g, const char* filename, CGNSBCMap& cgnsBCMap, const std::vector>& meshData); + Mesh2* loadMdsFromGmsh(gmi_model* g, const char* filename); Mesh2* loadMdsFromUgrid(gmi_model* g, const char* filename); diff --git a/test/cgns.cc b/test/cgns.cc index 799f42835..47a98b1d7 100644 --- a/test/cgns.cc +++ b/test/cgns.cc @@ -173,13 +173,13 @@ auto additional(const std::string &prefix, gmi_model *g, apf::Mesh2 *mesh) return clean; } -std::string doit(const std::string &argv1, const std::string &argv2, const bool &additionalTests) +std::string doit(const std::string &argv1, const std::string &argv2, const bool &additionalTests, const std::vector> &meshData) { gmi_register_null(); gmi_register_mesh(); gmi_model *g = gmi_load(".null"); apf::CGNSBCMap cgnsBCMap; - apf::Mesh2 *m = apf::loadMdsFromCGNS(g, argv1.c_str(), cgnsBCMap); + apf::Mesh2 *m = apf::loadMdsFromCGNS(g, argv1.c_str(), cgnsBCMap, meshData); m->verify(); // m->writeNative(argv2.c_str()); @@ -248,9 +248,12 @@ std::string doit(const std::string &argv1, const std::string &argv2, const bool // main purpose is to call additional tests through the test harness testing.cmake std::function cleanUp; if (additionalTests) + { cleanUp = additional(prefix, g, m); - // - if (additionalTests) + // + } + + if(additionalTests) { // add dummy matrix to mesh const auto addMatrix = [](apf::Mesh2 *mesh, const int &dim) { @@ -323,7 +326,54 @@ std::string doit(const std::string &argv1, const std::string &argv2, const bool for (int i = 0; i <= m->getDimension(); i++) addScalar(m, i); + + if (dim == 3) + { + { + const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK_cellMesh_additional"); + apf::writeVtkFiles(name.c_str(), m, 3); + } + { + const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK_faceMesh_additional"); + apf::writeVtkFiles(name.c_str(), m, 2); + } + { + const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK_edgeMesh_additional"); + apf::writeVtkFiles(name.c_str(), m, 1); + } + { + const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK_vertexMesh_additional"); + apf::writeVtkFiles(name.c_str(), m, 0); + } + } + else if (dim == 2) + { + { + const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK_cellMesh_additional"); + apf::writeVtkFiles(name.c_str(), m, 2); + } + { + const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK_edgeMesh_additional"); + apf::writeVtkFiles(name.c_str(), m, 1); + } + { + const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK_vertexMesh_additional"); + apf::writeVtkFiles(name.c_str(), m, 0); + } + } + else if (dim == 1) + { + { + const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK_cellMesh_additional"); + apf::writeVtkFiles(name.c_str(), m, 1); + } + { + const auto name = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + std::string("_toVTK_vertexMesh_additional"); + apf::writeVtkFiles(name.c_str(), m, 0); + } + } } + std::string cgnsOutputName = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + "_outputFile.cgns"; apf::writeCGNS(cgnsOutputName.c_str(), m, cgnsBCMap); // @@ -380,12 +430,20 @@ int main(int argc, char **argv) // Phase 1 std::string cgnsOutputName; { - cgnsOutputName = doit(argv[1], argv[2], additionalTests); + std::vector> meshData; + cgnsOutputName = doit(argv[1], argv[2], additionalTests, meshData); } // Phase 2 if (additionalTests) { - doit(cgnsOutputName.c_str(), "tempy.smb", false); + std::vector> meshData; + meshData.push_back(std::make_pair("Vertex", "DummyScalar_0")); + meshData.push_back(std::make_pair("Vertex", "DummyVector_0")); + meshData.push_back(std::make_pair("Vertex", "DummyMatrix_0")); + meshData.push_back(std::make_pair("CellCenter", "DummyScalar_3")); + meshData.push_back(std::make_pair("CellCenter", "DummyVector_3")); + meshData.push_back(std::make_pair("CellCenter", "DummyMatrix_3")); + doit(cgnsOutputName.c_str(), "tempy.smb", false, meshData); } // PCU_Comm_Free(); From 44a2b53248163034e9bf94d7a66230249491e6b7 Mon Sep 17 00:00:00 2001 From: a-jp Date: Tue, 3 Dec 2019 15:51:46 +0000 Subject: [PATCH 58/72] reading fields and recombining them: quite hard after all --- mds/mdsCGNS.cc | 549 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 524 insertions(+), 25 deletions(-) diff --git a/mds/mdsCGNS.cc b/mds/mdsCGNS.cc index ef027c893..cf96c9d85 100644 --- a/mds/mdsCGNS.cc +++ b/mds/mdsCGNS.cc @@ -13,6 +13,7 @@ #include #include #include +#include "apfFieldData.h" #include #include #include @@ -29,6 +30,7 @@ #include #include #include +#include #include #include // @@ -74,6 +76,124 @@ static std::string SupportedCGNSElementTypeToString(const CGNS_ENUMT(ElementType } } +struct MeshData +{ + MeshData(const int &s, const int &f, const CGNS_ENUMT(DataType_t) & dt, const CGNS_ENUMT(GridLocation_t) & l, const std::string &n) : si(s), fi(f), datatype(dt), location(l), name(n) + { + } + + int si = -1; + int fi = -1; + CGNS_ENUMT(DataType_t) + datatype; + CGNS_ENUMT(GridLocation_t) + location; + std::string name; + bool process = true; + + bool operator==(const MeshData &other) const + { + if (si != other.si) + return false; + + if (fi != other.fi) + return false; + + if (datatype != other.datatype) + return false; + + if (location != other.location) + return false; + + if (name != other.name) + return false; + + return true; + } + + bool operator!=(const MeshData &other) const + { + return !this->operator==(other); + } +}; + +struct MeshDataGroup +{ + std::map components; + bool process = true; + + CGNS_ENUMT(GridLocation_t) + location() const + { + return components.at(0).location; + } + + CGNS_ENUMT(DataType_t) + datatype() const + { + return components.at(0).datatype; + } + + std::string name() const + { + // pattern matching component writer in apfCGNS.cc, patterns must be kept in-sync with this file + const std::string end("_["); + const std::size_t found = components.at(0).name.find(end); + if (found != std::string::npos) + return components.at(0).name.substr(0, found); + else if (components.size() == 1) + return components.at(0).name; + else + { + info(); + PCU_ALWAYS_ASSERT_VERBOSE(true == false, "Problem with name"); + return ""; + } + } + + std::size_t size() const + { + return components.size(); + } + + int sIndex(const int index) const + { + return components.at(index).si; + } + + int fIndex(const int index) const + { + return components.at(index).fi; + } + + void insert(int i, MeshData &d) + { + components.insert(std::make_pair(i, d)); + } + + void info() const + { + if (components.size() == 1) + { + std::cout << "Scalar Group has " << components.size() << " related componenets: " << std::endl; + for (const auto m : components) + std::cout << "Field " << m.second.name << " @ " << m.second.si << " " << m.second.fi << std::endl; + } + else if (components.size() == 3) + { + std::cout << "Vector Group has " << components.size() << " related componenets: " << std::endl; + for (const auto m : components) + std::cout << "Field " << m.second.name << " @ " << m.second.si << " " << m.second.fi << std::endl; + } + else if (components.size() == 9) + { + std::cout << "Matrix Group has " << components.size() << " related componenets: " << std::endl; + for (const auto m : components) + std::cout << "Field " << m.second.name << " @ " << m.second.si << " " << m.second.fi << std::endl; + } + } +}; + template void DebugParallelPrinter(std::ostream &out, Arg &&arg, Args &&... args) { @@ -121,6 +241,8 @@ void Kill(const int fid, Args &&... args) void Kill(const int fid) { + DebugParallelPrinter(std::cout, "***** CGNS ERROR"); + if (PCU_Comm_Initialized()) { cgp_close(fid); @@ -142,8 +264,8 @@ auto ReadCGNSCoords(int cgid, int base, int zone, int ncoords, int nverts, const { // Read min required as defined by consecutive range // make one based as ReadElements makes zero based - const int lowest = globalToVert.begin()->first + 1; - const int highest = globalToVert.rbegin()->first + 1; + const cgsize_t lowest = globalToVert.begin()->first + 1; + const cgsize_t highest = globalToVert.rbegin()->first + 1; DebugParallelPrinter(std::cout, "From globalToVert ", lowest, highest, nverts); cgsize_t range_min[3]; @@ -156,7 +278,7 @@ auto ReadCGNSCoords(int cgid, int base, int zone, int ncoords, int nverts, const range_max[2] = highest; std::vector> ordinates(3); - const auto numToRead = range_max[0] - range_min[0] + 1; + const cgsize_t numToRead = range_max[0] - range_min[0] + 1; // one based ordinates[0].resize(numToRead, 0.0); ordinates[1].resize(numToRead, 0.0); ordinates[2].resize(numToRead, 0.0); @@ -188,12 +310,17 @@ auto ReadCGNSCoords(int cgid, int base, int zone, int ncoords, int nverts, const } } // to be clear, indices passed back are global, zero based + // should only return what's inside globalToVert, but above I have to read more.... std::map> points; int counter = lowest; for (int i = 0; i < numToRead; i++) { - int zeroBased = counter - 1; - points.insert(std::make_pair(zeroBased, std::array{{ordinates[0][i], ordinates[1][i], ordinates[2][i]}})); + int zeroBased = counter - 1; // remove as per the addition above + auto iter = globalToVert.find(zeroBased); + if (iter != globalToVert.end()) + { + points.insert(std::make_pair(zeroBased, std::array{{ordinates[0][i], ordinates[1][i], ordinates[2][i]}})); + } counter++; } @@ -254,7 +381,10 @@ void SimpleElementPartition(std::vector &numberToReadPerProc, std::vec DebugParallelPrinter(std::cout, "Returning from SimpleElementPartition \n"); } -auto ReadElements(int cgid, int base, int zone, int section, int el_start /* one based */, int el_end, int numElements, int verticesPerElement) +using Pair = std::pair; +using LocalElementRanges = std::vector; // one based + +auto ReadElements(int cgid, int base, int zone, int section, int el_start /* one based */, int el_end, int numElements, int verticesPerElement, LocalElementRanges &localElementRanges) { std::vector numberToReadPerProc; std::vector startingIndex; @@ -272,6 +402,11 @@ auto ReadElements(int cgid, int base, int zone, int section, int el_start /* one cgp_elements_read_data(cgid, base, zone, section, start, end, vertexIDs.data()); + if (numberToReadPerProc[PCU_Comm_Self()] > 0) + { + localElementRanges.push_back(std::make_pair(start, end)); + } + // remove CGNS one-based offset // to be clear these are the node ids defining the elements, not element ids for (auto &i : vertexIDs) @@ -452,7 +587,7 @@ struct BCInfo // for debug output, tags aren't written to vtk... apf::MeshEntity *elem = nullptr; apf::MeshIterator *it = m->begin(0); - auto* field = apf::createFieldOn(m, ("debug_" + tagName).c_str(), apf::SCALAR); + auto *field = apf::createFieldOn(m, ("debug_" + tagName).c_str(), apf::SCALAR); int vals[1]; double dval[1]; @@ -508,7 +643,7 @@ struct BCInfo // for debug output, tags aren't written to vtk... apf::MeshEntity *elem = nullptr; apf::MeshIterator *it = m->begin(1); - auto* field = apf::createField(m, ("debug_" + tagName).c_str(), apf::SCALAR, apf::getConstant(1)); + auto *field = apf::createField(m, ("debug_" + tagName).c_str(), apf::SCALAR, apf::getConstant(1)); int vals[1]; double dval[1]; @@ -564,7 +699,7 @@ struct BCInfo // for debug output, tags aren't written to vtk... apf::MeshEntity *elem = nullptr; apf::MeshIterator *it = m->begin(2); - auto* field = apf::createField(m, ("debug_" + tagName).c_str(), apf::SCALAR, apf::getConstant(2)); + auto *field = apf::createField(m, ("debug_" + tagName).c_str(), apf::SCALAR, apf::getConstant(2)); int vals[1]; double dval[1]; @@ -583,7 +718,7 @@ struct BCInfo const auto CellLoop = [&m](const std::string &tagName, apf::MeshTag *vertexTag, int dim) { apf::MeshTag *bcTag = nullptr; bcTag = m->createIntTag(tagName.c_str(), 1); // 1 is size of tag - + apf::MeshIterator *cellIter = m->begin(dim); apf::MeshEntity *cell = nullptr; int vals[1]; @@ -620,7 +755,7 @@ struct BCInfo // for debug output, tags aren't written to vtk... apf::MeshEntity *elem = nullptr; apf::MeshIterator *it = m->begin(dim); - auto* field = apf::createField(m, ("debug_" + tagName).c_str(), apf::SCALAR, apf::getConstant(dim)); + auto *field = apf::createField(m, ("debug_" + tagName).c_str(), apf::SCALAR, apf::getConstant(dim)); int vals[1]; double dval[1]; @@ -903,7 +1038,7 @@ void ReadBCInfo(const int cgid, const int base, const int zone, const int nBocos } } -apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCMap) +apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCMap, const std::vector> &readMeshData) { static_assert(std::is_same::value, "cgsize_t not compiled as int"); @@ -933,6 +1068,10 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM apf::Mesh2 *mesh = apf::makeEmptyMdsMesh(g, cellDim, false); apf::GlobalToVert globalToVert; + LocalElementRanges localElementRanges; + using NewElements = std::vector; + std::vector localElements; + int nzones = -1; cg_nzones(cgid, base, &nzones); basename = std::string(basename.c_str()); @@ -1007,13 +1146,11 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM cg_npe(elementType, &verticesPerElement); const auto readElementsAndVerts = [&](const apf::Mesh2::Type &type) { - const auto &ret = ReadElements(cgid, base, zone, section, el_start, el_end, numElements, verticesPerElement); + const auto &ret = ReadElements(cgid, base, zone, section, el_start, el_end, numElements, verticesPerElement, localElementRanges); if (std::get<1>(ret) > 0) { const std::vector vertexIDs = std::get<0>(ret); - //apf::construct(mesh, vertexIDs.data(), std::get<1>(ret), type, globalToVert); - apf::assemble(mesh, vertexIDs.data(), std::get<1>(ret), type, globalToVert); // corresponding finalize below - + localElements.emplace_back(apf::assemble(mesh, vertexIDs.data(), std::get<1>(ret), type, globalToVert)); // corresponding finalize below const auto nverts = sizes[0]; const auto ordinates = ReadCGNSCoords(cgid, base, zone, ncoords, nverts, vertexIDs, globalToVert); @@ -1021,15 +1158,18 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM { const auto pp = ordinates.at(p.first); apf::Vector3 point(pp[0], pp[1], pp[2]); - auto iter = globalToVert.find(p.first); - if (iter != globalToVert.end()) - { - mesh->setPoint(iter->second, 0, point); - } - else - { - Kill(cgid, "GlobalToVert lookup problem"); - } + mesh->setPoint(p.second, 0, point); + + // Don't know why I wrote it like this... + // auto iter = globalToVert.find(p.first); + // if (iter != globalToVert.end()) + // { + // mesh->setPoint(iter->second, 0, point); + // } + // else + // { + // Kill(cgid, "GlobalToVert lookup problem"); + // } } } }; @@ -1078,6 +1218,342 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM << " " << nBocos << std::endl; ReadBCInfo(cgid, base, zone, nBocos, physDim, cellDim, nsections, bcInfos, globalToVert); } + + int nsols = -1; + if (cg_nsols(cgid, base, zone, &nsols)) + Kill(cgid, "1, ", nsols); + + std::vector meshData; + if (nsols > 0) + { + for (int ns = 1; ns <= nsols; ns++) + { + CGNS_ENUMT(GridLocation_t) + location; + char sname[33]; + if (cg_sol_info(cgid, base, zone, ns, + sname, &location)) + Kill(cgid, "2"); + + int nflds = -1; + if (cg_nfields(cgid, base, zone, ns, &nflds)) + Kill(cgid, "3"); + + if (nflds > 0) + { + for (int f = 1; f <= nflds; f++) + { + CGNS_ENUMT(DataType_t) + datatype; + char name[33]; + if (cg_field_info(cgid, base, zone, ns, f, + &datatype, name)) + Kill(cgid, "4"); + + //std::cout << sname << " " << name << " " << f << " " << ns << " " << cg_DataTypeName(datatype) << " " << cg_GridLocationName(location) << std::endl; + meshData.push_back(MeshData(ns, f, datatype, location, name)); + } + } + } + } + + const auto index = [](const std::string &name) { + for (int i = 0; i < 9; i++) // check for vectors and matrices + { + // pattern matching component writer in apfCGNS.cc, patterns must be kept in-sync with this file + const std::string end("_[" + std::to_string(i) + "]"); + const std::size_t found = name.find(end); + if (found != std::string::npos) // does name contain a [x] where x[0,9) + { + return i; + } + } + return -1; + }; + + // process meshData and find vectors (and matrices) + const auto findMatch = [&meshData, &index, &cgid](MeshData &other, std::vector &meshDataGroups) { + MeshDataGroup group; + for (auto &md : meshData) + { + if (md != other) // don't compare with yourself + { + if (md.process) // make sure md has not be marked as a component already + { + if (md.name.size() == other.name.size()) + { + for (int i = 0; i < 9; i++) // check for vectors and matrices + { + // pattern matching component writer in apfCGNS.cc, patterns must be kept in-sync with this file + const std::string end("_[" + std::to_string(i) + "]"); + const std::size_t found = md.name.find(end); + if (found != std::string::npos) // does md contain a [x] where x[0,9) + { + const auto stub = md.name.substr(0, found); // get the part of the string not with a component index + const auto stubOther = other.name.substr(0, found); // get the part of the string not with a component index + + if (stub == stubOther) + { + if (md.location == other.location) // are at the same location in the mesh + { + if (md.datatype == other.datatype) // have same data type + { + md.process = false; + other.process = false; + const auto otherIndex = index(other.name); + if (otherIndex != -1) + group.insert(otherIndex, other); + else + Kill(cgid, "Bad fail"); + group.insert(i, md); + } + } + } + } + } + } + } + } + } + + if (group.size() > 0) + meshDataGroups.push_back(group); + }; + + // If a field or tag is already present, don't over-write or try to add + // Can modify this later for different behaviour, but useful default. + std::vector existingNames; + { + apf::DynamicArray tags; + mesh->getTags(tags); + for (std::size_t i = 0; i < tags.getSize(); ++i) + { + apf::MeshTag *t = tags[i]; + const std::string tagName(mesh->getTagName(t)); + existingNames.push_back(tagName); + } + for (int i = 0; i < mesh->countFields(); ++i) + { + apf::Field *f = mesh->getField(i); + const std::string fieldName(f->getName()); + existingNames.push_back(fieldName); + } + } + + for (auto &md : meshData) + { + if (md.process) + { + for (const auto &n : existingNames) + { + if (n == md.name) + md.process = false; + } + } + } + + std::vector meshDataGroups; + for (auto &md : meshData) + { + if (md.process) + findMatch(md, meshDataGroups); + } + + for (auto &md : meshData) + { + if (md.process) + { + MeshDataGroup group; + group.insert(0, md); + meshDataGroups.push_back(group); + md.process = false; + } + } + + for (auto &md : meshDataGroups) + { + if (md.process) + { + bool read = false; + for (const auto &n : readMeshData) + { + if (n.second == md.name()) + { + if (n.first == cg_GridLocationName(md.location())) + { + std::cout << md.name() << " " << n.first << " " << n.second << " " << cg_GridLocationName(md.location()) << std::endl; + read = true; + } + } + } + if (!read) + md.process = false; + } + } + + // add all double's as fields, even though they once may have been tags, since + // that info is lost in the cgns-writer (cos of cgns...) + for (const auto &md : meshDataGroups) + { + if (md.process) + { + if (md.location() == CGNS_ENUMV(Vertex)) + { + if (md.datatype() == CGNS_ENUMV(Integer)) + { + } + else if (md.datatype() == CGNS_ENUMV(RealDouble)) + { + const cgsize_t lowest = globalToVert.begin()->first + 1; // one based + const cgsize_t highest = globalToVert.rbegin()->first + 1; // one based + + cgsize_t range_min[3]; + range_min[0] = lowest; + range_min[1] = lowest; + range_min[2] = lowest; + cgsize_t range_max[3]; + range_max[0] = highest; + range_max[1] = highest; + range_max[2] = highest; + const cgsize_t numToRead = range_max[0] - range_min[0] + 1; // one based + + apf::Field *field = nullptr; + if (md.size() == 1) + field = apf::createFieldOn(mesh, md.name().c_str(), apf::SCALAR); + else if (md.size() == 3) + field = apf::createFieldOn(mesh, md.name().c_str(), apf::VECTOR); + else if (md.size() == 9) + field = apf::createFieldOn(mesh, md.name().c_str(), apf::MATRIX); + else + Kill(cgid, "Tensor size not accounted for"); + + apf::MeshEntity *elem = nullptr; + apf::MeshIterator *it = mesh->begin(0); + using Type = double; + std::vector compData(md.size(), Type(-123456)); + while ((elem = mesh->iterate(it))) + { + apf::setComponents(field, elem, 0, compData.data()); + } + mesh->end(it); + + using CGNSType = double; + std::vector meshVals(numToRead, -123456.0); + for (std::size_t i = 0; i < md.size(); i++) + { + if (cgp_field_read_data(cgid, base, zone, md.sIndex(i), md.fIndex(i), + &range_min[0], &range_max[0], meshVals.data())) + Kill(cgid, "Failed cgp_field_read_data"); + + cgsize_t counter = lowest; + for (cgsize_t it = 0; it < numToRead; it++) + { + cgsize_t zeroBased = counter - 1; // remove as per the addition above + auto iter = globalToVert.find(zeroBased); + if (iter != globalToVert.end()) + { + apf::getComponents(field, iter->second, 0, compData.data()); + compData.at(i) = meshVals.at(it); + apf::setComponents(field, iter->second, 0, compData.data()); + } + counter++; + } + } + } + else if (md.datatype() == CGNS_ENUMV(LongInteger)) + { + } + else + { + Kill(cgid, "Don't know how to process this at the moment"); + } + } + else if (md.location() == CGNS_ENUMV(CellCenter)) + { + if (md.datatype() == CGNS_ENUMV(Integer)) + { + } + else if (md.datatype() == CGNS_ENUMV(RealDouble)) + { + // HUGE assumption here, I assume the order the cgns elements are read (and therefore their global number in the file) + // is the same order they are created and added to the mesh by buildElements. + // I combine localElementRanges to give me the global indices, with vector and hope it works + PCU_ALWAYS_ASSERT_VERBOSE(localElementRanges.size() == localElements.size(), + "Size don't match for element/number ranges"); + + const auto dim = mesh->getDimension(); + apf::Field *field = nullptr; + md.info(); + if (md.size() == 1) + field = apf::createField(mesh, md.name().c_str(), apf::SCALAR, apf::getConstant(dim)); + else if (md.size() == 3) + field = apf::createField(mesh, md.name().c_str(), apf::VECTOR, apf::getConstant(dim)); + else if (md.size() == 9) + field = apf::createField(mesh, md.name().c_str(), apf::MATRIX, apf::getConstant(dim)); + else + Kill(cgid, "Tensor size not accounted for"); + + using Type = double; + std::vector compData(md.size(), Type(-123456)); + + for (std::size_t r = 0; r < localElementRanges.size(); r++) + { + const auto range = localElementRanges[r]; + const cgsize_t lowest = range.first; // one based + const cgsize_t highest = range.second; // one based + + cgsize_t range_min[3]; + range_min[0] = lowest; + range_min[1] = lowest; + range_min[2] = lowest; + cgsize_t range_max[3]; + range_max[0] = highest; + range_max[1] = highest; + range_max[2] = highest; + const std::size_t numToRead = range_max[0] - range_min[0] + 1; // one based + PCU_ALWAYS_ASSERT_VERBOSE(numToRead == localElements[r].size(), + "Size don't match for element/number sub-ranges"); + + apf::MeshEntity *elem = nullptr; + apf::MeshIterator *it = mesh->begin(dim); + while ((elem = mesh->iterate(it))) + { + apf::setComponents(field, elem, 0, compData.data()); + } + mesh->end(it); + + using CGNSType = double; + std::vector meshVals(numToRead, -123456.0); + for (std::size_t i = 0; i < md.size(); i++) + { + if (cgp_field_read_data(cgid, base, zone, md.sIndex(i), md.fIndex(i), + &range_min[0], &range_max[0], meshVals.data())) + Kill(cgid, "Failed cgp_field_read_data"); + + for (std::size_t it = 0; it < numToRead; it++) + { + elem = localElements[r][it]; + apf::getComponents(field, elem, 0, compData.data()); + compData.at(i) = meshVals.at(it); + apf::setComponents(field, elem, 0, compData.data()); + } + } + } + } + else if (md.datatype() == CGNS_ENUMV(LongInteger)) + { + } + else + { + Kill(cgid, "Don't know how to process this at the moment"); + } + } + else + { + Kill(cgid, "Don't know how to process this at the moment"); + } + } + } } apf::finalise(mesh, globalToVert); @@ -1085,6 +1561,7 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM apf::deriveMdsModel(mesh); mesh->acceptChanges(); apf::verify(mesh, true); + { apf::GlobalNumbering *gn = nullptr; gn = apf::makeGlobal(apf::numberOwnedNodes(mesh, "vert Idx")); @@ -1114,12 +1591,34 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM cg_close(cgid); return mesh; +} // namespace + +apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCMap) +{ + std::vector> meshData; + return DoIt(g, fname, cgnsBCMap, meshData); } + } // namespace namespace apf { +// caller needs to bring up and pull down mpi/pcu: mpi/pcu is required and assumed. +Mesh2 *loadMdsFromCGNS(gmi_model *g, const char *fname, apf::CGNSBCMap &cgnsBCMap, const std::vector> &meshData) +{ +#ifdef HAVE_CGNS + Mesh2 *m = DoIt(g, fname, cgnsBCMap, meshData); + return m; +#else + Mesh2 *m = nullptr; + PCU_ALWAYS_ASSERT_VERBOSE(m != nullptr, + "Build with ENABLE_CGNS to allow this functionality."); + exit(EXIT_FAILURE); + return m; +#endif +} + // caller needs to bring up and pull down mpi/pcu: mpi/pcu is required and assumed. Mesh2 *loadMdsFromCGNS(gmi_model *g, const char *fname, apf::CGNSBCMap &cgnsBCMap) { From f8bfdb65998c1510791ea160c9582063d2a8f757 Mon Sep 17 00:00:00 2001 From: a-jp Date: Wed, 4 Dec 2019 10:14:59 +0000 Subject: [PATCH 59/72] add mesh movement into additional tests --- test/cgns.cc | 54 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/test/cgns.cc b/test/cgns.cc index 47a98b1d7..a36bffe41 100644 --- a/test/cgns.cc +++ b/test/cgns.cc @@ -173,12 +173,11 @@ auto additional(const std::string &prefix, gmi_model *g, apf::Mesh2 *mesh) return clean; } -std::string doit(const std::string &argv1, const std::string &argv2, const bool &additionalTests, const std::vector> &meshData) +std::string doit(apf::CGNSBCMap &cgnsBCMap, const std::string &argv1, const std::string &argv2, const std::string& post, const bool &additionalTests, const bool &writeCGNS, const std::vector> &meshData) { gmi_register_null(); gmi_register_mesh(); gmi_model *g = gmi_load(".null"); - apf::CGNSBCMap cgnsBCMap; apf::Mesh2 *m = apf::loadMdsFromCGNS(g, argv1.c_str(), cgnsBCMap, meshData); m->verify(); // @@ -193,9 +192,9 @@ std::string doit(const std::string &argv1, const std::string &argv2, const bool //std::cout << "FOUND " << found << " " << path.size() << " " << path << " " << index << std::endl; #ifndef NDEBUG // debug settings, cmake double negative.... - const auto prefix = path.substr(index) + "_debug"; + const auto prefix = path.substr(index) + "_debug" + post; #else // optimised setting - const auto prefix = path.substr(index) + "_release"; + const auto prefix = path.substr(index) + "_release" + post; #endif const auto dim = m->getDimension(); @@ -245,6 +244,13 @@ std::string doit(const std::string &argv1, const std::string &argv2, const bool } } + std::string cgnsOutputName; + if (writeCGNS) + { + cgnsOutputName = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + "_outputFile.cgns"; + apf::writeCGNS(cgnsOutputName.c_str(), m, cgnsBCMap); + } + // main purpose is to call additional tests through the test harness testing.cmake std::function cleanUp; if (additionalTests) @@ -253,7 +259,7 @@ std::string doit(const std::string &argv1, const std::string &argv2, const bool // } - if(additionalTests) + if (additionalTests) { // add dummy matrix to mesh const auto addMatrix = [](apf::Mesh2 *mesh, const int &dim) { @@ -372,11 +378,37 @@ std::string doit(const std::string &argv1, const std::string &argv2, const bool apf::writeVtkFiles(name.c_str(), m, 0); } } + + if (writeCGNS) + { + std::string cgnsOutputName = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + "_additional_outputFile.cgns"; + apf::writeCGNS(cgnsOutputName.c_str(), m, cgnsBCMap); + } + // + { + apf::Field *field = nullptr; + const std::string name = "displace"; + field = field = apf::createFieldOn(m, name.c_str(), apf::VECTOR); + apf::MeshIterator *it = m->begin(0); + apf::MeshEntity *elm = nullptr; + while ((elm = m->iterate(it))) + { + apf::Vector3 v; + v[0] = 0.25; + v[1] = 0.25; + v[2] = 0.35; + apf::setVector(field, elm, 0, v); + } + m->end(it); + apf::displaceMesh(m, field); + if (writeCGNS) + { + std::string cgnsOutputName = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + "_additional_moved_outputFile.cgns"; + apf::writeCGNS(cgnsOutputName.c_str(), m, cgnsBCMap); + } + } } - std::string cgnsOutputName = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + "_outputFile.cgns"; - apf::writeCGNS(cgnsOutputName.c_str(), m, cgnsBCMap); - // if (additionalTests) { //cleanUp(); @@ -430,8 +462,9 @@ int main(int argc, char **argv) // Phase 1 std::string cgnsOutputName; { + apf::CGNSBCMap cgnsBCMap; std::vector> meshData; - cgnsOutputName = doit(argv[1], argv[2], additionalTests, meshData); + cgnsOutputName = doit(cgnsBCMap, argv[1], argv[2], "", additionalTests, additionalTests, meshData); } // Phase 2 if (additionalTests) @@ -443,7 +476,8 @@ int main(int argc, char **argv) meshData.push_back(std::make_pair("CellCenter", "DummyScalar_3")); meshData.push_back(std::make_pair("CellCenter", "DummyVector_3")); meshData.push_back(std::make_pair("CellCenter", "DummyMatrix_3")); - doit(cgnsOutputName.c_str(), "tempy.smb", false, meshData); + apf::CGNSBCMap cgnsBCMap; + doit(cgnsBCMap, cgnsOutputName.c_str(), "tempy.smb", "_reread", false, true, meshData); } // PCU_Comm_Free(); From a814e19cddb8522166cce21fd0e55f894275e34d Mon Sep 17 00:00:00 2001 From: a-jp Date: Mon, 9 Dec 2019 10:24:16 +0000 Subject: [PATCH 60/72] include new test for 3D --- test/testing.cmake | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/testing.cmake b/test/testing.cmake index 3f7db10d7..d59b4bc22 100644 --- a/test/testing.cmake +++ b/test/testing.cmake @@ -505,6 +505,12 @@ mpi_test(cgns_bcs_1 ${numProcs} "${CGNSDIR}/Mesh_3.adf.hdf.cgns" bcs1.smb additional) + +mpi_test(cgns_bcs_hex ${numProcs} + ./from_cgns + "${CGNSDIR}/8hexs.adf.hdf.cgns" + bcshex.smb + additional) # # 2D BCS tests # From eb44061d1c9cba31309f26053d61ba2af1ebb0ae Mon Sep 17 00:00:00 2001 From: a-jp Date: Mon, 9 Dec 2019 10:24:43 +0000 Subject: [PATCH 61/72] lots of bug fixes --- apf/apfCGNS.cc | 7 ++- mds/mdsCGNS.cc | 166 ++++++++++++++++++++++++++++++++++++++----------- test/cgns.cc | 85 +++++++++++++++++++++---- 3 files changed, 208 insertions(+), 50 deletions(-) diff --git a/apf/apfCGNS.cc b/apf/apfCGNS.cc index d2c91c148..adf29acdc 100644 --- a/apf/apfCGNS.cc +++ b/apf/apfCGNS.cc @@ -55,6 +55,7 @@ struct CGNS int base = -1; int zone = -1; const int phys_dim = 3; + std::string fname; }; /* @@ -325,7 +326,7 @@ void WriteFields(const CGNS &cgns, const std::vector 1) fieldNameNew += "_[" + std::to_string(component) + "]"; - + //std::cout << "VERTEX " << fieldNameNew << " " << fieldName << " " << component << " " << numComponents << std::endl; writeField(f, orderedEnts, solIndex, inner, post, numComponents, component, fieldNameNew, vStart, vEnd, fieldIndex); } @@ -366,6 +367,7 @@ void WriteFields(const CGNS &cgns, const std::vector *fieldData, std::vector &ddata, const int &numComponents, const int &component) { std::vector vals(numComponents, -12345); fieldData->get(elem, vals.data()); + //std::cout << numComponents << " " << component << " " << vals[0] << std::endl; ddata.push_back(vals[component]); }; @@ -1050,6 +1052,7 @@ void WriteCGNS(const char *prefix, apf::Mesh *m, const apf::CGNSBCMap &cgnsBCMap cgp_pio_mode(CGNS_ENUMV(CGP_INDEPENDENT)); CGNS cgns; + cgns.fname = std::string(prefix); if (cgp_open(prefix, CGNS_ENUMV(CG_MODE_WRITE), &cgns.index)) cgp_error_exit(); diff --git a/mds/mdsCGNS.cc b/mds/mdsCGNS.cc index cf96c9d85..77e9d4c26 100644 --- a/mds/mdsCGNS.cc +++ b/mds/mdsCGNS.cc @@ -505,12 +505,12 @@ struct BCInfo field = apf::createFieldOn(m, ("debug_fm_" + bcName).c_str(), apf::SCALAR); int vals[1]; - double dval[1]; + double dval; while ((elem = m->iterate(it))) { m->getIntTag(elem, tag, vals); - dval[0] = vals[0]; - apf::setComponents(field, elem, 0, dval); + dval = vals[0]; + apf::setScalar(field, elem, 0, dval); } m->end(it); } @@ -590,12 +590,12 @@ struct BCInfo auto *field = apf::createFieldOn(m, ("debug_" + tagName).c_str(), apf::SCALAR); int vals[1]; - double dval[1]; + double dval; while ((elem = m->iterate(it))) { m->getIntTag(elem, bcTag, vals); - dval[0] = vals[0]; - apf::setComponents(field, elem, 0, dval); + dval = vals[0]; + apf::setScalar(field, elem, 0, dval); } m->end(it); } @@ -646,12 +646,12 @@ struct BCInfo auto *field = apf::createField(m, ("debug_" + tagName).c_str(), apf::SCALAR, apf::getConstant(1)); int vals[1]; - double dval[1]; + double dval; while ((elem = m->iterate(it))) { m->getIntTag(elem, bcTag, vals); - dval[0] = vals[0]; - apf::setComponents(field, elem, 0, dval); + dval = vals[0]; + apf::setScalar(field, elem, 0, dval); } m->end(it); } @@ -702,12 +702,12 @@ struct BCInfo auto *field = apf::createField(m, ("debug_" + tagName).c_str(), apf::SCALAR, apf::getConstant(2)); int vals[1]; - double dval[1]; + double dval; while ((elem = m->iterate(it))) { m->getIntTag(elem, bcTag, vals); - dval[0] = vals[0]; - apf::setComponents(field, elem, 0, dval); + dval = vals[0]; + apf::setScalar(field, elem, 0, dval); } m->end(it); } @@ -758,12 +758,12 @@ struct BCInfo auto *field = apf::createField(m, ("debug_" + tagName).c_str(), apf::SCALAR, apf::getConstant(dim)); int vals[1]; - double dval[1]; + double dval; while ((elem = m->iterate(it))) { m->getIntTag(elem, bcTag, vals); - dval[0] = vals[0]; - apf::setComponents(field, elem, 0, dval); + dval = vals[0]; + apf::setScalar(field, elem, 0, dval); } m->end(it); } @@ -1214,9 +1214,11 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM if (nBocos > 0) { + std::cout << std::endl; std::cout << "Attempting to read BCS info " << " " << nBocos << std::endl; ReadBCInfo(cgid, base, zone, nBocos, physDim, cellDim, nsections, bcInfos, globalToVert); + std::cout << std::endl; } int nsols = -1; @@ -1427,13 +1429,22 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM else Kill(cgid, "Tensor size not accounted for"); + double scalar(-123456.0); + apf::Vector3 vector3(-123456.0, -123456.0, -123456.0); + apf::Matrix3x3 matrix3x3(-123456.0, -123456.0, -123456.0, -123456.0, -123456.0, -123456.0, -123456.0, -123456.0, -123456.0); + apf::MeshEntity *elem = nullptr; apf::MeshIterator *it = mesh->begin(0); - using Type = double; - std::vector compData(md.size(), Type(-123456)); while ((elem = mesh->iterate(it))) { - apf::setComponents(field, elem, 0, compData.data()); + if (md.size() == 1) + apf::setScalar(field, elem, 0, scalar); + else if (md.size() == 3) + apf::setVector(field, elem, 0, vector3); + else if (md.size() == 9) + apf::setMatrix(field, elem, 0, matrix3x3); + else + Kill(cgid, "Tensor size not accounted for"); } mesh->end(it); @@ -1452,9 +1463,28 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM auto iter = globalToVert.find(zeroBased); if (iter != globalToVert.end()) { - apf::getComponents(field, iter->second, 0, compData.data()); - compData.at(i) = meshVals.at(it); - apf::setComponents(field, iter->second, 0, compData.data()); + auto* elem = iter->second; + if (md.size() == 1) + { + apf::setScalar(field, elem, 0, meshVals.at(it)); + } + else if (md.size() == 3) + { + apf::getVector(field, elem, 0, vector3); + vector3[i] = meshVals.at(i); + apf::setVector(field, elem, 0, vector3); + } + else if (md.size() == 9) + { + apf::getMatrix(field, elem, 0, matrix3x3); + if (i < 3) + matrix3x3[0][i] = meshVals.at(it); + else if (i > 2 && i < 6) + matrix3x3[1][i - 3] = meshVals.at(it); + else if (i > 5 && i < 9) + matrix3x3[2][i - 6] = meshVals.at(it); + apf::setMatrix(field, elem, 0, matrix3x3); + } } counter++; } @@ -1492,9 +1522,25 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM field = apf::createField(mesh, md.name().c_str(), apf::MATRIX, apf::getConstant(dim)); else Kill(cgid, "Tensor size not accounted for"); - - using Type = double; - std::vector compData(md.size(), Type(-123456)); + + double scalar(-123456.0); + apf::Vector3 vector3(-123456.0, -123456.0, -123456.0); + apf::Matrix3x3 matrix3x3(-123456.0, -123456.0, -123456.0, -123456.0, -123456.0, -123456.0, -123456.0, -123456.0, -123456.0); + + apf::MeshEntity *elem = nullptr; + apf::MeshIterator *it = mesh->begin(dim); + while ((elem = mesh->iterate(it))) + { + if (md.size() == 1) + apf::setScalar(field, elem, 0, scalar); + else if (md.size() == 3) + apf::setVector(field, elem, 0, vector3); + else if (md.size() == 9) + apf::setMatrix(field, elem, 0, matrix3x3); + else + Kill(cgid, "Tensor size not accounted for"); + } + mesh->end(it); for (std::size_t r = 0; r < localElementRanges.size(); r++) { @@ -1514,14 +1560,6 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM PCU_ALWAYS_ASSERT_VERBOSE(numToRead == localElements[r].size(), "Size don't match for element/number sub-ranges"); - apf::MeshEntity *elem = nullptr; - apf::MeshIterator *it = mesh->begin(dim); - while ((elem = mesh->iterate(it))) - { - apf::setComponents(field, elem, 0, compData.data()); - } - mesh->end(it); - using CGNSType = double; std::vector meshVals(numToRead, -123456.0); for (std::size_t i = 0; i < md.size(); i++) @@ -1533,9 +1571,28 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM for (std::size_t it = 0; it < numToRead; it++) { elem = localElements[r][it]; - apf::getComponents(field, elem, 0, compData.data()); - compData.at(i) = meshVals.at(it); - apf::setComponents(field, elem, 0, compData.data()); + + if (md.size() == 1) + { + apf::setScalar(field, elem, 0, meshVals.at(it)); + } + else if (md.size() == 3) + { + apf::getVector(field, elem, 0, vector3); + vector3[i] = meshVals.at(i); + apf::setVector(field, elem, 0, vector3); + } + else if (md.size() == 9) + { + apf::getMatrix(field, elem, 0, matrix3x3); + if (i < 3) + matrix3x3[0][i] = meshVals.at(it); + else if (i > 2 && i < 6) + matrix3x3[1][i - 3] = meshVals.at(it); + else if (i > 5 && i < 9) + matrix3x3[2][i - 6] = meshVals.at(it); + apf::setMatrix(field, elem, 0, matrix3x3); + } } } } @@ -1556,6 +1613,45 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM } } + { + apf::MeshTag *tag = nullptr; + tag = mesh->createIntTag("origCGNSGlobalVertID", 1); // 1 is size of tag + const cgsize_t lowest = globalToVert.begin()->first + 1; // one based + const cgsize_t highest = globalToVert.rbegin()->first + 1; // one based + const cgsize_t numToRead = highest - lowest + 1; // one based + cgsize_t counter = lowest; + for (cgsize_t it = 0; it < numToRead; it++) + { + cgsize_t zeroBased = counter - 1; // remove as per the addition above + auto iter = globalToVert.find(zeroBased); + if (iter != globalToVert.end()) + { + const int oneBased = zeroBased + 1; + mesh->setIntTag(iter->second, tag, &oneBased); + } + counter++; + } + } + + { + apf::MeshTag *tag = nullptr; + tag = mesh->createIntTag("origCGNSGlobalElemID", 1); // 1 is size of tag + for (std::size_t r = 0; r < localElementRanges.size(); r++) + { + const auto range = localElementRanges[r]; + const cgsize_t lowest = range.first; // one based + const cgsize_t highest = range.second; // one based + const std::size_t numToRead = highest - lowest + 1; // one based + int counter = lowest; + for (std::size_t it = 0; it < numToRead; it++) + { + apf::MeshEntity *elem = nullptr; + elem = localElements[r][it]; + mesh->setIntTag(elem, tag, &counter); + counter++; + } + } + } apf::finalise(mesh, globalToVert); apf::alignMdsRemotes(mesh); apf::deriveMdsModel(mesh); diff --git a/test/cgns.cc b/test/cgns.cc index a36bffe41..cd4bd4175 100644 --- a/test/cgns.cc +++ b/test/cgns.cc @@ -46,9 +46,9 @@ apf::Field *convert_tag_doubleField(const std::string &name, apf::Mesh2 *m, apf: while ((elem = m->iterate(it))) { m->getIntTag(elem, t, vals); - double dval[1]; - dval[0] = vals[0]; - apf::setComponents(f, elem, 0, dval); + double dval; + dval = vals[0]; + apf::setScalar(f, elem, 0, dval); } m->end(it); return f; @@ -173,7 +173,7 @@ auto additional(const std::string &prefix, gmi_model *g, apf::Mesh2 *mesh) return clean; } -std::string doit(apf::CGNSBCMap &cgnsBCMap, const std::string &argv1, const std::string &argv2, const std::string& post, const bool &additionalTests, const bool &writeCGNS, const std::vector> &meshData) +std::string doit(apf::CGNSBCMap &cgnsBCMap, const std::string &argv1, const std::string &argv2, const std::string &post, const bool &additionalTests, const bool &writeCGNS, const std::vector> &meshData) { gmi_register_null(); gmi_register_mesh(); @@ -189,7 +189,7 @@ std::string doit(apf::CGNSBCMap &cgnsBCMap, const std::string &argv1, const std: if (found == std::string::npos) index = 0; - //std::cout << "FOUND " << found << " " << path.size() << " " << path << " " << index << std::endl; + //std::cout << "FOUND " << found << " " << path.size() << " " << path << " " << index << std::endl; #ifndef NDEBUG // debug settings, cmake double negative.... const auto prefix = path.substr(index) + "_debug" + post; @@ -265,16 +265,32 @@ std::string doit(apf::CGNSBCMap &cgnsBCMap, const std::string &argv1, const std: const auto addMatrix = [](apf::Mesh2 *mesh, const int &dim) { apf::Field *field = nullptr; const std::string name = "DummyMatrix_" + std::to_string(dim); + apf::MeshTag *tag = nullptr; if (dim != 0) + { field = apf::createField(mesh, name.c_str(), apf::MATRIX, apf::getConstant(dim)); + if (dim == mesh->getDimension()) + tag = mesh->findTag("origCGNSGlobalElemID"); + } else if (dim == 0) + { field = apf::createFieldOn(mesh, name.c_str(), apf::MATRIX); + tag = mesh->findTag("origCGNSGlobalVertID"); + } //std::cout << "*************************** "<< dim << std::endl; apf::MeshIterator *it = mesh->begin(dim); apf::MeshEntity *elm = nullptr; + int vals[1]; while ((elm = mesh->iterate(it))) { apf::Matrix3x3 m(11, 12, 13, 21, 22, 23, 31, 32, 33); + if (tag) + { + mesh->getIntTag(elm, tag, vals); + m[0][0] = vals[0]; + m[1][1] = -vals[0]; + m[2][2] = vals[0] * vals[0]; + } apf::setMatrix(field, elm, 0, m); } mesh->end(it); @@ -288,19 +304,39 @@ std::string doit(apf::CGNSBCMap &cgnsBCMap, const std::string &argv1, const std: const auto addVector = [](apf::Mesh2 *mesh, const int &dim) { apf::Field *field = nullptr; const std::string name = "DummyVector_" + std::to_string(dim); + apf::MeshTag *tag = nullptr; if (dim != 0) + { field = apf::createField(mesh, name.c_str(), apf::VECTOR, apf::getConstant(dim)); + if (dim == mesh->getDimension()) + tag = mesh->findTag("origCGNSGlobalElemID"); + } else if (dim == 0) + { field = apf::createFieldOn(mesh, name.c_str(), apf::VECTOR); + tag = mesh->findTag("origCGNSGlobalVertID"); + } //std::cout << "*************************** "<< dim << std::endl; apf::MeshIterator *it = mesh->begin(dim); apf::MeshEntity *elm = nullptr; + int vals[1]; while ((elm = mesh->iterate(it))) { apf::Vector3 v; - v[0] = 1.0; - v[1] = 2.0; - v[2] = 3.0; + if (tag) + { + mesh->getIntTag(elm, tag, vals); + v[0] = vals[0]; + v[1] = -vals[0]; + v[2] = vals[0] * vals[0]; + } + else + { + v[0] = 1.0; + v[1] = 2.0; + v[2] = 3.0; + } + apf::setVector(field, elm, 0, v); } mesh->end(it); @@ -314,16 +350,31 @@ std::string doit(apf::CGNSBCMap &cgnsBCMap, const std::string &argv1, const std: const auto addScalar = [](apf::Mesh2 *mesh, const int &dim) { apf::Field *field = nullptr; const std::string name = "DummyScalar_" + std::to_string(dim); + apf::MeshTag *tag = nullptr; if (dim != 0) + { field = apf::createField(mesh, name.c_str(), apf::SCALAR, apf::getConstant(dim)); + if (dim == mesh->getDimension()) + tag = mesh->findTag("origCGNSGlobalElemID"); + } else if (dim == 0) + { field = apf::createFieldOn(mesh, name.c_str(), apf::SCALAR); + tag = mesh->findTag("origCGNSGlobalVertID"); + } //std::cout << "*************************** "<< dim << std::endl; apf::MeshIterator *it = mesh->begin(dim); apf::MeshEntity *elm = nullptr; + int vals[1]; + vals[0] = -1234567; while ((elm = mesh->iterate(it))) { double v = 1.0; + if (tag) + { + mesh->getIntTag(elm, tag, vals); + v = double(vals[0]); + } apf::setScalar(field, elm, 0, v); } mesh->end(it); @@ -381,7 +432,8 @@ std::string doit(apf::CGNSBCMap &cgnsBCMap, const std::string &argv1, const std: if (writeCGNS) { - std::string cgnsOutputName = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + "_additional_outputFile.cgns"; + // what this one to be re-read if doing re-reading so that the dummy variables (vector/matrix/scalar) are there + cgnsOutputName = prefix + "_" + std::to_string(PCU_Comm_Peers()) + "procs" + "_additional_outputFile.cgns"; apf::writeCGNS(cgnsOutputName.c_str(), m, cgnsBCMap); } // @@ -471,12 +523,19 @@ int main(int argc, char **argv) { std::vector> meshData; meshData.push_back(std::make_pair("Vertex", "DummyScalar_0")); - meshData.push_back(std::make_pair("Vertex", "DummyVector_0")); - meshData.push_back(std::make_pair("Vertex", "DummyMatrix_0")); + // meshData.push_back(std::make_pair("Vertex", "DummyVector_0")); + // meshData.push_back(std::make_pair("Vertex", "DummyMatrix_0")); meshData.push_back(std::make_pair("CellCenter", "DummyScalar_3")); - meshData.push_back(std::make_pair("CellCenter", "DummyVector_3")); - meshData.push_back(std::make_pair("CellCenter", "DummyMatrix_3")); + // meshData.push_back(std::make_pair("CellCenter", "DummyVector_3")); + // meshData.push_back(std::make_pair("CellCenter", "DummyMatrix_3")); + // meshData.push_back(std::make_pair("CellCenter", "DummyScalar_2")); + // meshData.push_back(std::make_pair("CellCenter", "DummyVector_2")); + // meshData.push_back(std::make_pair("CellCenter", "DummyMatrix_2")); + // meshData.push_back(std::make_pair("CellCenter", "DummyScalar_1")); + // meshData.push_back(std::make_pair("CellCenter", "DummyVector_1")); + // meshData.push_back(std::make_pair("CellCenter", "DummyMatrix_1")); apf::CGNSBCMap cgnsBCMap; + std::cout << "RE-READING " << std::endl; doit(cgnsBCMap, cgnsOutputName.c_str(), "tempy.smb", "_reread", false, true, meshData); } // From 7be80759afd2965f5839679eff3dd9193b895f72 Mon Sep 17 00:00:00 2001 From: a-jp Date: Mon, 9 Dec 2019 10:29:04 +0000 Subject: [PATCH 62/72] re-enable reading of test fields --- test/cgns.cc | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/test/cgns.cc b/test/cgns.cc index cd4bd4175..1a531b865 100644 --- a/test/cgns.cc +++ b/test/cgns.cc @@ -523,17 +523,20 @@ int main(int argc, char **argv) { std::vector> meshData; meshData.push_back(std::make_pair("Vertex", "DummyScalar_0")); - // meshData.push_back(std::make_pair("Vertex", "DummyVector_0")); - // meshData.push_back(std::make_pair("Vertex", "DummyMatrix_0")); + meshData.push_back(std::make_pair("Vertex", "DummyVector_0")); + meshData.push_back(std::make_pair("Vertex", "DummyMatrix_0")); + meshData.push_back(std::make_pair("CellCenter", "DummyScalar_3")); - // meshData.push_back(std::make_pair("CellCenter", "DummyVector_3")); - // meshData.push_back(std::make_pair("CellCenter", "DummyMatrix_3")); - // meshData.push_back(std::make_pair("CellCenter", "DummyScalar_2")); - // meshData.push_back(std::make_pair("CellCenter", "DummyVector_2")); - // meshData.push_back(std::make_pair("CellCenter", "DummyMatrix_2")); - // meshData.push_back(std::make_pair("CellCenter", "DummyScalar_1")); - // meshData.push_back(std::make_pair("CellCenter", "DummyVector_1")); - // meshData.push_back(std::make_pair("CellCenter", "DummyMatrix_1")); + meshData.push_back(std::make_pair("CellCenter", "DummyVector_3")); + meshData.push_back(std::make_pair("CellCenter", "DummyMatrix_3")); + + meshData.push_back(std::make_pair("CellCenter", "DummyScalar_2")); + meshData.push_back(std::make_pair("CellCenter", "DummyVector_2")); + meshData.push_back(std::make_pair("CellCenter", "DummyMatrix_2")); + + meshData.push_back(std::make_pair("CellCenter", "DummyScalar_1")); + meshData.push_back(std::make_pair("CellCenter", "DummyVector_1")); + meshData.push_back(std::make_pair("CellCenter", "DummyMatrix_1")); apf::CGNSBCMap cgnsBCMap; std::cout << "RE-READING " << std::endl; doit(cgnsBCMap, cgnsOutputName.c_str(), "tempy.smb", "_reread", false, true, meshData); From e7f5a7411a8cf5c06df1fd42fb28fbb3939abfde Mon Sep 17 00:00:00 2001 From: a-jp Date: Mon, 13 Jan 2020 14:58:45 +0000 Subject: [PATCH 63/72] bug fix to index for vector and matrix reading --- apf/apfCGNS.cc | 2 ++ mds/mdsCGNS.cc | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/apf/apfCGNS.cc b/apf/apfCGNS.cc index adf29acdc..903cb2d27 100644 --- a/apf/apfCGNS.cc +++ b/apf/apfCGNS.cc @@ -37,6 +37,8 @@ // #endif +// Note: currently, even in 2D or 1D a full 3D vector and matrix are written out to the file + namespace { //https://proteustoolkit.org/capi/html/_parallel_mesh_converter_8cpp_source.html diff --git a/mds/mdsCGNS.cc b/mds/mdsCGNS.cc index 77e9d4c26..313a378ae 100644 --- a/mds/mdsCGNS.cc +++ b/mds/mdsCGNS.cc @@ -191,6 +191,11 @@ struct MeshDataGroup for (const auto m : components) std::cout << "Field " << m.second.name << " @ " << m.second.si << " " << m.second.fi << std::endl; } + else + { + PCU_ALWAYS_ASSERT_VERBOSE(true == false, "Tensor not accounted for"); + } + } }; @@ -1471,7 +1476,7 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM else if (md.size() == 3) { apf::getVector(field, elem, 0, vector3); - vector3[i] = meshVals.at(i); + vector3[i] = meshVals.at(it); apf::setVector(field, elem, 0, vector3); } else if (md.size() == 9) @@ -1485,6 +1490,8 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM matrix3x3[2][i - 6] = meshVals.at(it); apf::setMatrix(field, elem, 0, matrix3x3); } + else + Kill(cgid, "Tensor size not accounted for"); } counter++; } @@ -1579,7 +1586,7 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM else if (md.size() == 3) { apf::getVector(field, elem, 0, vector3); - vector3[i] = meshVals.at(i); + vector3[i] = meshVals.at(it); apf::setVector(field, elem, 0, vector3); } else if (md.size() == 9) @@ -1593,6 +1600,11 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM matrix3x3[2][i - 6] = meshVals.at(it); apf::setMatrix(field, elem, 0, matrix3x3); } + else + { + Kill(cgid, "Tensor size not accounted for"); + } + } } } From 5bd13027aa89c73522e71358adbca0ceaa78fdd0 Mon Sep 17 00:00:00 2001 From: a-jp Date: Mon, 13 Jan 2020 16:47:41 +0000 Subject: [PATCH 64/72] switch pair for tuple inside CGNSBCMap in prep for adding additional info about model classify id --- apf/apf.h | 4 ++-- apf/apfCGNS.cc | 18 +++++++++--------- mds/apfMDS.h | 4 ++-- mds/mdsCGNS.cc | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/apf/apf.h b/apf/apf.h index 85a9cd9eb..76191e85a 100644 --- a/apf/apf.h +++ b/apf/apf.h @@ -638,14 +638,14 @@ for (t::const_iterator i = (w).begin(); \ * to stop this type being defined twice in two includes... // Key [String] = Vertex/EdgeCenter/FaceCenter/CellCenter -// Value [vector of Pairs per Key]; Pairs = cgns_bc_name, tag value. +// Value [vector of Tuples per Key]; Tuple = cgns_bc_name, tag value. // Tag value holds [0, 1] as a // marker to indicate mesh_entities // within bc group. 1="in group", 0="not in group" // Tags set on vertices, edges, faces, and cells */ -using CGNSBCMap = std::map>>; +using CGNSBCMap = std::map>>; void writeCGNS(const char *prefix, Mesh *m, const CGNSBCMap &cgnsBCMap); /** \brief Write a set of parallel VTK Unstructured Mesh files from an apf::Mesh diff --git a/apf/apfCGNS.cc b/apf/apfCGNS.cc index 903cb2d27..b7b1064fe 100644 --- a/apf/apfCGNS.cc +++ b/apf/apfCGNS.cc @@ -626,7 +626,7 @@ void AddBocosToMainBase(const CGNS &cgns, const CellElementReturn &cellResults, } }; // - Looper(lambda, bcGroup.second); + Looper(lambda, std::get<1>(bcGroup)); // const int cacheStart = startingLocation + 1; int cacheEnd = -1; @@ -640,8 +640,8 @@ void AddBocosToMainBase(const CGNS &cgns, const CellElementReturn &cellResults, { const auto allEnd = startOfBCBlock + total - 1; //one-based int sectionNumber = -1; - const std::string name = bcGroup.first + " " + std::to_string(startOfBCBlock) + "->" + std::to_string(allEnd); //cg_ElementTypeName(apf2cgns[bc.first]); - if (cgp_section_write(cgns.index, cgns.base, cgns.zone, name.c_str(), apf2cgns.at(bc.first), startOfBCBlock, allEnd, 0, + const std::string name = std::get<0>(bcGroup) + " " + std::to_string(startOfBCBlock) + "->" + std::to_string(allEnd); //cg_ElementTypeName(apf2cgns[bc.first]); + if (cgp_section_write(cgns.index, cgns.base, cgns.zone, name.c_str(), apf2cgns.at(std::get<0>(bc)), startOfBCBlock, allEnd, 0, §ionNumber)) cgp_error_exit(); @@ -726,7 +726,7 @@ void AddBocosToMainBase(const CGNS &cgns, const CellElementReturn &cellResults, while ((vert = m->iterate(vertIter))) { - m->getIntTag(vert, p.second, vals); + m->getIntTag(vert, std::get<1>(p), vals); if (vals[0] == 1 && m->isOwned(vert)) { const auto n = apf::getNumber(gvn, vert, 0); @@ -740,7 +740,7 @@ void AddBocosToMainBase(const CGNS &cgns, const CellElementReturn &cellResults, globalElementList(bcList, allElements); int bcIndex = -1; - if (cg_boco_write(cgns.index, cgns.base, cgns.zone, p.first.c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointList), allElements.size(), + if (cg_boco_write(cgns.index, cgns.base, cgns.zone, std::get<0>(p).c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointList), allElements.size(), allElements.data(), &bcIndex)) cg_error_exit(); @@ -763,7 +763,7 @@ void AddBocosToMainBase(const CGNS &cgns, const CellElementReturn &cellResults, const std::array bcRange = {{se.first[0], se.second[0]}}; int bcIndex = -1; - if (cg_boco_write(cgns.index, cgns.base, cgns.zone, p.first.c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointRange), 2, + if (cg_boco_write(cgns.index, cgns.base, cgns.zone, std::get<0>(p).c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointRange), 2, bcRange.data(), &bcIndex)) cg_error_exit(); @@ -786,7 +786,7 @@ void AddBocosToMainBase(const CGNS &cgns, const CellElementReturn &cellResults, } const std::array bcRange = {{se.first[0], se.second[0]}}; int bcIndex = -1; - if (cg_boco_write(cgns.index, cgns.base, cgns.zone, p.first.c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointRange), 2, + if (cg_boco_write(cgns.index, cgns.base, cgns.zone, std::get<0>(p).c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointRange), 2, bcRange.data(), &bcIndex)) cg_error_exit(); @@ -812,7 +812,7 @@ void AddBocosToMainBase(const CGNS &cgns, const CellElementReturn &cellResults, std::size_t counter = ranges[e].first; for (const auto &elm : elements[e]) { - m->getIntTag(elm, p.second, vals); + m->getIntTag(elm, std::get<1>(p), vals); if (vals[0] == 1 && m->isOwned(elm)) { bcList.push_back(counter); @@ -826,7 +826,7 @@ void AddBocosToMainBase(const CGNS &cgns, const CellElementReturn &cellResults, globalElementList(bcList, allElements); int bcIndex = -1; - if (cg_boco_write(cgns.index, cgns.base, cgns.zone, p.first.c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointList), allElements.size(), + if (cg_boco_write(cgns.index, cgns.base, cgns.zone, std::get<0>(p).c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointList), allElements.size(), allElements.data(), &bcIndex)) cg_error_exit(); diff --git a/mds/apfMDS.h b/mds/apfMDS.h index fdd64f6fc..086fb4d5b 100644 --- a/mds/apfMDS.h +++ b/mds/apfMDS.h @@ -194,12 +194,12 @@ int getMdsIndex(Mesh2* in, MeshEntity* e); MeshEntity* getMdsEntity(Mesh2* in, int dimension, int index); // Key [String] = Vertex/EdgeCenter/FaceCenter/CellCenter -// Value [vector of Pairs per Key]; Pairs = cgns_bc_name, tag value. +// Value [vector of Tuples per Key]; Tuple = cgns_bc_name, tag value. // Tag value holds [0, 1] as a // marker to indicate mesh_entities // within bc group. 1="in group", 0="not in group" // Tags set on vertices, edges, faces, and cells -using CGNSBCMap = std::map>>; +using CGNSBCMap = std::map>>; Mesh2* loadMdsFromCGNS(gmi_model* g, const char* filename, CGNSBCMap& cgnsBCMap); // names of mesh data to read from file: (VERTEX, VelocityX; CellCentre, Pressure) diff --git a/mds/mdsCGNS.cc b/mds/mdsCGNS.cc index 313a378ae..8819d0f93 100644 --- a/mds/mdsCGNS.cc +++ b/mds/mdsCGNS.cc @@ -550,8 +550,8 @@ struct BCInfo } else { - std::vector> pair; - pair.push_back(std::make_pair(tagName, field)); + std::vector> pair; + pair.push_back(std::make_tuple(tagName, field)); cgnsBCMap.insert(std::make_pair(location, pair)); } }; From f41a750fa5507e34da6fc02a3188905bcdca8686 Mon Sep 17 00:00:00 2001 From: a-jp Date: Tue, 14 Jan 2020 17:04:25 +0000 Subject: [PATCH 65/72] move from tuple to struct --- apf/apf.h | 35 ++++++++++++++++++++--------------- apf/apfCGNS.cc | 16 ++++++++-------- mds/apfMDS.h | 14 ++++++-------- mds/mdsCGNS.cc | 24 ++++++++++++++---------- 4 files changed, 48 insertions(+), 41 deletions(-) diff --git a/apf/apf.h b/apf/apf.h index 76191e85a..d036d1a1f 100644 --- a/apf/apf.h +++ b/apf/apf.h @@ -631,21 +631,26 @@ for (t::iterator i = (w).begin(); \ for (t::const_iterator i = (w).begin(); \ (i) != (w).end(); ++(i)) -/** \brief Write a CGNS file - * - * CGNSBCMap type is already defined in apfMDS.h. - * Would be better if there were a base include that this and apfMDS.h could include - * to stop this type being defined twice in two includes... - -// Key [String] = Vertex/EdgeCenter/FaceCenter/CellCenter -// Value [vector of Tuples per Key]; Tuple = cgns_bc_name, tag value. -// Tag value holds [0, 1] as a -// marker to indicate mesh_entities -// within bc group. 1="in group", 0="not in group" -// Tags set on vertices, edges, faces, and cells - -*/ -using CGNSBCMap = std::map>>; +struct CGNSInfo +{ + // cgns_bc_name + std::string cgnsBCSName; + /* tag value + + Tag value holds [0, 1] as a + marker to indicate mesh_entities + within bc group. 1="in group", 0="not in group" + Tags set on vertices, edges, faces, and cells + */ + apf::MeshTag* bcsMarkerTag = nullptr; + // model dimension + int mdlDim = -1; + // model id + int mdlId = -1; +}; + +//using CGNSBCMap = std::map>>; +using CGNSBCMap = std::map>; void writeCGNS(const char *prefix, Mesh *m, const CGNSBCMap &cgnsBCMap); /** \brief Write a set of parallel VTK Unstructured Mesh files from an apf::Mesh diff --git a/apf/apfCGNS.cc b/apf/apfCGNS.cc index b7b1064fe..4debbb58b 100644 --- a/apf/apfCGNS.cc +++ b/apf/apfCGNS.cc @@ -626,7 +626,7 @@ void AddBocosToMainBase(const CGNS &cgns, const CellElementReturn &cellResults, } }; // - Looper(lambda, std::get<1>(bcGroup)); + Looper(lambda, bcGroup.bcsMarkerTag); // const int cacheStart = startingLocation + 1; int cacheEnd = -1; @@ -640,7 +640,7 @@ void AddBocosToMainBase(const CGNS &cgns, const CellElementReturn &cellResults, { const auto allEnd = startOfBCBlock + total - 1; //one-based int sectionNumber = -1; - const std::string name = std::get<0>(bcGroup) + " " + std::to_string(startOfBCBlock) + "->" + std::to_string(allEnd); //cg_ElementTypeName(apf2cgns[bc.first]); + const std::string name = bcGroup.cgnsBCSName + " " + std::to_string(startOfBCBlock) + "->" + std::to_string(allEnd); //cg_ElementTypeName(apf2cgns[bc.first]); if (cgp_section_write(cgns.index, cgns.base, cgns.zone, name.c_str(), apf2cgns.at(std::get<0>(bc)), startOfBCBlock, allEnd, 0, §ionNumber)) cgp_error_exit(); @@ -726,7 +726,7 @@ void AddBocosToMainBase(const CGNS &cgns, const CellElementReturn &cellResults, while ((vert = m->iterate(vertIter))) { - m->getIntTag(vert, std::get<1>(p), vals); + m->getIntTag(vert, p.bcsMarkerTag, vals); if (vals[0] == 1 && m->isOwned(vert)) { const auto n = apf::getNumber(gvn, vert, 0); @@ -740,7 +740,7 @@ void AddBocosToMainBase(const CGNS &cgns, const CellElementReturn &cellResults, globalElementList(bcList, allElements); int bcIndex = -1; - if (cg_boco_write(cgns.index, cgns.base, cgns.zone, std::get<0>(p).c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointList), allElements.size(), + if (cg_boco_write(cgns.index, cgns.base, cgns.zone, p.cgnsBCSName.c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointList), allElements.size(), allElements.data(), &bcIndex)) cg_error_exit(); @@ -763,7 +763,7 @@ void AddBocosToMainBase(const CGNS &cgns, const CellElementReturn &cellResults, const std::array bcRange = {{se.first[0], se.second[0]}}; int bcIndex = -1; - if (cg_boco_write(cgns.index, cgns.base, cgns.zone, std::get<0>(p).c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointRange), 2, + if (cg_boco_write(cgns.index, cgns.base, cgns.zone, p.cgnsBCSName.c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointRange), 2, bcRange.data(), &bcIndex)) cg_error_exit(); @@ -786,7 +786,7 @@ void AddBocosToMainBase(const CGNS &cgns, const CellElementReturn &cellResults, } const std::array bcRange = {{se.first[0], se.second[0]}}; int bcIndex = -1; - if (cg_boco_write(cgns.index, cgns.base, cgns.zone, std::get<0>(p).c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointRange), 2, + if (cg_boco_write(cgns.index, cgns.base, cgns.zone, p.cgnsBCSName.c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointRange), 2, bcRange.data(), &bcIndex)) cg_error_exit(); @@ -812,7 +812,7 @@ void AddBocosToMainBase(const CGNS &cgns, const CellElementReturn &cellResults, std::size_t counter = ranges[e].first; for (const auto &elm : elements[e]) { - m->getIntTag(elm, std::get<1>(p), vals); + m->getIntTag(elm, p.bcsMarkerTag, vals); if (vals[0] == 1 && m->isOwned(elm)) { bcList.push_back(counter); @@ -826,7 +826,7 @@ void AddBocosToMainBase(const CGNS &cgns, const CellElementReturn &cellResults, globalElementList(bcList, allElements); int bcIndex = -1; - if (cg_boco_write(cgns.index, cgns.base, cgns.zone, std::get<0>(p).c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointList), allElements.size(), + if (cg_boco_write(cgns.index, cgns.base, cgns.zone, p.cgnsBCSName.c_str(), CGNS_ENUMV(BCGeneral), CGNS_ENUMV(PointList), allElements.size(), allElements.data(), &bcIndex)) cg_error_exit(); diff --git a/mds/apfMDS.h b/mds/apfMDS.h index 086fb4d5b..8ff0c4ce3 100644 --- a/mds/apfMDS.h +++ b/mds/apfMDS.h @@ -31,7 +31,12 @@ \brief Interface to the compact Mesh Data Structure */ #include - +// +// AJP: for single define CGNSBCMap +// AJP: alternative is to allow common cgns base header +// but trying to avoid that since it's not core functionality +#include +// struct gmi_model; namespace apf { @@ -193,13 +198,6 @@ int getMdsIndex(Mesh2* in, MeshEntity* e); so call apf::reorderMdsMesh after any mesh modification. */ MeshEntity* getMdsEntity(Mesh2* in, int dimension, int index); -// Key [String] = Vertex/EdgeCenter/FaceCenter/CellCenter -// Value [vector of Tuples per Key]; Tuple = cgns_bc_name, tag value. -// Tag value holds [0, 1] as a -// marker to indicate mesh_entities -// within bc group. 1="in group", 0="not in group" -// Tags set on vertices, edges, faces, and cells -using CGNSBCMap = std::map>>; Mesh2* loadMdsFromCGNS(gmi_model* g, const char* filename, CGNSBCMap& cgnsBCMap); // names of mesh data to read from file: (VERTEX, VelocityX; CellCentre, Pressure) diff --git a/mds/mdsCGNS.cc b/mds/mdsCGNS.cc index 8819d0f93..9d5d26f44 100644 --- a/mds/mdsCGNS.cc +++ b/mds/mdsCGNS.cc @@ -193,9 +193,8 @@ struct MeshDataGroup } else { - PCU_ALWAYS_ASSERT_VERBOSE(true == false, "Tensor not accounted for"); + PCU_ALWAYS_ASSERT_VERBOSE(true == false, "Tensor not accounted for"); } - } }; @@ -546,13 +545,19 @@ struct BCInfo auto iter = cgnsBCMap.find(location); if (iter != cgnsBCMap.end()) { - iter->second.push_back(std::make_pair(tagName, field)); + apf::CGNSInfo info; + info.cgnsBCSName = tagName; + info.bcsMarkerTag = field; + iter->second.push_back(info); } else { - std::vector> pair; - pair.push_back(std::make_tuple(tagName, field)); - cgnsBCMap.insert(std::make_pair(location, pair)); + std::vector infos; + apf::CGNSInfo info; + info.cgnsBCSName = tagName; + info.bcsMarkerTag = field; + infos.push_back(info); + cgnsBCMap.insert(std::make_pair(location, infos)); } }; @@ -1468,7 +1473,7 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM auto iter = globalToVert.find(zeroBased); if (iter != globalToVert.end()) { - auto* elem = iter->second; + auto *elem = iter->second; if (md.size() == 1) { apf::setScalar(field, elem, 0, meshVals.at(it)); @@ -1491,7 +1496,7 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM apf::setMatrix(field, elem, 0, matrix3x3); } else - Kill(cgid, "Tensor size not accounted for"); + Kill(cgid, "Tensor size not accounted for"); } counter++; } @@ -1602,9 +1607,8 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM } else { - Kill(cgid, "Tensor size not accounted for"); + Kill(cgid, "Tensor size not accounted for"); } - } } } From 42384f54cafc6b8e5a5445a05ec25eb2f7938710 Mon Sep 17 00:00:00 2001 From: a-jp Date: Tue, 3 Mar 2020 14:30:59 +0000 Subject: [PATCH 66/72] remove prototype geometry classification - it doesn't work --- mds/mdsCGNS.cc | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/mds/mdsCGNS.cc b/mds/mdsCGNS.cc index 9d5d26f44..fd22769f8 100644 --- a/mds/mdsCGNS.cc +++ b/mds/mdsCGNS.cc @@ -1629,6 +1629,12 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM } } + // free up memory + if (PCU_Comm_Initialized()) + cgp_close(cgid); + else + cg_close(cgid); + { apf::MeshTag *tag = nullptr; tag = mesh->createIntTag("origCGNSGlobalVertID", 1); // 1 is size of tag @@ -1668,11 +1674,12 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM } } } + // not sure of the order of these three + // and with reference to: + apf::finalise(mesh, globalToVert); - apf::alignMdsRemotes(mesh); - apf::deriveMdsModel(mesh); mesh->acceptChanges(); - apf::verify(mesh, true); + apf::alignMdsRemotes(mesh); { apf::GlobalNumbering *gn = nullptr; @@ -1697,10 +1704,8 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM bc.TagBCEntities(cgid, mesh, cgnsBCMap); } - if (PCU_Comm_Initialized()) - cgp_close(cgid); - else - cg_close(cgid); + apf::deriveMdsModel(mesh); + apf::verify(mesh, true); return mesh; } // namespace From 27bbdb9eee5cbc0111c41dbf9b4622afd04382d1 Mon Sep 17 00:00:00 2001 From: a-jp Date: Tue, 3 Mar 2020 16:56:47 +0000 Subject: [PATCH 67/72] missing include --- apf/apfConvert.h | 1 + 1 file changed, 1 insertion(+) diff --git a/apf/apfConvert.h b/apf/apfConvert.h index 710d2048b..fcee947f8 100644 --- a/apf/apfConvert.h +++ b/apf/apfConvert.h @@ -12,6 +12,7 @@ \brief algorithms for mesh format conversion */ #include +#include namespace apf { From d1ad4b8636b159f52a3f445bcafb34192eea44aa Mon Sep 17 00:00:00 2001 From: a-jp Date: Tue, 3 Mar 2020 16:57:00 +0000 Subject: [PATCH 68/72] needless ; --- crv/crvQuality.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crv/crvQuality.cc b/crv/crvQuality.cc index 04119933a..c392a182e 100644 --- a/crv/crvQuality.cc +++ b/crv/crvQuality.cc @@ -98,7 +98,7 @@ Quality::Quality(apf::Mesh* m, int algorithm_) : PCU_ALWAYS_ASSERT(algorithm >= 0 && algorithm <= 2); order = mesh->getShape()->getOrder(); PCU_ALWAYS_ASSERT(order >= 1); -}; +} /* This work is based on the approach of Geometric Validity of high-order * lagrange finite elements, theory and practical guidance, From 87c0650bbcdfe302e78de0890fffe7a52cbeffbc Mon Sep 17 00:00:00 2001 From: a-jp Date: Tue, 3 Mar 2020 16:57:11 +0000 Subject: [PATCH 69/72] compile fixes --- mds/mdsCGNS.cc | 8 ++++---- test/cgns.cc | 9 ++++----- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/mds/mdsCGNS.cc b/mds/mdsCGNS.cc index fd22769f8..955e95031 100644 --- a/mds/mdsCGNS.cc +++ b/mds/mdsCGNS.cc @@ -31,6 +31,7 @@ #include #include #include +#include #include #include // @@ -963,14 +964,14 @@ void ReadBCInfo(const int cgid, const int base, const int zone, const int nBocos cgsize_t el_end = -1; int num_bndry = -1; int parent_flag = -1; - cgsize_t numElements = -1; + //cgsize_t numElements = -1; int verticesPerElement = -1; cg_section_read(cgid, base, zone, section, §ionName[0], &elementType, &el_start, &el_end, &num_bndry, &parent_flag); - numElements = el_end - el_start + 1; + //numElements = el_end - el_start + 1; cg_npe(elementType, &verticesPerElement); @@ -1690,8 +1691,7 @@ apf::Mesh2 *DoIt(gmi_model *g, const std::string &fname, apf::CGNSBCMap &cgnsBCM // https://github.com/SNLComputation/Albany/blob/master/src/disc/pumi/Albany_APFDiscretization.cpp @ various place throughout file // https://github.com/SCOREC/core/issues/249 { - apf::GlobalNumbering *gn = nullptr; - gn = apf::makeGlobal(apf::numberElements(mesh, "elem Idx")); + apf::makeGlobal(apf::numberElements(mesh, "elem Idx")); } for (auto &bc : bcInfos) diff --git a/test/cgns.cc b/test/cgns.cc index 1a531b865..6f853d2e0 100644 --- a/test/cgns.cc +++ b/test/cgns.cc @@ -10,6 +10,7 @@ #include // #include +#include // #include #include @@ -83,8 +84,7 @@ void simpleReorder(const std::string &prefix, apf::Mesh2 *m) // https://github.com/SNLComputation/Albany/blob/master/src/disc/pumi/Albany_APFDiscretization.cpp @ various place throughout file // https://github.com/SCOREC/core/issues/249 { - apf::GlobalNumbering *gn = nullptr; - gn = apf::makeGlobal(apf::numberElements(m, "elem Idx_preOrder")); + apf::makeGlobal(apf::numberElements(m, "elem Idx_preOrder")); } //apf::MeshTag *order = Parma_BfsReorder(m); @@ -100,8 +100,7 @@ void simpleReorder(const std::string &prefix, apf::Mesh2 *m) // https://github.com/SNLComputation/Albany/blob/master/src/disc/pumi/Albany_APFDiscretization.cpp @ various place throughout file // https://github.com/SCOREC/core/issues/249 { - apf::GlobalNumbering *gn = nullptr; - gn = apf::makeGlobal(apf::numberElements(m, "elem Idx_pstOrder")); + apf::makeGlobal(apf::numberElements(m, "elem Idx_pstOrder")); } const std::string name = prefix + "_reorder_" + std::to_string(PCU_Comm_Peers()) + "procs"; @@ -440,7 +439,7 @@ std::string doit(apf::CGNSBCMap &cgnsBCMap, const std::string &argv1, const std: { apf::Field *field = nullptr; const std::string name = "displace"; - field = field = apf::createFieldOn(m, name.c_str(), apf::VECTOR); + field = apf::createFieldOn(m, name.c_str(), apf::VECTOR); apf::MeshIterator *it = m->begin(0); apf::MeshEntity *elm = nullptr; while ((elm = m->iterate(it))) From 87dcaf3bb0b3300d1b1c3bbfa8fac27886b4294c Mon Sep 17 00:00:00 2001 From: a-jp Date: Tue, 3 Mar 2020 17:04:30 +0000 Subject: [PATCH 70/72] remove flags not accepted by gcc --- cmake/bob.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmake/bob.cmake b/cmake/bob.cmake index 6a5d6e556..74c5400fd 100644 --- a/cmake/bob.cmake +++ b/cmake/bob.cmake @@ -88,7 +88,8 @@ endfunction(bob_cxx11_flags) function(bob_cxx14_flags) set(FLAGS "${CMAKE_CXX_FLAGS}") - set(FLAGS "${FLAGS} --std=c++14 -Wall -Wextra -Wpedantic -Werror -Werror=return-stack-address -Werror=mismatched-tags -Wno-extra-semi -Werror=unused-parameter -Wno-error=deprecated-declarations") + # clang only: -Werror=return-stack-address -Werror=mismatched-tags + set(FLAGS "${FLAGS} --std=c++14 -Wall -Wextra -Wpedantic -Werror -Wno-extra-semi -Werror=unused-parameter -Wno-error=deprecated-declarations") if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") if (${PROJECT_NAME}_CXX_WARNINGS) set(FLAGS "${FLAGS} -Wno-c++98-compat-pedantic -Wno-c++98-compat") From 5a799fff503fa12600653dad16d30ac0e5f67b68 Mon Sep 17 00:00:00 2001 From: a-jp Date: Wed, 4 Mar 2020 15:07:48 +0000 Subject: [PATCH 71/72] refine comment --- mds/apfMDS.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mds/apfMDS.h b/mds/apfMDS.h index 8ff0c4ce3..284f85b06 100644 --- a/mds/apfMDS.h +++ b/mds/apfMDS.h @@ -32,7 +32,7 @@ #include // -// AJP: for single define CGNSBCMap +// AJP: including apf.h for single define: CGNSBCMap // AJP: alternative is to allow common cgns base header // but trying to avoid that since it's not core functionality #include From e8ad191cbe9e8fa477879b6ea5fe76bf05a6a5aa Mon Sep 17 00:00:00 2001 From: a-jp Date: Wed, 4 Mar 2020 15:26:38 +0000 Subject: [PATCH 72/72] rename cgns files consistent with pumi-meshes renaming --- test/testing.cmake | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/testing.cmake b/test/testing.cmake index d59b4bc22..96c419933 100644 --- a/test/testing.cmake +++ b/test/testing.cmake @@ -462,22 +462,22 @@ set(CGNSDIR ${MESHES}/cgns/basic) # mpi_test(cgns_2d_1 ${numProcs} ./from_cgns - "${CGNSDIR}/2D/4quads.adf.hdf.cgns" + "${CGNSDIR}/2D/4quads.cgns" 4quads.smb additional) mpi_test(cgns_2d_2 ${numProcs} ./from_cgns - "${CGNSDIR}/2D/5quad1Tri.adf.hdf.cgns" + "${CGNSDIR}/2D/5quad1Tri.cgns" 5quad1Tri.smb additional) mpi_test(cgns_2d_3 ${numProcs} ./from_cgns - "${CGNSDIR}/2D/5quad2Tri.adf.hdf.cgns" + "${CGNSDIR}/2D/5quad2Tri.cgns" 5quad2Tri.smb additional) mpi_test(cgns_2d_4 ${numProcs} ./from_cgns - "${CGNSDIR}/2D/9tris.adf.hdf.cgns" + "${CGNSDIR}/2D/9tris.cgns" 9tris.smb additional) # @@ -485,12 +485,12 @@ mpi_test(cgns_2d_4 ${numProcs} # mpi_test(cgns_3d_1 ${numProcs} ./from_cgns - "${CGNSDIR}/3D/tets_pyra.adf.hdf.cgns" + "${CGNSDIR}/3D/tets_pyra.cgns" tets_pyra.smb additional) mpi_test(cgns_3d_2 ${numProcs} ./from_cgns - "${CGNSDIR}/3D/hexs.adf.hdf.cgns" + "${CGNSDIR}/3D/hexs.cgns" hexs.smb additional) # @@ -502,13 +502,13 @@ set(CGNSDIR ${MESHES}/cgns/withBCS/3D) # mpi_test(cgns_bcs_1 ${numProcs} ./from_cgns - "${CGNSDIR}/Mesh_3.adf.hdf.cgns" + "${CGNSDIR}/mixed.cgns" bcs1.smb additional) mpi_test(cgns_bcs_hex ${numProcs} ./from_cgns - "${CGNSDIR}/8hexs.adf.hdf.cgns" + "${CGNSDIR}/8hexs.cgns" bcshex.smb additional) # @@ -520,7 +520,7 @@ set(CGNSDIR ${MESHES}/cgns/withBCS/2D) # mpi_test(cgns_bcs_2 ${numProcs} ./from_cgns - "${CGNSDIR}/Mesh_4.adf.hdf.cgns" + "${CGNSDIR}/4quads.cgns" bcs2.smb additional) # @@ -532,7 +532,7 @@ set(CGNSDIR ${MESHES}/cgns/withBCS/1D) # mpi_test(cgns_bcs_3 ${numProcs} ./from_cgns - "${CGNSDIR}/Mesh_5.adf.hdf.cgns" + "${CGNSDIR}/edges.cgns" bcs3.smb additional)