//? 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"<=2){
cout<<"args_[2] = "<=3){
cout<<"args_[3] = "<=4){
cout<<"args_[4] = "<