Il 14/10/21 14:37, Matthew Knepley ha scritto:
On Wed, Oct 13, 2021 at 6:30 PM Abhishek G.S.
<[email protected] <mailto:[email protected]>> wrote:
Hi,
I need some help with getting the file output working right.
I am using a DMDACreate3D to initialize my DM. This is my write
function
void write(){
PetscViewer viewer;
PetscViewerHDF5Open(PETSC_COMM_WORLD,filename.c_str(),FILE_MODE_WRITE,&viewer);
DMDAVecRestoreArray(dm,global_vector,global_array)
VecView(global_vec, viewer);
DMDAVecGetArray(dm,global_vector,global_array);
PetscViewerDestroy(&viewer);
}
1) I have 2 PDE's to solve. Still, I went ahead creating a single
DM with dof=1 and creating two vectors using the
DMCreateGlobalVector(). I want to write the file out
periodically. Should I perform DMDAVecRestoreArray and
DMDAVecGetArray every time is write out the global_vector? (I know
that it is just indexing the pointers and there is no copying of
values. But I am not sure)
I don't think you need the Get/RestoreArray() calls here.
2) I am writing out to HDF5 format. I see that the vecview is
supposed to reorder the global_vector based on the DM. However,
when I read the H5 files, I get an error on ViSIT and my output
image becomes a 1D image rather than a 2D/3D. What might be the
reason for this ?.
Error Msg : "In domain 0, your zonal variable "avtGhostZones" has
25600 values, but it should have 160. Some values were removed to
ensure VisIt runs smoothly"
I was using a 160x160x1 DM
I do not believe we support HDF5 <--> Visit/Paraview for DMDA. The
VecView() is just writing out the vector as a linear array without
mesh details. For
interfacing with the visualization, I think we use .vtu files. You
should be able to get this effect using
VecViewFromOptions(global_vec, NULL, "-vec_view");
in your code, and then
-vec_view vtk:sol.vtu
on the command line.
Hi.
If you want to stick with HDF5, you can also write a XDMF file with the
grid information and open that in Paraview.
I am attaching some routines that I have written to do that in a solver
that deals with a time dependent PDE system with 2 variables; with them
I end up with a single XDMF file that Paraview can load and which
contains references to all timesteps in my simulations, with each
timestep being contained in an HDF5 file on its own. The idea is to call
writeDomain at the beginning of the simulation, writeHDF5 for each
timestep that I want to save and writeSimulationXDMF at the end.
(Warning: 3D is in use, while 2D ia almost untested...)
It's not the optimal solution since (1) all timesteps could be in the
same HDF5 and (2) in each HDF5 i write the vectors separately and it
would be better to dump the entire data in one go and interpret them as
a Nx*Ny*Nz*Nvariables data from the XDMF. Nevertheless they might be a
starting point for you if you wan to try this approach.
Matteo
3) I tried using the "petsc_gen_xdmf.py" to generate the xdmf
files for use in Paraview. Here the key ["viz/geometry"] is
missing. The keys present in the output H5 file are just the two
vectors I am writing and has no info about mesh. Isn't this
supposed to come automatically since the vector is attached to the
DM? How do I sort this out?
This support is for unstructured grids, DMPlex and DMForest.
4) Can I have multiple vectors attached to the DM by
DMCreateGlobalVector() even though I created the DMDA using dof=1.
Yes.
Thanks,
Matt
thanks,
Abhishek
--
What most experimenters take for granted before they begin their
experiments is infinitely more interesting than any results to which
their experiments lead.
-- Norbert Wiener
https://www.cse.buffalo.edu/~knepley/
<https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.cse.buffalo.edu%2F~knepley%2F&data=04%7C01%7Cmatteo.semplice%40uninsubria.it%7Cf27a34f639784d0231c708d98f0f7279%7C9252ed8bdffc401c86ca6237da9991fa%7C0%7C0%7C637698118789688898%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=Xb8nyv7BIl6zSBbbLFkQzluIF8s%2BOLwUQeVfjtr3q4k%3D&reserved=0>
--
---
Professore Associato in Analisi Numerica
Dipartimento di Scienza e Alta Tecnologia
Università degli Studi dell'Insubria
Via Valleggio, 11 - Como
/* Output su file HDF5 (e XDMF per ParaView) */
#include <petscviewerhdf5.h>
#include "hdf5Output.h"
#include <sstream>
#include <fstream>
PetscErrorCode HDF5output::writeDomain(AppContext &ctx){
PetscErrorCode ierr;
PetscSNPrintf(hdf5DomainName,256,"%s.h5","dominio");
PetscViewer viewer;
PetscPrintf(PETSC_COMM_WORLD,"Save domain on file %s\n",hdf5DomainName);
ierr = PetscViewerHDF5Open(PETSC_COMM_WORLD,hdf5DomainName,FILE_MODE_WRITE,&viewer); CHKERRQ(ierr);
ierr = VecView(ctx.Phi,viewer); CHKERRQ(ierr);
PetscObjectSetName((PetscObject) ctx.NODETYPE, "NodeType");
ierr = VecView(ctx.NODETYPE,viewer); CHKERRQ(ierr);
ierr = PetscViewerDestroy(&viewer); CHKERRQ(ierr);
std::stringstream buffer;
if (ctx.rank==0){
char xdmfname[256];
PetscSNPrintf(xdmfname,256,"%s.xdmf","dominio");
std::ofstream xdmf;
xdmf.open(xdmfname,std::ios_base::out);
xdmf << "<?xml version=\"1.0\" ?>\n";
xdmf << "<Xdmf xmlns:xi=\"http://www.w3.org/2001/XInclude\" Version=\"2.0\">\n";
xdmf << "<Domain>\n";
xdmf << " <Grid GridType=\"Collection\" CollectionType=\"Temporal\">\n";
buffer << " <Grid GridType=\"Uniform\" Name=\"domain\">\n";
buffer << " <Time Type=\"Single\" Value=\""<<0.<<"\" />\n";
switch (ctx.dim){
case 2:
buffer << " <Topology TopologyType=\"2DCoRectMesh\" Dimensions=\"" << ctx.nnx << " " << ctx.nny << "\"/>\n";
buffer << " <Geometry GeometryType=\"ORIGIN_DXDY\">\n";
buffer << " <DataItem Format=\"XML\" NumberType=\"Float\" Dimensions=\"2\">" << ctx.xmin << " " << ctx.ymin << "</DataItem>\n";
buffer << " <DataItem Format=\"XML\" NumberType=\"Float\" Dimensions=\"2\">" << ctx.dx << " " << ctx.dy << "</DataItem>\n";
buffer << " </Geometry>\n";
break;
case 3:
buffer << " <Topology TopologyType=\"3DCoRectMesh\" Dimensions=\"" << ctx.nnx << " " << ctx.nny << " " << ctx.nnz << "\"/>\n";
buffer << " <Geometry GeometryType=\"ORIGIN_DXDYDZ\">\n";
buffer << " <DataItem Format=\"XML\" NumberType=\"Float\" Dimensions=\"3\">" << ctx.xmin << " " << ctx.ymin << " " << ctx.zmin << "</DataItem>\n";
buffer << " <DataItem Format=\"XML\" NumberType=\"Float\" Dimensions=\"3\">" << ctx.dx << " " << ctx.dy << " " << ctx.dz << "</DataItem>\n";
buffer << " </Geometry>\n";
buffer << " <Attribute Name=\"Phi\" Center=\"Node\" AttributeType=\"Scalar\">\n";
buffer << " <DataItem Format=\"HDF\" Dimensions=\"" << ctx.nnx << " " << ctx.nny << " " << ctx.nnz << "\">"<<hdf5DomainName<<":/Phi</DataItem>\n";
buffer << " </Attribute>\n";
buffer << " <Attribute Name=\"NodeType\" Center=\"Node\" AttributeType=\"Scalar\">\n";
buffer << " <DataItem Format=\"HDF\" Dimensions=\"" << ctx.nnx << " " << ctx.nny << " " << ctx.nnz << "\">"<<hdf5DomainName<<":/NodeType</DataItem>\n";
buffer << " </Attribute>\n";
break;
default:
abort();
}
buffer << " </Grid>\n";
xdmf << buffer.str();
xdmf << " </Grid>\n";
xdmf << "</Domain>\n";
xdmf << "</Xdmf>\n";
xdmf.close();
}
return ierr;
}
PetscErrorCode HDF5output::writeHDF5(Vec U, PetscScalar time, bool singleXDMF){
PetscErrorCode ierr;
if (time<nextSave)
return 0;
char hdf5name[256];
PetscSNPrintf(hdf5name,256,"%s_%d.h5",basename,stepBuffer.size());
PetscViewer viewer;
PetscPrintf(PETSC_COMM_WORLD,"Save on file %s\n",hdf5name);
ierr = PetscViewerHDF5Open(PETSC_COMM_WORLD,hdf5name,FILE_MODE_WRITE,&viewer); CHKERRQ(ierr);
Vec uField;
//s
ierr = DMGetGlobalVector(ctx.daField[var::s], &uField); CHKERRQ(ierr);
ierr = VecStrideGather(U,var::s,uField,INSERT_VALUES); CHKERRQ(ierr);
PetscObjectSetName((PetscObject) uField, "S");
ierr = VecView(uField,viewer); CHKERRQ(ierr);
ierr = DMRestoreGlobalVector(ctx.daField[var::s], &uField); CHKERRQ(ierr);
//c
ierr = DMGetGlobalVector(ctx.daField[var::c], &uField); CHKERRQ(ierr);
ierr = VecStrideGather(U,var::c,uField,INSERT_VALUES); CHKERRQ(ierr);
PetscObjectSetName((PetscObject) uField, "C");
ierr = VecView(uField,viewer); CHKERRQ(ierr);
ierr = DMRestoreGlobalVector(ctx.daField[var::c], &uField); CHKERRQ(ierr);
//levelset function and NodeTypes
//ierr = VecView(ctx.Phi,viewer); CHKERRQ(ierr);
//PetscObjectSetName((PetscObject) ctx.NODETYPE, "NodeType");
//ierr = VecView(ctx.NODETYPE,viewer); CHKERRQ(ierr);
ierr = PetscViewerDestroy(&viewer); CHKERRQ(ierr);
std::stringstream buffer;
if (ctx.rank==0){
buffer << " <Grid GridType=\"Uniform\" Name=\"domain\">\n";
buffer << " <Time Type=\"Single\" Value=\""<<time<<"\" />\n";
switch (ctx.dim){
case 2:
buffer << " <Topology TopologyType=\"2DCoRectMesh\" Dimensions=\"" << ctx.nnx << " " << ctx.nny << "\"/>\n";
buffer << " <Geometry GeometryType=\"ORIGIN_DXDY\">\n";
buffer << " <DataItem Format=\"XML\" NumberType=\"Float\" Dimensions=\"2\">" << ctx.xmin << " " << ctx.ymin << "</DataItem>\n";
buffer << " <DataItem Format=\"XML\" NumberType=\"Float\" Dimensions=\"2\">" << ctx.dx << " " << ctx.dy << "</DataItem>\n";
buffer << " </Geometry>\n";
buffer << " <Attribute Name=\"SO2\" Center=\"Node\" AttributeType=\"Scalar\">\n";
buffer << " <DataItem Format=\"HDF\" Dimensions=\"" << ctx.nnx << " " << ctx.nny << "\">"<<hdf5name<<":/S</DataItem>\n";
buffer << " </Attribute>\n";
buffer << " <Attribute Name=\"CaCO3\" Center=\"Node\" AttributeType=\"Scalar\">\n";
buffer << " <DataItem Format=\"HDF\" Dimensions=\"" << ctx.nnx << " " << ctx.nny << "\">"<<hdf5name<<":/C</DataItem>\n";
buffer << " </Attribute>\n";
break;
case 3:
buffer << " <Topology TopologyType=\"3DCoRectMesh\" Dimensions=\"" << ctx.nnx << " " << ctx.nny << " " << ctx.nnz << "\"/>\n";
buffer << " <Geometry GeometryType=\"ORIGIN_DXDYDZ\">\n";
buffer << " <DataItem Format=\"XML\" NumberType=\"Float\" Dimensions=\"3\">" << ctx.xmin << " " << ctx.ymin << " " << ctx.zmin << "</DataItem>\n";
buffer << " <DataItem Format=\"XML\" NumberType=\"Float\" Dimensions=\"3\">" << ctx.dx << " " << ctx.dy << " " << ctx.dz << "</DataItem>\n";
buffer << " </Geometry>\n";
buffer << " <Attribute Name=\"SO2\" Center=\"Node\" AttributeType=\"Scalar\">\n";
buffer << " <DataItem Format=\"HDF\" Dimensions=\"" << ctx.nnx << " " << ctx.nny << " " << ctx.nnz << "\">"<<hdf5name<<":/S</DataItem>\n";
buffer << " </Attribute>\n";
buffer << " <Attribute Name=\"CaCO3\" Center=\"Node\" AttributeType=\"Scalar\">\n";
buffer << " <DataItem Format=\"HDF\" Dimensions=\"" << ctx.nnx << " " << ctx.nny << " " << ctx.nnz << "\">"<<hdf5name<<":/C</DataItem>\n";
buffer << " </Attribute>\n";
buffer << " <Attribute Name=\"Phi\" Center=\"Node\" AttributeType=\"Scalar\">\n";
buffer << " <DataItem Format=\"HDF\" Dimensions=\"" << ctx.nnx << " " << ctx.nny << " " << ctx.nnz << "\">"<<hdf5DomainName<<":/Phi</DataItem>\n";
buffer << " </Attribute>\n";
buffer << " <Attribute Name=\"NodeType\" Center=\"Node\" AttributeType=\"Scalar\">\n";
buffer << " <DataItem Format=\"HDF\" Dimensions=\"" << ctx.nnx << " " << ctx.nny << " " << ctx.nnz << "\">"<<hdf5DomainName<<":/NodeType</DataItem>\n";
buffer << " </Attribute>\n";
break;
default:
abort();
}
buffer << " </Grid>\n";
}
//Note: ranks>0 have empty buffers, but stepBuffer.size does increase for everybody
hdfTime tStep;
tStep.t = time;
tStep.hdfSnippet = buffer.str();
stepBuffer.push_back(tStep);
if (singleXDMF) writeLastXDMF();
nextSave += dtSave;
return 0;
}
void HDF5output::writeLastXDMF(){
if (stepBuffer.empty())
return;
if (ctx.rank==0){
char xdmfname[256];
PetscSNPrintf(xdmfname,256,"%s_%d.xdmf",basename,stepBuffer.size()-1);
std::ofstream xdmf;
xdmf.open(xdmfname,std::ios_base::out);
xdmf << "<?xml version=\"1.0\" ?>\n";
xdmf << "<Xdmf xmlns:xi=\"http://www.w3.org/2001/XInclude\" Version=\"2.0\">\n";
xdmf << "<Domain>\n";
xdmf << " <Grid GridType=\"Collection\" CollectionType=\"Temporal\">\n";
xdmf << stepBuffer.back().hdfSnippet;
xdmf << " </Grid>\n";
xdmf << "</Domain>\n";
xdmf << "</Xdmf>\n";
xdmf.close();
}
}
void HDF5output::writeSimulationXDMF(){
if (ctx.rank==0){
char xdmfname[256];
snprintf(xdmfname,256,"%s.xdmf",basename);
std::ofstream xdmf;
xdmf.open(xdmfname,std::ios_base::out);
xdmf << "<?xml version=\"1.0\" ?>\n";
xdmf << "<Xdmf xmlns:xi=\"http://www.w3.org/2001/XInclude\" Version=\"2.0\">\n";
xdmf << "<Domain>\n";
xdmf << " <Grid GridType=\"Collection\" CollectionType=\"Temporal\">\n";
xdmf << " <Time TimeType=\"List\">\n";
xdmf << " <DataItem Dimensions=\""<< stepBuffer.size()<<"\">\n";
for (auto it = stepBuffer.begin(); it != stepBuffer.end(); it++)
xdmf << (*it).t << " " ;
xdmf << "\n";
xdmf << " </DataItem>\n";
xdmf << " </Time>\n";
xdmf << "\n";
for (auto it = stepBuffer.begin(); it != stepBuffer.end(); it++)
xdmf << (*it).hdfSnippet << "\n";
xdmf << " </Grid>\n";
xdmf << "</Domain>\n";
xdmf << "</Xdmf>\n";
xdmf.close();
}
}
/* Output su file VTK (per ParaView) */
#ifndef __HDF5OUTPUT_H
#define __HDF5OUTPUT_H
#include "appctx.h"
#include <vector>
#include <string>
PetscErrorCode writePhi(AppContext &_ctx);
typedef struct{
PetscScalar t;
std::string hdfSnippet;
} hdfTime;
class HDF5output{
public:
HDF5output(const char * _basename, AppContext &_ctx, PetscScalar tFinal, int nSave):
ctx(_ctx),
dtSave(tFinal/nSave),
nextSave(nSave>=0?0.:INFINITY)
{strncpy(basename,_basename,250);};
//! HDF5 output of the domain (levelset and NodeTypes)
PetscErrorCode writeDomain(AppContext &ctx);
//! HDF5 output of the solution
//! with singleXDMF=true it will also write a XDMF for this timestep
PetscErrorCode writeHDF5(Vec U, PetscScalar time, bool singleXDMF=false);
//! writes XDMF for the entire simulation
void writeSimulationXDMF();
private:
AppContext &ctx;
char basename[250];
char hdf5DomainName[256];
std::vector<hdfTime> stepBuffer;
PetscScalar dtSave, nextSave;
//! writes XDMF for a single timestep (the last)
void writeLastXDMF();
};
#endif