Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MFEMSidreDataCollection does not like to read a field. #1007

Open
BradWhitlock opened this issue Jan 21, 2023 · 0 comments
Open

MFEMSidreDataCollection does not like to read a field. #1007

BradWhitlock opened this issue Jan 21, 2023 · 0 comments

Comments

@BradWhitlock
Copy link
Member

BradWhitlock commented Jan 21, 2023

When writing a CI test for IntersectionShaper replacement rules, I had been trying to save an MFEMSidreDataCollection that included volume fraction arrays. These were mfem::GridFunctions allocated using code that I don't recall modifying other than splitting it out into a method. The following program makes a MFEMSidreDataCollection like what might be seen as output from the IntersectionShaper and writes it out and then reads it back in. On readback, sidre claims that the fields do not meet Blueprint standards. So, is the data wrong before writing it out? There was no apparent failure during Save(). Or, is there a problem in Load() that messes up these fields?

This code was built using an Axom on rzgenie that used the rzgenie-toss_3_x86_64_ib-gcc@8.3.1.cmake host config.

Running "sidredebug > output.txt" works fine as there are no fields.
Running "sidredebug -fields > output.txt" produces the errors below.

#include <axom/config.hpp>
#include <axom/sidre.hpp>

#include <mfem.hpp>

#define PARALLEL
#ifdef PARALLEL
#include <mpi.h>
#endif

#include <sys/stat.h>

#define USE_PREFIX

#include <iostream>
using std::cout;
using std::endl;

namespace sidre = axom::sidre;

// Is there something wrong with this MFEM grid function? It is
// borrowed from IntersectionShaper.
mfem::GridFunction *
newGridFunction(mfem::Mesh *mesh)
{
  const int vfOrder = 0;
  const int dim = mesh->Dimension();
  mfem::L2_FECollection* coll =
    new mfem::L2_FECollection(vfOrder, dim, mfem::BasisType::Positive);
  mfem::FiniteElementSpace* fes = new mfem::FiniteElementSpace(mesh, coll);
  mfem::GridFunction* gf = new mfem::GridFunction(fes);
  gf->MakeOwner(coll);
  memset(gf->GetData(), 0, gf->Size() * sizeof(double));
  return gf;
}

void
makeTestMesh(sidre::MFEMSidreDataCollection &dc, bool addFields)
{
  int polynomialOrder = 1;
  double lo[] = {0., 0., -0.25};
  double hi[] = {1., 1., 0.};
  int celldims[] = {20, 20, 1};
  auto mesh = new mfem::Mesh(mfem::Mesh::MakeCartesian3D(celldims[0],
                                                         celldims[1],
                                                         celldims[2],
                                                         mfem::Element::HEXAHEDRON,
                                                         hi[0] - lo[0],
                                                         hi[1] - lo[1],
                                                         hi[2] - lo[2],
                                                         false));
  mesh->SetCurvature(polynomialOrder);
  dc.SetMeshNodesName("positions");
  dc.SetMesh(mesh);

  if(addFields)
  {
    // This mode will make 2 clean materials in the mesh.
    mfem::GridFunction *mata = newGridFunction(mesh);
    mfem::GridFunction *matb = newGridFunction(mesh);
    for(int k = 0; k < celldims[2]; k++)
    {
      for(int j = 0; j < celldims[1]; j++)
      {
        for(int i = 0; i < celldims[0]; i++)
        {
          int id = k*celldims[1]*celldims[0] + j*celldims[0] + i;
          (*mata)(id) = (j < celldims[1]/2);
          (*matb)(id) = (j >= celldims[1]/2);
        }
      }
    }
    dc.RegisterField("vol_frac_a", mata);
    dc.RegisterField("vol_frac_b", matb);
  }
}

int
main(int argc, char *argv[])
{
#ifdef PARALLEL
  MPI_Init(&argc, &argv);
#endif
  bool addFields = false;
  for(int i = 1; i < argc; i++)
  {
    if(strcmp(argv[i],"-fields") == 0)
      addFields = true;
  }
  cout << "Making mesh" << endl;
  std::string baseName("foo");
  sidre::MFEMSidreDataCollection dc(baseName, nullptr, true);
  makeTestMesh(dc, addFields);

  // We have to set this to make it work.
  dc.SetComm(MPI_COMM_WORLD);

#ifdef USE_PREFIX
  mkdir("baselines", 0750);
  dc.SetPrefixPath("baselines");
#endif

  // Save the data
  cout << "Saving mesh" << endl;
  dc.SetCycle(0);
  dc.Save();

  cout << "Loading mesh" << endl;
  sidre::MFEMSidreDataCollection fromFileDC(baseName, nullptr, true);
  fromFileDC.SetCycle(0);
  // We have to set this to make it work.
  fromFileDC.SetComm(MPI_COMM_WORLD);
#ifdef USE_PREFIX
  fromFileDC.SetPrefixPath("baselines");
#endif
  fromFileDC.Load(0);

#ifdef PARALLEL
  MPI_Finalize();
#endif

  return 0;
}

CMake

cmake_minimum_required(VERSION 3.1)
set(CMAKE_CXX_COMPILER /usr/tce/packages/gcc/gcc-8.3.1/bin/g++)
set(CMAKE_C_COMPILER /usr/tce/packages/gcc/gcc-8.3.1/bin/gcc)
set(CMAKE_BUILD_TYPE Debug)

project(sidrebug)

add_compile_options("-std=c++14")

set(axom_DIR /usr/WS2/whitlocb/Axom/axom/install-rzgenie/lib/cmake)
find_package(axom)

add_executable(sidredebug main.cpp)
target_link_libraries(sidredebug axom)

Program output

Making mesh
gf->GetData=0x1b814d0, gf->Size=400
gf->GetData=0x1ba9760, gf->Size=400
Saving mesh
Loading mesh

***********************************
LEVEL=WARNING
MESSAGE=MFEMSidreDataCollection blueprint verification failed:

coordsets: 
  valid: "true"
  coords: 
    type: 
      valid: "true"
    info: 
      - "mesh::coordset::explicit: 'type' has valid value 'explicit'"
      - "mesh::coordset::explicit: 'values' is an mcarray"
    values: 
      valid: "true"
    valid: "true"
topologies: 
  valid: "true"
  mesh: 
    coordset: 
      valid: "true"
    type: 
      valid: "true"
    info: 
      - "mesh::topology::unstructured: 'type' has valid value 'unstructured'"
    elements: 
      valid: "true"
      shape: 
        valid: "true"
        info: 
          - "mesh::topology::shape: has valid value 'hex'"
      connectivity: 
        valid: "true"
    valid: "true"
    optional: 
      - "mesh::topology: includes grid_function"
    grid_function: 
      valid: "true"
  boundary: 
    coordset: 
      valid: "true"
    type: 
      valid: "true"
    info: 
      - "mesh::topology::unstructured: 'type' has valid value 'unstructured'"
    elements: 
      valid: "true"
      shape: 
        valid: "true"
        info: 
          - "mesh::topology::shape: has valid value 'quad'"
      connectivity: 
        valid: "true"
    valid: "true"
fields: 
  valid: "false"
  mesh_material_attribute: 
    association: 
      valid: "true"
      info: 
        - "mesh::association: has valid value 'element'"
    topology: 
      valid: "true"
    values: 
      valid: "true"
    info: 
      - "mesh::field: 'values' is an mlarray"
    valid: "true"
  boundary_material_attribute: 
    association: 
      valid: "true"
      info: 
        - "mesh::association: has valid value 'element'"
    topology: 
      valid: "true"
    values: 
      valid: "true"
    info: 
      - "mesh::field: 'values' is an mlarray"
    valid: "true"
  positions: 
    basis: 
      valid: "true"
    topology: 
      valid: "true"
    values: 
      valid: "true"
    info: 
      - "mesh::field: 'values' is an mlarray"
    valid: "true"
  vol_frac_a: 
    basis: 
      valid: "true"
    topology: 
      valid: "true"
    values: 
      errors: 
        - "mlarray: mlarray is empty"
      valid: "false"
    errors: 
      - "mesh::field: 'values' is not an mlarray"
    valid: "false"
  vol_frac_b: 
    basis: 
      valid: "true"
    topology: 
      valid: "true"
    values: 
      errors: 
        - "mlarray: mlarray is empty"
      valid: "false"
    errors: 
      - "mesh::field: 'values' is not an mlarray"
    valid: "false"
valid: "false"

FILE=/usr/WS2/whitlocb/Axom/axom/src/axom/sidre/core/MFEMSidreDataCollection.cpp
LINE=723
***********************************

***********************************
LEVEL=ERROR
MESSAGE=Cannot reconstruct mesh, data does not satisfy Conduit Blueprint
** StackTrace of 8 frames **
Frame 1: axom::slic::logErrorMessage(std::string const&, std::string const&, int)
Frame 2: axom::sidre::MFEMSidreDataCollection::reconstructMesh()
Frame 3: axom::sidre::MFEMSidreDataCollection::UpdateMeshAndFieldsFromDS()
Frame 4: axom::sidre::MFEMSidreDataCollection::Load(std::string const&, std::string const&)
Frame 5: axom::sidre::MFEMSidreDataCollection::Load(int)
Frame 6: main
Frame 7: __libc_start_main
Frame 8: ./sidredebug() [0x6b0cd4]
=====


FILE=/usr/WS2/whitlocb/Axom/axom/src/axom/sidre/core/MFEMSidreDataCollection.cpp
LINE=2398
***********************************
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant