Changeset 6369bc for src/Fragmentation/Summation/SetValues/SamplingGrid.cpp
- Timestamp:
- Jun 8, 2016, 10:45:28 PM (9 years ago)
- Children:
- 6c0b3f
- Parents:
- c739b3
- git-author:
- Frederik Heber <heber@…> (06/08/16 13:22:11)
- git-committer:
- Frederik Heber <heber@…> (06/08/16 22:45:28)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Fragmentation/Summation/SetValues/SamplingGrid.cpp
rc739b3 r6369bc 43 43 #include "Fragmentation/Summation/SetValues/SamplingGrid.hpp" 44 44 45 #include <boost/assign.hpp> 45 46 #include <boost/bind.hpp> 46 47 #include <algorithm> … … 610 611 "SamplingGrid::addWindowOntoWindow() - destiter is already at end of window."); 611 612 ASSERT( sourceiter != source_sampled_grid.end(), 612 "SamplingGrid::addWindowOntoWindow() - destiter is already at end of window.");613 "SamplingGrid::addWindowOntoWindow() - sourceiter is already at end of window."); 613 614 op(*destiter, *sourceiter); 614 615 ++destiter; … … 658 659 } 659 660 661 /** Struct contains a single point with displacements from the 662 * central point and the weight in the restriction. 663 */ 664 struct PointWeight_t { 665 PointWeight_t(const int &d1, const int &d2, const int &d3, const double &_weight) : 666 displacement(NDIM), 667 weight(_weight) 668 { 669 displacement[0] = d1; displacement[1] = d2; displacement[2] = d3; 670 } 671 typedef std::vector<int> displacement_t; 672 displacement_t displacement; 673 double weight; 674 }; 675 676 static void getLengthsOfGrid( 677 int _total[NDIM], 678 const SamplingGrid &_grid) 679 { 680 const size_t gridpoints_axis = _grid.getGridPointsPerAxis(); 681 static const double round_offset = 682 (std::numeric_limits<size_t>::round_style == std::round_toward_zero) ? 683 0.5 : 0.; // need offset to get to round_toward_nearest behavior 684 for (size_t index=0; index<NDIM; ++index) { 685 if (fabs(_grid.end[index] - _grid.begin[index]) > std::numeric_limits<double>::epsilon()*1e4) { 686 const double delta = (double)gridpoints_axis/(_grid.end[index] - _grid.begin[index]); 687 _total[index] = delta*(_grid.end_window[index] - _grid.begin_window[index])+round_offset; 688 } else 689 _total[index] = 0; 690 ASSERT (_total[index] == ::pow(2, _grid.level), 691 "SamplingGrid::downsample() - total "+toString(_total[index]) 692 +" does not match 2^level: "+toString(_grid.level)); 693 } 694 } 695 696 //!> stencil for full weight restriction, see vmg's stencils.hpp 697 static const std::vector< PointWeight_t > FullWeightNearestNeighbor = 698 boost::assign::list_of 699 ( PointWeight_t( 0, 0, 0, 0.125) ) 700 ( PointWeight_t( 1, 0, 0, 0.0625) ) 701 ( PointWeight_t(-1, 0, 0, 0.0625) ) 702 ( PointWeight_t( 0, 1, 0, 0.0625) ) 703 ( PointWeight_t( 0, -1, 0, 0.0625) ) 704 ( PointWeight_t( 0, 0, 1, 0.0625) ) 705 ( PointWeight_t( 0, 0, -1, 0.0625) ) 706 ( PointWeight_t( 1, 1, 0, 0.03125) ) 707 ( PointWeight_t( 1, -1, 0, 0.03125) ) 708 ( PointWeight_t(-1, 1, 0, 0.03125) ) 709 ( PointWeight_t(-1, -1, 0, 0.03125) ) 710 ( PointWeight_t( 0, 1, 1, 0.03125) ) 711 ( PointWeight_t( 0, 1, -1, 0.03125) ) 712 ( PointWeight_t( 0, -1, 1, 0.03125) ) 713 ( PointWeight_t( 0, -1, -1, 0.03125) ) 714 ( PointWeight_t( 1, 0, 1, 0.03125) ) 715 ( PointWeight_t( 1, 0, -1, 0.03125) ) 716 ( PointWeight_t(-1, 0, 1, 0.03125) ) 717 ( PointWeight_t(-1, 0, -1, 0.03125) ) 718 ( PointWeight_t( 1, 1, 1, 0.015625) ) 719 ( PointWeight_t( 1, 1, -1, 0.015625) ) 720 ( PointWeight_t( 1, -1, 1, 0.015625) ) 721 ( PointWeight_t(-1, 1, 1, 0.015625) ) 722 ( PointWeight_t( 1, -1, -1, 0.015625) ) 723 ( PointWeight_t(-1, 1, -1, 0.015625) ) 724 ( PointWeight_t(-1, -1, 1, 0.015625) ) 725 ( PointWeight_t(-1, -1, -1, 0.015625) ) 726 ; 727 728 int getValidIndex( 729 const PointWeight_t::displacement_t &_disp, 730 const int N[NDIM], 731 const int length[NDIM]) 732 { 733 int index = 0; 734 // we simply truncate in case of out of bounds access 735 if ((N[2]+_disp[2] >= 0) && (N[2]+_disp[2] < length[2])) 736 index += _disp[2]; 737 if ((N[1]+_disp[1] >= 0) && (N[1]+_disp[1] < length[1])) 738 index += _disp[1]*length[2]; 739 if ((N[0]+_disp[0] >= 0) && (N[0]+_disp[0] < length[0])) 740 index += _disp[0]*length[1]*length[2]; 741 return index; 742 } 743 744 void restrictFullWeight( 745 SamplingGrid::sampledvalues_t &_coarse_level, 746 const int length_c[NDIM], 747 const SamplingGrid::sampledvalues_t &_fine_level, 748 const int length_f[NDIM]) 749 { 750 int N_c[NDIM]; 751 int N_f[NDIM]; 752 SamplingGrid::sampledvalues_t::iterator coarseiter = _coarse_level.begin(); 753 for(N_c[0]=0, N_f[0]=0; (N_c[0] < length_c[0]) && (N_f[0] < length_f[0]); ++N_c[0], N_f[0] +=2) { 754 for(N_c[1]=0, N_f[1]=0; (N_c[1] < length_c[1]) && (N_f[1] < length_f[1]); ++N_c[1], N_f[1] +=2) { 755 for(N_c[2]=0, N_f[2]=0; (N_c[2] < length_c[2]) && (N_f[2] < length_f[2]); ++N_c[2], N_f[2] +=2) { 756 const int index_base = N_f[2] + (N_f[1] + N_f[0]*length_f[1])*length_f[2]; 757 // go through stencil and add each point relative to displacement with weight 758 for (std::vector< PointWeight_t >::const_iterator weightiter = FullWeightNearestNeighbor.begin(); 759 weightiter != FullWeightNearestNeighbor.end(); ++weightiter) { 760 const PointWeight_t::displacement_t disp = weightiter->displacement; 761 const int index_disp = getValidIndex(disp, N_f, length_f); 762 *coarseiter += _fine_level[index_base+index_disp]*weightiter->weight; 763 } 764 ++coarseiter; 765 } 766 ASSERT ( (N_c[2] == length_c[2]) && (N_f[2] == length_f[2]), 767 "restrictFullWeight() - N_c "+toString(N_c[2])+" != length_c "+toString(length_c[2]) 768 +" or N_f "+toString(N_f[2])+" != length_f "+toString(length_f[2])); 769 } 770 ASSERT ( (N_c[1] == length_c[1]) && (N_f[1] == length_f[1]), 771 "restrictFullWeight() - N_c "+toString(N_c[1])+" != length_c "+toString(length_c[1]) 772 +" or N_f "+toString(N_f[1])+" != length_f "+toString(length_f[1])); 773 } 774 ASSERT ( (N_c[0] == length_c[0]) && (N_f[0] == length_f[0]), 775 "restrictFullWeight() - N_c "+toString(N_c[0])+" != length_c "+toString(length_c[0]) 776 +" or N_f "+toString(N_f[0])+" != length_f "+toString(length_f[0])); 777 ASSERT( coarseiter == _coarse_level.end(), 778 "restrictFullWeight() - coarseiter is not at end of values."); 779 } 780 781 void SamplingGrid::downsample( 782 SamplingGrid& instance, 783 const SamplingGrid& other, 784 const int _level) 785 { 786 if (&instance != &other) { 787 // take over properties 788 static_cast<SamplingGridProperties &>(instance) = other; 789 instance.setWindowSize(other.begin_window, other.end_window); 790 if (_level >= other.level) { 791 instance.sampled_grid = other.sampled_grid; 792 } else { 793 // if desired level is smaller we need to downsample 794 // we do this similarly to vmg::RestrictionFullWeight (i.e. a full nearest 795 // neighbor interpolation) and always one grid level at a time till we 796 // have reached the desired one 797 798 // the reference such that we never have to copy the full grid but only 799 // downsampled ones 800 const sampledvalues_t * sourcevalues = &other.sampled_grid; 801 int length_d[3]; 802 int length_s[3]; 803 getLengthsOfGrid(length_s, other); 804 for (instance.level = other.level-1; instance.level >= _level; --instance.level) { 805 getLengthsOfGrid(length_d, instance); 806 // we always have an eighth of the number of sample points as we stop 807 sampledvalues_t downsampled(sourcevalues->size()/(size_t)8, 0.); 808 restrictFullWeight(downsampled, length_d, *sourcevalues, length_s); 809 // then copy the downsampled values 810 instance.sampled_grid = downsampled; 811 sourcevalues = &instance.sampled_grid; 812 // and exchange lengths 813 for (size_t i=0;i<3;++i) { 814 length_s[i] = length_d[i]; 815 } 816 } 817 instance.level = _level; 818 819 // and finally, renormalize downsampled grid to old value 820 // instance *= other.integral()/instance.integral(); 821 } 822 } 823 } 824 660 825 std::ostream & operator<<(std::ostream &ost, const SamplingGrid& other) 661 826 {
Note:
See TracChangeset
for help on using the changeset viewer.
