1137 lines
42 KiB
C++
1137 lines
42 KiB
C++
/***************************************************************************
|
|
|
|
TBofZCalc.cpp
|
|
|
|
Author: Bastian M. Wojek
|
|
e-mail: bastian.wojek@psi.ch
|
|
|
|
2009/04/25
|
|
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* Copyright (C) 2009 by Bastian M. Wojek *
|
|
* *
|
|
* *
|
|
* 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 2 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. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
|
***************************************************************************/
|
|
|
|
#include "TBofZCalc.h"
|
|
#include <omp.h>
|
|
#include <cmath>
|
|
//#include <iostream>
|
|
//#include <algorithm>
|
|
#include <cassert>
|
|
|
|
//------------------
|
|
// Method filling the z and B(z)-vectors for the case B(z) should be used numerically
|
|
//------------------
|
|
|
|
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;
|
|
}
|
|
|
|
// //------------------
|
|
// // Method returning the field minimum of the model
|
|
// //------------------
|
|
//
|
|
// double TBofZCalc::GetBmin() const {
|
|
// vector<double>::const_iterator iter;
|
|
// iter = min_element(fBZ.begin(),fBZ.end());
|
|
//
|
|
// return *iter;
|
|
// }
|
|
//
|
|
// //------------------
|
|
// // Method returning the field maximum of the model
|
|
// //------------------
|
|
//
|
|
// double TBofZCalc::GetBmax() const {
|
|
// vector<double>::const_iterator iter;
|
|
// iter = max_element(fBZ.begin(),fBZ.end());
|
|
//
|
|
// return *iter;
|
|
// }
|
|
//
|
|
// //------------------
|
|
// // Method returning the field B(z) at a given z according to the model
|
|
// //------------------
|
|
//
|
|
// double TBofZCalc::GetBofZ(double zz) const {
|
|
//
|
|
// bool found = false;
|
|
// unsigned int i;
|
|
// for (i=0; i<fZ.size(); i++) {
|
|
// if (fZ[i] > zz) {
|
|
// found = true;
|
|
// break;
|
|
// }
|
|
// }
|
|
//
|
|
// if (!found || i == 0) {
|
|
// cout << "TBofZCalc::GetBofZ: B(z) cannot be calculated for z = " << zz << " !" << endl;
|
|
// cout << "TBofZCalc::GetBofZ: Check your theory function!" << endl;
|
|
// return -1.0;
|
|
// }
|
|
//
|
|
// return fBZ[i-1]+(fBZ[i]-fBZ[i-1])*(zz-fZ[i-1])/(fZ[i]-fZ[i-1]);
|
|
//
|
|
// }
|
|
|
|
//------------------
|
|
// Constructor of the TLondon1D_HS class
|
|
// 1D-London screening in a superconducting half-space
|
|
// Parameters: Bext[G], deadlayer[nm], lambda[nm]
|
|
//------------------
|
|
|
|
TLondon1D_HS::TLondon1D_HS(const vector<double> ¶m, unsigned int steps)
|
|
{
|
|
fSteps = steps;
|
|
fDZ = 200.0/double(steps);
|
|
fParam = param;
|
|
}
|
|
|
|
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
|
|
// 1D-London screening in a thin superconducting film
|
|
// Parameters: Bext[G], deadlayer[nm], thickness[nm], lambda[nm]
|
|
//------------------
|
|
|
|
TLondon1D_1L::TLondon1D_1L(const vector<double> ¶m, unsigned int steps)
|
|
{
|
|
fSteps = steps;
|
|
fDZ = param[2]/double(steps);
|
|
fParam = param;
|
|
fMinZ = -1.0;
|
|
fMinB = -1.0;
|
|
|
|
// thicknesses have to be greater or equal to zero
|
|
for(unsigned int i(1); i<3; i++){
|
|
if(param[i] < 0.){
|
|
fParam[i] = 0.;
|
|
}
|
|
}
|
|
|
|
// lambdas have to be greater than zero
|
|
if(param[3] < 0.1){
|
|
fParam[3] = 0.1;
|
|
}
|
|
|
|
// 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.);
|
|
if(b_a<10E-7){
|
|
b_a = 10E-7;
|
|
}
|
|
|
|
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.);
|
|
if(fMinZ <= 0.){
|
|
fMinZ = 0.;
|
|
}
|
|
if(fMinB <= 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
|
|
// 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]
|
|
//------------------
|
|
|
|
TLondon1D_2L::TLondon1D_2L(const vector<double> ¶m, unsigned int steps)
|
|
{
|
|
fSteps = steps;
|
|
fDZ = (param[2]+param[3])/double(steps);
|
|
fParam = param;
|
|
fMinTag = -1;
|
|
fMinZ = -1.0;
|
|
fMinB = -1.0;
|
|
|
|
// thicknesses have to be greater or equal to zero
|
|
for(unsigned int i(1); i<4; i++)
|
|
assert(param[i]>=0.);
|
|
|
|
// 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 {
|
|
return fCoeff[2]*exp(-ZZ/fParam[5])+fCoeff[3]*exp(ZZ/fParam[5]);
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
//------------------
|
|
// Constructor of the TProximity1D_1LHS class
|
|
// 1D-Proximity screening in a thin superconducting film, 1layer+bulk, linear + exponential decay
|
|
// Parameters: Bext[G], B1[G], deadlayer[nm], thickness1[nm], lambda[nm]
|
|
//------------------
|
|
|
|
TProximity1D_1LHS::TProximity1D_1LHS(const vector<double> ¶m, unsigned int steps)
|
|
{
|
|
fSteps = steps;
|
|
fDZ = 200./double(steps);
|
|
fMinTag = -1;
|
|
fMinZ = -1.0;
|
|
fMinB = -1.0;
|
|
|
|
// replaced the former assertions of positive lengths by fixed parameter limits
|
|
|
|
fParam.resize(param.size());
|
|
fParam[0] = param[0]; // Bext
|
|
(param[0] != param[1]) ? fParam[1] = param[1] : fParam[1] = param[1]-0.01; // B1
|
|
(param[2] >= 0.) ? fParam[2] = param[2] : fParam[2] = 0.; // deadlayer
|
|
(param[3] >= 0.) ? fParam[3] = param[3] : fParam[3] = 0.; // thickness1
|
|
(param[3] >= 1.) ? fParam[4] = param[4] : fParam[4] = 1.; // lambda
|
|
|
|
fInterfaces[0]=fParam[2];
|
|
fInterfaces[1]=fParam[2]+fParam[3];
|
|
|
|
SetBmin();
|
|
}
|
|
|
|
double TProximity1D_1LHS::GetBofZ(double ZZ) const
|
|
{
|
|
if(ZZ < fInterfaces[0])
|
|
return fParam[0];
|
|
|
|
if (ZZ < fInterfaces[1]) {
|
|
return fParam[0]-(fParam[0]-fParam[1])/fParam[3]*(ZZ-fParam[2]);
|
|
} else {
|
|
return fParam[1]*exp((fParam[2]+fParam[3]-ZZ)/fParam[4]);
|
|
}
|
|
}
|
|
|
|
double TProximity1D_1LHS::GetBmax() const
|
|
{
|
|
// return applied field
|
|
return fParam[0];
|
|
}
|
|
|
|
double TProximity1D_1LHS::GetBmin() const
|
|
{
|
|
// return field minimum
|
|
return fMinB;
|
|
}
|
|
|
|
void TProximity1D_1LHS::SetBmin()
|
|
{
|
|
fMinTag = 2;
|
|
fMinZ = 200.;
|
|
fMinB = GetBofZ(fMinZ);
|
|
return;
|
|
}
|
|
|
|
vector< pair<double, double> > TProximity1D_1LHS::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[0]*(fParam[2]+fParam[3])-fParam[1]*fParam[2]-BB*fParam[3])/(fParam[0]-fParam[1]);
|
|
inverse[1]=fParam[2]+fParam[3]-fParam[4]*log(BB/fParam[1]);
|
|
|
|
if(inverse[0] > fInterfaces[0] && inverse[0] <= fInterfaces[1]) {
|
|
invAndDerivative.first = inverse[0];
|
|
invAndDerivative.second = fParam[3]/(fParam[1]-fParam[0]);
|
|
inv.push_back(invAndDerivative);
|
|
}
|
|
if(inverse[1] > fInterfaces[1]) {
|
|
invAndDerivative.first = inverse[1];
|
|
invAndDerivative.second = -fParam[4]/BB;
|
|
inv.push_back(invAndDerivative);
|
|
}
|
|
|
|
return inv;
|
|
}
|
|
|
|
//------------------
|
|
// Constructor of the TProximity1D_1LHSGss class
|
|
// 1D-Proximity screening in a thin superconducting film, 1layer+bulk, linear + exponential decay
|
|
// Parameters: Bext[G], B1[G], deadlayer[nm], thickness1[nm], sigma[nm]
|
|
//------------------
|
|
|
|
TProximity1D_1LHSGss::TProximity1D_1LHSGss(const vector<double> ¶m, unsigned int steps)
|
|
{
|
|
fSteps = steps;
|
|
fDZ = 200./double(steps);
|
|
fMinTag = -1;
|
|
fMinZ = -1.0;
|
|
fMinB = -1.0;
|
|
|
|
// replaced the former assertions of positive lengths by fixed parameter limits
|
|
|
|
fParam.resize(param.size());
|
|
fParam[0] = param[0]; // Bext
|
|
(param[0] != param[1]) ? fParam[1] = param[1] : fParam[1] = param[1]-0.01; // B1
|
|
(param[2] >= 0.) ? fParam[2] = param[2] : fParam[2] = 0.; // deadlayer
|
|
(param[3] >= 0.) ? fParam[3] = param[3] : fParam[3] = 0.; // thickness1
|
|
(param[3] >= 1.) ? fParam[4] = param[4] : fParam[4] = 1.; // sigma
|
|
|
|
fInterfaces[0]=fParam[2];
|
|
fInterfaces[1]=fParam[2]+fParam[3];
|
|
|
|
SetBmin();
|
|
}
|
|
|
|
double TProximity1D_1LHSGss::GetBofZ(double ZZ) const
|
|
{
|
|
if(ZZ < fInterfaces[0])
|
|
return fParam[0];
|
|
|
|
if (ZZ < fInterfaces[1]) {
|
|
return fParam[0]-(fParam[0]-fParam[1])/fParam[3]*(ZZ-fParam[2]);
|
|
} else {
|
|
return fParam[1]*exp(-(ZZ-fParam[2]-fParam[3])*(ZZ-fParam[2]-fParam[3])/(4.0*fParam[4]*fParam[4]));
|
|
}
|
|
}
|
|
|
|
double TProximity1D_1LHSGss::GetBmax() const
|
|
{
|
|
// return applied field
|
|
return fParam[0];
|
|
}
|
|
|
|
double TProximity1D_1LHSGss::GetBmin() const
|
|
{
|
|
// return field minimum
|
|
return fMinB;
|
|
}
|
|
|
|
void TProximity1D_1LHSGss::SetBmin()
|
|
{
|
|
fMinTag = 2;
|
|
fMinZ = 200.;
|
|
fMinB = GetBofZ(fMinZ);
|
|
return;
|
|
}
|
|
|
|
vector< pair<double, double> > TProximity1D_1LHSGss::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[0]*(fParam[2]+fParam[3])-fParam[1]*fParam[2]-BB*fParam[3])/(fParam[0]-fParam[1]);
|
|
inverse[1]=fParam[2]+fParam[3]+fParam[4]*sqrt(2.0*log(fParam[1]/BB));
|
|
|
|
if(inverse[0] > fInterfaces[0] && inverse[0] <= fInterfaces[1]) {
|
|
invAndDerivative.first = inverse[0];
|
|
invAndDerivative.second = fParam[3]/(fParam[1]-fParam[0]);
|
|
inv.push_back(invAndDerivative);
|
|
}
|
|
if(inverse[1] > fInterfaces[1]) {
|
|
invAndDerivative.first = inverse[1];
|
|
invAndDerivative.second = -fParam[4]/(BB*sqrt(2.0*log(fParam[1]/BB)));
|
|
inv.push_back(invAndDerivative);
|
|
}
|
|
|
|
return inv;
|
|
}
|
|
|
|
//------------------
|
|
// Constructor of the TLondon1D_3L class
|
|
// 1D-London screening in a thin superconducting film, three layers, three lambdas
|
|
// Parameters: Bext[G], deadlayer[nm], thickness1[nm], thickness2[nm], thickness3[nm], lambda1[nm], lambda2[nm], lambda3[nm]
|
|
//------------------
|
|
|
|
TLondon1D_3L::TLondon1D_3L(const vector<double> ¶m, unsigned int steps)
|
|
// : 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
|
|
for(unsigned int i(1); i<5; i++)
|
|
assert(param[i]>=0.);
|
|
|
|
// lambdas have to be greater than zero
|
|
for(unsigned int i(5); i<8; i++)
|
|
assert(param[i]!=0.);
|
|
|
|
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]), l3(param[7]);
|
|
|
|
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)) * \
|
|
l2*(l3*cosh(d2/l2)*cosh(d3/l3)+l2*sinh(d2/l2)*sinh(d3/l3))));
|
|
|
|
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)) + \
|
|
4.0*exp(d1/l1)*l2*(l1*cosh(d1/l1)*cosh(d2/l2) + l2*sinh(d1/l1)*sinh(d2/l2))*sinh(d3/l3));
|
|
|
|
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)) + \
|
|
(-1.0+exp(2.0*d1/l1))*l2*(l3*cosh(d2/l2) * cosh(d3/l3)+l2*sinh(d2/l2)*sinh(d3/l3))));
|
|
|
|
double N5((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))*l2*(l3*cosh(d2/l2) * cosh(d3/l3)+l2*sinh(d2/l2)*sinh(d3/l3)));
|
|
|
|
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) - \
|
|
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;
|
|
|
|
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) - \
|
|
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[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;
|
|
|
|
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 - \
|
|
exp(d1/l1)*l1*(l2+l3+exp(2.0*d3/l3)*(l3-l2))))/N3;
|
|
|
|
fCoeff[4]=(0.25*B0*exp(-d2/l2+(d1+d2+dd)/l3) * (4.0*exp(d1/l1+d2/l2+d3/l3)*l1*l2 - \
|
|
(-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;
|
|
|
|
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
|
|
for(unsigned int i(0); i<6; i++)
|
|
assert(fCoeff[i]);
|
|
|
|
SetBmin();
|
|
}
|
|
|
|
double TLondon1D_3L::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 {
|
|
return fCoeff[4]*exp(-ZZ/fParam[7])+fCoeff[5]*exp(ZZ/fParam[7]);
|
|
}
|
|
}
|
|
|
|
double TLondon1D_3L::GetBmax() const
|
|
{
|
|
// return applied field
|
|
return fParam[0];
|
|
}
|
|
|
|
double TLondon1D_3L::GetBmin() const
|
|
{
|
|
// return field minimum
|
|
return fMinB;
|
|
}
|
|
|
|
void TLondon1D_3L::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[7]*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_3L::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[7]*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[7]/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[7]*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[7]/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[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] <= 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[7]/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[7]/sqrt(BB*BB-4.0*fCoeff[4]*fCoeff[5]);
|
|
inv.push_back(invAndDerivative);
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
return inv;
|
|
}
|
|
|
|
//------------------
|
|
// Constructor of the TLondon1D_3LS class
|
|
// 1D-London screening in a thin superconducting film, three layers, two lambdas (top and bottom layer: lambda1)
|
|
// Parameters: Bext[G], deadlayer[nm], thickness1[nm], thickness2[nm], thickness3[nm], lambda1[nm], lambda2[nm]
|
|
//------------------
|
|
|
|
TLondon1D_3LS::TLondon1D_3LS(const vector<double> ¶m, unsigned int steps)
|
|
{
|
|
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
|
|
for(unsigned int i(1); i<5; i++)
|
|
assert(param[i]>=0.);
|
|
|
|
// lambdas have to be greater than zero
|
|
for(unsigned int i(5); i<7; i++){
|
|
assert(param[i]!=0.);
|
|
}
|
|
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 {
|
|
return fCoeff[4]*exp(-ZZ/fParam[5])+fCoeff[5]*exp(ZZ/fParam[5]);
|
|
}
|
|
}
|
|
|
|
double TLondon1D_3LS::GetBmax() const
|
|
{
|
|
// return applied field
|
|
return fParam[0];
|
|
}
|
|
|
|
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> ¶m) {
|
|
//
|
|
// 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);
|
|
// }
|
|
// }
|