예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}