I want to convert legacy .vtk files into binary files, preferably .vtu files, because I am using an Unstructured Grid.
To do so I adapted the ConvertFile-Example from http://www.vtk.org/Wiki/VTK/Examples/Cxx/IO/ConvertFile
#include <string>
#include <vtkSmartPointer.h>
#include <vtkGenericDataObjectReader.h>
#include <vtkVersion.h>
#include <vtkXMLUnstructuredGridWriter.h>
#include <vtkUnstructuredGrid.h>
int main(int argc, char *argv[])
{
if(argc < 3)
{
std::cerr << "Required arguments: input.vtk output.vtu" << std::endl;
return EXIT_FAILURE;
}
std::string inputFileName = argv[1];
std::string outputFileName = argv[2];
vtkSmartPointer<vtkGenericDataObjectReader> reader = vtkSmartPointer<vtkGenericDataObjectReader>::New();
reader->SetFileName(inputFileName.c_str());
reader->Update();
vtkSmartPointer<vtkXMLUnstructuredGridWriter> writer = vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
writer->SetFileName(outputFileName.c_str());
writer->SetInputConnection(reader->GetOutputPort());
writer->Update();
return EXIT_SUCCESS;
}
But when I use this to convert my legacy file, I lose all Cell Data after the first set. In this minimal example of my legacy file Scal_1 is in the .vtu file but Scal_2 is not.
# vtk DataFile Version 3.1
Lattice Boltzmann data
ASCII
DATASET UNSTRUCTURED_GRID
POINTS 9 INT
0 0 0 1 0 0 2 0 0
0 1 0 1 1 0 2 1 0
0 2 0 1 2 0 2 2 0
CELLS 4 20
4 0 1 3 4
4 1 2 4 5
4 3 4 6 7
4 4 5 7 8
CELL_TYPES 4
8 8 8 8
CELL_DATA 4
SCALARS Scal_1 DOUBLE
LOOKUP_TABLE default
1 2 1 0
SCALARS Scal_2 DOUBLE
LOOKUP_TABLE default
1 3 2 1
I am still new to vtk. Should I use another reader or writer? Or is something completely wrong?
The issue here is that the reader you chose is getting confused by having the input file containing 2 cell data arrays both marked as scalars. So with this the reader only outputs one cell data array. My suggestion is to use ParaView, specifically the pvpython executable, to convert the files. The corresponding Python code would look something like:
from paraview.simple import *
r = LegacyVTKReader( FileNames=['input.vtk'] )
w = XMLUnstructuredGridWriter()
w.FileName = 'output.vtu'
w.UpdatePipeline()
You can just use meshio (a project of mine). Install with
pip3 install meshio
and run
meshio-convert in.vtk out.vtu
Related
I want to use one or eye function in Armadillo to construct matrices or vectors. However, it does not allow me to do so. Here is a sample code:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
// [[Rcpp::export]]
SEXP Generate(arma::mat Mat){
arma::mat Mat_2 = ones<mat>(5,6);
}
error message reminds me of use of undeclared idenfier of 'mat'. When I remove <mat>, another massage says use of undeclared idenfier of 'ones'.
I looked up the Armadillo tutorial which includes the ones function. I wonder why my code fails to call it. Did I miss something?
There are a few problems in your code:
Why return SEXP? Use types to your advantage
Why pass Mat in if you do not use it?
No return statement
Somewhat loose use of namespaces.
A cleaned up version follows:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::mat Generate(int n=5, int k=6){
arma::mat m = arma::ones<arma::mat>(n,k);
return m;
}
/*** R
Generate()
*/
It compiles and runs fine:
> Rcpp::sourceCpp("~/git/stackoverflow/67006975/answer.cpp")
> Generate()
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 1 1 1 1 1
[2,] 1 1 1 1 1 1
[3,] 1 1 1 1 1 1
[4,] 1 1 1 1 1 1
[5,] 1 1 1 1 1 1
>
I am new to VTK and trying to write a simple code for volumetric rendering. I used examples from the VTK website to write this following code.
#include <vtkNamedColors.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkNew.h>
#include <vtkStructuredPointsReader.h>
#include <vtkPiecewiseFunction.h>
#include <vtkSmartVolumeMapper.h>
#include <vtkColorTransferFunction.h>
#include <vtkVolume.h>
#include <vtkVolumeProperty.h>
int main( int argc, char* argv[] )
{
// Add named color library
vtkNew<vtkNamedColors> colors ;
// Create renderer
vtkNew<vtkRenderer> renderer ;
// Create a new render window
vtkNew<vtkRenderWindow> renWin ;
renWin->AddRenderer(renderer);
// Make the render window interacting
vtkNew<vtkRenderWindowInteractor> iren ;
iren->SetRenderWindow(renWin);
//Create a Structure Points or Image data reader and read the data
vtkNew<vtkStructuredPointsReader> reader;
reader->SetFileName (argv[1]);
reader->Update();
// For volume rendering, we need to first define a map from scalar values to
// colors and opacity (transparency) values. Then add these maps to volume
// property
// Add a piece-wise function for color transfer functions. Piece-wise means
// adding control (interpolation) points.
vtkNew<vtkPiecewiseFunction> opacityTransferFunction;
opacityTransferFunction->AddPoint(0,0.0);
opacityTransferFunction->AddPoint(50,0.0);
// Piece-wise function cannot be used for colors because colors are vectors
vtkNew<vtkColorTransferFunction> colorTransferFunction;
colorTransferFunction->AddRGBPoint(0,0.0,0.0,1.0);
colorTransferFunction->AddRGBPoint(25,1.0,0.0,0.0);
colorTransferFunction->AddRGBPoint(50,1.0,1.0,1.0);
// Set volume rendering properties
vtkNew<vtkVolumeProperty> volumeProperty;
volumeProperty->SetColor(colorTransferFunction);
volumeProperty->SetScalarOpacity(opacityTransferFunction);
volumeProperty->ShadeOn();
volumeProperty->SetInterpolationTypeToLinear();
// Add a mapper to create graphic primitives from the data
vtkNew<vtkSmartVolumeMapper> mapper;
mapper->SetBlendModeToComposite();
mapper->SetInputConnection(reader->GetOutputPort());
// Create a new actor(the actual graphics object) and add the mapped data to
// it
vtkNew<vtkVolume> volume;
volume->SetMapper(mapper);
volume->SetProperty(volumeProperty);
// Add the volume actor to the renderer
renderer->AddVolume(volume);
// Set the background color
renderer->SetBackground(colors->GetColor3d("Black").GetData());
// Set the size of the render window
renWin->SetSize(512,512);
// Render the data
renWin->Render();
// Start the interactor
iren->Start();
return EXIT_SUCCESS;
}
I am using the following data file.
# vtk DataFile Version 3.0
First time trying vtk import \n
ASCII
DATASET STRUCTURED_POINTS
DIMENSIONS 3 4 6
ORIGIN 0 0 0
SPACING 1 1 1
POINT_DATA 72
SCALARS volume_scalars unsigned_char 1
LOOKUP_TABLE default
0 0 0 0 0 0 0 0 0 0 0 0
0 5 10 15 20 25 25 20 15 10 5 0
0 10 20 30 40 50 50 40 30 20 10 0
0 10 20 30 40 50 50 40 30 20 10 0
0 5 10 15 20 25 25 20 15 10 5 0
0 0 0 0 0 0 0 0 0 0 0 0
I tried using this file in paraview and it worked perfectly. I was able to produce a nicely rendered 3D object. But, with the above VTK code, I only get a black screen with no volumetric plot. I created a simple points plot using PolyDataMapper in VTK for the same data and that worked fine as well. I am not sure what is wrong with this code and how I should correct it. Any help would be really appreciated.
I supposed mixed opacity with transparency, in any case setting opacity to 0 will result in nothing visible. This fixes it (I'll let you check what values you need for opacity depending on what appearence you expect):
opacityTransferFunction->AddPoint(0,0.1);
opacityTransferFunction->AddPoint(50,0.1);
I am new at MPI and parallel computing.I wrote simple MPI program in Fortran. But the problem is the MPI_FILE_READ_AT ignores and does not read the file.
My code is:
program O72
use mpi
!implicit none
INTEGER :: NINTS, DATATYPE, STATUS(MPI_STATUS_SIZE), mpierr, FH, i
integer :: taskid, no_tasks, FILESIZE, FILENO_2
INTEGER(KIND=MPI_OFFSET_KIND) :: OFFSET
INTEGER :: BUF(10)
character :: filename='ab.dat'
FILESIZE=10
BUF(:)=0
call MPI_INIT(mpierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD,no_tasks,mpierr)
call MPI_COMM_RANK(MPI_COMM_WORLD,taskid,mpierr)
NINTS = FILESIZE/no_tasks !*INTSIZE)
OFFSET= taskid*NINTS !*INTSIZE
call MPI_File_open(MPI_COMM_WORLD, "ab.dat", MPI_MODE_RDONLY, &
MPI_INFO_NULL, FH, mpierr)
call MPI_FILE_READ_AT(FH, OFFSET, BUF, NINTS, MPI_INT, STATUS, mpierr)
write(6,*) taskid, no_tasks
call MPI_BARRIER(MPI_COMM_WORLD, mpierr)
write(6,*) 'taskid=',taskid,'NINTS=', NINTS
write(6,*) 'taskid_',taskid,'OFFSET=',OFFSET
write(6,*) BUF(:)
!call MPI_FILE_WRITE(FILENO_2, OFFSET, BUF, NINTS, DATATYPE, STATUS, mpierr)
call MPI_FILE_CLOSE(FH, mpierr)
!call MPI_FILE_CLOSE(FILENO_2)
call MPI_FINALIZE(mpierr)
end
Then, the input file is an ASCII file with 2 columns in which 1st column is always 1 and 2nd column is always 2.
1 2
1 2
1 2
1 2
1 2
1 2
1 2
1 2
1 2
1 2
And the output comes like this with 2 processor used:
0 2
1 2
taskid= 1 NINTS= 5
taskid_ 1 OFFSET= 5
taskid= 0 NINTS= 5
taskid_ 0 OFFSET= 0
171051313 171051313 171051313 171051313 171051313 0 0 0 0 0
822751753 822751753 822751753 822751753 822751753 0 0 0 0 0
I don't understand where the problem is and why random values are assigned to BUF(:)
Could you please help me?
I guess the simple answer is that MPI-IO only performs binary IOs, while what you try to achieve here is formatted IOs.
So starting from here, you see that you have a few problems in your code:
You file is formatted. Since as I said in preamble, MPI-IO only performs binary IO, you'll have to, either switch to a binary input file, or to read the file as a set of strings which you'll have to make sense of internally. Let's assume for the rest of this post that your input file is now binary.
The offset to use in MPI_File_read_at() is expected in bytes. What you pass is a number of elements. You therefore need to multiply this offset by the size of what you want to read, aka the size of an integer.
Finally, you print the full of buf which is an array of 10 integer whereas you only read nints of them. You probably should only print buf(1:nints).
With that, your code should work.
If a text file contains numbers in 100 rows * 100 columns (for example). Now i want my program to pick up ,for example , one number from 60th row and 97th column and then assign this value to a variable and perform some calculation with this variable. So i want to pick up some random numbers from a text file which contains a lot of numbers. how can i do that??
I made a code for practice but its giving some error.
the text file contains 6 different digits in 2 rows and 3 columns
#include <iostream>
#include <fstream>
using namespace std;
int main ()
{
int data[6],i=0;
ifstream myfile;
myfile.open ("a.txt");
while (i<<6)
{
myfile>>data[i];
i=i+1;
}
myfile.close();
cout<<data[0]<<"\t"<<data[1]<<"\t"<<data[2]<<"\t"<<data[3]<<"\t"<<data[4]<<"\t" <<data[5]<<"\n";
system("pause");
return 0;
}
while (i < 6)
{
myfile>>data[i];
i=i+1;
}
I am learning to program in MPI and I came across this question. Lets say I have a .txt file with 100,000 rows/lines, how do I chunk them for processing by 4 processors? i.e. I want to let processor 0 take care of the processing for lines 0-25000, processor 1 to take care of 25001-50000 and so on. I did some searching and did came across MPI_File_seek but I am not sure can it work on .txt and supports fscanf afterwards.
Text isn't a great format for parallel processing exactly because you don't know ahead of time where (say) line 25001 begins. So these sorts of problems are often dealt with ahead of time through some preprocessing step, either building an index or partitioning the file into the appropriate number of chunks for each process to read.
If you really want to do it through MPI, I'd suggest using MPI-IO to read in overlapping chunks of the text file onto the various processors, where the overlap is much longer than you expect your longest line to be, and then have each processor agree on where to start; eg, you could say that the first (or last) new line in the overlap region shared by processes N and N+1 is where process N leaves off and N+1 starts.
To follow this up with some code,
#include <stdio.h>
#include <mpi.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
void parprocess(MPI_File *in, MPI_File *out, const int rank, const int size, const int overlap) {
MPI_Offset globalstart;
int mysize;
char *chunk;
/* read in relevant chunk of file into "chunk",
* which starts at location in the file globalstart
* and has size mysize
*/
{
MPI_Offset globalend;
MPI_Offset filesize;
/* figure out who reads what */
MPI_File_get_size(*in, &filesize);
filesize--; /* get rid of text file eof */
mysize = filesize/size;
globalstart = rank * mysize;
globalend = globalstart + mysize - 1;
if (rank == size-1) globalend = filesize-1;
/* add overlap to the end of everyone's chunk except last proc... */
if (rank != size-1)
globalend += overlap;
mysize = globalend - globalstart + 1;
/* allocate memory */
chunk = malloc( (mysize + 1)*sizeof(char));
/* everyone reads in their part */
MPI_File_read_at_all(*in, globalstart, chunk, mysize, MPI_CHAR, MPI_STATUS_IGNORE);
chunk[mysize] = '\0';
}
/*
* everyone calculate what their start and end *really* are by going
* from the first newline after start to the first newline after the
* overlap region starts (eg, after end - overlap + 1)
*/
int locstart=0, locend=mysize-1;
if (rank != 0) {
while(chunk[locstart] != '\n') locstart++;
locstart++;
}
if (rank != size-1) {
locend-=overlap;
while(chunk[locend] != '\n') locend++;
}
mysize = locend-locstart+1;
/* "Process" our chunk by replacing non-space characters with '1' for
* rank 1, '2' for rank 2, etc...
*/
for (int i=locstart; i<=locend; i++) {
char c = chunk[i];
chunk[i] = ( isspace(c) ? c : '1' + (char)rank );
}
/* output the processed file */
MPI_File_write_at_all(*out, (MPI_Offset)(globalstart+(MPI_Offset)locstart), &(chunk[locstart]), mysize, MPI_CHAR, MPI_STATUS_IGNORE);
return;
}
int main(int argc, char **argv) {
MPI_File in, out;
int rank, size;
int ierr;
const int overlap = 100;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (argc != 3) {
if (rank == 0) fprintf(stderr, "Usage: %s infilename outfilename\n", argv[0]);
MPI_Finalize();
exit(1);
}
ierr = MPI_File_open(MPI_COMM_WORLD, argv[1], MPI_MODE_RDONLY, MPI_INFO_NULL, &in);
if (ierr) {
if (rank == 0) fprintf(stderr, "%s: Couldn't open file %s\n", argv[0], argv[1]);
MPI_Finalize();
exit(2);
}
ierr = MPI_File_open(MPI_COMM_WORLD, argv[2], MPI_MODE_CREATE|MPI_MODE_WRONLY, MPI_INFO_NULL, &out);
if (ierr) {
if (rank == 0) fprintf(stderr, "%s: Couldn't open output file %s\n", argv[0], argv[2]);
MPI_Finalize();
exit(3);
}
parprocess(&in, &out, rank, size, overlap);
MPI_File_close(&in);
MPI_File_close(&out);
MPI_Finalize();
return 0;
}
Running this on a narrow version of the text of the question, we get
$ mpirun -n 3 ./textio foo.in foo.out
$ paste foo.in foo.out
Hi guys I am learning to 11 1111 1 11 11111111 11
program in MPI and I came 1111111 11 111 111 1 1111
across this question. Lets 111111 1111 111111111 1111
say I have a .txt file with 111 1 1111 1 1111 1111 1111
100,000 rows/lines, how do 1111111 11111111111 111 11
I chunk them for processing 1 11111 1111 111 1111111111
by 4 processors? i.e. I want 22 2 22222222222 2222 2 2222
to let processor 0 take care 22 222 222222222 2 2222 2222
of the processing for lines 22 222 2222222222 222 22222
0-25000, processor 1 to take 22222222 222222222 2 22 2222
care of 25001-50000 and so 2222 22 22222222222 222 22
on. I did some searching and 333 3 333 3333 333333333 333
did came across MPI_File_seek 333 3333 333333 3333333333333
but I am not sure can it work 333 3 33 333 3333 333 33 3333
on .txt and supports fscanf 33 3333 333 33333333 333333
afterwards. 33333333333