void temperature_boundary_conditions(struct All_variables *E) { int node; /* bottom */ if(E->mesh.bottbc == 3){ /* variable bottom temperature condition */ /* to left of domain */ horizontal_bc_range(E, E->TB, 1, 3, E->control.TBCbotval, TBZ, 1, E->mesh.levmax,0,E->control.TBCbotval_side_xapply,0,E->mesh.layer[2]); horizontal_bc_range(E, E->TB, 1, 3, E->control.TBCbotval, FBZ, 0, E->mesh.levmax,0,E->control.TBCbotval_side_xapply,0,E->mesh.layer[2]); /* to right of domain, override node at boundary */ horizontal_bc_range(E, E->TB, 1, 3, E->control.TBCbotval_side, TBZ, 1, E->mesh.levmax,E->control.TBCbotval_side_xapply,E->mesh.layer[1],0,E->mesh.layer[2]); horizontal_bc_range(E, E->TB, 1, 3, E->control.TBCbotval_side, FBZ, 0, E->mesh.levmax,E->control.TBCbotval_side_xapply,E->mesh.layer[1],0,E->mesh.layer[2]); }else if((E->mesh.bottbc == 1)||(E->mesh.bottbc == 2)){ /* regular temp boundary condition and ggrd temp override */ horizontal_bc(E, E->TB, 1, 3, E->control.TBCbotval, TBZ, 1, E->mesh.levmax); horizontal_bc(E, E->TB, 1, 3, E->control.TBCbotval, FBZ, 0, E->mesh.levmax); }else if(E->mesh.bottbc == 0){ /* const flux */ horizontal_bc(E, E->TB, 1, 3, E->control.TBCbotval, TBZ, 0, E->mesh.levmax); horizontal_bc(E, E->TB, 1, 3, E->control.TBCbotval, FBZ, 1, E->mesh.levmax); }else if(E->mesh.bottbc == -1){ /* const flux and fixed T*/ /* flux on left */ horizontal_bc_range(E, E->TB, 1, 3, E->control.TBCbotval, TBZ, 0, E->mesh.levmax,0,E->control.TBCbotval_side_xapply,0,E->mesh.layer[2]); horizontal_bc_range(E, E->TB, 1, 3, E->control.TBCbotval, FBZ, 1, E->mesh.levmax,0,E->control.TBCbotval_side_xapply,0,E->mesh.layer[2]); /* temp on right */ horizontal_bc_range(E, E->TB, 1, 3, E->control.TBCbotval_side, TBZ, 1, E->mesh.levmax,E->control.TBCbotval_side_xapply,E->mesh.layer[1],0,E->mesh.layer[2]); horizontal_bc_range(E, E->TB, 1, 3, E->control.TBCbotval_side, FBZ, 0, E->mesh.levmax,E->control.TBCbotval_side_xapply,E->mesh.layer[1],0,E->mesh.layer[2]); } /* top */ if(E->mesh.toptbc >= 1) /* temp */ { horizontal_bc(E, E->TB, E->mesh.noz, 3, E->control.TBCtopval, TBZ, 1, E->mesh.levmax); horizontal_bc(E, E->TB, E->mesh.noz, 3, E->control.TBCtopval, FBZ, 0, E->mesh.levmax); } else if(E->mesh.toptbc == 0) /* flux */ { horizontal_bc(E, E->TB, E->mesh.noz, 3, E->control.TBCtopval, TBZ, 0, E->mesh.levmax); horizontal_bc(E, E->TB, E->mesh.noz, 3, E->control.TBCtopval, FBZ, 1, E->mesh.levmax); } if(E->mesh.periodic_x || E->mesh.periodic_y){ temperature_apply_periodic_bcs(E); }else{ temperature_refl_vert_bc(E); /* default */ } temperatures_conform_bcs(E); if(E->control.verbose) { for(node = 1; node <= E->lmesh.nno; node++) fprintf(E->fp, "TB== %d %g %g %g\n", node, E->TB[1][node], E->TB[2][node], E->TB[3][node]); for(node = 1; node <= E->lmesh.nno; node++) fprintf(E->fp, "TB== %d %u %u %u\n", node, E->node[node] & TBX, E->node[node] & TBY, E->node[node] & TBZ); } return; }
static void read_tic_from_file(struct All_variables *E) { int ii, ll, mm; float tt; int i, m; char output_file[255], input_s[1000]; FILE *fp; float v1, v2, v3, g; ii = E->monitor.solution_cycles_init; sprintf(output_file,"%s.velo.%d.%d",E->control.old_P_file,E->parallel.me,ii); fp=fopen(output_file,"r"); if (fp == NULL) { fprintf(E->fp,"(Initial_temperature.c #1) Cannot open %s\n",output_file); parallel_process_termination(); } if (E->parallel.me==0) fprintf(E->fp,"Reading %s for initial temperature\n",output_file); fgets(input_s,1000,fp); sscanf(input_s,"%d %d %f",&ll,&mm,&tt); for(m=1;m<=E->sphere.caps_per_proc;m++) { fgets(input_s,1000,fp); sscanf(input_s,"%d %d",&ll,&mm); for(i=1;i<=E->lmesh.nno;i++) { fgets(input_s,1000,fp); if(sscanf(input_s,"%g %g %g %f",&(v1),&(v2),&(v3),&(g)) != 4) { fprintf(stderr,"Error while reading file '%s'\n", output_file); exit(8); } /* Truncate the temperature to be within (0,1). */ /* This might not be desirable in some situations. */ E->T[m][i] = max(0.0,min(g,1.0)); } } fclose (fp); temperatures_conform_bcs(E); return; }
static void construct_tic_from_input(struct All_variables *E) { double mantle_temperature; switch (E->convection.tic_method){ case 0: /* a linear temperature profile + perturbations at some layers */ linear_temperature_profile(E); add_perturbations_at_layers(E); break; case 1: /* T=1 for whole mantle + cold lithosphere TBL */ mantle_temperature = 1; constant_temperature_profile(E, mantle_temperature); add_top_tbl(E, E->convection.half_space_age, mantle_temperature); break; case 2: /* T='mantle_temp' for whole mantle + cold lithosphere TBL + a spherical anomaly at lower center */ mantle_temperature = E->control.mantle_temp; constant_temperature_profile(E, mantle_temperature); add_top_tbl(E, E->convection.half_space_age, mantle_temperature); add_spherical_anomaly(E); break; case 3: /* a conductive temperature profile + perturbations at all layers */ conductive_temperature_profile(E); add_perturbations_at_all_layers(E); break; case 4: /* read initial temperature from grd files */ #ifdef USE_GGRD ggrd_temp_init_general(E,1); #else fprintf(stderr,"tic_method 4 only works for USE_GGRD compiled code\n"); parallel_process_termination(); #endif break; case 10: /* T='mantle_temp' for whole mantle + cold lithosphere TBL + perturbations at some layers */ mantle_temperature = E->control.mantle_temp; constant_temperature_profile(E, mantle_temperature); add_top_tbl(E, E->convection.half_space_age, mantle_temperature); add_perturbations_at_all_layers(E); break; case 11: /* T='mantle_temp' for whole mantle + hot CMB TBL + perturbations at some layers */ mantle_temperature = E->control.mantle_temp; constant_temperature_profile(E, mantle_temperature); add_bottom_tbl(E, E->convection.half_space_age, mantle_temperature); add_perturbations_at_all_layers(E); break; case 12: /* T='mantle_temp' for whole mantle + cold lithosphere TBL + hot CMB TBL + perturbations at some layers */ mantle_temperature = E->control.mantle_temp; constant_temperature_profile(E, mantle_temperature); add_top_tbl(E, E->convection.half_space_age, mantle_temperature); add_bottom_tbl(E, E->convection.half_space_age, mantle_temperature); add_perturbations_at_all_layers(E); break; case 90: /* for benchmarking purpose */ /* a constant temperature (0) + single perturbation at mid-layer as a delta function in r */ if((E->parallel.nprocz % 2) == 0) { if(E->parallel.me==0) fprintf(stderr, "ERROR: tic_method=%d -- nprocz is even, cannot put perturbation on processor boundary!\n", E->convection.tic_method); parallel_process_termination(); } constant_temperature_profile(E, 0); { /* adjust the amplitude of perturbation, so that * its integral in r is 1 */ int mid, k; E->convection.number_of_perturbations = 1; mid = (E->mesh.noz+1) / 2; E->convection.load_depth[0] = mid; k = mid - E->lmesh.nzs + 1; /* convert to local nz */ E->convection.perturb_mag[0] = 0; if ( (k > 1) && (k < E->lmesh.noz) ) { /* layer k is inside this proc. */ E->convection.perturb_mag[0] = 2 / (E->sx[1][3][k+1] - E->sx[1][3][k-1]); } } add_perturbations_at_layers(E); break; case 100: /* user-defined initial temperature goes here */ fprintf(stderr,"Need user definition for initial temperture: 'tic_method=%d'\n", E->convection.tic_method); parallel_process_termination(); break; default: /* unknown option */ fprintf(stderr,"Invalid value: 'tic_method=%d'\n", E->convection.tic_method); parallel_process_termination(); break; } temperatures_conform_bcs(E); /* debugging the code of expanding spherical harmonics */ /* debug_sphere_expansion(E);*/ return; }
void temperature_boundary_conditions( struct All_variables *E ) { void temperatures_conform_bcs(); void temperature_apply_periodic_bcs(); void arbitrary_bc_rectangle(); void arbitrary_bc_rectangle_file(); void arbitrary_bc_circle_file(); void arbitrary_bc_harmonic_file(); void arbitrary_bc_polynomial_file(); void field_arbitrary_rectangle_file(); void field_arbitrary_circle_file(); void field_arbitrary_harmonic_file(); int i,lv; struct RectBc RECT; /* Default: Isothermal top (toptbcval) and bottom (bottbcval), reflecting sidewalls. */ RECT.numb=2; /* X-normal */ RECT.norm[0]=RECT.norm[1]='X'; RECT.bb1[0]=RECT.bb1[1]= -1.0e32; RECT.bb2[0]=RECT.bb2[1]= 1.0e32; RECT.aa1[0]=RECT.aa1[1]= -1.0e32; RECT.aa2[0]=RECT.aa2[1]= 1.0e32; RECT.intercept[0]=E->mesh.layer0[1]; RECT.mag[0]=0.0; RECT.intercept[1]=E->mesh.layer1[1]; RECT.mag[1]=0.0; arbitrary_bc_rectangle(E,&RECT,E->Tb,E->NODE,FBX, TBD | FBZ | FBY, 0); /* Sides */ if(3==E->mesh.nsd) { RECT.numb=2; /* Y-normal */ RECT.norm[0]=RECT.norm[1]='Y'; RECT.bb1[0]=RECT.bb1[1]= -1.0e32; RECT.bb2[0]=RECT.bb2[1]= 1.0e32; RECT.aa1[0]=RECT.aa1[1]= -1.0e32; RECT.aa2[0]=RECT.aa2[1]= 1.0e32; RECT.intercept[0]=E->mesh.layer0[3]; RECT.mag[0]=0.0; RECT.intercept[1]=E->mesh.layer1[3]; RECT.mag[1]=0.0; arbitrary_bc_rectangle(E,&RECT,E->Tb,E->NODE,FBY, TBD | FBX | FBZ, 0); /* Sides */ } RECT.numb=2; /* Z-normal */ RECT.norm[0]=RECT.norm[1]='Z'; RECT.aa1[0]=RECT.aa1[1]= -1.0e32; RECT.aa2[0]=RECT.aa2[1]= 1.0e32; RECT.bb1[0]=RECT.bb1[1]= -1.0e32; RECT.bb2[0]=RECT.bb2[1]= 1.0e32; RECT.intercept[0]=E->mesh.layer0[2]; RECT.mag[0]=E->control.TBCtopval; RECT.intercept[1]=E->mesh.layer1[2]; RECT.mag[1]=E->control.TBCbotval; arbitrary_bc_rectangle(E,&RECT,E->Tb,E->NODE,TBD,FBZ | FBX | FBY, 0); /* Now read in from any file which is found (top level). */ read_bc_from_file(E,E->TB,E->node,"Temperature","Temp",TBD,FBZ | FBX | FBY); read_bc_from_file(E,E->TB,E->node,"Heat_flux_z","Hflz",FBZ,TBD | FBX | FBY); for(lv=E->mesh.levmax; lv>E->mesh.levmin; lv--) { inject_node_values(E,lv,E->Tb[lv],E->Tb[lv-1]); inject_node_int_values(E,lv,E->NODE[lv],E->NODE[lv-1]); } /* Read in arbitrary structures from parameter files */ arbitrary_bc_rectangle_file(E,&(E->temperature.Trectbcs),"Heat_flux_z",E->Tb,E->NODE,FBZ,TBD,0); arbitrary_bc_circle_file(E,&(E->temperature.Tcircbcs),"Heat_flux_z",E->Tb,E->NODE,FBZ,TBD); arbitrary_bc_harmonic_file(E,&(E->temperature.Tharmbcs),"Heat_flux_z",E->Tb,E->NODE,FBZ,TBD); arbitrary_bc_polynomial_file(E,&(E->temperature.Tpolybcs),"Heat_flux_z",E->Tb,E->NODE,FBZ,TBD); field_arbitrary_rectangle_file(E,1,&(E->temperature.Trects),"Temp_fixed",E->TB,E->node,TBD,FBZ|FBX|FBY,E->mesh.levmax); field_arbitrary_circle_file(E,1,&(E->temperature.Tcircs),"Temp_fixed",E->TB,E->node,TBD,FBZ|FBX|FBY,E->mesh.levmax); field_arbitrary_harmonic_file(E,1,&(E->temperature.Tharms),"Temp_fixed",E->TB,E->node,TBD,FBZ|FBX|FBY,E->mesh.levmax); for(lv=E->mesh.levmin; lv<E->mesh.levmax; lv++) { field_arbitrary_rectangle(E,&(E->temperature.Trects),E->Tb[lv],E->NODE[lv],TBD,FBZ|FBX|FBY,lv); field_arbitrary_circle(E,&(E->temperature.Tcircs),E->Tb[lv],E->NODE[lv],TBD,FBZ|FBX|FBY,lv); field_arbitrary_harmonic(E,&(E->temperature.Tharms),E->Tb[lv],E->NODE[lv],TBD,FBZ|FBX|FBY,lv); } arbitrary_bc_rectangle_file(E,&(E->temperature.Trectbcs),"Temp",E->Tb,E->NODE,TBD,FBZ|FBX|FBY,0); arbitrary_bc_circle_file(E,&(E->temperature.Tcircbcs),"Temp",E->Tb,E->NODE,TBD,FBZ|FBX|FBY); arbitrary_bc_harmonic_file(E,&(E->temperature.Tharmbcs),"Temp",E->Tb,E->NODE,TBD,FBZ|FBX|FBY); arbitrary_bc_polynomial_file(E,&(E->temperature.Tpolybcs),"Temp",E->Tb,E->NODE,TBD,FBZ|FBX|FBY); if(E->mesh.periodic_x || E->mesh.periodic_y) temperature_apply_periodic_bcs(E); field_arbitrary_rectangle_file(E,1,&(E->temperature.Tintz_off),"Tintz_off",(standard_precision *)NULL,E->node,0,INTZ,E->mesh.levmax); field_arbitrary_rectangle_file(E,1,&(E->temperature.Tintz_on) ,"Tintz_on" ,(standard_precision *)NULL,E->node,INTZ,0,E->mesh.levmax); for(lv=E->mesh.levmin; lv<E->mesh.levmax; lv++) { field_arbitrary_rectangle(E,&(E->temperature.Tintz_off),(standard_precision *)NULL,E->NODE[lv],0,INTZ,lv); field_arbitrary_rectangle(E,&(E->temperature.Tintz_on) ,(standard_precision *)NULL,E->NODE[lv],INTZ,0,lv); } temperatures_conform_bcs(E,E->T); return; }