30#include <unordered_map>
31#include <unordered_set>
37#include "bitpit_private_lapacke.hpp"
38#include "bitpit_voloctree.hpp"
41#include "pod_voloctree.hpp"
71: m_filter(1), m_sensorMask(1)
75 m_communicator = MPI_COMM_NULL;
78 m_podkernel =
nullptr;
79 m_meshType = MeshType::UNDEFINED;
84 m_nModes = std::numeric_limits<std::size_t>::max();
88 m_nReconstructionSnapshots = 0;
94 initializeCommunicator(comm);
95 MPI_Comm_size(m_communicator, &m_nProcs);
96 MPI_Comm_rank(m_communicator, &m_rank);
102 m_memoryMode = MemoryMode::MEMORY_NORMAL;
103 m_runMode = RunMode::COMPUTE;
104 m_writeMode = WriteMode::DUMP;
105 m_reconstructionMode = ReconstructionMode::MINIMIZATION;
106 m_errorMode = ErrorMode::NONE;
132 m_correlationMatrices.clear();
134 m_minimizationMatrices.clear();
137 m_reconstructionDatabase.clear();
138 m_leave1outOffDatabase.clear();
144 m_nReconstructionSnapshots = 0;
147 m_podkernel->clearMapper();
150# if BITPIT_ENABLE_MPI
183 if (stat(directory.c_str(), &info) != 0) {
184 throw std::runtime_error(
"The directory \"" + directory +
"\" does not exists!");
185 }
else if (!(info.st_mode & S_IFDIR)) {
186 throw std::runtime_error(
"The directory \"" + directory +
"\" is not valid: a file with the same name was found!");
189 m_directory = directory +
"/";
221 m_database.push_back(file);
232 m_database = database;
233 m_nSnapshots = database.size();
256 m_leave1outOffDatabase.push_back(file);
264 std::size_t nsoff=m_leave1outOffDatabase.size();
265 for (std::size_t i=0; i<m_nSnapshots; ++i){
266 std::string snapi=m_database[i].directory+
"/"+m_database[i].name;
267 for (std::size_t j=0; j<nsoff; ++j){
268 std::string snapj=m_leave1outOffDatabase[j].directory+
"/"+m_leave1outOffDatabase[j].name;
269 if (m_database[i].directory == m_leave1outOffDatabase[j].directory && m_database[i].name == m_leave1outOffDatabase[j].name)
270 m_listActiveIDsLeave1out.push_back(i);
295 m_reconstructionDatabase.push_back(file);
296 m_nReconstructionSnapshots++;
328 m_energyLevel = energy - ENERGY_CHECK_TOLERANCE;
338 return m_energyLevel + ENERGY_CHECK_TOLERANCE;
348 m_errorThreshold = threshold;
358 return m_errorThreshold;
369 std::map<std::string, std::size_t> fields;
370 std::size_t nsf= namesf.size();
371 std::size_t nvf= namevf.size();
373 for (std::size_t ifield=0; ifield<nsf; ++ifield)
374 fields[namesf[ifield]] = ifield;
376 for (std::size_t ifield=0; ifield<nvf; ++ifield){
377 for (std::size_t j=0; j<3; ++j)
378 fields[namevf[ifield][j]] = ifield*3+nsf+j;
381 m_nameTargetErrorFields = fields;
393 throw std::runtime_error (
"POD mesh type already set. Change not allowed.");
401 m_podkernel = std::unique_ptr<PODKernel>(
new PODVolOctree(m_communicator));
403 m_podkernel = std::unique_ptr<PODKernel>(
new PODVolOctree());
408 throw std::runtime_error (
"POD mesh type not allowed.");
422 throw std::runtime_error (
"POD mesh type not set.");
425 if (_octreecast_mesh){
427 throw std::runtime_error (
"POD mesh type not set to VolOctree.");
428 m_podkernel->setMesh(std::move(mesh));
431 throw std::runtime_error (
"POD mesh type not allowed.");
443void POD::setMesh(
const std::string &directory,
const std::string &name)
459 throw std::runtime_error (
"POD mesh type not set.");
461 std::unique_ptr<VolumeKernel> mesh = m_podkernel->readMesh(file);
507 if (m_memoryMode == mode) {
544 if (m_runMode == mode) {
578 if (m_writeMode == mode)
600 if (m_reconstructionMode == mode)
625 return m_reconstructionMode;
637 if (m_errorMode == mode)
677 if (m_staticMesh || mesh == m_podkernel->getMesh()){
679 for (
const Cell &cell : m_podkernel->getMesh()->getCells()) {
680 long id = cell.getId();
681 m_sensorMask[id] = mask[id];
688 throw std::runtime_error (
"POD: null mesh pointer passed to setSensorMask");
691 if (m_podkernel->isMapperDirty())
692 _computeMapper(mesh);
694 std::unordered_set<long> trueCells;
696 long id = cell.getId();
698 trueCells.insert(
id);
702 std::unordered_set<long> mappedCells = m_podkernel->mapCellsToPOD(&trueCells);
704 m_podkernel->mapBoolFieldToPOD(mask, mesh, &mappedCells, m_sensorMask);
730 return m_nameScalarFields;
740 return m_nameVectorFields;
751 std::vector<std::string> names;
752 for (
const std::string &ss : m_nameScalarFields)
754 for (
const std::array<std::string,3> &ssa : m_nameVectorFields){
755 for (
const std::string &ss : ssa)
769 if (m_podkernel ==
nullptr)
770 throw std::runtime_error (
"POD mesh not built");
772 return m_podkernel->getMesh();
802 return m_reconstructionCoeffs;
810 return m_listActiveIDs;
818 return m_sizeInternal;
840 log::cout() <<
"pod : evaluate decomposition ... " << std::endl;
843 log::cout() <<
"pod : restore decomposition ... " << std::endl;
848 log::cout() <<
"pod : evaluate reconstruction ... " << std::endl;
876 log::cout() <<
"pod : computing mean field and pod mesh... " << std::endl;
883 log::cout() <<
"pod : computing correlation matrix... " << std::endl;
887 log::cout() <<
"pod : computing eigenvectors... " << std::endl;
891 log::cout() <<
"pod : computing pod modes... " << std::endl;
896 log::cout() <<
"pod : dumping... " << std::endl;
906 int dumpBlock = (m_nProcs > 1) ? m_rank : -1;
908 log::cout() <<
"Dumping POD ... " << std::endl;
910 std::string header =
"pod";
911 OBinaryArchive binaryWriter(m_directory + m_name, ARCHIVE_VERSION, header, dumpBlock);
912 std::ostream &dataStream = binaryWriter.
getStream();
916 for (std::size_t i = 0; i < m_nSnapshots; ++i) {
922 binaryWriter.close();
926 for (std::size_t ir = 0; ir < m_nModes; ++ir)
938 std::string header =
"podmask";
939 OBinaryArchive binaryWriter(m_directory + m_name +
".mask.data", ARCHIVE_VERSION, header, dumpBlock);
940 std::ostream &dataStream = binaryWriter.
getStream();
941 m_sensorMask.
dump(dataStream);
942 binaryWriter.close();
947 std::string header =
"podmesh";
948 OBinaryArchive binaryWriter(m_directory + m_name +
".mesh", ARCHIVE_VERSION, header, dumpBlock);
949 m_podkernel->getMesh()->dump(binaryWriter.
getStream());
950 binaryWriter.close();
955 std::vector<std::string > datastring;
956 m_podkernel->getMesh()->getVTK().setDirectory(m_directory);
957 m_podkernel->getMesh()->getVTK().setName(m_name);
959 std::size_t nf=m_nModes;
962 std::vector<std::vector<std::vector<double>>> fields(nf, std::vector<std::vector<double>> (m_nScalarFields, std::vector<double>(m_podkernel->getMesh()->getInternalCellCount(), 0.0)));
963 std::vector<std::vector<std::vector<std::array<double,3>>>> fieldv(nf, std::vector<std::vector<std::array<double,3>>>(m_nVectorFields, std::vector<std::array<double,3>>(m_podkernel->getMesh()->getInternalCellCount(), {{0.0, 0.0, 0.0}})));
966 for (std::size_t isf = 0; isf < m_nScalarFields; ++isf) {
968 for (
const Cell &cell : m_podkernel->getMesh()->getCells()) {
969 if (cell.isInterior()) {
970 long id = cell.getId();
971 fields[0][isf][i] = m_mean.
scalar->at(
id, isf);
975 m_podkernel->getMesh()->getVTK().addData(
"scalarField" + std::to_string(isf) +
"_mean", VTKFieldType::SCALAR, VTKLocation::CELL, fields[0][isf]);
976 datastring.push_back(
"scalarField" + std::to_string(isf) +
"_mean");
978 for (std::size_t ivf = 0; ivf < m_nVectorFields; ++ivf) {
980 for (
const Cell &cell : m_podkernel->getMesh()->getCells()) {
981 if (cell.isInterior()) {
982 long id = cell.getId();
983 fieldv[0][ivf][i] = m_mean.
vector->at(
id, ivf);
987 m_podkernel->getMesh()->getVTK().addData(
"vectorField"+std::to_string(ivf)+
"_mean", VTKFieldType::VECTOR, VTKLocation::CELL, fieldv[0][ivf]);
988 datastring.push_back(
"vectorField"+std::to_string(ivf)+
"_mean");
991 for (std::size_t ir = 0; ir < m_nModes; ++ir) {
995 std::size_t nir = ir;
999 for (std::size_t isf = 0; isf < m_nScalarFields; ++isf) {
1001 for (
const Cell &cell : m_podkernel->getMesh()->getCells()) {
1002 if (cell.isInterior()) {
1003 long id = cell.getId();
1004 fields[nir][isf][i] = m_modes[ir].scalar->at(
id, isf);
1008 m_podkernel->getMesh()->getVTK().addData(
"scalarField"+std::to_string(isf)+
"_podMode"+std::to_string(ir), VTKFieldType::SCALAR, VTKLocation::CELL, fields[nir][isf]);
1009 datastring.push_back(
"scalarField"+std::to_string(isf)+
"_podMode"+std::to_string(ir));
1012 for (std::size_t ivf = 0; ivf < m_nVectorFields; ++ivf) {
1014 for (
const Cell &cell : m_podkernel->getMesh()->getCells()) {
1015 if (cell.isInterior()) {
1016 long id = cell.getId();
1017 fieldv[nir][ivf][i] = m_modes[ir].vector->at(
id, ivf);
1021 m_podkernel->getMesh()->getVTK().addData(
"vectorField"+std::to_string(ivf)+
"_podMode"+std::to_string(ir), VTKFieldType::VECTOR, VTKLocation::CELL, fieldv[nir][ivf]);
1022 datastring.push_back(
"vectorField"+std::to_string(ivf)+
"_podMode"+std::to_string(ir));
1026 m_modes[ir].clear();
1029 std::vector<uint8_t> mask(m_podkernel->getMesh()->getInternalCellCount(), 0);
1031 for (
const Cell &cell : m_podkernel->getMesh()->getCells()) {
1032 if (cell.isInterior()) {
1033 long id = cell.getId();
1034 mask[i] = m_filter[id];
1039 m_podkernel->getMesh()->getVTK().addData(
"filter", VTKFieldType::SCALAR, VTKLocation::CELL, mask);
1040 datastring.push_back(
"filter");
1041 m_podkernel->getMesh()->write();
1043 for (std::size_t is = 0; is < datastring.size(); ++is)
1044 m_podkernel->getMesh()->getVTK().removeData(datastring[is]);
1051void POD::restoreDecomposition()
1053 int dumpBlock = (m_nProcs > 1) ? m_rank : -1;
1056 log::cout() <<
"Restore POD ... " << std::endl;
1058 std::string header =
"pod";
1060 std::istream &dataStream = binaryReader.
getStream();
1062 utils::binary::read(dataStream, m_meshType_);
1063 setMeshType(m_meshType_);
1065 utils::binary::read(dataStream, nr_);
1066 m_nModes = std::min(m_nModes, nr_);
1067 m_modes.resize(m_nModes);
1068 utils::binary::read(dataStream, m_nSnapshots);
1069 m_database.resize(m_nSnapshots);
1070 for (std::size_t i = 0; i < m_nSnapshots; ++i) {
1071 utils::binary::read(dataStream, m_database[i].directory);
1072 utils::binary::read(dataStream, m_database[i].name);
1074 utils::binary::read(dataStream,m_staticMesh);
1075 utils::binary::read(dataStream,m_memoryMode);
1076 binaryReader.close();
1082 podfile.
name = m_name;
1083 m_podkernel->restoreMesh(podfile);
1088 m_filter.unsetKernel();
1089 m_filter.setStaticKernel(&m_podkernel->getMesh()->getCells());
1090 m_sensorMask.unsetKernel();
1091 m_sensorMask.setStaticKernel(&m_podkernel->getMesh()->getCells());
1093 if (m_memoryMode == MemoryMode::MEMORY_NORMAL) {
1094 for (std::size_t ir = 0; ir < m_nModes; ++ir) {
1107 IBinaryArchive binaryReader(m_directory + m_name +
".mask.data", dumpBlock);
1108 std::istream &dataStream = binaryReader.
getStream();
1109 m_sensorMask.restore(dataStream);
1110 binaryReader.close();
1114 fillListActiveIDs(m_sensorMask);
1121void POD::leave1out()
1123 setErrorMode(ErrorMode::COMBINED);
1124 setReconstructionMode(ReconstructionMode::PROJECTION);
1125 unsetLeave1outSnapshots();
1128 log::cout() <<
"pod : computing pod mesh... " << std::endl;
1132 fillListActiveIDs(m_filter);
1135 log::cout() <<
"pod : computing correlation matrix... " << std::endl;
1142 std::vector<std::vector<double>> h_correlationMatrices=m_correlationMatrices;
1143 std::vector<pod::SnapshotFile> h_database=m_database;
1144 std::size_t h_nSnapshots=m_nSnapshots;
1145 std::size_t nl1o=m_listActiveIDsLeave1out.size();
1147 m_nSnapshots=h_nSnapshots-1;
1149 for (std::size_t i=0; i<nl1o; ++i){
1150 std::size_t
id = m_listActiveIDsLeave1out[i];
1151 log::cout() <<
">> leave-1-out : removing snapshot " << m_database[id].directory+
"/"+m_database[id].name<< std::endl;
1153 m_reconstructionDatabase.clear();
1154 m_nReconstructionSnapshots = 0;
1155 addReconstructionSnapshot(m_database[
id]);
1156 m_database.erase(m_database.begin()+
id);
1158 for (std::size_t ifield = 0; ifield<m_nFields; ++ifield){
1160 m_correlationMatrices[ifield].erase(m_correlationMatrices[ifield].begin()+
id*h_nSnapshots, m_correlationMatrices[ifield].begin()+
id*h_nSnapshots+h_nSnapshots);
1164 for (std::size_t j=0; j<m_nSnapshots; ++j){
1165 m_correlationMatrices[ifield].erase(m_correlationMatrices[ifield].begin()+it);
1166 it= it-1+h_nSnapshots;
1171 log::cout() <<
"pod : computing eigenvectors... " << std::endl;
1175 log::cout() <<
"pod : computing pod modes... " << std::endl;
1179 evalReconstruction();
1182 m_correlationMatrices=h_correlationMatrices;
1183 m_database=h_database;
1188 if (m_writeMode != WriteMode::NONE){
1189 std::string ename = m_name +
".error";
1190 dumpField(ename, m_errorMap);
1192 m_nSnapshots=h_nSnapshots;
1200void POD::evalMeanMesh()
1202 if (m_database.empty())
1203 throw std::runtime_error (
"POD database empty");
1209#if BITPIT_ENABLE_MPI
1210 m_podkernel->getMesh()->setVTKWriteTarget(PatchKernel::WriteTarget::WRITE_TARGET_CELLS_INTERNAL);
1212 m_podkernel->getMesh()->setVTKWriteTarget(PatchKernel::WriteTarget::WRITE_TARGET_CELLS_ALL);
1219void POD::_evalMeanMesh()
1222 if (m_podkernel->getMesh() ==
nullptr){
1225 std::unique_ptr<VolumeKernel> readMesh = m_podkernel->readMesh(m_database[0]);
1226 m_podkernel->setMesh(std::move(readMesh));
1231 for (std::size_t i = 1; i < m_nSnapshots; ++i) {
1232 log::cout() <<
"pod : evaluation POD mesh - use snapshot " << i+1 <<
"/" << m_nSnapshots << std::endl;
1233 std::unique_ptr<VolumeKernel> readMesh = m_podkernel->readMesh(m_database[i]);
1234 m_podkernel->adaptMeshToMesh(m_podkernel->getMesh(), readMesh.get());
1235 m_podkernel->clearMapper();
1242 pod::PODField readf;
1243 readSnapshot(m_database[0], readf);
1247 m_podkernel->evalCellsVolume();
1249 m_filter.unsetKernel();
1250 m_filter.setStaticKernel(&(m_podkernel->getMesh()->getCells()));
1251 m_filter.fill(
true);
1255 m_mean.scalar = std::unique_ptr<pod::ScalarStorage>(
new pod::ScalarStorage(m_nScalarFields, &m_podkernel->getMesh()->getCells()));
1256 m_mean.vector = std::unique_ptr<pod::VectorStorage>(
new pod::VectorStorage(m_nVectorFields, &m_podkernel->getMesh()->getCells()));
1257 m_mean.scalar->fill(0.0);
1258 m_mean.vector->fill(std::array<double, 3>{{0.0, 0.0, 0.0}});
1261 for (std::size_t i = 0; i < m_nSnapshots; ++i) {
1262 log::cout() <<
"pod : evaluation mean - use snapshot " << i+1 <<
"/" << m_nSnapshots << std::endl;
1263 pod::PODField readf;
1264 readSnapshot(m_database[i], readf);
1267 _computeMapper(readf.mesh);
1268 readf = pod::PODField(m_podkernel->mapPODFieldToPOD(readf,
nullptr));
1269 m_podkernel->clearMapper();
1272 for (
const Cell &cell : m_podkernel->getMesh()->getCells()) {
1273 m_filter[cell.getId()] = (m_filter[cell.getId()]) && (readf.mask->at(cell.getId()));
1274 if (m_filter[cell.getId()]){
1275 for (std::size_t j = 0; j < m_nScalarFields; ++j)
1276 m_mean.scalar->at(cell.getId(),j) += readf.scalar->at(cell.getId(),j) /
double(m_nSnapshots);
1277 for (std::size_t j = 0; j < m_nVectorFields; ++j)
1278 m_mean.vector->at(cell.getId(),j) += readf.vector->at(cell.getId(),j) /
double(m_nSnapshots);
1281 for (std::size_t j = 0; j < m_nScalarFields; ++j)
1282 m_mean.scalar->at(cell.getId(),j) = 0.0;
1283 for (std::size_t j = 0; j < m_nVectorFields; ++j)
1284 m_mean.vector->at(cell.getId(),j) = {{0.0, 0.0, 0.0}};
1291 for (std::size_t i = 0; i < m_nSnapshots; ++i) {
1292 pod::PODField readf;
1293 readSnapshot(m_database[i], readf);
1296 _computeMapper(readf.mesh);
1297 readf = pod::PODField(m_podkernel->mapPODFieldToPOD(readf,
nullptr));
1298 m_podkernel->clearMapper();
1301 for (
const Cell &cell : m_podkernel->getMesh()->getCells())
1302 m_filter[cell.getId()] = (m_filter[cell.getId()]) && (readf.mask->at(cell.getId()));
1307 setSensorMask(m_filter, m_podkernel->getMesh());
1320 m_listActiveIDs.clear();
1321 std::unordered_set<long> listGhost;
1322 for (
const Cell &cell : m_podkernel->getMesh()->getCells()) {
1323 long id = cell.getId();
1326 if (mask[
id] && cell.isInterior()) {
1327 if (cell.isInterior()) {
1328 m_listActiveIDs.insert(
id);
1330 listGhost.insert(
id);
1335 m_sizeInternal = m_listActiveIDs.size();
1345void POD::evalCorrelation()
1348 for (std::size_t i = 0; i < m_nSnapshots; ++i){
1350 readSnapshot(m_database[i], snapi);
1352 _computeMapper(snapi.
mesh);
1353 snapi =
pod::PODField(m_podkernel->mapPODFieldToPOD(snapi,
nullptr));
1354 m_podkernel->clearMapper();
1358 diff(&snapi, m_mean);
1360 for (std::size_t j = i; j < m_nSnapshots; ++j){
1361 log::cout() <<
"pod : evaluation " << i <<
"," << j <<
" term of correlation matrix " << std::endl;
1363 readSnapshot(m_database[j], snapj);
1365 _computeMapper(snapj.
mesh);
1366 snapj =
pod::PODField(m_podkernel->mapPODFieldToPOD(snapj,
nullptr));
1367 m_podkernel->clearMapper();
1371 diff(&snapj, m_mean);
1373 evalCorrelationTerm(i, snapi, j, snapj);
1378# if BITPIT_ENABLE_MPI
1379 for (std::size_t i = 0; i < m_nFields; i++ )
1380 MPI_Allreduce(MPI_IN_PLACE, m_correlationMatrices[i].data(), m_nSnapshots*m_nSnapshots, MPI_DOUBLE, MPI_SUM, m_communicator);
1388void POD::initCorrelation()
1390 m_correlationMatrices.clear();
1391 m_correlationMatrices.resize(m_nFields,std::vector<double>(m_nSnapshots*m_nSnapshots, 0.0));
1397void POD::initErrorMaps()
1400 m_errorMap.mesh = m_podkernel->getMesh();
1401 m_errorMap.scalar = std::unique_ptr<pod::ScalarStorage>(
new pod::ScalarStorage(m_nScalarFields, &m_podkernel->getMesh()->getCells()));
1402 m_errorMap.vector = std::unique_ptr<pod::VectorStorage>(
new pod::VectorStorage(m_nVectorFields, &m_podkernel->getMesh()->getCells()));
1403 m_errorMap.scalar->fill(0.0);
1404 m_errorMap.vector->fill(std::array<double, 3>{{0.0, 0.0, 0.0}});
1405 m_errorMap.mask = std::unique_ptr<PiercedStorage<bool>>(
new PiercedStorage<bool>(1, &m_podkernel->getMesh()->getCells()));
1406 m_errorMap.mask->fill(0);
1407 for (
long id : m_listActiveIDs)
1408 m_errorMap.mask->at(id)=1;
1415void POD::evalCorrelationTerm(
int i, pod::PODField & snapi,
int j, pod::PODField & snapj)
1418 std::unordered_set<long>::iterator it;
1419 for (it = m_listActiveIDs.begin(); it != m_listActiveIDs.end(); ++it){
1421 std::size_t rawIndex = m_podkernel->getMesh()->getCells().getRawIndex(
id);
1422 if (m_nScalarFields){
1423 double* datasi = snapi.scalar->rawData(rawIndex);
1424 double* datasj = snapj.scalar->rawData(rawIndex);
1425 for (std::size_t ifield = 0; ifield < m_nScalarFields; ++ifield){
1426 m_correlationMatrices[ifield][i*m_nSnapshots+j] += (*datasi)*(*datasj)*getRawCellVolume(rawIndex);
1431 if (m_nVectorFields){
1432 std::array<double,3>* datavi = snapi.vector->rawData(rawIndex);
1433 std::array<double,3>* datavj = snapj.vector->rawData(rawIndex);
1434 for (std::size_t ifield = m_nScalarFields; ifield < m_nFields; ++ifield){
1435 m_correlationMatrices[ifield][i*m_nSnapshots+j] +=
dotProduct((*datavi),(*datavj))*getRawCellVolume(rawIndex);
1449void POD::evalReconstruction()
1451 m_reconstructionCoeffs.clear();
1452 m_reconstructionCoeffs.resize(m_nFields, std::vector<double>(m_nModes,0.0));
1454 for (std::size_t i = 0; i < m_nReconstructionSnapshots; ++i){
1456 readSnapshot(m_reconstructionDatabase[i], snapi);
1461 _computeMapper(snapi.
mesh);
1464 snapi =
pod::PODField(m_podkernel->mapPODFieldToPOD(snapi,
nullptr));
1465 m_podkernel->clearMapper();
1469 reconstructFields(snapi, reconi);
1470 std::string rname = m_name +
".recon." + m_reconstructionDatabase[i].name;
1472 if (m_writeMode != WriteMode::NONE && m_errorMode != ErrorMode::COMBINED)
1473 dumpField(rname, reconi);
1475 if (m_errorMode != ErrorMode::COMBINED){
1477 std::ofstream outr(m_directory + m_name +
".recon.coeff."+ m_reconstructionDatabase[i].name +
".dat", std::ofstream::out);
1478 for (std::size_t j = 0; j < m_nFields; ++j)
1479 outr << m_reconstructionCoeffs[j] << std::endl;
1483 if (m_errorMode == ErrorMode::SINGLE){
1484 std::vector<double> enorm = fieldsl2norm(m_errorMap);
1485 std::string ename = m_name +
".error."+ m_reconstructionDatabase[i].name;
1487 if (m_writeMode != WriteMode::NONE)
1488 dumpField(ename, m_errorMap);
1491 std::ofstream oute(m_directory + m_name +
".error.norm."+ m_reconstructionDatabase[i].name +
".dat", std::ofstream::out);
1492 for (std::size_t j = 0; j < m_nFields; ++j)
1493 oute << enorm[j] << std::endl;
1503void POD::evalErrorBoundingBox()
1505 setWriteMode(WriteMode::NONE);
1507 log::cout()<<
"Reading error field ..."<< std::endl;
1508 log::cout()<< efile.
directory+
"/"+efile.
name +
"..."<< std::endl;
1510 readSnapshot(efile, error);
1512 fillListActiveIDs(*error.mask);
1514 std::vector<std::size_t> scalarIds, vectorIds;
1515 std::map<std::string, std::size_t> targetErrorFields = m_nameTargetErrorFields;
1518 std::size_t count=0;
1519 for (
const std::string &val : m_nameScalarFields) {
1520 std::map<std::string, std::size_t>::iterator found = targetErrorFields.find(val);
1521 if (found != targetErrorFields.end()) {
1522 scalarIds.push_back(count);
1523 targetErrorFields.erase(found);
1529 for (
const std::array<std::string,3> &valv : m_nameVectorFields) {
1531 std::array<std::string,3> toerase;
1532 for (
const std::string &val : valv) {
1533 std::map<std::string, std::size_t>::iterator found = targetErrorFields.find(val);
1534 if (found != targetErrorFields.end()) {
1540 vectorIds.push_back(count);
1541 for (std::size_t i = 0; i < 3; ++i)
1542 targetErrorFields.erase(toerase[i]);
1548 if (targetErrorFields.size() != 0) {
1549 std::string verror =
" ";
1550 for (
const auto &targetErrorField : targetErrorFields)
1551 verror += targetErrorField.first +
" ";
1553 throw std::runtime_error (
"POD: fields not found in POD base or incomplete vector: " + verror);
1556 std::size_t nsf = scalarIds.size();
1557 std::size_t nvf = vectorIds.size();
1559 std::vector<std::array<double, 3>> minBoxes, maxBoxes;
1560 minBoxes.resize(m_nFields, {{0.0, 0.0, 0.0}});
1561 maxBoxes.resize(m_nFields, {{0.0, 0.0, 0.0}});
1563 std::unordered_set<long>::iterator it;
1564 for (it = m_listActiveIDs.begin(); it != m_listActiveIDs.end(); ++it) {
1566 std::array<double, 3> cellCentroid = error.mesh->evalCellCentroid(
id);
1567 std::size_t rawIndex = m_podkernel->getMesh()->getCells().getRawIndex(
id);
1570 double* datas = error.scalar->rawData(rawIndex);
1571 for (std::size_t i = 0; i < nsf; ++i){
1572 double* datasi = datas+scalarIds[i];
1573 if (*datasi >= m_errorThreshold){
1574 maxBoxes[scalarIds[i]]=
max(cellCentroid,maxBoxes[scalarIds[i]]);
1575 minBoxes[scalarIds[i]]=
min(cellCentroid,minBoxes[scalarIds[i]]);
1580 std::array<double,3>* datav = error.vector->rawData(rawIndex);
1581 for (std::size_t i = 0; i< nvf; ++i) {
1582 std::array<double,3>* datavi = datav+vectorIds[i];
1583 if (std::sqrt(
dotProduct((*datavi),(*datavi)) ) >= m_errorThreshold){
1584 maxBoxes[vectorIds[i]]=
max(cellCentroid,maxBoxes[vectorIds[i]]);
1585 minBoxes[vectorIds[i]]=
min(cellCentroid,minBoxes[vectorIds[i]]);
1591# if BITPIT_ENABLE_MPI
1592 MPI_Allreduce(MPI_IN_PLACE,
reinterpret_cast<double *
>(maxBoxes.data()), m_nFields*3, MPI_DOUBLE, MPI_MAX, m_communicator);
1593 MPI_Allreduce(MPI_IN_PLACE,
reinterpret_cast<double *
>(minBoxes.data()), m_nFields*3, MPI_DOUBLE, MPI_MIN, m_communicator);
1596 log::cout()<<
">> Fields Bounding boxes " << std::endl;
1597 log::cout()<<
"min: "<< minBoxes << std::endl;
1598 log::cout()<<
"max: "<< maxBoxes << std::endl;
1600 std::array<double, 3> minBox = {{0.0, 0.0, 0.0}};
1601 std::array<double, 3> maxBox = {{0.0, 0.0, 0.0}};
1603 for (std::size_t i =0; i < m_nFields; ++i){
1604 maxBox=
max(maxBoxes[i],maxBox);
1605 minBox=
min(minBoxes[i],minBox);
1608 log::cout()<<
">> Bounding box " << std::endl;
1609 log::cout()<<
"("<< minBox <<
") ("<< maxBox <<
")"<< std::endl;
1612#if BITPIT_ENABLE_MPI
1613 runSolver = (m_rank == 0);
1618 std::ofstream outBB(m_directory + m_name +
".box.dat", std::ofstream::out);
1619 outBB << minBox << std::endl;
1620 outBB << maxBox << std::endl;
1637 evalReconstructionCoeffs(field);
1638 buildFields(m_reconstructionCoeffs, reconi);
1639 if (m_errorMode != ErrorMode::NONE){
1640 if (m_errorMode == ErrorMode::SINGLE)
1642 buildErrorMaps(field,reconi);
1652void POD::reconstructFields(
const std::vector<std::vector<double>> &reconstructionCoeffs,
1655 reconi.
setMesh(m_podkernel->getMesh());
1656 buildFields(reconstructionCoeffs, reconi);
1668 std::map<std::string, std::size_t> targetFields,
1669 const std::unordered_set<long> * targetCells)
1671 std::vector<std::size_t> podscalarIds;
1672 std::vector<std::size_t> podvectorIds;
1674 std::vector<std::size_t> scalarIds;
1675 std::vector<std::array<std::size_t, 3>> vectorIds;
1678 std::size_t count = 0;
1679 for (
const std::string &val : m_nameScalarFields) {
1680 std::map<std::string, std::size_t>::iterator found = targetFields.find(val);
1681 if (found != targetFields.end()) {
1682 std::size_t ind = found->second;
1683 podscalarIds.push_back(count);
1684 scalarIds.push_back(ind);
1685 targetFields.erase(found);
1692 for (
const std::array<std::string,3> &valv : m_nameVectorFields) {
1694 std::array<std::size_t,3> vectorarr;
1695 std::array<std::string,3> toerase;
1696 for (
const std::string &val : valv) {
1697 std::map<std::string, std::size_t>::iterator found = targetFields.find(val);
1698 if (found != targetFields.end()) {
1699 std::size_t ind = found->second;
1700 vectorarr[ic] = ind;
1706 podvectorIds.push_back(count);
1707 vectorIds.push_back(vectorarr);
1708 for (std::size_t i = 0; i < 3; ++i)
1709 targetFields.erase(toerase[i]);
1715 if (targetFields.size() != 0) {
1716 std::string verror =
" ";
1717 for (
const auto &targetField : targetFields)
1718 verror += targetField.first +
" ";
1720 throw std::runtime_error (
"POD: fields not found in POD base or incomplete vector: " + verror);
1726 evalReconstructionCoeffs(fields, scalarIds, podscalarIds, vectorIds, podvectorIds);
1728 buildFields(m_reconstructionCoeffs, fields, scalarIds, podscalarIds, vectorIds, podvectorIds, targetCells);
1734 if (m_podkernel->isMapperDirty())
1735 _computeMapper(mesh);
1738 PiercedStorage<double> mappedFields = m_podkernel->mapFieldsToPOD(fields, mesh, &m_listActiveIDs, scalarIds, vectorIds);
1740 evalReconstructionCoeffs(mappedFields, scalarIds, podscalarIds, vectorIds, podvectorIds);
1743 std::unordered_set<long> mappedCells;
1744 std::unordered_set<long>* ptr_mappedCells =
nullptr;
1746 mappedCells = m_podkernel->mapCellsToPOD(targetCells);
1747 ptr_mappedCells = &mappedCells;
1750 buildFields(m_reconstructionCoeffs, mappedFields, scalarIds, podscalarIds, vectorIds, podvectorIds, ptr_mappedCells);
1752 m_podkernel->mapFieldsFromPOD(fields, mesh, targetCells, mappedFields, scalarIds, vectorIds);
1766 std::vector<std::vector<double>> reconstructionCoeffs(m_nFields, std::vector<double>(m_nModes,0.0));
1768 diff(&field, m_mean);
1772 for (std::size_t ir = 0; ir < m_nModes; ++ir) {
1773 if (m_memoryMode == MemoryMode::MEMORY_LIGHT) {
1778 for (
long id : m_listActiveIDs) {
1779 std::size_t rawIndex = field.
mesh->
getCells().getRawIndex(
id);
1782 if (m_nScalarFields) {
1783 const double *modes = m_modes[ir].scalar->rawData(rawIndex);
1784 const double *data = field.
scalar->rawData(rawIndex);
1785 for (std::size_t ifs = 0; ifs < m_nScalarFields; ++ifs) {
1786 reconstructionCoeffs[ifs][ir] += data[ifs] * modes[ifs] * getRawCellVolume(rawIndex);
1791 if (m_nVectorFields) {
1792 const std::array<double,3> *modes = m_modes[ir].vector->rawData(rawIndex);
1793 const std::array<double,3> *data = field.
vector->rawData(rawIndex);
1794 for (std::size_t ifv = 0; ifv < m_nVectorFields; ++ifv) {
1795 reconstructionCoeffs[ifv+m_nScalarFields][ir] +=
dotProduct(data[ifv], modes[ifv]) * getRawCellVolume(rawIndex);
1801#if BITPIT_ENABLE_MPI
1802 for (std::size_t i = 0; i < m_nFields; ++i) {
1803 MPI_Allreduce(MPI_IN_PLACE, reconstructionCoeffs[i].data(), m_nModes, MPI_DOUBLE, MPI_SUM, m_communicator);
1808 sum(&field, m_mean);
1811 return reconstructionCoeffs;
1822 std::vector<double>
norm = fieldsMax(snap);
1824 for (
long id : m_listActiveIDs){
1825 std::size_t rawIndex = m_podkernel->getMesh()->getCells().getRawIndex(
id);
1826 if (m_nScalarFields){
1827 double* recons = recon.
scalar->rawData(rawIndex);
1828 double* snaps = snap.
scalar->rawData(rawIndex);
1829 double* errors = m_errorMap.scalar->rawData(rawIndex);
1830 for (std::size_t ifs = 0; ifs < m_nScalarFields; ++ifs){
1831 *errors=std::max(*errors, std::abs(*recons - *snaps)/
norm[ifs]);
1837 if (m_nVectorFields){
1838 std::array<double,3>* reconv = recon.
vector->rawData(rawIndex);
1839 std::array<double,3>* snapv = snap.
vector->rawData(rawIndex);
1840 std::array<double,3>* errorv = m_errorMap.vector->rawData(rawIndex);
1841 for (std::size_t ifv = 0; ifv < m_nVectorFields; ++ifv){
1842 for (std::size_t j=0; j<3; ++j)
1843 (*errorv)[j]=std::max((*errorv)[j], std::abs((*reconv)[j] - (*snapv)[j])/
norm[ifv]);
1856void POD::initMinimization()
1858 m_minimizationMatrices.clear();
1859 m_minimizationMatrices.resize(m_nFields,std::vector<double>(m_nModes*m_nModes, 0.0));
1865void POD::evalMinimizationMatrices()
1871 if (m_reconstructionMode == ReconstructionMode::PROJECTION){
1872 for (std::size_t ifield = 0; ifield < m_nFields; ++ifield){
1873 for (std::size_t ir = 0; ir < m_nModes; ++ir)
1874 m_minimizationMatrices[ifield][ir*m_nModes+ir] = 1.0;
1879 for (std::size_t ir = 0; ir < m_nModes; ++ir){
1880 if (m_memoryMode == MemoryMode::MEMORY_LIGHT)
1883 for (std::size_t jr = ir; jr < m_nModes; ++jr){
1884 if (m_memoryMode == MemoryMode::MEMORY_LIGHT)
1887 std::unordered_set<long>::iterator it;
1888 for (it = m_listActiveIDs.begin(); it != m_listActiveIDs.end(); ++it){
1890 std::size_t rawIndex = m_podkernel->getMesh()->getCells().getRawIndex(
id);
1891 if (m_nScalarFields){
1892 double* datasi = m_modes[ir].scalar->rawData(rawIndex);
1893 double* datasj = m_modes[jr].scalar->rawData(rawIndex);
1894 for (std::size_t ifield = 0; ifield < m_nScalarFields; ++ifield){
1895 m_minimizationMatrices[ifield][ir*m_nModes+jr] += (*datasi)*(*datasj)*getRawCellVolume(rawIndex);
1901 for (std::size_t ifield = 0; ifield < m_nScalarFields; ++ifield){
1902 m_minimizationMatrices[ifield][jr*m_nModes+ir] = m_minimizationMatrices[ifield][ir*m_nModes+jr];
1906 if (m_nVectorFields){
1907 std::array<double,3>* datavi = m_modes[ir].vector->rawData(rawIndex);
1908 std::array<double,3>* datavj = m_modes[jr].vector->rawData(rawIndex);
1909 for (std::size_t ifield = m_nScalarFields; ifield < m_nFields; ++ifield){
1910 m_minimizationMatrices[ifield][ir*m_nModes+jr] +=
dotProduct((*datavi),(*datavj))*getRawCellVolume(rawIndex);
1916 for (std::size_t ifield = m_nScalarFields; ifield < m_nFields; ++ifield)
1917 m_minimizationMatrices[ifield][jr*m_nModes+ir] = m_minimizationMatrices[ifield][ir*m_nModes+jr];
1924# if BITPIT_ENABLE_MPI
1925 for (std::size_t i = 0; i < m_nFields; i++ )
1926 MPI_Allreduce(MPI_IN_PLACE, m_minimizationMatrices[i].data(), m_nModes*m_nModes, MPI_DOUBLE, MPI_SUM, m_communicator);
1939void POD::solveMinimization(std::vector<std::vector<double> > & rhs)
1942#if BITPIT_ENABLE_MPI
1943 runSolver = (m_rank == 0);
1949 for (std::size_t i = 0; i < m_nFields; ++i) {
1950 std::vector<double> A(m_nModes * m_nModes);
1951 std::vector<int> ipiv(m_nModes);
1953 for (std::size_t j = 0; j < m_nModes*m_nModes; ++j)
1954 A[j] = m_minimizationMatrices[i][j];
1956 lapack_int
info = LAPACKE_dgesv(LAPACK_COL_MAJOR, m_nModes, 1, A.data(), m_nModes, ipiv.data(), rhs[i].data(), m_nModes);
1958 log::cout() <<
"WARNING! algorithm convergence info " <<
info << std::endl;
1959 throw std::runtime_error(
"Unable to solve minimization problem.");
1964 for (std::size_t i = 0; i < m_nFields; ++i) {
1965 rhs[i] = std::vector<double>(m_nModes, 0.0);
1973void POD::evalEigen()
1976 m_lambda.resize(m_nFields,std::vector<double>(m_nSnapshots, 0.0));
1978 m_podCoeffs.clear();
1979 m_podCoeffs.resize(m_nFields, std::vector<std::vector<double>>(m_nSnapshots, std::vector<double>(m_nSnapshots,0.0)));
1982#if BITPIT_ENABLE_MPI
1983 runSolver = (m_rank == 0);
1989 int N = m_nSnapshots*m_nSnapshots;
1990 for (std::size_t i = 0; i < m_nFields; ++i) {
1991 std::vector<double> Marr(N);
1992 std::vector<double> alambda(m_nSnapshots);
1993 for (std::size_t j = 0; j < m_nSnapshots*m_nSnapshots; ++j)
1994 Marr[j/m_nSnapshots+j%m_nSnapshots*m_nSnapshots] = m_correlationMatrices[i][j];
1996 lapack_int info = LAPACKE_dsyev(LAPACK_COL_MAJOR,
'V',
'U', m_nSnapshots, Marr.data(), m_nSnapshots, alambda.data());
1998 log::cout() <<
"WARNING! algorithm convergence info " << info << std::endl;
1999 throw std::runtime_error(
"Unable to solve minimization problem.");
2003 checkModeCount(alambda.data(), i);
2005 for (std::size_t n = 0; n < m_nSnapshots; ++n)
2006 m_lambda[i][n] = alambda[m_nSnapshots - n - 1];
2008 for (std::size_t n = 0; n < m_nSnapshots; ++n) {
2009 for (std::size_t p = 0; p < m_nSnapshots; ++p)
2010 m_podCoeffs[i][p][n] = Marr[N - m_nSnapshots * (p + 1) + n] * std::sqrt(std::abs(m_lambda[i][p]));
2013 if (m_errorMode != ErrorMode::COMBINED){
2015 for (std::size_t ir=0; ir<m_nModes; ++ir) {
2016 std::ofstream out(m_directory + m_name +
".coeff."+std::to_string(ir)+
".dat", std::ofstream::out);
2017 for (std::size_t i = 0; i < m_nFields; ++i)
2018 out << m_podCoeffs[i][ir] << std::endl;
2023 std::ofstream outl(m_directory + m_name +
".lambda.dat", std::ofstream::out);
2024 for (std::size_t i = 0; i < m_nFields; ++i)
2025 outl << m_lambda[i] << std::endl;
2031#if BITPIT_ENABLE_MPI
2032 long bufferSize = m_nModes;
2033 MPI_Bcast(&bufferSize, 1, MPI_LONG, 0, m_communicator);
2034 m_nModes = bufferSize;
2035 for (std::size_t i = 0; i < m_nFields; ++i) {
2036 for (std::size_t p=0; p<m_nModes; ++p)
2037 MPI_Bcast(m_podCoeffs[i][p].data(), m_nSnapshots, MPI_DOUBLE, 0, m_communicator);
2039 MPI_Bcast(m_lambda[i].data(), m_nSnapshots, MPI_DOUBLE, 0, m_communicator);
2050void POD::checkModeCount(
double *alambda, std::size_t ifield)
2055 m_nModes = std::min(m_nModes, m_nSnapshots-1);
2057 m_nModes = std::min(m_nModes, m_nSnapshots);
2066 std::vector<double> dlambda(m_nSnapshots);
2068 for (std::size_t n=hn; n<m_nSnapshots; ++n){
2069 dlambda[n] = alambda[m_nSnapshots-n-1];
2070 sumen += std::abs(dlambda[n]);
2072 while (nr < m_nModes && en < m_energyLevel){
2073 en += std::abs(dlambda[nr]) / sumen * 100;
2076 _m_nr.push_back(nr);
2077 if (ifield == m_nFields-1)
2078 m_nModes = *(std::max_element(_m_nr.begin(), _m_nr.end()));
2084void POD::evalModes()
2086 m_modes.resize(m_nModes);
2093void POD::_evalModes()
2095 for (std::size_t ir = 0; ir < m_nModes; ++ir){
2096 m_modes[ir].scalar = std::unique_ptr<pod::ScalarStorage>(
new pod::ScalarStorage(m_nScalarFields, &m_podkernel->getMesh()->getCells()));
2097 m_modes[ir].vector = std::unique_ptr<pod::VectorStorage>(
new pod::VectorStorage(m_nVectorFields, &m_podkernel->getMesh()->getCells()));
2098 m_modes[ir].scalar->fill(0.0);
2099 m_modes[ir].vector->fill(std::array<double, 3>{{0.0, 0.0, 0.0}});
2102 for (std::size_t is = 0; is < m_nSnapshots; ++is){
2103 pod::PODField snapi;
2104 readSnapshot(m_database[is], snapi);
2106 _computeMapper(snapi.mesh);
2107 snapi = pod::PODField(m_podkernel->mapPODFieldToPOD(snapi,
nullptr));
2108 m_podkernel->clearMapper();
2112 diff(&snapi, m_mean);
2114 for (std::size_t ir = 0; ir < m_nModes; ++ir){
2115 for (
long id : m_listActiveIDs){
2116 std::size_t rawIndex = m_podkernel->getMesh()->getCells().getRawIndex(
id);
2117 if (m_nScalarFields){
2118 double* modes = m_modes[ir].scalar->rawData(rawIndex);
2119 double* datas = snapi.scalar->rawData(rawIndex);
2120 for (std::size_t ifs = 0; ifs < m_nScalarFields; ++ifs){
2121 *modes = *modes + *datas*m_podCoeffs[ifs][ir][is] / m_lambda[ifs][ir];
2126 if (m_nVectorFields){
2127 std::array<double, 3>* modev = m_modes[ir].vector->rawData(rawIndex);
2128 std::array<double, 3>* datav = snapi.vector->rawData(rawIndex);
2129 for (std::size_t ifv = 0; ifv < m_nVectorFields; ++ifv){
2130 *modev = *modev + *datav*m_podCoeffs[m_nScalarFields+ifv][ir][is] / m_lambda[m_nScalarFields+ifv][ir];
2136 if (m_memoryMode == MemoryMode::MEMORY_LIGHT){
2138 m_modes[ir].clear();
2153 int dumpBlock = (m_nProcs > 1) ? m_rank : -1;
2155 std::string filename = std::string(snap.
directory) +
"/" + std::string(snap.
name) +
".data";
2157 std::istream &dataStream = binaryReader.
getStream();
2161 fieldr.
setMesh(m_podkernel->getMesh());
2165 fieldr.
setMesh(m_podkernel->readMesh(snap));
2171 fieldr.
mask->restore(dataStream);
2176 utils::binary::read(dataStream, m_nScalarFields);
2177 m_nameScalarFields.resize(m_nScalarFields);
2178 for (std::size_t i = 0; i < m_nScalarFields; ++i)
2179 utils::binary::read(dataStream, m_nameScalarFields[i]);
2181 if (m_nScalarFields) {
2183 fieldr.
scalar->restore(dataStream);
2187 utils::binary::read(dataStream, m_nVectorFields);
2188 m_nFields = m_nScalarFields + m_nVectorFields;
2189 m_nameVectorFields.resize(m_nVectorFields);
2190 for (std::size_t i = 0; i < m_nVectorFields; ++i)
2191 utils::binary::read(dataStream, m_nameVectorFields[i]);
2193 if (m_nVectorFields) {
2195 fieldr.
vector->restore(dataStream);
2197 binaryReader.close();
2200 if (m_writeMode == WriteMode::DEBUG) {
2201 std::vector<std::string > datastring;
2205 std::vector<std::vector<double>> fields(m_nScalarFields, std::vector<double>(mesh->
getCellCount()));
2206 std::vector<std::vector<std::array<double,3>>> fieldv(m_nVectorFields, std::vector<std::array<double,3>>(mesh->
getCellCount()));
2210 long id = cell.getId();
2211 mask[i] = uint8_t(fieldr.
mask->at(
id));
2214 mesh->
getVTK().
addData(
"mask", VTKFieldType::SCALAR, VTKLocation::CELL, mask);
2215 datastring.push_back(
"mask");
2217 for (std::size_t isf = 0; isf < m_nScalarFields; ++isf) {
2220 long id = cell.getId();
2221 fields[isf][i] = fieldr.
scalar->at(
id, isf);
2224 mesh->
getVTK().
addData(m_nameScalarFields[isf], VTKFieldType::SCALAR, VTKLocation::CELL, fields[isf]);
2225 datastring.push_back(m_nameScalarFields[isf]);
2228 for (std::size_t ivf = 0; ivf < m_nVectorFields; ++ivf) {
2231 long id = cell.getId();
2232 fieldv[ivf][i] = fieldr.
vector->at(
id, ivf);
2235 std::string vname= m_nameVectorFields[ivf][0].substr(0,m_nameVectorFields[ivf][0].size()-2);
2236 mesh->
getVTK().
addData(vname, VTKFieldType::VECTOR, VTKLocation::CELL, fieldv[ivf]);
2237 datastring.push_back(vname);
2241 if (mesh == m_podkernel->getMesh())
2246 for (std::size_t is=0; is < datastring.size(); ++is)
2251 if (mesh == m_podkernel->getMesh()){
2252#if BITPIT_ENABLE_MPI
2265void POD::readMode(std::size_t ir)
2267 if (!m_podkernel->getMesh())
2268 throw std::runtime_error (
"POD: POD mesh not initialized before read a POD mode");
2271 throw std::runtime_error (
"POD: mode index > number of POD modes during read");
2273 int dumpBlock = (m_nProcs > 1) ? m_rank : -1;
2275 if (ir == m_nModes){
2277 std::string filename = m_directory + m_name +
".mean"+
".data";
2279 std::istream &dataStream = binaryReader.getStream();
2282 m_filter.restore(dataStream);
2287 utils::binary::read(dataStream, m_nScalarFields);
2288 m_nameScalarFields.resize(m_nScalarFields);
2289 for (std::size_t i = 0; i < m_nScalarFields; ++i)
2290 utils::binary::read(dataStream, m_nameScalarFields[i]);
2292 if (m_nScalarFields) {
2293 m_mean.scalar = std::unique_ptr<pod::ScalarStorage>(
new pod::ScalarStorage(m_nScalarFields, &m_podkernel->getMesh()->getCells()));
2294 m_mean.scalar->restore(dataStream);
2298 utils::binary::read(dataStream, m_nVectorFields);
2299 m_nameVectorFields.resize(m_nVectorFields);
2300 m_nFields = m_nScalarFields + m_nVectorFields;
2301 for (std::size_t i = 0; i < m_nVectorFields; ++i)
2302 utils::binary::read(dataStream, m_nameVectorFields[i]);
2304 if (m_nVectorFields) {
2305 m_mean.vector = std::unique_ptr<pod::VectorStorage>(
new pod::VectorStorage(m_nVectorFields, &m_podkernel->getMesh()->getCells()));
2306 m_mean.vector->restore(dataStream);
2308 binaryReader.close();
2312 m_modes[ir].clear();
2314 std::string filename = m_directory + m_name +
".mode."+std::to_string(ir)+
".data";
2315 IBinaryArchive binaryReader(filename, dumpBlock);
2316 std::istream &dataStream = binaryReader.getStream();
2319 m_filter.restore(dataStream);
2324 utils::binary::read(dataStream, m_nScalarFields);
2325 m_nameScalarFields.resize(m_nScalarFields);
2326 for (std::size_t i = 0; i < m_nScalarFields; ++i)
2327 utils::binary::read(dataStream, m_nameScalarFields[i]);
2329 if (m_nScalarFields) {
2330 m_modes[ir].scalar = std::unique_ptr<pod::ScalarStorage>(
new pod::ScalarStorage(m_nScalarFields, &m_podkernel->getMesh()->getCells()));
2331 m_modes[ir].scalar->restore(dataStream);
2335 utils::binary::read(dataStream, m_nVectorFields);
2336 m_nFields = m_nScalarFields + m_nVectorFields;
2337 m_nameVectorFields.resize(m_nVectorFields);
2338 for (std::size_t i = 0; i < m_nVectorFields; ++i)
2339 utils::binary::read(dataStream, m_nameVectorFields[i]);
2341 if (m_nVectorFields) {
2342 m_modes[ir].vector = std::unique_ptr<pod::VectorStorage>(
new pod::VectorStorage(m_nVectorFields, &m_podkernel->getMesh()->getCells()));
2343 m_modes[ir].vector->restore(dataStream);
2345 binaryReader.close();
2354double POD::getCellVolume(
long id)
2356 return m_podkernel->getCellVolume(
id);
2364double POD::getRawCellVolume(
long rawIndex)
2366 return m_podkernel->getRawCellVolume(rawIndex);
2374void POD::dumpMode(std::size_t ir)
2377 throw std::runtime_error (
"POD: mode index > number of pod modes during write");
2379 int dumpBlock = (m_nProcs > 1) ? m_rank : -1;
2381 if (ir == m_nModes) {
2383 std::string header =
"podmean." + std::to_string(ir);
2384 OBinaryArchive binaryWriter(m_directory + m_name +
".mean"+
".data", ARCHIVE_VERSION, header, dumpBlock);
2385 std::ostream &dataStream = binaryWriter.getStream();
2386 m_filter.dump(dataStream);
2387 utils::binary::write(dataStream,std::size_t(m_nScalarFields));
2388 if (m_nScalarFields) {
2389 for (std::size_t i = 0; i < m_nScalarFields; ++i)
2390 utils::binary::write(dataStream, m_nameScalarFields[i]);
2391 m_mean.scalar->dump(dataStream);
2394 utils::binary::write(dataStream,std::size_t(m_nVectorFields));
2395 if (m_nVectorFields) {
2396 for (std::size_t i = 0; i < m_nVectorFields; ++i)
2397 utils::binary::write(dataStream, m_nameVectorFields[i]);
2398 m_mean.vector->dump(dataStream);
2400 binaryWriter.close();
2404 std::string header =
"podmode." + std::to_string(ir);
2405 OBinaryArchive binaryWriter(m_directory + m_name +
".mode."+std::to_string(ir)+
".data", ARCHIVE_VERSION, header, dumpBlock);
2406 std::ostream &dataStream = binaryWriter.getStream();
2407 m_filter.dump(dataStream);
2408 utils::binary::write(dataStream,std::size_t(m_nScalarFields));
2409 if (m_nScalarFields) {
2410 for (std::size_t i = 0; i < m_nScalarFields; ++i)
2411 utils::binary::write(dataStream, m_nameScalarFields[i]);
2413 m_modes[ir].scalar->dump(dataStream);
2416 utils::binary::write(dataStream,std::size_t(m_nVectorFields));
2417 if (m_nVectorFields) {
2418 for (std::size_t i = 0; i < m_nVectorFields; ++i)
2419 utils::binary::write(dataStream, m_nameVectorFields[i]);
2421 m_modes[ir].vector->dump(dataStream);
2423 binaryWriter.close();
2435 log::cout() <<
"Dumping snapshot ... " << std::endl;
2437 int dumpBlock = (m_nProcs > 1) ? m_rank : -1;
2441 std::string header = name;
2442 OBinaryArchive binaryWriter(m_directory + name +
".data", ARCHIVE_VERSION, header, dumpBlock);
2443 std::ostream &dataStream = binaryWriter.
getStream();
2444 m_filter.dump(dataStream);
2445 utils::binary::write(dataStream,std::size_t(m_nScalarFields));
2446 if (m_nScalarFields) {
2447 for (std::size_t i = 0; i < m_nScalarFields; ++i) {
2448 utils::binary::write(dataStream, m_nameScalarFields[i]);
2450 field.
scalar->dump(dataStream);
2453 utils::binary::write(dataStream,std::size_t(m_nVectorFields));
2454 if (m_nVectorFields) {
2455 for (std::size_t i = 0; i < m_nVectorFields; ++i) {
2456 utils::binary::write(dataStream, m_nameVectorFields[i]);
2458 field.
vector->dump(dataStream);
2460 binaryWriter.close();
2465 std::string header = name;
2466 OBinaryArchive binaryWriter(m_directory + name +
".mesh", ARCHIVE_VERSION, header, dumpBlock);
2467 std::ostream &dataStream = binaryWriter.
getStream();
2469 binaryWriter.close();
2473 if (m_writeMode == WriteMode::DEBUG) {
2487 std::size_t nsf = 0;
2488 if (m_nScalarFields){
2489 nsf = a.
scalar->getFieldCount();
2490 if (nsf != b.
scalar->getFieldCount())
2491 throw std::runtime_error (
"POD: different field count");
2494 std::size_t nvf = 0;
2495 if (m_nVectorFields){
2496 nvf = a.
vector->getFieldCount();
2497 if (nvf != b.
vector->getFieldCount())
2498 throw std::runtime_error (
"POD: different field count");
2502 for (
long id : a.scalar->getKernel()->getIds()){
2503 std::size_t rawIndex = m_podkernel->getMesh()->getCells().getRawIndex(
id);
2504 double* datasa = a.
scalar->rawData(rawIndex);
2505 double* datasb = b.
scalar->rawData(rawIndex);
2506 for (std::size_t i = 0; i < nsf; ++i){
2507 *datasa = *datasa - *datasb;
2514 for (
long id : a.scalar->getKernel()->getIds()){
2515 std::size_t rawIndex = m_podkernel->getMesh()->getCells().getRawIndex(
id);
2516 std::array<double,3>* datava = a.
vector->rawData(rawIndex);
2517 std::array<double,3>* datavb = b.
vector->rawData(rawIndex);
2518 for (std::size_t i = 0; i < nvf; ++i)
2519 *datava = *datava - *datavb;
2532void POD::sum(pod::PODField* _a,
const pod::PODMode& b)
2534 pod::PODField& a = *_a;
2535 std::size_t nsf = 0;
2536 if (m_nScalarFields){
2537 nsf = a.
scalar->getFieldCount();
2538 if (nsf != b.scalar->getFieldCount())
2539 throw std::runtime_error (
"POD: different field count");
2542 std::size_t nvf = 0;
2543 if (m_nVectorFields){
2544 nvf = a.vector->getFieldCount();
2545 if (nvf != b.vector->getFieldCount())
2546 throw std::runtime_error (
"POD: different field count");
2550 for (
long id : a.scalar->getKernel()->getIds()){
2551 std::size_t rawIndex = m_podkernel->getMesh()->getCells().getRawIndex(
id);
2552 double *dataa = a.scalar->rawData(rawIndex);
2553 const double *datab = b.scalar->rawData(rawIndex);
2554 for (std::size_t i = 0; i < nsf; ++i){
2555 dataa[i] += datab[i];
2560 for (
long id : a.scalar->getKernel()->getIds()){
2561 std::size_t rawIndex = m_podkernel->getMesh()->getCells().getRawIndex(
id);
2562 std::array<double,3> *dataa = a.vector->rawData(rawIndex);
2563 const std::array<double,3> *datab = b.vector->rawData(rawIndex);
2564 for (std::size_t i = 0; i < nvf; ++i) {
2565 dataa[i] += datab[i];
2579 std::vector<double>
norm;
2580 norm.resize(m_nFields,0.0);
2582 std::unordered_set<long>::iterator it;
2583 for (it = m_listActiveIDs.begin(); it != m_listActiveIDs.end(); ++it){
2585 std::size_t rawIndex = m_podkernel->getMesh()->getCells().getRawIndex(
id);
2586 if (m_nScalarFields){
2587 double* datas = snap.
scalar->rawData(rawIndex);
2588 for (std::size_t ifield = 0; ifield < m_nScalarFields; ++ifield){
2589 norm[ifield] += (*datas)*(*datas)*snap.
mesh->evalCellVolume(
id);
2593 if (m_nVectorFields){
2594 std::array<double,3>* datav = snap.
vector->rawData(rawIndex);
2595 for (std::size_t ifield = m_nScalarFields; ifield < m_nFields; ++ifield){
2602# if BITPIT_ENABLE_MPI
2603 MPI_Allreduce(MPI_IN_PLACE,
norm.data(), m_nFields, MPI_DOUBLE, MPI_SUM, m_communicator);
2606 for (std::size_t ifield = 0; ifield < m_nFields; ++ifield)
2607 norm[ifield]=std::sqrt(
norm[ifield]);
2620 std::vector<double>
max;
2621 max.resize(m_nFields,0.0);
2622 for (
long id : m_listActiveIDs) {
2623 std::size_t rawIndex = snap.
mesh->
getCells().getRawIndex(
id);
2625 if (m_nScalarFields){
2626 const double *data = snap.
scalar->rawData(rawIndex);
2627 for (std::size_t i = 0; i < m_nScalarFields; ++i){
2628 double fieldData = data[i];
2629 max[i] = std::max(
max[i], std::abs(fieldData));
2632 if (m_nVectorFields){
2633 const std::array<double,3> *data = snap.
vector->rawData(rawIndex);
2634 for (std::size_t i = m_nScalarFields; i < m_nFields; ++i){
2635 const std::array<double,3> &fieldData = data[i - m_nScalarFields];
2641# if BITPIT_ENABLE_MPI
2642 MPI_Allreduce(MPI_IN_PLACE,
max.data(), m_nFields, MPI_DOUBLE, MPI_MAX, m_communicator);
2648#if BITPIT_ENABLE_MPI
2654void POD::initializeCommunicator(MPI_Comm communicator)
2657 if (isCommunicatorSet())
2658 throw std::runtime_error (
"POD communicator can be set just once");
2661 if (communicator == MPI_COMM_NULL)
2662 throw std::runtime_error (
"POD communicator is not valid");
2669 MPI_Comm_dup(communicator, &m_communicator);
2676MPI_Comm POD::getCommunicator()
const
2678 return m_communicator;
2687bool POD::isCommunicatorSet()
const
2690 return (getCommunicator() != MPI_COMM_NULL);
2696void POD::freeCommunicator()
2698 if (!isCommunicatorSet())
2701 int finalizedCalled;
2702 MPI_Finalized(&finalizedCalled);
2703 if (finalizedCalled)
2706 MPI_Comm_free(&m_communicator);
2715void POD::evalReconstructionCoeffs(pod::PODField & field)
2717 evalMinimizationMatrices();
2720 m_reconstructionCoeffs = projectField(field);
2723 solveMinimization(m_reconstructionCoeffs);
2735void POD::evalReconstructionCoeffs(PiercedStorage<double> &fields,
2736 const std::vector<std::size_t> &scalarIds,
const std::vector<std::size_t> & podscalarIds,
2737 const std::vector<std::array<std::size_t, 3>> & vectorIds,
const std::vector<std::size_t> & podvectorIds)
2739 std::size_t nsf = scalarIds.size();
2740 std::size_t nvf = vectorIds.size();
2743 diff(fields, m_mean, scalarIds, podscalarIds, vectorIds, podvectorIds, &m_listActiveIDs);
2745 m_reconstructionCoeffs.clear();
2746 m_reconstructionCoeffs.resize(m_nFields, std::vector<double>(m_nModes, 0.0));
2749 evalMinimizationMatrices();
2752 for (std::size_t ir = 0; ir < m_nModes; ++ir) {
2753 if (m_memoryMode == MemoryMode::MEMORY_LIGHT)
2756 std::unordered_set<long>::iterator it;
2757 for (it = m_listActiveIDs.begin(); it != m_listActiveIDs.end(); ++it) {
2759 std::size_t rawIndex = m_podkernel->getMesh()->getCells().getRawIndex(
id);
2760 double *datag = fields.rawData(rawIndex);
2762 double *modes = m_modes[ir].scalar->rawData(rawIndex);
2763 for (std::size_t ifield = 0; ifield < nsf; ++ifield) {
2764 double *modesi = modes + podscalarIds[ifield];
2765 double *datagi = datag + scalarIds[ifield];
2766 m_reconstructionCoeffs[ifield][ir] += (*datagi)*(*modesi)*getRawCellVolume(rawIndex);
2770 std::array<double,3>* modev = m_modes[ir].vector->rawData(rawIndex);
2771 for (std::size_t ifield = 0; ifield < nvf; ++ifield) {
2772 std::array<double,3>* modevi = modev + podvectorIds[ifield];
2773 for (std::size_t j = 0; j < 3; ++j) {
2774 double *datagi = datag + vectorIds[ifield][j];
2775 m_reconstructionCoeffs[m_nScalarFields+ifield][ir] += ((*datagi)*(*modevi)[j])*getRawCellVolume(rawIndex);
2782#if BITPIT_ENABLE_MPI
2783 for (std::size_t i = 0; i < m_nFields; ++i)
2784 MPI_Allreduce(MPI_IN_PLACE, m_reconstructionCoeffs[i].data(), m_nModes, MPI_DOUBLE, MPI_SUM, m_communicator);
2788 solveMinimization(m_reconstructionCoeffs);
2791 sum(fields, m_mean, scalarIds, podscalarIds, vectorIds, podvectorIds, &m_listActiveIDs);
2801void POD::buildFields(
const std::vector<std::vector<double>> &reconstructionCoeffs, pod::PODField &recon)
2804 recon.scalar = std::unique_ptr<pod::ScalarStorage>(
new pod::ScalarStorage(m_nScalarFields, &m_podkernel->getMesh()->getCells()));
2805 recon.vector = std::unique_ptr<pod::VectorStorage>(
new pod::VectorStorage(m_nVectorFields, &m_podkernel->getMesh()->getCells()));
2806 recon.scalar->fill(0.0);
2807 recon.vector->fill(std::array<double, 3>{{0.0, 0.0, 0.0}});
2810 for (std::size_t ir = 0; ir < m_nModes; ++ir) {
2811 if (m_memoryMode == MemoryMode::MEMORY_LIGHT) {
2816 for (
long id : m_listActiveIDs) {
2817 std::size_t rawIndex = recon.mesh->getCells().getRawIndex(
id);
2820 if (m_nScalarFields) {
2821 const double *modes = m_modes[ir].scalar->rawData(rawIndex);
2822 for (std::size_t isf = 0; isf < m_nScalarFields; ++isf) {
2823 recon.scalar->at(
id, isf) += modes[isf] * reconstructionCoeffs[isf][ir];
2828 if (m_nVectorFields) {
2829 const std::array<double,3> *modes = m_modes[ir].vector->rawData(rawIndex);
2830 for (std::size_t ifv = 0; ifv < m_nVectorFields; ++ifv) {
2831 recon.vector->at(
id, ifv) += modes[ifv] * reconstructionCoeffs[m_nScalarFields+ifv][ir];
2836 if (m_memoryMode == MemoryMode::MEMORY_LIGHT) {
2837 m_modes[ir].clear();
2842 sum(&recon, m_mean);
2859void POD::buildFields(
const std::vector<std::vector<double>> &reconstructionCoeffs, PiercedStorage<double> &fields,
2860 const std::vector<std::size_t> &scalarIds,
const std::vector<std::size_t> &podscalarIds,
2861 const std::vector<std::array<std::size_t, 3>> &vectorIds,
const std::vector<std::size_t> &podvectorIds,
2862 const std::unordered_set<long> *targetCells)
2864 std::size_t nsf = scalarIds.size();
2865 std::size_t nvf = vectorIds.size();
2866 if (nsf == 0 && nvf == 0) {
2870 std::unordered_set<long> targetCellsStorage;
2872 for (
const Cell &cell : m_podkernel->getMesh()->getCells()) {
2873 targetCellsStorage.insert(cell.getId());
2875 targetCells = &targetCellsStorage;
2879 for (
const long id : *targetCells) {
2880 std::size_t rawIndex = m_podkernel->getMesh()->getCells().getRawIndex(
id);
2881 double *recon = fields.rawData(rawIndex);
2882 for (std::size_t ifs = 0; ifs < m_nScalarFields; ++ifs) {
2883 double *reconsi = recon + scalarIds[ifs];
2886 for (std::size_t ifv = 0; ifv < m_nVectorFields; ++ifv) {
2887 for (std::size_t j = 0; j < 3; ++j) {
2888 double *reconvi = recon + vectorIds[ifv][j];
2895 for (std::size_t ir = 0; ir < m_nModes; ++ir) {
2896 if (m_memoryMode == MemoryMode::MEMORY_LIGHT) {
2900 for (
const long id : *targetCells) {
2901 std::size_t rawIndex = m_podkernel->getMesh()->getCells().getRawIndex(
id);
2902 double *recon = fields.rawData(rawIndex);
2904 if (m_nScalarFields > 0) {
2905 const double *modes = m_modes[ir].scalar->rawData(rawIndex);
2906 for (std::size_t ifs = 0; ifs < m_nScalarFields; ++ifs) {
2907 double *reconsi = recon + scalarIds[ifs];
2908 const double *modesi = modes + podscalarIds[ifs];
2909 (*reconsi) += (*modesi) * reconstructionCoeffs[ifs][ir];
2913 if (m_nVectorFields > 0) {
2914 const std::array<double,3> *modev = m_modes[ir].vector->rawData(rawIndex);
2915 for (std::size_t ifv = 0; ifv < m_nVectorFields; ++ifv) {
2916 const std::array<double,3> * modevi = modev + podvectorIds[ifv];
2917 for (std::size_t j = 0; j < 3; ++j) {
2918 double *reconvi = recon + vectorIds[ifv][j];
2919 (*reconvi) += (*modevi)[j] * reconstructionCoeffs[m_nScalarFields + ifv][ir];
2925 if (m_memoryMode == MemoryMode::MEMORY_LIGHT) {
2926 m_modes[ir].clear();
2931 sum(fields, m_mean, scalarIds, podscalarIds, vectorIds, podvectorIds, targetCells);
2942 throw std::runtime_error(
"POD: compute mapper can be called only in expert mode");
2943 _computeMapper(mesh);
2952void POD::adaptionAlter(
const std::vector<adaption::Info> & info)
2955 throw std::runtime_error(
"POD: update mapper can be called only in expert mode");
2956 _adaptionAlter(info);
2965 m_podkernel->computeMapper(mesh);
2966 m_podkernel->setMapperDirty(!m_expert);
2974void POD::adaptionPrepare(
const std::vector<adaption::Info> & info)
2976 m_podkernel->adaptionPrepare(info);
2984void POD::_adaptionAlter(
const std::vector<adaption::Info> & info)
2986 m_podkernel->adaptionAlter(info);
2993void POD::adaptionCleanUp(
const std::vector<adaption::Info> & info)
2995 m_podkernel->adaptionCleanUp(info);
3005 const std::vector<std::size_t> &scalarIds,
const std::vector<std::size_t> &podscalarIds,
3006 const std::vector<std::array<std::size_t, 3>> &vectorIds,
const std::vector<std::size_t> &podvectorIds,
3007 const std::unordered_set<long> *targetCells)
3011 std::size_t nsf = scalarIds.size();
3012 std::size_t nvf = vectorIds.size();
3014 for (
long id : *targetCells) {
3015 std::size_t rawIndex = m_podkernel->getMesh()->getCells().getRawIndex(
id);
3016 double *datag = fields.
rawData(rawIndex);
3017 double *datams = mode.
scalar->rawData(rawIndex);
3018 for (std::size_t i = 0; i < nsf; ++i) {
3019 double *datagi = datag + scalarIds[i];
3020 double *datamsi = datams + podscalarIds[i];
3021 (*datagi) -= (*datamsi);
3023 std::array<double,3>* datamv = mode.
vector->rawData(rawIndex);
3024 for (std::size_t i = 0; i < nvf; ++i) {
3025 std::array<double,3>* datamvi = datamv + podvectorIds[i];
3026 for (std::size_t j = 0; j < 3; ++j) {
3027 double *datagi = datag + vectorIds[i][j];
3028 (*datagi) -= (*datamvi)[j];
3042void POD::sum(PiercedStorage<double> &fields,
const pod::PODMode &mode,
3043 const std::vector<std::size_t> &scalarIds,
const std::vector<std::size_t> &podscalarIds,
3044 const std::vector<std::array<std::size_t, 3>> &vectorIds,
const std::vector<std::size_t> &podvectorIds,
3045 const std::unordered_set<long> *targetCells)
3049 std::size_t nsf = scalarIds.size();
3050 std::size_t nvf = vectorIds.size();
3052 for (
long id : *targetCells) {
3053 std::size_t rawIndex = m_podkernel->getMesh()->getCells().getRawIndex(
id);
3054 double *datag = fields.rawData(rawIndex);
3055 double *datams = mode.scalar->rawData(rawIndex);
3056 for (std::size_t i = 0; i < nsf; ++i) {
3057 double *datagi = datag + scalarIds[i];
3058 double *datamsi = datams + podscalarIds[i];
3059 (*datagi) += (*datamsi);
3061 std::array<double,3>* datamv = mode.vector->rawData(rawIndex);
3062 for (std::size_t i = 0; i < nvf; ++i) {
3063 std::array<double,3>* datamvi = datamv + podvectorIds[i];
3064 for (std::size_t j = 0; j < 3; ++j) {
3065 double *datagi = datag + vectorIds[i][j];
3066 (*datagi) += (*datamvi)[j];
3082 log::cout() <<
"Writing snapshot ... " << std::endl;
3085 m_podkernel->getMesh()->getVTK().setDirectory(m_directory);
3088 std::vector<std::string > datastring;
3092 std::vector<std::vector<double>> fields(m_nScalarFields, std::vector<double>(field.
mesh->
getInternalCellCount(), 0.0));
3093 std::vector<std::vector<std::array<double,3>>> fieldv(m_nVectorFields, std::vector<std::array<double,3>>(field.
mesh->
getInternalCellCount(), {{0.0, 0.0, 0.0}}));
3094 std::vector<uint8_t> field_mask(field.mesh->getInternalCellCount(), 0);
3097 for (std::size_t isf = 0; isf < m_nScalarFields; ++isf) {
3099 for (
const Cell &cell : field.mesh->getCells()) {
3100 if (cell.isInterior()){
3101 long id = cell.getId();
3102 fields[isf][i] = field.scalar->at(
id, isf);
3107 field.mesh->getVTK().addData(m_nameScalarFields[isf], VTKFieldType::SCALAR, VTKLocation::CELL, fields[isf]);
3108 datastring.push_back(m_nameScalarFields[isf]);
3112 for (std::size_t ivf = 0; ivf < m_nVectorFields; ++ivf) {
3114 for (
const Cell &cell : field.mesh->getCells()) {
3115 if (cell.isInterior()) {
3116 long id = cell.getId();
3117 fieldv[ivf][i] = field.vector->at(
id, ivf);
3121 std::string vname= m_nameVectorFields[ivf][0].substr(0,m_nameVectorFields[ivf][0].size()-2);
3123 field.mesh->getVTK().addData(vname, VTKFieldType::VECTOR, VTKLocation::CELL, fieldv[ivf]);
3124 datastring.push_back(vname);
3129 for (
const Cell &cell : field.mesh->getCells()) {
3130 if (cell.isInterior()) {
3131 long id = cell.getId();
3132 field_mask[j] = m_filter[id];
3136 field.mesh->getVTK().addData(
"filter", VTKFieldType::SCALAR, VTKLocation::CELL, field_mask);
3137 datastring.push_back(
"filter");
3140 field.mesh->write();
3143 for (std::size_t is=0; is < datastring.size(); ++is) {
3144 field.mesh->getVTK().removeData(datastring[is]);
3154void POD::write(
int mode_index, std::string file_name)
3156 log::cout() <<
"Writing mode ... " << std::endl;
3160 mode_mesh = m_podkernel->getMesh();
3164 std::vector<std::string> datastring;
3167 std::vector<std::vector<double>> fields(m_nScalarFields, std::vector<double>(mode_mesh->
getInternalCellCount(), 0.0));
3168 std::vector<std::vector<std::array<double,3>>> fieldv(m_nVectorFields, std::vector<std::array<double,3>>(mode_mesh->
getInternalCellCount(), {{0.0, 0.0, 0.0}}));
3169 std::vector<uint8_t> mask(mode_mesh->getInternalCellCount(), 0);
3172 for (std::size_t isf = 0; isf < m_nScalarFields; ++isf) {
3174 for (
const Cell &cell : mode_mesh->getCells()) {
3175 if (cell.isInterior()){
3176 long id = cell.getId();
3177 fields[isf][i] = m_modes[mode_index].scalar->at(
id, isf);
3182 mode_mesh->getVTK().addData(m_nameScalarFields[isf], VTKFieldType::SCALAR, VTKLocation::CELL, fields[isf]);
3183 datastring.push_back(m_nameScalarFields[isf]);
3187 for (std::size_t ivf = 0; ivf < m_nVectorFields; ++ivf) {
3189 for (
const Cell &cell : mode_mesh->getCells()) {
3190 if (cell.isInterior()) {
3191 long id = cell.getId();
3192 fieldv[ivf][i] = m_modes[mode_index].vector->at(
id, ivf);
3196 std::string vname= m_nameVectorFields[ivf][0].substr(0,m_nameVectorFields[ivf][0].size()-2);
3198 mode_mesh->getVTK().addData(vname, VTKFieldType::VECTOR, VTKLocation::CELL, fieldv[ivf]);
3199 datastring.push_back(vname);
3204 for (
const Cell &cell : mode_mesh->getCells()) {
3205 if (cell.isInterior()) {
3206 long id = cell.getId();
3207 mask[j] = m_filter[id];
3211 mode_mesh->getVTK().addData(
"mask", VTKFieldType::SCALAR, VTKLocation::CELL, mask);
3212 datastring.push_back(
"mask");
3218 for (std::size_t is=0; is < datastring.size(); ++is) {
3219 mode_mesh->getVTK().removeData(datastring[is]);
The Cell class defines the cells.
std::istream & getStream()
std::ostream & getStream()
The PODVolOctree is the specialized class of PODKernel for VolOctree meshes.
void setErrorThreshold(double threshold)
std::size_t getModeCount()
void fillListActiveIDs(const PiercedStorage< bool > &bfield)
std::vector< std::array< std::string, 3 > > getVectorNames()
std::size_t getSnapshotCount()
void evalReconstruction()
void unsetLeave1outSnapshots()
const std::string & getDirectory()
const std::vector< pod::PODMode > & getModes()
void setRunMode(RunMode mode)
const VolumeKernel * getMesh()
std::unique_ptr< PODKernel > & getKernel()
std::vector< std::string > getScalarNames()
const std::unordered_set< long int > & getListActiveIDs()
void setTargetErrorFields(std::vector< std::string > &namesf, std::vector< std::array< std::string, 3 > > &namevf)
void setMeshType(MeshType type)
void setStaticMesh(bool flag)
void setSensorMask(const PiercedStorage< bool > &mask, VolumeKernel *mesh=nullptr)
WriteMode
Output Write Mode of the POD object. It defines the amount of information written by the POD object.
void setMemoryMode(MemoryMode mode)
double getErrorThreshold()
void setDirectory(const std::string &directory)
const std::string & getName()
POD(MPI_Comm comm=MPI_COMM_WORLD)
void restoreDecomposition()
ReconstructionMode getReconstructionMode()
std::vector< std::string > getFieldsNames()
MemoryMode getMemoryMode()
void setExpert(bool mode=true)
void setUseMean(bool flag)
void addReconstructionSnapshot(const std::string &directory, const std::string &name)
void removeLeave1outSnapshot(const std::string &directory, const std::string &name)
MeshType
Type of the Mesh used to compute the POD basis.
ReconstructionMode
Mode of Reconstruction of fields by using the POD basis.
const pod::PODMode & getMean()
MemoryMode
Memory Mode of the POD object. It defines the use of the memory resources.
void setSnapshots(const std::vector< pod::SnapshotFile > &database)
void setWriteMode(WriteMode mode)
std::size_t getListIDInternalCount()
void setReconstructionMode(ReconstructionMode mode)
ErrorMode
Mode of Error evaluation of a reconstructed fields by the POD basis.
void setEnergyLevel(double energy)
void setModeCount(std::size_t nmodes)
void setName(const std::string &name)
void setErrorMode(ErrorMode mode)
void setMesh(const std::string &directory, const std::string &name)
std::vector< std::vector< double > > getReconstructionCoeffs()
void addSnapshot(const std::string &directory, const std::string &name)
RunMode
Run Mode of the POD object. It defines if the POD basis has to be computed or restored.
PiercedVector< Cell > & getCells()
VTKUnstructuredGrid & getVTK()
void setVTKWriteTarget(WriteTarget targetCells)
virtual long getCellCount() const
bool dump(std::ostream &stream)
void write(VTKWriteMode mode=VTKWriteMode::DEFAULT)
long getInternalCellCount() const
void setStaticKernel(const PiercedKernel< id_t > *kernel)
void unsetKernel(bool release=true)
Metafunction for generating a pierced storage.
__PS_POINTER__ rawData(std::size_t pos, std::size_t offset=0)
void dump(std::ostream &stream) const
void setDirectory(const std::string &)
VTKField & addData(VTKField &&field)
void removeData(const std::string &)
void setName(const std::string &)
The VolOctree defines a Octree patch.
The VolumeKernel class provides an interface for defining volume patches.
void sum(const std::array< T, d > &x, T1 &s)
double norm(const std::array< T, d > &x, int p)
T dotProduct(const std::array< T, d > &x, const std::array< T, d > &y)
std::array< T, d > max(const std::array< T, d > &x, const std::array< T, d > &y)
std::array< T, d > min(const std::array< T, d > &x, const std::array< T, d > &y)
void write(std::ostream &stream, const std::vector< bool > &container)
Logger & cout(log::Level defaultSeverity, log::Visibility defaultVisibility)
Logger & info(log::Visibility defaultVisibility)
The PODfield structure is used to store the fields inside POD classes.
std::unique_ptr< pod::ScalarStorage > scalar
std::unique_ptr< PiercedStorage< bool > > mask
std::unique_ptr< pod::VectorStorage > vector
void setMesh(VolumeKernel *lmesh)
The PODMode structure is used to store the modes inside pod classes.
std::unique_ptr< pod::VectorStorage > vector
std::unique_ptr< pod::ScalarStorage > scalar
The SnapFile structure is used to store the file names inside POD classes.