#include <array>
#if BITPIT_ENABLE_MPI
#include <mpi.h>
#endif
#include "pod.hpp"
#include "bitpit_patchkernel.hpp"
#include "bitpit_voloctree.hpp"
using namespace bitpit;
void run(int rank, int nProcs)
{
if (rank==0)
std::cout<< "0. Compute POD ..." << std::endl;
for (int i=1; i<11; i++)
pod.addSnapshot(
"./data",
"test."+std::to_string(i));
pod.setName(
"pod.test.solver");
if (rank==0)
std::cout<< "1. Restore POD ..." << std::endl;
if (rank==0)
std::cout<< "2. Read snapshot for reconstruction ..." << std::endl;
#if BITPIT_ENABLE_MPI
#else
#endif
{
int dumpBlock = (nProcs > 1) ? rank : -1;
std::string filename = "./data/test.0.mesh";
binaryReader.close();
}
std::size_t nf;
int dumpBlock = (nProcs > 1) ? rank : -1;
std::string filename = "./data/test.0.data";
std::istream &dataStream = binaryReader.
getStream();
fieldr.
mask->restore(dataStream);
std::size_t nsf;
std::vector<std::string> namesf;
namesf.resize(nsf);
for (std::size_t i = 0; i <nsf; ++i){
}
fieldr.
scalar->restore(dataStream);
std::size_t nvf;
std::vector<std::array<std::string,3>> namevf;
namevf.resize(nvf);
for (std::size_t i = 0; i < nvf; ++i){
}
fieldr.
vector->restore(dataStream);
binaryReader.close();
nf=nsf+nvf;
pod.reconstructFields(fieldr,reconr);
if (rank==0){
std::cout<<
">> N modes:" <<
pod.getModeCount() << std::endl;
std::cout<< ">> Reconstruction coeffs:" << std::endl;
for (std::size_t i = 0; i < nf; ++i)
std::cout<<
pod.getReconstructionCoeffs()[i] << std::endl;
}
std::unordered_set<long> targetCells;
std::map<std::string, std::size_t> fields;
long id = cell.getId();
for (std::size_t ifield=0; ifield<nsf; ifield++){
gfield0.
at(
id, ifield) = fieldr.
scalar->at(
id, ifield);
gfieldAdapt.
at(
id, ifield) = fieldr.
scalar->at(
id, ifield);
}
for (std::size_t ifield=0; ifield<nvf; ifield++){
for (std::size_t j=0; j<3; j++){
gfield0.
at(
id, ifield*3+nsf+j) = fieldr.
vector->at(
id, ifield)[j];
gfieldAdapt.
at(
id, ifield*3+nsf+j) = fieldr.
vector->at(
id, ifield)[j];
}
}
if (fieldr.
mask->at(
id)){
targetCells.insert(id);
gfield0.
at(
id, nsf+3*nvf) = fieldr.
mask->at(
id);
gfieldAdapt.
at(
id, nsf+3*nvf) = fieldr.
mask->at(
id);
}
}
for (std::size_t ifield=0; ifield<nsf; ifield++){
fields[namesf[ifield]] = ifield;
}
for (std::size_t ifield=0; ifield<nvf; ifield++){
for (std::size_t j=0; j<3; j++){
fields[namevf[ifield][j]] = ifield*3+nsf+j;
}
}
pod.reconstructFields(gfield0, meshr, fields, &targetCells);
if (rank==0){
std::cout<< " " << std::endl;
std::cout<< ">> Reconstruction coeffs hybrid interface:" << std::endl;
for (std::size_t i = 0; i < nf; ++i)
std::cout<<
pod.getReconstructionCoeffs()[i] << std::endl;
std::cout<< " " << std::endl;
std::cout<< ">> Reconstruction error hybrid interface" << std::endl;
double maxerr = 0.0;
long id = cell.getId();
for (std::size_t i = 0; i < nsf; ++i)
maxerr = std::max(maxerr, std::abs(gfield0.
at(
id, i) - fieldr.
scalar->at(
id, i)));
for (std::size_t i = 0; i < nvf; ++i){
for (std::size_t j=0; j<3; j++)
maxerr = std::max(maxerr, std::abs(gfield0.
at(
id, nsf+3*i+j) - fieldr.
vector->at(
id, i)[j]));
}
}
std::cout<< ">> Max error :" << maxerr << std::endl;
}
log::cout() <<
">> Marking the cells to adapt... " << std::endl;
for (int i = 0; i < 100; ++i) {
long cellId = rand() % nCells * 2;
if (!meshr->
getCells().exists(cellId)) {
continue;
}
}
}
for (int i = 0; i < 50; ++i) {
long cellId = rand() % nCells * 2;
if (!meshr->
getCells().exists(cellId)) {
continue;
}
if (fieldr.
mask->at(cellId)){
if (fieldr.
mask->at(neighId))
}
}
}
log::cout() <<
">> Initial number of cells... " << nCells << std::endl;
{
for (long & id : info.previous){
oldData.
insert(
id, std::vector<double>(nsf+3*nvf+1, 0.0));
for (std::size_t i=0; i<nsf+3*nvf+1; i++)
oldData[
id][i] = gfield0.
at(
id,i);
}
}
std::vector<adaption::Info> adaptInfo = meshr->
adaptionAlter(
true);
log::cout() <<
">> Final number of cells... " << nCells << std::endl;
if (info.type == adaption::Type::TYPE_RENUMBERING){
for (std::size_t i=0; i<nsf+3*nvf+1; i++){
gfield0.
at(info.current[0],i) = oldData[info.previous[0]][i];
gfieldAdapt.
at(info.current[0],i) = oldData[info.previous[0]][i];
}
}
if (info.type == adaption::Type::TYPE_REFINEMENT){
for (long & id : info.current){
for (std::size_t i=0; i<nsf+3*nvf+1; i++){
gfield0.
at(
id,i) = oldData[info.previous[0]][i];
gfieldAdapt.
at(
id,i) = oldData[info.previous[0]][i];
}
}
}
if (info.type == adaption::Type::TYPE_COARSENING){
for (std::size_t i=0; i<nsf+3*nvf+1; i++){
gfield0.
at(info.current[0], i) = 0.0;
gfieldAdapt.
at(info.current[0], i) = 0.0;
}
for (long & id : info.previous){
for (std::size_t i=0; i<nsf+3*nvf; i++){
gfield0.
at(info.current[0],i) += oldData[id][i] / info.previous.size();
gfieldAdapt.
at(info.current[0],i) += oldData[id][i] / info.previous.size();
}
gfield0.
at(info.current[0], nsf+3*nvf) = std::max(gfield0.
at(info.current[0], nsf+3*nvf), oldData[
id][nsf+3*nvf]);
gfieldAdapt.
at(info.current[0], nsf+3*nvf) = std::max(gfieldAdapt.
at(info.current[0], nsf+3*nvf), oldData[
id][nsf+3*nvf]);
}
}
}
}
targetCells.clear();
long id = cell.getId();
if (gfield0.
at(
id, nsf+3*nvf))
targetCells.insert(id);
}
pod.setStaticMesh(
false);
pod.reconstructFields(gfield0, meshr, fields, &targetCells);
if (rank==0){
std::cout<< " " << std::endl;
std::cout<< ">> Reconstruction coeffs hybrid interface:" << std::endl;
for (std::size_t i = 0; i < nf; ++i)
std::cout<<
pod.getReconstructionCoeffs()[i] << std::endl;
std::cout<< " " << std::endl;
std::cout<< ">> Reconstruction error hybrid interface" << std::endl;
double maxerr = 0.0;
long id = cell.getId();
for (std::size_t i = 0; i < nsf+3*nvf; ++i)
maxerr = std::max(maxerr, std::abs(gfield0.
at(
id, i) - gfieldAdapt.
at(
id, i)));
}
std::cout<< ">> Max error :" << maxerr << std::endl;
}
}
int main(int argc, char *argv[])
{
#if BITPIT_ENABLE_MPI
MPI_Init(&argc,&argv);
#endif
int nProcs;
int rank;
#if BITPIT_ENABLE_MPI
MPI_Comm_size(MPI_COMM_WORLD, &nProcs);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
#else
nProcs = 1;
rank = 0;
#endif
try {
run(rank, nProcs);
} catch (const std::exception &exception) {
exit(1);
}
#if BITPIT_ENABLE_MPI
MPI_Finalize();
#endif
}
The Cell class defines the cells.
std::istream & getStream()
The POD (Proper Orthogonal Decomposition) class provides an interface for defining POD object.
void setDirectory(const std::string &directory)
void setName(const std::string &name)
void markCellForRefinement(long id)
PiercedVector< Cell > & getCells()
std::vector< long > findCellNeighs(long id) const
std::vector< adaption::Info > adaptionPrepare(bool trackAdaption=true)
void markCellForCoarsening(long id)
void restore(std::istream &stream, bool reregister=false)
virtual long getCellCount() const
std::vector< adaption::Info > adaptionAlter(bool trackAdaption=true, bool squeezeStorage=false)
Metafunction for generating a pierced storage.
__PS_REFERENCE__ at(id_t id, std::size_t k=0)
Metafunction for generating a pierced vector.
iterator insert(id_t id, const value_t &value)
The VolOctree defines a Octree patch.
The VolumeKernel class provides an interface for defining volume patches.
void read(std::istream &stream, std::vector< bool > &container)
Logger & cout(log::Level defaultSeverity, log::Visibility defaultVisibility)
The namespace 'pod' contains structures for working with the POD class.
PiercedStorage< std::array< double, 3 > > VectorStorage
PiercedStorage< double > ScalarStorage
The Info struct defines the infomation associated to an adaption.
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