//? eqm2.cpp //? C+- by Ulrich Mutze. Status of work 2021-10-26. //? Copyright (c) 2021 Ulrich Mutze //? contact: see contact-info at www.ulrichmutze.de //? //? This program is free software: you can redistribute it and/or //? modify it under the terms of the GNU General Public License as //? published by the Free Software Foundation, either version 3 of //? the License, or (at your option) any later version. //? //? This program is distributed in the hope that it will be useful, //? but WITHOUT ANY WARRANTY; without even the implied warranty of //? MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //? GNU General Public License for //? more details. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace CpmRoot; using namespace CpmRootX; using namespace CpmFunctions; using namespace CpmSystem; using namespace CpmArrays; using namespace CpmGraphics; using namespace CpmImaging; using namespace CpmApplication; using namespace CpmAlgorithms; using namespace CpmGeo; using namespace CpmQuantumMechanics; using namespace std; /* Expansive Quantum Mechanics. We consider a particularly simple and transparent quantum mechanical model system in which an initially insolated subsystem A and a subsystem B figurating as the evironment of A can be identified. System A consists initially of a free particle in uniform motion. System B consists initially of a large number of localized potential wells each occupied by a particle in its ground state. All particles interact with the potential wells and with all other particles via a universal pair interaction. Physical space is idealized as a finite chain of equi-distant points. */ namespace eqm2{ // expansive quantum mechanics //#undef CPM_VEC //#define CPM_VEC // the program test4 gave execution time // 69.83 using valarray and // 70.30 using vector // So there is no difference between the methods so far. Lets see whether // this is still valid if more than one particles are in the game. // The actual version of the program fisihes irregularly with a // std::bad_alloc exception for both settings of this macro at // approximately at system time 0.12. There seems to be a memory // leak. How can this occur with the main classes having constructors // and (default) destructors ? Befor this is not resolved the // present version of expansive quantum mechanics is not useful. // No leaking as can be seen by running the 'Systemueberwachung' // parallel to eqm2. One sees memory usage mostly oscillating between // 189 MB and 221 MB, very rarely exceeding 300 MB. // Is a time limit built in ??? No !!! // The problematic point is the introduction of the 4th particle. // In our case a single state would require 32*32 MB = 1GB. // Since we need two of those simultaneously we need 2 GB of RAM // Plausible that these can't be allocated. // One should try to work with mutating methods in place where I // used generating ones. (already implemented !!!) // 2023-02-20 not clear to what an degree this is still relevant. // 2023-03-16 Comparison of eqm2.cpp (multiindexes using function c() // for elegance) and eqm2Mem6.cpp (old treatment of multiindexes): // new elegant version 1152.31 s , old method 1159.65 s execution time // for the same input data: cpmSel/eqm2/r20230316c new, // cpmSel/eqm2/r20230316b old. Both runs with optimization O2. // Quintessence: No reasopn for conserving the old version. //#define CPM_VEC #if defined(CPM_VEC) using VN = vector; using VC = vector; using VR = vector; #else using VN = valarray; using VC = valarray; using VR = valarray; #endif R abs(VC const& x){ R sum=0_R; N n{x.size()}; for (N i=0; i operator+(vector const& v1, vector const& v2) { N n{v1.size()}; vector res(n); for (N i=0; i operator-(vector const& v1, vector const& v2) { N n{v1.size()}; vector res(n); for (N i=0; i operator*(vector const& v1, vector const& v2) { N n{v1.size()}; vector res(n); for (N i=0; i operator*(vector const& v1, C const& z) { N n{v1.size()}; vector res(n); for (N i=0; i& operator+=(vector& v1, vector const& v2) { N n{v1.size()}; for (N i=0; i& operator-=(vector& v1, vector const& v2) { N n{v1.size()}; for (N i=0; i& operator*=(vector& v, C z) { N n{v.size()}; for (N i=0; i& operator*=(vector& v, R t) { N n{v.size()}; for (N i=0; i(m); } // returns m^np in Fortran-notation N szIni(N m, N np){ return static_cast(pow(m,np)); } // function for initializing Bio::ind_ // This allows only to use biotopes which have the same size for // all particles in it. VN indIni(N m, N np) { N i{1}; N k; #if defined(CPM_VEC) VN prel(np,1); #else // then valarry VN prel(1,np); #endif // preliminary result initialized with np numbers one cpmassert(np==prel.size(),"indIni(N m, N np)"); while (i fp{[](R x){ // defining a function in terms of an anonymous lambda // expression. R rho{0.5}; R x2{x*x}; R rho2{rho*rho}; return x2 > rho2 ? R{0.} : x2-rho2; } }; // notice that the definition of fp ends in ';' unlike the definition // of a functon. N aN{1}; N sizeN=sizeof(aN); R aR{1.}; N sizeR=sizeof(aR); N sizeC=sizeR*2; class Bio{ // biotope, only geometric data N m_{0}; // number of positions available to any of the np_ // particles N np_{0}; // number of particles. In the present program limited to 4 R xL_{0.}; R xU_{0.}; // the m_ positions are the centers of the intervals obtained // by dividing the interval [xL,xU] into m_ congruent parts. R d_{0.}; // gap between neigboring particle positions N sz_{0};// m_^np_ in Fortran notation // This will be the dimension of Wf::x_ VN ind_; // a list of np_ natural numbers which allow an economic // way of transforming multi-indexes into a single large index VR x_; // list of the positions available to any of the np_ partlcles. // thus a list of m_ real numbers Iv ivMax_; // we don't consider values xL_, xU_ for which the interval [xL_,xU_] // is not contained in in the interval ivMax_ public: Bio(N m, N np, R xL, R xU, Iv ivMax=Iv(-1000_R, 1000_R)): m_{m}, np_{np}, xL_{xL}, xU_{xU}, d_{dIni(m_,xL_,xU_)}, sz_{szIni(m_,np_)}, ind_{indIni(m_,np_)}, x_{xIni(m_,xL_,d_)}, ivMax_{ivMax} {} Bio(){} // required to satisfy the concept semiregular N m()const{ return m_;} N& m(){ return m_;} N np()const{ return np_;} R xL()const{ return xL_;} R xU()const{ return xU_;} R& xL(){ return xL_;} R& xU(){ return xU_;} R d()const{ return d_;} N sz()const{ return sz_;} VN ind()const{ return ind_;} VR x()const{ return x_;} Iv ivMax()const{ return ivMax_;} Bio shift(R sh)const; void toSingle_(){ np_=1; sz_=m_; ind_=indIni(m_,np_);} bool match(Bio const& b)const; bool contains(Bio const& b)const; // If the return value T2(nL,nU) differs from (-1,-1) the biotope // *this contains the biotope b and has nL additional points // at the lower end of b and nU additional points at the upper end // end of b. Of course nL and/or nU may be equal to 0. T2 excess(Bio const& b)const; N memUse()const{ return (m_+3)*sizeR+(np_+3)*sizeN;} // plain memory used in bytes for an instance of Bio (not Wf !). // most convenient way of writint to cpmcerr and cout (only if _CONSOLE is // set) and statusbar void write(std::ostringstream& ost)const{ ost<<"m_="<)")} Wf(Bio const& bio, Dyn const& dyn, F const& wfunc): bio_(bio), dyn_(dyn),rep_(bio_.sz()){ cpmassert(rep_.size()==bio_.sz(), "dimension mismatch in constructor Wf(Bio,Dyn,F)"); cpmassert(bio_.np()==1,"only one particle allowed"); for (N i=0;i cl{GREEN,RED,BLACK,ORANGE}; gr.mark(x,y,cl); } else if (np()==2){ R_Vector y0=traceToVec(0); R_Vector y1=traceToVec(1); R_Matrix y(3); y[1]=y0; y[2]=y1; y[3]=potL; y=y.scaleNeg(frcNeg); V cl{BLACK,LIGHTMAGENTA,ORANGE}; gr.mark(x,y,cl); } else if (np()==3){ R_Vector y0=traceToVec(0); R_Vector y1=traceToVec(1); R_Vector y2=traceToVec(2); R_Matrix y(4); y[1]=y0; y[2]=y1; y[3]=y2; y[4]=potL; y=y.scaleNeg(frcNeg); V cl{BLACK,LIGHTMAGENTA,BLUE,ORANGE}; gr.mark(x,y,cl); } else if (np()==4){ R_Vector y0=traceToVec(0); R_Vector y1=traceToVec(1); R_Vector y2=traceToVec(2); R_Vector y3=traceToVec(3); R_Matrix y(5); y[1]=y0; y[2]=y1; y[3]=y2; y[4]=y3; y[5]=potL; y=y.scaleNeg(frcNeg); V cl{BLACK,LIGHTMAGENTA,BLUE,GREEN,ORANGE}; gr.mark(x,y,cl); } R t2=cpmtime(); cpmmessage(loc," done in "&cpm(t2-t1)&" s"); CPM_MZ } N cycShift(N i, Z s, N m){ Z is=(Z)i-s; while (is<0){ is+=m;} while (is>=m){is-=m;} return (N)is; } Wf Wf::shift(Z s)const{ cpmassert(np()==1, "we only shift the first particle"); Wf res(*this); for (N i=0;i0.,"zero vectors can't be normalized"); R fac=1_R/cpmsqrt(r); VC rep(rep_); for (N i=0;i= xUMax) {bioL.xU()=xLMax; bU=true;} N m=bioL.m(); cpmassert(n>=3,"n should be larger than 2") Wf res(bioL,dyn_); // res carries the time information of *this if (np()==1){ for (N i=0;i=n ? rep_[i-n] : C{}; } else if (np()==2){ for (N i=0;i=n && j>=n) ? c(i-n,j-n) : C{}; } } } else if (np()==3){ for (N i=0;i=n && j>=n && k>=n) ? (c)(i-n,j-n,k-n) : C{}; } } } } else if (np()==4){ for (N i=0;i=n && j>=n && k>=n && l>=n) ? c(i-n,j-n,k-n,l-n) : C{}; } } } } } else cpmassert(np()<=4,"number of particles larger than 4"); res.readyL_=true; res.alarmL_=false; res.smooth(smoothSteps); R t2=cpmtime(); cpmmessage(loc," done in "&cpm(t2-t1)&" s"); CPM_MZ return res; } Wf Wf::extU(N n)const{ Z mL=1; static Word loc("Wf::extU(N n)"); CPM_MA R t1=cpmtime(); Bio bioU(bio_.m()+n, bio_.np(), bio_.xL(), bio_.xU()+bio_.d()*n); N m=bioU.m(); N bm=bio_.m(); VC rep(bioU.sz()); Wf res(bioU,dyn_,rep); // res carries the time information of *this if (np()==1){ for (N i=0;itiny){ alarmL_=true;} } else if (np()==2){ for (N i=0;itiny){ alarmL_=true;} } for (N j=0;jtiny){ alarmL_=true;} } } else if (np()==3){ for (N i=0;itiny){ alarmL_=true; } } } for (N i=0;itiny){ alarmL_=true;} } } for (N j=0;jtiny){ alarmL_=true; } } } } else if (np()==4){ for (N i=0;itiny){ alarmL_=true;} } } } for (N i=0;itiny){ alarmL_=true;} } } } for (N i=0;itiny){ alarmL_=true;} } } } for (N j=0;jtiny){ alarmL_=true;} } } } } readyL_=true; CPM_MZ return alarmL_; } } bool Wf::alrU()const{ Z mL=3; static Word loc("Wf::alrU()const"); CPM_MA if (readyU_){ CPM_MZ return alarmU_; } else{ R tiny=dyn_.tiny_; N iU=m()-1; alarmU_=false; R val; if (np()==1){ val=rep_[iU].abs(); if (val>tiny){ alarmU_=true;} } else if (np()==2){ for (N i=0;itiny){ alarmU_=true;} } for (N j=0;jtiny){ alarmU_=true;} } } else if (np()==3){ for (N i=0;itiny){ alarmU_=true;} } } for (N i=0;itiny){ alarmU_=true;} } } for (N j=0;jtiny){ alarmU_=true;} } } } else if (np()==4){ for (N i=0;itiny){ alarmU_=true; } } } } for (N i=0;itiny){ alarmU_=true; } } } } for (N i=0;itiny){ alarmU_=true;} } } } for (N j=0;jtiny){ alarmU_=true;} } } } } readyU_=true; CPM_MZ return alarmU_; } } Wf Wf::hf()const{ static Z beat1=0; alarmL_=false; alarmU_=false; readyL_=false; readyU_=false; R sumL{0.}; R sumU{0.}; R t1=cpmtime(); Z cp=-1; // communication pane // bool going=!dyn_.cyclic_; // h() is called for performing a time step // and not for working within norm determination cpmvalue("beat1: ",beat1,2); R fac=1_R/(2_R*d()*d()*mass()); R tiny=dyn_.tiny_; N iU=m()-1; Wf res(*this); if (np()==1){ R val=rep_[0].abs(); // avoid a second evaluation of abs() in // the block 'if (going){...}' if (val>tiny){ sumL+=val; alarmL_=true; } val=rep_[iU].abs(); if (val>tiny){ alarmU_=true; } for (N i=0;i=0 ? rep_[i-1] : rep_[iU]; } else{ amUi= i+1 < m() ? rep_[i+1] : C{}; amLi= Z(i)-1 >=0 ? rep_[i-1] : C{}; } // i-1 give unregular values for i of type N. res[i]=(amC-amUi-amLi)*fac; } } else if (np()==2){ for (N i=0;itiny){ alarmL_=true; } } if (i==iU){ val=c(i,j).abs(); if (val>tiny){ alarmU_=true; } } if (j==0){ val=c(i,j).abs(); if (val>tiny){ alarmL_=true; } } if (j==iU){ val=c(i,j).abs(); if (val>tiny){ alarmU_=true; } } C amC = c(i,j)*R{4.},amLi,amLj,amUi,amUj; if (dyn_.cyclic_){ amUi = i+1 < m() ? c(i+1,j) : c(0,j); amLi = Z(i)-1 >= 0 ? c(i-1,j) : c(iU,j); amUj = j+1 < m() ? c(i,j+1) : c(i,0); amLj = Z(i)-1 >= 0 ? c(i,j-1) : c(i,iU); } else{ amUi = i+1 < m() ? c(i+1,j) : C{}; amLi = Z(i)-1 >= 0 ? c(i-1,j) : C{}; amUj = j+1 < m() ? c(i,j+1) : C{}; amLj = Z(i)-1 >= 0 ? c(i,j-1) : C{}; } res.c(i,j)=(amC-amUi-amLi-amUj-amLj)*fac ; } } } else if (np()==3){ for (N i=0;itiny){ alarmL_=true; } } if (i==iU){ val=c(i,j,k).abs(); if (val>tiny){ alarmU_=true; } } if (j==0){ val=c(i,j,k).abs(); if (val>tiny){ alarmL_=true; } } if (j==iU){ val=c(i,j,k).abs(); if (val>tiny){ alarmU_=true; } } if (k==0){ val=c(i,j,k).abs(); if (val>tiny){ alarmL_=true; } } if (k==iU){ val=c(i,j,k).abs(); if (val>tiny){ alarmU_=true; } } C amC = c(i,j,k)*R{6.}; C amLi,amLj,amLk,amUi,amUj,amUk; if (dyn_.cyclic_){ amUi = i+1 < m() ? c(i+1,j,k) : c(0,j,k); amLi = Z(i)-1 >=0 ? c(i-1,j,k) : c(iU,j,k); amUj = j+1 < m() ? c(i,j+1,k) : c(i,0,k); amLj = Z(j)-1 >=0 ? c(i,j-1,k) : c(i,iU,k); amUk = k+1 < m() ? c(i,j,k+1) : c(i,j,0); amLk = Z(k)-1 >=0 ? c(i,j,k-1) : c(i,j,iU); } else{ amC = c(i,j,k)*R{6.}; amUi = i+1 < m() ? c(i+1,j,k) : C{}; amLi = Z(i)-1 >=0 ? c(i-1,j,k) : C{}; amUj = j+1 < m() ? c(i,j+1,k) : C{}; amLj = Z(j)-1 >=0 ? c(i,j-1,k) : C{}; amUk = k+1 < m() ? c(i,j,k+1) : C{}; amLk = Z(k)-1 >=0 ? c(i,j,k-1) : C{}; } res.c(i,j,k)=(amC-amUi-amLi-amUj-amLj-amUk-amLk)*fac; } } } } else if (np()==4){ for (N i=0;itiny){ alarmL_=true; } } if (i==iU){ val=c(i,j,k,l).abs(); if (val>tiny){ alarmU_=true; } } if (j==0){ val=c(i,j,k,l).abs(); if (val>tiny){ alarmL_=true; } } if (j==iU){ val=c(i,j,k,l).abs(); if (val>tiny){ alarmU_=true; } } if (k==0){ val=c(i,j,k,l).abs(); if (val>tiny){ alarmL_=true; } } if (k==iU){ val=c(i,j,k,l).abs(); if (val>tiny){ alarmU_=true; } } if (l==0){ val=c(i,j,k,l).abs(); if (val>tiny){ alarmL_=true; } } if (l==iU){ val=c(i,j,k,l).abs(); if (val>tiny){ alarmU_=true; } } C amC = c(i,j,k,l)*R{8.}; C amLi,amLj,amLk,amLl,amUi,amUj,amUk,amUl; if (dyn_.cyclic_){ amUi = i+1 < m() ? c(i+1,j,k,l) : c(0,j,k); amLi = Z(i)-1 >=0 ? c(i-1,j,k,l) : c(iU,j,k); amUj = j+1 < m() ? c(i,j+1,k,l) : c(i,0,k); amLj = Z(j)-1 >=0 ? c(i,j-1,k,l) : c(i,iU,k); amUk = k+1 < m() ? c(i,j,k+1,l) : c(i,j,0); amLk = Z(k)-1 >=0 ? c(i,j,k-1,l) : c(i,j,iU); amUl = l+1 < m() ? c(i,j,k,l+1) : c(i,j,0); amLl = Z(l)-1 >=0 ? c(i,j,k,l-1) : c(i,j,iU); } else{ amC = c(i,j,k,l)*R{8.}; amUi = i+1 < m() ? c(i+1,j,k,l) : C{}; amLi = Z(i)-1 >=0 ? c(i-1,j,k,l) : C{}; amUj = j+1 < m() ? c(i,j+1,k,l) : C{}; amLj = Z(j)-1 >=0 ? c(i,j-1,k,l) : C{}; amUk = k+1 < m() ? c(i,j,k+1,l) : C{}; amLk = Z(k)-1 >=0 ? c(i,j,k-1,l) : C{}; amUl = l+1 < m() ? c(i,j,k,l+1) : C{}; amLl = Z(l)-1 >=0 ? c(i,j,k,l-1) : C{}; } res.c(i,j,k,l)=(amC-amUi-amLi-amUj-amLj-amUk-amLk -amUl-amLl)*fac; } } } } } else cpmassert(np()<=4,"Wf::h(): number of particles larger than 4"); beat1++; R t2=cpmtime(); R realTimeSpan=t2-t1; R beatRate=R{60.}/realTimeSpan; R speed = dt_< R{0.} ? R{0.} : dt_*R{1000.}/realTimeSpan; Z bioSize=m(); Z nP=np(); if (dt_>R{0.}){ cpmvalues2("beats/min, speed: ",beatRate,speed,3); } else{ cpmvalue("beats/min: ",beatRate,3); } cpmvalues2("bioSize, np: ",bioSize,nP,4); readyL_=true; readyU_=true; return res; } Wf Wf::smoothS()const{ Z mL=1; static Word loc("Wf::smoothS()const"); CPM_MA auto fac=0.25_R; Wf res(*this); if (np()==1){ for (N i=0;i=0 ? rep_[i-1] : C{}; res[i]=(amC+amUi+amLi)*fac; } } else if (np()==2){ fac=1_R/8_R; for (N i=0;i= 0 ? c(i-1,j) : C{}; amUj = j+1 < m() ? c(i,j+1) : C{}; amLj = Z(i)-1 >= 0 ? c(i,j-1) : C{}; res.c(i,j)=(amC+amUi+amLi+amUj+amLj)*fac ; } } } else if (np()==3){ fac=1_R/12_R; for (N i=0;i=0 ? c(i-1,j,k) : C{}; amUj = j+1 < m() ? c(i,j+1,k) : C{}; amLj = Z(j)-1 >=0 ? c(i,j-1,k) : C{}; amUk = k+1 < m() ? c(i,j,k+1) : C{}; amLk = Z(k)-1 >=0 ? c(i,j,k-1) : C{}; res.c(i,j,k)=(amC+amUi+amLi+amUj+amLj-amUk-amLk)*fac; } } } } else if (np()==4){ fac=1_R/16_R; for (N i=0;i=0 ? c(i-1,j,k,l) : C{}; amUj = j+1 < m() ? c(i,j+1,k,l) : C{}; amLj = Z(j)-1 >=0 ? c(i,j-1,k,l) : C{}; amUk = k+1 < m() ? c(i,j,k+1,l) : C{}; amLk = Z(k)-1 >=0 ? c(i,j,k-1,l) : C{}; amUl = l+1 < m() ? c(i,j,k,l+1) : C{}; amLl = Z(l)-1 >=0 ? c(i,j,k,l-1) : C{}; res.c(i,j,k,l)= (amC+amUi+amLi+amUj+amLj+amUk+amLk+amUl+amLl)*fac; } } } } } else cpmassert(np()<=4,"Wf::smooth(): number of particles larger than 4"); CPM_MZ return res; } Wf Wf::hl()const{ static Z beat2=0; R t1=cpmtime(); cpmvalue("beat2: ",beat2,2); R fac=1_R/(2_R*d()*d()*mass()); N iU=m()-1; Wf res(*this); if (np()==1){ for (N i=0;i=0 ? rep_[i-1] : C{}; res[i]=(amC-amUi-amLi)*fac; } } else if (np()==2){ for (N i=0;i= 0 ? c(i-1,j) : C{}; amUj = j+1 < m() ? c(i,j+1) : C{}; amLj = Z(i)-1 >= 0 ? c(i,j-1) : C{}; res.c(i,j)=(amC-amUi-amLi-amUj-amLj)*fac ; } } } else if (np()==3){ for (N i=0;i=0 ? c(i-1,j,k) : C{}; amUj = j+1 < m() ? c(i,j+1,k) : C{}; amLj = Z(j)-1 >=0 ? c(i,j-1,k) : C{}; amUk = k+1 < m() ? c(i,j,k+1) : C{}; amLk = Z(k)-1 >=0 ? c(i,j,k-1) : C{}; res.c(i,j,k)=(amC-amUi-amLi-amUj-amLj-amUk-amLk)*fac; } } } } else if (np()==4){ for (N i=0;i=0 ? c(i-1,j,k,l) : C{}; amUj = j+1 < m() ? c(i,j+1,k,l) : C{}; amLj = Z(j)-1 >=0 ? c(i,j-1,k,l) : C{}; amUk = k+1 < m() ? c(i,j,k+1,l) : C{}; amLk = Z(k)-1 >=0 ? c(i,j,k-1,l) : C{}; amUl = l+1 < m() ? c(i,j,k,l+1) : C{}; amLl = Z(l)-1 >=0 ? c(i,j,k,l-1) : C{}; res.c(i,j,k,l)=(amC-amUi-amLi-amUj-amLj-amUk-amLk -amUl-amLl)*fac; } } } } } else cpmassert(np()<=4,"Wf::h(): number of particles larger than 4"); beat2++; R t2=cpmtime(); R realTimeSpan=t2-t1; R beatRate=R{60.}/realTimeSpan; R speed = dt_< 0_R ? 0_R : dt_*1000_R/realTimeSpan; Z bioSize=m(); Z nP=np(); if (dt_>0_R){ cpmvalues2("beats/min, speed: ",beatRate,speed,3); } else{ cpmvalue("beats/min: ",beatRate,3); } cpmvalues2("bioSize, np: ",bioSize,nP,4); return res; } Wf Wf::v()const{ VC rep(rep_); for (N i=0;i0_R){ psi.mark(gr); gr.vis(); cpmwait(tWait,2); } R eta=0_R; R_Vector etaV(iMax); // bool cycMem=dyn_.cyclic_; dyn_.cyclic_=true; // algorithm for operator norm requires an // hermitic operator. For running extensible dynamics cyclic // should be false (default value of B). for (Z i=1;i<=iMax;++i){ psi.cyclic(true); psi=psi.ham(); // total hamiltonian (with potentials) eta=psi.nor_(); if (tWait>0_R){ psi.mark(gr); gr.vis(); cpmwait(tWait,2); } ostringstream ost; ost<<" i= "< fpot{[&xc,&halfRangeInv,&rhoRel](R x){ // defining a //function in terms of a lambda expression. R eta=(x-xc)*halfRangeInv; // eta has the value 0 at the midpoint of iv and the value 1 and // -1 at the rims. eta is a variable dependend on x. It also is the // value of x in a different coordinate system. // The value of fpot at x==0 is thus -rho2. R eta2{eta*eta}; R rho2{rhoRel*rhoRel}; return eta2 > rho2 ? 0_R : eta2-rho2; }}; R_Func pot=fpot; R_Func pot0=fpot; R_Func potVac; // pot with constant value 0 R eKinMax=QMBase::eMax(m); R eKinSel=eKinMax*vRel*vRel; R vMax=QMBase::vMax(m); R vb=vMax*vRel; // v boost R lambda=-lambdaPotRel*eKinSel/pot(0_R); gr.addText("function pot"); gr.mark(pot); gr.visRep(makeMovie); cpmwait(tWait2,2); gr.clearText(); gr.clr_(); gr.paint(LIGHTGREEN); F h(function{[&pot,&lambda,&iv] (State const& s){ return s.sinParHam2(pot*lambda,iv.abs()); }}); Opr op((Z)m,h); Observable ob=op.toObservable(); gr.setText("hamilton operator as matrix",0.1,0.2,WHITE); ob.mark(gr); // potentially changes gr gr.visRep(makeMovie); cpmwait(tWait3,2); gr.clearText(); SpectralObject so=ob.spectralRepresentation(); gr.addText("spectrum"); so.markSpectrum(gr); // potentially changes gr gr.visRep(makeMovie); cpmwait(tWait3,2); gr.clearText(); State groundstate=so[1]; groundstate.mark(gr); // potentially changes gr gr.setText("raw groundstate",0.1,0.2); gr.visRep(makeMovie); cpmwait(tWait3,2); gr.clearText(); gr.setX(iv); // retting shape of potentially changed gr R_Func winFunc=R_Func::tableMountain(iv,soft); gr.mark(winFunc); gr.setText("window function",0.1,0.2); gr.visRep(makeMovie); cpmwait(tWait3,2); gr.clearText(); groundstate=groundstate.windowing(soft).normalize(); groundstate.mark(gr); gr.setText("windowed groundstate",0.1,0.2); gr.visRep(makeMovie); cpmwait(tWait3,2); gr.clearText(); R enrMin=so(1).real(); R potMin=lambda*pot(0_R); R eTot=enrMin+eKinSel; ostringstream o0; o0<<"enrMin = "< 0_R) gr.setY_(Iv(-axisInspect,axisInspect)); Dyn dyn(mass,tiny,potVac,potPair); Wf wgs(bio,dyn); // wgs: wavefunction ground state, an instance of Wf wgs.setSmoothSteps_(smoothSteps); for (N i=0,j=1; j<=m; ++i,++j){ wgs[i]=groundstate[j]; // now we no longer have vectors the indexing of // which starts with 1 } wgs.mark(gr); gr.setText("initial wave function at rest",0.1,0.2); gr.visRep(makeMovie); cpmwait(tWait4,2); gr.clearText(); Wf wf0=wgs.boost(vb); cpmmessage("initial wave function",1,true); wf0.mark(gr,iv); // initial wave function gr.setText("initial wave function moving",0.1,0.2); gr.visRep(makeMovie); cpmwait(tWait4,2); gr.clearText(); // now wf0 becomes part of a dynamical system with a defined time // evolution. auto t_ini=0_R; Sys sys(wf0,dtRel,t_ini); // now the hamiltonian of Wf is responsible for the time evolution cout<<"sys.t()="<tMax){ // this is condition for finishing the program run cpmmessage("tMax exceeded: tMax="&cpm(tMax)&", t="&cpm(sys.t())); if (makeMovie) ppm2mp4(Word("video")); CPM_MZ return; } if (sys.sz()>szMax){ // we have to reduce size by reduction cpmmessage("szMax exceeded: szMax="&cpm(szMax)& ", sys.sz()="&cpm(sys.sz())); goto reduction; // reduces np to 1 and thus considerably reduces sz } if (sys.np()>npMax){ // we have to reduce size by reduction cpmmessage("np exceeded: npMax="&cpm(npMax)& ", sys.np()="&cpm(sys.np())); if (useReduction) goto reduction; // reduces np to 1 and thus considerably reduces sz else{ if (makeMovie) ppm2mp4(Word("video")); CPM_MZ return; } } // we reached the rim of the biotope and have to extend it. Since the size // limit is not yet reached we may try this. Wf wf=sys.x(); R t1=sys.t(); cout<<"t1 = "<szMax){ cpmmessage("szMax exceeded: szMax="&cpm(szMax)& ", wf.sz()="&cpm(ws)); if (useReduction) goto reduction; // reduces np to 1 and thus considerably reduces sz else{ if (makeMovie) ppm2mp4(Word("video")); CPM_MZ return; } } cpmmessage("new Sys ahead",1,true); sys=Sys(wf,dtRel,t1); cpmmessage("new Sys done",1,true); ostringstream ost2; ost2<<"if (!wf.freeL()) done"<szMax){ cpmmessage("szMax exceeded: szMax="&cpm(szMax)& ", wf.sz()="&cpm(ws)); if (useReduction) goto reduction; // reduces np to 1 and thus considerably reduces sz else{ if (makeMovie) ppm2mp4(Word("video")); CPM_MZ return; } } } else{ // wf.np()1, "a new wave function was tensorially 'added'"); N ws=wf.sz(); if (ws>szMax){ cpmmessage("szMax exceeded: szMax="&cpm(szMax)& ", wf.sz()="&cpm(ws)); goto reduction; } R_Func potNew=pot0.shift(shiftRange)+wf.pot().shift(shiftRange); wf.setPot_(potNew); } cpmmessage("sys after extU etc.",1,true); cpmmessage("new Sys ahead"); sys=Sys(wf,dtRel,t1); cpmmessage("new Sys done"); gr.clearText(); sys.mark(gr); gr.vis(makeMovie); cpmwait(tWait4,2); cpmassert(sys.freeL(), "why? action to ensure sys.freeL() was done before !"); ostringstream ost2; ost2<<"if (!sys.freeU()) done"<szMax and we have to reduce // the wave function to that of a single particle state static Z redCount=0_Z; reduction: ostringstream ostred; ostred<<"reduction started at sys.sz() = "< f(f3); gr.mark(f); gr.vis(); Sys sys; cout<<"test4() done"<