45#include "bitpit_patchkernel.hpp"
46#include "bitpit_voloctree.hpp"
48using namespace bitpit;
53void run(
int rank,
int nProcs)
56 std::cout<<
"0. Compute POD ..." << std::endl;
61 for (
int i=1; i<11; i++)
62 pod.
addSnapshot(
"./data",
"test."+std::to_string(i));
78 std::cout<<
"1. Restore POD ..." << std::endl;
85 podr.
setName(
"pod.test.solver");
89 std::cout<<
"2. Read snapshot for reconstruction ..." << std::endl;
97 int dumpBlock = (nProcs > 1) ? rank : -1;
98 std::string filename =
"./data/test.0.mesh";
100 meshr->
restore(binaryReader.getStream());
101 binaryReader.close();
107 int dumpBlock = (nProcs > 1) ? rank : -1;
108 std::string filename =
"./data/test.0.data";
110 std::istream &dataStream = binaryReader.getStream();
114 fieldr.
mask->restore(dataStream);
119 std::vector<std::string> namesf;
121 for (std::size_t i = 0; i <nsf; ++i){
126 fieldr.
scalar->restore(dataStream);
131 std::vector<std::array<std::string,3>> namevf;
133 for (std::size_t i = 0; i < nvf; ++i){
138 fieldr.
vector->restore(dataStream);
139 binaryReader.close();
150 std::cout<<
">> N modes:" << pod.
getModeCount() << std::endl;
152 std::cout<<
">> Reconstruction coeffs:" << std::endl;
153 for (std::size_t i = 0; i < nf; ++i)
161 std::unordered_set<long> targetCells;
163 std::map<std::string, std::size_t> fields;
165 for (
Cell & cell : meshr->getCells()){
166 long id = cell.getId();
167 for (std::size_t ifield=0; ifield<nsf; ifield++){
168 gfield0.at(
id, ifield) = fieldr.
scalar->at(
id, ifield);
169 gfieldAdapt.at(
id, ifield) = fieldr.
scalar->at(
id, ifield);
172 for (std::size_t ifield=0; ifield<nvf; ifield++){
173 for (std::size_t j=0; j<3; j++){
174 gfield0.at(
id, ifield*3+nsf+j) = fieldr.
vector->at(
id, ifield)[j];
175 gfieldAdapt.at(
id, ifield*3+nsf+j) = fieldr.
vector->at(
id, ifield)[j];
179 if (fieldr.
mask->at(
id)){
180 targetCells.insert(
id);
181 gfield0.at(
id, nsf+3*nvf) = fieldr.
mask->at(
id);
182 gfieldAdapt.at(
id, nsf+3*nvf) = fieldr.
mask->at(
id);
186 for (std::size_t ifield=0; ifield<nsf; ifield++){
187 fields[namesf[ifield]] = ifield;
189 for (std::size_t ifield=0; ifield<nvf; ifield++){
190 for (std::size_t j=0; j<3; j++){
191 fields[namevf[ifield][j]] = ifield*3+nsf+j;
198 std::cout<<
" " << std::endl;
199 std::cout<<
">> Reconstruction coeffs hybrid interface:" << std::endl;
200 for (std::size_t i = 0; i < nf; ++i)
203 std::cout<<
" " << std::endl;
204 std::cout<<
">> Reconstruction error hybrid interface" << std::endl;
206 for (
Cell & cell : meshr->getCells()){
207 long id = cell.getId();
208 for (std::size_t i = 0; i < nsf; ++i)
209 maxerr = std::max(maxerr, std::abs(gfield0.at(
id, i) - fieldr.
scalar->at(
id, i)));
210 for (std::size_t i = 0; i < nvf; ++i){
211 for (std::size_t j=0; j<3; j++)
212 maxerr = std::max(maxerr, std::abs(gfield0.at(
id, nsf+3*i+j) - fieldr.
vector->at(
id, i)[j]));
215 std::cout<<
">> Max error :" << maxerr << std::endl;
224 log::cout() <<
">> Marking the cells to adapt... " << std::endl;
226 for (
int i = 0; i < 100; ++i) {
227 long cellId = rand() % nCells * 2;
228 if (!meshr->
getCells().exists(cellId)) {
232 for (
auto neighId : meshr->findCellNeighs(cellId)) {
237 for (
int i = 0; i < 50; ++i) {
238 long cellId = rand() % nCells * 2;
239 if (!meshr->
getCells().exists(cellId)) {
243 if (fieldr.
mask->at(cellId)){
245 for (
auto neighId : meshr->findCellNeighs(cellId)) {
246 if (fieldr.
mask->at(neighId))
253 log::cout() <<
">> Initial number of cells... " << nCells << std::endl;
258 std::vector<adaption::Info> preadaptInfo = meshr->
adaptionPrepare(
true);
262 for (
long &
id :
info.previous){
263 oldData.insert(
id, std::vector<double>(nsf+3*nvf+1, 0.0));
264 for (std::size_t i=0; i<nsf+3*nvf+1; i++)
265 oldData[
id][i] = gfield0.at(
id,i);
269 std::vector<adaption::Info> adaptInfo = meshr->
adaptionAlter(
true);
272 log::cout() <<
">> Final number of cells... " << nCells << std::endl;
275 if (
info.type == adaption::Type::TYPE_RENUMBERING){
276 for (std::size_t i=0; i<nsf+3*nvf+1; i++){
277 gfield0.at(
info.current[0],i) = oldData[
info.previous[0]][i];
278 gfieldAdapt.at(
info.current[0],i) = oldData[
info.previous[0]][i];
281 if (
info.type == adaption::Type::TYPE_REFINEMENT){
282 for (
long &
id :
info.current){
283 for (std::size_t i=0; i<nsf+3*nvf+1; i++){
284 gfield0.at(
id,i) = oldData[
info.previous[0]][i];
285 gfieldAdapt.at(
id,i) = oldData[
info.previous[0]][i];
289 if (
info.type == adaption::Type::TYPE_COARSENING){
290 for (std::size_t i=0; i<nsf+3*nvf+1; i++){
291 gfield0.at(
info.current[0], i) = 0.0;
292 gfieldAdapt.at(
info.current[0], i) = 0.0;
294 for (
long &
id :
info.previous){
295 for (std::size_t i=0; i<nsf+3*nvf; i++){
296 gfield0.at(
info.current[0],i) += oldData[id][i] /
info.previous.size();
297 gfieldAdapt.at(
info.current[0],i) += oldData[id][i] /
info.previous.size();
299 gfield0.at(
info.current[0], nsf+3*nvf) = std::max(gfield0.at(
info.current[0], nsf+3*nvf), oldData[
id][nsf+3*nvf]);
300 gfieldAdapt.at(
info.current[0], nsf+3*nvf) = std::max(gfieldAdapt.at(
info.current[0], nsf+3*nvf), oldData[
id][nsf+3*nvf]);
313 for (
Cell & cell : meshr->getCells()){
314 long id = cell.getId();
315 if (gfield0.at(
id, nsf+3*nvf))
316 targetCells.insert(
id);
325 std::cout<<
" " << std::endl;
326 std::cout<<
">> Reconstruction coeffs hybrid interface:" << std::endl;
327 for (std::size_t i = 0; i < nf; ++i)
330 std::cout<<
" " << std::endl;
331 std::cout<<
">> Reconstruction error hybrid interface" << std::endl;
333 for (
Cell & cell : meshr->getCells()){
334 long id = cell.getId();
335 for (std::size_t i = 0; i < nsf+3*nvf; ++i)
336 maxerr = std::max(maxerr, std::abs(gfield0.at(
id, i) - gfieldAdapt.at(
id, i)));
338 std::cout<<
">> Max error :" << maxerr << std::endl;
348int main(
int argc,
char *argv[])
351 MPI_Init(&argc,&argv);
358 MPI_Comm_size(MPI_COMM_WORLD, &nProcs);
359 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
368 }
catch (
const std::exception &exception) {
The Cell class defines the cells.
The POD (Proper Orthogonal Decomposition) class provides an interface for defining POD object.
std::size_t getModeCount()
void setMeshType(MeshType type)
void setStaticMesh(bool flag)
void setSensorMask(const PiercedStorage< bool > &mask, VolumeKernel *mesh=nullptr)
void setMemoryMode(MemoryMode mode)
void setDirectory(const std::string &directory)
void reconstructFields(pod::PODField &field, pod::PODField &recon)
void setWriteMode(WriteMode mode)
void setModeCount(std::size_t nmodes)
void setName(const std::string &name)
std::vector< std::vector< double > > getReconstructionCoeffs()
void addSnapshot(const std::string &directory, const std::string &name)
void markCellForRefinement(long id)
PiercedVector< Cell > & getCells()
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.
Metafunction for generating a pierced vector.
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)
Logger & info(log::Visibility defaultVisibility)
The Info struct defines the information 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