blob: 76a509fc27ba158399eded9004cfedf6a54e9dc2 [file] [log] [blame]
//------------------------------------------------------------------------------------------------------------------------------
// Samuel Williams
// SWWilliams@lbl.gov
// Lawrence Berkeley National Lab
//------------------------------------------------------------------------------------------------------------------------------
#include <stdint.h>
#include <stdio.h>
#include <math.h>
#include "defines.h"
#include "timer.h"
#include "mg.h"
//------------------------------------------------------------------------------------------------------------------------------
void initialize_problem(domain_type *domain, int level, double hLevel, double a, double b){
double NPi = 2.0*M_PI;
double Bmin = 1.0;
double Bmax = 10.0;
double c2 = (Bmax-Bmin)/2;
double c1 = (Bmax+Bmin)/2;
double c3=10.0; // how sharply (B)eta transitions
double c4 = -5.0/0.25;
int box;
for(box=0;box<domain->subdomains_per_rank;box++){
memset(domain->subdomains[box].levels[level].grids[__u_exact],0,domain->subdomains[box].levels[level].volume*sizeof(double));
memset(domain->subdomains[box].levels[level].grids[__f ],0,domain->subdomains[box].levels[level].volume*sizeof(double));
int i,j,k;
#pragma omp parallel for private(k,j,i) collapse(2)
for(k=0;k<domain->subdomains[box].levels[level].dim.k;k++){
for(j=0;j<domain->subdomains[box].levels[level].dim.j;j++){
for(i=0;i<domain->subdomains[box].levels[level].dim.i;i++){
double x = hLevel*((double)(i+domain->subdomains[box].levels[level].low.i)+0.5);
double y = hLevel*((double)(j+domain->subdomains[box].levels[level].low.j)+0.5);
double z = hLevel*((double)(k+domain->subdomains[box].levels[level].low.k)+0.5);
int ijk = (i+domain->subdomains[box].levels[level].ghosts)+
domain->subdomains[box].levels[level].pencil*(j+domain->subdomains[box].levels[level].ghosts)+
domain->subdomains[box].levels[level].plane *(k+domain->subdomains[box].levels[level].ghosts);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double r2 = pow((x-0.50),2) + pow((y-0.50),2) + pow((z-0.50),2); // distance from center squared
double r2x = 2.0*(x-0.50);
double r2y = 2.0*(y-0.50);
double r2z = 2.0*(z-0.50);
double r2xx = 2.0;
double r2yy = 2.0;
double r2zz = 2.0;
double r = pow(r2,0.5);
double rx = 0.5*r2x*pow(r2,-0.5);
double ry = 0.5*r2y*pow(r2,-0.5);
double rz = 0.5*r2z*pow(r2,-0.5);
double rxx = 0.5*r2xx*pow(r2,-0.5) - 0.25*r2x*r2x*pow(r2,-1.5);
double ryy = 0.5*r2yy*pow(r2,-0.5) - 0.25*r2y*r2y*pow(r2,-1.5);
double rzz = 0.5*r2zz*pow(r2,-0.5) - 0.25*r2z*r2z*pow(r2,-1.5);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// beta (B) is a bubble...
double A = 1.0;
double B = c1+c2*tanh( c3*(r-0.25) );
double Bx = c2*c3*rx*(1-pow(tanh( c3*(r-0.25) ),2));
double By = c2*c3*ry*(1-pow(tanh( c3*(r-0.25) ),2));
double Bz = c2*c3*rz*(1-pow(tanh( c3*(r-0.25) ),2));
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double u = exp(c4*r2)*sin(NPi*x)*sin(NPi*y)*sin(NPi*z);
double ux = c4*r2x*u + NPi*exp(c4*r2)*cos(NPi*x)*sin(NPi*y)*sin(NPi*z);
double uy = c4*r2y*u + NPi*exp(c4*r2)*sin(NPi*x)*cos(NPi*y)*sin(NPi*z);
double uz = c4*r2z*u + NPi*exp(c4*r2)*sin(NPi*x)*sin(NPi*y)*cos(NPi*z);
double uxx = c4*r2xx*u + c4*r2x*ux + c4*r2x*NPi*exp(c4*r2)*cos(NPi*x)*sin(NPi*y)*sin(NPi*z) - NPi*NPi*exp(c4*r2)*sin(NPi*x)*sin(NPi*y)*sin(NPi*z);
double uyy = c4*r2yy*u + c4*r2y*uy + c4*r2y*NPi*exp(c4*r2)*sin(NPi*x)*cos(NPi*y)*sin(NPi*z) - NPi*NPi*exp(c4*r2)*sin(NPi*x)*sin(NPi*y)*sin(NPi*z);
double uzz = c4*r2zz*u + c4*r2z*uz + c4*r2z*NPi*exp(c4*r2)*sin(NPi*x)*sin(NPi*y)*cos(NPi*z) - NPi*NPi*exp(c4*r2)*sin(NPi*x)*sin(NPi*y)*sin(NPi*z);
double f = a*A*u - b*( (Bx*ux + By*uy + Bz*uz) + B*(uxx + uyy + uzz) );
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
domain->subdomains[box].levels[level].grids[__alpha ][ijk] = A;
domain->subdomains[box].levels[level].grids[__beta ][ijk] = B;
domain->subdomains[box].levels[level].grids[__u_exact][ijk] = u;
domain->subdomains[box].levels[level].grids[__f ][ijk] = f;
}}}
}
double average_value_of_f = mean(domain,level,__f);
if(domain->rank==0){printf("\n average value of f = %20.12e\n",average_value_of_f);fflush(stdout);}
if(a!=0){
shift_grid(domain,level,__f ,__f ,-average_value_of_f);
shift_grid(domain,level,__u_exact,__u_exact,-average_value_of_f/a);
}
// what if a==0 and average_value_of_f != 0 ???
}
//------------------------------------------------------------------------------------------------------------------------------