111bool copyArray(vlsv::Reader& input, vlsv::Writer& output,
const std::string& tagName,
112 const list<pair<string, string>>& inputAttribs,
bool optional =
false) {
116 map<string, string> outputAttribs;
117 if (input.getArrayAttributes(tagName, inputAttribs, outputAttribs) ==
false) {
120 cerr <<
"ERROR: Failed to read array '" << tagName <<
"' attributes in " << __FILE__ <<
":" << __LINE__ << endl;
121 cerr <<
"Input attributes are:" << endl;
122 for (list<pair<string, string>>::const_iterator it = inputAttribs.begin(); it != inputAttribs.end(); ++it) {
123 cerr <<
"\t '" << it->first <<
"' = '" << it->second <<
"'" << endl;
133 map<string, string>::const_iterator it;
134 map<string, string>::iterator it2;
135 it = outputAttribs.find(
"arraysize");
136 if (it == outputAttribs.end())
return false;
137 uint64_t arraysize = atol(it->second.c_str());
138 it = outputAttribs.find(
"vectorsize");
139 if (it == outputAttribs.end())
return false;
140 const uint64_t vectorsize = atol(it->second.c_str());
141 it = outputAttribs.find(
"datasize");
142 if (it == outputAttribs.end())
return false;
143 const uint64_t datasize = atol(it->second.c_str());
144 it = outputAttribs.find(
"datatype");
145 if (it == outputAttribs.end())
return false;
146 const string datatype = it->second;
148 const size_t bytes = arraysize * vectorsize * datasize;
151 char* ptr =
new char[bytes];
152 if (input.readArray(tagName, inputAttribs, 0, arraysize, ptr) ==
false) {
153 cerr <<
"ERROR: Failed to clone array '" << tagName <<
"' in " << __FILE__ <<
":" << __LINE__ << endl;
159 if (output.writeArray(tagName, outputAttribs, datatype, arraysize, vectorsize, datasize, ptr) ==
false) {
160 cerr <<
"ERROR: Failed to write array '" << tagName <<
"' in " << __FILE__ <<
":" << __LINE__ << endl;
170bool HandleFsGrid(
const string& inputFileName, vlsv::Writer& output, std::map<uint, Real> orderedData) {
174 if (input.open(inputFileName) ==
false) {
175 cerr <<
"ERROR failed to open input file '" << inputFileName <<
"' in " << __FILE__ <<
":" << __LINE__ << endl;
180 std::string tagName =
"MESH";
181 list<pair<string, string>> inputAttribs;
182 inputAttribs.push_back(make_pair(
"name",
"fsgrid"));
183 map<string, string> outputAttribs;
185 if (input.getArrayAttributes(tagName, inputAttribs, outputAttribs) ==
false) {
186 cerr <<
"ERROR: Failed to read array '" << tagName <<
"' attributes in " << __FILE__ <<
":" << __LINE__ << endl;
187 cerr <<
"Input attributes are:" << endl;
188 for (list<pair<string, string>>::const_iterator it = inputAttribs.begin(); it != inputAttribs.end(); ++it) {
189 cerr <<
"\t '" << it->first <<
"' = '" << it->second <<
"'" << endl;
195 map<string, string>::const_iterator it;
196 it = outputAttribs.find(
"arraysize");
197 if (it == outputAttribs.end())
return false;
198 uint64_t arraysize = atol(it->second.c_str());
199 it = outputAttribs.find(
"vectorsize");
200 if (it == outputAttribs.end())
return false;
201 const uint64_t vectorsize = atol(it->second.c_str());
202 it = outputAttribs.find(
"datasize");
203 if (it == outputAttribs.end())
return false;
204 const uint64_t datasize = atol(it->second.c_str());
205 it = outputAttribs.find(
"datatype");
206 if (it == outputAttribs.end())
return false;
207 const string datatype = it->second;
208 it = outputAttribs.find(
"xperiodic");
209 if (it == outputAttribs.end())
return false;
210 const string xperiodic = it->second;
211 it = outputAttribs.find(
"yperiodic");
212 if (it == outputAttribs.end())
return false;
213 const string yperiodic = it->second;
214 it = outputAttribs.find(
"zperiodic");
215 if (it == outputAttribs.end())
217 const string zperiodic = it->second;
218 it = outputAttribs.find(
"type");
219 if (it == outputAttribs.end())
221 const string type = it->second;
223 map<string, string> patch;
224 patch[
"arraysize"] = std::to_string(arraysize);
225 patch[
"datasize"] = std::to_string(datasize);
226 patch[
"datatype"] = datatype;
227 patch[
"name"] =
"fsgrid";
228 patch[
"type"] = type;
229 patch[
"vectorsize"] = std::to_string(vectorsize);
230 patch[
"xperiodic"] = xperiodic;
231 patch[
"yperiodic"] = yperiodic;
232 patch[
"zperiodic"] = zperiodic;
235 std::vector<uint64_t> globalIds;
236 for (
const auto iter : orderedData) {
237 globalIds.push_back(iter.first);
241 output.writeArray(
"MESH", patch, arraysize, 1, &globalIds[0]);
243 std::array<int, 1> numWritingRanks = {1};
244 output.writeParameter(
"numWritingRanks", &numWritingRanks[0]);
247 std::map<std::string, std::string> xmlAttributes;
248 const std::string meshName =
"fsgrid";
249 xmlAttributes[
"mesh"] = meshName;
250 std::array<fsgrid::Task_t, 3> decom = {1, 1, 1};
251 output.writeArray(
"MESH_DECOMPOSITION", outputAttribs, 3u, 1u, &decom[0]);
254 inputAttribs.clear();
255 inputAttribs.push_back(make_pair(
"mesh",
"fsgrid"));
256 tagName =
"MESH_DOMAIN_SIZES";
258 if (input.getArrayAttributes(tagName, inputAttribs, outputAttribs) ==
false) {
259 cerr <<
"ERROR: Failed to read array '" << tagName <<
"' attributes in " << __FILE__ <<
":" << __LINE__ << endl;
260 cerr <<
"Input attributes are:" << endl;
261 for (list<pair<string, string>>::const_iterator it = inputAttribs.begin(); it != inputAttribs.end(); ++it) {
262 cerr <<
"\t '" << it->first <<
"' = '" << it->second <<
"'" << endl;
268 it = outputAttribs.find(
"datasize");
269 if (it == outputAttribs.end())
return false;
270 const uint64_t datasize2 = atol(it->second.c_str());
271 it = outputAttribs.find(
"datatype");
272 if (it == outputAttribs.end())
return false;
273 const string datatype2 = it->second;
274 it = outputAttribs.find(
"vectorsize");
275 if (it == outputAttribs.end())
return false;
276 const uint64_t vectorsize2 = atol(it->second.c_str());
279 patch[
"arraysize"] =
"1";
280 patch[
"datasize"] = to_string(datasize2);
281 patch[
"datatype"] = datatype2;
282 patch[
"mesh"] =
"fsgrid";
283 patch[
"vectorsize"] = to_string(vectorsize2);
286 std::array<uint64_t, 2> meshDomainSize({globalIds.size(), 0});
287 output.writeArray(
"MESH_DOMAIN_SIZES", patch, 1, vectorsize2, &meshDomainSize[0]);
298 vlsv::datatype::type dataType;
301 list<pair<string, string>> attribs;
302 attribs.push_back(make_pair(
"mesh",
"fsgrid"));
304 std::array<fsgrid::Task_t, 3> fsGridDecomposition = {0, 0, 0};
305 int* ptr = &fsGridDecomposition[0];
308 bool success =
file.getArrayInfo(
"MESH_DECOMPOSITION", attribs, arraySize, vectorSize, dataType, byteSize);
309 if (success ==
false) {
315 int fsgridInputRanks = 0;
316 if (
file.readParameter(
"numWritingRanks", fsgridInputRanks) ==
false) {
317 std::cerr <<
"FSGrid writing rank number not found in restart file" << endl;
320 std::array<fsgrid::FsSize_t, 3> gridSize;
321 fsgrid::FsSize_t* gridSizePtr = &gridSize[0];
322 success =
file.read(
"MESH_BBOX", attribs, 0, 3, gridSizePtr,
false);
323 if (success ==
false) {
324 std::cerr <<
"Could not read MESH_BBOX from file" << endl;
327 int64_t* domainInfo = NULL;
328 success =
file.read(
"MESH_DOMAIN_SIZES", attribs, 0, fsgridInputRanks, domainInfo);
329 if (success ==
false) {
330 std::cerr <<
"Could not read MESH_DOMAIN_SIZES from file" << endl;
333 std::vector<uint64_t> mesh_domain_sizes;
334 for (
int i = 0;
i < 2 * fsgridInputRanks;
i += 2) {
335 mesh_domain_sizes.push_back(domainInfo[
i]);
337 list<pair<string, string>> mesh_attribs;
338 mesh_attribs.push_back(make_pair(
"name",
"fsgrid"));
339 std::vector<fsgrid::FsSize_t> rank_first_ids(fsgridInputRanks);
340 fsgrid::FsSize_t* ids_ptr = &rank_first_ids[0];
342 std::set<fsgrid::FsIndex_t> x_corners, y_corners, z_corners;
344 int64_t begin_rank = 0;
346 for (
auto rank_size : mesh_domain_sizes) {
347 if (
file.read(
"MESH", mesh_attribs, begin_rank, 1, ids_ptr,
false) ==
false) {
348 std::cerr <<
"Reading MESH failed.\n";
351 std::array<fsgrid::FsIndex_t, 3> inds = fsgrid::globalIDtoCellCoord(*ids_ptr, gridSize);
352 x_corners.insert(inds[0]);
353 y_corners.insert(inds[1]);
354 z_corners.insert(inds[2]);
356 begin_rank += rank_size;
359 decomposition[0] = x_corners.size();
360 decomposition[1] = y_corners.size();
361 decomposition[2] = z_corners.size();
362 std::cout <<
"Fsgrid decomposition computed from MESH to be " << decomposition[0] <<
" " << decomposition[1] <<
" " << decomposition[2] << endl;
367 success =
file.read(
"MESH_DECOMPOSITION", attribs, 0, 3, ptr,
false);
368 decomposition[0] = fsGridDecomposition[0];
369 decomposition[1] = fsGridDecomposition[1];
370 decomposition[2] = fsGridDecomposition[2];
371 std::cout <<
"Fsgrid decomposition read as " << decomposition[0] <<
" " << decomposition[1] <<
" " << decomposition[2] << endl;
434 const uint compToExtract, map<uint, Real>* orderedData, unordered_map<size_t, size_t>& cellOrder,
435 const bool& storeCellOrder) {
438 if (!varToExtract || !orderedData) {
439 cerr <<
"ERROR, PASSED A NULL POINTER AT " << __FILE__ <<
" " << __LINE__ << endl;
442 bool meshSuccess =
true;
443 bool variableSuccess =
true;
445 datatype::type meshDataType;
446 datatype::type variableDataType;
447 uint64_t meshArraySize, meshVectorSize, meshDataSize;
448 uint64_t variableArraySize, variableVectorSize, variableDataSize;
450 list<pair<string, string>> variableAttributes;
451 const string _varToExtract(varToExtract);
452 variableAttributes.push_back(make_pair(
"mesh", meshName));
453 variableAttributes.push_back(make_pair(
"name", _varToExtract));
456 if (vlsvReader.getArrayInfo(
"VARIABLE", variableAttributes, variableArraySize, variableVectorSize, variableDataType,
457 variableDataSize) ==
false) {
458 cerr <<
"ERROR, failed to get array info for '" << _varToExtract <<
"' on mesh '" << meshName <<
"' at " << __FILE__ <<
" " << __LINE__ << endl;
464 std::vector<char> variableBuffer(variableVectorSize * variableDataSize);
465 float* variablePtrFloat =
reinterpret_cast<float*
>(variableBuffer.data());
466 double* variablePtrDouble =
reinterpret_cast<double*
>(variableBuffer.data());
467 uint* variablePtrUint =
reinterpret_cast<uint*
>(variableBuffer.data());
468 int* variablePtrInt =
reinterpret_cast<int*
>(variableBuffer.data());
473 vector<uint64_t> local_cells;
474 if (vlsvReader.
getCellIds(local_cells, meshName) ==
false) {
475 cerr <<
"Failed to read cell ids at " << __FILE__ <<
" " << __LINE__ << endl;
480 if (local_cells.size() != variableArraySize) {
481 cerr <<
"ERROR array size mismatch: " << local_cells.size() <<
" " << variableArraySize << endl;
483 if (compToExtract + 1 > variableVectorSize) {
484 cerr <<
"ERROR invalid component, this variable has size " << variableVectorSize << endl;
488 if (storeCellOrder ==
true) {
492 orderedData->clear();
494 for (uint64_t
i = 0;
i < local_cells.size(); ++
i) {
495 const short int amountToReadIn = 1;
496 const uint64_t& startingReadIndex =
i;
497 if (vlsvReader.readArray(
"VARIABLE", variableAttributes, startingReadIndex, amountToReadIn,
498 variableBuffer.data()) ==
false) {
499 cerr <<
"ERROR, failed to read variable '" << _varToExtract <<
"' at " << __FILE__ <<
" " << __LINE__ << endl;
500 variableSuccess =
false;
504 uint64_t&
CellID = local_cells[
i];
509 switch (variableDataType) {
510 case datatype::type::FLOAT:
511 if (variableDataSize ==
sizeof(
float)) extract = (
Real)(variablePtrFloat[compToExtract]);
512 if (variableDataSize ==
sizeof(
double)) extract = (
Real)(variablePtrDouble[compToExtract]);
514 case datatype::type::UINT:
515 extract = (
Real)(variablePtrUint[compToExtract]);
517 case datatype::type::INT:
518 extract = (
Real)(variablePtrInt[compToExtract]);
520 case datatype::type::UNKNOWN:
521 cerr <<
"ERROR, BAD DATATYPE AT " << __FILE__ <<
" " << __LINE__ << endl;
525 orderedData->insert(pair<uint64_t, Real>(
CellID, extract));
526 if (storeCellOrder ==
true) {
537 list<pair<string, string>> meshAttributesIn;
538 meshAttributesIn.push_back(make_pair(
"name",
"SpatialGrid"));
539 map<string, string> meshAttributesOut;
540 if (vlsvReader.getArrayAttributes(
"MESH", meshAttributesIn, meshAttributesOut) ==
false) {
541 cerr <<
"ERROR, failed to get array info for '" << _varToExtract <<
"' at " << __FILE__ <<
" " << __LINE__ << endl;
545 std::map<string, string>::iterator attributesOutIt;
546 attributesOutIt = meshAttributesOut.find(
"max_refinement_level");
547 if (attributesOutIt != meshAttributesOut.end()) {
548 maxRefLevel = stoi(attributesOutIt->second);
551 int xcells, ycells, zcells;
552 vlsvReader.readParameter(
"numWritingRanks", numtasks);
553 vlsvReader.readParameter(
"xcells_ini", xcells);
554 vlsvReader.readParameter(
"ycells_ini", ycells);
555 vlsvReader.readParameter(
"zcells_ini", zcells);
556 xcells *= pow(2, maxRefLevel);
557 ycells *= pow(2, maxRefLevel);
558 zcells *= pow(2, maxRefLevel);
559 std::array<int, 3> GlobalBox = {xcells, ycells, zcells};
560 std::array<int, 3> thisDomainDecomp;
566 std::array<int32_t, 3> taskSize, taskStart;
567 std::array<int32_t, 3> taskEnd;
569 int index, my_x, my_y, my_z;
570 orderedData->clear();
572 for (
int task = 0; task < numtasks; task++) {
574 my_x = task / thisDomainDecomp[2] / thisDomainDecomp[1];
575 my_y = (task / thisDomainDecomp[2]) % thisDomainDecomp[1];
576 my_z = task % thisDomainDecomp[2];
578 taskStart[0] = fsgrid::calcLocalStart(GlobalBox[0], thisDomainDecomp[0], my_x);
579 taskStart[1] = fsgrid::calcLocalStart(GlobalBox[1], thisDomainDecomp[1], my_y);
580 taskStart[2] = fsgrid::calcLocalStart(GlobalBox[2], thisDomainDecomp[2], my_z);
582 taskSize[0] = fsgrid::calcLocalSize(GlobalBox[0], thisDomainDecomp[0], my_x);
583 taskSize[1] = fsgrid::calcLocalSize(GlobalBox[1], thisDomainDecomp[1], my_y);
584 taskSize[2] = fsgrid::calcLocalSize(GlobalBox[2], thisDomainDecomp[2], my_z);
586 taskEnd[0] = taskStart[0] + taskSize[0];
587 taskEnd[1] = taskStart[1] + taskSize[1];
588 taskEnd[2] = taskStart[2] + taskSize[2];
590 int64_t readSize = taskSize[0] * taskSize[1] * taskSize[2];
592 std::vector<Real> buffer(readSize * variableVectorSize);
594 if (variableDataSize ==
sizeof(
Real)) {
595 if (vlsvReader.readArray(
"VARIABLE", variableAttributes, readOffset, readSize, (
char*)buffer.data()) ==
597 cerr <<
"ERROR, failed to read variable '" << _varToExtract <<
"' at " << __FILE__ <<
" " << __LINE__ << endl;
598 variableSuccess =
false;
602 std::vector<float> tmpbuffer(readSize * variableVectorSize);
603 if (vlsvReader.readArray(
"VARIABLE", variableAttributes, readOffset, readSize, (
char*)tmpbuffer.data()) ==
605 cerr <<
"ERROR, failed to read variable '" << _varToExtract <<
"' at " << __FILE__ <<
" " << __LINE__ << endl;
606 variableSuccess =
false;
609 for (
unsigned int i = 0;
i < readSize * variableVectorSize;
i++) {
610 buffer[
i] = tmpbuffer[
i];
614 uint64_t globalindex, counter = 0;
616 for (
int z = taskStart[2]; z < taskEnd[2]; z++) {
617 for (
int y = taskStart[1]; y < taskEnd[1]; y++) {
618 for (
int x = taskStart[0]; x < taskEnd[0]; x++) {
619 globalindex = x + y * xcells + z * xcells * ycells;
621 switch (variableDataType) {
622 case datatype::type::FLOAT:
623 if (variableDataSize ==
sizeof(
float))
624 memcpy(&data, &buffer[counter + compToExtract],
sizeof(
float));
625 if (variableDataSize ==
sizeof(
double))
626 memcpy(&data, &buffer[counter + compToExtract],
sizeof(
double));
628 case datatype::type::UINT:
629 memcpy(&data, &buffer[counter + compToExtract],
sizeof(uint));
631 case datatype::type::INT:
632 memcpy(&data, &buffer[counter + compToExtract],
sizeof(
int));
634 case datatype::type::UNKNOWN:
635 cerr <<
"ERROR, BAD DATATYPE AT " << __FILE__ <<
" " << __LINE__ << endl;
639 orderedData->insert(pair<uint64_t, Real>(globalindex, data));
640 counter += variableVectorSize;
644 readOffset += readSize;
650 if (compToExtract >= variableVectorSize) {
651 cerr <<
"ERROR invalid component, this variable has size " << variableVectorSize << endl;
654 orderedData->clear();
656 switch (variableDataType) {
657 case datatype::type::FLOAT: {
658 if (variableDataSize ==
sizeof(
double)) {
659 std::vector<double> buffer(variableVectorSize * variableArraySize);
661 if (vlsvReader.readArray(
"VARIABLE", variableAttributes, 0, variableArraySize, (
char*)buffer.data()) ==
663 cerr <<
"ERROR, failed to read variable '" << _varToExtract <<
"' at " << __FILE__ <<
" " << __LINE__ << endl;
664 variableSuccess =
false;
668 for (
unsigned int i = 0;
i < variableArraySize;
i++) {
669 orderedData->insert(pair<uint64_t, Real>(
i, buffer[
i * variableVectorSize + compToExtract]));
671 }
else if (variableDataSize ==
sizeof(
float)) {
672 std::vector<double> buffer(variableVectorSize * variableArraySize);
674 if (vlsvReader.readArray(
"VARIABLE", variableAttributes, 0, variableArraySize, (
char*)buffer.data()) ==
676 cerr <<
"ERROR, failed to read variable '" << _varToExtract <<
"' at " << __FILE__ <<
" " << __LINE__ << endl;
677 variableSuccess =
false;
681 for (
unsigned int i = 0;
i < variableArraySize;
i++) {
682 orderedData->insert(pair<uint64_t, Real>(
i, buffer[
i * variableVectorSize + compToExtract]));
687 cerr <<
"Error: No support for ionosphere parameters that are not float-valued implemented, at " << __FILE__ <<
" " << __LINE__ << endl;
693 cerr <<
"meshName not recognized\t" << __FILE__ <<
" " << __LINE__ << endl;
697 if (meshSuccess ==
false) {
698 cerr <<
"ERROR reading array MESH" << endl;
700 if (variableSuccess ==
false) {
701 cerr <<
"ERROR reading array VARIABLE " << varToExtract << endl;
703 return meshSuccess && variableSuccess;
810bool pDistance(
const map<uint, Real>& orderedData1,
const map<uint, Real>& orderedData2,
creal p,
Real* absolute,
811 Real* relative,
const bool doShiftAverage,
const unordered_map<size_t, size_t>& cellOrder,
812 vlsv::Writer& outputFile,
const std::string& meshName,
const std::string& varName) {
813 map<uint, Real> shiftedData2;
814 map<uint, Real>* data2 =
const_cast<map<uint, Real>*
>(&orderedData2);
816 if (doShiftAverage ==
true) {
817 shiftAverage(&orderedData1, &orderedData2, &shiftedData2);
818 data2 = &shiftedData2;
825 vector<Real> array(orderedData1.size());
826 for (
size_t i = 0;
i < array.size(); ++
i)
831 for (map<uint, Real>::const_iterator it1 = orderedData1.begin(); it1 != orderedData1.end(); ++it1) {
832 map<uint, Real>::const_iterator it2 = data2->find(it1->first);
834 if (it2 != data2->end()) {
835 value =
abs(it1->second - it2->second);
836 *absolute =
max(*absolute, value);
840 array[cellOrder.at(it1->first)] = value;
842 array.at(it1->first) = value;
846 for (map<uint, Real>::const_iterator it1 = orderedData1.begin(); it1 != orderedData1.end(); ++it1) {
847 map<uint, Real>::const_iterator it2 = data2->find(it1->first);
849 if (it2 != data2->end()) {
850 value =
abs(it1->second - it2->second);
855 array[cellOrder.at(it1->first)] = value;
857 array[it1->first] = value;
861 for (map<uint, Real>::const_iterator it1 = orderedData1.begin(); it1 != orderedData1.end(); ++it1) {
862 map<uint, Real>::const_iterator it2 = data2->find(it1->first);
864 if (it2 != data2->end()) {
865 value = pow(
abs(it1->second - it2->second), p);
870 array[cellOrder.at(it1->first)] = pow(value, 1.0 / p);
872 array[it1->first] = pow(value, 1.0 / p);
875 *absolute = pow(*absolute, 1.0 / p);
880 *relative = *absolute /
length;
882 cout <<
"WARNING (pDistance) : length of reference is 0.0, cannot divide to give relative distance." << endl;
891 if (meshName ==
"ionosphere") {
895 if (outputFile.writeArray(
"VARIABLE",
attributes, array.size(), 1, &(array[0])) ==
false) {
896 cerr <<
"ERROR failed to write variable '" << varName <<
"' to output file in " << __FILE__ <<
":" << __LINE__ << endl;
1086 const unordered_map<uint64_t, pair<uint64_t, uint32_t>>& cellsWithBlocksLocations,
1087 const uint64_t& cellId, vector<uint32_t>& blockIds) {
1090 unordered_map<uint64_t, pair<uint64_t, uint32_t>>::const_iterator it = cellsWithBlocksLocations.find(cellId);
1091 if (it == cellsWithBlocksLocations.end()) {
1092 cerr <<
"COULDNT FIND CELL ID " << cellId <<
" AT " << __FILE__ <<
" " << __LINE__ << endl;
1096 pair<uint64_t, uint32_t> offsetAndBlocks = it->second;
1097 const uint64_t blockOffset = get<0>(offsetAndBlocks);
1098 const uint32_t N_blocks = get<1>(offsetAndBlocks);
1101 list<pair<string, string>> attribs;
1102 attribs.push_back(make_pair(
"mesh",
attributes[
"--meshname"]));
1105 uint64_t blockIds_arraySize, blockIds_vectorSize, blockIds_dataSize;
1106 vlsv::datatype::type blockIds_dataType;
1108 if (vlsvReader.getArrayInfo(
"BLOCKIDS", attribs, blockIds_arraySize, blockIds_vectorSize, blockIds_dataType,
1109 blockIds_dataSize) ==
false) {
1110 cerr <<
"ERROR, COULD NOT FIND BLOCKIDS AT " << __FILE__ <<
" " << __LINE__ << endl;
1114 if (blockIds_dataType != vlsv::datatype::type::UINT) {
1115 cerr <<
"ERROR, bad datatype at " << __FILE__ <<
" " << __LINE__ << endl;
1119 char* blockIds_buffer =
new char[N_blocks * blockIds_vectorSize * blockIds_dataSize];
1121 if (vlsvReader.readArray(
"BLOCKIDS", attribs, blockOffset, N_blocks, blockIds_buffer) ==
false) {
1122 cerr <<
"ERROR, FAILED TO READ BLOCKIDS AT " << __FILE__ <<
" " << __LINE__ << endl;
1123 delete[] blockIds_buffer;
1127 blockIds.reserve(N_blocks);
1128 for (uint64_t
i = 0;
i < N_blocks; ++
i) {
1129 const uint64_t blockId =
convUInt(blockIds_buffer +
i * blockIds_dataSize, blockIds_dataType, blockIds_dataSize);
1130 blockIds.push_back((uint32_t)(blockId));
1132 delete[] blockIds_buffer;
1159 const unordered_map<uint64_t, pair<uint64_t, uint32_t>> & cellsWithBlocksLocations,
1160 const uint64_t & cellId,
1161 unordered_map<uint32_t, vector<double> > & avgs,
1162 uint64_t& vectorSize
1165 vector<uint32_t> blockIds;
1166 if (
getBlockIds(vlsvReader, cellsWithBlocksLocations, cellId, blockIds) ==
false) {
1170 list<pair<string, string>> attribs;
1171 attribs.push_back(make_pair(
"name", name));
1172 attribs.push_back(make_pair(
"mesh",
attributes[
"--meshname"]));
1174 datatype::type dataType;
1175 uint64_t arraySize, dataSize;
1176 if (vlsvReader.getArrayInfo(
"BLOCKVARIABLE", attribs, arraySize, vectorSize, dataType, dataSize) ==
false) {
1183 unordered_map<uint64_t, pair<uint64_t, uint32_t>>::const_iterator it = cellsWithBlocksLocations.find( cellId );
1184 if( it == cellsWithBlocksLocations.end() ) {
1185 cerr <<
"COULDNT FIND CELL ID " << cellId <<
" AT " << __FILE__ <<
" " << __LINE__ << endl;
1189 pair<uint64_t, uint32_t> offsetAndBlocks = it->second;
1190 const uint64_t blockOffset = get<0>(offsetAndBlocks);
1191 const uint32_t N_blocks = get<1>(offsetAndBlocks);
1193 if (N_blocks != blockIds.size()) {
1194 cerr <<
"ERROR, BAD AVGS ARRAY SIZE AT " << __FILE__ <<
" " << __LINE__ << endl;
1195 cerr <<
"AVGS SIZE: " << N_blocks << endl;
1196 cerr <<
"BLOCKIDS SIZE: " << blockIds.size() << endl;
1200 char* buffer =
new char[N_blocks * vectorSize * dataSize];
1201 if (vlsvReader.readArray(
"BLOCKVARIABLE", attribs, blockOffset, N_blocks, buffer) ==
false) {
1202 cerr <<
"ERROR could not read block variable at " << __FILE__ <<
" " << __LINE__ << endl;
1207 vector<double> avgs_temp (vectorSize);
1208 if( dataSize == 4 ) {
1209 float * buffer_float =
reinterpret_cast<float*
>( buffer );
1210 for( uint b = 0; b < blockIds.size(); ++b ) {
1211 const uint32_t & blockId = blockIds[b];
1212 for( uint
i = 0;
i < vectorSize; ++
i ) {
1213 avgs_temp[
i] = buffer_float[vectorSize * b +
i];
1215 avgs[blockId] = avgs_temp;
1217 }
else if (dataSize == 8) {
1218 double* buffer_double =
reinterpret_cast<double*
>(buffer);
1219 for (uint b = 0; b < blockIds.size(); ++b) {
1220 const uint32_t& blockId = blockIds[b];
1221 for (uint
i = 0;
i < vectorSize; ++
i) {
1222 avgs_temp[
i] = buffer_double[vectorSize * b +
i];
1224 avgs[blockId] = avgs_temp;
1227 cerr <<
"ERROR, BAD AVGS DATASIZE AT " << __FILE__ <<
" " << __LINE__ << endl;
1237 unordered_map<uint64_t, pair<uint64_t, uint32_t>>& cellsWithBlocksLocations) {
1238 if (cellsWithBlocksLocations.empty() ==
false) {
1239 cellsWithBlocksLocations.clear();
1241 const string meshName =
attributes[
"--meshname"];
1242 vlsv::datatype::type cwb_dataType;
1243 uint64_t cwb_arraySize, cwb_vectorSize, cwb_dataSize;
1244 list<pair<string, string>> attribs;
1247 attribs.push_back(make_pair(
"mesh", meshName));
1250 if (vlsvReader.getArrayInfo(
"CELLSWITHBLOCKS", attribs, cwb_arraySize, cwb_vectorSize, cwb_dataType, cwb_dataSize) ==
false) {
1251 cerr <<
"ERROR, COULD NOT FIND ARRAY CELLSWITHBLOCKS AT " << __FILE__ <<
" " << __LINE__ << endl;
1256 if (cwb_vectorSize != 1) {
1257 cerr <<
"ERROR, BAD VECTORSIZE AT " << __FILE__ <<
" " << __LINE__ << endl;
1260 if (cwb_dataType != vlsv::datatype::type::UINT) {
1261 cerr <<
"ERROR, BAD DATATYPE AT " << __FILE__ <<
" " << __LINE__ << endl;
1264 if (cwb_dataSize !=
sizeof(uint64_t)) {
1265 cerr <<
"ERROR, BAD DATASIZE AT " << __FILE__ <<
" " << __LINE__ << endl;
1270 const uint64_t cwb_amountToReadIn = cwb_arraySize * cwb_vectorSize * cwb_dataSize;
1271 const uint16_t cwb_startingPoint = 0;
1272 char* cwb_buffer =
new char[cwb_amountToReadIn];
1273 if (vlsvReader.readArray(
"CELLSWITHBLOCKS", attribs, cwb_startingPoint, cwb_arraySize, cwb_buffer) ==
false) {
1274 cerr <<
"Failed to read block metadata for mesh '" << meshName <<
"'" << endl;
1275 delete[] cwb_buffer;
1279 vlsv::datatype::type nb_dataType;
1280 uint64_t nb_arraySize, nb_vectorSize, nb_dataSize;
1284 if (vlsvReader.getArrayInfo(
"BLOCKSPERCELL", attribs, nb_arraySize, nb_vectorSize, nb_dataType, nb_dataSize) ==
false) {
1285 cerr <<
"ERROR, COULD NOT FIND ARRAY BLOCKSPERCELL AT " << __FILE__ <<
" " << __LINE__ << endl;
1290 const short int startingPoint = 0;
1291 char* nb_buffer =
new char[nb_arraySize * nb_vectorSize * nb_dataSize];
1292 if (vlsvReader.readArray(
"BLOCKSPERCELL", attribs, startingPoint, nb_arraySize, nb_buffer) ==
false) {
1293 cerr <<
"Failed to read number of blocks for mesh '" << meshName <<
"'" << endl;
1295 delete[] cwb_buffer;
1300 uint64_t blockOffset = 0;
1302 for (uint64_t cell = 0; cell < cwb_arraySize; ++cell) {
1303 const uint64_t readCellID =
convUInt(cwb_buffer + cell * cwb_dataSize, cwb_dataType, cwb_dataSize);
1304 N_blocks =
convUInt(nb_buffer + cell * nb_dataSize, nb_dataType, nb_dataSize);
1305 const pair<uint64_t, uint32_t> input = make_pair(blockOffset, N_blocks);
1307 cellsWithBlocksLocations.insert(make_pair(readCellID, input));
1308 blockOffset += N_blocks;
1311 delete[] cwb_buffer;
1317bool compareAvgs(
const string fileName1,
const string fileName2,
const bool verboseOutput, vector<uint64_t>& cellIds1,
1318 vector<uint64_t>& cellIds2) {
1319 if (cellIds1.empty() ==
true || cellIds2.empty() ==
true) {
1320 cerr <<
"ERROR, CELL IDS EMPTY IN COMPARE AVGS" << endl;
1325 unordered_map<uint64_t, pair<uint64_t, uint32_t>> cellsWithBlocksLocations1;
1326 unordered_map<uint64_t, pair<uint64_t, uint32_t>> cellsWithBlocksLocations2;
1329 if (vlsvReader1.open(fileName1) ==
false) {
1330 cerr <<
"Error opening file name " << fileName1 <<
" at " << __FILE__ <<
" " << __LINE__ << endl;
1335 if (vlsvReader2.open(fileName2) ==
false) {
1336 cerr <<
"Error opening file name " << fileName2 <<
" at " << __FILE__ <<
" " << __LINE__ << endl;
1341 cerr <<
"ERROR AT " << __FILE__ <<
" " << __LINE__ << endl;
1346 cerr <<
"ERROR AT " << __FILE__ <<
" " << __LINE__ << endl;
1350 if (cellsWithBlocksLocations2.size() != cellsWithBlocksLocations1.size()) {
1351 cerr <<
"BAD CELLS WITH BLOCKS SIZE AT " << __FILE__ <<
" " << __LINE__ << endl;
1356 vector<double> avgsDiffs;
1357 double totalAbsAvgs = 0;
1358 double totalAbsDiff = 0;
1359 double totalAbsLog10Diff = 0;
1361 uint64_t numOfRelevantCells = 0;
1362 uint64_t numOfIdenticalBlocks = 0;
1363 uint64_t numOfNonIdenticalBlocks = 0;
1364 if (cellIds1[0] == 0 || cellIds2[0] == 0) {
1368 for (unordered_map<uint64_t, pair<uint64_t, uint32_t>>::const_iterator it = cellsWithBlocksLocations1.begin();
1369 it != cellsWithBlocksLocations1.end(); ++it) {
1370 cellIds1.push_back(it->first);
1371 cellIds2.push_back(it->first);
1375 if (cellIds1.size() != cellIds2.size()) {
1376 cerr <<
"ERROR, BAD CELL ID SIZES AT " << __FILE__ <<
" " << __LINE__ << endl;
1381 const uint64_t& cellId1 = cellIds1[
cellIndex];
1382 const uint64_t& cellId2 = cellIds2[
cellIndex];
1384 uint64_t vectorSize1 = 0, vectorSize2;
1385 unordered_map<uint32_t, vector<double> > avgs1;
1386 unordered_map<uint32_t, vector<double> > avgs2;
1388 if(
readAvgs( vlsvReader1,
"proton", cellsWithBlocksLocations1, cellId1, avgs1, vectorSize1 ) ==
false ) {
1389 if(
readAvgs( vlsvReader1,
"avgs", cellsWithBlocksLocations1, cellId1, avgs1, vectorSize1 ) ==
false ) {
1390 cerr <<
"ERROR, FAILED TO READ AVGS AT " << __FILE__ <<
" " << __LINE__ << endl;
1395 if(
readAvgs( vlsvReader2,
"proton", cellsWithBlocksLocations2, cellId2, avgs2, vectorSize2 ) ==
false ) {
1396 if(
readAvgs( vlsvReader2,
"avgs", cellsWithBlocksLocations2, cellId2, avgs2, vectorSize2 ) ==
false ) {
1397 cerr <<
"ERROR, FAILED TO READ AVGS AT " << __FILE__ <<
" " << __LINE__ << endl;
1402 if (vectorSize1 != vectorSize2) {
1403 cerr <<
"ERROR, VECTORSIZES DON'T MATCH " << vectorSize1 <<
" VS " << vectorSize2 <<
" AT " << __FILE__ <<
" " << __LINE__ << endl;
1406 const uint64_t velocityCellsPerBlock = vectorSize1;
1410 const size_t sizeOfAvgs1 = avgs1.size();
1411 const size_t sizeOfAvgs2 = avgs2.size();
1413 vector<uint32_t> blockIds1;
1414 vector<uint32_t> blockIds2;
1415 blockIds1.reserve(sizeOfAvgs1);
1416 blockIds2.reserve(sizeOfAvgs2);
1418 for( unordered_map<uint32_t, vector<double> >::const_iterator it = avgs1.begin(); it != avgs1.end(); ++it ) {
1419 blockIds1.push_back(it->first);
1421 for( unordered_map<uint32_t, vector<double> >::const_iterator it = avgs2.begin(); it != avgs2.end(); ++it ) {
1422 blockIds2.push_back(it->first);
1426 sort(blockIds1.begin(), blockIds1.end());
1427 sort(blockIds2.begin(), blockIds2.end());
1429 vector<uint32_t>::const_iterator it1 = blockIds1.begin();
1430 vector<uint32_t>::const_iterator it2 = blockIds2.begin();
1433 vector<uint32_t> identicalBlockIds;
1434 vector<uint32_t> nonIdenticalBlockIds;
1437 if (it1 == blockIds1.end() || it2 == blockIds2.end()) {
1443 identicalBlockIds.push_back(*it1);
1446 }
else if (*it1 < *it2) {
1449 nonIdenticalBlockIds.push_back(*it1);
1451 }
else if (*it2 < *it1) {
1454 nonIdenticalBlockIds.push_back(*it2);
1460 for (; it1 != blockIds1.end(); ++it1) {
1461 nonIdenticalBlockIds.push_back(*it1);
1463 for (; it2 != blockIds2.end(); ++it2) {
1464 nonIdenticalBlockIds.push_back(*it2);
1467 const uint64_t totalNumberOfBlocks = identicalBlockIds.size() + nonIdenticalBlockIds.size();
1468 const double percentageOfIdenticalBlocks = (double)(totalNumberOfBlocks) / (double)(identicalBlockIds.size());
1470 avgsDiffs.reserve(avgsDiffs.size() + identicalBlockIds.size() * velocityCellsPerBlock);
1471 for (vector<uint32_t>::const_iterator it = identicalBlockIds.begin(); it != identicalBlockIds.end(); ++it) {
1473 const uint32_t blockId = *it;
1475 const vector<double> & avgsValues1 = avgs1.at(blockId);
1476 const vector<double> & avgsValues2 = avgs2.at(blockId);
1478 for (uint
i = 0;
i < velocityCellsPerBlock; ++
i) {
1482 numOfRelevantCells++;
1484 avgsDiffs.push_back(
abs(val1 - val2));
1485 totalAbsAvgs += (
abs(val1) +
abs(val2));
1486 totalAbsDiff +=
abs(val1 - val2);
1487 totalAbsLog10Diff +=
abs(log10(val1) - log10(val2));
1491 vector<double> zeroAvgs(velocityCellsPerBlock, 0);
1492 for( vector<uint32_t>::const_iterator it = nonIdenticalBlockIds.begin(); it != nonIdenticalBlockIds.end(); ++it ) {
1494 const uint32_t blockId = *it;
1497 const vector<double>* avgsValues1;
1498 const vector<double>* avgsValues2;
1500 unordered_map<uint32_t, vector<double> >::const_iterator it2 = avgs1.find( blockId );
1501 if( it2 == avgs1.end() ) {
1502 avgsValues1 = &zeroAvgs;
1504 avgsValues1 = &(it2->second);
1507 it2 = avgs2.find(blockId);
1508 if (it2 == avgs2.end()) {
1509 avgsValues2 = &zeroAvgs;
1511 avgsValues2 = &(it2->second);
1514 for (uint
i = 0;
i < velocityCellsPerBlock; ++
i) {
1518 numOfRelevantCells++;
1520 avgsDiffs.push_back(
abs(val1 - val2));
1521 totalAbsAvgs += (
abs(val1) +
abs(val2));
1522 totalAbsDiff +=
abs(val1 - val2);
1523 totalAbsLog10Diff +=
abs(log10(val1) - log10(val2));
1526 numOfIdenticalBlocks += identicalBlockIds.size();
1527 numOfNonIdenticalBlocks += nonIdenticalBlockIds.size();
1531 double minDiff = numeric_limits<Real>::max();
1533 for (vector<double>::const_iterator it = avgsDiffs.begin(); it != avgsDiffs.end(); ++it) {
1535 if (maxDiff < *it) {
1538 if (minDiff > *it) {
1545 vlsvReader1.readParameter(
"time", time1);
1546 vlsvReader2.readParameter(
"time", time2);
1548 const double relativeSumDiff = sumDiff / totalAbsAvgs;
1549 cout <<
"File names: " << fileName1 <<
" & " << fileName2 << endl
1550 << setprecision(3) <<
"NonIdenticalBlocks: " << numOfNonIdenticalBlocks << endl
1551 <<
"IdenticalBlocks: " << numOfIdenticalBlocks << endl
1552 <<
"Absolute_Error: " << totalAbsDiff << endl
1553 <<
"Mean-Absolute-Error: " << totalAbsDiff / numOfRelevantCells << endl
1554 <<
"Max-Absolute-Error: " << maxDiff << endl
1555 <<
"Absolute-log-Error: " << totalAbsLog10Diff << endl
1556 <<
"Mean-Absolute-log-Error: " << totalAbsLog10Diff / numOfRelevantCells << endl
1557 <<
"Delta-t: " << time2 - time1 << endl;
1570bool process2Files(
const string fileName1,
const string fileName2,
const char* varToExtract,
const uint compToExtract,
1571 const bool verboseOutput,
const uint compToExtract2 = 0) {
1572 map<uint, Real> orderedData1;
1573 map<uint, Real> orderedData2;
1574 Real absolute, relative, mini, maxi, size, avg, stdev;
1578 if (strcmp(varToExtract,
"proton") == 0 &&
attributes.find(
"--no-distrib") ==
attributes.end()) {
1579 vector<uint64_t> cellIds1;
1580 vector<uint64_t> cellIds2;
1581 cellIds1.reserve(1);
1582 cellIds2.reserve(1);
1583 cellIds1.push_back(compToExtract);
1584 cellIds2.push_back(compToExtract2);
1590 unordered_map<size_t, size_t> cellOrder;
1592 bool success =
true;
1596 if (success ==
false) {
1597 cerr <<
"ERROR Data import error with " << fileName1 << endl;
1604 if (success ==
false) {
1605 cerr <<
"ERROR Data import error with " << fileName2 << endl;
1610 if (orderedData1.size() != orderedData2.size()) {
1611 cerr <<
"ERROR Datasets have different size." << endl;
1616 const string prefix = fileName1.substr(0, fileName1.find_last_of(
'.'));
1617 const string suffix = fileName1.substr(fileName1.find_last_of(
'.'), fileName1.size());
1618 string outputFileName = prefix +
".diff." + varToExtract + suffix;
1619 const string varName = varToExtract;
1620 vlsv::Writer outputFile;
1622 if (outputFileName[0] ==
'.' && outputFileName[1] ==
'/') {
1623 outputFileName = outputFileName.substr(2, string::npos);
1626 for (
size_t s = 0; s < outputFileName.size(); ++s)
1627 if (outputFileName[s] ==
'/')
1628 outputFileName[s] =
'_';
1630 if (outputFile.open(outputFileName, MPI_COMM_SELF, 0) ==
false) {
1631 cerr <<
"ERROR failed to open output file '" << outputFileName <<
"' in " << __FILE__ <<
":" << __LINE__ << endl;
1635 map<string, string>::const_iterator it =
attributes.find(
"--meshname");
1636 if (
cloneMesh(fileName1, outputFile, it->second, orderedData1) ==
false) {
1637 std::cerr <<
"Failed" << std::endl;
1644 outputStats(&size, &mini, &maxi, &avg, &stdev, verboseOutput,
false);
1647 outputStats(&size, &mini, &maxi, &avg, &stdev, verboseOutput,
false);
1649 pDistance(orderedData1, orderedData2, 0, &absolute, &relative,
false, cellOrder, outputFile,
attributes[
"--meshname"],
"d0_" + varName);
1650 outputDistance(0, &absolute, &relative,
false, verboseOutput,
false);
1651 pDistance(orderedData1, orderedData2, 0, &absolute, &relative,
true, cellOrder, outputFile,
attributes[
"--meshname"],
"d0_sft_" + varName);
1652 outputDistance(0, &absolute, &relative,
true, verboseOutput,
false);
1654 pDistance(orderedData1, orderedData2, 1, &absolute, &relative,
false, cellOrder, outputFile,
attributes[
"--meshname"],
"d1_" + varName);
1655 outputDistance(1, &absolute, &relative,
false, verboseOutput,
false);
1656 pDistance(orderedData1, orderedData2, 1, &absolute, &relative,
true, cellOrder, outputFile,
attributes[
"--meshname"],
"d1_sft_" + varName);
1657 outputDistance(1, &absolute, &relative,
true, verboseOutput,
false);
1659 pDistance(orderedData1, orderedData2, 2, &absolute, &relative,
false, cellOrder, outputFile,
attributes[
"--meshname"],
"d2_" + varName);
1660 outputDistance(2, &absolute, &relative,
false, verboseOutput,
false);
1661 pDistance(orderedData1, orderedData2, 2, &absolute, &relative,
true, cellOrder, outputFile,
attributes[
"--meshname"],
"d2_sft_" + varName);
1662 outputDistance(2, &absolute, &relative,
true, verboseOutput,
false);
1664 outputDt(time2 - time1, verboseOutput,
false);
1669 if (verboseOutput ==
false) {
1784 MPI_Init(&argn, &args);
1787 map<string, string> defAttribs;
1788 map<string, string> descriptions;
1789 defAttribs.insert(make_pair(
"--meshname",
"SpatialGrid"));
1790 defAttribs.insert(make_pair(
"--filemask",
"bulk"));
1791 defAttribs.insert(make_pair(
"--help",
""));
1792 defAttribs.insert(make_pair(
"--no-distrib",
""));
1793 defAttribs.insert(make_pair(
"--diff",
""));
1795 descriptions[
"--meshname"] =
"Name of the spatial mesh that is used in diff.";
1796 descriptions[
"--filemask"] =
"File mask used in directory comparison mode. For example, if you want to compare "
1797 "files starting with 'fullf', set '--filemask=fullf'.";
1798 descriptions[
"--help"] =
"Print this help message.";
1799 descriptions[
"--diff"] =
"If set, difference file(s) are written.";
1800 descriptions[
"--no-distrib"] =
1801 "If set, velocity block data are not compared even if the given variable corresponds to velocity block data.";
1804 for (map<string, string>::const_iterator it = defAttribs.begin(); it != defAttribs.end(); ++it) {
1805 if (it->second.size() == 0)
continue;
1806 attributes.insert(make_pair(it->first, it->second));
1809 vector<string> argsVector;
1814 if (args[
i][1] ==
'\0') {
1815 argsVector.push_back(args[
i]);
1819 if (args[
i][0] ==
'-' && args[
i][1] ==
'-') {
1822 if (s.find(
"=") == string::npos) {
1823 attributes.insert(make_pair(
string(args[
i]),
""));
1825 size_t pos = s.find(
"=");
1826 string arg = s.substr(0, s.find(
'='));
1827 string val = s.substr(s.find(
'=') + 1, string::npos);
1833 if (s.find(
"=") == string::npos) {
1834 attributes.insert(make_pair(
string(args[
i]),
""));
1836 size_t pos = s.find(
"=");
1837 string arg = s.substr(0, s.find(
'='));
1838 string val = s.substr(s.find(
'=') + 1, string::npos);
1845 argsVector.push_back(args[
i]);
1855 if (argsVector.size() < 5) {
1857 cout <<
"USAGE 1: ./vlsvdiff <file1> <file2> <Variable> <component>" << endl;
1858 cout <<
"Gives single-file statistics and distances between the two files given, for the variable and component given" << endl;
1859 cout <<
"USAGE 2: ./vlsvdiff <folder1> <folder2> <Variable> <component>" << endl;
1860 cout <<
"Gives single-file statistics and distances between pairs of files grid*.vlsv taken in alphanumeric "
1861 "order in the two folders given, for the variable and component given" << endl;
1862 cout <<
"USAGE 3: ./vlsvdiff <file1> <folder2> <Variable> <component>" << endl;
1863 cout <<
" ./vlsvdiff <folder1> <file2> <Variable> <component>" << endl;
1864 cout <<
"Gives single-file statistics and distances between a file, and files grid*.vlsv taken in alphanumeric "
1865 "order in the given folder, for the variable and component given" << endl;
1867 cout <<
"Type ./vlsvdiff --help for more info" << endl;
1873 const string fileName1 = argsVector[1];
1875 const string fileName2 = argsVector[2];
1877 const char* varToExtract = argsVector[3].c_str();
1880 uint compToExtract = atoi(argsVector[4].c_str());
1882 uint compToExtract2;
1883 if (argsVector.size() > 5) {
1884 compToExtract2 = atoi(argsVector[5].c_str());
1886 compToExtract2 = compToExtract;
1890 if (
attributes[
"--meshname"] ==
"SpatialGrid") {
1892 }
else if (
attributes[
"--meshname"] ==
"fsgrid") {
1894 }
else if (
attributes[
"--meshname"] ==
"ionosphere") {
1897 std::cout <<
attributes[
"--meshname"] << std::endl;
1898 std::cerr <<
"Wrong grid type" << std::endl;
1902 DIR* dir1 = opendir(fileName1.c_str());
1903 DIR* dir2 = opendir(fileName2.c_str());
1905 if (dir1 ==
nullptr && dir2 ==
nullptr) {
1906 cout <<
"INFO Reading in two files." << endl;
1909 process2Files(fileName1, fileName2, varToExtract, compToExtract,
true, compToExtract2);
1910 }
else if (dir1 ==
nullptr || dir2 ==
nullptr) {
1912 cout <<
"#INFO Reading in one file and one directory." << endl;
1915 if (dir1 ==
nullptr) {
1918 for (
auto f : fileList) {
1920 process2Files(fileName1, fileName2 +
"/" + f, varToExtract, compToExtract,
false, compToExtract2);
1925 if (dir2 ==
nullptr) {
1928 for (
auto f : fileList) {
1930 process2Files(fileName1 +
"/" + f, fileName2, varToExtract, compToExtract,
false, compToExtract2);
1934 }
else if (dir1 && dir2) {
1936 cout <<
"#INFO Reading in two directories." << endl;
1944 if (fileList1.size() != fileList2.size()) {
1945 cerr <<
"ERROR Folders have different number of files." << endl;
1950 for (
auto it1 = fileList1.begin(), it2 = fileList2.begin(); it1 != fileList2.end(), it2 != fileList2.end(); it1++, it2++) {
1952 process2Files(fileName1 +
"/" + *it1, fileName2 +
"/" + *it2, varToExtract, compToExtract,
false, compToExtract2);