25#include "pod_voloctree.hpp"
64std::unique_ptr<VolumeKernel> PODVolOctree::createMesh()
69 return std::unique_ptr<VolumeKernel>(
new VolOctree());
79std::unique_ptr<VolumeMapper> PODVolOctree::_computeMapper(
const VolumeKernel* mesh,
bool fillInv)
81 const VolOctree* meshPOD =
static_cast<const VolOctree*
>(
getMesh());
82 const VolOctree* _mesh =
static_cast<const VolOctree*
>(mesh);
84 std::unique_ptr<VolumeMapper> mapper;
86 mapper = std::unique_ptr<VolumeMapper>(
new VolOctreeMapper(meshPOD, _mesh,
getCommunicator()));
88 mapper = std::unique_ptr<VolumeMapper>(
new VolOctreeMapper(meshPOD, _mesh));
91 mapper->initialize(fillInv);
103pod::PODField PODVolOctree::mapPODFieldToPOD(
const pod::PODField & field,
const std::unordered_set<long> * targetCells)
107 std::unordered_set<long> targetCellsStorage;
109 for (
const Cell &cell :
getMesh()->getCells())
110 targetCellsStorage.insert(cell.getId());
112 targetCells = &targetCellsStorage;
116 std::size_t nsf = field.scalar->getFieldCount();
117 std::size_t nvf = field.vector->getFieldCount();
121 pod::PODField mappedField(nsf, nvf,
getMesh(), &
getMesh()->getCells());
128 for (
long id : *targetCells){
129 std::size_t rawIndex =
m_meshPOD->getCells().getRawIndex(
id);
131 double *datamappedS = mappedField.scalar->data(
id);
132 std::array<double,3> *datamappedV = mappedField.vector->data(
id);
134 if (mappingInfo[
id].type == mapping::Type::TYPE_RENUMBERING){
135 bool dataB = field.mask->at(mappingInfo[
id].ids[0]);
136 mappedField.mask->set(
id, dataB);
138 double *dataS = field.scalar->data(mappingInfo[
id].ids[0]);
139 for (std::size_t i = 0; i < nsf; i++){
140 double *dataSi = dataS + i;
141 double *datamappedSi = datamappedS + i;
142 (*datamappedSi) = (*dataSi);
145 std::array<double,3> *dataV = field.vector->data(mappingInfo[
id].ids[0]);
146 for (std::size_t i = 0; i < nvf; i++) {
147 std::array<double,3> *dataVi = dataV + i;
148 std::array<double,3> *datamappedVi = datamappedV + i;
149 (*datamappedVi) = (*dataVi);
152 else if (mappingInfo[
id].type == mapping::Type::TYPE_COARSENING){
153 mappedField.mask->set(
id,
true);
155 for (std::size_t i = 0; i < nsf; i++){
156 double *datamappedSi = datamappedS + i;
157 (*datamappedSi) = 0.0;
159 for (std::size_t i = 0; i < nvf; i++){
160 std::array<double,3> *datamappedVi = datamappedV + i;
161 (*datamappedVi) = std::array<double,3>{0.0, 0.0, 0.0};
164 bool dataB, dataMappedB =
true;
166 std::array<double,3> *dataV;
168 for (
long idd : mappingInfo[id].ids){
169 dataB = field.mask->at(idd);
170 dataMappedB &= dataB;
172 dataS = field.scalar->data(idd);
173 double vol = field.mesh->evalCellVolume(idd);
174 for (std::size_t i = 0; i < nsf; i++){
175 double *dataSi = dataS + i;
176 double *datamappedSi = datamappedS + i;
177 (*datamappedSi) += (*dataSi) * vol / volmapped;
179 dataV = field.vector->data(idd);
180 for (std::size_t i = 0; i < nvf; i++) {
181 std::array<double,3> *dataVi = dataV + i;
182 std::array<double,3> *datamappedVi = datamappedV + i;
183 (*datamappedVi) += (*dataVi) * vol / volmapped;
186 mappedField.mask->set(
id, dataMappedB);
189 else if (mappingInfo[
id].type == mapping::Type::TYPE_REFINEMENT){
190 bool dataB = field.mask->at(mappingInfo[
id].ids[0]);
191 double *dataS = field.scalar->data(mappingInfo[
id].ids[0]);
192 std::array<double,3> *dataV = field.vector->data(mappingInfo[
id].ids[0]);
194 mappedField.mask->set(
id, dataB);
196 for (std::size_t i = 0; i < nsf; i++){
197 double *dataSi = dataS + i;
198 double *datamappedSi = datamappedS + i;
199 (*datamappedSi) = (*dataSi);
201 for (std::size_t i = 0; i < nvf; i++) {
202 std::array<double,3> *dataVi = dataV + i;
203 std::array<double,3> *datamappedVi = datamappedV + i;
204 (*datamappedVi) = (*dataVi);
216 std::map<int, std::map<long, bool> > dataBrec;
217 std::map<int, std::map<long, std::vector<double> > > dataSrec;
218 std::map<int, std::map<long, std::vector<std::array<double, 3> > > > dataVrec;
219 std::map<int, std::map<long, double> > volrec;
221 communicatePODField(field, dataBrec, dataSrec, dataVrec, volrec);
223 for (
long id : *targetCells){
225 double *datamappedS = mappedField.scalar->data(
id);
226 std::array<double,3> *datamappedV = mappedField.vector->data(
id);
228 if (mappingInfo[
id].type == mapping::Type::TYPE_RENUMBERING){
230 int rank = mappingInfo[id].ranks[0];
232 bool dataB = dataBrec[rank][mappingInfo[id].ids[0]];
233 mappedField.mask->set(
id, dataB);
235 double *dataS = dataSrec[rank][mappingInfo[id].ids[0]].data();
236 for (std::size_t i = 0; i < nsf; i++){
237 double *dataSi = dataS + i;
238 double *datamappedSi = datamappedS + i;
239 (*datamappedSi) = (*dataSi);
242 std::array<double,3> *dataV = dataVrec[rank][mappingInfo[id].ids[0]].data();
243 for (std::size_t i = 0; i < nvf; i++) {
244 std::array<double,3> *dataVi = dataV + i;
245 std::array<double,3> *datamappedVi = datamappedV + i;
246 (*datamappedVi) = (*dataVi);
251 bool dataB = field.mask->at(mappingInfo[
id].ids[0]);
252 mappedField.mask->set(
id, dataB);
254 double *dataS = field.scalar->data(mappingInfo[
id].ids[0]);
255 for (std::size_t i = 0; i < nsf; i++){
256 double *dataSi = dataS + i;
257 double *datamappedSi = datamappedS + i;
258 (*datamappedSi) = (*dataSi);
261 std::array<double,3> *dataV = field.vector->data(mappingInfo[
id].ids[0]);
262 for (std::size_t i = 0; i < nvf; i++) {
263 std::array<double,3> *dataVi = dataV + i;
264 std::array<double,3> *datamappedVi = datamappedV + i;
265 (*datamappedVi) = (*dataVi);
270 else if (mappingInfo[
id].type == mapping::Type::TYPE_COARSENING){
271 mappedField.mask->set(
id,
true);
273 for (std::size_t i = 0; i < nsf; i++){
274 double *datamappedSi = datamappedS + i;
275 (*datamappedSi) = 0.0;
277 for (std::size_t i = 0; i < nvf; i++){
278 std::array<double,3> *datamappedVi = datamappedV + i;
279 (*datamappedVi) = std::array<double,3>{0.0, 0.0, 0.0};
282 bool dataB, dataMappedB =
true;
284 std::array<double,3> *dataV;
288 for (
long idd : mappingInfo[id].ids){
289 int rank = mappingInfo[id].ranks[ii];
291 dataB = dataBrec[rank][idd];
292 dataS = dataSrec[rank][idd].data();
293 dataV = dataVrec[rank][idd].data();
294 vol = volrec[rank][idd];
297 dataB = field.mask->at(idd);
298 dataS = field.scalar->data(idd);
299 dataV = field.vector->data(idd);
300 vol = field.mesh->evalCellVolume(idd);
302 dataMappedB &= dataB;
304 for (std::size_t i = 0; i < nsf; i++){
305 double *dataSi = dataS + i;
306 double *datamappedSi = datamappedS + i;
307 (*datamappedSi) += (*dataSi) * vol / volmapped;
309 for (std::size_t i = 0; i < nvf; i++) {
310 std::array<double,3> *dataVi = dataV + i;
311 std::array<double,3> *datamappedVi = datamappedV + i;
312 (*datamappedVi) += (*dataVi) * vol / volmapped;
316 mappedField.mask->set(
id, dataMappedB);
319 else if (mappingInfo[
id].type == mapping::Type::TYPE_REFINEMENT){
322 std::array<double,3> *dataV;
323 int rank = mappingInfo[id].ranks[0];
325 dataB = dataBrec[rank][mappingInfo[id].ids[0]];
326 dataS = dataSrec[rank][mappingInfo[id].ids[0]].data();
327 dataV = dataVrec[rank][mappingInfo[id].ids[0]].data();
330 dataB = field.mask->at(mappingInfo[
id].ids[0]);
331 dataS = field.scalar->data(mappingInfo[
id].ids[0]);
332 dataV = field.vector->data(mappingInfo[
id].ids[0]);
335 mappedField.mask->set(
id, dataB);
337 for (std::size_t i = 0; i < nsf; i++){
338 double *dataSi = dataS + i;
339 double *datamappedSi = datamappedS + i;
340 (*datamappedSi) = (*dataSi);
342 for (std::size_t i = 0; i < nvf; i++) {
343 std::array<double,3> *dataVi = dataV + i;
344 std::array<double,3> *datamappedVi = datamappedV + i;
345 (*datamappedVi) = (*dataVi);
363void PODVolOctree::mapPODFieldFromPOD(pod::PODField & field,
const std::unordered_set<long> * targetCells,
364 const pod::PODField & mappedField)
368 std::unordered_set<long> targetCellsStorage;
370 for (
const Cell &cell : field.mesh->getCells())
371 targetCellsStorage.insert(cell.getId());
373 targetCells = &targetCellsStorage;
377 std::size_t nsf = field.scalar->getFieldCount();
378 std::size_t nvf = field.vector->getFieldCount();
387 for (
long id : *targetCells){
388 double *dataS = field.scalar->data(
id);
389 std::array<double,3> *dataV = field.vector->data(
id);
391 if (inverseMapping[
id].type == mapping::Type::TYPE_RENUMBERING){
392 bool datamappedB = mappedField.mask->at(inverseMapping[
id].ids[0]);
393 field.mask->set(
id, datamappedB);
394 double *datamappedS = mappedField.scalar->data(inverseMapping[
id].ids[0]);
395 for (std::size_t i = 0; i < nsf; i++){
396 double *dataSi = dataS + i;
397 double *datamappedSi = datamappedS + i;
398 (*dataSi) = (*datamappedSi);
400 std::array<double,3> *datamappedV = mappedField.vector->data(inverseMapping[
id].ids[0]);
401 for (std::size_t i = 0; i < nvf; i++) {
402 std::array<double,3> *dataVi = dataV + i;
403 std::array<double,3> *datamappedVi = datamappedV + i;
404 (*dataVi) = (*datamappedVi);
407 else if (inverseMapping[
id].type == mapping::Type::TYPE_COARSENING){
409 for (std::size_t i = 0; i < nsf; i++){
410 double *dataSi = dataS + i;
413 for (std::size_t i = 0; i < nvf; i++){
414 std::array<double,3> *dataVi = dataV + i;
415 (*dataVi) = std::array<double,3>{0.0, 0.0, 0.0};
419 std::array<double,3> *datamappedV;
420 double vol = field.mesh->evalCellVolume(
id);
421 for (
long idd : inverseMapping[id].ids){
422 std::size_t rawIndexIdd =
m_meshPOD->getCells().getRawIndex(idd);
423 datamappedB = mappedField.mask->at(idd);
424 dataB &= datamappedB;
425 datamappedS = mappedField.scalar->data(idd);
427 for (std::size_t i = 0; i < nsf; i++){
428 double *dataSi = dataS + i;
429 double *datamappedSi = datamappedS + i;
430 (*dataSi) += (*datamappedSi) * volmapped / vol;
432 datamappedV = mappedField.vector->data(idd);
433 for (std::size_t i = 0; i < nvf; i++) {
434 std::array<double,3> *dataVi = dataV + i;
435 std::array<double,3> *datamappedVi = datamappedV + i;
436 (*dataVi) += (*datamappedVi) * volmapped / vol;
439 field.mask->set(
id, dataB);
441 else if (inverseMapping[
id].type == mapping::Type::TYPE_REFINEMENT){
442 bool datamappedB = mappedField.mask->at(inverseMapping[
id].ids[0]);
443 field.mask->set(
id, datamappedB);
444 double *datamappedS = mappedField.scalar->data(inverseMapping[
id].ids[0]);
445 for (std::size_t i = 0; i < nsf; i++){
446 double *dataSi = dataS + i;
447 double *datamappedSi = datamappedS + i;
448 (*dataSi) = (*datamappedSi);
450 std::array<double,3> *datamappedV = mappedField.vector->data(inverseMapping[
id].ids[0]);
451 for (std::size_t i = 0; i < nvf; i++) {
452 std::array<double,3> *dataVi = dataV + i;
453 std::array<double,3> *datamappedVi = datamappedV + i;
454 (*dataVi) = (*datamappedVi);
466 std::map<int, std::map<long, bool> > dataBrec;
467 std::map<int, std::map<long, std::vector<double> > > dataSrec;
468 std::map<int, std::map<long, std::vector<std::array<double, 3> > > > dataVrec;
469 std::map<int, std::map<long, double> > volrec;
471 communicatePODFieldFromPOD(mappedField, dataBrec, dataSrec, dataVrec, volrec);
473 for (
long id : *targetCells){
474 double *dataS = field.scalar->data(
id);
475 std::array<double,3> *dataV = field.vector->data(
id);
477 if (inverseMapping[
id].type == mapping::Type::TYPE_RENUMBERING){
480 std::array<double,3> *datamappedV;
481 int rank = inverseMapping[id].ranks[0];
483 datamappedB = dataBrec[rank][inverseMapping[id].ids[0]];
484 datamappedS = dataSrec[rank][inverseMapping[id].ids[0]].data();
485 datamappedV = dataVrec[rank][inverseMapping[id].ids[0]].data();
488 datamappedB = mappedField.mask->at(inverseMapping[
id].ids[0]);
489 datamappedS = mappedField.scalar->data(inverseMapping[
id].ids[0]);
490 datamappedV = mappedField.vector->data(inverseMapping[
id].ids[0]);
493 field.mask->set(
id, datamappedB);
494 for (std::size_t i = 0; i < nsf; i++){
495 double *dataSi = dataS + i;
496 double *datamappedSi = datamappedS + i;
497 (*dataSi) = (*datamappedSi);
499 for (std::size_t i = 0; i < nvf; i++) {
500 std::array<double,3> *dataVi = dataV + i;
501 std::array<double,3> *datamappedVi = datamappedV + i;
502 (*dataVi) = (*datamappedVi);
505 else if (inverseMapping[
id].type == mapping::Type::TYPE_COARSENING){
507 for (std::size_t i = 0; i < nsf; i++){
508 double *dataSi = dataS + i;
511 for (std::size_t i = 0; i < nvf; i++){
512 std::array<double,3> *dataVi = dataV + i;
513 (*dataVi) = std::array<double,3>{0.0, 0.0, 0.0};
517 std::array<double,3> *datamappedV;
519 double vol = field.mesh->evalCellVolume(
id);
521 for (
long idd : inverseMapping[id].ids){
522 int rank = inverseMapping[id].ranks[ii];
524 datamappedB = dataBrec[rank][idd];
525 datamappedS = dataSrec[rank][idd].data();
526 datamappedV = dataVrec[rank][idd].data();
527 volmapped = volrec[rank][idd];
530 datamappedB = mappedField.mask->at(idd);
531 datamappedS = mappedField.scalar->data(idd);
532 datamappedV = mappedField.vector->data(idd);
536 dataB &= datamappedB;
537 for (std::size_t i = 0; i < nsf; i++){
538 double *dataSi = dataS + i;
539 double *datamappedSi = datamappedS + i;
540 (*dataSi) += (*datamappedSi) * volmapped / vol;
542 for (std::size_t i = 0; i < nvf; i++) {
543 std::array<double,3> *dataVi = dataV + i;
544 std::array<double,3> *datamappedVi = datamappedV + i;
545 (*dataVi) += (*datamappedVi) * volmapped / vol;
549 field.mask->set(
id, dataB);
551 else if (inverseMapping[
id].type == mapping::Type::TYPE_REFINEMENT){
554 std::array<double,3> *datamappedV;
555 int rank = inverseMapping[id].ranks[0];
557 datamappedB = dataBrec[rank][inverseMapping[id].ids[0]];
558 datamappedS = dataSrec[rank][inverseMapping[id].ids[0]].data();
559 datamappedV = dataVrec[rank][inverseMapping[id].ids[0]].data();
562 datamappedB = mappedField.mask->at(inverseMapping[
id].ids[0]);
563 datamappedS = mappedField.scalar->data(inverseMapping[
id].ids[0]);
564 datamappedV = mappedField.vector->data(inverseMapping[
id].ids[0]);
567 field.mask->set(
id, datamappedB);
568 for (std::size_t i = 0; i < nsf; i++){
569 double *dataSi = dataS + i;
570 double *datamappedSi = datamappedS + i;
571 (*dataSi) = (*datamappedSi);
573 for (std::size_t i = 0; i < nvf; i++) {
574 std::array<double,3> *dataVi = dataV + i;
575 std::array<double,3> *datamappedVi = datamappedV + i;
576 (*dataVi) = (*datamappedVi);
596PiercedStorage<double> PODVolOctree::mapFieldsToPOD(
const PiercedStorage<double> & fields,
const VolumeKernel * mesh,
597 const std::unordered_set<long> * targetCells,
598 const std::vector<std::size_t> &scalarIds,
599 const std::vector<std::array<std::size_t, 3>> &vectorIds)
603 std::unordered_set<long> targetCellsStorage;
605 for (
const Cell &cell :
getMesh()->getCells())
606 targetCellsStorage.insert(cell.getId());
608 targetCells = &targetCellsStorage;
612 std::size_t nsf = scalarIds.size();
613 std::size_t nvf = vectorIds.size();
617 PiercedStorage<double> mappedFields(fields.getFieldCount(), &
getMesh()->getCells());
623 for (
long id : *targetCells){
624 std::size_t rawIndex =
m_meshPOD->getCells().getRawIndex(
id);
625 double *datamapped = mappedFields.data(
id);
626 if (mappingInfo[
id].type == mapping::Type::TYPE_RENUMBERING){
627 const double *data = fields.data(mappingInfo[
id].ids[0]);
628 for (std::size_t i = 0; i < nsf; i++){
629 const double *datai = data + scalarIds[i];
630 double *datamappedi = datamapped + scalarIds[i];
631 (*datamappedi) = (*datai);
633 for (std::size_t i = 0; i < nvf; i++) {
634 for (std::size_t j = 0; j < 3; j++) {
635 const double *datai = data + vectorIds[i][j];
636 double *datamappedi = datamapped + vectorIds[i][j];
637 (*datamappedi) = (*datai);
641 else if (mappingInfo[
id].type == mapping::Type::TYPE_COARSENING){
642 for (std::size_t i = 0; i < nsf; i++){
643 double *datamappedi = datamapped + scalarIds[i];
644 (*datamappedi) = 0.0;
646 for (std::size_t i = 0; i < nvf; i++){
647 for (std::size_t j = 0; j < 3; j++) {
648 double *datamappedi = datamapped + vectorIds[i][j];
649 (*datamappedi) = 0.0;
653 for (
long idd : mappingInfo[id].ids){
654 const double *data = fields.data(idd);
655 double vol = mesh->evalCellVolume(idd);
657 for (std::size_t i = 0; i < nsf; i++){
658 const double *datai = data + scalarIds[i];
659 double *datamappedi = datamapped + scalarIds[i];
660 (*datamappedi) += (*datai) * vol / volmapped;
662 for (std::size_t i = 0; i < nvf; i++) {
663 for (std::size_t j = 0; j < 3; j++) {
664 const double *datai = data + vectorIds[i][j];
665 double *datamappedi = datamapped + vectorIds[i][j];
666 (*datamappedi) += (*datai) * vol / volmapped;
671 else if (mappingInfo[
id].type == mapping::Type::TYPE_REFINEMENT){
672 const double *data = fields.data(mappingInfo[
id].ids[0]);
673 for (std::size_t i = 0; i < nsf; i++){
674 const double *datai = data + scalarIds[i];
675 double *datamappedi = datamapped + scalarIds[i];
676 (*datamappedi) = (*datai);
678 for (std::size_t i = 0; i < nvf; i++) {
679 for (std::size_t j = 0; j < 3; j++) {
680 const double *datai = data + vectorIds[i][j];
681 double *datamappedi = datamapped + vectorIds[i][j];
682 (*datamappedi) = (*datai);
695 std::map<int, std::map<long, std::vector<double> > > datarec;
696 std::map<int, std::map<long, double> > volrec;
698 communicateField(fields, mesh, datarec, volrec);
700 for (
long id : *targetCells){
701 double *datamapped = mappedFields.data(
id);
702 if (mappingInfo[
id].type == mapping::Type::TYPE_RENUMBERING){
704 int rank = mappingInfo[id].ranks[0];
706 data = datarec[rank][mappingInfo[id].ids[0]].data();
709 data = fields.data(mappingInfo[
id].ids[0]);
712 for (std::size_t i = 0; i < nsf; i++){
713 const double *datai = data + scalarIds[i];
714 double *datamappedi = datamapped + scalarIds[i];
715 (*datamappedi) = (*datai);
717 for (std::size_t i = 0; i < nvf; i++) {
718 for (std::size_t j = 0; j < 3; j++) {
719 const double *datai = data + vectorIds[i][j];
720 double *datamappedi = datamapped + vectorIds[i][j];
721 (*datamappedi) = (*datai);
725 else if (mappingInfo[
id].type == mapping::Type::TYPE_COARSENING){
726 for (std::size_t i = 0; i < nsf; i++){
727 double *datamappedi = datamapped + scalarIds[i];
728 (*datamappedi) = 0.0;
730 for (std::size_t i = 0; i < nvf; i++){
731 for (std::size_t j = 0; j < 3; j++) {
732 double *datamappedi = datamapped + vectorIds[i][j];
733 (*datamappedi) = 0.0;
738 for (
long idd : mappingInfo[id].ids){
739 int rank = mappingInfo[id].ranks[ii];
743 data = datarec[rank][idd].data();
744 vol = volrec[rank][idd];
747 data = fields.data(idd);
748 vol = mesh->evalCellVolume(idd);
751 for (std::size_t i = 0; i < nsf; i++){
752 const double *datai = data + scalarIds[i];
753 double *datamappedi = datamapped + scalarIds[i];
754 (*datamappedi) += (*datai) * vol / volmapped;
756 for (std::size_t i = 0; i < nvf; i++) {
757 for (std::size_t j = 0; j < 3; j++) {
758 const double *datai = data + vectorIds[i][j];
759 double *datamappedi = datamapped + vectorIds[i][j];
760 (*datamappedi) += (*datai) * vol / volmapped;
766 else if (mappingInfo[
id].type == mapping::Type::TYPE_REFINEMENT){
768 int rank = mappingInfo[id].ranks[0];
770 data = datarec[rank][mappingInfo[id].ids[0]].data();
773 data = fields.data(mappingInfo[
id].ids[0]);
775 for (std::size_t i = 0; i < nsf; i++){
776 const double *datai = data + scalarIds[i];
777 double *datamappedi = datamapped + scalarIds[i];
778 (*datamappedi) = (*datai);
780 for (std::size_t i = 0; i < nvf; i++) {
781 for (std::size_t j = 0; j < 3; j++) {
782 const double *datai = data + vectorIds[i][j];
783 double *datamappedi = datamapped + vectorIds[i][j];
784 (*datamappedi) = (*datai);
807void PODVolOctree::mapFieldsFromPOD(PiercedStorage<double> & fields,
const VolumeKernel * mesh,
808 const std::unordered_set<long> * targetCells,
const PiercedStorage<double> & mappedFields,
809 const std::vector<std::size_t> &scalarIds,
const std::vector<std::array<std::size_t, 3>> &vectorIds)
813 std::unordered_set<long> targetCellsStorage;
815 for (
const Cell &cell : mesh->getCells())
816 targetCellsStorage.insert(cell.getId());
818 targetCells = &targetCellsStorage;
822 std::size_t nsf = scalarIds.size();
823 std::size_t nvf = vectorIds.size();
831 for (
long id : *targetCells){
832 double *data = fields.data(
id);
833 if (inverseMapping[
id].type == mapping::Type::TYPE_RENUMBERING){
834 const double *datamapped = mappedFields.data(inverseMapping[
id].ids[0]);
835 for (std::size_t i = 0; i < nsf; i++){
836 double *datai = data + scalarIds[i];
837 const double *datamappedi = datamapped + scalarIds[i];
838 (*datai) = (*datamappedi);
840 for (std::size_t i = 0; i < nvf; i++) {
841 for (std::size_t j = 0; j < 3; j++) {
842 double *datai = data + vectorIds[i][j];
843 const double *datamappedi = datamapped + vectorIds[i][j];
844 (*datai) = (*datamappedi);
848 else if (inverseMapping[
id].type == mapping::Type::TYPE_COARSENING){
849 for (std::size_t i = 0; i < nsf; i++){
850 double *datai = data + scalarIds[i];
853 for (std::size_t i = 0; i < nvf; i++){
854 for (std::size_t j = 0; j < 3; j++) {
855 double *datai = data + vectorIds[i][j];
859 double vol = mesh->evalCellVolume(
id);
860 for (
long idd : inverseMapping[id].ids){
861 std::size_t rawIndexIdd =
m_meshPOD->getCells().getRawIndex(idd);
862 const double * datamapped = mappedFields.data(idd);
865 for (std::size_t i = 0; i < nsf; i++){
866 double *datai = data + scalarIds[i];
867 const double *datamappedi = datamapped + scalarIds[i];
868 (*datai) += (*datamappedi) * volmapped / vol;
870 for (std::size_t i = 0; i < nvf; i++) {
871 for (std::size_t j = 0; j < 3; j++) {
872 double *datai = data + vectorIds[i][j];
873 const double *datamappedi = datamapped + vectorIds[i][j];
874 (*datai) += (*datamappedi) * volmapped / vol;
879 else if (inverseMapping[
id].type == mapping::Type::TYPE_REFINEMENT){
880 const double *datamapped = mappedFields.data(inverseMapping[
id].ids[0]);
881 for (std::size_t i = 0; i < nsf; i++){
882 double *datai = data + scalarIds[i];
883 const double *datamappedi = datamapped + scalarIds[i];
884 (*datai) = (*datamappedi);
886 for (std::size_t i = 0; i < nvf; i++) {
887 for (std::size_t j = 0; j < 3; j++) {
888 double *datai = data + vectorIds[i][j];
889 const double *datamappedi = datamapped + vectorIds[i][j];
890 (*datai) = (*datamappedi);
903 std::map<int, std::map<long, std::vector<double> > > datarec;
904 std::map<int, std::map<long, double> > volrec;
906 communicateFieldFromPOD(mappedFields, mesh, datarec, volrec);
908 for (
long id : *targetCells){
909 double *data = fields.data(
id);
910 if (inverseMapping[
id].type == mapping::Type::TYPE_RENUMBERING){
911 const double *datamapped;
912 int rank = inverseMapping[id].ranks[0];
914 datamapped = datarec[rank][inverseMapping[id].ids[0]].data();
917 datamapped = mappedFields.data(inverseMapping[
id].ids[0]);
920 for (std::size_t i = 0; i < nsf; i++){
921 double *datai = data + scalarIds[i];
922 const double *datamappedi = datamapped + scalarIds[i];
923 (*datai) = (*datamappedi);
925 for (std::size_t i = 0; i < nvf; i++) {
926 for (std::size_t j = 0; j < 3; j++) {
927 double *datai = data + vectorIds[i][j];
928 const double *datamappedi = datamapped + vectorIds[i][j];
929 (*datai) = (*datamappedi);
933 else if (inverseMapping[
id].type == mapping::Type::TYPE_COARSENING){
934 for (std::size_t i = 0; i < nsf; i++){
935 double *datai = data + scalarIds[i];
938 for (std::size_t i = 0; i < nvf; i++){
939 for (std::size_t j = 0; j < 3; j++) {
940 double *datai = data + vectorIds[i][j];
944 double vol = mesh->evalCellVolume(
id);
946 for (
long idd : inverseMapping[id].ids){
947 const double *datamapped;
949 int rank = inverseMapping[id].ranks[ii];
951 datamapped = datarec[rank][idd].data();
952 volmapped = volrec[rank][idd];
955 datamapped = mappedFields.data(idd);
959 for (std::size_t i = 0; i < nsf; i++){
960 double *datai = data + scalarIds[i];
961 const double *datamappedi = datamapped + scalarIds[i];
962 (*datai) += (*datamappedi) * volmapped / vol;
964 for (std::size_t i = 0; i < nvf; i++) {
965 for (std::size_t j = 0; j < 3; j++) {
966 double *datai = data + vectorIds[i][j];
967 const double *datamappedi = datamapped + vectorIds[i][j];
968 (*datai) += (*datamappedi) * volmapped / vol;
974 else if (inverseMapping[
id].type == mapping::Type::TYPE_REFINEMENT){
975 const double *datamapped;
976 int rank = inverseMapping[id].ranks[0];
978 datamapped = datarec[rank][inverseMapping[id].ids[0]].data();
981 datamapped = mappedFields.data(inverseMapping[
id].ids[0]);
983 for (std::size_t i = 0; i < nsf; i++){
984 double *datai = data + scalarIds[i];
985 const double *datamappedi = datamapped + scalarIds[i];
986 (*datai) = (*datamappedi);
988 for (std::size_t i = 0; i < nvf; i++) {
989 for (std::size_t j = 0; j < 3; j++) {
990 double *datai = data + vectorIds[i][j];
991 const double *datamappedi = datamapped + vectorIds[i][j];
992 (*datai) = (*datamappedi);
1014PiercedStorage<bool> PODVolOctree::mapBoolFieldToPOD(
const PiercedStorage<bool> & field,
const VolumeKernel * mesh,
1015 const std::unordered_set<long> * targetCells)
1019 PiercedStorage<bool> mappedField(1, &
getMesh()->getCells());
1020 mapBoolFieldToPOD(field, mesh, targetCells, mappedField);
1033void PODVolOctree::mapBoolFieldToPOD(
const PiercedStorage<bool> & field,
const VolumeKernel * mesh,
1034 const std::unordered_set<long> * targetCells, PiercedStorage<bool> & mappedField)
1039 std::unordered_set<long> targetCellsStorage;
1041 for (
const Cell &cell :
getMesh()->getCells())
1042 targetCellsStorage.insert(cell.getId());
1044 targetCells = &targetCellsStorage;
1050 mappedField.unsetKernel();
1051 mappedField.setStaticKernel(&
getMesh()->getCells());
1052 mappedField.fill(
false);
1054#if BITPIT_ENABLE_MPI
1058 for (
long id : *targetCells){
1059 if (mappingInfo[
id].type == mapping::Type::TYPE_RENUMBERING){
1060 bool dataB = field.at(mappingInfo[
id].ids[0]);
1061 mappedField.set(
id, dataB);
1063 else if (mappingInfo[
id].type == mapping::Type::TYPE_COARSENING){
1064 mappedField.set(
id,
false);
1065 bool dataB, dataMappedB =
true;
1066 for (
long idd : mappingInfo[id].ids){
1067 dataB = field.at(idd);
1068 dataMappedB &= dataB;
1070 mappedField.set(
id, dataMappedB);
1072 else if (mappingInfo[
id].type == mapping::Type::TYPE_REFINEMENT){
1073 bool dataB = field.at(mappingInfo[
id].ids[0]);
1074 mappedField.set(
id, dataB);
1078#if BITPIT_ENABLE_MPI
1084 std::map<int, std::map<long, bool> > dataBrec;
1086 communicateBoolField(field, dataBrec);
1088 for (
long id : *targetCells){
1090 if (mappingInfo[
id].type == mapping::Type::TYPE_RENUMBERING){
1092 int rank = mappingInfo[id].ranks[0];
1094 dataB = dataBrec[rank][mappingInfo[id].ids[0]];
1097 dataB = field.at(mappingInfo[
id].ids[0]);
1099 mappedField.set(
id, dataB);
1101 else if (mappingInfo[
id].type == mapping::Type::TYPE_COARSENING){
1102 mappedField.set(
id,
true);
1103 bool dataB, dataMappedB =
true;
1105 for (
long idd : mappingInfo[id].ids){
1106 int rank = mappingInfo[id].ranks[ii];
1108 dataB = dataBrec[rank][idd];
1111 dataB = field.at(idd);
1113 dataMappedB &= dataB;
1116 mappedField.set(
id, dataMappedB);
1119 else if (mappingInfo[
id].type == mapping::Type::TYPE_REFINEMENT){
1121 int rank = mappingInfo[id].ranks[0];
1123 dataB = dataBrec[rank][mappingInfo[id].ids[0]];
1126 dataB = field.at(mappingInfo[
id].ids[0]);
1128 mappedField.set(
id, dataB);
1143std::unordered_set<long> PODVolOctree::mapCellsToPOD(
const std::unordered_set<long> * targetCells)
1145 std::unordered_set<long> mappedCells;
1148#if BITPIT_ENABLE_MPI
1152 for (
const long &
id : *targetCells){
1153 if (inverseMapping[
id].type == mapping::Type::TYPE_RENUMBERING){
1154 mappedCells.insert(inverseMapping[
id].ids[0]);
1156 if (inverseMapping[
id].type == mapping::Type::TYPE_REFINEMENT){
1157 mappedCells.insert(inverseMapping[
id].ids[0]);
1159 if (inverseMapping[
id].type == mapping::Type::TYPE_COARSENING){
1160 for (
long idd : inverseMapping[id].ids)
1161 mappedCells.insert(idd);
1165#if BITPIT_ENABLE_MPI
1172 std::map<int, std::unordered_set<long> > sendPODcells;
1174 for (
const long &
id : *targetCells){
1175 if (inverseMapping[
id].type == mapping::Type::TYPE_RENUMBERING){
1176 int rank = inverseMapping[id].ranks[0];
1178 sendPODcells[rank].insert(inverseMapping[
id].ids[0]);
1181 mappedCells.insert(inverseMapping[
id].ids[0]);
1184 if (inverseMapping[
id].type == mapping::Type::TYPE_REFINEMENT){
1185 int rank = inverseMapping[id].ranks[0];
1187 sendPODcells[rank].insert(inverseMapping[
id].ids[0]);
1190 mappedCells.insert(inverseMapping[
id].ids[0]);
1193 if (inverseMapping[
id].type == mapping::Type::TYPE_COARSENING){
1195 for (
long idd : inverseMapping[id].ids){
1196 int rank = inverseMapping[id].ranks[ii];
1198 sendPODcells[rank].insert(idd);
1201 mappedCells.insert(idd);
1212 std::size_t bytes =
sizeof(long);
1213 for (
const auto &val : sendPODcells){
1214 std::size_t ncells = val.second.size();
1215 int rank = val.first;
1217 std::size_t buffSize = ncells * bytes;
1218 dataCommunicator.setSend(rank,buffSize);
1220 SendBuffer &sendBuffer = dataCommunicator.getSendBuffer(rank);
1221 for (
long ID : val.second){
1226 dataCommunicator.discoverRecvs();
1227 dataCommunicator.startAllRecvs();
1228 dataCommunicator.startAllSends();
1230 std::vector<int> recvRanks = dataCommunicator.getRecvRanks();
1231 std::sort(recvRanks.begin(),recvRanks.end());
1233 for (
int rank : recvRanks){
1234 dataCommunicator.waitRecv(rank);
1235 RecvBuffer & recvBuffer = dataCommunicator.getRecvBuffer(rank);
1236 long nof = recvBuffer.getSize() / bytes;
1237 for (
long ii = 0; ii < nof; ii++){
1240 mappedCells.insert(ID);
1244 dataCommunicator.waitAllSends();
1253void PODVolOctree::adaptMeshToMesh(
const VolumeKernel* meshToAdapt,
const VolumeKernel * meshReference)
1267 for (Cell & cell :
getMesh()->getCells()){
1268 long id = cell.getId();
1269 if (mappingInfo[
id].type == mapping::Type::TYPE_COARSENING){
1275#if BITPIT_ENABLE_MPI==1
1276 MPI_Allreduce(MPI_IN_PLACE, &adapt, 1, MPI_C_BOOL, MPI_LOR,
m_communicator);
1281 getMapper()->adaptionPrepare(infoAdapt);
1285 getMapper()->adaptionAlter(infoAdapt,
true,
false);
1295# if BITPIT_ENABLE_MPI
1297void PODVolOctree::communicatePODField(
const pod::PODField & field, std::map<
int, std::map<long, bool> > & dataBrec, std::map<
int, std::map<
long, std::vector<double> > > & dataSrec, std::map<
int, std::map<
long, std::vector<std::array<double,3> > > > & dataVrec, std::map<
int, std::map<long, double> > & volrec)
1302 std::size_t nsf = field.scalar->getFieldCount();
1303 std::size_t nvf = field.vector->getFieldCount();
1305 std::unordered_map<int, std::vector<long> > rankIDrec =
m_meshmap->getReceivedMappedIds();
1306 std::unordered_map<int, std::vector<long> > rankIDsend =
m_meshmap->getSentMappedIds();
1310 std::size_t bytes =
sizeof(bool) + (nsf+(3*nvf)+1)*
sizeof(
double);
1311 for (
const auto &val : rankIDsend){
1312 int rank = val.first;
1314 std::size_t buffSize = val.second.size() * bytes;
1315 dataCommunicator.setSend(rank,buffSize);
1317 SendBuffer &sendBuffer = dataCommunicator.getSendBuffer(rank);
1318 for (
long ID : val.second){
1319 bool mask = field.mask->at(ID);
1321 for (std::size_t i=0; i<nsf; i++)
1322 sendBuffer << field.scalar->at(ID,i);
1323 for (std::size_t i=0; i<nvf; i++){
1324 for (std::size_t j=0; j<3; j++){
1325 sendBuffer << field.vector->at(ID,i)[j];
1328 sendBuffer << field.mesh->evalCellVolume(ID);
1332 dataCommunicator.discoverRecvs();
1333 dataCommunicator.startAllRecvs();
1334 dataCommunicator.startAllSends();
1336 for (
const auto &val : rankIDrec){
1337 int rank = val.first;
1338 dataCommunicator.waitRecv(rank);
1339 RecvBuffer & recvBuffer = dataCommunicator.getRecvBuffer(rank);
1340 for (
long ID : val.second){
1341 recvBuffer >> dataBrec[rank][ID];
1342 for (std::size_t i=0; i<nsf; i++){
1345 dataSrec[rank][ID].push_back(data);
1347 for (std::size_t i=0; i<nvf; i++){
1348 std::array<double,3> data;
1349 recvBuffer >> data[0];
1350 recvBuffer >> data[1];
1351 recvBuffer >> data[2];
1352 dataVrec[rank][ID].push_back(data);
1354 recvBuffer >> volrec[rank][ID];
1357 dataCommunicator.waitAllSends();
1363void PODVolOctree::communicatePODFieldFromPOD(
const pod::PODField & field, std::map<
int, std::map<long, bool> > & dataBrec, std::map<
int, std::map<
long, std::vector<double> > > & dataSrec, std::map<
int, std::map<
long, std::vector<std::array<double,3> > > > & dataVrec, std::map<
int, std::map<long, double> > & volrec)
1368 std::size_t nsf = field.scalar->getFieldCount();
1369 std::size_t nvf = field.vector->getFieldCount();
1371 std::unordered_map<int, std::vector<long> > rankIDsend =
m_meshmap->getSentReferenceIds();
1375 std::size_t bytes =
sizeof(long) +
sizeof(
bool) + (nsf+3*nvf+1)*
sizeof(
double);
1376 for (
const auto &val : rankIDsend){
1377 int rank = val.first;
1379 std::size_t buffSize = val.second.size() * bytes;
1380 dataCommunicator.setSend(rank,buffSize);
1382 SendBuffer &sendBuffer = dataCommunicator.getSendBuffer(rank);
1383 for (
long ID : val.second){
1385 bool mask = field.mask->at(ID);
1387 for (std::size_t i=0; i<nsf; i++)
1388 sendBuffer << field.scalar->at(ID,i);
1389 for (std::size_t i=0; i<nvf; i++){
1390 for (std::size_t j=0; j<3; j++){
1391 sendBuffer << field.vector->at(ID,i)[j];
1394 sendBuffer << field.mesh->evalCellVolume(ID);
1398 dataCommunicator.discoverRecvs();
1399 dataCommunicator.startAllRecvs();
1400 dataCommunicator.startAllSends();
1402 std::vector<int> recvRanks = dataCommunicator.getRecvRanks();
1403 std::sort(recvRanks.begin(),recvRanks.end());
1405 for (
int rank : recvRanks){
1406 dataCommunicator.waitRecv(rank);
1407 RecvBuffer & recvBuffer = dataCommunicator.getRecvBuffer(rank);
1408 long nof = recvBuffer.getSize() / bytes;
1409 for (
long ii = 0; ii < nof; ii++){
1412 recvBuffer >> dataBrec[rank][ID];
1413 for (std::size_t i=0; i<nsf; i++){
1416 dataSrec[rank][ID].push_back(data);
1418 for (std::size_t i=0; i<nvf; i++){
1419 std::array<double,3> data;
1420 recvBuffer >> data[0];
1421 recvBuffer >> data[1];
1422 recvBuffer >> data[2];
1423 dataVrec[rank][ID].push_back(data);
1425 recvBuffer >> volrec[rank][ID];
1429 dataCommunicator.waitAllSends();
1435void PODVolOctree::communicateBoolField(
const PiercedStorage<bool> & field, std::map<
int, std::map<long, bool> > & dataBrec)
1438 std::unordered_map<int, std::vector<long> > rankIDrec =
m_meshmap->getReceivedMappedIds();
1439 std::unordered_map<int, std::vector<long> > rankIDsend =
m_meshmap->getSentMappedIds();
1443 std::size_t bytes =
sizeof(bool);
1444 for (
const auto &val : rankIDsend){
1445 int rank = val.first;
1447 std::size_t buffSize = val.second.size() * bytes;
1448 dataCommunicator.setSend(rank,buffSize);
1450 SendBuffer &sendBuffer = dataCommunicator.getSendBuffer(rank);
1451 for (
long ID : val.second){
1452 sendBuffer << field.at(ID);
1456 dataCommunicator.discoverRecvs();
1457 dataCommunicator.startAllRecvs();
1458 dataCommunicator.startAllSends();
1460 for (
const auto &val : rankIDrec){
1461 int rank = val.first;
1462 dataCommunicator.waitRecv(rank);
1463 RecvBuffer & recvBuffer = dataCommunicator.getRecvBuffer(rank);
1464 for (
long ID : val.second){
1465 recvBuffer >> dataBrec[rank][ID];
1469 dataCommunicator.waitAllSends();
1473void PODVolOctree::communicateField(
const PiercedStorage<double> & field,
const VolumeKernel * mesh, std::map<
int, std::map<
long, std::vector<double> > > & datarec, std::map<
int, std::map<long, double> > & volrec)
1476 std::size_t nf = field.getFieldCount();
1478 std::unordered_map<int, std::vector<long> > rankIDrec =
m_meshmap->getReceivedMappedIds();
1479 std::unordered_map<int, std::vector<long> > rankIDsend =
m_meshmap->getSentMappedIds();
1483 std::size_t bytes = (nf+1)*
sizeof(
double);
1484 for (
const auto &val : rankIDsend){
1485 int rank = val.first;
1487 std::size_t buffSize = val.second.size() * bytes;
1488 dataCommunicator.setSend(rank,buffSize);
1490 SendBuffer &sendBuffer = dataCommunicator.getSendBuffer(rank);
1491 for (
long ID : val.second){
1492 for (std::size_t ifield=0; ifield<nf; ifield++)
1493 sendBuffer << field.at(ID, ifield);
1494 sendBuffer << mesh->evalCellVolume(ID);
1498 dataCommunicator.discoverRecvs();
1499 dataCommunicator.startAllRecvs();
1500 dataCommunicator.startAllSends();
1502 for (
const auto &val : rankIDrec){
1503 int rank = val.first;
1504 dataCommunicator.waitRecv(rank);
1505 RecvBuffer & recvBuffer = dataCommunicator.getRecvBuffer(rank);
1506 for (
long ID : val.second){
1507 datarec[rank][ID].resize(nf);
1508 for (std::size_t ifield=0; ifield<nf; ifield++)
1509 recvBuffer >> datarec[rank][ID][ifield];
1510 recvBuffer >> volrec[rank][ID];
1514 dataCommunicator.waitAllSends();
1518void PODVolOctree::communicateFieldFromPOD(
const PiercedStorage<double> & field,
const VolumeKernel * mesh, std::map<
int, std::map<
long, std::vector<double> > > & datarec, std::map<
int, std::map<long, double> > & volrec)
1521 std::size_t nf = field.getFieldCount();
1523 std::unordered_map<int, std::vector<long> > rankIDsend =
m_meshmap->getSentReferenceIds();
1527 std::size_t bytes = (nf+1)*
sizeof(
double)+
sizeof(long);
1528 for (
const auto &val : rankIDsend){
1529 int rank = val.first;
1531 std::size_t buffSize = val.second.size() * bytes;
1532 dataCommunicator.setSend(rank,buffSize);
1534 SendBuffer &sendBuffer = dataCommunicator.getSendBuffer(rank);
1535 for (
long ID : val.second){
1537 for (std::size_t ifield=0; ifield<nf; ifield++)
1538 sendBuffer << field.at(ID, ifield);
1539 sendBuffer << mesh->evalCellVolume(ID);
1543 dataCommunicator.discoverRecvs();
1544 dataCommunicator.startAllRecvs();
1545 dataCommunicator.startAllSends();
1547 std::vector<int> recvRanks = dataCommunicator.getRecvRanks();
1548 std::sort(recvRanks.begin(),recvRanks.end());
1550 for (
int rank : recvRanks){
1551 dataCommunicator.waitRecv(rank);
1552 RecvBuffer & recvBuffer = dataCommunicator.getRecvBuffer(rank);
1553 long nof = recvBuffer.getSize() / bytes;
1554 for (
long ii = 0; ii < nof; ii++){
1557 datarec[rank][ID].resize(nf);
1558 for (std::size_t ifield=0; ifield<nf; ifield++)
1559 recvBuffer >> datarec[rank][ID][ifield];
1560 recvBuffer >> volrec[rank][ID];
1564 dataCommunicator.waitAllSends();
The PODKernel class provides an interface to manage the mesh dependent members and functions of a POD...
std::unique_ptr< VolumeMapper > m_meshmap
void computeMapper(const VolumeKernel *mesh, bool fillInv=true)
VolumeMapper * getMapper()
double getCellVolume(long id)
double getRawCellVolume(long rawIndex)
std::unique_ptr< VolumeKernel > m_meshPOD
MPI_Comm getCommunicator() const
The PODVolOctree is the specialized class of PODKernel for VolOctree meshes.
PODVolOctree(MPI_Comm comm=MPI_COMM_WORLD)
void markCellForRefinement(long id)
std::vector< adaption::Info > adaptionPrepare(bool trackAdaption=true)
std::vector< adaption::Info > adaptionAlter(bool trackAdaption=true, bool squeezeStorage=false)
The VolOctree defines a Octree patch.
const bitpit::PiercedStorage< mapping::Info > & getInverseMapping() const
const bitpit::PiercedStorage< mapping::Info > & getMapping() const
#define BITPIT_UNUSED(variable)