Finished the rewriting of the classes for B(z) and P(B) calculations for now. Maybe some of the assertions have to be removed later...

This commit is contained in:
Bastian M. Wojek 2009-04-25 16:08:18 +00:00
parent fae9c0446e
commit ec98ee12d0
10 changed files with 1193 additions and 500 deletions

View File

@ -6,16 +6,16 @@ ROOTCFLAGS = $(shell $(ROOTSYS)/bin/root-config --cflags)
#--------------------------------------------------- #---------------------------------------------------
OS = LINUX OS = LINUX
CXX = g++ CXX = g++-4.2.4
CXXFLAGS = -g -Wall -Wno-trigraphs -fPIC CXXFLAGS = -O3 -Wall -fopenmp -Wno-trigraphs -fPIC
MUSRFITINCLUDE = ../../../include MUSRFITINCLUDE = ../../../include
#MUSRFITINCLUDE = /home/l_wojek/rep/analysis/musrfit/src/include #MUSRFITINCLUDE = /home/l_wojek/rep/analysis/musrfit/src/include
LOCALINCLUDE = ../include LOCALINCLUDE = ../include
ROOTINCLUDE = $(ROOTSYS)/include ROOTINCLUDE = $(ROOTSYS)/include
INCLUDES = -I$(LOCALINCLUDE) -I$(MUSRFITINCLUDE) -I$(ROOTINCLUDE) INCLUDES = -I$(LOCALINCLUDE) -I$(MUSRFITINCLUDE) -I$(ROOTINCLUDE)
LD = g++ LD = g++-4.2.4
LDFLAGS = -g LDFLAGS = -O3
SOFLAGS = -O -shared SOFLAGS = -O3 -shared -fopenmp -lfftw3_threads -lfftw3 -lm -lpthread
# the output from the root-config script: # the output from the root-config script:
CXXFLAGS += $(ROOTCFLAGS) CXXFLAGS += $(ROOTCFLAGS)
@ -29,6 +29,7 @@ OBJS += TPofBCalc.o
OBJS += TPofTCalc.o OBJS += TPofTCalc.o
OBJS += TFitPofBStartupHandler.o TFitPofBStartupHandlerDict.o OBJS += TFitPofBStartupHandler.o TFitPofBStartupHandlerDict.o
OBJS += TLondon1D.o TLondon1DDict.o OBJS += TLondon1D.o TLondon1DDict.o
OBJS += TSkewedGss.o TSkewedGssDict.o
SHLIB = libTFitPofB.so SHLIB = libTFitPofB.so
@ -59,6 +60,10 @@ TLondon1DDict.cpp: ../include/TLondon1D.h ../include/TLondon1DLinkDef.h
@echo "Generating dictionary $@..." @echo "Generating dictionary $@..."
rootcint -f $@ -c -p -I$(MUSRFITINCLUDE) $^ rootcint -f $@ -c -p -I$(MUSRFITINCLUDE) $^
TSkewedGssDict.cpp: ../include/TSkewedGss.h ../include/TSkewedGssLinkDef.h
@echo "Generating dictionary $@..."
rootcint -f $@ -c -p -I$(MUSRFITINCLUDE) $^
TFitPofBStartupHandlerDict.cpp: ../include/TFitPofBStartupHandler.h ../include/TFitPofBStartupHandlerLinkDef.h TFitPofBStartupHandlerDict.cpp: ../include/TFitPofBStartupHandler.h ../include/TFitPofBStartupHandlerLinkDef.h
@echo "Generating dictionary $@..." @echo "Generating dictionary $@..."
rootcint -f $@ -c -p $^ rootcint -f $@ -c -p $^

View File

@ -5,26 +5,38 @@
Author: Bastian M. Wojek Author: Bastian M. Wojek
e-mail: bastian.wojek@psi.ch e-mail: bastian.wojek@psi.ch
2008/06/30 2009/04/25
***************************************************************************/ ***************************************************************************/
#include "TBofZCalc.h" #include "TBofZCalc.h"
#include <omp.h> #include <omp.h>
#include <cmath> #include <cmath>
#include <iostream> //#include <iostream>
#include <algorithm> //#include <algorithm>
#include <cassert>
vector<double> DataZ() const{ //------------------
if (fZ.empty) // Method filling the z and B(z)-vectors for the case B(z) should be used numerically
Calculate(); //------------------
return fZ;
void TBofZCalc::Calculate()
{
if (!fBZ.empty())
return;
double ZZ;
int j;
fZ.resize(fSteps);
fBZ.resize(fSteps);
#pragma omp parallel for default(shared) private(j,ZZ) schedule(dynamic)
for (j=0; j<fSteps; j++) {
ZZ = fParam[1] + (double)j*fDZ;
fZ[j] = ZZ;
fBZ[j] = GetBofZ(ZZ);
} }
return;
vector<double> DataBZ() const{
if (fBZ.empty)
Calculate();
return fBZ;
} }
// //------------------ // //------------------
@ -80,67 +92,315 @@ vector<double> DataBZ() const{
// Parameters: Bext[G], deadlayer[nm], lambda[nm] // Parameters: Bext[G], deadlayer[nm], lambda[nm]
//------------------ //------------------
TLondon1D_HS::TLondon1D_HS(unsigned int steps, const vector<double> &param) { TLondon1D_HS::TLondon1D_HS(const vector<double> &param, unsigned int steps)
{
fSteps = steps;
fDZ = 200.0/double(steps); fDZ = 200.0/double(steps);
double ZZ, BBz; fParam = param;
for (unsigned int j(0); j<steps; j++) {
ZZ = param[1] + (double)j*fDZ;
fZ.push_back(ZZ);
BBz = param[0]*exp(-(ZZ-param[1])/param[2]);
fBZ.push_back(BBz);
} }
double TLondon1D_HS::GetBofZ(double ZZ) const
{
if(ZZ < 0. || ZZ < fParam[1])
return fParam[0];
return fParam[0]*exp((fParam[1]-ZZ)/fParam[2]);
} }
double TLondon1D_HS::GetBmax() const
{
// return applied field
return fParam[0];
}
double TLondon1D_HS::GetBmin() const
{
// return field minimum
return fParam[0]*exp((fParam[1]-200.0)/fParam[2]);
}
vector< pair<double, double> > TLondon1D_HS::GetInverseAndDerivative(double BB) const
{
vector< pair<double, double> > inv;
if(BB <= 0.0 || BB > fParam[0])
return inv;
pair<double, double> invAndDerivative;
invAndDerivative.first = fParam[1] - fParam[2]*log(BB/fParam[0]);
invAndDerivative.second = -fParam[2]/BB;
inv.push_back(invAndDerivative);
return inv;
}
//------------------ //------------------
// Constructor of the TLondon1D_1L class // Constructor of the TLondon1D_1L class
// 1D-London screening in a thin superconducting film // 1D-London screening in a thin superconducting film
// Parameters: Bext[G], deadlayer[nm], thickness[nm], lambda[nm] // Parameters: Bext[G], deadlayer[nm], thickness[nm], lambda[nm]
//------------------ //------------------
TLondon1D_1L::TLondon1D_1L(unsigned int steps, const vector<double> &param) { TLondon1D_1L::TLondon1D_1L(const vector<double> &param, unsigned int steps)
{
double N(cosh(param[2]/2.0/param[3])); fSteps = steps;
fDZ = param[2]/double(steps); fDZ = param[2]/double(steps);
double ZZ, BBz; fParam = param;
fMinZ = -1.0;
fMinB = -1.0;
for (unsigned int j(0); j<steps; j++) { // thicknesses have to be greater or equal to zero
ZZ = param[1] + (double)j*fDZ; for(unsigned int i(1); i<3; i++)
fZ.push_back(ZZ); assert(param[i]>=0.);
BBz = param[0]*cosh((param[2]/2.0-(ZZ-param[1]))/param[3])/N;
fBZ.push_back(BBz); // lambdas have to be greater than zero
assert(param[3]!=0.);
// Calculate the coefficients of the exponentials
double N0(param[0]/(1.0+exp(param[2]/param[3])));
fCoeff[0]=N0*exp((param[1]+param[2])/param[3]);
fCoeff[1]=N0*exp(-param[1]/param[3]);
// none of the coefficients should be zero
for(unsigned int i(0); i<2; i++)
assert(fCoeff[i]);
SetBmin();
} }
double TLondon1D_1L::GetBofZ(double ZZ) const
{
if(ZZ < 0. || ZZ < fParam[1] || ZZ > fParam[1]+fParam[2])
return fParam[0];
return fCoeff[0]*exp(-ZZ/fParam[3])+fCoeff[1]*exp(ZZ/fParam[3]);
} }
double TLondon1D_1L::GetBmax() const
{
// return applied field
return fParam[0];
}
double TLondon1D_1L::GetBmin() const
{
// return field minimum
return fMinB;
}
void TLondon1D_1L::SetBmin()
{
double b_a(fCoeff[1]/fCoeff[0]);
assert (b_a>0.);
double minZ;
// check if the minimum is in the first layer
minZ=-0.5*fParam[3]*log(b_a);
if (minZ > fParam[1] && minZ <= fParam[2]) {
fMinZ = minZ;
fMinB = GetBofZ(minZ);
return;
}
assert(fMinZ > 0. && fMinB > 0.);
return;
}
vector< pair<double, double> > TLondon1D_1L::GetInverseAndDerivative(double BB) const
{
vector< pair<double, double> > inv;
if(BB <= fMinB || BB > fParam[0])
return inv;
double inverse[2];
pair<double, double> invAndDerivative;
inverse[0]=fParam[3]*log((BB-sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]))/(2.0*fCoeff[1]));
inverse[1]=fParam[3]*log((BB+sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]))/(2.0*fCoeff[1]));
if(inverse[0] > fParam[1] && inverse[0] < fMinZ) {
invAndDerivative.first = inverse[0];
invAndDerivative.second = -fParam[3]/sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]);
inv.push_back(invAndDerivative);
}
if(inverse[1] > fMinZ && inverse[1] <= fParam[1]+fParam[2]) {
invAndDerivative.first = inverse[1];
invAndDerivative.second = +fParam[3]/sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]);
inv.push_back(invAndDerivative);
}
return inv;
}
//------------------ //------------------
// Constructor of the TLondon1D_2L class // Constructor of the TLondon1D_2L class
// 1D-London screening in a thin superconducting film, two layers, two lambda // 1D-London screening in a thin superconducting film, two layers, two lambda
// Parameters: Bext[G], deadlayer[nm], thickness1[nm], thickness2[nm], lambda1[nm], lambda2[nm] // Parameters: Bext[G], deadlayer[nm], thickness1[nm], thickness2[nm], lambda1[nm], lambda2[nm]
//------------------ //------------------
TLondon1D_2L::TLondon1D_2L(unsigned int steps, const vector<double> &param) { TLondon1D_2L::TLondon1D_2L(const vector<double> &param, unsigned int steps)
{
double N1(param[5]*cosh(param[3]/param[5])*sinh(param[2]/param[4]) + param[4]*cosh(param[2]/param[4])*sinh(param[3]/param[5])); fSteps = steps;
double N2(4.0*N1);
fDZ = (param[2]+param[3])/double(steps); fDZ = (param[2]+param[3])/double(steps);
double ZZ, BBz; fParam = param;
fMinTag = -1;
fMinZ = -1.0;
fMinB = -1.0;
for (unsigned int j(0); j<steps; j++) { // thicknesses have to be greater or equal to zero
ZZ = param[1] + (double)j*fDZ; for(unsigned int i(1); i<4; i++)
fZ.push_back(ZZ); assert(param[i]>=0.);
if (ZZ < param[1]+param[2]) {
BBz = param[0]*(param[4]*cosh((param[2]+param[1]-ZZ)/param[4])*sinh(param[3]/param[5]) - param[5]*sinh((param[1]-ZZ)/param[4]) + param[5]*cosh(param[3]/param[5])*sinh((param[2]+param[1]-ZZ)/param[4]))/N1; // lambdas have to be greater than zero
for(unsigned int i(4); i<6; i++){
assert(param[i]!=0.);
}
fInterfaces[0]=param[1];
fInterfaces[1]=param[1]+param[2];
fInterfaces[2]=param[1]+param[2]+param[3];
// Calculate the coefficients of the exponentials
double B0(param[0]), dd(param[1]), d1(param[2]), d2(param[3]), l1(param[4]), l2(param[5]);
double N0((1.0+exp(2.0*d1/l1))*(-1.0+exp(2.0*d2/l2))*l1+(-1.0+exp(2.0*d1/l1))*(1.0+exp(2.0*d2/l2))*l2);
double N1(4.0*(l2*cosh(d2/l2)*sinh(d1/l1)+l1*cosh(d1/l1)*sinh(d2/l2)));
fCoeff[0]=B0*exp((d1+dd)/l1)*(-2.0*exp(d2/l2)*l2+exp(d1/l1)*(l2-l1)+exp(d1/l1+2.0*d2/l2)*(l1+l2))/N0;
fCoeff[1]=-B0*exp(-(dd+d1)/l1-d2/l2)*(l1-exp(2.0*d2/l2)*l1+(1.0-2.0*exp(d1/l1+d2/l2)+exp(2.0*d2/l2))*l2)/N1;
fCoeff[2]=B0*exp((d1+d2+dd)/l2)*(-(1.0+exp(2.0*d1/l1)-2.0*exp(d1/l1+d2/l2))*l1+(-1.0+exp(2.0*d1/l1))*l2)/N0;
fCoeff[3]=B0*exp(-d1/l1-(d1+d2+dd)/l2)*(-2.0*exp(d1/l1)*l1+exp(d2/l2)*(l1-l2+exp(2.0*d1/l1)*(l1+l2)))/N1;
// none of the coefficients should be zero
for(unsigned int i(0); i<4; i++)
assert(fCoeff[i]);
SetBmin();
}
double TLondon1D_2L::GetBofZ(double ZZ) const
{
if(ZZ < 0. || ZZ < fInterfaces[0] || ZZ > fInterfaces[2])
return fParam[0];
if (ZZ < fInterfaces[1]) {
return fCoeff[0]*exp(-ZZ/fParam[4])+fCoeff[1]*exp(ZZ/fParam[4]);
} else { } else {
BBz = param[0]*(exp(-param[2]/param[4]-(param[2]+param[3]+param[1]+ZZ)/param[5]) * (exp((param[3]+2.0*param[1])/param[5])*(exp(2.0*param[2]*(param[4]+param[5])/param[4]/param[5]) * (param[5]-param[4]) - exp(2.0*param[2]/param[5]) * (param[4]-2.0*param[4]*exp(param[2]/param[4]+param[3]/param[5])+param[5])) + exp(2.0*ZZ/param[5])*((param[4]-param[5]+(param[4]+param[5]) * exp(2.0*param[2]/param[4]))*exp(param[3]/param[5])-2.0*param[4]*exp(param[2]/param[4]))))/N2; return fCoeff[2]*exp(-ZZ/fParam[5])+fCoeff[3]*exp(ZZ/fParam[5]);
} }
fBZ.push_back(BBz);
} }
double TLondon1D_2L::GetBmax() const
{
// return applied field
return fParam[0];
}
double TLondon1D_2L::GetBmin() const
{
// return field minimum
return fMinB;
}
void TLondon1D_2L::SetBmin()
{
double b_a(fCoeff[1]/fCoeff[0]);
assert (b_a>0.);
double minZ;
// check if the minimum is in the first layer
minZ=-0.5*fParam[4]*log(b_a);
if (minZ > fInterfaces[0] && minZ <= fInterfaces[1]) {
fMinTag = 1;
fMinZ = minZ;
fMinB = GetBofZ(minZ);
return;
}
double d_c(fCoeff[3]/fCoeff[2]);
assert (d_c>0.);
// check if the minimum is in the second layer
minZ=-0.5*fParam[5]*log(d_c);
if (minZ > fInterfaces[1] && minZ <= fInterfaces[2]) {
fMinTag = 2;
fMinZ = minZ;
fMinB = GetBofZ(minZ);
return;
}
assert(fMinZ > 0. && fMinB > 0.);
return;
}
vector< pair<double, double> > TLondon1D_2L::GetInverseAndDerivative(double BB) const
{
vector< pair<double, double> > inv;
if(BB <= fMinB || BB > fParam[0])
return inv;
double inverse[3];
pair<double, double> invAndDerivative;
switch(fMinTag)
{
case 1:
inverse[0]=fParam[4]*log((BB-sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]))/(2.0*fCoeff[1]));
inverse[1]=fParam[4]*log((BB+sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]))/(2.0*fCoeff[1]));
inverse[2]=fParam[5]*log((BB+sqrt(BB*BB-4.0*fCoeff[2]*fCoeff[3]))/(2.0*fCoeff[3]));
if(inverse[0] > fInterfaces[0] && inverse[0] < fMinZ) {
invAndDerivative.first = inverse[0];
invAndDerivative.second = -fParam[4]/sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]);
inv.push_back(invAndDerivative);
}
if(inverse[1] > fMinZ && inverse[1] <= fInterfaces[1]) {
invAndDerivative.first = inverse[1];
invAndDerivative.second = +fParam[4]/sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]);
inv.push_back(invAndDerivative);
}
if(inverse[2] > fInterfaces[1] && inverse[2] <= fInterfaces[2]) {
invAndDerivative.first = inverse[2];
invAndDerivative.second = +fParam[5]/sqrt(BB*BB-4.0*fCoeff[2]*fCoeff[3]);
inv.push_back(invAndDerivative);
}
break;
case 2:
inverse[0]=fParam[4]*log((BB-sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]))/(2.0*fCoeff[1]));
inverse[1]=fParam[5]*log((BB-sqrt(BB*BB-4.0*fCoeff[2]*fCoeff[3]))/(2.0*fCoeff[3]));
inverse[2]=fParam[5]*log((BB+sqrt(BB*BB-4.0*fCoeff[2]*fCoeff[3]))/(2.0*fCoeff[3]));
if(inverse[0] > fInterfaces[0] && inverse[0] <= fInterfaces[1]) {
invAndDerivative.first = inverse[0];
invAndDerivative.second = -fParam[4]/sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]);
inv.push_back(invAndDerivative);
}
if(inverse[1] > fInterfaces[1] && inverse[1] < fMinZ) {
invAndDerivative.first = inverse[1];
invAndDerivative.second = -fParam[5]/sqrt(BB*BB-4.0*fCoeff[2]*fCoeff[3]);
inv.push_back(invAndDerivative);
}
if(inverse[2] > fMinZ && inverse[2] <= fInterfaces[2]) {
invAndDerivative.first = inverse[2];
invAndDerivative.second = +fParam[5]/sqrt(BB*BB-4.0*fCoeff[2]*fCoeff[3]);
inv.push_back(invAndDerivative);
}
break;
default:
break;
}
return inv;
} }
//------------------ //------------------
@ -149,67 +409,62 @@ TLondon1D_2L::TLondon1D_2L(unsigned int steps, const vector<double> &param) {
// Parameters: Bext[G], deadlayer[nm], thickness1[nm], thickness2[nm], thickness3[nm], lambda1[nm], lambda2[nm], lambda3[nm] // Parameters: Bext[G], deadlayer[nm], thickness1[nm], thickness2[nm], thickness3[nm], lambda1[nm], lambda2[nm], lambda3[nm]
//------------------ //------------------
TLondon1D_3L::TLondon1D_3L(unsigned int steps, const vector<double> &param) TLondon1D_3L::TLondon1D_3L(const vector<double> &param, unsigned int steps)
: fSteps(steps), fDZ((param[2]+param[3]+param[4])/double(steps)), fParam(param), fMinTag(-1), fMinZ(-1.0), fMinB(-1.0) // : fSteps(steps), fDZ((param[2]+param[3]+param[4])/double(steps)), fParam(param), fMinTag(-1), fMinZ(-1.0), fMinB(-1.0)
{ {
// no members of TLondon1D_3L, therefore the initialization list cannot be used!!
fSteps = steps;
fDZ = (param[2]+param[3]+param[4])/double(steps);
fParam = param;
fMinTag = -1;
fMinZ = -1.0;
fMinB = -1.0;
// thicknesses have to be greater or equal to zero // thicknesses have to be greater or equal to zero
for(unsigned int i(1); i<5; i++) for(unsigned int i(1); i<5; i++)
assert(param[i]>=0.); assert(param[i]>=0.);
// lambdas have to be greater than zero // lambdas have to be greater than zero
for(unsigned int i(5); i<param.size(); i++) for(unsigned int i(5); i<8; i++)
assert(param[i]>0.); assert(param[i]!=0.);
fInterfaces={param[1], param[1]+param[2], param[1]+param[2]+param[3], param[1]+param[2]+param[3]+param[4]}; fInterfaces[0]=param[1];
fInterfaces[1]=param[1]+param[2];
fInterfaces[2]=param[1]+param[2]+param[3];
fInterfaces[3]=param[1]+param[2]+param[3]+param[4];
// Calculate the coefficients of the exponentials // Calculate the coefficients of the exponentials
double N0(4.0*((1.0+exp(2.0*param[2]/param[5]))*param[5]*(param[7]*cosh(param[4]/param[7])*sinh(param[3]/param[6]) + \ double B0(param[0]), dd(param[1]), d1(param[2]), d2(param[3]), d3(param[4]), l1(param[5]), l2(param[6]), l3(param[7]);
param[6]*cosh(param[3]/param[6])*sinh(param[4]/param[7]))+(-1.0+exp(2.0*param[2]/param[5])) * \
param[6]*(param[7]*cosh(param[3]/param[6])*cosh(param[4]/param[7])+param[6]*sinh(param[3]/param[6])*sinh(param[4]/param[7]))));
double N2(2.0*param[7]*cosh(param[4]/param[7])*((-1.0+exp(2.0*param[2]/param[5]))*param[6]*cosh(param[3]/param[6]) + \ double N0(4.0*((1.0+exp(2.0*d1/l1))*l1*(l3*cosh(d3/l3)*sinh(d2/l2) + l2*cosh(d2/l2)*sinh(d3/l3))+(-1.0+exp(2.0*d1/l1)) * \
(1.0+exp(2.0*param[2]/param[5]))*param[5]*sinh(param[3]/param[6])) + \ l2*(l3*cosh(d2/l2)*cosh(d3/l3)+l2*sinh(d2/l2)*sinh(d3/l3))));
4.0*exp(param[2]/param[5])*param[6]*(param[5]*cosh(param[2]/param[5])*cosh(param[3]/param[6]) + \
param[6]*sinh(param[2]/param[5])*sinh(param[3]/param[6]))*sinh(param[4]/param[7]));
double N3(2.0*((1.0+exp(2.0*param[2]/param[5]))*param[5]*(param[7]*cosh(param[4]/param[7])*sinh(param[3]/param[6]) + \ double N2(2.0*l3*cosh(d3/l3)*((-1.0+exp(2.0*d1/l1))*l2*cosh(d2/l2) + (1.0+exp(2.0*d1/l1))*l1*sinh(d2/l2)) + \
param[6]*cosh(param[3]/param[6])*sinh(param[4]/param[7])) + \ 4.0*exp(d1/l1)*l2*(l1*cosh(d1/l1)*cosh(d2/l2) + l2*sinh(d1/l1)*sinh(d2/l2))*sinh(d3/l3));
(-1.0+exp(2.0*param[2]/param[5]))*param[6]*(param[7]*cosh(param[3]/param[6]) * \
cosh(param[4]/param[7])+param[6]*sinh(param[3]/param[6])*sinh(param[4]/param[7]))));
double N5((1.0+exp(2.0*param[2]/param[5]))*param[5]*(param[7]*cosh(param[4]/param[7])*sinh(param[3]/param[6]) + \ double N3(2.0*((1.0+exp(2.0*d1/l1))*l1*(l3*cosh(d3/l3)*sinh(d2/l2) + l2*cosh(d2/l2)*sinh(d3/l3)) + \
param[6]*cosh(param[3]/param[6])*sinh(param[4]/param[7])) + \ (-1.0+exp(2.0*d1/l1))*l2*(l3*cosh(d2/l2) * cosh(d3/l3)+l2*sinh(d2/l2)*sinh(d3/l3))));
(-1.0+exp(2.0*param[2]/param[5]))*param[6]*(param[7]*cosh(param[3]/param[6]) * \
cosh(param[4]/param[7])+param[6]*sinh(param[3]/param[6])*sinh(param[4]/param[7])));
fCoeff[0]=(B0*exp((param[2]+param[1])/param[5]-param[3]/param[6]-param[4]/param[7]) * \ double N5((1.0+exp(2.0*d1/l1))*l1*(l3*cosh(d3/l3)*sinh(d2/l2) + l2*cosh(d2/l2)*sinh(d3/l3)) + \
(exp(param[2]/param[5])*(param[5]-param[6])*(-param[6]+exp(2.0*param[4]/param[7])*(param[6]-param[7])-param[7]) - \ (-1.0+exp(2.0*d1/l1))*l2*(l3*cosh(d2/l2) * cosh(d3/l3)+l2*sinh(d2/l2)*sinh(d3/l3)));
4.0*exp(param[3]/param[6]+param[4]/param[7]) * param[6]*param[7] + \
exp(param[2]/param[5]+2.0*param[3]/param[6])*(param[5]+param[6]) * \
(-param[6]+param[7]+exp(2.0*param[4]/param[7])*(param[6]+param[7]))))/N0;
fCoeff[1]=(B0*exp(-param[1]/param[5]-param[3]/param[6]-param[4]/param[7])*(-param[6]*((-1.0+exp(2.0*param[3]/param[6])) * \ fCoeff[0]=(B0*exp((d1+dd)/l1-d2/l2-d3/l3) * (exp(d1/l1)*(l1-l2)*(-l2+exp(2.0*d3/l3)*(l2-l3)-l3) - \
(-1.0+exp(2.0*param[4]/param[7]))*param[6]+(1.0+exp(2.0*param[3]/param[6]) - \ 4.0*exp(d2/l2+d3/l3) * l2*l3 + exp(d1/l1+2.0*d2/l2)*(l1+l2) * (-l2+l3+exp(2.0*d3/l3)*(l2+l3))))/N0;
4.0*exp(param[2]/param[5]+param[3]/param[6]+param[4]/param[7]) + exp(2.0*param[4]/param[7])*(1.0+exp(2.0*param[3]/param[6])))*param[7]) + \
4.0*exp(param[3]/param[6]+param[4]/param[7])*param[5]*(param[7]*cosh(param[4]/param[7]) * \
sinh(param[3]/param[6])+param[6]*cosh(param[3]/param[6])*sinh(param[4]/param[7]))))/N0;
fCoeff[2]=(B0*exp((param[2]+param[1])/param[6])*(-exp(2.0*param[2]/param[5])*(param[5]-param[6])*param[7]-(param[5]+param[6])*param[7] + \ fCoeff[1]=(B0*exp(-dd/l1-d2/l2-d3/l3)*(-l2*((-1.0+exp(2.0*d2/l2)) * (-1.0+exp(2.0*d3/l3))*l2+(1.0+exp(2.0*d2/l2) - \
2.0*exp(param[2]/param[5]+param[3]/param[6])*param[5]*(param[7]*cosh(param[4]/param[7])+param[6]*sinh(param[4]/param[7]))))/N2; 4.0*exp(d1/l1+d2/l2+d3/l3) + exp(2.0*d3/l3)*(1.0+exp(2.0*d2/l2)))*l3) + 4.0*exp(d2/l2+d3/l3)*l1*(l3*cosh(d3/l3) * \
sinh(d2/l2)+l2*cosh(d2/l2)*sinh(d3/l3))))/N0;
fCoeff[3]=(B0*exp(-(param[2]+param[3]+param[1])/param[6]-param[4]/param[7])*(exp(param[3]/param[6]+param[4]/param[7]) * \ fCoeff[2]=(B0*exp((d1+dd)/l2)*(-exp(2.0*d1/l1)*(l1-l2)*l3-(l1+l2)*l3 + 2.0*exp(d1/l1+d2/l2)*l1*(l3*cosh(d3/l3)+l2*sinh(d3/l3))))/N2;
(param[5]-param[6]+exp(2.0*param[2]/param[5])*(param[5]+param[6]))*param[7] - \
exp(param[2]/param[5])*param[5]*(param[6]+param[7]+exp(2.0*param[4]/param[7])*(param[7]-param[6]))))/N3;
fCoeff[4]=(0.25*B0*exp(-param[3]/param[6]+(param[2]+param[3]+param[1])/param[7]) * \ fCoeff[3]=(B0*exp(-(d1+d2+dd)/l2-d3/l3)*(exp(d2/l2+d3/l3) * (l1-l2+exp(2.0*d1/l1)*(l1+l2))*l3 - \
(4.0*exp(param[2]/param[5]+param[3]/param[6]+param[4]/param[7])*param[5]*param[6] - \ exp(d1/l1)*l1*(l2+l3+exp(2.0*d3/l3)*(l3-l2))))/N3;
(-1.0+exp(2.0*param[2]/param[5]))*param[6]*(-param[6]+exp(2.0*param[3]/param[6])*(param[6]-param[7])-param[7]) - \
(1.0+exp(2.0*param[2]/param[5])*param[5]*(param[6]+exp(2.0*param[3]/param[6])*(param[6]-param[7])+param[7])))/N5;
fCoeff[5]=(B0*exp(-(param[2]+param[3]+param[4]+param[1])/param[7]+param[2]/param[5]) * \ fCoeff[4]=(0.25*B0*exp(-d2/l2+(d1+d2+dd)/l3) * (4.0*exp(d1/l1+d2/l2+d3/l3)*l1*l2 - \
(-param[5]*param[6]+exp(param[4]/param[7])*(param[6]*sinh(param[2]/param[5])*(param[7]*cosh(param[3]/param[6]) + \ (-1.0+exp(2.0*d1/l1))*l2*(-l2+exp(2.0*d2/l2)*(l2-l3)-l3) - (1.0+exp(2.0*d1/l1))*l1*(l2+exp(2.0*d2/l2)*(l2-l3)+l3)))/N5;
param[6]*sinh(param[3]/param[6])) + param[5]*cosh(param[2]/param[5]) * \
(param[6]*cosh(param[3]/param[6])+param[7]*sinh(param[3]/param[6])))))/N5; fCoeff[5]=(B0*exp(-(d1+d2+d3+dd)/l3+d1/l1) * (-l1*l2+exp(d3/l3)*(l2*sinh(d1/l1)*(l3*cosh(d2/l2) + \
l2*sinh(d2/l2)) + l1*cosh(d1/l1) * (l2*cosh(d2/l2)+l3*sinh(d2/l2)))))/N5;
// none of the coefficients should be zero // none of the coefficients should be zero
for(unsigned int i(0); i<6; i++) for(unsigned int i(0); i<6; i++)
@ -218,70 +473,17 @@ TLondon1D_3L::TLondon1D_3L(unsigned int steps, const vector<double> &param)
SetBmin(); SetBmin();
} }
void TLondon1D_3L::Calculate()
{
if (!fBZ.empty())
return;
double ZZ;
int j;
fZ.resize(fSteps);
fBZ.resize(fSteps);
#pragma omp parallel for default(shared) private(j,ZZ) schedule(dynamic)
for (j=0; j<fSteps; j++) {
ZZ = fParam[1] + (double)j*fDZ;
fZ[j] = ZZ;
fBZ[j] = GetBofZ(ZZ);
}
return;
}
double TLondon1D_3L::GetBofZ(double ZZ) const double TLondon1D_3L::GetBofZ(double ZZ) const
{ {
if(ZZ < 0. || ZZ < fInterfaces[0] || ZZ > fInterfaces[3]) if(ZZ < 0. || ZZ < fInterfaces[0] || ZZ > fInterfaces[3])
return fParam[0]; return fParam[0];
double N1(fParam[7]*cosh(fParam[4]/fParam[7])*((exp(2.0*fParam[2]/fParam[5])-1.0)*fParam[6]*cosh(fParam[3]/fParam[6]) + \
(1.0+exp(2.0*fParam[2]/fParam[5]))*fParam[5]*sinh(fParam[3]/fParam[6])) + \
2.0*exp(fParam[2]/fParam[5])*fParam[6]*(fParam[5]*cosh(fParam[2]/fParam[5])*cosh(fParam[3]/fParam[6]) + \
fParam[6]*sinh(fParam[2]/fParam[5])*sinh(fParam[3]/fParam[6]))*sinh(fParam[4]/fParam[7]));
double N21(2.0*(fParam[7]*cosh(fParam[4]/fParam[7])*((-1.0+exp(2.0*fParam[2]/fParam[5]))*fParam[6]*cosh(fParam[3]/fParam[6]) + \
(1.0+exp(2.0*fParam[2]/fParam[5]))*fParam[5]*sinh(fParam[3]/fParam[6])) + \
2.0*exp(fParam[2]/fParam[5])*fParam[6]*(fParam[5]*cosh(fParam[2]/fParam[5])*cosh(fParam[3]/fParam[6]) + \
fParam[6]*sinh(fParam[2]/fParam[5])*sinh(fParam[3]/fParam[6]))*sinh(fParam[4]/fParam[7])));
double N22(((fParam[5]+exp(2.0*fParam[2]/fParam[5])*(fParam[5]-fParam[6])+fParam[6])*(-fParam[7]*cosh(fParam[4]/fParam[7]) + \
fParam[6]*sinh(fParam[4]/fParam[7]))+exp(2.0*fParam[3]/fParam[6])*(fParam[5]-fParam[6] + \
exp(2.0*fParam[2]/fParam[5])*(fParam[5]+fParam[6]))*(fParam[7]*cosh(fParam[4]/fParam[7])+fParam[6]*sinh(fParam[4]/fParam[7]))));
double N3(4.0*((1.0+exp(2.0*fParam[2]/fParam[5]))*fParam[5]*(fParam[7]*cosh(fParam[4]/fParam[7])*sinh(fParam[3]/fParam[6]) + \
fParam[6]*cosh(fParam[3]/fParam[6])*sinh(fParam[4]/fParam[7])) + \
(-1.0+exp(2.0*fParam[2]/fParam[5]))*fParam[6]*(fParam[7]*cosh(fParam[3]/fParam[6])*cosh(fParam[4]/fParam[7]) + \
fParam[6]*sinh(fParam[3]/fParam[6])*sinh(fParam[4]/fParam[7]))));
if (ZZ < fInterfaces[1]) { if (ZZ < fInterfaces[1]) {
return (2.0*fParam[0]*exp(fParam[2]/fParam[5])*(-fParam[6]*fParam[7]*sinh((fParam[1]-ZZ)/fParam[5]) + \ return fCoeff[0]*exp(-ZZ/fParam[5])+fCoeff[1]*exp(ZZ/fParam[5]);
fParam[7]*cosh(fParam[4]/fParam[7])*(fParam[6]*cosh(fParam[3]/fParam[6])*sinh((fParam[2]+fParam[1]-ZZ)/fParam[5]) + \
fParam[5]*cosh((fParam[2]+fParam[1]-ZZ)/fParam[5])*sinh(fParam[3]/fParam[6])) + \
fParam[6]*(fParam[5]*cosh((fParam[2]+fParam[1]-ZZ)/fParam[5])*cosh(fParam[3]/fParam[6]) + \
fParam[6]*sinh((fParam[2]+fParam[1]-ZZ)/fParam[5])*sinh(fParam[3]/fParam[6]))*sinh(fParam[4]/fParam[7])))/N1;
} else if (ZZ < fInterfaces[2]) { } else if (ZZ < fInterfaces[2]) {
return (fParam[0]*exp((fParam[2]+fParam[1]-ZZ)/fParam[6])*(-fParam[5]-fParam[6]+exp(2.0*fParam[2]/fParam[5])*(fParam[6]-fParam[5]))*fParam[7])/N21 + \ return fCoeff[2]*exp(-ZZ/fParam[6])+fCoeff[3]*exp(ZZ/fParam[6]);
(fParam[0]*exp(-(fParam[2]+fParam[1]+ZZ)/fParam[6])*(exp((fParam[3]+2.0*ZZ)/fParam[6])*(fParam[5]-fParam[6] + \
exp(2.0*fParam[2]/fParam[5])*(fParam[5]+fParam[6]))*fParam[7] + \
2.0*exp(fParam[2]/fParam[5])*fParam[5]*(exp(2.0*ZZ/fParam[6])*(-fParam[7]*cosh(fParam[4]/fParam[7]) + \
fParam[6]*sinh(fParam[4]/fParam[7]))+(cosh(2.0*(fParam[2]+fParam[3]+fParam[1])/fParam[6]) + \
sinh(2.0*(fParam[2]+fParam[3]+fParam[1])/fParam[6]))*(fParam[7]*cosh(fParam[4]/fParam[7])+fParam[6]*sinh(fParam[4]/fParam[7])))))/N22;
} else { } else {
return (fParam[0]*exp(-(fParam[2]+fParam[3]+fParam[1]+ZZ)/fParam[7])*(-exp(-fParam[3]/fParam[6] + \ return fCoeff[4]*exp(-ZZ/fParam[7])+fCoeff[5]*exp(ZZ/fParam[7]);
2.0*(fParam[2]+fParam[3]+fParam[1])/fParam[7])*(-4.0*exp(fParam[2]/fParam[5]+fParam[3]/fParam[6]+fParam[4]/fParam[7])*fParam[5]*fParam[6] + \
(-1.0+exp(2.0*fParam[2]/fParam[5]))*fParam[6]*(-fParam[6]+exp(2.0*fParam[3]/fParam[6])*(fParam[6]-fParam[7])-fParam[7]) + \
(1.0+exp(2.0*fParam[2]/fParam[5]))*fParam[5]*(fParam[6]+exp(2.0*fParam[3]/fParam[6])*(fParam[6]-fParam[7])+fParam[7])) + \
4.0*exp(fParam[2]/fParam[5]-(fParam[4]-2.0*ZZ)/fParam[7])*(-fParam[5]*fParam[6]+exp(fParam[4]/fParam[7]) * \
(fParam[6]*sinh(fParam[2]/fParam[5])*(fParam[7]*cosh(fParam[3]/fParam[6])+fParam[6]*sinh(fParam[3]/fParam[6])) + \
fParam[5]*cosh(fParam[2]/fParam[5])*(fParam[6]*cosh(fParam[3]/fParam[6])+fParam[7]*sinh(fParam[3]/fParam[6]))))))/N3;
} }
} }
@ -336,7 +538,7 @@ void TLondon1D_3L::SetBmin()
return; return;
} }
assert(fminZ > 0. && fminB > 0.); assert(fMinZ > 0. && fMinB > 0.);
return; return;
} }
@ -344,7 +546,7 @@ vector< pair<double, double> > TLondon1D_3L::GetInverseAndDerivative(double BB)
{ {
vector< pair<double, double> > inv; vector< pair<double, double> > inv;
if(BB <= fminB || BB > fParam[0]) if(BB <= fMinB || BB > fParam[0])
return inv; return inv;
double inverse[4]; double inverse[4];
@ -358,12 +560,12 @@ vector< pair<double, double> > TLondon1D_3L::GetInverseAndDerivative(double BB)
inverse[2]=fParam[6]*log((BB+sqrt(BB*BB-4.0*fCoeff[2]*fCoeff[3]))/(2.0*fCoeff[3])); inverse[2]=fParam[6]*log((BB+sqrt(BB*BB-4.0*fCoeff[2]*fCoeff[3]))/(2.0*fCoeff[3]));
inverse[3]=fParam[7]*log((BB+sqrt(BB*BB-4.0*fCoeff[4]*fCoeff[5]))/(2.0*fCoeff[5])); inverse[3]=fParam[7]*log((BB+sqrt(BB*BB-4.0*fCoeff[4]*fCoeff[5]))/(2.0*fCoeff[5]));
if(inverse[0] > fInterfaces[0] && inverse[0] < fminZ) { if(inverse[0] > fInterfaces[0] && inverse[0] < fMinZ) {
invAndDerivative.first = inverse[0]; invAndDerivative.first = inverse[0];
invAndDerivative.second = -fParam[5]/sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]); invAndDerivative.second = -fParam[5]/sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]);
inv.push_back(invAndDerivative); inv.push_back(invAndDerivative);
} }
if(inverse[1] > fminZ && inverse[1] <= fInterfaces[1]) { if(inverse[1] > fMinZ && inverse[1] <= fInterfaces[1]) {
invAndDerivative.first = inverse[1]; invAndDerivative.first = inverse[1];
invAndDerivative.second = +fParam[5]/sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]); invAndDerivative.second = +fParam[5]/sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]);
inv.push_back(invAndDerivative); inv.push_back(invAndDerivative);
@ -391,12 +593,12 @@ vector< pair<double, double> > TLondon1D_3L::GetInverseAndDerivative(double BB)
invAndDerivative.second = -fParam[5]/sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]); invAndDerivative.second = -fParam[5]/sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]);
inv.push_back(invAndDerivative); inv.push_back(invAndDerivative);
} }
if(inverse[1] > fInterfaces[1] && inverse[1] < fminZ) { if(inverse[1] > fInterfaces[1] && inverse[1] < fMinZ) {
invAndDerivative.first = inverse[1]; invAndDerivative.first = inverse[1];
invAndDerivative.second = -fParam[6]/sqrt(BB*BB-4.0*fCoeff[2]*fCoeff[3]); invAndDerivative.second = -fParam[6]/sqrt(BB*BB-4.0*fCoeff[2]*fCoeff[3]);
inv.push_back(invAndDerivative); inv.push_back(invAndDerivative);
} }
if(inverse[2] > fminZ && inverse[2] <= fInterfaces[2]) { if(inverse[2] > fMinZ && inverse[2] <= fInterfaces[2]) {
invAndDerivative.first = inverse[2]; invAndDerivative.first = inverse[2];
invAndDerivative.second = +fParam[6]/sqrt(BB*BB-4.0*fCoeff[2]*fCoeff[3]); invAndDerivative.second = +fParam[6]/sqrt(BB*BB-4.0*fCoeff[2]*fCoeff[3]);
inv.push_back(invAndDerivative); inv.push_back(invAndDerivative);
@ -425,12 +627,12 @@ vector< pair<double, double> > TLondon1D_3L::GetInverseAndDerivative(double BB)
invAndDerivative.second = -fParam[6]/sqrt(BB*BB-4.0*fCoeff[2]*fCoeff[3]); invAndDerivative.second = -fParam[6]/sqrt(BB*BB-4.0*fCoeff[2]*fCoeff[3]);
inv.push_back(invAndDerivative); inv.push_back(invAndDerivative);
} }
if(inverse[2] > fInterfaces[2] && inverse[2] < fminZ) { if(inverse[2] > fInterfaces[2] && inverse[2] < fMinZ) {
invAndDerivative.first = inverse[2]; invAndDerivative.first = inverse[2];
invAndDerivative.second = -fParam[7]/sqrt(BB*BB-4.0*fCoeff[4]*fCoeff[5]); invAndDerivative.second = -fParam[7]/sqrt(BB*BB-4.0*fCoeff[4]*fCoeff[5]);
inv.push_back(invAndDerivative); inv.push_back(invAndDerivative);
} }
if(inverse[3] > fminZ && inverse[3] <= fInterfaces[3]) { if(inverse[3] > fMinZ && inverse[3] <= fInterfaces[3]) {
invAndDerivative.first = inverse[3]; invAndDerivative.first = inverse[3];
invAndDerivative.second = +fParam[7]/sqrt(BB*BB-4.0*fCoeff[4]*fCoeff[5]); invAndDerivative.second = +fParam[7]/sqrt(BB*BB-4.0*fCoeff[4]*fCoeff[5]);
inv.push_back(invAndDerivative); inv.push_back(invAndDerivative);
@ -450,74 +652,274 @@ vector< pair<double, double> > TLondon1D_3L::GetInverseAndDerivative(double BB)
// Parameters: Bext[G], deadlayer[nm], thickness1[nm], thickness2[nm], thickness3[nm], lambda1[nm], lambda2[nm] // Parameters: Bext[G], deadlayer[nm], thickness1[nm], thickness2[nm], thickness3[nm], lambda1[nm], lambda2[nm]
//------------------ //------------------
TLondon1D_3LS::TLondon1D_3LS(unsigned int steps, const vector<double> &param) { TLondon1D_3LS::TLondon1D_3LS(const vector<double> &param, unsigned int steps)
{
double N1(8.0*(param[5]*param[6]*cosh(param[3]/param[6])*sinh((param[2]+param[4])/param[5]) + ((param[5]*param[5]*cosh(param[2]/param[5])*cosh(param[4]/param[5])) + (param[6]*param[6]*sinh(param[2]/param[5])*sinh(param[4]/param[5])))*sinh(param[3]/param[6]))); fSteps = steps;
double N2(2.0*param[5]*param[6]*cosh(param[3]/param[6])*sinh((param[2]+param[4])/param[5]) + 2.0*(param[5]*param[5]*cosh(param[2]/param[5])*cosh(param[4]/param[5]) + param[6]*param[6]*sinh(param[2]/param[5])*sinh(param[4]/param[5]))*sinh(param[3]/param[6]));
double N3(8.0*(param[5]*param[6]*cosh(param[3]/param[6])*sinh((param[2]+param[4])/param[5]) + (param[5]*param[5]*cosh(param[2]/param[5])*cosh(param[4]/param[5]) + param[6]*param[6]*sinh(param[2]/param[5])*sinh(param[4]/param[5]))*sinh(param[3]/param[6])));
fDZ = (param[2]+param[3]+param[4])/double(steps); fDZ = (param[2]+param[3]+param[4])/double(steps);
double ZZ, BBz; fParam = param;
fMinTag = -1;
fMinZ = -1.0;
fMinB = -1.0;
for (unsigned int j(0); j<steps; j++) { // thicknesses have to be greater or equal to zero
ZZ = param[1] + (double)j*fDZ; for(unsigned int i(1); i<5; i++)
fZ.push_back(ZZ); assert(param[i]>=0.);
if (ZZ < param[1]+param[2]) {
BBz = (param[0]*exp(-1.0*((param[2]+param[4]+param[1]+ZZ)/param[5]+(param[3]/param[6]))) * // lambdas have to be greater than zero
(-4.0*exp((param[2]+param[4])/param[5]+(param[3]/param[6]))*(exp((2.0*param[1])/param[5]) - exp((2.0*ZZ)/param[5]))*param[5]*param[6]+exp((2.0*param[3])/param[6])*(param[5]-param[6] + (exp((2.0*param[4])/param[5])*(param[5]+param[6])))*((exp((2.0*ZZ)/param[5])*(param[5]-param[6])) + (exp((2.0*(param[2]+param[1]))/param[5])*(param[5]+param[6]))) - 4.0*((param[5]*cosh(param[4]/param[5]))-(param[6]*sinh(param[4]/param[5])))*((param[5]*cosh((param[2]+param[1]-ZZ)/param[5])) - (param[6]*sinh((param[2]+param[1]-ZZ)/param[5])))*(cosh((param[2]+param[4]+param[1]+ZZ)/param[5]) + sinh((param[2]+param[4]+param[1]+ZZ)/param[5]))))/N1; for(unsigned int i(5); i<7; i++){
} else if (ZZ < param[1]+param[2]+param[3]) { assert(param[i]!=0.);
BBz = (param[0]*param[5]*(2.0*param[6]*cosh((param[2]+param[3]+param[1]-ZZ)/param[6])*sinh(param[4]/param[5]) + (param[5]+param[6])*sinh(param[2]/param[5]-(param[2]+param[1]-ZZ)/param[6]) - (param[5]-param[6])*sinh(param[2]/param[5]+(param[2]+param[1]-ZZ)/param[6]) + 2.0*param[5]*cosh(param[4]/param[5])*sinh((param[2]+param[3]+param[1]-ZZ)/param[6])))/N2; }
fInterfaces[0]=param[1];
fInterfaces[1]=param[1]+param[2];
fInterfaces[2]=param[1]+param[2]+param[3];
fInterfaces[3]=param[1]+param[2]+param[3]+param[4];
// Calculate the coefficients of the exponentials
double B0(param[0]), dd(param[1]), d1(param[2]), d2(param[3]), d3(param[4]), l1(param[5]), l2(param[6]);
double N0(8.0*(l1*l2*cosh(d2/l2)*sinh((d1+d3)/l1)+(l1*l1*cosh(d1/l1)*cosh(d3/l1)+l2*l2*sinh(d1/l1)*sinh(d3/l1))*sinh(d2/l2)));
fCoeff[0]=B0*exp((dd-d3)/l1-d2/l2)*(-4.0*exp(d3/l1+d2/l2)*l1*l2-exp(d1/l1)*(l1-l2)*(l1+exp(2.0*d3/l1)*(l1-l2)+l2) + \
exp(d1/l1+2.0*d2/l2)*(l1+l2)*(l1-l2+exp(2.0*d3/l1)*(l1+l2)))/N0;
fCoeff[1]=B0*exp(-(d1+d3+dd)/l1-d2/l2)*((1.0+exp(2.0*d3/l1))*(-1.0+exp(2.0*d2/l2))*l1*l1-2.0*(1.0-2.0*exp((d1+d3)/l1+d2/l2) + \
exp(2.0*d2/l2))*l1*l2-(-1.0+exp(2.0*d3/l1))*(-1.0+exp(2.0*d2/l2))*l2*l2)/N0;
fCoeff[2]=2.0*B0*exp(-(d1+d3)/l1+(d1+dd)/l2)*l1*(-exp(d3/l1)*(l1+exp(2.0*d1/l1)*(l1-l2)+l2) + \
exp(d1/l1+d2/l2)*(l1-l2+exp(2.0*d3/l1)*(l1+l2)))/N0;
fCoeff[3]=2.0*B0*exp(-(d1+d3)/l1-(d1+d2+dd)/l2)*l1*(-exp(d1/l1)*(l1+exp(2.0*d3/l1)*(l1-l2)+l2) + \
exp(d3/l1+d2/l2)*(l1-l2+exp(2.0*d1/l1)*(l1+l2)))/N0;
fCoeff[4]=B0*exp((d2+dd)/l1-d2/l2)*((1.0+exp(2.0*d1/l1))*(-1.0+exp(2.0*d2/l2))*l1*l1-2.0*(1.0-2.0*exp((d1+d3)/l1+d2/l2) + \
exp(2.0*d2/l2))*l1*l2-(-1.0+exp(2.0*d1/l1))*(-1.0+exp(2.0*d2/l2))*l2*l2)/N0;
fCoeff[5]=B0*exp(-(2.0*d1+d2+d3+dd)/l1-d2/l2)*(-4.0*exp(d1/l1+d2/l2)*l1*l2+exp(d3/l1)*(-l1*l1-exp(2.0*d1/l1)*(l1-l2)*(l1-l2)+l2*l2) + \
exp(d3/l1+2.0*d2/l2)*(l1*l1-l2*l2+exp(2.0*d1/l1)*(l1+l2)*(l1+l2)))/N0;
// none of the coefficients should be zero
for(unsigned int i(0); i<6; i++)
assert(fCoeff[i]);
SetBmin();
}
double TLondon1D_3LS::GetBofZ(double ZZ) const
{
if(ZZ < 0. || ZZ < fInterfaces[0] || ZZ > fInterfaces[3])
return fParam[0];
if (ZZ < fInterfaces[1]) {
return fCoeff[0]*exp(-ZZ/fParam[5])+fCoeff[1]*exp(ZZ/fParam[5]);
} else if (ZZ < fInterfaces[2]) {
return fCoeff[2]*exp(-ZZ/fParam[6])+fCoeff[3]*exp(ZZ/fParam[6]);
} else { } else {
BBz = (param[0]*exp(-((2.0*param[2]+param[3]+param[4]+param[1]+ZZ)/param[5])-param[3]/param[6]) * (4.0*exp(param[2]/param[5]+param[3]/param[6])*param[5]*param[6]*((-1.0)*exp(2.0*ZZ/param[5]) + cosh(2.0*(param[2]+param[3]+param[4]+param[1])/param[5])+sinh(2.0*(param[2]+param[3]+param[4]+param[1])/param[5])) + 4.0*exp(((2.0*param[2]+param[3]+param[4]+param[1]+ZZ)/param[5]) + ((2.0*param[3])/param[6]))*(param[5]*cosh(param[2]/param[5]) + param[6]*sinh(param[2]/param[5]))*(param[5]*cosh((param[2]+param[3]+param[1]-ZZ)/param[5]) - param[6]*sinh((param[2]+param[3]+param[1]-ZZ)/param[5])) - 4.0*(param[5]*cosh(param[2]/param[5])-param[6]*sinh(param[2]/param[5])) * (param[5]*cosh((param[2]+param[3]+param[1]-ZZ)/param[5]) + param[6]*sinh((param[2]+param[3]+param[1]-ZZ)/param[5]))*(cosh((2.0*param[2]+param[3]+param[4]+param[1]+ZZ)/param[5]) + sinh((2.0*param[2]+param[3]+param[4]+param[1]+ZZ)/param[5]))))/N3; return fCoeff[4]*exp(-ZZ/fParam[5])+fCoeff[5]*exp(ZZ/fParam[5]);
}
fBZ.push_back(BBz);
} }
} }
//------------------ double TLondon1D_3LS::GetBmax() const
// Constructor of the TLondon1D_4L class {
// 1D-London screening in a thin superconducting film, four layers, four lambdas // return applied field
// Parameters: Bext[G], deadlayer[nm], thickness1[nm], thickness2[nm], thickness3[nm], thickness4[nm], return fParam[0];
// lambda1[nm], lambda2[nm], lambda3[nm], lambda4[nm]
//------------------
TLondon1D_4L::TLondon1D_4L(unsigned int steps, const vector<double> &param) {
double N1((param[6]+exp(2.0*param[2]/param[6])*(param[6]-param[7])+param[7])*(-1.0*param[9]*cosh(param[5]/param[9])*(param[8]*cosh(param[4]/param[8])-param[7]*sinh(param[4]/param[8]))+param[8]*(param[7]*cosh(param[4]/param[8])-param[8]*sinh(param[4]/param[8]))*sinh(param[5]/param[9]))+exp(2.0*param[3]/param[7])*(param[6]-param[7]+exp(2.0*param[2]/param[6])*(param[6]+param[7]))*(param[9]*cosh(param[5]/param[9])*(param[8]*cosh(param[4]/param[8])+param[7]*sinh(param[4]/param[8]))+param[8]*(param[7]*cosh(param[4]/param[8])+param[8]*sinh(param[4]/param[8]))*sinh(param[5]/param[9])));
double N11(param[9]*cosh(param[5]/param[9])*(param[8]*cosh(param[4]/param[8])*(param[7]*cosh(param[3]/param[7])-param[6]*sinh(param[3]/param[7]))+param[7]*(-1.0*param[6]*cosh(param[3]/param[7])+param[7]*sinh(param[3]/param[7]))*sinh(param[4]/param[8]))+param[8]*(param[7]*cosh(param[4]/param[8])*(-1.0*param[6]*cosh(param[3]/param[7])+param[7]*sinh(param[3]/param[7]))+param[8]*(param[7]*cosh(param[3]/param[7])-param[6]*sinh(param[3]/param[7]))*sinh(param[4]/param[8]))*sinh(param[5]/param[9]));
double N12(exp(2.0*(param[2]+param[1])/param[6])*(param[9]*cosh(param[5]/param[9])*(param[8]*cosh(param[4]/param[8])*(param[7]*cosh(param[3]/param[7])+param[6]*sinh(param[3]/param[7]))+param[7]*(param[6]*cosh(param[3]/param[7])+param[7]*sinh(param[3]/param[7]))*sinh(param[4]/param[8]))+param[8]*(param[7]*cosh(param[4]/param[8])*(param[6]*cosh(param[3]/param[7])+param[7]*sinh(param[3]/param[7]))+param[8]*(param[7]*cosh(param[3]/param[7])+param[6]*sinh(param[3]/param[7]))*sinh(param[4]/param[8]))*sinh(param[5]/param[9])));
double N2((param[6]+param[7]+(param[6]-param[7])*exp(2.0*param[2]/param[6]))*(-1.0*param[9]*cosh(param[5]/param[9])*(param[8]*cosh(param[4]/param[8])-param[7]*sinh(param[4]/param[8]))+param[8]*(param[7]*cosh(param[4]/param[8])-param[8]*sinh(param[4]/param[8]))*sinh(param[5]/param[9]))+exp(2.0*param[3]/param[7])*(param[6]-param[7]+exp(2.0*param[2]/param[6])*(param[6]+param[7]))*(param[9]*cosh(param[5]/param[9])*(param[8]*cosh(param[4]/param[8])+param[7]*sinh(param[4]/param[8]))+param[8]*(param[7]*cosh(param[4]/param[8])+param[8]*sinh(param[4]/param[8]))*sinh(param[5]/param[9])));
double N21(exp(param[3]/param[7])*param[8]*param[9]*(param[6]*cosh(param[2]/param[6])+param[7]*sinh(param[2]/param[6]))+param[6]*param[9]*cosh(param[5]/param[9])*(-1.0*param[8]*cosh(param[4]/param[8])+param[7]*sinh(param[4]/param[8]))+param[6]*param[8]*(param[7]*cosh(param[4]/param[8])-param[8]*sinh(param[4]/param[8]))*sinh(param[5]/param[9]));
double N22(exp((2.0*param[2]+param[3]+2.0*param[1])/param[7])*(-1.0*param[6]*param[8]*param[9]*cosh(param[2]/param[6])+param[7]*param[8]*param[9]*sinh(param[2]/param[6])+exp(param[3]/param[7])*param[6]*param[9]*cosh(param[5]/param[9])*(param[8]*cosh(param[4]/param[8])+param[7]*sinh(param[4]/param[8]))+exp(param[3]/param[7])*param[6]*param[8]*(param[7]*cosh(param[4]/param[8])+param[8]*sinh(param[4]/param[8]))*sinh(param[5]/param[9])));
double N3(2.0*((param[6]+exp(2.0*param[2]/param[6])*(param[6]-param[7])+param[7])*(-1.0*param[9]*cosh(param[5]/param[9])*(param[8]*cosh(param[4]/param[8])-param[7]*sinh(param[4]/param[8]))+param[8]*(param[7]*cosh(param[4]/param[8])-param[8]*sinh(param[4]/param[8]))*sinh(param[5]/param[9]))+exp(2.0*param[3]/param[7])*(param[6]-param[7]+exp(2.0*param[2]/param[6])*(param[6]+param[7]))*(param[9]*cosh(param[5]/param[9])*(param[8]*cosh(param[4]/param[8])+param[7]*sinh(param[4]/param[8]))+param[8]*(param[7]*cosh(param[4]/param[8])+param[8]*sinh(param[4]/param[8]))*sinh(param[5]/param[9]))));
double N4(4.0*((param[6]+exp(2.0*param[2]/param[6])*(param[6]-param[7])+param[7])*(-1.0*param[9]*cosh(param[5]/param[9])*(param[8]*cosh(param[4]/param[8])-param[7]*sinh(param[4]/param[8]))+param[8]*(param[7]*cosh(param[4]/param[8])-param[8]*sinh(param[4]/param[8]))*sinh(param[5]/param[9]))+exp(2.0*param[3]/param[7])*(param[6]-param[7]+exp(2.0*param[2]/param[6])*(param[6]+param[7]))*(param[9]*cosh(param[5]/param[9])*(param[8]*cosh(param[4]/param[8])+param[7]*sinh(param[4]/param[8]))+param[8]*(param[7]*cosh(param[4]/param[8])+param[8]*sinh(param[4]/param[8]))*sinh(param[5]/param[9]))));
double N42(-1.0*param[6]*param[7]*param[8]+exp(param[5]/param[9])*(param[6]*cosh(param[2]/param[6])*(param[8]*sinh(param[3]/param[7])*(param[9]*cosh(param[4]/param[8])+param[8]*sinh(param[4]/param[8]))+param[7]*cosh(param[3]/param[7])*(param[8]*cosh(param[4]/param[8])+param[9]*sinh(param[4]/param[8])))+param[7]*sinh(param[2]/param[6])*(param[8]*cosh(param[3]/param[7])*(param[9]*cosh(param[4]/param[8])+param[8]*sinh(param[4]/param[8]))+param[7]*sinh(param[3]/param[7])*(param[8]*cosh(param[4]/param[8])+param[9]*sinh(param[4]/param[8])))));
fDZ = (param[2]+param[3]+param[4]+param[5])/double(steps);
double ZZ, BBz;
for (unsigned int j(0); j<steps; j++) {
ZZ = param[1] + (double)j*fDZ;
fZ.push_back(ZZ);
if (ZZ < param[1]+param[2]) {
BBz = (2.0*param[0]*exp(-(param[1]+ZZ)/param[6]+param[3]/param[7])*(-1.0*exp(param[2]/param[6])*(exp(2.0*param[1]/param[6])-exp(2.0*ZZ/param[6]))*param[7]*param[8]*param[9]-exp(2.0*ZZ/param[6])*N11+N12))/N1;
} else if (ZZ < param[1]+param[2]+param[3]) {
BBz = (2.0*param[0]*exp(param[2]/param[6]-(param[2]+param[1]+ZZ)/param[7])*(exp(2.0*ZZ/param[7])*N21+N22))/N2;
} else if (ZZ < param[1]+param[2]+param[3]+param[4]) {
BBz = (param[0]*exp(-1.0*(param[2]+param[3]+param[1]+ZZ)/param[8]-param[5]/param[9])*(2.0*exp(param[2]/param[6]+param[3]/param[7]+(2.0*param[2]+2.0*param[3]+param[4]+2.0*param[1])/param[8])*param[6]*param[7]*(param[9]-param[8]+exp(2.0*param[5]/param[9])*(param[8]+param[9]))+4.0*exp(param[2]/param[6]+param[3]/param[7]-param[4]/param[8]+param[5]/param[9])*(-1.0*exp((2.0*param[2]+2.0*param[3]+param[4]+2.0*param[1])/param[8])*param[9]*(param[7]*sinh(param[2]/param[6])*(-1.0*param[8]*cosh(param[3]/param[7])+param[7]*sinh(param[3]/param[7]))+param[6]*cosh(param[2]/param[6])*(param[7]*cosh(param[3]/param[7])-param[8]*sinh(param[3]/param[7])))+exp(2.0*ZZ/param[8])*(exp(param[4]/param[8])*param[9]*(param[7]*sinh(param[2]/param[6])*(param[8]*cosh(param[3]/param[7])+param[7]*sinh(param[3]/param[7]))+param[6]*cosh(param[2]/param[6])*(param[7]*cosh(param[3]/param[7])+param[8]*sinh(param[3]/param[7])))+param[6]*param[7]*(-1.0*param[9]*cosh(param[5]/param[9])+param[8]*sinh(param[5]/param[9]))))))/N3;
} else {
BBz = (param[0]*exp(-1.0*(param[2]+param[3]+param[4]+param[1]+ZZ)/param[9])*(-1.0*exp(-1.0*param[4]/param[8]+2.0*(param[2]+param[3]+param[4]+param[1])/param[9])*((-1.0+exp(2.0*param[2]/param[6]))*param[7]*(exp(2.0*param[4]/param[8])*(param[8]-param[7]+exp(2.0*param[3]/param[7])*(param[7]+param[8]))*(param[8]-param[9])+exp(2.0*param[3]/param[7])*(param[7]-param[8])*(param[8]+param[9])-(param[7]+param[8])*(param[8]+param[9]))+param[6]*(-8.0*exp(param[2]/param[6]+param[3]/param[7]+param[4]/param[8]+param[5]/param[9])*param[7]*param[8]+(1.0+exp(2.0*param[2]/param[6]))*(-1.0+exp(2.0*param[3]/param[7]))*param[8]*(-1.0*param[8]+exp(2.0*param[4]/param[8])*(param[8]-param[9])-param[9])+(1.0+exp(2.0*param[2]/param[6]))*(1.0+exp(2.0*param[3]/param[7]))*param[7]*(param[8]+exp(2.0*param[4]/param[8])*(param[8]-param[9])+param[9])))+8.0*exp(param[2]/param[6]+param[3]/param[7]-(param[5]-2.0*ZZ)/param[9])*N42))/N4;
} }
fBZ.push_back(BBz);
double TLondon1D_3LS::GetBmin() const
{
// return field minimum
return fMinB;
} }
void TLondon1D_3LS::SetBmin()
{
double b_a(fCoeff[1]/fCoeff[0]);
assert (b_a>0.);
double minZ;
// check if the minimum is in the first layer
minZ=-0.5*fParam[5]*log(b_a);
if (minZ > fInterfaces[0] && minZ <= fInterfaces[1]) {
fMinTag = 1;
fMinZ = minZ;
fMinB = GetBofZ(minZ);
return;
} }
double d_c(fCoeff[3]/fCoeff[2]);
assert (d_c>0.);
// check if the minimum is in the second layer
minZ=-0.5*fParam[6]*log(d_c);
if (minZ > fInterfaces[1] && minZ <= fInterfaces[2]) {
fMinTag = 2;
fMinZ = minZ;
fMinB = GetBofZ(minZ);
return;
}
double f_e(fCoeff[5]/fCoeff[4]);
assert (f_e>0.);
// check if the minimum is in the third layer
minZ=-0.5*fParam[5]*log(f_e);
if (minZ > fInterfaces[2] && minZ <= fInterfaces[3]) {
fMinTag = 3;
fMinZ = minZ;
fMinB = GetBofZ(minZ);
return;
}
assert(fMinZ > 0. && fMinB > 0.);
return;
}
vector< pair<double, double> > TLondon1D_3LS::GetInverseAndDerivative(double BB) const
{
vector< pair<double, double> > inv;
if(BB <= fMinB || BB > fParam[0])
return inv;
double inverse[4];
pair<double, double> invAndDerivative;
switch(fMinTag)
{
case 1:
inverse[0]=fParam[5]*log((BB-sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]))/(2.0*fCoeff[1]));
inverse[1]=fParam[5]*log((BB+sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]))/(2.0*fCoeff[1]));
inverse[2]=fParam[6]*log((BB+sqrt(BB*BB-4.0*fCoeff[2]*fCoeff[3]))/(2.0*fCoeff[3]));
inverse[3]=fParam[5]*log((BB+sqrt(BB*BB-4.0*fCoeff[4]*fCoeff[5]))/(2.0*fCoeff[5]));
if(inverse[0] > fInterfaces[0] && inverse[0] < fMinZ) {
invAndDerivative.first = inverse[0];
invAndDerivative.second = -fParam[5]/sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]);
inv.push_back(invAndDerivative);
}
if(inverse[1] > fMinZ && inverse[1] <= fInterfaces[1]) {
invAndDerivative.first = inverse[1];
invAndDerivative.second = +fParam[5]/sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]);
inv.push_back(invAndDerivative);
}
if(inverse[2] > fInterfaces[1] && inverse[2] <= fInterfaces[2]) {
invAndDerivative.first = inverse[2];
invAndDerivative.second = +fParam[6]/sqrt(BB*BB-4.0*fCoeff[2]*fCoeff[3]);
inv.push_back(invAndDerivative);
}
if(inverse[3] > fInterfaces[2] && inverse[3] <= fInterfaces[3]) {
invAndDerivative.first = inverse[3];
invAndDerivative.second = +fParam[5]/sqrt(BB*BB-4.0*fCoeff[4]*fCoeff[5]);
inv.push_back(invAndDerivative);
}
break;
case 2:
inverse[0]=fParam[5]*log((BB-sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]))/(2.0*fCoeff[1]));
inverse[1]=fParam[6]*log((BB-sqrt(BB*BB-4.0*fCoeff[2]*fCoeff[3]))/(2.0*fCoeff[3]));
inverse[2]=fParam[6]*log((BB+sqrt(BB*BB-4.0*fCoeff[2]*fCoeff[3]))/(2.0*fCoeff[3]));
inverse[3]=fParam[5]*log((BB+sqrt(BB*BB-4.0*fCoeff[4]*fCoeff[5]))/(2.0*fCoeff[5]));
if(inverse[0] > fInterfaces[0] && inverse[0] <= fInterfaces[1]) {
invAndDerivative.first = inverse[0];
invAndDerivative.second = -fParam[5]/sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]);
inv.push_back(invAndDerivative);
}
if(inverse[1] > fInterfaces[1] && inverse[1] < fMinZ) {
invAndDerivative.first = inverse[1];
invAndDerivative.second = -fParam[6]/sqrt(BB*BB-4.0*fCoeff[2]*fCoeff[3]);
inv.push_back(invAndDerivative);
}
if(inverse[2] > fMinZ && inverse[2] <= fInterfaces[2]) {
invAndDerivative.first = inverse[2];
invAndDerivative.second = +fParam[6]/sqrt(BB*BB-4.0*fCoeff[2]*fCoeff[3]);
inv.push_back(invAndDerivative);
}
if(inverse[3] > fInterfaces[2] && inverse[3] <= fInterfaces[3]) {
invAndDerivative.first = inverse[3];
invAndDerivative.second = +fParam[5]/sqrt(BB*BB-4.0*fCoeff[4]*fCoeff[5]);
inv.push_back(invAndDerivative);
}
break;
case 3:
inverse[0]=fParam[5]*log((BB-sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]))/(2.0*fCoeff[1]));
inverse[1]=fParam[6]*log((BB-sqrt(BB*BB-4.0*fCoeff[2]*fCoeff[3]))/(2.0*fCoeff[3]));
inverse[2]=fParam[5]*log((BB-sqrt(BB*BB-4.0*fCoeff[4]*fCoeff[5]))/(2.0*fCoeff[5]));
inverse[3]=fParam[5]*log((BB+sqrt(BB*BB-4.0*fCoeff[4]*fCoeff[5]))/(2.0*fCoeff[5]));
if(inverse[0] > fInterfaces[0] && inverse[0] <= fInterfaces[1]) {
invAndDerivative.first = inverse[0];
invAndDerivative.second = -fParam[5]/sqrt(BB*BB-4.0*fCoeff[0]*fCoeff[1]);
inv.push_back(invAndDerivative);
}
if(inverse[1] > fInterfaces[1] && inverse[1] <= fInterfaces[2]) {
invAndDerivative.first = inverse[1];
invAndDerivative.second = -fParam[6]/sqrt(BB*BB-4.0*fCoeff[2]*fCoeff[3]);
inv.push_back(invAndDerivative);
}
if(inverse[2] > fInterfaces[2] && inverse[2] < fMinZ) {
invAndDerivative.first = inverse[2];
invAndDerivative.second = -fParam[5]/sqrt(BB*BB-4.0*fCoeff[4]*fCoeff[5]);
inv.push_back(invAndDerivative);
}
if(inverse[3] > fMinZ && inverse[3] <= fInterfaces[3]) {
invAndDerivative.first = inverse[3];
invAndDerivative.second = +fParam[5]/sqrt(BB*BB-4.0*fCoeff[4]*fCoeff[5]);
inv.push_back(invAndDerivative);
}
break;
default:
break;
}
return inv;
}
// //------------------
// // Constructor of the TLondon1D_4L class
// // 1D-London screening in a thin superconducting film, four layers, four lambdas
// // Parameters: Bext[G], deadlayer[nm], thickness1[nm], thickness2[nm], thickness3[nm], thickness4[nm],
// // lambda1[nm], lambda2[nm], lambda3[nm], lambda4[nm]
// //------------------
//
// TLondon1D_4L::TLondon1D_4L(unsigned int steps, const vector<double> &param) {
//
// double N1((param[6]+exp(2.0*param[2]/param[6])*(param[6]-param[7])+param[7])*(-1.0*param[9]*cosh(param[5]/param[9])*(param[8]*cosh(param[4]/param[8])-param[7]*sinh(param[4]/param[8]))+param[8]*(param[7]*cosh(param[4]/param[8])-param[8]*sinh(param[4]/param[8]))*sinh(param[5]/param[9]))+exp(2.0*param[3]/param[7])*(param[6]-param[7]+exp(2.0*param[2]/param[6])*(param[6]+param[7]))*(param[9]*cosh(param[5]/param[9])*(param[8]*cosh(param[4]/param[8])+param[7]*sinh(param[4]/param[8]))+param[8]*(param[7]*cosh(param[4]/param[8])+param[8]*sinh(param[4]/param[8]))*sinh(param[5]/param[9])));
//
// double N11(param[9]*cosh(param[5]/param[9])*(param[8]*cosh(param[4]/param[8])*(param[7]*cosh(param[3]/param[7])-param[6]*sinh(param[3]/param[7]))+param[7]*(-1.0*param[6]*cosh(param[3]/param[7])+param[7]*sinh(param[3]/param[7]))*sinh(param[4]/param[8]))+param[8]*(param[7]*cosh(param[4]/param[8])*(-1.0*param[6]*cosh(param[3]/param[7])+param[7]*sinh(param[3]/param[7]))+param[8]*(param[7]*cosh(param[3]/param[7])-param[6]*sinh(param[3]/param[7]))*sinh(param[4]/param[8]))*sinh(param[5]/param[9]));
//
// double N12(exp(2.0*(param[2]+param[1])/param[6])*(param[9]*cosh(param[5]/param[9])*(param[8]*cosh(param[4]/param[8])*(param[7]*cosh(param[3]/param[7])+param[6]*sinh(param[3]/param[7]))+param[7]*(param[6]*cosh(param[3]/param[7])+param[7]*sinh(param[3]/param[7]))*sinh(param[4]/param[8]))+param[8]*(param[7]*cosh(param[4]/param[8])*(param[6]*cosh(param[3]/param[7])+param[7]*sinh(param[3]/param[7]))+param[8]*(param[7]*cosh(param[3]/param[7])+param[6]*sinh(param[3]/param[7]))*sinh(param[4]/param[8]))*sinh(param[5]/param[9])));
//
// double N2((param[6]+param[7]+(param[6]-param[7])*exp(2.0*param[2]/param[6]))*(-1.0*param[9]*cosh(param[5]/param[9])*(param[8]*cosh(param[4]/param[8])-param[7]*sinh(param[4]/param[8]))+param[8]*(param[7]*cosh(param[4]/param[8])-param[8]*sinh(param[4]/param[8]))*sinh(param[5]/param[9]))+exp(2.0*param[3]/param[7])*(param[6]-param[7]+exp(2.0*param[2]/param[6])*(param[6]+param[7]))*(param[9]*cosh(param[5]/param[9])*(param[8]*cosh(param[4]/param[8])+param[7]*sinh(param[4]/param[8]))+param[8]*(param[7]*cosh(param[4]/param[8])+param[8]*sinh(param[4]/param[8]))*sinh(param[5]/param[9])));
//
// double N21(exp(param[3]/param[7])*param[8]*param[9]*(param[6]*cosh(param[2]/param[6])+param[7]*sinh(param[2]/param[6]))+param[6]*param[9]*cosh(param[5]/param[9])*(-1.0*param[8]*cosh(param[4]/param[8])+param[7]*sinh(param[4]/param[8]))+param[6]*param[8]*(param[7]*cosh(param[4]/param[8])-param[8]*sinh(param[4]/param[8]))*sinh(param[5]/param[9]));
//
// double N22(exp((2.0*param[2]+param[3]+2.0*param[1])/param[7])*(-1.0*param[6]*param[8]*param[9]*cosh(param[2]/param[6])+param[7]*param[8]*param[9]*sinh(param[2]/param[6])+exp(param[3]/param[7])*param[6]*param[9]*cosh(param[5]/param[9])*(param[8]*cosh(param[4]/param[8])+param[7]*sinh(param[4]/param[8]))+exp(param[3]/param[7])*param[6]*param[8]*(param[7]*cosh(param[4]/param[8])+param[8]*sinh(param[4]/param[8]))*sinh(param[5]/param[9])));
//
// double N3(2.0*((param[6]+exp(2.0*param[2]/param[6])*(param[6]-param[7])+param[7])*(-1.0*param[9]*cosh(param[5]/param[9])*(param[8]*cosh(param[4]/param[8])-param[7]*sinh(param[4]/param[8]))+param[8]*(param[7]*cosh(param[4]/param[8])-param[8]*sinh(param[4]/param[8]))*sinh(param[5]/param[9]))+exp(2.0*param[3]/param[7])*(param[6]-param[7]+exp(2.0*param[2]/param[6])*(param[6]+param[7]))*(param[9]*cosh(param[5]/param[9])*(param[8]*cosh(param[4]/param[8])+param[7]*sinh(param[4]/param[8]))+param[8]*(param[7]*cosh(param[4]/param[8])+param[8]*sinh(param[4]/param[8]))*sinh(param[5]/param[9]))));
//
// double N4(4.0*((param[6]+exp(2.0*param[2]/param[6])*(param[6]-param[7])+param[7])*(-1.0*param[9]*cosh(param[5]/param[9])*(param[8]*cosh(param[4]/param[8])-param[7]*sinh(param[4]/param[8]))+param[8]*(param[7]*cosh(param[4]/param[8])-param[8]*sinh(param[4]/param[8]))*sinh(param[5]/param[9]))+exp(2.0*param[3]/param[7])*(param[6]-param[7]+exp(2.0*param[2]/param[6])*(param[6]+param[7]))*(param[9]*cosh(param[5]/param[9])*(param[8]*cosh(param[4]/param[8])+param[7]*sinh(param[4]/param[8]))+param[8]*(param[7]*cosh(param[4]/param[8])+param[8]*sinh(param[4]/param[8]))*sinh(param[5]/param[9]))));
//
// double N42(-1.0*param[6]*param[7]*param[8]+exp(param[5]/param[9])*(param[6]*cosh(param[2]/param[6])*(param[8]*sinh(param[3]/param[7])*(param[9]*cosh(param[4]/param[8])+param[8]*sinh(param[4]/param[8]))+param[7]*cosh(param[3]/param[7])*(param[8]*cosh(param[4]/param[8])+param[9]*sinh(param[4]/param[8])))+param[7]*sinh(param[2]/param[6])*(param[8]*cosh(param[3]/param[7])*(param[9]*cosh(param[4]/param[8])+param[8]*sinh(param[4]/param[8]))+param[7]*sinh(param[3]/param[7])*(param[8]*cosh(param[4]/param[8])+param[9]*sinh(param[4]/param[8])))));
//
// fDZ = (param[2]+param[3]+param[4]+param[5])/double(steps);
// double ZZ, BBz;
//
// for (unsigned int j(0); j<steps; j++) {
// ZZ = param[1] + (double)j*fDZ;
// fZ.push_back(ZZ);
// if (ZZ < param[1]+param[2]) {
// BBz = (2.0*param[0]*exp(-(param[1]+ZZ)/param[6]+param[3]/param[7])*(-1.0*exp(param[2]/param[6])*(exp(2.0*param[1]/param[6])-exp(2.0*ZZ/param[6]))*param[7]*param[8]*param[9]-exp(2.0*ZZ/param[6])*N11+N12))/N1;
// } else if (ZZ < param[1]+param[2]+param[3]) {
// BBz = (2.0*param[0]*exp(param[2]/param[6]-(param[2]+param[1]+ZZ)/param[7])*(exp(2.0*ZZ/param[7])*N21+N22))/N2;
// } else if (ZZ < param[1]+param[2]+param[3]+param[4]) {
// BBz = (param[0]*exp(-1.0*(param[2]+param[3]+param[1]+ZZ)/param[8]-param[5]/param[9])*(2.0*exp(param[2]/param[6]+param[3]/param[7]+(2.0*param[2]+2.0*param[3]+param[4]+2.0*param[1])/param[8])*param[6]*param[7]*(param[9]-param[8]+exp(2.0*param[5]/param[9])*(param[8]+param[9]))+4.0*exp(param[2]/param[6]+param[3]/param[7]-param[4]/param[8]+param[5]/param[9])*(-1.0*exp((2.0*param[2]+2.0*param[3]+param[4]+2.0*param[1])/param[8])*param[9]*(param[7]*sinh(param[2]/param[6])*(-1.0*param[8]*cosh(param[3]/param[7])+param[7]*sinh(param[3]/param[7]))+param[6]*cosh(param[2]/param[6])*(param[7]*cosh(param[3]/param[7])-param[8]*sinh(param[3]/param[7])))+exp(2.0*ZZ/param[8])*(exp(param[4]/param[8])*param[9]*(param[7]*sinh(param[2]/param[6])*(param[8]*cosh(param[3]/param[7])+param[7]*sinh(param[3]/param[7]))+param[6]*cosh(param[2]/param[6])*(param[7]*cosh(param[3]/param[7])+param[8]*sinh(param[3]/param[7])))+param[6]*param[7]*(-1.0*param[9]*cosh(param[5]/param[9])+param[8]*sinh(param[5]/param[9]))))))/N3;
// } else {
// BBz = (param[0]*exp(-1.0*(param[2]+param[3]+param[4]+param[1]+ZZ)/param[9])*(-1.0*exp(-1.0*param[4]/param[8]+2.0*(param[2]+param[3]+param[4]+param[1])/param[9])*((-1.0+exp(2.0*param[2]/param[6]))*param[7]*(exp(2.0*param[4]/param[8])*(param[8]-param[7]+exp(2.0*param[3]/param[7])*(param[7]+param[8]))*(param[8]-param[9])+exp(2.0*param[3]/param[7])*(param[7]-param[8])*(param[8]+param[9])-(param[7]+param[8])*(param[8]+param[9]))+param[6]*(-8.0*exp(param[2]/param[6]+param[3]/param[7]+param[4]/param[8]+param[5]/param[9])*param[7]*param[8]+(1.0+exp(2.0*param[2]/param[6]))*(-1.0+exp(2.0*param[3]/param[7]))*param[8]*(-1.0*param[8]+exp(2.0*param[4]/param[8])*(param[8]-param[9])-param[9])+(1.0+exp(2.0*param[2]/param[6]))*(1.0+exp(2.0*param[3]/param[7]))*param[7]*(param[8]+exp(2.0*param[4]/param[8])*(param[8]-param[9])+param[9])))+8.0*exp(param[2]/param[6]+param[3]/param[7]-(param[5]-2.0*ZZ)/param[9])*N42))/N4;
// }
// fBZ.push_back(BBz);
// }
// }

View File

@ -22,9 +22,12 @@ ClassImp(TLondon1D1L)
ClassImp(TLondon1D2L) ClassImp(TLondon1D2L)
ClassImp(TLondon1D3L) ClassImp(TLondon1D3L)
ClassImp(TLondon1D3LS) ClassImp(TLondon1D3LS)
ClassImp(TLondon1D4L) // ClassImp(TLondon1D4L)
ClassImp(TLondon1D3LSub) ClassImp(TLondon1D3LSub)
ClassImp(TLondon1D3Lestimate)
//------------------ //------------------
// Destructor of the TLondon1DHS/1L/2L/3L/3LS classes -- cleaning up // Destructor of the TLondon1DHS/1L/2L/3L/3LS classes -- cleaning up
@ -85,16 +88,16 @@ TLondon1D3LS::~TLondon1D3LS() {
fPofT = 0; fPofT = 0;
} }
TLondon1D4L::~TLondon1D4L() { // TLondon1D4L::~TLondon1D4L() {
fPar.clear(); // fPar.clear();
fParForBofZ.clear(); // fParForBofZ.clear();
fParForPofB.clear(); // fParForPofB.clear();
fParForPofT.clear(); // fParForPofT.clear();
delete fImpProfile; // delete fImpProfile;
fImpProfile = 0; // fImpProfile = 0;
delete fPofT; // delete fPofT;
fPofT = 0; // fPofT = 0;
} // }
TLondon1D3LSub::~TLondon1D3LSub() { TLondon1D3LSub::~TLondon1D3LSub() {
fPar.clear(); fPar.clear();
@ -227,7 +230,7 @@ double TLondon1DHS::operator()(double t, const vector<double> &par) const {
fParForPofB[2] = par[1]; // energy fParForPofB[2] = par[1]; // energy
// fParForPofB[3] = par[3]; // deadlayer for convolution of field profile // fParForPofB[3] = par[3]; // deadlayer for convolution of field profile
TLondon1D_HS BofZ(fNSteps, fParForBofZ); TLondon1D_HS BofZ(fParForBofZ);
TPofBCalc PofB(BofZ, *fImpProfile, fParForPofB); TPofBCalc PofB(BofZ, *fImpProfile, fParForPofB);
fPofT->DoFFT(PofB); fPofT->DoFFT(PofB);
@ -367,7 +370,7 @@ double TLondon1D1L::operator()(double t, const vector<double> &par) const {
fParForPofB[2] = par[1]; // energy fParForPofB[2] = par[1]; // energy
TLondon1D_1L BofZ1(fNSteps, fParForBofZ); TLondon1D_1L BofZ1(fParForBofZ);
TPofBCalc PofB1(BofZ1, *fImpProfile, fParForPofB); TPofBCalc PofB1(BofZ1, *fImpProfile, fParForPofB);
fPofT->DoFFT(PofB1); fPofT->DoFFT(PofB1);
@ -524,7 +527,7 @@ double TLondon1D2L::operator()(double t, const vector<double> &par) const {
fImpProfile->WeightLayers(par[1], interfaces, weights); fImpProfile->WeightLayers(par[1], interfaces, weights);
} }
TLondon1D_2L BofZ2(fNSteps, fParForBofZ); TLondon1D_2L BofZ2(fParForBofZ);
TPofBCalc PofB2(BofZ2, *fImpProfile, fParForPofB); TPofBCalc PofB2(BofZ2, *fImpProfile, fParForPofB);
fPofT->DoFFT(PofB2); fPofT->DoFFT(PofB2);
@ -687,7 +690,7 @@ double TLondon1D3L::operator()(double t, const vector<double> &par) const {
fImpProfile->WeightLayers(par[1], interfaces, weights); fImpProfile->WeightLayers(par[1], interfaces, weights);
} }
TLondon1D_3L BofZ3(fNSteps, fParForBofZ); TLondon1D_3L BofZ3(fParForBofZ);
TPofBCalc PofB3(BofZ3, *fImpProfile, fParForPofB); TPofBCalc PofB3(BofZ3, *fImpProfile, fParForPofB);
fPofT->DoFFT(PofB3); fPofT->DoFFT(PofB3);
@ -836,7 +839,7 @@ double TLondon1D3LS::operator()(double t, const vector<double> &par) const {
fImpProfile->WeightLayers(par[1], interfaces, weights); fImpProfile->WeightLayers(par[1], interfaces, weights);
} }
TLondon1D_3LS BofZ3S(fNSteps, fParForBofZ); TLondon1D_3LS BofZ3S(fParForBofZ);
TPofBCalc PofB3S(BofZ3S, *fImpProfile, fParForPofB); TPofBCalc PofB3S(BofZ3S, *fImpProfile, fParForPofB);
fPofT->DoFFT(PofB3S); fPofT->DoFFT(PofB3S);
@ -854,169 +857,169 @@ double TLondon1D3LS::operator()(double t, const vector<double> &par) const {
} }
//------------------ // //------------------
// Constructor of the TLondon1D4L class -- reading available implantation profiles and // // Constructor of the TLondon1D4L class -- reading available implantation profiles and
// creates (a pointer to) the TPofTCalc object (with the FFT plan) // // creates (a pointer to) the TPofTCalc object (with the FFT plan)
//------------------ // //------------------
//
TLondon1D4L::TLondon1D4L() : fCalcNeeded(true), fFirstCall(true), fLastFourChanged(true) { // TLondon1D4L::TLondon1D4L() : fCalcNeeded(true), fFirstCall(true), fLastFourChanged(true) {
// read startup file // // read startup file
string startup_path_name("TFitPofB_startup.xml"); // string startup_path_name("TFitPofB_startup.xml");
//
TSAXParser *saxParser = new TSAXParser(); // TSAXParser *saxParser = new TSAXParser();
TFitPofBStartupHandler *startupHandler = new TFitPofBStartupHandler(); // TFitPofBStartupHandler *startupHandler = new TFitPofBStartupHandler();
saxParser->ConnectToHandler("TFitPofBStartupHandler", startupHandler); // saxParser->ConnectToHandler("TFitPofBStartupHandler", startupHandler);
int status (saxParser->ParseFile(startup_path_name.c_str())); // int status (saxParser->ParseFile(startup_path_name.c_str()));
// check for parse errors // // check for parse errors
if (status) { // error // if (status) { // error
cout << endl << "**WARNING** reading/parsing TFitPofB_startup.xml failed." << endl; // cout << endl << "**WARNING** reading/parsing TFitPofB_startup.xml failed." << endl;
} // }
//
fNSteps = startupHandler->GetNSteps(); // fNSteps = startupHandler->GetNSteps();
fWisdom = startupHandler->GetWisdomFile(); // fWisdom = startupHandler->GetWisdomFile();
string rge_path(startupHandler->GetDataPath()); // string rge_path(startupHandler->GetDataPath());
vector<string> energy_vec(startupHandler->GetEnergyList()); // vector<string> energy_vec(startupHandler->GetEnergyList());
//
fParForPofT.push_back(0.0); // fParForPofT.push_back(0.0);
fParForPofT.push_back(startupHandler->GetDeltat()); // fParForPofT.push_back(startupHandler->GetDeltat());
fParForPofT.push_back(startupHandler->GetDeltaB()); // fParForPofT.push_back(startupHandler->GetDeltaB());
//
fParForPofB.push_back(startupHandler->GetDeltat()); // fParForPofB.push_back(startupHandler->GetDeltat());
fParForPofB.push_back(startupHandler->GetDeltaB()); // fParForPofB.push_back(startupHandler->GetDeltaB());
fParForPofB.push_back(0.0); // fParForPofB.push_back(0.0);
//
TTrimSPData *x = new TTrimSPData(rge_path, energy_vec); // TTrimSPData *x = new TTrimSPData(rge_path, energy_vec);
fImpProfile = x; // fImpProfile = x;
x = 0; // x = 0;
delete x; // delete x;
//
TPofTCalc *y = new TPofTCalc(fWisdom, fParForPofT); // TPofTCalc *y = new TPofTCalc(fWisdom, fParForPofT);
fPofT = y; // fPofT = y;
y = 0; // y = 0;
delete y; // delete y;
//
// clean up // // clean up
if (saxParser) { // if (saxParser) {
delete saxParser; // delete saxParser;
saxParser = 0; // saxParser = 0;
} // }
if (startupHandler) { // if (startupHandler) {
delete startupHandler; // delete startupHandler;
startupHandler = 0; // startupHandler = 0;
} // }
} // }
//
//------------------ // //------------------
// TLondon1D4L-Method that calls the procedures to create B(z), p(B) and P(t) // // TLondon1D4L-Method that calls the procedures to create B(z), p(B) and P(t)
// It finally returns P(t) for a given t. // // It finally returns P(t) for a given t.
// Parameters: all the parameters for the function to be fitted through TLondon1D4L // // Parameters: all the parameters for the function to be fitted through TLondon1D4L
//------------------ // //------------------
//
double TLondon1D4L::operator()(double t, const vector<double> &par) const { // double TLondon1D4L::operator()(double t, const vector<double> &par) const {
//
assert(par.size() == 16); // assert(par.size() == 16);
//
if(t<0.0) // if(t<0.0)
return 0.0; // return 0.0;
//
// check if the function is called the first time and if yes, read in parameters // // check if the function is called the first time and if yes, read in parameters
//
if(fFirstCall){ // if(fFirstCall){
fPar = par; // fPar = par;
//
/* for (unsigned int i(0); i<fPar.size(); i++){ // /* for (unsigned int i(0); i<fPar.size(); i++){
cout << "fPar[" << i << "] = " << fPar[i] << endl; // cout << "fPar[" << i << "] = " << fPar[i] << endl;
} // }
*/ // */
for (unsigned int i(2); i<fPar.size(); i++){ // for (unsigned int i(2); i<fPar.size(); i++){
fParForBofZ.push_back(fPar[i]); // fParForBofZ.push_back(fPar[i]);
// cout << "fParForBofZ[" << i-2 << "] = " << fParForBofZ[i-2] << endl; // // cout << "fParForBofZ[" << i-2 << "] = " << fParForBofZ[i-2] << endl;
} // }
fFirstCall=false; // fFirstCall=false;
} // }
//
// check if any parameter has changed // // check if any parameter has changed
//
bool par_changed(false); // bool par_changed(false);
bool only_phase_changed(false); // bool only_phase_changed(false);
//
for (unsigned int i(0); i<fPar.size(); i++) { // for (unsigned int i(0); i<fPar.size(); i++) {
if( fPar[i]-par[i] ) { // if( fPar[i]-par[i] ) {
fPar[i] = par[i]; // fPar[i] = par[i];
par_changed = true; // par_changed = true;
if (i == 0) { // if (i == 0) {
only_phase_changed = true; // only_phase_changed = true;
} else { // } else {
only_phase_changed = false; // only_phase_changed = false;
} // }
if (i == fPar.size()-4 || i == fPar.size()-3 || i == fPar.size()-2 || i == fPar.size()-1) // if (i == fPar.size()-4 || i == fPar.size()-3 || i == fPar.size()-2 || i == fPar.size()-1)
fLastFourChanged = true; // fLastFourChanged = true;
} // }
} // }
//
if (par_changed) // if (par_changed)
fCalcNeeded = true; // fCalcNeeded = true;
//
// if model parameters have changed, recalculate B(z), P(B) and P(t) // // if model parameters have changed, recalculate B(z), P(B) and P(t)
//
if (fCalcNeeded) { // if (fCalcNeeded) {
//
fParForPofT[0] = par[0]; // phase // fParForPofT[0] = par[0]; // phase
//
if(!only_phase_changed) { // if(!only_phase_changed) {
//
// cout << " Parameters have changed, (re-)calculating p(B) and P(t) now..." << endl; // // cout << " Parameters have changed, (re-)calculating p(B) and P(t) now..." << endl;
//
for (unsigned int i(2); i<par.size(); i++) // for (unsigned int i(2); i<par.size(); i++)
fParForBofZ[i-2] = par[i]; // fParForBofZ[i-2] = par[i];
//
fParForPofB[2] = par[1]; // energy // fParForPofB[2] = par[1]; // energy
//
/* DEBUG --------------------------- // /* DEBUG ---------------------------
for(unsigned int i(0); i<fParForBofZ.size(); i++) { // for(unsigned int i(0); i<fParForBofZ.size(); i++) {
cout << "ParForBofZ[" << i << "] = " << fParForBofZ[i] << endl; // cout << "ParForBofZ[" << i << "] = " << fParForBofZ[i] << endl;
} // }
//
for(unsigned int i(0); i<fParForPofB.size(); i++) { // for(unsigned int i(0); i<fParForPofB.size(); i++) {
cout << "ParForPofB[" << i << "] = " << fParForPofB[i] << endl; // cout << "ParForPofB[" << i << "] = " << fParForPofB[i] << endl;
} // }
//
for(unsigned int i(0); i<fParForPofT.size(); i++) { // for(unsigned int i(0); i<fParForPofT.size(); i++) {
cout << "ParForPofT[" << i << "] = " << fParForPofT[i] << endl; // cout << "ParForPofT[" << i << "] = " << fParForPofT[i] << endl;
} // }
------------------------------------*/ // ------------------------------------*/
//
if(fLastFourChanged) { // if(fLastFourChanged) {
vector<double> interfaces; // vector<double> interfaces;
interfaces.push_back(par[3]+par[4]); // interfaces.push_back(par[3]+par[4]);
interfaces.push_back(par[3]+par[4]+par[5]); // interfaces.push_back(par[3]+par[4]+par[5]);
interfaces.push_back(par[3]+par[4]+par[5]+par[6]); // interfaces.push_back(par[3]+par[4]+par[5]+par[6]);
//
vector<double> weights; // vector<double> weights;
for(unsigned int i(par.size()-4); i<par.size(); i++) // for(unsigned int i(par.size()-4); i<par.size(); i++)
weights.push_back(par[i]); // weights.push_back(par[i]);
//
// cout << "Weighting has changed, re-calculating n(z) now..." << endl; // // cout << "Weighting has changed, re-calculating n(z) now..." << endl;
fImpProfile->WeightLayers(par[1], interfaces, weights); // fImpProfile->WeightLayers(par[1], interfaces, weights);
} // }
//
TLondon1D_4L BofZ4(fNSteps, fParForBofZ); // TLondon1D_4L BofZ4(fNSteps, fParForBofZ);
TPofBCalc PofB4(BofZ4, *fImpProfile, fParForPofB); // TPofBCalc PofB4(BofZ4, *fImpProfile, fParForPofB);
fPofT->DoFFT(PofB4); // fPofT->DoFFT(PofB4);
//
}/* else { // }/* else {
cout << "Only the phase parameter has changed, (re-)calculating P(t) now..." << endl; // cout << "Only the phase parameter has changed, (re-)calculating P(t) now..." << endl;
}*/ // }*/
//
fPofT->CalcPol(fParForPofT); // fPofT->CalcPol(fParForPofT);
//
fCalcNeeded = false; // fCalcNeeded = false;
fLastFourChanged = false; // fLastFourChanged = false;
} // }
//
return fPofT->Eval(t); // return fPofT->Eval(t);
//
} // }
//------------------ //------------------
// Constructor of the TLondon1D3LSub class -- reading available implantation profiles and // Constructor of the TLondon1D3LSub class -- reading available implantation profiles and
@ -1024,6 +1027,10 @@ double TLondon1D4L::operator()(double t, const vector<double> &par) const {
//------------------ //------------------
TLondon1D3LSub::TLondon1D3LSub() : fCalcNeeded(true), fFirstCall(true), fWeightsChanged(true) { TLondon1D3LSub::TLondon1D3LSub() : fCalcNeeded(true), fFirstCall(true), fWeightsChanged(true) {
// omp_set_nested(1);
// omp_set_dynamic(1);
// omp_set_num_threads(4);
// read startup file // read startup file
string startup_path_name("TFitPofB_startup.xml"); string startup_path_name("TFitPofB_startup.xml");
@ -1085,7 +1092,10 @@ double TLondon1D3LSub::operator()(double t, const vector<double> &par) const {
// check if the function is called the first time and if yes, read in parameters // check if the function is called the first time and if yes, read in parameters
//#pragma omp critical
//{
if(fFirstCall){ if(fFirstCall){
fPar = par; fPar = par;
/* for (unsigned int i(0); i<fPar.size(); i++){ /* for (unsigned int i(0); i<fPar.size(); i++){
@ -1099,6 +1109,7 @@ double TLondon1D3LSub::operator()(double t, const vector<double> &par) const {
fFirstCall=false; fFirstCall=false;
} }
// check if any parameter has changed // check if any parameter has changed
bool par_changed(false); bool par_changed(false);
@ -1164,7 +1175,7 @@ double TLondon1D3LSub::operator()(double t, const vector<double> &par) const {
fImpProfile->WeightLayers(par[1], interfaces, weights); fImpProfile->WeightLayers(par[1], interfaces, weights);
} }
TLondon1D_3L BofZ3(fNSteps, fParForBofZ); TLondon1D_3L BofZ3(fParForBofZ);
TPofBCalc PofB3(BofZ3, *fImpProfile, fParForPofB); TPofBCalc PofB3(BofZ3, *fImpProfile, fParForPofB);
// Add background contribution from the substrate // Add background contribution from the substrate
@ -1182,8 +1193,18 @@ double TLondon1D3LSub::operator()(double t, const vector<double> &par) const {
fCalcNeeded = false; fCalcNeeded = false;
fWeightsChanged = false; fWeightsChanged = false;
} }
//}
return fPofT->Eval(t); return fPofT->Eval(t);
} }
double TLondon1D3Lestimate::operator()(double z, const vector<double>& par) const {
TLondon1D_3L BofZ(par);
return BofZ.GetBofZ(z);
}

View File

@ -13,18 +13,189 @@
#include <cmath> #include <cmath>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <cassert>
/* USED FOR DEBUGGING----------------------------------- /* USED FOR DEBUGGING-----------------------------------
#include <cstdio> #include <cstdio>
#include <ctime> #include <ctime>
/-------------------------------------------------------*/ /-------------------------------------------------------*/
// Do not actually calculate P(B) but take it from a B and a P(B) vector of the same size
TPofBCalc::TPofBCalc( const vector<double>& b, const vector<double>& pb, double dt) {
assert(b.size() == pb.size() && b.size() >= 2);
fB = b;
fPB = pb;
vector<double>::const_iterator iter, iterB;
iterB = b.begin();
for(iter = pb.begin(); iter != pb.end(); iter++){
if(*iter != 0.0) {
fBmin = *iterB;
cout << fBmin << endl;
break;
}
iterB++;
}
for( ; iter != b.end(); iter++){
if(*iter == 0.0) {
fBmax = *(iterB-1);
cout << fBmax << endl;
break;
}
iterB++;
}
fDT = dt; // needed if a convolution should be done
fDB = b[1]-b[0];
cout << fDB << endl;
}
TPofBCalc::TPofBCalc( const string &type, const vector<double> &para ) : fDT(para[0]), fDB(para[1]) {
if (type == "skg"){ // skewed Gaussian
fBmin = 0.0;
fBmax = para[2]/gBar+10.0*fabs(para[4])/(2.0*pi*gBar);
double BB;
double expominus(para[3]*para[3]/(2.0*pi*pi*gBar*gBar));
double expoplus(para[4]*para[4]/(2.0*pi*pi*gBar*gBar));
double B0(para[2]/gBar);
double BmaxFFT(1.0/gBar/fDT);
for ( BB = 0.0 ; BB < B0 ; BB += fDB ) {
fB.push_back(BB);
fPB.push_back(exp(-(BB-B0)*(BB-B0)/expominus));
}
for ( ; BB < fBmax ; BB += fDB ) {
fB.push_back(BB);
fPB.push_back(exp(-(BB-B0)*(BB-B0)/expoplus));
}
unsigned int lastZerosStart(fB.size());
for ( ; BB <= BmaxFFT ; BB += fDB ) {
fB.push_back(BB);
fPB.push_back(0.0);
}
// make sure that we have an even number of elements in p(B) for FFT, so we do not have to care later
if (fB.size() % 2) {
fB.push_back(BB);
fPB.push_back(0.0);
}
// normalize p(B)
double pBsum = 0.0;
for (unsigned int i(0); i<lastZerosStart; i++)
pBsum += fPB[i];
pBsum *= fDB;
for (unsigned int i(0); i<lastZerosStart; i++)
fPB[i] /= pBsum;
} else { // fill the vectors with zeros
fBmin = 0.0;
fBmax = 1.0/gBar/fDT;
double BB;
for (BB=0.0 ; BB < fBmax ; BB += fDB ) {
fB.push_back(BB);
fPB.push_back(0.0);
}
// make sure that we have an even number of elements in p(B) for FFT, so we do not have to care later
if (fB.size() % 2) {
fB.push_back(BB);
fPB.push_back(0.0);
}
}
}
//-----------
// Constructor that does the P(B) calculation for given analytical inverse of B(z) and its derivative and n(z)
// Parameters: dt[us], dB[G], Energy[keV]
//-----------
TPofBCalc::TPofBCalc( const TBofZCalcInverse &BofZ, const TTrimSPData &dataTrimSP, const vector<double> &para ) : fDT(para[0]), fDB(para[1])
{
fBmin = BofZ.GetBmin();
fBmax = BofZ.GetBmax();
double BB;
// fill not used Bs before Bmin with 0.0
for (BB = 0.0; BB < fBmin; BB += fDB)
fB.push_back(BB);
fPB.resize(fB.size(),0.0);
unsigned int firstZerosEnd(fB.size());
// calculate p(B) from the inverse of B(z)
for ( ; BB <= fBmax ; BB += fDB) {
fB.push_back(BB);
fPB.push_back(0.0);
vector< pair<double, double> > inv;
inv = BofZ.GetInverseAndDerivative(BB);
for (unsigned int i(0); i<inv.size(); i++)
*(fPB.end()-1) += dataTrimSP.GetNofZ(inv[i].first, para[2])*fabs(inv[i].second);
}
unsigned int lastZerosStart(fB.size());
// fill not used Bs after Bext with 0.0
double BmaxFFT(1.0/gBar/fDT);
for ( ; BB <= BmaxFFT ; BB += fDB )
fB.push_back(BB);
fPB.resize(fB.size(),0.0);
// make sure that we have an even number of elements in p(B) for FFT, so we do not have to care later
if (fB.size() % 2) {
fB.push_back(BB);
fPB.push_back(0.0);
}
// normalize p(B)
double pBsum = 0.0;
for (unsigned int i(firstZerosEnd); i<lastZerosStart; i++)
pBsum += fPB[i];
pBsum *= fDB;
for (unsigned int i(firstZerosEnd); i<lastZerosStart; i++)
fPB[i] /= pBsum;
}
//----------- //-----------
// Constructor that does the P(B) calculation for given B(z) and n(z) // Constructor that does the P(B) calculation for given B(z) and n(z)
// Parameters: dt[us], dB[G], Energy[keV] // Parameters: dt[us], dB[G], Energy[keV]
//----------- //-----------
TPofBCalc::TPofBCalc( const TBofZCalc &BofZ, const TTrimSPData &dataTrimSP, const vector<double> &para ) : fDT(para[0]), fDB(para[1]) { TPofBCalc::TPofBCalc( const TBofZCalc &BofZ, const TTrimSPData &dataTrimSP, const vector<double> &para, unsigned int zonk ) : fDT(para[0]), fDB(para[1]) {
fBmin = BofZ.GetBmin(); fBmin = BofZ.GetBmin();
fBmax = BofZ.GetBmax(); fBmax = BofZ.GetBmax();
@ -45,7 +216,7 @@ TPofBCalc::TPofBCalc( const TBofZCalc &BofZ, const TTrimSPData &dataTrimSP, cons
vector<double> bofzZ(BofZ.DataZ()); vector<double> bofzZ(BofZ.DataZ());
vector<double> bofzBZ(BofZ.DataBZ()); vector<double> bofzBZ(BofZ.DataBZ());
double ddZ(BofZ.GetdZ()); double ddZ(BofZ.GetDZ());
/* USED FOR DEBUGGING----------------------------------- /* USED FOR DEBUGGING-----------------------------------
cout << "Bmin = " << fBmin << ", Bmax = " << fBmax << endl; cout << "Bmin = " << fBmin << ", Bmax = " << fBmax << endl;

View File

@ -41,6 +41,8 @@
#include <iostream> #include <iostream>
#include <cstdio> #include <cstdio>
#include <omp.h>
#include <TString.h> #include <TString.h>
#include <TObjArray.h> #include <TObjArray.h>
#include <TObjString.h> #include <TObjString.h>
@ -62,9 +64,25 @@
TPofTCalc::TPofTCalc (const string &wisdom, const vector<double> &par) : fWisdom(wisdom) { TPofTCalc::TPofTCalc (const string &wisdom, const vector<double> &par) : fWisdom(wisdom) {
int init_threads(fftw_init_threads());
if (!init_threads)
cout << "TPofTCalc::TPofTCalc: Couldn't initialize multiple FFTW-threads ..." << endl;
else
fftw_plan_with_nthreads(2);
fNFFT = ( int(1.0/gBar/par[1]/par[2]+1.0) % 2 ) ? int(1.0/gBar/par[1]/par[2]+2.0) : int(1.0/gBar/par[1]/par[2]+1.0); fNFFT = ( int(1.0/gBar/par[1]/par[2]+1.0) % 2 ) ? int(1.0/gBar/par[1]/par[2]+2.0) : int(1.0/gBar/par[1]/par[2]+1.0);
fTBin = 1.0/gBar/double(fNFFT-1)/par[2]; fTBin = 1.0/gBar/double(fNFFT-1)/par[2];
fT.resize(fNFFT/2+1);
fPT.resize(fNFFT/2+1);
int i;
#pragma omp parallel for default(shared) private(i) schedule(dynamic)
for (i=0; i<fNFFT/2+1; i++){
fT[i] = double(i)*fTBin;
}
fFFTin = (double *)malloc(sizeof(double) * fNFFT); fFFTin = (double *)malloc(sizeof(double) * fNFFT);
fFFTout = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * (fNFFT/2+1)); fFFTout = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * (fNFFT/2+1));
@ -121,13 +139,17 @@ void TPofTCalc::DoFFT(const TPofBCalc &PofB) {
} }
/--------------------------------------------*/ /--------------------------------------------*/
for (unsigned int i(0); i<fNFFT; i++) { int i;
#pragma omp parallel for default(shared) private(i) schedule(dynamic)
for (i=0; i<fNFFT; i++) {
fFFTin[i] = pB[i]; fFFTin[i] = pB[i];
} }
for (unsigned int i(0); i<fNFFT/2+1; i++) {
fFFTout[i][0] = 0.0; // for (unsigned int i(0); i<fNFFT/2+1; i++) {
fFFTout[i][1] = 0.0; // fFFTout[i][0] = 0.0;
} // fFFTout[i][1] = 0.0;
// }
// cout << "perform the Fourier transform..." << endl; // cout << "perform the Fourier transform..." << endl;
@ -143,15 +165,12 @@ void TPofTCalc::DoFFT(const TPofBCalc &PofB) {
void TPofTCalc::CalcPol(const vector<double> &par) { void TPofTCalc::CalcPol(const vector<double> &par) {
double sinph(sin(par[0]*PI/180.0)), cosph(cos(par[0]*PI/180.0)); double sinph(sin(par[0]*PI/180.0)), cosph(cos(par[0]*PI/180.0));
int i;
double polTemp(0.0); #pragma omp parallel for default(shared) private(i) schedule(dynamic)
fT.clear(); for (i=0; i<fNFFT/2+1; i++){
fPT.clear(); // fT[i] = double(i)*fTBin;
fPT[i] = cosph*fFFTout[i][0]*par[2] + sinph*fFFTout[i][1]*par[2];
for (unsigned int i(0); i<fNFFT/2+1; i++){
fT.push_back(double(i)*fTBin);
polTemp = cosph*fFFTout[i][0]*par[2] + sinph*fFFTout[i][1]*par[2];
fPT.push_back(polTemp);
} }
} }
@ -346,10 +365,15 @@ void TPofTCalc::FakeData(const string &rootOutputFileName, const vector<double>
//--------------------- //---------------------
double TPofTCalc::Eval(double t) const { double TPofTCalc::Eval(double t) const {
for (unsigned int i(0); i<fT.size()-1; i++) {
if (t < fT[i+1]) unsigned int i(int(t/fTBin));
if (i<fT.size()-1)
return fPT[i]+(fPT[i+1]-fPT[i])/(fT[i+1]-fT[i])*(t-fT[i]); return fPT[i]+(fPT[i+1]-fPT[i])/(fT[i+1]-fT[i])*(t-fT[i]);
}
// for (unsigned int i(0); i<fT.size()-1; i++) {
// if (t < fT[i+1])
// return fPT[i]+(fPT[i+1]-fPT[i])/(fT[i+1]-fT[i])*(t-fT[i]);
// }
cout << "TPofTCalc::Eval: No data for the time " << t << " us available! Returning -999.0 ..." << endl; cout << "TPofTCalc::Eval: No data for the time " << t << " us available! Returning -999.0 ..." << endl;
return -999.0; return -999.0;
@ -376,6 +400,7 @@ TPofTCalc::~TPofTCalc() {
free(fFFTin); free(fFFTin);
fftw_free(fFFTout); fftw_free(fFFTout);
// fftw_cleanup(); // fftw_cleanup();
// fftw_cleanup_threads();
fT.clear(); fT.clear();
fPT.clear(); fPT.clear();

View File

@ -5,7 +5,7 @@
Author: Bastian M. Wojek Author: Bastian M. Wojek
e-mail: bastian.wojek@psi.ch e-mail: bastian.wojek@psi.ch
2008/11/07 2009/04/25
***************************************************************************/ ***************************************************************************/
@ -13,12 +13,10 @@
#define _TBofZCalc_H_ #define _TBofZCalc_H_
#include <vector> #include <vector>
#include <pair>
using namespace std; using namespace std;
//-------------------- //--------------------
// Base class for any kind of theory function B(z) // Base class for any kind of theory function B(z)
// In principle only constructors for the different models have to be implemented
//-------------------- //--------------------
class TBofZCalc { class TBofZCalc {
@ -30,33 +28,52 @@ public:
virtual ~TBofZCalc() { virtual ~TBofZCalc() {
fZ.clear(); fZ.clear();
fBZ.clear(); fBZ.clear();
fParam.clear();
} }
virtual vector<double> DataZ() const; virtual vector<double> DataZ() const {return fZ;}
virtual vector<double> DataBZ() const; virtual vector<double> DataBZ() const {return fBZ;}
virtual void Calculate() = 0; virtual void Calculate();
virtual double GetBofZ(double) const = 0; virtual double GetBofZ(double) const = 0;
virtual double GetBmin() const = 0; virtual double GetBmin() const = 0;
virtual double GetBmax() const = 0; virtual double GetBmax() const = 0;
double GetdZ() const {return fDZ;} double GetDZ() const {return fDZ;}
protected: protected:
vector<double> fZ; int fSteps;
vector<double> fBZ;
double fDZ; double fDZ;
vector<double> fParam; vector<double> fParam;
unsigned int fSteps; vector<double> fZ;
vector<double> fBZ;
};
//--------------------
// Base class for any kind of theory function B(z) where the inverse and its derivative are given analytically
//--------------------
class TBofZCalcInverse : public TBofZCalc {
public:
TBofZCalcInverse() {}
virtual ~TBofZCalcInverse() {}
virtual vector< pair<double, double> > GetInverseAndDerivative(double) const = 0;
}; };
//-------------------- //--------------------
// Class "for Meissner screening" in a superconducting half-space // Class "for Meissner screening" in a superconducting half-space
//-------------------- //--------------------
class TLondon1D_HS : public TBofZCalc { class TLondon1D_HS : public TBofZCalcInverse {
public: public:
TLondon1D_HS(unsigned int, const vector<double>& ); TLondon1D_HS(const vector<double>&, unsigned int steps = 3000);
double GetBofZ(double) const;
double GetBmin() const;
double GetBmax() const;
vector< pair<double, double> > GetInverseAndDerivative(double) const;
}; };
@ -64,11 +81,22 @@ public:
// Class "for Meissner screening" in a thin superconducting film // Class "for Meissner screening" in a thin superconducting film
//-------------------- //--------------------
class TLondon1D_1L : public TBofZCalc { class TLondon1D_1L : public TBofZCalcInverse {
public: public:
TLondon1D_1L(unsigned int, const vector<double>& ); TLondon1D_1L(const vector<double>&, unsigned int steps = 3000);
double GetBofZ(double) const;
double GetBmin() const;
double GetBmax() const;
vector< pair<double, double> > GetInverseAndDerivative(double) const;
private:
void SetBmin();
double fMinZ;
double fMinB;
double fCoeff[2];
}; };
@ -76,28 +104,15 @@ public:
// Class "for Meissner screening" in a thin superconducting film - bilayer with two different lambdas // Class "for Meissner screening" in a thin superconducting film - bilayer with two different lambdas
//-------------------- //--------------------
class TLondon1D_2L : public TBofZCalc { class TLondon1D_2L : public TBofZCalcInverse {
public: public:
TLondon1D_2L(unsigned int, const vector<double>& ); TLondon1D_2L(const vector<double>&, unsigned int steps = 3000);
};
//--------------------
// Class "for Meissner screening" in a thin superconducting film - tri-layer with three different lambdas
//--------------------
class TLondon1D_3L : public TBofZCalc {
public:
TLondon1D_3L(unsigned int, const vector<double>& );
void Calculate();
double GetBofZ(double) const; double GetBofZ(double) const;
vector< pair<double, double> > GetInverseAndDerivative(double) const;
double GetBmin() const; double GetBmin() const;
double GetBmax() const; double GetBmax() const;
vector< pair<double, double> > GetInverseAndDerivative(double) const;
private: private:
void SetBmin(); void SetBmin();
@ -105,33 +120,68 @@ private:
int fMinTag; int fMinTag;
double fMinZ; double fMinZ;
double fMinB; double fMinB;
double fCoeff[6]; double fInterfaces[3];
double fInterfaces[4]; double fCoeff[4];
};
//--------------------
// Class "for Meissner screening" in a thin superconducting film - tri-layer with three different lambdas
//--------------------
class TLondon1D_3L : public TBofZCalcInverse {
public:
TLondon1D_3L(const vector<double>&, unsigned int steps = 3000);
double GetBofZ(double) const;
double GetBmin() const;
double GetBmax() const;
vector< pair<double, double> > GetInverseAndDerivative(double) const;
private:
void SetBmin();
int fMinTag;
double fMinZ;
double fMinB;
double fInterfaces[4];
double fCoeff[6];
}; };
//-------------------- //--------------------
// Class "for Meissner screening" in a thin superconducting film - tri-layer with two different lambdas // Class "for Meissner screening" in a thin superconducting film - tri-layer with two different lambdas
//-------------------- //--------------------
class TLondon1D_3LS : public TBofZCalc { class TLondon1D_3LS : public TBofZCalcInverse {
public: public:
TLondon1D_3LS(unsigned int, const vector<double>& ); TLondon1D_3LS(const vector<double>&, unsigned int steps = 3000);
double GetBofZ(double) const;
double GetBmin() const;
double GetBmax() const;
vector< pair<double, double> > GetInverseAndDerivative(double) const;
private:
void SetBmin();
int fMinTag;
double fMinZ;
double fMinB;
double fInterfaces[4];
double fCoeff[6];
}; };
//-------------------- // //--------------------
// Class "for Meissner screening" in a thin superconducting film - four layers with four different lambdas // // Class "for Meissner screening" in a thin superconducting film - four layers with four different lambdas
//-------------------- // //--------------------
//
class TLondon1D_4L : public TBofZCalc { // class TLondon1D_4L : public TBofZCalc {
//
public: // public:
//
TLondon1D_4L(unsigned int, const vector<double>& ); // TLondon1D_4L(unsigned int, const vector<double>& );
//
}; // };
#endif // _BofZCalc_H_ #endif // _BofZCalc_H_

View File

@ -140,30 +140,30 @@ private:
ClassDef(TLondon1D3LS,1) ClassDef(TLondon1D3LS,1)
}; };
class TLondon1D4L : public PUserFcnBase { // class TLondon1D4L : public PUserFcnBase {
//
public: // public:
// default constructor // // default constructor
TLondon1D4L(); // TLondon1D4L();
~TLondon1D4L(); // ~TLondon1D4L();
//
double operator()(double, const vector<double>&) const; // double operator()(double, const vector<double>&) const;
//
private: // private:
mutable vector<double> fPar; // mutable vector<double> fPar;
TTrimSPData *fImpProfile; // TTrimSPData *fImpProfile;
TPofTCalc *fPofT; // TPofTCalc *fPofT;
mutable bool fCalcNeeded; // mutable bool fCalcNeeded;
mutable bool fFirstCall; // mutable bool fFirstCall;
mutable vector<double> fParForPofT; // mutable vector<double> fParForPofT;
mutable vector<double> fParForBofZ; // mutable vector<double> fParForBofZ;
mutable vector<double> fParForPofB; // mutable vector<double> fParForPofB;
string fWisdom; // string fWisdom;
unsigned int fNSteps; // unsigned int fNSteps;
mutable bool fLastFourChanged; // mutable bool fLastFourChanged;
//
ClassDef(TLondon1D4L,1) // ClassDef(TLondon1D4L,1)
}; // };
class TLondon1D3LSub : public PUserFcnBase { class TLondon1D3LSub : public PUserFcnBase {
@ -190,4 +190,18 @@ private:
ClassDef(TLondon1D3LSub,1) ClassDef(TLondon1D3LSub,1)
}; };
// Class for fitting directly B(z) without any P(B)-calculation
class TLondon1D3Lestimate : public PUserFcnBase {
public:
// default constructor
TLondon1D3Lestimate() {}
~TLondon1D3Lestimate() {}
double operator()(double, const vector<double>&) const;
ClassDef(TLondon1D3Lestimate,1)
};
#endif //_TLondon1D_H_ #endif //_TLondon1D_H_

View File

@ -21,9 +21,11 @@
#pragma link C++ class TLondon1D2L+; #pragma link C++ class TLondon1D2L+;
#pragma link C++ class TLondon1D3L+; #pragma link C++ class TLondon1D3L+;
#pragma link C++ class TLondon1D3LS+; #pragma link C++ class TLondon1D3LS+;
#pragma link C++ class TLondon1D4L+; //#pragma link C++ class TLondon1D4L+;
#pragma link C++ class TLondon1D3LSub+; #pragma link C++ class TLondon1D3LSub+;
#pragma link C++ class TLondon1D3Lestimate;
#endif //__CINT__ #endif //__CINT__
// root dictionary stuff -------------------------------------------------- // root dictionary stuff --------------------------------------------------

View File

@ -22,7 +22,10 @@ class TPofBCalc {
public: public:
TPofBCalc( const TBofZCalc&, const TTrimSPData&, const vector<double>& ); TPofBCalc( const string&, const vector<double>& );
TPofBCalc( const TBofZCalc&, const TTrimSPData&, const vector<double>&, unsigned int );
TPofBCalc( const TBofZCalcInverse&, const TTrimSPData&, const vector<double>& );
TPofBCalc( const vector<double>&, const vector<double>& , double dt = 0.01 );
~TPofBCalc() { ~TPofBCalc() {
fB.clear(); fB.clear();
fPB.clear(); fPB.clear();

View File

@ -40,7 +40,7 @@ private:
vector<double> fT; vector<double> fT;
vector<double> fPT; vector<double> fPT;
double fTBin; double fTBin;
unsigned int fNFFT; int fNFFT;
const string fWisdom; const string fWisdom;
}; };