//? quantumscattering.cpp
//? C+- by Ulrich Mutze. Status of work 2019-09-01.
//? Copyright (c) 2016 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.
/*************************************************************************
This program tries to extend my Wolram Demonstration
'Simulating Quantum Scattering'
/////////////////////////////////////////////////
about
/////////////////////////////////////////////////
W file=quantum scattering.ini
Ws line1=Time evolution of the crossway system.
Ws line2=...
Ws line3=...
Ws line4=...
Ws line5=...
These are the program specific data that go into the creation
of the start-up screen of the project. Other elements of
this start-up screen are common to all C+- programs which
use class CpmApplication::IniFileBasedApplication
(see file cpminifilebasapp.h) as an application framework.
The definition of function IniFileBasedApplication::announceTheWork()
in file cpminifilebasapp.cpp defines these additional elements.
Notice also the following section, which any ini-file is expected to
have and which allows to influence the program run and the
auto-generated documentation in many ways. Although
ini-files are not seen by the compiler, they read like
C++ code by having type indicators for their data entries.
Also comments are treated as in C++.
Valid type indicators are B, Z, R, W for bool, integer, real, and
character string and the corresponding lists Bs, Zs, Rs, Ws.
There is a further valid type indicator F, which introduces the name
of an ini-file to be included. So ini-files nest to an arbitrary level.
This feature was developed for an industrial project where all data
defining the kinematics of a complex robot were originally held in a
single ini-file.
With the number of data growing to several thousands and with
people from other groups becoming involved in adjusting the
data, it became mandatory to split the data to separatly
editable units and nevertheless ensure integrity of production runs
by having a single ini-file at work.
Several of my C+- programs make use of this facility for similar
reasons.
Text lines in which there is no data type indicator are section
headings. Sections behave very much like namespaces: Althoug
section 'about' (see above) has an entry 'file' a section with
different name may also have an entry named 'file'. Sections
don't nest, so that several F-included files may add to
the same section, which turned out to be very convenient in the
framework for which I developed the scheme.
////////////////////////////////////////////////////////////////////////
selection
////////////////////////////////////////////////////////////////////////
R tWaitAnnounceScreen=0
Z sel=1
// a selector for the 'depth' of auto-generated documentation files.
// Control of auto-generated documentation files is based on the
// two entries sel, runName. These are the rules:
// 1. for sel<0 no documentation files will be created.
// 2. for sel==0 a light documentation file is created that
// covers all the input so that the program run can be repeated.
// 3. for sel>0, in addition to the light documentation file
// a more detailed one will be created that also can made to
// list computational results.
// 4. All documentation files have names which contain runName
// appended to the name of the calling program
Z cpmverbose=1
// controls the degree of detail with which program run
// information will be written to log file cpmcerr.txt
Z cpmdbg=2
// controls the reaction of the cpmassert macro:
// 1: warning on failing assertion
// 2: error stop on failing assertion
W runName=190901a
// identifier for the program run that will be appended to
// the names of documentation files.
// If the value of this quantity is "auto" this value will
// be replaced by an autogenerated name.
***********************************************************************/
#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 std;
using namespace std::placeholders;
namespace{ // anonymous namespace which hold all of classes
// ClassicalScatteringApp and ClassicalCrossway
// QuantumScatteringApp and Crossway
class ClassicalScatteringApp: public IniFileBasedApplication
{
public:
ClassicalScatteringApp();
void doTheWork();
};
ClassicalScatteringApp::ClassicalScatteringApp(void):
IniFileBasedApplication("classicalscattering"){}
R pot12(R r)
{
R rs=r+0.2_R;
return r>R(12.) ? 0_R : cpmexp(-r)/(rs*rs);
}
R2 f12(R const& x1, R const& x2)
{
R2 d(-x1,x2);
R r = d.nor_();
R rs=r+0.2;
R f = r>R(12.) ? 0_R : -cpmexp(-r)*(2_R+rs)/(rs*rs*rs);
R a1 = d[1]*f;
R a2 = -d[2]*f;
return R2(a1,a2);
}
R en(R m1, R m2, R x1, R v1, R x2, R v2, R beta, R lambda) // beta is K in Schiff p. 67
{
return 0.5_R*(m1*v1*v1 + m2*v2*v2 + beta*x2*x2) + lambda*pot12(R2(-x1,x2).nor_());
}
class ClassicalCrossWay
// The particle indexed 1 moves along the x-axis and that indexed 2 along the y-axis
// state space is R x R x R x R x Color
{
R L1_,L2_,m1_,m2_; // original lengths.
R beta_,lambda_;
R t_{0.}; // inital value of model time
R x1_, v1_, x2_, v2_; // position and velocity of particles 1 and 2
Color col_{BLACK}; // means to make graphics involving large numbers of
// Crossway particles better interpretable.
R enr_{0.};
public:
Word nameOf()const{ return "CCW"; }
ClassicalCrossWay():
L1_(1_R), L2_(1_R), m1_(1_R), m2_(1_R), beta_(1_R), lambda_(1_R),
x1_{0_R}, v1_{0_R}, x2_{0_R}, v2_{0_R}{enr_=en(m1_,m2_,x1_,v1_,x2_,v2_,beta_,lambda_);}
ClassicalCrossWay(R const& L1, R const& L2,
R const& m1, R const& m2, R const& beta, R const& lambda,
R const& x1, R const& v1, R const& x2, R const& v2):
L1_(L1), L2_(L2), m1_(m1), m2_(m2), beta_(beta), lambda_(lambda),
x1_{x1}, v1_{v1}, x2_{x2}, v2_{v2}{enr_=en(m1_,m2_,x1_,v1_,x2_,v2_,beta_,lambda_);}
void step_(R dt)
{
R tau=dt*0.5;
t_+=tau;
x1_+=v1_*tau;
x2_+=v2_*tau;
R2 k12=f12(x1_,x2_)*lambda_;
v1_+= k12[1]*dt/m1_; // always +k12 not + and -
v2_+= (-beta_*x2_+ k12[2])*dt/m2_;
x1_+=v1_*tau;
x2_+=v2_*tau;
t_+=tau;
enr_=en(m1_,m2_,x1_,v1_,x2_,v2_,beta_,lambda_);
}
R enr()const{ return enr_;}
R t()const{ return t_;}
R x1()const{ return x1_;}
R x2()const{ return x2_;}
R v1()const{ return v1_;}
R v2()const{ return v2_;}
Color col()const{ return col_;}
void setCol_(Color const& col){ col_=col;}
R2 point()const{ return R2(x1_,x2_); }
};
typedef ClassicalCrossWay CCW ;
void ClassicalScatteringApp::doTheWork()
// does what the name says
{
Word loc("ClassicalScatteringApp::doTheWork()");
Z mL=1;
CPM_MA
Word sec="biotope";
R L1,L2;
cpmrh(L1);
cpmrh(L2);
sec="initial conditions";
R x10,sigma1;
cpmrh(x10);
cpmrh(sigma1);
sec="system data";
Z ni,nf,np;
R m1,m2,lambda,beta,dt;
cpmrh(m1);
cpmrh(m2);
cpmrh(lambda);
cpmrh(beta);
cpmrh(dt);
cpmrh(ni);
cpmrh(nf);
cpmrh(np);
sec="run data";
Z nSteps,imgUpdate1,imgUpdate2;
R gamma,tWait0,tWait1,tWait2,tWait3,tWait4;
B makeMovie;
cpmrh(nSteps);
cpmrh(imgUpdate1);
cpmrh(imgUpdate2);
cpmrh(gamma);
cpmrh(makeMovie);
cpmrh(tWait0);
cpmrh(tWait1);
cpmrh(tWait2);
cpmrh(tWait3);
cpmrh(tWait4);
R tStart=cpmtime();
Color::setGamma(gamma);
R omega =cpmsqrt(beta/m2);
R ei = (ni+0.5_R)*omega;
R ef = (nf+0.5_R)*omega;
R v10 = cpmsqrt(2_R*(ef-ei)/m1);
// The the classical oscillation corresponding to the quantum ground state of the oscillator particle
// is x(t) = amp * sin(omega * t + delta) , v(t) = amp * omega * cos(omega * t + delta)
// ei = (beta/2) * ampĀ²
R amp = cpmsqrt(ei*2_R/beta); // amplitude of classical oscillation which corresponds
// to the quantum groundstate
R v20 = cpmsqrt(2_R*ei/m2);
//************************ creating the initial state ********************//
Response r;
r.setColorResponse();
r.setLevels(8_Z);
r.setRangeX(0_R,1_R);
V par(np);
cout<<" np = "<xU) xU=x1j;
gr.mark(p2,4,par[j].col()); // color set from ini state
}
if (show0()){
gr.vis(makeMovie);
}
}
while ( countP > 0){
countP--;
gr.vis(makeMovie);
}
cpmcerr<<" xL = "< 0){
countP--;
gr.vis(makeMovie);
}
// showing the initial state
gr.clr_();
gr.paint(LIGHTGREEN);
for (j=1;j<=np;++j){
R2 p2=par[j].point();
gr.mark(p2,4,par[j].col());
}
gr.vis(makeMovie);
cpmwait(tWait2,2);
countP=20;
while ( countP > 0){
countP--;
gr.vis(makeMovie);
}
V vr2(np);
for (Z j=1;j<=np;++j){
CCW pj=par[j];
vr2[j]=pj.point();
}
gr.setXY(vr2,1.025_R); // with securaty factor
gr.clr_();
gr.paint(WHITE);
for (j=1;j<=np;++j){
R2 p2=par[j].point();
gr.mark(p2,12,par[j].col());
}
gr.vis(makeMovie);
cpmwait(tWait3,2);
countP=20;
while ( countP > 0){
countP--;
gr.vis(makeMovie);
}
CPM_MZ
}
} // end of anonymous namespace
bool setXY(V const& pos, R secFac=1.1);
// same behavior as previous function
void test1(){
Z n=400000,i,j;
R_Vector val(n);
for (j=1;j<=n;++j){
val[j] = gaussRandomValue(0_R,0.1_R,j);
}
Histogram h(1,40,-0.4,0.4);
for (i=1;i<=n;++i){
h.put(1,val[i]);
}
Graph gr;
h.mark(gr,false);
gr.vis();
cpmwait(60_R,2);
return;
}
Z CpmApplication::main_(void)
// In this form the C++ typic function main()(defined in file
// cpmapplication.cpp) expects to see the basic functionality of
// the program.
// Notice that main() in cpmapplication.cpp provides the program
// with its graphical window and a status bar.
// The fact that class QuantumScatteringApp is derived from class
// IniFileBasedApplication lets the following short code, although it
// looks like abstract nonsense, do very specific things.
{
Word loc("Z CpmApplication::main_(void)");
Z mL=1;
CPM_MA
Z msel=0;
if (msel==0){
title_=Word("classicalscattering");
ClassicalScatteringApp app;
// creates the application class by reading and deploying
// quantumscattering.ini
app.run();
// brings the application class to live and action
}
if (msel==1){
test1();
}
else {
cout<< "unvalid value of msel nothing to do"<