Changeset 160ad7 for src/Fragmentation
- Timestamp:
- Sep 14, 2016, 6:42:53 PM (8 years ago)
- Branches:
- Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_StructOpt_integration_tests, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, GeometryObjects, Gui_displays_atomic_force_velocity, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, RotateToPrincipalAxisSystem_UndoRedo, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, Ubuntu_1604_changes, stable
- Children:
- ec1aae
- Parents:
- b839fb
- git-author:
- Frederik Heber <heber@…> (03/10/16 15:34:11)
- git-committer:
- Frederik Heber <heber@…> (09/14/16 18:42:53)
- Location:
- src/Fragmentation/Exporters
- Files:
-
- 2 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Fragmentation/Exporters/ExportGraph_ToJobs.cpp
rb839fb r160ad7 42 42 43 43 #include <algorithm> 44 #include <cmath> 45 #include <limits> 46 47 #include "CodePatterns/Log.hpp" 44 48 45 49 #include "Box.hpp" … … 56 60 #include "World.hpp" 57 61 62 const double ExportGraph_ToJobs::log_two(log(2.)); 63 58 64 ExportGraph_ToJobs::ExportGraph_ToJobs( 59 65 const Graph &_graph, … … 62 68 const SaturatedFragment::GlobalSaturationPositions_t &_globalsaturationpositions) : 63 69 ExportGraph(_graph, _treatment, _saturation,_globalsaturationpositions), 64 level(5) 70 level(5), 71 max_meshwidth(0.), 72 minimum_empty_boundary(5./AtomicLengthToAngstroem) 65 73 {} 66 74 … … 80 88 } 81 89 90 SamplingGridProperties ExportGraph_ToJobs::getGridExtentsForGivenBoundingBox( 91 const std::pair<Vector, Vector> &_minmax, 92 const SamplingGridProperties &_domain, 93 const double & _minimum_empty_boundary 94 ) 95 { 96 // return value 97 SamplingGridProperties fragment_window; 98 99 /// determine center of fragment 100 const Vector center = .5*(_minmax.first + _minmax.second); 101 LOG(4, "DEBUG: center of fragment is at " << center); 102 103 /// associate center to its containing grid cell (defined by boundary points) 104 Vector lower_center; 105 Vector higher_center; 106 bool equal_components[NDIM] = { false, false, false }; 107 for (size_t i=0;i<NDIM;++i) { 108 lower_center[i] = _domain.getNearestLowerGridPoint(center[i], i); 109 higher_center[i] = _domain.getNearestHigherGridPoint(center[i], i); 110 equal_components[i] = 111 fabs(lower_center[i] - higher_center[i]) < std::numeric_limits<double>::epsilon()*1e4; 112 } 113 LOG(5, "DEBUG: lower_center is " << lower_center << ", higher_center is " << higher_center); 114 115 // fashion min max into cubic box extents of at least extent plus empty 116 // boundary and at most three times the extent 117 const Vector extent = _minmax.second - _minmax.first; 118 double greatest_extent = extent[extent.GreatestComponent()]; 119 if (greatest_extent > _minimum_empty_boundary) 120 greatest_extent *= 3.; 121 else 122 greatest_extent += 2.* _minimum_empty_boundary; 123 const Vector total( 124 _domain.getTotalLengthPerAxis(0), 125 _domain.getTotalLengthPerAxis(1), 126 _domain.getTotalLengthPerAxis(2) 127 ); 128 const double greatest_total = total[total.GreatestComponent()]; 129 greatest_extent = std::min(greatest_extent, greatest_total); 130 LOG(5, "DEBUG: extent of fragment is " << extent << ", greatest_extent is " << greatest_extent); 131 132 /// increase levels around this center to find the matching window 133 const double delta[NDIM] = { 134 _domain.getDeltaPerAxis(0), 135 _domain.getDeltaPerAxis(1), 136 _domain.getDeltaPerAxis(2) 137 }; 138 LOG(6, "DEBUG: delta is " << Vector(delta)); 139 const double greatest_delta = std::max(delta[0], std::max(delta[1], delta[2])); 140 141 fragment_window.level = (int)ceil(log(greatest_extent/greatest_delta+1)/log_two); 142 const size_t half_fragment_gridpoints = 1 << (fragment_window.level-1); 143 const size_t domain_gridpoints = _domain.getGridPointsPerAxis(); 144 int begin_index[NDIM]; 145 int end_index[NDIM]; 146 int begin_steps[NDIM] = { 0, 0, 0 }; 147 int end_steps[NDIM] = { 0, 0, 0 }; 148 for (size_t i=0;i<NDIM;++i) { 149 begin_index[i] = round(lower_center[i]/delta[i]) - (half_fragment_gridpoints-1); 150 end_index[i] = round(higher_center[i]/delta[i]) + (half_fragment_gridpoints+(unsigned int)(equal_components[i])); 151 if (begin_index[i] < 0) 152 begin_steps[i] = -begin_index[i]; 153 if (end_index[i] > (int)domain_gridpoints) 154 end_steps[i] = end_index[i] - domain_gridpoints; 155 if ((begin_steps[i]+end_steps[i]+end_index[i]-begin_index[i] > (int)domain_gridpoints) 156 || ((begin_steps[i] != 0) && (end_steps[i] != 0))) { 157 begin_index[i] = 0; 158 end_index[i] = domain_gridpoints; 159 begin_steps[i] = 0; 160 end_steps[i] = 0; 161 } 162 } 163 for (size_t i=0;i<NDIM;++i) { 164 fragment_window.begin[i] = (begin_index[i]+begin_steps[i]-end_steps[i]) * delta[i]; 165 fragment_window.end[i] = (end_index[i]-end_steps[i]+begin_steps[i]) * delta[i]; 166 } 167 LOG(6, "DEBUG: fragment begin is " << Vector(fragment_window.begin) 168 << ", fragment end is " << Vector(fragment_window.end)); 169 170 /// check whether window is large enough, if not yet continue 171 #ifndef NDEBUG 172 for (size_t i=0;i<NDIM;++i) { 173 const double window_length = fragment_window.end[i] - fragment_window.begin[i]; 174 ASSERT (((greatest_total != greatest_extent) && (greatest_extent+delta[i] <= window_length)) 175 || ((greatest_total == greatest_extent) && (greatest_extent <= window_length)), 176 "ExportGraph_ToJobs::getGridExtentsForGivenBoundingBox() - level " 177 +toString(fragment_window.level)+" is insufficient to place fragment inside box " 178 +toString(_minmax.first)+" <-> "+toString(_minmax.second)); 179 } 180 #endif 181 #ifndef NDEBUG 182 for (size_t i=0;i<NDIM;++i) { 183 ASSERT( fragment_window.begin[i] >= _domain.begin[i], 184 "ExportGraph_ToJobs::getGridExtentsForGivenBoundingBox() - fragment begin " 185 +toString(fragment_window.begin[i])+" is smaller than that of domain " 186 +toString(_domain.begin[i])); 187 ASSERT( fragment_window.end[i] <= _domain.end[i], 188 "ExportGraph_ToJobs::getGridExtentsForGivenBoundingBox() - fragment end " 189 +toString(fragment_window.end[i])+" is smaller than that of domain " 190 +toString(_domain.end[i])); 191 } 192 #endif 193 if (DoLog(6)) 194 for (size_t i=0;i<NDIM;++i) 195 LOG(6, "DEBUG: We have " << (fragment_window.end[i] - fragment_window.begin[i])/delta[i] 196 << " gridpoints on axis " << i); 197 198 return fragment_window; 199 } 200 201 void ExportGraph_ToJobs::setAcceptableFragmentLevel( 202 SamplingGridProperties &_grid, 203 const double &_max_meshwidth 204 ) 205 { 206 double max_domain_meshwidth = _max_meshwidth; 207 for (size_t i=0;i<NDIM;++i) 208 max_domain_meshwidth = std::max(max_domain_meshwidth, _grid.getDeltaPerAxis(i)); 209 // find power of 2 that's just greater than that ratio of given over desired mesh width 210 const int desired_level = ceil(log(max_domain_meshwidth / _max_meshwidth)/log_two); 211 // we may never make level smaller (needs to be as large as domain's) 212 ASSERT( desired_level >= 0, 213 "ExportGraph_ToJobs::setAcceptableFragmentLevel() - should never get negative extra level."); 214 if (desired_level > 0) 215 _grid.level += desired_level; 216 LOG(4, "DEBUG: Fragment requires " << desired_level 217 << " additional grid levels to reach at least " << _max_meshwidth 218 << " from " << max_domain_meshwidth); 219 } 220 82 221 bool ExportGraph_ToJobs::operator()() 83 222 { … … 99 238 const KeySet &set = CurrentFragment->getKeySet(); 100 239 LOG(2, "INFO: Creating bond fragment job for set " << set << "."); 240 241 SamplingGridProperties fragment_window(grid); 242 if (max_meshwidth != 0.) { 243 // gather extent of the fragment in atomic length(!) 244 std::pair<Vector, Vector> minmax = CurrentFragment->getRoughBoundingBox(); 245 minmax.first *= 1./AtomicLengthToAngstroem; 246 minmax.second *= 1./AtomicLengthToAngstroem; 247 248 /** we need to find the begin and end points of the smaller grid 249 * otherwise we would calculate the whole domain with an incrased grid level with just 250 * a small window (which is only used for sampling and storing; vmg uses full grid). 251 * Hence, we need to make the grid smaller and such that it is still in a power of two 252 * and coinciding with the grid points of the global grid. 253 */ 254 fragment_window = getGridExtentsForGivenBoundingBox(minmax, grid, minimum_empty_boundary); 255 LOG(4, "DEBUG: Fragment " << CurrentFragment->getKeySet() << " has window from " 256 << Vector(fragment_window.begin) << " to " << Vector(fragment_window.end) 257 << " with total level portion of " << fragment_window.level ); 258 259 // next we need to check how much we need to increase from the grid level for 260 // the total domain to achieve at least maximum mesh width 261 setAcceptableFragmentLevel(fragment_window, max_meshwidth/AtomicLengthToAngstroem); 262 } 263 101 264 // store config in stream 102 265 { … … 107 270 FragmentJob::ptr testJob( 108 271 #ifdef HAVE_JOBMARKET 109 new MPQCJob(JobId::IllegalJob, output.str(), grid.begin, grid.end, level) 272 new MPQCJob( 273 JobId::IllegalJob, 274 output.str(), 275 fragment_window.begin, fragment_window.end, fragment_window.level) 110 276 #else 111 277 new MPQCCommandJob(output.str(), JobId::IllegalJob) -
src/Fragmentation/Exporters/ExportGraph_ToJobs.hpp
rb839fb r160ad7 20 20 #include "Fragmentation/Exporters/ExportGraph.hpp" 21 21 #include "Fragmentation/Summation/SetValues/SamplingGridProperties.hpp" 22 #include "LinearAlgebra/Vector.hpp" 23 24 class ExportGraph_ToJobsTest; 22 25 23 26 /** ExportGraph_ToJobs implements an ExportGraph by sending the created … … 27 30 class ExportGraph_ToJobs : public ExportGraph 28 31 { 32 //!> grant unit test access 33 friend class ExportGraph_ToJobsTest; 29 34 public: 30 35 /** Constructor for ExportGraph_ToJobs. … … 47 52 bool operator()(); 48 53 49 /** Sets the level for the sampling of the density. 54 /** Sets the level for the sampling of the density. 55 * 56 * \param _level level to set 57 */ 58 void setLevel(const size_t _level) { level = _level; } 59 60 /** Sets how far apart discrete points may be at most per axis. 50 61 * 51 * \param _ level level to set62 * \param _max_meshwidth maximum allowed mesh width. 52 63 */ 53 void set Level(const size_t _level) { level = _level; }64 void setMaximumMeshWidth(const double _max_meshwidth) { max_meshwidth = _max_meshwidth; } 54 65 55 66 /** Helper to get the global domain grid from the current simulation box. … … 63 74 64 75 private: 76 77 /** Helper function to get the discrete extent of the grid that 78 * captures the whole of the fragment inside \a _minmax, and some 79 * additional boundary \a _minimum_empty_boundary for a given 80 * domain \a _domain with some grid level. If the fragment is larger than 81 * the empty boundary, we make the small fragment grid at most three times 82 * the extent of the fragment. 83 * 84 * We need to maintain the following properties: 85 * -# the fragment grid's begin and end need to reside (exactly) on grid points 86 * of the global \a _domain 87 * -# the length of the fragment grid in \a _domain's deltas needs to be a 88 * power of 2. 89 * 90 * In order to achieve these, we use the center of the fragment obtained from 91 * its extensions in \a _minmax and convert it to the next lower and upper grid 92 * points on \a _domain. For increasing powers of 2 we check the extent of the 93 * gridpoints by going half of the gridpoints back and forth relative to these 94 * center grid points. If their length relative to \a _domain's delta is 95 * sufficient to capture the desired extent of fragment, namely \a _minmax 96 * including \a _minimum_empty_boundary, we are done. We need to do this 97 * iteratively, as the fragment grid may exceed \a _domain's begin or end 98 * and shifting is required. 99 * 100 * \param _minmax minimum and maximum components of fragment's bounding box 101 * \param _domain grid with begin and end components and grid level 102 * \param _minimum_empty_boundary additional empty boundary around fragment 103 * \return grid with begin and end points and and grid level to have same spacing as domain 104 */ 105 static SamplingGridProperties getGridExtentsForGivenBoundingBox( 106 const std::pair<Vector, Vector> &_minmax, 107 const SamplingGridProperties &_domain, 108 const double & _minimum_empty_boundary); 109 110 /** Helper function to calculate the required grid level for a fragment \a _grid 111 * such that is discretization mesh width is below the acceptable \a _max_meshwidth. 112 * 113 * \param _grid grid properties of the fragment, sets its level on return 114 * \param _max_meshwidth uppermost acceptable mesh width 115 */ 116 static void setAcceptableFragmentLevel( 117 SamplingGridProperties &_grid, 118 const double &_max_meshwidth); 119 120 //>! log of two 121 static const double log_two; 122 123 private: 65 124 //!> resolution of sampled electron density as \f$2^{\mathrm{level}}\f$ 66 125 size_t level; 126 //!> maximum allowed mesh width, i.e. discrete points may be at most that far part per axis 127 double max_meshwidth; 128 //!> desired minimum empty boundary around the fragment 129 const double minimum_empty_boundary; 67 130 }; 68 131 -
src/Fragmentation/Exporters/unittests/Makefile.am
rb839fb r160ad7 3 3 4 4 FRAGMENTATIONEXPORTERSSOURCES = \ 5 ../Fragmentation/Exporters/unittests/ExportGraph_ToJobsUnitTest.cpp \ 5 6 ../Fragmentation/Exporters/unittests/HydrogenPoolUnitTest.cpp \ 6 7 ../Fragmentation/Exporters/unittests/SaturatedFragmentUnitTest.cpp \ … … 9 10 10 11 FRAGMENTATIONEXPORTERSTESTSHEADERS = \ 12 ../Fragmentation/Exporters/unittests/ExportGraph_ToJobsUnitTest.hpp \ 11 13 ../Fragmentation/Exporters/unittests/HydrogenPoolUnitTest.hpp \ 12 14 ../Fragmentation/Exporters/unittests/SaturatedFragmentUnitTest.hpp \ … … 16 18 17 19 FRAGMENTATIONEXPORTERSTESTS = \ 20 ExportGraph_ToJobsUnitTest \ 18 21 HydrogenPoolUnitTest \ 19 22 SaturatedFragmentUnitTest \ … … 31 34 ${CodePatterns_LIBS} \ 32 35 $(BOOST_LIB) 36 37 ExportGraph_ToJobsUnitTest_SOURCES = \ 38 ../Fragmentation/Exporters/unittests/ExportGraph_ToJobsUnitTest.cpp \ 39 ../Fragmentation/Exporters/unittests/ExportGraph_ToJobsUnitTest.hpp 40 ExportGraph_ToJobsUnitTest_LDADD = \ 41 ../libMolecuilderUI.la \ 42 ../libMolecuilderFragmentationSetValues.la \ 43 ${ALLLIBS} 33 44 34 45 HydrogenPoolUnitTest_SOURCES = \
Note:
See TracChangeset
for help on using the changeset viewer.