Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <string.h>
- #define PI (3.1415926535897932384626433832795028841971693994)
- #include "init.h"
- #include "dens.h"
- #include "fields.h"
- #include "sources.h"
- #include "init.h"
- struct fields *LOCAL_MESONS;
- struct sources *LOCAL_SRCS;
- struct densities *LOCAL_DENS;
- struct init_data COMMON_DATA;
- //Need to add update Fields and Update Sigma then it's OVER!!!1!
- double UpdateDensities(struct fields *Mesons, struct sources *srcs, struct densities *Dens, double mu_p, double mu_n, double rmax, int nmax);
- double UpdateProtonDensities();
- double UpdateNeutronDensities();
- double CombineOldAndNew();
- double solveNewton(double (*f)(double), double c, double x_init);
- double fPrime(double x, double (*f)(double));
- double CalcProtonNumber(double mu_p);
- double CalcNeutronNumber(double mu_n);
- void GetRho(double *vecRhopn, double mup, double *vecSigma, double *vecRho0, double *vecOmega, double *vecA0, int nMax, int p_or_n);
- double numIntegrateVec(double *vF, double h, int down, int up, int nMax);
- double GetEFermi(double mu, double eA, double grho, double gomega, int p_or_n);
- double GetPFermi(double EFermi, double mass);
- double ScalarDensity2(double m_eff, double pf);
- void Get_gRhoScalar(double *r_grho_S, double *sigma, double *rho_p, double *rho_n, double rmax, int nmax);
- double SinhXoverX(double x);
- void UpdateFields(struct fields *Mesons, struct sources *Srcs, struct densities *Dens, double rmax, int nmax);
- void UpdateSigma(struct fields *Mesons, struct densities *Dens, double rmax, int nmax);
- void SolveKG_WithSource(double *vecPhi, double *vecJ, double **matGreen, double m, double rMax, int nMax);
- void SolvePoisson(double *vecPhi, double *vecJ, double **matGreen, double rMax, int nMax);
- void MakeGreenE(double **matGreen, double rMax, int nMax);
- //Update Densities
- double UpdateDensities(struct fields *Mesons, struct sources *SRCS, struct densities *Dens, double mu_p, double mu_n, double rmax, int nmax){
- *LOCAL_MESONS = *Mesons;
- *LOCAL_SRCS = *SRCS;
- //Let LOCAL_DENS point to Dens.
- *LOCAL_DENS = *Dens;
- UpdateProtonDensities(Dens->rho_p, mu_p);
- //Pass by reference so both can be updated
- double f_p;
- f_p = CombineOldAndNew(Dens->rho_p_prev, Dens->rho_p, nmax);
- // combine the new solution and the previous one
- //to help convergence
- // f_p is the relative difference between the new density
- // and the previous one
- UpdateNeutronDensities(Dens->rho_n, mu_n);
- double f_n;
- // pass by reference so that both can be updated
- f_n = CombineOldAndNew(Dens->rho_n_prev, Dens->rho_n, nmax);
- //Let LOCAL_MESONS,SRCS,DENS point to a NULL pointer so that nothing else can mess it up
- return (f_p + f_n)/2;
- }
- // passed by
- double UpdateProtonDensities(double mu_p){
- double Z = COMMON_DATA.Z;
- double mu_init = mu_p;
- double mu_now = solveNewton(CalcProtonNumber, Z, mu_init);
- mu_p = mu_now;
- }
- double UpdateNeutronDensities(double mu_n){
- double N = COMMON_DATA.N;
- double mu_init = mu_n;
- double mu_now = solveNewton(CalcNeutronNumber, N, mu_init);
- mu_n = mu_now;
- }
- double CalcProtonNumber(double mu_p){
- //double rmax = COMMON_DATA.rmax;
- //int nmax = COMMON_DATA.nmax;
- //Get local Mesons
- //Get rho_p from local dens
- double *integp1;
- integp1 = (double *) malloc((COMMON_DATA.nmax) * sizeof(double));
- GetRho(LOCAL_DENS->rho_p, mu_p, LOCAL_MESONS->sigma, LOCAL_MESONS->rho0, LOCAL_MESONS->omega, LOCAL_MESONS->A0, COMMON_DATA.nmax, 1);
- for(int l = 0; l < COMMON_DATA.nmax; l++){
- double dR = COMMON_DATA.rmax/COMMON_DATA.nmax;
- integp1[l] = 4*PI*pow(l*dR,2)*LOCAL_DENS->rho_p[l];
- }
- double Solp1 = numIntegrateVec(integp1, COMMON_DATA.rmax/COMMON_DATA.nmax, 0, COMMON_DATA.nmax, 100);
- return Solp1;
- }
- double CalcNeutronNumber(double mu_n){
- //double rmax = COMMON_DATA.rmax;
- //int nmax = COMMON_DATA.nmax;
- //Get local Mesons
- //Get rho_p from local dens
- double *integn1;
- integn1 = (double *) malloc((COMMON_DATA.nmax) * sizeof(double));
- GetRho(LOCAL_DENS->rho_n, mu_n, LOCAL_MESONS->sigma, LOCAL_MESONS->rho0, LOCAL_MESONS->omega, LOCAL_MESONS->A0, COMMON_DATA.nmax, 0);
- for(int l = 0; l < COMMON_DATA.nmax; l++){
- double dR = COMMON_DATA.rmax/COMMON_DATA.nmax;
- integn1[l] = 4*PI*pow(l*dR,2)*LOCAL_DENS->rho_n[l];
- }
- double Soln1 = numIntegrateVec(integn1, COMMON_DATA.rmax/COMMON_DATA.nmax, 0, COMMON_DATA.nmax, COMMON_DATA.nmax);
- return Soln1;
- }
- double CombineOldAndNew(double *rho_p_prev, double *rho_p, int nmax){
- // CLARIFICTION: Add double new_frac and old_frac in your initial data
- // structure. Set these in FillData. old_frac = 1.0 - new_frac.
- // new_frac = 0.6 is a good place to start
- //Get new_frac from COMMON_DATA.
- //Get old_frac from COMMON_DATA.
- double err;
- for(int k = 0; k< nmax; k++){
- rho_p[k] = COMMON_DATA.new_frac*rho_p[k] + COMMON_DATA.old_frac*rho_p_prev[k];
- //Caculate the relative error
- err += sqrt( pow((rho_p[k] - rho_p_prev[k]),2.0)/pow((rho_p[k]),2.0) );
- }
- memcpy(rho_p_prev, rho_p, COMMON_DATA.nmax*sizeof(double));
- return err;
- }
- void Get_gRhoScalar(double *r_grho_S, double *sigma, double *rho_p, double *rho_n, double rmax, int nmax){
- double dR = rmax/nmax;
- for(int k=0; k<=nmax; k++){
- double r = k*dR;
- double scalDen = ScalarDensity(COMMON_DATA.m_proton - COMMON_DATA.g_sigma*sigma[k], pow(rho_p[k]*3.0*PI*PI, (1.0/3.0)));
- r_grho_S[k] = scalDen*COMMON_DATA.g_sigma*r;
- }
- }
- double ScalarDensity2(double m_eff, double pf){
- double ef = sqrt(m_eff*m_eff + pf*pf);
- double rho_s = m_eff*( pf*ef - m_eff*m_eff*asinh(pf/m_eff) )/2.0/PI/PI;
- return rho_s;
- }
- double SinhXoverX(double x){
- if(x < 1e-8){
- return 1.0 + pow(x,2.0)/6.0 + pow(x,4.0)/120.0;
- }else return sinh(x)/x;
- }
- void UpdateFields(struct fields *Mesons, struct sources *Srcs, struct densities *Dens, double rmax, int nmax){
- UpdateSigma(Mesons, Dens, rmax, nmax);
- //Use Solve KG for omega and rho0
- SolveKG_WithSource(Mesons->omega, Srcs->r_grho_B, Mesons->GreenOmega, COMMON_DATA.m_omega, rmax, nmax);
- SolveKG_WithSource(Mesons->rho0, Srcs->r_grho_3, Mesons->GreenRho0, COMMON_DATA.m_rho, rmax, nmax);
- SolvePoisson(Mesons->A0, Srcs->r_grho_p,Mesons->GreenA0, rmax, nmax);
- //Use SolvePossion for A0
- return;
- }
- void UpdateSigma(struct fields *Mesons, struct densities *Dens, double rmax, int nmax){
- double *sigma_prev = Mesons->sigma_prev = makeVector(com_dat.nmax + 1);
- double *r_grho_S = Mesons->r_grho_S = makeVector(com_dat.nmax + 1);
- double *sigma;
- sigma = Mesons->sigma;
- double **GreenSigma = Mesons->GreenSigma;
- double *rho_p = Dens->rho_p;
- double *rho_n = Dens->rho_n;
- double mass = COMMON_DATA.m_sigma;
- //Get g_sigma from common_data
- int iter_max = 100;
- double tol = 1e-10;
- double err;
- for(int i = 0; i<iter_max;){
- memcpy(sigma_prev, sigma, COMMON_DATA.nmax*sizeof(double));
- Get_gRhoScalar(r_grho_S, sigma, rho_p, rho_n, rmax, nmax);
- SolveKG_WithSource(sigma, r_grho_S, GreenSigma, mass, rmax, nmax);
- //rho_p[k] = COMMON_DATA.new_frac*rho_p[k] + COMMON_DATA.old_frac*rho_p_prev[k];
- //Caculate the relative error
- err += sqrt( pow((sigma[i] - sigma_prev[i]),2.0)/pow((sigma[i]),2.0) );
- if(err>tol){
- break;
- }
- }
- // Free r_g_rho_S and sigma_prev;
- return;
- }
- //From previous assignment
- void GetRho(double *vecRhopn, double mup, double *vecSigma, double *vecRho0, double *vecOmega, double *vecA0, int nMax, int p_or_n){
- //Proton case
- if(p_or_n == 1){
- for (int k = 0; k < nMax; k++) {
- //Make sure to use effective mass as given in assignment AND account for hbarc
- double effMass = com_dat.m_proton/com_dat.hbarc - com_dat.g_sigma*vecSigma[k];
- double eFerm = GetEFermi(mup, com_dat.e_EM*vecA0[k], com_dat.g_rho*vecRho0[k], com_dat.g_omega*vecOmega[k], p_or_n);
- double pFerm = GetPFermi(eFerm, effMass);
- //Populating the vector in given in the first argument.
- vecRhopn[k] = pow(pFerm, 3)/(3.*pow(PI, 2));
- }
- }
- //Neutron case
- else{
- for (int k = 0; k < nMax; k++) {
- double effMass = com_dat.m_neutron/com_dat.hbarc - com_dat.g_sigma*vecSigma[k];
- double eFerm = GetEFermi(mup, com_dat.e_EM*vecA0[k], com_dat.g_rho*vecRho0[k], com_dat.g_omega*vecOmega[k], p_or_n);
- double pFerm = GetPFermi(eFerm, effMass);
- vecRhopn[k] = pow(pFerm, 3)/(3.*pow(PI, 2));
- }
- }
- }
- double fPrime(double x, double (*f)(double)){
- double h = 0.000000000000001;
- return (f(x-3.0*h) - 27.0*f(x-h) +27.0*f(x+h) - f(x-3.0*h))/48.0*h;
- }
- double solveNewton(double (*f)(double), double c, double x_init) {
- //set the tolerance
- double tol = 0.000000000000001;
- // set the maximum count (how many iterations)
- int maxCount = 100000;
- //-----dasdsalkjdlsajd
- int n = 10;
- //initializing x_old to be zero to start
- double x_o = 0;
- //Setting x_old to x_initial given in the function as an argument.
- x_o = x_init;
- //set x_new to be x_old with the n*tolerance added
- double x_n = x_o + n*tol;
- //initialize my counter to be zero to begin
- int count = 0;
- while (fabs(x_n - x_o)>tol){
- //Set x_old to x_new
- x_o = x_n;
- //Now make x_new = x_old -
- x_n = x_o - ((*f)(x_o)-c)/fPrime(x_o, f);
- //count + 1
- count += 1;
- //Testing
- ///////////////////////////////////////////////////////////////////////////////////////
- //printf("Iteration: %d, value is %.12f.\n", count, x_n);
- //////////////////////////////////////////////////////////////////////////////////////
- //Break the loop if the count exceeds the maximum count set.
- if (count > maxCount){
- break;
- }
- }
- //The whole function now returns the latest iteration of x_new
- return x_n;
- }
- //Getting the fermi energy
- double GetEFermi(double mu, double eA, double grho, double gomega, int p_or_n){
- //proton case
- if(p_or_n == 1){
- return mu - eA - grho - gomega;
- }
- //neutron case
- else{
- return mu + grho - gomega;
- }
- }
- //Fermi momentum
- double GetPFermi(double EFermi, double mass){
- return sqrt(pow(EFermi, 2) - pow(mass, 2));
- }
- void SolveKG_WithSource(double *vecPhi, double *vecJ, double **matGreen, double m, double rMax, int nMax){
- double dR = rMax/nMax;
- //Variable we're going to use.
- double dX = dR*m;
- double f_1, f_2;
- double *integ_vec;
- integ_vec = (double *) malloc((nMax) * sizeof(double));
- for(int k=0; k<nMax; k++){
- for(int l=0; l<nMax; l++){
- integ_vec[l] = matGreen[k][l]*vecJ[l];
- }
- f_1 = numIntegrateVec(integ_vec, dX, 0, k, nMax);
- f_2 = numIntegrateVec(integ_vec, dX, k, nMax, nMax);
- //Populating the solution vector
- vecPhi[k] = (f_1 + f_2)/m;
- }
- return;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement