source: src/Box.cpp@ 16648f

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing 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_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since 16648f was 16648f, checked in by Tillmann Crueger <crueger@…>, 15 years ago

Made the Box::explode() method handle boundary conditions

  • Property mode set to 100644
File size: 5.7 KB
RevLine 
[83c09a]1/*
2 * Box.cpp
3 *
4 * Created on: Jun 30, 2010
5 * Author: crueger
6 */
7
[527de2]8//#include "Helpers/MemDebug.hpp"
[6e00dd]9
[83c09a]10#include "Box.hpp"
11
[f429d7]12#include <cmath>
[16648f]13#include <iostream>
[f429d7]14
[83c09a]15#include "Matrix.hpp"
[3dcb1f]16#include "vector.hpp"
[29ac78]17#include "Plane.hpp"
[83c09a]18
[6e00dd]19#include "Helpers/Assert.hpp"
20
[16648f]21using namespace std;
22
[83c09a]23Box::Box()
24{
25 M= new Matrix();
26 M->one();
27 Minv = new Matrix();
28 Minv->one();
[77374e]29 conditions.resize(3);
30 conditions[0] = conditions[1] = conditions[2] = Wrap;
[83c09a]31}
32
[7579a4b]33Box::Box(const Box& src){
34 M=new Matrix(*src.M);
35 Minv = new Matrix(*src.Minv);
[77374e]36 conditions = src.conditions;
[7579a4b]37}
38
[83c09a]39Box::~Box()
40{
41 delete M;
42 delete Minv;
43}
44
[7579a4b]45const Matrix &Box::getM() const{
[83c09a]46 return *M;
47}
[7579a4b]48const Matrix &Box::getMinv() const{
[83c09a]49 return *Minv;
50}
51
52void Box::setM(Matrix _M){
[3bf9e2]53 ASSERT(_M.determinant()!=0,"Matrix in Box construction was not invertible");
[83c09a]54 *M =_M;
55 *Minv = M->invert();
56}
[7579a4b]57
[014475]58Vector Box::translateIn(const Vector &point) const{
[3dcb1f]59 return (*M) * point;
60}
61
[014475]62Vector Box::translateOut(const Vector &point) const{
[3dcb1f]63 return (*Minv) * point;
64}
65
[014475]66Vector Box::WrapPeriodically(const Vector &point) const{
[f429d7]67 Vector helper = translateOut(point);
68 for(int i=NDIM;i--;){
[c72562]69
70 switch(conditions[i]){
71 case Wrap:
72 helper.at(i)=fmod(helper.at(i),1);
73 helper.at(i)+=(helper.at(i)>0)?0:1;
74 break;
75 case Bounce:
76 {
77 // there probably is a better way to handle this...
78 // all the fabs and fmod modf probably makes it very slow
79 double intpart,fracpart;
80 fracpart = modf(fabs(helper.at(i)),&intpart);
81 helper.at(i) = fabs(fracpart-fmod(intpart,2));
82 }
83 break;
84 case Ignore:
85 break;
86 default:
87 ASSERT(0,"No default case for this");
88 }
89
[f429d7]90 }
91 return translateIn(helper);
92}
93
[0ff6b5]94bool Box::isInside(const Vector &point) const
95{
96 bool result = true;
[29ac78]97 Vector tester = translateOut(point);
[0ff6b5]98
99 for(int i=0;i<NDIM;i++)
[f3be87]100 result = result &&
101 ((conditions[i] == Ignore) ||
102 ((tester[i] >= -MYEPSILON) &&
103 ((tester[i] - 1.) < MYEPSILON)));
[0ff6b5]104
105 return result;
106}
107
108
[a630fd]109VECTORSET(std::list) Box::explode(const Vector &point,int n) const{
[16648f]110 ASSERT(isInside(point),"Exploded point not inside Box");
[12cf773]111 VECTORSET(std::list) res;
[89e820]112
[16648f]113 Vector translater = translateOut(point);
114 Vector mask; // contains the ignored coordinates
115
116 // count the number of coordinates we need to do
117 int dims = 0; // number of dimensions that are not ignored
118 vector<int> coords;
119 vector<int> index;
120 for(int i=0;i<NDIM;++i){
121 if(conditions[i]==Ignore){
122 mask[i]=translater[i];
123 continue;
124 }
125 coords.push_back(i);
126 index.push_back(-n);
127 dims++;
128 } // there are max vectors in total we need to create
129
130 if(!dims){
131 // all boundaries are ignored
132 res.push_back(point);
133 return res;
[89e820]134 }
[7ac4af]135
[16648f]136 int pos = 0;
137 while(pos<dims){
138 // create this vector
139 Vector helper;
140 for(int i=0;i<dims;++i){
141 switch(conditions[coords[i]]){
142 case Wrap:
143 helper[coords[i]] = index[i]+translater[coords[i]];
144 break;
145 case Bounce:
146 {
147 // Bouncing the coordinate x produces the series:
148 // 0 -> x
149 // 1 -> 2-x
150 // 2 -> 2+x
151 // 3 -> 4-x
152 // 4 -> 4+x
153 // the first number is the next bigger even number (n+n%2)
154 // the next number is the value with alternating sign (x-2*(n%2)*x)
155 // the negative numbers produce the same sequence reversed and shifted
156 int n = abs(index[i]) + (index[i]<0)?-1:0;
157 int sign = (index[i]<0)?-1:+1;
158 int even = n%2;
159 helper[coords[i]]=n+even+translater[coords[i]]-2*even*translater[coords[i]];
160 helper[coords[i]]*=sign;
161 }
162 break;
163 case Ignore:
164 ASSERT(0,"Ignored coordinate handled in generation loop");
165 default:
166 ASSERT(0,"No default case for this switch-case");
[7ac4af]167 }
[16648f]168
169 }
170 // add back all ignored coordinates (not handled in above loop)
171 helper+=mask;
172 res.push_back(translateIn(helper));
173 // set the new indexes
174 pos=0;
175 ++index[pos];
176 while(index[pos]>n && pos < dims){
177 index[pos++]=-n;
178 ++index[pos];
[7ac4af]179 }
180 }
181 return res;
182}
183
[16648f]184VECTORSET(std::list) Box::explode(const Vector &point) const{
185 ASSERT(isInside(point),"Exploded point not inside Box");
186 return explode(point,1);
187}
188
[014475]189double Box::periodicDistanceSquared(const Vector &point1,const Vector &point2) const{
[f1c838]190 Vector helper1 = WrapPeriodically(point1);
191 Vector helper2 = WrapPeriodically(point2);
192 VECTORSET(std::list) expansion = explode(helper1);
193 double res = expansion.minDistSquared(helper2);
[014475]194 return res;
195}
196
197double Box::periodicDistance(const Vector &point1,const Vector &point2) const{
198 double res;
199 res = sqrt(periodicDistanceSquared(point1,point2));
200 return res;
[527de2]201}
202
[77374e]203const Box::Conditions_t Box::getConditions(){
204 return conditions;
205}
206
207void Box::setCondition(int i,Box::BoundaryCondition_t condition){
208 conditions[i]=condition;
209}
210
[29ac78]211const vector<pair<Plane,Plane> > Box::getBoundingPlanes(){
212 vector<pair<Plane,Plane> > res;
213 for(int i=0;i<NDIM;++i){
214 Vector base1,base2,base3;
215 base2[(i+1)%NDIM] = 1.;
216 base3[(i+2)%NDIM] = 1.;
217 Plane p1(translateIn(base1),
218 translateIn(base2),
219 translateIn(base3));
220 Vector offset;
221 offset[i]=1;
222 Plane p2(translateIn(base1+offset),
223 translateIn(base2+offset),
224 translateIn(base3+offset));
225 res.push_back(make_pair(p1,p2));
226 }
227 return res;
228}
229
[7579a4b]230Box &Box::operator=(const Box &src){
231 if(&src!=this){
232 delete M;
233 delete Minv;
234 M = new Matrix(*src.M);
235 Minv = new Matrix(*src.Minv);
[77374e]236 conditions = src.conditions;
[7579a4b]237 }
238 return *this;
239}
240
241Box &Box::operator=(const Matrix &mat){
242 setM(mat);
243 return *this;
244}
Note: See TracBrowser for help on using the repository browser.