119 string outputMeshName =
"VelSlice";
121 if (out.open(fname,MPI_COMM_SELF,0) ==
false) {
122 cerr <<
"ERROR, failed to open output file with vlsv::Writer at " << __FILE__ <<
" " << __LINE__ << endl;
126 std::vector<uint64_t> cellIDs;
127 if (vlsvReader.
getCellIds(cellIDs) ==
false) {
128 cerr <<
"ERROR: failed to get cell IDs in " << __FILE__ <<
' ' << __LINE__ << endl;
135 dims[0] = 1; dims[1] = 2;
138 dims[0] = 0; dims[1] = 2;
141 dims[0] = 0; dims[1] = 1;
144 bbox[3]=1; bbox[4]=1; bbox[5]=4;
151 cerr <<
"ERROR: failed to init AMR mesh in " << __FILE__ <<
' ' << __LINE__ << endl;
157 const string attributeName =
"name";
158 if (vlsvReader.getUniqueAttributeValues(
"BLOCKVARIABLE",attributeName,blockVarNames) ==
false) {
159 cerr <<
"ERROR, FAILED TO GET UNIQUE ATTRIBUTE VALUES AT " << __FILE__ <<
" " << __LINE__ << endl;
162 struct BlockVarInfo {
164 vlsv::datatype::type dataType;
168 std::vector<BlockVarInfo> varInfo;
172 std::vector<float> nodeCoords;
173 std::vector<int> connectivity;
174 std::vector<std::vector<char> > variables;
175 for (
size_t cell=0; cell<cellIDs.size(); ++cell) {
176 uint64_t cellId = cellIDs[cell]-1;
177 uint64_t cellIndices[3];
178 cellIndices[0] = cellId % cellStruct.
cell_bounds[0];
191 std::vector<char*> varBuffer(blockVarNames.size());
194 varBuffer[counter] = NULL;
196 varBuffer[counter] = NULL;
204 list<pair<string,string> > attribs;
205 attribs.push_back(make_pair(
"name",*var));
206 attribs.push_back(make_pair(
"mesh",meshName));
210 if (vlsvReader.getArrayInfo(
"BLOCKVARIABLE",attribs,arraySize,vinfo.vectorSize,vinfo.dataType,vinfo.dataSize) ==
false) {
211 cerr <<
"Could not read BLOCKVARIABLE array info" << endl;
213 varInfo.push_back(vinfo);
215 if (varInfo.size() > variables.size()) variables.resize(varInfo.size());
217 std::vector<uint64_t> blockIDs;
218 if (vlsvReader.
getBlockIds(cellIDs[cell],blockIDs,popName) ==
false) {
219 for (
size_t v=0; v<varBuffer.size(); ++v)
delete [] varBuffer[v];
224 for (
size_t b=0; b<blockIDs.size(); ++b) {
225 uint64_t blockGID = blockIDs[b];
229 uint32_t blockIndices[3];
230 vlsv::calculateCellIndices(blockGID,refLevel,blockIndices[0],blockIndices[1],blockIndices[2]);
231 uint32_t refMul = pow(2,refLevel);
235 Real minBlockCoords[3];
236 Real maxBlockCoords[3];
237 for (
int i=0;
i<3; ++
i) {
251 for (
int i=0;
i<4; ++
i) {
252 const size_t offset = nodeCoords.size()/3;
253 nodeCoords.push_back(cellCrds[dims[0] ]); nodeCoords.push_back(cellCrds[dims[1] ]); nodeCoords.push_back(minBlockCoords[dims[2]-3]+
i*DV_cell);
254 nodeCoords.push_back(cellCrds[dims[0]+3]); nodeCoords.push_back(cellCrds[dims[1] ]); nodeCoords.push_back(minBlockCoords[dims[2]-3]+
i*DV_cell);
255 nodeCoords.push_back(cellCrds[dims[0] ]); nodeCoords.push_back(cellCrds[dims[1]+3]); nodeCoords.push_back(minBlockCoords[dims[2]-3]+
i*DV_cell);
256 nodeCoords.push_back(cellCrds[dims[0]+3]); nodeCoords.push_back(cellCrds[dims[1]+3]); nodeCoords.push_back(minBlockCoords[dims[2]-3]+
i*DV_cell);
257 nodeCoords.push_back(cellCrds[dims[0] ]); nodeCoords.push_back(cellCrds[dims[1] ]); nodeCoords.push_back(minBlockCoords[dims[2]-3]+(
i+1)*DV_cell);
258 nodeCoords.push_back(cellCrds[dims[0]+3]); nodeCoords.push_back(cellCrds[dims[1] ]); nodeCoords.push_back(minBlockCoords[dims[2]-3]+(
i+1)*DV_cell);
259 nodeCoords.push_back(cellCrds[dims[0] ]); nodeCoords.push_back(cellCrds[dims[1]+3]); nodeCoords.push_back(minBlockCoords[dims[2]-3]+(
i+1)*DV_cell);
260 nodeCoords.push_back(cellCrds[dims[0]+3]); nodeCoords.push_back(cellCrds[dims[1]+3]); nodeCoords.push_back(minBlockCoords[dims[2]-3]+(
i+1)*DV_cell);
262 connectivity.push_back(vlsv::celltype::VOXEL);
263 connectivity.push_back(8);
264 for (
int j=0;
j<8; ++
j) connectivity.push_back(offset+
j);
273 for (
size_t v=0; v<varBuffer.size(); ++v) {
274 uint64_t entrySize = varInfo[v].vectorSize*varInfo[v].dataSize;
275 char* baseptr = &(varBuffer[v][0]) + b*entrySize;
277 for (
int i=0;
i<4; ++
i) {
278 char* varptr = baseptr +
i*varInfo[v].dataSize;
282 for (uint64_t dummy=0; dummy<varInfo[v].dataSize; ++dummy) variables[v].push_back(varptr[dummy]);
285 for (uint64_t dummy=0; dummy<varInfo[v].dataSize; ++dummy) variables[v].push_back(varptr[dummy]);
288 for (uint64_t dummy=0; dummy<varInfo[v].dataSize; ++dummy) variables[v].push_back(varptr[dummy]);
296 for (
size_t v=0; v<varBuffer.size(); ++v)
delete [] varBuffer[v];
301 attributes[
"type"] = vlsv::mesh::STRING_UCD_GENERIC_MULTI;
306 if (out.writeArray(
"MESH",
attributes,connectivity.size(),1,&(connectivity[0])) ==
false) success =
false;
310 if (out.writeArray(
"MESH_NODE_CRDS",
attributes,nodeCoords.size()/3,3,&(nodeCoords[0])) ==
false) success =
false;
312 bbox[0]=1; bbox[1]=1; bbox[2]=1; bbox[3]=1; bbox[4]=1; bbox[5]=1;
313 if (out.writeArray(
"MESH_BBOX",
attributes,6,1,bbox) ==
false) success =
false;
315 uint32_t offsetEntries[vlsv::ucdgenericmulti::offsets::SIZE];
316 offsetEntries[vlsv::ucdgenericmulti::offsets::ZONE_ENTRIES] = connectivity.size();
317 offsetEntries[vlsv::ucdgenericmulti::offsets::NODE_ENTRIES] = nodeCoords.size()/3;
318 if (out.writeArray(
"MESH_OFFSETS",
attributes,1,vlsv::ucdgenericmulti::offsets::SIZE,offsetEntries) ==
false) success=
false;
320 uint32_t domainSize[vlsv::ucdgenericmulti::domainsizes::SIZE];
321 domainSize[vlsv::ucdgenericmulti::domainsizes::TOTAL_BLOCKS] = connectivity.size()/10;
322 domainSize[vlsv::ucdgenericmulti::domainsizes::GHOST_BLOCKS] = 0;
323 domainSize[vlsv::ucdgenericmulti::domainsizes::TOTAL_NODES] = nodeCoords.size()/3;
324 domainSize[vlsv::ucdgenericmulti::domainsizes::GHOST_NODES] = 0;
325 if (out.writeArray(
"MESH_DOMAIN_SIZES",
attributes,1,vlsv::ucdgenericmulti::domainsizes::SIZE,domainSize) ==
false) success =
false;
327 for (
size_t v=0; v<variables.size(); ++v) {
328 uint64_t vectorSize = varInfo[v].vectorSize/64;
329 uint64_t entrySize = vectorSize*varInfo[v].dataSize;
330 uint64_t arraySize = variables[v].size() / entrySize;
331 if (variables[v].size() % entrySize != 0) {
332 cerr <<
"Error in variable array size in " << __FILE__ <<
' ' << __LINE__ << endl;
337 char* ptr =
reinterpret_cast<char*
>(&(variables[v][0]));
338 if (out.writeArray(
"VARIABLE",
attributes,vlsv::getStringDatatype(varInfo[v].dataType),arraySize,vectorSize,varInfo[v].dataSize,ptr) ==
false) {
339 cerr <<
"Failed to write variable '" << varInfo[v].name <<
"' to sliced velocity mesh" << endl;
378 Matrix<Real, _size, 1> _B(B[0], B[1], B[2]);
379 Matrix<Real, _size, 1> unit_z(0, 0, 1);
380 Matrix<Real, _size, 1> Bxu = _B.cross( unit_z );
384 if ( (Bxu[0]*Bxu[0] + Bxu[1]*Bxu[1] + Bxu[2]*Bxu[2]) != 0 ) {
386 Matrix<Real, _size, 1> axisDir = Bxu/(
sqrt(Bxu[0]*Bxu[0] + Bxu[1]*Bxu[1] + Bxu[2]*Bxu[2]));
389 rotAngle = -1 * acos(_B[2] /
sqrt(_B[0]*_B[0] + _B[1]*_B[1] + _B[2]*_B[2]));
392 Transform<Real, _size, _size> rotationMatrix( AngleAxis<Real>(rotAngle, axisDir) );
396 for (
int i=0;
i<16; ++
i) Rot[
i] = 0;
401 for (
int j=0;
j<3; ++
j)
for (
int i=0;
i<3; ++
i) Rot[
j*4+
i] = rotationMatrix(
i,
j);
405 for (
int i=0;
i<16; ++
i) T[
i] = transform[
i];
408 for (
int k=0;
k<4; ++
k) {
409 for (
int i=0;
i<4; ++
i) {
410 transform[
k*4+
i] = 0;
411 for (
int j=0;
j<4; ++
j) {
412 transform[
k*4+
i] += Rot[
k*4+
j]*T[
j*4+
i];
419 cerr <<
"***** DEBUGGING INFO FOR applyRotation() *****" << endl;
420 cerr <<
"B = " << B[0] <<
'\t' << B[1] <<
'\t' << B[2] << endl;
421 cerr <<
"rotAngle is " << 180.0/M_PI*rotAngle <<
" degrees " << endl;
423 cerr <<
"transform matrix components:" << endl;
424 for (
int k=0;
k<4; ++
k) {
426 for (
int i=0;
i<4; ++
i) {
427 cerr << transform[
k*4+
i] <<
'\t';
434 B_rot[0] = transform[0]*B[0] + transform[1]*B[1] + transform[2 ]*B[2];
435 B_rot[1] = transform[4]*B[0] + transform[5]*B[1] + transform[6 ]*B[2];
436 B_rot[2] = transform[8]*B[0] + transform[9]*B[1] + transform[10]*B[2];
437 Real B_mag =
sqrt(B[0]*B[0] + B[1]*B[1] + B[2]*B[2]);
438 Real B_rot_mag =
sqrt(B_rot[0]*B_rot[0] + B_rot[1]*B_rot[1] + B_rot[2]*B_rot[2]);
440 cerr <<
"magnitude B = " << B_mag << endl;
441 cerr <<
"magnitude B (rotated) = " << B_rot_mag << endl;
442 cerr <<
"abs difference = " << fabs(B_mag-B_rot_mag) << endl;
445 cerr <<
"Rotated B direction = " << B_rot[0]/B_rot_mag <<
'\t' << B_rot[1]/B_rot_mag <<
'\t' << B_rot[2]/B_rot_mag << endl;
452 vlsv::datatype::type cellIdDataType;
453 uint64_t cellIdArraySize, cellIdVectorSize, cellIdDataSize;
455 list<pair<string,string> > xmlAttributes;
456 xmlAttributes.push_back(make_pair(
"mesh",meshName));
457 xmlAttributes.push_back(make_pair(
"name",
"CellID"));
458 if (vlsvReader.getArrayInfo(
"VARIABLE", xmlAttributes, cellIdArraySize, cellIdVectorSize, cellIdDataType, cellIdDataSize) ==
false) {
459 cerr <<
"Error " << __FILE__ <<
" " << __LINE__ << endl;
464 uint64_t* cellIdBuffer = NULL;
468 if (vlsvReader.read(
"VARIABLE",xmlAttributes,0,cellIdArraySize,cellIdBuffer,
true) ==
false) {
469 cerr <<
"Error: failed to read cell IDs in " << __FILE__ <<
":" << __LINE__ << endl;
470 delete [] cellIdBuffer;
478 uint64_t
cellIndex = numeric_limits<uint64_t>::max();
479 for (uint64_t cell=0; cell<cellIdArraySize; ++cell) {
482 if (cellID == cellIdBuffer[cell]) {
487 delete [] cellIdBuffer; cellIdBuffer = NULL;
490 if (
cellIndex == numeric_limits<uint64_t>::max()) {
491 cerr <<
"Spatial cell #" << cellID <<
" not found in " << __FILE__ <<
":" << __LINE__ << endl;
498 double* ptr = velocity;
499 xmlAttributes.clear();
500 xmlAttributes.push_back(make_pair(
"mesh",meshName));
501 xmlAttributes.push_back(make_pair(
"name",
"vg_v"));
502 if (vlsvReader.read(
"VARIABLE",xmlAttributes,
cellIndex,1,ptr,
false) ==
true) {
503 cerr <<
"NOTE: Using combined vg_v (all populations!) for plasma frame shifting." << endl;
504 V_bulk[0] = velocity[0];
505 V_bulk[0] = velocity[0];
506 V_bulk[0] = velocity[0];
510 xmlAttributes.clear();
511 xmlAttributes.push_back(make_pair(
"mesh",meshName));
512 xmlAttributes.push_back(make_pair(
"name",popName+
"/vg_v"));
513 if (vlsvReader.read(
"VARIABLE",xmlAttributes,
cellIndex,1,ptr,
false) ==
true) {
514 cerr <<
"NOTE: Using <pop>/vg_v for plasma frame shifting." << endl;
515 V_bulk[0] = velocity[0];
516 V_bulk[0] = velocity[0];
517 V_bulk[0] = velocity[0];
522 double numberDensity;
523 ptr = &numberDensity;
524 xmlAttributes.clear();
525 xmlAttributes.push_back(make_pair(
"mesh",meshName));
526 xmlAttributes.push_back(make_pair(
"name",
"rho"));
527 if (vlsvReader.read(
"VARIABLE",xmlAttributes,
cellIndex,1,ptr,
false) ==
true) {
531 xmlAttributes.clear();
532 xmlAttributes.push_back(make_pair(
"mesh",meshName));
533 xmlAttributes.push_back(make_pair(
"name",
"rho_v"));
534 if (vlsvReader.read(
"VARIABLE",xmlAttributes,
cellIndex,1,ptr,
false) ==
true) {
535 cerr <<
"NOTE: Using rho_v / rho for plasma frame shifting." << endl;
536 V_bulk[0] = momentum[0] / (numberDensity + numeric_limits<double>::min());
537 V_bulk[1] = momentum[1] / (numberDensity + numeric_limits<double>::min());
538 V_bulk[2] = momentum[2] / (numberDensity + numeric_limits<double>::min());
545 xmlAttributes.clear();
546 xmlAttributes.push_back(make_pair(
"mesh",meshName));
547 xmlAttributes.push_back(make_pair(
"name",
"moments"));
548 if (vlsvReader.read(
"VARIABLE",xmlAttributes,
cellIndex,1,ptr,
false) ==
true) {
549 cerr <<
"NOTE: Using combined vg_v (all populations!) from restart for plasma frame shifting." << endl;
550 V_bulk[0] = moments[1];
551 V_bulk[0] = moments[2];
552 V_bulk[0] = moments[3];
556 cerr <<
"ERROR: Could not find a usable velocity for plasma frame shift!" << endl;
565 vlsv::datatype::type cellIdDataType;
566 uint64_t cellIdArraySize, cellIdVectorSize, cellIdDataSize;
568 list<pair<string,string> > xmlAttributes;
569 xmlAttributes.push_back(make_pair(
"mesh",meshName));
570 xmlAttributes.push_back(make_pair(
"name",
"CellID"));
571 if (vlsvReader.getArrayInfo(
"VARIABLE", xmlAttributes, cellIdArraySize, cellIdVectorSize, cellIdDataType, cellIdDataSize) ==
false) {
572 cerr <<
"Error " << __FILE__ <<
" " << __LINE__ << endl;
577 uint64_t* cellIdBuffer = NULL;
581 if (vlsvReader.read(
"VARIABLE",xmlAttributes,0,cellIdArraySize,cellIdBuffer,
true) ==
false) {
582 cerr <<
"Error: failed to read cell IDs in " << __FILE__ <<
":" << __LINE__ << endl;
583 delete [] cellIdBuffer;
591 uint64_t
cellIndex = numeric_limits<uint64_t>::max();
592 for (uint64_t cell=0; cell<cellIdArraySize; ++cell) {
595 if (cellID == cellIdBuffer[cell]) {
600 delete [] cellIdBuffer; cellIdBuffer = NULL;
603 if (
cellIndex == numeric_limits<uint64_t>::max()) {
604 cerr <<
"Spatial cell #" << cellID <<
" not found in " << __FILE__ <<
":" << __LINE__ << endl;
609 vlsv::datatype::type variableDataType;
610 uint64_t variableArraySize, variableVectorSize, variableDataSize;
621 double B1[3] = {0,0,0};
622 double B2[3] = {0,0,0};
627 if (
runDebug ==
true) cerr <<
"***** DEBUG INFO FOR getB() *****" << endl;
633 xmlAttributes.clear();
634 xmlAttributes.push_back(make_pair(
"mesh",meshName));
635 xmlAttributes.push_back(make_pair(
"name",
"vg_b_vol"));
636 if (vlsvReader.read(
"VARIABLE",xmlAttributes,
cellIndex,1,B1_ptr,
false) ==
false) B_read =
false;
637 if (B_read ==
true) {
638 if (
runDebug ==
true) cerr <<
"Using vg_b_vol" << endl;
644 xmlAttributes.clear();
645 xmlAttributes.push_back(make_pair(
"mesh",meshName));
646 xmlAttributes.push_back(make_pair(
"name",
"vg_b_background_vol"));
647 if (vlsvReader.read(
"VARIABLE",xmlAttributes,
cellIndex,1,B1_ptr,
false) ==
false) B_read =
false;
648 xmlAttributes.clear();
649 xmlAttributes.push_back(make_pair(
"mesh",meshName));
650 xmlAttributes.push_back(make_pair(
"name",
"vg_b_perturbed_vol"));
651 if (vlsvReader.read(
"VARIABLE",xmlAttributes,
cellIndex,1,B2_ptr,
false) ==
false) B_read =
false;
652 if (B_read ==
true) {
653 if (
runDebug ==
true) cerr <<
"Using vg_b_background_vol + vg_b_perturbed_vol" << endl;
659 xmlAttributes.clear();
660 xmlAttributes.push_back(make_pair(
"mesh",meshName));
661 xmlAttributes.push_back(make_pair(
"name",
"B_vol"));
662 if (vlsvReader.read(
"VARIABLE",xmlAttributes,
cellIndex,1,B1_ptr,
false) ==
false) B_read =
false;
663 if (B_read ==
true) {
664 if (
runDebug ==
true) cerr <<
"Using B_vol" << endl;
670 xmlAttributes.clear();
671 xmlAttributes.push_back(make_pair(
"mesh",meshName));
672 xmlAttributes.push_back(make_pair(
"name",
"BGB_vol"));
673 if (vlsvReader.read(
"VARIABLE",xmlAttributes,
cellIndex,1,B1_ptr,
false) ==
false) B_read =
false;
674 xmlAttributes.clear();
675 xmlAttributes.push_back(make_pair(
"mesh",meshName));
676 xmlAttributes.push_back(make_pair(
"name",
"PERB_vol"));
677 if (vlsvReader.read(
"VARIABLE",xmlAttributes,
cellIndex,1,B2_ptr,
false) ==
false) B_read =
false;
678 if (B_read ==
true) {
679 if (
runDebug ==
true) cerr <<
"Using BGB_vol + PERB_vol" << endl;
685 xmlAttributes.clear();
686 xmlAttributes.push_back(make_pair(
"mesh",meshName));
687 xmlAttributes.push_back(make_pair(
"name",
"B"));
688 if (vlsvReader.read(
"VARIABLE",xmlAttributes,
cellIndex,1,B1_ptr,
false) ==
false) B_read =
false;
689 if (B_read ==
true) {
690 if (
runDebug ==
true) cerr <<
"Using B" << endl;
696 xmlAttributes.clear();
697 xmlAttributes.push_back(make_pair(
"mesh",meshName));
698 xmlAttributes.push_back(make_pair(
"name",
"background_B"));
699 if (vlsvReader.read(
"VARIABLE",xmlAttributes,
cellIndex,1,B1_ptr,
false) ==
false) B_read =
false;
700 xmlAttributes.clear();
701 xmlAttributes.push_back(make_pair(
"mesh",meshName));
702 xmlAttributes.push_back(make_pair(
"name",
"perturbed_B"));
703 if (vlsvReader.read(
"VARIABLE",xmlAttributes,
cellIndex,1,B2_ptr,
false) ==
false) B_read =
false;
704 if (B_read ==
true) {
705 if (
runDebug ==
true) cerr <<
"Using background_B + perturbed_B" << endl;
712 if (B_read ==
false) {
713 cerr <<
"Failed to read magnetic field in " << __FILE__ <<
" " << __LINE__ << endl;
717 for (
int i=0;
i<3; ++
i) B[
i] = B1[
i] + B2[
i];
720 cerr <<
"B1 = " << B1[0] <<
'\t' << B1[1] <<
'\t' << B1[2] << endl;
721 cerr <<
"B2 = " << B2[0] <<
'\t' << B2[1] <<
'\t' << B2[2] << endl;
722 cerr <<
"B = " << B[0] <<
'\t' << B[1] <<
'\t' << B[2] << endl;
730 const string& meshName,
732 const uint64_t& cellID,
734 const bool plasmaFrame,
736 const std::string& popName
745 cerr <<
"Trying older Vlasiator file format..." << endl;
747 cerr <<
"ERROR, failed to read velocity mesh metadata in " << __FILE__ <<
":" << __LINE__ << endl;
753 string outputMeshName =
"VelGrid_" + popName;
754 int cellsInBlocksPerDirection = 4;
759 for (
int i=0;
i<16; ++
i) transform[
i] = 0;
765 if (plasmaFrame ==
true) {
772 if (rotate ==
true) {
775 getB(B,vlsvReader,meshName,cellID);
779 if (plasmaFrame ==
true || rotate ==
true) {
782 if (out.writeArray(
"TRANSFORM",
attributes,16,1,transform) ==
false) success =
false;
786 std::vector<uint64_t> blockIds;
787 if (vlsvReader.
getBlockIds(cellID,blockIds,popName) ==
false ) {
788 cerr <<
"Trying older Vlasiator file format..." << endl;
789 if (vlsvReader.
getBlockIds(cellID,blockIds,
"") ==
false) {
790 cerr <<
"ERROR, failed to read IDs at " << __FILE__ <<
":" << __LINE__ << endl;
795 const size_t N_blocks = blockIds.size();
799 attributes[
"type"] = vlsv::mesh::STRING_UCD_AMR;
802 attributes[
"max_refinement_level"] = ss.str();
803 attributes[
"geometry"] = vlsv::geometry::STRING_CARTESIAN;
804 if (plasmaFrame ==
true || rotate ==
true)
attributes[
"transform"] =
"transmat";
806 if (out.writeArray(
"MESH",
attributes,blockIds.size(),1,&(blockIds[0])) ==
false) success =
false;
809 if (out.writeArray(
"MESH",
attributes,blockIds.size(),1,&(blockIds[0])) ==
false) success =
false;
815 std::vector<uint64_t> cellIDs(blockIds.size()*64);
816 for (
size_t b=0; b<blockIds.size(); ++b) {
817 for (
int c=0;
c<64; ++
c) cellIDs[b*64+
c] = blockIds[b]*64+
c;
821 if (out.writeArray(
"VARIABLE",
attributes,cellIDs.size(),1,&(cellIDs[0])) ==
false) success =
false;
825 uint64_t domainSize[2];
826 domainSize[0] = blockIds.size();
829 if (out.writeArray(
"MESH_DOMAIN_SIZES",
attributes,1,2,domainSize) ==
false) success =
false;
831 std::vector<uint64_t> ().swap(blockIds);
835 if (out.writeArray(
"MESH_DOMAIN_SIZES",
attributes,1,2,domainSize) ==
false) success =
false;
847 if (out.writeArray(
"MESH_BBOX",
attributes,6,1,bbox) ==
false) success =
false;
849 bbox[3] = cellsInBlocksPerDirection;
850 bbox[4] = cellsInBlocksPerDirection;
851 bbox[5] = cellsInBlocksPerDirection;
852 const uint32_t
blockSize = bbox[3]*bbox[4]*bbox[5];
854 if (out.writeArray(
"MESH_BBOX",
attributes,6,1,bbox) ==
false) success =
false;
857 std::vector<float> coords;
858 for (
int crd=0; crd<3; ++crd) {
863 for (
size_t i=0;
i<bbox[crd]; ++
i) {
864 for (
size_t j=0;
j<bbox[crd+3]; ++
j) {
872 if (crd == 0) arrayName =
"MESH_NODE_CRDS_X";
873 else if (crd == 1) arrayName =
"MESH_NODE_CRDS_Y";
874 else if (crd == 2) arrayName =
"MESH_NODE_CRDS_Z";
876 if (coords.size() != bbox[crd]*bbox[crd+3]+1) {
877 cerr <<
"ERROR incorrect node coordinates at " << __FILE__ <<
" " << __LINE__ << endl;
881 if (out.writeArray(arrayName,
attributes,coords.size(),1,&(coords[0])) ==
false) {
882 cerr <<
"ERROR, failed to write velocity grid coordinates in " << __FILE__ <<
":" << __LINE__ << endl;
887 std::vector<float> ().swap(coords);
890 for (
int crd=0; crd<3; ++crd) {
892 for (
size_t i=0;
i<bbox[crd]; ++
i) {
898 if (crd == 0) arrayName =
"MESH_NODE_CRDS_X";
899 else if (crd == 1) arrayName =
"MESH_NODE_CRDS_Y";
900 else if (crd == 2) arrayName =
"MESH_NODE_CRDS_Z";
903 if (out.writeArray(arrayName,
attributes,coords.size(),1,&(coords[0])) ==
false) {
904 cerr <<
"ERROR, failed to write velocity block coordinates in " << __FILE__ <<
":" << __LINE__ << endl;
909 std::vector<float> ().swap(coords);
915 if (out.writeArray(
"MESH_GHOST_LOCALIDS",
attributes,domainSize[1],1,&dummy) ==
false) {
916 cerr <<
"ERROR, failed to write ghost cell local IDs in " << __FILE__ <<
":" << __LINE__ << endl;
919 if (out.writeArray(
"MESH_GHOST_DOMAINS",
attributes,domainSize[1],1,&dummy) ==
false) {
920 cerr <<
"ERROR, failed to write ghost cell domains in " << __FILE__ <<
":" << __LINE__ << endl;
925 if (out.writeArray(
"MESH_GHOST_LOCALIDS",
attributes,domainSize[1],1,&dummy) ==
false) {
926 cerr <<
"ERROR, failed to write ghost cell local IDs in " << __FILE__ <<
":" << __LINE__ << endl;
929 if (out.writeArray(
"MESH_GHOST_DOMAINS",
attributes,domainSize[1],1,&dummy) ==
false) {
930 cerr <<
"ERROR, failed to write ghost cell domains in " << __FILE__ <<
":" << __LINE__ << endl;
939 const string attributeName =
"name";
940 if (vlsvReader.getUniqueAttributeValues(
"BLOCKVARIABLE", attributeName, blockVarNames) ==
false) {
941 cerr <<
"ERROR, FAILED TO GET UNIQUE ATTRIBUTE VALUES AT " << __FILE__ <<
" " << __LINE__ << endl;
945 if (success ==
true) {
948 if (*it != popName)
continue;
950 list<pair<string, string> > attribs;
951 attribs.push_back(make_pair(
"name", *it));
952 attribs.push_back(make_pair(
"mesh", meshName));
953 datatype::type dataType;
954 uint64_t arraySize, vectorSize, dataSize;
955 if (vlsvReader.getArrayInfo(
"BLOCKVARIABLE", attribs, arraySize, vectorSize, dataType, dataSize) ==
false) {
956 cerr <<
"Could not read BLOCKVARIABLE array info in " << __FILE__ <<
":" << __LINE__ << endl;
960 char* buffer =
new char[N_blocks * vectorSize * dataSize];
961 if (vlsvReader.readArray(
"BLOCKVARIABLE", attribs, vlsvReader.
getBlockOffset(cellID), N_blocks, buffer) ==
false) {
962 cerr <<
"ERROR could not read block variable in " << __FILE__ <<
":" << __LINE__ << endl;
969 if (out.writeArray(
"VARIABLE",
971 vlsv::getStringDatatype(dataType),
975 buffer) ==
false) success =
false;
977 delete [] buffer; buffer = NULL;
1305 const std::string& popName) {
1306 bool success =
true;
1308 Real vx_min=0,vx_max=0,vy_min=0,vy_max=0,
vz_min=0,vz_max=0;
1311 for (
int crd=0; crd<3; ++crd) {
1312 list<pair<string,string> > attribsIn;
1313 attribsIn.push_back(make_pair(
"mesh",popName));
1316 if (crd == 0) tagName =
"MESH_NODE_CRDS_X";
1317 if (crd == 1) tagName =
"MESH_NODE_CRDS_Y";
1318 if (crd == 2) tagName =
"MESH_NODE_CRDS_Z";
1321 map<string,string> attribsOut;
1322 if (vlsvReader.getArrayAttributes(tagName,attribsIn,attribsOut) ==
false) {
1323 success =
false;
continue;
1327 uint64_t N_nodes = 0;
1328 map<string,string>::const_iterator it = attribsOut.find(
"arraysize");
1329 if (it != attribsOut.end()) N_nodes = atol(it->second.c_str());
1333 if (vlsvReader.read(tagName,attribsIn,0,N_nodes,crds,
true) ==
false) success =
false;
1335 if (crd == 0) { vx_min = crds[0]; vx_max = crds[N_nodes-1]; }
1336 if (crd == 1) { vy_min = crds[0]; vy_max = crds[N_nodes-1]; }
1337 if (crd == 2) {
vz_min = crds[0]; vz_max = crds[N_nodes-1]; }
1338 delete [] crds; crds = NULL;
1342 list<pair<string,string> > attribs;
1343 attribs.push_back(make_pair(
"mesh",popName));
1344 uint64_t velMeshBbox[6];
1345 uint64_t* velMeshBbox_ptr = velMeshBbox;
1346 if (vlsvReader.read(
"MESH_BBOX",attribs,0,6,velMeshBbox_ptr,
false) ==
false) {
1347 cerr <<
"Failed to read velocity mesh BBOX in " << __FILE__ <<
":" << __LINE__ << endl;
1352 for (
int i = 0;
i<3; ++
i) {
1357 Real vx_length = vx_max - vx_min;
1358 Real vy_length = vy_max - vy_min;
1373 map<string,string> attribsOut;
1374 vlsvReader.getArrayAttributes(
"MESH_BBOX",attribs,attribsOut);
1375 if (attribsOut.find(
"max_velocity_ref_level") != attribsOut.end()) {
1376 cellStruct.
maxVelRefLevel = atoi(attribsOut[
"max_velocity_ref_level"].c_str());
1379 if (
runDebug ==
true && success ==
true) {
1380 cerr <<
"Pop '" << popName <<
"'" << endl;
1381 cerr <<
"\t mesh limits : ";
1382 cerr << vx_min <<
'\t' << vx_max <<
'\t' << vy_min <<
'\t' << vy_max <<
'\t' <<
vz_min <<
'\t' << vz_max << endl;
1383 cerr <<
"\t mesh bbox size: " << velMeshBbox[0] <<
' ' << velMeshBbox[1] <<
' ' << velMeshBbox[2] << endl;
1385 cerr <<
"\t max ref level : " << cellStruct.
maxVelRefLevel << endl;
1520 uint64_t & cellId = mainOptions.
cellId;
1521 std::vector<uint64_t> & cellIdList = mainOptions.
cellIdList;
1524 std::array<Real, 3> & coordinates = mainOptions.
coordinates;
1525 std::array<Real, 3> & point1 = mainOptions.
point1;
1526 std::array<Real, 3> & point2 = mainOptions.
point2;
1529 if( getCellIdFromCoordinates ==
true || rotateVectors ==
true || plasmaFrame ==
true || getCellIdFromInput ==
true || getCellIdFromLine ==
true || outputDirectoryPath.empty() ==
false ) {
1530 cerr <<
"Error at: " << __FILE__ <<
" " << __LINE__ <<
", invalid arguments in retrieveOptions()" << endl;
1535 po::options_description desc(
"Options");
1538 (
"help",
"display help")
1539 (
"debug",
"write debugging info to stderr")
1540 (
"cellid", po::value<uint64_t>(),
"Set cell id")
1541 (
"cellidlist", po::value< std::vector<uint64_t>>()->multitoken(),
"Set list of cell ids")
1542 (
"rotate",
"Rotate velocities so that they face z-axis")
1543 (
"plasmaFrame",
"Shift the distribution so that the bulk velocity is 0")
1544 (
"coordinates", po::value< std::vector<Real> >()->multitoken(),
"Set spatial coordinates x y z")
1545 (
"unit", po::value<string>(),
"Sets the units. Options: re, km, m (OPTIONAL)")
1546 (
"point1", po::value< std::vector<Real> >()->multitoken(),
"Set the starting point x y z of a line")
1547 (
"point2", po::value< std::vector<Real> >()->multitoken(),
"Set the ending point x y z of a line")
1548 (
"pointamount", po::value<unsigned int>(),
"Number of points along a line (OPTIONAL)")
1549 (
"outputdirectory", po::value< std::vector<string> >(),
"The directory where the file is saved (default current folder) (OPTIONAL)");
1552 po::variables_map vm;
1554 po::store(po::parse_command_line(argn, args, desc, po::command_line_style::unix_style ^ po::command_line_style::allow_short), vm);
1557 if( vm.count(
"help") ) {
1559 cout << desc << endl;
1563 const size_t _size = 3;
1564 if( !vm[
"coordinates"].empty() && vm[
"coordinates"].as< std::vector<Real> >().size() == _size ) {
1566 std::vector<Real> _coordinates = vm[
"coordinates"].as< std::vector<Real> >();
1567 for( uint
i = 0;
i < 3; ++
i ) {
1568 coordinates[
i] = _coordinates[
i];
1571 getCellIdFromCoordinates =
true;
1573 if( !vm[
"point1"].empty() && vm[
"point1"].as< std::vector<Real> >().size() == _size
1574 && !vm[
"point2"].empty() && vm[
"point2"].as< std::vector<Real> >().size() == _size ) {
1576 std::vector<Real> _point1 = vm[
"point1"].as< std::vector<Real> >();
1577 std::vector<Real> _point2 = vm[
"point2"].as< std::vector<Real> >();
1579 for( uint
i = 0;
i < 3; ++
i ) {
1580 point1[
i] = _point1[
i];
1581 point2[
i] = _point2[
i];
1586 if( vm.count(
"pointAmount") ) {
1588 numberOfCoordinatesInALine = vm[
"pointAmount"].as<uint32_t>();
1591 getCellIdFromLine =
true;
1594 if( vm.count(
"rotate") ) {
1596 rotateVectors =
true;
1598 if (vm.count(
"debug") ) {
1603 if( vm.count(
"plasmaFrame") ) {
1608 if( vm.count(
"cellid") ) {
1610 const uint64_t cellId = vm[
"cellid"].as<uint64_t>();
1611 cellIdList.push_back(cellId);
1612 getCellIdFromInput =
true;
1614 if( vm.count(
"cellidlist") ) {
1615 cellIdList = vm[
"cellidlist"].as< std::vector<uint64_t> >();
1616 getCellIdFromInput =
true;
1618 if( vm.count(
"outputdirectory") ) {
1620 outputDirectoryPath = vm[
"outputdirectory"].as< std::vector<string> >();
1622 if( outputDirectoryPath.size() != 1 ) {
1626 string & pathName = outputDirectoryPath.back();
1628 const unsigned index = pathName.find_last_of(
"/\\");
1630 if(
index != (pathName.length() - 1) ) {
1632 const size_t index1 = pathName.find(
"/");
1633 const size_t index2 = pathName.find(
"\\");
1635 if( index1 != string::npos && index2 != string::npos ) {
1636 cout <<
"Do not use both '/' and '\\' in directory path! " << index1 <<
" " << index2 << endl;
1637 cout << desc << endl;
1639 }
else if( index1 != string::npos ) {
1643 pathName.append( 1,
c );
1646 const char c =
'\\';
1648 pathName.append( 1,
c );
1652 string defaultPath =
"";
1653 outputDirectoryPath.push_back(defaultPath);
1656 Real unit_conversion = 1;
1657 if( vm.count(
"unit") ) {
1659 const string unit = vm[
"unit"].as<
string>();
1660 if( unit.compare(
"re" ) == 0 ) {
1662 unit_conversion = 6371000;
1663 }
else if( unit.compare(
"km" ) == 0 ) {
1665 unit_conversion = 1000;
1666 }
else if( unit.compare(
"m" ) == 0 ) {
1668 unit_conversion = 1;
1671 cout <<
"Invalid unit!" << endl;
1672 cout << desc << endl;
1677 if( getCellIdFromLine ) {
1678 const uint16_t vectorSize = 3;
1679 for( uint
i = 0;
i < vectorSize; ++
i ) {
1681 point1[
i] = point1[
i] * unit_conversion;
1682 point2[
i] = point2[
i] * unit_conversion;
1684 }
else if( getCellIdFromCoordinates ) {
1685 const uint16_t vectorSize = 3;
1686 for( uint
i = 0;
i < vectorSize; ++
i ) {
1688 coordinates[
i] = coordinates[
i] * unit_conversion;
1691 cout <<
"Nothing to convert!" << endl;
1692 cout << desc << endl;
1701 if( getCellIdFromLine ) ++count;
1702 if( getCellIdFromInput ) ++count;
1703 if( getCellIdFromCoordinates ) ++count;
1706 cout <<
"Contradiction in the way of retrieving cell id ( can only be 1 out of 3 options )" << endl;
1709 }
catch( exception &e ) {
1710 cerr <<
"Error " << e.what() <<
" at " << __FILE__ <<
" " << __LINE__ << endl;
1713 cerr <<
"Unknown error" <<
" at " << __FILE__ <<
" " << __LINE__ << endl;
1717 if( outputDirectoryPath.size() != 1 ) {
1718 cerr <<
"Error at: " << __FILE__ <<
" " << __LINE__ <<
", invalid outputDirectoryPath!" << endl;
1736 const std::array<Real, 3> & start,
const std::array<Real, 3> & end, uint32_t numberOfCoordinates,
1737 std::vector< std::array<Real, 3> > & outputCoordinates
1740 uint32_t _numberOfCoordinates;
1742 if( numberOfCoordinates == 0 ) {
1747 (end[0] - start[0]) * (end[0] - start[0])
1748 + (end[1] - start[1]) * (end[1] - start[1])
1749 + (end[2] - start[2]) * (end[2] - start[2])
1751 Real minCellLength = numeric_limits<Real>::max();
1753 const uint32_t sizeOfCellLength = 3;
1755 for( uint
i = 0;
i < sizeOfCellLength; ++
i ) {
1759 if( minCellLength == 0 ) {
1760 cerr <<
"ERROR, BAD MINIMUM CELL LENGTH AT " << __FILE__ <<
" " << __LINE__ << endl;
1763 _numberOfCoordinates = (uint32_t)( line_length / minCellLength );
1766 if( _numberOfCoordinates < 2 ) {
1767 cerr <<
"Cannot use numberOfCoordinates lower than 2 at " << __FILE__ <<
" " << __LINE__ << endl;
1772 _numberOfCoordinates = (uint32_t)(1.2 * _numberOfCoordinates);
1773 }
else if( numberOfCoordinates < 2 ) {
1774 cerr <<
"Cannot use numberOfCoordinates lower than 2 at " << __FILE__ <<
" " << __LINE__ << endl;
1778 _numberOfCoordinates = numberOfCoordinates;
1781 std::array<Real, 3> line_unit;
1782 for( uint
i = 0;
i < 3; ++
i ) {
1783 line_unit[
i] = (end[
i] - start[
i]) / (
Real)(_numberOfCoordinates - 1);
1787 outputCoordinates.reserve(_numberOfCoordinates);
1788 for( uint
j = 0;
j < _numberOfCoordinates; ++
j ) {
1789 const std::array<Real, 3> input{{start[0] +
j * line_unit[0],
1790 start[1] +
j * line_unit[1],
1791 start[2] +
j * line_unit[2],}};
1792 outputCoordinates.push_back(input);
1796 if( outputCoordinates.empty() ) {
1797 cerr <<
"Error at: " << __FILE__ <<
" " << __LINE__ <<
", Calculated coordinates empty!" << endl;
1808 vlsvReader.open(fileName);
1809 const string meshName =
"SpatialGrid";
1810 const string tagName =
"MESH";
1811 const string attributeName =
"name";
1818 std::vector<uint64_t> cellIdList;
1826 unordered_set<uint64_t> cellIdList_velocity;
1833 if( cellID == numeric_limits<uint64_t>::max() ) {
1835 cout <<
"Could not find a cell id in the given coordinates!" << endl;
1843 cellIdList.push_back( cellID );
1846 unordered_set<uint64_t> cellIdList_velocity;
1853 std::vector< std::array<Real, 3> > coordinateList;
1860 std::vector< std::array<Real, 3> >::iterator it;
1862 for( it = coordinateList.begin(); it != coordinateList.end(); ++it ) {
1865 const std::array<Real, 3> & coords = *it;
1868 if( cellID != numeric_limits<uint64_t>::max() ) {
1871 if( cellIdList.empty() ) {
1873 cellIdList.push_back( cellID );
1874 }
else if( cellIdList.back() != cellID ) {
1876 cellIdList.push_back( cellID );
1883 for(std::vector<uint64_t>::const_iterator
id = mainOptions.
cellIdList.begin();
id != mainOptions.
cellIdList.end() ;
id++) {
1886 cellIdList.push_back( *
id );
1890 cerr <<
"Error at: " << __FILE__ <<
" " << __LINE__ <<
", No user input for cell id retrieval!" << endl;
1896 if( cellIdList.empty() ) {
1897 cout <<
"Could not find a cell id!" << endl;
1903 std::vector<uint64_t>::iterator it;
1908 cout <<
"Total number of extractions: " << cellIdList.size() << endl;
1910 for( it = cellIdList.begin(); it != cellIdList.end(); ++it ) {
1912 const uint64_t cellID = *it;
1914 cout <<
"Cell id: " << cellID << endl;
1923 ss2 <<
"velgrid" <<
'.';
1925 ss2 <<
"rotated" <<
'.';
1928 ss2 <<
"shifted" <<
'.';
1935 string outputFileName = fileName;
1936 size_t pos = outputFileName.rfind(
".vlsv");
1937 if (pos != string::npos) outputFileName.replace(pos, 5, newSuffix);
1939 pos = outputFileName.find(
".");
1940 if (pos != string::npos) outputFileName.replace(0, pos, newPrefix);
1942 string slicePrefix =
"VelSlice";
1943 string outputSliceName = fileName;
1944 pos = outputSliceName.find(
".");
1945 if (pos != string::npos) outputSliceName.replace(0,pos,slicePrefix);
1948 string outputFilePath;
1952 outputFilePath.append( outputFileName );
1955 bool velGridExtracted =
true;
1959 velGridExtracted =
false;
1965 int moreToGo = cellIdList.size() - extractNum;
1967 cout <<
"Extracted num. " << extractNum <<
", " << moreToGo <<
" more to go" << endl;
1972 cout <<
"\t extracted from '" << fileName <<
"'" << endl;
1977 if (velGridExtracted ==
false) {
1978 cerr <<
"ERROR, FAILED TO EXTRACT VELOCITY GRID AT: " << __FILE__ <<
" " << __LINE__ << endl;
1979 if (remove(outputFilePath.c_str()) != 0) {
1980 cerr <<
"\t ERROR: failed to remote dummy output file!" << endl;
1990 int required=MPI_THREAD_FUNNELED;
1991 int provided, resultlen;
1992 char mpiversion[MPI_MAX_LIBRARY_VERSION_STRING];
1993 bool overrideMCAompio =
false;
1995 MPI_Get_library_version(mpiversion, &resultlen);
1996 string versionstr = string(mpiversion);
1997 stringstream mpiioMessage;
1998 if(versionstr.find(
"Open MPI") != std::string::npos) {
1999 #ifdef VLASIATOR_ALLOW_MCA_OMPIO
2000 mpiioMessage <<
"We detected OpenMPI but the compilation flag VLASIATOR_ALLOW_MCA_OMPIO was set so we do not override the default MCA io flag." << endl;
2002 overrideMCAompio =
true;
2005 MPI_T_cvar_handle io_handle;
2007 MPI_T_init_thread(required, &provided);
2008 MPI_T_cvar_get_index(
"io", &
index);
2009 MPI_T_cvar_handle_alloc(
index, NULL, &io_handle, &count);
2010 MPI_T_cvar_write(io_handle,
"^ompio");
2011 MPI_T_cvar_read(io_handle, io_value);
2012 MPI_T_cvar_handle_free(&io_handle);
2013 mpiioMessage <<
"We detected OpenMPI so we set the cvars value to disable ompio, MCA io: " << io_value << endl;
2018 MPI_Init_thread(&argn,&args,required,&provided);
2019 MPI_Comm_size(MPI_COMM_WORLD, &ntasks);
2020 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
2021 if (required > provided){
2023 cerr <<
"MPI_Init_thread failed! Got " << provided <<
", need "<<required <<endl;
2028 const char* mpiioenv = std::getenv(
"OMPI_MCA_io");
2029 if(mpiioenv !=
nullptr) {
2030 std::string mpiioenvstr(mpiioenv);
2031 if(mpiioenvstr.find(
"^ompio") == std::string::npos) {
2032 cout << mpiioMessage.str();
2038 const string mask = args[1];
2050 if (rank == 0 && argn < 3) {
2057 int entryCounter = 0;
2058 for (
size_t entryName = 0; entryName < fileList.size(); entryName++) {
2059 if (entryCounter++ % ntasks == rank) {
2061 const string & fileName = fileList[entryName];
2066 if(overrideMCAompio) {