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
Line 
1/*
2 * Box.cpp
3 *
4 * Created on: Jun 30, 2010
5 * Author: crueger
6 */
7
8//#include "Helpers/MemDebug.hpp"
9
10#include "Box.hpp"
11
12#include <cmath>
13#include <iostream>
14
15#include "Matrix.hpp"
16#include "vector.hpp"
17#include "Plane.hpp"
18
19#include "Helpers/Assert.hpp"
20
21using namespace std;
22
23Box::Box()
24{
25 M= new Matrix();
26 M->one();
27 Minv = new Matrix();
28 Minv->one();
29 conditions.resize(3);
30 conditions[0] = conditions[1] = conditions[2] = Wrap;
31}
32
33Box::Box(const Box& src){
34 M=new Matrix(*src.M);
35 Minv = new Matrix(*src.Minv);
36 conditions = src.conditions;
37}
38
39Box::~Box()
40{
41 delete M;
42 delete Minv;
43}
44
45const Matrix &Box::getM() const{
46 return *M;
47}
48const Matrix &Box::getMinv() const{
49 return *Minv;
50}
51
52void Box::setM(Matrix _M){
53 ASSERT(_M.determinant()!=0,"Matrix in Box construction was not invertible");
54 *M =_M;
55 *Minv = M->invert();
56}
57
58Vector Box::translateIn(const Vector &point) const{
59 return (*M) * point;
60}
61
62Vector Box::translateOut(const Vector &point) const{
63 return (*Minv) * point;
64}
65
66Vector Box::WrapPeriodically(const Vector &point) const{
67 Vector helper = translateOut(point);
68 for(int i=NDIM;i--;){
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
90 }
91 return translateIn(helper);
92}
93
94bool Box::isInside(const Vector &point) const
95{
96 bool result = true;
97 Vector tester = translateOut(point);
98
99 for(int i=0;i<NDIM;i++)
100 result = result &&
101 ((conditions[i] == Ignore) ||
102 ((tester[i] >= -MYEPSILON) &&
103 ((tester[i] - 1.) < MYEPSILON)));
104
105 return result;
106}
107
108
109VECTORSET(std::list) Box::explode(const Vector &point,int n) const{
110 ASSERT(isInside(point),"Exploded point not inside Box");
111 VECTORSET(std::list) res;
112
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;
134 }
135
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");
167 }
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];
179 }
180 }
181 return res;
182}
183
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
189double Box::periodicDistanceSquared(const Vector &point1,const Vector &point2) const{
190 Vector helper1 = WrapPeriodically(point1);
191 Vector helper2 = WrapPeriodically(point2);
192 VECTORSET(std::list) expansion = explode(helper1);
193 double res = expansion.minDistSquared(helper2);
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;
201}
202
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
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
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);
236 conditions = src.conditions;
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.